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:
parent
920b5ee2c3
commit
2a06601f53
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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. */
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user