Make bind() perform more validation

Changes:

    * Make bind() validate that no other socket has the same
      callsign/SSID bound to a listening socket, emitting EADDRINUSE if
      one already exists

    * Make bind() validate that no address is already bound to the
      socket, emitting EINVAL otherwise
This commit is contained in:
XANTRONIX Development 2020-07-23 17:58:29 -04:00 committed by XANTRONIX Industrial
parent 529112225a
commit 3657c883c7
3 changed files with 20 additions and 4 deletions

View file

@ -64,7 +64,7 @@ int patty_ax25_call_setsockopt(int server,
*/
typedef struct _patty_ax25_call_bind_request {
int fd;
patty_ax25_addr peer;
patty_ax25_addr addr;
} patty_ax25_call_bind_request;
typedef struct _patty_ax25_call_bind_response {

View file

@ -82,7 +82,7 @@ error_io:
int patty_ax25_call_bind(int server,
int fd,
patty_ax25_addr *peer) {
patty_ax25_addr *addr) {
enum patty_ax25_call call = PATTY_AX25_CALL_BIND;
patty_ax25_call_bind_request request = {
@ -91,7 +91,7 @@ int patty_ax25_call_bind(int server,
patty_ax25_call_bind_response response;
memcpy(&request.peer, peer, sizeof(*peer));
memcpy(&request.addr, addr, sizeof(*addr));
if (write(server, &call, sizeof(call)) < 0) {
goto error_io;

View file

@ -624,6 +624,20 @@ static int server_bind(patty_ax25_server *server,
goto error_sock_by_fd;
}
if (sock->local.callsign[0] != '\0') {
response.ret = -1;
response.eno = EINVAL;
goto error_bound;
}
if (sock_by_addr(server->socks_local, &request.addr) != NULL) {
response.ret = -1;
response.eno = EADDRINUSE;
goto error_exists;
}
switch (sock->status) {
case PATTY_AX25_SOCK_LISTENING:
case PATTY_AX25_SOCK_ESTABLISHED:
@ -636,12 +650,14 @@ static int server_bind(patty_ax25_server *server,
break;
}
memcpy(&sock->local, &request.peer, sizeof(request.peer));
memcpy(&sock->local, &request.addr, sizeof(request.addr));
response.ret = 0;
response.eno = 0;
error_invalid_status:
error_exists:
error_bound:
error_sock_by_fd:
return write(client, &response, sizeof(response));