changeset 3217:a22bf524a456

refactor http listen code: *) add listen's to the global cmcf->ports array instead of server's one *) rename ngx_http_listen_conf_t to ngx_http_listen_opt_t
author Igor Sysoev <igor@sysoev.ru>
date Wed, 21 Oct 2009 08:19:46 +0000
parents 79ae445ec57b
children 022a7662b4ed
files src/http/ngx_http.c src/http/ngx_http.h src/http/ngx_http_core_module.c src/http/ngx_http_core_module.h
diffstat 4 files changed, 114 insertions(+), 174 deletions(-) [+]
line wrap: on
line diff
--- a/src/http/ngx_http.c
+++ b/src/http/ngx_http.c
@@ -17,11 +17,6 @@ static ngx_int_t ngx_http_init_headers_i
 static ngx_int_t ngx_http_init_phase_handlers(ngx_conf_t *cf,
     ngx_http_core_main_conf_t *cmcf);
 
-static ngx_int_t ngx_http_init_server_lists(ngx_conf_t *cf,
-    ngx_array_t *servers, ngx_array_t *ports);
-static ngx_int_t ngx_http_add_ports(ngx_conf_t *cf,
-    ngx_http_core_srv_conf_t *cscf, ngx_array_t *ports,
-    ngx_http_listen_t *listen);
 static ngx_int_t ngx_http_add_addresses(ngx_conf_t *cf,
     ngx_http_core_srv_conf_t *cscf, ngx_http_conf_port_t *port,
     ngx_http_listen_t *listen);
@@ -122,7 +117,6 @@ ngx_http_block(ngx_conf_t *cf, ngx_comma
     char                        *rv;
     ngx_uint_t                   mi, m, s;
     ngx_conf_t                   pcf;
-    ngx_array_t                  ports;
     ngx_http_module_t           *module;
     ngx_http_conf_ctx_t         *ctx;
     ngx_http_core_loc_conf_t    *clcf;
@@ -362,19 +356,9 @@ ngx_http_block(ngx_conf_t *cf, ngx_comma
     }
 
 
-    /*
-     * create the lists of ports, addresses and server names
-     * to find quickly the server core module configuration at run-time
-     */
-
-    if (ngx_http_init_server_lists(cf, &cmcf->servers, &ports) != NGX_OK) {
-        return NGX_CONF_ERROR;
-    }
-
-
     /* optimize the lists of ports, addresses and server names */
 
-    if (ngx_http_optimize_servers(cf, cmcf, &ports) != NGX_OK) {
+    if (ngx_http_optimize_servers(cf, cmcf, cmcf->ports) != NGX_OK) {
         return NGX_CONF_ERROR;
     }
 
@@ -1109,53 +1093,30 @@ inclusive:
 }
 
 
-static ngx_int_t
-ngx_http_init_server_lists(ngx_conf_t *cf, ngx_array_t *servers,
-    ngx_array_t *ports)
+ngx_int_t
+ngx_http_add_listen(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
+    ngx_http_listen_t *listen)
 {
-    ngx_uint_t                  s, i;
-    ngx_http_listen_t          *listen;
-    ngx_http_core_srv_conf_t  **cscfp;
-
-    if (ngx_array_init(ports, cf->temp_pool, 2, sizeof(ngx_http_conf_port_t))
-        != NGX_OK)
-    {
-        return NGX_ERROR;
-    }
+    in_port_t                   p;
+    ngx_uint_t                  i;
+    struct sockaddr            *sa;
+    struct sockaddr_in         *sin;
+    ngx_http_conf_port_t       *port;
+    ngx_http_core_main_conf_t  *cmcf;
+#if (NGX_HAVE_INET6)
+    struct sockaddr_in6        *sin6;
+#endif
 
-    /* "server" directives */
-
-    cscfp = servers->elts;
-    for (s = 0; s < servers->nelts; s++) {
-
-        /* "listen" directives */
+    cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
 
-        listen = cscfp[s]->listen.elts;
-        for (i = 0; i < cscfp[s]->listen.nelts; i++) {
-
-            if (ngx_http_add_ports(cf, cscfp[s], ports, &listen[i]) != NGX_OK) {
-                return NGX_ERROR;
-            }
+    if (cmcf->ports == NULL) {
+        cmcf->ports = ngx_array_create(cf->temp_pool, 2,
+                                       sizeof(ngx_http_conf_port_t));
+        if (cmcf->ports == NULL) {
+            return NGX_ERROR;
         }
     }
 
-    return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_add_ports(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
-    ngx_array_t *ports, ngx_http_listen_t *listen)
-{
-    in_port_t                 p;
-    ngx_uint_t                i;
-    struct sockaddr          *sa;
-    struct sockaddr_in       *sin;
-    ngx_http_conf_port_t     *port;
-#if (NGX_HAVE_INET6)
-    struct sockaddr_in6      *sin6;
-#endif
-
     sa = (struct sockaddr *) &listen->sockaddr;
 
     switch (sa->sa_family) {
@@ -1173,8 +1134,8 @@ ngx_http_add_ports(ngx_conf_t *cf, ngx_h
         break;
     }
 
-    port = ports->elts;
-    for (i = 0; i < ports->nelts; i++) {
+    port = cmcf->ports->elts;
+    for (i = 0; i < cmcf->ports->nelts; i++) {
 
         if (p != port[i].port || sa->sa_family != port[i].family) {
             continue;
@@ -1187,7 +1148,7 @@ ngx_http_add_ports(ngx_conf_t *cf, ngx_h
 
     /* add a port to the port list */
 
-    port = ngx_array_push(ports);
+    port = ngx_array_push(cmcf->ports);
     if (port == NULL) {
         return NGX_ERROR;
     }
@@ -1250,22 +1211,20 @@ ngx_http_add_addresses(ngx_conf_t *cf, n
 
         /* check the duplicate "default" server for this address:port */
 
-        if (listen->conf.default_server) {
+        if (listen->opt.default_server) {
 
             if (addr[i].default_server) {
-                ngx_log_error(NGX_LOG_ERR, cf->log, 0,
-                              "the duplicate default server in %s:%ui",
-                               listen->file_name, listen->line);
-
+                ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+                                   "the duplicate default server");
                 return NGX_ERROR;
             }
 
             addr[i].core_srv_conf = cscf;
             addr[i].default_server = 1;
 #if (NGX_HTTP_SSL)
-            addr[i].ssl = listen->conf.ssl;
+            addr[i].ssl = listen->opt.ssl;
 #endif
-            addr[i].listen_conf = &listen->conf;
+            addr[i].opt = listen->opt;
         }
 
         return NGX_OK;
@@ -1302,7 +1261,7 @@ ngx_http_add_address(ngx_conf_t *cf, ngx
         return NGX_ERROR;
     }
 
-    addr->sockaddr = (struct sockaddr *) &listen->sockaddr;
+    ngx_memcpy(addr->sockaddr, listen->sockaddr, listen->socklen);
     addr->socklen = listen->socklen;
     addr->hash.buckets = NULL;
     addr->hash.size = 0;
@@ -1314,13 +1273,13 @@ ngx_http_add_address(ngx_conf_t *cf, ngx
     addr->regex = NULL;
 #endif
     addr->core_srv_conf = cscf;
-    addr->default_server = listen->conf.default_server;
-    addr->bind = listen->conf.bind;
-    addr->wildcard = listen->conf.wildcard;
+    addr->default_server = listen->opt.default_server;
+    addr->bind = listen->opt.bind;
+    addr->wildcard = listen->opt.wildcard;
 #if (NGX_HTTP_SSL)
-    addr->ssl = listen->conf.ssl;
+    addr->ssl = listen->opt.ssl;
 #endif
-    addr->listen_conf = &listen->conf;
+    addr->opt = listen->opt;
 
     return ngx_http_add_names(cf, cscf, addr);
 }
@@ -1470,14 +1429,14 @@ ngx_http_server_names(ngx_conf_t *cf, ng
         if (rc == NGX_DECLINED) {
             ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
                           "invalid server name or wildcard \"%V\" on %s",
-                          &name[s].name, addr->listen_conf->addr);
+                          &name[s].name, addr->opt.addr);
             return NGX_ERROR;
         }
 
         if (rc == NGX_BUSY) {
             ngx_log_error(NGX_LOG_WARN, cf->log, 0,
                           "conflicting server name \"%V\" on %s, ignored",
-                          &name[s].name, addr->listen_conf->addr);
+                          &name[s].name, addr->opt.addr);
         }
     }
 
@@ -1721,20 +1680,20 @@ ngx_http_add_listening(ngx_conf_t *cf, n
     }
 #endif
 
-    ls->backlog = addr->listen_conf->backlog;
-    ls->rcvbuf = addr->listen_conf->rcvbuf;
-    ls->sndbuf = addr->listen_conf->sndbuf;
+    ls->backlog = addr->opt.backlog;
+    ls->rcvbuf = addr->opt.rcvbuf;
+    ls->sndbuf = addr->opt.sndbuf;
 
 #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
-    ls->accept_filter = addr->listen_conf->accept_filter;
+    ls->accept_filter = addr->opt.accept_filter;
 #endif
 
 #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
-    ls->deferred_accept = addr->listen_conf->deferred_accept;
+    ls->deferred_accept = addr->opt.deferred_accept;
 #endif
 
 #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
-    ls->ipv6only = addr->listen_conf->ipv6only;
+    ls->ipv6only = addr->opt.ipv6only;
 #endif
 
     return ls;
--- a/src/http/ngx_http.h
+++ b/src/http/ngx_http.h
@@ -57,6 +57,8 @@ struct ngx_http_log_ctx_s {
 
 ngx_int_t ngx_http_add_location(ngx_conf_t *cf, ngx_queue_t **locations,
     ngx_http_core_loc_conf_t *clcf);
+ngx_int_t ngx_http_add_listen(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
+    ngx_http_listen_t *listen);
 
 
 void ngx_http_init_connection(ngx_connection_t *c);
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -2807,13 +2807,6 @@ ngx_http_core_create_srv_conf(ngx_conf_t
      *     conf->client_large_buffers.num = 0;
      */
 
-    if (ngx_array_init(&cscf->listen, cf->temp_pool, 4,
-                       sizeof(ngx_http_listen_t))
-        != NGX_OK)
-    {
-        return NULL;
-    }
-
     if (ngx_array_init(&cscf->server_names, cf->temp_pool, 4,
                        sizeof(ngx_http_server_name_t))
         != NGX_OK)
@@ -2839,21 +2832,16 @@ ngx_http_core_merge_srv_conf(ngx_conf_t 
     ngx_http_core_srv_conf_t *prev = parent;
     ngx_http_core_srv_conf_t *conf = child;
 
-    ngx_http_listen_t       *ls;
+    ngx_http_listen_t        ls;
     struct sockaddr_in      *sin;
     ngx_http_server_name_t  *sn;
 
     /* TODO: it does not merge, it inits only */
 
-    if (conf->listen.nelts == 0) {
-        ls = ngx_array_push(&conf->listen);
-        if (ls == NULL) {
-            return NGX_CONF_ERROR;
-        }
-
-        ngx_memzero(ls, sizeof(ngx_http_listen_t));
-
-        sin = (struct sockaddr_in *) &ls->sockaddr;
+    if (!conf->listen) {
+        ngx_memzero(&ls, sizeof(ngx_http_listen_t));
+
+        sin = (struct sockaddr_in *) &ls.sockaddr;
 
         sin->sin_family = AF_INET;
 #if (NGX_WIN32)
@@ -2863,15 +2851,19 @@ ngx_http_core_merge_srv_conf(ngx_conf_t 
 #endif
         sin->sin_addr.s_addr = INADDR_ANY;
 
-        ls->socklen = sizeof(struct sockaddr_in);
-
-        ls->conf.backlog = NGX_LISTEN_BACKLOG;
-        ls->conf.rcvbuf = -1;
-        ls->conf.sndbuf = -1;
-        ls->conf.wildcard = 1;
-
-        (void) ngx_sock_ntop((struct sockaddr *) &ls->sockaddr, ls->conf.addr,
+        ls.socklen = sizeof(struct sockaddr_in);
+
+        ls.opt.backlog = NGX_LISTEN_BACKLOG;
+        ls.opt.rcvbuf = -1;
+        ls.opt.sndbuf = -1;
+        ls.opt.wildcard = 1;
+
+        (void) ngx_sock_ntop((struct sockaddr *) &ls.sockaddr, ls.opt.addr,
                              NGX_SOCKADDR_STRLEN, 1);
+
+        if (ngx_http_add_listen(cf, conf, &ls) == NGX_OK) {
+            return NGX_CONF_OK;
+        }
     }
 
     if (conf->server_name.data == NULL) {
@@ -3273,17 +3265,14 @@ ngx_http_core_merge_loc_conf(ngx_conf_t 
 static char *
 ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
 {
-    ngx_http_core_srv_conf_t *scf = conf;
+    ngx_http_core_srv_conf_t *cscf = conf;
 
     ngx_str_t          *value, size;
     ngx_url_t           u;
     ngx_uint_t          n;
-    ngx_http_listen_t  *ls;
-
-    /*
-     * TODO: check duplicate 'listen' directives,
-     *       add resolved name to server names ???
-     */
+    ngx_http_listen_t   ls;
+
+    cscf->listen = 1;
 
     value = cf->args->elts;
 
@@ -3303,32 +3292,21 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx
         return NGX_CONF_ERROR;
     }
 
-    ls = ngx_array_push(&scf->listen);
-    if (ls == NULL) {
-        return NGX_CONF_ERROR;
-    }
-
-    ngx_memzero(ls, sizeof(ngx_http_listen_t));
-
-    ngx_memcpy(ls->sockaddr, u.sockaddr, u.socklen);
-
-    ls->socklen = u.socklen;
-    ls->file_name = cf->conf_file->file.name.data;
-    ls->line = cf->conf_file->line;
-    ls->conf.backlog = NGX_LISTEN_BACKLOG;
-    ls->conf.rcvbuf = -1;
-    ls->conf.sndbuf = -1;
-    ls->conf.wildcard = u.wildcard;
-
-    (void) ngx_sock_ntop((struct sockaddr *) &ls->sockaddr, ls->conf.addr,
+    ngx_memzero(&ls, sizeof(ngx_http_listen_t));
+
+    ngx_memcpy(ls.sockaddr, u.sockaddr, u.socklen);
+
+    ls.socklen = u.socklen;
+    ls.opt.backlog = NGX_LISTEN_BACKLOG;
+    ls.opt.rcvbuf = -1;
+    ls.opt.sndbuf = -1;
+    ls.opt.wildcard = u.wildcard;
+
+    (void) ngx_sock_ntop((struct sockaddr *) &ls.sockaddr, ls.opt.addr,
                          NGX_SOCKADDR_STRLEN, 1);
 
-    if (cf->args->nelts == 2) {
-        return NGX_CONF_OK;
-    }
-
-    if (ngx_strcmp(value[2].data, "default") == 0) {
-        ls->conf.default_server = 1;
+    if (cf->args->nelts > 2 && ngx_strcmp(value[2].data, "default") == 0) {
+        ls.opt.default_server = 1;
         n = 3;
 
     } else {
@@ -3337,7 +3315,7 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx
 
     for ( /* void */ ; n < cf->args->nelts; n++) {
 
-        if (ls->conf.default_server == 0) {
+        if (ls.opt.default_server == 0) {
             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                                "\"%V\" parameter can be specified for "
                                "the default \"listen\" directive only",
@@ -3346,15 +3324,15 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx
         }
 
         if (ngx_strcmp(value[n].data, "bind") == 0) {
-            ls->conf.bind = 1;
+            ls.opt.bind = 1;
             continue;
         }
 
         if (ngx_strncmp(value[n].data, "backlog=", 8) == 0) {
-            ls->conf.backlog = ngx_atoi(value[n].data + 8, value[n].len - 8);
-            ls->conf.bind = 1;
-
-            if (ls->conf.backlog == NGX_ERROR || ls->conf.backlog == 0) {
+            ls.opt.backlog = ngx_atoi(value[n].data + 8, value[n].len - 8);
+            ls.opt.bind = 1;
+
+            if (ls.opt.backlog == NGX_ERROR || ls.opt.backlog == 0) {
                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                                    "invalid backlog \"%V\"", &value[n]);
                 return NGX_CONF_ERROR;
@@ -3367,10 +3345,10 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx
             size.len = value[n].len - 7;
             size.data = value[n].data + 7;
 
-            ls->conf.rcvbuf = ngx_parse_size(&size);
-            ls->conf.bind = 1;
-
-            if (ls->conf.rcvbuf == NGX_ERROR) {
+            ls.opt.rcvbuf = ngx_parse_size(&size);
+            ls.opt.bind = 1;
+
+            if (ls.opt.rcvbuf == NGX_ERROR) {
                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                                    "invalid rcvbuf \"%V\"", &value[n]);
                 return NGX_CONF_ERROR;
@@ -3383,10 +3361,10 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx
             size.len = value[n].len - 7;
             size.data = value[n].data + 7;
 
-            ls->conf.sndbuf = ngx_parse_size(&size);
-            ls->conf.bind = 1;
-
-            if (ls->conf.sndbuf == NGX_ERROR) {
+            ls.opt.sndbuf = ngx_parse_size(&size);
+            ls.opt.bind = 1;
+
+            if (ls.opt.sndbuf == NGX_ERROR) {
                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                                    "invalid sndbuf \"%V\"", &value[n]);
                 return NGX_CONF_ERROR;
@@ -3397,8 +3375,8 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx
 
         if (ngx_strncmp(value[n].data, "accept_filter=", 14) == 0) {
 #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
-            ls->conf.accept_filter = (char *) &value[n].data[14];
-            ls->conf.bind = 1;
+            ls.opt.accept_filter = (char *) &value[n].data[14];
+            ls.opt.bind = 1;
 #else
             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                                "accept filters \"%V\" are not supported "
@@ -3410,8 +3388,8 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx
 
         if (ngx_strcmp(value[n].data, "deferred") == 0) {
 #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
-            ls->conf.deferred_accept = 1;
-            ls->conf.bind = 1;
+            ls.opt.deferred_accept = 1;
+            ls.opt.bind = 1;
 #else
             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                                "the deferred accept is not supported "
@@ -3424,15 +3402,15 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx
 #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
             struct sockaddr  *sa;
 
-            sa = (struct sockaddr *) ls->sockaddr;
+            sa = (struct sockaddr *) ls.sockaddr;
 
             if (sa->sa_family == AF_INET6) {
 
                 if (ngx_strcmp(&value[n].data[10], "n") == 0) {
-                    ls->conf.ipv6only = 1;
+                    ls.opt.ipv6only = 1;
 
                 } else if (ngx_strcmp(&value[n].data[10], "ff") == 0) {
-                    ls->conf.ipv6only = 2;
+                    ls.opt.ipv6only = 2;
 
                 } else {
                     ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
@@ -3441,13 +3419,12 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx
                     return NGX_CONF_ERROR;
                 }
 
-                ls->conf.bind = 1;
+                ls.opt.bind = 1;
 
             } else {
                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                                    "ipv6only is not supported "
-                                   "on addr \"%s\", ignored",
-                                   ls->conf.addr);
+                                   "on addr \"%s\", ignored", ls.opt.addr);
             }
 
             continue;
@@ -3461,7 +3438,7 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx
 
         if (ngx_strcmp(value[n].data, "ssl") == 0) {
 #if (NGX_HTTP_SSL)
-            ls->conf.ssl = 1;
+            ls.opt.ssl = 1;
             continue;
 #else
             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
@@ -3476,7 +3453,11 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx
         return NGX_CONF_ERROR;
     }
 
-    return NGX_CONF_OK;
+    if (ngx_http_add_listen(cf, cscf, &ls) == NGX_OK) {
+        return NGX_CONF_OK;
+    }
+
+    return NGX_CONF_ERROR;
 }
 
 
--- a/src/http/ngx_http_core_module.h
+++ b/src/http/ngx_http_core_module.h
@@ -65,17 +65,14 @@ typedef struct {
 #endif
 
     u_char                     addr[NGX_SOCKADDR_STRLEN + 1];
-} ngx_http_listen_conf_t;
+} ngx_http_listen_opt_t;
 
 
 typedef struct {
     u_char                     sockaddr[NGX_SOCKADDRLEN];
     socklen_t                  socklen;
 
-    u_char                    *file_name;
-    ngx_uint_t                 line;
-
-    ngx_http_listen_conf_t     conf;
+    ngx_http_listen_opt_t      opt;
 } ngx_http_listen_t;
 
 
@@ -142,6 +139,8 @@ typedef struct {
 
     ngx_hash_keys_arrays_t    *variables_keys;
 
+    ngx_array_t               *ports;
+
     ngx_uint_t                 try_files;       /* unsigned  try_files:1 */
 
     ngx_http_phase_t           phases[NGX_HTTP_LOG_PHASE + 1];
@@ -149,9 +148,6 @@ typedef struct {
 
 
 typedef struct {
-    /* array of the ngx_http_listen_t, "listen" directive */
-    ngx_array_t                 listen;
-
     /* array of the ngx_http_server_name_t, "server_name" directive */
     ngx_array_t                 server_names;
 
@@ -172,6 +168,8 @@ typedef struct {
     ngx_flag_t                  merge_slashes;
     ngx_flag_t                  underscores_in_headers;
 
+    ngx_uint_t                  listen;         /* unsigned  listen:1; */
+
     ngx_http_core_loc_conf_t  **named_locations;
 } ngx_http_core_srv_conf_t;
 
@@ -222,7 +220,7 @@ typedef struct {
 
 
 typedef struct {
-    struct sockaddr           *sockaddr;
+    u_char                     sockaddr[NGX_SOCKADDRLEN];
     socklen_t                  socklen;
 
     ngx_hash_t                 hash;
@@ -246,7 +244,7 @@ typedef struct {
     unsigned                   ssl:1;
 #endif
 
-    ngx_http_listen_conf_t    *listen_conf;
+    ngx_http_listen_opt_t      opt;
 } ngx_http_conf_addr_t;