src/core/ngx_connection.c - nginx-1.31.9 nginx/ @ 2a3a19c6f

Global variables defined

Functions defined

Source code


  1. /*
  2. * Copyright (C) Igor Sysoev
  3. * Copyright (C) Nginx, Inc.
  4. */


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


  8. ‌ngx_os_io_t  ngx_io;


  9. static void ngx_drain_connections(ngx_cycle_t *cycle);


  10. ngx_listening_t *
  11. ‌ngx_create_listening(ngx_conf_t *cf, struct sockaddr *sockaddr,
  12.     socklen_t socklen)
  13. {
  14.     size_t            len;
  15.     ngx_listening_t  *ls;
  16.     struct sockaddr  *sa;
  17.     u_char            text[NGX_SOCKADDR_STRLEN];

  18.     ls = ngx_array_push(&cf->cycle->listening);
  19.     if (ls == NULL) {
  20.         return NULL;
  21.     }

  22.     ngx_memzero(ls, sizeof(ngx_listening_t));

  23.     sa = ngx_palloc(cf->pool, socklen);
  24.     if (sa == NULL) {
  25.         return NULL;
  26.     }

  27.     ngx_memcpy(sa, sockaddr, socklen);

  28.     ls->sockaddr = sa;
  29.     ls->socklen = socklen;

  30.     len = ngx_sock_ntop(sa, socklen, text, NGX_SOCKADDR_STRLEN, 1);
  31.     ls->addr_text.len = len;

  32.     switch (ls->sockaddr->sa_family) {
  33. #if (NGX_HAVE_INET6)
  34.     case AF_INET6:
  35.         ls->addr_text_max_len = NGX_INET6_ADDRSTRLEN;
  36.         break;
  37. #endif
  38. #if (NGX_HAVE_UNIX_DOMAIN)
  39.     case AF_UNIX:
  40.         ls->addr_text_max_len = NGX_UNIX_ADDRSTRLEN;
  41.         len++;
  42.         break;
  43. #endif
  44.     case AF_INET:
  45.         ls->addr_text_max_len = NGX_INET_ADDRSTRLEN;
  46.         break;
  47.     default:
  48.         ls->addr_text_max_len = NGX_SOCKADDR_STRLEN;
  49.         break;
  50.     }

  51.     ls->addr_text.data = ngx_pnalloc(cf->pool, len);
  52.     if (ls->addr_text.data == NULL) {
  53.         return NULL;
  54.     }

  55.     ngx_memcpy(ls->addr_text.data, text, len);

  56. #if !(NGX_WIN32)
  57.     ngx_rbtree_init(&ls->rbtree, &ls->sentinel, ngx_udp_rbtree_insert_value);
  58. #endif

  59.     ls->fd = (ngx_socket_t) -1;
  60.     ls->type = SOCK_STREAM;

  61.     ls->backlog = NGX_LISTEN_BACKLOG;
  62.     ls->rcvbuf = -1;
  63.     ls->sndbuf = -1;

  64. #if (NGX_HAVE_SETFIB)
  65.     ls->setfib = -1;
  66. #endif

  67. #if (NGX_HAVE_TCP_FASTOPEN)
  68.     ls->fastopen = -1;
  69. #endif

  70.     return ls;
  71. }


  72. ngx_int_t
  73. ‌ngx_clone_listening(ngx_cycle_t *cycle, ngx_listening_t *ls)
  74. {
  75. #if (NGX_HAVE_REUSEPORT)

  76.     ngx_int_t         n;
  77.     ngx_core_conf_t  *ccf;
  78.     ngx_listening_t   ols;

  79.     if (!ls->reuseport || ls->worker != 0) {
  80.         return NGX_OK;
  81.     }

  82.     ols = *ls;

  83.     ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);

  84.     for (n = 1; n < ccf->worker_processes; n++) {

  85.         /* create a socket for each worker process */

  86.         ls = ngx_array_push(&cycle->listening);
  87.         if (ls == NULL) {
  88.             return NGX_ERROR;
  89.         }

  90.         *ls = ols;
  91.         ls->worker = n;
  92.     }

  93. #endif

  94.     return NGX_OK;
  95. }


  96. ngx_int_t
  97. ‌ngx_set_inherited_sockets(ngx_cycle_t *cycle)
  98. {
  99.     size_t                     len;
  100.     ngx_uint_t                 i;
  101.     ngx_listening_t           *ls;
  102.     socklen_t                  olen;
  103. #if (NGX_HAVE_DEFERRED_ACCEPT || NGX_HAVE_TCP_FASTOPEN)
  104.     ngx_err_t                  err;
  105. #endif
  106. #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
  107.     struct accept_filter_arg   af;
  108. #endif
  109. #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
  110.     int                        timeout;
  111. #endif
  112. #if (NGX_HAVE_REUSEPORT)
  113.     int                        reuseport;
  114. #endif

  115.     ls = cycle->listening.elts;
  116.     for (i = 0; i < cycle->listening.nelts; i++) {

  117.         ls[i].sockaddr = ngx_palloc(cycle->pool, sizeof(ngx_sockaddr_t));
  118.         if (ls[i].sockaddr == NULL) {
  119.             return NGX_ERROR;
  120.         }

  121.         ls[i].socklen = sizeof(ngx_sockaddr_t);
  122.         if (getsockname(ls[i].fd, ls[i].sockaddr, &ls[i].socklen) == -1) {
  123.             ngx_log_error(NGX_LOG_CRIT, cycle->log, ngx_socket_errno,
  124.                           "getsockname() of the inherited "
  125.                           "socket #%d failed", ls[i].fd);
  126.             ls[i].ignore = 1;
  127.             continue;
  128.         }

  129.         if (ls[i].socklen > (socklen_t) sizeof(ngx_sockaddr_t)) {
  130.             ls[i].socklen = sizeof(ngx_sockaddr_t);
  131.         }

  132.         switch (ls[i].sockaddr->sa_family) {

  133. #if (NGX_HAVE_INET6)
  134.         case AF_INET6:
  135.             ls[i].addr_text_max_len = NGX_INET6_ADDRSTRLEN;
  136.             len = NGX_INET6_ADDRSTRLEN + sizeof("[]:65535") - 1;
  137.             break;
  138. #endif

  139. #if (NGX_HAVE_UNIX_DOMAIN)
  140.         case AF_UNIX:
  141.             ls[i].addr_text_max_len = NGX_UNIX_ADDRSTRLEN;
  142.             len = NGX_UNIX_ADDRSTRLEN;
  143.             break;
  144. #endif

  145.         case AF_INET:
  146.             ls[i].addr_text_max_len = NGX_INET_ADDRSTRLEN;
  147.             len = NGX_INET_ADDRSTRLEN + sizeof(":65535") - 1;
  148.             break;

  149.         default:
  150.             ngx_log_error(NGX_LOG_CRIT, cycle->log, ngx_socket_errno,
  151.                           "the inherited socket #%d has "
  152.                           "an unsupported protocol family", ls[i].fd);
  153.             ls[i].ignore = 1;
  154.             continue;
  155.         }

  156.         ls[i].addr_text.data = ngx_pnalloc(cycle->pool, len);
  157.         if (ls[i].addr_text.data == NULL) {
  158.             return NGX_ERROR;
  159.         }

  160.         len = ngx_sock_ntop(ls[i].sockaddr, ls[i].socklen,
  161.                             ls[i].addr_text.data, len, 1);
  162.         if (len == 0) {
  163.             return NGX_ERROR;
  164.         }

  165.         ls[i].addr_text.len = len;

  166.         ls[i].backlog = NGX_LISTEN_BACKLOG;

  167.         olen = sizeof(int);

  168.         if (getsockopt(ls[i].fd, SOL_SOCKET, SO_TYPE, (void *) &ls[i].type,
  169.                        &olen)
  170.             == -1)
  171.         {
  172.             ngx_log_error(NGX_LOG_CRIT, cycle->log, ngx_socket_errno,
  173.                           "getsockopt(SO_TYPE) %V failed", &ls[i].addr_text);
  174.             ls[i].ignore = 1;
  175.             continue;
  176.         }

  177.         olen = sizeof(int);

  178.         if (getsockopt(ls[i].fd, SOL_SOCKET, SO_RCVBUF, (void *) &ls[i].rcvbuf,
  179.                        &olen)
  180.             == -1)
  181.         {
  182.             ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  183.                           "getsockopt(SO_RCVBUF) %V failed, ignored",
  184.                           &ls[i].addr_text);

  185.             ls[i].rcvbuf = -1;
  186.         }

  187.         olen = sizeof(int);

  188.         if (getsockopt(ls[i].fd, SOL_SOCKET, SO_SNDBUF, (void *) &ls[i].sndbuf,
  189.                        &olen)
  190.             == -1)
  191.         {
  192.             ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  193.                           "getsockopt(SO_SNDBUF) %V failed, ignored",
  194.                           &ls[i].addr_text);

  195.             ls[i].sndbuf = -1;
  196.         }

  197. #if 0
  198.         /* SO_SETFIB is currently a set only option */

  199. #if (NGX_HAVE_SETFIB)

  200.         olen = sizeof(int);

  201.         if (getsockopt(ls[i].fd, SOL_SOCKET, SO_SETFIB,
  202.                        (void *) &ls[i].setfib, &olen)
  203.             == -1)
  204.         {
  205.             ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  206.                           "getsockopt(SO_SETFIB) %V failed, ignored",
  207.                           &ls[i].addr_text);

  208.             ls[i].setfib = -1;
  209.         }

  210. #endif
  211. #endif

  212. #if (NGX_HAVE_REUSEPORT)

  213.         reuseport = 0;
  214.         olen = sizeof(int);

  215. #ifdef SO_REUSEPORT_LB

  216.         if (getsockopt(ls[i].fd, SOL_SOCKET, SO_REUSEPORT_LB,
  217.                        (void *) &reuseport, &olen)
  218.             == -1)
  219.         {
  220.             ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  221.                           "getsockopt(SO_REUSEPORT_LB) %V failed, ignored",
  222.                           &ls[i].addr_text);

  223.         } else {
  224.             ls[i].reuseport = reuseport ? 1 : 0;
  225.         }

  226. #else

  227.         if (getsockopt(ls[i].fd, SOL_SOCKET, SO_REUSEPORT,
  228.                        (void *) &reuseport, &olen)
  229.             == -1)
  230.         {
  231.             ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  232.                           "getsockopt(SO_REUSEPORT) %V failed, ignored",
  233.                           &ls[i].addr_text);

  234.         } else {
  235.             ls[i].reuseport = reuseport ? 1 : 0;
  236.         }
  237. #endif

  238. #endif

  239.         if (ls[i].type != SOCK_STREAM) {
  240.             continue;
  241.         }

  242. #ifdef SO_PROTOCOL

  243.         olen = sizeof(int);

  244.         if (getsockopt(ls[i].fd, SOL_SOCKET, SO_PROTOCOL,
  245.                        (void *) &ls[i].protocol, &olen)
  246.             == -1)
  247.         {
  248.             ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  249.                           "getsockopt(SO_PROTOCOL) %V failed, ignored",
  250.                           &ls[i].addr_text);
  251.             ls[i].protocol = 0;

  252.         } else if (ls[i].protocol == IPPROTO_TCP) {
  253.             ls[i].protocol = 0;
  254.         }

  255. #endif

  256. #if (NGX_HAVE_TCP_FASTOPEN)

  257.         olen = sizeof(int);

  258.         if (getsockopt(ls[i].fd, IPPROTO_TCP, TCP_FASTOPEN,
  259.                        (void *) &ls[i].fastopen, &olen)
  260.             == -1)
  261.         {
  262.             err = ngx_socket_errno;

  263.             if (err != NGX_EOPNOTSUPP && err != NGX_ENOPROTOOPT
  264.                 && err != NGX_EINVAL)
  265.             {
  266.                 ngx_log_error(NGX_LOG_NOTICE, cycle->log, err,
  267.                               "getsockopt(TCP_FASTOPEN) %V failed, ignored",
  268.                               &ls[i].addr_text);
  269.             }

  270.             ls[i].fastopen = -1;
  271.         }

  272. #endif

  273. #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)

  274.         ngx_memzero(&af, sizeof(struct accept_filter_arg));
  275.         olen = sizeof(struct accept_filter_arg);

  276.         if (getsockopt(ls[i].fd, SOL_SOCKET, SO_ACCEPTFILTER, &af, &olen)
  277.             == -1)
  278.         {
  279.             err = ngx_socket_errno;

  280.             if (err == NGX_EINVAL) {
  281.                 continue;
  282.             }

  283.             ngx_log_error(NGX_LOG_NOTICE, cycle->log, err,
  284.                           "getsockopt(SO_ACCEPTFILTER) for %V failed, ignored",
  285.                           &ls[i].addr_text);
  286.             continue;
  287.         }

  288.         if (olen < sizeof(struct accept_filter_arg) || af.af_name[0] == '\0') {
  289.             continue;
  290.         }

  291.         ls[i].accept_filter = ngx_palloc(cycle->pool, 16);
  292.         if (ls[i].accept_filter == NULL) {
  293.             return NGX_ERROR;
  294.         }

  295.         (void) ngx_cpystrn((u_char *) ls[i].accept_filter,
  296.                            (u_char *) af.af_name, 16);
  297. #endif

  298. #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)

  299.         timeout = 0;
  300.         olen = sizeof(int);

  301.         if (getsockopt(ls[i].fd, IPPROTO_TCP, TCP_DEFER_ACCEPT, &timeout, &olen)
  302.             == -1)
  303.         {
  304.             err = ngx_socket_errno;

  305.             if (err == NGX_EOPNOTSUPP) {
  306.                 continue;
  307.             }

  308.             ngx_log_error(NGX_LOG_NOTICE, cycle->log, err,
  309.                           "getsockopt(TCP_DEFER_ACCEPT) for %V failed, ignored",
  310.                           &ls[i].addr_text);
  311.             continue;
  312.         }

  313.         if (olen < sizeof(int) || timeout == 0) {
  314.             continue;
  315.         }

  316.         ls[i].deferred_accept = 1;
  317. #endif
  318.     }

  319.     return NGX_OK;
  320. }


  321. ngx_int_t
  322. ‌ngx_open_listening_sockets(ngx_cycle_t *cycle)
  323. {
  324.     int               reuseaddr;
  325.     ngx_uint_t        i, tries, failed;
  326.     ngx_err_t         err;
  327.     ngx_log_t        *log;
  328.     ngx_socket_t      s;
  329.     ngx_listening_t  *ls;

  330.     reuseaddr = 1;
  331. #if (NGX_SUPPRESS_WARN)
  332.     failed = 0;
  333. #endif

  334.     log = cycle->log;

  335.     /* TODO: configurable try number */

  336.     for (tries = 5; tries; tries--) {
  337.         failed = 0;

  338.         /* for each listening socket */

  339.         ls = cycle->listening.elts;
  340.         for (i = 0; i < cycle->listening.nelts; i++) {

  341.             if (ls[i].ignore) {
  342.                 continue;
  343.             }

  344. #if (NGX_HAVE_REUSEPORT)

  345.             if (ls[i].add_reuseport || ls[i].change_protocol) {

  346.                 /*
  347.                  * to allow transition from a socket without SO_REUSEPORT
  348.                  * to multiple sockets with SO_REUSEPORT, we have to set
  349.                  * SO_REUSEPORT on the old socket before opening new ones
  350.                  *
  351.                  * to allow transition between different socket protocols
  352.                  * (e.g. IPPROTO_MPTCP), SO_REUSEPORT is set on both old
  353.                  * and new sockets
  354.                  */

  355.                 int  reuseport = 1;

  356. #ifdef SO_REUSEPORT_LB

  357.                 if (setsockopt(ls[i].fd, SOL_SOCKET, SO_REUSEPORT_LB,
  358.                                (const void *) &reuseport, sizeof(int))
  359.                     == -1)
  360.                 {
  361.                     ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  362.                                   "setsockopt(SO_REUSEPORT_LB) %V failed, "
  363.                                   "ignored",
  364.                                   &ls[i].addr_text);
  365.                 }

  366. #else

  367.                 if (setsockopt(ls[i].fd, SOL_SOCKET, SO_REUSEPORT,
  368.                                (const void *) &reuseport, sizeof(int))
  369.                     == -1)
  370.                 {
  371.                     ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  372.                                   "setsockopt(SO_REUSEPORT) %V failed, ignored",
  373.                                   &ls[i].addr_text);
  374.                 }
  375. #endif

  376.                 ls[i].add_reuseport = 0;
  377.             }
  378. #endif

  379.             if (ls[i].fd != (ngx_socket_t) -1 && !ls[i].change_protocol) {
  380.                 continue;
  381.             }

  382.             if (ls[i].inherited) {

  383.                 /* TODO: close on exit */
  384.                 /* TODO: nonblocking */
  385.                 /* TODO: deferred accept */

  386.                 continue;
  387.             }

  388.             s = ngx_socket(ls[i].sockaddr->sa_family, ls[i].type,
  389.                            ls[i].protocol);

  390.             if (s == (ngx_socket_t) -1) {
  391.                 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
  392.                               ngx_socket_n " %V failed", &ls[i].addr_text);
  393.                 return NGX_ERROR;
  394.             }

  395.             if (ls[i].type != SOCK_DGRAM || !ngx_test_config) {

  396.                 if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
  397.                                (const void *) &reuseaddr, sizeof(int))
  398.                     == -1)
  399.                 {
  400.                     ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
  401.                                   "setsockopt(SO_REUSEADDR) %V failed",
  402.                                   &ls[i].addr_text);

  403.                     if (ngx_close_socket(s) == -1) {
  404.                         ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
  405.                                       ngx_close_socket_n " %V failed",
  406.                                       &ls[i].addr_text);
  407.                     }

  408.                     return NGX_ERROR;
  409.                 }
  410.             }

  411. #if (NGX_HAVE_REUSEPORT)

  412.             if ((ls[i].reuseport || ls[i].change_protocol)
  413.                 && !ngx_test_config)
  414.             {
  415.                 int  reuseport;

  416.                 reuseport = 1;

  417. #ifdef SO_REUSEPORT_LB

  418.                 if (setsockopt(s, SOL_SOCKET, SO_REUSEPORT_LB,
  419.                                (const void *) &reuseport, sizeof(int))
  420.                     == -1)
  421.                 {
  422.                     ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
  423.                                   "setsockopt(SO_REUSEPORT_LB) %V failed",
  424.                                   &ls[i].addr_text);

  425.                     if (ngx_close_socket(s) == -1) {
  426.                         ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
  427.                                       ngx_close_socket_n " %V failed",
  428.                                       &ls[i].addr_text);
  429.                     }

  430.                     return NGX_ERROR;
  431.                 }

  432. #else

  433.                 if (setsockopt(s, SOL_SOCKET, SO_REUSEPORT,
  434.                                (const void *) &reuseport, sizeof(int))
  435.                     == -1)
  436.                 {
  437.                     ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
  438.                                   "setsockopt(SO_REUSEPORT) %V failed",
  439.                                   &ls[i].addr_text);

  440.                     if (ngx_close_socket(s) == -1) {
  441.                         ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
  442.                                       ngx_close_socket_n " %V failed",
  443.                                       &ls[i].addr_text);
  444.                     }

  445.                     return NGX_ERROR;
  446.                 }
  447. #endif
  448.             }
  449. #endif

  450. #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)

  451.             if (ls[i].sockaddr->sa_family == AF_INET6) {
  452.                 int  ipv6only;

  453.                 ipv6only = ls[i].ipv6only;

  454.                 if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY,
  455.                                (const void *) &ipv6only, sizeof(int))
  456.                     == -1)
  457.                 {
  458.                     ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
  459.                                   "setsockopt(IPV6_V6ONLY) %V failed, ignored",
  460.                                   &ls[i].addr_text);
  461.                 }
  462.             }
  463. #endif
  464.             /* TODO: close on exit */

  465.             if (ngx_nonblocking(s) == -1) {
  466.                 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
  467.                               ngx_nonblocking_n " %V failed",
  468.                               &ls[i].addr_text);

  469.                 if (ngx_close_socket(s) == -1) {
  470.                     ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
  471.                                   ngx_close_socket_n " %V failed",
  472.                                   &ls[i].addr_text);
  473.                 }

  474.                 return NGX_ERROR;
  475.             }

  476.             ngx_log_debug2(NGX_LOG_DEBUG_CORE, log, 0,
  477.                            "bind() %V #%d ", &ls[i].addr_text, s);

  478.             if (bind(s, ls[i].sockaddr, ls[i].socklen) == -1) {
  479.                 err = ngx_socket_errno;

  480.                 if (err != NGX_EADDRINUSE || !ngx_test_config) {
  481.                     ngx_log_error(NGX_LOG_EMERG, log, err,
  482.                                   "bind() to %V failed", &ls[i].addr_text);
  483.                 }

  484.                 if (ngx_close_socket(s) == -1) {
  485.                     ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
  486.                                   ngx_close_socket_n " %V failed",
  487.                                   &ls[i].addr_text);
  488.                 }

  489.                 if (err != NGX_EADDRINUSE) {
  490.                     return NGX_ERROR;
  491.                 }

  492.                 if (!ngx_test_config) {
  493.                     failed = 1;
  494.                 }

  495.                 continue;
  496.             }

  497. #if (NGX_HAVE_UNIX_DOMAIN)

  498.             if (ls[i].sockaddr->sa_family == AF_UNIX) {
  499.                 mode_t   mode;
  500.                 u_char  *name;

  501.                 name = ls[i].addr_text.data + sizeof("unix:") - 1;
  502.                 mode = (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);

  503.                 if (chmod((char *) name, mode) == -1) {
  504.                     ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
  505.                                   "chmod() \"%s\" failed", name);
  506.                 }

  507.                 if (ngx_test_config) {
  508.                     if (ngx_delete_file(name) == NGX_FILE_ERROR) {
  509.                         ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
  510.                                       ngx_delete_file_n " %s failed", name);
  511.                     }
  512.                 }
  513.             }
  514. #endif

  515.             if (ls[i].type != SOCK_STREAM) {
  516.                 ls[i].fd = s;
  517.                 ls[i].open = 1;
  518.                 continue;
  519.             }

  520.             if (listen(s, ls[i].backlog) == -1) {
  521.                 err = ngx_socket_errno;

  522.                 /*
  523.                  * on OpenVZ after suspend/resume EADDRINUSE
  524.                  * may be returned by listen() instead of bind(), see
  525.                  * https://bugs.openvz.org/browse/OVZ-5587
  526.                  */

  527.                 if (err != NGX_EADDRINUSE || !ngx_test_config) {
  528.                     ngx_log_error(NGX_LOG_EMERG, log, err,
  529.                                   "listen() to %V, backlog %d failed",
  530.                                   &ls[i].addr_text, ls[i].backlog);
  531.                 }

  532.                 if (ngx_close_socket(s) == -1) {
  533.                     ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
  534.                                   ngx_close_socket_n " %V failed",
  535.                                   &ls[i].addr_text);
  536.                 }

  537.                 if (err != NGX_EADDRINUSE) {
  538.                     return NGX_ERROR;
  539.                 }

  540.                 if (!ngx_test_config) {
  541.                     failed = 1;
  542.                 }

  543.                 continue;
  544.             }

  545.             ls[i].listen = 1;

  546.             ls[i].fd = s;
  547.             ls[i].open = 1;
  548.         }

  549.         if (!failed) {
  550.             break;
  551.         }

  552.         /* TODO: delay configurable */

  553.         ngx_log_error(NGX_LOG_NOTICE, log, 0,
  554.                       "try again to bind() after 500ms");

  555.         ngx_msleep(500);
  556.     }

  557.     if (failed) {
  558.         ngx_log_error(NGX_LOG_EMERG, log, 0, "still could not bind()");
  559.         return NGX_ERROR;
  560.     }

  561.     return NGX_OK;
  562. }


  563. void
  564. ‌ngx_configure_listening_sockets(ngx_cycle_t *cycle)
  565. {
  566.     int                        value;
  567.     ngx_uint_t                 i;
  568.     ngx_listening_t           *ls;

  569. #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
  570.     struct accept_filter_arg   af;
  571. #endif

  572.     ls = cycle->listening.elts;
  573.     for (i = 0; i < cycle->listening.nelts; i++) {

  574.         ls[i].log = *ls[i].logp;

  575.         if (ls[i].rcvbuf != -1) {
  576.             if (setsockopt(ls[i].fd, SOL_SOCKET, SO_RCVBUF,
  577.                            (const void *) &ls[i].rcvbuf, sizeof(int))
  578.                 == -1)
  579.             {
  580.                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  581.                               "setsockopt(SO_RCVBUF, %d) %V failed, ignored",
  582.                               ls[i].rcvbuf, &ls[i].addr_text);
  583.             }
  584.         }

  585.         if (ls[i].sndbuf != -1) {
  586.             if (setsockopt(ls[i].fd, SOL_SOCKET, SO_SNDBUF,
  587.                            (const void *) &ls[i].sndbuf, sizeof(int))
  588.                 == -1)
  589.             {
  590.                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  591.                               "setsockopt(SO_SNDBUF, %d) %V failed, ignored",
  592.                               ls[i].sndbuf, &ls[i].addr_text);
  593.             }
  594.         }

  595.         if (ls[i].keepalive) {
  596.             value = (ls[i].keepalive == 1) ? 1 : 0;

  597.             if (setsockopt(ls[i].fd, SOL_SOCKET, SO_KEEPALIVE,
  598.                            (const void *) &value, sizeof(int))
  599.                 == -1)
  600.             {
  601.                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  602.                               "setsockopt(SO_KEEPALIVE, %d) %V failed, ignored",
  603.                               value, &ls[i].addr_text);
  604.             }
  605.         }

  606. #if (NGX_HAVE_KEEPALIVE_TUNABLE)

  607. #if !(NGX_DARWIN)

  608.         if (ls[i].keepidle) {
  609.             value = ls[i].keepidle;

  610. #if (NGX_KEEPALIVE_FACTOR)
  611.             value *= NGX_KEEPALIVE_FACTOR;
  612. #endif

  613.             if (setsockopt(ls[i].fd, IPPROTO_TCP, TCP_KEEPIDLE,
  614.                            (const void *) &value, sizeof(int))
  615.                 == -1)
  616.             {
  617.                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  618.                               "setsockopt(TCP_KEEPIDLE, %d) %V failed, ignored",
  619.                               value, &ls[i].addr_text);
  620.             }
  621.         }

  622. #endif

  623.         if (ls[i].keepintvl) {
  624.             value = ls[i].keepintvl;

  625. #if (NGX_KEEPALIVE_FACTOR)
  626.             value *= NGX_KEEPALIVE_FACTOR;
  627. #endif

  628.             if (setsockopt(ls[i].fd, IPPROTO_TCP, TCP_KEEPINTVL,
  629.                            (const void *) &value, sizeof(int))
  630.                 == -1)
  631.             {
  632.                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  633.                              "setsockopt(TCP_KEEPINTVL, %d) %V failed, ignored",
  634.                              value, &ls[i].addr_text);
  635.             }
  636.         }

  637.         if (ls[i].keepcnt) {
  638.             if (setsockopt(ls[i].fd, IPPROTO_TCP, TCP_KEEPCNT,
  639.                            (const void *) &ls[i].keepcnt, sizeof(int))
  640.                 == -1)
  641.             {
  642.                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  643.                               "setsockopt(TCP_KEEPCNT, %d) %V failed, ignored",
  644.                               ls[i].keepcnt, &ls[i].addr_text);
  645.             }
  646.         }

  647. #endif

  648. #if (NGX_HAVE_SETFIB)
  649.         if (ls[i].setfib != -1) {
  650.             if (setsockopt(ls[i].fd, SOL_SOCKET, SO_SETFIB,
  651.                            (const void *) &ls[i].setfib, sizeof(int))
  652.                 == -1)
  653.             {
  654.                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  655.                               "setsockopt(SO_SETFIB, %d) %V failed, ignored",
  656.                               ls[i].setfib, &ls[i].addr_text);
  657.             }
  658.         }
  659. #endif

  660. #if (NGX_HAVE_TCP_FASTOPEN)
  661.         if (ls[i].fastopen != -1) {
  662.             if (setsockopt(ls[i].fd, IPPROTO_TCP, TCP_FASTOPEN,
  663.                            (const void *) &ls[i].fastopen, sizeof(int))
  664.                 == -1)
  665.             {
  666.                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  667.                               "setsockopt(TCP_FASTOPEN, %d) %V failed, ignored",
  668.                               ls[i].fastopen, &ls[i].addr_text);
  669.             }
  670.         }
  671. #endif

  672. #if 0
  673.         if (1) {
  674.             int tcp_nodelay = 1;

  675.             if (setsockopt(ls[i].fd, IPPROTO_TCP, TCP_NODELAY,
  676.                        (const void *) &tcp_nodelay, sizeof(int))
  677.                 == -1)
  678.             {
  679.                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  680.                               "setsockopt(TCP_NODELAY) %V failed, ignored",
  681.                               &ls[i].addr_text);
  682.             }
  683.         }
  684. #endif

  685.         if (ls[i].listen) {

  686.             /* change backlog via listen() */

  687.             if (listen(ls[i].fd, ls[i].backlog) == -1) {
  688.                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  689.                               "listen() to %V, backlog %d failed, ignored",
  690.                               &ls[i].addr_text, ls[i].backlog);
  691.             }
  692.         }

  693.         /*
  694.          * setting deferred mode should be last operation on socket,
  695.          * because code may prematurely continue cycle on failure
  696.          */

  697. #if (NGX_HAVE_DEFERRED_ACCEPT)

  698. #ifdef SO_ACCEPTFILTER

  699.         if (ls[i].delete_deferred) {
  700.             if (setsockopt(ls[i].fd, SOL_SOCKET, SO_ACCEPTFILTER, NULL, 0)
  701.                 == -1)
  702.             {
  703.                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  704.                               "setsockopt(SO_ACCEPTFILTER, NULL) "
  705.                               "for %V failed, ignored",
  706.                               &ls[i].addr_text);

  707.                 if (ls[i].accept_filter) {
  708.                     ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
  709.                                   "could not change the accept filter "
  710.                                   "to \"%s\" for %V, ignored",
  711.                                   ls[i].accept_filter, &ls[i].addr_text);
  712.                 }

  713.                 continue;
  714.             }

  715.             ls[i].deferred_accept = 0;
  716.         }

  717.         if (ls[i].add_deferred) {
  718.             ngx_memzero(&af, sizeof(struct accept_filter_arg));
  719.             (void) ngx_cpystrn((u_char *) af.af_name,
  720.                                (u_char *) ls[i].accept_filter, 16);

  721.             if (setsockopt(ls[i].fd, SOL_SOCKET, SO_ACCEPTFILTER,
  722.                            &af, sizeof(struct accept_filter_arg))
  723.                 == -1)
  724.             {
  725.                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  726.                               "setsockopt(SO_ACCEPTFILTER, \"%s\") "
  727.                               "for %V failed, ignored",
  728.                               ls[i].accept_filter, &ls[i].addr_text);
  729.                 continue;
  730.             }

  731.             ls[i].deferred_accept = 1;
  732.         }

  733. #endif

  734. #ifdef TCP_DEFER_ACCEPT

  735.         if (ls[i].add_deferred || ls[i].delete_deferred) {

  736.             if (ls[i].add_deferred) {
  737.                 /*
  738.                  * There is no way to find out how long a connection was
  739.                  * in queue (and a connection may bypass deferred queue at all
  740.                  * if syncookies were used), hence we use 1 second timeout
  741.                  * here.
  742.                  */
  743.                 value = 1;

  744.             } else {
  745.                 value = 0;
  746.             }

  747.             if (setsockopt(ls[i].fd, IPPROTO_TCP, TCP_DEFER_ACCEPT,
  748.                            &value, sizeof(int))
  749.                 == -1)
  750.             {
  751.                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  752.                               "setsockopt(TCP_DEFER_ACCEPT, %d) for %V failed, "
  753.                               "ignored",
  754.                               value, &ls[i].addr_text);

  755.                 continue;
  756.             }
  757.         }

  758.         if (ls[i].add_deferred) {
  759.             ls[i].deferred_accept = 1;
  760.         }

  761. #endif

  762. #endif /* NGX_HAVE_DEFERRED_ACCEPT */

  763. #if (NGX_HAVE_IP_RECVDSTADDR)

  764.         if (ls[i].wildcard
  765.             && ls[i].type == SOCK_DGRAM
  766.             && ls[i].sockaddr->sa_family == AF_INET)
  767.         {
  768.             value = 1;

  769.             if (setsockopt(ls[i].fd, IPPROTO_IP, IP_RECVDSTADDR,
  770.                            (const void *) &value, sizeof(int))
  771.                 == -1)
  772.             {
  773.                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  774.                               "setsockopt(IP_RECVDSTADDR) "
  775.                               "for %V failed, ignored",
  776.                               &ls[i].addr_text);
  777.             }
  778.         }

  779. #elif (NGX_HAVE_IP_PKTINFO)

  780.         if (ls[i].wildcard
  781.             && ls[i].type == SOCK_DGRAM
  782.             && ls[i].sockaddr->sa_family == AF_INET)
  783.         {
  784.             value = 1;

  785.             if (setsockopt(ls[i].fd, IPPROTO_IP, IP_PKTINFO,
  786.                            (const void *) &value, sizeof(int))
  787.                 == -1)
  788.             {
  789.                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  790.                               "setsockopt(IP_PKTINFO) "
  791.                               "for %V failed, ignored",
  792.                               &ls[i].addr_text);
  793.             }
  794.         }

  795. #endif

  796. #if (NGX_HAVE_INET6 && NGX_HAVE_IPV6_RECVPKTINFO)

  797.         if (ls[i].wildcard
  798.             && ls[i].type == SOCK_DGRAM
  799.             && ls[i].sockaddr->sa_family == AF_INET6)
  800.         {
  801.             value = 1;

  802.             if (setsockopt(ls[i].fd, IPPROTO_IPV6, IPV6_RECVPKTINFO,
  803.                            (const void *) &value, sizeof(int))
  804.                 == -1)
  805.             {
  806.                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  807.                               "setsockopt(IPV6_RECVPKTINFO) "
  808.                               "for %V failed, ignored",
  809.                               &ls[i].addr_text);
  810.             }
  811.         }

  812. #endif

  813. #if (NGX_HAVE_IP_MTU_DISCOVER)

  814.         if (ls[i].quic && ls[i].sockaddr->sa_family == AF_INET) {
  815.             value = IP_PMTUDISC_DO;

  816.             if (setsockopt(ls[i].fd, IPPROTO_IP, IP_MTU_DISCOVER,
  817.                            (const void *) &value, sizeof(int))
  818.                 == -1)
  819.             {
  820.                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  821.                               "setsockopt(IP_MTU_DISCOVER) "
  822.                               "for %V failed, ignored",
  823.                               &ls[i].addr_text);
  824.             }
  825.         }

  826. #elif (NGX_HAVE_IP_DONTFRAG)

  827.         if (ls[i].quic && ls[i].sockaddr->sa_family == AF_INET) {
  828.             value = 1;

  829.             if (setsockopt(ls[i].fd, IPPROTO_IP, IP_DONTFRAG,
  830.                            (const void *) &value, sizeof(int))
  831.                 == -1)
  832.             {
  833.                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  834.                               "setsockopt(IP_DONTFRAG) "
  835.                               "for %V failed, ignored",
  836.                               &ls[i].addr_text);
  837.             }
  838.         }

  839. #endif

  840. #if (NGX_HAVE_INET6)

  841. #if (NGX_HAVE_IPV6_MTU_DISCOVER)

  842.         if (ls[i].quic && ls[i].sockaddr->sa_family == AF_INET6) {
  843.             value = IPV6_PMTUDISC_DO;

  844.             if (setsockopt(ls[i].fd, IPPROTO_IPV6, IPV6_MTU_DISCOVER,
  845.                            (const void *) &value, sizeof(int))
  846.                 == -1)
  847.             {
  848.                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  849.                               "setsockopt(IPV6_MTU_DISCOVER) "
  850.                               "for %V failed, ignored",
  851.                               &ls[i].addr_text);
  852.             }
  853.         }

  854. #elif (NGX_HAVE_IPV6_DONTFRAG)

  855.         if (ls[i].quic && ls[i].sockaddr->sa_family == AF_INET6) {
  856.             value = 1;

  857.             if (setsockopt(ls[i].fd, IPPROTO_IPV6, IPV6_DONTFRAG,
  858.                            (const void *) &value, sizeof(int))
  859.                 == -1)
  860.             {
  861.                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  862.                               "setsockopt(IPV6_DONTFRAG) "
  863.                               "for %V failed, ignored",
  864.                               &ls[i].addr_text);
  865.             }
  866.         }

  867. #endif

  868. #endif
  869.     }

  870.     return;
  871. }


  872. void
  873. ‌ngx_close_listening_sockets(ngx_cycle_t *cycle)
  874. {
  875.     ngx_uint_t         i;
  876.     ngx_listening_t   *ls;
  877.     ngx_connection_t  *c;

  878.     ngx_accept_mutex_held = 0;
  879.     ngx_use_accept_mutex = 0;

  880.     ls = cycle->listening.elts;
  881.     for (i = 0; i < cycle->listening.nelts; i++) {

  882. #if (NGX_QUIC)
  883.         if (ls[i].quic
  884.             && (!ls[i].reuseport || !ngx_quic_bpf_enabled(cycle)))
  885.         {
  886.             continue;
  887.         }
  888. #endif

  889.         c = ls[i].connection;

  890.         if (c) {
  891.             if (c->read->active) {
  892.                 if (ngx_event_flags & NGX_USE_EPOLL_EVENT) {

  893.                     /*
  894.                      * it seems that Linux-2.6.x OpenVZ sends events
  895.                      * for closed shared listening sockets unless
  896.                      * the events was explicitly deleted
  897.                      */

  898.                     ngx_del_event(c->read, NGX_READ_EVENT, 0);

  899.                 } else {
  900.                     ngx_del_event(c->read, NGX_READ_EVENT, NGX_CLOSE_EVENT);
  901.                 }
  902.             }

  903.             if (c->read->timer_set) {
  904.                 ngx_del_timer(c->read);
  905.             }

  906.             ngx_free_connection(c);

  907.             c->fd = (ngx_socket_t) -1;
  908.         }

  909.         ngx_log_debug2(NGX_LOG_DEBUG_CORE, cycle->log, 0,
  910.                        "close listening %V #%d ", &ls[i].addr_text, ls[i].fd);

  911.         if (ngx_close_socket(ls[i].fd) == -1) {
  912.             ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_socket_errno,
  913.                           ngx_close_socket_n " %V failed", &ls[i].addr_text);
  914.         }

  915. #if (NGX_HAVE_UNIX_DOMAIN)

  916.         if (ls[i].sockaddr->sa_family == AF_UNIX
  917.             && ngx_process <= NGX_PROCESS_MASTER
  918.             && ngx_new_binary == 0
  919.             && (!ls[i].inherited || ngx_getppid() != ngx_parent))
  920.         {
  921.             u_char *name = ls[i].addr_text.data + sizeof("unix:") - 1;

  922.             if (ngx_delete_file(name) == NGX_FILE_ERROR) {
  923.                 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_socket_errno,
  924.                               ngx_delete_file_n " %s failed", name);
  925.             }
  926.         }

  927. #endif

  928.         ls[i].fd = (ngx_socket_t) -1;
  929.     }

  930.     cycle->listening.nelts = 0;
  931. }


  932. ngx_connection_t *
  933. ‌ngx_get_connection(ngx_socket_t s, ngx_log_t *log)
  934. {
  935.     ngx_uint_t         instance;
  936.     ngx_event_t       *rev, *wev;
  937.     ngx_connection_t  *c;

  938.     /* disable warning: Win32 SOCKET is u_int while UNIX socket is int */

  939.     if (ngx_cycle->files && (ngx_uint_t) s >= ngx_cycle->files_n) {
  940.         ngx_log_error(NGX_LOG_ALERT, log, 0,
  941.                       "the new socket has number %d, "
  942.                       "but only %ui files are available",
  943.                       s, ngx_cycle->files_n);
  944.         return NULL;
  945.     }

  946.     ngx_drain_connections((ngx_cycle_t *) ngx_cycle);

  947.     c = ngx_cycle->free_connections;

  948.     if (c == NULL) {
  949.         ngx_log_error(NGX_LOG_ALERT, log, 0,
  950.                       "%ui worker_connections are not enough",
  951.                       ngx_cycle->connection_n);

  952.         return NULL;
  953.     }

  954.     ngx_cycle->free_connections = c->data;
  955.     ngx_cycle->free_connection_n--;

  956.     if (ngx_cycle->files && ngx_cycle->files[s] == NULL) {
  957.         ngx_cycle->files[s] = c;
  958.     }

  959.     rev = c->read;
  960.     wev = c->write;

  961.     ngx_memzero(c, sizeof(ngx_connection_t));

  962.     c->read = rev;
  963.     c->write = wev;
  964.     c->fd = s;
  965.     c->log = log;

  966.     instance = rev->instance;

  967.     ngx_memzero(rev, sizeof(ngx_event_t));
  968.     ngx_memzero(wev, sizeof(ngx_event_t));

  969.     rev->instance = !instance;
  970.     wev->instance = !instance;

  971.     rev->index = NGX_INVALID_INDEX;
  972.     wev->index = NGX_INVALID_INDEX;

  973.     rev->data = c;
  974.     wev->data = c;

  975.     wev->write = 1;

  976.     return c;
  977. }


  978. void
  979. ‌ngx_free_connection(ngx_connection_t *c)
  980. {
  981.     c->data = ngx_cycle->free_connections;
  982.     ngx_cycle->free_connections = c;
  983.     ngx_cycle->free_connection_n++;

  984.     if (ngx_cycle->files && ngx_cycle->files[c->fd] == c) {
  985.         ngx_cycle->files[c->fd] = NULL;
  986.     }
  987. }


  988. void
  989. ‌ngx_close_connection(ngx_connection_t *c)
  990. {
  991.     ngx_err_t     err;
  992.     ngx_uint_t    log_error, level;
  993.     ngx_socket_t  fd;

  994.     if (c->fd == (ngx_socket_t) -1) {
  995.         ngx_log_error(NGX_LOG_ALERT, c->log, 0, "connection already closed");
  996.         return;
  997.     }

  998.     if (c->read->timer_set) {
  999.         ngx_del_timer(c->read);
  1000.     }

  1001.     if (c->write->timer_set) {
  1002.         ngx_del_timer(c->write);
  1003.     }

  1004.     if (!c->shared) {
  1005.         if (ngx_del_conn) {
  1006.             ngx_del_conn(c, NGX_CLOSE_EVENT);

  1007.         } else {
  1008.             if (c->read->active || c->read->disabled) {
  1009.                 ngx_del_event(c->read, NGX_READ_EVENT, NGX_CLOSE_EVENT);
  1010.             }

  1011.             if (c->write->active || c->write->disabled) {
  1012.                 ngx_del_event(c->write, NGX_WRITE_EVENT, NGX_CLOSE_EVENT);
  1013.             }
  1014.         }
  1015.     }

  1016.     if (c->read->posted) {
  1017.         ngx_delete_posted_event(c->read);
  1018.     }

  1019.     if (c->write->posted) {
  1020.         ngx_delete_posted_event(c->write);
  1021.     }

  1022.     c->read->closed = 1;
  1023.     c->write->closed = 1;

  1024.     ngx_reusable_connection(c, 0);

  1025.     log_error = c->log_error;

  1026.     ngx_free_connection(c);

  1027.     fd = c->fd;
  1028.     c->fd = (ngx_socket_t) -1;

  1029.     if (c->shared) {
  1030.         return;
  1031.     }

  1032.     if (ngx_close_socket(fd) == -1) {

  1033.         err = ngx_socket_errno;

  1034.         if (err == NGX_ECONNRESET || err == NGX_ENOTCONN) {

  1035.             switch (log_error) {

  1036.             case NGX_ERROR_INFO:
  1037.                 level = NGX_LOG_INFO;
  1038.                 break;

  1039.             case NGX_ERROR_ERR:
  1040.                 level = NGX_LOG_ERR;
  1041.                 break;

  1042.             default:
  1043.                 level = NGX_LOG_CRIT;
  1044.             }

  1045.         } else {
  1046.             level = NGX_LOG_CRIT;
  1047.         }

  1048.         ngx_log_error(level, c->log, err, ngx_close_socket_n " %d failed", fd);
  1049.     }
  1050. }


  1051. void
  1052. ‌ngx_reusable_connection(ngx_connection_t *c, ngx_uint_t reusable)
  1053. {
  1054.     ngx_log_debug1(NGX_LOG_DEBUG_CORE, c->log, 0,
  1055.                    "reusable connection: %ui", reusable);

  1056.     if (c->reusable) {
  1057.         ngx_queue_remove(&c->queue);
  1058.         ngx_cycle->reusable_connections_n--;

  1059. #if (NGX_STAT_STUB)
  1060.         (void) ngx_atomic_fetch_add(ngx_stat_waiting, -1);
  1061. #endif
  1062.     }

  1063.     c->reusable = reusable;

  1064.     if (reusable) {
  1065.         /* need cast as ngx_cycle is volatile */

  1066.         ngx_queue_insert_head(
  1067.             (ngx_queue_t *) &ngx_cycle->reusable_connections_queue, &c->queue);
  1068.         ngx_cycle->reusable_connections_n++;

  1069. #if (NGX_STAT_STUB)
  1070.         (void) ngx_atomic_fetch_add(ngx_stat_waiting, 1);
  1071. #endif
  1072.     }
  1073. }


  1074. static void
  1075. ‌ngx_drain_connections(ngx_cycle_t *cycle)
  1076. {
  1077.     ngx_uint_t         i, n;
  1078.     ngx_queue_t       *q;
  1079.     ngx_connection_t  *c;

  1080.     if (cycle->free_connection_n > cycle->connection_n / 16
  1081.         || cycle->reusable_connections_n == 0)
  1082.     {
  1083.         return;
  1084.     }

  1085.     if (cycle->connections_reuse_time != ngx_time()) {
  1086.         cycle->connections_reuse_time = ngx_time();

  1087.         ngx_log_error(NGX_LOG_WARN, cycle->log, 0,
  1088.                       "%ui worker_connections are not enough, "
  1089.                       "reusing connections",
  1090.                       cycle->connection_n);
  1091.     }

  1092.     c = NULL;
  1093.     n = ngx_max(ngx_min(32, cycle->reusable_connections_n / 8), 1);

  1094.     for (i = 0; i < n; i++) {
  1095.         if (ngx_queue_empty(&cycle->reusable_connections_queue)) {
  1096.             break;
  1097.         }

  1098.         q = ngx_queue_last(&cycle->reusable_connections_queue);
  1099.         c = ngx_queue_data(q, ngx_connection_t, queue);

  1100.         ngx_log_debug0(NGX_LOG_DEBUG_CORE, c->log, 0,
  1101.                        "reusing connection");

  1102.         c->close = 1;
  1103.         c->read->handler(c->read);
  1104.     }

  1105.     if (cycle->free_connection_n == 0 && c && c->reusable) {

  1106.         /*
  1107.          * if no connections were freed, try to reuse the last
  1108.          * connection again: this should free it as long as
  1109.          * previous reuse moved it to lingering close
  1110.          */

  1111.         ngx_log_debug0(NGX_LOG_DEBUG_CORE, c->log, 0,
  1112.                        "reusing connection again");

  1113.         c->close = 1;
  1114.         c->read->handler(c->read);
  1115.     }
  1116. }


  1117. void
  1118. ‌ngx_close_idle_connections(ngx_cycle_t *cycle)
  1119. {
  1120.     ngx_uint_t         i;
  1121.     ngx_connection_t  *c;

  1122.     c = cycle->connections;

  1123.     for (i = 0; i < cycle->connection_n; i++) {

  1124.         /* THREAD: lock */

  1125.         if (c[i].fd != (ngx_socket_t) -1 && c[i].idle) {
  1126.             c[i].close = 1;
  1127.             c[i].read->handler(c[i].read);
  1128.         }
  1129.     }
  1130. }


  1131. ngx_int_t
  1132. ‌ngx_connection_local_sockaddr(ngx_connection_t *c, ngx_str_t *s,
  1133.     ngx_uint_t port)
  1134. {
  1135.     socklen_t             len;
  1136.     ngx_uint_t            addr;
  1137.     ngx_sockaddr_t        sa;
  1138.     struct sockaddr_in   *sin;
  1139. #if (NGX_HAVE_INET6)
  1140.     ngx_uint_t            i;
  1141.     struct sockaddr_in6  *sin6;
  1142. #endif

  1143.     addr = 0;

  1144.     if (c->local_socklen) {
  1145.         switch (c->local_sockaddr->sa_family) {

  1146. #if (NGX_HAVE_INET6)
  1147.         case AF_INET6:
  1148.             sin6 = (struct sockaddr_in6 *) c->local_sockaddr;

  1149.             for (i = 0; addr == 0 && i < 16; i++) {
  1150.                 addr |= sin6->sin6_addr.s6_addr[i];
  1151.             }

  1152.             break;
  1153. #endif

  1154. #if (NGX_HAVE_UNIX_DOMAIN)
  1155.         case AF_UNIX:
  1156.             addr = 1;
  1157.             break;
  1158. #endif

  1159.         default: /* AF_INET */
  1160.             sin = (struct sockaddr_in *) c->local_sockaddr;
  1161.             addr = sin->sin_addr.s_addr;
  1162.             break;
  1163.         }
  1164.     }

  1165.     if (addr == 0) {

  1166.         len = sizeof(ngx_sockaddr_t);

  1167.         if (getsockname(c->fd, &sa.sockaddr, &len) == -1) {
  1168.             ngx_connection_error(c, ngx_socket_errno, "getsockname() failed");
  1169.             return NGX_ERROR;
  1170.         }

  1171.         c->local_sockaddr = ngx_palloc(c->pool, len);
  1172.         if (c->local_sockaddr == NULL) {
  1173.             return NGX_ERROR;
  1174.         }

  1175.         ngx_memcpy(c->local_sockaddr, &sa, len);

  1176.         c->local_socklen = len;
  1177.     }

  1178.     if (s == NULL) {
  1179.         return NGX_OK;
  1180.     }

  1181.     s->len = ngx_sock_ntop(c->local_sockaddr, c->local_socklen,
  1182.                            s->data, s->len, port);

  1183.     return NGX_OK;
  1184. }


  1185. ngx_int_t
  1186. ‌ngx_tcp_nodelay(ngx_connection_t *c)
  1187. {
  1188.     int  tcp_nodelay;

  1189.     if (c->tcp_nodelay != NGX_TCP_NODELAY_UNSET) {
  1190.         return NGX_OK;
  1191.     }

  1192.     ngx_log_debug0(NGX_LOG_DEBUG_CORE, c->log, 0, "tcp_nodelay");

  1193.     tcp_nodelay = 1;

  1194.     if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY,
  1195.                    (const void *) &tcp_nodelay, sizeof(int))
  1196.         == -1)
  1197.     {
  1198. #if (NGX_SOLARIS)
  1199.         if (c->log_error == NGX_ERROR_INFO) {

  1200.             /* Solaris returns EINVAL if a socket has been shut down */
  1201.             c->log_error = NGX_ERROR_IGNORE_EINVAL;

  1202.             ngx_connection_error(c, ngx_socket_errno,
  1203.                                  "setsockopt(TCP_NODELAY) failed");

  1204.             c->log_error = NGX_ERROR_INFO;

  1205.             return NGX_ERROR;
  1206.         }
  1207. #endif

  1208.         ngx_connection_error(c, ngx_socket_errno,
  1209.                              "setsockopt(TCP_NODELAY) failed");
  1210.         return NGX_ERROR;
  1211.     }

  1212.     c->tcp_nodelay = NGX_TCP_NODELAY_SET;

  1213.     return NGX_OK;
  1214. }


  1215. ngx_int_t
  1216. ‌ngx_connection_error(ngx_connection_t *c, ngx_err_t err, char *text)
  1217. {
  1218.     ngx_uint_t  level;

  1219.     /* Winsock may return NGX_ECONNABORTED instead of NGX_ECONNRESET */

  1220.     if ((err == NGX_ECONNRESET
  1221. #if (NGX_WIN32)
  1222.          || err == NGX_ECONNABORTED
  1223. #endif
  1224.         ) && c->log_error == NGX_ERROR_IGNORE_ECONNRESET)
  1225.     {
  1226.         return 0;
  1227.     }

  1228. #if (NGX_SOLARIS)
  1229.     if (err == NGX_EINVAL && c->log_error == NGX_ERROR_IGNORE_EINVAL) {
  1230.         return 0;
  1231.     }
  1232. #endif

  1233.     if (err == NGX_EMSGSIZE && c->log_error == NGX_ERROR_IGNORE_EMSGSIZE) {
  1234.         return 0;
  1235.     }

  1236. #if (NGX_LINUX)
  1237.     if (err == NGX_EIO && c->ktls_recv) {
  1238.         return 0;
  1239.     }
  1240. #endif

  1241.     if (err == 0
  1242.         || err == NGX_ECONNRESET
  1243. #if (NGX_WIN32)
  1244.         || err == NGX_ECONNABORTED
  1245. #else
  1246.         || err == NGX_EPIPE
  1247. #endif
  1248.         || err == NGX_ENOTCONN
  1249.         || err == NGX_ETIMEDOUT
  1250.         || err == NGX_ECONNREFUSED
  1251.         || err == NGX_ENETDOWN
  1252.         || err == NGX_ENETUNREACH
  1253.         || err == NGX_EHOSTDOWN
  1254.         || err == NGX_EHOSTUNREACH)
  1255.     {
  1256.         switch (c->log_error) {

  1257.         case NGX_ERROR_IGNORE_EMSGSIZE:
  1258.         case NGX_ERROR_IGNORE_EINVAL:
  1259.         case NGX_ERROR_IGNORE_ECONNRESET:
  1260.         case NGX_ERROR_INFO:
  1261.             level = NGX_LOG_INFO;
  1262.             break;

  1263.         default:
  1264.             level = NGX_LOG_ERR;
  1265.         }

  1266.     } else {
  1267.         level = NGX_LOG_ALERT;
  1268.     }

  1269.     ngx_log_error(level, c->log, err, text);

  1270.     return NGX_ERROR;
  1271. }