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
This commit is contained in:
XANTRONIX Development 2020-08-05 21:47:08 -04:00 committed by XANTRONIX Industrial
parent d0d17b58fb
commit 36f98bf7f0
3 changed files with 119 additions and 65 deletions

View file

@ -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);

View file

@ -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;

View file

@ -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;
}