static char * ngx_gateway_core_resolver(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_gateway_core_srv_conf_t *cscf = conf; #if defined(nginx_version) && nginx_version < 1001007 ngx_url_t u; #endif ngx_str_t *value; value = cf->args->elts; if (cscf->resolver != NGX_CONF_UNSET_PTR) { return “is duplicate”; } if (ngx_strcmp(value[1].data, "off") == 0) { cscf->resolver = NULL; return NGX_CONF_OK; } #if defined(nginx_version) && nginx_version < 1001007 ngx_memzero(&u, sizeof(ngx_url_t)); u.host = value[1]; u.port = 53; if (ngx_inet_resolve_host(cf->pool, &u) != NGX_OK) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%V: %s"), &u.host, u.err); return NGX_CONF_ERROR; }
static char * ngx_mail_core_resolver(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_mail_core_srv_conf_t *cscf = conf; ngx_url_t u; ngx_str_t *value; value = cf->args->elts; if (cscf->resolver != NGX_CONF_UNSET_PTR) { return "is duplicate"; } if (ngx_strcmp(value[1].data, "off") == 0) { cscf->resolver = NULL; return NGX_CONF_OK; } ngx_memzero(&u, sizeof(ngx_url_t)); u.host = value[1]; u.port = 53; if (ngx_inet_resolve_host(cf->pool, &u) != NGX_OK) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%V: %s", &u.host, u.err); return NGX_CONF_ERROR; } cscf->resolver = ngx_resolver_create(cf, &u.addrs[0]); if (cscf->resolver == NULL) { return NGX_CONF_OK; } return NGX_CONF_OK; }
ngx_int_t ngx_stream_upstream_init_round_robin(ngx_conf_t *cf, ngx_stream_upstream_srv_conf_t *us) { ngx_url_t u; ngx_uint_t i, j, n, w; ngx_stream_upstream_server_t *server; ngx_stream_upstream_rr_peer_t *peer, **peerp; ngx_stream_upstream_rr_peers_t *peers, *backup; us->peer.init = ngx_stream_upstream_init_round_robin_peer; if (us->servers) { server = us->servers->elts; n = 0; w = 0; for (i = 0; i < us->servers->nelts; i++) { if (server[i].backup) { continue; } n += server[i].naddrs; w += server[i].naddrs * server[i].weight; } if (n == 0) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no servers in upstream \"%V\" in %s:%ui", &us->host, us->file_name, us->line); return NGX_ERROR; } peers = ngx_pcalloc(cf->pool, sizeof(ngx_stream_upstream_rr_peers_t)); if (peers == NULL) { return NGX_ERROR; } peer = ngx_pcalloc(cf->pool, sizeof(ngx_stream_upstream_rr_peer_t) * n); if (peer == NULL) { return NGX_ERROR; } peers->single = (n == 1); peers->number = n; peers->weighted = (w != n); peers->total_weight = w; peers->name = &us->host; n = 0; peerp = &peers->peer; for (i = 0; i < us->servers->nelts; i++) { if (server[i].backup) { continue; } for (j = 0; j < server[i].naddrs; j++) { peer[n].sockaddr = server[i].addrs[j].sockaddr; peer[n].socklen = server[i].addrs[j].socklen; peer[n].name = server[i].addrs[j].name; peer[n].weight = server[i].weight; peer[n].effective_weight = server[i].weight; peer[n].current_weight = 0; peer[n].max_fails = server[i].max_fails; peer[n].fail_timeout = server[i].fail_timeout; peer[n].down = server[i].down; peer[n].server = server[i].name; *peerp = &peer[n]; peerp = &peer[n].next; n++; } } us->peer.data = peers; /* backup servers */ n = 0; w = 0; for (i = 0; i < us->servers->nelts; i++) { if (!server[i].backup) { continue; } n += server[i].naddrs; w += server[i].naddrs * server[i].weight; } if (n == 0) { return NGX_OK; } backup = ngx_pcalloc(cf->pool, sizeof(ngx_stream_upstream_rr_peers_t)); if (backup == NULL) { return NGX_ERROR; } peer = ngx_pcalloc(cf->pool, sizeof(ngx_stream_upstream_rr_peer_t) * n); if (peer == NULL) { return NGX_ERROR; } peers->single = 0; backup->single = 0; backup->number = n; backup->weighted = (w != n); backup->total_weight = w; backup->name = &us->host; n = 0; peerp = &backup->peer; for (i = 0; i < us->servers->nelts; i++) { if (!server[i].backup) { continue; } for (j = 0; j < server[i].naddrs; j++) { peer[n].sockaddr = server[i].addrs[j].sockaddr; peer[n].socklen = server[i].addrs[j].socklen; peer[n].name = server[i].addrs[j].name; peer[n].weight = server[i].weight; peer[n].effective_weight = server[i].weight; peer[n].current_weight = 0; peer[n].max_fails = server[i].max_fails; peer[n].fail_timeout = server[i].fail_timeout; peer[n].down = server[i].down; peer[n].server = server[i].name; *peerp = &peer[n]; peerp = &peer[n].next; n++; } } peers->next = backup; return NGX_OK; } /* an upstream implicitly defined by proxy_pass, etc. */ if (us->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 = us->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_stream_upstream_rr_peers_t)); if (peers == NULL) { return NGX_ERROR; } peer = ngx_pcalloc(cf->pool, sizeof(ngx_stream_upstream_rr_peer_t) * n); if (peer == NULL) { return NGX_ERROR; } peers->single = (n == 1); peers->number = n; peers->weighted = 0; peers->total_weight = n; peers->name = &us->host; peerp = &peers->peer; for (i = 0; i < u.naddrs; i++) { peer[i].sockaddr = u.addrs[i].sockaddr; peer[i].socklen = u.addrs[i].socklen; peer[i].name = u.addrs[i].name; peer[i].weight = 1; peer[i].effective_weight = 1; peer[i].current_weight = 0; peer[i].max_fails = 1; peer[i].fail_timeout = 10; *peerp = &peer[i]; peerp = &peer[i].next; } us->peer.data = peers; /* implicitly defined upstream has no backup servers */ 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_event_debug_connection(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { #if (NGX_DEBUG) ngx_event_conf_t *ecf = conf; ngx_int_t rc; ngx_str_t *value; ngx_url_t u; ngx_cidr_t c, *cidr; ngx_uint_t i; struct sockaddr_in *sin; #if (NGX_HAVE_INET6) struct sockaddr_in6 *sin6; #endif value = cf->args->elts; #if (NGX_HAVE_UNIX_DOMAIN) if (ngx_strcmp(value[1].data, "unix:") == 0) { cidr = ngx_array_push(&ecf->debug_connection); if (cidr == NULL) { return NGX_CONF_ERROR; } cidr->family = AF_UNIX; return NGX_CONF_OK; } #endif rc = ngx_ptocidr(&value[1], &c); if (rc != NGX_ERROR) { if (rc == NGX_DONE) { ngx_conf_log_error(NGX_LOG_WARN, cf, 0, "low address bits of %V are meaningless", &value[1]); } cidr = ngx_array_push(&ecf->debug_connection); if (cidr == NULL) { return NGX_CONF_ERROR; } *cidr = c; return NGX_CONF_OK; } ngx_memzero(&u, sizeof(ngx_url_t)); u.host = value[1]; if (ngx_inet_resolve_host(cf->pool, &u) != NGX_OK) { if (u.err) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s in debug_connection \"%V\"", u.err, &u.host); } return NGX_CONF_ERROR; } cidr = ngx_array_push_n(&ecf->debug_connection, u.naddrs); if (cidr == NULL) { return NGX_CONF_ERROR; } ngx_memzero(cidr, u.naddrs * sizeof(ngx_cidr_t)); for (i = 0; i < u.naddrs; i++) { cidr[i].family = u.addrs[i].sockaddr->sa_family; switch (cidr[i].family) { #if (NGX_HAVE_INET6) case AF_INET6: sin6 = (struct sockaddr_in6 *) u.addrs[i].sockaddr; cidr[i].u.in6.addr = sin6->sin6_addr; ngx_memset(cidr[i].u.in6.mask.s6_addr, 0xff, 16); break; #endif default: /* AF_INET */ sin = (struct sockaddr_in *) u.addrs[i].sockaddr; cidr[i].u.in.addr = sin->sin_addr.s_addr; cidr[i].u.in.mask = 0xffffffff; break; } } #else ngx_conf_log_error(NGX_LOG_WARN, cf, 0, "\"debug_connection\" is ignored, you need to rebuild " "nginx using --with-debug option to enable it"); #endif return NGX_CONF_OK; }
ngx_resolver_t * ngx_resolver_create(ngx_conf_t *cf, ngx_str_t *names, ngx_uint_t n) { ngx_str_t s; ngx_url_t u; ngx_uint_t i; ngx_resolver_t *r; ngx_pool_cleanup_t *cln; ngx_udp_connection_t *uc; cln = ngx_pool_cleanup_add(cf->pool, 0); if (cln == NULL) { return NULL; } cln->handler = ngx_resolver_cleanup; r = ngx_calloc(sizeof(ngx_resolver_t), cf->log); if (r == NULL) { return NULL; } if (n) { if (ngx_array_init(&r->udp_connections, cf->pool, n, sizeof(ngx_udp_connection_t)) != NGX_OK) { return NULL; } } cln->data = r; r->event = ngx_calloc(sizeof(ngx_event_t), cf->log); if (r->event == NULL) { return NULL; } ngx_rbtree_init(&r->name_rbtree, &r->name_sentinel, ngx_resolver_rbtree_insert_value); ngx_rbtree_init(&r->addr_rbtree, &r->addr_sentinel, ngx_rbtree_insert_value); ngx_queue_init(&r->name_resend_queue); ngx_queue_init(&r->addr_resend_queue); ngx_queue_init(&r->name_expire_queue); ngx_queue_init(&r->addr_expire_queue); r->event->handler = ngx_resolver_resend_handler; r->event->data = r; r->event->log = &cf->cycle->new_log; r->ident = -1; r->resend_timeout = 5; r->expire = 30; r->valid = 0; r->log = &cf->cycle->new_log; r->log_level = NGX_LOG_ERR; for (i = 0; i < n; i++) { if (ngx_strncmp(names[i].data, "valid=", 6) == 0) { s.len = names[i].len - 6; s.data = names[i].data + 6; r->valid = ngx_parse_time(&s, 1); if (r->valid == NGX_ERROR) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter: %V", &names[i]); return NULL; } continue; } ngx_memzero(&u, sizeof(ngx_url_t)); u.host = names[i]; u.port = 53; if (ngx_inet_resolve_host(cf->pool, &u) != NGX_OK) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%V: %s", &u.host, u.err); return NULL; } uc = ngx_array_push(&r->udp_connections); if (uc == NULL) { return NULL; } ngx_memzero(uc, sizeof(ngx_udp_connection_t)); uc->sockaddr = u.addrs->sockaddr; uc->socklen = u.addrs->socklen; uc->server = u.addrs->name; uc->log = cf->cycle->new_log; uc->log.handler = ngx_resolver_log_error; uc->log.data = uc; uc->log.action = "resolving"; } return r; }
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, w, color; ngx_uint_t dyn_resolve = 0; ngx_http_upstream_server_t *server; ngx_http_upstream_rr_peers_t *peers, *backup; u_char addr6[NGX_INET6_ADDRSTRLEN]; us->peer.init = ngx_http_upstream_init_round_robin_peer; if (us->servers) { server = us->servers->elts; n = 0; w = 0; for (i = 0; i < us->servers->nelts; i++) { if (server[i].backup) { continue; } n += server[i].naddrs; w += server[i].naddrs * server[i].weight; } if (n == 0) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no servers in upstream \"%V\" in %s:%ui", &us->host, us->file_name, us->line); return NGX_ERROR; } 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->weighted = (w != n); peers->total_weight = w; peers->name = &us->host; n = 0; color = 1; for (i = 0; i < us->servers->nelts; i++) { if (server[i].backup) { continue; } #if (NGX_HAVE_INET6) dyn_resolve = (ngx_inet6_addr(server[i].host.data, server[i].host.len, addr6) == NGX_ERROR) ? 1 : 0; if (dyn_resolve) /* host is not an ipv6 address, check ipv4 */ #endif { dyn_resolve = (ngx_inet_addr(server[i].host.data, server[i].host.len) == INADDR_NONE) ? 1 : 0; } for (j = 0; j < server[i].naddrs; j++) { 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].host = server[i].host; peers->peer[n].weight = server[i].weight; peers->peer[n].effective_weight = server[i].weight; peers->peer[n].current_weight = 0; 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].color = color; peers->peer[n].dyn_resolve = dyn_resolve; #if (NGX_HTTP_UPSTREAM_CHECK) if (!server[i].down) { peers->peer[n].check_index = ngx_http_upstream_check_add_peer(cf, us, &server[i].addrs[j]); } else { peers->peer[n].check_index = (ngx_uint_t) NGX_ERROR; } #endif n++; } color++; } us->peer.data = peers; /* backup servers */ n = 0; w = 0; for (i = 0; i < us->servers->nelts; i++) { if (!server[i].backup) { continue; } n += server[i].naddrs; w += server[i].naddrs * server[i].weight; } 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->weighted = (w != n); backup->total_weight = w; backup->name = &us->host; n = 0; for (i = 0; i < us->servers->nelts; i++) { if (!server[i].backup) { continue; } #if (NGX_HAVE_INET6) dyn_resolve = (ngx_inet6_addr(server[i].host.data, server[i].host.len, addr6) == NGX_ERROR) ? 1 : 0; if (dyn_resolve) /* host is not an ipv6 address, check ipv4 */ #endif { dyn_resolve = (ngx_inet_addr(server[i].host.data, server[i].host.len) == INADDR_NONE) ? 1 : 0; } for (j = 0; j < server[i].naddrs; j++) { 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].host = server[i].host; backup->peer[n].weight = server[i].weight; backup->peer[n].effective_weight = server[i].weight; backup->peer[n].current_weight = 0; 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; backup->peer[n].color = color; backup->peer[n].dyn_resolve = dyn_resolve; #if (NGX_HTTP_UPSTREAM_CHECK) if (!server[i].down) { backup->peer[n].check_index = ngx_http_upstream_check_add_peer(cf, us, &server[i].addrs[j]); } else { backup->peer[n].check_index = (ngx_uint_t) NGX_ERROR; } #endif n++; } color++; } peers->next = backup; return NGX_OK; } /* an upstream implicitly defined by proxy_pass, etc. */ if (us->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 = us->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->weighted = 0; peers->total_weight = n; peers->name = &us->host; #if (NGX_HAVE_INET6) dyn_resolve = (ngx_inet6_addr(u.host.data, u.host.len, addr6) == NGX_ERROR) ? 1 : 0; if (dyn_resolve) /* host is not an ipv6 address, check ipv4 */ #endif { dyn_resolve = (ngx_inet_addr(u.host.data, u.host.len) == INADDR_NONE) ? 1 : 0; } 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].host = u.host; peers->peer[i].weight = 1; peers->peer[i].effective_weight = 1; peers->peer[i].current_weight = 0; peers->peer[i].max_fails = 1; peers->peer[i].fail_timeout = 10; #if (NGX_HTTP_UPSTREAM_CHECK) peers->peer[i].check_index = (ngx_uint_t) NGX_ERROR; #endif peers->peer[i].color = 0; peers->peer[i].dyn_resolve = dyn_resolve; } us->peer.data = peers; /* implicitly defined upstream has no backup servers */ return NGX_OK; }