diff --git a/src/config.h b/src/config.h index a91108f..5f3706c 100644 --- a/src/config.h +++ b/src/config.h @@ -28,7 +28,8 @@ #define MAX_SESSIONS 4096 /* maximum number of opened sessions */ #define MAX_SESSIONS_PER_IP 4096 /* maximum number of sessions from a single IP */ #define MAX_TCP_CONN 4096 /* maximum number of TCP connections */ -#define SESSION_TIMEOUT 21600 /* Sessions are thrown out after no contact for this many seconds. 0 = no timeout */ +#define SESSION_TIMEOUT 600 /* Sessions are thrown out after no contact for this many seconds. 0 = no timeout */ +#define CONN_TIMEOUT 600 /* TCP connections are thrown out after no contact for this many seconds. 0 = no timeout */ #define TNFS_HEADERSZ 4 /* minimum header size */ #define TNFS_MAX_PAYLOAD (MAXMSGSZ - TNFS_HEADERSZ - 1) /* Maximum usuable payload in a UDP datagram (-1 for status byte) */ #define MAX_TNFSPATH 256 /* maximum path length */ diff --git a/src/datagram.c b/src/datagram.c index 342b8d1..903c9fd 100644 --- a/src/datagram.c +++ b/src/datagram.c @@ -221,6 +221,8 @@ void tnfs_mainloop() while (1) { + tnfs_close_stale_connections(tcpsocks); + event_wait_res_t *wait_res = tnfs_event_wait(1); if (wait_res->size == SOCKET_ERROR) { @@ -301,6 +303,7 @@ void tcp_accept(TcpConnection *tcp_conn_list) MSGLOG(cliaddr.sin_addr.s_addr, "New TCP connection at index %d.", i); tcp_conn->cli_fd = acc_fd; tcp_conn->cliaddr = cliaddr; + tcp_conn->last_contact = time(NULL); return; } tcp_conn++; @@ -361,6 +364,8 @@ void tnfs_handle_tcpmsg(TcpConnection *tcp_conn) unsigned char buf[MAXMSGSZ]; int sz; + tcp_conn->last_contact = time(NULL); + sz = recv(tcp_conn->cli_fd, (char *)buf, sizeof(buf), 0); #ifdef WIN32 @@ -375,6 +380,14 @@ void tnfs_handle_tcpmsg(TcpConnection *tcp_conn) if (sz <= 0) { MSGLOG(tcp_conn->cliaddr.sin_addr.s_addr, "Client disconnected, closing socket."); + tnfs_close_tcp(tcp_conn); + return; + } + tnfs_decode(&tcp_conn->cliaddr, tcp_conn->cli_fd, sz, buf); +} + +void tnfs_close_tcp(TcpConnection *tcp_conn) +{ tnfs_reset_cli_fd_in_sessions(tcp_conn->cli_fd); #ifdef WIN32 @@ -384,9 +397,6 @@ void tnfs_handle_tcpmsg(TcpConnection *tcp_conn) #endif tnfs_event_unregister(tcp_conn->cli_fd); tcp_conn->cli_fd = 0; - return; - } - tnfs_decode(&tcp_conn->cliaddr, tcp_conn->cli_fd, sz, buf); } void tnfs_decode(struct sockaddr_in *cliaddr, int cli_fd, int rxbytes, unsigned char *rxbuf) @@ -575,3 +585,21 @@ void tnfs_resend(Session *sess, struct sockaddr_in *cliaddr, int cli_fd) "Retransmit was truncated"); } } + +void tnfs_close_stale_connections(TcpConnection *tcp_conn_list) +{ + time_t now = time(NULL); + TcpConnection *tcp_conn = tcp_conn_list; + for (int i = 0; i < MAX_TCP_CONN; i++) + { + if (tcp_conn->cli_fd != 0) + { + if ((now - tcp_conn->last_contact) > CONN_TIMEOUT) + { + MSGLOG(tcp_conn->cliaddr.sin_addr.s_addr, "Socket is no longer active; disconnecting."); + tnfs_close_tcp(tcp_conn); + } + } + tcp_conn++; + } +} diff --git a/src/datagram.h b/src/datagram.h index 8f58666..4cdb2ff 100644 --- a/src/datagram.h +++ b/src/datagram.h @@ -57,4 +57,6 @@ void tnfs_badcommand(Header *hdr, Session *sess); void tnfs_notpermitted(Header *hdr); void tnfs_send(Session *sess, Header *hdr, unsigned char *msg, int msgsz); void tnfs_resend(Session *sess, struct sockaddr_in *cliaddr, int cli_fd); +void tnfs_close_stale_connections(TcpConnection *tcp_conn_list); +void tnfs_close_tcp(TcpConnection *tcp_conn); #endif diff --git a/src/tnfs.h b/src/tnfs.h index 07095db..312cda9 100644 --- a/src/tnfs.h +++ b/src/tnfs.h @@ -157,6 +157,7 @@ typedef struct _tcp_conn { struct sockaddr_in cliaddr; /* client address */ int cli_fd; /* FD for the TCP connection */ + time_t last_contact; /* timestamp of last received request */ } TcpConnection; #endif