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;
|
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:
|
||||||
|
|
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 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,
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue