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_null_string, 0 }
0107 };
0108 
0109 #endif
0110 
0111 
0112 static ngx_conf_deprecated_t  ngx_conf_deprecated_proxy_downstream_buffer = {
0113     ngx_conf_deprecated, "proxy_downstream_buffer", "proxy_buffer_size"
0114 };
0115 
0116 static ngx_conf_deprecated_t  ngx_conf_deprecated_proxy_upstream_buffer = {
0117     ngx_conf_deprecated, "proxy_upstream_buffer", "proxy_buffer_size"
0118 };
0119 
0120 
0121 static ngx_command_t  ngx_stream_proxy_commands[] = {
0122 
0123     { ngx_string("proxy_pass"),
0124       NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
0125       ngx_stream_proxy_pass,
0126       NGX_STREAM_SRV_CONF_OFFSET,
0127       0,
0128       NULL },
0129 
0130     { ngx_string("proxy_bind"),
0131       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE12,
0132       ngx_stream_proxy_bind,
0133       NGX_STREAM_SRV_CONF_OFFSET,
0134       0,
0135       NULL },
0136 
0137     { ngx_string("proxy_connect_timeout"),
0138       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
0139       ngx_conf_set_msec_slot,
0140       NGX_STREAM_SRV_CONF_OFFSET,
0141       offsetof(ngx_stream_proxy_srv_conf_t, connect_timeout),
0142       NULL },
0143 
0144     { ngx_string("proxy_timeout"),
0145       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
0146       ngx_conf_set_msec_slot,
0147       NGX_STREAM_SRV_CONF_OFFSET,
0148       offsetof(ngx_stream_proxy_srv_conf_t, timeout),
0149       NULL },
0150 
0151     { ngx_string("proxy_buffer_size"),
0152       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
0153       ngx_conf_set_size_slot,
0154       NGX_STREAM_SRV_CONF_OFFSET,
0155       offsetof(ngx_stream_proxy_srv_conf_t, buffer_size),
0156       NULL },
0157 
0158     { ngx_string("proxy_downstream_buffer"),
0159       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
0160       ngx_conf_set_size_slot,
0161       NGX_STREAM_SRV_CONF_OFFSET,
0162       offsetof(ngx_stream_proxy_srv_conf_t, buffer_size),
0163       &ngx_conf_deprecated_proxy_downstream_buffer },
0164 
0165     { ngx_string("proxy_upstream_buffer"),
0166       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
0167       ngx_conf_set_size_slot,
0168       NGX_STREAM_SRV_CONF_OFFSET,
0169       offsetof(ngx_stream_proxy_srv_conf_t, buffer_size),
0170       &ngx_conf_deprecated_proxy_upstream_buffer },
0171 
0172     { ngx_string("proxy_upload_rate"),
0173       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
0174       ngx_conf_set_size_slot,
0175       NGX_STREAM_SRV_CONF_OFFSET,
0176       offsetof(ngx_stream_proxy_srv_conf_t, upload_rate),
0177       NULL },
0178 
0179     { ngx_string("proxy_download_rate"),
0180       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
0181       ngx_conf_set_size_slot,
0182       NGX_STREAM_SRV_CONF_OFFSET,
0183       offsetof(ngx_stream_proxy_srv_conf_t, download_rate),
0184       NULL },
0185 
0186     { ngx_string("proxy_responses"),
0187       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
0188       ngx_conf_set_num_slot,
0189       NGX_STREAM_SRV_CONF_OFFSET,
0190       offsetof(ngx_stream_proxy_srv_conf_t, responses),
0191       NULL },
0192 
0193     { ngx_string("proxy_next_upstream"),
0194       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
0195       ngx_conf_set_flag_slot,
0196       NGX_STREAM_SRV_CONF_OFFSET,
0197       offsetof(ngx_stream_proxy_srv_conf_t, next_upstream),
0198       NULL },
0199 
0200     { ngx_string("proxy_next_upstream_tries"),
0201       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
0202       ngx_conf_set_num_slot,
0203       NGX_STREAM_SRV_CONF_OFFSET,
0204       offsetof(ngx_stream_proxy_srv_conf_t, next_upstream_tries),
0205       NULL },
0206 
0207     { ngx_string("proxy_next_upstream_timeout"),
0208       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
0209       ngx_conf_set_msec_slot,
0210       NGX_STREAM_SRV_CONF_OFFSET,
0211       offsetof(ngx_stream_proxy_srv_conf_t, next_upstream_timeout),
0212       NULL },
0213 
0214     { ngx_string("proxy_protocol"),
0215       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
0216       ngx_conf_set_flag_slot,
0217       NGX_STREAM_SRV_CONF_OFFSET,
0218       offsetof(ngx_stream_proxy_srv_conf_t, proxy_protocol),
0219       NULL },
0220 
0221 #if (NGX_STREAM_SSL)
0222 
0223     { ngx_string("proxy_ssl"),
0224       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
0225       ngx_conf_set_flag_slot,
0226       NGX_STREAM_SRV_CONF_OFFSET,
0227       offsetof(ngx_stream_proxy_srv_conf_t, ssl_enable),
0228       NULL },
0229 
0230     { ngx_string("proxy_ssl_session_reuse"),
0231       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
0232       ngx_conf_set_flag_slot,
0233       NGX_STREAM_SRV_CONF_OFFSET,
0234       offsetof(ngx_stream_proxy_srv_conf_t, ssl_session_reuse),
0235       NULL },
0236 
0237     { ngx_string("proxy_ssl_protocols"),
0238       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_1MORE,
0239       ngx_conf_set_bitmask_slot,
0240       NGX_STREAM_SRV_CONF_OFFSET,
0241       offsetof(ngx_stream_proxy_srv_conf_t, ssl_protocols),
0242       &ngx_stream_proxy_ssl_protocols },
0243 
0244     { ngx_string("proxy_ssl_ciphers"),
0245       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
0246       ngx_conf_set_str_slot,
0247       NGX_STREAM_SRV_CONF_OFFSET,
0248       offsetof(ngx_stream_proxy_srv_conf_t, ssl_ciphers),
0249       NULL },
0250 
0251     { ngx_string("proxy_ssl_name"),
0252       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
0253       ngx_stream_set_complex_value_slot,
0254       NGX_STREAM_SRV_CONF_OFFSET,
0255       offsetof(ngx_stream_proxy_srv_conf_t, ssl_name),
0256       NULL },
0257 
0258     { ngx_string("proxy_ssl_server_name"),
0259       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
0260       ngx_conf_set_flag_slot,
0261       NGX_STREAM_SRV_CONF_OFFSET,
0262       offsetof(ngx_stream_proxy_srv_conf_t, ssl_server_name),
0263       NULL },
0264 
0265     { ngx_string("proxy_ssl_verify"),
0266       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
0267       ngx_conf_set_flag_slot,
0268       NGX_STREAM_SRV_CONF_OFFSET,
0269       offsetof(ngx_stream_proxy_srv_conf_t, ssl_verify),
0270       NULL },
0271 
0272     { ngx_string("proxy_ssl_verify_depth"),
0273       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
0274       ngx_conf_set_num_slot,
0275       NGX_STREAM_SRV_CONF_OFFSET,
0276       offsetof(ngx_stream_proxy_srv_conf_t, ssl_verify_depth),
0277       NULL },
0278 
0279     { ngx_string("proxy_ssl_trusted_certificate"),
0280       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
0281       ngx_conf_set_str_slot,
0282       NGX_STREAM_SRV_CONF_OFFSET,
0283       offsetof(ngx_stream_proxy_srv_conf_t, ssl_trusted_certificate),
0284       NULL },
0285 
0286     { ngx_string("proxy_ssl_crl"),
0287       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
0288       ngx_conf_set_str_slot,
0289       NGX_STREAM_SRV_CONF_OFFSET,
0290       offsetof(ngx_stream_proxy_srv_conf_t, ssl_crl),
0291       NULL },
0292 
0293     { ngx_string("proxy_ssl_certificate"),
0294       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
0295       ngx_conf_set_str_slot,
0296       NGX_STREAM_SRV_CONF_OFFSET,
0297       offsetof(ngx_stream_proxy_srv_conf_t, ssl_certificate),
0298       NULL },
0299 
0300     { ngx_string("proxy_ssl_certificate_key"),
0301       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
0302       ngx_conf_set_str_slot,
0303       NGX_STREAM_SRV_CONF_OFFSET,
0304       offsetof(ngx_stream_proxy_srv_conf_t, ssl_certificate_key),
0305       NULL },
0306 
0307     { ngx_string("proxy_ssl_password_file"),
0308       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
0309       ngx_stream_proxy_ssl_password_file,
0310       NGX_STREAM_SRV_CONF_OFFSET,
0311       0,
0312       NULL },
0313 
0314 #endif
0315 
0316       ngx_null_command
0317 };
0318 
0319 
0320 static ngx_stream_module_t  ngx_stream_proxy_module_ctx = {
0321     NULL,                                  /* preconfiguration */
0322     NULL,                                  /* postconfiguration */
0323 
0324     NULL,                                  /* create main configuration */
0325     NULL,                                  /* init main configuration */
0326 
0327     ngx_stream_proxy_create_srv_conf,      /* create server configuration */
0328     ngx_stream_proxy_merge_srv_conf        /* merge server configuration */
0329 };
0330 
0331 
0332 ngx_module_t  ngx_stream_proxy_module = {
0333     NGX_MODULE_V1,
0334     &ngx_stream_proxy_module_ctx,          /* module context */
0335     ngx_stream_proxy_commands,             /* module directives */
0336     NGX_STREAM_MODULE,                     /* module type */
0337     NULL,                                  /* init master */
0338     NULL,                                  /* init module */
0339     NULL,                                  /* init process */
0340     NULL,                                  /* init thread */
0341     NULL,                                  /* exit thread */
0342     NULL,                                  /* exit process */
0343     NULL,                                  /* exit master */
0344     NGX_MODULE_V1_PADDING
0345 };
0346 
0347 
0348 static void
0349 ngx_stream_proxy_handler(ngx_stream_session_t *s)
0350 {
0351     u_char                           *p;
0352     ngx_str_t                        *host;
0353     ngx_uint_t                        i;
0354     ngx_connection_t                 *c;
0355     ngx_resolver_ctx_t               *ctx, temp;
0356     ngx_stream_upstream_t            *u;
0357     ngx_stream_core_srv_conf_t       *cscf;
0358     ngx_stream_proxy_srv_conf_t      *pscf;
0359     ngx_stream_upstream_srv_conf_t   *uscf, **uscfp;
0360     ngx_stream_upstream_main_conf_t  *umcf;
0361 
0362     c = s->connection;
0363 
0364     pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);
0365 
0366     ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0,
0367                    "proxy connection handler");
0368 
0369     u = ngx_pcalloc(c->pool, sizeof(ngx_stream_upstream_t));
0370     if (u == NULL) {
0371         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
0372         return;
0373     }
0374 
0375     s->upstream = u;
0376 
0377     s->log_handler = ngx_stream_proxy_log_error;
0378 
0379     u->peer.log = c->log;
0380     u->peer.log_error = NGX_ERROR_ERR;
0381 
0382     if (ngx_stream_proxy_set_local(s, u, pscf->local) != NGX_OK) {
0383         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
0384         return;
0385     }
0386 
0387     u->peer.type = c->type;
0388     u->start_sec = ngx_time();
0389 
0390     c->write->handler = ngx_stream_proxy_downstream_handler;
0391     c->read->handler = ngx_stream_proxy_downstream_handler;
0392 
0393     s->upstream_states = ngx_array_create(c->pool, 1,
0394                                           sizeof(ngx_stream_upstream_state_t));
0395     if (s->upstream_states == NULL) {
0396         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
0397         return;
0398     }
0399 
0400     if (c->type == SOCK_STREAM) {
0401         p = ngx_pnalloc(c->pool, pscf->buffer_size);
0402         if (p == NULL) {
0403             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
0404             return;
0405         }
0406 
0407         u->downstream_buf.start = p;
0408         u->downstream_buf.end = p + pscf->buffer_size;
0409         u->downstream_buf.pos = p;
0410         u->downstream_buf.last = p;
0411 
0412         if (c->read->ready) {
0413             ngx_post_event(c->read, &ngx_posted_events);
0414         }
0415     }
0416 
0417     if (pscf->upstream_value) {
0418         if (ngx_stream_proxy_eval(s, pscf) != NGX_OK) {
0419             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
0420             return;
0421         }
0422     }
0423 
0424     if (u->resolved == NULL) {
0425 
0426         uscf = pscf->upstream;
0427 
0428     } else {
0429 
0430 #if (NGX_STREAM_SSL)
0431         u->ssl_name = u->resolved->host;
0432 #endif
0433 
0434         host = &u->resolved->host;
0435 
0436         umcf = ngx_stream_get_module_main_conf(s, ngx_stream_upstream_module);
0437 
0438         uscfp = umcf->upstreams.elts;
0439 
0440         for (i = 0; i < umcf->upstreams.nelts; i++) {
0441 
0442             uscf = uscfp[i];
0443 
0444             if (uscf->host.len == host->len
0445                 && ((uscf->port == 0 && u->resolved->no_port)
0446                      || uscf->port == u->resolved->port)
0447                 && ngx_strncasecmp(uscf->host.data, host->data, host->len) == 0)
0448             {
0449                 goto found;
0450             }
0451         }
0452 
0453         if (u->resolved->sockaddr) {
0454 
0455             if (u->resolved->port == 0
0456                 && u->resolved->sockaddr->sa_family != AF_UNIX)
0457             {
0458                 ngx_log_error(NGX_LOG_ERR, c->log, 0,
0459                               "no port in upstream \"%V\"", host);
0460                 ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
0461                 return;
0462             }
0463 
0464             if (ngx_stream_upstream_create_round_robin_peer(s, u->resolved)
0465                 != NGX_OK)
0466             {
0467                 ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
0468                 return;
0469             }
0470 
0471             ngx_stream_proxy_connect(s);
0472 
0473             return;
0474         }
0475 
0476         if (u->resolved->port == 0) {
0477             ngx_log_error(NGX_LOG_ERR, c->log, 0,
0478                           "no port in upstream \"%V\"", host);
0479             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
0480             return;
0481         }
0482 
0483         temp.name = *host;
0484 
0485         cscf = ngx_stream_get_module_srv_conf(s, ngx_stream_core_module);
0486 
0487         ctx = ngx_resolve_start(cscf->resolver, &temp);
0488         if (ctx == NULL) {
0489             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
0490             return;
0491         }
0492 
0493         if (ctx == NGX_NO_RESOLVER) {
0494             ngx_log_error(NGX_LOG_ERR, c->log, 0,
0495                           "no resolver defined to resolve %V", host);
0496             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
0497             return;
0498         }
0499 
0500         ctx->name = *host;
0501         ctx->handler = ngx_stream_proxy_resolve_handler;
0502         ctx->data = s;
0503         ctx->timeout = cscf->resolver_timeout;
0504 
0505         u->resolved->ctx = ctx;
0506 
0507         if (ngx_resolve_name(ctx) != NGX_OK) {
0508             u->resolved->ctx = NULL;
0509             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
0510             return;
0511         }
0512 
0513         return;
0514     }
0515 
0516 found:
0517 
0518     if (uscf == NULL) {
0519         ngx_log_error(NGX_LOG_ALERT, c->log, 0, "no upstream configuration");
0520         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
0521         return;
0522     }
0523 
0524     u->upstream = uscf;
0525 
0526 #if (NGX_STREAM_SSL)
0527     u->ssl_name = uscf->host;
0528 #endif
0529 
0530     if (uscf->peer.init(s, uscf) != NGX_OK) {
0531         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
0532         return;
0533     }
0534 
0535     u->peer.start_time = ngx_current_msec;
0536 
0537     if (pscf->next_upstream_tries
0538         && u->peer.tries > pscf->next_upstream_tries)
0539     {
0540         u->peer.tries = pscf->next_upstream_tries;
0541     }
0542 
0543     ngx_stream_proxy_connect(s);
0544 }
0545 
0546 
0547 static ngx_int_t
0548 ngx_stream_proxy_eval(ngx_stream_session_t *s,
0549     ngx_stream_proxy_srv_conf_t *pscf)
0550 {
0551     ngx_str_t               host;
0552     ngx_url_t               url;
0553     ngx_stream_upstream_t  *u;
0554 
0555     if (ngx_stream_complex_value(s, pscf->upstream_value, &host) != NGX_OK) {
0556         return NGX_ERROR;
0557     }
0558 
0559     ngx_memzero(&url, sizeof(ngx_url_t));
0560 
0561     url.url = host;
0562     url.no_resolve = 1;
0563 
0564     if (ngx_parse_url(s->connection->pool, &url) != NGX_OK) {
0565         if (url.err) {
0566             ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
0567                           "%s in upstream \"%V\"", url.err, &url.url);
0568         }
0569 
0570         return NGX_ERROR;
0571     }
0572 
0573     u = s->upstream;
0574 
0575     u->resolved = ngx_pcalloc(s->connection->pool,
0576                               sizeof(ngx_stream_upstream_resolved_t));
0577     if (u->resolved == NULL) {
0578         return NGX_ERROR;
0579     }
0580 
0581     if (url.addrs) {
0582         u->resolved->sockaddr = url.addrs[0].sockaddr;
0583         u->resolved->socklen = url.addrs[0].socklen;
0584         u->resolved->name = url.addrs[0].name;
0585         u->resolved->naddrs = 1;
0586     }
0587 
0588     u->resolved->host = url.host;
0589     u->resolved->port = url.port;
0590     u->resolved->no_port = url.no_port;
0591 
0592     return NGX_OK;
0593 }
0594 
0595 
0596 static ngx_int_t
0597 ngx_stream_proxy_set_local(ngx_stream_session_t *s, ngx_stream_upstream_t *u,
0598     ngx_stream_upstream_local_t *local)
0599 {
0600     ngx_int_t    rc;
0601     ngx_str_t    val;
0602     ngx_addr_t  *addr;
0603 
0604     if (local == NULL) {
0605         u->peer.local = NULL;
0606         return NGX_OK;
0607     }
0608 
0609 #if (NGX_HAVE_TRANSPARENT_PROXY)
0610     u->peer.transparent = local->transparent;
0611 #endif
0612 
0613     if (local->value == NULL) {
0614         u->peer.local = local->addr;
0615         return NGX_OK;
0616     }
0617 
0618     if (ngx_stream_complex_value(s, local->value, &val) != NGX_OK) {
0619         return NGX_ERROR;
0620     }
0621 
0622     if (val.len == 0) {
0623         return NGX_OK;
0624     }
0625 
0626     addr = ngx_palloc(s->connection->pool, sizeof(ngx_addr_t));
0627     if (addr == NULL) {
0628         return NGX_ERROR;
0629     }
0630 
0631     rc = ngx_parse_addr_port(s->connection->pool, addr, val.data, val.len);
0632     if (rc == NGX_ERROR) {
0633         return NGX_ERROR;
0634     }
0635 
0636     if (rc != NGX_OK) {
0637         ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
0638                       "invalid local address \"%V\"", &val);
0639         return NGX_OK;
0640     }
0641 
0642     addr->name = val;
0643     u->peer.local = addr;
0644 
0645     return NGX_OK;
0646 }
0647 
0648 
0649 static void
0650 ngx_stream_proxy_connect(ngx_stream_session_t *s)
0651 {
0652     ngx_int_t                     rc;
0653     ngx_connection_t             *c, *pc;
0654     ngx_stream_upstream_t        *u;
0655     ngx_stream_proxy_srv_conf_t  *pscf;
0656 
0657     c = s->connection;
0658 
0659     c->log->action = "connecting to upstream";
0660 
0661     pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);
0662 
0663     u = s->upstream;
0664 
0665     u->connected = 0;
0666     u->proxy_protocol = pscf->proxy_protocol;
0667 
0668     if (u->state) {
0669         u->state->response_time = ngx_current_msec - u->state->response_time;
0670     }
0671 
0672     u->state = ngx_array_push(s->upstream_states);
0673     if (u->state == NULL) {
0674         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
0675         return;
0676     }
0677 
0678     ngx_memzero(u->state, sizeof(ngx_stream_upstream_state_t));
0679 
0680     u->state->connect_time = (ngx_msec_t) -1;
0681     u->state->first_byte_time = (ngx_msec_t) -1;
0682     u->state->response_time = ngx_current_msec;
0683 
0684     rc = ngx_event_connect_peer(&u->peer);
0685 
0686     ngx_log_debug1(NGX_LOG_DEBUG_STREAM, c->log, 0, "proxy connect: %i", rc);
0687 
0688     if (rc == NGX_ERROR) {
0689         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
0690         return;
0691     }
0692 
0693     u->state->peer = u->peer.name;
0694 
0695     if (rc == NGX_BUSY) {
0696         ngx_log_error(NGX_LOG_ERR, c->log, 0, "no live upstreams");
0697         ngx_stream_proxy_finalize(s, NGX_STREAM_BAD_GATEWAY);
0698         return;
0699     }
0700 
0701     if (rc == NGX_DECLINED) {
0702         ngx_stream_proxy_next_upstream(s);
0703         return;
0704     }
0705 
0706     /* rc == NGX_OK || rc == NGX_AGAIN || rc == NGX_DONE */
0707 
0708     pc = u->peer.connection;
0709 
0710     pc->data = s;
0711     pc->log = c->log;
0712     pc->pool = c->pool;
0713     pc->read->log = c->log;
0714     pc->write->log = c->log;
0715 
0716     if (rc != NGX_AGAIN) {
0717         ngx_stream_proxy_init_upstream(s);
0718         return;
0719     }
0720 
0721     pc->read->handler = ngx_stream_proxy_connect_handler;
0722     pc->write->handler = ngx_stream_proxy_connect_handler;
0723 
0724     ngx_add_timer(pc->write, pscf->connect_timeout);
0725 }
0726 
0727 
0728 static void
0729 ngx_stream_proxy_init_upstream(ngx_stream_session_t *s)
0730 {
0731     int                           tcp_nodelay;
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         && pc->tcp_nodelay == NGX_TCP_NODELAY_UNSET)
0748     {
0749         ngx_log_debug0(NGX_LOG_DEBUG_STREAM, pc->log, 0, "tcp_nodelay");
0750 
0751         tcp_nodelay = 1;
0752 
0753         if (setsockopt(pc->fd, IPPROTO_TCP, TCP_NODELAY,
0754                        (const void *) &tcp_nodelay, sizeof(int)) == -1)
0755         {
0756             ngx_connection_error(pc, ngx_socket_errno,
0757                                  "setsockopt(TCP_NODELAY) failed");
0758             ngx_stream_proxy_next_upstream(s);
0759             return;
0760         }
0761 
0762         pc->tcp_nodelay = NGX_TCP_NODELAY_SET;
0763     }
0764 
0765     pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);
0766 
0767 #if (NGX_STREAM_SSL)
0768 
0769     if (pc->type == SOCK_STREAM && pscf->ssl) {
0770 
0771         if (u->proxy_protocol) {
0772             if (ngx_stream_proxy_send_proxy_protocol(s) != NGX_OK) {
0773                 return;
0774             }
0775 
0776             u->proxy_protocol = 0;
0777         }
0778 
0779         if (pc->ssl == NULL) {
0780             ngx_stream_proxy_ssl_init_connection(s);
0781             return;
0782         }
0783     }
0784 
0785 #endif
0786 
0787     c = s->connection;
0788 
0789     if (c->log->log_level >= NGX_LOG_INFO) {
0790         ngx_str_t  str;
0791         u_char     addr[NGX_SOCKADDR_STRLEN];
0792 
0793         str.len = NGX_SOCKADDR_STRLEN;
0794         str.data = addr;
0795 
0796         if (ngx_connection_local_sockaddr(pc, &str, 1) == NGX_OK) {
0797             handler = c->log->handler;
0798             c->log->handler = NULL;
0799 
0800             ngx_log_error(NGX_LOG_INFO, c->log, 0,
0801                           "%sproxy %V connected to %V",
0802                           pc->type == SOCK_DGRAM ? "udp " : "",
0803                           &str, u->peer.name);
0804 
0805             c->log->handler = handler;
0806         }
0807     }
0808 
0809     u->state->connect_time = ngx_current_msec - u->state->response_time;
0810 
0811     if (u->peer.notify) {
0812         u->peer.notify(&u->peer, u->peer.data,
0813                        NGX_STREAM_UPSTREAM_NOTIFY_CONNECT);
0814     }
0815 
0816     c->log->action = "proxying connection";
0817 
0818     if (u->upstream_buf.start == NULL) {
0819         p = ngx_pnalloc(c->pool, pscf->buffer_size);
0820         if (p == NULL) {
0821             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
0822             return;
0823         }
0824 
0825         u->upstream_buf.start = p;
0826         u->upstream_buf.end = p + pscf->buffer_size;
0827         u->upstream_buf.pos = p;
0828         u->upstream_buf.last = p;
0829     }
0830 
0831     if (c->buffer && c->buffer->pos < c->buffer->last) {
0832         ngx_log_debug1(NGX_LOG_DEBUG_STREAM, c->log, 0,
0833                        "stream proxy add preread buffer: %uz",
0834                        c->buffer->last - c->buffer->pos);
0835 
0836         cl = ngx_chain_get_free_buf(c->pool, &u->free);
0837         if (cl == NULL) {
0838             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
0839             return;
0840         }
0841 
0842         *cl->buf = *c->buffer;
0843 
0844         cl->buf->tag = (ngx_buf_tag_t) &ngx_stream_proxy_module;
0845         cl->buf->flush = 1;
0846         cl->buf->last_buf = (c->type == SOCK_DGRAM);
0847 
0848         cl->next = u->upstream_out;
0849         u->upstream_out = cl;
0850     }
0851 
0852     if (u->proxy_protocol) {
0853         ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0,
0854                        "stream proxy add PROXY protocol header");
0855 
0856         cl = ngx_chain_get_free_buf(c->pool, &u->free);
0857         if (cl == NULL) {
0858             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
0859             return;
0860         }
0861 
0862         p = ngx_pnalloc(c->pool, NGX_PROXY_PROTOCOL_MAX_HEADER);
0863         if (p == NULL) {
0864             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
0865             return;
0866         }
0867 
0868         cl->buf->pos = p;
0869 
0870         p = ngx_proxy_protocol_write(c, p, p + NGX_PROXY_PROTOCOL_MAX_HEADER);
0871         if (p == NULL) {
0872             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
0873             return;
0874         }
0875 
0876         cl->buf->last = p;
0877         cl->buf->temporary = 1;
0878         cl->buf->flush = 0;
0879         cl->buf->last_buf = 0;
0880         cl->buf->tag = (ngx_buf_tag_t) &ngx_stream_proxy_module;
0881 
0882         cl->next = u->upstream_out;
0883         u->upstream_out = cl;
0884 
0885         u->proxy_protocol = 0;
0886     }
0887 
0888     if (c->type == SOCK_DGRAM && pscf->responses == 0) {
0889         pc->read->ready = 0;
0890         pc->read->eof = 1;
0891     }
0892 
0893     u->connected = 1;
0894 
0895     pc->read->handler = ngx_stream_proxy_upstream_handler;
0896     pc->write->handler = ngx_stream_proxy_upstream_handler;
0897 
0898     if (pc->read->ready || pc->read->eof) {
0899         ngx_post_event(pc->read, &ngx_posted_events);
0900     }
0901 
0902     ngx_stream_proxy_process(s, 0, 1);
0903 }
0904 
0905 
0906 #if (NGX_STREAM_SSL)
0907 
0908 static ngx_int_t
0909 ngx_stream_proxy_send_proxy_protocol(ngx_stream_session_t *s)
0910 {
0911     u_char                       *p;
0912     ssize_t                       n, size;
0913     ngx_connection_t             *c, *pc;
0914     ngx_stream_upstream_t        *u;
0915     ngx_stream_proxy_srv_conf_t  *pscf;
0916     u_char                        buf[NGX_PROXY_PROTOCOL_MAX_HEADER];
0917 
0918     c = s->connection;
0919 
0920     ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0,
0921                    "stream proxy send PROXY protocol header");
0922 
0923     p = ngx_proxy_protocol_write(c, buf, buf + NGX_PROXY_PROTOCOL_MAX_HEADER);
0924     if (p == NULL) {
0925         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
0926         return NGX_ERROR;
0927     }
0928 
0929     u = s->upstream;
0930 
0931     pc = u->peer.connection;
0932 
0933     size = p - buf;
0934 
0935     n = pc->send(pc, buf, size);
0936 
0937     if (n == NGX_AGAIN) {
0938         if (ngx_handle_write_event(pc->write, 0) != NGX_OK) {
0939             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
0940             return NGX_ERROR;
0941         }
0942 
0943         pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);
0944 
0945         ngx_add_timer(pc->write, pscf->timeout);
0946 
0947         pc->write->handler = ngx_stream_proxy_connect_handler;
0948 
0949         return NGX_AGAIN;
0950     }
0951 
0952     if (n == NGX_ERROR) {
0953         ngx_stream_proxy_finalize(s, NGX_STREAM_OK);
0954         return NGX_ERROR;
0955     }
0956 
0957     if (n != size) {
0958 
0959         /*
0960          * PROXY protocol specification:
0961          * The sender must always ensure that the header
0962          * is sent at once, so that the transport layer
0963          * maintains atomicity along the path to the receiver.
0964          */
0965 
0966         ngx_log_error(NGX_LOG_ERR, c->log, 0,
0967                       "could not send PROXY protocol header at once");
0968 
0969         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
0970 
0971         return NGX_ERROR;
0972     }
0973 
0974     return NGX_OK;
0975 }
0976 
0977 
0978 static char *
0979 ngx_stream_proxy_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd,
0980     void *conf)
0981 {
0982     ngx_stream_proxy_srv_conf_t *pscf = conf;
0983 
0984     ngx_str_t  *value;
0985 
0986     if (pscf->ssl_passwords != NGX_CONF_UNSET_PTR) {
0987         return "is duplicate";
0988     }
0989 
0990     value = cf->args->elts;
0991 
0992     pscf->ssl_passwords = ngx_ssl_read_password_file(cf, &value[1]);
0993 
0994     if (pscf->ssl_passwords == NULL) {
0995         return NGX_CONF_ERROR;
0996     }
0997 
0998     return NGX_CONF_OK;
0999 }
1000 
1001 
1002 static void
1003 ngx_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 
1055 static void
1056 ngx_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 
1103 failed:
1104 
1105     ngx_stream_proxy_next_upstream(s);
1106 }
1107 
1108 
1109 static ngx_int_t
1110 ngx_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 
1200 done:
1201 
1202     u->ssl_name = name;
1203 
1204     return NGX_OK;
1205 }
1206 
1207 #endif
1208 
1209 
1210 static void
1211 ngx_stream_proxy_downstream_handler(ngx_event_t *ev)
1212 {
1213     ngx_stream_proxy_process_connection(ev, ev->write);
1214 }
1215 
1216 
1217 static void
1218 ngx_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 
1286 static void
1287 ngx_stream_proxy_upstream_handler(ngx_event_t *ev)
1288 {
1289     ngx_stream_proxy_process_connection(ev, !ev->write);
1290 }
1291 
1292 
1293 static void
1294 ngx_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 
1377 static void
1378 ngx_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 
1406 static ngx_int_t
1407 ngx_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 
1450 static void
1451 ngx_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 
1666 static void
1667 ngx_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 (pc && pc->buffered) {
1681         ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
1682                       "buffered data on next upstream");
1683         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
1684         return;
1685     }
1686 
1687     if (s->connection->type == SOCK_DGRAM) {
1688         u->upstream_out = NULL;
1689     }
1690 
1691     if (u->peer.sockaddr) {
1692         u->peer.free(&u->peer, u->peer.data, NGX_PEER_FAILED);
1693         u->peer.sockaddr = NULL;
1694     }
1695 
1696     pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);
1697 
1698     timeout = pscf->next_upstream_timeout;
1699 
1700     if (u->peer.tries == 0
1701         || !pscf->next_upstream
1702         || (timeout && ngx_current_msec - u->peer.start_time >= timeout))
1703     {
1704         ngx_stream_proxy_finalize(s, NGX_STREAM_BAD_GATEWAY);
1705         return;
1706     }
1707 
1708     if (pc) {
1709         ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
1710                        "close proxy upstream connection: %d", pc->fd);
1711 
1712 #if (NGX_STREAM_SSL)
1713         if (pc->ssl) {
1714             pc->ssl->no_wait_shutdown = 1;
1715             pc->ssl->no_send_shutdown = 1;
1716 
1717             (void) ngx_ssl_shutdown(pc);
1718         }
1719 #endif
1720 
1721         u->state->bytes_received = u->received;
1722         u->state->bytes_sent = pc->sent;
1723 
1724         ngx_close_connection(pc);
1725         u->peer.connection = NULL;
1726     }
1727 
1728     ngx_stream_proxy_connect(s);
1729 }
1730 
1731 
1732 static void
1733 ngx_stream_proxy_finalize(ngx_stream_session_t *s, ngx_uint_t rc)
1734 {
1735     ngx_connection_t       *pc;
1736     ngx_stream_upstream_t  *u;
1737 
1738     ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
1739                    "finalize stream proxy: %i", rc);
1740 
1741     u = s->upstream;
1742 
1743     if (u == NULL) {
1744         goto noupstream;
1745     }
1746 
1747     if (u->resolved && u->resolved->ctx) {
1748         ngx_resolve_name_done(u->resolved->ctx);
1749         u->resolved->ctx = NULL;
1750     }
1751 
1752     pc = u->peer.connection;
1753 
1754     if (u->state) {
1755         u->state->response_time = ngx_current_msec - u->state->response_time;
1756 
1757         if (pc) {
1758             u->state->bytes_received = u->received;
1759             u->state->bytes_sent = pc->sent;
1760         }
1761     }
1762 
1763     if (u->peer.free && u->peer.sockaddr) {
1764         u->peer.free(&u->peer, u->peer.data, 0);
1765         u->peer.sockaddr = NULL;
1766     }
1767 
1768     if (pc) {
1769         ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
1770                        "close stream proxy upstream connection: %d", pc->fd);
1771 
1772 #if (NGX_STREAM_SSL)
1773         if (pc->ssl) {
1774             pc->ssl->no_wait_shutdown = 1;
1775             (void) ngx_ssl_shutdown(pc);
1776         }
1777 #endif
1778 
1779         ngx_close_connection(pc);
1780         u->peer.connection = NULL;
1781     }
1782 
1783 noupstream:
1784 
1785     ngx_stream_finalize_session(s, rc);
1786 }
1787 
1788 
1789 static u_char *
1790 ngx_stream_proxy_log_error(ngx_log_t *log, u_char *buf, size_t len)
1791 {
1792     u_char                 *p;
1793     ngx_connection_t       *pc;
1794     ngx_stream_session_t   *s;
1795     ngx_stream_upstream_t  *u;
1796 
1797     s = log->data;
1798 
1799     u = s->upstream;
1800 
1801     p = buf;
1802 
1803     if (u->peer.name) {
1804         p = ngx_snprintf(p, len, ", upstream: \"%V\"", u->peer.name);
1805         len -= p - buf;
1806     }
1807 
1808     pc = u->peer.connection;
1809 
1810     p = ngx_snprintf(p, len,
1811                      ", bytes from/to client:%O/%O"
1812                      ", bytes from/to upstream:%O/%O",
1813                      s->received, s->connection->sent,
1814                      u->received, pc ? pc->sent : 0);
1815 
1816     return p;
1817 }
1818 
1819 
1820 static void *
1821 ngx_stream_proxy_create_srv_conf(ngx_conf_t *cf)
1822 {
1823     ngx_stream_proxy_srv_conf_t  *conf;
1824 
1825     conf = ngx_pcalloc(cf->pool, sizeof(ngx_stream_proxy_srv_conf_t));
1826     if (conf == NULL) {
1827         return NULL;
1828     }
1829 
1830     /*
1831      * set by ngx_pcalloc():
1832      *
1833      *     conf->ssl_protocols = 0;
1834      *     conf->ssl_ciphers = { 0, NULL };
1835      *     conf->ssl_name = NULL;
1836      *     conf->ssl_trusted_certificate = { 0, NULL };
1837      *     conf->ssl_crl = { 0, NULL };
1838      *     conf->ssl_certificate = { 0, NULL };
1839      *     conf->ssl_certificate_key = { 0, NULL };
1840      *
1841      *     conf->ssl = NULL;
1842      *     conf->upstream = NULL;
1843      *     conf->upstream_value = NULL;
1844      */
1845 
1846     conf->connect_timeout = NGX_CONF_UNSET_MSEC;
1847     conf->timeout = NGX_CONF_UNSET_MSEC;
1848     conf->next_upstream_timeout = NGX_CONF_UNSET_MSEC;
1849     conf->buffer_size = NGX_CONF_UNSET_SIZE;
1850     conf->upload_rate = NGX_CONF_UNSET_SIZE;
1851     conf->download_rate = NGX_CONF_UNSET_SIZE;
1852     conf->responses = NGX_CONF_UNSET_UINT;
1853     conf->next_upstream_tries = NGX_CONF_UNSET_UINT;
1854     conf->next_upstream = NGX_CONF_UNSET;
1855     conf->proxy_protocol = NGX_CONF_UNSET;
1856     conf->local = NGX_CONF_UNSET_PTR;
1857 
1858 #if (NGX_STREAM_SSL)
1859     conf->ssl_enable = NGX_CONF_UNSET;
1860     conf->ssl_session_reuse = NGX_CONF_UNSET;
1861     conf->ssl_server_name = NGX_CONF_UNSET;
1862     conf->ssl_verify = NGX_CONF_UNSET;
1863     conf->ssl_verify_depth = NGX_CONF_UNSET_UINT;
1864     conf->ssl_passwords = NGX_CONF_UNSET_PTR;
1865 #endif
1866 
1867     return conf;
1868 }
1869 
1870 
1871 static char *
1872 ngx_stream_proxy_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
1873 {
1874     ngx_stream_proxy_srv_conf_t *prev = parent;
1875     ngx_stream_proxy_srv_conf_t *conf = child;
1876 
1877     ngx_conf_merge_msec_value(conf->connect_timeout,
1878                               prev->connect_timeout, 60000);
1879 
1880     ngx_conf_merge_msec_value(conf->timeout,
1881                               prev->timeout, 10 * 60000);
1882 
1883     ngx_conf_merge_msec_value(conf->next_upstream_timeout,
1884                               prev->next_upstream_timeout, 0);
1885 
1886     ngx_conf_merge_size_value(conf->buffer_size,
1887                               prev->buffer_size, 16384);
1888 
1889     ngx_conf_merge_size_value(conf->upload_rate,
1890                               prev->upload_rate, 0);
1891 
1892     ngx_conf_merge_size_value(conf->download_rate,
1893                               prev->download_rate, 0);
1894 
1895     ngx_conf_merge_uint_value(conf->responses,
1896                               prev->responses, NGX_MAX_INT32_VALUE);
1897 
1898     ngx_conf_merge_uint_value(conf->next_upstream_tries,
1899                               prev->next_upstream_tries, 0);
1900 
1901     ngx_conf_merge_value(conf->next_upstream, prev->next_upstream, 1);
1902 
1903     ngx_conf_merge_value(conf->proxy_protocol, prev->proxy_protocol, 0);
1904 
1905     ngx_conf_merge_ptr_value(conf->local, prev->local, NULL);
1906 
1907 #if (NGX_STREAM_SSL)
1908 
1909     ngx_conf_merge_value(conf->ssl_enable, prev->ssl_enable, 0);
1910 
1911     ngx_conf_merge_value(conf->ssl_session_reuse,
1912                               prev->ssl_session_reuse, 1);
1913 
1914     ngx_conf_merge_bitmask_value(conf->ssl_protocols, prev->ssl_protocols,
1915                               (NGX_CONF_BITMASK_SET|NGX_SSL_TLSv1
1916                                |NGX_SSL_TLSv1_1|NGX_SSL_TLSv1_2));
1917 
1918     ngx_conf_merge_str_value(conf->ssl_ciphers, prev->ssl_ciphers, "DEFAULT");
1919 
1920     if (conf->ssl_name == NULL) {
1921         conf->ssl_name = prev->ssl_name;
1922     }
1923 
1924     ngx_conf_merge_value(conf->ssl_server_name, prev->ssl_server_name, 0);
1925 
1926     ngx_conf_merge_value(conf->ssl_verify, prev->ssl_verify, 0);
1927 
1928     ngx_conf_merge_uint_value(conf->ssl_verify_depth,
1929                               prev->ssl_verify_depth, 1);
1930 
1931     ngx_conf_merge_str_value(conf->ssl_trusted_certificate,
1932                               prev->ssl_trusted_certificate, "");
1933 
1934     ngx_conf_merge_str_value(conf->ssl_crl, prev->ssl_crl, "");
1935 
1936     ngx_conf_merge_str_value(conf->ssl_certificate,
1937                               prev->ssl_certificate, "");
1938 
1939     ngx_conf_merge_str_value(conf->ssl_certificate_key,
1940                               prev->ssl_certificate_key, "");
1941 
1942     ngx_conf_merge_ptr_value(conf->ssl_passwords, prev->ssl_passwords, NULL);
1943 
1944     if (conf->ssl_enable && ngx_stream_proxy_set_ssl(cf, conf) != NGX_OK) {
1945         return NGX_CONF_ERROR;
1946     }
1947 
1948 #endif
1949 
1950     return NGX_CONF_OK;
1951 }
1952 
1953 
1954 #if (NGX_STREAM_SSL)
1955 
1956 static ngx_int_t
1957 ngx_stream_proxy_set_ssl(ngx_conf_t *cf, ngx_stream_proxy_srv_conf_t *pscf)
1958 {
1959     ngx_pool_cleanup_t  *cln;
1960 
1961     pscf->ssl = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_t));
1962     if (pscf->ssl == NULL) {
1963         return NGX_ERROR;
1964     }
1965 
1966     pscf->ssl->log = cf->log;
1967 
1968     if (ngx_ssl_create(pscf->ssl, pscf->ssl_protocols, NULL) != NGX_OK) {
1969         return NGX_ERROR;
1970     }
1971 
1972     cln = ngx_pool_cleanup_add(cf->pool, 0);
1973     if (cln == NULL) {
1974         return NGX_ERROR;
1975     }
1976 
1977     cln->handler = ngx_ssl_cleanup_ctx;
1978     cln->data = pscf->ssl;
1979 
1980     if (pscf->ssl_certificate.len) {
1981 
1982         if (pscf->ssl_certificate_key.len == 0) {
1983             ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
1984                           "no \"proxy_ssl_certificate_key\" is defined "
1985                           "for certificate \"%V\"", &pscf->ssl_certificate);
1986             return NGX_ERROR;
1987         }
1988 
1989         if (ngx_ssl_certificate(cf, pscf->ssl, &pscf->ssl_certificate,
1990                                 &pscf->ssl_certificate_key, pscf->ssl_passwords)
1991             != NGX_OK)
1992         {
1993             return NGX_ERROR;
1994         }
1995     }
1996 
1997     if (ngx_ssl_ciphers(cf, pscf->ssl, &pscf->ssl_ciphers, 0) != NGX_OK) {
1998         return NGX_ERROR;
1999     }
2000 
2001     if (pscf->ssl_verify) {
2002         if (pscf->ssl_trusted_certificate.len == 0) {
2003             ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
2004                       "no proxy_ssl_trusted_certificate for proxy_ssl_verify");
2005             return NGX_ERROR;
2006         }
2007 
2008         if (ngx_ssl_trusted_certificate(cf, pscf->ssl,
2009                                         &pscf->ssl_trusted_certificate,
2010                                         pscf->ssl_verify_depth)
2011             != NGX_OK)
2012         {
2013             return NGX_ERROR;
2014         }
2015 
2016         if (ngx_ssl_crl(cf, pscf->ssl, &pscf->ssl_crl) != NGX_OK) {
2017             return NGX_ERROR;
2018         }
2019     }
2020 
2021     return NGX_OK;
2022 }
2023 
2024 #endif
2025 
2026 
2027 static char *
2028 ngx_stream_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
2029 {
2030     ngx_stream_proxy_srv_conf_t *pscf = conf;
2031 
2032     ngx_url_t                            u;
2033     ngx_str_t                           *value, *url;
2034     ngx_stream_complex_value_t           cv;
2035     ngx_stream_core_srv_conf_t          *cscf;
2036     ngx_stream_compile_complex_value_t   ccv;
2037 
2038     if (pscf->upstream || pscf->upstream_value) {
2039         return "is duplicate";
2040     }
2041 
2042     cscf = ngx_stream_conf_get_module_srv_conf(cf, ngx_stream_core_module);
2043 
2044     cscf->handler = ngx_stream_proxy_handler;
2045 
2046     value = cf->args->elts;
2047 
2048     url = &value[1];
2049 
2050     ngx_memzero(&ccv, sizeof(ngx_stream_compile_complex_value_t));
2051 
2052     ccv.cf = cf;
2053     ccv.value = url;
2054     ccv.complex_value = &cv;
2055 
2056     if (ngx_stream_compile_complex_value(&ccv) != NGX_OK) {
2057         return NGX_CONF_ERROR;
2058     }
2059 
2060     if (cv.lengths) {
2061         pscf->upstream_value = ngx_palloc(cf->pool,
2062                                           sizeof(ngx_stream_complex_value_t));
2063         if (pscf->upstream_value == NULL) {
2064             return NGX_CONF_ERROR;
2065         }
2066 
2067         *pscf->upstream_value = cv;
2068 
2069         return NGX_CONF_OK;
2070     }
2071 
2072     ngx_memzero(&u, sizeof(ngx_url_t));
2073 
2074     u.url = *url;
2075     u.no_resolve = 1;
2076 
2077     pscf->upstream = ngx_stream_upstream_add(cf, &u, 0);
2078     if (pscf->upstream == NULL) {
2079         return NGX_CONF_ERROR;
2080     }
2081 
2082     return NGX_CONF_OK;
2083 }
2084 
2085 
2086 static char *
2087 ngx_stream_proxy_bind(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
2088 {
2089     ngx_stream_proxy_srv_conf_t *pscf = conf;
2090 
2091     ngx_int_t                            rc;
2092     ngx_str_t                           *value;
2093     ngx_stream_complex_value_t           cv;
2094     ngx_stream_upstream_local_t         *local;
2095     ngx_stream_compile_complex_value_t   ccv;
2096 
2097     if (pscf->local != NGX_CONF_UNSET_PTR) {
2098         return "is duplicate";
2099     }
2100 
2101     value = cf->args->elts;
2102 
2103     if (cf->args->nelts == 2 && ngx_strcmp(value[1].data, "off") == 0) {
2104         pscf->local = NULL;
2105         return NGX_CONF_OK;
2106     }
2107 
2108     ngx_memzero(&ccv, sizeof(ngx_stream_compile_complex_value_t));
2109 
2110     ccv.cf = cf;
2111     ccv.value = &value[1];
2112     ccv.complex_value = &cv;
2113 
2114     if (ngx_stream_compile_complex_value(&ccv) != NGX_OK) {
2115         return NGX_CONF_ERROR;
2116     }
2117 
2118     local = ngx_pcalloc(cf->pool, sizeof(ngx_stream_upstream_local_t));
2119     if (local == NULL) {
2120         return NGX_CONF_ERROR;
2121     }
2122 
2123     pscf->local = local;
2124 
2125     if (cv.lengths) {
2126         local->value = ngx_palloc(cf->pool, sizeof(ngx_stream_complex_value_t));
2127         if (local->value == NULL) {
2128             return NGX_CONF_ERROR;
2129         }
2130 
2131         *local->value = cv;
2132 
2133     } else {
2134         local->addr = ngx_palloc(cf->pool, sizeof(ngx_addr_t));
2135         if (local->addr == NULL) {
2136             return NGX_CONF_ERROR;
2137         }
2138 
2139         rc = ngx_parse_addr_port(cf->pool, local->addr, value[1].data,
2140                                  value[1].len);
2141 
2142         switch (rc) {
2143         case NGX_OK:
2144             local->addr->name = value[1];
2145             break;
2146 
2147         case NGX_DECLINED:
2148             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2149                                "invalid address \"%V\"", &value[1]);
2150             /* fall through */
2151 
2152         default:
2153             return NGX_CONF_ERROR;
2154         }
2155     }
2156 
2157     if (cf->args->nelts > 2) {
2158         if (ngx_strcmp(value[2].data, "transparent") == 0) {
2159 #if (NGX_HAVE_TRANSPARENT_PROXY)
2160             local->transparent = 1;
2161 #else
2162             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2163                                "transparent proxying is not supported "
2164                                "on this platform, ignored");
2165 #endif
2166         } else {
2167             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2168                                "invalid parameter \"%V\"", &value[2]);
2169             return NGX_CONF_ERROR;
2170         }
2171     }
2172 
2173     return NGX_CONF_OK;
2174 }