3 * Copyright (C) Igor Sysoev
7 #include <ngx_config.h>
11 static ngx_int_t ngx_parse_unix_domain_url(ngx_pool_t *pool, ngx_url_t *u);
12 static ngx_int_t ngx_parse_inet_url(ngx_pool_t *pool, ngx_url_t *u);
18 ngx_inet_addr(u_char *text, size_t len)
28 for (p = text; p < text + len; p++) {
32 if (c >= '0' && c <= '9') {
33 octet = octet * 10 + (c - '0');
37 if (c == '.' && octet < 256) {
38 addr = (addr << 8) + octet;
52 addr = (addr << 8) + octet;
63 ngx_sock_ntop(struct sockaddr *sa, u_char *text, size_t len)
66 struct sockaddr_in *sin;
68 if (sa->sa_family == AF_INET) {
70 sin = (struct sockaddr_in *) sa;
71 p = (u_char *) &sin->sin_addr;
73 return ngx_snprintf(text, len, "%ud.%ud.%ud.%ud",
74 p[0], p[1], p[2], p[3])
83 ngx_inet_ntop(int family, void *addr, u_char *text, size_t len)
87 if (family == AF_INET) {
91 return ngx_snprintf(text, len, "%ud.%ud.%ud.%ud",
92 p[0], p[1], p[2], p[3])
103 ngx_ptocidr(ngx_str_t *text, void *cidr)
105 u_char *addr, *mask, *last;
107 ngx_inet_cidr_t *in_cidr;
111 last = addr + text->len;
113 mask = ngx_strlchr(addr, last, '/');
115 in_cidr->addr = ngx_inet_addr(addr, (mask ? mask : last) - addr);
117 if (in_cidr->addr == INADDR_NONE) {
122 in_cidr->mask = 0xffffffff;
128 shift = ngx_atoi(mask, last - mask);
129 if (shift == NGX_ERROR) {
135 /* the x86 compilers use the shl instruction that shifts by modulo 32 */
139 if (in_cidr->addr == 0) {
146 in_cidr->mask = htonl((ngx_uint_t) (0 - (1 << (32 - shift))));
148 if (in_cidr->addr == (in_cidr->addr & in_cidr->mask)) {
152 in_cidr->addr &= in_cidr->mask;
159 ngx_parse_url(ngx_pool_t *pool, ngx_url_t *u)
165 if (ngx_strncasecmp(p, (u_char *) "unix:", 5) == 0) {
166 return ngx_parse_unix_domain_url(pool, u);
169 if ((p[0] == ':' || p[0] == '/') && !u->listen) {
170 u->err = "invalid host";
174 return ngx_parse_inet_url(pool, u);
179 ngx_parse_unix_domain_url(ngx_pool_t *pool, ngx_url_t *u)
181 #if (NGX_HAVE_UNIX_DOMAIN)
182 u_char *path, *uri, *last;
184 struct sockaddr_un *saun;
195 uri = ngx_strlchr(path, last, ':');
200 u->uri.len = last - uri;
206 u->err = "no path in the unix domain socket";
214 if (len > sizeof(saun->sun_path)) {
215 u->err = "too long path in the unix domain socket";
219 u->addrs = ngx_pcalloc(pool, sizeof(ngx_peer_addr_t));
220 if (u->addrs == NULL) {
224 saun = ngx_pcalloc(pool, sizeof(struct sockaddr_un));
231 saun->sun_family = AF_UNIX;
232 (void) ngx_cpystrn((u_char *) saun->sun_path, path, len);
234 u->addrs[0].sockaddr = (struct sockaddr *) saun;
235 u->addrs[0].socklen = sizeof(struct sockaddr_un);
236 u->addrs[0].name.len = len + 4;
237 u->addrs[0].name.data = u->url.data;
243 u->err = "the unix domain sockets are not supported on this platform";
252 ngx_parse_inet_url(ngx_pool_t *pool, ngx_url_t *u)
254 u_char *p, *host, *port, *last, *uri, *args;
263 last = host + u->url.len;
265 port = ngx_strlchr(host, last, ':');
267 uri = ngx_strlchr(host, last, '/');
269 args = ngx_strlchr(host, last, '?');
275 } else if (args < uri) {
281 if (u->listen || !u->uri_part) {
282 u->err = "invalid host";
286 u->uri.len = last - uri;
302 u->err = "invalid port";
306 n = ngx_atoi(port, len);
308 if (n < 1 || n > 65536) {
309 u->err = "invalid port";
313 u->port = (in_port_t) n;
315 u->port_text.len = len;
316 u->port_text.data = port;
325 /* test value as port only */
327 n = ngx_atoi(host, last - host);
329 if (n != NGX_ERROR) {
331 if (n < 1 || n > 65536) {
332 u->err = "invalid port";
336 u->port = (in_port_t) n;
338 u->port_text.len = last - host;
339 u->port_text.data = host;
356 if (len == 1 && *host == '*') {
369 p = ngx_alloc(len, pool->log);
374 (void) ngx_cpystrn(p, host, len);
376 u->addr.in_addr = inet_addr((const char *) p);
378 if (u->addr.in_addr == INADDR_NONE) {
379 h = gethostbyname((const char *) p);
381 if (h == NULL || h->h_addr_list[0] == NULL) {
383 u->err = "host not found";
387 u->addr.in_addr = *(in_addr_t *) (h->h_addr_list[0]);
393 u->addr.in_addr = INADDR_ANY;
397 u->port = u->default_port;
404 if (ngx_inet_resolve_host(pool, u) != NGX_OK) {
413 ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u)
420 struct sockaddr_in *sin;
422 host = ngx_alloc(u->host.len + 1, pool->log);
427 (void) ngx_cpystrn(host, u->host.data, u->host.len + 1);
431 in_addr = inet_addr((char *) host);
433 if (in_addr == INADDR_NONE) {
434 h = gethostbyname((char *) host);
438 if (h == NULL || h->h_addr_list[0] == NULL) {
439 u->err = "host not found";
443 if (u->one_addr == 0) {
444 for (i = 0; h->h_addr_list[i] != NULL; i++) { /* void */ }
450 /* MP: ngx_shared_palloc() */
452 u->addrs = ngx_pcalloc(pool, i * sizeof(ngx_peer_addr_t));
453 if (u->addrs == NULL) {
459 for (i = 0; h->h_addr_list[i] != NULL; i++) {
461 sin = ngx_pcalloc(pool, sizeof(struct sockaddr_in));
466 sin->sin_family = AF_INET;
467 sin->sin_port = htons(u->port);
468 sin->sin_addr.s_addr = *(in_addr_t *) (h->h_addr_list[i]);
470 u->addrs[i].sockaddr = (struct sockaddr *) sin;
471 u->addrs[i].socklen = sizeof(struct sockaddr_in);
473 len = NGX_INET_ADDRSTRLEN + sizeof(":65536") - 1;
475 p = ngx_pnalloc(pool, len);
480 len = ngx_sock_ntop((struct sockaddr *) sin, p, len);
482 u->addrs[i].name.len = ngx_sprintf(&p[len], ":%d", u->port) - p;
483 u->addrs[i].name.data = p;
490 /* MP: ngx_shared_palloc() */
492 u->addrs = ngx_pcalloc(pool, sizeof(ngx_peer_addr_t));
493 if (u->addrs == NULL) {
497 sin = ngx_pcalloc(pool, sizeof(struct sockaddr_in));
504 sin->sin_family = AF_INET;
505 sin->sin_port = htons(u->port);
506 sin->sin_addr.s_addr = in_addr;
508 u->addrs[0].sockaddr = (struct sockaddr *) sin;
509 u->addrs[0].socklen = sizeof(struct sockaddr_in);
511 p = ngx_pnalloc(pool, u->host.len + sizeof(":65536") - 1);
516 u->addrs[0].name.len = ngx_sprintf(p, "%V:%d", &u->host, u->port) - p;
517 u->addrs[0].name.data = p;