]> xenbits.xensource.com Git - unikraft/libs/lwip.git/commitdiff
Indicate EPOLLRDHUP when the peer closed the connection
authorMarco Schlumpp <marco@unikraft.io>
Thu, 11 Apr 2024 14:39:22 +0000 (16:39 +0200)
committerRazvan Deaconescu <razvan.deaconescu@upb.ro>
Fri, 31 May 2024 17:50:26 +0000 (20:50 +0300)
The RDHUP event is used by nginx to reduce the amount of syscalls it has
to do by knowing whether a EOF is coming up. Not setting this event will
cause nginx to hang with fcgi_pass configurations.

Signed-off-by: Marco Schlumpp <marco@unikraft.io>
Reviewed-by: Michalis Pappas <michalis@unikraft.io>
Reviewed-by: Eduard Vintilă <eduard.vintila47@gmail.com>
Reviewed-by: Maria Pană <maria.pana4@gmail.com>
Approved-by: Razvan Deaconescu <razvand@unikraft.io>
GitHub-Closes: #55

sockets.c

index 3af5daaebc54a725402bf3c2128df327d698b5d5..f82da50063853ef04776c7914692f4f4a628fb85 100644 (file)
--- a/sockets.c
+++ b/sockets.c
@@ -45,6 +45,8 @@
 #include <lwip/priv/sockets_priv.h>
 #include <lwip/api.h>
 #include <lwip/sys.h>
+#include <lwip/tcp.h>
+#include <lwip/tcpbase.h>
 
 
 static inline
@@ -421,16 +423,26 @@ get_lwip_socket_events(struct lwip_sock *sock)
 
        UK_ASSERT(sock);
 
-       /* A TCP connection may be in not-connected state. Don't report it as
-        * readable or writeable.
-        */
-       if ((NETCONNTYPE_GROUP(sock->conn->type) == NETCONN_TCP) &&
-           (sock->conn->state == NETCONN_NONE) &&
-           (!NETCONN_RECVMBOX_WAITABLE(sock->conn))) {
-               if (sock->errevent != 0)
-                       events |= EPOLLERR;
+       if ((NETCONNTYPE_GROUP(sock->conn->type) == NETCONN_TCP)) {
+               /* A TCP connection may be in not-connected state. Don't report it as
+                * readable or writeable.
+                */
+               if ((sock->conn->state == NETCONN_NONE) &&
+                   (!NETCONN_RECVMBOX_WAITABLE(sock->conn))) {
+                       if (sock->errevent != 0)
+                               events |= EPOLLERR;
+
+                       return events;
+               }
 
-               return events;
+                /* Check whether the TCP connection is in CLOSE_WAIT (= got a
+                 * FIN packet). In that case the peer will not sent more data
+                 * and we can tell the application that the receive buffer is
+                 * everything we got until the EOF.
+                 */
+                if (sock->conn->pcb.tcp == NULL ||
+                   sock->conn->pcb.tcp->state == CLOSE_WAIT)
+                       events |= EPOLLRDHUP;
        }
 
        if (sock->lastdata.pbuf || sock->rcvevent > 0)