src/stream/ngx_stream_proxy_module.c - nginx source code

Global variables defined

Data types defined

Functions defined

Source code


  1. /*
  2. * Copyright (C) Roman Arutyunyan
  3. * Copyright (C) Nginx, Inc.
  4. */


  5. #include <ngx_config.h>
  6. #include <ngx_core.h>
  7. #include <ngx_stream.h>


  8. typedef struct {
  9.     ngx_addr_t                      *addr;
  10.     ngx_stream_complex_value_t      *value;
  11. #if (NGX_HAVE_TRANSPARENT_PROXY)
  12.     ngx_uint_t                       transparent; /* unsigned  transparent:1; */
  13. #endif
  14. } ngx_stream_upstream_local_t;


  15. typedef struct {
  16.     ngx_msec_t                       connect_timeout;
  17.     ngx_msec_t                       timeout;
  18.     ngx_msec_t                       next_upstream_timeout;
  19.     size_t                           buffer_size;
  20.     ngx_stream_complex_value_t      *upload_rate;
  21.     ngx_stream_complex_value_t      *download_rate;
  22.     ngx_uint_t                       requests;
  23.     ngx_uint_t                       responses;
  24.     ngx_uint_t                       next_upstream_tries;
  25.     ngx_flag_t                       next_upstream;
  26.     ngx_flag_t                       proxy_protocol;
  27.     ngx_flag_t                       half_close;
  28.     ngx_stream_upstream_local_t     *local;
  29.     ngx_flag_t                       socket_keepalive;

  30. #if (NGX_STREAM_SSL)
  31.     ngx_flag_t                       ssl_enable;
  32.     ngx_flag_t                       ssl_session_reuse;
  33.     ngx_uint_t                       ssl_protocols;
  34.     ngx_str_t                        ssl_ciphers;
  35.     ngx_stream_complex_value_t      *ssl_name;
  36.     ngx_flag_t                       ssl_server_name;

  37.     ngx_flag_t                       ssl_verify;
  38.     ngx_uint_t                       ssl_verify_depth;
  39.     ngx_str_t                        ssl_trusted_certificate;
  40.     ngx_str_t                        ssl_crl;
  41.     ngx_stream_complex_value_t      *ssl_certificate;
  42.     ngx_stream_complex_value_t      *ssl_certificate_key;
  43.     ngx_array_t                     *ssl_passwords;
  44.     ngx_array_t                     *ssl_conf_commands;

  45.     ngx_ssl_t                       *ssl;
  46. #endif

  47.     ngx_stream_upstream_srv_conf_t  *upstream;
  48.     ngx_stream_complex_value_t      *upstream_value;
  49. } ngx_stream_proxy_srv_conf_t;


  50. static void ngx_stream_proxy_handler(ngx_stream_session_t *s);
  51. static ngx_int_t ngx_stream_proxy_eval(ngx_stream_session_t *s,
  52.     ngx_stream_proxy_srv_conf_t *pscf);
  53. static ngx_int_t ngx_stream_proxy_set_local(ngx_stream_session_t *s,
  54.     ngx_stream_upstream_t *u, ngx_stream_upstream_local_t *local);
  55. static void ngx_stream_proxy_connect(ngx_stream_session_t *s);
  56. static void ngx_stream_proxy_init_upstream(ngx_stream_session_t *s);
  57. static void ngx_stream_proxy_resolve_handler(ngx_resolver_ctx_t *ctx);
  58. static void ngx_stream_proxy_upstream_handler(ngx_event_t *ev);
  59. static void ngx_stream_proxy_downstream_handler(ngx_event_t *ev);
  60. static void ngx_stream_proxy_process_connection(ngx_event_t *ev,
  61.     ngx_uint_t from_upstream);
  62. static void ngx_stream_proxy_connect_handler(ngx_event_t *ev);
  63. static ngx_int_t ngx_stream_proxy_test_connect(ngx_connection_t *c);
  64. static void ngx_stream_proxy_process(ngx_stream_session_t *s,
  65.     ngx_uint_t from_upstream, ngx_uint_t do_write);
  66. static ngx_int_t ngx_stream_proxy_test_finalize(ngx_stream_session_t *s,
  67.     ngx_uint_t from_upstream);
  68. static void ngx_stream_proxy_next_upstream(ngx_stream_session_t *s);
  69. static void ngx_stream_proxy_finalize(ngx_stream_session_t *s, ngx_uint_t rc);
  70. static u_char *ngx_stream_proxy_log_error(ngx_log_t *log, u_char *buf,
  71.     size_t len);

  72. static void *ngx_stream_proxy_create_srv_conf(ngx_conf_t *cf);
  73. static char *ngx_stream_proxy_merge_srv_conf(ngx_conf_t *cf, void *parent,
  74.     void *child);
  75. static char *ngx_stream_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd,
  76.     void *conf);
  77. static char *ngx_stream_proxy_bind(ngx_conf_t *cf, ngx_command_t *cmd,
  78.     void *conf);

  79. #if (NGX_STREAM_SSL)

  80. static ngx_int_t ngx_stream_proxy_send_proxy_protocol(ngx_stream_session_t *s);
  81. static char *ngx_stream_proxy_ssl_password_file(ngx_conf_t *cf,
  82.     ngx_command_t *cmd, void *conf);
  83. static char *ngx_stream_proxy_ssl_conf_command_check(ngx_conf_t *cf, void *post,
  84.     void *data);
  85. static void ngx_stream_proxy_ssl_init_connection(ngx_stream_session_t *s);
  86. static void ngx_stream_proxy_ssl_handshake(ngx_connection_t *pc);
  87. static void ngx_stream_proxy_ssl_save_session(ngx_connection_t *c);
  88. static ngx_int_t ngx_stream_proxy_ssl_name(ngx_stream_session_t *s);
  89. static ngx_int_t ngx_stream_proxy_ssl_certificate(ngx_stream_session_t *s);
  90. static ngx_int_t ngx_stream_proxy_merge_ssl(ngx_conf_t *cf,
  91.     ngx_stream_proxy_srv_conf_t *conf, ngx_stream_proxy_srv_conf_t *prev);
  92. static ngx_int_t ngx_stream_proxy_set_ssl(ngx_conf_t *cf,
  93.     ngx_stream_proxy_srv_conf_t *pscf);


  94. static ngx_conf_bitmask_t  ngx_stream_proxy_ssl_protocols[] = {
  95.     { ngx_string("SSLv2"), NGX_SSL_SSLv2 },
  96.     { ngx_string("SSLv3"), NGX_SSL_SSLv3 },
  97.     { ngx_string("TLSv1"), NGX_SSL_TLSv1 },
  98.     { ngx_string("TLSv1.1"), NGX_SSL_TLSv1_1 },
  99.     { ngx_string("TLSv1.2"), NGX_SSL_TLSv1_2 },
  100.     { ngx_string("TLSv1.3"), NGX_SSL_TLSv1_3 },
  101.     { ngx_null_string, 0 }
  102. };

  103. static ngx_conf_post_t  ngx_stream_proxy_ssl_conf_command_post =
  104.     { ngx_stream_proxy_ssl_conf_command_check };

  105. #endif


  106. static ngx_conf_deprecated_t  ngx_conf_deprecated_proxy_downstream_buffer = {
  107.     ngx_conf_deprecated, "proxy_downstream_buffer", "proxy_buffer_size"
  108. };

  109. static ngx_conf_deprecated_t  ngx_conf_deprecated_proxy_upstream_buffer = {
  110.     ngx_conf_deprecated, "proxy_upstream_buffer", "proxy_buffer_size"
  111. };


  112. static ngx_command_t  ngx_stream_proxy_commands[] = {

  113.     { ngx_string("proxy_pass"),
  114.       NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  115.       ngx_stream_proxy_pass,
  116.       NGX_STREAM_SRV_CONF_OFFSET,
  117.       0,
  118.       NULL },

  119.     { ngx_string("proxy_bind"),
  120.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE12,
  121.       ngx_stream_proxy_bind,
  122.       NGX_STREAM_SRV_CONF_OFFSET,
  123.       0,
  124.       NULL },

  125.     { ngx_string("proxy_socket_keepalive"),
  126.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
  127.       ngx_conf_set_flag_slot,
  128.       NGX_STREAM_SRV_CONF_OFFSET,
  129.       offsetof(ngx_stream_proxy_srv_conf_t, socket_keepalive),
  130.       NULL },

  131.     { ngx_string("proxy_connect_timeout"),
  132.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  133.       ngx_conf_set_msec_slot,
  134.       NGX_STREAM_SRV_CONF_OFFSET,
  135.       offsetof(ngx_stream_proxy_srv_conf_t, connect_timeout),
  136.       NULL },

  137.     { ngx_string("proxy_timeout"),
  138.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  139.       ngx_conf_set_msec_slot,
  140.       NGX_STREAM_SRV_CONF_OFFSET,
  141.       offsetof(ngx_stream_proxy_srv_conf_t, timeout),
  142.       NULL },

  143.     { ngx_string("proxy_buffer_size"),
  144.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  145.       ngx_conf_set_size_slot,
  146.       NGX_STREAM_SRV_CONF_OFFSET,
  147.       offsetof(ngx_stream_proxy_srv_conf_t, buffer_size),
  148.       NULL },

  149.     { ngx_string("proxy_downstream_buffer"),
  150.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  151.       ngx_conf_set_size_slot,
  152.       NGX_STREAM_SRV_CONF_OFFSET,
  153.       offsetof(ngx_stream_proxy_srv_conf_t, buffer_size),
  154.       &ngx_conf_deprecated_proxy_downstream_buffer },

  155.     { ngx_string("proxy_upstream_buffer"),
  156.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  157.       ngx_conf_set_size_slot,
  158.       NGX_STREAM_SRV_CONF_OFFSET,
  159.       offsetof(ngx_stream_proxy_srv_conf_t, buffer_size),
  160.       &ngx_conf_deprecated_proxy_upstream_buffer },

  161.     { ngx_string("proxy_upload_rate"),
  162.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  163.       ngx_stream_set_complex_value_size_slot,
  164.       NGX_STREAM_SRV_CONF_OFFSET,
  165.       offsetof(ngx_stream_proxy_srv_conf_t, upload_rate),
  166.       NULL },

  167.     { ngx_string("proxy_download_rate"),
  168.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  169.       ngx_stream_set_complex_value_size_slot,
  170.       NGX_STREAM_SRV_CONF_OFFSET,
  171.       offsetof(ngx_stream_proxy_srv_conf_t, download_rate),
  172.       NULL },

  173.     { ngx_string("proxy_requests"),
  174.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  175.       ngx_conf_set_num_slot,
  176.       NGX_STREAM_SRV_CONF_OFFSET,
  177.       offsetof(ngx_stream_proxy_srv_conf_t, requests),
  178.       NULL },

  179.     { ngx_string("proxy_responses"),
  180.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  181.       ngx_conf_set_num_slot,
  182.       NGX_STREAM_SRV_CONF_OFFSET,
  183.       offsetof(ngx_stream_proxy_srv_conf_t, responses),
  184.       NULL },

  185.     { ngx_string("proxy_next_upstream"),
  186.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
  187.       ngx_conf_set_flag_slot,
  188.       NGX_STREAM_SRV_CONF_OFFSET,
  189.       offsetof(ngx_stream_proxy_srv_conf_t, next_upstream),
  190.       NULL },

  191.     { ngx_string("proxy_next_upstream_tries"),
  192.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  193.       ngx_conf_set_num_slot,
  194.       NGX_STREAM_SRV_CONF_OFFSET,
  195.       offsetof(ngx_stream_proxy_srv_conf_t, next_upstream_tries),
  196.       NULL },

  197.     { ngx_string("proxy_next_upstream_timeout"),
  198.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  199.       ngx_conf_set_msec_slot,
  200.       NGX_STREAM_SRV_CONF_OFFSET,
  201.       offsetof(ngx_stream_proxy_srv_conf_t, next_upstream_timeout),
  202.       NULL },

  203.     { ngx_string("proxy_protocol"),
  204.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
  205.       ngx_conf_set_flag_slot,
  206.       NGX_STREAM_SRV_CONF_OFFSET,
  207.       offsetof(ngx_stream_proxy_srv_conf_t, proxy_protocol),
  208.       NULL },

  209.     { ngx_string("proxy_half_close"),
  210.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
  211.       ngx_conf_set_flag_slot,
  212.       NGX_STREAM_SRV_CONF_OFFSET,
  213.       offsetof(ngx_stream_proxy_srv_conf_t, half_close),
  214.       NULL },

  215. #if (NGX_STREAM_SSL)

  216.     { ngx_string("proxy_ssl"),
  217.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
  218.       ngx_conf_set_flag_slot,
  219.       NGX_STREAM_SRV_CONF_OFFSET,
  220.       offsetof(ngx_stream_proxy_srv_conf_t, ssl_enable),
  221.       NULL },

  222.     { ngx_string("proxy_ssl_session_reuse"),
  223.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
  224.       ngx_conf_set_flag_slot,
  225.       NGX_STREAM_SRV_CONF_OFFSET,
  226.       offsetof(ngx_stream_proxy_srv_conf_t, ssl_session_reuse),
  227.       NULL },

  228.     { ngx_string("proxy_ssl_protocols"),
  229.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_1MORE,
  230.       ngx_conf_set_bitmask_slot,
  231.       NGX_STREAM_SRV_CONF_OFFSET,
  232.       offsetof(ngx_stream_proxy_srv_conf_t, ssl_protocols),
  233.       &ngx_stream_proxy_ssl_protocols },

  234.     { ngx_string("proxy_ssl_ciphers"),
  235.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  236.       ngx_conf_set_str_slot,
  237.       NGX_STREAM_SRV_CONF_OFFSET,
  238.       offsetof(ngx_stream_proxy_srv_conf_t, ssl_ciphers),
  239.       NULL },

  240.     { ngx_string("proxy_ssl_name"),
  241.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  242.       ngx_stream_set_complex_value_slot,
  243.       NGX_STREAM_SRV_CONF_OFFSET,
  244.       offsetof(ngx_stream_proxy_srv_conf_t, ssl_name),
  245.       NULL },

  246.     { ngx_string("proxy_ssl_server_name"),
  247.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
  248.       ngx_conf_set_flag_slot,
  249.       NGX_STREAM_SRV_CONF_OFFSET,
  250.       offsetof(ngx_stream_proxy_srv_conf_t, ssl_server_name),
  251.       NULL },

  252.     { ngx_string("proxy_ssl_verify"),
  253.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
  254.       ngx_conf_set_flag_slot,
  255.       NGX_STREAM_SRV_CONF_OFFSET,
  256.       offsetof(ngx_stream_proxy_srv_conf_t, ssl_verify),
  257.       NULL },

  258.     { ngx_string("proxy_ssl_verify_depth"),
  259.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  260.       ngx_conf_set_num_slot,
  261.       NGX_STREAM_SRV_CONF_OFFSET,
  262.       offsetof(ngx_stream_proxy_srv_conf_t, ssl_verify_depth),
  263.       NULL },

  264.     { ngx_string("proxy_ssl_trusted_certificate"),
  265.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  266.       ngx_conf_set_str_slot,
  267.       NGX_STREAM_SRV_CONF_OFFSET,
  268.       offsetof(ngx_stream_proxy_srv_conf_t, ssl_trusted_certificate),
  269.       NULL },

  270.     { ngx_string("proxy_ssl_crl"),
  271.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  272.       ngx_conf_set_str_slot,
  273.       NGX_STREAM_SRV_CONF_OFFSET,
  274.       offsetof(ngx_stream_proxy_srv_conf_t, ssl_crl),
  275.       NULL },

  276.     { ngx_string("proxy_ssl_certificate"),
  277.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  278.       ngx_stream_set_complex_value_zero_slot,
  279.       NGX_STREAM_SRV_CONF_OFFSET,
  280.       offsetof(ngx_stream_proxy_srv_conf_t, ssl_certificate),
  281.       NULL },

  282.     { ngx_string("proxy_ssl_certificate_key"),
  283.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  284.       ngx_stream_set_complex_value_zero_slot,
  285.       NGX_STREAM_SRV_CONF_OFFSET,
  286.       offsetof(ngx_stream_proxy_srv_conf_t, ssl_certificate_key),
  287.       NULL },

  288.     { ngx_string("proxy_ssl_password_file"),
  289.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  290.       ngx_stream_proxy_ssl_password_file,
  291.       NGX_STREAM_SRV_CONF_OFFSET,
  292.       0,
  293.       NULL },

  294.     { ngx_string("proxy_ssl_conf_command"),
  295.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE2,
  296.       ngx_conf_set_keyval_slot,
  297.       NGX_STREAM_SRV_CONF_OFFSET,
  298.       offsetof(ngx_stream_proxy_srv_conf_t, ssl_conf_commands),
  299.       &ngx_stream_proxy_ssl_conf_command_post },

  300. #endif

  301.       ngx_null_command
  302. };


  303. static ngx_stream_module_t  ngx_stream_proxy_module_ctx = {
  304.     NULL,                                  /* preconfiguration */
  305.     NULL,                                  /* postconfiguration */

  306.     NULL,                                  /* create main configuration */
  307.     NULL,                                  /* init main configuration */

  308.     ngx_stream_proxy_create_srv_conf,      /* create server configuration */
  309.     ngx_stream_proxy_merge_srv_conf        /* merge server configuration */
  310. };


  311. ngx_module_t  ngx_stream_proxy_module = {
  312.     NGX_MODULE_V1,
  313.     &ngx_stream_proxy_module_ctx,          /* module context */
  314.     ngx_stream_proxy_commands,             /* module directives */
  315.     NGX_STREAM_MODULE,                     /* module type */
  316.     NULL,                                  /* init master */
  317.     NULL,                                  /* init module */
  318.     NULL,                                  /* init process */
  319.     NULL,                                  /* init thread */
  320.     NULL,                                  /* exit thread */
  321.     NULL,                                  /* exit process */
  322.     NULL,                                  /* exit master */
  323.     NGX_MODULE_V1_PADDING
  324. };


  325. static void
  326. ngx_stream_proxy_handler(ngx_stream_session_t *s)
  327. {
  328.     u_char                           *p;
  329.     ngx_str_t                        *host;
  330.     ngx_uint_t                        i;
  331.     ngx_connection_t                 *c;
  332.     ngx_resolver_ctx_t               *ctx, temp;
  333.     ngx_stream_upstream_t            *u;
  334.     ngx_stream_core_srv_conf_t       *cscf;
  335.     ngx_stream_proxy_srv_conf_t      *pscf;
  336.     ngx_stream_upstream_srv_conf_t   *uscf, **uscfp;
  337.     ngx_stream_upstream_main_conf_t  *umcf;

  338.     c = s->connection;

  339.     pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);

  340.     ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0,
  341.                    "proxy connection handler");

  342.     u = ngx_pcalloc(c->pool, sizeof(ngx_stream_upstream_t));
  343.     if (u == NULL) {
  344.         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  345.         return;
  346.     }

  347.     s->upstream = u;

  348.     s->log_handler = ngx_stream_proxy_log_error;

  349.     u->requests = 1;

  350.     u->peer.log = c->log;
  351.     u->peer.log_error = NGX_ERROR_ERR;

  352.     if (ngx_stream_proxy_set_local(s, u, pscf->local) != NGX_OK) {
  353.         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  354.         return;
  355.     }

  356.     if (pscf->socket_keepalive) {
  357.         u->peer.so_keepalive = 1;
  358.     }

  359.     u->peer.type = c->type;
  360.     u->start_sec = ngx_time();

  361.     c->write->handler = ngx_stream_proxy_downstream_handler;
  362.     c->read->handler = ngx_stream_proxy_downstream_handler;

  363.     s->upstream_states = ngx_array_create(c->pool, 1,
  364.                                           sizeof(ngx_stream_upstream_state_t));
  365.     if (s->upstream_states == NULL) {
  366.         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  367.         return;
  368.     }

  369.     p = ngx_pnalloc(c->pool, pscf->buffer_size);
  370.     if (p == NULL) {
  371.         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  372.         return;
  373.     }

  374.     u->downstream_buf.start = p;
  375.     u->downstream_buf.end = p + pscf->buffer_size;
  376.     u->downstream_buf.pos = p;
  377.     u->downstream_buf.last = p;

  378.     if (c->read->ready) {
  379.         ngx_post_event(c->read, &ngx_posted_events);
  380.     }

  381.     if (pscf->upstream_value) {
  382.         if (ngx_stream_proxy_eval(s, pscf) != NGX_OK) {
  383.             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  384.             return;
  385.         }
  386.     }

  387.     if (u->resolved == NULL) {

  388.         uscf = pscf->upstream;

  389.     } else {

  390. #if (NGX_STREAM_SSL)
  391.         u->ssl_name = u->resolved->host;
  392. #endif

  393.         host = &u->resolved->host;

  394.         umcf = ngx_stream_get_module_main_conf(s, ngx_stream_upstream_module);

  395.         uscfp = umcf->upstreams.elts;

  396.         for (i = 0; i < umcf->upstreams.nelts; i++) {

  397.             uscf = uscfp[i];

  398.             if (uscf->host.len == host->len
  399.                 && ((uscf->port == 0 && u->resolved->no_port)
  400.                      || uscf->port == u->resolved->port)
  401.                 && ngx_strncasecmp(uscf->host.data, host->data, host->len) == 0)
  402.             {
  403.                 goto found;
  404.             }
  405.         }

  406.         if (u->resolved->sockaddr) {

  407.             if (u->resolved->port == 0
  408.                 && u->resolved->sockaddr->sa_family != AF_UNIX)
  409.             {
  410.                 ngx_log_error(NGX_LOG_ERR, c->log, 0,
  411.                               "no port in upstream \"%V\"", host);
  412.                 ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  413.                 return;
  414.             }

  415.             if (ngx_stream_upstream_create_round_robin_peer(s, u->resolved)
  416.                 != NGX_OK)
  417.             {
  418.                 ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  419.                 return;
  420.             }

  421.             ngx_stream_proxy_connect(s);

  422.             return;
  423.         }

  424.         if (u->resolved->port == 0) {
  425.             ngx_log_error(NGX_LOG_ERR, c->log, 0,
  426.                           "no port in upstream \"%V\"", host);
  427.             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  428.             return;
  429.         }

  430.         temp.name = *host;

  431.         cscf = ngx_stream_get_module_srv_conf(s, ngx_stream_core_module);

  432.         ctx = ngx_resolve_start(cscf->resolver, &temp);
  433.         if (ctx == NULL) {
  434.             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  435.             return;
  436.         }

  437.         if (ctx == NGX_NO_RESOLVER) {
  438.             ngx_log_error(NGX_LOG_ERR, c->log, 0,
  439.                           "no resolver defined to resolve %V", host);
  440.             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  441.             return;
  442.         }

  443.         ctx->name = *host;
  444.         ctx->handler = ngx_stream_proxy_resolve_handler;
  445.         ctx->data = s;
  446.         ctx->timeout = cscf->resolver_timeout;

  447.         u->resolved->ctx = ctx;

  448.         if (ngx_resolve_name(ctx) != NGX_OK) {
  449.             u->resolved->ctx = NULL;
  450.             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  451.             return;
  452.         }

  453.         return;
  454.     }

  455. found:

  456.     if (uscf == NULL) {
  457.         ngx_log_error(NGX_LOG_ALERT, c->log, 0, "no upstream configuration");
  458.         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  459.         return;
  460.     }

  461.     u->upstream = uscf;

  462. #if (NGX_STREAM_SSL)
  463.     u->ssl_name = uscf->host;
  464. #endif

  465.     if (uscf->peer.init(s, uscf) != NGX_OK) {
  466.         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  467.         return;
  468.     }

  469.     u->peer.start_time = ngx_current_msec;

  470.     if (pscf->next_upstream_tries
  471.         && u->peer.tries > pscf->next_upstream_tries)
  472.     {
  473.         u->peer.tries = pscf->next_upstream_tries;
  474.     }

  475.     ngx_stream_proxy_connect(s);
  476. }


  477. static ngx_int_t
  478. ngx_stream_proxy_eval(ngx_stream_session_t *s,
  479.     ngx_stream_proxy_srv_conf_t *pscf)
  480. {
  481.     ngx_str_t               host;
  482.     ngx_url_t               url;
  483.     ngx_stream_upstream_t  *u;

  484.     if (ngx_stream_complex_value(s, pscf->upstream_value, &host) != NGX_OK) {
  485.         return NGX_ERROR;
  486.     }

  487.     ngx_memzero(&url, sizeof(ngx_url_t));

  488.     url.url = host;
  489.     url.no_resolve = 1;

  490.     if (ngx_parse_url(s->connection->pool, &url) != NGX_OK) {
  491.         if (url.err) {
  492.             ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
  493.                           "%s in upstream \"%V\"", url.err, &url.url);
  494.         }

  495.         return NGX_ERROR;
  496.     }

  497.     u = s->upstream;

  498.     u->resolved = ngx_pcalloc(s->connection->pool,
  499.                               sizeof(ngx_stream_upstream_resolved_t));
  500.     if (u->resolved == NULL) {
  501.         return NGX_ERROR;
  502.     }

  503.     if (url.addrs) {
  504.         u->resolved->sockaddr = url.addrs[0].sockaddr;
  505.         u->resolved->socklen = url.addrs[0].socklen;
  506.         u->resolved->name = url.addrs[0].name;
  507.         u->resolved->naddrs = 1;
  508.     }

  509.     u->resolved->host = url.host;
  510.     u->resolved->port = url.port;
  511.     u->resolved->no_port = url.no_port;

  512.     return NGX_OK;
  513. }


  514. static ngx_int_t
  515. ngx_stream_proxy_set_local(ngx_stream_session_t *s, ngx_stream_upstream_t *u,
  516.     ngx_stream_upstream_local_t *local)
  517. {
  518.     ngx_int_t    rc;
  519.     ngx_str_t    val;
  520.     ngx_addr_t  *addr;

  521.     if (local == NULL) {
  522.         u->peer.local = NULL;
  523.         return NGX_OK;
  524.     }

  525. #if (NGX_HAVE_TRANSPARENT_PROXY)
  526.     u->peer.transparent = local->transparent;
  527. #endif

  528.     if (local->value == NULL) {
  529.         u->peer.local = local->addr;
  530.         return NGX_OK;
  531.     }

  532.     if (ngx_stream_complex_value(s, local->value, &val) != NGX_OK) {
  533.         return NGX_ERROR;
  534.     }

  535.     if (val.len == 0) {
  536.         return NGX_OK;
  537.     }

  538.     addr = ngx_palloc(s->connection->pool, sizeof(ngx_addr_t));
  539.     if (addr == NULL) {
  540.         return NGX_ERROR;
  541.     }

  542.     rc = ngx_parse_addr_port(s->connection->pool, addr, val.data, val.len);
  543.     if (rc == NGX_ERROR) {
  544.         return NGX_ERROR;
  545.     }

  546.     if (rc != NGX_OK) {
  547.         ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
  548.                       "invalid local address \"%V\"", &val);
  549.         return NGX_OK;
  550.     }

  551.     addr->name = val;
  552.     u->peer.local = addr;

  553.     return NGX_OK;
  554. }


  555. static void
  556. ngx_stream_proxy_connect(ngx_stream_session_t *s)
  557. {
  558.     ngx_int_t                     rc;
  559.     ngx_connection_t             *c, *pc;
  560.     ngx_stream_upstream_t        *u;
  561.     ngx_stream_proxy_srv_conf_t  *pscf;

  562.     c = s->connection;

  563.     c->log->action = "connecting to upstream";

  564.     pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);

  565.     u = s->upstream;

  566.     u->connected = 0;
  567.     u->proxy_protocol = pscf->proxy_protocol;

  568.     if (u->state) {
  569.         u->state->response_time = ngx_current_msec - u->start_time;
  570.     }

  571.     u->state = ngx_array_push(s->upstream_states);
  572.     if (u->state == NULL) {
  573.         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  574.         return;
  575.     }

  576.     ngx_memzero(u->state, sizeof(ngx_stream_upstream_state_t));

  577.     u->start_time = ngx_current_msec;

  578.     u->state->connect_time = (ngx_msec_t) -1;
  579.     u->state->first_byte_time = (ngx_msec_t) -1;
  580.     u->state->response_time = (ngx_msec_t) -1;

  581.     rc = ngx_event_connect_peer(&u->peer);

  582.     ngx_log_debug1(NGX_LOG_DEBUG_STREAM, c->log, 0, "proxy connect: %i", rc);

  583.     if (rc == NGX_ERROR) {
  584.         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  585.         return;
  586.     }

  587.     u->state->peer = u->peer.name;

  588. #if (NGX_STREAM_UPSTREAM_ZONE)
  589.     if (u->upstream && u->upstream->shm_zone
  590.         && (u->upstream->flags & NGX_STREAM_UPSTREAM_MODIFY))
  591.     {
  592.         u->state->peer = ngx_palloc(s->connection->pool,
  593.                                     sizeof(ngx_str_t) + u->peer.name->len);
  594.         if (u->state->peer == NULL) {
  595.             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  596.             return;
  597.         }

  598.         u->state->peer->len = u->peer.name->len;
  599.         u->state->peer->data = (u_char *) (u->state->peer + 1);
  600.         ngx_memcpy(u->state->peer->data, u->peer.name->data, u->peer.name->len);

  601.         u->peer.name = u->state->peer;
  602.     }
  603. #endif

  604.     if (rc == NGX_BUSY) {
  605.         ngx_log_error(NGX_LOG_ERR, c->log, 0, "no live upstreams");
  606.         ngx_stream_proxy_finalize(s, NGX_STREAM_BAD_GATEWAY);
  607.         return;
  608.     }

  609.     if (rc == NGX_DECLINED) {
  610.         ngx_stream_proxy_next_upstream(s);
  611.         return;
  612.     }

  613.     /* rc == NGX_OK || rc == NGX_AGAIN || rc == NGX_DONE */

  614.     pc = u->peer.connection;

  615.     pc->data = s;
  616.     pc->log = c->log;
  617.     pc->pool = c->pool;
  618.     pc->read->log = c->log;
  619.     pc->write->log = c->log;

  620.     if (rc != NGX_AGAIN) {
  621.         ngx_stream_proxy_init_upstream(s);
  622.         return;
  623.     }

  624.     pc->read->handler = ngx_stream_proxy_connect_handler;
  625.     pc->write->handler = ngx_stream_proxy_connect_handler;

  626.     ngx_add_timer(pc->write, pscf->connect_timeout);
  627. }


  628. static void
  629. ngx_stream_proxy_init_upstream(ngx_stream_session_t *s)
  630. {
  631.     u_char                       *p;
  632.     ngx_chain_t                  *cl;
  633.     ngx_connection_t             *c, *pc;
  634.     ngx_log_handler_pt            handler;
  635.     ngx_stream_upstream_t        *u;
  636.     ngx_stream_core_srv_conf_t   *cscf;
  637.     ngx_stream_proxy_srv_conf_t  *pscf;

  638.     u = s->upstream;
  639.     pc = u->peer.connection;

  640.     cscf = ngx_stream_get_module_srv_conf(s, ngx_stream_core_module);

  641.     if (pc->type == SOCK_STREAM
  642.         && cscf->tcp_nodelay
  643.         && ngx_tcp_nodelay(pc) != NGX_OK)
  644.     {
  645.         ngx_stream_proxy_next_upstream(s);
  646.         return;
  647.     }

  648.     pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);

  649. #if (NGX_STREAM_SSL)

  650.     if (pc->type == SOCK_STREAM && pscf->ssl_enable) {

  651.         if (u->proxy_protocol) {
  652.             if (ngx_stream_proxy_send_proxy_protocol(s) != NGX_OK) {
  653.                 return;
  654.             }

  655.             u->proxy_protocol = 0;
  656.         }

  657.         if (pc->ssl == NULL) {
  658.             ngx_stream_proxy_ssl_init_connection(s);
  659.             return;
  660.         }
  661.     }

  662. #endif

  663.     c = s->connection;

  664.     if (c->log->log_level >= NGX_LOG_INFO) {
  665.         ngx_str_t  str;
  666.         u_char     addr[NGX_SOCKADDR_STRLEN];

  667.         str.len = NGX_SOCKADDR_STRLEN;
  668.         str.data = addr;

  669.         if (ngx_connection_local_sockaddr(pc, &str, 1) == NGX_OK) {
  670.             handler = c->log->handler;
  671.             c->log->handler = NULL;

  672.             ngx_log_error(NGX_LOG_INFO, c->log, 0,
  673.                           "%sproxy %V connected to %V",
  674.                           pc->type == SOCK_DGRAM ? "udp " : "",
  675.                           &str, u->peer.name);

  676.             c->log->handler = handler;
  677.         }
  678.     }

  679.     u->state->connect_time = ngx_current_msec - u->start_time;

  680.     if (u->peer.notify) {
  681.         u->peer.notify(&u->peer, u->peer.data,
  682.                        NGX_STREAM_UPSTREAM_NOTIFY_CONNECT);
  683.     }

  684.     if (u->upstream_buf.start == NULL) {
  685.         p = ngx_pnalloc(c->pool, pscf->buffer_size);
  686.         if (p == NULL) {
  687.             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  688.             return;
  689.         }

  690.         u->upstream_buf.start = p;
  691.         u->upstream_buf.end = p + pscf->buffer_size;
  692.         u->upstream_buf.pos = p;
  693.         u->upstream_buf.last = p;
  694.     }

  695.     if (c->buffer && c->buffer->pos <= c->buffer->last) {
  696.         ngx_log_debug1(NGX_LOG_DEBUG_STREAM, c->log, 0,
  697.                        "stream proxy add preread buffer: %uz",
  698.                        c->buffer->last - c->buffer->pos);

  699.         cl = ngx_chain_get_free_buf(c->pool, &u->free);
  700.         if (cl == NULL) {
  701.             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  702.             return;
  703.         }

  704.         *cl->buf = *c->buffer;

  705.         cl->buf->tag = (ngx_buf_tag_t) &ngx_stream_proxy_module;
  706.         cl->buf->temporary = (cl->buf->pos == cl->buf->last) ? 0 : 1;
  707.         cl->buf->flush = 1;

  708.         cl->next = u->upstream_out;
  709.         u->upstream_out = cl;
  710.     }

  711.     if (u->proxy_protocol) {
  712.         ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0,
  713.                        "stream proxy add PROXY protocol header");

  714.         cl = ngx_chain_get_free_buf(c->pool, &u->free);
  715.         if (cl == NULL) {
  716.             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  717.             return;
  718.         }

  719.         p = ngx_pnalloc(c->pool, NGX_PROXY_PROTOCOL_V1_MAX_HEADER);
  720.         if (p == NULL) {
  721.             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  722.             return;
  723.         }

  724.         cl->buf->pos = p;

  725.         p = ngx_proxy_protocol_write(c, p,
  726.                                      p + NGX_PROXY_PROTOCOL_V1_MAX_HEADER);
  727.         if (p == NULL) {
  728.             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  729.             return;
  730.         }

  731.         cl->buf->last = p;
  732.         cl->buf->temporary = 1;
  733.         cl->buf->flush = 0;
  734.         cl->buf->last_buf = 0;
  735.         cl->buf->tag = (ngx_buf_tag_t) &ngx_stream_proxy_module;

  736.         cl->next = u->upstream_out;
  737.         u->upstream_out = cl;

  738.         u->proxy_protocol = 0;
  739.     }

  740.     u->upload_rate = ngx_stream_complex_value_size(s, pscf->upload_rate, 0);
  741.     u->download_rate = ngx_stream_complex_value_size(s, pscf->download_rate, 0);

  742.     u->connected = 1;

  743.     pc->read->handler = ngx_stream_proxy_upstream_handler;
  744.     pc->write->handler = ngx_stream_proxy_upstream_handler;

  745.     if (pc->read->ready) {
  746.         ngx_post_event(pc->read, &ngx_posted_events);
  747.     }

  748.     ngx_stream_proxy_process(s, 0, 1);
  749. }


  750. #if (NGX_STREAM_SSL)

  751. static ngx_int_t
  752. ngx_stream_proxy_send_proxy_protocol(ngx_stream_session_t *s)
  753. {
  754.     u_char                       *p;
  755.     ssize_t                       n, size;
  756.     ngx_connection_t             *c, *pc;
  757.     ngx_stream_upstream_t        *u;
  758.     ngx_stream_proxy_srv_conf_t  *pscf;
  759.     u_char                        buf[NGX_PROXY_PROTOCOL_V1_MAX_HEADER];

  760.     c = s->connection;

  761.     ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0,
  762.                    "stream proxy send PROXY protocol header");

  763.     p = ngx_proxy_protocol_write(c, buf,
  764.                                  buf + NGX_PROXY_PROTOCOL_V1_MAX_HEADER);
  765.     if (p == NULL) {
  766.         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  767.         return NGX_ERROR;
  768.     }

  769.     u = s->upstream;

  770.     pc = u->peer.connection;

  771.     size = p - buf;

  772.     n = pc->send(pc, buf, size);

  773.     if (n == NGX_AGAIN) {
  774.         if (ngx_handle_write_event(pc->write, 0) != NGX_OK) {
  775.             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  776.             return NGX_ERROR;
  777.         }

  778.         pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);

  779.         ngx_add_timer(pc->write, pscf->timeout);

  780.         pc->write->handler = ngx_stream_proxy_connect_handler;

  781.         return NGX_AGAIN;
  782.     }

  783.     if (n == NGX_ERROR) {
  784.         ngx_stream_proxy_finalize(s, NGX_STREAM_OK);
  785.         return NGX_ERROR;
  786.     }

  787.     if (n != size) {

  788.         /*
  789.          * PROXY protocol specification:
  790.          * The sender must always ensure that the header
  791.          * is sent at once, so that the transport layer
  792.          * maintains atomicity along the path to the receiver.
  793.          */

  794.         ngx_log_error(NGX_LOG_ERR, c->log, 0,
  795.                       "could not send PROXY protocol header at once");

  796.         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);

  797.         return NGX_ERROR;
  798.     }

  799.     return NGX_OK;
  800. }


  801. static char *
  802. ngx_stream_proxy_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd,
  803.     void *conf)
  804. {
  805.     ngx_stream_proxy_srv_conf_t *pscf = conf;

  806.     ngx_str_t  *value;

  807.     if (pscf->ssl_passwords != NGX_CONF_UNSET_PTR) {
  808.         return "is duplicate";
  809.     }

  810.     value = cf->args->elts;

  811.     pscf->ssl_passwords = ngx_ssl_read_password_file(cf, &value[1]);

  812.     if (pscf->ssl_passwords == NULL) {
  813.         return NGX_CONF_ERROR;
  814.     }

  815.     return NGX_CONF_OK;
  816. }


  817. static char *
  818. ngx_stream_proxy_ssl_conf_command_check(ngx_conf_t *cf, void *post, void *data)
  819. {
  820. #ifndef SSL_CONF_FLAG_FILE
  821.     return "is not supported on this platform";
  822. #else
  823.     return NGX_CONF_OK;
  824. #endif
  825. }


  826. static void
  827. ngx_stream_proxy_ssl_init_connection(ngx_stream_session_t *s)
  828. {
  829.     ngx_int_t                     rc;
  830.     ngx_connection_t             *pc;
  831.     ngx_stream_upstream_t        *u;
  832.     ngx_stream_proxy_srv_conf_t  *pscf;

  833.     u = s->upstream;

  834.     pc = u->peer.connection;

  835.     pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);

  836.     if (ngx_ssl_create_connection(pscf->ssl, pc, NGX_SSL_BUFFER|NGX_SSL_CLIENT)
  837.         != NGX_OK)
  838.     {
  839.         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  840.         return;
  841.     }

  842.     if (pscf->ssl_server_name || pscf->ssl_verify) {
  843.         if (ngx_stream_proxy_ssl_name(s) != NGX_OK) {
  844.             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  845.             return;
  846.         }
  847.     }

  848.     if (pscf->ssl_certificate
  849.         && pscf->ssl_certificate->value.len
  850.         && (pscf->ssl_certificate->lengths
  851.             || pscf->ssl_certificate_key->lengths))
  852.     {
  853.         if (ngx_stream_proxy_ssl_certificate(s) != NGX_OK) {
  854.             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  855.             return;
  856.         }
  857.     }

  858.     if (pscf->ssl_session_reuse) {
  859.         pc->ssl->save_session = ngx_stream_proxy_ssl_save_session;

  860.         if (u->peer.set_session(&u->peer, u->peer.data) != NGX_OK) {
  861.             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  862.             return;
  863.         }
  864.     }

  865.     s->connection->log->action = "SSL handshaking to upstream";

  866.     rc = ngx_ssl_handshake(pc);

  867.     if (rc == NGX_AGAIN) {

  868.         if (!pc->write->timer_set) {
  869.             ngx_add_timer(pc->write, pscf->connect_timeout);
  870.         }

  871.         pc->ssl->handler = ngx_stream_proxy_ssl_handshake;
  872.         return;
  873.     }

  874.     ngx_stream_proxy_ssl_handshake(pc);
  875. }


  876. static void
  877. ngx_stream_proxy_ssl_handshake(ngx_connection_t *pc)
  878. {
  879.     long                          rc;
  880.     ngx_stream_session_t         *s;
  881.     ngx_stream_upstream_t        *u;
  882.     ngx_stream_proxy_srv_conf_t  *pscf;

  883.     s = pc->data;

  884.     pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);

  885.     if (pc->ssl->handshaked) {

  886.         if (pscf->ssl_verify) {
  887.             rc = SSL_get_verify_result(pc->ssl->connection);

  888.             if (rc != X509_V_OK) {
  889.                 ngx_log_error(NGX_LOG_ERR, pc->log, 0,
  890.                               "upstream SSL certificate verify error: (%l:%s)",
  891.                               rc, X509_verify_cert_error_string(rc));
  892.                 goto failed;
  893.             }

  894.             u = s->upstream;

  895.             if (ngx_ssl_check_host(pc, &u->ssl_name) != NGX_OK) {
  896.                 ngx_log_error(NGX_LOG_ERR, pc->log, 0,
  897.                               "upstream SSL certificate does not match \"%V\"",
  898.                               &u->ssl_name);
  899.                 goto failed;
  900.             }
  901.         }

  902.         if (pc->write->timer_set) {
  903.             ngx_del_timer(pc->write);
  904.         }

  905.         ngx_stream_proxy_init_upstream(s);

  906.         return;
  907.     }

  908. failed:

  909.     ngx_stream_proxy_next_upstream(s);
  910. }


  911. static void
  912. ngx_stream_proxy_ssl_save_session(ngx_connection_t *c)
  913. {
  914.     ngx_stream_session_t   *s;
  915.     ngx_stream_upstream_t  *u;

  916.     s = c->data;
  917.     u = s->upstream;

  918.     u->peer.save_session(&u->peer, u->peer.data);
  919. }


  920. static ngx_int_t
  921. ngx_stream_proxy_ssl_name(ngx_stream_session_t *s)
  922. {
  923.     u_char                       *p, *last;
  924.     ngx_str_t                     name;
  925.     ngx_stream_upstream_t        *u;
  926.     ngx_stream_proxy_srv_conf_t  *pscf;

  927.     pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);

  928.     u = s->upstream;

  929.     if (pscf->ssl_name) {
  930.         if (ngx_stream_complex_value(s, pscf->ssl_name, &name) != NGX_OK) {
  931.             return NGX_ERROR;
  932.         }

  933.     } else {
  934.         name = u->ssl_name;
  935.     }

  936.     if (name.len == 0) {
  937.         goto done;
  938.     }

  939.     /*
  940.      * ssl name here may contain port, strip it for compatibility
  941.      * with the http module
  942.      */

  943.     p = name.data;
  944.     last = name.data + name.len;

  945.     if (*p == '[') {
  946.         p = ngx_strlchr(p, last, ']');

  947.         if (p == NULL) {
  948.             p = name.data;
  949.         }
  950.     }

  951.     p = ngx_strlchr(p, last, ':');

  952.     if (p != NULL) {
  953.         name.len = p - name.data;
  954.     }

  955.     if (!pscf->ssl_server_name) {
  956.         goto done;
  957.     }

  958. #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME

  959.     /* as per RFC 6066, literal IPv4 and IPv6 addresses are not permitted */

  960.     if (name.len == 0 || *name.data == '[') {
  961.         goto done;
  962.     }

  963.     if (ngx_inet_addr(name.data, name.len) != INADDR_NONE) {
  964.         goto done;
  965.     }

  966.     /*
  967.      * SSL_set_tlsext_host_name() needs a null-terminated string,
  968.      * hence we explicitly null-terminate name here
  969.      */

  970.     p = ngx_pnalloc(s->connection->pool, name.len + 1);
  971.     if (p == NULL) {
  972.         return NGX_ERROR;
  973.     }

  974.     (void) ngx_cpystrn(p, name.data, name.len + 1);

  975.     name.data = p;

  976.     ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
  977.                    "upstream SSL server name: \"%s\"", name.data);

  978.     if (SSL_set_tlsext_host_name(u->peer.connection->ssl->connection,
  979.                                  (char *) name.data)
  980.         == 0)
  981.     {
  982.         ngx_ssl_error(NGX_LOG_ERR, s->connection->log, 0,
  983.                       "SSL_set_tlsext_host_name(\"%s\") failed", name.data);
  984.         return NGX_ERROR;
  985.     }

  986. #endif

  987. done:

  988.     u->ssl_name = name;

  989.     return NGX_OK;
  990. }


  991. static ngx_int_t
  992. ngx_stream_proxy_ssl_certificate(ngx_stream_session_t *s)
  993. {
  994.     ngx_str_t                     cert, key;
  995.     ngx_connection_t             *c;
  996.     ngx_stream_proxy_srv_conf_t  *pscf;

  997.     c = s->upstream->peer.connection;

  998.     pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);

  999.     if (ngx_stream_complex_value(s, pscf->ssl_certificate, &cert)
  1000.         != NGX_OK)
  1001.     {
  1002.         return NGX_ERROR;
  1003.     }

  1004.     ngx_log_debug1(NGX_LOG_DEBUG_STREAM, c->log, 0,
  1005.                    "stream upstream ssl cert: \"%s\"", cert.data);

  1006.     if (*cert.data == '\0') {
  1007.         return NGX_OK;
  1008.     }

  1009.     if (ngx_stream_complex_value(s, pscf->ssl_certificate_key, &key)
  1010.         != NGX_OK)
  1011.     {
  1012.         return NGX_ERROR;
  1013.     }

  1014.     ngx_log_debug1(NGX_LOG_DEBUG_STREAM, c->log, 0,
  1015.                    "stream upstream ssl key: \"%s\"", key.data);

  1016.     if (ngx_ssl_connection_certificate(c, c->pool, &cert, &key,
  1017.                                        pscf->ssl_passwords)
  1018.         != NGX_OK)
  1019.     {
  1020.         return NGX_ERROR;
  1021.     }

  1022.     return NGX_OK;
  1023. }

  1024. #endif


  1025. static void
  1026. ngx_stream_proxy_downstream_handler(ngx_event_t *ev)
  1027. {
  1028.     ngx_stream_proxy_process_connection(ev, ev->write);
  1029. }


  1030. static void
  1031. ngx_stream_proxy_resolve_handler(ngx_resolver_ctx_t *ctx)
  1032. {
  1033.     ngx_stream_session_t            *s;
  1034.     ngx_stream_upstream_t           *u;
  1035.     ngx_stream_proxy_srv_conf_t     *pscf;
  1036.     ngx_stream_upstream_resolved_t  *ur;

  1037.     s = ctx->data;

  1038.     u = s->upstream;
  1039.     ur = u->resolved;

  1040.     ngx_log_debug0(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
  1041.                    "stream upstream resolve");

  1042.     if (ctx->state) {
  1043.         ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
  1044.                       "%V could not be resolved (%i: %s)",
  1045.                       &ctx->name, ctx->state,
  1046.                       ngx_resolver_strerror(ctx->state));

  1047.         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  1048.         return;
  1049.     }

  1050.     ur->naddrs = ctx->naddrs;
  1051.     ur->addrs = ctx->addrs;

  1052. #if (NGX_DEBUG)
  1053.     {
  1054.     u_char      text[NGX_SOCKADDR_STRLEN];
  1055.     ngx_str_t   addr;
  1056.     ngx_uint_t  i;

  1057.     addr.data = text;

  1058.     for (i = 0; i < ctx->naddrs; i++) {
  1059.         addr.len = ngx_sock_ntop(ur->addrs[i].sockaddr, ur->addrs[i].socklen,
  1060.                                  text, NGX_SOCKADDR_STRLEN, 0);

  1061.         ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
  1062.                        "name was resolved to %V", &addr);
  1063.     }
  1064.     }
  1065. #endif

  1066.     if (ngx_stream_upstream_create_round_robin_peer(s, ur) != NGX_OK) {
  1067.         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  1068.         return;
  1069.     }

  1070.     ngx_resolve_name_done(ctx);
  1071.     ur->ctx = NULL;

  1072.     u->peer.start_time = ngx_current_msec;

  1073.     pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);

  1074.     if (pscf->next_upstream_tries
  1075.         && u->peer.tries > pscf->next_upstream_tries)
  1076.     {
  1077.         u->peer.tries = pscf->next_upstream_tries;
  1078.     }

  1079.     ngx_stream_proxy_connect(s);
  1080. }


  1081. static void
  1082. ngx_stream_proxy_upstream_handler(ngx_event_t *ev)
  1083. {
  1084.     ngx_stream_proxy_process_connection(ev, !ev->write);
  1085. }


  1086. static void
  1087. ngx_stream_proxy_process_connection(ngx_event_t *ev, ngx_uint_t from_upstream)
  1088. {
  1089.     ngx_connection_t             *c, *pc;
  1090.     ngx_log_handler_pt            handler;
  1091.     ngx_stream_session_t         *s;
  1092.     ngx_stream_upstream_t        *u;
  1093.     ngx_stream_proxy_srv_conf_t  *pscf;

  1094.     c = ev->data;
  1095.     s = c->data;
  1096.     u = s->upstream;

  1097.     if (c->close) {
  1098.         ngx_log_error(NGX_LOG_INFO, c->log, 0, "shutdown timeout");
  1099.         ngx_stream_proxy_finalize(s, NGX_STREAM_OK);
  1100.         return;
  1101.     }

  1102.     c = s->connection;
  1103.     pc = u->peer.connection;

  1104.     pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);

  1105.     if (ev->timedout) {
  1106.         ev->timedout = 0;

  1107.         if (ev->delayed) {
  1108.             ev->delayed = 0;

  1109.             if (!ev->ready) {
  1110.                 if (ngx_handle_read_event(ev, 0) != NGX_OK) {
  1111.                     ngx_stream_proxy_finalize(s,
  1112.                                               NGX_STREAM_INTERNAL_SERVER_ERROR);
  1113.                     return;
  1114.                 }

  1115.                 if (u->connected && !c->read->delayed && !pc->read->delayed) {
  1116.                     ngx_add_timer(c->write, pscf->timeout);
  1117.                 }

  1118.                 return;
  1119.             }

  1120.         } else {
  1121.             if (s->connection->type == SOCK_DGRAM) {

  1122.                 if (pscf->responses == NGX_MAX_INT32_VALUE
  1123.                     || (u->responses >= pscf->responses * u->requests))
  1124.                 {

  1125.                     /*
  1126.                      * successfully terminate timed out UDP session
  1127.                      * if expected number of responses was received
  1128.                      */

  1129.                     handler = c->log->handler;
  1130.                     c->log->handler = NULL;

  1131.                     ngx_log_error(NGX_LOG_INFO, c->log, 0,
  1132.                                   "udp timed out"
  1133.                                   ", packets from/to client:%ui/%ui"
  1134.                                   ", bytes from/to client:%O/%O"
  1135.                                   ", bytes from/to upstream:%O/%O",
  1136.                                   u->requests, u->responses,
  1137.                                   s->received, c->sent, u->received,
  1138.                                   pc ? pc->sent : 0);

  1139.                     c->log->handler = handler;

  1140.                     ngx_stream_proxy_finalize(s, NGX_STREAM_OK);
  1141.                     return;
  1142.                 }

  1143.                 ngx_connection_error(pc, NGX_ETIMEDOUT, "upstream timed out");

  1144.                 pc->read->error = 1;

  1145.                 ngx_stream_proxy_finalize(s, NGX_STREAM_BAD_GATEWAY);

  1146.                 return;
  1147.             }

  1148.             ngx_connection_error(c, NGX_ETIMEDOUT, "connection timed out");

  1149.             ngx_stream_proxy_finalize(s, NGX_STREAM_OK);

  1150.             return;
  1151.         }

  1152.     } else if (ev->delayed) {

  1153.         ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0,
  1154.                        "stream connection delayed");

  1155.         if (ngx_handle_read_event(ev, 0) != NGX_OK) {
  1156.             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  1157.         }

  1158.         return;
  1159.     }

  1160.     if (from_upstream && !u->connected) {
  1161.         return;
  1162.     }

  1163.     ngx_stream_proxy_process(s, from_upstream, ev->write);
  1164. }


  1165. static void
  1166. ngx_stream_proxy_connect_handler(ngx_event_t *ev)
  1167. {
  1168.     ngx_connection_t      *c;
  1169.     ngx_stream_session_t  *s;

  1170.     c = ev->data;
  1171.     s = c->data;

  1172.     if (ev->timedout) {
  1173.         ngx_log_error(NGX_LOG_ERR, c->log, NGX_ETIMEDOUT, "upstream timed out");
  1174.         ngx_stream_proxy_next_upstream(s);
  1175.         return;
  1176.     }

  1177.     ngx_del_timer(c->write);

  1178.     ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0,
  1179.                    "stream proxy connect upstream");

  1180.     if (ngx_stream_proxy_test_connect(c) != NGX_OK) {
  1181.         ngx_stream_proxy_next_upstream(s);
  1182.         return;
  1183.     }

  1184.     ngx_stream_proxy_init_upstream(s);
  1185. }


  1186. static ngx_int_t
  1187. ngx_stream_proxy_test_connect(ngx_connection_t *c)
  1188. {
  1189.     int        err;
  1190.     socklen_t  len;

  1191. #if (NGX_HAVE_KQUEUE)

  1192.     if (ngx_event_flags & NGX_USE_KQUEUE_EVENT)  {
  1193.         err = c->write->kq_errno ? c->write->kq_errno : c->read->kq_errno;

  1194.         if (err) {
  1195.             (void) ngx_connection_error(c, err,
  1196.                                     "kevent() reported that connect() failed");
  1197.             return NGX_ERROR;
  1198.         }

  1199.     } else
  1200. #endif
  1201.     {
  1202.         err = 0;
  1203.         len = sizeof(int);

  1204.         /*
  1205.          * BSDs and Linux return 0 and set a pending error in err
  1206.          * Solaris returns -1 and sets errno
  1207.          */

  1208.         if (getsockopt(c->fd, SOL_SOCKET, SO_ERROR, (void *) &err, &len)
  1209.             == -1)
  1210.         {
  1211.             err = ngx_socket_errno;
  1212.         }

  1213.         if (err) {
  1214.             (void) ngx_connection_error(c, err, "connect() failed");
  1215.             return NGX_ERROR;
  1216.         }
  1217.     }

  1218.     return NGX_OK;
  1219. }


  1220. static void
  1221. ngx_stream_proxy_process(ngx_stream_session_t *s, ngx_uint_t from_upstream,
  1222.     ngx_uint_t do_write)
  1223. {
  1224.     char                         *recv_action, *send_action;
  1225.     off_t                        *received, limit;
  1226.     size_t                        size, limit_rate;
  1227.     ssize_t                       n;
  1228.     ngx_buf_t                    *b;
  1229.     ngx_int_t                     rc;
  1230.     ngx_uint_t                    flags, *packets;
  1231.     ngx_msec_t                    delay;
  1232.     ngx_chain_t                  *cl, **ll, **out, **busy;
  1233.     ngx_connection_t             *c, *pc, *src, *dst;
  1234.     ngx_log_handler_pt            handler;
  1235.     ngx_stream_upstream_t        *u;
  1236.     ngx_stream_proxy_srv_conf_t  *pscf;

  1237.     u = s->upstream;

  1238.     c = s->connection;
  1239.     pc = u->connected ? u->peer.connection : NULL;

  1240.     if (c->type == SOCK_DGRAM && (ngx_terminate || ngx_exiting)) {

  1241.         /* socket is already closed on worker shutdown */

  1242.         handler = c->log->handler;
  1243.         c->log->handler = NULL;

  1244.         ngx_log_error(NGX_LOG_INFO, c->log, 0, "disconnected on shutdown");

  1245.         c->log->handler = handler;

  1246.         ngx_stream_proxy_finalize(s, NGX_STREAM_OK);
  1247.         return;
  1248.     }

  1249.     pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);

  1250.     if (from_upstream) {
  1251.         src = pc;
  1252.         dst = c;
  1253.         b = &u->upstream_buf;
  1254.         limit_rate = u->download_rate;
  1255.         received = &u->received;
  1256.         packets = &u->responses;
  1257.         out = &u->downstream_out;
  1258.         busy = &u->downstream_busy;
  1259.         recv_action = "proxying and reading from upstream";
  1260.         send_action = "proxying and sending to client";

  1261.     } else {
  1262.         src = c;
  1263.         dst = pc;
  1264.         b = &u->downstream_buf;
  1265.         limit_rate = u->upload_rate;
  1266.         received = &s->received;
  1267.         packets = &u->requests;
  1268.         out = &u->upstream_out;
  1269.         busy = &u->upstream_busy;
  1270.         recv_action = "proxying and reading from client";
  1271.         send_action = "proxying and sending to upstream";
  1272.     }

  1273.     for ( ;; ) {

  1274.         if (do_write && dst) {

  1275.             if (*out || *busy || dst->buffered) {
  1276.                 c->log->action = send_action;

  1277.                 rc = ngx_stream_top_filter(s, *out, from_upstream);

  1278.                 if (rc == NGX_ERROR) {
  1279.                     ngx_stream_proxy_finalize(s, NGX_STREAM_OK);
  1280.                     return;
  1281.                 }

  1282.                 ngx_chain_update_chains(c->pool, &u->free, busy, out,
  1283.                                       (ngx_buf_tag_t) &ngx_stream_proxy_module);

  1284.                 if (*busy == NULL) {
  1285.                     b->pos = b->start;
  1286.                     b->last = b->start;
  1287.                 }
  1288.             }
  1289.         }

  1290.         size = b->end - b->last;

  1291.         if (size && src->read->ready && !src->read->delayed) {

  1292.             if (limit_rate) {
  1293.                 limit = (off_t) limit_rate * (ngx_time() - u->start_sec + 1)
  1294.                         - *received;

  1295.                 if (limit <= 0) {
  1296.                     src->read->delayed = 1;
  1297.                     delay = (ngx_msec_t) (- limit * 1000 / limit_rate + 1);
  1298.                     ngx_add_timer(src->read, delay);
  1299.                     break;
  1300.                 }

  1301.                 if (c->type == SOCK_STREAM && (off_t) size > limit) {
  1302.                     size = (size_t) limit;
  1303.                 }
  1304.             }

  1305.             c->log->action = recv_action;

  1306.             n = src->recv(src, b->last, size);

  1307.             if (n == NGX_AGAIN) {
  1308.                 break;
  1309.             }

  1310.             if (n == NGX_ERROR) {
  1311.                 src->read->eof = 1;
  1312.                 n = 0;
  1313.             }

  1314.             if (n >= 0) {
  1315.                 if (limit_rate) {
  1316.                     delay = (ngx_msec_t) (n * 1000 / limit_rate);

  1317.                     if (delay > 0) {
  1318.                         src->read->delayed = 1;
  1319.                         ngx_add_timer(src->read, delay);
  1320.                     }
  1321.                 }

  1322.                 if (from_upstream) {
  1323.                     if (u->state->first_byte_time == (ngx_msec_t) -1) {
  1324.                         u->state->first_byte_time = ngx_current_msec
  1325.                                                     - u->start_time;
  1326.                     }
  1327.                 }

  1328.                 for (ll = out; *ll; ll = &(*ll)->next) { /* void */ }

  1329.                 cl = ngx_chain_get_free_buf(c->pool, &u->free);
  1330.                 if (cl == NULL) {
  1331.                     ngx_stream_proxy_finalize(s,
  1332.                                               NGX_STREAM_INTERNAL_SERVER_ERROR);
  1333.                     return;
  1334.                 }

  1335.                 *ll = cl;

  1336.                 cl->buf->pos = b->last;
  1337.                 cl->buf->last = b->last + n;
  1338.                 cl->buf->tag = (ngx_buf_tag_t) &ngx_stream_proxy_module;

  1339.                 cl->buf->temporary = (n ? 1 : 0);
  1340.                 cl->buf->last_buf = src->read->eof;
  1341.                 cl->buf->flush = !src->read->eof;

  1342.                 (*packets)++;
  1343.                 *received += n;
  1344.                 b->last += n;
  1345.                 do_write = 1;

  1346.                 continue;
  1347.             }
  1348.         }

  1349.         break;
  1350.     }

  1351.     c->log->action = "proxying connection";

  1352.     if (ngx_stream_proxy_test_finalize(s, from_upstream) == NGX_OK) {
  1353.         return;
  1354.     }

  1355.     flags = src->read->eof ? NGX_CLOSE_EVENT : 0;

  1356.     if (ngx_handle_read_event(src->read, flags) != NGX_OK) {
  1357.         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  1358.         return;
  1359.     }

  1360.     if (dst) {

  1361.         if (dst->type == SOCK_STREAM && pscf->half_close
  1362.             && src->read->eof && !u->half_closed && !dst->buffered)
  1363.         {
  1364.             if (ngx_shutdown_socket(dst->fd, NGX_WRITE_SHUTDOWN) == -1) {
  1365.                 ngx_connection_error(c, ngx_socket_errno,
  1366.                                      ngx_shutdown_socket_n " failed");

  1367.                 ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  1368.                 return;
  1369.             }

  1370.             u->half_closed = 1;
  1371.             ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
  1372.                            "stream proxy %s socket shutdown",
  1373.                            from_upstream ? "client" : "upstream");
  1374.         }

  1375.         if (ngx_handle_write_event(dst->write, 0) != NGX_OK) {
  1376.             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  1377.             return;
  1378.         }

  1379.         if (!c->read->delayed && !pc->read->delayed) {
  1380.             ngx_add_timer(c->write, pscf->timeout);

  1381.         } else if (c->write->timer_set) {
  1382.             ngx_del_timer(c->write);
  1383.         }
  1384.     }
  1385. }


  1386. static ngx_int_t
  1387. ngx_stream_proxy_test_finalize(ngx_stream_session_t *s,
  1388.     ngx_uint_t from_upstream)
  1389. {
  1390.     ngx_connection_t             *c, *pc;
  1391.     ngx_log_handler_pt            handler;
  1392.     ngx_stream_upstream_t        *u;
  1393.     ngx_stream_proxy_srv_conf_t  *pscf;

  1394.     pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);

  1395.     c = s->connection;
  1396.     u = s->upstream;
  1397.     pc = u->connected ? u->peer.connection : NULL;

  1398.     if (c->type == SOCK_DGRAM) {

  1399.         if (pscf->requests && u->requests < pscf->requests) {
  1400.             return NGX_DECLINED;
  1401.         }

  1402.         if (pscf->requests) {
  1403.             ngx_delete_udp_connection(c);
  1404.         }

  1405.         if (pscf->responses == NGX_MAX_INT32_VALUE
  1406.             || u->responses < pscf->responses * u->requests)
  1407.         {
  1408.             return NGX_DECLINED;
  1409.         }

  1410.         if (pc == NULL || c->buffered || pc->buffered) {
  1411.             return NGX_DECLINED;
  1412.         }

  1413.         handler = c->log->handler;
  1414.         c->log->handler = NULL;

  1415.         ngx_log_error(NGX_LOG_INFO, c->log, 0,
  1416.                       "udp done"
  1417.                       ", packets from/to client:%ui/%ui"
  1418.                       ", bytes from/to client:%O/%O"
  1419.                       ", bytes from/to upstream:%O/%O",
  1420.                       u->requests, u->responses,
  1421.                       s->received, c->sent, u->received, pc ? pc->sent : 0);

  1422.         c->log->handler = handler;

  1423.         ngx_stream_proxy_finalize(s, NGX_STREAM_OK);

  1424.         return NGX_OK;
  1425.     }

  1426.     /* c->type == SOCK_STREAM */

  1427.     if (pc == NULL
  1428.         || (!c->read->eof && !pc->read->eof)
  1429.         || (!c->read->eof && c->buffered)
  1430.         || (!pc->read->eof && pc->buffered))
  1431.     {
  1432.         return NGX_DECLINED;
  1433.     }

  1434.     if (pscf->half_close) {
  1435.         /* avoid closing live connections until both read ends get EOF */
  1436.         if (!(c->read->eof && pc->read->eof && !c->buffered && !pc->buffered)) {
  1437.              return NGX_DECLINED;
  1438.         }
  1439.     }

  1440.     handler = c->log->handler;
  1441.     c->log->handler = NULL;

  1442.     ngx_log_error(NGX_LOG_INFO, c->log, 0,
  1443.                   "%s disconnected"
  1444.                   ", bytes from/to client:%O/%O"
  1445.                   ", bytes from/to upstream:%O/%O",
  1446.                   from_upstream ? "upstream" : "client",
  1447.                   s->received, c->sent, u->received, pc ? pc->sent : 0);

  1448.     c->log->handler = handler;

  1449.     ngx_stream_proxy_finalize(s, NGX_STREAM_OK);

  1450.     return NGX_OK;
  1451. }


  1452. static void
  1453. ngx_stream_proxy_next_upstream(ngx_stream_session_t *s)
  1454. {
  1455.     ngx_msec_t                    timeout;
  1456.     ngx_connection_t             *pc;
  1457.     ngx_stream_upstream_t        *u;
  1458.     ngx_stream_proxy_srv_conf_t  *pscf;

  1459.     ngx_log_debug0(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
  1460.                    "stream proxy next upstream");

  1461.     u = s->upstream;
  1462.     pc = u->peer.connection;

  1463.     if (pc && pc->buffered) {
  1464.         ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
  1465.                       "buffered data on next upstream");
  1466.         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  1467.         return;
  1468.     }

  1469.     if (s->connection->type == SOCK_DGRAM) {
  1470.         u->upstream_out = NULL;
  1471.     }

  1472.     if (u->peer.sockaddr) {
  1473.         u->peer.free(&u->peer, u->peer.data, NGX_PEER_FAILED);
  1474.         u->peer.sockaddr = NULL;
  1475.     }

  1476.     pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);

  1477.     timeout = pscf->next_upstream_timeout;

  1478.     if (u->peer.tries == 0
  1479.         || !pscf->next_upstream
  1480.         || (timeout && ngx_current_msec - u->peer.start_time >= timeout))
  1481.     {
  1482.         ngx_stream_proxy_finalize(s, NGX_STREAM_BAD_GATEWAY);
  1483.         return;
  1484.     }

  1485.     if (pc) {
  1486.         ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
  1487.                        "close proxy upstream connection: %d", pc->fd);

  1488. #if (NGX_STREAM_SSL)
  1489.         if (pc->ssl) {
  1490.             pc->ssl->no_wait_shutdown = 1;
  1491.             pc->ssl->no_send_shutdown = 1;

  1492.             (void) ngx_ssl_shutdown(pc);
  1493.         }
  1494. #endif

  1495.         u->state->bytes_received = u->received;
  1496.         u->state->bytes_sent = pc->sent;

  1497.         ngx_close_connection(pc);
  1498.         u->peer.connection = NULL;
  1499.     }

  1500.     ngx_stream_proxy_connect(s);
  1501. }


  1502. static void
  1503. ngx_stream_proxy_finalize(ngx_stream_session_t *s, ngx_uint_t rc)
  1504. {
  1505.     ngx_uint_t              state;
  1506.     ngx_connection_t       *pc;
  1507.     ngx_stream_upstream_t  *u;

  1508.     ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
  1509.                    "finalize stream proxy: %i", rc);

  1510.     u = s->upstream;

  1511.     if (u == NULL) {
  1512.         goto noupstream;
  1513.     }

  1514.     if (u->resolved && u->resolved->ctx) {
  1515.         ngx_resolve_name_done(u->resolved->ctx);
  1516.         u->resolved->ctx = NULL;
  1517.     }

  1518.     pc = u->peer.connection;

  1519.     if (u->state) {
  1520.         if (u->state->response_time == (ngx_msec_t) -1) {
  1521.             u->state->response_time = ngx_current_msec - u->start_time;
  1522.         }

  1523.         if (pc) {
  1524.             u->state->bytes_received = u->received;
  1525.             u->state->bytes_sent = pc->sent;
  1526.         }
  1527.     }

  1528.     if (u->peer.free && u->peer.sockaddr) {
  1529.         state = 0;

  1530.         if (pc && pc->type == SOCK_DGRAM
  1531.             && (pc->read->error || pc->write->error))
  1532.         {
  1533.             state = NGX_PEER_FAILED;
  1534.         }

  1535.         u->peer.free(&u->peer, u->peer.data, state);
  1536.         u->peer.sockaddr = NULL;
  1537.     }

  1538.     if (pc) {
  1539.         ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
  1540.                        "close stream proxy upstream connection: %d", pc->fd);

  1541. #if (NGX_STREAM_SSL)
  1542.         if (pc->ssl) {
  1543.             pc->ssl->no_wait_shutdown = 1;
  1544.             (void) ngx_ssl_shutdown(pc);
  1545.         }
  1546. #endif

  1547.         ngx_close_connection(pc);
  1548.         u->peer.connection = NULL;
  1549.     }

  1550. noupstream:

  1551.     ngx_stream_finalize_session(s, rc);
  1552. }


  1553. static u_char *
  1554. ngx_stream_proxy_log_error(ngx_log_t *log, u_char *buf, size_t len)
  1555. {
  1556.     u_char                 *p;
  1557.     ngx_connection_t       *pc;
  1558.     ngx_stream_session_t   *s;
  1559.     ngx_stream_upstream_t  *u;

  1560.     s = log->data;

  1561.     u = s->upstream;

  1562.     p = buf;

  1563.     if (u->peer.name) {
  1564.         p = ngx_snprintf(p, len, ", upstream: \"%V\"", u->peer.name);
  1565.         len -= p - buf;
  1566.     }

  1567.     pc = u->peer.connection;

  1568.     p = ngx_snprintf(p, len,
  1569.                      ", bytes from/to client:%O/%O"
  1570.                      ", bytes from/to upstream:%O/%O",
  1571.                      s->received, s->connection->sent,
  1572.                      u->received, pc ? pc->sent : 0);

  1573.     return p;
  1574. }


  1575. static void *
  1576. ngx_stream_proxy_create_srv_conf(ngx_conf_t *cf)
  1577. {
  1578.     ngx_stream_proxy_srv_conf_t  *conf;

  1579.     conf = ngx_pcalloc(cf->pool, sizeof(ngx_stream_proxy_srv_conf_t));
  1580.     if (conf == NULL) {
  1581.         return NULL;
  1582.     }

  1583.     /*
  1584.      * set by ngx_pcalloc():
  1585.      *
  1586.      *     conf->ssl_protocols = 0;
  1587.      *     conf->ssl_ciphers = { 0, NULL };
  1588.      *     conf->ssl_trusted_certificate = { 0, NULL };
  1589.      *     conf->ssl_crl = { 0, NULL };
  1590.      *
  1591.      *     conf->ssl = NULL;
  1592.      *     conf->upstream = NULL;
  1593.      *     conf->upstream_value = NULL;
  1594.      */

  1595.     conf->connect_timeout = NGX_CONF_UNSET_MSEC;
  1596.     conf->timeout = NGX_CONF_UNSET_MSEC;
  1597.     conf->next_upstream_timeout = NGX_CONF_UNSET_MSEC;
  1598.     conf->buffer_size = NGX_CONF_UNSET_SIZE;
  1599.     conf->upload_rate = NGX_CONF_UNSET_PTR;
  1600.     conf->download_rate = NGX_CONF_UNSET_PTR;
  1601.     conf->requests = NGX_CONF_UNSET_UINT;
  1602.     conf->responses = NGX_CONF_UNSET_UINT;
  1603.     conf->next_upstream_tries = NGX_CONF_UNSET_UINT;
  1604.     conf->next_upstream = NGX_CONF_UNSET;
  1605.     conf->proxy_protocol = NGX_CONF_UNSET;
  1606.     conf->local = NGX_CONF_UNSET_PTR;
  1607.     conf->socket_keepalive = NGX_CONF_UNSET;
  1608.     conf->half_close = NGX_CONF_UNSET;

  1609. #if (NGX_STREAM_SSL)
  1610.     conf->ssl_enable = NGX_CONF_UNSET;
  1611.     conf->ssl_session_reuse = NGX_CONF_UNSET;
  1612.     conf->ssl_name = NGX_CONF_UNSET_PTR;
  1613.     conf->ssl_server_name = NGX_CONF_UNSET;
  1614.     conf->ssl_verify = NGX_CONF_UNSET;
  1615.     conf->ssl_verify_depth = NGX_CONF_UNSET_UINT;
  1616.     conf->ssl_certificate = NGX_CONF_UNSET_PTR;
  1617.     conf->ssl_certificate_key = NGX_CONF_UNSET_PTR;
  1618.     conf->ssl_passwords = NGX_CONF_UNSET_PTR;
  1619.     conf->ssl_conf_commands = NGX_CONF_UNSET_PTR;
  1620. #endif

  1621.     return conf;
  1622. }


  1623. static char *
  1624. ngx_stream_proxy_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
  1625. {
  1626.     ngx_stream_proxy_srv_conf_t *prev = parent;
  1627.     ngx_stream_proxy_srv_conf_t *conf = child;

  1628.     ngx_conf_merge_msec_value(conf->connect_timeout,
  1629.                               prev->connect_timeout, 60000);

  1630.     ngx_conf_merge_msec_value(conf->timeout,
  1631.                               prev->timeout, 10 * 60000);

  1632.     ngx_conf_merge_msec_value(conf->next_upstream_timeout,
  1633.                               prev->next_upstream_timeout, 0);

  1634.     ngx_conf_merge_size_value(conf->buffer_size,
  1635.                               prev->buffer_size, 16384);

  1636.     ngx_conf_merge_ptr_value(conf->upload_rate, prev->upload_rate, NULL);

  1637.     ngx_conf_merge_ptr_value(conf->download_rate, prev->download_rate, NULL);

  1638.     ngx_conf_merge_uint_value(conf->requests,
  1639.                               prev->requests, 0);

  1640.     ngx_conf_merge_uint_value(conf->responses,
  1641.                               prev->responses, NGX_MAX_INT32_VALUE);

  1642.     ngx_conf_merge_uint_value(conf->next_upstream_tries,
  1643.                               prev->next_upstream_tries, 0);

  1644.     ngx_conf_merge_value(conf->next_upstream, prev->next_upstream, 1);

  1645.     ngx_conf_merge_value(conf->proxy_protocol, prev->proxy_protocol, 0);

  1646.     ngx_conf_merge_ptr_value(conf->local, prev->local, NULL);

  1647.     ngx_conf_merge_value(conf->socket_keepalive,
  1648.                               prev->socket_keepalive, 0);

  1649.     ngx_conf_merge_value(conf->half_close, prev->half_close, 0);

  1650. #if (NGX_STREAM_SSL)

  1651.     if (ngx_stream_proxy_merge_ssl(cf, conf, prev) != NGX_OK) {
  1652.         return NGX_CONF_ERROR;
  1653.     }

  1654.     ngx_conf_merge_value(conf->ssl_enable, prev->ssl_enable, 0);

  1655.     ngx_conf_merge_value(conf->ssl_session_reuse,
  1656.                               prev->ssl_session_reuse, 1);

  1657.     ngx_conf_merge_bitmask_value(conf->ssl_protocols, prev->ssl_protocols,
  1658.                               (NGX_CONF_BITMASK_SET|NGX_SSL_DEFAULT_PROTOCOLS));

  1659.     ngx_conf_merge_str_value(conf->ssl_ciphers, prev->ssl_ciphers, "DEFAULT");

  1660.     ngx_conf_merge_ptr_value(conf->ssl_name, prev->ssl_name, NULL);

  1661.     ngx_conf_merge_value(conf->ssl_server_name, prev->ssl_server_name, 0);

  1662.     ngx_conf_merge_value(conf->ssl_verify, prev->ssl_verify, 0);

  1663.     ngx_conf_merge_uint_value(conf->ssl_verify_depth,
  1664.                               prev->ssl_verify_depth, 1);

  1665.     ngx_conf_merge_str_value(conf->ssl_trusted_certificate,
  1666.                               prev->ssl_trusted_certificate, "");

  1667.     ngx_conf_merge_str_value(conf->ssl_crl, prev->ssl_crl, "");

  1668.     ngx_conf_merge_ptr_value(conf->ssl_certificate,
  1669.                               prev->ssl_certificate, NULL);

  1670.     ngx_conf_merge_ptr_value(conf->ssl_certificate_key,
  1671.                               prev->ssl_certificate_key, NULL);

  1672.     ngx_conf_merge_ptr_value(conf->ssl_passwords, prev->ssl_passwords, NULL);

  1673.     ngx_conf_merge_ptr_value(conf->ssl_conf_commands,
  1674.                               prev->ssl_conf_commands, NULL);

  1675.     if (conf->ssl_enable && ngx_stream_proxy_set_ssl(cf, conf) != NGX_OK) {
  1676.         return NGX_CONF_ERROR;
  1677.     }

  1678. #endif

  1679.     return NGX_CONF_OK;
  1680. }


  1681. #if (NGX_STREAM_SSL)

  1682. static ngx_int_t
  1683. ngx_stream_proxy_merge_ssl(ngx_conf_t *cf, ngx_stream_proxy_srv_conf_t *conf,
  1684.     ngx_stream_proxy_srv_conf_t *prev)
  1685. {
  1686.     ngx_uint_t  preserve;

  1687.     if (conf->ssl_protocols == 0
  1688.         && conf->ssl_ciphers.data == NULL
  1689.         && conf->ssl_certificate == NGX_CONF_UNSET_PTR
  1690.         && conf->ssl_certificate_key == NGX_CONF_UNSET_PTR
  1691.         && conf->ssl_passwords == NGX_CONF_UNSET_PTR
  1692.         && conf->ssl_verify == NGX_CONF_UNSET
  1693.         && conf->ssl_verify_depth == NGX_CONF_UNSET_UINT
  1694.         && conf->ssl_trusted_certificate.data == NULL
  1695.         && conf->ssl_crl.data == NULL
  1696.         && conf->ssl_session_reuse == NGX_CONF_UNSET
  1697.         && conf->ssl_conf_commands == NGX_CONF_UNSET_PTR)
  1698.     {
  1699.         if (prev->ssl) {
  1700.             conf->ssl = prev->ssl;
  1701.             return NGX_OK;
  1702.         }

  1703.         preserve = 1;

  1704.     } else {
  1705.         preserve = 0;
  1706.     }

  1707.     conf->ssl = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_t));
  1708.     if (conf->ssl == NULL) {
  1709.         return NGX_ERROR;
  1710.     }

  1711.     conf->ssl->log = cf->log;

  1712.     /*
  1713.      * special handling to preserve conf->ssl
  1714.      * in the "stream" section to inherit it to all servers
  1715.      */

  1716.     if (preserve) {
  1717.         prev->ssl = conf->ssl;
  1718.     }

  1719.     return NGX_OK;
  1720. }


  1721. static ngx_int_t
  1722. ngx_stream_proxy_set_ssl(ngx_conf_t *cf, ngx_stream_proxy_srv_conf_t *pscf)
  1723. {
  1724.     ngx_pool_cleanup_t  *cln;

  1725.     if (pscf->ssl->ctx) {
  1726.         return NGX_OK;
  1727.     }

  1728.     if (ngx_ssl_create(pscf->ssl, pscf->ssl_protocols, NULL) != NGX_OK) {
  1729.         return NGX_ERROR;
  1730.     }

  1731.     cln = ngx_pool_cleanup_add(cf->pool, 0);
  1732.     if (cln == NULL) {
  1733.         ngx_ssl_cleanup_ctx(pscf->ssl);
  1734.         return NGX_ERROR;
  1735.     }

  1736.     cln->handler = ngx_ssl_cleanup_ctx;
  1737.     cln->data = pscf->ssl;

  1738.     if (ngx_ssl_ciphers(cf, pscf->ssl, &pscf->ssl_ciphers, 0) != NGX_OK) {
  1739.         return NGX_ERROR;
  1740.     }

  1741.     if (pscf->ssl_certificate
  1742.         && pscf->ssl_certificate->value.len)
  1743.     {
  1744.         if (pscf->ssl_certificate_key == NULL) {
  1745.             ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
  1746.                           "no \"proxy_ssl_certificate_key\" is defined "
  1747.                           "for certificate \"%V\"",
  1748.                           &pscf->ssl_certificate->value);
  1749.             return NGX_ERROR;
  1750.         }

  1751.         if (pscf->ssl_certificate->lengths
  1752.             || pscf->ssl_certificate_key->lengths)
  1753.         {
  1754.             pscf->ssl_passwords =
  1755.                            ngx_ssl_preserve_passwords(cf, pscf->ssl_passwords);
  1756.             if (pscf->ssl_passwords == NULL) {
  1757.                 return NGX_ERROR;
  1758.             }

  1759.         } else {
  1760.             if (ngx_ssl_certificate(cf, pscf->ssl,
  1761.                                     &pscf->ssl_certificate->value,
  1762.                                     &pscf->ssl_certificate_key->value,
  1763.                                     pscf->ssl_passwords)
  1764.                 != NGX_OK)
  1765.             {
  1766.                 return NGX_ERROR;
  1767.             }
  1768.         }
  1769.     }

  1770.     if (pscf->ssl_verify) {
  1771.         if (pscf->ssl_trusted_certificate.len == 0) {
  1772.             ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
  1773.                       "no proxy_ssl_trusted_certificate for proxy_ssl_verify");
  1774.             return NGX_ERROR;
  1775.         }

  1776.         if (ngx_ssl_trusted_certificate(cf, pscf->ssl,
  1777.                                         &pscf->ssl_trusted_certificate,
  1778.                                         pscf->ssl_verify_depth)
  1779.             != NGX_OK)
  1780.         {
  1781.             return NGX_ERROR;
  1782.         }

  1783.         if (ngx_ssl_crl(cf, pscf->ssl, &pscf->ssl_crl) != NGX_OK) {
  1784.             return NGX_ERROR;
  1785.         }
  1786.     }

  1787.     if (ngx_ssl_client_session_cache(cf, pscf->ssl, pscf->ssl_session_reuse)
  1788.         != NGX_OK)
  1789.     {
  1790.         return NGX_ERROR;
  1791.     }

  1792.     if (ngx_ssl_conf_commands(cf, pscf->ssl, pscf->ssl_conf_commands)
  1793.         != NGX_OK)
  1794.     {
  1795.         return NGX_ERROR;
  1796.     }

  1797.     return NGX_OK;
  1798. }

  1799. #endif


  1800. static char *
  1801. ngx_stream_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  1802. {
  1803.     ngx_stream_proxy_srv_conf_t *pscf = conf;

  1804.     ngx_url_t                            u;
  1805.     ngx_str_t                           *value, *url;
  1806.     ngx_stream_complex_value_t           cv;
  1807.     ngx_stream_core_srv_conf_t          *cscf;
  1808.     ngx_stream_compile_complex_value_t   ccv;

  1809.     if (pscf->upstream || pscf->upstream_value) {
  1810.         return "is duplicate";
  1811.     }

  1812.     cscf = ngx_stream_conf_get_module_srv_conf(cf, ngx_stream_core_module);

  1813.     cscf->handler = ngx_stream_proxy_handler;

  1814.     value = cf->args->elts;

  1815.     url = &value[1];

  1816.     ngx_memzero(&ccv, sizeof(ngx_stream_compile_complex_value_t));

  1817.     ccv.cf = cf;
  1818.     ccv.value = url;
  1819.     ccv.complex_value = &cv;

  1820.     if (ngx_stream_compile_complex_value(&ccv) != NGX_OK) {
  1821.         return NGX_CONF_ERROR;
  1822.     }

  1823.     if (cv.lengths) {
  1824.         pscf->upstream_value = ngx_palloc(cf->pool,
  1825.                                           sizeof(ngx_stream_complex_value_t));
  1826.         if (pscf->upstream_value == NULL) {
  1827.             return NGX_CONF_ERROR;
  1828.         }

  1829.         *pscf->upstream_value = cv;

  1830.         return NGX_CONF_OK;
  1831.     }

  1832.     ngx_memzero(&u, sizeof(ngx_url_t));

  1833.     u.url = *url;
  1834.     u.no_resolve = 1;

  1835.     pscf->upstream = ngx_stream_upstream_add(cf, &u, 0);
  1836.     if (pscf->upstream == NULL) {
  1837.         return NGX_CONF_ERROR;
  1838.     }

  1839.     return NGX_CONF_OK;
  1840. }


  1841. static char *
  1842. ngx_stream_proxy_bind(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  1843. {
  1844.     ngx_stream_proxy_srv_conf_t *pscf = conf;

  1845.     ngx_int_t                            rc;
  1846.     ngx_str_t                           *value;
  1847.     ngx_stream_complex_value_t           cv;
  1848.     ngx_stream_upstream_local_t         *local;
  1849.     ngx_stream_compile_complex_value_t   ccv;

  1850.     if (pscf->local != NGX_CONF_UNSET_PTR) {
  1851.         return "is duplicate";
  1852.     }

  1853.     value = cf->args->elts;

  1854.     if (cf->args->nelts == 2 && ngx_strcmp(value[1].data, "off") == 0) {
  1855.         pscf->local = NULL;
  1856.         return NGX_CONF_OK;
  1857.     }

  1858.     ngx_memzero(&ccv, sizeof(ngx_stream_compile_complex_value_t));

  1859.     ccv.cf = cf;
  1860.     ccv.value = &value[1];
  1861.     ccv.complex_value = &cv;

  1862.     if (ngx_stream_compile_complex_value(&ccv) != NGX_OK) {
  1863.         return NGX_CONF_ERROR;
  1864.     }

  1865.     local = ngx_pcalloc(cf->pool, sizeof(ngx_stream_upstream_local_t));
  1866.     if (local == NULL) {
  1867.         return NGX_CONF_ERROR;
  1868.     }

  1869.     pscf->local = local;

  1870.     if (cv.lengths) {
  1871.         local->value = ngx_palloc(cf->pool, sizeof(ngx_stream_complex_value_t));
  1872.         if (local->value == NULL) {
  1873.             return NGX_CONF_ERROR;
  1874.         }

  1875.         *local->value = cv;

  1876.     } else {
  1877.         local->addr = ngx_palloc(cf->pool, sizeof(ngx_addr_t));
  1878.         if (local->addr == NULL) {
  1879.             return NGX_CONF_ERROR;
  1880.         }

  1881.         rc = ngx_parse_addr_port(cf->pool, local->addr, value[1].data,
  1882.                                  value[1].len);

  1883.         switch (rc) {
  1884.         case NGX_OK:
  1885.             local->addr->name = value[1];
  1886.             break;

  1887.         case NGX_DECLINED:
  1888.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  1889.                                "invalid address \"%V\"", &value[1]);
  1890.             /* fall through */

  1891.         default:
  1892.             return NGX_CONF_ERROR;
  1893.         }
  1894.     }

  1895.     if (cf->args->nelts > 2) {
  1896.         if (ngx_strcmp(value[2].data, "transparent") == 0) {
  1897. #if (NGX_HAVE_TRANSPARENT_PROXY)
  1898.             ngx_core_conf_t  *ccf;

  1899.             ccf = (ngx_core_conf_t *) ngx_get_conf(cf->cycle->conf_ctx,
  1900.                                                    ngx_core_module);

  1901.             ccf->transparent = 1;
  1902.             local->transparent = 1;
  1903. #else
  1904.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  1905.                                "transparent proxying is not supported "
  1906.                                "on this platform, ignored");
  1907. #endif
  1908.         } else {
  1909.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  1910.                                "invalid parameter \"%V\"", &value[2]);
  1911.             return NGX_CONF_ERROR;
  1912.         }
  1913.     }

  1914.     return NGX_CONF_OK;
  1915. }