]> git.kaiwu.me - nginx.git/commitdiff
SSL: reworked posted next events.
authorMaxim Dounin <mdounin@mdounin.ru>
Tue, 24 Dec 2019 14:24:59 +0000 (17:24 +0300)
committerMaxim Dounin <mdounin@mdounin.ru>
Tue, 24 Dec 2019 14:24:59 +0000 (17:24 +0300)
Introduced in 9d2ad2fb4423 available bytes handling in SSL relied
on connection read handler being overwritten to set the ready flag
and the amount of available bytes.  This approach is, however, does
not work properly when connection read handler is changed, for example,
when switching to a next pipelined request, and can result in unexpected
connection timeouts, see here:

http://mailman.nginx.org/pipermail/nginx-devel/2019-December/012825.html

Fix is to introduce ngx_event_process_posted_next() instead, which
will set ready and available regardless of how event handler is set.

src/event/ngx_event.c
src/event/ngx_event_openssl.c
src/event/ngx_event_openssl.h
src/event/ngx_event_posted.c
src/event/ngx_event_posted.h

index 6e19f311b61c02eb8e344a8cdb30ce9339d79e90..54ab605e37ec81c960be5f9942a80ae37b36e11f 100644 (file)
@@ -238,8 +238,6 @@ ngx_process_events_and_timers(ngx_cycle_t *cycle)
     }
 
     if (!ngx_queue_empty(&ngx_posted_next_events)) {
-        ngx_queue_add(&ngx_posted_events, &ngx_posted_next_events);
-        ngx_queue_init(&ngx_posted_next_events);
         timer = 0;
     }
 
@@ -263,6 +261,7 @@ ngx_process_events_and_timers(ngx_cycle_t *cycle)
     }
 
     ngx_event_process_posted(cycle, &ngx_posted_events);
+    ngx_event_process_posted_next(cycle, &ngx_posted_next_events);
 }
 
 
index e9431b2d6a19148fe3ef4496662f387c234d4598..6a0e8c0ad4da70aa46d1b8ede117cb71cd344574 100644 (file)
@@ -43,7 +43,6 @@ static ssize_t ngx_ssl_recv_early(ngx_connection_t *c, u_char *buf,
 #endif
 static ngx_int_t ngx_ssl_handle_recv(ngx_connection_t *c, int n);
 static void ngx_ssl_write_handler(ngx_event_t *wev);
-static void ngx_ssl_next_read_handler(ngx_event_t *rev);
 #ifdef SSL_READ_EARLY_DATA_SUCCESS
 static ssize_t ngx_ssl_write_early(ngx_connection_t *c, u_char *data,
     size_t size);
@@ -2018,11 +2017,6 @@ ngx_ssl_recv(ngx_connection_t *c, u_char *buf, size_t size)
                         c->read->available = 0;
                         c->read->ready = 0;
 
-                        if (c->ssl->next_read_handler == NULL) {
-                            c->ssl->next_read_handler = c->read->handler;
-                            c->read->handler = ngx_ssl_next_read_handler;
-                        }
-
                         ngx_post_event(c->read, &ngx_posted_next_events);
                     }
 
@@ -2328,31 +2322,6 @@ ngx_ssl_write_handler(ngx_event_t *wev)
 }
 
 
-static void
-ngx_ssl_next_read_handler(ngx_event_t *rev)
-{
-    ngx_connection_t  *c;
-
-    c = rev->data;
-
-    ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL next read handler");
-
-    rev->handler = c->ssl->next_read_handler;
-    c->ssl->next_read_handler = NULL;
-
-    if (!rev->ready) {
-        rev->ready = 1;
-        rev->available = -1;
-    }
-
-    if (rev->posted) {
-        ngx_delete_posted_event(rev);
-    }
-
-    rev->handler(rev);
-}
-
-
 /*
  * OpenSSL has no SSL_writev() so we copy several bufs into our 16K buffer
  * before the SSL_write() call to decrease a SSL overhead.
index 71df9004526dbc8d800258ffb018fc113ea4d670..61da0c5db6f2114adf863b48597bd0a7e0d8f509 100644 (file)
@@ -86,7 +86,6 @@ struct ngx_ssl_connection_s {
 
     ngx_event_handler_pt        saved_read_handler;
     ngx_event_handler_pt        saved_write_handler;
-    ngx_event_handler_pt        next_read_handler;
 
     u_char                      early_buf;
 
index fd0b411c4c3da7ee1078aa4292fcc26733467e2c..125bf4c677243f8584b2ad52fdfbc14818f4a5e4 100644 (file)
@@ -34,3 +34,29 @@ ngx_event_process_posted(ngx_cycle_t *cycle, ngx_queue_t *posted)
         ev->handler(ev);
     }
 }
+
+
+void
+ngx_event_process_posted_next(ngx_cycle_t *cycle, ngx_queue_t *posted)
+{
+    ngx_queue_t  *q;
+    ngx_event_t  *ev;
+
+    while (!ngx_queue_empty(posted)) {
+
+        q = ngx_queue_head(posted);
+        ev = ngx_queue_data(q, ngx_event_t, queue);
+
+        ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
+                      "posted next event %p", ev);
+
+        ngx_delete_posted_event(ev);
+
+        if (!ev->ready) {
+            ev->ready = 1;
+            ev->available = -1;
+        }
+
+        ev->handler(ev);
+    }
+}
index bac5b35552642117f1dee1a760927476ecabdc1a..de0a8045408720e588fc213fa7281c5e69345407 100644 (file)
@@ -39,6 +39,7 @@
 
 
 void ngx_event_process_posted(ngx_cycle_t *cycle, ngx_queue_t *posted);
+void ngx_event_process_posted_next(ngx_cycle_t *cycle, ngx_queue_t *posted);
 
 
 extern ngx_queue_t  ngx_posted_accept_events;