60
* ngx_sock_ntop() and ngx_inet_ntop() may be implemented as
61
* "ngx_sprintf(text, "%ud.%ud.%ud.%ud", p[0], p[1], p[2], p[3])", however,
62
* they had been implemented long before the ngx_sprintf() had appeared
63
* and they are faster by 1.5-2.5 times, so it is worth to keep them.
65
* By the way, the implementation using ngx_sprintf() is faster by 2.5-3 times
66
* than using FreeBSD libc's snprintf().
72
ngx_sock_ntop(int family, struct sockaddr *sa, u_char *text, size_t len)
63
ngx_sock_ntop(struct sockaddr *sa, u_char *text, size_t len, ngx_uint_t port)
77
struct sockaddr_in *sin;
83
if (family != AF_INET) {
87
sin = (struct sockaddr_in *) sa;
88
p = (u_char *) &sin->sin_addr;
90
if (len > INET_ADDRSTRLEN) {
91
len = INET_ADDRSTRLEN;
94
n = ngx_sprint_uchar(text, p[0], len);
111
n += ngx_sprint_uchar(&text[n], p[i++], len - n);
66
struct sockaddr_in *sin;
69
struct sockaddr_in6 *sin6;
72
switch (sa->sa_family) {
76
sin = (struct sockaddr_in *) sa;
77
p = (u_char *) &sin->sin_addr;
80
p = ngx_snprintf(text, len, "%ud.%ud.%ud.%ud:%d",
81
p[0], p[1], p[2], p[3], ntohs(sin->sin_port));
83
p = ngx_snprintf(text, len, "%ud.%ud.%ud.%ud",
84
p[0], p[1], p[2], p[3]);
93
sin6 = (struct sockaddr_in6 *) sa;
101
n = ngx_inet6_ntop((u_char *) &sin6->sin6_addr, &text[n], len);
104
n = ngx_sprintf(&text[1 + n], "]:%d",
105
ntohs(sin6->sin6_port)) - text;
127
118
ngx_inet_ntop(int family, void *addr, u_char *text, size_t len)
137
if (family != AF_INET) {
143
if (len > INET_ADDRSTRLEN) {
144
len = INET_ADDRSTRLEN;
147
n = ngx_sprint_uchar(text, p[0], len);
164
n += ngx_sprint_uchar(&text[n], p[i++], len - n);
128
return ngx_snprintf(text, len, "%ud.%ud.%ud.%ud",
129
p[0], p[1], p[2], p[3])
135
return ngx_inet6_ntop(addr, text, len);
180
ngx_sprint_uchar(u_char *text, u_char c, size_t len)
148
ngx_inet6_ntop(u_char *p, u_char *text, size_t len)
152
ngx_uint_t i, zero, last;
154
if (len < NGX_INET6_ADDRSTRLEN) {
158
zero = (ngx_uint_t) -1;
159
last = (ngx_uint_t) -1;
194
*text++ = (u_char) (c1 + '0');
205
*text++ = (u_char) (c2 + '0');
215
*text = (u_char) (c2 + '0');
163
for (i = 0; i < 16; i += 2) {
165
if (p[i] || p[i + 1]) {
191
if ((max == 5 && p[10] == 0xff && p[11] == 0xff)
193
|| (max == 7 && p[14] != 0 && p[15] != 1))
201
for (i = 0; i < n; i += 2) {
209
dst = ngx_sprintf(dst, "%uxi", p[i] * 256 + p[i + 1]);
217
dst = ngx_sprintf(dst, "%ud.%ud.%ud.%ud", p[12], p[13], p[14], p[15]);
222
226
/* AF_INET only */
225
ngx_ptocidr(ngx_str_t *text, void *cidr)
229
ngx_ptocidr(ngx_str_t *text, ngx_cidr_t *cidr)
229
ngx_inet_cidr_t *in_cidr;
233
for (i = 0; i < text->len; i++) {
234
if (text->data[i] == '/') {
239
if (i == text->len) {
243
text->data[i] = '\0';
244
in_cidr->addr = inet_addr((char *) text->data);
246
if (in_cidr->addr == INADDR_NONE) {
250
m = ngx_atoi(&text->data[i + 1], text->len - (i + 1));
251
if (m == NGX_ERROR) {
231
u_char *addr, *mask, *last;
235
last = addr + text->len;
237
mask = ngx_strlchr(addr, last, '/');
239
cidr->u.in.addr = ngx_inet_addr(addr, (mask ? mask : last) - addr);
241
if (cidr->u.in.addr == INADDR_NONE) {
246
cidr->family = AF_INET;
247
cidr->u.in.mask = 0xffffffff;
253
shift = ngx_atoi(mask, last - mask);
254
if (shift == NGX_ERROR) {
258
cidr->family = AF_INET;
257
262
/* the x86 compilers use the shl instruction that shifts by modulo 32 */
263
in_cidr->mask = htonl((ngx_uint_t) (0 - (1 << (32 - m))));
265
if (in_cidr->addr == (in_cidr->addr & in_cidr->mask)) {
269
in_cidr->addr &= in_cidr->mask;
266
if (cidr->u.in.addr == 0) {
273
cidr->u.in.mask = htonl((ngx_uint_t) (0 - (1 << (32 - shift))));
275
if (cidr->u.in.addr == (cidr->u.in.addr & cidr->u.in.mask)) {
279
cidr->u.in.addr &= cidr->u.in.mask;
276
286
ngx_parse_url(ngx_pool_t *pool, ngx_url_t *u)
278
u_char *p, *host, *port_start;
279
size_t len, port_len;
292
if (ngx_strncasecmp(p, (u_char *) "unix:", 5) == 0) {
293
return ngx_parse_unix_domain_url(pool, u);
296
if ((p[0] == ':' || p[0] == '/') && !u->listen) {
297
u->err = "invalid host";
302
return ngx_parse_inet6_url(pool, u);
305
return ngx_parse_inet_url(pool, u);
310
ngx_parse_unix_domain_url(ngx_pool_t *pool, ngx_url_t *u)
283
312
#if (NGX_HAVE_UNIX_DOMAIN)
313
u_char *path, *uri, *last;
284
315
struct sockaddr_un *saun;
287
317
len = u->url.len;
290
if (ngx_strncasecmp(p, (u_char *) "unix:", 5) == 0) {
292
#if (NGX_HAVE_UNIX_DOMAIN)
301
for (i = 0; i < len; i++) {
306
u->uri.len -= len + 1;
307
u->uri.data += len + 1;
326
uri = ngx_strlchr(path, last, ':');
331
u->uri.len = last - uri;
337
u->err = "no path in the unix domain socket";
344
if (len > sizeof(saun->sun_path)) {
345
u->err = "too long path in the unix domain socket";
349
u->socklen = sizeof(struct sockaddr_un);
350
saun = (struct sockaddr_un *) &u->sockaddr;
351
saun->sun_family = AF_UNIX;
352
(void) ngx_cpystrn((u_char *) saun->sun_path, path, len);
354
u->addrs = ngx_pcalloc(pool, sizeof(ngx_peer_addr_t));
355
if (u->addrs == NULL) {
359
saun = ngx_pcalloc(pool, sizeof(struct sockaddr_un));
367
saun->sun_family = AF_UNIX;
368
(void) ngx_cpystrn((u_char *) saun->sun_path, path, len);
370
u->addrs[0].sockaddr = (struct sockaddr *) saun;
371
u->addrs[0].socklen = sizeof(struct sockaddr_un);
372
u->addrs[0].name.len = len + 4;
373
u->addrs[0].name.data = u->url.data;
379
u->err = "the unix domain sockets are not supported on this platform";
388
ngx_parse_inet_url(ngx_pool_t *pool, ngx_url_t *u)
390
u_char *p, *host, *port, *last, *uri, *args;
394
struct sockaddr_in *sin;
396
u->socklen = sizeof(struct sockaddr_in);
397
sin = (struct sockaddr_in *) &u->sockaddr;
398
sin->sin_family = AF_INET;
404
last = host + u->url.len;
406
port = ngx_strlchr(host, last, ':');
408
uri = ngx_strlchr(host, last, '/');
410
args = ngx_strlchr(host, last, '?');
416
} else if (args < uri) {
422
if (u->listen || !u->uri_part) {
423
u->err = "invalid host";
427
u->uri.len = last - uri;
315
u->err = "no path in the unix domain socket";
319
if (len + 1 > sizeof(saun->sun_path)) {
320
u->err = "too long path in the unix domain socket";
324
u->addrs = ngx_pcalloc(pool, sizeof(ngx_peer_addr_t));
325
if (u->addrs == NULL) {
329
saun = ngx_pcalloc(pool, sizeof(struct sockaddr_un));
336
saun->sun_family = AF_UNIX;
337
(void) ngx_cpystrn((u_char *) saun->sun_path, p, len + 1);
339
u->addrs[0].sockaddr = (struct sockaddr *) saun;
340
u->addrs[0].socklen = sizeof(struct sockaddr_un);
341
u->addrs[0].name.len = len + 5;
342
u->addrs[0].name.data = u->url.data;
443
u->err = "invalid port";
447
n = ngx_atoi(port, len);
449
if (n < 1 || n > 65536) {
450
u->err = "invalid port";
454
u->port = (in_port_t) n;
455
sin->sin_port = htons((in_port_t) n);
457
u->port_text.len = len;
458
u->port_text.data = port;
467
/* test value as port only */
469
n = ngx_atoi(host, last - host);
471
if (n != NGX_ERROR) {
473
if (n < 1 || n > 65536) {
474
u->err = "invalid port";
478
u->port = (in_port_t) n;
479
sin->sin_port = htons((in_port_t) n);
481
u->port_text.len = last - host;
482
u->port_text.data = host;
501
if (len == 1 && *host == '*') {
352
u->err = "the unix domain sockets are not supported on this platform";
359
if ((p[0] == ':' || p[0] == '/') && !u->listen) {
360
u->err = "invalid host";
369
for (i = 0; i < len; i++) {
372
port_start = &p[i + 1];
376
port_len = len - (i + 1);
382
u->uri.len = len - i;
385
if (u->host.len == 0) {
389
if (port_start == NULL) {
394
port_len = &p[i] - port_start;
397
u->err = "invalid port";
408
port_len = &p[i] - port_start;
411
u->err = "invalid port";
416
port = ngx_atoi(port_start, port_len);
418
if (port == NGX_ERROR || port < 1 || port > 65536) {
419
u->err = "invalid port";
514
p = ngx_alloc(len, pool->log);
420
516
return NGX_ERROR;
423
u->port_text.len = port_len;
424
u->port_text.data = port_start;
519
(void) ngx_cpystrn(p, host, len);
521
sin->sin_addr.s_addr = inet_addr((const char *) p);
523
if (sin->sin_addr.s_addr == INADDR_NONE) {
524
h = gethostbyname((const char *) p);
526
if (h == NULL || h->h_addr_list[0] == NULL) {
528
u->err = "host not found";
532
sin->sin_addr.s_addr = *(in_addr_t *) (h->h_addr_list[0]);
535
if (sin->sin_addr.s_addr == INADDR_ANY) {
427
port = ngx_atoi(p, len);
429
if (port == NGX_ERROR) {
542
sin->sin_addr.s_addr = INADDR_ANY;
439
u->port = (in_port_t) port;
547
u->port = u->default_port;
548
sin->sin_port = htons(u->default_port);
446
if (u->default_port == 0) {
451
u->port = u->default_port;
454
if (u->host.len == 1 && u->host.data[0] == '*') {
462
host = ngx_alloc(u->host.len + 1, pool->log);
467
(void) ngx_cpystrn(host, u->host.data, u->host.len + 1);
469
u->addr.in_addr = inet_addr((const char *) host);
471
if (u->addr.in_addr == INADDR_NONE) {
472
h = gethostbyname((const char *) host);
474
if (h == NULL || h->h_addr_list[0] == NULL) {
476
u->err = "host not found";
480
u->addr.in_addr = *(in_addr_t *) (h->h_addr_list[0]);
486
u->addr.in_addr = INADDR_ANY;
492
if (u->host.len == 0) {
502
u->port = u->default_port;
510
555
if (ngx_inet_resolve_host(pool, u) != NGX_OK) {
564
ngx_parse_inet6_url(ngx_pool_t *pool, ngx_url_t *u)
568
u_char *p, *host, *port, *last, *uri;
571
struct sockaddr_in6 *sin6;
573
u->socklen = sizeof(struct sockaddr_in6);
574
sin6 = (struct sockaddr_in6 *) &u->sockaddr;
575
sin6->sin6_family = AF_INET6;
577
host = u->url.data + 1;
579
last = u->url.data + u->url.len;
581
p = ngx_strlchr(host, last, ']');
584
u->err = "invalid host";
592
uri = ngx_strlchr(port, last, '/');
595
if (u->listen || !u->uri_part) {
596
u->err = "invalid host";
600
u->uri.len = last - uri;
610
u->err = "invalid port";
614
n = ngx_atoi(port, len);
616
if (n < 1 || n > 65536) {
617
u->err = "invalid port";
621
u->port = (in_port_t) n;
622
sin6->sin6_port = htons((in_port_t) n);
624
u->port_text.len = len;
625
u->port_text.data = port;
642
p = ngx_alloc(len, pool->log);
647
(void) ngx_cpystrn(p, host, len);
651
rc = WSAStringToAddress((char *) p, AF_INET6, NULL,
652
(SOCKADDR *) sin6, &u->socklen);
656
sin6->sin6_port = htons(u->port);
661
rc = inet_pton(AF_INET6, (const char *) p, &sin6->sin6_addr);
668
u->err = "invalid IPv6 address";
672
if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
676
u->family = AF_INET6;
683
u->port = u->default_port;
684
sin6->sin6_port = htons(u->default_port);
691
u->err = "the INET6 sockets are not supported on this platform";
519
700
ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u)
521
702
u_char *p, *host;
523
705
in_addr_t in_addr;
525
707
struct hostent *h;