Klaus Demo nginx / 798fcf1
SSL: available bytes handling (ticket #1431). Added code to track number of bytes available in the socket. This makes it possible to avoid looping for a long time while working with fast enough peer when data are added to the socket buffer faster than we are able to read and process data. When kernel does not provide number of bytes available, it is retrieved using ioctl(FIONREAD) as long as a buffer is filled by SSL_read(). It is assumed that number of bytes returned by SSL_read() is close to the number of bytes read from the socket, as we do not use SSL compression. But even if it is not true for some reason, this is not important, as we post an additional reading event anyway. Note that data can be buffered at SSL layer, and it is not possible to simply stop reading at some point and wait till the event will be reported by the kernel again. This can be only done when there are no data in SSL buffers, and there is no good way to find out if it's the case. Instead of trying to figure out if SSL buffers are empty, this patch introduces events posted for the next event loop iteration - such events will be processed only on the next event loop iteration, after going into the kernel and retrieving additional events. This seems to be simple and reliable approach. Maxim Dounin 27 days ago
5 changed file(s) with 78 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
236236 }
237237 }
238238
239 if (!ngx_queue_empty(&ngx_posted_next_events)) {
240 ngx_queue_add(&ngx_posted_events, &ngx_posted_next_events);
241 ngx_queue_init(&ngx_posted_next_events);
242 timer = 0;
243 }
244
239245 delta = ngx_current_msec;
240246
241247 (void) ngx_process_events(cycle, timer, flags);
638644 #endif
639645
640646 ngx_queue_init(&ngx_posted_accept_events);
647 ngx_queue_init(&ngx_posted_next_events);
641648 ngx_queue_init(&ngx_posted_events);
642649
643650 if (ngx_event_timer_init(cycle->log) == NGX_ERROR) {
4242 #endif
4343 static ngx_int_t ngx_ssl_handle_recv(ngx_connection_t *c, int n);
4444 static void ngx_ssl_write_handler(ngx_event_t *wev);
45 static void ngx_ssl_next_read_handler(ngx_event_t *rev);
4546 #ifdef SSL_READ_EARLY_DATA_SUCCESS
4647 static ssize_t ngx_ssl_write_early(ngx_connection_t *c, u_char *data,
4748 size_t size);
20022003
20032004 if (size == 0) {
20042005 c->read->ready = 1;
2006
2007 if (c->read->available >= 0) {
2008 c->read->available -= bytes;
2009
2010 /*
2011 * there can be data buffered at SSL layer,
2012 * so we post an event to continue reading on the next
2013 * iteration of the event loop
2014 */
2015
2016 if (c->read->available < 0) {
2017 c->read->available = 0;
2018 c->read->ready = 0;
2019
2020 if (c->ssl->next_read_handler == NULL) {
2021 c->ssl->next_read_handler = c->read->handler;
2022 c->read->handler = ngx_ssl_next_read_handler;
2023 }
2024
2025 ngx_post_event(c->read, &ngx_posted_next_events);
2026 }
2027
2028 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
2029 "SSL_read: avail:%d", c->read->available);
2030
2031 } else {
2032
2033 #if (NGX_HAVE_FIONREAD)
2034
2035 if (ngx_socket_nread(c->fd, &c->read->available) == -1) {
2036 c->read->error = 1;
2037 ngx_connection_error(c, ngx_socket_errno,
2038 ngx_socket_nread_n " failed");
2039 return NGX_ERROR;
2040 }
2041
2042 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
2043 "SSL_read: avail:%d", c->read->available);
2044
2045 #endif
2046 }
2047
20052048 return bytes;
20062049 }
20072050
22812324 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL write handler");
22822325
22832326 c->read->handler(c->read);
2327 }
2328
2329
2330 static void
2331 ngx_ssl_next_read_handler(ngx_event_t *rev)
2332 {
2333 ngx_connection_t *c;
2334
2335 c = rev->data;
2336
2337 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL next read handler");
2338
2339 rev->handler = c->ssl->next_read_handler;
2340 c->ssl->next_read_handler = NULL;
2341
2342 if (!rev->ready) {
2343 rev->ready = 1;
2344 rev->available = -1;
2345 }
2346
2347 if (rev->posted) {
2348 ngx_delete_posted_event(rev);
2349 }
2350
2351 rev->handler(rev);
22842352 }
22852353
22862354
8585
8686 ngx_event_handler_pt saved_read_handler;
8787 ngx_event_handler_pt saved_write_handler;
88 ngx_event_handler_pt next_read_handler;
8889
8990 u_char early_buf;
9091
1010
1111
1212 ngx_queue_t ngx_posted_accept_events;
13 ngx_queue_t ngx_posted_next_events;
1314 ngx_queue_t ngx_posted_events;
1415
1516
4141
4242
4343 extern ngx_queue_t ngx_posted_accept_events;
44 extern ngx_queue_t ngx_posted_next_events;
4445 extern ngx_queue_t ngx_posted_events;
4546
4647