Better handle read()s of multiple frames from TNC

Implement better handling of situations when read() captures multiple
TNC frames; ensure each frame is handled in src/server.c, function
handle_iface(), to ensure packets aren't ignored before the next
select() call
This commit is contained in:
XANTRONIX Development 2020-07-12 22:14:58 -04:00 committed by XANTRONIX Industrial
parent f0c1a0e782
commit 905d5b117c
5 changed files with 34 additions and 9 deletions

View file

@ -82,6 +82,8 @@ int patty_ax25_if_promisc_add(patty_ax25_if *iface,
int patty_ax25_if_promisc_delete(patty_ax25_if *iface,
int fd);
ssize_t patty_ax25_if_pending(patty_ax25_if *iface);
ssize_t patty_ax25_if_recv(patty_ax25_if *iface,
void **buf);

View file

@ -39,6 +39,8 @@ void patty_kiss_tnc_destroy(patty_kiss_tnc *tnc);
size_t patty_kiss_tnc_dropped(patty_kiss_tnc *tnc);
ssize_t patty_kiss_tnc_pending(patty_kiss_tnc *tnc);
ssize_t patty_kiss_tnc_recv(patty_kiss_tnc *tnc,
void *buf,
size_t len,

View file

@ -336,6 +336,10 @@ static int handle_promisc_frame(uint32_t key,
return patty_kiss_tnc_send(tnc, frame->buf, frame->len, 0);
}
ssize_t patty_ax25_if_pending(patty_ax25_if *iface) {
return patty_kiss_tnc_pending(iface->tnc);
}
ssize_t patty_ax25_if_recv(patty_ax25_if *iface,
void **buf) {
ssize_t readlen;
@ -347,6 +351,8 @@ ssize_t patty_ax25_if_recv(patty_ax25_if *iface,
iface->rx_bufsz,
&port)) < 0) {
goto error_kiss_tnc_recv;
} else if (readlen == 0) {
goto done;
}
*buf = iface->rx_buf;
@ -364,6 +370,7 @@ ssize_t patty_ax25_if_recv(patty_ax25_if *iface,
goto error_handle_promisc_frame;
}
done:
return readlen;
error_handle_promisc_frame:

View file

@ -109,6 +109,18 @@ size_t patty_kiss_tnc_dropped(patty_kiss_tnc *tnc) {
return tnc->dropped;
}
ssize_t patty_kiss_tnc_pending(patty_kiss_tnc *tnc) {
if (tnc->readlen < 0) {
return -1;
}
if (tnc->offset == 0) {
return 0;
}
return tnc->readlen - tnc->offset;
}
ssize_t patty_kiss_tnc_recv(patty_kiss_tnc *tnc,
void *buf,
size_t len,

View file

@ -1342,17 +1342,19 @@ static int handle_iface(patty_ax25_server *server, patty_ax25_if *iface) {
goto done;
}
if ((readlen = patty_ax25_if_recv(iface, &buf)) < 0) {
goto error_io;
} else if (readlen == 0) {
fd_clear(server, fd);
do {
if ((readlen = patty_ax25_if_recv(iface, &buf)) < 0) {
goto error_io;
} else if (readlen == 0) {
fd_clear(server, fd);
goto done;
}
goto done;
}
if (handle_frame(server, iface, buf, readlen) < 0) {
goto error_io;
}
if (handle_frame(server, iface, buf, readlen) < 0) {
goto error_io;
}
} while (patty_ax25_if_pending(iface));
done:
return 0;