comparison src/http/modules/ngx_http_realip_module.c @ 578:f3a9e57d2e17

Merge with current.
author Maxim Dounin <mdounin@mdounin.ru>
date Thu, 11 Mar 2010 21:27:17 +0300
parents 40c366b3535c
children
comparison
equal deleted inserted replaced
539:5f4de8cf0d9d 578:f3a9e57d2e17
23 typedef struct { 23 typedef struct {
24 ngx_array_t *from; /* array of ngx_http_realip_from_t */ 24 ngx_array_t *from; /* array of ngx_http_realip_from_t */
25 ngx_uint_t type; 25 ngx_uint_t type;
26 ngx_uint_t hash; 26 ngx_uint_t hash;
27 ngx_str_t header; 27 ngx_str_t header;
28 #if (NGX_HAVE_UNIX_DOMAIN)
29 ngx_uint_t unixsock; /* unsigned unixsock:2; */
30 #endif
28 } ngx_http_realip_loc_conf_t; 31 } ngx_http_realip_loc_conf_t;
29 32
30 33
31 typedef struct { 34 typedef struct {
32 ngx_connection_t *connection; 35 ngx_connection_t *connection;
33 in_addr_t addr; 36 struct sockaddr *sockaddr;
37 socklen_t socklen;
34 ngx_str_t addr_text; 38 ngx_str_t addr_text;
35 } ngx_http_realip_ctx_t; 39 } ngx_http_realip_ctx_t;
36 40
37 41
38 static ngx_int_t ngx_http_realip_handler(ngx_http_request_t *r); 42 static ngx_int_t ngx_http_realip_handler(ngx_http_request_t *r);
43 static ngx_int_t ngx_http_realip_set_addr(ngx_http_request_t *r, u_char *ip,
44 size_t len);
39 static void ngx_http_realip_cleanup(void *data); 45 static void ngx_http_realip_cleanup(void *data);
40 static char *ngx_http_realip_from(ngx_conf_t *cf, ngx_command_t *cmd, 46 static char *ngx_http_realip_from(ngx_conf_t *cf, ngx_command_t *cmd,
41 void *conf); 47 void *conf);
42 static char *ngx_http_realip(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); 48 static char *ngx_http_realip(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
43 static void *ngx_http_realip_create_loc_conf(ngx_conf_t *cf); 49 static void *ngx_http_realip_create_loc_conf(ngx_conf_t *cf);
101 static ngx_int_t 107 static ngx_int_t
102 ngx_http_realip_handler(ngx_http_request_t *r) 108 ngx_http_realip_handler(ngx_http_request_t *r)
103 { 109 {
104 u_char *ip, *p; 110 u_char *ip, *p;
105 size_t len; 111 size_t len;
106 in_addr_t addr;
107 ngx_uint_t i, hash; 112 ngx_uint_t i, hash;
108 ngx_list_part_t *part; 113 ngx_list_part_t *part;
109 ngx_table_elt_t *header; 114 ngx_table_elt_t *header;
110 struct sockaddr_in *sin; 115 struct sockaddr_in *sin;
111 ngx_connection_t *c; 116 ngx_connection_t *c;
112 ngx_pool_cleanup_t *cln;
113 ngx_http_realip_ctx_t *ctx; 117 ngx_http_realip_ctx_t *ctx;
114 ngx_http_realip_from_t *from; 118 ngx_http_realip_from_t *from;
115 ngx_http_realip_loc_conf_t *rlcf; 119 ngx_http_realip_loc_conf_t *rlcf;
116 120
117 ctx = ngx_http_get_module_ctx(r, ngx_http_realip_module); 121 ctx = ngx_http_get_module_ctx(r, ngx_http_realip_module);
118 122
119 if (ctx) { 123 if (ctx) {
120 return NGX_DECLINED; 124 return NGX_DECLINED;
121 } 125 }
122 126
123 cln = ngx_pool_cleanup_add(r->pool, sizeof(ngx_http_realip_ctx_t));
124 if (cln == NULL) {
125 return NGX_HTTP_INTERNAL_SERVER_ERROR;
126 }
127
128 rlcf = ngx_http_get_module_loc_conf(r, ngx_http_realip_module); 127 rlcf = ngx_http_get_module_loc_conf(r, ngx_http_realip_module);
129 128
130 if (rlcf->from == NULL) { 129 if (rlcf->from == NULL
130 #if (NGX_HAVE_UNIX_DOMAIN)
131 && !rlcf->unixsock
132 #endif
133 )
134 {
131 return NGX_DECLINED; 135 return NGX_DECLINED;
132 } 136 }
133 137
134 switch (rlcf->type) { 138 switch (rlcf->type) {
135 139
205 209
206 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "realip: \"%s\"", ip); 210 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "realip: \"%s\"", ip);
207 211
208 /* AF_INET only */ 212 /* AF_INET only */
209 213
210 if (r->connection->sockaddr->sa_family != AF_INET) { 214 if (c->sockaddr->sa_family == AF_INET) {
215 sin = (struct sockaddr_in *) c->sockaddr;
216
217 from = rlcf->from->elts;
218 for (i = 0; i < rlcf->from->nelts; i++) {
219
220 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0,
221 "realip: %08XD %08XD %08XD",
222 sin->sin_addr.s_addr, from[i].mask, from[i].addr);
223
224 if ((sin->sin_addr.s_addr & from[i].mask) == from[i].addr) {
225 return ngx_http_realip_set_addr(r, ip, len);
226 }
227 }
228 }
229
230 #if (NGX_HAVE_UNIX_DOMAIN)
231
232 if (c->sockaddr->sa_family == AF_UNIX && rlcf->unixsock) {
233 return ngx_http_realip_set_addr(r, ip, len);
234 }
235
236 #endif
237
238 return NGX_DECLINED;
239 }
240
241
242 static ngx_int_t
243 ngx_http_realip_set_addr(ngx_http_request_t *r, u_char *ip, size_t len)
244 {
245 u_char *p;
246 ngx_int_t rc;
247 ngx_addr_t addr;
248 ngx_connection_t *c;
249 ngx_pool_cleanup_t *cln;
250 ngx_http_realip_ctx_t *ctx;
251
252 cln = ngx_pool_cleanup_add(r->pool, sizeof(ngx_http_realip_ctx_t));
253 if (cln == NULL) {
254 return NGX_HTTP_INTERNAL_SERVER_ERROR;
255 }
256
257 ctx = cln->data;
258 ngx_http_set_ctx(r, ctx, ngx_http_realip_module);
259
260 c = r->connection;
261
262 rc = ngx_parse_addr(c->pool, &addr, ip, len);
263
264 switch (rc) {
265 case NGX_DECLINED:
211 return NGX_DECLINED; 266 return NGX_DECLINED;
212 } 267 case NGX_ERROR:
213 268 return NGX_HTTP_INTERNAL_SERVER_ERROR;
214 sin = (struct sockaddr_in *) c->sockaddr; 269 default: /* NGX_OK */
215 270 break;
216 from = rlcf->from->elts; 271 }
217 for (i = 0; i < rlcf->from->nelts; i++) { 272
218 273 p = ngx_pnalloc(c->pool, len);
219 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0, 274 if (p == NULL) {
220 "realip: %08XD %08XD %08XD", 275 return NGX_HTTP_INTERNAL_SERVER_ERROR;
221 sin->sin_addr.s_addr, from[i].mask, from[i].addr); 276 }
222 277
223 if ((sin->sin_addr.s_addr & from[i].mask) == from[i].addr) { 278 ngx_memcpy(p, ip, len);
224 279
225 ctx = cln->data; 280 cln->handler = ngx_http_realip_cleanup;
226 281
227 ngx_http_set_ctx(r, ctx, ngx_http_realip_module); 282 ctx->connection = c;
228 283 ctx->sockaddr = c->sockaddr;
229 addr = inet_addr((char *) ip); 284 ctx->socklen = c->socklen;
230 285 ctx->addr_text = c->addr_text;
231 if (addr == INADDR_NONE) { 286
232 return NGX_DECLINED; 287 c->sockaddr = addr.sockaddr;
233 } 288 c->socklen = addr.socklen;
234 289 c->addr_text.len = len;
235 p = ngx_pnalloc(c->pool, len); 290 c->addr_text.data = p;
236 if (p == NULL) {
237 return NGX_HTTP_INTERNAL_SERVER_ERROR;
238 }
239
240 ngx_memcpy(p, ip, len);
241
242 cln->handler = ngx_http_realip_cleanup;
243
244 ctx->connection = c;
245 ctx->addr = sin->sin_addr.s_addr;
246 ctx->addr_text = c->addr_text;
247
248 sin->sin_addr.s_addr = addr;
249
250 c->addr_text.len = len;
251 c->addr_text.data = p;
252
253 return NGX_DECLINED;
254 }
255 }
256 291
257 return NGX_DECLINED; 292 return NGX_DECLINED;
258 } 293 }
259 294
260 295
261 static void 296 static void
262 ngx_http_realip_cleanup(void *data) 297 ngx_http_realip_cleanup(void *data)
263 { 298 {
264 ngx_http_realip_ctx_t *ctx = data; 299 ngx_http_realip_ctx_t *ctx = data;
265 300
266 ngx_connection_t *c; 301 ngx_connection_t *c;
267 struct sockaddr_in *sin;
268 302
269 c = ctx->connection; 303 c = ctx->connection;
270 304
271 sin = (struct sockaddr_in *) c->sockaddr; 305 c->sockaddr = ctx->sockaddr;
272 sin->sin_addr.s_addr = ctx->addr; 306 c->socklen = ctx->socklen;
273
274 c->addr_text = ctx->addr_text; 307 c->addr_text = ctx->addr_text;
275 } 308 }
276 309
277 310
278 static char * 311 static char *
282 315
283 ngx_int_t rc; 316 ngx_int_t rc;
284 ngx_str_t *value; 317 ngx_str_t *value;
285 ngx_cidr_t cidr; 318 ngx_cidr_t cidr;
286 ngx_http_realip_from_t *from; 319 ngx_http_realip_from_t *from;
320
321 value = cf->args->elts;
322
323 #if (NGX_HAVE_UNIX_DOMAIN)
324
325 if (ngx_strcmp(value[1].data, "unix:") == 0) {
326 rlcf->unixsock = 1;
327 return NGX_CONF_OK;
328 }
329
330 #endif
287 331
288 if (rlcf->from == NULL) { 332 if (rlcf->from == NULL) {
289 rlcf->from = ngx_array_create(cf->pool, 2, 333 rlcf->from = ngx_array_create(cf->pool, 2,
290 sizeof(ngx_http_realip_from_t)); 334 sizeof(ngx_http_realip_from_t));
291 if (rlcf->from == NULL) { 335 if (rlcf->from == NULL) {
296 from = ngx_array_push(rlcf->from); 340 from = ngx_array_push(rlcf->from);
297 if (from == NULL) { 341 if (from == NULL) {
298 return NGX_CONF_ERROR; 342 return NGX_CONF_ERROR;
299 } 343 }
300 344
301 value = cf->args->elts;
302
303 rc = ngx_ptocidr(&value[1], &cidr); 345 rc = ngx_ptocidr(&value[1], &cidr);
304 346
305 if (rc == NGX_ERROR) { 347 if (rc == NGX_ERROR) {
306 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"", 348 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"",
307 &value[1]); 349 &value[1]);
308 return NGX_CONF_ERROR; 350 return NGX_CONF_ERROR;
309 } 351 }
310 352
311 if (cidr.family != AF_INET) { 353 if (cidr.family != AF_INET) {
312 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 354 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
313 "\"realip_from\" supports IPv4 only"); 355 "\"set_real_ip_from\" supports IPv4 only");
314 return NGX_CONF_ERROR; 356 return NGX_CONF_ERROR;
315 } 357 }
316 358
317 if (rc == NGX_DONE) { 359 if (rc == NGX_DONE) {
318 ngx_conf_log_error(NGX_LOG_WARN, cf, 0, 360 ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
370 * conf->hash = 0; 412 * conf->hash = 0;
371 * conf->header = { 0, NULL }; 413 * conf->header = { 0, NULL };
372 */ 414 */
373 415
374 conf->type = NGX_CONF_UNSET_UINT; 416 conf->type = NGX_CONF_UNSET_UINT;
417 #if (NGX_HAVE_UNIX_DOMAIN)
418 conf->unixsock = 2;
419 #endif
375 420
376 return conf; 421 return conf;
377 } 422 }
378 423
379 424
384 ngx_http_realip_loc_conf_t *conf = child; 429 ngx_http_realip_loc_conf_t *conf = child;
385 430
386 if (conf->from == NULL) { 431 if (conf->from == NULL) {
387 conf->from = prev->from; 432 conf->from = prev->from;
388 } 433 }
434
435 #if (NGX_HAVE_UNIX_DOMAIN)
436 if (conf->unixsock == 2) {
437 conf->unixsock = (prev->unixsock == 2) ? 0 : prev->unixsock;
438 }
439 #endif
389 440
390 ngx_conf_merge_uint_value(conf->type, prev->type, NGX_HTTP_REALIP_XREALIP); 441 ngx_conf_merge_uint_value(conf->type, prev->type, NGX_HTTP_REALIP_XREALIP);
391 442
392 if (conf->header.len == 0) { 443 if (conf->header.len == 0) {
393 conf->hash = prev->hash; 444 conf->hash = prev->hash;