diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/nginx.h | 2 | ||||
-rw-r--r-- | src/core/ngx_conf_file.h | 2 | ||||
-rw-r--r-- | src/core/ngx_core.h | 6 | ||||
-rw-r--r-- | src/core/ngx_cpuinfo.c | 12 | ||||
-rw-r--r-- | src/core/ngx_inet.c | 336 | ||||
-rw-r--r-- | src/core/ngx_inet.h | 68 | ||||
-rw-r--r-- | src/core/ngx_parse.c | 8 |
7 files changed, 417 insertions, 17 deletions
diff --git a/src/core/nginx.h b/src/core/nginx.h index ece57f55c..72aaa34bc 100644 --- a/src/core/nginx.h +++ b/src/core/nginx.h @@ -8,7 +8,7 @@ #define _NGINX_H_INCLUDED_ -#define NGINX_VER "nginx/0.3.46" +#define NGINX_VER "nginx/0.3.47" #define NGINX_VAR "NGINX" #define NGX_OLDPID_EXT ".oldbin" diff --git a/src/core/ngx_conf_file.h b/src/core/ngx_conf_file.h index 8f84e36a7..17c24c725 100644 --- a/src/core/ngx_conf_file.h +++ b/src/core/ngx_conf_file.h @@ -61,7 +61,7 @@ #define NGX_CONF_OK NULL -#define NGX_CONF_ERROR (char *) -1 +#define NGX_CONF_ERROR (void *) -1 #define NGX_CONF_BLOCK_START 1 #define NGX_CONF_BLOCK_DONE 2 diff --git a/src/core/ngx_core.h b/src/core/ngx_core.h index 1779513e1..cd066af35 100644 --- a/src/core/ngx_core.h +++ b/src/core/ngx_core.h @@ -63,6 +63,9 @@ typedef void (*ngx_connection_handler_pt)(ngx_connection_t *c); #include <ngx_radix_tree.h> #include <ngx_times.h> #include <ngx_shmtx.h> +#if (NGX_OPENSSL) +#include <ngx_event_openssl.h> +#endif #include <ngx_inet.h> #if (NGX_HAVE_UNIX_DOMAIN) #include <ngx_unix_domain.h> @@ -71,9 +74,6 @@ typedef void (*ngx_connection_handler_pt)(ngx_connection_t *c); #include <ngx_process_cycle.h> #include <ngx_conf_file.h> #include <ngx_os.h> -#if (NGX_OPENSSL) -#include <ngx_event_openssl.h> -#endif #include <ngx_connection.h> diff --git a/src/core/ngx_cpuinfo.c b/src/core/ngx_cpuinfo.c index f905cbc13..2ed26b8d4 100644 --- a/src/core/ngx_cpuinfo.c +++ b/src/core/ngx_cpuinfo.c @@ -31,16 +31,14 @@ ngx_cpuid(uint32_t i, uint32_t *buf) " mov %%ebx, %%esi; " " cpuid; " - " mov %%eax, %0; " - " mov %%ebx, %1; " - " mov %%edx, %2; " - " mov %%ecx, %3; " + " mov %%eax, (%1); " + " mov %%ebx, 4(%1); " + " mov %%edx, 8(%1); " + " mov %%ecx, 12(%1); " " mov %%esi, %%ebx; " - : "=m" (buf[0]), "=m" (buf[1]), "=m" (buf[2]), "=m" (buf[3]) - : "a" (i) - : "ecx", "edx", "esi" ); + : : "a" (i), "D" (buf) : "ecx", "edx", "esi", "memory" ); } diff --git a/src/core/ngx_inet.c b/src/core/ngx_inet.c index a42df699b..f2b0cf78b 100644 --- a/src/core/ngx_inet.c +++ b/src/core/ngx_inet.c @@ -220,6 +220,339 @@ ngx_ptocidr(ngx_str_t *text, void *cidr) } +ngx_int_t +ngx_parse_url(ngx_conf_t *cf, ngx_url_t *u) +{ + u_char *p; + size_t len; + ngx_int_t port; + ngx_uint_t i; +#if (NGX_HAVE_UNIX_DOMAIN) + struct sockaddr_un *saun; +#endif + + len = u->url.len; + p = u->url.data; + + if (ngx_strncasecmp(p, "unix:", 5) == 0) { + +#if (NGX_HAVE_UNIX_DOMAIN) + + u->type = NGX_PARSE_URL_UNIX; + + p += 5; + len -= 5; + + if (u->uri_part) { + for (i = 0; i < len; i++) { + + if (p[i] == ':') { + len = i; + + u->uri.len -= len + 1; + u->uri.data += len + 1; + + break; + } + } + } + + if (len == 0) { + u->err = "no path in the unix domain socket"; + return NGX_ERROR; + } + + if (len + 1 > sizeof(saun->sun_path)) { + u->err = "too long path in the unix domain socket"; + return NGX_ERROR; + } + + u->peers = ngx_pcalloc(cf->pool, sizeof(ngx_peers_t)); + if (u->peers == NULL) { + return NGX_ERROR; + } + + saun = ngx_pcalloc(cf->pool, sizeof(struct sockaddr_un)); + if (saun == NULL) { + return NGX_ERROR; + } + + u->peers->number = 1; + + saun->sun_family = AF_UNIX; + (void) ngx_cpystrn((u_char *) saun->sun_path, p, len + 1); + + u->peers->peer[0].sockaddr = (struct sockaddr *) saun; + u->peers->peer[0].socklen = sizeof(struct sockaddr_un); + u->peers->peer[0].name = u->url; + u->peers->peer[0].uri_separator = ":"; + + u->host_header.len = sizeof("localhost") - 1; + u->host_header.data = (u_char *) "localhost"; + + return NGX_OK; + +#else + u->err = "the unix domain sockets are not supported on this platform"; + + return NGX_ERROR; + +#endif + } + + if ((p[0] == ':' || p[0] == '/') && !u->listen) { + u->err = "invalid host"; + return NGX_ERROR; + } + + u->type = NGX_PARSE_URL_INET; + + u->host.data = p; + u->host_header.len = len; + u->host_header.data = p; + + for (i = 0; i < len; i++) { + + if (p[i] == ':') { + u->port.data = &p[i + 1]; + u->host.len = i; + + if (!u->uri_part) { + u->port.len = &p[len] - u->port.data; + break; + } + } + + if (p[i] == '/') { + u->uri.len = len - i; + u->uri.data = &p[i]; + u->host_header.len = i; + + if (u->host.len == 0) { + u->host.len = i; + } + + if (u->port.data == NULL) { + u->default_port = 1; + goto port; + } + + u->port.len = &p[i] - u->port.data; + + if (u->port.len == 0) { + u->err = "invalid port"; + return NGX_ERROR; + } + + break; + } + } + + if (u->port.data) { + + if (u->port.len == 0) { + u->port.len = &p[i] - u->port.data; + + if (u->port.len == 0) { + u->err = "invalid port"; + return NGX_ERROR; + } + } + + port = ngx_atoi(u->port.data, u->port.len); + + if (port == NGX_ERROR || port < 1 || port > 65536) { + u->err = "invalid port"; + return NGX_ERROR; + } + + } else { + port = ngx_atoi(p, len); + + if (port == NGX_ERROR) { + u->default_port = 1; + u->host.len = len; + + goto port; + } + + u->port.len = len; + u->port.data = p; + u->wildcard = 1; + } + + u->portn = (in_port_t) port; + +port: + + if (u->listen) { + return NGX_OK; + } + + if (u->default_port) { + + if (u->upstream) { + return NGX_OK; + } + + if (u->default_portn == 0) { + u->err = "no port"; + return NGX_ERROR; + } + + u->portn = u->default_portn; + + u->port.data = ngx_palloc(cf->pool, sizeof("65536") - 1); + if (u->port.data == NULL) { + return NGX_ERROR; + } + + u->port.len = ngx_sprintf(u->port.data, "%d", u->portn) - u->port.data; + + } else if (u->portn) { + if (u->portn == u->default_portn) { + u->default_port = 1; + } + + } else { + u->err = "no port"; + return NGX_ERROR; + } + + if (u->host.len == 0) { + u->err = "no host"; + return NGX_ERROR; + } + + u->peers = ngx_inet_resolve_peer(cf, &u->host, u->portn); + + if (u->peers == NULL) { + return NGX_ERROR; + } + + if (u->peers == NGX_CONF_ERROR) { + u->err = "host not found"; + return NGX_ERROR; + } + + return NGX_OK; +} + + +ngx_peers_t * +ngx_inet_resolve_peer(ngx_conf_t *cf, ngx_str_t *name, in_port_t port) +{ + u_char *host; + size_t len; + in_addr_t in_addr; + ngx_uint_t i; + ngx_peers_t *peers; + struct hostent *h; + struct sockaddr_in *sin; + + host = ngx_palloc(cf->temp_pool, name->len + 1); + if (host == NULL) { + return NULL; + } + + (void) ngx_cpystrn(host, name->data, name->len + 1); + + /* AF_INET only */ + + in_addr = inet_addr((char *) host); + + if (in_addr == INADDR_NONE) { + h = gethostbyname((char *) host); + + if (h == NULL || h->h_addr_list[0] == NULL) { + return NGX_CONF_ERROR; + } + + for (i = 0; h->h_addr_list[i] != NULL; i++) { /* void */ } + + /* MP: ngx_shared_palloc() */ + + peers = ngx_pcalloc(cf->pool, + sizeof(ngx_peers_t) + sizeof(ngx_peer_t) * (i - 1)); + if (peers == NULL) { + return NULL; + } + + peers->number = i; + peers->weight = 1; + + for (i = 0; h->h_addr_list[i] != NULL; i++) { + + sin = ngx_pcalloc(cf->pool, sizeof(struct sockaddr_in)); + if (sin == NULL) { + return NULL; + } + + sin->sin_family = AF_INET; + sin->sin_port = htons(port); + sin->sin_addr.s_addr = *(in_addr_t *) (h->h_addr_list[i]); + + peers->peer[i].sockaddr = (struct sockaddr *) sin; + peers->peer[i].socklen = sizeof(struct sockaddr_in); + + len = INET_ADDRSTRLEN - 1 + 1 + sizeof(":65536") - 1; + + peers->peer[i].name.data = ngx_palloc(cf->pool, len); + if (peers->peer[i].name.data == NULL) { + return NULL; + } + + len = ngx_sock_ntop(AF_INET, (struct sockaddr *) sin, + peers->peer[i].name.data, len); + + peers->peer[i].name.len = + ngx_sprintf(&peers->peer[i].name.data[len], + ":%d", port) + - peers->peer[i].name.data; + + peers->peer[i].uri_separator = ""; + } + + } else { + + /* MP: ngx_shared_palloc() */ + + peers = ngx_pcalloc(cf->pool, sizeof(ngx_peers_t)); + if (peers == NULL) { + return NULL; + } + + sin = ngx_pcalloc(cf->pool, sizeof(struct sockaddr_in)); + if (sin == NULL) { + return NULL; + } + + peers->number = 1; + + sin->sin_family = AF_INET; + sin->sin_port = htons(port); + sin->sin_addr.s_addr = in_addr; + + peers->peer[0].sockaddr = (struct sockaddr *) sin; + peers->peer[0].socklen = sizeof(struct sockaddr_in); + + peers->peer[0].name.data = ngx_palloc(cf->pool, + name->len + sizeof(":65536") - 1); + if (peers->peer[0].name.data == NULL) { + return NULL; + } + + peers->peer[0].name.len = ngx_sprintf(peers->peer[0].name.data, "%V:%d", + name, port) + - peers->peer[0].name.data; + + peers->peer[0].uri_separator = ""; + } + + return peers; +} + + ngx_peers_t * ngx_inet_upstream_parse(ngx_conf_t *cf, ngx_inet_upstream_t *u) { @@ -241,6 +574,7 @@ ngx_inet_upstream_parse(ngx_conf_t *cf, ngx_inet_upstream_t *u) } if (u->default_port) { + if (u->default_port_value == 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "no port in upstream \"%V\"", &u->name); @@ -277,7 +611,7 @@ ngx_inet_upstream_parse(ngx_conf_t *cf, ngx_inet_upstream_t *u) u->port = htons(u->port); - host = ngx_palloc(cf->pool, u->host.len + 1); + host = ngx_palloc(cf->temp_pool, u->host.len + 1); if (host == NULL) { return NULL; } diff --git a/src/core/ngx_inet.h b/src/core/ngx_inet.h index a01fc8a70..25f923230 100644 --- a/src/core/ngx_inet.h +++ b/src/core/ngx_inet.h @@ -12,6 +12,10 @@ #include <ngx_core.h> +#define NGX_PARSE_URL_INET 1 +#define NGX_PARSE_URL_UNIX 2 + + typedef struct { in_addr_t addr; in_addr_t mask; @@ -19,6 +23,66 @@ typedef struct { typedef struct { + struct sockaddr *sockaddr; + socklen_t socklen; + + ngx_str_t name; + char *uri_separator; + + ngx_uint_t weight; + + ngx_uint_t fails; + time_t accessed; + + ngx_uint_t max_fails; + time_t fail_timeout; + +#if (NGX_SSL) + ngx_ssl_session_t *ssl_session; +#endif +} ngx_peer_t; + + +struct ngx_peers_s { + ngx_uint_t current; + ngx_uint_t weight; + + ngx_uint_t number; + ngx_uint_t last_cached; + + /* ngx_mutex_t *mutex; */ + ngx_connection_t **cached; + + ngx_peer_t peer[1]; +}; + + +typedef struct { + ngx_int_t type; + + ngx_peers_t *peers; + + ngx_str_t url; + ngx_str_t host; + ngx_str_t host_header; + ngx_str_t port; + ngx_str_t uri; + + in_port_t portn; + in_port_t default_portn; + + unsigned listen:1; + unsigned uri_part:1; + unsigned upstream:1; + + unsigned default_port:1; + unsigned wildcard:1; + + char *err; +} ngx_url_t; + + +typedef struct { ngx_str_t name; /* "schema:host:port/uri" */ ngx_str_t url; /* "host:port/uri" */ ngx_str_t host; @@ -35,6 +99,7 @@ typedef struct { unsigned uri_part:1; unsigned port_only:1; + unsigned virtual:1; } ngx_inet_upstream_t; @@ -45,7 +110,10 @@ size_t ngx_inet_ntop(int family, void *addr, u_char *text, size_t len); ngx_int_t ngx_ptocidr(ngx_str_t *text, void *cidr); ngx_peers_t *ngx_inet_upstream_parse(ngx_conf_t *cf, ngx_inet_upstream_t *u); +ngx_peers_t *ngx_inet_resolve_peer(ngx_conf_t *cf, ngx_str_t *name, + in_port_t port); char *ngx_inet_parse_host_port(ngx_inet_upstream_t *u); +ngx_int_t ngx_parse_url(ngx_conf_t *cf, ngx_url_t *u); #endif /* _NGX_INET_H_INCLUDED_ */ diff --git a/src/core/ngx_parse.c b/src/core/ngx_parse.c index f8e5f6c2e..28e5d96c1 100644 --- a/src/core/ngx_parse.c +++ b/src/core/ngx_parse.c @@ -50,10 +50,10 @@ ngx_parse_size(ngx_str_t *line) ngx_int_t ngx_parse_time(ngx_str_t *line, ngx_int_t sec) { - size_t len; - u_char *start, last; - ngx_int_t value, total, scale; - ngx_uint_t max, i; + size_t len; + u_char *start, last; + ngx_int_t value, total, scale; + ngx_uint_t max, i; enum { st_start = 0, st_year, |