[nginx] Mail: POP3 pipelining support.

Maxim Dounin mdounin at mdounin.ru
Wed May 19 01:27:18 UTC 2021


details:   https://hg.nginx.org/nginx/rev/815c63581be4
branches:  
changeset: 7838:815c63581be4
user:      Maxim Dounin <mdounin at mdounin.ru>
date:      Wed May 19 03:13:18 2021 +0300
description:
Mail: POP3 pipelining support.

The change is mostly the same as the SMTP one (04e43d03e153 and 3f5d0af4e40a),
and ensures that nginx is able to properly handle or reject multiple POP3
commands, as required by the PIPELINING capability (RFC 2449).  The s->cmd
field is not really used and set for consistency.

diffstat:

 src/mail/ngx_mail_parse.c        |  32 +++++++++++++++++++++++++++++---
 src/mail/ngx_mail_pop3_handler.c |  15 ++++++++++++---
 src/mail/ngx_mail_proxy_module.c |   4 ++++
 3 files changed, 45 insertions(+), 6 deletions(-)

diffs (128 lines):

diff -r ba8a8299b904 -r 815c63581be4 src/mail/ngx_mail_parse.c
--- a/src/mail/ngx_mail_parse.c	Wed May 19 03:13:17 2021 +0300
+++ b/src/mail/ngx_mail_parse.c	Wed May 19 03:13:18 2021 +0300
@@ -21,6 +21,8 @@ ngx_mail_pop3_parse_command(ngx_mail_ses
     ngx_str_t  *arg;
     enum {
         sw_start = 0,
+        sw_command,
+        sw_invalid,
         sw_spaces_before_argument,
         sw_argument,
         sw_almost_done
@@ -35,8 +37,14 @@ ngx_mail_pop3_parse_command(ngx_mail_ses
 
         /* POP3 command */
         case sw_start:
+            s->cmd_start = p;
+            state = sw_command;
+
+            /* fall through */
+
+        case sw_command:
             if (ch == ' ' || ch == CR || ch == LF) {
-                c = s->buffer->start;
+                c = s->cmd_start;
 
                 if (p - c == 4) {
 
@@ -85,6 +93,9 @@ ngx_mail_pop3_parse_command(ngx_mail_ses
                     goto invalid;
                 }
 
+                s->cmd.data = s->cmd_start;
+                s->cmd.len = p - s->cmd_start;
+
                 switch (ch) {
                 case ' ':
                     state = sw_spaces_before_argument;
@@ -104,6 +115,9 @@ ngx_mail_pop3_parse_command(ngx_mail_ses
 
             break;
 
+        case sw_invalid:
+            goto invalid;
+
         case sw_spaces_before_argument:
             switch (ch) {
             case ' ':
@@ -205,10 +219,22 @@ done:
 
 invalid:
 
-    s->state = sw_start;
+    s->state = sw_invalid;
     s->arg_start = NULL;
 
-    return NGX_MAIL_PARSE_INVALID_COMMAND;
+    /* skip invalid command till LF */
+
+    for ( /* void */ ; p < s->buffer->last; p++) {
+        if (*p == LF) {
+            s->state = sw_start;
+            s->buffer->pos = p + 1;
+            return NGX_MAIL_PARSE_INVALID_COMMAND;
+        }
+    }
+
+    s->buffer->pos = p;
+
+    return NGX_AGAIN;
 }
 
 
diff -r ba8a8299b904 -r 815c63581be4 src/mail/ngx_mail_pop3_handler.c
--- a/src/mail/ngx_mail_pop3_handler.c	Wed May 19 03:13:17 2021 +0300
+++ b/src/mail/ngx_mail_pop3_handler.c	Wed May 19 03:13:18 2021 +0300
@@ -262,6 +262,10 @@ ngx_mail_pop3_auth_state(ngx_event_t *re
         }
     }
 
+    if (s->buffer->pos < s->buffer->last) {
+        s->blocked = 1;
+    }
+
     switch (rc) {
 
     case NGX_DONE:
@@ -283,11 +287,14 @@ ngx_mail_pop3_auth_state(ngx_event_t *re
     case NGX_OK:
 
         s->args.nelts = 0;
-        s->buffer->pos = s->buffer->start;
-        s->buffer->last = s->buffer->start;
+
+        if (s->buffer->pos == s->buffer->last) {
+            s->buffer->pos = s->buffer->start;
+            s->buffer->last = s->buffer->start;
+        }
 
         if (s->state) {
-            s->arg_start = s->buffer->start;
+            s->arg_start = s->buffer->pos;
         }
 
         if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
@@ -400,6 +407,8 @@ ngx_mail_pop3_stls(ngx_mail_session_t *s
     if (c->ssl == NULL) {
         sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module);
         if (sslcf->starttls) {
+            s->buffer->pos = s->buffer->start;
+            s->buffer->last = s->buffer->start;
             c->read->handler = ngx_mail_starttls_handler;
             return NGX_OK;
         }
diff -r ba8a8299b904 -r 815c63581be4 src/mail/ngx_mail_proxy_module.c
--- a/src/mail/ngx_mail_proxy_module.c	Wed May 19 03:13:17 2021 +0300
+++ b/src/mail/ngx_mail_proxy_module.c	Wed May 19 03:13:18 2021 +0300
@@ -327,6 +327,10 @@ ngx_mail_proxy_pop3_handler(ngx_event_t 
         c->log->action = NULL;
         ngx_log_error(NGX_LOG_INFO, c->log, 0, "client logged in");
 
+        if (s->buffer->pos < s->buffer->last) {
+            ngx_post_event(c->write, &ngx_posted_events);
+        }
+
         ngx_mail_proxy_handler(s->connection->write);
 
         return;


More information about the nginx-devel mailing list