static char * ngx_http_srcache_store_statuses(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_http_srcache_loc_conf_t *slcf = conf; ngx_uint_t i, n; ngx_int_t status; ngx_str_t *value; value = cf->args->elts; if (slcf->store_statuses) { return "is duplicate"; } n = cf->args->nelts - 1; slcf->store_statuses = ngx_pnalloc(cf->pool, (n + 1) * sizeof(ngx_int_t)); if (slcf->store_statuses == NULL) { return NGX_CONF_ERROR; } for (i = 1; i <= n; i++) { status = ngx_atoi(value[i].data, value[i].len); if (status == NGX_ERROR) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "status code \"%V\" is an invalid number", &value[i]); return NGX_CONF_ERROR; } if (status < 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "status code \"%V\" is not a positive number", &value[i]); return NGX_CONF_ERROR; } slcf->store_statuses[i - 1] = status; } slcf->store_statuses[i - 1] = 0; ngx_sort(slcf->store_statuses, n, sizeof(ngx_int_t), ngx_http_srcache_cmp_int); #if 0 for (i = 0; i < n; i++) { dd("status: %d", (int) slcf->store_statuses[i]); } #endif return NGX_CONF_OK; }
static ngx_int_t ngx_http_optimize_servers(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf, ngx_array_t *ports) { ngx_uint_t s, p, a; ngx_http_conf_port_t *port; ngx_http_conf_addr_t *addr; ngx_http_server_name_t *name; port = ports->elts; for (p = 0; p < ports->nelts; p++) { ngx_sort(port[p].addrs.elts, (size_t) port[p].addrs.nelts, sizeof(ngx_http_conf_addr_t), ngx_http_cmp_conf_addrs); /* * check whether all name-based servers have the same * configuraiton as a default server for given address:port */ addr = port[p].addrs.elts; for (a = 0; a < port[p].addrs.nelts; a++) { name = addr[a].names.elts; for (s = 0; s < addr[a].names.nelts; s++) { if (addr[a].core_srv_conf == name[s].core_srv_conf #if (NGX_PCRE) && name[s].captures == 0 #endif ) { continue; } if (ngx_http_server_names(cf, cmcf, &addr[a]) != NGX_OK) { return NGX_ERROR; } break; } } if (ngx_http_init_listening(cf, &port[p]) != NGX_OK) { return NGX_ERROR; } } return NGX_OK; }
static ngx_int_t ngx_http_google_response_header_set_cookie_conf(ngx_http_request_t * r, ngx_http_google_ctx_t * ctx, ngx_str_t * v) { if (ctx->type != ngx_http_google_type_main && ctx->type != ngx_http_google_type_scholar) return NGX_OK; if (ctx->ncr) return NGX_OK; ngx_uint_t i; ngx_array_t * kvs = ngx_http_google_explode_kv(r, v, ":"); if (!kvs) return NGX_ERROR; ngx_int_t nw = 0; ngx_keyval_t * kv, * hd; hd = kvs->elts; for (i = 0; i < kvs->nelts; i++) { kv = hd + i; if (!ngx_strncasecmp(kv->key.data, (u_char *)"LD", 2)) { if (ctx->lang->len) kv->value = *ctx->lang; else { ngx_str_set(&kv->value, "zh-CN"); } } if (!ngx_strncasecmp(kv->key.data, (u_char *)"NW", 2)) nw = 1; } if (!nw) { kv = ngx_array_push(kvs); if (!kv) return NGX_ERROR; ngx_str_set(&kv->key, "NW"); ngx_str_set(&kv->value, "1"); } // sort with length ngx_sort(kvs->elts, kvs->nelts, sizeof(ngx_keyval_t), ngx_http_google_response_header_sort_cookie_conf); ngx_str_t * nv = ngx_http_google_implode_kv(r, kvs, ":"); if (!nv) return NGX_ERROR; *v = *nv; return NGX_OK; }
static ngx_int_t ngx_http_optimize_servers(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf, ngx_array_t *ports) { ngx_uint_t p, a; ngx_http_conf_port_t *port; ngx_http_conf_addr_t *addr; if (ports == NULL) { return NGX_OK; } port = ports->elts; for (p = 0; p < ports->nelts; p++) { ngx_sort(port[p].addrs.elts, (size_t) port[p].addrs.nelts, sizeof(ngx_http_conf_addr_t), ngx_http_cmp_conf_addrs); /* * check whether all name-based servers have the same * configuraiton as a default server for given address:port */ addr = port[p].addrs.elts; for (a = 0; a < port[p].addrs.nelts; a++) { if (addr[a].servers.nelts > 1 #if (NGX_PCRE) || addr[a].default_server->captures #endif ) { if (ngx_http_server_names(cf, cmcf, &addr[a]) != NGX_OK) { return NGX_ERROR; } } } if (ngx_http_init_listening(cf, &port[p]) != NGX_OK) { return NGX_ERROR; } } return NGX_OK; }
static void ngx_http_sub_init_tables(ngx_http_sub_tables_t *tables, ngx_http_sub_match_t *match, ngx_uint_t n) { u_char c; ngx_uint_t i, j, min, max, ch; min = match[0].match.len; max = match[0].match.len; for (i = 1; i < n; i++) { min = ngx_min(min, match[i].match.len); max = ngx_max(max, match[i].match.len); } tables->min_match_len = min; tables->max_match_len = max; ngx_http_sub_cmp_index = tables->min_match_len - 1; ngx_sort(match, n, sizeof(ngx_http_sub_match_t), ngx_http_sub_cmp_matches); min = ngx_min(min, 255); ngx_memset(tables->shift, min, 256); ch = 0; for (i = 0; i < n; i++) { for (j = 0; j < min; j++) { c = match[i].match.data[tables->min_match_len - 1 - j]; tables->shift[c] = ngx_min(tables->shift[c], (u_char) j); } c = match[i].match.data[tables->min_match_len - 1]; while (ch <= (ngx_uint_t) c) { tables->index[ch++] = (u_char) i; } } while (ch < 257) { tables->index[ch++] = (u_char) n; } }
static ngx_int_t ngx_tcp_optimize_servers(ngx_conf_t *cf, ngx_tcp_core_main_conf_t *cmcf, ngx_array_t *ports) { ngx_uint_t p; ngx_tcp_conf_port_t *port; port = ports->elts; for (p = 0; p < ports->nelts; p++) { ngx_sort(port[p].addrs.elts, (size_t) port[p].addrs.nelts, sizeof(ngx_tcp_conf_addr_t), ngx_tcp_cmp_conf_addrs); if (ngx_tcp_init_listening(cf, &port[p]) != NGX_OK) { return NGX_ERROR; } } return NGX_OK; }
ngx_int_t ngx_tcp_upstream_init_round_robin(ngx_conf_t *cf, ngx_tcp_upstream_srv_conf_t *us) { ngx_url_t u; ngx_uint_t i, j, n; ngx_tcp_upstream_server_t *server; ngx_tcp_upstream_rr_peers_t *peers, *backup; us->peer.init = ngx_tcp_upstream_init_round_robin_peer; if (us->servers) { server = us->servers->elts; n = 0; for (i = 0; i < us->servers->nelts; i++) { if (server[i].backup) { continue; } n += server[i].naddrs; } peers = ngx_pcalloc(cf->pool, sizeof(ngx_tcp_upstream_rr_peers_t) + sizeof(ngx_tcp_upstream_rr_peer_t) * (n - 1)); if (peers == NULL) { return NGX_ERROR; } peers->single = (n == 1); peers->number = n; peers->name = &us->host; n = 0; for (i = 0; i < us->servers->nelts; i++) { for (j = 0; j < server[i].naddrs; j++) { if (server[i].backup) { continue; } peers->peer[n].sockaddr = server[i].addrs[j].sockaddr; peers->peer[n].socklen = server[i].addrs[j].socklen; peers->peer[n].name = server[i].addrs[j].name; peers->peer[n].max_fails = server[i].max_fails; peers->peer[n].fail_timeout = server[i].fail_timeout; peers->peer[n].down = server[i].down; peers->peer[n].weight = server[i].down ? 0 : server[i].weight; peers->peer[n].current_weight = peers->peer[n].weight; if (!server[i].down && us->check_interval) { peers->peer[n].check_index = ngx_tcp_check_add_peer(cf, us, &server[i].addrs[j], server[i].max_busy); if (peers->peer[n].check_index == (ngx_uint_t) NGX_INVALID_CHECK_INDEX) { return NGX_ERROR; } } else { peers->peer[n].check_index = (ngx_uint_t) NGX_INVALID_CHECK_INDEX; } n++; } } us->peer.data = peers; ngx_sort(&peers->peer[0], (size_t) n, sizeof(ngx_tcp_upstream_rr_peer_t), ngx_tcp_upstream_cmp_servers); /* backup servers */ n = 0; for (i = 0; i < us->servers->nelts; i++) { if (!server[i].backup) { continue; } n += server[i].naddrs; } if (n == 0) { return NGX_OK; } backup = ngx_pcalloc(cf->pool, sizeof(ngx_tcp_upstream_rr_peers_t) + sizeof(ngx_tcp_upstream_rr_peer_t) * (n - 1)); if (backup == NULL) { return NGX_ERROR; } peers->single = 0; backup->single = 0; backup->number = n; backup->name = &us->host; n = 0; for (i = 0; i < us->servers->nelts; i++) { for (j = 0; j < server[i].naddrs; j++) { if (!server[i].backup) { continue; } backup->peer[n].sockaddr = server[i].addrs[j].sockaddr; backup->peer[n].socklen = server[i].addrs[j].socklen; backup->peer[n].name = server[i].addrs[j].name; backup->peer[n].weight = server[i].weight; backup->peer[n].current_weight = server[i].weight; backup->peer[n].max_fails = server[i].max_fails; backup->peer[n].fail_timeout = server[i].fail_timeout; backup->peer[n].down = server[i].down; if (!server[i].down && us->check_interval) { backup->peer[n].check_index = ngx_tcp_check_add_peer(cf, us, &server[i].addrs[j], server[i].max_busy); if (backup->peer[n].check_index == (ngx_uint_t) NGX_INVALID_CHECK_INDEX) { return NGX_ERROR; } } else { backup->peer[n].check_index = (ngx_uint_t) NGX_INVALID_CHECK_INDEX; } n++; } } peers->next = backup; ngx_sort(&backup->peer[0], (size_t) n, sizeof(ngx_tcp_upstream_rr_peer_t), ngx_tcp_upstream_cmp_servers); return NGX_OK; } /* an upstream implicitly defined by proxy_pass, etc. */ #if (nginx_version) >= 1003011 if (us->port == 0) { #else if (us->port == 0 && us->default_port == 0) { #endif ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no port in upstream \"%V\" in %s:%ui", &us->host, us->file_name, us->line); return NGX_ERROR; } ngx_memzero(&u, sizeof(ngx_url_t)); u.host = us->host; #if (nginx_version) >= 1003011 u.port = us->port; #else u.port = (in_port_t) (us->port ? us->port : us->default_port); #endif if (ngx_inet_resolve_host(cf->pool, &u) != NGX_OK) { if (u.err) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "%s in upstream \"%V\" in %s:%ui", u.err, &us->host, us->file_name, us->line); } return NGX_ERROR; } n = u.naddrs; peers = ngx_pcalloc(cf->pool, sizeof(ngx_tcp_upstream_rr_peers_t) + sizeof(ngx_tcp_upstream_rr_peer_t) * (n - 1)); if (peers == NULL) { return NGX_ERROR; } peers->single = (n == 1); peers->number = n; peers->name = &us->host; for (i = 0; i < u.naddrs; i++) { peers->peer[i].sockaddr = u.addrs[i].sockaddr; peers->peer[i].socklen = u.addrs[i].socklen; peers->peer[i].name = u.addrs[i].name; peers->peer[i].weight = 1; peers->peer[i].current_weight = 1; peers->peer[i].max_fails = 1; peers->peer[i].fail_timeout = 10; peers->peer[i].check_index = (ngx_uint_t) NGX_INVALID_CHECK_INDEX; } us->peer.data = peers; /* implicitly defined upstream has no backup servers */ return NGX_OK; } static ngx_int_t ngx_tcp_upstream_cmp_servers(const void *one, const void *two) { ngx_tcp_upstream_rr_peer_t *first, *second; first = (ngx_tcp_upstream_rr_peer_t *) one; second = (ngx_tcp_upstream_rr_peer_t *) two; return (first->weight < second->weight); }
ngx_int_t ngx_http_upstream_init_round_robin(ngx_conf_t *cf, ngx_http_upstream_srv_conf_t *us) { ngx_url_t u; ngx_uint_t i, j, n; ngx_http_upstream_server_t *server; ngx_http_upstream_rr_peers_t *peers, *backup; us->peer.init = ngx_http_upstream_init_round_robin_peer; if (us->servers) { server = us->servers->elts; n = 0; for (i = 0; i < us->servers->nelts; i++) { if (server[i].backup) { continue; } n += server[i].naddrs; } peers = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_rr_peers_t) + sizeof(ngx_http_upstream_rr_peer_t) * (n - 1)); if (peers == NULL) { return NGX_ERROR; } peers->single = (n == 1); peers->number = n; peers->name = &us->host; n = 0; for (i = 0; i < us->servers->nelts; i++) { for (j = 0; j < server[i].naddrs; j++) { if (server[i].backup) { continue; } peers->peer[n].sockaddr = server[i].addrs[j].sockaddr; peers->peer[n].socklen = server[i].addrs[j].socklen; peers->peer[n].name = server[i].addrs[j].name; peers->peer[n].max_fails = server[i].max_fails; peers->peer[n].fail_timeout = server[i].fail_timeout; peers->peer[n].down = server[i].down; peers->peer[n].weight = server[i].down ? 0 : server[i].weight; peers->peer[n].current_weight = peers->peer[n].weight; n++; } } us->peer.data = peers; ngx_sort(&peers->peer[0], (size_t) n, sizeof(ngx_http_upstream_rr_peer_t), ngx_http_upstream_cmp_servers); /* backup servers */ n = 0; for (i = 0; i < us->servers->nelts; i++) { if (!server[i].backup) { continue; } n += server[i].naddrs; } if (n == 0) { return NGX_OK; } backup = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_rr_peers_t) + sizeof(ngx_http_upstream_rr_peer_t) * (n - 1)); if (backup == NULL) { return NGX_ERROR; } peers->single = 0; backup->single = 0; backup->number = n; backup->name = &us->host; n = 0; for (i = 0; i < us->servers->nelts; i++) { for (j = 0; j < server[i].naddrs; j++) { if (!server[i].backup) { continue; } backup->peer[n].sockaddr = server[i].addrs[j].sockaddr; backup->peer[n].socklen = server[i].addrs[j].socklen; backup->peer[n].name = server[i].addrs[j].name; backup->peer[n].weight = server[i].weight; backup->peer[n].current_weight = server[i].weight; backup->peer[n].max_fails = server[i].max_fails; backup->peer[n].fail_timeout = server[i].fail_timeout; backup->peer[n].down = server[i].down; n++; } } peers->next = backup; ngx_sort(&backup->peer[0], (size_t) n, sizeof(ngx_http_upstream_rr_peer_t), ngx_http_upstream_cmp_servers); return NGX_OK; } /* an upstream implicitly defined by proxy_pass, etc. */ if (us->port == 0 && us->default_port == 0) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no port in upstream \"%V\" in %s:%ui", &us->host, us->file_name, us->line); return NGX_ERROR; } ngx_memzero(&u, sizeof(ngx_url_t)); u.host = us->host; u.port = (in_port_t) (us->port ? us->port : us->default_port); if (ngx_inet_resolve_host(cf->pool, &u) != NGX_OK) { if (u.err) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "%s in upstream \"%V\" in %s:%ui", u.err, &us->host, us->file_name, us->line); } return NGX_ERROR; } n = u.naddrs; peers = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_rr_peers_t) + sizeof(ngx_http_upstream_rr_peer_t) * (n - 1)); if (peers == NULL) { return NGX_ERROR; } peers->single = (n == 1); peers->number = n; peers->name = &us->host; for (i = 0; i < u.naddrs; i++) { peers->peer[i].sockaddr = u.addrs[i].sockaddr; peers->peer[i].socklen = u.addrs[i].socklen; peers->peer[i].name = u.addrs[i].name; peers->peer[i].weight = 1; peers->peer[i].current_weight = 1; peers->peer[i].max_fails = 1; peers->peer[i].fail_timeout = 10; } us->peer.data = peers; /* implicitly defined upstream has no backup servers */ return NGX_OK; }
static char * ngx_handoff_optimize_servers(ngx_conf_t *cf, ngx_handoff_core_main_conf_t *cmcf, ngx_array_t *ports) { ngx_uint_t i, p, last, bind_wildcard; ngx_listening_t *ls; ngx_handoff_port_t *mport; ngx_handoff_conf_port_t *port; ngx_handoff_conf_addr_t *addr; port = ports->elts; for (p = 0; p < ports->nelts; p++) { ngx_sort(port[p].addrs.elts, (size_t) port[p].addrs.nelts, sizeof(ngx_handoff_conf_addr_t), ngx_handoff_cmp_conf_addrs); addr = port[p].addrs.elts; last = port[p].addrs.nelts; /* * if there is the binding to the "*:port" then we need to bind() * to the "*:port" only and ignore the other bindings */ if (addr[last - 1].wildcard) { addr[last - 1].bind = 1; bind_wildcard = 1; } else { bind_wildcard = 0; } i = 0; while (i < last) { if (bind_wildcard && !addr[i].bind) { i++; continue; } ls = ngx_create_listening(cf, addr[i].sockaddr, addr[i].socklen); if (ls == NULL) { return NGX_CONF_ERROR; } ls->addr_ntop = 1; ls->handler = ngx_handoff_init_connection; ls->pool_size = 256; /* TODO: error_log directive */ ls->logp = &cf->cycle->new_log; ls->log.data = &ls->addr_text; ls->log.handler = ngx_accept_log_error; #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) ls->ipv6only = addr[i].ipv6only; #endif #if (NGX_HAVE_TPROXY) ls->tproxy = addr[i].tproxy; #endif mport = ngx_palloc(cf->pool, sizeof(ngx_handoff_port_t)); if (mport == NULL) { return NGX_CONF_ERROR; } ls->servers = mport; if (i == last - 1) { mport->naddrs = last; } else { mport->naddrs = 1; i = 0; } switch (ls->sockaddr->sa_family) { #if (NGX_HAVE_INET6) case AF_INET6: if (ngx_handoff_add_addrs6(cf, mport, addr) != NGX_OK) { return NGX_CONF_ERROR; } break; #endif default: /* AF_INET */ if (ngx_handoff_add_addrs(cf, mport, addr) != NGX_OK) { return NGX_CONF_ERROR; } break; } addr++; last--; } } return NGX_CONF_OK; }
// 对已经整理好的监听端口数组排序 // 调用ngx_create_listening添加到cycle的监听端口数组,只是添加,没有其他动作 // 设置有连接发生时的回调函数ngx_stream_init_connection static char * ngx_stream_optimize_servers(ngx_conf_t *cf, ngx_array_t *ports) { ngx_uint_t i, p, last, bind_wildcard; ngx_listening_t *ls; ngx_stream_port_t *stport; ngx_stream_conf_port_t *port; ngx_stream_conf_addr_t *addr; ngx_stream_core_srv_conf_t *cscf; // 遍历已经整理好的监听端口数组 // 由ngx_stream_add_ports添加 port = ports->elts; for (p = 0; p < ports->nelts; p++) { // port[p].addrs里存储的是监听相同端口的不同server{}的ngx_stream_listen_t // 根据wildcard、bind对server排序 ngx_sort(port[p].addrs.elts, (size_t) port[p].addrs.nelts, sizeof(ngx_stream_conf_addr_t), ngx_stream_cmp_conf_addrs); // addrs.elts里存储的是监听端口结构体ngx_stream_listen_t // addr 数组首地址, last 数组长度 addr = port[p].addrs.elts; last = port[p].addrs.nelts; /* * if there is the binding to the "*:port" then we need to bind() * to the "*:port" only and ignore the other bindings */ if (addr[last - 1].opt.wildcard) { addr[last - 1].opt.bind = 1; bind_wildcard = 1; } else { bind_wildcard = 0; } i = 0; while (i < last) { if (bind_wildcard && !addr[i].opt.bind) { i++; continue; } // 添加到cycle的监听端口数组,只是添加,没有其他动作 // 这里的ls是ngx_listening_t ls = ngx_create_listening(cf, &addr[i].opt.u.sockaddr, addr[i].opt.socklen); if (ls == NULL) { return NGX_CONF_ERROR; } // 设置监听端口的其他参数 ls->addr_ntop = 1; // 重要! // 设置有连接发生时的回调函数 ls->handler = ngx_stream_init_connection; // 设置连接的内存池是256bytes,不可配置 ls->pool_size = 256; // addr[i].opt就是ngx_stream_listen_t // 在ngx_stream_add_ports里添加 // addr->opt.ctx就是server的配置数组ngx_stream_conf_ctx_t // 这里没有使用addr[i].opt.ctx // 因为addr的前进与i++并不同步 // 获取此server配置数组里的cscf cscf = addr->opt.ctx->srv_conf[ngx_stream_core_module.ctx_index]; ls->logp = cscf->error_log; ls->log.data = &ls->addr_text; ls->log.handler = ngx_accept_log_error; // 端口的backlog ls->backlog = addr[i].opt.backlog; ls->keepalive = addr[i].opt.so_keepalive; #if (NGX_HAVE_KEEPALIVE_TUNABLE) ls->keepidle = addr[i].opt.tcp_keepidle; ls->keepintvl = addr[i].opt.tcp_keepintvl; ls->keepcnt = addr[i].opt.tcp_keepcnt; #endif #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) ls->ipv6only = addr[i].opt.ipv6only; #endif #if (NGX_HAVE_REUSEPORT) // 新的reuseport设置 ls->reuseport = addr[i].opt.reuseport; #endif // 存储本server信息 stport = ngx_palloc(cf->pool, sizeof(ngx_stream_port_t)); if (stport == NULL) { return NGX_CONF_ERROR; } ls->servers = stport; stport->naddrs = i + 1; switch (ls->sockaddr->sa_family) { #if (NGX_HAVE_INET6) case AF_INET6: if (ngx_stream_add_addrs6(cf, stport, addr) != NGX_OK) { return NGX_CONF_ERROR; } break; #endif default: /* AF_INET */ if (ngx_stream_add_addrs(cf, stport, addr) != NGX_OK) { return NGX_CONF_ERROR; } break; } // reuseport专用的函数,1.8.x没有 if (ngx_clone_listening(cf, ls) != NGX_OK) { return NGX_CONF_ERROR; } // 数组指针前进到下一个元素,即下一个server addr++; last--; } } return NGX_CONF_OK; }
static char * ngx_stream_optimize_servers(ngx_conf_t *cf, ngx_array_t *ports) { ngx_uint_t i, p, last, bind_wildcard; ngx_listening_t *ls; ngx_stream_port_t *stport; ngx_stream_conf_port_t *port; ngx_stream_conf_addr_t *addr; ngx_stream_core_srv_conf_t *cscf; port = ports->elts; for (p = 0; p < ports->nelts; p++) { ngx_sort(port[p].addrs.elts, (size_t) port[p].addrs.nelts, sizeof(ngx_stream_conf_addr_t), ngx_stream_cmp_conf_addrs); addr = port[p].addrs.elts; last = port[p].addrs.nelts; /* * if there is the binding to the "*:port" then we need to bind() * to the "*:port" only and ignore the other bindings */ if (addr[last - 1].opt.wildcard) { addr[last - 1].opt.bind = 1; bind_wildcard = 1; } else { bind_wildcard = 0; } i = 0; while (i < last) { if (bind_wildcard && !addr[i].opt.bind) { i++; continue; } ls = ngx_create_listening(cf, &addr[i].opt.sockaddr.sockaddr, addr[i].opt.socklen); if (ls == NULL) { return NGX_CONF_ERROR; } ls->addr_ntop = 1; ls->handler = ngx_stream_init_connection; ls->pool_size = 256; ls->type = addr[i].opt.type; cscf = addr->opt.ctx->srv_conf[ngx_stream_core_module.ctx_index]; ls->logp = cscf->error_log; ls->log.data = &ls->addr_text; ls->log.handler = ngx_accept_log_error; ls->backlog = addr[i].opt.backlog; ls->wildcard = addr[i].opt.wildcard; ls->keepalive = addr[i].opt.so_keepalive; #if (NGX_HAVE_KEEPALIVE_TUNABLE) ls->keepidle = addr[i].opt.tcp_keepidle; ls->keepintvl = addr[i].opt.tcp_keepintvl; ls->keepcnt = addr[i].opt.tcp_keepcnt; #endif #if (NGX_HAVE_INET6) ls->ipv6only = addr[i].opt.ipv6only; #endif #if (NGX_HAVE_REUSEPORT) ls->reuseport = addr[i].opt.reuseport; #endif stport = ngx_palloc(cf->pool, sizeof(ngx_stream_port_t)); if (stport == NULL) { return NGX_CONF_ERROR; } ls->servers = stport; stport->naddrs = i + 1; switch (ls->sockaddr->sa_family) { #if (NGX_HAVE_INET6) case AF_INET6: if (ngx_stream_add_addrs6(cf, stport, addr) != NGX_OK) { return NGX_CONF_ERROR; } break; #endif default: /* AF_INET */ if (ngx_stream_add_addrs(cf, stport, addr) != NGX_OK) { return NGX_CONF_ERROR; } break; } if (ngx_clone_listening(cf, ls) != NGX_OK) { return NGX_CONF_ERROR; } addr++; last--; } } return NGX_CONF_OK; }