Back to home page

Nginx displayed by LXR

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