]> git.kaiwu.me - nginx.git/commitdiff
Mail: fixed reading with fully filled buffer (ticket #2159).
authorMaxim Dounin <mdounin@mdounin.ru>
Wed, 21 Apr 2021 20:24:59 +0000 (23:24 +0300)
committerMaxim Dounin <mdounin@mdounin.ru>
Wed, 21 Apr 2021 20:24:59 +0000 (23:24 +0300)
With SMTP pipelining, ngx_mail_read_command() can be called with s->buffer
without any space available, to parse additional commands received to the
buffer on previous calls.  Previously, this resulted in recv() being called
with zero length, resulting in zero being returned, which was interpreted
as a connection close by the client, so nginx silently closed connection.

Fix is to avoid calling c->recv() if there is no free space in the buffer,
but continue parsing of the already received commands.

src/mail/ngx_mail_handler.c

index 0aaa0e78610710e09d47ee1e9363cfd833e753a4..57503e9a66daac808e67643335c61e68bccdbba4 100644 (file)
@@ -833,20 +833,23 @@ ngx_mail_read_command(ngx_mail_session_t *s, ngx_connection_t *c)
     ngx_str_t                  l;
     ngx_mail_core_srv_conf_t  *cscf;
 
-    n = c->recv(c, s->buffer->last, s->buffer->end - s->buffer->last);
+    if (s->buffer->last < s->buffer->end) {
 
-    if (n == NGX_ERROR || n == 0) {
-        ngx_mail_close_connection(c);
-        return NGX_ERROR;
-    }
+        n = c->recv(c, s->buffer->last, s->buffer->end - s->buffer->last);
 
-    if (n > 0) {
-        s->buffer->last += n;
-    }
+        if (n == NGX_ERROR || n == 0) {
+            ngx_mail_close_connection(c);
+            return NGX_ERROR;
+        }
 
-    if (n == NGX_AGAIN) {
-        if (s->buffer->pos == s->buffer->last) {
-            return NGX_AGAIN;
+        if (n > 0) {
+            s->buffer->last += n;
+        }
+
+        if (n == NGX_AGAIN) {
+            if (s->buffer->pos == s->buffer->last) {
+                return NGX_AGAIN;
+            }
         }
     }