comparison src/event/quic/bpf/ngx_quic_reuseport_helper.c @ 8720:1a489587e1c8 quic

QUIC: fixed key extraction in bpf. In case of long header packets, dcid length was not read correctly. While there, macros to parse uint64 was fixed as well as format specifiers to print it in debug mode. Thanks to Gao Yan <gaoyan09@baidu.com>.
author Vladimir Homutov <vl@nginx.com>
date Mon, 15 Mar 2021 19:05:38 +0300
parents 7df607cb2d11
children a2fbae359828
comparison
equal deleted inserted replaced
8719:5cb5b568282b 8720:1a489587e1c8
56 #define ngx_quic_parse_uint64(p) \ 56 #define ngx_quic_parse_uint64(p) \
57 (((__u64)(p)[0] << 56) | \ 57 (((__u64)(p)[0] << 56) | \
58 ((__u64)(p)[1] << 48) | \ 58 ((__u64)(p)[1] << 48) | \
59 ((__u64)(p)[2] << 40) | \ 59 ((__u64)(p)[2] << 40) | \
60 ((__u64)(p)[3] << 32) | \ 60 ((__u64)(p)[3] << 32) | \
61 (p)[4] << 24 | \ 61 ((__u64)(p)[4] << 24) | \
62 (p)[5] << 16 | \ 62 ((__u64)(p)[5] << 16) | \
63 (p)[6] << 8 | \ 63 ((__u64)(p)[6] << 8) | \
64 (p)[7]) 64 ((__u64)(p)[7]))
65 65
66 /* 66 /*
67 * actual map object is created by the "bpf" system call, 67 * actual map object is created by the "bpf" system call,
68 * all pointers to this variable are replaced by the bpf loader 68 * all pointers to this variable are replaced by the bpf loader
69 */ 69 */
80 80
81 start = ctx->data; 81 start = ctx->data;
82 end = (unsigned char *) ctx->data_end; 82 end = (unsigned char *) ctx->data_end;
83 offset = 0; 83 offset = 0;
84 84
85 advance_data(sizeof(struct udphdr)); /* skip UDP header */ 85 advance_data(sizeof(struct udphdr)); /* data at UDP header */
86 advance_data(1); /* QUIC flags */ 86 advance_data(1); /* data at QUIC flags */
87 87
88 if (data[0] & NGX_QUIC_PKT_LONG) { 88 if (data[0] & NGX_QUIC_PKT_LONG) {
89 89
90 advance_data(4); /* skip QUIC version */ 90 advance_data(4); /* data at QUIC version */
91 advance_data(1); /* data at DCID len */
92
91 len = data[0]; /* read DCID length */ 93 len = data[0]; /* read DCID length */
92 94
93 if (len < 8) { 95 if (len < 8) {
94 /* it's useless to search for key in such short DCID */ 96 /* it's useless to search for key in such short DCID */
95 return SK_PASS; 97 return SK_PASS;
96 } 98 }
97
98 advance_data(1); /* skip DCID len */
99 99
100 } else { 100 } else {
101 len = NGX_QUIC_SERVER_CID_LEN; 101 len = NGX_QUIC_SERVER_CID_LEN;
102 } 102 }
103 103
113 113
114 rc = bpf_sk_select_reuseport(ctx, &ngx_quic_sockmap, &key, 0); 114 rc = bpf_sk_select_reuseport(ctx, &ngx_quic_sockmap, &key, 0);
115 115
116 switch (rc) { 116 switch (rc) {
117 case 0: 117 case 0:
118 debugmsg("nginx quic socket selected by key 0x%x", key); 118 debugmsg("nginx quic socket selected by key 0x%llx", key);
119 return SK_PASS; 119 return SK_PASS;
120 120
121 /* kernel returns positive error numbers, errno.h defines positive */ 121 /* kernel returns positive error numbers, errno.h defines positive */
122 case -ENOENT: 122 case -ENOENT:
123 debugmsg("nginx quic default route for key 0x%x", key); 123 debugmsg("nginx quic default route for key 0x%llx", key);
124 /* let the default reuseport logic decide which socket to choose */ 124 /* let the default reuseport logic decide which socket to choose */
125 return SK_PASS; 125 return SK_PASS;
126 126
127 default: 127 default:
128 debugmsg("nginx quic bpf_sk_select_reuseport err: %d key 0x%x", 128 debugmsg("nginx quic bpf_sk_select_reuseport err: %d key 0x%llx",
129 rc, key); 129 rc, key);
130 goto failed; 130 goto failed;
131 } 131 }
132 132
133 failed: 133 failed: