nginxtra 1.8.0.11 → 1.8.1.12

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,11 +2,11 @@ module Nginxtra
2
2
  class Version
3
3
  class << self
4
4
  def to_a
5
- to_s.split(".").map &:to_i
5
+ to_s.split(".").map(&:to_i)
6
6
  end
7
7
 
8
8
  def to_s
9
- "1.8.0.11"
9
+ "1.8.1.12"
10
10
  end
11
11
  end
12
12
  end
@@ -1,11 +1,11 @@
1
1
  rails_server = yield(:server) || :passenger
2
2
  ssl_details = yield :ssl
3
3
 
4
- if ssl_details
5
- default_port = 443
6
- else
7
- default_port = 80
8
- end
4
+ default_port = if ssl_details
5
+ 443
6
+ else
7
+ 80
8
+ end
9
9
 
10
10
  if rails_server == :passenger && !@passenger_requirements_done
11
11
  @config.require_passenger!
@@ -1,4 +1,51 @@
1
1
 
2
+ Changes with nginx 1.8.1 26 Jan 2016
3
+
4
+ *) Security: invalid pointer dereference might occur during DNS server
5
+ response processing if the "resolver" directive was used, allowing an
6
+ attacker who is able to forge UDP packets from the DNS server to
7
+ cause segmentation fault in a worker process (CVE-2016-0742).
8
+
9
+ *) Security: use-after-free condition might occur during CNAME response
10
+ processing if the "resolver" directive was used, allowing an attacker
11
+ who is able to trigger name resolution to cause segmentation fault in
12
+ a worker process, or might have potential other impact
13
+ (CVE-2016-0746).
14
+
15
+ *) Security: CNAME resolution was insufficiently limited if the
16
+ "resolver" directive was used, allowing an attacker who is able to
17
+ trigger arbitrary name resolution to cause excessive resource
18
+ consumption in worker processes (CVE-2016-0747).
19
+
20
+ *) Bugfix: the "proxy_protocol" parameter of the "listen" directive did
21
+ not work if not specified in the first "listen" directive for a
22
+ listen socket.
23
+
24
+ *) Bugfix: nginx might fail to start on some old Linux variants; the bug
25
+ had appeared in 1.7.11.
26
+
27
+ *) Bugfix: a segmentation fault might occur in a worker process if the
28
+ "try_files" and "alias" directives were used inside a location given
29
+ by a regular expression; the bug had appeared in 1.7.1.
30
+
31
+ *) Bugfix: the "try_files" directive inside a nested location given by a
32
+ regular expression worked incorrectly if the "alias" directive was
33
+ used in the outer location.
34
+
35
+ *) Bugfix: "header already sent" alerts might appear in logs when using
36
+ cache; the bug had appeared in 1.7.5.
37
+
38
+ *) Bugfix: a segmentation fault might occur in a worker process if
39
+ different ssl_session_cache settings were used in different virtual
40
+ servers.
41
+
42
+ *) Bugfix: the "expires" directive might not work when using variables.
43
+
44
+ *) Bugfix: if nginx was built with the ngx_http_spdy_module it was
45
+ possible to use the SPDY protocol even if the "spdy" parameter of the
46
+ "listen" directive was not specified.
47
+
48
+
2
49
  Changes with nginx 1.8.0 21 Apr 2015
3
50
 
4
51
  *) 1.8.x stable branch.
@@ -1,4 +1,56 @@
1
1
 
2
+ Изменения в nginx 1.8.1 26.01.2016
3
+
4
+ *) Безопасность: при использовании директивы resolver во время обработки
5
+ ответов DNS-сервера могло происходить разыменование некорректного
6
+ адреса, что позволяло атакующему, имеющему возможность подделывать
7
+ UDP-пакеты от DNS-сервера, вызвать segmentation fault в рабочем
8
+ процессе (CVE-2016-0742).
9
+
10
+ *) Безопасность: при использовании директивы resolver во время обработки
11
+ CNAME-записей могло произойти обращение к ранее освобождённой памяти,
12
+ что позволяло атакующему, имеющему возможность инициировать
13
+ преобразование произвольных имён в адреса, вызвать segmentation fault
14
+ в рабочем процессе, а также потенциально могло иметь другие
15
+ последствия (CVE-2016-0746).
16
+
17
+ *) Безопасность: при использовании директивы resolver во время обработки
18
+ CNAME-записей не во всех случаях проверялось ограничение на
19
+ максимальное количество записей в цепочке, что позволяло атакующему,
20
+ имеющему возможность инициировать преобразование произвольных имён в
21
+ адреса, вызвать чрезмерное потребление ресурсов рабочими процессами
22
+ (CVE-2016-0747).
23
+
24
+ *) Исправление: параметр proxy_protocol директивы listen не работал,
25
+ если не был указан в первой директиве listen для данного
26
+ listen-сокета.
27
+
28
+ *) Исправление: nginx мог не запускаться на некоторых старых версиях
29
+ Linux; ошибка появилась в 1.7.11.
30
+
31
+ *) Исправление: при совместном использовании директив try_files и alias
32
+ внутри location'а, заданного регулярным выражением, в рабочем
33
+ процессе мог произойти segmentation fault; ошибка появилась в 1.7.1.
34
+
35
+ *) Исправление: директива try_files внутри вложенного location'а,
36
+ заданного регулярным выражением, работала неправильно, если во
37
+ внешнем location'е использовалась директива alias.
38
+
39
+ *) Исправление: при использовании кэша в логах могли появляться
40
+ сообщения "header already sent"; ошибка появилась в 1.7.5.
41
+
42
+ *) Исправление: при использовании различных настроек ssl_session_cache в
43
+ разных виртуальных серверах в рабочем процессе мог произойти
44
+ segmentation fault.
45
+
46
+ *) Исправление: директива expires могла не срабатывать при использовании
47
+ переменных.
48
+
49
+ *) Исправление: если nginx был собран с модулем ngx_http_spdy_module,
50
+ протокол SPDY мог быть использован клиентом, даже если не был указан
51
+ параметр spdy директивы listen.
52
+
53
+
2
54
  Изменения в nginx 1.8.0 21.04.2015
3
55
 
4
56
  *) Стабильная ветка 1.8.x.
@@ -9,8 +9,8 @@
9
9
  #define _NGINX_H_INCLUDED_
10
10
 
11
11
 
12
- #define nginx_version 1008000
13
- #define NGINX_VERSION "1.8.0"
12
+ #define nginx_version 1008001
13
+ #define NGINX_VERSION "1.8.1"
14
14
  #define NGINX_VER "nginx/" NGINX_VERSION
15
15
 
16
16
  #ifdef NGX_BUILD
@@ -188,7 +188,7 @@ ngx_parse_time(ngx_str_t *line, ngx_uint_t is_sec)
188
188
  break;
189
189
 
190
190
  case 'm':
191
- if (*p == 's') {
191
+ if (p < last && *p == 's') {
192
192
  if (is_sec || step >= st_msec) {
193
193
  return NGX_ERROR;
194
194
  }
@@ -59,15 +59,15 @@ ngx_int_t ngx_udp_connect(ngx_udp_connection_t *uc);
59
59
  static void ngx_resolver_cleanup(void *data);
60
60
  static void ngx_resolver_cleanup_tree(ngx_resolver_t *r, ngx_rbtree_t *tree);
61
61
  static ngx_int_t ngx_resolve_name_locked(ngx_resolver_t *r,
62
- ngx_resolver_ctx_t *ctx);
62
+ ngx_resolver_ctx_t *ctx, ngx_str_t *name);
63
63
  static void ngx_resolver_expire(ngx_resolver_t *r, ngx_rbtree_t *tree,
64
64
  ngx_queue_t *queue);
65
65
  static ngx_int_t ngx_resolver_send_query(ngx_resolver_t *r,
66
66
  ngx_resolver_node_t *rn);
67
- static ngx_int_t ngx_resolver_create_name_query(ngx_resolver_node_t *rn,
68
- ngx_resolver_ctx_t *ctx);
69
- static ngx_int_t ngx_resolver_create_addr_query(ngx_resolver_node_t *rn,
70
- ngx_resolver_ctx_t *ctx);
67
+ static ngx_int_t ngx_resolver_create_name_query(ngx_resolver_t *r,
68
+ ngx_resolver_node_t *rn, ngx_str_t *name);
69
+ static ngx_int_t ngx_resolver_create_addr_query(ngx_resolver_t *r,
70
+ ngx_resolver_node_t *rn, ngx_addr_t *addr);
71
71
  static void ngx_resolver_resend_handler(ngx_event_t *ev);
72
72
  static time_t ngx_resolver_resend(ngx_resolver_t *r, ngx_rbtree_t *tree,
73
73
  ngx_queue_t *queue);
@@ -375,7 +375,7 @@ ngx_resolve_name(ngx_resolver_ctx_t *ctx)
375
375
 
376
376
  /* lock name mutex */
377
377
 
378
- rc = ngx_resolve_name_locked(r, ctx);
378
+ rc = ngx_resolve_name_locked(r, ctx, &ctx->name);
379
379
 
380
380
  if (rc == NGX_OK) {
381
381
  return NGX_OK;
@@ -402,7 +402,6 @@ ngx_resolve_name(ngx_resolver_ctx_t *ctx)
402
402
  void
403
403
  ngx_resolve_name_done(ngx_resolver_ctx_t *ctx)
404
404
  {
405
- uint32_t hash;
406
405
  ngx_resolver_t *r;
407
406
  ngx_resolver_ctx_t *w, **p;
408
407
  ngx_resolver_node_t *rn;
@@ -422,11 +421,9 @@ ngx_resolve_name_done(ngx_resolver_ctx_t *ctx)
422
421
 
423
422
  /* lock name mutex */
424
423
 
425
- if (ctx->state == NGX_AGAIN) {
426
-
427
- hash = ngx_crc32_short(ctx->name.data, ctx->name.len);
424
+ if (ctx->state == NGX_AGAIN || ctx->state == NGX_RESOLVE_TIMEDOUT) {
428
425
 
429
- rn = ngx_resolver_lookup_name(r, &ctx->name, hash);
426
+ rn = ctx->node;
430
427
 
431
428
  if (rn) {
432
429
  p = &rn->waiting;
@@ -467,23 +464,28 @@ done:
467
464
 
468
465
 
469
466
  static ngx_int_t
470
- ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx)
467
+ ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx,
468
+ ngx_str_t *name)
471
469
  {
472
470
  uint32_t hash;
473
471
  ngx_int_t rc;
472
+ ngx_str_t cname;
474
473
  ngx_uint_t naddrs;
475
474
  ngx_addr_t *addrs;
476
- ngx_resolver_ctx_t *next;
475
+ ngx_resolver_ctx_t *next, *last;
477
476
  ngx_resolver_node_t *rn;
478
477
 
479
- ngx_strlow(ctx->name.data, ctx->name.data, ctx->name.len);
478
+ ngx_strlow(name->data, name->data, name->len);
480
479
 
481
- hash = ngx_crc32_short(ctx->name.data, ctx->name.len);
480
+ hash = ngx_crc32_short(name->data, name->len);
482
481
 
483
- rn = ngx_resolver_lookup_name(r, &ctx->name, hash);
482
+ rn = ngx_resolver_lookup_name(r, name, hash);
484
483
 
485
484
  if (rn) {
486
485
 
486
+ /* ctx can be a list after NGX_RESOLVE_CNAME */
487
+ for (last = ctx; last->next; last = last->next);
488
+
487
489
  if (rn->valid >= ngx_time()) {
488
490
 
489
491
  ngx_log_debug0(NGX_LOG_DEBUG_CORE, r->log, 0, "resolve cached");
@@ -511,7 +513,7 @@ ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx)
511
513
  }
512
514
  }
513
515
 
514
- ctx->next = rn->waiting;
516
+ last->next = rn->waiting;
515
517
  rn->waiting = NULL;
516
518
 
517
519
  /* unlock name mutex */
@@ -551,13 +553,13 @@ ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx)
551
553
 
552
554
  if (ctx->recursion++ < NGX_RESOLVER_MAX_RECURSION) {
553
555
 
554
- ctx->name.len = rn->cnlen;
555
- ctx->name.data = rn->u.cname;
556
+ cname.len = rn->cnlen;
557
+ cname.data = rn->u.cname;
556
558
 
557
- return ngx_resolve_name_locked(r, ctx);
559
+ return ngx_resolve_name_locked(r, ctx, &cname);
558
560
  }
559
561
 
560
- ctx->next = rn->waiting;
562
+ last->next = rn->waiting;
561
563
  rn->waiting = NULL;
562
564
 
563
565
  /* unlock name mutex */
@@ -576,10 +578,29 @@ ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx)
576
578
 
577
579
  if (rn->waiting) {
578
580
 
579
- ctx->next = rn->waiting;
581
+ if (ctx->event == NULL) {
582
+ ctx->event = ngx_resolver_calloc(r, sizeof(ngx_event_t));
583
+ if (ctx->event == NULL) {
584
+ return NGX_ERROR;
585
+ }
586
+
587
+ ctx->event->handler = ngx_resolver_timeout_handler;
588
+ ctx->event->data = ctx;
589
+ ctx->event->log = r->log;
590
+ ctx->ident = -1;
591
+
592
+ ngx_add_timer(ctx->event, ctx->timeout);
593
+ }
594
+
595
+ last->next = rn->waiting;
580
596
  rn->waiting = ctx;
581
597
  ctx->state = NGX_AGAIN;
582
598
 
599
+ do {
600
+ ctx->node = rn;
601
+ ctx = ctx->next;
602
+ } while (ctx);
603
+
583
604
  return NGX_AGAIN;
584
605
  }
585
606
 
@@ -618,14 +639,14 @@ ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx)
618
639
  return NGX_ERROR;
619
640
  }
620
641
 
621
- rn->name = ngx_resolver_dup(r, ctx->name.data, ctx->name.len);
642
+ rn->name = ngx_resolver_dup(r, name->data, name->len);
622
643
  if (rn->name == NULL) {
623
644
  ngx_resolver_free(r, rn);
624
645
  return NGX_ERROR;
625
646
  }
626
647
 
627
648
  rn->node.key = hash;
628
- rn->nlen = (u_short) ctx->name.len;
649
+ rn->nlen = (u_short) name->len;
629
650
  rn->query = NULL;
630
651
  #if (NGX_HAVE_INET6)
631
652
  rn->query6 = NULL;
@@ -634,7 +655,7 @@ ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx)
634
655
  ngx_rbtree_insert(&r->name_rbtree, &rn->node);
635
656
  }
636
657
 
637
- rc = ngx_resolver_create_name_query(rn, ctx);
658
+ rc = ngx_resolver_create_name_query(r, rn, name);
638
659
 
639
660
  if (rc == NGX_ERROR) {
640
661
  goto failed;
@@ -647,8 +668,14 @@ ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx)
647
668
  ngx_resolver_free(r, rn->name);
648
669
  ngx_resolver_free(r, rn);
649
670
 
650
- ctx->state = NGX_RESOLVE_NXDOMAIN;
651
- ctx->handler(ctx);
671
+ do {
672
+ ctx->state = NGX_RESOLVE_NXDOMAIN;
673
+ next = ctx->next;
674
+
675
+ ctx->handler(ctx);
676
+
677
+ ctx = next;
678
+ } while (ctx);
652
679
 
653
680
  return NGX_OK;
654
681
  }
@@ -669,9 +696,9 @@ ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx)
669
696
  }
670
697
 
671
698
  ctx->event->handler = ngx_resolver_timeout_handler;
672
- ctx->event->data = rn;
699
+ ctx->event->data = ctx;
673
700
  ctx->event->log = r->log;
674
- rn->ident = -1;
701
+ ctx->ident = -1;
675
702
 
676
703
  ngx_add_timer(ctx->event, ctx->timeout);
677
704
  }
@@ -692,6 +719,11 @@ ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx)
692
719
 
693
720
  ctx->state = NGX_AGAIN;
694
721
 
722
+ do {
723
+ ctx->node = rn;
724
+ ctx = ctx->next;
725
+ } while (ctx);
726
+
695
727
  return NGX_AGAIN;
696
728
 
697
729
  failed:
@@ -799,9 +831,22 @@ ngx_resolve_addr(ngx_resolver_ctx_t *ctx)
799
831
 
800
832
  if (rn->waiting) {
801
833
 
834
+ ctx->event = ngx_resolver_calloc(r, sizeof(ngx_event_t));
835
+ if (ctx->event == NULL) {
836
+ return NGX_ERROR;
837
+ }
838
+
839
+ ctx->event->handler = ngx_resolver_timeout_handler;
840
+ ctx->event->data = ctx;
841
+ ctx->event->log = r->log;
842
+ ctx->ident = -1;
843
+
844
+ ngx_add_timer(ctx->event, ctx->timeout);
845
+
802
846
  ctx->next = rn->waiting;
803
847
  rn->waiting = ctx;
804
848
  ctx->state = NGX_AGAIN;
849
+ ctx->node = rn;
805
850
 
806
851
  /* unlock addr mutex */
807
852
 
@@ -843,7 +888,7 @@ ngx_resolve_addr(ngx_resolver_ctx_t *ctx)
843
888
  ngx_rbtree_insert(tree, &rn->node);
844
889
  }
845
890
 
846
- if (ngx_resolver_create_addr_query(rn, ctx) != NGX_OK) {
891
+ if (ngx_resolver_create_addr_query(r, rn, &ctx->addr) != NGX_OK) {
847
892
  goto failed;
848
893
  }
849
894
 
@@ -862,9 +907,9 @@ ngx_resolve_addr(ngx_resolver_ctx_t *ctx)
862
907
  }
863
908
 
864
909
  ctx->event->handler = ngx_resolver_timeout_handler;
865
- ctx->event->data = rn;
910
+ ctx->event->data = ctx;
866
911
  ctx->event->log = r->log;
867
- rn->ident = -1;
912
+ ctx->ident = -1;
868
913
 
869
914
  ngx_add_timer(ctx->event, ctx->timeout);
870
915
 
@@ -887,6 +932,7 @@ ngx_resolve_addr(ngx_resolver_ctx_t *ctx)
887
932
  /* unlock addr mutex */
888
933
 
889
934
  ctx->state = NGX_AGAIN;
935
+ ctx->node = rn;
890
936
 
891
937
  return NGX_OK;
892
938
 
@@ -917,17 +963,11 @@ failed:
917
963
  void
918
964
  ngx_resolve_addr_done(ngx_resolver_ctx_t *ctx)
919
965
  {
920
- in_addr_t addr;
921
966
  ngx_queue_t *expire_queue;
922
967
  ngx_rbtree_t *tree;
923
968
  ngx_resolver_t *r;
924
969
  ngx_resolver_ctx_t *w, **p;
925
- struct sockaddr_in *sin;
926
970
  ngx_resolver_node_t *rn;
927
- #if (NGX_HAVE_INET6)
928
- uint32_t hash;
929
- struct sockaddr_in6 *sin6;
930
- #endif
931
971
 
932
972
  r = ctx->resolver;
933
973
 
@@ -954,23 +994,9 @@ ngx_resolve_addr_done(ngx_resolver_ctx_t *ctx)
954
994
 
955
995
  /* lock addr mutex */
956
996
 
957
- if (ctx->state == NGX_AGAIN) {
997
+ if (ctx->state == NGX_AGAIN || ctx->state == NGX_RESOLVE_TIMEDOUT) {
958
998
 
959
- switch (ctx->addr.sockaddr->sa_family) {
960
-
961
- #if (NGX_HAVE_INET6)
962
- case AF_INET6:
963
- sin6 = (struct sockaddr_in6 *) ctx->addr.sockaddr;
964
- hash = ngx_crc32_short(sin6->sin6_addr.s6_addr, 16);
965
- rn = ngx_resolver_lookup_addr6(r, &sin6->sin6_addr, hash);
966
- break;
967
- #endif
968
-
969
- default: /* AF_INET */
970
- sin = (struct sockaddr_in *) ctx->addr.sockaddr;
971
- addr = ntohl(sin->sin_addr.s_addr);
972
- rn = ngx_resolver_lookup_addr(r, addr);
973
- }
999
+ rn = ctx->node;
974
1000
 
975
1001
  if (rn) {
976
1002
  p = &rn->waiting;
@@ -1292,7 +1318,7 @@ ngx_resolver_process_response(ngx_resolver_t *r, u_char *buf, size_t n)
1292
1318
  times = 0;
1293
1319
 
1294
1320
  for (q = ngx_queue_head(&r->name_resend_queue);
1295
- q != ngx_queue_sentinel(&r->name_resend_queue) || times++ < 100;
1321
+ q != ngx_queue_sentinel(&r->name_resend_queue) && times++ < 100;
1296
1322
  q = ngx_queue_next(q))
1297
1323
  {
1298
1324
  rn = ngx_queue_data(q, ngx_resolver_node_t, queue);
@@ -1955,20 +1981,39 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
1955
1981
 
1956
1982
  ngx_queue_insert_head(&r->name_expire_queue, &rn->queue);
1957
1983
 
1984
+ ngx_resolver_free(r, rn->query);
1985
+ rn->query = NULL;
1986
+ #if (NGX_HAVE_INET6)
1987
+ rn->query6 = NULL;
1988
+ #endif
1989
+
1958
1990
  ctx = rn->waiting;
1959
1991
  rn->waiting = NULL;
1960
1992
 
1961
1993
  if (ctx) {
1962
- ctx->name = name;
1963
1994
 
1964
- (void) ngx_resolve_name_locked(r, ctx);
1965
- }
1995
+ if (ctx->recursion++ >= NGX_RESOLVER_MAX_RECURSION) {
1966
1996
 
1967
- ngx_resolver_free(r, rn->query);
1968
- rn->query = NULL;
1969
- #if (NGX_HAVE_INET6)
1970
- rn->query6 = NULL;
1971
- #endif
1997
+ /* unlock name mutex */
1998
+
1999
+ do {
2000
+ ctx->state = NGX_RESOLVE_NXDOMAIN;
2001
+ next = ctx->next;
2002
+
2003
+ ctx->handler(ctx);
2004
+
2005
+ ctx = next;
2006
+ } while (ctx);
2007
+
2008
+ return;
2009
+ }
2010
+
2011
+ for (next = ctx; next; next = next->next) {
2012
+ next->node = NULL;
2013
+ }
2014
+
2015
+ (void) ngx_resolve_name_locked(r, ctx, &name);
2016
+ }
1972
2017
 
1973
2018
  /* unlock name mutex */
1974
2019
 
@@ -2476,27 +2521,23 @@ ngx_resolver_rbtree_insert_addr6_value(ngx_rbtree_node_t *temp,
2476
2521
 
2477
2522
 
2478
2523
  static ngx_int_t
2479
- ngx_resolver_create_name_query(ngx_resolver_node_t *rn, ngx_resolver_ctx_t *ctx)
2524
+ ngx_resolver_create_name_query(ngx_resolver_t *r, ngx_resolver_node_t *rn,
2525
+ ngx_str_t *name)
2480
2526
  {
2481
2527
  u_char *p, *s;
2482
2528
  size_t len, nlen;
2483
2529
  ngx_uint_t ident;
2484
- #if (NGX_HAVE_INET6)
2485
- ngx_resolver_t *r;
2486
- #endif
2487
2530
  ngx_resolver_qs_t *qs;
2488
2531
  ngx_resolver_hdr_t *query;
2489
2532
 
2490
- nlen = ctx->name.len ? (1 + ctx->name.len + 1) : 1;
2533
+ nlen = name->len ? (1 + name->len + 1) : 1;
2491
2534
 
2492
2535
  len = sizeof(ngx_resolver_hdr_t) + nlen + sizeof(ngx_resolver_qs_t);
2493
2536
 
2494
2537
  #if (NGX_HAVE_INET6)
2495
- r = ctx->resolver;
2496
-
2497
- p = ngx_resolver_alloc(ctx->resolver, r->ipv6 ? len * 2 : len);
2538
+ p = ngx_resolver_alloc(r, r->ipv6 ? len * 2 : len);
2498
2539
  #else
2499
- p = ngx_resolver_alloc(ctx->resolver, len);
2540
+ p = ngx_resolver_alloc(r, len);
2500
2541
  #endif
2501
2542
  if (p == NULL) {
2502
2543
  return NGX_ERROR;
@@ -2515,8 +2556,8 @@ ngx_resolver_create_name_query(ngx_resolver_node_t *rn, ngx_resolver_ctx_t *ctx)
2515
2556
 
2516
2557
  ident = ngx_random();
2517
2558
 
2518
- ngx_log_debug2(NGX_LOG_DEBUG_CORE, ctx->resolver->log, 0,
2519
- "resolve: \"%V\" A %i", &ctx->name, ident & 0xffff);
2559
+ ngx_log_debug2(NGX_LOG_DEBUG_CORE, r->log, 0,
2560
+ "resolve: \"%V\" A %i", name, ident & 0xffff);
2520
2561
 
2521
2562
  query->ident_hi = (u_char) ((ident >> 8) & 0xff);
2522
2563
  query->ident_lo = (u_char) (ident & 0xff);
@@ -2546,11 +2587,11 @@ ngx_resolver_create_name_query(ngx_resolver_node_t *rn, ngx_resolver_ctx_t *ctx)
2546
2587
  p--;
2547
2588
  *p-- = '\0';
2548
2589
 
2549
- if (ctx->name.len == 0) {
2590
+ if (name->len == 0) {
2550
2591
  return NGX_DECLINED;
2551
2592
  }
2552
2593
 
2553
- for (s = ctx->name.data + ctx->name.len - 1; s >= ctx->name.data; s--) {
2594
+ for (s = name->data + name->len - 1; s >= name->data; s--) {
2554
2595
  if (*s != '.') {
2555
2596
  *p = *s;
2556
2597
  len++;
@@ -2586,8 +2627,8 @@ ngx_resolver_create_name_query(ngx_resolver_node_t *rn, ngx_resolver_ctx_t *ctx)
2586
2627
 
2587
2628
  ident = ngx_random();
2588
2629
 
2589
- ngx_log_debug2(NGX_LOG_DEBUG_CORE, ctx->resolver->log, 0,
2590
- "resolve: \"%V\" AAAA %i", &ctx->name, ident & 0xffff);
2630
+ ngx_log_debug2(NGX_LOG_DEBUG_CORE, r->log, 0,
2631
+ "resolve: \"%V\" AAAA %i", name, ident & 0xffff);
2591
2632
 
2592
2633
  query->ident_hi = (u_char) ((ident >> 8) & 0xff);
2593
2634
  query->ident_lo = (u_char) (ident & 0xff);
@@ -2604,11 +2645,12 @@ ngx_resolver_create_name_query(ngx_resolver_node_t *rn, ngx_resolver_ctx_t *ctx)
2604
2645
 
2605
2646
 
2606
2647
  static ngx_int_t
2607
- ngx_resolver_create_addr_query(ngx_resolver_node_t *rn, ngx_resolver_ctx_t *ctx)
2648
+ ngx_resolver_create_addr_query(ngx_resolver_t *r, ngx_resolver_node_t *rn,
2649
+ ngx_addr_t *addr)
2608
2650
  {
2609
2651
  u_char *p, *d;
2610
2652
  size_t len;
2611
- in_addr_t addr;
2653
+ in_addr_t inaddr;
2612
2654
  ngx_int_t n;
2613
2655
  ngx_uint_t ident;
2614
2656
  ngx_resolver_hdr_t *query;
@@ -2617,7 +2659,7 @@ ngx_resolver_create_addr_query(ngx_resolver_node_t *rn, ngx_resolver_ctx_t *ctx)
2617
2659
  struct sockaddr_in6 *sin6;
2618
2660
  #endif
2619
2661
 
2620
- switch (ctx->addr.sockaddr->sa_family) {
2662
+ switch (addr->sockaddr->sa_family) {
2621
2663
 
2622
2664
  #if (NGX_HAVE_INET6)
2623
2665
  case AF_INET6:
@@ -2634,7 +2676,7 @@ ngx_resolver_create_addr_query(ngx_resolver_node_t *rn, ngx_resolver_ctx_t *ctx)
2634
2676
  + sizeof(ngx_resolver_qs_t);
2635
2677
  }
2636
2678
 
2637
- p = ngx_resolver_alloc(ctx->resolver, len);
2679
+ p = ngx_resolver_alloc(r, len);
2638
2680
  if (p == NULL) {
2639
2681
  return NGX_ERROR;
2640
2682
  }
@@ -2658,11 +2700,11 @@ ngx_resolver_create_addr_query(ngx_resolver_node_t *rn, ngx_resolver_ctx_t *ctx)
2658
2700
 
2659
2701
  p += sizeof(ngx_resolver_hdr_t);
2660
2702
 
2661
- switch (ctx->addr.sockaddr->sa_family) {
2703
+ switch (addr->sockaddr->sa_family) {
2662
2704
 
2663
2705
  #if (NGX_HAVE_INET6)
2664
2706
  case AF_INET6:
2665
- sin6 = (struct sockaddr_in6 *) ctx->addr.sockaddr;
2707
+ sin6 = (struct sockaddr_in6 *) addr->sockaddr;
2666
2708
 
2667
2709
  for (n = 15; n >= 0; n--) {
2668
2710
  p = ngx_sprintf(p, "\1%xd\1%xd",
@@ -2677,11 +2719,11 @@ ngx_resolver_create_addr_query(ngx_resolver_node_t *rn, ngx_resolver_ctx_t *ctx)
2677
2719
 
2678
2720
  default: /* AF_INET */
2679
2721
 
2680
- sin = (struct sockaddr_in *) ctx->addr.sockaddr;
2681
- addr = ntohl(sin->sin_addr.s_addr);
2722
+ sin = (struct sockaddr_in *) addr->sockaddr;
2723
+ inaddr = ntohl(sin->sin_addr.s_addr);
2682
2724
 
2683
2725
  for (n = 0; n < 32; n += 8) {
2684
- d = ngx_sprintf(&p[1], "%ud", (addr >> n) & 0xff);
2726
+ d = ngx_sprintf(&p[1], "%ud", (inaddr >> n) & 0xff);
2685
2727
  *p = (u_char) (d - &p[1]);
2686
2728
  p = d;
2687
2729
  }
@@ -2795,21 +2837,13 @@ done:
2795
2837
  static void
2796
2838
  ngx_resolver_timeout_handler(ngx_event_t *ev)
2797
2839
  {
2798
- ngx_resolver_ctx_t *ctx, *next;
2799
- ngx_resolver_node_t *rn;
2840
+ ngx_resolver_ctx_t *ctx;
2800
2841
 
2801
- rn = ev->data;
2802
- ctx = rn->waiting;
2803
- rn->waiting = NULL;
2842
+ ctx = ev->data;
2804
2843
 
2805
- do {
2806
- ctx->state = NGX_RESOLVE_TIMEDOUT;
2807
- next = ctx->next;
2808
-
2809
- ctx->handler(ctx);
2844
+ ctx->state = NGX_RESOLVE_TIMEDOUT;
2810
2845
 
2811
- ctx = next;
2812
- } while (ctx);
2846
+ ctx->handler(ctx);
2813
2847
  }
2814
2848
 
2815
2849