static char * ngx_http_tfs_rcs_interface(ngx_conf_t *cf, ngx_http_tfs_upstream_t *tu) { ngx_int_t rc; ngx_str_t *value; if (cf->args->nelts != 2) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid number of arguments in " "\"rcs_interface\" directive"); return NGX_CONF_ERROR; } value = cf->args->elts; rc = ngx_http_tfs_get_local_ip(value[1], &tu->local_addr); if (rc == NGX_ERROR) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "device is invalid(%V)", &value[1]); return NGX_CONF_ERROR; } ngx_inet_ntop(AF_INET, &tu->local_addr.sin_addr, tu->local_addr_text, NGX_INET_ADDRSTRLEN); return NGX_CONF_OK; }
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 *addr_in; if (!(ls = ngx_array_push(&cf->cycle->listening))) { return NULL; } ngx_memzero(ls, sizeof(ngx_listening_t)); if (!(addr_in = ngx_pcalloc(cf->pool, sizeof(struct sockaddr_in)))) { return NULL; } #if (HAVE_SIN_LEN) addr_in->sin_len = sizeof(struct sockaddr_in); #endif addr_in->sin_family = AF_INET; addr_in->sin_addr.s_addr = addr; addr_in->sin_port = htons(port); if (!(ls->addr_text.data = ngx_palloc(cf->pool, INET_ADDRSTRLEN + 6))) { return NULL; } len = ngx_inet_ntop(AF_INET, &addr, ls->addr_text.data, INET_ADDRSTRLEN); ls->addr_text.len = ngx_snprintf((char *) ls->addr_text.data + len, 6, ":%d", port); ls->fd = (ngx_socket_t) -1; ls->family = AF_INET; ls->type = SOCK_STREAM; ls->protocol = IPPROTO_IP; #if (WIN32) ls->flags = WSA_FLAG_OVERLAPPED; #endif ls->sockaddr = (struct sockaddr *) addr_in; ls->socklen = sizeof(struct sockaddr_in); ls->addr = offsetof(struct sockaddr_in, sin_addr); ls->addr_text_max_len = INET_ADDRSTRLEN; return ls; }
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_pnalloc(cf->pool, NGX_INET_ADDRSTRLEN + sizeof(":65535") - 1); if (ls->addr_text.data == NULL) { return NULL; } len = ngx_inet_ntop(AF_INET, &addr, ls->addr_text.data, NGX_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->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 = NGX_INET_ADDRSTRLEN; return ls; }
static char * ngx_http_tfs_net_device(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_http_tfs_srv_conf_t *tscf = conf; ngx_int_t rc; ngx_str_t *value; value = cf->args->elts; rc = ngx_http_tfs_get_local_ip(value[1], &tscf->local_addr); if (rc == NGX_ERROR) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "device is invalid(%V)", &value[1]); return NGX_CONF_ERROR; } ngx_inet_ntop(AF_INET, &tscf->local_addr.sin_addr, tscf->local_addr_text, NGX_INET_ADDRSTRLEN); return NGX_CONF_OK; }
static int ngx_lua_http_btt_announce(lua_State *l) { size_t size; u_char *p, *last, *buf, ip[NGX_INET_ADDRSTRLEN]; uint32_t n; ngx_int_t rc; ngx_btt_ctx_t *ctx; ngx_btt_conf_t *bcf; ngx_lua_thread_t *thr; ngx_lua_http_ctx_t *hctx; ngx_http_request_t *r; ngx_btt_peer_info_t *pi; thr = ngx_lua_thread(l); ngx_log_debug0(NGX_LOG_DEBUG_HTTP, thr->log, 0, "lua http btt announce"); ctx = ngx_pcalloc(thr->pool, sizeof(ngx_btt_ctx_t)); if (ctx == NULL) { lua_pushboolean(l, 0); return 1; } ctx->pool = thr->pool; ctx->log = thr->log; hctx = thr->module_ctx; r = hctx->r; if (ngx_lua_http_btt_parse_args(r, ctx) != NGX_OK) { lua_pushboolean(l, 0); return 1; } /* Checking the value of the uri arguments */ if (ngx_lua_http_btt_check_args(r, ctx) != NGX_OK) { lua_pushboolean(l, 0); return 1; } bcf = (ngx_btt_conf_t *) ngx_get_conf(ngx_cycle->conf_ctx, ngx_lua_btt_module); /* Insert or update peer information in peer list */ /* TODO: Checking ctx->event */ rc = ngx_btt_update_peer(bcf, ctx); if (rc != NGX_OK) { lua_pushboolean(l, 0); return 1; } /* Querying the peer list */ if (ctx->event != NGX_BTT_EVENT_STOPPED) { ctx->peers = ngx_palloc(thr->pool, sizeof(ngx_btt_peer_info_t) * ctx->numwant); if (ctx->peers == NULL) { lua_pushboolean(l, 0); return 1; } rc = ngx_btt_query_peers(bcf, ctx); if (rc != NGX_OK) { lua_pushboolean(l, 0); return 1; } } /* Calculating the size of the response */ /* TODO: * * 8:completei2e * 10:downloadedi4e * 10:incompletei1e * * 12:min intervali811e */ size = sizeof("d8:intervalie5:peerse") - 1 + NGX_TIME_T_LEN; if (ctx->compact) { size += NGX_INT_T_LEN + 1 + 6 * ctx->peers_n; } else { size += sizeof("le") - 1; if (!ctx->no_peer_id) { size += (sizeof("7:peer_id20:") - 1 + 20) * ctx->peers_n; } size += (sizeof("d2:ip4:portiee") - 1 + NGX_INT_T_LEN + 1 + NGX_INET_ADDRSTRLEN + NGX_INT_T_LEN) * ctx->peers_n; } buf = ngx_palloc(thr->pool, size); if (buf == NULL) { lua_pushboolean(l, 0); return 1; } p = buf; last = p + size; /* Building the response */ p = ngx_slprintf(p, last, "d8:intervali%Te5:peers", bcf->interval); if (ctx->compact) { p = ngx_slprintf(p, last, "%uz:", 6 * ctx->peers_n); } else { *p++ = 'l'; } for (n = 0; n < ctx->peers_n; n++) { pi = &ctx->peers[n]; if (ctx->compact) { p = ngx_cpymem(p, &pi->external_ip, sizeof(pi->external_ip)); pi->internal_port = htons(pi->internal_port); p = ngx_cpymem(p, &pi->internal_port, sizeof(pi->internal_port)); } else { *p++ = 'd'; if (!ctx->no_peer_id) { p = ngx_slprintf(p, last, "7:peer_id20:%*s", sizeof(pi->peer_id), pi->peer_id); } size = ngx_inet_ntop(AF_INET, &pi->external_ip, ip, sizeof(ip)); p = ngx_slprintf(p, last, "2:ip%uz:%*s4:porti%uDe", size, size, ip, (uint32_t) pi->internal_port); *p++ = 'e'; } } if (!ctx->compact) { *p++ = 'e'; } *p++ = 'e'; ngx_lua_output(thr, buf, p - buf); ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "lua http btt announce response:%N%*s", p - buf, buf); lua_pushboolean(l, 1); return 1; }
ngx_int_t ngx_http_upstream_create_round_robin_peer(ngx_http_request_t *r, ngx_http_upstream_resolved_t *ur) { u_char *p; size_t len; ngx_uint_t i, n; struct sockaddr_in *sin; ngx_http_upstream_rr_peers_t *peers; ngx_http_upstream_rr_peer_data_t *rrp; rrp = r->upstream->peer.data; if (rrp == NULL) { rrp = ngx_palloc(r->pool, sizeof(ngx_http_upstream_rr_peer_data_t)); if (rrp == NULL) { return NGX_ERROR; } r->upstream->peer.data = rrp; } peers = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_rr_peers_t) + sizeof(ngx_http_upstream_rr_peer_t) * (ur->naddrs - 1)); if (peers == NULL) { return NGX_ERROR; } peers->single = (ur->naddrs == 1); peers->number = ur->naddrs; peers->name = &ur->host; if (ur->sockaddr) { peers->peer[0].sockaddr = ur->sockaddr; peers->peer[0].socklen = ur->socklen; peers->peer[0].name = ur->host; peers->peer[0].weight = 1; peers->peer[0].current_weight = 1; peers->peer[0].max_fails = 1; peers->peer[0].fail_timeout = 10; } else { for (i = 0; i < ur->naddrs; i++) { len = NGX_INET_ADDRSTRLEN + sizeof(":65536") - 1; p = ngx_pnalloc(r->pool, len); if (p == NULL) { return NGX_ERROR; } len = ngx_inet_ntop(AF_INET, &ur->addrs[i], p, NGX_INET_ADDRSTRLEN); len = ngx_sprintf(&p[len], ":%d", ur->port) - p; sin = ngx_pcalloc(r->pool, sizeof(struct sockaddr_in)); if (sin == NULL) { return NGX_ERROR; } sin->sin_family = AF_INET; sin->sin_port = htons(ur->port); sin->sin_addr.s_addr = ur->addrs[i]; peers->peer[i].sockaddr = (struct sockaddr *) sin; peers->peer[i].socklen = sizeof(struct sockaddr_in); peers->peer[i].name.len = len; peers->peer[i].name.data = p; peers->peer[i].weight = 1; peers->peer[i].current_weight = 1; peers->peer[i].max_fails = 1; peers->peer[i].fail_timeout = 10; } } rrp->peers = peers; rrp->current = 0; if (rrp->peers->number <= 8 * sizeof(uintptr_t)) { rrp->tried = &rrp->data; rrp->data = 0; } else { n = (rrp->peers->number + (8 * sizeof(uintptr_t) - 1)) / (8 * sizeof(uintptr_t)); rrp->tried = ngx_pcalloc(r->pool, n * sizeof(uintptr_t)); if (rrp->tried == NULL) { return NGX_ERROR; } } r->upstream->peer.get = ngx_http_upstream_get_round_robin_peer; r->upstream->peer.free = ngx_http_upstream_free_round_robin_peer; r->upstream->peer.tries = rrp->peers->number; #if (NGX_HTTP_SSL) r->upstream->peer.set_session = ngx_http_upstream_empty_set_session; r->upstream->peer.save_session = ngx_http_upstream_empty_save_session; #endif return NGX_OK; }
static void ngx_http_lua_socket_resolve_handler(ngx_resolver_ctx_t *ctx) { ngx_http_request_t *r; ngx_connection_t *c; ngx_http_upstream_resolved_t *ur; ngx_http_lua_ctx_t *lctx; lua_State *L; ngx_http_lua_socket_udp_upstream_t *u; u_char *p; size_t len; struct sockaddr_in *sin; ngx_uint_t i; unsigned waiting; u = ctx->data; r = u->request; c = r->connection; ur = u->resolved; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "lua udp socket resolve handler"); lctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); if (lctx == NULL) { return; } lctx->cur_co_ctx = u->co_ctx; u->co_ctx->cleanup = NULL; L = lctx->cur_co_ctx->co; dd("setting socket_ready to 1"); waiting = u->waiting; if (ctx->state) { ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, "lua udp socket resolver error: %s (waiting: %d)", ngx_resolver_strerror(ctx->state), (int) u->waiting); lua_pushnil(L); lua_pushlstring(L, (char *) ctx->name.data, ctx->name.len); lua_pushfstring(L, " could not be resolved (%d: %s)", (int) ctx->state, ngx_resolver_strerror(ctx->state)); lua_concat(L, 2); u->prepare_retvals = ngx_http_lua_socket_error_retval_handler; ngx_http_lua_socket_udp_handle_error(r, u, NGX_HTTP_LUA_SOCKET_FT_RESOLVER); if (waiting) { ngx_http_run_posted_requests(c); } return; } ur->naddrs = ctx->naddrs; ur->addrs = ctx->addrs; #if (NGX_DEBUG) { in_addr_t addr; ngx_uint_t i; for (i = 0; i < ctx->naddrs; i++) { dd("addr i: %d %p", (int) i, &ctx->addrs[i]); addr = ntohl(ctx->addrs[i]); ngx_log_debug4(NGX_LOG_DEBUG_HTTP, c->log, 0, "name was resolved to %ud.%ud.%ud.%ud", (addr >> 24) & 0xff, (addr >> 16) & 0xff, (addr >> 8) & 0xff, addr & 0xff); } } #endif if (ur->naddrs == 0) { ngx_resolve_name_done(ctx); u->ft_type |= NGX_HTTP_LUA_SOCKET_FT_RESOLVER; lua_pushnil(L); lua_pushliteral(L, "name cannot be resolved to a address"); if (waiting) { ngx_http_run_posted_requests(c); } return; } if (ur->naddrs == 1) { i = 0; } else { i = ngx_random() % ur->naddrs; } dd("selected addr index: %d", (int) i); len = NGX_INET_ADDRSTRLEN + sizeof(":65536") - 1; p = ngx_pnalloc(r->pool, len + sizeof(struct sockaddr_in)); if (p == NULL) { ngx_resolve_name_done(ctx); u->ft_type |= NGX_HTTP_LUA_SOCKET_FT_RESOLVER; lua_pushnil(L); lua_pushliteral(L, "out of memory"); if (waiting) { ngx_http_run_posted_requests(c); } return; } sin = (struct sockaddr_in *) &p[len]; ngx_memzero(sin, sizeof(struct sockaddr_in)); len = ngx_inet_ntop(AF_INET, &ur->addrs[i], p, NGX_INET_ADDRSTRLEN); len = ngx_sprintf(&p[len], ":%d", ur->port) - p; sin->sin_family = AF_INET; sin->sin_port = htons(ur->port); sin->sin_addr.s_addr = ur->addrs[i]; ur->sockaddr = (struct sockaddr *) sin; ur->socklen = sizeof(struct sockaddr_in); ur->host.data = p; ur->host.len = len; ur->naddrs = 1; ur->ctx = NULL; ngx_resolve_name_done(ctx); u->waiting = 0; if (waiting) { lctx->resume_handler = ngx_http_lua_socket_udp_resume; r->write_event_handler(r); ngx_http_run_posted_requests(c); } else { (void) ngx_http_lua_socket_resolve_retval_handler(r, u, L); } }
static void ngx_http_lua_socket_resolve_handler(ngx_resolver_ctx_t *ctx) { ngx_http_request_t *r; ngx_connection_t *c; ngx_http_upstream_resolved_t *ur; ngx_http_lua_ctx_t *lctx; lua_State *L; ngx_http_lua_socket_udp_upstream_t *u; u_char *p; size_t len; #if defined(nginx_version) && nginx_version >= 1005008 socklen_t socklen; struct sockaddr *sockaddr; #else struct sockaddr_in *sin; #endif ngx_uint_t i; unsigned waiting; u = ctx->data; r = u->request; c = r->connection; ur = u->resolved; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "lua udp socket resolve handler"); lctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); if (lctx == NULL) { return; } lctx->cur_co_ctx = u->co_ctx; u->co_ctx->cleanup = NULL; L = lctx->cur_co_ctx->co; dd("setting socket_ready to 1"); waiting = u->waiting; if (ctx->state) { ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, "lua udp socket resolver error: %s (waiting: %d)", ngx_resolver_strerror(ctx->state), (int) u->waiting); lua_pushnil(L); lua_pushlstring(L, (char *) ctx->name.data, ctx->name.len); lua_pushfstring(L, " could not be resolved (%d: %s)", (int) ctx->state, ngx_resolver_strerror(ctx->state)); lua_concat(L, 2); #if 1 ngx_resolve_name_done(ctx); ur->ctx = NULL; #endif u->prepare_retvals = ngx_http_lua_socket_error_retval_handler; ngx_http_lua_socket_udp_handle_error(r, u, NGX_HTTP_LUA_SOCKET_FT_RESOLVER); if (waiting) { ngx_http_run_posted_requests(c); } return; } ur->naddrs = ctx->naddrs; ur->addrs = ctx->addrs; #if (NGX_DEBUG) { # if defined(nginx_version) && nginx_version >= 1005008 u_char text[NGX_SOCKADDR_STRLEN]; ngx_str_t addr; # else in_addr_t addr; # endif ngx_uint_t i; # if defined(nginx_version) && nginx_version >= 1005008 addr.data = text; for (i = 0; i < ctx->naddrs; i++) { addr.len = ngx_sock_ntop(ur->addrs[i].sockaddr, ur->addrs[i].socklen, text, NGX_SOCKADDR_STRLEN, 0); ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "name was resolved to %V", &addr); } # else for (i = 0; i < ctx->naddrs; i++) { dd("addr i: %d %p", (int) i, &ctx->addrs[i]); addr = ntohl(ctx->addrs[i]); ngx_log_debug4(NGX_LOG_DEBUG_HTTP, c->log, 0, "name was resolved to %ud.%ud.%ud.%ud", (addr >> 24) & 0xff, (addr >> 16) & 0xff, (addr >> 8) & 0xff, addr & 0xff); } # endif } #endif ngx_http_lua_assert(ur->naddrs > 0); if (ur->naddrs == 1) { i = 0; } else { i = ngx_random() % ur->naddrs; } dd("selected addr index: %d", (int) i); #if defined(nginx_version) && nginx_version >= 1005008 socklen = ur->addrs[i].socklen; sockaddr = ngx_palloc(r->pool, socklen); if (sockaddr == NULL) { goto nomem; } ngx_memcpy(sockaddr, ur->addrs[i].sockaddr, socklen); switch (sockaddr->sa_family) { #if (NGX_HAVE_INET6) case AF_INET6: ((struct sockaddr_in6 *) sockaddr)->sin6_port = htons(ur->port); break; #endif default: /* AF_INET */ ((struct sockaddr_in *) sockaddr)->sin_port = htons(ur->port); } p = ngx_pnalloc(r->pool, NGX_SOCKADDR_STRLEN); if (p == NULL) { goto nomem; } len = ngx_sock_ntop(sockaddr, socklen, p, NGX_SOCKADDR_STRLEN, 1); ur->sockaddr = sockaddr; ur->socklen = socklen; #else /* for nginx older than 1.5.8 */ len = NGX_INET_ADDRSTRLEN + sizeof(":65536") - 1; p = ngx_pnalloc(r->pool, len + sizeof(struct sockaddr_in)); if (p == NULL) { goto nomem; } sin = (struct sockaddr_in *) &p[len]; ngx_memzero(sin, sizeof(struct sockaddr_in)); len = ngx_inet_ntop(AF_INET, &ur->addrs[i], p, NGX_INET_ADDRSTRLEN); len = ngx_sprintf(&p[len], ":%d", ur->port) - p; sin->sin_family = AF_INET; sin->sin_port = htons(ur->port); sin->sin_addr.s_addr = ur->addrs[i]; ur->sockaddr = (struct sockaddr *) sin; ur->socklen = sizeof(struct sockaddr_in); #endif ur->host.data = p; ur->host.len = len; ur->naddrs = 1; ngx_resolve_name_done(ctx); ur->ctx = NULL; u->waiting = 0; if (waiting) { lctx->resume_handler = ngx_http_lua_socket_udp_resume; r->write_event_handler(r); ngx_http_run_posted_requests(c); } else { (void) ngx_http_lua_socket_resolve_retval_handler(r, u, L); } return; nomem: if (ur->ctx) { ngx_resolve_name_done(ctx); ur->ctx = NULL; } u->prepare_retvals = ngx_http_lua_socket_error_retval_handler; ngx_http_lua_socket_udp_handle_error(r, u, NGX_HTTP_LUA_SOCKET_FT_NOMEM); if (waiting) { ngx_http_run_posted_requests(c); } else { lua_pushnil(L); lua_pushliteral(L, "no memory"); } }
static void ngx_http_upstream_dynamic_handler(ngx_resolver_ctx_t *ctx) { ngx_http_request_t *r; ngx_http_upstream_t *u; ngx_peer_connection_t *pc; struct sockaddr_in *sin, *csin; in_port_t port; ngx_str_t *addr; u_char *p; size_t len; ngx_http_upstream_srv_conf_t *us; ngx_http_upstream_dynamic_srv_conf_t *dscf; r = ctx->data; u = r->upstream; us = u->conf->upstream; pc = &u->peer; dscf = ngx_http_conf_upstream_srv_conf(us, ngx_http_upstream_dynamic_module); if (ctx->state) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "%V could not be resolved (%i: %s)", &ctx->name, ctx->state, ngx_resolver_strerror(ctx->state)); dscf->fail_check = ngx_time(); pc->resolved = NGX_HTTP_UPSTREAM_DR_FAILED; } else { /* dns query ok */ dscf->fail_check = 0; sin = ngx_pcalloc(r->pool, sizeof(struct sockaddr_in)); if (sin == NULL) { ngx_http_upstream_finalize_request(r, u, NGX_HTTP_INTERNAL_SERVER_ERROR); return; } ngx_memcpy(sin, pc->sockaddr, pc->socklen); /* only the first IP addr is used in version 1 */ csin = (struct sockaddr_in *) ctx->addrs[0].sockaddr; if (sin->sin_addr.s_addr == csin->sin_addr.s_addr) { pc->resolved = NGX_HTTP_UPSTREAM_DR_OK; goto out; } sin->sin_addr.s_addr = csin->sin_addr.s_addr; len = NGX_INET_ADDRSTRLEN + sizeof(":65535") - 1; p = ngx_pnalloc(r->pool, len); if (p == NULL) { ngx_http_upstream_finalize_request(r, u, NGX_HTTP_INTERNAL_SERVER_ERROR); return; } port = ntohs(sin->sin_port); len = ngx_inet_ntop(AF_INET, &sin->sin_addr.s_addr, p, NGX_INET_ADDRSTRLEN); len = ngx_sprintf(&p[len], ":%d", port) - p; addr = ngx_palloc(r->pool, sizeof(ngx_str_t)); if (addr == NULL) { ngx_http_upstream_finalize_request(r, u, NGX_HTTP_INTERNAL_SERVER_ERROR); return; } addr->data = p; addr->len = len; pc->sockaddr = (struct sockaddr *) sin; pc->socklen = sizeof(struct sockaddr_in); pc->name = addr; ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "name was resolved to %V", pc->name); pc->resolved = NGX_HTTP_UPSTREAM_DR_OK; } out: ngx_resolve_name_done(ctx); u->dyn_resolve_ctx = NULL; ngx_http_upstream_connect(r, u); }
static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { char *rv; ngx_uint_t mi, m, s, l, p, a, n; ngx_uint_t port_found, addr_found, virtual_names; ngx_conf_t pcf; ngx_array_t in_ports; ngx_listening_t *ls; ngx_http_listen_t *lscf; ngx_http_module_t *module; ngx_http_handler_pt *h; ngx_http_conf_ctx_t *ctx; ngx_http_in_port_t *in_port, *inport; ngx_http_in_addr_t *in_addr, *inaddr; ngx_http_server_name_t *s_name, *name; ngx_http_core_srv_conf_t **cscfp, *cscf; ngx_http_core_loc_conf_t *clcf; ngx_http_core_main_conf_t *cmcf; #if (WIN32) ngx_iocp_conf_t *iocpcf; #endif /* the main http context */ ngx_test_null(ctx, ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)), NGX_CONF_ERROR); *(ngx_http_conf_ctx_t **) conf = ctx; // 把新创建的配置上下文挂钩起来 /* count the number of the http modules and set up their indices */ ngx_http_max_module = 0; for (m = 0; ngx_modules[m]; m++) { if (ngx_modules[m]->type != NGX_HTTP_MODULE) { continue; } ngx_modules[m]->ctx_index = ngx_http_max_module++; } /* the main http main_conf, it's the same in the all http contexts */ ngx_test_null(ctx->main_conf, ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module), NGX_CONF_ERROR); /* the http null srv_conf, it's used to merge the server{}s' srv_conf's */ ngx_test_null(ctx->srv_conf, ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module), NGX_CONF_ERROR); /* the http null loc_conf, it's used to merge the server{}s' loc_conf's */ ngx_test_null(ctx->loc_conf, ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module), NGX_CONF_ERROR); /* create the main_conf, srv_conf and loc_conf in all http modules */ for (m = 0; ngx_modules[m]; m++) { if (ngx_modules[m]->type != NGX_HTTP_MODULE) { continue; } module = ngx_modules[m]->ctx; mi = ngx_modules[m]->ctx_index; if (module->pre_conf) { if (module->pre_conf(cf) != NGX_OK) { return NGX_CONF_ERROR; } } if (module->create_main_conf) { ngx_test_null(ctx->main_conf[mi], module->create_main_conf(cf), NGX_CONF_ERROR); } if (module->create_srv_conf) { ngx_test_null(ctx->srv_conf[mi], module->create_srv_conf(cf), NGX_CONF_ERROR); } if (module->create_loc_conf) { ngx_test_null(ctx->loc_conf[mi], module->create_loc_conf(cf), NGX_CONF_ERROR); } } /* parse inside the http{} block */ pcf = *cf; cf->ctx = ctx; cf->module_type = NGX_HTTP_MODULE; cf->cmd_type = NGX_HTTP_MAIN_CONF; rv = ngx_conf_parse(cf, NULL); if (rv != NGX_CONF_OK) { *cf = pcf; return rv; } /* * init http{} main_conf's, merge the server{}s' srv_conf's * and its location{}s' loc_conf's */ cmcf = ctx->main_conf[ngx_http_core_module.ctx_index]; cscfp = cmcf->servers.elts; for (m = 0; ngx_modules[m]; m++) { if (ngx_modules[m]->type != NGX_HTTP_MODULE) { continue; } module = ngx_modules[m]->ctx; mi = ngx_modules[m]->ctx_index; /* init http{} main_conf's */ if (module->init_main_conf) { rv = module->init_main_conf(cf, ctx->main_conf[mi]); if (rv != NGX_CONF_OK) { *cf = pcf; return rv; } } for (s = 0; s < cmcf->servers.nelts; s++) { /* merge the server{}s' srv_conf's */ if (module->merge_srv_conf) { rv = module->merge_srv_conf(cf, ctx->srv_conf[mi], cscfp[s]->ctx->srv_conf[mi]); if (rv != NGX_CONF_OK) { *cf = pcf; return rv; } } if (module->merge_loc_conf) { /* merge the server{}'s loc_conf */ rv = module->merge_loc_conf(cf, ctx->loc_conf[mi], cscfp[s]->ctx->loc_conf[mi]); if (rv != NGX_CONF_OK) { *cf = pcf; return rv; } /* merge the locations{}' loc_conf's */ rv = ngx_http_merge_locations(cf, &cscfp[s]->locations, cscfp[s]->ctx->loc_conf, module, mi); if (rv != NGX_CONF_OK) { *cf = pcf; return rv; } #if 0 clcfp = (ngx_http_core_loc_conf_t **) cscfp[s]->locations.elts; for (l = 0; l < cscfp[s]->locations.nelts; l++) { rv = module->merge_loc_conf(cf, cscfp[s]->ctx->loc_conf[mi], clcfp[l]->loc_conf[mi]); if (rv != NGX_CONF_OK) { *cf = pcf; return rv; } } #endif } } } /* we needed "http"'s cf->ctx while merging configuration */ *cf = pcf; /* init lists of the handlers */ ngx_init_array(cmcf->phases[NGX_HTTP_REWRITE_PHASE].handlers, cf->cycle->pool, 10, sizeof(ngx_http_handler_pt), NGX_CONF_ERROR); cmcf->phases[NGX_HTTP_REWRITE_PHASE].type = NGX_OK; /* the special find config phase for single handler */ ngx_init_array(cmcf->phases[NGX_HTTP_FIND_CONFIG_PHASE].handlers, cf->cycle->pool, 1, sizeof(ngx_http_handler_pt), NGX_CONF_ERROR); cmcf->phases[NGX_HTTP_FIND_CONFIG_PHASE].type = NGX_OK; ngx_test_null(h, ngx_push_array( &cmcf->phases[NGX_HTTP_FIND_CONFIG_PHASE].handlers), NGX_CONF_ERROR); *h = ngx_http_find_location_config; ngx_init_array(cmcf->phases[NGX_HTTP_ACCESS_PHASE].handlers, cf->cycle->pool, 10, sizeof(ngx_http_handler_pt), NGX_CONF_ERROR); cmcf->phases[NGX_HTTP_ACCESS_PHASE].type = NGX_DECLINED; ngx_init_array(cmcf->phases[NGX_HTTP_CONTENT_PHASE].handlers, cf->cycle->pool, 10, sizeof(ngx_http_handler_pt), NGX_CONF_ERROR); cmcf->phases[NGX_HTTP_CONTENT_PHASE].type = NGX_OK; /* * create the lists of the ports, the addresses and the server names * to allow quickly find the server core module configuration at run-time */ ngx_init_array(in_ports, cf->pool, 10, sizeof(ngx_http_in_port_t), NGX_CONF_ERROR); /* "server" directives */ cscfp = cmcf->servers.elts; for (s = 0; s < cmcf->servers.nelts; s++) { /* "listen" directives */ lscf = cscfp[s]->listen.elts; for (l = 0; l < cscfp[s]->listen.nelts; l++) { port_found = 0; /* AF_INET only */ in_port = in_ports.elts; for (p = 0; p < in_ports.nelts; p++) { if (lscf[l].port == in_port[p].port) { /* the port is already in the port list */ port_found = 1; addr_found = 0; in_addr = in_port[p].addrs.elts; for (a = 0; a < in_port[p].addrs.nelts; a++) { if (lscf[l].addr == in_addr[a].addr) { /* the address is already bound to this port */ /* "server_name" directives */ s_name = cscfp[s]->server_names.elts; for (n = 0; n < cscfp[s]->server_names.nelts; n++) { /* * add the server name and server core module * configuration to the address:port */ /* TODO: duplicate names can be checked here */ ngx_test_null(name, ngx_push_array(&in_addr[a].names), NGX_CONF_ERROR); name->name = s_name[n].name; name->core_srv_conf = s_name[n].core_srv_conf; } /* * check duplicate "default" server that * serves this address:port */ if (lscf[l].default_server) { if (in_addr[a].default_server) { ngx_log_error(NGX_LOG_ERR, cf->log, 0, "duplicate default server in %s:%d", lscf[l].file_name.data, lscf[l].line); return NGX_CONF_ERROR; } in_addr[a].core_srv_conf = cscfp[s]; in_addr[a].default_server = 1; } addr_found = 1; break; } else if (in_addr[a].addr == INADDR_ANY) { /* * "*:port" must be the last resort so move it * to the end of the address list and add * the new address at its place */ ngx_test_null(inaddr, ngx_push_array(&in_port[p].addrs), NGX_CONF_ERROR); ngx_memcpy(inaddr, &in_addr[a], sizeof(ngx_http_in_addr_t)); in_addr[a].addr = lscf[l].addr; in_addr[a].default_server = lscf[l].default_server; in_addr[a].core_srv_conf = cscfp[s]; /* * create the empty list of the server names that * can be served on this address:port */ ngx_init_array(inaddr->names, cf->pool, 10, sizeof(ngx_http_server_name_t), NGX_CONF_ERROR); addr_found = 1; break; } } if (!addr_found) { /* * add the address to the addresses list that * bound to this port */ ngx_test_null(inaddr, ngx_push_array(&in_port[p].addrs), NGX_CONF_ERROR); inaddr->addr = lscf[l].addr; inaddr->default_server = lscf[l].default_server; inaddr->core_srv_conf = cscfp[s]; /* * create the empty list of the server names that * can be served on this address:port */ ngx_init_array(inaddr->names, cf->pool, 10, sizeof(ngx_http_server_name_t), NGX_CONF_ERROR); } } } if (!port_found) { /* add the port to the in_port list */ ngx_test_null(in_port, ngx_push_array(&in_ports), NGX_CONF_ERROR); in_port->port = lscf[l].port; ngx_test_null(in_port->port_text.data, ngx_palloc(cf->pool, 7), NGX_CONF_ERROR); in_port->port_text.len = ngx_snprintf((char *) in_port->port_text.data, 7, ":%d", in_port->port); /* create list of the addresses that bound to this port ... */ ngx_init_array(in_port->addrs, cf->pool, 10, sizeof(ngx_http_in_addr_t), NGX_CONF_ERROR); ngx_test_null(inaddr, ngx_push_array(&in_port->addrs), NGX_CONF_ERROR); /* ... and add the address to this list */ inaddr->addr = lscf[l].addr; inaddr->default_server = lscf[l].default_server; inaddr->core_srv_conf = cscfp[s]; /* * create the empty list of the server names that * can be served on this address:port */ ngx_init_array(inaddr->names, cf->pool, 10, sizeof(ngx_http_server_name_t), NGX_CONF_ERROR); } } } /* optimize the lists of the ports, the addresses and the server names */ /* AF_INET only */ in_port = in_ports.elts; for (p = 0; p < in_ports.nelts; p++) { /* check whether the all server names point to the same server */ in_addr = in_port[p].addrs.elts; for (a = 0; a < in_port[p].addrs.nelts; a++) { virtual_names = 0; name = in_addr[a].names.elts; for (n = 0; n < in_addr[a].names.nelts; n++) { if (in_addr[a].core_srv_conf != name[n].core_srv_conf) { virtual_names = 1; break; } } /* * if the all server names point to the same server * then we do not need to check them at run-time */ if (!virtual_names) { in_addr[a].names.nelts = 0; } } /* * if there's the binding to "*:port" then we need to bind() * to "*:port" only and ignore the other bindings */ if (in_addr[a - 1].addr == INADDR_ANY) { a--; } else { a = 0; } in_addr = in_port[p].addrs.elts; while (a < in_port[p].addrs.nelts) { ls = ngx_listening_inet_stream_socket(cf, in_addr[a].addr, in_port[p].port); if (ls == NULL) { return NGX_CONF_ERROR; } ls->backlog = -1; #if 0 #if 0 ls->nonblocking = 1; #else ls->nonblocking = 0; #endif #endif ls->addr_ntop = 1; ls->handler = ngx_http_init_connection; cscf = in_addr[a].core_srv_conf; ls->pool_size = cscf->connection_pool_size; ls->post_accept_timeout = cscf->post_accept_timeout; clcf = cscf->ctx->loc_conf[ngx_http_core_module.ctx_index]; ls->log = clcf->err_log; #if (WIN32) iocpcf = ngx_event_get_conf(cf->cycle->conf_ctx, ngx_iocp_module); if (iocpcf->acceptex_read) { ls->post_accept_buffer_size = cscf->client_header_buffer_size; } #endif ls->ctx = ctx; if (in_port[p].addrs.nelts > 1) { in_addr = in_port[p].addrs.elts; if (in_addr[in_port[p].addrs.nelts - 1].addr != INADDR_ANY) { /* * if this port has not the "*:port" binding then create * the separate ngx_http_in_port_t for the all bindings */ ngx_test_null(inport, ngx_palloc(cf->pool, sizeof(ngx_http_in_port_t)), NGX_CONF_ERROR); inport->port = in_port[p].port; inport->port_text = in_port[p].port_text; /* init list of the addresses ... */ ngx_init_array(inport->addrs, cf->pool, 1, sizeof(ngx_http_in_addr_t), NGX_CONF_ERROR); /* ... and set up it with the first address */ inport->addrs.nelts = 1; inport->addrs.elts = in_port[p].addrs.elts; ls->servers = inport; /* prepare for the next cycle */ in_port[p].addrs.elts = (char *) in_port[p].addrs.elts + in_port[p].addrs.size; in_port[p].addrs.nelts--; in_addr = (ngx_http_in_addr_t *) in_port[p].addrs.elts; a = 0; continue; } } ls->servers = &in_port[p]; a++; } } #if (NGX_DEBUG) in_port = in_ports.elts; for (p = 0; p < in_ports.nelts; p++) { ngx_log_debug2(NGX_LOG_DEBUG_HTTP, cf->log, 0, "port: %d %08x", in_port[p].port, &in_port[p]); in_addr = in_port[p].addrs.elts; for (a = 0; a < in_port[p].addrs.nelts; a++) { u_char ip[20]; ngx_inet_ntop(AF_INET, &in_addr[a].addr, ip, 20); ngx_log_debug2(NGX_LOG_DEBUG_HTTP, cf->log, 0, "%s %08x", ip, in_addr[a].core_srv_conf); s_name = in_addr[a].names.elts; for (n = 0; n < in_addr[a].names.nelts; n++) { ngx_log_debug2(NGX_LOG_DEBUG_HTTP, cf->log, 0, "%s %08x", s_name[n].name.data, s_name[n].core_srv_conf); } } } #endif return NGX_CONF_OK; }
static ngx_int_t ngx_limit_tcp_http_get_addr_index(ngx_listening_t *ls, struct sockaddr *addr, ngx_flag_t type) { ngx_uint_t i; ngx_http_port_t *port; struct sockaddr_in *sin, *lsin; ngx_http_in_addr_t *haddr; #if (NGX_HAVE_INET6) struct sockaddr_in6 *sin6, *lsin6; ngx_http_in6_addr_t *haddr6; #endif port = ls->servers; ngx_log_debug2(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0, "listen: %V port num: %ui", &ls->addr_text, port->naddrs); switch (ls->sockaddr->sa_family) { #if (NGX_HAVE_INET6) case AF_INET6: sin6 = (struct sockaddr_in6 *) addr; haddr6 = port->addrs; if (type) { lsin6 = (struct sockaddr_in6 *) ls->sockaddr; if (ngx_memcmp(&lsin6->sin6_port, &sin6->sin6_port, sizeof(in_port_t)) != 0) { return NGX_ERROR; } } for (i = 0; i < port->naddrs; i++) { if (ngx_memcmp(&haddr6[i].addr6, &sin6->sin6_addr, 16) == 0) { return i; } } if (type) { break; } else { return i - 1; } #endif default: sin = (struct sockaddr_in *) addr; haddr = port->addrs; if (type) { lsin = (struct sockaddr_in *) ls->sockaddr; if (lsin->sin_port != sin->sin_port) { return NGX_ERROR; } } for (i = 0; i < port->naddrs; i++) { #if NGX_DEBUG u_char ip1[NGX_INET6_ADDRSTRLEN], ip2[NGX_INET6_ADDRSTRLEN]; ngx_memzero(ip1, NGX_INET6_ADDRSTRLEN); ngx_memzero(ip2, NGX_INET6_ADDRSTRLEN); (void) ngx_inet_ntop(AF_INET, &sin->sin_addr, ip1, NGX_INET6_ADDRSTRLEN); (void) ngx_inet_ntop(AF_INET, &haddr[i].addr, ip2, NGX_INET6_ADDRSTRLEN); ngx_log_debug2(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0, "limit %s to %s", ip1, ip2); #endif if (haddr[i].addr == sin->sin_addr.s_addr) { return i; } } if (type) { break; } else { return i - 1; } } return NGX_ERROR; }