diff --git a/include/types/connection.h b/include/types/connection.h index 4779bc037..2ae16d771 100644 --- a/include/types/connection.h +++ b/include/types/connection.h @@ -268,53 +268,63 @@ struct connection { }; /* proxy protocol v2 definitions */ -#define PP2_SIGNATURE_LEN 12 -#define PP2_HEADER_LEN 16 -#define PP2_VERSION 0x20 -#define PP2_CMD_LOCAL 0x00 -#define PP2_CMD_PROXY 0x01 -#define PP2_FAM_UNSPEC 0x00 -#define PP2_FAM_INET 0x10 -#define PP2_FAM_INET6 0x20 -#define PP2_FAM_UNIX 0x30 -#define PP2_TRANS_UNSPEC 0x00 -#define PP2_TRANS_STREAM 0x01 -#define PP2_TRANS_DGRAM 0x02 +#define PP2_SIGNATURE "\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A" +#define PP2_SIGNATURE_LEN 12 +#define PP2_HEADER_LEN 16 -#define PP2_ADDR_LEN_UNSPEC 0 -#define PP2_ADDR_LEN_INET 12 -#define PP2_ADDR_LEN_INET6 36 -#define PP2_ADDR_LEN_UNIX 216 +/* ver_cmd byte */ +#define PP2_CMD_LOCAL 0x00 +#define PP2_CMD_PROXY 0x01 +#define PP2_CMD_MASK 0x0F -#define PP2_HDR_LEN_UNSPEC (PP2_HEADER_LEN + PP2_ADDR_LEN_UNSPEC) -#define PP2_HDR_LEN_INET (PP2_HEADER_LEN + PP2_ADDR_LEN_INET) -#define PP2_HDR_LEN_INET6 (PP2_HEADER_LEN + PP2_ADDR_LEN_INET6) -#define PP2_HDR_LEN_UNIX (PP2_HEADER_LEN + PP2_ADDR_LEN_UNIX) +#define PP2_VERSION 0x20 +#define PP2_VERSION_MASK 0xF0 + +/* fam byte */ +#define PP2_TRANS_UNSPEC 0x00 +#define PP2_TRANS_STREAM 0x01 +#define PP2_TRANS_DGRAM 0x02 +#define PP2_TRANS_MASK 0x0F + +#define PP2_FAM_UNSPEC 0x00 +#define PP2_FAM_INET 0x10 +#define PP2_FAM_INET6 0x20 +#define PP2_FAM_UNIX 0x30 +#define PP2_FAM_MASK 0xF0 + +#define PP2_ADDR_LEN_UNSPEC (0) +#define PP2_ADDR_LEN_INET (4 + 4 + 2 + 2) +#define PP2_ADDR_LEN_INET6 (16 + 16 + 2 + 2) +#define PP2_ADDR_LEN_UNIX (108 + 108) + +#define PP2_HDR_LEN_UNSPEC (PP2_HEADER_LEN + PP2_ADDR_LEN_UNSPEC) +#define PP2_HDR_LEN_INET (PP2_HEADER_LEN + PP2_ADDR_LEN_INET) +#define PP2_HDR_LEN_INET6 (PP2_HEADER_LEN + PP2_ADDR_LEN_INET6) +#define PP2_HDR_LEN_UNIX (PP2_HEADER_LEN + PP2_ADDR_LEN_UNIX) struct proxy_hdr_v2 { uint8_t sig[12]; /* hex 0D 0A 0D 0A 00 0D 0A 51 55 49 54 0A */ - uint8_t cmd; /* protocol version and command */ + uint8_t ver_cmd; /* protocol version and command */ uint8_t fam; /* protocol family and transport */ uint16_t len; /* number of following bytes part of the header */ -}; - -union proxy_addr { - struct { /* for TCP/UDP over IPv4, len = 12 */ - uint32_t src_addr; - uint32_t dst_addr; - uint16_t src_port; - uint16_t dst_port; - } ipv4_addr; - struct { /* for TCP/UDP over IPv6, len = 36 */ - uint8_t src_addr[16]; - uint8_t dst_addr[16]; - uint16_t src_port; - uint16_t dst_port; - } ipv6_addr; - struct { /* for AF_UNIX sockets, len = 216 */ - uint8_t src_addr[108]; - uint8_t dst_addr[108]; - } unix_addr; + union { + struct { /* for TCP/UDP over IPv4, len = 12 */ + uint32_t src_addr; + uint32_t dst_addr; + uint16_t src_port; + uint16_t dst_port; + } ip4; + struct { /* for TCP/UDP over IPv6, len = 36 */ + uint8_t src_addr[16]; + uint8_t dst_addr[16]; + uint16_t src_port; + uint16_t dst_port; + } ip6; + struct { /* for AF_UNIX sockets, len = 216 */ + uint8_t src_addr[108]; + uint8_t dst_addr[108]; + } unx; + } addr; }; #define PP2_TYPE_SSL 0x20 diff --git a/src/connection.c b/src/connection.c index 93db7e5ac..454c1c174 100644 --- a/src/connection.c +++ b/src/connection.c @@ -558,10 +558,9 @@ static int make_tlv(char *dest, int dest_len, char type, uint16_t length, char * int make_proxy_line_v2(char *buf, int buf_len, struct server *srv, struct connection *remote) { - const char pp2_signature[12] = {0x0D, 0x0A, 0x0D, 0x0A, 0x00, 0x0D, 0x0A, 0x51, 0x55, 0x49, 0x54, 0x0A}; + const char pp2_signature[] = PP2_SIGNATURE; int ret = 0; - struct proxy_hdr_v2 *hdr_p = (struct proxy_hdr_v2 *)buf; - union proxy_addr *addr_p = (union proxy_addr *)(buf + PP2_HEADER_LEN); + struct proxy_hdr_v2 *hdr = (struct proxy_hdr_v2 *)buf; struct sockaddr_storage null_addr = {0}; struct sockaddr_storage *src = &null_addr; struct sockaddr_storage *dst = &null_addr; @@ -574,7 +573,7 @@ int make_proxy_line_v2(char *buf, int buf_len, struct server *srv, struct connec if (buf_len < PP2_HEADER_LEN) return 0; - memcpy(hdr_p->sig, pp2_signature, PP2_SIGNATURE_LEN); + memcpy(hdr->sig, pp2_signature, PP2_SIGNATURE_LEN); if (remote) { src = &remote->addr.from; @@ -583,30 +582,30 @@ int make_proxy_line_v2(char *buf, int buf_len, struct server *srv, struct connec if (src && dst && src->ss_family == dst->ss_family && src->ss_family == AF_INET) { if (buf_len < PP2_HDR_LEN_INET) return 0; - hdr_p->cmd = PP2_VERSION | PP2_CMD_PROXY; - hdr_p->fam = PP2_FAM_INET | PP2_TRANS_STREAM; - addr_p->ipv4_addr.src_addr = ((struct sockaddr_in *)src)->sin_addr.s_addr; - addr_p->ipv4_addr.dst_addr = ((struct sockaddr_in *)dst)->sin_addr.s_addr; - addr_p->ipv4_addr.src_port = ((struct sockaddr_in *)src)->sin_port; - addr_p->ipv4_addr.dst_port = ((struct sockaddr_in *)dst)->sin_port; + hdr->ver_cmd = PP2_VERSION | PP2_CMD_PROXY; + hdr->fam = PP2_FAM_INET | PP2_TRANS_STREAM; + hdr->addr.ip4.src_addr = ((struct sockaddr_in *)src)->sin_addr.s_addr; + hdr->addr.ip4.dst_addr = ((struct sockaddr_in *)dst)->sin_addr.s_addr; + hdr->addr.ip4.src_port = ((struct sockaddr_in *)src)->sin_port; + hdr->addr.ip4.dst_port = ((struct sockaddr_in *)dst)->sin_port; ret = PP2_HDR_LEN_INET; } else if (src && dst && src->ss_family == dst->ss_family && src->ss_family == AF_INET6) { if (buf_len < PP2_HDR_LEN_INET6) return 0; - hdr_p->cmd = PP2_VERSION | PP2_CMD_PROXY; - hdr_p->fam = PP2_FAM_INET6 | PP2_TRANS_STREAM; - memcpy(addr_p->ipv6_addr.src_addr, &((struct sockaddr_in6 *)src)->sin6_addr, 16); - memcpy(addr_p->ipv6_addr.dst_addr, &((struct sockaddr_in6 *)dst)->sin6_addr, 16); - addr_p->ipv6_addr.src_port = ((struct sockaddr_in6 *)src)->sin6_port; - addr_p->ipv6_addr.dst_port = ((struct sockaddr_in6 *)dst)->sin6_port; + hdr->ver_cmd = PP2_VERSION | PP2_CMD_PROXY; + hdr->fam = PP2_FAM_INET6 | PP2_TRANS_STREAM; + memcpy(hdr->addr.ip6.src_addr, &((struct sockaddr_in6 *)src)->sin6_addr, 16); + memcpy(hdr->addr.ip6.dst_addr, &((struct sockaddr_in6 *)dst)->sin6_addr, 16); + hdr->addr.ip6.src_port = ((struct sockaddr_in6 *)src)->sin6_port; + hdr->addr.ip6.dst_port = ((struct sockaddr_in6 *)dst)->sin6_port; ret = PP2_HDR_LEN_INET6; } else { if (buf_len < PP2_HDR_LEN_UNSPEC) return 0; - hdr_p->cmd = PP2_VERSION | PP2_CMD_LOCAL; - hdr_p->fam = PP2_FAM_UNSPEC | PP2_TRANS_UNSPEC; + hdr->ver_cmd = PP2_VERSION | PP2_CMD_LOCAL; + hdr->fam = PP2_FAM_UNSPEC | PP2_TRANS_UNSPEC; ret = PP2_HDR_LEN_UNSPEC; } @@ -643,7 +642,7 @@ int make_proxy_line_v2(char *buf, int buf_len, struct server *srv, struct connec } #endif - hdr_p->len = htons((uint16_t)(ret - PP2_HEADER_LEN)); + hdr->len = htons((uint16_t)(ret - PP2_HEADER_LEN)); return ret; }