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

Periodically update the address table and correctly remove entries.

This commit is contained in:
Daniel Collins 2012-11-18 18:29:05 +00:00
parent 0faeb985d2
commit 3558f2196e
2 changed files with 47 additions and 17 deletions

View File

@ -46,6 +46,22 @@ static void _init_fail(void)
addr_table_cleanup(); addr_table_cleanup();
} }
/* Find the last entry in the address table.
* Returns addr_table_base if there are none.
*/
static addr_table_entry_t *_last_entry()
{
addr_table_entry_t *last = addr_table_base, *next = addr_table_base + 1;
addr_table_entry_t *end = addr_table_base + ADDR_TABLE_MAX_ENTRIES;
while(next < end && next->flags & ADDR_TABLE_ENTRY_VALID)
{
last = next++;
}
return last;
}
void addr_table_init(void) void addr_table_init(void)
{ {
/* Mutex used to protect the address table. */ /* Mutex used to protect the address table. */
@ -102,9 +118,25 @@ void addr_table_init(void)
addr_table_unlock(); addr_table_unlock();
} }
/* Release all handles to the address table and associated objects. */
void addr_table_cleanup(void) void addr_table_cleanup(void)
{ {
/* Release any remaining addresses bound by this process. */
if(addr_table_base)
{
ipx_socket *s, *tmp;
HASH_ITER(hh, sockets, s, tmp)
{
if(s->flags & IPX_BOUND)
{
addr_table_remove(s->port);
}
}
}
/* Close handles to the address table. */
if(addr_table_header) if(addr_table_header)
{ {
UnmapViewOfFile(addr_table_header); UnmapViewOfFile(addr_table_header);
@ -335,14 +367,7 @@ void addr_table_remove(uint16_t port)
entry++; entry++;
} }
/* Continue iteration until we find the last entry... */ addr_table_entry_t *last = _last_entry();
addr_table_entry_t *last = entry;
while(last < end && (last->flags & ADDR_TABLE_ENTRY_VALID))
{
last++;
}
/* Replace entry with the last entry and mark the latter as invalid. */ /* Replace entry with the last entry and mark the latter as invalid. */
@ -373,19 +398,14 @@ void addr_table_update(void)
/* Remove any expired entries. */ /* Remove any expired entries. */
addr_table_entry_t *entry = addr_table_base; addr_table_entry_t *entry = addr_table_base;
addr_table_entry_t *last = addr_table_base; addr_table_entry_t *last = _last_entry();
addr_table_entry_t *end = addr_table_base + ADDR_TABLE_MAX_ENTRIES; addr_table_entry_t *end = addr_table_base + ADDR_TABLE_MAX_ENTRIES;
while(last < end && (last->flags & ADDR_TABLE_ENTRY_VALID))
{
last++;
}
for(; entry < end && (entry->flags & ADDR_TABLE_ENTRY_VALID); entry++) for(; entry < end && (entry->flags & ADDR_TABLE_ENTRY_VALID); entry++)
{ {
if(entry->time + ADDR_TABLE_ENTRY_TIMEOUT <= time(NULL)) if(entry->time + ADDR_TABLE_ENTRY_TIMEOUT <= time(NULL))
{ {
*end = *last; *entry = *last;
last->flags &= ~ADDR_TABLE_ENTRY_VALID; last->flags &= ~ADDR_TABLE_ENTRY_VALID;
last--; last--;

View File

@ -18,12 +18,14 @@
#include <windows.h> #include <windows.h>
#include <winsock2.h> #include <winsock2.h>
#include <uthash.h> #include <uthash.h>
#include <time.h>
#include "router.h" #include "router.h"
#include "common.h" #include "common.h"
#include "ipxwrapper.h" #include "ipxwrapper.h"
#include "interface.h" #include "interface.h"
#include "addrcache.h" #include "addrcache.h"
#include "addrtable.h"
static bool router_running = false; static bool router_running = false;
static WSAEVENT router_event = WSA_INVALID_EVENT; static WSAEVENT router_event = WSA_INVALID_EVENT;
@ -310,9 +312,11 @@ static bool handle_recv(int fd)
static DWORD router_main(void *arg) static DWORD router_main(void *arg)
{ {
time_t last_at_update = 0;
while(1) while(1)
{ {
WaitForSingleObject(router_event, INFINITE); WaitForSingleObject(router_event, 1000);
WSAResetEvent(router_event); WSAResetEvent(router_event);
@ -321,6 +325,12 @@ static DWORD router_main(void *arg)
return 0; return 0;
} }
if(last_at_update != time(NULL))
{
addr_table_update();
last_at_update = time(NULL);
}
if(!handle_recv(shared_socket) || !handle_recv(private_socket)) if(!handle_recv(shared_socket) || !handle_recv(private_socket))
{ {
return 1; return 1;