gnunet-svn
[Top][All Lists]
Advanced

[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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]