src/stream/ngx_stream_proxy_module.c - nginx-1.31.3 nginx/ @ 42f8df65b

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_array_t                     *ssl_alpn;

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

  47.     ngx_ssl_t                       *ssl;
  48. #endif

  49.     ngx_stream_upstream_srv_conf_t  *upstream;
  50.     ngx_stream_complex_value_t      *upstream_value;
  51. } ngx_stream_proxy_srv_conf_t;


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

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

  81. #if (NGX_STREAM_SSL)

  82. static ngx_int_t ngx_stream_proxy_send_proxy_protocol(ngx_stream_session_t *s);
  83. static char *ngx_stream_proxy_ssl_alpn_set_slot(ngx_conf_t *cf,
  84.     ngx_command_t *cmd, void *conf);
  85. static char *ngx_stream_proxy_ssl_certificate_cache(ngx_conf_t *cf,
  86.     ngx_command_t *cmd, void *conf);
  87. static char *ngx_stream_proxy_ssl_password_file(ngx_conf_t *cf,
  88.     ngx_command_t *cmd, void *conf);
  89. static char *ngx_stream_proxy_ssl_conf_command_check(ngx_conf_t *cf, void *post,
  90.     void *data);
  91. static void ngx_stream_proxy_ssl_init_connection(ngx_stream_session_t *s);
  92. static void ngx_stream_proxy_ssl_handshake(ngx_connection_t *pc);
  93. static void ngx_stream_proxy_ssl_save_session(ngx_connection_t *c);
  94. static ngx_int_t ngx_stream_proxy_ssl_name(ngx_stream_session_t *s);
  95. static ngx_int_t ngx_stream_proxy_ssl_alpn(ngx_stream_session_t *s);
  96. static ngx_int_t ngx_stream_proxy_ssl_certificate(ngx_stream_session_t *s);
  97. static ngx_int_t ngx_stream_proxy_merge_ssl(ngx_conf_t *cf,
  98.     ngx_stream_proxy_srv_conf_t *conf, ngx_stream_proxy_srv_conf_t *prev);
  99. static ngx_int_t ngx_stream_proxy_merge_ssl_passwords(ngx_conf_t *cf,
  100.     ngx_stream_proxy_srv_conf_t *conf, ngx_stream_proxy_srv_conf_t *prev);
  101. static ngx_int_t ngx_stream_proxy_set_ssl(ngx_conf_t *cf,
  102.     ngx_stream_proxy_srv_conf_t *pscf);


  103. static ngx_conf_bitmask_t  ngx_stream_proxy_ssl_protocols[] = {
  104.     { ngx_string("SSLv2"), NGX_SSL_SSLv2 },
  105.     { ngx_string("SSLv3"), NGX_SSL_SSLv3 },
  106.     { ngx_string("TLSv1"), NGX_SSL_TLSv1 },
  107.     { ngx_string("TLSv1.1"), NGX_SSL_TLSv1_1 },
  108.     { ngx_string("TLSv1.2"), NGX_SSL_TLSv1_2 },
  109.     { ngx_string("TLSv1.3"), NGX_SSL_TLSv1_3 },
  110.     { ngx_null_string, 0 }
  111. };

  112. static ngx_conf_post_t  ngx_stream_proxy_ssl_conf_command_post =
  113.     { ngx_stream_proxy_ssl_conf_command_check };

  114. #endif


  115. static ngx_conf_deprecated_t  ngx_conf_deprecated_proxy_downstream_buffer = {
  116.     ngx_conf_deprecated, "proxy_downstream_buffer", "proxy_buffer_size"
  117. };

  118. static ngx_conf_deprecated_t  ngx_conf_deprecated_proxy_upstream_buffer = {
  119.     ngx_conf_deprecated, "proxy_upstream_buffer", "proxy_buffer_size"
  120. };


  121. static ngx_command_t  ngx_stream_proxy_commands[] = {

  122.     { ngx_string("proxy_pass"),
  123.       NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  124.       ngx_stream_proxy_pass,
  125.       NGX_STREAM_SRV_CONF_OFFSET,
  126.       0,
  127.       NULL },

  128.     { ngx_string("proxy_bind"),
  129.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE12,
  130.       ngx_stream_proxy_bind,
  131.       NGX_STREAM_SRV_CONF_OFFSET,
  132.       0,
  133.       NULL },

  134.     { ngx_string("proxy_socket_keepalive"),
  135.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
  136.       ngx_conf_set_flag_slot,
  137.       NGX_STREAM_SRV_CONF_OFFSET,
  138.       offsetof(ngx_stream_proxy_srv_conf_t, socket_keepalive),
  139.       NULL },

  140.     { ngx_string("proxy_connect_timeout"),
  141.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  142.       ngx_conf_set_msec_slot,
  143.       NGX_STREAM_SRV_CONF_OFFSET,
  144.       offsetof(ngx_stream_proxy_srv_conf_t, connect_timeout),
  145.       NULL },

  146.     { ngx_string("proxy_timeout"),
  147.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  148.       ngx_conf_set_msec_slot,
  149.       NGX_STREAM_SRV_CONF_OFFSET,
  150.       offsetof(ngx_stream_proxy_srv_conf_t, timeout),
  151.       NULL },

  152.     { ngx_string("proxy_buffer_size"),
  153.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  154.       ngx_conf_set_size_slot,
  155.       NGX_STREAM_SRV_CONF_OFFSET,
  156.       offsetof(ngx_stream_proxy_srv_conf_t, buffer_size),
  157.       NULL },

  158.     { ngx_string("proxy_downstream_buffer"),
  159.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  160.       ngx_conf_set_size_slot,
  161.       NGX_STREAM_SRV_CONF_OFFSET,
  162.       offsetof(ngx_stream_proxy_srv_conf_t, buffer_size),
  163.       &ngx_conf_deprecated_proxy_downstream_buffer },

  164.     { ngx_string("proxy_upstream_buffer"),
  165.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  166.       ngx_conf_set_size_slot,
  167.       NGX_STREAM_SRV_CONF_OFFSET,
  168.       offsetof(ngx_stream_proxy_srv_conf_t, buffer_size),
  169.       &ngx_conf_deprecated_proxy_upstream_buffer },

  170.     { ngx_string("proxy_upload_rate"),
  171.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  172.       ngx_stream_set_complex_value_size_slot,
  173.       NGX_STREAM_SRV_CONF_OFFSET,
  174.       offsetof(ngx_stream_proxy_srv_conf_t, upload_rate),
  175.       NULL },

  176.     { ngx_string("proxy_download_rate"),
  177.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  178.       ngx_stream_set_complex_value_size_slot,
  179.       NGX_STREAM_SRV_CONF_OFFSET,
  180.       offsetof(ngx_stream_proxy_srv_conf_t, download_rate),
  181.       NULL },

  182.     { ngx_string("proxy_requests"),
  183.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  184.       ngx_conf_set_num_slot,
  185.       NGX_STREAM_SRV_CONF_OFFSET,
  186.       offsetof(ngx_stream_proxy_srv_conf_t, requests),
  187.       NULL },

  188.     { ngx_string("proxy_responses"),
  189.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  190.       ngx_conf_set_num_slot,
  191.       NGX_STREAM_SRV_CONF_OFFSET,
  192.       offsetof(ngx_stream_proxy_srv_conf_t, responses),
  193.       NULL },

  194.     { ngx_string("proxy_next_upstream"),
  195.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
  196.       ngx_conf_set_flag_slot,
  197.       NGX_STREAM_SRV_CONF_OFFSET,
  198.       offsetof(ngx_stream_proxy_srv_conf_t, next_upstream),
  199.       NULL },

  200.     { ngx_string("proxy_next_upstream_tries"),
  201.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  202.       ngx_conf_set_num_slot,
  203.       NGX_STREAM_SRV_CONF_OFFSET,
  204.       offsetof(ngx_stream_proxy_srv_conf_t, next_upstream_tries),
  205.       NULL },

  206.     { ngx_string("proxy_next_upstream_timeout"),
  207.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  208.       ngx_conf_set_msec_slot,
  209.       NGX_STREAM_SRV_CONF_OFFSET,
  210.       offsetof(ngx_stream_proxy_srv_conf_t, next_upstream_timeout),
  211.       NULL },

  212.     { ngx_string("proxy_protocol"),
  213.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
  214.       ngx_conf_set_flag_slot,
  215.       NGX_STREAM_SRV_CONF_OFFSET,
  216.       offsetof(ngx_stream_proxy_srv_conf_t, proxy_protocol),
  217.       NULL },

  218.     { ngx_string("proxy_half_close"),
  219.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
  220.       ngx_conf_set_flag_slot,
  221.       NGX_STREAM_SRV_CONF_OFFSET,
  222.       offsetof(ngx_stream_proxy_srv_conf_t, half_close),
  223.       NULL },

  224. #if (NGX_STREAM_SSL)

  225.     { ngx_string("proxy_ssl"),
  226.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
  227.       ngx_conf_set_flag_slot,
  228.       NGX_STREAM_SRV_CONF_OFFSET,
  229.       offsetof(ngx_stream_proxy_srv_conf_t, ssl_enable),
  230.       NULL },

  231.     { ngx_string("proxy_ssl_session_reuse"),
  232.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
  233.       ngx_conf_set_flag_slot,
  234.       NGX_STREAM_SRV_CONF_OFFSET,
  235.       offsetof(ngx_stream_proxy_srv_conf_t, ssl_session_reuse),
  236.       NULL },

  237.     { ngx_string("proxy_ssl_protocols"),
  238.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_1MORE,
  239.       ngx_conf_set_bitmask_slot,
  240.       NGX_STREAM_SRV_CONF_OFFSET,
  241.       offsetof(ngx_stream_proxy_srv_conf_t, ssl_protocols),
  242.       &ngx_stream_proxy_ssl_protocols },

  243.     { ngx_string("proxy_ssl_ciphers"),
  244.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  245.       ngx_conf_set_str_slot,
  246.       NGX_STREAM_SRV_CONF_OFFSET,
  247.       offsetof(ngx_stream_proxy_srv_conf_t, ssl_ciphers),
  248.       NULL },

  249.     { ngx_string("proxy_ssl_name"),
  250.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  251.       ngx_stream_set_complex_value_slot,
  252.       NGX_STREAM_SRV_CONF_OFFSET,
  253.       offsetof(ngx_stream_proxy_srv_conf_t, ssl_name),
  254.       NULL },

  255.     { ngx_string("proxy_ssl_server_name"),
  256.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
  257.       ngx_conf_set_flag_slot,
  258.       NGX_STREAM_SRV_CONF_OFFSET,
  259.       offsetof(ngx_stream_proxy_srv_conf_t, ssl_server_name),
  260.       NULL },

  261.     { ngx_string("proxy_ssl_alpn"),
  262.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_1MORE,
  263.       ngx_stream_proxy_ssl_alpn_set_slot,
  264.       NGX_STREAM_SRV_CONF_OFFSET,
  265.       0,
  266.       NULL },

  267.     { ngx_string("proxy_ssl_verify"),
  268.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
  269.       ngx_conf_set_flag_slot,
  270.       NGX_STREAM_SRV_CONF_OFFSET,
  271.       offsetof(ngx_stream_proxy_srv_conf_t, ssl_verify),
  272.       NULL },

  273.     { ngx_string("proxy_ssl_verify_depth"),
  274.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  275.       ngx_conf_set_num_slot,
  276.       NGX_STREAM_SRV_CONF_OFFSET,
  277.       offsetof(ngx_stream_proxy_srv_conf_t, ssl_verify_depth),
  278.       NULL },

  279.     { ngx_string("proxy_ssl_trusted_certificate"),
  280.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  281.       ngx_conf_set_str_slot,
  282.       NGX_STREAM_SRV_CONF_OFFSET,
  283.       offsetof(ngx_stream_proxy_srv_conf_t, ssl_trusted_certificate),
  284.       NULL },

  285.     { ngx_string("proxy_ssl_crl"),
  286.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  287.       ngx_conf_set_str_slot,
  288.       NGX_STREAM_SRV_CONF_OFFSET,
  289.       offsetof(ngx_stream_proxy_srv_conf_t, ssl_crl),
  290.       NULL },

  291.     { ngx_string("proxy_ssl_certificate"),
  292.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  293.       ngx_stream_set_complex_value_zero_slot,
  294.       NGX_STREAM_SRV_CONF_OFFSET,
  295.       offsetof(ngx_stream_proxy_srv_conf_t, ssl_certificate),
  296.       NULL },

  297.     { ngx_string("proxy_ssl_certificate_key"),
  298.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  299.       ngx_stream_set_complex_value_zero_slot,
  300.       NGX_STREAM_SRV_CONF_OFFSET,
  301.       offsetof(ngx_stream_proxy_srv_conf_t, ssl_certificate_key),
  302.       NULL },

  303.     { ngx_string("proxy_ssl_certificate_cache"),
  304.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE123,
  305.       ngx_stream_proxy_ssl_certificate_cache,
  306.       NGX_STREAM_SRV_CONF_OFFSET,
  307.       0,
  308.       NULL },

  309.     { ngx_string("proxy_ssl_password_file"),
  310.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  311.       ngx_stream_proxy_ssl_password_file,
  312.       NGX_STREAM_SRV_CONF_OFFSET,
  313.       0,
  314.       NULL },

  315.     { ngx_string("proxy_ssl_conf_command"),
  316.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE2,
  317.       ngx_conf_set_keyval_slot,
  318.       NGX_STREAM_SRV_CONF_OFFSET,
  319.       offsetof(ngx_stream_proxy_srv_conf_t, ssl_conf_commands),
  320.       &ngx_stream_proxy_ssl_conf_command_post },

  321. #endif

  322.       ngx_null_command
  323. };


  324. static ngx_stream_module_t  ngx_stream_proxy_module_ctx = {
  325.     NULL,                                  /* preconfiguration */
  326.     NULL,                                  /* postconfiguration */

  327.     NULL,                                  /* create main configuration */
  328.     NULL,                                  /* init main configuration */

  329.     ngx_stream_proxy_create_srv_conf,      /* create server configuration */
  330.     ngx_stream_proxy_merge_srv_conf        /* merge server configuration */
  331. };


  332. ngx_module_t  ngx_stream_proxy_module = {
  333.     NGX_MODULE_V1,
  334.     &ngx_stream_proxy_module_ctx,          /* module context */
  335.     ngx_stream_proxy_commands,             /* module directives */
  336.     NGX_STREAM_MODULE,                     /* module type */
  337.     NULL,                                  /* init master */
  338.     NULL,                                  /* init module */
  339.     NULL,                                  /* init process */
  340.     NULL,                                  /* init thread */
  341.     NULL,                                  /* exit thread */
  342.     NULL,                                  /* exit process */
  343.     NULL,                                  /* exit master */
  344.     NGX_MODULE_V1_PADDING
  345. };


  346. static void
  347. ngx_stream_proxy_handler(ngx_stream_session_t *s)
  348. {
  349.     u_char                           *p;
  350.     ngx_str_t                        *host;
  351.     ngx_uint_t                        i;
  352.     ngx_connection_t                 *c;
  353.     ngx_resolver_ctx_t               *ctx, temp;
  354.     ngx_stream_upstream_t            *u;
  355.     ngx_stream_core_srv_conf_t       *cscf;
  356.     ngx_stream_proxy_srv_conf_t      *pscf;
  357.     ngx_stream_upstream_srv_conf_t   *uscf, **uscfp;
  358.     ngx_stream_upstream_main_conf_t  *umcf;

  359.     c = s->connection;

  360.     pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);

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

  363.     u = ngx_pcalloc(c->pool, sizeof(ngx_stream_upstream_t));
  364.     if (u == NULL) {
  365.         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  366.         return;
  367.     }

  368.     s->upstream = u;

  369.     s->log_handler = ngx_stream_proxy_log_error;

  370.     u->requests = 1;

  371.     u->peer.log = c->log;
  372.     u->peer.log_error = NGX_ERROR_ERR;

  373.     if (ngx_stream_proxy_set_local(s, u, pscf->local) != NGX_OK) {
  374.         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  375.         return;
  376.     }

  377.     if (pscf->socket_keepalive) {
  378.         u->peer.so_keepalive = 1;
  379.     }

  380.     u->peer.type = c->type;
  381.     u->start_sec = ngx_time();

  382.     c->write->handler = ngx_stream_proxy_downstream_handler;
  383.     c->read->handler = ngx_stream_proxy_downstream_handler;

  384.     s->upstream_states = ngx_array_create(c->pool, 1,
  385.                                           sizeof(ngx_stream_upstream_state_t));
  386.     if (s->upstream_states == NULL) {
  387.         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  388.         return;
  389.     }

  390.     p = ngx_pnalloc(c->pool, pscf->buffer_size);
  391.     if (p == NULL) {
  392.         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  393.         return;
  394.     }

  395.     u->downstream_buf.start = p;
  396.     u->downstream_buf.end = p + pscf->buffer_size;
  397.     u->downstream_buf.pos = p;
  398.     u->downstream_buf.last = p;

  399.     if (c->read->ready) {
  400.         ngx_post_event(c->read, &ngx_posted_events);
  401.     }

  402.     if (pscf->upstream_value) {
  403.         if (ngx_stream_proxy_eval(s, pscf) != NGX_OK) {
  404.             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  405.             return;
  406.         }
  407.     }

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

  409.         uscf = pscf->upstream;

  410.     } else {

  411. #if (NGX_STREAM_SSL)
  412.         u->ssl_name = u->resolved->host;
  413. #endif

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

  415.         umcf = ngx_stream_get_module_main_conf(s, ngx_stream_upstream_module);

  416.         uscfp = umcf->upstreams.elts;

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

  418.             uscf = uscfp[i];

  419.             if (uscf->host.len == host->len
  420.                 && ((uscf->port == 0 && u->resolved->no_port)
  421.                      || uscf->port == u->resolved->port)
  422.                 && ngx_strncasecmp(uscf->host.data, host->data, host->len) == 0)
  423.             {
  424.                 goto found;
  425.             }
  426.         }

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

  428.             if (u->resolved->port == 0
  429.                 && u->resolved->sockaddr->sa_family != AF_UNIX)
  430.             {
  431.                 ngx_log_error(NGX_LOG_ERR, c->log, 0,
  432.                               "no port in upstream \"%V\"", host);
  433.                 ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  434.                 return;
  435.             }

  436.             if (ngx_stream_upstream_create_round_robin_peer(s, u->resolved)
  437.                 != NGX_OK)
  438.             {
  439.                 ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  440.                 return;
  441.             }

  442.             ngx_stream_proxy_connect(s);

  443.             return;
  444.         }

  445.         if (u->resolved->port == 0) {
  446.             ngx_log_error(NGX_LOG_ERR, c->log, 0,
  447.                           "no port in upstream \"%V\"", host);
  448.             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  449.             return;
  450.         }

  451.         temp.name = *host;

  452.         cscf = ngx_stream_get_module_srv_conf(s, ngx_stream_core_module);

  453.         ctx = ngx_resolve_start(cscf->resolver, &temp);
  454.         if (ctx == NULL) {
  455.             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  456.             return;
  457.         }

  458.         if (ctx == NGX_NO_RESOLVER) {
  459.             ngx_log_error(NGX_LOG_ERR, c->log, 0,
  460.                           "no resolver defined to resolve %V", host);
  461.             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  462.             return;
  463.         }

  464.         ctx->name = *host;
  465.         ctx->handler = ngx_stream_proxy_resolve_handler;
  466.         ctx->data = s;
  467.         ctx->timeout = cscf->resolver_timeout;

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

  469.         if (ngx_resolve_name(ctx) != NGX_OK) {
  470.             u->resolved->ctx = NULL;
  471.             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  472.             return;
  473.         }

  474.         return;
  475.     }

  476. found:

  477.     if (uscf == NULL) {
  478.         ngx_log_error(NGX_LOG_ALERT, c->log, 0, "no upstream configuration");
  479.         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  480.         return;
  481.     }

  482.     u->upstream = uscf;

  483. #if (NGX_STREAM_SSL)
  484.     u->ssl_name = uscf->host;
  485. #endif

  486.     if (uscf->peer.init(s, uscf) != NGX_OK) {
  487.         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  488.         return;
  489.     }

  490.     u->peer.start_time = ngx_current_msec;

  491.     if (pscf->next_upstream_tries
  492.         && u->peer.tries > pscf->next_upstream_tries)
  493.     {
  494.         u->peer.tries = pscf->next_upstream_tries;
  495.     }

  496.     ngx_stream_proxy_connect(s);
  497. }


  498. static ngx_int_t
  499. ngx_stream_proxy_eval(ngx_stream_session_t *s,
  500.     ngx_stream_proxy_srv_conf_t *pscf)
  501. {
  502.     ngx_str_t               host;
  503.     ngx_url_t               url;
  504.     ngx_stream_upstream_t  *u;

  505.     if (ngx_stream_complex_value(s, pscf->upstream_value, &host) != NGX_OK) {
  506.         return NGX_ERROR;
  507.     }

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

  509.     url.url = host;
  510.     url.no_resolve = 1;

  511.     if (ngx_parse_url(s->connection->pool, &url) != NGX_OK) {
  512.         if (url.err) {
  513.             ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
  514.                           "%s in upstream \"%V\"", url.err, &url.url);
  515.         }

  516.         return NGX_ERROR;
  517.     }

  518.     u = s->upstream;

  519.     u->resolved = ngx_pcalloc(s->connection->pool,
  520.                               sizeof(ngx_stream_upstream_resolved_t));
  521.     if (u->resolved == NULL) {
  522.         return NGX_ERROR;
  523.     }

  524.     if (url.addrs) {
  525.         u->resolved->sockaddr = url.addrs[0].sockaddr;
  526.         u->resolved->socklen = url.addrs[0].socklen;
  527.         u->resolved->name = url.addrs[0].name;
  528.         u->resolved->naddrs = 1;
  529.     }

  530.     u->resolved->host = url.host;
  531.     u->resolved->port = url.port;
  532.     u->resolved->no_port = url.no_port;

  533.     return NGX_OK;
  534. }


  535. static ngx_int_t
  536. ngx_stream_proxy_set_local(ngx_stream_session_t *s, ngx_stream_upstream_t *u,
  537.     ngx_stream_upstream_local_t *local)
  538. {
  539.     ngx_int_t    rc;
  540.     ngx_str_t    val;
  541.     ngx_addr_t  *addr;

  542.     if (local == NULL) {
  543.         u->peer.local = NULL;
  544.         return NGX_OK;
  545.     }

  546. #if (NGX_HAVE_TRANSPARENT_PROXY)
  547.     u->peer.transparent = local->transparent;
  548. #endif

  549.     if (local->value == NULL) {
  550.         u->peer.local = local->addr;
  551.         return NGX_OK;
  552.     }

  553.     if (ngx_stream_complex_value(s, local->value, &val) != NGX_OK) {
  554.         return NGX_ERROR;
  555.     }

  556.     if (val.len == 0) {
  557.         u->peer.local = NULL;
  558.         return NGX_OK;
  559.     }

  560.     addr = ngx_palloc(s->connection->pool, sizeof(ngx_addr_t));
  561.     if (addr == NULL) {
  562.         return NGX_ERROR;
  563.     }

  564.     rc = ngx_parse_addr_port(s->connection->pool, addr, val.data, val.len);
  565.     if (rc == NGX_ERROR) {
  566.         return NGX_ERROR;
  567.     }

  568.     if (rc != NGX_OK) {
  569.         ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
  570.                       "invalid local address \"%V\"", &val);
  571.         u->peer.local = NULL;
  572.         return NGX_OK;
  573.     }

  574.     addr->name = val;
  575.     u->peer.local = addr;

  576.     return NGX_OK;
  577. }


  578. static void
  579. ngx_stream_proxy_connect(ngx_stream_session_t *s)
  580. {
  581.     ngx_int_t                     rc;
  582.     ngx_connection_t             *c, *pc;
  583.     ngx_stream_upstream_t        *u;
  584.     ngx_stream_proxy_srv_conf_t  *pscf;

  585.     c = s->connection;

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

  587.     pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);

  588.     u = s->upstream;

  589.     u->connected = 0;
  590.     u->proxy_protocol = pscf->proxy_protocol;

  591.     if (u->state) {
  592.         u->state->response_time = ngx_current_msec - u->start_time;
  593.     }

  594.     u->state = ngx_array_push(s->upstream_states);
  595.     if (u->state == NULL) {
  596.         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  597.         return;
  598.     }

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

  600.     u->start_time = ngx_current_msec;

  601.     u->state->connect_time = (ngx_msec_t) -1;
  602.     u->state->first_byte_time = (ngx_msec_t) -1;
  603.     u->state->response_time = (ngx_msec_t) -1;

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

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

  606.     if (rc == NGX_ERROR) {
  607.         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  608.         return;
  609.     }

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

  611. #if (NGX_STREAM_UPSTREAM_ZONE)
  612.     if (u->upstream && u->upstream->shm_zone
  613.         && (u->upstream->flags & NGX_STREAM_UPSTREAM_MODIFY))
  614.     {
  615.         u->state->peer = ngx_palloc(s->connection->pool,
  616.                                     sizeof(ngx_str_t) + u->peer.name->len);
  617.         if (u->state->peer == NULL) {
  618.             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  619.             return;
  620.         }

  621.         u->state->peer->len = u->peer.name->len;
  622.         u->state->peer->data = (u_char *) (u->state->peer + 1);
  623.         ngx_memcpy(u->state->peer->data, u->peer.name->data, u->peer.name->len);

  624.         u->peer.name = u->state->peer;
  625.     }
  626. #endif

  627.     if (rc == NGX_BUSY) {
  628.         ngx_log_error(NGX_LOG_ERR, c->log, 0, "no live upstreams");
  629.         ngx_stream_proxy_finalize(s, NGX_STREAM_BAD_GATEWAY);
  630.         return;
  631.     }

  632.     if (rc == NGX_DECLINED) {
  633.         ngx_stream_proxy_next_upstream(s);
  634.         return;
  635.     }

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

  637.     pc = u->peer.connection;

  638.     pc->data = s;
  639.     pc->log = c->log;
  640.     pc->pool = c->pool;
  641.     pc->read->log = c->log;
  642.     pc->write->log = c->log;

  643.     if (rc != NGX_AGAIN) {
  644.         ngx_stream_proxy_init_upstream(s);
  645.         return;
  646.     }

  647.     pc->read->handler = ngx_stream_proxy_connect_handler;
  648.     pc->write->handler = ngx_stream_proxy_connect_handler;

  649.     ngx_add_timer(pc->write, pscf->connect_timeout);
  650. }


  651. static void
  652. ngx_stream_proxy_init_upstream(ngx_stream_session_t *s)
  653. {
  654.     u_char                       *p;
  655.     ngx_chain_t                  *cl;
  656.     ngx_connection_t             *c, *pc;
  657.     ngx_log_handler_pt            handler;
  658.     ngx_stream_upstream_t        *u;
  659.     ngx_stream_core_srv_conf_t   *cscf;
  660.     ngx_stream_proxy_srv_conf_t  *pscf;

  661.     u = s->upstream;
  662.     pc = u->peer.connection;

  663.     cscf = ngx_stream_get_module_srv_conf(s, ngx_stream_core_module);

  664.     if (pc->type == SOCK_STREAM
  665.         && cscf->tcp_nodelay
  666.         && ngx_tcp_nodelay(pc) != NGX_OK)
  667.     {
  668.         ngx_stream_proxy_next_upstream(s);
  669.         return;
  670.     }

  671.     pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);

  672. #if (NGX_STREAM_SSL)

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

  674.         if (u->proxy_protocol) {
  675.             if (ngx_stream_proxy_send_proxy_protocol(s) != NGX_OK) {
  676.                 return;
  677.             }

  678.             u->proxy_protocol = 0;
  679.         }

  680.         if (pc->ssl == NULL) {
  681.             ngx_stream_proxy_ssl_init_connection(s);
  682.             return;
  683.         }
  684.     }

  685. #endif

  686.     c = s->connection;

  687.     if (c->log->log_level >= NGX_LOG_INFO) {
  688.         ngx_str_t  str;
  689.         u_char     addr[NGX_SOCKADDR_STRLEN];

  690.         str.len = NGX_SOCKADDR_STRLEN;
  691.         str.data = addr;

  692.         if (ngx_connection_local_sockaddr(pc, &str, 1) == NGX_OK) {
  693.             handler = c->log->handler;
  694.             c->log->handler = NULL;

  695.             ngx_log_error(NGX_LOG_INFO, c->log, 0,
  696.                           "%sproxy %V connected to %V",
  697.                           pc->type == SOCK_DGRAM ? "udp " : "",
  698.                           &str, u->peer.name);

  699.             c->log->handler = handler;
  700.         }
  701.     }

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

  703.     if (u->peer.notify) {
  704.         u->peer.notify(&u->peer, u->peer.data,
  705.                        NGX_STREAM_UPSTREAM_NOTIFY_CONNECT);
  706.     }

  707.     if (u->upstream_buf.start == NULL) {
  708.         p = ngx_pnalloc(c->pool, pscf->buffer_size);
  709.         if (p == NULL) {
  710.             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  711.             return;
  712.         }

  713.         u->upstream_buf.start = p;
  714.         u->upstream_buf.end = p + pscf->buffer_size;
  715.         u->upstream_buf.pos = p;
  716.         u->upstream_buf.last = p;
  717.     }

  718.     if (c->buffer && c->buffer->pos <= c->buffer->last) {
  719.         ngx_log_debug1(NGX_LOG_DEBUG_STREAM, c->log, 0,
  720.                        "stream proxy add preread buffer: %uz",
  721.                        c->buffer->last - c->buffer->pos);

  722.         cl = ngx_chain_get_free_buf(c->pool, &u->free);
  723.         if (cl == NULL) {
  724.             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  725.             return;
  726.         }

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

  728.         cl->buf->tag = (ngx_buf_tag_t) &ngx_stream_proxy_module;
  729.         cl->buf->temporary = (cl->buf->pos == cl->buf->last) ? 0 : 1;
  730.         cl->buf->flush = 1;

  731.         cl->next = u->upstream_out;
  732.         u->upstream_out = cl;
  733.     }

  734.     if (u->proxy_protocol) {
  735.         ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0,
  736.                        "stream proxy add PROXY protocol header");

  737.         cl = ngx_chain_get_free_buf(c->pool, &u->free);
  738.         if (cl == NULL) {
  739.             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  740.             return;
  741.         }

  742.         p = ngx_pnalloc(c->pool, NGX_PROXY_PROTOCOL_V1_MAX_HEADER);
  743.         if (p == NULL) {
  744.             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  745.             return;
  746.         }

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

  748.         p = ngx_proxy_protocol_write(c, p,
  749.                                      p + NGX_PROXY_PROTOCOL_V1_MAX_HEADER);
  750.         if (p == NULL) {
  751.             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  752.             return;
  753.         }

  754.         cl->buf->last = p;
  755.         cl->buf->temporary = 1;
  756.         cl->buf->flush = 0;
  757.         cl->buf->last_buf = 0;
  758.         cl->buf->tag = (ngx_buf_tag_t) &ngx_stream_proxy_module;

  759.         cl->next = u->upstream_out;
  760.         u->upstream_out = cl;

  761.         u->proxy_protocol = 0;
  762.     }

  763.     u->upload_rate = ngx_stream_complex_value_size(s, pscf->upload_rate, 0);
  764.     u->download_rate = ngx_stream_complex_value_size(s, pscf->download_rate, 0);

  765.     u->connected = 1;

  766.     pc->read->handler = ngx_stream_proxy_upstream_handler;
  767.     pc->write->handler = ngx_stream_proxy_upstream_handler;

  768.     if (pc->read->ready) {
  769.         ngx_post_event(pc->read, &ngx_posted_events);
  770.     }

  771.     ngx_stream_proxy_process(s, 0, 1);
  772. }


  773. #if (NGX_STREAM_SSL)

  774. static ngx_int_t
  775. ngx_stream_proxy_send_proxy_protocol(ngx_stream_session_t *s)
  776. {
  777.     u_char                       *p;
  778.     ssize_t                       n, size;
  779.     ngx_connection_t             *c, *pc;
  780.     ngx_stream_upstream_t        *u;
  781.     ngx_stream_proxy_srv_conf_t  *pscf;
  782.     u_char                        buf[NGX_PROXY_PROTOCOL_V1_MAX_HEADER];

  783.     c = s->connection;

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

  786.     p = ngx_proxy_protocol_write(c, buf,
  787.                                  buf + NGX_PROXY_PROTOCOL_V1_MAX_HEADER);
  788.     if (p == NULL) {
  789.         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  790.         return NGX_ERROR;
  791.     }

  792.     u = s->upstream;

  793.     pc = u->peer.connection;

  794.     size = p - buf;

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

  796.     if (n == NGX_AGAIN) {
  797.         if (ngx_handle_write_event(pc->write, 0) != NGX_OK) {
  798.             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  799.             return NGX_ERROR;
  800.         }

  801.         pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);

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

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

  804.         return NGX_AGAIN;
  805.     }

  806.     if (n == NGX_ERROR) {
  807.         ngx_stream_proxy_finalize(s, NGX_STREAM_OK);
  808.         return NGX_ERROR;
  809.     }

  810.     if (n != size) {

  811.         /*
  812.          * PROXY protocol specification:
  813.          * The sender must always ensure that the header
  814.          * is sent at once, so that the transport layer
  815.          * maintains atomicity along the path to the receiver.
  816.          */

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

  819.         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);

  820.         return NGX_ERROR;
  821.     }

  822.     return NGX_OK;
  823. }


  824. static char *
  825. ngx_stream_proxy_ssl_alpn_set_slot(ngx_conf_t *cf, ngx_command_t *cmd,
  826.     void *conf)
  827. {
  828. #ifdef TLSEXT_TYPE_application_layer_protocol_negotiation

  829.     ngx_stream_proxy_srv_conf_t *pscf = conf;

  830.     ngx_str_t                           *value;
  831.     ngx_uint_t                           i;
  832.     ngx_stream_complex_value_t          *cv;
  833.     ngx_stream_compile_complex_value_t   ccv;

  834.     if (pscf->ssl_alpn != NGX_CONF_UNSET_PTR) {
  835.         return "is duplicate";
  836.     }

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

  838.     pscf->ssl_alpn = ngx_array_create(cf->pool, cf->args->nelts - 1,
  839.                                       sizeof(ngx_stream_complex_value_t));
  840.     if (pscf->ssl_alpn == NULL) {
  841.         return NGX_CONF_ERROR;
  842.     }

  843.     cv = ngx_array_push_n(pscf->ssl_alpn, cf->args->nelts - 1);

  844.     for (i = 1; i < cf->args->nelts; i++) {
  845.         ngx_memzero(&ccv, sizeof(ngx_stream_compile_complex_value_t));

  846.         ccv.cf = cf;
  847.         ccv.value = &value[i];
  848.         ccv.complex_value = &cv[i - 1];

  849.         if (ngx_stream_compile_complex_value(&ccv) != NGX_OK) {
  850.             return NGX_CONF_ERROR;
  851.         }

  852.         if (cv[i - 1].lengths == NULL && value[i].len > 255) {
  853.             return "protocol too long";
  854.         }
  855.     }

  856.     return NGX_CONF_OK;

  857. #else
  858.     ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  859.                        "the \"proxy_ssl_alpn\" directive requires "
  860.                        "OpenSSL with ALPN support");

  861.     return NGX_CONF_ERROR;
  862. #endif
  863. }


  864. static char *
  865. ngx_stream_proxy_ssl_certificate_cache(ngx_conf_t *cf, ngx_command_t *cmd,
  866.     void *conf)
  867. {
  868.     ngx_stream_proxy_srv_conf_t *pscf = conf;

  869.     time_t       inactive, valid;
  870.     ngx_str_t   *value, s;
  871.     ngx_int_t    max;
  872.     ngx_uint_t   i;

  873.     if (pscf->ssl_certificate_cache != NGX_CONF_UNSET_PTR) {
  874.         return "is duplicate";
  875.     }

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

  877.     max = 0;
  878.     inactive = 10;
  879.     valid = 60;

  880.     for (i = 1; i < cf->args->nelts; i++) {

  881.         if (ngx_strncmp(value[i].data, "max=", 4) == 0) {

  882.             max = ngx_atoi(value[i].data + 4, value[i].len - 4);
  883.             if (max <= 0) {
  884.                 goto failed;
  885.             }

  886.             continue;
  887.         }

  888.         if (ngx_strncmp(value[i].data, "inactive=", 9) == 0) {

  889.             s.len = value[i].len - 9;
  890.             s.data = value[i].data + 9;

  891.             inactive = ngx_parse_time(&s, 1);
  892.             if (inactive == (time_t) NGX_ERROR) {
  893.                 goto failed;
  894.             }

  895.             continue;
  896.         }

  897.         if (ngx_strncmp(value[i].data, "valid=", 6) == 0) {

  898.             s.len = value[i].len - 6;
  899.             s.data = value[i].data + 6;

  900.             valid = ngx_parse_time(&s, 1);
  901.             if (valid == (time_t) NGX_ERROR) {
  902.                 goto failed;
  903.             }

  904.             continue;
  905.         }

  906.         if (ngx_strcmp(value[i].data, "off") == 0) {

  907.             pscf->ssl_certificate_cache = NULL;

  908.             continue;
  909.         }

  910.     failed:

  911.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  912.                            "invalid parameter \"%V\"", &value[i]);
  913.         return NGX_CONF_ERROR;
  914.     }

  915.     if (pscf->ssl_certificate_cache == NULL) {
  916.         return NGX_CONF_OK;
  917.     }

  918.     if (max == 0) {
  919.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  920.                            "\"proxy_ssl_certificate_cache\" must have "
  921.                            "the \"max\" parameter");
  922.         return NGX_CONF_ERROR;
  923.     }

  924.     pscf->ssl_certificate_cache = ngx_ssl_cache_init(cf->pool, max, valid,
  925.                                                      inactive);
  926.     if (pscf->ssl_certificate_cache == NULL) {
  927.         return NGX_CONF_ERROR;
  928.     }

  929.     return NGX_CONF_OK;
  930. }


  931. static char *
  932. ngx_stream_proxy_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd,
  933.     void *conf)
  934. {
  935.     ngx_stream_proxy_srv_conf_t *pscf = conf;

  936.     ngx_str_t  *value;

  937.     if (pscf->ssl_passwords != NGX_CONF_UNSET_PTR) {
  938.         return "is duplicate";
  939.     }

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

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

  942.     if (pscf->ssl_passwords == NULL) {
  943.         return NGX_CONF_ERROR;
  944.     }

  945.     return NGX_CONF_OK;
  946. }


  947. static char *
  948. ngx_stream_proxy_ssl_conf_command_check(ngx_conf_t *cf, void *post, void *data)
  949. {
  950. #ifndef SSL_CONF_FLAG_FILE
  951.     return "is not supported on this platform";
  952. #else
  953.     return NGX_CONF_OK;
  954. #endif
  955. }


  956. static void
  957. ngx_stream_proxy_ssl_init_connection(ngx_stream_session_t *s)
  958. {
  959.     ngx_int_t                     rc;
  960.     ngx_connection_t             *pc;
  961.     ngx_stream_upstream_t        *u;
  962.     ngx_stream_proxy_srv_conf_t  *pscf;

  963.     u = s->upstream;

  964.     pc = u->peer.connection;

  965.     pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);

  966.     if (ngx_ssl_create_connection(pscf->ssl, pc, NGX_SSL_BUFFER|NGX_SSL_CLIENT)
  967.         != NGX_OK)
  968.     {
  969.         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  970.         return;
  971.     }

  972.     if (pscf->ssl_server_name || pscf->ssl_verify) {
  973.         if (ngx_stream_proxy_ssl_name(s) != NGX_OK) {
  974.             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  975.             return;
  976.         }
  977.     }

  978.     if (pscf->ssl_alpn) {
  979.         if (ngx_stream_proxy_ssl_alpn(s) != NGX_OK) {
  980.             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  981.             return;
  982.         }
  983.     }

  984.     if (pscf->ssl_certificate
  985.         && pscf->ssl_certificate->value.len
  986.         && (pscf->ssl_certificate->lengths
  987.             || pscf->ssl_certificate_key->lengths))
  988.     {
  989.         if (ngx_stream_proxy_ssl_certificate(s) != NGX_OK) {
  990.             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  991.             return;
  992.         }
  993.     }

  994.     if (pscf->ssl_session_reuse) {
  995.         pc->ssl->save_session = ngx_stream_proxy_ssl_save_session;

  996.         if (u->peer.set_session(&u->peer, u->peer.data) != NGX_OK) {
  997.             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  998.             return;
  999.         }
  1000.     }

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

  1002.     rc = ngx_ssl_handshake(pc);

  1003.     if (rc == NGX_AGAIN) {

  1004.         if (!pc->write->timer_set) {
  1005.             ngx_add_timer(pc->write, pscf->connect_timeout);
  1006.         }

  1007.         pc->ssl->handler = ngx_stream_proxy_ssl_handshake;
  1008.         return;
  1009.     }

  1010.     ngx_stream_proxy_ssl_handshake(pc);
  1011. }


  1012. static void
  1013. ngx_stream_proxy_ssl_handshake(ngx_connection_t *pc)
  1014. {
  1015.     long                          rc;
  1016.     ngx_stream_session_t         *s;
  1017.     ngx_stream_upstream_t        *u;
  1018.     ngx_stream_proxy_srv_conf_t  *pscf;

  1019.     s = pc->data;

  1020.     pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);

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

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

  1024.             if (rc != X509_V_OK) {
  1025.                 ngx_log_error(NGX_LOG_ERR, pc->log, 0,
  1026.                               "upstream SSL certificate verify error: (%l:%s)",
  1027.                               rc, X509_verify_cert_error_string(rc));
  1028.                 goto failed;
  1029.             }

  1030.             u = s->upstream;

  1031.             if (ngx_ssl_check_host(pc, &u->ssl_name) != NGX_OK) {
  1032.                 ngx_log_error(NGX_LOG_ERR, pc->log, 0,
  1033.                               "upstream SSL certificate does not match \"%V\"",
  1034.                               &u->ssl_name);
  1035.                 goto failed;
  1036.             }
  1037.         }

  1038.         if (pc->write->timer_set) {
  1039.             ngx_del_timer(pc->write);
  1040.         }

  1041.         ngx_stream_proxy_init_upstream(s);

  1042.         return;
  1043.     }

  1044. failed:

  1045.     ngx_stream_proxy_next_upstream(s);
  1046. }


  1047. static void
  1048. ngx_stream_proxy_ssl_save_session(ngx_connection_t *c)
  1049. {
  1050.     ngx_stream_session_t   *s;
  1051.     ngx_stream_upstream_t  *u;

  1052.     s = c->data;
  1053.     u = s->upstream;

  1054.     u->peer.save_session(&u->peer, u->peer.data);
  1055. }


  1056. static ngx_int_t
  1057. ngx_stream_proxy_ssl_name(ngx_stream_session_t *s)
  1058. {
  1059.     u_char                       *p, *last;
  1060.     ngx_str_t                     name;
  1061.     ngx_stream_upstream_t        *u;
  1062.     ngx_stream_proxy_srv_conf_t  *pscf;

  1063.     pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);

  1064.     u = s->upstream;

  1065.     if (pscf->ssl_name) {
  1066.         if (ngx_stream_complex_value(s, pscf->ssl_name, &name) != NGX_OK) {
  1067.             return NGX_ERROR;
  1068.         }

  1069.     } else {
  1070.         name = u->ssl_name;
  1071.     }

  1072.     if (name.len == 0) {
  1073.         goto done;
  1074.     }

  1075.     /*
  1076.      * ssl name here may contain port, strip it for compatibility
  1077.      * with the http module
  1078.      */

  1079.     p = name.data;
  1080.     last = name.data + name.len;

  1081.     if (*p == '[') {
  1082.         p = ngx_strlchr(p, last, ']');

  1083.         if (p == NULL) {
  1084.             p = name.data;
  1085.         }
  1086.     }

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

  1088.     if (p != NULL) {
  1089.         name.len = p - name.data;
  1090.     }

  1091.     if (!pscf->ssl_server_name) {
  1092.         goto done;
  1093.     }

  1094. #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME

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

  1096.     if (name.len == 0 || *name.data == '[') {
  1097.         goto done;
  1098.     }

  1099.     if (ngx_inet_addr(name.data, name.len) != INADDR_NONE) {
  1100.         goto done;
  1101.     }

  1102.     /*
  1103.      * SSL_set_tlsext_host_name() needs a null-terminated string,
  1104.      * hence we explicitly null-terminate name here
  1105.      */

  1106.     p = ngx_pnalloc(s->connection->pool, name.len + 1);
  1107.     if (p == NULL) {
  1108.         return NGX_ERROR;
  1109.     }

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

  1111.     name.data = p;

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

  1114.     if (SSL_set_tlsext_host_name(u->peer.connection->ssl->connection,
  1115.                                  (char *) name.data)
  1116.         == 0)
  1117.     {
  1118.         ngx_ssl_error(NGX_LOG_ERR, s->connection->log, 0,
  1119.                       "SSL_set_tlsext_host_name(\"%s\") failed", name.data);
  1120.         return NGX_ERROR;
  1121.     }

  1122. #endif

  1123. done:

  1124.     u->ssl_name = name;

  1125.     return NGX_OK;
  1126. }


  1127. static ngx_int_t
  1128. ngx_stream_proxy_ssl_alpn(ngx_stream_session_t *s)
  1129. {
  1130. #ifdef TLSEXT_TYPE_application_layer_protocol_negotiation

  1131.     size_t                        len;
  1132.     u_char                       *p, *buf;
  1133.     ngx_str_t                     proto, *value;
  1134.     ngx_uint_t                    i;
  1135.     ngx_array_t                  *values;
  1136.     ngx_connection_t             *c;
  1137.     ngx_stream_upstream_t        *u;
  1138.     ngx_stream_complex_value_t   *cv;
  1139.     ngx_stream_proxy_srv_conf_t  *pscf;

  1140.     pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);

  1141.     u = s->upstream;
  1142.     c = u->peer.connection;

  1143.     values = NULL;
  1144.     len = 0;

  1145.     cv = pscf->ssl_alpn->elts;

  1146.     for (i = 0; i < pscf->ssl_alpn->nelts; i++) {

  1147.         if (ngx_stream_complex_value(s, &cv[i], &proto) != NGX_OK) {
  1148.             return NGX_ERROR;
  1149.         }

  1150.         if (proto.len == 0 || proto.len > 255) {
  1151.             continue;
  1152.         }

  1153.         if (values == NULL) {
  1154.             values = ngx_array_create(c->pool, 1, sizeof(ngx_str_t));
  1155.             if (values == NULL) {
  1156.                 return NGX_ERROR;
  1157.             }
  1158.         }

  1159.         value = ngx_array_push(values);
  1160.         if (value == NULL) {
  1161.             return NGX_ERROR;
  1162.         }

  1163.         *value = proto;

  1164.         len += 1 + proto.len;
  1165.     }

  1166.     if (len == 0) {
  1167.         return NGX_OK;
  1168.     }

  1169.     buf = ngx_pnalloc(c->pool, len);
  1170.     if (buf == NULL) {
  1171.         return NGX_ERROR;
  1172.     }

  1173.     p = buf;
  1174.     value = values->elts;

  1175.     for (i = 0; i < values->nelts; i++) {

  1176.         ngx_log_debug1(NGX_LOG_DEBUG_STREAM, c->log, 0,
  1177.                        "upstream SSL ALPN: \"%V\"", &value[i]);

  1178.         *p++ = value[i].len;
  1179.         p = ngx_cpymem(p, value[i].data, value[i].len);
  1180.     }

  1181.     if (SSL_set_alpn_protos(c->ssl->connection, buf, p - buf) != 0) {
  1182.         ngx_ssl_error(NGX_LOG_ERR, c->log, 0,
  1183.                       "SSL_set_alpn_protos() failed");
  1184.         return NGX_ERROR;
  1185.     }

  1186. #endif

  1187.     return NGX_OK;
  1188. }


  1189. static ngx_int_t
  1190. ngx_stream_proxy_ssl_certificate(ngx_stream_session_t *s)
  1191. {
  1192.     ngx_str_t                     cert, key;
  1193.     ngx_connection_t             *c;
  1194.     ngx_stream_proxy_srv_conf_t  *pscf;

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

  1196.     pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);

  1197.     if (ngx_stream_complex_value(s, pscf->ssl_certificate, &cert)
  1198.         != NGX_OK)
  1199.     {
  1200.         return NGX_ERROR;
  1201.     }

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

  1204.     if (*cert.data == '\0') {
  1205.         return NGX_OK;
  1206.     }

  1207.     if (ngx_stream_complex_value(s, pscf->ssl_certificate_key, &key)
  1208.         != NGX_OK)
  1209.     {
  1210.         return NGX_ERROR;
  1211.     }

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

  1214.     if (ngx_ssl_connection_certificate(c, c->pool, &cert, &key,
  1215.                                        pscf->ssl_certificate_cache,
  1216.                                        pscf->ssl_passwords)
  1217.         != NGX_OK)
  1218.     {
  1219.         return NGX_ERROR;
  1220.     }

  1221.     return NGX_OK;
  1222. }

  1223. #endif


  1224. static void
  1225. ngx_stream_proxy_downstream_handler(ngx_event_t *ev)
  1226. {
  1227.     ngx_stream_proxy_process_connection(ev, ev->write);
  1228. }


  1229. static void
  1230. ngx_stream_proxy_resolve_handler(ngx_resolver_ctx_t *ctx)
  1231. {
  1232.     ngx_stream_session_t            *s;
  1233.     ngx_stream_upstream_t           *u;
  1234.     ngx_stream_proxy_srv_conf_t     *pscf;
  1235.     ngx_stream_upstream_resolved_t  *ur;

  1236.     s = ctx->data;

  1237.     u = s->upstream;
  1238.     ur = u->resolved;

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

  1241.     if (ctx->state) {
  1242.         ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
  1243.                       "%V could not be resolved (%i: %s)",
  1244.                       &ctx->name, ctx->state,
  1245.                       ngx_resolver_strerror(ctx->state));

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

  1249.     ur->naddrs = ctx->naddrs;
  1250.     ur->addrs = ctx->addrs;

  1251. #if (NGX_DEBUG)
  1252.     {
  1253.     u_char      text[NGX_SOCKADDR_STRLEN];
  1254.     ngx_str_t   addr;
  1255.     ngx_uint_t  i;

  1256.     addr.data = text;

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

  1260.         ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
  1261.                        "name was resolved to %V", &addr);
  1262.     }
  1263.     }
  1264. #endif

  1265.     if (ngx_stream_upstream_create_round_robin_peer(s, ur) != NGX_OK) {
  1266.         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  1267.         return;
  1268.     }

  1269.     ngx_resolve_name_done(ctx);
  1270.     ur->ctx = NULL;

  1271.     u->peer.start_time = ngx_current_msec;

  1272.     pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);

  1273.     if (pscf->next_upstream_tries
  1274.         && u->peer.tries > pscf->next_upstream_tries)
  1275.     {
  1276.         u->peer.tries = pscf->next_upstream_tries;
  1277.     }

  1278.     ngx_stream_proxy_connect(s);
  1279. }


  1280. static void
  1281. ngx_stream_proxy_upstream_handler(ngx_event_t *ev)
  1282. {
  1283.     ngx_stream_proxy_process_connection(ev, !ev->write);
  1284. }


  1285. static void
  1286. ngx_stream_proxy_process_connection(ngx_event_t *ev, ngx_uint_t from_upstream)
  1287. {
  1288.     ngx_connection_t             *c, *pc;
  1289.     ngx_log_handler_pt            handler;
  1290.     ngx_stream_session_t         *s;
  1291.     ngx_stream_upstream_t        *u;
  1292.     ngx_stream_proxy_srv_conf_t  *pscf;

  1293.     c = ev->data;
  1294.     s = c->data;
  1295.     u = s->upstream;

  1296.     if (c->close) {
  1297.         ngx_log_error(NGX_LOG_INFO, c->log, 0, "shutdown timeout");
  1298.         ngx_stream_proxy_finalize(s, NGX_STREAM_OK);
  1299.         return;
  1300.     }

  1301.     c = s->connection;
  1302.     pc = u->peer.connection;

  1303.     pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);

  1304.     if (ev->timedout) {
  1305.         ev->timedout = 0;

  1306.         if (ev->delayed) {
  1307.             ev->delayed = 0;

  1308.             if (!ev->ready) {
  1309.                 if (ngx_handle_read_event(ev, 0) != NGX_OK) {
  1310.                     ngx_stream_proxy_finalize(s,
  1311.                                               NGX_STREAM_INTERNAL_SERVER_ERROR);
  1312.                     return;
  1313.                 }

  1314.                 if (u->connected && !c->read->delayed && !pc->read->delayed) {
  1315.                     ngx_add_timer(c->write, pscf->timeout);
  1316.                 }

  1317.                 return;
  1318.             }

  1319.         } else {
  1320.             if (s->connection->type == SOCK_DGRAM) {

  1321.                 if (pscf->responses == NGX_MAX_INT32_VALUE
  1322.                     || (u->responses >= pscf->responses * u->requests))
  1323.                 {

  1324.                     /*
  1325.                      * successfully terminate timed out UDP session
  1326.                      * if expected number of responses was received
  1327.                      */

  1328.                     handler = c->log->handler;
  1329.                     c->log->handler = NULL;

  1330.                     ngx_log_error(NGX_LOG_INFO, c->log, 0,
  1331.                                   "udp timed out"
  1332.                                   ", packets from/to client:%ui/%ui"
  1333.                                   ", bytes from/to client:%O/%O"
  1334.                                   ", bytes from/to upstream:%O/%O",
  1335.                                   u->requests, u->responses,
  1336.                                   s->received, c->sent, u->received,
  1337.                                   pc ? pc->sent : 0);

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

  1339.                     ngx_stream_proxy_finalize(s, NGX_STREAM_OK);
  1340.                     return;
  1341.                 }

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

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

  1344.                 ngx_stream_proxy_finalize(s, NGX_STREAM_BAD_GATEWAY);

  1345.                 return;
  1346.             }

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

  1348.             ngx_stream_proxy_finalize(s, NGX_STREAM_OK);

  1349.             return;
  1350.         }

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

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

  1354.         if (ngx_handle_read_event(ev, 0) != NGX_OK) {
  1355.             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  1356.         }

  1357.         return;
  1358.     }

  1359.     if (from_upstream && !u->connected) {
  1360.         return;
  1361.     }

  1362.     ngx_stream_proxy_process(s, from_upstream, ev->write);
  1363. }


  1364. static void
  1365. ngx_stream_proxy_connect_handler(ngx_event_t *ev)
  1366. {
  1367.     ngx_connection_t      *c;
  1368.     ngx_stream_session_t  *s;

  1369.     c = ev->data;
  1370.     s = c->data;

  1371.     if (ev->timedout) {
  1372.         ngx_log_error(NGX_LOG_ERR, c->log, NGX_ETIMEDOUT, "upstream timed out");
  1373.         ngx_stream_proxy_next_upstream(s);
  1374.         return;
  1375.     }

  1376.     ngx_del_timer(c->write);

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

  1379.     if (ngx_stream_proxy_test_connect(c) != NGX_OK) {
  1380.         ngx_stream_proxy_next_upstream(s);
  1381.         return;
  1382.     }

  1383.     ngx_stream_proxy_init_upstream(s);
  1384. }


  1385. static ngx_int_t
  1386. ngx_stream_proxy_test_connect(ngx_connection_t *c)
  1387. {
  1388.     int        err;
  1389.     socklen_t  len;

  1390. #if (NGX_HAVE_KQUEUE)

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

  1393.         if (err) {
  1394.             (void) ngx_connection_error(c, err,
  1395.                                     "kevent() reported that connect() failed");
  1396.             return NGX_ERROR;
  1397.         }

  1398.     } else
  1399. #endif
  1400.     {
  1401.         err = 0;
  1402.         len = sizeof(int);

  1403.         /*
  1404.          * BSDs and Linux return 0 and set a pending error in err
  1405.          * Solaris returns -1 and sets errno
  1406.          */

  1407.         if (getsockopt(c->fd, SOL_SOCKET, SO_ERROR, (void *) &err, &len)
  1408.             == -1)
  1409.         {
  1410.             err = ngx_socket_errno;
  1411.         }

  1412.         if (err) {
  1413.             (void) ngx_connection_error(c, err, "connect() failed");
  1414.             return NGX_ERROR;
  1415.         }
  1416.     }

  1417.     return NGX_OK;
  1418. }


  1419. static void
  1420. ngx_stream_proxy_process(ngx_stream_session_t *s, ngx_uint_t from_upstream,
  1421.     ngx_uint_t do_write)
  1422. {
  1423.     char                         *recv_action, *send_action;
  1424.     off_t                        *received, limit;
  1425.     size_t                        size, limit_rate;
  1426.     ssize_t                       n;
  1427.     ngx_buf_t                    *b;
  1428.     ngx_int_t                     rc;
  1429.     ngx_uint_t                    flags, *packets;
  1430.     ngx_msec_t                    delay;
  1431.     ngx_chain_t                  *cl, **ll, **out, **busy;
  1432.     ngx_connection_t             *c, *pc, *src, *dst;
  1433.     ngx_log_handler_pt            handler;
  1434.     ngx_stream_upstream_t        *u;
  1435.     ngx_stream_proxy_srv_conf_t  *pscf;

  1436.     u = s->upstream;

  1437.     c = s->connection;
  1438.     pc = u->connected ? u->peer.connection : NULL;

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

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

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

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

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

  1445.         ngx_stream_proxy_finalize(s, NGX_STREAM_OK);
  1446.         return;
  1447.     }

  1448.     pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);

  1449.     if (from_upstream) {
  1450.         src = pc;
  1451.         dst = c;
  1452.         b = &u->upstream_buf;
  1453.         limit_rate = u->download_rate;
  1454.         received = &u->received;
  1455.         packets = &u->responses;
  1456.         out = &u->downstream_out;
  1457.         busy = &u->downstream_busy;
  1458.         recv_action = "proxying and reading from upstream";
  1459.         send_action = "proxying and sending to client";

  1460.     } else {
  1461.         src = c;
  1462.         dst = pc;
  1463.         b = &u->downstream_buf;
  1464.         limit_rate = u->upload_rate;
  1465.         received = &s->received;
  1466.         packets = &u->requests;
  1467.         out = &u->upstream_out;
  1468.         busy = &u->upstream_busy;
  1469.         recv_action = "proxying and reading from client";
  1470.         send_action = "proxying and sending to upstream";
  1471.     }

  1472.     for ( ;; ) {

  1473.         if (do_write && dst) {

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

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

  1477.                 if (rc == NGX_ERROR) {
  1478.                     ngx_stream_proxy_finalize(s, NGX_STREAM_OK);
  1479.                     return;
  1480.                 }

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

  1483.                 if (*busy == NULL) {
  1484.                     b->pos = b->start;
  1485.                     b->last = b->start;
  1486.                 }
  1487.             }
  1488.         }

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

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

  1491.             if (limit_rate) {
  1492.                 limit = (off_t) limit_rate * (ngx_time() - u->start_sec + 1)
  1493.                         - *received;

  1494.                 if (limit <= 0) {
  1495.                     src->read->delayed = 1;
  1496.                     delay = (ngx_msec_t) (- limit * 1000 / limit_rate + 1);
  1497.                     ngx_add_timer(src->read, delay);
  1498.                     break;
  1499.                 }

  1500.                 if (c->type == SOCK_STREAM && (off_t) size > limit) {
  1501.                     size = (size_t) limit;
  1502.                 }
  1503.             }

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

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

  1506.             if (n == NGX_AGAIN) {
  1507.                 break;
  1508.             }

  1509.             if (n == NGX_ERROR) {
  1510.                 src->read->eof = 1;
  1511.                 n = 0;
  1512.             }

  1513.             if (n >= 0) {
  1514.                 if (limit_rate) {
  1515.                     delay = (ngx_msec_t) (n * 1000 / limit_rate);

  1516.                     if (delay > 0) {
  1517.                         src->read->delayed = 1;
  1518.                         ngx_add_timer(src->read, delay);
  1519.                     }
  1520.                 }

  1521.                 if (from_upstream) {
  1522.                     if (u->state->first_byte_time == (ngx_msec_t) -1) {
  1523.                         u->state->first_byte_time = ngx_current_msec
  1524.                                                     - u->start_time;

  1525.                         if (u->peer.notify) {
  1526.                             u->peer.notify(&u->peer, u->peer.data,
  1527.                                        NGX_STREAM_UPSTREAM_NOTIFY_FIRST_BYTE);
  1528.                         }
  1529.                     }
  1530.                 }

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

  1532.                 cl = ngx_chain_get_free_buf(c->pool, &u->free);
  1533.                 if (cl == NULL) {
  1534.                     ngx_stream_proxy_finalize(s,
  1535.                                               NGX_STREAM_INTERNAL_SERVER_ERROR);
  1536.                     return;
  1537.                 }

  1538.                 *ll = cl;

  1539.                 cl->buf->pos = b->last;
  1540.                 cl->buf->last = b->last + n;
  1541.                 cl->buf->tag = (ngx_buf_tag_t) &ngx_stream_proxy_module;

  1542.                 cl->buf->temporary = (n ? 1 : 0);
  1543.                 cl->buf->last_buf = src->read->eof;
  1544.                 cl->buf->flush = !src->read->eof;

  1545.                 (*packets)++;
  1546.                 *received += n;
  1547.                 b->last += n;
  1548.                 do_write = 1;

  1549.                 continue;
  1550.             }
  1551.         }

  1552.         break;
  1553.     }

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

  1555.     if (ngx_stream_proxy_test_finalize(s, from_upstream) == NGX_OK) {
  1556.         return;
  1557.     }

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

  1559.     if (ngx_handle_read_event(src->read, flags) != NGX_OK) {
  1560.         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  1561.         return;
  1562.     }

  1563.     if (dst) {

  1564.         if (dst->type == SOCK_STREAM && pscf->half_close
  1565.             && src->read->eof && !u->half_closed && !dst->buffered)
  1566.         {
  1567.             if (ngx_shutdown_socket(dst->fd, NGX_WRITE_SHUTDOWN) == -1) {
  1568.                 ngx_connection_error(c, ngx_socket_errno,
  1569.                                      ngx_shutdown_socket_n " failed");

  1570.                 ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  1571.                 return;
  1572.             }

  1573.             u->half_closed = 1;
  1574.             ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
  1575.                            "stream proxy %s socket shutdown",
  1576.                            from_upstream ? "client" : "upstream");
  1577.         }

  1578.         if (ngx_handle_write_event(dst->write, 0) != NGX_OK) {
  1579.             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  1580.             return;
  1581.         }

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

  1584.         } else if (c->write->timer_set) {
  1585.             ngx_del_timer(c->write);
  1586.         }
  1587.     }
  1588. }


  1589. static ngx_int_t
  1590. ngx_stream_proxy_test_finalize(ngx_stream_session_t *s,
  1591.     ngx_uint_t from_upstream)
  1592. {
  1593.     ngx_connection_t             *c, *pc;
  1594.     ngx_log_handler_pt            handler;
  1595.     ngx_stream_upstream_t        *u;
  1596.     ngx_stream_proxy_srv_conf_t  *pscf;

  1597.     pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);

  1598.     c = s->connection;
  1599.     u = s->upstream;
  1600.     pc = u->connected ? u->peer.connection : NULL;

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

  1602.         if (pscf->requests && u->requests < pscf->requests) {
  1603.             return NGX_DECLINED;
  1604.         }

  1605.         if (pscf->requests) {
  1606.             ngx_delete_udp_connection(c);
  1607.         }

  1608.         if (pscf->responses == NGX_MAX_INT32_VALUE
  1609.             || u->responses < pscf->responses * u->requests)
  1610.         {
  1611.             return NGX_DECLINED;
  1612.         }

  1613.         if (pc == NULL || c->buffered || pc->buffered) {
  1614.             return NGX_DECLINED;
  1615.         }

  1616.         handler = c->log->handler;
  1617.         c->log->handler = NULL;

  1618.         ngx_log_error(NGX_LOG_INFO, c->log, 0,
  1619.                       "udp done"
  1620.                       ", packets from/to client:%ui/%ui"
  1621.                       ", bytes from/to client:%O/%O"
  1622.                       ", bytes from/to upstream:%O/%O",
  1623.                       u->requests, u->responses,
  1624.                       s->received, c->sent, u->received, pc ? pc->sent : 0);

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

  1626.         ngx_stream_proxy_finalize(s, NGX_STREAM_OK);

  1627.         return NGX_OK;
  1628.     }

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

  1630.     if (pc == NULL
  1631.         || (!c->read->eof && !pc->read->eof)
  1632.         || (!c->read->eof && c->buffered)
  1633.         || (!pc->read->eof && pc->buffered))
  1634.     {
  1635.         return NGX_DECLINED;
  1636.     }

  1637.     if (pscf->half_close) {
  1638.         /* avoid closing live connections until both read ends get EOF */
  1639.         if (!(c->read->eof && pc->read->eof && !c->buffered && !pc->buffered)) {
  1640.              return NGX_DECLINED;
  1641.         }
  1642.     }

  1643.     handler = c->log->handler;
  1644.     c->log->handler = NULL;

  1645.     ngx_log_error(NGX_LOG_INFO, c->log, 0,
  1646.                   "%s disconnected"
  1647.                   ", bytes from/to client:%O/%O"
  1648.                   ", bytes from/to upstream:%O/%O",
  1649.                   from_upstream ? "upstream" : "client",
  1650.                   s->received, c->sent, u->received, pc ? pc->sent : 0);

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

  1652.     ngx_stream_proxy_finalize(s, NGX_STREAM_OK);

  1653.     return NGX_OK;
  1654. }


  1655. static void
  1656. ngx_stream_proxy_next_upstream(ngx_stream_session_t *s)
  1657. {
  1658.     ngx_msec_t                    timeout;
  1659.     ngx_connection_t             *pc;
  1660.     ngx_stream_upstream_t        *u;
  1661.     ngx_stream_proxy_srv_conf_t  *pscf;

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

  1664.     u = s->upstream;
  1665.     pc = u->peer.connection;

  1666.     if (pc && pc->buffered) {
  1667.         ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
  1668.                       "buffered data on next upstream");
  1669.         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  1670.         return;
  1671.     }

  1672.     if (s->connection->type == SOCK_DGRAM) {
  1673.         u->upstream_out = NULL;
  1674.     }

  1675.     if (u->peer.sockaddr) {
  1676.         u->peer.free(&u->peer, u->peer.data, NGX_PEER_FAILED);
  1677.         u->peer.sockaddr = NULL;
  1678.     }

  1679.     pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);

  1680.     timeout = pscf->next_upstream_timeout;

  1681.     if (u->peer.tries == 0
  1682.         || !pscf->next_upstream
  1683.         || (timeout && ngx_current_msec - u->peer.start_time >= timeout))
  1684.     {
  1685.         ngx_stream_proxy_finalize(s, NGX_STREAM_BAD_GATEWAY);
  1686.         return;
  1687.     }

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

  1691. #if (NGX_STREAM_SSL)
  1692.         if (pc->ssl) {
  1693.             pc->ssl->no_wait_shutdown = 1;
  1694.             pc->ssl->no_send_shutdown = 1;

  1695.             (void) ngx_ssl_shutdown(pc);
  1696.         }
  1697. #endif

  1698.         u->state->bytes_received = u->received;
  1699.         u->state->bytes_sent = pc->sent;

  1700.         ngx_close_connection(pc);
  1701.         u->peer.connection = NULL;
  1702.     }

  1703.     ngx_stream_proxy_connect(s);
  1704. }


  1705. static void
  1706. ngx_stream_proxy_finalize(ngx_stream_session_t *s, ngx_uint_t rc)
  1707. {
  1708.     ngx_uint_t              state;
  1709.     ngx_connection_t       *pc;
  1710.     ngx_stream_upstream_t  *u;

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

  1713.     u = s->upstream;

  1714.     if (u == NULL) {
  1715.         goto noupstream;
  1716.     }

  1717.     if (u->resolved && u->resolved->ctx) {
  1718.         ngx_resolve_name_done(u->resolved->ctx);
  1719.         u->resolved->ctx = NULL;
  1720.     }

  1721.     pc = u->peer.connection;

  1722.     if (u->state) {
  1723.         if (u->state->response_time == (ngx_msec_t) -1) {
  1724.             u->state->response_time = ngx_current_msec - u->start_time;
  1725.         }

  1726.         if (pc) {
  1727.             u->state->bytes_received = u->received;
  1728.             u->state->bytes_sent = pc->sent;
  1729.         }
  1730.     }

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

  1733.         if (pc && pc->type == SOCK_DGRAM
  1734.             && (pc->read->error || pc->write->error))
  1735.         {
  1736.             state = NGX_PEER_FAILED;
  1737.         }

  1738.         u->peer.free(&u->peer, u->peer.data, state);
  1739.         u->peer.sockaddr = NULL;
  1740.     }

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

  1744. #if (NGX_STREAM_SSL)
  1745.         if (pc->ssl) {
  1746.             pc->ssl->no_wait_shutdown = 1;
  1747.             (void) ngx_ssl_shutdown(pc);
  1748.         }
  1749. #endif

  1750.         ngx_close_connection(pc);
  1751.         u->peer.connection = NULL;
  1752.     }

  1753. noupstream:

  1754.     ngx_stream_finalize_session(s, rc);
  1755. }


  1756. static u_char *
  1757. ngx_stream_proxy_log_error(ngx_log_t *log, u_char *buf, size_t len)
  1758. {
  1759.     u_char                 *p;
  1760.     ngx_connection_t       *pc;
  1761.     ngx_stream_session_t   *s;
  1762.     ngx_stream_upstream_t  *u;

  1763.     s = log->data;

  1764.     u = s->upstream;

  1765.     p = buf;

  1766.     if (u->peer.name) {
  1767.         p = ngx_snprintf(p, len, ", upstream: \"%V\"", u->peer.name);
  1768.         len -= p - buf;
  1769.     }

  1770.     pc = u->peer.connection;

  1771.     p = ngx_snprintf(p, len,
  1772.                      ", bytes from/to client:%O/%O"
  1773.                      ", bytes from/to upstream:%O/%O",
  1774.                      s->received, s->connection->sent,
  1775.                      u->received, pc ? pc->sent : 0);

  1776.     return p;
  1777. }


  1778. static void *
  1779. ngx_stream_proxy_create_srv_conf(ngx_conf_t *cf)
  1780. {
  1781.     ngx_stream_proxy_srv_conf_t  *conf;

  1782.     conf = ngx_pcalloc(cf->pool, sizeof(ngx_stream_proxy_srv_conf_t));
  1783.     if (conf == NULL) {
  1784.         return NULL;
  1785.     }

  1786.     /*
  1787.      * set by ngx_pcalloc():
  1788.      *
  1789.      *     conf->ssl_protocols = 0;
  1790.      *     conf->ssl_ciphers = { 0, NULL };
  1791.      *     conf->ssl_trusted_certificate = { 0, NULL };
  1792.      *     conf->ssl_crl = { 0, NULL };
  1793.      *
  1794.      *     conf->ssl = NULL;
  1795.      *     conf->upstream = NULL;
  1796.      *     conf->upstream_value = NULL;
  1797.      */

  1798.     conf->connect_timeout = NGX_CONF_UNSET_MSEC;
  1799.     conf->timeout = NGX_CONF_UNSET_MSEC;
  1800.     conf->next_upstream_timeout = NGX_CONF_UNSET_MSEC;
  1801.     conf->buffer_size = NGX_CONF_UNSET_SIZE;
  1802.     conf->upload_rate = NGX_CONF_UNSET_PTR;
  1803.     conf->download_rate = NGX_CONF_UNSET_PTR;
  1804.     conf->requests = NGX_CONF_UNSET_UINT;
  1805.     conf->responses = NGX_CONF_UNSET_UINT;
  1806.     conf->next_upstream_tries = NGX_CONF_UNSET_UINT;
  1807.     conf->next_upstream = NGX_CONF_UNSET;
  1808.     conf->proxy_protocol = NGX_CONF_UNSET;
  1809.     conf->local = NGX_CONF_UNSET_PTR;
  1810.     conf->socket_keepalive = NGX_CONF_UNSET;
  1811.     conf->half_close = NGX_CONF_UNSET;

  1812. #if (NGX_STREAM_SSL)
  1813.     conf->ssl_enable = NGX_CONF_UNSET;
  1814.     conf->ssl_session_reuse = NGX_CONF_UNSET;
  1815.     conf->ssl_name = NGX_CONF_UNSET_PTR;
  1816.     conf->ssl_server_name = NGX_CONF_UNSET;
  1817.     conf->ssl_alpn = NGX_CONF_UNSET_PTR;
  1818.     conf->ssl_verify = NGX_CONF_UNSET;
  1819.     conf->ssl_verify_depth = NGX_CONF_UNSET_UINT;
  1820.     conf->ssl_certificate = NGX_CONF_UNSET_PTR;
  1821.     conf->ssl_certificate_key = NGX_CONF_UNSET_PTR;
  1822.     conf->ssl_certificate_cache = NGX_CONF_UNSET_PTR;
  1823.     conf->ssl_passwords = NGX_CONF_UNSET_PTR;
  1824.     conf->ssl_conf_commands = NGX_CONF_UNSET_PTR;
  1825. #endif

  1826.     return conf;
  1827. }


  1828. static char *
  1829. ngx_stream_proxy_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
  1830. {
  1831.     ngx_stream_proxy_srv_conf_t *prev = parent;
  1832.     ngx_stream_proxy_srv_conf_t *conf = child;

  1833.     ngx_conf_merge_msec_value(conf->connect_timeout,
  1834.                               prev->connect_timeout, 60000);

  1835.     ngx_conf_merge_msec_value(conf->timeout,
  1836.                               prev->timeout, 10 * 60000);

  1837.     ngx_conf_merge_msec_value(conf->next_upstream_timeout,
  1838.                               prev->next_upstream_timeout, 0);

  1839.     ngx_conf_merge_size_value(conf->buffer_size,
  1840.                               prev->buffer_size, 16384);

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

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

  1843.     ngx_conf_merge_uint_value(conf->requests,
  1844.                               prev->requests, 0);

  1845.     ngx_conf_merge_uint_value(conf->responses,
  1846.                               prev->responses, NGX_MAX_INT32_VALUE);

  1847.     ngx_conf_merge_uint_value(conf->next_upstream_tries,
  1848.                               prev->next_upstream_tries, 0);

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

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

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

  1852.     ngx_conf_merge_value(conf->socket_keepalive,
  1853.                               prev->socket_keepalive, 0);

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

  1855. #if (NGX_STREAM_SSL)

  1856.     if (ngx_stream_proxy_merge_ssl(cf, conf, prev) != NGX_OK) {
  1857.         return NGX_CONF_ERROR;
  1858.     }

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

  1860.     ngx_conf_merge_value(conf->ssl_session_reuse,
  1861.                               prev->ssl_session_reuse, 1);

  1862.     ngx_conf_merge_bitmask_value(conf->ssl_protocols, prev->ssl_protocols,
  1863.                               (NGX_CONF_BITMASK_SET|NGX_SSL_DEFAULT_PROTOCOLS));

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

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

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

  1867.     ngx_conf_merge_ptr_value(conf->ssl_alpn, prev->ssl_alpn, NULL);

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

  1869.     ngx_conf_merge_uint_value(conf->ssl_verify_depth,
  1870.                               prev->ssl_verify_depth, 1);

  1871.     ngx_conf_merge_str_value(conf->ssl_trusted_certificate,
  1872.                               prev->ssl_trusted_certificate, "");

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

  1874.     ngx_conf_merge_ptr_value(conf->ssl_certificate,
  1875.                               prev->ssl_certificate, NULL);

  1876.     ngx_conf_merge_ptr_value(conf->ssl_certificate_key,
  1877.                               prev->ssl_certificate_key, NULL);

  1878.     ngx_conf_merge_ptr_value(conf->ssl_certificate_cache,
  1879.                               prev->ssl_certificate_cache, NULL);

  1880.     if (ngx_stream_proxy_merge_ssl_passwords(cf, conf, prev) != NGX_OK) {
  1881.         return NGX_CONF_ERROR;
  1882.     }

  1883.     ngx_conf_merge_ptr_value(conf->ssl_conf_commands,
  1884.                               prev->ssl_conf_commands, NULL);

  1885.     if (conf->ssl_enable && ngx_stream_proxy_set_ssl(cf, conf) != NGX_OK) {
  1886.         return NGX_CONF_ERROR;
  1887.     }

  1888. #endif

  1889.     return NGX_CONF_OK;
  1890. }


  1891. #if (NGX_STREAM_SSL)

  1892. static ngx_int_t
  1893. ngx_stream_proxy_merge_ssl(ngx_conf_t *cf, ngx_stream_proxy_srv_conf_t *conf,
  1894.     ngx_stream_proxy_srv_conf_t *prev)
  1895. {
  1896.     ngx_uint_t  preserve;

  1897.     if (conf->ssl_protocols == 0
  1898.         && conf->ssl_ciphers.data == NULL
  1899.         && conf->ssl_certificate == NGX_CONF_UNSET_PTR
  1900.         && conf->ssl_certificate_key == NGX_CONF_UNSET_PTR
  1901.         && conf->ssl_passwords == NGX_CONF_UNSET_PTR
  1902.         && conf->ssl_verify == NGX_CONF_UNSET
  1903.         && conf->ssl_verify_depth == NGX_CONF_UNSET_UINT
  1904.         && conf->ssl_trusted_certificate.data == NULL
  1905.         && conf->ssl_crl.data == NULL
  1906.         && conf->ssl_session_reuse == NGX_CONF_UNSET
  1907.         && conf->ssl_conf_commands == NGX_CONF_UNSET_PTR)
  1908.     {
  1909.         if (prev->ssl) {
  1910.             conf->ssl = prev->ssl;
  1911.             return NGX_OK;
  1912.         }

  1913.         preserve = 1;

  1914.     } else {
  1915.         preserve = 0;
  1916.     }

  1917.     conf->ssl = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_t));
  1918.     if (conf->ssl == NULL) {
  1919.         return NGX_ERROR;
  1920.     }

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

  1922.     /*
  1923.      * special handling to preserve conf->ssl
  1924.      * in the "stream" section to inherit it to all servers
  1925.      */

  1926.     if (preserve) {
  1927.         prev->ssl = conf->ssl;
  1928.     }

  1929.     return NGX_OK;
  1930. }


  1931. static ngx_int_t
  1932. ngx_stream_proxy_merge_ssl_passwords(ngx_conf_t *cf,
  1933.     ngx_stream_proxy_srv_conf_t *conf, ngx_stream_proxy_srv_conf_t *prev)
  1934. {
  1935.     ngx_uint_t  preserve;

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

  1937.     if (conf->ssl_certificate == NULL
  1938.         || conf->ssl_certificate->value.len == 0
  1939.         || conf->ssl_certificate_key == NULL)
  1940.     {
  1941.         return NGX_OK;
  1942.     }

  1943.     if (conf->ssl_certificate->lengths == NULL
  1944.         && conf->ssl_certificate_key->lengths == NULL)
  1945.     {
  1946.         if (conf->ssl_passwords && conf->ssl_passwords->pool == NULL) {
  1947.             /* un-preserve empty password list */
  1948.             conf->ssl_passwords = NULL;
  1949.         }

  1950.         return NGX_OK;
  1951.     }

  1952.     if (conf->ssl_passwords && conf->ssl_passwords->pool != cf->temp_pool) {
  1953.         /* already preserved */
  1954.         return NGX_OK;
  1955.     }

  1956.     preserve = (conf->ssl_passwords == prev->ssl_passwords) ? 1 : 0;

  1957.     conf->ssl_passwords = ngx_ssl_preserve_passwords(cf, conf->ssl_passwords);
  1958.     if (conf->ssl_passwords == NULL) {
  1959.         return NGX_ERROR;
  1960.     }

  1961.     /*
  1962.      * special handling to keep a preserved ssl_passwords copy
  1963.      * in the previous configuration to inherit it to all children
  1964.      */

  1965.     if (preserve) {
  1966.         prev->ssl_passwords = conf->ssl_passwords;
  1967.     }

  1968.     return NGX_OK;
  1969. }


  1970. static ngx_int_t
  1971. ngx_stream_proxy_set_ssl(ngx_conf_t *cf, ngx_stream_proxy_srv_conf_t *pscf)
  1972. {
  1973.     ngx_pool_cleanup_t  *cln;

  1974.     if (pscf->ssl->ctx) {
  1975.         return NGX_OK;
  1976.     }

  1977.     if (ngx_ssl_create(pscf->ssl, pscf->ssl_protocols, NULL) != NGX_OK) {
  1978.         return NGX_ERROR;
  1979.     }

  1980.     cln = ngx_pool_cleanup_add(cf->pool, 0);
  1981.     if (cln == NULL) {
  1982.         ngx_ssl_cleanup_ctx(pscf->ssl);
  1983.         return NGX_ERROR;
  1984.     }

  1985.     cln->handler = ngx_ssl_cleanup_ctx;
  1986.     cln->data = pscf->ssl;

  1987.     if (ngx_ssl_ciphers(cf, pscf->ssl, &pscf->ssl_ciphers, 0) != NGX_OK) {
  1988.         return NGX_ERROR;
  1989.     }

  1990.     if (pscf->ssl_certificate
  1991.         && pscf->ssl_certificate->value.len)
  1992.     {
  1993.         if (pscf->ssl_certificate_key == NULL) {
  1994.             ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
  1995.                           "no \"proxy_ssl_certificate_key\" is defined "
  1996.                           "for certificate \"%V\"",
  1997.                           &pscf->ssl_certificate->value);
  1998.             return NGX_ERROR;
  1999.         }

  2000.         if (pscf->ssl_certificate->lengths == NULL
  2001.             && pscf->ssl_certificate_key->lengths == NULL)
  2002.         {
  2003.             if (ngx_ssl_certificate(cf, pscf->ssl,
  2004.                                     &pscf->ssl_certificate->value,
  2005.                                     &pscf->ssl_certificate_key->value,
  2006.                                     pscf->ssl_passwords)
  2007.                 != NGX_OK)
  2008.             {
  2009.                 return NGX_ERROR;
  2010.             }
  2011.         }
  2012.     }

  2013.     if (pscf->ssl_verify) {
  2014.         if (pscf->ssl_trusted_certificate.len == 0) {
  2015.             ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
  2016.                       "no proxy_ssl_trusted_certificate for proxy_ssl_verify");
  2017.             return NGX_ERROR;
  2018.         }

  2019.         if (ngx_ssl_trusted_certificate(cf, pscf->ssl,
  2020.                                         &pscf->ssl_trusted_certificate,
  2021.                                         pscf->ssl_verify_depth)
  2022.             != NGX_OK)
  2023.         {
  2024.             return NGX_ERROR;
  2025.         }

  2026.         if (ngx_ssl_crl(cf, pscf->ssl, &pscf->ssl_crl) != NGX_OK) {
  2027.             return NGX_ERROR;
  2028.         }
  2029.     }

  2030.     if (ngx_ssl_client_session_cache(cf, pscf->ssl, pscf->ssl_session_reuse)
  2031.         != NGX_OK)
  2032.     {
  2033.         return NGX_ERROR;
  2034.     }

  2035.     if (ngx_ssl_conf_commands(cf, pscf->ssl, pscf->ssl_conf_commands)
  2036.         != NGX_OK)
  2037.     {
  2038.         return NGX_ERROR;
  2039.     }

  2040.     return NGX_OK;
  2041. }

  2042. #endif


  2043. static char *
  2044. ngx_stream_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  2045. {
  2046.     ngx_stream_proxy_srv_conf_t *pscf = conf;

  2047.     ngx_url_t                            u;
  2048.     ngx_str_t                           *value, *url;
  2049.     ngx_stream_complex_value_t           cv;
  2050.     ngx_stream_core_srv_conf_t          *cscf;
  2051.     ngx_stream_compile_complex_value_t   ccv;

  2052.     if (pscf->upstream || pscf->upstream_value) {
  2053.         return "is duplicate";
  2054.     }

  2055.     cscf = ngx_stream_conf_get_module_srv_conf(cf, ngx_stream_core_module);

  2056.     cscf->handler = ngx_stream_proxy_handler;

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

  2058.     url = &value[1];

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

  2060.     ccv.cf = cf;
  2061.     ccv.value = url;
  2062.     ccv.complex_value = &cv;

  2063.     if (ngx_stream_compile_complex_value(&ccv) != NGX_OK) {
  2064.         return NGX_CONF_ERROR;
  2065.     }

  2066.     if (cv.lengths) {
  2067.         pscf->upstream_value = ngx_palloc(cf->pool,
  2068.                                           sizeof(ngx_stream_complex_value_t));
  2069.         if (pscf->upstream_value == NULL) {
  2070.             return NGX_CONF_ERROR;
  2071.         }

  2072.         *pscf->upstream_value = cv;

  2073.         return NGX_CONF_OK;
  2074.     }

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

  2076.     u.url = *url;
  2077.     u.no_resolve = 1;

  2078.     pscf->upstream = ngx_stream_upstream_add(cf, &u, 0);
  2079.     if (pscf->upstream == NULL) {
  2080.         return NGX_CONF_ERROR;
  2081.     }

  2082.     return NGX_CONF_OK;
  2083. }


  2084. static char *
  2085. ngx_stream_proxy_bind(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  2086. {
  2087.     ngx_stream_proxy_srv_conf_t *pscf = conf;

  2088.     ngx_int_t                            rc;
  2089.     ngx_str_t                           *value;
  2090.     ngx_stream_complex_value_t           cv;
  2091.     ngx_stream_upstream_local_t         *local;
  2092.     ngx_stream_compile_complex_value_t   ccv;

  2093.     if (pscf->local != NGX_CONF_UNSET_PTR) {
  2094.         return "is duplicate";
  2095.     }

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

  2097.     if (cf->args->nelts == 2 && ngx_strcmp(value[1].data, "off") == 0) {
  2098.         pscf->local = NULL;
  2099.         return NGX_CONF_OK;
  2100.     }

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

  2102.     ccv.cf = cf;
  2103.     ccv.value = &value[1];
  2104.     ccv.complex_value = &cv;

  2105.     if (ngx_stream_compile_complex_value(&ccv) != NGX_OK) {
  2106.         return NGX_CONF_ERROR;
  2107.     }

  2108.     local = ngx_pcalloc(cf->pool, sizeof(ngx_stream_upstream_local_t));
  2109.     if (local == NULL) {
  2110.         return NGX_CONF_ERROR;
  2111.     }

  2112.     pscf->local = local;

  2113.     if (cv.lengths) {
  2114.         local->value = ngx_palloc(cf->pool, sizeof(ngx_stream_complex_value_t));
  2115.         if (local->value == NULL) {
  2116.             return NGX_CONF_ERROR;
  2117.         }

  2118.         *local->value = cv;

  2119.     } else {
  2120.         local->addr = ngx_palloc(cf->pool, sizeof(ngx_addr_t));
  2121.         if (local->addr == NULL) {
  2122.             return NGX_CONF_ERROR;
  2123.         }

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

  2126.         switch (rc) {
  2127.         case NGX_OK:
  2128.             local->addr->name = value[1];
  2129.             break;

  2130.         case NGX_DECLINED:
  2131.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  2132.                                "invalid address \"%V\"", &value[1]);
  2133.             /* fall through */

  2134.         default:
  2135.             return NGX_CONF_ERROR;
  2136.         }
  2137.     }

  2138.     if (cf->args->nelts > 2) {
  2139.         if (ngx_strcmp(value[2].data, "transparent") == 0) {
  2140. #if (NGX_HAVE_TRANSPARENT_PROXY)
  2141.             ngx_core_conf_t  *ccf;

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

  2144.             ccf->transparent = 1;
  2145.             local->transparent = 1;
  2146. #else
  2147.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  2148.                                "transparent proxying is not supported "
  2149.                                "on this platform, ignored");
  2150. #endif
  2151.         } else {
  2152.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  2153.                                "invalid parameter \"%V\"", &value[2]);
  2154.             return NGX_CONF_ERROR;
  2155.         }
  2156.     }

  2157.     return NGX_CONF_OK;
  2158. }