OpenClonk
C4PuncherServer Class Referenceabstract
Inheritance diagram for C4PuncherServer:
[legend]
Collaboration diagram for C4PuncherServer:
[legend]

Public Types

typedef C4NetpuncherID::value CID
 
typedef EndpointAddress addr_t
 

Public Member Functions

 C4PuncherServer ()
 
bool Init (uint16_t iPort=addr_t::IPPORT_NONE) override
 
bool InitBroadcast (addr_t *pBroadcastAddr) override
 
bool Close () override
 
bool Close (const addr_t &addr) override
 
bool CloseBroadcast () override
 
bool Execute (int iMaxTime=TO_INF, pollfd *=nullptr) override
 
bool Connect (const addr_t &addr) override
 
bool Send (const C4NetIOPacket &rPacket) override
 
virtual bool Send (const class C4NetIOPacket &rPacket)=0
 
bool SendDirect (C4NetIOPacket &&rPacket)
 
bool Broadcast (const C4NetIOPacket &rPacket) override
 
virtual bool Broadcast (const class C4NetIOPacket &rPacket)=0
 
bool SetBroadcast (const addr_t &addr, bool fSet=true) override
 
C4TimeMilliseconds GetNextTick (C4TimeMilliseconds tNow) override
 
bool GetStatistic (int *pBroadcastRate) override
 
bool GetConnStatistic (const addr_t &addr, int *pIRate, int *pORate, int *pLoss) override
 
void ClearStatistic () override
 
void SetCallback (CBClass *pnCallback) override
 
virtual void SetCallback (CBClass *pnCallback)=0
 
virtual void UnBlock ()
 
void GetFDs (std::vector< struct pollfd > &FDs) override
 
bool IsNotify () override
 
virtual const char * GetError () const
 
void ResetError ()
 
bool ExecuteUntil (int iTimeout=-1)
 
bool IsSignaled ()
 
virtual bool IsLowPriority ()
 
virtual uint32_t TimerInterval ()
 

Static Public Member Functions

static std::vector< HostAddressGetLocalAddresses ()
 

Static Public Attributes

static const int TO_INF = -1
 

Protected Types

enum  IPTypeID {
  IPID_Ping = 0, IPID_Test = 1, IPID_Conn = 2, IPID_ConnOK = 3,
  IPID_AddAddr = 7, IPID_Data = 4, IPID_Check = 5, IPID_Close = 6
}
 

Protected Member Functions

bool BroadcastDirect (const Packet &rPacket, unsigned int iNr=~0u)
 
bool DoLoopbackTest ()
 
void ClearMCPackets ()
 
void AddPeer (Peer *pPeer)
 
PeerGetPeer (const addr_t &addr)
 
PeerConnectPeer (const addr_t &PeerAddr, bool fFailCallback)
 
void OnShareFree (CStdCSecEx *pCSec) override
 
void DoCheck ()
 
const addr_tgetMCAddr () const
 
bool SetMCLoopback (int fLoopback)
 
bool getMCLoopback () const
 
void SetReUseAddress (bool fAllow)
 
bool InitIPv6Socket (SOCKET socket)
 
void SetError (const char *strnError, bool fSockErr=false)
 
void Changed ()
 

Protected Attributes

CStdCSecEx PeerListCSec
 
CStdCSec PeerListAddCSec
 
CStdCSec OutCSec
 
bool fInit {false}
 
bool fMultiCast {false}
 
uint16_t iPort
 
PeerpPeerList {nullptr}
 
bool fSavePacket {false}
 
C4NetIOPacket LastPacket
 
addr_t MCLoopbackAddr
 
bool fDelayedLoopbackTest {false}
 
C4TimeMilliseconds tNextCheck
 
PacketList OPackets
 
unsigned int iOPacketCounter {0}
 
int iBroadcastRate {0}
 
CStdCSec StatCSec
 
CStdCSec ExecuteCSec
 
StdCopyStrBuf Error
 

Static Protected Attributes

static const unsigned int iVersion = 2
 
static const unsigned int iStdTimeout = 1000
 
static const unsigned int iCheckInterval = 1000
 
static const unsigned int iMaxOPacketBacklog = 10000
 
static const unsigned int iUDPHeaderSize = 8 + 24
 

Private Member Functions

virtual bool OnConn (const addr_t &AddrPeer, const addr_t &AddrConnect, const addr_t *pOwnAddr, C4NetIO *pNetIO)
 
virtual void OnDisconn (const addr_t &AddrPeer, C4NetIO *pNetIO, const char *szReason)
 

Detailed Description

Definition at line 25 of file main.cpp.

Member Typedef Documentation

◆ addr_t

typedef EndpointAddress C4NetIO::addr_t
inherited

Definition at line 212 of file C4NetIO.h.

◆ CID

Definition at line 28 of file main.cpp.

Member Enumeration Documentation

◆ IPTypeID

enum C4NetIOUDP::IPTypeID
protectedinherited
Enumerator
IPID_Ping 
IPID_Test 
IPID_Conn 
IPID_ConnOK 
IPID_AddAddr 
IPID_Data 
IPID_Check 
IPID_Close 

Definition at line 634 of file C4NetIO.h.

Constructor & Destructor Documentation

◆ C4PuncherServer()

C4PuncherServer::C4PuncherServer ( )
inline

Definition at line 29 of file main.cpp.

References C4NetIOUDP::Close(), C4NetpuncherPacket::Construct(), C4NetIOPacket::getAddr(), C4NetpuncherPacket::PackTo(), PID_Puncher_IDReq, PID_Puncher_SReq, Puncher, C4NetIOUDP::Send(), and C4NetIOUDP::SetCallback().

29  {
31  rng = std::bind(std::uniform_int_distribution<CID>(1/*, max*/), std::ref(random_device));
32  }
void SetCallback(CBClass *pnCallback) override
Definition: C4NetIO.h:936
Here is the call graph for this function:

Member Function Documentation

◆ AddPeer()

void C4NetIOUDP::AddPeer ( Peer pPeer)
protectedinherited

Definition at line 3756 of file C4NetIO.cpp.

References StdSchedulerProc::Changed(), C4NetIOUDP::Peer::Next, C4NetIOUDP::PeerListAddCSec, C4NetIOUDP::PeerListCSec, and C4NetIOUDP::pPeerList.

Referenced by C4NetIOUDP::ConnectPeer().

3757 {
3758  // get locks
3759  CStdShareLock PeerListLock(&PeerListCSec);
3760  CStdLock PeerListAddLock(&PeerListAddCSec);
3761  // add
3762  pPeer->Next = pPeerList;
3763  pPeerList = pPeer;
3764  Changed();
3765 }
CStdCSecEx PeerListCSec
Definition: C4NetIO.h:871
Peer * pPeerList
Definition: C4NetIO.h:881
CStdCSec PeerListAddCSec
Definition: C4NetIO.h:872
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Broadcast() [1/2]

virtual bool C4NetIO::Broadcast ( const class C4NetIOPacket rPacket)
pure virtualinherited

Referenced by C4NetIO::IsNotify().

Here is the caller graph for this function:

◆ Broadcast() [2/2]

bool C4NetIOUDP::Broadcast ( const C4NetIOPacket rPacket)
overrideinherited

Definition at line 2745 of file C4NetIO.cpp.

References C4NetIOUDP::PacketList::AddPacket(), C4NetIOUDP::BroadcastDirect(), C4NetIOUDP::Peer::doBroadcast(), C4NetIOPacket::Duplicate(), C4NetIOUDP::Packet::FragmentCnt(), C4NetIOUDP::iOPacketCounter, C4NetIOUDP::Peer::MultiCast(), C4NetIOUDP::Peer::Next, C4NetIOUDP::OPackets, C4NetIOUDP::Peer::Open(), C4NetIOUDP::OutCSec, C4NetIOUDP::Packet, C4NetIOUDP::PeerListCSec, C4NetIOUDP::pPeerList, and C4NetIOUDP::Peer::Send().

2746 {
2747  CStdShareLock PeerListLock(&PeerListCSec);
2748  // search: any client reachable via multicast?
2749  Peer *pPeer;
2750  for (pPeer = pPeerList; pPeer; pPeer = pPeer->Next)
2751  if (pPeer->Open() && pPeer->MultiCast() && pPeer->doBroadcast())
2752  break;
2753  bool fSuccess = true;
2754  if (pPeer)
2755  {
2756  CStdLock OutLock(&OutCSec);
2757  // send it via multicast: encapsulate packet
2758  Packet *pPkt = new Packet(rPacket.Duplicate(), iOPacketCounter);
2759  iOPacketCounter += pPkt->FragmentCnt();
2760  // add to list
2761  OPackets.AddPacket(pPkt);
2762  // send it
2763  fSuccess &= BroadcastDirect(*pPkt);
2764  }
2765  // send to all clients connected via du, too
2766  for (pPeer = pPeerList; pPeer; pPeer = pPeer->Next)
2767  if (pPeer->Open() && !pPeer->MultiCast() && pPeer->doBroadcast())
2768  pPeer->Send(rPacket);
2769  return true;
2770 }
CStdCSecEx PeerListCSec
Definition: C4NetIO.h:871
friend class Packet
Definition: C4NetIO.h:705
PacketList OPackets
Definition: C4NetIO.h:895
CStdCSec OutCSec
Definition: C4NetIO.h:873
bool AddPacket(Packet *pPacket)
Definition: C4NetIO.cpp:3094
Peer * pPeerList
Definition: C4NetIO.h:881
unsigned int iOPacketCounter
Definition: C4NetIO.h:896
bool BroadcastDirect(const Packet &rPacket, unsigned int iNr=~0u)
Definition: C4NetIO.cpp:3660
C4NetIOPacket Duplicate() const
Definition: C4NetIO.h:325
friend class Peer
Definition: C4NetIO.h:868
Here is the call graph for this function:

◆ BroadcastDirect()

bool C4NetIOUDP::BroadcastDirect ( const Packet rPacket,
unsigned int  iNr = ~0u 
)
protectedinherited

Definition at line 3660 of file C4NetIO.cpp.

References C4NetIOUDP::Packet::FragmentCnt(), C4NetIOUDP::Packet::GetFragment(), C4NetIOUDP::Packet::GetNr(), and C4NetIOUDP::Peer::SendDirect().

Referenced by C4NetIOUDP::Broadcast(), and C4NetIOUDP::Peer::OnRecv().

3661 {
3662  // only one fragment?
3663  if (iNr + 1)
3664  return SendDirect(rPacket.GetFragment(iNr - rPacket.GetNr(), true));
3665  // send all fragments
3666  bool fSuccess = true;
3667  for (unsigned int iFrgm = 0; iFrgm < rPacket.FragmentCnt(); iFrgm++)
3668  fSuccess &= SendDirect(rPacket.GetFragment(iFrgm, true));
3669  return fSuccess;
3670 }
bool SendDirect(C4NetIOPacket &&rPacket)
Definition: C4NetIO.cpp:3672
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Changed()

void StdSchedulerProc::Changed ( )
protectedinherited

Definition at line 108 of file StdScheduler.cpp.

References s.

Referenced by C4NetIOTCP::Accept(), C4NetIOTCP::AddConnectWait(), C4NetIOUDP::AddPeer(), StdScheduler::IsInManualLoop(), C4NetIOTCP::Listen(), and CStdTimerProc::SetDelay().

109 {
110  auto s = scheduler;
111  if (s)
112  s->Changed(this);
113 }
#define s
Here is the caller graph for this function:

◆ ClearMCPackets()

void C4NetIOUDP::ClearMCPackets ( )
protectedinherited

Definition at line 3738 of file C4NetIO.cpp.

References C4NetIOUDP::PacketList::Clear(), C4NetIOUDP::PacketList::ClearPackets(), C4NetIOUDP::Peer::GetMCAckPacketCounter(), C4NetIOUDP::Peer::Next, C4NetIOUDP::Peer::OPackets, C4NetIOUDP::Peer::OutCSec, C4NetIOUDP::PeerListCSec, and C4NetIOUDP::pPeerList.

Referenced by C4NetIOUDP::Peer::OnRecv().

3739 {
3740  CStdShareLock PeerListLock(&PeerListCSec);
3741  CStdLock OutLock(&OutCSec);
3742  // clear packets if no client is present
3743  if (!pPeerList)
3744  OPackets.Clear();
3745  else
3746  {
3747  // find minimum acknowledged packet number
3748  unsigned int iAckNr = pPeerList->GetMCAckPacketCounter();
3749  for (Peer *pPeer = pPeerList->Next; pPeer; pPeer = pPeer->Next)
3750  iAckNr = std::min(iAckNr, pPeerList->GetMCAckPacketCounter());
3751  // clear packets
3752  OPackets.ClearPackets(iAckNr);
3753  }
3754 }
CStdCSecEx PeerListCSec
Definition: C4NetIO.h:871
PacketList OPackets
Definition: C4NetIO.h:895
unsigned int GetMCAckPacketCounter() const
Definition: C4NetIO.h:823
CStdCSec OutCSec
Definition: C4NetIO.h:873
Peer * pPeerList
Definition: C4NetIO.h:881
void ClearPackets(unsigned int iUntil)
Definition: C4NetIO.cpp:3138
friend class Peer
Definition: C4NetIO.h:868
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ClearStatistic()

void C4NetIOUDP::ClearStatistic ( )
overridevirtualinherited

Reimplemented from C4NetIOSimpleUDP.

Definition at line 2818 of file C4NetIO.cpp.

References C4NetIOUDP::AddAddrPacket::Addr, C4NetIOUDP::Peer::Close(), C4NetIOUDP::ConnectPeer(), StdBuf::Copy(), C4NetIOUDP::fDelayedLoopbackTest, C4NetIOUDP::fMultiCast, C4NetIOUDP::fSavePacket, C4NetIOPacket::getAddr(), C4NetIOUDP::GetPeer(), C4NetIOPacket::getStatus(), C4NetIOUDP::iBroadcastRate, C4NetIOUDP::IPID_AddAddr, C4NetIOUDP::IPID_Conn, C4NetIOUDP::IPID_Ping, C4NetIOUDP::IPID_Test, C4NetIOUDP::LastPacket, C4NetIOUDP::MCLoopbackAddr, C4NetIOUDP::AddAddrPacket::NewAddr, C4NetIOUDP::Peer::Next, C4NetIOUDP::Peer::OnRecv(), C4NetIOUDP::Packet, C4NetIOUDP::PeerListCSec, C4NetIOUDP::pPeerList, C4NetIOUDP::SendDirect(), C4NetIOUDP::Peer::SetAltAddr(), and C4NetIOUDP::StatCSec.

2819 {
2820  CStdShareLock PeerListLock(&PeerListCSec);
2821  // clear all peer statistics
2822  for (Peer *pPeer = pPeerList; pPeer; pPeer = pPeer->Next)
2823  pPeer->ClearStatistics();
2824  // broadcast statistics
2825  CStdLock StatLock(&StatCSec);
2826  iBroadcastRate = 0;
2827 }
CStdCSecEx PeerListCSec
Definition: C4NetIO.h:871
int iBroadcastRate
Definition: C4NetIO.h:899
Peer * pPeerList
Definition: C4NetIO.h:881
CStdCSec StatCSec
Definition: C4NetIO.h:900
friend class Peer
Definition: C4NetIO.h:868
Here is the call graph for this function:

◆ Close() [1/2]

bool C4NetIOUDP::Close ( )
overridevirtualinherited

Reimplemented from C4NetIOSimpleUDP.

Definition at line 2639 of file C4NetIO.cpp.

References CStdShareLock::Clear(), C4NetIOSimpleUDP::Close(), C4NetIOUDP::CloseBroadcast(), C4NetIOUDP::fInit, C4NetIOUDP::fMultiCast, C4NetIOUDP::Peer::Next, C4NetIOUDP::PeerListCSec, and C4NetIOUDP::pPeerList.

Referenced by C4PuncherServer(), C4NetIOUDP::Init(), and C4NetIOUDP::~C4NetIOUDP().

2640 {
2641  // should be initialized
2642  if (!fInit) return false;
2643 
2644  // close all peers
2645  CStdShareLock PeerListLock(&PeerListCSec);
2646  for (Peer *pPeer = pPeerList; pPeer; pPeer = pPeer->Next)
2647  pPeer->Close("owner class closed");
2648  PeerListLock.Clear();
2649 
2650  // deactivate multicast
2651  if (fMultiCast)
2652  CloseBroadcast();
2653 
2654  // close UDP
2655  bool fSuccess = C4NetIOSimpleUDP::Close();
2656 
2657 #ifdef C4NETIO_DEBUG
2658  // close log
2659  CloseDebugLog();
2660 #endif
2661 
2662  // ok
2663  fInit = false;
2664  return fSuccess;
2665 }
CStdCSecEx PeerListCSec
Definition: C4NetIO.h:871
bool Close() override
Definition: C4NetIO.cpp:2041
Peer * pPeerList
Definition: C4NetIO.h:881
bool CloseBroadcast() override
Definition: C4NetIO.cpp:2667
bool fInit
Definition: C4NetIO.h:876
bool fMultiCast
Definition: C4NetIO.h:877
friend class Peer
Definition: C4NetIO.h:868
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Close() [2/2]

bool C4NetIOUDP::Close ( const addr_t addr)
overridevirtualinherited

Reimplemented from C4NetIOSimpleUDP.

Definition at line 2723 of file C4NetIO.cpp.

References C4NetIOUDP::Peer::Close(), C4NetIOUDP::GetPeer(), and C4NetIOUDP::PeerListCSec.

2724 {
2725  CStdShareLock PeerListLock(&PeerListCSec);
2726  // find peer
2727  Peer *pPeer = GetPeer(addr);
2728  if (!pPeer) return false;
2729  // close
2730  pPeer->Close("closed");
2731  return true;
2732 }
CStdCSecEx PeerListCSec
Definition: C4NetIO.h:871
Peer * GetPeer(const addr_t &addr)
Definition: C4NetIO.cpp:3793
friend class Peer
Definition: C4NetIO.h:868
Here is the call graph for this function:

◆ CloseBroadcast()

bool C4NetIOUDP::CloseBroadcast ( )
overridevirtualinherited

Reimplemented from C4NetIOSimpleUDP.

Definition at line 2667 of file C4NetIO.cpp.

References C4NetIOSimpleUDP::CloseBroadcast(), C4NetIOUDP::fMultiCast, and C4NetIO::ResetError().

Referenced by C4NetIOUDP::Close(), and C4NetIOUDP::InitBroadcast().

2668 {
2669  ResetError();
2670 
2671  // multicast not active?
2672  if (!fMultiCast) return true;
2673 
2674  // ok
2675  fMultiCast = false;
2677 }
void ResetError()
Definition: C4NetIO.h:286
bool fMultiCast
Definition: C4NetIO.h:877
virtual bool CloseBroadcast()
Definition: C4NetIO.cpp:2082
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Connect()

bool C4NetIOUDP::Connect ( const addr_t addr)
overridevirtualinherited

Reimplemented from C4NetIOSimpleUDP.

Definition at line 2717 of file C4NetIO.cpp.

References C4NetIOUDP::ConnectPeer().

2718 {
2719  // connect
2720  return !! ConnectPeer(addr, true);
2721 }
Peer * ConnectPeer(const addr_t &PeerAddr, bool fFailCallback)
Definition: C4NetIO.cpp:3803
Here is the call graph for this function:

◆ ConnectPeer()

C4NetIOUDP::Peer * C4NetIOUDP::ConnectPeer ( const addr_t PeerAddr,
bool  fFailCallback 
)
protectedinherited

Definition at line 3803 of file C4NetIO.cpp.

References C4NetIOUDP::AddPeer(), CStdLock::Clear(), C4NetIOUDP::Peer::Close(), C4NetIOUDP::Peer::Connect(), C4NetIOUDP::GetPeer(), C4NetIOUDP::Peer::Peer(), C4NetIOUDP::PeerListAddCSec, and C4NetIOUDP::PeerListCSec.

Referenced by C4NetIOUDP::ClearStatistic(), and C4NetIOUDP::Connect().

3804 {
3805  CStdShareLock PeerListLock(&PeerListCSec);
3806  // lock so no new peer can be added after this point
3807  CStdLock PeerListAddLock(&PeerListAddCSec);
3808  // recheck: address already known?
3809  Peer *pnPeer = GetPeer(PeerAddr);
3810  if (pnPeer) return pnPeer;
3811  // create new Peer class
3812  pnPeer = new Peer(PeerAddr, this);
3813  if (!pnPeer) return nullptr;
3814  // add peer to list
3815  AddPeer(pnPeer);
3816  PeerListAddLock.Clear();
3817  // send connection request
3818  if (!pnPeer->Connect(fFailCallback)) { pnPeer->Close("connect failed"); return nullptr; }
3819  // ok (do not wait for peer)
3820  return pnPeer;
3821 }
CStdCSecEx PeerListCSec
Definition: C4NetIO.h:871
Peer * GetPeer(const addr_t &addr)
Definition: C4NetIO.cpp:3793
void AddPeer(Peer *pPeer)
Definition: C4NetIO.cpp:3756
CStdCSec PeerListAddCSec
Definition: C4NetIO.h:872
friend class Peer
Definition: C4NetIO.h:868
Here is the call graph for this function:
Here is the caller graph for this function:

◆ DoCheck()

void C4NetIOUDP::DoCheck ( )
protectedinherited

Definition at line 3823 of file C4NetIO.cpp.

References _MAX_PATH, StdStrBuf::Append(), StdStrBuf::AppendFormat(), C4NetIOUDP::CheckPacketHdr::AskCount, C4NetIOUDP::Peer::fMultiCast, StdStrBuf::Format(), C4NetIOPacket::getAddr(), StdStrBuf::getData(), StdStrBuf::getLength(), StdBuf::getSize(), C4NetIOUDP::iCheckInterval, C4NetIOUDP::Peer::iOPacketCounter, C4NetIOUDP::IPID_Check, C4NetIOUDP::IPID_Close, C4NetIOUDP::IPID_Conn, C4NetIOUDP::IPID_ConnOK, C4NetIOUDP::IPID_Data, C4NetIOUDP::IPID_Ping, C4NetIOUDP::IPID_Test, C4NetIOUDP::CheckPacketHdr::MCAskCount, C4NetIOUDP::ConnOKPacket::MCM_MC, C4NetIOUDP::ConnOKPacket::MCM_MCOK, C4NetIOUDP::ConnOKPacket::MCM_NoMC, C4NetIOUDP::Peer::MultiCast(), C4NetIOUDP::Peer::Next, C4TimeMilliseconds::Now(), C4NetIOUDP::PacketHdr::Nr, C4NetIOUDP::Peer::Open(), C4NetIOUDP::PeerListCSec, C4NetIOUDP::pPeerList, C4NetIOUDP::Peer::SendDirect(), sprintf, C4NetIOUDP::PacketHdr::StatusByte, C4NetIOUDP::tNextCheck, and C4NetIO::EndpointAddress::ToString().

Referenced by C4NetIOUDP::Execute().

3824 {
3825  CStdShareLock PeerListLock(&PeerListCSec);
3826  // mc connection check?
3827  if (fMultiCast)
3828  {
3829  // only if a peer is connected via multicast
3830  Peer *pPeer;
3831  for (pPeer = pPeerList; pPeer; pPeer = pPeer->Next)
3832  if (pPeer->Open() && pPeer->MultiCast())
3833  break;
3834  if (pPeer)
3835  {
3836  // set up packet
3837  CheckPacketHdr Pkt;
3838  Pkt.StatusByte = uint8_t(IPID_Check | 0x80);
3839  Pkt.Nr = iOPacketCounter;
3840  Pkt.AskCount = Pkt.MCAskCount = 0;
3841  // send it
3842  SendDirect(C4NetIOPacket(&Pkt, sizeof(Pkt)));
3843  }
3844  }
3845  // peer connection checks
3846  for (Peer *pPeer = pPeerList; pPeer; pPeer = pPeer->Next)
3847  if (pPeer->Open())
3848  pPeer->Check();
3849 
3850  // set time for next check
3852 }
CStdCSecEx PeerListCSec
Definition: C4NetIO.h:871
Peer * pPeerList
Definition: C4NetIO.h:881
unsigned int iOPacketCounter
Definition: C4NetIO.h:896
bool fMultiCast
Definition: C4NetIO.h:877
static const unsigned int iCheckInterval
Definition: C4NetIO.h:654
C4TimeMilliseconds tNextCheck
Definition: C4NetIO.h:892
bool SendDirect(C4NetIOPacket &&rPacket)
Definition: C4NetIO.cpp:3672
static C4TimeMilliseconds Now()
friend class Peer
Definition: C4NetIO.h:868
Here is the call graph for this function:
Here is the caller graph for this function:

◆ DoLoopbackTest()

bool C4NetIOUDP::DoLoopbackTest ( )
protectedinherited

Definition at line 3699 of file C4NetIO.cpp.

References C4NetIOSimpleUDP::Broadcast(), StdBuf::Compare(), C4NetIOSimpleUDP::Execute(), C4NetIOUDP::fSavePacket, C4NetIOPacket::getAddr(), C4NetIO::GetError(), C4NetIOSimpleUDP::getMCLoopback(), StdBuf::getSize(), C4NetIOUDP::IPID_Test, C4NetIOUDP::iStdTimeout, C4NetIOUDP::LastPacket, C4NetIOUDP::MCLoopbackAddr, C4NetIO::SetError(), C4NetIOSimpleUDP::SetMCLoopback(), and UnsyncedRandom().

Referenced by C4NetIOUDP::Execute(), and C4NetIOUDP::InitBroadcast().

3700 {
3701  // (try to) enable loopback
3703  // ensure loopback is activate
3704  if (!C4NetIOSimpleUDP::getMCLoopback()) return false;
3705 
3706  // send test packet
3707  const PacketHdr TestPacket = { uint8_t(IPID_Test | 0x80), UnsyncedRandom(UINT32_MAX) };
3708  if (!C4NetIOSimpleUDP::Broadcast(C4NetIOPacket(&TestPacket, sizeof(TestPacket))))
3709  return false;
3710 
3711  // wait for socket to become readable (should happen immediatly, do not expect packet loss)
3712  fSavePacket = true;
3714  {
3715  fSavePacket = false;
3716  if (!GetError()) SetError("Multicast disabled: loopback test failed");
3717  return false;
3718  }
3719  fSavePacket = false;
3720 
3721  // compare it to the packet that was sent
3722  if (LastPacket.getSize() != sizeof(TestPacket) ||
3723  LastPacket.Compare(&TestPacket, sizeof(TestPacket)))
3724  {
3725  SetError("Multicast disabled: loopback test failed");
3726  return false;
3727  }
3728 
3729  // save the loopback addr back
3731 
3732  // disable loopback
3734  // ok
3735  return true;
3736 }
bool SetMCLoopback(int fLoopback)
Definition: C4NetIO.cpp:2290
uint32_t UnsyncedRandom()
Definition: C4Random.cpp:58
void SetError(const char *strnError, bool fSockErr=false)
Definition: C4NetIO.cpp:750
bool fSavePacket
Definition: C4NetIO.h:884
bool Execute(int iMaxTime=TO_INF, pollfd *=nullptr) override
Definition: C4NetIO.cpp:2100
C4NetIOPacket LastPacket
Definition: C4NetIO.h:885
size_t getSize() const
Definition: StdBuf.h:101
bool Broadcast(const C4NetIOPacket &rPacket) override
Definition: C4NetIO.cpp:2200
addr_t MCLoopbackAddr
Definition: C4NetIO.h:888
int Compare(const void *pCData, size_t iCSize, size_t iAt=0) const
Definition: StdBuf.h:165
virtual const char * GetError() const
Definition: C4NetIO.h:285
static const unsigned int iStdTimeout
Definition: C4NetIO.h:654
bool getMCLoopback() const
Definition: C4NetIO.h:576
const C4NetIO::addr_t & getAddr() const
Definition: C4NetIO.h:316
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Execute()

bool C4NetIOUDP::Execute ( int  iMaxTime = TO_INF,
pollfd *  = nullptr 
)
overridevirtualinherited

Reimplemented from C4NetIOSimpleUDP.

Definition at line 2679 of file C4NetIO.cpp.

References C4NetIOUDP::DoCheck(), C4NetIOUDP::DoLoopbackTest(), C4NetIOSimpleUDP::Execute(), C4NetIOUDP::ExecuteCSec, C4NetIOUDP::fDelayedLoopbackTest, C4NetIOUDP::fInit, C4NetIOUDP::fMultiCast, C4NetIOUDP::GetNextTick(), C4NetIOUDP::Peer::Next, C4TimeMilliseconds::Now(), C4NetIOUDP::PeerListCSec, C4NetIOUDP::pPeerList, C4NetIO::ResetError(), C4NetIO::SetError(), C4NetIOUDP::tNextCheck, and C4NetIO::TO_INF.

2680 {
2681  if (!fInit) { SetError("not yet initialized"); return false; }
2682 
2683  CStdLock ExecuteLock(&ExecuteCSec);
2684  CStdShareLock PeerListLock(&PeerListCSec);
2685 
2686  ResetError();
2687 
2688  // adjust maximum block time
2690  uint32_t iMaxBlock = std::max(tNow, GetNextTick(tNow)) - tNow;
2691  if (iMaxTime == TO_INF || iMaxTime > (int) iMaxBlock) iMaxTime = iMaxBlock;
2692 
2693  // execute subclass
2694  if (!C4NetIOSimpleUDP::Execute(iMaxTime))
2695  return false;
2696 
2697  // connection check needed?
2699  DoCheck();
2700  // client timeout?
2701  for (Peer *pPeer = pPeerList; pPeer; pPeer = pPeer->Next)
2702  if (!pPeer->Closed())
2703  pPeer->CheckTimeout();
2704 
2705  // do a delayed loopback test once the incoming buffer is empty
2707  {
2708  if (fMultiCast)
2710  fDelayedLoopbackTest = false;
2711  }
2712 
2713  // ok
2714  return true;
2715 }
void ResetError()
Definition: C4NetIO.h:286
C4TimeMilliseconds GetNextTick(C4TimeMilliseconds tNow) override
Definition: C4NetIO.cpp:2783
bool DoLoopbackTest()
Definition: C4NetIO.cpp:3699
CStdCSecEx PeerListCSec
Definition: C4NetIO.h:871
void SetError(const char *strnError, bool fSockErr=false)
Definition: C4NetIO.cpp:750
Peer * pPeerList
Definition: C4NetIO.h:881
bool Execute(int iMaxTime=TO_INF, pollfd *=nullptr) override
Definition: C4NetIO.cpp:2100
bool fDelayedLoopbackTest
Definition: C4NetIO.h:889
bool fInit
Definition: C4NetIO.h:876
bool fMultiCast
Definition: C4NetIO.h:877
static const int TO_INF
Definition: C4NetIO.h:66
void DoCheck()
Definition: C4NetIO.cpp:3823
C4TimeMilliseconds tNextCheck
Definition: C4NetIO.h:892
CStdCSec ExecuteCSec
Definition: C4NetIO.h:924
static C4TimeMilliseconds Now()
friend class Peer
Definition: C4NetIO.h:868
Here is the call graph for this function:

◆ ExecuteUntil()

bool StdSchedulerProc::ExecuteUntil ( int  iTimeout = -1)
inherited

Definition at line 33 of file StdScheduler.cpp.

References StdSchedulerProc::Execute(), and C4TimeMilliseconds::Now().

Referenced by main().

34 {
35  // Infinite?
36  if (iTimeout < 0)
37  for (;;)
38  if (!Execute())
39  return false;
40  // Calculate endpoint
41  C4TimeMilliseconds tStopTime = C4TimeMilliseconds::Now() + iTimeout;
42  for (;;)
43  {
44  // Call execute with given timeout
45  if (!Execute(std::max(iTimeout, 0)))
46  return false;
47  // Calculate timeout
49  if (tTime >= tStopTime)
50  break;
51  iTimeout = tStopTime - tTime;
52  }
53  // All ok.
54  return true;
55 }
virtual bool Execute(int iTimeout=-1, pollfd *readyfds=nullptr)=0
static C4TimeMilliseconds Now()
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetConnStatistic()

bool C4NetIOUDP::GetConnStatistic ( const addr_t addr,
int *  pIRate,
int *  pORate,
int *  pLoss 
)
overridevirtualinherited

Reimplemented from C4NetIOSimpleUDP.

Definition at line 2805 of file C4NetIO.cpp.

References C4NetIOUDP::Peer::GetIRate(), C4NetIOUDP::Peer::GetORate(), C4NetIOUDP::GetPeer(), C4NetIOUDP::Peer::Open(), and C4NetIOUDP::PeerListCSec.

2806 {
2807  CStdShareLock PeerListLock(&PeerListCSec);
2808  // find peer
2809  Peer *pPeer = GetPeer(addr);
2810  if (!pPeer || !pPeer->Open()) return false;
2811  // return statistics
2812  if (pIRate) *pIRate = pPeer->GetIRate();
2813  if (pORate) *pORate = pPeer->GetORate();
2814  if (pLoss) *pLoss = 0;
2815  return true;
2816 }
CStdCSecEx PeerListCSec
Definition: C4NetIO.h:871
Peer * GetPeer(const addr_t &addr)
Definition: C4NetIO.cpp:3793
friend class Peer
Definition: C4NetIO.h:868
Here is the call graph for this function:

◆ GetError()

virtual const char* C4NetIO::GetError ( ) const
inlinevirtualinherited

Definition at line 285 of file C4NetIO.h.

References StdStrBuf::getData().

Referenced by C4Network2IO::ConnectWithSocket(), C4NetIOUDP::DoLoopbackTest(), C4StartupNetDlg::DoRefresh(), C4DownloadDlg::GetError(), C4Network2IO::Init(), C4NetIOUDP::InitBroadcast(), C4Network2::InitLeague(), C4Game::InitNetworkFromAddress(), C4Network2::LeagueEnd(), C4Network2::LeaguePlrAuthCheck(), C4Network2::LeagueStart(), C4Network2::LeagueUpdate(), C4Network2::LeagueUpdateProcessReply(), main(), MyCBClass::OnConn(), C4ChatControl::OnConnectBtn(), MyCBClass::OnPacket(), C4StartupNetListEntry::OnReference(), C4ChatControl::ProcessInput(), C4Network2IOConnection::Send(), and C4StartupNetListEntry::SetRefQuery().

285 { return Error.getData(); }
StdCopyStrBuf Error
Definition: C4NetIO.h:282
const char * getData() const
Definition: StdBuf.h:442
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetFDs()

void C4NetIOSimpleUDP::GetFDs ( std::vector< struct pollfd > &  FDs)
overridevirtualinherited

Reimplemented from StdSchedulerProc.

Definition at line 2252 of file C4NetIO.cpp.

References INVALID_SOCKET, and C4NetIO::SetError().

2253 {
2254  // add pipe
2255  pollfd pfd = { Pipe[0], POLLIN, 0 };
2256  fds.push_back(pfd);
2257  // add socket
2258  if (sock != INVALID_SOCKET)
2259  {
2260  pollfd pfd = { sock, POLLIN, 0 };
2261  fds.push_back(pfd);
2262  }
2263 }
#define INVALID_SOCKET
Definition: C4NetIO.h:36
Here is the call graph for this function:

◆ GetLocalAddresses()

std::vector< C4NetIO::HostAddress > C4NetIO::GetLocalAddresses ( )
staticinherited

Definition at line 631 of file C4NetIO.cpp.

References C4NetIO::HostAddress::IsLoopback(), and C4NetIO::HostAddress::SetHost().

Referenced by C4Network2Client::AddLocalAddrs(), and C4NetIOUDP::InitBroadcast().

632 {
633  std::vector<HostAddress> result;
634 
635 #ifdef HAVE_WINSOCK
636  HostAddress addr;
637  const size_t BUFFER_SIZE = 16000;
638  PIP_ADAPTER_ADDRESSES addresses = nullptr;
639  for (int i = 0; i < 3; ++i)
640  {
641  addresses = (PIP_ADAPTER_ADDRESSES) realloc(addresses, BUFFER_SIZE * (i+1));
642  if (!addresses)
643  // allocation failed
644  return result;
645  ULONG bufsz = BUFFER_SIZE * (i+1);
646  DWORD rv = GetAdaptersAddresses(AF_UNSPEC,
647  GAA_FLAG_SKIP_ANYCAST|GAA_FLAG_SKIP_MULTICAST|GAA_FLAG_SKIP_DNS_SERVER|GAA_FLAG_SKIP_FRIENDLY_NAME,
648  nullptr, addresses, &bufsz);
649  if (rv == ERROR_BUFFER_OVERFLOW)
650  // too little space, try again
651  continue;
652  if (rv != NO_ERROR)
653  {
654  // Something else happened
655  free(addresses);
656  return result;
657  }
658  // All okay, add addresses
659  for (PIP_ADAPTER_ADDRESSES address = addresses; address; address = address->Next)
660  {
661  for (PIP_ADAPTER_UNICAST_ADDRESS unicast = address->FirstUnicastAddress; unicast; unicast = unicast->Next)
662  {
663  addr.SetHost(unicast->Address.lpSockaddr);
664  if (addr.IsLoopback())
665  continue;
666  result.push_back(addr);
667  }
668  }
669  }
670  free(addresses);
671 #else
672  bool have_ipv6 = false;
673 
674 #ifdef __linux__
675  // Get IPv6 addresses on Linux from procfs which allows filtering deprecated privacy addresses.
676  FILE *f = fopen("/proc/net/if_inet6", "r");
677  if (f)
678  {
679  sockaddr_in6 sa6 = sockaddr_in6();
680  sa6.sin6_family = AF_INET6;
681  auto a6 = sa6.sin6_addr.s6_addr;
682  uint8_t if_idx, plen, scope, flags;
683  char devname[20];
684  while (fscanf(f, "%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx %02hhx %02hhx %02hhx %02hhx %20s\n",
685  &a6[0], &a6[1], &a6[2], &a6[3], &a6[4], &a6[5], &a6[6], &a6[7],
686  &a6[8], &a6[9], &a6[10], &a6[11], &a6[12], &a6[13], &a6[14], &a6[15],
687  &if_idx, &plen, &scope, &flags, devname) != EOF)
688  {
689  // Skip loopback and deprecated addresses.
690  if (scope == IPV6_ADDR_LOOPBACK || flags & IFA_F_DEPRECATED)
691  continue;
692  sa6.sin6_scope_id = scope == IPV6_ADDR_LINKLOCAL ? if_idx : 0;
693  result.emplace_back((sockaddr*) &sa6);
694  }
695  have_ipv6 = result.size() > 0;
696  fclose(f);
697  }
698 #endif
699 
700  struct ifaddrs* addrs;
701  if (getifaddrs(&addrs) < 0)
702  return result;
703  for (struct ifaddrs* ifaddr = addrs; ifaddr != nullptr; ifaddr = ifaddr->ifa_next)
704  {
705  struct sockaddr* ad = ifaddr->ifa_addr;
706  if (ad == nullptr) continue;
707 
708  if ((ad->sa_family == AF_INET || (!have_ipv6 && ad->sa_family == AF_INET6)) && (~ifaddr->ifa_flags & IFF_LOOPBACK)) // Choose only non-loopback IPv4/6 devices
709  {
710  result.emplace_back(ad);
711  }
712  }
713  freeifaddrs(addrs);
714 #endif
715 
716  return result;
717 }
uint32_t DWORD
Here is the call graph for this function:
Here is the caller graph for this function:

◆ getMCAddr()

const addr_t& C4NetIOSimpleUDP::getMCAddr ( ) const
inlineprotectedinherited

Definition at line 572 of file C4NetIO.h.

Referenced by C4NetIOUDP::SendDirect().

572 { return MCAddr; }
Here is the caller graph for this function:

◆ getMCLoopback()

bool C4NetIOSimpleUDP::getMCLoopback ( ) const
inlineprotectedinherited

Definition at line 576 of file C4NetIO.h.

Referenced by C4NetIOUDP::DoLoopbackTest(), and C4NetIOUDP::InitBroadcast().

576 { return fMCLoopback; }
Here is the caller graph for this function:

◆ GetNextTick()

C4TimeMilliseconds C4NetIOUDP::GetNextTick ( C4TimeMilliseconds  tNow)
overridevirtualinherited

Reimplemented from StdSchedulerProc.

Definition at line 2783 of file C4NetIO.cpp.

References C4TimeMilliseconds::IsInfinite(), C4NetIOUDP::Peer::Next, C4NetIOUDP::PeerListCSec, C4NetIOUDP::pPeerList, and C4NetIOUDP::tNextCheck.

Referenced by C4NetIOUDP::Execute().

2784 {
2785  // maximum time: check interval
2786  C4TimeMilliseconds tTiming = tNextCheck.IsInfinite() ? tNow : std::max(tNow, tNextCheck);
2787 
2788  // client timeouts (e.g. connection timeout)
2789  CStdShareLock PeerListLock(&PeerListCSec);
2790  for (Peer *pPeer = pPeerList; pPeer; pPeer = pPeer->Next)
2791  if (!pPeer->Closed())
2792  if (!pPeer->GetTimeout().IsInfinite())
2793  tTiming = std::min(tTiming, pPeer->GetTimeout());
2794  // return timing value
2795  return tTiming;
2796 }
CStdCSecEx PeerListCSec
Definition: C4NetIO.h:871
Peer * pPeerList
Definition: C4NetIO.h:881
C4TimeMilliseconds tNextCheck
Definition: C4NetIO.h:892
friend class Peer
Definition: C4NetIO.h:868
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetPeer()

C4NetIOUDP::Peer * C4NetIOUDP::GetPeer ( const addr_t addr)
protectedinherited

Definition at line 3793 of file C4NetIO.cpp.

References C4NetIOUDP::Peer::addr, C4NetIOUDP::Peer::Next, C4NetIOUDP::PeerListCSec, and C4NetIOUDP::pPeerList.

Referenced by C4NetIOUDP::ClearStatistic(), C4NetIOUDP::Close(), C4NetIOUDP::ConnectPeer(), C4NetIOUDP::GetConnStatistic(), C4NetIOUDP::Send(), and C4NetIOUDP::SetBroadcast().

3794 {
3795  CStdShareLock PeerListLock(&PeerListCSec);
3796  for (Peer *pPeer = pPeerList; pPeer; pPeer = pPeer->Next)
3797  if (!pPeer->Closed())
3798  if (pPeer->GetAddr() == addr || pPeer->GetAltAddr() == addr)
3799  return pPeer;
3800  return nullptr;
3801 }
CStdCSecEx PeerListCSec
Definition: C4NetIO.h:871
Peer * pPeerList
Definition: C4NetIO.h:881
friend class Peer
Definition: C4NetIO.h:868
Here is the caller graph for this function:

◆ GetStatistic()

bool C4NetIOUDP::GetStatistic ( int *  pBroadcastRate)
overridevirtualinherited

Reimplemented from C4NetIOSimpleUDP.

Definition at line 2798 of file C4NetIO.cpp.

References C4NetIOUDP::iBroadcastRate, and C4NetIOUDP::StatCSec.

2799 {
2800  CStdLock StatLock(&StatCSec);
2801  if (pBroadcastRate) *pBroadcastRate = iBroadcastRate;
2802  return true;
2803 }
int iBroadcastRate
Definition: C4NetIO.h:899
CStdCSec StatCSec
Definition: C4NetIO.h:900

◆ Init()

bool C4NetIOUDP::Init ( uint16_t  iPort = addr_t::IPPORT_NONE)
overridevirtualinherited

Reimplemented from C4NetIOSimpleUDP.

Definition at line 2472 of file C4NetIO.cpp.

References C4NetIOUDP::Close(), C4NetIOUDP::fInit, C4NetIOUDP::fMultiCast, C4NetIOUDP::iCheckInterval, C4NetIOSimpleUDP::Init(), C4NetIOUDP::iPort, C4TimeMilliseconds::Now(), C4NetIOSimpleUDP::SetCallback(), and C4NetIOUDP::tNextCheck.

Referenced by main().

2473 {
2474  // already initialized? close first
2475  if (fInit) Close();
2476 
2477 #ifdef C4NETIO_DEBUG
2478  // open log
2479  OpenDebugLog();
2480 #endif
2481 
2482  // Initialize UDP
2483  if (!C4NetIOSimpleUDP::Init(inPort))
2484  return false;
2485  iPort = inPort;
2486 
2487  // set callback
2488  C4NetIOSimpleUDP::SetCallback(CBProxy(this));
2489 
2490  // set flags
2491  fInit = true;
2492  fMultiCast = false;
2493 
2495 
2496  // ok, that's all for now.
2497  // call InitBroadcast for more initialization fun
2498  return true;
2499 }
void SetCallback(CBClass *pnCallback) override
Definition: C4NetIO.h:589
bool Close() override
Definition: C4NetIO.cpp:2639
uint16_t iPort
Definition: C4NetIO.h:878
bool fInit
Definition: C4NetIO.h:876
bool fMultiCast
Definition: C4NetIO.h:877
bool Init(uint16_t iPort=addr_t::IPPORT_NONE) override
Definition: C4NetIO.cpp:1898
static const unsigned int iCheckInterval
Definition: C4NetIO.h:654
C4TimeMilliseconds tNextCheck
Definition: C4NetIO.h:892
static C4TimeMilliseconds Now()
Here is the call graph for this function:
Here is the caller graph for this function:

◆ InitBroadcast()

bool C4NetIOUDP::InitBroadcast ( addr_t pBroadcastAddr)
overridevirtualinherited

Reimplemented from C4NetIOSimpleUDP.

Definition at line 2501 of file C4NetIO.cpp.

References C4NetIOSimpleUDP::Broadcast(), C4NetIOPacket::Clear(), C4NetIOSimpleUDP::CloseBroadcast(), C4NetIOUDP::CloseBroadcast(), C4NetIOUDP::DoLoopbackTest(), C4NetIOSimpleUDP::Execute(), C4NetIOUDP::fDelayedLoopbackTest, C4NetIOUDP::fInit, C4NetIOUDP::fMultiCast, C4NetIOUDP::fSavePacket, C4NetIOPacket::getAddr(), C4NetIO::GetError(), C4NetIO::GetLocalAddresses(), C4NetIOSimpleUDP::getMCLoopback(), C4NetIO::EndpointAddress::GetPort(), C4NetIOUDP::iBroadcastRate, C4NetIOSimpleUDP::InitBroadcast(), C4NetIOUDP::iOPacketCounter, C4NetIOUDP::IPID_Ping, C4NetIOUDP::iPort, C4NetIO::HostAddress::IPv6, C4NetIO::HostAddress::IsMulticast(), StdBuf::isNull(), C4NetIO::EndpointAddress::IsNull(), C4NetIOUDP::iStdTimeout, C4NetIOUDP::LastPacket, C4NetIOUDP::MCLoopbackAddr, C4NetIO::ResetError(), C4NetIO::EndpointAddress::SetAddress(), C4NetIO::SetError(), C4NetIOSimpleUDP::SetMCLoopback(), C4NetIO::EndpointAddress::SetPort(), and UnsyncedRandom().

Referenced by C4NetIOUDP::Peer::OnRecv().

2502 {
2503  // no error... yet
2504  ResetError();
2505 
2506  // security
2507  if (!pBroadcastAddr) return false;
2508 
2509  // Init() has to be called first
2510  if (!fInit) return false;
2511  // already activated?
2512  if (fMultiCast) CloseBroadcast();
2513 
2514  // set up multicast group information
2515  C4NetIO::addr_t MCAddr = *pBroadcastAddr;
2516 
2517  // broadcast addr valid?
2518  if (!MCAddr.IsMulticast())
2519  {
2520  // port is needed in order to search a mc address automatically
2521  if (!iPort)
2522  {
2523  SetError("broadcast address is not valid");
2524  return false;
2525  }
2526  // Set up address as unicast-prefix-based IPv6 multicast address (RFC 3306).
2527  sockaddr_in6 saddrgen = sockaddr_in6();
2528  saddrgen.sin6_family = AF_INET6;
2529  uint8_t *addrgen = saddrgen.sin6_addr.s6_addr;
2530  // ff3e ("global multicast based on network prefix") : 64 (length of network prefix)
2531  static const uint8_t mcast_prefix[4] = { 0xff, 0x3e, 0, 64};
2532  memcpy(addrgen, mcast_prefix, sizeof(mcast_prefix));
2533  addrgen += sizeof(mcast_prefix);
2534  // 64 bit network prefix
2535  addr_t prefixAddr;
2536  for (auto& addr : GetLocalAddresses())
2537  if (addr.GetFamily() == HostAddress::IPv6 && !addr.IsLocal())
2538  {
2539  prefixAddr.SetAddress(addr);
2540  break;
2541  }
2542  if (prefixAddr.IsNull())
2543  {
2544  SetError("no IPv6 unicast address available");
2545  return false;
2546  }
2547  static const size_t network_prefix_size = 8;
2548  memcpy(addrgen, &static_cast<sockaddr_in6*>(&prefixAddr)->sin6_addr, network_prefix_size);
2549  addrgen += network_prefix_size;
2550  // 32 bit group id: search for a free one
2551  for (int iRetries = 1000; iRetries; iRetries--)
2552  {
2553  uint32_t rnd = UnsyncedRandom();
2554  memcpy(addrgen, &rnd, sizeof(rnd));
2555  // "high-order bit of the Group ID will be the same value as the T flag"
2556  addrgen[0] |= 0x80;
2557  // create new - random - address
2558  MCAddr.SetAddress((sockaddr*) &saddrgen);
2559  MCAddr.SetPort(iPort);
2560  // init broadcast
2561  if (!C4NetIOSimpleUDP::InitBroadcast(&MCAddr))
2562  return false;
2563  // do the loopback test
2564  if (!DoLoopbackTest())
2565  {
2567  if (!GetError()) SetError("multicast loopback test failed");
2568  return false;
2569  }
2570  // send a ping packet
2571  const PacketHdr PingPacket = { IPID_Ping | static_cast<uint8_t>(0x80u), 0 };
2572  if (!C4NetIOSimpleUDP::Broadcast(C4NetIOPacket(&PingPacket, sizeof(PingPacket))))
2573  {
2575  return false;
2576  }
2577  bool fSuccess = false;
2578  for (;;)
2579  {
2580  fSavePacket = true; LastPacket.Clear();
2581  // wait for something to happen
2583  {
2584  fSavePacket = false;
2586  return false;
2587  }
2588  fSavePacket = false;
2589  // Timeout? So expect this address to be unused
2590  if (LastPacket.isNull()) { fSuccess = true; break; }
2591  // looped back?
2593  // ignore this one
2594  continue;
2595  // otherwise: there must be someone else in this MC group
2597  break;
2598  }
2599  if (fSuccess) break;
2600  // no success? try again...
2601  }
2602 
2603  // return found address
2604  *pBroadcastAddr = MCAddr;
2605  }
2606  else
2607  {
2608  // check: must be same port
2609  if (MCAddr.GetPort() == iPort)
2610  {
2611  SetError("invalid multicast address: wrong port");
2612  return false;
2613  }
2614  // init
2615  if (!C4NetIOSimpleUDP::InitBroadcast(&MCAddr))
2616  return false;
2617  // do loopback test (if not delayed)
2618  if (!fDelayedLoopbackTest)
2619  if (!DoLoopbackTest())
2620  {
2622  if (!GetError()) SetError("multicast loopback test failed");
2623  return false;
2624  }
2625  }
2626 
2627  // (try to) disable multicast loopback
2629 
2630  // set flags
2631  fMultiCast = true;
2632  iOPacketCounter = 0;
2633  iBroadcastRate = 0;
2634 
2635  // ok
2636  return true;
2637 }
void ResetError()
Definition: C4NetIO.h:286
bool DoLoopbackTest()
Definition: C4NetIO.cpp:3699
bool SetMCLoopback(int fLoopback)
Definition: C4NetIO.cpp:2290
virtual bool InitBroadcast(addr_t *pBroadcastAddr)
Definition: C4NetIO.cpp:1986
uint32_t UnsyncedRandom()
Definition: C4Random.cpp:58
bool IsMulticast() const
Definition: C4NetIO.cpp:242
void SetError(const char *strnError, bool fSockErr=false)
Definition: C4NetIO.cpp:750
int iBroadcastRate
Definition: C4NetIO.h:899
bool fSavePacket
Definition: C4NetIO.h:884
void SetAddress(const sockaddr *addr)
Definition: C4NetIO.cpp:364
bool Execute(int iMaxTime=TO_INF, pollfd *=nullptr) override
Definition: C4NetIO.cpp:2100
C4NetIOPacket LastPacket
Definition: C4NetIO.h:885
bool CloseBroadcast() override
Definition: C4NetIO.cpp:2667
static std::vector< HostAddress > GetLocalAddresses()
Definition: C4NetIO.cpp:631
bool fDelayedLoopbackTest
Definition: C4NetIO.h:889
uint16_t iPort
Definition: C4NetIO.h:878
bool isNull() const
Definition: StdBuf.h:98
void SetPort(uint16_t port)
Definition: C4NetIO.cpp:531
bool Broadcast(const C4NetIOPacket &rPacket) override
Definition: C4NetIO.cpp:2200
addr_t MCLoopbackAddr
Definition: C4NetIO.h:888
unsigned int iOPacketCounter
Definition: C4NetIO.h:896
bool fInit
Definition: C4NetIO.h:876
EndpointAddress addr_t
Definition: C4NetIO.h:212
bool fMultiCast
Definition: C4NetIO.h:877
virtual bool CloseBroadcast()
Definition: C4NetIO.cpp:2082
virtual const char * GetError() const
Definition: C4NetIO.h:285
uint16_t GetPort() const
Definition: C4NetIO.cpp:547
void Clear()
Definition: C4NetIO.cpp:789
static const unsigned int iStdTimeout
Definition: C4NetIO.h:654
bool getMCLoopback() const
Definition: C4NetIO.h:576
const C4NetIO::addr_t & getAddr() const
Definition: C4NetIO.h:316
Here is the call graph for this function:
Here is the caller graph for this function:

◆ InitIPv6Socket()

bool C4NetIO::InitIPv6Socket ( SOCKET  socket)
protectedinherited

Definition at line 730 of file C4NetIO.cpp.

References C4NetIO::SetError(), and SOCKET_ERROR.

Referenced by C4NetIOTCP::CreateSocket(), C4NetIOSimpleUDP::Init(), C4NetIO::IsNotify(), and C4NetIOTCP::Listen().

731 {
732  int opt = 0;
733  if (setsockopt(socket, IPPROTO_IPV6, IPV6_V6ONLY, reinterpret_cast<char*>(&opt), sizeof(opt)) == SOCKET_ERROR)
734  {
735  SetError("could not enable dual-stack socket", true);
736  return false;
737  }
738 
739 #ifdef IPV6_ADDR_PREFERENCES
740  // Prefer stable addresses. This should prevent issues with address
741  // deprecation while a match is running. No error handling - if the call
742  // fails, we just take any address.
743  opt = IPV6_PREFER_SRC_PUBLIC;
744  setsockopt(socket, IPPROTO_IPV6, IPV6_ADDR_PREFERENCES, reinterpret_cast<char*>(&opt), sizeof(opt));
745 #endif
746 
747  return true;
748 }
void SetError(const char *strnError, bool fSockErr=false)
Definition: C4NetIO.cpp:750
#define SOCKET_ERROR
Definition: C4NetIO.cpp:47
Here is the call graph for this function:
Here is the caller graph for this function:

◆ IsLowPriority()

virtual bool StdSchedulerProc::IsLowPriority ( )
inlinevirtualinherited

Definition at line 82 of file StdScheduler.h.

82 { return false; }

◆ IsNotify()

bool C4NetIO::IsNotify ( )
inlineoverridevirtualinherited

Reimplemented from StdSchedulerProc.

Definition at line 259 of file C4NetIO.h.

References C4NetIO::Broadcast(), C4NetIO::ClearStatistic(), C4NetIO::Close(), C4NetIO::Connect(), C4NetIO::GetConnStatistic(), C4NetIO::GetStatistic(), C4NetIO::InitIPv6Socket(), C4NetIO::Send(), C4NetIO::SetBroadcast(), and SOCKET.

259 { return true; }
Here is the call graph for this function:

◆ IsSignaled()

bool StdSchedulerProc::IsSignaled ( )
inherited

Referenced by StdSchedulerProc::GetFDs().

Here is the caller graph for this function:

◆ OnShareFree()

void C4NetIOUDP::OnShareFree ( CStdCSecEx pCSec)
overrideprotectedvirtualinherited

Implements CStdCSecExCallback.

Definition at line 3767 of file C4NetIO.cpp.

References C4NetIOUDP::Peer::Closed(), C4NetIOUDP::Peer::Next, C4NetIOUDP::PeerListCSec, and C4NetIOUDP::pPeerList.

3768 {
3769  if (pCSec == &PeerListCSec)
3770  {
3771  Peer *pPeer = pPeerList, *pLast = nullptr;
3772  while (pPeer)
3773  {
3774  // delete?
3775  if (pPeer->Closed())
3776  {
3777  // unlink
3778  Peer *pDelete = pPeer;
3779  (pLast ? pLast->Next : pPeerList) = pPeer = pPeer->Next;
3780  // delete
3781  delete pDelete;
3782  }
3783  else
3784  {
3785  // next peer
3786  pLast = pPeer;
3787  pPeer = pPeer->Next;
3788  }
3789  }
3790  }
3791 }
CStdCSecEx PeerListCSec
Definition: C4NetIO.h:871
Peer * pPeerList
Definition: C4NetIO.h:881
friend class Peer
Definition: C4NetIO.h:868
Here is the call graph for this function:

◆ ResetError()

void C4NetIO::ResetError ( )
inlineinherited

Definition at line 286 of file C4NetIO.h.

References StdStrBuf::Clear(), and C4NetIO::SetCallback().

Referenced by C4NetIO::C4NetIO(), C4NetIOTCP::Close(), C4NetIOSimpleUDP::Close(), C4NetIOUDP::CloseBroadcast(), C4Network2IO::ConnectWithSocket(), C4NetIOSimpleUDP::Execute(), C4NetIOUDP::Execute(), C4NetIOSimpleUDP::Init(), C4NetIOSimpleUDP::InitBroadcast(), C4NetIOUDP::InitBroadcast(), C4Network2IOConnection::Send(), and C4NetIOSimpleUDP::Send().

286 { Error.Clear(); }
void Clear()
Definition: StdBuf.h:466
StdCopyStrBuf Error
Definition: C4NetIO.h:282
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Send() [1/2]

virtual bool C4NetIO::Send ( const class C4NetIOPacket rPacket)
pure virtualinherited

Referenced by C4NetIOUDP::Peer::GetAltAddr(), C4NetIOTCP::Peer::GetORate(), C4NetIO::IsNotify(), main(), MyCBClass::OnConn(), MyCBClass::OnPacket(), C4Network2IOConnection::Send(), and C4Network2IO::SendPuncherPacket().

Here is the caller graph for this function:

◆ Send() [2/2]

bool C4NetIOUDP::Send ( const C4NetIOPacket rPacket)
overrideinherited

Definition at line 2734 of file C4NetIO.cpp.

References C4NetIOPacket::getAddr(), C4NetIOUDP::GetPeer(), C4NetIOUDP::PeerListCSec, and C4NetIOUDP::Peer::Send().

Referenced by C4PuncherServer().

2735 {
2736  // find Peer class for given address
2737  CStdShareLock PeerListLock(&PeerListCSec);
2738  Peer *pPeer = GetPeer(rPacket.getAddr());
2739  // not found?
2740  if (!pPeer) return false;
2741  // send the packet
2742  return pPeer->Send(rPacket);
2743 }
bool Send(const C4NetIOPacket &rPacket)
Definition: C4NetIO.cpp:3188
CStdCSecEx PeerListCSec
Definition: C4NetIO.h:871
Peer * GetPeer(const addr_t &addr)
Definition: C4NetIO.cpp:3793
const C4NetIO::addr_t & getAddr() const
Definition: C4NetIO.h:316
friend class Peer
Definition: C4NetIO.h:868
Here is the call graph for this function:
Here is the caller graph for this function:

◆ SendDirect()

bool C4NetIOUDP::SendDirect ( C4NetIOPacket &&  rPacket)
inherited

Definition at line 3672 of file C4NetIO.cpp.

References C4NetIOSimpleUDP::getMCAddr(), C4NetIOUDP::iBroadcastRate, C4NetIOUDP::IPID_Test, C4NetIOUDP::iUDPHeaderSize, C4NetIOSimpleUDP::Send(), C4NetIOPacket::SetAddr(), C4NetIOUDP::Peer::StatCSec, and UnsyncedRandom().

Referenced by C4NetIOUDP::ClearStatistic(), and C4NetIOUDP::Peer::SendDirect().

3673 {
3674  addr_t toaddr = rPacket.getAddr();
3675  // packet meant to be broadcasted?
3676  if (rPacket.getStatus() & 0x80)
3677  {
3678  // set addr
3679  toaddr = C4NetIOSimpleUDP::getMCAddr();
3680  // statistics
3681  CStdLock StatLock(&StatCSec);
3682  iBroadcastRate += rPacket.getSize() + iUDPHeaderSize;
3683  }
3684 
3685  // debug
3686 #ifdef C4NETIO_DEBUG
3687  { C4NetIOPacket Pkt2 = rPacket; Pkt2.SetAddr(toaddr); DebugLogPkt(true, Pkt2); }
3688 #endif
3689 
3690 #ifdef C4NETIO_SIMULATE_PACKETLOSS
3691  if ((rPacket.getStatus() & 0x7F) != IPID_Test)
3692  if (UnsyncedRandom(100) < C4NETIO_SIMULATE_PACKETLOSS) return true;
3693 #endif
3694 
3695  // send it
3696  return C4NetIOSimpleUDP::Send(C4NetIOPacket(rPacket.getRef(), toaddr));
3697 }
uint32_t UnsyncedRandom()
Definition: C4Random.cpp:58
uint8_t getStatus() const
Definition: C4NetIO.h:318
int iBroadcastRate
Definition: C4NetIO.h:899
static const unsigned int iUDPHeaderSize
Definition: C4NetIO.h:659
size_t getSize() const
Definition: StdBuf.h:101
const addr_t & getMCAddr() const
Definition: C4NetIO.h:572
EndpointAddress addr_t
Definition: C4NetIO.h:212
bool Send(const C4NetIOPacket &rPacket) override
Definition: C4NetIO.cpp:2180
C4NetIOPacket getRef() const
Definition: C4NetIO.h:324
void SetAddr(const C4NetIO::addr_t &naddr)
Definition: C4NetIO.h:327
const C4NetIO::addr_t & getAddr() const
Definition: C4NetIO.h:316
CStdCSec StatCSec
Definition: C4NetIO.h:900
Here is the call graph for this function:
Here is the caller graph for this function:

◆ SetBroadcast()

bool C4NetIOUDP::SetBroadcast ( const addr_t addr,
bool  fSet = true 
)
overridevirtualinherited

Reimplemented from C4NetIOSimpleUDP.

Definition at line 2772 of file C4NetIO.cpp.

References C4NetIOUDP::GetPeer(), C4NetIOUDP::PeerListCSec, and C4NetIOUDP::Peer::SetBroadcast().

2773 {
2774  CStdShareLock PeerListLock(&PeerListCSec);
2775  // find peer
2776  Peer *pPeer = GetPeer(addr);
2777  if (!pPeer) return false;
2778  // set flag
2779  pPeer->SetBroadcast(fSet);
2780  return true;
2781 }
CStdCSecEx PeerListCSec
Definition: C4NetIO.h:871
Peer * GetPeer(const addr_t &addr)
Definition: C4NetIO.cpp:3793
friend class Peer
Definition: C4NetIO.h:868
Here is the call graph for this function:

◆ SetCallback() [1/2]

virtual void C4NetIO::SetCallback ( CBClass pnCallback)
pure virtualinherited

Referenced by C4NetIOMan::AddIO(), C4Network2IO::Init(), and C4NetIO::ResetError().

Here is the caller graph for this function:

◆ SetCallback() [2/2]

void C4NetIOUDP::SetCallback ( CBClass *  pnCallback)
inlineoverrideinherited

Definition at line 936 of file C4NetIO.h.

Referenced by C4PuncherServer().

936 { pCB = pnCallback; };
Here is the caller graph for this function:

◆ SetError()

void C4NetIO::SetError ( const char *  strnError,
bool  fSockErr = false 
)
protectedinherited

Definition at line 750 of file C4NetIO.cpp.

References C4NetIOPacket::C4NetIOPacket(), StdStrBuf::Copy(), C4NetIO::Error, StdStrBuf::Format(), GetSocketErrorMsg(), and HaveSocketError().

Referenced by C4NetIOTCP::Accept(), C4NetIOTCP::Bind(), C4NetIOSimpleUDP::Broadcast(), C4NetIOSimpleUDP::CloseBroadcast(), C4NetIOTCP::Connect(), C4NetIOTCP::CreateSocket(), C4NetIOUDP::DoLoopbackTest(), C4NetIOTCP::Execute(), C4NetIOSimpleUDP::Execute(), C4NetIOUDP::Execute(), C4NetIOSimpleUDP::GetFDs(), C4NetIOTCP::Init(), C4NetIOSimpleUDP::Init(), C4NetIOSimpleUDP::InitBroadcast(), C4NetIOUDP::InitBroadcast(), C4NetIO::InitIPv6Socket(), C4NetIOTCP::Listen(), C4NetIOTCP::Peer::Send(), C4NetIOSimpleUDP::Send(), C4NetIOTCP::UnBlock(), and C4NetIOSimpleUDP::UnBlock().

751 {
752  fSockErr &= HaveSocketError();
753  if (fSockErr)
754  Error.Format("%s (%s)", strnError, GetSocketErrorMsg());
755  else
756  Error.Copy(strnError);
757 }
const char * GetSocketErrorMsg(int iError)
Definition: C4NetIO.cpp:190
StdCopyStrBuf Error
Definition: C4NetIO.h:282
void Format(const char *szFmt,...) GNUC_FORMAT_ATTRIBUTE_O
Definition: StdBuf.cpp:174
bool HaveSocketError()
Definition: C4NetIO.cpp:199
void Copy()
Definition: StdBuf.h:467
Here is the call graph for this function:
Here is the caller graph for this function:

◆ SetMCLoopback()

bool C4NetIOSimpleUDP::SetMCLoopback ( int  fLoopback)
protectedinherited

Definition at line 2290 of file C4NetIO.cpp.

References iSize, and SOCKET_ERROR.

Referenced by C4NetIOUDP::DoLoopbackTest(), C4Network2IODiscover::Init(), C4Network2IODiscoverClient::Init(), C4NetIOSimpleUDP::InitBroadcast(), and C4NetIOUDP::InitBroadcast().

2291 {
2292  // enable/disable MC loopback
2293  setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, reinterpret_cast<char *>(&fLoopback), sizeof fLoopback);
2294  // read result
2295  socklen_t iSize = sizeof(fLoopback);
2296  if (getsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, reinterpret_cast<char *>(&fLoopback), &iSize) == SOCKET_ERROR)
2297  return false;
2298  fMCLoopback = !! fLoopback;
2299  return true;
2300 }
int iSize
Definition: TstC4NetIO.cpp:32
#define SOCKET_ERROR
Definition: C4NetIO.cpp:47
Here is the caller graph for this function:

◆ SetReUseAddress()

void C4NetIOSimpleUDP::SetReUseAddress ( bool  fAllow)
protectedinherited

Definition at line 2302 of file C4NetIO.cpp.

Referenced by C4Network2IODiscover::Init(), and C4Network2IODiscoverClient::Init().

2303 {
2304  fAllowReUse = fAllow;
2305 }
Here is the caller graph for this function:

◆ TimerInterval()

virtual uint32_t StdSchedulerProc::TimerInterval ( )
inlinevirtualinherited

Reimplemented in CStdTimerProc.

Definition at line 84 of file StdScheduler.h.

Referenced by SCHAdditions::assignAdditionForProc:.

84 { return 0; }
Here is the caller graph for this function:

◆ UnBlock()

void C4NetIOSimpleUDP::UnBlock ( )
virtualinherited

Definition at line 2243 of file C4NetIO.cpp.

References C4NetIO::SetError().

Referenced by C4NetIOSimpleUDP::Broadcast().

2244 {
2245  // write one character to the pipe, this will unblock everything that
2246  // waits for the FD set returned by GetFDs.
2247  char c = 42;
2248  if (write(Pipe[1], &c, 1) == -1)
2249  SetError("write failed");
2250 }
void SetError(const char *strnError, bool fSockErr=false)
Definition: C4NetIO.cpp:750
Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ Error

StdCopyStrBuf C4NetIO::Error
protectedinherited

Definition at line 282 of file C4NetIO.h.

Referenced by C4NetIO::SetError().

◆ ExecuteCSec

CStdCSec C4NetIOUDP::ExecuteCSec
protectedinherited

Definition at line 924 of file C4NetIO.h.

Referenced by C4NetIOUDP::Execute().

◆ fDelayedLoopbackTest

bool C4NetIOUDP::fDelayedLoopbackTest {false}
protectedinherited

◆ fInit

bool C4NetIOUDP::fInit {false}
protectedinherited

◆ fMultiCast

◆ fSavePacket

bool C4NetIOUDP::fSavePacket {false}
protectedinherited

◆ iBroadcastRate

int C4NetIOUDP::iBroadcastRate {0}
protectedinherited

◆ iCheckInterval

const unsigned int C4NetIOUDP::iCheckInterval = 1000
staticprotectedinherited

Definition at line 654 of file C4NetIO.h.

Referenced by C4NetIOUDP::DoCheck(), and C4NetIOUDP::Init().

◆ iMaxOPacketBacklog

const unsigned int C4NetIOUDP::iMaxOPacketBacklog = 10000
staticprotectedinherited

Definition at line 657 of file C4NetIO.h.

◆ iOPacketCounter

unsigned int C4NetIOUDP::iOPacketCounter {0}
protectedinherited

◆ iPort

uint16_t C4NetIOUDP::iPort
protectedinherited

◆ iStdTimeout

const unsigned int C4NetIOUDP::iStdTimeout = 1000
staticprotectedinherited

◆ iUDPHeaderSize

const unsigned int C4NetIOUDP::iUDPHeaderSize = 8 + 24
staticprotectedinherited

◆ iVersion

const unsigned int C4NetIOUDP::iVersion = 2
staticprotectedinherited

Definition at line 649 of file C4NetIO.h.

Referenced by C4NetIOUDP::Peer::DoConn(), and C4NetIOUDP::Peer::OnRecv().

◆ LastPacket

C4NetIOPacket C4NetIOUDP::LastPacket
protectedinherited

◆ MCLoopbackAddr

addr_t C4NetIOUDP::MCLoopbackAddr
protectedinherited

◆ OPackets

PacketList C4NetIOUDP::OPackets
protectedinherited

Definition at line 895 of file C4NetIO.h.

Referenced by C4NetIOUDP::Broadcast(), and C4NetIOUDP::Peer::OnRecv().

◆ OutCSec

CStdCSec C4NetIOUDP::OutCSec
protectedinherited

Definition at line 873 of file C4NetIO.h.

Referenced by C4NetIOUDP::Broadcast(), and C4NetIOUDP::Peer::OnRecv().

◆ PeerListAddCSec

CStdCSec C4NetIOUDP::PeerListAddCSec
protectedinherited

Definition at line 872 of file C4NetIO.h.

Referenced by C4NetIOUDP::AddPeer(), and C4NetIOUDP::ConnectPeer().

◆ PeerListCSec

◆ pPeerList

◆ StatCSec

CStdCSec C4NetIOUDP::StatCSec
protectedinherited

Definition at line 900 of file C4NetIO.h.

Referenced by C4NetIOUDP::ClearStatistic(), and C4NetIOUDP::GetStatistic().

◆ tNextCheck

C4TimeMilliseconds C4NetIOUDP::tNextCheck
protectedinherited

◆ TO_INF


The documentation for this class was generated from the following file: