Prevent UA frame from terminating socket w/o DISC
Changes: * Add a "pending disconnect" state to enum patty_ax25_sock_state (PATTY_AX25_SOCK_PENDING_DISCONNECT), used when an originating system sends a DISC frame, pending a UA response * When handling a UA frame, rather than terminating a socket in the established state implicitly, check for a "pending disconnect" state explicitly Other changes: * When a remote socket has already been obtained in handle_frame() in src/server.c, pass that socket to any other method that would otherwise be looking up the same socket
This commit is contained in:
parent
8761a4e3c2
commit
e06a9d195e
2 changed files with 50 additions and 37 deletions
|
@ -30,6 +30,7 @@ enum patty_ax25_sock_status {
|
|||
PATTY_AX25_SOCK_LISTENING,
|
||||
PATTY_AX25_SOCK_PENDING_ACCEPT,
|
||||
PATTY_AX25_SOCK_PENDING_CONNECT,
|
||||
PATTY_AX25_SOCK_PENDING_DISCONNECT,
|
||||
PATTY_AX25_SOCK_ESTABLISHED,
|
||||
PATTY_AX25_SOCK_PROMISC
|
||||
};
|
||||
|
|
86
src/server.c
86
src/server.c
|
@ -292,8 +292,13 @@ static int sock_shutdown(patty_ax25_server *server,
|
|||
patty_ax25_sock *sock) {
|
||||
fd_clear(server, sock->fd);
|
||||
|
||||
return sock->status == PATTY_AX25_SOCK_ESTABLISHED?
|
||||
patty_ax25_sock_send_disc(sock, PATTY_AX25_FRAME_POLL): 0;
|
||||
if (sock->status != PATTY_AX25_SOCK_ESTABLISHED) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
sock->status = PATTY_AX25_SOCK_PENDING_DISCONNECT;
|
||||
|
||||
return patty_ax25_sock_send_disc(sock, PATTY_AX25_FRAME_POLL);
|
||||
}
|
||||
|
||||
static int sock_save(patty_ax25_server *server,
|
||||
|
@ -318,6 +323,7 @@ static int sock_save(patty_ax25_server *server,
|
|||
|
||||
break;
|
||||
|
||||
case PATTY_AX25_SOCK_PENDING_DISCONNECT:
|
||||
case PATTY_AX25_SOCK_CLOSED:
|
||||
case PATTY_AX25_SOCK_PROMISC:
|
||||
break;
|
||||
|
@ -360,6 +366,7 @@ static int sock_close(patty_ax25_server *server,
|
|||
|
||||
case PATTY_AX25_SOCK_PENDING_ACCEPT:
|
||||
case PATTY_AX25_SOCK_PENDING_CONNECT:
|
||||
case PATTY_AX25_SOCK_PENDING_DISCONNECT:
|
||||
case PATTY_AX25_SOCK_ESTABLISHED:
|
||||
if (sock_delete_remote(server, sock) < 0) {
|
||||
goto error_sock_delete_remote;
|
||||
|
@ -1130,12 +1137,9 @@ static int reply_ua(patty_ax25_if *iface,
|
|||
|
||||
static int handle_frmr(patty_ax25_server *server,
|
||||
patty_ax25_if *iface,
|
||||
patty_ax25_sock *sock,
|
||||
patty_ax25_frame *frame) {
|
||||
patty_ax25_sock *sock;
|
||||
|
||||
if ((sock = sock_by_addrpair(server->socks_remote,
|
||||
&frame->dest,
|
||||
&frame->src)) == NULL) {
|
||||
if (sock == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1216,14 +1220,12 @@ error_client_by_sock:
|
|||
|
||||
static int handle_ua(patty_ax25_server *server,
|
||||
patty_ax25_if *iface,
|
||||
patty_ax25_sock *sock,
|
||||
patty_ax25_frame *frame) {
|
||||
int client;
|
||||
patty_ax25_sock *sock;
|
||||
patty_ax25_call_connect_response response;
|
||||
|
||||
if ((sock = sock_by_addrpair(server->socks_remote,
|
||||
&frame->dest,
|
||||
&frame->src)) == NULL) {
|
||||
if (sock == NULL) {
|
||||
return reply_dm(iface, frame, PATTY_AX25_FRAME_FINAL);
|
||||
}
|
||||
|
||||
|
@ -1231,9 +1233,12 @@ static int handle_ua(patty_ax25_server *server,
|
|||
case PATTY_AX25_SOCK_PENDING_CONNECT:
|
||||
break;
|
||||
|
||||
case PATTY_AX25_SOCK_ESTABLISHED:
|
||||
case PATTY_AX25_SOCK_PENDING_DISCONNECT:
|
||||
return sock_close(server, sock);
|
||||
|
||||
case PATTY_AX25_SOCK_ESTABLISHED:
|
||||
return 0;
|
||||
|
||||
default:
|
||||
return reply_dm(iface, frame, PATTY_AX25_FRAME_FINAL);
|
||||
}
|
||||
|
@ -1269,18 +1274,12 @@ error_client_by_sock:
|
|||
|
||||
static int handle_dm(patty_ax25_server *server,
|
||||
patty_ax25_if *iface,
|
||||
patty_ax25_sock *sock,
|
||||
patty_ax25_frame *frame) {
|
||||
int client;
|
||||
patty_ax25_sock *sock;
|
||||
patty_ax25_call_connect_response response;
|
||||
|
||||
if ((sock = sock_by_addrpair(server->socks_remote,
|
||||
&frame->dest,
|
||||
&frame->src)) == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (sock->status != PATTY_AX25_SOCK_PENDING_CONNECT) {
|
||||
if (sock == NULL || sock->status != PATTY_AX25_SOCK_PENDING_CONNECT) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1332,22 +1331,27 @@ error_write:
|
|||
|
||||
static int handle_disc(patty_ax25_server *server,
|
||||
patty_ax25_if *iface,
|
||||
patty_ax25_sock *sock,
|
||||
patty_ax25_frame *frame) {
|
||||
patty_ax25_sock *sock;
|
||||
|
||||
if ((sock = sock_by_addrpair(server->socks_remote,
|
||||
&frame->dest,
|
||||
&frame->src)) == NULL) {
|
||||
return 0;
|
||||
if (sock == NULL) {
|
||||
goto reply_dm;
|
||||
}
|
||||
|
||||
if (sock->status != PATTY_AX25_SOCK_ESTABLISHED) {
|
||||
return frame->pf? reply_dm(iface, frame, PATTY_AX25_FRAME_FINAL): 0;
|
||||
switch (sock->status) {
|
||||
case PATTY_AX25_SOCK_ESTABLISHED:
|
||||
(void)sock_close(server, sock);
|
||||
|
||||
return reply_ua(iface, frame, PATTY_AX25_FRAME_FINAL);
|
||||
|
||||
case PATTY_AX25_SOCK_PENDING_DISCONNECT:
|
||||
return 0;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
(void)sock_close(server, sock);
|
||||
|
||||
return reply_ua(iface, frame, PATTY_AX25_FRAME_FINAL);
|
||||
reply_dm:
|
||||
return reply_dm(iface, frame, PATTY_AX25_FRAME_FINAL);
|
||||
}
|
||||
|
||||
static int handle_rej(patty_ax25_server *server,
|
||||
|
@ -1355,6 +1359,10 @@ static int handle_rej(patty_ax25_server *server,
|
|||
patty_ax25_frame *frame) {
|
||||
unsigned int i;
|
||||
|
||||
if (sock == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i=frame->nr; i<sock->seq_send; i++) {
|
||||
if (patty_ax25_sock_resend(sock, i) < 0) {
|
||||
goto error_sock_resend;
|
||||
|
@ -1370,6 +1378,10 @@ error_sock_resend:
|
|||
static int handle_srej(patty_ax25_server *server,
|
||||
patty_ax25_sock *sock,
|
||||
patty_ax25_frame *frame) {
|
||||
if (sock == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: Read the fine print of section 4.3.2.4
|
||||
*/
|
||||
|
@ -1525,16 +1537,16 @@ static int handle_frame(patty_ax25_server *server,
|
|||
}
|
||||
|
||||
switch (frame.type) {
|
||||
case PATTY_AX25_FRAME_UA: return handle_ua(server, iface, &frame);
|
||||
case PATTY_AX25_FRAME_DM: return handle_dm(server, iface, &frame);
|
||||
case PATTY_AX25_FRAME_SABM:
|
||||
case PATTY_AX25_FRAME_SABME: return handle_sabm(server, iface, &frame);
|
||||
case PATTY_AX25_FRAME_DISC: return handle_disc(server, iface, &frame);
|
||||
case PATTY_AX25_FRAME_I: return handle_i(server, iface, sock, &frame);
|
||||
case PATTY_AX25_FRAME_REJ: return handle_rej(server, sock, &frame);
|
||||
case PATTY_AX25_FRAME_SREJ: return handle_srej(server, sock, &frame);
|
||||
case PATTY_AX25_FRAME_XID: return handle_xid(server, iface, &frame, buf, offset, len);
|
||||
case PATTY_AX25_FRAME_FRMR: return handle_frmr(server, iface, &frame);
|
||||
case PATTY_AX25_FRAME_SABM:
|
||||
case PATTY_AX25_FRAME_SABME: return handle_sabm(server, iface, &frame);
|
||||
case PATTY_AX25_FRAME_UA: return handle_ua(server, iface, sock, &frame);
|
||||
case PATTY_AX25_FRAME_DM: return handle_dm(server, iface, sock, &frame);
|
||||
case PATTY_AX25_FRAME_DISC: return handle_disc(server, iface, sock, &frame);
|
||||
case PATTY_AX25_FRAME_FRMR: return handle_frmr(server, iface, sock, &frame);
|
||||
|
||||
default:
|
||||
break;
|
||||
|
|
Loading…
Add table
Reference in a new issue