Mercurial > hg > nginx
annotate src/http/modules/ngx_http_realip_module.c @ 3440:88741ec7731a stable-0.7
merge r3294, r3305:
Fix a bug introduced in r2032: After a child process has read a terminate
message from a channel, the process tries to read the channel again.
The kernel (at least FreeBSD) may preempt the process and sends a SIGIO
signal to a master process. The master process sends a new terminate message,
the kernel switches again to the the child process, and the child process
reads the messages instead of an EAGAIN error. And this may repeat over
and over. Being that the child process can not exit the cycle and test
the termination flag set by the message handler.
The fix disallow the master process to send a new terminate message on
SIGIO signal reception. It may send the message only on SIGALARM signal.
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Mon, 01 Feb 2010 15:49:36 +0000 |
parents | 2efa8d2fcde1 |
children | fb4f7605505f |
rev | line source |
---|---|
573 | 1 |
2 /* | |
3 * Copyright (C) Igor Sysoev | |
4 */ | |
5 | |
6 | |
7 #include <ngx_config.h> | |
8 #include <ngx_core.h> | |
9 #include <ngx_http.h> | |
10 | |
11 | |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
12 #define NGX_HTTP_REALIP_XREALIP 0 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
13 #define NGX_HTTP_REALIP_XFWD 1 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
14 #define NGX_HTTP_REALIP_HEADER 2 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
15 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
16 |
573 | 17 typedef struct { |
2176
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
18 in_addr_t mask; |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
19 in_addr_t addr; |
573 | 20 } ngx_http_realip_from_t; |
21 | |
22 | |
23 typedef struct { | |
2176
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
24 ngx_array_t *from; /* array of ngx_http_realip_from_t */ |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
25 ngx_uint_t type; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
26 ngx_uint_t hash; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
27 ngx_str_t header; |
573 | 28 } ngx_http_realip_loc_conf_t; |
29 | |
30 | |
2176
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
31 typedef struct { |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
32 ngx_connection_t *connection; |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
33 in_addr_t addr; |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
34 ngx_str_t addr_text; |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
35 } ngx_http_realip_ctx_t; |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
36 |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
37 |
573 | 38 static ngx_int_t ngx_http_realip_handler(ngx_http_request_t *r); |
2176
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
39 static void ngx_http_realip_cleanup(void *data); |
573 | 40 static char *ngx_http_realip_from(ngx_conf_t *cf, ngx_command_t *cmd, |
41 void *conf); | |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
42 static char *ngx_http_realip(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); |
573 | 43 static void *ngx_http_realip_create_loc_conf(ngx_conf_t *cf); |
44 static char *ngx_http_realip_merge_loc_conf(ngx_conf_t *cf, | |
45 void *parent, void *child); | |
681 | 46 static ngx_int_t ngx_http_realip_init(ngx_conf_t *cf); |
573 | 47 |
48 | |
49 static ngx_command_t ngx_http_realip_commands[] = { | |
50 | |
51 { ngx_string("set_real_ip_from"), | |
52 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
53 ngx_http_realip_from, | |
54 NGX_HTTP_LOC_CONF_OFFSET, | |
55 0, | |
56 NULL }, | |
57 | |
58 { ngx_string("real_ip_header"), | |
59 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
60 ngx_http_realip, |
573 | 61 NGX_HTTP_LOC_CONF_OFFSET, |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
62 0, |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
63 NULL }, |
573 | 64 |
65 ngx_null_command | |
66 }; | |
67 | |
68 | |
69 | |
667 | 70 static ngx_http_module_t ngx_http_realip_module_ctx = { |
573 | 71 NULL, /* preconfiguration */ |
681 | 72 ngx_http_realip_init, /* postconfiguration */ |
573 | 73 |
74 NULL, /* create main configuration */ | |
75 NULL, /* init main configuration */ | |
76 | |
77 NULL, /* create server configuration */ | |
78 NULL, /* merge server configuration */ | |
79 | |
80 ngx_http_realip_create_loc_conf, /* create location configuration */ | |
81 ngx_http_realip_merge_loc_conf /* merge location configuration */ | |
82 }; | |
83 | |
84 | |
85 ngx_module_t ngx_http_realip_module = { | |
86 NGX_MODULE_V1, | |
87 &ngx_http_realip_module_ctx, /* module context */ | |
88 ngx_http_realip_commands, /* module directives */ | |
89 NGX_HTTP_MODULE, /* module type */ | |
90 NULL, /* init master */ | |
681 | 91 NULL, /* init module */ |
573 | 92 NULL, /* init process */ |
93 NULL, /* init thread */ | |
94 NULL, /* exit thread */ | |
95 NULL, /* exit process */ | |
96 NULL, /* exit master */ | |
97 NGX_MODULE_V1_PADDING | |
98 }; | |
99 | |
100 | |
101 static ngx_int_t | |
102 ngx_http_realip_handler(ngx_http_request_t *r) | |
103 { | |
104 u_char *ip, *p; | |
105 size_t len; | |
1114
3f354952e91d
fix broken values, debug logging, and style fix
Igor Sysoev <igor@sysoev.ru>
parents:
986
diff
changeset
|
106 in_addr_t addr; |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
107 ngx_uint_t i, hash; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
108 ngx_list_part_t *part; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
109 ngx_table_elt_t *header; |
573 | 110 struct sockaddr_in *sin; |
2176
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
111 ngx_connection_t *c; |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
112 ngx_pool_cleanup_t *cln; |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
113 ngx_http_realip_ctx_t *ctx; |
573 | 114 ngx_http_realip_from_t *from; |
115 ngx_http_realip_loc_conf_t *rlcf; | |
116 | |
2176
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
117 ctx = ngx_http_get_module_ctx(r, ngx_http_realip_module); |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
118 |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
119 if (ctx) { |
986
68c85f283043
ngx_http_realip_module must return NGX_DECLINED
Igor Sysoev <igor@sysoev.ru>
parents:
681
diff
changeset
|
120 return NGX_DECLINED; |
573 | 121 } |
122 | |
2176
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
123 cln = ngx_pool_cleanup_add(r->pool, sizeof(ngx_http_realip_ctx_t)); |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
124 if (cln == NULL) { |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
125 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
126 } |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
127 |
573 | 128 rlcf = ngx_http_get_module_loc_conf(r, ngx_http_realip_module); |
129 | |
130 if (rlcf->from == NULL) { | |
986
68c85f283043
ngx_http_realip_module must return NGX_DECLINED
Igor Sysoev <igor@sysoev.ru>
parents:
681
diff
changeset
|
131 return NGX_DECLINED; |
573 | 132 } |
133 | |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
134 switch (rlcf->type) { |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
135 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
136 case NGX_HTTP_REALIP_XREALIP: |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
137 |
573 | 138 if (r->headers_in.x_real_ip == NULL) { |
986
68c85f283043
ngx_http_realip_module must return NGX_DECLINED
Igor Sysoev <igor@sysoev.ru>
parents:
681
diff
changeset
|
139 return NGX_DECLINED; |
573 | 140 } |
141 | |
142 len = r->headers_in.x_real_ip->value.len; | |
143 ip = r->headers_in.x_real_ip->value.data; | |
144 | |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
145 break; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
146 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
147 case NGX_HTTP_REALIP_XFWD: |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
148 |
573 | 149 if (r->headers_in.x_forwarded_for == NULL) { |
986
68c85f283043
ngx_http_realip_module must return NGX_DECLINED
Igor Sysoev <igor@sysoev.ru>
parents:
681
diff
changeset
|
150 return NGX_DECLINED; |
573 | 151 } |
152 | |
153 len = r->headers_in.x_forwarded_for->value.len; | |
154 ip = r->headers_in.x_forwarded_for->value.data; | |
155 | |
1114
3f354952e91d
fix broken values, debug logging, and style fix
Igor Sysoev <igor@sysoev.ru>
parents:
986
diff
changeset
|
156 for (p = ip + len - 1; p > ip; p--) { |
573 | 157 if (*p == ' ' || *p == ',') { |
1114
3f354952e91d
fix broken values, debug logging, and style fix
Igor Sysoev <igor@sysoev.ru>
parents:
986
diff
changeset
|
158 p++; |
3f354952e91d
fix broken values, debug logging, and style fix
Igor Sysoev <igor@sysoev.ru>
parents:
986
diff
changeset
|
159 len -= p - ip; |
3f354952e91d
fix broken values, debug logging, and style fix
Igor Sysoev <igor@sysoev.ru>
parents:
986
diff
changeset
|
160 ip = p; |
3f354952e91d
fix broken values, debug logging, and style fix
Igor Sysoev <igor@sysoev.ru>
parents:
986
diff
changeset
|
161 break; |
573 | 162 } |
163 } | |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
164 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
165 break; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
166 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
167 default: /* NGX_HTTP_REALIP_HEADER */ |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
168 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
169 part = &r->headers_in.headers.part; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
170 header = part->elts; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
171 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
172 hash = rlcf->hash; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
173 len = rlcf->header.len; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
174 p = rlcf->header.data; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
175 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
176 for (i = 0; /* void */ ; i++) { |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
177 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
178 if (i >= part->nelts) { |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
179 if (part->next == NULL) { |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
180 break; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
181 } |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
182 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
183 part = part->next; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
184 header = part->elts; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
185 i = 0; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
186 } |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
187 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
188 if (hash == header[i].hash |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
189 && len == header[i].key.len |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
190 && ngx_strncmp(p, header[i].lowcase_key, len) == 0) |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
191 { |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
192 len = header[i].value.len; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
193 ip = header[i].value.data; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
194 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
195 goto found; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
196 } |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
197 } |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
198 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
199 return NGX_DECLINED; |
573 | 200 } |
201 | |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
202 found: |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
203 |
2176
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
204 c = r->connection; |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
205 |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
206 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "realip: \"%s\"", ip); |
1114
3f354952e91d
fix broken values, debug logging, and style fix
Igor Sysoev <igor@sysoev.ru>
parents:
986
diff
changeset
|
207 |
573 | 208 /* AF_INET only */ |
209 | |
2512
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2257
diff
changeset
|
210 if (r->connection->sockaddr->sa_family != AF_INET) { |
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2257
diff
changeset
|
211 return NGX_DECLINED; |
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2257
diff
changeset
|
212 } |
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2257
diff
changeset
|
213 |
2176
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
214 sin = (struct sockaddr_in *) c->sockaddr; |
573 | 215 |
216 from = rlcf->from->elts; | |
217 for (i = 0; i < rlcf->from->nelts; i++) { | |
218 | |
2176
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
219 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0, |
573 | 220 "realip: %08XD %08XD %08XD", |
221 sin->sin_addr.s_addr, from[i].mask, from[i].addr); | |
222 | |
223 if ((sin->sin_addr.s_addr & from[i].mask) == from[i].addr) { | |
224 | |
2176
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
225 ctx = cln->data; |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
226 |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
227 ngx_http_set_ctx(r, ctx, ngx_http_realip_module); |
1114
3f354952e91d
fix broken values, debug logging, and style fix
Igor Sysoev <igor@sysoev.ru>
parents:
986
diff
changeset
|
228 |
3f354952e91d
fix broken values, debug logging, and style fix
Igor Sysoev <igor@sysoev.ru>
parents:
986
diff
changeset
|
229 addr = inet_addr((char *) ip); |
3f354952e91d
fix broken values, debug logging, and style fix
Igor Sysoev <igor@sysoev.ru>
parents:
986
diff
changeset
|
230 |
3f354952e91d
fix broken values, debug logging, and style fix
Igor Sysoev <igor@sysoev.ru>
parents:
986
diff
changeset
|
231 if (addr == INADDR_NONE) { |
3f354952e91d
fix broken values, debug logging, and style fix
Igor Sysoev <igor@sysoev.ru>
parents:
986
diff
changeset
|
232 return NGX_DECLINED; |
3f354952e91d
fix broken values, debug logging, and style fix
Igor Sysoev <igor@sysoev.ru>
parents:
986
diff
changeset
|
233 } |
3f354952e91d
fix broken values, debug logging, and style fix
Igor Sysoev <igor@sysoev.ru>
parents:
986
diff
changeset
|
234 |
2176
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
235 p = ngx_pnalloc(c->pool, len); |
1118
cec2866f29bd
a client address must be allocated from a connection pool
Igor Sysoev <igor@sysoev.ru>
parents:
1114
diff
changeset
|
236 if (p == NULL) { |
cec2866f29bd
a client address must be allocated from a connection pool
Igor Sysoev <igor@sysoev.ru>
parents:
1114
diff
changeset
|
237 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
cec2866f29bd
a client address must be allocated from a connection pool
Igor Sysoev <igor@sysoev.ru>
parents:
1114
diff
changeset
|
238 } |
cec2866f29bd
a client address must be allocated from a connection pool
Igor Sysoev <igor@sysoev.ru>
parents:
1114
diff
changeset
|
239 |
cec2866f29bd
a client address must be allocated from a connection pool
Igor Sysoev <igor@sysoev.ru>
parents:
1114
diff
changeset
|
240 ngx_memcpy(p, ip, len); |
cec2866f29bd
a client address must be allocated from a connection pool
Igor Sysoev <igor@sysoev.ru>
parents:
1114
diff
changeset
|
241 |
2176
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
242 cln->handler = ngx_http_realip_cleanup; |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
243 |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
244 ctx->connection = c; |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
245 ctx->addr = sin->sin_addr.s_addr; |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
246 ctx->addr_text = c->addr_text; |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
247 |
1114
3f354952e91d
fix broken values, debug logging, and style fix
Igor Sysoev <igor@sysoev.ru>
parents:
986
diff
changeset
|
248 sin->sin_addr.s_addr = addr; |
3f354952e91d
fix broken values, debug logging, and style fix
Igor Sysoev <igor@sysoev.ru>
parents:
986
diff
changeset
|
249 |
2176
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
250 c->addr_text.len = len; |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
251 c->addr_text.data = p; |
573 | 252 |
986
68c85f283043
ngx_http_realip_module must return NGX_DECLINED
Igor Sysoev <igor@sysoev.ru>
parents:
681
diff
changeset
|
253 return NGX_DECLINED; |
573 | 254 } |
255 } | |
256 | |
986
68c85f283043
ngx_http_realip_module must return NGX_DECLINED
Igor Sysoev <igor@sysoev.ru>
parents:
681
diff
changeset
|
257 return NGX_DECLINED; |
573 | 258 } |
259 | |
260 | |
2176
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
261 static void |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
262 ngx_http_realip_cleanup(void *data) |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
263 { |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
264 ngx_http_realip_ctx_t *ctx = data; |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
265 |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
266 ngx_connection_t *c; |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
267 struct sockaddr_in *sin; |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
268 |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
269 c = ctx->connection; |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
270 |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
271 sin = (struct sockaddr_in *) c->sockaddr; |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
272 sin->sin_addr.s_addr = ctx->addr; |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
273 |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
274 c->addr_text = ctx->addr_text; |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
275 } |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
276 |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
277 |
573 | 278 static char * |
279 ngx_http_realip_from(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
280 { | |
281 ngx_http_realip_loc_conf_t *rlcf = conf; | |
282 | |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
283 ngx_int_t rc; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
284 ngx_str_t *value; |
2537
a472d954c534
prepare ngx_ptocidr() for IPv6
Igor Sysoev <igor@sysoev.ru>
parents:
2512
diff
changeset
|
285 ngx_cidr_t cidr; |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
286 ngx_http_realip_from_t *from; |
573 | 287 |
288 if (rlcf->from == NULL) { | |
289 rlcf->from = ngx_array_create(cf->pool, 2, | |
290 sizeof(ngx_http_realip_from_t)); | |
291 if (rlcf->from == NULL) { | |
292 return NGX_CONF_ERROR; | |
293 } | |
294 } | |
295 | |
296 from = ngx_array_push(rlcf->from); | |
297 if (from == NULL) { | |
298 return NGX_CONF_ERROR; | |
299 } | |
300 | |
301 value = cf->args->elts; | |
302 | |
2537
a472d954c534
prepare ngx_ptocidr() for IPv6
Igor Sysoev <igor@sysoev.ru>
parents:
2512
diff
changeset
|
303 rc = ngx_ptocidr(&value[1], &cidr); |
1380
b590a528fd41
ignore meaningless bits in CIDR and warn about them
Igor Sysoev <igor@sysoev.ru>
parents:
1118
diff
changeset
|
304 |
b590a528fd41
ignore meaningless bits in CIDR and warn about them
Igor Sysoev <igor@sysoev.ru>
parents:
1118
diff
changeset
|
305 if (rc == NGX_ERROR) { |
573 | 306 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"", |
307 &value[1]); | |
308 return NGX_CONF_ERROR; | |
309 } | |
310 | |
2537
a472d954c534
prepare ngx_ptocidr() for IPv6
Igor Sysoev <igor@sysoev.ru>
parents:
2512
diff
changeset
|
311 if (cidr.family != AF_INET) { |
a472d954c534
prepare ngx_ptocidr() for IPv6
Igor Sysoev <igor@sysoev.ru>
parents:
2512
diff
changeset
|
312 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
a472d954c534
prepare ngx_ptocidr() for IPv6
Igor Sysoev <igor@sysoev.ru>
parents:
2512
diff
changeset
|
313 "\"realip_from\" supports IPv4 only"); |
a472d954c534
prepare ngx_ptocidr() for IPv6
Igor Sysoev <igor@sysoev.ru>
parents:
2512
diff
changeset
|
314 return NGX_CONF_ERROR; |
a472d954c534
prepare ngx_ptocidr() for IPv6
Igor Sysoev <igor@sysoev.ru>
parents:
2512
diff
changeset
|
315 } |
a472d954c534
prepare ngx_ptocidr() for IPv6
Igor Sysoev <igor@sysoev.ru>
parents:
2512
diff
changeset
|
316 |
1380
b590a528fd41
ignore meaningless bits in CIDR and warn about them
Igor Sysoev <igor@sysoev.ru>
parents:
1118
diff
changeset
|
317 if (rc == NGX_DONE) { |
b590a528fd41
ignore meaningless bits in CIDR and warn about them
Igor Sysoev <igor@sysoev.ru>
parents:
1118
diff
changeset
|
318 ngx_conf_log_error(NGX_LOG_WARN, cf, 0, |
b590a528fd41
ignore meaningless bits in CIDR and warn about them
Igor Sysoev <igor@sysoev.ru>
parents:
1118
diff
changeset
|
319 "low address bits of %V are meaningless", &value[1]); |
b590a528fd41
ignore meaningless bits in CIDR and warn about them
Igor Sysoev <igor@sysoev.ru>
parents:
1118
diff
changeset
|
320 } |
b590a528fd41
ignore meaningless bits in CIDR and warn about them
Igor Sysoev <igor@sysoev.ru>
parents:
1118
diff
changeset
|
321 |
2537
a472d954c534
prepare ngx_ptocidr() for IPv6
Igor Sysoev <igor@sysoev.ru>
parents:
2512
diff
changeset
|
322 from->mask = cidr.u.in.mask; |
a472d954c534
prepare ngx_ptocidr() for IPv6
Igor Sysoev <igor@sysoev.ru>
parents:
2512
diff
changeset
|
323 from->addr = cidr.u.in.addr; |
573 | 324 |
325 return NGX_CONF_OK; | |
326 } | |
327 | |
328 | |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
329 static char * |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
330 ngx_http_realip(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
331 { |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
332 ngx_http_realip_loc_conf_t *rlcf = conf; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
333 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
334 ngx_str_t *value; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
335 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
336 value = cf->args->elts; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
337 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
338 if (ngx_strcmp(value[1].data, "X-Real-IP") == 0) { |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
339 rlcf->type = NGX_HTTP_REALIP_XREALIP; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
340 return NGX_CONF_OK; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
341 } |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
342 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
343 if (ngx_strcmp(value[1].data, "X-Forwarded-For") == 0) { |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
344 rlcf->type = NGX_HTTP_REALIP_XFWD; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
345 return NGX_CONF_OK; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
346 } |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
347 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
348 rlcf->type = NGX_HTTP_REALIP_HEADER; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
349 rlcf->hash = ngx_hash_strlow(value[1].data, value[1].data, value[1].len); |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
350 rlcf->header = value[1]; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
351 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
352 return NGX_CONF_OK; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
353 } |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
354 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
355 |
573 | 356 static void * |
357 ngx_http_realip_create_loc_conf(ngx_conf_t *cf) | |
358 { | |
359 ngx_http_realip_loc_conf_t *conf; | |
360 | |
361 conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_realip_loc_conf_t)); | |
362 if (conf == NULL) { | |
3237
2efa8d2fcde1
merge r2903, r2911, r2912, r3002:
Igor Sysoev <igor@sysoev.ru>
parents:
2537
diff
changeset
|
363 return NULL; |
573 | 364 } |
365 | |
366 /* | |
367 * set by ngx_pcalloc(): | |
368 * | |
369 * conf->from = NULL; | |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
370 * conf->hash = 0; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
371 * conf->header = { 0, NULL }; |
573 | 372 */ |
373 | |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
374 conf->type = NGX_CONF_UNSET_UINT; |
573 | 375 |
376 return conf; | |
377 } | |
378 | |
379 | |
380 static char * | |
381 ngx_http_realip_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) | |
382 { | |
383 ngx_http_realip_loc_conf_t *prev = parent; | |
384 ngx_http_realip_loc_conf_t *conf = child; | |
385 | |
386 if (conf->from == NULL) { | |
387 conf->from = prev->from; | |
388 } | |
389 | |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
390 ngx_conf_merge_uint_value(conf->type, prev->type, NGX_HTTP_REALIP_XREALIP); |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
391 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
392 if (conf->header.len == 0) { |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
393 conf->hash = prev->hash; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
394 conf->header = prev->header; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
395 } |
573 | 396 |
397 return NGX_CONF_OK; | |
398 } | |
399 | |
400 | |
401 static ngx_int_t | |
681 | 402 ngx_http_realip_init(ngx_conf_t *cf) |
573 | 403 { |
404 ngx_http_handler_pt *h; | |
405 ngx_http_core_main_conf_t *cmcf; | |
406 | |
681 | 407 cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); |
573 | 408 |
409 h = ngx_array_push(&cmcf->phases[NGX_HTTP_POST_READ_PHASE].handlers); | |
410 if (h == NULL) { | |
411 return NGX_ERROR; | |
412 } | |
413 | |
414 *h = ngx_http_realip_handler; | |
415 | |
581 | 416 h = ngx_array_push(&cmcf->phases[NGX_HTTP_PREACCESS_PHASE].handlers); |
573 | 417 if (h == NULL) { |
418 return NGX_ERROR; | |
419 } | |
420 | |
421 *h = ngx_http_realip_handler; | |
422 | |
423 return NGX_OK; | |
424 } |