Back to home page

Nginx displayed by LXR

Source navigation ]
Diff markup ]
Identifier search ]
general search ]
 
 
Version: nginx-1.13.12 ]​[ nginx-1.12.2 ]​

0001 
0002 /*
0003  * Copyright (C) Roman Arutyunyan
0004  * Copyright (C) Nginx, Inc.
0005  */
0006 
0007 
0008 #include <ngx_config.h>
0009 #include <ngx_core.h>
0010 #include <ngx_stream.h>
0011 
0012 
0013 typedef struct {
0014     ngx_addr_t                      *addr;
0015     ngx_stream_complex_value_t      *value;
0016 #if (NGX_HAVE_TRANSPARENT_PROXY)
0017     ngx_uint_t                       transparent; /* unsigned  transparent:1; */
0018 #endif
0019 } ngx_stream_upstream_local_t;
0020 
0021 
0022 typedef struct {
0023     ngx_msec_t                       connect_timeout;
0024     ngx_msec_t                       timeout;
0025     ngx_msec_t                       next_upstream_timeout;
0026     size_t                           buffer_size;
0027     size_t                           upload_rate;
0028     size_t                           download_rate;
0029     ngx_uint_t                       responses;
0030     ngx_uint_t                       next_upstream_tries;
0031     ngx_flag_t                       next_upstream;
0032     ngx_flag_t                       proxy_protocol;
0033     ngx_stream_upstream_local_t     *local;
0034 
0035 #if (NGX_STREAM_SSL)
0036     ngx_flag_t                       ssl_enable;
0037     ngx_flag_t                       ssl_session_reuse;
0038     ngx_uint_t                       ssl_protocols;
0039     ngx_str_t                        ssl_ciphers;
0040     ngx_stream_complex_value_t      *ssl_name;
0041     ngx_flag_t                       ssl_server_name;
0042 
0043     ngx_flag_t                       ssl_verify;
0044     ngx_uint_t                       ssl_verify_depth;
0045     ngx_str_t                        ssl_trusted_certificate;
0046     ngx_str_t                        ssl_crl;
0047     ngx_str_t                        ssl_certificate;
0048     ngx_str_t                        ssl_certificate_key;
0049     ngx_array_t                     *ssl_passwords;
0050 
0051     ngx_ssl_t                       *ssl;
0052 #endif
0053 
0054     ngx_stream_upstream_srv_conf_t  *upstream;
0055     ngx_stream_complex_value_t      *upstream_value;
0056 } ngx_stream_proxy_srv_conf_t;
0057 
0058 
0059 static void ngx_stream_proxy_handler(ngx_stream_session_t *s);
0060 static ngx_int_t ngx_stream_proxy_eval(ngx_stream_session_t *s,
0061     ngx_stream_proxy_srv_conf_t *pscf);
0062 static ngx_int_t ngx_stream_proxy_set_local(ngx_stream_session_t *s,
0063     ngx_stream_upstream_t *u, ngx_stream_upstream_local_t *local);
0064 static void ngx_stream_proxy_connect(ngx_stream_session_t *s);
0065 static void ngx_stream_proxy_init_upstream(ngx_stream_session_t *s);
0066 static void ngx_stream_proxy_resolve_handler(ngx_resolver_ctx_t *ctx);
0067 static void ngx_stream_proxy_upstream_handler(ngx_event_t *ev);
0068 static void ngx_stream_proxy_downstream_handler(ngx_event_t *ev);
0069 static void ngx_stream_proxy_process_connection(ngx_event_t *ev,
0070     ngx_uint_t from_upstream);
0071 static void ngx_stream_proxy_connect_handler(ngx_event_t *ev);
0072 static ngx_int_t ngx_stream_proxy_test_connect(ngx_connection_t *c);
0073 static void ngx_stream_proxy_process(ngx_stream_session_t *s,
0074     ngx_uint_t from_upstream, ngx_uint_t do_write);
0075 static void ngx_stream_proxy_next_upstream(ngx_stream_session_t *s);
0076 static void ngx_stream_proxy_finalize(ngx_stream_session_t *s, ngx_uint_t rc);
0077 static u_char *ngx_stream_proxy_log_error(ngx_log_t *log, u_char *buf,
0078     size_t len);
0079 
0080 static void *ngx_stream_proxy_create_srv_conf(ngx_conf_t *cf);
0081 static char *ngx_stream_proxy_merge_srv_conf(ngx_conf_t *cf, void *parent,
0082     void *child);
0083 static char *ngx_stream_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd,
0084     void *conf);
0085 static char *ngx_stream_proxy_bind(ngx_conf_t *cf, ngx_command_t *cmd,
0086     void *conf);
0087 
0088 #if (NGX_STREAM_SSL)
0089 
0090 static ngx_int_t ngx_stream_proxy_send_proxy_protocol(ngx_stream_session_t *s);
0091 static char *ngx_stream_proxy_ssl_password_file(ngx_conf_t *cf,
0092     ngx_command_t *cmd, void *conf);
0093 static void ngx_stream_proxy_ssl_init_connection(ngx_stream_session_t *s);
0094 static void ngx_stream_proxy_ssl_handshake(ngx_connection_t *pc);
0095 static ngx_int_t ngx_stream_proxy_ssl_name(ngx_stream_session_t *s);
0096 static ngx_int_t ngx_stream_proxy_set_ssl(ngx_conf_t *cf,
0097     ngx_stream_proxy_srv_conf_t *pscf);
0098 
0099 
0100 static ngx_conf_bitmask_t  ngx_stream_proxy_ssl_protocols[] = {
0101     { ngx_string("SSLv2"), NGX_SSL_SSLv2 },
0102     { ngx_string("SSLv3"), NGX_SSL_SSLv3 },
0103     { ngx_string("TLSv1"), NGX_SSL_TLSv1 },
0104     { ngx_string("TLSv1.1"), NGX_SSL_TLSv1_1 },
0105     { ngx_string("TLSv1.2"), NGX_SSL_TLSv1_2 },
0106     { ngx_string("TLSv1.3"), NGX_SSL_TLSv1_3 },
0107     { ngx_null_string, 0 }
0108 };
0109 
0110 #endif
0111 
0112 
0113 static ngx_conf_deprecated_t  ngx_conf_deprecated_proxy_downstream_buffer = {
0114     ngx_conf_deprecated, "proxy_downstream_buffer", "proxy_buffer_size"
0115 };
0116 
0117 static ngx_conf_deprecated_t  ngx_conf_deprecated_proxy_upstream_buffer = {
0118     ngx_conf_deprecated, "proxy_upstream_buffer", "proxy_buffer_size"
0119 };
0120 
0121 
0122 static ngx_command_t  ngx_stream_proxy_commands[] = {
0123 
0124     { ngx_string("proxy_pass"),
0125       NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
0126       ngx_stream_proxy_pass,
0127       NGX_STREAM_SRV_CONF_OFFSET,
0128       0,
0129       NULL },
0130 
0131     { ngx_string("proxy_bind"),
0132       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE12,
0133       ngx_stream_proxy_bind,
0134       NGX_STREAM_SRV_CONF_OFFSET,
0135       0,
0136       NULL },
0137 
0138     { ngx_string("proxy_connect_timeout"),
0139       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
0140       ngx_conf_set_msec_slot,
0141       NGX_STREAM_SRV_CONF_OFFSET,
0142       offsetof(ngx_stream_proxy_srv_conf_t, connect_timeout),
0143       NULL },
0144 
0145     { ngx_string("proxy_timeout"),
0146       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
0147       ngx_conf_set_msec_slot,
0148       NGX_STREAM_SRV_CONF_OFFSET,
0149       offsetof(ngx_stream_proxy_srv_conf_t, timeout),
0150       NULL },
0151 
0152     { ngx_string("proxy_buffer_size"),
0153       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
0154       ngx_conf_set_size_slot,
0155       NGX_STREAM_SRV_CONF_OFFSET,
0156       offsetof(ngx_stream_proxy_srv_conf_t, buffer_size),
0157       NULL },
0158 
0159     { ngx_string("proxy_downstream_buffer"),
0160       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
0161       ngx_conf_set_size_slot,
0162       NGX_STREAM_SRV_CONF_OFFSET,
0163       offsetof(ngx_stream_proxy_srv_conf_t, buffer_size),
0164       &ngx_conf_deprecated_proxy_downstream_buffer },
0165 
0166     { ngx_string("proxy_upstream_buffer"),
0167       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
0168       ngx_conf_set_size_slot,
0169       NGX_STREAM_SRV_CONF_OFFSET,
0170       offsetof(ngx_stream_proxy_srv_conf_t, buffer_size),
0171       &ngx_conf_deprecated_proxy_upstream_buffer },
0172 
0173     { ngx_string("proxy_upload_rate"),
0174       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
0175       ngx_conf_set_size_slot,
0176       NGX_STREAM_SRV_CONF_OFFSET,
0177       offsetof(ngx_stream_proxy_srv_conf_t, upload_rate),
0178       NULL },
0179 
0180     { ngx_string("proxy_download_rate"),
0181       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
0182       ngx_conf_set_size_slot,
0183       NGX_STREAM_SRV_CONF_OFFSET,
0184       offsetof(ngx_stream_proxy_srv_conf_t, download_rate),
0185       NULL },
0186 
0187     { ngx_string("proxy_responses"),
0188       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
0189       ngx_conf_set_num_slot,
0190       NGX_STREAM_SRV_CONF_OFFSET,
0191       offsetof(ngx_stream_proxy_srv_conf_t, responses),
0192       NULL },
0193 
0194     { ngx_string("proxy_next_upstream"),
0195       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
0196       ngx_conf_set_flag_slot,
0197       NGX_STREAM_SRV_CONF_OFFSET,
0198       offsetof(ngx_stream_proxy_srv_conf_t, next_upstream),
0199       NULL },
0200 
0201     { ngx_string("proxy_next_upstream_tries"),
0202       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
0203       ngx_conf_set_num_slot,
0204       NGX_STREAM_SRV_CONF_OFFSET,
0205       offsetof(ngx_stream_proxy_srv_conf_t, next_upstream_tries),
0206       NULL },
0207 
0208     { ngx_string("proxy_next_upstream_timeout"),
0209       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
0210       ngx_conf_set_msec_slot,
0211       NGX_STREAM_SRV_CONF_OFFSET,
0212       offsetof(ngx_stream_proxy_srv_conf_t, next_upstream_timeout),
0213       NULL },
0214 
0215     { ngx_string("proxy_protocol"),
0216       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
0217       ngx_conf_set_flag_slot,
0218       NGX_STREAM_SRV_CONF_OFFSET,
0219       offsetof(ngx_stream_proxy_srv_conf_t, proxy_protocol),
0220       NULL },
0221 
0222 #if (NGX_STREAM_SSL)
0223 
0224     { ngx_string("proxy_ssl"),
0225       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
0226       ngx_conf_set_flag_slot,
0227       NGX_STREAM_SRV_CONF_OFFSET,
0228       offsetof(ngx_stream_proxy_srv_conf_t, ssl_enable),
0229       NULL },
0230 
0231     { ngx_string("proxy_ssl_session_reuse"),
0232       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
0233       ngx_conf_set_flag_slot,
0234       NGX_STREAM_SRV_CONF_OFFSET,
0235       offsetof(ngx_stream_proxy_srv_conf_t, ssl_session_reuse),
0236       NULL },
0237 
0238     { ngx_string("proxy_ssl_protocols"),
0239       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_1MORE,
0240       ngx_conf_set_bitmask_slot,
0241       NGX_STREAM_SRV_CONF_OFFSET,
0242       offsetof(ngx_stream_proxy_srv_conf_t, ssl_protocols),
0243       &ngx_stream_proxy_ssl_protocols },
0244 
0245     { ngx_string("proxy_ssl_ciphers"),
0246       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
0247       ngx_conf_set_str_slot,
0248       NGX_STREAM_SRV_CONF_OFFSET,
0249       offsetof(ngx_stream_proxy_srv_conf_t, ssl_ciphers),
0250       NULL },
0251 
0252     { ngx_string("proxy_ssl_name"),
0253       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
0254       ngx_stream_set_complex_value_slot,
0255       NGX_STREAM_SRV_CONF_OFFSET,
0256       offsetof(ngx_stream_proxy_srv_conf_t, ssl_name),
0257       NULL },
0258 
0259     { ngx_string("proxy_ssl_server_name"),
0260       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
0261       ngx_conf_set_flag_slot,
0262       NGX_STREAM_SRV_CONF_OFFSET,
0263       offsetof(ngx_stream_proxy_srv_conf_t, ssl_server_name),
0264       NULL },
0265 
0266     { ngx_string("proxy_ssl_verify"),
0267       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
0268       ngx_conf_set_flag_slot,
0269       NGX_STREAM_SRV_CONF_OFFSET,
0270       offsetof(ngx_stream_proxy_srv_conf_t, ssl_verify),
0271       NULL },
0272 
0273     { ngx_string("proxy_ssl_verify_depth"),
0274       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
0275       ngx_conf_set_num_slot,
0276       NGX_STREAM_SRV_CONF_OFFSET,
0277       offsetof(ngx_stream_proxy_srv_conf_t, ssl_verify_depth),
0278       NULL },
0279 
0280     { ngx_string("proxy_ssl_trusted_certificate"),
0281       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
0282       ngx_conf_set_str_slot,
0283       NGX_STREAM_SRV_CONF_OFFSET,
0284       offsetof(ngx_stream_proxy_srv_conf_t, ssl_trusted_certificate),
0285       NULL },
0286 
0287     { ngx_string("proxy_ssl_crl"),
0288       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
0289       ngx_conf_set_str_slot,
0290       NGX_STREAM_SRV_CONF_OFFSET,
0291       offsetof(ngx_stream_proxy_srv_conf_t, ssl_crl),
0292       NULL },
0293 
0294     { ngx_string("proxy_ssl_certificate"),
0295       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
0296       ngx_conf_set_str_slot,
0297       NGX_STREAM_SRV_CONF_OFFSET,
0298       offsetof(ngx_stream_proxy_srv_conf_t, ssl_certificate),
0299       NULL },
0300 
0301     { ngx_string("proxy_ssl_certificate_key"),
0302       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
0303       ngx_conf_set_str_slot,
0304       NGX_STREAM_SRV_CONF_OFFSET,
0305       offsetof(ngx_stream_proxy_srv_conf_t, ssl_certificate_key),
0306       NULL },
0307 
0308     { ngx_string("proxy_ssl_password_file"),
0309       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
0310       ngx_stream_proxy_ssl_password_file,
0311       NGX_STREAM_SRV_CONF_OFFSET,
0312       0,
0313       NULL },
0314 
0315 #endif
0316 
0317       ngx_null_command
0318 };
0319 
0320 
0321 static ngx_stream_module_t  ngx_stream_proxy_module_ctx = {
0322     NULL,                                  /* preconfiguration */
0323     NULL,                                  /* postconfiguration */
0324 
0325     NULL,                                  /* create main configuration */
0326     NULL,                                  /* init main configuration */
0327 
0328     ngx_stream_proxy_create_srv_conf,      /* create server configuration */
0329     ngx_stream_proxy_merge_srv_conf        /* merge server configuration */
0330 };
0331 
0332 
0333 ngx_module_t  ngx_stream_proxy_module = {
0334     NGX_MODULE_V1,
0335     &ngx_stream_proxy_module_ctx,          /* module context */
0336     ngx_stream_proxy_commands,             /* module directives */
0337     NGX_STREAM_MODULE,                     /* module type */
0338     NULL,                                  /* init master */
0339     NULL,                                  /* init module */
0340     NULL,                                  /* init process */
0341     NULL,                                  /* init thread */
0342     NULL,                                  /* exit thread */
0343     NULL,                                  /* exit process */
0344     NULL,                                  /* exit master */
0345     NGX_MODULE_V1_PADDING
0346 };
0347 
0348 
0349 static void
0350 ngx_stream_proxy_handler(ngx_stream_session_t *s)
0351 {
0352     u_char                           *p;
0353     ngx_str_t                        *host;
0354     ngx_uint_t                        i;
0355     ngx_connection_t                 *c;
0356     ngx_resolver_ctx_t               *ctx, temp;
0357     ngx_stream_upstream_t            *u;
0358     ngx_stream_core_srv_conf_t       *cscf;
0359     ngx_stream_proxy_srv_conf_t      *pscf;
0360     ngx_stream_upstream_srv_conf_t   *uscf, **uscfp;
0361     ngx_stream_upstream_main_conf_t  *umcf;
0362 
0363     c = s->connection;
0364 
0365     pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);
0366 
0367     ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0,
0368                    "proxy connection handler");
0369 
0370     u = ngx_pcalloc(c->pool, sizeof(ngx_stream_upstream_t));
0371     if (u == NULL) {
0372         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
0373         return;
0374     }
0375 
0376     s->upstream = u;
0377 
0378     s->log_handler = ngx_stream_proxy_log_error;
0379 
0380     u->peer.log = c->log;
0381     u->peer.log_error = NGX_ERROR_ERR;
0382 
0383     if (ngx_stream_proxy_set_local(s, u, pscf->local) != NGX_OK) {
0384         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
0385         return;
0386     }
0387 
0388     u->peer.type = c->type;
0389     u->start_sec = ngx_time();
0390 
0391     c->write->handler = ngx_stream_proxy_downstream_handler;
0392     c->read->handler = ngx_stream_proxy_downstream_handler;
0393 
0394     s->upstream_states = ngx_array_create(c->pool, 1,
0395                                           sizeof(ngx_stream_upstream_state_t));
0396     if (s->upstream_states == NULL) {
0397         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
0398         return;
0399     }
0400 
0401     if (c->type == SOCK_STREAM) {
0402         p = ngx_pnalloc(c->pool, pscf->buffer_size);
0403         if (p == NULL) {
0404             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
0405             return;
0406         }
0407 
0408         u->downstream_buf.start = p;
0409         u->downstream_buf.end = p + pscf->buffer_size;
0410         u->downstream_buf.pos = p;
0411         u->downstream_buf.last = p;
0412 
0413         if (c->read->ready) {
0414             ngx_post_event(c->read, &ngx_posted_events);
0415         }
0416     }
0417 
0418     if (pscf->upstream_value) {
0419         if (ngx_stream_proxy_eval(s, pscf) != NGX_OK) {
0420             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
0421             return;
0422         }
0423     }
0424 
0425     if (u->resolved == NULL) {
0426 
0427         uscf = pscf->upstream;
0428 
0429     } else {
0430 
0431 #if (NGX_STREAM_SSL)
0432         u->ssl_name = u->resolved->host;
0433 #endif
0434 
0435         host = &u->resolved->host;
0436 
0437         umcf = ngx_stream_get_module_main_conf(s, ngx_stream_upstream_module);
0438 
0439         uscfp = umcf->upstreams.elts;
0440 
0441         for (i = 0; i < umcf->upstreams.nelts; i++) {
0442 
0443             uscf = uscfp[i];
0444 
0445             if (uscf->host.len == host->len
0446                 && ((uscf->port == 0 && u->resolved->no_port)
0447                      || uscf->port == u->resolved->port)
0448                 && ngx_strncasecmp(uscf->host.data, host->data, host->len) == 0)
0449             {
0450                 goto found;
0451             }
0452         }
0453 
0454         if (u->resolved->sockaddr) {
0455 
0456             if (u->resolved->port == 0
0457                 && u->resolved->sockaddr->sa_family != AF_UNIX)
0458             {
0459                 ngx_log_error(NGX_LOG_ERR, c->log, 0,
0460                               "no port in upstream \"%V\"", host);
0461                 ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
0462                 return;
0463             }
0464 
0465             if (ngx_stream_upstream_create_round_robin_peer(s, u->resolved)
0466                 != NGX_OK)
0467             {
0468                 ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
0469                 return;
0470             }
0471 
0472             ngx_stream_proxy_connect(s);
0473 
0474             return;
0475         }
0476 
0477         if (u->resolved->port == 0) {
0478             ngx_log_error(NGX_LOG_ERR, c->log, 0,
0479                           "no port in upstream \"%V\"", host);
0480             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
0481             return;
0482         }
0483 
0484         temp.name = *host;
0485 
0486         cscf = ngx_stream_get_module_srv_conf(s, ngx_stream_core_module);
0487 
0488         ctx = ngx_resolve_start(cscf->resolver, &temp);
0489         if (ctx == NULL) {
0490             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
0491             return;
0492         }
0493 
0494         if (ctx == NGX_NO_RESOLVER) {
0495             ngx_log_error(NGX_LOG_ERR, c->log, 0,
0496                           "no resolver defined to resolve %V", host);
0497             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
0498             return;
0499         }
0500 
0501         ctx->name = *host;
0502         ctx->handler = ngx_stream_proxy_resolve_handler;
0503         ctx->data = s;
0504         ctx->timeout = cscf->resolver_timeout;
0505 
0506         u->resolved->ctx = ctx;
0507 
0508         if (ngx_resolve_name(ctx) != NGX_OK) {
0509             u->resolved->ctx = NULL;
0510             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
0511             return;
0512         }
0513 
0514         return;
0515     }
0516 
0517 found:
0518 
0519     if (uscf == NULL) {
0520         ngx_log_error(NGX_LOG_ALERT, c->log, 0, "no upstream configuration");
0521         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
0522         return;
0523     }
0524 
0525     u->upstream = uscf;
0526 
0527 #if (NGX_STREAM_SSL)
0528     u->ssl_name = uscf->host;
0529 #endif
0530 
0531     if (uscf->peer.init(s, uscf) != NGX_OK) {
0532         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
0533         return;
0534     }
0535 
0536     u->peer.start_time = ngx_current_msec;
0537 
0538     if (pscf->next_upstream_tries
0539         && u->peer.tries > pscf->next_upstream_tries)
0540     {
0541         u->peer.tries = pscf->next_upstream_tries;
0542     }
0543 
0544     ngx_stream_proxy_connect(s);
0545 }
0546 
0547 
0548 static ngx_int_t
0549 ngx_stream_proxy_eval(ngx_stream_session_t *s,
0550     ngx_stream_proxy_srv_conf_t *pscf)
0551 {
0552     ngx_str_t               host;
0553     ngx_url_t               url;
0554     ngx_stream_upstream_t  *u;
0555 
0556     if (ngx_stream_complex_value(s, pscf->upstream_value, &host) != NGX_OK) {
0557         return NGX_ERROR;
0558     }
0559 
0560     ngx_memzero(&url, sizeof(ngx_url_t));
0561 
0562     url.url = host;
0563     url.no_resolve = 1;
0564 
0565     if (ngx_parse_url(s->connection->pool, &url) != NGX_OK) {
0566         if (url.err) {
0567             ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
0568                           "%s in upstream \"%V\"", url.err, &url.url);
0569         }
0570 
0571         return NGX_ERROR;
0572     }
0573 
0574     u = s->upstream;
0575 
0576     u->resolved = ngx_pcalloc(s->connection->pool,
0577                               sizeof(ngx_stream_upstream_resolved_t));
0578     if (u->resolved == NULL) {
0579         return NGX_ERROR;
0580     }
0581 
0582     if (url.addrs) {
0583         u->resolved->sockaddr = url.addrs[0].sockaddr;
0584         u->resolved->socklen = url.addrs[0].socklen;
0585         u->resolved->name = url.addrs[0].name;
0586         u->resolved->naddrs = 1;
0587     }
0588 
0589     u->resolved->host = url.host;
0590     u->resolved->port = url.port;
0591     u->resolved->no_port = url.no_port;
0592 
0593     return NGX_OK;
0594 }
0595 
0596 
0597 static ngx_int_t
0598 ngx_stream_proxy_set_local(ngx_stream_session_t *s, ngx_stream_upstream_t *u,
0599     ngx_stream_upstream_local_t *local)
0600 {
0601     ngx_int_t    rc;
0602     ngx_str_t    val;
0603     ngx_addr_t  *addr;
0604 
0605     if (local == NULL) {
0606         u->peer.local = NULL;
0607         return NGX_OK;
0608     }
0609 
0610 #if (NGX_HAVE_TRANSPARENT_PROXY)
0611     u->peer.transparent = local->transparent;
0612 #endif
0613 
0614     if (local->value == NULL) {
0615         u->peer.local = local->addr;
0616         return NGX_OK;
0617     }
0618 
0619     if (ngx_stream_complex_value(s, local->value, &val) != NGX_OK) {
0620         return NGX_ERROR;
0621     }
0622 
0623     if (val.len == 0) {
0624         return NGX_OK;
0625     }
0626 
0627     addr = ngx_palloc(s->connection->pool, sizeof(ngx_addr_t));
0628     if (addr == NULL) {
0629         return NGX_ERROR;
0630     }
0631 
0632     rc = ngx_parse_addr_port(s->connection->pool, addr, val.data, val.len);
0633     if (rc == NGX_ERROR) {
0634         return NGX_ERROR;
0635     }
0636 
0637     if (rc != NGX_OK) {
0638         ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
0639                       "invalid local address \"%V\"", &val);
0640         return NGX_OK;
0641     }
0642 
0643     addr->name = val;
0644     u->peer.local = addr;
0645 
0646     return NGX_OK;
0647 }
0648 
0649 
0650 static void
0651 ngx_stream_proxy_connect(ngx_stream_session_t *s)
0652 {
0653     ngx_int_t                     rc;
0654     ngx_connection_t             *c, *pc;
0655     ngx_stream_upstream_t        *u;
0656     ngx_stream_proxy_srv_conf_t  *pscf;
0657 
0658     c = s->connection;
0659 
0660     c->log->action = "connecting to upstream";
0661 
0662     pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);
0663 
0664     u = s->upstream;
0665 
0666     u->connected = 0;
0667     u->proxy_protocol = pscf->proxy_protocol;
0668 
0669     if (u->state) {
0670         u->state->response_time = ngx_current_msec - u->state->response_time;
0671     }
0672 
0673     u->state = ngx_array_push(s->upstream_states);
0674     if (u->state == NULL) {
0675         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
0676         return;
0677     }
0678 
0679     ngx_memzero(u->state, sizeof(ngx_stream_upstream_state_t));
0680 
0681     u->state->connect_time = (ngx_msec_t) -1;
0682     u->state->first_byte_time = (ngx_msec_t) -1;
0683     u->state->response_time = ngx_current_msec;
0684 
0685     rc = ngx_event_connect_peer(&u->peer);
0686 
0687     ngx_log_debug1(NGX_LOG_DEBUG_STREAM, c->log, 0, "proxy connect: %i", rc);
0688 
0689     if (rc == NGX_ERROR) {
0690         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
0691         return;
0692     }
0693 
0694     u->state->peer = u->peer.name;
0695 
0696     if (rc == NGX_BUSY) {
0697         ngx_log_error(NGX_LOG_ERR, c->log, 0, "no live upstreams");
0698         ngx_stream_proxy_finalize(s, NGX_STREAM_BAD_GATEWAY);
0699         return;
0700     }
0701 
0702     if (rc == NGX_DECLINED) {
0703         ngx_stream_proxy_next_upstream(s);
0704         return;
0705     }
0706 
0707     /* rc == NGX_OK || rc == NGX_AGAIN || rc == NGX_DONE */
0708 
0709     pc = u->peer.connection;
0710 
0711     pc->data = s;
0712     pc->log = c->log;
0713     pc->pool = c->pool;
0714     pc->read->log = c->log;
0715     pc->write->log = c->log;
0716 
0717     if (rc != NGX_AGAIN) {
0718         ngx_stream_proxy_init_upstream(s);
0719         return;
0720     }
0721 
0722     pc->read->handler = ngx_stream_proxy_connect_handler;
0723     pc->write->handler = ngx_stream_proxy_connect_handler;
0724 
0725     ngx_add_timer(pc->write, pscf->connect_timeout);
0726 }
0727 
0728 
0729 static void
0730 ngx_stream_proxy_init_upstream(ngx_stream_session_t *s)
0731 {
0732     u_char                       *p;
0733     ngx_chain_t                  *cl;
0734     ngx_connection_t             *c, *pc;
0735     ngx_log_handler_pt            handler;
0736     ngx_stream_upstream_t        *u;
0737     ngx_stream_core_srv_conf_t   *cscf;
0738     ngx_stream_proxy_srv_conf_t  *pscf;
0739 
0740     u = s->upstream;
0741     pc = u->peer.connection;
0742 
0743     cscf = ngx_stream_get_module_srv_conf(s, ngx_stream_core_module);
0744 
0745     if (pc->type == SOCK_STREAM
0746         && cscf->tcp_nodelay
0747         && ngx_tcp_nodelay(pc) != NGX_OK)
0748     {
0749         ngx_stream_proxy_next_upstream(s);
0750         return;
0751     }
0752 
0753     pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);
0754 
0755 #if (NGX_STREAM_SSL)
0756 
0757     if (pc->type == SOCK_STREAM && pscf->ssl) {
0758 
0759         if (u->proxy_protocol) {
0760             if (ngx_stream_proxy_send_proxy_protocol(s) != NGX_OK) {
0761                 return;
0762             }
0763 
0764             u->proxy_protocol = 0;
0765         }
0766 
0767         if (pc->ssl == NULL) {
0768             ngx_stream_proxy_ssl_init_connection(s);
0769             return;
0770         }
0771     }
0772 
0773 #endif
0774 
0775     c = s->connection;
0776 
0777     if (c->log->log_level >= NGX_LOG_INFO) {
0778         ngx_str_t  str;
0779         u_char     addr[NGX_SOCKADDR_STRLEN];
0780 
0781         str.len = NGX_SOCKADDR_STRLEN;
0782         str.data = addr;
0783 
0784         if (ngx_connection_local_sockaddr(pc, &str, 1) == NGX_OK) {
0785             handler = c->log->handler;
0786             c->log->handler = NULL;
0787 
0788             ngx_log_error(NGX_LOG_INFO, c->log, 0,
0789                           "%sproxy %V connected to %V",
0790                           pc->type == SOCK_DGRAM ? "udp " : "",
0791                           &str, u->peer.name);
0792 
0793             c->log->handler = handler;
0794         }
0795     }
0796 
0797     u->state->connect_time = ngx_current_msec - u->state->response_time;
0798 
0799     if (u->peer.notify) {
0800         u->peer.notify(&u->peer, u->peer.data,
0801                        NGX_STREAM_UPSTREAM_NOTIFY_CONNECT);
0802     }
0803 
0804     if (u->upstream_buf.start == NULL) {
0805         p = ngx_pnalloc(c->pool, pscf->buffer_size);
0806         if (p == NULL) {
0807             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
0808             return;
0809         }
0810 
0811         u->upstream_buf.start = p;
0812         u->upstream_buf.end = p + pscf->buffer_size;
0813         u->upstream_buf.pos = p;
0814         u->upstream_buf.last = p;
0815     }
0816 
0817     if (c->buffer && c->buffer->pos < c->buffer->last) {
0818         ngx_log_debug1(NGX_LOG_DEBUG_STREAM, c->log, 0,
0819                        "stream proxy add preread buffer: %uz",
0820                        c->buffer->last - c->buffer->pos);
0821 
0822         cl = ngx_chain_get_free_buf(c->pool, &u->free);
0823         if (cl == NULL) {
0824             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
0825             return;
0826         }
0827 
0828         *cl->buf = *c->buffer;
0829 
0830         cl->buf->tag = (ngx_buf_tag_t) &ngx_stream_proxy_module;
0831         cl->buf->flush = 1;
0832         cl->buf->last_buf = (c->type == SOCK_DGRAM);
0833 
0834         cl->next = u->upstream_out;
0835         u->upstream_out = cl;
0836     }
0837 
0838     if (u->proxy_protocol) {
0839         ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0,
0840                        "stream proxy add PROXY protocol header");
0841 
0842         cl = ngx_chain_get_free_buf(c->pool, &u->free);
0843         if (cl == NULL) {
0844             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
0845             return;
0846         }
0847 
0848         p = ngx_pnalloc(c->pool, NGX_PROXY_PROTOCOL_MAX_HEADER);
0849         if (p == NULL) {
0850             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
0851             return;
0852         }
0853 
0854         cl->buf->pos = p;
0855 
0856         p = ngx_proxy_protocol_write(c, p, p + NGX_PROXY_PROTOCOL_MAX_HEADER);
0857         if (p == NULL) {
0858             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
0859             return;
0860         }
0861 
0862         cl->buf->last = p;
0863         cl->buf->temporary = 1;
0864         cl->buf->flush = 0;
0865         cl->buf->last_buf = 0;
0866         cl->buf->tag = (ngx_buf_tag_t) &ngx_stream_proxy_module;
0867 
0868         cl->next = u->upstream_out;
0869         u->upstream_out = cl;
0870 
0871         u->proxy_protocol = 0;
0872     }
0873 
0874     if (c->type == SOCK_DGRAM && pscf->responses == 0) {
0875         pc->read->ready = 0;
0876         pc->read->eof = 1;
0877     }
0878 
0879     u->connected = 1;
0880 
0881     pc->read->handler = ngx_stream_proxy_upstream_handler;
0882     pc->write->handler = ngx_stream_proxy_upstream_handler;
0883 
0884     if (pc->read->ready || pc->read->eof) {
0885         ngx_post_event(pc->read, &ngx_posted_events);
0886     }
0887 
0888     ngx_stream_proxy_process(s, 0, 1);
0889 }
0890 
0891 
0892 #if (NGX_STREAM_SSL)
0893 
0894 static ngx_int_t
0895 ngx_stream_proxy_send_proxy_protocol(ngx_stream_session_t *s)
0896 {
0897     u_char                       *p;
0898     ssize_t                       n, size;
0899     ngx_connection_t             *c, *pc;
0900     ngx_stream_upstream_t        *u;
0901     ngx_stream_proxy_srv_conf_t  *pscf;
0902     u_char                        buf[NGX_PROXY_PROTOCOL_MAX_HEADER];
0903 
0904     c = s->connection;
0905 
0906     ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0,
0907                    "stream proxy send PROXY protocol header");
0908 
0909     p = ngx_proxy_protocol_write(c, buf, buf + NGX_PROXY_PROTOCOL_MAX_HEADER);
0910     if (p == NULL) {
0911         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
0912         return NGX_ERROR;
0913     }
0914 
0915     u = s->upstream;
0916 
0917     pc = u->peer.connection;
0918 
0919     size = p - buf;
0920 
0921     n = pc->send(pc, buf, size);
0922 
0923     if (n == NGX_AGAIN) {
0924         if (ngx_handle_write_event(pc->write, 0) != NGX_OK) {
0925             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
0926             return NGX_ERROR;
0927         }
0928 
0929         pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);
0930 
0931         ngx_add_timer(pc->write, pscf->timeout);
0932 
0933         pc->write->handler = ngx_stream_proxy_connect_handler;
0934 
0935         return NGX_AGAIN;
0936     }
0937 
0938     if (n == NGX_ERROR) {
0939         ngx_stream_proxy_finalize(s, NGX_STREAM_OK);
0940         return NGX_ERROR;
0941     }
0942 
0943     if (n != size) {
0944 
0945         /*
0946          * PROXY protocol specification:
0947          * The sender must always ensure that the header
0948          * is sent at once, so that the transport layer
0949          * maintains atomicity along the path to the receiver.
0950          */
0951 
0952         ngx_log_error(NGX_LOG_ERR, c->log, 0,
0953                       "could not send PROXY protocol header at once");
0954 
0955         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
0956 
0957         return NGX_ERROR;
0958     }
0959 
0960     return NGX_OK;
0961 }
0962 
0963 
0964 static char *
0965 ngx_stream_proxy_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd,
0966     void *conf)
0967 {
0968     ngx_stream_proxy_srv_conf_t *pscf = conf;
0969 
0970     ngx_str_t  *value;
0971 
0972     if (pscf->ssl_passwords != NGX_CONF_UNSET_PTR) {
0973         return "is duplicate";
0974     }
0975 
0976     value = cf->args->elts;
0977 
0978     pscf->ssl_passwords = ngx_ssl_read_password_file(cf, &value[1]);
0979 
0980     if (pscf->ssl_passwords == NULL) {
0981         return NGX_CONF_ERROR;
0982     }
0983 
0984     return NGX_CONF_OK;
0985 }
0986 
0987 
0988 static void
0989 ngx_stream_proxy_ssl_init_connection(ngx_stream_session_t *s)
0990 {
0991     ngx_int_t                     rc;
0992     ngx_connection_t             *pc;
0993     ngx_stream_upstream_t        *u;
0994     ngx_stream_proxy_srv_conf_t  *pscf;
0995 
0996     u = s->upstream;
0997 
0998     pc = u->peer.connection;
0999 
1000     pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);
1001 
1002     if (ngx_ssl_create_connection(pscf->ssl, pc, NGX_SSL_BUFFER|NGX_SSL_CLIENT)
1003         != NGX_OK)
1004     {
1005         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
1006         return;
1007     }
1008 
1009     if (pscf->ssl_server_name || pscf->ssl_verify) {
1010         if (ngx_stream_proxy_ssl_name(s) != NGX_OK) {
1011             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
1012             return;
1013         }
1014     }
1015 
1016     if (pscf->ssl_session_reuse) {
1017         if (u->peer.set_session(&u->peer, u->peer.data) != NGX_OK) {
1018             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
1019             return;
1020         }
1021     }
1022 
1023     s->connection->log->action = "SSL handshaking to upstream";
1024 
1025     rc = ngx_ssl_handshake(pc);
1026 
1027     if (rc == NGX_AGAIN) {
1028 
1029         if (!pc->write->timer_set) {
1030             ngx_add_timer(pc->write, pscf->connect_timeout);
1031         }
1032 
1033         pc->ssl->handler = ngx_stream_proxy_ssl_handshake;
1034         return;
1035     }
1036 
1037     ngx_stream_proxy_ssl_handshake(pc);
1038 }
1039 
1040 
1041 static void
1042 ngx_stream_proxy_ssl_handshake(ngx_connection_t *pc)
1043 {
1044     long                          rc;
1045     ngx_stream_session_t         *s;
1046     ngx_stream_upstream_t        *u;
1047     ngx_stream_proxy_srv_conf_t  *pscf;
1048 
1049     s = pc->data;
1050 
1051     pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);
1052 
1053     if (pc->ssl->handshaked) {
1054 
1055         if (pscf->ssl_verify) {
1056             rc = SSL_get_verify_result(pc->ssl->connection);
1057 
1058             if (rc != X509_V_OK) {
1059                 ngx_log_error(NGX_LOG_ERR, pc->log, 0,
1060                               "upstream SSL certificate verify error: (%l:%s)",
1061                               rc, X509_verify_cert_error_string(rc));
1062                 goto failed;
1063             }
1064 
1065             u = s->upstream;
1066 
1067             if (ngx_ssl_check_host(pc, &u->ssl_name) != NGX_OK) {
1068                 ngx_log_error(NGX_LOG_ERR, pc->log, 0,
1069                               "upstream SSL certificate does not match \"%V\"",
1070                               &u->ssl_name);
1071                 goto failed;
1072             }
1073         }
1074 
1075         if (pscf->ssl_session_reuse) {
1076             u = s->upstream;
1077             u->peer.save_session(&u->peer, u->peer.data);
1078         }
1079 
1080         if (pc->write->timer_set) {
1081             ngx_del_timer(pc->write);
1082         }
1083 
1084         ngx_stream_proxy_init_upstream(s);
1085 
1086         return;
1087     }
1088 
1089 failed:
1090 
1091     ngx_stream_proxy_next_upstream(s);
1092 }
1093 
1094 
1095 static ngx_int_t
1096 ngx_stream_proxy_ssl_name(ngx_stream_session_t *s)
1097 {
1098     u_char                       *p, *last;
1099     ngx_str_t                     name;
1100     ngx_stream_upstream_t        *u;
1101     ngx_stream_proxy_srv_conf_t  *pscf;
1102 
1103     pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);
1104 
1105     u = s->upstream;
1106 
1107     if (pscf->ssl_name) {
1108         if (ngx_stream_complex_value(s, pscf->ssl_name, &name) != NGX_OK) {
1109             return NGX_ERROR;
1110         }
1111 
1112     } else {
1113         name = u->ssl_name;
1114     }
1115 
1116     if (name.len == 0) {
1117         goto done;
1118     }
1119 
1120     /*
1121      * ssl name here may contain port, strip it for compatibility
1122      * with the http module
1123      */
1124 
1125     p = name.data;
1126     last = name.data + name.len;
1127 
1128     if (*p == '[') {
1129         p = ngx_strlchr(p, last, ']');
1130 
1131         if (p == NULL) {
1132             p = name.data;
1133         }
1134     }
1135 
1136     p = ngx_strlchr(p, last, ':');
1137 
1138     if (p != NULL) {
1139         name.len = p - name.data;
1140     }
1141 
1142     if (!pscf->ssl_server_name) {
1143         goto done;
1144     }
1145 
1146 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1147 
1148     /* as per RFC 6066, literal IPv4 and IPv6 addresses are not permitted */
1149 
1150     if (name.len == 0 || *name.data == '[') {
1151         goto done;
1152     }
1153 
1154     if (ngx_inet_addr(name.data, name.len) != INADDR_NONE) {
1155         goto done;
1156     }
1157 
1158     /*
1159      * SSL_set_tlsext_host_name() needs a null-terminated string,
1160      * hence we explicitly null-terminate name here
1161      */
1162 
1163     p = ngx_pnalloc(s->connection->pool, name.len + 1);
1164     if (p == NULL) {
1165         return NGX_ERROR;
1166     }
1167 
1168     (void) ngx_cpystrn(p, name.data, name.len + 1);
1169 
1170     name.data = p;
1171 
1172     ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
1173                    "upstream SSL server name: \"%s\"", name.data);
1174 
1175     if (SSL_set_tlsext_host_name(u->peer.connection->ssl->connection,
1176                                  (char *) name.data)
1177         == 0)
1178     {
1179         ngx_ssl_error(NGX_LOG_ERR, s->connection->log, 0,
1180                       "SSL_set_tlsext_host_name(\"%s\") failed", name.data);
1181         return NGX_ERROR;
1182     }
1183 
1184 #endif
1185 
1186 done:
1187 
1188     u->ssl_name = name;
1189 
1190     return NGX_OK;
1191 }
1192 
1193 #endif
1194 
1195 
1196 static void
1197 ngx_stream_proxy_downstream_handler(ngx_event_t *ev)
1198 {
1199     ngx_stream_proxy_process_connection(ev, ev->write);
1200 }
1201 
1202 
1203 static void
1204 ngx_stream_proxy_resolve_handler(ngx_resolver_ctx_t *ctx)
1205 {
1206     ngx_stream_session_t            *s;
1207     ngx_stream_upstream_t           *u;
1208     ngx_stream_proxy_srv_conf_t     *pscf;
1209     ngx_stream_upstream_resolved_t  *ur;
1210 
1211     s = ctx->data;
1212 
1213     u = s->upstream;
1214     ur = u->resolved;
1215 
1216     ngx_log_debug0(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
1217                    "stream upstream resolve");
1218 
1219     if (ctx->state) {
1220         ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
1221                       "%V could not be resolved (%i: %s)",
1222                       &ctx->name, ctx->state,
1223                       ngx_resolver_strerror(ctx->state));
1224 
1225         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
1226         return;
1227     }
1228 
1229     ur->naddrs = ctx->naddrs;
1230     ur->addrs = ctx->addrs;
1231 
1232 #if (NGX_DEBUG)
1233     {
1234     u_char      text[NGX_SOCKADDR_STRLEN];
1235     ngx_str_t   addr;
1236     ngx_uint_t  i;
1237 
1238     addr.data = text;
1239 
1240     for (i = 0; i < ctx->naddrs; i++) {
1241         addr.len = ngx_sock_ntop(ur->addrs[i].sockaddr, ur->addrs[i].socklen,
1242                                  text, NGX_SOCKADDR_STRLEN, 0);
1243 
1244         ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
1245                        "name was resolved to %V", &addr);
1246     }
1247     }
1248 #endif
1249 
1250     if (ngx_stream_upstream_create_round_robin_peer(s, ur) != NGX_OK) {
1251         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
1252         return;
1253     }
1254 
1255     ngx_resolve_name_done(ctx);
1256     ur->ctx = NULL;
1257 
1258     u->peer.start_time = ngx_current_msec;
1259 
1260     pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);
1261 
1262     if (pscf->next_upstream_tries
1263         && u->peer.tries > pscf->next_upstream_tries)
1264     {
1265         u->peer.tries = pscf->next_upstream_tries;
1266     }
1267 
1268     ngx_stream_proxy_connect(s);
1269 }
1270 
1271 
1272 static void
1273 ngx_stream_proxy_upstream_handler(ngx_event_t *ev)
1274 {
1275     ngx_stream_proxy_process_connection(ev, !ev->write);
1276 }
1277 
1278 
1279 static void
1280 ngx_stream_proxy_process_connection(ngx_event_t *ev, ngx_uint_t from_upstream)
1281 {
1282     ngx_connection_t             *c, *pc;
1283     ngx_stream_session_t         *s;
1284     ngx_stream_upstream_t        *u;
1285     ngx_stream_proxy_srv_conf_t  *pscf;
1286 
1287     c = ev->data;
1288     s = c->data;
1289     u = s->upstream;
1290 
1291     if (c->close) {
1292         ngx_log_error(NGX_LOG_INFO, c->log, 0, "shutdown timeout");
1293         ngx_stream_proxy_finalize(s, NGX_STREAM_OK);
1294         return;
1295     }
1296 
1297     c = s->connection;
1298     pc = u->peer.connection;
1299 
1300     pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);
1301 
1302     if (ev->timedout) {
1303         ev->timedout = 0;
1304 
1305         if (ev->delayed) {
1306             ev->delayed = 0;
1307 
1308             if (!ev->ready) {
1309                 if (ngx_handle_read_event(ev, 0) != NGX_OK) {
1310                     ngx_stream_proxy_finalize(s,
1311                                               NGX_STREAM_INTERNAL_SERVER_ERROR);
1312                     return;
1313                 }
1314 
1315                 if (u->connected && !c->read->delayed && !pc->read->delayed) {
1316                     ngx_add_timer(c->write, pscf->timeout);
1317                 }
1318 
1319                 return;
1320             }
1321 
1322         } else {
1323             if (s->connection->type == SOCK_DGRAM) {
1324                 if (pscf->responses == NGX_MAX_INT32_VALUE) {
1325 
1326                     /*
1327                      * successfully terminate timed out UDP session
1328                      * with unspecified number of responses
1329                      */
1330 
1331                     pc->read->ready = 0;
1332                     pc->read->eof = 1;
1333 
1334                     ngx_stream_proxy_process(s, 1, 0);
1335                     return;
1336                 }
1337 
1338                 ngx_connection_error(pc, NGX_ETIMEDOUT, "upstream timed out");
1339 
1340                 if (u->received == 0) {
1341                     ngx_stream_proxy_next_upstream(s);
1342                     return;
1343                 }
1344 
1345             } else {
1346                 ngx_connection_error(c, NGX_ETIMEDOUT, "connection timed out");
1347             }
1348 
1349             ngx_stream_proxy_finalize(s, NGX_STREAM_OK);
1350             return;
1351         }
1352 
1353     } else if (ev->delayed) {
1354 
1355         ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0,
1356                        "stream connection delayed");
1357 
1358         if (ngx_handle_read_event(ev, 0) != NGX_OK) {
1359             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
1360         }
1361 
1362         return;
1363     }
1364 
1365     if (from_upstream && !u->connected) {
1366         return;
1367     }
1368 
1369     ngx_stream_proxy_process(s, from_upstream, ev->write);
1370 }
1371 
1372 
1373 static void
1374 ngx_stream_proxy_connect_handler(ngx_event_t *ev)
1375 {
1376     ngx_connection_t      *c;
1377     ngx_stream_session_t  *s;
1378 
1379     c = ev->data;
1380     s = c->data;
1381 
1382     if (ev->timedout) {
1383         ngx_log_error(NGX_LOG_ERR, c->log, NGX_ETIMEDOUT, "upstream timed out");
1384         ngx_stream_proxy_next_upstream(s);
1385         return;
1386     }
1387 
1388     ngx_del_timer(c->write);
1389 
1390     ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0,
1391                    "stream proxy connect upstream");
1392 
1393     if (ngx_stream_proxy_test_connect(c) != NGX_OK) {
1394         ngx_stream_proxy_next_upstream(s);
1395         return;
1396     }
1397 
1398     ngx_stream_proxy_init_upstream(s);
1399 }
1400 
1401 
1402 static ngx_int_t
1403 ngx_stream_proxy_test_connect(ngx_connection_t *c)
1404 {
1405     int        err;
1406     socklen_t  len;
1407 
1408 #if (NGX_HAVE_KQUEUE)
1409 
1410     if (ngx_event_flags & NGX_USE_KQUEUE_EVENT)  {
1411         err = c->write->kq_errno ? c->write->kq_errno : c->read->kq_errno;
1412 
1413         if (err) {
1414             (void) ngx_connection_error(c, err,
1415                                     "kevent() reported that connect() failed");
1416             return NGX_ERROR;
1417         }
1418 
1419     } else
1420 #endif
1421     {
1422         err = 0;
1423         len = sizeof(int);
1424 
1425         /*
1426          * BSDs and Linux return 0 and set a pending error in err
1427          * Solaris returns -1 and sets errno
1428          */
1429 
1430         if (getsockopt(c->fd, SOL_SOCKET, SO_ERROR, (void *) &err, &len)
1431             == -1)
1432         {
1433             err = ngx_socket_errno;
1434         }
1435 
1436         if (err) {
1437             (void) ngx_connection_error(c, err, "connect() failed");
1438             return NGX_ERROR;
1439         }
1440     }
1441 
1442     return NGX_OK;
1443 }
1444 
1445 
1446 static void
1447 ngx_stream_proxy_process(ngx_stream_session_t *s, ngx_uint_t from_upstream,
1448     ngx_uint_t do_write)
1449 {
1450     char                         *recv_action, *send_action;
1451     off_t                        *received, limit;
1452     size_t                        size, limit_rate;
1453     ssize_t                       n;
1454     ngx_buf_t                    *b;
1455     ngx_int_t                     rc;
1456     ngx_uint_t                    flags;
1457     ngx_msec_t                    delay;
1458     ngx_chain_t                  *cl, **ll, **out, **busy;
1459     ngx_connection_t             *c, *pc, *src, *dst;
1460     ngx_log_handler_pt            handler;
1461     ngx_stream_upstream_t        *u;
1462     ngx_stream_proxy_srv_conf_t  *pscf;
1463 
1464     u = s->upstream;
1465 
1466     c = s->connection;
1467     pc = u->connected ? u->peer.connection : NULL;
1468 
1469     if (c->type == SOCK_DGRAM && (ngx_terminate || ngx_exiting)) {
1470 
1471         /* socket is already closed on worker shutdown */
1472 
1473         handler = c->log->handler;
1474         c->log->handler = NULL;
1475 
1476         ngx_log_error(NGX_LOG_INFO, c->log, 0, "disconnected on shutdown");
1477 
1478         c->log->handler = handler;
1479 
1480         ngx_stream_proxy_finalize(s, NGX_STREAM_OK);
1481         return;
1482     }
1483 
1484     pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);
1485 
1486     if (from_upstream) {
1487         src = pc;
1488         dst = c;
1489         b = &u->upstream_buf;
1490         limit_rate = pscf->download_rate;
1491         received = &u->received;
1492         out = &u->downstream_out;
1493         busy = &u->downstream_busy;
1494         recv_action = "proxying and reading from upstream";
1495         send_action = "proxying and sending to client";
1496 
1497     } else {
1498         src = c;
1499         dst = pc;
1500         b = &u->downstream_buf;
1501         limit_rate = pscf->upload_rate;
1502         received = &s->received;
1503         out = &u->upstream_out;
1504         busy = &u->upstream_busy;
1505         recv_action = "proxying and reading from client";
1506         send_action = "proxying and sending to upstream";
1507     }
1508 
1509     for ( ;; ) {
1510 
1511         if (do_write && dst) {
1512 
1513             if (*out || *busy || dst->buffered) {
1514                 c->log->action = send_action;
1515 
1516                 rc = ngx_stream_top_filter(s, *out, from_upstream);
1517 
1518                 if (rc == NGX_ERROR) {
1519                     if (c->type == SOCK_DGRAM && !from_upstream) {
1520                         ngx_stream_proxy_next_upstream(s);
1521                         return;
1522                     }
1523 
1524                     ngx_stream_proxy_finalize(s, NGX_STREAM_OK);
1525                     return;
1526                 }
1527 
1528                 ngx_chain_update_chains(c->pool, &u->free, busy, out,
1529                                       (ngx_buf_tag_t) &ngx_stream_proxy_module);
1530 
1531                 if (*busy == NULL) {
1532                     b->pos = b->start;
1533                     b->last = b->start;
1534                 }
1535             }
1536         }
1537 
1538         size = b->end - b->last;
1539 
1540         if (size && src->read->ready && !src->read->delayed
1541             && !src->read->error)
1542         {
1543             if (limit_rate) {
1544                 limit = (off_t) limit_rate * (ngx_time() - u->start_sec + 1)
1545                         - *received;
1546 
1547                 if (limit <= 0) {
1548                     src->read->delayed = 1;
1549                     delay = (ngx_msec_t) (- limit * 1000 / limit_rate + 1);
1550                     ngx_add_timer(src->read, delay);
1551                     break;
1552                 }
1553 
1554                 if ((off_t) size > limit) {
1555                     size = (size_t) limit;
1556                 }
1557             }
1558 
1559             c->log->action = recv_action;
1560 
1561             n = src->recv(src, b->last, size);
1562 
1563             if (n == NGX_AGAIN) {
1564                 break;
1565             }
1566 
1567             if (n == NGX_ERROR) {
1568                 if (c->type == SOCK_DGRAM && u->received == 0) {
1569                     ngx_stream_proxy_next_upstream(s);
1570                     return;
1571                 }
1572 
1573                 src->read->eof = 1;
1574                 n = 0;
1575             }
1576 
1577             if (n >= 0) {
1578                 if (limit_rate) {
1579                     delay = (ngx_msec_t) (n * 1000 / limit_rate);
1580 
1581                     if (delay > 0) {
1582                         src->read->delayed = 1;
1583                         ngx_add_timer(src->read, delay);
1584                     }
1585                 }
1586 
1587                 if (from_upstream) {
1588                     if (u->state->first_byte_time == (ngx_msec_t) -1) {
1589                         u->state->first_byte_time = ngx_current_msec
1590                                                     - u->state->response_time;
1591                     }
1592                 }
1593 
1594                 if (c->type == SOCK_DGRAM && ++u->responses == pscf->responses)
1595                 {
1596                     src->read->ready = 0;
1597                     src->read->eof = 1;
1598                 }
1599 
1600                 for (ll = out; *ll; ll = &(*ll)->next) { /* void */ }
1601 
1602                 cl = ngx_chain_get_free_buf(c->pool, &u->free);
1603                 if (cl == NULL) {
1604                     ngx_stream_proxy_finalize(s,
1605                                               NGX_STREAM_INTERNAL_SERVER_ERROR);
1606                     return;
1607                 }
1608 
1609                 *ll = cl;
1610 
1611                 cl->buf->pos = b->last;
1612                 cl->buf->last = b->last + n;
1613                 cl->buf->tag = (ngx_buf_tag_t) &ngx_stream_proxy_module;
1614 
1615                 cl->buf->temporary = (n ? 1 : 0);
1616                 cl->buf->last_buf = src->read->eof;
1617                 cl->buf->flush = 1;
1618 
1619                 *received += n;
1620                 b->last += n;
1621                 do_write = 1;
1622 
1623                 continue;
1624             }
1625         }
1626 
1627         break;
1628     }
1629 
1630     c->log->action = "proxying connection";
1631 
1632     if (src->read->eof && dst && (dst->read->eof || !dst->buffered)) {
1633         handler = c->log->handler;
1634         c->log->handler = NULL;
1635 
1636         ngx_log_error(NGX_LOG_INFO, c->log, 0,
1637                       "%s%s disconnected"
1638                       ", bytes from/to client:%O/%O"
1639                       ", bytes from/to upstream:%O/%O",
1640                       src->type == SOCK_DGRAM ? "udp " : "",
1641                       from_upstream ? "upstream" : "client",
1642                       s->received, c->sent, u->received, pc ? pc->sent : 0);
1643 
1644         c->log->handler = handler;
1645 
1646         ngx_stream_proxy_finalize(s, NGX_STREAM_OK);
1647         return;
1648     }
1649 
1650     flags = src->read->eof ? NGX_CLOSE_EVENT : 0;
1651 
1652     if (!src->shared && ngx_handle_read_event(src->read, flags) != NGX_OK) {
1653         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
1654         return;
1655     }
1656 
1657     if (dst) {
1658         if (!dst->shared && ngx_handle_write_event(dst->write, 0) != NGX_OK) {
1659             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
1660             return;
1661         }
1662 
1663         if (!c->read->delayed && !pc->read->delayed) {
1664             ngx_add_timer(c->write, pscf->timeout);
1665 
1666         } else if (c->write->timer_set) {
1667             ngx_del_timer(c->write);
1668         }
1669     }
1670 }
1671 
1672 
1673 static void
1674 ngx_stream_proxy_next_upstream(ngx_stream_session_t *s)
1675 {
1676     ngx_msec_t                    timeout;
1677     ngx_connection_t             *pc;
1678     ngx_stream_upstream_t        *u;
1679     ngx_stream_proxy_srv_conf_t  *pscf;
1680 
1681     ngx_log_debug0(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
1682                    "stream proxy next upstream");
1683 
1684     u = s->upstream;
1685     pc = u->peer.connection;
1686 
1687     if (pc && pc->buffered) {
1688         ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
1689                       "buffered data on next upstream");
1690         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
1691         return;
1692     }
1693 
1694     if (s->connection->type == SOCK_DGRAM) {
1695         u->upstream_out = NULL;
1696     }
1697 
1698     if (u->peer.sockaddr) {
1699         u->peer.free(&u->peer, u->peer.data, NGX_PEER_FAILED);
1700         u->peer.sockaddr = NULL;
1701     }
1702 
1703     pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);
1704 
1705     timeout = pscf->next_upstream_timeout;
1706 
1707     if (u->peer.tries == 0
1708         || !pscf->next_upstream
1709         || (timeout && ngx_current_msec - u->peer.start_time >= timeout))
1710     {
1711         ngx_stream_proxy_finalize(s, NGX_STREAM_BAD_GATEWAY);
1712         return;
1713     }
1714 
1715     if (pc) {
1716         ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
1717                        "close proxy upstream connection: %d", pc->fd);
1718 
1719 #if (NGX_STREAM_SSL)
1720         if (pc->ssl) {
1721             pc->ssl->no_wait_shutdown = 1;
1722             pc->ssl->no_send_shutdown = 1;
1723 
1724             (void) ngx_ssl_shutdown(pc);
1725         }
1726 #endif
1727 
1728         u->state->bytes_received = u->received;
1729         u->state->bytes_sent = pc->sent;
1730 
1731         ngx_close_connection(pc);
1732         u->peer.connection = NULL;
1733     }
1734 
1735     ngx_stream_proxy_connect(s);
1736 }
1737 
1738 
1739 static void
1740 ngx_stream_proxy_finalize(ngx_stream_session_t *s, ngx_uint_t rc)
1741 {
1742     ngx_connection_t       *pc;
1743     ngx_stream_upstream_t  *u;
1744 
1745     ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
1746                    "finalize stream proxy: %i", rc);
1747 
1748     u = s->upstream;
1749 
1750     if (u == NULL) {
1751         goto noupstream;
1752     }
1753 
1754     if (u->resolved && u->resolved->ctx) {
1755         ngx_resolve_name_done(u->resolved->ctx);
1756         u->resolved->ctx = NULL;
1757     }
1758 
1759     pc = u->peer.connection;
1760 
1761     if (u->state) {
1762         u->state->response_time = ngx_current_msec - u->state->response_time;
1763 
1764         if (pc) {
1765             u->state->bytes_received = u->received;
1766             u->state->bytes_sent = pc->sent;
1767         }
1768     }
1769 
1770     if (u->peer.free && u->peer.sockaddr) {
1771         u->peer.free(&u->peer, u->peer.data, 0);
1772         u->peer.sockaddr = NULL;
1773     }
1774 
1775     if (pc) {
1776         ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
1777                        "close stream proxy upstream connection: %d", pc->fd);
1778 
1779 #if (NGX_STREAM_SSL)
1780         if (pc->ssl) {
1781             pc->ssl->no_wait_shutdown = 1;
1782             (void) ngx_ssl_shutdown(pc);
1783         }
1784 #endif
1785 
1786         ngx_close_connection(pc);
1787         u->peer.connection = NULL;
1788     }
1789 
1790 noupstream:
1791 
1792     ngx_stream_finalize_session(s, rc);
1793 }
1794 
1795 
1796 static u_char *
1797 ngx_stream_proxy_log_error(ngx_log_t *log, u_char *buf, size_t len)
1798 {
1799     u_char                 *p;
1800     ngx_connection_t       *pc;
1801     ngx_stream_session_t   *s;
1802     ngx_stream_upstream_t  *u;
1803 
1804     s = log->data;
1805 
1806     u = s->upstream;
1807 
1808     p = buf;
1809 
1810     if (u->peer.name) {
1811         p = ngx_snprintf(p, len, ", upstream: \"%V\"", u->peer.name);
1812         len -= p - buf;
1813     }
1814 
1815     pc = u->peer.connection;
1816 
1817     p = ngx_snprintf(p, len,
1818                      ", bytes from/to client:%O/%O"
1819                      ", bytes from/to upstream:%O/%O",
1820                      s->received, s->connection->sent,
1821                      u->received, pc ? pc->sent : 0);
1822 
1823     return p;
1824 }
1825 
1826 
1827 static void *
1828 ngx_stream_proxy_create_srv_conf(ngx_conf_t *cf)
1829 {
1830     ngx_stream_proxy_srv_conf_t  *conf;
1831 
1832     conf = ngx_pcalloc(cf->pool, sizeof(ngx_stream_proxy_srv_conf_t));
1833     if (conf == NULL) {
1834         return NULL;
1835     }
1836 
1837     /*
1838      * set by ngx_pcalloc():
1839      *
1840      *     conf->ssl_protocols = 0;
1841      *     conf->ssl_ciphers = { 0, NULL };
1842      *     conf->ssl_name = NULL;
1843      *     conf->ssl_trusted_certificate = { 0, NULL };
1844      *     conf->ssl_crl = { 0, NULL };
1845      *     conf->ssl_certificate = { 0, NULL };
1846      *     conf->ssl_certificate_key = { 0, NULL };
1847      *
1848      *     conf->ssl = NULL;
1849      *     conf->upstream = NULL;
1850      *     conf->upstream_value = NULL;
1851      */
1852 
1853     conf->connect_timeout = NGX_CONF_UNSET_MSEC;
1854     conf->timeout = NGX_CONF_UNSET_MSEC;
1855     conf->next_upstream_timeout = NGX_CONF_UNSET_MSEC;
1856     conf->buffer_size = NGX_CONF_UNSET_SIZE;
1857     conf->upload_rate = NGX_CONF_UNSET_SIZE;
1858     conf->download_rate = NGX_CONF_UNSET_SIZE;
1859     conf->responses = NGX_CONF_UNSET_UINT;
1860     conf->next_upstream_tries = NGX_CONF_UNSET_UINT;
1861     conf->next_upstream = NGX_CONF_UNSET;
1862     conf->proxy_protocol = NGX_CONF_UNSET;
1863     conf->local = NGX_CONF_UNSET_PTR;
1864 
1865 #if (NGX_STREAM_SSL)
1866     conf->ssl_enable = NGX_CONF_UNSET;
1867     conf->ssl_session_reuse = NGX_CONF_UNSET;
1868     conf->ssl_server_name = NGX_CONF_UNSET;
1869     conf->ssl_verify = NGX_CONF_UNSET;
1870     conf->ssl_verify_depth = NGX_CONF_UNSET_UINT;
1871     conf->ssl_passwords = NGX_CONF_UNSET_PTR;
1872 #endif
1873 
1874     return conf;
1875 }
1876 
1877 
1878 static char *
1879 ngx_stream_proxy_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
1880 {
1881     ngx_stream_proxy_srv_conf_t *prev = parent;
1882     ngx_stream_proxy_srv_conf_t *conf = child;
1883 
1884     ngx_conf_merge_msec_value(conf->connect_timeout,
1885                               prev->connect_timeout, 60000);
1886 
1887     ngx_conf_merge_msec_value(conf->timeout,
1888                               prev->timeout, 10 * 60000);
1889 
1890     ngx_conf_merge_msec_value(conf->next_upstream_timeout,
1891                               prev->next_upstream_timeout, 0);
1892 
1893     ngx_conf_merge_size_value(conf->buffer_size,
1894                               prev->buffer_size, 16384);
1895 
1896     ngx_conf_merge_size_value(conf->upload_rate,
1897                               prev->upload_rate, 0);
1898 
1899     ngx_conf_merge_size_value(conf->download_rate,
1900                               prev->download_rate, 0);
1901 
1902     ngx_conf_merge_uint_value(conf->responses,
1903                               prev->responses, NGX_MAX_INT32_VALUE);
1904 
1905     ngx_conf_merge_uint_value(conf->next_upstream_tries,
1906                               prev->next_upstream_tries, 0);
1907 
1908     ngx_conf_merge_value(conf->next_upstream, prev->next_upstream, 1);
1909 
1910     ngx_conf_merge_value(conf->proxy_protocol, prev->proxy_protocol, 0);
1911 
1912     ngx_conf_merge_ptr_value(conf->local, prev->local, NULL);
1913 
1914 #if (NGX_STREAM_SSL)
1915 
1916     ngx_conf_merge_value(conf->ssl_enable, prev->ssl_enable, 0);
1917 
1918     ngx_conf_merge_value(conf->ssl_session_reuse,
1919                               prev->ssl_session_reuse, 1);
1920 
1921     ngx_conf_merge_bitmask_value(conf->ssl_protocols, prev->ssl_protocols,
1922                               (NGX_CONF_BITMASK_SET|NGX_SSL_TLSv1
1923                                |NGX_SSL_TLSv1_1|NGX_SSL_TLSv1_2));
1924 
1925     ngx_conf_merge_str_value(conf->ssl_ciphers, prev->ssl_ciphers, "DEFAULT");
1926 
1927     if (conf->ssl_name == NULL) {
1928         conf->ssl_name = prev->ssl_name;
1929     }
1930 
1931     ngx_conf_merge_value(conf->ssl_server_name, prev->ssl_server_name, 0);
1932 
1933     ngx_conf_merge_value(conf->ssl_verify, prev->ssl_verify, 0);
1934 
1935     ngx_conf_merge_uint_value(conf->ssl_verify_depth,
1936                               prev->ssl_verify_depth, 1);
1937 
1938     ngx_conf_merge_str_value(conf->ssl_trusted_certificate,
1939                               prev->ssl_trusted_certificate, "");
1940 
1941     ngx_conf_merge_str_value(conf->ssl_crl, prev->ssl_crl, "");
1942 
1943     ngx_conf_merge_str_value(conf->ssl_certificate,
1944                               prev->ssl_certificate, "");
1945 
1946     ngx_conf_merge_str_value(conf->ssl_certificate_key,
1947                               prev->ssl_certificate_key, "");
1948 
1949     ngx_conf_merge_ptr_value(conf->ssl_passwords, prev->ssl_passwords, NULL);
1950 
1951     if (conf->ssl_enable && ngx_stream_proxy_set_ssl(cf, conf) != NGX_OK) {
1952         return NGX_CONF_ERROR;
1953     }
1954 
1955 #endif
1956 
1957     return NGX_CONF_OK;
1958 }
1959 
1960 
1961 #if (NGX_STREAM_SSL)
1962 
1963 static ngx_int_t
1964 ngx_stream_proxy_set_ssl(ngx_conf_t *cf, ngx_stream_proxy_srv_conf_t *pscf)
1965 {
1966     ngx_pool_cleanup_t  *cln;
1967 
1968     pscf->ssl = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_t));
1969     if (pscf->ssl == NULL) {
1970         return NGX_ERROR;
1971     }
1972 
1973     pscf->ssl->log = cf->log;
1974 
1975     if (ngx_ssl_create(pscf->ssl, pscf->ssl_protocols, NULL) != NGX_OK) {
1976         return NGX_ERROR;
1977     }
1978 
1979     cln = ngx_pool_cleanup_add(cf->pool, 0);
1980     if (cln == NULL) {
1981         return NGX_ERROR;
1982     }
1983 
1984     cln->handler = ngx_ssl_cleanup_ctx;
1985     cln->data = pscf->ssl;
1986 
1987     if (pscf->ssl_certificate.len) {
1988 
1989         if (pscf->ssl_certificate_key.len == 0) {
1990             ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
1991                           "no \"proxy_ssl_certificate_key\" is defined "
1992                           "for certificate \"%V\"", &pscf->ssl_certificate);
1993             return NGX_ERROR;
1994         }
1995 
1996         if (ngx_ssl_certificate(cf, pscf->ssl, &pscf->ssl_certificate,
1997                                 &pscf->ssl_certificate_key, pscf->ssl_passwords)
1998             != NGX_OK)
1999         {
2000             return NGX_ERROR;
2001         }
2002     }
2003 
2004     if (ngx_ssl_ciphers(cf, pscf->ssl, &pscf->ssl_ciphers, 0) != NGX_OK) {
2005         return NGX_ERROR;
2006     }
2007 
2008     if (pscf->ssl_verify) {
2009         if (pscf->ssl_trusted_certificate.len == 0) {
2010             ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
2011                       "no proxy_ssl_trusted_certificate for proxy_ssl_verify");
2012             return NGX_ERROR;
2013         }
2014 
2015         if (ngx_ssl_trusted_certificate(cf, pscf->ssl,
2016                                         &pscf->ssl_trusted_certificate,
2017                                         pscf->ssl_verify_depth)
2018             != NGX_OK)
2019         {
2020             return NGX_ERROR;
2021         }
2022 
2023         if (ngx_ssl_crl(cf, pscf->ssl, &pscf->ssl_crl) != NGX_OK) {
2024             return NGX_ERROR;
2025         }
2026     }
2027 
2028     return NGX_OK;
2029 }
2030 
2031 #endif
2032 
2033 
2034 static char *
2035 ngx_stream_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
2036 {
2037     ngx_stream_proxy_srv_conf_t *pscf = conf;
2038 
2039     ngx_url_t                            u;
2040     ngx_str_t                           *value, *url;
2041     ngx_stream_complex_value_t           cv;
2042     ngx_stream_core_srv_conf_t          *cscf;
2043     ngx_stream_compile_complex_value_t   ccv;
2044 
2045     if (pscf->upstream || pscf->upstream_value) {
2046         return "is duplicate";
2047     }
2048 
2049     cscf = ngx_stream_conf_get_module_srv_conf(cf, ngx_stream_core_module);
2050 
2051     cscf->handler = ngx_stream_proxy_handler;
2052 
2053     value = cf->args->elts;
2054 
2055     url = &value[1];
2056 
2057     ngx_memzero(&ccv, sizeof(ngx_stream_compile_complex_value_t));
2058 
2059     ccv.cf = cf;
2060     ccv.value = url;
2061     ccv.complex_value = &cv;
2062 
2063     if (ngx_stream_compile_complex_value(&ccv) != NGX_OK) {
2064         return NGX_CONF_ERROR;
2065     }
2066 
2067     if (cv.lengths) {
2068         pscf->upstream_value = ngx_palloc(cf->pool,
2069                                           sizeof(ngx_stream_complex_value_t));
2070         if (pscf->upstream_value == NULL) {
2071             return NGX_CONF_ERROR;
2072         }
2073 
2074         *pscf->upstream_value = cv;
2075 
2076         return NGX_CONF_OK;
2077     }
2078 
2079     ngx_memzero(&u, sizeof(ngx_url_t));
2080 
2081     u.url = *url;
2082     u.no_resolve = 1;
2083 
2084     pscf->upstream = ngx_stream_upstream_add(cf, &u, 0);
2085     if (pscf->upstream == NULL) {
2086         return NGX_CONF_ERROR;
2087     }
2088 
2089     return NGX_CONF_OK;
2090 }
2091 
2092 
2093 static char *
2094 ngx_stream_proxy_bind(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
2095 {
2096     ngx_stream_proxy_srv_conf_t *pscf = conf;
2097 
2098     ngx_int_t                            rc;
2099     ngx_str_t                           *value;
2100     ngx_stream_complex_value_t           cv;
2101     ngx_stream_upstream_local_t         *local;
2102     ngx_stream_compile_complex_value_t   ccv;
2103 
2104     if (pscf->local != NGX_CONF_UNSET_PTR) {
2105         return "is duplicate";
2106     }
2107 
2108     value = cf->args->elts;
2109 
2110     if (cf->args->nelts == 2 && ngx_strcmp(value[1].data, "off") == 0) {
2111         pscf->local = NULL;
2112         return NGX_CONF_OK;
2113     }
2114 
2115     ngx_memzero(&ccv, sizeof(ngx_stream_compile_complex_value_t));
2116 
2117     ccv.cf = cf;
2118     ccv.value = &value[1];
2119     ccv.complex_value = &cv;
2120 
2121     if (ngx_stream_compile_complex_value(&ccv) != NGX_OK) {
2122         return NGX_CONF_ERROR;
2123     }
2124 
2125     local = ngx_pcalloc(cf->pool, sizeof(ngx_stream_upstream_local_t));
2126     if (local == NULL) {
2127         return NGX_CONF_ERROR;
2128     }
2129 
2130     pscf->local = local;
2131 
2132     if (cv.lengths) {
2133         local->value = ngx_palloc(cf->pool, sizeof(ngx_stream_complex_value_t));
2134         if (local->value == NULL) {
2135             return NGX_CONF_ERROR;
2136         }
2137 
2138         *local->value = cv;
2139 
2140     } else {
2141         local->addr = ngx_palloc(cf->pool, sizeof(ngx_addr_t));
2142         if (local->addr == NULL) {
2143             return NGX_CONF_ERROR;
2144         }
2145 
2146         rc = ngx_parse_addr_port(cf->pool, local->addr, value[1].data,
2147                                  value[1].len);
2148 
2149         switch (rc) {
2150         case NGX_OK:
2151             local->addr->name = value[1];
2152             break;
2153 
2154         case NGX_DECLINED:
2155             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2156                                "invalid address \"%V\"", &value[1]);
2157             /* fall through */
2158 
2159         default:
2160             return NGX_CONF_ERROR;
2161         }
2162     }
2163 
2164     if (cf->args->nelts > 2) {
2165         if (ngx_strcmp(value[2].data, "transparent") == 0) {
2166 #if (NGX_HAVE_TRANSPARENT_PROXY)
2167             ngx_core_conf_t  *ccf;
2168 
2169             ccf = (ngx_core_conf_t *) ngx_get_conf(cf->cycle->conf_ctx,
2170                                                    ngx_core_module);
2171 
2172             ccf->transparent = 1;
2173             local->transparent = 1;
2174 #else
2175             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2176                                "transparent proxying is not supported "
2177                                "on this platform, ignored");
2178 #endif
2179         } else {
2180             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2181                                "invalid parameter \"%V\"", &value[2]);
2182             return NGX_CONF_ERROR;
2183         }
2184     }
2185 
2186     return NGX_CONF_OK;
2187 }