[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] [libmicrohttpd] 02/03: Watch "upgraded" sockets for OOB dat
From: |
gnunet |
Subject: |
[GNUnet-SVN] [libmicrohttpd] 02/03: Watch "upgraded" sockets for OOB data and disconnects. Currently states are only monitored. States processing have to be added. |
Date: |
Wed, 01 Mar 2017 21:51:20 +0100 |
This is an automated email from the git hooks/post-receive script.
karlson2k pushed a commit to branch master
in repository libmicrohttpd.
commit cf9bb9428f0065cf0ca8ef2c726933b4db2385f1
Author: Evgeny Grin (Karlson2k) <address@hidden>
AuthorDate: Wed Mar 1 23:43:00 2017 +0300
Watch "upgraded" sockets for OOB data and disconnects.
Currently states are only monitored. States processing have to be added.
---
src/microhttpd/daemon.c | 281 ++++++++++++++++++++++++++++------------------
src/microhttpd/response.c | 6 +-
2 files changed, 176 insertions(+), 111 deletions(-)
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
index 5646fcfb..e0d0b522 100644
--- a/src/microhttpd/daemon.c
+++ b/src/microhttpd/daemon.c
@@ -681,82 +681,179 @@ MHD_get_fdset (struct MHD_Daemon *daemon,
* @param urh upgrade handle to wait for
* @param[out] rs read set to initialize
* @param[out] ws write set to initialize
+ * @param[out] es except set to initialize
* @param[out] max_fd maximum FD to update
* @param fd_setsize value of FD_SETSIZE
- * @return #MHD_YES on success, #MHD_NO on error
+ * @return true on success, false on error
*/
-static int
+static bool
urh_to_fdset (struct MHD_UpgradeResponseHandle *urh,
fd_set *rs,
fd_set *ws,
+ fd_set *es,
MHD_socket *max_fd,
unsigned int fd_setsize)
{
- if ( (urh->out_buffer_used < urh->out_buffer_size) &&
- (MHD_INVALID_SOCKET != urh->mhd.socket) &&
- (! MHD_add_to_fd_set_ (urh->mhd.socket,
- rs,
- max_fd,
- fd_setsize)) )
- return MHD_NO;
- if ( (0 != urh->in_buffer_used) &&
- (! urh->was_closed) &&
- (MHD_INVALID_SOCKET != urh->mhd.socket) &&
- (! MHD_add_to_fd_set_ (urh->mhd.socket,
- ws,
- max_fd,
- fd_setsize)) )
- return MHD_NO;
- if ( (urh->in_buffer_used < urh->in_buffer_size) &&
- (! urh->was_closed) &&
- (MHD_INVALID_SOCKET != urh->connection->socket_fd) &&
- (! MHD_add_to_fd_set_ (urh->connection->socket_fd,
- rs,
- max_fd,
- fd_setsize)) )
- return MHD_NO;
- if ( (0 != urh->out_buffer_used) &&
- (MHD_INVALID_SOCKET != urh->connection->socket_fd) &&
- (! MHD_add_to_fd_set_ (urh->connection->socket_fd,
- ws,
- max_fd,
- fd_setsize)) )
- return MHD_NO;
- return MHD_YES;
+ const MHD_socket conn_sckt = urh->connection->socket_fd;
+ const MHD_socket mhd_sckt = urh->mhd.socket;
+ bool res = true;
+
+ if (MHD_INVALID_SOCKET != conn_sckt)
+ {
+ if ( (urh->in_buffer_used < urh->in_buffer_size) &&
+ (! MHD_add_to_fd_set_ (conn_sckt,
+ rs,
+ max_fd,
+ fd_setsize)) )
+ res = false;
+ if ( (0 != urh->out_buffer_used) &&
+ (! MHD_add_to_fd_set_ (conn_sckt,
+ ws,
+ max_fd,
+ fd_setsize)) )
+ res = false;
+ if (0 != urh->in_buffer_size)
+ MHD_add_to_fd_set_ (conn_sckt,
+ es,
+ max_fd,
+ fd_setsize);
+ }
+ if (MHD_INVALID_SOCKET != mhd_sckt)
+ {
+ if ( (urh->out_buffer_used < urh->out_buffer_size) &&
+ (! MHD_add_to_fd_set_ (mhd_sckt,
+ rs,
+ max_fd,
+ fd_setsize)) )
+ res = false;
+ if ( (0 != urh->in_buffer_used) &&
+ (! MHD_add_to_fd_set_ (mhd_sckt,
+ ws,
+ max_fd,
+ fd_setsize)) )
+ res = false;
+ if (0 != urh->out_buffer_size)
+ MHD_add_to_fd_set_ (mhd_sckt,
+ es,
+ max_fd,
+ fd_setsize);
+ }
+
+ return res;
}
/**
- * Update the @a urh based on the ready FDs in the @a rs and @a ws.
+ * Update the @a urh based on the ready FDs in
+ * the @a rs, @a ws, and @a es.
*
* @param urh upgrade handle to update
* @param rs read result from select()
* @param ws write result from select()
+ * @param ws except result from select()
*/
static void
urh_from_fdset (struct MHD_UpgradeResponseHandle *urh,
const fd_set *rs,
- const fd_set *ws)
+ const fd_set *ws,
+ const fd_set *es,)
{
- const MHD_socket mhd_sckt = urh->mhd.socket;
const MHD_socket conn_sckt = urh->connection->socket_fd;
+ const MHD_socket mhd_sckt = urh->mhd.socket;
+
+ urh->app.celi = MHD_EPOLL_STATE_UNREADY;
+ urh->mhd.celi = MHD_EPOLL_STATE_UNREADY;
+
+ if (MHD_INVALID_SOCKET != conn_sckt)
+ {
+ if (FD_ISSET (conn_sckt, rs))
+ urh->app.celi |= MHD_EPOLL_STATE_READ_READY;
+ if (FD_ISSET (conn_sckt, ws))
+ urh->app.celi |= MHD_EPOLL_STATE_WRITE_READY;
+ if (FD_ISSET (conn_sckt, es))
+ urh->app.celi |= MHD_EPOLL_STATE_ERROR;
+ }
+ if ((MHD_INVALID_SOCKET != mhd_sckt))
+ {
+ if (FD_ISSET (mhd_sckt, rs))
+ urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY;
+ if (FD_ISSET (mhd_sckt, ws))
+ urh->mhd.celi |= MHD_EPOLL_STATE_WRITE_READY;
+ if (FD_ISSET (mhd_sckt, es))
+ urh->mhd.celi |= MHD_EPOLL_STATE_ERROR;
+ }
+}
+
+
+/**
+ * Set required 'event' members in 'pollfd' elements,
+ * assuming that @a p[0].fd is MHD side of socketpair
+ * and @a p[1].fd is TLS connected socket.
+ *
+ * @param urh upgrade handle to watch for
+ * @param p pollfd array to update
+ */
+static void
+urh_update_pollfd(struct MHD_UpgradeResponseHandle *urh,
+ struct pollfd p[2])
+{
+ p[0].events = 0;
+ p[1].events = 0;
+ if (urh->in_buffer_used < urh->in_buffer_size)
+ p[0].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC;
+ if (0 != urh->out_buffer_used)
+ p[0].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC;
+ if (0 != urh->in_buffer_size)
+ p[0].events |= MHD_POLL_EVENTS_ERR_DISC;
+ if (urh->out_buffer_used < urh->out_buffer_size)
+ p[1].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC;
+ if (0 != urh->in_buffer_used)
+ p[1].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC;
+ if (0 != urh->out_buffer_size)
+ p[1].events |= MHD_POLL_EVENTS_ERR_DISC;
+}
+
- if ((MHD_INVALID_SOCKET != conn_sckt) &&
- FD_ISSET (conn_sckt, rs))
+/**
+ * Set @a p to watch for @a urh.
+ *
+ * @param urh upgrade handle to watch for
+ * @param p pollfd array to set
+ */
+static void
+urh_to_pollfd(struct MHD_UpgradeResponseHandle *urh,
+ struct pollfd p[2])
+{
+ p[0].fd = urh->connection->socket_fd;
+ p[1].fd = urh->mhd.socket;
+ urh_update_pollfd(urh, p);
+}
+
+
+/**
+ * Update ready state in @a urh based on pollfd.
+ * @param urh upgrade handle to update
+ * @param p 'poll()' processed pollfd.
+ */
+static void
+urh_from_pollfd(struct MHD_UpgradeResponseHandle *urh,
+ struct pollfd p[2])
+{
+ if (0 != (p[0].revents & POLLIN))
urh->app.celi |= MHD_EPOLL_STATE_READ_READY;
- if ((MHD_INVALID_SOCKET != conn_sckt) &&
- FD_ISSET (conn_sckt, ws))
+ if (0 != (p[0].revents & POLLOUT))
urh->app.celi |= MHD_EPOLL_STATE_WRITE_READY;
- if ((MHD_INVALID_SOCKET != mhd_sckt) &&
- FD_ISSET (mhd_sckt, rs))
+ if (0 != (p[0].revents & MHD_POLL_REVENTS_ERR_DISC))
+ urh->app.celi |= MHD_EPOLL_STATE_ERROR;
+ if (0 != (p[1].revents & POLLIN))
urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY;
- if ((MHD_INVALID_SOCKET != mhd_sckt) &&
- FD_ISSET (mhd_sckt, ws))
+ if (0 != (p[1].revents & POLLOUT))
urh->mhd.celi |= MHD_EPOLL_STATE_WRITE_READY;
+ if (0 != (p[1].revents & MHD_POLL_REVENTS_ERR_DISC))
+ urh->mhd.celi |= MHD_EPOLL_STATE_ERROR;
}
#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
-
/**
* Obtain the `select()` sets for this daemon.
* Daemon's FDs will be added to fd_sets. To get only
@@ -891,6 +988,7 @@ MHD_get_fdset2 (struct MHD_Daemon *daemon,
urh_to_fdset (urh,
read_fd_set,
write_fd_set,
+ except_fd_set,
max_fd,
fd_setsize))
result = MHD_NO;
@@ -1362,19 +1460,22 @@ thread_main_connection_upgrade (struct MHD_Connection
*con)
/* use select */
fd_set rs;
fd_set ws;
+ fd_set es;
MHD_socket max_fd;
int num_ready;
- int result;
+ bool result;
FD_ZERO (&rs);
FD_ZERO (&ws);
+ FD_ZERO (&es);
max_fd = MHD_INVALID_SOCKET;
result = urh_to_fdset (urh,
&rs,
&ws,
+ &es,
&max_fd,
FD_SETSIZE);
- if (MHD_NO == result)
+ if (! result)
{
#ifdef HAVE_MESSAGES
MHD_DLOG (con->daemon,
@@ -1399,7 +1500,7 @@ thread_main_connection_upgrade (struct MHD_Connection
*con)
num_ready = MHD_SYS_select_ (max_fd + 1,
&rs,
&ws,
- NULL,
+ &es,
tvp);
}
else
@@ -1420,7 +1521,8 @@ thread_main_connection_upgrade (struct MHD_Connection
*con)
}
urh_from_fdset (urh,
&rs,
- &ws);
+ &ws
+ &es);
process_urh (urh);
if ( (0 == urh->in_buffer_size) &&
(0 == urh->out_buffer_size) &&
@@ -1433,38 +1535,29 @@ thread_main_connection_upgrade (struct MHD_Connection
*con)
else if (0 != (daemon->options & MHD_USE_TLS))
{
/* use poll() */
+ struct pollfd p[2];
+ memset (p,
+ 0,
+ sizeof (p));
+ p[0].fd = urh->connection->socket_fd;
+ p[1].fd = urh->mhd.socket;
while ( (MHD_CONNECTION_UPGRADE == con->state) ||
(0 != urh->out_buffer_used) )
{
- struct pollfd p[2];
- unsigned int timeout;
+ int timeout;
- memset (p,
- 0,
- sizeof (struct pollfd) * 2);
- p[0].fd = urh->connection->socket_fd;
- p[1].fd = urh->mhd.socket;
- if (urh->in_buffer_used < urh->in_buffer_size)
- p[0].events |= POLLIN;
- if (0 != urh->out_buffer_used)
- p[0].events |= POLLOUT;
- if (urh->out_buffer_used < urh->out_buffer_size)
- p[1].events |= POLLIN;
- if (0 != urh->in_buffer_used)
- p[1].events |= POLLOUT;
+ urh_update_pollfd(urh, p);
if ( (con->tls_read_ready) &&
(urh->in_buffer_used < urh->in_buffer_size))
timeout = 0; /* No need to wait if incoming data is already
pending in TLS buffers. */
else
- timeout = UINT_MAX;
+ timeout = -1;
- /* FIXME: does this check really needed? */
- if ( (0 != (p[0].events | p[1].events)) &&
- (MHD_sys_poll_ (p,
- 2,
- timeout) < 0) )
+ if (MHD_sys_poll_ (p,
+ 2,
+ timeout) < 0)
{
const int err = MHD_socket_get_error_ ();
@@ -1477,14 +1570,7 @@ thread_main_connection_upgrade (struct MHD_Connection
*con)
#endif
break;
}
- if (0 != (p[0].revents & POLLIN))
- urh->app.celi |= MHD_EPOLL_STATE_READ_READY;
- if (0 != (p[0].revents & POLLOUT))
- urh->app.celi |= MHD_EPOLL_STATE_WRITE_READY;
- if (0 != (p[1].revents & POLLIN))
- urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY;
- if (0 != (p[1].revents & POLLOUT))
- urh->mhd.celi |= MHD_EPOLL_STATE_WRITE_READY;
+ urh_from_pollfd(urh, p);
process_urh (urh);
if ( (0 == urh->in_buffer_size) &&
(0 == urh->out_buffer_size) &&
@@ -3153,7 +3239,8 @@ MHD_run_from_select (struct MHD_Daemon *daemon,
/* update urh state based on select() output */
urh_from_fdset (urh,
read_fd_set,
- write_fd_set);
+ write_fd_set,
+ except_fd_set);
/* call generic forwarding function for passing data */
process_urh (urh);
/* Finished forwarding? */
@@ -3448,18 +3535,8 @@ MHD_poll_all (struct MHD_Daemon *daemon,
#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
for (urh = daemon->urh_tail; NULL != urh; urh = urh->prev)
{
- p[poll_server+i].fd = urh->connection->socket_fd;
- if (urh->in_buffer_used < urh->in_buffer_size)
- p[poll_server+i].events |= POLLIN;
- if (0 != urh->out_buffer_used)
- p[poll_server+i].events |= POLLOUT;
- i++;
- p[poll_server+i].fd = urh->mhd.socket;
- if (urh->out_buffer_used < urh->out_buffer_size)
- p[poll_server+i].events |= POLLIN;
- if (0 != urh->in_buffer_used)
- p[poll_server+i].events |= POLLOUT;
- i++;
+ urh_to_pollfd(urh, &(p[poll_server+i]));
+ i += 2;
}
#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
if (0 == poll_server + num_connections)
@@ -3528,23 +3605,11 @@ MHD_poll_all (struct MHD_Daemon *daemon,
* from 'daemon->urh_head' list. */
urhn = urh->prev;
/* Check for fd mismatch. FIXME: required for safety? */
- if (p[poll_server+i].fd == urh->connection->socket_fd)
- {
- if (0 != (p[poll_server+i].revents & POLLIN))
- urh->app.celi |= MHD_EPOLL_STATE_READ_READY;
- if (0 != (p[poll_server+i].revents & POLLOUT))
- urh->app.celi |= MHD_EPOLL_STATE_WRITE_READY;
- }
- i++;
- /* Check for fd mismatch. FIXME: required for safety? */
- if (p[poll_server+i].fd == urh->mhd.socket)
- {
- if (0 != (p[poll_server+i].revents & POLLIN))
- urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY;
- if (0 != (p[poll_server+i].revents & POLLOUT))
- urh->mhd.celi |= MHD_EPOLL_STATE_WRITE_READY;
- }
- i++;
+ if ((p[poll_server+i].fd != urh->connection->socket_fd) ||
+ (p[poll_server+i+1].fd != urh->mhd.socket))
+ break;
+ urh_from_pollfd(urh, &(p[poll_server+i]));
+ i += 2;
process_urh (urh);
/* Finished forwarding? */
if ( (0 == urh->in_buffer_size) &&
diff --git a/src/microhttpd/response.c b/src/microhttpd/response.c
index 498174e6..26ad649b 100644
--- a/src/microhttpd/response.c
+++ b/src/microhttpd/response.c
@@ -852,7 +852,7 @@ MHD_response_execute_upgrade_ (struct MHD_Response
*response,
EXTRA_CHECK (-1 != daemon->epoll_upgrade_fd);
/* First, add network socket */
- event.events = EPOLLIN | EPOLLOUT;
+ event.events = EPOLLIN | EPOLLOUT | EPOLLPRI;
event.data.ptr = &urh->app;
if (0 != epoll_ctl (daemon->epoll_upgrade_fd,
EPOLL_CTL_ADD,
@@ -871,14 +871,14 @@ MHD_response_execute_upgrade_ (struct MHD_Response
*response,
}
/* Second, add our end of the UNIX socketpair() */
- event.events = EPOLLIN | EPOLLOUT;
+ event.events = EPOLLIN | EPOLLOUT | EPOLLPRI;
event.data.ptr = &urh->mhd;
if (0 != epoll_ctl (daemon->epoll_upgrade_fd,
EPOLL_CTL_ADD,
urh->mhd.socket,
&event))
{
- event.events = EPOLLIN | EPOLLOUT;
+ event.events = EPOLLIN | EPOLLOUT | EPOLLPRI;
event.data.ptr = &urh->app;
if (0 != epoll_ctl (daemon->epoll_upgrade_fd,
EPOLL_CTL_DEL,
--
To stop receiving notification emails like this one, please contact
address@hidden