mirror of
https://github.com/solemnwarning/ipxwrapper
synced 2024-12-30 16:45:37 +01:00
Allow address sharing when the existing socket doesn't have SO_REUSEADDR.
The IPX/SPX protocol versions in 98/2000/XP only require the second socket to have SO_REUSEADDR when attempting to bind to an already-used address. The state of the option on the first socket is ignored. The ADDR_TABLE_ENTRY_REUSE flag is kept and set on all sockets in the address table to keep compatibility with previous versions.
This commit is contained in:
parent
533e35729d
commit
68d13baac2
@ -1,3 +1,6 @@
|
|||||||
|
Version XXX:
|
||||||
|
Bugfix: Allow address reuse when only the binding socket has SO_REUSEADDR.
|
||||||
|
|
||||||
Version 0.4.1:
|
Version 0.4.1:
|
||||||
Feature: Added workaround for point-to-point links.
|
Feature: Added workaround for point-to-point links.
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* IPXWrapper - Address table
|
/* IPXWrapper - Address table
|
||||||
* Copyright (C) 2008-2012 Daniel Collins <solemnwarning@solemnwarning.net>
|
* Copyright (C) 2008-2014 Daniel Collins <solemnwarning@solemnwarning.net>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms of the GNU General Public License version 2 as published by
|
* under the terms of the GNU General Public License version 2 as published by
|
||||||
@ -179,7 +179,7 @@ void addr_table_unlock(void)
|
|||||||
*
|
*
|
||||||
* Returns false if a conflict was confirmed, true otherwise.
|
* Returns false if a conflict was confirmed, true otherwise.
|
||||||
*/
|
*/
|
||||||
bool addr_table_check(const struct sockaddr_ipx *addr, bool reuse)
|
bool addr_table_check(const struct sockaddr_ipx *addr)
|
||||||
{
|
{
|
||||||
if(addr_table_base)
|
if(addr_table_base)
|
||||||
{
|
{
|
||||||
@ -190,12 +190,8 @@ bool addr_table_check(const struct sockaddr_ipx *addr, bool reuse)
|
|||||||
|
|
||||||
while(entry < end && (entry->flags & ADDR_TABLE_ENTRY_VALID))
|
while(entry < end && (entry->flags & ADDR_TABLE_ENTRY_VALID))
|
||||||
{
|
{
|
||||||
if(addr->sa_socket == entry->socket && (!(entry->flags & ADDR_TABLE_ENTRY_REUSE) || !reuse))
|
if(addr->sa_socket == entry->socket)
|
||||||
{
|
{
|
||||||
/* A socket is already bound to this address and either
|
|
||||||
* it or this one doesn't have SO_REUSEADDR set.
|
|
||||||
*/
|
|
||||||
|
|
||||||
addr_table_unlock();
|
addr_table_unlock();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -217,7 +213,7 @@ bool addr_table_check(const struct sockaddr_ipx *addr, bool reuse)
|
|||||||
|
|
||||||
HASH_ITER(hh, sockets, s, tmp)
|
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)
|
||||||
{
|
{
|
||||||
unlock_sockets();
|
unlock_sockets();
|
||||||
return true;
|
return true;
|
||||||
@ -303,7 +299,7 @@ uint16_t addr_table_auto_socket(void)
|
|||||||
* Performs no conflict checking. Take the address table lock in the caller and
|
* Performs no conflict checking. Take the address table lock in the caller and
|
||||||
* use addr_table_check() before calling this.
|
* use addr_table_check() before calling this.
|
||||||
*/
|
*/
|
||||||
void addr_table_add(const struct sockaddr_ipx *addr, uint16_t port, bool reuse)
|
void addr_table_add(const struct sockaddr_ipx *addr, uint16_t port)
|
||||||
{
|
{
|
||||||
if(!addr_table_base)
|
if(!addr_table_base)
|
||||||
{
|
{
|
||||||
@ -330,12 +326,7 @@ void addr_table_add(const struct sockaddr_ipx *addr, uint16_t port, bool reuse)
|
|||||||
entry->nodenum = addr48_in(addr->sa_nodenum);
|
entry->nodenum = addr48_in(addr->sa_nodenum);
|
||||||
entry->socket = addr->sa_socket;
|
entry->socket = addr->sa_socket;
|
||||||
|
|
||||||
entry->flags = ADDR_TABLE_ENTRY_VALID;
|
entry->flags = ADDR_TABLE_ENTRY_VALID | ADDR_TABLE_ENTRY_REUSE;
|
||||||
|
|
||||||
if(reuse)
|
|
||||||
{
|
|
||||||
entry->flags |= ADDR_TABLE_ENTRY_REUSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
entry->port = port;
|
entry->port = port;
|
||||||
entry->time = time(NULL);
|
entry->time = time(NULL);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* IPXWrapper - Address table
|
/* IPXWrapper - Address table
|
||||||
* Copyright (C) 2008-2012 Daniel Collins <solemnwarning@solemnwarning.net>
|
* Copyright (C) 2008-2014 Daniel Collins <solemnwarning@solemnwarning.net>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms of the GNU General Public License version 2 as published by
|
* under the terms of the GNU General Public License version 2 as published by
|
||||||
@ -61,10 +61,10 @@ void addr_table_cleanup(void);
|
|||||||
void addr_table_lock(void);
|
void addr_table_lock(void);
|
||||||
void addr_table_unlock(void);
|
void addr_table_unlock(void);
|
||||||
|
|
||||||
bool addr_table_check(const struct sockaddr_ipx *addr, bool reuse);
|
bool addr_table_check(const struct sockaddr_ipx *addr);
|
||||||
uint16_t addr_table_auto_socket(void);
|
uint16_t addr_table_auto_socket(void);
|
||||||
|
|
||||||
void addr_table_add(const struct sockaddr_ipx *addr, uint16_t port, bool reuse);
|
void addr_table_add(const struct sockaddr_ipx *addr, uint16_t port);
|
||||||
void addr_table_remove(uint16_t port);
|
void addr_table_remove(uint16_t port);
|
||||||
|
|
||||||
void addr_table_update(void);
|
void addr_table_update(void);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* ipxwrapper - Winsock functions
|
/* ipxwrapper - Winsock functions
|
||||||
* Copyright (C) 2008 Daniel Collins <solemnwarning@solemnwarning.net>
|
* Copyright (C) 2008-2014 Daniel Collins <solemnwarning@solemnwarning.net>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms of the GNU General Public License version 2 as published by
|
* under the terms of the GNU General Public License version 2 as published by
|
||||||
@ -335,7 +335,7 @@ int WSAAPI bind(SOCKET fd, const struct sockaddr *addr, int addrlen)
|
|||||||
|
|
||||||
/* Check that the address is free. */
|
/* Check that the address is free. */
|
||||||
|
|
||||||
if(!addr_table_check(&ipxaddr, !!(sock->flags & IPX_REUSE)))
|
if(!(sock->flags & IPX_REUSE) && !addr_table_check(&ipxaddr))
|
||||||
{
|
{
|
||||||
/* Address has already been bound. */
|
/* Address has already been bound. */
|
||||||
|
|
||||||
@ -401,7 +401,7 @@ int WSAAPI bind(SOCKET fd, const struct sockaddr *addr, int addrlen)
|
|||||||
|
|
||||||
/* Add to the address table. */
|
/* Add to the address table. */
|
||||||
|
|
||||||
addr_table_add(&ipxaddr, sock->port, !!(sock->flags & IPX_REUSE));
|
addr_table_add(&ipxaddr, sock->port);
|
||||||
|
|
||||||
/* Mark the IPX socket as bound. */
|
/* Mark the IPX socket as bound. */
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ try_binds(
|
|||||||
try_binds(
|
try_binds(
|
||||||
"Single process, conflicting socket numbers, second using SO_REUSEADDR",
|
"Single process, conflicting socket numbers, second using SO_REUSEADDR",
|
||||||
|
|
||||||
"bind.exe 0 1234 --reuse 0 1234" => "FAIL",
|
"bind.exe 0 1234 --reuse 0 1234" => "OK",
|
||||||
);
|
);
|
||||||
|
|
||||||
try_binds(
|
try_binds(
|
||||||
@ -144,7 +144,7 @@ try_binds(
|
|||||||
"Two processes, conflicting socket numbers, second using SO_REUSEADDR",
|
"Two processes, conflicting socket numbers, second using SO_REUSEADDR",
|
||||||
|
|
||||||
"bind.exe 0 1234" => "OK",
|
"bind.exe 0 1234" => "OK",
|
||||||
"bind.exe --reuse 0 1234" => "FAIL",
|
"bind.exe --reuse 0 1234" => "OK",
|
||||||
);
|
);
|
||||||
|
|
||||||
sub try_binds
|
sub try_binds
|
||||||
|
Loading…
x
Reference in New Issue
Block a user