comparison src/core/ngx_resolver.c @ 366:babd3d9efb62 NGINX_0_6_27

nginx 0.6.27 *) Change: now by default the rtsig method is not built on Linux 2.6.18+. *) Change: now a request method is not changed while redirection to a named location via an "error_page" directive. *) Feature: the "resolver" and "resolver_timeout" directives in SMTP proxy. *) Feature: the "post_action" directive supports named locations. *) Bugfix: a segmentation fault occurred in worker process, if a request was redirected from proxy, FastCGI, or memcached location to static named locations. *) Bugfix: browsers did not repeat SSL handshake if there is no valid client certificate in first handshake. Thanks to Alexander V. Inyukhin. *) Bugfix: if response code 495-497 was redirected via an "error_page" directive without code change, then nginx tried to allocate too many memory. *) Bugfix: memory leak in long-lived non buffered connections. *) Bugfix: memory leak in resolver. *) Bugfix: a segmentation fault occurred in worker process, if a request was redirected from proxy, FastCGI, or memcached location to static named locations. *) Bugfix: in the $proxy_host and $proxy_port variables caching. Thanks to Sergey Bochenkov. *) Bugfix: a "proxy_pass" directive with variables used incorrectly the same port as in another "proxy_pass" directive with the same host name and without variables. Thanks to Sergey Bochenkov. *) Bugfix: an alert "sendmsg() failed (9: Bad file descriptor)" on some 64-bit platforms while reconfiguration. *) Bugfix: a segmentation fault occurred in worker process, if empty stub block was used second time in SSI. *) Bugfix: in copying URI part contained escaped symbols into arguments.
author Igor Sysoev <http://sysoev.ru>
date Wed, 12 Mar 2008 00:00:00 +0300
parents a39aab45a53f
children 6639b93e81b2
comparison
equal deleted inserted replaced
365:9b0140fa1132 366:babd3d9efb62
48 48
49 49
50 ngx_int_t ngx_udp_connect(ngx_udp_connection_t *uc); 50 ngx_int_t ngx_udp_connect(ngx_udp_connection_t *uc);
51 51
52 52
53 static void ngx_resolver_cleanup(void *data);
54 static void ngx_resolver_cleanup_tree(ngx_resolver_t *r, ngx_rbtree_t *tree);
53 static ngx_int_t ngx_resolve_name_locked(ngx_resolver_t *r, 55 static ngx_int_t ngx_resolve_name_locked(ngx_resolver_t *r,
54 ngx_resolver_ctx_t *ctx); 56 ngx_resolver_ctx_t *ctx);
55 static void ngx_resolver_expire(ngx_resolver_t *r, ngx_rbtree_t *tree, 57 static void ngx_resolver_expire(ngx_resolver_t *r, ngx_rbtree_t *tree,
56 ngx_queue_t *queue); 58 ngx_queue_t *queue);
57 static ngx_int_t ngx_resolver_send_query(ngx_resolver_t *r, 59 static ngx_int_t ngx_resolver_send_query(ngx_resolver_t *r,
79 static ngx_int_t ngx_resolver_copy(ngx_resolver_t *r, ngx_str_t *name, 81 static ngx_int_t ngx_resolver_copy(ngx_resolver_t *r, ngx_str_t *name,
80 u_char *buf, u_char *src, u_char *last); 82 u_char *buf, u_char *src, u_char *last);
81 static void ngx_resolver_timeout_handler(ngx_event_t *ev); 83 static void ngx_resolver_timeout_handler(ngx_event_t *ev);
82 static void ngx_resolver_free_node(ngx_resolver_t *r, ngx_resolver_node_t *rn); 84 static void ngx_resolver_free_node(ngx_resolver_t *r, ngx_resolver_node_t *rn);
83 static void *ngx_resolver_alloc(ngx_resolver_t *r, size_t size); 85 static void *ngx_resolver_alloc(ngx_resolver_t *r, size_t size);
86 static void *ngx_resolver_calloc(ngx_resolver_t *r, size_t size);
84 static void ngx_resolver_free(ngx_resolver_t *r, void *p); 87 static void ngx_resolver_free(ngx_resolver_t *r, void *p);
85 static void ngx_resolver_free_locked(ngx_resolver_t *r, void *p); 88 static void ngx_resolver_free_locked(ngx_resolver_t *r, void *p);
86 static void *ngx_resolver_dup(ngx_resolver_t *r, void *src, size_t size); 89 static void *ngx_resolver_dup(ngx_resolver_t *r, void *src, size_t size);
87 90
88 91
89 /* STUB: ngx_peer_addr_t * */ 92 /* STUB: ngx_peer_addr_t * */
90 93
91 ngx_resolver_t * 94 ngx_resolver_t *
92 ngx_resolver_create(ngx_peer_addr_t *addr, ngx_log_t *log) 95 ngx_resolver_create(ngx_conf_t *cf, ngx_peer_addr_t *addr)
93 { 96 {
94 ngx_resolver_t *r; 97 ngx_resolver_t *r;
98 ngx_pool_cleanup_t *cln;
95 ngx_udp_connection_t *uc; 99 ngx_udp_connection_t *uc;
96 100
97 r = ngx_calloc(sizeof(ngx_resolver_t), log); 101 cln = ngx_pool_cleanup_add(cf->pool, 0);
102 if (cln == NULL) {
103 return NULL;
104 }
105
106 cln->handler = ngx_resolver_cleanup;
107
108 r = ngx_calloc(sizeof(ngx_resolver_t), cf->log);
98 if (r == NULL) { 109 if (r == NULL) {
99 return NULL; 110 return NULL;
100 } 111 }
101 112
102 r->event = ngx_calloc(sizeof(ngx_event_t), log); 113 cln->data = r;
114
115 r->event = ngx_calloc(sizeof(ngx_event_t), cf->log);
103 if (r->event == NULL) { 116 if (r->event == NULL) {
104 return NULL; 117 return NULL;
105 } 118 }
106 119
107 ngx_rbtree_init(&r->name_rbtree, &r->name_sentinel, 120 ngx_rbtree_init(&r->name_rbtree, &r->name_sentinel,
116 ngx_queue_init(&r->name_expire_queue); 129 ngx_queue_init(&r->name_expire_queue);
117 ngx_queue_init(&r->addr_expire_queue); 130 ngx_queue_init(&r->addr_expire_queue);
118 131
119 r->event->handler = ngx_resolver_resend_handler; 132 r->event->handler = ngx_resolver_resend_handler;
120 r->event->data = r; 133 r->event->data = r;
121 r->event->log = log; 134 r->event->log = cf->cycle->new_log;
122 r->ident = -1; 135 r->ident = -1;
123 136
124 r->resend_timeout = 5; 137 r->resend_timeout = 5;
125 r->expire = 30; 138 r->expire = 30;
126 r->valid = 300; 139 r->valid = 300;
127 140
128 r->log = log; 141 r->log = cf->cycle->new_log;
129 r->log_level = NGX_LOG_ALERT; 142 r->log_level = NGX_LOG_ALERT;
130 143
131 if (addr) { 144 if (addr) {
132 uc = ngx_calloc(sizeof(ngx_udp_connection_t), log); 145 uc = ngx_calloc(sizeof(ngx_udp_connection_t), cf->log);
133 if (uc == NULL) { 146 if (uc == NULL) {
134 return NULL; 147 return NULL;
135 } 148 }
136 149
137 r->udp_connection = uc; 150 r->udp_connection = uc;
138 151
139 uc->sockaddr = addr->sockaddr; 152 uc->sockaddr = addr->sockaddr;
140 uc->socklen = addr->socklen; 153 uc->socklen = addr->socklen;
141 uc->server = addr->name; 154 uc->server = addr->name;
142 uc->log = log; 155 uc->log = cf->cycle->new_log;
143 } 156 }
144 157
145 return r; 158 return r;
159 }
160
161
162 static void
163 ngx_resolver_cleanup(void *data)
164 {
165 ngx_resolver_t *r = data;
166
167 if (r) {
168 ngx_log_debug0(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0,
169 "cleanup resolver");
170
171 ngx_resolver_cleanup_tree(r, &r->name_rbtree);
172
173 ngx_resolver_cleanup_tree(r, &r->addr_rbtree);
174
175 if (r->event) {
176 ngx_free(r->event);
177 }
178
179 if (r->udp_connection) {
180 if (r->udp_connection->connection) {
181 ngx_close_connection(r->udp_connection->connection);
182 }
183
184 ngx_free(r->udp_connection);
185 }
186
187 ngx_free(r);
188 }
189 }
190
191
192 static void
193 ngx_resolver_cleanup_tree(ngx_resolver_t *r, ngx_rbtree_t *tree)
194 {
195 ngx_resolver_ctx_t *ctx, *next;
196 ngx_resolver_node_t *rn;
197
198 while (tree->root != tree->sentinel) {
199
200 rn = (ngx_resolver_node_t *) ngx_rbtree_min(tree->root, tree->sentinel);
201
202 ngx_queue_remove(&rn->queue);
203
204 for (ctx = rn->waiting; ctx; ctx = next) {
205 next = ctx->next;
206
207 if (ctx->event) {
208 ngx_resolver_free(r, ctx->event);
209 }
210
211 ngx_resolver_free(r, ctx);
212 }
213
214 ngx_rbtree_delete(tree, &rn->node);
215
216 ngx_resolver_free_node(r, rn);
217 }
146 } 218 }
147 219
148 220
149 ngx_resolver_ctx_t * 221 ngx_resolver_ctx_t *
150 ngx_resolve_start(ngx_resolver_t *r, ngx_resolver_ctx_t *temp) 222 ngx_resolve_start(ngx_resolver_t *r, ngx_resolver_ctx_t *temp)
209 281
210 if (rc == NGX_AGAIN) { 282 if (rc == NGX_AGAIN) {
211 return NGX_OK; 283 return NGX_OK;
212 } 284 }
213 285
214 /* lock alloc mutex */ 286 /* NGX_ERROR */
215 287
216 if (ctx->event) { 288 if (ctx->event) {
217 ngx_resolver_free_locked(r, ctx->event); 289 ngx_resolver_free(r, ctx->event);
218 ctx->event = NULL; 290 }
219 } 291
220 292 ngx_resolver_free(r, ctx);
221 /* unlock alloc mutex */
222 293
223 return NGX_ERROR; 294 return NGX_ERROR;
224 } 295 }
225 296
226 297
277 348
278 ngx_resolver_expire(r, &r->name_rbtree, &r->name_expire_queue); 349 ngx_resolver_expire(r, &r->name_rbtree, &r->name_expire_queue);
279 350
280 /* unlock name mutex */ 351 /* unlock name mutex */
281 352
282 ngx_resolver_free(r, ctx); 353 /* lock alloc mutex */
354
355 if (ctx->event) {
356 ngx_resolver_free_locked(r, ctx->event);
357 }
358
359 ngx_resolver_free_locked(r, ctx);
360
361 /* unlock alloc mutex */
283 } 362 }
284 363
285 364
286 /* NGX_RESOLVE_A only */ 365 /* NGX_RESOLVE_A only */
287 366
570 ngx_resolver_free(r, rn); 649 ngx_resolver_free(r, rn);
571 } 650 }
572 651
573 /* unlock addr mutex */ 652 /* unlock addr mutex */
574 653
575 /* lock alloc mutex */
576
577 if (ctx->event) { 654 if (ctx->event) {
578 ngx_resolver_free_locked(r, ctx->event); 655 ngx_resolver_free(r, ctx->event);
579 } 656 }
580 657
581 ngx_resolver_free_locked(r, ctx); 658 ngx_resolver_free(r, ctx);
582
583 /* unlock alloc mutex */
584 659
585 return NGX_ERROR; 660 return NGX_ERROR;
586 } 661 }
587 662
588 663
637 712
638 ngx_resolver_expire(r, &r->addr_rbtree, &r->addr_expire_queue); 713 ngx_resolver_expire(r, &r->addr_rbtree, &r->addr_expire_queue);
639 714
640 /* unlock addr mutex */ 715 /* unlock addr mutex */
641 716
642 ngx_resolver_free(r, ctx); 717 /* lock alloc mutex */
718
719 if (ctx->event) {
720 ngx_resolver_free_locked(r, ctx->event);
721 }
722
723 ngx_resolver_free_locked(r, ctx);
724
725 /* unlock alloc mutex */
643 } 726 }
644 727
645 728
646 static void 729 static void
647 ngx_resolver_expire(ngx_resolver_t *r, ngx_rbtree_t *tree, ngx_queue_t *queue) 730 ngx_resolver_expire(ngx_resolver_t *r, ngx_rbtree_t *tree, ngx_queue_t *queue)
693 return NGX_ERROR; 776 return NGX_ERROR;
694 } 777 }
695 778
696 uc->connection->data = r; 779 uc->connection->data = r;
697 uc->connection->read->handler = ngx_resolver_read_response; 780 uc->connection->read->handler = ngx_resolver_read_response;
781 uc->connection->read->resolver = 1;
698 } 782 }
699 783
700 n = ngx_send(uc->connection, rn->query, rn->qlen); 784 n = ngx_send(uc->connection, rn->query, rn->qlen);
701 785
702 if (n == -1) { 786 if (n == -1) {
1811 1895
1812 return p; 1896 return p;
1813 } 1897 }
1814 1898
1815 1899
1816 void * 1900 static void *
1817 ngx_resolver_calloc(ngx_resolver_t *r, size_t size) 1901 ngx_resolver_calloc(ngx_resolver_t *r, size_t size)
1818 { 1902 {
1819 u_char *p; 1903 u_char *p;
1820 1904
1821 p = ngx_resolver_alloc(r, size); 1905 p = ngx_resolver_alloc(r, size);