Support of several servers in the "resolver" directive.

Patch by Kirill A. Korinskiy.
This commit is contained in:
Igor Sysoev 2011-10-24 16:09:05 +00:00
parent ba71972b21
commit 620718102b
4 changed files with 58 additions and 51 deletions

View File

@ -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) {

View File

@ -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);

View File

@ -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;

View File

@ -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;