ref: d1f2b422e6cbcf2b50b0e02b989cb3fbb314eb9e
parent: 48f038cc625fc63cbb17a853134fa1676c7bb55c
author: Simon Howard <fraggle@soulsphere.org>
date: Sat Feb 9 18:00:33 EST 2019
net: Send hole punch requests on connect. To avoid spurious requests, only send requests if no response is received after 2 seconds - most connect requests should complete before that if the server port is publicly accessible.
--- a/src/net_client.c
+++ b/src/net_client.c
@@ -35,6 +35,7 @@
#include "net_gui.h"
#include "net_io.h"
#include "net_packet.h"
+#include "net_query.h"
#include "net_server.h"
#include "net_structrw.h"
#include "w_checksum.h"
@@ -1024,6 +1025,7 @@
{
int start_time;
int last_send_time;
+ boolean sent_hole_punch;
server_addr = addr;
NET_ReferenceAddress(addr);
@@ -1032,13 +1034,10 @@
memcpy(net_local_deh_sha1sum, data->deh_sha1sum, sizeof(sha1_digest_t));
net_local_is_freedoom = data->is_freedoom;
- // create a new network I/O context and add just the
- // necessary module
-
+ // create a new network I/O context and add just the necessary module
client_context = NET_NewContext();
// initialize module for client mode
-
if (!addr->module->InitClient())
{
return false;
@@ -1048,13 +1047,11 @@
net_client_connected = true;
net_client_received_wait_data = false;
+ sent_hole_punch = false;
- // Initialize connection
-
NET_Conn_InitClient(&client_connection, addr, NET_PROTOCOL_UNKNOWN);
// try to connect
-
start_time = I_GetTimeMS();
last_send_time = -1;
@@ -1063,7 +1060,6 @@
int nowtime = I_GetTimeMS();
// Send a SYN packet every second.
-
if (nowtime - last_send_time > 1000 || last_send_time < 0)
{
NET_CL_SendSYN(data);
@@ -1071,23 +1067,25 @@
}
// time out after 5 seconds
-
if (nowtime - start_time > 5000)
{
break;
}
- // run client code
+ if (!sent_hole_punch && nowtime - start_time > 2000)
+ {
+ NET_Log("client: no response to SYN, requesting hole punch");
+ NET_RequestHolePunch(client_context, addr);
+ sent_hole_punch = true;
+ }
+ // run client code
NET_CL_Run();
- // run the server, just incase we are doing a loopback
- // connect
-
+ // run the server, just in case we are doing a loopback connect
NET_SV_Run();
// Don't hog the CPU
-
I_Sleep(1);
}
--- a/src/net_query.c
+++ b/src/net_query.c
@@ -176,6 +176,28 @@
NET_FreePacket(packet);
}
+// Send a hole punch request to the master server for the server at the
+// given address.
+void NET_RequestHolePunch(net_context_t *context, net_addr_t *addr)
+{
+ net_addr_t *master_addr;
+ net_packet_t *packet;
+
+ master_addr = NET_Query_ResolveMaster(context);
+ if (master_addr == NULL)
+ {
+ return;
+ }
+
+ packet = NET_NewPacket(32);
+ NET_WriteInt16(packet, NET_MASTER_PACKET_TYPE_NAT_HOLE_PUNCH);
+ NET_WriteString(packet, NET_AddrToString(addr));
+ NET_SendPacket(master_addr, packet);
+
+ NET_FreePacket(packet);
+ NET_ReleaseAddress(master_addr);
+}
+
// Given the specified address, find the target associated. If no
// target is found, and 'create' is true, a new target is created.
--- a/src/net_query.h
+++ b/src/net_query.h
@@ -39,6 +39,7 @@
extern void NET_Query_AddToMaster(net_addr_t *master_addr);
extern boolean NET_Query_CheckAddedToMaster(boolean *result);
extern void NET_Query_AddResponse(net_packet_t *packet);
+extern void NET_RequestHolePunch(net_context_t *context, net_addr_t *addr);
#endif /* #ifndef NET_QUERY_H */