comparison src/core/ngx_resolver.c @ 6349:978e79b95c9f

Resolver: fixed CNAME processing for several requests. When several requests were waiting for a response, then after getting a CNAME response only the last request was properly processed, while others were left waiting.
author Ruslan Ermilov <ru@nginx.com>
date Tue, 26 Jan 2016 16:46:38 +0300
parents 7316c57e4fe7
children a5767988c022
comparison
equal deleted inserted replaced
6348:7316c57e4fe7 6349:978e79b95c9f
476 { 476 {
477 uint32_t hash; 477 uint32_t hash;
478 ngx_int_t rc; 478 ngx_int_t rc;
479 ngx_uint_t naddrs; 479 ngx_uint_t naddrs;
480 ngx_addr_t *addrs; 480 ngx_addr_t *addrs;
481 ngx_resolver_ctx_t *next; 481 ngx_resolver_ctx_t *next, *last;
482 ngx_resolver_node_t *rn; 482 ngx_resolver_node_t *rn;
483 483
484 ngx_strlow(ctx->name.data, ctx->name.data, ctx->name.len); 484 ngx_strlow(ctx->name.data, ctx->name.data, ctx->name.len);
485 485
486 hash = ngx_crc32_short(ctx->name.data, ctx->name.len); 486 hash = ngx_crc32_short(ctx->name.data, ctx->name.len);
487 487
488 rn = ngx_resolver_lookup_name(r, &ctx->name, hash); 488 rn = ngx_resolver_lookup_name(r, &ctx->name, hash);
489 489
490 if (rn) { 490 if (rn) {
491
492 /* ctx can be a list after NGX_RESOLVE_CNAME */
493 for (last = ctx; last->next; last = last->next);
491 494
492 if (rn->valid >= ngx_time()) { 495 if (rn->valid >= ngx_time()) {
493 496
494 ngx_log_debug0(NGX_LOG_DEBUG_CORE, r->log, 0, "resolve cached"); 497 ngx_log_debug0(NGX_LOG_DEBUG_CORE, r->log, 0, "resolve cached");
495 498
514 if (addrs == NULL) { 517 if (addrs == NULL) {
515 return NGX_ERROR; 518 return NGX_ERROR;
516 } 519 }
517 } 520 }
518 521
519 ctx->next = rn->waiting; 522 last->next = rn->waiting;
520 rn->waiting = NULL; 523 rn->waiting = NULL;
521 524
522 /* unlock name mutex */ 525 /* unlock name mutex */
523 526
524 do { 527 do {
560 ctx->name.data = rn->u.cname; 563 ctx->name.data = rn->u.cname;
561 564
562 return ngx_resolve_name_locked(r, ctx); 565 return ngx_resolve_name_locked(r, ctx);
563 } 566 }
564 567
565 ctx->next = rn->waiting; 568 last->next = rn->waiting;
566 rn->waiting = NULL; 569 rn->waiting = NULL;
567 570
568 /* unlock name mutex */ 571 /* unlock name mutex */
569 572
570 do { 573 do {
593 ctx->ident = -1; 596 ctx->ident = -1;
594 597
595 ngx_add_timer(ctx->event, ctx->timeout); 598 ngx_add_timer(ctx->event, ctx->timeout);
596 } 599 }
597 600
598 ctx->next = rn->waiting; 601 last->next = rn->waiting;
599 rn->waiting = ctx; 602 rn->waiting = ctx;
600 ctx->state = NGX_AGAIN; 603 ctx->state = NGX_AGAIN;
601 604
602 return NGX_AGAIN; 605 return NGX_AGAIN;
603 } 606 }
664 667
665 ngx_resolver_free(r, rn->query); 668 ngx_resolver_free(r, rn->query);
666 ngx_resolver_free(r, rn->name); 669 ngx_resolver_free(r, rn->name);
667 ngx_resolver_free(r, rn); 670 ngx_resolver_free(r, rn);
668 671
669 ctx->state = NGX_RESOLVE_NXDOMAIN; 672 do {
670 ctx->handler(ctx); 673 ctx->state = NGX_RESOLVE_NXDOMAIN;
674 next = ctx->next;
675
676 ctx->handler(ctx);
677
678 ctx = next;
679 } while (ctx);
671 680
672 return NGX_OK; 681 return NGX_OK;
673 } 682 }
674 683
675 rn->naddrs = (u_short) -1; 684 rn->naddrs = (u_short) -1;