Klaus Demo nginx / 3686010
prepare ngx_ptocidr() for IPv6 Igor Sysoev 13 years ago
6 changed file(s) with 120 addition(s) and 71 deletion(s). Raw diff Collapse all Expand all
225225 /* AF_INET only */
226226
227227 ngx_int_t
228 ngx_ptocidr(ngx_str_t *text, void *cidr)
229 {
230 u_char *addr, *mask, *last;
231 ngx_int_t shift;
232 ngx_inet_cidr_t *in_cidr;
233
234 in_cidr = cidr;
228 ngx_ptocidr(ngx_str_t *text, ngx_cidr_t *cidr)
229 {
230 u_char *addr, *mask, *last;
231 ngx_int_t shift;
232
235233 addr = text->data;
236234 last = addr + text->len;
237235
238236 mask = ngx_strlchr(addr, last, '/');
239237
240 in_cidr->addr = ngx_inet_addr(addr, (mask ? mask : last) - addr);
241
242 if (in_cidr->addr == INADDR_NONE) {
238 cidr->u.in.addr = ngx_inet_addr(addr, (mask ? mask : last) - addr);
239
240 if (cidr->u.in.addr == INADDR_NONE) {
243241 return NGX_ERROR;
244242 }
245243
246244 if (mask == NULL) {
247 in_cidr->mask = 0xffffffff;
245 cidr->family = AF_INET;
246 cidr->u.in.mask = 0xffffffff;
248247 return NGX_OK;
249248 }
250249
255254 return NGX_ERROR;
256255 }
257256
257 cidr->family = AF_INET;
258
258259 if (shift == 0) {
259260
260261 /* the x86 compilers use the shl instruction that shifts by modulo 32 */
261262
262 in_cidr->mask = 0;
263
264 if (in_cidr->addr == 0) {
263 cidr->u.in.mask = 0;
264
265 if (cidr->u.in.addr == 0) {
265266 return NGX_OK;
266267 }
267268
268269 return NGX_DONE;
269270 }
270271
271 in_cidr->mask = htonl((ngx_uint_t) (0 - (1 << (32 - shift))));
272
273 if (in_cidr->addr == (in_cidr->addr & in_cidr->mask)) {
272 cidr->u.in.mask = htonl((ngx_uint_t) (0 - (1 << (32 - shift))));
273
274 if (cidr->u.in.addr == (cidr->u.in.addr & cidr->u.in.mask)) {
274275 return NGX_OK;
275276 }
276277
277 in_cidr->addr &= in_cidr->mask;
278 cidr->u.in.addr &= cidr->u.in.mask;
278279
279280 return NGX_DONE;
280281 }
3434
3535
3636 typedef struct {
37 in_addr_t addr;
38 in_addr_t mask;
39 } ngx_inet_cidr_t;
37 struct in6_addr addr;
38 struct in6_addr mask;
39 } ngx_in6_cidr_t;
40
41
42 #if (NGX_HAVE_INET6)
43
44 typedef struct {
45 in_addr_t addr;
46 in_addr_t mask;
47 } ngx_in_cidr_t;
48
49 #endif
50
51
52 typedef struct {
53 ngx_uint_t family;
54 union {
55 ngx_in_cidr_t in;
56 #if (NGX_HAVE_INET6)
57 ngx_in6_cidr_t in6;
58 #endif
59 } u;
60 } ngx_cidr_t;
4061
4162
4263 typedef union {
43 in_addr_t in_addr;
64 in_addr_t in_addr;
4465 } ngx_url_addr_t;
4566
4667
4768 typedef struct {
48 struct sockaddr *sockaddr;
49 socklen_t socklen;
50 ngx_str_t name;
69 struct sockaddr *sockaddr;
70 socklen_t socklen;
71 ngx_str_t name;
5172 } ngx_peer_addr_t;
5273
5374
5475 typedef struct {
55 ngx_str_t url;
56 ngx_str_t host;
57 ngx_str_t port_text;
58 ngx_str_t uri;
76 ngx_str_t url;
77 ngx_str_t host;
78 ngx_str_t port_text;
79 ngx_str_t uri;
5980
60 in_port_t port;
61 in_port_t default_port;
62 int family;
81 in_port_t port;
82 in_port_t default_port;
83 int family;
6384
64 unsigned listen:1;
65 unsigned uri_part:1;
66 unsigned no_resolve:1;
67 unsigned one_addr:1;
85 unsigned listen:1;
86 unsigned uri_part:1;
87 unsigned no_resolve:1;
88 unsigned one_addr:1;
6889
69 unsigned no_port:1;
70 unsigned wildcard:1;
90 unsigned no_port:1;
91 unsigned wildcard:1;
7192
72 ngx_url_addr_t addr;
93 ngx_url_addr_t addr;
7394
74 socklen_t socklen;
75 u_char sockaddr[NGX_SOCKADDRLEN];
95 socklen_t socklen;
96 u_char sockaddr[NGX_SOCKADDRLEN];
7697
77 ngx_peer_addr_t *addrs;
78 ngx_uint_t naddrs;
98 ngx_peer_addr_t *addrs;
99 ngx_uint_t naddrs;
79100
80 char *err;
101 char *err;
81102 } ngx_url_t;
82103
83104
85106 size_t ngx_sock_ntop(struct sockaddr *sa, u_char *text, size_t len,
86107 ngx_uint_t port);
87108 size_t ngx_inet_ntop(int family, void *addr, u_char *text, size_t len);
88 ngx_int_t ngx_ptocidr(ngx_str_t *text, void *cidr);
109 ngx_int_t ngx_ptocidr(ngx_str_t *text, ngx_cidr_t *cidr);
89110 ngx_int_t ngx_parse_url(ngx_pool_t *pool, ngx_url_t *u);
90111 ngx_int_t ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u);
91112
10391039 ngx_str_t *value;
10401040 ngx_event_debug_t *dc;
10411041 struct hostent *h;
1042 ngx_inet_cidr_t in_cidr;
1042 ngx_cidr_t cidr;
10431043
10441044 value = cf->args->elts;
1045
1046 /* AF_INET only */
10471045
10481046 dc = ngx_array_push(&ecf->debug_connection);
10491047 if (dc == NULL) {
10501048 return NGX_CONF_ERROR;
10511049 }
10521050
1053 rc = ngx_ptocidr(&value[1], &in_cidr);
1051 rc = ngx_ptocidr(&value[1], &cidr);
10541052
10551053 if (rc == NGX_DONE) {
10561054 ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
10591057 }
10601058
10611059 if (rc == NGX_OK) {
1062 dc->mask = in_cidr.mask;
1063 dc->addr = in_cidr.addr;
1060
1061 /* AF_INET only */
1062
1063 if (cidr.family != AF_INET) {
1064 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1065 "\"debug_connection\" supports IPv4 only");
1066 return NGX_CONF_ERROR;
1067 }
1068
1069 dc->mask = cidr.u.in.mask;
1070 dc->addr = cidr.u.in.addr;
1071
10641072 return NGX_CONF_OK;
10651073 }
10661074
140140
141141 ngx_int_t rc;
142142 ngx_str_t *value;
143 ngx_inet_cidr_t in_cidr;
143 ngx_cidr_t cidr;
144144 ngx_http_access_rule_t *rule;
145145
146146 if (alcf->rules == NULL) {
167167 return NGX_CONF_OK;
168168 }
169169
170 rc = ngx_ptocidr(&value[1], &in_cidr);
170 rc = ngx_ptocidr(&value[1], &cidr);
171171
172172 if (rc == NGX_ERROR) {
173173 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"",
175175 return NGX_CONF_ERROR;
176176 }
177177
178 if (cidr.family != AF_INET) {
179 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
180 "\"allow\" supports IPv4 only");
181 return NGX_CONF_ERROR;
182 }
183
178184 if (rc == NGX_DONE) {
179185 ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
180186 "low address bits of %V are meaningless", &value[1]);
181187 }
182188
183 rule->mask = in_cidr.mask;
184 rule->addr = in_cidr.addr;
189 rule->mask = cidr.u.in.mask;
190 rule->addr = cidr.u.in.addr;
185191
186192 return NGX_CONF_OK;
187193 }
777777 ngx_int_t rc, del;
778778 ngx_str_t *net;
779779 ngx_uint_t i;
780 ngx_inet_cidr_t cidrin;
780 ngx_cidr_t cidr;
781781 ngx_http_variable_value_t *val, *old;
782782
783783 if (ctx->tree == NULL) {
788788 }
789789
790790 if (ngx_strcmp(value[0].data, "default") == 0) {
791 cidrin.addr = 0;
792 cidrin.mask = 0;
791 cidr.u.in.addr = 0;
792 cidr.u.in.mask = 0;
793793 net = &value[0];
794794
795795 } else {
803803 }
804804
805805 if (ngx_strcmp(net->data, "255.255.255.255") == 0) {
806 cidrin.addr = 0xffffffff;
807 cidrin.mask = 0xffffffff;
806 cidr.u.in.addr = 0xffffffff;
807 cidr.u.in.mask = 0xffffffff;
808808
809809 } else {
810 rc = ngx_ptocidr(net, &cidrin);
810 rc = ngx_ptocidr(net, &cidr);
811811
812812 if (rc == NGX_ERROR) {
813813 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
815815 return NGX_CONF_ERROR;
816816 }
817817
818 if (cidr.family != AF_INET) {
819 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
820 "\"geo\" supports IPv4 only");
821 return NGX_CONF_ERROR;
822 }
823
818824 if (rc == NGX_DONE) {
819825 ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
820826 "low address bits of %V are meaningless",
821827 net);
822828 }
823829
824 cidrin.addr = ntohl(cidrin.addr);
825 cidrin.mask = ntohl(cidrin.mask);
830 cidr.u.in.addr = ntohl(cidr.u.in.addr);
831 cidr.u.in.mask = ntohl(cidr.u.in.mask);
826832 }
827833
828834 if (del) {
829 if (ngx_radix32tree_delete(ctx->tree, cidrin.addr, cidrin.mask)
835 if (ngx_radix32tree_delete(ctx->tree, cidr.u.in.addr,
836 cidr.u.in.mask)
830837 != NGX_OK)
831838 {
832839 ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
844851 }
845852
846853 for (i = 2; i; i--) {
847 rc = ngx_radix32tree_insert(ctx->tree, cidrin.addr, cidrin.mask,
854 rc = ngx_radix32tree_insert(ctx->tree, cidr.u.in.addr, cidr.u.in.mask,
848855 (uintptr_t) val);
849856 if (rc == NGX_OK) {
850857 return NGX_CONF_OK;
857864 /* rc == NGX_BUSY */
858865
859866 old = (ngx_http_variable_value_t *)
860 ngx_radix32tree_find(ctx->tree, cidrin.addr & cidrin.mask);
867 ngx_radix32tree_find(ctx->tree, cidr.u.in.addr & cidr.u.in.mask);
861868
862869 ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
863870 "duplicate network \"%V\", value: \"%v\", old value: \"%v\"",
864871 net, val, old);
865872
866 rc = ngx_radix32tree_delete(ctx->tree, cidrin.addr, cidrin.mask);
873 rc = ngx_radix32tree_delete(ctx->tree, cidr.u.in.addr, cidr.u.in.mask);
867874
868875 if (rc == NGX_ERROR) {
869876 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid radix tree");
281281
282282 ngx_int_t rc;
283283 ngx_str_t *value;
284 ngx_inet_cidr_t in_cidr;
284 ngx_cidr_t cidr;
285285 ngx_http_realip_from_t *from;
286286
287287 if (rlcf->from == NULL) {
299299
300300 value = cf->args->elts;
301301
302 rc = ngx_ptocidr(&value[1], &in_cidr);
302 rc = ngx_ptocidr(&value[1], &cidr);
303303
304304 if (rc == NGX_ERROR) {
305305 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"",
307307 return NGX_CONF_ERROR;
308308 }
309309
310 if (cidr.family != AF_INET) {
311 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
312 "\"realip_from\" supports IPv4 only");
313 return NGX_CONF_ERROR;
314 }
315
310316 if (rc == NGX_DONE) {
311317 ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
312318 "low address bits of %V are meaningless", &value[1]);
313319 }
314320
315 from->mask = in_cidr.mask;
316 from->addr = in_cidr.addr;
321 from->mask = cidr.u.in.mask;
322 from->addr = cidr.u.in.addr;
317323
318324 return NGX_CONF_OK;
319325 }