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