static void ngx_http_upstream_resolveMK_handler(ngx_resolver_ctx_t *ctx) { ngx_resolver_t *r; ngx_http_upstream_resolveMK_peer_t *peer; ngx_http_upstream_resolveMK_srv_conf_t *urcf; struct sockaddr *addr; ngx_uint_t i; r = ctx->resolver; urcf = (ngx_http_upstream_resolveMK_srv_conf_t *)ctx->data; ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->log, 0, "upstream_resolveMK: \"%V\" resolved state(%i: %s)", &ctx->name, ctx->state, ngx_resolver_strerror(ctx->state)); if (ctx->state || ctx->naddrs == 0) { ngx_log_error(NGX_LOG_ERR, r->log, 0, "upstream_resolveMK: resolver failed ,\"%V\" (%i: %s))", &ctx->name, ctx->state, ngx_resolver_strerror(ctx->state)); goto end; } urcf->resolved_num = 0; for (i = 0; i < ctx->nsrvs; i++) { peer = &urcf->peers[urcf->resolved_num]; addr = &peer->sockaddr; peer->socklen = ctx->srvs[i].addrs[0].socklen; ngx_memcpy(addr, ctx->srvs[i].addrs[0].sockaddr, peer->socklen); switch (addr->sa_family) { case AF_INET6: ((struct sockaddr_in6*)addr)->sin6_port = htons(ctx->srvs[i].port); break; default: ((struct sockaddr_in*)addr)->sin_port = htons(ctx->srvs[i].port); } peer->name.data = peer->ipstr; peer->name.len = ngx_sock_ntop(addr, peer->socklen, peer->ipstr, NGX_SOCKADDR_STRLEN, 1); urcf->resolved_num++; if (urcf->resolved_num >= urcf->resolver_max_ip) { break; } } end: ngx_resolve_name_done(ctx); urcf->resolved_access = ngx_time(); urcf->resolver_stats = RESOLVE_STATS_DONE; }
static void ngx_mail_smtp_resolve_name_handler(ngx_resolver_ctx_t *ctx) { ngx_uint_t i; ngx_connection_t *c; ngx_mail_session_t *s; s = ctx->data; c = s->connection; if (ctx->state) { ngx_log_error(NGX_LOG_ERR, c->log, 0, "\"%V\" could not be resolved (%i: %s)", &ctx->name, ctx->state, ngx_resolver_strerror(ctx->state)); if (ctx->state == NGX_RESOLVE_NXDOMAIN) { s->host = smtp_unavailable; } else { s->host = smtp_tempunavail; } } else { #if (NGX_DEBUG) { u_char text[NGX_SOCKADDR_STRLEN]; ngx_str_t addr; addr.data = text; for (i = 0; i < ctx->naddrs; i++) { addr.len = ngx_sock_ntop(ctx->addrs[i].sockaddr, ctx->addrs[i].socklen, text, NGX_SOCKADDR_STRLEN, 0); ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0, "name was resolved to %V", &addr); } } #endif for (i = 0; i < ctx->naddrs; i++) { if (ngx_cmp_sockaddr(ctx->addrs[i].sockaddr, ctx->addrs[i].socklen, c->sockaddr, c->socklen, 0) == NGX_OK) { goto found; } } s->host = smtp_unavailable; } found: ngx_resolve_name_done(ctx); ngx_mail_smtp_greeting(s, c); }
static void ngx_mail_smtp_resolve_name_handler(ngx_resolver_ctx_t *ctx) { in_addr_t addr; ngx_uint_t i; ngx_connection_t *c; struct sockaddr_in *sin; ngx_mail_session_t *s; s = ctx->data; c = s->connection; if (ctx->state) { ngx_log_error(NGX_LOG_ERR, c->log, 0, "%V could not be resolved (%i: %s)", &ctx->name, ctx->state, ngx_resolver_strerror(ctx->state)); if (ctx->state == NGX_RESOLVE_NXDOMAIN) { s->host = smtp_unavailable; } else { s->host = smtp_tempunavail; } } else { /* AF_INET only */ sin = (struct sockaddr_in *) c->sockaddr; for (i = 0; i < ctx->naddrs; i++) { addr = ctx->addrs[i]; ngx_log_debug4(NGX_LOG_DEBUG_MAIL, c->log, 0, "name was resolved to %ud.%ud.%ud.%ud", (ntohl(addr) >> 24) & 0xff, (ntohl(addr) >> 16) & 0xff, (ntohl(addr) >> 8) & 0xff, ntohl(addr) & 0xff); if (addr == sin->sin_addr.s_addr) { goto found; } } s->host = smtp_unavailable; } found: ngx_resolve_name_done(ctx); ngx_mail_smtp_greeting(s, c); }
static void ngx_tcp_upstream_resolve_handler(ngx_resolver_ctx_t *ctx) { ngx_tcp_session_t *s; ngx_tcp_upstream_resolved_t *ur; s = ctx->data; s->upstream->resolved->ctx = NULL; if (ctx->state) { ngx_log_error(NGX_LOG_ERR, s->connection->log, 0, "%V could not be resolved (%i: %s)", &ctx->name, ctx->state, ngx_resolver_strerror(ctx->state)); ngx_resolve_name_done(ctx); ngx_tcp_finalize_session(s); return; } ur = s->upstream->resolved; ur->naddrs = ctx->naddrs; ur->addrs = ctx->addrs; #if (NGX_DEBUG) { in_addr_t addr; ngx_uint_t i; for (i = 0; i < ctx->naddrs; i++) { addr = ntohl(ur->addrs[i]); ngx_log_debug4(NGX_LOG_DEBUG_TCP, s->connection->log, 0, "name was resolved to %ud.%ud.%ud.%ud", (addr >> 24) & 0xff, (addr >> 16) & 0xff, (addr >> 8) & 0xff, addr & 0xff); } } #endif if (ngx_tcp_upstream_create_round_robin_peer(s, ur) != NGX_OK) { ngx_resolve_name_done(ctx); ngx_tcp_finalize_session(s); return; } ngx_resolve_name_done(ctx); ngx_tcp_upstream_connect(s, s->upstream); /*need add the event.*/ }
static void ngx_mail_smtp_resolve_addr_handler(ngx_resolver_ctx_t *ctx) { ngx_connection_t *c; ngx_mail_session_t *s; s = ctx->data; c = s->connection; if (ctx->state) { ngx_log_error(NGX_LOG_ERR, c->log, 0, "%V could not be resolved (%i: %s)", &c->addr_text, ctx->state, ngx_resolver_strerror(ctx->state)); if (ctx->state == NGX_RESOLVE_NXDOMAIN) { s->host = smtp_unavailable; } else { s->host = smtp_tempunavail; } ngx_resolve_addr_done(ctx); ngx_mail_smtp_greeting(s, s->connection); return; } c->log->action = "in resolving client hostname"; s->host.data = ngx_pstrdup(c->pool, &ctx->name); if (s->host.data == NULL) { ngx_resolve_addr_done(ctx); ngx_mail_close_connection(c); return; } s->host.len = ctx->name.len; ngx_resolve_addr_done(ctx); ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0, "address resolved: %V", &s->host); c->read->handler = ngx_mail_smtp_resolve_name; ngx_post_event(c->read, &ngx_posted_events); }
static void dns_handler(ngx_resolver_ctx_t * rctx) { ngx_http_request_t * r = rctx->data; ngx_http_rdns_ctx_t * ctx; ngx_http_rdns_loc_conf_t * loc_cf; struct sockaddr_in * sin = (struct sockaddr_in *) r->connection->sockaddr; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "rdns: dns request handler"); ctx = ngx_http_get_module_ctx(r, ngx_http_rdns_module); if (ctx == NULL) { ngx_log_debug0(NGX_LOG_ERR, r->connection->log, 0, "rdns: dns request handler: failed to get request context"); ngx_resolve_name_done(rctx); ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); return; } loc_cf = ngx_http_get_module_loc_conf(r, ngx_http_rdns_module); if (loc_cf == NULL) { ngx_log_debug0(NGX_LOG_ERR, r->connection->log, 0, "rdns: dns request handler: failed to get rdns location config"); ngx_resolve_name_done(rctx); ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); return; } if (rctx->state) { ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "rdns: dns request handler: failed with error '%s'", ngx_resolver_strerror(rctx->state)); ngx_resolve_name_done(rctx); var_set(r, loc_cf->rdns_result_index, var_rdns_result_not_found); } else { int found = 0; in_addr_t orig_in_addr = sin->sin_addr.s_addr; ngx_uint_t i; for (i = 0; i < rctx->naddrs; ++i) { in_addr_t resolved_in_addr; #if (OLD_RESOLVER_API) resolved_in_addr = rctx->addrs[i]; #else resolved_in_addr = ((struct sockaddr_in *) rctx->addrs[i].sockaddr)->sin_addr.s_addr; #endif ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "rdns: dns request handler: checking result '%d'", resolved_in_addr); if (resolved_in_addr == orig_in_addr) { ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "rdns: dns request handler: resolved to '%V'", &rctx->name); var_set(r, loc_cf->rdns_result_index, rctx->name); ngx_resolve_name_done(rctx); found = 1; break; } } if (!found) { ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "rdns: dns request handler: resolving inconsistency: '%d' -> '%V' !-> '%d'", sin->sin_addr.s_addr, &rctx->name, sin->sin_addr.s_addr); ngx_resolve_name_done(rctx); var_set(r, loc_cf->rdns_result_index, var_rdns_result_not_found); } } ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "(DONE) rdns: dns request handler"); resolver_handler_finalize(r, ctx); }
static void rdns_handler(ngx_resolver_ctx_t * rctx) { ngx_http_request_t * r = rctx->data; ngx_http_rdns_ctx_t * ctx = ngx_http_get_module_ctx(r, ngx_http_rdns_module); ngx_http_rdns_loc_conf_t * loc_cf; ngx_http_rdns_common_conf_t * cconf; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "rdns: reverse dns request handler"); if (ctx == NULL) { ngx_log_debug0(NGX_LOG_ERR, r->connection->log, 0, "rdns: reverse dns request handler: failed to get request context"); ngx_resolve_addr_done(rctx); ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); return; } loc_cf = ngx_http_get_module_loc_conf(r, ngx_http_rdns_module); if (loc_cf == NULL) { ngx_log_debug0(NGX_LOG_ERR, r->connection->log, 0, "rdns: reverse dns request handler: failed to get rdns location config"); ngx_resolve_addr_done(rctx); ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); return; } if (rctx->state) { ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "rdns: reverse dns request handler: failed with error '%s'", ngx_resolver_strerror(rctx->state)); ngx_resolve_addr_done(rctx); var_set(r, loc_cf->rdns_result_index, var_rdns_result_not_found); resolver_handler_finalize(r, ctx); } else { ngx_str_t hostname; ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "rdns: reverse dns request handler: result='%V'", &rctx->name); hostname.data = ngx_pcalloc(r->pool, rctx->name.len * sizeof(u_char)); ngx_memcpy(hostname.data, rctx->name.data, rctx->name.len); hostname.len = rctx->name.len; ngx_resolve_addr_done(rctx); cconf = rdns_get_common_conf(ctx, loc_cf); if (cconf == NULL) { ngx_log_debug0(NGX_LOG_ERR, r->connection->log, 0, "rdns: reverse dns request handler: failed to get common config"); ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); return; } if (cconf->double_mode) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "rdns: reverse dns request handler: double mode"); dns_request(r, hostname); } else { ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "rdns: reverse dns request handler: resolved to '%V'", &hostname); var_set(r, loc_cf->rdns_result_index, hostname); ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "(DONE) rdns: reverse dns request handler"); resolver_handler_finalize(r, ctx); } } }
static void ngx_http_lua_socket_resolve_handler(ngx_resolver_ctx_t *ctx) { ngx_http_request_t *r; ngx_connection_t *c; ngx_http_upstream_resolved_t *ur; ngx_http_lua_ctx_t *lctx; lua_State *L; ngx_http_lua_socket_udp_upstream_t *u; u_char *p; size_t len; struct sockaddr_in *sin; ngx_uint_t i; unsigned waiting; u = ctx->data; r = u->request; c = r->connection; ur = u->resolved; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "lua udp socket resolve handler"); lctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); if (lctx == NULL) { return; } lctx->cur_co_ctx = u->co_ctx; u->co_ctx->cleanup = NULL; L = lctx->cur_co_ctx->co; dd("setting socket_ready to 1"); waiting = u->waiting; if (ctx->state) { ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, "lua udp socket resolver error: %s (waiting: %d)", ngx_resolver_strerror(ctx->state), (int) u->waiting); lua_pushnil(L); lua_pushlstring(L, (char *) ctx->name.data, ctx->name.len); lua_pushfstring(L, " could not be resolved (%d: %s)", (int) ctx->state, ngx_resolver_strerror(ctx->state)); lua_concat(L, 2); u->prepare_retvals = ngx_http_lua_socket_error_retval_handler; ngx_http_lua_socket_udp_handle_error(r, u, NGX_HTTP_LUA_SOCKET_FT_RESOLVER); if (waiting) { ngx_http_run_posted_requests(c); } return; } ur->naddrs = ctx->naddrs; ur->addrs = ctx->addrs; #if (NGX_DEBUG) { in_addr_t addr; ngx_uint_t i; for (i = 0; i < ctx->naddrs; i++) { dd("addr i: %d %p", (int) i, &ctx->addrs[i]); addr = ntohl(ctx->addrs[i]); ngx_log_debug4(NGX_LOG_DEBUG_HTTP, c->log, 0, "name was resolved to %ud.%ud.%ud.%ud", (addr >> 24) & 0xff, (addr >> 16) & 0xff, (addr >> 8) & 0xff, addr & 0xff); } } #endif if (ur->naddrs == 0) { ngx_resolve_name_done(ctx); u->ft_type |= NGX_HTTP_LUA_SOCKET_FT_RESOLVER; lua_pushnil(L); lua_pushliteral(L, "name cannot be resolved to a address"); if (waiting) { ngx_http_run_posted_requests(c); } return; } if (ur->naddrs == 1) { i = 0; } else { i = ngx_random() % ur->naddrs; } dd("selected addr index: %d", (int) i); len = NGX_INET_ADDRSTRLEN + sizeof(":65536") - 1; p = ngx_pnalloc(r->pool, len + sizeof(struct sockaddr_in)); if (p == NULL) { ngx_resolve_name_done(ctx); u->ft_type |= NGX_HTTP_LUA_SOCKET_FT_RESOLVER; lua_pushnil(L); lua_pushliteral(L, "out of memory"); if (waiting) { ngx_http_run_posted_requests(c); } return; } sin = (struct sockaddr_in *) &p[len]; ngx_memzero(sin, sizeof(struct sockaddr_in)); len = ngx_inet_ntop(AF_INET, &ur->addrs[i], p, NGX_INET_ADDRSTRLEN); len = ngx_sprintf(&p[len], ":%d", ur->port) - p; sin->sin_family = AF_INET; sin->sin_port = htons(ur->port); sin->sin_addr.s_addr = ur->addrs[i]; ur->sockaddr = (struct sockaddr *) sin; ur->socklen = sizeof(struct sockaddr_in); ur->host.data = p; ur->host.len = len; ur->naddrs = 1; ur->ctx = NULL; ngx_resolve_name_done(ctx); u->waiting = 0; if (waiting) { lctx->resume_handler = ngx_http_lua_socket_udp_resume; r->write_event_handler(r); ngx_http_run_posted_requests(c); } else { (void) ngx_http_lua_socket_resolve_retval_handler(r, u, L); } }
static void ngx_http_lua_socket_resolve_handler(ngx_resolver_ctx_t *ctx) { ngx_http_request_t *r; ngx_connection_t *c; ngx_http_upstream_resolved_t *ur; ngx_http_lua_ctx_t *lctx; lua_State *L; ngx_http_lua_socket_udp_upstream_t *u; u_char *p; size_t len; #if defined(nginx_version) && nginx_version >= 1005008 socklen_t socklen; struct sockaddr *sockaddr; #else struct sockaddr_in *sin; #endif ngx_uint_t i; unsigned waiting; u = ctx->data; r = u->request; c = r->connection; ur = u->resolved; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "lua udp socket resolve handler"); lctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); if (lctx == NULL) { return; } lctx->cur_co_ctx = u->co_ctx; u->co_ctx->cleanup = NULL; L = lctx->cur_co_ctx->co; dd("setting socket_ready to 1"); waiting = u->waiting; if (ctx->state) { ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, "lua udp socket resolver error: %s (waiting: %d)", ngx_resolver_strerror(ctx->state), (int) u->waiting); lua_pushnil(L); lua_pushlstring(L, (char *) ctx->name.data, ctx->name.len); lua_pushfstring(L, " could not be resolved (%d: %s)", (int) ctx->state, ngx_resolver_strerror(ctx->state)); lua_concat(L, 2); #if 1 ngx_resolve_name_done(ctx); ur->ctx = NULL; #endif u->prepare_retvals = ngx_http_lua_socket_error_retval_handler; ngx_http_lua_socket_udp_handle_error(r, u, NGX_HTTP_LUA_SOCKET_FT_RESOLVER); if (waiting) { ngx_http_run_posted_requests(c); } return; } ur->naddrs = ctx->naddrs; ur->addrs = ctx->addrs; #if (NGX_DEBUG) { # if defined(nginx_version) && nginx_version >= 1005008 u_char text[NGX_SOCKADDR_STRLEN]; ngx_str_t addr; # else in_addr_t addr; # endif ngx_uint_t i; # if defined(nginx_version) && nginx_version >= 1005008 addr.data = text; for (i = 0; i < ctx->naddrs; i++) { addr.len = ngx_sock_ntop(ur->addrs[i].sockaddr, ur->addrs[i].socklen, text, NGX_SOCKADDR_STRLEN, 0); ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "name was resolved to %V", &addr); } # else for (i = 0; i < ctx->naddrs; i++) { dd("addr i: %d %p", (int) i, &ctx->addrs[i]); addr = ntohl(ctx->addrs[i]); ngx_log_debug4(NGX_LOG_DEBUG_HTTP, c->log, 0, "name was resolved to %ud.%ud.%ud.%ud", (addr >> 24) & 0xff, (addr >> 16) & 0xff, (addr >> 8) & 0xff, addr & 0xff); } # endif } #endif ngx_http_lua_assert(ur->naddrs > 0); if (ur->naddrs == 1) { i = 0; } else { i = ngx_random() % ur->naddrs; } dd("selected addr index: %d", (int) i); #if defined(nginx_version) && nginx_version >= 1005008 socklen = ur->addrs[i].socklen; sockaddr = ngx_palloc(r->pool, socklen); if (sockaddr == NULL) { goto nomem; } ngx_memcpy(sockaddr, ur->addrs[i].sockaddr, socklen); switch (sockaddr->sa_family) { #if (NGX_HAVE_INET6) case AF_INET6: ((struct sockaddr_in6 *) sockaddr)->sin6_port = htons(ur->port); break; #endif default: /* AF_INET */ ((struct sockaddr_in *) sockaddr)->sin_port = htons(ur->port); } p = ngx_pnalloc(r->pool, NGX_SOCKADDR_STRLEN); if (p == NULL) { goto nomem; } len = ngx_sock_ntop(sockaddr, socklen, p, NGX_SOCKADDR_STRLEN, 1); ur->sockaddr = sockaddr; ur->socklen = socklen; #else /* for nginx older than 1.5.8 */ len = NGX_INET_ADDRSTRLEN + sizeof(":65536") - 1; p = ngx_pnalloc(r->pool, len + sizeof(struct sockaddr_in)); if (p == NULL) { goto nomem; } sin = (struct sockaddr_in *) &p[len]; ngx_memzero(sin, sizeof(struct sockaddr_in)); len = ngx_inet_ntop(AF_INET, &ur->addrs[i], p, NGX_INET_ADDRSTRLEN); len = ngx_sprintf(&p[len], ":%d", ur->port) - p; sin->sin_family = AF_INET; sin->sin_port = htons(ur->port); sin->sin_addr.s_addr = ur->addrs[i]; ur->sockaddr = (struct sockaddr *) sin; ur->socklen = sizeof(struct sockaddr_in); #endif ur->host.data = p; ur->host.len = len; ur->naddrs = 1; ngx_resolve_name_done(ctx); ur->ctx = NULL; u->waiting = 0; if (waiting) { lctx->resume_handler = ngx_http_lua_socket_udp_resume; r->write_event_handler(r); ngx_http_run_posted_requests(c); } else { (void) ngx_http_lua_socket_resolve_retval_handler(r, u, L); } return; nomem: if (ur->ctx) { ngx_resolve_name_done(ctx); ur->ctx = NULL; } u->prepare_retvals = ngx_http_lua_socket_error_retval_handler; ngx_http_lua_socket_udp_handle_error(r, u, NGX_HTTP_LUA_SOCKET_FT_NOMEM); if (waiting) { ngx_http_run_posted_requests(c); } else { lua_pushnil(L); lua_pushliteral(L, "no memory"); } }
static void ngx_ssl_ocsp_resolve_handler(ngx_resolver_ctx_t *resolve) { ngx_ssl_ocsp_ctx_t *ctx = resolve->data; u_char *p; size_t len; in_port_t port; socklen_t socklen; ngx_uint_t i; struct sockaddr *sockaddr; ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ctx->log, 0, "ssl ocsp resolve handler"); if (resolve->state) { ngx_log_error(NGX_LOG_ERR, ctx->log, 0, "%V could not be resolved (%i: %s)", &resolve->name, resolve->state, ngx_resolver_strerror(resolve->state)); goto failed; } #if (NGX_DEBUG) { u_char text[NGX_SOCKADDR_STRLEN]; ngx_str_t addr; addr.data = text; for (i = 0; i < resolve->naddrs; i++) { addr.len = ngx_sock_ntop(resolve->addrs[i].sockaddr, resolve->addrs[i].socklen, text, NGX_SOCKADDR_STRLEN, 0); ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ctx->log, 0, "name was resolved to %V", &addr); } } #endif ctx->naddrs = resolve->naddrs; ctx->addrs = ngx_pcalloc(ctx->pool, ctx->naddrs * sizeof(ngx_addr_t)); if (ctx->addrs == NULL) { goto failed; } port = htons(ctx->port); for (i = 0; i < resolve->naddrs; i++) { socklen = resolve->addrs[i].socklen; sockaddr = ngx_palloc(ctx->pool, socklen); if (sockaddr == NULL) { goto failed; } ngx_memcpy(sockaddr, resolve->addrs[i].sockaddr, socklen); switch (sockaddr->sa_family) { #if (NGX_HAVE_INET6) case AF_INET6: ((struct sockaddr_in6 *) sockaddr)->sin6_port = port; break; #endif default: /* AF_INET */ ((struct sockaddr_in *) sockaddr)->sin_port = port; } ctx->addrs[i].sockaddr = sockaddr; ctx->addrs[i].socklen = socklen; p = ngx_pnalloc(ctx->pool, NGX_SOCKADDR_STRLEN); if (p == NULL) { goto failed; } len = ngx_sock_ntop(sockaddr, socklen, p, NGX_SOCKADDR_STRLEN, 1); ctx->addrs[i].name.len = len; ctx->addrs[i].name.data = p; } ngx_resolve_name_done(resolve); ngx_ssl_ocsp_connect(ctx); return; failed: ngx_resolve_name_done(resolve); ngx_ssl_ocsp_error(ctx); }
static void ngx_http_upstream_dynamic_handler(ngx_resolver_ctx_t *ctx) { ngx_http_request_t *r; ngx_http_upstream_t *u; ngx_peer_connection_t *pc; struct sockaddr_in *sin, *csin; in_port_t port; ngx_str_t *addr; u_char *p; size_t len; ngx_http_upstream_srv_conf_t *us; ngx_http_upstream_dynamic_srv_conf_t *dscf; r = ctx->data; u = r->upstream; us = u->conf->upstream; pc = &u->peer; dscf = ngx_http_conf_upstream_srv_conf(us, ngx_http_upstream_dynamic_module); if (ctx->state) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "%V could not be resolved (%i: %s)", &ctx->name, ctx->state, ngx_resolver_strerror(ctx->state)); dscf->fail_check = ngx_time(); pc->resolved = NGX_HTTP_UPSTREAM_DR_FAILED; } else { /* dns query ok */ dscf->fail_check = 0; sin = ngx_pcalloc(r->pool, sizeof(struct sockaddr_in)); if (sin == NULL) { ngx_http_upstream_finalize_request(r, u, NGX_HTTP_INTERNAL_SERVER_ERROR); return; } ngx_memcpy(sin, pc->sockaddr, pc->socklen); /* only the first IP addr is used in version 1 */ csin = (struct sockaddr_in *) ctx->addrs[0].sockaddr; if (sin->sin_addr.s_addr == csin->sin_addr.s_addr) { pc->resolved = NGX_HTTP_UPSTREAM_DR_OK; goto out; } sin->sin_addr.s_addr = csin->sin_addr.s_addr; len = NGX_INET_ADDRSTRLEN + sizeof(":65535") - 1; p = ngx_pnalloc(r->pool, len); if (p == NULL) { ngx_http_upstream_finalize_request(r, u, NGX_HTTP_INTERNAL_SERVER_ERROR); return; } port = ntohs(sin->sin_port); len = ngx_inet_ntop(AF_INET, &sin->sin_addr.s_addr, p, NGX_INET_ADDRSTRLEN); len = ngx_sprintf(&p[len], ":%d", port) - p; addr = ngx_palloc(r->pool, sizeof(ngx_str_t)); if (addr == NULL) { ngx_http_upstream_finalize_request(r, u, NGX_HTTP_INTERNAL_SERVER_ERROR); return; } addr->data = p; addr->len = len; pc->sockaddr = (struct sockaddr *) sin; pc->socklen = sizeof(struct sockaddr_in); pc->name = addr; ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "name was resolved to %V", pc->name); pc->resolved = NGX_HTTP_UPSTREAM_DR_OK; } out: ngx_resolve_name_done(ctx); u->dyn_resolve_ctx = NULL; ngx_http_upstream_connect(r, u); }
static void ngx_resolver_process_response(ngx_resolver_t *r, u_char *buf, size_t n) { char *err; size_t len; ngx_uint_t i, times, ident, qident, flags, code, nqs, nan, qtype, qclass; ngx_queue_t *q; ngx_resolver_qs_t *qs; ngx_resolver_node_t *rn; ngx_resolver_query_t *query; if ((size_t) n < sizeof(ngx_resolver_query_t)) { goto short_response; } query = (ngx_resolver_query_t *) buf; ident = (query->ident_hi << 8) + query->ident_lo; flags = (query->flags_hi << 8) + query->flags_lo; nqs = (query->nqs_hi << 8) + query->nqs_lo; nan = (query->nan_hi << 8) + query->nan_lo; ngx_log_debug6(NGX_LOG_DEBUG_CORE, r->log, 0, "resolver DNS response %ui fl:%04Xui %ui/%ui/%ui/%ui", ident, flags, nqs, nan, (query->nns_hi << 8) + query->nns_lo, (query->nar_hi << 8) + query->nar_lo); if (!(flags & 0x8000)) { ngx_log_error(r->log_level, r->log, 0, "invalid DNS response %ui fl:%04Xui", ident, flags); return; } code = flags & 0x7f; if (code == NGX_RESOLVE_FORMERR) { times = 0; for (q = ngx_queue_head(&r->name_resend_queue); q != ngx_queue_sentinel(&r->name_resend_queue) || times++ < 100; q = ngx_queue_next(q)) { rn = ngx_queue_data(q, ngx_resolver_node_t, queue); qident = (rn->query[0] << 8) + rn->query[1]; if (qident == ident) { ngx_log_error(r->log_level, r->log, 0, "DNS error (%ui: %s), query id:%ui, name:\"%*s\"", code, ngx_resolver_strerror(code), ident, rn->nlen, rn->name); return; } } goto dns_error; } if (code > NGX_RESOLVE_REFUSED) { goto dns_error; } if (nqs != 1) { err = "invalid number of questions in DNS response"; goto done; } i = sizeof(ngx_resolver_query_t); while (i < (ngx_uint_t) n) { if (buf[i] == '\0') { goto found; } len = buf[i]; i += 1 + len; } goto short_response; found: if (i++ == 0) { err = "zero-length domain name in DNS response"; goto done; } if (i + sizeof(ngx_resolver_qs_t) + nan * (2 + sizeof(ngx_resolver_an_t)) > (ngx_uint_t) n) { goto short_response; } qs = (ngx_resolver_qs_t *) &buf[i]; qtype = (qs->type_hi << 8) + qs->type_lo; qclass = (qs->class_hi << 8) + qs->class_lo; ngx_log_debug2(NGX_LOG_DEBUG_CORE, r->log, 0, "resolver DNS response qt:%ui cl:%ui", qtype, qclass); if (qclass != 1) { ngx_log_error(r->log_level, r->log, 0, "unknown query class %ui in DNS response", qclass); return; } switch (qtype) { case NGX_RESOLVE_A: ngx_resolver_process_a(r, buf, n, ident, code, nan, i + sizeof(ngx_resolver_qs_t)); break; case NGX_RESOLVE_PTR: ngx_resolver_process_ptr(r, buf, n, ident, code, nan); break; default: ngx_log_error(r->log_level, r->log, 0, "unknown query type %ui in DNS response", qtype); return; } return; short_response: err = "short dns response"; done: ngx_log_error(r->log_level, r->log, 0, err); return; dns_error: ngx_log_error(r->log_level, r->log, 0, "DNS error (%ui: %s), query id:%ui", code, ngx_resolver_strerror(code), ident); return; }
static void ngx_http_upstream_dynamic_server_resolve_handler(ngx_resolver_ctx_t *ctx) { ngx_http_upstream_dynamic_server_main_conf_t *udsmcf = ngx_http_cycle_get_module_main_conf(ngx_cycle, ngx_http_upstream_dynamic_servers_module); ngx_http_upstream_dynamic_server_conf_t *dynamic_server; ngx_conf_t cf; uint32_t hash; ngx_resolver_node_t *rn; ngx_pool_t *new_pool; ngx_addr_t *addrs; dynamic_server = ctx->data; ngx_log_debug(NGX_LOG_DEBUG_CORE, ctx->resolver->log, 0, "upstream-dynamic-servers: Finished resolving '%V'", &ctx->name); if (ctx->state) { ngx_log_error(NGX_LOG_ERR, ctx->resolver->log, 0, "upstream-dynamic-servers: '%V' could not be resolved (%i: %s)", &ctx->name, ctx->state, ngx_resolver_strerror(ctx->state)); ngx_url_t u; ngx_memzero(&u, sizeof(ngx_url_t)); // If the domain fails to resolve on start up, assign a static IP that // should never route (we'll also mark it as down in the upstream later // on). This is to account for various things inside nginx that seem to // expect a server to always have at least 1 IP. u.url = ngx_http_upstream_dynamic_server_null_route; u.default_port = 80; u.no_resolve = 1; if (ngx_parse_url(ngx_cycle->pool, &u) != NGX_OK) { if (u.err) { ngx_log_error(NGX_LOG_ERR, ctx->resolver->log, 0, "%s in upstream \"%V\"", u.err, &u.url); } goto end; } ctx->addr.sockaddr = u.addrs[0].sockaddr; ctx->addr.socklen = u.addrs[0].socklen; ctx->addr.name = u.addrs[0].name; ctx->addrs = &ctx->addr; ctx->naddrs = u.naddrs; } if (ctx->naddrs != dynamic_server->server->naddrs) { goto reinit_upstream; } ngx_uint_t i, j, founded; ngx_addr_t *existing_addr; for (i = 0; i < ctx->naddrs; i++) { founded = 0; for (j = 0; j < ctx->naddrs; j++) { existing_addr = &dynamic_server->server->addrs[j]; if (ngx_cmp_sockaddr(existing_addr->sockaddr, existing_addr->socklen, ctx->addrs[i].sockaddr, ctx->addrs[i].socklen, 0) == NGX_OK) { founded = 1; break; } } if (!founded) { goto reinit_upstream; } } ngx_log_debug(NGX_LOG_DEBUG_CORE, ctx->resolver->log, 0, "upstream-dynamic-servers: No DNS changes for '%V' - keeping existing upstream configuration", &ctx->name); goto end; reinit_upstream: new_pool = ngx_create_pool(NGX_DEFAULT_POOL_SIZE, ctx->resolver->log); if (new_pool == NULL) { ngx_log_error(NGX_LOG_ERR, ctx->resolver->log, 0, "upstream-dynamic-servers: Could not create new pool"); goto end; } ngx_log_debug(NGX_LOG_DEBUG_CORE, ctx->resolver->log, 0, "upstream-dynamic-servers: DNS changes for '%V' detected - reinitializing upstream configuration", &ctx->name); ngx_memzero(&cf, sizeof(ngx_conf_t)); cf.name = "dynamic_server_init_upstream"; cf.cycle = (ngx_cycle_t *) ngx_cycle; cf.pool = new_pool; cf.module_type = NGX_HTTP_MODULE; cf.cmd_type = NGX_HTTP_MAIN_CONF; cf.log = ngx_cycle->log; cf.ctx = udsmcf->conf_ctx; addrs = ngx_pcalloc(new_pool, ctx->naddrs * sizeof(ngx_addr_t)); ngx_memcpy(addrs, ctx->addrs, ctx->naddrs * sizeof(ngx_addr_t)); struct sockaddr *sockaddr; ngx_addr_t *addr; socklen_t socklen; for (i = 0; i < ctx->naddrs; i++) { addr = &addrs[i]; socklen = ctx->addrs[i].socklen; sockaddr = ngx_palloc(new_pool, socklen); ngx_memcpy(sockaddr, ctx->addrs[i].sockaddr, socklen); switch(sockaddr->sa_family) { case AF_INET6: ((struct sockaddr_in6 *)sockaddr)->sin6_port = htons((u_short) dynamic_server->port); break; default: ((struct sockaddr_in *)sockaddr)->sin_port = htons((u_short) dynamic_server->port); } addr->sockaddr = sockaddr; addr->socklen = socklen; u_char *p; size_t len; p = ngx_pnalloc(new_pool, NGX_SOCKADDR_STRLEN); if (p == NULL) { ngx_log_error(NGX_LOG_ERR, ctx->resolver->log, 0, "upstream-dynamic-servers: Error initializing sockaddr"); ngx_destroy_pool(new_pool); goto end; } len = ngx_sock_ntop(sockaddr, socklen, p, NGX_SOCKADDR_STRLEN, 1); addr->name.len = len; addr->name.data = p; ngx_log_debug(NGX_LOG_DEBUG_CORE, ctx->resolver->log, 0, "upstream-dynamic-servers: '%V' was resolved to '%V'", &ctx->name, &addr->name); } // If the domain failed to resolve, mark this server as down. dynamic_server->server->down = ctx->state ? 1 : 0; dynamic_server->server->addrs = addrs; dynamic_server->server->naddrs = ctx->naddrs; ngx_http_upstream_init_pt init; init = dynamic_server->upstream_conf->peer.init_upstream ? dynamic_server->upstream_conf->peer.init_upstream : ngx_http_upstream_init_round_robin; if (init(&cf, dynamic_server->upstream_conf) != NGX_OK) { ngx_log_error(NGX_LOG_ERR, ctx->resolver->log, 0, "upstream-dynamic-servers: Error re-initializing upstream after DNS changes"); } if (dynamic_server->previous_pool != NULL) { ngx_destroy_pool(dynamic_server->previous_pool); dynamic_server->previous_pool = NULL; } dynamic_server->previous_pool = dynamic_server->pool; dynamic_server->pool = new_pool; end: if (ctx->resolver->log->log_level & NGX_LOG_DEBUG_CORE) { hash = ngx_crc32_short(ctx->name.data, ctx->name.len); rn = ngx_resolver_lookup_name(ctx->resolver, &ctx->name, hash); uint32_t refresh_in; if (rn != NULL && rn->ttl) { refresh_in = (rn->valid - ngx_time()) * 1000; if (!refresh_in || refresh_in < 1000) { refresh_in = 1000; } } else { refresh_in = 1000; } ngx_log_debug(NGX_LOG_DEBUG_CORE, ctx->resolver->log, 0, "upstream-dynamic-servers: Refreshing DNS of '%V' in %ims", &ctx->name, refresh_in); } ngx_resolve_name_done(ctx); if (ngx_exiting) { ngx_log_debug(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0, "upstream-dynamic-servers: worker is about to exit, do not set the timer again"); return; } ngx_add_timer(&dynamic_server->timer, 1000); }
static void ngx_ssl_ocsp_resolve_handler(ngx_resolver_ctx_t *resolve) { ngx_ssl_ocsp_ctx_t *ctx = resolve->data; u_char *p; size_t len; in_port_t port; ngx_uint_t i; struct sockaddr_in *sin; ngx_log_debug0(NGX_LOG_ALERT, ctx->log, 0, "ssl ocsp resolve handler"); if (resolve->state) { ngx_log_error(NGX_LOG_ERR, ctx->log, 0, "%V could not be resolved (%i: %s)", &resolve->name, resolve->state, ngx_resolver_strerror(resolve->state)); goto failed; } #if (NGX_DEBUG) { in_addr_t addr; for (i = 0; i < resolve->naddrs; i++) { addr = ntohl(resolve->addrs[i]); ngx_log_debug4(NGX_LOG_DEBUG_EVENT, ctx->log, 0, "name was resolved to %ud.%ud.%ud.%ud", (addr >> 24) & 0xff, (addr >> 16) & 0xff, (addr >> 8) & 0xff, addr & 0xff); } } #endif ctx->naddrs = resolve->naddrs; ctx->addrs = ngx_pcalloc(ctx->pool, ctx->naddrs * sizeof(ngx_addr_t)); if (ctx->addrs == NULL) { goto failed; } port = htons(ctx->port); for (i = 0; i < resolve->naddrs; i++) { sin = ngx_pcalloc(ctx->pool, sizeof(struct sockaddr_in)); if (sin == NULL) { goto failed; } sin->sin_family = AF_INET; sin->sin_port = port; sin->sin_addr.s_addr = resolve->addrs[i]; ctx->addrs[i].sockaddr = (struct sockaddr *) sin; ctx->addrs[i].socklen = sizeof(struct sockaddr_in); len = NGX_INET_ADDRSTRLEN + sizeof(":65535") - 1; p = ngx_pnalloc(ctx->pool, len); if (p == NULL) { goto failed; } len = ngx_sock_ntop((struct sockaddr *) sin, p, len, 1); ctx->addrs[i].name.len = len; ctx->addrs[i].name.data = p; } ngx_resolve_name_done(resolve); ngx_ssl_ocsp_connect(ctx); return; failed: ngx_resolve_name_done(resolve); ngx_ssl_ocsp_error(ctx); }
static void ngx_mail_smtp_resolve_addr_handler(ngx_resolver_ctx_t *ctx) { ngx_connection_t *c; ngx_mail_session_t *s; ngx_mail_core_srv_conf_t *cscf; s = ctx->data; c = s->connection; if (ctx->state) { ngx_log_error(NGX_LOG_ERR, c->log, 0, "%V could not be resolved (%i: %s)", &c->addr_text, ctx->state, ngx_resolver_strerror(ctx->state)); if (ctx->state == NGX_RESOLVE_NXDOMAIN) { s->host = smtp_unavailable; } else { s->host = smtp_tempunavail; } ngx_resolve_addr_done(ctx); ngx_mail_smtp_greeting(s, s->connection); return; } c->log->action = "in resolving client hostname"; s->host.data = ngx_pstrdup(c->pool, &ctx->name); if (s->host.data == NULL) { ngx_resolve_addr_done(ctx); ngx_mail_close_connection(c); return; } s->host.len = ctx->name.len; ngx_resolve_addr_done(ctx); ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0, "address resolved: %V", &s->host); cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); ctx = ngx_resolve_start(cscf->resolver, NULL); if (ctx == NULL) { ngx_mail_close_connection(c); return; } ctx->name = s->host; ctx->type = NGX_RESOLVE_A; ctx->handler = ngx_mail_smtp_resolve_name_handler; ctx->data = s; ctx->timeout = cscf->resolver_timeout; if (ngx_resolve_name(ctx) != NGX_OK) { ngx_mail_close_connection(c); } }