From 2049874f3c436cc1d85bb8bcccb272a3b933f4a9 Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Sun, 11 Oct 2015 16:31:59 +0200 Subject: [PATCH] Add a function to check for active connections. If a connection sends data in one way, then the receiver will have shut down data in the other way, and when the sender is finished he will also shut down his direction, so the connection looks closed to the sender, but the receiver might actually still miss the final packets. So UTCP should keep running until the receiver has received a FINACK and is in the TIME_WAIT state. We consider UTCP to be active when there is at least one connection not in the CLOSED or TIME_WAIT state. The test program now uses this condition, which allows a transfer of a file to complete without missing the last few bytes. --- test.c | 2 +- utcp.c | 11 +++++++++++ utcp.h | 1 + 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/test.c b/test.c index a37f856..0eb8462 100644 --- a/test.c +++ b/test.c @@ -109,7 +109,7 @@ int main(int argc, char *argv[]) { char buf[102400]; struct timeval timeout = utcp_timeout(u); - while(dir) { + while(!connected || utcp_is_active(u)) { size_t max = c ? utcp_get_sndbuf_free(c) : 0; if(max > sizeof buf) max = sizeof buf; diff --git a/utcp.c b/utcp.c index 062cc5a..c63def1 100644 --- a/utcp.c +++ b/utcp.c @@ -1154,6 +1154,17 @@ struct timeval utcp_timeout(struct utcp *utcp) { return diff; } +bool utcp_is_active(struct utcp *utcp) { + if(!utcp) + return false; + + for(int i = 0; i < utcp->nconnections; i++) + if(utcp->connections[i]->state != CLOSED && utcp->connections[i]->state != TIME_WAIT) + return true; + + return false; +} + struct utcp *utcp_init(utcp_accept_t accept, utcp_pre_accept_t pre_accept, utcp_send_t send, void *priv) { struct utcp *utcp = calloc(1, sizeof *utcp); if(!utcp) diff --git a/utcp.h b/utcp.h index 8d3874f..085a287 100644 --- a/utcp.h +++ b/utcp.h @@ -62,6 +62,7 @@ extern struct timeval utcp_timeout(struct utcp *utcp); extern void utcp_set_recv_cb(struct utcp_connection *connection, utcp_recv_t recv); extern void utcp_set_poll_cb(struct utcp_connection *connection, utcp_poll_t poll); extern void utcp_set_accept_cb(struct utcp *utcp, utcp_accept_t accept, utcp_pre_accept_t pre_accept); +extern bool utcp_is_active(struct utcp *utcp); // Global socket options -- 2.39.5