src/core/ngx_connection.c - nginx-1.7.10

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(void);


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

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

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

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

  26.     ngx_memcpy(sa, sockaddr, socklen);

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

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

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

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

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

  55.     ls->fd = (ngx_socket_t) -1;
  56.     ls->type = SOCK_STREAM;

  57.     ls->backlog = NGX_LISTEN_BACKLOG;
  58.     ls->rcvbuf = -1;
  59.     ls->sndbuf = -1;

  60. #if (NGX_HAVE_SETFIB)
  61.     ls->setfib = -1;
  62. #endif

  63. #if (NGX_HAVE_TCP_FASTOPEN)
  64.     ls->fastopen = -1;
  65. #endif

  66.     return ls;
  67. }


  68. ngx_int_t
  69. ngx_set_inherited_sockets(ngx_cycle_t *cycle)
  70. {
  71.     size_t                     len;
  72.     ngx_uint_t                 i;
  73.     ngx_listening_t           *ls;
  74.     socklen_t                  olen;
  75. #if (NGX_HAVE_DEFERRED_ACCEPT || NGX_HAVE_TCP_FASTOPEN)
  76.     ngx_err_t                  err;
  77. #endif
  78. #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
  79.     struct accept_filter_arg   af;
  80. #endif
  81. #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
  82.     int                        timeout;
  83. #endif

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

  86.         ls[i].sockaddr = ngx_palloc(cycle->pool, NGX_SOCKADDRLEN);
  87.         if (ls[i].sockaddr == NULL) {
  88.             return NGX_ERROR;
  89.         }

  90.         ls[i].socklen = NGX_SOCKADDRLEN;
  91.         if (getsockname(ls[i].fd, ls[i].sockaddr, &ls[i].socklen) == -1) {
  92.             ngx_log_error(NGX_LOG_CRIT, cycle->log, ngx_socket_errno,
  93.                           "getsockname() of the inherited "
  94.                           "socket #%d failed", ls[i].fd);
  95.             ls[i].ignore = 1;
  96.             continue;
  97.         }

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

  99. #if (NGX_HAVE_INET6)
  100.         case AF_INET6:
  101.              ls[i].addr_text_max_len = NGX_INET6_ADDRSTRLEN;
  102.              len = NGX_INET6_ADDRSTRLEN + sizeof("[]:65535") - 1;
  103.              break;
  104. #endif

  105. #if (NGX_HAVE_UNIX_DOMAIN)
  106.         case AF_UNIX:
  107.              ls[i].addr_text_max_len = NGX_UNIX_ADDRSTRLEN;
  108.              len = NGX_UNIX_ADDRSTRLEN;
  109.              break;
  110. #endif

  111.         case AF_INET:
  112.              ls[i].addr_text_max_len = NGX_INET_ADDRSTRLEN;
  113.              len = NGX_INET_ADDRSTRLEN + sizeof(":65535") - 1;
  114.              break;

  115.         default:
  116.             ngx_log_error(NGX_LOG_CRIT, cycle->log, ngx_socket_errno,
  117.                           "the inherited socket #%d has "
  118.                           "an unsupported protocol family", ls[i].fd);
  119.             ls[i].ignore = 1;
  120.             continue;
  121.         }

  122.         ls[i].addr_text.data = ngx_pnalloc(cycle->pool, len);
  123.         if (ls[i].addr_text.data == NULL) {
  124.             return NGX_ERROR;
  125.         }

  126.         len = ngx_sock_ntop(ls[i].sockaddr, ls[i].socklen,
  127.                             ls[i].addr_text.data, len, 1);
  128.         if (len == 0) {
  129.             return NGX_ERROR;
  130.         }

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

  132.         ls[i].backlog = NGX_LISTEN_BACKLOG;

  133.         olen = sizeof(int);

  134.         if (getsockopt(ls[i].fd, SOL_SOCKET, SO_RCVBUF, (void *) &ls[i].rcvbuf,
  135.                        &olen)
  136.             == -1)
  137.         {
  138.             ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  139.                           "getsockopt(SO_RCVBUF) %V failed, ignored",
  140.                           &ls[i].addr_text);

  141.             ls[i].rcvbuf = -1;
  142.         }

  143.         olen = sizeof(int);

  144.         if (getsockopt(ls[i].fd, SOL_SOCKET, SO_SNDBUF, (void *) &ls[i].sndbuf,
  145.                        &olen)
  146.             == -1)
  147.         {
  148.             ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  149.                           "getsockopt(SO_SNDBUF) %V failed, ignored",
  150.                           &ls[i].addr_text);

  151.             ls[i].sndbuf = -1;
  152.         }

  153. #if 0
  154.         /* SO_SETFIB is currently a set only option */

  155. #if (NGX_HAVE_SETFIB)

  156.         olen = sizeof(int);

  157.         if (getsockopt(ls[i].fd, SOL_SOCKET, SO_SETFIB,
  158.                        (void *) &ls[i].setfib, &olen)
  159.             == -1)
  160.         {
  161.             ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  162.                           "getsockopt(SO_SETFIB) %V failed, ignored",
  163.                           &ls[i].addr_text);

  164.             ls[i].setfib = -1;
  165.         }

  166. #endif
  167. #endif

  168. #if (NGX_HAVE_TCP_FASTOPEN)

  169.         olen = sizeof(int);

  170.         if (getsockopt(ls[i].fd, IPPROTO_TCP, TCP_FASTOPEN,
  171.                        (void *) &ls[i].fastopen, &olen)
  172.             == -1)
  173.         {
  174.             err = ngx_socket_errno;

  175.             if (err != NGX_EOPNOTSUPP && err != NGX_ENOPROTOOPT) {
  176.                 ngx_log_error(NGX_LOG_NOTICE, cycle->log, err,
  177.                               "getsockopt(TCP_FASTOPEN) %V failed, ignored",
  178.                               &ls[i].addr_text);
  179.             }

  180.             ls[i].fastopen = -1;
  181.         }

  182. #endif

  183. #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)

  184.         ngx_memzero(&af, sizeof(struct accept_filter_arg));
  185.         olen = sizeof(struct accept_filter_arg);

  186.         if (getsockopt(ls[i].fd, SOL_SOCKET, SO_ACCEPTFILTER, &af, &olen)
  187.             == -1)
  188.         {
  189.             err = ngx_socket_errno;

  190.             if (err == NGX_EINVAL) {
  191.                 continue;
  192.             }

  193.             ngx_log_error(NGX_LOG_NOTICE, cycle->log, err,
  194.                           "getsockopt(SO_ACCEPTFILTER) for %V failed, ignored",
  195.                           &ls[i].addr_text);
  196.             continue;
  197.         }

  198.         if (olen < sizeof(struct accept_filter_arg) || af.af_name[0] == '\0') {
  199.             continue;
  200.         }

  201.         ls[i].accept_filter = ngx_palloc(cycle->pool, 16);
  202.         if (ls[i].accept_filter == NULL) {
  203.             return NGX_ERROR;
  204.         }

  205.         (void) ngx_cpystrn((u_char *) ls[i].accept_filter,
  206.                            (u_char *) af.af_name, 16);
  207. #endif

  208. #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)

  209.         timeout = 0;
  210.         olen = sizeof(int);

  211.         if (getsockopt(ls[i].fd, IPPROTO_TCP, TCP_DEFER_ACCEPT, &timeout, &olen)
  212.             == -1)
  213.         {
  214.             err = ngx_socket_errno;

  215.             if (err == NGX_EOPNOTSUPP) {
  216.                 continue;
  217.             }

  218.             ngx_log_error(NGX_LOG_NOTICE, cycle->log, err,
  219.                           "getsockopt(TCP_DEFER_ACCEPT) for %V failed, ignored",
  220.                           &ls[i].addr_text);
  221.             continue;
  222.         }

  223.         if (olen < sizeof(int) || timeout == 0) {
  224.             continue;
  225.         }

  226.         ls[i].deferred_accept = 1;
  227. #endif
  228.     }

  229.     return NGX_OK;
  230. }


  231. ngx_int_t
  232. ngx_open_listening_sockets(ngx_cycle_t *cycle)
  233. {
  234.     int               reuseaddr;
  235.     ngx_uint_t        i, tries, failed;
  236.     ngx_err_t         err;
  237.     ngx_log_t        *log;
  238.     ngx_socket_t      s;
  239.     ngx_listening_t  *ls;

  240.     reuseaddr = 1;
  241. #if (NGX_SUPPRESS_WARN)
  242.     failed = 0;
  243. #endif

  244.     log = cycle->log;

  245.     /* TODO: configurable try number */

  246.     for (tries = 5; tries; tries--) {
  247.         failed = 0;

  248.         /* for each listening socket */

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

  251.             if (ls[i].ignore) {
  252.                 continue;
  253.             }

  254.             if (ls[i].fd != (ngx_socket_t) -1) {
  255.                 continue;
  256.             }

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

  258.                 /* TODO: close on exit */
  259.                 /* TODO: nonblocking */
  260.                 /* TODO: deferred accept */

  261.                 continue;
  262.             }

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

  264.             if (s == (ngx_socket_t) -1) {
  265.                 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
  266.                               ngx_socket_n " %V failed", &ls[i].addr_text);
  267.                 return NGX_ERROR;
  268.             }

  269.             if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
  270.                            (const void *) &reuseaddr, sizeof(int))
  271.                 == -1)
  272.             {
  273.                 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
  274.                               "setsockopt(SO_REUSEADDR) %V failed",
  275.                               &ls[i].addr_text);

  276.                 if (ngx_close_socket(s) == -1) {
  277.                     ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
  278.                                   ngx_close_socket_n " %V failed",
  279.                                   &ls[i].addr_text);
  280.                 }

  281.                 return NGX_ERROR;
  282.             }

  283. #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)

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

  286.                 ipv6only = ls[i].ipv6only;

  287.                 if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY,
  288.                                (const void *) &ipv6only, sizeof(int))
  289.                     == -1)
  290.                 {
  291.                     ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
  292.                                   "setsockopt(IPV6_V6ONLY) %V failed, ignored",
  293.                                   &ls[i].addr_text);
  294.                 }
  295.             }
  296. #endif
  297.             /* TODO: close on exit */

  298.             if (!(ngx_event_flags & NGX_USE_AIO_EVENT)) {
  299.                 if (ngx_nonblocking(s) == -1) {
  300.                     ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
  301.                                   ngx_nonblocking_n " %V failed",
  302.                                   &ls[i].addr_text);

  303.                     if (ngx_close_socket(s) == -1) {
  304.                         ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
  305.                                       ngx_close_socket_n " %V failed",
  306.                                       &ls[i].addr_text);
  307.                     }

  308.                     return NGX_ERROR;
  309.                 }
  310.             }

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

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

  315.                 if (err != NGX_EADDRINUSE || !ngx_test_config) {
  316.                     ngx_log_error(NGX_LOG_EMERG, log, err,
  317.                                   "bind() to %V failed", &ls[i].addr_text);
  318.                 }

  319.                 if (ngx_close_socket(s) == -1) {
  320.                     ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
  321.                                   ngx_close_socket_n " %V failed",
  322.                                   &ls[i].addr_text);
  323.                 }

  324.                 if (err != NGX_EADDRINUSE) {
  325.                     return NGX_ERROR;
  326.                 }

  327.                 if (!ngx_test_config) {
  328.                     failed = 1;
  329.                 }

  330.                 continue;
  331.             }

  332. #if (NGX_HAVE_UNIX_DOMAIN)

  333.             if (ls[i].sockaddr->sa_family == AF_UNIX) {
  334.                 mode_t   mode;
  335.                 u_char  *name;

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

  338.                 if (chmod((char *) name, mode) == -1) {
  339.                     ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
  340.                                   "chmod() \"%s\" failed", name);
  341.                 }

  342.                 if (ngx_test_config) {
  343.                     if (ngx_delete_file(name) == NGX_FILE_ERROR) {
  344.                         ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
  345.                                       ngx_delete_file_n " %s failed", name);
  346.                     }
  347.                 }
  348.             }
  349. #endif

  350.             if (listen(s, ls[i].backlog) == -1) {
  351.                 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
  352.                               "listen() to %V, backlog %d failed",
  353.                               &ls[i].addr_text, ls[i].backlog);

  354.                 if (ngx_close_socket(s) == -1) {
  355.                     ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
  356.                                   ngx_close_socket_n " %V failed",
  357.                                   &ls[i].addr_text);
  358.                 }

  359.                 return NGX_ERROR;
  360.             }

  361.             ls[i].listen = 1;

  362.             ls[i].fd = s;
  363.         }

  364.         if (!failed) {
  365.             break;
  366.         }

  367.         /* TODO: delay configurable */

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

  370.         ngx_msleep(500);
  371.     }

  372.     if (failed) {
  373.         ngx_log_error(NGX_LOG_EMERG, log, 0, "still could not bind()");
  374.         return NGX_ERROR;
  375.     }

  376.     return NGX_OK;
  377. }


  378. void
  379. ngx_configure_listening_sockets(ngx_cycle_t *cycle)
  380. {
  381.     int                        value;
  382.     ngx_uint_t                 i;
  383.     ngx_listening_t           *ls;

  384. #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
  385.     struct accept_filter_arg   af;
  386. #endif

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

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

  390.         if (ls[i].rcvbuf != -1) {
  391.             if (setsockopt(ls[i].fd, SOL_SOCKET, SO_RCVBUF,
  392.                            (const void *) &ls[i].rcvbuf, sizeof(int))
  393.                 == -1)
  394.             {
  395.                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  396.                               "setsockopt(SO_RCVBUF, %d) %V failed, ignored",
  397.                               ls[i].rcvbuf, &ls[i].addr_text);
  398.             }
  399.         }

  400.         if (ls[i].sndbuf != -1) {
  401.             if (setsockopt(ls[i].fd, SOL_SOCKET, SO_SNDBUF,
  402.                            (const void *) &ls[i].sndbuf, sizeof(int))
  403.                 == -1)
  404.             {
  405.                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  406.                               "setsockopt(SO_SNDBUF, %d) %V failed, ignored",
  407.                               ls[i].sndbuf, &ls[i].addr_text);
  408.             }
  409.         }

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

  412.             if (setsockopt(ls[i].fd, SOL_SOCKET, SO_KEEPALIVE,
  413.                            (const void *) &value, sizeof(int))
  414.                 == -1)
  415.             {
  416.                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  417.                               "setsockopt(SO_KEEPALIVE, %d) %V failed, ignored",
  418.                               value, &ls[i].addr_text);
  419.             }
  420.         }

  421. #if (NGX_HAVE_KEEPALIVE_TUNABLE)

  422.         if (ls[i].keepidle) {
  423.             value = ls[i].keepidle;

  424. #if (NGX_KEEPALIVE_FACTOR)
  425.             value *= NGX_KEEPALIVE_FACTOR;
  426. #endif

  427.             if (setsockopt(ls[i].fd, IPPROTO_TCP, TCP_KEEPIDLE,
  428.                            (const void *) &value, sizeof(int))
  429.                 == -1)
  430.             {
  431.                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  432.                               "setsockopt(TCP_KEEPIDLE, %d) %V failed, ignored",
  433.                               value, &ls[i].addr_text);
  434.             }
  435.         }

  436.         if (ls[i].keepintvl) {
  437.             value = ls[i].keepintvl;

  438. #if (NGX_KEEPALIVE_FACTOR)
  439.             value *= NGX_KEEPALIVE_FACTOR;
  440. #endif

  441.             if (setsockopt(ls[i].fd, IPPROTO_TCP, TCP_KEEPINTVL,
  442.                            (const void *) &value, sizeof(int))
  443.                 == -1)
  444.             {
  445.                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  446.                              "setsockopt(TCP_KEEPINTVL, %d) %V failed, ignored",
  447.                              value, &ls[i].addr_text);
  448.             }
  449.         }

  450.         if (ls[i].keepcnt) {
  451.             if (setsockopt(ls[i].fd, IPPROTO_TCP, TCP_KEEPCNT,
  452.                            (const void *) &ls[i].keepcnt, sizeof(int))
  453.                 == -1)
  454.             {
  455.                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  456.                               "setsockopt(TCP_KEEPCNT, %d) %V failed, ignored",
  457.                               ls[i].keepcnt, &ls[i].addr_text);
  458.             }
  459.         }

  460. #endif

  461. #if (NGX_HAVE_SETFIB)
  462.         if (ls[i].setfib != -1) {
  463.             if (setsockopt(ls[i].fd, SOL_SOCKET, SO_SETFIB,
  464.                            (const void *) &ls[i].setfib, sizeof(int))
  465.                 == -1)
  466.             {
  467.                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  468.                               "setsockopt(SO_SETFIB, %d) %V failed, ignored",
  469.                               ls[i].setfib, &ls[i].addr_text);
  470.             }
  471.         }
  472. #endif

  473. #if (NGX_HAVE_TCP_FASTOPEN)
  474.         if (ls[i].fastopen != -1) {
  475.             if (setsockopt(ls[i].fd, IPPROTO_TCP, TCP_FASTOPEN,
  476.                            (const void *) &ls[i].fastopen, sizeof(int))
  477.                 == -1)
  478.             {
  479.                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  480.                               "setsockopt(TCP_FASTOPEN, %d) %V failed, ignored",
  481.                               ls[i].fastopen, &ls[i].addr_text);
  482.             }
  483.         }
  484. #endif

  485. #if 0
  486.         if (1) {
  487.             int tcp_nodelay = 1;

  488.             if (setsockopt(ls[i].fd, IPPROTO_TCP, TCP_NODELAY,
  489.                        (const void *) &tcp_nodelay, sizeof(int))
  490.                 == -1)
  491.             {
  492.                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  493.                               "setsockopt(TCP_NODELAY) %V failed, ignored",
  494.                               &ls[i].addr_text);
  495.             }
  496.         }
  497. #endif

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

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

  500.             if (listen(ls[i].fd, ls[i].backlog) == -1) {
  501.                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  502.                               "listen() to %V, backlog %d failed, ignored",
  503.                               &ls[i].addr_text, ls[i].backlog);
  504.             }
  505.         }

  506.         /*
  507.          * setting deferred mode should be last operation on socket,
  508.          * because code may prematurely continue cycle on failure
  509.          */

  510. #if (NGX_HAVE_DEFERRED_ACCEPT)

  511. #ifdef SO_ACCEPTFILTER

  512.         if (ls[i].delete_deferred) {
  513.             if (setsockopt(ls[i].fd, SOL_SOCKET, SO_ACCEPTFILTER, NULL, 0)
  514.                 == -1)
  515.             {
  516.                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  517.                               "setsockopt(SO_ACCEPTFILTER, NULL) "
  518.                               "for %V failed, ignored",
  519.                               &ls[i].addr_text);

  520.                 if (ls[i].accept_filter) {
  521.                     ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
  522.                                   "could not change the accept filter "
  523.                                   "to \"%s\" for %V, ignored",
  524.                                   ls[i].accept_filter, &ls[i].addr_text);
  525.                 }

  526.                 continue;
  527.             }

  528.             ls[i].deferred_accept = 0;
  529.         }

  530.         if (ls[i].add_deferred) {
  531.             ngx_memzero(&af, sizeof(struct accept_filter_arg));
  532.             (void) ngx_cpystrn((u_char *) af.af_name,
  533.                                (u_char *) ls[i].accept_filter, 16);

  534.             if (setsockopt(ls[i].fd, SOL_SOCKET, SO_ACCEPTFILTER,
  535.                            &af, sizeof(struct accept_filter_arg))
  536.                 == -1)
  537.             {
  538.                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  539.                               "setsockopt(SO_ACCEPTFILTER, \"%s\") "
  540.                               "for %V failed, ignored",
  541.                               ls[i].accept_filter, &ls[i].addr_text);
  542.                 continue;
  543.             }

  544.             ls[i].deferred_accept = 1;
  545.         }

  546. #endif

  547. #ifdef TCP_DEFER_ACCEPT

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

  549.             if (ls[i].add_deferred) {
  550.                 /*
  551.                  * There is no way to find out how long a connection was
  552.                  * in queue (and a connection may bypass deferred queue at all
  553.                  * if syncookies were used), hence we use 1 second timeout
  554.                  * here.
  555.                  */
  556.                 value = 1;

  557.             } else {
  558.                 value = 0;
  559.             }

  560.             if (setsockopt(ls[i].fd, IPPROTO_TCP, TCP_DEFER_ACCEPT,
  561.                            &value, sizeof(int))
  562.                 == -1)
  563.             {
  564.                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
  565.                               "setsockopt(TCP_DEFER_ACCEPT, %d) for %V failed, "
  566.                               "ignored",
  567.                               value, &ls[i].addr_text);

  568.                 continue;
  569.             }
  570.         }

  571.         if (ls[i].add_deferred) {
  572.             ls[i].deferred_accept = 1;
  573.         }

  574. #endif

  575. #endif /* NGX_HAVE_DEFERRED_ACCEPT */
  576.     }

  577.     return;
  578. }


  579. void
  580. ngx_close_listening_sockets(ngx_cycle_t *cycle)
  581. {
  582.     ngx_uint_t         i;
  583.     ngx_listening_t   *ls;
  584.     ngx_connection_t  *c;

  585.     if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
  586.         return;
  587.     }

  588.     ngx_accept_mutex_held = 0;
  589.     ngx_use_accept_mutex = 0;

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

  592.         c = ls[i].connection;

  593.         if (c) {
  594.             if (c->read->active) {
  595.                 if (ngx_event_flags & NGX_USE_RTSIG_EVENT) {
  596.                     ngx_del_conn(c, NGX_CLOSE_EVENT);

  597.                 } else if (ngx_event_flags & NGX_USE_EPOLL_EVENT) {

  598.                     /*
  599.                      * it seems that Linux-2.6.x OpenVZ sends events
  600.                      * for closed shared listening sockets unless
  601.                      * the events was explicitly deleted
  602.                      */

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

  604.                 } else {
  605.                     ngx_del_event(c->read, NGX_READ_EVENT, NGX_CLOSE_EVENT);
  606.                 }
  607.             }

  608.             ngx_free_connection(c);

  609.             c->fd = (ngx_socket_t) -1;
  610.         }

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

  613.         if (ngx_close_socket(ls[i].fd) == -1) {
  614.             ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_socket_errno,
  615.                           ngx_close_socket_n " %V failed", &ls[i].addr_text);
  616.         }

  617. #if (NGX_HAVE_UNIX_DOMAIN)

  618.         if (ls[i].sockaddr->sa_family == AF_UNIX
  619.             && ngx_process <= NGX_PROCESS_MASTER
  620.             && ngx_new_binary == 0)
  621.         {
  622.             u_char *name = ls[i].addr_text.data + sizeof("unix:") - 1;

  623.             if (ngx_delete_file(name) == NGX_FILE_ERROR) {
  624.                 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_socket_errno,
  625.                               ngx_delete_file_n " %s failed", name);
  626.             }
  627.         }

  628. #endif

  629.         ls[i].fd = (ngx_socket_t) -1;
  630.     }

  631.     cycle->listening.nelts = 0;
  632. }


  633. ngx_connection_t *
  634. ngx_get_connection(ngx_socket_t s, ngx_log_t *log)
  635. {
  636.     ngx_uint_t         instance;
  637.     ngx_event_t       *rev, *wev;
  638.     ngx_connection_t  *c;

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

  640.     if (ngx_cycle->files && (ngx_uint_t) s >= ngx_cycle->files_n) {
  641.         ngx_log_error(NGX_LOG_ALERT, log, 0,
  642.                       "the new socket has number %d, "
  643.                       "but only %ui files are available",
  644.                       s, ngx_cycle->files_n);
  645.         return NULL;
  646.     }

  647.     /* ngx_mutex_lock */

  648.     c = ngx_cycle->free_connections;

  649.     if (c == NULL) {
  650.         ngx_drain_connections();
  651.         c = ngx_cycle->free_connections;
  652.     }

  653.     if (c == NULL) {
  654.         ngx_log_error(NGX_LOG_ALERT, log, 0,
  655.                       "%ui worker_connections are not enough",
  656.                       ngx_cycle->connection_n);

  657.         /* ngx_mutex_unlock */

  658.         return NULL;
  659.     }

  660.     ngx_cycle->free_connections = c->data;
  661.     ngx_cycle->free_connection_n--;

  662.     /* ngx_mutex_unlock */

  663.     if (ngx_cycle->files) {
  664.         ngx_cycle->files[s] = c;
  665.     }

  666.     rev = c->read;
  667.     wev = c->write;

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

  669.     c->read = rev;
  670.     c->write = wev;
  671.     c->fd = s;
  672.     c->log = log;

  673.     instance = rev->instance;

  674.     ngx_memzero(rev, sizeof(ngx_event_t));
  675.     ngx_memzero(wev, sizeof(ngx_event_t));

  676.     rev->instance = !instance;
  677.     wev->instance = !instance;

  678.     rev->index = NGX_INVALID_INDEX;
  679.     wev->index = NGX_INVALID_INDEX;

  680.     rev->data = c;
  681.     wev->data = c;

  682.     wev->write = 1;

  683.     return c;
  684. }


  685. void
  686. ngx_free_connection(ngx_connection_t *c)
  687. {
  688.     /* ngx_mutex_lock */

  689.     c->data = ngx_cycle->free_connections;
  690.     ngx_cycle->free_connections = c;
  691.     ngx_cycle->free_connection_n++;

  692.     /* ngx_mutex_unlock */

  693.     if (ngx_cycle->files) {
  694.         ngx_cycle->files[c->fd] = NULL;
  695.     }
  696. }


  697. void
  698. ngx_close_connection(ngx_connection_t *c)
  699. {
  700.     ngx_err_t     err;
  701.     ngx_uint_t    log_error, level;
  702.     ngx_socket_t  fd;

  703.     if (c->fd == (ngx_socket_t) -1) {
  704.         ngx_log_error(NGX_LOG_ALERT, c->log, 0, "connection already closed");
  705.         return;
  706.     }

  707.     if (c->read->timer_set) {
  708.         ngx_del_timer(c->read);
  709.     }

  710.     if (c->write->timer_set) {
  711.         ngx_del_timer(c->write);
  712.     }

  713.     if (ngx_del_conn) {
  714.         ngx_del_conn(c, NGX_CLOSE_EVENT);

  715.     } else {
  716.         if (c->read->active || c->read->disabled) {
  717.             ngx_del_event(c->read, NGX_READ_EVENT, NGX_CLOSE_EVENT);
  718.         }

  719.         if (c->write->active || c->write->disabled) {
  720.             ngx_del_event(c->write, NGX_WRITE_EVENT, NGX_CLOSE_EVENT);
  721.         }
  722.     }

  723. #if (NGX_THREADS)

  724.     /*
  725.      * we have to clean the connection information before the closing
  726.      * because another thread may reopen the same file descriptor
  727.      * before we clean the connection
  728.      */

  729.     ngx_unlock(&c->lock);

  730. #endif

  731.     if (c->read->posted) {
  732.         ngx_delete_posted_event(c->read);
  733.     }

  734.     if (c->write->posted) {
  735.         ngx_delete_posted_event(c->write);
  736.     }

  737.     c->read->closed = 1;
  738.     c->write->closed = 1;

  739.     ngx_reusable_connection(c, 0);

  740.     log_error = c->log_error;

  741.     ngx_free_connection(c);

  742.     fd = c->fd;
  743.     c->fd = (ngx_socket_t) -1;

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

  745.         err = ngx_socket_errno;

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

  747.             switch (log_error) {

  748.             case NGX_ERROR_INFO:
  749.                 level = NGX_LOG_INFO;
  750.                 break;

  751.             case NGX_ERROR_ERR:
  752.                 level = NGX_LOG_ERR;
  753.                 break;

  754.             default:
  755.                 level = NGX_LOG_CRIT;
  756.             }

  757.         } else {
  758.             level = NGX_LOG_CRIT;
  759.         }

  760.         /* we use ngx_cycle->log because c->log was in c->pool */

  761.         ngx_log_error(level, ngx_cycle->log, err,
  762.                       ngx_close_socket_n " %d failed", fd);
  763.     }
  764. }


  765. void
  766. ngx_reusable_connection(ngx_connection_t *c, ngx_uint_t reusable)
  767. {
  768.     ngx_log_debug1(NGX_LOG_DEBUG_CORE, c->log, 0,
  769.                    "reusable connection: %ui", reusable);

  770.     if (c->reusable) {
  771.         ngx_queue_remove(&c->queue);

  772. #if (NGX_STAT_STUB)
  773.         (void) ngx_atomic_fetch_add(ngx_stat_waiting, -1);
  774. #endif
  775.     }

  776.     c->reusable = reusable;

  777.     if (reusable) {
  778.         /* need cast as ngx_cycle is volatile */

  779.         ngx_queue_insert_head(
  780.             (ngx_queue_t *) &ngx_cycle->reusable_connections_queue, &c->queue);

  781. #if (NGX_STAT_STUB)
  782.         (void) ngx_atomic_fetch_add(ngx_stat_waiting, 1);
  783. #endif
  784.     }
  785. }


  786. static void
  787. ngx_drain_connections(void)
  788. {
  789.     ngx_int_t          i;
  790.     ngx_queue_t       *q;
  791.     ngx_connection_t  *c;

  792.     for (i = 0; i < 32; i++) {
  793.         if (ngx_queue_empty(&ngx_cycle->reusable_connections_queue)) {
  794.             break;
  795.         }

  796.         q = ngx_queue_last(&ngx_cycle->reusable_connections_queue);
  797.         c = ngx_queue_data(q, ngx_connection_t, queue);

  798.         ngx_log_debug0(NGX_LOG_DEBUG_CORE, c->log, 0,
  799.                        "reusing connection");

  800.         c->close = 1;
  801.         c->read->handler(c->read);
  802.     }
  803. }


  804. ngx_int_t
  805. ngx_connection_local_sockaddr(ngx_connection_t *c, ngx_str_t *s,
  806.     ngx_uint_t port)
  807. {
  808.     socklen_t             len;
  809.     ngx_uint_t            addr;
  810.     u_char                sa[NGX_SOCKADDRLEN];
  811.     struct sockaddr_in   *sin;
  812. #if (NGX_HAVE_INET6)
  813.     ngx_uint_t            i;
  814.     struct sockaddr_in6  *sin6;
  815. #endif

  816.     if (c->local_socklen == 0) {
  817.         return NGX_ERROR;
  818.     }

  819.     switch (c->local_sockaddr->sa_family) {

  820. #if (NGX_HAVE_INET6)
  821.     case AF_INET6:
  822.         sin6 = (struct sockaddr_in6 *) c->local_sockaddr;

  823.         for (addr = 0, i = 0; addr == 0 && i < 16; i++) {
  824.             addr |= sin6->sin6_addr.s6_addr[i];
  825.         }

  826.         break;
  827. #endif

  828. #if (NGX_HAVE_UNIX_DOMAIN)
  829.     case AF_UNIX:
  830.         addr = 1;
  831.         break;
  832. #endif

  833.     default: /* AF_INET */
  834.         sin = (struct sockaddr_in *) c->local_sockaddr;
  835.         addr = sin->sin_addr.s_addr;
  836.         break;
  837.     }

  838.     if (addr == 0) {

  839.         len = NGX_SOCKADDRLEN;

  840.         if (getsockname(c->fd, (struct sockaddr *) &sa, &len) == -1) {
  841.             ngx_connection_error(c, ngx_socket_errno, "getsockname() failed");
  842.             return NGX_ERROR;
  843.         }

  844.         c->local_sockaddr = ngx_palloc(c->pool, len);
  845.         if (c->local_sockaddr == NULL) {
  846.             return NGX_ERROR;
  847.         }

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

  849.         c->local_socklen = len;
  850.     }

  851.     if (s == NULL) {
  852.         return NGX_OK;
  853.     }

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

  856.     return NGX_OK;
  857. }


  858. ngx_int_t
  859. ngx_connection_error(ngx_connection_t *c, ngx_err_t err, char *text)
  860. {
  861.     ngx_uint_t  level;

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

  863.     if ((err == NGX_ECONNRESET
  864. #if (NGX_WIN32)
  865.          || err == NGX_ECONNABORTED
  866. #endif
  867.         ) && c->log_error == NGX_ERROR_IGNORE_ECONNRESET)
  868.     {
  869.         return 0;
  870.     }

  871. #if (NGX_SOLARIS)
  872.     if (err == NGX_EINVAL && c->log_error == NGX_ERROR_IGNORE_EINVAL) {
  873.         return 0;
  874.     }
  875. #endif

  876.     if (err == 0
  877.         || err == NGX_ECONNRESET
  878. #if (NGX_WIN32)
  879.         || err == NGX_ECONNABORTED
  880. #else
  881.         || err == NGX_EPIPE
  882. #endif
  883.         || err == NGX_ENOTCONN
  884.         || err == NGX_ETIMEDOUT
  885.         || err == NGX_ECONNREFUSED
  886.         || err == NGX_ENETDOWN
  887.         || err == NGX_ENETUNREACH
  888.         || err == NGX_EHOSTDOWN
  889.         || err == NGX_EHOSTUNREACH)
  890.     {
  891.         switch (c->log_error) {

  892.         case NGX_ERROR_IGNORE_EINVAL:
  893.         case NGX_ERROR_IGNORE_ECONNRESET:
  894.         case NGX_ERROR_INFO:
  895.             level = NGX_LOG_INFO;
  896.             break;

  897.         default:
  898.             level = NGX_LOG_ERR;
  899.         }

  900.     } else {
  901.         level = NGX_LOG_ALERT;
  902.     }

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

  904.     return NGX_ERROR;
  905. }