src/stream/ngx_stream_proxy_module.c - nginx-1.31.4 nginx/ @ 8d9666701

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_uint_t                       proxy_protocol;
  27.     ngx_flag_t                       half_close;
  28.     ngx_stream_upstream_local_t     *local;
  29.     ngx_flag_t                       socket_keepalive;
  30.     size_t                           socket_rcvbuf;
  31.     size_t                           socket_sndbuf;

  32. #if (NGX_STREAM_SSL)
  33.     ngx_flag_t                       ssl_enable;
  34.     ngx_flag_t                       ssl_session_reuse;
  35.     ngx_uint_t                       ssl_protocols;
  36.     ngx_str_t                        ssl_ciphers;
  37.     ngx_stream_complex_value_t      *ssl_name;
  38.     ngx_flag_t                       ssl_server_name;
  39.     ngx_array_t                     *ssl_alpn;

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

  49.     ngx_ssl_t                       *ssl;
  50. #endif

  51.     ngx_stream_upstream_srv_conf_t  *upstream;
  52.     ngx_stream_complex_value_t      *upstream_value;
  53. } ngx_stream_proxy_srv_conf_t;


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

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

  83. #if (NGX_STREAM_SSL)

  84. static ngx_int_t ngx_stream_proxy_send_proxy_protocol(ngx_stream_session_t *s);
  85. static char *ngx_stream_proxy_ssl_alpn_set_slot(ngx_conf_t *cf,
  86.     ngx_command_t *cmd, void *conf);
  87. static char *ngx_stream_proxy_ssl_certificate_cache(ngx_conf_t *cf,
  88.     ngx_command_t *cmd, void *conf);
  89. static char *ngx_stream_proxy_ssl_password_file(ngx_conf_t *cf,
  90.     ngx_command_t *cmd, void *conf);
  91. static char *ngx_stream_proxy_ssl_conf_command_check(ngx_conf_t *cf, void *post,
  92.     void *data);
  93. static void ngx_stream_proxy_ssl_init_connection(ngx_stream_session_t *s);
  94. static void ngx_stream_proxy_ssl_handshake(ngx_connection_t *pc);
  95. static void ngx_stream_proxy_ssl_save_session(ngx_connection_t *c);
  96. static ngx_int_t ngx_stream_proxy_ssl_name(ngx_stream_session_t *s);
  97. static ngx_int_t ngx_stream_proxy_ssl_alpn(ngx_stream_session_t *s);
  98. static ngx_int_t ngx_stream_proxy_ssl_certificate(ngx_stream_session_t *s);
  99. static ngx_int_t ngx_stream_proxy_merge_ssl(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_merge_ssl_passwords(ngx_conf_t *cf,
  102.     ngx_stream_proxy_srv_conf_t *conf, ngx_stream_proxy_srv_conf_t *prev);
  103. static ngx_int_t ngx_stream_proxy_set_ssl(ngx_conf_t *cf,
  104.     ngx_stream_proxy_srv_conf_t *pscf);


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

  114. static ngx_conf_post_t  ngx_stream_proxy_ssl_conf_command_post =
  115.     { ngx_stream_proxy_ssl_conf_command_check };

  116. #endif


  117. static ngx_conf_deprecated_t  ngx_conf_deprecated_proxy_downstream_buffer = {
  118.     ngx_conf_deprecated, "proxy_downstream_buffer", "proxy_buffer_size"
  119. };

  120. static ngx_conf_deprecated_t  ngx_conf_deprecated_proxy_upstream_buffer = {
  121.     ngx_conf_deprecated, "proxy_upstream_buffer", "proxy_buffer_size"
  122. };


  123. static ngx_conf_enum_t  ngx_stream_proxy_protocol_versions[] = {
  124.     { ngx_string("off"), 0 },
  125.     { ngx_string("on"), 1 },
  126.     { ngx_string("v2"), 2 },
  127.     { ngx_null_string, 0 }
  128. };


  129. static ngx_command_t  ngx_stream_proxy_commands[] = {

  130.     { ngx_string("proxy_pass"),
  131.       NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  132.       ngx_stream_proxy_pass,
  133.       NGX_STREAM_SRV_CONF_OFFSET,
  134.       0,
  135.       NULL },

  136.     { ngx_string("proxy_bind"),
  137.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE12,
  138.       ngx_stream_proxy_bind,
  139.       NGX_STREAM_SRV_CONF_OFFSET,
  140.       0,
  141.       NULL },

  142.     { ngx_string("proxy_socket_keepalive"),
  143.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
  144.       ngx_conf_set_flag_slot,
  145.       NGX_STREAM_SRV_CONF_OFFSET,
  146.       offsetof(ngx_stream_proxy_srv_conf_t, socket_keepalive),
  147.       NULL },

  148.     { ngx_string("proxy_socket_rcvbuf"),
  149.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  150.       ngx_conf_set_size_slot,
  151.       NGX_STREAM_SRV_CONF_OFFSET,
  152.       offsetof(ngx_stream_proxy_srv_conf_t, socket_rcvbuf),
  153.       NULL },

  154.     { ngx_string("proxy_socket_sndbuf"),
  155.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  156.       ngx_conf_set_size_slot,
  157.       NGX_STREAM_SRV_CONF_OFFSET,
  158.       offsetof(ngx_stream_proxy_srv_conf_t, socket_sndbuf),
  159.       NULL },

  160.     { ngx_string("proxy_connect_timeout"),
  161.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  162.       ngx_conf_set_msec_slot,
  163.       NGX_STREAM_SRV_CONF_OFFSET,
  164.       offsetof(ngx_stream_proxy_srv_conf_t, connect_timeout),
  165.       NULL },

  166.     { ngx_string("proxy_timeout"),
  167.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  168.       ngx_conf_set_msec_slot,
  169.       NGX_STREAM_SRV_CONF_OFFSET,
  170.       offsetof(ngx_stream_proxy_srv_conf_t, timeout),
  171.       NULL },

  172.     { ngx_string("proxy_buffer_size"),
  173.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  174.       ngx_conf_set_size_slot,
  175.       NGX_STREAM_SRV_CONF_OFFSET,
  176.       offsetof(ngx_stream_proxy_srv_conf_t, buffer_size),
  177.       NULL },

  178.     { ngx_string("proxy_downstream_buffer"),
  179.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  180.       ngx_conf_set_size_slot,
  181.       NGX_STREAM_SRV_CONF_OFFSET,
  182.       offsetof(ngx_stream_proxy_srv_conf_t, buffer_size),
  183.       &ngx_conf_deprecated_proxy_downstream_buffer },

  184.     { ngx_string("proxy_upstream_buffer"),
  185.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  186.       ngx_conf_set_size_slot,
  187.       NGX_STREAM_SRV_CONF_OFFSET,
  188.       offsetof(ngx_stream_proxy_srv_conf_t, buffer_size),
  189.       &ngx_conf_deprecated_proxy_upstream_buffer },

  190.     { ngx_string("proxy_upload_rate"),
  191.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  192.       ngx_stream_set_complex_value_size_slot,
  193.       NGX_STREAM_SRV_CONF_OFFSET,
  194.       offsetof(ngx_stream_proxy_srv_conf_t, upload_rate),
  195.       NULL },

  196.     { ngx_string("proxy_download_rate"),
  197.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  198.       ngx_stream_set_complex_value_size_slot,
  199.       NGX_STREAM_SRV_CONF_OFFSET,
  200.       offsetof(ngx_stream_proxy_srv_conf_t, download_rate),
  201.       NULL },

  202.     { ngx_string("proxy_requests"),
  203.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  204.       ngx_conf_set_num_slot,
  205.       NGX_STREAM_SRV_CONF_OFFSET,
  206.       offsetof(ngx_stream_proxy_srv_conf_t, requests),
  207.       NULL },

  208.     { ngx_string("proxy_responses"),
  209.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  210.       ngx_conf_set_num_slot,
  211.       NGX_STREAM_SRV_CONF_OFFSET,
  212.       offsetof(ngx_stream_proxy_srv_conf_t, responses),
  213.       NULL },

  214.     { ngx_string("proxy_next_upstream"),
  215.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
  216.       ngx_conf_set_flag_slot,
  217.       NGX_STREAM_SRV_CONF_OFFSET,
  218.       offsetof(ngx_stream_proxy_srv_conf_t, next_upstream),
  219.       NULL },

  220.     { ngx_string("proxy_next_upstream_tries"),
  221.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  222.       ngx_conf_set_num_slot,
  223.       NGX_STREAM_SRV_CONF_OFFSET,
  224.       offsetof(ngx_stream_proxy_srv_conf_t, next_upstream_tries),
  225.       NULL },

  226.     { ngx_string("proxy_next_upstream_timeout"),
  227.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  228.       ngx_conf_set_msec_slot,
  229.       NGX_STREAM_SRV_CONF_OFFSET,
  230.       offsetof(ngx_stream_proxy_srv_conf_t, next_upstream_timeout),
  231.       NULL },

  232.     { ngx_string("proxy_protocol"),
  233.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  234.       ngx_conf_set_enum_slot,
  235.       NGX_STREAM_SRV_CONF_OFFSET,
  236.       offsetof(ngx_stream_proxy_srv_conf_t, proxy_protocol),
  237.       &ngx_stream_proxy_protocol_versions },

  238.     { ngx_string("proxy_half_close"),
  239.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
  240.       ngx_conf_set_flag_slot,
  241.       NGX_STREAM_SRV_CONF_OFFSET,
  242.       offsetof(ngx_stream_proxy_srv_conf_t, half_close),
  243.       NULL },

  244. #if (NGX_STREAM_SSL)

  245.     { ngx_string("proxy_ssl"),
  246.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
  247.       ngx_conf_set_flag_slot,
  248.       NGX_STREAM_SRV_CONF_OFFSET,
  249.       offsetof(ngx_stream_proxy_srv_conf_t, ssl_enable),
  250.       NULL },

  251.     { ngx_string("proxy_ssl_session_reuse"),
  252.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
  253.       ngx_conf_set_flag_slot,
  254.       NGX_STREAM_SRV_CONF_OFFSET,
  255.       offsetof(ngx_stream_proxy_srv_conf_t, ssl_session_reuse),
  256.       NULL },

  257.     { ngx_string("proxy_ssl_protocols"),
  258.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_1MORE,
  259.       ngx_conf_set_bitmask_slot,
  260.       NGX_STREAM_SRV_CONF_OFFSET,
  261.       offsetof(ngx_stream_proxy_srv_conf_t, ssl_protocols),
  262.       &ngx_stream_proxy_ssl_protocols },

  263.     { ngx_string("proxy_ssl_ciphers"),
  264.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  265.       ngx_conf_set_str_slot,
  266.       NGX_STREAM_SRV_CONF_OFFSET,
  267.       offsetof(ngx_stream_proxy_srv_conf_t, ssl_ciphers),
  268.       NULL },

  269.     { ngx_string("proxy_ssl_name"),
  270.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  271.       ngx_stream_set_complex_value_slot,
  272.       NGX_STREAM_SRV_CONF_OFFSET,
  273.       offsetof(ngx_stream_proxy_srv_conf_t, ssl_name),
  274.       NULL },

  275.     { ngx_string("proxy_ssl_server_name"),
  276.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
  277.       ngx_conf_set_flag_slot,
  278.       NGX_STREAM_SRV_CONF_OFFSET,
  279.       offsetof(ngx_stream_proxy_srv_conf_t, ssl_server_name),
  280.       NULL },

  281.     { ngx_string("proxy_ssl_alpn"),
  282.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_1MORE,
  283.       ngx_stream_proxy_ssl_alpn_set_slot,
  284.       NGX_STREAM_SRV_CONF_OFFSET,
  285.       0,
  286.       NULL },

  287.     { ngx_string("proxy_ssl_verify"),
  288.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
  289.       ngx_conf_set_flag_slot,
  290.       NGX_STREAM_SRV_CONF_OFFSET,
  291.       offsetof(ngx_stream_proxy_srv_conf_t, ssl_verify),
  292.       NULL },

  293.     { ngx_string("proxy_ssl_verify_depth"),
  294.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  295.       ngx_conf_set_num_slot,
  296.       NGX_STREAM_SRV_CONF_OFFSET,
  297.       offsetof(ngx_stream_proxy_srv_conf_t, ssl_verify_depth),
  298.       NULL },

  299.     { ngx_string("proxy_ssl_trusted_certificate"),
  300.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  301.       ngx_conf_set_str_slot,
  302.       NGX_STREAM_SRV_CONF_OFFSET,
  303.       offsetof(ngx_stream_proxy_srv_conf_t, ssl_trusted_certificate),
  304.       NULL },

  305.     { ngx_string("proxy_ssl_crl"),
  306.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  307.       ngx_conf_set_str_slot,
  308.       NGX_STREAM_SRV_CONF_OFFSET,
  309.       offsetof(ngx_stream_proxy_srv_conf_t, ssl_crl),
  310.       NULL },

  311.     { ngx_string("proxy_ssl_certificate"),
  312.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  313.       ngx_stream_set_complex_value_zero_slot,
  314.       NGX_STREAM_SRV_CONF_OFFSET,
  315.       offsetof(ngx_stream_proxy_srv_conf_t, ssl_certificate),
  316.       NULL },

  317.     { ngx_string("proxy_ssl_certificate_key"),
  318.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  319.       ngx_stream_set_complex_value_zero_slot,
  320.       NGX_STREAM_SRV_CONF_OFFSET,
  321.       offsetof(ngx_stream_proxy_srv_conf_t, ssl_certificate_key),
  322.       NULL },

  323.     { ngx_string("proxy_ssl_certificate_cache"),
  324.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE123,
  325.       ngx_stream_proxy_ssl_certificate_cache,
  326.       NGX_STREAM_SRV_CONF_OFFSET,
  327.       0,
  328.       NULL },

  329.     { ngx_string("proxy_ssl_password_file"),
  330.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  331.       ngx_stream_proxy_ssl_password_file,
  332.       NGX_STREAM_SRV_CONF_OFFSET,
  333.       0,
  334.       NULL },

  335.     { ngx_string("proxy_ssl_conf_command"),
  336.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE2,
  337.       ngx_conf_set_keyval_slot,
  338.       NGX_STREAM_SRV_CONF_OFFSET,
  339.       offsetof(ngx_stream_proxy_srv_conf_t, ssl_conf_commands),
  340.       &ngx_stream_proxy_ssl_conf_command_post },

  341. #endif

  342.       ngx_null_command
  343. };


  344. static ngx_stream_module_t  ngx_stream_proxy_module_ctx = {
  345.     NULL,                                  /* preconfiguration */
  346.     NULL,                                  /* postconfiguration */

  347.     NULL,                                  /* create main configuration */
  348.     NULL,                                  /* init main configuration */

  349.     ngx_stream_proxy_create_srv_conf,      /* create server configuration */
  350.     ngx_stream_proxy_merge_srv_conf        /* merge server configuration */
  351. };


  352. ngx_module_t  ngx_stream_proxy_module = {
  353.     NGX_MODULE_V1,
  354.     &ngx_stream_proxy_module_ctx,          /* module context */
  355.     ngx_stream_proxy_commands,             /* module directives */
  356.     NGX_STREAM_MODULE,                     /* module type */
  357.     NULL,                                  /* init master */
  358.     NULL,                                  /* init module */
  359.     NULL,                                  /* init process */
  360.     NULL,                                  /* init thread */
  361.     NULL,                                  /* exit thread */
  362.     NULL,                                  /* exit process */
  363.     NULL,                                  /* exit master */
  364.     NGX_MODULE_V1_PADDING
  365. };


  366. static void
  367. ngx_stream_proxy_handler(ngx_stream_session_t *s)
  368. {
  369.     u_char                           *p;
  370.     ngx_str_t                        *host;
  371.     ngx_uint_t                        i;
  372.     ngx_connection_t                 *c;
  373.     ngx_resolver_ctx_t               *ctx, temp;
  374.     ngx_stream_upstream_t            *u;
  375.     ngx_stream_core_srv_conf_t       *cscf;
  376.     ngx_stream_proxy_srv_conf_t      *pscf;
  377.     ngx_stream_upstream_srv_conf_t   *uscf, **uscfp;
  378.     ngx_stream_upstream_main_conf_t  *umcf;

  379.     c = s->connection;

  380.     pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);

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

  383.     u = ngx_pcalloc(c->pool, sizeof(ngx_stream_upstream_t));
  384.     if (u == NULL) {
  385.         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  386.         return;
  387.     }

  388.     s->upstream = u;

  389.     s->log_handler = ngx_stream_proxy_log_error;

  390.     u->requests = 1;

  391.     u->peer.log = c->log;
  392.     u->peer.log_error = NGX_ERROR_ERR;

  393.     if (ngx_stream_proxy_set_local(s, u, pscf->local) != NGX_OK) {
  394.         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  395.         return;
  396.     }

  397.     if (pscf->socket_keepalive) {
  398.         u->peer.so_keepalive = 1;
  399.     }

  400.     if (pscf->socket_rcvbuf) {
  401.         u->peer.rcvbuf = (int) pscf->socket_rcvbuf;
  402.     }

  403.     if (pscf->socket_sndbuf) {
  404.         u->peer.sndbuf = (int) pscf->socket_sndbuf;
  405.     }

  406.     u->peer.type = c->type;
  407.     u->start_sec = ngx_time();

  408.     c->write->handler = ngx_stream_proxy_downstream_handler;
  409.     c->read->handler = ngx_stream_proxy_downstream_handler;

  410.     s->upstream_states = ngx_array_create(c->pool, 1,
  411.                                           sizeof(ngx_stream_upstream_state_t));
  412.     if (s->upstream_states == NULL) {
  413.         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  414.         return;
  415.     }

  416.     p = ngx_pnalloc(c->pool, pscf->buffer_size);
  417.     if (p == NULL) {
  418.         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  419.         return;
  420.     }

  421.     u->downstream_buf.start = p;
  422.     u->downstream_buf.end = p + pscf->buffer_size;
  423.     u->downstream_buf.pos = p;
  424.     u->downstream_buf.last = p;

  425.     if (c->read->ready) {
  426.         ngx_post_event(c->read, &ngx_posted_events);
  427.     }

  428.     if (pscf->upstream_value) {
  429.         if (ngx_stream_proxy_eval(s, pscf) != NGX_OK) {
  430.             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  431.             return;
  432.         }
  433.     }

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

  435.         uscf = pscf->upstream;

  436.     } else {

  437. #if (NGX_STREAM_SSL)
  438.         u->ssl_name = u->resolved->host;
  439. #endif

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

  441.         umcf = ngx_stream_get_module_main_conf(s, ngx_stream_upstream_module);

  442.         uscfp = umcf->upstreams.elts;

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

  444.             uscf = uscfp[i];

  445.             if (uscf->host.len == host->len
  446.                 && ((uscf->port == 0 && u->resolved->no_port)
  447.                      || uscf->port == u->resolved->port)
  448.                 && ngx_strncasecmp(uscf->host.data, host->data, host->len) == 0)
  449.             {
  450.                 goto found;
  451.             }
  452.         }

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

  454.             if (u->resolved->port == 0
  455.                 && u->resolved->sockaddr->sa_family != AF_UNIX)
  456.             {
  457.                 ngx_log_error(NGX_LOG_ERR, c->log, 0,
  458.                               "no port in upstream \"%V\"", host);
  459.                 ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  460.                 return;
  461.             }

  462.             if (ngx_stream_upstream_create_round_robin_peer(s, u->resolved)
  463.                 != NGX_OK)
  464.             {
  465.                 ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  466.                 return;
  467.             }

  468.             ngx_stream_proxy_connect(s);

  469.             return;
  470.         }

  471.         if (u->resolved->port == 0) {
  472.             ngx_log_error(NGX_LOG_ERR, c->log, 0,
  473.                           "no port in upstream \"%V\"", host);
  474.             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  475.             return;
  476.         }

  477.         temp.name = *host;

  478.         cscf = ngx_stream_get_module_srv_conf(s, ngx_stream_core_module);

  479.         ctx = ngx_resolve_start(cscf->resolver, &temp);
  480.         if (ctx == NULL) {
  481.             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  482.             return;
  483.         }

  484.         if (ctx == NGX_NO_RESOLVER) {
  485.             ngx_log_error(NGX_LOG_ERR, c->log, 0,
  486.                           "no resolver defined to resolve %V", host);
  487.             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  488.             return;
  489.         }

  490.         ctx->name = *host;
  491.         ctx->handler = ngx_stream_proxy_resolve_handler;
  492.         ctx->data = s;
  493.         ctx->timeout = cscf->resolver_timeout;

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

  495.         if (ngx_resolve_name(ctx) != NGX_OK) {
  496.             u->resolved->ctx = NULL;
  497.             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  498.             return;
  499.         }

  500.         return;
  501.     }

  502. found:

  503.     if (uscf == NULL) {
  504.         ngx_log_error(NGX_LOG_ALERT, c->log, 0, "no upstream configuration");
  505.         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  506.         return;
  507.     }

  508.     u->upstream = uscf;

  509. #if (NGX_STREAM_SSL)
  510.     u->ssl_name = uscf->host;
  511. #endif

  512.     if (uscf->peer.init(s, uscf) != NGX_OK) {
  513.         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  514.         return;
  515.     }

  516.     u->peer.start_time = ngx_current_msec;

  517.     if (pscf->next_upstream_tries
  518.         && u->peer.tries > pscf->next_upstream_tries)
  519.     {
  520.         u->peer.tries = pscf->next_upstream_tries;
  521.     }

  522.     ngx_stream_proxy_connect(s);
  523. }


  524. static ngx_int_t
  525. ngx_stream_proxy_eval(ngx_stream_session_t *s,
  526.     ngx_stream_proxy_srv_conf_t *pscf)
  527. {
  528.     ngx_str_t               host;
  529.     ngx_url_t               url;
  530.     ngx_stream_upstream_t  *u;

  531.     if (ngx_stream_complex_value(s, pscf->upstream_value, &host) != NGX_OK) {
  532.         return NGX_ERROR;
  533.     }

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

  535.     url.url = host;
  536.     url.no_resolve = 1;

  537.     if (ngx_parse_url(s->connection->pool, &url) != NGX_OK) {
  538.         if (url.err) {
  539.             ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
  540.                           "%s in upstream \"%V\"", url.err, &url.url);
  541.         }

  542.         return NGX_ERROR;
  543.     }

  544.     u = s->upstream;

  545.     u->resolved = ngx_pcalloc(s->connection->pool,
  546.                               sizeof(ngx_stream_upstream_resolved_t));
  547.     if (u->resolved == NULL) {
  548.         return NGX_ERROR;
  549.     }

  550.     if (url.addrs) {
  551.         u->resolved->sockaddr = url.addrs[0].sockaddr;
  552.         u->resolved->socklen = url.addrs[0].socklen;
  553.         u->resolved->name = url.addrs[0].name;
  554.         u->resolved->naddrs = 1;
  555.     }

  556.     u->resolved->host = url.host;
  557.     u->resolved->port = url.port;
  558.     u->resolved->no_port = url.no_port;

  559.     return NGX_OK;
  560. }


  561. static ngx_int_t
  562. ngx_stream_proxy_set_local(ngx_stream_session_t *s, ngx_stream_upstream_t *u,
  563.     ngx_stream_upstream_local_t *local)
  564. {
  565.     ngx_int_t    rc;
  566.     ngx_str_t    val;
  567.     ngx_addr_t  *addr;

  568.     if (local == NULL) {
  569.         u->peer.local = NULL;
  570.         return NGX_OK;
  571.     }

  572. #if (NGX_HAVE_TRANSPARENT_PROXY)
  573.     u->peer.transparent = local->transparent;
  574. #endif

  575.     if (local->value == NULL) {
  576.         u->peer.local = local->addr;
  577.         return NGX_OK;
  578.     }

  579.     if (ngx_stream_complex_value(s, local->value, &val) != NGX_OK) {
  580.         return NGX_ERROR;
  581.     }

  582.     if (val.len == 0) {
  583.         u->peer.local = NULL;
  584.         return NGX_OK;
  585.     }

  586.     addr = ngx_palloc(s->connection->pool, sizeof(ngx_addr_t));
  587.     if (addr == NULL) {
  588.         return NGX_ERROR;
  589.     }

  590.     rc = ngx_parse_addr_port(s->connection->pool, addr, val.data, val.len);
  591.     if (rc == NGX_ERROR) {
  592.         return NGX_ERROR;
  593.     }

  594.     if (rc != NGX_OK) {
  595.         ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
  596.                       "invalid local address \"%V\"", &val);
  597.         u->peer.local = NULL;
  598.         return NGX_OK;
  599.     }

  600.     addr->name = val;
  601.     u->peer.local = addr;

  602.     return NGX_OK;
  603. }


  604. static void
  605. ngx_stream_proxy_connect(ngx_stream_session_t *s)
  606. {
  607.     ngx_int_t                     rc;
  608.     ngx_connection_t             *c, *pc;
  609.     ngx_stream_upstream_t        *u;
  610.     ngx_stream_proxy_srv_conf_t  *pscf;

  611.     c = s->connection;

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

  613.     pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);

  614.     u = s->upstream;

  615.     u->connected = 0;
  616.     u->proxy_protocol = pscf->proxy_protocol;

  617.     if (u->state) {
  618.         u->state->response_time = ngx_current_msec - u->start_time;
  619.     }

  620.     u->state = ngx_array_push(s->upstream_states);
  621.     if (u->state == NULL) {
  622.         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  623.         return;
  624.     }

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

  626.     u->start_time = ngx_current_msec;

  627.     u->state->connect_time = (ngx_msec_t) -1;
  628.     u->state->first_byte_time = (ngx_msec_t) -1;
  629.     u->state->response_time = (ngx_msec_t) -1;

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

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

  632.     if (rc == NGX_ERROR) {
  633.         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  634.         return;
  635.     }

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

  637. #if (NGX_STREAM_UPSTREAM_ZONE)
  638.     if (u->upstream && u->upstream->shm_zone
  639.         && (u->upstream->flags & NGX_STREAM_UPSTREAM_MODIFY))
  640.     {
  641.         u->state->peer = ngx_palloc(s->connection->pool,
  642.                                     sizeof(ngx_str_t) + u->peer.name->len);
  643.         if (u->state->peer == NULL) {
  644.             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  645.             return;
  646.         }

  647.         u->state->peer->len = u->peer.name->len;
  648.         u->state->peer->data = (u_char *) (u->state->peer + 1);
  649.         ngx_memcpy(u->state->peer->data, u->peer.name->data, u->peer.name->len);

  650.         u->peer.name = u->state->peer;
  651.     }
  652. #endif

  653.     if (rc == NGX_BUSY) {
  654.         ngx_log_error(NGX_LOG_ERR, c->log, 0, "no live upstreams");
  655.         ngx_stream_proxy_finalize(s, NGX_STREAM_BAD_GATEWAY);
  656.         return;
  657.     }

  658.     if (rc == NGX_DECLINED) {
  659.         ngx_stream_proxy_next_upstream(s);
  660.         return;
  661.     }

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

  663.     pc = u->peer.connection;

  664.     pc->data = s;
  665.     pc->log = c->log;
  666.     pc->pool = c->pool;
  667.     pc->read->log = c->log;
  668.     pc->write->log = c->log;

  669.     if (rc != NGX_AGAIN) {
  670.         ngx_stream_proxy_init_upstream(s);
  671.         return;
  672.     }

  673.     pc->read->handler = ngx_stream_proxy_connect_handler;
  674.     pc->write->handler = ngx_stream_proxy_connect_handler;

  675.     ngx_add_timer(pc->write, pscf->connect_timeout);
  676. }


  677. static void
  678. ngx_stream_proxy_init_upstream(ngx_stream_session_t *s)
  679. {
  680.     u_char                       *p;
  681.     size_t                        size;
  682.     ngx_chain_t                  *cl;
  683.     ngx_connection_t             *c, *pc;
  684.     ngx_log_handler_pt            handler;
  685.     ngx_stream_upstream_t        *u;
  686.     ngx_stream_core_srv_conf_t   *cscf;
  687.     ngx_stream_proxy_srv_conf_t  *pscf;
  688.     static u_char                 buf[NGX_PROXY_PROTOCOL_MAX_HEADER];

  689.     u = s->upstream;
  690.     pc = u->peer.connection;

  691.     cscf = ngx_stream_get_module_srv_conf(s, ngx_stream_core_module);

  692.     if (pc->type == SOCK_STREAM
  693.         && cscf->tcp_nodelay
  694.         && ngx_tcp_nodelay(pc) != NGX_OK)
  695.     {
  696.         ngx_stream_proxy_next_upstream(s);
  697.         return;
  698.     }

  699.     pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);

  700. #if (NGX_STREAM_SSL)

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

  702.         if (u->proxy_protocol) {
  703.             if (ngx_stream_proxy_send_proxy_protocol(s) != NGX_OK) {
  704.                 return;
  705.             }

  706.             u->proxy_protocol = 0;
  707.         }

  708.         if (pc->ssl == NULL) {
  709.             ngx_stream_proxy_ssl_init_connection(s);
  710.             return;
  711.         }
  712.     }

  713. #endif

  714.     c = s->connection;

  715.     if (c->log->log_level >= NGX_LOG_INFO) {
  716.         ngx_str_t  str;
  717.         u_char     addr[NGX_SOCKADDR_STRLEN];

  718.         str.len = NGX_SOCKADDR_STRLEN;
  719.         str.data = addr;

  720.         if (ngx_connection_local_sockaddr(pc, &str, 1) == NGX_OK) {
  721.             handler = c->log->handler;
  722.             c->log->handler = NULL;

  723.             ngx_log_error(NGX_LOG_INFO, c->log, 0,
  724.                           "%sproxy %V connected to %V",
  725.                           pc->type == SOCK_DGRAM ? "udp " : "",
  726.                           &str, u->peer.name);

  727.             c->log->handler = handler;
  728.         }
  729.     }

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

  731.     if (u->peer.notify) {
  732.         u->peer.notify(&u->peer, u->peer.data,
  733.                        NGX_STREAM_UPSTREAM_NOTIFY_CONNECT);
  734.     }

  735.     if (u->upstream_buf.start == NULL) {
  736.         p = ngx_pnalloc(c->pool, pscf->buffer_size);
  737.         if (p == NULL) {
  738.             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  739.             return;
  740.         }

  741.         u->upstream_buf.start = p;
  742.         u->upstream_buf.end = p + pscf->buffer_size;
  743.         u->upstream_buf.pos = p;
  744.         u->upstream_buf.last = p;
  745.     }

  746.     if (c->buffer && c->buffer->pos <= c->buffer->last) {
  747.         ngx_log_debug1(NGX_LOG_DEBUG_STREAM, c->log, 0,
  748.                        "stream proxy add preread buffer: %uz",
  749.                        c->buffer->last - c->buffer->pos);

  750.         cl = ngx_chain_get_free_buf(c->pool, &u->free);
  751.         if (cl == NULL) {
  752.             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  753.             return;
  754.         }

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

  756.         cl->buf->tag = (ngx_buf_tag_t) &ngx_stream_proxy_module;
  757.         cl->buf->temporary = (cl->buf->pos == cl->buf->last) ? 0 : 1;
  758.         cl->buf->flush = 1;

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

  762.     if (u->proxy_protocol) {
  763.         ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0,
  764.                        "stream proxy add PROXY protocol header");

  765.         if (u->proxy_protocol == 2) {
  766.             p = ngx_proxy_protocol_v2_write(c, buf, buf + sizeof(buf), NULL);

  767.         } else {
  768.             p = ngx_proxy_protocol_write(c, buf, buf + sizeof(buf));
  769.         }

  770.         if (p == NULL) {
  771.             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  772.             return;
  773.         }

  774.         size = p - buf;

  775.         p = ngx_pnalloc(c->pool, size);
  776.         if (p == NULL) {
  777.             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  778.             return;
  779.         }

  780.         ngx_memcpy(p, buf, size);

  781.         cl = ngx_chain_get_free_buf(c->pool, &u->free);
  782.         if (cl == NULL) {
  783.             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  784.             return;
  785.         }

  786.         cl->buf->pos = p;
  787.         cl->buf->last = p + size;

  788.         cl->buf->temporary = 1;
  789.         cl->buf->flush = 0;
  790.         cl->buf->last_buf = 0;
  791.         cl->buf->tag = (ngx_buf_tag_t) &ngx_stream_proxy_module;

  792.         cl->next = u->upstream_out;
  793.         u->upstream_out = cl;

  794.         u->proxy_protocol = 0;
  795.     }

  796.     u->upload_rate = ngx_stream_complex_value_size(s, pscf->upload_rate, 0);
  797.     u->download_rate = ngx_stream_complex_value_size(s, pscf->download_rate, 0);

  798.     u->connected = 1;

  799.     pc->read->handler = ngx_stream_proxy_upstream_handler;
  800.     pc->write->handler = ngx_stream_proxy_upstream_handler;

  801.     if (pc->read->ready) {
  802.         ngx_post_event(pc->read, &ngx_posted_events);
  803.     }

  804.     ngx_stream_proxy_process(s, 0, 1);
  805. }


  806. #if (NGX_STREAM_SSL)

  807. static ngx_int_t
  808. ngx_stream_proxy_send_proxy_protocol(ngx_stream_session_t *s)
  809. {
  810.     u_char                       *p;
  811.     size_t                        size;
  812.     ssize_t                       n;
  813.     ngx_connection_t             *c, *pc;
  814.     ngx_stream_upstream_t        *u;
  815.     ngx_stream_proxy_srv_conf_t  *pscf;
  816.     static u_char                 buf[NGX_PROXY_PROTOCOL_MAX_HEADER];

  817.     c = s->connection;

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

  820.     u = s->upstream;

  821.     if (u->proxy_protocol == 2) {
  822.         p = ngx_proxy_protocol_v2_write(c, buf, buf + sizeof(buf), NULL);

  823.     } else {
  824.         p = ngx_proxy_protocol_write(c, buf, buf + sizeof(buf));
  825.     }

  826.     if (p == NULL) {
  827.         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  828.         return NGX_ERROR;
  829.     }

  830.     pc = u->peer.connection;

  831.     size = p - buf;

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

  833.     if (n == NGX_AGAIN) {
  834.         if (ngx_handle_write_event(pc->write, 0) != NGX_OK) {
  835.             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  836.             return NGX_ERROR;
  837.         }

  838.         pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);

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

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

  841.         return NGX_AGAIN;
  842.     }

  843.     if (n == NGX_ERROR) {
  844.         ngx_stream_proxy_finalize(s, NGX_STREAM_OK);
  845.         return NGX_ERROR;
  846.     }

  847.     if (n != (ssize_t) size) {

  848.         /*
  849.          * PROXY protocol specification:
  850.          * The sender must always ensure that the header
  851.          * is sent at once, so that the transport layer
  852.          * maintains atomicity along the path to the receiver.
  853.          */

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

  856.         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);

  857.         return NGX_ERROR;
  858.     }

  859.     return NGX_OK;
  860. }


  861. static char *
  862. ngx_stream_proxy_ssl_alpn_set_slot(ngx_conf_t *cf, ngx_command_t *cmd,
  863.     void *conf)
  864. {
  865. #ifdef TLSEXT_TYPE_application_layer_protocol_negotiation

  866.     ngx_stream_proxy_srv_conf_t *pscf = conf;

  867.     ngx_str_t                           *value;
  868.     ngx_uint_t                           i;
  869.     ngx_stream_complex_value_t          *cv;
  870.     ngx_stream_compile_complex_value_t   ccv;

  871.     if (pscf->ssl_alpn != NGX_CONF_UNSET_PTR) {
  872.         return "is duplicate";
  873.     }

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

  875.     pscf->ssl_alpn = ngx_array_create(cf->pool, cf->args->nelts - 1,
  876.                                       sizeof(ngx_stream_complex_value_t));
  877.     if (pscf->ssl_alpn == NULL) {
  878.         return NGX_CONF_ERROR;
  879.     }

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

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

  883.         ccv.cf = cf;
  884.         ccv.value = &value[i];
  885.         ccv.complex_value = &cv[i - 1];

  886.         if (ngx_stream_compile_complex_value(&ccv) != NGX_OK) {
  887.             return NGX_CONF_ERROR;
  888.         }

  889.         if (cv[i - 1].lengths == NULL && value[i].len > 255) {
  890.             return "protocol too long";
  891.         }
  892.     }

  893.     return NGX_CONF_OK;

  894. #else
  895.     ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  896.                        "the \"proxy_ssl_alpn\" directive requires "
  897.                        "OpenSSL with ALPN support");

  898.     return NGX_CONF_ERROR;
  899. #endif
  900. }


  901. static char *
  902. ngx_stream_proxy_ssl_certificate_cache(ngx_conf_t *cf, ngx_command_t *cmd,
  903.     void *conf)
  904. {
  905.     ngx_stream_proxy_srv_conf_t *pscf = conf;

  906.     time_t       inactive, valid;
  907.     ngx_str_t   *value, s;
  908.     ngx_int_t    max;
  909.     ngx_uint_t   i;

  910.     if (pscf->ssl_certificate_cache != NGX_CONF_UNSET_PTR) {
  911.         return "is duplicate";
  912.     }

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

  914.     max = 0;
  915.     inactive = 10;
  916.     valid = 60;

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

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

  919.             max = ngx_atoi(value[i].data + 4, value[i].len - 4);
  920.             if (max <= 0) {
  921.                 goto failed;
  922.             }

  923.             continue;
  924.         }

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

  926.             s.len = value[i].len - 9;
  927.             s.data = value[i].data + 9;

  928.             inactive = ngx_parse_time(&s, 1);
  929.             if (inactive == (time_t) NGX_ERROR) {
  930.                 goto failed;
  931.             }

  932.             continue;
  933.         }

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

  935.             s.len = value[i].len - 6;
  936.             s.data = value[i].data + 6;

  937.             valid = ngx_parse_time(&s, 1);
  938.             if (valid == (time_t) NGX_ERROR) {
  939.                 goto failed;
  940.             }

  941.             continue;
  942.         }

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

  944.             pscf->ssl_certificate_cache = NULL;

  945.             continue;
  946.         }

  947.     failed:

  948.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  949.                            "invalid parameter \"%V\"", &value[i]);
  950.         return NGX_CONF_ERROR;
  951.     }

  952.     if (pscf->ssl_certificate_cache == NULL) {
  953.         return NGX_CONF_OK;
  954.     }

  955.     if (max == 0) {
  956.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  957.                            "\"proxy_ssl_certificate_cache\" must have "
  958.                            "the \"max\" parameter");
  959.         return NGX_CONF_ERROR;
  960.     }

  961.     pscf->ssl_certificate_cache = ngx_ssl_cache_init(cf->pool, max, valid,
  962.                                                      inactive);
  963.     if (pscf->ssl_certificate_cache == NULL) {
  964.         return NGX_CONF_ERROR;
  965.     }

  966.     return NGX_CONF_OK;
  967. }


  968. static char *
  969. ngx_stream_proxy_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd,
  970.     void *conf)
  971. {
  972.     ngx_stream_proxy_srv_conf_t *pscf = conf;

  973.     ngx_str_t  *value;

  974.     if (pscf->ssl_passwords != NGX_CONF_UNSET_PTR) {
  975.         return "is duplicate";
  976.     }

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

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

  979.     if (pscf->ssl_passwords == NULL) {
  980.         return NGX_CONF_ERROR;
  981.     }

  982.     return NGX_CONF_OK;
  983. }


  984. static char *
  985. ngx_stream_proxy_ssl_conf_command_check(ngx_conf_t *cf, void *post, void *data)
  986. {
  987. #ifndef SSL_CONF_FLAG_FILE
  988.     return "is not supported on this platform";
  989. #else
  990.     return NGX_CONF_OK;
  991. #endif
  992. }


  993. static void
  994. ngx_stream_proxy_ssl_init_connection(ngx_stream_session_t *s)
  995. {
  996.     ngx_int_t                     rc;
  997.     ngx_connection_t             *pc;
  998.     ngx_stream_upstream_t        *u;
  999.     ngx_stream_proxy_srv_conf_t  *pscf;

  1000.     u = s->upstream;

  1001.     pc = u->peer.connection;

  1002.     pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);

  1003.     if (ngx_ssl_create_connection(pscf->ssl, pc, NGX_SSL_BUFFER|NGX_SSL_CLIENT)
  1004.         != NGX_OK)
  1005.     {
  1006.         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  1007.         return;
  1008.     }

  1009.     if (pscf->ssl_server_name || pscf->ssl_verify) {
  1010.         if (ngx_stream_proxy_ssl_name(s) != NGX_OK) {
  1011.             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  1012.             return;
  1013.         }
  1014.     }

  1015.     if (pscf->ssl_alpn) {
  1016.         if (ngx_stream_proxy_ssl_alpn(s) != NGX_OK) {
  1017.             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  1018.             return;
  1019.         }
  1020.     }

  1021.     if (pscf->ssl_certificate
  1022.         && pscf->ssl_certificate->value.len
  1023.         && (pscf->ssl_certificate->lengths
  1024.             || pscf->ssl_certificate_key->lengths))
  1025.     {
  1026.         if (ngx_stream_proxy_ssl_certificate(s) != NGX_OK) {
  1027.             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  1028.             return;
  1029.         }
  1030.     }

  1031.     if (pscf->ssl_session_reuse) {
  1032.         pc->ssl->save_session = ngx_stream_proxy_ssl_save_session;

  1033.         if (u->peer.set_session(&u->peer, u->peer.data) != NGX_OK) {
  1034.             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  1035.             return;
  1036.         }
  1037.     }

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

  1039.     rc = ngx_ssl_handshake(pc);

  1040.     if (rc == NGX_AGAIN) {

  1041.         if (!pc->write->timer_set) {
  1042.             ngx_add_timer(pc->write, pscf->connect_timeout);
  1043.         }

  1044.         pc->ssl->handler = ngx_stream_proxy_ssl_handshake;
  1045.         return;
  1046.     }

  1047.     ngx_stream_proxy_ssl_handshake(pc);
  1048. }


  1049. static void
  1050. ngx_stream_proxy_ssl_handshake(ngx_connection_t *pc)
  1051. {
  1052.     long                          rc;
  1053.     ngx_stream_session_t         *s;
  1054.     ngx_stream_upstream_t        *u;
  1055.     ngx_stream_proxy_srv_conf_t  *pscf;

  1056.     s = pc->data;

  1057.     pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);

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

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

  1061.             if (rc != X509_V_OK) {
  1062.                 ngx_log_error(NGX_LOG_ERR, pc->log, 0,
  1063.                               "upstream SSL certificate verify error: (%l:%s)",
  1064.                               rc, X509_verify_cert_error_string(rc));
  1065.                 goto failed;
  1066.             }

  1067.             u = s->upstream;

  1068.             if (ngx_ssl_check_host(pc, &u->ssl_name) != NGX_OK) {
  1069.                 ngx_log_error(NGX_LOG_ERR, pc->log, 0,
  1070.                               "upstream SSL certificate does not match \"%V\"",
  1071.                               &u->ssl_name);
  1072.                 goto failed;
  1073.             }
  1074.         }

  1075.         if (pc->write->timer_set) {
  1076.             ngx_del_timer(pc->write);
  1077.         }

  1078.         ngx_stream_proxy_init_upstream(s);

  1079.         return;
  1080.     }

  1081. failed:

  1082.     ngx_stream_proxy_next_upstream(s);
  1083. }


  1084. static void
  1085. ngx_stream_proxy_ssl_save_session(ngx_connection_t *c)
  1086. {
  1087.     ngx_stream_session_t   *s;
  1088.     ngx_stream_upstream_t  *u;

  1089.     s = c->data;
  1090.     u = s->upstream;

  1091.     u->peer.save_session(&u->peer, u->peer.data);
  1092. }


  1093. static ngx_int_t
  1094. ngx_stream_proxy_ssl_name(ngx_stream_session_t *s)
  1095. {
  1096.     u_char                       *p, *last;
  1097.     ngx_str_t                     name;
  1098.     ngx_stream_upstream_t        *u;
  1099.     ngx_stream_proxy_srv_conf_t  *pscf;

  1100.     pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);

  1101.     u = s->upstream;

  1102.     if (pscf->ssl_name) {
  1103.         if (ngx_stream_complex_value(s, pscf->ssl_name, &name) != NGX_OK) {
  1104.             return NGX_ERROR;
  1105.         }

  1106.     } else {
  1107.         name = u->ssl_name;
  1108.     }

  1109.     if (name.len == 0) {
  1110.         goto done;
  1111.     }

  1112.     /*
  1113.      * ssl name here may contain port, strip it for compatibility
  1114.      * with the http module
  1115.      */

  1116.     p = name.data;
  1117.     last = name.data + name.len;

  1118.     if (*p == '[') {
  1119.         p = ngx_strlchr(p, last, ']');

  1120.         if (p == NULL) {
  1121.             p = name.data;
  1122.         }
  1123.     }

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

  1125.     if (p != NULL) {
  1126.         name.len = p - name.data;
  1127.     }

  1128.     if (!pscf->ssl_server_name) {
  1129.         goto done;
  1130.     }

  1131. #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME

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

  1133.     if (name.len == 0 || *name.data == '[') {
  1134.         goto done;
  1135.     }

  1136.     if (ngx_inet_addr(name.data, name.len) != INADDR_NONE) {
  1137.         goto done;
  1138.     }

  1139.     /*
  1140.      * SSL_set_tlsext_host_name() needs a null-terminated string,
  1141.      * hence we explicitly null-terminate name here
  1142.      */

  1143.     p = ngx_pnalloc(s->connection->pool, name.len + 1);
  1144.     if (p == NULL) {
  1145.         return NGX_ERROR;
  1146.     }

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

  1148.     name.data = p;

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

  1151.     if (SSL_set_tlsext_host_name(u->peer.connection->ssl->connection,
  1152.                                  (char *) name.data)
  1153.         == 0)
  1154.     {
  1155.         ngx_ssl_error(NGX_LOG_ERR, s->connection->log, 0,
  1156.                       "SSL_set_tlsext_host_name(\"%s\") failed", name.data);
  1157.         return NGX_ERROR;
  1158.     }

  1159. #endif

  1160. done:

  1161.     u->ssl_name = name;

  1162.     return NGX_OK;
  1163. }


  1164. static ngx_int_t
  1165. ngx_stream_proxy_ssl_alpn(ngx_stream_session_t *s)
  1166. {
  1167. #ifdef TLSEXT_TYPE_application_layer_protocol_negotiation

  1168.     size_t                        len;
  1169.     u_char                       *p, *buf;
  1170.     ngx_str_t                     proto, *value;
  1171.     ngx_uint_t                    i;
  1172.     ngx_array_t                  *values;
  1173.     ngx_connection_t             *c;
  1174.     ngx_stream_upstream_t        *u;
  1175.     ngx_stream_complex_value_t   *cv;
  1176.     ngx_stream_proxy_srv_conf_t  *pscf;

  1177.     pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);

  1178.     u = s->upstream;
  1179.     c = u->peer.connection;

  1180.     values = NULL;
  1181.     len = 0;

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

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

  1184.         if (ngx_stream_complex_value(s, &cv[i], &proto) != NGX_OK) {
  1185.             return NGX_ERROR;
  1186.         }

  1187.         if (proto.len == 0 || proto.len > 255) {
  1188.             continue;
  1189.         }

  1190.         if (values == NULL) {
  1191.             values = ngx_array_create(c->pool, 1, sizeof(ngx_str_t));
  1192.             if (values == NULL) {
  1193.                 return NGX_ERROR;
  1194.             }
  1195.         }

  1196.         value = ngx_array_push(values);
  1197.         if (value == NULL) {
  1198.             return NGX_ERROR;
  1199.         }

  1200.         *value = proto;

  1201.         len += 1 + proto.len;
  1202.     }

  1203.     if (len == 0) {
  1204.         return NGX_OK;
  1205.     }

  1206.     buf = ngx_pnalloc(c->pool, len);
  1207.     if (buf == NULL) {
  1208.         return NGX_ERROR;
  1209.     }

  1210.     p = buf;
  1211.     value = values->elts;

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

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

  1215.         *p++ = value[i].len;
  1216.         p = ngx_cpymem(p, value[i].data, value[i].len);
  1217.     }

  1218.     if (SSL_set_alpn_protos(c->ssl->connection, buf, p - buf) != 0) {
  1219.         ngx_ssl_error(NGX_LOG_ERR, c->log, 0,
  1220.                       "SSL_set_alpn_protos() failed");
  1221.         return NGX_ERROR;
  1222.     }

  1223. #endif

  1224.     return NGX_OK;
  1225. }


  1226. static ngx_int_t
  1227. ngx_stream_proxy_ssl_certificate(ngx_stream_session_t *s)
  1228. {
  1229.     ngx_str_t                     cert, key;
  1230.     ngx_connection_t             *c;
  1231.     ngx_stream_proxy_srv_conf_t  *pscf;

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

  1233.     pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);

  1234.     if (ngx_stream_complex_value(s, pscf->ssl_certificate, &cert)
  1235.         != NGX_OK)
  1236.     {
  1237.         return NGX_ERROR;
  1238.     }

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

  1241.     if (*cert.data == '\0') {
  1242.         return NGX_OK;
  1243.     }

  1244.     if (ngx_stream_complex_value(s, pscf->ssl_certificate_key, &key)
  1245.         != NGX_OK)
  1246.     {
  1247.         return NGX_ERROR;
  1248.     }

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

  1251.     if (ngx_ssl_connection_certificate(c, c->pool, &cert, &key,
  1252.                                        pscf->ssl_certificate_cache,
  1253.                                        pscf->ssl_passwords)
  1254.         != NGX_OK)
  1255.     {
  1256.         return NGX_ERROR;
  1257.     }

  1258.     return NGX_OK;
  1259. }

  1260. #endif


  1261. static void
  1262. ngx_stream_proxy_downstream_handler(ngx_event_t *ev)
  1263. {
  1264.     ngx_stream_proxy_process_connection(ev, ev->write);
  1265. }


  1266. static void
  1267. ngx_stream_proxy_resolve_handler(ngx_resolver_ctx_t *ctx)
  1268. {
  1269.     ngx_stream_session_t            *s;
  1270.     ngx_stream_upstream_t           *u;
  1271.     ngx_stream_proxy_srv_conf_t     *pscf;
  1272.     ngx_stream_upstream_resolved_t  *ur;

  1273.     s = ctx->data;

  1274.     u = s->upstream;
  1275.     ur = u->resolved;

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

  1278.     if (ctx->state) {
  1279.         ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
  1280.                       "%V could not be resolved (%i: %s)",
  1281.                       &ctx->name, ctx->state,
  1282.                       ngx_resolver_strerror(ctx->state));

  1283.         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  1284.         return;
  1285.     }

  1286.     ur->naddrs = ctx->naddrs;
  1287.     ur->addrs = ctx->addrs;

  1288. #if (NGX_DEBUG)
  1289.     {
  1290.     u_char      text[NGX_SOCKADDR_STRLEN];
  1291.     ngx_str_t   addr;
  1292.     ngx_uint_t  i;

  1293.     addr.data = text;

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

  1297.         ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
  1298.                        "name was resolved to %V", &addr);
  1299.     }
  1300.     }
  1301. #endif

  1302.     if (ngx_stream_upstream_create_round_robin_peer(s, ur) != NGX_OK) {
  1303.         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  1304.         return;
  1305.     }

  1306.     ngx_resolve_name_done(ctx);
  1307.     ur->ctx = NULL;

  1308.     u->peer.start_time = ngx_current_msec;

  1309.     pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);

  1310.     if (pscf->next_upstream_tries
  1311.         && u->peer.tries > pscf->next_upstream_tries)
  1312.     {
  1313.         u->peer.tries = pscf->next_upstream_tries;
  1314.     }

  1315.     ngx_stream_proxy_connect(s);
  1316. }


  1317. static void
  1318. ngx_stream_proxy_upstream_handler(ngx_event_t *ev)
  1319. {
  1320.     ngx_stream_proxy_process_connection(ev, !ev->write);
  1321. }


  1322. static void
  1323. ngx_stream_proxy_process_connection(ngx_event_t *ev, ngx_uint_t from_upstream)
  1324. {
  1325.     ngx_connection_t             *c, *pc;
  1326.     ngx_log_handler_pt            handler;
  1327.     ngx_stream_session_t         *s;
  1328.     ngx_stream_upstream_t        *u;
  1329.     ngx_stream_proxy_srv_conf_t  *pscf;

  1330.     c = ev->data;
  1331.     s = c->data;
  1332.     u = s->upstream;

  1333.     if (c->close) {
  1334.         ngx_log_error(NGX_LOG_INFO, c->log, 0, "shutdown timeout");
  1335.         ngx_stream_proxy_finalize(s, NGX_STREAM_OK);
  1336.         return;
  1337.     }

  1338.     c = s->connection;
  1339.     pc = u->peer.connection;

  1340.     pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);

  1341.     if (ev->timedout) {
  1342.         ev->timedout = 0;

  1343.         if (ev->delayed) {
  1344.             ev->delayed = 0;

  1345.             if (!ev->ready) {
  1346.                 if (ngx_handle_read_event(ev, 0) != NGX_OK) {
  1347.                     ngx_stream_proxy_finalize(s,
  1348.                                               NGX_STREAM_INTERNAL_SERVER_ERROR);
  1349.                     return;
  1350.                 }

  1351.                 if (u->connected && !c->read->delayed && !pc->read->delayed) {
  1352.                     ngx_add_timer(c->write, pscf->timeout);
  1353.                 }

  1354.                 return;
  1355.             }

  1356.         } else {
  1357.             if (s->connection->type == SOCK_DGRAM) {

  1358.                 if (pscf->responses == NGX_MAX_INT32_VALUE
  1359.                     || (u->responses >= pscf->responses * u->requests))
  1360.                 {

  1361.                     /*
  1362.                      * successfully terminate timed out UDP session
  1363.                      * if expected number of responses was received
  1364.                      */

  1365.                     handler = c->log->handler;
  1366.                     c->log->handler = NULL;

  1367.                     ngx_log_error(NGX_LOG_INFO, c->log, 0,
  1368.                                   "udp timed out"
  1369.                                   ", packets from/to client:%ui/%ui"
  1370.                                   ", bytes from/to client:%O/%O"
  1371.                                   ", bytes from/to upstream:%O/%O",
  1372.                                   u->requests, u->responses,
  1373.                                   s->received, c->sent, u->received,
  1374.                                   pc ? pc->sent : 0);

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

  1376.                     ngx_stream_proxy_finalize(s, NGX_STREAM_OK);
  1377.                     return;
  1378.                 }

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

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

  1381.                 ngx_stream_proxy_finalize(s, NGX_STREAM_BAD_GATEWAY);

  1382.                 return;
  1383.             }

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

  1385.             ngx_stream_proxy_finalize(s, NGX_STREAM_OK);

  1386.             return;
  1387.         }

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

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

  1391.         if (ngx_handle_read_event(ev, 0) != NGX_OK) {
  1392.             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  1393.         }

  1394.         return;
  1395.     }

  1396.     if (from_upstream && !u->connected) {
  1397.         return;
  1398.     }

  1399.     ngx_stream_proxy_process(s, from_upstream, ev->write);
  1400. }


  1401. static void
  1402. ngx_stream_proxy_connect_handler(ngx_event_t *ev)
  1403. {
  1404.     ngx_connection_t      *c;
  1405.     ngx_stream_session_t  *s;

  1406.     c = ev->data;
  1407.     s = c->data;

  1408.     if (ev->timedout) {
  1409.         ngx_log_error(NGX_LOG_ERR, c->log, NGX_ETIMEDOUT, "upstream timed out");
  1410.         ngx_stream_proxy_next_upstream(s);
  1411.         return;
  1412.     }

  1413.     ngx_del_timer(c->write);

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

  1416.     if (ngx_stream_proxy_test_connect(c) != NGX_OK) {
  1417.         ngx_stream_proxy_next_upstream(s);
  1418.         return;
  1419.     }

  1420.     ngx_stream_proxy_init_upstream(s);
  1421. }


  1422. static ngx_int_t
  1423. ngx_stream_proxy_test_connect(ngx_connection_t *c)
  1424. {
  1425.     int        err;
  1426.     socklen_t  len;

  1427. #if (NGX_HAVE_KQUEUE)

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

  1430.         if (err) {
  1431.             (void) ngx_connection_error(c, err,
  1432.                                     "kevent() reported that connect() failed");
  1433.             return NGX_ERROR;
  1434.         }

  1435.     } else
  1436. #endif
  1437.     {
  1438.         err = 0;
  1439.         len = sizeof(int);

  1440.         /*
  1441.          * BSDs and Linux return 0 and set a pending error in err
  1442.          * Solaris returns -1 and sets errno
  1443.          */

  1444.         if (getsockopt(c->fd, SOL_SOCKET, SO_ERROR, (void *) &err, &len)
  1445.             == -1)
  1446.         {
  1447.             err = ngx_socket_errno;
  1448.         }

  1449.         if (err) {
  1450.             (void) ngx_connection_error(c, err, "connect() failed");
  1451.             return NGX_ERROR;
  1452.         }
  1453.     }

  1454.     return NGX_OK;
  1455. }


  1456. static void
  1457. ngx_stream_proxy_process(ngx_stream_session_t *s, ngx_uint_t from_upstream,
  1458.     ngx_uint_t do_write)
  1459. {
  1460.     char                         *recv_action, *send_action;
  1461.     off_t                        *received, limit;
  1462.     size_t                        size, limit_rate;
  1463.     ssize_t                       n;
  1464.     ngx_buf_t                    *b;
  1465.     ngx_int_t                     rc;
  1466.     ngx_uint_t                    flags, *packets;
  1467.     ngx_msec_t                    delay;
  1468.     ngx_chain_t                  *cl, **ll, **out, **busy;
  1469.     ngx_connection_t             *c, *pc, *src, *dst;
  1470.     ngx_log_handler_pt            handler;
  1471.     ngx_stream_upstream_t        *u;
  1472.     ngx_stream_proxy_srv_conf_t  *pscf;

  1473.     u = s->upstream;

  1474.     c = s->connection;
  1475.     pc = u->connected ? u->peer.connection : NULL;

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

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

  1478.         handler = c->log->handler;
  1479.         c->log->handler = NULL;

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

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

  1482.         ngx_stream_proxy_finalize(s, NGX_STREAM_OK);
  1483.         return;
  1484.     }

  1485.     pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);

  1486.     if (from_upstream) {
  1487.         src = pc;
  1488.         dst = c;
  1489.         b = &u->upstream_buf;
  1490.         limit_rate = u->download_rate;
  1491.         received = &u->received;
  1492.         packets = &u->responses;
  1493.         out = &u->downstream_out;
  1494.         busy = &u->downstream_busy;
  1495.         recv_action = "proxying and reading from upstream";
  1496.         send_action = "proxying and sending to client";

  1497.     } else {
  1498.         src = c;
  1499.         dst = pc;
  1500.         b = &u->downstream_buf;
  1501.         limit_rate = u->upload_rate;
  1502.         received = &s->received;
  1503.         packets = &u->requests;
  1504.         out = &u->upstream_out;
  1505.         busy = &u->upstream_busy;
  1506.         recv_action = "proxying and reading from client";
  1507.         send_action = "proxying and sending to upstream";
  1508.     }

  1509.     for ( ;; ) {

  1510.         if (do_write && dst) {

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

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

  1514.                 if (rc == NGX_ERROR) {
  1515.                     ngx_stream_proxy_finalize(s, NGX_STREAM_OK);
  1516.                     return;
  1517.                 }

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

  1520.                 if (*busy == NULL) {
  1521.                     b->pos = b->start;
  1522.                     b->last = b->start;
  1523.                 }
  1524.             }
  1525.         }

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

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

  1528.             if (limit_rate) {
  1529.                 limit = (off_t) limit_rate * (ngx_time() - u->start_sec + 1)
  1530.                         - *received;

  1531.                 if (limit <= 0) {
  1532.                     src->read->delayed = 1;
  1533.                     delay = (ngx_msec_t) (- limit * 1000 / limit_rate + 1);
  1534.                     ngx_add_timer(src->read, delay);
  1535.                     break;
  1536.                 }

  1537.                 if (c->type == SOCK_STREAM && (off_t) size > limit) {
  1538.                     size = (size_t) limit;
  1539.                 }
  1540.             }

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

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

  1543.             if (n == NGX_AGAIN) {
  1544.                 break;
  1545.             }

  1546.             if (n == NGX_ERROR) {
  1547.                 src->read->eof = 1;
  1548.                 n = 0;
  1549.             }

  1550.             if (n >= 0) {
  1551.                 if (limit_rate) {
  1552.                     delay = (ngx_msec_t) (n * 1000 / limit_rate);

  1553.                     if (delay > 0) {
  1554.                         src->read->delayed = 1;
  1555.                         ngx_add_timer(src->read, delay);
  1556.                     }
  1557.                 }

  1558.                 if (from_upstream) {
  1559.                     if (u->state->first_byte_time == (ngx_msec_t) -1) {
  1560.                         u->state->first_byte_time = ngx_current_msec
  1561.                                                     - u->start_time;

  1562.                         if (u->peer.notify) {
  1563.                             u->peer.notify(&u->peer, u->peer.data,
  1564.                                        NGX_STREAM_UPSTREAM_NOTIFY_FIRST_BYTE);
  1565.                         }
  1566.                     }
  1567.                 }

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

  1569.                 cl = ngx_chain_get_free_buf(c->pool, &u->free);
  1570.                 if (cl == NULL) {
  1571.                     ngx_stream_proxy_finalize(s,
  1572.                                               NGX_STREAM_INTERNAL_SERVER_ERROR);
  1573.                     return;
  1574.                 }

  1575.                 *ll = cl;

  1576.                 cl->buf->pos = b->last;
  1577.                 cl->buf->last = b->last + n;
  1578.                 cl->buf->tag = (ngx_buf_tag_t) &ngx_stream_proxy_module;

  1579.                 cl->buf->temporary = (n ? 1 : 0);
  1580.                 cl->buf->last_buf = src->read->eof;
  1581.                 cl->buf->flush = !src->read->eof;

  1582.                 (*packets)++;
  1583.                 *received += n;
  1584.                 b->last += n;
  1585.                 do_write = 1;

  1586.                 continue;
  1587.             }
  1588.         }

  1589.         break;
  1590.     }

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

  1592.     if (ngx_stream_proxy_test_finalize(s, from_upstream) == NGX_OK) {
  1593.         return;
  1594.     }

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

  1596.     if (ngx_handle_read_event(src->read, flags) != NGX_OK) {
  1597.         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  1598.         return;
  1599.     }

  1600.     if (dst) {

  1601.         if (dst->type == SOCK_STREAM && pscf->half_close
  1602.             && src->read->eof && !u->half_closed && !dst->buffered)
  1603.         {
  1604.             if (ngx_shutdown_socket(dst->fd, NGX_WRITE_SHUTDOWN) == -1) {
  1605.                 ngx_connection_error(c, ngx_socket_errno,
  1606.                                      ngx_shutdown_socket_n " failed");

  1607.                 ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  1608.                 return;
  1609.             }

  1610.             u->half_closed = 1;
  1611.             ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
  1612.                            "stream proxy %s socket shutdown",
  1613.                            from_upstream ? "client" : "upstream");
  1614.         }

  1615.         if (ngx_handle_write_event(dst->write, 0) != NGX_OK) {
  1616.             ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  1617.             return;
  1618.         }

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

  1621.         } else if (c->write->timer_set) {
  1622.             ngx_del_timer(c->write);
  1623.         }
  1624.     }
  1625. }


  1626. static ngx_int_t
  1627. ngx_stream_proxy_test_finalize(ngx_stream_session_t *s,
  1628.     ngx_uint_t from_upstream)
  1629. {
  1630.     ngx_connection_t             *c, *pc;
  1631.     ngx_log_handler_pt            handler;
  1632.     ngx_stream_upstream_t        *u;
  1633.     ngx_stream_proxy_srv_conf_t  *pscf;

  1634.     pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);

  1635.     c = s->connection;
  1636.     u = s->upstream;
  1637.     pc = u->connected ? u->peer.connection : NULL;

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

  1639.         if (pscf->requests && u->requests < pscf->requests) {
  1640.             return NGX_DECLINED;
  1641.         }

  1642.         if (pscf->requests) {
  1643.             ngx_delete_udp_connection(c);
  1644.         }

  1645.         if (pscf->responses == NGX_MAX_INT32_VALUE
  1646.             || u->responses < pscf->responses * u->requests)
  1647.         {
  1648.             return NGX_DECLINED;
  1649.         }

  1650.         if (pc == NULL || c->buffered || pc->buffered) {
  1651.             return NGX_DECLINED;
  1652.         }

  1653.         handler = c->log->handler;
  1654.         c->log->handler = NULL;

  1655.         ngx_log_error(NGX_LOG_INFO, c->log, 0,
  1656.                       "udp done"
  1657.                       ", packets from/to client:%ui/%ui"
  1658.                       ", bytes from/to client:%O/%O"
  1659.                       ", bytes from/to upstream:%O/%O",
  1660.                       u->requests, u->responses,
  1661.                       s->received, c->sent, u->received, pc ? pc->sent : 0);

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

  1663.         ngx_stream_proxy_finalize(s, NGX_STREAM_OK);

  1664.         return NGX_OK;
  1665.     }

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

  1667.     if (pc == NULL
  1668.         || (!c->read->eof && !pc->read->eof)
  1669.         || (!c->read->eof && c->buffered)
  1670.         || (!pc->read->eof && pc->buffered))
  1671.     {
  1672.         return NGX_DECLINED;
  1673.     }

  1674.     if (pscf->half_close) {
  1675.         /* avoid closing live connections until both read ends get EOF */
  1676.         if (!(c->read->eof && pc->read->eof && !c->buffered && !pc->buffered)) {
  1677.              return NGX_DECLINED;
  1678.         }
  1679.     }

  1680.     handler = c->log->handler;
  1681.     c->log->handler = NULL;

  1682.     ngx_log_error(NGX_LOG_INFO, c->log, 0,
  1683.                   "%s disconnected"
  1684.                   ", bytes from/to client:%O/%O"
  1685.                   ", bytes from/to upstream:%O/%O",
  1686.                   from_upstream ? "upstream" : "client",
  1687.                   s->received, c->sent, u->received, pc ? pc->sent : 0);

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

  1689.     ngx_stream_proxy_finalize(s, NGX_STREAM_OK);

  1690.     return NGX_OK;
  1691. }


  1692. static void
  1693. ngx_stream_proxy_next_upstream(ngx_stream_session_t *s)
  1694. {
  1695.     ngx_msec_t                    timeout;
  1696.     ngx_connection_t             *pc;
  1697.     ngx_stream_upstream_t        *u;
  1698.     ngx_stream_proxy_srv_conf_t  *pscf;

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

  1701.     u = s->upstream;
  1702.     pc = u->peer.connection;

  1703.     if (pc && pc->buffered) {
  1704.         ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
  1705.                       "buffered data on next upstream");
  1706.         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  1707.         return;
  1708.     }

  1709.     if (s->connection->type == SOCK_DGRAM) {
  1710.         u->upstream_out = NULL;
  1711.     }

  1712.     if (u->peer.sockaddr) {
  1713.         u->peer.free(&u->peer, u->peer.data, NGX_PEER_FAILED);
  1714.         u->peer.sockaddr = NULL;
  1715.     }

  1716.     pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);

  1717.     timeout = pscf->next_upstream_timeout;

  1718.     if (u->peer.tries == 0
  1719.         || !pscf->next_upstream
  1720.         || (timeout && ngx_current_msec - u->peer.start_time >= timeout))
  1721.     {
  1722.         ngx_stream_proxy_finalize(s, NGX_STREAM_BAD_GATEWAY);
  1723.         return;
  1724.     }

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

  1728. #if (NGX_STREAM_SSL)
  1729.         if (pc->ssl) {
  1730.             pc->ssl->no_wait_shutdown = 1;
  1731.             pc->ssl->no_send_shutdown = 1;

  1732.             (void) ngx_ssl_shutdown(pc);
  1733.         }
  1734. #endif

  1735.         u->state->bytes_received = u->received;
  1736.         u->state->bytes_sent = pc->sent;

  1737.         ngx_close_connection(pc);
  1738.         u->peer.connection = NULL;
  1739.     }

  1740.     ngx_stream_proxy_connect(s);
  1741. }


  1742. static void
  1743. ngx_stream_proxy_finalize(ngx_stream_session_t *s, ngx_uint_t rc)
  1744. {
  1745.     ngx_uint_t              state;
  1746.     ngx_connection_t       *pc;
  1747.     ngx_stream_upstream_t  *u;

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

  1750.     u = s->upstream;

  1751.     if (u == NULL) {
  1752.         goto noupstream;
  1753.     }

  1754.     if (u->resolved && u->resolved->ctx) {
  1755.         ngx_resolve_name_done(u->resolved->ctx);
  1756.         u->resolved->ctx = NULL;
  1757.     }

  1758.     pc = u->peer.connection;

  1759.     if (u->state) {
  1760.         if (u->state->response_time == (ngx_msec_t) -1) {
  1761.             u->state->response_time = ngx_current_msec - u->start_time;
  1762.         }

  1763.         if (pc) {
  1764.             u->state->bytes_received = u->received;
  1765.             u->state->bytes_sent = pc->sent;
  1766.         }
  1767.     }

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

  1770.         if (pc && pc->type == SOCK_DGRAM
  1771.             && (pc->read->error || pc->write->error))
  1772.         {
  1773.             state = NGX_PEER_FAILED;
  1774.         }

  1775.         u->peer.free(&u->peer, u->peer.data, state);
  1776.         u->peer.sockaddr = NULL;
  1777.     }

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

  1781. #if (NGX_STREAM_SSL)
  1782.         if (pc->ssl) {
  1783.             pc->ssl->no_wait_shutdown = 1;
  1784.             (void) ngx_ssl_shutdown(pc);
  1785.         }
  1786. #endif

  1787.         ngx_close_connection(pc);
  1788.         u->peer.connection = NULL;
  1789.     }

  1790. noupstream:

  1791.     ngx_stream_finalize_session(s, rc);
  1792. }


  1793. static u_char *
  1794. ngx_stream_proxy_log_error(ngx_log_t *log, u_char *buf, size_t len)
  1795. {
  1796.     u_char                 *p;
  1797.     ngx_connection_t       *pc;
  1798.     ngx_stream_session_t   *s;
  1799.     ngx_stream_upstream_t  *u;

  1800.     s = log->data;

  1801.     u = s->upstream;

  1802.     p = buf;

  1803.     if (u->peer.name) {
  1804.         p = ngx_snprintf(p, len, ", upstream: \"%V\"", u->peer.name);
  1805.         len -= p - buf;
  1806.     }

  1807.     pc = u->peer.connection;

  1808.     p = ngx_snprintf(p, len,
  1809.                      ", bytes from/to client:%O/%O"
  1810.                      ", bytes from/to upstream:%O/%O",
  1811.                      s->received, s->connection->sent,
  1812.                      u->received, pc ? pc->sent : 0);

  1813.     return p;
  1814. }


  1815. static void *
  1816. ngx_stream_proxy_create_srv_conf(ngx_conf_t *cf)
  1817. {
  1818.     ngx_stream_proxy_srv_conf_t  *conf;

  1819.     conf = ngx_pcalloc(cf->pool, sizeof(ngx_stream_proxy_srv_conf_t));
  1820.     if (conf == NULL) {
  1821.         return NULL;
  1822.     }

  1823.     /*
  1824.      * set by ngx_pcalloc():
  1825.      *
  1826.      *     conf->ssl_protocols = 0;
  1827.      *     conf->ssl_ciphers = { 0, NULL };
  1828.      *     conf->ssl_trusted_certificate = { 0, NULL };
  1829.      *     conf->ssl_crl = { 0, NULL };
  1830.      *
  1831.      *     conf->ssl = NULL;
  1832.      *     conf->upstream = NULL;
  1833.      *     conf->upstream_value = NULL;
  1834.      */

  1835.     conf->connect_timeout = NGX_CONF_UNSET_MSEC;
  1836.     conf->timeout = NGX_CONF_UNSET_MSEC;
  1837.     conf->next_upstream_timeout = NGX_CONF_UNSET_MSEC;
  1838.     conf->buffer_size = NGX_CONF_UNSET_SIZE;
  1839.     conf->upload_rate = NGX_CONF_UNSET_PTR;
  1840.     conf->download_rate = NGX_CONF_UNSET_PTR;
  1841.     conf->requests = NGX_CONF_UNSET_UINT;
  1842.     conf->responses = NGX_CONF_UNSET_UINT;
  1843.     conf->next_upstream_tries = NGX_CONF_UNSET_UINT;
  1844.     conf->next_upstream = NGX_CONF_UNSET;
  1845.     conf->proxy_protocol = NGX_CONF_UNSET_UINT;
  1846.     conf->local = NGX_CONF_UNSET_PTR;
  1847.     conf->socket_keepalive = NGX_CONF_UNSET;
  1848.     conf->socket_rcvbuf = NGX_CONF_UNSET_SIZE;
  1849.     conf->socket_sndbuf = NGX_CONF_UNSET_SIZE;
  1850.     conf->half_close = NGX_CONF_UNSET;

  1851. #if (NGX_STREAM_SSL)
  1852.     conf->ssl_enable = NGX_CONF_UNSET;
  1853.     conf->ssl_session_reuse = NGX_CONF_UNSET;
  1854.     conf->ssl_name = NGX_CONF_UNSET_PTR;
  1855.     conf->ssl_server_name = NGX_CONF_UNSET;
  1856.     conf->ssl_alpn = NGX_CONF_UNSET_PTR;
  1857.     conf->ssl_verify = NGX_CONF_UNSET;
  1858.     conf->ssl_verify_depth = NGX_CONF_UNSET_UINT;
  1859.     conf->ssl_certificate = NGX_CONF_UNSET_PTR;
  1860.     conf->ssl_certificate_key = NGX_CONF_UNSET_PTR;
  1861.     conf->ssl_certificate_cache = NGX_CONF_UNSET_PTR;
  1862.     conf->ssl_passwords = NGX_CONF_UNSET_PTR;
  1863.     conf->ssl_conf_commands = NGX_CONF_UNSET_PTR;
  1864. #endif

  1865.     return conf;
  1866. }


  1867. static char *
  1868. ngx_stream_proxy_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
  1869. {
  1870.     ngx_stream_proxy_srv_conf_t *prev = parent;
  1871.     ngx_stream_proxy_srv_conf_t *conf = child;

  1872.     ngx_conf_merge_msec_value(conf->connect_timeout,
  1873.                               prev->connect_timeout, 60000);

  1874.     ngx_conf_merge_msec_value(conf->timeout,
  1875.                               prev->timeout, 10 * 60000);

  1876.     ngx_conf_merge_msec_value(conf->next_upstream_timeout,
  1877.                               prev->next_upstream_timeout, 0);

  1878.     ngx_conf_merge_size_value(conf->buffer_size,
  1879.                               prev->buffer_size, 16384);

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

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

  1882.     ngx_conf_merge_uint_value(conf->requests,
  1883.                               prev->requests, 0);

  1884.     ngx_conf_merge_uint_value(conf->responses,
  1885.                               prev->responses, NGX_MAX_INT32_VALUE);

  1886.     ngx_conf_merge_uint_value(conf->next_upstream_tries,
  1887.                               prev->next_upstream_tries, 0);

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

  1889.     ngx_conf_merge_uint_value(conf->proxy_protocol, prev->proxy_protocol, 0);

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

  1891.     ngx_conf_merge_value(conf->socket_keepalive,
  1892.                               prev->socket_keepalive, 0);

  1893.     ngx_conf_merge_size_value(conf->socket_rcvbuf, prev->socket_rcvbuf, 0);

  1894.     ngx_conf_merge_size_value(conf->socket_sndbuf, prev->socket_sndbuf, 0);

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

  1896. #if (NGX_STREAM_SSL)

  1897.     if (ngx_stream_proxy_merge_ssl(cf, conf, prev) != NGX_OK) {
  1898.         return NGX_CONF_ERROR;
  1899.     }

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

  1901.     ngx_conf_merge_value(conf->ssl_session_reuse,
  1902.                               prev->ssl_session_reuse, 1);

  1903.     ngx_conf_merge_bitmask_value(conf->ssl_protocols, prev->ssl_protocols,
  1904.                               (NGX_CONF_BITMASK_SET|NGX_SSL_DEFAULT_PROTOCOLS));

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

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

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

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

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

  1910.     ngx_conf_merge_uint_value(conf->ssl_verify_depth,
  1911.                               prev->ssl_verify_depth, 1);

  1912.     ngx_conf_merge_str_value(conf->ssl_trusted_certificate,
  1913.                               prev->ssl_trusted_certificate, "");

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

  1915.     ngx_conf_merge_ptr_value(conf->ssl_certificate,
  1916.                               prev->ssl_certificate, NULL);

  1917.     ngx_conf_merge_ptr_value(conf->ssl_certificate_key,
  1918.                               prev->ssl_certificate_key, NULL);

  1919.     ngx_conf_merge_ptr_value(conf->ssl_certificate_cache,
  1920.                               prev->ssl_certificate_cache, NULL);

  1921.     if (ngx_stream_proxy_merge_ssl_passwords(cf, conf, prev) != NGX_OK) {
  1922.         return NGX_CONF_ERROR;
  1923.     }

  1924.     ngx_conf_merge_ptr_value(conf->ssl_conf_commands,
  1925.                               prev->ssl_conf_commands, NULL);

  1926.     if (conf->ssl_enable && ngx_stream_proxy_set_ssl(cf, conf) != NGX_OK) {
  1927.         return NGX_CONF_ERROR;
  1928.     }

  1929. #endif

  1930.     return NGX_CONF_OK;
  1931. }


  1932. #if (NGX_STREAM_SSL)

  1933. static ngx_int_t
  1934. ngx_stream_proxy_merge_ssl(ngx_conf_t *cf, ngx_stream_proxy_srv_conf_t *conf,
  1935.     ngx_stream_proxy_srv_conf_t *prev)
  1936. {
  1937.     ngx_uint_t  preserve;

  1938.     if (conf->ssl_protocols == 0
  1939.         && conf->ssl_ciphers.data == NULL
  1940.         && conf->ssl_certificate == NGX_CONF_UNSET_PTR
  1941.         && conf->ssl_certificate_key == NGX_CONF_UNSET_PTR
  1942.         && conf->ssl_passwords == NGX_CONF_UNSET_PTR
  1943.         && conf->ssl_verify == NGX_CONF_UNSET
  1944.         && conf->ssl_verify_depth == NGX_CONF_UNSET_UINT
  1945.         && conf->ssl_trusted_certificate.data == NULL
  1946.         && conf->ssl_crl.data == NULL
  1947.         && conf->ssl_session_reuse == NGX_CONF_UNSET
  1948.         && conf->ssl_conf_commands == NGX_CONF_UNSET_PTR)
  1949.     {
  1950.         if (prev->ssl) {
  1951.             conf->ssl = prev->ssl;
  1952.             return NGX_OK;
  1953.         }

  1954.         preserve = 1;

  1955.     } else {
  1956.         preserve = 0;
  1957.     }

  1958.     conf->ssl = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_t));
  1959.     if (conf->ssl == NULL) {
  1960.         return NGX_ERROR;
  1961.     }

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

  1963.     /*
  1964.      * special handling to preserve conf->ssl
  1965.      * in the "stream" section to inherit it to all servers
  1966.      */

  1967.     if (preserve) {
  1968.         prev->ssl = conf->ssl;
  1969.     }

  1970.     return NGX_OK;
  1971. }


  1972. static ngx_int_t
  1973. ngx_stream_proxy_merge_ssl_passwords(ngx_conf_t *cf,
  1974.     ngx_stream_proxy_srv_conf_t *conf, ngx_stream_proxy_srv_conf_t *prev)
  1975. {
  1976.     ngx_uint_t  preserve;

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

  1978.     if (conf->ssl_certificate == NULL
  1979.         || conf->ssl_certificate->value.len == 0
  1980.         || conf->ssl_certificate_key == NULL)
  1981.     {
  1982.         return NGX_OK;
  1983.     }

  1984.     if (conf->ssl_certificate->lengths == NULL
  1985.         && conf->ssl_certificate_key->lengths == NULL)
  1986.     {
  1987.         if (conf->ssl_passwords && conf->ssl_passwords->pool == NULL) {
  1988.             /* un-preserve empty password list */
  1989.             conf->ssl_passwords = NULL;
  1990.         }

  1991.         return NGX_OK;
  1992.     }

  1993.     if (conf->ssl_passwords && conf->ssl_passwords->pool != cf->temp_pool) {
  1994.         /* already preserved */
  1995.         return NGX_OK;
  1996.     }

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

  1998.     conf->ssl_passwords = ngx_ssl_preserve_passwords(cf, conf->ssl_passwords);
  1999.     if (conf->ssl_passwords == NULL) {
  2000.         return NGX_ERROR;
  2001.     }

  2002.     /*
  2003.      * special handling to keep a preserved ssl_passwords copy
  2004.      * in the previous configuration to inherit it to all children
  2005.      */

  2006.     if (preserve) {
  2007.         prev->ssl_passwords = conf->ssl_passwords;
  2008.     }

  2009.     return NGX_OK;
  2010. }


  2011. static ngx_int_t
  2012. ngx_stream_proxy_set_ssl(ngx_conf_t *cf, ngx_stream_proxy_srv_conf_t *pscf)
  2013. {
  2014.     ngx_pool_cleanup_t  *cln;

  2015.     if (pscf->ssl->ctx) {
  2016.         return NGX_OK;
  2017.     }

  2018.     if (ngx_ssl_create(pscf->ssl, pscf->ssl_protocols, NULL) != NGX_OK) {
  2019.         return NGX_ERROR;
  2020.     }

  2021.     cln = ngx_pool_cleanup_add(cf->pool, 0);
  2022.     if (cln == NULL) {
  2023.         ngx_ssl_cleanup_ctx(pscf->ssl);
  2024.         return NGX_ERROR;
  2025.     }

  2026.     cln->handler = ngx_ssl_cleanup_ctx;
  2027.     cln->data = pscf->ssl;

  2028.     if (ngx_ssl_ciphers(cf, pscf->ssl, &pscf->ssl_ciphers, 0) != NGX_OK) {
  2029.         return NGX_ERROR;
  2030.     }

  2031.     if (pscf->ssl_certificate
  2032.         && pscf->ssl_certificate->value.len)
  2033.     {
  2034.         if (pscf->ssl_certificate_key == NULL) {
  2035.             ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
  2036.                           "no \"proxy_ssl_certificate_key\" is defined "
  2037.                           "for certificate \"%V\"",
  2038.                           &pscf->ssl_certificate->value);
  2039.             return NGX_ERROR;
  2040.         }

  2041.         if (pscf->ssl_certificate->lengths == NULL
  2042.             && pscf->ssl_certificate_key->lengths == NULL)
  2043.         {
  2044.             if (ngx_ssl_certificate(cf, pscf->ssl,
  2045.                                     &pscf->ssl_certificate->value,
  2046.                                     &pscf->ssl_certificate_key->value,
  2047.                                     pscf->ssl_passwords)
  2048.                 != NGX_OK)
  2049.             {
  2050.                 return NGX_ERROR;
  2051.             }
  2052.         }
  2053.     }

  2054.     if (pscf->ssl_verify) {
  2055.         if (pscf->ssl_trusted_certificate.len == 0) {
  2056.             ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
  2057.                       "no proxy_ssl_trusted_certificate for proxy_ssl_verify");
  2058.             return NGX_ERROR;
  2059.         }

  2060.         if (ngx_ssl_trusted_certificate(cf, pscf->ssl,
  2061.                                         &pscf->ssl_trusted_certificate,
  2062.                                         pscf->ssl_verify_depth)
  2063.             != NGX_OK)
  2064.         {
  2065.             return NGX_ERROR;
  2066.         }

  2067.         if (ngx_ssl_crl(cf, pscf->ssl, &pscf->ssl_crl) != NGX_OK) {
  2068.             return NGX_ERROR;
  2069.         }
  2070.     }

  2071.     if (ngx_ssl_client_session_cache(cf, pscf->ssl, pscf->ssl_session_reuse)
  2072.         != NGX_OK)
  2073.     {
  2074.         return NGX_ERROR;
  2075.     }

  2076.     if (ngx_ssl_conf_commands(cf, pscf->ssl, pscf->ssl_conf_commands)
  2077.         != NGX_OK)
  2078.     {
  2079.         return NGX_ERROR;
  2080.     }

  2081.     return NGX_OK;
  2082. }

  2083. #endif


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

  2088.     ngx_url_t                            u;
  2089.     ngx_str_t                           *value, *url;
  2090.     ngx_stream_complex_value_t           cv;
  2091.     ngx_stream_core_srv_conf_t          *cscf;
  2092.     ngx_stream_compile_complex_value_t   ccv;

  2093.     if (pscf->upstream || pscf->upstream_value) {
  2094.         return "is duplicate";
  2095.     }

  2096.     cscf = ngx_stream_conf_get_module_srv_conf(cf, ngx_stream_core_module);

  2097.     cscf->handler = ngx_stream_proxy_handler;

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

  2099.     url = &value[1];

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

  2101.     ccv.cf = cf;
  2102.     ccv.value = url;
  2103.     ccv.complex_value = &cv;

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

  2107.     if (cv.lengths) {
  2108.         pscf->upstream_value = ngx_palloc(cf->pool,
  2109.                                           sizeof(ngx_stream_complex_value_t));
  2110.         if (pscf->upstream_value == NULL) {
  2111.             return NGX_CONF_ERROR;
  2112.         }

  2113.         *pscf->upstream_value = cv;

  2114.         return NGX_CONF_OK;
  2115.     }

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

  2117.     u.url = *url;
  2118.     u.no_resolve = 1;

  2119.     pscf->upstream = ngx_stream_upstream_add(cf, &u, 0);
  2120.     if (pscf->upstream == NULL) {
  2121.         return NGX_CONF_ERROR;
  2122.     }

  2123.     return NGX_CONF_OK;
  2124. }


  2125. static char *
  2126. ngx_stream_proxy_bind(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  2127. {
  2128.     ngx_stream_proxy_srv_conf_t *pscf = conf;

  2129.     ngx_int_t                            rc;
  2130.     ngx_str_t                           *value;
  2131.     ngx_stream_complex_value_t           cv;
  2132.     ngx_stream_upstream_local_t         *local;
  2133.     ngx_stream_compile_complex_value_t   ccv;

  2134.     if (pscf->local != NGX_CONF_UNSET_PTR) {
  2135.         return "is duplicate";
  2136.     }

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

  2138.     if (cf->args->nelts == 2 && ngx_strcmp(value[1].data, "off") == 0) {
  2139.         pscf->local = NULL;
  2140.         return NGX_CONF_OK;
  2141.     }

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

  2143.     ccv.cf = cf;
  2144.     ccv.value = &value[1];
  2145.     ccv.complex_value = &cv;

  2146.     if (ngx_stream_compile_complex_value(&ccv) != NGX_OK) {
  2147.         return NGX_CONF_ERROR;
  2148.     }

  2149.     local = ngx_pcalloc(cf->pool, sizeof(ngx_stream_upstream_local_t));
  2150.     if (local == NULL) {
  2151.         return NGX_CONF_ERROR;
  2152.     }

  2153.     pscf->local = local;

  2154.     if (cv.lengths) {
  2155.         local->value = ngx_palloc(cf->pool, sizeof(ngx_stream_complex_value_t));
  2156.         if (local->value == NULL) {
  2157.             return NGX_CONF_ERROR;
  2158.         }

  2159.         *local->value = cv;

  2160.     } else {
  2161.         local->addr = ngx_palloc(cf->pool, sizeof(ngx_addr_t));
  2162.         if (local->addr == NULL) {
  2163.             return NGX_CONF_ERROR;
  2164.         }

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

  2167.         switch (rc) {
  2168.         case NGX_OK:
  2169.             local->addr->name = value[1];
  2170.             break;

  2171.         case NGX_DECLINED:
  2172.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  2173.                                "invalid address \"%V\"", &value[1]);
  2174.             /* fall through */

  2175.         default:
  2176.             return NGX_CONF_ERROR;
  2177.         }
  2178.     }

  2179.     if (cf->args->nelts > 2) {
  2180.         if (ngx_strcmp(value[2].data, "transparent") == 0) {
  2181. #if (NGX_HAVE_TRANSPARENT_PROXY)
  2182.             ngx_core_conf_t  *ccf;

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

  2185.             ccf->transparent = 1;
  2186.             local->transparent = 1;
  2187. #else
  2188.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  2189.                                "transparent proxying is not supported "
  2190.                                "on this platform, ignored");
  2191. #endif
  2192.         } else {
  2193.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  2194.                                "invalid parameter \"%V\"", &value[2]);
  2195.             return NGX_CONF_ERROR;
  2196.         }
  2197.     }

  2198.     return NGX_CONF_OK;
  2199. }