OpenClonk
C4NetIOUDP::Peer Class Reference

#include <C4NetIO.h>

Collaboration diagram for C4NetIOUDP::Peer:
[legend]

Public Member Functions

 Peer (const C4NetIO::addr_t &naddr, C4NetIOUDP *pnParent)
 
 ~Peer ()
 
const C4NetIO::addr_tGetAddr () const
 
const C4NetIO::addr_tGetAltAddr () const
 
bool Connect (bool fFailCallback)
 
bool Send (const C4NetIOPacket &rPacket)
 
bool Check (bool fForceCheck=true)
 
void OnRecv (const C4NetIOPacket &Packet)
 
void Close (const char *szReason)
 
bool Open () const
 
bool Closed () const
 
bool MultiCast () const
 
unsigned int GetMCAckPacketCounter () const
 
C4TimeMilliseconds GetTimeout ()
 
void CheckTimeout ()
 
bool doBroadcast () const
 
void SetBroadcast (bool fSet)
 
void SetAltAddr (const C4NetIO::addr_t &naddr2)
 
int GetIRate () const
 
int GetORate () const
 
int GetLoss () const
 
void ClearStatistics ()
 

Public Attributes

PeerNext
 

Protected Types

enum  ConnStatus { CS_None , CS_Conn , CS_Works , CS_Closed }
 

Protected Member Functions

bool DoConn (bool fMC)
 
bool DoCheck (int iAskCnt=0, int iMCAskCnt=0, unsigned int *pAskList=nullptr)
 
bool SendDirect (const Packet &rPacket, unsigned int iNr=~0)
 
bool SendDirect (C4NetIOPacket &&rPacket)
 
void OnConn ()
 
void OnClose (const char *szReason)
 
void CheckCompleteIPackets ()
 
void SetTimeout (int iLength=iStdTimeout, int iRetryCnt=0)
 
void OnTimeout ()
 

Protected Attributes

C4NetIOUDP *const pParent
 
C4NetIO::addr_t addr
 
C4NetIO::addr_t addr2
 
addr_t PeerAddr
 
enum C4NetIOUDP::Peer::ConnStatus eStatus
 
bool fMultiCast
 
bool fDoBroadcast
 
bool fConnFailCallback
 
PacketList OPackets
 
PacketList IPackets
 
PacketList IMCPackets
 
unsigned int iOPacketCounter
 
unsigned int iIPacketCounter
 
unsigned int iRIPacketCounter
 
unsigned int iIMCPacketCounter
 
unsigned int iRIMCPacketCounter
 
unsigned int iMCAckPacketCounter
 
CStdCSec OutCSec
 
C4TimeMilliseconds tNextReCheck
 
unsigned int iLastPacketAsked
 
unsigned int iLastMCPacketAsked
 
C4TimeMilliseconds tTimeout
 
unsigned int iRetries
 
int iIRate
 
int iORate
 
int iLoss
 
CStdCSec StatCSec
 

Static Protected Attributes

static const unsigned int iConnectRetries = 5
 
static const unsigned int iReCheckInterval = 1000
 

Detailed Description

Definition at line 736 of file C4NetIO.h.

Member Enumeration Documentation

◆ ConnStatus

Enumerator
CS_None 
CS_Conn 
CS_Works 
CS_Closed 

Definition at line 760 of file C4NetIO.h.

Constructor & Destructor Documentation

◆ Peer()

C4NetIOUDP::Peer::Peer ( const C4NetIO::addr_t naddr,
C4NetIOUDP pnParent 
)

Definition at line 3161 of file C4NetIO.cpp.

3162  : pParent(pnParent), addr(naddr),
3163  eStatus(CS_None),
3164  fMultiCast(false), fDoBroadcast(false),
3166  iOPacketCounter(0),
3171  iIRate(0), iORate(0), iLoss(0)
3172 {
3173 }
unsigned int iOPacketCounter
Definition: C4NetIO.h:777
C4TimeMilliseconds tNextReCheck
Definition: C4NetIO.h:787
bool fDoBroadcast
Definition: C4NetIO.h:768
enum C4NetIOUDP::Peer::ConnStatus eStatus
C4NetIO::addr_t addr
Definition: C4NetIO.h:754
C4NetIOUDP *const pParent
Definition: C4NetIO.h:751
unsigned int iIMCPacketCounter
Definition: C4NetIO.h:779
unsigned int iRIPacketCounter
Definition: C4NetIO.h:778
unsigned int iMCAckPacketCounter
Definition: C4NetIO.h:781
unsigned int iIPacketCounter
Definition: C4NetIO.h:778
unsigned int iRIMCPacketCounter
Definition: C4NetIO.h:779
PacketList OPackets
Definition: C4NetIO.h:773
static const unsigned int iMaxOPacketBacklog
Definition: C4NetIO.h:658

◆ ~Peer()

C4NetIOUDP::Peer::~Peer ( )

Definition at line 3175 of file C4NetIO.cpp.

3176 {
3177  // send close-packet
3178  Close("deleted");
3179 }
void Close(const char *szReason)
Definition: C4NetIO.cpp:3458

References C4NetIOUDP::Close().

Here is the call graph for this function:

Member Function Documentation

◆ Check()

bool C4NetIOUDP::Peer::Check ( bool  fForceCheck = true)

Definition at line 3210 of file C4NetIO.cpp.

3211 {
3212  // only on working connections
3213  if (eStatus != CS_Works) return true;
3214  // prevent re-check (check floods)
3215  // instead, ask for other packets that are missing until recheck is allowed
3216  bool fNoReCheck = tNextReCheck > C4TimeMilliseconds::Now();
3217  if (!fNoReCheck) iLastPacketAsked = iLastMCPacketAsked = 0;
3218  unsigned int iStartAt = fNoReCheck ? std::max(iLastPacketAsked + 1, iIPacketCounter) : iIPacketCounter;
3219  unsigned int iStartAtMC = fNoReCheck ? std::max(iLastMCPacketAsked + 1, iIMCPacketCounter) : iIMCPacketCounter;
3220  // check if we have something to ask for
3221  const unsigned int iMaxAskCnt = 10;
3222  unsigned int i, iAskList[iMaxAskCnt], iAskCnt = 0, iMCAskCnt = 0;
3223  for (i = iStartAt; i < iRIPacketCounter; i++)
3224  if (!IPackets.FragmentPresent(i))
3225  if (iAskCnt < iMaxAskCnt)
3226  iLastPacketAsked = iAskList[iAskCnt++] = i;
3227  for (i = iStartAtMC; i < iRIMCPacketCounter; i++)
3228  if (!IMCPackets.FragmentPresent(i))
3229  if (iAskCnt + iMCAskCnt < iMaxAskCnt)
3230  iLastMCPacketAsked = iAskList[iAskCnt + iMCAskCnt++] = i;
3231  int iEAskCnt = iAskCnt + iMCAskCnt;
3232  // no re-check limit? set it
3233  if (!fNoReCheck)
3234  {
3235  if (iEAskCnt)
3237  else
3239  }
3240  // something to ask for? (or check forced?)
3241  if (iEAskCnt || fForceCheck)
3242  return DoCheck(iAskCnt, iMCAskCnt, iAskList);
3243  return true;
3244 }
bool FragmentPresent(unsigned int iNr)
Definition: C4NetIO.cpp:3087
bool DoCheck(int iAskCnt=0, int iMCAskCnt=0, unsigned int *pAskList=nullptr)
Definition: C4NetIO.cpp:3506
static const unsigned int iReCheckInterval
Definition: C4NetIO.h:748
PacketList IPackets
Definition: C4NetIO.h:774
unsigned int iLastPacketAsked
Definition: C4NetIO.h:788
PacketList IMCPackets
Definition: C4NetIO.h:774
unsigned int iLastMCPacketAsked
Definition: C4NetIO.h:788
static C4TimeMilliseconds Now()

References C4NetIOUDP::DoCheck(), C4TimeMilliseconds::NegativeInfinity, and C4TimeMilliseconds::Now().

Here is the call graph for this function:

◆ CheckCompleteIPackets()

void C4NetIOUDP::Peer::CheckCompleteIPackets ( )
protected

Definition at line 3581 of file C4NetIO.cpp.

3582 {
3583  // only status CS_Works
3584  if (eStatus != CS_Works) return;
3585  // (If the status is CS_Conn, we'll have to wait until the connection in the
3586  // opposite direction is etablished. There is no problem in checking for
3587  // complete packets here, but the one using the interface may get very confused
3588  // if he gets a callback for a connection that hasn't been announced to him
3589  // yet)
3590 
3591  // check for complete incoming packets
3592  Packet *pPkt;
3593  while ((pPkt = IPackets.GetFirstPacketComplete()))
3594  {
3595  // missing packet?
3596  if (pPkt->GetNr() != iIPacketCounter) break;
3597  // do callback
3598  if (pParent->pCB)
3599  pParent->pCB->OnPacket(pPkt->GetData(), pParent);
3600  // advance packet counter
3601  iIPacketCounter = pPkt->GetNr() + pPkt->FragmentCnt();
3602  // remove packet from queue
3603  int iNr = pPkt->GetNr();
3604  IPackets.DeletePacket(pPkt);
3605  assert(!IPackets.GetPacketFrgm(iNr)); (void)iNr;
3606  }
3607  while ((pPkt = IMCPackets.GetFirstPacketComplete()))
3608  {
3609  // missing packet?
3610  if (pPkt->GetNr() != iIMCPacketCounter) break;
3611  // do callback
3612  if (pParent->pCB)
3613  pParent->pCB->OnPacket(pPkt->GetData(), pParent);
3614  // advance packet counter
3615  iIMCPacketCounter = pPkt->GetNr() + pPkt->FragmentCnt();
3616  // remove packet from queue
3617  int iNr = pPkt->GetNr();
3618  IMCPackets.DeletePacket(pPkt);
3619  assert(!IMCPackets.GetPacketFrgm(iNr)); (void)iNr;
3620  }
3621 }
virtual void OnPacket(const class C4NetIOPacket &rPacket, C4NetIO *pNetIO)=0
bool DeletePacket(Packet *pPacket)
Definition: C4NetIO.cpp:3118
Packet * GetFirstPacketComplete()
Definition: C4NetIO.cpp:3081
Packet * GetPacketFrgm(unsigned int iNr)
Definition: C4NetIO.cpp:3070
friend class Packet
Definition: C4NetIO.h:706

References C4NetIOUDP::Packet::FragmentCnt(), C4NetIOUDP::Packet::GetData(), and C4NetIOUDP::Packet::GetNr().

Here is the call graph for this function:

◆ CheckTimeout()

void C4NetIOUDP::Peer::CheckTimeout ( )

Definition at line 3473 of file C4NetIO.cpp.

3474 {
3475  // check
3477  OnTimeout();
3478 }
C4TimeMilliseconds tTimeout
Definition: C4NetIO.h:791

References C4TimeMilliseconds::Now().

Here is the call graph for this function:

◆ ClearStatistics()

void C4NetIOUDP::Peer::ClearStatistics ( )

Definition at line 3480 of file C4NetIO.cpp.

3481 {
3482  CStdLock StatLock(&StatCSec);
3483  iIRate = iORate = 0;
3484  iLoss = 0;
3485 }
CStdCSec StatCSec
Definition: C4NetIO.h:796

References C4NetIOUDP::StatCSec.

◆ Close()

void C4NetIOUDP::Peer::Close ( const char *  szReason)

Definition at line 3458 of file C4NetIO.cpp.

3459 {
3460  // already closed?
3461  if (eStatus == CS_Closed)
3462  return;
3463  // send close-packet
3464  ClosePacket Pkt;
3465  Pkt.StatusByte = IPID_Close;
3466  Pkt.Nr = 0;
3467  Pkt.Addr = addr;
3468  SendDirect(C4NetIOPacket(&Pkt, sizeof(Pkt), false, addr));
3469  // callback
3470  OnClose(szReason);
3471 }
bool SendDirect(const Packet &rPacket, unsigned int iNr=~0)
Definition: C4NetIO.cpp:3530
void OnClose(const char *szReason)
Definition: C4NetIO.cpp:3570
@ IPID_Close
Definition: C4NetIO.h:644

References C4NetIOUDP::ClosePacket::Addr, CS_Closed, C4NetIOUDP::IPID_Close, C4NetIOUDP::PacketHdr::Nr, C4NetIOUDP::SendDirect(), and C4NetIOUDP::PacketHdr::StatusByte.

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

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Closed()

bool C4NetIOUDP::Peer::Closed ( ) const
inline

Definition at line 819 of file C4NetIO.h.

819 { return eStatus == CS_Closed; }

References CS_Closed, and eStatus.

Referenced by C4NetIOUDP::OnShareFree().

Here is the caller graph for this function:

◆ Connect()

bool C4NetIOUDP::Peer::Connect ( bool  fFailCallback)

Definition at line 3181 of file C4NetIO.cpp.

3182 {
3183  // initiate connection (DoConn will set status CS_Conn)
3184  fMultiCast = false; fConnFailCallback = fFailCallback;
3185  return DoConn(false);
3186 }
bool fConnFailCallback
Definition: C4NetIO.h:770
bool DoConn(bool fMC)
Definition: C4NetIO.cpp:3487

References C4NetIOUDP::fMultiCast.

Referenced by C4NetIOUDP::ConnectPeer().

Here is the caller graph for this function:

◆ doBroadcast()

bool C4NetIOUDP::Peer::doBroadcast ( ) const
inline

Definition at line 831 of file C4NetIO.h.

831 { return fDoBroadcast; }

References fDoBroadcast.

Referenced by C4NetIOUDP::Broadcast().

Here is the caller graph for this function:

◆ DoCheck()

bool C4NetIOUDP::Peer::DoCheck ( int  iAskCnt = 0,
int  iMCAskCnt = 0,
unsigned int *  pAskList = nullptr 
)
protected

Definition at line 3506 of file C4NetIO.cpp.

3507 {
3508  // security
3509  if (!pAskList) iAskCnt = iMCAskCnt = 0;
3510  // statistics
3511  { CStdLock StatLock(&StatCSec); iLoss += iAskCnt + iMCAskCnt; }
3512  // alloc data
3513  int iAskListSize = (iAskCnt + iMCAskCnt) * sizeof(*pAskList);
3514  StdBuf Packet; Packet.New(sizeof(CheckPacketHdr) + iAskListSize);
3515  CheckPacketHdr *pChkPkt = getMBufPtr<CheckPacketHdr>(Packet);
3516  // set up header
3517  pChkPkt->StatusByte = IPID_Check; // (note: always du here, see C4NetIOUDP::DoCheck)
3518  pChkPkt->Nr = iOPacketCounter;
3519  pChkPkt->AckNr = iIPacketCounter;
3520  pChkPkt->MCAckNr = iIMCPacketCounter;
3521  // copy ask list
3522  pChkPkt->AskCount = iAskCnt;
3523  pChkPkt->MCAskCount = iMCAskCnt;
3524  if (pAskList)
3525  Packet.Write(pAskList, iAskListSize, sizeof(CheckPacketHdr));
3526  // send packet
3527  return SendDirect(C4NetIOPacket(Packet, addr));
3528 }
@ IPID_Check
Definition: C4NetIO.h:643
Definition: StdBuf.h:30

References C4NetIOUDP::CheckPacketHdr::AckNr, C4NetIOUDP::CheckPacketHdr::AskCount, C4NetIOUDP::iOPacketCounter, C4NetIOUDP::IPID_Check, C4NetIOUDP::CheckPacketHdr::MCAckNr, C4NetIOUDP::CheckPacketHdr::MCAskCount, C4NetIOUDP::PacketHdr::Nr, C4NetIOUDP::Packet, C4NetIOUDP::SendDirect(), C4NetIOUDP::StatCSec, and C4NetIOUDP::PacketHdr::StatusByte.

Here is the call graph for this function:

◆ DoConn()

bool C4NetIOUDP::Peer::DoConn ( bool  fMC)
protected

Definition at line 3487 of file C4NetIO.cpp.

3488 {
3489  // set status
3490  eStatus = CS_Conn;
3491  // set timeout
3493  // send packet (include current outgoing packet counter and mc addr)
3494  ConnPacket Pkt;
3495  Pkt.StatusByte = uint8_t(IPID_Conn) | (fMC ? 0x80 : 0x00);
3496  Pkt.ProtocolVer = pParent->iVersion;
3497  Pkt.Nr = fMC ? pParent->iOPacketCounter : iOPacketCounter;
3498  Pkt.Addr = addr;
3499  if (pParent->fMultiCast)
3500  Pkt.MCAddr = pParent->C4NetIOSimpleUDP::getMCAddr();
3501  else
3502  Pkt.MCAddr = C4NetIO::addr_t();
3503  return SendDirect(C4NetIOPacket(&Pkt, sizeof(Pkt), false, addr));
3504 }
EndpointAddress addr_t
Definition: C4NetIO.h:213
void SetTimeout(int iLength=iStdTimeout, int iRetryCnt=0)
Definition: C4NetIO.cpp:3623
static const unsigned int iConnectRetries
Definition: C4NetIO.h:747
static const unsigned int iStdTimeout
Definition: C4NetIO.h:655
@ IPID_Conn
Definition: C4NetIO.h:639
bool fMultiCast
Definition: C4NetIO.h:878
unsigned int iOPacketCounter
Definition: C4NetIO.h:897
static const unsigned int iVersion
Definition: C4NetIO.h:650

References C4NetIOUDP::ConnPacket::Addr, C4NetIOUDP::iOPacketCounter, C4NetIOUDP::IPID_Conn, C4NetIOUDP::iStdTimeout, C4NetIOUDP::ConnPacket::MCAddr, C4NetIOUDP::PacketHdr::Nr, C4NetIOUDP::ConnPacket::ProtocolVer, C4NetIOUDP::SendDirect(), and C4NetIOUDP::PacketHdr::StatusByte.

Here is the call graph for this function:

◆ GetAddr()

const C4NetIO::addr_t& C4NetIOUDP::Peer::GetAddr ( ) const
inline

Definition at line 800 of file C4NetIO.h.

800 { return addr; }

References addr.

◆ GetAltAddr()

const C4NetIO::addr_t& C4NetIOUDP::Peer::GetAltAddr ( ) const
inline

Definition at line 801 of file C4NetIO.h.

801 { return addr2; }
C4NetIO::addr_t addr2
Definition: C4NetIO.h:756

References addr2.

◆ GetIRate()

int C4NetIOUDP::Peer::GetIRate ( ) const
inline

Definition at line 839 of file C4NetIO.h.

839 { return iIRate; }

References iIRate.

Referenced by C4NetIOUDP::GetConnStatistic().

Here is the caller graph for this function:

◆ GetLoss()

int C4NetIOUDP::Peer::GetLoss ( ) const
inline

Definition at line 841 of file C4NetIO.h.

841 { return iLoss; }

References iLoss.

◆ GetMCAckPacketCounter()

unsigned int C4NetIOUDP::Peer::GetMCAckPacketCounter ( ) const
inline

Definition at line 824 of file C4NetIO.h.

824 { return iMCAckPacketCounter; }

References iMCAckPacketCounter.

Referenced by C4NetIOUDP::ClearMCPackets().

Here is the caller graph for this function:

◆ GetORate()

int C4NetIOUDP::Peer::GetORate ( ) const
inline

Definition at line 840 of file C4NetIO.h.

840 { return iORate; }

References iORate.

Referenced by C4NetIOUDP::GetConnStatistic().

Here is the caller graph for this function:

◆ GetTimeout()

C4TimeMilliseconds C4NetIOUDP::Peer::GetTimeout ( )
inline

Definition at line 827 of file C4NetIO.h.

827 { return tTimeout; }

References tTimeout.

◆ MultiCast()

bool C4NetIOUDP::Peer::MultiCast ( ) const
inline

Definition at line 821 of file C4NetIO.h.

821 { return fMultiCast; }

References fMultiCast.

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

Here is the caller graph for this function:

◆ OnClose()

void C4NetIOUDP::Peer::OnClose ( const char *  szReason)
protected

Definition at line 3570 of file C4NetIO.cpp.

3571 {
3572  // do callback
3573  C4NetIO::CBClass *pCB = pParent->pCB;
3574  if (eStatus == CS_Works || (eStatus == CS_Conn && fConnFailCallback))
3575  if (pCB)
3576  pCB->OnDisconn(addr, pParent, szReason);
3577  // set status (this will schedule this peer for deletion)
3578  eStatus = CS_Closed;
3579 }
virtual void OnDisconn(const addr_t &AddrPeer, C4NetIO *pNetIO, const char *szReason)
Definition: C4NetIO.h:222

References CS_Closed, and C4NetIO::CBClass::OnDisconn().

Here is the call graph for this function:

◆ OnConn()

void C4NetIOUDP::Peer::OnConn ( )
protected

Definition at line 3553 of file C4NetIO.cpp.

3554 {
3555  // reset timeout
3556  SetTimeout(TO_INF);
3557  // set status
3558  eStatus = CS_Works;
3559  // do callback
3560  C4NetIO::CBClass *pCB = pParent->pCB;
3561  if (pCB && !pCB->OnConn(addr, addr, &PeerAddr, pParent))
3562  {
3563  Close("closed");
3564  return;
3565  }
3566  // do packet callback (in case the peer sent data while the connection was in progress)
3568 }
virtual bool OnConn(const addr_t &AddrPeer, const addr_t &AddrConnect, const addr_t *pOwnAddr, C4NetIO *pNetIO)
Definition: C4NetIO.h:221
static const int TO_INF
Definition: C4NetIO.h:66
void CheckCompleteIPackets()
Definition: C4NetIO.cpp:3581
addr_t PeerAddr
Definition: C4NetIO.h:758

References C4NetIOUDP::Close(), C4NetIO::CBClass::OnConn(), and C4NetIO::TO_INF.

Here is the call graph for this function:

◆ OnRecv()

void C4NetIOUDP::Peer::OnRecv ( const C4NetIOPacket Packet)

Definition at line 3246 of file C4NetIO.cpp.

3247 {
3248  // statistics
3249  { CStdLock StatLock(&StatCSec); iIRate += rPacket.getSize() + iUDPHeaderSize; }
3250  // get packet header
3251  if (rPacket.getSize() < sizeof(PacketHdr)) return;
3252  const PacketHdr *pHdr = getBufPtr<PacketHdr>(rPacket);
3253  bool fBroadcasted = !!(pHdr->StatusByte & 0x80);
3254  // save packet nr
3255  (fBroadcasted ? iRIMCPacketCounter : iRIPacketCounter) = std::max<unsigned int>((fBroadcasted ? iRIMCPacketCounter : iRIPacketCounter), pHdr->Nr);
3256 #ifdef C4NETIOUDP_OPT_RECV_CHECK_IMMEDIATE
3257  // do check
3258  if (eStatus == CS_Works)
3259  Check(false);
3260 #endif
3261  // what type of packet is it?
3262  switch (pHdr->StatusByte & 0x7f)
3263  {
3264 
3265  case IPID_Conn:
3266  {
3267  // check size
3268  if (rPacket.getSize() != sizeof(ConnPacket)) break;
3269  const ConnPacket *pPkt = getBufPtr<ConnPacket>(rPacket);
3270  // right version?
3271  if (pPkt->ProtocolVer != pParent->iVersion) break;
3272  if (!fBroadcasted)
3273  {
3274  // Second connection attempt using different address?
3275  if (!PeerAddr.IsNull() && PeerAddr != pPkt->Addr)
3276  {
3277  // Notify peer that he has two addresses to reach this connection.
3278  AddAddrPacket Pkt;
3279  Pkt.StatusByte = IPID_AddAddr;
3280  Pkt.Nr = iOPacketCounter;
3281  Pkt.Addr = PeerAddr;
3282  Pkt.NewAddr = pPkt->Addr;
3283  SendDirect(C4NetIOPacket(&Pkt, sizeof(Pkt), false, addr));
3284  // But do nothing else - don't interfere with this connection
3285  break;
3286  }
3287  // reinit?
3288  else if (eStatus == CS_Works && iIPacketCounter != pPkt->Nr)
3289  {
3290  // close (callback!) ...
3291  OnClose("reconnect"); eStatus = CS_Closed;
3292  // ... and reconnect
3293  Connect(false);
3294  }
3295  // save back the address the peer is using
3296  PeerAddr = pPkt->Addr;
3297  }
3298  // set packet counter
3299  if (fBroadcasted)
3301  else
3302  iRIPacketCounter = iIPacketCounter = pPkt->Nr;
3303  // clear incoming packets
3304  IPackets.Clear();
3305  IMCPackets.Clear();
3306 
3308 
3310  // Activate Multicast?
3311  if (!pParent->fMultiCast)
3312  {
3313  addr_t MCAddr = pPkt->MCAddr;
3314  if (!MCAddr.IsNull())
3315  {
3316  // Init Broadcast (with delayed loopback test)
3317  pParent->fDelayedLoopbackTest = true;
3318  if (!pParent->InitBroadcast(&MCAddr))
3319  pParent->fDelayedLoopbackTest = false;
3320  }
3321  }
3322  // build ConnOk Packet
3323  ConnOKPacket nPack;
3324  bool fullyConnected = false;
3325 
3326  nPack.StatusByte = IPID_ConnOK; // (always du, no mc experiments here)
3327  nPack.Nr = fBroadcasted ? pParent->iOPacketCounter : iOPacketCounter;
3328  nPack.Addr = addr;
3329  if (fBroadcasted)
3330  nPack.MCMode = ConnOKPacket::MCM_MCOK; // multicast send ok
3331  else if (pParent->fMultiCast && addr.GetPort() == pParent->iPort)
3332  nPack.MCMode = ConnOKPacket::MCM_MC; // du ok, try multicast next
3333  else
3334  {
3335  nPack.MCMode = ConnOKPacket::MCM_NoMC; // du ok
3336  // no multicast => we're fully connected now
3337  fullyConnected = true;
3338  }
3339  // send it
3340  SendDirect(C4NetIOPacket(&nPack, sizeof(nPack), false, addr));
3341  // Clients will try sending data from OnConn, so send ConnOK before that.
3342  if (fullyConnected) OnConn();
3343  }
3344  break;
3345 
3346  case IPID_ConnOK:
3347  {
3348  if (eStatus != CS_Conn) break;
3349  // check size
3350  if (rPacket.getSize() != sizeof(ConnOKPacket)) break;
3351  const ConnOKPacket *pPkt = getBufPtr<ConnOKPacket>(rPacket);
3352  // save port
3353  PeerAddr = pPkt->Addr;
3354  // Needs another Conn/ConnOK-sequence?
3355  switch (pPkt->MCMode)
3356  {
3357  case ConnOKPacket::MCM_MC:
3358  // multicast has to be active
3359  if (pParent->fMultiCast)
3360  {
3361  // already trying to connect via multicast?
3362  if (fMultiCast) break;
3363  // Send another Conn packet back (this time broadcasted to check if multicast works)
3364  fMultiCast = true; DoConn(true);
3365  break;
3366  }
3367  // fallthru
3369  // Connection is established (no multicast support)
3370  fMultiCast = false; OnConn();
3371  break;
3373  // Connection is established (multicast support)
3374  fMultiCast = true; OnConn();
3375  break;
3376  }
3377  }
3378  break;
3379 
3380  case IPID_Data:
3381  {
3382  // get the packet header
3383  if (rPacket.getSize() < sizeof(DataPacketHdr)) return;
3384  const DataPacketHdr *pHdr = getBufPtr<DataPacketHdr>(rPacket);
3385  // already complet?
3386  if (pHdr->Nr < (fBroadcasted ? iIMCPacketCounter : iIPacketCounter)) break;
3387  // find or create packet
3388  bool fAddPacket = false;
3389  PacketList *pPacketList = fBroadcasted ? &IMCPackets : &IPackets;
3390  Packet *pPkt = pPacketList->GetPacket(pHdr->FNr);
3391  if (!pPkt) { pPkt = new Packet(); fAddPacket = true; }
3392  // add the fragment
3393  if (pPkt->AddFragment(rPacket, addr))
3394  {
3395  // add the packet to list
3396  if (fAddPacket) if (!pPacketList->AddPacket(pPkt)) { delete pPkt; break; }
3397  // check for complete packets
3399  }
3400  else
3401  // delete the packet
3402  if (fAddPacket) delete pPkt;
3403  }
3404  break;
3405 
3406  case IPID_Check:
3407  {
3408  // get the packet header
3409  if (rPacket.getSize() < sizeof(CheckPacketHdr)) break;
3410  const CheckPacketHdr *pPkt = getBufPtr<CheckPacketHdr>(rPacket);
3411  // check packet size
3412  if (rPacket.getSize() < sizeof(CheckPacketHdr) + (pPkt->AskCount + pPkt->MCAskCount) * sizeof(int)) break;
3413  // clear all acknowledged packets
3414  CStdLock OutLock(&OutCSec);
3415  OPackets.ClearPackets(pPkt->AckNr);
3416  if (pPkt->MCAckNr > iMCAckPacketCounter)
3417  {
3418  iMCAckPacketCounter = pPkt->MCAckNr;
3420  }
3421  OutLock.Clear();
3422  // read ask list
3423  const int *pAskList = getBufPtr<int>(rPacket, sizeof(CheckPacketHdr));
3424  // send the packets he asks for
3425  unsigned int i;
3426  for (i = 0; i < pPkt->AskCount + pPkt->MCAskCount; i++)
3427  {
3428  // packet available?
3429  bool fMCPacket = i >= pPkt->AskCount;
3430  CStdLock OutLock(fMCPacket ? &pParent->OutCSec : &OutCSec);
3431  Packet *pPkt2Send = (fMCPacket ? pParent->OPackets : OPackets).GetPacketFrgm(pAskList[i]);
3432  if (!pPkt2Send) { Close("starvation"); break; }
3433  // send the fragment
3434  if (fMCPacket)
3435  pParent->BroadcastDirect(*pPkt2Send, pAskList[i]);
3436  else
3437  SendDirect(*pPkt2Send, pAskList[i]);
3438  }
3439  }
3440  break;
3441 
3442  case IPID_Close:
3443  {
3444  // check packet size
3445  if (rPacket.getSize() < sizeof(ClosePacket)) break;
3446  const ClosePacket *pPkt = getBufPtr<ClosePacket>(rPacket);
3447  // ignore if it's for another address
3448  if (!PeerAddr.IsNull() && PeerAddr != pPkt->Addr)
3449  break;
3450  // close
3451  OnClose("connection closed by peer");
3452  }
3453  break;
3454 
3455  }
3456 }
void ClearPackets(unsigned int iUntil)
Definition: C4NetIO.cpp:3138
bool Check(bool fForceCheck=true)
Definition: C4NetIO.cpp:3210
CStdCSec OutCSec
Definition: C4NetIO.h:784
bool Connect(bool fFailCallback)
Definition: C4NetIO.cpp:3181
void ClearMCPackets()
Definition: C4NetIO.cpp:3738
bool fDelayedLoopbackTest
Definition: C4NetIO.h:890
static const unsigned int iUDPHeaderSize
Definition: C4NetIO.h:660
@ IPID_AddAddr
Definition: C4NetIO.h:641
@ IPID_Data
Definition: C4NetIO.h:642
@ IPID_ConnOK
Definition: C4NetIO.h:640
uint16_t iPort
Definition: C4NetIO.h:879
friend class PacketList
Definition: C4NetIO.h:733
bool BroadcastDirect(const Packet &rPacket, unsigned int iNr=~0u)
Definition: C4NetIO.cpp:3660
bool InitBroadcast(addr_t *pBroadcastAddr) override
Definition: C4NetIO.cpp:2501
CStdCSec OutCSec
Definition: C4NetIO.h:874
PacketList OPackets
Definition: C4NetIO.h:896
uint16_t GetPort() const
Definition: C4NetIO.cpp:547

References C4NetIOUDP::CheckPacketHdr::AckNr, C4NetIOUDP::Packet::AddFragment(), C4NetIOUDP::PacketList::AddPacket(), C4NetIOUDP::ConnPacket::Addr, C4NetIOUDP::ConnOKPacket::Addr, C4NetIOUDP::AddAddrPacket::Addr, C4NetIOUDP::ClosePacket::Addr, C4NetIOUDP::CheckPacketHdr::AskCount, CStdLock::Clear(), C4NetIOUDP::PacketList::ClearPackets(), C4NetIOUDP::Close(), C4NetIOUDP::Connect(), CS_Closed, C4NetIOUDP::fMultiCast, C4NetIOUDP::DataPacketHdr::FNr, C4NetIOUDP::PacketList::GetPacket(), StdBuf::getSize(), C4NetIOUDP::iOPacketCounter, C4NetIOUDP::IPID_AddAddr, C4NetIOUDP::IPID_Check, C4NetIOUDP::IPID_Close, C4NetIOUDP::IPID_Conn, C4NetIOUDP::IPID_ConnOK, C4NetIOUDP::IPID_Data, C4NetIO::EndpointAddress::IsNull(), C4NetIOUDP::iUDPHeaderSize, C4NetIOUDP::CheckPacketHdr::MCAckNr, C4NetIOUDP::ConnPacket::MCAddr, C4NetIOUDP::CheckPacketHdr::MCAskCount, C4NetIOUDP::ConnOKPacket::MCM_MC, C4NetIOUDP::ConnOKPacket::MCM_MCOK, C4NetIOUDP::ConnOKPacket::MCM_NoMC, C4NetIOUDP::ConnOKPacket::MCMode, C4TimeMilliseconds::NegativeInfinity, C4NetIOUDP::AddAddrPacket::NewAddr, C4NetIOUDP::PacketHdr::Nr, C4NetIOUDP::OPackets, C4NetIOUDP::OutCSec, C4NetIOUDP::Packet, C4NetIOUDP::ConnPacket::ProtocolVer, C4NetIOUDP::SendDirect(), C4NetIOUDP::StatCSec, and C4NetIOUDP::PacketHdr::StatusByte.

Here is the call graph for this function:

◆ OnTimeout()

void C4NetIOUDP::Peer::OnTimeout ( )
protected

Definition at line 3636 of file C4NetIO.cpp.

3637 {
3638  // what state?
3639  if (eStatus == CS_Conn)
3640  {
3641  // retries left?
3642  if (iRetries)
3643  {
3644  int iRetryCnt = iRetries - 1;
3645  // call DoConn (will set timeout)
3646  DoConn(fMultiCast);
3647  // set retry count
3648  iRetries = iRetryCnt;
3649  return;
3650  }
3651  // connection timeout: close
3652  Close("connection timeout");
3653  }
3654  // reset timeout
3655  SetTimeout(TO_INF);
3656 }
unsigned int iRetries
Definition: C4NetIO.h:792

References C4NetIOUDP::Close(), C4NetIOUDP::fMultiCast, and C4NetIO::TO_INF.

Here is the call graph for this function:

◆ Open()

bool C4NetIOUDP::Peer::Open ( ) const
inline

Definition at line 817 of file C4NetIO.h.

817 { return eStatus == CS_Works; }

References CS_Works, and eStatus.

Referenced by C4NetIOUDP::Broadcast(), C4NetIOUDP::DoCheck(), and C4NetIOUDP::GetConnStatistic().

Here is the caller graph for this function:

◆ Send()

bool C4NetIOUDP::Peer::Send ( const C4NetIOPacket rPacket)

Definition at line 3188 of file C4NetIO.cpp.

3189 {
3190  CStdLock OutLock(&OutCSec);
3191  // encapsulate packet
3192  Packet *pnPacket = new Packet(rPacket.Duplicate(), iOPacketCounter);
3193  iOPacketCounter += pnPacket->FragmentCnt();
3194  pnPacket->GetData().SetAddr(addr);
3195  // add it to outgoing packet stack
3196  if (!OPackets.AddPacket(pnPacket))
3197  return false;
3198  // This should be ensured by calling function anyway.
3199  // It is not secure to send packets before the connection
3200  // is etablished completly.
3201  if (eStatus != CS_Works) return true;
3202  // send it
3203  if (!SendDirect(*pnPacket)) {
3204  Close("failed to send packet");
3205  return false;
3206  }
3207  return true;
3208 }
C4NetIOPacket Duplicate() const
Definition: C4NetIO.h:326
bool AddPacket(Packet *pPacket)
Definition: C4NetIO.cpp:3094

References C4NetIOUDP::PacketList::AddPacket(), C4NetIOUDP::Close(), C4NetIOPacket::Duplicate(), C4NetIOUDP::Packet::FragmentCnt(), C4NetIOUDP::Packet::GetData(), C4NetIOUDP::iOPacketCounter, C4NetIOUDP::OPackets, C4NetIOUDP::OutCSec, C4NetIOUDP::Packet, C4NetIOUDP::SendDirect(), and C4NetIOPacket::SetAddr().

Referenced by C4NetIOUDP::Broadcast(), and C4NetIOUDP::Send().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ SendDirect() [1/2]

bool C4NetIOUDP::Peer::SendDirect ( C4NetIOPacket &&  rPacket)
protected

Definition at line 3542 of file C4NetIO.cpp.

3543 {
3544  // insert correct addr
3545  C4NetIO::addr_t v6Addr(addr.AsIPv6());
3546  if (!(rPacket.getStatus() & 0x80)) rPacket.SetAddr(v6Addr);
3547  // count outgoing
3548  { CStdLock StatLock(&StatCSec); iORate += rPacket.getSize() + iUDPHeaderSize; }
3549  // forward call
3550  return pParent->SendDirect(std::move(rPacket));
3551 }
void SetAddr(const C4NetIO::addr_t &naddr)
Definition: C4NetIO.h:328
uint8_t getStatus() const
Definition: C4NetIO.h:319
bool SendDirect(C4NetIOPacket &&rPacket)
Definition: C4NetIO.cpp:3672
size_t getSize() const
Definition: StdBuf.h:101
EndpointAddress AsIPv6() const
Definition: C4NetIO.cpp:336

References C4NetIOUDP::iUDPHeaderSize, and C4NetIOUDP::StatCSec.

◆ SendDirect() [2/2]

bool C4NetIOUDP::Peer::SendDirect ( const Packet rPacket,
unsigned int  iNr = ~0 
)
protected

Definition at line 3530 of file C4NetIO.cpp.

3531 {
3532  // send one fragment only?
3533  if (iNr + 1)
3534  return SendDirect(rPacket.GetFragment(iNr - rPacket.GetNr()));
3535  // otherwise: send all fragments
3536  bool fSuccess = true;
3537  for (unsigned int i = 0; i < rPacket.FragmentCnt(); i++)
3538  fSuccess &= SendDirect(rPacket.GetFragment(i));
3539  return fSuccess;
3540 }

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

Here is the call graph for this function:

◆ SetAltAddr()

void C4NetIOUDP::Peer::SetAltAddr ( const C4NetIO::addr_t naddr2)
inline

Definition at line 836 of file C4NetIO.h.

836 { addr2 = naddr2; }

References addr2.

◆ SetBroadcast()

void C4NetIOUDP::Peer::SetBroadcast ( bool  fSet)
inline

Definition at line 833 of file C4NetIO.h.

833 { fDoBroadcast = fSet; }

References fDoBroadcast.

Referenced by C4NetIOUDP::SetBroadcast().

Here is the caller graph for this function:

◆ SetTimeout()

void C4NetIOUDP::Peer::SetTimeout ( int  iLength = iStdTimeout,
int  iRetryCnt = 0 
)
protected

Definition at line 3623 of file C4NetIO.cpp.

3624 {
3625  if (iLength != TO_INF)
3626  {
3627  tTimeout = C4TimeMilliseconds::Now() + iLength;
3628  }
3629  else
3630  {
3632  }
3633  iRetries = iRetryCnt;
3634 }

References C4TimeMilliseconds::Now(), C4TimeMilliseconds::PositiveInfinity, and C4NetIO::TO_INF.

Here is the call graph for this function:

Member Data Documentation

◆ addr

C4NetIO::addr_t C4NetIOUDP::Peer::addr
protected

Definition at line 754 of file C4NetIO.h.

Referenced by GetAddr().

◆ addr2

C4NetIO::addr_t C4NetIOUDP::Peer::addr2
protected

Definition at line 756 of file C4NetIO.h.

Referenced by GetAltAddr(), and SetAltAddr().

◆ eStatus

enum C4NetIOUDP::Peer::ConnStatus C4NetIOUDP::Peer::eStatus
protected

Referenced by Closed(), and Open().

◆ fConnFailCallback

bool C4NetIOUDP::Peer::fConnFailCallback
protected

Definition at line 770 of file C4NetIO.h.

◆ fDoBroadcast

bool C4NetIOUDP::Peer::fDoBroadcast
protected

Definition at line 768 of file C4NetIO.h.

Referenced by doBroadcast(), and SetBroadcast().

◆ fMultiCast

bool C4NetIOUDP::Peer::fMultiCast
protected

Definition at line 766 of file C4NetIO.h.

Referenced by MultiCast().

◆ iConnectRetries

const unsigned int C4NetIOUDP::Peer::iConnectRetries = 5
staticprotected

Definition at line 747 of file C4NetIO.h.

◆ iIMCPacketCounter

unsigned int C4NetIOUDP::Peer::iIMCPacketCounter
protected

Definition at line 779 of file C4NetIO.h.

◆ iIPacketCounter

unsigned int C4NetIOUDP::Peer::iIPacketCounter
protected

Definition at line 778 of file C4NetIO.h.

◆ iIRate

int C4NetIOUDP::Peer::iIRate
protected

Definition at line 795 of file C4NetIO.h.

Referenced by GetIRate().

◆ iLastMCPacketAsked

unsigned int C4NetIOUDP::Peer::iLastMCPacketAsked
protected

Definition at line 788 of file C4NetIO.h.

◆ iLastPacketAsked

unsigned int C4NetIOUDP::Peer::iLastPacketAsked
protected

Definition at line 788 of file C4NetIO.h.

◆ iLoss

int C4NetIOUDP::Peer::iLoss
protected

Definition at line 795 of file C4NetIO.h.

Referenced by GetLoss().

◆ iMCAckPacketCounter

unsigned int C4NetIOUDP::Peer::iMCAckPacketCounter
protected

Definition at line 781 of file C4NetIO.h.

Referenced by GetMCAckPacketCounter().

◆ IMCPackets

PacketList C4NetIOUDP::Peer::IMCPackets
protected

Definition at line 774 of file C4NetIO.h.

◆ iOPacketCounter

unsigned int C4NetIOUDP::Peer::iOPacketCounter
protected

Definition at line 777 of file C4NetIO.h.

◆ iORate

int C4NetIOUDP::Peer::iORate
protected

Definition at line 795 of file C4NetIO.h.

Referenced by GetORate().

◆ IPackets

PacketList C4NetIOUDP::Peer::IPackets
protected

Definition at line 774 of file C4NetIO.h.

◆ iReCheckInterval

const unsigned int C4NetIOUDP::Peer::iReCheckInterval = 1000
staticprotected

Definition at line 748 of file C4NetIO.h.

◆ iRetries

unsigned int C4NetIOUDP::Peer::iRetries
protected

Definition at line 792 of file C4NetIO.h.

◆ iRIMCPacketCounter

unsigned int C4NetIOUDP::Peer::iRIMCPacketCounter
protected

Definition at line 779 of file C4NetIO.h.

◆ iRIPacketCounter

unsigned int C4NetIOUDP::Peer::iRIPacketCounter
protected

Definition at line 778 of file C4NetIO.h.

◆ Next

◆ OPackets

PacketList C4NetIOUDP::Peer::OPackets
protected

Definition at line 773 of file C4NetIO.h.

◆ OutCSec

CStdCSec C4NetIOUDP::Peer::OutCSec
protected

Definition at line 784 of file C4NetIO.h.

◆ PeerAddr

addr_t C4NetIOUDP::Peer::PeerAddr
protected

Definition at line 758 of file C4NetIO.h.

◆ pParent

C4NetIOUDP* const C4NetIOUDP::Peer::pParent
protected

Definition at line 751 of file C4NetIO.h.

◆ StatCSec

CStdCSec C4NetIOUDP::Peer::StatCSec
protected

Definition at line 796 of file C4NetIO.h.

◆ tNextReCheck

C4TimeMilliseconds C4NetIOUDP::Peer::tNextReCheck
protected

Definition at line 787 of file C4NetIO.h.

◆ tTimeout

C4TimeMilliseconds C4NetIOUDP::Peer::tTimeout
protected

Definition at line 791 of file C4NetIO.h.

Referenced by GetTimeout().


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