Rewrite network interface.

This commit is contained in:
momo5502 2016-02-10 17:18:45 +01:00
parent 1359c12160
commit e3904db37c
11 changed files with 85 additions and 67 deletions

View File

@ -141,8 +141,7 @@ namespace Components
Network::Address master(Utils::VA("%s:%u", masterServerName, masterPort));
Logger::Print("Sending heartbeat to master: %s:%u\n", masterServerName, masterPort);
Network::Send(master, Utils::VA("heartbeat %s\n", "IW4"));
Network::SendCommand(master, "heartbeat", "IW4");
}
void Dedicated::OnFrame(Dedicated::Callback callback)

View File

@ -28,12 +28,11 @@ namespace Components
Logger::Print("Starting local server discovery...\n");
Discovery::DiscoveryContainer.Challenge = Utils::VA("%d", Utils::Cryptography::Rand::GenerateInt());
Discovery::DiscoveryContainer.Challenge = Utils::VA("%X", Utils::Cryptography::Rand::GenerateInt());
//Network::BroadcastAll("discovery\n");
unsigned int minPort = Dvar::Var("net_discoveryPortRangeMin").Get<unsigned int>();
unsigned int maxPort = Dvar::Var("net_discoveryPortRangeMax").Get<unsigned int>();
Network::BroadcastRange(minPort, maxPort, Utils::VA("discovery\n%s", Discovery::DiscoveryContainer.Challenge.data()));
Network::BroadcastRange(minPort, maxPort, Utils::VA("discovery %s", Discovery::DiscoveryContainer.Challenge.data()));
Logger::Print("Discovery sent within %dms, awaiting responses...\n", Game::Com_Milliseconds() - start);
@ -55,7 +54,7 @@ namespace Components
}
Logger::Print("Received discovery request from %s\n", address.GetString());
Network::Send(address, Utils::VA("discoveryResponse\n%s", data.data()));
Network::SendCommand(address, "discoveryResponse", data);
});
Network::Handle("discoveryResponse", [] (Network::Address address, std::string data)

View File

@ -121,11 +121,11 @@ namespace Components
download->lastPing = Game::Com_Milliseconds();
download->maxParts = request->maxPackets;
std::string packet = "dlAckResponse\n";
std::string packet;
packet.append(reinterpret_cast<char*>(&download->id), sizeof(int));
packet.append(challenge);
Network::SendRaw(target, packet);
Network::SendCommand(target, "dlAckResponse", packet);
}
}
@ -232,13 +232,13 @@ namespace Components
request.length = download.challenge.size();
std::string packet = "dlAckRequest\n";
std::string packet;
packet.append(reinterpret_cast<char*>(&request), sizeof(request));
packet.append(download.challenge);
Download::DataContainer.ServerDownloads.push_back(download);
Network::SendRaw(target, packet);
Network::SendCommand(target, "dlAckRequest", packet);
}
std::string Download::AssembleBuffer(Download::Container::DownloadCL* download)
@ -260,7 +260,7 @@ namespace Components
{
download->lastPing = Game::Com_Milliseconds();
std::string data = "dlMissRequest\n";
std::string data;
data.append(reinterpret_cast<char*>(&download->id), sizeof(int));
for (auto &packet : packets)
@ -268,7 +268,7 @@ namespace Components
data.append(reinterpret_cast<char*>(&packet), sizeof(int));
}
Network::SendRaw(download->target, data);
Network::SendCommand(download->target, "dlMissRequest", data);
}
}
@ -308,7 +308,7 @@ namespace Components
response.append(reinterpret_cast<char*>(&packetContainer), sizeof(packetContainer));
response.append(data);
Network::SendRaw(download->target, response);
Network::SendCommand(download->target, "dlPacketResponse", response);
}
void Download::Frame()
@ -384,7 +384,7 @@ namespace Components
response.append(reinterpret_cast<char*>(&download.id), sizeof(int));
response.append(file);
Network::SendRaw(target, response);
Network::SendCommand(target, "dlRequest", response);
return download.id;
}

View File

@ -79,8 +79,6 @@ namespace Components
}
}
// TODO: Check the external IP as well!
return false;
}
@ -89,35 +87,52 @@ namespace Components
Network::PacketHandlers[Utils::StrToLower(packet)] = callback;
}
void Network::Send(Game::netsrc_t type, Address target, std::string data)
void Network::Send(Game::netsrc_t type, Network::Address target, std::string data)
{
Game::NET_OutOfBandPrint(type, *target.Get(), data.data());
// NET_OutOfBandPrint only supports non-binary data!
//Game::NET_OutOfBandPrint(type, *target.Get(), data.data());
std::string rawData;
rawData.append("\xFF\xFF\xFF\xFF", 4);
rawData.append(data);
//rawData.append("\0", 1);
Network::SendRaw(type, target, rawData);
}
void Network::Send(Address target, std::string data)
void Network::Send(Network::Address target, std::string data)
{
Network::Send(Game::netsrc_t::NS_CLIENT, target, data);
}
void Network::SendRaw(Game::netsrc_t type, Address target, std::string data)
void Network::SendRaw(Game::netsrc_t type, Network::Address target, std::string data)
{
DWORD header = 0xFFFFFFFF;
std::string rawData;
rawData.append(reinterpret_cast<char*>(&header), 4);
rawData.append(data.begin(), data.end());
rawData.append("\0", 1);
// NET_OutOfBandData doesn't seem to work properly
//Game::NET_OutOfBandData(type, *target.Get(), data.data(), data.size());
Game::Sys_SendPacket(type, rawData.size(), rawData.data(), *target.Get());
Game::Sys_SendPacket(type, data.size(), data.data(), *target.Get());
}
void Network::SendRaw(Address target, std::string data)
void Network::SendRaw(Network::Address target, std::string data)
{
Network::SendRaw(Game::netsrc_t::NS_CLIENT, target, data);
}
void Network::SendCommand(Game::netsrc_t type, Network::Address target, std::string command, std::string data)
{
// Use space a separator (possible separators are '\n', ' ')
std::string packet;
packet.append(command);
packet.append(" ", 1);
packet.append(data);
Network::Send(type, target, packet);
}
void Network::SendCommand(Network::Address target, std::string command, std::string data)
{
Network::SendCommand(Game::netsrc_t::NS_CLIENT, target, command, data);
}
void Network::Broadcast(unsigned short port, std::string data)
{
Address target;
@ -126,7 +141,7 @@ namespace Components
target.SetIP(INADDR_BROADCAST);
target.SetType(Game::netadrtype_t::NA_BROADCAST);
Network::SendRaw(Game::netsrc_t::NS_CLIENT, target, data);
Network::Send(Game::netsrc_t::NS_CLIENT, target, data);
}
void Network::BroadcastRange(unsigned int min, unsigned int max, std::string data)
@ -181,7 +196,8 @@ namespace Components
}
// Remove trailing 0x00 byte
if (data.size() && !data[data.size() - 1]) data.pop_back();
// Actually, don't remove it, it might be part of the packet. Send correctly formatted packets instead!
//if (data.size() && !data[data.size() - 1]) data.pop_back();
Network::PacketHandlers[Network::SelectedPacket](from, data);
}

View File

@ -42,14 +42,18 @@ namespace Components
static void Handle(std::string packet, Callback callback);
// Only non-binary data
// Send quake-styled binary data
static void Send(Address target, std::string data);
static void Send(Game::netsrc_t type, Address target, std::string data);
// Allows sending binary data
// Allows sending raw data without quake header
static void SendRaw(Address target, std::string data);
static void SendRaw(Game::netsrc_t type, Address target, std::string data);
// Send quake-style command using binary data
static void SendCommand(Address target, std::string command, std::string data = "");
static void SendCommand(Game::netsrc_t type, Address target, std::string command, std::string data = "");
static void Broadcast(unsigned short port, std::string data);
static void BroadcastRange(unsigned int min, unsigned int max, std::string data);
static void BroadcastAll(std::string data);

View File

@ -121,21 +121,21 @@ namespace Components
if (entries.size() >= NODE_PACKET_LIMIT)
{
std::string packet = "nodeListResponse\n";
std::string packet;
packet.append((Dedicated::IsDedicated() ? "\x01" : "\0"), 1);
packet.append(reinterpret_cast<char*>(entries.data()), entries.size() * sizeof(Node::AddressEntry));
Network::SendRaw(address, packet);
Network::SendCommand(address, "nodeListResponse", packet);
entries.clear();
}
}
std::string packet = "nodeListResponse\n";
std::string packet;
packet.append((Dedicated::IsDedicated() ? "\x01" : "\0"), 1);
packet.append(reinterpret_cast<char*>(entries.data()), entries.size() * sizeof(Node::AddressEntry));
Network::SendRaw(address, packet);
Network::SendCommand(address, "nodeListResponse", packet);
}
void Node::DeleteInvalidSessions()
@ -234,12 +234,12 @@ namespace Components
packet.SerializeToString(&data);
Logger::Print("Sending registration request to %s\n", node.address.GetString());
Network::SendRaw(node.address, "nodeRegisterRequest\n" + data);
Network::SendCommand(node.address, "nodeRegisterRequest", data);
}
else
{
Logger::Print("Sending session request to %s\n", node.address.GetString());
Network::Send(node.address, "sessionRequest\n");
Network::SendCommand(node.address, "sessionRequest");
}
}
}
@ -254,11 +254,11 @@ namespace Components
if (Dedicated::IsDedicated())
{
Network::Send(node.address, "nodeListRequest\n");
Network::SendCommand(node.address, "nodeListRequest");
}
else
{
Network::Send(node.address, "sessionRequest\n");
Network::SendCommand(node.address, "sessionRequest");
}
}
}
@ -312,7 +312,7 @@ namespace Components
QuickPatch::OnShutdown([] ()
{
std::string data, challenge;
challenge = Utils::VA("X", Utils::Cryptography::Rand::GenerateInt());
challenge = Utils::VA("%X", Utils::Cryptography::Rand::GenerateInt());
Proto::NodePacket packet;
packet.set_challenge(challenge);
@ -321,7 +321,7 @@ namespace Components
for (auto node : Node::Nodes)
{
Network::SendRaw(node.address, "nodeDeregister\n" + data);
Network::SendCommand(node.address, "nodeDeregister", data);
}
});
@ -359,7 +359,7 @@ namespace Components
entry->challenge = challenge;
entry->state = Node::STATE_NEGOTIATING;
Network::SendRaw(address, "nodeRegisterSynchronize\n" + response);
Network::SendCommand(address, "nodeRegisterSynchronize", response);
});
Network::Handle("nodeRegisterSynchronize", [] (Network::Address address, std::string data)
@ -406,7 +406,7 @@ namespace Components
packet.set_publickey(publicKey);
packet.SerializeToString(&data);
Network::SendRaw(address, "nodeRegisterAcknowledge\n" + data);
Network::SendCommand(address, "nodeRegisterAcknowledge", data);
});
Network::Handle("nodeRegisterAcknowledge", [] (Network::Address address, std::string data)
@ -474,7 +474,7 @@ namespace Components
{
// Unallowed connection
Logger::Print("Node list requested by %s, but no valid session was present!\n", address.GetString());
Network::Send(address, "nodeListError\n");
Network::SendCommand(address, "nodeListError");
}
});
@ -521,7 +521,7 @@ namespace Components
Node::Sessions.push_back(session);
Network::Send(address, "sessionInitialize\n" + session.challenge);
Network::SendCommand(address, "sessionInitialize", session.challenge);
});
Network::Handle("sessionSynchronize", [] (Network::Address address, std::string data)
@ -534,7 +534,7 @@ namespace Components
{
Logger::Print("Session for %s validated.\n", address.GetString());
session->valid = true;
Network::Send(address, "sessionAcknowledge\n");
Network::SendCommand(address, "sessionAcknowledge");
}
else
{
@ -553,7 +553,7 @@ namespace Components
Logger::Print("Session initialization received. Synchronizing...\n", address.GetString());
entry->lastTime = Game::Com_Milliseconds();
Network::Send(address, "sessionSynchronize\n" + data);
Network::SendCommand(address, "sessionSynchronize", data);
});
Network::Handle("sessionAcknowledge", [] (Network::Address address, std::string data)
@ -566,7 +566,7 @@ namespace Components
entry->lastTime = Game::Com_Milliseconds();
Logger::Print("Session acknowledged, synchronizing node list...\n", address.GetString());
Network::Send(address, "nodeListRequest\n");
Network::SendCommand(address, "nodeListRequest");
Node::SendNodeList(address);
});
}
@ -700,7 +700,7 @@ namespace Components
for (int i = 0; i < 10; ++i)
{
std::string message = Utils::VA("%d", Utils::Cryptography::Rand::GenerateInt());
std::string message = Utils::VA("%X", Utils::Cryptography::Rand::GenerateInt());
std::string signature = Utils::Cryptography::ECDSA::SignMessage(Node::SignatureKey, message);
if (!Utils::Cryptography::ECDSA::VerifyMessage(Node::SignatureKey, message, signature))
@ -716,7 +716,7 @@ namespace Components
for (int i = 0; i < 10; ++i)
{
std::string message = Utils::VA("%d", Utils::Cryptography::Rand::GenerateInt());
std::string message = Utils::VA("%X", Utils::Cryptography::Rand::GenerateInt());
std::string signature = Utils::Cryptography::ECDSA::SignMessage(Node::SignatureKey, message);
// Invalidate the message...
@ -734,7 +734,7 @@ namespace Components
printf("Testing ECDSA key import...");
std::string pubKey = Node::SignatureKey.GetPublicKey();
std::string message = Utils::VA("%d", Utils::Cryptography::Rand::GenerateInt());
std::string message = Utils::VA("%X", Utils::Cryptography::Rand::GenerateInt());
std::string signature = Utils::Cryptography::ECDSA::SignMessage(Node::SignatureKey, message);
Utils::Cryptography::ECDSA::Key testKey;

View File

@ -30,7 +30,7 @@ namespace Components
Party::Container.Target = target;
Party::Container.Challenge = Utils::VA("%X", Utils::Cryptography::Rand::GenerateInt());
Network::Send(Party::Container.Target, Utils::VA("getinfo %s\n", Party::Container.Challenge.data()));
Network::SendCommand(Party::Container.Target, "getinfo", Party::Container.Challenge);
Command::Execute("openmenu popup_reconnectingtoparty");
}
@ -308,7 +308,7 @@ namespace Components
info.Set("matchtype", "0");
}
Network::Send(address, Utils::VA("infoResponse\n\\%s\n", info.Build().data()));
Network::SendCommand(address, "infoResponse", "\\" + info.Build());
});
Network::Handle("infoResponse", [] (Network::Address address, std::string data)
@ -339,7 +339,7 @@ namespace Components
// Send playlist request
Party::Container.RequestTime = Game::Com_Milliseconds();
Party::Container.AwaitingPlaylist = true;
Network::Send(address, "getplaylist\n");
Network::SendCommand(address, "getplaylist");
// This is not a safe method
// TODO: Fix actual error!

View File

@ -49,12 +49,12 @@ namespace Components
unsigned int size = compressedList.size();
unsigned int hash = Utils::OneAtATime(compressedList.data(), compressedList.size());
std::string response = "playlistresponse\n";
std::string response;
response.append(reinterpret_cast<char*>(&hash), 4);
response.append(reinterpret_cast<char*>(&size), 4);
response.append(compressedList);
Network::SendRaw(address, response);
Network::SendCommand(address, "playlistresponse", response);
}
void Playlist::PlaylistReponse(Network::Address address, std::string data)

View File

@ -64,7 +64,7 @@ namespace Components
}
ServerInfo::PlayerContainer.Target = info->Addr;
Network::Send(ServerInfo::PlayerContainer.Target, "getstatus\n");
Network::SendCommand(ServerInfo::PlayerContainer.Target, "getstatus");
}
}
@ -157,7 +157,7 @@ namespace Components
playerList.append(Utils::VA("%i %i \"%s\"\n", score, ping, name.data()));
}
Network::Send(address, Utils::VA("statusResponse\n\\%s\n%s\n", info.Build().data(), playerList.data()));
Network::SendCommand(address, "statusResponse", "\\" + info.Build() + "\n" + playerList + "\n");
});
Network::Handle("statusResponse", [] (Network::Address address, std::string data)

View File

@ -224,8 +224,8 @@ namespace Components
Logger::Print("Sending serverlist request to master: %s:%u\n", masterServerName, masterPort);
Network::Send(ServerList::RefreshContainer.Host, Utils::VA("getservers IW4 %i full empty", PROTOCOL));
//Network::Send(ServerList::RefreshContainer.Host, "getservers 0 full empty\n");
Network::SendCommand(ServerList::RefreshContainer.Host, "getservers", Utils::VA("IW4 %i full empty", PROTOCOL));
//Network::SendCommand(ServerList::RefreshContainer.Host, "getservers", "0 full empty");
#else
ServerList::RefreshContainer.Mutex.lock();
@ -500,11 +500,11 @@ namespace Components
SendServers--;
server->SendTime = Game::Com_Milliseconds();
server->Challenge = Utils::VA("%d", Utils::Cryptography::Rand::GenerateInt());
server->Challenge = Utils::VA("%X", Utils::Cryptography::Rand::GenerateInt());
ServerList::RefreshContainer.SentCount++;
Network::Send(server->Target, Utils::VA("getinfo %s\n", server->Challenge.data()));
Network::SendCommand(server->Target, "getinfo", server->Challenge);
// Display in the menu, like in COD4
Localization::Set("MPUI_SERVERQUERIED", Utils::VA("Sent requests: %d/%d", ServerList::RefreshContainer.SentCount, ServerList::RefreshContainer.SendCount));

View File

@ -131,9 +131,9 @@ namespace Utils
std::string ParseChallenge(std::string data)
{
// Ensure line break
data.append("\n");
return data.substr(0, data.find_first_of("\n")).data();
auto pos = data.find_first_of("\n ");
if (pos == std::string::npos) return data;
return data.substr(0, pos).data();
}
// TODO: Use modern file reading methods