Ticket #1298: udp_session_reuse.diff
| File udp_session_reuse.diff, 14.0 KB (added by , 9 years ago) |
|---|
-
nginx-1.12.0/src/core/ngx_buf.c
diff --git a/nginx-1.12.0/src/core/ngx_buf.c b/nginx-1.12.0/src/core/ngx_buf.c old mode 100644 new mode 100755 index 1862a06..100e5ca
a b ngx_create_temp_buf(ngx_pool_t *pool, size_t size) 43 43 return b; 44 44 } 45 45 46 ngx_buf_t * 47 ngx_recreate_temp_buf(ngx_buf_t *b, ngx_pool_t *pool, size_t size) 48 { 49 if (b == NULL) { 50 return NULL; 51 } 52 53 if (b->start != NULL && ngx_pfree(pool, b->start) != NGX_OK) { 54 return NULL; 55 } 56 57 ngx_memzero(b, sizeof(ngx_buf_t)); 58 b->start = ngx_palloc(pool, size); 59 if (b->start == NULL) { 60 return NULL; 61 } 62 63 /* 64 * set by ngx_calloc_buf(): 65 * 66 * b->file_pos = 0; 67 * b->file_last = 0; 68 * b->file = NULL; 69 * b->shadow = NULL; 70 * b->tag = 0; 71 * and flags 72 */ 73 74 b->pos = b->start; 75 b->last = b->start; 76 b->end = b->last + size; 77 b->temporary = 1; 78 79 return b; 80 } 81 46 82 47 83 ngx_chain_t * 48 84 ngx_alloc_chain_link(ngx_pool_t *pool) -
nginx-1.12.0/src/core/ngx_buf.h
diff --git a/nginx-1.12.0/src/core/ngx_buf.h b/nginx-1.12.0/src/core/ngx_buf.h old mode 100644 new mode 100755 index 12781a7..c0e1dcf
a b typedef struct { 141 141 (b->file_last - b->file_pos)) 142 142 143 143 ngx_buf_t *ngx_create_temp_buf(ngx_pool_t *pool, size_t size); 144 ngx_buf_t *ngx_recreate_temp_buf(ngx_buf_t *b, ngx_pool_t *pool, size_t size); 144 145 ngx_chain_t *ngx_create_chain_of_bufs(ngx_pool_t *pool, ngx_bufs_t *bufs); 145 146 146 147 -
nginx-1.12.0/src/core/ngx_connection.c
diff --git a/nginx-1.12.0/src/core/ngx_connection.c b/nginx-1.12.0/src/core/ngx_connection.c old mode 100644 new mode 100755 index 2af2876..4fe9040
a b ngx_close_connection(ngx_connection_t *c) 1158 1158 1159 1159 log_error = c->log_error; 1160 1160 1161 if (c->type == SOCK_DGRAM && c->listening != NULL) { 1162 uint64_t client_key = sock2key((struct sockaddr_in *)c->sockaddr); 1163 ngx_radix64tree_delete(c->listening->dgram_conns, client_key, client_key); 1164 } 1165 1161 1166 ngx_free_connection(c); 1162 1167 1163 1168 fd = c->fd; -
nginx-1.12.0/src/core/ngx_connection.h
diff --git a/nginx-1.12.0/src/core/ngx_connection.h b/nginx-1.12.0/src/core/ngx_connection.h old mode 100644 new mode 100755 index 1d3e3a3..d3182f0
a b struct ngx_listening_s { 87 87 int fastopen; 88 88 #endif 89 89 90 ngx_radix_tree_t *dgram_conns; 90 91 }; 91 92 92 93 -
nginx-1.12.0/src/core/ngx_radix_tree.c
diff --git a/nginx-1.12.0/src/core/ngx_radix_tree.c b/nginx-1.12.0/src/core/ngx_radix_tree.c old mode 100644 new mode 100755 index c1d8737..4ebaebd
a b ngx_radix32tree_find(ngx_radix_tree_t *tree, uint32_t key) 262 262 return value; 263 263 } 264 264 265 ngx_int_t 266 ngx_radix64tree_insert(ngx_radix_tree_t *tree, uint64_t key, uint64_t mask, 267 uintptr_t value) 268 { 269 uint64_t bit; 270 ngx_radix_node_t *node, *next; 271 272 bit = 0x8000000000000000; 273 274 node = tree->root; 275 next = tree->root; 276 277 while (bit & mask) { 278 if (key & bit) { 279 next = node->right; 280 281 } else { 282 next = node->left; 283 } 284 285 if (next == NULL) { 286 break; 287 } 288 289 bit >>= 1; 290 node = next; 291 } 292 293 if (next) { 294 if (node->value != NGX_RADIX_NO_VALUE) { 295 return NGX_BUSY; 296 } 297 298 node->value = value; 299 return NGX_OK; 300 } 301 302 while (bit & mask) { 303 next = ngx_radix_alloc(tree); 304 if (next == NULL) { 305 return NGX_ERROR; 306 } 307 308 next->right = NULL; 309 next->left = NULL; 310 next->parent = node; 311 next->value = NGX_RADIX_NO_VALUE; 312 313 if (key & bit) { 314 node->right = next; 315 316 } else { 317 node->left = next; 318 } 319 320 bit >>= 1; 321 node = next; 322 } 323 324 node->value = value; 325 326 return NGX_OK; 327 } 328 329 330 ngx_int_t 331 ngx_radix64tree_delete(ngx_radix_tree_t *tree, uint64_t key, uint64_t mask) 332 { 333 uint64_t bit; 334 ngx_radix_node_t *node; 335 336 bit = 0x8000000000000000; 337 node = tree->root; 338 339 while (node && (bit & mask)) { 340 if (key & bit) { 341 node = node->right; 342 343 } else { 344 node = node->left; 345 } 346 347 bit >>= 1; 348 } 349 350 if (node == NULL) { 351 return NGX_ERROR; 352 } 353 354 if (node->right || node->left) { 355 if (node->value != NGX_RADIX_NO_VALUE) { 356 node->value = NGX_RADIX_NO_VALUE; 357 return NGX_OK; 358 } 359 360 return NGX_ERROR; 361 } 362 363 for ( ;; ) { 364 if (node->parent->right == node) { 365 node->parent->right = NULL; 366 367 } else { 368 node->parent->left = NULL; 369 } 370 371 node->right = tree->free; 372 tree->free = node; 373 374 node = node->parent; 375 376 if (node->right || node->left) { 377 break; 378 } 379 380 if (node->value != NGX_RADIX_NO_VALUE) { 381 break; 382 } 383 384 if (node->parent == NULL) { 385 break; 386 } 387 } 388 389 return NGX_OK; 390 } 391 392 393 uintptr_t 394 ngx_radix64tree_find(ngx_radix_tree_t *tree, uint64_t key) 395 { 396 uint64_t bit; 397 uintptr_t value; 398 ngx_radix_node_t *node; 399 400 bit = 0x8000000000000000; 401 value = NGX_RADIX_NO_VALUE; 402 node = tree->root; 403 404 while (node) { 405 if (node->value != NGX_RADIX_NO_VALUE) { 406 value = node->value; 407 } 408 409 if (key & bit) { 410 node = node->right; 411 412 } else { 413 node = node->left; 414 } 415 416 bit >>= 1; 417 } 418 419 return value; 420 } 421 265 422 266 423 #if (NGX_HAVE_INET6) 267 424 -
nginx-1.12.0/src/core/ngx_radix_tree.h
diff --git a/nginx-1.12.0/src/core/ngx_radix_tree.h b/nginx-1.12.0/src/core/ngx_radix_tree.h old mode 100644 new mode 100755 index 4fe06e0..d34ac34
a b ngx_int_t ngx_radix32tree_delete(ngx_radix_tree_t *tree, 43 43 uint32_t key, uint32_t mask); 44 44 uintptr_t ngx_radix32tree_find(ngx_radix_tree_t *tree, uint32_t key); 45 45 46 ngx_int_t ngx_radix64tree_insert(ngx_radix_tree_t *tree, 47 uint64_t key, uint64_t mask, uintptr_t value); 48 ngx_int_t ngx_radix64tree_delete(ngx_radix_tree_t *tree, 49 uint64_t key, uint64_t mask); 50 uintptr_t ngx_radix64tree_find(ngx_radix_tree_t *tree, uint64_t key); 51 46 52 #if (NGX_HAVE_INET6) 47 53 ngx_int_t ngx_radix128tree_insert(ngx_radix_tree_t *tree, 48 54 u_char *key, u_char *mask, uintptr_t value); … … ngx_int_t ngx_radix128tree_delete(ngx_radix_tree_t *tree, 51 57 uintptr_t ngx_radix128tree_find(ngx_radix_tree_t *tree, u_char *key); 52 58 #endif 53 59 60 static ngx_inline uint64_t 61 sock2key(struct sockaddr_in *sin) 62 { 63 return ((uint64_t)sin->sin_addr.s_addr << 32) + sin->sin_port; 64 } 54 65 55 66 #endif /* _NGX_RADIX_TREE_H_INCLUDED_ */ -
nginx-1.12.0/src/event/ngx_event_accept.c
diff --git a/nginx-1.12.0/src/event/ngx_event_accept.c b/nginx-1.12.0/src/event/ngx_event_accept.c old mode 100644 new mode 100755 index 406066f..5b922e3
a b static void ngx_debug_accepted_connection(ngx_event_conf_t *ecf, 21 21 ngx_connection_t *c); 22 22 #endif 23 23 24 void ngx_stream_session_udp_handler(ngx_event_t *rev); 25 24 26 25 27 void 26 28 ngx_event_accept(ngx_event_t *ev) … … ngx_event_recvmsg(ngx_event_t *ev) 341 343 ngx_event_conf_t *ecf; 342 344 ngx_connection_t *c, *lc; 343 345 static u_char buffer[65535]; 346 #if (NGX_DEBUG) 347 ngx_str_t client_addr; 348 u_char client_text[NGX_SOCKADDR_STRLEN]; 349 #endif 350 uint64_t client_key; 351 uintptr_t v; 344 352 345 353 #if (NGX_HAVE_MSGHDR_MSG_CONTROL) 346 354 … … ngx_event_recvmsg(ngx_event_t *ev) 440 448 ngx_accept_disabled = ngx_cycle->connection_n / 8 441 449 - ngx_cycle->free_connection_n; 442 450 451 #if (NGX_DEBUG) 452 client_addr.data = client_text; 453 client_addr.len = ngx_sock_ntop((struct sockaddr *)msg.msg_name, 454 msg.msg_namelen, client_text, NGX_SOCKADDR_STRLEN, 1); 455 #endif 456 457 client_key = sock2key(&sa.sockaddr_in); 458 v = ngx_radix64tree_find(ls->dgram_conns, client_key); 459 if (v != NGX_RADIX_NO_VALUE) { 460 #if (NGX_DEBUG) 461 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ev->log, 0, 462 "reuse incoming conenction on %V from %V(%08X)", &ls->addr_text, &client_addr, client_key); 463 #endif 464 c = (ngx_connection_t *)v; 465 c->number = ngx_atomic_fetch_add(ngx_connection_counter, 1); 466 c->log->connection = c->number; 467 c->buffer = ngx_recreate_temp_buf(c->buffer, c->pool, n); 468 if (c->buffer == NULL) { 469 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ev->log, 0, 470 "failed to recreate buf for incoming conenction on %V", &ls->addr_text); 471 ngx_close_accepted_connection(c); 472 return; 473 } 474 475 c->buffer->last = ngx_cpymem(c->buffer->last, buffer, n); 476 ngx_stream_session_udp_handler(c->read); 477 continue; 478 } 479 480 #if (NGX_DEBUG) 481 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ev->log, 0, 482 "setup incoming conenction on %V from %V(%08X)", &ls->addr_text, &client_addr, client_key); 483 #endif 443 484 c = ngx_get_connection(lc->fd, ev->log); 444 485 if (c == NULL) { 445 486 #ifdef NGX_HTTP_STATUS … … ngx_event_recvmsg(ngx_event_t *ev) 641 682 ev->available -= n; 642 683 } 643 684 685 client_key = sock2key(&sa.sockaddr_in); 686 ngx_radix64tree_insert(ls->dgram_conns, client_key, client_key, (uintptr_t)c); 644 687 } while (ev->available); 645 688 } 646 689 -
nginx-1.12.0/src/stream/ngx_stream.c
diff --git a/nginx-1.12.0/src/stream/ngx_stream.c b/nginx-1.12.0/src/stream/ngx_stream.c old mode 100644 new mode 100755 index 4a394d7..7f7b457
a b ngx_stream_optimize_servers(ngx_conf_t *cf, ngx_array_t *ports) 521 521 522 522 stport->naddrs = i + 1; 523 523 524 if (ls->type == SOCK_DGRAM) { 525 ls->dgram_conns = ngx_radix_tree_create(cf->pool, -1); 526 if (ls->dgram_conns == NULL) { 527 return NGX_CONF_ERROR; 528 } 529 } else { 530 ls->dgram_conns = NULL; 531 } 532 524 533 switch (ls->sockaddr->sa_family) { 525 534 #if (NGX_HAVE_INET6) 526 535 case AF_INET6: -
nginx-1.12.0/src/stream/ngx_stream.h
diff --git a/nginx-1.12.0/src/stream/ngx_stream.h b/nginx-1.12.0/src/stream/ngx_stream.h old mode 100644 new mode 100755 index d478cc1..438e387
a b ngx_int_t ngx_stream_core_content_phase(ngx_stream_session_t *s, 293 293 294 294 void ngx_stream_init_connection(ngx_connection_t *c); 295 295 void ngx_stream_session_handler(ngx_event_t *rev); 296 void ngx_stream_session_udp_handler(ngx_event_t *rev); 296 297 void ngx_stream_finalize_session(ngx_stream_session_t *s, ngx_uint_t rc); 297 298 298 299 -
nginx-1.12.0/src/stream/ngx_stream_handler.c
diff --git a/nginx-1.12.0/src/stream/ngx_stream_handler.c b/nginx-1.12.0/src/stream/ngx_stream_handler.c old mode 100644 new mode 100755 index 437f6ea..92b3f7a
a b ngx_stream_session_handler(ngx_event_t *rev) 336 336 ngx_stream_core_run_phases(s); 337 337 } 338 338 339 void 340 ngx_stream_session_udp_handler(ngx_event_t *rev) 341 { 342 ngx_connection_t *c; 343 ngx_stream_session_t *s; 344 345 c = rev->data; 346 s = c->data; 347 348 ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0, 349 "stream session udp handler"); 350 351 c->log->action = "reuse session"; 352 353 s->received += c->buffer->last - c->buffer->pos; 354 355 ngx_stream_core_run_phases(s); 356 } 357 339 358 340 359 void 341 360 ngx_stream_finalize_session(ngx_stream_session_t *s, ngx_uint_t rc) -
nginx-1.12.0/src/stream/ngx_stream_proxy_module.c
diff --git a/nginx-1.12.0/src/stream/ngx_stream_proxy_module.c b/nginx-1.12.0/src/stream/ngx_stream_proxy_module.c old mode 100644 new mode 100755 index c19dd7e..3d53b64
a b ngx_stream_proxy_handler(ngx_stream_session_t *s) 368 368 369 369 c = s->connection; 370 370 371 if (c->type == SOCK_DGRAM && s->upstream) { 372 ngx_stream_proxy_connect(s); 373 return; 374 } 375 371 376 pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module); 372 377 373 378 ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0, … … ngx_stream_proxy_connect(ngx_stream_session_t *s) 709 714 710 715 c = s->connection; 711 716 712 c->log->action = "connecting to upstream";713 714 717 pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module); 715 718 716 719 u = s->upstream; 717 720 721 if (c->type == SOCK_DGRAM && u->peer.connection) { 722 ngx_chain_t *cl; 723 724 pc = u->peer.connection; 725 726 ngx_log_debug1(NGX_LOG_DEBUG_STREAM, c->log, 0, "reuse proxy connect: %p", pc); 727 728 if (c->buffer && c->buffer->pos < c->buffer->last) { 729 ngx_log_debug1(NGX_LOG_DEBUG_STREAM, c->log, 0, 730 "stream proxy add buffer: %uz", 731 c->buffer->last - c->buffer->pos); 732 733 cl = ngx_chain_get_free_buf(c->pool, &u->free); 734 if (cl == NULL) { 735 #ifdef NGX_HTTP_STATUS 736 ngx_http_status_update(cscf->status_index, STATUS_TYPE_PROXY_ERROR, 1); 737 #endif 738 ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR); 739 return; 740 } 741 742 *cl->buf = *c->buffer; 743 744 cl->buf->tag = (ngx_buf_tag_t) &ngx_stream_proxy_module; 745 cl->buf->flush = 1; 746 cl->buf->last_buf = 1; 747 748 cl->next = u->upstream_out; 749 u->upstream_out = cl; 750 } 751 752 if (pscf->responses == 0) { 753 pc->read->ready = 0; 754 pc->read->eof = 1; 755 } 756 757 ngx_stream_proxy_process(s, 0, 1); 758 759 return; 760 } 761 762 c->log->action = "connecting to upstream"; 763 718 764 u->connected = 0; 719 765 u->proxy_protocol = pscf->proxy_protocol; 720 766
