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) { #if (NGX_HAVE_INET6) case AF_INET6: sin6 = (struct sockaddr_in6 *) sa; p = sin6->sin6_port; break; #endif default: /* AF_INET */ sin = (struct sockaddr_in *) sa; p = sin->sin_port; break; } port = ports->elts; for (i = 0; i < ports->nelts; i++) { if (p != port[i].port || sa->sa_family != port[i].family) { continue; } /* a port is already in the port list */ return ngx_http_add_addresses(cf, cscf, &port[i], listen); } /* add a port to the port list */ port = ngx_array_push(ports); if (port == NULL) { return NGX_ERROR; } port->family = sa->sa_family; port->port = p; port->addrs.elts = NULL; return ngx_http_add_address(cf, cscf, port, 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_opt_t *lsopt) { u_char *p; size_t len, off; ngx_uint_t i, default_server; struct sockaddr *sa; ngx_http_conf_addr_t *addr; #if (NGX_HAVE_UNIX_DOMAIN) struct sockaddr_un *saun; #endif /* * we can not compare whole sockaddr struct's as kernel * may fill some fields in inherited sockaddr struct's */ sa = &lsopt->u.sockaddr; switch (sa->sa_family) { #if (NGX_HAVE_INET6) case AF_INET6: off = offsetof(struct sockaddr_in6, sin6_addr); len = 16; break; #endif #if (NGX_HAVE_UNIX_DOMAIN) case AF_UNIX: off = offsetof(struct sockaddr_un, sun_path); len = sizeof(saun->sun_path); break; #endif default: /* AF_INET */ off = offsetof(struct sockaddr_in, sin_addr); len = 4; break; } p = lsopt->u.sockaddr_data + off; addr = port->addrs.elts; for (i = 0; i < port->addrs.nelts; i++) { if (ngx_memcmp(p, addr[i].opt.u.sockaddr_data + off, len) != 0) { continue; } /* the address is already in the address list */ if (ngx_http_add_server(cf, cscf, &addr[i]) != NGX_OK) { return NGX_ERROR; } /* preserve default_server bit during listen options overwriting */ default_server = addr[i].opt.default_server; if (lsopt->set) { if (addr[i].opt.set) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "a duplicate listen options for %s", addr[i].opt.addr); return NGX_ERROR; } addr[i].opt = *lsopt; } /* check the duplicate "default" server for this address:port */ if (lsopt->default_server) { if (default_server) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "a duplicate default server for %s", addr[i].opt.addr); return NGX_ERROR; } default_server = 1; addr[i].default_server = cscf; } addr[i].opt.default_server = default_server; return NGX_OK; } /* add the address to the addresses list that bound to this port */ return ngx_http_add_address(cf, cscf, port, lsopt); }
ngx_int_t ngx_http_add_listen(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf, ngx_http_listen_opt_t *lsopt) { 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 cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); 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; } } sa = &lsopt->u.sockaddr; switch (sa->sa_family) { #if (NGX_HAVE_INET6) case AF_INET6: sin6 = &lsopt->u.sockaddr_in6; p = sin6->sin6_port; break; #endif #if (NGX_HAVE_UNIX_DOMAIN) case AF_UNIX: p = 0; break; #endif default: /* AF_INET */ sin = &lsopt->u.sockaddr_in; p = sin->sin_port; break; } port = cmcf->ports->elts; for (i = 0; i < cmcf->ports->nelts; i++) { if (p != port[i].port || sa->sa_family != port[i].family) { continue; } /* a port is already in the port list */ return ngx_http_add_addresses(cf, cscf, &port[i], lsopt); } /* add a port to the port list */ port = ngx_array_push(cmcf->ports); if (port == NULL) { return NGX_ERROR; } port->family = sa->sa_family; port->port = p; port->addrs.elts = NULL; return ngx_http_add_address(cf, cscf, port, lsopt); }
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) { u_char *p; size_t len, off; ngx_uint_t i; struct sockaddr *sa; ngx_http_conf_addr_t *addr; /* * we can not compare whole sockaddr struct's as kernel * may fill some fields in inherited sockaddr struct's */ sa = (struct sockaddr *) &listen->sockaddr; switch (sa->sa_family) { #if (NGX_HAVE_INET6) case AF_INET6: off = offsetof(struct sockaddr_in6, sin6_addr); len = 16; break; #endif default: /* AF_INET */ off = offsetof(struct sockaddr_in, sin_addr); len = 4; break; } p = listen->sockaddr + off; addr = port->addrs.elts; for (i = 0; i < port->addrs.nelts; i++) { if (ngx_memcmp(p, (u_char *) addr[i].sockaddr + off, len) != 0) { continue; } /* the address is already in the address list */ if (ngx_http_add_names(cf, cscf, &addr[i]) != NGX_OK) { return NGX_ERROR; } /* check the duplicate "default" server for this address:port */ if (listen->conf.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); return NGX_ERROR; } addr[i].core_srv_conf = cscf; addr[i].default_server = 1; #if (NGX_HTTP_SSL) addr[i].ssl = listen->conf.ssl; #endif addr[i].listen_conf = &listen->conf; } return NGX_OK; } /* add the address to the addresses list that bound to this port */ return ngx_http_add_address(cf, cscf, port, listen); }