mirror of
https://github.com/solemnwarning/directplay-lite
synced 2024-12-30 16:45:37 +01:00
IDirectPlay8Peer: Randomly select dynamic ports in Connect() method.
It turns out disabling SO_LINGER on Windows doesn't /really/ make the socket go away by the time closesocket() returns, just very shortly afterwards, so rapidly destroying and re-creating connections on a slow machine can fail due to a connect() address conflict.
This commit is contained in:
parent
6df47cee60
commit
9c1345f44a
@ -482,17 +482,32 @@ HRESULT DirectPlay8Peer::Connect(CONST DPN_APPLICATION_DESC* CONST pdnAppDesc, I
|
|||||||
|
|
||||||
if(l_port == 0)
|
if(l_port == 0)
|
||||||
{
|
{
|
||||||
|
/* Start at a random point in the ephemeral port range and try each one, wrapping
|
||||||
|
* around when we reach the end.
|
||||||
|
*
|
||||||
|
* Gets the "random" point by querying the performance counter rather than calling
|
||||||
|
* rand() just in case the application relies on the RNG state.
|
||||||
|
*/
|
||||||
|
|
||||||
|
LARGE_INTEGER p_counter;
|
||||||
|
QueryPerformanceCounter(&p_counter);
|
||||||
|
|
||||||
|
int port_range = AUTO_PORT_MAX - AUTO_PORT_MIN;
|
||||||
|
int base_port = p_counter.QuadPart % port_range;
|
||||||
|
|
||||||
for(int p = AUTO_PORT_MIN; p <= AUTO_PORT_MAX; ++p)
|
for(int p = AUTO_PORT_MIN; p <= AUTO_PORT_MAX; ++p)
|
||||||
{
|
{
|
||||||
/* TODO: Only continue if creation failed due to address conflict. */
|
/* TODO: Only continue if creation failed due to address conflict. */
|
||||||
|
|
||||||
udp_socket = create_udp_socket(l_ipaddr, p);
|
int port = AUTO_PORT_MIN + ((base_port + p) % (port_range + 1));
|
||||||
|
|
||||||
|
udp_socket = create_udp_socket(l_ipaddr, port);
|
||||||
if(udp_socket == -1)
|
if(udp_socket == -1)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
listener_socket = create_listener_socket(l_ipaddr, p);
|
listener_socket = create_listener_socket(l_ipaddr, port);
|
||||||
if(listener_socket == -1)
|
if(listener_socket == -1)
|
||||||
{
|
{
|
||||||
closesocket(udp_socket);
|
closesocket(udp_socket);
|
||||||
@ -502,7 +517,7 @@ HRESULT DirectPlay8Peer::Connect(CONST DPN_APPLICATION_DESC* CONST pdnAppDesc, I
|
|||||||
}
|
}
|
||||||
|
|
||||||
local_ip = l_ipaddr;
|
local_ip = l_ipaddr;
|
||||||
local_port = p;
|
local_port = port;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user