comparison src/http/ngx_http_core_module.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 19db5a6bc34e
children cebf5fed00bf
comparison
equal deleted inserted replaced
6682:db422604ceb0 6683:b802b7e1d9bc
2821 2821
2822 static ngx_int_t 2822 static ngx_int_t
2823 ngx_http_get_forwarded_addr_internal(ngx_http_request_t *r, ngx_addr_t *addr, 2823 ngx_http_get_forwarded_addr_internal(ngx_http_request_t *r, ngx_addr_t *addr,
2824 u_char *xff, size_t xfflen, ngx_array_t *proxies, int recursive) 2824 u_char *xff, size_t xfflen, ngx_array_t *proxies, int recursive)
2825 { 2825 {
2826 u_char *p; 2826 u_char *p;
2827 in_addr_t inaddr; 2827 ngx_int_t rc;
2828 ngx_int_t rc; 2828 ngx_addr_t paddr;
2829 ngx_addr_t paddr; 2829
2830 ngx_cidr_t *cidr; 2830 if (ngx_cidr_match(addr->sockaddr, proxies) != NGX_OK) {
2831 ngx_uint_t family, i; 2831 return NGX_DECLINED;
2832 #if (NGX_HAVE_INET6) 2832 }
2833 ngx_uint_t n; 2833
2834 struct in6_addr *inaddr6; 2834 for (p = xff + xfflen - 1; p > xff; p--, xfflen--) {
2835 #endif 2835 if (*p != ' ' && *p != ',') {
2836
2837 #if (NGX_SUPPRESS_WARN)
2838 inaddr = 0;
2839 #if (NGX_HAVE_INET6)
2840 inaddr6 = NULL;
2841 #endif
2842 #endif
2843
2844 family = addr->sockaddr->sa_family;
2845
2846 if (family == AF_INET) {
2847 inaddr = ((struct sockaddr_in *) addr->sockaddr)->sin_addr.s_addr;
2848 }
2849
2850 #if (NGX_HAVE_INET6)
2851 else if (family == AF_INET6) {
2852 inaddr6 = &((struct sockaddr_in6 *) addr->sockaddr)->sin6_addr;
2853
2854 if (IN6_IS_ADDR_V4MAPPED(inaddr6)) {
2855 family = AF_INET;
2856
2857 p = inaddr6->s6_addr;
2858
2859 inaddr = p[12] << 24;
2860 inaddr += p[13] << 16;
2861 inaddr += p[14] << 8;
2862 inaddr += p[15];
2863
2864 inaddr = htonl(inaddr);
2865 }
2866 }
2867 #endif
2868
2869 for (cidr = proxies->elts, i = 0; i < proxies->nelts; i++) {
2870 if (cidr[i].family != family) {
2871 goto next;
2872 }
2873
2874 switch (family) {
2875
2876 #if (NGX_HAVE_INET6)
2877 case AF_INET6:
2878 for (n = 0; n < 16; n++) {
2879 if ((inaddr6->s6_addr[n] & cidr[i].u.in6.mask.s6_addr[n])
2880 != cidr[i].u.in6.addr.s6_addr[n])
2881 {
2882 goto next;
2883 }
2884 }
2885 break; 2836 break;
2886 #endif 2837 }
2887 2838 }
2888 #if (NGX_HAVE_UNIX_DOMAIN) 2839
2889 case AF_UNIX: 2840 for ( /* void */ ; p > xff; p--) {
2841 if (*p == ' ' || *p == ',') {
2842 p++;
2890 break; 2843 break;
2891 #endif 2844 }
2892 2845 }
2893 default: /* AF_INET */ 2846
2894 if ((inaddr & cidr[i].u.in.mask) != cidr[i].u.in.addr) { 2847 if (ngx_parse_addr_port(r->pool, &paddr, p, xfflen - (p - xff)) != NGX_OK) {
2895 goto next; 2848 return NGX_DECLINED;
2896 } 2849 }
2897 break; 2850
2898 } 2851 *addr = paddr;
2899 2852
2900 for (p = xff + xfflen - 1; p > xff; p--, xfflen--) { 2853 if (recursive && p > xff) {
2901 if (*p != ' ' && *p != ',') { 2854 rc = ngx_http_get_forwarded_addr_internal(r, addr, xff, p - 1 - xff,
2902 break; 2855 proxies, 1);
2903 } 2856
2904 } 2857 if (rc == NGX_DECLINED) {
2905 2858 return NGX_DONE;
2906 for ( /* void */ ; p > xff; p--) { 2859 }
2907 if (*p == ' ' || *p == ',') { 2860
2908 p++; 2861 /* rc == NGX_OK || rc == NGX_DONE */
2909 break; 2862 return rc;
2910 } 2863 }
2911 } 2864
2912 2865 return NGX_OK;
2913 if (ngx_parse_addr_port(r->pool, &paddr, p, xfflen - (p - xff))
2914 != NGX_OK)
2915 {
2916 return NGX_DECLINED;
2917 }
2918
2919 *addr = paddr;
2920
2921 if (recursive && p > xff) {
2922 rc = ngx_http_get_forwarded_addr_internal(r, addr, xff, p - 1 - xff,
2923 proxies, 1);
2924
2925 if (rc == NGX_DECLINED) {
2926 return NGX_DONE;
2927 }
2928
2929 /* rc == NGX_OK || rc == NGX_DONE */
2930 return rc;
2931 }
2932
2933 return NGX_OK;
2934
2935 next:
2936 continue;
2937 }
2938
2939 return NGX_DECLINED;
2940 } 2866 }
2941 2867
2942 2868
2943 static char * 2869 static char *
2944 ngx_http_core_server(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy) 2870 ngx_http_core_server(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)