Well, I have WORKING FREAKING SESSIONS BAYBEE
This commit is contained in:
parent
22bf692a61
commit
2b1bc4c30e
2 changed files with 132 additions and 108 deletions
|
@ -50,7 +50,7 @@
|
||||||
(((c & 0xe0) == 0x20) && ((c & 0x0f) == 0x0f))
|
(((c & 0xe0) == 0x20) && ((c & 0x0f) == 0x0f))
|
||||||
|
|
||||||
#define PATTY_AX25_CONTROL_UNNUMBERED_DISC(c) \
|
#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) \
|
#define PATTY_AX25_CONTROL_UNNUMBERED_DM(c) \
|
||||||
(((c & 0xe0) == 0x00) && ((c & 0x0f) == 0x0f))
|
(((c & 0xe0) == 0x00) && ((c & 0x0f) == 0x0f))
|
||||||
|
|
238
src/server.c
238
src/server.c
|
@ -117,6 +117,28 @@ static int destroy_if(patty_ax25_if *iface, void *ctx) {
|
||||||
return 0;
|
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,
|
static patty_ax25_sock *sock_by_fd(patty_dict *dict,
|
||||||
int fd) {
|
int fd) {
|
||||||
return patty_dict_get_with_hash(dict, (uint32_t)fd);
|
return patty_dict_get_with_hash(dict, (uint32_t)fd);
|
||||||
|
@ -161,15 +183,33 @@ error_dict_set:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sock_save_by_addr(patty_dict *dict,
|
static inline uint32_t hash_addr(patty_ax25_addr *addr) {
|
||||||
patty_ax25_sock *sock,
|
|
||||||
patty_ax25_addr *addr) {
|
|
||||||
uint32_t hash;
|
uint32_t hash;
|
||||||
|
|
||||||
patty_hash_init(&hash);
|
patty_hash_init(&hash);
|
||||||
patty_ax25_addr_hash(&hash, addr);
|
patty_ax25_addr_hash(&hash, addr);
|
||||||
patty_hash_end(&hash);
|
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,
|
if (patty_dict_set_with_hash(dict,
|
||||||
addr,
|
addr,
|
||||||
sizeof(*addr),
|
sizeof(*addr),
|
||||||
|
@ -188,12 +228,7 @@ static int sock_save_by_addrpair(patty_dict *dict,
|
||||||
patty_ax25_sock *sock,
|
patty_ax25_sock *sock,
|
||||||
patty_ax25_addr *local,
|
patty_ax25_addr *local,
|
||||||
patty_ax25_addr *remote) {
|
patty_ax25_addr *remote) {
|
||||||
uint32_t hash;
|
uint32_t hash = hash_addrpair(local, remote);
|
||||||
|
|
||||||
patty_hash_init(&hash);
|
|
||||||
patty_ax25_addr_hash(&hash, local);
|
|
||||||
patty_ax25_addr_hash(&hash, remote);
|
|
||||||
patty_hash_end(&hash);
|
|
||||||
|
|
||||||
if (patty_dict_set_with_hash(dict,
|
if (patty_dict_set_with_hash(dict,
|
||||||
sock,
|
sock,
|
||||||
|
@ -209,67 +244,9 @@ error_dict_set_with_hash:
|
||||||
return -1;
|
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,
|
static int sock_delete_by_addr(patty_dict *dict,
|
||||||
patty_ax25_addr *addr) {
|
patty_ax25_addr *addr) {
|
||||||
uint32_t hash;
|
uint32_t hash = hash_addr(addr);
|
||||||
|
|
||||||
patty_hash_init(&hash);
|
|
||||||
patty_ax25_addr_hash(&hash, addr);
|
|
||||||
patty_hash_end(&hash);
|
|
||||||
|
|
||||||
return patty_dict_delete_with_hash(dict, hash);
|
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,
|
static int sock_delete_by_addrpair(patty_dict *dict,
|
||||||
patty_ax25_addr *local,
|
patty_ax25_addr *local,
|
||||||
patty_ax25_addr *remote) {
|
patty_ax25_addr *remote) {
|
||||||
uint32_t hash;
|
uint32_t hash = hash_addrpair(local, remote);
|
||||||
|
|
||||||
patty_hash_init(&hash);
|
|
||||||
patty_ax25_addr_hash(&hash, local);
|
|
||||||
patty_ax25_addr_hash(&hash, remote);
|
|
||||||
patty_hash_end(&hash);
|
|
||||||
|
|
||||||
return patty_dict_delete_with_hash(dict, hash);
|
return patty_dict_delete_with_hash(dict, hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void watch_fd(patty_ax25_server *server, int fd) {
|
static int sock_close(patty_ax25_server *server,
|
||||||
FD_SET(fd, &server->fds_watch);
|
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) {
|
if (sock_delete_by_addrpair(server->socks_established,
|
||||||
server->fd_max = fd + 1;
|
&sock->local,
|
||||||
|
&sock->remote) < 0) {
|
||||||
|
goto error_sock_delete_by_addrpair_established;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static inline void clear_fd(patty_ax25_server *server, int fd) {
|
if (sock->status == PATTY_AX25_SOCK_PENDING_CONNECT) {
|
||||||
FD_CLR(fd, &server->fds_watch);
|
if (sock_delete_by_addrpair(server->socks_pending_connect,
|
||||||
|
&sock->local,
|
||||||
if (server->fd_max == fd + 1) {
|
&sock->remote) < 0) {
|
||||||
server->fd_max--;
|
goto error_sock_delete_by_addrpair_pending_connect;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static inline void watch_sock(patty_ax25_server *server, patty_ax25_sock *sock) {
|
if (sock->status == PATTY_AX25_SOCK_PENDING_ACCEPT) {
|
||||||
watch_fd(server, sock->fd);
|
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);
|
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,
|
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;
|
goto error_sock_by_fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sock_delete(server, sock) < 0) {
|
if (sock_close(server, sock) < 0) {
|
||||||
response.ret = -1;
|
response.ret = -1;
|
||||||
response.eno = EBADF;
|
response.eno = EBADF;
|
||||||
|
|
||||||
goto error_sock_delete;
|
goto error_sock_delete;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (close(request.socket) < 0) {
|
|
||||||
response.ret = -1;
|
|
||||||
response.eno = errno;
|
|
||||||
|
|
||||||
goto error_close;
|
|
||||||
}
|
|
||||||
|
|
||||||
response.ret = 0;
|
response.ret = 0;
|
||||||
response.eno = 0;
|
response.eno = 0;
|
||||||
|
|
||||||
error_close:
|
error_close:
|
||||||
error_sock_delete:
|
error_sock_delete:
|
||||||
|
error_sock_send_disc:
|
||||||
error_sock_by_fd:
|
error_sock_by_fd:
|
||||||
if (write(client, &response, sizeof(response)) < 0) {
|
if (write(client, &response, sizeof(response)) < 0) {
|
||||||
goto error_io;
|
goto error_io;
|
||||||
|
@ -1058,7 +1050,7 @@ static int handle_sabm(patty_ax25_server *server,
|
||||||
goto error_write;
|
goto error_write;
|
||||||
}
|
}
|
||||||
|
|
||||||
watch_sock(server, remote);
|
watch_fd(server, remote->fd);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -1115,7 +1107,7 @@ static int handle_ua(patty_ax25_server *server,
|
||||||
goto error_write;
|
goto error_write;
|
||||||
}
|
}
|
||||||
|
|
||||||
watch_sock(server, sock);
|
watch_fd(server, sock->fd);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -1135,6 +1127,12 @@ static int handle_dm(patty_ax25_server *server,
|
||||||
patty_ax25_sock *sock;
|
patty_ax25_sock *sock;
|
||||||
patty_ax25_call_connect_response response;
|
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,
|
if ((sock = sock_by_addrpair(server->socks_pending_connect,
|
||||||
&frame->dest,
|
&frame->dest,
|
||||||
&frame->src)) == NULL) {
|
&frame->src)) == NULL) {
|
||||||
|
@ -1192,6 +1190,10 @@ static int handle_info(patty_ax25_server *server,
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO: Validate RX and TX sequence numbers
|
||||||
|
*/
|
||||||
|
|
||||||
if (write(sock->fd, frame->info, frame->infolen) < 0) {
|
if (write(sock->fd, frame->info, frame->infolen) < 0) {
|
||||||
goto error_write;
|
goto error_write;
|
||||||
}
|
}
|
||||||
|
@ -1203,6 +1205,27 @@ error_write:
|
||||||
return -1;
|
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,
|
static int handle_frame(patty_ax25_server *server,
|
||||||
patty_ax25_if *iface,
|
patty_ax25_if *iface,
|
||||||
void *buf,
|
void *buf,
|
||||||
|
@ -1226,6 +1249,8 @@ static int handle_frame(patty_ax25_server *server,
|
||||||
return handle_dm(server, iface, &frame);
|
return handle_dm(server, iface, &frame);
|
||||||
} else if (PATTY_AX25_CONTROL_INFO(frame.control)) {
|
} else if (PATTY_AX25_CONTROL_INFO(frame.control)) {
|
||||||
return handle_info(server, iface, &frame);
|
return handle_info(server, iface, &frame);
|
||||||
|
} else if (PATTY_AX25_CONTROL_UNNUMBERED_DISC(frame.control)) {
|
||||||
|
return handle_disc(server, iface, &frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1304,15 +1329,15 @@ static int handle_sock(void *key,
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((len = read(sock->fd, sock->buf, sock->bufsz)) < 0) {
|
if ((len = read(sock->fd, sock->buf, sock->bufsz)) < 0) {
|
||||||
|
if (errno == EIO) {
|
||||||
|
(void)sock_close(server, sock);
|
||||||
|
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
goto error_io;
|
goto error_io;
|
||||||
} else if (len == 0) {
|
} else if (len == 0) {
|
||||||
clear_sock(server, sock);
|
sock_close(server, sock);
|
||||||
|
|
||||||
if (patty_dict_delete(server->socks_established,
|
|
||||||
NULL + fd,
|
|
||||||
sizeof(fd)) < 0) {
|
|
||||||
goto error_dict_delete;
|
|
||||||
}
|
|
||||||
|
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
@ -1325,7 +1350,6 @@ done:
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error_sock_write:
|
error_sock_write:
|
||||||
error_dict_delete:
|
|
||||||
error_io:
|
error_io:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue