mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-07 07:37:02 +02:00
REORG: spoe: move spoe_encode_varint / spoe_decode_varint from spoe to common
These encoding functions does general stuff and can be used in other context than spoe. This patch moves the function spoe_encode_varint and spoe_decode_varint from spoe to common. It also remove the prefix spoe. These functions will be used for encoding values in new binary sample fetch.
This commit is contained in:
parent
f4128a9981
commit
6ab2bae084
@ -267,7 +267,7 @@ check_max_frame_size(struct spoe_frame *frame, char **buf, char *end)
|
||||
(type & SPOE_DATA_T_MASK) != SPOE_DATA_T_UINT32 &&
|
||||
(type & SPOE_DATA_T_MASK) != SPOE_DATA_T_UINT64)
|
||||
return -1;
|
||||
if (spoe_decode_varint(&p, end, &sz) == -1)
|
||||
if (decode_varint(&p, end, &sz) == -1)
|
||||
return -1;
|
||||
|
||||
/* Keep the lower value */
|
||||
@ -453,7 +453,7 @@ check_discon_status_code(struct spoe_frame *frame, char **buf, char *end)
|
||||
(type & SPOE_DATA_T_MASK) != SPOE_DATA_T_UINT32 &&
|
||||
(type & SPOE_DATA_T_MASK) != SPOE_DATA_T_UINT64)
|
||||
return -1;
|
||||
if (spoe_decode_varint(&p, end, &sz) == -1)
|
||||
if (decode_varint(&p, end, &sz) == -1)
|
||||
return -1;
|
||||
|
||||
frame->client->status_code = (unsigned int)sz;
|
||||
@ -709,9 +709,9 @@ handle_hanotify(struct spoe_frame *frame)
|
||||
}
|
||||
|
||||
/* Read the stream-id and frame-id */
|
||||
if (spoe_decode_varint(&p, end, &stream_id) == -1)
|
||||
if (decode_varint(&p, end, &stream_id) == -1)
|
||||
goto ignore;
|
||||
if (spoe_decode_varint(&p, end, &frame_id) == -1)
|
||||
if (decode_varint(&p, end, &frame_id) == -1)
|
||||
goto ignore;
|
||||
|
||||
frame->stream_id = (unsigned int)stream_id;
|
||||
@ -765,9 +765,9 @@ handle_hafrag(struct spoe_frame *frame)
|
||||
p+= 4;
|
||||
|
||||
/* Read the stream-id and frame-id */
|
||||
if (spoe_decode_varint(&p, end, &stream_id) == -1)
|
||||
if (decode_varint(&p, end, &stream_id) == -1)
|
||||
goto ignore;
|
||||
if (spoe_decode_varint(&p, end, &frame_id) == -1)
|
||||
if (decode_varint(&p, end, &frame_id) == -1)
|
||||
goto ignore;
|
||||
|
||||
if (frame->fragmented == false ||
|
||||
@ -842,7 +842,7 @@ prepare_agenthello(struct spoe_frame *frame)
|
||||
/* "max-frame-size" K/V item */
|
||||
spoe_encode_buffer("max-frame-size", 14, &p ,end);
|
||||
*p++ = SPOE_DATA_T_UINT32;
|
||||
spoe_encode_varint(client->max_frame_size, &p, end);
|
||||
encode_varint(client->max_frame_size, &p, end);
|
||||
DEBUG(frame->worker, "<%lu> Agent maximum frame size : %u",
|
||||
client->id, client->max_frame_size);
|
||||
|
||||
@ -917,7 +917,7 @@ prepare_agentdicon(struct spoe_frame *frame)
|
||||
/* "status-code" K/V item */
|
||||
spoe_encode_buffer("status-code", 11, &p, end);
|
||||
*p++ = SPOE_DATA_T_UINT32;
|
||||
spoe_encode_varint(client->status_code, &p, end);
|
||||
encode_varint(client->status_code, &p, end);
|
||||
DEBUG(frame->worker, "<%lu> Disconnect status code : %u",
|
||||
client->id, client->status_code);
|
||||
|
||||
@ -956,8 +956,8 @@ prepare_agentack(struct spoe_frame *frame)
|
||||
p += 4;
|
||||
|
||||
/* Set stream-id and frame-id for ACK frames */
|
||||
spoe_encode_varint(frame->stream_id, &p, end);
|
||||
spoe_encode_varint(frame->frame_id, &p, end);
|
||||
encode_varint(frame->stream_id, &p, end);
|
||||
encode_varint(frame->frame_id, &p, end);
|
||||
|
||||
DEBUG(frame->worker, "STREAM-ID=%u - FRAME-ID=%u",
|
||||
frame->stream_id, frame->frame_id);
|
||||
@ -1369,7 +1369,7 @@ process_frame_cb(evutil_socket_t fd, short events, void *arg)
|
||||
*p++ = SPOE_SCOPE_SESS; /* Arg 1: the scope */
|
||||
spoe_encode_buffer("ip_score", 8, &p, end); /* Arg 2: variable name */
|
||||
*p++ = SPOE_DATA_T_UINT32;
|
||||
spoe_encode_varint(frame->ip_score, &p, end); /* Arg 3: variable value */
|
||||
encode_varint(frame->ip_score, &p, end); /* Arg 3: variable value */
|
||||
frame->len = (p - frame->buf);
|
||||
}
|
||||
write_frame(NULL, frame);
|
||||
|
@ -205,6 +205,83 @@ static inline const char *LIM2A(unsigned long n, const char *alt)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Encode the integer <i> into a varint (variable-length integer). The encoded
|
||||
* value is copied in <*buf>. Here is the encoding format:
|
||||
*
|
||||
* 0 <= X < 240 : 1 byte (7.875 bits) [ XXXX XXXX ]
|
||||
* 240 <= X < 2288 : 2 bytes (11 bits) [ 1111 XXXX ] [ 0XXX XXXX ]
|
||||
* 2288 <= X < 264432 : 3 bytes (18 bits) [ 1111 XXXX ] [ 1XXX XXXX ] [ 0XXX XXXX ]
|
||||
* 264432 <= X < 33818864 : 4 bytes (25 bits) [ 1111 XXXX ] [ 1XXX XXXX ]*2 [ 0XXX XXXX ]
|
||||
* 33818864 <= X < 4328786160 : 5 bytes (32 bits) [ 1111 XXXX ] [ 1XXX XXXX ]*3 [ 0XXX XXXX ]
|
||||
* ...
|
||||
*
|
||||
* On success, it returns the number of written bytes and <*buf> is moved after
|
||||
* the encoded value. Otherwise, it returns -1. */
|
||||
static inline int
|
||||
encode_varint(uint64_t i, char **buf, char *end)
|
||||
{
|
||||
unsigned char *p = (unsigned char *)*buf;
|
||||
int r;
|
||||
|
||||
if (p >= (unsigned char *)end)
|
||||
return -1;
|
||||
|
||||
if (i < 240) {
|
||||
*p++ = i;
|
||||
*buf = (char *)p;
|
||||
return 1;
|
||||
}
|
||||
|
||||
*p++ = (unsigned char)i | 240;
|
||||
i = (i - 240) >> 4;
|
||||
while (i >= 128) {
|
||||
if (p >= (unsigned char *)end)
|
||||
return -1;
|
||||
*p++ = (unsigned char)i | 128;
|
||||
i = (i - 128) >> 7;
|
||||
}
|
||||
|
||||
if (p >= (unsigned char *)end)
|
||||
return -1;
|
||||
*p++ = (unsigned char)i;
|
||||
|
||||
r = ((char *)p - *buf);
|
||||
*buf = (char *)p;
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Decode a varint from <*buf> and save the decoded value in <*i>. See
|
||||
* 'spoe_encode_varint' for details about varint.
|
||||
* On success, it returns the number of read bytes and <*buf> is moved after the
|
||||
* varint. Otherwise, it returns -1. */
|
||||
static inline int
|
||||
decode_varint(char **buf, char *end, uint64_t *i)
|
||||
{
|
||||
unsigned char *p = (unsigned char *)*buf;
|
||||
int r;
|
||||
|
||||
if (p >= (unsigned char *)end)
|
||||
return -1;
|
||||
|
||||
*i = *p++;
|
||||
if (*i < 240) {
|
||||
*buf = (char *)p;
|
||||
return 1;
|
||||
}
|
||||
|
||||
r = 4;
|
||||
do {
|
||||
if (p >= (unsigned char *)end)
|
||||
return -1;
|
||||
*i += (uint64_t)*p << r;
|
||||
r += 7;
|
||||
} while (*p++ >= 128);
|
||||
|
||||
r = ((char *)p - *buf);
|
||||
*buf = (char *)p;
|
||||
return r;
|
||||
}
|
||||
|
||||
/* returns a locally allocated string containing the quoted encoding of the
|
||||
* input string. The output may be truncated to QSTR_SIZE chars, but it is
|
||||
* guaranteed that the string will always be properly terminated. Quotes are
|
||||
|
@ -22,88 +22,13 @@
|
||||
#ifndef _PROTO_SPOE_H
|
||||
#define _PROTO_SPOE_H
|
||||
|
||||
#include <common/standard.h>
|
||||
|
||||
#include <types/spoe.h>
|
||||
|
||||
#include <proto/sample.h>
|
||||
|
||||
|
||||
/* Encode the integer <i> into a varint (variable-length integer). The encoded
|
||||
* value is copied in <*buf>. Here is the encoding format:
|
||||
*
|
||||
* 0 <= X < 240 : 1 byte (7.875 bits) [ XXXX XXXX ]
|
||||
* 240 <= X < 2288 : 2 bytes (11 bits) [ 1111 XXXX ] [ 0XXX XXXX ]
|
||||
* 2288 <= X < 264432 : 3 bytes (18 bits) [ 1111 XXXX ] [ 1XXX XXXX ] [ 0XXX XXXX ]
|
||||
* 264432 <= X < 33818864 : 4 bytes (25 bits) [ 1111 XXXX ] [ 1XXX XXXX ]*2 [ 0XXX XXXX ]
|
||||
* 33818864 <= X < 4328786160 : 5 bytes (32 bits) [ 1111 XXXX ] [ 1XXX XXXX ]*3 [ 0XXX XXXX ]
|
||||
* ...
|
||||
*
|
||||
* On success, it returns the number of written bytes and <*buf> is moved after
|
||||
* the encoded value. Otherwise, it returns -1. */
|
||||
static inline int
|
||||
spoe_encode_varint(uint64_t i, char **buf, char *end)
|
||||
{
|
||||
unsigned char *p = (unsigned char *)*buf;
|
||||
int r;
|
||||
|
||||
if (p >= (unsigned char *)end)
|
||||
return -1;
|
||||
|
||||
if (i < 240) {
|
||||
*p++ = i;
|
||||
*buf = (char *)p;
|
||||
return 1;
|
||||
}
|
||||
|
||||
*p++ = (unsigned char)i | 240;
|
||||
i = (i - 240) >> 4;
|
||||
while (i >= 128) {
|
||||
if (p >= (unsigned char *)end)
|
||||
return -1;
|
||||
*p++ = (unsigned char)i | 128;
|
||||
i = (i - 128) >> 7;
|
||||
}
|
||||
|
||||
if (p >= (unsigned char *)end)
|
||||
return -1;
|
||||
*p++ = (unsigned char)i;
|
||||
|
||||
r = ((char *)p - *buf);
|
||||
*buf = (char *)p;
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Decode a varint from <*buf> and save the decoded value in <*i>. See
|
||||
* 'spoe_encode_varint' for details about varint.
|
||||
* On success, it returns the number of read bytes and <*buf> is moved after the
|
||||
* varint. Otherwise, it returns -1. */
|
||||
static inline int
|
||||
spoe_decode_varint(char **buf, char *end, uint64_t *i)
|
||||
{
|
||||
unsigned char *p = (unsigned char *)*buf;
|
||||
int r;
|
||||
|
||||
if (p >= (unsigned char *)end)
|
||||
return -1;
|
||||
|
||||
*i = *p++;
|
||||
if (*i < 240) {
|
||||
*buf = (char *)p;
|
||||
return 1;
|
||||
}
|
||||
|
||||
r = 4;
|
||||
do {
|
||||
if (p >= (unsigned char *)end)
|
||||
return -1;
|
||||
*i += (uint64_t)*p << r;
|
||||
r += 7;
|
||||
} while (*p++ >= 128);
|
||||
|
||||
r = ((char *)p - *buf);
|
||||
*buf = (char *)p;
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Encode a buffer. Its length <len> is encoded as a varint, followed by a copy
|
||||
* of <str>. It must have enough space in <*buf> to encode the buffer, else an
|
||||
* error is triggered.
|
||||
@ -124,7 +49,7 @@ spoe_encode_buffer(const char *str, size_t len, char **buf, char *end)
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = spoe_encode_varint(len, &p, end);
|
||||
ret = encode_varint(len, &p, end);
|
||||
if (ret == -1 || p + len > end)
|
||||
return -1;
|
||||
|
||||
@ -152,7 +77,7 @@ spoe_encode_frag_buffer(const char *str, size_t len, char **buf, char *end)
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = spoe_encode_varint(len, &p, end);
|
||||
ret = encode_varint(len, &p, end);
|
||||
if (ret == -1 || p >= end)
|
||||
return -1;
|
||||
|
||||
@ -176,7 +101,7 @@ spoe_decode_buffer(char **buf, char *end, char **str, size_t *len)
|
||||
*str = NULL;
|
||||
*len = 0;
|
||||
|
||||
ret = spoe_decode_varint(&p, end, &sz);
|
||||
ret = decode_varint(&p, end, &sz);
|
||||
if (ret == -1 || p + sz > end)
|
||||
return -1;
|
||||
|
||||
@ -217,7 +142,7 @@ spoe_encode_data(struct sample *smp, unsigned int *off, char **buf, char *end)
|
||||
|
||||
case SMP_T_SINT:
|
||||
*p++ = SPOE_DATA_T_INT64;
|
||||
if (spoe_encode_varint(smp->data.u.sint, &p, end) == -1)
|
||||
if (encode_varint(smp->data.u.sint, &p, end) == -1)
|
||||
return -1;
|
||||
break;
|
||||
|
||||
@ -313,7 +238,7 @@ spoe_encode_data(struct sample *smp, unsigned int *off, char **buf, char *end)
|
||||
*
|
||||
* A types data is composed of a type (1 byte) and corresponding data:
|
||||
* - boolean: non additional data (0 bytes)
|
||||
* - integers: a variable-length integer (see spoe_decode_varint)
|
||||
* - integers: a variable-length integer (see decode_varint)
|
||||
* - ipv4: 4 bytes
|
||||
* - ipv6: 16 bytes
|
||||
* - binary and string: a buffer prefixed by its size, a variable-length
|
||||
@ -337,7 +262,7 @@ spoe_skip_data(char **buf, char *end)
|
||||
case SPOE_DATA_T_INT64:
|
||||
case SPOE_DATA_T_UINT32:
|
||||
case SPOE_DATA_T_UINT64:
|
||||
if (spoe_decode_varint(&p, end, &v) == -1)
|
||||
if (decode_varint(&p, end, &v) == -1)
|
||||
return -1;
|
||||
break;
|
||||
case SPOE_DATA_T_IPV4:
|
||||
@ -386,7 +311,7 @@ spoe_decode_data(char **buf, char *end, struct sample *smp)
|
||||
case SPOE_DATA_T_INT64:
|
||||
case SPOE_DATA_T_UINT32:
|
||||
case SPOE_DATA_T_UINT64:
|
||||
if (spoe_decode_varint(&p, end, (uint64_t *)&smp->data.u.sint) == -1)
|
||||
if (decode_varint(&p, end, (uint64_t *)&smp->data.u.sint) == -1)
|
||||
return -1;
|
||||
smp->data.type = SMP_T_SINT;
|
||||
break;
|
||||
|
@ -388,7 +388,7 @@ spoe_prepare_hahello_frame(struct appctx *appctx, char *frame, size_t size)
|
||||
goto too_big;
|
||||
|
||||
*p++ = SPOE_DATA_T_UINT32;
|
||||
if (spoe_encode_varint(SPOE_APPCTX(appctx)->max_frame_size, &p, end) == -1)
|
||||
if (encode_varint(SPOE_APPCTX(appctx)->max_frame_size, &p, end) == -1)
|
||||
goto too_big;
|
||||
|
||||
/* "capabilities" K/V item */
|
||||
@ -469,7 +469,7 @@ spoe_prepare_hadiscon_frame(struct appctx *appctx, char *frame, size_t size)
|
||||
goto too_big;
|
||||
|
||||
*p++ = SPOE_DATA_T_UINT32;
|
||||
if (spoe_encode_varint(SPOE_APPCTX(appctx)->status_code, &p, end) == -1)
|
||||
if (encode_varint(SPOE_APPCTX(appctx)->status_code, &p, end) == -1)
|
||||
goto too_big;
|
||||
|
||||
/* "message" K/V item */
|
||||
@ -527,9 +527,9 @@ spoe_prepare_hanotify_frame(struct appctx *appctx, struct spoe_context *ctx,
|
||||
p += 4;
|
||||
|
||||
/* Set stream-id and frame-id */
|
||||
if (spoe_encode_varint(stream_id, &p, end) == -1)
|
||||
if (encode_varint(stream_id, &p, end) == -1)
|
||||
goto too_big;
|
||||
if (spoe_encode_varint(frame_id, &p, end) == -1)
|
||||
if (encode_varint(frame_id, &p, end) == -1)
|
||||
goto too_big;
|
||||
|
||||
/* Copy encoded messages, if possible */
|
||||
@ -583,9 +583,9 @@ spoe_prepare_hafrag_frame(struct appctx *appctx, struct spoe_context *ctx,
|
||||
p += 4;
|
||||
|
||||
/* Set stream-id and frame-id */
|
||||
if (spoe_encode_varint(stream_id, &p, end) == -1)
|
||||
if (encode_varint(stream_id, &p, end) == -1)
|
||||
goto too_big;
|
||||
if (spoe_encode_varint(frame_id, &p, end) == -1)
|
||||
if (encode_varint(frame_id, &p, end) == -1)
|
||||
goto too_big;
|
||||
|
||||
if (ctx == NULL)
|
||||
@ -706,7 +706,7 @@ spoe_handle_agenthello_frame(struct appctx *appctx, char *frame, size_t size)
|
||||
SPOE_APPCTX(appctx)->status_code = SPOE_FRM_ERR_INVALID;
|
||||
return 0;
|
||||
}
|
||||
if (spoe_decode_varint(&p, end, &sz) == -1) {
|
||||
if (decode_varint(&p, end, &sz) == -1) {
|
||||
SPOE_APPCTX(appctx)->status_code = SPOE_FRM_ERR_INVALID;
|
||||
return 0;
|
||||
}
|
||||
@ -858,7 +858,7 @@ spoe_handle_agentdiscon_frame(struct appctx *appctx, char *frame, size_t size)
|
||||
SPOE_APPCTX(appctx)->status_code = SPOE_FRM_ERR_INVALID;
|
||||
return 0;
|
||||
}
|
||||
if (spoe_decode_varint(&p, end, &sz) == -1) {
|
||||
if (decode_varint(&p, end, &sz) == -1) {
|
||||
SPOE_APPCTX(appctx)->status_code = SPOE_FRM_ERR_INVALID;
|
||||
return 0;
|
||||
}
|
||||
@ -935,11 +935,11 @@ spoe_handle_agentack_frame(struct appctx *appctx, struct spoe_context **ctx,
|
||||
}
|
||||
|
||||
/* Get the stream-id and the frame-id */
|
||||
if (spoe_decode_varint(&p, end, &stream_id) == -1) {
|
||||
if (decode_varint(&p, end, &stream_id) == -1) {
|
||||
SPOE_APPCTX(appctx)->status_code = SPOE_FRM_ERR_INVALID;
|
||||
return 0;
|
||||
}
|
||||
if (spoe_decode_varint(&p, end, &frame_id) == -1) {
|
||||
if (decode_varint(&p, end, &frame_id) == -1) {
|
||||
SPOE_APPCTX(appctx)->status_code = SPOE_FRM_ERR_INVALID;
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user