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