Well, I have WORKING FREAKING SESSIONS BAYBEE

This commit is contained in:
XANTRONIX Development 2020-07-01 20:15:46 -04:00 committed by XANTRONIX Industrial
parent 22bf692a61
commit 2b1bc4c30e
2 changed files with 132 additions and 108 deletions

View file

@ -50,7 +50,7 @@
(((c & 0xe0) == 0x20) && ((c & 0x0f) == 0x0f))
#define PATTY_AX25_CONTROL_UNNUMBERED_DISC(c) \
(((c & 0xe0) == 0x20) && ((c & 0x0f) == 0x03))
(((c & 0xe0) == 0x40) && ((c & 0x0f) == 0x03))
#define PATTY_AX25_CONTROL_UNNUMBERED_DM(c) \
(((c & 0xe0) == 0x00) && ((c & 0x0f) == 0x0f))

View file

@ -117,6 +117,28 @@ static int destroy_if(patty_ax25_if *iface, void *ctx) {
return 0;
}
static inline void watch_fd(patty_ax25_server *server, int fd) {
FD_SET(fd, &server->fds_watch);
if (server->fd_max <= fd) {
server->fd_max = fd + 1;
}
}
static inline void clear_fd(patty_ax25_server *server, int fd) {
int i;
FD_CLR(fd, &server->fds_watch);
for (i=0; i<8*sizeof(&server->fds_watch); i++) {
if (FD_ISSET(i, &server->fds_watch)) {
server->fd_max = i;
}
}
server->fd_max++;
}
static patty_ax25_sock *sock_by_fd(patty_dict *dict,
int fd) {
return patty_dict_get_with_hash(dict, (uint32_t)fd);
@ -161,15 +183,33 @@ error_dict_set:
return -1;
}
static int sock_save_by_addr(patty_dict *dict,
patty_ax25_sock *sock,
patty_ax25_addr *addr) {
static inline uint32_t hash_addr(patty_ax25_addr *addr) {
uint32_t hash;
patty_hash_init(&hash);
patty_ax25_addr_hash(&hash, addr);
patty_hash_end(&hash);
return hash;
}
static inline uint32_t hash_addrpair(patty_ax25_addr *local,
patty_ax25_addr *remote) {
uint32_t hash;
patty_hash_init(&hash);
patty_ax25_addr_hash(&hash, local);
patty_ax25_addr_hash(&hash, remote);
patty_hash_end(&hash);
return hash;
}
static int sock_save_by_addr(patty_dict *dict,
patty_ax25_sock *sock,
patty_ax25_addr *addr) {
uint32_t hash = hash_addr(addr);
if (patty_dict_set_with_hash(dict,
addr,
sizeof(*addr),
@ -188,12 +228,7 @@ static int sock_save_by_addrpair(patty_dict *dict,
patty_ax25_sock *sock,
patty_ax25_addr *local,
patty_ax25_addr *remote) {
uint32_t hash;
patty_hash_init(&hash);
patty_ax25_addr_hash(&hash, local);
patty_ax25_addr_hash(&hash, remote);
patty_hash_end(&hash);
uint32_t hash = hash_addrpair(local, remote);
if (patty_dict_set_with_hash(dict,
sock,
@ -209,67 +244,9 @@ error_dict_set_with_hash:
return -1;
}
static int sock_delete(patty_ax25_server *server,
patty_ax25_sock *sock) {
if (sock->status == PATTY_AX25_SOCK_ESTABLISHED) {
uint32_t hash;
patty_hash_init(&hash);
patty_ax25_addr_hash(&hash, &sock->local);
patty_ax25_addr_hash(&hash, &sock->remote);
patty_hash_end(&hash);
if (patty_dict_delete_with_hash(server->socks_established, hash) < 0) {
goto error_dict_delete_established;
}
}
if (sock->status == PATTY_AX25_SOCK_PENDING_CONNECT) {
uint32_t hash;
patty_hash_init(&hash);
patty_ax25_addr_hash(&hash, &sock->local);
patty_hash_end(&hash);
if (patty_dict_delete_with_hash(server->socks_pending_connect, hash) < 0) {
goto error_dict_delete_pending_connect;
}
}
if (sock->status == PATTY_AX25_SOCK_PENDING_ACCEPT) {
uint32_t hash;
patty_hash_init(&hash);
patty_ax25_addr_hash(&hash, &sock->local);
patty_hash_end(&hash);
if (patty_dict_delete_with_hash(server->socks_pending_accept, hash) < 0) {
goto error_dict_delete_pending_accept;
}
}
if (patty_dict_delete_with_hash(server->socks_by_fd, sock->fd) < 0) {
goto error_dict_delete_by_fd;
}
free(sock);
return 0;
error_dict_delete_by_fd:
error_dict_delete_pending_accept:
error_dict_delete_pending_connect:
error_dict_delete_established:
return -1;
}
static int sock_delete_by_addr(patty_dict *dict,
patty_ax25_addr *addr) {
uint32_t hash;
patty_hash_init(&hash);
patty_ax25_addr_hash(&hash, addr);
patty_hash_end(&hash);
uint32_t hash = hash_addr(addr);
return patty_dict_delete_with_hash(dict, hash);
}
@ -277,38 +254,59 @@ static int sock_delete_by_addr(patty_dict *dict,
static int sock_delete_by_addrpair(patty_dict *dict,
patty_ax25_addr *local,
patty_ax25_addr *remote) {
uint32_t hash;
patty_hash_init(&hash);
patty_ax25_addr_hash(&hash, local);
patty_ax25_addr_hash(&hash, remote);
patty_hash_end(&hash);
uint32_t hash = hash_addrpair(local, remote);
return patty_dict_delete_with_hash(dict, hash);
}
static inline void watch_fd(patty_ax25_server *server, int fd) {
FD_SET(fd, &server->fds_watch);
static int sock_close(patty_ax25_server *server,
patty_ax25_sock *sock) {
if (sock->status == PATTY_AX25_SOCK_ESTABLISHED) {
if (patty_ax25_sock_send_disc(sock, 1) < 0) {
goto error_sock_send_disc;
}
if (server->fd_max <= fd) {
server->fd_max = fd + 1;
if (sock_delete_by_addrpair(server->socks_established,
&sock->local,
&sock->remote) < 0) {
goto error_sock_delete_by_addrpair_established;
}
}
}
static inline void clear_fd(patty_ax25_server *server, int fd) {
FD_CLR(fd, &server->fds_watch);
if (server->fd_max == fd + 1) {
server->fd_max--;
if (sock->status == PATTY_AX25_SOCK_PENDING_CONNECT) {
if (sock_delete_by_addrpair(server->socks_pending_connect,
&sock->local,
&sock->remote) < 0) {
goto error_sock_delete_by_addrpair_pending_connect;
}
}
}
static inline void watch_sock(patty_ax25_server *server, patty_ax25_sock *sock) {
watch_fd(server, sock->fd);
}
if (sock->status == PATTY_AX25_SOCK_PENDING_ACCEPT) {
if (sock_delete_by_addr(server->socks_pending_accept,
&sock->local) < 0) {
goto error_sock_delete_by_addr_pending_accept;
}
}
if (patty_dict_delete_with_hash(server->socks_by_fd, sock->fd) < 0) {
goto error_dict_delete_by_fd_socks;
}
(void)patty_dict_delete_with_hash(server->clients_by_sock, sock->fd);
static inline void clear_sock(patty_ax25_server *server, patty_ax25_sock *sock) {
clear_fd(server, sock->fd);
patty_ax25_sock_destroy(sock);
return 0;
error_dict_delete_by_fd_clients:
error_dict_delete_by_fd_socks:
error_sock_delete_by_addr_pending_accept:
error_sock_delete_by_addrpair_pending_connect:
error_sock_delete_by_addrpair_established:
error_sock_send_disc:
return -1;
}
int patty_ax25_server_add_if(patty_ax25_server *server,
@ -741,25 +739,19 @@ static int server_close(patty_ax25_server *server,
goto error_sock_by_fd;
}
if (sock_delete(server, sock) < 0) {
if (sock_close(server, sock) < 0) {
response.ret = -1;
response.eno = EBADF;
goto error_sock_delete;
}
if (close(request.socket) < 0) {
response.ret = -1;
response.eno = errno;
goto error_close;
}
response.ret = 0;
response.eno = 0;
error_close:
error_sock_delete:
error_sock_send_disc:
error_sock_by_fd:
if (write(client, &response, sizeof(response)) < 0) {
goto error_io;
@ -1058,7 +1050,7 @@ static int handle_sabm(patty_ax25_server *server,
goto error_write;
}
watch_sock(server, remote);
watch_fd(server, remote->fd);
return 0;
@ -1115,7 +1107,7 @@ static int handle_ua(patty_ax25_server *server,
goto error_write;
}
watch_sock(server, sock);
watch_fd(server, sock->fd);
return 0;
@ -1135,6 +1127,12 @@ static int handle_dm(patty_ax25_server *server,
patty_ax25_sock *sock;
patty_ax25_call_connect_response response;
if ((sock = sock_by_addrpair(server->socks_established,
&frame->dest,
&frame->src)) != NULL) {
return sock_close(server, sock);
}
if ((sock = sock_by_addrpair(server->socks_pending_connect,
&frame->dest,
&frame->src)) == NULL) {
@ -1192,6 +1190,10 @@ static int handle_info(patty_ax25_server *server,
goto done;
}
/*
* TODO: Validate RX and TX sequence numbers
*/
if (write(sock->fd, frame->info, frame->infolen) < 0) {
goto error_write;
}
@ -1203,6 +1205,27 @@ error_write:
return -1;
}
static int handle_disc(patty_ax25_server *server,
patty_ax25_if *iface,
patty_ax25_frame *frame) {
patty_ax25_sock *sock;
if ((sock = sock_by_addrpair(server->socks_established,
&frame->dest,
&frame->src)) == NULL) {
return reply_frmr(iface, frame, PATTY_AX25_FRAME_U_FINAL);
}
if (sock_close(server, sock) < 0) {
goto error_sock_delete;
}
return reply_dm(iface, frame, PATTY_AX25_FRAME_U_FINAL);
error_sock_delete:
return -1;
}
static int handle_frame(patty_ax25_server *server,
patty_ax25_if *iface,
void *buf,
@ -1226,6 +1249,8 @@ static int handle_frame(patty_ax25_server *server,
return handle_dm(server, iface, &frame);
} else if (PATTY_AX25_CONTROL_INFO(frame.control)) {
return handle_info(server, iface, &frame);
} else if (PATTY_AX25_CONTROL_UNNUMBERED_DISC(frame.control)) {
return handle_disc(server, iface, &frame);
}
return 0;
@ -1304,15 +1329,15 @@ static int handle_sock(void *key,
}
if ((len = read(sock->fd, sock->buf, sock->bufsz)) < 0) {
if (errno == EIO) {
(void)sock_close(server, sock);
goto done;
}
goto error_io;
} else if (len == 0) {
clear_sock(server, sock);
if (patty_dict_delete(server->socks_established,
NULL + fd,
sizeof(fd)) < 0) {
goto error_dict_delete;
}
sock_close(server, sock);
goto done;
}
@ -1325,7 +1350,6 @@ done:
return 0;
error_sock_write:
error_dict_delete:
error_io:
return -1;
}