diff src/core/ngx_resolver.c @ 646:615b5ea36fc0 NGINX_1_1_7

nginx 1.1.7 *) Feature: support of several resolvers in the "resolver" directive. Thanks to Kirill A. Korinskiy. *) Bugfix: a segmentation fault occurred on start or while reconfiguration if the "ssl" directive was used at http level and there was no "ssl_certificate" defined. *) Bugfix: reduced memory consumption while proxying of big files if they were buffered to disk. *) Bugfix: a segmentation fault might occur in a worker process if "proxy_http_version 1.1" directive was used. *) Bugfix: in the "expires @time" directive.
author Igor Sysoev <http://sysoev.ru>
date Mon, 31 Oct 2011 00:00:00 +0400
parents 8dc007eddbcf
children f200748c0ac8
line wrap: on
line diff
--- a/src/core/ngx_resolver.c
+++ b/src/core/ngx_resolver.c
@@ -91,8 +91,10 @@ static u_char *ngx_resolver_log_error(ng
 
 
 ngx_resolver_t *
-ngx_resolver_create(ngx_conf_t *cf, ngx_addr_t *addr)
+ngx_resolver_create(ngx_conf_t *cf, ngx_str_t *names, ngx_uint_t n)
 {
+    ngx_url_t              u;
+    ngx_uint_t             i;
     ngx_resolver_t        *r;
     ngx_pool_cleanup_t    *cln;
     ngx_udp_connection_t  *uc;
@@ -109,6 +111,15 @@ ngx_resolver_create(ngx_conf_t *cf, ngx_
         return NULL;
     }
 
+    if (n) {
+        if (ngx_array_init(&r->udp_connections, cf->pool, n,
+                           sizeof(ngx_udp_connection_t))
+            != NGX_OK)
+        {
+            return NULL;
+        }
+    }
+
     cln->data = r;
 
     r->event = ngx_calloc(sizeof(ngx_event_t), cf->log);
@@ -140,17 +151,27 @@ ngx_resolver_create(ngx_conf_t *cf, ngx_
     r->log = &cf->cycle->new_log;
     r->log_level = NGX_LOG_ERR;
 
-    if (addr) {
-        uc = ngx_calloc(sizeof(ngx_udp_connection_t), cf->log);
+    for (i = 0; i < n; i++) {
+        ngx_memzero(&u, sizeof(ngx_url_t));
+
+        u.host = names[i];
+        u.port = 53;
+
+        if (ngx_inet_resolve_host(cf->pool, &u) != NGX_OK) {
+            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%V: %s", &u.host, u.err);
+            return NULL;
+        }
+
+        uc = ngx_array_push(&r->udp_connections);
         if (uc == NULL) {
             return NULL;
         }
 
-        r->udp_connection = uc;
-
-        uc->sockaddr = addr->sockaddr;
-        uc->socklen = addr->socklen;
-        uc->server = addr->name;
+        ngx_memzero(uc, sizeof(ngx_udp_connection_t));
+
+        uc->sockaddr = u.addrs->sockaddr;
+        uc->socklen = u.addrs->socklen;
+        uc->server = u.addrs->name;
 
         uc->log = cf->cycle->new_log;
         uc->log.handler = ngx_resolver_log_error;
@@ -167,6 +188,9 @@ ngx_resolver_cleanup(void *data)
 {
     ngx_resolver_t  *r = data;
 
+    ngx_uint_t             i;
+    ngx_udp_connection_t  *uc;
+
     if (r) {
         ngx_log_debug0(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0,
                        "cleanup resolver");
@@ -179,12 +203,13 @@ ngx_resolver_cleanup(void *data)
             ngx_free(r->event);
         }
 
-        if (r->udp_connection) {
-            if (r->udp_connection->connection) {
-                ngx_close_connection(r->udp_connection->connection);
+
+        uc = r->udp_connections.elts;
+
+        for (i = 0; i < r->udp_connections.nelts; i++) {
+            if (uc[i].connection) {
+                ngx_close_connection(uc[i].connection);
             }
-
-            ngx_free(r->udp_connection);
         }
 
         ngx_free(r);
@@ -242,7 +267,7 @@ ngx_resolve_start(ngx_resolver_t *r, ngx
         }
     }
 
-    if (r->udp_connection == NULL) {
+    if (r->udp_connections.nelts == 0) {
         return NGX_NO_RESOLVER;
     }
 
@@ -826,7 +851,12 @@ ngx_resolver_send_query(ngx_resolver_t *
     ssize_t                n;
     ngx_udp_connection_t  *uc;
 
-    uc = r->udp_connection;
+    uc = r->udp_connections.elts;
+
+    uc = &uc[r->last_connection++];
+    if (r->last_connection == r->udp_connections.nelts) {
+        r->last_connection = 0;
+    }
 
     if (uc->connection == NULL) {
         if (ngx_udp_connect(uc) != NGX_OK) {