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 }