diff options
author | Sergey Kandaurov <pluknet@nginx.com> | 2021-03-10 15:39:01 +0300 |
---|---|---|
committer | Sergey Kandaurov <pluknet@nginx.com> | 2021-03-10 15:39:01 +0300 |
commit | 02b52e4c0b71b960ce426ef80fefa359e5e6b42e (patch) | |
tree | eb36f3f05641ada335fc88ff4f04d6e75555010c /src/mail/ngx_mail_handler.c | |
parent | b7433b15fcdd97cc0d8b45407a4af1520663e54f (diff) | |
parent | 0026dded46da04b6b4522c5887bed5fceb4eda11 (diff) | |
download | nginx-02b52e4c0b71b960ce426ef80fefa359e5e6b42e.tar.gz nginx-02b52e4c0b71b960ce426ef80fefa359e5e6b42e.zip |
Merged with the default branch.
Diffstat (limited to 'src/mail/ngx_mail_handler.c')
-rw-r--r-- | src/mail/ngx_mail_handler.c | 135 |
1 files changed, 126 insertions, 9 deletions
diff --git a/src/mail/ngx_mail_handler.c b/src/mail/ngx_mail_handler.c index 803a247d2..b9010535b 100644 --- a/src/mail/ngx_mail_handler.c +++ b/src/mail/ngx_mail_handler.c @@ -11,6 +11,8 @@ #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); #if (NGX_MAIL_SSL) @@ -26,6 +28,7 @@ ngx_mail_init_connection(ngx_connection_t *c) { size_t len; ngx_uint_t i; + ngx_event_t *rev; ngx_mail_port_t *port; struct sockaddr *sa; struct sockaddr_in *sin; @@ -129,6 +132,10 @@ ngx_mail_init_connection(ngx_connection_t *c) s->main_conf = addr_conf->ctx->main_conf; s->srv_conf = addr_conf->ctx->srv_conf; +#if (NGX_MAIL_SSL) + s->ssl = addr_conf->ssl; +#endif + s->addr_text = &addr_conf->addr_text; c->data = s; @@ -159,13 +166,125 @@ ngx_mail_init_connection(ngx_connection_t *c) c->log_error = NGX_ERROR_INFO; + 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; + } + + rev->handler(rev); +} + + +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; + } + + if (ngx_mail_realip_handler(s) != NGX_OK) { + 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; + ngx_mail_session_t *s; + + c = rev->data; + s = c->data; + #if (NGX_MAIL_SSL) { ngx_mail_ssl_conf_t *sslcf; sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module); - if (sslcf->enable || addr_conf->ssl) { + if (sslcf->enable || s->ssl) { c->log->action = "SSL handshaking"; ngx_mail_ssl_init_connection(&sslcf->ssl, c); @@ -215,9 +334,10 @@ ngx_mail_ssl_init_connection(ngx_ssl_t *ssl, ngx_connection_t *c) 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; @@ -338,6 +458,8 @@ ngx_mail_init_session(ngx_connection_t *c) s = c->data; + c->log->action = "sending client greeting line"; + cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); s->protocol = cscf->protocol->type; @@ -722,11 +844,6 @@ ngx_mail_read_command(ngx_mail_session_t *s, ngx_connection_t *c) } if (n == NGX_AGAIN) { - if (ngx_handle_read_event(c->read, 0) != NGX_OK) { - ngx_mail_session_internal_server_error(s); - return NGX_ERROR; - } - if (s->buffer->pos == s->buffer->last) { return NGX_AGAIN; } |