commit 76178ee71572e399ede72eac8d448595e6daac63
Author: Simon Howard <fraggle@soulsphere.org>
AuthorDate: Sat Feb 9 19:25:33 2019 -0500
Commit: Simon Howard <fraggle@soulsphere.org>
CommitDate: Sat Feb 9 19:25:33 2019 -0500
net: Add initial server code for NAT hole punching.
This allows the master server to send a hole punch request to servers
that will assist clients in connecting to them if they are behind
firewalls / NAT gateways. However, this is just the first piece in
implementation of #469 and more work is needed.
---
src/net_defs.h | 2 ++
src/net_query.c | 35 ++++++++++++++-------------------
src/net_query.h | 2 +-
src/net_server.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
4 files changed, 76 insertions(+), 22 deletions(-)
diff --git a/src/net_defs.h b/src/net_defs.h
index bf6a264e..10fda972 100644
--- a/src/net_defs.h
+++ b/src/net_defs.h
@@ -149,6 +149,7 @@ typedef enum
NET_PACKET_TYPE_QUERY,
NET_PACKET_TYPE_QUERY_RESPONSE,
NET_PACKET_TYPE_LAUNCH,
+ NET_PACKET_TYPE_NAT_HOLE_PUNCH,
} net_packet_type_t;
typedef enum
@@ -163,6 +164,7 @@ typedef enum
NET_MASTER_PACKET_TYPE_SIGN_START_RESPONSE,
NET_MASTER_PACKET_TYPE_SIGN_END,
NET_MASTER_PACKET_TYPE_SIGN_END_RESPONSE,
+ NET_MASTER_PACKET_TYPE_NAT_HOLE_PUNCH,
} net_master_packet_type_t;
// Settings specified when the client connects to the server.
diff --git a/src/net_query.c b/src/net_query.c
index da292b50..97c42ca0 100644
--- a/src/net_query.c
+++ b/src/net_query.c
@@ -120,40 +120,35 @@ void NET_Query_AddToMaster(net_addr_t *master_addr)
// Process a packet received from the master server.
-void NET_Query_MasterResponse(net_packet_t *packet)
+void NET_Query_AddResponse(net_packet_t *packet)
{
- unsigned int packet_type;
unsigned int result;
- if (!NET_ReadInt16(packet, &packet_type)
- || !NET_ReadInt16(packet, &result))
+ if (!NET_ReadInt16(packet, &result))
{
return;
}
- if (packet_type == NET_MASTER_PACKET_TYPE_ADD_RESPONSE)
+ if (result != 0)
{
- if (result != 0)
- {
- // Only show the message once.
+ // Only show the message once.
- if (!registered_with_master)
- {
- printf("Registered with master server at %s\n",
- MASTER_SERVER_ADDRESS);
- registered_with_master = true;
- }
- }
- else
+ if (!registered_with_master)
{
- // Always show rejections.
-
- printf("Failed to register with master server at %s\n",
+ printf("Registered with master server at %s\n",
MASTER_SERVER_ADDRESS);
+ registered_with_master = true;
}
+ }
+ else
+ {
+ // Always show rejections.
- got_master_response = true;
+ printf("Failed to register with master server at %s\n",
+ MASTER_SERVER_ADDRESS);
}
+
+ got_master_response = true;
}
boolean NET_Query_CheckAddedToMaster(boolean *result)
diff --git a/src/net_query.h b/src/net_query.h
index 563a055b..2fea8357 100644
--- a/src/net_query.h
+++ b/src/net_query.h
@@ -38,7 +38,7 @@ extern int NET_Query_Poll(net_query_callback_t callback, void *user_data);
extern net_addr_t *NET_Query_ResolveMaster(net_context_t *context);
extern void NET_Query_AddToMaster(net_addr_t *master_addr);
extern boolean NET_Query_CheckAddedToMaster(boolean *result);
-extern void NET_Query_MasterResponse(net_packet_t *packet);
+extern void NET_Query_AddResponse(net_packet_t *packet);
#endif /* #ifndef NET_QUERY_H */
diff --git a/src/net_server.c b/src/net_server.c
index c9dd3d9b..5c374b4a 100644
--- a/src/net_server.c
+++ b/src/net_server.c
@@ -1423,6 +1423,63 @@ void NET_SV_SendQueryResponse(net_addr_t *addr)
NET_FreePacket(reply);
}
+static void NET_SV_ParseHolePunch(net_packet_t *packet)
+{
+ const char *addr_string;
+ net_packet_t *sendpacket;
+ net_addr_t *addr;
+
+ addr_string = NET_ReadString(packet);
+ if (addr_string == NULL)
+ {
+ NET_Log("server: error: hole punch request but no address provided");
+ return;
+ }
+
+ addr = NET_ResolveAddress(server_context, addr_string);
+ if (addr == NULL)
+ {
+ NET_Log("server: error: failed to resolve address: %s", addr_string);
+ return;
+ }
+
+ sendpacket = NET_NewPacket(16);
+ NET_WriteInt16(sendpacket, NET_PACKET_TYPE_NAT_HOLE_PUNCH);
+ NET_SendPacket(addr, sendpacket);
+ NET_FreePacket(sendpacket);
+
+ // TODO: We should NET_FreeAddress(addr) here, but this could cause a
+ // problem if the client has already connected. The address system needs
+ // to be changed to use a reference-counting system to prevent this.
+}
+
+static void NET_SV_MasterPacket(net_packet_t *packet)
+{
+ unsigned int packet_type;
+
+ // Read the packet type
+
+ if (!NET_ReadInt16(packet, &packet_type))
+ {
+ NET_Log("server: error: no packet type in master server message");
+ return;
+ }
+
+ NET_Log("server: packet from master server; type %d", packet_type);
+ NET_LogPacket(packet);
+
+ switch (packet_type)
+ {
+ case NET_MASTER_PACKET_TYPE_ADD_RESPONSE:
+ NET_Query_AddResponse(packet);
+ break;
+
+ case NET_MASTER_PACKET_TYPE_NAT_HOLE_PUNCH:
+ NET_SV_ParseHolePunch(packet);
+ break;
+ }
+}
+
// Process a packet received by the server
static void NET_SV_Packet(net_packet_t *packet, net_addr_t *addr)
@@ -1434,7 +1491,7 @@ static void NET_SV_Packet(net_packet_t *packet, net_addr_t *addr)
if (addr != NULL && addr == master_server)
{
- NET_Query_MasterResponse(packet);
+ NET_SV_MasterPacket(packet);
return;
}