Annotation of embedaddon/nginx/src/core/ngx_connection.c, revision 1.1.1.1

1.1       misho       1: 
                      2: /*
                      3:  * Copyright (C) Igor Sysoev
                      4:  * Copyright (C) Nginx, Inc.
                      5:  */
                      6: 
                      7: 
                      8: #include <ngx_config.h>
                      9: #include <ngx_core.h>
                     10: #include <ngx_event.h>
                     11: 
                     12: 
                     13: ngx_os_io_t  ngx_io;
                     14: 
                     15: 
                     16: static void ngx_drain_connections(void);
                     17: 
                     18: 
                     19: ngx_listening_t *
                     20: ngx_create_listening(ngx_conf_t *cf, void *sockaddr, socklen_t socklen)
                     21: {
                     22:     size_t            len;
                     23:     ngx_listening_t  *ls;
                     24:     struct sockaddr  *sa;
                     25:     u_char            text[NGX_SOCKADDR_STRLEN];
                     26: 
                     27:     ls = ngx_array_push(&cf->cycle->listening);
                     28:     if (ls == NULL) {
                     29:         return NULL;
                     30:     }
                     31: 
                     32:     ngx_memzero(ls, sizeof(ngx_listening_t));
                     33: 
                     34:     sa = ngx_palloc(cf->pool, socklen);
                     35:     if (sa == NULL) {
                     36:         return NULL;
                     37:     }
                     38: 
                     39:     ngx_memcpy(sa, sockaddr, socklen);
                     40: 
                     41:     ls->sockaddr = sa;
                     42:     ls->socklen = socklen;
                     43: 
                     44:     len = ngx_sock_ntop(sa, text, NGX_SOCKADDR_STRLEN, 1);
                     45:     ls->addr_text.len = len;
                     46: 
                     47:     switch (ls->sockaddr->sa_family) {
                     48: #if (NGX_HAVE_INET6)
                     49:     case AF_INET6:
                     50:          ls->addr_text_max_len = NGX_INET6_ADDRSTRLEN;
                     51:          break;
                     52: #endif
                     53: #if (NGX_HAVE_UNIX_DOMAIN)
                     54:     case AF_UNIX:
                     55:          ls->addr_text_max_len = NGX_UNIX_ADDRSTRLEN;
                     56:          len++;
                     57:          break;
                     58: #endif
                     59:     case AF_INET:
                     60:          ls->addr_text_max_len = NGX_INET_ADDRSTRLEN;
                     61:          break;
                     62:     default:
                     63:          ls->addr_text_max_len = NGX_SOCKADDR_STRLEN;
                     64:          break;
                     65:     }
                     66: 
                     67:     ls->addr_text.data = ngx_pnalloc(cf->pool, len);
                     68:     if (ls->addr_text.data == NULL) {
                     69:         return NULL;
                     70:     }
                     71: 
                     72:     ngx_memcpy(ls->addr_text.data, text, len);
                     73: 
                     74:     ls->fd = (ngx_socket_t) -1;
                     75:     ls->type = SOCK_STREAM;
                     76: 
                     77:     ls->backlog = NGX_LISTEN_BACKLOG;
                     78:     ls->rcvbuf = -1;
                     79:     ls->sndbuf = -1;
                     80: 
                     81: #if (NGX_HAVE_SETFIB)
                     82:     ls->setfib = -1;
                     83: #endif
                     84: 
                     85:     return ls;
                     86: }
                     87: 
                     88: 
                     89: ngx_int_t
                     90: ngx_set_inherited_sockets(ngx_cycle_t *cycle)
                     91: {
                     92:     size_t                     len;
                     93:     ngx_uint_t                 i;
                     94:     ngx_listening_t           *ls;
                     95:     socklen_t                  olen;
                     96: #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
                     97:     ngx_err_t                  err;
                     98:     struct accept_filter_arg   af;
                     99: #endif
                    100: #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
                    101:     int                        timeout;
                    102: #endif
                    103: 
                    104:     ls = cycle->listening.elts;
                    105:     for (i = 0; i < cycle->listening.nelts; i++) {
                    106: 
                    107:         ls[i].sockaddr = ngx_palloc(cycle->pool, NGX_SOCKADDRLEN);
                    108:         if (ls[i].sockaddr == NULL) {
                    109:             return NGX_ERROR;
                    110:         }
                    111: 
                    112:         ls[i].socklen = NGX_SOCKADDRLEN;
                    113:         if (getsockname(ls[i].fd, ls[i].sockaddr, &ls[i].socklen) == -1) {
                    114:             ngx_log_error(NGX_LOG_CRIT, cycle->log, ngx_socket_errno,
                    115:                           "getsockname() of the inherited "
                    116:                           "socket #%d failed", ls[i].fd);
                    117:             ls[i].ignore = 1;
                    118:             continue;
                    119:         }
                    120: 
                    121:         switch (ls[i].sockaddr->sa_family) {
                    122: 
                    123: #if (NGX_HAVE_INET6)
                    124:         case AF_INET6:
                    125:              ls[i].addr_text_max_len = NGX_INET6_ADDRSTRLEN;
                    126:              len = NGX_INET6_ADDRSTRLEN + sizeof(":65535") - 1;
                    127:              break;
                    128: #endif
                    129: 
                    130: #if (NGX_HAVE_UNIX_DOMAIN)
                    131:         case AF_UNIX:
                    132:              ls[i].addr_text_max_len = NGX_UNIX_ADDRSTRLEN;
                    133:              len = NGX_UNIX_ADDRSTRLEN;
                    134:              break;
                    135: #endif
                    136: 
                    137:         case AF_INET:
                    138:              ls[i].addr_text_max_len = NGX_INET_ADDRSTRLEN;
                    139:              len = NGX_INET_ADDRSTRLEN + sizeof(":65535") - 1;
                    140:              break;
                    141: 
                    142:         default:
                    143:             ngx_log_error(NGX_LOG_CRIT, cycle->log, ngx_socket_errno,
                    144:                           "the inherited socket #%d has "
                    145:                           "an unsupported protocol family", ls[i].fd);
                    146:             ls[i].ignore = 1;
                    147:             continue;
                    148:         }
                    149: 
                    150:         ls[i].addr_text.data = ngx_pnalloc(cycle->pool, len);
                    151:         if (ls[i].addr_text.data == NULL) {
                    152:             return NGX_ERROR;
                    153:         }
                    154: 
                    155:         len = ngx_sock_ntop(ls[i].sockaddr, ls[i].addr_text.data, len, 1);
                    156:         if (len == 0) {
                    157:             return NGX_ERROR;
                    158:         }
                    159: 
                    160:         ls[i].addr_text.len = len;
                    161: 
                    162:         ls[i].backlog = NGX_LISTEN_BACKLOG;
                    163: 
                    164:         olen = sizeof(int);
                    165: 
                    166:         if (getsockopt(ls[i].fd, SOL_SOCKET, SO_RCVBUF, (void *) &ls[i].rcvbuf,
                    167:                        &olen)
                    168:             == -1)
                    169:         {
                    170:             ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
                    171:                           "getsockopt(SO_RCVBUF) %V failed, ignored",
                    172:                           &ls[i].addr_text);
                    173: 
                    174:             ls[i].rcvbuf = -1;
                    175:         }
                    176: 
                    177:         olen = sizeof(int);
                    178: 
                    179:         if (getsockopt(ls[i].fd, SOL_SOCKET, SO_SNDBUF, (void *) &ls[i].sndbuf,
                    180:                        &olen)
                    181:             == -1)
                    182:         {
                    183:             ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
                    184:                           "getsockopt(SO_SNDBUF) %V failed, ignored",
                    185:                           &ls[i].addr_text);
                    186: 
                    187:             ls[i].sndbuf = -1;
                    188:         }
                    189: 
                    190: #if 0
                    191:         /* SO_SETFIB is currently a set only option */
                    192: 
                    193: #if (NGX_HAVE_SETFIB)
                    194: 
                    195:         if (getsockopt(ls[i].setfib, SOL_SOCKET, SO_SETFIB,
                    196:                        (void *) &ls[i].setfib, &olen)
                    197:             == -1)
                    198:         {
                    199:             ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
                    200:                           "getsockopt(SO_SETFIB) %V failed, ignored",
                    201:                           &ls[i].addr_text);
                    202: 
                    203:             ls[i].setfib = -1;
                    204:         }
                    205: 
                    206: #endif
                    207: #endif
                    208: 
                    209: #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
                    210: 
                    211:         ngx_memzero(&af, sizeof(struct accept_filter_arg));
                    212:         olen = sizeof(struct accept_filter_arg);
                    213: 
                    214:         if (getsockopt(ls[i].fd, SOL_SOCKET, SO_ACCEPTFILTER, &af, &olen)
                    215:             == -1)
                    216:         {
                    217:             err = ngx_errno;
                    218: 
                    219:             if (err == NGX_EINVAL) {
                    220:                 continue;
                    221:             }
                    222: 
                    223:             ngx_log_error(NGX_LOG_NOTICE, cycle->log, err,
                    224:                           "getsockopt(SO_ACCEPTFILTER) for %V failed, ignored",
                    225:                           &ls[i].addr_text);
                    226:             continue;
                    227:         }
                    228: 
                    229:         if (olen < sizeof(struct accept_filter_arg) || af.af_name[0] == '\0') {
                    230:             continue;
                    231:         }
                    232: 
                    233:         ls[i].accept_filter = ngx_palloc(cycle->pool, 16);
                    234:         if (ls[i].accept_filter == NULL) {
                    235:             return NGX_ERROR;
                    236:         }
                    237: 
                    238:         (void) ngx_cpystrn((u_char *) ls[i].accept_filter,
                    239:                            (u_char *) af.af_name, 16);
                    240: #endif
                    241: 
                    242: #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
                    243: 
                    244:         timeout = 0;
                    245:         olen = sizeof(int);
                    246: 
                    247:         if (getsockopt(ls[i].fd, IPPROTO_TCP, TCP_DEFER_ACCEPT, &timeout, &olen)
                    248:             == -1)
                    249:         {
                    250:             ngx_log_error(NGX_LOG_NOTICE, cycle->log, ngx_errno,
                    251:                           "getsockopt(TCP_DEFER_ACCEPT) for %V failed, ignored",
                    252:                           &ls[i].addr_text);
                    253:             continue;
                    254:         }
                    255: 
                    256:         if (olen < sizeof(int) || timeout == 0) {
                    257:             continue;
                    258:         }
                    259: 
                    260:         ls[i].deferred_accept = 1;
                    261: #endif
                    262:     }
                    263: 
                    264:     return NGX_OK;
                    265: }
                    266: 
                    267: 
                    268: ngx_int_t
                    269: ngx_open_listening_sockets(ngx_cycle_t *cycle)
                    270: {
                    271:     int               reuseaddr;
                    272:     ngx_uint_t        i, tries, failed;
                    273:     ngx_err_t         err;
                    274:     ngx_log_t        *log;
                    275:     ngx_socket_t      s;
                    276:     ngx_listening_t  *ls;
                    277: 
                    278:     reuseaddr = 1;
                    279: #if (NGX_SUPPRESS_WARN)
                    280:     failed = 0;
                    281: #endif
                    282: 
                    283:     log = cycle->log;
                    284: 
                    285:     /* TODO: configurable try number */
                    286: 
                    287:     for (tries = 5; tries; tries--) {
                    288:         failed = 0;
                    289: 
                    290:         /* for each listening socket */
                    291: 
                    292:         ls = cycle->listening.elts;
                    293:         for (i = 0; i < cycle->listening.nelts; i++) {
                    294: 
                    295:             if (ls[i].ignore) {
                    296:                 continue;
                    297:             }
                    298: 
                    299:             if (ls[i].fd != -1) {
                    300:                 continue;
                    301:             }
                    302: 
                    303:             if (ls[i].inherited) {
                    304: 
                    305:                 /* TODO: close on exit */
                    306:                 /* TODO: nonblocking */
                    307:                 /* TODO: deferred accept */
                    308: 
                    309:                 continue;
                    310:             }
                    311: 
                    312:             s = ngx_socket(ls[i].sockaddr->sa_family, ls[i].type, 0);
                    313: 
                    314:             if (s == -1) {
                    315:                 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
                    316:                               ngx_socket_n " %V failed", &ls[i].addr_text);
                    317:                 return NGX_ERROR;
                    318:             }
                    319: 
                    320:             if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
                    321:                            (const void *) &reuseaddr, sizeof(int))
                    322:                 == -1)
                    323:             {
                    324:                 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
                    325:                               "setsockopt(SO_REUSEADDR) %V failed",
                    326:                               &ls[i].addr_text);
                    327: 
                    328:                 if (ngx_close_socket(s) == -1) {
                    329:                     ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
                    330:                                   ngx_close_socket_n " %V failed",
                    331:                                   &ls[i].addr_text);
                    332:                 }
                    333: 
                    334:                 return NGX_ERROR;
                    335:             }
                    336: 
                    337: #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
                    338: 
                    339:             if (ls[i].sockaddr->sa_family == AF_INET6) {
                    340:                 int  ipv6only;
                    341: 
                    342:                 ipv6only = ls[i].ipv6only;
                    343: 
                    344:                 if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY,
                    345:                                (const void *) &ipv6only, sizeof(int))
                    346:                     == -1)
                    347:                 {
                    348:                     ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
                    349:                                   "setsockopt(IPV6_V6ONLY) %V failed, ignored",
                    350:                                   &ls[i].addr_text);
                    351:                 }
                    352:             }
                    353: #endif
                    354:             /* TODO: close on exit */
                    355: 
                    356:             if (!(ngx_event_flags & NGX_USE_AIO_EVENT)) {
                    357:                 if (ngx_nonblocking(s) == -1) {
                    358:                     ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
                    359:                                   ngx_nonblocking_n " %V failed",
                    360:                                   &ls[i].addr_text);
                    361: 
                    362:                     if (ngx_close_socket(s) == -1) {
                    363:                         ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
                    364:                                       ngx_close_socket_n " %V failed",
                    365:                                       &ls[i].addr_text);
                    366:                     }
                    367: 
                    368:                     return NGX_ERROR;
                    369:                 }
                    370:             }
                    371: 
                    372:             ngx_log_debug2(NGX_LOG_DEBUG_CORE, log, 0,
                    373:                            "bind() %V #%d ", &ls[i].addr_text, s);
                    374: 
                    375:             if (bind(s, ls[i].sockaddr, ls[i].socklen) == -1) {
                    376:                 err = ngx_socket_errno;
                    377: 
                    378:                 if (err == NGX_EADDRINUSE && ngx_test_config) {
                    379:                     continue;
                    380:                 }
                    381: 
                    382:                 ngx_log_error(NGX_LOG_EMERG, log, err,
                    383:                               "bind() to %V failed", &ls[i].addr_text);
                    384: 
                    385:                 if (ngx_close_socket(s) == -1) {
                    386:                     ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
                    387:                                   ngx_close_socket_n " %V failed",
                    388:                                   &ls[i].addr_text);
                    389:                 }
                    390: 
                    391:                 if (err != NGX_EADDRINUSE) {
                    392:                     return NGX_ERROR;
                    393:                 }
                    394: 
                    395:                 failed = 1;
                    396: 
                    397:                 continue;
                    398:             }
                    399: 
                    400: #if (NGX_HAVE_UNIX_DOMAIN)
                    401: 
                    402:             if (ls[i].sockaddr->sa_family == AF_UNIX) {
                    403:                 mode_t   mode;
                    404:                 u_char  *name;
                    405: 
                    406:                 name = ls[i].addr_text.data + sizeof("unix:") - 1;
                    407:                 mode = (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
                    408: 
                    409:                 if (chmod((char *) name, mode) == -1) {
                    410:                     ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
                    411:                                   "chmod() \"%s\" failed", name);
                    412:                 }
                    413: 
                    414:                 if (ngx_test_config) {
                    415:                     if (ngx_delete_file(name) == NGX_FILE_ERROR) {
                    416:                         ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
                    417:                                       ngx_delete_file_n " %s failed", name);
                    418:                     }
                    419:                 }
                    420:             }
                    421: #endif
                    422: 
                    423:             if (listen(s, ls[i].backlog) == -1) {
                    424:                 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
                    425:                               "listen() to %V, backlog %d failed",
                    426:                               &ls[i].addr_text, ls[i].backlog);
                    427: 
                    428:                 if (ngx_close_socket(s) == -1) {
                    429:                     ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
                    430:                                   ngx_close_socket_n " %V failed",
                    431:                                   &ls[i].addr_text);
                    432:                 }
                    433: 
                    434:                 return NGX_ERROR;
                    435:             }
                    436: 
                    437:             ls[i].listen = 1;
                    438: 
                    439:             ls[i].fd = s;
                    440:         }
                    441: 
                    442:         if (!failed) {
                    443:             break;
                    444:         }
                    445: 
                    446:         /* TODO: delay configurable */
                    447: 
                    448:         ngx_log_error(NGX_LOG_NOTICE, log, 0,
                    449:                       "try again to bind() after 500ms");
                    450: 
                    451:         ngx_msleep(500);
                    452:     }
                    453: 
                    454:     if (failed) {
                    455:         ngx_log_error(NGX_LOG_EMERG, log, 0, "still could not bind()");
                    456:         return NGX_ERROR;
                    457:     }
                    458: 
                    459:     return NGX_OK;
                    460: }
                    461: 
                    462: 
                    463: void
                    464: ngx_configure_listening_sockets(ngx_cycle_t *cycle)
                    465: {
                    466:     int                        keepalive;
                    467:     ngx_uint_t                 i;
                    468:     ngx_listening_t           *ls;
                    469: 
                    470: #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
                    471:     struct accept_filter_arg   af;
                    472: #endif
                    473: #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
                    474:     int                        timeout;
                    475: #endif
                    476: 
                    477:     ls = cycle->listening.elts;
                    478:     for (i = 0; i < cycle->listening.nelts; i++) {
                    479: 
                    480:         ls[i].log = *ls[i].logp;
                    481: 
                    482:         if (ls[i].rcvbuf != -1) {
                    483:             if (setsockopt(ls[i].fd, SOL_SOCKET, SO_RCVBUF,
                    484:                            (const void *) &ls[i].rcvbuf, sizeof(int))
                    485:                 == -1)
                    486:             {
                    487:                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
                    488:                               "setsockopt(SO_RCVBUF, %d) %V failed, ignored",
                    489:                               ls[i].rcvbuf, &ls[i].addr_text);
                    490:             }
                    491:         }
                    492: 
                    493:         if (ls[i].sndbuf != -1) {
                    494:             if (setsockopt(ls[i].fd, SOL_SOCKET, SO_SNDBUF,
                    495:                            (const void *) &ls[i].sndbuf, sizeof(int))
                    496:                 == -1)
                    497:             {
                    498:                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
                    499:                               "setsockopt(SO_SNDBUF, %d) %V failed, ignored",
                    500:                               ls[i].sndbuf, &ls[i].addr_text);
                    501:             }
                    502:         }
                    503: 
                    504:         if (ls[i].keepalive) {
                    505:             keepalive = (ls[i].keepalive == 1) ? 1 : 0;
                    506: 
                    507:             if (setsockopt(ls[i].fd, SOL_SOCKET, SO_KEEPALIVE,
                    508:                            (const void *) &keepalive, sizeof(int))
                    509:                 == -1)
                    510:             {
                    511:                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
                    512:                               "setsockopt(SO_KEEPALIVE, %d) %V failed, ignored",
                    513:                               keepalive, &ls[i].addr_text);
                    514:             }
                    515:         }
                    516: 
                    517: #if (NGX_HAVE_KEEPALIVE_TUNABLE)
                    518: 
                    519:         if (ls[i].keepidle) {
                    520:             if (setsockopt(ls[i].fd, IPPROTO_TCP, TCP_KEEPIDLE,
                    521:                            (const void *) &ls[i].keepidle, sizeof(int))
                    522:                 == -1)
                    523:             {
                    524:                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
                    525:                               "setsockopt(TCP_KEEPIDLE, %d) %V failed, ignored",
                    526:                               ls[i].keepidle, &ls[i].addr_text);
                    527:             }
                    528:         }
                    529: 
                    530:         if (ls[i].keepintvl) {
                    531:             if (setsockopt(ls[i].fd, IPPROTO_TCP, TCP_KEEPINTVL,
                    532:                            (const void *) &ls[i].keepintvl, sizeof(int))
                    533:                 == -1)
                    534:             {
                    535:                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
                    536:                              "setsockopt(TCP_KEEPINTVL, %d) %V failed, ignored",
                    537:                              ls[i].keepintvl, &ls[i].addr_text);
                    538:             }
                    539:         }
                    540: 
                    541:         if (ls[i].keepcnt) {
                    542:             if (setsockopt(ls[i].fd, IPPROTO_TCP, TCP_KEEPCNT,
                    543:                            (const void *) &ls[i].keepcnt, sizeof(int))
                    544:                 == -1)
                    545:             {
                    546:                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
                    547:                               "setsockopt(TCP_KEEPCNT, %d) %V failed, ignored",
                    548:                               ls[i].keepcnt, &ls[i].addr_text);
                    549:             }
                    550:         }
                    551: 
                    552: #endif
                    553: 
                    554: #if (NGX_HAVE_SETFIB)
                    555:         if (ls[i].setfib != -1) {
                    556:             if (setsockopt(ls[i].fd, SOL_SOCKET, SO_SETFIB,
                    557:                            (const void *) &ls[i].setfib, sizeof(int))
                    558:                 == -1)
                    559:             {
                    560:                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
                    561:                               "setsockopt(SO_SETFIB, %d) %V failed, ignored",
                    562:                               ls[i].setfib, &ls[i].addr_text);
                    563:             }
                    564:         }
                    565: #endif
                    566: 
                    567: #if 0
                    568:         if (1) {
                    569:             int tcp_nodelay = 1;
                    570: 
                    571:             if (setsockopt(ls[i].fd, IPPROTO_TCP, TCP_NODELAY,
                    572:                        (const void *) &tcp_nodelay, sizeof(int))
                    573:                 == -1)
                    574:             {
                    575:                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
                    576:                               "setsockopt(TCP_NODELAY) %V failed, ignored",
                    577:                               &ls[i].addr_text);
                    578:             }
                    579:         }
                    580: #endif
                    581: 
                    582:         if (ls[i].listen) {
                    583: 
                    584:             /* change backlog via listen() */
                    585: 
                    586:             if (listen(ls[i].fd, ls[i].backlog) == -1) {
                    587:                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
                    588:                               "listen() to %V, backlog %d failed, ignored",
                    589:                               &ls[i].addr_text, ls[i].backlog);
                    590:             }
                    591:         }
                    592: 
                    593:         /*
                    594:          * setting deferred mode should be last operation on socket,
                    595:          * because code may prematurely continue cycle on failure
                    596:          */
                    597: 
                    598: #if (NGX_HAVE_DEFERRED_ACCEPT)
                    599: 
                    600: #ifdef SO_ACCEPTFILTER
                    601: 
                    602:         if (ls[i].delete_deferred) {
                    603:             if (setsockopt(ls[i].fd, SOL_SOCKET, SO_ACCEPTFILTER, NULL, 0)
                    604:                 == -1)
                    605:             {
                    606:                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                    607:                               "setsockopt(SO_ACCEPTFILTER, NULL) "
                    608:                               "for %V failed, ignored",
                    609:                               &ls[i].addr_text);
                    610: 
                    611:                 if (ls[i].accept_filter) {
                    612:                     ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
                    613:                                   "could not change the accept filter "
                    614:                                   "to \"%s\" for %V, ignored",
                    615:                                   ls[i].accept_filter, &ls[i].addr_text);
                    616:                 }
                    617: 
                    618:                 continue;
                    619:             }
                    620: 
                    621:             ls[i].deferred_accept = 0;
                    622:         }
                    623: 
                    624:         if (ls[i].add_deferred) {
                    625:             ngx_memzero(&af, sizeof(struct accept_filter_arg));
                    626:             (void) ngx_cpystrn((u_char *) af.af_name,
                    627:                                (u_char *) ls[i].accept_filter, 16);
                    628: 
                    629:             if (setsockopt(ls[i].fd, SOL_SOCKET, SO_ACCEPTFILTER,
                    630:                            &af, sizeof(struct accept_filter_arg))
                    631:                 == -1)
                    632:             {
                    633:                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                    634:                               "setsockopt(SO_ACCEPTFILTER, \"%s\") "
                    635:                               "for %V failed, ignored",
                    636:                               ls[i].accept_filter, &ls[i].addr_text);
                    637:                 continue;
                    638:             }
                    639: 
                    640:             ls[i].deferred_accept = 1;
                    641:         }
                    642: 
                    643: #endif
                    644: 
                    645: #ifdef TCP_DEFER_ACCEPT
                    646: 
                    647:         if (ls[i].add_deferred || ls[i].delete_deferred) {
                    648: 
                    649:             if (ls[i].add_deferred) {
                    650:                 timeout = (int) (ls[i].post_accept_timeout / 1000);
                    651: 
                    652:             } else {
                    653:                 timeout = 0;
                    654:             }
                    655: 
                    656:             if (setsockopt(ls[i].fd, IPPROTO_TCP, TCP_DEFER_ACCEPT,
                    657:                            &timeout, sizeof(int))
                    658:                 == -1)
                    659:             {
                    660:                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                    661:                               "setsockopt(TCP_DEFER_ACCEPT, %d) for %V failed, "
                    662:                               "ignored",
                    663:                               timeout, &ls[i].addr_text);
                    664: 
                    665:                 continue;
                    666:             }
                    667:         }
                    668: 
                    669:         if (ls[i].add_deferred) {
                    670:             ls[i].deferred_accept = 1;
                    671:         }
                    672: 
                    673: #endif
                    674: 
                    675: #endif /* NGX_HAVE_DEFERRED_ACCEPT */
                    676:     }
                    677: 
                    678:     return;
                    679: }
                    680: 
                    681: 
                    682: void
                    683: ngx_close_listening_sockets(ngx_cycle_t *cycle)
                    684: {
                    685:     ngx_uint_t         i;
                    686:     ngx_listening_t   *ls;
                    687:     ngx_connection_t  *c;
                    688: 
                    689:     if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
                    690:         return;
                    691:     }
                    692: 
                    693:     ngx_accept_mutex_held = 0;
                    694:     ngx_use_accept_mutex = 0;
                    695: 
                    696:     ls = cycle->listening.elts;
                    697:     for (i = 0; i < cycle->listening.nelts; i++) {
                    698: 
                    699:         c = ls[i].connection;
                    700: 
                    701:         if (c) {
                    702:             if (c->read->active) {
                    703:                 if (ngx_event_flags & NGX_USE_RTSIG_EVENT) {
                    704:                     ngx_del_conn(c, NGX_CLOSE_EVENT);
                    705: 
                    706:                 } else if (ngx_event_flags & NGX_USE_EPOLL_EVENT) {
                    707: 
                    708:                     /*
                    709:                      * it seems that Linux-2.6.x OpenVZ sends events
                    710:                      * for closed shared listening sockets unless
                    711:                      * the events was explicitly deleted
                    712:                      */
                    713: 
                    714:                     ngx_del_event(c->read, NGX_READ_EVENT, 0);
                    715: 
                    716:                 } else {
                    717:                     ngx_del_event(c->read, NGX_READ_EVENT, NGX_CLOSE_EVENT);
                    718:                 }
                    719:             }
                    720: 
                    721:             ngx_free_connection(c);
                    722: 
                    723:             c->fd = (ngx_socket_t) -1;
                    724:         }
                    725: 
                    726:         ngx_log_debug2(NGX_LOG_DEBUG_CORE, cycle->log, 0,
                    727:                        "close listening %V #%d ", &ls[i].addr_text, ls[i].fd);
                    728: 
                    729:         if (ngx_close_socket(ls[i].fd) == -1) {
                    730:             ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_socket_errno,
                    731:                           ngx_close_socket_n " %V failed", &ls[i].addr_text);
                    732:         }
                    733: 
                    734: #if (NGX_HAVE_UNIX_DOMAIN)
                    735: 
                    736:         if (ls[i].sockaddr->sa_family == AF_UNIX
                    737:             && ngx_process <= NGX_PROCESS_MASTER
                    738:             && ngx_new_binary == 0)
                    739:         {
                    740:             u_char *name = ls[i].addr_text.data + sizeof("unix:") - 1;
                    741: 
                    742:             if (ngx_delete_file(name) == NGX_FILE_ERROR) {
                    743:                 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_socket_errno,
                    744:                               ngx_delete_file_n " %s failed", name);
                    745:             }
                    746:         }
                    747: 
                    748: #endif
                    749: 
                    750:         ls[i].fd = (ngx_socket_t) -1;
                    751:     }
                    752: 
                    753:     cycle->listening.nelts = 0;
                    754: }
                    755: 
                    756: 
                    757: ngx_connection_t *
                    758: ngx_get_connection(ngx_socket_t s, ngx_log_t *log)
                    759: {
                    760:     ngx_uint_t         instance;
                    761:     ngx_event_t       *rev, *wev;
                    762:     ngx_connection_t  *c;
                    763: 
                    764:     /* disable warning: Win32 SOCKET is u_int while UNIX socket is int */
                    765: 
                    766:     if (ngx_cycle->files && (ngx_uint_t) s >= ngx_cycle->files_n) {
                    767:         ngx_log_error(NGX_LOG_ALERT, log, 0,
                    768:                       "the new socket has number %d, "
                    769:                       "but only %ui files are available",
                    770:                       s, ngx_cycle->files_n);
                    771:         return NULL;
                    772:     }
                    773: 
                    774:     /* ngx_mutex_lock */
                    775: 
                    776:     c = ngx_cycle->free_connections;
                    777: 
                    778:     if (c == NULL) {
                    779:         ngx_drain_connections();
                    780:         c = ngx_cycle->free_connections;
                    781:     }
                    782: 
                    783:     if (c == NULL) {
                    784:         ngx_log_error(NGX_LOG_ALERT, log, 0,
                    785:                       "%ui worker_connections are not enough",
                    786:                       ngx_cycle->connection_n);
                    787: 
                    788:         /* ngx_mutex_unlock */
                    789: 
                    790:         return NULL;
                    791:     }
                    792: 
                    793:     ngx_cycle->free_connections = c->data;
                    794:     ngx_cycle->free_connection_n--;
                    795: 
                    796:     /* ngx_mutex_unlock */
                    797: 
                    798:     if (ngx_cycle->files) {
                    799:         ngx_cycle->files[s] = c;
                    800:     }
                    801: 
                    802:     rev = c->read;
                    803:     wev = c->write;
                    804: 
                    805:     ngx_memzero(c, sizeof(ngx_connection_t));
                    806: 
                    807:     c->read = rev;
                    808:     c->write = wev;
                    809:     c->fd = s;
                    810:     c->log = log;
                    811: 
                    812:     instance = rev->instance;
                    813: 
                    814:     ngx_memzero(rev, sizeof(ngx_event_t));
                    815:     ngx_memzero(wev, sizeof(ngx_event_t));
                    816: 
                    817:     rev->instance = !instance;
                    818:     wev->instance = !instance;
                    819: 
                    820:     rev->index = NGX_INVALID_INDEX;
                    821:     wev->index = NGX_INVALID_INDEX;
                    822: 
                    823:     rev->data = c;
                    824:     wev->data = c;
                    825: 
                    826:     wev->write = 1;
                    827: 
                    828:     return c;
                    829: }
                    830: 
                    831: 
                    832: void
                    833: ngx_free_connection(ngx_connection_t *c)
                    834: {
                    835:     /* ngx_mutex_lock */
                    836: 
                    837:     c->data = ngx_cycle->free_connections;
                    838:     ngx_cycle->free_connections = c;
                    839:     ngx_cycle->free_connection_n++;
                    840: 
                    841:     /* ngx_mutex_unlock */
                    842: 
                    843:     if (ngx_cycle->files) {
                    844:         ngx_cycle->files[c->fd] = NULL;
                    845:     }
                    846: }
                    847: 
                    848: 
                    849: void
                    850: ngx_close_connection(ngx_connection_t *c)
                    851: {
                    852:     ngx_err_t     err;
                    853:     ngx_uint_t    log_error, level;
                    854:     ngx_socket_t  fd;
                    855: 
                    856:     if (c->fd == -1) {
                    857:         ngx_log_error(NGX_LOG_ALERT, c->log, 0, "connection already closed");
                    858:         return;
                    859:     }
                    860: 
                    861:     if (c->read->timer_set) {
                    862:         ngx_del_timer(c->read);
                    863:     }
                    864: 
                    865:     if (c->write->timer_set) {
                    866:         ngx_del_timer(c->write);
                    867:     }
                    868: 
                    869:     if (ngx_del_conn) {
                    870:         ngx_del_conn(c, NGX_CLOSE_EVENT);
                    871: 
                    872:     } else {
                    873:         if (c->read->active || c->read->disabled) {
                    874:             ngx_del_event(c->read, NGX_READ_EVENT, NGX_CLOSE_EVENT);
                    875:         }
                    876: 
                    877:         if (c->write->active || c->write->disabled) {
                    878:             ngx_del_event(c->write, NGX_WRITE_EVENT, NGX_CLOSE_EVENT);
                    879:         }
                    880:     }
                    881: 
                    882: #if (NGX_THREADS)
                    883: 
                    884:     /*
                    885:      * we have to clean the connection information before the closing
                    886:      * because another thread may reopen the same file descriptor
                    887:      * before we clean the connection
                    888:      */
                    889: 
                    890:     ngx_mutex_lock(ngx_posted_events_mutex);
                    891: 
                    892:     if (c->read->prev) {
                    893:         ngx_delete_posted_event(c->read);
                    894:     }
                    895: 
                    896:     if (c->write->prev) {
                    897:         ngx_delete_posted_event(c->write);
                    898:     }
                    899: 
                    900:     c->read->closed = 1;
                    901:     c->write->closed = 1;
                    902: 
                    903:     ngx_unlock(&c->lock);
                    904:     c->read->locked = 0;
                    905:     c->write->locked = 0;
                    906: 
                    907:     ngx_mutex_unlock(ngx_posted_events_mutex);
                    908: 
                    909: #else
                    910: 
                    911:     if (c->read->prev) {
                    912:         ngx_delete_posted_event(c->read);
                    913:     }
                    914: 
                    915:     if (c->write->prev) {
                    916:         ngx_delete_posted_event(c->write);
                    917:     }
                    918: 
                    919:     c->read->closed = 1;
                    920:     c->write->closed = 1;
                    921: 
                    922: #endif
                    923: 
                    924:     ngx_reusable_connection(c, 0);
                    925: 
                    926:     log_error = c->log_error;
                    927: 
                    928:     ngx_free_connection(c);
                    929: 
                    930:     fd = c->fd;
                    931:     c->fd = (ngx_socket_t) -1;
                    932: 
                    933:     if (ngx_close_socket(fd) == -1) {
                    934: 
                    935:         err = ngx_socket_errno;
                    936: 
                    937:         if (err == NGX_ECONNRESET || err == NGX_ENOTCONN) {
                    938: 
                    939:             switch (log_error) {
                    940: 
                    941:             case NGX_ERROR_INFO:
                    942:                 level = NGX_LOG_INFO;
                    943:                 break;
                    944: 
                    945:             case NGX_ERROR_ERR:
                    946:                 level = NGX_LOG_ERR;
                    947:                 break;
                    948: 
                    949:             default:
                    950:                 level = NGX_LOG_CRIT;
                    951:             }
                    952: 
                    953:         } else {
                    954:             level = NGX_LOG_CRIT;
                    955:         }
                    956: 
                    957:         /* we use ngx_cycle->log because c->log was in c->pool */
                    958: 
                    959:         ngx_log_error(level, ngx_cycle->log, err,
                    960:                       ngx_close_socket_n " %d failed", fd);
                    961:     }
                    962: }
                    963: 
                    964: 
                    965: void
                    966: ngx_reusable_connection(ngx_connection_t *c, ngx_uint_t reusable)
                    967: {
                    968:     ngx_log_debug1(NGX_LOG_DEBUG_CORE, c->log, 0,
                    969:                    "reusable connection: %ui", reusable);
                    970: 
                    971:     if (c->reusable) {
                    972:         ngx_queue_remove(&c->queue);
                    973: 
                    974: #if (NGX_STAT_STUB)
                    975:         (void) ngx_atomic_fetch_add(ngx_stat_waiting, -1);
                    976: #endif
                    977:     }
                    978: 
                    979:     c->reusable = reusable;
                    980: 
                    981:     if (reusable) {
                    982:         /* need cast as ngx_cycle is volatile */
                    983: 
                    984:         ngx_queue_insert_head(
                    985:             (ngx_queue_t *) &ngx_cycle->reusable_connections_queue, &c->queue);
                    986: 
                    987: #if (NGX_STAT_STUB)
                    988:         (void) ngx_atomic_fetch_add(ngx_stat_waiting, 1);
                    989: #endif
                    990:     }
                    991: }
                    992: 
                    993: 
                    994: static void
                    995: ngx_drain_connections(void)
                    996: {
                    997:     ngx_int_t          i;
                    998:     ngx_queue_t       *q;
                    999:     ngx_connection_t  *c;
                   1000: 
                   1001:     for (i = 0; i < 32; i++) {
                   1002:         if (ngx_queue_empty(&ngx_cycle->reusable_connections_queue)) {
                   1003:             break;
                   1004:         }
                   1005: 
                   1006:         q = ngx_queue_last(&ngx_cycle->reusable_connections_queue);
                   1007:         c = ngx_queue_data(q, ngx_connection_t, queue);
                   1008: 
                   1009:         ngx_log_debug0(NGX_LOG_DEBUG_CORE, c->log, 0,
                   1010:                        "reusing connection");
                   1011: 
                   1012:         c->close = 1;
                   1013:         c->read->handler(c->read);
                   1014:     }
                   1015: }
                   1016: 
                   1017: 
                   1018: ngx_int_t
                   1019: ngx_connection_local_sockaddr(ngx_connection_t *c, ngx_str_t *s,
                   1020:     ngx_uint_t port)
                   1021: {
                   1022:     socklen_t             len;
                   1023:     ngx_uint_t            addr;
                   1024:     u_char                sa[NGX_SOCKADDRLEN];
                   1025:     struct sockaddr_in   *sin;
                   1026: #if (NGX_HAVE_INET6)
                   1027:     ngx_uint_t            i;
                   1028:     struct sockaddr_in6  *sin6;
                   1029: #endif
                   1030: 
                   1031:     switch (c->local_sockaddr->sa_family) {
                   1032: 
                   1033: #if (NGX_HAVE_INET6)
                   1034:     case AF_INET6:
                   1035:         sin6 = (struct sockaddr_in6 *) c->local_sockaddr;
                   1036: 
                   1037:         for (addr = 0, i = 0; addr == 0 && i < 16; i++) {
                   1038:             addr |= sin6->sin6_addr.s6_addr[i];
                   1039:         }
                   1040: 
                   1041:         break;
                   1042: #endif
                   1043: 
                   1044:     default: /* AF_INET */
                   1045:         sin = (struct sockaddr_in *) c->local_sockaddr;
                   1046:         addr = sin->sin_addr.s_addr;
                   1047:         break;
                   1048:     }
                   1049: 
                   1050:     if (addr == 0) {
                   1051: 
                   1052:         len = NGX_SOCKADDRLEN;
                   1053: 
                   1054:         if (getsockname(c->fd, (struct sockaddr *) &sa, &len) == -1) {
                   1055:             ngx_connection_error(c, ngx_socket_errno, "getsockname() failed");
                   1056:             return NGX_ERROR;
                   1057:         }
                   1058: 
                   1059:         c->local_sockaddr = ngx_palloc(c->pool, len);
                   1060:         if (c->local_sockaddr == NULL) {
                   1061:             return NGX_ERROR;
                   1062:         }
                   1063: 
                   1064:         ngx_memcpy(c->local_sockaddr, &sa, len);
                   1065:     }
                   1066: 
                   1067:     if (s == NULL) {
                   1068:         return NGX_OK;
                   1069:     }
                   1070: 
                   1071:     s->len = ngx_sock_ntop(c->local_sockaddr, s->data, s->len, port);
                   1072: 
                   1073:     return NGX_OK;
                   1074: }
                   1075: 
                   1076: 
                   1077: ngx_int_t
                   1078: ngx_connection_error(ngx_connection_t *c, ngx_err_t err, char *text)
                   1079: {
                   1080:     ngx_uint_t  level;
                   1081: 
                   1082:     /* Winsock may return NGX_ECONNABORTED instead of NGX_ECONNRESET */
                   1083: 
                   1084:     if ((err == NGX_ECONNRESET
                   1085: #if (NGX_WIN32)
                   1086:          || err == NGX_ECONNABORTED
                   1087: #endif
                   1088:         ) && c->log_error == NGX_ERROR_IGNORE_ECONNRESET)
                   1089:     {
                   1090:         return 0;
                   1091:     }
                   1092: 
                   1093: #if (NGX_SOLARIS)
                   1094:     if (err == NGX_EINVAL && c->log_error == NGX_ERROR_IGNORE_EINVAL) {
                   1095:         return 0;
                   1096:     }
                   1097: #endif
                   1098: 
                   1099:     if (err == 0
                   1100:         || err == NGX_ECONNRESET
                   1101: #if (NGX_WIN32)
                   1102:         || err == NGX_ECONNABORTED
                   1103: #else
                   1104:         || err == NGX_EPIPE
                   1105: #endif
                   1106:         || err == NGX_ENOTCONN
                   1107:         || err == NGX_ETIMEDOUT
                   1108:         || err == NGX_ECONNREFUSED
                   1109:         || err == NGX_ENETDOWN
                   1110:         || err == NGX_ENETUNREACH
                   1111:         || err == NGX_EHOSTDOWN
                   1112:         || err == NGX_EHOSTUNREACH)
                   1113:     {
                   1114:         switch (c->log_error) {
                   1115: 
                   1116:         case NGX_ERROR_IGNORE_EINVAL:
                   1117:         case NGX_ERROR_IGNORE_ECONNRESET:
                   1118:         case NGX_ERROR_INFO:
                   1119:             level = NGX_LOG_INFO;
                   1120:             break;
                   1121: 
                   1122:         default:
                   1123:             level = NGX_LOG_ERR;
                   1124:         }
                   1125: 
                   1126:     } else {
                   1127:         level = NGX_LOG_ALERT;
                   1128:     }
                   1129: 
                   1130:     ngx_log_error(level, c->log, err, text);
                   1131: 
                   1132:     return NGX_ERROR;
                   1133: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>