diff --git a/src/core/ngx_resolver.c b/src/core/ngx_resolver.c index ab7883011..268faa456 100644 --- a/src/core/ngx_resolver.c +++ b/src/core/ngx_resolver.c @@ -91,8 +91,10 @@ static u_char *ngx_resolver_log_error(ngx_log_t *log, u_char *buf, size_t len); 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_addr_t *addr) 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_addr_t *addr) 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; + ngx_memzero(uc, sizeof(ngx_udp_connection_t)); - uc->sockaddr = addr->sockaddr; - uc->socklen = addr->socklen; - uc->server = addr->name; + 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); - } - ngx_free(r->udp_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); @@ -242,7 +267,7 @@ ngx_resolve_start(ngx_resolver_t *r, ngx_resolver_ctx_t *temp) } } - 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 *r, ngx_resolver_node_t *rn) 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 index ef3c2082c..a2ddbefae 100644 --- 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 index c6909cd2e..7c4442265 100644 --- 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_commands[] = { 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 *cf, void *parent, void *child) * 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, ngx_command_t *cmd, void *conf) { ngx_http_core_loc_conf_t *clcf = conf; - ngx_url_t u; ngx_str_t *value; if (clcf->resolver) { @@ -4549,19 +4548,9 @@ ngx_http_core_resolver(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) 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); - return NGX_CONF_ERROR; - } - - clcf->resolver = ngx_resolver_create(cf, &u.addrs[0]); + clcf->resolver = ngx_resolver_create(cf, &value[1], cf->args->nelts - 1); if (clcf->resolver == NULL) { - return NGX_OK; + return NGX_CONF_ERROR; } return NGX_CONF_OK; diff --git a/src/mail/ngx_mail_core_module.c b/src/mail/ngx_mail_core_module.c index bd2c916d5..0088fbf26 100644 --- 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_commands[] = { 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, ngx_command_t *cmd, void *conf) { ngx_mail_core_srv_conf_t *cscf = conf; - ngx_url_t u; ngx_str_t *value; value = cf->args->elts; @@ -507,19 +506,9 @@ ngx_mail_core_resolver(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) 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); - return NGX_CONF_ERROR; - } - - cscf->resolver = ngx_resolver_create(cf, &u.addrs[0]); + cscf->resolver = ngx_resolver_create(cf, &value[1], cf->args->nelts - 1); if (cscf->resolver == NULL) { - return NGX_CONF_OK; + return NGX_CONF_ERROR; } return NGX_CONF_OK;