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