From 0819a324c1e103f40208fa4c613ebcc0e8a28b4a Mon Sep 17 00:00:00 2001 From: Daniel Collins Date: Sun, 5 Jan 2014 19:45:45 +0000 Subject: [PATCH] Refactored address table code. - Use process+socket as key rather than local port number. - Store socket protocol in table. - Removed ADDR_TABLE_ENTRY_REUSE flag. --- src/addrtable.c | 56 ++++++++++++++++++++++++++++++------------------- src/addrtable.h | 18 +++++++++++----- src/winsock.c | 12 +++++------ 3 files changed, 53 insertions(+), 33 deletions(-) diff --git a/src/addrtable.c b/src/addrtable.c index b7e7c59..052216c 100644 --- a/src/addrtable.c +++ b/src/addrtable.c @@ -130,7 +130,7 @@ void addr_table_cleanup(void) { if(s->flags & IPX_BOUND) { - addr_table_remove(s->port); + addr_table_remove(s); } } } @@ -299,7 +299,7 @@ uint16_t addr_table_auto_socket(void) * Performs no conflict checking. Take the address table lock in the caller and * use addr_table_check() before calling this. */ -void addr_table_add(const struct sockaddr_ipx *addr, uint16_t port) +void addr_table_add(const ipx_socket *sock) { if(!addr_table_base) { @@ -322,14 +322,27 @@ void addr_table_add(const struct sockaddr_ipx *addr, uint16_t port) if(entry < end) { - entry->netnum = addr32_in(addr->sa_netnum); - entry->nodenum = addr48_in(addr->sa_nodenum); - entry->socket = addr->sa_socket; + entry->netnum = addr32_in(sock->addr.sa_netnum); + entry->nodenum = addr48_in(sock->addr.sa_nodenum); + entry->socket = sock->addr.sa_socket; - entry->flags = ADDR_TABLE_ENTRY_VALID | ADDR_TABLE_ENTRY_REUSE; + if(sock->flags & IPX_IS_SPXII) + { + entry->type = ADDR_TABLE_TYPE_SPXII; + } + else if(sock->flags & IPX_IS_SPX) + { + entry->type = ADDR_TABLE_TYPE_SPX; + } + else{ + entry->type = ADDR_TABLE_TYPE_IPX; + } - entry->port = port; - entry->time = time(NULL); + entry->process = GetCurrentProcessId(); + entry->sock = sock->fd; + + entry->flags = ADDR_TABLE_ENTRY_VALID; + entry->time = time(NULL); } else{ log_printf(LOG_ERROR, "Out of address table slots, not appending!"); @@ -339,7 +352,7 @@ void addr_table_add(const struct sockaddr_ipx *addr, uint16_t port) } /* Remove an entry from the address table. */ -void addr_table_remove(uint16_t port) +void addr_table_remove(const ipx_socket *sock) { if(!addr_table_base) { @@ -353,20 +366,19 @@ void addr_table_remove(uint16_t port) addr_table_entry_t *entry = addr_table_base; addr_table_entry_t *end = addr_table_base + ADDR_TABLE_MAX_ENTRIES; - while(entry < end && (entry->flags & ADDR_TABLE_ENTRY_VALID) && entry->port != port) + while(entry < end && (entry->flags & ADDR_TABLE_ENTRY_VALID)) { - entry++; - } - - addr_table_entry_t *last = _last_entry(); - - /* Replace entry with the last entry and mark the latter as invalid. */ - - if(entry < end) - { - *entry = *last; + if(entry->process == GetCurrentProcessId() && entry->sock == sock->fd) + { + addr_table_entry_t *last = _last_entry(); + + *entry = *last; + last->flags &= ~ADDR_TABLE_ENTRY_VALID; + + break; + } - last->flags &= ~ADDR_TABLE_ENTRY_VALID; + ++entry; } addr_table_unlock(); @@ -415,7 +427,7 @@ void addr_table_update(void) for(entry = addr_table_base; entry < end && (entry->flags & ADDR_TABLE_ENTRY_VALID); entry++) { - if(entry->port == sock->port) + if(entry->process == GetCurrentProcessId() && entry->sock == sock->fd) { entry->time = time(NULL); break; diff --git a/src/addrtable.h b/src/addrtable.h index 884f0b3..8320d46 100644 --- a/src/addrtable.h +++ b/src/addrtable.h @@ -23,6 +23,7 @@ #include #include "addr.h" +#include "ipxwrapper.h" #define ADDR_TABLE_MAX_ENTRIES 512 #define ADDR_TABLE_ENTRY_TIMEOUT 10 @@ -30,7 +31,7 @@ #define ADDR_TABLE_MUTEX "IPXWrapper_addr_table_mutex" #define ADDR_TABLE_NAME "IPXWrapper_addr_table" -#define ADDR_TABLE_VERSION 1 +#define ADDR_TABLE_VERSION 2 typedef struct addr_table_header addr_table_header_t; @@ -40,7 +41,6 @@ struct addr_table_header }; #define ADDR_TABLE_ENTRY_VALID ((int)(1<<0)) -#define ADDR_TABLE_ENTRY_REUSE ((int)(1<<1)) typedef struct addr_table_entry addr_table_entry_t; @@ -50,8 +50,16 @@ struct addr_table_entry addr48_t nodenum; uint16_t socket; + enum { + ADDR_TABLE_TYPE_IPX, + ADDR_TABLE_TYPE_SPX, + ADDR_TABLE_TYPE_SPXII + } type; + + DWORD process; + int sock; + int flags; - uint16_t port; time_t time; }; @@ -64,8 +72,8 @@ void addr_table_unlock(void); bool addr_table_check(const struct sockaddr_ipx *addr); uint16_t addr_table_auto_socket(void); -void addr_table_add(const struct sockaddr_ipx *addr, uint16_t port); -void addr_table_remove(uint16_t port); +void addr_table_add(const ipx_socket *sock); +void addr_table_remove(const ipx_socket *sock); void addr_table_update(void); diff --git a/src/winsock.c b/src/winsock.c index bda829f..cb9597b 100644 --- a/src/winsock.c +++ b/src/winsock.c @@ -263,7 +263,7 @@ int WSAAPI closesocket(SOCKET sockfd) if(sock->flags & IPX_BOUND) { - addr_table_remove(sock->port); + addr_table_remove(sock); } HASH_DEL(sockets, sock); @@ -448,15 +448,15 @@ int WSAAPI bind(SOCKET fd, const struct sockaddr *addr, int addrlen) log_printf(LOG_DEBUG, "Bound to local UDP port %hu", ntohs(sock->port)); - /* Add to the address table. */ - - addr_table_add(&ipxaddr, sock->port); - - /* Mark the IPX socket as bound. */ + /* Mark the IPX socket as bound and insert it into the address + * table. + */ memcpy(&(sock->addr), &ipxaddr, sizeof(ipxaddr)); sock->flags |= IPX_BOUND; + addr_table_add(sock); + addr_table_unlock(); unlock_sockets();