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 struct {
14 ngx_addr_t *addr;
15 ngx_stream_complex_value_t *value;
16 #if (NGX_HAVE_TRANSPARENT_PROXY)
17 ngx_uint_t transparent; /* unsigned transparent:1; */
18 #endif
19 } ngx_stream_upstream_local_t;
20
21
22 typedef struct {
23 ngx_msec_t connect_timeout;
24 ngx_msec_t timeout;
25 ngx_msec_t next_upstream_timeout;
26 size_t buffer_size;
27 ngx_stream_complex_value_t *upload_rate;
28 ngx_stream_complex_value_t *download_rate;
29 ngx_uint_t requests;
30 ngx_uint_t responses;
31 ngx_uint_t next_upstream_tries;
32 ngx_flag_t next_upstream;
33 ngx_flag_t proxy_protocol;
34 ngx_stream_upstream_local_t *local;
35 ngx_flag_t socket_keepalive;
36
37 #if (NGX_STREAM_SSL)
38 ngx_flag_t ssl_enable;
39 ngx_flag_t ssl_session_reuse;
40 ngx_uint_t ssl_protocols;
41 ngx_str_t ssl_ciphers;
42 ngx_stream_complex_value_t *ssl_name;
43 ngx_flag_t ssl_server_name;
44
45 ngx_flag_t ssl_verify;
46 ngx_uint_t ssl_verify_depth;
47 ngx_str_t ssl_trusted_certificate;
48 ngx_str_t ssl_crl;
49 ngx_str_t ssl_certificate;
50 ngx_str_t ssl_certificate_key;
51 ngx_array_t *ssl_passwords;
52 ngx_array_t *ssl_conf_commands;
53
54 ngx_ssl_t *ssl;
55 #endif
56
57 ngx_stream_upstream_srv_conf_t *upstream;
58 ngx_stream_complex_value_t *upstream_value;
59 } ngx_stream_proxy_srv_conf_t;
60
61
62 static void ngx_stream_proxy_handler(ngx_stream_session_t *s);
63 static ngx_int_t ngx_stream_proxy_eval(ngx_stream_session_t *s,
64 ngx_stream_proxy_srv_conf_t *pscf);
65 static ngx_int_t ngx_stream_proxy_set_local(ngx_stream_session_t *s,
66 ngx_stream_upstream_t *u, ngx_stream_upstream_local_t *local);
67 static void ngx_stream_proxy_connect(ngx_stream_session_t *s);
68 static void ngx_stream_proxy_init_upstream(ngx_stream_session_t *s);
69 static void ngx_stream_proxy_resolve_handler(ngx_resolver_ctx_t *ctx);
70 static void ngx_stream_proxy_upstream_handler(ngx_event_t *ev);
71 static void ngx_stream_proxy_downstream_handler(ngx_event_t *ev);
72 static void ngx_stream_proxy_process_connection(ngx_event_t *ev,
73 ngx_uint_t from_upstream);
74 static void ngx_stream_proxy_connect_handler(ngx_event_t *ev);
75 static ngx_int_t ngx_stream_proxy_test_connect(ngx_connection_t *c);
76 static void ngx_stream_proxy_process(ngx_stream_session_t *s,
77 ngx_uint_t from_upstream, ngx_uint_t do_write);
78 static ngx_int_t ngx_stream_proxy_test_finalize(ngx_stream_session_t *s,
79 ngx_uint_t from_upstream);
80 static void ngx_stream_proxy_next_upstream(ngx_stream_session_t *s);
81 static void ngx_stream_proxy_finalize(ngx_stream_session_t *s, ngx_uint_t rc);
82 static u_char *ngx_stream_proxy_log_error(ngx_log_t *log, u_char *buf,
83 size_t len);
84
85 static void *ngx_stream_proxy_create_srv_conf(ngx_conf_t *cf);
86 static char *ngx_stream_proxy_merge_srv_conf(ngx_conf_t *cf, void *parent,
87 void *child);
88 static char *ngx_stream_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd,
89 void *conf);
90 static char *ngx_stream_proxy_bind(ngx_conf_t *cf, ngx_command_t *cmd,
91 void *conf);
92
93 #if (NGX_STREAM_SSL)
94
95 static ngx_int_t ngx_stream_proxy_send_proxy_protocol(ngx_stream_session_t *s);
96 static char *ngx_stream_proxy_ssl_password_file(ngx_conf_t *cf,
97 ngx_command_t *cmd, void *conf);
98 static char *ngx_stream_proxy_ssl_conf_command_check(ngx_conf_t *cf, void *post,
99 void *data);
100 static void ngx_stream_proxy_ssl_init_connection(ngx_stream_session_t *s);
101 static void ngx_stream_proxy_ssl_handshake(ngx_connection_t *pc);
102 static void ngx_stream_proxy_ssl_save_session(ngx_connection_t *c);
103 static ngx_int_t ngx_stream_proxy_ssl_name(ngx_stream_session_t *s);
104 static ngx_int_t ngx_stream_proxy_set_ssl(ngx_conf_t *cf,
105 ngx_stream_proxy_srv_conf_t *pscf);
106
107
108 static ngx_conf_bitmask_t ngx_stream_proxy_ssl_protocols[] = {
109 { ngx_string("SSLv2"), NGX_SSL_SSLv2 },
110 { ngx_string("SSLv3"), NGX_SSL_SSLv3 },
111 { ngx_string("TLSv1"), NGX_SSL_TLSv1 },
112 { ngx_string("TLSv1.1"), NGX_SSL_TLSv1_1 },
113 { ngx_string("TLSv1.2"), NGX_SSL_TLSv1_2 },
114 { ngx_string("TLSv1.3"), NGX_SSL_TLSv1_3 },
115 { ngx_null_string, 0 }
116 };
117
118 static ngx_conf_post_t ngx_stream_proxy_ssl_conf_command_post =
119 { ngx_stream_proxy_ssl_conf_command_check };
120
121 #endif
122
123
124 static ngx_conf_deprecated_t ngx_conf_deprecated_proxy_downstream_buffer = {
125 ngx_conf_deprecated, "proxy_downstream_buffer", "proxy_buffer_size"
126 };
127
128 static ngx_conf_deprecated_t ngx_conf_deprecated_proxy_upstream_buffer = {
129 ngx_conf_deprecated, "proxy_upstream_buffer", "proxy_buffer_size"
130 };
131
132
133 static ngx_command_t ngx_stream_proxy_commands[] = {
134
135 { ngx_string("proxy_pass"),
136 NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
137 ngx_stream_proxy_pass,
138 NGX_STREAM_SRV_CONF_OFFSET,
139 0,
140 NULL },
141
142 { ngx_string("proxy_bind"),
143 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE12,
144 ngx_stream_proxy_bind,
145 NGX_STREAM_SRV_CONF_OFFSET,
146 0,
147 NULL },
148
149 { ngx_string("proxy_socket_keepalive"),
150 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
151 ngx_conf_set_flag_slot,
152 NGX_STREAM_SRV_CONF_OFFSET,
153 offsetof(ngx_stream_proxy_srv_conf_t, socket_keepalive),
154 NULL },
155
156 { ngx_string("proxy_connect_timeout"),
157 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
158 ngx_conf_set_msec_slot,
159 NGX_STREAM_SRV_CONF_OFFSET,
160 offsetof(ngx_stream_proxy_srv_conf_t, connect_timeout),
161 NULL },
162
163 { ngx_string("proxy_timeout"),
164 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
165 ngx_conf_set_msec_slot,
166 NGX_STREAM_SRV_CONF_OFFSET,
167 offsetof(ngx_stream_proxy_srv_conf_t, timeout),
168 NULL },
169
170 { ngx_string("proxy_buffer_size"),
171 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
172 ngx_conf_set_size_slot,
173 NGX_STREAM_SRV_CONF_OFFSET,
174 offsetof(ngx_stream_proxy_srv_conf_t, buffer_size),
175 NULL },
176
177 { ngx_string("proxy_downstream_buffer"),
178 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
179 ngx_conf_set_size_slot,
180 NGX_STREAM_SRV_CONF_OFFSET,
181 offsetof(ngx_stream_proxy_srv_conf_t, buffer_size),
182 &ngx_conf_deprecated_proxy_downstream_buffer },
183
184 { ngx_string("proxy_upstream_buffer"),
185 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
186 ngx_conf_set_size_slot,
187 NGX_STREAM_SRV_CONF_OFFSET,
188 offsetof(ngx_stream_proxy_srv_conf_t, buffer_size),
189 &ngx_conf_deprecated_proxy_upstream_buffer },
190
191 { ngx_string("proxy_upload_rate"),
192 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
193 ngx_stream_set_complex_value_size_slot,
194 NGX_STREAM_SRV_CONF_OFFSET,
195 offsetof(ngx_stream_proxy_srv_conf_t, upload_rate),
196 NULL },
197
198 { ngx_string("proxy_download_rate"),
199 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
200 ngx_stream_set_complex_value_size_slot,
201 NGX_STREAM_SRV_CONF_OFFSET,
202 offsetof(ngx_stream_proxy_srv_conf_t, download_rate),
203 NULL },
204
205 { ngx_string("proxy_requests"),
206 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
207 ngx_conf_set_num_slot,
208 NGX_STREAM_SRV_CONF_OFFSET,
209 offsetof(ngx_stream_proxy_srv_conf_t, requests),
210 NULL },
211
212 { ngx_string("proxy_responses"),
213 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
214 ngx_conf_set_num_slot,
215 NGX_STREAM_SRV_CONF_OFFSET,
216 offsetof(ngx_stream_proxy_srv_conf_t, responses),
217 NULL },
218
219 { ngx_string("proxy_next_upstream"),
220 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
221 ngx_conf_set_flag_slot,
222 NGX_STREAM_SRV_CONF_OFFSET,
223 offsetof(ngx_stream_proxy_srv_conf_t, next_upstream),
224 NULL },
225
226 { ngx_string("proxy_next_upstream_tries"),
227 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
228 ngx_conf_set_num_slot,
229 NGX_STREAM_SRV_CONF_OFFSET,
230 offsetof(ngx_stream_proxy_srv_conf_t, next_upstream_tries),
231 NULL },
232
233 { ngx_string("proxy_next_upstream_timeout"),
234 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
235 ngx_conf_set_msec_slot,
236 NGX_STREAM_SRV_CONF_OFFSET,
237 offsetof(ngx_stream_proxy_srv_conf_t, next_upstream_timeout),
238 NULL },
239
240 { ngx_string("proxy_protocol"),
241 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
242 ngx_conf_set_flag_slot,
243 NGX_STREAM_SRV_CONF_OFFSET,
244 offsetof(ngx_stream_proxy_srv_conf_t, proxy_protocol),
245 NULL },
246
247 #if (NGX_STREAM_SSL)
248
249 { ngx_string("proxy_ssl"),
250 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
251 ngx_conf_set_flag_slot,
252 NGX_STREAM_SRV_CONF_OFFSET,
253 offsetof(ngx_stream_proxy_srv_conf_t, ssl_enable),
254 NULL },
255
256 { ngx_string("proxy_ssl_session_reuse"),
257 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
258 ngx_conf_set_flag_slot,
259 NGX_STREAM_SRV_CONF_OFFSET,
260 offsetof(ngx_stream_proxy_srv_conf_t, ssl_session_reuse),
261 NULL },
262
263 { ngx_string("proxy_ssl_protocols"),
264 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_1MORE,
265 ngx_conf_set_bitmask_slot,
266 NGX_STREAM_SRV_CONF_OFFSET,
267 offsetof(ngx_stream_proxy_srv_conf_t, ssl_protocols),
268 &ngx_stream_proxy_ssl_protocols },
269
270 { ngx_string("proxy_ssl_ciphers"),
271 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
272 ngx_conf_set_str_slot,
273 NGX_STREAM_SRV_CONF_OFFSET,
274 offsetof(ngx_stream_proxy_srv_conf_t, ssl_ciphers),
275 NULL },
276
277 { ngx_string("proxy_ssl_name"),
278 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
279 ngx_stream_set_complex_value_slot,
280 NGX_STREAM_SRV_CONF_OFFSET,
281 offsetof(ngx_stream_proxy_srv_conf_t, ssl_name),
282 NULL },
283
284 { ngx_string("proxy_ssl_server_name"),
285 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
286 ngx_conf_set_flag_slot,
287 NGX_STREAM_SRV_CONF_OFFSET,
288 offsetof(ngx_stream_proxy_srv_conf_t, ssl_server_name),
289 NULL },
290
291 { ngx_string("proxy_ssl_verify"),
292 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
293 ngx_conf_set_flag_slot,
294 NGX_STREAM_SRV_CONF_OFFSET,
295 offsetof(ngx_stream_proxy_srv_conf_t, ssl_verify),
296 NULL },
297
298 { ngx_string("proxy_ssl_verify_depth"),
299 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
300 ngx_conf_set_num_slot,
301 NGX_STREAM_SRV_CONF_OFFSET,
302 offsetof(ngx_stream_proxy_srv_conf_t, ssl_verify_depth),
303 NULL },
304
305 { ngx_string("proxy_ssl_trusted_certificate"),
306 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
307 ngx_conf_set_str_slot,
308 NGX_STREAM_SRV_CONF_OFFSET,
309 offsetof(ngx_stream_proxy_srv_conf_t, ssl_trusted_certificate),
310 NULL },
311
312 { ngx_string("proxy_ssl_crl"),
313 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
314 ngx_conf_set_str_slot,
315 NGX_STREAM_SRV_CONF_OFFSET,
316 offsetof(ngx_stream_proxy_srv_conf_t, ssl_crl),
317 NULL },
318
319 { ngx_string("proxy_ssl_certificate"),
320 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
321 ngx_conf_set_str_slot,
322 NGX_STREAM_SRV_CONF_OFFSET,
323 offsetof(ngx_stream_proxy_srv_conf_t, ssl_certificate),
324 NULL },
325
326 { ngx_string("proxy_ssl_certificate_key"),
327 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
328 ngx_conf_set_str_slot,
329 NGX_STREAM_SRV_CONF_OFFSET,
330 offsetof(ngx_stream_proxy_srv_conf_t, ssl_certificate_key),
331 NULL },
332
333 { ngx_string("proxy_ssl_password_file"),
334 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
335 ngx_stream_proxy_ssl_password_file,
336 NGX_STREAM_SRV_CONF_OFFSET,
337 0,
338 NULL },
339
340 { ngx_string("proxy_ssl_conf_command"),
341 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE2,
342 ngx_conf_set_keyval_slot,
343 NGX_STREAM_SRV_CONF_OFFSET,
344 offsetof(ngx_stream_proxy_srv_conf_t, ssl_conf_commands),
345 &ngx_stream_proxy_ssl_conf_command_post },
346
347 #endif
348
349 ngx_null_command
350 };
351
352
353 static ngx_stream_module_t ngx_stream_proxy_module_ctx = {
354 NULL, /* preconfiguration */
355 NULL, /* postconfiguration */
356
357 NULL, /* create main configuration */
358 NULL, /* init main configuration */
359
360 ngx_stream_proxy_create_srv_conf, /* create server configuration */
361 ngx_stream_proxy_merge_srv_conf /* merge server configuration */
362 };
363
364
365 ngx_module_t ngx_stream_proxy_module = {
366 NGX_MODULE_V1,
367 &ngx_stream_proxy_module_ctx, /* module context */
368 ngx_stream_proxy_commands, /* module directives */
369 NGX_STREAM_MODULE, /* module type */
370 NULL, /* init master */
371 NULL, /* init module */
372 NULL, /* init process */
373 NULL, /* init thread */
374 NULL, /* exit thread */
375 NULL, /* exit process */
376 NULL, /* exit master */
377 NGX_MODULE_V1_PADDING
378 };
379
380
381 static void
ngx_stream_proxy_handler(ngx_stream_session_t * s)382 ngx_stream_proxy_handler(ngx_stream_session_t *s)
383 {
384 u_char *p;
385 ngx_str_t *host;
386 ngx_uint_t i;
387 ngx_connection_t *c;
388 ngx_resolver_ctx_t *ctx, temp;
389 ngx_stream_upstream_t *u;
390 ngx_stream_core_srv_conf_t *cscf;
391 ngx_stream_proxy_srv_conf_t *pscf;
392 ngx_stream_upstream_srv_conf_t *uscf, **uscfp;
393 ngx_stream_upstream_main_conf_t *umcf;
394
395 c = s->connection;
396
397 pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);
398
399 ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0,
400 "proxy connection handler");
401
402 u = ngx_pcalloc(c->pool, sizeof(ngx_stream_upstream_t));
403 if (u == NULL) {
404 ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
405 return;
406 }
407
408 s->upstream = u;
409
410 s->log_handler = ngx_stream_proxy_log_error;
411
412 u->requests = 1;
413
414 u->peer.log = c->log;
415 u->peer.log_error = NGX_ERROR_ERR;
416
417 if (ngx_stream_proxy_set_local(s, u, pscf->local) != NGX_OK) {
418 ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
419 return;
420 }
421
422 if (pscf->socket_keepalive) {
423 u->peer.so_keepalive = 1;
424 }
425
426 u->peer.type = c->type;
427 u->start_sec = ngx_time();
428
429 c->write->handler = ngx_stream_proxy_downstream_handler;
430 c->read->handler = ngx_stream_proxy_downstream_handler;
431
432 s->upstream_states = ngx_array_create(c->pool, 1,
433 sizeof(ngx_stream_upstream_state_t));
434 if (s->upstream_states == NULL) {
435 ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
436 return;
437 }
438
439 p = ngx_pnalloc(c->pool, pscf->buffer_size);
440 if (p == NULL) {
441 ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
442 return;
443 }
444
445 u->downstream_buf.start = p;
446 u->downstream_buf.end = p + pscf->buffer_size;
447 u->downstream_buf.pos = p;
448 u->downstream_buf.last = p;
449
450 if (c->read->ready) {
451 ngx_post_event(c->read, &ngx_posted_events);
452 }
453
454 if (pscf->upstream_value) {
455 if (ngx_stream_proxy_eval(s, pscf) != NGX_OK) {
456 ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
457 return;
458 }
459 }
460
461 if (u->resolved == NULL) {
462
463 uscf = pscf->upstream;
464
465 } else {
466
467 #if (NGX_STREAM_SSL)
468 u->ssl_name = u->resolved->host;
469 #endif
470
471 host = &u->resolved->host;
472
473 umcf = ngx_stream_get_module_main_conf(s, ngx_stream_upstream_module);
474
475 uscfp = umcf->upstreams.elts;
476
477 for (i = 0; i < umcf->upstreams.nelts; i++) {
478
479 uscf = uscfp[i];
480
481 if (uscf->host.len == host->len
482 && ((uscf->port == 0 && u->resolved->no_port)
483 || uscf->port == u->resolved->port)
484 && ngx_strncasecmp(uscf->host.data, host->data, host->len) == 0)
485 {
486 goto found;
487 }
488 }
489
490 if (u->resolved->sockaddr) {
491
492 if (u->resolved->port == 0
493 && u->resolved->sockaddr->sa_family != AF_UNIX)
494 {
495 ngx_log_error(NGX_LOG_ERR, c->log, 0,
496 "no port in upstream \"%V\"", host);
497 ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
498 return;
499 }
500
501 if (ngx_stream_upstream_create_round_robin_peer(s, u->resolved)
502 != NGX_OK)
503 {
504 ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
505 return;
506 }
507
508 ngx_stream_proxy_connect(s);
509
510 return;
511 }
512
513 if (u->resolved->port == 0) {
514 ngx_log_error(NGX_LOG_ERR, c->log, 0,
515 "no port in upstream \"%V\"", host);
516 ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
517 return;
518 }
519
520 temp.name = *host;
521
522 cscf = ngx_stream_get_module_srv_conf(s, ngx_stream_core_module);
523
524 ctx = ngx_resolve_start(cscf->resolver, &temp);
525 if (ctx == NULL) {
526 ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
527 return;
528 }
529
530 if (ctx == NGX_NO_RESOLVER) {
531 ngx_log_error(NGX_LOG_ERR, c->log, 0,
532 "no resolver defined to resolve %V", host);
533 ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
534 return;
535 }
536
537 ctx->name = *host;
538 ctx->handler = ngx_stream_proxy_resolve_handler;
539 ctx->data = s;
540 ctx->timeout = cscf->resolver_timeout;
541
542 u->resolved->ctx = ctx;
543
544 if (ngx_resolve_name(ctx) != NGX_OK) {
545 u->resolved->ctx = NULL;
546 ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
547 return;
548 }
549
550 return;
551 }
552
553 found:
554
555 if (uscf == NULL) {
556 ngx_log_error(NGX_LOG_ALERT, c->log, 0, "no upstream configuration");
557 ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
558 return;
559 }
560
561 u->upstream = uscf;
562
563 #if (NGX_STREAM_SSL)
564 u->ssl_name = uscf->host;
565 #endif
566
567 if (uscf->peer.init(s, uscf) != NGX_OK) {
568 ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
569 return;
570 }
571
572 u->peer.start_time = ngx_current_msec;
573
574 if (pscf->next_upstream_tries
575 && u->peer.tries > pscf->next_upstream_tries)
576 {
577 u->peer.tries = pscf->next_upstream_tries;
578 }
579
580 ngx_stream_proxy_connect(s);
581 }
582
583
584 static ngx_int_t
ngx_stream_proxy_eval(ngx_stream_session_t * s,ngx_stream_proxy_srv_conf_t * pscf)585 ngx_stream_proxy_eval(ngx_stream_session_t *s,
586 ngx_stream_proxy_srv_conf_t *pscf)
587 {
588 ngx_str_t host;
589 ngx_url_t url;
590 ngx_stream_upstream_t *u;
591
592 if (ngx_stream_complex_value(s, pscf->upstream_value, &host) != NGX_OK) {
593 return NGX_ERROR;
594 }
595
596 ngx_memzero(&url, sizeof(ngx_url_t));
597
598 url.url = host;
599 url.no_resolve = 1;
600
601 if (ngx_parse_url(s->connection->pool, &url) != NGX_OK) {
602 if (url.err) {
603 ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
604 "%s in upstream \"%V\"", url.err, &url.url);
605 }
606
607 return NGX_ERROR;
608 }
609
610 u = s->upstream;
611
612 u->resolved = ngx_pcalloc(s->connection->pool,
613 sizeof(ngx_stream_upstream_resolved_t));
614 if (u->resolved == NULL) {
615 return NGX_ERROR;
616 }
617
618 if (url.addrs) {
619 u->resolved->sockaddr = url.addrs[0].sockaddr;
620 u->resolved->socklen = url.addrs[0].socklen;
621 u->resolved->name = url.addrs[0].name;
622 u->resolved->naddrs = 1;
623 }
624
625 u->resolved->host = url.host;
626 u->resolved->port = url.port;
627 u->resolved->no_port = url.no_port;
628
629 return NGX_OK;
630 }
631
632
633 static ngx_int_t
ngx_stream_proxy_set_local(ngx_stream_session_t * s,ngx_stream_upstream_t * u,ngx_stream_upstream_local_t * local)634 ngx_stream_proxy_set_local(ngx_stream_session_t *s, ngx_stream_upstream_t *u,
635 ngx_stream_upstream_local_t *local)
636 {
637 ngx_int_t rc;
638 ngx_str_t val;
639 ngx_addr_t *addr;
640
641 if (local == NULL) {
642 u->peer.local = NULL;
643 return NGX_OK;
644 }
645
646 #if (NGX_HAVE_TRANSPARENT_PROXY)
647 u->peer.transparent = local->transparent;
648 #endif
649
650 if (local->value == NULL) {
651 u->peer.local = local->addr;
652 return NGX_OK;
653 }
654
655 if (ngx_stream_complex_value(s, local->value, &val) != NGX_OK) {
656 return NGX_ERROR;
657 }
658
659 if (val.len == 0) {
660 return NGX_OK;
661 }
662
663 addr = ngx_palloc(s->connection->pool, sizeof(ngx_addr_t));
664 if (addr == NULL) {
665 return NGX_ERROR;
666 }
667
668 rc = ngx_parse_addr_port(s->connection->pool, addr, val.data, val.len);
669 if (rc == NGX_ERROR) {
670 return NGX_ERROR;
671 }
672
673 if (rc != NGX_OK) {
674 ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
675 "invalid local address \"%V\"", &val);
676 return NGX_OK;
677 }
678
679 addr->name = val;
680 u->peer.local = addr;
681
682 return NGX_OK;
683 }
684
685
686 static void
ngx_stream_proxy_connect(ngx_stream_session_t * s)687 ngx_stream_proxy_connect(ngx_stream_session_t *s)
688 {
689 ngx_int_t rc;
690 ngx_connection_t *c, *pc;
691 ngx_stream_upstream_t *u;
692 ngx_stream_proxy_srv_conf_t *pscf;
693
694 c = s->connection;
695
696 c->log->action = "connecting to upstream";
697
698 pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);
699
700 u = s->upstream;
701
702 u->connected = 0;
703 u->proxy_protocol = pscf->proxy_protocol;
704
705 if (u->state) {
706 u->state->response_time = ngx_current_msec - u->start_time;
707 }
708
709 u->state = ngx_array_push(s->upstream_states);
710 if (u->state == NULL) {
711 ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
712 return;
713 }
714
715 ngx_memzero(u->state, sizeof(ngx_stream_upstream_state_t));
716
717 u->start_time = ngx_current_msec;
718
719 u->state->connect_time = (ngx_msec_t) -1;
720 u->state->first_byte_time = (ngx_msec_t) -1;
721 u->state->response_time = (ngx_msec_t) -1;
722
723 rc = ngx_event_connect_peer(&u->peer);
724
725 ngx_log_debug1(NGX_LOG_DEBUG_STREAM, c->log, 0, "proxy connect: %i", rc);
726
727 if (rc == NGX_ERROR) {
728 ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
729 return;
730 }
731
732 u->state->peer = u->peer.name;
733
734 if (rc == NGX_BUSY) {
735 ngx_log_error(NGX_LOG_ERR, c->log, 0, "no live upstreams");
736 ngx_stream_proxy_finalize(s, NGX_STREAM_BAD_GATEWAY);
737 return;
738 }
739
740 if (rc == NGX_DECLINED) {
741 ngx_stream_proxy_next_upstream(s);
742 return;
743 }
744
745 /* rc == NGX_OK || rc == NGX_AGAIN || rc == NGX_DONE */
746
747 pc = u->peer.connection;
748
749 pc->data = s;
750 pc->log = c->log;
751 pc->pool = c->pool;
752 pc->read->log = c->log;
753 pc->write->log = c->log;
754
755 if (rc != NGX_AGAIN) {
756 ngx_stream_proxy_init_upstream(s);
757 return;
758 }
759
760 pc->read->handler = ngx_stream_proxy_connect_handler;
761 pc->write->handler = ngx_stream_proxy_connect_handler;
762
763 ngx_add_timer(pc->write, pscf->connect_timeout);
764 }
765
766
767 static void
ngx_stream_proxy_init_upstream(ngx_stream_session_t * s)768 ngx_stream_proxy_init_upstream(ngx_stream_session_t *s)
769 {
770 u_char *p;
771 ngx_chain_t *cl;
772 ngx_connection_t *c, *pc;
773 ngx_log_handler_pt handler;
774 ngx_stream_upstream_t *u;
775 ngx_stream_core_srv_conf_t *cscf;
776 ngx_stream_proxy_srv_conf_t *pscf;
777
778 u = s->upstream;
779 pc = u->peer.connection;
780
781 cscf = ngx_stream_get_module_srv_conf(s, ngx_stream_core_module);
782
783 if (pc->type == SOCK_STREAM
784 && cscf->tcp_nodelay
785 && ngx_tcp_nodelay(pc) != NGX_OK)
786 {
787 ngx_stream_proxy_next_upstream(s);
788 return;
789 }
790
791 pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);
792
793 #if (NGX_STREAM_SSL)
794
795 if (pc->type == SOCK_STREAM && pscf->ssl) {
796
797 if (u->proxy_protocol) {
798 if (ngx_stream_proxy_send_proxy_protocol(s) != NGX_OK) {
799 return;
800 }
801
802 u->proxy_protocol = 0;
803 }
804
805 if (pc->ssl == NULL) {
806 ngx_stream_proxy_ssl_init_connection(s);
807 return;
808 }
809 }
810
811 #endif
812
813 c = s->connection;
814
815 if (c->log->log_level >= NGX_LOG_INFO) {
816 ngx_str_t str;
817 u_char addr[NGX_SOCKADDR_STRLEN];
818
819 str.len = NGX_SOCKADDR_STRLEN;
820 str.data = addr;
821
822 if (ngx_connection_local_sockaddr(pc, &str, 1) == NGX_OK) {
823 handler = c->log->handler;
824 c->log->handler = NULL;
825
826 ngx_log_error(NGX_LOG_INFO, c->log, 0,
827 "%sproxy %V connected to %V",
828 pc->type == SOCK_DGRAM ? "udp " : "",
829 &str, u->peer.name);
830
831 c->log->handler = handler;
832 }
833 }
834
835 u->state->connect_time = ngx_current_msec - u->start_time;
836
837 if (u->peer.notify) {
838 u->peer.notify(&u->peer, u->peer.data,
839 NGX_STREAM_UPSTREAM_NOTIFY_CONNECT);
840 }
841
842 if (u->upstream_buf.start == NULL) {
843 p = ngx_pnalloc(c->pool, pscf->buffer_size);
844 if (p == NULL) {
845 ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
846 return;
847 }
848
849 u->upstream_buf.start = p;
850 u->upstream_buf.end = p + pscf->buffer_size;
851 u->upstream_buf.pos = p;
852 u->upstream_buf.last = p;
853 }
854
855 if (c->buffer && c->buffer->pos <= c->buffer->last) {
856 ngx_log_debug1(NGX_LOG_DEBUG_STREAM, c->log, 0,
857 "stream proxy add preread buffer: %uz",
858 c->buffer->last - c->buffer->pos);
859
860 cl = ngx_chain_get_free_buf(c->pool, &u->free);
861 if (cl == NULL) {
862 ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
863 return;
864 }
865
866 *cl->buf = *c->buffer;
867
868 cl->buf->tag = (ngx_buf_tag_t) &ngx_stream_proxy_module;
869 cl->buf->temporary = (cl->buf->pos == cl->buf->last) ? 0 : 1;
870 cl->buf->flush = 1;
871
872 cl->next = u->upstream_out;
873 u->upstream_out = cl;
874 }
875
876 if (u->proxy_protocol) {
877 ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0,
878 "stream proxy add PROXY protocol header");
879
880 cl = ngx_chain_get_free_buf(c->pool, &u->free);
881 if (cl == NULL) {
882 ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
883 return;
884 }
885
886 p = ngx_pnalloc(c->pool, NGX_PROXY_PROTOCOL_MAX_HEADER);
887 if (p == NULL) {
888 ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
889 return;
890 }
891
892 cl->buf->pos = p;
893
894 p = ngx_proxy_protocol_write(c, p, p + NGX_PROXY_PROTOCOL_MAX_HEADER);
895 if (p == NULL) {
896 ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
897 return;
898 }
899
900 cl->buf->last = p;
901 cl->buf->temporary = 1;
902 cl->buf->flush = 0;
903 cl->buf->last_buf = 0;
904 cl->buf->tag = (ngx_buf_tag_t) &ngx_stream_proxy_module;
905
906 cl->next = u->upstream_out;
907 u->upstream_out = cl;
908
909 u->proxy_protocol = 0;
910 }
911
912 u->upload_rate = ngx_stream_complex_value_size(s, pscf->upload_rate, 0);
913 u->download_rate = ngx_stream_complex_value_size(s, pscf->download_rate, 0);
914
915 u->connected = 1;
916
917 pc->read->handler = ngx_stream_proxy_upstream_handler;
918 pc->write->handler = ngx_stream_proxy_upstream_handler;
919
920 if (pc->read->ready) {
921 ngx_post_event(pc->read, &ngx_posted_events);
922 }
923
924 ngx_stream_proxy_process(s, 0, 1);
925 }
926
927
928 #if (NGX_STREAM_SSL)
929
930 static ngx_int_t
ngx_stream_proxy_send_proxy_protocol(ngx_stream_session_t * s)931 ngx_stream_proxy_send_proxy_protocol(ngx_stream_session_t *s)
932 {
933 u_char *p;
934 ssize_t n, size;
935 ngx_connection_t *c, *pc;
936 ngx_stream_upstream_t *u;
937 ngx_stream_proxy_srv_conf_t *pscf;
938 u_char buf[NGX_PROXY_PROTOCOL_MAX_HEADER];
939
940 c = s->connection;
941
942 ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0,
943 "stream proxy send PROXY protocol header");
944
945 p = ngx_proxy_protocol_write(c, buf, buf + NGX_PROXY_PROTOCOL_MAX_HEADER);
946 if (p == NULL) {
947 ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
948 return NGX_ERROR;
949 }
950
951 u = s->upstream;
952
953 pc = u->peer.connection;
954
955 size = p - buf;
956
957 n = pc->send(pc, buf, size);
958
959 if (n == NGX_AGAIN) {
960 if (ngx_handle_write_event(pc->write, 0) != NGX_OK) {
961 ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
962 return NGX_ERROR;
963 }
964
965 pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);
966
967 ngx_add_timer(pc->write, pscf->timeout);
968
969 pc->write->handler = ngx_stream_proxy_connect_handler;
970
971 return NGX_AGAIN;
972 }
973
974 if (n == NGX_ERROR) {
975 ngx_stream_proxy_finalize(s, NGX_STREAM_OK);
976 return NGX_ERROR;
977 }
978
979 if (n != size) {
980
981 /*
982 * PROXY protocol specification:
983 * The sender must always ensure that the header
984 * is sent at once, so that the transport layer
985 * maintains atomicity along the path to the receiver.
986 */
987
988 ngx_log_error(NGX_LOG_ERR, c->log, 0,
989 "could not send PROXY protocol header at once");
990
991 ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
992
993 return NGX_ERROR;
994 }
995
996 return NGX_OK;
997 }
998
999
1000 static char *
ngx_stream_proxy_ssl_password_file(ngx_conf_t * cf,ngx_command_t * cmd,void * conf)1001 ngx_stream_proxy_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd,
1002 void *conf)
1003 {
1004 ngx_stream_proxy_srv_conf_t *pscf = conf;
1005
1006 ngx_str_t *value;
1007
1008 if (pscf->ssl_passwords != NGX_CONF_UNSET_PTR) {
1009 return "is duplicate";
1010 }
1011
1012 value = cf->args->elts;
1013
1014 pscf->ssl_passwords = ngx_ssl_read_password_file(cf, &value[1]);
1015
1016 if (pscf->ssl_passwords == NULL) {
1017 return NGX_CONF_ERROR;
1018 }
1019
1020 return NGX_CONF_OK;
1021 }
1022
1023
1024 static char *
ngx_stream_proxy_ssl_conf_command_check(ngx_conf_t * cf,void * post,void * data)1025 ngx_stream_proxy_ssl_conf_command_check(ngx_conf_t *cf, void *post, void *data)
1026 {
1027 #ifndef SSL_CONF_FLAG_FILE
1028 return "is not supported on this platform";
1029 #else
1030 return NGX_CONF_OK;
1031 #endif
1032 }
1033
1034
1035 static void
ngx_stream_proxy_ssl_init_connection(ngx_stream_session_t * s)1036 ngx_stream_proxy_ssl_init_connection(ngx_stream_session_t *s)
1037 {
1038 ngx_int_t rc;
1039 ngx_connection_t *pc;
1040 ngx_stream_upstream_t *u;
1041 ngx_stream_proxy_srv_conf_t *pscf;
1042
1043 u = s->upstream;
1044
1045 pc = u->peer.connection;
1046
1047 pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);
1048
1049 if (ngx_ssl_create_connection(pscf->ssl, pc, NGX_SSL_BUFFER|NGX_SSL_CLIENT)
1050 != NGX_OK)
1051 {
1052 ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
1053 return;
1054 }
1055
1056 if (pscf->ssl_server_name || pscf->ssl_verify) {
1057 if (ngx_stream_proxy_ssl_name(s) != NGX_OK) {
1058 ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
1059 return;
1060 }
1061 }
1062
1063 if (pscf->ssl_session_reuse) {
1064 pc->ssl->save_session = ngx_stream_proxy_ssl_save_session;
1065
1066 if (u->peer.set_session(&u->peer, u->peer.data) != NGX_OK) {
1067 ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
1068 return;
1069 }
1070 }
1071
1072 s->connection->log->action = "SSL handshaking to upstream";
1073
1074 rc = ngx_ssl_handshake(pc);
1075
1076 if (rc == NGX_AGAIN) {
1077
1078 if (!pc->write->timer_set) {
1079 ngx_add_timer(pc->write, pscf->connect_timeout);
1080 }
1081
1082 pc->ssl->handler = ngx_stream_proxy_ssl_handshake;
1083 return;
1084 }
1085
1086 ngx_stream_proxy_ssl_handshake(pc);
1087 }
1088
1089
1090 static void
ngx_stream_proxy_ssl_handshake(ngx_connection_t * pc)1091 ngx_stream_proxy_ssl_handshake(ngx_connection_t *pc)
1092 {
1093 long rc;
1094 ngx_stream_session_t *s;
1095 ngx_stream_upstream_t *u;
1096 ngx_stream_proxy_srv_conf_t *pscf;
1097
1098 s = pc->data;
1099
1100 pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);
1101
1102 if (pc->ssl->handshaked) {
1103
1104 if (pscf->ssl_verify) {
1105 rc = SSL_get_verify_result(pc->ssl->connection);
1106
1107 if (rc != X509_V_OK) {
1108 ngx_log_error(NGX_LOG_ERR, pc->log, 0,
1109 "upstream SSL certificate verify error: (%l:%s)",
1110 rc, X509_verify_cert_error_string(rc));
1111 goto failed;
1112 }
1113
1114 u = s->upstream;
1115
1116 if (ngx_ssl_check_host(pc, &u->ssl_name) != NGX_OK) {
1117 ngx_log_error(NGX_LOG_ERR, pc->log, 0,
1118 "upstream SSL certificate does not match \"%V\"",
1119 &u->ssl_name);
1120 goto failed;
1121 }
1122 }
1123
1124 if (pc->write->timer_set) {
1125 ngx_del_timer(pc->write);
1126 }
1127
1128 ngx_stream_proxy_init_upstream(s);
1129
1130 return;
1131 }
1132
1133 failed:
1134
1135 ngx_stream_proxy_next_upstream(s);
1136 }
1137
1138
1139 static void
ngx_stream_proxy_ssl_save_session(ngx_connection_t * c)1140 ngx_stream_proxy_ssl_save_session(ngx_connection_t *c)
1141 {
1142 ngx_stream_session_t *s;
1143 ngx_stream_upstream_t *u;
1144
1145 s = c->data;
1146 u = s->upstream;
1147
1148 u->peer.save_session(&u->peer, u->peer.data);
1149 }
1150
1151
1152 static ngx_int_t
ngx_stream_proxy_ssl_name(ngx_stream_session_t * s)1153 ngx_stream_proxy_ssl_name(ngx_stream_session_t *s)
1154 {
1155 u_char *p, *last;
1156 ngx_str_t name;
1157 ngx_stream_upstream_t *u;
1158 ngx_stream_proxy_srv_conf_t *pscf;
1159
1160 pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);
1161
1162 u = s->upstream;
1163
1164 if (pscf->ssl_name) {
1165 if (ngx_stream_complex_value(s, pscf->ssl_name, &name) != NGX_OK) {
1166 return NGX_ERROR;
1167 }
1168
1169 } else {
1170 name = u->ssl_name;
1171 }
1172
1173 if (name.len == 0) {
1174 goto done;
1175 }
1176
1177 /*
1178 * ssl name here may contain port, strip it for compatibility
1179 * with the http module
1180 */
1181
1182 p = name.data;
1183 last = name.data + name.len;
1184
1185 if (*p == '[') {
1186 p = ngx_strlchr(p, last, ']');
1187
1188 if (p == NULL) {
1189 p = name.data;
1190 }
1191 }
1192
1193 p = ngx_strlchr(p, last, ':');
1194
1195 if (p != NULL) {
1196 name.len = p - name.data;
1197 }
1198
1199 if (!pscf->ssl_server_name) {
1200 goto done;
1201 }
1202
1203 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1204
1205 /* as per RFC 6066, literal IPv4 and IPv6 addresses are not permitted */
1206
1207 if (name.len == 0 || *name.data == '[') {
1208 goto done;
1209 }
1210
1211 if (ngx_inet_addr(name.data, name.len) != INADDR_NONE) {
1212 goto done;
1213 }
1214
1215 /*
1216 * SSL_set_tlsext_host_name() needs a null-terminated string,
1217 * hence we explicitly null-terminate name here
1218 */
1219
1220 p = ngx_pnalloc(s->connection->pool, name.len + 1);
1221 if (p == NULL) {
1222 return NGX_ERROR;
1223 }
1224
1225 (void) ngx_cpystrn(p, name.data, name.len + 1);
1226
1227 name.data = p;
1228
1229 ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
1230 "upstream SSL server name: \"%s\"", name.data);
1231
1232 if (SSL_set_tlsext_host_name(u->peer.connection->ssl->connection,
1233 (char *) name.data)
1234 == 0)
1235 {
1236 ngx_ssl_error(NGX_LOG_ERR, s->connection->log, 0,
1237 "SSL_set_tlsext_host_name(\"%s\") failed", name.data);
1238 return NGX_ERROR;
1239 }
1240
1241 #endif
1242
1243 done:
1244
1245 u->ssl_name = name;
1246
1247 return NGX_OK;
1248 }
1249
1250 #endif
1251
1252
1253 static void
ngx_stream_proxy_downstream_handler(ngx_event_t * ev)1254 ngx_stream_proxy_downstream_handler(ngx_event_t *ev)
1255 {
1256 ngx_stream_proxy_process_connection(ev, ev->write);
1257 }
1258
1259
1260 static void
ngx_stream_proxy_resolve_handler(ngx_resolver_ctx_t * ctx)1261 ngx_stream_proxy_resolve_handler(ngx_resolver_ctx_t *ctx)
1262 {
1263 ngx_stream_session_t *s;
1264 ngx_stream_upstream_t *u;
1265 ngx_stream_proxy_srv_conf_t *pscf;
1266 ngx_stream_upstream_resolved_t *ur;
1267
1268 s = ctx->data;
1269
1270 u = s->upstream;
1271 ur = u->resolved;
1272
1273 ngx_log_debug0(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
1274 "stream upstream resolve");
1275
1276 if (ctx->state) {
1277 ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
1278 "%V could not be resolved (%i: %s)",
1279 &ctx->name, ctx->state,
1280 ngx_resolver_strerror(ctx->state));
1281
1282 ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
1283 return;
1284 }
1285
1286 ur->naddrs = ctx->naddrs;
1287 ur->addrs = ctx->addrs;
1288
1289 #if (NGX_DEBUG)
1290 {
1291 u_char text[NGX_SOCKADDR_STRLEN];
1292 ngx_str_t addr;
1293 ngx_uint_t i;
1294
1295 addr.data = text;
1296
1297 for (i = 0; i < ctx->naddrs; i++) {
1298 addr.len = ngx_sock_ntop(ur->addrs[i].sockaddr, ur->addrs[i].socklen,
1299 text, NGX_SOCKADDR_STRLEN, 0);
1300
1301 ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
1302 "name was resolved to %V", &addr);
1303 }
1304 }
1305 #endif
1306
1307 if (ngx_stream_upstream_create_round_robin_peer(s, ur) != NGX_OK) {
1308 ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
1309 return;
1310 }
1311
1312 ngx_resolve_name_done(ctx);
1313 ur->ctx = NULL;
1314
1315 u->peer.start_time = ngx_current_msec;
1316
1317 pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);
1318
1319 if (pscf->next_upstream_tries
1320 && u->peer.tries > pscf->next_upstream_tries)
1321 {
1322 u->peer.tries = pscf->next_upstream_tries;
1323 }
1324
1325 ngx_stream_proxy_connect(s);
1326 }
1327
1328
1329 static void
ngx_stream_proxy_upstream_handler(ngx_event_t * ev)1330 ngx_stream_proxy_upstream_handler(ngx_event_t *ev)
1331 {
1332 ngx_stream_proxy_process_connection(ev, !ev->write);
1333 }
1334
1335
1336 static void
ngx_stream_proxy_process_connection(ngx_event_t * ev,ngx_uint_t from_upstream)1337 ngx_stream_proxy_process_connection(ngx_event_t *ev, ngx_uint_t from_upstream)
1338 {
1339 ngx_connection_t *c, *pc;
1340 ngx_log_handler_pt handler;
1341 ngx_stream_session_t *s;
1342 ngx_stream_upstream_t *u;
1343 ngx_stream_proxy_srv_conf_t *pscf;
1344
1345 c = ev->data;
1346 s = c->data;
1347 u = s->upstream;
1348
1349 if (c->close) {
1350 ngx_log_error(NGX_LOG_INFO, c->log, 0, "shutdown timeout");
1351 ngx_stream_proxy_finalize(s, NGX_STREAM_OK);
1352 return;
1353 }
1354
1355 c = s->connection;
1356 pc = u->peer.connection;
1357
1358 pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);
1359
1360 if (ev->timedout) {
1361 ev->timedout = 0;
1362
1363 if (ev->delayed) {
1364 ev->delayed = 0;
1365
1366 if (!ev->ready) {
1367 if (ngx_handle_read_event(ev, 0) != NGX_OK) {
1368 ngx_stream_proxy_finalize(s,
1369 NGX_STREAM_INTERNAL_SERVER_ERROR);
1370 return;
1371 }
1372
1373 if (u->connected && !c->read->delayed && !pc->read->delayed) {
1374 ngx_add_timer(c->write, pscf->timeout);
1375 }
1376
1377 return;
1378 }
1379
1380 } else {
1381 if (s->connection->type == SOCK_DGRAM) {
1382
1383 if (pscf->responses == NGX_MAX_INT32_VALUE
1384 || (u->responses >= pscf->responses * u->requests))
1385 {
1386
1387 /*
1388 * successfully terminate timed out UDP session
1389 * if expected number of responses was received
1390 */
1391
1392 handler = c->log->handler;
1393 c->log->handler = NULL;
1394
1395 ngx_log_error(NGX_LOG_INFO, c->log, 0,
1396 "udp timed out"
1397 ", packets from/to client:%ui/%ui"
1398 ", bytes from/to client:%O/%O"
1399 ", bytes from/to upstream:%O/%O",
1400 u->requests, u->responses,
1401 s->received, c->sent, u->received,
1402 pc ? pc->sent : 0);
1403
1404 c->log->handler = handler;
1405
1406 ngx_stream_proxy_finalize(s, NGX_STREAM_OK);
1407 return;
1408 }
1409
1410 ngx_connection_error(pc, NGX_ETIMEDOUT, "upstream timed out");
1411
1412 pc->read->error = 1;
1413
1414 ngx_stream_proxy_finalize(s, NGX_STREAM_BAD_GATEWAY);
1415
1416 return;
1417 }
1418
1419 ngx_connection_error(c, NGX_ETIMEDOUT, "connection timed out");
1420
1421 ngx_stream_proxy_finalize(s, NGX_STREAM_OK);
1422
1423 return;
1424 }
1425
1426 } else if (ev->delayed) {
1427
1428 ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0,
1429 "stream connection delayed");
1430
1431 if (ngx_handle_read_event(ev, 0) != NGX_OK) {
1432 ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
1433 }
1434
1435 return;
1436 }
1437
1438 if (from_upstream && !u->connected) {
1439 return;
1440 }
1441
1442 ngx_stream_proxy_process(s, from_upstream, ev->write);
1443 }
1444
1445
1446 static void
ngx_stream_proxy_connect_handler(ngx_event_t * ev)1447 ngx_stream_proxy_connect_handler(ngx_event_t *ev)
1448 {
1449 ngx_connection_t *c;
1450 ngx_stream_session_t *s;
1451
1452 c = ev->data;
1453 s = c->data;
1454
1455 if (ev->timedout) {
1456 ngx_log_error(NGX_LOG_ERR, c->log, NGX_ETIMEDOUT, "upstream timed out");
1457 ngx_stream_proxy_next_upstream(s);
1458 return;
1459 }
1460
1461 ngx_del_timer(c->write);
1462
1463 ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0,
1464 "stream proxy connect upstream");
1465
1466 if (ngx_stream_proxy_test_connect(c) != NGX_OK) {
1467 ngx_stream_proxy_next_upstream(s);
1468 return;
1469 }
1470
1471 ngx_stream_proxy_init_upstream(s);
1472 }
1473
1474
1475 static ngx_int_t
ngx_stream_proxy_test_connect(ngx_connection_t * c)1476 ngx_stream_proxy_test_connect(ngx_connection_t *c)
1477 {
1478 int err;
1479 socklen_t len;
1480
1481 #if (NGX_HAVE_KQUEUE)
1482
1483 if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
1484 err = c->write->kq_errno ? c->write->kq_errno : c->read->kq_errno;
1485
1486 if (err) {
1487 (void) ngx_connection_error(c, err,
1488 "kevent() reported that connect() failed");
1489 return NGX_ERROR;
1490 }
1491
1492 } else
1493 #endif
1494 {
1495 err = 0;
1496 len = sizeof(int);
1497
1498 /*
1499 * BSDs and Linux return 0 and set a pending error in err
1500 * Solaris returns -1 and sets errno
1501 */
1502
1503 if (getsockopt(c->fd, SOL_SOCKET, SO_ERROR, (void *) &err, &len)
1504 == -1)
1505 {
1506 err = ngx_socket_errno;
1507 }
1508
1509 if (err) {
1510 (void) ngx_connection_error(c, err, "connect() failed");
1511 return NGX_ERROR;
1512 }
1513 }
1514
1515 return NGX_OK;
1516 }
1517
1518
1519 static void
ngx_stream_proxy_process(ngx_stream_session_t * s,ngx_uint_t from_upstream,ngx_uint_t do_write)1520 ngx_stream_proxy_process(ngx_stream_session_t *s, ngx_uint_t from_upstream,
1521 ngx_uint_t do_write)
1522 {
1523 char *recv_action, *send_action;
1524 off_t *received, limit;
1525 size_t size, limit_rate;
1526 ssize_t n;
1527 ngx_buf_t *b;
1528 ngx_int_t rc;
1529 ngx_uint_t flags, *packets;
1530 ngx_msec_t delay;
1531 ngx_chain_t *cl, **ll, **out, **busy;
1532 ngx_connection_t *c, *pc, *src, *dst;
1533 ngx_log_handler_pt handler;
1534 ngx_stream_upstream_t *u;
1535 ngx_stream_proxy_srv_conf_t *pscf;
1536
1537 u = s->upstream;
1538
1539 c = s->connection;
1540 pc = u->connected ? u->peer.connection : NULL;
1541
1542 if (c->type == SOCK_DGRAM && (ngx_terminate || ngx_exiting)) {
1543
1544 /* socket is already closed on worker shutdown */
1545
1546 handler = c->log->handler;
1547 c->log->handler = NULL;
1548
1549 ngx_log_error(NGX_LOG_INFO, c->log, 0, "disconnected on shutdown");
1550
1551 c->log->handler = handler;
1552
1553 ngx_stream_proxy_finalize(s, NGX_STREAM_OK);
1554 return;
1555 }
1556
1557 pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);
1558
1559 if (from_upstream) {
1560 src = pc;
1561 dst = c;
1562 b = &u->upstream_buf;
1563 limit_rate = u->download_rate;
1564 received = &u->received;
1565 packets = &u->responses;
1566 out = &u->downstream_out;
1567 busy = &u->downstream_busy;
1568 recv_action = "proxying and reading from upstream";
1569 send_action = "proxying and sending to client";
1570
1571 } else {
1572 src = c;
1573 dst = pc;
1574 b = &u->downstream_buf;
1575 limit_rate = u->upload_rate;
1576 received = &s->received;
1577 packets = &u->requests;
1578 out = &u->upstream_out;
1579 busy = &u->upstream_busy;
1580 recv_action = "proxying and reading from client";
1581 send_action = "proxying and sending to upstream";
1582 }
1583
1584 for ( ;; ) {
1585
1586 if (do_write && dst) {
1587
1588 if (*out || *busy || dst->buffered) {
1589 c->log->action = send_action;
1590
1591 rc = ngx_stream_top_filter(s, *out, from_upstream);
1592
1593 if (rc == NGX_ERROR) {
1594 ngx_stream_proxy_finalize(s, NGX_STREAM_OK);
1595 return;
1596 }
1597
1598 ngx_chain_update_chains(c->pool, &u->free, busy, out,
1599 (ngx_buf_tag_t) &ngx_stream_proxy_module);
1600
1601 if (*busy == NULL) {
1602 b->pos = b->start;
1603 b->last = b->start;
1604 }
1605 }
1606 }
1607
1608 size = b->end - b->last;
1609
1610 if (size && src->read->ready && !src->read->delayed
1611 && !src->read->error)
1612 {
1613 if (limit_rate) {
1614 limit = (off_t) limit_rate * (ngx_time() - u->start_sec + 1)
1615 - *received;
1616
1617 if (limit <= 0) {
1618 src->read->delayed = 1;
1619 delay = (ngx_msec_t) (- limit * 1000 / limit_rate + 1);
1620 ngx_add_timer(src->read, delay);
1621 break;
1622 }
1623
1624 if (c->type == SOCK_STREAM && (off_t) size > limit) {
1625 size = (size_t) limit;
1626 }
1627 }
1628
1629 c->log->action = recv_action;
1630
1631 n = src->recv(src, b->last, size);
1632
1633 if (n == NGX_AGAIN) {
1634 break;
1635 }
1636
1637 if (n == NGX_ERROR) {
1638 src->read->eof = 1;
1639 n = 0;
1640 }
1641
1642 if (n >= 0) {
1643 if (limit_rate) {
1644 delay = (ngx_msec_t) (n * 1000 / limit_rate);
1645
1646 if (delay > 0) {
1647 src->read->delayed = 1;
1648 ngx_add_timer(src->read, delay);
1649 }
1650 }
1651
1652 if (from_upstream) {
1653 if (u->state->first_byte_time == (ngx_msec_t) -1) {
1654 u->state->first_byte_time = ngx_current_msec
1655 - u->start_time;
1656 }
1657 }
1658
1659 for (ll = out; *ll; ll = &(*ll)->next) { /* void */ }
1660
1661 cl = ngx_chain_get_free_buf(c->pool, &u->free);
1662 if (cl == NULL) {
1663 ngx_stream_proxy_finalize(s,
1664 NGX_STREAM_INTERNAL_SERVER_ERROR);
1665 return;
1666 }
1667
1668 *ll = cl;
1669
1670 cl->buf->pos = b->last;
1671 cl->buf->last = b->last + n;
1672 cl->buf->tag = (ngx_buf_tag_t) &ngx_stream_proxy_module;
1673
1674 cl->buf->temporary = (n ? 1 : 0);
1675 cl->buf->last_buf = src->read->eof;
1676 cl->buf->flush = 1;
1677
1678 (*packets)++;
1679 *received += n;
1680 b->last += n;
1681 do_write = 1;
1682
1683 continue;
1684 }
1685 }
1686
1687 break;
1688 }
1689
1690 c->log->action = "proxying connection";
1691
1692 if (ngx_stream_proxy_test_finalize(s, from_upstream) == NGX_OK) {
1693 return;
1694 }
1695
1696 flags = src->read->eof ? NGX_CLOSE_EVENT : 0;
1697
1698 if (ngx_handle_read_event(src->read, flags) != NGX_OK) {
1699 ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
1700 return;
1701 }
1702
1703 if (dst) {
1704 if (ngx_handle_write_event(dst->write, 0) != NGX_OK) {
1705 ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
1706 return;
1707 }
1708
1709 if (!c->read->delayed && !pc->read->delayed) {
1710 ngx_add_timer(c->write, pscf->timeout);
1711
1712 } else if (c->write->timer_set) {
1713 ngx_del_timer(c->write);
1714 }
1715 }
1716 }
1717
1718
1719 static ngx_int_t
ngx_stream_proxy_test_finalize(ngx_stream_session_t * s,ngx_uint_t from_upstream)1720 ngx_stream_proxy_test_finalize(ngx_stream_session_t *s,
1721 ngx_uint_t from_upstream)
1722 {
1723 ngx_connection_t *c, *pc;
1724 ngx_log_handler_pt handler;
1725 ngx_stream_upstream_t *u;
1726 ngx_stream_proxy_srv_conf_t *pscf;
1727
1728 pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);
1729
1730 c = s->connection;
1731 u = s->upstream;
1732 pc = u->connected ? u->peer.connection : NULL;
1733
1734 if (c->type == SOCK_DGRAM) {
1735
1736 if (pscf->requests && u->requests < pscf->requests) {
1737 return NGX_DECLINED;
1738 }
1739
1740 if (pscf->requests) {
1741 ngx_delete_udp_connection(c);
1742 }
1743
1744 if (pscf->responses == NGX_MAX_INT32_VALUE
1745 || u->responses < pscf->responses * u->requests)
1746 {
1747 return NGX_DECLINED;
1748 }
1749
1750 if (pc == NULL || c->buffered || pc->buffered) {
1751 return NGX_DECLINED;
1752 }
1753
1754 handler = c->log->handler;
1755 c->log->handler = NULL;
1756
1757 ngx_log_error(NGX_LOG_INFO, c->log, 0,
1758 "udp done"
1759 ", packets from/to client:%ui/%ui"
1760 ", bytes from/to client:%O/%O"
1761 ", bytes from/to upstream:%O/%O",
1762 u->requests, u->responses,
1763 s->received, c->sent, u->received, pc ? pc->sent : 0);
1764
1765 c->log->handler = handler;
1766
1767 ngx_stream_proxy_finalize(s, NGX_STREAM_OK);
1768
1769 return NGX_OK;
1770 }
1771
1772 /* c->type == SOCK_STREAM */
1773
1774 if (pc == NULL
1775 || (!c->read->eof && !pc->read->eof)
1776 || (!c->read->eof && c->buffered)
1777 || (!pc->read->eof && pc->buffered))
1778 {
1779 return NGX_DECLINED;
1780 }
1781
1782 handler = c->log->handler;
1783 c->log->handler = NULL;
1784
1785 ngx_log_error(NGX_LOG_INFO, c->log, 0,
1786 "%s disconnected"
1787 ", bytes from/to client:%O/%O"
1788 ", bytes from/to upstream:%O/%O",
1789 from_upstream ? "upstream" : "client",
1790 s->received, c->sent, u->received, pc ? pc->sent : 0);
1791
1792 c->log->handler = handler;
1793
1794 ngx_stream_proxy_finalize(s, NGX_STREAM_OK);
1795
1796 return NGX_OK;
1797 }
1798
1799
1800 static void
ngx_stream_proxy_next_upstream(ngx_stream_session_t * s)1801 ngx_stream_proxy_next_upstream(ngx_stream_session_t *s)
1802 {
1803 ngx_msec_t timeout;
1804 ngx_connection_t *pc;
1805 ngx_stream_upstream_t *u;
1806 ngx_stream_proxy_srv_conf_t *pscf;
1807
1808 ngx_log_debug0(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
1809 "stream proxy next upstream");
1810
1811 u = s->upstream;
1812 pc = u->peer.connection;
1813
1814 if (pc && pc->buffered) {
1815 ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
1816 "buffered data on next upstream");
1817 ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
1818 return;
1819 }
1820
1821 if (s->connection->type == SOCK_DGRAM) {
1822 u->upstream_out = NULL;
1823 }
1824
1825 if (u->peer.sockaddr) {
1826 u->peer.free(&u->peer, u->peer.data, NGX_PEER_FAILED);
1827 u->peer.sockaddr = NULL;
1828 }
1829
1830 pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);
1831
1832 timeout = pscf->next_upstream_timeout;
1833
1834 if (u->peer.tries == 0
1835 || !pscf->next_upstream
1836 || (timeout && ngx_current_msec - u->peer.start_time >= timeout))
1837 {
1838 ngx_stream_proxy_finalize(s, NGX_STREAM_BAD_GATEWAY);
1839 return;
1840 }
1841
1842 if (pc) {
1843 ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
1844 "close proxy upstream connection: %d", pc->fd);
1845
1846 #if (NGX_STREAM_SSL)
1847 if (pc->ssl) {
1848 pc->ssl->no_wait_shutdown = 1;
1849 pc->ssl->no_send_shutdown = 1;
1850
1851 (void) ngx_ssl_shutdown(pc);
1852 }
1853 #endif
1854
1855 u->state->bytes_received = u->received;
1856 u->state->bytes_sent = pc->sent;
1857
1858 ngx_close_connection(pc);
1859 u->peer.connection = NULL;
1860 }
1861
1862 ngx_stream_proxy_connect(s);
1863 }
1864
1865
1866 static void
ngx_stream_proxy_finalize(ngx_stream_session_t * s,ngx_uint_t rc)1867 ngx_stream_proxy_finalize(ngx_stream_session_t *s, ngx_uint_t rc)
1868 {
1869 ngx_uint_t state;
1870 ngx_connection_t *pc;
1871 ngx_stream_upstream_t *u;
1872
1873 ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
1874 "finalize stream proxy: %i", rc);
1875
1876 u = s->upstream;
1877
1878 if (u == NULL) {
1879 goto noupstream;
1880 }
1881
1882 if (u->resolved && u->resolved->ctx) {
1883 ngx_resolve_name_done(u->resolved->ctx);
1884 u->resolved->ctx = NULL;
1885 }
1886
1887 pc = u->peer.connection;
1888
1889 if (u->state) {
1890 if (u->state->response_time == (ngx_msec_t) -1) {
1891 u->state->response_time = ngx_current_msec - u->start_time;
1892 }
1893
1894 if (pc) {
1895 u->state->bytes_received = u->received;
1896 u->state->bytes_sent = pc->sent;
1897 }
1898 }
1899
1900 if (u->peer.free && u->peer.sockaddr) {
1901 state = 0;
1902
1903 if (pc && pc->type == SOCK_DGRAM
1904 && (pc->read->error || pc->write->error))
1905 {
1906 state = NGX_PEER_FAILED;
1907 }
1908
1909 u->peer.free(&u->peer, u->peer.data, state);
1910 u->peer.sockaddr = NULL;
1911 }
1912
1913 if (pc) {
1914 ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
1915 "close stream proxy upstream connection: %d", pc->fd);
1916
1917 #if (NGX_STREAM_SSL)
1918 if (pc->ssl) {
1919 pc->ssl->no_wait_shutdown = 1;
1920 (void) ngx_ssl_shutdown(pc);
1921 }
1922 #endif
1923
1924 ngx_close_connection(pc);
1925 u->peer.connection = NULL;
1926 }
1927
1928 noupstream:
1929
1930 ngx_stream_finalize_session(s, rc);
1931 }
1932
1933
1934 static u_char *
ngx_stream_proxy_log_error(ngx_log_t * log,u_char * buf,size_t len)1935 ngx_stream_proxy_log_error(ngx_log_t *log, u_char *buf, size_t len)
1936 {
1937 u_char *p;
1938 ngx_connection_t *pc;
1939 ngx_stream_session_t *s;
1940 ngx_stream_upstream_t *u;
1941
1942 s = log->data;
1943
1944 u = s->upstream;
1945
1946 p = buf;
1947
1948 if (u->peer.name) {
1949 p = ngx_snprintf(p, len, ", upstream: \"%V\"", u->peer.name);
1950 len -= p - buf;
1951 }
1952
1953 pc = u->peer.connection;
1954
1955 p = ngx_snprintf(p, len,
1956 ", bytes from/to client:%O/%O"
1957 ", bytes from/to upstream:%O/%O",
1958 s->received, s->connection->sent,
1959 u->received, pc ? pc->sent : 0);
1960
1961 return p;
1962 }
1963
1964
1965 static void *
ngx_stream_proxy_create_srv_conf(ngx_conf_t * cf)1966 ngx_stream_proxy_create_srv_conf(ngx_conf_t *cf)
1967 {
1968 ngx_stream_proxy_srv_conf_t *conf;
1969
1970 conf = ngx_pcalloc(cf->pool, sizeof(ngx_stream_proxy_srv_conf_t));
1971 if (conf == NULL) {
1972 return NULL;
1973 }
1974
1975 /*
1976 * set by ngx_pcalloc():
1977 *
1978 * conf->ssl_protocols = 0;
1979 * conf->ssl_ciphers = { 0, NULL };
1980 * conf->ssl_name = NULL;
1981 * conf->ssl_trusted_certificate = { 0, NULL };
1982 * conf->ssl_crl = { 0, NULL };
1983 * conf->ssl_certificate = { 0, NULL };
1984 * conf->ssl_certificate_key = { 0, NULL };
1985 *
1986 * conf->upload_rate = NULL;
1987 * conf->download_rate = NULL;
1988 * conf->ssl = NULL;
1989 * conf->upstream = NULL;
1990 * conf->upstream_value = NULL;
1991 */
1992
1993 conf->connect_timeout = NGX_CONF_UNSET_MSEC;
1994 conf->timeout = NGX_CONF_UNSET_MSEC;
1995 conf->next_upstream_timeout = NGX_CONF_UNSET_MSEC;
1996 conf->buffer_size = NGX_CONF_UNSET_SIZE;
1997 conf->requests = NGX_CONF_UNSET_UINT;
1998 conf->responses = NGX_CONF_UNSET_UINT;
1999 conf->next_upstream_tries = NGX_CONF_UNSET_UINT;
2000 conf->next_upstream = NGX_CONF_UNSET;
2001 conf->proxy_protocol = NGX_CONF_UNSET;
2002 conf->local = NGX_CONF_UNSET_PTR;
2003 conf->socket_keepalive = NGX_CONF_UNSET;
2004
2005 #if (NGX_STREAM_SSL)
2006 conf->ssl_enable = NGX_CONF_UNSET;
2007 conf->ssl_session_reuse = NGX_CONF_UNSET;
2008 conf->ssl_server_name = NGX_CONF_UNSET;
2009 conf->ssl_verify = NGX_CONF_UNSET;
2010 conf->ssl_verify_depth = NGX_CONF_UNSET_UINT;
2011 conf->ssl_passwords = NGX_CONF_UNSET_PTR;
2012 conf->ssl_conf_commands = NGX_CONF_UNSET_PTR;
2013 #endif
2014
2015 return conf;
2016 }
2017
2018
2019 static char *
ngx_stream_proxy_merge_srv_conf(ngx_conf_t * cf,void * parent,void * child)2020 ngx_stream_proxy_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
2021 {
2022 ngx_stream_proxy_srv_conf_t *prev = parent;
2023 ngx_stream_proxy_srv_conf_t *conf = child;
2024
2025 ngx_conf_merge_msec_value(conf->connect_timeout,
2026 prev->connect_timeout, 60000);
2027
2028 ngx_conf_merge_msec_value(conf->timeout,
2029 prev->timeout, 10 * 60000);
2030
2031 ngx_conf_merge_msec_value(conf->next_upstream_timeout,
2032 prev->next_upstream_timeout, 0);
2033
2034 ngx_conf_merge_size_value(conf->buffer_size,
2035 prev->buffer_size, 16384);
2036
2037 if (conf->upload_rate == NULL) {
2038 conf->upload_rate = prev->upload_rate;
2039 }
2040
2041 if (conf->download_rate == NULL) {
2042 conf->download_rate = prev->download_rate;
2043 }
2044
2045 ngx_conf_merge_uint_value(conf->requests,
2046 prev->requests, 0);
2047
2048 ngx_conf_merge_uint_value(conf->responses,
2049 prev->responses, NGX_MAX_INT32_VALUE);
2050
2051 ngx_conf_merge_uint_value(conf->next_upstream_tries,
2052 prev->next_upstream_tries, 0);
2053
2054 ngx_conf_merge_value(conf->next_upstream, prev->next_upstream, 1);
2055
2056 ngx_conf_merge_value(conf->proxy_protocol, prev->proxy_protocol, 0);
2057
2058 ngx_conf_merge_ptr_value(conf->local, prev->local, NULL);
2059
2060 ngx_conf_merge_value(conf->socket_keepalive,
2061 prev->socket_keepalive, 0);
2062
2063 #if (NGX_STREAM_SSL)
2064
2065 ngx_conf_merge_value(conf->ssl_enable, prev->ssl_enable, 0);
2066
2067 ngx_conf_merge_value(conf->ssl_session_reuse,
2068 prev->ssl_session_reuse, 1);
2069
2070 ngx_conf_merge_bitmask_value(conf->ssl_protocols, prev->ssl_protocols,
2071 (NGX_CONF_BITMASK_SET|NGX_SSL_TLSv1
2072 |NGX_SSL_TLSv1_1|NGX_SSL_TLSv1_2));
2073
2074 ngx_conf_merge_str_value(conf->ssl_ciphers, prev->ssl_ciphers, "DEFAULT");
2075
2076 if (conf->ssl_name == NULL) {
2077 conf->ssl_name = prev->ssl_name;
2078 }
2079
2080 ngx_conf_merge_value(conf->ssl_server_name, prev->ssl_server_name, 0);
2081
2082 ngx_conf_merge_value(conf->ssl_verify, prev->ssl_verify, 0);
2083
2084 ngx_conf_merge_uint_value(conf->ssl_verify_depth,
2085 prev->ssl_verify_depth, 1);
2086
2087 ngx_conf_merge_str_value(conf->ssl_trusted_certificate,
2088 prev->ssl_trusted_certificate, "");
2089
2090 ngx_conf_merge_str_value(conf->ssl_crl, prev->ssl_crl, "");
2091
2092 ngx_conf_merge_str_value(conf->ssl_certificate,
2093 prev->ssl_certificate, "");
2094
2095 ngx_conf_merge_str_value(conf->ssl_certificate_key,
2096 prev->ssl_certificate_key, "");
2097
2098 ngx_conf_merge_ptr_value(conf->ssl_passwords, prev->ssl_passwords, NULL);
2099
2100 ngx_conf_merge_ptr_value(conf->ssl_conf_commands,
2101 prev->ssl_conf_commands, NULL);
2102
2103 if (conf->ssl_enable && ngx_stream_proxy_set_ssl(cf, conf) != NGX_OK) {
2104 return NGX_CONF_ERROR;
2105 }
2106
2107 #endif
2108
2109 return NGX_CONF_OK;
2110 }
2111
2112
2113 #if (NGX_STREAM_SSL)
2114
2115 static ngx_int_t
ngx_stream_proxy_set_ssl(ngx_conf_t * cf,ngx_stream_proxy_srv_conf_t * pscf)2116 ngx_stream_proxy_set_ssl(ngx_conf_t *cf, ngx_stream_proxy_srv_conf_t *pscf)
2117 {
2118 ngx_pool_cleanup_t *cln;
2119
2120 pscf->ssl = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_t));
2121 if (pscf->ssl == NULL) {
2122 return NGX_ERROR;
2123 }
2124
2125 pscf->ssl->log = cf->log;
2126
2127 if (ngx_ssl_create(pscf->ssl, pscf->ssl_protocols, NULL) != NGX_OK) {
2128 return NGX_ERROR;
2129 }
2130
2131 cln = ngx_pool_cleanup_add(cf->pool, 0);
2132 if (cln == NULL) {
2133 ngx_ssl_cleanup_ctx(pscf->ssl);
2134 return NGX_ERROR;
2135 }
2136
2137 cln->handler = ngx_ssl_cleanup_ctx;
2138 cln->data = pscf->ssl;
2139
2140 if (pscf->ssl_certificate.len) {
2141
2142 if (pscf->ssl_certificate_key.len == 0) {
2143 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
2144 "no \"proxy_ssl_certificate_key\" is defined "
2145 "for certificate \"%V\"", &pscf->ssl_certificate);
2146 return NGX_ERROR;
2147 }
2148
2149 if (ngx_ssl_certificate(cf, pscf->ssl, &pscf->ssl_certificate,
2150 &pscf->ssl_certificate_key, pscf->ssl_passwords)
2151 != NGX_OK)
2152 {
2153 return NGX_ERROR;
2154 }
2155 }
2156
2157 if (ngx_ssl_ciphers(cf, pscf->ssl, &pscf->ssl_ciphers, 0) != NGX_OK) {
2158 return NGX_ERROR;
2159 }
2160
2161 if (pscf->ssl_verify) {
2162 if (pscf->ssl_trusted_certificate.len == 0) {
2163 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
2164 "no proxy_ssl_trusted_certificate for proxy_ssl_verify");
2165 return NGX_ERROR;
2166 }
2167
2168 if (ngx_ssl_trusted_certificate(cf, pscf->ssl,
2169 &pscf->ssl_trusted_certificate,
2170 pscf->ssl_verify_depth)
2171 != NGX_OK)
2172 {
2173 return NGX_ERROR;
2174 }
2175
2176 if (ngx_ssl_crl(cf, pscf->ssl, &pscf->ssl_crl) != NGX_OK) {
2177 return NGX_ERROR;
2178 }
2179 }
2180
2181 if (ngx_ssl_client_session_cache(cf, pscf->ssl, pscf->ssl_session_reuse)
2182 != NGX_OK)
2183 {
2184 return NGX_ERROR;
2185 }
2186
2187 if (ngx_ssl_conf_commands(cf, pscf->ssl, pscf->ssl_conf_commands)
2188 != NGX_OK)
2189 {
2190 return NGX_ERROR;
2191 }
2192
2193 return NGX_OK;
2194 }
2195
2196 #endif
2197
2198
2199 static char *
ngx_stream_proxy_pass(ngx_conf_t * cf,ngx_command_t * cmd,void * conf)2200 ngx_stream_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
2201 {
2202 ngx_stream_proxy_srv_conf_t *pscf = conf;
2203
2204 ngx_url_t u;
2205 ngx_str_t *value, *url;
2206 ngx_stream_complex_value_t cv;
2207 ngx_stream_core_srv_conf_t *cscf;
2208 ngx_stream_compile_complex_value_t ccv;
2209
2210 if (pscf->upstream || pscf->upstream_value) {
2211 return "is duplicate";
2212 }
2213
2214 cscf = ngx_stream_conf_get_module_srv_conf(cf, ngx_stream_core_module);
2215
2216 cscf->handler = ngx_stream_proxy_handler;
2217
2218 value = cf->args->elts;
2219
2220 url = &value[1];
2221
2222 ngx_memzero(&ccv, sizeof(ngx_stream_compile_complex_value_t));
2223
2224 ccv.cf = cf;
2225 ccv.value = url;
2226 ccv.complex_value = &cv;
2227
2228 if (ngx_stream_compile_complex_value(&ccv) != NGX_OK) {
2229 return NGX_CONF_ERROR;
2230 }
2231
2232 if (cv.lengths) {
2233 pscf->upstream_value = ngx_palloc(cf->pool,
2234 sizeof(ngx_stream_complex_value_t));
2235 if (pscf->upstream_value == NULL) {
2236 return NGX_CONF_ERROR;
2237 }
2238
2239 *pscf->upstream_value = cv;
2240
2241 return NGX_CONF_OK;
2242 }
2243
2244 ngx_memzero(&u, sizeof(ngx_url_t));
2245
2246 u.url = *url;
2247 u.no_resolve = 1;
2248
2249 pscf->upstream = ngx_stream_upstream_add(cf, &u, 0);
2250 if (pscf->upstream == NULL) {
2251 return NGX_CONF_ERROR;
2252 }
2253
2254 return NGX_CONF_OK;
2255 }
2256
2257
2258 static char *
ngx_stream_proxy_bind(ngx_conf_t * cf,ngx_command_t * cmd,void * conf)2259 ngx_stream_proxy_bind(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
2260 {
2261 ngx_stream_proxy_srv_conf_t *pscf = conf;
2262
2263 ngx_int_t rc;
2264 ngx_str_t *value;
2265 ngx_stream_complex_value_t cv;
2266 ngx_stream_upstream_local_t *local;
2267 ngx_stream_compile_complex_value_t ccv;
2268
2269 if (pscf->local != NGX_CONF_UNSET_PTR) {
2270 return "is duplicate";
2271 }
2272
2273 value = cf->args->elts;
2274
2275 if (cf->args->nelts == 2 && ngx_strcmp(value[1].data, "off") == 0) {
2276 pscf->local = NULL;
2277 return NGX_CONF_OK;
2278 }
2279
2280 ngx_memzero(&ccv, sizeof(ngx_stream_compile_complex_value_t));
2281
2282 ccv.cf = cf;
2283 ccv.value = &value[1];
2284 ccv.complex_value = &cv;
2285
2286 if (ngx_stream_compile_complex_value(&ccv) != NGX_OK) {
2287 return NGX_CONF_ERROR;
2288 }
2289
2290 local = ngx_pcalloc(cf->pool, sizeof(ngx_stream_upstream_local_t));
2291 if (local == NULL) {
2292 return NGX_CONF_ERROR;
2293 }
2294
2295 pscf->local = local;
2296
2297 if (cv.lengths) {
2298 local->value = ngx_palloc(cf->pool, sizeof(ngx_stream_complex_value_t));
2299 if (local->value == NULL) {
2300 return NGX_CONF_ERROR;
2301 }
2302
2303 *local->value = cv;
2304
2305 } else {
2306 local->addr = ngx_palloc(cf->pool, sizeof(ngx_addr_t));
2307 if (local->addr == NULL) {
2308 return NGX_CONF_ERROR;
2309 }
2310
2311 rc = ngx_parse_addr_port(cf->pool, local->addr, value[1].data,
2312 value[1].len);
2313
2314 switch (rc) {
2315 case NGX_OK:
2316 local->addr->name = value[1];
2317 break;
2318
2319 case NGX_DECLINED:
2320 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2321 "invalid address \"%V\"", &value[1]);
2322 /* fall through */
2323
2324 default:
2325 return NGX_CONF_ERROR;
2326 }
2327 }
2328
2329 if (cf->args->nelts > 2) {
2330 if (ngx_strcmp(value[2].data, "transparent") == 0) {
2331 #if (NGX_HAVE_TRANSPARENT_PROXY)
2332 ngx_core_conf_t *ccf;
2333
2334 ccf = (ngx_core_conf_t *) ngx_get_conf(cf->cycle->conf_ctx,
2335 ngx_core_module);
2336
2337 ccf->transparent = 1;
2338 local->transparent = 1;
2339 #else
2340 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2341 "transparent proxying is not supported "
2342 "on this platform, ignored");
2343 #endif
2344 } else {
2345 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2346 "invalid parameter \"%V\"", &value[2]);
2347 return NGX_CONF_ERROR;
2348 }
2349 }
2350
2351 return NGX_CONF_OK;
2352 }
2353