Skip to content

Commit 77ae04d

Browse files
Merge pull request #25 from kosmas-valianos/constBuffer
const buffer for the pp2_parse_hdr func
2 parents d4cf637 + 809419b commit 77ae04d

File tree

2 files changed

+36
-21
lines changed

2 files changed

+36
-21
lines changed

src/proxy_protocol.c

Lines changed: 35 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -583,14 +583,18 @@ static uint32_t crctable[256] = {
583583
0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L
584584
};
585585

586-
static uint32_t crc32c(const uint8_t* buf, uint32_t len)
586+
static uint32_t crc32c_continue(uint32_t crc, const uint8_t* buf, uint32_t len)
587587
{
588-
uint32_t crc = 0xffffffff;
589588
while (len-- > 0)
590589
{
591590
crc = (crc >> 8) ^ crctable[(crc ^ (*buf++)) & 0xFF];
592591
}
593-
return crc ^ 0xffffffff;
592+
return crc;
593+
}
594+
595+
static uint32_t crc32c(const uint8_t* buf, uint32_t len)
596+
{
597+
return crc32c_continue(0xffffffff, buf, len) ^ 0xffffffff;
594598
}
595599

596600
static uint8_t *pp2_create_hdr(const pp_info_t *pp_info, uint16_t *pp2_hdr_len, int32_t *error)
@@ -844,13 +848,13 @@ uint8_t *pp_create_hdr(uint8_t version, const pp_info_t *pp_info, uint16_t *pp_h
844848
}
845849

846850
/* Verifies and parses a version 2 PROXY protocol header */
847-
static int32_t pp2_parse_hdr(uint8_t *buffer, uint32_t buffer_length, pp_info_t *pp_info)
851+
static int32_t pp2_parse_hdr(const uint8_t *buffer, uint32_t buffer_length, pp_info_t *pp_info)
848852
{
849853
const uint8_t *pp2_hdr = buffer;
850-
const proxy_hdr_v2_t *proxy_hdr_v2 = (proxy_hdr_v2_t*) buffer;
854+
const proxy_hdr_v2_t *proxy_hdr_v2 = (const proxy_hdr_v2_t*) buffer;
851855
uint8_t cmd, fam;
852856
uint16_t len = 0, tlv_vectors_len = 0;
853-
proxy_addr_t *addr = NULL;
857+
const proxy_addr_t *addr = NULL;
854858

855859
/* The next byte (the 13th one) is the protocol version and command */
856860
/* The highest four bits contains the version. Only \x2 is accepted */
@@ -924,7 +928,7 @@ static int32_t pp2_parse_hdr(uint8_t *buffer, uint32_t buffer_length, pp_info_t
924928
* - destination layer 4 address if any, in network byte order (port)
925929
*/
926930
buffer += sizeof(proxy_hdr_v2_t);
927-
addr = (proxy_addr_t*) buffer;
931+
addr = (const proxy_addr_t*) buffer;
928932
if (fam == AF_UNSPEC)
929933
{
930934
tlv_vectors_len = len;
@@ -977,7 +981,7 @@ static int32_t pp2_parse_hdr(uint8_t *buffer, uint32_t buffer_length, pp_info_t
977981
/* Any TLV vector must be at least 3 bytes */
978982
while (tlv_vectors_len > sizeof_pp2_tlv_t)
979983
{
980-
pp2_tlv_t *pp2_tlv = (pp2_tlv_t*) buffer;
984+
const pp2_tlv_t *pp2_tlv = (const pp2_tlv_t*) buffer;
981985
uint16_t pp2_tlv_len = pp2_tlv->length_hi << 8 | pp2_tlv->length_lo;
982986
uint16_t pp2_tlv_offset = sizeof_pp2_tlv_t + pp2_tlv_len;
983987
if (pp2_tlv_offset > tlv_vectors_len)
@@ -996,7 +1000,9 @@ static int32_t pp2_parse_hdr(uint8_t *buffer, uint32_t buffer_length, pp_info_t
9961000
break;
9971001
case PP2_TYPE_CRC32C: /* 32-bit number */
9981002
{
999-
uint32_t crc32c_chksum, crc32c_calculated;
1003+
uint32_t crc32c_chksum, crc32c_calculated, crc;
1004+
const uint8_t zeros[4] = {0, 0, 0, 0};
1005+
uint32_t total_hdr_len, offset_to_chksum_value, after_chksum_offset;
10001006

10011007
if (pp2_tlv_len != sizeof(uint32_t))
10021008
{
@@ -1006,11 +1012,20 @@ static int32_t pp2_parse_hdr(uint8_t *buffer, uint32_t buffer_length, pp_info_t
10061012
/* Received CRC32c checksum */
10071013
memcpy(&crc32c_chksum, pp2_tlv->value, pp2_tlv_len);
10081014

1009-
/* Calculate the CRC32c checksum value of the whole PROXY header */
1010-
memset(pp2_tlv->value, 0, pp2_tlv_len);
1011-
crc32c_calculated = crc32c(pp2_hdr, sizeof(proxy_hdr_v2_t) + len);
1015+
/* Calculate the CRC32c checksum value of the whole PROXY header.
1016+
* The checksum is computed with the checksum field treated as zeros.
1017+
* Instead of zeroing the field in the buffer, compute CRC in 3 segments:
1018+
* before the checksum value, 4 zero bytes, after the checksum value. */
1019+
total_hdr_len = sizeof(proxy_hdr_v2_t) + len;
1020+
offset_to_chksum_value = (const uint8_t*)pp2_tlv->value - pp2_hdr;
1021+
after_chksum_offset = offset_to_chksum_value + sizeof(uint32_t);
1022+
1023+
crc = crc32c_continue(0xffffffff, pp2_hdr, offset_to_chksum_value);
1024+
crc = crc32c_continue(crc, zeros, sizeof(uint32_t));
1025+
crc = crc32c_continue(crc, pp2_hdr + after_chksum_offset, total_hdr_len - after_chksum_offset);
1026+
crc32c_calculated = crc ^ 0xffffffff;
10121027

1013-
/* Verify that the calculated CRC32c checksum is the same as the received CRC32c checksum*/
1028+
/* Verify that the calculated CRC32c checksum is the same as the received CRC32c checksum */
10141029
if (memcmp(&crc32c_chksum, &crc32c_calculated, 4))
10151030
{
10161031
return -ERR_PP2_TYPE_CRC32C;
@@ -1037,7 +1052,7 @@ static int32_t pp2_parse_hdr(uint8_t *buffer, uint32_t buffer_length, pp_info_t
10371052
break;
10381053
case PP2_TYPE_SSL:
10391054
{
1040-
pp2_tlv_ssl_t *pp2_tlv_ssl = (pp2_tlv_ssl_t*) pp2_tlv->value;
1055+
const pp2_tlv_ssl_t *pp2_tlv_ssl = (const pp2_tlv_ssl_t*) pp2_tlv->value;
10411056
uint16_t pp2_tlvs_ssl_len = 0, pp2_sub_tlv_offset = 0;
10421057
uint8_t tlv_ssl_version_found = 0;
10431058

@@ -1050,7 +1065,7 @@ static int32_t pp2_parse_hdr(uint8_t *buffer, uint32_t buffer_length, pp_info_t
10501065
pp2_tlvs_ssl_len = pp2_tlv_len - sizeof(pp2_tlv_ssl->client) - sizeof(pp2_tlv_ssl->verify);
10511066
while (pp2_sub_tlv_offset < pp2_tlvs_ssl_len)
10521067
{
1053-
pp2_tlv_t *pp2_sub_tlv_ssl = (pp2_tlv_t*) ((uint8_t*) pp2_tlv_ssl->sub_tlv + pp2_sub_tlv_offset);
1068+
const pp2_tlv_t *pp2_sub_tlv_ssl = (const pp2_tlv_t*) ((const uint8_t*) pp2_tlv_ssl->sub_tlv + pp2_sub_tlv_offset);
10541069
uint16_t pp2_sub_tlv_ssl_len = pp2_sub_tlv_ssl->length_hi << 8 | pp2_sub_tlv_ssl->length_lo;
10551070
switch (pp2_sub_tlv_ssl->type)
10561071
{
@@ -1090,12 +1105,12 @@ static int32_t pp2_parse_hdr(uint8_t *buffer, uint32_t buffer_length, pp_info_t
10901105
break;
10911106
case PP2_TYPE_AWS:
10921107
{
1093-
pp2_tlv_aws_t *pp2_tlv_aws;
1108+
const pp2_tlv_aws_t *pp2_tlv_aws;
10941109
if (pp2_tlv_len < sizeof(pp2_tlv_aws_t))
10951110
{
10961111
return -ERR_PP2_TYPE_AWS;
10971112
}
1098-
pp2_tlv_aws = (pp2_tlv_aws_t*) pp2_tlv->value;
1113+
pp2_tlv_aws = (const pp2_tlv_aws_t*) pp2_tlv->value;
10991114
/* Connection is done through Private Link/Interface VPC endpoint */
11001115
if (pp2_tlv_aws->type == PP2_SUBTYPE_AWS_VPCE_ID) /* US-ASCII */
11011116
{
@@ -1109,12 +1124,12 @@ static int32_t pp2_parse_hdr(uint8_t *buffer, uint32_t buffer_length, pp_info_t
11091124
}
11101125
case PP2_TYPE_AZURE:
11111126
{
1112-
pp2_tlv_azure_t *pp2_tlv_azure;
1127+
const pp2_tlv_azure_t *pp2_tlv_azure;
11131128
if (pp2_tlv_len < sizeof(pp2_tlv_azure_t))
11141129
{
11151130
return -ERR_PP2_TYPE_AZURE;
11161131
}
1117-
pp2_tlv_azure = (pp2_tlv_azure_t*) pp2_tlv->value;
1132+
pp2_tlv_azure = (const pp2_tlv_azure_t*) pp2_tlv->value;
11181133
/* Connection is done through Private Link service */
11191134
if (pp2_tlv_azure->type == PP2_SUBTYPE_AZURE_PRIVATEENDPOINT_LINKID) /* 32-bit number */
11201135
{
@@ -1309,7 +1324,7 @@ static int32_t pp1_parse_hdr(const uint8_t *buffer, uint32_t buffer_length, pp_i
13091324
return pp1_hdr_len;
13101325
}
13111326

1312-
int32_t pp_parse_hdr(uint8_t *buffer, uint32_t buffer_length, pp_info_t *pp_info)
1327+
int32_t pp_parse_hdr(const uint8_t *buffer, uint32_t buffer_length, pp_info_t *pp_info)
13131328
{
13141329
memset(pp_info, 0, sizeof(*pp_info));
13151330
if (buffer_length >= 16 && !memcmp(buffer, PP2_SIG, 12))

src/proxy_protocol.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,6 @@ uint8_t *pp_create_hdr(uint8_t version, const pp_info_t *pp_info, uint16_t *pp_h
211211
* == 0 No PROXY protocol header found
212212
* < 0 Error occurred. Optionally, pp_strerror() with that value can be used to get a descriptive message
213213
*/
214-
int32_t pp_parse_hdr(uint8_t *buffer, uint32_t buffer_length, pp_info_t *pp_info);
214+
int32_t pp_parse_hdr(const uint8_t *buffer, uint32_t buffer_length, pp_info_t *pp_info);
215215

216216
#endif

0 commit comments

Comments
 (0)