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:
parent
b281925eba
commit
ebbfb50b1c
3 changed files with 32 additions and 22 deletions
|
@ -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:
|
||||
|
|
31
src/if.c
31
src/if.c
|
@ -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,
|
||||
|
|
|
@ -183,7 +183,9 @@ ssize_t patty_kiss_tnc_recv(patty_kiss_tnc *tnc,
|
|||
goto error_io;
|
||||
}
|
||||
|
||||
*port = PATTY_KISS_COMMAND_PORT(c);
|
||||
if (port) {
|
||||
*port = PATTY_KISS_COMMAND_PORT(c);
|
||||
}
|
||||
|
||||
flags |= KISS_COMMAND;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue