From c4dcaff3f01cdd774d15767962c76910f9d3e39a Mon Sep 17 00:00:00 2001 From: Thierry FOURNIER Date: Fri, 18 May 2018 12:25:39 +0200 Subject: [PATCH] BUG/MEDIUM: spoe: Flags are not encoded in network order The flags are direct copy of the "unsigned int" in the network stream, so the stream contains a 32 bits field encoded with the host endian. - This is not reliable for stream betwen different architecture host - For x86, the bits doesn't correspond to the documentation. This patch add some precision in the documentation and put the bitfield in the stream usig network butes order. Warning: this patch can break compatibility with existing agents. This patch should be backported in all version supporing SPOE Original network capture: 12:28:16.181343 IP 127.0.0.1.46782 > 127.0.0.1.12345: Flags [P.], seq 134:168, ack 59, win 342, options [nop,nop,TS val 2855241281 ecr 2855241281], length 34 0x0000: 4500 0056 6b94 4000 4006 d10b 7f00 0001 E..Vk.@.@....... 0x0010: 7f00 0001 b6be 3039 a3d1 ee54 7d61 d6f7 ......09...T}a.. 0x0020: 8018 0156 fe4a 0000 0101 080a aa2f 8641 ...V.J......./.A 0x0030: aa2f 8641 0000 001e 0301 0000 0000 010f ./.A............ ^^^^^^^^^^ 0x0040: 6368 6563 6b2d 636c 6965 6e74 2d69 7001 check-client-ip. 0x0050: 0006 7f00 0001 ...... Fixed network capture: 12:24:26.948165 IP 127.0.0.1.46706 > 127.0.0.1.12345: Flags [P.], seq 4066280627:4066280661, ack 3148908096, win 342, options [nop,nop,TS val 2855183972 ecr 2855177690], length 34 0x0000: 4500 0056 0538 4000 4006 3768 7f00 0001 E..V.8@.@.7h.... 0x0010: 7f00 0001 b672 3039 f25e 84b3 bbb0 8640 .....r09.^.....@ 0x0020: 8018 0156 fe4a 0000 0101 080a aa2e a664 ...V.J.........d 0x0030: aa2e 8dda 0000 001e 0300 0000 0114 010f ................ ^^^^^^^^^^ 0x0040: 6368 6563 6b2d 636c 6965 6e74 2d69 7001 check-client-ip. 0x0050: 0006 7f00 0001 ...... --- contrib/spoa_example/spoa.c | 7 +++++++ doc/SPOE.txt | 7 ++++++- src/flt_spoe.c | 7 +++++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/contrib/spoa_example/spoa.c b/contrib/spoa_example/spoa.c index bf2dbe9a9..71a36f072 100644 --- a/contrib/spoa_example/spoa.c +++ b/contrib/spoa_example/spoa.c @@ -514,6 +514,7 @@ handle_hahello(struct spoe_frame *frame) /* Retrieve flags */ memcpy((char *)&(frame->flags), p, 4); + frame->flags = ntohl(frame->flags); p += 4; /* Fragmentation is not supported for HELLO frame */ @@ -621,6 +622,7 @@ handle_hadiscon(struct spoe_frame *frame) /* Retrieve flags */ memcpy((char *)&(frame->flags), p, 4); + frame->flags = ntohl(frame->flags); p += 4; /* Fragmentation is not supported for DISCONNECT frame */ @@ -702,6 +704,7 @@ handle_hanotify(struct spoe_frame *frame) /* Retrieve flags */ memcpy((char *)&(frame->flags), p, 4); + frame->flags = ntohl(frame->flags); p += 4; /* Fragmentation is not supported */ @@ -764,6 +767,7 @@ handle_hafrag(struct spoe_frame *frame) /* Retrieve flags */ memcpy((char *)&(frame->flags), p, 4); + frame->flags = ntohl(frame->flags); p+= 4; /* Read the stream-id and frame-id */ @@ -826,6 +830,7 @@ prepare_agenthello(struct spoe_frame *frame) *p++ = SPOE_FRM_T_AGENT_HELLO; /* Set flags */ + flags = htonl(flags); memcpy(p, (char *)&flags, 4); p += 4; @@ -907,6 +912,7 @@ prepare_agentdicon(struct spoe_frame *frame) *p++ = SPOE_FRM_T_AGENT_DISCON; /* Set flags */ + flags = htonl(flags); memcpy(p, (char *)&flags, 4); p += 4; @@ -954,6 +960,7 @@ prepare_agentack(struct spoe_frame *frame) *p++ = SPOE_FRM_T_AGENT_ACK; /* Set flags */ + flags = htonl(flags); memcpy(p, (char *)&flags, 4); p += 4; diff --git a/doc/SPOE.txt b/doc/SPOE.txt index 756988f68..c34102a67 100644 --- a/doc/SPOE.txt +++ b/doc/SPOE.txt @@ -694,7 +694,12 @@ actions. KV-NAME : KV-VALUE : - FLAGS : 0 1 2-31 + FLAGS : + + Flags are a 32 bits field. They are encoded on 4 bytes in network byte + order, where the bit 0 is the LSB. + + 0 1 2-31 +---+---+----------+ | | A | | | F | B | | diff --git a/src/flt_spoe.c b/src/flt_spoe.c index cc6c55e29..4e27c63b2 100644 --- a/src/flt_spoe.c +++ b/src/flt_spoe.c @@ -399,6 +399,7 @@ spoe_prepare_hahello_frame(struct appctx *appctx, char *frame, size_t size) *p++ = SPOE_FRM_T_HAPROXY_HELLO; /* Set flags */ + flags = htonl(flags); memcpy(p, (char *)&flags, 4); p += 4; @@ -488,6 +489,7 @@ spoe_prepare_hadiscon_frame(struct appctx *appctx, char *frame, size_t size) *p++ = SPOE_FRM_T_HAPROXY_DISCON; /* Set flags */ + flags = htonl(flags); memcpy(p, (char *)&flags, 4); p += 4; @@ -559,6 +561,7 @@ spoe_prepare_hanotify_frame(struct appctx *appctx, struct spoe_context *ctx, *p++ = SPOE_FRM_T_HAPROXY_NOTIFY; /* Set flags */ + flags = htonl(flags); memcpy(p, (char *)&flags, 4); p += 4; @@ -615,6 +618,7 @@ spoe_prepare_hafrag_frame(struct appctx *appctx, struct spoe_context *ctx, *p++ = SPOE_FRM_T_UNSET; /* Set flags */ + flags = htonl(flags); memcpy(p, (char *)&flags, 4); p += 4; @@ -669,6 +673,7 @@ spoe_handle_agenthello_frame(struct appctx *appctx, char *frame, size_t size) /* Retrieve flags */ memcpy((char *)&flags, p, 4); + flags = ntohl(flags); p += 4; /* Fragmentation is not supported for HELLO frame */ @@ -852,6 +857,7 @@ spoe_handle_agentdiscon_frame(struct appctx *appctx, char *frame, size_t size) /* Retrieve flags */ memcpy((char *)&flags, p, 4); + flags = ntohl(flags); p += 4; /* Fragmentation is not supported for DISCONNECT frame */ @@ -962,6 +968,7 @@ spoe_handle_agentack_frame(struct appctx *appctx, struct spoe_context **ctx, /* Retrieve flags */ memcpy((char *)&flags, p, 4); + flags = ntohl(flags); p += 4; /* Fragmentation is not supported for now */