Mercurial > hg > nginx
diff src/mail/ngx_mail_handler.c @ 7794:12ea1de7d87c
Mail: parsing of the PROXY protocol from clients.
Activated with the "proxy_protocol" parameter of the "listen" directive.
Obtained information is passed to the auth_http script in Proxy-Protocol-Addr,
Proxy-Protocol-Port, Proxy-Protocol-Server-Addr, and Proxy-Protocol-Server-Port
headers.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Fri, 05 Mar 2021 17:16:24 +0300 |
parents | adee10c7fac8 |
children | ef4bdbbce57e |
line wrap: on
line diff
--- a/src/mail/ngx_mail_handler.c Fri Mar 05 17:16:23 2021 +0300 +++ b/src/mail/ngx_mail_handler.c Fri Mar 05 17:16:24 2021 +0300 @@ -11,6 +11,7 @@ #include <ngx_mail.h> +static void ngx_mail_proxy_protocol_handler(ngx_event_t *rev); static void ngx_mail_init_session_handler(ngx_event_t *rev); static void ngx_mail_init_session(ngx_connection_t *c); @@ -168,6 +169,22 @@ rev = c->read; rev->handler = ngx_mail_init_session_handler; + if (addr_conf->proxy_protocol) { + c->log->action = "reading PROXY protocol"; + + rev->handler = ngx_mail_proxy_protocol_handler; + + if (!rev->ready) { + ngx_add_timer(rev, cscf->timeout); + + if (ngx_handle_read_event(rev, 0) != NGX_OK) { + ngx_mail_close_connection(c); + } + + return; + } + } + if (ngx_use_accept_mutex) { ngx_post_event(rev, &ngx_posted_events); return; @@ -178,6 +195,76 @@ static void +ngx_mail_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_mail_session_t *s; + ngx_mail_core_srv_conf_t *cscf; + + c = rev->data; + s = c->data; + + ngx_log_debug0(NGX_LOG_DEBUG_MAIL, c->log, 0, + "mail PROXY protocol handler"); + + if (rev->timedout) { + ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out"); + c->timedout = 1; + ngx_mail_close_connection(c); + return; + } + + n = recv(c->fd, (char *) buf, sizeof(buf), MSG_PEEK); + + err = ngx_socket_errno; + + ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0, "recv(): %z", n); + + if (n == -1) { + if (err == NGX_EAGAIN) { + rev->ready = 0; + + if (!rev->timer_set) { + cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); + ngx_add_timer(rev, cscf->timeout); + } + + if (ngx_handle_read_event(rev, 0) != NGX_OK) { + ngx_mail_close_connection(c); + } + + return; + } + + ngx_connection_error(c, err, "recv() failed"); + + ngx_mail_close_connection(c); + return; + } + + p = ngx_proxy_protocol_read(c, buf, buf + n); + + if (p == NULL) { + ngx_mail_close_connection(c); + return; + } + + size = p - buf; + + if (c->recv(c, buf, size) != (ssize_t) size) { + ngx_mail_close_connection(c); + return; + } + + ngx_mail_init_session_handler(rev); +} + + +static void ngx_mail_init_session_handler(ngx_event_t *rev) { ngx_connection_t *c; @@ -242,9 +329,10 @@ s = c->data; - cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); - - ngx_add_timer(c->read, cscf->timeout); + if (!c->read->timer_set) { + cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); + ngx_add_timer(c->read, cscf->timeout); + } c->ssl->handler = ngx_mail_ssl_handshake_handler;