#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);
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);
}
int fireperf_server(struct fireperf_config* conf) {
+ struct fireperf_server_stats stats;
+
DEBUG(conf, "Launching " PACKAGE_NAME " in server mode\n");
int sockfd = -1;
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)) {
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));
- }
- }
}
}
}