Ticket #44: nginx-realip-ipv6.patch

File nginx-realip-ipv6.patch, 4.5 KB (added by anaconda, 15 years ago)
  • src/http/modules/ngx_http_realip_module.c

     
    1919    in_addr_t          addr;
    2020} ngx_http_realip_from_t;
    2121
     22#if (NGX_HAVE_INET6)
     23typedef struct {
     24    struct in6_addr    mask;
     25    struct in6_addr    addr;
     26} ngx_http_realip_from6_t;
     27#endif
    2228
    2329typedef struct {
    2430    ngx_array_t       *from;     /* array of ngx_http_realip_from_t */
     31#if (NGX_HAVE_INET6)
     32    ngx_array_t       *from6;    /* array of ngx_http_realip_from6_t */
     33#endif
    2534    ngx_uint_t         type;
    2635    ngx_uint_t         hash;
    2736    ngx_str_t          header;
     
    117126    ngx_http_realip_ctx_t       *ctx;
    118127    ngx_http_realip_from_t      *from;
    119128    ngx_http_realip_loc_conf_t  *rlcf;
     129#if (NGX_HAVE_INET6)
     130    ngx_uint_t                   n;
     131    struct sockaddr_in6         *sin6;
     132    ngx_http_realip_from6_t     *from6;
     133#endif
    120134
    121135    ctx = ngx_http_get_module_ctx(r, ngx_http_realip_module);
    122136
     
    209223
    210224    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "realip: \"%s\"", ip);
    211225
    212     /* AF_INET only */
    213 
    214226    if (c->sockaddr->sa_family == AF_INET) {
    215227        sin = (struct sockaddr_in *) c->sockaddr;
    216228
     
    227239        }
    228240    }
    229241
     242#if (NGX_HAVE_INET6)
     243    if (c->sockaddr->sa_family == AF_INET6) {
     244        sin6 = (struct sockaddr_in6 *) c->sockaddr;
     245
     246        from6 = rlcf->from6->elts;
     247        for (i = 0; i < rlcf->from6->nelts; i++) {
     248            for (n = 0; n < 16; n++) {
     249                if ((sin6->sin6_addr.s6_addr[n] & from6[i].mask.s6_addr[n]) != from6[i].addr.s6_addr[n]) {
     250                    goto next;
     251                }
     252            }
     253
     254            return ngx_http_realip_set_addr(r, ip, len);
     255
     256    next:
     257        continue;
     258        }
     259    }
     260#endif
     261
    230262#if (NGX_HAVE_UNIX_DOMAIN)
    231263
    232264    if (c->sockaddr->sa_family == AF_UNIX && rlcf->unixsock) {
     
    317349    ngx_str_t               *value;
    318350    ngx_cidr_t               cidr;
    319351    ngx_http_realip_from_t  *from;
     352#if (NGX_HAVE_INET6)
     353    ngx_http_realip_from6_t *from6;
     354#endif
    320355
    321356    value = cf->args->elts;
    322357
     
    328363    }
    329364
    330365#endif
    331 
    332     if (rlcf->from == NULL) {
    333         rlcf->from = ngx_array_create(cf->pool, 2,
    334                                       sizeof(ngx_http_realip_from_t));
    335         if (rlcf->from == NULL) {
    336             return NGX_CONF_ERROR;
    337         }
    338     }
    339 
    340     from = ngx_array_push(rlcf->from);
    341     if (from == NULL) {
    342         return NGX_CONF_ERROR;
    343     }
    344 
     366   
    345367    rc = ngx_ptocidr(&value[1], &cidr);
    346368
    347369    if (rc == NGX_ERROR) {
     
    350372        return NGX_CONF_ERROR;
    351373    }
    352374
     375#if !(NGX_HAVE_INET6)
    353376    if (cidr.family != AF_INET) {
    354377        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
    355378                           "\"set_real_ip_from\" supports IPv4 only");
    356379        return NGX_CONF_ERROR;
    357380    }
     381#endif
    358382
    359383    if (rc == NGX_DONE) {
    360384        ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
    361385                           "low address bits of %V are meaningless", &value[1]);
    362386    }
    363387
    364     from->mask = cidr.u.in.mask;
    365     from->addr = cidr.u.in.addr;
     388    switch (cidr.family) {
     389#if (NGX_HAVE_INET6)
     390    case AF_INET6:
     391        if (rlcf->from6 == NULL) {
     392            rlcf->from6 = ngx_array_create(cf->pool, 2,
     393                                           sizeof(ngx_http_realip_from6_t));
     394            if (rlcf->from6 == NULL) {
     395                return NGX_CONF_ERROR;
     396            }
     397        }
    366398
     399        from6 = ngx_array_push(rlcf->from6);
     400        if (from6 == NULL) {
     401            return NGX_CONF_ERROR;
     402        }
     403
     404        from6->addr = cidr.u.in6.addr;
     405        from6->mask = cidr.u.in6.mask;
     406        break;
     407#endif
     408
     409    default: /* AF_INET */
     410        if (rlcf->from == NULL) {
     411            rlcf->from = ngx_array_create(cf->pool, 2,
     412                                          sizeof(ngx_http_realip_from_t));
     413            if (rlcf->from == NULL) {
     414                return NGX_CONF_ERROR;
     415            }
     416        }
     417
     418        from = ngx_array_push(rlcf->from);
     419        if (from == NULL) {
     420            return NGX_CONF_ERROR;
     421        }
     422
     423        from->addr = cidr.u.in.addr;
     424        from->mask = cidr.u.in.mask;
     425    }
     426
    367427    return NGX_CONF_OK;
    368428}
    369429
     
    432492        conf->from = prev->from;
    433493    }
    434494
     495#if (NGX_HAVE_INET6)
     496    if (conf->from6 == NULL) {
     497        conf->from6 = prev->from6;
     498    }
     499#endif
     500
    435501#if (NGX_HAVE_UNIX_DOMAIN)
    436502    if (conf->unixsock == 2) {
    437503        conf->unixsock = (prev->unixsock == 2) ? 0 : prev->unixsock;