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

Partial cleanup of locking code.

This commit is contained in:
Daniel Collins 2011-09-08 00:20:34 +00:00
parent eec97eee76
commit b3d911abea
3 changed files with 73 additions and 43 deletions

View File

@ -47,13 +47,29 @@ HMODULE winsock2_dll = NULL;
HMODULE mswsock_dll = NULL; HMODULE mswsock_dll = NULL;
HMODULE wsock32_dll = NULL; HMODULE wsock32_dll = NULL;
static HANDLE mutex = NULL;
static HANDLE router_thread = NULL; static HANDLE router_thread = NULL;
struct router_vars *router = NULL; struct router_vars *router = NULL;
static CRITICAL_SECTION sockets_cs;
static CRITICAL_SECTION hosts_cs;
static BOOL start_router(void); static BOOL start_router(void);
#define INIT_CS(cs) if(!init_cs(cs, &initialised_cs)) { return FALSE; }
static BOOL init_cs(CRITICAL_SECTION *cs, int *counter) {
if(!InitializeCriticalSectionAndSpinCount(&(router->crit_sec), 0x80000000)) {
log_printf("Failed to initialise critical section: %s", w32_error(GetLastError()));
return FALSE;
}
(*counter)++;
return TRUE;
}
BOOL WINAPI DllMain(HINSTANCE me, DWORD why, LPVOID res) { BOOL WINAPI DllMain(HINSTANCE me, DWORD why, LPVOID res) {
static int initialised_cs = 0;
if(why == DLL_PROCESS_ATTACH) { if(why == DLL_PROCESS_ATTACH) {
log_open(); log_open();
@ -76,11 +92,8 @@ BOOL WINAPI DllMain(HINSTANCE me, DWORD why, LPVOID res) {
nics = get_interfaces(-1); nics = get_interfaces(-1);
mutex = CreateMutex(NULL, FALSE, NULL); INIT_CS(&sockets_cs);
if(!mutex) { INIT_CS(&hosts_cs);
log_printf("Failed to create mutex");
return FALSE;
}
WSADATA wsdata; WSADATA wsdata;
int err = WSAStartup(MAKEWORD(1,1), &wsdata); int err = WSAStartup(MAKEWORD(1,1), &wsdata);
@ -108,14 +121,17 @@ BOOL WINAPI DllMain(HINSTANCE me, DWORD why, LPVOID res) {
router = NULL; router = NULL;
} }
if(mutex) { WSACleanup();
CloseHandle(mutex);
mutex = NULL; switch(initialised_cs) {
case 2: DeleteCriticalSection(&hosts_cs);
case 1: DeleteCriticalSection(&sockets_cs);
default: break;
} }
free_interfaces(nics); initialised_cs = 0;
WSACleanup(); free_interfaces(nics);
reg_close(); reg_close();
@ -153,7 +169,7 @@ void __stdcall *find_sym(char const *symbol) {
* TODO: Change this behaviour. It is almost as bad as the BKL. * TODO: Change this behaviour. It is almost as bad as the BKL.
*/ */
ipx_socket *get_socket(SOCKET fd) { ipx_socket *get_socket(SOCKET fd) {
lock_mutex(); lock_sockets();
ipx_socket *ptr = sockets; ipx_socket *ptr = sockets;
@ -166,20 +182,20 @@ ipx_socket *get_socket(SOCKET fd) {
} }
if(!ptr) { if(!ptr) {
unlock_mutex(); unlock_sockets();
} }
return ptr; return ptr;
} }
/* Lock the mutex */ /* Lock the mutex */
void lock_mutex(void) { void lock_sockets(void) {
WaitForSingleObject(mutex, INFINITE); EnterCriticalSection(&sockets_cs);
} }
/* Unlock the mutex */ /* Unlock the mutex */
void unlock_mutex(void) { void unlock_sockets(void) {
while(ReleaseMutex(mutex)) {} LeaveCriticalSection(&sockets_cs);
} }
/* Initialize and start the router thread */ /* Initialize and start the router thread */
@ -205,6 +221,8 @@ static BOOL start_router(void) {
/* Add a host to the hosts list or update an existing one */ /* Add a host to the hosts list or update an existing one */
void add_host(const unsigned char *net, const unsigned char *node, uint32_t ipaddr) { void add_host(const unsigned char *net, const unsigned char *node, uint32_t ipaddr) {
EnterCriticalSection(&hosts_cs);
ipx_host *hptr = hosts; ipx_host *hptr = hosts;
while(hptr) { while(hptr) {
@ -212,6 +230,7 @@ void add_host(const unsigned char *net, const unsigned char *node, uint32_t ipad
hptr->ipaddr = ipaddr; hptr->ipaddr = ipaddr;
hptr->last_packet = time(NULL); hptr->last_packet = time(NULL);
LeaveCriticalSection(&hosts_cs);
return; return;
} }
@ -220,6 +239,8 @@ void add_host(const unsigned char *net, const unsigned char *node, uint32_t ipad
hptr = malloc(sizeof(ipx_host)); hptr = malloc(sizeof(ipx_host));
if(!hptr) { if(!hptr) {
LeaveCriticalSection(&hosts_cs);
log_printf("No memory for hosts list entry"); log_printf("No memory for hosts list entry");
return; return;
} }
@ -232,10 +253,14 @@ void add_host(const unsigned char *net, const unsigned char *node, uint32_t ipad
hptr->next = hosts; hptr->next = hosts;
hosts = hptr; hosts = hptr;
LeaveCriticalSection(&hosts_cs);
} }
/* Search the hosts list */ /* Search the hosts list */
ipx_host *find_host(const unsigned char *net, const unsigned char *node) { ipx_host *find_host(const unsigned char *net, const unsigned char *node) {
EnterCriticalSection(&hosts_cs);
ipx_host *hptr = hosts, *pptr = NULL; ipx_host *hptr = hosts, *pptr = NULL;
while(hptr) { while(hptr) {
@ -251,15 +276,16 @@ ipx_host *find_host(const unsigned char *net, const unsigned char *node) {
free(hptr); free(hptr);
} }
return NULL; hptr = NULL;
}else{
return hptr;
} }
break;
} }
pptr = hptr; pptr = hptr;
hptr = hptr->next; hptr = hptr->next;
} }
return NULL; LeaveCriticalSection(&hosts_cs);
return hptr;
} }

View File

@ -41,19 +41,14 @@
#define IPX_EX_BOUND (int)(1<<5) #define IPX_EX_BOUND (int)(1<<5)
#define RETURN(...) \ #define RETURN(...) \
unlock_mutex();\ unlock_sockets();\
return __VA_ARGS__; return __VA_ARGS__;
#define RETURN_WSA(errnum, ...) \ #define RETURN_WSA(errnum, ...) \
unlock_mutex();\ unlock_sockets();\
WSASetLastError(errnum);\ WSASetLastError(errnum);\
return __VA_ARGS__; return __VA_ARGS__;
#define RETURN_ERR(errnum, ...) \
unlock_mutex();\
SetLastError(errnum);\
return __VA_ARGS__;
typedef struct ipx_socket ipx_socket; typedef struct ipx_socket ipx_socket;
typedef struct ipx_packet ipx_packet; typedef struct ipx_packet ipx_packet;
typedef struct ipx_host ipx_host; typedef struct ipx_host ipx_host;
@ -116,8 +111,8 @@ extern HMODULE wsock32_dll;
void __stdcall *find_sym(char const *sym); void __stdcall *find_sym(char const *sym);
ipx_socket *get_socket(SOCKET fd); ipx_socket *get_socket(SOCKET fd);
void lock_mutex(void); void lock_sockets(void);
void unlock_mutex(void); void unlock_sockets(void);
ipx_host *find_host(const unsigned char *net, const unsigned char *node); ipx_host *find_host(const unsigned char *net, const unsigned char *node);
void add_host(const unsigned char *net, const unsigned char *node, uint32_t ipaddr); void add_host(const unsigned char *net, const unsigned char *node, uint32_t ipaddr);

View File

@ -102,7 +102,8 @@ SOCKET WSAAPI socket(int af, int type, int 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) {
RETURN_WSA(ERROR_OUTOFMEMORY, -1); WSASetLastError(ERROR_OUTOFMEMORY);
return -1;
} }
nsock->fd = r_socket(AF_INET, SOCK_DGRAM, 0); nsock->fd = r_socket(AF_INET, SOCK_DGRAM, 0);
@ -110,13 +111,13 @@ SOCKET WSAAPI socket(int af, int type, int protocol) {
log_printf("Creating fake socket failed: %s", w32_error(WSAGetLastError())); log_printf("Creating fake socket failed: %s", w32_error(WSAGetLastError()));
free(nsock); free(nsock);
RETURN(-1); return -1;
} }
nsock->flags = IPX_SEND | IPX_RECV; nsock->flags = IPX_SEND | IPX_RECV;
nsock->s_ptype = (protocol ? NSPROTO_IPX - protocol : 0); nsock->s_ptype = (protocol ? NSPROTO_IPX - protocol : 0);
lock_mutex(); lock_sockets();
nsock->next = sockets; nsock->next = sockets;
sockets = nsock; sockets = nsock;
@ -226,7 +227,7 @@ int WSAAPI bind(SOCKET fd, const struct sockaddr *addr, int addrlen) {
RETURN(0); RETURN(0);
}else{ }else{
RETURN(r_bind(fd, addr, addrlen)); return r_bind(fd, addr, addrlen);
} }
} }
@ -255,7 +256,7 @@ int WSAAPI getsockname(SOCKET fd, struct sockaddr *addr, int *addrlen) {
RETURN_WSA(WSAEINVAL, -1); RETURN_WSA(WSAEINVAL, -1);
} }
}else{ }else{
RETURN(r_getsockname(fd, addr, addrlen)); return r_getsockname(fd, addr, addrlen);
} }
} }
@ -269,7 +270,7 @@ static int recv_packet(ipx_socket *sockptr, char *buf, int bufsize, int flags, s
SOCKET fd = sockptr->fd; SOCKET fd = sockptr->fd;
int is_bound = sockptr->flags & IPX_BOUND; int is_bound = sockptr->flags & IPX_BOUND;
unlock_mutex(); unlock_sockets();
if(!is_bound) { if(!is_bound) {
WSASetLastError(WSAEINVAL); WSASetLastError(WSAEINVAL);
@ -318,7 +319,7 @@ int WSAAPI recvfrom(SOCKET fd, char *buf, int len, int flags, struct sockaddr *a
if(sockptr) { if(sockptr) {
if(addr && addrlen && *addrlen < sizeof(struct sockaddr_ipx)) { if(addr && addrlen && *addrlen < sizeof(struct sockaddr_ipx)) {
unlock_mutex(); unlock_sockets();
WSASetLastError(WSAEFAULT); WSASetLastError(WSAEFAULT);
return -1; return -1;
@ -471,9 +472,11 @@ int WSAAPI getsockopt(SOCKET fd, int level, int optname, char FAR *optval, int F
RETURN_WSA(WSAENOPROTOOPT, -1); RETURN_WSA(WSAENOPROTOOPT, -1);
} }
unlock_sockets();
} }
RETURN(r_getsockopt(fd, level, optname, optval, optlen)); return r_getsockopt(fd, level, optname, optval, optlen);
} }
int WSAAPI setsockopt(SOCKET fd, int level, int optname, const char FAR *optval, int optlen) { int WSAAPI setsockopt(SOCKET fd, int level, int optname, const char FAR *optval, int optlen) {
@ -520,9 +523,11 @@ int WSAAPI setsockopt(SOCKET fd, int level, int optname, const char FAR *optval,
RETURN(0); RETURN(0);
} }
} }
unlock_sockets();
} }
RETURN(r_setsockopt(fd, level, optname, optval, optlen)); return r_setsockopt(fd, level, optname, optval, optlen);
} }
int WSAAPI sendto(SOCKET fd, const char *buf, int len, int flags, const struct sockaddr *addr, int addrlen) { int WSAAPI sendto(SOCKET fd, const char *buf, int len, int flags, const struct sockaddr *addr, int addrlen) {
@ -599,7 +604,7 @@ int WSAAPI sendto(SOCKET fd, const char *buf, int len, int flags, const struct s
free(packet); free(packet);
RETURN(len); RETURN(len);
}else{ }else{
RETURN(r_sendto(fd, buf, len, flags, addr, addrlen)); return r_sendto(fd, buf, len, flags, addr, addrlen);
} }
} }
@ -618,7 +623,7 @@ int PASCAL shutdown(SOCKET fd, int cmd) {
RETURN(0); RETURN(0);
}else{ }else{
RETURN(r_shutdown(fd, cmd)); return r_shutdown(fd, cmd);
} }
} }
@ -648,7 +653,11 @@ int PASCAL ioctlsocket(SOCKET fd, long cmd, u_long *argp) {
*(unsigned long*)argp = packet.size; *(unsigned long*)argp = packet.size;
RETURN(0); RETURN(0);
}else{
RETURN(r_ioctlsocket(fd, cmd, argp));
} }
if(sockptr) {
unlock_sockets();
}
return r_ioctlsocket(fd, cmd, argp);
} }