1
0
mirror of https://github.com/solemnwarning/ipxwrapper synced 2024-12-30 16:45:37 +01:00

Use a hash table instead of a linked list for storing the IPX sockets.

This commit is contained in:
Daniel Collins 2012-11-11 20:54:43 +00:00
parent 920b5ee2c3
commit 2a06601f53
5 changed files with 62 additions and 71 deletions

View File

@ -21,6 +21,7 @@
#include <windows.h> #include <windows.h>
#include <winsock2.h> #include <winsock2.h>
#include <uthash.h>
#include "addrtable.h" #include "addrtable.h"
#include "ipxwrapper.h" #include "ipxwrapper.h"
@ -176,9 +177,9 @@ bool addr_table_check(const struct sockaddr_ipx *addr, bool reuse)
lock_sockets(); lock_sockets();
ipx_socket *s = sockets; ipx_socket *s, *tmp;
for(; s; s = s->next) HASH_ITER(hh, sockets, s, tmp)
{ {
if(memcmp(&(s->addr), addr, sizeof(struct sockaddr_ipx)) == 0 && (!(s->flags & IPX_REUSE) || !reuse)) if(memcmp(&(s->addr), addr, sizeof(struct sockaddr_ipx)) == 0 && (!(s->flags & IPX_REUSE) || !reuse))
{ {
@ -236,9 +237,9 @@ uint16_t addr_table_auto_socket(void)
else{ else{
lock_sockets(); lock_sockets();
ipx_socket *s = sockets; ipx_socket *s, *tmp;
while(s) HASH_ITER(hh, sockets, s, tmp)
{ {
if((s->flags & IPX_BOUND) && ntohs(sock) == s->addr.sa_socket) if((s->flags & IPX_BOUND) && ntohs(sock) == s->addr.sa_socket)
{ {
@ -253,8 +254,6 @@ uint16_t addr_table_auto_socket(void)
s = sockets; s = sockets;
continue; continue;
} }
s = s->next;
} }
unlock_sockets(); unlock_sockets();
@ -367,8 +366,6 @@ void addr_table_update(void)
addr_table_lock(); addr_table_lock();
ipx_socket *sock = sockets;
/* Remove any expired entries. */ /* Remove any expired entries. */
addr_table_entry_t *entry = addr_table_base; addr_table_entry_t *entry = addr_table_base;
@ -393,7 +390,9 @@ void addr_table_update(void)
/* This is really, really efficient. */ /* This is really, really efficient. */
for(; sock; sock = sock->next) ipx_socket *sock, *tmp;
HASH_ITER(hh, sockets, sock, tmp)
{ {
if(sock->flags & IPX_BOUND) if(sock->flags & IPX_BOUND)
{ {

View File

@ -113,37 +113,34 @@ BOOL WINAPI DllMain(HINSTANCE me, DWORD why, LPVOID res)
return TRUE; return TRUE;
} }
/* Lock the mutex and search the sockets list for an ipx_socket structure with /* Lock the sockets table and search for one by file descriptor.
* the requested fd, if no matching fd is found, unlock the mutex *
* * Returns an ipx_socket pointer on success, unlocks the sockets table and
* TODO: Change this behaviour. It is almost as bad as the BKL. * returns NULL if no match is found.
*/ */
ipx_socket *get_socket(SOCKET fd) { ipx_socket *get_socket(SOCKET sockfd)
{
lock_sockets(); lock_sockets();
ipx_socket *ptr = sockets; ipx_socket *sock;
HASH_FIND_INT(sockets, &sockfd, sock);
while(ptr) { if(!sock)
if(ptr->fd == fd) { {
break;
}
ptr = ptr->next;
}
if(!ptr) {
unlock_sockets(); unlock_sockets();
} }
return ptr; return sock;
} }
/* Lock the mutex */ /* Lock the mutex */
void lock_sockets(void) { void lock_sockets(void)
{
EnterCriticalSection(&sockets_cs); EnterCriticalSection(&sockets_cs);
} }
/* Unlock the mutex */ /* Unlock the mutex */
void unlock_sockets(void) { void unlock_sockets(void)
{
LeaveCriticalSection(&sockets_cs); LeaveCriticalSection(&sockets_cs);
} }

View File

@ -23,6 +23,7 @@
#include <wsipx.h> #include <wsipx.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <uthash.h>
#include "config.h" #include "config.h"
#include "router.h" #include "router.h"
@ -71,7 +72,7 @@ struct ipx_socket {
/* Address used with connect call, only set when IPX_CONNECTED is */ /* Address used with connect call, only set when IPX_CONNECTED is */
struct sockaddr_ipx remote_addr; struct sockaddr_ipx remote_addr;
ipx_socket *next; UT_hash_handle hh;
}; };
struct ipx_packet { struct ipx_packet {
@ -92,7 +93,7 @@ struct ipx_packet {
extern ipx_socket *sockets; extern ipx_socket *sockets;
extern main_config_t main_config; extern main_config_t main_config;
ipx_socket *get_socket(SOCKET fd); ipx_socket *get_socket(SOCKET sockfd);
void lock_sockets(void); void lock_sockets(void);
void unlock_sockets(void); void unlock_sockets(void);

View File

@ -17,6 +17,7 @@
#include <windows.h> #include <windows.h>
#include <winsock2.h> #include <winsock2.h>
#include <uthash.h>
#include "router.h" #include "router.h"
#include "common.h" #include "common.h"
@ -205,9 +206,9 @@ static bool handle_recv(int fd)
lock_sockets(); lock_sockets();
ipx_socket *sock = sockets; ipx_socket *sock, *tmp;
for(; sock; sock = sock->next) HASH_ITER(hh, sockets, sock, tmp)
{ {
if( if(
/* Socket is bound and not shutdown for recv. */ /* Socket is bound and not shutdown for recv. */

View File

@ -154,19 +154,22 @@ INT WINAPI WSHEnumProtocols(LPINT protocols, LPWSTR ign, LPVOID buf, LPDWORD bsp
return do_EnumProtocols(protocols, buf, bsptr, FALSE); return do_EnumProtocols(protocols, buf, bsptr, FALSE);
} }
SOCKET WSAAPI socket(int af, int type, int protocol) { SOCKET WSAAPI socket(int af, int type, int protocol)
{
log_printf(LOG_DEBUG, "socket(%d, %d, %d)", af, type, protocol); log_printf(LOG_DEBUG, "socket(%d, %d, %d)", af, type, protocol);
if(af == AF_IPX) { if(af == AF_IPX)
{
ipx_socket *nsock = malloc(sizeof(ipx_socket)); ipx_socket *nsock = malloc(sizeof(ipx_socket));
if(!nsock) { if(!nsock)
{
WSASetLastError(ERROR_OUTOFMEMORY); WSASetLastError(ERROR_OUTOFMEMORY);
return -1; return -1;
} }
nsock->fd = r_socket(AF_INET, SOCK_DGRAM, 0); if((nsock->fd = r_socket(AF_INET, SOCK_DGRAM, 0)) == -1)
if(nsock->fd == -1) { {
log_printf(LOG_ERROR, "Creating fake socket failed: %s", w32_error(WSAGetLastError())); log_printf(LOG_ERROR, "Cannot create UDP socket: %s", w32_error(WSAGetLastError()));
free(nsock); free(nsock);
return -1; return -1;
@ -175,59 +178,49 @@ SOCKET WSAAPI socket(int af, int type, int protocol) {
nsock->flags = IPX_SEND | IPX_RECV | IPX_RECV_BCAST; nsock->flags = IPX_SEND | IPX_RECV | IPX_RECV_BCAST;
nsock->s_ptype = (protocol ? NSPROTO_IPX - protocol : 0); nsock->s_ptype = (protocol ? NSPROTO_IPX - protocol : 0);
lock_sockets();
nsock->next = sockets;
sockets = nsock;
log_printf(LOG_INFO, "IPX socket created (fd = %d)", nsock->fd); log_printf(LOG_INFO, "IPX socket created (fd = %d)", nsock->fd);
RETURN(nsock->fd); lock_sockets();
}else{ HASH_ADD_INT(sockets, fd, nsock);
unlock_sockets();
return nsock->fd;
}
else{
return r_socket(af, type, protocol); return r_socket(af, type, protocol);
} }
} }
int WSAAPI closesocket(SOCKET fd) { int WSAAPI closesocket(SOCKET sockfd)
int ret = r_closesocket(fd); {
int ret = r_closesocket(sockfd);
ipx_socket *ptr = get_socket(fd); ipx_socket *sock = get_socket(sockfd);
ipx_socket *pptr = sockets; if(!sock)
{
if(!ptr) {
/* Not an IPX socket */ /* Not an IPX socket */
return ret; return ret;
} }
if(ret == SOCKET_ERROR) { if(ret == SOCKET_ERROR)
log_printf(LOG_ERROR, "closesocket(%d) failed: %s", fd, w32_error(WSAGetLastError())); {
log_printf(LOG_ERROR, "closesocket(%d): %s", sockfd, w32_error(WSAGetLastError()));
RETURN(SOCKET_ERROR); RETURN(SOCKET_ERROR);
} }
log_printf(LOG_INFO, "IPX socket closed (fd = %d)", fd); log_printf(LOG_INFO, "IPX socket closed (fd = %d)", sockfd);
if(ptr->flags & IPX_BOUND) if(sock->flags & IPX_BOUND)
{ {
addr_table_remove(ptr->port); addr_table_remove(sock->port);
} }
if(ptr == sockets) { HASH_DEL(sockets, sock);
sockets = ptr->next; free(sock);
free(ptr);
}else{
while(ptr && pptr->next) {
if(ptr == pptr->next) {
pptr->next = ptr->next;
free(ptr);
break;
}
pptr = pptr->next;
}
}
RETURN(0); unlock_sockets();
return 0;
} }
static bool _complete_bind_address(struct sockaddr_ipx *addr) static bool _complete_bind_address(struct sockaddr_ipx *addr)