Skip to content

Commit

Permalink
More relay tweaks and fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
IonAgorria committed Mar 27, 2024
1 parent 3d8d11b commit a39da5c
Show file tree
Hide file tree
Showing 20 changed files with 219 additions and 144 deletions.
27 changes: 15 additions & 12 deletions Source/Network/NetConnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#include "P2P_interface.h"
#include "NetConnectionAux.h"

const uint32_t TRANSPORT_RECV_SLEEP = 10;

///////// NetAddress //////////////

NetAddress::NetAddress(uint32_t host, uint16_t port): addr() {
Expand Down Expand Up @@ -135,6 +137,7 @@ int32_t NetTransport::receive(void* buffer, uint32_t minlen, uint32_t maxlen, in
int32_t amount = receive_raw(static_cast<uint8_t*>(buffer) + received, static_cast<int32_t>(maxlen) - received, timeout);
if (has_timeout && amount == NT_STATUS_NO_DATA) {
//Keep waiting
Sleep(TRANSPORT_RECV_SLEEP);
continue;
}
if (amount < 0) {
Expand Down Expand Up @@ -270,12 +273,12 @@ int32_t NetConnection::send(const XBuffer* data, NETID source, NETID destination
return -1;
}
if (data == nullptr) {
fprintf(stderr, "NetConnection::send NETID %" PRIX64 " null buffer\n", netid);
fprintf(stderr, "NetConnection::send NETID 0x%" PRIX64 " null buffer\n", netid);
ErrH.Abort("Got null buffer in send");
}
if (data->tell() == 0) {
xassert(0);
fprintf(stderr, "NetConnection::send NETID %" PRIX64 " data to sent is empty!\n", netid);
fprintf(stderr, "NetConnection::send NETID 0x%" PRIX64 " data to sent is empty!\n", netid);
return -2;
}
if (destination == NETID_NONE) {
Expand Down Expand Up @@ -308,7 +311,7 @@ int32_t NetConnection::send(const XBuffer* data, NETID source, NETID destination
int32_t msg_size = static_cast<int32_t>(body_len + header_len);
if (msg_size > PERIMETER_MESSAGE_MAX_SIZE) {
xassert(0);
fprintf(stderr, "NetConnection::send NETID %" PRIX64 " data too big len %d\n", netid, msg_size);
fprintf(stderr, "NetConnection::send NETID 0x%" PRIX64 " data too big len %d\n", netid, msg_size);
return -2;
}

Expand All @@ -324,7 +327,7 @@ int32_t NetConnection::send(const XBuffer* data, NETID source, NETID destination

#ifdef PERIMETER_DEBUG
if (xbuf.tell() != msg_size) {
fprintf(stderr, "NetConnection::send NETID %" PRIX64 " written buffer mismatch buf %" PRIsize " msg %" PRIi32 " len %" PRIsize " %s\n",
fprintf(stderr, "NetConnection::send NETID 0x%" PRIX64 " written buffer mismatch buf %" PRIsize " msg %" PRIi32 " len %" PRIsize " %s\n",
netid, xbuf.tell(), msg_size, sending_buffer.tell(), SDLNet_GetError());
close_error();
return -4;
Expand All @@ -333,7 +336,7 @@ int32_t NetConnection::send(const XBuffer* data, NETID source, NETID destination
int32_t sent = transport->send(xbuf.buf, xbuf.tell(), timeout);

if (sent != msg_size) {
fprintf(stderr, "NetConnection::send NETID %" PRIX64 " length mismatch sent %" PRIi32 " msg %" PRIi32 " len %" PRIsize " %s\n",
fprintf(stderr, "NetConnection::send NETID 0x%" PRIX64 " length mismatch sent %" PRIi32 " msg %" PRIi32 " len %" PRIsize " %s\n",
netid, sent, msg_size, sending_buffer.tell(), SDLNet_GetError());
close_error();
return -4;
Expand All @@ -358,14 +361,14 @@ int32_t NetConnection::receive(NetConnectionMessage** packet_ptr, int32_t timeou
return amount;
}
if (amount != sizeof(header)) {
fprintf(stderr, "NetConnection::receive NETID %" PRIX64 " header failed amount %d %s\n", netid, amount, SDLNet_GetError());
fprintf(stderr, "NetConnection::receive NETID 0x%" PRIX64 " header failed amount %d %s\n", netid, amount, SDLNet_GetError());
return -2;
}
header = SDL_SwapBE64(header);

//Check magic
if ((header & NC_HEADER_MASK) != NC_HEADER_MAGIC) {
fprintf(stderr, "NetConnection::receive NETID %" PRIX64 " header failed magic mismatch 0x%" PRIX64 " %s\n", netid, header, SDLNet_GetError());
fprintf(stderr, "NetConnection::receive NETID 0x%" PRIX64 " header failed magic mismatch 0x%" PRIX64 " %s\n", netid, header, SDLNet_GetError());
return -2;
}

Expand All @@ -376,7 +379,7 @@ int32_t NetConnection::receive(NetConnectionMessage** packet_ptr, int32_t timeou
//Ensure is not too big
if (amount >= PERIMETER_MESSAGE_MAX_SIZE) {
xassert(0);
fprintf(stderr, "NetConnection::receive NETID %" PRIX64 " header failed too long 0x%" PRIX64 " len %" PRIu32 "\n", netid, header, amount);
fprintf(stderr, "NetConnection::receive NETID 0x%" PRIX64 " header failed too long 0x%" PRIX64 " len %" PRIu32 "\n", netid, header, amount);
return -2;
}

Expand All @@ -394,10 +397,10 @@ int32_t NetConnection::receive(NetConnectionMessage** packet_ptr, int32_t timeou
std::max(timeout, 0) + RECV_DATA_AFTER_HEADER_TIMEOUT
);
if (received <= 0) {
fprintf(stderr, "NetConnection::receive NETID %" PRIX64 " data chunk failed amount %d received %d %s\n", netid, amount, received, SDLNet_GetError());
fprintf(stderr, "NetConnection::receive NETID 0x%" PRIX64 " data chunk failed amount %d received %d %s\n", netid, amount, received, SDLNet_GetError());
amount = -5;
} else if (amount != received) {
fprintf(stderr, "NetConnection::receive NETID %" PRIX64 " data failed amount %d received %d %s\n", netid, amount, received, SDLNet_GetError());
fprintf(stderr, "NetConnection::receive NETID 0x%" PRIX64 " data failed amount %d received %d %s\n", netid, amount, received, SDLNet_GetError());
amount = -6;
}

Expand All @@ -406,10 +409,10 @@ int32_t NetConnection::receive(NetConnectionMessage** packet_ptr, int32_t timeou
amount -= sizeof(NETID) * 2;
if (amount < 0) {
xassert(0);
fprintf(stderr, "NetConnection::receive NETID %" PRIX64 " header without message 0x%" PRIX64 " len %" PRIu32 "\n", netid, header, amount);
fprintf(stderr, "NetConnection::receive NETID 0x%" PRIX64 " header without message 0x%" PRIX64 " len %" PRIu32 "\n", netid, header, amount);
amount = -7;
} else if (amount == 0) {
fprintf(stderr, "NetConnection::receive NETID %" PRIX64 " message is empty 0x%" PRIX64 "\n", netid, header);
fprintf(stderr, "NetConnection::receive NETID 0x%" PRIX64 " message is empty 0x%" PRIX64 "\n", netid, header);
} else {
*packet > packet->source;
*packet > packet->destination;
Expand Down
5 changes: 5 additions & 0 deletions Source/Network/NetConnection.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ class NetAddress {
return *this;
}

bool operator==(const NetAddress& other) const {
return this->addr.host == other.addr.host
&& this->addr.port == other.addr.port;
}

NetAddress();
NetAddress(uint32_t host, uint16_t port);
~NetAddress();
Expand Down
76 changes: 63 additions & 13 deletions Source/Network/NetConnectionHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "NetConnectionAux.h"
#include "NetRelay.h"
#include "codepages/codepages.h"
#include "NetRelaySerialization.h"

NetConnectionHandler::NetConnectionHandler(PNetCenter* center): net_center(center) {
stopConnections();
Expand Down Expand Up @@ -328,7 +329,8 @@ void NetConnectionHandler::stopListening() {
bool NetConnectionHandler::startRelayRoom() {
//Create relay connection
NetAddress conn;
if (!getNetRelayAddress(conn)) {
const char* primary_relay = getPrimaryNetRelayAddress();
if (!primary_relay || !NetAddress::resolve(conn, primary_relay, NET_RELAY_DEFAULT_PORT)) {
return false;
}
TCPsocket socket = conn.openTCP();
Expand All @@ -340,14 +342,62 @@ bool NetConnectionHandler::startRelayRoom() {
delete connection;
return false;
}

connection->is_relay = true;
has_relay_connection = true;

//Do the request to list relays we can use to create the room
static NetRelayMessage_PeerListLobbyHosts msg_lobby_hosts;
static NetRelayMessage_RelayListLobbies response_lobby_hosts;
bool ok = sendNetRelayMessage(connection, &msg_lobby_hosts, NETID_NONE);
if (ok) ok = receiveNetRelayMessage(connection, NETID_NONE, &response_lobby_hosts, RELAY_MSG_RELAY_LIST_LOBBY_HOSTS);
if (ok) {
bool use_current_relay = false;
XPrmIArchive ia;
std::swap(ia.buffer(), response_lobby_hosts.data);
ia.reset();
std::vector<NetRelay_LobbyHost> hosts = {};
ia >> hosts;
NetAddress host_conn;
for (NetRelay_LobbyHost& host : hosts) {
std::string host_address = host.getAddress();
if (host_address == primary_relay) {
use_current_relay = true;
break;
}
NetAddress::resolve(
host_conn,
host_address,
NET_RELAY_DEFAULT_PORT
);
if (host_conn == conn) {
use_current_relay = true;
break;
}
}

//Use last host we got from list and establish connection
if (!use_current_relay) {
connection->close();

conn = host_conn;
socket = conn.openTCP();
if (!socket) {
ok = false;
} else {
connection = newConnectionFromSocket(socket, NETID_RELAY);
if (!connection || connection->netid == NETID_NONE) {
delete connection;
ok = false;
}
}
}
}

//Send our room info to create it
const NetRelayMessage_PeerSetupRoom& msg = net_center->GenerateRelaySetupRoom();

bool ok = sendNetRelayMessage(connection, &msg, NETID_HOST);
if (ok) {
const NetRelayMessage_PeerSetupRoom& msg_setup_room = net_center->GenerateRelaySetupRoom();
ok = sendNetRelayMessage(connection, &msg_setup_room, NETID_HOST);
}

//Receive list of peers and our own netid
if (ok) {
Expand Down Expand Up @@ -575,7 +625,7 @@ bool NetConnectionHandler::reassignConnectionNETID(NetConnection* connection, NE

//Couldn't be reassigned
xassert(0);
fprintf(stderr, "Couldn't reassign connection %" PRIX64 " to %" PRIX64 "\n", connection->netid, netid);
fprintf(stderr, "Couldn't reassign connection 0x%" PRIX64 " to 0x%" PRIX64 "\n", connection->netid, netid);
return false;
}

Expand All @@ -589,7 +639,7 @@ void NetConnectionHandler::receivedRelayMessage(NetConnection* connection, NetCo
bool terminate = false;
if (msg_header.protocol_version != NET_RELAY_PROTOCOL_VERSION) {
xassert(0);
fprintf(stderr, "[Relay] Unexpected protocol %" PRIX32 "\n", msg_header.protocol_version);
fprintf(stderr, "[Relay] Unexpected protocol 0x%" PRIX32 "\n", msg_header.protocol_version);
terminate = true;
} else {
bool wrong_destination;
Expand All @@ -615,7 +665,7 @@ void NetConnectionHandler::receivedRelayMessage(NetConnection* connection, NetCo
default: {
#ifdef PERIMETER_DEBUG
xassert(0);
fprintf(stderr, "[Relay] connection sent unknown msg type: %" PRIX32 "\n", msg_header.msg_type);
fprintf(stderr, "[Relay] connection sent unknown msg type: 0x%" PRIX32 "\n", msg_header.msg_type);
#endif
break;
}
Expand Down Expand Up @@ -667,20 +717,20 @@ void NetConnectionHandler::receivedRelayMessage(NetConnection* connection, NetCo
}

#ifdef PERIMETER_DEBUG
printf("[Relay] room list destination %" PRIX64 " peers: %" PRIsize " [",
printf("[Relay] room list destination 0x%" PRIX64 " peers: %" PRIsize " [",
msg->destination, message.peers.size());
for (NETID netid : message.peers) {
printf(" %" PRIX64, netid);
printf(" 0x%" PRIX64, netid);
}
printf(" ]\nNETIDs local: %" PRIX64 " host: %" PRIX64 "\n", net_center->m_localNETID, net_center->m_hostNETID);
printf(" ]\nNETIDs local: 0x%" PRIX64 " host: 0x%" PRIX64 "\n", net_center->m_localNETID, net_center->m_hostNETID);
#endif
break;
}
case RELAY_MSG_RELAY_ADD_PEER: {
static NetRelayMessage_RelayAddPeer message;
message.read(*msg);
#ifdef PERIMETER_DEBUG
printf("[Relay] room add peer %" PRIX64 "\n", message.netid);
printf("[Relay] room add peer 0x%" PRIX64 "\n", message.netid);
#endif
NetRelayPeerInfo info;
info.relay_netid = msg->source;
Expand All @@ -692,7 +742,7 @@ void NetConnectionHandler::receivedRelayMessage(NetConnection* connection, NetCo
static NetRelayMessage_RelayRemovePeer message;
message.read(*msg);
#ifdef PERIMETER_DEBUG
printf("[Relay] room remove peer %" PRIX64 "\n", message.netid);
printf("[Relay] room remove peer 0x%" PRIX64 "\n", message.netid);
#endif
auto it = relayPeers.begin();
auto end = relayPeers.end();
Expand Down
38 changes: 26 additions & 12 deletions Source/Network/NetRelay.cpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
#include "NetIncludes.h"
#include "P2P_interface.h"
#include "NetConnectionAux.h"
#include "NetRelay.h"

bool getNetRelayAddress(NetAddress& addr) {
const char* getPrimaryNetRelayAddress() {
const char* cmdline_relay = check_command_line("netrelay");
return NetAddress::resolve(
addr,
cmdline_relay ? cmdline_relay : NET_RELAY_DEFAULT_ADDRESS,
NET_RELAY_DEFAULT_PORT
);
return cmdline_relay ? cmdline_relay : NET_RELAY_DEFAULT_ADDRESS;
}

bool receiveNetRelayMessage(
Expand All @@ -30,10 +28,10 @@ bool receiveNetRelayMessage(
fprintf(stderr, "Missing packet?\n");
ret = -1;
} else if (packet->source != relay->getNETID()) {
fprintf(stderr, "Unexpected relay message source %" PRIX64 " expected %" PRIX64 "\n", packet->source, relay->getNETID());
fprintf(stderr, "Unexpected relay message source 0x%" PRIX64 " expected 0x%" PRIX64 "\n", packet->source, relay->getNETID());
ret = -1;
} else if (packet->destination != source) {
fprintf(stderr, "Unexpected relay message destination %" PRIX64 " expected %" PRIX64 "\n", packet->destination, source);
fprintf(stderr, "Unexpected relay message destination 0x%" PRIX64 " expected 0x%" PRIX64 "\n", packet->destination, source);
ret = -1;
}
}
Expand All @@ -44,7 +42,7 @@ bool receiveNetRelayMessage(
result->read_relay_header(*packet);
if (result->protocol_version != NET_RELAY_PROTOCOL_VERSION) {
xassert(0);
fprintf(stderr, "Unexpected relay protocol %" PRIX32 "\n", result->protocol_version);
fprintf(stderr, "Unexpected relay protocol 0x%" PRIX32 "\n", result->protocol_version);
ret = -1;
} else if (result->msg_type == RELAY_MSG_CLOSE) {
static NetRelayMessage_Close msg_close;
Expand All @@ -54,7 +52,7 @@ bool receiveNetRelayMessage(
ret = -1;
} else if (result_type_expected != RELAY_MSG_UNKNOWN && result->msg_type != result_type_expected) {
xassert(0);
fprintf(stderr, "Unexpected relay message type %" PRIX32 " expected %" PRIX32 "\n", result->msg_type, result_type_expected);
fprintf(stderr, "Unexpected relay message type 0x%" PRIX32 " expected 0x%" PRIX32 "\n", result->msg_type, result_type_expected);
ret = -1;
}
}
Expand Down Expand Up @@ -167,11 +165,22 @@ void NetRelayMessage_Close::write(XBuffer& out) const {
out < code;
}

void NetRelayMessage_PeerListRooms::write(XBuffer& out) const {
void NetRelayMessage_PeerListLobbyHosts::write(XBuffer& out) const {
//Game identifier
write_string(out, "perimeter", 32);
//Game version required
write_string(out, PERIMETER_VERSION, 32);
//Send in XPrm format
out < NET_RELAY_FORMAT_XPRM;
}

void NetRelayMessage_PeerListLobbies::write(XBuffer& out) const {
//Game identifier
write_string(out, "perimeter", 32);
//Game version required
write_string(out, PERIMETER_VERSION, 32);
//Send in XPrm format
out < FORMAT_XPRM;
out < NET_RELAY_FORMAT_XPRM;
}

void NetRelayMessage_PeerSetupRoom::write(XBuffer& out) const {
Expand All @@ -191,6 +200,7 @@ void NetRelayMessage_PeerSetupRoom::write(XBuffer& out) const {
write_map(out, {
{ "scenario", scenarioName },
{ "game_content", std::to_string(gameContent) },
{ "arch", std::to_string(NetConnectionInfo::computeArchFlags()) },
}, 32, 64, 128);
}

Expand All @@ -212,6 +222,10 @@ void NetRelayMessage_PeerPingResponse::write(XBuffer& out) const {
out < subsecs;
}

void NetRelayMessage_RelayListLobbyHosts::read(XBuffer& in) {
data = in;
}

void NetRelayMessage_RelayListLobbies::read(XBuffer& in) {
data = in;
}
Expand Down
Loading

0 comments on commit a39da5c

Please sign in to comment.