]> git.ipfire.org Git - fireperf.git/commitdiff
server: Gracefully close connections when the client went away
authorMichael Tremer <michael.tremer@ipfire.org>
Thu, 28 Jan 2021 14:46:01 +0000 (14:46 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Thu, 28 Jan 2021 14:46:01 +0000 (14:46 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/server.c

index 07a8a3feb3098f8c072dfa8e20ef3830ee30b96c..67eeb273b1a2b93f6b92d4ce99ebb8597cd5fb76 100644 (file)
 
 #define SOCKET_BACKLOG   1024
 
+// Struct to collect server statistics
+struct fireperf_server_stats {
+       // Total number of open connections
+       unsigned int connections;
+};
+
 static int create_socket(struct fireperf_config* conf) {
        // Open a new socket
        int fd = socket(AF_INET6, SOCK_STREAM|SOCK_NONBLOCK|SOCK_CLOEXEC, 0);
@@ -100,11 +106,6 @@ static int handle_io_on_connection(struct fireperf_config* conf, int fd) {
        if (bytes_read < 0) {
                ERROR(conf, "Could not read from socket %d: %s\n", fd, strerror(errno));
                return -1;
-
-       // Connection closed
-       } else if (bytes_read == 0) {
-               DEBUG(conf, "Connection %d has closed\n", fd);
-               return 1;
        }
 
        DEBUG(conf, "Read %zu bytes from socket %d\n", bytes_read, fd);
@@ -113,6 +114,8 @@ static int handle_io_on_connection(struct fireperf_config* conf, int fd) {
 }
 
 int fireperf_server(struct fireperf_config* conf) {
+       struct fireperf_server_stats stats;
+
        DEBUG(conf, "Launching " PACKAGE_NAME " in server mode\n");
 
        int sockfd = -1;
@@ -169,7 +172,7 @@ int fireperf_server(struct fireperf_config* conf) {
                                        goto ERROR;
 
                                // Add the new socket to epoll()
-                               ev.events  = EPOLLIN;
+                               ev.events  = EPOLLIN|EPOLLHUP;
                                ev.data.fd = connfd;
 
                                if (epoll_ctl(epollfd, EPOLL_CTL_ADD, connfd, &ev)) {
@@ -178,19 +181,36 @@ int fireperf_server(struct fireperf_config* conf) {
                                        goto ERROR;
                                }
 
+                               // A connection has been opened
+                               stats.connections++;
+                               continue;
+                       }
+
+                       // Handle any connection events (like disconnects)
+                       if (ev.events & EPOLLHUP) {
+                               DEBUG(conf, "Connection %d has closed\n", fd);
+
+                               // Remove the file descriptor from epoll()
+                               if (epoll_ctl(epollfd, EPOLL_CTL_DEL, fd, NULL)) {
+                                       ERROR(conf, "Could not remove socket file descriptfor from epoll(): %s\n",
+                                               strerror(errno));
+                               }
+
+                               // Free up any resources
+                               close(fd);
+
+                               // This connection is now closed
+                               stats.connections--;
+
+                               // Skip processing anything else, because it would be pointless
+                               continue;
+                       }
+
                        // One of the connections had IO
-                       } else {
+                       if (ev.events & EPOLLIN) {
                                r = handle_io_on_connection(conf, fd);
                                if (r < 0)
                                        goto ERROR;
-
-                               // Connection closed?
-                               else if (r == 1) {
-                                       if (epoll_ctl(epollfd, EPOLL_CTL_DEL, fd, NULL)) {
-                                               ERROR(conf, "Could not remove socket file descriptfor from epoll(): %s\n",
-                                                       strerror(errno));
-                                       }
-                               }
                        }
                }
        }