comparison src/event/ngx_event_udp.c @ 8384:c61fcdc1b8e3 quic

UDP: extended datagram context. Sometimes it is required to process datagram properties at higher level (i.e. QUIC is interested in source address which may change and IP options). The patch adds ngx_udp_dgram_t structure used to pass packet-related information in c->udp.
author Vladimir Homutov <vl@nginx.com>
date Fri, 02 Apr 2021 18:58:19 +0300
parents 385d511b5064
children 9ce6d80df113
comparison
equal deleted inserted replaced
8383:385d511b5064 8384:c61fcdc1b8e3
27 ssize_t n; 27 ssize_t n;
28 ngx_str_t key; 28 ngx_str_t key;
29 ngx_buf_t buf; 29 ngx_buf_t buf;
30 ngx_log_t *log; 30 ngx_log_t *log;
31 ngx_err_t err; 31 ngx_err_t err;
32 socklen_t socklen, local_socklen; 32 socklen_t local_socklen;
33 ngx_event_t *rev, *wev; 33 ngx_event_t *rev, *wev;
34 struct iovec iov[1]; 34 struct iovec iov[1];
35 struct msghdr msg; 35 struct msghdr msg;
36 ngx_sockaddr_t sa, lsa; 36 ngx_sockaddr_t sa, lsa;
37 struct sockaddr *sockaddr, *local_sockaddr; 37 ngx_udp_dgram_t dgram;
38 struct sockaddr *local_sockaddr;
38 ngx_listening_t *ls; 39 ngx_listening_t *ls;
39 ngx_event_conf_t *ecf; 40 ngx_event_conf_t *ecf;
40 ngx_connection_t *c, *lc; 41 ngx_connection_t *c, *lc;
41 static u_char buffer[65535]; 42 static u_char buffer[65535];
42 43
129 "recvmsg() truncated data"); 130 "recvmsg() truncated data");
130 continue; 131 continue;
131 } 132 }
132 #endif 133 #endif
133 134
134 sockaddr = msg.msg_name; 135 dgram.sockaddr = msg.msg_name;
135 socklen = msg.msg_namelen; 136 dgram.socklen = msg.msg_namelen;
136 137
137 if (socklen > (socklen_t) sizeof(ngx_sockaddr_t)) { 138 if (dgram.socklen > (socklen_t) sizeof(ngx_sockaddr_t)) {
138 socklen = sizeof(ngx_sockaddr_t); 139 dgram.socklen = sizeof(ngx_sockaddr_t);
139 } 140 }
140 141
141 if (socklen == 0) { 142 if (dgram.socklen == 0) {
142 143
143 /* 144 /*
144 * on Linux recvmsg() returns zero msg_namelen 145 * on Linux recvmsg() returns zero msg_namelen
145 * when receiving packets from unbound AF_UNIX sockets 146 * when receiving packets from unbound AF_UNIX sockets
146 */ 147 */
147 148
148 socklen = sizeof(struct sockaddr); 149 dgram.socklen = sizeof(struct sockaddr);
149 ngx_memzero(&sa, sizeof(struct sockaddr)); 150 ngx_memzero(&sa, sizeof(struct sockaddr));
150 sa.sockaddr.sa_family = ls->sockaddr->sa_family; 151 sa.sockaddr.sa_family = ls->sockaddr->sa_family;
151 } 152 }
152 153
153 local_sockaddr = ls->sockaddr; 154 local_sockaddr = ls->sockaddr;
221 } 222 }
222 } 223 }
223 224
224 #endif 225 #endif
225 226
226 key.data = (u_char *) sockaddr; 227 key.data = (u_char *) dgram.sockaddr;
227 key.len = socklen; 228 key.len = dgram.socklen;
228 229
229 #if (NGX_HAVE_UNIX_DOMAIN) 230 #if (NGX_HAVE_UNIX_DOMAIN)
230 231
231 if (sockaddr->sa_family == AF_UNIX) { 232 if (dgram.sockaddr->sa_family == AF_UNIX) {
232 struct sockaddr_un *saun = (struct sockaddr_un *) sockaddr; 233 struct sockaddr_un *saun = (struct sockaddr_un *) dgram.sockaddr;
233 234
234 if (socklen <= (socklen_t) offsetof(struct sockaddr_un, sun_path) 235 if (dgram.socklen <= (socklen_t) offsetof(struct sockaddr_un,
236 sun_path)
235 || saun->sun_path[0] == '\0') 237 || saun->sun_path[0] == '\0')
236 { 238 {
237 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0, 239 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0,
238 "unbound unix socket"); 240 "unbound unix socket");
239 key.len = 0; 241 key.len = 0;
266 268
267 c->log->handler = handler; 269 c->log->handler = handler;
268 } 270 }
269 #endif 271 #endif
270 272
271 #if (NGX_QUIC)
272 if (ls->quic) {
273 c->socklen = socklen;
274 ngx_memcpy(c->sockaddr, sockaddr, socklen);
275 }
276 #endif
277
278 ngx_memzero(&buf, sizeof(ngx_buf_t)); 273 ngx_memzero(&buf, sizeof(ngx_buf_t));
279 274
280 buf.pos = buffer; 275 buf.pos = buffer;
281 buf.last = buffer + n; 276 buf.last = buffer + n;
282 buf.start = buf.pos; 277 buf.start = buf.pos;
283 buf.end = buffer + sizeof(buffer); 278 buf.end = buffer + sizeof(buffer);
284 279
285 rev = c->read; 280 rev = c->read;
286 281
287 c->udp->buffer = &buf; 282 dgram.buffer = &buf;
283
284 c->udp->dgram = &dgram;
288 285
289 rev->ready = 1; 286 rev->ready = 1;
290 rev->active = 0; 287 rev->active = 0;
291 288
292 rev->handler(rev); 289 rev->handler(rev);
293 290
294 if (c->udp) { 291 if (c->udp) {
295 c->udp->buffer = NULL; 292 c->udp->dgram = NULL;
296 } 293 }
297 294
298 rev->ready = 0; 295 rev->ready = 0;
299 rev->active = 1; 296 rev->active = 1;
300 297
313 return; 310 return;
314 } 311 }
315 312
316 c->shared = 1; 313 c->shared = 1;
317 c->type = SOCK_DGRAM; 314 c->type = SOCK_DGRAM;
318 c->socklen = socklen; 315 c->socklen = dgram.socklen;
319 316
320 #if (NGX_STAT_STUB) 317 #if (NGX_STAT_STUB)
321 (void) ngx_atomic_fetch_add(ngx_stat_active, 1); 318 (void) ngx_atomic_fetch_add(ngx_stat_active, 1);
322 #endif 319 #endif
323 320
325 if (c->pool == NULL) { 322 if (c->pool == NULL) {
326 ngx_close_accepted_udp_connection(c); 323 ngx_close_accepted_udp_connection(c);
327 return; 324 return;
328 } 325 }
329 326
330 len = socklen; 327 len = dgram.socklen;
331 328
332 #if (NGX_QUIC) 329 #if (NGX_QUIC)
333 if (ls->quic) { 330 if (ls->quic) {
334 len = NGX_SOCKADDRLEN; 331 len = NGX_SOCKADDRLEN;
335 } 332 }
339 if (c->sockaddr == NULL) { 336 if (c->sockaddr == NULL) {
340 ngx_close_accepted_udp_connection(c); 337 ngx_close_accepted_udp_connection(c);
341 return; 338 return;
342 } 339 }
343 340
344 ngx_memcpy(c->sockaddr, sockaddr, socklen); 341 ngx_memcpy(c->sockaddr, dgram.sockaddr, dgram.socklen);
345 342
346 log = ngx_palloc(c->pool, sizeof(ngx_log_t)); 343 log = ngx_palloc(c->pool, sizeof(ngx_log_t));
347 if (log == NULL) { 344 if (log == NULL) {
348 ngx_close_accepted_udp_connection(c); 345 ngx_close_accepted_udp_connection(c);
349 return; 346 return;
481 ngx_udp_shared_recv(ngx_connection_t *c, u_char *buf, size_t size) 478 ngx_udp_shared_recv(ngx_connection_t *c, u_char *buf, size_t size)
482 { 479 {
483 ssize_t n; 480 ssize_t n;
484 ngx_buf_t *b; 481 ngx_buf_t *b;
485 482
486 if (c->udp == NULL || c->udp->buffer == NULL) { 483 if (c->udp == NULL || c->udp->dgram == NULL) {
487 return NGX_AGAIN; 484 return NGX_AGAIN;
488 } 485 }
489 486
490 b = c->udp->buffer; 487 b = c->udp->dgram->buffer;
491 488
492 n = ngx_min(b->last - b->pos, (ssize_t) size); 489 n = ngx_min(b->last - b->pos, (ssize_t) size);
493 490
494 ngx_memcpy(buf, b->pos, n); 491 ngx_memcpy(buf, b->pos, n);
495 492
496 c->udp->buffer = NULL; 493 c->udp->dgram = NULL;
497 494
498 c->read->ready = 0; 495 c->read->ready = 0;
499 c->read->active = 1; 496 c->read->active = 1;
500 497
501 return n; 498 return n;