Mercurial > hg > nginx
annotate src/stream/ngx_stream_proxy_module.c @ 6202:6345822f0abb
Stream: upstream "connected" flag.
Once upstream is connected, the upstream buffer is allocated. Previously, the
proxy module used the buffer allocation status to check if upstream is
connected. Now it's enough to check the flag.
author | Roman Arutyunyan <arut@nginx.com> |
---|---|
date | Thu, 25 Jun 2015 12:36:52 +0300 |
parents | 24488e6db782 |
children | fdfdcad62875 |
rev | line source |
---|---|
6115 | 1 |
2 /* | |
3 * Copyright (C) Roman Arutyunyan | |
4 * Copyright (C) Nginx, Inc. | |
5 */ | |
6 | |
7 | |
8 #include <ngx_config.h> | |
9 #include <ngx_core.h> | |
10 #include <ngx_stream.h> | |
11 | |
12 | |
13 typedef void (*ngx_stream_proxy_handler_pt)(ngx_stream_session_t *s); | |
14 | |
15 | |
16 typedef struct { | |
17 ngx_msec_t connect_timeout; | |
18 ngx_msec_t timeout; | |
19 ngx_msec_t next_upstream_timeout; | |
20 size_t downstream_buf_size; | |
6201
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
21 size_t downstream_limit_rate; |
6115 | 22 size_t upstream_buf_size; |
6201
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
23 size_t upstream_limit_rate; |
6115 | 24 ngx_uint_t next_upstream_tries; |
25 ngx_flag_t next_upstream; | |
6184
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
26 ngx_flag_t proxy_protocol; |
6183
4dcffe43a7ea
Stream: the "proxy_bind" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
27 ngx_addr_t *local; |
6115 | 28 |
29 #if (NGX_STREAM_SSL) | |
30 ngx_flag_t ssl_enable; | |
31 ngx_flag_t ssl_session_reuse; | |
32 ngx_uint_t ssl_protocols; | |
33 ngx_str_t ssl_ciphers; | |
34 ngx_str_t ssl_name; | |
35 ngx_flag_t ssl_server_name; | |
36 | |
37 ngx_flag_t ssl_verify; | |
38 ngx_uint_t ssl_verify_depth; | |
39 ngx_str_t ssl_trusted_certificate; | |
40 ngx_str_t ssl_crl; | |
41 ngx_str_t ssl_certificate; | |
42 ngx_str_t ssl_certificate_key; | |
43 ngx_array_t *ssl_passwords; | |
44 | |
45 ngx_ssl_t *ssl; | |
46 #endif | |
47 | |
48 ngx_stream_upstream_srv_conf_t *upstream; | |
49 } ngx_stream_proxy_srv_conf_t; | |
50 | |
51 | |
52 static void ngx_stream_proxy_handler(ngx_stream_session_t *s); | |
53 static void ngx_stream_proxy_connect(ngx_stream_session_t *s); | |
54 static void ngx_stream_proxy_init_upstream(ngx_stream_session_t *s); | |
55 static void ngx_stream_proxy_upstream_handler(ngx_event_t *ev); | |
56 static void ngx_stream_proxy_downstream_handler(ngx_event_t *ev); | |
6200
abee77018d3a
Stream: common handler for upstream and downstream.
Roman Arutyunyan <arut@nginx.com>
parents:
6184
diff
changeset
|
57 static void ngx_stream_proxy_process_connection(ngx_event_t *ev, |
abee77018d3a
Stream: common handler for upstream and downstream.
Roman Arutyunyan <arut@nginx.com>
parents:
6184
diff
changeset
|
58 ngx_uint_t from_upstream); |
6115 | 59 static void ngx_stream_proxy_connect_handler(ngx_event_t *ev); |
60 static ngx_int_t ngx_stream_proxy_test_connect(ngx_connection_t *c); | |
61 static ngx_int_t ngx_stream_proxy_process(ngx_stream_session_t *s, | |
62 ngx_uint_t from_upstream, ngx_uint_t do_write); | |
63 static void ngx_stream_proxy_next_upstream(ngx_stream_session_t *s); | |
64 static void ngx_stream_proxy_finalize(ngx_stream_session_t *s, ngx_int_t rc); | |
65 static u_char *ngx_stream_proxy_log_error(ngx_log_t *log, u_char *buf, | |
66 size_t len); | |
67 | |
68 static void *ngx_stream_proxy_create_srv_conf(ngx_conf_t *cf); | |
69 static char *ngx_stream_proxy_merge_srv_conf(ngx_conf_t *cf, void *parent, | |
70 void *child); | |
71 static char *ngx_stream_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, | |
72 void *conf); | |
6183
4dcffe43a7ea
Stream: the "proxy_bind" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
73 static char *ngx_stream_proxy_bind(ngx_conf_t *cf, ngx_command_t *cmd, |
4dcffe43a7ea
Stream: the "proxy_bind" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
74 void *conf); |
6184
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
75 static ngx_int_t ngx_stream_proxy_send_proxy_protocol(ngx_stream_session_t *s); |
6115 | 76 |
77 #if (NGX_STREAM_SSL) | |
78 | |
79 static char *ngx_stream_proxy_ssl_password_file(ngx_conf_t *cf, | |
80 ngx_command_t *cmd, void *conf); | |
81 static void ngx_stream_proxy_ssl_init_connection(ngx_stream_session_t *s); | |
82 static void ngx_stream_proxy_ssl_handshake(ngx_connection_t *pc); | |
83 static ngx_int_t ngx_stream_proxy_ssl_name(ngx_stream_session_t *s); | |
84 static ngx_int_t ngx_stream_proxy_set_ssl(ngx_conf_t *cf, | |
85 ngx_stream_proxy_srv_conf_t *pscf); | |
86 | |
87 | |
88 static ngx_conf_bitmask_t ngx_stream_proxy_ssl_protocols[] = { | |
89 { ngx_string("SSLv2"), NGX_SSL_SSLv2 }, | |
90 { ngx_string("SSLv3"), NGX_SSL_SSLv3 }, | |
91 { ngx_string("TLSv1"), NGX_SSL_TLSv1 }, | |
92 { ngx_string("TLSv1.1"), NGX_SSL_TLSv1_1 }, | |
93 { ngx_string("TLSv1.2"), NGX_SSL_TLSv1_2 }, | |
94 { ngx_null_string, 0 } | |
95 }; | |
96 | |
97 #endif | |
98 | |
99 | |
100 static ngx_command_t ngx_stream_proxy_commands[] = { | |
101 | |
102 { ngx_string("proxy_pass"), | |
103 NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, | |
104 ngx_stream_proxy_pass, | |
105 NGX_STREAM_SRV_CONF_OFFSET, | |
106 0, | |
107 NULL }, | |
108 | |
6183
4dcffe43a7ea
Stream: the "proxy_bind" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
109 { ngx_string("proxy_bind"), |
4dcffe43a7ea
Stream: the "proxy_bind" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
110 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, |
4dcffe43a7ea
Stream: the "proxy_bind" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
111 ngx_stream_proxy_bind, |
4dcffe43a7ea
Stream: the "proxy_bind" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
112 NGX_STREAM_SRV_CONF_OFFSET, |
4dcffe43a7ea
Stream: the "proxy_bind" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
113 0, |
4dcffe43a7ea
Stream: the "proxy_bind" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
114 NULL }, |
4dcffe43a7ea
Stream: the "proxy_bind" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
115 |
6115 | 116 { ngx_string("proxy_connect_timeout"), |
117 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, | |
118 ngx_conf_set_msec_slot, | |
119 NGX_STREAM_SRV_CONF_OFFSET, | |
120 offsetof(ngx_stream_proxy_srv_conf_t, connect_timeout), | |
121 NULL }, | |
122 | |
123 { ngx_string("proxy_timeout"), | |
124 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, | |
125 ngx_conf_set_msec_slot, | |
126 NGX_STREAM_SRV_CONF_OFFSET, | |
127 offsetof(ngx_stream_proxy_srv_conf_t, timeout), | |
128 NULL }, | |
129 | |
130 { ngx_string("proxy_downstream_buffer"), | |
131 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, | |
132 ngx_conf_set_size_slot, | |
133 NGX_STREAM_SRV_CONF_OFFSET, | |
134 offsetof(ngx_stream_proxy_srv_conf_t, downstream_buf_size), | |
135 NULL }, | |
136 | |
6201
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
137 { ngx_string("proxy_downstream_limit_rate"), |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
138 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
139 ngx_conf_set_size_slot, |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
140 NGX_STREAM_SRV_CONF_OFFSET, |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
141 offsetof(ngx_stream_proxy_srv_conf_t, downstream_limit_rate), |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
142 NULL }, |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
143 |
6115 | 144 { ngx_string("proxy_upstream_buffer"), |
145 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, | |
146 ngx_conf_set_size_slot, | |
147 NGX_STREAM_SRV_CONF_OFFSET, | |
148 offsetof(ngx_stream_proxy_srv_conf_t, upstream_buf_size), | |
149 NULL }, | |
150 | |
6201
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
151 { ngx_string("proxy_upstream_limit_rate"), |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
152 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
153 ngx_conf_set_size_slot, |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
154 NGX_STREAM_SRV_CONF_OFFSET, |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
155 offsetof(ngx_stream_proxy_srv_conf_t, upstream_limit_rate), |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
156 NULL }, |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
157 |
6115 | 158 { ngx_string("proxy_next_upstream"), |
159 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG, | |
160 ngx_conf_set_flag_slot, | |
161 NGX_STREAM_SRV_CONF_OFFSET, | |
162 offsetof(ngx_stream_proxy_srv_conf_t, next_upstream), | |
163 NULL }, | |
164 | |
165 { ngx_string("proxy_next_upstream_tries"), | |
166 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, | |
167 ngx_conf_set_num_slot, | |
168 NGX_STREAM_SRV_CONF_OFFSET, | |
169 offsetof(ngx_stream_proxy_srv_conf_t, next_upstream_tries), | |
170 NULL }, | |
171 | |
172 { ngx_string("proxy_next_upstream_timeout"), | |
173 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, | |
174 ngx_conf_set_msec_slot, | |
175 NGX_STREAM_SRV_CONF_OFFSET, | |
176 offsetof(ngx_stream_proxy_srv_conf_t, next_upstream_timeout), | |
177 NULL }, | |
178 | |
6184
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
179 { ngx_string("proxy_protocol"), |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
180 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG, |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
181 ngx_conf_set_flag_slot, |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
182 NGX_STREAM_SRV_CONF_OFFSET, |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
183 offsetof(ngx_stream_proxy_srv_conf_t, proxy_protocol), |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
184 NULL }, |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
185 |
6115 | 186 #if (NGX_STREAM_SSL) |
187 | |
188 { ngx_string("proxy_ssl"), | |
189 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG, | |
190 ngx_conf_set_flag_slot, | |
191 NGX_STREAM_SRV_CONF_OFFSET, | |
192 offsetof(ngx_stream_proxy_srv_conf_t, ssl_enable), | |
193 NULL }, | |
194 | |
195 { ngx_string("proxy_ssl_session_reuse"), | |
196 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG, | |
197 ngx_conf_set_flag_slot, | |
198 NGX_STREAM_SRV_CONF_OFFSET, | |
199 offsetof(ngx_stream_proxy_srv_conf_t, ssl_session_reuse), | |
200 NULL }, | |
201 | |
202 { ngx_string("proxy_ssl_protocols"), | |
203 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_1MORE, | |
204 ngx_conf_set_bitmask_slot, | |
205 NGX_STREAM_SRV_CONF_OFFSET, | |
206 offsetof(ngx_stream_proxy_srv_conf_t, ssl_protocols), | |
207 &ngx_stream_proxy_ssl_protocols }, | |
208 | |
209 { ngx_string("proxy_ssl_ciphers"), | |
210 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, | |
211 ngx_conf_set_str_slot, | |
212 NGX_STREAM_SRV_CONF_OFFSET, | |
213 offsetof(ngx_stream_proxy_srv_conf_t, ssl_ciphers), | |
214 NULL }, | |
215 | |
216 { ngx_string("proxy_ssl_name"), | |
217 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, | |
218 ngx_conf_set_str_slot, | |
219 NGX_STREAM_SRV_CONF_OFFSET, | |
220 offsetof(ngx_stream_proxy_srv_conf_t, ssl_name), | |
221 NULL }, | |
222 | |
223 { ngx_string("proxy_ssl_server_name"), | |
224 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG, | |
225 ngx_conf_set_flag_slot, | |
226 NGX_STREAM_SRV_CONF_OFFSET, | |
227 offsetof(ngx_stream_proxy_srv_conf_t, ssl_server_name), | |
228 NULL }, | |
229 | |
230 { ngx_string("proxy_ssl_verify"), | |
231 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG, | |
232 ngx_conf_set_flag_slot, | |
233 NGX_STREAM_SRV_CONF_OFFSET, | |
234 offsetof(ngx_stream_proxy_srv_conf_t, ssl_verify), | |
235 NULL }, | |
236 | |
237 { ngx_string("proxy_ssl_verify_depth"), | |
238 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, | |
239 ngx_conf_set_num_slot, | |
240 NGX_STREAM_SRV_CONF_OFFSET, | |
241 offsetof(ngx_stream_proxy_srv_conf_t, ssl_verify_depth), | |
242 NULL }, | |
243 | |
244 { ngx_string("proxy_ssl_trusted_certificate"), | |
245 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, | |
246 ngx_conf_set_str_slot, | |
247 NGX_STREAM_SRV_CONF_OFFSET, | |
248 offsetof(ngx_stream_proxy_srv_conf_t, ssl_trusted_certificate), | |
249 NULL }, | |
250 | |
251 { ngx_string("proxy_ssl_crl"), | |
252 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, | |
253 ngx_conf_set_str_slot, | |
254 NGX_STREAM_SRV_CONF_OFFSET, | |
255 offsetof(ngx_stream_proxy_srv_conf_t, ssl_crl), | |
256 NULL }, | |
257 | |
258 { ngx_string("proxy_ssl_certificate"), | |
259 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, | |
260 ngx_conf_set_str_slot, | |
261 NGX_STREAM_SRV_CONF_OFFSET, | |
262 offsetof(ngx_stream_proxy_srv_conf_t, ssl_certificate), | |
263 NULL }, | |
264 | |
265 { ngx_string("proxy_ssl_certificate_key"), | |
266 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, | |
267 ngx_conf_set_str_slot, | |
268 NGX_STREAM_SRV_CONF_OFFSET, | |
269 offsetof(ngx_stream_proxy_srv_conf_t, ssl_certificate_key), | |
270 NULL }, | |
271 | |
272 { ngx_string("proxy_ssl_password_file"), | |
273 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, | |
274 ngx_stream_proxy_ssl_password_file, | |
275 NGX_STREAM_SRV_CONF_OFFSET, | |
276 0, | |
277 NULL }, | |
278 | |
279 #endif | |
280 | |
281 ngx_null_command | |
282 }; | |
283 | |
284 | |
285 static ngx_stream_module_t ngx_stream_proxy_module_ctx = { | |
6174
68c106e6fa0a
Stream: added postconfiguration method to stream modules.
Vladimir Homutov <vl@nginx.com>
parents:
6157
diff
changeset
|
286 NULL, /* postconfiguration */ |
68c106e6fa0a
Stream: added postconfiguration method to stream modules.
Vladimir Homutov <vl@nginx.com>
parents:
6157
diff
changeset
|
287 |
6115 | 288 NULL, /* create main configuration */ |
289 NULL, /* init main configuration */ | |
290 | |
291 ngx_stream_proxy_create_srv_conf, /* create server configuration */ | |
292 ngx_stream_proxy_merge_srv_conf /* merge server configuration */ | |
293 }; | |
294 | |
295 | |
296 ngx_module_t ngx_stream_proxy_module = { | |
297 NGX_MODULE_V1, | |
298 &ngx_stream_proxy_module_ctx, /* module context */ | |
299 ngx_stream_proxy_commands, /* module directives */ | |
300 NGX_STREAM_MODULE, /* module type */ | |
301 NULL, /* init master */ | |
302 NULL, /* init module */ | |
303 NULL, /* init process */ | |
304 NULL, /* init thread */ | |
305 NULL, /* exit thread */ | |
306 NULL, /* exit process */ | |
307 NULL, /* exit master */ | |
308 NGX_MODULE_V1_PADDING | |
309 }; | |
310 | |
311 | |
312 static void | |
313 ngx_stream_proxy_handler(ngx_stream_session_t *s) | |
314 { | |
315 u_char *p; | |
316 ngx_connection_t *c; | |
317 ngx_stream_upstream_t *u; | |
318 ngx_stream_proxy_srv_conf_t *pscf; | |
319 ngx_stream_upstream_srv_conf_t *uscf; | |
320 | |
321 c = s->connection; | |
322 | |
323 pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module); | |
324 | |
325 ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0, | |
326 "proxy connection handler"); | |
327 | |
328 u = ngx_pcalloc(c->pool, sizeof(ngx_stream_upstream_t)); | |
329 if (u == NULL) { | |
330 ngx_stream_proxy_finalize(s, NGX_ERROR); | |
331 return; | |
332 } | |
333 | |
334 s->upstream = u; | |
335 | |
336 s->log_handler = ngx_stream_proxy_log_error; | |
337 | |
338 u->peer.log = c->log; | |
339 u->peer.log_error = NGX_ERROR_ERR; | |
340 | |
6183
4dcffe43a7ea
Stream: the "proxy_bind" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
341 u->peer.local = pscf->local; |
4dcffe43a7ea
Stream: the "proxy_bind" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
342 |
6115 | 343 uscf = pscf->upstream; |
344 | |
345 if (uscf->peer.init(s, uscf) != NGX_OK) { | |
346 ngx_stream_proxy_finalize(s, NGX_ERROR); | |
347 return; | |
348 } | |
349 | |
350 u->peer.start_time = ngx_current_msec; | |
351 | |
352 if (pscf->next_upstream_tries | |
353 && u->peer.tries > pscf->next_upstream_tries) | |
354 { | |
355 u->peer.tries = pscf->next_upstream_tries; | |
356 } | |
357 | |
6184
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
358 u->proxy_protocol = pscf->proxy_protocol; |
6201
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
359 u->start_sec = ngx_time(); |
6184
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
360 |
6115 | 361 p = ngx_pnalloc(c->pool, pscf->downstream_buf_size); |
362 if (p == NULL) { | |
363 ngx_stream_proxy_finalize(s, NGX_ERROR); | |
364 return; | |
365 } | |
366 | |
367 u->downstream_buf.start = p; | |
368 u->downstream_buf.end = p + pscf->downstream_buf_size; | |
369 u->downstream_buf.pos = p; | |
370 u->downstream_buf.last = p; | |
371 | |
372 c->write->handler = ngx_stream_proxy_downstream_handler; | |
373 c->read->handler = ngx_stream_proxy_downstream_handler; | |
374 | |
6184
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
375 if (u->proxy_protocol |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
376 #if (NGX_STREAM_SSL) |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
377 && pscf->ssl == NULL |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
378 #endif |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
379 && pscf->downstream_buf_size >= NGX_PROXY_PROTOCOL_MAX_HEADER |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
380 ) |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
381 { |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
382 /* optimization for a typical case */ |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
383 |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
384 ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0, |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
385 "stream proxy send PROXY protocol header"); |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
386 |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
387 p = ngx_proxy_protocol_write(c, u->downstream_buf.last, |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
388 u->downstream_buf.end); |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
389 if (p == NULL) { |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
390 ngx_stream_proxy_finalize(s, NGX_ERROR); |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
391 return; |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
392 } |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
393 |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
394 u->downstream_buf.last = p; |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
395 u->proxy_protocol = 0; |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
396 } |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
397 |
6115 | 398 if (ngx_stream_proxy_process(s, 0, 0) != NGX_OK) { |
399 return; | |
400 } | |
401 | |
402 ngx_stream_proxy_connect(s); | |
403 } | |
404 | |
405 | |
406 static void | |
407 ngx_stream_proxy_connect(ngx_stream_session_t *s) | |
408 { | |
409 ngx_int_t rc; | |
410 ngx_connection_t *c, *pc; | |
411 ngx_stream_upstream_t *u; | |
412 ngx_stream_proxy_srv_conf_t *pscf; | |
413 | |
414 c = s->connection; | |
415 | |
416 c->log->action = "connecting to upstream"; | |
417 | |
418 u = s->upstream; | |
419 | |
420 rc = ngx_event_connect_peer(&u->peer); | |
421 | |
422 ngx_log_debug1(NGX_LOG_DEBUG_STREAM, c->log, 0, "proxy connect: %i", rc); | |
423 | |
424 pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module); | |
425 | |
426 if (rc == NGX_ERROR) { | |
427 ngx_stream_proxy_finalize(s, NGX_ERROR); | |
428 return; | |
429 } | |
430 | |
431 if (rc == NGX_BUSY) { | |
432 ngx_log_error(NGX_LOG_ERR, c->log, 0, "no live upstreams"); | |
433 ngx_stream_proxy_finalize(s, NGX_DECLINED); | |
434 return; | |
435 } | |
436 | |
437 if (rc == NGX_DECLINED) { | |
438 ngx_stream_proxy_next_upstream(s); | |
439 return; | |
440 } | |
441 | |
442 /* rc == NGX_OK || rc == NGX_AGAIN || rc == NGX_DONE */ | |
443 | |
444 pc = u->peer.connection; | |
445 | |
446 pc->data = s; | |
447 pc->log = c->log; | |
448 pc->pool = c->pool; | |
449 pc->read->log = c->log; | |
450 pc->write->log = c->log; | |
451 | |
452 if (rc != NGX_AGAIN) { | |
453 ngx_stream_proxy_init_upstream(s); | |
454 return; | |
455 } | |
456 | |
457 pc->read->handler = ngx_stream_proxy_connect_handler; | |
458 pc->write->handler = ngx_stream_proxy_connect_handler; | |
459 | |
460 ngx_add_timer(pc->write, pscf->connect_timeout); | |
461 } | |
462 | |
463 | |
464 static void | |
465 ngx_stream_proxy_init_upstream(ngx_stream_session_t *s) | |
466 { | |
467 u_char *p; | |
468 ngx_connection_t *c, *pc; | |
469 ngx_log_handler_pt handler; | |
470 ngx_stream_upstream_t *u; | |
471 ngx_stream_proxy_srv_conf_t *pscf; | |
472 | |
6184
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
473 u = s->upstream; |
6115 | 474 |
6184
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
475 if (u->proxy_protocol) { |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
476 if (ngx_stream_proxy_send_proxy_protocol(s) != NGX_OK) { |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
477 return; |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
478 } |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
479 |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
480 u->proxy_protocol = 0; |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
481 } |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
482 |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
483 pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module); |
6115 | 484 |
485 pc = u->peer.connection; | |
486 | |
487 #if (NGX_STREAM_SSL) | |
488 if (pscf->ssl && pc->ssl == NULL) { | |
489 ngx_stream_proxy_ssl_init_connection(s); | |
490 return; | |
491 } | |
492 #endif | |
493 | |
494 c = s->connection; | |
495 | |
496 if (c->log->log_level >= NGX_LOG_INFO) { | |
497 ngx_str_t s; | |
498 u_char addr[NGX_SOCKADDR_STRLEN]; | |
499 | |
500 s.len = NGX_SOCKADDR_STRLEN; | |
501 s.data = addr; | |
502 | |
503 if (ngx_connection_local_sockaddr(pc, &s, 1) == NGX_OK) { | |
504 handler = c->log->handler; | |
505 c->log->handler = NULL; | |
506 | |
507 ngx_log_error(NGX_LOG_INFO, c->log, 0, "proxy %V connected to %V", | |
508 &s, u->peer.name); | |
509 | |
510 c->log->handler = handler; | |
511 } | |
512 } | |
513 | |
514 c->log->action = "proxying connection"; | |
515 | |
516 p = ngx_pnalloc(c->pool, pscf->upstream_buf_size); | |
517 if (p == NULL) { | |
518 ngx_stream_proxy_finalize(s, NGX_ERROR); | |
519 return; | |
520 } | |
521 | |
522 u->upstream_buf.start = p; | |
523 u->upstream_buf.end = p + pscf->upstream_buf_size; | |
524 u->upstream_buf.pos = p; | |
525 u->upstream_buf.last = p; | |
526 | |
6202
6345822f0abb
Stream: upstream "connected" flag.
Roman Arutyunyan <arut@nginx.com>
parents:
6201
diff
changeset
|
527 u->connected = 1; |
6345822f0abb
Stream: upstream "connected" flag.
Roman Arutyunyan <arut@nginx.com>
parents:
6201
diff
changeset
|
528 |
6115 | 529 pc->read->handler = ngx_stream_proxy_upstream_handler; |
530 pc->write->handler = ngx_stream_proxy_upstream_handler; | |
531 | |
532 if (ngx_stream_proxy_process(s, 1, 0) != NGX_OK) { | |
533 return; | |
534 } | |
535 | |
536 ngx_stream_proxy_process(s, 0, 1); | |
537 } | |
538 | |
539 | |
6184
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
540 static ngx_int_t |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
541 ngx_stream_proxy_send_proxy_protocol(ngx_stream_session_t *s) |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
542 { |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
543 u_char *p; |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
544 ssize_t n, size; |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
545 ngx_connection_t *c, *pc; |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
546 ngx_stream_upstream_t *u; |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
547 ngx_stream_proxy_srv_conf_t *pscf; |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
548 u_char buf[NGX_PROXY_PROTOCOL_MAX_HEADER]; |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
549 |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
550 c = s->connection; |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
551 |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
552 ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0, |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
553 "stream proxy send PROXY protocol header"); |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
554 |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
555 p = ngx_proxy_protocol_write(c, buf, buf + NGX_PROXY_PROTOCOL_MAX_HEADER); |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
556 if (p == NULL) { |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
557 ngx_stream_proxy_finalize(s, NGX_ERROR); |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
558 return NGX_ERROR; |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
559 } |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
560 |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
561 u = s->upstream; |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
562 |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
563 pc = u->peer.connection; |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
564 |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
565 size = p - buf; |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
566 |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
567 n = pc->send(pc, buf, size); |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
568 |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
569 if (n == NGX_AGAIN) { |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
570 if (ngx_handle_write_event(pc->write, 0) != NGX_OK) { |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
571 ngx_stream_proxy_finalize(s, NGX_ERROR); |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
572 return NGX_ERROR; |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
573 } |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
574 |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
575 pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module); |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
576 |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
577 ngx_add_timer(pc->write, pscf->timeout); |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
578 |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
579 pc->write->handler = ngx_stream_proxy_connect_handler; |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
580 |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
581 return NGX_AGAIN; |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
582 } |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
583 |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
584 if (n == NGX_ERROR) { |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
585 ngx_stream_proxy_finalize(s, NGX_DECLINED); |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
586 return NGX_ERROR; |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
587 } |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
588 |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
589 if (n != size) { |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
590 |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
591 /* |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
592 * PROXY protocol specification: |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
593 * The sender must always ensure that the header |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
594 * is sent at once, so that the transport layer |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
595 * maintains atomicity along the path to the receiver. |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
596 */ |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
597 |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
598 ngx_log_error(NGX_LOG_ERR, c->log, 0, |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
599 "could not send PROXY protocol header at once"); |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
600 |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
601 ngx_stream_proxy_finalize(s, NGX_DECLINED); |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
602 |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
603 return NGX_ERROR; |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
604 } |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
605 |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
606 return NGX_OK; |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
607 } |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
608 |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
609 |
6115 | 610 #if (NGX_STREAM_SSL) |
611 | |
612 static char * | |
613 ngx_stream_proxy_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd, | |
614 void *conf) | |
615 { | |
616 ngx_stream_proxy_srv_conf_t *pscf = conf; | |
617 | |
618 ngx_str_t *value; | |
619 | |
620 if (pscf->ssl_passwords != NGX_CONF_UNSET_PTR) { | |
621 return "is duplicate"; | |
622 } | |
623 | |
624 value = cf->args->elts; | |
625 | |
626 pscf->ssl_passwords = ngx_ssl_read_password_file(cf, &value[1]); | |
627 | |
628 if (pscf->ssl_passwords == NULL) { | |
629 return NGX_CONF_ERROR; | |
630 } | |
631 | |
632 return NGX_CONF_OK; | |
633 } | |
634 | |
635 | |
636 static void | |
637 ngx_stream_proxy_ssl_init_connection(ngx_stream_session_t *s) | |
638 { | |
639 ngx_int_t rc; | |
640 ngx_connection_t *pc; | |
641 ngx_stream_upstream_t *u; | |
642 ngx_stream_proxy_srv_conf_t *pscf; | |
643 | |
644 u = s->upstream; | |
645 | |
646 pc = u->peer.connection; | |
647 | |
648 pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module); | |
649 | |
650 if (ngx_ssl_create_connection(pscf->ssl, pc, NGX_SSL_BUFFER|NGX_SSL_CLIENT) | |
651 != NGX_OK) | |
652 { | |
653 ngx_stream_proxy_finalize(s, NGX_ERROR); | |
654 return; | |
655 } | |
656 | |
657 if (pscf->ssl_server_name || pscf->ssl_verify) { | |
658 if (ngx_stream_proxy_ssl_name(s) != NGX_OK) { | |
659 ngx_stream_proxy_finalize(s, NGX_ERROR); | |
660 return; | |
661 } | |
662 } | |
663 | |
664 if (pscf->ssl_session_reuse) { | |
665 if (u->peer.set_session(&u->peer, u->peer.data) != NGX_OK) { | |
666 ngx_stream_proxy_finalize(s, NGX_ERROR); | |
667 return; | |
668 } | |
669 } | |
670 | |
671 s->connection->log->action = "SSL handshaking to upstream"; | |
672 | |
673 rc = ngx_ssl_handshake(pc); | |
674 | |
675 if (rc == NGX_AGAIN) { | |
676 | |
677 if (!pc->write->timer_set) { | |
678 ngx_add_timer(pc->write, pscf->connect_timeout); | |
679 } | |
680 | |
681 pc->ssl->handler = ngx_stream_proxy_ssl_handshake; | |
682 return; | |
683 } | |
684 | |
685 ngx_stream_proxy_ssl_handshake(pc); | |
686 } | |
687 | |
688 | |
689 static void | |
690 ngx_stream_proxy_ssl_handshake(ngx_connection_t *pc) | |
691 { | |
692 long rc; | |
693 ngx_stream_session_t *s; | |
694 ngx_stream_upstream_t *u; | |
695 ngx_stream_proxy_srv_conf_t *pscf; | |
696 | |
697 s = pc->data; | |
698 | |
699 pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module); | |
700 | |
701 if (pc->ssl->handshaked) { | |
702 | |
703 if (pscf->ssl_verify) { | |
704 rc = SSL_get_verify_result(pc->ssl->connection); | |
705 | |
706 if (rc != X509_V_OK) { | |
707 ngx_log_error(NGX_LOG_ERR, pc->log, 0, | |
708 "upstream SSL certificate verify error: (%l:%s)", | |
709 rc, X509_verify_cert_error_string(rc)); | |
710 goto failed; | |
711 } | |
712 | |
713 u = s->upstream; | |
714 | |
715 if (ngx_ssl_check_host(pc, &u->ssl_name) != NGX_OK) { | |
716 ngx_log_error(NGX_LOG_ERR, pc->log, 0, | |
717 "upstream SSL certificate does not match \"%V\"", | |
718 &u->ssl_name); | |
719 goto failed; | |
720 } | |
721 } | |
722 | |
723 if (pscf->ssl_session_reuse) { | |
724 u = s->upstream; | |
725 u->peer.save_session(&u->peer, u->peer.data); | |
726 } | |
727 | |
728 ngx_stream_proxy_init_upstream(s); | |
729 | |
730 return; | |
731 } | |
732 | |
733 failed: | |
734 | |
735 ngx_stream_proxy_next_upstream(s); | |
736 } | |
737 | |
738 | |
739 static ngx_int_t | |
740 ngx_stream_proxy_ssl_name(ngx_stream_session_t *s) | |
741 { | |
742 u_char *p, *last; | |
743 ngx_str_t name; | |
744 ngx_stream_upstream_t *u; | |
745 ngx_stream_proxy_srv_conf_t *pscf; | |
746 | |
747 pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module); | |
748 | |
749 u = s->upstream; | |
750 | |
751 name = pscf->ssl_name; | |
752 | |
753 if (name.len == 0) { | |
754 name = pscf->upstream->host; | |
755 } | |
756 | |
757 if (name.len == 0) { | |
758 goto done; | |
759 } | |
760 | |
761 /* | |
762 * ssl name here may contain port, strip it for compatibility | |
763 * with the http module | |
764 */ | |
765 | |
766 p = name.data; | |
767 last = name.data + name.len; | |
768 | |
769 if (*p == '[') { | |
770 p = ngx_strlchr(p, last, ']'); | |
771 | |
772 if (p == NULL) { | |
773 p = name.data; | |
774 } | |
775 } | |
776 | |
777 p = ngx_strlchr(p, last, ':'); | |
778 | |
779 if (p != NULL) { | |
780 name.len = p - name.data; | |
781 } | |
782 | |
783 if (!pscf->ssl_server_name) { | |
784 goto done; | |
785 } | |
786 | |
787 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME | |
788 | |
789 /* as per RFC 6066, literal IPv4 and IPv6 addresses are not permitted */ | |
790 | |
791 if (name.len == 0 || *name.data == '[') { | |
792 goto done; | |
793 } | |
794 | |
795 if (ngx_inet_addr(name.data, name.len) != INADDR_NONE) { | |
796 goto done; | |
797 } | |
798 | |
799 /* | |
800 * SSL_set_tlsext_host_name() needs a null-terminated string, | |
801 * hence we explicitly null-terminate name here | |
802 */ | |
803 | |
804 p = ngx_pnalloc(s->connection->pool, name.len + 1); | |
805 if (p == NULL) { | |
806 return NGX_ERROR; | |
807 } | |
808 | |
809 (void) ngx_cpystrn(p, name.data, name.len + 1); | |
810 | |
811 name.data = p; | |
812 | |
813 ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0, | |
814 "upstream SSL server name: \"%s\"", name.data); | |
815 | |
816 if (SSL_set_tlsext_host_name(u->peer.connection->ssl->connection, name.data) | |
817 == 0) | |
818 { | |
819 ngx_ssl_error(NGX_LOG_ERR, s->connection->log, 0, | |
820 "SSL_set_tlsext_host_name(\"%s\") failed", name.data); | |
821 return NGX_ERROR; | |
822 } | |
823 | |
824 #endif | |
825 | |
826 done: | |
827 | |
828 u->ssl_name = name; | |
829 | |
830 return NGX_OK; | |
831 } | |
832 | |
833 #endif | |
834 | |
835 | |
836 static void | |
837 ngx_stream_proxy_downstream_handler(ngx_event_t *ev) | |
838 { | |
6200
abee77018d3a
Stream: common handler for upstream and downstream.
Roman Arutyunyan <arut@nginx.com>
parents:
6184
diff
changeset
|
839 ngx_stream_proxy_process_connection(ev, ev->write); |
abee77018d3a
Stream: common handler for upstream and downstream.
Roman Arutyunyan <arut@nginx.com>
parents:
6184
diff
changeset
|
840 } |
abee77018d3a
Stream: common handler for upstream and downstream.
Roman Arutyunyan <arut@nginx.com>
parents:
6184
diff
changeset
|
841 |
abee77018d3a
Stream: common handler for upstream and downstream.
Roman Arutyunyan <arut@nginx.com>
parents:
6184
diff
changeset
|
842 |
abee77018d3a
Stream: common handler for upstream and downstream.
Roman Arutyunyan <arut@nginx.com>
parents:
6184
diff
changeset
|
843 static void |
abee77018d3a
Stream: common handler for upstream and downstream.
Roman Arutyunyan <arut@nginx.com>
parents:
6184
diff
changeset
|
844 ngx_stream_proxy_upstream_handler(ngx_event_t *ev) |
abee77018d3a
Stream: common handler for upstream and downstream.
Roman Arutyunyan <arut@nginx.com>
parents:
6184
diff
changeset
|
845 { |
abee77018d3a
Stream: common handler for upstream and downstream.
Roman Arutyunyan <arut@nginx.com>
parents:
6184
diff
changeset
|
846 ngx_stream_proxy_process_connection(ev, !ev->write); |
abee77018d3a
Stream: common handler for upstream and downstream.
Roman Arutyunyan <arut@nginx.com>
parents:
6184
diff
changeset
|
847 } |
abee77018d3a
Stream: common handler for upstream and downstream.
Roman Arutyunyan <arut@nginx.com>
parents:
6184
diff
changeset
|
848 |
abee77018d3a
Stream: common handler for upstream and downstream.
Roman Arutyunyan <arut@nginx.com>
parents:
6184
diff
changeset
|
849 |
abee77018d3a
Stream: common handler for upstream and downstream.
Roman Arutyunyan <arut@nginx.com>
parents:
6184
diff
changeset
|
850 static void |
abee77018d3a
Stream: common handler for upstream and downstream.
Roman Arutyunyan <arut@nginx.com>
parents:
6184
diff
changeset
|
851 ngx_stream_proxy_process_connection(ngx_event_t *ev, ngx_uint_t from_upstream) |
abee77018d3a
Stream: common handler for upstream and downstream.
Roman Arutyunyan <arut@nginx.com>
parents:
6184
diff
changeset
|
852 { |
6201
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
853 ngx_connection_t *c, *pc; |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
854 ngx_stream_session_t *s; |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
855 ngx_stream_upstream_t *u; |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
856 ngx_stream_proxy_srv_conf_t *pscf; |
6115 | 857 |
858 c = ev->data; | |
859 s = c->data; | |
6200
abee77018d3a
Stream: common handler for upstream and downstream.
Roman Arutyunyan <arut@nginx.com>
parents:
6184
diff
changeset
|
860 u = s->upstream; |
6115 | 861 |
862 if (ev->timedout) { | |
6201
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
863 |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
864 if (ev->delayed) { |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
865 |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
866 ev->timedout = 0; |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
867 ev->delayed = 0; |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
868 |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
869 if (!ev->ready) { |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
870 if (ngx_handle_read_event(ev, 0) != NGX_OK) { |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
871 ngx_stream_proxy_finalize(s, NGX_ERROR); |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
872 return; |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
873 } |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
874 |
6202
6345822f0abb
Stream: upstream "connected" flag.
Roman Arutyunyan <arut@nginx.com>
parents:
6201
diff
changeset
|
875 if (u->connected) { |
6201
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
876 pc = u->peer.connection; |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
877 |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
878 if (!c->read->delayed && !pc->read->delayed) { |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
879 pscf = ngx_stream_get_module_srv_conf(s, |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
880 ngx_stream_proxy_module); |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
881 ngx_add_timer(c->write, pscf->timeout); |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
882 } |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
883 } |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
884 |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
885 return; |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
886 } |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
887 |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
888 } else { |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
889 ngx_connection_error(c, NGX_ETIMEDOUT, "connection timed out"); |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
890 ngx_stream_proxy_finalize(s, NGX_DECLINED); |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
891 return; |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
892 } |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
893 |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
894 } else if (ev->delayed) { |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
895 |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
896 ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0, |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
897 "stream connection delayed"); |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
898 |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
899 if (ngx_handle_read_event(ev, 0) != NGX_OK) { |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
900 ngx_stream_proxy_finalize(s, NGX_ERROR); |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
901 } |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
902 |
6115 | 903 return; |
904 } | |
905 | |
6202
6345822f0abb
Stream: upstream "connected" flag.
Roman Arutyunyan <arut@nginx.com>
parents:
6201
diff
changeset
|
906 if (from_upstream && !u->connected) { |
6200
abee77018d3a
Stream: common handler for upstream and downstream.
Roman Arutyunyan <arut@nginx.com>
parents:
6184
diff
changeset
|
907 return; |
6115 | 908 } |
909 | |
6200
abee77018d3a
Stream: common handler for upstream and downstream.
Roman Arutyunyan <arut@nginx.com>
parents:
6184
diff
changeset
|
910 ngx_stream_proxy_process(s, from_upstream, ev->write); |
6115 | 911 } |
912 | |
913 | |
914 static void | |
915 ngx_stream_proxy_connect_handler(ngx_event_t *ev) | |
916 { | |
917 ngx_connection_t *c; | |
918 ngx_stream_session_t *s; | |
919 | |
920 c = ev->data; | |
921 s = c->data; | |
922 | |
923 if (ev->timedout) { | |
924 ngx_log_error(NGX_LOG_ERR, c->log, NGX_ETIMEDOUT, "upstream timed out"); | |
925 ngx_stream_proxy_next_upstream(s); | |
926 return; | |
927 } | |
928 | |
929 ngx_del_timer(c->write); | |
930 | |
931 ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0, | |
932 "stream proxy connect upstream"); | |
933 | |
934 if (ngx_stream_proxy_test_connect(c) != NGX_OK) { | |
935 ngx_stream_proxy_next_upstream(s); | |
936 return; | |
937 } | |
938 | |
939 ngx_stream_proxy_init_upstream(s); | |
940 } | |
941 | |
942 | |
943 static ngx_int_t | |
944 ngx_stream_proxy_test_connect(ngx_connection_t *c) | |
945 { | |
946 int err; | |
947 socklen_t len; | |
948 | |
949 #if (NGX_HAVE_KQUEUE) | |
950 | |
951 if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) { | |
952 err = c->write->kq_errno ? c->write->kq_errno : c->read->kq_errno; | |
953 | |
954 if (err) { | |
955 (void) ngx_connection_error(c, err, | |
956 "kevent() reported that connect() failed"); | |
957 return NGX_ERROR; | |
958 } | |
959 | |
960 } else | |
961 #endif | |
962 { | |
963 err = 0; | |
964 len = sizeof(int); | |
965 | |
966 /* | |
967 * BSDs and Linux return 0 and set a pending error in err | |
968 * Solaris returns -1 and sets errno | |
969 */ | |
970 | |
971 if (getsockopt(c->fd, SOL_SOCKET, SO_ERROR, (void *) &err, &len) | |
972 == -1) | |
973 { | |
974 err = ngx_socket_errno; | |
975 } | |
976 | |
977 if (err) { | |
978 (void) ngx_connection_error(c, err, "connect() failed"); | |
979 return NGX_ERROR; | |
980 } | |
981 } | |
982 | |
983 return NGX_OK; | |
984 } | |
985 | |
986 | |
987 static ngx_int_t | |
988 ngx_stream_proxy_process(ngx_stream_session_t *s, ngx_uint_t from_upstream, | |
989 ngx_uint_t do_write) | |
990 { | |
6201
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
991 off_t *received, limit; |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
992 size_t size, limit_rate; |
6115 | 993 ssize_t n; |
994 ngx_buf_t *b; | |
6124
f1f222db290b
Stream: prevent repeated event notifications after eof.
Roman Arutyunyan <arut@nginx.com>
parents:
6115
diff
changeset
|
995 ngx_uint_t flags; |
6201
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
996 ngx_msec_t delay; |
6115 | 997 ngx_connection_t *c, *pc, *src, *dst; |
998 ngx_log_handler_pt handler; | |
999 ngx_stream_upstream_t *u; | |
1000 ngx_stream_proxy_srv_conf_t *pscf; | |
1001 | |
1002 u = s->upstream; | |
1003 | |
1004 c = s->connection; | |
6202
6345822f0abb
Stream: upstream "connected" flag.
Roman Arutyunyan <arut@nginx.com>
parents:
6201
diff
changeset
|
1005 pc = u->connected ? u->peer.connection : NULL; |
6115 | 1006 |
6201
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
1007 pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module); |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
1008 |
6115 | 1009 if (from_upstream) { |
1010 src = pc; | |
1011 dst = c; | |
1012 b = &u->upstream_buf; | |
6201
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
1013 limit_rate = pscf->upstream_limit_rate; |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
1014 received = &u->received; |
6115 | 1015 |
1016 } else { | |
1017 src = c; | |
1018 dst = pc; | |
1019 b = &u->downstream_buf; | |
6201
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
1020 limit_rate = pscf->downstream_limit_rate; |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
1021 received = &s->received; |
6115 | 1022 } |
1023 | |
1024 for ( ;; ) { | |
1025 | |
1026 if (do_write) { | |
1027 | |
1028 size = b->last - b->pos; | |
1029 | |
1030 if (size && dst && dst->write->ready) { | |
1031 | |
1032 n = dst->send(dst, b->pos, size); | |
1033 | |
1034 if (n == NGX_ERROR) { | |
1035 ngx_stream_proxy_finalize(s, NGX_DECLINED); | |
1036 return NGX_ERROR; | |
1037 } | |
1038 | |
1039 if (n > 0) { | |
1040 b->pos += n; | |
1041 | |
1042 if (b->pos == b->last) { | |
1043 b->pos = b->start; | |
1044 b->last = b->start; | |
1045 } | |
1046 } | |
1047 } | |
1048 } | |
1049 | |
1050 size = b->end - b->last; | |
1051 | |
6201
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
1052 if (size && src->read->ready && !src->read->delayed) { |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
1053 |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
1054 if (limit_rate) { |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
1055 limit = (off_t) limit_rate * (ngx_time() - u->start_sec + 1) |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
1056 - *received; |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
1057 |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
1058 if (limit <= 0) { |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
1059 src->read->delayed = 1; |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
1060 delay = (ngx_msec_t) (- limit * 1000 / limit_rate + 1); |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
1061 ngx_add_timer(src->read, delay); |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
1062 break; |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
1063 } |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
1064 |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
1065 if (size > (size_t) limit) { |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
1066 size = limit; |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
1067 } |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
1068 } |
6115 | 1069 |
1070 n = src->recv(src, b->last, size); | |
1071 | |
1072 if (n == NGX_AGAIN || n == 0) { | |
1073 break; | |
1074 } | |
1075 | |
1076 if (n > 0) { | |
6201
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
1077 if (limit_rate) { |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
1078 delay = (ngx_msec_t) (n * 1000 / limit_rate); |
6115 | 1079 |
6201
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
1080 if (delay > 0) { |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
1081 src->read->delayed = 1; |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
1082 ngx_add_timer(src->read, delay); |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
1083 } |
6115 | 1084 } |
1085 | |
6201
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
1086 *received += n; |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
1087 b->last += n; |
6115 | 1088 do_write = 1; |
6201
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
1089 |
6115 | 1090 continue; |
1091 } | |
1092 | |
1093 if (n == NGX_ERROR) { | |
1094 src->read->eof = 1; | |
1095 } | |
1096 } | |
1097 | |
1098 break; | |
1099 } | |
1100 | |
1101 if (src->read->eof && (b->pos == b->last || (dst && dst->read->eof))) { | |
1102 handler = c->log->handler; | |
1103 c->log->handler = NULL; | |
1104 | |
1105 ngx_log_error(NGX_LOG_INFO, c->log, 0, | |
1106 "%s disconnected" | |
1107 ", bytes from/to client:%O/%O" | |
1108 ", bytes from/to upstream:%O/%O", | |
1109 from_upstream ? "upstream" : "client", | |
1110 s->received, c->sent, u->received, pc ? pc->sent : 0); | |
1111 | |
1112 c->log->handler = handler; | |
1113 | |
1114 ngx_stream_proxy_finalize(s, NGX_OK); | |
1115 return NGX_DONE; | |
1116 } | |
1117 | |
6124
f1f222db290b
Stream: prevent repeated event notifications after eof.
Roman Arutyunyan <arut@nginx.com>
parents:
6115
diff
changeset
|
1118 flags = src->read->eof ? NGX_CLOSE_EVENT : 0; |
f1f222db290b
Stream: prevent repeated event notifications after eof.
Roman Arutyunyan <arut@nginx.com>
parents:
6115
diff
changeset
|
1119 |
f1f222db290b
Stream: prevent repeated event notifications after eof.
Roman Arutyunyan <arut@nginx.com>
parents:
6115
diff
changeset
|
1120 if (ngx_handle_read_event(src->read, flags) != NGX_OK) { |
6115 | 1121 ngx_stream_proxy_finalize(s, NGX_ERROR); |
1122 return NGX_ERROR; | |
1123 } | |
1124 | |
1125 if (dst) { | |
1126 if (ngx_handle_write_event(dst->write, 0) != NGX_OK) { | |
1127 ngx_stream_proxy_finalize(s, NGX_ERROR); | |
1128 return NGX_ERROR; | |
1129 } | |
1130 | |
6201
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
1131 if (!c->read->delayed && !pc->read->delayed) { |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
1132 ngx_add_timer(c->write, pscf->timeout); |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
1133 |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
1134 } else if (c->write->timer_set) { |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
1135 ngx_del_timer(c->write); |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
1136 } |
6115 | 1137 } |
1138 | |
1139 return NGX_OK; | |
1140 } | |
1141 | |
1142 | |
1143 static void | |
1144 ngx_stream_proxy_next_upstream(ngx_stream_session_t *s) | |
1145 { | |
1146 ngx_msec_t timeout; | |
1147 ngx_connection_t *pc; | |
1148 ngx_stream_upstream_t *u; | |
1149 ngx_stream_proxy_srv_conf_t *pscf; | |
1150 | |
1151 ngx_log_debug0(NGX_LOG_DEBUG_STREAM, s->connection->log, 0, | |
1152 "stream proxy next upstream"); | |
1153 | |
1154 u = s->upstream; | |
1155 | |
1156 if (u->peer.sockaddr) { | |
1157 u->peer.free(&u->peer, u->peer.data, NGX_PEER_FAILED); | |
1158 u->peer.sockaddr = NULL; | |
1159 } | |
1160 | |
1161 pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module); | |
1162 | |
1163 timeout = pscf->next_upstream_timeout; | |
1164 | |
1165 if (u->peer.tries == 0 | |
1166 || !pscf->next_upstream | |
1167 || (timeout && ngx_current_msec - u->peer.start_time >= timeout)) | |
1168 { | |
1169 ngx_stream_proxy_finalize(s, NGX_DECLINED); | |
1170 return; | |
1171 } | |
1172 | |
1173 pc = u->peer.connection; | |
1174 | |
1175 if (pc) { | |
1176 ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0, | |
1177 "close proxy upstream connection: %d", pc->fd); | |
1178 | |
1179 #if (NGX_STREAM_SSL) | |
1180 if (pc->ssl) { | |
1181 pc->ssl->no_wait_shutdown = 1; | |
1182 pc->ssl->no_send_shutdown = 1; | |
1183 | |
1184 (void) ngx_ssl_shutdown(pc); | |
1185 } | |
1186 #endif | |
1187 | |
1188 ngx_close_connection(pc); | |
1189 u->peer.connection = NULL; | |
1190 } | |
1191 | |
1192 ngx_stream_proxy_connect(s); | |
1193 } | |
1194 | |
1195 | |
1196 static void | |
1197 ngx_stream_proxy_finalize(ngx_stream_session_t *s, ngx_int_t rc) | |
1198 { | |
1199 ngx_connection_t *pc; | |
1200 ngx_stream_upstream_t *u; | |
1201 | |
1202 ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0, | |
1203 "finalize stream proxy: %i", rc); | |
1204 | |
1205 u = s->upstream; | |
1206 | |
1207 if (u == NULL) { | |
1208 goto noupstream; | |
1209 } | |
1210 | |
1211 if (u->peer.free && u->peer.sockaddr) { | |
1212 u->peer.free(&u->peer, u->peer.data, 0); | |
1213 u->peer.sockaddr = NULL; | |
1214 } | |
1215 | |
1216 pc = u->peer.connection; | |
1217 | |
1218 if (pc) { | |
1219 ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0, | |
1220 "close stream proxy upstream connection: %d", pc->fd); | |
1221 | |
1222 #if (NGX_STREAM_SSL) | |
1223 if (pc->ssl) { | |
1224 pc->ssl->no_wait_shutdown = 1; | |
1225 (void) ngx_ssl_shutdown(pc); | |
1226 } | |
1227 #endif | |
1228 | |
1229 ngx_close_connection(pc); | |
1230 u->peer.connection = NULL; | |
1231 } | |
1232 | |
1233 noupstream: | |
1234 | |
1235 ngx_stream_close_connection(s->connection); | |
1236 } | |
1237 | |
1238 | |
1239 static u_char * | |
1240 ngx_stream_proxy_log_error(ngx_log_t *log, u_char *buf, size_t len) | |
1241 { | |
1242 u_char *p; | |
1243 ngx_connection_t *pc; | |
1244 ngx_stream_session_t *s; | |
1245 ngx_stream_upstream_t *u; | |
1246 | |
1247 s = log->data; | |
1248 | |
1249 u = s->upstream; | |
1250 | |
1251 p = buf; | |
1252 | |
1253 if (u->peer.name) { | |
1254 p = ngx_snprintf(p, len, ", upstream: \"%V\"", u->peer.name); | |
1255 len -= p - buf; | |
1256 } | |
1257 | |
1258 pc = u->peer.connection; | |
1259 | |
1260 p = ngx_snprintf(p, len, | |
1261 ", bytes from/to client:%O/%O" | |
1262 ", bytes from/to upstream:%O/%O", | |
1263 s->received, s->connection->sent, | |
1264 u->received, pc ? pc->sent : 0); | |
1265 | |
1266 return p; | |
1267 } | |
1268 | |
1269 | |
1270 static void * | |
1271 ngx_stream_proxy_create_srv_conf(ngx_conf_t *cf) | |
1272 { | |
1273 ngx_stream_proxy_srv_conf_t *conf; | |
1274 | |
1275 conf = ngx_pcalloc(cf->pool, sizeof(ngx_stream_proxy_srv_conf_t)); | |
1276 if (conf == NULL) { | |
1277 return NULL; | |
1278 } | |
1279 | |
1280 /* | |
1281 * set by ngx_pcalloc(): | |
1282 * | |
1283 * conf->ssl_protocols = 0; | |
1284 * conf->ssl_ciphers = { 0, NULL }; | |
1285 * conf->ssl_name = { 0, NULL }; | |
1286 * conf->ssl_trusted_certificate = { 0, NULL }; | |
1287 * conf->ssl_crl = { 0, NULL }; | |
1288 * conf->ssl_certificate = { 0, NULL }; | |
1289 * conf->ssl_certificate_key = { 0, NULL }; | |
1290 * | |
1291 * conf->ssl = NULL; | |
1292 * conf->upstream = NULL; | |
1293 */ | |
1294 | |
1295 conf->connect_timeout = NGX_CONF_UNSET_MSEC; | |
1296 conf->timeout = NGX_CONF_UNSET_MSEC; | |
1297 conf->next_upstream_timeout = NGX_CONF_UNSET_MSEC; | |
1298 conf->downstream_buf_size = NGX_CONF_UNSET_SIZE; | |
6201
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
1299 conf->downstream_limit_rate = NGX_CONF_UNSET_SIZE; |
6115 | 1300 conf->upstream_buf_size = NGX_CONF_UNSET_SIZE; |
6201
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
1301 conf->upstream_limit_rate = NGX_CONF_UNSET_SIZE; |
6115 | 1302 conf->next_upstream_tries = NGX_CONF_UNSET_UINT; |
1303 conf->next_upstream = NGX_CONF_UNSET; | |
6184
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
1304 conf->proxy_protocol = NGX_CONF_UNSET; |
6183
4dcffe43a7ea
Stream: the "proxy_bind" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
1305 conf->local = NGX_CONF_UNSET_PTR; |
6115 | 1306 |
1307 #if (NGX_STREAM_SSL) | |
1308 conf->ssl_enable = NGX_CONF_UNSET; | |
1309 conf->ssl_session_reuse = NGX_CONF_UNSET; | |
1310 conf->ssl_server_name = NGX_CONF_UNSET; | |
1311 conf->ssl_verify = NGX_CONF_UNSET; | |
1312 conf->ssl_verify_depth = NGX_CONF_UNSET_UINT; | |
1313 conf->ssl_passwords = NGX_CONF_UNSET_PTR; | |
1314 #endif | |
1315 | |
1316 return conf; | |
1317 } | |
1318 | |
1319 | |
1320 static char * | |
1321 ngx_stream_proxy_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) | |
1322 { | |
1323 ngx_stream_proxy_srv_conf_t *prev = parent; | |
1324 ngx_stream_proxy_srv_conf_t *conf = child; | |
1325 | |
1326 ngx_conf_merge_msec_value(conf->connect_timeout, | |
1327 prev->connect_timeout, 60000); | |
1328 | |
1329 ngx_conf_merge_msec_value(conf->timeout, | |
1330 prev->timeout, 10 * 60000); | |
1331 | |
1332 ngx_conf_merge_msec_value(conf->next_upstream_timeout, | |
1333 prev->next_upstream_timeout, 0); | |
1334 | |
1335 ngx_conf_merge_size_value(conf->downstream_buf_size, | |
1336 prev->downstream_buf_size, 16384); | |
1337 | |
6201
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
1338 ngx_conf_merge_size_value(conf->downstream_limit_rate, |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
1339 prev->downstream_limit_rate, 0); |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
1340 |
6115 | 1341 ngx_conf_merge_size_value(conf->upstream_buf_size, |
1342 prev->upstream_buf_size, 16384); | |
1343 | |
6201
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
1344 ngx_conf_merge_size_value(conf->upstream_limit_rate, |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
1345 prev->upstream_limit_rate, 0); |
24488e6db782
Stream: upstream and downstream limit rates.
Roman Arutyunyan <arut@nginx.com>
parents:
6200
diff
changeset
|
1346 |
6115 | 1347 ngx_conf_merge_uint_value(conf->next_upstream_tries, |
1348 prev->next_upstream_tries, 0); | |
1349 | |
1350 ngx_conf_merge_value(conf->next_upstream, prev->next_upstream, 1); | |
1351 | |
6184
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
1352 ngx_conf_merge_value(conf->proxy_protocol, prev->proxy_protocol, 0); |
fa663739e115
Stream: client-side PROXY protocol.
Roman Arutyunyan <arut@nginx.com>
parents:
6183
diff
changeset
|
1353 |
6183
4dcffe43a7ea
Stream: the "proxy_bind" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
1354 ngx_conf_merge_ptr_value(conf->local, prev->local, NULL); |
4dcffe43a7ea
Stream: the "proxy_bind" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
1355 |
6115 | 1356 #if (NGX_STREAM_SSL) |
1357 | |
1358 ngx_conf_merge_value(conf->ssl_enable, prev->ssl_enable, 0); | |
1359 | |
1360 ngx_conf_merge_value(conf->ssl_session_reuse, | |
1361 prev->ssl_session_reuse, 1); | |
1362 | |
1363 ngx_conf_merge_bitmask_value(conf->ssl_protocols, prev->ssl_protocols, | |
6157
b2899e7d0ef8
Disabled SSLv3 by default (ticket #653).
Maxim Dounin <mdounin@mdounin.ru>
parents:
6124
diff
changeset
|
1364 (NGX_CONF_BITMASK_SET|NGX_SSL_TLSv1 |
b2899e7d0ef8
Disabled SSLv3 by default (ticket #653).
Maxim Dounin <mdounin@mdounin.ru>
parents:
6124
diff
changeset
|
1365 |NGX_SSL_TLSv1_1|NGX_SSL_TLSv1_2)); |
6115 | 1366 |
1367 ngx_conf_merge_str_value(conf->ssl_ciphers, prev->ssl_ciphers, "DEFAULT"); | |
1368 | |
1369 ngx_conf_merge_str_value(conf->ssl_name, prev->ssl_name, ""); | |
1370 | |
1371 ngx_conf_merge_value(conf->ssl_server_name, prev->ssl_server_name, 0); | |
1372 | |
1373 ngx_conf_merge_value(conf->ssl_verify, prev->ssl_verify, 0); | |
1374 | |
1375 ngx_conf_merge_uint_value(conf->ssl_verify_depth, | |
1376 prev->ssl_verify_depth, 1); | |
1377 | |
1378 ngx_conf_merge_str_value(conf->ssl_trusted_certificate, | |
1379 prev->ssl_trusted_certificate, ""); | |
1380 | |
1381 ngx_conf_merge_str_value(conf->ssl_crl, prev->ssl_crl, ""); | |
1382 | |
1383 ngx_conf_merge_str_value(conf->ssl_certificate, | |
1384 prev->ssl_certificate, ""); | |
1385 | |
1386 ngx_conf_merge_str_value(conf->ssl_certificate_key, | |
1387 prev->ssl_certificate_key, ""); | |
1388 | |
1389 ngx_conf_merge_ptr_value(conf->ssl_passwords, prev->ssl_passwords, NULL); | |
1390 | |
1391 if (conf->ssl_enable && ngx_stream_proxy_set_ssl(cf, conf) != NGX_OK) { | |
1392 return NGX_CONF_ERROR; | |
1393 } | |
1394 | |
1395 #endif | |
1396 | |
1397 return NGX_CONF_OK; | |
1398 } | |
1399 | |
1400 | |
1401 #if (NGX_STREAM_SSL) | |
1402 | |
1403 static ngx_int_t | |
1404 ngx_stream_proxy_set_ssl(ngx_conf_t *cf, ngx_stream_proxy_srv_conf_t *pscf) | |
1405 { | |
1406 ngx_pool_cleanup_t *cln; | |
1407 | |
1408 pscf->ssl = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_t)); | |
1409 if (pscf->ssl == NULL) { | |
1410 return NGX_ERROR; | |
1411 } | |
1412 | |
1413 pscf->ssl->log = cf->log; | |
1414 | |
1415 if (ngx_ssl_create(pscf->ssl, pscf->ssl_protocols, NULL) != NGX_OK) { | |
1416 return NGX_ERROR; | |
1417 } | |
1418 | |
1419 cln = ngx_pool_cleanup_add(cf->pool, 0); | |
1420 if (cln == NULL) { | |
1421 return NGX_ERROR; | |
1422 } | |
1423 | |
1424 cln->handler = ngx_ssl_cleanup_ctx; | |
1425 cln->data = pscf->ssl; | |
1426 | |
1427 if (pscf->ssl_certificate.len) { | |
1428 | |
1429 if (pscf->ssl_certificate_key.len == 0) { | |
1430 ngx_log_error(NGX_LOG_EMERG, cf->log, 0, | |
1431 "no \"proxy_ssl_certificate_key\" is defined " | |
1432 "for certificate \"%V\"", &pscf->ssl_certificate); | |
1433 return NGX_ERROR; | |
1434 } | |
1435 | |
1436 if (ngx_ssl_certificate(cf, pscf->ssl, &pscf->ssl_certificate, | |
1437 &pscf->ssl_certificate_key, pscf->ssl_passwords) | |
1438 != NGX_OK) | |
1439 { | |
1440 return NGX_ERROR; | |
1441 } | |
1442 } | |
1443 | |
1444 if (SSL_CTX_set_cipher_list(pscf->ssl->ctx, | |
1445 (const char *) pscf->ssl_ciphers.data) | |
1446 == 0) | |
1447 { | |
1448 ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0, | |
1449 "SSL_CTX_set_cipher_list(\"%V\") failed", | |
1450 &pscf->ssl_ciphers); | |
1451 return NGX_ERROR; | |
1452 } | |
1453 | |
1454 if (pscf->ssl_verify) { | |
1455 if (pscf->ssl_trusted_certificate.len == 0) { | |
1456 ngx_log_error(NGX_LOG_EMERG, cf->log, 0, | |
1457 "no proxy_ssl_trusted_certificate for proxy_ssl_verify"); | |
1458 return NGX_ERROR; | |
1459 } | |
1460 | |
1461 if (ngx_ssl_trusted_certificate(cf, pscf->ssl, | |
1462 &pscf->ssl_trusted_certificate, | |
1463 pscf->ssl_verify_depth) | |
1464 != NGX_OK) | |
1465 { | |
1466 return NGX_ERROR; | |
1467 } | |
1468 | |
1469 if (ngx_ssl_crl(cf, pscf->ssl, &pscf->ssl_crl) != NGX_OK) { | |
1470 return NGX_ERROR; | |
1471 } | |
1472 } | |
1473 | |
1474 return NGX_OK; | |
1475 } | |
1476 | |
1477 #endif | |
1478 | |
1479 | |
1480 static char * | |
1481 ngx_stream_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
1482 { | |
1483 ngx_stream_proxy_srv_conf_t *pscf = conf; | |
1484 | |
1485 ngx_url_t u; | |
1486 ngx_str_t *value, *url; | |
1487 ngx_stream_core_srv_conf_t *cscf; | |
1488 | |
1489 if (pscf->upstream) { | |
1490 return "is duplicate"; | |
1491 } | |
1492 | |
1493 cscf = ngx_stream_conf_get_module_srv_conf(cf, ngx_stream_core_module); | |
1494 | |
1495 cscf->handler = ngx_stream_proxy_handler; | |
1496 | |
1497 value = cf->args->elts; | |
1498 | |
1499 url = &value[1]; | |
1500 | |
1501 ngx_memzero(&u, sizeof(ngx_url_t)); | |
1502 | |
1503 u.url = *url; | |
1504 u.no_resolve = 1; | |
1505 | |
1506 pscf->upstream = ngx_stream_upstream_add(cf, &u, 0); | |
1507 if (pscf->upstream == NULL) { | |
1508 return NGX_CONF_ERROR; | |
1509 } | |
1510 | |
1511 return NGX_CONF_OK; | |
1512 } | |
6183
4dcffe43a7ea
Stream: the "proxy_bind" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
1513 |
4dcffe43a7ea
Stream: the "proxy_bind" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
1514 |
4dcffe43a7ea
Stream: the "proxy_bind" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
1515 static char * |
4dcffe43a7ea
Stream: the "proxy_bind" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
1516 ngx_stream_proxy_bind(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
4dcffe43a7ea
Stream: the "proxy_bind" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
1517 { |
4dcffe43a7ea
Stream: the "proxy_bind" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
1518 ngx_stream_proxy_srv_conf_t *pscf = conf; |
4dcffe43a7ea
Stream: the "proxy_bind" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
1519 |
4dcffe43a7ea
Stream: the "proxy_bind" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
1520 ngx_int_t rc; |
4dcffe43a7ea
Stream: the "proxy_bind" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
1521 ngx_str_t *value; |
4dcffe43a7ea
Stream: the "proxy_bind" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
1522 |
4dcffe43a7ea
Stream: the "proxy_bind" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
1523 if (pscf->local != NGX_CONF_UNSET_PTR) { |
4dcffe43a7ea
Stream: the "proxy_bind" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
1524 return "is duplicate"; |
4dcffe43a7ea
Stream: the "proxy_bind" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
1525 } |
4dcffe43a7ea
Stream: the "proxy_bind" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
1526 |
4dcffe43a7ea
Stream: the "proxy_bind" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
1527 value = cf->args->elts; |
4dcffe43a7ea
Stream: the "proxy_bind" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
1528 |
4dcffe43a7ea
Stream: the "proxy_bind" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
1529 if (ngx_strcmp(value[1].data, "off") == 0) { |
4dcffe43a7ea
Stream: the "proxy_bind" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
1530 pscf->local = NULL; |
4dcffe43a7ea
Stream: the "proxy_bind" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
1531 return NGX_CONF_OK; |
4dcffe43a7ea
Stream: the "proxy_bind" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
1532 } |
4dcffe43a7ea
Stream: the "proxy_bind" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
1533 |
4dcffe43a7ea
Stream: the "proxy_bind" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
1534 pscf->local = ngx_palloc(cf->pool, sizeof(ngx_addr_t)); |
4dcffe43a7ea
Stream: the "proxy_bind" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
1535 if (pscf->local == NULL) { |
4dcffe43a7ea
Stream: the "proxy_bind" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
1536 return NGX_CONF_ERROR; |
4dcffe43a7ea
Stream: the "proxy_bind" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
1537 } |
4dcffe43a7ea
Stream: the "proxy_bind" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
1538 |
4dcffe43a7ea
Stream: the "proxy_bind" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
1539 rc = ngx_parse_addr(cf->pool, pscf->local, value[1].data, value[1].len); |
4dcffe43a7ea
Stream: the "proxy_bind" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
1540 |
4dcffe43a7ea
Stream: the "proxy_bind" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
1541 switch (rc) { |
4dcffe43a7ea
Stream: the "proxy_bind" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
1542 case NGX_OK: |
4dcffe43a7ea
Stream: the "proxy_bind" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
1543 pscf->local->name = value[1]; |
4dcffe43a7ea
Stream: the "proxy_bind" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
1544 return NGX_CONF_OK; |
4dcffe43a7ea
Stream: the "proxy_bind" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
1545 |
4dcffe43a7ea
Stream: the "proxy_bind" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
1546 case NGX_DECLINED: |
4dcffe43a7ea
Stream: the "proxy_bind" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
1547 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
4dcffe43a7ea
Stream: the "proxy_bind" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
1548 "invalid address \"%V\"", &value[1]); |
4dcffe43a7ea
Stream: the "proxy_bind" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
1549 /* fall through */ |
4dcffe43a7ea
Stream: the "proxy_bind" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
1550 |
4dcffe43a7ea
Stream: the "proxy_bind" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
1551 default: |
4dcffe43a7ea
Stream: the "proxy_bind" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
1552 return NGX_CONF_ERROR; |
4dcffe43a7ea
Stream: the "proxy_bind" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
1553 } |
4dcffe43a7ea
Stream: the "proxy_bind" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
1554 } |