]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
REORG: spoe: move spoe_encode_varint / spoe_decode_varint from spoe to common
authorThierry FOURNIER <thierry.fournier@ozon.io>
Wed, 19 Apr 2017 09:49:44 +0000 (11:49 +0200)
committerWilly Tarreau <w@1wt.eu>
Thu, 27 Apr 2017 09:50:41 +0000 (11:50 +0200)
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.

contrib/spoa_example/spoa.c
include/common/standard.h
include/proto/spoe.h
src/flt_spoe.c

index 7c6d50424cba72758b17bb162ce5a5b84d2808b1..8fb62e022fcef01315b2cc93bc55e78ee2ba0e56 100644 (file)
@@ -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);
index 682711105ee8953c1525196d3fdc4ffbabf6b48c..4ba6a950c1765337545238d4c1d899c5f7307758 100644 (file)
@@ -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
index da19db1d776698678f66b07ac32db73a5c938a2e..1372a7d457b20e06bd95adedc1ddb6bc3fd7b13e 100644 (file)
 #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;
index 42e9c0c16bf01ce43e4831931c32becdd3657eaf..9288de99fa0c7c9f0109526619793921d0716780 100644 (file)
@@ -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;
        }