From 905d5b117c9e3b23a57efe950bbad79dd08a0cb6 Mon Sep 17 00:00:00 2001 From: XANTRONIX Development Date: Sun, 12 Jul 2020 22:14:58 -0400 Subject: [PATCH] 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 --- include/patty/ax25/if.h | 2 ++ include/patty/kiss.h | 2 ++ src/if.c | 7 +++++++ src/kiss.c | 12 ++++++++++++ src/server.c | 20 +++++++++++--------- 5 files changed, 34 insertions(+), 9 deletions(-) diff --git a/include/patty/ax25/if.h b/include/patty/ax25/if.h index a3c6c1a..e8313d7 100644 --- a/include/patty/ax25/if.h +++ b/include/patty/ax25/if.h @@ -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); diff --git a/include/patty/kiss.h b/include/patty/kiss.h index 090bfbf..2fb34bc 100644 --- a/include/patty/kiss.h +++ b/include/patty/kiss.h @@ -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, diff --git a/src/if.c b/src/if.c index 46e67b0..61e56c0 100644 --- a/src/if.c +++ b/src/if.c @@ -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: diff --git a/src/kiss.c b/src/kiss.c index cb4d895..0f734e2 100644 --- a/src/kiss.c +++ b/src/kiss.c @@ -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, diff --git a/src/server.c b/src/server.c index 482f05e..a456ca8 100644 --- a/src/server.c +++ b/src/server.c @@ -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;