forked from Mirrors/openclonk
Implement netpunching for IPv6
parent
c94b4cc3b0
commit
33a32cb6bd
|
@ -18,6 +18,11 @@
|
||||||
#include "network/C4Network2Address.h"
|
#include "network/C4Network2Address.h"
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
|
void C4NetpuncherID::CompileFunc(StdCompiler *pComp) {
|
||||||
|
pComp->Value(mkNamingAdapt(v4, "IPv4", 0u));
|
||||||
|
pComp->Value(mkNamingAdapt(v6, "IPv6", 0u));
|
||||||
|
}
|
||||||
|
|
||||||
std::unique_ptr<C4NetpuncherPacket> C4NetpuncherPacket::Construct(const C4NetIOPacket& rpack) {
|
std::unique_ptr<C4NetpuncherPacket> C4NetpuncherPacket::Construct(const C4NetIOPacket& rpack) {
|
||||||
if (!rpack.getPData()) return nullptr;
|
if (!rpack.getPData()) return nullptr;
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -27,7 +27,14 @@ enum C4NetpuncherPacketType {
|
||||||
// extend this with exchanging ICE parameters, some day?
|
// extend this with exchanging ICE parameters, some day?
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef uint32_t C4NetpuncherID_t;
|
struct C4NetpuncherID {
|
||||||
|
typedef uint32_t value;
|
||||||
|
|
||||||
|
value v4 = 0, v6 = 0;
|
||||||
|
|
||||||
|
void CompileFunc(StdCompiler *pComp);
|
||||||
|
bool operator==(const C4NetpuncherID& other) const { return v4 == other.v4 && v6 == other.v6; }
|
||||||
|
};
|
||||||
|
|
||||||
class C4NetpuncherPacket {
|
class C4NetpuncherPacket {
|
||||||
public:
|
public:
|
||||||
|
@ -38,7 +45,7 @@ public:
|
||||||
C4NetIOPacket PackTo(const C4NetIO::addr_t&) const;
|
C4NetIOPacket PackTo(const C4NetIO::addr_t&) const;
|
||||||
protected:
|
protected:
|
||||||
virtual StdBuf PackInto() const = 0;
|
virtual StdBuf PackInto() const = 0;
|
||||||
typedef C4NetpuncherID_t CID;
|
typedef C4NetpuncherID::value CID;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<C4NetpuncherPacketType TYPE>
|
template<C4NetpuncherPacketType TYPE>
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
class C4PuncherServer : public C4NetIOUDP, private C4NetIO::CBClass
|
class C4PuncherServer : public C4NetIOUDP, private C4NetIO::CBClass
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef C4NetpuncherID_t CID;
|
typedef C4NetpuncherID::value CID;
|
||||||
C4PuncherServer() {
|
C4PuncherServer() {
|
||||||
C4NetIOUDP::SetCallback(this);
|
C4NetIOUDP::SetCallback(this);
|
||||||
rng = std::bind(std::uniform_int_distribution<CID>(1/*, max*/), std::ref(random_device));
|
rng = std::bind(std::uniform_int_distribution<CID>(1/*, max*/), std::ref(random_device));
|
||||||
|
|
|
@ -148,7 +148,7 @@ C4Network2::C4Network2()
|
||||||
fPausedForVote(false),
|
fPausedForVote(false),
|
||||||
iLastOwnVoting(0),
|
iLastOwnVoting(0),
|
||||||
fStreaming(false),
|
fStreaming(false),
|
||||||
NetpuncherGameID(0)
|
NetpuncherGameID(C4NetpuncherID())
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -169,7 +169,7 @@ bool C4Network2::InitHost(bool fLobby)
|
||||||
fChasing = false;
|
fChasing = false;
|
||||||
fAllowJoin = false;
|
fAllowJoin = false;
|
||||||
iNextClientID = C4ClientIDStart;
|
iNextClientID = C4ClientIDStart;
|
||||||
NetpuncherGameID = 0;
|
NetpuncherGameID = C4NetpuncherID();
|
||||||
NetpuncherAddr = ::Config.Network.PuncherAddress;
|
NetpuncherAddr = ::Config.Network.PuncherAddress;
|
||||||
// initialize client list
|
// initialize client list
|
||||||
Clients.Init(&Game.Clients, true);
|
Clients.Init(&Game.Clients, true);
|
||||||
|
@ -689,7 +689,7 @@ void C4Network2::Clear()
|
||||||
delete pVoteDialog; pVoteDialog = nullptr;
|
delete pVoteDialog; pVoteDialog = nullptr;
|
||||||
fPausedForVote = false;
|
fPausedForVote = false;
|
||||||
iLastOwnVoting = 0;
|
iLastOwnVoting = 0;
|
||||||
NetpuncherGameID = 0;
|
NetpuncherGameID = C4NetpuncherID();
|
||||||
Votes.Clear();
|
Votes.Clear();
|
||||||
// don't clear fPasswordNeeded here, it's needed by InitClient
|
// don't clear fPasswordNeeded here, it's needed by InitClient
|
||||||
}
|
}
|
||||||
|
@ -907,7 +907,7 @@ void C4Network2::HandleLobbyPacket(char cStatus, const C4PacketBase *pBasePkt, C
|
||||||
if (pLobby) pLobby->HandlePacket(cStatus, pBasePkt, pClient);
|
if (pLobby) pLobby->HandlePacket(cStatus, pBasePkt, pClient);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool C4Network2::HandlePuncherPacket(C4NetpuncherPacket::uptr pkt)
|
bool C4Network2::HandlePuncherPacket(C4NetpuncherPacket::uptr pkt, C4NetIO::HostAddress::AddressFamily family)
|
||||||
{
|
{
|
||||||
// TODO: is this all thread-safe?
|
// TODO: is this all thread-safe?
|
||||||
assert(pkt);
|
assert(pkt);
|
||||||
|
@ -928,20 +928,30 @@ bool C4Network2::HandlePuncherPacket(C4NetpuncherPacket::uptr pkt)
|
||||||
case PID_Puncher_AssID:
|
case PID_Puncher_AssID:
|
||||||
if (isHost())
|
if (isHost())
|
||||||
{
|
{
|
||||||
NetpuncherGameID = GETPKT(AssID)->GetID();
|
getNetpuncherGameID(family) = GETPKT(AssID)->GetID();
|
||||||
InvalidateReference();
|
InvalidateReference();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// While we don't need the ID as a client, this nicely serves as the signal that we can start using the netpuncher
|
// While we don't need the ID as a client, this nicely serves as the signal that we can start using the netpuncher
|
||||||
if (Status.getState() == GS_Init && getNetpuncherGameID())
|
if (Status.getState() == GS_Init && getNetpuncherGameID(family))
|
||||||
NetIO.SendPuncherPacket(C4NetpuncherPacketSReq(getNetpuncherGameID()));
|
NetIO.SendPuncherPacket(C4NetpuncherPacketSReq(getNetpuncherGameID(family)), family);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
default: return false;
|
default: return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
C4NetpuncherID::value& C4Network2::getNetpuncherGameID(C4NetIO::HostAddress::AddressFamily family)
|
||||||
|
{
|
||||||
|
switch (family)
|
||||||
|
{
|
||||||
|
case C4NetIO::HostAddress::IPv4: return NetpuncherGameID.v4;
|
||||||
|
case C4NetIO::HostAddress::IPv6: return NetpuncherGameID.v6;
|
||||||
|
default: assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void C4Network2::InitPuncher()
|
void C4Network2::InitPuncher()
|
||||||
{
|
{
|
||||||
// We have an internet connection, so let's punch the puncher server here in order to open an udp port
|
// We have an internet connection, so let's punch the puncher server here in order to open an udp port
|
||||||
|
@ -952,6 +962,12 @@ void C4Network2::InitPuncher()
|
||||||
PuncherAddr.SetDefaultPort(C4NetStdPortPuncher);
|
PuncherAddr.SetDefaultPort(C4NetStdPortPuncher);
|
||||||
NetIO.InitPuncher(PuncherAddr);
|
NetIO.InitPuncher(PuncherAddr);
|
||||||
}
|
}
|
||||||
|
PuncherAddr.SetAddress(getNetpuncherAddr(), C4NetIO::HostAddress::IPv6);
|
||||||
|
if (!PuncherAddr.IsNull())
|
||||||
|
{
|
||||||
|
PuncherAddr.SetDefaultPort(C4NetStdPortPuncher);
|
||||||
|
NetIO.InitPuncher(PuncherAddr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void C4Network2::OnGameSynchronized()
|
void C4Network2::OnGameSynchronized()
|
||||||
|
|
|
@ -194,7 +194,7 @@ protected:
|
||||||
unsigned int iCurrentStreamAmount, iCurrentStreamPosition;
|
unsigned int iCurrentStreamAmount, iCurrentStreamPosition;
|
||||||
|
|
||||||
// puncher
|
// puncher
|
||||||
C4NetpuncherID_t NetpuncherGameID;
|
C4NetpuncherID NetpuncherGameID;
|
||||||
StdCopyStrBuf NetpuncherAddr;
|
StdCopyStrBuf NetpuncherAddr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -257,7 +257,7 @@ public:
|
||||||
void OnDisconn(C4Network2IOConnection *pConn);
|
void OnDisconn(C4Network2IOConnection *pConn);
|
||||||
void HandlePacket(char cStatus, const C4PacketBase *pBasePkt, C4Network2IOConnection *pConn);
|
void HandlePacket(char cStatus, const C4PacketBase *pBasePkt, C4Network2IOConnection *pConn);
|
||||||
void HandleLobbyPacket(char cStatus, const C4PacketBase *pBasePkt, C4Network2IOConnection *pConn);
|
void HandleLobbyPacket(char cStatus, const C4PacketBase *pBasePkt, C4Network2IOConnection *pConn);
|
||||||
bool HandlePuncherPacket(C4NetpuncherPacket::uptr);
|
bool HandlePuncherPacket(C4NetpuncherPacket::uptr, C4NetIO::HostAddress::AddressFamily family);
|
||||||
|
|
||||||
// runtime join stuff
|
// runtime join stuff
|
||||||
void OnGameSynchronized();
|
void OnGameSynchronized();
|
||||||
|
@ -303,7 +303,8 @@ public:
|
||||||
bool StopStreaming();
|
bool StopStreaming();
|
||||||
|
|
||||||
// netpuncher
|
// netpuncher
|
||||||
C4NetpuncherID_t getNetpuncherGameID() const { return NetpuncherGameID; }
|
C4NetpuncherID::value& getNetpuncherGameID(C4NetIO::HostAddress::AddressFamily family);
|
||||||
|
C4NetpuncherID getNetpuncherGameID() const { return NetpuncherGameID; };
|
||||||
StdStrBuf getNetpuncherAddr() const { return NetpuncherAddr; }
|
StdStrBuf getNetpuncherAddr() const { return NetpuncherAddr; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -460,28 +460,49 @@ bool C4Network2IO::InitPuncher(C4NetIO::addr_t nPuncherAddr)
|
||||||
if (!pNetIO_UDP)
|
if (!pNetIO_UDP)
|
||||||
return false;
|
return false;
|
||||||
// save address
|
// save address
|
||||||
PuncherAddr = nPuncherAddr;
|
switch (nPuncherAddr.GetFamily())
|
||||||
|
{
|
||||||
|
case C4NetIO::HostAddress::IPv4:
|
||||||
|
PuncherAddrIPv4 = nPuncherAddr;
|
||||||
|
break;
|
||||||
|
case C4NetIO::HostAddress::IPv6:
|
||||||
|
PuncherAddrIPv6 = nPuncherAddr;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
// let's punch
|
// let's punch
|
||||||
return pNetIO_UDP->Connect(PuncherAddr);
|
return pNetIO_UDP->Connect(nPuncherAddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void C4Network2IO::Punch(const C4NetIO::addr_t &punchee_addr) {
|
void C4Network2IO::Punch(const C4NetIO::addr_t &punchee_addr)
|
||||||
|
{
|
||||||
if (!pNetIO_UDP)
|
if (!pNetIO_UDP)
|
||||||
return;
|
return;
|
||||||
C4PacketPing PktPeng;
|
C4PacketPing PktPeng;
|
||||||
dynamic_cast<C4NetIOUDP*>(pNetIO_UDP)->SendDirect(MkC4NetIOPacket(PID_Pong, PktPeng, punchee_addr));
|
dynamic_cast<C4NetIOUDP*>(pNetIO_UDP)->SendDirect(MkC4NetIOPacket(PID_Pong, PktPeng, punchee_addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
void C4Network2IO::SendPuncherPacket(const C4NetpuncherPacket& p) {
|
void C4Network2IO::SendPuncherPacket(const C4NetpuncherPacket& p, C4NetIO::HostAddress::AddressFamily family)
|
||||||
if (!pNetIO_UDP || PuncherAddr.IsNull()) return;
|
{
|
||||||
pNetIO_UDP->Send(p.PackTo(PuncherAddr));
|
if (!pNetIO_UDP) return;
|
||||||
|
if (family == C4NetIO::HostAddress::IPv4 && !PuncherAddrIPv4.IsNull())
|
||||||
|
pNetIO_UDP->Send(p.PackTo(PuncherAddrIPv4));
|
||||||
|
else if (family == C4NetIO::HostAddress::IPv6 && !PuncherAddrIPv6.IsNull())
|
||||||
|
pNetIO_UDP->Send(p.PackTo(PuncherAddrIPv6));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool C4Network2IO::IsPuncherAddr(const C4NetIO::addr_t& addr) const
|
||||||
|
{
|
||||||
|
return (!PuncherAddrIPv4.IsNull() && PuncherAddrIPv4 == addr)
|
||||||
|
|| (!PuncherAddrIPv6.IsNull() && PuncherAddrIPv6 == addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// C4NetIO interface
|
// C4NetIO interface
|
||||||
bool C4Network2IO::OnConn(const C4NetIO::addr_t &PeerAddr, const C4NetIO::addr_t &ConnectAddr, const C4NetIO::addr_t *pOwnAddr, C4NetIO *pNetIO)
|
bool C4Network2IO::OnConn(const C4NetIO::addr_t &PeerAddr, const C4NetIO::addr_t &ConnectAddr, const C4NetIO::addr_t *pOwnAddr, C4NetIO *pNetIO)
|
||||||
{
|
{
|
||||||
// puncher answer?
|
// puncher answer?
|
||||||
if (pNetIO == pNetIO_UDP && !PuncherAddr.IsNull() && PuncherAddr == ConnectAddr)
|
if (pNetIO == pNetIO_UDP && IsPuncherAddr(ConnectAddr))
|
||||||
{
|
{
|
||||||
// got an address?
|
// got an address?
|
||||||
if (pOwnAddr)
|
if (pOwnAddr)
|
||||||
|
@ -537,9 +558,12 @@ bool C4Network2IO::OnConn(const C4NetIO::addr_t &PeerAddr, const C4NetIO::addr_t
|
||||||
void C4Network2IO::OnDisconn(const C4NetIO::addr_t &addr, C4NetIO *pNetIO, const char *szReason)
|
void C4Network2IO::OnDisconn(const C4NetIO::addr_t &addr, C4NetIO *pNetIO, const char *szReason)
|
||||||
{
|
{
|
||||||
// punch?
|
// punch?
|
||||||
if (pNetIO == pNetIO_UDP && !PuncherAddr.IsNull() && PuncherAddr == addr)
|
if (pNetIO == pNetIO_UDP && IsPuncherAddr(addr))
|
||||||
{
|
{
|
||||||
PuncherAddr.Clear();
|
if (PuncherAddrIPv4 == addr)
|
||||||
|
PuncherAddrIPv4.Clear();
|
||||||
|
else
|
||||||
|
PuncherAddrIPv6.Clear();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#if(C4NET2IO_DUMP_LEVEL > 1)
|
#if(C4NET2IO_DUMP_LEVEL > 1)
|
||||||
|
@ -579,7 +603,7 @@ void C4Network2IO::OnPacket(const class C4NetIOPacket &rPacket, C4NetIO *pNetIO)
|
||||||
C4TimeMilliseconds::Now().AsString().getData(),
|
C4TimeMilliseconds::Now().AsString().getData(),
|
||||||
rPacket.getStatus(), getNetIOName(pNetIO));
|
rPacket.getStatus(), getNetIOName(pNetIO));
|
||||||
#endif
|
#endif
|
||||||
if (pNetIO == pNetIO_UDP && !PuncherAddr.IsNull() && PuncherAddr == rPacket.getAddr())
|
if (pNetIO == pNetIO_UDP && IsPuncherAddr(rPacket.getAddr()))
|
||||||
{
|
{
|
||||||
HandlePuncherPacket(rPacket);
|
HandlePuncherPacket(rPacket);
|
||||||
return;
|
return;
|
||||||
|
@ -1141,7 +1165,7 @@ void C4Network2IO::HandleFwdReq(const C4PacketFwd &rFwd, C4Network2IOConnection
|
||||||
void C4Network2IO::HandlePuncherPacket(const C4NetIOPacket& rPacket)
|
void C4Network2IO::HandlePuncherPacket(const C4NetIOPacket& rPacket)
|
||||||
{
|
{
|
||||||
auto pkt = C4NetpuncherPacket::Construct(rPacket);
|
auto pkt = C4NetpuncherPacket::Construct(rPacket);
|
||||||
if (pkt && ::Network.HandlePuncherPacket(move(pkt)));
|
if (pkt && ::Network.HandlePuncherPacket(move(pkt), rPacket.getAddr().GetFamily()));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
assert(pNetIO_UDP);
|
assert(pNetIO_UDP);
|
||||||
|
|
|
@ -97,7 +97,8 @@ protected:
|
||||||
iUDPIRate, iUDPORate, iUDPBCRate;
|
iUDPIRate, iUDPORate, iUDPBCRate;
|
||||||
|
|
||||||
// punching
|
// punching
|
||||||
C4NetIO::addr_t PuncherAddr;
|
C4NetIO::addr_t PuncherAddrIPv4, PuncherAddrIPv6;
|
||||||
|
bool IsPuncherAddr(const C4NetIO::addr_t& addr) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -137,7 +138,7 @@ public:
|
||||||
|
|
||||||
// punch
|
// punch
|
||||||
bool InitPuncher(C4NetIO::addr_t PuncherAddr); // by main thread
|
bool InitPuncher(C4NetIO::addr_t PuncherAddr); // by main thread
|
||||||
void SendPuncherPacket(const C4NetpuncherPacket&);
|
void SendPuncherPacket(const C4NetpuncherPacket&, C4NetIO::HostAddress::AddressFamily family);
|
||||||
void Punch(const C4NetIO::addr_t&); // sends a ping packet
|
void Punch(const C4NetIO::addr_t&); // sends a ping packet
|
||||||
|
|
||||||
// stuff
|
// stuff
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
C4Network2Reference::C4Network2Reference()
|
C4Network2Reference::C4Network2Reference()
|
||||||
: Icon(0), GameMode(), Time(0), Frame(0), StartTime(0), LeaguePerformance(0),
|
: Icon(0), GameMode(), Time(0), Frame(0), StartTime(0), LeaguePerformance(0),
|
||||||
JoinAllowed(true), ObservingAllowed(true), PasswordNeeded(false), OfficialServer(false),
|
JoinAllowed(true), ObservingAllowed(true), PasswordNeeded(false), OfficialServer(false),
|
||||||
IsEditor(false), iAddrCnt(0), NetpuncherGameID(0)
|
IsEditor(false), iAddrCnt(0), NetpuncherGameID(C4NetpuncherID())
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -127,7 +127,7 @@ void C4Network2Reference::CompileFunc(StdCompiler *pComp)
|
||||||
pComp->Value(mkNamingAdapt(Game.sEngineName, "Game", "None"));
|
pComp->Value(mkNamingAdapt(Game.sEngineName, "Game", "None"));
|
||||||
pComp->Value(mkNamingAdapt(mkArrayAdaptDM(Game.iVer,0),"Version" ));
|
pComp->Value(mkNamingAdapt(mkArrayAdaptDM(Game.iVer,0),"Version" ));
|
||||||
pComp->Value(mkNamingAdapt(OfficialServer, "OfficialServer", false));
|
pComp->Value(mkNamingAdapt(OfficialServer, "OfficialServer", false));
|
||||||
pComp->Value(mkNamingAdapt(NetpuncherGameID, "NetpuncherID", 0, false, false));
|
pComp->Value(mkNamingAdapt(NetpuncherGameID, "NetpuncherID", C4NetpuncherID(), false, false));
|
||||||
pComp->Value(mkNamingAdapt(NetpuncherAddr, "NetpuncherAddr", "", false, false));
|
pComp->Value(mkNamingAdapt(NetpuncherAddr, "NetpuncherAddr", "", false, false));
|
||||||
|
|
||||||
pComp->Value(Parameters);
|
pComp->Value(Parameters);
|
||||||
|
|
|
@ -51,7 +51,7 @@ private:
|
||||||
bool PasswordNeeded;
|
bool PasswordNeeded;
|
||||||
bool OfficialServer;
|
bool OfficialServer;
|
||||||
bool IsEditor;
|
bool IsEditor;
|
||||||
C4NetpuncherID_t NetpuncherGameID;
|
C4NetpuncherID NetpuncherGameID;
|
||||||
StdCopyStrBuf NetpuncherAddr;
|
StdCopyStrBuf NetpuncherAddr;
|
||||||
|
|
||||||
// Engine information
|
// Engine information
|
||||||
|
@ -79,7 +79,7 @@ public:
|
||||||
int32_t getStartTime() const { return StartTime; }
|
int32_t getStartTime() const { return StartTime; }
|
||||||
StdStrBuf getGameGoalString() const;
|
StdStrBuf getGameGoalString() const;
|
||||||
bool isEditor() const { return IsEditor; }
|
bool isEditor() const { return IsEditor; }
|
||||||
C4NetpuncherID_t getNetpuncherGameID() const { return NetpuncherGameID; }
|
C4NetpuncherID getNetpuncherGameID() const { return NetpuncherGameID; }
|
||||||
StdStrBuf getNetpuncherAddr() const { return NetpuncherAddr; }
|
StdStrBuf getNetpuncherAddr() const { return NetpuncherAddr; }
|
||||||
|
|
||||||
void SetSourceAddress(const C4NetIO::EndpointAddress &ip);
|
void SetSourceAddress(const C4NetIO::EndpointAddress &ip);
|
||||||
|
|
Loading…
Reference in New Issue