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;
int fd,
sock,
pty;
sock;
patty_ax25_addr peer;
char path[PATTY_AX25_SOCK_PATH_SIZE];
@ -42,6 +41,8 @@ int main(int argc, char **argv) {
uint8_t buf[4096];
ssize_t readlen;
patty_kiss_tnc *raw;
if (argc != 2) {
usage(argc, argv, "No patty socket provided");
}
@ -79,14 +80,14 @@ int main(int argc, char **argv) {
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",
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;
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);
@ -114,7 +115,9 @@ int main(int argc, char **argv) {
error_print_frame:
error_ax25_frame_decode:
error_open_pty:
patty_kiss_tnc_destroy(raw);
error_kiss_tnc_new:
patty_ax25_call_close(fd, sock);
error_call_setsockopt:

View file

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