Use KISS framing for raw sockets

Use KISS framing for raw sockets to avoid multiple write() calls from
being buffered, which caused read() on the other end of a file
descriptor to read more than frame at once
This commit is contained in:
XANTRONIX Development 2020-07-08 18:29:27 -04:00 committed by XANTRONIX Industrial
parent b281925eba
commit ebbfb50b1c
3 changed files with 32 additions and 22 deletions

View file

@ -33,8 +33,7 @@ int main(int argc, char **argv) {
patty_ax25_call_setsockopt_if ifreq; patty_ax25_call_setsockopt_if ifreq;
int fd, int fd,
sock, sock;
pty;
patty_ax25_addr peer; patty_ax25_addr peer;
char path[PATTY_AX25_SOCK_PATH_SIZE]; char path[PATTY_AX25_SOCK_PATH_SIZE];
@ -42,6 +41,8 @@ int main(int argc, char **argv) {
uint8_t buf[4096]; uint8_t buf[4096];
ssize_t readlen; ssize_t readlen;
patty_kiss_tnc *raw;
if (argc != 2) { if (argc != 2) {
usage(argc, argv, "No patty socket provided"); usage(argc, argv, "No patty socket provided");
} }
@ -79,14 +80,14 @@ int main(int argc, char **argv) {
goto error_call_setsockopt; goto error_call_setsockopt;
} }
if ((pty = open(path, O_RDWR)) < 0) { if ((raw = patty_kiss_tnc_new(path)) == NULL) {
fprintf(stderr, "%s: %s: %s: %s\n", fprintf(stderr, "%s: %s: %s: %s\n",
argv[0], path, "open()", strerror(errno)); argv[0], path, "patty_kiss_tnc_new()", strerror(errno));
goto error_open_pty; goto error_kiss_tnc_new;
} }
while ((readlen = read(pty, buf, sizeof(buf))) > 0) { while ((readlen = patty_kiss_tnc_recv(raw, buf, sizeof(buf), NULL)) > 0) {
patty_ax25_frame frame; patty_ax25_frame frame;
if (patty_ax25_frame_decode(&frame, PATTY_AX25_FRAME_NORMAL, buf, readlen) < 0) { if (patty_ax25_frame_decode(&frame, PATTY_AX25_FRAME_NORMAL, buf, readlen) < 0) {
@ -104,7 +105,7 @@ int main(int argc, char **argv) {
} }
} }
close(pty); patty_kiss_tnc_destroy(raw);
patty_ax25_call_close(fd, sock); patty_ax25_call_close(fd, sock);
@ -114,7 +115,9 @@ int main(int argc, char **argv) {
error_print_frame: error_print_frame:
error_ax25_frame_decode: error_ax25_frame_decode:
error_open_pty: patty_kiss_tnc_destroy(raw);
error_kiss_tnc_new:
patty_ax25_call_close(fd, sock); patty_ax25_call_close(fd, sock);
error_call_setsockopt: error_call_setsockopt:

View file

@ -273,15 +273,21 @@ error_ntop:
int patty_ax25_if_promisc_add(patty_ax25_if *iface, int patty_ax25_if_promisc_add(patty_ax25_if *iface,
int fd) { int fd) {
patty_kiss_tnc *tnc;
if (patty_dict_get(iface->promisc_fds, (uint32_t)fd)) { if (patty_dict_get(iface->promisc_fds, (uint32_t)fd)) {
errno = EEXIST; errno = EEXIST;
goto error_exists; goto error_exists;
} }
if ((tnc = patty_kiss_tnc_new_fd(fd)) == NULL) {
goto error_kiss_tnc_new_fd;
}
if (patty_dict_set(iface->promisc_fds, if (patty_dict_set(iface->promisc_fds,
(uint32_t)fd, (uint32_t)fd,
NULL + fd) == NULL) { tnc) == NULL) {
errno = ENOMEM; errno = ENOMEM;
goto error_dict_set; goto error_dict_set;
@ -290,20 +296,26 @@ int patty_ax25_if_promisc_add(patty_ax25_if *iface,
return 0; return 0;
error_dict_set: error_dict_set:
patty_kiss_tnc_destroy(tnc);
error_kiss_tnc_new_fd:
error_exists: error_exists:
return -1; return -1;
} }
int patty_ax25_if_promisc_delete(patty_ax25_if *iface, int patty_ax25_if_promisc_delete(patty_ax25_if *iface,
int fd) { int fd) {
if (patty_dict_delete(iface->promisc_fds, patty_kiss_tnc *tnc;
(uint32_t)fd) < 0) {
if ((tnc = patty_dict_get(iface->promisc_fds, (uint32_t)fd)) == NULL) {
errno = ENOENT; errno = ENOENT;
goto error_notfound; goto error_notfound;
} }
return 0; patty_kiss_tnc_destroy(tnc);
return patty_dict_delete(iface->promisc_fds, (uint32_t)fd);
error_notfound: error_notfound:
return -1; return -1;
@ -318,17 +330,10 @@ struct promisc_frame {
static int handle_promisc_frame(uint32_t key, static int handle_promisc_frame(uint32_t key,
void *value, void *value,
void *ctx) { void *ctx) {
int fd = (int)key; patty_kiss_tnc *tnc = value;
struct promisc_frame *frame = ctx; struct promisc_frame *frame = ctx;
if (write(fd, frame->buf, frame->len) < 0) { return patty_kiss_tnc_send(tnc, frame->buf, frame->len, 0);
goto error_write;
}
return tcdrain(fd);
error_write:
return -1;
} }
ssize_t patty_ax25_if_recv(patty_ax25_if *iface, ssize_t patty_ax25_if_recv(patty_ax25_if *iface,

View file

@ -183,7 +183,9 @@ ssize_t patty_kiss_tnc_recv(patty_kiss_tnc *tnc,
goto error_io; goto error_io;
} }
*port = PATTY_KISS_COMMAND_PORT(c); if (port) {
*port = PATTY_KISS_COMMAND_PORT(c);
}
flags |= KISS_COMMAND; flags |= KISS_COMMAND;