Changed resolver API to use ngx_addr_t.
diff --git a/src/core/ngx_resolver.c b/src/core/ngx_resolver.c
index 293a869..5233105 100644
--- a/src/core/ngx_resolver.c
+++ b/src/core/ngx_resolver.c
@@ -88,8 +88,8 @@
static void ngx_resolver_free(ngx_resolver_t *r, void *p);
static void ngx_resolver_free_locked(ngx_resolver_t *r, void *p);
static void *ngx_resolver_dup(ngx_resolver_t *r, void *src, size_t size);
-static in_addr_t *ngx_resolver_rotate(ngx_resolver_t *r, in_addr_t *src,
- ngx_uint_t n);
+static ngx_addr_t *ngx_resolver_export(ngx_resolver_t *r, in_addr_t *src,
+ ngx_uint_t n, ngx_uint_t rotate);
static u_char *ngx_resolver_log_error(ngx_log_t *log, u_char *buf, size_t len);
@@ -281,7 +281,11 @@
temp->state = NGX_OK;
temp->naddrs = 1;
temp->addrs = &temp->addr;
- temp->addr = addr;
+ temp->addr.sockaddr = (struct sockaddr *) &temp->sin;
+ temp->addr.socklen = sizeof(struct sockaddr_in);
+ ngx_memzero(&temp->sin, sizeof(struct sockaddr_in));
+ temp->sin.sin_family = AF_INET;
+ temp->sin.sin_addr.s_addr = addr;
temp->quick = 1;
return temp;
@@ -417,9 +421,9 @@
ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx)
{
uint32_t hash;
- in_addr_t addr, *addrs;
ngx_int_t rc;
ngx_uint_t naddrs;
+ ngx_addr_t *addrs;
ngx_resolver_ctx_t *next;
ngx_resolver_node_t *rn;
@@ -445,16 +449,14 @@
/* NGX_RESOLVE_A answer */
- if (naddrs != 1) {
- addr = 0;
- addrs = ngx_resolver_rotate(r, rn->u.addrs, naddrs);
+ if (naddrs == 1) {
+ addrs = NULL;
+
+ } else {
+ addrs = ngx_resolver_export(r, rn->u.addrs, naddrs, 1);
if (addrs == NULL) {
return NGX_ERROR;
}
-
- } else {
- addr = rn->u.addr;
- addrs = NULL;
}
ctx->next = rn->waiting;
@@ -465,8 +467,19 @@
do {
ctx->state = NGX_OK;
ctx->naddrs = naddrs;
- ctx->addrs = (naddrs == 1) ? &ctx->addr : addrs;
- ctx->addr = addr;
+
+ if (addrs == NULL) {
+ ctx->addrs = &ctx->addr;
+ ctx->addr.sockaddr = (struct sockaddr *) &ctx->sin;
+ ctx->addr.socklen = sizeof(struct sockaddr_in);
+ ngx_memzero(&ctx->sin, sizeof(struct sockaddr_in));
+ ctx->sin.sin_family = AF_INET;
+ ctx->sin.sin_addr.s_addr = rn->u.addr;
+
+ } else {
+ ctx->addrs = addrs;
+ }
+
next = ctx->next;
ctx->handler(ctx);
@@ -474,7 +487,8 @@
ctx = next;
} while (ctx);
- if (addrs) {
+ if (addrs != NULL) {
+ ngx_resolver_free(r, addrs->sockaddr);
ngx_resolver_free(r, addrs);
}
@@ -626,20 +640,29 @@
}
+/* AF_INET only */
+
ngx_int_t
ngx_resolve_addr(ngx_resolver_ctx_t *ctx)
{
u_char *name;
+ in_addr_t addr;
ngx_resolver_t *r;
+ struct sockaddr_in *sin;
ngx_resolver_node_t *rn;
r = ctx->resolver;
- ctx->addr = ntohl(ctx->addr);
+ if (ctx->addr.sockaddr->sa_family != AF_INET) {
+ return NGX_ERROR;
+ }
+
+ sin = (struct sockaddr_in *) ctx->addr.sockaddr;
+ addr = ntohl(sin->sin_addr.s_addr);
/* lock addr mutex */
- rn = ngx_resolver_lookup_addr(r, ctx->addr);
+ rn = ngx_resolver_lookup_addr(r, addr);
if (rn) {
@@ -694,7 +717,7 @@
goto failed;
}
- rn->node.key = ctx->addr;
+ rn->node.key = addr;
rn->query = NULL;
ngx_rbtree_insert(&r->addr_rbtree, &rn->node);
@@ -765,14 +788,24 @@
}
+/* AF_INET only */
+
void
ngx_resolve_addr_done(ngx_resolver_ctx_t *ctx)
{
in_addr_t addr;
ngx_resolver_t *r;
ngx_resolver_ctx_t *w, **p;
+ struct sockaddr_in *sin;
ngx_resolver_node_t *rn;
+ if (ctx->addr.sockaddr->sa_family != AF_INET) {
+ return;
+ }
+
+ sin = (struct sockaddr_in *) ctx->addr.sockaddr;
+ addr = ntohl(sin->sin_addr.s_addr);
+
r = ctx->resolver;
ngx_log_debug1(NGX_LOG_DEBUG_CORE, r->log, 0,
@@ -786,7 +819,7 @@
if (ctx->state == NGX_AGAIN || ctx->state == NGX_RESOLVE_TIMEDOUT) {
- rn = ngx_resolver_lookup_addr(r, ctx->addr);
+ rn = ngx_resolver_lookup_addr(r, addr);
if (rn) {
p = &rn->waiting;
@@ -804,8 +837,6 @@
}
}
- addr = ntohl(ctx->addr);
-
ngx_log_error(NGX_LOG_ALERT, r->log, 0,
"could not cancel %ud.%ud.%ud.%ud resolving",
(addr >> 24) & 0xff, (addr >> 16) & 0xff,
@@ -1177,8 +1208,9 @@
size_t len;
int32_t ttl;
uint32_t hash;
- in_addr_t addr, *addrs;
+ in_addr_t *addr;
ngx_str_t name;
+ ngx_addr_t *addrs;
ngx_uint_t type, class, qident, naddrs, a, i, n, start;
ngx_resolver_an_t *an;
ngx_resolver_ctx_t *ctx, *next;
@@ -1247,8 +1279,6 @@
i = ans;
naddrs = 0;
- addr = 0;
- addrs = NULL;
cname = NULL;
ttl = 0;
@@ -1319,9 +1349,6 @@
goto short_response;
}
- addr = htonl((buf[i] << 24) + (buf[i + 1] << 16)
- + (buf[i + 2] << 8) + (buf[i + 3]));
-
naddrs++;
break;
@@ -1352,66 +1379,69 @@
if (naddrs) {
if (naddrs == 1) {
- rn->u.addr = addr;
+ addr = &rn->u.addr;
+ rn->naddrs = 1;
} else {
-
- addrs = ngx_resolver_alloc(r, naddrs * sizeof(in_addr_t));
- if (addrs == NULL) {
+ addr = ngx_resolver_alloc(r, naddrs * sizeof(in_addr_t));
+ if (addr == NULL) {
goto failed;
}
- n = 0;
- i = ans;
+ rn->u.addrs = addr;
+ rn->naddrs = (u_short) naddrs;
+ }
- for (a = 0; a < nan; a++) {
+ n = 0;
+ i = ans;
- for ( ;; ) {
+ for (a = 0; a < nan; a++) {
- if (buf[i] & 0xc0) {
- i += 2;
- break;
- }
+ for ( ;; ) {
- if (buf[i] == 0) {
- i++;
- break;
- }
-
- i += 1 + buf[i];
+ if (buf[i] & 0xc0) {
+ i += 2;
+ break;
}
- an = (ngx_resolver_an_t *) &buf[i];
-
- type = (an->type_hi << 8) + an->type_lo;
- len = (an->len_hi << 8) + an->len_lo;
-
- i += sizeof(ngx_resolver_an_t);
-
- if (type == NGX_RESOLVE_A) {
-
- addrs[n++] = htonl((buf[i] << 24) + (buf[i + 1] << 16)
- + (buf[i + 2] << 8) + (buf[i + 3]));
-
- if (n == naddrs) {
- break;
- }
+ if (buf[i] == 0) {
+ i++;
+ break;
}
- i += len;
+ i += 1 + buf[i];
}
- rn->u.addrs = addrs;
+ an = (ngx_resolver_an_t *) &buf[i];
- addrs = ngx_resolver_dup(r, rn->u.addrs,
- naddrs * sizeof(in_addr_t));
+ type = (an->type_hi << 8) + an->type_lo;
+ len = (an->len_hi << 8) + an->len_lo;
+
+ i += sizeof(ngx_resolver_an_t);
+
+ if (type == NGX_RESOLVE_A) {
+
+ addr[n] = htonl((buf[i] << 24) + (buf[i + 1] << 16)
+ + (buf[i + 2] << 8) + (buf[i + 3]));
+
+ if (++n == naddrs) {
+ break;
+ }
+ }
+
+ i += len;
+ }
+
+ if (naddrs == 1) {
+ addrs = NULL;
+
+ } else {
+ addrs = ngx_resolver_export(r, rn->u.addrs, naddrs, 0);
if (addrs == NULL) {
goto failed;
}
}
- rn->naddrs = (u_short) naddrs;
-
ngx_queue_remove(&rn->queue);
rn->valid = ngx_time() + (r->valid ? r->valid : ttl);
@@ -1428,14 +1458,26 @@
ctx = next;
ctx->state = NGX_OK;
ctx->naddrs = naddrs;
- ctx->addrs = (naddrs == 1) ? &ctx->addr : addrs;
- ctx->addr = addr;
+
+ if (addrs == NULL) {
+ ctx->addrs = &ctx->addr;
+ ctx->addr.sockaddr = (struct sockaddr *) &ctx->sin;
+ ctx->addr.socklen = sizeof(struct sockaddr_in);
+ ngx_memzero(&ctx->sin, sizeof(struct sockaddr_in));
+ ctx->sin.sin_family = AF_INET;
+ ctx->sin.sin_addr.s_addr = rn->u.addr;
+
+ } else {
+ ctx->addrs = addrs;
+ }
+
next = ctx->next;
ctx->handler(ctx);
}
- if (naddrs > 1) {
+ if (addrs != NULL) {
+ ngx_resolver_free(r, addrs->sockaddr);
ngx_resolver_free(r, addrs);
}
@@ -1918,9 +1960,15 @@
{
u_char *p, *d;
size_t len;
+ in_addr_t addr;
ngx_int_t n;
ngx_uint_t ident;
ngx_resolver_hdr_t *query;
+ struct sockaddr_in *sin;
+
+ if (ctx->addr.sockaddr->sa_family != AF_INET) {
+ return NGX_ERROR;
+ }
len = sizeof(ngx_resolver_hdr_t)
+ sizeof(".255.255.255.255.in-addr.arpa.") - 1
@@ -1950,8 +1998,11 @@
p += sizeof(ngx_resolver_hdr_t);
+ sin = (struct sockaddr_in *) ctx->addr.sockaddr;
+ addr = ntohl(sin->sin_addr.s_addr);
+
for (n = 0; n < 32; n += 8) {
- d = ngx_sprintf(&p[1], "%ud", (ctx->addr >> n) & 0xff);
+ d = ngx_sprintf(&p[1], "%ud", (addr >> n) & 0xff);
*p = (u_char) (d - &p[1]);
p = d;
}
@@ -2167,27 +2218,38 @@
}
-static in_addr_t *
-ngx_resolver_rotate(ngx_resolver_t *r, in_addr_t *src, ngx_uint_t n)
+static ngx_addr_t *
+ngx_resolver_export(ngx_resolver_t *r, in_addr_t *src, ngx_uint_t n,
+ ngx_uint_t rotate)
{
- void *dst, *p;
- ngx_uint_t j;
+ ngx_addr_t *dst;
+ ngx_uint_t i, j;
+ struct sockaddr_in *sin;
- dst = ngx_resolver_alloc(r, n * sizeof(in_addr_t));
-
+ dst = ngx_resolver_calloc(r, n * sizeof(ngx_addr_t));
if (dst == NULL) {
- return dst;
+ return NULL;
}
- j = ngx_random() % n;
+ sin = ngx_resolver_calloc(r, n * sizeof(struct sockaddr_in));
- if (j == 0) {
- ngx_memcpy(dst, src, n * sizeof(in_addr_t));
- return dst;
+ if (sin == NULL) {
+ ngx_resolver_free(r, dst);
+ return NULL;
}
- p = ngx_cpymem(dst, &src[j], (n - j) * sizeof(in_addr_t));
- ngx_memcpy(p, src, j * sizeof(in_addr_t));
+ j = rotate ? ngx_random() % n : 0;
+
+ for (i = 0; i < n; i++) {
+ dst[i].sockaddr = (struct sockaddr *) &sin[i];
+ dst[i].socklen = sizeof(struct sockaddr_in);
+ sin[i].sin_family = AF_INET;
+ sin[i].sin_addr.s_addr = src[j++];
+
+ if (j == n) {
+ j = 0;
+ }
+ }
return dst;
}
diff --git a/src/core/ngx_resolver.h b/src/core/ngx_resolver.h
index ae34ca5..c9942d8 100644
--- a/src/core/ngx_resolver.h
+++ b/src/core/ngx_resolver.h
@@ -121,8 +121,9 @@
ngx_str_t name;
ngx_uint_t naddrs;
- in_addr_t *addrs;
- in_addr_t addr;
+ ngx_addr_t *addrs;
+ ngx_addr_t addr;
+ struct sockaddr_in sin;
ngx_resolver_handler_pt handler;
void *data;
diff --git a/src/event/ngx_event_openssl_stapling.c b/src/event/ngx_event_openssl_stapling.c
index 7707614..976ffc1 100644
--- a/src/event/ngx_event_openssl_stapling.c
+++ b/src/event/ngx_event_openssl_stapling.c
@@ -816,11 +816,12 @@
{
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;
+ 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");
@@ -835,15 +836,19 @@
#if (NGX_DEBUG)
{
- in_addr_t addr;
+ u_char text[NGX_SOCKADDR_STRLEN];
+ ngx_str_t addr;
+
+ addr.data = text;
for (i = 0; i < resolve->naddrs; i++) {
- addr = ntohl(resolve->addrs[i]);
+ addr.len = ngx_sock_ntop(resolve->addrs[i].sockaddr,
+ resolve->addrs[i].socklen,
+ text, NGX_SOCKADDR_STRLEN, 0);
- 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);
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
+ "name was resolved to %V", &addr);
+
}
}
#endif
@@ -859,27 +864,34 @@
for (i = 0; i < resolve->naddrs; i++) {
- sin = ngx_pcalloc(ctx->pool, sizeof(struct sockaddr_in));
- if (sin == NULL) {
+ socklen = resolve->addrs[i].socklen;
+
+ sockaddr = ngx_palloc(ctx->pool, socklen);
+ if (sockaddr == NULL) {
goto failed;
}
- sin->sin_family = AF_INET;
- sin->sin_port = port;
- sin->sin_addr.s_addr = resolve->addrs[i];
+ ngx_memcpy(sockaddr, resolve->addrs[i].sockaddr, socklen);
- ctx->addrs[i].sockaddr = (struct sockaddr *) sin;
- ctx->addrs[i].socklen = sizeof(struct sockaddr_in);
+ 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;
+ }
- len = NGX_INET_ADDRSTRLEN + sizeof(":65535") - 1;
+ ctx->addrs[i].sockaddr = sockaddr;
+ ctx->addrs[i].socklen = socklen;
- p = ngx_pnalloc(ctx->pool, len);
+ p = ngx_pnalloc(ctx->pool, NGX_SOCKADDR_STRLEN);
if (p == NULL) {
goto failed;
}
- len = ngx_sock_ntop((struct sockaddr *) sin, sizeof(struct sockaddr_in),
- p, len, 1);
+ len = ngx_sock_ntop(sockaddr, socklen, p, NGX_SOCKADDR_STRLEN, 1);
ctx->addrs[i].name.len = len;
ctx->addrs[i].name.data = p;
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
index c148f38..522e17f 100644
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -918,16 +918,18 @@
#if (NGX_DEBUG)
{
- in_addr_t addr;
+ u_char text[NGX_SOCKADDR_STRLEN];
+ ngx_str_t addr;
ngx_uint_t i;
- for (i = 0; i < ctx->naddrs; i++) {
- addr = ntohl(ur->addrs[i]);
+ addr.data = text;
- ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "name was resolved to %ud.%ud.%ud.%ud",
- (addr >> 24) & 0xff, (addr >> 16) & 0xff,
- (addr >> 8) & 0xff, addr & 0xff);
+ 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);
}
}
#endif
diff --git a/src/http/ngx_http_upstream.h b/src/http/ngx_http_upstream.h
index 469988e..9f96c50 100644
--- a/src/http/ngx_http_upstream.h
+++ b/src/http/ngx_http_upstream.h
@@ -256,7 +256,7 @@
ngx_uint_t no_port; /* unsigned no_port:1 */
ngx_uint_t naddrs;
- in_addr_t *addrs;
+ ngx_addr_t *addrs;
struct sockaddr *sockaddr;
socklen_t socklen;
diff --git a/src/http/ngx_http_upstream_round_robin.c b/src/http/ngx_http_upstream_round_robin.c
index 2b4ce7a..85ff558 100644
--- a/src/http/ngx_http_upstream_round_robin.c
+++ b/src/http/ngx_http_upstream_round_robin.c
@@ -266,8 +266,9 @@
{
u_char *p;
size_t len;
+ socklen_t socklen;
ngx_uint_t i, n;
- struct sockaddr_in *sin;
+ struct sockaddr *sockaddr;
ngx_http_upstream_rr_peers_t *peers;
ngx_http_upstream_rr_peer_data_t *rrp;
@@ -306,27 +307,34 @@
for (i = 0; i < ur->naddrs; i++) {
- len = NGX_INET_ADDRSTRLEN + sizeof(":65536") - 1;
+ socklen = ur->addrs[i].socklen;
- p = ngx_pnalloc(r->pool, len);
+ sockaddr = ngx_palloc(r->pool, socklen);
+ if (sockaddr == NULL) {
+ return NGX_ERROR;
+ }
+
+ 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) {
return NGX_ERROR;
}
- len = ngx_inet_ntop(AF_INET, &ur->addrs[i], p, NGX_INET_ADDRSTRLEN);
- len = ngx_sprintf(&p[len], ":%d", ur->port) - p;
+ len = ngx_sock_ntop(sockaddr, socklen, p, NGX_SOCKADDR_STRLEN, 1);
- sin = ngx_pcalloc(r->pool, sizeof(struct sockaddr_in));
- if (sin == NULL) {
- return NGX_ERROR;
- }
-
- sin->sin_family = AF_INET;
- sin->sin_port = htons(ur->port);
- sin->sin_addr.s_addr = ur->addrs[i];
-
- peers->peer[i].sockaddr = (struct sockaddr *) sin;
- peers->peer[i].socklen = sizeof(struct sockaddr_in);
+ peers->peer[i].sockaddr = sockaddr;
+ peers->peer[i].socklen = socklen;
peers->peer[i].name.len = len;
peers->peer[i].name.data = p;
peers->peer[i].weight = 1;
diff --git a/src/mail/ngx_mail_smtp_handler.c b/src/mail/ngx_mail_smtp_handler.c
index 0238b62..d24ac5e 100644
--- a/src/mail/ngx_mail_smtp_handler.c
+++ b/src/mail/ngx_mail_smtp_handler.c
@@ -55,7 +55,6 @@
void
ngx_mail_smtp_init_session(ngx_mail_session_t *s, ngx_connection_t *c)
{
- struct sockaddr_in *sin;
ngx_resolver_ctx_t *ctx;
ngx_mail_core_srv_conf_t *cscf;
@@ -67,11 +66,13 @@
return;
}
- if (c->sockaddr->sa_family != AF_INET) {
+#if (NGX_HAVE_UNIX_DOMAIN)
+ if (c->sockaddr->sa_family == AF_UNIX) {
s->host = smtp_tempunavail;
ngx_mail_smtp_greeting(s, c);
return;
}
+#endif
c->log->action = "in resolving client address";
@@ -81,11 +82,8 @@
return;
}
- /* AF_INET only */
-
- sin = (struct sockaddr_in *) c->sockaddr;
-
- ctx->addr = sin->sin_addr.s_addr;
+ ctx->addr.sockaddr = c->sockaddr;
+ ctx->addr.socklen = c->socklen;
ctx->handler = ngx_mail_smtp_resolve_addr_handler;
ctx->data = s;
ctx->timeout = cscf->resolver_timeout;
@@ -181,10 +179,8 @@
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;
@@ -205,22 +201,29 @@
} else {
- /* AF_INET only */
+#if (NGX_DEBUG)
+ {
+ u_char text[NGX_SOCKADDR_STRLEN];
+ ngx_str_t addr;
- sin = (struct sockaddr_in *) c->sockaddr;
+ 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);
- addr = ctx->addrs[i];
+ ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0,
+ "name was resolved to %V", &addr);
+ }
+ }
+#endif
- 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) {
+ 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;
}
}