Mercurial > hg > nginx
comparison src/http/modules/ngx_http_geo_module.c @ 4996:f95b3772d832
Geo: made "default" affect both IPv4 and IPv6 when using prefixes.
Previously, "default" was equivalent to specifying 0.0.0.0/0, now
it's equivalent to specifying both 0.0.0.0/0 and ::/0 (if support
for IPv6 is enabled) with the same value.
author | Ruslan Ermilov <ru@nginx.com> |
---|---|
date | Wed, 26 Dec 2012 05:03:51 +0000 |
parents | a8cc59ead621 |
children | 3f776d65c5b9 |
comparison
equal
deleted
inserted
replaced
4995:e2e58cc10a62 | 4996:f95b3772d832 |
---|---|
91 ngx_http_geo_conf_ctx_t *ctx, in_addr_t start, in_addr_t end); | 91 ngx_http_geo_conf_ctx_t *ctx, in_addr_t start, in_addr_t end); |
92 static ngx_uint_t ngx_http_geo_delete_range(ngx_conf_t *cf, | 92 static ngx_uint_t ngx_http_geo_delete_range(ngx_conf_t *cf, |
93 ngx_http_geo_conf_ctx_t *ctx, in_addr_t start, in_addr_t end); | 93 ngx_http_geo_conf_ctx_t *ctx, in_addr_t start, in_addr_t end); |
94 static char *ngx_http_geo_cidr(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx, | 94 static char *ngx_http_geo_cidr(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx, |
95 ngx_str_t *value); | 95 ngx_str_t *value); |
96 static char *ngx_http_geo_cidr_add(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx, | |
97 ngx_cidr_t *cidr, ngx_str_t *value, ngx_str_t *net); | |
96 static ngx_http_variable_value_t *ngx_http_geo_value(ngx_conf_t *cf, | 98 static ngx_http_variable_value_t *ngx_http_geo_value(ngx_conf_t *cf, |
97 ngx_http_geo_conf_ctx_t *ctx, ngx_str_t *value); | 99 ngx_http_geo_conf_ctx_t *ctx, ngx_str_t *value); |
98 static char *ngx_http_geo_add_proxy(ngx_conf_t *cf, | 100 static char *ngx_http_geo_add_proxy(ngx_conf_t *cf, |
99 ngx_http_geo_conf_ctx_t *ctx, ngx_cidr_t *cidr); | 101 ngx_http_geo_conf_ctx_t *ctx, ngx_cidr_t *cidr); |
100 static ngx_int_t ngx_http_geo_cidr_value(ngx_conf_t *cf, ngx_str_t *net, | 102 static ngx_int_t ngx_http_geo_cidr_value(ngx_conf_t *cf, ngx_str_t *net, |
1012 | 1014 |
1013 static char * | 1015 static char * |
1014 ngx_http_geo_cidr(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx, | 1016 ngx_http_geo_cidr(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx, |
1015 ngx_str_t *value) | 1017 ngx_str_t *value) |
1016 { | 1018 { |
1017 ngx_int_t rc, del; | 1019 ngx_int_t rc, del; |
1018 ngx_str_t *net; | 1020 ngx_str_t *net; |
1019 ngx_uint_t i; | 1021 ngx_cidr_t cidr; |
1020 ngx_cidr_t cidr; | |
1021 ngx_http_variable_value_t *val, *old; | |
1022 | 1022 |
1023 if (ctx->tree == NULL) { | 1023 if (ctx->tree == NULL) { |
1024 ctx->tree = ngx_radix_tree_create(ctx->pool, -1); | 1024 ctx->tree = ngx_radix_tree_create(ctx->pool, -1); |
1025 if (ctx->tree == NULL) { | 1025 if (ctx->tree == NULL) { |
1026 return NGX_CONF_ERROR; | 1026 return NGX_CONF_ERROR; |
1038 | 1038 |
1039 if (ngx_strcmp(value[0].data, "default") == 0) { | 1039 if (ngx_strcmp(value[0].data, "default") == 0) { |
1040 cidr.family = AF_INET; | 1040 cidr.family = AF_INET; |
1041 cidr.u.in.addr = 0; | 1041 cidr.u.in.addr = 0; |
1042 cidr.u.in.mask = 0; | 1042 cidr.u.in.mask = 0; |
1043 | |
1044 if (ngx_http_geo_cidr_add(cf, ctx, &cidr, &value[1], &value[0]) | |
1045 != NGX_CONF_OK) | |
1046 { | |
1047 return NGX_CONF_ERROR; | |
1048 } | |
1049 | |
1050 #if (NGX_HAVE_INET6) | |
1051 cidr.family = AF_INET6; | |
1052 ngx_memzero(&cidr.u.in6, sizeof(ngx_in6_cidr_t)); | |
1053 | |
1054 if (ngx_http_geo_cidr_add(cf, ctx, &cidr, &value[1], &value[0]) | |
1055 != NGX_CONF_OK) | |
1056 { | |
1057 return NGX_CONF_ERROR; | |
1058 } | |
1059 #endif | |
1060 | |
1061 return NGX_CONF_OK; | |
1062 } | |
1063 | |
1064 if (ngx_strcmp(value[0].data, "delete") == 0) { | |
1065 net = &value[1]; | |
1066 del = 1; | |
1067 | |
1068 } else { | |
1043 net = &value[0]; | 1069 net = &value[0]; |
1044 | 1070 del = 0; |
1045 } else { | 1071 } |
1046 if (ngx_strcmp(value[0].data, "delete") == 0) { | 1072 |
1047 net = &value[1]; | 1073 if (ngx_http_geo_cidr_value(cf, net, &cidr) != NGX_OK) { |
1048 del = 1; | 1074 return NGX_CONF_ERROR; |
1049 | 1075 } |
1050 } else { | 1076 |
1051 net = &value[0]; | 1077 if (cidr.family == AF_INET) { |
1052 del = 0; | 1078 cidr.u.in.addr = ntohl(cidr.u.in.addr); |
1053 } | 1079 cidr.u.in.mask = ntohl(cidr.u.in.mask); |
1054 | 1080 } |
1055 if (ngx_http_geo_cidr_value(cf, net, &cidr) != NGX_OK) { | 1081 |
1056 return NGX_CONF_ERROR; | 1082 if (del) { |
1057 } | 1083 switch (cidr.family) { |
1058 | |
1059 if (cidr.family == AF_INET) { | |
1060 cidr.u.in.addr = ntohl(cidr.u.in.addr); | |
1061 cidr.u.in.mask = ntohl(cidr.u.in.mask); | |
1062 } | |
1063 | |
1064 if (del) { | |
1065 switch (cidr.family) { | |
1066 | 1084 |
1067 #if (NGX_HAVE_INET6) | 1085 #if (NGX_HAVE_INET6) |
1068 case AF_INET6: | 1086 case AF_INET6: |
1069 rc = ngx_radix128tree_delete(ctx->tree6, | 1087 rc = ngx_radix128tree_delete(ctx->tree6, |
1070 cidr.u.in6.addr.s6_addr, | 1088 cidr.u.in6.addr.s6_addr, |
1071 cidr.u.in6.mask.s6_addr); | 1089 cidr.u.in6.mask.s6_addr); |
1072 break; | 1090 break; |
1073 #endif | 1091 #endif |
1074 | 1092 |
1075 default: /* AF_INET */ | 1093 default: /* AF_INET */ |
1076 rc = ngx_radix32tree_delete(ctx->tree, cidr.u.in.addr, | 1094 rc = ngx_radix32tree_delete(ctx->tree, cidr.u.in.addr, |
1077 cidr.u.in.mask); | 1095 cidr.u.in.mask); |
1078 break; | 1096 break; |
1079 } | 1097 } |
1080 | 1098 |
1081 if (rc != NGX_OK) { | 1099 if (rc != NGX_OK) { |
1082 ngx_conf_log_error(NGX_LOG_WARN, cf, 0, | 1100 ngx_conf_log_error(NGX_LOG_WARN, cf, 0, |
1083 "no network \"%V\" to delete", net); | 1101 "no network \"%V\" to delete", net); |
1084 } | 1102 } |
1085 | 1103 |
1086 return NGX_CONF_OK; | 1104 return NGX_CONF_OK; |
1087 } | 1105 } |
1088 } | 1106 |
1089 | 1107 return ngx_http_geo_cidr_add(cf, ctx, &cidr, &value[1], net); |
1090 val = ngx_http_geo_value(cf, ctx, &value[1]); | 1108 } |
1109 | |
1110 | |
1111 static char * | |
1112 ngx_http_geo_cidr_add(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx, | |
1113 ngx_cidr_t *cidr, ngx_str_t *value, ngx_str_t *net) | |
1114 { | |
1115 ngx_int_t rc; | |
1116 ngx_uint_t i; | |
1117 ngx_http_variable_value_t *val, *old; | |
1118 | |
1119 val = ngx_http_geo_value(cf, ctx, value); | |
1091 | 1120 |
1092 if (val == NULL) { | 1121 if (val == NULL) { |
1093 return NGX_CONF_ERROR; | 1122 return NGX_CONF_ERROR; |
1094 } | 1123 } |
1095 | 1124 |
1096 switch (cidr.family) { | 1125 switch (cidr->family) { |
1097 | 1126 |
1098 #if (NGX_HAVE_INET6) | 1127 #if (NGX_HAVE_INET6) |
1099 case AF_INET6: | 1128 case AF_INET6: |
1100 for (i = 2; i; i--) { | 1129 for (i = 2; i; i--) { |
1101 rc = ngx_radix128tree_insert(ctx->tree6, cidr.u.in6.addr.s6_addr, | 1130 rc = ngx_radix128tree_insert(ctx->tree6, cidr->u.in6.addr.s6_addr, |
1102 cidr.u.in6.mask.s6_addr, | 1131 cidr->u.in6.mask.s6_addr, |
1103 (uintptr_t) val); | 1132 (uintptr_t) val); |
1104 | 1133 |
1105 if (rc == NGX_OK) { | 1134 if (rc == NGX_OK) { |
1106 return NGX_CONF_OK; | 1135 return NGX_CONF_OK; |
1107 } | 1136 } |
1112 | 1141 |
1113 /* rc == NGX_BUSY */ | 1142 /* rc == NGX_BUSY */ |
1114 | 1143 |
1115 old = (ngx_http_variable_value_t *) | 1144 old = (ngx_http_variable_value_t *) |
1116 ngx_radix128tree_find(ctx->tree6, | 1145 ngx_radix128tree_find(ctx->tree6, |
1117 cidr.u.in6.addr.s6_addr); | 1146 cidr->u.in6.addr.s6_addr); |
1118 | 1147 |
1119 ngx_conf_log_error(NGX_LOG_WARN, cf, 0, | 1148 ngx_conf_log_error(NGX_LOG_WARN, cf, 0, |
1120 "duplicate network \"%V\", value: \"%v\", old value: \"%v\"", | 1149 "duplicate network \"%V\", value: \"%v\", old value: \"%v\"", |
1121 net, val, old); | 1150 net, val, old); |
1122 | 1151 |
1123 rc = ngx_radix128tree_delete(ctx->tree6, | 1152 rc = ngx_radix128tree_delete(ctx->tree6, |
1124 cidr.u.in6.addr.s6_addr, | 1153 cidr->u.in6.addr.s6_addr, |
1125 cidr.u.in6.mask.s6_addr); | 1154 cidr->u.in6.mask.s6_addr); |
1126 | 1155 |
1127 if (rc == NGX_ERROR) { | 1156 if (rc == NGX_ERROR) { |
1128 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid radix tree"); | 1157 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid radix tree"); |
1129 return NGX_CONF_ERROR; | 1158 return NGX_CONF_ERROR; |
1130 } | 1159 } |
1133 break; | 1162 break; |
1134 #endif | 1163 #endif |
1135 | 1164 |
1136 default: /* AF_INET */ | 1165 default: /* AF_INET */ |
1137 for (i = 2; i; i--) { | 1166 for (i = 2; i; i--) { |
1138 rc = ngx_radix32tree_insert(ctx->tree, cidr.u.in.addr, | 1167 rc = ngx_radix32tree_insert(ctx->tree, cidr->u.in.addr, |
1139 cidr.u.in.mask, (uintptr_t) val); | 1168 cidr->u.in.mask, (uintptr_t) val); |
1140 | 1169 |
1141 if (rc == NGX_OK) { | 1170 if (rc == NGX_OK) { |
1142 return NGX_CONF_OK; | 1171 return NGX_CONF_OK; |
1143 } | 1172 } |
1144 | 1173 |
1147 } | 1176 } |
1148 | 1177 |
1149 /* rc == NGX_BUSY */ | 1178 /* rc == NGX_BUSY */ |
1150 | 1179 |
1151 old = (ngx_http_variable_value_t *) | 1180 old = (ngx_http_variable_value_t *) |
1152 ngx_radix32tree_find(ctx->tree, cidr.u.in.addr); | 1181 ngx_radix32tree_find(ctx->tree, cidr->u.in.addr); |
1153 | 1182 |
1154 ngx_conf_log_error(NGX_LOG_WARN, cf, 0, | 1183 ngx_conf_log_error(NGX_LOG_WARN, cf, 0, |
1155 "duplicate network \"%V\", value: \"%v\", old value: \"%v\"", | 1184 "duplicate network \"%V\", value: \"%v\", old value: \"%v\"", |
1156 net, val, old); | 1185 net, val, old); |
1157 | 1186 |
1158 rc = ngx_radix32tree_delete(ctx->tree, | 1187 rc = ngx_radix32tree_delete(ctx->tree, |
1159 cidr.u.in.addr, cidr.u.in.mask); | 1188 cidr->u.in.addr, cidr->u.in.mask); |
1160 | 1189 |
1161 if (rc == NGX_ERROR) { | 1190 if (rc == NGX_ERROR) { |
1162 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid radix tree"); | 1191 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid radix tree"); |
1163 return NGX_CONF_ERROR; | 1192 return NGX_CONF_ERROR; |
1164 } | 1193 } |