Mercurial > hg > nginx-quic
annotate src/http/modules/ngx_http_realip_module.c @ 4622:0dfdc3f732cb
Upstream: fixed ip_hash rebalancing with the "down" flag.
Due to weight being set to 0 for down peers, order of peers after sorting
wasn't the same as without the "down" flag (with down peers at the end),
resulting in client rebalancing for clients on other servers. The only
rebalancing which should happen after adding "down" to a server is one
for clients on the server.
The problem was introduced in r1377 (which fixed endless loop by setting
weight to 0 for down servers). The loop is no longer possible with new
smooth algorithm, so preserving original weight is safe.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Mon, 14 May 2012 09:58:07 +0000 |
parents | b1950b0a9550 |
children | df93068953c0 |
rev | line source |
---|---|
573 | 1 |
2 /* | |
3 * Copyright (C) Igor Sysoev | |
4412 | 4 * Copyright (C) Nginx, Inc. |
573 | 5 */ |
6 | |
7 | |
8 #include <ngx_config.h> | |
9 #include <ngx_core.h> | |
10 #include <ngx_http.h> | |
11 | |
12 | |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
13 #define NGX_HTTP_REALIP_XREALIP 0 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
14 #define NGX_HTTP_REALIP_XFWD 1 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
15 #define NGX_HTTP_REALIP_HEADER 2 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
16 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
17 |
573 | 18 typedef struct { |
4562
b1950b0a9550
Replaced ngx_http_realip_from_t with ngx_in_cidr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
4412
diff
changeset
|
19 ngx_array_t *from; /* array of ngx_in_cidr_t */ |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
20 ngx_uint_t type; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
21 ngx_uint_t hash; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
22 ngx_str_t header; |
3274 | 23 #if (NGX_HAVE_UNIX_DOMAIN) |
3305
8017f9bda3f6
fix "set_real_ip_from unix:" inheritance
Igor Sysoev <igor@sysoev.ru>
parents:
3291
diff
changeset
|
24 ngx_uint_t unixsock; /* unsigned unixsock:2; */ |
3274 | 25 #endif |
573 | 26 } ngx_http_realip_loc_conf_t; |
27 | |
28 | |
2176
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
29 typedef struct { |
3274 | 30 ngx_connection_t *connection; |
31 struct sockaddr *sockaddr; | |
32 socklen_t socklen; | |
33 ngx_str_t addr_text; | |
2176
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
34 } ngx_http_realip_ctx_t; |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
35 |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
36 |
573 | 37 static ngx_int_t ngx_http_realip_handler(ngx_http_request_t *r); |
3274 | 38 static ngx_int_t ngx_http_realip_set_addr(ngx_http_request_t *r, u_char *ip, |
39 size_t len); | |
2176
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
40 static void ngx_http_realip_cleanup(void *data); |
573 | 41 static char *ngx_http_realip_from(ngx_conf_t *cf, ngx_command_t *cmd, |
42 void *conf); | |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
43 static char *ngx_http_realip(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); |
573 | 44 static void *ngx_http_realip_create_loc_conf(ngx_conf_t *cf); |
45 static char *ngx_http_realip_merge_loc_conf(ngx_conf_t *cf, | |
46 void *parent, void *child); | |
681 | 47 static ngx_int_t ngx_http_realip_init(ngx_conf_t *cf); |
573 | 48 |
49 | |
50 static ngx_command_t ngx_http_realip_commands[] = { | |
51 | |
52 { ngx_string("set_real_ip_from"), | |
53 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
54 ngx_http_realip_from, | |
55 NGX_HTTP_LOC_CONF_OFFSET, | |
56 0, | |
57 NULL }, | |
58 | |
59 { ngx_string("real_ip_header"), | |
60 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
|
61 ngx_http_realip, |
573 | 62 NGX_HTTP_LOC_CONF_OFFSET, |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
63 0, |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
64 NULL }, |
573 | 65 |
66 ngx_null_command | |
67 }; | |
68 | |
69 | |
70 | |
667 | 71 static ngx_http_module_t ngx_http_realip_module_ctx = { |
573 | 72 NULL, /* preconfiguration */ |
681 | 73 ngx_http_realip_init, /* postconfiguration */ |
573 | 74 |
75 NULL, /* create main configuration */ | |
76 NULL, /* init main configuration */ | |
77 | |
78 NULL, /* create server configuration */ | |
79 NULL, /* merge server configuration */ | |
80 | |
81 ngx_http_realip_create_loc_conf, /* create location configuration */ | |
82 ngx_http_realip_merge_loc_conf /* merge location configuration */ | |
83 }; | |
84 | |
85 | |
86 ngx_module_t ngx_http_realip_module = { | |
87 NGX_MODULE_V1, | |
88 &ngx_http_realip_module_ctx, /* module context */ | |
89 ngx_http_realip_commands, /* module directives */ | |
90 NGX_HTTP_MODULE, /* module type */ | |
91 NULL, /* init master */ | |
681 | 92 NULL, /* init module */ |
573 | 93 NULL, /* init process */ |
94 NULL, /* init thread */ | |
95 NULL, /* exit thread */ | |
96 NULL, /* exit process */ | |
97 NULL, /* exit master */ | |
98 NGX_MODULE_V1_PADDING | |
99 }; | |
100 | |
101 | |
102 static ngx_int_t | |
103 ngx_http_realip_handler(ngx_http_request_t *r) | |
104 { | |
105 u_char *ip, *p; | |
106 size_t len; | |
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; |
4562
b1950b0a9550
Replaced ngx_http_realip_from_t with ngx_in_cidr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
4412
diff
changeset
|
111 ngx_in_cidr_t *from; |
2176
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
112 ngx_connection_t *c; |
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_loc_conf_t *rlcf; |
115 | |
2176
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
116 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
|
117 |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
118 if (ctx) { |
986
68c85f283043
ngx_http_realip_module must return NGX_DECLINED
Igor Sysoev <igor@sysoev.ru>
parents:
681
diff
changeset
|
119 return NGX_DECLINED; |
573 | 120 } |
121 | |
122 rlcf = ngx_http_get_module_loc_conf(r, ngx_http_realip_module); | |
123 | |
3291
78faaf5cea44
allow to work single "set_real_ip_from unix:"
Igor Sysoev <igor@sysoev.ru>
parents:
3280
diff
changeset
|
124 if (rlcf->from == NULL |
78faaf5cea44
allow to work single "set_real_ip_from unix:"
Igor Sysoev <igor@sysoev.ru>
parents:
3280
diff
changeset
|
125 #if (NGX_HAVE_UNIX_DOMAIN) |
78faaf5cea44
allow to work single "set_real_ip_from unix:"
Igor Sysoev <igor@sysoev.ru>
parents:
3280
diff
changeset
|
126 && !rlcf->unixsock |
78faaf5cea44
allow to work single "set_real_ip_from unix:"
Igor Sysoev <igor@sysoev.ru>
parents:
3280
diff
changeset
|
127 #endif |
78faaf5cea44
allow to work single "set_real_ip_from unix:"
Igor Sysoev <igor@sysoev.ru>
parents:
3280
diff
changeset
|
128 ) |
78faaf5cea44
allow to work single "set_real_ip_from unix:"
Igor Sysoev <igor@sysoev.ru>
parents:
3280
diff
changeset
|
129 { |
986
68c85f283043
ngx_http_realip_module must return NGX_DECLINED
Igor Sysoev <igor@sysoev.ru>
parents:
681
diff
changeset
|
130 return NGX_DECLINED; |
573 | 131 } |
132 | |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
133 switch (rlcf->type) { |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
134 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
135 case NGX_HTTP_REALIP_XREALIP: |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
136 |
573 | 137 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
|
138 return NGX_DECLINED; |
573 | 139 } |
140 | |
141 len = r->headers_in.x_real_ip->value.len; | |
142 ip = r->headers_in.x_real_ip->value.data; | |
143 | |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
144 break; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
145 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
146 case NGX_HTTP_REALIP_XFWD: |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
147 |
573 | 148 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
|
149 return NGX_DECLINED; |
573 | 150 } |
151 | |
152 len = r->headers_in.x_forwarded_for->value.len; | |
153 ip = r->headers_in.x_forwarded_for->value.data; | |
154 | |
1114
3f354952e91d
fix broken values, debug logging, and style fix
Igor Sysoev <igor@sysoev.ru>
parents:
986
diff
changeset
|
155 for (p = ip + len - 1; p > ip; p--) { |
573 | 156 if (*p == ' ' || *p == ',') { |
1114
3f354952e91d
fix broken values, debug logging, and style fix
Igor Sysoev <igor@sysoev.ru>
parents:
986
diff
changeset
|
157 p++; |
3f354952e91d
fix broken values, debug logging, and style fix
Igor Sysoev <igor@sysoev.ru>
parents:
986
diff
changeset
|
158 len -= p - ip; |
3f354952e91d
fix broken values, debug logging, and style fix
Igor Sysoev <igor@sysoev.ru>
parents:
986
diff
changeset
|
159 ip = p; |
3f354952e91d
fix broken values, debug logging, and style fix
Igor Sysoev <igor@sysoev.ru>
parents:
986
diff
changeset
|
160 break; |
573 | 161 } |
162 } | |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
163 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
164 break; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
165 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
166 default: /* NGX_HTTP_REALIP_HEADER */ |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
167 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
168 part = &r->headers_in.headers.part; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
169 header = part->elts; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
170 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
171 hash = rlcf->hash; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
172 len = rlcf->header.len; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
173 p = rlcf->header.data; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
174 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
175 for (i = 0; /* void */ ; i++) { |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
176 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
177 if (i >= part->nelts) { |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
178 if (part->next == NULL) { |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
179 break; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
180 } |
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 part = part->next; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
183 header = part->elts; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
184 i = 0; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
185 } |
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 if (hash == header[i].hash |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
188 && len == header[i].key.len |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
189 && 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
|
190 { |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
191 len = header[i].value.len; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
192 ip = header[i].value.data; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
193 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
194 goto found; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
195 } |
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 return NGX_DECLINED; |
573 | 199 } |
200 | |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
201 found: |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
202 |
2176
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
203 c = r->connection; |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
204 |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
205 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
|
206 |
573 | 207 /* AF_INET only */ |
208 | |
3274 | 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); | |
2512
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2257
diff
changeset
|
229 } |
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2257
diff
changeset
|
230 |
3274 | 231 #endif |
573 | 232 |
3274 | 233 return NGX_DECLINED; |
234 } | |
235 | |
573 | 236 |
3274 | 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; | |
573 | 246 |
3274 | 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 } | |
2176
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
251 |
3274 | 252 ctx = cln->data; |
253 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
|
254 |
3274 | 255 c = r->connection; |
256 | |
257 rc = ngx_parse_addr(c->pool, &addr, ip, len); | |
1114
3f354952e91d
fix broken values, debug logging, and style fix
Igor Sysoev <igor@sysoev.ru>
parents:
986
diff
changeset
|
258 |
3274 | 259 switch (rc) { |
260 case NGX_DECLINED: | |
261 return NGX_DECLINED; | |
262 case NGX_ERROR: | |
263 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
264 default: /* NGX_OK */ | |
265 break; | |
266 } | |
1114
3f354952e91d
fix broken values, debug logging, and style fix
Igor Sysoev <igor@sysoev.ru>
parents:
986
diff
changeset
|
267 |
3274 | 268 p = ngx_pnalloc(c->pool, len); |
269 if (p == NULL) { | |
270 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
271 } | |
1118
cec2866f29bd
a client address must be allocated from a connection pool
Igor Sysoev <igor@sysoev.ru>
parents:
1114
diff
changeset
|
272 |
3274 | 273 ngx_memcpy(p, ip, len); |
2176
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
274 |
3274 | 275 cln->handler = ngx_http_realip_cleanup; |
2176
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
276 |
3274 | 277 ctx->connection = c; |
278 ctx->sockaddr = c->sockaddr; | |
279 ctx->socklen = c->socklen; | |
280 ctx->addr_text = c->addr_text; | |
573 | 281 |
3274 | 282 c->sockaddr = addr.sockaddr; |
283 c->socklen = addr.socklen; | |
284 c->addr_text.len = len; | |
285 c->addr_text.data = p; | |
573 | 286 |
986
68c85f283043
ngx_http_realip_module must return NGX_DECLINED
Igor Sysoev <igor@sysoev.ru>
parents:
681
diff
changeset
|
287 return NGX_DECLINED; |
573 | 288 } |
289 | |
290 | |
2176
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
291 static void |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
292 ngx_http_realip_cleanup(void *data) |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
293 { |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
294 ngx_http_realip_ctx_t *ctx = data; |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
295 |
3273
fe71be4a02f1
support IPv6 addresses in Real IP headers
Igor Sysoev <igor@sysoev.ru>
parents:
3267
diff
changeset
|
296 ngx_connection_t *c; |
2176
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
297 |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
298 c = ctx->connection; |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
299 |
3273
fe71be4a02f1
support IPv6 addresses in Real IP headers
Igor Sysoev <igor@sysoev.ru>
parents:
3267
diff
changeset
|
300 c->sockaddr = ctx->sockaddr; |
fe71be4a02f1
support IPv6 addresses in Real IP headers
Igor Sysoev <igor@sysoev.ru>
parents:
3267
diff
changeset
|
301 c->socklen = ctx->socklen; |
2176
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
302 c->addr_text = ctx->addr_text; |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
303 } |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
304 |
29d26406e1bd
restore connection address on request closure,
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
305 |
573 | 306 static char * |
307 ngx_http_realip_from(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
308 { | |
309 ngx_http_realip_loc_conf_t *rlcf = conf; | |
310 | |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
311 ngx_int_t rc; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
312 ngx_str_t *value; |
2537
a472d954c534
prepare ngx_ptocidr() for IPv6
Igor Sysoev <igor@sysoev.ru>
parents:
2512
diff
changeset
|
313 ngx_cidr_t cidr; |
4562
b1950b0a9550
Replaced ngx_http_realip_from_t with ngx_in_cidr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
4412
diff
changeset
|
314 ngx_in_cidr_t *from; |
573 | 315 |
3274 | 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 | |
326 | |
573 | 327 if (rlcf->from == NULL) { |
328 rlcf->from = ngx_array_create(cf->pool, 2, | |
4562
b1950b0a9550
Replaced ngx_http_realip_from_t with ngx_in_cidr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
4412
diff
changeset
|
329 sizeof(ngx_in_cidr_t)); |
573 | 330 if (rlcf->from == NULL) { |
331 return NGX_CONF_ERROR; | |
332 } | |
333 } | |
334 | |
335 from = ngx_array_push(rlcf->from); | |
336 if (from == NULL) { | |
337 return NGX_CONF_ERROR; | |
338 } | |
339 | |
2537
a472d954c534
prepare ngx_ptocidr() for IPv6
Igor Sysoev <igor@sysoev.ru>
parents:
2512
diff
changeset
|
340 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
|
341 |
b590a528fd41
ignore meaningless bits in CIDR and warn about them
Igor Sysoev <igor@sysoev.ru>
parents:
1118
diff
changeset
|
342 if (rc == NGX_ERROR) { |
573 | 343 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"", |
344 &value[1]); | |
345 return NGX_CONF_ERROR; | |
346 } | |
347 | |
2537
a472d954c534
prepare ngx_ptocidr() for IPv6
Igor Sysoev <igor@sysoev.ru>
parents:
2512
diff
changeset
|
348 if (cidr.family != AF_INET) { |
a472d954c534
prepare ngx_ptocidr() for IPv6
Igor Sysoev <igor@sysoev.ru>
parents:
2512
diff
changeset
|
349 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
3280
9285e936c79d
fix directive name in error message: "set_realip_from" to "set_real_ip_from"
Igor Sysoev <igor@sysoev.ru>
parents:
3279
diff
changeset
|
350 "\"set_real_ip_from\" supports IPv4 only"); |
2537
a472d954c534
prepare ngx_ptocidr() for IPv6
Igor Sysoev <igor@sysoev.ru>
parents:
2512
diff
changeset
|
351 return NGX_CONF_ERROR; |
a472d954c534
prepare ngx_ptocidr() for IPv6
Igor Sysoev <igor@sysoev.ru>
parents:
2512
diff
changeset
|
352 } |
a472d954c534
prepare ngx_ptocidr() for IPv6
Igor Sysoev <igor@sysoev.ru>
parents:
2512
diff
changeset
|
353 |
1380
b590a528fd41
ignore meaningless bits in CIDR and warn about them
Igor Sysoev <igor@sysoev.ru>
parents:
1118
diff
changeset
|
354 if (rc == NGX_DONE) { |
b590a528fd41
ignore meaningless bits in CIDR and warn about them
Igor Sysoev <igor@sysoev.ru>
parents:
1118
diff
changeset
|
355 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
|
356 "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
|
357 } |
b590a528fd41
ignore meaningless bits in CIDR and warn about them
Igor Sysoev <igor@sysoev.ru>
parents:
1118
diff
changeset
|
358 |
2537
a472d954c534
prepare ngx_ptocidr() for IPv6
Igor Sysoev <igor@sysoev.ru>
parents:
2512
diff
changeset
|
359 from->mask = cidr.u.in.mask; |
a472d954c534
prepare ngx_ptocidr() for IPv6
Igor Sysoev <igor@sysoev.ru>
parents:
2512
diff
changeset
|
360 from->addr = cidr.u.in.addr; |
573 | 361 |
362 return NGX_CONF_OK; | |
363 } | |
364 | |
365 | |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
366 static char * |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
367 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
|
368 { |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
369 ngx_http_realip_loc_conf_t *rlcf = conf; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
370 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
371 ngx_str_t *value; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
372 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
373 value = cf->args->elts; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
374 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
375 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
|
376 rlcf->type = NGX_HTTP_REALIP_XREALIP; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
377 return NGX_CONF_OK; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
378 } |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
379 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
380 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
|
381 rlcf->type = NGX_HTTP_REALIP_XFWD; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
382 return NGX_CONF_OK; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
383 } |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
384 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
385 rlcf->type = NGX_HTTP_REALIP_HEADER; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
386 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
|
387 rlcf->header = value[1]; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
388 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
389 return NGX_CONF_OK; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
390 } |
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 |
573 | 393 static void * |
394 ngx_http_realip_create_loc_conf(ngx_conf_t *cf) | |
395 { | |
396 ngx_http_realip_loc_conf_t *conf; | |
397 | |
398 conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_realip_loc_conf_t)); | |
399 if (conf == NULL) { | |
2912
c7d57b539248
return NULL instead of NGX_CONF_ERROR on a create conf failure
Igor Sysoev <igor@sysoev.ru>
parents:
2537
diff
changeset
|
400 return NULL; |
573 | 401 } |
402 | |
403 /* | |
404 * set by ngx_pcalloc(): | |
405 * | |
406 * conf->from = NULL; | |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
407 * conf->hash = 0; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
408 * conf->header = { 0, NULL }; |
573 | 409 */ |
410 | |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
411 conf->type = NGX_CONF_UNSET_UINT; |
3305
8017f9bda3f6
fix "set_real_ip_from unix:" inheritance
Igor Sysoev <igor@sysoev.ru>
parents:
3291
diff
changeset
|
412 #if (NGX_HAVE_UNIX_DOMAIN) |
8017f9bda3f6
fix "set_real_ip_from unix:" inheritance
Igor Sysoev <igor@sysoev.ru>
parents:
3291
diff
changeset
|
413 conf->unixsock = 2; |
8017f9bda3f6
fix "set_real_ip_from unix:" inheritance
Igor Sysoev <igor@sysoev.ru>
parents:
3291
diff
changeset
|
414 #endif |
573 | 415 |
416 return conf; | |
417 } | |
418 | |
419 | |
420 static char * | |
421 ngx_http_realip_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) | |
422 { | |
423 ngx_http_realip_loc_conf_t *prev = parent; | |
424 ngx_http_realip_loc_conf_t *conf = child; | |
425 | |
426 if (conf->from == NULL) { | |
427 conf->from = prev->from; | |
3305
8017f9bda3f6
fix "set_real_ip_from unix:" inheritance
Igor Sysoev <igor@sysoev.ru>
parents:
3291
diff
changeset
|
428 } |
8017f9bda3f6
fix "set_real_ip_from unix:" inheritance
Igor Sysoev <igor@sysoev.ru>
parents:
3291
diff
changeset
|
429 |
3274 | 430 #if (NGX_HAVE_UNIX_DOMAIN) |
3305
8017f9bda3f6
fix "set_real_ip_from unix:" inheritance
Igor Sysoev <igor@sysoev.ru>
parents:
3291
diff
changeset
|
431 if (conf->unixsock == 2) { |
8017f9bda3f6
fix "set_real_ip_from unix:" inheritance
Igor Sysoev <igor@sysoev.ru>
parents:
3291
diff
changeset
|
432 conf->unixsock = (prev->unixsock == 2) ? 0 : prev->unixsock; |
8017f9bda3f6
fix "set_real_ip_from unix:" inheritance
Igor Sysoev <igor@sysoev.ru>
parents:
3291
diff
changeset
|
433 } |
3274 | 434 #endif |
573 | 435 |
2257
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
436 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
|
437 |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
438 if (conf->header.len == 0) { |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
439 conf->hash = prev->hash; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
440 conf->header = prev->header; |
74d270c8821e
real_ip_header supports any header
Igor Sysoev <igor@sysoev.ru>
parents:
2202
diff
changeset
|
441 } |
573 | 442 |
443 return NGX_CONF_OK; | |
444 } | |
445 | |
446 | |
447 static ngx_int_t | |
681 | 448 ngx_http_realip_init(ngx_conf_t *cf) |
573 | 449 { |
450 ngx_http_handler_pt *h; | |
451 ngx_http_core_main_conf_t *cmcf; | |
452 | |
681 | 453 cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); |
573 | 454 |
455 h = ngx_array_push(&cmcf->phases[NGX_HTTP_POST_READ_PHASE].handlers); | |
456 if (h == NULL) { | |
457 return NGX_ERROR; | |
458 } | |
459 | |
460 *h = ngx_http_realip_handler; | |
461 | |
581 | 462 h = ngx_array_push(&cmcf->phases[NGX_HTTP_PREACCESS_PHASE].handlers); |
573 | 463 if (h == NULL) { |
464 return NGX_ERROR; | |
465 } | |
466 | |
467 *h = ngx_http_realip_handler; | |
468 | |
469 return NGX_OK; | |
470 } |