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"
This commit is contained in:
parent
8ab4c24b4a
commit
7ed169d7cc
1 changed files with 46 additions and 4 deletions
50
src/server.c
50
src/server.c
|
@ -20,7 +20,8 @@ struct _patty_ax25_server {
|
||||||
int fd, /* fd of UNIX domain socket */
|
int fd, /* fd of UNIX domain socket */
|
||||||
fd_max;
|
fd_max;
|
||||||
|
|
||||||
struct timeval timeout;
|
struct timeval timer,
|
||||||
|
elapsed;
|
||||||
|
|
||||||
fd_set fds_watch, /* fds to monitor with select() */
|
fd_set fds_watch, /* fds to monitor with select() */
|
||||||
fds_r; /* fds select()ed for reading */
|
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);
|
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
|
* 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,
|
* 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 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return sock->status == PATTY_AX25_SOCK_PENDING_CONNECT?
|
if (sock->status == PATTY_AX25_SOCK_PENDING_CONNECT) {
|
||||||
patty_ax25_sock_send_sabm(sock, PATTY_AX25_FRAME_POLL): 0;
|
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,
|
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);
|
return reply_dm(iface, frame, PATTY_AX25_FRAME_FINAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
patty_ax25_sock_timer_ack_cancel(sock);
|
||||||
|
|
||||||
sock->status = PATTY_AX25_SOCK_ESTABLISHED;
|
sock->status = PATTY_AX25_SOCK_ESTABLISHED;
|
||||||
|
|
||||||
if ((client = client_by_sock(server, sock)) < 0) {
|
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;
|
remote->mode = PATTY_AX25_SOCK_SABME;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
patty_ax25_sock_timer_ack_restart(remote);
|
||||||
|
|
||||||
return patty_ax25_sock_send_sabm(remote, PATTY_AX25_FRAME_POLL);
|
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;
|
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)) {
|
if (!FD_ISSET(sock->fd, &server->fds_r)) {
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
@ -1660,16 +1689,29 @@ int patty_ax25_server_run(patty_ax25_server *server) {
|
||||||
while (1) {
|
while (1) {
|
||||||
int nready;
|
int nready;
|
||||||
|
|
||||||
|
struct timeval remaining,
|
||||||
|
*timer;
|
||||||
|
|
||||||
memcpy(&server->fds_r, &server->fds_watch, sizeof(server->fds_r));
|
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,
|
if ((nready = select( server->fd_max,
|
||||||
&server->fds_r,
|
&server->fds_r,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL)) < 0) {
|
timer)) < 0) {
|
||||||
goto error_io;
|
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) {
|
if (handle_clients(server) < 0) {
|
||||||
goto error_io;
|
goto error_io;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue