};
/* 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_ADDR_LEN_UNSPEC 0
-#define PP2_ADDR_LEN_INET 12
-#define PP2_ADDR_LEN_INET6 36
-#define PP2_ADDR_LEN_UNIX 216
-
-#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_SIGNATURE "\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A"
+#define PP2_SIGNATURE_LEN 12
+#define PP2_HEADER_LEN 16
+
+/* ver_cmd byte */
+#define PP2_CMD_LOCAL 0x00
+#define PP2_CMD_PROXY 0x01
+#define PP2_CMD_MASK 0x0F
+
+#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
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;
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;
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;
}
}
#endif
- hdr_p->len = htons((uint16_t)(ret - PP2_HEADER_LEN));
+ hdr->len = htons((uint16_t)(ret - PP2_HEADER_LEN));
return ret;
}