comparison src/http/modules/ngx_http_realip_module.c @ 3274:95b0b0d7843f

set_real_ip_from unix:
author Igor Sysoev <igor@sysoev.ru>
date Mon, 02 Nov 2009 16:46:07 +0000
parents fe71be4a02f1
children 0ec36375f52c
comparison
equal deleted inserted replaced
3273:fe71be4a02f1 3274:95b0b0d7843f
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:1; */
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 struct sockaddr *sockaddr; 36 struct sockaddr *sockaddr;
34 socklen_t socklen; 37 socklen_t socklen;
35 ngx_str_t addr_text; 38 ngx_str_t addr_text;
36 } ngx_http_realip_ctx_t; 39 } ngx_http_realip_ctx_t;
37 40
38 41
39 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);
40 static void ngx_http_realip_cleanup(void *data); 45 static void ngx_http_realip_cleanup(void *data);
41 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,
42 void *conf); 47 void *conf);
43 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);
44 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);
102 static ngx_int_t 107 static ngx_int_t
103 ngx_http_realip_handler(ngx_http_request_t *r) 108 ngx_http_realip_handler(ngx_http_request_t *r)
104 { 109 {
105 u_char *ip, *p; 110 u_char *ip, *p;
106 size_t len; 111 size_t len;
107 ngx_int_t rc;
108 ngx_uint_t i, hash; 112 ngx_uint_t i, hash;
109 ngx_addr_t addr;
110 ngx_list_part_t *part; 113 ngx_list_part_t *part;
111 ngx_table_elt_t *header; 114 ngx_table_elt_t *header;
112 struct sockaddr_in *sin; 115 struct sockaddr_in *sin;
113 ngx_connection_t *c; 116 ngx_connection_t *c;
114 ngx_pool_cleanup_t *cln;
115 ngx_http_realip_ctx_t *ctx; 117 ngx_http_realip_ctx_t *ctx;
116 ngx_http_realip_from_t *from; 118 ngx_http_realip_from_t *from;
117 ngx_http_realip_loc_conf_t *rlcf; 119 ngx_http_realip_loc_conf_t *rlcf;
118 120
119 ctx = ngx_http_get_module_ctx(r, ngx_http_realip_module); 121 ctx = ngx_http_get_module_ctx(r, ngx_http_realip_module);
120 122
121 if (ctx) { 123 if (ctx) {
122 return NGX_DECLINED; 124 return NGX_DECLINED;
123 }
124
125 cln = ngx_pool_cleanup_add(r->pool, sizeof(ngx_http_realip_ctx_t));
126 if (cln == NULL) {
127 return NGX_HTTP_INTERNAL_SERVER_ERROR;
128 } 125 }
129 126
130 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);
131 128
132 if (rlcf->from == NULL) { 129 if (rlcf->from == NULL) {
207 204
208 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "realip: \"%s\"", ip); 205 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "realip: \"%s\"", ip);
209 206
210 /* AF_INET only */ 207 /* AF_INET only */
211 208
212 if (r->connection->sockaddr->sa_family != AF_INET) { 209 if (c->sockaddr->sa_family == AF_INET) {
210 sin = (struct sockaddr_in *) c->sockaddr;
211
212 from = rlcf->from->elts;
213 for (i = 0; i < rlcf->from->nelts; i++) {
214
215 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0,
216 "realip: %08XD %08XD %08XD",
217 sin->sin_addr.s_addr, from[i].mask, from[i].addr);
218
219 if ((sin->sin_addr.s_addr & from[i].mask) == from[i].addr) {
220 return ngx_http_realip_set_addr(r, ip, len);
221 }
222 }
223 }
224
225 #if (NGX_HAVE_UNIX_DOMAIN)
226
227 if (c->sockaddr->sa_family == AF_UNIX && rlcf->unixsock) {
228 return ngx_http_realip_set_addr(r, ip, len);
229 }
230
231 #endif
232
233 return NGX_DECLINED;
234 }
235
236
237 static ngx_int_t
238 ngx_http_realip_set_addr(ngx_http_request_t *r, u_char *ip, size_t len)
239 {
240 u_char *p;
241 ngx_int_t rc;
242 ngx_addr_t addr;
243 ngx_connection_t *c;
244 ngx_pool_cleanup_t *cln;
245 ngx_http_realip_ctx_t *ctx;
246
247 cln = ngx_pool_cleanup_add(r->pool, sizeof(ngx_http_realip_ctx_t));
248 if (cln == NULL) {
249 return NGX_HTTP_INTERNAL_SERVER_ERROR;
250 }
251
252 ctx = cln->data;
253 ngx_http_set_ctx(r, ctx, ngx_http_realip_module);
254
255 c = r->connection;
256
257 rc = ngx_parse_addr(c->pool, &addr, ip, len);
258
259 switch (rc) {
260 case NGX_DECLINED:
213 return NGX_DECLINED; 261 return NGX_DECLINED;
214 } 262 case NGX_ERROR:
215 263 return NGX_HTTP_INTERNAL_SERVER_ERROR;
216 sin = (struct sockaddr_in *) c->sockaddr; 264 default: /* NGX_OK */
217 265 break;
218 from = rlcf->from->elts; 266 }
219 for (i = 0; i < rlcf->from->nelts; i++) { 267
220 268 p = ngx_pnalloc(c->pool, len);
221 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0, 269 if (p == NULL) {
222 "realip: %08XD %08XD %08XD", 270 return NGX_HTTP_INTERNAL_SERVER_ERROR;
223 sin->sin_addr.s_addr, from[i].mask, from[i].addr); 271 }
224 272
225 if ((sin->sin_addr.s_addr & from[i].mask) == from[i].addr) { 273 ngx_memcpy(p, ip, len);
226 274
227 ctx = cln->data; 275 cln->handler = ngx_http_realip_cleanup;
228 276
229 ngx_http_set_ctx(r, ctx, ngx_http_realip_module); 277 ctx->connection = c;
230 278 ctx->sockaddr = c->sockaddr;
231 rc = ngx_parse_addr(c->pool, &addr, ip, len); 279 ctx->socklen = c->socklen;
232 280 ctx->addr_text = c->addr_text;
233 switch (rc) { 281
234 case NGX_DECLINED: 282 c->sockaddr = addr.sockaddr;
235 return NGX_DECLINED; 283 c->socklen = addr.socklen;
236 case NGX_ERROR: 284 c->addr_text.len = len;
237 return NGX_HTTP_INTERNAL_SERVER_ERROR; 285 c->addr_text.data = p;
238 default: /* NGX_OK */
239 break;
240 }
241
242 p = ngx_pnalloc(c->pool, len);
243 if (p == NULL) {
244 return NGX_HTTP_INTERNAL_SERVER_ERROR;
245 }
246
247 ngx_memcpy(p, ip, len);
248
249 cln->handler = ngx_http_realip_cleanup;
250
251 ctx->connection = c;
252 ctx->sockaddr = c->sockaddr;
253 ctx->socklen = c->socklen;
254 ctx->addr_text = c->addr_text;
255
256 c->sockaddr = addr.sockaddr;
257 c->socklen = addr.socklen;
258 c->addr_text.len = len;
259 c->addr_text.data = p;
260
261 return NGX_DECLINED;
262 }
263 }
264 286
265 return NGX_DECLINED; 287 return NGX_DECLINED;
266 } 288 }
267 289
268 290
288 310
289 ngx_int_t rc; 311 ngx_int_t rc;
290 ngx_str_t *value; 312 ngx_str_t *value;
291 ngx_cidr_t cidr; 313 ngx_cidr_t cidr;
292 ngx_http_realip_from_t *from; 314 ngx_http_realip_from_t *from;
315
316 value = cf->args->elts;
317
318 #if (NGX_HAVE_UNIX_DOMAIN)
319
320 if (ngx_strcmp(value[1].data, "unix:") == 0) {
321 rlcf->unixsock = 1;
322 return NGX_CONF_OK;
323 }
324
325 #endif
293 326
294 if (rlcf->from == NULL) { 327 if (rlcf->from == NULL) {
295 rlcf->from = ngx_array_create(cf->pool, 2, 328 rlcf->from = ngx_array_create(cf->pool, 2,
296 sizeof(ngx_http_realip_from_t)); 329 sizeof(ngx_http_realip_from_t));
297 if (rlcf->from == NULL) { 330 if (rlcf->from == NULL) {
301 334
302 from = ngx_array_push(rlcf->from); 335 from = ngx_array_push(rlcf->from);
303 if (from == NULL) { 336 if (from == NULL) {
304 return NGX_CONF_ERROR; 337 return NGX_CONF_ERROR;
305 } 338 }
306
307 value = cf->args->elts;
308 339
309 rc = ngx_ptocidr(&value[1], &cidr); 340 rc = ngx_ptocidr(&value[1], &cidr);
310 341
311 if (rc == NGX_ERROR) { 342 if (rc == NGX_ERROR) {
312 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"", 343 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"",
373 * set by ngx_pcalloc(): 404 * set by ngx_pcalloc():
374 * 405 *
375 * conf->from = NULL; 406 * conf->from = NULL;
376 * conf->hash = 0; 407 * conf->hash = 0;
377 * conf->header = { 0, NULL }; 408 * conf->header = { 0, NULL };
409 * conf->unixsock = 0;
378 */ 410 */
379 411
380 conf->type = NGX_CONF_UNSET_UINT; 412 conf->type = NGX_CONF_UNSET_UINT;
381 413
382 return conf; 414 return conf;
389 ngx_http_realip_loc_conf_t *prev = parent; 421 ngx_http_realip_loc_conf_t *prev = parent;
390 ngx_http_realip_loc_conf_t *conf = child; 422 ngx_http_realip_loc_conf_t *conf = child;
391 423
392 if (conf->from == NULL) { 424 if (conf->from == NULL) {
393 conf->from = prev->from; 425 conf->from = prev->from;
426 #if (NGX_HAVE_UNIX_DOMAIN)
427 conf->unixsock = prev->unixsock;
428 #endif
394 } 429 }
395 430
396 ngx_conf_merge_uint_value(conf->type, prev->type, NGX_HTTP_REALIP_XREALIP); 431 ngx_conf_merge_uint_value(conf->type, prev->type, NGX_HTTP_REALIP_XREALIP);
397 432
398 if (conf->header.len == 0) { 433 if (conf->header.len == 0) {