Mercurial > hg > nginx
comparison src/core/ngx_inet.c @ 6683:b802b7e1d9bc
Core: introduced ngx_cidr_match() function.
author | Dmitry Volyntsev <xeioex@nginx.com> |
---|---|
date | Wed, 07 Sep 2016 13:56:53 +0300 |
parents | 0a820872dd4c |
children | 3f94a0fc05cf |
comparison
equal
deleted
inserted
replaced
6682:db422604ceb0 | 6683:b802b7e1d9bc |
---|---|
464 } | 464 } |
465 } | 465 } |
466 | 466 |
467 | 467 |
468 ngx_int_t | 468 ngx_int_t |
469 ngx_cidr_match(struct sockaddr *sa, ngx_array_t *cidrs) | |
470 { | |
471 #if (NGX_HAVE_INET6) | |
472 u_char *p; | |
473 #endif | |
474 in_addr_t inaddr; | |
475 ngx_cidr_t *cidr; | |
476 ngx_uint_t family, i; | |
477 #if (NGX_HAVE_INET6) | |
478 ngx_uint_t n; | |
479 struct in6_addr *inaddr6; | |
480 #endif | |
481 | |
482 #if (NGX_SUPPRESS_WARN) | |
483 inaddr = 0; | |
484 #if (NGX_HAVE_INET6) | |
485 inaddr6 = NULL; | |
486 #endif | |
487 #endif | |
488 | |
489 family = sa->sa_family; | |
490 | |
491 if (family == AF_INET) { | |
492 inaddr = ((struct sockaddr_in *) sa)->sin_addr.s_addr; | |
493 } | |
494 | |
495 #if (NGX_HAVE_INET6) | |
496 else if (family == AF_INET6) { | |
497 inaddr6 = &((struct sockaddr_in6 *) sa)->sin6_addr; | |
498 | |
499 if (IN6_IS_ADDR_V4MAPPED(inaddr6)) { | |
500 family = AF_INET; | |
501 | |
502 p = inaddr6->s6_addr; | |
503 | |
504 inaddr = p[12] << 24; | |
505 inaddr += p[13] << 16; | |
506 inaddr += p[14] << 8; | |
507 inaddr += p[15]; | |
508 | |
509 inaddr = htonl(inaddr); | |
510 } | |
511 } | |
512 #endif | |
513 | |
514 for (cidr = cidrs->elts, i = 0; i < cidrs->nelts; i++) { | |
515 if (cidr[i].family != family) { | |
516 goto next; | |
517 } | |
518 | |
519 switch (family) { | |
520 | |
521 #if (NGX_HAVE_INET6) | |
522 case AF_INET6: | |
523 for (n = 0; n < 16; n++) { | |
524 if ((inaddr6->s6_addr[n] & cidr[i].u.in6.mask.s6_addr[n]) | |
525 != cidr[i].u.in6.addr.s6_addr[n]) | |
526 { | |
527 goto next; | |
528 } | |
529 } | |
530 break; | |
531 #endif | |
532 | |
533 #if (NGX_HAVE_UNIX_DOMAIN) | |
534 case AF_UNIX: | |
535 break; | |
536 #endif | |
537 | |
538 default: /* AF_INET */ | |
539 if ((inaddr & cidr[i].u.in.mask) != cidr[i].u.in.addr) { | |
540 goto next; | |
541 } | |
542 break; | |
543 } | |
544 | |
545 return NGX_OK; | |
546 | |
547 next: | |
548 continue; | |
549 } | |
550 | |
551 return NGX_DECLINED; | |
552 } | |
553 | |
554 | |
555 ngx_int_t | |
469 ngx_parse_addr(ngx_pool_t *pool, ngx_addr_t *addr, u_char *text, size_t len) | 556 ngx_parse_addr(ngx_pool_t *pool, ngx_addr_t *addr, u_char *text, size_t len) |
470 { | 557 { |
471 in_addr_t inaddr; | 558 in_addr_t inaddr; |
472 ngx_uint_t family; | 559 ngx_uint_t family; |
473 struct sockaddr_in *sin; | 560 struct sockaddr_in *sin; |