OpenClonk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
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 718 of file C4NetIO.h.

Member Enumeration Documentation

Enumerator
CS_None 
CS_Conn 
CS_Works 
CS_Closed 

Definition at line 742 of file C4NetIO.h.

Constructor & Destructor Documentation

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

Definition at line 3127 of file C4NetIO.cpp.

3128  : pParent(pnParent), addr(naddr),
3129  eStatus(CS_None),
3130  fMultiCast(false), fDoBroadcast(false),
3132  iOPacketCounter(0),
3137  iIRate(0), iORate(0), iLoss(0)
3138 {
3139 }
unsigned int iMCAckPacketCounter
Definition: C4NetIO.h:763
C4NetIO::addr_t addr
Definition: C4NetIO.h:736
unsigned int iIMCPacketCounter
Definition: C4NetIO.h:761
static const unsigned int iMaxOPacketBacklog
Definition: C4NetIO.h:640
unsigned int iRIPacketCounter
Definition: C4NetIO.h:760
unsigned int iIPacketCounter
Definition: C4NetIO.h:760
C4NetIOUDP *const pParent
Definition: C4NetIO.h:733
enum C4NetIOUDP::Peer::ConnStatus eStatus
unsigned int iOPacketCounter
Definition: C4NetIO.h:759
bool fDoBroadcast
Definition: C4NetIO.h:750
PacketList OPackets
Definition: C4NetIO.h:755
unsigned int iRIMCPacketCounter
Definition: C4NetIO.h:761
C4TimeMilliseconds tNextReCheck
Definition: C4NetIO.h:769
C4NetIOUDP::Peer::~Peer ( )

Definition at line 3141 of file C4NetIO.cpp.

References C4NetIOUDP::Close().

3142 {
3143  // send close-packet
3144  Close("deleted");
3145 }
void Close(const char *szReason)
Definition: C4NetIO.cpp:3417

Here is the call graph for this function:

Member Function Documentation

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

Definition at line 3176 of file C4NetIO.cpp.

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

3177 {
3178  // only on working connections
3179  if (eStatus != CS_Works) return true;
3180  // prevent re-check (check floods)
3181  // instead, ask for other packets that are missing until recheck is allowed
3182  bool fNoReCheck = tNextReCheck > C4TimeMilliseconds::Now();
3183  if (!fNoReCheck) iLastPacketAsked = iLastMCPacketAsked = 0;
3184  unsigned int iStartAt = fNoReCheck ? std::max(iLastPacketAsked + 1, iIPacketCounter) : iIPacketCounter;
3185  unsigned int iStartAtMC = fNoReCheck ? std::max(iLastMCPacketAsked + 1, iIMCPacketCounter) : iIMCPacketCounter;
3186  // check if we have something to ask for
3187  const unsigned int iMaxAskCnt = 10;
3188  unsigned int i, iAskList[iMaxAskCnt], iAskCnt = 0, iMCAskCnt = 0;
3189  for (i = iStartAt; i < iRIPacketCounter; i++)
3190  if (!IPackets.FragmentPresent(i))
3191  if (iAskCnt < iMaxAskCnt)
3192  iLastPacketAsked = iAskList[iAskCnt++] = i;
3193  for (i = iStartAtMC; i < iRIMCPacketCounter; i++)
3194  if (!IMCPackets.FragmentPresent(i))
3195  if (iAskCnt + iMCAskCnt < iMaxAskCnt)
3196  iLastMCPacketAsked = iAskList[iAskCnt + iMCAskCnt++] = i;
3197  int iEAskCnt = iAskCnt + iMCAskCnt;
3198  // no re-check limit? set it
3199  if (!fNoReCheck)
3200  {
3201  if (iEAskCnt)
3203  else
3205  }
3206  // something to ask for? (or check forced?)
3207  if (iEAskCnt || fForceCheck)
3208  return DoCheck(iAskCnt, iMCAskCnt, iAskList);
3209  return true;
3210 }
unsigned int iLastMCPacketAsked
Definition: C4NetIO.h:770
unsigned int iLastPacketAsked
Definition: C4NetIO.h:770
unsigned int iIMCPacketCounter
Definition: C4NetIO.h:761
static const unsigned int iReCheckInterval
Definition: C4NetIO.h:730
bool DoCheck(int iAskCnt=0, int iMCAskCnt=0, unsigned int *pAskList=nullptr)
Definition: C4NetIO.cpp:3465
unsigned int iRIPacketCounter
Definition: C4NetIO.h:760
bool FragmentPresent(unsigned int iNr)
Definition: C4NetIO.cpp:3053
unsigned int iIPacketCounter
Definition: C4NetIO.h:760
PacketList IPackets
Definition: C4NetIO.h:756
enum C4NetIOUDP::Peer::ConnStatus eStatus
PacketList IMCPackets
Definition: C4NetIO.h:756
unsigned int iRIMCPacketCounter
Definition: C4NetIO.h:761
C4TimeMilliseconds tNextReCheck
Definition: C4NetIO.h:769
static C4TimeMilliseconds Now()

Here is the call graph for this function:

void C4NetIOUDP::Peer::CheckCompleteIPackets ( )
protected

Definition at line 3540 of file C4NetIO.cpp.

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

3541 {
3542  // only status CS_Works
3543  if (eStatus != CS_Works) return;
3544  // (If the status is CS_Conn, we'll have to wait until the connection in the
3545  // opposite direction is etablished. There is no problem in checking for
3546  // complete packets here, but the one using the interface may get very confused
3547  // if he gets a callback for a connection that hasn't been announced to him
3548  // yet)
3549 
3550  // check for complete incoming packets
3551  Packet *pPkt;
3552  while ((pPkt = IPackets.GetFirstPacketComplete()))
3553  {
3554  // missing packet?
3555  if (pPkt->GetNr() != iIPacketCounter) break;
3556  // do callback
3557  if (pParent->pCB)
3558  pParent->pCB->OnPacket(pPkt->GetData(), pParent);
3559  // advance packet counter
3560  iIPacketCounter = pPkt->GetNr() + pPkt->FragmentCnt();
3561  // remove packet from queue
3562  int iNr = pPkt->GetNr();
3563  IPackets.DeletePacket(pPkt);
3564  assert(!IPackets.GetPacketFrgm(iNr)); (void)iNr;
3565  }
3566  while ((pPkt = IMCPackets.GetFirstPacketComplete()))
3567  {
3568  // missing packet?
3569  if (pPkt->GetNr() != iIMCPacketCounter) break;
3570  // do callback
3571  if (pParent->pCB)
3572  pParent->pCB->OnPacket(pPkt->GetData(), pParent);
3573  // advance packet counter
3574  iIMCPacketCounter = pPkt->GetNr() + pPkt->FragmentCnt();
3575  // remove packet from queue
3576  int iNr = pPkt->GetNr();
3577  IMCPackets.DeletePacket(pPkt);
3578  assert(!IMCPackets.GetPacketFrgm(iNr)); (void)iNr;
3579  }
3580 }
friend class Packet
Definition: C4NetIO.h:688
unsigned int iIMCPacketCounter
Definition: C4NetIO.h:761
Packet * GetFirstPacketComplete()
Definition: C4NetIO.cpp:3047
unsigned int iIPacketCounter
Definition: C4NetIO.h:760
PacketList IPackets
Definition: C4NetIO.h:756
C4NetIOUDP *const pParent
Definition: C4NetIO.h:733
enum C4NetIOUDP::Peer::ConnStatus eStatus
bool DeletePacket(Packet *pPacket)
Definition: C4NetIO.cpp:3084
Packet * GetPacketFrgm(unsigned int iNr)
Definition: C4NetIO.cpp:3036
PacketList IMCPackets
Definition: C4NetIO.h:756

Here is the call graph for this function:

void C4NetIOUDP::Peer::CheckTimeout ( )

Definition at line 3432 of file C4NetIO.cpp.

References C4TimeMilliseconds::Now().

3433 {
3434  // check
3436  OnTimeout();
3437 }
C4TimeMilliseconds tTimeout
Definition: C4NetIO.h:773
static C4TimeMilliseconds Now()

Here is the call graph for this function:

void C4NetIOUDP::Peer::ClearStatistics ( )

Definition at line 3439 of file C4NetIO.cpp.

References C4NetIOUDP::StatCSec.

3440 {
3441  CStdLock StatLock(&StatCSec);
3442  iIRate = iORate = 0;
3443  iLoss = 0;
3444 }
CStdCSec StatCSec
Definition: C4NetIO.h:778
void C4NetIOUDP::Peer::Close ( const char *  szReason)

Definition at line 3417 of file C4NetIO.cpp.

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().

3418 {
3419  // already closed?
3420  if (eStatus == CS_Closed)
3421  return;
3422  // send close-packet
3423  ClosePacket Pkt;
3424  Pkt.StatusByte = IPID_Close;
3425  Pkt.Nr = 0;
3426  Pkt.Addr = addr;
3427  SendDirect(C4NetIOPacket(&Pkt, sizeof(Pkt), false, addr));
3428  // callback
3429  OnClose(szReason);
3430 }
C4NetIO::addr_t addr
Definition: C4NetIO.h:736
void OnClose(const char *szReason)
Definition: C4NetIO.cpp:3529
enum C4NetIOUDP::Peer::ConnStatus eStatus
bool SendDirect(const Packet &rPacket, unsigned int iNr=~0)
Definition: C4NetIO.cpp:3489

Here is the call graph for this function:

Here is the caller graph for this function:

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

Definition at line 801 of file C4NetIO.h.

References CS_Closed, and eStatus.

Referenced by C4NetIOUDP::OnShareFree().

801 { return eStatus == CS_Closed; }
enum C4NetIOUDP::Peer::ConnStatus eStatus

Here is the caller graph for this function:

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

Definition at line 3147 of file C4NetIO.cpp.

References C4NetIOUDP::fMultiCast.

Referenced by C4NetIOUDP::ConnectPeer().

3148 {
3149  // initiate connection (DoConn will set status CS_Conn)
3150  fMultiCast = false; fConnFailCallback = fFailCallback;
3151  return DoConn(false);
3152 }
bool DoConn(bool fMC)
Definition: C4NetIO.cpp:3446
bool fConnFailCallback
Definition: C4NetIO.h:752

Here is the caller graph for this function:

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

Definition at line 813 of file C4NetIO.h.

References fDoBroadcast.

Referenced by C4NetIOUDP::Broadcast().

813 { return fDoBroadcast; }
bool fDoBroadcast
Definition: C4NetIO.h:750

Here is the caller graph for this function:

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

Definition at line 3465 of file C4NetIO.cpp.

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

3466 {
3467  // security
3468  if (!pAskList) iAskCnt = iMCAskCnt = 0;
3469  // statistics
3470  { CStdLock StatLock(&StatCSec); iLoss += iAskCnt + iMCAskCnt; }
3471  // alloc data
3472  int iAskListSize = (iAskCnt + iMCAskCnt) * sizeof(*pAskList);
3473  StdBuf Packet; Packet.New(sizeof(CheckPacketHdr) + iAskListSize);
3474  CheckPacketHdr *pChkPkt = getMBufPtr<CheckPacketHdr>(Packet);
3475  // set up header
3476  pChkPkt->StatusByte = IPID_Check; // (note: always du here, see C4NetIOUDP::DoCheck)
3477  pChkPkt->Nr = iOPacketCounter;
3478  pChkPkt->AckNr = iIPacketCounter;
3479  pChkPkt->MCAckNr = iIMCPacketCounter;
3480  // copy ask list
3481  pChkPkt->AskCount = iAskCnt;
3482  pChkPkt->MCAskCount = iMCAskCnt;
3483  if (pAskList)
3484  Packet.Write(pAskList, iAskListSize, sizeof(CheckPacketHdr));
3485  // send packet
3486  return SendDirect(C4NetIOPacket(Packet, addr));
3487 }
C4NetIO::addr_t addr
Definition: C4NetIO.h:736
Definition: StdBuf.h:37
friend class Packet
Definition: C4NetIO.h:688
unsigned int iIMCPacketCounter
Definition: C4NetIO.h:761
unsigned int iIPacketCounter
Definition: C4NetIO.h:760
void New(size_t inSize)
Definition: StdBuf.h:154
void Write(const void *pnData, size_t inSize, size_t iAt=0)
Definition: StdBuf.h:161
unsigned int iOPacketCounter
Definition: C4NetIO.h:759
CStdCSec StatCSec
Definition: C4NetIO.h:778
bool SendDirect(const Packet &rPacket, unsigned int iNr=~0)
Definition: C4NetIO.cpp:3489

Here is the call graph for this function:

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

Definition at line 3446 of file C4NetIO.cpp.

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.

3447 {
3448  // set status
3449  eStatus = CS_Conn;
3450  // set timeout
3452  // send packet (include current outgoing packet counter and mc addr)
3453  ConnPacket Pkt;
3454  Pkt.StatusByte = uint8_t(IPID_Conn) | (fMC ? 0x80 : 0x00);
3455  Pkt.ProtocolVer = pParent->iVersion;
3456  Pkt.Nr = fMC ? pParent->iOPacketCounter : iOPacketCounter;
3457  Pkt.Addr = addr;
3458  if (pParent->fMultiCast)
3459  Pkt.MCAddr = pParent->C4NetIOSimpleUDP::getMCAddr();
3460  else
3461  Pkt.MCAddr = C4NetIO::addr_t();
3462  return SendDirect(C4NetIOPacket(&Pkt, sizeof(Pkt), false, addr));
3463 }
C4NetIO::addr_t addr
Definition: C4NetIO.h:736
void SetTimeout(int iLength=iStdTimeout, int iRetryCnt=0)
Definition: C4NetIO.cpp:3582
static const unsigned int iVersion
Definition: C4NetIO.h:632
C4NetIOUDP *const pParent
Definition: C4NetIO.h:733
unsigned int iOPacketCounter
Definition: C4NetIO.h:879
enum C4NetIOUDP::Peer::ConnStatus eStatus
EndpointAddress addr_t
Definition: C4NetIO.h:212
bool fMultiCast
Definition: C4NetIO.h:860
unsigned int iOPacketCounter
Definition: C4NetIO.h:759
bool SendDirect(const Packet &rPacket, unsigned int iNr=~0)
Definition: C4NetIO.cpp:3489
static const unsigned int iStdTimeout
Definition: C4NetIO.h:637
static const unsigned int iConnectRetries
Definition: C4NetIO.h:729

Here is the call graph for this function:

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

Definition at line 782 of file C4NetIO.h.

References addr.

782 { return addr; }
C4NetIO::addr_t addr
Definition: C4NetIO.h:736
const C4NetIO::addr_t& C4NetIOUDP::Peer::GetAltAddr ( ) const
inline

Definition at line 783 of file C4NetIO.h.

References addr2.

783 { return addr2; }
C4NetIO::addr_t addr2
Definition: C4NetIO.h:738
int C4NetIOUDP::Peer::GetIRate ( ) const
inline

Definition at line 821 of file C4NetIO.h.

References iIRate.

Referenced by C4NetIOUDP::GetConnStatistic().

821 { return iIRate; }

Here is the caller graph for this function:

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

Definition at line 823 of file C4NetIO.h.

References iLoss.

823 { return iLoss; }
unsigned int C4NetIOUDP::Peer::GetMCAckPacketCounter ( ) const
inline

Definition at line 806 of file C4NetIO.h.

References iMCAckPacketCounter.

Referenced by C4NetIOUDP::ClearMCPackets().

806 { return iMCAckPacketCounter; }
unsigned int iMCAckPacketCounter
Definition: C4NetIO.h:763

Here is the caller graph for this function:

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

Definition at line 822 of file C4NetIO.h.

References iORate.

Referenced by C4NetIOUDP::GetConnStatistic().

822 { return iORate; }

Here is the caller graph for this function:

C4TimeMilliseconds C4NetIOUDP::Peer::GetTimeout ( )
inline

Definition at line 809 of file C4NetIO.h.

References tTimeout.

809 { return tTimeout; }
C4TimeMilliseconds tTimeout
Definition: C4NetIO.h:773
bool C4NetIOUDP::Peer::MultiCast ( ) const
inline

Definition at line 803 of file C4NetIO.h.

References fMultiCast.

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

803 { return fMultiCast; }

Here is the caller graph for this function:

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

Definition at line 3529 of file C4NetIO.cpp.

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

3530 {
3531  // do callback
3532  C4NetIO::CBClass *pCB = pParent->pCB;
3533  if (eStatus == CS_Works || (eStatus == CS_Conn && fConnFailCallback))
3534  if (pCB)
3535  pCB->OnDisconn(addr, pParent, szReason);
3536  // set status (this will schedule this peer for deletion)
3537  eStatus = CS_Closed;
3538 }
C4NetIO::addr_t addr
Definition: C4NetIO.h:736
C4NetIOUDP *const pParent
Definition: C4NetIO.h:733
bool fConnFailCallback
Definition: C4NetIO.h:752
enum C4NetIOUDP::Peer::ConnStatus eStatus
virtual void OnDisconn(const addr_t &AddrPeer, C4NetIO *pNetIO, const char *szReason)
Definition: C4NetIO.h:221

Here is the call graph for this function:

void C4NetIOUDP::Peer::OnConn ( )
protected

Definition at line 3512 of file C4NetIO.cpp.

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

3513 {
3514  // reset timeout
3515  SetTimeout(TO_INF);
3516  // set status
3517  eStatus = CS_Works;
3518  // do callback
3519  C4NetIO::CBClass *pCB = pParent->pCB;
3520  if (pCB && !pCB->OnConn(addr, addr, &PeerAddr, pParent))
3521  {
3522  Close("closed");
3523  return;
3524  }
3525  // do packet callback (in case the peer sent data while the connection was in progress)
3527 }
C4NetIO::addr_t addr
Definition: C4NetIO.h:736
addr_t PeerAddr
Definition: C4NetIO.h:740
void SetTimeout(int iLength=iStdTimeout, int iRetryCnt=0)
Definition: C4NetIO.cpp:3582
virtual bool OnConn(const addr_t &AddrPeer, const addr_t &AddrConnect, const addr_t *pOwnAddr, C4NetIO *pNetIO)
Definition: C4NetIO.h:220
void Close(const char *szReason)
Definition: C4NetIO.cpp:3417
C4NetIOUDP *const pParent
Definition: C4NetIO.h:733
void CheckCompleteIPackets()
Definition: C4NetIO.cpp:3540
enum C4NetIOUDP::Peer::ConnStatus eStatus
static const int TO_INF
Definition: C4NetIO.h:67

Here is the call graph for this function:

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

Definition at line 3212 of file C4NetIO.cpp.

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, 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.

3213 {
3214  // statistics
3215  { CStdLock StatLock(&StatCSec); iIRate += rPacket.getSize() + iUDPHeaderSize; }
3216  // get packet header
3217  if (rPacket.getSize() < sizeof(PacketHdr)) return;
3218  const PacketHdr *pHdr = getBufPtr<PacketHdr>(rPacket);
3219  bool fBroadcasted = !!(pHdr->StatusByte & 0x80);
3220  // save packet nr
3221  (fBroadcasted ? iRIMCPacketCounter : iRIPacketCounter) = std::max<unsigned int>((fBroadcasted ? iRIMCPacketCounter : iRIPacketCounter), pHdr->Nr);
3222 #ifdef C4NETIOUDP_OPT_RECV_CHECK_IMMEDIATE
3223  // do check
3224  if (eStatus == CS_Works)
3225  Check(false);
3226 #endif
3227  // what type of packet is it?
3228  switch (pHdr->StatusByte & 0x7f)
3229  {
3230 
3231  case IPID_Conn:
3232  {
3233  // check size
3234  if (rPacket.getSize() != sizeof(ConnPacket)) break;
3235  const ConnPacket *pPkt = getBufPtr<ConnPacket>(rPacket);
3236  // right version?
3237  if (pPkt->ProtocolVer != pParent->iVersion) break;
3238  if (!fBroadcasted)
3239  {
3240  // Second connection attempt using different address?
3241  if (!PeerAddr.IsNull() && PeerAddr != pPkt->Addr)
3242  {
3243  // Notify peer that he has two addresses to reach this connection.
3244  AddAddrPacket Pkt;
3245  Pkt.StatusByte = IPID_AddAddr;
3246  Pkt.Nr = iOPacketCounter;
3247  Pkt.Addr = PeerAddr;
3248  Pkt.NewAddr = pPkt->Addr;
3249  SendDirect(C4NetIOPacket(&Pkt, sizeof(Pkt), false, addr));
3250  // But do nothing else - don't interfere with this connection
3251  break;
3252  }
3253  // reinit?
3254  else if (eStatus == CS_Works && iIPacketCounter != pPkt->Nr)
3255  {
3256  // close (callback!) ...
3257  OnClose("reconnect"); eStatus = CS_Closed;
3258  // ... and reconnect
3259  Connect(false);
3260  }
3261  // save back the address the peer is using
3262  PeerAddr = pPkt->Addr;
3263  }
3264  // set packet counter
3265  if (fBroadcasted)
3267  else
3268  iRIPacketCounter = iIPacketCounter = pPkt->Nr;
3269  // clear incoming packets
3270  IPackets.Clear();
3271  IMCPackets.Clear();
3272 
3274 
3276  // Activate Multicast?
3277  if (!pParent->fMultiCast)
3278  {
3279  addr_t MCAddr = pPkt->MCAddr;
3280  if (!MCAddr.IsNull())
3281  {
3282  // Init Broadcast (with delayed loopback test)
3283  pParent->fDelayedLoopbackTest = true;
3284  if (!pParent->InitBroadcast(&MCAddr))
3285  pParent->fDelayedLoopbackTest = false;
3286  }
3287  }
3288  // build ConnOk Packet
3289  ConnOKPacket nPack;
3290 
3291  nPack.StatusByte = IPID_ConnOK; // (always du, no mc experiments here)
3292  nPack.Nr = fBroadcasted ? pParent->iOPacketCounter : iOPacketCounter;
3293  nPack.Addr = addr;
3294  if (fBroadcasted)
3295  nPack.MCMode = ConnOKPacket::MCM_MCOK; // multicast send ok
3296  else if (pParent->fMultiCast && addr.GetPort() == pParent->iPort)
3297  nPack.MCMode = ConnOKPacket::MCM_MC; // du ok, try multicast next
3298  else
3299  nPack.MCMode = ConnOKPacket::MCM_NoMC; // du ok
3300  // send it
3301  SendDirect(C4NetIOPacket(&nPack, sizeof(nPack), false, addr));
3302  }
3303  break;
3304 
3305  case IPID_ConnOK:
3306  {
3307  if (eStatus != CS_Conn) break;
3308  // check size
3309  if (rPacket.getSize() != sizeof(ConnOKPacket)) break;
3310  const ConnOKPacket *pPkt = getBufPtr<ConnOKPacket>(rPacket);
3311  // save port
3312  PeerAddr = pPkt->Addr;
3313  // Needs another Conn/ConnOK-sequence?
3314  switch (pPkt->MCMode)
3315  {
3316  case ConnOKPacket::MCM_MC:
3317  // multicast has to be active
3318  if (pParent->fMultiCast)
3319  {
3320  // already trying to connect via multicast?
3321  if (fMultiCast) break;
3322  // Send another Conn packet back (this time broadcasted to check if multicast works)
3323  fMultiCast = true; DoConn(true);
3324  break;
3325  }
3326  // fallthru
3328  // Connection is established (no multicast support)
3329  fMultiCast = false; OnConn();
3330  break;
3332  // Connection is established (multicast support)
3333  fMultiCast = true; OnConn();
3334  break;
3335  }
3336  }
3337  break;
3338 
3339  case IPID_Data:
3340  {
3341  // get the packet header
3342  if (rPacket.getSize() < sizeof(DataPacketHdr)) return;
3343  const DataPacketHdr *pHdr = getBufPtr<DataPacketHdr>(rPacket);
3344  // already complet?
3345  if (pHdr->Nr < (fBroadcasted ? iIMCPacketCounter : iIPacketCounter)) break;
3346  // find or create packet
3347  bool fAddPacket = false;
3348  PacketList *pPacketList = fBroadcasted ? &IMCPackets : &IPackets;
3349  Packet *pPkt = pPacketList->GetPacket(pHdr->FNr);
3350  if (!pPkt) { pPkt = new Packet(); fAddPacket = true; }
3351  // add the fragment
3352  if (pPkt->AddFragment(rPacket, addr))
3353  {
3354  // add the packet to list
3355  if (fAddPacket) if (!pPacketList->AddPacket(pPkt)) { delete pPkt; break; }
3356  // check for complete packets
3358  }
3359  else
3360  // delete the packet
3361  if (fAddPacket) delete pPkt;
3362  }
3363  break;
3364 
3365  case IPID_Check:
3366  {
3367  // get the packet header
3368  if (rPacket.getSize() < sizeof(CheckPacketHdr)) break;
3369  const CheckPacketHdr *pPkt = getBufPtr<CheckPacketHdr>(rPacket);
3370  // check packet size
3371  if (rPacket.getSize() < sizeof(CheckPacketHdr) + (pPkt->AskCount + pPkt->MCAskCount) * sizeof(int)) break;
3372  // clear all acknowledged packets
3373  CStdLock OutLock(&OutCSec);
3374  OPackets.ClearPackets(pPkt->AckNr);
3375  if (pPkt->MCAckNr > iMCAckPacketCounter)
3376  {
3377  iMCAckPacketCounter = pPkt->MCAckNr;
3379  }
3380  OutLock.Clear();
3381  // read ask list
3382  const int *pAskList = getBufPtr<int>(rPacket, sizeof(CheckPacketHdr));
3383  // send the packets he asks for
3384  unsigned int i;
3385  for (i = 0; i < pPkt->AskCount + pPkt->MCAskCount; i++)
3386  {
3387  // packet available?
3388  bool fMCPacket = i >= pPkt->AskCount;
3389  CStdLock OutLock(fMCPacket ? &pParent->OutCSec : &OutCSec);
3390  Packet *pPkt2Send = (fMCPacket ? pParent->OPackets : OPackets).GetPacketFrgm(pAskList[i]);
3391  if (!pPkt2Send) { Close("starvation"); break; }
3392  // send the fragment
3393  if (fMCPacket)
3394  pParent->BroadcastDirect(*pPkt2Send, pAskList[i]);
3395  else
3396  SendDirect(*pPkt2Send, pAskList[i]);
3397  }
3398  }
3399  break;
3400 
3401  case IPID_Close:
3402  {
3403  // check packet size
3404  if (rPacket.getSize() < sizeof(ClosePacket)) break;
3405  const ClosePacket *pPkt = getBufPtr<ClosePacket>(rPacket);
3406  // ignore if it's for another address
3407  if (!PeerAddr.IsNull() && PeerAddr != pPkt->Addr)
3408  break;
3409  // close
3410  OnClose("connection closed by peer");
3411  }
3412  break;
3413 
3414  }
3415 }
unsigned int iMCAckPacketCounter
Definition: C4NetIO.h:763
C4NetIO::addr_t addr
Definition: C4NetIO.h:736
unsigned int iLastMCPacketAsked
Definition: C4NetIO.h:770
addr_t PeerAddr
Definition: C4NetIO.h:740
friend class Packet
Definition: C4NetIO.h:688
unsigned int iLastPacketAsked
Definition: C4NetIO.h:770
PacketList OPackets
Definition: C4NetIO.h:878
void OnClose(const char *szReason)
Definition: C4NetIO.cpp:3529
unsigned int iIMCPacketCounter
Definition: C4NetIO.h:761
CStdCSec OutCSec
Definition: C4NetIO.h:856
static const unsigned int iUDPHeaderSize
Definition: C4NetIO.h:642
virtual bool InitBroadcast(addr_t *pBroadcastAddr)
Definition: C4NetIO.cpp:2463
unsigned int iRIPacketCounter
Definition: C4NetIO.h:760
bool Check(bool fForceCheck=true)
Definition: C4NetIO.cpp:3176
void Close(const char *szReason)
Definition: C4NetIO.cpp:3417
unsigned int iIPacketCounter
Definition: C4NetIO.h:760
PacketList IPackets
Definition: C4NetIO.h:756
bool DoConn(bool fMC)
Definition: C4NetIO.cpp:3446
static const unsigned int iVersion
Definition: C4NetIO.h:632
bool fDelayedLoopbackTest
Definition: C4NetIO.h:872
friend class PacketList
Definition: C4NetIO.h:715
uint16_t iPort
Definition: C4NetIO.h:861
C4NetIOUDP *const pParent
Definition: C4NetIO.h:733
unsigned int iOPacketCounter
Definition: C4NetIO.h:879
void CheckCompleteIPackets()
Definition: C4NetIO.cpp:3540
enum C4NetIOUDP::Peer::ConnStatus eStatus
bool BroadcastDirect(const Packet &rPacket, unsigned int iNr=~0u)
Definition: C4NetIO.cpp:3619
EndpointAddress addr_t
Definition: C4NetIO.h:212
bool fMultiCast
Definition: C4NetIO.h:860
void ClearMCPackets()
Definition: C4NetIO.cpp:3697
unsigned int iOPacketCounter
Definition: C4NetIO.h:759
CStdCSec StatCSec
Definition: C4NetIO.h:778
CStdCSec OutCSec
Definition: C4NetIO.h:766
bool SendDirect(const Packet &rPacket, unsigned int iNr=~0)
Definition: C4NetIO.cpp:3489
bool Connect(bool fFailCallback)
Definition: C4NetIO.cpp:3147
PacketList IMCPackets
Definition: C4NetIO.h:756
void ClearPackets(unsigned int iUntil)
Definition: C4NetIO.cpp:3104
PacketList OPackets
Definition: C4NetIO.h:755
unsigned int iRIMCPacketCounter
Definition: C4NetIO.h:761
uint16_t GetPort() const
Definition: C4NetIO.cpp:548
C4TimeMilliseconds tNextReCheck
Definition: C4NetIO.h:769

Here is the call graph for this function:

void C4NetIOUDP::Peer::OnTimeout ( )
protected

Definition at line 3595 of file C4NetIO.cpp.

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

3596 {
3597  // what state?
3598  if (eStatus == CS_Conn)
3599  {
3600  // retries left?
3601  if (iRetries)
3602  {
3603  int iRetryCnt = iRetries - 1;
3604  // call DoConn (will set timeout)
3605  DoConn(fMultiCast);
3606  // set retry count
3607  iRetries = iRetryCnt;
3608  return;
3609  }
3610  // connection timeout: close
3611  Close("connection timeout");
3612  }
3613  // reset timeout
3614  SetTimeout(TO_INF);
3615 }
unsigned int iRetries
Definition: C4NetIO.h:774
void SetTimeout(int iLength=iStdTimeout, int iRetryCnt=0)
Definition: C4NetIO.cpp:3582
void Close(const char *szReason)
Definition: C4NetIO.cpp:3417
bool DoConn(bool fMC)
Definition: C4NetIO.cpp:3446
enum C4NetIOUDP::Peer::ConnStatus eStatus
static const int TO_INF
Definition: C4NetIO.h:67

Here is the call graph for this function:

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

Definition at line 799 of file C4NetIO.h.

References CS_Works, and eStatus.

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

799 { return eStatus == CS_Works; }
enum C4NetIOUDP::Peer::ConnStatus eStatus

Here is the caller graph for this function:

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

Definition at line 3154 of file C4NetIO.cpp.

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().

3155 {
3156  CStdLock OutLock(&OutCSec);
3157  // encapsulate packet
3158  Packet *pnPacket = new Packet(rPacket.Duplicate(), iOPacketCounter);
3159  iOPacketCounter += pnPacket->FragmentCnt();
3160  pnPacket->GetData().SetAddr(addr);
3161  // add it to outgoing packet stack
3162  if (!OPackets.AddPacket(pnPacket))
3163  return false;
3164  // This should be ensured by calling function anyway.
3165  // It is not secure to send packets before the connection
3166  // is etablished completly.
3167  if (eStatus != CS_Works) return true;
3168  // send it
3169  if (!SendDirect(*pnPacket)) {
3170  Close("failed to send packet");
3171  return false;
3172  }
3173  return true;
3174 }
C4NetIO::addr_t addr
Definition: C4NetIO.h:736
friend class Packet
Definition: C4NetIO.h:688
bool AddPacket(Packet *pPacket)
Definition: C4NetIO.cpp:3060
void Close(const char *szReason)
Definition: C4NetIO.cpp:3417
enum C4NetIOUDP::Peer::ConnStatus eStatus
unsigned int iOPacketCounter
Definition: C4NetIO.h:759
CStdCSec OutCSec
Definition: C4NetIO.h:766
bool SendDirect(const Packet &rPacket, unsigned int iNr=~0)
Definition: C4NetIO.cpp:3489
PacketList OPackets
Definition: C4NetIO.h:755
C4NetIOPacket Duplicate() const
Definition: C4NetIO.h:325

Here is the call graph for this function:

Here is the caller graph for this function:

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

Definition at line 3489 of file C4NetIO.cpp.

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

3490 {
3491  // send one fragment only?
3492  if (iNr + 1)
3493  return SendDirect(rPacket.GetFragment(iNr - rPacket.GetNr()));
3494  // otherwise: send all fragments
3495  bool fSuccess = true;
3496  for (unsigned int i = 0; i < rPacket.FragmentCnt(); i++)
3497  fSuccess &= SendDirect(rPacket.GetFragment(i));
3498  return fSuccess;
3499 }
bool SendDirect(const Packet &rPacket, unsigned int iNr=~0)
Definition: C4NetIO.cpp:3489

Here is the call graph for this function:

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

Definition at line 3501 of file C4NetIO.cpp.

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

3502 {
3503  // insert correct addr
3504  C4NetIO::addr_t v6Addr(addr.AsIPv6());
3505  if (!(rPacket.getStatus() & 0x80)) rPacket.SetAddr(v6Addr);
3506  // count outgoing
3507  { CStdLock StatLock(&StatCSec); iORate += rPacket.getSize() + iUDPHeaderSize; }
3508  // forward call
3509  return pParent->SendDirect(std::move(rPacket));
3510 }
C4NetIO::addr_t addr
Definition: C4NetIO.h:736
static const unsigned int iUDPHeaderSize
Definition: C4NetIO.h:642
size_t getSize() const
Definition: StdBuf.h:109
C4NetIOUDP *const pParent
Definition: C4NetIO.h:733
uint8_t getStatus() const
Definition: C4NetIO.h:318
CStdCSec StatCSec
Definition: C4NetIO.h:778
EndpointAddress AsIPv6() const
Definition: C4NetIO.cpp:342
bool SendDirect(C4NetIOPacket &&rPacket)
Definition: C4NetIO.cpp:3631
void SetAddr(const C4NetIO::addr_t &naddr)
Definition: C4NetIO.h:327
void C4NetIOUDP::Peer::SetAltAddr ( const C4NetIO::addr_t naddr2)
inline

Definition at line 818 of file C4NetIO.h.

818 { addr2 = naddr2; }
C4NetIO::addr_t addr2
Definition: C4NetIO.h:738
void C4NetIOUDP::Peer::SetBroadcast ( bool  fSet)
inline

Definition at line 815 of file C4NetIO.h.

Referenced by C4NetIOUDP::SetBroadcast().

815 { fDoBroadcast = fSet; }
bool fDoBroadcast
Definition: C4NetIO.h:750

Here is the caller graph for this function:

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

Definition at line 3582 of file C4NetIO.cpp.

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

3583 {
3584  if (iLength != TO_INF)
3585  {
3586  tTimeout = C4TimeMilliseconds::Now() + iLength;
3587  }
3588  else
3589  {
3591  }
3592  iRetries = iRetryCnt;
3593 }
unsigned int iRetries
Definition: C4NetIO.h:774
C4TimeMilliseconds tTimeout
Definition: C4NetIO.h:773
static const int TO_INF
Definition: C4NetIO.h:67
static C4TimeMilliseconds Now()

Here is the call graph for this function:

Member Data Documentation

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

Definition at line 736 of file C4NetIO.h.

Referenced by GetAddr().

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

Definition at line 738 of file C4NetIO.h.

Referenced by GetAltAddr().

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

Referenced by Closed(), and Open().

bool C4NetIOUDP::Peer::fConnFailCallback
protected

Definition at line 752 of file C4NetIO.h.

bool C4NetIOUDP::Peer::fDoBroadcast
protected

Definition at line 750 of file C4NetIO.h.

Referenced by doBroadcast().

bool C4NetIOUDP::Peer::fMultiCast
protected

Definition at line 748 of file C4NetIO.h.

Referenced by MultiCast().

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

Definition at line 729 of file C4NetIO.h.

unsigned int C4NetIOUDP::Peer::iIMCPacketCounter
protected

Definition at line 761 of file C4NetIO.h.

unsigned int C4NetIOUDP::Peer::iIPacketCounter
protected

Definition at line 760 of file C4NetIO.h.

int C4NetIOUDP::Peer::iIRate
protected

Definition at line 777 of file C4NetIO.h.

Referenced by GetIRate().

unsigned int C4NetIOUDP::Peer::iLastMCPacketAsked
protected

Definition at line 770 of file C4NetIO.h.

unsigned int C4NetIOUDP::Peer::iLastPacketAsked
protected

Definition at line 770 of file C4NetIO.h.

int C4NetIOUDP::Peer::iLoss
protected

Definition at line 777 of file C4NetIO.h.

Referenced by GetLoss().

unsigned int C4NetIOUDP::Peer::iMCAckPacketCounter
protected

Definition at line 763 of file C4NetIO.h.

Referenced by GetMCAckPacketCounter().

PacketList C4NetIOUDP::Peer::IMCPackets
protected

Definition at line 756 of file C4NetIO.h.

unsigned int C4NetIOUDP::Peer::iOPacketCounter
protected

Definition at line 759 of file C4NetIO.h.

int C4NetIOUDP::Peer::iORate
protected

Definition at line 777 of file C4NetIO.h.

Referenced by GetORate().

PacketList C4NetIOUDP::Peer::IPackets
protected

Definition at line 756 of file C4NetIO.h.

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

Definition at line 730 of file C4NetIO.h.

unsigned int C4NetIOUDP::Peer::iRetries
protected

Definition at line 774 of file C4NetIO.h.

unsigned int C4NetIOUDP::Peer::iRIMCPacketCounter
protected

Definition at line 761 of file C4NetIO.h.

unsigned int C4NetIOUDP::Peer::iRIPacketCounter
protected

Definition at line 760 of file C4NetIO.h.

PacketList C4NetIOUDP::Peer::OPackets
protected

Definition at line 755 of file C4NetIO.h.

CStdCSec C4NetIOUDP::Peer::OutCSec
protected

Definition at line 766 of file C4NetIO.h.

addr_t C4NetIOUDP::Peer::PeerAddr
protected

Definition at line 740 of file C4NetIO.h.

C4NetIOUDP* const C4NetIOUDP::Peer::pParent
protected

Definition at line 733 of file C4NetIO.h.

CStdCSec C4NetIOUDP::Peer::StatCSec
protected

Definition at line 778 of file C4NetIO.h.

C4TimeMilliseconds C4NetIOUDP::Peer::tNextReCheck
protected

Definition at line 769 of file C4NetIO.h.

C4TimeMilliseconds C4NetIOUDP::Peer::tTimeout
protected

Definition at line 773 of file C4NetIO.h.

Referenced by GetTimeout().


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