commit b357bbaa6fcedfa43af7e2549535112468bde41b
parent 03e7c4f4d5a90eefa8d3c77575173b8948ba14c4
Author: Evgeny Grin (Karlson2k) <k2k@narod.ru>
Date: Tue, 15 Nov 2016 19:06:43 +0300
Fixed forwarding data of TLS "upgraded" connections for chunks sizes larger than forward buffer
Diffstat:
3 files changed, 43 insertions(+), 2 deletions(-)
diff --git a/ChangeLog b/ChangeLog
@@ -1,3 +1,7 @@
+Tue Nov 15 19:08:43 MSK 2016
+ Fixed forwarding "upgraded" TLS connections for
+ chunks sizes larger than buffer size. -EG
+
Mon Nov 14 22:18:30 MSK 2016
Fixed unintentional usage of SO_REUSEADDR on W32.
Added support for SO_EXCLBIND on Solaris.
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
@@ -1012,10 +1012,12 @@ process_urh (struct MHD_UpgradeResponseHandle *urh)
urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
/* Reading from remote client is not required anymore. */
urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY;
+ urh->connection->tls_read_ready = 0;
}
/* handle reading from TLS client and writing to application */
- if ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->app.celi)) &&
+ if ( ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->app.celi)) ||
+ (urh->connection->tls_read_ready) ) &&
(urh->in_buffer_used < urh->in_buffer_size) )
{
ssize_t res;
@@ -1025,6 +1027,7 @@ process_urh (struct MHD_UpgradeResponseHandle *urh)
if (buf_size > SSIZE_MAX)
buf_size = SSIZE_MAX;
+ urh->connection->tls_read_ready = 0;
res = gnutls_record_recv (urh->connection->tls_session,
&urh->in_buffer[urh->in_buffer_used],
buf_size);
@@ -1036,6 +1039,11 @@ process_urh (struct MHD_UpgradeResponseHandle *urh)
else if (res > 0)
{
urh->in_buffer_used += res;
+ if (0 < gnutls_record_check_pending (urh->connection->tls_session))
+ {
+ urh->connection->tls_read_ready = !0;
+ urh->connection->daemon->has_tls_recv_ready = !0;
+ }
}
else if (0 >= res)
{
@@ -1083,6 +1091,7 @@ process_urh (struct MHD_UpgradeResponseHandle *urh)
urh->in_buffer_used = 0;
urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY;
+ urh->connection->tls_read_ready = 0;
}
}
else
@@ -2872,7 +2881,7 @@ MHD_get_timeout (struct MHD_Daemon *daemon,
}
#ifdef HTTPS_SUPPORT
- if (0 != daemon->num_tls_read_ready)
+ if (0 != daemon->num_tls_read_ready || daemon->has_tls_recv_ready)
{
/* if there is any TLS connection with data ready for
reading, we must not block in the event loop */
@@ -2974,6 +2983,14 @@ MHD_run_from_select (struct MHD_Daemon *daemon,
read_fd_set)) )
MHD_itc_clear_ (daemon->itc);
+#ifdef HTTPS_SUPPORT
+ /* Reset TLS read-ready.
+ * New value will be set by read handlers. */
+ if ( (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
+ (0 != (daemon->options & MHD_USE_TLS)) )
+ daemon->has_tls_recv_ready = 0;
+#endif /* HTTPS_SUPPORT */
+
/* Resuming external connections when using an extern mainloop */
if (MHD_ALLOW_SUSPEND_RESUME == (daemon->options & mask))
resume_suspended_connections (daemon);
@@ -3363,6 +3380,14 @@ MHD_poll_all (struct MHD_Daemon *daemon,
(0 != (p[poll_itc_idx].revents & POLLIN)) )
MHD_itc_clear_ (daemon->itc);
+#ifdef HTTPS_SUPPORT
+ /* Reset TLS read-ready.
+ * New value will be set by read handlers. */
+ if ( (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
+ (0 != (daemon->options & MHD_USE_TLS)) )
+ daemon->has_tls_recv_ready = 0;
+#endif /* HTTPS_SUPPORT */
+
/* handle shutdown */
if (MHD_YES == daemon->shutdown)
{
@@ -3759,6 +3784,12 @@ MHD_epoll (struct MHD_Daemon *daemon,
#endif
return MHD_NO;
}
+#ifdef HTTPS_SUPPORT
+ /* Reset TLS read-ready.
+ * New value will be set by read handlers. */
+ if ( 0 != (daemon->options & MHD_USE_TLS) )
+ daemon->has_tls_recv_ready = 0;
+#endif /* HTTPS_SUPPORT */
for (i=0;i<(unsigned int) num_events;i++)
{
/* First, check for the values of `ptr` that would indicate
diff --git a/src/microhttpd/internal.h b/src/microhttpd/internal.h
@@ -1553,6 +1553,12 @@ struct MHD_Daemon
*/
unsigned int num_tls_read_ready;
+ /**
+ * Indicate that some TLS connection(s) have received data pending in
+ * TLS buffers.
+ */
+ bool has_tls_recv_ready;
+
#endif /* HTTPS_SUPPORT */
#ifdef DAUTH_SUPPORT