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_LISTENING,
|
||||||
PATTY_AX25_SOCK_PENDING_ACCEPT,
|
PATTY_AX25_SOCK_PENDING_ACCEPT,
|
||||||
PATTY_AX25_SOCK_PENDING_CONNECT,
|
PATTY_AX25_SOCK_PENDING_CONNECT,
|
||||||
|
PATTY_AX25_SOCK_PENDING_DISCONNECT,
|
||||||
PATTY_AX25_SOCK_ESTABLISHED,
|
PATTY_AX25_SOCK_ESTABLISHED,
|
||||||
PATTY_AX25_SOCK_PROMISC
|
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) {
|
patty_ax25_sock *sock) {
|
||||||
fd_clear(server, sock->fd);
|
fd_clear(server, sock->fd);
|
||||||
|
|
||||||
return sock->status == PATTY_AX25_SOCK_ESTABLISHED?
|
if (sock->status != PATTY_AX25_SOCK_ESTABLISHED) {
|
||||||
patty_ax25_sock_send_disc(sock, PATTY_AX25_FRAME_POLL): 0;
|
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,
|
static int sock_save(patty_ax25_server *server,
|
||||||
|
@ -318,6 +323,7 @@ static int sock_save(patty_ax25_server *server,
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PATTY_AX25_SOCK_PENDING_DISCONNECT:
|
||||||
case PATTY_AX25_SOCK_CLOSED:
|
case PATTY_AX25_SOCK_CLOSED:
|
||||||
case PATTY_AX25_SOCK_PROMISC:
|
case PATTY_AX25_SOCK_PROMISC:
|
||||||
break;
|
break;
|
||||||
|
@ -360,6 +366,7 @@ static int sock_close(patty_ax25_server *server,
|
||||||
|
|
||||||
case PATTY_AX25_SOCK_PENDING_ACCEPT:
|
case PATTY_AX25_SOCK_PENDING_ACCEPT:
|
||||||
case PATTY_AX25_SOCK_PENDING_CONNECT:
|
case PATTY_AX25_SOCK_PENDING_CONNECT:
|
||||||
|
case PATTY_AX25_SOCK_PENDING_DISCONNECT:
|
||||||
case PATTY_AX25_SOCK_ESTABLISHED:
|
case PATTY_AX25_SOCK_ESTABLISHED:
|
||||||
if (sock_delete_remote(server, sock) < 0) {
|
if (sock_delete_remote(server, sock) < 0) {
|
||||||
goto error_sock_delete_remote;
|
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,
|
static int handle_frmr(patty_ax25_server *server,
|
||||||
patty_ax25_if *iface,
|
patty_ax25_if *iface,
|
||||||
|
patty_ax25_sock *sock,
|
||||||
patty_ax25_frame *frame) {
|
patty_ax25_frame *frame) {
|
||||||
patty_ax25_sock *sock;
|
if (sock == NULL) {
|
||||||
|
|
||||||
if ((sock = sock_by_addrpair(server->socks_remote,
|
|
||||||
&frame->dest,
|
|
||||||
&frame->src)) == NULL) {
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1216,14 +1220,12 @@ error_client_by_sock:
|
||||||
|
|
||||||
static int handle_ua(patty_ax25_server *server,
|
static int handle_ua(patty_ax25_server *server,
|
||||||
patty_ax25_if *iface,
|
patty_ax25_if *iface,
|
||||||
|
patty_ax25_sock *sock,
|
||||||
patty_ax25_frame *frame) {
|
patty_ax25_frame *frame) {
|
||||||
int client;
|
int client;
|
||||||
patty_ax25_sock *sock;
|
|
||||||
patty_ax25_call_connect_response response;
|
patty_ax25_call_connect_response response;
|
||||||
|
|
||||||
if ((sock = sock_by_addrpair(server->socks_remote,
|
if (sock == NULL) {
|
||||||
&frame->dest,
|
|
||||||
&frame->src)) == NULL) {
|
|
||||||
return reply_dm(iface, frame, PATTY_AX25_FRAME_FINAL);
|
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:
|
case PATTY_AX25_SOCK_PENDING_CONNECT:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PATTY_AX25_SOCK_ESTABLISHED:
|
case PATTY_AX25_SOCK_PENDING_DISCONNECT:
|
||||||
return sock_close(server, sock);
|
return sock_close(server, sock);
|
||||||
|
|
||||||
|
case PATTY_AX25_SOCK_ESTABLISHED:
|
||||||
|
return 0;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return reply_dm(iface, frame, PATTY_AX25_FRAME_FINAL);
|
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,
|
static int handle_dm(patty_ax25_server *server,
|
||||||
patty_ax25_if *iface,
|
patty_ax25_if *iface,
|
||||||
|
patty_ax25_sock *sock,
|
||||||
patty_ax25_frame *frame) {
|
patty_ax25_frame *frame) {
|
||||||
int client;
|
int client;
|
||||||
patty_ax25_sock *sock;
|
|
||||||
patty_ax25_call_connect_response response;
|
patty_ax25_call_connect_response response;
|
||||||
|
|
||||||
if ((sock = sock_by_addrpair(server->socks_remote,
|
if (sock == NULL || sock->status != PATTY_AX25_SOCK_PENDING_CONNECT) {
|
||||||
&frame->dest,
|
|
||||||
&frame->src)) == NULL) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sock->status != PATTY_AX25_SOCK_PENDING_CONNECT) {
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1332,22 +1331,27 @@ error_write:
|
||||||
|
|
||||||
static int handle_disc(patty_ax25_server *server,
|
static int handle_disc(patty_ax25_server *server,
|
||||||
patty_ax25_if *iface,
|
patty_ax25_if *iface,
|
||||||
|
patty_ax25_sock *sock,
|
||||||
patty_ax25_frame *frame) {
|
patty_ax25_frame *frame) {
|
||||||
patty_ax25_sock *sock;
|
if (sock == NULL) {
|
||||||
|
goto reply_dm;
|
||||||
if ((sock = sock_by_addrpair(server->socks_remote,
|
|
||||||
&frame->dest,
|
|
||||||
&frame->src)) == NULL) {
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sock->status != PATTY_AX25_SOCK_ESTABLISHED) {
|
switch (sock->status) {
|
||||||
return frame->pf? reply_dm(iface, frame, PATTY_AX25_FRAME_FINAL): 0;
|
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);
|
reply_dm:
|
||||||
|
return reply_dm(iface, frame, PATTY_AX25_FRAME_FINAL);
|
||||||
return reply_ua(iface, frame, PATTY_AX25_FRAME_FINAL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int handle_rej(patty_ax25_server *server,
|
static int handle_rej(patty_ax25_server *server,
|
||||||
|
@ -1355,6 +1359,10 @@ static int handle_rej(patty_ax25_server *server,
|
||||||
patty_ax25_frame *frame) {
|
patty_ax25_frame *frame) {
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
|
if (sock == NULL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
for (i=frame->nr; i<sock->seq_send; i++) {
|
for (i=frame->nr; i<sock->seq_send; i++) {
|
||||||
if (patty_ax25_sock_resend(sock, i) < 0) {
|
if (patty_ax25_sock_resend(sock, i) < 0) {
|
||||||
goto error_sock_resend;
|
goto error_sock_resend;
|
||||||
|
@ -1370,6 +1378,10 @@ error_sock_resend:
|
||||||
static int handle_srej(patty_ax25_server *server,
|
static int handle_srej(patty_ax25_server *server,
|
||||||
patty_ax25_sock *sock,
|
patty_ax25_sock *sock,
|
||||||
patty_ax25_frame *frame) {
|
patty_ax25_frame *frame) {
|
||||||
|
if (sock == NULL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TODO: Read the fine print of section 4.3.2.4
|
* 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) {
|
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_I: return handle_i(server, iface, sock, &frame);
|
||||||
case PATTY_AX25_FRAME_REJ: return handle_rej(server, 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_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_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:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Add table
Reference in a new issue