Mercurial > hg > nginx-mail
diff src/http/modules/ngx_http_realip_module.c @ 665:0b460e61bdcd default tip
Merge with nginx 1.0.0.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Mon, 25 Apr 2011 04:22:17 +0400 |
parents | 40c366b3535c |
children |
line wrap: on
line diff
--- a/src/http/modules/ngx_http_realip_module.c +++ b/src/http/modules/ngx_http_realip_module.c @@ -25,17 +25,23 @@ typedef struct { ngx_uint_t type; ngx_uint_t hash; ngx_str_t header; +#if (NGX_HAVE_UNIX_DOMAIN) + ngx_uint_t unixsock; /* unsigned unixsock:2; */ +#endif } ngx_http_realip_loc_conf_t; typedef struct { ngx_connection_t *connection; - in_addr_t addr; + struct sockaddr *sockaddr; + socklen_t socklen; ngx_str_t addr_text; } ngx_http_realip_ctx_t; static ngx_int_t ngx_http_realip_handler(ngx_http_request_t *r); +static ngx_int_t ngx_http_realip_set_addr(ngx_http_request_t *r, u_char *ip, + size_t len); static void ngx_http_realip_cleanup(void *data); static char *ngx_http_realip_from(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); @@ -103,13 +109,11 @@ ngx_http_realip_handler(ngx_http_request { u_char *ip, *p; size_t len; - in_addr_t addr; ngx_uint_t i, hash; ngx_list_part_t *part; ngx_table_elt_t *header; struct sockaddr_in *sin; ngx_connection_t *c; - ngx_pool_cleanup_t *cln; ngx_http_realip_ctx_t *ctx; ngx_http_realip_from_t *from; ngx_http_realip_loc_conf_t *rlcf; @@ -120,14 +124,14 @@ ngx_http_realip_handler(ngx_http_request return NGX_DECLINED; } - cln = ngx_pool_cleanup_add(r->pool, sizeof(ngx_http_realip_ctx_t)); - if (cln == NULL) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; - } - rlcf = ngx_http_get_module_loc_conf(r, ngx_http_realip_module); - if (rlcf->from == NULL) { + if (rlcf->from == NULL +#if (NGX_HAVE_UNIX_DOMAIN) + && !rlcf->unixsock +#endif + ) + { return NGX_DECLINED; } @@ -207,52 +211,83 @@ found: /* AF_INET only */ - if (r->connection->sockaddr->sa_family != AF_INET) { - return NGX_DECLINED; + if (c->sockaddr->sa_family == AF_INET) { + sin = (struct sockaddr_in *) c->sockaddr; + + from = rlcf->from->elts; + for (i = 0; i < rlcf->from->nelts; i++) { + + ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0, + "realip: %08XD %08XD %08XD", + sin->sin_addr.s_addr, from[i].mask, from[i].addr); + + if ((sin->sin_addr.s_addr & from[i].mask) == from[i].addr) { + return ngx_http_realip_set_addr(r, ip, len); + } + } + } + +#if (NGX_HAVE_UNIX_DOMAIN) + + if (c->sockaddr->sa_family == AF_UNIX && rlcf->unixsock) { + return ngx_http_realip_set_addr(r, ip, len); } - sin = (struct sockaddr_in *) c->sockaddr; +#endif - from = rlcf->from->elts; - for (i = 0; i < rlcf->from->nelts; i++) { + return NGX_DECLINED; +} - ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0, - "realip: %08XD %08XD %08XD", - sin->sin_addr.s_addr, from[i].mask, from[i].addr); - if ((sin->sin_addr.s_addr & from[i].mask) == from[i].addr) { - - ctx = cln->data; - - ngx_http_set_ctx(r, ctx, ngx_http_realip_module); +static ngx_int_t +ngx_http_realip_set_addr(ngx_http_request_t *r, u_char *ip, size_t len) +{ + u_char *p; + ngx_int_t rc; + ngx_addr_t addr; + ngx_connection_t *c; + ngx_pool_cleanup_t *cln; + ngx_http_realip_ctx_t *ctx; - addr = inet_addr((char *) ip); + cln = ngx_pool_cleanup_add(r->pool, sizeof(ngx_http_realip_ctx_t)); + if (cln == NULL) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } - if (addr == INADDR_NONE) { - return NGX_DECLINED; - } + ctx = cln->data; + ngx_http_set_ctx(r, ctx, ngx_http_realip_module); + + c = r->connection; + + rc = ngx_parse_addr(c->pool, &addr, ip, len); - p = ngx_pnalloc(c->pool, len); - if (p == NULL) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; - } + switch (rc) { + case NGX_DECLINED: + return NGX_DECLINED; + case NGX_ERROR: + return NGX_HTTP_INTERNAL_SERVER_ERROR; + default: /* NGX_OK */ + break; + } - ngx_memcpy(p, ip, len); - - cln->handler = ngx_http_realip_cleanup; + p = ngx_pnalloc(c->pool, len); + if (p == NULL) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } - ctx->connection = c; - ctx->addr = sin->sin_addr.s_addr; - ctx->addr_text = c->addr_text; + ngx_memcpy(p, ip, len); - sin->sin_addr.s_addr = addr; + cln->handler = ngx_http_realip_cleanup; - c->addr_text.len = len; - c->addr_text.data = p; + ctx->connection = c; + ctx->sockaddr = c->sockaddr; + ctx->socklen = c->socklen; + ctx->addr_text = c->addr_text; - return NGX_DECLINED; - } - } + c->sockaddr = addr.sockaddr; + c->socklen = addr.socklen; + c->addr_text.len = len; + c->addr_text.data = p; return NGX_DECLINED; } @@ -263,14 +298,12 @@ ngx_http_realip_cleanup(void *data) { ngx_http_realip_ctx_t *ctx = data; - ngx_connection_t *c; - struct sockaddr_in *sin; + ngx_connection_t *c; c = ctx->connection; - sin = (struct sockaddr_in *) c->sockaddr; - sin->sin_addr.s_addr = ctx->addr; - + c->sockaddr = ctx->sockaddr; + c->socklen = ctx->socklen; c->addr_text = ctx->addr_text; } @@ -285,6 +318,17 @@ ngx_http_realip_from(ngx_conf_t *cf, ngx ngx_cidr_t cidr; ngx_http_realip_from_t *from; + value = cf->args->elts; + +#if (NGX_HAVE_UNIX_DOMAIN) + + if (ngx_strcmp(value[1].data, "unix:") == 0) { + rlcf->unixsock = 1; + return NGX_CONF_OK; + } + +#endif + if (rlcf->from == NULL) { rlcf->from = ngx_array_create(cf->pool, 2, sizeof(ngx_http_realip_from_t)); @@ -298,8 +342,6 @@ ngx_http_realip_from(ngx_conf_t *cf, ngx return NGX_CONF_ERROR; } - value = cf->args->elts; - rc = ngx_ptocidr(&value[1], &cidr); if (rc == NGX_ERROR) { @@ -310,7 +352,7 @@ ngx_http_realip_from(ngx_conf_t *cf, ngx if (cidr.family != AF_INET) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "\"realip_from\" supports IPv4 only"); + "\"set_real_ip_from\" supports IPv4 only"); return NGX_CONF_ERROR; } @@ -372,6 +414,9 @@ ngx_http_realip_create_loc_conf(ngx_conf */ conf->type = NGX_CONF_UNSET_UINT; +#if (NGX_HAVE_UNIX_DOMAIN) + conf->unixsock = 2; +#endif return conf; } @@ -387,6 +432,12 @@ ngx_http_realip_merge_loc_conf(ngx_conf_ conf->from = prev->from; } +#if (NGX_HAVE_UNIX_DOMAIN) + if (conf->unixsock == 2) { + conf->unixsock = (prev->unixsock == 2) ? 0 : prev->unixsock; + } +#endif + ngx_conf_merge_uint_value(conf->type, prev->type, NGX_HTTP_REALIP_XREALIP); if (conf->header.len == 0) {