Back to home page

Nginx displayed by LXR

Source navigation ]
Diff markup ]
Identifier search ]
general search ]
 
 
Version: nginx-1.13.12 ]​[ nginx-1.12.2 ]​

0001 
0002 /*
0003  * Copyright (C) Igor Sysoev
0004  * Copyright (C) Nginx, Inc.
0005  */
0006 
0007 
0008 #include <ngx_config.h>
0009 #include <ngx_core.h>
0010 #include <ngx_event.h>
0011 
0012 
0013 ngx_os_io_t  ngx_io;
0014 
0015 
0016 static void ngx_drain_connections(ngx_cycle_t *cycle);
0017 
0018 
0019 ngx_listening_t *
0020 ngx_create_listening(ngx_conf_t *cf, struct sockaddr *sockaddr,
0021     socklen_t socklen)
0022 {
0023     size_t            len;
0024     ngx_listening_t  *ls;
0025     struct sockaddr  *sa;
0026     u_char            text[NGX_SOCKADDR_STRLEN];
0027 
0028     ls = ngx_array_push(&cf->cycle->listening);
0029     if (ls == NULL) {
0030         return NULL;
0031     }
0032 
0033     ngx_memzero(ls, sizeof(ngx_listening_t));
0034 
0035     sa = ngx_palloc(cf->pool, socklen);
0036     if (sa == NULL) {
0037         return NULL;
0038     }
0039 
0040     ngx_memcpy(sa, sockaddr, socklen);
0041 
0042     ls->sockaddr = sa;
0043     ls->socklen = socklen;
0044 
0045     len = ngx_sock_ntop(sa, socklen, text, NGX_SOCKADDR_STRLEN, 1);
0046     ls->addr_text.len = len;
0047 
0048     switch (ls->sockaddr->sa_family) {
0049 #if (NGX_HAVE_INET6)
0050     case AF_INET6:
0051         ls->addr_text_max_len = NGX_INET6_ADDRSTRLEN;
0052         break;
0053 #endif
0054 #if (NGX_HAVE_UNIX_DOMAIN)
0055     case AF_UNIX:
0056         ls->addr_text_max_len = NGX_UNIX_ADDRSTRLEN;
0057         len++;
0058         break;
0059 #endif
0060     case AF_INET:
0061         ls->addr_text_max_len = NGX_INET_ADDRSTRLEN;
0062         break;
0063     default:
0064         ls->addr_text_max_len = NGX_SOCKADDR_STRLEN;
0065         break;
0066     }
0067 
0068     ls->addr_text.data = ngx_pnalloc(cf->pool, len);
0069     if (ls->addr_text.data == NULL) {
0070         return NULL;
0071     }
0072 
0073     ngx_memcpy(ls->addr_text.data, text, len);
0074 
0075     ls->fd = (ngx_socket_t) -1;
0076     ls->type = SOCK_STREAM;
0077 
0078     ls->backlog = NGX_LISTEN_BACKLOG;
0079     ls->rcvbuf = -1;
0080     ls->sndbuf = -1;
0081 
0082 #if (NGX_HAVE_SETFIB)
0083     ls->setfib = -1;
0084 #endif
0085 
0086 #if (NGX_HAVE_TCP_FASTOPEN)
0087     ls->fastopen = -1;
0088 #endif
0089 
0090     return ls;
0091 }
0092 
0093 
0094 ngx_int_t
0095 ngx_clone_listening(ngx_conf_t *cf, ngx_listening_t *ls)
0096 {
0097 #if (NGX_HAVE_REUSEPORT)
0098 
0099     ngx_int_t         n;
0100     ngx_core_conf_t  *ccf;
0101     ngx_listening_t   ols;
0102 
0103     if (!ls->reuseport) {
0104         return NGX_OK;
0105     }
0106 
0107     ols = *ls;
0108 
0109     ccf = (ngx_core_conf_t *) ngx_get_conf(cf->cycle->conf_ctx,
0110                                            ngx_core_module);
0111 
0112     for (n = 1; n < ccf->worker_processes; n++) {
0113 
0114         /* create a socket for each worker process */
0115 
0116         ls = ngx_array_push(&cf->cycle->listening);
0117         if (ls == NULL) {
0118             return NGX_ERROR;
0119         }
0120 
0121         *ls = ols;
0122         ls->worker = n;
0123     }
0124 
0125 #endif
0126 
0127     return NGX_OK;
0128 }
0129 
0130 
0131 ngx_int_t
0132 ngx_set_inherited_sockets(ngx_cycle_t *cycle)
0133 {
0134     size_t                     len;
0135     ngx_uint_t                 i;
0136     ngx_listening_t           *ls;
0137     socklen_t                  olen;
0138 #if (NGX_HAVE_DEFERRED_ACCEPT || NGX_HAVE_TCP_FASTOPEN)
0139     ngx_err_t                  err;
0140 #endif
0141 #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
0142     struct accept_filter_arg   af;
0143 #endif
0144 #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
0145     int                        timeout;
0146 #endif
0147 #if (NGX_HAVE_REUSEPORT)
0148     int                        reuseport;
0149 #endif
0150 
0151     ls = cycle->listening.elts;
0152     for (i = 0; i < cycle->listening.nelts; i++) {
0153 
0154         ls[i].sockaddr = ngx_palloc(cycle->pool, sizeof(ngx_sockaddr_t));
0155         if (ls[i].sockaddr == NULL) {
0156             return NGX_ERROR;
0157         }
0158 
0159         ls[i].socklen = sizeof(ngx_sockaddr_t);
0160         if (getsockname(ls[i].fd, ls[i].sockaddr, &ls[i].socklen) == -1) {
0161             ngx_log_error(NGX_LOG_CRIT, cycle->log, ngx_socket_errno,
0162                           "getsockname() of the inherited "
0163                           "socket #%d failed", ls[i].fd);
0164             ls[i].ignore = 1;
0165             continue;
0166         }
0167 
0168         if (ls[i].socklen > (socklen_t) sizeof(ngx_sockaddr_t)) {
0169             ls[i].socklen = sizeof(ngx_sockaddr_t);
0170         }
0171 
0172         switch (ls[i].sockaddr->sa_family) {
0173 
0174 #if (NGX_HAVE_INET6)
0175         case AF_INET6:
0176             ls[i].addr_text_max_len = NGX_INET6_ADDRSTRLEN;
0177             len = NGX_INET6_ADDRSTRLEN + sizeof("[]:65535") - 1;
0178             break;
0179 #endif
0180 
0181 #if (NGX_HAVE_UNIX_DOMAIN)
0182         case AF_UNIX:
0183             ls[i].addr_text_max_len = NGX_UNIX_ADDRSTRLEN;
0184             len = NGX_UNIX_ADDRSTRLEN;
0185             break;
0186 #endif
0187 
0188         case AF_INET:
0189             ls[i].addr_text_max_len = NGX_INET_ADDRSTRLEN;
0190             len = NGX_INET_ADDRSTRLEN + sizeof(":65535") - 1;
0191             break;
0192 
0193         default:
0194             ngx_log_error(NGX_LOG_CRIT, cycle->log, ngx_socket_errno,
0195                           "the inherited socket #%d has "
0196                           "an unsupported protocol family", ls[i].fd);
0197             ls[i].ignore = 1;
0198             continue;
0199         }
0200 
0201         ls[i].addr_text.data = ngx_pnalloc(cycle->pool, len);
0202         if (ls[i].addr_text.data == NULL) {
0203             return NGX_ERROR;
0204         }
0205 
0206         len = ngx_sock_ntop(ls[i].sockaddr, ls[i].socklen,
0207                             ls[i].addr_text.data, len, 1);
0208         if (len == 0) {
0209             return NGX_ERROR;
0210         }
0211 
0212         ls[i].addr_text.len = len;
0213 
0214         ls[i].backlog = NGX_LISTEN_BACKLOG;
0215 
0216         olen = sizeof(int);
0217 
0218         if (getsockopt(ls[i].fd, SOL_SOCKET, SO_TYPE, (void *) &ls[i].type,
0219                        &olen)
0220             == -1)
0221         {
0222             ngx_log_error(NGX_LOG_CRIT, cycle->log, ngx_socket_errno,
0223                           "getsockopt(SO_TYPE) %V failed", &ls[i].addr_text);
0224             ls[i].ignore = 1;
0225             continue;
0226         }
0227 
0228         olen = sizeof(int);
0229 
0230         if (getsockopt(ls[i].fd, SOL_SOCKET, SO_RCVBUF, (void *) &ls[i].rcvbuf,
0231                        &olen)
0232             == -1)
0233         {
0234             ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
0235                           "getsockopt(SO_RCVBUF) %V failed, ignored",
0236                           &ls[i].addr_text);
0237 
0238             ls[i].rcvbuf = -1;
0239         }
0240 
0241         olen = sizeof(int);
0242 
0243         if (getsockopt(ls[i].fd, SOL_SOCKET, SO_SNDBUF, (void *) &ls[i].sndbuf,
0244                        &olen)
0245             == -1)
0246         {
0247             ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
0248                           "getsockopt(SO_SNDBUF) %V failed, ignored",
0249                           &ls[i].addr_text);
0250 
0251             ls[i].sndbuf = -1;
0252         }
0253 
0254 #if 0
0255         /* SO_SETFIB is currently a set only option */
0256 
0257 #if (NGX_HAVE_SETFIB)
0258 
0259         olen = sizeof(int);
0260 
0261         if (getsockopt(ls[i].fd, SOL_SOCKET, SO_SETFIB,
0262                        (void *) &ls[i].setfib, &olen)
0263             == -1)
0264         {
0265             ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
0266                           "getsockopt(SO_SETFIB) %V failed, ignored",
0267                           &ls[i].addr_text);
0268 
0269             ls[i].setfib = -1;
0270         }
0271 
0272 #endif
0273 #endif
0274 
0275 #if (NGX_HAVE_REUSEPORT)
0276 
0277         reuseport = 0;
0278         olen = sizeof(int);
0279 
0280         if (getsockopt(ls[i].fd, SOL_SOCKET, SO_REUSEPORT,
0281                        (void *) &reuseport, &olen)
0282             == -1)
0283         {
0284             ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
0285                           "getsockopt(SO_REUSEPORT) %V failed, ignored",
0286                           &ls[i].addr_text);
0287 
0288         } else {
0289             ls[i].reuseport = reuseport ? 1 : 0;
0290         }
0291 
0292 #endif
0293 
0294         if (ls[i].type != SOCK_STREAM) {
0295             continue;
0296         }
0297 
0298 #if (NGX_HAVE_TCP_FASTOPEN)
0299 
0300         olen = sizeof(int);
0301 
0302         if (getsockopt(ls[i].fd, IPPROTO_TCP, TCP_FASTOPEN,
0303                        (void *) &ls[i].fastopen, &olen)
0304             == -1)
0305         {
0306             err = ngx_socket_errno;
0307 
0308             if (err != NGX_EOPNOTSUPP && err != NGX_ENOPROTOOPT) {
0309                 ngx_log_error(NGX_LOG_NOTICE, cycle->log, err,
0310                               "getsockopt(TCP_FASTOPEN) %V failed, ignored",
0311                               &ls[i].addr_text);
0312             }
0313 
0314             ls[i].fastopen = -1;
0315         }
0316 
0317 #endif
0318 
0319 #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
0320 
0321         ngx_memzero(&af, sizeof(struct accept_filter_arg));
0322         olen = sizeof(struct accept_filter_arg);
0323 
0324         if (getsockopt(ls[i].fd, SOL_SOCKET, SO_ACCEPTFILTER, &af, &olen)
0325             == -1)
0326         {
0327             err = ngx_socket_errno;
0328 
0329             if (err == NGX_EINVAL) {
0330                 continue;
0331             }
0332 
0333             ngx_log_error(NGX_LOG_NOTICE, cycle->log, err,
0334                           "getsockopt(SO_ACCEPTFILTER) for %V failed, ignored",
0335                           &ls[i].addr_text);
0336             continue;
0337         }
0338 
0339         if (olen < sizeof(struct accept_filter_arg) || af.af_name[0] == '\0') {
0340             continue;
0341         }
0342 
0343         ls[i].accept_filter = ngx_palloc(cycle->pool, 16);
0344         if (ls[i].accept_filter == NULL) {
0345             return NGX_ERROR;
0346         }
0347 
0348         (void) ngx_cpystrn((u_char *) ls[i].accept_filter,
0349                            (u_char *) af.af_name, 16);
0350 #endif
0351 
0352 #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
0353 
0354         timeout = 0;
0355         olen = sizeof(int);
0356 
0357         if (getsockopt(ls[i].fd, IPPROTO_TCP, TCP_DEFER_ACCEPT, &timeout, &olen)
0358             == -1)
0359         {
0360             err = ngx_socket_errno;
0361 
0362             if (err == NGX_EOPNOTSUPP) {
0363                 continue;
0364             }
0365 
0366             ngx_log_error(NGX_LOG_NOTICE, cycle->log, err,
0367                           "getsockopt(TCP_DEFER_ACCEPT) for %V failed, ignored",
0368                           &ls[i].addr_text);
0369             continue;
0370         }
0371 
0372         if (olen < sizeof(int) || timeout == 0) {
0373             continue;
0374         }
0375 
0376         ls[i].deferred_accept = 1;
0377 #endif
0378     }
0379 
0380     return NGX_OK;
0381 }
0382 
0383 
0384 ngx_int_t
0385 ngx_open_listening_sockets(ngx_cycle_t *cycle)
0386 {
0387     int               reuseaddr;
0388     ngx_uint_t        i, tries, failed;
0389     ngx_err_t         err;
0390     ngx_log_t        *log;
0391     ngx_socket_t      s;
0392     ngx_listening_t  *ls;
0393 
0394     reuseaddr = 1;
0395 #if (NGX_SUPPRESS_WARN)
0396     failed = 0;
0397 #endif
0398 
0399     log = cycle->log;
0400 
0401     /* TODO: configurable try number */
0402 
0403     for (tries = 5; tries; tries--) {
0404         failed = 0;
0405 
0406         /* for each listening socket */
0407 
0408         ls = cycle->listening.elts;
0409         for (i = 0; i < cycle->listening.nelts; i++) {
0410 
0411             if (ls[i].ignore) {
0412                 continue;
0413             }
0414 
0415 #if (NGX_HAVE_REUSEPORT)
0416 
0417             if (ls[i].add_reuseport) {
0418 
0419                 /*
0420                  * to allow transition from a socket without SO_REUSEPORT
0421                  * to multiple sockets with SO_REUSEPORT, we have to set
0422                  * SO_REUSEPORT on the old socket before opening new ones
0423                  */
0424 
0425                 int  reuseport = 1;
0426 
0427                 if (setsockopt(ls[i].fd, SOL_SOCKET, SO_REUSEPORT,
0428                                (const void *) &reuseport, sizeof(int))
0429                     == -1)
0430                 {
0431                     ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
0432                                   "setsockopt(SO_REUSEPORT) %V failed, ignored",
0433                                   &ls[i].addr_text);
0434                 }
0435 
0436                 ls[i].add_reuseport = 0;
0437             }
0438 #endif
0439 
0440             if (ls[i].fd != (ngx_socket_t) -1) {
0441                 continue;
0442             }
0443 
0444             if (ls[i].inherited) {
0445 
0446                 /* TODO: close on exit */
0447                 /* TODO: nonblocking */
0448                 /* TODO: deferred accept */
0449 
0450                 continue;
0451             }
0452 
0453             s = ngx_socket(ls[i].sockaddr->sa_family, ls[i].type, 0);
0454 
0455             if (s == (ngx_socket_t) -1) {
0456                 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
0457                               ngx_socket_n " %V failed", &ls[i].addr_text);
0458                 return NGX_ERROR;
0459             }
0460 
0461             if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
0462                            (const void *) &reuseaddr, sizeof(int))
0463                 == -1)
0464             {
0465                 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
0466                               "setsockopt(SO_REUSEADDR) %V failed",
0467                               &ls[i].addr_text);
0468 
0469                 if (ngx_close_socket(s) == -1) {
0470                     ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
0471                                   ngx_close_socket_n " %V failed",
0472                                   &ls[i].addr_text);
0473                 }
0474 
0475                 return NGX_ERROR;
0476             }
0477 
0478 #if (NGX_HAVE_REUSEPORT)
0479 
0480             if (ls[i].reuseport && !ngx_test_config) {
0481                 int  reuseport;
0482 
0483                 reuseport = 1;
0484 
0485                 if (setsockopt(s, SOL_SOCKET, SO_REUSEPORT,
0486                                (const void *) &reuseport, sizeof(int))
0487                     == -1)
0488                 {
0489                     ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
0490                                   "setsockopt(SO_REUSEPORT) %V failed",
0491                                   &ls[i].addr_text);
0492 
0493                     if (ngx_close_socket(s) == -1) {
0494                         ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
0495                                       ngx_close_socket_n " %V failed",
0496                                       &ls[i].addr_text);
0497                     }
0498 
0499                     return NGX_ERROR;
0500                 }
0501             }
0502 #endif
0503 
0504 #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
0505 
0506             if (ls[i].sockaddr->sa_family == AF_INET6) {
0507                 int  ipv6only;
0508 
0509                 ipv6only = ls[i].ipv6only;
0510 
0511                 if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY,
0512                                (const void *) &ipv6only, sizeof(int))
0513                     == -1)
0514                 {
0515                     ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
0516                                   "setsockopt(IPV6_V6ONLY) %V failed, ignored",
0517                                   &ls[i].addr_text);
0518                 }
0519             }
0520 #endif
0521             /* TODO: close on exit */
0522 
0523             if (!(ngx_event_flags & NGX_USE_IOCP_EVENT)) {
0524                 if (ngx_nonblocking(s) == -1) {
0525                     ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
0526                                   ngx_nonblocking_n " %V failed",
0527                                   &ls[i].addr_text);
0528 
0529                     if (ngx_close_socket(s) == -1) {
0530                         ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
0531                                       ngx_close_socket_n " %V failed",
0532                                       &ls[i].addr_text);
0533                     }
0534 
0535                     return NGX_ERROR;
0536                 }
0537             }
0538 
0539             ngx_log_debug2(NGX_LOG_DEBUG_CORE, log, 0,
0540                            "bind() %V #%d ", &ls[i].addr_text, s);
0541 
0542             if (bind(s, ls[i].sockaddr, ls[i].socklen) == -1) {
0543                 err = ngx_socket_errno;
0544 
0545                 if (err != NGX_EADDRINUSE || !ngx_test_config) {
0546                     ngx_log_error(NGX_LOG_EMERG, log, err,
0547                                   "bind() to %V failed", &ls[i].addr_text);
0548                 }
0549 
0550                 if (ngx_close_socket(s) == -1) {
0551                     ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
0552                                   ngx_close_socket_n " %V failed",
0553                                   &ls[i].addr_text);
0554                 }
0555 
0556                 if (err != NGX_EADDRINUSE) {
0557                     return NGX_ERROR;
0558                 }
0559 
0560                 if (!ngx_test_config) {
0561                     failed = 1;
0562                 }
0563 
0564                 continue;
0565             }
0566 
0567 #if (NGX_HAVE_UNIX_DOMAIN)
0568 
0569             if (ls[i].sockaddr->sa_family == AF_UNIX) {
0570                 mode_t   mode;
0571                 u_char  *name;
0572 
0573                 name = ls[i].addr_text.data + sizeof("unix:") - 1;
0574                 mode = (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
0575 
0576                 if (chmod((char *) name, mode) == -1) {
0577                     ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
0578                                   "chmod() \"%s\" failed", name);
0579                 }
0580 
0581                 if (ngx_test_config) {
0582                     if (ngx_delete_file(name) == NGX_FILE_ERROR) {
0583                         ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
0584                                       ngx_delete_file_n " %s failed", name);
0585                     }
0586                 }
0587             }
0588 #endif
0589 
0590             if (ls[i].type != SOCK_STREAM) {
0591                 ls[i].fd = s;
0592                 continue;
0593             }
0594 
0595             if (listen(s, ls[i].backlog) == -1) {
0596                 err = ngx_socket_errno;
0597 
0598                 /*
0599                  * on OpenVZ after suspend/resume EADDRINUSE
0600                  * may be returned by listen() instead of bind(), see
0601                  * https://bugzilla.openvz.org/show_bug.cgi?id=2470
0602                  */
0603 
0604                 if (err != NGX_EADDRINUSE || !ngx_test_config) {
0605                     ngx_log_error(NGX_LOG_EMERG, log, err,
0606                                   "listen() to %V, backlog %d failed",
0607                                   &ls[i].addr_text, ls[i].backlog);
0608                 }
0609 
0610                 if (ngx_close_socket(s) == -1) {
0611                     ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
0612                                   ngx_close_socket_n " %V failed",
0613                                   &ls[i].addr_text);
0614                 }
0615 
0616                 if (err != NGX_EADDRINUSE) {
0617                     return NGX_ERROR;
0618                 }
0619 
0620                 if (!ngx_test_config) {
0621                     failed = 1;
0622                 }
0623 
0624                 continue;
0625             }
0626 
0627             ls[i].listen = 1;
0628 
0629             ls[i].fd = s;
0630         }
0631 
0632         if (!failed) {
0633             break;
0634         }
0635 
0636         /* TODO: delay configurable */
0637 
0638         ngx_log_error(NGX_LOG_NOTICE, log, 0,
0639                       "try again to bind() after 500ms");
0640 
0641         ngx_msleep(500);
0642     }
0643 
0644     if (failed) {
0645         ngx_log_error(NGX_LOG_EMERG, log, 0, "still could not bind()");
0646         return NGX_ERROR;
0647     }
0648 
0649     return NGX_OK;
0650 }
0651 
0652 
0653 void
0654 ngx_configure_listening_sockets(ngx_cycle_t *cycle)
0655 {
0656     int                        value;
0657     ngx_uint_t                 i;
0658     ngx_listening_t           *ls;
0659 
0660 #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
0661     struct accept_filter_arg   af;
0662 #endif
0663 
0664     ls = cycle->listening.elts;
0665     for (i = 0; i < cycle->listening.nelts; i++) {
0666 
0667         ls[i].log = *ls[i].logp;
0668 
0669         if (ls[i].rcvbuf != -1) {
0670             if (setsockopt(ls[i].fd, SOL_SOCKET, SO_RCVBUF,
0671                            (const void *) &ls[i].rcvbuf, sizeof(int))
0672                 == -1)
0673             {
0674                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
0675                               "setsockopt(SO_RCVBUF, %d) %V failed, ignored",
0676                               ls[i].rcvbuf, &ls[i].addr_text);
0677             }
0678         }
0679 
0680         if (ls[i].sndbuf != -1) {
0681             if (setsockopt(ls[i].fd, SOL_SOCKET, SO_SNDBUF,
0682                            (const void *) &ls[i].sndbuf, sizeof(int))
0683                 == -1)
0684             {
0685                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
0686                               "setsockopt(SO_SNDBUF, %d) %V failed, ignored",
0687                               ls[i].sndbuf, &ls[i].addr_text);
0688             }
0689         }
0690 
0691         if (ls[i].keepalive) {
0692             value = (ls[i].keepalive == 1) ? 1 : 0;
0693 
0694             if (setsockopt(ls[i].fd, SOL_SOCKET, SO_KEEPALIVE,
0695                            (const void *) &value, sizeof(int))
0696                 == -1)
0697             {
0698                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
0699                               "setsockopt(SO_KEEPALIVE, %d) %V failed, ignored",
0700                               value, &ls[i].addr_text);
0701             }
0702         }
0703 
0704 #if (NGX_HAVE_KEEPALIVE_TUNABLE)
0705 
0706         if (ls[i].keepidle) {
0707             value = ls[i].keepidle;
0708 
0709 #if (NGX_KEEPALIVE_FACTOR)
0710             value *= NGX_KEEPALIVE_FACTOR;
0711 #endif
0712 
0713             if (setsockopt(ls[i].fd, IPPROTO_TCP, TCP_KEEPIDLE,
0714                            (const void *) &value, sizeof(int))
0715                 == -1)
0716             {
0717                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
0718                               "setsockopt(TCP_KEEPIDLE, %d) %V failed, ignored",
0719                               value, &ls[i].addr_text);
0720             }
0721         }
0722 
0723         if (ls[i].keepintvl) {
0724             value = ls[i].keepintvl;
0725 
0726 #if (NGX_KEEPALIVE_FACTOR)
0727             value *= NGX_KEEPALIVE_FACTOR;
0728 #endif
0729 
0730             if (setsockopt(ls[i].fd, IPPROTO_TCP, TCP_KEEPINTVL,
0731                            (const void *) &value, sizeof(int))
0732                 == -1)
0733             {
0734                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
0735                              "setsockopt(TCP_KEEPINTVL, %d) %V failed, ignored",
0736                              value, &ls[i].addr_text);
0737             }
0738         }
0739 
0740         if (ls[i].keepcnt) {
0741             if (setsockopt(ls[i].fd, IPPROTO_TCP, TCP_KEEPCNT,
0742                            (const void *) &ls[i].keepcnt, sizeof(int))
0743                 == -1)
0744             {
0745                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
0746                               "setsockopt(TCP_KEEPCNT, %d) %V failed, ignored",
0747                               ls[i].keepcnt, &ls[i].addr_text);
0748             }
0749         }
0750 
0751 #endif
0752 
0753 #if (NGX_HAVE_SETFIB)
0754         if (ls[i].setfib != -1) {
0755             if (setsockopt(ls[i].fd, SOL_SOCKET, SO_SETFIB,
0756                            (const void *) &ls[i].setfib, sizeof(int))
0757                 == -1)
0758             {
0759                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
0760                               "setsockopt(SO_SETFIB, %d) %V failed, ignored",
0761                               ls[i].setfib, &ls[i].addr_text);
0762             }
0763         }
0764 #endif
0765 
0766 #if (NGX_HAVE_TCP_FASTOPEN)
0767         if (ls[i].fastopen != -1) {
0768             if (setsockopt(ls[i].fd, IPPROTO_TCP, TCP_FASTOPEN,
0769                            (const void *) &ls[i].fastopen, sizeof(int))
0770                 == -1)
0771             {
0772                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
0773                               "setsockopt(TCP_FASTOPEN, %d) %V failed, ignored",
0774                               ls[i].fastopen, &ls[i].addr_text);
0775             }
0776         }
0777 #endif
0778 
0779 #if 0
0780         if (1) {
0781             int tcp_nodelay = 1;
0782 
0783             if (setsockopt(ls[i].fd, IPPROTO_TCP, TCP_NODELAY,
0784                        (const void *) &tcp_nodelay, sizeof(int))
0785                 == -1)
0786             {
0787                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
0788                               "setsockopt(TCP_NODELAY) %V failed, ignored",
0789                               &ls[i].addr_text);
0790             }
0791         }
0792 #endif
0793 
0794         if (ls[i].listen) {
0795 
0796             /* change backlog via listen() */
0797 
0798             if (listen(ls[i].fd, ls[i].backlog) == -1) {
0799                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
0800                               "listen() to %V, backlog %d failed, ignored",
0801                               &ls[i].addr_text, ls[i].backlog);
0802             }
0803         }
0804 
0805         /*
0806          * setting deferred mode should be last operation on socket,
0807          * because code may prematurely continue cycle on failure
0808          */
0809 
0810 #if (NGX_HAVE_DEFERRED_ACCEPT)
0811 
0812 #ifdef SO_ACCEPTFILTER
0813 
0814         if (ls[i].delete_deferred) {
0815             if (setsockopt(ls[i].fd, SOL_SOCKET, SO_ACCEPTFILTER, NULL, 0)
0816                 == -1)
0817             {
0818                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
0819                               "setsockopt(SO_ACCEPTFILTER, NULL) "
0820                               "for %V failed, ignored",
0821                               &ls[i].addr_text);
0822 
0823                 if (ls[i].accept_filter) {
0824                     ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
0825                                   "could not change the accept filter "
0826                                   "to \"%s\" for %V, ignored",
0827                                   ls[i].accept_filter, &ls[i].addr_text);
0828                 }
0829 
0830                 continue;
0831             }
0832 
0833             ls[i].deferred_accept = 0;
0834         }
0835 
0836         if (ls[i].add_deferred) {
0837             ngx_memzero(&af, sizeof(struct accept_filter_arg));
0838             (void) ngx_cpystrn((u_char *) af.af_name,
0839                                (u_char *) ls[i].accept_filter, 16);
0840 
0841             if (setsockopt(ls[i].fd, SOL_SOCKET, SO_ACCEPTFILTER,
0842                            &af, sizeof(struct accept_filter_arg))
0843                 == -1)
0844             {
0845                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
0846                               "setsockopt(SO_ACCEPTFILTER, \"%s\") "
0847                               "for %V failed, ignored",
0848                               ls[i].accept_filter, &ls[i].addr_text);
0849                 continue;
0850             }
0851 
0852             ls[i].deferred_accept = 1;
0853         }
0854 
0855 #endif
0856 
0857 #ifdef TCP_DEFER_ACCEPT
0858 
0859         if (ls[i].add_deferred || ls[i].delete_deferred) {
0860 
0861             if (ls[i].add_deferred) {
0862                 /*
0863                  * There is no way to find out how long a connection was
0864                  * in queue (and a connection may bypass deferred queue at all
0865                  * if syncookies were used), hence we use 1 second timeout
0866                  * here.
0867                  */
0868                 value = 1;
0869 
0870             } else {
0871                 value = 0;
0872             }
0873 
0874             if (setsockopt(ls[i].fd, IPPROTO_TCP, TCP_DEFER_ACCEPT,
0875                            &value, sizeof(int))
0876                 == -1)
0877             {
0878                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
0879                               "setsockopt(TCP_DEFER_ACCEPT, %d) for %V failed, "
0880                               "ignored",
0881                               value, &ls[i].addr_text);
0882 
0883                 continue;
0884             }
0885         }
0886 
0887         if (ls[i].add_deferred) {
0888             ls[i].deferred_accept = 1;
0889         }
0890 
0891 #endif
0892 
0893 #endif /* NGX_HAVE_DEFERRED_ACCEPT */
0894 
0895 #if (NGX_HAVE_IP_RECVDSTADDR)
0896 
0897         if (ls[i].wildcard
0898             && ls[i].type == SOCK_DGRAM
0899             && ls[i].sockaddr->sa_family == AF_INET)
0900         {
0901             value = 1;
0902 
0903             if (setsockopt(ls[i].fd, IPPROTO_IP, IP_RECVDSTADDR,
0904                            (const void *) &value, sizeof(int))
0905                 == -1)
0906             {
0907                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
0908                               "setsockopt(IP_RECVDSTADDR) "
0909                               "for %V failed, ignored",
0910                               &ls[i].addr_text);
0911             }
0912         }
0913 
0914 #elif (NGX_HAVE_IP_PKTINFO)
0915 
0916         if (ls[i].wildcard
0917             && ls[i].type == SOCK_DGRAM
0918             && ls[i].sockaddr->sa_family == AF_INET)
0919         {
0920             value = 1;
0921 
0922             if (setsockopt(ls[i].fd, IPPROTO_IP, IP_PKTINFO,
0923                            (const void *) &value, sizeof(int))
0924                 == -1)
0925             {
0926                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
0927                               "setsockopt(IP_PKTINFO) "
0928                               "for %V failed, ignored",
0929                               &ls[i].addr_text);
0930             }
0931         }
0932 
0933 #endif
0934 
0935 #if (NGX_HAVE_INET6 && NGX_HAVE_IPV6_RECVPKTINFO)
0936 
0937         if (ls[i].wildcard
0938             && ls[i].type == SOCK_DGRAM
0939             && ls[i].sockaddr->sa_family == AF_INET6)
0940         {
0941             value = 1;
0942 
0943             if (setsockopt(ls[i].fd, IPPROTO_IPV6, IPV6_RECVPKTINFO,
0944                            (const void *) &value, sizeof(int))
0945                 == -1)
0946             {
0947                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
0948                               "setsockopt(IPV6_RECVPKTINFO) "
0949                               "for %V failed, ignored",
0950                               &ls[i].addr_text);
0951             }
0952         }
0953 
0954 #endif
0955     }
0956 
0957     return;
0958 }
0959 
0960 
0961 void
0962 ngx_close_listening_sockets(ngx_cycle_t *cycle)
0963 {
0964     ngx_uint_t         i;
0965     ngx_listening_t   *ls;
0966     ngx_connection_t  *c;
0967 
0968     if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
0969         return;
0970     }
0971 
0972     ngx_accept_mutex_held = 0;
0973     ngx_use_accept_mutex = 0;
0974 
0975     ls = cycle->listening.elts;
0976     for (i = 0; i < cycle->listening.nelts; i++) {
0977 
0978         c = ls[i].connection;
0979 
0980         if (c) {
0981             if (c->read->active) {
0982                 if (ngx_event_flags & NGX_USE_EPOLL_EVENT) {
0983 
0984                     /*
0985                      * it seems that Linux-2.6.x OpenVZ sends events
0986                      * for closed shared listening sockets unless
0987                      * the events was explicitly deleted
0988                      */
0989 
0990                     ngx_del_event(c->read, NGX_READ_EVENT, 0);
0991 
0992                 } else {
0993                     ngx_del_event(c->read, NGX_READ_EVENT, NGX_CLOSE_EVENT);
0994                 }
0995             }
0996 
0997             ngx_free_connection(c);
0998 
0999             c->fd = (ngx_socket_t) -1;
1000         }
1001 
1002         ngx_log_debug2(NGX_LOG_DEBUG_CORE, cycle->log, 0,
1003                        "close listening %V #%d ", &ls[i].addr_text, ls[i].fd);
1004 
1005         if (ngx_close_socket(ls[i].fd) == -1) {
1006             ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_socket_errno,
1007                           ngx_close_socket_n " %V failed", &ls[i].addr_text);
1008         }
1009 
1010 #if (NGX_HAVE_UNIX_DOMAIN)
1011 
1012         if (ls[i].sockaddr->sa_family == AF_UNIX
1013             && ngx_process <= NGX_PROCESS_MASTER
1014             && ngx_new_binary == 0)
1015         {
1016             u_char *name = ls[i].addr_text.data + sizeof("unix:") - 1;
1017 
1018             if (ngx_delete_file(name) == NGX_FILE_ERROR) {
1019                 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_socket_errno,
1020                               ngx_delete_file_n " %s failed", name);
1021             }
1022         }
1023 
1024 #endif
1025 
1026         ls[i].fd = (ngx_socket_t) -1;
1027     }
1028 
1029     cycle->listening.nelts = 0;
1030 }
1031 
1032 
1033 ngx_connection_t *
1034 ngx_get_connection(ngx_socket_t s, ngx_log_t *log)
1035 {
1036     ngx_uint_t         instance;
1037     ngx_event_t       *rev, *wev;
1038     ngx_connection_t  *c;
1039 
1040     /* disable warning: Win32 SOCKET is u_int while UNIX socket is int */
1041 
1042     if (ngx_cycle->files && (ngx_uint_t) s >= ngx_cycle->files_n) {
1043         ngx_log_error(NGX_LOG_ALERT, log, 0,
1044                       "the new socket has number %d, "
1045                       "but only %ui files are available",
1046                       s, ngx_cycle->files_n);
1047         return NULL;
1048     }
1049 
1050     c = ngx_cycle->free_connections;
1051 
1052     if (c == NULL) {
1053         ngx_drain_connections((ngx_cycle_t *) ngx_cycle);
1054         c = ngx_cycle->free_connections;
1055     }
1056 
1057     if (c == NULL) {
1058         ngx_log_error(NGX_LOG_ALERT, log, 0,
1059                       "%ui worker_connections are not enough",
1060                       ngx_cycle->connection_n);
1061 
1062         return NULL;
1063     }
1064 
1065     ngx_cycle->free_connections = c->data;
1066     ngx_cycle->free_connection_n--;
1067 
1068     if (ngx_cycle->files && ngx_cycle->files[s] == NULL) {
1069         ngx_cycle->files[s] = c;
1070     }
1071 
1072     rev = c->read;
1073     wev = c->write;
1074 
1075     ngx_memzero(c, sizeof(ngx_connection_t));
1076 
1077     c->read = rev;
1078     c->write = wev;
1079     c->fd = s;
1080     c->log = log;
1081 
1082     instance = rev->instance;
1083 
1084     ngx_memzero(rev, sizeof(ngx_event_t));
1085     ngx_memzero(wev, sizeof(ngx_event_t));
1086 
1087     rev->instance = !instance;
1088     wev->instance = !instance;
1089 
1090     rev->index = NGX_INVALID_INDEX;
1091     wev->index = NGX_INVALID_INDEX;
1092 
1093     rev->data = c;
1094     wev->data = c;
1095 
1096     wev->write = 1;
1097 
1098     return c;
1099 }
1100 
1101 
1102 void
1103 ngx_free_connection(ngx_connection_t *c)
1104 {
1105     c->data = ngx_cycle->free_connections;
1106     ngx_cycle->free_connections = c;
1107     ngx_cycle->free_connection_n++;
1108 
1109     if (ngx_cycle->files && ngx_cycle->files[c->fd] == c) {
1110         ngx_cycle->files[c->fd] = NULL;
1111     }
1112 }
1113 
1114 
1115 void
1116 ngx_close_connection(ngx_connection_t *c)
1117 {
1118     ngx_err_t     err;
1119     ngx_uint_t    log_error, level;
1120     ngx_socket_t  fd;
1121 
1122     if (c->fd == (ngx_socket_t) -1) {
1123         ngx_log_error(NGX_LOG_ALERT, c->log, 0, "connection already closed");
1124         return;
1125     }
1126 
1127     if (c->read->timer_set) {
1128         ngx_del_timer(c->read);
1129     }
1130 
1131     if (c->write->timer_set) {
1132         ngx_del_timer(c->write);
1133     }
1134 
1135     if (!c->shared) {
1136         if (ngx_del_conn) {
1137             ngx_del_conn(c, NGX_CLOSE_EVENT);
1138 
1139         } else {
1140             if (c->read->active || c->read->disabled) {
1141                 ngx_del_event(c->read, NGX_READ_EVENT, NGX_CLOSE_EVENT);
1142             }
1143 
1144             if (c->write->active || c->write->disabled) {
1145                 ngx_del_event(c->write, NGX_WRITE_EVENT, NGX_CLOSE_EVENT);
1146             }
1147         }
1148     }
1149 
1150     if (c->read->posted) {
1151         ngx_delete_posted_event(c->read);
1152     }
1153 
1154     if (c->write->posted) {
1155         ngx_delete_posted_event(c->write);
1156     }
1157 
1158     c->read->closed = 1;
1159     c->write->closed = 1;
1160 
1161     ngx_reusable_connection(c, 0);
1162 
1163     log_error = c->log_error;
1164 
1165     ngx_free_connection(c);
1166 
1167     fd = c->fd;
1168     c->fd = (ngx_socket_t) -1;
1169 
1170     if (c->shared) {
1171         return;
1172     }
1173 
1174     if (ngx_close_socket(fd) == -1) {
1175 
1176         err = ngx_socket_errno;
1177 
1178         if (err == NGX_ECONNRESET || err == NGX_ENOTCONN) {
1179 
1180             switch (log_error) {
1181 
1182             case NGX_ERROR_INFO:
1183                 level = NGX_LOG_INFO;
1184                 break;
1185 
1186             case NGX_ERROR_ERR:
1187                 level = NGX_LOG_ERR;
1188                 break;
1189 
1190             default:
1191                 level = NGX_LOG_CRIT;
1192             }
1193 
1194         } else {
1195             level = NGX_LOG_CRIT;
1196         }
1197 
1198         ngx_log_error(level, c->log, err, ngx_close_socket_n " %d failed", fd);
1199     }
1200 }
1201 
1202 
1203 void
1204 ngx_reusable_connection(ngx_connection_t *c, ngx_uint_t reusable)
1205 {
1206     ngx_log_debug1(NGX_LOG_DEBUG_CORE, c->log, 0,
1207                    "reusable connection: %ui", reusable);
1208 
1209     if (c->reusable) {
1210         ngx_queue_remove(&c->queue);
1211         ngx_cycle->reusable_connections_n--;
1212 
1213 #if (NGX_STAT_STUB)
1214         (void) ngx_atomic_fetch_add(ngx_stat_waiting, -1);
1215 #endif
1216     }
1217 
1218     c->reusable = reusable;
1219 
1220     if (reusable) {
1221         /* need cast as ngx_cycle is volatile */
1222 
1223         ngx_queue_insert_head(
1224             (ngx_queue_t *) &ngx_cycle->reusable_connections_queue, &c->queue);
1225         ngx_cycle->reusable_connections_n++;
1226 
1227 #if (NGX_STAT_STUB)
1228         (void) ngx_atomic_fetch_add(ngx_stat_waiting, 1);
1229 #endif
1230     }
1231 }
1232 
1233 
1234 static void
1235 ngx_drain_connections(ngx_cycle_t *cycle)
1236 {
1237     ngx_uint_t         i, n;
1238     ngx_queue_t       *q;
1239     ngx_connection_t  *c;
1240 
1241     n = ngx_max(ngx_min(32, cycle->reusable_connections_n / 8), 1);
1242 
1243     for (i = 0; i < n; i++) {
1244         if (ngx_queue_empty(&cycle->reusable_connections_queue)) {
1245             break;
1246         }
1247 
1248         q = ngx_queue_last(&cycle->reusable_connections_queue);
1249         c = ngx_queue_data(q, ngx_connection_t, queue);
1250 
1251         ngx_log_debug0(NGX_LOG_DEBUG_CORE, c->log, 0,
1252                        "reusing connection");
1253 
1254         c->close = 1;
1255         c->read->handler(c->read);
1256     }
1257 }
1258 
1259 
1260 void
1261 ngx_close_idle_connections(ngx_cycle_t *cycle)
1262 {
1263     ngx_uint_t         i;
1264     ngx_connection_t  *c;
1265 
1266     c = cycle->connections;
1267 
1268     for (i = 0; i < cycle->connection_n; i++) {
1269 
1270         /* THREAD: lock */
1271 
1272         if (c[i].fd != (ngx_socket_t) -1 && c[i].idle) {
1273             c[i].close = 1;
1274             c[i].read->handler(c[i].read);
1275         }
1276     }
1277 }
1278 
1279 
1280 ngx_int_t
1281 ngx_connection_local_sockaddr(ngx_connection_t *c, ngx_str_t *s,
1282     ngx_uint_t port)
1283 {
1284     socklen_t             len;
1285     ngx_uint_t            addr;
1286     ngx_sockaddr_t        sa;
1287     struct sockaddr_in   *sin;
1288 #if (NGX_HAVE_INET6)
1289     ngx_uint_t            i;
1290     struct sockaddr_in6  *sin6;
1291 #endif
1292 
1293     addr = 0;
1294 
1295     if (c->local_socklen) {
1296         switch (c->local_sockaddr->sa_family) {
1297 
1298 #if (NGX_HAVE_INET6)
1299         case AF_INET6:
1300             sin6 = (struct sockaddr_in6 *) c->local_sockaddr;
1301 
1302             for (i = 0; addr == 0 && i < 16; i++) {
1303                 addr |= sin6->sin6_addr.s6_addr[i];
1304             }
1305 
1306             break;
1307 #endif
1308 
1309 #if (NGX_HAVE_UNIX_DOMAIN)
1310         case AF_UNIX:
1311             addr = 1;
1312             break;
1313 #endif
1314 
1315         default: /* AF_INET */
1316             sin = (struct sockaddr_in *) c->local_sockaddr;
1317             addr = sin->sin_addr.s_addr;
1318             break;
1319         }
1320     }
1321 
1322     if (addr == 0) {
1323 
1324         len = sizeof(ngx_sockaddr_t);
1325 
1326         if (getsockname(c->fd, &sa.sockaddr, &len) == -1) {
1327             ngx_connection_error(c, ngx_socket_errno, "getsockname() failed");
1328             return NGX_ERROR;
1329         }
1330 
1331         c->local_sockaddr = ngx_palloc(c->pool, len);
1332         if (c->local_sockaddr == NULL) {
1333             return NGX_ERROR;
1334         }
1335 
1336         ngx_memcpy(c->local_sockaddr, &sa, len);
1337 
1338         c->local_socklen = len;
1339     }
1340 
1341     if (s == NULL) {
1342         return NGX_OK;
1343     }
1344 
1345     s->len = ngx_sock_ntop(c->local_sockaddr, c->local_socklen,
1346                            s->data, s->len, port);
1347 
1348     return NGX_OK;
1349 }
1350 
1351 
1352 ngx_int_t
1353 ngx_connection_error(ngx_connection_t *c, ngx_err_t err, char *text)
1354 {
1355     ngx_uint_t  level;
1356 
1357     /* Winsock may return NGX_ECONNABORTED instead of NGX_ECONNRESET */
1358 
1359     if ((err == NGX_ECONNRESET
1360 #if (NGX_WIN32)
1361          || err == NGX_ECONNABORTED
1362 #endif
1363         ) && c->log_error == NGX_ERROR_IGNORE_ECONNRESET)
1364     {
1365         return 0;
1366     }
1367 
1368 #if (NGX_SOLARIS)
1369     if (err == NGX_EINVAL && c->log_error == NGX_ERROR_IGNORE_EINVAL) {
1370         return 0;
1371     }
1372 #endif
1373 
1374     if (err == 0
1375         || err == NGX_ECONNRESET
1376 #if (NGX_WIN32)
1377         || err == NGX_ECONNABORTED
1378 #else
1379         || err == NGX_EPIPE
1380 #endif
1381         || err == NGX_ENOTCONN
1382         || err == NGX_ETIMEDOUT
1383         || err == NGX_ECONNREFUSED
1384         || err == NGX_ENETDOWN
1385         || err == NGX_ENETUNREACH
1386         || err == NGX_EHOSTDOWN
1387         || err == NGX_EHOSTUNREACH)
1388     {
1389         switch (c->log_error) {
1390 
1391         case NGX_ERROR_IGNORE_EINVAL:
1392         case NGX_ERROR_IGNORE_ECONNRESET:
1393         case NGX_ERROR_INFO:
1394             level = NGX_LOG_INFO;
1395             break;
1396 
1397         default:
1398             level = NGX_LOG_ERR;
1399         }
1400 
1401     } else {
1402         level = NGX_LOG_ALERT;
1403     }
1404 
1405     ngx_log_error(level, c->log, err, text);
1406 
1407     return NGX_ERROR;
1408 }