diff options
| author | Maxim Dounin <mdounin@mdounin.ru> | 2012-06-04 11:58:12 +0000 |
|---|---|---|
| committer | Maxim Dounin <mdounin@mdounin.ru> | 2012-06-04 11:58:12 +0000 |
| commit | 8acd40c4951ca822e2fb4672de9e4f23c6b6a97a (patch) | |
| tree | 4085dcdab5e39ebb470432ff09f15e2f3fa83902 /src/event | |
| parent | 21ad7d043686e548f2898b07d1f4083788a28890 (diff) | |
| download | nginx-8acd40c4951ca822e2fb4672de9e4f23c6b6a97a.tar.gz nginx-8acd40c4951ca822e2fb4672de9e4f23c6b6a97a.tar.bz2 | |
Merge of r4614, r4624-r4629, r4631: proxy recursive changes.
*) Added IPv6 and UNIX-domain socket support in "debug_connection"
directive.
*) New function ngx_http_get_forwarded_addr() to look up real client
address.
On input it takes an original address, string in the X-Forwarded-For format
and its length, list of trusted proxies, and a flag indicating to perform
the recursive search. On output it returns NGX_OK and the "deepest" valid
address in a chain, or NGX_DECLINED. It supports AF_INET and AF_INET6.
Additionally, original address and/or proxy may be specified as AF_UNIX.
*) Realip: chains of trusted proxies and IPv6 support.
The module now supports recursive search of client address through
the chain of trusted proxies, controlled by the "real_ip_recursive"
directive (closes #2). It also gets full IPv6 support (closes #44)
and canonical value of the $client_addr variable on address change.
Example:
real_ip_header X-Forwarded-For;
set_real_ip_from 127.0.0.0/8;
set_real_ip_from ::1;
set_real_ip_from unix:;
real_ip_recursive on;
*) Geo: chains of trusted proxies and partial IPv6 support.
The module now supports recursive search of client address through
the chain of trusted proxies, controlled by the "proxy_recursive"
directive in the "geo" block. It also gets partial IPv6 support:
now proxies may be specified with IPv6 addresses.
Example:
geo $test {
...
proxy 127.0.0.1;
proxy ::1;
proxy_recursive;
}
There's also a slight change in behavior. When original client
address (as specified by the "geo" directive) is one of the
trusted proxies, and the value of the X-Forwarded-For request
header cannot not be parsed as a valid address, an original client
address will be used for lookup. Previously, 255.255.255.255 was
used in this case.
*) Geoip: trusted proxies support and partial IPv6 support.
The module now supports recursive search of client address through the
chain of trusted proxies (closes #100), in the same scope as the geo
module. Proxies are listed by the "geoip_proxy" directive, recursive
search is enabled by the "geoip_proxy_recursive" directive. IPv6 is
partially supported: proxies may be specified with IPv6 addresses.
Example:
geoip_country .../GeoIP.dat;
geoip_proxy 127.0.0.1;
geoip_proxy ::1;
geoip_proxy 10.0.0.0/8;
geoip_proxy_recursive on;
Diffstat (limited to 'src/event')
| -rw-r--r-- | src/event/ngx_event.c | 39 | ||||
| -rw-r--r-- | src/event/ngx_event.h | 6 | ||||
| -rw-r--r-- | src/event/ngx_event_accept.c | 53 |
3 files changed, 64 insertions, 34 deletions
diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c index a0a9d743b..c584dd87d 100644 --- a/src/event/ngx_event.c +++ b/src/event/ngx_event.c @@ -1064,38 +1064,34 @@ ngx_event_debug_connection(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) ngx_int_t rc; ngx_str_t *value; - ngx_event_debug_t *dc; struct hostent *h; - ngx_cidr_t cidr; + ngx_cidr_t *cidr; value = cf->args->elts; - dc = ngx_array_push(&ecf->debug_connection); - if (dc == NULL) { + cidr = ngx_array_push(&ecf->debug_connection); + if (cidr == NULL) { return NGX_CONF_ERROR; } - rc = ngx_ptocidr(&value[1], &cidr); +#if (NGX_HAVE_UNIX_DOMAIN) + + if (ngx_strcmp(value[1].data, "unix:") == 0) { + cidr->family = AF_UNIX; + return NGX_CONF_OK; + } + +#endif + + rc = ngx_ptocidr(&value[1], cidr); if (rc == NGX_DONE) { ngx_conf_log_error(NGX_LOG_WARN, cf, 0, "low address bits of %V are meaningless", &value[1]); - rc = NGX_OK; + return NGX_CONF_OK; } if (rc == NGX_OK) { - - /* AF_INET only */ - - if (cidr.family != AF_INET) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "\"debug_connection\" supports IPv4 only"); - return NGX_CONF_ERROR; - } - - dc->mask = cidr.u.in.mask; - dc->addr = cidr.u.in.addr; - return NGX_CONF_OK; } @@ -1107,8 +1103,9 @@ ngx_event_debug_connection(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) return NGX_CONF_ERROR; } - dc->mask = 0xffffffff; - dc->addr = *(in_addr_t *)(h->h_addr_list[0]); + cidr->family = AF_INET; + cidr->u.in.mask = 0xffffffff; + cidr->u.in.addr = *(in_addr_t *)(h->h_addr_list[0]); #else @@ -1142,7 +1139,7 @@ ngx_event_core_create_conf(ngx_cycle_t *cycle) #if (NGX_DEBUG) if (ngx_array_init(&ecf->debug_connection, cycle->pool, 4, - sizeof(ngx_event_debug_t)) == NGX_ERROR) + sizeof(ngx_cidr_t)) == NGX_ERROR) { return NULL; } diff --git a/src/event/ngx_event.h b/src/event/ngx_event.h index 8cc87ebff..2096da234 100644 --- a/src/event/ngx_event.h +++ b/src/event/ngx_event.h @@ -222,12 +222,6 @@ struct ngx_event_aio_s { typedef struct { - in_addr_t mask; - in_addr_t addr; -} ngx_event_debug_t; - - -typedef struct { ngx_int_t (*add)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags); ngx_int_t (*del)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags); diff --git a/src/event/ngx_event_accept.c b/src/event/ngx_event_accept.c index f2dd50ffc..6087d60da 100644 --- a/src/event/ngx_event_accept.c +++ b/src/event/ngx_event_accept.c @@ -286,17 +286,56 @@ ngx_event_accept(ngx_event_t *ev) #if (NGX_DEBUG) { - in_addr_t i; - ngx_event_debug_t *dc; - struct sockaddr_in *sin; + struct sockaddr_in *sin; + ngx_cidr_t *cidr; + ngx_uint_t i; +#if (NGX_HAVE_INET6) + struct sockaddr_in6 *sin6; + ngx_uint_t n; +#endif - sin = (struct sockaddr_in *) sa; - dc = ecf->debug_connection.elts; + cidr = ecf->debug_connection.elts; for (i = 0; i < ecf->debug_connection.nelts; i++) { - if ((sin->sin_addr.s_addr & dc[i].mask) == dc[i].addr) { - log->log_level = NGX_LOG_DEBUG_CONNECTION|NGX_LOG_DEBUG_ALL; + if (cidr[i].family != c->sockaddr->sa_family) { + goto next; + } + + switch (cidr[i].family) { + +#if (NGX_HAVE_INET6) + case AF_INET6: + sin6 = (struct sockaddr_in6 *) c->sockaddr; + for (n = 0; n < 16; n++) { + if ((sin6->sin6_addr.s6_addr[n] + & cidr[i].u.in6.mask.s6_addr[n]) + != cidr[i].u.in6.addr.s6_addr[n]) + { + goto next; + } + } + break; +#endif + +#if (NGX_HAVE_UNIX_DOMAIN) + case AF_UNIX: + break; +#endif + + default: /* AF_INET */ + sin = (struct sockaddr_in *) c->sockaddr; + if ((sin->sin_addr.s_addr & cidr[i].u.in.mask) + != cidr[i].u.in.addr) + { + goto next; + } break; } + + log->log_level = NGX_LOG_DEBUG_CONNECTION|NGX_LOG_DEBUG_ALL; + break; + + next: + continue; } } |
