Skip to content

Commit e075081

Browse files
Add support for alignment, padding using a NOOP TLV when creating v2 header
1 parent 4563afc commit e075081

3 files changed

Lines changed: 46 additions & 12 deletions

File tree

src/proxy_protocol.c

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -644,6 +644,7 @@ uint8_t *pp2_create_hdr(const pp_info_t *pp_info, uint16_t *pp2_hdr_len, int32_t
644644
/* Calculate the total length */
645645
uint16_t len = proxy_addr_len;
646646
const tlv_array_t *tlv_array = &pp_info->pp2_info.tlv_array;
647+
uint16_t padding_bytes = 0;
647648
uint32_t i;
648649
for (i = 0; i < tlv_array->len; i++)
649650
{
@@ -654,10 +655,20 @@ uint8_t *pp2_create_hdr(const pp_info_t *pp_info, uint16_t *pp2_hdr_len, int32_t
654655
{
655656
len += sizeof_pp2_tlv_t + sizeof(uint32_t);
656657
}
658+
*pp2_hdr_len = sizeof(proxy_hdr_v2_t) + len;
659+
if (pp_info->pp2_info.align_padding > 1)
660+
{
661+
uint16_t pow = 1 << pp_info->pp2_info.align_padding;
662+
if (*pp2_hdr_len % pow)
663+
{
664+
padding_bytes = (*pp2_hdr_len - sizeof_pp2_tlv_t) % pow;
665+
len += sizeof_pp2_tlv_t + padding_bytes;
666+
*pp2_hdr_len = sizeof(proxy_hdr_v2_t) + len;
667+
}
668+
}
657669
proxy_hdr_v2.len = htons(len);
658670

659671
/* Create the PROXY protocol header */
660-
*pp2_hdr_len = sizeof(proxy_hdr_v2_t) + len;
661672
uint8_t *pp2_hdr = malloc(*pp2_hdr_len);
662673
if (!pp2_hdr)
663674
{
@@ -677,6 +688,18 @@ uint8_t *pp2_create_hdr(const pp_info_t *pp_info, uint16_t *pp2_hdr_len, int32_t
677688
memcpy(pp2_hdr + index, tlv_array->tlvs[i], tlv_len);
678689
index += tlv_len;
679690
}
691+
if (pp_info->pp2_info.align_padding > 1)
692+
{
693+
pp2_tlv_t tlv = {
694+
.type = PP2_TYPE_NOOP,
695+
.length_hi = padding_bytes >> 8,
696+
.length_lo = padding_bytes & 0x00ff
697+
};
698+
memcpy(pp2_hdr + index, &tlv, sizeof_pp2_tlv_t);
699+
index += sizeof_pp2_tlv_t;
700+
memset(pp2_hdr + index, 0, padding_bytes);
701+
index += padding_bytes;
702+
}
680703
if (pp_info->pp2_info.crc32c)
681704
{
682705
pp2_tlv_t tlv = { .type = PP2_TYPE_CRC32C, .length_lo = sizeof(uint32_t) };

src/proxy_protocol.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,16 @@ typedef struct
8080

8181
typedef struct
8282
{
83-
uint8_t local; /* 1: LOCAL 0: PROXY */
83+
uint8_t local; /* 1: LOCAL 0: PROXY */
84+
/*
85+
* In creation
86+
* > 1: The power of 2 in which the header will be aligned using a NOOP TLV.
87+
* Example: 2 => 2^2 => 4 => Append enough bytes to the header using the NOOP TLV so that size_of_hdr % 4 becomes 0
88+
* <= 1: No alignment, padding
89+
* In parsing:
90+
* Ignored
91+
*/
92+
uint8_t align_padding;
8493
pp2_ssl_info_t pp2_ssl_info;
8594
tlv_array_t tlv_array;
8695
/*

tests/test.c

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,7 @@ int main()
423423
.pp_info_out_expected = tests[8].pp_info_in,
424424
},
425425
{
426-
.name = "v2 PROXY protocol header: create and parse - PROXY, TCP over IPv4. TLVs: "
426+
.name = "v2 PROXY protocol header: create and parse - PROXY, TCP over IPv4. Aligned, padded. TLVs: "
427427
"PP2_TYPE_SSL, PP2_SUBTYPE_SSL_VERSION, PP2_SUBTYPE_SSL_CN, PP2_SUBTYPE_SSL_CIPHER,"
428428
"PP2_SUBTYPE_SSL_SIG_ALG, PP2_SUBTYPE_SSL_KEY_ALG, PP2_TYPE_AWS(PP2_SUBTYPE_AWS_VPCE_ID), PP2_TYPE_CRC32C",
429429
.version = 2,
@@ -435,13 +435,14 @@ int main()
435435
.src_port = 42332,
436436
.dst_port = 8080,
437437
.pp2_info = {
438-
.crc32c = 1,
438+
.align_padding = 2,
439439
.pp2_ssl_info = {
440440
.ssl = 1,
441441
.cert_in_connection = 1,
442442
.cert_in_session = 1,
443443
.cert_verified = 1,
444-
}
444+
},
445+
.crc32c = 1
445446
}
446447
},
447448
.add_tlvs = {
@@ -452,9 +453,8 @@ int main()
452453
},
453454
{
454455
.type = PP2_SUBTYPE_SSL_CN,
455-
.value_len = 11,
456-
/* example.com */
457-
.value = (uint8_t*) "\x65\x78\x61\x6d\x70\x6c\x65\x2e\x63\x6f\x6d"
456+
.value_len = 18,
457+
.value = (uint8_t*) "proxy-protocol.com"
458458
},
459459
{
460460
.type = PP2_SUBTYPE_SSL_CIPHER,
@@ -480,7 +480,7 @@ int main()
480480
{
481481
.type = PP2_TYPE_CRC32C,
482482
.value_len = 4,
483-
.value = (uint8_t*) "\x72\x45\x29\xd8"
483+
.value = (uint8_t*) "\x75\x40\xf1\x2f"
484484
},
485485
},
486486
.pp_info_out_expected = tests[9].pp_info_in,
@@ -516,8 +516,7 @@ int main()
516516
{
517517
.type = PP2_SUBTYPE_SSL_CN,
518518
.value_len = 11,
519-
/* example.com */
520-
.value = (uint8_t*) "\x65\x78\x61\x6d\x70\x6c\x65\x2e\x63\x6f\x6d"
519+
.value = (uint8_t*) "example.com"
521520
},
522521
{
523522
.type = PP2_SUBTYPE_SSL_CIPHER,
@@ -561,6 +560,7 @@ int main()
561560
else
562561
{
563562
uint16_t pp_hdr_len;
563+
uint16_t pow = 1 << tests[i].pp_info_in.pp2_info.align_padding;
564564
int32_t error;
565565

566566
if (tests[i].add_tlvs[0].type)
@@ -576,7 +576,9 @@ int main()
576576

577577
uint8_t *pp_hdr = pp_create_hdr(tests[i].version, &tests[i].pp_info_in, &pp_hdr_len, &error);
578578
pp_info_clear(&tests[i].pp_info_in);
579-
if (!pp_hdr || error != ERR_NULL)
579+
if (!pp_hdr
580+
|| error != ERR_NULL
581+
|| (pow > 1 && pp_hdr_len % pow))
580582
{
581583
printf("FAILED\n");
582584
pp_info_clear(&pp_info_out);

0 commit comments

Comments
 (0)