From 7ed169d7cc0be8a03111c3a96a33358ae1904204 Mon Sep 17 00:00:00 2001 From: XANTRONIX Development Date: Mon, 27 Jul 2020 00:52:25 -0400 Subject: [PATCH] Implement XID, SABM, SABME ack timer in server Implement XID, SABM, SABME ack Timer T1 semantics in src/server.c, as per AX.25 v2.2 Section 6.3.1 "Link Connection Establishment" --- src/server.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 46 insertions(+), 4 deletions(-) diff --git a/src/server.c b/src/server.c index ee697f0..83b8cae 100644 --- a/src/server.c +++ b/src/server.c @@ -20,7 +20,8 @@ struct _patty_ax25_server { int fd, /* fd of UNIX domain socket */ fd_max; - struct timeval timeout; + struct timeval timer, + elapsed; fd_set fds_watch, /* fds to monitor with select() */ fds_r; /* fds select()ed for reading */ @@ -828,6 +829,8 @@ static int server_connect(patty_ax25_server *server, return respond_connect(client, -1, errno); } + patty_ax25_sock_timer_ack_restart(sock); + /* * At this point, we will wait for a DM, FRMR or XID response, which * will help us determine what version of AX.25 to apply for this socket, @@ -1146,8 +1149,13 @@ static int handle_frmr(patty_ax25_server *server, return 0; } - return sock->status == PATTY_AX25_SOCK_PENDING_CONNECT? - patty_ax25_sock_send_sabm(sock, PATTY_AX25_FRAME_POLL): 0; + if (sock->status == PATTY_AX25_SOCK_PENDING_CONNECT) { + patty_ax25_sock_timer_ack_restart(sock); + + return patty_ax25_sock_send_sabm(sock, PATTY_AX25_FRAME_POLL); + } + + return 0; } static int handle_sabm(patty_ax25_server *server, @@ -1240,6 +1248,8 @@ static int handle_ua(patty_ax25_server *server, return reply_dm(iface, frame, PATTY_AX25_FRAME_FINAL); } + patty_ax25_sock_timer_ack_cancel(sock); + sock->status = PATTY_AX25_SOCK_ESTABLISHED; if ((client = client_by_sock(server, sock)) < 0) { @@ -1436,6 +1446,7 @@ static int handle_xid(patty_ax25_server *server, remote->mode = PATTY_AX25_SOCK_SABME; } + patty_ax25_sock_timer_ack_restart(remote); return patty_ax25_sock_send_sabm(remote, PATTY_AX25_FRAME_POLL); } @@ -1611,6 +1622,24 @@ static int handle_sock(uint32_t key, ssize_t len; + if (sock->status == PATTY_AX25_SOCK_PENDING_CONNECT) { + if (patty_ax25_sock_timer_ack_expired(sock)) { + if (sock->retries) { + patty_ax25_sock_timer_ack_restart(sock); + + return patty_ax25_sock_send_sabm(sock, PATTY_AX25_FRAME_POLL); + } else { + (void)sock_shutdown(server, sock); + + return sock_close(server, sock); + } + } else { + patty_ax25_sock_timer_ack_sub(sock, &server->elapsed); + } + + goto done; + } + if (!FD_ISSET(sock->fd, &server->fds_r)) { goto done; } @@ -1660,16 +1689,29 @@ int patty_ax25_server_run(patty_ax25_server *server) { while (1) { int nready; + struct timeval remaining, + *timer; + memcpy(&server->fds_r, &server->fds_watch, sizeof(server->fds_r)); + memcpy(&remaining, &server->timer, sizeof(remaining)); + + timer = timerisset(&remaining)? &remaining: NULL; if ((nready = select( server->fd_max, &server->fds_r, NULL, NULL, - NULL)) < 0) { + timer)) < 0) { goto error_io; } + if (timer) { + timersub(&server->timer, &remaining, &server->elapsed); + memcpy(&server->timer, &remaining, sizeof(server->timer)); + } else { + timerclear(&server->elapsed); + } + if (handle_clients(server) < 0) { goto error_io; }