Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add support for PXO's NAT hole punch #570

Merged
merged 1 commit into from
Sep 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions netcon/mtclient/mtgametrack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,9 @@ extern nw_RegisterCallback_fp DLLnw_RegisterCallback;
typedef int (*nw_DoReceiveCallbacks_fp)();
extern nw_DoReceiveCallbacks_fp DLLnw_DoReceiveCallbacks;

typedef int (*nw_SendWithID_fp)(uint8_t id, uint8_t *data, int len, network_address *who_to);
extern nw_SendWithID_fp DLLnw_SendWithID;

#if (defined(LOGGER) && (!defined(RELEASE)))
#define DLLmprintf(...) DLLDebug_ConsolePrintf(__VA_ARGS__)
#else
Expand Down Expand Up @@ -266,6 +269,23 @@ void IdleGameTracker() {
}
}

static void SendClientHolePunch(SOCKADDR_IN *addr) {
game_packet_header HolePunchAck;
network_address send_address;

memset(&send_address, 0, sizeof(network_address));
memcpy(send_address.address, &addr->sin_addr, 4);
send_address.port = htons(addr->sin_port);
send_address.connection_type = NP_TCP;

HolePunchAck.game_type = GameType;
HolePunchAck.type = INTEL_INT(GNT_NAT_HOLE_PUNCH_ACK);
HolePunchAck.len = INTEL_INT(GAME_HEADER_ONLY_SIZE);
HolePunchAck.sig = 0; // to make sure tracker ignores this packet when it's ACK'd there

DLLnw_SendWithID(PXO_NETID_GAME_TRACKER, (uint8_t *)&HolePunchAck, INTEL_INT(HolePunchAck.len), &send_address);
}

void HandleGamePacket(uint8_t *data, int len, network_address *from) {

memcpy(&inpacket, data, sizeof(inpacket));
Expand Down Expand Up @@ -294,6 +314,20 @@ void HandleGamePacket(uint8_t *data, int len, network_address *from) {
}
}
break;
case GNT_NAT_HOLE_PUNCH_REQ:
if (len == (GAME_HEADER_ONLY_SIZE+sizeof(hole_punch_addr_ip6))) {
// we don't support IPv6 yet so skip this one
} else {
SOCKADDR_IN nataddr;

auto ipv4 = reinterpret_cast<hole_punch_addr *>(&inpacket.data);
nataddr.sin_addr.s_addr = ipv4->addr;
nataddr.sin_port = ipv4->port;
nataddr.sin_family = AF_INET;

SendClientHolePunch(&nataddr);
}
break;
}
// mprintf(0,"Sending ACK.\n");
AckPacket(inpacket.sig);
Expand Down
14 changes: 14 additions & 0 deletions netcon/mtclient/mtgametrack.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,9 @@
#define GNT_GAMEUPDATE_TINY 9
#define GNT_GAMELIST_LITE_DATA 10
#define GNT_GAMELIST_LITE_FILTER_REQ 11
// NOTE: IDs 12-16 are special for Descent3 and shouldn't be used here!!
#define GNT_NAT_HOLE_PUNCH_REQ 17
#define GNT_NAT_HOLE_PUNCH_ACK 18

#define GT_FREESPACE 1
#define GT_DESCENT3 2
Expand Down Expand Up @@ -211,6 +214,17 @@ struct game_list {
uint16_t game_port[MAX_GAME_LISTS_PER_PACKET * 4];
};

struct hole_punch_addr {
uint32_t addr;
uint16_t port;
};

struct hole_punch_addr_ip6 {
// in6_addr addr;
uint8_t addr[16]; // NOTE: replace with above line that uses in6_addr once IPv6 is supported
uint16_t port;
};

// Function prototypes

int InitGameTrackerClient(int gametype);
Expand Down
Loading