From 36f98bf7f05cf924ab08a494cd0fe482b4cc323d Mon Sep 17 00:00:00 2001 From: XANTRONIX Development Date: Wed, 5 Aug 2020 21:47:08 -0400 Subject: [PATCH] Improve SOCK_RAW facilities Changes: * Reimplement patty_ax25_sock_send() to be geared specifically for sending raw frames; the function which formerly held this name is now a private method * Implement patty_ax25_sock_recv() to receive a frame from a raw socket * Implement patty_ax25_sock_recv_pending() to determine how many raw frames are pending receipt in the buffer * When handling raw sockets, use patty_ax25_sock_recv_pending() to ensure any raw pending frames read from a client intended for transmission on an interface are read completely --- include/patty/ax25/sock.h | 12 ++-- src/server.c | 26 ++++--- src/sock.c | 146 ++++++++++++++++++++++++++------------ 3 files changed, 119 insertions(+), 65 deletions(-) diff --git a/include/patty/ax25/sock.h b/include/patty/ax25/sock.h index 498b93c..ac0fead 100644 --- a/include/patty/ax25/sock.h +++ b/include/patty/ax25/sock.h @@ -140,10 +140,14 @@ void patty_ax25_sock_vs_incr(patty_ax25_sock *sock); void patty_ax25_sock_vr_incr(patty_ax25_sock *sock); ssize_t patty_ax25_sock_send(patty_ax25_sock *sock, - enum patty_ax25_frame_cr cr, - uint16_t control, - void *info, - size_t infolen); + void *buf, + size_t len); + +ssize_t patty_ax25_sock_recv(patty_ax25_sock *sock, + void *buf, + size_t len); + +ssize_t patty_ax25_sock_recv_pending(patty_ax25_sock *sock); ssize_t patty_ax25_sock_resend(patty_ax25_sock *sock, unsigned int seq); diff --git a/src/server.c b/src/server.c index d87bcbe..fb13ec8 100644 --- a/src/server.c +++ b/src/server.c @@ -1736,25 +1736,23 @@ error_io: static int handle_sock_raw(patty_ax25_server *server, patty_ax25_sock *sock) { - ssize_t len; - int port; - if (!FD_ISSET(sock->fd, &server->fds_r) || sock->iface == NULL) { return 0; } - if ((len = patty_kiss_tnc_recv(sock->raw, - sock->iface->tx_buf, - sock->iface->mtu, - &port)) < 0) { - goto error_io; - } + do { + ssize_t len; - if (patty_ax25_if_send(sock->iface, - sock->iface->tx_buf, - len) < 0) { - goto error_io; - } + if ((len = patty_ax25_sock_recv(sock, + sock->iface->tx_buf, + sock->iface->mtu)) < 0) { + goto error_io; + } + + if (patty_ax25_sock_send(sock, sock->iface->tx_buf, len) < 0) { + goto error_io; + } + } while (patty_ax25_sock_recv_pending(sock)); return 0; diff --git a/src/sock.c b/src/sock.c index 94921d9..1c38559 100644 --- a/src/sock.c +++ b/src/sock.c @@ -421,10 +421,62 @@ error_toobig: } ssize_t patty_ax25_sock_send(patty_ax25_sock *sock, - enum patty_ax25_frame_cr cr, - uint16_t control, - void *info, - size_t infolen) { + void *buf, + size_t len) { + if (sock->type != PATTY_AX25_SOCK_RAW) { + errno = EINVAL; + + goto error_invalid_type; + } + + if (sock->iface == NULL) { + errno = ENETDOWN; + + goto error_noif; + } + + return patty_ax25_if_send(sock->iface, buf, len); + +error_noif: +error_invalid_type: + return -1; +} + +ssize_t patty_ax25_sock_recv(patty_ax25_sock *sock, + void *buf, + size_t len) { + int port; + + if (sock->type != PATTY_AX25_SOCK_RAW) { + errno = EINVAL; + + goto error_invalid_type; + } + + return patty_kiss_tnc_recv(sock->raw, buf, len, &port); + +error_invalid_type: + return -1; +} + +ssize_t patty_ax25_sock_recv_pending(patty_ax25_sock *sock) { + if (sock->type != PATTY_AX25_SOCK_RAW) { + errno = EINVAL; + + goto error_invalid_type; + } + + return patty_kiss_tnc_pending(sock->raw); + +error_invalid_type: + return -1; +} + +static ssize_t frame_send(patty_ax25_sock *sock, + enum patty_ax25_frame_cr cr, + uint16_t control, + void *info, + size_t infolen) { size_t offset = 0; ssize_t encoded; @@ -535,40 +587,40 @@ static uint16_t control_u(enum patty_ax25_frame_type type, ssize_t patty_ax25_sock_send_rr(patty_ax25_sock *sock, enum patty_ax25_frame_cr cr, int pf) { - return patty_ax25_sock_send(sock, - cr, - control_s(sock, PATTY_AX25_FRAME_RR, pf), - NULL, - 0); + return frame_send(sock, + cr, + control_s(sock, PATTY_AX25_FRAME_RR, pf), + NULL, + 0); } ssize_t patty_ax25_sock_send_rnr(patty_ax25_sock *sock, enum patty_ax25_frame_cr cr, int pf) { - return patty_ax25_sock_send(sock, - cr, - control_s(sock, PATTY_AX25_FRAME_RNR, pf), - NULL, - 0); + return frame_send(sock, + cr, + control_s(sock, PATTY_AX25_FRAME_RNR, pf), + NULL, + 0); } ssize_t patty_ax25_sock_send_rej(patty_ax25_sock *sock, enum patty_ax25_frame_cr cr, int pf) { - return patty_ax25_sock_send(sock, - cr, - control_s(sock, PATTY_AX25_FRAME_REJ, pf), - NULL, - 0); + return frame_send(sock, + cr, + control_s(sock, PATTY_AX25_FRAME_REJ, pf), + NULL, + 0); } ssize_t patty_ax25_sock_send_srej(patty_ax25_sock *sock, enum patty_ax25_frame_cr cr) { - return patty_ax25_sock_send(sock, - cr, - control_s(sock, PATTY_AX25_FRAME_SREJ, 1), - NULL, - 0); + return frame_send(sock, + cr, + control_s(sock, PATTY_AX25_FRAME_SREJ, 1), + NULL, + 0); } ssize_t patty_ax25_sock_send_sabm(patty_ax25_sock *sock, int pf) { @@ -576,19 +628,19 @@ ssize_t patty_ax25_sock_send_sabm(patty_ax25_sock *sock, int pf) { PATTY_AX25_FRAME_SABME: PATTY_AX25_FRAME_SABM; - return patty_ax25_sock_send(sock, - PATTY_AX25_FRAME_COMMAND, - control_u(type, pf), - NULL, - 0); + return frame_send(sock, + PATTY_AX25_FRAME_COMMAND, + control_u(type, pf), + NULL, + 0); } ssize_t patty_ax25_sock_send_disc(patty_ax25_sock *sock, int pf) { - return patty_ax25_sock_send(sock, - PATTY_AX25_FRAME_COMMAND, - control_u(PATTY_AX25_FRAME_DISC, pf), - NULL, - 0); + return frame_send(sock, + PATTY_AX25_FRAME_COMMAND, + control_u(PATTY_AX25_FRAME_DISC, pf), + NULL, + 0); } ssize_t patty_ax25_sock_send_xid(patty_ax25_sock *sock, @@ -622,11 +674,11 @@ ssize_t patty_ax25_sock_send_xid(patty_ax25_sock *sock, goto error_frame_encode_xid; } - return patty_ax25_sock_send(sock, - cr, - control_u(PATTY_AX25_FRAME_XID, 0), - buf, - encoded); + return frame_send(sock, + cr, + control_u(PATTY_AX25_FRAME_XID, 0), + buf, + encoded); error_frame_encode_xid: error_noif: @@ -637,11 +689,11 @@ ssize_t patty_ax25_sock_send_test(patty_ax25_sock *sock, enum patty_ax25_frame_cr cr, void *info, size_t infolen) { - return patty_ax25_sock_send(sock, - PATTY_AX25_FRAME_COMMAND, - control_u(PATTY_AX25_FRAME_TEST, 1), - info, - infolen); + return frame_send(sock, + PATTY_AX25_FRAME_COMMAND, + control_u(PATTY_AX25_FRAME_TEST, 1), + info, + infolen); } ssize_t patty_ax25_sock_write(patty_ax25_sock *sock, @@ -661,15 +713,15 @@ ssize_t patty_ax25_sock_write(patty_ax25_sock *sock, control = control_i(sock, 0); - if (patty_ax25_sock_send(sock, PATTY_AX25_FRAME_COMMAND, control, buf, len) < 0) { - goto error_send; + if (frame_send(sock, PATTY_AX25_FRAME_COMMAND, control, buf, len) < 0) { + goto error_frame_send; } patty_ax25_sock_vs_incr(sock); return len; -error_send: +error_frame_send: error_invalid_mode: return -1; }