diff options
Diffstat (limited to 'app/nginx/src/stream')
29 files changed, 0 insertions, 18005 deletions
diff --git a/app/nginx/src/stream/ngx_stream.c b/app/nginx/src/stream/ngx_stream.c deleted file mode 100644 index 4a394d7..0000000 --- a/app/nginx/src/stream/ngx_stream.c +++ /dev/null @@ -1,683 +0,0 @@ - -/* - * Copyright (C) Roman Arutyunyan - * Copyright (C) Nginx, Inc. - */ - - -#include <ngx_config.h> -#include <ngx_core.h> -#include <ngx_event.h> -#include <ngx_stream.h> - - -static char *ngx_stream_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); -static ngx_int_t ngx_stream_init_phases(ngx_conf_t *cf, - ngx_stream_core_main_conf_t *cmcf); -static ngx_int_t ngx_stream_init_phase_handlers(ngx_conf_t *cf, - ngx_stream_core_main_conf_t *cmcf); -static ngx_int_t ngx_stream_add_ports(ngx_conf_t *cf, ngx_array_t *ports, - ngx_stream_listen_t *listen); -static char *ngx_stream_optimize_servers(ngx_conf_t *cf, ngx_array_t *ports); -static ngx_int_t ngx_stream_add_addrs(ngx_conf_t *cf, ngx_stream_port_t *stport, - ngx_stream_conf_addr_t *addr); -#if (NGX_HAVE_INET6) -static ngx_int_t ngx_stream_add_addrs6(ngx_conf_t *cf, - ngx_stream_port_t *stport, ngx_stream_conf_addr_t *addr); -#endif -static ngx_int_t ngx_stream_cmp_conf_addrs(const void *one, const void *two); - - -ngx_uint_t ngx_stream_max_module; - - -ngx_stream_filter_pt ngx_stream_top_filter; - - -static ngx_command_t ngx_stream_commands[] = { - - { ngx_string("stream"), - NGX_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS, - ngx_stream_block, - 0, - 0, - NULL }, - - ngx_null_command -}; - - -static ngx_core_module_t ngx_stream_module_ctx = { - ngx_string("stream"), - NULL, - NULL -}; - - -ngx_module_t ngx_stream_module = { - NGX_MODULE_V1, - &ngx_stream_module_ctx, /* module context */ - ngx_stream_commands, /* module directives */ - NGX_CORE_MODULE, /* module type */ - NULL, /* init master */ - NULL, /* init module */ - NULL, /* init process */ - NULL, /* init thread */ - NULL, /* exit thread */ - NULL, /* exit process */ - NULL, /* exit master */ - NGX_MODULE_V1_PADDING -}; - - -static char * -ngx_stream_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) -{ - char *rv; - ngx_uint_t i, m, mi, s; - ngx_conf_t pcf; - ngx_array_t ports; - ngx_stream_listen_t *listen; - ngx_stream_module_t *module; - ngx_stream_conf_ctx_t *ctx; - ngx_stream_core_srv_conf_t **cscfp; - ngx_stream_core_main_conf_t *cmcf; - - if (*(ngx_stream_conf_ctx_t **) conf) { - return "is duplicate"; - } - - /* the main stream context */ - - ctx = ngx_pcalloc(cf->pool, sizeof(ngx_stream_conf_ctx_t)); - if (ctx == NULL) { - return NGX_CONF_ERROR; - } - - *(ngx_stream_conf_ctx_t **) conf = ctx; - - /* count the number of the stream modules and set up their indices */ - - ngx_stream_max_module = ngx_count_modules(cf->cycle, NGX_STREAM_MODULE); - - - /* the stream main_conf context, it's the same in the all stream contexts */ - - ctx->main_conf = ngx_pcalloc(cf->pool, - sizeof(void *) * ngx_stream_max_module); - if (ctx->main_conf == NULL) { - return NGX_CONF_ERROR; - } - - - /* - * the stream null srv_conf context, it is used to merge - * the server{}s' srv_conf's - */ - - ctx->srv_conf = ngx_pcalloc(cf->pool, - sizeof(void *) * ngx_stream_max_module); - if (ctx->srv_conf == NULL) { - return NGX_CONF_ERROR; - } - - - /* - * create the main_conf's and the null srv_conf's of the all stream modules - */ - - for (m = 0; cf->cycle->modules[m]; m++) { - if (cf->cycle->modules[m]->type != NGX_STREAM_MODULE) { - continue; - } - - module = cf->cycle->modules[m]->ctx; - mi = cf->cycle->modules[m]->ctx_index; - - if (module->create_main_conf) { - ctx->main_conf[mi] = module->create_main_conf(cf); - if (ctx->main_conf[mi] == NULL) { - return NGX_CONF_ERROR; - } - } - - if (module->create_srv_conf) { - ctx->srv_conf[mi] = module->create_srv_conf(cf); - if (ctx->srv_conf[mi] == NULL) { - return NGX_CONF_ERROR; - } - } - } - - - pcf = *cf; - cf->ctx = ctx; - - for (m = 0; cf->cycle->modules[m]; m++) { - if (cf->cycle->modules[m]->type != NGX_STREAM_MODULE) { - continue; - } - - module = cf->cycle->modules[m]->ctx; - - if (module->preconfiguration) { - if (module->preconfiguration(cf) != NGX_OK) { - return NGX_CONF_ERROR; - } - } - } - - - /* parse inside the stream{} block */ - - cf->module_type = NGX_STREAM_MODULE; - cf->cmd_type = NGX_STREAM_MAIN_CONF; - rv = ngx_conf_parse(cf, NULL); - - if (rv != NGX_CONF_OK) { - *cf = pcf; - return rv; - } - - - /* init stream{} main_conf's, merge the server{}s' srv_conf's */ - - cmcf = ctx->main_conf[ngx_stream_core_module.ctx_index]; - cscfp = cmcf->servers.elts; - - for (m = 0; cf->cycle->modules[m]; m++) { - if (cf->cycle->modules[m]->type != NGX_STREAM_MODULE) { - continue; - } - - module = cf->cycle->modules[m]->ctx; - mi = cf->cycle->modules[m]->ctx_index; - - /* init stream{} main_conf's */ - - cf->ctx = ctx; - - 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 */ - - cf->ctx = cscfp[s]->ctx; - - 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 (ngx_stream_init_phases(cf, cmcf) != NGX_OK) { - return NGX_CONF_ERROR; - } - - for (m = 0; cf->cycle->modules[m]; m++) { - if (cf->cycle->modules[m]->type != NGX_STREAM_MODULE) { - continue; - } - - module = cf->cycle->modules[m]->ctx; - - if (module->postconfiguration) { - if (module->postconfiguration(cf) != NGX_OK) { - return NGX_CONF_ERROR; - } - } - } - - if (ngx_stream_variables_init_vars(cf) != NGX_OK) { - return NGX_CONF_ERROR; - } - - *cf = pcf; - - if (ngx_stream_init_phase_handlers(cf, cmcf) != NGX_OK) { - return NGX_CONF_ERROR; - } - - if (ngx_array_init(&ports, cf->temp_pool, 4, sizeof(ngx_stream_conf_port_t)) - != NGX_OK) - { - return NGX_CONF_ERROR; - } - - listen = cmcf->listen.elts; - - for (i = 0; i < cmcf->listen.nelts; i++) { - if (ngx_stream_add_ports(cf, &ports, &listen[i]) != NGX_OK) { - return NGX_CONF_ERROR; - } - } - - return ngx_stream_optimize_servers(cf, &ports); -} - - -static ngx_int_t -ngx_stream_init_phases(ngx_conf_t *cf, ngx_stream_core_main_conf_t *cmcf) -{ - if (ngx_array_init(&cmcf->phases[NGX_STREAM_POST_ACCEPT_PHASE].handlers, - cf->pool, 1, sizeof(ngx_stream_handler_pt)) - != NGX_OK) - { - return NGX_ERROR; - } - - if (ngx_array_init(&cmcf->phases[NGX_STREAM_PREACCESS_PHASE].handlers, - cf->pool, 1, sizeof(ngx_stream_handler_pt)) - != NGX_OK) - { - return NGX_ERROR; - } - - if (ngx_array_init(&cmcf->phases[NGX_STREAM_ACCESS_PHASE].handlers, - cf->pool, 1, sizeof(ngx_stream_handler_pt)) - != NGX_OK) - { - return NGX_ERROR; - } - - if (ngx_array_init(&cmcf->phases[NGX_STREAM_SSL_PHASE].handlers, - cf->pool, 1, sizeof(ngx_stream_handler_pt)) - != NGX_OK) - { - return NGX_ERROR; - } - - if (ngx_array_init(&cmcf->phases[NGX_STREAM_PREREAD_PHASE].handlers, - cf->pool, 1, sizeof(ngx_stream_handler_pt)) - != NGX_OK) - { - return NGX_ERROR; - } - - if (ngx_array_init(&cmcf->phases[NGX_STREAM_LOG_PHASE].handlers, - cf->pool, 1, sizeof(ngx_stream_handler_pt)) - != NGX_OK) - { - return NGX_ERROR; - } - - return NGX_OK; -} - - -static ngx_int_t -ngx_stream_init_phase_handlers(ngx_conf_t *cf, - ngx_stream_core_main_conf_t *cmcf) -{ - ngx_int_t j; - ngx_uint_t i, n; - ngx_stream_handler_pt *h; - ngx_stream_phase_handler_t *ph; - ngx_stream_phase_handler_pt checker; - - n = 1 /* content phase */; - - for (i = 0; i < NGX_STREAM_LOG_PHASE; i++) { - n += cmcf->phases[i].handlers.nelts; - } - - ph = ngx_pcalloc(cf->pool, - n * sizeof(ngx_stream_phase_handler_t) + sizeof(void *)); - if (ph == NULL) { - return NGX_ERROR; - } - - cmcf->phase_engine.handlers = ph; - n = 0; - - for (i = 0; i < NGX_STREAM_LOG_PHASE; i++) { - h = cmcf->phases[i].handlers.elts; - - switch (i) { - - case NGX_STREAM_PREREAD_PHASE: - checker = ngx_stream_core_preread_phase; - break; - - case NGX_STREAM_CONTENT_PHASE: - ph->checker = ngx_stream_core_content_phase; - n++; - ph++; - - continue; - - default: - checker = ngx_stream_core_generic_phase; - } - - n += cmcf->phases[i].handlers.nelts; - - for (j = cmcf->phases[i].handlers.nelts - 1; j >= 0; j--) { - ph->checker = checker; - ph->handler = h[j]; - ph->next = n; - ph++; - } - } - - return NGX_OK; -} - - -static ngx_int_t -ngx_stream_add_ports(ngx_conf_t *cf, ngx_array_t *ports, - ngx_stream_listen_t *listen) -{ - in_port_t p; - ngx_uint_t i; - struct sockaddr *sa; - ngx_stream_conf_port_t *port; - ngx_stream_conf_addr_t *addr; - - sa = &listen->sockaddr.sockaddr; - p = ngx_inet_get_port(sa); - - port = ports->elts; - for (i = 0; i < ports->nelts; i++) { - - if (p == port[i].port - && listen->type == port[i].type - && sa->sa_family == port[i].family) - { - /* a port is already in the port list */ - - port = &port[i]; - goto found; - } - } - - /* add a port to the port list */ - - port = ngx_array_push(ports); - if (port == NULL) { - return NGX_ERROR; - } - - port->family = sa->sa_family; - port->type = listen->type; - port->port = p; - - if (ngx_array_init(&port->addrs, cf->temp_pool, 2, - sizeof(ngx_stream_conf_addr_t)) - != NGX_OK) - { - return NGX_ERROR; - } - -found: - - addr = ngx_array_push(&port->addrs); - if (addr == NULL) { - return NGX_ERROR; - } - - addr->opt = *listen; - - return NGX_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; -} - - -static ngx_int_t -ngx_stream_add_addrs(ngx_conf_t *cf, ngx_stream_port_t *stport, - ngx_stream_conf_addr_t *addr) -{ - u_char *p; - size_t len; - ngx_uint_t i; - struct sockaddr_in *sin; - ngx_stream_in_addr_t *addrs; - u_char buf[NGX_SOCKADDR_STRLEN]; - - stport->addrs = ngx_pcalloc(cf->pool, - stport->naddrs * sizeof(ngx_stream_in_addr_t)); - if (stport->addrs == NULL) { - return NGX_ERROR; - } - - addrs = stport->addrs; - - for (i = 0; i < stport->naddrs; i++) { - - sin = &addr[i].opt.sockaddr.sockaddr_in; - addrs[i].addr = sin->sin_addr.s_addr; - - addrs[i].conf.ctx = addr[i].opt.ctx; -#if (NGX_STREAM_SSL) - addrs[i].conf.ssl = addr[i].opt.ssl; -#endif - addrs[i].conf.proxy_protocol = addr[i].opt.proxy_protocol; - - len = ngx_sock_ntop(&addr[i].opt.sockaddr.sockaddr, addr[i].opt.socklen, - buf, NGX_SOCKADDR_STRLEN, 1); - - p = ngx_pnalloc(cf->pool, len); - if (p == NULL) { - return NGX_ERROR; - } - - ngx_memcpy(p, buf, len); - - addrs[i].conf.addr_text.len = len; - addrs[i].conf.addr_text.data = p; - } - - return NGX_OK; -} - - -#if (NGX_HAVE_INET6) - -static ngx_int_t -ngx_stream_add_addrs6(ngx_conf_t *cf, ngx_stream_port_t *stport, - ngx_stream_conf_addr_t *addr) -{ - u_char *p; - size_t len; - ngx_uint_t i; - struct sockaddr_in6 *sin6; - ngx_stream_in6_addr_t *addrs6; - u_char buf[NGX_SOCKADDR_STRLEN]; - - stport->addrs = ngx_pcalloc(cf->pool, - stport->naddrs * sizeof(ngx_stream_in6_addr_t)); - if (stport->addrs == NULL) { - return NGX_ERROR; - } - - addrs6 = stport->addrs; - - for (i = 0; i < stport->naddrs; i++) { - - sin6 = &addr[i].opt.sockaddr.sockaddr_in6; - addrs6[i].addr6 = sin6->sin6_addr; - - addrs6[i].conf.ctx = addr[i].opt.ctx; -#if (NGX_STREAM_SSL) - addrs6[i].conf.ssl = addr[i].opt.ssl; -#endif - addrs6[i].conf.proxy_protocol = addr[i].opt.proxy_protocol; - - len = ngx_sock_ntop(&addr[i].opt.sockaddr.sockaddr, addr[i].opt.socklen, - buf, NGX_SOCKADDR_STRLEN, 1); - - p = ngx_pnalloc(cf->pool, len); - if (p == NULL) { - return NGX_ERROR; - } - - ngx_memcpy(p, buf, len); - - addrs6[i].conf.addr_text.len = len; - addrs6[i].conf.addr_text.data = p; - } - - return NGX_OK; -} - -#endif - - -static ngx_int_t -ngx_stream_cmp_conf_addrs(const void *one, const void *two) -{ - ngx_stream_conf_addr_t *first, *second; - - first = (ngx_stream_conf_addr_t *) one; - second = (ngx_stream_conf_addr_t *) two; - - if (first->opt.wildcard) { - /* a wildcard must be the last resort, shift it to the end */ - return 1; - } - - if (second->opt.wildcard) { - /* a wildcard must be the last resort, shift it to the end */ - return -1; - } - - if (first->opt.bind && !second->opt.bind) { - /* shift explicit bind()ed addresses to the start */ - return -1; - } - - if (!first->opt.bind && second->opt.bind) { - /* shift explicit bind()ed addresses to the start */ - return 1; - } - - /* do not sort by default */ - - return 0; -} diff --git a/app/nginx/src/stream/ngx_stream.h b/app/nginx/src/stream/ngx_stream.h deleted file mode 100644 index 814e3b9..0000000 --- a/app/nginx/src/stream/ngx_stream.h +++ /dev/null @@ -1,304 +0,0 @@ - -/* - * Copyright (C) Roman Arutyunyan - * Copyright (C) Nginx, Inc. - */ - - -#ifndef _NGX_STREAM_H_INCLUDED_ -#define _NGX_STREAM_H_INCLUDED_ - - -#include <ngx_config.h> -#include <ngx_core.h> - -#if (NGX_STREAM_SSL) -#include <ngx_stream_ssl_module.h> -#endif - - -typedef struct ngx_stream_session_s ngx_stream_session_t; - - -#include <ngx_stream_variables.h> -#include <ngx_stream_script.h> -#include <ngx_stream_upstream.h> -#include <ngx_stream_upstream_round_robin.h> - - -#define NGX_STREAM_OK 200 -#define NGX_STREAM_BAD_REQUEST 400 -#define NGX_STREAM_FORBIDDEN 403 -#define NGX_STREAM_INTERNAL_SERVER_ERROR 500 -#define NGX_STREAM_BAD_GATEWAY 502 -#define NGX_STREAM_SERVICE_UNAVAILABLE 503 - - -typedef struct { - void **main_conf; - void **srv_conf; -} ngx_stream_conf_ctx_t; - - -typedef struct { - ngx_sockaddr_t sockaddr; - socklen_t socklen; - - /* server ctx */ - ngx_stream_conf_ctx_t *ctx; - - unsigned bind:1; - unsigned wildcard:1; - unsigned ssl:1; -#if (NGX_HAVE_INET6) - unsigned ipv6only:1; -#endif - unsigned reuseport:1; - unsigned so_keepalive:2; - unsigned proxy_protocol:1; -#if (NGX_HAVE_KEEPALIVE_TUNABLE) - int tcp_keepidle; - int tcp_keepintvl; - int tcp_keepcnt; -#endif - int backlog; - int type; -} ngx_stream_listen_t; - - -typedef struct { - ngx_stream_conf_ctx_t *ctx; - ngx_str_t addr_text; - unsigned ssl:1; - unsigned proxy_protocol:1; -} ngx_stream_addr_conf_t; - -typedef struct { - in_addr_t addr; - ngx_stream_addr_conf_t conf; -} ngx_stream_in_addr_t; - - -#if (NGX_HAVE_INET6) - -typedef struct { - struct in6_addr addr6; - ngx_stream_addr_conf_t conf; -} ngx_stream_in6_addr_t; - -#endif - - -typedef struct { - /* ngx_stream_in_addr_t or ngx_stream_in6_addr_t */ - void *addrs; - ngx_uint_t naddrs; -} ngx_stream_port_t; - - -typedef struct { - int family; - int type; - in_port_t port; - ngx_array_t addrs; /* array of ngx_stream_conf_addr_t */ -} ngx_stream_conf_port_t; - - -typedef struct { - ngx_stream_listen_t opt; -} ngx_stream_conf_addr_t; - - -typedef enum { - NGX_STREAM_POST_ACCEPT_PHASE = 0, - NGX_STREAM_PREACCESS_PHASE, - NGX_STREAM_ACCESS_PHASE, - NGX_STREAM_SSL_PHASE, - NGX_STREAM_PREREAD_PHASE, - NGX_STREAM_CONTENT_PHASE, - NGX_STREAM_LOG_PHASE -} ngx_stream_phases; - - -typedef struct ngx_stream_phase_handler_s ngx_stream_phase_handler_t; - -typedef ngx_int_t (*ngx_stream_phase_handler_pt)(ngx_stream_session_t *s, - ngx_stream_phase_handler_t *ph); -typedef ngx_int_t (*ngx_stream_handler_pt)(ngx_stream_session_t *s); -typedef void (*ngx_stream_content_handler_pt)(ngx_stream_session_t *s); - - -struct ngx_stream_phase_handler_s { - ngx_stream_phase_handler_pt checker; - ngx_stream_handler_pt handler; - ngx_uint_t next; -}; - - -typedef struct { - ngx_stream_phase_handler_t *handlers; -} ngx_stream_phase_engine_t; - - -typedef struct { - ngx_array_t handlers; -} ngx_stream_phase_t; - - -typedef struct { - ngx_array_t servers; /* ngx_stream_core_srv_conf_t */ - ngx_array_t listen; /* ngx_stream_listen_t */ - - ngx_stream_phase_engine_t phase_engine; - - ngx_hash_t variables_hash; - - ngx_array_t variables; /* ngx_stream_variable_t */ - ngx_array_t prefix_variables; /* ngx_stream_variable_t */ - ngx_uint_t ncaptures; - - ngx_uint_t variables_hash_max_size; - ngx_uint_t variables_hash_bucket_size; - - ngx_hash_keys_arrays_t *variables_keys; - - ngx_stream_phase_t phases[NGX_STREAM_LOG_PHASE + 1]; -} ngx_stream_core_main_conf_t; - - -typedef struct { - ngx_stream_content_handler_pt handler; - - ngx_stream_conf_ctx_t *ctx; - - u_char *file_name; - ngx_uint_t line; - - ngx_flag_t tcp_nodelay; - size_t preread_buffer_size; - ngx_msec_t preread_timeout; - - ngx_log_t *error_log; - - ngx_msec_t resolver_timeout; - ngx_resolver_t *resolver; - - ngx_msec_t proxy_protocol_timeout; - - ngx_uint_t listen; /* unsigned listen:1; */ -} ngx_stream_core_srv_conf_t; - - -struct ngx_stream_session_s { - uint32_t signature; /* "STRM" */ - - ngx_connection_t *connection; - - off_t received; - time_t start_sec; - ngx_msec_t start_msec; - - ngx_log_handler_pt log_handler; - - void **ctx; - void **main_conf; - void **srv_conf; - - ngx_stream_upstream_t *upstream; - ngx_array_t *upstream_states; - /* of ngx_stream_upstream_state_t */ - ngx_stream_variable_value_t *variables; - -#if (NGX_PCRE) - ngx_uint_t ncaptures; - int *captures; - u_char *captures_data; -#endif - - ngx_int_t phase_handler; - ngx_uint_t status; - - unsigned ssl:1; - - unsigned stat_processing:1; - - unsigned health_check:1; -}; - - -typedef struct { - ngx_int_t (*preconfiguration)(ngx_conf_t *cf); - ngx_int_t (*postconfiguration)(ngx_conf_t *cf); - - void *(*create_main_conf)(ngx_conf_t *cf); - char *(*init_main_conf)(ngx_conf_t *cf, void *conf); - - void *(*create_srv_conf)(ngx_conf_t *cf); - char *(*merge_srv_conf)(ngx_conf_t *cf, void *prev, - void *conf); -} ngx_stream_module_t; - - -#define NGX_STREAM_MODULE 0x4d525453 /* "STRM" */ - -#define NGX_STREAM_MAIN_CONF 0x02000000 -#define NGX_STREAM_SRV_CONF 0x04000000 -#define NGX_STREAM_UPS_CONF 0x08000000 - - -#define NGX_STREAM_MAIN_CONF_OFFSET offsetof(ngx_stream_conf_ctx_t, main_conf) -#define NGX_STREAM_SRV_CONF_OFFSET offsetof(ngx_stream_conf_ctx_t, srv_conf) - - -#define ngx_stream_get_module_ctx(s, module) (s)->ctx[module.ctx_index] -#define ngx_stream_set_ctx(s, c, module) s->ctx[module.ctx_index] = c; -#define ngx_stream_delete_ctx(s, module) s->ctx[module.ctx_index] = NULL; - - -#define ngx_stream_get_module_main_conf(s, module) \ - (s)->main_conf[module.ctx_index] -#define ngx_stream_get_module_srv_conf(s, module) \ - (s)->srv_conf[module.ctx_index] - -#define ngx_stream_conf_get_module_main_conf(cf, module) \ - ((ngx_stream_conf_ctx_t *) cf->ctx)->main_conf[module.ctx_index] -#define ngx_stream_conf_get_module_srv_conf(cf, module) \ - ((ngx_stream_conf_ctx_t *) cf->ctx)->srv_conf[module.ctx_index] - -#define ngx_stream_cycle_get_module_main_conf(cycle, module) \ - (cycle->conf_ctx[ngx_stream_module.index] ? \ - ((ngx_stream_conf_ctx_t *) cycle->conf_ctx[ngx_stream_module.index]) \ - ->main_conf[module.ctx_index]: \ - NULL) - - -#define NGX_STREAM_WRITE_BUFFERED 0x10 - - -void ngx_stream_core_run_phases(ngx_stream_session_t *s); -ngx_int_t ngx_stream_core_generic_phase(ngx_stream_session_t *s, - ngx_stream_phase_handler_t *ph); -ngx_int_t ngx_stream_core_preread_phase(ngx_stream_session_t *s, - ngx_stream_phase_handler_t *ph); -ngx_int_t ngx_stream_core_content_phase(ngx_stream_session_t *s, - ngx_stream_phase_handler_t *ph); - - -void ngx_stream_init_connection(ngx_connection_t *c); -void ngx_stream_session_handler(ngx_event_t *rev); -void ngx_stream_finalize_session(ngx_stream_session_t *s, ngx_uint_t rc); - - -extern ngx_module_t ngx_stream_module; -extern ngx_uint_t ngx_stream_max_module; -extern ngx_module_t ngx_stream_core_module; - - -typedef ngx_int_t (*ngx_stream_filter_pt)(ngx_stream_session_t *s, - ngx_chain_t *chain, ngx_uint_t from_upstream); - - -extern ngx_stream_filter_pt ngx_stream_top_filter; - - -#endif /* _NGX_STREAM_H_INCLUDED_ */ diff --git a/app/nginx/src/stream/ngx_stream_access_module.c b/app/nginx/src/stream/ngx_stream_access_module.c deleted file mode 100644 index 1745cdf..0000000 --- a/app/nginx/src/stream/ngx_stream_access_module.c +++ /dev/null @@ -1,459 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) Nginx, Inc. - */ - - -#include <ngx_config.h> -#include <ngx_core.h> -#include <ngx_stream.h> - - -typedef struct { - in_addr_t mask; - in_addr_t addr; - ngx_uint_t deny; /* unsigned deny:1; */ -} ngx_stream_access_rule_t; - -#if (NGX_HAVE_INET6) - -typedef struct { - struct in6_addr addr; - struct in6_addr mask; - ngx_uint_t deny; /* unsigned deny:1; */ -} ngx_stream_access_rule6_t; - -#endif - -#if (NGX_HAVE_UNIX_DOMAIN) - -typedef struct { - ngx_uint_t deny; /* unsigned deny:1; */ -} ngx_stream_access_rule_un_t; - -#endif - -typedef struct { - ngx_array_t *rules; /* array of ngx_stream_access_rule_t */ -#if (NGX_HAVE_INET6) - ngx_array_t *rules6; /* array of ngx_stream_access_rule6_t */ -#endif -#if (NGX_HAVE_UNIX_DOMAIN) - ngx_array_t *rules_un; /* array of ngx_stream_access_rule_un_t */ -#endif -} ngx_stream_access_srv_conf_t; - - -static ngx_int_t ngx_stream_access_handler(ngx_stream_session_t *s); -static ngx_int_t ngx_stream_access_inet(ngx_stream_session_t *s, - ngx_stream_access_srv_conf_t *ascf, in_addr_t addr); -#if (NGX_HAVE_INET6) -static ngx_int_t ngx_stream_access_inet6(ngx_stream_session_t *s, - ngx_stream_access_srv_conf_t *ascf, u_char *p); -#endif -#if (NGX_HAVE_UNIX_DOMAIN) -static ngx_int_t ngx_stream_access_unix(ngx_stream_session_t *s, - ngx_stream_access_srv_conf_t *ascf); -#endif -static ngx_int_t ngx_stream_access_found(ngx_stream_session_t *s, - ngx_uint_t deny); -static char *ngx_stream_access_rule(ngx_conf_t *cf, ngx_command_t *cmd, - void *conf); -static void *ngx_stream_access_create_srv_conf(ngx_conf_t *cf); -static char *ngx_stream_access_merge_srv_conf(ngx_conf_t *cf, - void *parent, void *child); -static ngx_int_t ngx_stream_access_init(ngx_conf_t *cf); - - -static ngx_command_t ngx_stream_access_commands[] = { - - { ngx_string("allow"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, - ngx_stream_access_rule, - NGX_STREAM_SRV_CONF_OFFSET, - 0, - NULL }, - - { ngx_string("deny"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, - ngx_stream_access_rule, - NGX_STREAM_SRV_CONF_OFFSET, - 0, - NULL }, - - ngx_null_command -}; - - - -static ngx_stream_module_t ngx_stream_access_module_ctx = { - NULL, /* preconfiguration */ - ngx_stream_access_init, /* postconfiguration */ - - NULL, /* create main configuration */ - NULL, /* init main configuration */ - - ngx_stream_access_create_srv_conf, /* create server configuration */ - ngx_stream_access_merge_srv_conf /* merge server configuration */ -}; - - -ngx_module_t ngx_stream_access_module = { - NGX_MODULE_V1, - &ngx_stream_access_module_ctx, /* module context */ - ngx_stream_access_commands, /* module directives */ - NGX_STREAM_MODULE, /* module type */ - NULL, /* init master */ - NULL, /* init module */ - NULL, /* init process */ - NULL, /* init thread */ - NULL, /* exit thread */ - NULL, /* exit process */ - NULL, /* exit master */ - NGX_MODULE_V1_PADDING -}; - - -static ngx_int_t -ngx_stream_access_handler(ngx_stream_session_t *s) -{ - struct sockaddr_in *sin; - ngx_stream_access_srv_conf_t *ascf; -#if (NGX_HAVE_INET6) - u_char *p; - in_addr_t addr; - struct sockaddr_in6 *sin6; -#endif - - ascf = ngx_stream_get_module_srv_conf(s, ngx_stream_access_module); - - switch (s->connection->sockaddr->sa_family) { - - case AF_INET: - if (ascf->rules) { - sin = (struct sockaddr_in *) s->connection->sockaddr; - return ngx_stream_access_inet(s, ascf, sin->sin_addr.s_addr); - } - break; - -#if (NGX_HAVE_INET6) - - case AF_INET6: - sin6 = (struct sockaddr_in6 *) s->connection->sockaddr; - p = sin6->sin6_addr.s6_addr; - - if (ascf->rules && IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { - addr = p[12] << 24; - addr += p[13] << 16; - addr += p[14] << 8; - addr += p[15]; - return ngx_stream_access_inet(s, ascf, htonl(addr)); - } - - if (ascf->rules6) { - return ngx_stream_access_inet6(s, ascf, p); - } - - break; - -#endif - -#if (NGX_HAVE_UNIX_DOMAIN) - - case AF_UNIX: - if (ascf->rules_un) { - return ngx_stream_access_unix(s, ascf); - } - - break; - -#endif - } - - return NGX_DECLINED; -} - - -static ngx_int_t -ngx_stream_access_inet(ngx_stream_session_t *s, - ngx_stream_access_srv_conf_t *ascf, in_addr_t addr) -{ - ngx_uint_t i; - ngx_stream_access_rule_t *rule; - - rule = ascf->rules->elts; - for (i = 0; i < ascf->rules->nelts; i++) { - - ngx_log_debug3(NGX_LOG_DEBUG_STREAM, s->connection->log, 0, - "access: %08XD %08XD %08XD", - addr, rule[i].mask, rule[i].addr); - - if ((addr & rule[i].mask) == rule[i].addr) { - return ngx_stream_access_found(s, rule[i].deny); - } - } - - return NGX_DECLINED; -} - - -#if (NGX_HAVE_INET6) - -static ngx_int_t -ngx_stream_access_inet6(ngx_stream_session_t *s, - ngx_stream_access_srv_conf_t *ascf, u_char *p) -{ - ngx_uint_t n; - ngx_uint_t i; - ngx_stream_access_rule6_t *rule6; - - rule6 = ascf->rules6->elts; - for (i = 0; i < ascf->rules6->nelts; i++) { - -#if (NGX_DEBUG) - { - size_t cl, ml, al; - u_char ct[NGX_INET6_ADDRSTRLEN]; - u_char mt[NGX_INET6_ADDRSTRLEN]; - u_char at[NGX_INET6_ADDRSTRLEN]; - - cl = ngx_inet6_ntop(p, ct, NGX_INET6_ADDRSTRLEN); - ml = ngx_inet6_ntop(rule6[i].mask.s6_addr, mt, NGX_INET6_ADDRSTRLEN); - al = ngx_inet6_ntop(rule6[i].addr.s6_addr, at, NGX_INET6_ADDRSTRLEN); - - ngx_log_debug6(NGX_LOG_DEBUG_STREAM, s->connection->log, 0, - "access: %*s %*s %*s", cl, ct, ml, mt, al, at); - } -#endif - - for (n = 0; n < 16; n++) { - if ((p[n] & rule6[i].mask.s6_addr[n]) != rule6[i].addr.s6_addr[n]) { - goto next; - } - } - - return ngx_stream_access_found(s, rule6[i].deny); - - next: - continue; - } - - return NGX_DECLINED; -} - -#endif - - -#if (NGX_HAVE_UNIX_DOMAIN) - -static ngx_int_t -ngx_stream_access_unix(ngx_stream_session_t *s, - ngx_stream_access_srv_conf_t *ascf) -{ - ngx_uint_t i; - ngx_stream_access_rule_un_t *rule_un; - - rule_un = ascf->rules_un->elts; - for (i = 0; i < ascf->rules_un->nelts; i++) { - - /* TODO: check path */ - if (1) { - return ngx_stream_access_found(s, rule_un[i].deny); - } - } - - return NGX_DECLINED; -} - -#endif - - -static ngx_int_t -ngx_stream_access_found(ngx_stream_session_t *s, ngx_uint_t deny) -{ - if (deny) { - ngx_log_error(NGX_LOG_ERR, s->connection->log, 0, - "access forbidden by rule"); - return NGX_STREAM_FORBIDDEN; - } - - return NGX_OK; -} - - -static char * -ngx_stream_access_rule(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) -{ - ngx_stream_access_srv_conf_t *ascf = conf; - - ngx_int_t rc; - ngx_uint_t all; - ngx_str_t *value; - ngx_cidr_t cidr; - ngx_stream_access_rule_t *rule; -#if (NGX_HAVE_INET6) - ngx_stream_access_rule6_t *rule6; -#endif -#if (NGX_HAVE_UNIX_DOMAIN) - ngx_stream_access_rule_un_t *rule_un; -#endif - - ngx_memzero(&cidr, sizeof(ngx_cidr_t)); - - value = cf->args->elts; - - all = (value[1].len == 3 && ngx_strcmp(value[1].data, "all") == 0); - - if (!all) { - -#if (NGX_HAVE_UNIX_DOMAIN) - - if (value[1].len == 5 && ngx_strcmp(value[1].data, "unix:") == 0) { - cidr.family = AF_UNIX; - rc = NGX_OK; - - } else { - rc = ngx_ptocidr(&value[1], &cidr); - } - -#else - rc = ngx_ptocidr(&value[1], &cidr); -#endif - - if (rc == NGX_ERROR) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "invalid parameter \"%V\"", &value[1]); - return NGX_CONF_ERROR; - } - - if (rc == NGX_DONE) { - ngx_conf_log_error(NGX_LOG_WARN, cf, 0, - "low address bits of %V are meaningless", &value[1]); - } - } - - if (cidr.family == AF_INET || all) { - - if (ascf->rules == NULL) { - ascf->rules = ngx_array_create(cf->pool, 4, - sizeof(ngx_stream_access_rule_t)); - if (ascf->rules == NULL) { - return NGX_CONF_ERROR; - } - } - - rule = ngx_array_push(ascf->rules); - if (rule == NULL) { - return NGX_CONF_ERROR; - } - - rule->mask = cidr.u.in.mask; - rule->addr = cidr.u.in.addr; - rule->deny = (value[0].data[0] == 'd') ? 1 : 0; - } - -#if (NGX_HAVE_INET6) - if (cidr.family == AF_INET6 || all) { - - if (ascf->rules6 == NULL) { - ascf->rules6 = ngx_array_create(cf->pool, 4, - sizeof(ngx_stream_access_rule6_t)); - if (ascf->rules6 == NULL) { - return NGX_CONF_ERROR; - } - } - - rule6 = ngx_array_push(ascf->rules6); - if (rule6 == NULL) { - return NGX_CONF_ERROR; - } - - rule6->mask = cidr.u.in6.mask; - rule6->addr = cidr.u.in6.addr; - rule6->deny = (value[0].data[0] == 'd') ? 1 : 0; - } -#endif - -#if (NGX_HAVE_UNIX_DOMAIN) - if (cidr.family == AF_UNIX || all) { - - if (ascf->rules_un == NULL) { - ascf->rules_un = ngx_array_create(cf->pool, 1, - sizeof(ngx_stream_access_rule_un_t)); - if (ascf->rules_un == NULL) { - return NGX_CONF_ERROR; - } - } - - rule_un = ngx_array_push(ascf->rules_un); - if (rule_un == NULL) { - return NGX_CONF_ERROR; - } - - rule_un->deny = (value[0].data[0] == 'd') ? 1 : 0; - } -#endif - - return NGX_CONF_OK; -} - - -static void * -ngx_stream_access_create_srv_conf(ngx_conf_t *cf) -{ - ngx_stream_access_srv_conf_t *conf; - - conf = ngx_pcalloc(cf->pool, sizeof(ngx_stream_access_srv_conf_t)); - if (conf == NULL) { - return NULL; - } - - return conf; -} - - -static char * -ngx_stream_access_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) -{ - ngx_stream_access_srv_conf_t *prev = parent; - ngx_stream_access_srv_conf_t *conf = child; - - if (conf->rules == NULL -#if (NGX_HAVE_INET6) - && conf->rules6 == NULL -#endif -#if (NGX_HAVE_UNIX_DOMAIN) - && conf->rules_un == NULL -#endif - ) { - conf->rules = prev->rules; -#if (NGX_HAVE_INET6) - conf->rules6 = prev->rules6; -#endif -#if (NGX_HAVE_UNIX_DOMAIN) - conf->rules_un = prev->rules_un; -#endif - } - - return NGX_CONF_OK; -} - - -static ngx_int_t -ngx_stream_access_init(ngx_conf_t *cf) -{ - ngx_stream_handler_pt *h; - ngx_stream_core_main_conf_t *cmcf; - - cmcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_core_module); - - h = ngx_array_push(&cmcf->phases[NGX_STREAM_ACCESS_PHASE].handlers); - if (h == NULL) { - return NGX_ERROR; - } - - *h = ngx_stream_access_handler; - - return NGX_OK; -} diff --git a/app/nginx/src/stream/ngx_stream_core_module.c b/app/nginx/src/stream/ngx_stream_core_module.c deleted file mode 100644 index f7870ee..0000000 --- a/app/nginx/src/stream/ngx_stream_core_module.c +++ /dev/null @@ -1,888 +0,0 @@ - -/* - * Copyright (C) Roman Arutyunyan - * Copyright (C) Nginx, Inc. - */ - - -#include <ngx_config.h> -#include <ngx_core.h> -#include <ngx_stream.h> - - -static ngx_int_t ngx_stream_core_preconfiguration(ngx_conf_t *cf); -static void *ngx_stream_core_create_main_conf(ngx_conf_t *cf); -static char *ngx_stream_core_init_main_conf(ngx_conf_t *cf, void *conf); -static void *ngx_stream_core_create_srv_conf(ngx_conf_t *cf); -static char *ngx_stream_core_merge_srv_conf(ngx_conf_t *cf, void *parent, - void *child); -static char *ngx_stream_core_error_log(ngx_conf_t *cf, ngx_command_t *cmd, - void *conf); -static char *ngx_stream_core_server(ngx_conf_t *cf, ngx_command_t *cmd, - void *conf); -static char *ngx_stream_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, - void *conf); -static char *ngx_stream_core_resolver(ngx_conf_t *cf, ngx_command_t *cmd, - void *conf); - - -static ngx_command_t ngx_stream_core_commands[] = { - - { ngx_string("variables_hash_max_size"), - NGX_STREAM_MAIN_CONF|NGX_CONF_TAKE1, - ngx_conf_set_num_slot, - NGX_STREAM_MAIN_CONF_OFFSET, - offsetof(ngx_stream_core_main_conf_t, variables_hash_max_size), - NULL }, - - { ngx_string("variables_hash_bucket_size"), - NGX_STREAM_MAIN_CONF|NGX_CONF_TAKE1, - ngx_conf_set_num_slot, - NGX_STREAM_MAIN_CONF_OFFSET, - offsetof(ngx_stream_core_main_conf_t, variables_hash_bucket_size), - NULL }, - - { ngx_string("server"), - NGX_STREAM_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS, - ngx_stream_core_server, - 0, - 0, - NULL }, - - { ngx_string("listen"), - NGX_STREAM_SRV_CONF|NGX_CONF_1MORE, - ngx_stream_core_listen, - NGX_STREAM_SRV_CONF_OFFSET, - 0, - NULL }, - - { ngx_string("error_log"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_1MORE, - ngx_stream_core_error_log, - NGX_STREAM_SRV_CONF_OFFSET, - 0, - NULL }, - - { ngx_string("resolver"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_1MORE, - ngx_stream_core_resolver, - NGX_STREAM_SRV_CONF_OFFSET, - 0, - NULL }, - - { ngx_string("resolver_timeout"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_msec_slot, - NGX_STREAM_SRV_CONF_OFFSET, - offsetof(ngx_stream_core_srv_conf_t, resolver_timeout), - NULL }, - - { ngx_string("proxy_protocol_timeout"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_msec_slot, - NGX_STREAM_SRV_CONF_OFFSET, - offsetof(ngx_stream_core_srv_conf_t, proxy_protocol_timeout), - NULL }, - - { ngx_string("tcp_nodelay"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG, - ngx_conf_set_flag_slot, - NGX_STREAM_SRV_CONF_OFFSET, - offsetof(ngx_stream_core_srv_conf_t, tcp_nodelay), - NULL }, - - { ngx_string("preread_buffer_size"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_size_slot, - NGX_STREAM_SRV_CONF_OFFSET, - offsetof(ngx_stream_core_srv_conf_t, preread_buffer_size), - NULL }, - - { ngx_string("preread_timeout"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_msec_slot, - NGX_STREAM_SRV_CONF_OFFSET, - offsetof(ngx_stream_core_srv_conf_t, preread_timeout), - NULL }, - - ngx_null_command -}; - - -static ngx_stream_module_t ngx_stream_core_module_ctx = { - ngx_stream_core_preconfiguration, /* preconfiguration */ - NULL, /* postconfiguration */ - - ngx_stream_core_create_main_conf, /* create main configuration */ - ngx_stream_core_init_main_conf, /* init main configuration */ - - ngx_stream_core_create_srv_conf, /* create server configuration */ - ngx_stream_core_merge_srv_conf /* merge server configuration */ -}; - - -ngx_module_t ngx_stream_core_module = { - NGX_MODULE_V1, - &ngx_stream_core_module_ctx, /* module context */ - ngx_stream_core_commands, /* module directives */ - NGX_STREAM_MODULE, /* module type */ - NULL, /* init master */ - NULL, /* init module */ - NULL, /* init process */ - NULL, /* init thread */ - NULL, /* exit thread */ - NULL, /* exit process */ - NULL, /* exit master */ - NGX_MODULE_V1_PADDING -}; - - -void -ngx_stream_core_run_phases(ngx_stream_session_t *s) -{ - ngx_int_t rc; - ngx_stream_phase_handler_t *ph; - ngx_stream_core_main_conf_t *cmcf; - - cmcf = ngx_stream_get_module_main_conf(s, ngx_stream_core_module); - - ph = cmcf->phase_engine.handlers; - - while (ph[s->phase_handler].checker) { - - rc = ph[s->phase_handler].checker(s, &ph[s->phase_handler]); - - if (rc == NGX_OK) { - return; - } - } -} - - -ngx_int_t -ngx_stream_core_generic_phase(ngx_stream_session_t *s, - ngx_stream_phase_handler_t *ph) -{ - ngx_int_t rc; - - /* - * generic phase checker, - * used by all phases, except for preread and content - */ - - ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0, - "generic phase: %ui", s->phase_handler); - - rc = ph->handler(s); - - if (rc == NGX_OK) { - s->phase_handler = ph->next; - return NGX_AGAIN; - } - - if (rc == NGX_DECLINED) { - s->phase_handler++; - return NGX_AGAIN; - } - - if (rc == NGX_AGAIN || rc == NGX_DONE) { - return NGX_OK; - } - - if (rc == NGX_ERROR) { - rc = NGX_STREAM_INTERNAL_SERVER_ERROR; - } - - ngx_stream_finalize_session(s, rc); - - return NGX_OK; -} - - -ngx_int_t -ngx_stream_core_preread_phase(ngx_stream_session_t *s, - ngx_stream_phase_handler_t *ph) -{ - size_t size; - ssize_t n; - ngx_int_t rc; - ngx_connection_t *c; - ngx_stream_core_srv_conf_t *cscf; - - c = s->connection; - - c->log->action = "prereading client data"; - - cscf = ngx_stream_get_module_srv_conf(s, ngx_stream_core_module); - - if (c->read->timedout) { - rc = NGX_STREAM_OK; - - } else if (c->read->timer_set) { - rc = NGX_AGAIN; - - } else { - rc = ph->handler(s); - } - - while (rc == NGX_AGAIN) { - - if (c->buffer == NULL) { - c->buffer = ngx_create_temp_buf(c->pool, cscf->preread_buffer_size); - if (c->buffer == NULL) { - rc = NGX_ERROR; - break; - } - } - - size = c->buffer->end - c->buffer->last; - - if (size == 0) { - ngx_log_error(NGX_LOG_ERR, c->log, 0, "preread buffer full"); - rc = NGX_STREAM_BAD_REQUEST; - break; - } - - if (c->read->eof) { - rc = NGX_STREAM_OK; - break; - } - - if (!c->read->ready) { - if (ngx_handle_read_event(c->read, 0) != NGX_OK) { - rc = NGX_ERROR; - break; - } - - if (!c->read->timer_set) { - ngx_add_timer(c->read, cscf->preread_timeout); - } - - c->read->handler = ngx_stream_session_handler; - - return NGX_OK; - } - - n = c->recv(c, c->buffer->last, size); - - if (n == NGX_ERROR) { - rc = NGX_STREAM_OK; - break; - } - - if (n > 0) { - c->buffer->last += n; - } - - rc = ph->handler(s); - } - - if (c->read->timer_set) { - ngx_del_timer(c->read); - } - - if (rc == NGX_OK) { - s->phase_handler = ph->next; - return NGX_AGAIN; - } - - if (rc == NGX_DECLINED) { - s->phase_handler++; - return NGX_AGAIN; - } - - if (rc == NGX_DONE) { - return NGX_OK; - } - - if (rc == NGX_ERROR) { - rc = NGX_STREAM_INTERNAL_SERVER_ERROR; - } - - ngx_stream_finalize_session(s, rc); - - return NGX_OK; -} - - -ngx_int_t -ngx_stream_core_content_phase(ngx_stream_session_t *s, - ngx_stream_phase_handler_t *ph) -{ - int tcp_nodelay; - ngx_connection_t *c; - ngx_stream_core_srv_conf_t *cscf; - - c = s->connection; - - c->log->action = NULL; - - cscf = ngx_stream_get_module_srv_conf(s, ngx_stream_core_module); - - if (c->type == SOCK_STREAM - && cscf->tcp_nodelay - && c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) - { - ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0, "tcp_nodelay"); - - tcp_nodelay = 1; - - if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY, - (const void *) &tcp_nodelay, sizeof(int)) == -1) - { - ngx_connection_error(c, ngx_socket_errno, - "setsockopt(TCP_NODELAY) failed"); - ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR); - return NGX_OK; - } - - c->tcp_nodelay = NGX_TCP_NODELAY_SET; - } - - cscf->handler(s); - - return NGX_OK; -} - - -static ngx_int_t -ngx_stream_core_preconfiguration(ngx_conf_t *cf) -{ - return ngx_stream_variables_add_core_vars(cf); -} - - -static void * -ngx_stream_core_create_main_conf(ngx_conf_t *cf) -{ - ngx_stream_core_main_conf_t *cmcf; - - cmcf = ngx_pcalloc(cf->pool, sizeof(ngx_stream_core_main_conf_t)); - if (cmcf == NULL) { - return NULL; - } - - if (ngx_array_init(&cmcf->servers, cf->pool, 4, - sizeof(ngx_stream_core_srv_conf_t *)) - != NGX_OK) - { - return NULL; - } - - if (ngx_array_init(&cmcf->listen, cf->pool, 4, sizeof(ngx_stream_listen_t)) - != NGX_OK) - { - return NULL; - } - - cmcf->variables_hash_max_size = NGX_CONF_UNSET_UINT; - cmcf->variables_hash_bucket_size = NGX_CONF_UNSET_UINT; - - return cmcf; -} - - -static char * -ngx_stream_core_init_main_conf(ngx_conf_t *cf, void *conf) -{ - ngx_stream_core_main_conf_t *cmcf = conf; - - ngx_conf_init_uint_value(cmcf->variables_hash_max_size, 1024); - ngx_conf_init_uint_value(cmcf->variables_hash_bucket_size, 64); - - cmcf->variables_hash_bucket_size = - ngx_align(cmcf->variables_hash_bucket_size, ngx_cacheline_size); - - if (cmcf->ncaptures) { - cmcf->ncaptures = (cmcf->ncaptures + 1) * 3; - } - - return NGX_CONF_OK; -} - - -static void * -ngx_stream_core_create_srv_conf(ngx_conf_t *cf) -{ - ngx_stream_core_srv_conf_t *cscf; - - cscf = ngx_pcalloc(cf->pool, sizeof(ngx_stream_core_srv_conf_t)); - if (cscf == NULL) { - return NULL; - } - - /* - * set by ngx_pcalloc(): - * - * cscf->handler = NULL; - * cscf->error_log = NULL; - */ - - cscf->file_name = cf->conf_file->file.name.data; - cscf->line = cf->conf_file->line; - cscf->resolver_timeout = NGX_CONF_UNSET_MSEC; - cscf->proxy_protocol_timeout = NGX_CONF_UNSET_MSEC; - cscf->tcp_nodelay = NGX_CONF_UNSET; - cscf->preread_buffer_size = NGX_CONF_UNSET_SIZE; - cscf->preread_timeout = NGX_CONF_UNSET_MSEC; - - return cscf; -} - - -static char * -ngx_stream_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) -{ - ngx_stream_core_srv_conf_t *prev = parent; - ngx_stream_core_srv_conf_t *conf = child; - - ngx_conf_merge_msec_value(conf->resolver_timeout, - prev->resolver_timeout, 30000); - - if (conf->resolver == NULL) { - - if (prev->resolver == NULL) { - - /* - * create dummy resolver in stream {} context - * to inherit it in all servers - */ - - prev->resolver = ngx_resolver_create(cf, NULL, 0); - if (prev->resolver == NULL) { - return NGX_CONF_ERROR; - } - } - - conf->resolver = prev->resolver; - } - - if (conf->handler == NULL) { - ngx_log_error(NGX_LOG_EMERG, cf->log, 0, - "no handler for server in %s:%ui", - conf->file_name, conf->line); - return NGX_CONF_ERROR; - } - - if (conf->error_log == NULL) { - if (prev->error_log) { - conf->error_log = prev->error_log; - } else { - conf->error_log = &cf->cycle->new_log; - } - } - - ngx_conf_merge_msec_value(conf->proxy_protocol_timeout, - prev->proxy_protocol_timeout, 30000); - - ngx_conf_merge_value(conf->tcp_nodelay, prev->tcp_nodelay, 1); - - ngx_conf_merge_size_value(conf->preread_buffer_size, - prev->preread_buffer_size, 16384); - - ngx_conf_merge_msec_value(conf->preread_timeout, - prev->preread_timeout, 30000); - - return NGX_CONF_OK; -} - - -static char * -ngx_stream_core_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) -{ - ngx_stream_core_srv_conf_t *cscf = conf; - - return ngx_log_set_log(cf, &cscf->error_log); -} - - -static char * -ngx_stream_core_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) -{ - char *rv; - void *mconf; - ngx_uint_t m; - ngx_conf_t pcf; - ngx_stream_module_t *module; - ngx_stream_conf_ctx_t *ctx, *stream_ctx; - ngx_stream_core_srv_conf_t *cscf, **cscfp; - ngx_stream_core_main_conf_t *cmcf; - - ctx = ngx_pcalloc(cf->pool, sizeof(ngx_stream_conf_ctx_t)); - if (ctx == NULL) { - return NGX_CONF_ERROR; - } - - stream_ctx = cf->ctx; - ctx->main_conf = stream_ctx->main_conf; - - /* the server{}'s srv_conf */ - - ctx->srv_conf = ngx_pcalloc(cf->pool, - sizeof(void *) * ngx_stream_max_module); - if (ctx->srv_conf == NULL) { - return NGX_CONF_ERROR; - } - - for (m = 0; cf->cycle->modules[m]; m++) { - if (cf->cycle->modules[m]->type != NGX_STREAM_MODULE) { - continue; - } - - module = cf->cycle->modules[m]->ctx; - - if (module->create_srv_conf) { - mconf = module->create_srv_conf(cf); - if (mconf == NULL) { - return NGX_CONF_ERROR; - } - - ctx->srv_conf[cf->cycle->modules[m]->ctx_index] = mconf; - } - } - - /* the server configuration context */ - - cscf = ctx->srv_conf[ngx_stream_core_module.ctx_index]; - cscf->ctx = ctx; - - cmcf = ctx->main_conf[ngx_stream_core_module.ctx_index]; - - cscfp = ngx_array_push(&cmcf->servers); - if (cscfp == NULL) { - return NGX_CONF_ERROR; - } - - *cscfp = cscf; - - - /* parse inside server{} */ - - pcf = *cf; - cf->ctx = ctx; - cf->cmd_type = NGX_STREAM_SRV_CONF; - - rv = ngx_conf_parse(cf, NULL); - - *cf = pcf; - - if (rv == NGX_CONF_OK && !cscf->listen) { - ngx_log_error(NGX_LOG_EMERG, cf->log, 0, - "no \"listen\" is defined for server in %s:%ui", - cscf->file_name, cscf->line); - return NGX_CONF_ERROR; - } - - return rv; -} - - -static char * -ngx_stream_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) -{ - ngx_stream_core_srv_conf_t *cscf = conf; - - ngx_str_t *value; - ngx_url_t u; - ngx_uint_t i, backlog; - ngx_stream_listen_t *ls, *als; - ngx_stream_core_main_conf_t *cmcf; - - cscf->listen = 1; - - value = cf->args->elts; - - ngx_memzero(&u, sizeof(ngx_url_t)); - - u.url = value[1]; - u.listen = 1; - - if (ngx_parse_url(cf->pool, &u) != NGX_OK) { - if (u.err) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "%s in \"%V\" of the \"listen\" directive", - u.err, &u.url); - } - - return NGX_CONF_ERROR; - } - - cmcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_core_module); - - ls = ngx_array_push(&cmcf->listen); - if (ls == NULL) { - return NGX_CONF_ERROR; - } - - ngx_memzero(ls, sizeof(ngx_stream_listen_t)); - - ngx_memcpy(&ls->sockaddr.sockaddr, &u.sockaddr, u.socklen); - - ls->socklen = u.socklen; - ls->backlog = NGX_LISTEN_BACKLOG; - ls->type = SOCK_STREAM; - ls->wildcard = u.wildcard; - ls->ctx = cf->ctx; - -#if (NGX_HAVE_INET6) - ls->ipv6only = 1; -#endif - - backlog = 0; - - for (i = 2; i < cf->args->nelts; i++) { - -#if !(NGX_WIN32) - if (ngx_strcmp(value[i].data, "udp") == 0) { - ls->type = SOCK_DGRAM; - continue; - } -#endif - - if (ngx_strcmp(value[i].data, "bind") == 0) { - ls->bind = 1; - continue; - } - - if (ngx_strncmp(value[i].data, "backlog=", 8) == 0) { - ls->backlog = ngx_atoi(value[i].data + 8, value[i].len - 8); - ls->bind = 1; - - if (ls->backlog == NGX_ERROR || ls->backlog == 0) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "invalid backlog \"%V\"", &value[i]); - return NGX_CONF_ERROR; - } - - backlog = 1; - - continue; - } - - if (ngx_strncmp(value[i].data, "ipv6only=o", 10) == 0) { -#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) - size_t len; - u_char buf[NGX_SOCKADDR_STRLEN]; - - if (ls->sockaddr.sockaddr.sa_family == AF_INET6) { - - if (ngx_strcmp(&value[i].data[10], "n") == 0) { - ls->ipv6only = 1; - - } else if (ngx_strcmp(&value[i].data[10], "ff") == 0) { - ls->ipv6only = 0; - - } else { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "invalid ipv6only flags \"%s\"", - &value[i].data[9]); - return NGX_CONF_ERROR; - } - - ls->bind = 1; - - } else { - len = ngx_sock_ntop(&ls->sockaddr.sockaddr, ls->socklen, buf, - NGX_SOCKADDR_STRLEN, 1); - - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "ipv6only is not supported " - "on addr \"%*s\", ignored", len, buf); - } - - continue; -#else - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "bind ipv6only is not supported " - "on this platform"); - return NGX_CONF_ERROR; -#endif - } - - if (ngx_strcmp(value[i].data, "reuseport") == 0) { -#if (NGX_HAVE_REUSEPORT) - ls->reuseport = 1; - ls->bind = 1; -#else - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "reuseport is not supported " - "on this platform, ignored"); -#endif - continue; - } - - if (ngx_strcmp(value[i].data, "ssl") == 0) { -#if (NGX_STREAM_SSL) - ls->ssl = 1; - continue; -#else - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "the \"ssl\" parameter requires " - "ngx_stream_ssl_module"); - return NGX_CONF_ERROR; -#endif - } - - if (ngx_strncmp(value[i].data, "so_keepalive=", 13) == 0) { - - if (ngx_strcmp(&value[i].data[13], "on") == 0) { - ls->so_keepalive = 1; - - } else if (ngx_strcmp(&value[i].data[13], "off") == 0) { - ls->so_keepalive = 2; - - } else { - -#if (NGX_HAVE_KEEPALIVE_TUNABLE) - u_char *p, *end; - ngx_str_t s; - - end = value[i].data + value[i].len; - s.data = value[i].data + 13; - - p = ngx_strlchr(s.data, end, ':'); - if (p == NULL) { - p = end; - } - - if (p > s.data) { - s.len = p - s.data; - - ls->tcp_keepidle = ngx_parse_time(&s, 1); - if (ls->tcp_keepidle == (time_t) NGX_ERROR) { - goto invalid_so_keepalive; - } - } - - s.data = (p < end) ? (p + 1) : end; - - p = ngx_strlchr(s.data, end, ':'); - if (p == NULL) { - p = end; - } - - if (p > s.data) { - s.len = p - s.data; - - ls->tcp_keepintvl = ngx_parse_time(&s, 1); - if (ls->tcp_keepintvl == (time_t) NGX_ERROR) { - goto invalid_so_keepalive; - } - } - - s.data = (p < end) ? (p + 1) : end; - - if (s.data < end) { - s.len = end - s.data; - - ls->tcp_keepcnt = ngx_atoi(s.data, s.len); - if (ls->tcp_keepcnt == NGX_ERROR) { - goto invalid_so_keepalive; - } - } - - if (ls->tcp_keepidle == 0 && ls->tcp_keepintvl == 0 - && ls->tcp_keepcnt == 0) - { - goto invalid_so_keepalive; - } - - ls->so_keepalive = 1; - -#else - - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "the \"so_keepalive\" parameter accepts " - "only \"on\" or \"off\" on this platform"); - return NGX_CONF_ERROR; - -#endif - } - - ls->bind = 1; - - continue; - -#if (NGX_HAVE_KEEPALIVE_TUNABLE) - invalid_so_keepalive: - - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "invalid so_keepalive value: \"%s\"", - &value[i].data[13]); - return NGX_CONF_ERROR; -#endif - } - - if (ngx_strcmp(value[i].data, "proxy_protocol") == 0) { - ls->proxy_protocol = 1; - continue; - } - - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "the invalid \"%V\" parameter", &value[i]); - return NGX_CONF_ERROR; - } - - if (ls->type == SOCK_DGRAM) { - if (backlog) { - return "\"backlog\" parameter is incompatible with \"udp\""; - } - -#if (NGX_STREAM_SSL) - if (ls->ssl) { - return "\"ssl\" parameter is incompatible with \"udp\""; - } -#endif - - if (ls->so_keepalive) { - return "\"so_keepalive\" parameter is incompatible with \"udp\""; - } - - if (ls->proxy_protocol) { - return "\"proxy_protocol\" parameter is incompatible with \"udp\""; - } - } - - als = cmcf->listen.elts; - - for (i = 0; i < cmcf->listen.nelts - 1; i++) { - if (ls->type != als[i].type) { - continue; - } - - if (ngx_cmp_sockaddr(&als[i].sockaddr.sockaddr, als[i].socklen, - &ls->sockaddr.sockaddr, ls->socklen, 1) - != NGX_OK) - { - continue; - } - - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "duplicate \"%V\" address and port pair", &u.url); - return NGX_CONF_ERROR; - } - - return NGX_CONF_OK; -} - - -static char * -ngx_stream_core_resolver(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) -{ - ngx_stream_core_srv_conf_t *cscf = conf; - - ngx_str_t *value; - - if (cscf->resolver) { - return "is duplicate"; - } - - value = cf->args->elts; - - cscf->resolver = ngx_resolver_create(cf, &value[1], cf->args->nelts - 1); - if (cscf->resolver == NULL) { - return NGX_CONF_ERROR; - } - - return NGX_CONF_OK; -} diff --git a/app/nginx/src/stream/ngx_stream_geo_module.c b/app/nginx/src/stream/ngx_stream_geo_module.c deleted file mode 100644 index 2204546..0000000 --- a/app/nginx/src/stream/ngx_stream_geo_module.c +++ /dev/null @@ -1,1586 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) Nginx, Inc. - */ - - -#include <ngx_config.h> -#include <ngx_core.h> -#include <ngx_stream.h> - - -typedef struct { - ngx_stream_variable_value_t *value; - u_short start; - u_short end; -} ngx_stream_geo_range_t; - - -typedef struct { - ngx_radix_tree_t *tree; -#if (NGX_HAVE_INET6) - ngx_radix_tree_t *tree6; -#endif -} ngx_stream_geo_trees_t; - - -typedef struct { - ngx_stream_geo_range_t **low; - ngx_stream_variable_value_t *default_value; -} ngx_stream_geo_high_ranges_t; - - -typedef struct { - ngx_str_node_t sn; - ngx_stream_variable_value_t *value; - size_t offset; -} ngx_stream_geo_variable_value_node_t; - - -typedef struct { - ngx_stream_variable_value_t *value; - ngx_str_t *net; - ngx_stream_geo_high_ranges_t high; - ngx_radix_tree_t *tree; -#if (NGX_HAVE_INET6) - ngx_radix_tree_t *tree6; -#endif - ngx_rbtree_t rbtree; - ngx_rbtree_node_t sentinel; - ngx_pool_t *pool; - ngx_pool_t *temp_pool; - - size_t data_size; - - ngx_str_t include_name; - ngx_uint_t includes; - ngx_uint_t entries; - - unsigned ranges:1; - unsigned outside_entries:1; - unsigned allow_binary_include:1; - unsigned binary_include:1; -} ngx_stream_geo_conf_ctx_t; - - -typedef struct { - union { - ngx_stream_geo_trees_t trees; - ngx_stream_geo_high_ranges_t high; - } u; - - ngx_int_t index; -} ngx_stream_geo_ctx_t; - - -static ngx_int_t ngx_stream_geo_addr(ngx_stream_session_t *s, - ngx_stream_geo_ctx_t *ctx, ngx_addr_t *addr); - -static char *ngx_stream_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, - void *conf); -static char *ngx_stream_geo(ngx_conf_t *cf, ngx_command_t *dummy, void *conf); -static char *ngx_stream_geo_range(ngx_conf_t *cf, - ngx_stream_geo_conf_ctx_t *ctx, ngx_str_t *value); -static char *ngx_stream_geo_add_range(ngx_conf_t *cf, - ngx_stream_geo_conf_ctx_t *ctx, in_addr_t start, in_addr_t end); -static ngx_uint_t ngx_stream_geo_delete_range(ngx_conf_t *cf, - ngx_stream_geo_conf_ctx_t *ctx, in_addr_t start, in_addr_t end); -static char *ngx_stream_geo_cidr(ngx_conf_t *cf, - ngx_stream_geo_conf_ctx_t *ctx, ngx_str_t *value); -static char *ngx_stream_geo_cidr_add(ngx_conf_t *cf, - ngx_stream_geo_conf_ctx_t *ctx, ngx_cidr_t *cidr, ngx_str_t *value, - ngx_str_t *net); -static ngx_stream_variable_value_t *ngx_stream_geo_value(ngx_conf_t *cf, - ngx_stream_geo_conf_ctx_t *ctx, ngx_str_t *value); -static ngx_int_t ngx_stream_geo_cidr_value(ngx_conf_t *cf, ngx_str_t *net, - ngx_cidr_t *cidr); -static char *ngx_stream_geo_include(ngx_conf_t *cf, - ngx_stream_geo_conf_ctx_t *ctx, ngx_str_t *name); -static ngx_int_t ngx_stream_geo_include_binary_base(ngx_conf_t *cf, - ngx_stream_geo_conf_ctx_t *ctx, ngx_str_t *name); -static void ngx_stream_geo_create_binary_base(ngx_stream_geo_conf_ctx_t *ctx); -static u_char *ngx_stream_geo_copy_values(u_char *base, u_char *p, - ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel); - - -static ngx_command_t ngx_stream_geo_commands[] = { - - { ngx_string("geo"), - NGX_STREAM_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE12, - ngx_stream_geo_block, - 0, - 0, - NULL }, - - ngx_null_command -}; - - -static ngx_stream_module_t ngx_stream_geo_module_ctx = { - NULL, /* preconfiguration */ - NULL, /* postconfiguration */ - - NULL, /* create main configuration */ - NULL, /* init main configuration */ - - NULL, /* create server configuration */ - NULL /* merge server configuration */ -}; - - -ngx_module_t ngx_stream_geo_module = { - NGX_MODULE_V1, - &ngx_stream_geo_module_ctx, /* module context */ - ngx_stream_geo_commands, /* module directives */ - NGX_STREAM_MODULE, /* module type */ - NULL, /* init master */ - NULL, /* init module */ - NULL, /* init process */ - NULL, /* init thread */ - NULL, /* exit thread */ - NULL, /* exit process */ - NULL, /* exit master */ - NGX_MODULE_V1_PADDING -}; - - -typedef struct { - u_char GEORNG[6]; - u_char version; - u_char ptr_size; - uint32_t endianness; - uint32_t crc32; -} ngx_stream_geo_header_t; - - -static ngx_stream_geo_header_t ngx_stream_geo_header = { - { 'G', 'E', 'O', 'R', 'N', 'G' }, 0, sizeof(void *), 0x12345678, 0 -}; - - -/* geo range is AF_INET only */ - -static ngx_int_t -ngx_stream_geo_cidr_variable(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data) -{ - ngx_stream_geo_ctx_t *ctx = (ngx_stream_geo_ctx_t *) data; - - in_addr_t inaddr; - ngx_addr_t addr; - struct sockaddr_in *sin; - ngx_stream_variable_value_t *vv; -#if (NGX_HAVE_INET6) - u_char *p; - struct in6_addr *inaddr6; -#endif - - if (ngx_stream_geo_addr(s, ctx, &addr) != NGX_OK) { - vv = (ngx_stream_variable_value_t *) - ngx_radix32tree_find(ctx->u.trees.tree, INADDR_NONE); - goto done; - } - - switch (addr.sockaddr->sa_family) { - -#if (NGX_HAVE_INET6) - case AF_INET6: - inaddr6 = &((struct sockaddr_in6 *) addr.sockaddr)->sin6_addr; - p = inaddr6->s6_addr; - - if (IN6_IS_ADDR_V4MAPPED(inaddr6)) { - inaddr = p[12] << 24; - inaddr += p[13] << 16; - inaddr += p[14] << 8; - inaddr += p[15]; - - vv = (ngx_stream_variable_value_t *) - ngx_radix32tree_find(ctx->u.trees.tree, inaddr); - - } else { - vv = (ngx_stream_variable_value_t *) - ngx_radix128tree_find(ctx->u.trees.tree6, p); - } - - break; -#endif - - default: /* AF_INET */ - sin = (struct sockaddr_in *) addr.sockaddr; - inaddr = ntohl(sin->sin_addr.s_addr); - - vv = (ngx_stream_variable_value_t *) - ngx_radix32tree_find(ctx->u.trees.tree, inaddr); - - break; - } - -done: - - *v = *vv; - - ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0, - "stream geo: %v", v); - - return NGX_OK; -} - - -static ngx_int_t -ngx_stream_geo_range_variable(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data) -{ - ngx_stream_geo_ctx_t *ctx = (ngx_stream_geo_ctx_t *) data; - - in_addr_t inaddr; - ngx_addr_t addr; - ngx_uint_t n; - struct sockaddr_in *sin; - ngx_stream_geo_range_t *range; -#if (NGX_HAVE_INET6) - u_char *p; - struct in6_addr *inaddr6; -#endif - - *v = *ctx->u.high.default_value; - - if (ngx_stream_geo_addr(s, ctx, &addr) == NGX_OK) { - - switch (addr.sockaddr->sa_family) { - -#if (NGX_HAVE_INET6) - case AF_INET6: - inaddr6 = &((struct sockaddr_in6 *) addr.sockaddr)->sin6_addr; - - if (IN6_IS_ADDR_V4MAPPED(inaddr6)) { - p = inaddr6->s6_addr; - - inaddr = p[12] << 24; - inaddr += p[13] << 16; - inaddr += p[14] << 8; - inaddr += p[15]; - - } else { - inaddr = INADDR_NONE; - } - - break; -#endif - - default: /* AF_INET */ - sin = (struct sockaddr_in *) addr.sockaddr; - inaddr = ntohl(sin->sin_addr.s_addr); - break; - } - - } else { - inaddr = INADDR_NONE; - } - - if (ctx->u.high.low) { - range = ctx->u.high.low[inaddr >> 16]; - - if (range) { - n = inaddr & 0xffff; - do { - if (n >= (ngx_uint_t) range->start - && n <= (ngx_uint_t) range->end) - { - *v = *range->value; - break; - } - } while ((++range)->value); - } - } - - ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0, - "stream geo: %v", v); - - return NGX_OK; -} - - -static ngx_int_t -ngx_stream_geo_addr(ngx_stream_session_t *s, ngx_stream_geo_ctx_t *ctx, - ngx_addr_t *addr) -{ - ngx_stream_variable_value_t *v; - - if (ctx->index == -1) { - ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0, - "stream geo started: %V", &s->connection->addr_text); - - addr->sockaddr = s->connection->sockaddr; - addr->socklen = s->connection->socklen; - /* addr->name = s->connection->addr_text; */ - - return NGX_OK; - } - - v = ngx_stream_get_flushed_variable(s, ctx->index); - - if (v == NULL || v->not_found) { - ngx_log_debug0(NGX_LOG_DEBUG_STREAM, s->connection->log, 0, - "stream geo not found"); - - return NGX_ERROR; - } - - ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0, - "stream geo started: %v", v); - - if (ngx_parse_addr(s->connection->pool, addr, v->data, v->len) == NGX_OK) { - return NGX_OK; - } - - return NGX_ERROR; -} - - -static char * -ngx_stream_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) -{ - char *rv; - size_t len; - ngx_str_t *value, name; - ngx_uint_t i; - ngx_conf_t save; - ngx_pool_t *pool; - ngx_array_t *a; - ngx_stream_variable_t *var; - ngx_stream_geo_ctx_t *geo; - ngx_stream_geo_conf_ctx_t ctx; -#if (NGX_HAVE_INET6) - static struct in6_addr zero; -#endif - - value = cf->args->elts; - - geo = ngx_palloc(cf->pool, sizeof(ngx_stream_geo_ctx_t)); - if (geo == NULL) { - return NGX_CONF_ERROR; - } - - name = value[1]; - - if (name.data[0] != '$') { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "invalid variable name \"%V\"", &name); - return NGX_CONF_ERROR; - } - - name.len--; - name.data++; - - if (cf->args->nelts == 3) { - - geo->index = ngx_stream_get_variable_index(cf, &name); - if (geo->index == NGX_ERROR) { - return NGX_CONF_ERROR; - } - - name = value[2]; - - if (name.data[0] != '$') { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "invalid variable name \"%V\"", &name); - return NGX_CONF_ERROR; - } - - name.len--; - name.data++; - - } else { - geo->index = -1; - } - - var = ngx_stream_add_variable(cf, &name, NGX_STREAM_VAR_CHANGEABLE); - if (var == NULL) { - return NGX_CONF_ERROR; - } - - pool = ngx_create_pool(NGX_DEFAULT_POOL_SIZE, cf->log); - if (pool == NULL) { - return NGX_CONF_ERROR; - } - - ngx_memzero(&ctx, sizeof(ngx_stream_geo_conf_ctx_t)); - - ctx.temp_pool = ngx_create_pool(NGX_DEFAULT_POOL_SIZE, cf->log); - if (ctx.temp_pool == NULL) { - return NGX_CONF_ERROR; - } - - ngx_rbtree_init(&ctx.rbtree, &ctx.sentinel, ngx_str_rbtree_insert_value); - - ctx.pool = cf->pool; - ctx.data_size = sizeof(ngx_stream_geo_header_t) - + sizeof(ngx_stream_variable_value_t) - + 0x10000 * sizeof(ngx_stream_geo_range_t *); - ctx.allow_binary_include = 1; - - save = *cf; - cf->pool = pool; - cf->ctx = &ctx; - cf->handler = ngx_stream_geo; - cf->handler_conf = conf; - - rv = ngx_conf_parse(cf, NULL); - - *cf = save; - - if (ctx.ranges) { - - if (ctx.high.low && !ctx.binary_include) { - for (i = 0; i < 0x10000; i++) { - a = (ngx_array_t *) ctx.high.low[i]; - - if (a == NULL) { - continue; - } - - if (a->nelts == 0) { - ctx.high.low[i] = NULL; - continue; - } - - len = a->nelts * sizeof(ngx_stream_geo_range_t); - - ctx.high.low[i] = ngx_palloc(cf->pool, len + sizeof(void *)); - if (ctx.high.low[i] == NULL) { - return NGX_CONF_ERROR; - } - - ngx_memcpy(ctx.high.low[i], a->elts, len); - ctx.high.low[i][a->nelts].value = NULL; - ctx.data_size += len + sizeof(void *); - } - - if (ctx.allow_binary_include - && !ctx.outside_entries - && ctx.entries > 100000 - && ctx.includes == 1) - { - ngx_stream_geo_create_binary_base(&ctx); - } - } - - if (ctx.high.default_value == NULL) { - ctx.high.default_value = &ngx_stream_variable_null_value; - } - - geo->u.high = ctx.high; - - var->get_handler = ngx_stream_geo_range_variable; - var->data = (uintptr_t) geo; - - ngx_destroy_pool(ctx.temp_pool); - ngx_destroy_pool(pool); - - } else { - if (ctx.tree == NULL) { - ctx.tree = ngx_radix_tree_create(cf->pool, -1); - if (ctx.tree == NULL) { - return NGX_CONF_ERROR; - } - } - - geo->u.trees.tree = ctx.tree; - -#if (NGX_HAVE_INET6) - if (ctx.tree6 == NULL) { - ctx.tree6 = ngx_radix_tree_create(cf->pool, -1); - if (ctx.tree6 == NULL) { - return NGX_CONF_ERROR; - } - } - - geo->u.trees.tree6 = ctx.tree6; -#endif - - var->get_handler = ngx_stream_geo_cidr_variable; - var->data = (uintptr_t) geo; - - ngx_destroy_pool(ctx.temp_pool); - ngx_destroy_pool(pool); - - if (ngx_radix32tree_insert(ctx.tree, 0, 0, - (uintptr_t) &ngx_stream_variable_null_value) - == NGX_ERROR) - { - return NGX_CONF_ERROR; - } - - /* NGX_BUSY is okay (default was set explicitly) */ - -#if (NGX_HAVE_INET6) - if (ngx_radix128tree_insert(ctx.tree6, zero.s6_addr, zero.s6_addr, - (uintptr_t) &ngx_stream_variable_null_value) - == NGX_ERROR) - { - return NGX_CONF_ERROR; - } -#endif - } - - return rv; -} - - -static char * -ngx_stream_geo(ngx_conf_t *cf, ngx_command_t *dummy, void *conf) -{ - char *rv; - ngx_str_t *value; - ngx_stream_geo_conf_ctx_t *ctx; - - ctx = cf->ctx; - - value = cf->args->elts; - - if (cf->args->nelts == 1) { - - if (ngx_strcmp(value[0].data, "ranges") == 0) { - - if (ctx->tree -#if (NGX_HAVE_INET6) - || ctx->tree6 -#endif - ) - { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "the \"ranges\" directive must be " - "the first directive inside \"geo\" block"); - goto failed; - } - - ctx->ranges = 1; - - rv = NGX_CONF_OK; - - goto done; - } - } - - if (cf->args->nelts != 2) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "invalid number of the geo parameters"); - goto failed; - } - - if (ngx_strcmp(value[0].data, "include") == 0) { - - rv = ngx_stream_geo_include(cf, ctx, &value[1]); - - goto done; - } - - if (ctx->ranges) { - rv = ngx_stream_geo_range(cf, ctx, value); - - } else { - rv = ngx_stream_geo_cidr(cf, ctx, value); - } - -done: - - ngx_reset_pool(cf->pool); - - return rv; - -failed: - - ngx_reset_pool(cf->pool); - - return NGX_CONF_ERROR; -} - - -static char * -ngx_stream_geo_range(ngx_conf_t *cf, ngx_stream_geo_conf_ctx_t *ctx, - ngx_str_t *value) -{ - u_char *p, *last; - in_addr_t start, end; - ngx_str_t *net; - ngx_uint_t del; - - if (ngx_strcmp(value[0].data, "default") == 0) { - - if (ctx->high.default_value) { - ngx_conf_log_error(NGX_LOG_WARN, cf, 0, - "duplicate default geo range value: \"%V\", old value: \"%v\"", - &value[1], ctx->high.default_value); - } - - ctx->high.default_value = ngx_stream_geo_value(cf, ctx, &value[1]); - if (ctx->high.default_value == NULL) { - return NGX_CONF_ERROR; - } - - return NGX_CONF_OK; - } - - if (ctx->binary_include) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "binary geo range base \"%s\" cannot be mixed with usual entries", - ctx->include_name.data); - return NGX_CONF_ERROR; - } - - if (ctx->high.low == NULL) { - ctx->high.low = ngx_pcalloc(ctx->pool, - 0x10000 * sizeof(ngx_stream_geo_range_t *)); - if (ctx->high.low == NULL) { - return NGX_CONF_ERROR; - } - } - - ctx->entries++; - ctx->outside_entries = 1; - - if (ngx_strcmp(value[0].data, "delete") == 0) { - net = &value[1]; - del = 1; - - } else { - net = &value[0]; - del = 0; - } - - last = net->data + net->len; - - p = ngx_strlchr(net->data, last, '-'); - - if (p == NULL) { - goto invalid; - } - - start = ngx_inet_addr(net->data, p - net->data); - - if (start == INADDR_NONE) { - goto invalid; - } - - start = ntohl(start); - - p++; - - end = ngx_inet_addr(p, last - p); - - if (end == INADDR_NONE) { - goto invalid; - } - - end = ntohl(end); - - if (start > end) { - goto invalid; - } - - if (del) { - if (ngx_stream_geo_delete_range(cf, ctx, start, end)) { - ngx_conf_log_error(NGX_LOG_WARN, cf, 0, - "no address range \"%V\" to delete", net); - } - - return NGX_CONF_OK; - } - - ctx->value = ngx_stream_geo_value(cf, ctx, &value[1]); - - if (ctx->value == NULL) { - return NGX_CONF_ERROR; - } - - ctx->net = net; - - return ngx_stream_geo_add_range(cf, ctx, start, end); - -invalid: - - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid range \"%V\"", net); - - return NGX_CONF_ERROR; -} - - -/* the add procedure is optimized to add a growing up sequence */ - -static char * -ngx_stream_geo_add_range(ngx_conf_t *cf, ngx_stream_geo_conf_ctx_t *ctx, - in_addr_t start, in_addr_t end) -{ - in_addr_t n; - ngx_uint_t h, i, s, e; - ngx_array_t *a; - ngx_stream_geo_range_t *range; - - for (n = start; n <= end; n = (n + 0x10000) & 0xffff0000) { - - h = n >> 16; - - if (n == start) { - s = n & 0xffff; - } else { - s = 0; - } - - if ((n | 0xffff) > end) { - e = end & 0xffff; - - } else { - e = 0xffff; - } - - a = (ngx_array_t *) ctx->high.low[h]; - - if (a == NULL) { - a = ngx_array_create(ctx->temp_pool, 64, - sizeof(ngx_stream_geo_range_t)); - if (a == NULL) { - return NGX_CONF_ERROR; - } - - ctx->high.low[h] = (ngx_stream_geo_range_t *) a; - } - - i = a->nelts; - range = a->elts; - - while (i) { - - i--; - - if (e < (ngx_uint_t) range[i].start) { - continue; - } - - if (s > (ngx_uint_t) range[i].end) { - - /* add after the range */ - - range = ngx_array_push(a); - if (range == NULL) { - return NGX_CONF_ERROR; - } - - range = a->elts; - - ngx_memmove(&range[i + 2], &range[i + 1], - (a->nelts - 2 - i) * sizeof(ngx_stream_geo_range_t)); - - range[i + 1].start = (u_short) s; - range[i + 1].end = (u_short) e; - range[i + 1].value = ctx->value; - - goto next; - } - - if (s == (ngx_uint_t) range[i].start - && e == (ngx_uint_t) range[i].end) - { - ngx_conf_log_error(NGX_LOG_WARN, cf, 0, - "duplicate range \"%V\", value: \"%v\", old value: \"%v\"", - ctx->net, ctx->value, range[i].value); - - range[i].value = ctx->value; - - goto next; - } - - if (s > (ngx_uint_t) range[i].start - && e < (ngx_uint_t) range[i].end) - { - /* split the range and insert the new one */ - - range = ngx_array_push(a); - if (range == NULL) { - return NGX_CONF_ERROR; - } - - range = ngx_array_push(a); - if (range == NULL) { - return NGX_CONF_ERROR; - } - - range = a->elts; - - ngx_memmove(&range[i + 3], &range[i + 1], - (a->nelts - 3 - i) * sizeof(ngx_stream_geo_range_t)); - - range[i + 2].start = (u_short) (e + 1); - range[i + 2].end = range[i].end; - range[i + 2].value = range[i].value; - - range[i + 1].start = (u_short) s; - range[i + 1].end = (u_short) e; - range[i + 1].value = ctx->value; - - range[i].end = (u_short) (s - 1); - - goto next; - } - - if (s == (ngx_uint_t) range[i].start - && e < (ngx_uint_t) range[i].end) - { - /* shift the range start and insert the new range */ - - range = ngx_array_push(a); - if (range == NULL) { - return NGX_CONF_ERROR; - } - - range = a->elts; - - ngx_memmove(&range[i + 1], &range[i], - (a->nelts - 1 - i) * sizeof(ngx_stream_geo_range_t)); - - range[i + 1].start = (u_short) (e + 1); - - range[i].start = (u_short) s; - range[i].end = (u_short) e; - range[i].value = ctx->value; - - goto next; - } - - if (s > (ngx_uint_t) range[i].start - && e == (ngx_uint_t) range[i].end) - { - /* shift the range end and insert the new range */ - - range = ngx_array_push(a); - if (range == NULL) { - return NGX_CONF_ERROR; - } - - range = a->elts; - - ngx_memmove(&range[i + 2], &range[i + 1], - (a->nelts - 2 - i) * sizeof(ngx_stream_geo_range_t)); - - range[i + 1].start = (u_short) s; - range[i + 1].end = (u_short) e; - range[i + 1].value = ctx->value; - - range[i].end = (u_short) (s - 1); - - goto next; - } - - s = (ngx_uint_t) range[i].start; - e = (ngx_uint_t) range[i].end; - - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "range \"%V\" overlaps \"%d.%d.%d.%d-%d.%d.%d.%d\"", - ctx->net, - h >> 8, h & 0xff, s >> 8, s & 0xff, - h >> 8, h & 0xff, e >> 8, e & 0xff); - - return NGX_CONF_ERROR; - } - - /* add the first range */ - - range = ngx_array_push(a); - if (range == NULL) { - return NGX_CONF_ERROR; - } - - range = a->elts; - - ngx_memmove(&range[1], &range[0], - (a->nelts - 1) * sizeof(ngx_stream_geo_range_t)); - - range[0].start = (u_short) s; - range[0].end = (u_short) e; - range[0].value = ctx->value; - - next: - - if (h == 0xffff) { - break; - } - } - - return NGX_CONF_OK; -} - - -static ngx_uint_t -ngx_stream_geo_delete_range(ngx_conf_t *cf, ngx_stream_geo_conf_ctx_t *ctx, - in_addr_t start, in_addr_t end) -{ - in_addr_t n; - ngx_uint_t h, i, s, e, warn; - ngx_array_t *a; - ngx_stream_geo_range_t *range; - - warn = 0; - - for (n = start; n <= end; n = (n + 0x10000) & 0xffff0000) { - - h = n >> 16; - - if (n == start) { - s = n & 0xffff; - } else { - s = 0; - } - - if ((n | 0xffff) > end) { - e = end & 0xffff; - - } else { - e = 0xffff; - } - - a = (ngx_array_t *) ctx->high.low[h]; - - if (a == NULL || a->nelts == 0) { - warn = 1; - goto next; - } - - range = a->elts; - for (i = 0; i < a->nelts; i++) { - - if (s == (ngx_uint_t) range[i].start - && e == (ngx_uint_t) range[i].end) - { - ngx_memmove(&range[i], &range[i + 1], - (a->nelts - 1 - i) * sizeof(ngx_stream_geo_range_t)); - - a->nelts--; - - break; - } - - if (i == a->nelts - 1) { - warn = 1; - } - } - - next: - - if (h == 0xffff) { - break; - } - } - - return warn; -} - - -static char * -ngx_stream_geo_cidr(ngx_conf_t *cf, ngx_stream_geo_conf_ctx_t *ctx, - ngx_str_t *value) -{ - char *rv; - ngx_int_t rc, del; - ngx_str_t *net; - ngx_cidr_t cidr; - - if (ctx->tree == NULL) { - ctx->tree = ngx_radix_tree_create(ctx->pool, -1); - if (ctx->tree == NULL) { - return NGX_CONF_ERROR; - } - } - -#if (NGX_HAVE_INET6) - if (ctx->tree6 == NULL) { - ctx->tree6 = ngx_radix_tree_create(ctx->pool, -1); - if (ctx->tree6 == NULL) { - return NGX_CONF_ERROR; - } - } -#endif - - if (ngx_strcmp(value[0].data, "default") == 0) { - cidr.family = AF_INET; - cidr.u.in.addr = 0; - cidr.u.in.mask = 0; - - rv = ngx_stream_geo_cidr_add(cf, ctx, &cidr, &value[1], &value[0]); - - if (rv != NGX_CONF_OK) { - return rv; - } - -#if (NGX_HAVE_INET6) - cidr.family = AF_INET6; - ngx_memzero(&cidr.u.in6, sizeof(ngx_in6_cidr_t)); - - rv = ngx_stream_geo_cidr_add(cf, ctx, &cidr, &value[1], &value[0]); - - if (rv != NGX_CONF_OK) { - return rv; - } -#endif - - return NGX_CONF_OK; - } - - if (ngx_strcmp(value[0].data, "delete") == 0) { - net = &value[1]; - del = 1; - - } else { - net = &value[0]; - del = 0; - } - - if (ngx_stream_geo_cidr_value(cf, net, &cidr) != NGX_OK) { - return NGX_CONF_ERROR; - } - - if (cidr.family == AF_INET) { - cidr.u.in.addr = ntohl(cidr.u.in.addr); - cidr.u.in.mask = ntohl(cidr.u.in.mask); - } - - if (del) { - switch (cidr.family) { - -#if (NGX_HAVE_INET6) - case AF_INET6: - rc = ngx_radix128tree_delete(ctx->tree6, - cidr.u.in6.addr.s6_addr, - cidr.u.in6.mask.s6_addr); - break; -#endif - - default: /* AF_INET */ - rc = ngx_radix32tree_delete(ctx->tree, cidr.u.in.addr, - cidr.u.in.mask); - break; - } - - if (rc != NGX_OK) { - ngx_conf_log_error(NGX_LOG_WARN, cf, 0, - "no network \"%V\" to delete", net); - } - - return NGX_CONF_OK; - } - - return ngx_stream_geo_cidr_add(cf, ctx, &cidr, &value[1], net); -} - - -static char * -ngx_stream_geo_cidr_add(ngx_conf_t *cf, ngx_stream_geo_conf_ctx_t *ctx, - ngx_cidr_t *cidr, ngx_str_t *value, ngx_str_t *net) -{ - ngx_int_t rc; - ngx_stream_variable_value_t *val, *old; - - val = ngx_stream_geo_value(cf, ctx, value); - - if (val == NULL) { - return NGX_CONF_ERROR; - } - - switch (cidr->family) { - -#if (NGX_HAVE_INET6) - case AF_INET6: - rc = ngx_radix128tree_insert(ctx->tree6, cidr->u.in6.addr.s6_addr, - cidr->u.in6.mask.s6_addr, - (uintptr_t) val); - - if (rc == NGX_OK) { - return NGX_CONF_OK; - } - - if (rc == NGX_ERROR) { - return NGX_CONF_ERROR; - } - - /* rc == NGX_BUSY */ - - old = (ngx_stream_variable_value_t *) - ngx_radix128tree_find(ctx->tree6, - cidr->u.in6.addr.s6_addr); - - ngx_conf_log_error(NGX_LOG_WARN, cf, 0, - "duplicate network \"%V\", value: \"%v\", old value: \"%v\"", - net, val, old); - - rc = ngx_radix128tree_delete(ctx->tree6, - cidr->u.in6.addr.s6_addr, - cidr->u.in6.mask.s6_addr); - - if (rc == NGX_ERROR) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid radix tree"); - return NGX_CONF_ERROR; - } - - rc = ngx_radix128tree_insert(ctx->tree6, cidr->u.in6.addr.s6_addr, - cidr->u.in6.mask.s6_addr, - (uintptr_t) val); - - break; -#endif - - default: /* AF_INET */ - rc = ngx_radix32tree_insert(ctx->tree, cidr->u.in.addr, - cidr->u.in.mask, (uintptr_t) val); - - if (rc == NGX_OK) { - return NGX_CONF_OK; - } - - if (rc == NGX_ERROR) { - return NGX_CONF_ERROR; - } - - /* rc == NGX_BUSY */ - - old = (ngx_stream_variable_value_t *) - ngx_radix32tree_find(ctx->tree, cidr->u.in.addr); - - ngx_conf_log_error(NGX_LOG_WARN, cf, 0, - "duplicate network \"%V\", value: \"%v\", old value: \"%v\"", - net, val, old); - - rc = ngx_radix32tree_delete(ctx->tree, - cidr->u.in.addr, cidr->u.in.mask); - - if (rc == NGX_ERROR) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid radix tree"); - return NGX_CONF_ERROR; - } - - rc = ngx_radix32tree_insert(ctx->tree, cidr->u.in.addr, - cidr->u.in.mask, (uintptr_t) val); - - break; - } - - if (rc == NGX_OK) { - return NGX_CONF_OK; - } - - return NGX_CONF_ERROR; -} - - -static ngx_stream_variable_value_t * -ngx_stream_geo_value(ngx_conf_t *cf, ngx_stream_geo_conf_ctx_t *ctx, - ngx_str_t *value) -{ - uint32_t hash; - ngx_stream_variable_value_t *val; - ngx_stream_geo_variable_value_node_t *gvvn; - - hash = ngx_crc32_long(value->data, value->len); - - gvvn = (ngx_stream_geo_variable_value_node_t *) - ngx_str_rbtree_lookup(&ctx->rbtree, value, hash); - - if (gvvn) { - return gvvn->value; - } - - val = ngx_palloc(ctx->pool, sizeof(ngx_stream_variable_value_t)); - if (val == NULL) { - return NULL; - } - - val->len = value->len; - val->data = ngx_pstrdup(ctx->pool, value); - if (val->data == NULL) { - return NULL; - } - - val->valid = 1; - val->no_cacheable = 0; - val->not_found = 0; - - gvvn = ngx_palloc(ctx->temp_pool, - sizeof(ngx_stream_geo_variable_value_node_t)); - if (gvvn == NULL) { - return NULL; - } - - gvvn->sn.node.key = hash; - gvvn->sn.str.len = val->len; - gvvn->sn.str.data = val->data; - gvvn->value = val; - gvvn->offset = 0; - - ngx_rbtree_insert(&ctx->rbtree, &gvvn->sn.node); - - ctx->data_size += ngx_align(sizeof(ngx_stream_variable_value_t) - + value->len, sizeof(void *)); - - return val; -} - - -static ngx_int_t -ngx_stream_geo_cidr_value(ngx_conf_t *cf, ngx_str_t *net, ngx_cidr_t *cidr) -{ - ngx_int_t rc; - - if (ngx_strcmp(net->data, "255.255.255.255") == 0) { - cidr->family = AF_INET; - cidr->u.in.addr = 0xffffffff; - cidr->u.in.mask = 0xffffffff; - - return NGX_OK; - } - - rc = ngx_ptocidr(net, cidr); - - if (rc == NGX_ERROR) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid network \"%V\"", net); - return NGX_ERROR; - } - - if (rc == NGX_DONE) { - ngx_conf_log_error(NGX_LOG_WARN, cf, 0, - "low address bits of %V are meaningless", net); - } - - return NGX_OK; -} - - -static char * -ngx_stream_geo_include(ngx_conf_t *cf, ngx_stream_geo_conf_ctx_t *ctx, - ngx_str_t *name) -{ - char *rv; - ngx_str_t file; - - file.len = name->len + 4; - file.data = ngx_pnalloc(ctx->temp_pool, name->len + 5); - if (file.data == NULL) { - return NGX_CONF_ERROR; - } - - ngx_sprintf(file.data, "%V.bin%Z", name); - - if (ngx_conf_full_name(cf->cycle, &file, 1) != NGX_OK) { - return NGX_CONF_ERROR; - } - - if (ctx->ranges) { - ngx_log_debug1(NGX_LOG_DEBUG_CORE, cf->log, 0, "include %s", file.data); - - switch (ngx_stream_geo_include_binary_base(cf, ctx, &file)) { - case NGX_OK: - return NGX_CONF_OK; - case NGX_ERROR: - return NGX_CONF_ERROR; - default: - break; - } - } - - file.len -= 4; - file.data[file.len] = '\0'; - - ctx->include_name = file; - - if (ctx->outside_entries) { - ctx->allow_binary_include = 0; - } - - ngx_log_debug1(NGX_LOG_DEBUG_CORE, cf->log, 0, "include %s", file.data); - - rv = ngx_conf_parse(cf, &file); - - ctx->includes++; - ctx->outside_entries = 0; - - return rv; -} - - -static ngx_int_t -ngx_stream_geo_include_binary_base(ngx_conf_t *cf, - ngx_stream_geo_conf_ctx_t *ctx, ngx_str_t *name) -{ - u_char *base, ch; - time_t mtime; - size_t size, len; - ssize_t n; - uint32_t crc32; - ngx_err_t err; - ngx_int_t rc; - ngx_uint_t i; - ngx_file_t file; - ngx_file_info_t fi; - ngx_stream_geo_range_t *range, **ranges; - ngx_stream_geo_header_t *header; - ngx_stream_variable_value_t *vv; - - ngx_memzero(&file, sizeof(ngx_file_t)); - file.name = *name; - file.log = cf->log; - - file.fd = ngx_open_file(name->data, NGX_FILE_RDONLY, 0, 0); - if (file.fd == NGX_INVALID_FILE) { - err = ngx_errno; - if (err != NGX_ENOENT) { - ngx_conf_log_error(NGX_LOG_CRIT, cf, err, - ngx_open_file_n " \"%s\" failed", name->data); - } - return NGX_DECLINED; - } - - if (ctx->outside_entries) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "binary geo range base \"%s\" cannot be mixed with usual entries", - name->data); - rc = NGX_ERROR; - goto done; - } - - if (ctx->binary_include) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "second binary geo range base \"%s\" cannot be mixed with \"%s\"", - name->data, ctx->include_name.data); - rc = NGX_ERROR; - goto done; - } - - if (ngx_fd_info(file.fd, &fi) == NGX_FILE_ERROR) { - ngx_conf_log_error(NGX_LOG_CRIT, cf, ngx_errno, - ngx_fd_info_n " \"%s\" failed", name->data); - goto failed; - } - - size = (size_t) ngx_file_size(&fi); - mtime = ngx_file_mtime(&fi); - - ch = name->data[name->len - 4]; - name->data[name->len - 4] = '\0'; - - if (ngx_file_info(name->data, &fi) == NGX_FILE_ERROR) { - ngx_conf_log_error(NGX_LOG_CRIT, cf, ngx_errno, - ngx_file_info_n " \"%s\" failed", name->data); - goto failed; - } - - name->data[name->len - 4] = ch; - - if (mtime < ngx_file_mtime(&fi)) { - ngx_conf_log_error(NGX_LOG_WARN, cf, 0, - "stale binary geo range base \"%s\"", name->data); - goto failed; - } - - base = ngx_palloc(ctx->pool, size); - if (base == NULL) { - goto failed; - } - - n = ngx_read_file(&file, base, size, 0); - - if (n == NGX_ERROR) { - ngx_conf_log_error(NGX_LOG_CRIT, cf, ngx_errno, - ngx_read_file_n " \"%s\" failed", name->data); - goto failed; - } - - if ((size_t) n != size) { - ngx_conf_log_error(NGX_LOG_CRIT, cf, 0, - ngx_read_file_n " \"%s\" returned only %z bytes instead of %z", - name->data, n, size); - goto failed; - } - - header = (ngx_stream_geo_header_t *) base; - - if (size < 16 || ngx_memcmp(&ngx_stream_geo_header, header, 12) != 0) { - ngx_conf_log_error(NGX_LOG_WARN, cf, 0, - "incompatible binary geo range base \"%s\"", name->data); - goto failed; - } - - ngx_crc32_init(crc32); - - vv = (ngx_stream_variable_value_t *) - (base + sizeof(ngx_stream_geo_header_t)); - - while (vv->data) { - len = ngx_align(sizeof(ngx_stream_variable_value_t) + vv->len, - sizeof(void *)); - ngx_crc32_update(&crc32, (u_char *) vv, len); - vv->data += (size_t) base; - vv = (ngx_stream_variable_value_t *) ((u_char *) vv + len); - } - ngx_crc32_update(&crc32, (u_char *) vv, - sizeof(ngx_stream_variable_value_t)); - vv++; - - ranges = (ngx_stream_geo_range_t **) vv; - - for (i = 0; i < 0x10000; i++) { - ngx_crc32_update(&crc32, (u_char *) &ranges[i], sizeof(void *)); - if (ranges[i]) { - ranges[i] = (ngx_stream_geo_range_t *) - ((u_char *) ranges[i] + (size_t) base); - } - } - - range = (ngx_stream_geo_range_t *) &ranges[0x10000]; - - while ((u_char *) range < base + size) { - while (range->value) { - ngx_crc32_update(&crc32, (u_char *) range, - sizeof(ngx_stream_geo_range_t)); - range->value = (ngx_stream_variable_value_t *) - ((u_char *) range->value + (size_t) base); - range++; - } - ngx_crc32_update(&crc32, (u_char *) range, sizeof(void *)); - range = (ngx_stream_geo_range_t *) ((u_char *) range + sizeof(void *)); - } - - ngx_crc32_final(crc32); - - if (crc32 != header->crc32) { - ngx_conf_log_error(NGX_LOG_WARN, cf, 0, - "CRC32 mismatch in binary geo range base \"%s\"", name->data); - goto failed; - } - - ngx_conf_log_error(NGX_LOG_NOTICE, cf, 0, - "using binary geo range base \"%s\"", name->data); - - ctx->include_name = *name; - ctx->binary_include = 1; - ctx->high.low = ranges; - rc = NGX_OK; - - goto done; - -failed: - - rc = NGX_DECLINED; - -done: - - if (ngx_close_file(file.fd) == NGX_FILE_ERROR) { - ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno, - ngx_close_file_n " \"%s\" failed", name->data); - } - - return rc; -} - - -static void -ngx_stream_geo_create_binary_base(ngx_stream_geo_conf_ctx_t *ctx) -{ - u_char *p; - uint32_t hash; - ngx_str_t s; - ngx_uint_t i; - ngx_file_mapping_t fm; - ngx_stream_geo_range_t *r, *range, **ranges; - ngx_stream_geo_header_t *header; - ngx_stream_geo_variable_value_node_t *gvvn; - - fm.name = ngx_pnalloc(ctx->temp_pool, ctx->include_name.len + 5); - if (fm.name == NULL) { - return; - } - - ngx_sprintf(fm.name, "%V.bin%Z", &ctx->include_name); - - fm.size = ctx->data_size; - fm.log = ctx->pool->log; - - ngx_log_error(NGX_LOG_NOTICE, fm.log, 0, - "creating binary geo range base \"%s\"", fm.name); - - if (ngx_create_file_mapping(&fm) != NGX_OK) { - return; - } - - p = ngx_cpymem(fm.addr, &ngx_stream_geo_header, - sizeof(ngx_stream_geo_header_t)); - - p = ngx_stream_geo_copy_values(fm.addr, p, ctx->rbtree.root, - ctx->rbtree.sentinel); - - p += sizeof(ngx_stream_variable_value_t); - - ranges = (ngx_stream_geo_range_t **) p; - - p += 0x10000 * sizeof(ngx_stream_geo_range_t *); - - for (i = 0; i < 0x10000; i++) { - r = ctx->high.low[i]; - if (r == NULL) { - continue; - } - - range = (ngx_stream_geo_range_t *) p; - ranges[i] = (ngx_stream_geo_range_t *) (p - (u_char *) fm.addr); - - do { - s.len = r->value->len; - s.data = r->value->data; - hash = ngx_crc32_long(s.data, s.len); - gvvn = (ngx_stream_geo_variable_value_node_t *) - ngx_str_rbtree_lookup(&ctx->rbtree, &s, hash); - - range->value = (ngx_stream_variable_value_t *) gvvn->offset; - range->start = r->start; - range->end = r->end; - range++; - - } while ((++r)->value); - - range->value = NULL; - - p = (u_char *) range + sizeof(void *); - } - - header = fm.addr; - header->crc32 = ngx_crc32_long((u_char *) fm.addr - + sizeof(ngx_stream_geo_header_t), - fm.size - sizeof(ngx_stream_geo_header_t)); - - ngx_close_file_mapping(&fm); -} - - -static u_char * -ngx_stream_geo_copy_values(u_char *base, u_char *p, ngx_rbtree_node_t *node, - ngx_rbtree_node_t *sentinel) -{ - ngx_stream_variable_value_t *vv; - ngx_stream_geo_variable_value_node_t *gvvn; - - if (node == sentinel) { - return p; - } - - gvvn = (ngx_stream_geo_variable_value_node_t *) node; - gvvn->offset = p - base; - - vv = (ngx_stream_variable_value_t *) p; - *vv = *gvvn->value; - p += sizeof(ngx_stream_variable_value_t); - vv->data = (u_char *) (p - base); - - p = ngx_cpymem(p, gvvn->sn.str.data, gvvn->sn.str.len); - - p = ngx_align_ptr(p, sizeof(void *)); - - p = ngx_stream_geo_copy_values(base, p, node->left, sentinel); - - return ngx_stream_geo_copy_values(base, p, node->right, sentinel); -} diff --git a/app/nginx/src/stream/ngx_stream_geoip_module.c b/app/nginx/src/stream/ngx_stream_geoip_module.c deleted file mode 100644 index f694033..0000000 --- a/app/nginx/src/stream/ngx_stream_geoip_module.c +++ /dev/null @@ -1,814 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) Nginx, Inc. - */ - - -#include <ngx_config.h> -#include <ngx_core.h> -#include <ngx_stream.h> - -#include <GeoIP.h> -#include <GeoIPCity.h> - - -#define NGX_GEOIP_COUNTRY_CODE 0 -#define NGX_GEOIP_COUNTRY_CODE3 1 -#define NGX_GEOIP_COUNTRY_NAME 2 - - -typedef struct { - GeoIP *country; - GeoIP *org; - GeoIP *city; -#if (NGX_HAVE_GEOIP_V6) - unsigned country_v6:1; - unsigned org_v6:1; - unsigned city_v6:1; -#endif -} ngx_stream_geoip_conf_t; - - -typedef struct { - ngx_str_t *name; - uintptr_t data; -} ngx_stream_geoip_var_t; - - -typedef const char *(*ngx_stream_geoip_variable_handler_pt)(GeoIP *, - u_long addr); - - -ngx_stream_geoip_variable_handler_pt ngx_stream_geoip_country_functions[] = { - GeoIP_country_code_by_ipnum, - GeoIP_country_code3_by_ipnum, - GeoIP_country_name_by_ipnum, -}; - - -#if (NGX_HAVE_GEOIP_V6) - -typedef const char *(*ngx_stream_geoip_variable_handler_v6_pt)(GeoIP *, - geoipv6_t addr); - - -ngx_stream_geoip_variable_handler_v6_pt - ngx_stream_geoip_country_v6_functions[] = -{ - GeoIP_country_code_by_ipnum_v6, - GeoIP_country_code3_by_ipnum_v6, - GeoIP_country_name_by_ipnum_v6, -}; - -#endif - - -static ngx_int_t ngx_stream_geoip_country_variable(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data); -static ngx_int_t ngx_stream_geoip_org_variable(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data); -static ngx_int_t ngx_stream_geoip_city_variable(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data); -static ngx_int_t ngx_stream_geoip_region_name_variable(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data); -static ngx_int_t ngx_stream_geoip_city_float_variable(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data); -static ngx_int_t ngx_stream_geoip_city_int_variable(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data); -static GeoIPRecord *ngx_stream_geoip_get_city_record(ngx_stream_session_t *s); - -static ngx_int_t ngx_stream_geoip_add_variables(ngx_conf_t *cf); -static void *ngx_stream_geoip_create_conf(ngx_conf_t *cf); -static char *ngx_stream_geoip_country(ngx_conf_t *cf, ngx_command_t *cmd, - void *conf); -static char *ngx_stream_geoip_org(ngx_conf_t *cf, ngx_command_t *cmd, - void *conf); -static char *ngx_stream_geoip_city(ngx_conf_t *cf, ngx_command_t *cmd, - void *conf); -static void ngx_stream_geoip_cleanup(void *data); - - -static ngx_command_t ngx_stream_geoip_commands[] = { - - { ngx_string("geoip_country"), - NGX_STREAM_MAIN_CONF|NGX_CONF_TAKE12, - ngx_stream_geoip_country, - NGX_STREAM_MAIN_CONF_OFFSET, - 0, - NULL }, - - { ngx_string("geoip_org"), - NGX_STREAM_MAIN_CONF|NGX_CONF_TAKE12, - ngx_stream_geoip_org, - NGX_STREAM_MAIN_CONF_OFFSET, - 0, - NULL }, - - { ngx_string("geoip_city"), - NGX_STREAM_MAIN_CONF|NGX_CONF_TAKE12, - ngx_stream_geoip_city, - NGX_STREAM_MAIN_CONF_OFFSET, - 0, - NULL }, - - ngx_null_command -}; - - -static ngx_stream_module_t ngx_stream_geoip_module_ctx = { - ngx_stream_geoip_add_variables, /* preconfiguration */ - NULL, /* postconfiguration */ - - ngx_stream_geoip_create_conf, /* create main configuration */ - NULL, /* init main configuration */ - - NULL, /* create server configuration */ - NULL /* merge server configuration */ -}; - - -ngx_module_t ngx_stream_geoip_module = { - NGX_MODULE_V1, - &ngx_stream_geoip_module_ctx, /* module context */ - ngx_stream_geoip_commands, /* module directives */ - NGX_STREAM_MODULE, /* module type */ - NULL, /* init master */ - NULL, /* init module */ - NULL, /* init process */ - NULL, /* init thread */ - NULL, /* exit thread */ - NULL, /* exit process */ - NULL, /* exit master */ - NGX_MODULE_V1_PADDING -}; - - -static ngx_stream_variable_t ngx_stream_geoip_vars[] = { - - { ngx_string("geoip_country_code"), NULL, - ngx_stream_geoip_country_variable, - NGX_GEOIP_COUNTRY_CODE, 0, 0 }, - - { ngx_string("geoip_country_code3"), NULL, - ngx_stream_geoip_country_variable, - NGX_GEOIP_COUNTRY_CODE3, 0, 0 }, - - { ngx_string("geoip_country_name"), NULL, - ngx_stream_geoip_country_variable, - NGX_GEOIP_COUNTRY_NAME, 0, 0 }, - - { ngx_string("geoip_org"), NULL, - ngx_stream_geoip_org_variable, - 0, 0, 0 }, - - { ngx_string("geoip_city_continent_code"), NULL, - ngx_stream_geoip_city_variable, - offsetof(GeoIPRecord, continent_code), 0, 0 }, - - { ngx_string("geoip_city_country_code"), NULL, - ngx_stream_geoip_city_variable, - offsetof(GeoIPRecord, country_code), 0, 0 }, - - { ngx_string("geoip_city_country_code3"), NULL, - ngx_stream_geoip_city_variable, - offsetof(GeoIPRecord, country_code3), 0, 0 }, - - { ngx_string("geoip_city_country_name"), NULL, - ngx_stream_geoip_city_variable, - offsetof(GeoIPRecord, country_name), 0, 0 }, - - { ngx_string("geoip_region"), NULL, - ngx_stream_geoip_city_variable, - offsetof(GeoIPRecord, region), 0, 0 }, - - { ngx_string("geoip_region_name"), NULL, - ngx_stream_geoip_region_name_variable, - 0, 0, 0 }, - - { ngx_string("geoip_city"), NULL, - ngx_stream_geoip_city_variable, - offsetof(GeoIPRecord, city), 0, 0 }, - - { ngx_string("geoip_postal_code"), NULL, - ngx_stream_geoip_city_variable, - offsetof(GeoIPRecord, postal_code), 0, 0 }, - - { ngx_string("geoip_latitude"), NULL, - ngx_stream_geoip_city_float_variable, - offsetof(GeoIPRecord, latitude), 0, 0 }, - - { ngx_string("geoip_longitude"), NULL, - ngx_stream_geoip_city_float_variable, - offsetof(GeoIPRecord, longitude), 0, 0 }, - - { ngx_string("geoip_dma_code"), NULL, - ngx_stream_geoip_city_int_variable, - offsetof(GeoIPRecord, dma_code), 0, 0 }, - - { ngx_string("geoip_area_code"), NULL, - ngx_stream_geoip_city_int_variable, - offsetof(GeoIPRecord, area_code), 0, 0 }, - - { ngx_null_string, NULL, NULL, 0, 0, 0 } -}; - - -static u_long -ngx_stream_geoip_addr(ngx_stream_session_t *s, ngx_stream_geoip_conf_t *gcf) -{ - ngx_addr_t addr; - struct sockaddr_in *sin; - - addr.sockaddr = s->connection->sockaddr; - addr.socklen = s->connection->socklen; - /* addr.name = s->connection->addr_text; */ - -#if (NGX_HAVE_INET6) - - if (addr.sockaddr->sa_family == AF_INET6) { - u_char *p; - in_addr_t inaddr; - struct in6_addr *inaddr6; - - inaddr6 = &((struct sockaddr_in6 *) addr.sockaddr)->sin6_addr; - - if (IN6_IS_ADDR_V4MAPPED(inaddr6)) { - p = inaddr6->s6_addr; - - inaddr = p[12] << 24; - inaddr += p[13] << 16; - inaddr += p[14] << 8; - inaddr += p[15]; - - return inaddr; - } - } - -#endif - - if (addr.sockaddr->sa_family != AF_INET) { - return INADDR_NONE; - } - - sin = (struct sockaddr_in *) addr.sockaddr; - return ntohl(sin->sin_addr.s_addr); -} - - -#if (NGX_HAVE_GEOIP_V6) - -static geoipv6_t -ngx_stream_geoip_addr_v6(ngx_stream_session_t *s, ngx_stream_geoip_conf_t *gcf) -{ - ngx_addr_t addr; - in_addr_t addr4; - struct in6_addr addr6; - struct sockaddr_in *sin; - struct sockaddr_in6 *sin6; - - addr.sockaddr = s->connection->sockaddr; - addr.socklen = s->connection->socklen; - /* addr.name = s->connection->addr_text; */ - - switch (addr.sockaddr->sa_family) { - - case AF_INET: - /* Produce IPv4-mapped IPv6 address. */ - sin = (struct sockaddr_in *) addr.sockaddr; - addr4 = ntohl(sin->sin_addr.s_addr); - - ngx_memzero(&addr6, sizeof(struct in6_addr)); - addr6.s6_addr[10] = 0xff; - addr6.s6_addr[11] = 0xff; - addr6.s6_addr[12] = addr4 >> 24; - addr6.s6_addr[13] = addr4 >> 16; - addr6.s6_addr[14] = addr4 >> 8; - addr6.s6_addr[15] = addr4; - return addr6; - - case AF_INET6: - sin6 = (struct sockaddr_in6 *) addr.sockaddr; - return sin6->sin6_addr; - - default: - return in6addr_any; - } -} - -#endif - - -static ngx_int_t -ngx_stream_geoip_country_variable(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data) -{ - ngx_stream_geoip_variable_handler_pt handler = - ngx_stream_geoip_country_functions[data]; -#if (NGX_HAVE_GEOIP_V6) - ngx_stream_geoip_variable_handler_v6_pt handler_v6 = - ngx_stream_geoip_country_v6_functions[data]; -#endif - - const char *val; - ngx_stream_geoip_conf_t *gcf; - - gcf = ngx_stream_get_module_main_conf(s, ngx_stream_geoip_module); - - if (gcf->country == NULL) { - goto not_found; - } - -#if (NGX_HAVE_GEOIP_V6) - val = gcf->country_v6 - ? handler_v6(gcf->country, ngx_stream_geoip_addr_v6(s, gcf)) - : handler(gcf->country, ngx_stream_geoip_addr(s, gcf)); -#else - val = handler(gcf->country, ngx_stream_geoip_addr(s, gcf)); -#endif - - if (val == NULL) { - goto not_found; - } - - v->len = ngx_strlen(val); - v->valid = 1; - v->no_cacheable = 0; - v->not_found = 0; - v->data = (u_char *) val; - - return NGX_OK; - -not_found: - - v->not_found = 1; - - return NGX_OK; -} - - -static ngx_int_t -ngx_stream_geoip_org_variable(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data) -{ - size_t len; - char *val; - ngx_stream_geoip_conf_t *gcf; - - gcf = ngx_stream_get_module_main_conf(s, ngx_stream_geoip_module); - - if (gcf->org == NULL) { - goto not_found; - } - -#if (NGX_HAVE_GEOIP_V6) - val = gcf->org_v6 - ? GeoIP_name_by_ipnum_v6(gcf->org, - ngx_stream_geoip_addr_v6(s, gcf)) - : GeoIP_name_by_ipnum(gcf->org, - ngx_stream_geoip_addr(s, gcf)); -#else - val = GeoIP_name_by_ipnum(gcf->org, ngx_stream_geoip_addr(s, gcf)); -#endif - - if (val == NULL) { - goto not_found; - } - - len = ngx_strlen(val); - v->data = ngx_pnalloc(s->connection->pool, len); - if (v->data == NULL) { - ngx_free(val); - return NGX_ERROR; - } - - ngx_memcpy(v->data, val, len); - - v->len = len; - v->valid = 1; - v->no_cacheable = 0; - v->not_found = 0; - - ngx_free(val); - - return NGX_OK; - -not_found: - - v->not_found = 1; - - return NGX_OK; -} - - -static ngx_int_t -ngx_stream_geoip_city_variable(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data) -{ - char *val; - size_t len; - GeoIPRecord *gr; - - gr = ngx_stream_geoip_get_city_record(s); - if (gr == NULL) { - goto not_found; - } - - val = *(char **) ((char *) gr + data); - if (val == NULL) { - goto no_value; - } - - len = ngx_strlen(val); - v->data = ngx_pnalloc(s->connection->pool, len); - if (v->data == NULL) { - GeoIPRecord_delete(gr); - return NGX_ERROR; - } - - ngx_memcpy(v->data, val, len); - - v->len = len; - v->valid = 1; - v->no_cacheable = 0; - v->not_found = 0; - - GeoIPRecord_delete(gr); - - return NGX_OK; - -no_value: - - GeoIPRecord_delete(gr); - -not_found: - - v->not_found = 1; - - return NGX_OK; -} - - -static ngx_int_t -ngx_stream_geoip_region_name_variable(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data) -{ - size_t len; - const char *val; - GeoIPRecord *gr; - - gr = ngx_stream_geoip_get_city_record(s); - if (gr == NULL) { - goto not_found; - } - - val = GeoIP_region_name_by_code(gr->country_code, gr->region); - - GeoIPRecord_delete(gr); - - if (val == NULL) { - goto not_found; - } - - len = ngx_strlen(val); - v->data = ngx_pnalloc(s->connection->pool, len); - if (v->data == NULL) { - return NGX_ERROR; - } - - ngx_memcpy(v->data, val, len); - - v->len = len; - v->valid = 1; - v->no_cacheable = 0; - v->not_found = 0; - - return NGX_OK; - -not_found: - - v->not_found = 1; - - return NGX_OK; -} - - -static ngx_int_t -ngx_stream_geoip_city_float_variable(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data) -{ - float val; - GeoIPRecord *gr; - - gr = ngx_stream_geoip_get_city_record(s); - if (gr == NULL) { - v->not_found = 1; - return NGX_OK; - } - - v->data = ngx_pnalloc(s->connection->pool, NGX_INT64_LEN + 5); - if (v->data == NULL) { - GeoIPRecord_delete(gr); - return NGX_ERROR; - } - - val = *(float *) ((char *) gr + data); - - v->len = ngx_sprintf(v->data, "%.4f", val) - v->data; - v->valid = 1; - v->no_cacheable = 0; - v->not_found = 0; - - GeoIPRecord_delete(gr); - - return NGX_OK; -} - - -static ngx_int_t -ngx_stream_geoip_city_int_variable(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data) -{ - int val; - GeoIPRecord *gr; - - gr = ngx_stream_geoip_get_city_record(s); - if (gr == NULL) { - v->not_found = 1; - return NGX_OK; - } - - v->data = ngx_pnalloc(s->connection->pool, NGX_INT64_LEN); - if (v->data == NULL) { - GeoIPRecord_delete(gr); - return NGX_ERROR; - } - - val = *(int *) ((char *) gr + data); - - v->len = ngx_sprintf(v->data, "%d", val) - v->data; - v->valid = 1; - v->no_cacheable = 0; - v->not_found = 0; - - GeoIPRecord_delete(gr); - - return NGX_OK; -} - - -static GeoIPRecord * -ngx_stream_geoip_get_city_record(ngx_stream_session_t *s) -{ - ngx_stream_geoip_conf_t *gcf; - - gcf = ngx_stream_get_module_main_conf(s, ngx_stream_geoip_module); - - if (gcf->city) { -#if (NGX_HAVE_GEOIP_V6) - return gcf->city_v6 - ? GeoIP_record_by_ipnum_v6(gcf->city, - ngx_stream_geoip_addr_v6(s, gcf)) - : GeoIP_record_by_ipnum(gcf->city, - ngx_stream_geoip_addr(s, gcf)); -#else - return GeoIP_record_by_ipnum(gcf->city, ngx_stream_geoip_addr(s, gcf)); -#endif - } - - return NULL; -} - - -static ngx_int_t -ngx_stream_geoip_add_variables(ngx_conf_t *cf) -{ - ngx_stream_variable_t *var, *v; - - for (v = ngx_stream_geoip_vars; v->name.len; v++) { - var = ngx_stream_add_variable(cf, &v->name, v->flags); - if (var == NULL) { - return NGX_ERROR; - } - - var->get_handler = v->get_handler; - var->data = v->data; - } - - return NGX_OK; -} - - -static void * -ngx_stream_geoip_create_conf(ngx_conf_t *cf) -{ - ngx_pool_cleanup_t *cln; - ngx_stream_geoip_conf_t *conf; - - conf = ngx_pcalloc(cf->pool, sizeof(ngx_stream_geoip_conf_t)); - if (conf == NULL) { - return NULL; - } - - cln = ngx_pool_cleanup_add(cf->pool, 0); - if (cln == NULL) { - return NULL; - } - - cln->handler = ngx_stream_geoip_cleanup; - cln->data = conf; - - return conf; -} - - -static char * -ngx_stream_geoip_country(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) -{ - ngx_stream_geoip_conf_t *gcf = conf; - - ngx_str_t *value; - - if (gcf->country) { - return "is duplicate"; - } - - value = cf->args->elts; - - gcf->country = GeoIP_open((char *) value[1].data, GEOIP_MEMORY_CACHE); - - if (gcf->country == NULL) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "GeoIP_open(\"%V\") failed", &value[1]); - - return NGX_CONF_ERROR; - } - - if (cf->args->nelts == 3) { - if (ngx_strcmp(value[2].data, "utf8") == 0) { - GeoIP_set_charset(gcf->country, GEOIP_CHARSET_UTF8); - - } else { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "invalid parameter \"%V\"", &value[2]); - return NGX_CONF_ERROR; - } - } - - switch (gcf->country->databaseType) { - - case GEOIP_COUNTRY_EDITION: - - return NGX_CONF_OK; - -#if (NGX_HAVE_GEOIP_V6) - case GEOIP_COUNTRY_EDITION_V6: - - gcf->country_v6 = 1; - return NGX_CONF_OK; -#endif - - default: - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "invalid GeoIP database \"%V\" type:%d", - &value[1], gcf->country->databaseType); - return NGX_CONF_ERROR; - } -} - - -static char * -ngx_stream_geoip_org(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) -{ - ngx_stream_geoip_conf_t *gcf = conf; - - ngx_str_t *value; - - if (gcf->org) { - return "is duplicate"; - } - - value = cf->args->elts; - - gcf->org = GeoIP_open((char *) value[1].data, GEOIP_MEMORY_CACHE); - - if (gcf->org == NULL) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "GeoIP_open(\"%V\") failed", &value[1]); - - return NGX_CONF_ERROR; - } - - if (cf->args->nelts == 3) { - if (ngx_strcmp(value[2].data, "utf8") == 0) { - GeoIP_set_charset(gcf->org, GEOIP_CHARSET_UTF8); - - } else { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "invalid parameter \"%V\"", &value[2]); - return NGX_CONF_ERROR; - } - } - - switch (gcf->org->databaseType) { - - case GEOIP_ISP_EDITION: - case GEOIP_ORG_EDITION: - case GEOIP_DOMAIN_EDITION: - case GEOIP_ASNUM_EDITION: - - return NGX_CONF_OK; - -#if (NGX_HAVE_GEOIP_V6) - case GEOIP_ISP_EDITION_V6: - case GEOIP_ORG_EDITION_V6: - case GEOIP_DOMAIN_EDITION_V6: - case GEOIP_ASNUM_EDITION_V6: - - gcf->org_v6 = 1; - return NGX_CONF_OK; -#endif - - default: - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "invalid GeoIP database \"%V\" type:%d", - &value[1], gcf->org->databaseType); - return NGX_CONF_ERROR; - } -} - - -static char * -ngx_stream_geoip_city(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) -{ - ngx_stream_geoip_conf_t *gcf = conf; - - ngx_str_t *value; - - if (gcf->city) { - return "is duplicate"; - } - - value = cf->args->elts; - - gcf->city = GeoIP_open((char *) value[1].data, GEOIP_MEMORY_CACHE); - - if (gcf->city == NULL) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "GeoIP_open(\"%V\") failed", &value[1]); - - return NGX_CONF_ERROR; - } - - if (cf->args->nelts == 3) { - if (ngx_strcmp(value[2].data, "utf8") == 0) { - GeoIP_set_charset(gcf->city, GEOIP_CHARSET_UTF8); - - } else { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "invalid parameter \"%V\"", &value[2]); - return NGX_CONF_ERROR; - } - } - - switch (gcf->city->databaseType) { - - case GEOIP_CITY_EDITION_REV0: - case GEOIP_CITY_EDITION_REV1: - - return NGX_CONF_OK; - -#if (NGX_HAVE_GEOIP_V6) - case GEOIP_CITY_EDITION_REV0_V6: - case GEOIP_CITY_EDITION_REV1_V6: - - gcf->city_v6 = 1; - return NGX_CONF_OK; -#endif - - default: - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "invalid GeoIP City database \"%V\" type:%d", - &value[1], gcf->city->databaseType); - return NGX_CONF_ERROR; - } -} - - -static void -ngx_stream_geoip_cleanup(void *data) -{ - ngx_stream_geoip_conf_t *gcf = data; - - if (gcf->country) { - GeoIP_delete(gcf->country); - } - - if (gcf->org) { - GeoIP_delete(gcf->org); - } - - if (gcf->city) { - GeoIP_delete(gcf->city); - } -} diff --git a/app/nginx/src/stream/ngx_stream_handler.c b/app/nginx/src/stream/ngx_stream_handler.c deleted file mode 100644 index 669b6a1..0000000 --- a/app/nginx/src/stream/ngx_stream_handler.c +++ /dev/null @@ -1,385 +0,0 @@ - -/* - * Copyright (C) Roman Arutyunyan - * Copyright (C) Nginx, Inc. - */ - - -#include <ngx_config.h> -#include <ngx_core.h> -#include <ngx_event.h> -#include <ngx_stream.h> - - -static void ngx_stream_log_session(ngx_stream_session_t *s); -static void ngx_stream_close_connection(ngx_connection_t *c); -static u_char *ngx_stream_log_error(ngx_log_t *log, u_char *buf, size_t len); -static void ngx_stream_proxy_protocol_handler(ngx_event_t *rev); - - -void -ngx_stream_init_connection(ngx_connection_t *c) -{ - u_char text[NGX_SOCKADDR_STRLEN]; - size_t len; - ngx_uint_t i; - ngx_time_t *tp; - ngx_event_t *rev; - struct sockaddr *sa; - ngx_stream_port_t *port; - struct sockaddr_in *sin; - ngx_stream_in_addr_t *addr; - ngx_stream_session_t *s; - ngx_stream_addr_conf_t *addr_conf; -#if (NGX_HAVE_INET6) - struct sockaddr_in6 *sin6; - ngx_stream_in6_addr_t *addr6; -#endif - ngx_stream_core_srv_conf_t *cscf; - ngx_stream_core_main_conf_t *cmcf; - - /* find the server configuration for the address:port */ - - port = c->listening->servers; - - if (port->naddrs > 1) { - - /* - * There are several addresses on this port and one of them - * is the "*:port" wildcard so getsockname() is needed to determine - * the server address. - * - * AcceptEx() and recvmsg() already gave this address. - */ - - if (ngx_connection_local_sockaddr(c, NULL, 0) != NGX_OK) { - ngx_stream_close_connection(c); - return; - } - - sa = c->local_sockaddr; - - switch (sa->sa_family) { - -#if (NGX_HAVE_INET6) - case AF_INET6: - sin6 = (struct sockaddr_in6 *) sa; - - addr6 = port->addrs; - - /* the last address is "*" */ - - for (i = 0; i < port->naddrs - 1; i++) { - if (ngx_memcmp(&addr6[i].addr6, &sin6->sin6_addr, 16) == 0) { - break; - } - } - - addr_conf = &addr6[i].conf; - - break; -#endif - - default: /* AF_INET */ - sin = (struct sockaddr_in *) sa; - - addr = port->addrs; - - /* the last address is "*" */ - - for (i = 0; i < port->naddrs - 1; i++) { - if (addr[i].addr == sin->sin_addr.s_addr) { - break; - } - } - - addr_conf = &addr[i].conf; - - break; - } - - } else { - switch (c->local_sockaddr->sa_family) { - -#if (NGX_HAVE_INET6) - case AF_INET6: - addr6 = port->addrs; - addr_conf = &addr6[0].conf; - break; -#endif - - default: /* AF_INET */ - addr = port->addrs; - addr_conf = &addr[0].conf; - break; - } - } - - s = ngx_pcalloc(c->pool, sizeof(ngx_stream_session_t)); - if (s == NULL) { - ngx_stream_close_connection(c); - return; - } - - s->signature = NGX_STREAM_MODULE; - s->main_conf = addr_conf->ctx->main_conf; - s->srv_conf = addr_conf->ctx->srv_conf; - -#if (NGX_STREAM_SSL) - s->ssl = addr_conf->ssl; -#endif - - if (c->buffer) { - s->received += c->buffer->last - c->buffer->pos; - } - - s->connection = c; - c->data = s; - - cscf = ngx_stream_get_module_srv_conf(s, ngx_stream_core_module); - - ngx_set_connection_log(c, cscf->error_log); - - len = ngx_sock_ntop(c->sockaddr, c->socklen, text, NGX_SOCKADDR_STRLEN, 1); - - ngx_log_error(NGX_LOG_INFO, c->log, 0, "*%uA %sclient %*s connected to %V", - c->number, c->type == SOCK_DGRAM ? "udp " : "", - len, text, &addr_conf->addr_text); - - c->log->connection = c->number; - c->log->handler = ngx_stream_log_error; - c->log->data = s; - c->log->action = "initializing session"; - c->log_error = NGX_ERROR_INFO; - - s->ctx = ngx_pcalloc(c->pool, sizeof(void *) * ngx_stream_max_module); - if (s->ctx == NULL) { - ngx_stream_close_connection(c); - return; - } - - cmcf = ngx_stream_get_module_main_conf(s, ngx_stream_core_module); - - s->variables = ngx_pcalloc(s->connection->pool, - cmcf->variables.nelts - * sizeof(ngx_stream_variable_value_t)); - - if (s->variables == NULL) { - ngx_stream_close_connection(c); - return; - } - - tp = ngx_timeofday(); - s->start_sec = tp->sec; - s->start_msec = tp->msec; - - rev = c->read; - rev->handler = ngx_stream_session_handler; - - if (addr_conf->proxy_protocol) { - c->log->action = "reading PROXY protocol"; - - rev->handler = ngx_stream_proxy_protocol_handler; - - if (!rev->ready) { - ngx_add_timer(rev, cscf->proxy_protocol_timeout); - - if (ngx_handle_read_event(rev, 0) != NGX_OK) { - ngx_stream_finalize_session(s, - NGX_STREAM_INTERNAL_SERVER_ERROR); - } - - return; - } - } - - if (ngx_use_accept_mutex) { - ngx_post_event(rev, &ngx_posted_events); - return; - } - - rev->handler(rev); -} - - -static void -ngx_stream_proxy_protocol_handler(ngx_event_t *rev) -{ - u_char *p, buf[NGX_PROXY_PROTOCOL_MAX_HEADER]; - size_t size; - ssize_t n; - ngx_err_t err; - ngx_connection_t *c; - ngx_stream_session_t *s; - ngx_stream_core_srv_conf_t *cscf; - - c = rev->data; - s = c->data; - - ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0, - "stream PROXY protocol handler"); - - if (rev->timedout) { - ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out"); - ngx_stream_finalize_session(s, NGX_STREAM_OK); - return; - } - - n = recv(c->fd, (char *) buf, sizeof(buf), MSG_PEEK); - - err = ngx_socket_errno; - - ngx_log_debug1(NGX_LOG_DEBUG_STREAM, c->log, 0, "recv(): %z", n); - - if (n == -1) { - if (err == NGX_EAGAIN) { - rev->ready = 0; - - if (!rev->timer_set) { - cscf = ngx_stream_get_module_srv_conf(s, - ngx_stream_core_module); - - ngx_add_timer(rev, cscf->proxy_protocol_timeout); - } - - if (ngx_handle_read_event(rev, 0) != NGX_OK) { - ngx_stream_finalize_session(s, - NGX_STREAM_INTERNAL_SERVER_ERROR); - } - - return; - } - - ngx_connection_error(c, err, "recv() failed"); - - ngx_stream_finalize_session(s, NGX_STREAM_OK); - return; - } - - if (rev->timer_set) { - ngx_del_timer(rev); - } - - p = ngx_proxy_protocol_read(c, buf, buf + n); - - if (p == NULL) { - ngx_stream_finalize_session(s, NGX_STREAM_BAD_REQUEST); - return; - } - - size = p - buf; - - if (c->recv(c, buf, size) != (ssize_t) size) { - ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR); - return; - } - - c->log->action = "initializing session"; - - ngx_stream_session_handler(rev); -} - - -void -ngx_stream_session_handler(ngx_event_t *rev) -{ - ngx_connection_t *c; - ngx_stream_session_t *s; - - c = rev->data; - s = c->data; - - ngx_stream_core_run_phases(s); -} - - -void -ngx_stream_finalize_session(ngx_stream_session_t *s, ngx_uint_t rc) -{ - ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0, - "finalize stream session: %i", rc); - - s->status = rc; - - ngx_stream_log_session(s); - - ngx_stream_close_connection(s->connection); -} - - -static void -ngx_stream_log_session(ngx_stream_session_t *s) -{ - ngx_uint_t i, n; - ngx_stream_handler_pt *log_handler; - ngx_stream_core_main_conf_t *cmcf; - - cmcf = ngx_stream_get_module_main_conf(s, ngx_stream_core_module); - - log_handler = cmcf->phases[NGX_STREAM_LOG_PHASE].handlers.elts; - n = cmcf->phases[NGX_STREAM_LOG_PHASE].handlers.nelts; - - for (i = 0; i < n; i++) { - log_handler[i](s); - } -} - - -static void -ngx_stream_close_connection(ngx_connection_t *c) -{ - ngx_pool_t *pool; - - ngx_log_debug1(NGX_LOG_DEBUG_STREAM, c->log, 0, - "close stream connection: %d", c->fd); - -#if (NGX_STREAM_SSL) - - if (c->ssl) { - if (ngx_ssl_shutdown(c) == NGX_AGAIN) { - c->ssl->handler = ngx_stream_close_connection; - return; - } - } - -#endif - -#if (NGX_STAT_STUB) - (void) ngx_atomic_fetch_add(ngx_stat_active, -1); -#endif - - pool = c->pool; - - ngx_close_connection(c); - - ngx_destroy_pool(pool); -} - - -static u_char * -ngx_stream_log_error(ngx_log_t *log, u_char *buf, size_t len) -{ - u_char *p; - ngx_stream_session_t *s; - - if (log->action) { - p = ngx_snprintf(buf, len, " while %s", log->action); - len -= p - buf; - buf = p; - } - - s = log->data; - - p = ngx_snprintf(buf, len, ", %sclient: %V, server: %V", - s->connection->type == SOCK_DGRAM ? "udp " : "", - &s->connection->addr_text, - &s->connection->listening->addr_text); - len -= p - buf; - buf = p; - - if (s->log_handler) { - p = s->log_handler(log, buf, len); - } - - return p; -} diff --git a/app/nginx/src/stream/ngx_stream_limit_conn_module.c b/app/nginx/src/stream/ngx_stream_limit_conn_module.c deleted file mode 100644 index b64a426..0000000 --- a/app/nginx/src/stream/ngx_stream_limit_conn_module.c +++ /dev/null @@ -1,646 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) Nginx, Inc. - */ - - -#include <ngx_config.h> -#include <ngx_core.h> -#include <ngx_stream.h> - - -typedef struct { - u_char color; - u_char len; - u_short conn; - u_char data[1]; -} ngx_stream_limit_conn_node_t; - - -typedef struct { - ngx_shm_zone_t *shm_zone; - ngx_rbtree_node_t *node; -} ngx_stream_limit_conn_cleanup_t; - - -typedef struct { - ngx_rbtree_t *rbtree; - ngx_stream_complex_value_t key; -} ngx_stream_limit_conn_ctx_t; - - -typedef struct { - ngx_shm_zone_t *shm_zone; - ngx_uint_t conn; -} ngx_stream_limit_conn_limit_t; - - -typedef struct { - ngx_array_t limits; - ngx_uint_t log_level; -} ngx_stream_limit_conn_conf_t; - - -static ngx_rbtree_node_t *ngx_stream_limit_conn_lookup(ngx_rbtree_t *rbtree, - ngx_str_t *key, uint32_t hash); -static void ngx_stream_limit_conn_cleanup(void *data); -static ngx_inline void ngx_stream_limit_conn_cleanup_all(ngx_pool_t *pool); - -static void *ngx_stream_limit_conn_create_conf(ngx_conf_t *cf); -static char *ngx_stream_limit_conn_merge_conf(ngx_conf_t *cf, void *parent, - void *child); -static char *ngx_stream_limit_conn_zone(ngx_conf_t *cf, ngx_command_t *cmd, - void *conf); -static char *ngx_stream_limit_conn(ngx_conf_t *cf, ngx_command_t *cmd, - void *conf); -static ngx_int_t ngx_stream_limit_conn_init(ngx_conf_t *cf); - - -static ngx_conf_enum_t ngx_stream_limit_conn_log_levels[] = { - { ngx_string("info"), NGX_LOG_INFO }, - { ngx_string("notice"), NGX_LOG_NOTICE }, - { ngx_string("warn"), NGX_LOG_WARN }, - { ngx_string("error"), NGX_LOG_ERR }, - { ngx_null_string, 0 } -}; - - -static ngx_command_t ngx_stream_limit_conn_commands[] = { - - { ngx_string("limit_conn_zone"), - NGX_STREAM_MAIN_CONF|NGX_CONF_TAKE2, - ngx_stream_limit_conn_zone, - 0, - 0, - NULL }, - - { ngx_string("limit_conn"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE2, - ngx_stream_limit_conn, - NGX_STREAM_SRV_CONF_OFFSET, - 0, - NULL }, - - { ngx_string("limit_conn_log_level"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_enum_slot, - NGX_STREAM_SRV_CONF_OFFSET, - offsetof(ngx_stream_limit_conn_conf_t, log_level), - &ngx_stream_limit_conn_log_levels }, - - ngx_null_command -}; - - -static ngx_stream_module_t ngx_stream_limit_conn_module_ctx = { - NULL, /* preconfiguration */ - ngx_stream_limit_conn_init, /* postconfiguration */ - - NULL, /* create main configuration */ - NULL, /* init main configuration */ - - ngx_stream_limit_conn_create_conf, /* create server configuration */ - ngx_stream_limit_conn_merge_conf /* merge server configuration */ -}; - - -ngx_module_t ngx_stream_limit_conn_module = { - NGX_MODULE_V1, - &ngx_stream_limit_conn_module_ctx, /* module context */ - ngx_stream_limit_conn_commands, /* module directives */ - NGX_STREAM_MODULE, /* module type */ - NULL, /* init master */ - NULL, /* init module */ - NULL, /* init process */ - NULL, /* init thread */ - NULL, /* exit thread */ - NULL, /* exit process */ - NULL, /* exit master */ - NGX_MODULE_V1_PADDING -}; - - -static ngx_int_t -ngx_stream_limit_conn_handler(ngx_stream_session_t *s) -{ - size_t n; - uint32_t hash; - ngx_str_t key; - ngx_uint_t i; - ngx_slab_pool_t *shpool; - ngx_rbtree_node_t *node; - ngx_pool_cleanup_t *cln; - ngx_stream_limit_conn_ctx_t *ctx; - ngx_stream_limit_conn_node_t *lc; - ngx_stream_limit_conn_conf_t *lccf; - ngx_stream_limit_conn_limit_t *limits; - ngx_stream_limit_conn_cleanup_t *lccln; - - lccf = ngx_stream_get_module_srv_conf(s, ngx_stream_limit_conn_module); - limits = lccf->limits.elts; - - for (i = 0; i < lccf->limits.nelts; i++) { - ctx = limits[i].shm_zone->data; - - if (ngx_stream_complex_value(s, &ctx->key, &key) != NGX_OK) { - return NGX_ERROR; - } - - if (key.len == 0) { - continue; - } - - if (key.len > 255) { - ngx_log_error(NGX_LOG_ERR, s->connection->log, 0, - "the value of the \"%V\" key " - "is more than 255 bytes: \"%V\"", - &ctx->key.value, &key); - continue; - } - - hash = ngx_crc32_short(key.data, key.len); - - shpool = (ngx_slab_pool_t *) limits[i].shm_zone->shm.addr; - - ngx_shmtx_lock(&shpool->mutex); - - node = ngx_stream_limit_conn_lookup(ctx->rbtree, &key, hash); - - if (node == NULL) { - - n = offsetof(ngx_rbtree_node_t, color) - + offsetof(ngx_stream_limit_conn_node_t, data) - + key.len; - - node = ngx_slab_alloc_locked(shpool, n); - - if (node == NULL) { - ngx_shmtx_unlock(&shpool->mutex); - ngx_stream_limit_conn_cleanup_all(s->connection->pool); - return NGX_STREAM_SERVICE_UNAVAILABLE; - } - - lc = (ngx_stream_limit_conn_node_t *) &node->color; - - node->key = hash; - lc->len = (u_char) key.len; - lc->conn = 1; - ngx_memcpy(lc->data, key.data, key.len); - - ngx_rbtree_insert(ctx->rbtree, node); - - } else { - - lc = (ngx_stream_limit_conn_node_t *) &node->color; - - if ((ngx_uint_t) lc->conn >= limits[i].conn) { - - ngx_shmtx_unlock(&shpool->mutex); - - ngx_log_error(lccf->log_level, s->connection->log, 0, - "limiting connections by zone \"%V\"", - &limits[i].shm_zone->shm.name); - - ngx_stream_limit_conn_cleanup_all(s->connection->pool); - return NGX_STREAM_SERVICE_UNAVAILABLE; - } - - lc->conn++; - } - - ngx_log_debug2(NGX_LOG_DEBUG_STREAM, s->connection->log, 0, - "limit conn: %08Xi %d", node->key, lc->conn); - - ngx_shmtx_unlock(&shpool->mutex); - - cln = ngx_pool_cleanup_add(s->connection->pool, - sizeof(ngx_stream_limit_conn_cleanup_t)); - if (cln == NULL) { - return NGX_ERROR; - } - - cln->handler = ngx_stream_limit_conn_cleanup; - lccln = cln->data; - - lccln->shm_zone = limits[i].shm_zone; - lccln->node = node; - } - - return NGX_DECLINED; -} - - -static void -ngx_stream_limit_conn_rbtree_insert_value(ngx_rbtree_node_t *temp, - ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel) -{ - ngx_rbtree_node_t **p; - ngx_stream_limit_conn_node_t *lcn, *lcnt; - - for ( ;; ) { - - if (node->key < temp->key) { - - p = &temp->left; - - } else if (node->key > temp->key) { - - p = &temp->right; - - } else { /* node->key == temp->key */ - - lcn = (ngx_stream_limit_conn_node_t *) &node->color; - lcnt = (ngx_stream_limit_conn_node_t *) &temp->color; - - p = (ngx_memn2cmp(lcn->data, lcnt->data, lcn->len, lcnt->len) < 0) - ? &temp->left : &temp->right; - } - - if (*p == sentinel) { - break; - } - - temp = *p; - } - - *p = node; - node->parent = temp; - node->left = sentinel; - node->right = sentinel; - ngx_rbt_red(node); -} - - -static ngx_rbtree_node_t * -ngx_stream_limit_conn_lookup(ngx_rbtree_t *rbtree, ngx_str_t *key, - uint32_t hash) -{ - ngx_int_t rc; - ngx_rbtree_node_t *node, *sentinel; - ngx_stream_limit_conn_node_t *lcn; - - node = rbtree->root; - sentinel = rbtree->sentinel; - - while (node != sentinel) { - - if (hash < node->key) { - node = node->left; - continue; - } - - if (hash > node->key) { - node = node->right; - continue; - } - - /* hash == node->key */ - - lcn = (ngx_stream_limit_conn_node_t *) &node->color; - - rc = ngx_memn2cmp(key->data, lcn->data, key->len, (size_t) lcn->len); - - if (rc == 0) { - return node; - } - - node = (rc < 0) ? node->left : node->right; - } - - return NULL; -} - - -static void -ngx_stream_limit_conn_cleanup(void *data) -{ - ngx_stream_limit_conn_cleanup_t *lccln = data; - - ngx_slab_pool_t *shpool; - ngx_rbtree_node_t *node; - ngx_stream_limit_conn_ctx_t *ctx; - ngx_stream_limit_conn_node_t *lc; - - ctx = lccln->shm_zone->data; - shpool = (ngx_slab_pool_t *) lccln->shm_zone->shm.addr; - node = lccln->node; - lc = (ngx_stream_limit_conn_node_t *) &node->color; - - ngx_shmtx_lock(&shpool->mutex); - - ngx_log_debug2(NGX_LOG_DEBUG_STREAM, lccln->shm_zone->shm.log, 0, - "limit conn cleanup: %08Xi %d", node->key, lc->conn); - - lc->conn--; - - if (lc->conn == 0) { - ngx_rbtree_delete(ctx->rbtree, node); - ngx_slab_free_locked(shpool, node); - } - - ngx_shmtx_unlock(&shpool->mutex); -} - - -static ngx_inline void -ngx_stream_limit_conn_cleanup_all(ngx_pool_t *pool) -{ - ngx_pool_cleanup_t *cln; - - cln = pool->cleanup; - - while (cln && cln->handler == ngx_stream_limit_conn_cleanup) { - ngx_stream_limit_conn_cleanup(cln->data); - cln = cln->next; - } - - pool->cleanup = cln; -} - - -static ngx_int_t -ngx_stream_limit_conn_init_zone(ngx_shm_zone_t *shm_zone, void *data) -{ - ngx_stream_limit_conn_ctx_t *octx = data; - - size_t len; - ngx_slab_pool_t *shpool; - ngx_rbtree_node_t *sentinel; - ngx_stream_limit_conn_ctx_t *ctx; - - ctx = shm_zone->data; - - if (octx) { - if (ctx->key.value.len != octx->key.value.len - || ngx_strncmp(ctx->key.value.data, octx->key.value.data, - ctx->key.value.len) - != 0) - { - ngx_log_error(NGX_LOG_EMERG, shm_zone->shm.log, 0, - "limit_conn_zone \"%V\" uses the \"%V\" key " - "while previously it used the \"%V\" key", - &shm_zone->shm.name, &ctx->key.value, - &octx->key.value); - return NGX_ERROR; - } - - ctx->rbtree = octx->rbtree; - - return NGX_OK; - } - - shpool = (ngx_slab_pool_t *) shm_zone->shm.addr; - - if (shm_zone->shm.exists) { - ctx->rbtree = shpool->data; - - return NGX_OK; - } - - ctx->rbtree = ngx_slab_alloc(shpool, sizeof(ngx_rbtree_t)); - if (ctx->rbtree == NULL) { - return NGX_ERROR; - } - - shpool->data = ctx->rbtree; - - sentinel = ngx_slab_alloc(shpool, sizeof(ngx_rbtree_node_t)); - if (sentinel == NULL) { - return NGX_ERROR; - } - - ngx_rbtree_init(ctx->rbtree, sentinel, - ngx_stream_limit_conn_rbtree_insert_value); - - len = sizeof(" in limit_conn_zone \"\"") + shm_zone->shm.name.len; - - shpool->log_ctx = ngx_slab_alloc(shpool, len); - if (shpool->log_ctx == NULL) { - return NGX_ERROR; - } - - ngx_sprintf(shpool->log_ctx, " in limit_conn_zone \"%V\"%Z", - &shm_zone->shm.name); - - return NGX_OK; -} - - -static void * -ngx_stream_limit_conn_create_conf(ngx_conf_t *cf) -{ - ngx_stream_limit_conn_conf_t *conf; - - conf = ngx_pcalloc(cf->pool, sizeof(ngx_stream_limit_conn_conf_t)); - if (conf == NULL) { - return NULL; - } - - /* - * set by ngx_pcalloc(): - * - * conf->limits.elts = NULL; - */ - - conf->log_level = NGX_CONF_UNSET_UINT; - - return conf; -} - - -static char * -ngx_stream_limit_conn_merge_conf(ngx_conf_t *cf, void *parent, void *child) -{ - ngx_stream_limit_conn_conf_t *prev = parent; - ngx_stream_limit_conn_conf_t *conf = child; - - if (conf->limits.elts == NULL) { - conf->limits = prev->limits; - } - - ngx_conf_merge_uint_value(conf->log_level, prev->log_level, NGX_LOG_ERR); - - return NGX_CONF_OK; -} - - -static char * -ngx_stream_limit_conn_zone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) -{ - u_char *p; - ssize_t size; - ngx_str_t *value, name, s; - ngx_uint_t i; - ngx_shm_zone_t *shm_zone; - ngx_stream_limit_conn_ctx_t *ctx; - ngx_stream_compile_complex_value_t ccv; - - value = cf->args->elts; - - ctx = ngx_pcalloc(cf->pool, sizeof(ngx_stream_limit_conn_ctx_t)); - if (ctx == NULL) { - return NGX_CONF_ERROR; - } - - ngx_memzero(&ccv, sizeof(ngx_stream_compile_complex_value_t)); - - ccv.cf = cf; - ccv.value = &value[1]; - ccv.complex_value = &ctx->key; - - if (ngx_stream_compile_complex_value(&ccv) != NGX_OK) { - return NGX_CONF_ERROR; - } - - size = 0; - name.len = 0; - - for (i = 2; i < cf->args->nelts; i++) { - - if (ngx_strncmp(value[i].data, "zone=", 5) == 0) { - - name.data = value[i].data + 5; - - p = (u_char *) ngx_strchr(name.data, ':'); - - if (p == NULL) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "invalid zone size \"%V\"", &value[i]); - return NGX_CONF_ERROR; - } - - name.len = p - name.data; - - s.data = p + 1; - s.len = value[i].data + value[i].len - s.data; - - size = ngx_parse_size(&s); - - if (size == NGX_ERROR) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "invalid zone size \"%V\"", &value[i]); - return NGX_CONF_ERROR; - } - - if (size < (ssize_t) (8 * ngx_pagesize)) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "zone \"%V\" is too small", &value[i]); - return NGX_CONF_ERROR; - } - - continue; - } - - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "invalid parameter \"%V\"", &value[i]); - return NGX_CONF_ERROR; - } - - if (name.len == 0) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "\"%V\" must have \"zone\" parameter", - &cmd->name); - return NGX_CONF_ERROR; - } - - shm_zone = ngx_shared_memory_add(cf, &name, size, - &ngx_stream_limit_conn_module); - if (shm_zone == NULL) { - return NGX_CONF_ERROR; - } - - if (shm_zone->data) { - ctx = shm_zone->data; - - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "%V \"%V\" is already bound to key \"%V\"", - &cmd->name, &name, &ctx->key.value); - return NGX_CONF_ERROR; - } - - shm_zone->init = ngx_stream_limit_conn_init_zone; - shm_zone->data = ctx; - - return NGX_CONF_OK; -} - - -static char * -ngx_stream_limit_conn(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) -{ - ngx_shm_zone_t *shm_zone; - ngx_stream_limit_conn_conf_t *lccf = conf; - ngx_stream_limit_conn_limit_t *limit, *limits; - - ngx_str_t *value; - ngx_int_t n; - ngx_uint_t i; - - value = cf->args->elts; - - shm_zone = ngx_shared_memory_add(cf, &value[1], 0, - &ngx_stream_limit_conn_module); - if (shm_zone == NULL) { - return NGX_CONF_ERROR; - } - - limits = lccf->limits.elts; - - if (limits == NULL) { - if (ngx_array_init(&lccf->limits, cf->pool, 1, - sizeof(ngx_stream_limit_conn_limit_t)) - != NGX_OK) - { - return NGX_CONF_ERROR; - } - } - - for (i = 0; i < lccf->limits.nelts; i++) { - if (shm_zone == limits[i].shm_zone) { - return "is duplicate"; - } - } - - n = ngx_atoi(value[2].data, value[2].len); - if (n <= 0) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "invalid number of connections \"%V\"", &value[2]); - return NGX_CONF_ERROR; - } - - if (n > 65535) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "connection limit must be less 65536"); - return NGX_CONF_ERROR; - } - - limit = ngx_array_push(&lccf->limits); - if (limit == NULL) { - return NGX_CONF_ERROR; - } - - limit->conn = n; - limit->shm_zone = shm_zone; - - return NGX_CONF_OK; -} - - -static ngx_int_t -ngx_stream_limit_conn_init(ngx_conf_t *cf) -{ - ngx_stream_handler_pt *h; - ngx_stream_core_main_conf_t *cmcf; - - cmcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_core_module); - - h = ngx_array_push(&cmcf->phases[NGX_STREAM_PREACCESS_PHASE].handlers); - if (h == NULL) { - return NGX_ERROR; - } - - *h = ngx_stream_limit_conn_handler; - - return NGX_OK; -} diff --git a/app/nginx/src/stream/ngx_stream_log_module.c b/app/nginx/src/stream/ngx_stream_log_module.c deleted file mode 100644 index 466bdda..0000000 --- a/app/nginx/src/stream/ngx_stream_log_module.c +++ /dev/null @@ -1,1543 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) Nginx, Inc. - */ - - -#include <ngx_config.h> -#include <ngx_core.h> -#include <ngx_stream.h> - -#if (NGX_ZLIB) -#include <zlib.h> -#endif - - -typedef struct ngx_stream_log_op_s ngx_stream_log_op_t; - -typedef u_char *(*ngx_stream_log_op_run_pt) (ngx_stream_session_t *s, - u_char *buf, ngx_stream_log_op_t *op); - -typedef size_t (*ngx_stream_log_op_getlen_pt) (ngx_stream_session_t *s, - uintptr_t data); - - -struct ngx_stream_log_op_s { - size_t len; - ngx_stream_log_op_getlen_pt getlen; - ngx_stream_log_op_run_pt run; - uintptr_t data; -}; - - -typedef struct { - ngx_str_t name; - ngx_array_t *flushes; - ngx_array_t *ops; /* array of ngx_stream_log_op_t */ -} ngx_stream_log_fmt_t; - - -typedef struct { - ngx_array_t formats; /* array of ngx_stream_log_fmt_t */ -} ngx_stream_log_main_conf_t; - - -typedef struct { - u_char *start; - u_char *pos; - u_char *last; - - ngx_event_t *event; - ngx_msec_t flush; - ngx_int_t gzip; -} ngx_stream_log_buf_t; - - -typedef struct { - ngx_array_t *lengths; - ngx_array_t *values; -} ngx_stream_log_script_t; - - -typedef struct { - ngx_open_file_t *file; - ngx_stream_log_script_t *script; - time_t disk_full_time; - time_t error_log_time; - ngx_syslog_peer_t *syslog_peer; - ngx_stream_log_fmt_t *format; - ngx_stream_complex_value_t *filter; -} ngx_stream_log_t; - - -typedef struct { - ngx_array_t *logs; /* array of ngx_stream_log_t */ - - ngx_open_file_cache_t *open_file_cache; - time_t open_file_cache_valid; - ngx_uint_t open_file_cache_min_uses; - - ngx_uint_t off; /* unsigned off:1 */ -} ngx_stream_log_srv_conf_t; - - -typedef struct { - ngx_str_t name; - size_t len; - ngx_stream_log_op_run_pt run; -} ngx_stream_log_var_t; - - -static void ngx_stream_log_write(ngx_stream_session_t *s, ngx_stream_log_t *log, - u_char *buf, size_t len); -static ssize_t ngx_stream_log_script_write(ngx_stream_session_t *s, - ngx_stream_log_script_t *script, u_char **name, u_char *buf, size_t len); - -#if (NGX_ZLIB) -static ssize_t ngx_stream_log_gzip(ngx_fd_t fd, u_char *buf, size_t len, - ngx_int_t level, ngx_log_t *log); - -static void *ngx_stream_log_gzip_alloc(void *opaque, u_int items, u_int size); -static void ngx_stream_log_gzip_free(void *opaque, void *address); -#endif - -static void ngx_stream_log_flush(ngx_open_file_t *file, ngx_log_t *log); -static void ngx_stream_log_flush_handler(ngx_event_t *ev); - -static ngx_int_t ngx_stream_log_variable_compile(ngx_conf_t *cf, - ngx_stream_log_op_t *op, ngx_str_t *value, ngx_uint_t json); -static size_t ngx_stream_log_variable_getlen(ngx_stream_session_t *s, - uintptr_t data); -static u_char *ngx_stream_log_variable(ngx_stream_session_t *s, u_char *buf, - ngx_stream_log_op_t *op); -static uintptr_t ngx_stream_log_escape(u_char *dst, u_char *src, size_t size); -static size_t ngx_stream_log_json_variable_getlen(ngx_stream_session_t *s, - uintptr_t data); -static u_char *ngx_stream_log_json_variable(ngx_stream_session_t *s, - u_char *buf, ngx_stream_log_op_t *op); - - -static void *ngx_stream_log_create_main_conf(ngx_conf_t *cf); -static void *ngx_stream_log_create_srv_conf(ngx_conf_t *cf); -static char *ngx_stream_log_merge_srv_conf(ngx_conf_t *cf, void *parent, - void *child); -static char *ngx_stream_log_set_log(ngx_conf_t *cf, ngx_command_t *cmd, - void *conf); -static char *ngx_stream_log_set_format(ngx_conf_t *cf, ngx_command_t *cmd, - void *conf); -static char *ngx_stream_log_compile_format(ngx_conf_t *cf, - ngx_array_t *flushes, ngx_array_t *ops, ngx_array_t *args, ngx_uint_t s); -static char *ngx_stream_log_open_file_cache(ngx_conf_t *cf, ngx_command_t *cmd, - void *conf); -static ngx_int_t ngx_stream_log_init(ngx_conf_t *cf); - - -static ngx_command_t ngx_stream_log_commands[] = { - - { ngx_string("log_format"), - NGX_STREAM_MAIN_CONF|NGX_CONF_2MORE, - ngx_stream_log_set_format, - NGX_STREAM_MAIN_CONF_OFFSET, - 0, - NULL }, - - { ngx_string("access_log"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_1MORE, - ngx_stream_log_set_log, - NGX_STREAM_SRV_CONF_OFFSET, - 0, - NULL }, - - { ngx_string("open_log_file_cache"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1234, - ngx_stream_log_open_file_cache, - NGX_STREAM_SRV_CONF_OFFSET, - 0, - NULL }, - - ngx_null_command -}; - - -static ngx_stream_module_t ngx_stream_log_module_ctx = { - NULL, /* preconfiguration */ - ngx_stream_log_init, /* postconfiguration */ - - ngx_stream_log_create_main_conf, /* create main configuration */ - NULL, /* init main configuration */ - - ngx_stream_log_create_srv_conf, /* create server configuration */ - ngx_stream_log_merge_srv_conf /* merge server configuration */ -}; - - -ngx_module_t ngx_stream_log_module = { - NGX_MODULE_V1, - &ngx_stream_log_module_ctx, /* module context */ - ngx_stream_log_commands, /* module directives */ - NGX_STREAM_MODULE, /* module type */ - NULL, /* init master */ - NULL, /* init module */ - NULL, /* init process */ - NULL, /* init thread */ - NULL, /* exit thread */ - NULL, /* exit process */ - NULL, /* exit master */ - NGX_MODULE_V1_PADDING -}; - - -static ngx_int_t -ngx_stream_log_handler(ngx_stream_session_t *s) -{ - u_char *line, *p; - size_t len, size; - ssize_t n; - ngx_str_t val; - ngx_uint_t i, l; - ngx_stream_log_t *log; - ngx_stream_log_op_t *op; - ngx_stream_log_buf_t *buffer; - ngx_stream_log_srv_conf_t *lscf; - - ngx_log_debug0(NGX_LOG_DEBUG_STREAM, s->connection->log, 0, - "stream log handler"); - - lscf = ngx_stream_get_module_srv_conf(s, ngx_stream_log_module); - - if (lscf->off || lscf->logs == NULL) { - return NGX_OK; - } - - log = lscf->logs->elts; - for (l = 0; l < lscf->logs->nelts; l++) { - - if (log[l].filter) { - if (ngx_stream_complex_value(s, log[l].filter, &val) != NGX_OK) { - return NGX_ERROR; - } - - if (val.len == 0 || (val.len == 1 && val.data[0] == '0')) { - continue; - } - } - - if (ngx_time() == log[l].disk_full_time) { - - /* - * on FreeBSD writing to a full filesystem with enabled softupdates - * may block process for much longer time than writing to non-full - * filesystem, so we skip writing to a log for one second - */ - - continue; - } - - ngx_stream_script_flush_no_cacheable_variables(s, - log[l].format->flushes); - - len = 0; - op = log[l].format->ops->elts; - for (i = 0; i < log[l].format->ops->nelts; i++) { - if (op[i].len == 0) { - len += op[i].getlen(s, op[i].data); - - } else { - len += op[i].len; - } - } - - if (log[l].syslog_peer) { - - /* length of syslog's PRI and HEADER message parts */ - len += sizeof("<255>Jan 01 00:00:00 ") - 1 - + ngx_cycle->hostname.len + 1 - + log[l].syslog_peer->tag.len + 2; - - goto alloc_line; - } - - len += NGX_LINEFEED_SIZE; - - buffer = log[l].file ? log[l].file->data : NULL; - - if (buffer) { - - if (len > (size_t) (buffer->last - buffer->pos)) { - - ngx_stream_log_write(s, &log[l], buffer->start, - buffer->pos - buffer->start); - - buffer->pos = buffer->start; - } - - if (len <= (size_t) (buffer->last - buffer->pos)) { - - p = buffer->pos; - - if (buffer->event && p == buffer->start) { - ngx_add_timer(buffer->event, buffer->flush); - } - - for (i = 0; i < log[l].format->ops->nelts; i++) { - p = op[i].run(s, p, &op[i]); - } - - ngx_linefeed(p); - - buffer->pos = p; - - continue; - } - - if (buffer->event && buffer->event->timer_set) { - ngx_del_timer(buffer->event); - } - } - - alloc_line: - - line = ngx_pnalloc(s->connection->pool, len); - if (line == NULL) { - return NGX_ERROR; - } - - p = line; - - if (log[l].syslog_peer) { - p = ngx_syslog_add_header(log[l].syslog_peer, line); - } - - for (i = 0; i < log[l].format->ops->nelts; i++) { - p = op[i].run(s, p, &op[i]); - } - - if (log[l].syslog_peer) { - - size = p - line; - - n = ngx_syslog_send(log[l].syslog_peer, line, size); - - if (n < 0) { - ngx_log_error(NGX_LOG_WARN, s->connection->log, 0, - "send() to syslog failed"); - - } else if ((size_t) n != size) { - ngx_log_error(NGX_LOG_WARN, s->connection->log, 0, - "send() to syslog has written only %z of %uz", - n, size); - } - - continue; - } - - ngx_linefeed(p); - - ngx_stream_log_write(s, &log[l], line, p - line); - } - - return NGX_OK; -} - - -static void -ngx_stream_log_write(ngx_stream_session_t *s, ngx_stream_log_t *log, - u_char *buf, size_t len) -{ - u_char *name; - time_t now; - ssize_t n; - ngx_err_t err; -#if (NGX_ZLIB) - ngx_stream_log_buf_t *buffer; -#endif - - if (log->script == NULL) { - name = log->file->name.data; - -#if (NGX_ZLIB) - buffer = log->file->data; - - if (buffer && buffer->gzip) { - n = ngx_stream_log_gzip(log->file->fd, buf, len, buffer->gzip, - s->connection->log); - } else { - n = ngx_write_fd(log->file->fd, buf, len); - } -#else - n = ngx_write_fd(log->file->fd, buf, len); -#endif - - } else { - name = NULL; - n = ngx_stream_log_script_write(s, log->script, &name, buf, len); - } - - if (n == (ssize_t) len) { - return; - } - - now = ngx_time(); - - if (n == -1) { - err = ngx_errno; - - if (err == NGX_ENOSPC) { - log->disk_full_time = now; - } - - if (now - log->error_log_time > 59) { - ngx_log_error(NGX_LOG_ALERT, s->connection->log, err, - ngx_write_fd_n " to \"%s\" failed", name); - - log->error_log_time = now; - } - - return; - } - - if (now - log->error_log_time > 59) { - ngx_log_error(NGX_LOG_ALERT, s->connection->log, 0, - ngx_write_fd_n " to \"%s\" was incomplete: %z of %uz", - name, n, len); - - log->error_log_time = now; - } -} - - -static ssize_t -ngx_stream_log_script_write(ngx_stream_session_t *s, - ngx_stream_log_script_t *script, u_char **name, u_char *buf, size_t len) -{ - ssize_t n; - ngx_str_t log; - ngx_open_file_info_t of; - ngx_stream_log_srv_conf_t *lscf; - - if (ngx_stream_script_run(s, &log, script->lengths->elts, 1, - script->values->elts) - == NULL) - { - /* simulate successful logging */ - return len; - } - - log.data[log.len - 1] = '\0'; - *name = log.data; - - ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0, - "stream log \"%s\"", log.data); - - lscf = ngx_stream_get_module_srv_conf(s, ngx_stream_log_module); - - ngx_memzero(&of, sizeof(ngx_open_file_info_t)); - - of.log = 1; - of.valid = lscf->open_file_cache_valid; - of.min_uses = lscf->open_file_cache_min_uses; - of.directio = NGX_OPEN_FILE_DIRECTIO_OFF; - - if (ngx_open_cached_file(lscf->open_file_cache, &log, &of, - s->connection->pool) - != NGX_OK) - { - if (of.err == 0) { - /* simulate successful logging */ - return len; - } - - ngx_log_error(NGX_LOG_CRIT, s->connection->log, ngx_errno, - "%s \"%s\" failed", of.failed, log.data); - /* simulate successful logging */ - return len; - } - - ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0, - "stream log #%d", of.fd); - - n = ngx_write_fd(of.fd, buf, len); - - return n; -} - - -#if (NGX_ZLIB) - -static ssize_t -ngx_stream_log_gzip(ngx_fd_t fd, u_char *buf, size_t len, ngx_int_t level, - ngx_log_t *log) -{ - int rc, wbits, memlevel; - u_char *out; - size_t size; - ssize_t n; - z_stream zstream; - ngx_err_t err; - ngx_pool_t *pool; - - wbits = MAX_WBITS; - memlevel = MAX_MEM_LEVEL - 1; - - while ((ssize_t) len < ((1 << (wbits - 1)) - 262)) { - wbits--; - memlevel--; - } - - /* - * This is a formula from deflateBound() for conservative upper bound of - * compressed data plus 18 bytes of gzip wrapper. - */ - - size = len + ((len + 7) >> 3) + ((len + 63) >> 6) + 5 + 18; - - ngx_memzero(&zstream, sizeof(z_stream)); - - pool = ngx_create_pool(256, log); - if (pool == NULL) { - /* simulate successful logging */ - return len; - } - - pool->log = log; - - zstream.zalloc = ngx_stream_log_gzip_alloc; - zstream.zfree = ngx_stream_log_gzip_free; - zstream.opaque = pool; - - out = ngx_pnalloc(pool, size); - if (out == NULL) { - goto done; - } - - zstream.next_in = buf; - zstream.avail_in = len; - zstream.next_out = out; - zstream.avail_out = size; - - rc = deflateInit2(&zstream, (int) level, Z_DEFLATED, wbits + 16, memlevel, - Z_DEFAULT_STRATEGY); - - if (rc != Z_OK) { - ngx_log_error(NGX_LOG_ALERT, log, 0, "deflateInit2() failed: %d", rc); - goto done; - } - - ngx_log_debug4(NGX_LOG_DEBUG_STREAM, log, 0, - "deflate in: ni:%p no:%p ai:%ud ao:%ud", - zstream.next_in, zstream.next_out, - zstream.avail_in, zstream.avail_out); - - rc = deflate(&zstream, Z_FINISH); - - if (rc != Z_STREAM_END) { - ngx_log_error(NGX_LOG_ALERT, log, 0, - "deflate(Z_FINISH) failed: %d", rc); - goto done; - } - - ngx_log_debug5(NGX_LOG_DEBUG_STREAM, log, 0, - "deflate out: ni:%p no:%p ai:%ud ao:%ud rc:%d", - zstream.next_in, zstream.next_out, - zstream.avail_in, zstream.avail_out, - rc); - - size -= zstream.avail_out; - - rc = deflateEnd(&zstream); - - if (rc != Z_OK) { - ngx_log_error(NGX_LOG_ALERT, log, 0, "deflateEnd() failed: %d", rc); - goto done; - } - - n = ngx_write_fd(fd, out, size); - - if (n != (ssize_t) size) { - err = (n == -1) ? ngx_errno : 0; - - ngx_destroy_pool(pool); - - ngx_set_errno(err); - return -1; - } - -done: - - ngx_destroy_pool(pool); - - /* simulate successful logging */ - return len; -} - - -static void * -ngx_stream_log_gzip_alloc(void *opaque, u_int items, u_int size) -{ - ngx_pool_t *pool = opaque; - - ngx_log_debug2(NGX_LOG_DEBUG_STREAM, pool->log, 0, - "gzip alloc: n:%ud s:%ud", items, size); - - return ngx_palloc(pool, items * size); -} - - -static void -ngx_stream_log_gzip_free(void *opaque, void *address) -{ -#if 0 - ngx_pool_t *pool = opaque; - - ngx_log_debug1(NGX_LOG_DEBUG_STREAM, pool->log, 0, - "gzip free: %p", address); -#endif -} - -#endif - - -static void -ngx_stream_log_flush(ngx_open_file_t *file, ngx_log_t *log) -{ - size_t len; - ssize_t n; - ngx_stream_log_buf_t *buffer; - - buffer = file->data; - - len = buffer->pos - buffer->start; - - if (len == 0) { - return; - } - -#if (NGX_ZLIB) - if (buffer->gzip) { - n = ngx_stream_log_gzip(file->fd, buffer->start, len, buffer->gzip, - log); - } else { - n = ngx_write_fd(file->fd, buffer->start, len); - } -#else - n = ngx_write_fd(file->fd, buffer->start, len); -#endif - - if (n == -1) { - ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, - ngx_write_fd_n " to \"%s\" failed", - file->name.data); - - } else if ((size_t) n != len) { - ngx_log_error(NGX_LOG_ALERT, log, 0, - ngx_write_fd_n " to \"%s\" was incomplete: %z of %uz", - file->name.data, n, len); - } - - buffer->pos = buffer->start; - - if (buffer->event && buffer->event->timer_set) { - ngx_del_timer(buffer->event); - } -} - - -static void -ngx_stream_log_flush_handler(ngx_event_t *ev) -{ - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, 0, - "stream log buffer flush handler"); - - ngx_stream_log_flush(ev->data, ev->log); -} - - -static u_char * -ngx_stream_log_copy_short(ngx_stream_session_t *s, u_char *buf, - ngx_stream_log_op_t *op) -{ - size_t len; - uintptr_t data; - - len = op->len; - data = op->data; - - while (len--) { - *buf++ = (u_char) (data & 0xff); - data >>= 8; - } - - return buf; -} - - -static u_char * -ngx_stream_log_copy_long(ngx_stream_session_t *s, u_char *buf, - ngx_stream_log_op_t *op) -{ - return ngx_cpymem(buf, (u_char *) op->data, op->len); -} - - -static ngx_int_t -ngx_stream_log_variable_compile(ngx_conf_t *cf, ngx_stream_log_op_t *op, - ngx_str_t *value, ngx_uint_t json) -{ - ngx_int_t index; - - index = ngx_stream_get_variable_index(cf, value); - if (index == NGX_ERROR) { - return NGX_ERROR; - } - - op->len = 0; - - if (json) { - op->getlen = ngx_stream_log_json_variable_getlen; - op->run = ngx_stream_log_json_variable; - - } else { - op->getlen = ngx_stream_log_variable_getlen; - op->run = ngx_stream_log_variable; - } - - op->data = index; - - return NGX_OK; -} - - -static size_t -ngx_stream_log_variable_getlen(ngx_stream_session_t *s, uintptr_t data) -{ - uintptr_t len; - ngx_stream_variable_value_t *value; - - value = ngx_stream_get_indexed_variable(s, data); - - if (value == NULL || value->not_found) { - return 1; - } - - len = ngx_stream_log_escape(NULL, value->data, value->len); - - value->escape = len ? 1 : 0; - - return value->len + len * 3; -} - - -static u_char * -ngx_stream_log_variable(ngx_stream_session_t *s, u_char *buf, - ngx_stream_log_op_t *op) -{ - ngx_stream_variable_value_t *value; - - value = ngx_stream_get_indexed_variable(s, op->data); - - if (value == NULL || value->not_found) { - *buf = '-'; - return buf + 1; - } - - if (value->escape == 0) { - return ngx_cpymem(buf, value->data, value->len); - - } else { - return (u_char *) ngx_stream_log_escape(buf, value->data, value->len); - } -} - - -static uintptr_t -ngx_stream_log_escape(u_char *dst, u_char *src, size_t size) -{ - ngx_uint_t n; - static u_char hex[] = "0123456789ABCDEF"; - - static uint32_t escape[] = { - 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ - - /* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */ - 0x00000004, /* 0000 0000 0000 0000 0000 0000 0000 0100 */ - - /* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */ - 0x10000000, /* 0001 0000 0000 0000 0000 0000 0000 0000 */ - - /* ~}| {zyx wvut srqp onml kjih gfed cba` */ - 0x80000000, /* 1000 0000 0000 0000 0000 0000 0000 0000 */ - - 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ - 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ - 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ - 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ - }; - - - if (dst == NULL) { - - /* find the number of the characters to be escaped */ - - n = 0; - - while (size) { - if (escape[*src >> 5] & (1U << (*src & 0x1f))) { - n++; - } - src++; - size--; - } - - return (uintptr_t) n; - } - - while (size) { - if (escape[*src >> 5] & (1U << (*src & 0x1f))) { - *dst++ = '\\'; - *dst++ = 'x'; - *dst++ = hex[*src >> 4]; - *dst++ = hex[*src & 0xf]; - src++; - - } else { - *dst++ = *src++; - } - size--; - } - - return (uintptr_t) dst; -} - - -static size_t -ngx_stream_log_json_variable_getlen(ngx_stream_session_t *s, uintptr_t data) -{ - uintptr_t len; - ngx_stream_variable_value_t *value; - - value = ngx_stream_get_indexed_variable(s, data); - - if (value == NULL || value->not_found) { - return 0; - } - - len = ngx_escape_json(NULL, value->data, value->len); - - value->escape = len ? 1 : 0; - - return value->len + len; -} - - -static u_char * -ngx_stream_log_json_variable(ngx_stream_session_t *s, u_char *buf, - ngx_stream_log_op_t *op) -{ - ngx_stream_variable_value_t *value; - - value = ngx_stream_get_indexed_variable(s, op->data); - - if (value == NULL || value->not_found) { - return buf; - } - - if (value->escape == 0) { - return ngx_cpymem(buf, value->data, value->len); - - } else { - return (u_char *) ngx_escape_json(buf, value->data, value->len); - } -} - - -static void * -ngx_stream_log_create_main_conf(ngx_conf_t *cf) -{ - ngx_stream_log_main_conf_t *conf; - - conf = ngx_pcalloc(cf->pool, sizeof(ngx_stream_log_main_conf_t)); - if (conf == NULL) { - return NULL; - } - - if (ngx_array_init(&conf->formats, cf->pool, 4, - sizeof(ngx_stream_log_fmt_t)) - != NGX_OK) - { - return NULL; - } - - return conf; -} - - -static void * -ngx_stream_log_create_srv_conf(ngx_conf_t *cf) -{ - ngx_stream_log_srv_conf_t *conf; - - conf = ngx_pcalloc(cf->pool, sizeof(ngx_stream_log_srv_conf_t)); - if (conf == NULL) { - return NULL; - } - - conf->open_file_cache = NGX_CONF_UNSET_PTR; - - return conf; -} - - -static char * -ngx_stream_log_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) -{ - ngx_stream_log_srv_conf_t *prev = parent; - ngx_stream_log_srv_conf_t *conf = child; - - if (conf->open_file_cache == NGX_CONF_UNSET_PTR) { - - conf->open_file_cache = prev->open_file_cache; - conf->open_file_cache_valid = prev->open_file_cache_valid; - conf->open_file_cache_min_uses = prev->open_file_cache_min_uses; - - if (conf->open_file_cache == NGX_CONF_UNSET_PTR) { - conf->open_file_cache = NULL; - } - } - - if (conf->logs || conf->off) { - return NGX_CONF_OK; - } - - conf->logs = prev->logs; - conf->off = prev->off; - - return NGX_CONF_OK; -} - - -static char * -ngx_stream_log_set_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) -{ - ngx_stream_log_srv_conf_t *lscf = conf; - - ssize_t size; - ngx_int_t gzip; - ngx_uint_t i, n; - ngx_msec_t flush; - ngx_str_t *value, name, s; - ngx_stream_log_t *log; - ngx_syslog_peer_t *peer; - ngx_stream_log_buf_t *buffer; - ngx_stream_log_fmt_t *fmt; - ngx_stream_script_compile_t sc; - ngx_stream_log_main_conf_t *lmcf; - ngx_stream_compile_complex_value_t ccv; - - value = cf->args->elts; - - if (ngx_strcmp(value[1].data, "off") == 0) { - lscf->off = 1; - if (cf->args->nelts == 2) { - return NGX_CONF_OK; - } - - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "invalid parameter \"%V\"", &value[2]); - return NGX_CONF_ERROR; - } - - if (lscf->logs == NULL) { - lscf->logs = ngx_array_create(cf->pool, 2, sizeof(ngx_stream_log_t)); - if (lscf->logs == NULL) { - return NGX_CONF_ERROR; - } - } - - lmcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_log_module); - - log = ngx_array_push(lscf->logs); - if (log == NULL) { - return NGX_CONF_ERROR; - } - - ngx_memzero(log, sizeof(ngx_stream_log_t)); - - - if (ngx_strncmp(value[1].data, "syslog:", 7) == 0) { - - peer = ngx_pcalloc(cf->pool, sizeof(ngx_syslog_peer_t)); - if (peer == NULL) { - return NGX_CONF_ERROR; - } - - if (ngx_syslog_process_conf(cf, peer) != NGX_CONF_OK) { - return NGX_CONF_ERROR; - } - - log->syslog_peer = peer; - - goto process_formats; - } - - n = ngx_stream_script_variables_count(&value[1]); - - if (n == 0) { - log->file = ngx_conf_open_file(cf->cycle, &value[1]); - if (log->file == NULL) { - return NGX_CONF_ERROR; - } - - } else { - if (ngx_conf_full_name(cf->cycle, &value[1], 0) != NGX_OK) { - return NGX_CONF_ERROR; - } - - log->script = ngx_pcalloc(cf->pool, sizeof(ngx_stream_log_script_t)); - if (log->script == NULL) { - return NGX_CONF_ERROR; - } - - ngx_memzero(&sc, sizeof(ngx_stream_script_compile_t)); - - sc.cf = cf; - sc.source = &value[1]; - sc.lengths = &log->script->lengths; - sc.values = &log->script->values; - sc.variables = n; - sc.complete_lengths = 1; - sc.complete_values = 1; - - if (ngx_stream_script_compile(&sc) != NGX_OK) { - return NGX_CONF_ERROR; - } - } - -process_formats: - - if (cf->args->nelts >= 3) { - name = value[2]; - - } else { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "log format is not specified"); - return NGX_CONF_ERROR; - } - - fmt = lmcf->formats.elts; - for (i = 0; i < lmcf->formats.nelts; i++) { - if (fmt[i].name.len == name.len - && ngx_strcasecmp(fmt[i].name.data, name.data) == 0) - { - log->format = &fmt[i]; - break; - } - } - - if (log->format == NULL) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "unknown log format \"%V\"", &name); - return NGX_CONF_ERROR; - } - - size = 0; - flush = 0; - gzip = 0; - - for (i = 3; i < cf->args->nelts; i++) { - - if (ngx_strncmp(value[i].data, "buffer=", 7) == 0) { - s.len = value[i].len - 7; - s.data = value[i].data + 7; - - size = ngx_parse_size(&s); - - if (size == NGX_ERROR || size == 0) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "invalid buffer size \"%V\"", &s); - return NGX_CONF_ERROR; - } - - continue; - } - - if (ngx_strncmp(value[i].data, "flush=", 6) == 0) { - s.len = value[i].len - 6; - s.data = value[i].data + 6; - - flush = ngx_parse_time(&s, 0); - - if (flush == (ngx_msec_t) NGX_ERROR || flush == 0) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "invalid flush time \"%V\"", &s); - return NGX_CONF_ERROR; - } - - continue; - } - - if (ngx_strncmp(value[i].data, "gzip", 4) == 0 - && (value[i].len == 4 || value[i].data[4] == '=')) - { -#if (NGX_ZLIB) - if (size == 0) { - size = 64 * 1024; - } - - if (value[i].len == 4) { - gzip = Z_BEST_SPEED; - continue; - } - - s.len = value[i].len - 5; - s.data = value[i].data + 5; - - gzip = ngx_atoi(s.data, s.len); - - if (gzip < 1 || gzip > 9) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "invalid compression level \"%V\"", &s); - return NGX_CONF_ERROR; - } - - continue; - -#else - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "nginx was built without zlib support"); - return NGX_CONF_ERROR; -#endif - } - - if (ngx_strncmp(value[i].data, "if=", 3) == 0) { - s.len = value[i].len - 3; - s.data = value[i].data + 3; - - ngx_memzero(&ccv, sizeof(ngx_stream_compile_complex_value_t)); - - ccv.cf = cf; - ccv.value = &s; - ccv.complex_value = ngx_palloc(cf->pool, - sizeof(ngx_stream_complex_value_t)); - if (ccv.complex_value == NULL) { - return NGX_CONF_ERROR; - } - - if (ngx_stream_compile_complex_value(&ccv) != NGX_OK) { - return NGX_CONF_ERROR; - } - - log->filter = ccv.complex_value; - - continue; - } - - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "invalid parameter \"%V\"", &value[i]); - return NGX_CONF_ERROR; - } - - if (flush && size == 0) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "no buffer is defined for access_log \"%V\"", - &value[1]); - return NGX_CONF_ERROR; - } - - if (size) { - - if (log->script) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "buffered logs cannot have variables in name"); - return NGX_CONF_ERROR; - } - - if (log->syslog_peer) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "logs to syslog cannot be buffered"); - return NGX_CONF_ERROR; - } - - if (log->file->data) { - buffer = log->file->data; - - if (buffer->last - buffer->start != size - || buffer->flush != flush - || buffer->gzip != gzip) - { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "access_log \"%V\" already defined " - "with conflicting parameters", - &value[1]); - return NGX_CONF_ERROR; - } - - return NGX_CONF_OK; - } - - buffer = ngx_pcalloc(cf->pool, sizeof(ngx_stream_log_buf_t)); - if (buffer == NULL) { - return NGX_CONF_ERROR; - } - - buffer->start = ngx_pnalloc(cf->pool, size); - if (buffer->start == NULL) { - return NGX_CONF_ERROR; - } - - buffer->pos = buffer->start; - buffer->last = buffer->start + size; - - if (flush) { - buffer->event = ngx_pcalloc(cf->pool, sizeof(ngx_event_t)); - if (buffer->event == NULL) { - return NGX_CONF_ERROR; - } - - buffer->event->data = log->file; - buffer->event->handler = ngx_stream_log_flush_handler; - buffer->event->log = &cf->cycle->new_log; - buffer->event->cancelable = 1; - - buffer->flush = flush; - } - - buffer->gzip = gzip; - - log->file->flush = ngx_stream_log_flush; - log->file->data = buffer; - } - - return NGX_CONF_OK; -} - - -static char * -ngx_stream_log_set_format(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) -{ - ngx_stream_log_main_conf_t *lmcf = conf; - - ngx_str_t *value; - ngx_uint_t i; - ngx_stream_log_fmt_t *fmt; - - value = cf->args->elts; - - fmt = lmcf->formats.elts; - for (i = 0; i < lmcf->formats.nelts; i++) { - if (fmt[i].name.len == value[1].len - && ngx_strcmp(fmt[i].name.data, value[1].data) == 0) - { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "duplicate \"log_format\" name \"%V\"", - &value[1]); - return NGX_CONF_ERROR; - } - } - - fmt = ngx_array_push(&lmcf->formats); - if (fmt == NULL) { - return NGX_CONF_ERROR; - } - - fmt->name = value[1]; - - fmt->flushes = ngx_array_create(cf->pool, 4, sizeof(ngx_int_t)); - if (fmt->flushes == NULL) { - return NGX_CONF_ERROR; - } - - fmt->ops = ngx_array_create(cf->pool, 16, sizeof(ngx_stream_log_op_t)); - if (fmt->ops == NULL) { - return NGX_CONF_ERROR; - } - - return ngx_stream_log_compile_format(cf, fmt->flushes, fmt->ops, - cf->args, 2); -} - - -static char * -ngx_stream_log_compile_format(ngx_conf_t *cf, ngx_array_t *flushes, - ngx_array_t *ops, ngx_array_t *args, ngx_uint_t s) -{ - u_char *data, *p, ch; - size_t i, len; - ngx_str_t *value, var; - ngx_int_t *flush; - ngx_uint_t bracket, json; - ngx_stream_log_op_t *op; - - json = 0; - value = args->elts; - - if (s < args->nelts && ngx_strncmp(value[s].data, "escape=", 7) == 0) { - data = value[s].data + 7; - - if (ngx_strcmp(data, "json") == 0) { - json = 1; - - } else if (ngx_strcmp(data, "default") != 0) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "unknown log format escaping \"%s\"", data); - return NGX_CONF_ERROR; - } - - s++; - } - - for ( /* void */ ; s < args->nelts; s++) { - - i = 0; - - while (i < value[s].len) { - - op = ngx_array_push(ops); - if (op == NULL) { - return NGX_CONF_ERROR; - } - - data = &value[s].data[i]; - - if (value[s].data[i] == '$') { - - if (++i == value[s].len) { - goto invalid; - } - - if (value[s].data[i] == '{') { - bracket = 1; - - if (++i == value[s].len) { - goto invalid; - } - - var.data = &value[s].data[i]; - - } else { - bracket = 0; - var.data = &value[s].data[i]; - } - - for (var.len = 0; i < value[s].len; i++, var.len++) { - ch = value[s].data[i]; - - if (ch == '}' && bracket) { - i++; - bracket = 0; - break; - } - - if ((ch >= 'A' && ch <= 'Z') - || (ch >= 'a' && ch <= 'z') - || (ch >= '0' && ch <= '9') - || ch == '_') - { - continue; - } - - break; - } - - if (bracket) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "the closing bracket in \"%V\" " - "variable is missing", &var); - return NGX_CONF_ERROR; - } - - if (var.len == 0) { - goto invalid; - } - - if (ngx_stream_log_variable_compile(cf, op, &var, json) - != NGX_OK) - { - return NGX_CONF_ERROR; - } - - if (flushes) { - - flush = ngx_array_push(flushes); - if (flush == NULL) { - return NGX_CONF_ERROR; - } - - *flush = op->data; /* variable index */ - } - - continue; - } - - i++; - - while (i < value[s].len && value[s].data[i] != '$') { - i++; - } - - len = &value[s].data[i] - data; - - if (len) { - - op->len = len; - op->getlen = NULL; - - if (len <= sizeof(uintptr_t)) { - op->run = ngx_stream_log_copy_short; - op->data = 0; - - while (len--) { - op->data <<= 8; - op->data |= data[len]; - } - - } else { - op->run = ngx_stream_log_copy_long; - - p = ngx_pnalloc(cf->pool, len); - if (p == NULL) { - return NGX_CONF_ERROR; - } - - ngx_memcpy(p, data, len); - op->data = (uintptr_t) p; - } - } - } - } - - return NGX_CONF_OK; - -invalid: - - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%s\"", data); - - return NGX_CONF_ERROR; -} - - -static char * -ngx_stream_log_open_file_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) -{ - ngx_stream_log_srv_conf_t *lscf = conf; - - time_t inactive, valid; - ngx_str_t *value, s; - ngx_int_t max, min_uses; - ngx_uint_t i; - - if (lscf->open_file_cache != NGX_CONF_UNSET_PTR) { - return "is duplicate"; - } - - value = cf->args->elts; - - max = 0; - inactive = 10; - valid = 60; - min_uses = 1; - - for (i = 1; i < cf->args->nelts; i++) { - - if (ngx_strncmp(value[i].data, "max=", 4) == 0) { - - max = ngx_atoi(value[i].data + 4, value[i].len - 4); - if (max == NGX_ERROR) { - goto failed; - } - - continue; - } - - if (ngx_strncmp(value[i].data, "inactive=", 9) == 0) { - - s.len = value[i].len - 9; - s.data = value[i].data + 9; - - inactive = ngx_parse_time(&s, 1); - if (inactive == (time_t) NGX_ERROR) { - goto failed; - } - - continue; - } - - if (ngx_strncmp(value[i].data, "min_uses=", 9) == 0) { - - min_uses = ngx_atoi(value[i].data + 9, value[i].len - 9); - if (min_uses == NGX_ERROR) { - goto failed; - } - - continue; - } - - if (ngx_strncmp(value[i].data, "valid=", 6) == 0) { - - s.len = value[i].len - 6; - s.data = value[i].data + 6; - - valid = ngx_parse_time(&s, 1); - if (valid == (time_t) NGX_ERROR) { - goto failed; - } - - continue; - } - - if (ngx_strcmp(value[i].data, "off") == 0) { - - lscf->open_file_cache = NULL; - - continue; - } - - failed: - - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "invalid \"open_log_file_cache\" parameter \"%V\"", - &value[i]); - return NGX_CONF_ERROR; - } - - if (lscf->open_file_cache == NULL) { - return NGX_CONF_OK; - } - - if (max == 0) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "\"open_log_file_cache\" must have \"max\" parameter"); - return NGX_CONF_ERROR; - } - - lscf->open_file_cache = ngx_open_file_cache_init(cf->pool, max, inactive); - - if (lscf->open_file_cache) { - - lscf->open_file_cache_valid = valid; - lscf->open_file_cache_min_uses = min_uses; - - return NGX_CONF_OK; - } - - return NGX_CONF_ERROR; -} - - -static ngx_int_t -ngx_stream_log_init(ngx_conf_t *cf) -{ - ngx_stream_handler_pt *h; - ngx_stream_core_main_conf_t *cmcf; - - cmcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_core_module); - - h = ngx_array_push(&cmcf->phases[NGX_STREAM_LOG_PHASE].handlers); - if (h == NULL) { - return NGX_ERROR; - } - - *h = ngx_stream_log_handler; - - return NGX_OK; -} diff --git a/app/nginx/src/stream/ngx_stream_map_module.c b/app/nginx/src/stream/ngx_stream_map_module.c deleted file mode 100644 index ef06b2d..0000000 --- a/app/nginx/src/stream/ngx_stream_map_module.c +++ /dev/null @@ -1,588 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) Nginx, Inc. - */ - - -#include <ngx_config.h> -#include <ngx_core.h> -#include <ngx_stream.h> - - -typedef struct { - ngx_uint_t hash_max_size; - ngx_uint_t hash_bucket_size; -} ngx_stream_map_conf_t; - - -typedef struct { - ngx_hash_keys_arrays_t keys; - - ngx_array_t *values_hash; -#if (NGX_PCRE) - ngx_array_t regexes; -#endif - - ngx_stream_variable_value_t *default_value; - ngx_conf_t *cf; - unsigned hostnames:1; - unsigned no_cacheable:1; -} ngx_stream_map_conf_ctx_t; - - -typedef struct { - ngx_stream_map_t map; - ngx_stream_complex_value_t value; - ngx_stream_variable_value_t *default_value; - ngx_uint_t hostnames; /* unsigned hostnames:1 */ -} ngx_stream_map_ctx_t; - - -static int ngx_libc_cdecl ngx_stream_map_cmp_dns_wildcards(const void *one, - const void *two); -static void *ngx_stream_map_create_conf(ngx_conf_t *cf); -static char *ngx_stream_map_block(ngx_conf_t *cf, ngx_command_t *cmd, - void *conf); -static char *ngx_stream_map(ngx_conf_t *cf, ngx_command_t *dummy, void *conf); - - -static ngx_command_t ngx_stream_map_commands[] = { - - { ngx_string("map"), - NGX_STREAM_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE2, - ngx_stream_map_block, - NGX_STREAM_MAIN_CONF_OFFSET, - 0, - NULL }, - - { ngx_string("map_hash_max_size"), - NGX_STREAM_MAIN_CONF|NGX_CONF_TAKE1, - ngx_conf_set_num_slot, - NGX_STREAM_MAIN_CONF_OFFSET, - offsetof(ngx_stream_map_conf_t, hash_max_size), - NULL }, - - { ngx_string("map_hash_bucket_size"), - NGX_STREAM_MAIN_CONF|NGX_CONF_TAKE1, - ngx_conf_set_num_slot, - NGX_STREAM_MAIN_CONF_OFFSET, - offsetof(ngx_stream_map_conf_t, hash_bucket_size), - NULL }, - - ngx_null_command -}; - - -static ngx_stream_module_t ngx_stream_map_module_ctx = { - NULL, /* preconfiguration */ - NULL, /* postconfiguration */ - - ngx_stream_map_create_conf, /* create main configuration */ - NULL, /* init main configuration */ - - NULL, /* create server configuration */ - NULL /* merge server configuration */ -}; - - -ngx_module_t ngx_stream_map_module = { - NGX_MODULE_V1, - &ngx_stream_map_module_ctx, /* module context */ - ngx_stream_map_commands, /* module directives */ - NGX_STREAM_MODULE, /* module type */ - NULL, /* init master */ - NULL, /* init module */ - NULL, /* init process */ - NULL, /* init thread */ - NULL, /* exit thread */ - NULL, /* exit process */ - NULL, /* exit master */ - NGX_MODULE_V1_PADDING -}; - - -static ngx_int_t -ngx_stream_map_variable(ngx_stream_session_t *s, ngx_stream_variable_value_t *v, - uintptr_t data) -{ - ngx_stream_map_ctx_t *map = (ngx_stream_map_ctx_t *) data; - - ngx_str_t val, str; - ngx_stream_complex_value_t *cv; - ngx_stream_variable_value_t *value; - - ngx_log_debug0(NGX_LOG_DEBUG_STREAM, s->connection->log, 0, - "stream map started"); - - if (ngx_stream_complex_value(s, &map->value, &val) != NGX_OK) { - return NGX_ERROR; - } - - if (map->hostnames && val.len > 0 && val.data[val.len - 1] == '.') { - val.len--; - } - - value = ngx_stream_map_find(s, &map->map, &val); - - if (value == NULL) { - value = map->default_value; - } - - if (!value->valid) { - cv = (ngx_stream_complex_value_t *) value->data; - - if (ngx_stream_complex_value(s, cv, &str) != NGX_OK) { - return NGX_ERROR; - } - - v->valid = 1; - v->no_cacheable = 0; - v->not_found = 0; - v->len = str.len; - v->data = str.data; - - } else { - *v = *value; - } - - ngx_log_debug2(NGX_LOG_DEBUG_STREAM, s->connection->log, 0, - "stream map: \"%V\" \"%v\"", &val, v); - - return NGX_OK; -} - - -static void * -ngx_stream_map_create_conf(ngx_conf_t *cf) -{ - ngx_stream_map_conf_t *mcf; - - mcf = ngx_palloc(cf->pool, sizeof(ngx_stream_map_conf_t)); - if (mcf == NULL) { - return NULL; - } - - mcf->hash_max_size = NGX_CONF_UNSET_UINT; - mcf->hash_bucket_size = NGX_CONF_UNSET_UINT; - - return mcf; -} - - -static char * -ngx_stream_map_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) -{ - ngx_stream_map_conf_t *mcf = conf; - - char *rv; - ngx_str_t *value, name; - ngx_conf_t save; - ngx_pool_t *pool; - ngx_hash_init_t hash; - ngx_stream_map_ctx_t *map; - ngx_stream_variable_t *var; - ngx_stream_map_conf_ctx_t ctx; - ngx_stream_compile_complex_value_t ccv; - - if (mcf->hash_max_size == NGX_CONF_UNSET_UINT) { - mcf->hash_max_size = 2048; - } - - if (mcf->hash_bucket_size == NGX_CONF_UNSET_UINT) { - mcf->hash_bucket_size = ngx_cacheline_size; - - } else { - mcf->hash_bucket_size = ngx_align(mcf->hash_bucket_size, - ngx_cacheline_size); - } - - map = ngx_pcalloc(cf->pool, sizeof(ngx_stream_map_ctx_t)); - if (map == NULL) { - return NGX_CONF_ERROR; - } - - value = cf->args->elts; - - ngx_memzero(&ccv, sizeof(ngx_stream_compile_complex_value_t)); - - ccv.cf = cf; - ccv.value = &value[1]; - ccv.complex_value = &map->value; - - if (ngx_stream_compile_complex_value(&ccv) != NGX_OK) { - return NGX_CONF_ERROR; - } - - name = value[2]; - - if (name.data[0] != '$') { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "invalid variable name \"%V\"", &name); - return NGX_CONF_ERROR; - } - - name.len--; - name.data++; - - var = ngx_stream_add_variable(cf, &name, NGX_STREAM_VAR_CHANGEABLE); - if (var == NULL) { - return NGX_CONF_ERROR; - } - - var->get_handler = ngx_stream_map_variable; - var->data = (uintptr_t) map; - - pool = ngx_create_pool(NGX_DEFAULT_POOL_SIZE, cf->log); - if (pool == NULL) { - return NGX_CONF_ERROR; - } - - ctx.keys.pool = cf->pool; - ctx.keys.temp_pool = pool; - - if (ngx_hash_keys_array_init(&ctx.keys, NGX_HASH_LARGE) != NGX_OK) { - ngx_destroy_pool(pool); - return NGX_CONF_ERROR; - } - - ctx.values_hash = ngx_pcalloc(pool, sizeof(ngx_array_t) * ctx.keys.hsize); - if (ctx.values_hash == NULL) { - ngx_destroy_pool(pool); - return NGX_CONF_ERROR; - } - -#if (NGX_PCRE) - if (ngx_array_init(&ctx.regexes, cf->pool, 2, - sizeof(ngx_stream_map_regex_t)) - != NGX_OK) - { - ngx_destroy_pool(pool); - return NGX_CONF_ERROR; - } -#endif - - ctx.default_value = NULL; - ctx.cf = &save; - ctx.hostnames = 0; - ctx.no_cacheable = 0; - - save = *cf; - cf->pool = pool; - cf->ctx = &ctx; - cf->handler = ngx_stream_map; - cf->handler_conf = conf; - - rv = ngx_conf_parse(cf, NULL); - - *cf = save; - - if (rv != NGX_CONF_OK) { - ngx_destroy_pool(pool); - return rv; - } - - if (ctx.no_cacheable) { - var->flags |= NGX_STREAM_VAR_NOCACHEABLE; - } - - map->default_value = ctx.default_value ? ctx.default_value: - &ngx_stream_variable_null_value; - - map->hostnames = ctx.hostnames; - - hash.key = ngx_hash_key_lc; - hash.max_size = mcf->hash_max_size; - hash.bucket_size = mcf->hash_bucket_size; - hash.name = "map_hash"; - hash.pool = cf->pool; - - if (ctx.keys.keys.nelts) { - hash.hash = &map->map.hash.hash; - hash.temp_pool = NULL; - - if (ngx_hash_init(&hash, ctx.keys.keys.elts, ctx.keys.keys.nelts) - != NGX_OK) - { - ngx_destroy_pool(pool); - return NGX_CONF_ERROR; - } - } - - if (ctx.keys.dns_wc_head.nelts) { - - ngx_qsort(ctx.keys.dns_wc_head.elts, - (size_t) ctx.keys.dns_wc_head.nelts, - sizeof(ngx_hash_key_t), ngx_stream_map_cmp_dns_wildcards); - - hash.hash = NULL; - hash.temp_pool = pool; - - if (ngx_hash_wildcard_init(&hash, ctx.keys.dns_wc_head.elts, - ctx.keys.dns_wc_head.nelts) - != NGX_OK) - { - ngx_destroy_pool(pool); - return NGX_CONF_ERROR; - } - - map->map.hash.wc_head = (ngx_hash_wildcard_t *) hash.hash; - } - - if (ctx.keys.dns_wc_tail.nelts) { - - ngx_qsort(ctx.keys.dns_wc_tail.elts, - (size_t) ctx.keys.dns_wc_tail.nelts, - sizeof(ngx_hash_key_t), ngx_stream_map_cmp_dns_wildcards); - - hash.hash = NULL; - hash.temp_pool = pool; - - if (ngx_hash_wildcard_init(&hash, ctx.keys.dns_wc_tail.elts, - ctx.keys.dns_wc_tail.nelts) - != NGX_OK) - { - ngx_destroy_pool(pool); - return NGX_CONF_ERROR; - } - - map->map.hash.wc_tail = (ngx_hash_wildcard_t *) hash.hash; - } - -#if (NGX_PCRE) - - if (ctx.regexes.nelts) { - map->map.regex = ctx.regexes.elts; - map->map.nregex = ctx.regexes.nelts; - } - -#endif - - ngx_destroy_pool(pool); - - return rv; -} - - -static int ngx_libc_cdecl -ngx_stream_map_cmp_dns_wildcards(const void *one, const void *two) -{ - ngx_hash_key_t *first, *second; - - first = (ngx_hash_key_t *) one; - second = (ngx_hash_key_t *) two; - - return ngx_dns_strcmp(first->key.data, second->key.data); -} - - -static char * -ngx_stream_map(ngx_conf_t *cf, ngx_command_t *dummy, void *conf) -{ - u_char *data; - size_t len; - ngx_int_t rv; - ngx_str_t *value, v; - ngx_uint_t i, key; - ngx_stream_map_conf_ctx_t *ctx; - ngx_stream_complex_value_t cv, *cvp; - ngx_stream_variable_value_t *var, **vp; - ngx_stream_compile_complex_value_t ccv; - - ctx = cf->ctx; - - value = cf->args->elts; - - if (cf->args->nelts == 1 - && ngx_strcmp(value[0].data, "hostnames") == 0) - { - ctx->hostnames = 1; - return NGX_CONF_OK; - } - - if (cf->args->nelts == 1 - && ngx_strcmp(value[0].data, "volatile") == 0) - { - ctx->no_cacheable = 1; - return NGX_CONF_OK; - } - - if (cf->args->nelts != 2) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "invalid number of the map parameters"); - return NGX_CONF_ERROR; - } - - if (ngx_strcmp(value[0].data, "include") == 0) { - return ngx_conf_include(cf, dummy, conf); - } - - key = 0; - - for (i = 0; i < value[1].len; i++) { - key = ngx_hash(key, value[1].data[i]); - } - - key %= ctx->keys.hsize; - - vp = ctx->values_hash[key].elts; - - if (vp) { - for (i = 0; i < ctx->values_hash[key].nelts; i++) { - - if (vp[i]->valid) { - data = vp[i]->data; - len = vp[i]->len; - - } else { - cvp = (ngx_stream_complex_value_t *) vp[i]->data; - data = cvp->value.data; - len = cvp->value.len; - } - - if (value[1].len != len) { - continue; - } - - if (ngx_strncmp(value[1].data, data, len) == 0) { - var = vp[i]; - goto found; - } - } - - } else { - if (ngx_array_init(&ctx->values_hash[key], cf->pool, 4, - sizeof(ngx_stream_variable_value_t *)) - != NGX_OK) - { - return NGX_CONF_ERROR; - } - } - - var = ngx_palloc(ctx->keys.pool, sizeof(ngx_stream_variable_value_t)); - if (var == NULL) { - return NGX_CONF_ERROR; - } - - v.len = value[1].len; - v.data = ngx_pstrdup(ctx->keys.pool, &value[1]); - if (v.data == NULL) { - return NGX_CONF_ERROR; - } - - ngx_memzero(&ccv, sizeof(ngx_stream_compile_complex_value_t)); - - ccv.cf = ctx->cf; - ccv.value = &v; - ccv.complex_value = &cv; - - if (ngx_stream_compile_complex_value(&ccv) != NGX_OK) { - return NGX_CONF_ERROR; - } - - if (cv.lengths != NULL) { - cvp = ngx_palloc(ctx->keys.pool, sizeof(ngx_stream_complex_value_t)); - if (cvp == NULL) { - return NGX_CONF_ERROR; - } - - *cvp = cv; - - var->len = 0; - var->data = (u_char *) cvp; - var->valid = 0; - - } else { - var->len = v.len; - var->data = v.data; - var->valid = 1; - } - - var->no_cacheable = 0; - var->not_found = 0; - - vp = ngx_array_push(&ctx->values_hash[key]); - if (vp == NULL) { - return NGX_CONF_ERROR; - } - - *vp = var; - -found: - - if (ngx_strcmp(value[0].data, "default") == 0) { - - if (ctx->default_value) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "duplicate default map parameter"); - return NGX_CONF_ERROR; - } - - ctx->default_value = var; - - return NGX_CONF_OK; - } - -#if (NGX_PCRE) - - if (value[0].len && value[0].data[0] == '~') { - ngx_regex_compile_t rc; - ngx_stream_map_regex_t *regex; - u_char errstr[NGX_MAX_CONF_ERRSTR]; - - regex = ngx_array_push(&ctx->regexes); - if (regex == NULL) { - return NGX_CONF_ERROR; - } - - value[0].len--; - value[0].data++; - - ngx_memzero(&rc, sizeof(ngx_regex_compile_t)); - - if (value[0].data[0] == '*') { - value[0].len--; - value[0].data++; - rc.options = NGX_REGEX_CASELESS; - } - - rc.pattern = value[0]; - rc.err.len = NGX_MAX_CONF_ERRSTR; - rc.err.data = errstr; - - regex->regex = ngx_stream_regex_compile(ctx->cf, &rc); - if (regex->regex == NULL) { - return NGX_CONF_ERROR; - } - - regex->value = var; - - return NGX_CONF_OK; - } - -#endif - - if (value[0].len && value[0].data[0] == '\\') { - value[0].len--; - value[0].data++; - } - - rv = ngx_hash_add_key(&ctx->keys, &value[0], var, - (ctx->hostnames) ? NGX_HASH_WILDCARD_KEY : 0); - - if (rv == NGX_OK) { - return NGX_CONF_OK; - } - - if (rv == NGX_DECLINED) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "invalid hostname or wildcard \"%V\"", &value[0]); - } - - if (rv == NGX_BUSY) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "conflicting parameter \"%V\"", &value[0]); - } - - return NGX_CONF_ERROR; -} diff --git a/app/nginx/src/stream/ngx_stream_proxy_module.c b/app/nginx/src/stream/ngx_stream_proxy_module.c deleted file mode 100644 index 81a0891..0000000 --- a/app/nginx/src/stream/ngx_stream_proxy_module.c +++ /dev/null @@ -1,2170 +0,0 @@ - -/* - * Copyright (C) Roman Arutyunyan - * Copyright (C) Nginx, Inc. - */ - - -#include <ngx_config.h> -#include <ngx_core.h> -#include <ngx_stream.h> - - -typedef struct { - ngx_addr_t *addr; - ngx_stream_complex_value_t *value; -#if (NGX_HAVE_TRANSPARENT_PROXY) - ngx_uint_t transparent; /* unsigned transparent:1; */ -#endif -} ngx_stream_upstream_local_t; - - -typedef struct { - ngx_msec_t connect_timeout; - ngx_msec_t timeout; - ngx_msec_t next_upstream_timeout; - size_t buffer_size; - size_t upload_rate; - size_t download_rate; - ngx_uint_t responses; - ngx_uint_t next_upstream_tries; - ngx_flag_t next_upstream; - ngx_flag_t proxy_protocol; - ngx_stream_upstream_local_t *local; - -#if (NGX_STREAM_SSL) - ngx_flag_t ssl_enable; - ngx_flag_t ssl_session_reuse; - ngx_uint_t ssl_protocols; - ngx_str_t ssl_ciphers; - ngx_stream_complex_value_t *ssl_name; - ngx_flag_t ssl_server_name; - - ngx_flag_t ssl_verify; - ngx_uint_t ssl_verify_depth; - ngx_str_t ssl_trusted_certificate; - ngx_str_t ssl_crl; - ngx_str_t ssl_certificate; - ngx_str_t ssl_certificate_key; - ngx_array_t *ssl_passwords; - - ngx_ssl_t *ssl; -#endif - - ngx_stream_upstream_srv_conf_t *upstream; - ngx_stream_complex_value_t *upstream_value; -} ngx_stream_proxy_srv_conf_t; - - -static void ngx_stream_proxy_handler(ngx_stream_session_t *s); -static ngx_int_t ngx_stream_proxy_eval(ngx_stream_session_t *s, - ngx_stream_proxy_srv_conf_t *pscf); -static ngx_int_t ngx_stream_proxy_set_local(ngx_stream_session_t *s, - ngx_stream_upstream_t *u, ngx_stream_upstream_local_t *local); -static void ngx_stream_proxy_connect(ngx_stream_session_t *s); -static void ngx_stream_proxy_init_upstream(ngx_stream_session_t *s); -static void ngx_stream_proxy_resolve_handler(ngx_resolver_ctx_t *ctx); -static void ngx_stream_proxy_upstream_handler(ngx_event_t *ev); -static void ngx_stream_proxy_downstream_handler(ngx_event_t *ev); -static void ngx_stream_proxy_process_connection(ngx_event_t *ev, - ngx_uint_t from_upstream); -static void ngx_stream_proxy_connect_handler(ngx_event_t *ev); -static ngx_int_t ngx_stream_proxy_test_connect(ngx_connection_t *c); -static void ngx_stream_proxy_process(ngx_stream_session_t *s, - ngx_uint_t from_upstream, ngx_uint_t do_write); -static void ngx_stream_proxy_next_upstream(ngx_stream_session_t *s); -static void ngx_stream_proxy_finalize(ngx_stream_session_t *s, ngx_uint_t rc); -static u_char *ngx_stream_proxy_log_error(ngx_log_t *log, u_char *buf, - size_t len); - -static void *ngx_stream_proxy_create_srv_conf(ngx_conf_t *cf); -static char *ngx_stream_proxy_merge_srv_conf(ngx_conf_t *cf, void *parent, - void *child); -static char *ngx_stream_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, - void *conf); -static char *ngx_stream_proxy_bind(ngx_conf_t *cf, ngx_command_t *cmd, - void *conf); - -#if (NGX_STREAM_SSL) - -static ngx_int_t ngx_stream_proxy_send_proxy_protocol(ngx_stream_session_t *s); -static char *ngx_stream_proxy_ssl_password_file(ngx_conf_t *cf, - ngx_command_t *cmd, void *conf); -static void ngx_stream_proxy_ssl_init_connection(ngx_stream_session_t *s); -static void ngx_stream_proxy_ssl_handshake(ngx_connection_t *pc); -static ngx_int_t ngx_stream_proxy_ssl_name(ngx_stream_session_t *s); -static ngx_int_t ngx_stream_proxy_set_ssl(ngx_conf_t *cf, - ngx_stream_proxy_srv_conf_t *pscf); - - -static ngx_conf_bitmask_t ngx_stream_proxy_ssl_protocols[] = { - { ngx_string("SSLv2"), NGX_SSL_SSLv2 }, - { ngx_string("SSLv3"), NGX_SSL_SSLv3 }, - { ngx_string("TLSv1"), NGX_SSL_TLSv1 }, - { ngx_string("TLSv1.1"), NGX_SSL_TLSv1_1 }, - { ngx_string("TLSv1.2"), NGX_SSL_TLSv1_2 }, - { ngx_null_string, 0 } -}; - -#endif - - -static ngx_conf_deprecated_t ngx_conf_deprecated_proxy_downstream_buffer = { - ngx_conf_deprecated, "proxy_downstream_buffer", "proxy_buffer_size" -}; - -static ngx_conf_deprecated_t ngx_conf_deprecated_proxy_upstream_buffer = { - ngx_conf_deprecated, "proxy_upstream_buffer", "proxy_buffer_size" -}; - - -static ngx_command_t ngx_stream_proxy_commands[] = { - - { ngx_string("proxy_pass"), - NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, - ngx_stream_proxy_pass, - NGX_STREAM_SRV_CONF_OFFSET, - 0, - NULL }, - - { ngx_string("proxy_bind"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE12, - ngx_stream_proxy_bind, - NGX_STREAM_SRV_CONF_OFFSET, - 0, - NULL }, - - { ngx_string("proxy_connect_timeout"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_msec_slot, - NGX_STREAM_SRV_CONF_OFFSET, - offsetof(ngx_stream_proxy_srv_conf_t, connect_timeout), - NULL }, - - { ngx_string("proxy_timeout"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_msec_slot, - NGX_STREAM_SRV_CONF_OFFSET, - offsetof(ngx_stream_proxy_srv_conf_t, timeout), - NULL }, - - { ngx_string("proxy_buffer_size"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_size_slot, - NGX_STREAM_SRV_CONF_OFFSET, - offsetof(ngx_stream_proxy_srv_conf_t, buffer_size), - NULL }, - - { ngx_string("proxy_downstream_buffer"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_size_slot, - NGX_STREAM_SRV_CONF_OFFSET, - offsetof(ngx_stream_proxy_srv_conf_t, buffer_size), - &ngx_conf_deprecated_proxy_downstream_buffer }, - - { ngx_string("proxy_upstream_buffer"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_size_slot, - NGX_STREAM_SRV_CONF_OFFSET, - offsetof(ngx_stream_proxy_srv_conf_t, buffer_size), - &ngx_conf_deprecated_proxy_upstream_buffer }, - - { ngx_string("proxy_upload_rate"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_size_slot, - NGX_STREAM_SRV_CONF_OFFSET, - offsetof(ngx_stream_proxy_srv_conf_t, upload_rate), - NULL }, - - { ngx_string("proxy_download_rate"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_size_slot, - NGX_STREAM_SRV_CONF_OFFSET, - offsetof(ngx_stream_proxy_srv_conf_t, download_rate), - NULL }, - - { ngx_string("proxy_responses"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_num_slot, - NGX_STREAM_SRV_CONF_OFFSET, - offsetof(ngx_stream_proxy_srv_conf_t, responses), - NULL }, - - { ngx_string("proxy_next_upstream"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG, - ngx_conf_set_flag_slot, - NGX_STREAM_SRV_CONF_OFFSET, - offsetof(ngx_stream_proxy_srv_conf_t, next_upstream), - NULL }, - - { ngx_string("proxy_next_upstream_tries"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_num_slot, - NGX_STREAM_SRV_CONF_OFFSET, - offsetof(ngx_stream_proxy_srv_conf_t, next_upstream_tries), - NULL }, - - { ngx_string("proxy_next_upstream_timeout"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_msec_slot, - NGX_STREAM_SRV_CONF_OFFSET, - offsetof(ngx_stream_proxy_srv_conf_t, next_upstream_timeout), - NULL }, - - { ngx_string("proxy_protocol"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG, - ngx_conf_set_flag_slot, - NGX_STREAM_SRV_CONF_OFFSET, - offsetof(ngx_stream_proxy_srv_conf_t, proxy_protocol), - NULL }, - -#if (NGX_STREAM_SSL) - - { ngx_string("proxy_ssl"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG, - ngx_conf_set_flag_slot, - NGX_STREAM_SRV_CONF_OFFSET, - offsetof(ngx_stream_proxy_srv_conf_t, ssl_enable), - NULL }, - - { ngx_string("proxy_ssl_session_reuse"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG, - ngx_conf_set_flag_slot, - NGX_STREAM_SRV_CONF_OFFSET, - offsetof(ngx_stream_proxy_srv_conf_t, ssl_session_reuse), - NULL }, - - { ngx_string("proxy_ssl_protocols"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_1MORE, - ngx_conf_set_bitmask_slot, - NGX_STREAM_SRV_CONF_OFFSET, - offsetof(ngx_stream_proxy_srv_conf_t, ssl_protocols), - &ngx_stream_proxy_ssl_protocols }, - - { ngx_string("proxy_ssl_ciphers"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_str_slot, - NGX_STREAM_SRV_CONF_OFFSET, - offsetof(ngx_stream_proxy_srv_conf_t, ssl_ciphers), - NULL }, - - { ngx_string("proxy_ssl_name"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, - ngx_stream_set_complex_value_slot, - NGX_STREAM_SRV_CONF_OFFSET, - offsetof(ngx_stream_proxy_srv_conf_t, ssl_name), - NULL }, - - { ngx_string("proxy_ssl_server_name"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG, - ngx_conf_set_flag_slot, - NGX_STREAM_SRV_CONF_OFFSET, - offsetof(ngx_stream_proxy_srv_conf_t, ssl_server_name), - NULL }, - - { ngx_string("proxy_ssl_verify"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG, - ngx_conf_set_flag_slot, - NGX_STREAM_SRV_CONF_OFFSET, - offsetof(ngx_stream_proxy_srv_conf_t, ssl_verify), - NULL }, - - { ngx_string("proxy_ssl_verify_depth"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_num_slot, - NGX_STREAM_SRV_CONF_OFFSET, - offsetof(ngx_stream_proxy_srv_conf_t, ssl_verify_depth), - NULL }, - - { ngx_string("proxy_ssl_trusted_certificate"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_str_slot, - NGX_STREAM_SRV_CONF_OFFSET, - offsetof(ngx_stream_proxy_srv_conf_t, ssl_trusted_certificate), - NULL }, - - { ngx_string("proxy_ssl_crl"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_str_slot, - NGX_STREAM_SRV_CONF_OFFSET, - offsetof(ngx_stream_proxy_srv_conf_t, ssl_crl), - NULL }, - - { ngx_string("proxy_ssl_certificate"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_str_slot, - NGX_STREAM_SRV_CONF_OFFSET, - offsetof(ngx_stream_proxy_srv_conf_t, ssl_certificate), - NULL }, - - { ngx_string("proxy_ssl_certificate_key"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_str_slot, - NGX_STREAM_SRV_CONF_OFFSET, - offsetof(ngx_stream_proxy_srv_conf_t, ssl_certificate_key), - NULL }, - - { ngx_string("proxy_ssl_password_file"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, - ngx_stream_proxy_ssl_password_file, - NGX_STREAM_SRV_CONF_OFFSET, - 0, - NULL }, - -#endif - - ngx_null_command -}; - - -static ngx_stream_module_t ngx_stream_proxy_module_ctx = { - NULL, /* preconfiguration */ - NULL, /* postconfiguration */ - - NULL, /* create main configuration */ - NULL, /* init main configuration */ - - ngx_stream_proxy_create_srv_conf, /* create server configuration */ - ngx_stream_proxy_merge_srv_conf /* merge server configuration */ -}; - - -ngx_module_t ngx_stream_proxy_module = { - NGX_MODULE_V1, - &ngx_stream_proxy_module_ctx, /* module context */ - ngx_stream_proxy_commands, /* module directives */ - NGX_STREAM_MODULE, /* module type */ - NULL, /* init master */ - NULL, /* init module */ - NULL, /* init process */ - NULL, /* init thread */ - NULL, /* exit thread */ - NULL, /* exit process */ - NULL, /* exit master */ - NGX_MODULE_V1_PADDING -}; - - -static void -ngx_stream_proxy_handler(ngx_stream_session_t *s) -{ - u_char *p; - ngx_str_t *host; - ngx_uint_t i; - ngx_connection_t *c; - ngx_resolver_ctx_t *ctx, temp; - ngx_stream_upstream_t *u; - ngx_stream_core_srv_conf_t *cscf; - ngx_stream_proxy_srv_conf_t *pscf; - ngx_stream_upstream_srv_conf_t *uscf, **uscfp; - ngx_stream_upstream_main_conf_t *umcf; - - c = s->connection; - - pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module); - - ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0, - "proxy connection handler"); - - u = ngx_pcalloc(c->pool, sizeof(ngx_stream_upstream_t)); - if (u == NULL) { - ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR); - return; - } - - s->upstream = u; - - s->log_handler = ngx_stream_proxy_log_error; - - u->peer.log = c->log; - u->peer.log_error = NGX_ERROR_ERR; - - if (ngx_stream_proxy_set_local(s, u, pscf->local) != NGX_OK) { - ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR); - return; - } - - u->peer.type = c->type; - u->start_sec = ngx_time(); - - c->write->handler = ngx_stream_proxy_downstream_handler; - c->read->handler = ngx_stream_proxy_downstream_handler; - - s->upstream_states = ngx_array_create(c->pool, 1, - sizeof(ngx_stream_upstream_state_t)); - if (s->upstream_states == NULL) { - ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR); - return; - } - - if (c->type == SOCK_STREAM) { - p = ngx_pnalloc(c->pool, pscf->buffer_size); - if (p == NULL) { - ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR); - return; - } - - u->downstream_buf.start = p; - u->downstream_buf.end = p + pscf->buffer_size; - u->downstream_buf.pos = p; - u->downstream_buf.last = p; - - if (c->read->ready) { - ngx_post_event(c->read, &ngx_posted_events); - } - } - - if (pscf->upstream_value) { - if (ngx_stream_proxy_eval(s, pscf) != NGX_OK) { - ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR); - return; - } - } - - if (u->resolved == NULL) { - - uscf = pscf->upstream; - - } else { - -#if (NGX_STREAM_SSL) - u->ssl_name = u->resolved->host; -#endif - - host = &u->resolved->host; - - umcf = ngx_stream_get_module_main_conf(s, ngx_stream_upstream_module); - - uscfp = umcf->upstreams.elts; - - for (i = 0; i < umcf->upstreams.nelts; i++) { - - uscf = uscfp[i]; - - if (uscf->host.len == host->len - && ((uscf->port == 0 && u->resolved->no_port) - || uscf->port == u->resolved->port) - && ngx_strncasecmp(uscf->host.data, host->data, host->len) == 0) - { - goto found; - } - } - - if (u->resolved->sockaddr) { - - if (u->resolved->port == 0 - && u->resolved->sockaddr->sa_family != AF_UNIX) - { - ngx_log_error(NGX_LOG_ERR, c->log, 0, - "no port in upstream \"%V\"", host); - ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR); - return; - } - - if (ngx_stream_upstream_create_round_robin_peer(s, u->resolved) - != NGX_OK) - { - ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR); - return; - } - - ngx_stream_proxy_connect(s); - - return; - } - - if (u->resolved->port == 0) { - ngx_log_error(NGX_LOG_ERR, c->log, 0, - "no port in upstream \"%V\"", host); - ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR); - return; - } - - temp.name = *host; - - cscf = ngx_stream_get_module_srv_conf(s, ngx_stream_core_module); - - ctx = ngx_resolve_start(cscf->resolver, &temp); - if (ctx == NULL) { - ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR); - return; - } - - if (ctx == NGX_NO_RESOLVER) { - ngx_log_error(NGX_LOG_ERR, c->log, 0, - "no resolver defined to resolve %V", host); - ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR); - return; - } - - ctx->name = *host; - ctx->handler = ngx_stream_proxy_resolve_handler; - ctx->data = s; - ctx->timeout = cscf->resolver_timeout; - - u->resolved->ctx = ctx; - - if (ngx_resolve_name(ctx) != NGX_OK) { - u->resolved->ctx = NULL; - ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR); - return; - } - - return; - } - -found: - - if (uscf == NULL) { - ngx_log_error(NGX_LOG_ALERT, c->log, 0, "no upstream configuration"); - ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR); - return; - } - - u->upstream = uscf; - -#if (NGX_STREAM_SSL) - u->ssl_name = uscf->host; -#endif - - if (uscf->peer.init(s, uscf) != NGX_OK) { - ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR); - return; - } - - u->peer.start_time = ngx_current_msec; - - if (pscf->next_upstream_tries - && u->peer.tries > pscf->next_upstream_tries) - { - u->peer.tries = pscf->next_upstream_tries; - } - - ngx_stream_proxy_connect(s); -} - - -static ngx_int_t -ngx_stream_proxy_eval(ngx_stream_session_t *s, - ngx_stream_proxy_srv_conf_t *pscf) -{ - ngx_str_t host; - ngx_url_t url; - ngx_stream_upstream_t *u; - - if (ngx_stream_complex_value(s, pscf->upstream_value, &host) != NGX_OK) { - return NGX_ERROR; - } - - ngx_memzero(&url, sizeof(ngx_url_t)); - - url.url = host; - url.no_resolve = 1; - - if (ngx_parse_url(s->connection->pool, &url) != NGX_OK) { - if (url.err) { - ngx_log_error(NGX_LOG_ERR, s->connection->log, 0, - "%s in upstream \"%V\"", url.err, &url.url); - } - - return NGX_ERROR; - } - - u = s->upstream; - - u->resolved = ngx_pcalloc(s->connection->pool, - sizeof(ngx_stream_upstream_resolved_t)); - if (u->resolved == NULL) { - return NGX_ERROR; - } - - if (url.addrs) { - u->resolved->sockaddr = url.addrs[0].sockaddr; - u->resolved->socklen = url.addrs[0].socklen; - u->resolved->name = url.addrs[0].name; - u->resolved->naddrs = 1; - } - - u->resolved->host = url.host; - u->resolved->port = url.port; - u->resolved->no_port = url.no_port; - - return NGX_OK; -} - - -static ngx_int_t -ngx_stream_proxy_set_local(ngx_stream_session_t *s, ngx_stream_upstream_t *u, - ngx_stream_upstream_local_t *local) -{ - ngx_int_t rc; - ngx_str_t val; - ngx_addr_t *addr; - - if (local == NULL) { - u->peer.local = NULL; - return NGX_OK; - } - -#if (NGX_HAVE_TRANSPARENT_PROXY) - u->peer.transparent = local->transparent; -#endif - - if (local->value == NULL) { - u->peer.local = local->addr; - return NGX_OK; - } - - if (ngx_stream_complex_value(s, local->value, &val) != NGX_OK) { - return NGX_ERROR; - } - - if (val.len == 0) { - return NGX_OK; - } - - addr = ngx_palloc(s->connection->pool, sizeof(ngx_addr_t)); - if (addr == NULL) { - return NGX_ERROR; - } - - rc = ngx_parse_addr_port(s->connection->pool, addr, val.data, val.len); - if (rc == NGX_ERROR) { - return NGX_ERROR; - } - - if (rc != NGX_OK) { - ngx_log_error(NGX_LOG_ERR, s->connection->log, 0, - "invalid local address \"%V\"", &val); - return NGX_OK; - } - - addr->name = val; - u->peer.local = addr; - - return NGX_OK; -} - - -static void -ngx_stream_proxy_connect(ngx_stream_session_t *s) -{ - ngx_int_t rc; - ngx_connection_t *c, *pc; - ngx_stream_upstream_t *u; - ngx_stream_proxy_srv_conf_t *pscf; - - c = s->connection; - - c->log->action = "connecting to upstream"; - - pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module); - - u = s->upstream; - - u->connected = 0; - u->proxy_protocol = pscf->proxy_protocol; - - if (u->state) { - u->state->response_time = ngx_current_msec - u->state->response_time; - } - - u->state = ngx_array_push(s->upstream_states); - if (u->state == NULL) { - ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR); - return; - } - - ngx_memzero(u->state, sizeof(ngx_stream_upstream_state_t)); - - u->state->connect_time = (ngx_msec_t) -1; - u->state->first_byte_time = (ngx_msec_t) -1; - u->state->response_time = ngx_current_msec; - - rc = ngx_event_connect_peer(&u->peer); - - ngx_log_debug1(NGX_LOG_DEBUG_STREAM, c->log, 0, "proxy connect: %i", rc); - - if (rc == NGX_ERROR) { - ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR); - return; - } - - u->state->peer = u->peer.name; - - if (rc == NGX_BUSY) { - ngx_log_error(NGX_LOG_ERR, c->log, 0, "no live upstreams"); - ngx_stream_proxy_finalize(s, NGX_STREAM_BAD_GATEWAY); - return; - } - - if (rc == NGX_DECLINED) { - ngx_stream_proxy_next_upstream(s); - return; - } - - /* rc == NGX_OK || rc == NGX_AGAIN || rc == NGX_DONE */ - - pc = u->peer.connection; - - pc->data = s; - pc->log = c->log; - pc->pool = c->pool; - pc->read->log = c->log; - pc->write->log = c->log; - - if (rc != NGX_AGAIN) { - ngx_stream_proxy_init_upstream(s); - return; - } - - pc->read->handler = ngx_stream_proxy_connect_handler; - pc->write->handler = ngx_stream_proxy_connect_handler; - - ngx_add_timer(pc->write, pscf->connect_timeout); -} - - -static void -ngx_stream_proxy_init_upstream(ngx_stream_session_t *s) -{ - int tcp_nodelay; - u_char *p; - ngx_chain_t *cl; - ngx_connection_t *c, *pc; - ngx_log_handler_pt handler; - ngx_stream_upstream_t *u; - ngx_stream_core_srv_conf_t *cscf; - ngx_stream_proxy_srv_conf_t *pscf; - - u = s->upstream; - pc = u->peer.connection; - - cscf = ngx_stream_get_module_srv_conf(s, ngx_stream_core_module); - - if (pc->type == SOCK_STREAM - && cscf->tcp_nodelay - && pc->tcp_nodelay == NGX_TCP_NODELAY_UNSET) - { - ngx_log_debug0(NGX_LOG_DEBUG_STREAM, pc->log, 0, "tcp_nodelay"); - - tcp_nodelay = 1; - - if (setsockopt(pc->fd, IPPROTO_TCP, TCP_NODELAY, - (const void *) &tcp_nodelay, sizeof(int)) == -1) - { - ngx_connection_error(pc, ngx_socket_errno, - "setsockopt(TCP_NODELAY) failed"); - ngx_stream_proxy_next_upstream(s); - return; - } - - pc->tcp_nodelay = NGX_TCP_NODELAY_SET; - } - - pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module); - -#if (NGX_STREAM_SSL) - - if (pc->type == SOCK_STREAM && pscf->ssl) { - - if (u->proxy_protocol) { - if (ngx_stream_proxy_send_proxy_protocol(s) != NGX_OK) { - return; - } - - u->proxy_protocol = 0; - } - - if (pc->ssl == NULL) { - ngx_stream_proxy_ssl_init_connection(s); - return; - } - } - -#endif - - c = s->connection; - - if (c->log->log_level >= NGX_LOG_INFO) { - ngx_str_t str; - u_char addr[NGX_SOCKADDR_STRLEN]; - - str.len = NGX_SOCKADDR_STRLEN; - str.data = addr; - - if (ngx_connection_local_sockaddr(pc, &str, 1) == NGX_OK) { - handler = c->log->handler; - c->log->handler = NULL; - - ngx_log_error(NGX_LOG_INFO, c->log, 0, - "%sproxy %V connected to %V", - pc->type == SOCK_DGRAM ? "udp " : "", - &str, u->peer.name); - - c->log->handler = handler; - } - } - - u->state->connect_time = ngx_current_msec - u->state->response_time; - - if (u->peer.notify) { - u->peer.notify(&u->peer, u->peer.data, - NGX_STREAM_UPSTREAM_NOTIFY_CONNECT); - } - - c->log->action = "proxying connection"; - - if (u->upstream_buf.start == NULL) { - p = ngx_pnalloc(c->pool, pscf->buffer_size); - if (p == NULL) { - ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR); - return; - } - - u->upstream_buf.start = p; - u->upstream_buf.end = p + pscf->buffer_size; - u->upstream_buf.pos = p; - u->upstream_buf.last = p; - } - - if (c->buffer && c->buffer->pos < c->buffer->last) { - ngx_log_debug1(NGX_LOG_DEBUG_STREAM, c->log, 0, - "stream proxy add preread buffer: %uz", - c->buffer->last - c->buffer->pos); - - cl = ngx_chain_get_free_buf(c->pool, &u->free); - if (cl == NULL) { - ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR); - return; - } - - *cl->buf = *c->buffer; - - cl->buf->tag = (ngx_buf_tag_t) &ngx_stream_proxy_module; - cl->buf->flush = 1; - cl->buf->last_buf = (c->type == SOCK_DGRAM); - - cl->next = u->upstream_out; - u->upstream_out = cl; - } - - if (u->proxy_protocol) { - ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0, - "stream proxy add PROXY protocol header"); - - cl = ngx_chain_get_free_buf(c->pool, &u->free); - if (cl == NULL) { - ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR); - return; - } - - p = ngx_pnalloc(c->pool, NGX_PROXY_PROTOCOL_MAX_HEADER); - if (p == NULL) { - ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR); - return; - } - - cl->buf->pos = p; - - p = ngx_proxy_protocol_write(c, p, p + NGX_PROXY_PROTOCOL_MAX_HEADER); - if (p == NULL) { - ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR); - return; - } - - cl->buf->last = p; - cl->buf->temporary = 1; - cl->buf->flush = 0; - cl->buf->last_buf = 0; - cl->buf->tag = (ngx_buf_tag_t) &ngx_stream_proxy_module; - - cl->next = u->upstream_out; - u->upstream_out = cl; - - u->proxy_protocol = 0; - } - - if (c->type == SOCK_DGRAM && pscf->responses == 0) { - pc->read->ready = 0; - pc->read->eof = 1; - } - - u->connected = 1; - - pc->read->handler = ngx_stream_proxy_upstream_handler; - pc->write->handler = ngx_stream_proxy_upstream_handler; - - if (pc->read->ready || pc->read->eof) { - ngx_post_event(pc->read, &ngx_posted_events); - } - - ngx_stream_proxy_process(s, 0, 1); -} - - -#if (NGX_STREAM_SSL) - -static ngx_int_t -ngx_stream_proxy_send_proxy_protocol(ngx_stream_session_t *s) -{ - u_char *p; - ssize_t n, size; - ngx_connection_t *c, *pc; - ngx_stream_upstream_t *u; - ngx_stream_proxy_srv_conf_t *pscf; - u_char buf[NGX_PROXY_PROTOCOL_MAX_HEADER]; - - c = s->connection; - - ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0, - "stream proxy send PROXY protocol header"); - - p = ngx_proxy_protocol_write(c, buf, buf + NGX_PROXY_PROTOCOL_MAX_HEADER); - if (p == NULL) { - ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR); - return NGX_ERROR; - } - - u = s->upstream; - - pc = u->peer.connection; - - size = p - buf; - - n = pc->send(pc, buf, size); - - if (n == NGX_AGAIN) { - if (ngx_handle_write_event(pc->write, 0) != NGX_OK) { - ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR); - return NGX_ERROR; - } - - pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module); - - ngx_add_timer(pc->write, pscf->timeout); - - pc->write->handler = ngx_stream_proxy_connect_handler; - - return NGX_AGAIN; - } - - if (n == NGX_ERROR) { - ngx_stream_proxy_finalize(s, NGX_STREAM_OK); - return NGX_ERROR; - } - - if (n != size) { - - /* - * PROXY protocol specification: - * The sender must always ensure that the header - * is sent at once, so that the transport layer - * maintains atomicity along the path to the receiver. - */ - - ngx_log_error(NGX_LOG_ERR, c->log, 0, - "could not send PROXY protocol header at once"); - - ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR); - - return NGX_ERROR; - } - - return NGX_OK; -} - - -static char * -ngx_stream_proxy_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd, - void *conf) -{ - ngx_stream_proxy_srv_conf_t *pscf = conf; - - ngx_str_t *value; - - if (pscf->ssl_passwords != NGX_CONF_UNSET_PTR) { - return "is duplicate"; - } - - value = cf->args->elts; - - pscf->ssl_passwords = ngx_ssl_read_password_file(cf, &value[1]); - - if (pscf->ssl_passwords == NULL) { - return NGX_CONF_ERROR; - } - - return NGX_CONF_OK; -} - - -static void -ngx_stream_proxy_ssl_init_connection(ngx_stream_session_t *s) -{ - ngx_int_t rc; - ngx_connection_t *pc; - ngx_stream_upstream_t *u; - ngx_stream_proxy_srv_conf_t *pscf; - - u = s->upstream; - - pc = u->peer.connection; - - pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module); - - if (ngx_ssl_create_connection(pscf->ssl, pc, NGX_SSL_BUFFER|NGX_SSL_CLIENT) - != NGX_OK) - { - ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR); - return; - } - - if (pscf->ssl_server_name || pscf->ssl_verify) { - if (ngx_stream_proxy_ssl_name(s) != NGX_OK) { - ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR); - return; - } - } - - if (pscf->ssl_session_reuse) { - if (u->peer.set_session(&u->peer, u->peer.data) != NGX_OK) { - ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR); - return; - } - } - - s->connection->log->action = "SSL handshaking to upstream"; - - rc = ngx_ssl_handshake(pc); - - if (rc == NGX_AGAIN) { - - if (!pc->write->timer_set) { - ngx_add_timer(pc->write, pscf->connect_timeout); - } - - pc->ssl->handler = ngx_stream_proxy_ssl_handshake; - return; - } - - ngx_stream_proxy_ssl_handshake(pc); -} - - -static void -ngx_stream_proxy_ssl_handshake(ngx_connection_t *pc) -{ - long rc; - ngx_stream_session_t *s; - ngx_stream_upstream_t *u; - ngx_stream_proxy_srv_conf_t *pscf; - - s = pc->data; - - pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module); - - if (pc->ssl->handshaked) { - - if (pscf->ssl_verify) { - rc = SSL_get_verify_result(pc->ssl->connection); - - if (rc != X509_V_OK) { - ngx_log_error(NGX_LOG_ERR, pc->log, 0, - "upstream SSL certificate verify error: (%l:%s)", - rc, X509_verify_cert_error_string(rc)); - goto failed; - } - - u = s->upstream; - - if (ngx_ssl_check_host(pc, &u->ssl_name) != NGX_OK) { - ngx_log_error(NGX_LOG_ERR, pc->log, 0, - "upstream SSL certificate does not match \"%V\"", - &u->ssl_name); - goto failed; - } - } - - if (pscf->ssl_session_reuse) { - u = s->upstream; - u->peer.save_session(&u->peer, u->peer.data); - } - - if (pc->write->timer_set) { - ngx_del_timer(pc->write); - } - - ngx_stream_proxy_init_upstream(s); - - return; - } - -failed: - - ngx_stream_proxy_next_upstream(s); -} - - -static ngx_int_t -ngx_stream_proxy_ssl_name(ngx_stream_session_t *s) -{ - u_char *p, *last; - ngx_str_t name; - ngx_stream_upstream_t *u; - ngx_stream_proxy_srv_conf_t *pscf; - - pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module); - - u = s->upstream; - - if (pscf->ssl_name) { - if (ngx_stream_complex_value(s, pscf->ssl_name, &name) != NGX_OK) { - return NGX_ERROR; - } - - } else { - name = u->ssl_name; - } - - if (name.len == 0) { - goto done; - } - - /* - * ssl name here may contain port, strip it for compatibility - * with the http module - */ - - p = name.data; - last = name.data + name.len; - - if (*p == '[') { - p = ngx_strlchr(p, last, ']'); - - if (p == NULL) { - p = name.data; - } - } - - p = ngx_strlchr(p, last, ':'); - - if (p != NULL) { - name.len = p - name.data; - } - - if (!pscf->ssl_server_name) { - goto done; - } - -#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME - - /* as per RFC 6066, literal IPv4 and IPv6 addresses are not permitted */ - - if (name.len == 0 || *name.data == '[') { - goto done; - } - - if (ngx_inet_addr(name.data, name.len) != INADDR_NONE) { - goto done; - } - - /* - * SSL_set_tlsext_host_name() needs a null-terminated string, - * hence we explicitly null-terminate name here - */ - - p = ngx_pnalloc(s->connection->pool, name.len + 1); - if (p == NULL) { - return NGX_ERROR; - } - - (void) ngx_cpystrn(p, name.data, name.len + 1); - - name.data = p; - - ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0, - "upstream SSL server name: \"%s\"", name.data); - - if (SSL_set_tlsext_host_name(u->peer.connection->ssl->connection, - (char *) name.data) - == 0) - { - ngx_ssl_error(NGX_LOG_ERR, s->connection->log, 0, - "SSL_set_tlsext_host_name(\"%s\") failed", name.data); - return NGX_ERROR; - } - -#endif - -done: - - u->ssl_name = name; - - return NGX_OK; -} - -#endif - - -static void -ngx_stream_proxy_downstream_handler(ngx_event_t *ev) -{ - ngx_stream_proxy_process_connection(ev, ev->write); -} - - -static void -ngx_stream_proxy_resolve_handler(ngx_resolver_ctx_t *ctx) -{ - ngx_stream_session_t *s; - ngx_stream_upstream_t *u; - ngx_stream_proxy_srv_conf_t *pscf; - ngx_stream_upstream_resolved_t *ur; - - s = ctx->data; - - u = s->upstream; - ur = u->resolved; - - ngx_log_debug0(NGX_LOG_DEBUG_STREAM, s->connection->log, 0, - "stream upstream resolve"); - - if (ctx->state) { - ngx_log_error(NGX_LOG_ERR, s->connection->log, 0, - "%V could not be resolved (%i: %s)", - &ctx->name, ctx->state, - ngx_resolver_strerror(ctx->state)); - - ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR); - return; - } - - ur->naddrs = ctx->naddrs; - ur->addrs = ctx->addrs; - -#if (NGX_DEBUG) - { - u_char text[NGX_SOCKADDR_STRLEN]; - ngx_str_t addr; - ngx_uint_t i; - - 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_STREAM, s->connection->log, 0, - "name was resolved to %V", &addr); - } - } -#endif - - if (ngx_stream_upstream_create_round_robin_peer(s, ur) != NGX_OK) { - ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR); - return; - } - - ngx_resolve_name_done(ctx); - ur->ctx = NULL; - - u->peer.start_time = ngx_current_msec; - - pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module); - - if (pscf->next_upstream_tries - && u->peer.tries > pscf->next_upstream_tries) - { - u->peer.tries = pscf->next_upstream_tries; - } - - ngx_stream_proxy_connect(s); -} - - -static void -ngx_stream_proxy_upstream_handler(ngx_event_t *ev) -{ - ngx_stream_proxy_process_connection(ev, !ev->write); -} - - -static void -ngx_stream_proxy_process_connection(ngx_event_t *ev, ngx_uint_t from_upstream) -{ - ngx_connection_t *c, *pc; - ngx_stream_session_t *s; - ngx_stream_upstream_t *u; - ngx_stream_proxy_srv_conf_t *pscf; - - c = ev->data; - s = c->data; - u = s->upstream; - - c = s->connection; - pc = u->peer.connection; - - pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module); - - if (ev->timedout) { - ev->timedout = 0; - - if (ev->delayed) { - ev->delayed = 0; - - if (!ev->ready) { - if (ngx_handle_read_event(ev, 0) != NGX_OK) { - ngx_stream_proxy_finalize(s, - NGX_STREAM_INTERNAL_SERVER_ERROR); - return; - } - - if (u->connected && !c->read->delayed && !pc->read->delayed) { - ngx_add_timer(c->write, pscf->timeout); - } - - return; - } - - } else { - if (s->connection->type == SOCK_DGRAM) { - if (pscf->responses == NGX_MAX_INT32_VALUE) { - - /* - * successfully terminate timed out UDP session - * with unspecified number of responses - */ - - pc->read->ready = 0; - pc->read->eof = 1; - - ngx_stream_proxy_process(s, 1, 0); - return; - } - - if (u->received == 0) { - ngx_stream_proxy_next_upstream(s); - return; - } - } - - ngx_connection_error(c, NGX_ETIMEDOUT, "connection timed out"); - ngx_stream_proxy_finalize(s, NGX_STREAM_OK); - return; - } - - } else if (ev->delayed) { - - ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0, - "stream connection delayed"); - - if (ngx_handle_read_event(ev, 0) != NGX_OK) { - ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR); - } - - return; - } - - if (from_upstream && !u->connected) { - return; - } - - ngx_stream_proxy_process(s, from_upstream, ev->write); -} - - -static void -ngx_stream_proxy_connect_handler(ngx_event_t *ev) -{ - ngx_connection_t *c; - ngx_stream_session_t *s; - - c = ev->data; - s = c->data; - - if (ev->timedout) { - ngx_log_error(NGX_LOG_ERR, c->log, NGX_ETIMEDOUT, "upstream timed out"); - ngx_stream_proxy_next_upstream(s); - return; - } - - ngx_del_timer(c->write); - - ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0, - "stream proxy connect upstream"); - - if (ngx_stream_proxy_test_connect(c) != NGX_OK) { - ngx_stream_proxy_next_upstream(s); - return; - } - - ngx_stream_proxy_init_upstream(s); -} - - -static ngx_int_t -ngx_stream_proxy_test_connect(ngx_connection_t *c) -{ - int err; - socklen_t len; - -#if (NGX_HAVE_KQUEUE) - - if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) { - err = c->write->kq_errno ? c->write->kq_errno : c->read->kq_errno; - - if (err) { - (void) ngx_connection_error(c, err, - "kevent() reported that connect() failed"); - return NGX_ERROR; - } - - } else -#endif - { - err = 0; - len = sizeof(int); - - /* - * BSDs and Linux return 0 and set a pending error in err - * Solaris returns -1 and sets errno - */ - - if (getsockopt(c->fd, SOL_SOCKET, SO_ERROR, (void *) &err, &len) - == -1) - { - err = ngx_socket_errno; - } - - if (err) { - (void) ngx_connection_error(c, err, "connect() failed"); - return NGX_ERROR; - } - } - - return NGX_OK; -} - - -static void -ngx_stream_proxy_process(ngx_stream_session_t *s, ngx_uint_t from_upstream, - ngx_uint_t do_write) -{ - off_t *received, limit; - size_t size, limit_rate; - ssize_t n; - ngx_buf_t *b; - ngx_int_t rc; - ngx_uint_t flags; - ngx_msec_t delay; - ngx_chain_t *cl, **ll, **out, **busy; - ngx_connection_t *c, *pc, *src, *dst; - ngx_log_handler_pt handler; - ngx_stream_upstream_t *u; - ngx_stream_proxy_srv_conf_t *pscf; - - u = s->upstream; - - c = s->connection; - pc = u->connected ? u->peer.connection : NULL; - - if (c->type == SOCK_DGRAM && (ngx_terminate || ngx_exiting)) { - - /* socket is already closed on worker shutdown */ - - handler = c->log->handler; - c->log->handler = NULL; - - ngx_log_error(NGX_LOG_INFO, c->log, 0, "disconnected on shutdown"); - - c->log->handler = handler; - - ngx_stream_proxy_finalize(s, NGX_STREAM_OK); - return; - } - - pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module); - - if (from_upstream) { - src = pc; - dst = c; - b = &u->upstream_buf; - limit_rate = pscf->download_rate; - received = &u->received; - out = &u->downstream_out; - busy = &u->downstream_busy; - - } else { - src = c; - dst = pc; - b = &u->downstream_buf; - limit_rate = pscf->upload_rate; - received = &s->received; - out = &u->upstream_out; - busy = &u->upstream_busy; - } - - for ( ;; ) { - - if (do_write && dst) { - - if (*out || *busy || dst->buffered) { - rc = ngx_stream_top_filter(s, *out, from_upstream); - - if (rc == NGX_ERROR) { - if (c->type == SOCK_DGRAM && !from_upstream) { - ngx_stream_proxy_next_upstream(s); - return; - } - - ngx_stream_proxy_finalize(s, NGX_STREAM_OK); - return; - } - - ngx_chain_update_chains(c->pool, &u->free, busy, out, - (ngx_buf_tag_t) &ngx_stream_proxy_module); - - if (*busy == NULL) { - b->pos = b->start; - b->last = b->start; - } - } - } - - size = b->end - b->last; - - if (size && src->read->ready && !src->read->delayed - && !src->read->error) - { - if (limit_rate) { - limit = (off_t) limit_rate * (ngx_time() - u->start_sec + 1) - - *received; - - if (limit <= 0) { - src->read->delayed = 1; - delay = (ngx_msec_t) (- limit * 1000 / limit_rate + 1); - ngx_add_timer(src->read, delay); - break; - } - - if ((off_t) size > limit) { - size = (size_t) limit; - } - } - - n = src->recv(src, b->last, size); - - if (n == NGX_AGAIN) { - break; - } - - if (n == NGX_ERROR) { - if (c->type == SOCK_DGRAM && u->received == 0) { - ngx_stream_proxy_next_upstream(s); - return; - } - - src->read->eof = 1; - n = 0; - } - - if (n >= 0) { - if (limit_rate) { - delay = (ngx_msec_t) (n * 1000 / limit_rate); - - if (delay > 0) { - src->read->delayed = 1; - ngx_add_timer(src->read, delay); - } - } - - if (from_upstream) { - if (u->state->first_byte_time == (ngx_msec_t) -1) { - u->state->first_byte_time = ngx_current_msec - - u->state->response_time; - } - } - - if (c->type == SOCK_DGRAM && ++u->responses == pscf->responses) - { - src->read->ready = 0; - src->read->eof = 1; - } - - for (ll = out; *ll; ll = &(*ll)->next) { /* void */ } - - cl = ngx_chain_get_free_buf(c->pool, &u->free); - if (cl == NULL) { - ngx_stream_proxy_finalize(s, - NGX_STREAM_INTERNAL_SERVER_ERROR); - return; - } - - *ll = cl; - - cl->buf->pos = b->last; - cl->buf->last = b->last + n; - cl->buf->tag = (ngx_buf_tag_t) &ngx_stream_proxy_module; - - cl->buf->temporary = (n ? 1 : 0); - cl->buf->last_buf = src->read->eof; - cl->buf->flush = 1; - - *received += n; - b->last += n; - do_write = 1; - - continue; - } - } - - break; - } - - if (src->read->eof && dst && (dst->read->eof || !dst->buffered)) { - handler = c->log->handler; - c->log->handler = NULL; - - ngx_log_error(NGX_LOG_INFO, c->log, 0, - "%s%s disconnected" - ", bytes from/to client:%O/%O" - ", bytes from/to upstream:%O/%O", - src->type == SOCK_DGRAM ? "udp " : "", - from_upstream ? "upstream" : "client", - s->received, c->sent, u->received, pc ? pc->sent : 0); - - c->log->handler = handler; - - ngx_stream_proxy_finalize(s, NGX_STREAM_OK); - return; - } - - flags = src->read->eof ? NGX_CLOSE_EVENT : 0; - - if (!src->shared && ngx_handle_read_event(src->read, flags) != NGX_OK) { - ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR); - return; - } - - if (dst) { - if (!dst->shared && ngx_handle_write_event(dst->write, 0) != NGX_OK) { - ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR); - return; - } - - if (!c->read->delayed && !pc->read->delayed) { - ngx_add_timer(c->write, pscf->timeout); - - } else if (c->write->timer_set) { - ngx_del_timer(c->write); - } - } -} - - -static void -ngx_stream_proxy_next_upstream(ngx_stream_session_t *s) -{ - ngx_msec_t timeout; - ngx_connection_t *pc; - ngx_stream_upstream_t *u; - ngx_stream_proxy_srv_conf_t *pscf; - - ngx_log_debug0(NGX_LOG_DEBUG_STREAM, s->connection->log, 0, - "stream proxy next upstream"); - - u = s->upstream; - pc = u->peer.connection; - - if (u->upstream_out || u->upstream_busy || (pc && pc->buffered)) { - ngx_log_error(NGX_LOG_ERR, s->connection->log, 0, - "pending buffers on next upstream"); - ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR); - return; - } - - if (u->peer.sockaddr) { - u->peer.free(&u->peer, u->peer.data, NGX_PEER_FAILED); - u->peer.sockaddr = NULL; - } - - pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module); - - timeout = pscf->next_upstream_timeout; - - if (u->peer.tries == 0 - || !pscf->next_upstream - || (timeout && ngx_current_msec - u->peer.start_time >= timeout)) - { - ngx_stream_proxy_finalize(s, NGX_STREAM_BAD_GATEWAY); - return; - } - - if (pc) { - ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0, - "close proxy upstream connection: %d", pc->fd); - -#if (NGX_STREAM_SSL) - if (pc->ssl) { - pc->ssl->no_wait_shutdown = 1; - pc->ssl->no_send_shutdown = 1; - - (void) ngx_ssl_shutdown(pc); - } -#endif - - u->state->bytes_received = u->received; - u->state->bytes_sent = pc->sent; - - ngx_close_connection(pc); - u->peer.connection = NULL; - } - - ngx_stream_proxy_connect(s); -} - - -static void -ngx_stream_proxy_finalize(ngx_stream_session_t *s, ngx_uint_t rc) -{ - ngx_connection_t *pc; - ngx_stream_upstream_t *u; - - ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0, - "finalize stream proxy: %i", rc); - - u = s->upstream; - - if (u == NULL) { - goto noupstream; - } - - if (u->resolved && u->resolved->ctx) { - ngx_resolve_name_done(u->resolved->ctx); - u->resolved->ctx = NULL; - } - - pc = u->peer.connection; - - if (u->state) { - u->state->response_time = ngx_current_msec - u->state->response_time; - - if (pc) { - u->state->bytes_received = u->received; - u->state->bytes_sent = pc->sent; - } - } - - if (u->peer.free && u->peer.sockaddr) { - u->peer.free(&u->peer, u->peer.data, 0); - u->peer.sockaddr = NULL; - } - - if (pc) { - ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0, - "close stream proxy upstream connection: %d", pc->fd); - -#if (NGX_STREAM_SSL) - if (pc->ssl) { - pc->ssl->no_wait_shutdown = 1; - (void) ngx_ssl_shutdown(pc); - } -#endif - - ngx_close_connection(pc); - u->peer.connection = NULL; - } - -noupstream: - - ngx_stream_finalize_session(s, rc); -} - - -static u_char * -ngx_stream_proxy_log_error(ngx_log_t *log, u_char *buf, size_t len) -{ - u_char *p; - ngx_connection_t *pc; - ngx_stream_session_t *s; - ngx_stream_upstream_t *u; - - s = log->data; - - u = s->upstream; - - p = buf; - - if (u->peer.name) { - p = ngx_snprintf(p, len, ", upstream: \"%V\"", u->peer.name); - len -= p - buf; - } - - pc = u->peer.connection; - - p = ngx_snprintf(p, len, - ", bytes from/to client:%O/%O" - ", bytes from/to upstream:%O/%O", - s->received, s->connection->sent, - u->received, pc ? pc->sent : 0); - - return p; -} - - -static void * -ngx_stream_proxy_create_srv_conf(ngx_conf_t *cf) -{ - ngx_stream_proxy_srv_conf_t *conf; - - conf = ngx_pcalloc(cf->pool, sizeof(ngx_stream_proxy_srv_conf_t)); - if (conf == NULL) { - return NULL; - } - - /* - * set by ngx_pcalloc(): - * - * conf->ssl_protocols = 0; - * conf->ssl_ciphers = { 0, NULL }; - * conf->ssl_name = NULL; - * conf->ssl_trusted_certificate = { 0, NULL }; - * conf->ssl_crl = { 0, NULL }; - * conf->ssl_certificate = { 0, NULL }; - * conf->ssl_certificate_key = { 0, NULL }; - * - * conf->ssl = NULL; - * conf->upstream = NULL; - * conf->upstream_value = NULL; - */ - - conf->connect_timeout = NGX_CONF_UNSET_MSEC; - conf->timeout = NGX_CONF_UNSET_MSEC; - conf->next_upstream_timeout = NGX_CONF_UNSET_MSEC; - conf->buffer_size = NGX_CONF_UNSET_SIZE; - conf->upload_rate = NGX_CONF_UNSET_SIZE; - conf->download_rate = NGX_CONF_UNSET_SIZE; - conf->responses = NGX_CONF_UNSET_UINT; - conf->next_upstream_tries = NGX_CONF_UNSET_UINT; - conf->next_upstream = NGX_CONF_UNSET; - conf->proxy_protocol = NGX_CONF_UNSET; - conf->local = NGX_CONF_UNSET_PTR; - -#if (NGX_STREAM_SSL) - conf->ssl_enable = NGX_CONF_UNSET; - conf->ssl_session_reuse = NGX_CONF_UNSET; - conf->ssl_server_name = NGX_CONF_UNSET; - conf->ssl_verify = NGX_CONF_UNSET; - conf->ssl_verify_depth = NGX_CONF_UNSET_UINT; - conf->ssl_passwords = NGX_CONF_UNSET_PTR; -#endif - - return conf; -} - - -static char * -ngx_stream_proxy_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) -{ - ngx_stream_proxy_srv_conf_t *prev = parent; - ngx_stream_proxy_srv_conf_t *conf = child; - - ngx_conf_merge_msec_value(conf->connect_timeout, - prev->connect_timeout, 60000); - - ngx_conf_merge_msec_value(conf->timeout, - prev->timeout, 10 * 60000); - - ngx_conf_merge_msec_value(conf->next_upstream_timeout, - prev->next_upstream_timeout, 0); - - ngx_conf_merge_size_value(conf->buffer_size, - prev->buffer_size, 16384); - - ngx_conf_merge_size_value(conf->upload_rate, - prev->upload_rate, 0); - - ngx_conf_merge_size_value(conf->download_rate, - prev->download_rate, 0); - - ngx_conf_merge_uint_value(conf->responses, - prev->responses, NGX_MAX_INT32_VALUE); - - ngx_conf_merge_uint_value(conf->next_upstream_tries, - prev->next_upstream_tries, 0); - - ngx_conf_merge_value(conf->next_upstream, prev->next_upstream, 1); - - ngx_conf_merge_value(conf->proxy_protocol, prev->proxy_protocol, 0); - - ngx_conf_merge_ptr_value(conf->local, prev->local, NULL); - -#if (NGX_STREAM_SSL) - - ngx_conf_merge_value(conf->ssl_enable, prev->ssl_enable, 0); - - ngx_conf_merge_value(conf->ssl_session_reuse, - prev->ssl_session_reuse, 1); - - ngx_conf_merge_bitmask_value(conf->ssl_protocols, prev->ssl_protocols, - (NGX_CONF_BITMASK_SET|NGX_SSL_TLSv1 - |NGX_SSL_TLSv1_1|NGX_SSL_TLSv1_2)); - - ngx_conf_merge_str_value(conf->ssl_ciphers, prev->ssl_ciphers, "DEFAULT"); - - if (conf->ssl_name == NULL) { - conf->ssl_name = prev->ssl_name; - } - - ngx_conf_merge_value(conf->ssl_server_name, prev->ssl_server_name, 0); - - ngx_conf_merge_value(conf->ssl_verify, prev->ssl_verify, 0); - - ngx_conf_merge_uint_value(conf->ssl_verify_depth, - prev->ssl_verify_depth, 1); - - ngx_conf_merge_str_value(conf->ssl_trusted_certificate, - prev->ssl_trusted_certificate, ""); - - ngx_conf_merge_str_value(conf->ssl_crl, prev->ssl_crl, ""); - - ngx_conf_merge_str_value(conf->ssl_certificate, - prev->ssl_certificate, ""); - - ngx_conf_merge_str_value(conf->ssl_certificate_key, - prev->ssl_certificate_key, ""); - - ngx_conf_merge_ptr_value(conf->ssl_passwords, prev->ssl_passwords, NULL); - - if (conf->ssl_enable && ngx_stream_proxy_set_ssl(cf, conf) != NGX_OK) { - return NGX_CONF_ERROR; - } - -#endif - - return NGX_CONF_OK; -} - - -#if (NGX_STREAM_SSL) - -static ngx_int_t -ngx_stream_proxy_set_ssl(ngx_conf_t *cf, ngx_stream_proxy_srv_conf_t *pscf) -{ - ngx_pool_cleanup_t *cln; - - pscf->ssl = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_t)); - if (pscf->ssl == NULL) { - return NGX_ERROR; - } - - pscf->ssl->log = cf->log; - - if (ngx_ssl_create(pscf->ssl, pscf->ssl_protocols, NULL) != NGX_OK) { - return NGX_ERROR; - } - - cln = ngx_pool_cleanup_add(cf->pool, 0); - if (cln == NULL) { - return NGX_ERROR; - } - - cln->handler = ngx_ssl_cleanup_ctx; - cln->data = pscf->ssl; - - if (pscf->ssl_certificate.len) { - - if (pscf->ssl_certificate_key.len == 0) { - ngx_log_error(NGX_LOG_EMERG, cf->log, 0, - "no \"proxy_ssl_certificate_key\" is defined " - "for certificate \"%V\"", &pscf->ssl_certificate); - return NGX_ERROR; - } - - if (ngx_ssl_certificate(cf, pscf->ssl, &pscf->ssl_certificate, - &pscf->ssl_certificate_key, pscf->ssl_passwords) - != NGX_OK) - { - return NGX_ERROR; - } - } - - if (ngx_ssl_ciphers(cf, pscf->ssl, &pscf->ssl_ciphers, 0) != NGX_OK) { - return NGX_ERROR; - } - - if (pscf->ssl_verify) { - if (pscf->ssl_trusted_certificate.len == 0) { - ngx_log_error(NGX_LOG_EMERG, cf->log, 0, - "no proxy_ssl_trusted_certificate for proxy_ssl_verify"); - return NGX_ERROR; - } - - if (ngx_ssl_trusted_certificate(cf, pscf->ssl, - &pscf->ssl_trusted_certificate, - pscf->ssl_verify_depth) - != NGX_OK) - { - return NGX_ERROR; - } - - if (ngx_ssl_crl(cf, pscf->ssl, &pscf->ssl_crl) != NGX_OK) { - return NGX_ERROR; - } - } - - return NGX_OK; -} - -#endif - - -static char * -ngx_stream_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) -{ - ngx_stream_proxy_srv_conf_t *pscf = conf; - - ngx_url_t u; - ngx_str_t *value, *url; - ngx_stream_complex_value_t cv; - ngx_stream_core_srv_conf_t *cscf; - ngx_stream_compile_complex_value_t ccv; - - if (pscf->upstream || pscf->upstream_value) { - return "is duplicate"; - } - - cscf = ngx_stream_conf_get_module_srv_conf(cf, ngx_stream_core_module); - - cscf->handler = ngx_stream_proxy_handler; - - value = cf->args->elts; - - url = &value[1]; - - ngx_memzero(&ccv, sizeof(ngx_stream_compile_complex_value_t)); - - ccv.cf = cf; - ccv.value = url; - ccv.complex_value = &cv; - - if (ngx_stream_compile_complex_value(&ccv) != NGX_OK) { - return NGX_CONF_ERROR; - } - - if (cv.lengths) { - pscf->upstream_value = ngx_palloc(cf->pool, - sizeof(ngx_stream_complex_value_t)); - if (pscf->upstream_value == NULL) { - return NGX_CONF_ERROR; - } - - *pscf->upstream_value = cv; - - return NGX_CONF_OK; - } - - ngx_memzero(&u, sizeof(ngx_url_t)); - - u.url = *url; - u.no_resolve = 1; - - pscf->upstream = ngx_stream_upstream_add(cf, &u, 0); - if (pscf->upstream == NULL) { - return NGX_CONF_ERROR; - } - - return NGX_CONF_OK; -} - - -static char * -ngx_stream_proxy_bind(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) -{ - ngx_stream_proxy_srv_conf_t *pscf = conf; - - ngx_int_t rc; - ngx_str_t *value; - ngx_stream_complex_value_t cv; - ngx_stream_upstream_local_t *local; - ngx_stream_compile_complex_value_t ccv; - - if (pscf->local != NGX_CONF_UNSET_PTR) { - return "is duplicate"; - } - - value = cf->args->elts; - - if (cf->args->nelts == 2 && ngx_strcmp(value[1].data, "off") == 0) { - pscf->local = NULL; - return NGX_CONF_OK; - } - - ngx_memzero(&ccv, sizeof(ngx_stream_compile_complex_value_t)); - - ccv.cf = cf; - ccv.value = &value[1]; - ccv.complex_value = &cv; - - if (ngx_stream_compile_complex_value(&ccv) != NGX_OK) { - return NGX_CONF_ERROR; - } - - local = ngx_pcalloc(cf->pool, sizeof(ngx_stream_upstream_local_t)); - if (local == NULL) { - return NGX_CONF_ERROR; - } - - pscf->local = local; - - if (cv.lengths) { - local->value = ngx_palloc(cf->pool, sizeof(ngx_stream_complex_value_t)); - if (local->value == NULL) { - return NGX_CONF_ERROR; - } - - *local->value = cv; - - } else { - local->addr = ngx_palloc(cf->pool, sizeof(ngx_addr_t)); - if (local->addr == NULL) { - return NGX_CONF_ERROR; - } - - rc = ngx_parse_addr_port(cf->pool, local->addr, value[1].data, - value[1].len); - - switch (rc) { - case NGX_OK: - local->addr->name = value[1]; - break; - - case NGX_DECLINED: - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "invalid address \"%V\"", &value[1]); - /* fall through */ - - default: - return NGX_CONF_ERROR; - } - } - - if (cf->args->nelts > 2) { - if (ngx_strcmp(value[2].data, "transparent") == 0) { -#if (NGX_HAVE_TRANSPARENT_PROXY) - local->transparent = 1; -#else - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "transparent proxying is not supported " - "on this platform, ignored"); -#endif - } else { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "invalid parameter \"%V\"", &value[2]); - return NGX_CONF_ERROR; - } - } - - return NGX_CONF_OK; -} diff --git a/app/nginx/src/stream/ngx_stream_realip_module.c b/app/nginx/src/stream/ngx_stream_realip_module.c deleted file mode 100644 index 0740431..0000000 --- a/app/nginx/src/stream/ngx_stream_realip_module.c +++ /dev/null @@ -1,348 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) Nginx, Inc. - */ - - -#include <ngx_config.h> -#include <ngx_core.h> -#include <ngx_stream.h> - - -typedef struct { - ngx_array_t *from; /* array of ngx_cidr_t */ -} ngx_stream_realip_srv_conf_t; - - -typedef struct { - struct sockaddr *sockaddr; - socklen_t socklen; - ngx_str_t addr_text; -} ngx_stream_realip_ctx_t; - - -static ngx_int_t ngx_stream_realip_handler(ngx_stream_session_t *s); -static ngx_int_t ngx_stream_realip_set_addr(ngx_stream_session_t *s, - ngx_addr_t *addr); -static char *ngx_stream_realip_from(ngx_conf_t *cf, ngx_command_t *cmd, - void *conf); -static void *ngx_stream_realip_create_srv_conf(ngx_conf_t *cf); -static char *ngx_stream_realip_merge_srv_conf(ngx_conf_t *cf, void *parent, - void *child); -static ngx_int_t ngx_stream_realip_add_variables(ngx_conf_t *cf); -static ngx_int_t ngx_stream_realip_init(ngx_conf_t *cf); - - -static ngx_int_t ngx_stream_realip_remote_addr_variable(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data); -static ngx_int_t ngx_stream_realip_remote_port_variable(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data); - - -static ngx_command_t ngx_stream_realip_commands[] = { - - { ngx_string("set_real_ip_from"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, - ngx_stream_realip_from, - NGX_STREAM_SRV_CONF_OFFSET, - 0, - NULL }, - - ngx_null_command -}; - - -static ngx_stream_module_t ngx_stream_realip_module_ctx = { - ngx_stream_realip_add_variables, /* preconfiguration */ - ngx_stream_realip_init, /* postconfiguration */ - - NULL, /* create main configuration */ - NULL, /* init main configuration */ - - ngx_stream_realip_create_srv_conf, /* create server configuration */ - ngx_stream_realip_merge_srv_conf /* merge server configuration */ -}; - - -ngx_module_t ngx_stream_realip_module = { - NGX_MODULE_V1, - &ngx_stream_realip_module_ctx, /* module context */ - ngx_stream_realip_commands, /* module directives */ - NGX_STREAM_MODULE, /* module type */ - NULL, /* init master */ - NULL, /* init module */ - NULL, /* init process */ - NULL, /* init thread */ - NULL, /* exit thread */ - NULL, /* exit process */ - NULL, /* exit master */ - NGX_MODULE_V1_PADDING -}; - - -static ngx_stream_variable_t ngx_stream_realip_vars[] = { - - { ngx_string("realip_remote_addr"), NULL, - ngx_stream_realip_remote_addr_variable, 0, 0, 0 }, - - { ngx_string("realip_remote_port"), NULL, - ngx_stream_realip_remote_port_variable, 0, 0, 0 }, - - { ngx_null_string, NULL, NULL, 0, 0, 0 } -}; - - -static ngx_int_t -ngx_stream_realip_handler(ngx_stream_session_t *s) -{ - ngx_addr_t addr; - ngx_connection_t *c; - ngx_stream_realip_srv_conf_t *rscf; - - rscf = ngx_stream_get_module_srv_conf(s, ngx_stream_realip_module); - - if (rscf->from == NULL) { - return NGX_DECLINED; - } - - c = s->connection; - - if (c->proxy_protocol_addr.len == 0) { - return NGX_DECLINED; - } - - if (ngx_cidr_match(c->sockaddr, rscf->from) != NGX_OK) { - return NGX_DECLINED; - } - - if (ngx_parse_addr(c->pool, &addr, c->proxy_protocol_addr.data, - c->proxy_protocol_addr.len) - != NGX_OK) - { - return NGX_DECLINED; - } - - ngx_inet_set_port(addr.sockaddr, c->proxy_protocol_port); - - return ngx_stream_realip_set_addr(s, &addr); -} - - -static ngx_int_t -ngx_stream_realip_set_addr(ngx_stream_session_t *s, ngx_addr_t *addr) -{ - size_t len; - u_char *p; - u_char text[NGX_SOCKADDR_STRLEN]; - ngx_connection_t *c; - ngx_stream_realip_ctx_t *ctx; - - c = s->connection; - - ctx = ngx_palloc(c->pool, sizeof(ngx_stream_realip_ctx_t)); - if (ctx == NULL) { - return NGX_ERROR; - } - - len = ngx_sock_ntop(addr->sockaddr, addr->socklen, text, - NGX_SOCKADDR_STRLEN, 0); - if (len == 0) { - return NGX_ERROR; - } - - p = ngx_pnalloc(c->pool, len); - if (p == NULL) { - return NGX_ERROR; - } - - ngx_memcpy(p, text, len); - - ngx_stream_set_ctx(s, ctx, ngx_stream_realip_module); - - ctx->sockaddr = c->sockaddr; - ctx->socklen = c->socklen; - ctx->addr_text = c->addr_text; - - c->sockaddr = addr->sockaddr; - c->socklen = addr->socklen; - c->addr_text.len = len; - c->addr_text.data = p; - - return NGX_DECLINED; -} - - -static char * -ngx_stream_realip_from(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) -{ - ngx_stream_realip_srv_conf_t *rscf = conf; - - ngx_int_t rc; - ngx_str_t *value; - ngx_cidr_t *cidr; - - value = cf->args->elts; - - if (rscf->from == NULL) { - rscf->from = ngx_array_create(cf->pool, 2, - sizeof(ngx_cidr_t)); - if (rscf->from == NULL) { - return NGX_CONF_ERROR; - } - } - - cidr = ngx_array_push(rscf->from); - if (cidr == NULL) { - return NGX_CONF_ERROR; - } - -#if (NGX_HAVE_UNIX_DOMAIN) - - if (ngx_strcmp(value[1].data, "unix:") == 0) { - cidr->family = AF_UNIX; - return NGX_CONF_OK; - } - -#endif - - rc = ngx_ptocidr(&value[1], cidr); - - if (rc == NGX_ERROR) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"", - &value[1]); - return NGX_CONF_ERROR; - } - - if (rc == NGX_DONE) { - ngx_conf_log_error(NGX_LOG_WARN, cf, 0, - "low address bits of %V are meaningless", &value[1]); - } - - return NGX_CONF_OK; -} - - -static void * -ngx_stream_realip_create_srv_conf(ngx_conf_t *cf) -{ - ngx_stream_realip_srv_conf_t *conf; - - conf = ngx_pcalloc(cf->pool, sizeof(ngx_stream_realip_srv_conf_t)); - if (conf == NULL) { - return NULL; - } - - /* - * set by ngx_pcalloc(): - * - * conf->from = NULL; - */ - - return conf; -} - - -static char * -ngx_stream_realip_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) -{ - ngx_stream_realip_srv_conf_t *prev = parent; - ngx_stream_realip_srv_conf_t *conf = child; - - if (conf->from == NULL) { - conf->from = prev->from; - } - - return NGX_CONF_OK; -} - - -static ngx_int_t -ngx_stream_realip_add_variables(ngx_conf_t *cf) -{ - ngx_stream_variable_t *var, *v; - - for (v = ngx_stream_realip_vars; v->name.len; v++) { - var = ngx_stream_add_variable(cf, &v->name, v->flags); - if (var == NULL) { - return NGX_ERROR; - } - - var->get_handler = v->get_handler; - var->data = v->data; - } - - return NGX_OK; -} - - -static ngx_int_t -ngx_stream_realip_init(ngx_conf_t *cf) -{ - ngx_stream_handler_pt *h; - ngx_stream_core_main_conf_t *cmcf; - - cmcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_core_module); - - h = ngx_array_push(&cmcf->phases[NGX_STREAM_POST_ACCEPT_PHASE].handlers); - if (h == NULL) { - return NGX_ERROR; - } - - *h = ngx_stream_realip_handler; - - return NGX_OK; -} - - -static ngx_int_t -ngx_stream_realip_remote_addr_variable(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data) -{ - ngx_str_t *addr_text; - ngx_stream_realip_ctx_t *ctx; - - ctx = ngx_stream_get_module_ctx(s, ngx_stream_realip_module); - - addr_text = ctx ? &ctx->addr_text : &s->connection->addr_text; - - v->len = addr_text->len; - v->valid = 1; - v->no_cacheable = 0; - v->not_found = 0; - v->data = addr_text->data; - - return NGX_OK; -} - - -static ngx_int_t -ngx_stream_realip_remote_port_variable(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data) -{ - ngx_uint_t port; - struct sockaddr *sa; - ngx_stream_realip_ctx_t *ctx; - - ctx = ngx_stream_get_module_ctx(s, ngx_stream_realip_module); - - sa = ctx ? ctx->sockaddr : s->connection->sockaddr; - - v->len = 0; - v->valid = 1; - v->no_cacheable = 0; - v->not_found = 0; - - v->data = ngx_pnalloc(s->connection->pool, sizeof("65535") - 1); - if (v->data == NULL) { - return NGX_ERROR; - } - - port = ngx_inet_get_port(sa); - - if (port > 0 && port < 65536) { - v->len = ngx_sprintf(v->data, "%ui", port) - v->data; - } - - return NGX_OK; -} diff --git a/app/nginx/src/stream/ngx_stream_return_module.c b/app/nginx/src/stream/ngx_stream_return_module.c deleted file mode 100644 index 9301b02..0000000 --- a/app/nginx/src/stream/ngx_stream_return_module.c +++ /dev/null @@ -1,218 +0,0 @@ - -/* - * Copyright (C) Roman Arutyunyan - * Copyright (C) Nginx, Inc. - */ - - -#include <ngx_config.h> -#include <ngx_core.h> -#include <ngx_stream.h> - - -typedef struct { - ngx_stream_complex_value_t text; -} ngx_stream_return_srv_conf_t; - - -typedef struct { - ngx_chain_t *out; -} ngx_stream_return_ctx_t; - - -static void ngx_stream_return_handler(ngx_stream_session_t *s); -static void ngx_stream_return_write_handler(ngx_event_t *ev); - -static void *ngx_stream_return_create_srv_conf(ngx_conf_t *cf); -static char *ngx_stream_return(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); - - -static ngx_command_t ngx_stream_return_commands[] = { - - { ngx_string("return"), - NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, - ngx_stream_return, - NGX_STREAM_SRV_CONF_OFFSET, - 0, - NULL }, - - ngx_null_command -}; - - -static ngx_stream_module_t ngx_stream_return_module_ctx = { - NULL, /* preconfiguration */ - NULL, /* postconfiguration */ - - NULL, /* create main configuration */ - NULL, /* init main configuration */ - - ngx_stream_return_create_srv_conf, /* create server configuration */ - NULL /* merge server configuration */ -}; - - -ngx_module_t ngx_stream_return_module = { - NGX_MODULE_V1, - &ngx_stream_return_module_ctx, /* module context */ - ngx_stream_return_commands, /* module directives */ - NGX_STREAM_MODULE, /* module type */ - NULL, /* init master */ - NULL, /* init module */ - NULL, /* init process */ - NULL, /* init thread */ - NULL, /* exit thread */ - NULL, /* exit process */ - NULL, /* exit master */ - NGX_MODULE_V1_PADDING -}; - - -static void -ngx_stream_return_handler(ngx_stream_session_t *s) -{ - ngx_str_t text; - ngx_buf_t *b; - ngx_connection_t *c; - ngx_stream_return_ctx_t *ctx; - ngx_stream_return_srv_conf_t *rscf; - - c = s->connection; - - c->log->action = "returning text"; - - rscf = ngx_stream_get_module_srv_conf(s, ngx_stream_return_module); - - if (ngx_stream_complex_value(s, &rscf->text, &text) != NGX_OK) { - ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR); - return; - } - - ngx_log_debug1(NGX_LOG_DEBUG_STREAM, c->log, 0, - "stream return text: \"%V\"", &text); - - if (text.len == 0) { - ngx_stream_finalize_session(s, NGX_STREAM_OK); - return; - } - - ctx = ngx_pcalloc(c->pool, sizeof(ngx_stream_return_ctx_t)); - if (ctx == NULL) { - ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR); - return; - } - - ngx_stream_set_ctx(s, ctx, ngx_stream_return_module); - - b = ngx_calloc_buf(c->pool); - if (b == NULL) { - ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR); - return; - } - - b->memory = 1; - b->pos = text.data; - b->last = text.data + text.len; - b->last_buf = 1; - - ctx->out = ngx_alloc_chain_link(c->pool); - if (ctx->out == NULL) { - ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR); - return; - } - - ctx->out->buf = b; - ctx->out->next = NULL; - - c->write->handler = ngx_stream_return_write_handler; - - ngx_stream_return_write_handler(c->write); -} - - -static void -ngx_stream_return_write_handler(ngx_event_t *ev) -{ - ngx_connection_t *c; - ngx_stream_session_t *s; - ngx_stream_return_ctx_t *ctx; - - c = ev->data; - s = c->data; - - if (ev->timedout) { - ngx_connection_error(c, NGX_ETIMEDOUT, "connection timed out"); - ngx_stream_finalize_session(s, NGX_STREAM_OK); - return; - } - - ctx = ngx_stream_get_module_ctx(s, ngx_stream_return_module); - - if (ngx_stream_top_filter(s, ctx->out, 1) == NGX_ERROR) { - ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR); - return; - } - - ctx->out = NULL; - - if (!c->buffered) { - ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0, - "stream return done sending"); - ngx_stream_finalize_session(s, NGX_STREAM_OK); - return; - } - - if (ngx_handle_write_event(ev, 0) != NGX_OK) { - ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR); - return; - } - - ngx_add_timer(ev, 5000); -} - - -static void * -ngx_stream_return_create_srv_conf(ngx_conf_t *cf) -{ - ngx_stream_return_srv_conf_t *conf; - - conf = ngx_pcalloc(cf->pool, sizeof(ngx_stream_return_srv_conf_t)); - if (conf == NULL) { - return NULL; - } - - return conf; -} - - -static char * -ngx_stream_return(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) -{ - ngx_stream_return_srv_conf_t *rscf = conf; - - ngx_str_t *value; - ngx_stream_core_srv_conf_t *cscf; - ngx_stream_compile_complex_value_t ccv; - - if (rscf->text.value.data) { - return "is duplicate"; - } - - value = cf->args->elts; - - ngx_memzero(&ccv, sizeof(ngx_stream_compile_complex_value_t)); - - ccv.cf = cf; - ccv.value = &value[1]; - ccv.complex_value = &rscf->text; - - if (ngx_stream_compile_complex_value(&ccv) != NGX_OK) { - return NGX_CONF_ERROR; - } - - cscf = ngx_stream_conf_get_module_srv_conf(cf, ngx_stream_core_module); - - cscf->handler = ngx_stream_return_handler; - - return NGX_CONF_OK; -} diff --git a/app/nginx/src/stream/ngx_stream_script.c b/app/nginx/src/stream/ngx_stream_script.c deleted file mode 100644 index aa555ca..0000000 --- a/app/nginx/src/stream/ngx_stream_script.c +++ /dev/null @@ -1,921 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) Nginx, Inc. - */ - - -#include <ngx_config.h> -#include <ngx_core.h> -#include <ngx_stream.h> - - -static ngx_int_t ngx_stream_script_init_arrays( - ngx_stream_script_compile_t *sc); -static ngx_int_t ngx_stream_script_done(ngx_stream_script_compile_t *sc); -static ngx_int_t ngx_stream_script_add_copy_code( - ngx_stream_script_compile_t *sc, ngx_str_t *value, ngx_uint_t last); -static ngx_int_t ngx_stream_script_add_var_code( - ngx_stream_script_compile_t *sc, ngx_str_t *name); -#if (NGX_PCRE) -static ngx_int_t ngx_stream_script_add_capture_code( - ngx_stream_script_compile_t *sc, ngx_uint_t n); -#endif -static ngx_int_t ngx_stream_script_add_full_name_code( - ngx_stream_script_compile_t *sc); -static size_t ngx_stream_script_full_name_len_code( - ngx_stream_script_engine_t *e); -static void ngx_stream_script_full_name_code(ngx_stream_script_engine_t *e); - - -#define ngx_stream_script_exit (u_char *) &ngx_stream_script_exit_code - -static uintptr_t ngx_stream_script_exit_code = (uintptr_t) NULL; - - -void -ngx_stream_script_flush_complex_value(ngx_stream_session_t *s, - ngx_stream_complex_value_t *val) -{ - ngx_uint_t *index; - - index = val->flushes; - - if (index) { - while (*index != (ngx_uint_t) -1) { - - if (s->variables[*index].no_cacheable) { - s->variables[*index].valid = 0; - s->variables[*index].not_found = 0; - } - - index++; - } - } -} - - -ngx_int_t -ngx_stream_complex_value(ngx_stream_session_t *s, - ngx_stream_complex_value_t *val, ngx_str_t *value) -{ - size_t len; - ngx_stream_script_code_pt code; - ngx_stream_script_engine_t e; - ngx_stream_script_len_code_pt lcode; - - if (val->lengths == NULL) { - *value = val->value; - return NGX_OK; - } - - ngx_stream_script_flush_complex_value(s, val); - - ngx_memzero(&e, sizeof(ngx_stream_script_engine_t)); - - e.ip = val->lengths; - e.session = s; - e.flushed = 1; - - len = 0; - - while (*(uintptr_t *) e.ip) { - lcode = *(ngx_stream_script_len_code_pt *) e.ip; - len += lcode(&e); - } - - value->len = len; - value->data = ngx_pnalloc(s->connection->pool, len); - if (value->data == NULL) { - return NGX_ERROR; - } - - e.ip = val->values; - e.pos = value->data; - e.buf = *value; - - while (*(uintptr_t *) e.ip) { - code = *(ngx_stream_script_code_pt *) e.ip; - code((ngx_stream_script_engine_t *) &e); - } - - *value = e.buf; - - return NGX_OK; -} - - -ngx_int_t -ngx_stream_compile_complex_value(ngx_stream_compile_complex_value_t *ccv) -{ - ngx_str_t *v; - ngx_uint_t i, n, nv, nc; - ngx_array_t flushes, lengths, values, *pf, *pl, *pv; - ngx_stream_script_compile_t sc; - - v = ccv->value; - - nv = 0; - nc = 0; - - for (i = 0; i < v->len; i++) { - if (v->data[i] == '$') { - if (v->data[i + 1] >= '1' && v->data[i + 1] <= '9') { - nc++; - - } else { - nv++; - } - } - } - - if ((v->len == 0 || v->data[0] != '$') - && (ccv->conf_prefix || ccv->root_prefix)) - { - if (ngx_conf_full_name(ccv->cf->cycle, v, ccv->conf_prefix) != NGX_OK) { - return NGX_ERROR; - } - - ccv->conf_prefix = 0; - ccv->root_prefix = 0; - } - - ccv->complex_value->value = *v; - ccv->complex_value->flushes = NULL; - ccv->complex_value->lengths = NULL; - ccv->complex_value->values = NULL; - - if (nv == 0 && nc == 0) { - return NGX_OK; - } - - n = nv + 1; - - if (ngx_array_init(&flushes, ccv->cf->pool, n, sizeof(ngx_uint_t)) - != NGX_OK) - { - return NGX_ERROR; - } - - n = nv * (2 * sizeof(ngx_stream_script_copy_code_t) - + sizeof(ngx_stream_script_var_code_t)) - + sizeof(uintptr_t); - - if (ngx_array_init(&lengths, ccv->cf->pool, n, 1) != NGX_OK) { - return NGX_ERROR; - } - - n = (nv * (2 * sizeof(ngx_stream_script_copy_code_t) - + sizeof(ngx_stream_script_var_code_t)) - + sizeof(uintptr_t) - + v->len - + sizeof(uintptr_t) - 1) - & ~(sizeof(uintptr_t) - 1); - - if (ngx_array_init(&values, ccv->cf->pool, n, 1) != NGX_OK) { - return NGX_ERROR; - } - - pf = &flushes; - pl = &lengths; - pv = &values; - - ngx_memzero(&sc, sizeof(ngx_stream_script_compile_t)); - - sc.cf = ccv->cf; - sc.source = v; - sc.flushes = &pf; - sc.lengths = &pl; - sc.values = &pv; - sc.complete_lengths = 1; - sc.complete_values = 1; - sc.zero = ccv->zero; - sc.conf_prefix = ccv->conf_prefix; - sc.root_prefix = ccv->root_prefix; - - if (ngx_stream_script_compile(&sc) != NGX_OK) { - return NGX_ERROR; - } - - if (flushes.nelts) { - ccv->complex_value->flushes = flushes.elts; - ccv->complex_value->flushes[flushes.nelts] = (ngx_uint_t) -1; - } - - ccv->complex_value->lengths = lengths.elts; - ccv->complex_value->values = values.elts; - - return NGX_OK; -} - - -char * -ngx_stream_set_complex_value_slot(ngx_conf_t *cf, ngx_command_t *cmd, - void *conf) -{ - char *p = conf; - - ngx_str_t *value; - ngx_stream_complex_value_t **cv; - ngx_stream_compile_complex_value_t ccv; - - cv = (ngx_stream_complex_value_t **) (p + cmd->offset); - - if (*cv != NULL) { - return "is duplicate"; - } - - *cv = ngx_palloc(cf->pool, sizeof(ngx_stream_complex_value_t)); - if (*cv == NULL) { - return NGX_CONF_ERROR; - } - - value = cf->args->elts; - - ngx_memzero(&ccv, sizeof(ngx_stream_compile_complex_value_t)); - - ccv.cf = cf; - ccv.value = &value[1]; - ccv.complex_value = *cv; - - if (ngx_stream_compile_complex_value(&ccv) != NGX_OK) { - return NGX_CONF_ERROR; - } - - return NGX_CONF_OK; -} - - -ngx_uint_t -ngx_stream_script_variables_count(ngx_str_t *value) -{ - ngx_uint_t i, n; - - for (n = 0, i = 0; i < value->len; i++) { - if (value->data[i] == '$') { - n++; - } - } - - return n; -} - - -ngx_int_t -ngx_stream_script_compile(ngx_stream_script_compile_t *sc) -{ - u_char ch; - ngx_str_t name; - ngx_uint_t i, bracket; - - if (ngx_stream_script_init_arrays(sc) != NGX_OK) { - return NGX_ERROR; - } - - for (i = 0; i < sc->source->len; /* void */ ) { - - name.len = 0; - - if (sc->source->data[i] == '$') { - - if (++i == sc->source->len) { - goto invalid_variable; - } - - if (sc->source->data[i] >= '1' && sc->source->data[i] <= '9') { -#if (NGX_PCRE) - ngx_uint_t n; - - n = sc->source->data[i] - '0'; - - if (ngx_stream_script_add_capture_code(sc, n) != NGX_OK) { - return NGX_ERROR; - } - - i++; - - continue; -#else - ngx_conf_log_error(NGX_LOG_EMERG, sc->cf, 0, - "using variable \"$%c\" requires " - "PCRE library", sc->source->data[i]); - return NGX_ERROR; -#endif - } - - if (sc->source->data[i] == '{') { - bracket = 1; - - if (++i == sc->source->len) { - goto invalid_variable; - } - - name.data = &sc->source->data[i]; - - } else { - bracket = 0; - name.data = &sc->source->data[i]; - } - - for ( /* void */ ; i < sc->source->len; i++, name.len++) { - ch = sc->source->data[i]; - - if (ch == '}' && bracket) { - i++; - bracket = 0; - break; - } - - if ((ch >= 'A' && ch <= 'Z') - || (ch >= 'a' && ch <= 'z') - || (ch >= '0' && ch <= '9') - || ch == '_') - { - continue; - } - - break; - } - - if (bracket) { - ngx_conf_log_error(NGX_LOG_EMERG, sc->cf, 0, - "the closing bracket in \"%V\" " - "variable is missing", &name); - return NGX_ERROR; - } - - if (name.len == 0) { - goto invalid_variable; - } - - sc->variables++; - - if (ngx_stream_script_add_var_code(sc, &name) != NGX_OK) { - return NGX_ERROR; - } - - continue; - } - - name.data = &sc->source->data[i]; - - while (i < sc->source->len) { - - if (sc->source->data[i] == '$') { - break; - } - - i++; - name.len++; - } - - sc->size += name.len; - - if (ngx_stream_script_add_copy_code(sc, &name, (i == sc->source->len)) - != NGX_OK) - { - return NGX_ERROR; - } - } - - return ngx_stream_script_done(sc); - -invalid_variable: - - ngx_conf_log_error(NGX_LOG_EMERG, sc->cf, 0, "invalid variable name"); - - return NGX_ERROR; -} - - -u_char * -ngx_stream_script_run(ngx_stream_session_t *s, ngx_str_t *value, - void *code_lengths, size_t len, void *code_values) -{ - ngx_uint_t i; - ngx_stream_script_code_pt code; - ngx_stream_script_engine_t e; - ngx_stream_core_main_conf_t *cmcf; - ngx_stream_script_len_code_pt lcode; - - cmcf = ngx_stream_get_module_main_conf(s, ngx_stream_core_module); - - for (i = 0; i < cmcf->variables.nelts; i++) { - if (s->variables[i].no_cacheable) { - s->variables[i].valid = 0; - s->variables[i].not_found = 0; - } - } - - ngx_memzero(&e, sizeof(ngx_stream_script_engine_t)); - - e.ip = code_lengths; - e.session = s; - e.flushed = 1; - - while (*(uintptr_t *) e.ip) { - lcode = *(ngx_stream_script_len_code_pt *) e.ip; - len += lcode(&e); - } - - - value->len = len; - value->data = ngx_pnalloc(s->connection->pool, len); - if (value->data == NULL) { - return NULL; - } - - e.ip = code_values; - e.pos = value->data; - - while (*(uintptr_t *) e.ip) { - code = *(ngx_stream_script_code_pt *) e.ip; - code((ngx_stream_script_engine_t *) &e); - } - - return e.pos; -} - - -void -ngx_stream_script_flush_no_cacheable_variables(ngx_stream_session_t *s, - ngx_array_t *indices) -{ - ngx_uint_t n, *index; - - if (indices) { - index = indices->elts; - for (n = 0; n < indices->nelts; n++) { - if (s->variables[index[n]].no_cacheable) { - s->variables[index[n]].valid = 0; - s->variables[index[n]].not_found = 0; - } - } - } -} - - -static ngx_int_t -ngx_stream_script_init_arrays(ngx_stream_script_compile_t *sc) -{ - ngx_uint_t n; - - if (sc->flushes && *sc->flushes == NULL) { - n = sc->variables ? sc->variables : 1; - *sc->flushes = ngx_array_create(sc->cf->pool, n, sizeof(ngx_uint_t)); - if (*sc->flushes == NULL) { - return NGX_ERROR; - } - } - - if (*sc->lengths == NULL) { - n = sc->variables * (2 * sizeof(ngx_stream_script_copy_code_t) - + sizeof(ngx_stream_script_var_code_t)) - + sizeof(uintptr_t); - - *sc->lengths = ngx_array_create(sc->cf->pool, n, 1); - if (*sc->lengths == NULL) { - return NGX_ERROR; - } - } - - if (*sc->values == NULL) { - n = (sc->variables * (2 * sizeof(ngx_stream_script_copy_code_t) - + sizeof(ngx_stream_script_var_code_t)) - + sizeof(uintptr_t) - + sc->source->len - + sizeof(uintptr_t) - 1) - & ~(sizeof(uintptr_t) - 1); - - *sc->values = ngx_array_create(sc->cf->pool, n, 1); - if (*sc->values == NULL) { - return NGX_ERROR; - } - } - - sc->variables = 0; - - return NGX_OK; -} - - -static ngx_int_t -ngx_stream_script_done(ngx_stream_script_compile_t *sc) -{ - ngx_str_t zero; - uintptr_t *code; - - if (sc->zero) { - - zero.len = 1; - zero.data = (u_char *) "\0"; - - if (ngx_stream_script_add_copy_code(sc, &zero, 0) != NGX_OK) { - return NGX_ERROR; - } - } - - if (sc->conf_prefix || sc->root_prefix) { - if (ngx_stream_script_add_full_name_code(sc) != NGX_OK) { - return NGX_ERROR; - } - } - - if (sc->complete_lengths) { - code = ngx_stream_script_add_code(*sc->lengths, sizeof(uintptr_t), - NULL); - if (code == NULL) { - return NGX_ERROR; - } - - *code = (uintptr_t) NULL; - } - - if (sc->complete_values) { - code = ngx_stream_script_add_code(*sc->values, sizeof(uintptr_t), - &sc->main); - if (code == NULL) { - return NGX_ERROR; - } - - *code = (uintptr_t) NULL; - } - - return NGX_OK; -} - - -void * -ngx_stream_script_add_code(ngx_array_t *codes, size_t size, void *code) -{ - u_char *elts, **p; - void *new; - - elts = codes->elts; - - new = ngx_array_push_n(codes, size); - if (new == NULL) { - return NULL; - } - - if (code) { - if (elts != codes->elts) { - p = code; - *p += (u_char *) codes->elts - elts; - } - } - - return new; -} - - -static ngx_int_t -ngx_stream_script_add_copy_code(ngx_stream_script_compile_t *sc, - ngx_str_t *value, ngx_uint_t last) -{ - u_char *p; - size_t size, len, zero; - ngx_stream_script_copy_code_t *code; - - zero = (sc->zero && last); - len = value->len + zero; - - code = ngx_stream_script_add_code(*sc->lengths, - sizeof(ngx_stream_script_copy_code_t), - NULL); - if (code == NULL) { - return NGX_ERROR; - } - - code->code = (ngx_stream_script_code_pt) ngx_stream_script_copy_len_code; - code->len = len; - - size = (sizeof(ngx_stream_script_copy_code_t) + len + sizeof(uintptr_t) - 1) - & ~(sizeof(uintptr_t) - 1); - - code = ngx_stream_script_add_code(*sc->values, size, &sc->main); - if (code == NULL) { - return NGX_ERROR; - } - - code->code = ngx_stream_script_copy_code; - code->len = len; - - p = ngx_cpymem((u_char *) code + sizeof(ngx_stream_script_copy_code_t), - value->data, value->len); - - if (zero) { - *p = '\0'; - sc->zero = 0; - } - - return NGX_OK; -} - - -size_t -ngx_stream_script_copy_len_code(ngx_stream_script_engine_t *e) -{ - ngx_stream_script_copy_code_t *code; - - code = (ngx_stream_script_copy_code_t *) e->ip; - - e->ip += sizeof(ngx_stream_script_copy_code_t); - - return code->len; -} - - -void -ngx_stream_script_copy_code(ngx_stream_script_engine_t *e) -{ - u_char *p; - ngx_stream_script_copy_code_t *code; - - code = (ngx_stream_script_copy_code_t *) e->ip; - - p = e->pos; - - if (!e->skip) { - e->pos = ngx_copy(p, e->ip + sizeof(ngx_stream_script_copy_code_t), - code->len); - } - - e->ip += sizeof(ngx_stream_script_copy_code_t) - + ((code->len + sizeof(uintptr_t) - 1) & ~(sizeof(uintptr_t) - 1)); - - ngx_log_debug2(NGX_LOG_DEBUG_STREAM, e->session->connection->log, 0, - "stream script copy: \"%*s\"", e->pos - p, p); -} - - -static ngx_int_t -ngx_stream_script_add_var_code(ngx_stream_script_compile_t *sc, ngx_str_t *name) -{ - ngx_int_t index, *p; - ngx_stream_script_var_code_t *code; - - index = ngx_stream_get_variable_index(sc->cf, name); - - if (index == NGX_ERROR) { - return NGX_ERROR; - } - - if (sc->flushes) { - p = ngx_array_push(*sc->flushes); - if (p == NULL) { - return NGX_ERROR; - } - - *p = index; - } - - code = ngx_stream_script_add_code(*sc->lengths, - sizeof(ngx_stream_script_var_code_t), - NULL); - if (code == NULL) { - return NGX_ERROR; - } - - code->code = (ngx_stream_script_code_pt) - ngx_stream_script_copy_var_len_code; - code->index = (uintptr_t) index; - - code = ngx_stream_script_add_code(*sc->values, - sizeof(ngx_stream_script_var_code_t), - &sc->main); - if (code == NULL) { - return NGX_ERROR; - } - - code->code = ngx_stream_script_copy_var_code; - code->index = (uintptr_t) index; - - return NGX_OK; -} - - -size_t -ngx_stream_script_copy_var_len_code(ngx_stream_script_engine_t *e) -{ - ngx_stream_variable_value_t *value; - ngx_stream_script_var_code_t *code; - - code = (ngx_stream_script_var_code_t *) e->ip; - - e->ip += sizeof(ngx_stream_script_var_code_t); - - if (e->flushed) { - value = ngx_stream_get_indexed_variable(e->session, code->index); - - } else { - value = ngx_stream_get_flushed_variable(e->session, code->index); - } - - if (value && !value->not_found) { - return value->len; - } - - return 0; -} - - -void -ngx_stream_script_copy_var_code(ngx_stream_script_engine_t *e) -{ - u_char *p; - ngx_stream_variable_value_t *value; - ngx_stream_script_var_code_t *code; - - code = (ngx_stream_script_var_code_t *) e->ip; - - e->ip += sizeof(ngx_stream_script_var_code_t); - - if (!e->skip) { - - if (e->flushed) { - value = ngx_stream_get_indexed_variable(e->session, code->index); - - } else { - value = ngx_stream_get_flushed_variable(e->session, code->index); - } - - if (value && !value->not_found) { - p = e->pos; - e->pos = ngx_copy(p, value->data, value->len); - - ngx_log_debug2(NGX_LOG_DEBUG_STREAM, - e->session->connection->log, 0, - "stream script var: \"%*s\"", e->pos - p, p); - } - } -} - - -#if (NGX_PCRE) - -static ngx_int_t -ngx_stream_script_add_capture_code(ngx_stream_script_compile_t *sc, - ngx_uint_t n) -{ - ngx_stream_script_copy_capture_code_t *code; - - code = ngx_stream_script_add_code(*sc->lengths, - sizeof(ngx_stream_script_copy_capture_code_t), - NULL); - if (code == NULL) { - return NGX_ERROR; - } - - code->code = (ngx_stream_script_code_pt) - ngx_stream_script_copy_capture_len_code; - code->n = 2 * n; - - - code = ngx_stream_script_add_code(*sc->values, - sizeof(ngx_stream_script_copy_capture_code_t), - &sc->main); - if (code == NULL) { - return NGX_ERROR; - } - - code->code = ngx_stream_script_copy_capture_code; - code->n = 2 * n; - - if (sc->ncaptures < n) { - sc->ncaptures = n; - } - - return NGX_OK; -} - - -size_t -ngx_stream_script_copy_capture_len_code(ngx_stream_script_engine_t *e) -{ - int *cap; - ngx_uint_t n; - ngx_stream_session_t *s; - ngx_stream_script_copy_capture_code_t *code; - - s = e->session; - - code = (ngx_stream_script_copy_capture_code_t *) e->ip; - - e->ip += sizeof(ngx_stream_script_copy_capture_code_t); - - n = code->n; - - if (n < s->ncaptures) { - cap = s->captures; - return cap[n + 1] - cap[n]; - } - - return 0; -} - - -void -ngx_stream_script_copy_capture_code(ngx_stream_script_engine_t *e) -{ - int *cap; - u_char *p, *pos; - ngx_uint_t n; - ngx_stream_session_t *s; - ngx_stream_script_copy_capture_code_t *code; - - s = e->session; - - code = (ngx_stream_script_copy_capture_code_t *) e->ip; - - e->ip += sizeof(ngx_stream_script_copy_capture_code_t); - - n = code->n; - - pos = e->pos; - - if (n < s->ncaptures) { - cap = s->captures; - p = s->captures_data; - e->pos = ngx_copy(pos, &p[cap[n]], cap[n + 1] - cap[n]); - } - - ngx_log_debug2(NGX_LOG_DEBUG_STREAM, e->session->connection->log, 0, - "stream script capture: \"%*s\"", e->pos - pos, pos); -} - -#endif - - -static ngx_int_t -ngx_stream_script_add_full_name_code(ngx_stream_script_compile_t *sc) -{ - ngx_stream_script_full_name_code_t *code; - - code = ngx_stream_script_add_code(*sc->lengths, - sizeof(ngx_stream_script_full_name_code_t), - NULL); - if (code == NULL) { - return NGX_ERROR; - } - - code->code = (ngx_stream_script_code_pt) - ngx_stream_script_full_name_len_code; - code->conf_prefix = sc->conf_prefix; - - code = ngx_stream_script_add_code(*sc->values, - sizeof(ngx_stream_script_full_name_code_t), &sc->main); - if (code == NULL) { - return NGX_ERROR; - } - - code->code = ngx_stream_script_full_name_code; - code->conf_prefix = sc->conf_prefix; - - return NGX_OK; -} - - -static size_t -ngx_stream_script_full_name_len_code(ngx_stream_script_engine_t *e) -{ - ngx_stream_script_full_name_code_t *code; - - code = (ngx_stream_script_full_name_code_t *) e->ip; - - e->ip += sizeof(ngx_stream_script_full_name_code_t); - - return code->conf_prefix ? ngx_cycle->conf_prefix.len: - ngx_cycle->prefix.len; -} - - -static void -ngx_stream_script_full_name_code(ngx_stream_script_engine_t *e) -{ - ngx_stream_script_full_name_code_t *code; - - ngx_str_t value, *prefix; - - code = (ngx_stream_script_full_name_code_t *) e->ip; - - value.data = e->buf.data; - value.len = e->pos - e->buf.data; - - prefix = code->conf_prefix ? (ngx_str_t *) &ngx_cycle->conf_prefix: - (ngx_str_t *) &ngx_cycle->prefix; - - if (ngx_get_full_name(e->session->connection->pool, prefix, &value) - != NGX_OK) - { - e->ip = ngx_stream_script_exit; - return; - } - - e->buf = value; - - ngx_log_debug1(NGX_LOG_DEBUG_STREAM, e->session->connection->log, 0, - "stream script fullname: \"%V\"", &value); - - e->ip += sizeof(ngx_stream_script_full_name_code_t); -} diff --git a/app/nginx/src/stream/ngx_stream_script.h b/app/nginx/src/stream/ngx_stream_script.h deleted file mode 100644 index 25a450d..0000000 --- a/app/nginx/src/stream/ngx_stream_script.h +++ /dev/null @@ -1,127 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) Nginx, Inc. - */ - - -#ifndef _NGX_STREAM_SCRIPT_H_INCLUDED_ -#define _NGX_STREAM_SCRIPT_H_INCLUDED_ - - -#include <ngx_config.h> -#include <ngx_core.h> -#include <ngx_stream.h> - - -typedef struct { - u_char *ip; - u_char *pos; - ngx_stream_variable_value_t *sp; - - ngx_str_t buf; - ngx_str_t line; - - unsigned flushed:1; - unsigned skip:1; - - ngx_stream_session_t *session; -} ngx_stream_script_engine_t; - - -typedef struct { - ngx_conf_t *cf; - ngx_str_t *source; - - ngx_array_t **flushes; - ngx_array_t **lengths; - ngx_array_t **values; - - ngx_uint_t variables; - ngx_uint_t ncaptures; - ngx_uint_t size; - - void *main; - - unsigned complete_lengths:1; - unsigned complete_values:1; - unsigned zero:1; - unsigned conf_prefix:1; - unsigned root_prefix:1; -} ngx_stream_script_compile_t; - - -typedef struct { - ngx_str_t value; - ngx_uint_t *flushes; - void *lengths; - void *values; -} ngx_stream_complex_value_t; - - -typedef struct { - ngx_conf_t *cf; - ngx_str_t *value; - ngx_stream_complex_value_t *complex_value; - - unsigned zero:1; - unsigned conf_prefix:1; - unsigned root_prefix:1; -} ngx_stream_compile_complex_value_t; - - -typedef void (*ngx_stream_script_code_pt) (ngx_stream_script_engine_t *e); -typedef size_t (*ngx_stream_script_len_code_pt) (ngx_stream_script_engine_t *e); - - -typedef struct { - ngx_stream_script_code_pt code; - uintptr_t len; -} ngx_stream_script_copy_code_t; - - -typedef struct { - ngx_stream_script_code_pt code; - uintptr_t index; -} ngx_stream_script_var_code_t; - - -typedef struct { - ngx_stream_script_code_pt code; - uintptr_t n; -} ngx_stream_script_copy_capture_code_t; - - -typedef struct { - ngx_stream_script_code_pt code; - uintptr_t conf_prefix; -} ngx_stream_script_full_name_code_t; - - -void ngx_stream_script_flush_complex_value(ngx_stream_session_t *s, - ngx_stream_complex_value_t *val); -ngx_int_t ngx_stream_complex_value(ngx_stream_session_t *s, - ngx_stream_complex_value_t *val, ngx_str_t *value); -ngx_int_t ngx_stream_compile_complex_value( - ngx_stream_compile_complex_value_t *ccv); -char *ngx_stream_set_complex_value_slot(ngx_conf_t *cf, ngx_command_t *cmd, - void *conf); - - -ngx_uint_t ngx_stream_script_variables_count(ngx_str_t *value); -ngx_int_t ngx_stream_script_compile(ngx_stream_script_compile_t *sc); -u_char *ngx_stream_script_run(ngx_stream_session_t *s, ngx_str_t *value, - void *code_lengths, size_t reserved, void *code_values); -void ngx_stream_script_flush_no_cacheable_variables(ngx_stream_session_t *s, - ngx_array_t *indices); - -void *ngx_stream_script_add_code(ngx_array_t *codes, size_t size, void *code); - -size_t ngx_stream_script_copy_len_code(ngx_stream_script_engine_t *e); -void ngx_stream_script_copy_code(ngx_stream_script_engine_t *e); -size_t ngx_stream_script_copy_var_len_code(ngx_stream_script_engine_t *e); -void ngx_stream_script_copy_var_code(ngx_stream_script_engine_t *e); -size_t ngx_stream_script_copy_capture_len_code(ngx_stream_script_engine_t *e); -void ngx_stream_script_copy_capture_code(ngx_stream_script_engine_t *e); - -#endif /* _NGX_STREAM_SCRIPT_H_INCLUDED_ */ diff --git a/app/nginx/src/stream/ngx_stream_split_clients_module.c b/app/nginx/src/stream/ngx_stream_split_clients_module.c deleted file mode 100644 index af6c8a1..0000000 --- a/app/nginx/src/stream/ngx_stream_split_clients_module.c +++ /dev/null @@ -1,244 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) Nginx, Inc. - */ - - -#include <ngx_config.h> -#include <ngx_core.h> -#include <ngx_stream.h> - - -typedef struct { - uint32_t percent; - ngx_stream_variable_value_t value; -} ngx_stream_split_clients_part_t; - - -typedef struct { - ngx_stream_complex_value_t value; - ngx_array_t parts; -} ngx_stream_split_clients_ctx_t; - - -static char *ngx_conf_split_clients_block(ngx_conf_t *cf, ngx_command_t *cmd, - void *conf); -static char *ngx_stream_split_clients(ngx_conf_t *cf, ngx_command_t *dummy, - void *conf); - -static ngx_command_t ngx_stream_split_clients_commands[] = { - - { ngx_string("split_clients"), - NGX_STREAM_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE2, - ngx_conf_split_clients_block, - NGX_STREAM_MAIN_CONF_OFFSET, - 0, - NULL }, - - ngx_null_command -}; - - -static ngx_stream_module_t ngx_stream_split_clients_module_ctx = { - NULL, /* preconfiguration */ - NULL, /* postconfiguration */ - - NULL, /* create main configuration */ - NULL, /* init main configuration */ - - NULL, /* create server configuration */ - NULL /* merge server configuration */ -}; - - -ngx_module_t ngx_stream_split_clients_module = { - NGX_MODULE_V1, - &ngx_stream_split_clients_module_ctx, /* module context */ - ngx_stream_split_clients_commands, /* module directives */ - NGX_STREAM_MODULE, /* module type */ - NULL, /* init master */ - NULL, /* init module */ - NULL, /* init process */ - NULL, /* init thread */ - NULL, /* exit thread */ - NULL, /* exit process */ - NULL, /* exit master */ - NGX_MODULE_V1_PADDING -}; - - -static ngx_int_t -ngx_stream_split_clients_variable(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data) -{ - ngx_stream_split_clients_ctx_t *ctx = - (ngx_stream_split_clients_ctx_t *) data; - - uint32_t hash; - ngx_str_t val; - ngx_uint_t i; - ngx_stream_split_clients_part_t *part; - - *v = ngx_stream_variable_null_value; - - if (ngx_stream_complex_value(s, &ctx->value, &val) != NGX_OK) { - return NGX_OK; - } - - hash = ngx_murmur_hash2(val.data, val.len); - - part = ctx->parts.elts; - - for (i = 0; i < ctx->parts.nelts; i++) { - - ngx_log_debug2(NGX_LOG_DEBUG_STREAM, s->connection->log, 0, - "stream split: %uD %uD", hash, part[i].percent); - - if (hash < part[i].percent || part[i].percent == 0) { - *v = part[i].value; - return NGX_OK; - } - } - - return NGX_OK; -} - - -static char * -ngx_conf_split_clients_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) -{ - char *rv; - uint32_t sum, last; - ngx_str_t *value, name; - ngx_uint_t i; - ngx_conf_t save; - ngx_stream_variable_t *var; - ngx_stream_split_clients_ctx_t *ctx; - ngx_stream_split_clients_part_t *part; - ngx_stream_compile_complex_value_t ccv; - - ctx = ngx_pcalloc(cf->pool, sizeof(ngx_stream_split_clients_ctx_t)); - if (ctx == NULL) { - return NGX_CONF_ERROR; - } - - value = cf->args->elts; - - ngx_memzero(&ccv, sizeof(ngx_stream_compile_complex_value_t)); - - ccv.cf = cf; - ccv.value = &value[1]; - ccv.complex_value = &ctx->value; - - if (ngx_stream_compile_complex_value(&ccv) != NGX_OK) { - return NGX_CONF_ERROR; - } - - name = value[2]; - - if (name.data[0] != '$') { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "invalid variable name \"%V\"", &name); - return NGX_CONF_ERROR; - } - - name.len--; - name.data++; - - var = ngx_stream_add_variable(cf, &name, NGX_STREAM_VAR_CHANGEABLE); - if (var == NULL) { - return NGX_CONF_ERROR; - } - - var->get_handler = ngx_stream_split_clients_variable; - var->data = (uintptr_t) ctx; - - if (ngx_array_init(&ctx->parts, cf->pool, 2, - sizeof(ngx_stream_split_clients_part_t)) - != NGX_OK) - { - return NGX_CONF_ERROR; - } - - save = *cf; - cf->ctx = ctx; - cf->handler = ngx_stream_split_clients; - cf->handler_conf = conf; - - rv = ngx_conf_parse(cf, NULL); - - *cf = save; - - if (rv != NGX_CONF_OK) { - return rv; - } - - sum = 0; - last = 0; - part = ctx->parts.elts; - - for (i = 0; i < ctx->parts.nelts; i++) { - sum = part[i].percent ? sum + part[i].percent : 10000; - if (sum > 10000) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "percent total is greater than 100%%"); - return NGX_CONF_ERROR; - } - - if (part[i].percent) { - last += part[i].percent * (uint64_t) 0xffffffff / 10000; - part[i].percent = last; - } - } - - return rv; -} - - -static char * -ngx_stream_split_clients(ngx_conf_t *cf, ngx_command_t *dummy, void *conf) -{ - ngx_int_t n; - ngx_str_t *value; - ngx_stream_split_clients_ctx_t *ctx; - ngx_stream_split_clients_part_t *part; - - ctx = cf->ctx; - value = cf->args->elts; - - part = ngx_array_push(&ctx->parts); - if (part == NULL) { - return NGX_CONF_ERROR; - } - - if (value[0].len == 1 && value[0].data[0] == '*') { - part->percent = 0; - - } else { - if (value[0].len == 0 || value[0].data[value[0].len - 1] != '%') { - goto invalid; - } - - n = ngx_atofp(value[0].data, value[0].len - 1, 2); - if (n == NGX_ERROR || n == 0) { - goto invalid; - } - - part->percent = (uint32_t) n; - } - - part->value.len = value[1].len; - part->value.valid = 1; - part->value.no_cacheable = 0; - part->value.not_found = 0; - part->value.data = value[1].data; - - return NGX_CONF_OK; - -invalid: - - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "invalid percent value \"%V\"", &value[0]); - return NGX_CONF_ERROR; -} diff --git a/app/nginx/src/stream/ngx_stream_ssl_module.c b/app/nginx/src/stream/ngx_stream_ssl_module.c deleted file mode 100644 index 2f242b6..0000000 --- a/app/nginx/src/stream/ngx_stream_ssl_module.c +++ /dev/null @@ -1,839 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) Nginx, Inc. - */ - - -#include <ngx_config.h> -#include <ngx_core.h> -#include <ngx_stream.h> - - -typedef ngx_int_t (*ngx_ssl_variable_handler_pt)(ngx_connection_t *c, - ngx_pool_t *pool, ngx_str_t *s); - - -#define NGX_DEFAULT_CIPHERS "HIGH:!aNULL:!MD5" -#define NGX_DEFAULT_ECDH_CURVE "auto" - - -static ngx_int_t ngx_stream_ssl_handler(ngx_stream_session_t *s); -static ngx_int_t ngx_stream_ssl_init_connection(ngx_ssl_t *ssl, - ngx_connection_t *c); -static void ngx_stream_ssl_handshake_handler(ngx_connection_t *c); -static ngx_int_t ngx_stream_ssl_static_variable(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data); -static ngx_int_t ngx_stream_ssl_variable(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data); - -static ngx_int_t ngx_stream_ssl_add_variables(ngx_conf_t *cf); -static void *ngx_stream_ssl_create_conf(ngx_conf_t *cf); -static char *ngx_stream_ssl_merge_conf(ngx_conf_t *cf, void *parent, - void *child); - -static char *ngx_stream_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd, - void *conf); -static char *ngx_stream_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd, - void *conf); -static ngx_int_t ngx_stream_ssl_init(ngx_conf_t *cf); - - -static ngx_conf_bitmask_t ngx_stream_ssl_protocols[] = { - { ngx_string("SSLv2"), NGX_SSL_SSLv2 }, - { ngx_string("SSLv3"), NGX_SSL_SSLv3 }, - { ngx_string("TLSv1"), NGX_SSL_TLSv1 }, - { ngx_string("TLSv1.1"), NGX_SSL_TLSv1_1 }, - { ngx_string("TLSv1.2"), NGX_SSL_TLSv1_2 }, - { ngx_null_string, 0 } -}; - - -static ngx_conf_enum_t ngx_stream_ssl_verify[] = { - { ngx_string("off"), 0 }, - { ngx_string("on"), 1 }, - { ngx_string("optional"), 2 }, - { ngx_string("optional_no_ca"), 3 }, - { ngx_null_string, 0 } -}; - - -static ngx_command_t ngx_stream_ssl_commands[] = { - - { ngx_string("ssl_handshake_timeout"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_msec_slot, - NGX_STREAM_SRV_CONF_OFFSET, - offsetof(ngx_stream_ssl_conf_t, handshake_timeout), - NULL }, - - { ngx_string("ssl_certificate"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_str_array_slot, - NGX_STREAM_SRV_CONF_OFFSET, - offsetof(ngx_stream_ssl_conf_t, certificates), - NULL }, - - { ngx_string("ssl_certificate_key"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_str_array_slot, - NGX_STREAM_SRV_CONF_OFFSET, - offsetof(ngx_stream_ssl_conf_t, certificate_keys), - NULL }, - - { ngx_string("ssl_password_file"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, - ngx_stream_ssl_password_file, - NGX_STREAM_SRV_CONF_OFFSET, - 0, - NULL }, - - { ngx_string("ssl_dhparam"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_str_slot, - NGX_STREAM_SRV_CONF_OFFSET, - offsetof(ngx_stream_ssl_conf_t, dhparam), - NULL }, - - { ngx_string("ssl_ecdh_curve"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_str_slot, - NGX_STREAM_SRV_CONF_OFFSET, - offsetof(ngx_stream_ssl_conf_t, ecdh_curve), - NULL }, - - { ngx_string("ssl_protocols"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_1MORE, - ngx_conf_set_bitmask_slot, - NGX_STREAM_SRV_CONF_OFFSET, - offsetof(ngx_stream_ssl_conf_t, protocols), - &ngx_stream_ssl_protocols }, - - { ngx_string("ssl_ciphers"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_str_slot, - NGX_STREAM_SRV_CONF_OFFSET, - offsetof(ngx_stream_ssl_conf_t, ciphers), - NULL }, - - { ngx_string("ssl_verify_client"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_enum_slot, - NGX_STREAM_SRV_CONF_OFFSET, - offsetof(ngx_stream_ssl_conf_t, verify), - &ngx_stream_ssl_verify }, - - { ngx_string("ssl_verify_depth"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_num_slot, - NGX_STREAM_SRV_CONF_OFFSET, - offsetof(ngx_stream_ssl_conf_t, verify_depth), - NULL }, - - { ngx_string("ssl_client_certificate"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_str_slot, - NGX_STREAM_SRV_CONF_OFFSET, - offsetof(ngx_stream_ssl_conf_t, client_certificate), - NULL }, - - { ngx_string("ssl_trusted_certificate"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_str_slot, - NGX_STREAM_SRV_CONF_OFFSET, - offsetof(ngx_stream_ssl_conf_t, trusted_certificate), - NULL }, - - { ngx_string("ssl_prefer_server_ciphers"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG, - ngx_conf_set_flag_slot, - NGX_STREAM_SRV_CONF_OFFSET, - offsetof(ngx_stream_ssl_conf_t, prefer_server_ciphers), - NULL }, - - { ngx_string("ssl_session_cache"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE12, - ngx_stream_ssl_session_cache, - NGX_STREAM_SRV_CONF_OFFSET, - 0, - NULL }, - - { ngx_string("ssl_session_tickets"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG, - ngx_conf_set_flag_slot, - NGX_STREAM_SRV_CONF_OFFSET, - offsetof(ngx_stream_ssl_conf_t, session_tickets), - NULL }, - - { ngx_string("ssl_session_ticket_key"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_str_array_slot, - NGX_STREAM_SRV_CONF_OFFSET, - offsetof(ngx_stream_ssl_conf_t, session_ticket_keys), - NULL }, - - { ngx_string("ssl_session_timeout"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_sec_slot, - NGX_STREAM_SRV_CONF_OFFSET, - offsetof(ngx_stream_ssl_conf_t, session_timeout), - NULL }, - - { ngx_string("ssl_crl"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_str_slot, - NGX_STREAM_SRV_CONF_OFFSET, - offsetof(ngx_stream_ssl_conf_t, crl), - NULL }, - - ngx_null_command -}; - - -static ngx_stream_module_t ngx_stream_ssl_module_ctx = { - ngx_stream_ssl_add_variables, /* preconfiguration */ - ngx_stream_ssl_init, /* postconfiguration */ - - NULL, /* create main configuration */ - NULL, /* init main configuration */ - - ngx_stream_ssl_create_conf, /* create server configuration */ - ngx_stream_ssl_merge_conf /* merge server configuration */ -}; - - -ngx_module_t ngx_stream_ssl_module = { - NGX_MODULE_V1, - &ngx_stream_ssl_module_ctx, /* module context */ - ngx_stream_ssl_commands, /* module directives */ - NGX_STREAM_MODULE, /* module type */ - NULL, /* init master */ - NULL, /* init module */ - NULL, /* init process */ - NULL, /* init thread */ - NULL, /* exit thread */ - NULL, /* exit process */ - NULL, /* exit master */ - NGX_MODULE_V1_PADDING -}; - - -static ngx_stream_variable_t ngx_stream_ssl_vars[] = { - - { ngx_string("ssl_protocol"), NULL, ngx_stream_ssl_static_variable, - (uintptr_t) ngx_ssl_get_protocol, NGX_STREAM_VAR_CHANGEABLE, 0 }, - - { ngx_string("ssl_cipher"), NULL, ngx_stream_ssl_static_variable, - (uintptr_t) ngx_ssl_get_cipher_name, NGX_STREAM_VAR_CHANGEABLE, 0 }, - - { ngx_string("ssl_ciphers"), NULL, ngx_stream_ssl_variable, - (uintptr_t) ngx_ssl_get_ciphers, NGX_STREAM_VAR_CHANGEABLE, 0 }, - - { ngx_string("ssl_curves"), NULL, ngx_stream_ssl_variable, - (uintptr_t) ngx_ssl_get_curves, NGX_STREAM_VAR_CHANGEABLE, 0 }, - - { ngx_string("ssl_session_id"), NULL, ngx_stream_ssl_variable, - (uintptr_t) ngx_ssl_get_session_id, NGX_STREAM_VAR_CHANGEABLE, 0 }, - - { ngx_string("ssl_session_reused"), NULL, ngx_stream_ssl_variable, - (uintptr_t) ngx_ssl_get_session_reused, NGX_STREAM_VAR_CHANGEABLE, 0 }, - - { ngx_string("ssl_server_name"), NULL, ngx_stream_ssl_variable, - (uintptr_t) ngx_ssl_get_server_name, NGX_STREAM_VAR_CHANGEABLE, 0 }, - - { ngx_string("ssl_client_cert"), NULL, ngx_stream_ssl_variable, - (uintptr_t) ngx_ssl_get_certificate, NGX_STREAM_VAR_CHANGEABLE, 0 }, - - { ngx_string("ssl_client_raw_cert"), NULL, ngx_stream_ssl_variable, - (uintptr_t) ngx_ssl_get_raw_certificate, - NGX_STREAM_VAR_CHANGEABLE, 0 }, - - { ngx_string("ssl_client_s_dn"), NULL, ngx_stream_ssl_variable, - (uintptr_t) ngx_ssl_get_subject_dn, NGX_STREAM_VAR_CHANGEABLE, 0 }, - - { ngx_string("ssl_client_i_dn"), NULL, ngx_stream_ssl_variable, - (uintptr_t) ngx_ssl_get_issuer_dn, NGX_STREAM_VAR_CHANGEABLE, 0 }, - - { ngx_string("ssl_client_serial"), NULL, ngx_stream_ssl_variable, - (uintptr_t) ngx_ssl_get_serial_number, NGX_STREAM_VAR_CHANGEABLE, 0 }, - - { ngx_string("ssl_client_fingerprint"), NULL, ngx_stream_ssl_variable, - (uintptr_t) ngx_ssl_get_fingerprint, NGX_STREAM_VAR_CHANGEABLE, 0 }, - - { ngx_string("ssl_client_verify"), NULL, ngx_stream_ssl_variable, - (uintptr_t) ngx_ssl_get_client_verify, NGX_STREAM_VAR_CHANGEABLE, 0 }, - - { ngx_string("ssl_client_v_start"), NULL, ngx_stream_ssl_variable, - (uintptr_t) ngx_ssl_get_client_v_start, NGX_STREAM_VAR_CHANGEABLE, 0 }, - - { ngx_string("ssl_client_v_end"), NULL, ngx_stream_ssl_variable, - (uintptr_t) ngx_ssl_get_client_v_end, NGX_STREAM_VAR_CHANGEABLE, 0 }, - - { ngx_string("ssl_client_v_remain"), NULL, ngx_stream_ssl_variable, - (uintptr_t) ngx_ssl_get_client_v_remain, NGX_STREAM_VAR_CHANGEABLE, 0 }, - - { ngx_null_string, NULL, NULL, 0, 0, 0 } -}; - - -static ngx_str_t ngx_stream_ssl_sess_id_ctx = ngx_string("STREAM"); - - -static ngx_int_t -ngx_stream_ssl_handler(ngx_stream_session_t *s) -{ - long rc; - X509 *cert; - ngx_int_t rv; - ngx_connection_t *c; - ngx_stream_ssl_conf_t *sslcf; - - if (!s->ssl) { - return NGX_OK; - } - - c = s->connection; - - sslcf = ngx_stream_get_module_srv_conf(s, ngx_stream_ssl_module); - - if (c->ssl == NULL) { - c->log->action = "SSL handshaking"; - - if (sslcf->ssl.ctx == NULL) { - ngx_log_error(NGX_LOG_ERR, c->log, 0, - "no \"ssl_certificate\" is defined " - "in server listening on SSL port"); - return NGX_ERROR; - } - - rv = ngx_stream_ssl_init_connection(&sslcf->ssl, c); - - if (rv != NGX_OK) { - return rv; - } - } - - if (sslcf->verify) { - rc = SSL_get_verify_result(c->ssl->connection); - - if (rc != X509_V_OK - && (sslcf->verify != 3 || !ngx_ssl_verify_error_optional(rc))) - { - ngx_log_error(NGX_LOG_INFO, c->log, 0, - "client SSL certificate verify error: (%l:%s)", - rc, X509_verify_cert_error_string(rc)); - - ngx_ssl_remove_cached_session(sslcf->ssl.ctx, - (SSL_get0_session(c->ssl->connection))); - return NGX_ERROR; - } - - if (sslcf->verify == 1) { - cert = SSL_get_peer_certificate(c->ssl->connection); - - if (cert == NULL) { - ngx_log_error(NGX_LOG_INFO, c->log, 0, - "client sent no required SSL certificate"); - - ngx_ssl_remove_cached_session(sslcf->ssl.ctx, - (SSL_get0_session(c->ssl->connection))); - return NGX_ERROR; - } - - X509_free(cert); - } - } - - return NGX_OK; -} - - -static ngx_int_t -ngx_stream_ssl_init_connection(ngx_ssl_t *ssl, ngx_connection_t *c) -{ - ngx_int_t rc; - ngx_stream_session_t *s; - ngx_stream_ssl_conf_t *sslcf; - - s = c->data; - - if (ngx_ssl_create_connection(ssl, c, 0) == NGX_ERROR) { - return NGX_ERROR; - } - - rc = ngx_ssl_handshake(c); - - if (rc == NGX_ERROR) { - return NGX_ERROR; - } - - if (rc == NGX_AGAIN) { - sslcf = ngx_stream_get_module_srv_conf(s, ngx_stream_ssl_module); - - ngx_add_timer(c->read, sslcf->handshake_timeout); - - c->ssl->handler = ngx_stream_ssl_handshake_handler; - - return NGX_AGAIN; - } - - /* rc == NGX_OK */ - - return NGX_OK; -} - - -static void -ngx_stream_ssl_handshake_handler(ngx_connection_t *c) -{ - ngx_stream_session_t *s; - - s = c->data; - - if (!c->ssl->handshaked) { - ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR); - return; - } - - if (c->read->timer_set) { - ngx_del_timer(c->read); - } - - ngx_stream_core_run_phases(s); -} - - -static ngx_int_t -ngx_stream_ssl_static_variable(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data) -{ - ngx_ssl_variable_handler_pt handler = (ngx_ssl_variable_handler_pt) data; - - size_t len; - ngx_str_t str; - - if (s->connection->ssl) { - - (void) handler(s->connection, NULL, &str); - - v->data = str.data; - - for (len = 0; v->data[len]; len++) { /* void */ } - - v->len = len; - v->valid = 1; - v->no_cacheable = 0; - v->not_found = 0; - - return NGX_OK; - } - - v->not_found = 1; - - return NGX_OK; -} - - -static ngx_int_t -ngx_stream_ssl_variable(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data) -{ - ngx_ssl_variable_handler_pt handler = (ngx_ssl_variable_handler_pt) data; - - ngx_str_t str; - - if (s->connection->ssl) { - - if (handler(s->connection, s->connection->pool, &str) != NGX_OK) { - return NGX_ERROR; - } - - v->len = str.len; - v->data = str.data; - - if (v->len) { - v->valid = 1; - v->no_cacheable = 0; - v->not_found = 0; - - return NGX_OK; - } - } - - v->not_found = 1; - - return NGX_OK; -} - - -static ngx_int_t -ngx_stream_ssl_add_variables(ngx_conf_t *cf) -{ - ngx_stream_variable_t *var, *v; - - for (v = ngx_stream_ssl_vars; v->name.len; v++) { - var = ngx_stream_add_variable(cf, &v->name, v->flags); - if (var == NULL) { - return NGX_ERROR; - } - - var->get_handler = v->get_handler; - var->data = v->data; - } - - return NGX_OK; -} - - -static void * -ngx_stream_ssl_create_conf(ngx_conf_t *cf) -{ - ngx_stream_ssl_conf_t *scf; - - scf = ngx_pcalloc(cf->pool, sizeof(ngx_stream_ssl_conf_t)); - if (scf == NULL) { - return NULL; - } - - /* - * set by ngx_pcalloc(): - * - * scf->protocols = 0; - * scf->dhparam = { 0, NULL }; - * scf->ecdh_curve = { 0, NULL }; - * scf->client_certificate = { 0, NULL }; - * scf->trusted_certificate = { 0, NULL }; - * scf->crl = { 0, NULL }; - * scf->ciphers = { 0, NULL }; - * scf->shm_zone = NULL; - */ - - scf->handshake_timeout = NGX_CONF_UNSET_MSEC; - scf->certificates = NGX_CONF_UNSET_PTR; - scf->certificate_keys = NGX_CONF_UNSET_PTR; - scf->passwords = NGX_CONF_UNSET_PTR; - scf->prefer_server_ciphers = NGX_CONF_UNSET; - scf->verify = NGX_CONF_UNSET_UINT; - scf->verify_depth = NGX_CONF_UNSET_UINT; - scf->builtin_session_cache = NGX_CONF_UNSET; - scf->session_timeout = NGX_CONF_UNSET; - scf->session_tickets = NGX_CONF_UNSET; - scf->session_ticket_keys = NGX_CONF_UNSET_PTR; - - return scf; -} - - -static char * -ngx_stream_ssl_merge_conf(ngx_conf_t *cf, void *parent, void *child) -{ - ngx_stream_ssl_conf_t *prev = parent; - ngx_stream_ssl_conf_t *conf = child; - - ngx_pool_cleanup_t *cln; - - ngx_conf_merge_msec_value(conf->handshake_timeout, - prev->handshake_timeout, 60000); - - ngx_conf_merge_value(conf->session_timeout, - prev->session_timeout, 300); - - ngx_conf_merge_value(conf->prefer_server_ciphers, - prev->prefer_server_ciphers, 0); - - ngx_conf_merge_bitmask_value(conf->protocols, prev->protocols, - (NGX_CONF_BITMASK_SET|NGX_SSL_TLSv1 - |NGX_SSL_TLSv1_1|NGX_SSL_TLSv1_2)); - - ngx_conf_merge_uint_value(conf->verify, prev->verify, 0); - ngx_conf_merge_uint_value(conf->verify_depth, prev->verify_depth, 1); - - ngx_conf_merge_ptr_value(conf->certificates, prev->certificates, NULL); - ngx_conf_merge_ptr_value(conf->certificate_keys, prev->certificate_keys, - NULL); - - ngx_conf_merge_ptr_value(conf->passwords, prev->passwords, NULL); - - ngx_conf_merge_str_value(conf->dhparam, prev->dhparam, ""); - - ngx_conf_merge_str_value(conf->client_certificate, prev->client_certificate, - ""); - ngx_conf_merge_str_value(conf->trusted_certificate, - prev->trusted_certificate, ""); - ngx_conf_merge_str_value(conf->crl, prev->crl, ""); - - ngx_conf_merge_str_value(conf->ecdh_curve, prev->ecdh_curve, - NGX_DEFAULT_ECDH_CURVE); - - ngx_conf_merge_str_value(conf->ciphers, prev->ciphers, NGX_DEFAULT_CIPHERS); - - - conf->ssl.log = cf->log; - - if (conf->certificates == NULL) { - return NGX_CONF_OK; - } - - if (conf->certificate_keys == NULL - || conf->certificate_keys->nelts < conf->certificates->nelts) - { - ngx_log_error(NGX_LOG_EMERG, cf->log, 0, - "no \"ssl_certificate_key\" is defined " - "for certificate \"%V\"", - ((ngx_str_t *) conf->certificates->elts) - + conf->certificates->nelts - 1); - return NGX_CONF_ERROR; - } - - if (ngx_ssl_create(&conf->ssl, conf->protocols, NULL) != NGX_OK) { - return NGX_CONF_ERROR; - } - - cln = ngx_pool_cleanup_add(cf->pool, 0); - if (cln == NULL) { - return NGX_CONF_ERROR; - } - - cln->handler = ngx_ssl_cleanup_ctx; - cln->data = &conf->ssl; - - if (ngx_ssl_certificates(cf, &conf->ssl, conf->certificates, - conf->certificate_keys, conf->passwords) - != NGX_OK) - { - return NGX_CONF_ERROR; - } - - if (ngx_ssl_ciphers(cf, &conf->ssl, &conf->ciphers, - conf->prefer_server_ciphers) - != NGX_OK) - { - return NGX_CONF_ERROR; - } - - if (conf->verify) { - - if (conf->client_certificate.len == 0 && conf->verify != 3) { - ngx_log_error(NGX_LOG_EMERG, cf->log, 0, - "no ssl_client_certificate for ssl_client_verify"); - return NGX_CONF_ERROR; - } - - if (ngx_ssl_client_certificate(cf, &conf->ssl, - &conf->client_certificate, - conf->verify_depth) - != NGX_OK) - { - return NGX_CONF_ERROR; - } - - if (ngx_ssl_trusted_certificate(cf, &conf->ssl, - &conf->trusted_certificate, - conf->verify_depth) - != NGX_OK) - { - return NGX_CONF_ERROR; - } - - if (ngx_ssl_crl(cf, &conf->ssl, &conf->crl) != NGX_OK) { - return NGX_CONF_ERROR; - } - } - - if (ngx_ssl_dhparam(cf, &conf->ssl, &conf->dhparam) != NGX_OK) { - return NGX_CONF_ERROR; - } - - if (ngx_ssl_ecdh_curve(cf, &conf->ssl, &conf->ecdh_curve) != NGX_OK) { - return NGX_CONF_ERROR; - } - - ngx_conf_merge_value(conf->builtin_session_cache, - prev->builtin_session_cache, NGX_SSL_NONE_SCACHE); - - if (conf->shm_zone == NULL) { - conf->shm_zone = prev->shm_zone; - } - - if (ngx_ssl_session_cache(&conf->ssl, &ngx_stream_ssl_sess_id_ctx, - conf->builtin_session_cache, - conf->shm_zone, conf->session_timeout) - != NGX_OK) - { - return NGX_CONF_ERROR; - } - - ngx_conf_merge_value(conf->session_tickets, - prev->session_tickets, 1); - -#ifdef SSL_OP_NO_TICKET - if (!conf->session_tickets) { - SSL_CTX_set_options(conf->ssl.ctx, SSL_OP_NO_TICKET); - } -#endif - - ngx_conf_merge_ptr_value(conf->session_ticket_keys, - prev->session_ticket_keys, NULL); - - if (ngx_ssl_session_ticket_keys(cf, &conf->ssl, conf->session_ticket_keys) - != NGX_OK) - { - return NGX_CONF_ERROR; - } - - return NGX_CONF_OK; -} - - -static char * -ngx_stream_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) -{ - ngx_stream_ssl_conf_t *scf = conf; - - ngx_str_t *value; - - if (scf->passwords != NGX_CONF_UNSET_PTR) { - return "is duplicate"; - } - - value = cf->args->elts; - - scf->passwords = ngx_ssl_read_password_file(cf, &value[1]); - - if (scf->passwords == NULL) { - return NGX_CONF_ERROR; - } - - return NGX_CONF_OK; -} - - -static char * -ngx_stream_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) -{ - ngx_stream_ssl_conf_t *scf = conf; - - size_t len; - ngx_str_t *value, name, size; - ngx_int_t n; - ngx_uint_t i, j; - - value = cf->args->elts; - - for (i = 1; i < cf->args->nelts; i++) { - - if (ngx_strcmp(value[i].data, "off") == 0) { - scf->builtin_session_cache = NGX_SSL_NO_SCACHE; - continue; - } - - if (ngx_strcmp(value[i].data, "none") == 0) { - scf->builtin_session_cache = NGX_SSL_NONE_SCACHE; - continue; - } - - if (ngx_strcmp(value[i].data, "builtin") == 0) { - scf->builtin_session_cache = NGX_SSL_DFLT_BUILTIN_SCACHE; - continue; - } - - if (value[i].len > sizeof("builtin:") - 1 - && ngx_strncmp(value[i].data, "builtin:", sizeof("builtin:") - 1) - == 0) - { - n = ngx_atoi(value[i].data + sizeof("builtin:") - 1, - value[i].len - (sizeof("builtin:") - 1)); - - if (n == NGX_ERROR) { - goto invalid; - } - - scf->builtin_session_cache = n; - - continue; - } - - if (value[i].len > sizeof("shared:") - 1 - && ngx_strncmp(value[i].data, "shared:", sizeof("shared:") - 1) - == 0) - { - len = 0; - - for (j = sizeof("shared:") - 1; j < value[i].len; j++) { - if (value[i].data[j] == ':') { - break; - } - - len++; - } - - if (len == 0) { - goto invalid; - } - - name.len = len; - name.data = value[i].data + sizeof("shared:") - 1; - - size.len = value[i].len - j - 1; - size.data = name.data + len + 1; - - n = ngx_parse_size(&size); - - if (n == NGX_ERROR) { - goto invalid; - } - - if (n < (ngx_int_t) (8 * ngx_pagesize)) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "session cache \"%V\" is too small", - &value[i]); - - return NGX_CONF_ERROR; - } - - scf->shm_zone = ngx_shared_memory_add(cf, &name, n, - &ngx_stream_ssl_module); - if (scf->shm_zone == NULL) { - return NGX_CONF_ERROR; - } - - scf->shm_zone->init = ngx_ssl_session_cache_init; - - continue; - } - - goto invalid; - } - - if (scf->shm_zone && scf->builtin_session_cache == NGX_CONF_UNSET) { - scf->builtin_session_cache = NGX_SSL_NO_BUILTIN_SCACHE; - } - - return NGX_CONF_OK; - -invalid: - - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "invalid session cache \"%V\"", &value[i]); - - return NGX_CONF_ERROR; -} - - -static ngx_int_t -ngx_stream_ssl_init(ngx_conf_t *cf) -{ - ngx_stream_handler_pt *h; - ngx_stream_core_main_conf_t *cmcf; - - cmcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_core_module); - - h = ngx_array_push(&cmcf->phases[NGX_STREAM_SSL_PHASE].handlers); - if (h == NULL) { - return NGX_ERROR; - } - - *h = ngx_stream_ssl_handler; - - return NGX_OK; -} diff --git a/app/nginx/src/stream/ngx_stream_ssl_module.h b/app/nginx/src/stream/ngx_stream_ssl_module.h deleted file mode 100644 index 65f5d45..0000000 --- a/app/nginx/src/stream/ngx_stream_ssl_module.h +++ /dev/null @@ -1,56 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) Nginx, Inc. - */ - - -#ifndef _NGX_STREAM_SSL_H_INCLUDED_ -#define _NGX_STREAM_SSL_H_INCLUDED_ - - -#include <ngx_config.h> -#include <ngx_core.h> -#include <ngx_stream.h> - - -typedef struct { - ngx_msec_t handshake_timeout; - - ngx_flag_t prefer_server_ciphers; - - ngx_ssl_t ssl; - - ngx_uint_t protocols; - - ngx_uint_t verify; - ngx_uint_t verify_depth; - - ssize_t builtin_session_cache; - - time_t session_timeout; - - ngx_array_t *certificates; - ngx_array_t *certificate_keys; - - ngx_str_t dhparam; - ngx_str_t ecdh_curve; - ngx_str_t client_certificate; - ngx_str_t trusted_certificate; - ngx_str_t crl; - - ngx_str_t ciphers; - - ngx_array_t *passwords; - - ngx_shm_zone_t *shm_zone; - - ngx_flag_t session_tickets; - ngx_array_t *session_ticket_keys; -} ngx_stream_ssl_conf_t; - - -extern ngx_module_t ngx_stream_ssl_module; - - -#endif /* _NGX_STREAM_SSL_H_INCLUDED_ */ diff --git a/app/nginx/src/stream/ngx_stream_ssl_preread_module.c b/app/nginx/src/stream/ngx_stream_ssl_preread_module.c deleted file mode 100644 index 2040b4f..0000000 --- a/app/nginx/src/stream/ngx_stream_ssl_preread_module.c +++ /dev/null @@ -1,449 +0,0 @@ - -/* - * Copyright (C) Nginx, Inc. - */ - - -#include <ngx_config.h> -#include <ngx_core.h> -#include <ngx_stream.h> - - -typedef struct { - ngx_flag_t enabled; -} ngx_stream_ssl_preread_srv_conf_t; - - -typedef struct { - size_t left; - size_t size; - u_char *pos; - u_char *dst; - u_char buf[4]; - ngx_str_t host; - ngx_log_t *log; - ngx_pool_t *pool; - ngx_uint_t state; -} ngx_stream_ssl_preread_ctx_t; - - -static ngx_int_t ngx_stream_ssl_preread_handler(ngx_stream_session_t *s); -static ngx_int_t ngx_stream_ssl_preread_parse_record( - ngx_stream_ssl_preread_ctx_t *ctx, u_char *pos, u_char *last); -static ngx_int_t ngx_stream_ssl_preread_server_name_variable( - ngx_stream_session_t *s, ngx_stream_variable_value_t *v, uintptr_t data); -static ngx_int_t ngx_stream_ssl_preread_add_variables(ngx_conf_t *cf); -static void *ngx_stream_ssl_preread_create_srv_conf(ngx_conf_t *cf); -static char *ngx_stream_ssl_preread_merge_srv_conf(ngx_conf_t *cf, void *parent, - void *child); -static ngx_int_t ngx_stream_ssl_preread_init(ngx_conf_t *cf); - - -static ngx_command_t ngx_stream_ssl_preread_commands[] = { - - { ngx_string("ssl_preread"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG, - ngx_conf_set_flag_slot, - NGX_STREAM_SRV_CONF_OFFSET, - offsetof(ngx_stream_ssl_preread_srv_conf_t, enabled), - NULL }, - - ngx_null_command -}; - - -static ngx_stream_module_t ngx_stream_ssl_preread_module_ctx = { - ngx_stream_ssl_preread_add_variables, /* preconfiguration */ - ngx_stream_ssl_preread_init, /* postconfiguration */ - - NULL, /* create main configuration */ - NULL, /* init main configuration */ - - ngx_stream_ssl_preread_create_srv_conf, /* create server configuration */ - ngx_stream_ssl_preread_merge_srv_conf /* merge server configuration */ -}; - - -ngx_module_t ngx_stream_ssl_preread_module = { - NGX_MODULE_V1, - &ngx_stream_ssl_preread_module_ctx, /* module context */ - ngx_stream_ssl_preread_commands, /* module directives */ - NGX_STREAM_MODULE, /* module type */ - NULL, /* init master */ - NULL, /* init module */ - NULL, /* init process */ - NULL, /* init thread */ - NULL, /* exit thread */ - NULL, /* exit process */ - NULL, /* exit master */ - NGX_MODULE_V1_PADDING -}; - - -static ngx_stream_variable_t ngx_stream_ssl_preread_vars[] = { - - { ngx_string("ssl_preread_server_name"), NULL, - ngx_stream_ssl_preread_server_name_variable, 0, 0, 0 }, - - { ngx_null_string, NULL, NULL, 0, 0, 0 } -}; - - -static ngx_int_t -ngx_stream_ssl_preread_handler(ngx_stream_session_t *s) -{ - u_char *last, *p; - size_t len; - ngx_int_t rc; - ngx_connection_t *c; - ngx_stream_ssl_preread_ctx_t *ctx; - ngx_stream_ssl_preread_srv_conf_t *sscf; - - c = s->connection; - - ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0, "ssl preread handler"); - - sscf = ngx_stream_get_module_srv_conf(s, ngx_stream_ssl_preread_module); - - if (!sscf->enabled) { - return NGX_DECLINED; - } - - if (c->type != SOCK_STREAM) { - return NGX_DECLINED; - } - - if (c->buffer == NULL) { - return NGX_AGAIN; - } - - ctx = ngx_stream_get_module_ctx(s, ngx_stream_ssl_preread_module); - if (ctx == NULL) { - ctx = ngx_pcalloc(c->pool, sizeof(ngx_stream_ssl_preread_ctx_t)); - if (ctx == NULL) { - return NGX_ERROR; - } - - ngx_stream_set_ctx(s, ctx, ngx_stream_ssl_preread_module); - - ctx->pool = c->pool; - ctx->log = c->log; - ctx->pos = c->buffer->pos; - } - - p = ctx->pos; - last = c->buffer->last; - - while (last - p >= 5) { - - if (p[0] != 0x16) { - ngx_log_debug0(NGX_LOG_DEBUG_STREAM, ctx->log, 0, - "ssl preread: not a handshake"); - return NGX_DECLINED; - } - - if (p[1] != 3) { - ngx_log_debug0(NGX_LOG_DEBUG_STREAM, ctx->log, 0, - "ssl preread: unsupported SSL version"); - return NGX_DECLINED; - } - - len = (p[3] << 8) + p[4]; - - /* read the whole record before parsing */ - if ((size_t) (last - p) < len + 5) { - break; - } - - p += 5; - - rc = ngx_stream_ssl_preread_parse_record(ctx, p, p + len); - if (rc != NGX_AGAIN) { - return rc; - } - - p += len; - } - - ctx->pos = p; - - return NGX_AGAIN; -} - - -static ngx_int_t -ngx_stream_ssl_preread_parse_record(ngx_stream_ssl_preread_ctx_t *ctx, - u_char *pos, u_char *last) -{ - size_t left, n, size; - u_char *dst, *p; - - enum { - sw_start = 0, - sw_header, /* handshake msg_type, length */ - sw_head_tail, /* version, random */ - sw_sid_len, /* session_id length */ - sw_sid, /* session_id */ - sw_cs_len, /* cipher_suites length */ - sw_cs, /* cipher_suites */ - sw_cm_len, /* compression_methods length */ - sw_cm, /* compression_methods */ - sw_ext, /* extension */ - sw_ext_header, /* extension_type, extension_data length */ - sw_sni_len, /* SNI length */ - sw_sni_host_head, /* SNI name_type, host_name length */ - sw_sni_host /* SNI host_name */ - } state; - - ngx_log_debug2(NGX_LOG_DEBUG_STREAM, ctx->log, 0, - "ssl preread: state %ui left %z", ctx->state, ctx->left); - - state = ctx->state; - size = ctx->size; - left = ctx->left; - dst = ctx->dst; - p = ctx->buf; - - for ( ;; ) { - n = ngx_min((size_t) (last - pos), size); - - if (dst) { - dst = ngx_cpymem(dst, pos, n); - } - - pos += n; - size -= n; - left -= n; - - if (size != 0) { - break; - } - - switch (state) { - - case sw_start: - state = sw_header; - dst = p; - size = 4; - left = size; - break; - - case sw_header: - if (p[0] != 1) { - ngx_log_debug0(NGX_LOG_DEBUG_STREAM, ctx->log, 0, - "ssl preread: not a client hello"); - return NGX_DECLINED; - } - - state = sw_head_tail; - dst = NULL; - size = 34; - left = (p[1] << 16) + (p[2] << 8) + p[3]; - break; - - case sw_head_tail: - state = sw_sid_len; - dst = p; - size = 1; - break; - - case sw_sid_len: - state = sw_sid; - dst = NULL; - size = p[0]; - break; - - case sw_sid: - state = sw_cs_len; - dst = p; - size = 2; - break; - - case sw_cs_len: - state = sw_cs; - dst = NULL; - size = (p[0] << 8) + p[1]; - break; - - case sw_cs: - state = sw_cm_len; - dst = p; - size = 1; - break; - - case sw_cm_len: - state = sw_cm; - dst = NULL; - size = p[0]; - break; - - case sw_cm: - if (left == 0) { - /* no extensions */ - return NGX_OK; - } - - state = sw_ext; - dst = p; - size = 2; - break; - - case sw_ext: - if (left == 0) { - return NGX_OK; - } - - state = sw_ext_header; - dst = p; - size = 4; - break; - - case sw_ext_header: - if (p[0] == 0 && p[1] == 0) { - /* SNI extension */ - state = sw_sni_len; - dst = NULL; - size = 2; - break; - } - - state = sw_ext; - dst = NULL; - size = (p[2] << 8) + p[3]; - break; - - case sw_sni_len: - state = sw_sni_host_head; - dst = p; - size = 3; - break; - - case sw_sni_host_head: - if (p[0] != 0) { - ngx_log_debug0(NGX_LOG_DEBUG_STREAM, ctx->log, 0, - "ssl preread: SNI hostname type is not DNS"); - return NGX_DECLINED; - } - - state = sw_sni_host; - size = (p[1] << 8) + p[2]; - - ctx->host.data = ngx_pnalloc(ctx->pool, size); - if (ctx->host.data == NULL) { - return NGX_ERROR; - } - - dst = ctx->host.data; - break; - - case sw_sni_host: - ctx->host.len = (p[1] << 8) + p[2]; - - ngx_log_debug1(NGX_LOG_DEBUG_STREAM, ctx->log, 0, - "ssl preread: SNI hostname \"%V\"", &ctx->host); - return NGX_OK; - } - - if (left < size) { - ngx_log_debug0(NGX_LOG_DEBUG_STREAM, ctx->log, 0, - "ssl preread: failed to parse handshake"); - return NGX_DECLINED; - } - } - - ctx->state = state; - ctx->size = size; - ctx->left = left; - ctx->dst = dst; - - return NGX_AGAIN; -} - - -static ngx_int_t -ngx_stream_ssl_preread_server_name_variable(ngx_stream_session_t *s, - ngx_variable_value_t *v, uintptr_t data) -{ - ngx_stream_ssl_preread_ctx_t *ctx; - - ctx = ngx_stream_get_module_ctx(s, ngx_stream_ssl_preread_module); - - if (ctx == NULL) { - v->not_found = 1; - return NGX_OK; - } - - v->valid = 1; - v->no_cacheable = 0; - v->not_found = 0; - v->len = ctx->host.len; - v->data = ctx->host.data; - - return NGX_OK; -} - - -static ngx_int_t -ngx_stream_ssl_preread_add_variables(ngx_conf_t *cf) -{ - ngx_stream_variable_t *var, *v; - - for (v = ngx_stream_ssl_preread_vars; v->name.len; v++) { - var = ngx_stream_add_variable(cf, &v->name, v->flags); - if (var == NULL) { - return NGX_ERROR; - } - - var->get_handler = v->get_handler; - var->data = v->data; - } - - return NGX_OK; -} - - -static void * -ngx_stream_ssl_preread_create_srv_conf(ngx_conf_t *cf) -{ - ngx_stream_ssl_preread_srv_conf_t *conf; - - conf = ngx_pcalloc(cf->pool, sizeof(ngx_stream_ssl_preread_srv_conf_t)); - if (conf == NULL) { - return NULL; - } - - conf->enabled = NGX_CONF_UNSET; - - return conf; -} - - -static char * -ngx_stream_ssl_preread_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) -{ - ngx_stream_ssl_preread_srv_conf_t *prev = parent; - ngx_stream_ssl_preread_srv_conf_t *conf = child; - - ngx_conf_merge_value(conf->enabled, prev->enabled, 0); - - return NGX_CONF_OK; -} - - -static ngx_int_t -ngx_stream_ssl_preread_init(ngx_conf_t *cf) -{ - ngx_stream_handler_pt *h; - ngx_stream_core_main_conf_t *cmcf; - - cmcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_core_module); - - h = ngx_array_push(&cmcf->phases[NGX_STREAM_PREREAD_PHASE].handlers); - if (h == NULL) { - return NGX_ERROR; - } - - *h = ngx_stream_ssl_preread_handler; - - return NGX_OK; -} diff --git a/app/nginx/src/stream/ngx_stream_upstream.c b/app/nginx/src/stream/ngx_stream_upstream.c deleted file mode 100644 index c9e1784..0000000 --- a/app/nginx/src/stream/ngx_stream_upstream.c +++ /dev/null @@ -1,717 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) Nginx, Inc. - */ - - -#include <ngx_config.h> -#include <ngx_core.h> -#include <ngx_stream.h> - - -static ngx_int_t ngx_stream_upstream_add_variables(ngx_conf_t *cf); -static ngx_int_t ngx_stream_upstream_addr_variable(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data); -static ngx_int_t ngx_stream_upstream_response_time_variable( - ngx_stream_session_t *s, ngx_stream_variable_value_t *v, uintptr_t data); -static ngx_int_t ngx_stream_upstream_bytes_variable(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data); - -static char *ngx_stream_upstream(ngx_conf_t *cf, ngx_command_t *cmd, - void *dummy); -static char *ngx_stream_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd, - void *conf); -static void *ngx_stream_upstream_create_main_conf(ngx_conf_t *cf); -static char *ngx_stream_upstream_init_main_conf(ngx_conf_t *cf, void *conf); - - -static ngx_command_t ngx_stream_upstream_commands[] = { - - { ngx_string("upstream"), - NGX_STREAM_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE1, - ngx_stream_upstream, - 0, - 0, - NULL }, - - { ngx_string("server"), - NGX_STREAM_UPS_CONF|NGX_CONF_1MORE, - ngx_stream_upstream_server, - NGX_STREAM_SRV_CONF_OFFSET, - 0, - NULL }, - - ngx_null_command -}; - - -static ngx_stream_module_t ngx_stream_upstream_module_ctx = { - ngx_stream_upstream_add_variables, /* preconfiguration */ - NULL, /* postconfiguration */ - - ngx_stream_upstream_create_main_conf, /* create main configuration */ - ngx_stream_upstream_init_main_conf, /* init main configuration */ - - NULL, /* create server configuration */ - NULL /* merge server configuration */ -}; - - -ngx_module_t ngx_stream_upstream_module = { - NGX_MODULE_V1, - &ngx_stream_upstream_module_ctx, /* module context */ - ngx_stream_upstream_commands, /* module directives */ - NGX_STREAM_MODULE, /* module type */ - NULL, /* init master */ - NULL, /* init module */ - NULL, /* init process */ - NULL, /* init thread */ - NULL, /* exit thread */ - NULL, /* exit process */ - NULL, /* exit master */ - NGX_MODULE_V1_PADDING -}; - - -static ngx_stream_variable_t ngx_stream_upstream_vars[] = { - - { ngx_string("upstream_addr"), NULL, - ngx_stream_upstream_addr_variable, 0, - NGX_STREAM_VAR_NOCACHEABLE, 0 }, - - { ngx_string("upstream_bytes_sent"), NULL, - ngx_stream_upstream_bytes_variable, 0, - NGX_STREAM_VAR_NOCACHEABLE, 0 }, - - { ngx_string("upstream_connect_time"), NULL, - ngx_stream_upstream_response_time_variable, 2, - NGX_STREAM_VAR_NOCACHEABLE, 0 }, - - { ngx_string("upstream_first_byte_time"), NULL, - ngx_stream_upstream_response_time_variable, 1, - NGX_STREAM_VAR_NOCACHEABLE, 0 }, - - { ngx_string("upstream_session_time"), NULL, - ngx_stream_upstream_response_time_variable, 0, - NGX_STREAM_VAR_NOCACHEABLE, 0 }, - - { ngx_string("upstream_bytes_received"), NULL, - ngx_stream_upstream_bytes_variable, 1, - NGX_STREAM_VAR_NOCACHEABLE, 0 }, - - { ngx_null_string, NULL, NULL, 0, 0, 0 } -}; - - -static ngx_int_t -ngx_stream_upstream_add_variables(ngx_conf_t *cf) -{ - ngx_stream_variable_t *var, *v; - - for (v = ngx_stream_upstream_vars; v->name.len; v++) { - var = ngx_stream_add_variable(cf, &v->name, v->flags); - if (var == NULL) { - return NGX_ERROR; - } - - var->get_handler = v->get_handler; - var->data = v->data; - } - - return NGX_OK; -} - - -static ngx_int_t -ngx_stream_upstream_addr_variable(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data) -{ - u_char *p; - size_t len; - ngx_uint_t i; - ngx_stream_upstream_state_t *state; - - v->valid = 1; - v->no_cacheable = 0; - v->not_found = 0; - - if (s->upstream_states == NULL || s->upstream_states->nelts == 0) { - v->not_found = 1; - return NGX_OK; - } - - len = 0; - state = s->upstream_states->elts; - - for (i = 0; i < s->upstream_states->nelts; i++) { - if (state[i].peer) { - len += state[i].peer->len; - } - - len += 2; - } - - p = ngx_pnalloc(s->connection->pool, len); - if (p == NULL) { - return NGX_ERROR; - } - - v->data = p; - - i = 0; - - for ( ;; ) { - if (state[i].peer) { - p = ngx_cpymem(p, state[i].peer->data, state[i].peer->len); - } - - if (++i == s->upstream_states->nelts) { - break; - } - - *p++ = ','; - *p++ = ' '; - } - - v->len = p - v->data; - - return NGX_OK; -} - - -static ngx_int_t -ngx_stream_upstream_bytes_variable(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data) -{ - u_char *p; - size_t len; - ngx_uint_t i; - ngx_stream_upstream_state_t *state; - - v->valid = 1; - v->no_cacheable = 0; - v->not_found = 0; - - if (s->upstream_states == NULL || s->upstream_states->nelts == 0) { - v->not_found = 1; - return NGX_OK; - } - - len = s->upstream_states->nelts * (NGX_OFF_T_LEN + 2); - - p = ngx_pnalloc(s->connection->pool, len); - if (p == NULL) { - return NGX_ERROR; - } - - v->data = p; - - i = 0; - state = s->upstream_states->elts; - - for ( ;; ) { - - if (data == 1) { - p = ngx_sprintf(p, "%O", state[i].bytes_received); - - } else { - p = ngx_sprintf(p, "%O", state[i].bytes_sent); - } - - if (++i == s->upstream_states->nelts) { - break; - } - - *p++ = ','; - *p++ = ' '; - } - - v->len = p - v->data; - - return NGX_OK; -} - - -static ngx_int_t -ngx_stream_upstream_response_time_variable(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data) -{ - u_char *p; - size_t len; - ngx_uint_t i; - ngx_msec_int_t ms; - ngx_stream_upstream_state_t *state; - - v->valid = 1; - v->no_cacheable = 0; - v->not_found = 0; - - if (s->upstream_states == NULL || s->upstream_states->nelts == 0) { - v->not_found = 1; - return NGX_OK; - } - - len = s->upstream_states->nelts * (NGX_TIME_T_LEN + 4 + 2); - - p = ngx_pnalloc(s->connection->pool, len); - if (p == NULL) { - return NGX_ERROR; - } - - v->data = p; - - i = 0; - state = s->upstream_states->elts; - - for ( ;; ) { - - if (data == 1) { - if (state[i].first_byte_time == (ngx_msec_t) -1) { - *p++ = '-'; - goto next; - } - - ms = state[i].first_byte_time; - - } else if (data == 2 && state[i].connect_time != (ngx_msec_t) -1) { - ms = state[i].connect_time; - - } else { - ms = state[i].response_time; - } - - ms = ngx_max(ms, 0); - p = ngx_sprintf(p, "%T.%03M", (time_t) ms / 1000, ms % 1000); - - next: - - if (++i == s->upstream_states->nelts) { - break; - } - - *p++ = ','; - *p++ = ' '; - } - - v->len = p - v->data; - - return NGX_OK; -} - - -static char * -ngx_stream_upstream(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy) -{ - char *rv; - void *mconf; - ngx_str_t *value; - ngx_url_t u; - ngx_uint_t m; - ngx_conf_t pcf; - ngx_stream_module_t *module; - ngx_stream_conf_ctx_t *ctx, *stream_ctx; - ngx_stream_upstream_srv_conf_t *uscf; - - ngx_memzero(&u, sizeof(ngx_url_t)); - - value = cf->args->elts; - u.host = value[1]; - u.no_resolve = 1; - u.no_port = 1; - - uscf = ngx_stream_upstream_add(cf, &u, NGX_STREAM_UPSTREAM_CREATE - |NGX_STREAM_UPSTREAM_WEIGHT - |NGX_STREAM_UPSTREAM_MAX_CONNS - |NGX_STREAM_UPSTREAM_MAX_FAILS - |NGX_STREAM_UPSTREAM_FAIL_TIMEOUT - |NGX_STREAM_UPSTREAM_DOWN - |NGX_STREAM_UPSTREAM_BACKUP); - if (uscf == NULL) { - return NGX_CONF_ERROR; - } - - - ctx = ngx_pcalloc(cf->pool, sizeof(ngx_stream_conf_ctx_t)); - if (ctx == NULL) { - return NGX_CONF_ERROR; - } - - stream_ctx = cf->ctx; - ctx->main_conf = stream_ctx->main_conf; - - /* the upstream{}'s srv_conf */ - - ctx->srv_conf = ngx_pcalloc(cf->pool, - sizeof(void *) * ngx_stream_max_module); - if (ctx->srv_conf == NULL) { - return NGX_CONF_ERROR; - } - - ctx->srv_conf[ngx_stream_upstream_module.ctx_index] = uscf; - - uscf->srv_conf = ctx->srv_conf; - - for (m = 0; cf->cycle->modules[m]; m++) { - if (cf->cycle->modules[m]->type != NGX_STREAM_MODULE) { - continue; - } - - module = cf->cycle->modules[m]->ctx; - - if (module->create_srv_conf) { - mconf = module->create_srv_conf(cf); - if (mconf == NULL) { - return NGX_CONF_ERROR; - } - - ctx->srv_conf[cf->cycle->modules[m]->ctx_index] = mconf; - } - } - - uscf->servers = ngx_array_create(cf->pool, 4, - sizeof(ngx_stream_upstream_server_t)); - if (uscf->servers == NULL) { - return NGX_CONF_ERROR; - } - - - /* parse inside upstream{} */ - - pcf = *cf; - cf->ctx = ctx; - cf->cmd_type = NGX_STREAM_UPS_CONF; - - rv = ngx_conf_parse(cf, NULL); - - *cf = pcf; - - if (rv != NGX_CONF_OK) { - return rv; - } - - if (uscf->servers->nelts == 0) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "no servers are inside upstream"); - return NGX_CONF_ERROR; - } - - return rv; -} - - -static char * -ngx_stream_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) -{ - ngx_stream_upstream_srv_conf_t *uscf = conf; - - time_t fail_timeout; - ngx_str_t *value, s; - ngx_url_t u; - ngx_int_t weight, max_conns, max_fails; - ngx_uint_t i; - ngx_stream_upstream_server_t *us; - - us = ngx_array_push(uscf->servers); - if (us == NULL) { - return NGX_CONF_ERROR; - } - - ngx_memzero(us, sizeof(ngx_stream_upstream_server_t)); - - value = cf->args->elts; - - weight = 1; - max_conns = 0; - max_fails = 1; - fail_timeout = 10; - - for (i = 2; i < cf->args->nelts; i++) { - - if (ngx_strncmp(value[i].data, "weight=", 7) == 0) { - - if (!(uscf->flags & NGX_STREAM_UPSTREAM_WEIGHT)) { - goto not_supported; - } - - weight = ngx_atoi(&value[i].data[7], value[i].len - 7); - - if (weight == NGX_ERROR || weight == 0) { - goto invalid; - } - - continue; - } - - if (ngx_strncmp(value[i].data, "max_conns=", 10) == 0) { - - if (!(uscf->flags & NGX_STREAM_UPSTREAM_MAX_CONNS)) { - goto not_supported; - } - - max_conns = ngx_atoi(&value[i].data[10], value[i].len - 10); - - if (max_conns == NGX_ERROR) { - goto invalid; - } - - continue; - } - - if (ngx_strncmp(value[i].data, "max_fails=", 10) == 0) { - - if (!(uscf->flags & NGX_STREAM_UPSTREAM_MAX_FAILS)) { - goto not_supported; - } - - max_fails = ngx_atoi(&value[i].data[10], value[i].len - 10); - - if (max_fails == NGX_ERROR) { - goto invalid; - } - - continue; - } - - if (ngx_strncmp(value[i].data, "fail_timeout=", 13) == 0) { - - if (!(uscf->flags & NGX_STREAM_UPSTREAM_FAIL_TIMEOUT)) { - goto not_supported; - } - - s.len = value[i].len - 13; - s.data = &value[i].data[13]; - - fail_timeout = ngx_parse_time(&s, 1); - - if (fail_timeout == (time_t) NGX_ERROR) { - goto invalid; - } - - continue; - } - - if (ngx_strcmp(value[i].data, "backup") == 0) { - - if (!(uscf->flags & NGX_STREAM_UPSTREAM_BACKUP)) { - goto not_supported; - } - - us->backup = 1; - - continue; - } - - if (ngx_strcmp(value[i].data, "down") == 0) { - - if (!(uscf->flags & NGX_STREAM_UPSTREAM_DOWN)) { - goto not_supported; - } - - us->down = 1; - - continue; - } - - goto invalid; - } - - ngx_memzero(&u, sizeof(ngx_url_t)); - - u.url = value[1]; - - if (ngx_parse_url(cf->pool, &u) != NGX_OK) { - if (u.err) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "%s in upstream \"%V\"", u.err, &u.url); - } - - return NGX_CONF_ERROR; - } - - if (u.no_port) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "no port in upstream \"%V\"", &u.url); - return NGX_CONF_ERROR; - } - - us->name = u.url; - us->addrs = u.addrs; - us->naddrs = u.naddrs; - us->weight = weight; - us->max_conns = max_conns; - us->max_fails = max_fails; - us->fail_timeout = fail_timeout; - - return NGX_CONF_OK; - -invalid: - - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "invalid parameter \"%V\"", &value[i]); - - return NGX_CONF_ERROR; - -not_supported: - - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "balancing method does not support parameter \"%V\"", - &value[i]); - - return NGX_CONF_ERROR; -} - - -ngx_stream_upstream_srv_conf_t * -ngx_stream_upstream_add(ngx_conf_t *cf, ngx_url_t *u, ngx_uint_t flags) -{ - ngx_uint_t i; - ngx_stream_upstream_server_t *us; - ngx_stream_upstream_srv_conf_t *uscf, **uscfp; - ngx_stream_upstream_main_conf_t *umcf; - - if (!(flags & NGX_STREAM_UPSTREAM_CREATE)) { - - if (ngx_parse_url(cf->pool, u) != NGX_OK) { - if (u->err) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "%s in upstream \"%V\"", u->err, &u->url); - } - - return NULL; - } - } - - umcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_upstream_module); - - uscfp = umcf->upstreams.elts; - - for (i = 0; i < umcf->upstreams.nelts; i++) { - - if (uscfp[i]->host.len != u->host.len - || ngx_strncasecmp(uscfp[i]->host.data, u->host.data, u->host.len) - != 0) - { - continue; - } - - if ((flags & NGX_STREAM_UPSTREAM_CREATE) - && (uscfp[i]->flags & NGX_STREAM_UPSTREAM_CREATE)) - { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "duplicate upstream \"%V\"", &u->host); - return NULL; - } - - if ((uscfp[i]->flags & NGX_STREAM_UPSTREAM_CREATE) && !u->no_port) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "upstream \"%V\" may not have port %d", - &u->host, u->port); - return NULL; - } - - if ((flags & NGX_STREAM_UPSTREAM_CREATE) && !uscfp[i]->no_port) { - ngx_log_error(NGX_LOG_EMERG, cf->log, 0, - "upstream \"%V\" may not have port %d in %s:%ui", - &u->host, uscfp[i]->port, - uscfp[i]->file_name, uscfp[i]->line); - return NULL; - } - - if (uscfp[i]->port != u->port) { - continue; - } - - if (flags & NGX_STREAM_UPSTREAM_CREATE) { - uscfp[i]->flags = flags; - } - - return uscfp[i]; - } - - uscf = ngx_pcalloc(cf->pool, sizeof(ngx_stream_upstream_srv_conf_t)); - if (uscf == NULL) { - return NULL; - } - - uscf->flags = flags; - uscf->host = u->host; - uscf->file_name = cf->conf_file->file.name.data; - uscf->line = cf->conf_file->line; - uscf->port = u->port; - uscf->no_port = u->no_port; - - if (u->naddrs == 1 && (u->port || u->family == AF_UNIX)) { - uscf->servers = ngx_array_create(cf->pool, 1, - sizeof(ngx_stream_upstream_server_t)); - if (uscf->servers == NULL) { - return NULL; - } - - us = ngx_array_push(uscf->servers); - if (us == NULL) { - return NULL; - } - - ngx_memzero(us, sizeof(ngx_stream_upstream_server_t)); - - us->addrs = u->addrs; - us->naddrs = 1; - } - - uscfp = ngx_array_push(&umcf->upstreams); - if (uscfp == NULL) { - return NULL; - } - - *uscfp = uscf; - - return uscf; -} - - -static void * -ngx_stream_upstream_create_main_conf(ngx_conf_t *cf) -{ - ngx_stream_upstream_main_conf_t *umcf; - - umcf = ngx_pcalloc(cf->pool, sizeof(ngx_stream_upstream_main_conf_t)); - if (umcf == NULL) { - return NULL; - } - - if (ngx_array_init(&umcf->upstreams, cf->pool, 4, - sizeof(ngx_stream_upstream_srv_conf_t *)) - != NGX_OK) - { - return NULL; - } - - return umcf; -} - - -static char * -ngx_stream_upstream_init_main_conf(ngx_conf_t *cf, void *conf) -{ - ngx_stream_upstream_main_conf_t *umcf = conf; - - ngx_uint_t i; - ngx_stream_upstream_init_pt init; - ngx_stream_upstream_srv_conf_t **uscfp; - - uscfp = umcf->upstreams.elts; - - for (i = 0; i < umcf->upstreams.nelts; i++) { - - init = uscfp[i]->peer.init_upstream - ? uscfp[i]->peer.init_upstream - : ngx_stream_upstream_init_round_robin; - - if (init(cf, uscfp[i]) != NGX_OK) { - return NGX_CONF_ERROR; - } - } - - return NGX_CONF_OK; -} diff --git a/app/nginx/src/stream/ngx_stream_upstream.h b/app/nginx/src/stream/ngx_stream_upstream.h deleted file mode 100644 index 90076e0..0000000 --- a/app/nginx/src/stream/ngx_stream_upstream.h +++ /dev/null @@ -1,154 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) Nginx, Inc. - */ - - -#ifndef _NGX_STREAM_UPSTREAM_H_INCLUDED_ -#define _NGX_STREAM_UPSTREAM_H_INCLUDED_ - - -#include <ngx_config.h> -#include <ngx_core.h> -#include <ngx_stream.h> -#include <ngx_event_connect.h> - - -#define NGX_STREAM_UPSTREAM_CREATE 0x0001 -#define NGX_STREAM_UPSTREAM_WEIGHT 0x0002 -#define NGX_STREAM_UPSTREAM_MAX_FAILS 0x0004 -#define NGX_STREAM_UPSTREAM_FAIL_TIMEOUT 0x0008 -#define NGX_STREAM_UPSTREAM_DOWN 0x0010 -#define NGX_STREAM_UPSTREAM_BACKUP 0x0020 -#define NGX_STREAM_UPSTREAM_MAX_CONNS 0x0100 - - -#define NGX_STREAM_UPSTREAM_NOTIFY_CONNECT 0x1 - - -typedef struct { - ngx_array_t upstreams; - /* ngx_stream_upstream_srv_conf_t */ -} ngx_stream_upstream_main_conf_t; - - -typedef struct ngx_stream_upstream_srv_conf_s ngx_stream_upstream_srv_conf_t; - - -typedef ngx_int_t (*ngx_stream_upstream_init_pt)(ngx_conf_t *cf, - ngx_stream_upstream_srv_conf_t *us); -typedef ngx_int_t (*ngx_stream_upstream_init_peer_pt)(ngx_stream_session_t *s, - ngx_stream_upstream_srv_conf_t *us); - - -typedef struct { - ngx_stream_upstream_init_pt init_upstream; - ngx_stream_upstream_init_peer_pt init; - void *data; -} ngx_stream_upstream_peer_t; - - -typedef struct { - ngx_str_t name; - ngx_addr_t *addrs; - ngx_uint_t naddrs; - ngx_uint_t weight; - ngx_uint_t max_conns; - ngx_uint_t max_fails; - time_t fail_timeout; - ngx_msec_t slow_start; - - unsigned down:1; - unsigned backup:1; - - NGX_COMPAT_BEGIN(4) - NGX_COMPAT_END -} ngx_stream_upstream_server_t; - - -struct ngx_stream_upstream_srv_conf_s { - ngx_stream_upstream_peer_t peer; - void **srv_conf; - - ngx_array_t *servers; - /* ngx_stream_upstream_server_t */ - - ngx_uint_t flags; - ngx_str_t host; - u_char *file_name; - ngx_uint_t line; - in_port_t port; - ngx_uint_t no_port; /* unsigned no_port:1 */ - -#if (NGX_STREAM_UPSTREAM_ZONE) - ngx_shm_zone_t *shm_zone; -#endif -}; - - -typedef struct { - ngx_msec_t response_time; - ngx_msec_t connect_time; - ngx_msec_t first_byte_time; - off_t bytes_sent; - off_t bytes_received; - - ngx_str_t *peer; -} ngx_stream_upstream_state_t; - - -typedef struct { - ngx_str_t host; - in_port_t port; - ngx_uint_t no_port; /* unsigned no_port:1 */ - - ngx_uint_t naddrs; - ngx_resolver_addr_t *addrs; - - struct sockaddr *sockaddr; - socklen_t socklen; - ngx_str_t name; - - ngx_resolver_ctx_t *ctx; -} ngx_stream_upstream_resolved_t; - - -typedef struct { - ngx_peer_connection_t peer; - - ngx_buf_t downstream_buf; - ngx_buf_t upstream_buf; - - ngx_chain_t *free; - ngx_chain_t *upstream_out; - ngx_chain_t *upstream_busy; - ngx_chain_t *downstream_out; - ngx_chain_t *downstream_busy; - - off_t received; - time_t start_sec; - ngx_uint_t responses; - - ngx_str_t ssl_name; - - ngx_stream_upstream_srv_conf_t *upstream; - ngx_stream_upstream_resolved_t *resolved; - ngx_stream_upstream_state_t *state; - unsigned connected:1; - unsigned proxy_protocol:1; -} ngx_stream_upstream_t; - - -ngx_stream_upstream_srv_conf_t *ngx_stream_upstream_add(ngx_conf_t *cf, - ngx_url_t *u, ngx_uint_t flags); - - -#define ngx_stream_conf_upstream_srv_conf(uscf, module) \ - uscf->srv_conf[module.ctx_index] - - -extern ngx_module_t ngx_stream_upstream_module; - - -#endif /* _NGX_STREAM_UPSTREAM_H_INCLUDED_ */ diff --git a/app/nginx/src/stream/ngx_stream_upstream_hash_module.c b/app/nginx/src/stream/ngx_stream_upstream_hash_module.c deleted file mode 100644 index cb44fcd..0000000 --- a/app/nginx/src/stream/ngx_stream_upstream_hash_module.c +++ /dev/null @@ -1,675 +0,0 @@ - -/* - * Copyright (C) Roman Arutyunyan - * Copyright (C) Nginx, Inc. - */ - - -#include <ngx_config.h> -#include <ngx_core.h> -#include <ngx_stream.h> - - -typedef struct { - uint32_t hash; - ngx_str_t *server; -} ngx_stream_upstream_chash_point_t; - - -typedef struct { - ngx_uint_t number; - ngx_stream_upstream_chash_point_t point[1]; -} ngx_stream_upstream_chash_points_t; - - -typedef struct { - ngx_stream_complex_value_t key; - ngx_stream_upstream_chash_points_t *points; -} ngx_stream_upstream_hash_srv_conf_t; - - -typedef struct { - /* the round robin data must be first */ - ngx_stream_upstream_rr_peer_data_t rrp; - ngx_stream_upstream_hash_srv_conf_t *conf; - ngx_str_t key; - ngx_uint_t tries; - ngx_uint_t rehash; - uint32_t hash; - ngx_event_get_peer_pt get_rr_peer; -} ngx_stream_upstream_hash_peer_data_t; - - -static ngx_int_t ngx_stream_upstream_init_hash(ngx_conf_t *cf, - ngx_stream_upstream_srv_conf_t *us); -static ngx_int_t ngx_stream_upstream_init_hash_peer(ngx_stream_session_t *s, - ngx_stream_upstream_srv_conf_t *us); -static ngx_int_t ngx_stream_upstream_get_hash_peer(ngx_peer_connection_t *pc, - void *data); - -static ngx_int_t ngx_stream_upstream_init_chash(ngx_conf_t *cf, - ngx_stream_upstream_srv_conf_t *us); -static int ngx_libc_cdecl - ngx_stream_upstream_chash_cmp_points(const void *one, const void *two); -static ngx_uint_t ngx_stream_upstream_find_chash_point( - ngx_stream_upstream_chash_points_t *points, uint32_t hash); -static ngx_int_t ngx_stream_upstream_init_chash_peer(ngx_stream_session_t *s, - ngx_stream_upstream_srv_conf_t *us); -static ngx_int_t ngx_stream_upstream_get_chash_peer(ngx_peer_connection_t *pc, - void *data); - -static void *ngx_stream_upstream_hash_create_conf(ngx_conf_t *cf); -static char *ngx_stream_upstream_hash(ngx_conf_t *cf, ngx_command_t *cmd, - void *conf); - - -static ngx_command_t ngx_stream_upstream_hash_commands[] = { - - { ngx_string("hash"), - NGX_STREAM_UPS_CONF|NGX_CONF_TAKE12, - ngx_stream_upstream_hash, - NGX_STREAM_SRV_CONF_OFFSET, - 0, - NULL }, - - ngx_null_command -}; - - -static ngx_stream_module_t ngx_stream_upstream_hash_module_ctx = { - NULL, /* preconfiguration */ - NULL, /* postconfiguration */ - - NULL, /* create main configuration */ - NULL, /* init main configuration */ - - ngx_stream_upstream_hash_create_conf, /* create server configuration */ - NULL /* merge server configuration */ -}; - - -ngx_module_t ngx_stream_upstream_hash_module = { - NGX_MODULE_V1, - &ngx_stream_upstream_hash_module_ctx, /* module context */ - ngx_stream_upstream_hash_commands, /* module directives */ - NGX_STREAM_MODULE, /* module type */ - NULL, /* init master */ - NULL, /* init module */ - NULL, /* init process */ - NULL, /* init thread */ - NULL, /* exit thread */ - NULL, /* exit process */ - NULL, /* exit master */ - NGX_MODULE_V1_PADDING -}; - - -static ngx_int_t -ngx_stream_upstream_init_hash(ngx_conf_t *cf, - ngx_stream_upstream_srv_conf_t *us) -{ - if (ngx_stream_upstream_init_round_robin(cf, us) != NGX_OK) { - return NGX_ERROR; - } - - us->peer.init = ngx_stream_upstream_init_hash_peer; - - return NGX_OK; -} - - -static ngx_int_t -ngx_stream_upstream_init_hash_peer(ngx_stream_session_t *s, - ngx_stream_upstream_srv_conf_t *us) -{ - ngx_stream_upstream_hash_srv_conf_t *hcf; - ngx_stream_upstream_hash_peer_data_t *hp; - - hp = ngx_palloc(s->connection->pool, - sizeof(ngx_stream_upstream_hash_peer_data_t)); - if (hp == NULL) { - return NGX_ERROR; - } - - s->upstream->peer.data = &hp->rrp; - - if (ngx_stream_upstream_init_round_robin_peer(s, us) != NGX_OK) { - return NGX_ERROR; - } - - s->upstream->peer.get = ngx_stream_upstream_get_hash_peer; - - hcf = ngx_stream_conf_upstream_srv_conf(us, - ngx_stream_upstream_hash_module); - - if (ngx_stream_complex_value(s, &hcf->key, &hp->key) != NGX_OK) { - return NGX_ERROR; - } - - ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0, - "upstream hash key:\"%V\"", &hp->key); - - hp->conf = hcf; - hp->tries = 0; - hp->rehash = 0; - hp->hash = 0; - hp->get_rr_peer = ngx_stream_upstream_get_round_robin_peer; - - return NGX_OK; -} - - -static ngx_int_t -ngx_stream_upstream_get_hash_peer(ngx_peer_connection_t *pc, void *data) -{ - ngx_stream_upstream_hash_peer_data_t *hp = data; - - time_t now; - u_char buf[NGX_INT_T_LEN]; - size_t size; - uint32_t hash; - ngx_int_t w; - uintptr_t m; - ngx_uint_t n, p; - ngx_stream_upstream_rr_peer_t *peer; - - ngx_log_debug1(NGX_LOG_DEBUG_STREAM, pc->log, 0, - "get hash peer, try: %ui", pc->tries); - - ngx_stream_upstream_rr_peers_wlock(hp->rrp.peers); - - if (hp->tries > 20 || hp->rrp.peers->single) { - ngx_stream_upstream_rr_peers_unlock(hp->rrp.peers); - return hp->get_rr_peer(pc, &hp->rrp); - } - - now = ngx_time(); - - pc->connection = NULL; - - for ( ;; ) { - - /* - * Hash expression is compatible with Cache::Memcached: - * ((crc32([REHASH] KEY) >> 16) & 0x7fff) + PREV_HASH - * with REHASH omitted at the first iteration. - */ - - ngx_crc32_init(hash); - - if (hp->rehash > 0) { - size = ngx_sprintf(buf, "%ui", hp->rehash) - buf; - ngx_crc32_update(&hash, buf, size); - } - - ngx_crc32_update(&hash, hp->key.data, hp->key.len); - ngx_crc32_final(hash); - - hash = (hash >> 16) & 0x7fff; - - hp->hash += hash; - hp->rehash++; - - w = hp->hash % hp->rrp.peers->total_weight; - peer = hp->rrp.peers->peer; - p = 0; - - while (w >= peer->weight) { - w -= peer->weight; - peer = peer->next; - p++; - } - - n = p / (8 * sizeof(uintptr_t)); - m = (uintptr_t) 1 << p % (8 * sizeof(uintptr_t)); - - if (hp->rrp.tried[n] & m) { - goto next; - } - - ngx_log_debug2(NGX_LOG_DEBUG_STREAM, pc->log, 0, - "get hash peer, value:%uD, peer:%ui", hp->hash, p); - - if (peer->down) { - goto next; - } - - if (peer->max_fails - && peer->fails >= peer->max_fails - && now - peer->checked <= peer->fail_timeout) - { - goto next; - } - - if (peer->max_conns && peer->conns >= peer->max_conns) { - goto next; - } - - break; - - next: - - if (++hp->tries > 20) { - ngx_stream_upstream_rr_peers_unlock(hp->rrp.peers); - return hp->get_rr_peer(pc, &hp->rrp); - } - } - - hp->rrp.current = peer; - - pc->sockaddr = peer->sockaddr; - pc->socklen = peer->socklen; - pc->name = &peer->name; - - peer->conns++; - - if (now - peer->checked > peer->fail_timeout) { - peer->checked = now; - } - - ngx_stream_upstream_rr_peers_unlock(hp->rrp.peers); - - hp->rrp.tried[n] |= m; - - return NGX_OK; -} - - -static ngx_int_t -ngx_stream_upstream_init_chash(ngx_conf_t *cf, - ngx_stream_upstream_srv_conf_t *us) -{ - u_char *host, *port, c; - size_t host_len, port_len, size; - uint32_t hash, base_hash; - ngx_str_t *server; - ngx_uint_t npoints, i, j; - ngx_stream_upstream_rr_peer_t *peer; - ngx_stream_upstream_rr_peers_t *peers; - ngx_stream_upstream_chash_points_t *points; - ngx_stream_upstream_hash_srv_conf_t *hcf; - union { - uint32_t value; - u_char byte[4]; - } prev_hash; - - if (ngx_stream_upstream_init_round_robin(cf, us) != NGX_OK) { - return NGX_ERROR; - } - - us->peer.init = ngx_stream_upstream_init_chash_peer; - - peers = us->peer.data; - npoints = peers->total_weight * 160; - - size = sizeof(ngx_stream_upstream_chash_points_t) - + sizeof(ngx_stream_upstream_chash_point_t) * (npoints - 1); - - points = ngx_palloc(cf->pool, size); - if (points == NULL) { - return NGX_ERROR; - } - - points->number = 0; - - for (peer = peers->peer; peer; peer = peer->next) { - server = &peer->server; - - /* - * Hash expression is compatible with Cache::Memcached::Fast: - * crc32(HOST \0 PORT PREV_HASH). - */ - - if (server->len >= 5 - && ngx_strncasecmp(server->data, (u_char *) "unix:", 5) == 0) - { - host = server->data + 5; - host_len = server->len - 5; - port = NULL; - port_len = 0; - goto done; - } - - for (j = 0; j < server->len; j++) { - c = server->data[server->len - j - 1]; - - if (c == ':') { - host = server->data; - host_len = server->len - j - 1; - port = server->data + server->len - j; - port_len = j; - goto done; - } - - if (c < '0' || c > '9') { - break; - } - } - - host = server->data; - host_len = server->len; - port = NULL; - port_len = 0; - - done: - - ngx_crc32_init(base_hash); - ngx_crc32_update(&base_hash, host, host_len); - ngx_crc32_update(&base_hash, (u_char *) "", 1); - ngx_crc32_update(&base_hash, port, port_len); - - prev_hash.value = 0; - npoints = peer->weight * 160; - - for (j = 0; j < npoints; j++) { - hash = base_hash; - - ngx_crc32_update(&hash, prev_hash.byte, 4); - ngx_crc32_final(hash); - - points->point[points->number].hash = hash; - points->point[points->number].server = server; - points->number++; - -#if (NGX_HAVE_LITTLE_ENDIAN) - prev_hash.value = hash; -#else - prev_hash.byte[0] = (u_char) (hash & 0xff); - prev_hash.byte[1] = (u_char) ((hash >> 8) & 0xff); - prev_hash.byte[2] = (u_char) ((hash >> 16) & 0xff); - prev_hash.byte[3] = (u_char) ((hash >> 24) & 0xff); -#endif - } - } - - ngx_qsort(points->point, - points->number, - sizeof(ngx_stream_upstream_chash_point_t), - ngx_stream_upstream_chash_cmp_points); - - for (i = 0, j = 1; j < points->number; j++) { - if (points->point[i].hash != points->point[j].hash) { - points->point[++i] = points->point[j]; - } - } - - points->number = i + 1; - - hcf = ngx_stream_conf_upstream_srv_conf(us, - ngx_stream_upstream_hash_module); - hcf->points = points; - - return NGX_OK; -} - - -static int ngx_libc_cdecl -ngx_stream_upstream_chash_cmp_points(const void *one, const void *two) -{ - ngx_stream_upstream_chash_point_t *first = - (ngx_stream_upstream_chash_point_t *) one; - ngx_stream_upstream_chash_point_t *second = - (ngx_stream_upstream_chash_point_t *) two; - - if (first->hash < second->hash) { - return -1; - - } else if (first->hash > second->hash) { - return 1; - - } else { - return 0; - } -} - - -static ngx_uint_t -ngx_stream_upstream_find_chash_point(ngx_stream_upstream_chash_points_t *points, - uint32_t hash) -{ - ngx_uint_t i, j, k; - ngx_stream_upstream_chash_point_t *point; - - /* find first point >= hash */ - - point = &points->point[0]; - - i = 0; - j = points->number; - - while (i < j) { - k = (i + j) / 2; - - if (hash > point[k].hash) { - i = k + 1; - - } else if (hash < point[k].hash) { - j = k; - - } else { - return k; - } - } - - return i; -} - - -static ngx_int_t -ngx_stream_upstream_init_chash_peer(ngx_stream_session_t *s, - ngx_stream_upstream_srv_conf_t *us) -{ - uint32_t hash; - ngx_stream_upstream_hash_srv_conf_t *hcf; - ngx_stream_upstream_hash_peer_data_t *hp; - - if (ngx_stream_upstream_init_hash_peer(s, us) != NGX_OK) { - return NGX_ERROR; - } - - s->upstream->peer.get = ngx_stream_upstream_get_chash_peer; - - hp = s->upstream->peer.data; - hcf = ngx_stream_conf_upstream_srv_conf(us, - ngx_stream_upstream_hash_module); - - hash = ngx_crc32_long(hp->key.data, hp->key.len); - - ngx_stream_upstream_rr_peers_rlock(hp->rrp.peers); - - hp->hash = ngx_stream_upstream_find_chash_point(hcf->points, hash); - - ngx_stream_upstream_rr_peers_unlock(hp->rrp.peers); - - return NGX_OK; -} - - -static ngx_int_t -ngx_stream_upstream_get_chash_peer(ngx_peer_connection_t *pc, void *data) -{ - ngx_stream_upstream_hash_peer_data_t *hp = data; - - time_t now; - intptr_t m; - ngx_str_t *server; - ngx_int_t total; - ngx_uint_t i, n, best_i; - ngx_stream_upstream_rr_peer_t *peer, *best; - ngx_stream_upstream_chash_point_t *point; - ngx_stream_upstream_chash_points_t *points; - ngx_stream_upstream_hash_srv_conf_t *hcf; - - ngx_log_debug1(NGX_LOG_DEBUG_STREAM, pc->log, 0, - "get consistent hash peer, try: %ui", pc->tries); - - ngx_stream_upstream_rr_peers_wlock(hp->rrp.peers); - - pc->connection = NULL; - - now = ngx_time(); - hcf = hp->conf; - - points = hcf->points; - point = &points->point[0]; - - for ( ;; ) { - server = point[hp->hash % points->number].server; - - ngx_log_debug2(NGX_LOG_DEBUG_STREAM, pc->log, 0, - "consistent hash peer:%uD, server:\"%V\"", - hp->hash, server); - - best = NULL; - best_i = 0; - total = 0; - - for (peer = hp->rrp.peers->peer, i = 0; - peer; - peer = peer->next, i++) - { - n = i / (8 * sizeof(uintptr_t)); - m = (uintptr_t) 1 << i % (8 * sizeof(uintptr_t)); - - if (hp->rrp.tried[n] & m) { - continue; - } - - if (peer->down) { - continue; - } - - if (peer->server.len != server->len - || ngx_strncmp(peer->server.data, server->data, server->len) - != 0) - { - continue; - } - - if (peer->max_fails - && peer->fails >= peer->max_fails - && now - peer->checked <= peer->fail_timeout) - { - continue; - } - - if (peer->max_conns && peer->conns >= peer->max_conns) { - continue; - } - - peer->current_weight += peer->effective_weight; - total += peer->effective_weight; - - if (peer->effective_weight < peer->weight) { - peer->effective_weight++; - } - - if (best == NULL || peer->current_weight > best->current_weight) { - best = peer; - best_i = i; - } - } - - if (best) { - best->current_weight -= total; - break; - } - - hp->hash++; - hp->tries++; - - if (hp->tries >= points->number) { - pc->name = hp->rrp.peers->name; - ngx_stream_upstream_rr_peers_unlock(hp->rrp.peers); - return NGX_BUSY; - } - } - - hp->rrp.current = best; - - pc->sockaddr = best->sockaddr; - pc->socklen = best->socklen; - pc->name = &best->name; - - best->conns++; - - if (now - best->checked > best->fail_timeout) { - best->checked = now; - } - - ngx_stream_upstream_rr_peers_unlock(hp->rrp.peers); - - n = best_i / (8 * sizeof(uintptr_t)); - m = (uintptr_t) 1 << best_i % (8 * sizeof(uintptr_t)); - - hp->rrp.tried[n] |= m; - - return NGX_OK; -} - - -static void * -ngx_stream_upstream_hash_create_conf(ngx_conf_t *cf) -{ - ngx_stream_upstream_hash_srv_conf_t *conf; - - conf = ngx_palloc(cf->pool, sizeof(ngx_stream_upstream_hash_srv_conf_t)); - if (conf == NULL) { - return NULL; - } - - conf->points = NULL; - - return conf; -} - - -static char * -ngx_stream_upstream_hash(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) -{ - ngx_stream_upstream_hash_srv_conf_t *hcf = conf; - - ngx_str_t *value; - ngx_stream_upstream_srv_conf_t *uscf; - ngx_stream_compile_complex_value_t ccv; - - value = cf->args->elts; - - ngx_memzero(&ccv, sizeof(ngx_stream_compile_complex_value_t)); - - ccv.cf = cf; - ccv.value = &value[1]; - ccv.complex_value = &hcf->key; - - if (ngx_stream_compile_complex_value(&ccv) != NGX_OK) { - return NGX_CONF_ERROR; - } - - uscf = ngx_stream_conf_get_module_srv_conf(cf, ngx_stream_upstream_module); - - if (uscf->peer.init_upstream) { - ngx_conf_log_error(NGX_LOG_WARN, cf, 0, - "load balancing method redefined"); - } - - uscf->flags = NGX_STREAM_UPSTREAM_CREATE - |NGX_STREAM_UPSTREAM_WEIGHT - |NGX_STREAM_UPSTREAM_MAX_CONNS - |NGX_STREAM_UPSTREAM_MAX_FAILS - |NGX_STREAM_UPSTREAM_FAIL_TIMEOUT - |NGX_STREAM_UPSTREAM_DOWN; - - if (cf->args->nelts == 2) { - uscf->peer.init_upstream = ngx_stream_upstream_init_hash; - - } else if (ngx_strcmp(value[2].data, "consistent") == 0) { - uscf->peer.init_upstream = ngx_stream_upstream_init_chash; - - } else { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "invalid parameter \"%V\"", &value[2]); - return NGX_CONF_ERROR; - } - - return NGX_CONF_OK; -} diff --git a/app/nginx/src/stream/ngx_stream_upstream_least_conn_module.c b/app/nginx/src/stream/ngx_stream_upstream_least_conn_module.c deleted file mode 100644 index 739b20a..0000000 --- a/app/nginx/src/stream/ngx_stream_upstream_least_conn_module.c +++ /dev/null @@ -1,310 +0,0 @@ - -/* - * Copyright (C) Maxim Dounin - * Copyright (C) Nginx, Inc. - */ - - -#include <ngx_config.h> -#include <ngx_core.h> -#include <ngx_stream.h> - - -static ngx_int_t ngx_stream_upstream_init_least_conn_peer( - ngx_stream_session_t *s, ngx_stream_upstream_srv_conf_t *us); -static ngx_int_t ngx_stream_upstream_get_least_conn_peer( - ngx_peer_connection_t *pc, void *data); -static char *ngx_stream_upstream_least_conn(ngx_conf_t *cf, ngx_command_t *cmd, - void *conf); - - -static ngx_command_t ngx_stream_upstream_least_conn_commands[] = { - - { ngx_string("least_conn"), - NGX_STREAM_UPS_CONF|NGX_CONF_NOARGS, - ngx_stream_upstream_least_conn, - 0, - 0, - NULL }, - - ngx_null_command -}; - - -static ngx_stream_module_t ngx_stream_upstream_least_conn_module_ctx = { - NULL, /* preconfiguration */ - NULL, /* postconfiguration */ - - NULL, /* create main configuration */ - NULL, /* init main configuration */ - - NULL, /* create server configuration */ - NULL /* merge server configuration */ -}; - - -ngx_module_t ngx_stream_upstream_least_conn_module = { - NGX_MODULE_V1, - &ngx_stream_upstream_least_conn_module_ctx, /* module context */ - ngx_stream_upstream_least_conn_commands, /* module directives */ - NGX_STREAM_MODULE, /* module type */ - NULL, /* init master */ - NULL, /* init module */ - NULL, /* init process */ - NULL, /* init thread */ - NULL, /* exit thread */ - NULL, /* exit process */ - NULL, /* exit master */ - NGX_MODULE_V1_PADDING -}; - - -static ngx_int_t -ngx_stream_upstream_init_least_conn(ngx_conf_t *cf, - ngx_stream_upstream_srv_conf_t *us) -{ - ngx_log_debug0(NGX_LOG_DEBUG_STREAM, cf->log, 0, - "init least conn"); - - if (ngx_stream_upstream_init_round_robin(cf, us) != NGX_OK) { - return NGX_ERROR; - } - - us->peer.init = ngx_stream_upstream_init_least_conn_peer; - - return NGX_OK; -} - - -static ngx_int_t -ngx_stream_upstream_init_least_conn_peer(ngx_stream_session_t *s, - ngx_stream_upstream_srv_conf_t *us) -{ - ngx_log_debug0(NGX_LOG_DEBUG_STREAM, s->connection->log, 0, - "init least conn peer"); - - if (ngx_stream_upstream_init_round_robin_peer(s, us) != NGX_OK) { - return NGX_ERROR; - } - - s->upstream->peer.get = ngx_stream_upstream_get_least_conn_peer; - - return NGX_OK; -} - - -static ngx_int_t -ngx_stream_upstream_get_least_conn_peer(ngx_peer_connection_t *pc, void *data) -{ - ngx_stream_upstream_rr_peer_data_t *rrp = data; - - time_t now; - uintptr_t m; - ngx_int_t rc, total; - ngx_uint_t i, n, p, many; - ngx_stream_upstream_rr_peer_t *peer, *best; - ngx_stream_upstream_rr_peers_t *peers; - - ngx_log_debug1(NGX_LOG_DEBUG_STREAM, pc->log, 0, - "get least conn peer, try: %ui", pc->tries); - - if (rrp->peers->single) { - return ngx_stream_upstream_get_round_robin_peer(pc, rrp); - } - - pc->connection = NULL; - - now = ngx_time(); - - peers = rrp->peers; - - ngx_stream_upstream_rr_peers_wlock(peers); - - best = NULL; - total = 0; - -#if (NGX_SUPPRESS_WARN) - many = 0; - p = 0; -#endif - - for (peer = peers->peer, i = 0; - peer; - peer = peer->next, i++) - { - n = i / (8 * sizeof(uintptr_t)); - m = (uintptr_t) 1 << i % (8 * sizeof(uintptr_t)); - - if (rrp->tried[n] & m) { - continue; - } - - if (peer->down) { - continue; - } - - if (peer->max_fails - && peer->fails >= peer->max_fails - && now - peer->checked <= peer->fail_timeout) - { - continue; - } - - if (peer->max_conns && peer->conns >= peer->max_conns) { - continue; - } - - /* - * select peer with least number of connections; if there are - * multiple peers with the same number of connections, select - * based on round-robin - */ - - if (best == NULL - || peer->conns * best->weight < best->conns * peer->weight) - { - best = peer; - many = 0; - p = i; - - } else if (peer->conns * best->weight == best->conns * peer->weight) { - many = 1; - } - } - - if (best == NULL) { - ngx_log_debug0(NGX_LOG_DEBUG_STREAM, pc->log, 0, - "get least conn peer, no peer found"); - - goto failed; - } - - if (many) { - ngx_log_debug0(NGX_LOG_DEBUG_STREAM, pc->log, 0, - "get least conn peer, many"); - - for (peer = best, i = p; - peer; - peer = peer->next, i++) - { - n = i / (8 * sizeof(uintptr_t)); - m = (uintptr_t) 1 << i % (8 * sizeof(uintptr_t)); - - if (rrp->tried[n] & m) { - continue; - } - - if (peer->down) { - continue; - } - - if (peer->conns * best->weight != best->conns * peer->weight) { - continue; - } - - if (peer->max_fails - && peer->fails >= peer->max_fails - && now - peer->checked <= peer->fail_timeout) - { - continue; - } - - if (peer->max_conns && peer->conns >= peer->max_conns) { - continue; - } - - peer->current_weight += peer->effective_weight; - total += peer->effective_weight; - - if (peer->effective_weight < peer->weight) { - peer->effective_weight++; - } - - if (peer->current_weight > best->current_weight) { - best = peer; - p = i; - } - } - } - - best->current_weight -= total; - - if (now - best->checked > best->fail_timeout) { - best->checked = now; - } - - pc->sockaddr = best->sockaddr; - pc->socklen = best->socklen; - pc->name = &best->name; - - best->conns++; - - rrp->current = best; - - n = p / (8 * sizeof(uintptr_t)); - m = (uintptr_t) 1 << p % (8 * sizeof(uintptr_t)); - - rrp->tried[n] |= m; - - ngx_stream_upstream_rr_peers_unlock(peers); - - return NGX_OK; - -failed: - - if (peers->next) { - ngx_log_debug0(NGX_LOG_DEBUG_STREAM, pc->log, 0, - "get least conn peer, backup servers"); - - rrp->peers = peers->next; - - n = (rrp->peers->number + (8 * sizeof(uintptr_t) - 1)) - / (8 * sizeof(uintptr_t)); - - for (i = 0; i < n; i++) { - rrp->tried[i] = 0; - } - - ngx_stream_upstream_rr_peers_unlock(peers); - - rc = ngx_stream_upstream_get_least_conn_peer(pc, rrp); - - if (rc != NGX_BUSY) { - return rc; - } - - ngx_stream_upstream_rr_peers_wlock(peers); - } - - ngx_stream_upstream_rr_peers_unlock(peers); - - pc->name = peers->name; - - return NGX_BUSY; -} - - -static char * -ngx_stream_upstream_least_conn(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) -{ - ngx_stream_upstream_srv_conf_t *uscf; - - uscf = ngx_stream_conf_get_module_srv_conf(cf, ngx_stream_upstream_module); - - if (uscf->peer.init_upstream) { - ngx_conf_log_error(NGX_LOG_WARN, cf, 0, - "load balancing method redefined"); - } - - uscf->peer.init_upstream = ngx_stream_upstream_init_least_conn; - - uscf->flags = NGX_STREAM_UPSTREAM_CREATE - |NGX_STREAM_UPSTREAM_WEIGHT - |NGX_STREAM_UPSTREAM_MAX_CONNS - |NGX_STREAM_UPSTREAM_MAX_FAILS - |NGX_STREAM_UPSTREAM_FAIL_TIMEOUT - |NGX_STREAM_UPSTREAM_DOWN - |NGX_STREAM_UPSTREAM_BACKUP; - - return NGX_CONF_OK; -} diff --git a/app/nginx/src/stream/ngx_stream_upstream_round_robin.c b/app/nginx/src/stream/ngx_stream_upstream_round_robin.c deleted file mode 100644 index 526de3a..0000000 --- a/app/nginx/src/stream/ngx_stream_upstream_round_robin.c +++ /dev/null @@ -1,874 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) Nginx, Inc. - */ - - -#include <ngx_config.h> -#include <ngx_core.h> -#include <ngx_stream.h> - - -#define ngx_stream_upstream_tries(p) ((p)->number \ - + ((p)->next ? (p)->next->number : 0)) - - -static ngx_stream_upstream_rr_peer_t *ngx_stream_upstream_get_peer( - ngx_stream_upstream_rr_peer_data_t *rrp); -static void ngx_stream_upstream_notify_round_robin_peer( - ngx_peer_connection_t *pc, void *data, ngx_uint_t state); - -#if (NGX_STREAM_SSL) - -static ngx_int_t ngx_stream_upstream_set_round_robin_peer_session( - ngx_peer_connection_t *pc, void *data); -static void ngx_stream_upstream_save_round_robin_peer_session( - ngx_peer_connection_t *pc, void *data); -static ngx_int_t ngx_stream_upstream_empty_set_session( - ngx_peer_connection_t *pc, void *data); -static void ngx_stream_upstream_empty_save_session(ngx_peer_connection_t *pc, - void *data); - -#endif - - -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_conns = server[i].max_conns; - 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_conns = server[i].max_conns; - 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_conns = 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_stream_upstream_init_round_robin_peer(ngx_stream_session_t *s, - ngx_stream_upstream_srv_conf_t *us) -{ - ngx_uint_t n; - ngx_stream_upstream_rr_peer_data_t *rrp; - - rrp = s->upstream->peer.data; - - if (rrp == NULL) { - rrp = ngx_palloc(s->connection->pool, - sizeof(ngx_stream_upstream_rr_peer_data_t)); - if (rrp == NULL) { - return NGX_ERROR; - } - - s->upstream->peer.data = rrp; - } - - rrp->peers = us->peer.data; - rrp->current = NULL; - rrp->config = 0; - - n = rrp->peers->number; - - if (rrp->peers->next && rrp->peers->next->number > n) { - n = rrp->peers->next->number; - } - - if (n <= 8 * sizeof(uintptr_t)) { - rrp->tried = &rrp->data; - rrp->data = 0; - - } else { - n = (n + (8 * sizeof(uintptr_t) - 1)) / (8 * sizeof(uintptr_t)); - - rrp->tried = ngx_pcalloc(s->connection->pool, n * sizeof(uintptr_t)); - if (rrp->tried == NULL) { - return NGX_ERROR; - } - } - - s->upstream->peer.get = ngx_stream_upstream_get_round_robin_peer; - s->upstream->peer.free = ngx_stream_upstream_free_round_robin_peer; - s->upstream->peer.notify = ngx_stream_upstream_notify_round_robin_peer; - s->upstream->peer.tries = ngx_stream_upstream_tries(rrp->peers); -#if (NGX_STREAM_SSL) - s->upstream->peer.set_session = - ngx_stream_upstream_set_round_robin_peer_session; - s->upstream->peer.save_session = - ngx_stream_upstream_save_round_robin_peer_session; -#endif - - return NGX_OK; -} - - -ngx_int_t -ngx_stream_upstream_create_round_robin_peer(ngx_stream_session_t *s, - ngx_stream_upstream_resolved_t *ur) -{ - u_char *p; - size_t len; - socklen_t socklen; - ngx_uint_t i, n; - struct sockaddr *sockaddr; - ngx_stream_upstream_rr_peer_t *peer, **peerp; - ngx_stream_upstream_rr_peers_t *peers; - ngx_stream_upstream_rr_peer_data_t *rrp; - - rrp = s->upstream->peer.data; - - if (rrp == NULL) { - rrp = ngx_palloc(s->connection->pool, - sizeof(ngx_stream_upstream_rr_peer_data_t)); - if (rrp == NULL) { - return NGX_ERROR; - } - - s->upstream->peer.data = rrp; - } - - peers = ngx_pcalloc(s->connection->pool, - sizeof(ngx_stream_upstream_rr_peers_t)); - if (peers == NULL) { - return NGX_ERROR; - } - - peer = ngx_pcalloc(s->connection->pool, - sizeof(ngx_stream_upstream_rr_peer_t) * ur->naddrs); - if (peer == NULL) { - return NGX_ERROR; - } - - peers->single = (ur->naddrs == 1); - peers->number = ur->naddrs; - peers->name = &ur->host; - - if (ur->sockaddr) { - peer[0].sockaddr = ur->sockaddr; - peer[0].socklen = ur->socklen; - peer[0].name = ur->name; - peer[0].weight = 1; - peer[0].effective_weight = 1; - peer[0].current_weight = 0; - peer[0].max_conns = 0; - peer[0].max_fails = 1; - peer[0].fail_timeout = 10; - peers->peer = peer; - - } else { - peerp = &peers->peer; - - for (i = 0; i < ur->naddrs; i++) { - - socklen = ur->addrs[i].socklen; - - sockaddr = ngx_palloc(s->connection->pool, socklen); - if (sockaddr == NULL) { - return NGX_ERROR; - } - - ngx_memcpy(sockaddr, ur->addrs[i].sockaddr, socklen); - ngx_inet_set_port(sockaddr, ur->port); - - p = ngx_pnalloc(s->connection->pool, NGX_SOCKADDR_STRLEN); - if (p == NULL) { - return NGX_ERROR; - } - - len = ngx_sock_ntop(sockaddr, socklen, p, NGX_SOCKADDR_STRLEN, 1); - - peer[i].sockaddr = sockaddr; - peer[i].socklen = socklen; - peer[i].name.len = len; - peer[i].name.data = p; - peer[i].weight = 1; - peer[i].effective_weight = 1; - peer[i].current_weight = 0; - peer[i].max_conns = 0; - peer[i].max_fails = 1; - peer[i].fail_timeout = 10; - *peerp = &peer[i]; - peerp = &peer[i].next; - } - } - - rrp->peers = peers; - rrp->current = NULL; - rrp->config = 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(s->connection->pool, n * sizeof(uintptr_t)); - if (rrp->tried == NULL) { - return NGX_ERROR; - } - } - - s->upstream->peer.get = ngx_stream_upstream_get_round_robin_peer; - s->upstream->peer.free = ngx_stream_upstream_free_round_robin_peer; - s->upstream->peer.tries = ngx_stream_upstream_tries(rrp->peers); -#if (NGX_STREAM_SSL) - s->upstream->peer.set_session = ngx_stream_upstream_empty_set_session; - s->upstream->peer.save_session = ngx_stream_upstream_empty_save_session; -#endif - - return NGX_OK; -} - - -ngx_int_t -ngx_stream_upstream_get_round_robin_peer(ngx_peer_connection_t *pc, void *data) -{ - ngx_stream_upstream_rr_peer_data_t *rrp = data; - - ngx_int_t rc; - ngx_uint_t i, n; - ngx_stream_upstream_rr_peer_t *peer; - ngx_stream_upstream_rr_peers_t *peers; - - ngx_log_debug1(NGX_LOG_DEBUG_STREAM, pc->log, 0, - "get rr peer, try: %ui", pc->tries); - - pc->connection = NULL; - - peers = rrp->peers; - ngx_stream_upstream_rr_peers_wlock(peers); - - if (peers->single) { - peer = peers->peer; - - if (peer->down) { - goto failed; - } - - if (peer->max_conns && peer->conns >= peer->max_conns) { - goto failed; - } - - rrp->current = peer; - - } else { - - /* there are several peers */ - - peer = ngx_stream_upstream_get_peer(rrp); - - if (peer == NULL) { - goto failed; - } - - ngx_log_debug2(NGX_LOG_DEBUG_STREAM, pc->log, 0, - "get rr peer, current: %p %i", - peer, peer->current_weight); - } - - pc->sockaddr = peer->sockaddr; - pc->socklen = peer->socklen; - pc->name = &peer->name; - - peer->conns++; - - ngx_stream_upstream_rr_peers_unlock(peers); - - return NGX_OK; - -failed: - - if (peers->next) { - - ngx_log_debug0(NGX_LOG_DEBUG_STREAM, pc->log, 0, "backup servers"); - - rrp->peers = peers->next; - - n = (rrp->peers->number + (8 * sizeof(uintptr_t) - 1)) - / (8 * sizeof(uintptr_t)); - - for (i = 0; i < n; i++) { - rrp->tried[i] = 0; - } - - ngx_stream_upstream_rr_peers_unlock(peers); - - rc = ngx_stream_upstream_get_round_robin_peer(pc, rrp); - - if (rc != NGX_BUSY) { - return rc; - } - - ngx_stream_upstream_rr_peers_wlock(peers); - } - - ngx_stream_upstream_rr_peers_unlock(peers); - - pc->name = peers->name; - - return NGX_BUSY; -} - - -static ngx_stream_upstream_rr_peer_t * -ngx_stream_upstream_get_peer(ngx_stream_upstream_rr_peer_data_t *rrp) -{ - time_t now; - uintptr_t m; - ngx_int_t total; - ngx_uint_t i, n, p; - ngx_stream_upstream_rr_peer_t *peer, *best; - - now = ngx_time(); - - best = NULL; - total = 0; - -#if (NGX_SUPPRESS_WARN) - p = 0; -#endif - - for (peer = rrp->peers->peer, i = 0; - peer; - peer = peer->next, i++) - { - n = i / (8 * sizeof(uintptr_t)); - m = (uintptr_t) 1 << i % (8 * sizeof(uintptr_t)); - - if (rrp->tried[n] & m) { - continue; - } - - if (peer->down) { - continue; - } - - if (peer->max_fails - && peer->fails >= peer->max_fails - && now - peer->checked <= peer->fail_timeout) - { - continue; - } - - if (peer->max_conns && peer->conns >= peer->max_conns) { - continue; - } - - peer->current_weight += peer->effective_weight; - total += peer->effective_weight; - - if (peer->effective_weight < peer->weight) { - peer->effective_weight++; - } - - if (best == NULL || peer->current_weight > best->current_weight) { - best = peer; - p = i; - } - } - - if (best == NULL) { - return NULL; - } - - rrp->current = best; - - n = p / (8 * sizeof(uintptr_t)); - m = (uintptr_t) 1 << p % (8 * sizeof(uintptr_t)); - - rrp->tried[n] |= m; - - best->current_weight -= total; - - if (now - best->checked > best->fail_timeout) { - best->checked = now; - } - - return best; -} - - -void -ngx_stream_upstream_free_round_robin_peer(ngx_peer_connection_t *pc, void *data, - ngx_uint_t state) -{ - ngx_stream_upstream_rr_peer_data_t *rrp = data; - - time_t now; - ngx_stream_upstream_rr_peer_t *peer; - - ngx_log_debug2(NGX_LOG_DEBUG_STREAM, pc->log, 0, - "free rr peer %ui %ui", pc->tries, state); - - peer = rrp->current; - - ngx_stream_upstream_rr_peers_rlock(rrp->peers); - ngx_stream_upstream_rr_peer_lock(rrp->peers, peer); - - if (rrp->peers->single) { - peer->conns--; - - ngx_stream_upstream_rr_peer_unlock(rrp->peers, peer); - ngx_stream_upstream_rr_peers_unlock(rrp->peers); - - pc->tries = 0; - return; - } - - if (state & NGX_PEER_FAILED) { - now = ngx_time(); - - peer->fails++; - peer->accessed = now; - peer->checked = now; - - if (peer->max_fails) { - peer->effective_weight -= peer->weight / peer->max_fails; - - if (peer->fails >= peer->max_fails) { - ngx_log_error(NGX_LOG_WARN, pc->log, 0, - "upstream server temporarily disabled"); - } - } - - ngx_log_debug2(NGX_LOG_DEBUG_STREAM, pc->log, 0, - "free rr peer failed: %p %i", - peer, peer->effective_weight); - - if (peer->effective_weight < 0) { - peer->effective_weight = 0; - } - - } else { - - /* mark peer live if check passed */ - - if (peer->accessed < peer->checked) { - peer->fails = 0; - } - } - - peer->conns--; - - ngx_stream_upstream_rr_peer_unlock(rrp->peers, peer); - ngx_stream_upstream_rr_peers_unlock(rrp->peers); - - if (pc->tries) { - pc->tries--; - } -} - - -static void -ngx_stream_upstream_notify_round_robin_peer(ngx_peer_connection_t *pc, - void *data, ngx_uint_t type) -{ - ngx_stream_upstream_rr_peer_data_t *rrp = data; - - ngx_stream_upstream_rr_peer_t *peer; - - peer = rrp->current; - - if (type == NGX_STREAM_UPSTREAM_NOTIFY_CONNECT - && pc->connection->type == SOCK_STREAM) - { - ngx_stream_upstream_rr_peers_rlock(rrp->peers); - ngx_stream_upstream_rr_peer_lock(rrp->peers, peer); - - if (peer->accessed < peer->checked) { - peer->fails = 0; - } - - ngx_stream_upstream_rr_peer_unlock(rrp->peers, peer); - ngx_stream_upstream_rr_peers_unlock(rrp->peers); - } -} - - -#if (NGX_STREAM_SSL) - -static ngx_int_t -ngx_stream_upstream_set_round_robin_peer_session(ngx_peer_connection_t *pc, - void *data) -{ - ngx_stream_upstream_rr_peer_data_t *rrp = data; - - ngx_int_t rc; - ngx_ssl_session_t *ssl_session; - ngx_stream_upstream_rr_peer_t *peer; -#if (NGX_STREAM_UPSTREAM_ZONE) - int len; -#if OPENSSL_VERSION_NUMBER >= 0x0090707fL - const -#endif - u_char *p; - ngx_stream_upstream_rr_peers_t *peers; - u_char buf[NGX_SSL_MAX_SESSION_SIZE]; -#endif - - peer = rrp->current; - -#if (NGX_STREAM_UPSTREAM_ZONE) - peers = rrp->peers; - - if (peers->shpool) { - ngx_stream_upstream_rr_peers_rlock(peers); - ngx_stream_upstream_rr_peer_lock(peers, peer); - - if (peer->ssl_session == NULL) { - ngx_stream_upstream_rr_peer_unlock(peers, peer); - ngx_stream_upstream_rr_peers_unlock(peers); - return NGX_OK; - } - - len = peer->ssl_session_len; - - ngx_memcpy(buf, peer->ssl_session, len); - - ngx_stream_upstream_rr_peer_unlock(peers, peer); - ngx_stream_upstream_rr_peers_unlock(peers); - - p = buf; - ssl_session = d2i_SSL_SESSION(NULL, &p, len); - - rc = ngx_ssl_set_session(pc->connection, ssl_session); - - ngx_log_debug1(NGX_LOG_DEBUG_STREAM, pc->log, 0, - "set session: %p", ssl_session); - - ngx_ssl_free_session(ssl_session); - - return rc; - } -#endif - - ssl_session = peer->ssl_session; - - rc = ngx_ssl_set_session(pc->connection, ssl_session); - - ngx_log_debug1(NGX_LOG_DEBUG_STREAM, pc->log, 0, - "set session: %p", ssl_session); - - return rc; -} - - -static void -ngx_stream_upstream_save_round_robin_peer_session(ngx_peer_connection_t *pc, - void *data) -{ - ngx_stream_upstream_rr_peer_data_t *rrp = data; - - ngx_ssl_session_t *old_ssl_session, *ssl_session; - ngx_stream_upstream_rr_peer_t *peer; -#if (NGX_STREAM_UPSTREAM_ZONE) - int len; - u_char *p; - ngx_stream_upstream_rr_peers_t *peers; - u_char buf[NGX_SSL_MAX_SESSION_SIZE]; -#endif - -#if (NGX_STREAM_UPSTREAM_ZONE) - peers = rrp->peers; - - if (peers->shpool) { - - ssl_session = SSL_get0_session(pc->connection->ssl->connection); - - if (ssl_session == NULL) { - return; - } - - ngx_log_debug1(NGX_LOG_DEBUG_STREAM, pc->log, 0, - "save session: %p", ssl_session); - - len = i2d_SSL_SESSION(ssl_session, NULL); - - /* do not cache too big session */ - - if (len > NGX_SSL_MAX_SESSION_SIZE) { - return; - } - - p = buf; - (void) i2d_SSL_SESSION(ssl_session, &p); - - peer = rrp->current; - - ngx_stream_upstream_rr_peers_rlock(peers); - ngx_stream_upstream_rr_peer_lock(peers, peer); - - if (len > peer->ssl_session_len) { - ngx_shmtx_lock(&peers->shpool->mutex); - - if (peer->ssl_session) { - ngx_slab_free_locked(peers->shpool, peer->ssl_session); - } - - peer->ssl_session = ngx_slab_alloc_locked(peers->shpool, len); - - ngx_shmtx_unlock(&peers->shpool->mutex); - - if (peer->ssl_session == NULL) { - peer->ssl_session_len = 0; - - ngx_stream_upstream_rr_peer_unlock(peers, peer); - ngx_stream_upstream_rr_peers_unlock(peers); - return; - } - - peer->ssl_session_len = len; - } - - ngx_memcpy(peer->ssl_session, buf, len); - - ngx_stream_upstream_rr_peer_unlock(peers, peer); - ngx_stream_upstream_rr_peers_unlock(peers); - - return; - } -#endif - - ssl_session = ngx_ssl_get_session(pc->connection); - - if (ssl_session == NULL) { - return; - } - - ngx_log_debug1(NGX_LOG_DEBUG_STREAM, pc->log, 0, - "save session: %p", ssl_session); - - peer = rrp->current; - - old_ssl_session = peer->ssl_session; - peer->ssl_session = ssl_session; - - if (old_ssl_session) { - - ngx_log_debug1(NGX_LOG_DEBUG_STREAM, pc->log, 0, - "old session: %p", old_ssl_session); - - /* TODO: may block */ - - ngx_ssl_free_session(old_ssl_session); - } -} - - -static ngx_int_t -ngx_stream_upstream_empty_set_session(ngx_peer_connection_t *pc, void *data) -{ - return NGX_OK; -} - - -static void -ngx_stream_upstream_empty_save_session(ngx_peer_connection_t *pc, void *data) -{ - return; -} - -#endif diff --git a/app/nginx/src/stream/ngx_stream_upstream_round_robin.h b/app/nginx/src/stream/ngx_stream_upstream_round_robin.h deleted file mode 100644 index 35d9fce..0000000 --- a/app/nginx/src/stream/ngx_stream_upstream_round_robin.h +++ /dev/null @@ -1,146 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) Nginx, Inc. - */ - - -#ifndef _NGX_STREAM_UPSTREAM_ROUND_ROBIN_H_INCLUDED_ -#define _NGX_STREAM_UPSTREAM_ROUND_ROBIN_H_INCLUDED_ - - -#include <ngx_config.h> -#include <ngx_core.h> -#include <ngx_stream.h> - - -typedef struct ngx_stream_upstream_rr_peer_s ngx_stream_upstream_rr_peer_t; - -struct ngx_stream_upstream_rr_peer_s { - struct sockaddr *sockaddr; - socklen_t socklen; - ngx_str_t name; - ngx_str_t server; - - ngx_int_t current_weight; - ngx_int_t effective_weight; - ngx_int_t weight; - - ngx_uint_t conns; - ngx_uint_t max_conns; - - ngx_uint_t fails; - time_t accessed; - time_t checked; - - ngx_uint_t max_fails; - time_t fail_timeout; - ngx_msec_t slow_start; - ngx_msec_t start_time; - - ngx_uint_t down; - - void *ssl_session; - int ssl_session_len; - -#if (NGX_STREAM_UPSTREAM_ZONE) - ngx_atomic_t lock; -#endif - - ngx_stream_upstream_rr_peer_t *next; - - NGX_COMPAT_BEGIN(25) - NGX_COMPAT_END -}; - - -typedef struct ngx_stream_upstream_rr_peers_s ngx_stream_upstream_rr_peers_t; - -struct ngx_stream_upstream_rr_peers_s { - ngx_uint_t number; - -#if (NGX_STREAM_UPSTREAM_ZONE) - ngx_slab_pool_t *shpool; - ngx_atomic_t rwlock; - ngx_stream_upstream_rr_peers_t *zone_next; -#endif - - ngx_uint_t total_weight; - - unsigned single:1; - unsigned weighted:1; - - ngx_str_t *name; - - ngx_stream_upstream_rr_peers_t *next; - - ngx_stream_upstream_rr_peer_t *peer; -}; - - -#if (NGX_STREAM_UPSTREAM_ZONE) - -#define ngx_stream_upstream_rr_peers_rlock(peers) \ - \ - if (peers->shpool) { \ - ngx_rwlock_rlock(&peers->rwlock); \ - } - -#define ngx_stream_upstream_rr_peers_wlock(peers) \ - \ - if (peers->shpool) { \ - ngx_rwlock_wlock(&peers->rwlock); \ - } - -#define ngx_stream_upstream_rr_peers_unlock(peers) \ - \ - if (peers->shpool) { \ - ngx_rwlock_unlock(&peers->rwlock); \ - } - - -#define ngx_stream_upstream_rr_peer_lock(peers, peer) \ - \ - if (peers->shpool) { \ - ngx_rwlock_wlock(&peer->lock); \ - } - -#define ngx_stream_upstream_rr_peer_unlock(peers, peer) \ - \ - if (peers->shpool) { \ - ngx_rwlock_unlock(&peer->lock); \ - } - -#else - -#define ngx_stream_upstream_rr_peers_rlock(peers) -#define ngx_stream_upstream_rr_peers_wlock(peers) -#define ngx_stream_upstream_rr_peers_unlock(peers) -#define ngx_stream_upstream_rr_peer_lock(peers, peer) -#define ngx_stream_upstream_rr_peer_unlock(peers, peer) - -#endif - - -typedef struct { - ngx_uint_t config; - ngx_stream_upstream_rr_peers_t *peers; - ngx_stream_upstream_rr_peer_t *current; - uintptr_t *tried; - uintptr_t data; -} ngx_stream_upstream_rr_peer_data_t; - - -ngx_int_t ngx_stream_upstream_init_round_robin(ngx_conf_t *cf, - ngx_stream_upstream_srv_conf_t *us); -ngx_int_t ngx_stream_upstream_init_round_robin_peer(ngx_stream_session_t *s, - ngx_stream_upstream_srv_conf_t *us); -ngx_int_t ngx_stream_upstream_create_round_robin_peer(ngx_stream_session_t *s, - ngx_stream_upstream_resolved_t *ur); -ngx_int_t ngx_stream_upstream_get_round_robin_peer(ngx_peer_connection_t *pc, - void *data); -void ngx_stream_upstream_free_round_robin_peer(ngx_peer_connection_t *pc, - void *data, ngx_uint_t state); - - -#endif /* _NGX_STREAM_UPSTREAM_ROUND_ROBIN_H_INCLUDED_ */ diff --git a/app/nginx/src/stream/ngx_stream_upstream_zone_module.c b/app/nginx/src/stream/ngx_stream_upstream_zone_module.c deleted file mode 100644 index 07ab88d..0000000 --- a/app/nginx/src/stream/ngx_stream_upstream_zone_module.c +++ /dev/null @@ -1,243 +0,0 @@ - -/* - * Copyright (C) Ruslan Ermilov - * Copyright (C) Nginx, Inc. - */ - - -#include <ngx_config.h> -#include <ngx_core.h> -#include <ngx_stream.h> - - -static char *ngx_stream_upstream_zone(ngx_conf_t *cf, ngx_command_t *cmd, - void *conf); -static ngx_int_t ngx_stream_upstream_init_zone(ngx_shm_zone_t *shm_zone, - void *data); -static ngx_stream_upstream_rr_peers_t *ngx_stream_upstream_zone_copy_peers( - ngx_slab_pool_t *shpool, ngx_stream_upstream_srv_conf_t *uscf); - - -static ngx_command_t ngx_stream_upstream_zone_commands[] = { - - { ngx_string("zone"), - NGX_STREAM_UPS_CONF|NGX_CONF_TAKE12, - ngx_stream_upstream_zone, - 0, - 0, - NULL }, - - ngx_null_command -}; - - -static ngx_stream_module_t ngx_stream_upstream_zone_module_ctx = { - NULL, /* preconfiguration */ - NULL, /* postconfiguration */ - - NULL, /* create main configuration */ - NULL, /* init main configuration */ - - NULL, /* create server configuration */ - NULL /* merge server configuration */ -}; - - -ngx_module_t ngx_stream_upstream_zone_module = { - NGX_MODULE_V1, - &ngx_stream_upstream_zone_module_ctx, /* module context */ - ngx_stream_upstream_zone_commands, /* module directives */ - NGX_STREAM_MODULE, /* module type */ - NULL, /* init master */ - NULL, /* init module */ - NULL, /* init process */ - NULL, /* init thread */ - NULL, /* exit thread */ - NULL, /* exit process */ - NULL, /* exit master */ - NGX_MODULE_V1_PADDING -}; - - -static char * -ngx_stream_upstream_zone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) -{ - ssize_t size; - ngx_str_t *value; - ngx_stream_upstream_srv_conf_t *uscf; - ngx_stream_upstream_main_conf_t *umcf; - - uscf = ngx_stream_conf_get_module_srv_conf(cf, ngx_stream_upstream_module); - umcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_upstream_module); - - value = cf->args->elts; - - if (!value[1].len) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "invalid zone name \"%V\"", &value[1]); - return NGX_CONF_ERROR; - } - - if (cf->args->nelts == 3) { - size = ngx_parse_size(&value[2]); - - if (size == NGX_ERROR) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "invalid zone size \"%V\"", &value[2]); - return NGX_CONF_ERROR; - } - - if (size < (ssize_t) (8 * ngx_pagesize)) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "zone \"%V\" is too small", &value[1]); - return NGX_CONF_ERROR; - } - - } else { - size = 0; - } - - uscf->shm_zone = ngx_shared_memory_add(cf, &value[1], size, - &ngx_stream_upstream_module); - if (uscf->shm_zone == NULL) { - return NGX_CONF_ERROR; - } - - uscf->shm_zone->init = ngx_stream_upstream_init_zone; - uscf->shm_zone->data = umcf; - - uscf->shm_zone->noreuse = 1; - - return NGX_CONF_OK; -} - - -static ngx_int_t -ngx_stream_upstream_init_zone(ngx_shm_zone_t *shm_zone, void *data) -{ - size_t len; - ngx_uint_t i; - ngx_slab_pool_t *shpool; - ngx_stream_upstream_rr_peers_t *peers, **peersp; - ngx_stream_upstream_srv_conf_t *uscf, **uscfp; - ngx_stream_upstream_main_conf_t *umcf; - - shpool = (ngx_slab_pool_t *) shm_zone->shm.addr; - umcf = shm_zone->data; - uscfp = umcf->upstreams.elts; - - if (shm_zone->shm.exists) { - peers = shpool->data; - - for (i = 0; i < umcf->upstreams.nelts; i++) { - uscf = uscfp[i]; - - if (uscf->shm_zone != shm_zone) { - continue; - } - - uscf->peer.data = peers; - peers = peers->zone_next; - } - - return NGX_OK; - } - - len = sizeof(" in upstream zone \"\"") + shm_zone->shm.name.len; - - shpool->log_ctx = ngx_slab_alloc(shpool, len); - if (shpool->log_ctx == NULL) { - return NGX_ERROR; - } - - ngx_sprintf(shpool->log_ctx, " in upstream zone \"%V\"%Z", - &shm_zone->shm.name); - - - /* copy peers to shared memory */ - - peersp = (ngx_stream_upstream_rr_peers_t **) (void *) &shpool->data; - - for (i = 0; i < umcf->upstreams.nelts; i++) { - uscf = uscfp[i]; - - if (uscf->shm_zone != shm_zone) { - continue; - } - - peers = ngx_stream_upstream_zone_copy_peers(shpool, uscf); - if (peers == NULL) { - return NGX_ERROR; - } - - *peersp = peers; - peersp = &peers->zone_next; - } - - return NGX_OK; -} - - -static ngx_stream_upstream_rr_peers_t * -ngx_stream_upstream_zone_copy_peers(ngx_slab_pool_t *shpool, - ngx_stream_upstream_srv_conf_t *uscf) -{ - ngx_stream_upstream_rr_peer_t *peer, **peerp; - ngx_stream_upstream_rr_peers_t *peers, *backup; - - peers = ngx_slab_alloc(shpool, sizeof(ngx_stream_upstream_rr_peers_t)); - if (peers == NULL) { - return NULL; - } - - ngx_memcpy(peers, uscf->peer.data, sizeof(ngx_stream_upstream_rr_peers_t)); - - peers->shpool = shpool; - - for (peerp = &peers->peer; *peerp; peerp = &peer->next) { - /* pool is unlocked */ - peer = ngx_slab_calloc_locked(shpool, - sizeof(ngx_stream_upstream_rr_peer_t)); - if (peer == NULL) { - return NULL; - } - - ngx_memcpy(peer, *peerp, sizeof(ngx_stream_upstream_rr_peer_t)); - - *peerp = peer; - } - - if (peers->next == NULL) { - goto done; - } - - backup = ngx_slab_alloc(shpool, sizeof(ngx_stream_upstream_rr_peers_t)); - if (backup == NULL) { - return NULL; - } - - ngx_memcpy(backup, peers->next, sizeof(ngx_stream_upstream_rr_peers_t)); - - backup->shpool = shpool; - - for (peerp = &backup->peer; *peerp; peerp = &peer->next) { - /* pool is unlocked */ - peer = ngx_slab_calloc_locked(shpool, - sizeof(ngx_stream_upstream_rr_peer_t)); - if (peer == NULL) { - return NULL; - } - - ngx_memcpy(peer, *peerp, sizeof(ngx_stream_upstream_rr_peer_t)); - - *peerp = peer; - } - - peers->next = backup; - -done: - - uscf->peer.data = peers; - - return peers; -} diff --git a/app/nginx/src/stream/ngx_stream_variables.c b/app/nginx/src/stream/ngx_stream_variables.c deleted file mode 100644 index 5d15f3a..0000000 --- a/app/nginx/src/stream/ngx_stream_variables.c +++ /dev/null @@ -1,1234 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) Nginx, Inc. - */ - - -#include <ngx_config.h> -#include <ngx_core.h> -#include <ngx_stream.h> -#include <nginx.h> - -static ngx_stream_variable_t *ngx_stream_add_prefix_variable(ngx_conf_t *cf, - ngx_str_t *name, ngx_uint_t flags); - -static ngx_int_t ngx_stream_variable_binary_remote_addr( - ngx_stream_session_t *s, ngx_stream_variable_value_t *v, uintptr_t data); -static ngx_int_t ngx_stream_variable_remote_addr(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data); -static ngx_int_t ngx_stream_variable_remote_port(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data); -static ngx_int_t ngx_stream_variable_proxy_protocol_addr( - ngx_stream_session_t *s, ngx_stream_variable_value_t *v, uintptr_t data); -static ngx_int_t ngx_stream_variable_proxy_protocol_port( - ngx_stream_session_t *s, ngx_stream_variable_value_t *v, uintptr_t data); -static ngx_int_t ngx_stream_variable_server_addr(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data); -static ngx_int_t ngx_stream_variable_server_port(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data); -static ngx_int_t ngx_stream_variable_bytes(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data); -static ngx_int_t ngx_stream_variable_session_time(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data); -static ngx_int_t ngx_stream_variable_status(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data); -static ngx_int_t ngx_stream_variable_connection(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data); - -static ngx_int_t ngx_stream_variable_nginx_version(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data); -static ngx_int_t ngx_stream_variable_hostname(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data); -static ngx_int_t ngx_stream_variable_pid(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data); -static ngx_int_t ngx_stream_variable_msec(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data); -static ngx_int_t ngx_stream_variable_time_iso8601(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data); -static ngx_int_t ngx_stream_variable_time_local(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data); -static ngx_int_t ngx_stream_variable_protocol(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data); - - -static ngx_stream_variable_t ngx_stream_core_variables[] = { - - { ngx_string("binary_remote_addr"), NULL, - ngx_stream_variable_binary_remote_addr, 0, 0, 0 }, - - { ngx_string("remote_addr"), NULL, - ngx_stream_variable_remote_addr, 0, 0, 0 }, - - { ngx_string("remote_port"), NULL, - ngx_stream_variable_remote_port, 0, 0, 0 }, - - { ngx_string("proxy_protocol_addr"), NULL, - ngx_stream_variable_proxy_protocol_addr, 0, 0, 0 }, - - { ngx_string("proxy_protocol_port"), NULL, - ngx_stream_variable_proxy_protocol_port, 0, 0, 0 }, - - { ngx_string("server_addr"), NULL, - ngx_stream_variable_server_addr, 0, 0, 0 }, - - { ngx_string("server_port"), NULL, - ngx_stream_variable_server_port, 0, 0, 0 }, - - { ngx_string("bytes_sent"), NULL, ngx_stream_variable_bytes, - 0, 0, 0 }, - - { ngx_string("bytes_received"), NULL, ngx_stream_variable_bytes, - 1, 0, 0 }, - - { ngx_string("session_time"), NULL, ngx_stream_variable_session_time, - 0, NGX_STREAM_VAR_NOCACHEABLE, 0 }, - - { ngx_string("status"), NULL, ngx_stream_variable_status, - 0, NGX_STREAM_VAR_NOCACHEABLE, 0 }, - - { ngx_string("connection"), NULL, - ngx_stream_variable_connection, 0, 0, 0 }, - - { ngx_string("nginx_version"), NULL, ngx_stream_variable_nginx_version, - 0, 0, 0 }, - - { ngx_string("hostname"), NULL, ngx_stream_variable_hostname, - 0, 0, 0 }, - - { ngx_string("pid"), NULL, ngx_stream_variable_pid, - 0, 0, 0 }, - - { ngx_string("msec"), NULL, ngx_stream_variable_msec, - 0, NGX_STREAM_VAR_NOCACHEABLE, 0 }, - - { ngx_string("time_iso8601"), NULL, ngx_stream_variable_time_iso8601, - 0, NGX_STREAM_VAR_NOCACHEABLE, 0 }, - - { ngx_string("time_local"), NULL, ngx_stream_variable_time_local, - 0, NGX_STREAM_VAR_NOCACHEABLE, 0 }, - - { ngx_string("protocol"), NULL, - ngx_stream_variable_protocol, 0, 0, 0 }, - - { ngx_null_string, NULL, NULL, 0, 0, 0 } -}; - - -ngx_stream_variable_value_t ngx_stream_variable_null_value = - ngx_stream_variable(""); -ngx_stream_variable_value_t ngx_stream_variable_true_value = - ngx_stream_variable("1"); - - -static ngx_uint_t ngx_stream_variable_depth = 100; - - -ngx_stream_variable_t * -ngx_stream_add_variable(ngx_conf_t *cf, ngx_str_t *name, ngx_uint_t flags) -{ - ngx_int_t rc; - ngx_uint_t i; - ngx_hash_key_t *key; - ngx_stream_variable_t *v; - ngx_stream_core_main_conf_t *cmcf; - - if (name->len == 0) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "invalid variable name \"$\""); - return NULL; - } - - if (flags & NGX_STREAM_VAR_PREFIX) { - return ngx_stream_add_prefix_variable(cf, name, flags); - } - - cmcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_core_module); - - key = cmcf->variables_keys->keys.elts; - for (i = 0; i < cmcf->variables_keys->keys.nelts; i++) { - if (name->len != key[i].key.len - || ngx_strncasecmp(name->data, key[i].key.data, name->len) != 0) - { - continue; - } - - v = key[i].value; - - if (!(v->flags & NGX_STREAM_VAR_CHANGEABLE)) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "the duplicate \"%V\" variable", name); - return NULL; - } - - v->flags &= flags | ~NGX_STREAM_VAR_WEAK; - - return v; - } - - v = ngx_palloc(cf->pool, sizeof(ngx_stream_variable_t)); - if (v == NULL) { - return NULL; - } - - v->name.len = name->len; - v->name.data = ngx_pnalloc(cf->pool, name->len); - if (v->name.data == NULL) { - return NULL; - } - - ngx_strlow(v->name.data, name->data, name->len); - - v->set_handler = NULL; - v->get_handler = NULL; - v->data = 0; - v->flags = flags; - v->index = 0; - - rc = ngx_hash_add_key(cmcf->variables_keys, &v->name, v, 0); - - if (rc == NGX_ERROR) { - return NULL; - } - - if (rc == NGX_BUSY) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "conflicting variable name \"%V\"", name); - return NULL; - } - - return v; -} - - -static ngx_stream_variable_t * -ngx_stream_add_prefix_variable(ngx_conf_t *cf, ngx_str_t *name, - ngx_uint_t flags) -{ - ngx_uint_t i; - ngx_stream_variable_t *v; - ngx_stream_core_main_conf_t *cmcf; - - cmcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_core_module); - - v = cmcf->prefix_variables.elts; - for (i = 0; i < cmcf->prefix_variables.nelts; i++) { - if (name->len != v[i].name.len - || ngx_strncasecmp(name->data, v[i].name.data, name->len) != 0) - { - continue; - } - - v = &v[i]; - - if (!(v->flags & NGX_STREAM_VAR_CHANGEABLE)) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "the duplicate \"%V\" variable", name); - return NULL; - } - - v->flags &= flags | ~NGX_STREAM_VAR_WEAK; - - return v; - } - - v = ngx_array_push(&cmcf->prefix_variables); - if (v == NULL) { - return NULL; - } - - v->name.len = name->len; - v->name.data = ngx_pnalloc(cf->pool, name->len); - if (v->name.data == NULL) { - return NULL; - } - - ngx_strlow(v->name.data, name->data, name->len); - - v->set_handler = NULL; - v->get_handler = NULL; - v->data = 0; - v->flags = flags; - v->index = 0; - - return v; -} - - -ngx_int_t -ngx_stream_get_variable_index(ngx_conf_t *cf, ngx_str_t *name) -{ - ngx_uint_t i; - ngx_stream_variable_t *v; - ngx_stream_core_main_conf_t *cmcf; - - if (name->len == 0) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "invalid variable name \"$\""); - return NGX_ERROR; - } - - cmcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_core_module); - - v = cmcf->variables.elts; - - if (v == NULL) { - if (ngx_array_init(&cmcf->variables, cf->pool, 4, - sizeof(ngx_stream_variable_t)) - != NGX_OK) - { - return NGX_ERROR; - } - - } else { - for (i = 0; i < cmcf->variables.nelts; i++) { - if (name->len != v[i].name.len - || ngx_strncasecmp(name->data, v[i].name.data, name->len) != 0) - { - continue; - } - - return i; - } - } - - v = ngx_array_push(&cmcf->variables); - if (v == NULL) { - return NGX_ERROR; - } - - v->name.len = name->len; - v->name.data = ngx_pnalloc(cf->pool, name->len); - if (v->name.data == NULL) { - return NGX_ERROR; - } - - ngx_strlow(v->name.data, name->data, name->len); - - v->set_handler = NULL; - v->get_handler = NULL; - v->data = 0; - v->flags = 0; - v->index = cmcf->variables.nelts - 1; - - return v->index; -} - - -ngx_stream_variable_value_t * -ngx_stream_get_indexed_variable(ngx_stream_session_t *s, ngx_uint_t index) -{ - ngx_stream_variable_t *v; - ngx_stream_core_main_conf_t *cmcf; - - cmcf = ngx_stream_get_module_main_conf(s, ngx_stream_core_module); - - if (cmcf->variables.nelts <= index) { - ngx_log_error(NGX_LOG_ALERT, s->connection->log, 0, - "unknown variable index: %ui", index); - return NULL; - } - - if (s->variables[index].not_found || s->variables[index].valid) { - return &s->variables[index]; - } - - v = cmcf->variables.elts; - - if (ngx_stream_variable_depth == 0) { - ngx_log_error(NGX_LOG_ERR, s->connection->log, 0, - "cycle while evaluating variable \"%V\"", - &v[index].name); - return NULL; - } - - ngx_stream_variable_depth--; - - if (v[index].get_handler(s, &s->variables[index], v[index].data) - == NGX_OK) - { - ngx_stream_variable_depth++; - - if (v[index].flags & NGX_STREAM_VAR_NOCACHEABLE) { - s->variables[index].no_cacheable = 1; - } - - return &s->variables[index]; - } - - ngx_stream_variable_depth++; - - s->variables[index].valid = 0; - s->variables[index].not_found = 1; - - return NULL; -} - - -ngx_stream_variable_value_t * -ngx_stream_get_flushed_variable(ngx_stream_session_t *s, ngx_uint_t index) -{ - ngx_stream_variable_value_t *v; - - v = &s->variables[index]; - - if (v->valid || v->not_found) { - if (!v->no_cacheable) { - return v; - } - - v->valid = 0; - v->not_found = 0; - } - - return ngx_stream_get_indexed_variable(s, index); -} - - -ngx_stream_variable_value_t * -ngx_stream_get_variable(ngx_stream_session_t *s, ngx_str_t *name, - ngx_uint_t key) -{ - size_t len; - ngx_uint_t i, n; - ngx_stream_variable_t *v; - ngx_stream_variable_value_t *vv; - ngx_stream_core_main_conf_t *cmcf; - - cmcf = ngx_stream_get_module_main_conf(s, ngx_stream_core_module); - - v = ngx_hash_find(&cmcf->variables_hash, key, name->data, name->len); - - if (v) { - if (v->flags & NGX_STREAM_VAR_INDEXED) { - return ngx_stream_get_flushed_variable(s, v->index); - } - - if (ngx_stream_variable_depth == 0) { - ngx_log_error(NGX_LOG_ERR, s->connection->log, 0, - "cycle while evaluating variable \"%V\"", name); - return NULL; - } - - ngx_stream_variable_depth--; - - vv = ngx_palloc(s->connection->pool, - sizeof(ngx_stream_variable_value_t)); - - if (vv && v->get_handler(s, vv, v->data) == NGX_OK) { - ngx_stream_variable_depth++; - return vv; - } - - ngx_stream_variable_depth++; - return NULL; - } - - vv = ngx_palloc(s->connection->pool, sizeof(ngx_stream_variable_value_t)); - if (vv == NULL) { - return NULL; - } - - len = 0; - - v = cmcf->prefix_variables.elts; - n = cmcf->prefix_variables.nelts; - - for (i = 0; i < cmcf->prefix_variables.nelts; i++) { - if (name->len >= v[i].name.len && name->len > len - && ngx_strncmp(name->data, v[i].name.data, v[i].name.len) == 0) - { - len = v[i].name.len; - n = i; - } - } - - if (n != cmcf->prefix_variables.nelts) { - if (v[n].get_handler(s, vv, (uintptr_t) name) == NGX_OK) { - return vv; - } - - return NULL; - } - - vv->not_found = 1; - - return vv; -} - - -static ngx_int_t -ngx_stream_variable_binary_remote_addr(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data) - { - struct sockaddr_in *sin; -#if (NGX_HAVE_INET6) - struct sockaddr_in6 *sin6; -#endif - - switch (s->connection->sockaddr->sa_family) { - -#if (NGX_HAVE_INET6) - case AF_INET6: - sin6 = (struct sockaddr_in6 *) s->connection->sockaddr; - - v->len = sizeof(struct in6_addr); - v->valid = 1; - v->no_cacheable = 0; - v->not_found = 0; - v->data = sin6->sin6_addr.s6_addr; - - break; -#endif - - default: /* AF_INET */ - sin = (struct sockaddr_in *) s->connection->sockaddr; - - v->len = sizeof(in_addr_t); - v->valid = 1; - v->no_cacheable = 0; - v->not_found = 0; - v->data = (u_char *) &sin->sin_addr; - - break; - } - - return NGX_OK; -} - - -static ngx_int_t -ngx_stream_variable_remote_addr(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data) -{ - v->len = s->connection->addr_text.len; - v->valid = 1; - v->no_cacheable = 0; - v->not_found = 0; - v->data = s->connection->addr_text.data; - - return NGX_OK; -} - - -static ngx_int_t -ngx_stream_variable_remote_port(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data) -{ - ngx_uint_t port; - - v->len = 0; - v->valid = 1; - v->no_cacheable = 0; - v->not_found = 0; - - v->data = ngx_pnalloc(s->connection->pool, sizeof("65535") - 1); - if (v->data == NULL) { - return NGX_ERROR; - } - - port = ngx_inet_get_port(s->connection->sockaddr); - - if (port > 0 && port < 65536) { - v->len = ngx_sprintf(v->data, "%ui", port) - v->data; - } - - return NGX_OK; -} - - -static ngx_int_t -ngx_stream_variable_proxy_protocol_addr(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data) -{ - v->len = s->connection->proxy_protocol_addr.len; - v->valid = 1; - v->no_cacheable = 0; - v->not_found = 0; - v->data = s->connection->proxy_protocol_addr.data; - - return NGX_OK; -} - - -static ngx_int_t -ngx_stream_variable_proxy_protocol_port(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data) -{ - ngx_uint_t port; - - v->len = 0; - v->valid = 1; - v->no_cacheable = 0; - v->not_found = 0; - - v->data = ngx_pnalloc(s->connection->pool, sizeof("65535") - 1); - if (v->data == NULL) { - return NGX_ERROR; - } - - port = s->connection->proxy_protocol_port; - - if (port > 0 && port < 65536) { - v->len = ngx_sprintf(v->data, "%ui", port) - v->data; - } - - return NGX_OK; -} - - -static ngx_int_t -ngx_stream_variable_server_addr(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data) -{ - ngx_str_t str; - u_char addr[NGX_SOCKADDR_STRLEN]; - - str.len = NGX_SOCKADDR_STRLEN; - str.data = addr; - - if (ngx_connection_local_sockaddr(s->connection, &str, 0) != NGX_OK) { - return NGX_ERROR; - } - - str.data = ngx_pnalloc(s->connection->pool, str.len); - if (str.data == NULL) { - return NGX_ERROR; - } - - ngx_memcpy(str.data, addr, str.len); - - v->len = str.len; - v->valid = 1; - v->no_cacheable = 0; - v->not_found = 0; - v->data = str.data; - - return NGX_OK; -} - - -static ngx_int_t -ngx_stream_variable_server_port(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data) -{ - ngx_uint_t port; - - v->len = 0; - v->valid = 1; - v->no_cacheable = 0; - v->not_found = 0; - - if (ngx_connection_local_sockaddr(s->connection, NULL, 0) != NGX_OK) { - return NGX_ERROR; - } - - v->data = ngx_pnalloc(s->connection->pool, sizeof("65535") - 1); - if (v->data == NULL) { - return NGX_ERROR; - } - - port = ngx_inet_get_port(s->connection->local_sockaddr); - - if (port > 0 && port < 65536) { - v->len = ngx_sprintf(v->data, "%ui", port) - v->data; - } - - return NGX_OK; -} - - -static ngx_int_t -ngx_stream_variable_bytes(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data) -{ - u_char *p; - - p = ngx_pnalloc(s->connection->pool, NGX_OFF_T_LEN); - if (p == NULL) { - return NGX_ERROR; - } - - if (data == 1) { - v->len = ngx_sprintf(p, "%O", s->received) - p; - - } else { - v->len = ngx_sprintf(p, "%O", s->connection->sent) - p; - } - - v->valid = 1; - v->no_cacheable = 0; - v->not_found = 0; - v->data = p; - - return NGX_OK; -} - - -static ngx_int_t -ngx_stream_variable_session_time(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data) -{ - u_char *p; - ngx_time_t *tp; - ngx_msec_int_t ms; - - p = ngx_pnalloc(s->connection->pool, NGX_TIME_T_LEN + 4); - if (p == NULL) { - return NGX_ERROR; - } - - tp = ngx_timeofday(); - - ms = (ngx_msec_int_t) - ((tp->sec - s->start_sec) * 1000 + (tp->msec - s->start_msec)); - ms = ngx_max(ms, 0); - - v->len = ngx_sprintf(p, "%T.%03M", (time_t) ms / 1000, ms % 1000) - p; - v->valid = 1; - v->no_cacheable = 0; - v->not_found = 0; - v->data = p; - - return NGX_OK; -} - - -static ngx_int_t -ngx_stream_variable_status(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data) -{ - v->data = ngx_pnalloc(s->connection->pool, NGX_INT_T_LEN); - if (v->data == NULL) { - return NGX_ERROR; - } - - v->len = ngx_sprintf(v->data, "%03ui", s->status) - v->data; - v->valid = 1; - v->no_cacheable = 0; - v->not_found = 0; - - return NGX_OK; -} - - -static ngx_int_t -ngx_stream_variable_connection(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data) -{ - u_char *p; - - p = ngx_pnalloc(s->connection->pool, NGX_ATOMIC_T_LEN); - if (p == NULL) { - return NGX_ERROR; - } - - v->len = ngx_sprintf(p, "%uA", s->connection->number) - p; - v->valid = 1; - v->no_cacheable = 0; - v->not_found = 0; - v->data = p; - - return NGX_OK; -} - - -static ngx_int_t -ngx_stream_variable_nginx_version(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data) -{ - v->len = sizeof(NGINX_VERSION) - 1; - v->valid = 1; - v->no_cacheable = 0; - v->not_found = 0; - v->data = (u_char *) NGINX_VERSION; - - return NGX_OK; -} - - -static ngx_int_t -ngx_stream_variable_hostname(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data) -{ - v->len = ngx_cycle->hostname.len; - v->valid = 1; - v->no_cacheable = 0; - v->not_found = 0; - v->data = ngx_cycle->hostname.data; - - return NGX_OK; -} - - -static ngx_int_t -ngx_stream_variable_pid(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data) -{ - u_char *p; - - p = ngx_pnalloc(s->connection->pool, NGX_INT64_LEN); - if (p == NULL) { - return NGX_ERROR; - } - - v->len = ngx_sprintf(p, "%P", ngx_pid) - p; - v->valid = 1; - v->no_cacheable = 0; - v->not_found = 0; - v->data = p; - - return NGX_OK; -} - - -static ngx_int_t -ngx_stream_variable_msec(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data) -{ - u_char *p; - ngx_time_t *tp; - - p = ngx_pnalloc(s->connection->pool, NGX_TIME_T_LEN + 4); - if (p == NULL) { - return NGX_ERROR; - } - - tp = ngx_timeofday(); - - v->len = ngx_sprintf(p, "%T.%03M", tp->sec, tp->msec) - p; - v->valid = 1; - v->no_cacheable = 0; - v->not_found = 0; - v->data = p; - - return NGX_OK; -} - - -static ngx_int_t -ngx_stream_variable_time_iso8601(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data) -{ - u_char *p; - - p = ngx_pnalloc(s->connection->pool, ngx_cached_http_log_iso8601.len); - if (p == NULL) { - return NGX_ERROR; - } - - ngx_memcpy(p, ngx_cached_http_log_iso8601.data, - ngx_cached_http_log_iso8601.len); - - v->len = ngx_cached_http_log_iso8601.len; - v->valid = 1; - v->no_cacheable = 0; - v->not_found = 0; - v->data = p; - - return NGX_OK; -} - - -static ngx_int_t -ngx_stream_variable_time_local(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data) -{ - u_char *p; - - p = ngx_pnalloc(s->connection->pool, ngx_cached_http_log_time.len); - if (p == NULL) { - return NGX_ERROR; - } - - ngx_memcpy(p, ngx_cached_http_log_time.data, ngx_cached_http_log_time.len); - - v->len = ngx_cached_http_log_time.len; - v->valid = 1; - v->no_cacheable = 0; - v->not_found = 0; - v->data = p; - - return NGX_OK; -} - - -static ngx_int_t -ngx_stream_variable_protocol(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data) -{ - v->len = 3; - v->valid = 1; - v->no_cacheable = 0; - v->not_found = 0; - v->data = (u_char *) (s->connection->type == SOCK_DGRAM ? "UDP" : "TCP"); - - return NGX_OK; -} - - -void * -ngx_stream_map_find(ngx_stream_session_t *s, ngx_stream_map_t *map, - ngx_str_t *match) -{ - void *value; - u_char *low; - size_t len; - ngx_uint_t key; - - len = match->len; - - if (len) { - low = ngx_pnalloc(s->connection->pool, len); - if (low == NULL) { - return NULL; - } - - } else { - low = NULL; - } - - key = ngx_hash_strlow(low, match->data, len); - - value = ngx_hash_find_combined(&map->hash, key, low, len); - if (value) { - return value; - } - -#if (NGX_PCRE) - - if (len && map->nregex) { - ngx_int_t n; - ngx_uint_t i; - ngx_stream_map_regex_t *reg; - - reg = map->regex; - - for (i = 0; i < map->nregex; i++) { - - n = ngx_stream_regex_exec(s, reg[i].regex, match); - - if (n == NGX_OK) { - return reg[i].value; - } - - if (n == NGX_DECLINED) { - continue; - } - - /* NGX_ERROR */ - - return NULL; - } - } - -#endif - - return NULL; -} - - -#if (NGX_PCRE) - -static ngx_int_t -ngx_stream_variable_not_found(ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data) -{ - v->not_found = 1; - return NGX_OK; -} - - -ngx_stream_regex_t * -ngx_stream_regex_compile(ngx_conf_t *cf, ngx_regex_compile_t *rc) -{ - u_char *p; - size_t size; - ngx_str_t name; - ngx_uint_t i, n; - ngx_stream_variable_t *v; - ngx_stream_regex_t *re; - ngx_stream_regex_variable_t *rv; - ngx_stream_core_main_conf_t *cmcf; - - rc->pool = cf->pool; - - if (ngx_regex_compile(rc) != NGX_OK) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%V", &rc->err); - return NULL; - } - - re = ngx_pcalloc(cf->pool, sizeof(ngx_stream_regex_t)); - if (re == NULL) { - return NULL; - } - - re->regex = rc->regex; - re->ncaptures = rc->captures; - re->name = rc->pattern; - - cmcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_core_module); - cmcf->ncaptures = ngx_max(cmcf->ncaptures, re->ncaptures); - - n = (ngx_uint_t) rc->named_captures; - - if (n == 0) { - return re; - } - - rv = ngx_palloc(rc->pool, n * sizeof(ngx_stream_regex_variable_t)); - if (rv == NULL) { - return NULL; - } - - re->variables = rv; - re->nvariables = n; - - size = rc->name_size; - p = rc->names; - - for (i = 0; i < n; i++) { - rv[i].capture = 2 * ((p[0] << 8) + p[1]); - - name.data = &p[2]; - name.len = ngx_strlen(name.data); - - v = ngx_stream_add_variable(cf, &name, NGX_STREAM_VAR_CHANGEABLE); - if (v == NULL) { - return NULL; - } - - rv[i].index = ngx_stream_get_variable_index(cf, &name); - if (rv[i].index == NGX_ERROR) { - return NULL; - } - - v->get_handler = ngx_stream_variable_not_found; - - p += size; - } - - return re; -} - - -ngx_int_t -ngx_stream_regex_exec(ngx_stream_session_t *s, ngx_stream_regex_t *re, - ngx_str_t *str) -{ - ngx_int_t rc, index; - ngx_uint_t i, n, len; - ngx_stream_variable_value_t *vv; - ngx_stream_core_main_conf_t *cmcf; - - cmcf = ngx_stream_get_module_main_conf(s, ngx_stream_core_module); - - if (re->ncaptures) { - len = cmcf->ncaptures; - - if (s->captures == NULL) { - s->captures = ngx_palloc(s->connection->pool, len * sizeof(int)); - if (s->captures == NULL) { - return NGX_ERROR; - } - } - - } else { - len = 0; - } - - rc = ngx_regex_exec(re->regex, str, s->captures, len); - - if (rc == NGX_REGEX_NO_MATCHED) { - return NGX_DECLINED; - } - - if (rc < 0) { - ngx_log_error(NGX_LOG_ALERT, s->connection->log, 0, - ngx_regex_exec_n " failed: %i on \"%V\" using \"%V\"", - rc, str, &re->name); - return NGX_ERROR; - } - - for (i = 0; i < re->nvariables; i++) { - - n = re->variables[i].capture; - index = re->variables[i].index; - vv = &s->variables[index]; - - vv->len = s->captures[n + 1] - s->captures[n]; - vv->valid = 1; - vv->no_cacheable = 0; - vv->not_found = 0; - vv->data = &str->data[s->captures[n]]; - -#if (NGX_DEBUG) - { - ngx_stream_variable_t *v; - - v = cmcf->variables.elts; - - ngx_log_debug2(NGX_LOG_DEBUG_STREAM, s->connection->log, 0, - "stream regex set $%V to \"%v\"", &v[index].name, vv); - } -#endif - } - - s->ncaptures = rc * 2; - s->captures_data = str->data; - - return NGX_OK; -} - -#endif - - -ngx_int_t -ngx_stream_variables_add_core_vars(ngx_conf_t *cf) -{ - ngx_stream_variable_t *cv, *v; - ngx_stream_core_main_conf_t *cmcf; - - cmcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_core_module); - - cmcf->variables_keys = ngx_pcalloc(cf->temp_pool, - sizeof(ngx_hash_keys_arrays_t)); - if (cmcf->variables_keys == NULL) { - return NGX_ERROR; - } - - cmcf->variables_keys->pool = cf->pool; - cmcf->variables_keys->temp_pool = cf->pool; - - if (ngx_hash_keys_array_init(cmcf->variables_keys, NGX_HASH_SMALL) - != NGX_OK) - { - return NGX_ERROR; - } - - if (ngx_array_init(&cmcf->prefix_variables, cf->pool, 8, - sizeof(ngx_stream_variable_t)) - != NGX_OK) - { - return NGX_ERROR; - } - - for (cv = ngx_stream_core_variables; cv->name.len; cv++) { - v = ngx_stream_add_variable(cf, &cv->name, cv->flags); - if (v == NULL) { - return NGX_ERROR; - } - - *v = *cv; - } - - return NGX_OK; -} - - -ngx_int_t -ngx_stream_variables_init_vars(ngx_conf_t *cf) -{ - size_t len; - ngx_uint_t i, n; - ngx_hash_key_t *key; - ngx_hash_init_t hash; - ngx_stream_variable_t *v, *av, *pv; - ngx_stream_core_main_conf_t *cmcf; - - /* set the handlers for the indexed stream variables */ - - cmcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_core_module); - - v = cmcf->variables.elts; - pv = cmcf->prefix_variables.elts; - key = cmcf->variables_keys->keys.elts; - - for (i = 0; i < cmcf->variables.nelts; i++) { - - for (n = 0; n < cmcf->variables_keys->keys.nelts; n++) { - - av = key[n].value; - - if (v[i].name.len == key[n].key.len - && ngx_strncmp(v[i].name.data, key[n].key.data, v[i].name.len) - == 0) - { - v[i].get_handler = av->get_handler; - v[i].data = av->data; - - av->flags |= NGX_STREAM_VAR_INDEXED; - v[i].flags = av->flags; - - av->index = i; - - if (av->get_handler == NULL - || (av->flags & NGX_STREAM_VAR_WEAK)) - { - break; - } - - goto next; - } - } - - len = 0; - av = NULL; - - for (n = 0; n < cmcf->prefix_variables.nelts; n++) { - if (v[i].name.len >= pv[n].name.len && v[i].name.len > len - && ngx_strncmp(v[i].name.data, pv[n].name.data, pv[n].name.len) - == 0) - { - av = &pv[n]; - len = pv[n].name.len; - } - } - - if (av) { - v[i].get_handler = av->get_handler; - v[i].data = (uintptr_t) &v[i].name; - v[i].flags = av->flags; - - goto next; - } - - if (v[i].get_handler == NULL) { - ngx_log_error(NGX_LOG_EMERG, cf->log, 0, - "unknown \"%V\" variable", &v[i].name); - return NGX_ERROR; - } - - next: - continue; - } - - - for (n = 0; n < cmcf->variables_keys->keys.nelts; n++) { - av = key[n].value; - - if (av->flags & NGX_STREAM_VAR_NOHASH) { - key[n].key.data = NULL; - } - } - - - hash.hash = &cmcf->variables_hash; - hash.key = ngx_hash_key; - hash.max_size = cmcf->variables_hash_max_size; - hash.bucket_size = cmcf->variables_hash_bucket_size; - hash.name = "variables_hash"; - hash.pool = cf->pool; - hash.temp_pool = NULL; - - if (ngx_hash_init(&hash, cmcf->variables_keys->keys.elts, - cmcf->variables_keys->keys.nelts) - != NGX_OK) - { - return NGX_ERROR; - } - - cmcf->variables_keys = NULL; - - return NGX_OK; -} diff --git a/app/nginx/src/stream/ngx_stream_variables.h b/app/nginx/src/stream/ngx_stream_variables.h deleted file mode 100644 index 8155111..0000000 --- a/app/nginx/src/stream/ngx_stream_variables.h +++ /dev/null @@ -1,111 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) Nginx, Inc. - */ - - -#ifndef _NGX_STREAM_VARIABLES_H_INCLUDED_ -#define _NGX_STREAM_VARIABLES_H_INCLUDED_ - - -#include <ngx_config.h> -#include <ngx_core.h> -#include <ngx_stream.h> - - -typedef ngx_variable_value_t ngx_stream_variable_value_t; - -#define ngx_stream_variable(v) { sizeof(v) - 1, 1, 0, 0, 0, (u_char *) v } - -typedef struct ngx_stream_variable_s ngx_stream_variable_t; - -typedef void (*ngx_stream_set_variable_pt) (ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data); -typedef ngx_int_t (*ngx_stream_get_variable_pt) (ngx_stream_session_t *s, - ngx_stream_variable_value_t *v, uintptr_t data); - - -#define NGX_STREAM_VAR_CHANGEABLE 1 -#define NGX_STREAM_VAR_NOCACHEABLE 2 -#define NGX_STREAM_VAR_INDEXED 4 -#define NGX_STREAM_VAR_NOHASH 8 -#define NGX_STREAM_VAR_WEAK 16 -#define NGX_STREAM_VAR_PREFIX 32 - - -struct ngx_stream_variable_s { - ngx_str_t name; /* must be first to build the hash */ - ngx_stream_set_variable_pt set_handler; - ngx_stream_get_variable_pt get_handler; - uintptr_t data; - ngx_uint_t flags; - ngx_uint_t index; -}; - - -ngx_stream_variable_t *ngx_stream_add_variable(ngx_conf_t *cf, ngx_str_t *name, - ngx_uint_t flags); -ngx_int_t ngx_stream_get_variable_index(ngx_conf_t *cf, ngx_str_t *name); -ngx_stream_variable_value_t *ngx_stream_get_indexed_variable( - ngx_stream_session_t *s, ngx_uint_t index); -ngx_stream_variable_value_t *ngx_stream_get_flushed_variable( - ngx_stream_session_t *s, ngx_uint_t index); - -ngx_stream_variable_value_t *ngx_stream_get_variable(ngx_stream_session_t *s, - ngx_str_t *name, ngx_uint_t key); - - -#if (NGX_PCRE) - -typedef struct { - ngx_uint_t capture; - ngx_int_t index; -} ngx_stream_regex_variable_t; - - -typedef struct { - ngx_regex_t *regex; - ngx_uint_t ncaptures; - ngx_stream_regex_variable_t *variables; - ngx_uint_t nvariables; - ngx_str_t name; -} ngx_stream_regex_t; - - -typedef struct { - ngx_stream_regex_t *regex; - void *value; -} ngx_stream_map_regex_t; - - -ngx_stream_regex_t *ngx_stream_regex_compile(ngx_conf_t *cf, - ngx_regex_compile_t *rc); -ngx_int_t ngx_stream_regex_exec(ngx_stream_session_t *s, ngx_stream_regex_t *re, - ngx_str_t *str); - -#endif - - -typedef struct { - ngx_hash_combined_t hash; -#if (NGX_PCRE) - ngx_stream_map_regex_t *regex; - ngx_uint_t nregex; -#endif -} ngx_stream_map_t; - - -void *ngx_stream_map_find(ngx_stream_session_t *s, ngx_stream_map_t *map, - ngx_str_t *match); - - -ngx_int_t ngx_stream_variables_add_core_vars(ngx_conf_t *cf); -ngx_int_t ngx_stream_variables_init_vars(ngx_conf_t *cf); - - -extern ngx_stream_variable_value_t ngx_stream_variable_null_value; -extern ngx_stream_variable_value_t ngx_stream_variable_true_value; - - -#endif /* _NGX_STREAM_VARIABLES_H_INCLUDED_ */ diff --git a/app/nginx/src/stream/ngx_stream_write_filter_module.c b/app/nginx/src/stream/ngx_stream_write_filter_module.c deleted file mode 100644 index 8fdcd37..0000000 --- a/app/nginx/src/stream/ngx_stream_write_filter_module.c +++ /dev/null @@ -1,273 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) Nginx, Inc. - */ - - -#include <ngx_config.h> -#include <ngx_core.h> -#include <ngx_stream.h> - - -typedef struct { - ngx_chain_t *from_upstream; - ngx_chain_t *from_downstream; -} ngx_stream_write_filter_ctx_t; - - -static ngx_int_t ngx_stream_write_filter(ngx_stream_session_t *s, - ngx_chain_t *in, ngx_uint_t from_upstream); -static ngx_int_t ngx_stream_write_filter_init(ngx_conf_t *cf); - - -static ngx_stream_module_t ngx_stream_write_filter_module_ctx = { - NULL, /* preconfiguration */ - ngx_stream_write_filter_init, /* postconfiguration */ - - NULL, /* create main configuration */ - NULL, /* init main configuration */ - - NULL, /* create server configuration */ - NULL /* merge server configuration */ -}; - - -ngx_module_t ngx_stream_write_filter_module = { - NGX_MODULE_V1, - &ngx_stream_write_filter_module_ctx, /* module context */ - NULL, /* module directives */ - NGX_STREAM_MODULE, /* module type */ - NULL, /* init master */ - NULL, /* init module */ - NULL, /* init process */ - NULL, /* init thread */ - NULL, /* exit thread */ - NULL, /* exit process */ - NULL, /* exit master */ - NGX_MODULE_V1_PADDING -}; - - -static ngx_int_t -ngx_stream_write_filter(ngx_stream_session_t *s, ngx_chain_t *in, - ngx_uint_t from_upstream) -{ - off_t size; - ngx_uint_t last, flush, sync; - ngx_chain_t *cl, *ln, **ll, **out, *chain; - ngx_connection_t *c; - ngx_stream_write_filter_ctx_t *ctx; - - ctx = ngx_stream_get_module_ctx(s, ngx_stream_write_filter_module); - - if (ctx == NULL) { - ctx = ngx_pcalloc(s->connection->pool, - sizeof(ngx_stream_write_filter_ctx_t)); - if (ctx == NULL) { - return NGX_ERROR; - } - - ngx_stream_set_ctx(s, ctx, ngx_stream_write_filter_module); - } - - if (from_upstream) { - c = s->connection; - out = &ctx->from_upstream; - - } else { - c = s->upstream->peer.connection; - out = &ctx->from_downstream; - } - - if (c->error) { - return NGX_ERROR; - } - - size = 0; - flush = 0; - sync = 0; - last = 0; - ll = out; - - /* find the size, the flush point and the last link of the saved chain */ - - for (cl = *out; cl; cl = cl->next) { - ll = &cl->next; - - ngx_log_debug7(NGX_LOG_DEBUG_EVENT, c->log, 0, - "write old buf t:%d f:%d %p, pos %p, size: %z " - "file: %O, size: %O", - cl->buf->temporary, cl->buf->in_file, - cl->buf->start, cl->buf->pos, - cl->buf->last - cl->buf->pos, - cl->buf->file_pos, - cl->buf->file_last - cl->buf->file_pos); - -#if 1 - if (ngx_buf_size(cl->buf) == 0 && !ngx_buf_special(cl->buf)) { - ngx_log_error(NGX_LOG_ALERT, c->log, 0, - "zero size buf in writer " - "t:%d r:%d f:%d %p %p-%p %p %O-%O", - cl->buf->temporary, - cl->buf->recycled, - cl->buf->in_file, - cl->buf->start, - cl->buf->pos, - cl->buf->last, - cl->buf->file, - cl->buf->file_pos, - cl->buf->file_last); - - ngx_debug_point(); - return NGX_ERROR; - } -#endif - - size += ngx_buf_size(cl->buf); - - if (cl->buf->flush || cl->buf->recycled) { - flush = 1; - } - - if (cl->buf->sync) { - sync = 1; - } - - if (cl->buf->last_buf) { - last = 1; - } - } - - /* add the new chain to the existent one */ - - for (ln = in; ln; ln = ln->next) { - cl = ngx_alloc_chain_link(c->pool); - if (cl == NULL) { - return NGX_ERROR; - } - - cl->buf = ln->buf; - *ll = cl; - ll = &cl->next; - - ngx_log_debug7(NGX_LOG_DEBUG_EVENT, c->log, 0, - "write new buf t:%d f:%d %p, pos %p, size: %z " - "file: %O, size: %O", - cl->buf->temporary, cl->buf->in_file, - cl->buf->start, cl->buf->pos, - cl->buf->last - cl->buf->pos, - cl->buf->file_pos, - cl->buf->file_last - cl->buf->file_pos); - -#if 1 - if (ngx_buf_size(cl->buf) == 0 && !ngx_buf_special(cl->buf)) { - ngx_log_error(NGX_LOG_ALERT, c->log, 0, - "zero size buf in writer " - "t:%d r:%d f:%d %p %p-%p %p %O-%O", - cl->buf->temporary, - cl->buf->recycled, - cl->buf->in_file, - cl->buf->start, - cl->buf->pos, - cl->buf->last, - cl->buf->file, - cl->buf->file_pos, - cl->buf->file_last); - - ngx_debug_point(); - return NGX_ERROR; - } -#endif - - size += ngx_buf_size(cl->buf); - - if (cl->buf->flush || cl->buf->recycled) { - flush = 1; - } - - if (cl->buf->sync) { - sync = 1; - } - - if (cl->buf->last_buf) { - last = 1; - } - } - - *ll = NULL; - - ngx_log_debug3(NGX_LOG_DEBUG_STREAM, c->log, 0, - "stream write filter: l:%ui f:%ui s:%O", last, flush, size); - - if (size == 0 - && !(c->buffered & NGX_LOWLEVEL_BUFFERED) - && !(last && c->need_last_buf)) - { - if (last || flush || sync) { - for (cl = *out; cl; /* void */) { - ln = cl; - cl = cl->next; - ngx_free_chain(c->pool, ln); - } - - *out = NULL; - c->buffered &= ~NGX_STREAM_WRITE_BUFFERED; - - return NGX_OK; - } - - ngx_log_error(NGX_LOG_ALERT, c->log, 0, - "the stream output chain is empty"); - - ngx_debug_point(); - - return NGX_ERROR; - } - - chain = c->send_chain(c, *out, 0); - - ngx_log_debug1(NGX_LOG_DEBUG_STREAM, c->log, 0, - "stream write filter %p", chain); - - if (chain == NGX_CHAIN_ERROR) { - c->error = 1; - return NGX_ERROR; - } - - for (cl = *out; cl && cl != chain; /* void */) { - ln = cl; - cl = cl->next; - ngx_free_chain(c->pool, ln); - } - - *out = chain; - - if (chain) { - if (c->shared) { - ngx_log_error(NGX_LOG_ALERT, c->log, 0, - "shared connection is busy"); - return NGX_ERROR; - } - - c->buffered |= NGX_STREAM_WRITE_BUFFERED; - return NGX_AGAIN; - } - - c->buffered &= ~NGX_STREAM_WRITE_BUFFERED; - - if (c->buffered & NGX_LOWLEVEL_BUFFERED) { - return NGX_AGAIN; - } - - return NGX_OK; -} - - -static ngx_int_t -ngx_stream_write_filter_init(ngx_conf_t *cf) -{ - ngx_stream_top_filter = ngx_stream_write_filter; - - return NGX_OK; -} |