src/core/ngx_connection.c - nginx

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_event_flags & NGX_USE_IOCP_EVENT)) {
  466.                 if (ngx_nonblocking(s) == -1) {
  467.                     ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
  468.                                   ngx_nonblocking_n " %V failed",
  469.                                   &ls[i].addr_text);

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

  475.                     return NGX_ERROR;
  476.                 }
  477.             }

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

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

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

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

  491.                 if (err != NGX_EADDRINUSE) {
  492.                     return NGX_ERROR;
  493.                 }

  494.                 if (!ngx_test_config) {
  495.                     failed = 1;
  496.                 }

  497.                 continue;
  498.             }

  499. #if (NGX_HAVE_UNIX_DOMAIN)

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

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

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

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

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

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

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

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

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

  539.                 if (err != NGX_EADDRINUSE) {
  540.                     return NGX_ERROR;
  541.                 }

  542.                 if (!ngx_test_config) {
  543.                     failed = 1;
  544.                 }

  545.                 continue;
  546.             }

  547.             ls[i].listen = 1;

  548.             ls[i].fd = s;
  549.             ls[i].open = 1;
  550.         }

  551.         if (!failed) {
  552.             break;
  553.         }

  554.         /* TODO: delay configurable */

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

  557.         ngx_msleep(500);
  558.     }

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

  563.     return NGX_OK;
  564. }


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

  571. #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
  572.     struct accept_filter_arg   af;
  573. #endif

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

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

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

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

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

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

  608. #if (NGX_HAVE_KEEPALIVE_TUNABLE)

  609. #if !(NGX_DARWIN)

  610.         if (ls[i].keepidle) {
  611.             value = ls[i].keepidle;

  612. #if (NGX_KEEPALIVE_FACTOR)
  613.             value *= NGX_KEEPALIVE_FACTOR;
  614. #endif

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

  624. #endif

  625.         if (ls[i].keepintvl) {
  626.             value = ls[i].keepintvl;

  627. #if (NGX_KEEPALIVE_FACTOR)
  628.             value *= NGX_KEEPALIVE_FACTOR;
  629. #endif

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

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

  649. #endif

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

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

  674. #if 0
  675.         if (1) {
  676.             int tcp_nodelay = 1;

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

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

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

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

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

  699. #if (NGX_HAVE_DEFERRED_ACCEPT)

  700. #ifdef SO_ACCEPTFILTER

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

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

  715.                 continue;
  716.             }

  717.             ls[i].deferred_accept = 0;
  718.         }

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

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

  733.             ls[i].deferred_accept = 1;
  734.         }

  735. #endif

  736. #ifdef TCP_DEFER_ACCEPT

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

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

  746.             } else {
  747.                 value = 0;
  748.             }

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

  757.                 continue;
  758.             }
  759.         }

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

  763. #endif

  764. #endif /* NGX_HAVE_DEFERRED_ACCEPT */

  765. #if (NGX_HAVE_IP_RECVDSTADDR)

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

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

  781. #elif (NGX_HAVE_IP_PKTINFO)

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

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

  797. #endif

  798. #if (NGX_HAVE_INET6 && NGX_HAVE_IPV6_RECVPKTINFO)

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

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

  814. #endif

  815. #if (NGX_HAVE_IP_MTU_DISCOVER)

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

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

  828. #elif (NGX_HAVE_IP_DONTFRAG)

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

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

  841. #endif

  842. #if (NGX_HAVE_INET6)

  843. #if (NGX_HAVE_IPV6_MTU_DISCOVER)

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

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

  856. #elif (NGX_HAVE_IP_DONTFRAG)

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

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

  869. #endif

  870. #endif
  871.     }

  872.     return;
  873. }


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

  880.     if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
  881.         return;
  882.     }

  883.     ngx_accept_mutex_held = 0;
  884.     ngx_use_accept_mutex = 0;

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

  887. #if (NGX_QUIC)
  888.         if (ls[i].quic) {
  889.             continue;
  890.         }
  891. #endif

  892.         c = ls[i].connection;

  893.         if (c) {
  894.             if (c->read->active) {
  895.                 if (ngx_event_flags & NGX_USE_EPOLL_EVENT) {

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

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

  902.                 } else {
  903.                     ngx_del_event(c->read, NGX_READ_EVENT, NGX_CLOSE_EVENT);
  904.                 }
  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 (err == 0
  1237.         || err == NGX_ECONNRESET
  1238. #if (NGX_WIN32)
  1239.         || err == NGX_ECONNABORTED
  1240. #else
  1241.         || err == NGX_EPIPE
  1242. #endif
  1243.         || err == NGX_ENOTCONN
  1244.         || err == NGX_ETIMEDOUT
  1245.         || err == NGX_ECONNREFUSED
  1246.         || err == NGX_ENETDOWN
  1247.         || err == NGX_ENETUNREACH
  1248.         || err == NGX_EHOSTDOWN
  1249.         || err == NGX_EHOSTUNREACH)
  1250.     {
  1251.         switch (c->log_error) {

  1252.         case NGX_ERROR_IGNORE_EMSGSIZE:
  1253.         case NGX_ERROR_IGNORE_EINVAL:
  1254.         case NGX_ERROR_IGNORE_ECONNRESET:
  1255.         case NGX_ERROR_INFO:
  1256.             level = NGX_LOG_INFO;
  1257.             break;

  1258.         default:
  1259.             level = NGX_LOG_ERR;
  1260.         }

  1261.     } else {
  1262.         level = NGX_LOG_ALERT;
  1263.     }

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

  1265.     return NGX_ERROR;
  1266. }