src/stream/ngx_stream.c - nginx source code

Global variables 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_event.h>
  8. #include <ngx_stream.h>


  9. static char *ngx_stream_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
  10. static ngx_int_t ngx_stream_init_phases(ngx_conf_t *cf,
  11.     ngx_stream_core_main_conf_t *cmcf);
  12. static ngx_int_t ngx_stream_init_phase_handlers(ngx_conf_t *cf,
  13.     ngx_stream_core_main_conf_t *cmcf);

  14. static ngx_int_t ngx_stream_add_addresses(ngx_conf_t *cf,
  15.     ngx_stream_core_srv_conf_t *cscf, ngx_stream_conf_port_t *port,
  16.     ngx_stream_listen_opt_t *lsopt);
  17. static ngx_int_t ngx_stream_add_address(ngx_conf_t *cf,
  18.     ngx_stream_core_srv_conf_t *cscf, ngx_stream_conf_port_t *port,
  19.     ngx_stream_listen_opt_t *lsopt);
  20. static ngx_int_t ngx_stream_add_server(ngx_conf_t *cf,
  21.     ngx_stream_core_srv_conf_t *cscf, ngx_stream_conf_addr_t *addr);

  22. static ngx_int_t ngx_stream_optimize_servers(ngx_conf_t *cf,
  23.     ngx_stream_core_main_conf_t *cmcf, ngx_array_t *ports);
  24. static ngx_int_t ngx_stream_server_names(ngx_conf_t *cf,
  25.     ngx_stream_core_main_conf_t *cmcf, ngx_stream_conf_addr_t *addr);
  26. static ngx_int_t ngx_stream_cmp_conf_addrs(const void *one, const void *two);
  27. static int ngx_libc_cdecl ngx_stream_cmp_dns_wildcards(const void *one,
  28.     const void *two);

  29. static ngx_int_t ngx_stream_init_listening(ngx_conf_t *cf,
  30.     ngx_stream_conf_port_t *port);
  31. static ngx_listening_t *ngx_stream_add_listening(ngx_conf_t *cf,
  32.     ngx_stream_conf_addr_t *addr);
  33. static ngx_int_t ngx_stream_add_addrs(ngx_conf_t *cf, ngx_stream_port_t *stport,
  34.     ngx_stream_conf_addr_t *addr);
  35. #if (NGX_HAVE_INET6)
  36. static ngx_int_t ngx_stream_add_addrs6(ngx_conf_t *cf,
  37.     ngx_stream_port_t *stport, ngx_stream_conf_addr_t *addr);
  38. #endif


  39. ngx_uint_t  ngx_stream_max_module;


  40. ngx_stream_filter_pt  ngx_stream_top_filter;


  41. static ngx_command_t  ngx_stream_commands[] = {

  42.     { ngx_string("stream"),
  43.       NGX_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
  44.       ngx_stream_block,
  45.       0,
  46.       0,
  47.       NULL },

  48.       ngx_null_command
  49. };


  50. static ngx_core_module_t  ngx_stream_module_ctx = {
  51.     ngx_string("stream"),
  52.     NULL,
  53.     NULL
  54. };


  55. ngx_module_t  ngx_stream_module = {
  56.     NGX_MODULE_V1,
  57.     &ngx_stream_module_ctx,                /* module context */
  58.     ngx_stream_commands,                   /* module directives */
  59.     NGX_CORE_MODULE,                       /* module type */
  60.     NULL,                                  /* init master */
  61.     NULL,                                  /* init module */
  62.     NULL,                                  /* init process */
  63.     NULL,                                  /* init thread */
  64.     NULL,                                  /* exit thread */
  65.     NULL,                                  /* exit process */
  66.     NULL,                                  /* exit master */
  67.     NGX_MODULE_V1_PADDING
  68. };


  69. static char *
  70. ngx_stream_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  71. {
  72.     char                          *rv;
  73.     ngx_uint_t                     mi, m, s;
  74.     ngx_conf_t                     pcf;
  75.     ngx_stream_module_t           *module;
  76.     ngx_stream_conf_ctx_t         *ctx;
  77.     ngx_stream_core_srv_conf_t   **cscfp;
  78.     ngx_stream_core_main_conf_t   *cmcf;

  79.     if (*(ngx_stream_conf_ctx_t **) conf) {
  80.         return "is duplicate";
  81.     }

  82.     /* the main stream context */

  83.     ctx = ngx_pcalloc(cf->pool, sizeof(ngx_stream_conf_ctx_t));
  84.     if (ctx == NULL) {
  85.         return NGX_CONF_ERROR;
  86.     }

  87.     *(ngx_stream_conf_ctx_t **) conf = ctx;

  88.     /* count the number of the stream modules and set up their indices */

  89.     ngx_stream_max_module = ngx_count_modules(cf->cycle, NGX_STREAM_MODULE);


  90.     /* the stream main_conf context, it's the same in the all stream contexts */

  91.     ctx->main_conf = ngx_pcalloc(cf->pool,
  92.                                  sizeof(void *) * ngx_stream_max_module);
  93.     if (ctx->main_conf == NULL) {
  94.         return NGX_CONF_ERROR;
  95.     }


  96.     /*
  97.      * the stream null srv_conf context, it is used to merge
  98.      * the server{}s' srv_conf's
  99.      */

  100.     ctx->srv_conf = ngx_pcalloc(cf->pool,
  101.                                 sizeof(void *) * ngx_stream_max_module);
  102.     if (ctx->srv_conf == NULL) {
  103.         return NGX_CONF_ERROR;
  104.     }


  105.     /*
  106.      * create the main_conf's and the null srv_conf's of the all stream modules
  107.      */

  108.     for (m = 0; cf->cycle->modules[m]; m++) {
  109.         if (cf->cycle->modules[m]->type != NGX_STREAM_MODULE) {
  110.             continue;
  111.         }

  112.         module = cf->cycle->modules[m]->ctx;
  113.         mi = cf->cycle->modules[m]->ctx_index;

  114.         if (module->create_main_conf) {
  115.             ctx->main_conf[mi] = module->create_main_conf(cf);
  116.             if (ctx->main_conf[mi] == NULL) {
  117.                 return NGX_CONF_ERROR;
  118.             }
  119.         }

  120.         if (module->create_srv_conf) {
  121.             ctx->srv_conf[mi] = module->create_srv_conf(cf);
  122.             if (ctx->srv_conf[mi] == NULL) {
  123.                 return NGX_CONF_ERROR;
  124.             }
  125.         }
  126.     }


  127.     pcf = *cf;
  128.     cf->ctx = ctx;

  129.     for (m = 0; cf->cycle->modules[m]; m++) {
  130.         if (cf->cycle->modules[m]->type != NGX_STREAM_MODULE) {
  131.             continue;
  132.         }

  133.         module = cf->cycle->modules[m]->ctx;

  134.         if (module->preconfiguration) {
  135.             if (module->preconfiguration(cf) != NGX_OK) {
  136.                 return NGX_CONF_ERROR;
  137.             }
  138.         }
  139.     }


  140.     /* parse inside the stream{} block */

  141.     cf->module_type = NGX_STREAM_MODULE;
  142.     cf->cmd_type = NGX_STREAM_MAIN_CONF;
  143.     rv = ngx_conf_parse(cf, NULL);

  144.     if (rv != NGX_CONF_OK) {
  145.         *cf = pcf;
  146.         return rv;
  147.     }


  148.     /* init stream{} main_conf's, merge the server{}s' srv_conf's */

  149.     cmcf = ctx->main_conf[ngx_stream_core_module.ctx_index];
  150.     cscfp = cmcf->servers.elts;

  151.     for (m = 0; cf->cycle->modules[m]; m++) {
  152.         if (cf->cycle->modules[m]->type != NGX_STREAM_MODULE) {
  153.             continue;
  154.         }

  155.         module = cf->cycle->modules[m]->ctx;
  156.         mi = cf->cycle->modules[m]->ctx_index;

  157.         /* init stream{} main_conf's */

  158.         cf->ctx = ctx;

  159.         if (module->init_main_conf) {
  160.             rv = module->init_main_conf(cf, ctx->main_conf[mi]);
  161.             if (rv != NGX_CONF_OK) {
  162.                 *cf = pcf;
  163.                 return rv;
  164.             }
  165.         }

  166.         for (s = 0; s < cmcf->servers.nelts; s++) {

  167.             /* merge the server{}s' srv_conf's */

  168.             cf->ctx = cscfp[s]->ctx;

  169.             if (module->merge_srv_conf) {
  170.                 rv = module->merge_srv_conf(cf,
  171.                                             ctx->srv_conf[mi],
  172.                                             cscfp[s]->ctx->srv_conf[mi]);
  173.                 if (rv != NGX_CONF_OK) {
  174.                     *cf = pcf;
  175.                     return rv;
  176.                 }
  177.             }
  178.         }
  179.     }

  180.     if (ngx_stream_init_phases(cf, cmcf) != NGX_OK) {
  181.         return NGX_CONF_ERROR;
  182.     }

  183.     for (m = 0; cf->cycle->modules[m]; m++) {
  184.         if (cf->cycle->modules[m]->type != NGX_STREAM_MODULE) {
  185.             continue;
  186.         }

  187.         module = cf->cycle->modules[m]->ctx;

  188.         if (module->postconfiguration) {
  189.             if (module->postconfiguration(cf) != NGX_OK) {
  190.                 return NGX_CONF_ERROR;
  191.             }
  192.         }
  193.     }

  194.     if (ngx_stream_variables_init_vars(cf) != NGX_OK) {
  195.         return NGX_CONF_ERROR;
  196.     }

  197.     *cf = pcf;

  198.     if (ngx_stream_init_phase_handlers(cf, cmcf) != NGX_OK) {
  199.         return NGX_CONF_ERROR;
  200.     }

  201.     /* optimize the lists of ports, addresses and server names */

  202.     if (ngx_stream_optimize_servers(cf, cmcf, cmcf->ports) != NGX_OK) {
  203.         return NGX_CONF_ERROR;
  204.     }

  205.     return NGX_CONF_OK;
  206. }


  207. static ngx_int_t
  208. ngx_stream_init_phases(ngx_conf_t *cf, ngx_stream_core_main_conf_t *cmcf)
  209. {
  210.     if (ngx_array_init(&cmcf->phases[NGX_STREAM_POST_ACCEPT_PHASE].handlers,
  211.                        cf->pool, 1, sizeof(ngx_stream_handler_pt))
  212.         != NGX_OK)
  213.     {
  214.         return NGX_ERROR;
  215.     }

  216.     if (ngx_array_init(&cmcf->phases[NGX_STREAM_PREACCESS_PHASE].handlers,
  217.                        cf->pool, 1, sizeof(ngx_stream_handler_pt))
  218.         != NGX_OK)
  219.     {
  220.         return NGX_ERROR;
  221.     }

  222.     if (ngx_array_init(&cmcf->phases[NGX_STREAM_ACCESS_PHASE].handlers,
  223.                        cf->pool, 1, sizeof(ngx_stream_handler_pt))
  224.         != NGX_OK)
  225.     {
  226.         return NGX_ERROR;
  227.     }

  228.     if (ngx_array_init(&cmcf->phases[NGX_STREAM_SSL_PHASE].handlers,
  229.                        cf->pool, 1, sizeof(ngx_stream_handler_pt))
  230.         != NGX_OK)
  231.     {
  232.         return NGX_ERROR;
  233.     }

  234.     if (ngx_array_init(&cmcf->phases[NGX_STREAM_PREREAD_PHASE].handlers,
  235.                        cf->pool, 1, sizeof(ngx_stream_handler_pt))
  236.         != NGX_OK)
  237.     {
  238.         return NGX_ERROR;
  239.     }

  240.     if (ngx_array_init(&cmcf->phases[NGX_STREAM_LOG_PHASE].handlers,
  241.                        cf->pool, 1, sizeof(ngx_stream_handler_pt))
  242.         != NGX_OK)
  243.     {
  244.         return NGX_ERROR;
  245.     }

  246.     return NGX_OK;
  247. }


  248. static ngx_int_t
  249. ngx_stream_init_phase_handlers(ngx_conf_t *cf,
  250.     ngx_stream_core_main_conf_t *cmcf)
  251. {
  252.     ngx_int_t                     j;
  253.     ngx_uint_t                    i, n;
  254.     ngx_stream_handler_pt        *h;
  255.     ngx_stream_phase_handler_t   *ph;
  256.     ngx_stream_phase_handler_pt   checker;

  257.     n = 1 /* content phase */;

  258.     for (i = 0; i < NGX_STREAM_LOG_PHASE; i++) {
  259.         n += cmcf->phases[i].handlers.nelts;
  260.     }

  261.     ph = ngx_pcalloc(cf->pool,
  262.                      n * sizeof(ngx_stream_phase_handler_t) + sizeof(void *));
  263.     if (ph == NULL) {
  264.         return NGX_ERROR;
  265.     }

  266.     cmcf->phase_engine.handlers = ph;
  267.     n = 0;

  268.     for (i = 0; i < NGX_STREAM_LOG_PHASE; i++) {
  269.         h = cmcf->phases[i].handlers.elts;

  270.         switch (i) {

  271.         case NGX_STREAM_PREREAD_PHASE:
  272.             checker = ngx_stream_core_preread_phase;
  273.             break;

  274.         case NGX_STREAM_CONTENT_PHASE:
  275.             ph->checker = ngx_stream_core_content_phase;
  276.             n++;
  277.             ph++;

  278.             continue;

  279.         default:
  280.             checker = ngx_stream_core_generic_phase;
  281.         }

  282.         n += cmcf->phases[i].handlers.nelts;

  283.         for (j = cmcf->phases[i].handlers.nelts - 1; j >= 0; j--) {
  284.             ph->checker = checker;
  285.             ph->handler = h[j];
  286.             ph->next = n;
  287.             ph++;
  288.         }
  289.     }

  290.     return NGX_OK;
  291. }


  292. ngx_int_t
  293. ngx_stream_add_listen(ngx_conf_t *cf, ngx_stream_core_srv_conf_t *cscf,
  294.     ngx_stream_listen_opt_t *lsopt)
  295. {
  296.     in_port_t                     p;
  297.     ngx_uint_t                    i;
  298.     struct sockaddr              *sa;
  299.     ngx_stream_conf_port_t       *port;
  300.     ngx_stream_core_main_conf_t  *cmcf;

  301.     cmcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_core_module);

  302.     if (cmcf->ports == NULL) {
  303.         cmcf->ports = ngx_array_create(cf->temp_pool, 2,
  304.                                        sizeof(ngx_stream_conf_port_t));
  305.         if (cmcf->ports == NULL) {
  306.             return NGX_ERROR;
  307.         }
  308.     }

  309.     sa = lsopt->sockaddr;
  310.     p = ngx_inet_get_port(sa);

  311.     port = cmcf->ports->elts;
  312.     for (i = 0; i < cmcf->ports->nelts; i++) {

  313.         if (p != port[i].port
  314.             || lsopt->type != port[i].type
  315.             || sa->sa_family != port[i].family)
  316.         {
  317.             continue;
  318.         }

  319.         /* a port is already in the port list */

  320.         return ngx_stream_add_addresses(cf, cscf, &port[i], lsopt);
  321.     }

  322.     /* add a port to the port list */

  323.     port = ngx_array_push(cmcf->ports);
  324.     if (port == NULL) {
  325.         return NGX_ERROR;
  326.     }

  327.     port->family = sa->sa_family;
  328.     port->type = lsopt->type;
  329.     port->port = p;
  330.     port->addrs.elts = NULL;

  331.     return ngx_stream_add_address(cf, cscf, port, lsopt);
  332. }


  333. static ngx_int_t
  334. ngx_stream_add_addresses(ngx_conf_t *cf, ngx_stream_core_srv_conf_t *cscf,
  335.     ngx_stream_conf_port_t *port, ngx_stream_listen_opt_t *lsopt)
  336. {
  337.     ngx_uint_t               i, default_server, proxy_protocol,
  338.                              protocols, protocols_prev;
  339.     ngx_stream_conf_addr_t  *addr;
  340. #if (NGX_STREAM_SSL)
  341.     ngx_uint_t               ssl;
  342. #endif

  343.     /*
  344.      * we cannot compare whole sockaddr struct's as kernel
  345.      * may fill some fields in inherited sockaddr struct's
  346.      */

  347.     addr = port->addrs.elts;

  348.     for (i = 0; i < port->addrs.nelts; i++) {

  349.         if (ngx_cmp_sockaddr(lsopt->sockaddr, lsopt->socklen,
  350.                              addr[i].opt.sockaddr,
  351.                              addr[i].opt.socklen, 0)
  352.             != NGX_OK)
  353.         {
  354.             continue;
  355.         }

  356.         /* the address is already in the address list */

  357.         if (ngx_stream_add_server(cf, cscf, &addr[i]) != NGX_OK) {
  358.             return NGX_ERROR;
  359.         }

  360.         /* preserve default_server bit during listen options overwriting */
  361.         default_server = addr[i].opt.default_server;

  362.         proxy_protocol = lsopt->proxy_protocol || addr[i].opt.proxy_protocol;
  363.         protocols = lsopt->proxy_protocol;
  364.         protocols_prev = addr[i].opt.proxy_protocol;

  365. #if (NGX_STREAM_SSL)
  366.         ssl = lsopt->ssl || addr[i].opt.ssl;
  367.         protocols |= lsopt->ssl << 1;
  368.         protocols_prev |= addr[i].opt.ssl << 1;
  369. #endif

  370.         if (lsopt->set) {

  371.             if (addr[i].opt.set) {
  372.                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  373.                                    "duplicate listen options for %V",
  374.                                    &addr[i].opt.addr_text);
  375.                 return NGX_ERROR;
  376.             }

  377.             addr[i].opt = *lsopt;
  378.         }

  379.         /* check the duplicate "default" server for this address:port */

  380.         if (lsopt->default_server) {

  381.             if (default_server) {
  382.                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  383.                                    "a duplicate default server for %V",
  384.                                    &addr[i].opt.addr_text);
  385.                 return NGX_ERROR;
  386.             }

  387.             default_server = 1;
  388.             addr[i].default_server = cscf;
  389.         }

  390.         /* check for conflicting protocol options */

  391.         if ((protocols | protocols_prev) != protocols_prev) {

  392.             /* options added */

  393.             if ((addr[i].opt.set && !lsopt->set)
  394.                 || addr[i].protocols_changed
  395.                 || (protocols | protocols_prev) != protocols)
  396.             {
  397.                 ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
  398.                                    "protocol options redefined for %V",
  399.                                    &addr[i].opt.addr_text);
  400.             }

  401.             addr[i].protocols = protocols_prev;
  402.             addr[i].protocols_set = 1;
  403.             addr[i].protocols_changed = 1;

  404.         } else if ((protocols_prev | protocols) != protocols) {

  405.             /* options removed */

  406.             if (lsopt->set
  407.                 || (addr[i].protocols_set && protocols != addr[i].protocols))
  408.             {
  409.                 ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
  410.                                    "protocol options redefined for %V",
  411.                                    &addr[i].opt.addr_text);
  412.             }

  413.             addr[i].protocols = protocols;
  414.             addr[i].protocols_set = 1;
  415.             addr[i].protocols_changed = 1;

  416.         } else {

  417.             /* the same options */

  418.             if ((lsopt->set && addr[i].protocols_changed)
  419.                 || (addr[i].protocols_set && protocols != addr[i].protocols))
  420.             {
  421.                 ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
  422.                                    "protocol options redefined for %V",
  423.                                    &addr[i].opt.addr_text);
  424.             }

  425.             addr[i].protocols = protocols;
  426.             addr[i].protocols_set = 1;
  427.         }

  428.         addr[i].opt.default_server = default_server;
  429.         addr[i].opt.proxy_protocol = proxy_protocol;
  430. #if (NGX_STREAM_SSL)
  431.         addr[i].opt.ssl = ssl;
  432. #endif

  433.         return NGX_OK;
  434.     }

  435.     /* add the address to the addresses list that bound to this port */

  436.     return ngx_stream_add_address(cf, cscf, port, lsopt);
  437. }


  438. /*
  439. * add the server address, the server names and the server core module
  440. * configurations to the port list
  441. */

  442. static ngx_int_t
  443. ngx_stream_add_address(ngx_conf_t *cf, ngx_stream_core_srv_conf_t *cscf,
  444.     ngx_stream_conf_port_t *port, ngx_stream_listen_opt_t *lsopt)
  445. {
  446.     ngx_stream_conf_addr_t  *addr;

  447.     if (port->addrs.elts == NULL) {
  448.         if (ngx_array_init(&port->addrs, cf->temp_pool, 4,
  449.                            sizeof(ngx_stream_conf_addr_t))
  450.             != NGX_OK)
  451.         {
  452.             return NGX_ERROR;
  453.         }
  454.     }

  455.     addr = ngx_array_push(&port->addrs);
  456.     if (addr == NULL) {
  457.         return NGX_ERROR;
  458.     }

  459.     addr->opt = *lsopt;
  460.     addr->protocols = 0;
  461.     addr->protocols_set = 0;
  462.     addr->protocols_changed = 0;
  463.     addr->hash.buckets = NULL;
  464.     addr->hash.size = 0;
  465.     addr->wc_head = NULL;
  466.     addr->wc_tail = NULL;
  467. #if (NGX_PCRE)
  468.     addr->nregex = 0;
  469.     addr->regex = NULL;
  470. #endif
  471.     addr->default_server = cscf;
  472.     addr->servers.elts = NULL;

  473.     return ngx_stream_add_server(cf, cscf, addr);
  474. }


  475. /* add the server core module configuration to the address:port */

  476. static ngx_int_t
  477. ngx_stream_add_server(ngx_conf_t *cf, ngx_stream_core_srv_conf_t *cscf,
  478.     ngx_stream_conf_addr_t *addr)
  479. {
  480.     ngx_uint_t                    i;
  481.     ngx_stream_core_srv_conf_t  **server;

  482.     if (addr->servers.elts == NULL) {
  483.         if (ngx_array_init(&addr->servers, cf->temp_pool, 4,
  484.                            sizeof(ngx_stream_core_srv_conf_t *))
  485.             != NGX_OK)
  486.         {
  487.             return NGX_ERROR;
  488.         }

  489.     } else {
  490.         server = addr->servers.elts;
  491.         for (i = 0; i < addr->servers.nelts; i++) {
  492.             if (server[i] == cscf) {
  493.                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  494.                                    "a duplicate listen %V",
  495.                                    &addr->opt.addr_text);
  496.                 return NGX_ERROR;
  497.             }
  498.         }
  499.     }

  500.     server = ngx_array_push(&addr->servers);
  501.     if (server == NULL) {
  502.         return NGX_ERROR;
  503.     }

  504.     *server = cscf;

  505.     return NGX_OK;
  506. }


  507. static ngx_int_t
  508. ngx_stream_optimize_servers(ngx_conf_t *cf, ngx_stream_core_main_conf_t *cmcf,
  509.     ngx_array_t *ports)
  510. {
  511.     ngx_uint_t               p, a;
  512.     ngx_stream_conf_port_t  *port;
  513.     ngx_stream_conf_addr_t  *addr;

  514.     if (ports == NULL) {
  515.         return NGX_OK;
  516.     }

  517.     port = ports->elts;
  518.     for (p = 0; p < ports->nelts; p++) {

  519.         ngx_sort(port[p].addrs.elts, (size_t) port[p].addrs.nelts,
  520.                  sizeof(ngx_stream_conf_addr_t), ngx_stream_cmp_conf_addrs);

  521.         /*
  522.          * check whether all name-based servers have the same
  523.          * configuration as a default server for given address:port
  524.          */

  525.         addr = port[p].addrs.elts;
  526.         for (a = 0; a < port[p].addrs.nelts; a++) {

  527.             if (addr[a].servers.nelts > 1
  528. #if (NGX_PCRE)
  529.                 || addr[a].default_server->captures
  530. #endif
  531.                )
  532.             {
  533.                 if (ngx_stream_server_names(cf, cmcf, &addr[a]) != NGX_OK) {
  534.                     return NGX_ERROR;
  535.                 }
  536.             }
  537.         }

  538.         if (ngx_stream_init_listening(cf, &port[p]) != NGX_OK) {
  539.             return NGX_ERROR;
  540.         }
  541.     }

  542.     return NGX_OK;
  543. }


  544. static ngx_int_t
  545. ngx_stream_server_names(ngx_conf_t *cf, ngx_stream_core_main_conf_t *cmcf,
  546.     ngx_stream_conf_addr_t *addr)
  547. {
  548.     ngx_int_t                     rc;
  549.     ngx_uint_t                    n, s;
  550.     ngx_hash_init_t               hash;
  551.     ngx_hash_keys_arrays_t        ha;
  552.     ngx_stream_server_name_t     *name;
  553.     ngx_stream_core_srv_conf_t  **cscfp;
  554. #if (NGX_PCRE)
  555.     ngx_uint_t                    regex, i;

  556.     regex = 0;
  557. #endif

  558.     ngx_memzero(&ha, sizeof(ngx_hash_keys_arrays_t));

  559.     ha.temp_pool = ngx_create_pool(NGX_DEFAULT_POOL_SIZE, cf->log);
  560.     if (ha.temp_pool == NULL) {
  561.         return NGX_ERROR;
  562.     }

  563.     ha.pool = cf->pool;

  564.     if (ngx_hash_keys_array_init(&ha, NGX_HASH_LARGE) != NGX_OK) {
  565.         goto failed;
  566.     }

  567.     cscfp = addr->servers.elts;

  568.     for (s = 0; s < addr->servers.nelts; s++) {

  569.         name = cscfp[s]->server_names.elts;

  570.         for (n = 0; n < cscfp[s]->server_names.nelts; n++) {

  571. #if (NGX_PCRE)
  572.             if (name[n].regex) {
  573.                 regex++;
  574.                 continue;
  575.             }
  576. #endif

  577.             rc = ngx_hash_add_key(&ha, &name[n].name, name[n].server,
  578.                                   NGX_HASH_WILDCARD_KEY);

  579.             if (rc == NGX_ERROR) {
  580.                 goto failed;
  581.             }

  582.             if (rc == NGX_DECLINED) {
  583.                 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
  584.                               "invalid server name or wildcard \"%V\" on %V",
  585.                               &name[n].name, &addr->opt.addr_text);
  586.                 goto failed;
  587.             }

  588.             if (rc == NGX_BUSY) {
  589.                 ngx_log_error(NGX_LOG_WARN, cf->log, 0,
  590.                               "conflicting server name \"%V\" on %V, ignored",
  591.                               &name[n].name, &addr->opt.addr_text);
  592.             }
  593.         }
  594.     }

  595.     hash.key = ngx_hash_key_lc;
  596.     hash.max_size = cmcf->server_names_hash_max_size;
  597.     hash.bucket_size = cmcf->server_names_hash_bucket_size;
  598.     hash.name = "server_names_hash";
  599.     hash.pool = cf->pool;

  600.     if (ha.keys.nelts) {
  601.         hash.hash = &addr->hash;
  602.         hash.temp_pool = NULL;

  603.         if (ngx_hash_init(&hash, ha.keys.elts, ha.keys.nelts) != NGX_OK) {
  604.             goto failed;
  605.         }
  606.     }

  607.     if (ha.dns_wc_head.nelts) {

  608.         ngx_qsort(ha.dns_wc_head.elts, (size_t) ha.dns_wc_head.nelts,
  609.                   sizeof(ngx_hash_key_t), ngx_stream_cmp_dns_wildcards);

  610.         hash.hash = NULL;
  611.         hash.temp_pool = ha.temp_pool;

  612.         if (ngx_hash_wildcard_init(&hash, ha.dns_wc_head.elts,
  613.                                    ha.dns_wc_head.nelts)
  614.             != NGX_OK)
  615.         {
  616.             goto failed;
  617.         }

  618.         addr->wc_head = (ngx_hash_wildcard_t *) hash.hash;
  619.     }

  620.     if (ha.dns_wc_tail.nelts) {

  621.         ngx_qsort(ha.dns_wc_tail.elts, (size_t) ha.dns_wc_tail.nelts,
  622.                   sizeof(ngx_hash_key_t), ngx_stream_cmp_dns_wildcards);

  623.         hash.hash = NULL;
  624.         hash.temp_pool = ha.temp_pool;

  625.         if (ngx_hash_wildcard_init(&hash, ha.dns_wc_tail.elts,
  626.                                    ha.dns_wc_tail.nelts)
  627.             != NGX_OK)
  628.         {
  629.             goto failed;
  630.         }

  631.         addr->wc_tail = (ngx_hash_wildcard_t *) hash.hash;
  632.     }

  633.     ngx_destroy_pool(ha.temp_pool);

  634. #if (NGX_PCRE)

  635.     if (regex == 0) {
  636.         return NGX_OK;
  637.     }

  638.     addr->nregex = regex;
  639.     addr->regex = ngx_palloc(cf->pool,
  640.                              regex * sizeof(ngx_stream_server_name_t));
  641.     if (addr->regex == NULL) {
  642.         return NGX_ERROR;
  643.     }

  644.     i = 0;

  645.     for (s = 0; s < addr->servers.nelts; s++) {

  646.         name = cscfp[s]->server_names.elts;

  647.         for (n = 0; n < cscfp[s]->server_names.nelts; n++) {
  648.             if (name[n].regex) {
  649.                 addr->regex[i++] = name[n];
  650.             }
  651.         }
  652.     }

  653. #endif

  654.     return NGX_OK;

  655. failed:

  656.     ngx_destroy_pool(ha.temp_pool);

  657.     return NGX_ERROR;
  658. }


  659. static ngx_int_t
  660. ngx_stream_cmp_conf_addrs(const void *one, const void *two)
  661. {
  662.     ngx_stream_conf_addr_t  *first, *second;

  663.     first = (ngx_stream_conf_addr_t *) one;
  664.     second = (ngx_stream_conf_addr_t *) two;

  665.     if (first->opt.wildcard) {
  666.         /* a wildcard address must be the last resort, shift it to the end */
  667.         return 1;
  668.     }

  669.     if (second->opt.wildcard) {
  670.         /* a wildcard address must be the last resort, shift it to the end */
  671.         return -1;
  672.     }

  673.     if (first->opt.bind && !second->opt.bind) {
  674.         /* shift explicit bind()ed addresses to the start */
  675.         return -1;
  676.     }

  677.     if (!first->opt.bind && second->opt.bind) {
  678.         /* shift explicit bind()ed addresses to the start */
  679.         return 1;
  680.     }

  681.     /* do not sort by default */

  682.     return 0;
  683. }


  684. static int ngx_libc_cdecl
  685. ngx_stream_cmp_dns_wildcards(const void *one, const void *two)
  686. {
  687.     ngx_hash_key_t  *first, *second;

  688.     first = (ngx_hash_key_t *) one;
  689.     second = (ngx_hash_key_t *) two;

  690.     return ngx_dns_strcmp(first->key.data, second->key.data);
  691. }


  692. static ngx_int_t
  693. ngx_stream_init_listening(ngx_conf_t *cf, ngx_stream_conf_port_t *port)
  694. {
  695.     ngx_uint_t               i, last, bind_wildcard;
  696.     ngx_listening_t         *ls;
  697.     ngx_stream_port_t       *stport;
  698.     ngx_stream_conf_addr_t  *addr;

  699.     addr = port->addrs.elts;
  700.     last = port->addrs.nelts;

  701.     /*
  702.      * If there is a binding to an "*:port" then we need to bind() to
  703.      * the "*:port" only and ignore other implicit bindings.  The bindings
  704.      * have been already sorted: explicit bindings are on the start, then
  705.      * implicit bindings go, and wildcard binding is in the end.
  706.      */

  707.     if (addr[last - 1].opt.wildcard) {
  708.         addr[last - 1].opt.bind = 1;
  709.         bind_wildcard = 1;

  710.     } else {
  711.         bind_wildcard = 0;
  712.     }

  713.     i = 0;

  714.     while (i < last) {

  715.         if (bind_wildcard && !addr[i].opt.bind) {
  716.             i++;
  717.             continue;
  718.         }

  719.         ls = ngx_stream_add_listening(cf, &addr[i]);
  720.         if (ls == NULL) {
  721.             return NGX_ERROR;
  722.         }

  723.         stport = ngx_pcalloc(cf->pool, sizeof(ngx_stream_port_t));
  724.         if (stport == NULL) {
  725.             return NGX_ERROR;
  726.         }

  727.         ls->servers = stport;

  728.         stport->naddrs = i + 1;

  729.         switch (ls->sockaddr->sa_family) {

  730. #if (NGX_HAVE_INET6)
  731.         case AF_INET6:
  732.             if (ngx_stream_add_addrs6(cf, stport, addr) != NGX_OK) {
  733.                 return NGX_ERROR;
  734.             }
  735.             break;
  736. #endif
  737.         default: /* AF_INET */
  738.             if (ngx_stream_add_addrs(cf, stport, addr) != NGX_OK) {
  739.                 return NGX_ERROR;
  740.             }
  741.             break;
  742.         }

  743.         addr++;
  744.         last--;
  745.     }

  746.     return NGX_OK;
  747. }


  748. static ngx_listening_t *
  749. ngx_stream_add_listening(ngx_conf_t *cf, ngx_stream_conf_addr_t *addr)
  750. {
  751.     ngx_listening_t             *ls;
  752.     ngx_stream_core_srv_conf_t  *cscf;

  753.     ls = ngx_create_listening(cf, addr->opt.sockaddr, addr->opt.socklen);
  754.     if (ls == NULL) {
  755.         return NULL;
  756.     }

  757.     ls->addr_ntop = 1;

  758.     ls->handler = ngx_stream_init_connection;

  759.     ls->pool_size = 256;

  760.     cscf = addr->default_server;

  761.     ls->logp = cscf->error_log;
  762.     ls->log.data = &ls->addr_text;
  763.     ls->log.handler = ngx_accept_log_error;

  764.     ls->type = addr->opt.type;
  765.     ls->backlog = addr->opt.backlog;
  766.     ls->rcvbuf = addr->opt.rcvbuf;
  767.     ls->sndbuf = addr->opt.sndbuf;

  768.     ls->keepalive = addr->opt.so_keepalive;
  769. #if (NGX_HAVE_KEEPALIVE_TUNABLE)
  770.     ls->keepidle = addr->opt.tcp_keepidle;
  771.     ls->keepintvl = addr->opt.tcp_keepintvl;
  772.     ls->keepcnt = addr->opt.tcp_keepcnt;
  773. #endif

  774. #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
  775.     ls->accept_filter = addr->opt.accept_filter;
  776. #endif

  777. #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
  778.     ls->deferred_accept = addr->opt.deferred_accept;
  779. #endif

  780. #if (NGX_HAVE_INET6)
  781.     ls->ipv6only = addr->opt.ipv6only;
  782. #endif

  783. #if (NGX_HAVE_SETFIB)
  784.     ls->setfib = addr->opt.setfib;
  785. #endif

  786. #if (NGX_HAVE_TCP_FASTOPEN)
  787.     ls->fastopen = addr->opt.fastopen;
  788. #endif

  789. #if (NGX_HAVE_REUSEPORT)
  790.     ls->reuseport = addr->opt.reuseport;
  791. #endif

  792.     ls->wildcard = addr->opt.wildcard;

  793.     return ls;
  794. }


  795. static ngx_int_t
  796. ngx_stream_add_addrs(ngx_conf_t *cf, ngx_stream_port_t *stport,
  797.     ngx_stream_conf_addr_t *addr)
  798. {
  799.     ngx_uint_t                   i;
  800.     struct sockaddr_in          *sin;
  801.     ngx_stream_in_addr_t        *addrs;
  802.     ngx_stream_virtual_names_t  *vn;

  803.     stport->addrs = ngx_pcalloc(cf->pool,
  804.                                 stport->naddrs * sizeof(ngx_stream_in_addr_t));
  805.     if (stport->addrs == NULL) {
  806.         return NGX_ERROR;
  807.     }

  808.     addrs = stport->addrs;

  809.     for (i = 0; i < stport->naddrs; i++) {

  810.         sin = (struct sockaddr_in *) addr[i].opt.sockaddr;
  811.         addrs[i].addr = sin->sin_addr.s_addr;
  812.         addrs[i].conf.default_server = addr[i].default_server;
  813. #if (NGX_STREAM_SSL)
  814.         addrs[i].conf.ssl = addr[i].opt.ssl;
  815. #endif
  816.         addrs[i].conf.proxy_protocol = addr[i].opt.proxy_protocol;

  817.         if (addr[i].hash.buckets == NULL
  818.             && (addr[i].wc_head == NULL
  819.                 || addr[i].wc_head->hash.buckets == NULL)
  820.             && (addr[i].wc_tail == NULL
  821.                 || addr[i].wc_tail->hash.buckets == NULL)
  822. #if (NGX_PCRE)
  823.             && addr[i].nregex == 0
  824. #endif
  825.             )
  826.         {
  827.             continue;
  828.         }

  829.         vn = ngx_palloc(cf->pool, sizeof(ngx_stream_virtual_names_t));
  830.         if (vn == NULL) {
  831.             return NGX_ERROR;
  832.         }

  833.         addrs[i].conf.virtual_names = vn;

  834.         vn->names.hash = addr[i].hash;
  835.         vn->names.wc_head = addr[i].wc_head;
  836.         vn->names.wc_tail = addr[i].wc_tail;
  837. #if (NGX_PCRE)
  838.         vn->nregex = addr[i].nregex;
  839.         vn->regex = addr[i].regex;
  840. #endif
  841.     }

  842.     return NGX_OK;
  843. }


  844. #if (NGX_HAVE_INET6)

  845. static ngx_int_t
  846. ngx_stream_add_addrs6(ngx_conf_t *cf, ngx_stream_port_t *stport,
  847.     ngx_stream_conf_addr_t *addr)
  848. {
  849.     ngx_uint_t                   i;
  850.     struct sockaddr_in6         *sin6;
  851.     ngx_stream_in6_addr_t       *addrs6;
  852.     ngx_stream_virtual_names_t  *vn;

  853.     stport->addrs = ngx_pcalloc(cf->pool,
  854.                                 stport->naddrs * sizeof(ngx_stream_in6_addr_t));
  855.     if (stport->addrs == NULL) {
  856.         return NGX_ERROR;
  857.     }

  858.     addrs6 = stport->addrs;

  859.     for (i = 0; i < stport->naddrs; i++) {

  860.         sin6 = (struct sockaddr_in6 *) addr[i].opt.sockaddr;
  861.         addrs6[i].addr6 = sin6->sin6_addr;
  862.         addrs6[i].conf.default_server = addr[i].default_server;
  863. #if (NGX_STREAM_SSL)
  864.         addrs6[i].conf.ssl = addr[i].opt.ssl;
  865. #endif
  866.         addrs6[i].conf.proxy_protocol = addr[i].opt.proxy_protocol;

  867.         if (addr[i].hash.buckets == NULL
  868.             && (addr[i].wc_head == NULL
  869.                 || addr[i].wc_head->hash.buckets == NULL)
  870.             && (addr[i].wc_tail == NULL
  871.                 || addr[i].wc_tail->hash.buckets == NULL)
  872. #if (NGX_PCRE)
  873.             && addr[i].nregex == 0
  874. #endif
  875.             )
  876.         {
  877.             continue;
  878.         }

  879.         vn = ngx_palloc(cf->pool, sizeof(ngx_stream_virtual_names_t));
  880.         if (vn == NULL) {
  881.             return NGX_ERROR;
  882.         }

  883.         addrs6[i].conf.virtual_names = vn;

  884.         vn->names.hash = addr[i].hash;
  885.         vn->names.wc_head = addr[i].wc_head;
  886.         vn->names.wc_tail = addr[i].wc_tail;
  887. #if (NGX_PCRE)
  888.         vn->nregex = addr[i].nregex;
  889.         vn->regex = addr[i].regex;
  890. #endif
  891.     }

  892.     return NGX_OK;
  893. }

  894. #endif