ref: 76178ee71572e399ede72eac8d448595e6daac63
parent: 660cad3966afdcd745a3468e23416e48aee88c28
author: Simon Howard <fraggle@soulsphere.org>
date: Sat Feb 9 14:25:33 EST 2019
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.
--- a/src/net_defs.h
+++ b/src/net_defs.h
@@ -149,6 +149,7 @@
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 @@
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.
--- a/src/net_query.c
+++ b/src/net_query.c
@@ -120,40 +120,35 @@
// 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)
--- a/src/net_query.h
+++ b/src/net_query.h
@@ -38,7 +38,7 @@
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 */
--- a/src/net_server.c
+++ b/src/net_server.c
@@ -1423,6 +1423,63 @@
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 @@
if (addr != NULL && addr == master_server)
{
- NET_Query_MasterResponse(packet);
+ NET_SV_MasterPacket(packet);
return;
}