Hello! On Tue, Jan 15, 2019 at 01:28:52PM +0200, Dmitriy M. wrote:
> Спасибо за развернутый ответ и патч. > > Мы модифицировали патч, добавив логику перебора IP исходящих соединений. В > нашем случае нам достаточно 4х IP, т.е.: > > proxy_bind 10.10.0.1 10.10.0.2 10.10.0.3 10.10.0.4; > > Вроде работает пока, балансируя соединения с 4 IP поровну. Нет, так мы точно делать не будем. Если хочется вращать много локальных адресов в рамках одного сервера - то вот патч, который позволяет задать локальный адрес из auth-скрипта с помощью заголовка Auth-Bind: # HG changeset patch # User Maxim Dounin <mdou...@mdounin.ru> # Date 1547559561 -10800 # Tue Jan 15 16:39:21 2019 +0300 # Node ID 7d052f39bf8c8fb028569e290f67edf4bacb3252 # Parent 6d15e452fa2eaf19408e24a0d0fcc3a31344a289 Mail: Auth-Bind header. diff --git a/src/mail/ngx_mail.h b/src/mail/ngx_mail.h --- a/src/mail/ngx_mail.h +++ b/src/mail/ngx_mail.h @@ -400,7 +400,8 @@ char *ngx_mail_capabilities(ngx_conf_t * /* STUB */ -void ngx_mail_proxy_init(ngx_mail_session_t *s, ngx_addr_t *peer); +void ngx_mail_proxy_init(ngx_mail_session_t *s, ngx_addr_t *peer, + ngx_addr_t *local); void ngx_mail_auth_http_init(ngx_mail_session_t *s); /**/ diff --git a/src/mail/ngx_mail_auth_http_module.c b/src/mail/ngx_mail_auth_http_module.c --- a/src/mail/ngx_mail_auth_http_module.c +++ b/src/mail/ngx_mail_auth_http_module.c @@ -53,6 +53,7 @@ struct ngx_mail_auth_http_ctx_s { ngx_str_t err; ngx_str_t errmsg; ngx_str_t errcode; + ngx_str_t bind; time_t sleep; @@ -467,7 +468,7 @@ ngx_mail_auth_http_process_headers(ngx_m time_t timer; size_t len, size; ngx_int_t rc, port, n; - ngx_addr_t *peer; + ngx_addr_t *peer, *local; ngx_log_debug0(NGX_LOG_DEBUG_MAIL, s->connection->log, 0, "mail auth http process headers"); @@ -677,6 +678,18 @@ ngx_mail_auth_http_process_headers(ngx_m continue; } + if (len == sizeof("Auth-Bind") - 1 + && ngx_strncasecmp(ctx->header_name_start, + (u_char *) "Auth-Bind", + sizeof("Auth-Bind") - 1) + == 0) + { + ctx->bind.len = ctx->header_end - ctx->header_start; + ctx->bind.data = ctx->header_start; + + continue; + } + /* ignore other headers */ continue; @@ -772,6 +785,52 @@ ngx_mail_auth_http_process_headers(ngx_m return; } + if (ctx->bind.len) { + + local = ngx_palloc(s->connection->pool, sizeof(ngx_addr_t)); + if (local == NULL) { + ngx_close_connection(ctx->peer.connection); + ngx_destroy_pool(ctx->pool); + ngx_mail_session_internal_server_error(s); + return; + } + + rc = ngx_parse_addr_port(s->connection->pool, local, + ctx->bind.data, ctx->bind.len); + + switch (rc) { + case NGX_OK: + break; + + case NGX_DECLINED: + ngx_log_error(NGX_LOG_ERR, s->connection->log, 0, + "auth http server %V sent invalid bind " + "address:\"%V\"", + ctx->peer.name, &ctx->bind); + /* fall through */ + + default: + ngx_destroy_pool(ctx->pool); + ngx_mail_session_internal_server_error(s); + return; + } + + local->name.len = ctx->bind.len; + + local->name.data = ngx_pnalloc(s->connection->pool, + local->name.len); + if (local->name.data == NULL) { + ngx_destroy_pool(ctx->pool); + ngx_mail_session_internal_server_error(s); + return; + } + + ngx_memcpy(local->name.data, ctx->bind.data, ctx->bind.len); + + } else { + local = NULL; + } + peer = ngx_pcalloc(s->connection->pool, sizeof(ngx_addr_t)); if (peer == NULL) { ngx_destroy_pool(ctx->pool); @@ -832,7 +891,7 @@ ngx_mail_auth_http_process_headers(ngx_m ngx_memcpy(peer->name.data + len, ctx->port.data, ctx->port.len); ngx_destroy_pool(ctx->pool); - ngx_mail_proxy_init(s, peer); + ngx_mail_proxy_init(s, peer, local); return; } diff --git a/src/mail/ngx_mail_proxy_module.c b/src/mail/ngx_mail_proxy_module.c --- a/src/mail/ngx_mail_proxy_module.c +++ b/src/mail/ngx_mail_proxy_module.c @@ -109,7 +109,7 @@ static u_char smtp_auth_ok[] = "235 2.0 void -ngx_mail_proxy_init(ngx_mail_session_t *s, ngx_addr_t *peer) +ngx_mail_proxy_init(ngx_mail_session_t *s, ngx_addr_t *peer, ngx_addr_t *local) { ngx_int_t rc; ngx_mail_proxy_ctx_t *p; @@ -134,6 +134,7 @@ ngx_mail_proxy_init(ngx_mail_session_t * p->upstream.get = ngx_event_get_peer; p->upstream.log = s->connection->log; p->upstream.log_error = NGX_ERROR_ERR; + p->upstream.local = local; rc = ngx_event_connect_peer(&p->upstream); -- Maxim Dounin http://mdounin.ru/ _______________________________________________ nginx-ru mailing list nginx-ru@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-ru