From f1035e971bb894203bdfba6cafbaf0bb30f197eb Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Mon, 25 Feb 2019 09:57:57 +0100 Subject: [PATCH] Small fixes for utcp_abort_all_connections(). - Make utcp_reset_connection() a private function. - Ensure we don't repeat any action when aborting a connection twice. - Call the receive callback after resetting the connection, so the callback function can safely call utcp_close(). --- utcp.c | 70 +++++++++++++++++++++++++++++----------------------------- utcp.h | 1 - 2 files changed, 35 insertions(+), 36 deletions(-) diff --git a/utcp.c b/utcp.c index 7591e19..d09b9e7 100644 --- a/utcp.c +++ b/utcp.c @@ -1598,38 +1598,16 @@ int utcp_shutdown(struct utcp_connection *c, int dir) { return 0; } -// Closes all the opened connections -void utcp_abort_all_connections(struct utcp *utcp) { - if(!utcp) { - return; - } - - for(int i = 0; i < utcp->nconnections; i++) { - struct utcp_connection *c = utcp->connections[i]; - - if(c->recv) { - errno = 0; - c->recv(c, NULL, 0); - } - - if(utcp_reset_connection(c) != -1) { - c->reapable = false; - } - } - - return; -} - -int utcp_reset_connection(struct utcp_connection *c) { +static bool reset_connection(struct utcp_connection *c) { if(!c) { errno = EFAULT; - return -1; + return false; } if(c->reapable) { debug("Error: abort() called on closed connection %p\n", c); errno = EBADF; - return -1; + return false; } c->recv = NULL; @@ -1637,7 +1615,7 @@ int utcp_reset_connection(struct utcp_connection *c) { switch(c->state) { case CLOSED: - return 0; + return true; case LISTEN: case SYN_SENT: @@ -1645,7 +1623,7 @@ int utcp_reset_connection(struct utcp_connection *c) { case LAST_ACK: case TIME_WAIT: set_state(c, CLOSED); - return 0; + return true; case SYN_RECEIVED: case ESTABLISHED: @@ -1669,7 +1647,32 @@ int utcp_reset_connection(struct utcp_connection *c) { print_packet(c->utcp, "send", &hdr, sizeof(hdr)); c->utcp->send(c->utcp, &hdr, sizeof(hdr)); - return 0; + return true; +} + +// Closes all the opened connections +void utcp_abort_all_connections(struct utcp *utcp) { + if(!utcp) { + errno = EINVAL; + return; + } + + for(int i = 0; i < utcp->nconnections; i++) { + struct utcp_connection *c = utcp->connections[i]; + + if(c->reapable || c->state == CLOSED) { + continue; + } + + reset_connection(c); + + if(c->recv) { + errno = 0; + c->recv(c, NULL, 0); + } + } + + return; } int utcp_close(struct utcp_connection *c) { @@ -1684,15 +1687,12 @@ int utcp_close(struct utcp_connection *c) { } int utcp_abort(struct utcp_connection *c) { - int utcp_reset_return; - - utcp_reset_return = utcp_reset_connection(c); - - if(utcp_reset_return != -1) { - c->reapable = true; + if(!reset_connection(c)) { + return -1; } - return utcp_reset_return; + c->reapable = true; + return 0; } /* Handle timeouts. diff --git a/utcp.h b/utcp.h index 0cad458..fe4c720 100644 --- a/utcp.h +++ b/utcp.h @@ -78,7 +78,6 @@ extern void utcp_set_poll_cb(struct utcp_connection *connection, utcp_poll_t pol 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); extern void utcp_abort_all_connections(struct utcp *utcp); -extern int utcp_reset_connection(struct utcp_connection *c); // Global socket options -- 2.39.5