comparison src/event/ngx_event_openssl.c @ 7612:1ce3f01a4355

SSL: reworked posted next events. 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.
author Maxim Dounin <mdounin@mdounin.ru>
date Tue, 24 Dec 2019 17:24:59 +0300
parents 9d2ad2fb4423
children f1720934c45b
comparison
equal deleted inserted replaced
7611:8e64e11aaca0 7612:1ce3f01a4355
41 static ssize_t ngx_ssl_recv_early(ngx_connection_t *c, u_char *buf, 41 static ssize_t ngx_ssl_recv_early(ngx_connection_t *c, u_char *buf,
42 size_t size); 42 size_t size);
43 #endif 43 #endif
44 static ngx_int_t ngx_ssl_handle_recv(ngx_connection_t *c, int n); 44 static ngx_int_t ngx_ssl_handle_recv(ngx_connection_t *c, int n);
45 static void ngx_ssl_write_handler(ngx_event_t *wev); 45 static void ngx_ssl_write_handler(ngx_event_t *wev);
46 static void ngx_ssl_next_read_handler(ngx_event_t *rev);
47 #ifdef SSL_READ_EARLY_DATA_SUCCESS 46 #ifdef SSL_READ_EARLY_DATA_SUCCESS
48 static ssize_t ngx_ssl_write_early(ngx_connection_t *c, u_char *data, 47 static ssize_t ngx_ssl_write_early(ngx_connection_t *c, u_char *data,
49 size_t size); 48 size_t size);
50 #endif 49 #endif
51 static void ngx_ssl_read_handler(ngx_event_t *rev); 50 static void ngx_ssl_read_handler(ngx_event_t *rev);
2016 2015
2017 if (c->read->available < 0) { 2016 if (c->read->available < 0) {
2018 c->read->available = 0; 2017 c->read->available = 0;
2019 c->read->ready = 0; 2018 c->read->ready = 0;
2020 2019
2021 if (c->ssl->next_read_handler == NULL) {
2022 c->ssl->next_read_handler = c->read->handler;
2023 c->read->handler = ngx_ssl_next_read_handler;
2024 }
2025
2026 ngx_post_event(c->read, &ngx_posted_next_events); 2020 ngx_post_event(c->read, &ngx_posted_next_events);
2027 } 2021 }
2028 2022
2029 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, 2023 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
2030 "SSL_read: avail:%d", c->read->available); 2024 "SSL_read: avail:%d", c->read->available);
2323 c = wev->data; 2317 c = wev->data;
2324 2318
2325 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL write handler"); 2319 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL write handler");
2326 2320
2327 c->read->handler(c->read); 2321 c->read->handler(c->read);
2328 }
2329
2330
2331 static void
2332 ngx_ssl_next_read_handler(ngx_event_t *rev)
2333 {
2334 ngx_connection_t *c;
2335
2336 c = rev->data;
2337
2338 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL next read handler");
2339
2340 rev->handler = c->ssl->next_read_handler;
2341 c->ssl->next_read_handler = NULL;
2342
2343 if (!rev->ready) {
2344 rev->ready = 1;
2345 rev->available = -1;
2346 }
2347
2348 if (rev->posted) {
2349 ngx_delete_posted_event(rev);
2350 }
2351
2352 rev->handler(rev);
2353 } 2322 }
2354 2323
2355 2324
2356 /* 2325 /*
2357 * OpenSSL has no SSL_writev() so we copy several bufs into our 16K buffer 2326 * OpenSSL has no SSL_writev() so we copy several bufs into our 16K buffer