⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ngx_connection.c

📁 Nginx是一个高性能的HTTP和反向代理服务器
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) Igor Sysoev */#include <ngx_config.h>#include <ngx_core.h>#include <ngx_event.h>ngx_os_io_t  ngx_io;ngx_listening_t *ngx_listening_inet_stream_socket(ngx_conf_t *cf, in_addr_t addr, in_port_t port){    size_t               len;    ngx_listening_t     *ls;    struct sockaddr_in  *sin;    ls = ngx_array_push(&cf->cycle->listening);    if (ls == NULL) {        return NULL;    }    ngx_memzero(ls, sizeof(ngx_listening_t));    sin = ngx_pcalloc(cf->pool, sizeof(struct sockaddr_in));    if (sin == NULL) {        return NULL;    }    sin->sin_family = AF_INET;    sin->sin_addr.s_addr = addr;    sin->sin_port = htons(port);    ls->addr_text.data = ngx_palloc(cf->pool,                                    INET_ADDRSTRLEN - 1 + sizeof(":65535") - 1);    if (ls->addr_text.data == NULL) {        return NULL;    }    len = ngx_inet_ntop(AF_INET, &addr, ls->addr_text.data, INET_ADDRSTRLEN);    ls->addr_text.len = ngx_sprintf(ls->addr_text.data + len, ":%d", port)                        - ls->addr_text.data;    ls->fd = (ngx_socket_t) -1;    ls->family = AF_INET;    ls->type = SOCK_STREAM;    ls->sockaddr = (struct sockaddr *) sin;    ls->socklen = sizeof(struct sockaddr_in);    ls->addr = offsetof(struct sockaddr_in, sin_addr);    ls->addr_text_max_len = INET_ADDRSTRLEN;    return ls;}ngx_int_tngx_set_inherited_sockets(ngx_cycle_t *cycle){    size_t                     len;    ngx_uint_t                 i;    ngx_listening_t           *ls;    struct sockaddr_in        *sin;    socklen_t                  olen;#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)    ngx_err_t                  err;    struct accept_filter_arg   af;#endif#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)    int                        timeout;#endif    ls = cycle->listening.elts;    for (i = 0; i < cycle->listening.nelts; i++) {        /* AF_INET only */        ls[i].sockaddr = ngx_palloc(cycle->pool, sizeof(struct sockaddr_in));        if (ls[i].sockaddr == NULL) {            return NGX_ERROR;        }        ls[i].socklen = sizeof(struct sockaddr_in);        if (getsockname(ls[i].fd, ls[i].sockaddr, &ls[i].socklen) == -1) {            ngx_log_error(NGX_LOG_CRIT, cycle->log, ngx_socket_errno,                          "getsockname() of the inherited "                          "socket #%d failed", ls[i].fd);            ls[i].ignore = 1;            continue;        }        sin = (struct sockaddr_in *) ls[i].sockaddr;        if (sin->sin_family != AF_INET) {            ngx_log_error(NGX_LOG_CRIT, cycle->log, ngx_socket_errno,                          "the inherited socket #%d has "                          "unsupported family", ls[i].fd);            ls[i].ignore = 1;            continue;        }        ls[i].addr_text_max_len = INET_ADDRSTRLEN;        ls[i].addr_text.data = ngx_palloc(cycle->pool, INET_ADDRSTRLEN - 1                                                       + sizeof(":65535") - 1);        if (ls[i].addr_text.data == NULL) {            return NGX_ERROR;        }        ls[i].family = sin->sin_family;        len = ngx_sock_ntop(ls[i].family, ls[i].sockaddr,                            ls[i].addr_text.data, INET_ADDRSTRLEN);        if (len == 0) {            return NGX_ERROR;        }        ls[i].addr_text.len = ngx_sprintf(ls[i].addr_text.data + len, ":%d",                                          ntohs(sin->sin_port))                              - ls[i].addr_text.data;        ls[i].backlog = NGX_LISTEN_BACKLOG;        olen = sizeof(int);        if (getsockopt(ls[i].fd, SOL_SOCKET, SO_RCVBUF, (void *) &ls[i].rcvbuf,                       &olen)            == -1)        {            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,                          "getsockopt(SO_RCVBUF) %V failed, ignored",                          &ls[i].addr_text);            ls[i].rcvbuf = -1;        }        olen = sizeof(int);        if (getsockopt(ls[i].fd, SOL_SOCKET, SO_SNDBUF, (void *) &ls[i].sndbuf,                       &olen)            == -1)        {            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,                          "getsockopt(SO_SNDBUF) %V failed, ignored",                          &ls[i].addr_text);            ls[i].sndbuf = -1;        }#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)        ngx_memzero(&af, sizeof(struct accept_filter_arg));        olen = sizeof(struct accept_filter_arg);        if (getsockopt(ls[i].fd, SOL_SOCKET, SO_ACCEPTFILTER, &af, &olen)            == -1)        {            err = ngx_errno;            if (err == NGX_EINVAL) {                continue;            }            ngx_log_error(NGX_LOG_NOTICE, cycle->log, err,                          "getsockopt(SO_ACCEPTFILTER) for %V failed, ignored",                          &ls[i].addr_text);            continue;        }        if (olen < sizeof(struct accept_filter_arg) || af.af_name[0] == '\0') {            continue;        }        ls[i].accept_filter = ngx_palloc(cycle->pool, 16);        if (ls[i].accept_filter == NULL) {            return NGX_ERROR;        }        (void) ngx_cpystrn((u_char *) ls[i].accept_filter,                           (u_char *) af.af_name, 16);#endif#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)        timeout = 0;        olen = sizeof(int);        if (getsockopt(ls[i].fd, IPPROTO_TCP, TCP_DEFER_ACCEPT, &timeout, &olen)            == -1)        {            ngx_log_error(NGX_LOG_NOTICE, cycle->log, ngx_errno,                          "getsockopt(TCP_DEFER_ACCEPT) for %V failed, ignored",                          &ls[i].addr_text);            continue;        }        if (olen < sizeof(int) || timeout == 0) {            continue;        }        ls[i].deferred_accept = 1;#endif    }    return NGX_OK;}ngx_int_tngx_open_listening_sockets(ngx_cycle_t *cycle){    int               reuseaddr;    ngx_uint_t        i, tries, failed;    ngx_err_t         err;    ngx_log_t        *log;    ngx_socket_t      s;    ngx_listening_t  *ls;    reuseaddr = 1;#if (NGX_SUPPRESS_WARN)    failed = 0;#endif    log = cycle->log;    /* TODO: configurable try number */    for (tries = 5 ; tries; tries--) {        failed = 0;        /* for each listening socket */        ls = cycle->listening.elts;        for (i = 0; i < cycle->listening.nelts; i++) {            if (ls[i].ignore) {                continue;            }            if (ls[i].fd != -1) {                continue;            }            if (ls[i].inherited) {                /* TODO: close on exit */                /* TODO: nonblocking */                /* TODO: deferred accept */                continue;            }            s = ngx_socket(ls[i].family, ls[i].type, 0);            if (s == -1) {                ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,                              ngx_socket_n " %V failed", &ls[i].addr_text);                return NGX_ERROR;            }            if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,                           (const void *) &reuseaddr, sizeof(int))                == -1)            {                ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,                              "setsockopt(SO_REUSEADDR) %V failed",                              &ls[i].addr_text);                if (ngx_close_socket(s) == -1) {                    ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,                                  ngx_close_socket_n " %V failed",                                  &ls[i].addr_text);                }                return NGX_ERROR;            }            /* TODO: close on exit */            if (!(ngx_event_flags & NGX_USE_AIO_EVENT)) {                if (ngx_nonblocking(s) == -1) {                    ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,                                  ngx_nonblocking_n " %V failed",                                  &ls[i].addr_text);                    if (ngx_close_socket(s) == -1) {                        ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,                                      ngx_close_socket_n " %V failed",                                      &ls[i].addr_text);                    }                    return NGX_ERROR;                }            }            ngx_log_debug2(NGX_LOG_DEBUG_CORE, cycle->log, 0,                           "bind() %V #%d ", &ls[i].addr_text, s);            if (bind(s, ls[i].sockaddr, ls[i].socklen) == -1) {                err = ngx_socket_errno;                if (err == NGX_EADDRINUSE && ngx_test_config) {                    continue;                }                ngx_log_error(NGX_LOG_EMERG, log, err,                              "bind() to %V failed", &ls[i].addr_text);                if (ngx_close_socket(s) == -1) {                    ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,                                  ngx_close_socket_n " %V failed",                                  &ls[i].addr_text);                }                if (err != NGX_EADDRINUSE) {                    return NGX_ERROR;                }                failed = 1;                continue;            }            if (listen(s, ls[i].backlog) == -1) {                ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,                              "listen() to %V, backlog %d failed",                              &ls[i].addr_text, ls[i].backlog);                if (ngx_close_socket(s) == -1) {                    ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,                                  ngx_close_socket_n " %V failed",                                  &ls[i].addr_text);                }                return NGX_ERROR;            }            ls[i].listen = 1;            ls[i].fd = s;        }        if (!failed) {            break;        }        /* TODO: delay configurable */        ngx_log_error(NGX_LOG_NOTICE, log, 0,                      "try again to bind() after 500ms");        ngx_msleep(500);    }    if (failed) {        ngx_log_error(NGX_LOG_EMERG, log, 0, "still could not bind()");        return NGX_ERROR;    }    return NGX_OK;}voidngx_configure_listening_socket(ngx_cycle_t *cycle){    ngx_uint_t                 i;    ngx_listening_t           *ls;#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)    struct accept_filter_arg   af;#endif#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)    int                        timeout;#endif    ls = cycle->listening.elts;    for (i = 0; i < cycle->listening.nelts; i++) {        if (ls[i].rcvbuf != -1) {            if (setsockopt(ls[i].fd, SOL_SOCKET, SO_RCVBUF,                           (const void *) &ls[i].rcvbuf, sizeof(int))                == -1)            {                ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,                              "setsockopt(SO_RCVBUF, %d) %V failed, ignored",                              ls[i].rcvbuf, &ls[i].addr_text);            }        }        if (ls[i].sndbuf != -1) {            if (setsockopt(ls[i].fd, SOL_SOCKET, SO_SNDBUF,                           (const void *) &ls[i].sndbuf, sizeof(int))                == -1)            {                ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,                              "setsockopt(SO_SNDBUF, %d) %V failed, ignored",                              ls[i].sndbuf, &ls[i].addr_text);            }        }#if 0        if (1) {            int tcp_nodelay = 1;            if (setsockopt(ls[i].fd, IPPROTO_TCP, TCP_NODELAY,                       (const void *) &tcp_nodelay, sizeof(int))                == -1)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -