Bläddra i källkod

more checks for FD_SETSIZE, implemented check for FD_SETSIZE on W32

Evgeny Grin (Karlson2k) 12 år sedan
förälder
incheckning
582da7168a
2 ändrade filer med 66 tillägg och 43 borttagningar
  1. 4 0
      ChangeLog
  2. 62 43
      src/microhttpd/daemon.c

+ 4 - 0
ChangeLog

@@ -1,3 +1,7 @@
+Tue Mar 25 09:06:13 CET 2014
+	Added more FD_SETSIZE checks.
+	Implemented FD_SETSIZE checks for W32. -EG
+
 Wed Mar 05 13:15:05 CET 2014
 	Cleanup and refactoring of configure.ac.
 	m4 macros updated.

+ 62 - 43
src/microhttpd/daemon.c

@@ -572,16 +572,33 @@ MHD_TLS_init (struct MHD_Daemon *daemon)
  * @param fd file descriptor to add to the @a set
  * @param set set to modify
  * @param max_fd maximum value to potentially update
+ * @return #MHD_YES on success, #MHD_NO otherwise
  */
-static void
+static int
 add_to_fd_set (MHD_socket fd,
 	       fd_set *set,
 	       MHD_socket *max_fd)
 {
+  if (NULL == set)
+    return MHD_NO;
+#ifdef MHD_WINSOCK_SOCKETS
+  if (set->fd_count >= FD_SETSIZE)
+    {
+      if (FD_ISSET(fd, set))
+        return MHD_YES;
+      else
+        return MHD_NO;
+    }
+#else  // ! MHD_WINSOCK_SOCKETS
+  if (fd >= FD_SETSIZE)
+    return MHD_NO;
+#endif // ! MHD_WINSOCK_SOCKETS
   FD_SET (fd, set);
   if ( (NULL != max_fd) && (MHD_INVALID_SOCKET != fd) &&
        ((fd > *max_fd) || (MHD_INVALID_SOCKET == *max_fd)) )
     *max_fd = fd;
+
+  return MHD_YES;
 }
 
 
@@ -599,7 +616,8 @@ add_to_fd_set (MHD_socket fd,
  *               than existing value); can be NULL
  * @return #MHD_YES on success, #MHD_NO if this
  *         daemon was not started with the right
- *         options for this call.
+ *         options for this call or any FD didn't
+ *         fit fd_set.
  * @ingroup event
  */
 int
@@ -610,7 +628,6 @@ MHD_get_fdset (struct MHD_Daemon *daemon,
 	       MHD_socket *max_fd)
 {
   struct MHD_Connection *pos;
-  MHD_socket fd;
 
   if ( (NULL == daemon)
        || (NULL == read_fd_set)
@@ -626,38 +643,32 @@ MHD_get_fdset (struct MHD_Daemon *daemon,
       /* we're in epoll mode, use the epoll FD as a stand-in for
 	 the entire event set */
 
-      if (daemon->epoll_fd >= FD_SETSIZE)
-	return MHD_NO; /* poll fd too big, fail hard */
-      FD_SET (daemon->epoll_fd, read_fd_set);
-      if ( (NULL != max_fd) &&  ((*max_fd) < daemon->epoll_fd) )
-	*max_fd = daemon->epoll_fd;
-      return MHD_YES;
+      return add_to_fd_set (daemon->epoll_fd, read_fd_set, max_fd);
     }
 #endif
-  fd = daemon->socket_fd;
-  if (MHD_INVALID_SOCKET != fd)
-  {
-    FD_SET (fd, read_fd_set);
-    /* update max file descriptor */
-    if ( (NULL != max_fd) &&
-         ((*max_fd) < fd || MHD_INVALID_SOCKET == (*max_fd)))
-      *max_fd = fd;
-  }
+  if (MHD_INVALID_SOCKET != daemon->socket_fd &&
+      MHD_YES != add_to_fd_set (daemon->socket_fd, read_fd_set, max_fd))
+    return MHD_NO;
+
   for (pos = daemon->connections_head; NULL != pos; pos = pos->next)
     {
       switch (pos->event_loop_info)
 	{
 	case MHD_EVENT_LOOP_INFO_READ:
-	  add_to_fd_set (pos->socket_fd, read_fd_set, max_fd);
+	  if (MHD_YES != add_to_fd_set (pos->socket_fd, read_fd_set, max_fd))
+	    return MHD_NO;
 	  break;
 	case MHD_EVENT_LOOP_INFO_WRITE:
-	  add_to_fd_set (pos->socket_fd, write_fd_set, max_fd);
-	  if (pos->read_buffer_size > pos->read_buffer_offset)
-	    add_to_fd_set (pos->socket_fd, read_fd_set, max_fd);
+	  if (MHD_YES != add_to_fd_set (pos->socket_fd, write_fd_set, max_fd))
+	    return MHD_NO;
+	  if (pos->read_buffer_size > pos->read_buffer_offset &&
+	      MHD_YES != add_to_fd_set (pos->socket_fd, read_fd_set, max_fd))
+            return MHD_NO;
 	  break;
 	case MHD_EVENT_LOOP_INFO_BLOCK:
-	  if (pos->read_buffer_size > pos->read_buffer_offset)
-	    add_to_fd_set (pos->socket_fd, read_fd_set, max_fd);
+	  if (pos->read_buffer_size > pos->read_buffer_offset &&
+	      MHD_YES != add_to_fd_set (pos->socket_fd, read_fd_set, max_fd))
+            return MHD_NO;
 	  break;
 	case MHD_EVENT_LOOP_INFO_CLEANUP:
 	  /* this should never happen */
@@ -724,22 +735,27 @@ MHD_handle_connection (void *data)
       if (0 == (con->daemon->options & MHD_USE_POLL))
 	{
 	  /* use select */
+	  int err_state = 0;
 	  FD_ZERO (&rs);
 	  FD_ZERO (&ws);
 	  max = 0;
 	  switch (con->event_loop_info)
 	    {
 	    case MHD_EVENT_LOOP_INFO_READ:
-	      add_to_fd_set (con->socket_fd, &rs, &max);
+	      if (MHD_YES != add_to_fd_set (con->socket_fd, &rs, &max))
+	        err_state = 1;
 	      break;
 	    case MHD_EVENT_LOOP_INFO_WRITE:
-	      add_to_fd_set (con->socket_fd, &ws, &max);
-	      if (con->read_buffer_size > con->read_buffer_offset)
-		add_to_fd_set (con->socket_fd, &rs, &max);
+	      if (MHD_YES != add_to_fd_set (con->socket_fd, &ws, &max))
+                err_state = 1;
+	      if (con->read_buffer_size > con->read_buffer_offset &&
+	          MHD_YES != add_to_fd_set (con->socket_fd, &rs, &max))
+	        err_state = 1;
 	      break;
 	    case MHD_EVENT_LOOP_INFO_BLOCK:
-	      if (con->read_buffer_size > con->read_buffer_offset)
-		add_to_fd_set (con->socket_fd, &rs, &max);
+	      if (con->read_buffer_size > con->read_buffer_offset &&
+	          MHD_YES != add_to_fd_set (con->socket_fd, &rs, &max))
+	        err_state = 1;
 	      tv.tv_sec = 0;
 	      tv.tv_usec = 0;
 	      tvp = &tv;
@@ -748,6 +764,15 @@ MHD_handle_connection (void *data)
 	      /* how did we get here!? */
 	      goto exit;
 	    }
+            if (0 != err_state)
+              {
+#if HAVE_MESSAGES
+                MHD_DLOG (con->daemon,
+                        "Can't add FD to fd_set\n");
+#endif
+                goto exit;
+              }
+
 	  num_ready = MHD_SYS_select_ (max + 1, &rs, &ws, NULL, tvp);
 	  if (num_ready < 0)
 	    {
@@ -756,7 +781,7 @@ MHD_handle_connection (void *data)
 #if HAVE_MESSAGES
 	      MHD_DLOG (con->daemon,
 			"Error during select (%d): `%s'\n",
-			max,
+			MHD_socket_errno_,
 			MHD_socket_last_strerr_ ());
 #endif
 	      break;
@@ -2078,19 +2103,13 @@ MHD_select (struct MHD_Daemon *daemon,
   else
     {
       /* accept only, have one thread per connection */
-      if (MHD_INVALID_SOCKET != daemon->socket_fd)
-	{
-	  max = daemon->socket_fd;
-	  FD_SET (daemon->socket_fd, &rs);
-	}
-    }
-  if (MHD_INVALID_PIPE_ != daemon->wpipe[0])
-    {
-      FD_SET (daemon->wpipe[0], &rs);
-      /* update max file descriptor */
-      if (max < daemon->wpipe[0] || max == MHD_INVALID_SOCKET)
-	max = daemon->wpipe[0];
+      if (MHD_INVALID_SOCKET != daemon->socket_fd &&
+          MHD_YES != add_to_fd_set(daemon->socket_fd, &rs, &max))
+        return MHD_NO;
     }
+  if (MHD_INVALID_PIPE_ != daemon->wpipe[0] &&
+      MHD_YES != add_to_fd_set(daemon->wpipe[0], &rs, &max))
+    return MHD_NO;
 
   tv = NULL;
   if (MHD_NO == may_block)