Mercurial > hg > nginx
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; |