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 <winsock2.h>
#include <uthash.h>
#include "addrtable.h"
#include "ipxwrapper.h"
@ -176,9 +177,9 @@ bool addr_table_check(const struct sockaddr_ipx *addr, bool reuse)
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))
{
@ -236,9 +237,9 @@ uint16_t addr_table_auto_socket(void)
else{
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)
{
@ -253,8 +254,6 @@ uint16_t addr_table_auto_socket(void)
s = sockets;
continue;
}
s = s->next;
}
unlock_sockets();
@ -367,8 +366,6 @@ void addr_table_update(void)
addr_table_lock();
ipx_socket *sock = sockets;
/* Remove any expired entries. */
addr_table_entry_t *entry = addr_table_base;
@ -393,7 +390,9 @@ void addr_table_update(void)
/* 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)
{

View File

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

View File

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

View File

@ -17,6 +17,7 @@
#include <windows.h>
#include <winsock2.h>
#include <uthash.h>
#include "router.h"
#include "common.h"
@ -205,9 +206,9 @@ static bool handle_recv(int fd)
lock_sockets();
ipx_socket *sock = sockets;
ipx_socket *sock, *tmp;
for(; sock; sock = sock->next)
HASH_ITER(hh, sockets, sock, tmp)
{
if(
/* 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);
}
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);
if(af == AF_IPX) {
if(af == AF_IPX)
{
ipx_socket *nsock = malloc(sizeof(ipx_socket));
if(!nsock) {
if(!nsock)
{
WSASetLastError(ERROR_OUTOFMEMORY);
return -1;
}
nsock->fd = r_socket(AF_INET, SOCK_DGRAM, 0);
if(nsock->fd == -1) {
log_printf(LOG_ERROR, "Creating fake socket failed: %s", w32_error(WSAGetLastError()));
if((nsock->fd = r_socket(AF_INET, SOCK_DGRAM, 0)) == -1)
{
log_printf(LOG_ERROR, "Cannot create UDP socket: %s", w32_error(WSAGetLastError()));
free(nsock);
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->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);
RETURN(nsock->fd);
}else{
lock_sockets();
HASH_ADD_INT(sockets, fd, nsock);
unlock_sockets();
return nsock->fd;
}
else{
return r_socket(af, type, protocol);
}
}
int WSAAPI closesocket(SOCKET fd) {
int ret = r_closesocket(fd);
int WSAAPI closesocket(SOCKET sockfd)
{
int ret = r_closesocket(sockfd);
ipx_socket *ptr = get_socket(fd);
ipx_socket *pptr = sockets;
if(!ptr) {
ipx_socket *sock = get_socket(sockfd);
if(!sock)
{
/* Not an IPX socket */
return ret;
}
if(ret == SOCKET_ERROR) {
log_printf(LOG_ERROR, "closesocket(%d) failed: %s", fd, w32_error(WSAGetLastError()));
if(ret == SOCKET_ERROR)
{
log_printf(LOG_ERROR, "closesocket(%d): %s", sockfd, w32_error(WSAGetLastError()));
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) {
sockets = ptr->next;
free(ptr);
}else{
while(ptr && pptr->next) {
if(ptr == pptr->next) {
pptr->next = ptr->next;
free(ptr);
break;
}
pptr = pptr->next;
}
}
HASH_DEL(sockets, sock);
free(sock);
RETURN(0);
unlock_sockets();
return 0;
}
static bool _complete_bind_address(struct sockaddr_ipx *addr)