src/core/ngx_connection.c - nginx source code

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. #if (NGX_HAVE_TCP_FASTOPEN)

  243.         olen = sizeof(int);

  244.         if (getsockopt(ls[i].fd, IPPROTO_TCP, TCP_FASTOPEN,
  245.                        (void *) &ls[i].fastopen, &olen)
  246.             == -1)
  247.         {
  248.             err = ngx_socket_errno;

  249.             if (err != NGX_EOPNOTSUPP && err != NGX_ENOPROTOOPT
  250.                 && err != NGX_EINVAL)
  251.             {
  252.                 ngx_log_error(NGX_LOG_NOTICE, cycle->log, err,
  253.                               "getsockopt(TCP_FASTOPEN) %V failed, ignored",
  254.                               &ls[i].addr_text);
  255.             }

  256.             ls[i].fastopen = -1;
  257.         }

  258. #endif

  259. #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)

  260.         ngx_memzero(&af, sizeof(struct accept_filter_arg));
  261.         olen = sizeof(struct accept_filter_arg);

  262.         if (getsockopt(ls[i].fd, SOL_SOCKET, SO_ACCEPTFILTER, &af, &olen)
  263.             == -1)
  264.         {
  265.             err = ngx_socket_errno;

  266.             if (err == NGX_EINVAL) {
  267.                 continue;
  268.             }

  269.             ngx_log_error(NGX_LOG_NOTICE, cycle->log, err,
  270.                           "getsockopt(SO_ACCEPTFILTER) for %V failed, ignored",
  271.                           &ls[i].addr_text);
  272.             continue;
  273.         }

  274.         if (olen < sizeof(struct accept_filter_arg) || af.af_name[0] == '\0') {
  275.             continue;
  276.         }

  277.         ls[i].accept_filter = ngx_palloc(cycle->pool, 16);
  278.         if (ls[i].accept_filter == NULL) {
  279.             return NGX_ERROR;
  280.         }

  281.         (void) ngx_cpystrn((u_char *) ls[i].accept_filter,
  282.                            (u_char *) af.af_name, 16);
  283. #endif

  284. #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)

  285.         timeout = 0;
  286.         olen = sizeof(int);

  287.         if (getsockopt(ls[i].fd, IPPROTO_TCP, TCP_DEFER_ACCEPT, &timeout, &olen)
  288.             == -1)
  289.         {
  290.             err = ngx_socket_errno;

  291.             if (err == NGX_EOPNOTSUPP) {
  292.                 continue;
  293.             }

  294.             ngx_log_error(NGX_LOG_NOTICE, cycle->log, err,
  295.                           "getsockopt(TCP_DEFER_ACCEPT) for %V failed, ignored",
  296.                           &ls[i].addr_text);
  297.             continue;
  298.         }

  299.         if (olen < sizeof(int) || timeout == 0) {
  300.             continue;
  301.         }

  302.         ls[i].deferred_accept = 1;
  303. #endif
  304.     }

  305.     return NGX_OK;
  306. }


  307. ngx_int_t
  308. ngx_open_listening_sockets(ngx_cycle_t *cycle)
  309. {
  310.     int               reuseaddr;
  311.     ngx_uint_t        i, tries, failed;
  312.     ngx_err_t         err;
  313.     ngx_log_t        *log;
  314.     ngx_socket_t      s;
  315.     ngx_listening_t  *ls;

  316.     reuseaddr = 1;
  317. #if (NGX_SUPPRESS_WARN)
  318.     failed = 0;
  319. #endif

  320.     log = cycle->log;

  321.     /* TODO: configurable try number */

  322.     for (tries = 5; tries; tries--) {
  323.         failed = 0;

  324.         /* for each listening socket */

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

  327.             if (ls[i].ignore) {
  328.                 continue;
  329.             }

  330. #if (NGX_HAVE_REUSEPORT)

  331.             if (ls[i].add_reuseport) {

  332.                 /*
  333.                  * to allow transition from a socket without SO_REUSEPORT
  334.                  * to multiple sockets with SO_REUSEPORT, we have to set
  335.                  * SO_REUSEPORT on the old socket before opening new ones
  336.                  */

  337.                 int  reuseport = 1;

  338. #ifdef SO_REUSEPORT_LB

  339.                 if (setsockopt(ls[i].fd, SOL_SOCKET, SO_REUSEPORT_LB,
  340.                                (const void *) &reuseport, sizeof(int))
  341.                     == -1)
  342.                 {
  343.                     ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  344.                                   "setsockopt(SO_REUSEPORT_LB) %V failed, "
  345.                                   "ignored",
  346.                                   &ls[i].addr_text);
  347.                 }

  348. #else

  349.                 if (setsockopt(ls[i].fd, SOL_SOCKET, SO_REUSEPORT,
  350.                                (const void *) &reuseport, sizeof(int))
  351.                     == -1)
  352.                 {
  353.                     ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  354.                                   "setsockopt(SO_REUSEPORT) %V failed, ignored",
  355.                                   &ls[i].addr_text);
  356.                 }
  357. #endif

  358.                 ls[i].add_reuseport = 0;
  359.             }
  360. #endif

  361.             if (ls[i].fd != (ngx_socket_t) -1) {
  362.                 continue;
  363.             }

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

  365.                 /* TODO: close on exit */
  366.                 /* TODO: nonblocking */
  367.                 /* TODO: deferred accept */

  368.                 continue;
  369.             }

  370.             s = ngx_socket(ls[i].sockaddr->sa_family, ls[i].type, 0);

  371.             if (s == (ngx_socket_t) -1) {
  372.                 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
  373.                               ngx_socket_n " %V failed", &ls[i].addr_text);
  374.                 return NGX_ERROR;
  375.             }

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

  377.                 if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
  378.                                (const void *) &reuseaddr, sizeof(int))
  379.                     == -1)
  380.                 {
  381.                     ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
  382.                                   "setsockopt(SO_REUSEADDR) %V failed",
  383.                                   &ls[i].addr_text);

  384.                     if (ngx_close_socket(s) == -1) {
  385.                         ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
  386.                                       ngx_close_socket_n " %V failed",
  387.                                       &ls[i].addr_text);
  388.                     }

  389.                     return NGX_ERROR;
  390.                 }
  391.             }

  392. #if (NGX_HAVE_REUSEPORT)

  393.             if (ls[i].reuseport && !ngx_test_config) {
  394.                 int  reuseport;

  395.                 reuseport = 1;

  396. #ifdef SO_REUSEPORT_LB

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

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

  409.                     return NGX_ERROR;
  410.                 }

  411. #else

  412.                 if (setsockopt(s, SOL_SOCKET, SO_REUSEPORT,
  413.                                (const void *) &reuseport, sizeof(int))
  414.                     == -1)
  415.                 {
  416.                     ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
  417.                                   "setsockopt(SO_REUSEPORT) %V failed",
  418.                                   &ls[i].addr_text);

  419.                     if (ngx_close_socket(s) == -1) {
  420.                         ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
  421.                                       ngx_close_socket_n " %V failed",
  422.                                       &ls[i].addr_text);
  423.                     }

  424.                     return NGX_ERROR;
  425.                 }
  426. #endif
  427.             }
  428. #endif

  429. #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)

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

  432.                 ipv6only = ls[i].ipv6only;

  433.                 if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY,
  434.                                (const void *) &ipv6only, sizeof(int))
  435.                     == -1)
  436.                 {
  437.                     ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
  438.                                   "setsockopt(IPV6_V6ONLY) %V failed, ignored",
  439.                                   &ls[i].addr_text);
  440.                 }
  441.             }
  442. #endif
  443.             /* TODO: close on exit */

  444.             if (!(ngx_event_flags & NGX_USE_IOCP_EVENT)) {
  445.                 if (ngx_nonblocking(s) == -1) {
  446.                     ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
  447.                                   ngx_nonblocking_n " %V failed",
  448.                                   &ls[i].addr_text);

  449.                     if (ngx_close_socket(s) == -1) {
  450.                         ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
  451.                                       ngx_close_socket_n " %V failed",
  452.                                       &ls[i].addr_text);
  453.                     }

  454.                     return NGX_ERROR;
  455.                 }
  456.             }

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

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

  461.                 if (err != NGX_EADDRINUSE || !ngx_test_config) {
  462.                     ngx_log_error(NGX_LOG_EMERG, log, err,
  463.                                   "bind() to %V failed", &ls[i].addr_text);
  464.                 }

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

  470.                 if (err != NGX_EADDRINUSE) {
  471.                     return NGX_ERROR;
  472.                 }

  473.                 if (!ngx_test_config) {
  474.                     failed = 1;
  475.                 }

  476.                 continue;
  477.             }

  478. #if (NGX_HAVE_UNIX_DOMAIN)

  479.             if (ls[i].sockaddr->sa_family == AF_UNIX) {
  480.                 mode_t   mode;
  481.                 u_char  *name;

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

  484.                 if (chmod((char *) name, mode) == -1) {
  485.                     ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
  486.                                   "chmod() \"%s\" failed", name);
  487.                 }

  488.                 if (ngx_test_config) {
  489.                     if (ngx_delete_file(name) == NGX_FILE_ERROR) {
  490.                         ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
  491.                                       ngx_delete_file_n " %s failed", name);
  492.                     }
  493.                 }
  494.             }
  495. #endif

  496.             if (ls[i].type != SOCK_STREAM) {
  497.                 ls[i].fd = s;
  498.                 continue;
  499.             }

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

  502.                 /*
  503.                  * on OpenVZ after suspend/resume EADDRINUSE
  504.                  * may be returned by listen() instead of bind(), see
  505.                  * https://bugs.openvz.org/browse/OVZ-5587
  506.                  */

  507.                 if (err != NGX_EADDRINUSE || !ngx_test_config) {
  508.                     ngx_log_error(NGX_LOG_EMERG, log, err,
  509.                                   "listen() to %V, backlog %d failed",
  510.                                   &ls[i].addr_text, ls[i].backlog);
  511.                 }

  512.                 if (ngx_close_socket(s) == -1) {
  513.                     ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
  514.                                   ngx_close_socket_n " %V failed",
  515.                                   &ls[i].addr_text);
  516.                 }

  517.                 if (err != NGX_EADDRINUSE) {
  518.                     return NGX_ERROR;
  519.                 }

  520.                 if (!ngx_test_config) {
  521.                     failed = 1;
  522.                 }

  523.                 continue;
  524.             }

  525.             ls[i].listen = 1;

  526.             ls[i].fd = s;
  527.         }

  528.         if (!failed) {
  529.             break;
  530.         }

  531.         /* TODO: delay configurable */

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

  534.         ngx_msleep(500);
  535.     }

  536.     if (failed) {
  537.         ngx_log_error(NGX_LOG_EMERG, log, 0, "still could not bind()");
  538.         return NGX_ERROR;
  539.     }

  540.     return NGX_OK;
  541. }


  542. void
  543. ngx_configure_listening_sockets(ngx_cycle_t *cycle)
  544. {
  545.     int                        value;
  546.     ngx_uint_t                 i;
  547.     ngx_listening_t           *ls;

  548. #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
  549.     struct accept_filter_arg   af;
  550. #endif

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

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

  554.         if (ls[i].rcvbuf != -1) {
  555.             if (setsockopt(ls[i].fd, SOL_SOCKET, SO_RCVBUF,
  556.                            (const void *) &ls[i].rcvbuf, sizeof(int))
  557.                 == -1)
  558.             {
  559.                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  560.                               "setsockopt(SO_RCVBUF, %d) %V failed, ignored",
  561.                               ls[i].rcvbuf, &ls[i].addr_text);
  562.             }
  563.         }

  564.         if (ls[i].sndbuf != -1) {
  565.             if (setsockopt(ls[i].fd, SOL_SOCKET, SO_SNDBUF,
  566.                            (const void *) &ls[i].sndbuf, sizeof(int))
  567.                 == -1)
  568.             {
  569.                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  570.                               "setsockopt(SO_SNDBUF, %d) %V failed, ignored",
  571.                               ls[i].sndbuf, &ls[i].addr_text);
  572.             }
  573.         }

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

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

  585. #if (NGX_HAVE_KEEPALIVE_TUNABLE)

  586.         if (ls[i].keepidle) {
  587.             value = ls[i].keepidle;

  588. #if (NGX_KEEPALIVE_FACTOR)
  589.             value *= NGX_KEEPALIVE_FACTOR;
  590. #endif

  591.             if (setsockopt(ls[i].fd, IPPROTO_TCP, TCP_KEEPIDLE,
  592.                            (const void *) &value, sizeof(int))
  593.                 == -1)
  594.             {
  595.                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  596.                               "setsockopt(TCP_KEEPIDLE, %d) %V failed, ignored",
  597.                               value, &ls[i].addr_text);
  598.             }
  599.         }

  600.         if (ls[i].keepintvl) {
  601.             value = ls[i].keepintvl;

  602. #if (NGX_KEEPALIVE_FACTOR)
  603.             value *= NGX_KEEPALIVE_FACTOR;
  604. #endif

  605.             if (setsockopt(ls[i].fd, IPPROTO_TCP, TCP_KEEPINTVL,
  606.                            (const void *) &value, sizeof(int))
  607.                 == -1)
  608.             {
  609.                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  610.                              "setsockopt(TCP_KEEPINTVL, %d) %V failed, ignored",
  611.                              value, &ls[i].addr_text);
  612.             }
  613.         }

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

  624. #endif

  625. #if (NGX_HAVE_SETFIB)
  626.         if (ls[i].setfib != -1) {
  627.             if (setsockopt(ls[i].fd, SOL_SOCKET, SO_SETFIB,
  628.                            (const void *) &ls[i].setfib, sizeof(int))
  629.                 == -1)
  630.             {
  631.                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  632.                               "setsockopt(SO_SETFIB, %d) %V failed, ignored",
  633.                               ls[i].setfib, &ls[i].addr_text);
  634.             }
  635.         }
  636. #endif

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

  649. #if 0
  650.         if (1) {
  651.             int tcp_nodelay = 1;

  652.             if (setsockopt(ls[i].fd, IPPROTO_TCP, TCP_NODELAY,
  653.                        (const void *) &tcp_nodelay, sizeof(int))
  654.                 == -1)
  655.             {
  656.                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  657.                               "setsockopt(TCP_NODELAY) %V failed, ignored",
  658.                               &ls[i].addr_text);
  659.             }
  660.         }
  661. #endif

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

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

  664.             if (listen(ls[i].fd, ls[i].backlog) == -1) {
  665.                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  666.                               "listen() to %V, backlog %d failed, ignored",
  667.                               &ls[i].addr_text, ls[i].backlog);
  668.             }
  669.         }

  670.         /*
  671.          * setting deferred mode should be last operation on socket,
  672.          * because code may prematurely continue cycle on failure
  673.          */

  674. #if (NGX_HAVE_DEFERRED_ACCEPT)

  675. #ifdef SO_ACCEPTFILTER

  676.         if (ls[i].delete_deferred) {
  677.             if (setsockopt(ls[i].fd, SOL_SOCKET, SO_ACCEPTFILTER, NULL, 0)
  678.                 == -1)
  679.             {
  680.                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  681.                               "setsockopt(SO_ACCEPTFILTER, NULL) "
  682.                               "for %V failed, ignored",
  683.                               &ls[i].addr_text);

  684.                 if (ls[i].accept_filter) {
  685.                     ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
  686.                                   "could not change the accept filter "
  687.                                   "to \"%s\" for %V, ignored",
  688.                                   ls[i].accept_filter, &ls[i].addr_text);
  689.                 }

  690.                 continue;
  691.             }

  692.             ls[i].deferred_accept = 0;
  693.         }

  694.         if (ls[i].add_deferred) {
  695.             ngx_memzero(&af, sizeof(struct accept_filter_arg));
  696.             (void) ngx_cpystrn((u_char *) af.af_name,
  697.                                (u_char *) ls[i].accept_filter, 16);

  698.             if (setsockopt(ls[i].fd, SOL_SOCKET, SO_ACCEPTFILTER,
  699.                            &af, sizeof(struct accept_filter_arg))
  700.                 == -1)
  701.             {
  702.                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  703.                               "setsockopt(SO_ACCEPTFILTER, \"%s\") "
  704.                               "for %V failed, ignored",
  705.                               ls[i].accept_filter, &ls[i].addr_text);
  706.                 continue;
  707.             }

  708.             ls[i].deferred_accept = 1;
  709.         }

  710. #endif

  711. #ifdef TCP_DEFER_ACCEPT

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

  713.             if (ls[i].add_deferred) {
  714.                 /*
  715.                  * There is no way to find out how long a connection was
  716.                  * in queue (and a connection may bypass deferred queue at all
  717.                  * if syncookies were used), hence we use 1 second timeout
  718.                  * here.
  719.                  */
  720.                 value = 1;

  721.             } else {
  722.                 value = 0;
  723.             }

  724.             if (setsockopt(ls[i].fd, IPPROTO_TCP, TCP_DEFER_ACCEPT,
  725.                            &value, sizeof(int))
  726.                 == -1)
  727.             {
  728.                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  729.                               "setsockopt(TCP_DEFER_ACCEPT, %d) for %V failed, "
  730.                               "ignored",
  731.                               value, &ls[i].addr_text);

  732.                 continue;
  733.             }
  734.         }

  735.         if (ls[i].add_deferred) {
  736.             ls[i].deferred_accept = 1;
  737.         }

  738. #endif

  739. #endif /* NGX_HAVE_DEFERRED_ACCEPT */

  740. #if (NGX_HAVE_IP_RECVDSTADDR)

  741.         if (ls[i].wildcard
  742.             && ls[i].type == SOCK_DGRAM
  743.             && ls[i].sockaddr->sa_family == AF_INET)
  744.         {
  745.             value = 1;

  746.             if (setsockopt(ls[i].fd, IPPROTO_IP, IP_RECVDSTADDR,
  747.                            (const void *) &value, sizeof(int))
  748.                 == -1)
  749.             {
  750.                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  751.                               "setsockopt(IP_RECVDSTADDR) "
  752.                               "for %V failed, ignored",
  753.                               &ls[i].addr_text);
  754.             }
  755.         }

  756. #elif (NGX_HAVE_IP_PKTINFO)

  757.         if (ls[i].wildcard
  758.             && ls[i].type == SOCK_DGRAM
  759.             && ls[i].sockaddr->sa_family == AF_INET)
  760.         {
  761.             value = 1;

  762.             if (setsockopt(ls[i].fd, IPPROTO_IP, IP_PKTINFO,
  763.                            (const void *) &value, sizeof(int))
  764.                 == -1)
  765.             {
  766.                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  767.                               "setsockopt(IP_PKTINFO) "
  768.                               "for %V failed, ignored",
  769.                               &ls[i].addr_text);
  770.             }
  771.         }

  772. #endif

  773. #if (NGX_HAVE_INET6 && NGX_HAVE_IPV6_RECVPKTINFO)

  774.         if (ls[i].wildcard
  775.             && ls[i].type == SOCK_DGRAM
  776.             && ls[i].sockaddr->sa_family == AF_INET6)
  777.         {
  778.             value = 1;

  779.             if (setsockopt(ls[i].fd, IPPROTO_IPV6, IPV6_RECVPKTINFO,
  780.                            (const void *) &value, sizeof(int))
  781.                 == -1)
  782.             {
  783.                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  784.                               "setsockopt(IPV6_RECVPKTINFO) "
  785.                               "for %V failed, ignored",
  786.                               &ls[i].addr_text);
  787.             }
  788.         }

  789. #endif

  790. #if (NGX_HAVE_IP_MTU_DISCOVER)

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

  793.             if (setsockopt(ls[i].fd, IPPROTO_IP, IP_MTU_DISCOVER,
  794.                            (const void *) &value, sizeof(int))
  795.                 == -1)
  796.             {
  797.                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  798.                               "setsockopt(IP_MTU_DISCOVER) "
  799.                               "for %V failed, ignored",
  800.                               &ls[i].addr_text);
  801.             }
  802.         }

  803. #elif (NGX_HAVE_IP_DONTFRAG)

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

  806.             if (setsockopt(ls[i].fd, IPPROTO_IP, IP_DONTFRAG,
  807.                            (const void *) &value, sizeof(int))
  808.                 == -1)
  809.             {
  810.                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  811.                               "setsockopt(IP_DONTFRAG) "
  812.                               "for %V failed, ignored",
  813.                               &ls[i].addr_text);
  814.             }
  815.         }

  816. #endif

  817. #if (NGX_HAVE_INET6)

  818. #if (NGX_HAVE_IPV6_MTU_DISCOVER)

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

  821.             if (setsockopt(ls[i].fd, IPPROTO_IPV6, IPV6_MTU_DISCOVER,
  822.                            (const void *) &value, sizeof(int))
  823.                 == -1)
  824.             {
  825.                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  826.                               "setsockopt(IPV6_MTU_DISCOVER) "
  827.                               "for %V failed, ignored",
  828.                               &ls[i].addr_text);
  829.             }
  830.         }

  831. #elif (NGX_HAVE_IP_DONTFRAG)

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

  834.             if (setsockopt(ls[i].fd, IPPROTO_IPV6, IPV6_DONTFRAG,
  835.                            (const void *) &value, sizeof(int))
  836.                 == -1)
  837.             {
  838.                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  839.                               "setsockopt(IPV6_DONTFRAG) "
  840.                               "for %V failed, ignored",
  841.                               &ls[i].addr_text);
  842.             }
  843.         }

  844. #endif

  845. #endif
  846.     }

  847.     return;
  848. }


  849. void
  850. ngx_close_listening_sockets(ngx_cycle_t *cycle)
  851. {
  852.     ngx_uint_t         i;
  853.     ngx_listening_t   *ls;
  854.     ngx_connection_t  *c;

  855.     if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
  856.         return;
  857.     }

  858.     ngx_accept_mutex_held = 0;
  859.     ngx_use_accept_mutex = 0;

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

  862. #if (NGX_QUIC)
  863.         if (ls[i].quic) {
  864.             continue;
  865.         }
  866. #endif

  867.         c = ls[i].connection;

  868.         if (c) {
  869.             if (c->read->active) {
  870.                 if (ngx_event_flags & NGX_USE_EPOLL_EVENT) {

  871.                     /*
  872.                      * it seems that Linux-2.6.x OpenVZ sends events
  873.                      * for closed shared listening sockets unless
  874.                      * the events was explicitly deleted
  875.                      */

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

  877.                 } else {
  878.                     ngx_del_event(c->read, NGX_READ_EVENT, NGX_CLOSE_EVENT);
  879.                 }
  880.             }

  881.             ngx_free_connection(c);

  882.             c->fd = (ngx_socket_t) -1;
  883.         }

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

  886.         if (ngx_close_socket(ls[i].fd) == -1) {
  887.             ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_socket_errno,
  888.                           ngx_close_socket_n " %V failed", &ls[i].addr_text);
  889.         }

  890. #if (NGX_HAVE_UNIX_DOMAIN)

  891.         if (ls[i].sockaddr->sa_family == AF_UNIX
  892.             && ngx_process <= NGX_PROCESS_MASTER
  893.             && ngx_new_binary == 0
  894.             && (!ls[i].inherited || ngx_getppid() != ngx_parent))
  895.         {
  896.             u_char *name = ls[i].addr_text.data + sizeof("unix:") - 1;

  897.             if (ngx_delete_file(name) == NGX_FILE_ERROR) {
  898.                 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_socket_errno,
  899.                               ngx_delete_file_n " %s failed", name);
  900.             }
  901.         }

  902. #endif

  903.         ls[i].fd = (ngx_socket_t) -1;
  904.     }

  905.     cycle->listening.nelts = 0;
  906. }


  907. ngx_connection_t *
  908. ngx_get_connection(ngx_socket_t s, ngx_log_t *log)
  909. {
  910.     ngx_uint_t         instance;
  911.     ngx_event_t       *rev, *wev;
  912.     ngx_connection_t  *c;

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

  914.     if (ngx_cycle->files && (ngx_uint_t) s >= ngx_cycle->files_n) {
  915.         ngx_log_error(NGX_LOG_ALERT, log, 0,
  916.                       "the new socket has number %d, "
  917.                       "but only %ui files are available",
  918.                       s, ngx_cycle->files_n);
  919.         return NULL;
  920.     }

  921.     ngx_drain_connections((ngx_cycle_t *) ngx_cycle);

  922.     c = ngx_cycle->free_connections;

  923.     if (c == NULL) {
  924.         ngx_log_error(NGX_LOG_ALERT, log, 0,
  925.                       "%ui worker_connections are not enough",
  926.                       ngx_cycle->connection_n);

  927.         return NULL;
  928.     }

  929.     ngx_cycle->free_connections = c->data;
  930.     ngx_cycle->free_connection_n--;

  931.     if (ngx_cycle->files && ngx_cycle->files[s] == NULL) {
  932.         ngx_cycle->files[s] = c;
  933.     }

  934.     rev = c->read;
  935.     wev = c->write;

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

  937.     c->read = rev;
  938.     c->write = wev;
  939.     c->fd = s;
  940.     c->log = log;

  941.     instance = rev->instance;

  942.     ngx_memzero(rev, sizeof(ngx_event_t));
  943.     ngx_memzero(wev, sizeof(ngx_event_t));

  944.     rev->instance = !instance;
  945.     wev->instance = !instance;

  946.     rev->index = NGX_INVALID_INDEX;
  947.     wev->index = NGX_INVALID_INDEX;

  948.     rev->data = c;
  949.     wev->data = c;

  950.     wev->write = 1;

  951.     return c;
  952. }


  953. void
  954. ngx_free_connection(ngx_connection_t *c)
  955. {
  956.     c->data = ngx_cycle->free_connections;
  957.     ngx_cycle->free_connections = c;
  958.     ngx_cycle->free_connection_n++;

  959.     if (ngx_cycle->files && ngx_cycle->files[c->fd] == c) {
  960.         ngx_cycle->files[c->fd] = NULL;
  961.     }
  962. }


  963. void
  964. ngx_close_connection(ngx_connection_t *c)
  965. {
  966.     ngx_err_t     err;
  967.     ngx_uint_t    log_error, level;
  968.     ngx_socket_t  fd;

  969.     if (c->fd == (ngx_socket_t) -1) {
  970.         ngx_log_error(NGX_LOG_ALERT, c->log, 0, "connection already closed");
  971.         return;
  972.     }

  973.     if (c->read->timer_set) {
  974.         ngx_del_timer(c->read);
  975.     }

  976.     if (c->write->timer_set) {
  977.         ngx_del_timer(c->write);
  978.     }

  979.     if (!c->shared) {
  980.         if (ngx_del_conn) {
  981.             ngx_del_conn(c, NGX_CLOSE_EVENT);

  982.         } else {
  983.             if (c->read->active || c->read->disabled) {
  984.                 ngx_del_event(c->read, NGX_READ_EVENT, NGX_CLOSE_EVENT);
  985.             }

  986.             if (c->write->active || c->write->disabled) {
  987.                 ngx_del_event(c->write, NGX_WRITE_EVENT, NGX_CLOSE_EVENT);
  988.             }
  989.         }
  990.     }

  991.     if (c->read->posted) {
  992.         ngx_delete_posted_event(c->read);
  993.     }

  994.     if (c->write->posted) {
  995.         ngx_delete_posted_event(c->write);
  996.     }

  997.     c->read->closed = 1;
  998.     c->write->closed = 1;

  999.     ngx_reusable_connection(c, 0);

  1000.     log_error = c->log_error;

  1001.     ngx_free_connection(c);

  1002.     fd = c->fd;
  1003.     c->fd = (ngx_socket_t) -1;

  1004.     if (c->shared) {
  1005.         return;
  1006.     }

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

  1008.         err = ngx_socket_errno;

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

  1010.             switch (log_error) {

  1011.             case NGX_ERROR_INFO:
  1012.                 level = NGX_LOG_INFO;
  1013.                 break;

  1014.             case NGX_ERROR_ERR:
  1015.                 level = NGX_LOG_ERR;
  1016.                 break;

  1017.             default:
  1018.                 level = NGX_LOG_CRIT;
  1019.             }

  1020.         } else {
  1021.             level = NGX_LOG_CRIT;
  1022.         }

  1023.         ngx_log_error(level, c->log, err, ngx_close_socket_n " %d failed", fd);
  1024.     }
  1025. }


  1026. void
  1027. ngx_reusable_connection(ngx_connection_t *c, ngx_uint_t reusable)
  1028. {
  1029.     ngx_log_debug1(NGX_LOG_DEBUG_CORE, c->log, 0,
  1030.                    "reusable connection: %ui", reusable);

  1031.     if (c->reusable) {
  1032.         ngx_queue_remove(&c->queue);
  1033.         ngx_cycle->reusable_connections_n--;

  1034. #if (NGX_STAT_STUB)
  1035.         (void) ngx_atomic_fetch_add(ngx_stat_waiting, -1);
  1036. #endif
  1037.     }

  1038.     c->reusable = reusable;

  1039.     if (reusable) {
  1040.         /* need cast as ngx_cycle is volatile */

  1041.         ngx_queue_insert_head(
  1042.             (ngx_queue_t *) &ngx_cycle->reusable_connections_queue, &c->queue);
  1043.         ngx_cycle->reusable_connections_n++;

  1044. #if (NGX_STAT_STUB)
  1045.         (void) ngx_atomic_fetch_add(ngx_stat_waiting, 1);
  1046. #endif
  1047.     }
  1048. }


  1049. static void
  1050. ngx_drain_connections(ngx_cycle_t *cycle)
  1051. {
  1052.     ngx_uint_t         i, n;
  1053.     ngx_queue_t       *q;
  1054.     ngx_connection_t  *c;

  1055.     if (cycle->free_connection_n > cycle->connection_n / 16
  1056.         || cycle->reusable_connections_n == 0)
  1057.     {
  1058.         return;
  1059.     }

  1060.     if (cycle->connections_reuse_time != ngx_time()) {
  1061.         cycle->connections_reuse_time = ngx_time();

  1062.         ngx_log_error(NGX_LOG_WARN, cycle->log, 0,
  1063.                       "%ui worker_connections are not enough, "
  1064.                       "reusing connections",
  1065.                       cycle->connection_n);
  1066.     }

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

  1069.     for (i = 0; i < n; i++) {
  1070.         if (ngx_queue_empty(&cycle->reusable_connections_queue)) {
  1071.             break;
  1072.         }

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

  1075.         ngx_log_debug0(NGX_LOG_DEBUG_CORE, c->log, 0,
  1076.                        "reusing connection");

  1077.         c->close = 1;
  1078.         c->read->handler(c->read);
  1079.     }

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

  1081.         /*
  1082.          * if no connections were freed, try to reuse the last
  1083.          * connection again: this should free it as long as
  1084.          * previous reuse moved it to lingering close
  1085.          */

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

  1088.         c->close = 1;
  1089.         c->read->handler(c->read);
  1090.     }
  1091. }


  1092. void
  1093. ngx_close_idle_connections(ngx_cycle_t *cycle)
  1094. {
  1095.     ngx_uint_t         i;
  1096.     ngx_connection_t  *c;

  1097.     c = cycle->connections;

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

  1099.         /* THREAD: lock */

  1100.         if (c[i].fd != (ngx_socket_t) -1 && c[i].idle) {
  1101.             c[i].close = 1;
  1102.             c[i].read->handler(c[i].read);
  1103.         }
  1104.     }
  1105. }


  1106. ngx_int_t
  1107. ngx_connection_local_sockaddr(ngx_connection_t *c, ngx_str_t *s,
  1108.     ngx_uint_t port)
  1109. {
  1110.     socklen_t             len;
  1111.     ngx_uint_t            addr;
  1112.     ngx_sockaddr_t        sa;
  1113.     struct sockaddr_in   *sin;
  1114. #if (NGX_HAVE_INET6)
  1115.     ngx_uint_t            i;
  1116.     struct sockaddr_in6  *sin6;
  1117. #endif

  1118.     addr = 0;

  1119.     if (c->local_socklen) {
  1120.         switch (c->local_sockaddr->sa_family) {

  1121. #if (NGX_HAVE_INET6)
  1122.         case AF_INET6:
  1123.             sin6 = (struct sockaddr_in6 *) c->local_sockaddr;

  1124.             for (i = 0; addr == 0 && i < 16; i++) {
  1125.                 addr |= sin6->sin6_addr.s6_addr[i];
  1126.             }

  1127.             break;
  1128. #endif

  1129. #if (NGX_HAVE_UNIX_DOMAIN)
  1130.         case AF_UNIX:
  1131.             addr = 1;
  1132.             break;
  1133. #endif

  1134.         default: /* AF_INET */
  1135.             sin = (struct sockaddr_in *) c->local_sockaddr;
  1136.             addr = sin->sin_addr.s_addr;
  1137.             break;
  1138.         }
  1139.     }

  1140.     if (addr == 0) {

  1141.         len = sizeof(ngx_sockaddr_t);

  1142.         if (getsockname(c->fd, &sa.sockaddr, &len) == -1) {
  1143.             ngx_connection_error(c, ngx_socket_errno, "getsockname() failed");
  1144.             return NGX_ERROR;
  1145.         }

  1146.         c->local_sockaddr = ngx_palloc(c->pool, len);
  1147.         if (c->local_sockaddr == NULL) {
  1148.             return NGX_ERROR;
  1149.         }

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

  1151.         c->local_socklen = len;
  1152.     }

  1153.     if (s == NULL) {
  1154.         return NGX_OK;
  1155.     }

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

  1158.     return NGX_OK;
  1159. }


  1160. ngx_int_t
  1161. ngx_tcp_nodelay(ngx_connection_t *c)
  1162. {
  1163.     int  tcp_nodelay;

  1164.     if (c->tcp_nodelay != NGX_TCP_NODELAY_UNSET) {
  1165.         return NGX_OK;
  1166.     }

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

  1168.     tcp_nodelay = 1;

  1169.     if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY,
  1170.                    (const void *) &tcp_nodelay, sizeof(int))
  1171.         == -1)
  1172.     {
  1173. #if (NGX_SOLARIS)
  1174.         if (c->log_error == NGX_ERROR_INFO) {

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

  1177.             ngx_connection_error(c, ngx_socket_errno,
  1178.                                  "setsockopt(TCP_NODELAY) failed");

  1179.             c->log_error = NGX_ERROR_INFO;

  1180.             return NGX_ERROR;
  1181.         }
  1182. #endif

  1183.         ngx_connection_error(c, ngx_socket_errno,
  1184.                              "setsockopt(TCP_NODELAY) failed");
  1185.         return NGX_ERROR;
  1186.     }

  1187.     c->tcp_nodelay = NGX_TCP_NODELAY_SET;

  1188.     return NGX_OK;
  1189. }


  1190. ngx_int_t
  1191. ngx_connection_error(ngx_connection_t *c, ngx_err_t err, char *text)
  1192. {
  1193.     ngx_uint_t  level;

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

  1195.     if ((err == NGX_ECONNRESET
  1196. #if (NGX_WIN32)
  1197.          || err == NGX_ECONNABORTED
  1198. #endif
  1199.         ) && c->log_error == NGX_ERROR_IGNORE_ECONNRESET)
  1200.     {
  1201.         return 0;
  1202.     }

  1203. #if (NGX_SOLARIS)
  1204.     if (err == NGX_EINVAL && c->log_error == NGX_ERROR_IGNORE_EINVAL) {
  1205.         return 0;
  1206.     }
  1207. #endif

  1208.     if (err == NGX_EMSGSIZE && c->log_error == NGX_ERROR_IGNORE_EMSGSIZE) {
  1209.         return 0;
  1210.     }

  1211.     if (err == 0
  1212.         || err == NGX_ECONNRESET
  1213. #if (NGX_WIN32)
  1214.         || err == NGX_ECONNABORTED
  1215. #else
  1216.         || err == NGX_EPIPE
  1217. #endif
  1218.         || err == NGX_ENOTCONN
  1219.         || err == NGX_ETIMEDOUT
  1220.         || err == NGX_ECONNREFUSED
  1221.         || err == NGX_ENETDOWN
  1222.         || err == NGX_ENETUNREACH
  1223.         || err == NGX_EHOSTDOWN
  1224.         || err == NGX_EHOSTUNREACH)
  1225.     {
  1226.         switch (c->log_error) {

  1227.         case NGX_ERROR_IGNORE_EMSGSIZE:
  1228.         case NGX_ERROR_IGNORE_EINVAL:
  1229.         case NGX_ERROR_IGNORE_ECONNRESET:
  1230.         case NGX_ERROR_INFO:
  1231.             level = NGX_LOG_INFO;
  1232.             break;

  1233.         default:
  1234.             level = NGX_LOG_ERR;
  1235.         }

  1236.     } else {
  1237.         level = NGX_LOG_ALERT;
  1238.     }

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

  1240.     return NGX_ERROR;
  1241. }