# HG changeset patch # User Igor Sysoev # Date 1319472545 0 # Node ID 016352c19049192a1c2e6565e3e0c9b413ed2310 # Parent 4c4997de65b80604d60df31c13d2d51778302133 Support of several servers in the "resolver" directive. Patch by Kirill A. Korinskiy. diff --git a/src/core/ngx_resolver.c b/src/core/ngx_resolver.c --- 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) { diff --git a/src/core/ngx_resolver.h b/src/core/ngx_resolver.h --- a/src/core/ngx_resolver.h +++ b/src/core/ngx_resolver.h @@ -77,16 +77,16 @@ typedef struct { typedef struct { /* has to be pointer because of "incomplete type" */ ngx_event_t *event; - - /* TODO: DNS peers balancer */ - /* STUB */ - ngx_udp_connection_t *udp_connection; - + void *dummy; ngx_log_t *log; /* ident must be after 3 pointers */ ngx_int_t ident; + /* simple round robin DNS peers balancer */ + ngx_array_t udp_connections; + ngx_uint_t last_connection; + ngx_rbtree_t name_rbtree; ngx_rbtree_node_t name_sentinel; @@ -123,8 +123,6 @@ struct ngx_resolver_ctx_s { in_addr_t *addrs; in_addr_t addr; - /* TODO: DNS peers balancer ctx */ - ngx_resolver_handler_pt handler; void *data; ngx_msec_t timeout; @@ -135,7 +133,8 @@ struct ngx_resolver_ctx_s { }; -ngx_resolver_t *ngx_resolver_create(ngx_conf_t *cf, ngx_addr_t *addr); +ngx_resolver_t *ngx_resolver_create(ngx_conf_t *cf, ngx_str_t *names, + ngx_uint_t n); ngx_resolver_ctx_t *ngx_resolve_start(ngx_resolver_t *r, ngx_resolver_ctx_t *temp); ngx_int_t ngx_resolve_name(ngx_resolver_ctx_t *ctx); diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c --- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -718,7 +718,7 @@ static ngx_command_t ngx_http_core_comm NULL }, { ngx_string("resolver"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, ngx_http_core_resolver, NGX_HTTP_LOC_CONF_OFFSET, 0, @@ -3535,7 +3535,7 @@ ngx_http_core_merge_loc_conf(ngx_conf_t * to inherit it in all servers */ - prev->resolver = ngx_resolver_create(cf, NULL); + prev->resolver = ngx_resolver_create(cf, NULL, 0); if (prev->resolver == NULL) { return NGX_CONF_ERROR; } @@ -4540,7 +4540,6 @@ ngx_http_core_resolver(ngx_conf_t *cf, n { ngx_http_core_loc_conf_t *clcf = conf; - ngx_url_t u; ngx_str_t *value; if (clcf->resolver) { @@ -4549,21 +4548,11 @@ ngx_http_core_resolver(ngx_conf_t *cf, n value = cf->args->elts; - ngx_memzero(&u, sizeof(ngx_url_t)); - - u.host = value[1]; - 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); + clcf->resolver = ngx_resolver_create(cf, &value[1], cf->args->nelts - 1); + if (clcf->resolver == NULL) { return NGX_CONF_ERROR; } - clcf->resolver = ngx_resolver_create(cf, &u.addrs[0]); - if (clcf->resolver == NULL) { - return NGX_OK; - } - return NGX_CONF_OK; } diff --git a/src/mail/ngx_mail_core_module.c b/src/mail/ngx_mail_core_module.c --- a/src/mail/ngx_mail_core_module.c +++ b/src/mail/ngx_mail_core_module.c @@ -69,7 +69,7 @@ static ngx_command_t ngx_mail_core_comm NULL }, { ngx_string("resolver"), - NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, + NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE, ngx_mail_core_resolver, NGX_MAIL_SRV_CONF_OFFSET, 0, @@ -493,7 +493,6 @@ ngx_mail_core_resolver(ngx_conf_t *cf, n { ngx_mail_core_srv_conf_t *cscf = conf; - ngx_url_t u; ngx_str_t *value; value = cf->args->elts; @@ -507,21 +506,11 @@ ngx_mail_core_resolver(ngx_conf_t *cf, n return NGX_CONF_OK; } - ngx_memzero(&u, sizeof(ngx_url_t)); - - u.host = value[1]; - 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); + cscf->resolver = ngx_resolver_create(cf, &value[1], cf->args->nelts - 1); + if (cscf->resolver == NULL) { return NGX_CONF_ERROR; } - cscf->resolver = ngx_resolver_create(cf, &u.addrs[0]); - if (cscf->resolver == NULL) { - return NGX_CONF_OK; - } - return NGX_CONF_OK; }