mirror of
https://github.com/nginx/nginx.git
synced 2025-01-19 01:42:58 +08:00
Stream: variables in proxy_pass and proxy_ssl_name.
This commit is contained in:
parent
a85edfeef6
commit
74305af672
@ -37,7 +37,7 @@ typedef struct {
|
||||
ngx_flag_t ssl_session_reuse;
|
||||
ngx_uint_t ssl_protocols;
|
||||
ngx_str_t ssl_ciphers;
|
||||
ngx_str_t ssl_name;
|
||||
ngx_stream_complex_value_t *ssl_name;
|
||||
ngx_flag_t ssl_server_name;
|
||||
|
||||
ngx_flag_t ssl_verify;
|
||||
@ -52,14 +52,18 @@ typedef struct {
|
||||
#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,
|
||||
@ -246,7 +250,7 @@ static ngx_command_t ngx_stream_proxy_commands[] = {
|
||||
|
||||
{ ngx_string("proxy_ssl_name"),
|
||||
NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_str_slot,
|
||||
ngx_stream_set_complex_value_slot,
|
||||
NGX_STREAM_SRV_CONF_OFFSET,
|
||||
offsetof(ngx_stream_proxy_srv_conf_t, ssl_name),
|
||||
NULL },
|
||||
@ -344,11 +348,16 @@ ngx_module_t ngx_stream_proxy_module = {
|
||||
static void
|
||||
ngx_stream_proxy_handler(ngx_stream_session_t *s)
|
||||
{
|
||||
u_char *p;
|
||||
ngx_connection_t *c;
|
||||
ngx_stream_upstream_t *u;
|
||||
ngx_stream_proxy_srv_conf_t *pscf;
|
||||
ngx_stream_upstream_srv_conf_t *uscf;
|
||||
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;
|
||||
|
||||
@ -377,7 +386,161 @@ ngx_stream_proxy_handler(ngx_stream_session_t *s)
|
||||
|
||||
u->peer.type = c->type;
|
||||
|
||||
uscf = pscf->upstream;
|
||||
u->proxy_protocol = pscf->proxy_protocol;
|
||||
u->start_sec = ngx_time();
|
||||
|
||||
c->write->handler = ngx_stream_proxy_downstream_handler;
|
||||
c->read->handler = ngx_stream_proxy_downstream_handler;
|
||||
|
||||
if (c->type == SOCK_STREAM) {
|
||||
p = ngx_pnalloc(c->pool, pscf->buffer_size);
|
||||
if (p == NULL) {
|
||||
ngx_stream_proxy_finalize(s, NGX_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 (u->proxy_protocol
|
||||
#if (NGX_STREAM_SSL)
|
||||
&& pscf->ssl == NULL
|
||||
#endif
|
||||
&& pscf->buffer_size >= NGX_PROXY_PROTOCOL_MAX_HEADER)
|
||||
{
|
||||
/* optimization for a typical case */
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0,
|
||||
"stream proxy send PROXY protocol header");
|
||||
|
||||
p = ngx_proxy_protocol_write(c, u->downstream_buf.last,
|
||||
u->downstream_buf.end);
|
||||
if (p == NULL) {
|
||||
ngx_stream_proxy_finalize(s, NGX_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
u->downstream_buf.last = p;
|
||||
u->proxy_protocol = 0;
|
||||
}
|
||||
|
||||
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_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;
|
||||
|
||||
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_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ngx_stream_upstream_create_round_robin_peer(s, u->resolved)
|
||||
!= NGX_OK)
|
||||
{
|
||||
ngx_stream_proxy_finalize(s, NGX_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
ngx_stream_proxy_connect(s);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
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->port == 0) {
|
||||
ngx_log_error(NGX_LOG_ERR, c->log, 0,
|
||||
"no port in upstream \"%V\"", host);
|
||||
ngx_stream_proxy_finalize(s, NGX_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_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_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_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_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
#if (NGX_HTTP_SSL)
|
||||
u->ssl_name = uscf->host;
|
||||
#endif
|
||||
|
||||
if (uscf->peer.init(s, uscf) != NGX_OK) {
|
||||
ngx_stream_proxy_finalize(s, NGX_ERROR);
|
||||
@ -392,55 +555,58 @@ ngx_stream_proxy_handler(ngx_stream_session_t *s)
|
||||
u->peer.tries = pscf->next_upstream_tries;
|
||||
}
|
||||
|
||||
u->proxy_protocol = pscf->proxy_protocol;
|
||||
u->start_sec = ngx_time();
|
||||
ngx_stream_proxy_connect(s);
|
||||
}
|
||||
|
||||
c->write->handler = ngx_stream_proxy_downstream_handler;
|
||||
c->read->handler = ngx_stream_proxy_downstream_handler;
|
||||
|
||||
if (c->type == SOCK_DGRAM) {
|
||||
ngx_stream_proxy_connect(s);
|
||||
return;
|
||||
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;
|
||||
}
|
||||
|
||||
p = ngx_pnalloc(c->pool, pscf->buffer_size);
|
||||
if (p == NULL) {
|
||||
ngx_stream_proxy_finalize(s, NGX_ERROR);
|
||||
return;
|
||||
}
|
||||
ngx_memzero(&url, sizeof(ngx_url_t));
|
||||
|
||||
u->downstream_buf.start = p;
|
||||
u->downstream_buf.end = p + pscf->buffer_size;
|
||||
u->downstream_buf.pos = p;
|
||||
u->downstream_buf.last = p;
|
||||
url.url = host;
|
||||
url.no_resolve = 1;
|
||||
|
||||
if (u->proxy_protocol
|
||||
#if (NGX_STREAM_SSL)
|
||||
&& pscf->ssl == NULL
|
||||
#endif
|
||||
&& pscf->buffer_size >= NGX_PROXY_PROTOCOL_MAX_HEADER)
|
||||
{
|
||||
/* optimization for a typical case */
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0,
|
||||
"stream proxy send PROXY protocol header");
|
||||
|
||||
p = ngx_proxy_protocol_write(c, u->downstream_buf.last,
|
||||
u->downstream_buf.end);
|
||||
if (p == NULL) {
|
||||
ngx_stream_proxy_finalize(s, NGX_ERROR);
|
||||
return;
|
||||
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);
|
||||
}
|
||||
|
||||
u->downstream_buf.last = p;
|
||||
u->proxy_protocol = 0;
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (c->read->ready) {
|
||||
ngx_post_event(c->read, &ngx_posted_events);
|
||||
u = s->upstream;
|
||||
|
||||
u->resolved = ngx_pcalloc(s->connection->pool,
|
||||
sizeof(ngx_stream_upstream_resolved_t));
|
||||
if (u->resolved == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_stream_proxy_connect(s);
|
||||
if (url.addrs && url.addrs[0].sockaddr) {
|
||||
u->resolved->sockaddr = url.addrs[0].sockaddr;
|
||||
u->resolved->socklen = url.addrs[0].socklen;
|
||||
u->resolved->naddrs = 1;
|
||||
u->resolved->host = url.addrs[0].name;
|
||||
|
||||
} else {
|
||||
u->resolved->host = url.host;
|
||||
}
|
||||
|
||||
u->resolved->port = url.port;
|
||||
u->resolved->no_port = url.no_port;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
@ -883,10 +1049,13 @@ ngx_stream_proxy_ssl_name(ngx_stream_session_t *s)
|
||||
|
||||
u = s->upstream;
|
||||
|
||||
name = pscf->ssl_name;
|
||||
if (pscf->ssl_name) {
|
||||
if (ngx_stream_complex_value(s, pscf->ssl_name, &name) != NGX_OK) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (name.len == 0) {
|
||||
name = pscf->upstream->host;
|
||||
} else {
|
||||
name = u->ssl_name;
|
||||
}
|
||||
|
||||
if (name.len == 0) {
|
||||
@ -975,6 +1144,75 @@ ngx_stream_proxy_downstream_handler(ngx_event_t *ev)
|
||||
}
|
||||
|
||||
|
||||
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_HTTP, 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_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_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)
|
||||
{
|
||||
@ -1397,6 +1635,11 @@ ngx_stream_proxy_finalize(ngx_stream_session_t *s, ngx_int_t rc)
|
||||
goto noupstream;
|
||||
}
|
||||
|
||||
if (u->resolved && u->resolved->ctx) {
|
||||
ngx_resolve_name_done(u->resolved->ctx);
|
||||
u->resolved->ctx = NULL;
|
||||
}
|
||||
|
||||
if (u->peer.free && u->peer.sockaddr) {
|
||||
u->peer.free(&u->peer, u->peer.data, 0);
|
||||
u->peer.sockaddr = NULL;
|
||||
@ -1471,7 +1714,7 @@ ngx_stream_proxy_create_srv_conf(ngx_conf_t *cf)
|
||||
*
|
||||
* conf->ssl_protocols = 0;
|
||||
* conf->ssl_ciphers = { 0, NULL };
|
||||
* conf->ssl_name = { 0, NULL };
|
||||
* conf->ssl_name = NULL;
|
||||
* conf->ssl_trusted_certificate = { 0, NULL };
|
||||
* conf->ssl_crl = { 0, NULL };
|
||||
* conf->ssl_certificate = { 0, NULL };
|
||||
@ -1479,6 +1722,7 @@ ngx_stream_proxy_create_srv_conf(ngx_conf_t *cf)
|
||||
*
|
||||
* conf->ssl = NULL;
|
||||
* conf->upstream = NULL;
|
||||
* conf->upstream_value = NULL;
|
||||
*/
|
||||
|
||||
conf->connect_timeout = NGX_CONF_UNSET_MSEC;
|
||||
@ -1555,7 +1799,9 @@ ngx_stream_proxy_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||
|
||||
ngx_conf_merge_str_value(conf->ssl_ciphers, prev->ssl_ciphers, "DEFAULT");
|
||||
|
||||
ngx_conf_merge_str_value(conf->ssl_name, prev->ssl_name, "");
|
||||
if (conf->ssl_name == NULL) {
|
||||
conf->ssl_name = prev->ssl_name;
|
||||
}
|
||||
|
||||
ngx_conf_merge_value(conf->ssl_server_name, prev->ssl_server_name, 0);
|
||||
|
||||
@ -1665,11 +1911,13 @@ 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_core_srv_conf_t *cscf;
|
||||
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) {
|
||||
if (pscf->upstream || pscf->upstream_value) {
|
||||
return "is duplicate";
|
||||
}
|
||||
|
||||
@ -1681,6 +1929,28 @@ ngx_stream_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
|
||||
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;
|
||||
|
@ -78,6 +78,21 @@ struct ngx_stream_upstream_srv_conf_s {
|
||||
};
|
||||
|
||||
|
||||
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_resolver_ctx_t *ctx;
|
||||
} ngx_stream_upstream_resolved_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_peer_connection_t peer;
|
||||
ngx_buf_t downstream_buf;
|
||||
@ -88,6 +103,7 @@ typedef struct {
|
||||
#if (NGX_STREAM_SSL)
|
||||
ngx_str_t ssl_name;
|
||||
#endif
|
||||
ngx_stream_upstream_resolved_t *resolved;
|
||||
unsigned connected:1;
|
||||
unsigned proxy_protocol:1;
|
||||
} ngx_stream_upstream_t;
|
||||
|
@ -23,6 +23,10 @@ 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
|
||||
|
||||
@ -292,6 +296,123 @@ ngx_stream_upstream_init_round_robin_peer(ngx_stream_session_t *s,
|
||||
}
|
||||
|
||||
|
||||
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->host;
|
||||
peer[0].weight = 1;
|
||||
peer[0].effective_weight = 1;
|
||||
peer[0].current_weight = 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_fails = 1;
|
||||
peer[i].fail_timeout = 10;
|
||||
*peerp = &peer[i];
|
||||
peerp = &peer[i].next;
|
||||
}
|
||||
}
|
||||
|
||||
rrp->peers = peers;
|
||||
rrp->current = NULL;
|
||||
|
||||
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)
|
||||
{
|
||||
@ -699,4 +820,18 @@ ngx_stream_upstream_save_round_robin_peer_session(ngx_peer_connection_t *pc,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
|
@ -130,6 +130,8 @@ 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,
|
||||
|
Loading…
Reference in New Issue
Block a user