bool C4Network2Client::DoConnectAttempt(C4Network2IO *pIO) { // local? if (isLocal()) { iNextConnAttempt = 0; return true; } // msg and data connected? Nothing to do if (getMsgConn() != getDataConn()) { iNextConnAttempt = time(NULL) + 10; return true; } // too early? if (iNextConnAttempt && iNextConnAttempt > time(NULL)) return true; // find address to try int32_t iBestAddress = -1; for (int32_t i = 0; i < iAddrCnt; i++) // no connection for this protocol? if ((!pDataConn || Addr[i].getProtocol() != pDataConn->getProtocol()) && (!pMsgConn || Addr[i].getProtocol() != pMsgConn->getProtocol())) // protocol available? if (pIO->getNetIO(Addr[i].getProtocol())) // new best address? if (iBestAddress < 0 || AddrAttempts[i] < AddrAttempts[iBestAddress]) iBestAddress = i; // too many attempts or nothing found? if (iBestAddress < 0 || AddrAttempts[iBestAddress] > C4NetClientConnectAttempts) { iNextConnAttempt = time(NULL) + 10; return true; } // save attempt AddrAttempts[iBestAddress]++; iNextConnAttempt = time(NULL) + C4NetClientConnectInterval; // log LogSilentF("Network: connecting client %s on %s...", getName(), Addr[iBestAddress].toString().getData()); // connect return pIO->Connect(Addr[iBestAddress].getAddr(), Addr[iBestAddress].getProtocol(), pClient->getCore()); }
bool C4Network2Client::DoConnectAttempt(C4Network2IO *pIO) { // local? if (isLocal()) { iNextConnAttempt = 0; return true; } // msg and data connected? Nothing to do if (getMsgConn() != getDataConn()) { iNextConnAttempt = time(nullptr) + 10; return true; } // too early? if (iNextConnAttempt && iNextConnAttempt > time(nullptr)) return true; // find address to try int32_t iBestAddress = -1; for (int32_t i = 0; i < iAddrCnt; i++) // no connection for this protocol? if ((!pDataConn || Addr[i].getProtocol() != pDataConn->getProtocol()) && (!pMsgConn || Addr[i].getProtocol() != pMsgConn->getProtocol())) // protocol available? if (pIO->getNetIO(Addr[i].getProtocol())) // new best address? if (iBestAddress < 0 || AddrAttempts[i] < AddrAttempts[iBestAddress]) iBestAddress = i; // too many attempts or nothing found? if (iBestAddress < 0 || AddrAttempts[iBestAddress] > C4NetClientConnectAttempts) { iNextConnAttempt = time(nullptr) + 10; return true; } // save attempt AddrAttempts[iBestAddress]++; iNextConnAttempt = time(nullptr) + C4NetClientConnectInterval; auto addr = Addr[iBestAddress].getAddr(); // try TCP simultaneous open if the stars align right if (addr.GetFamily() == C4NetIO::addr_t::IPv6 && // address needs to be IPv6... !addr.IsLocal() && !addr.IsPrivate() && // ...global unicast... Addr[iBestAddress].getProtocol() == P_TCP && // ...TCP, !TcpSimOpenSocket && // there is no previous request, pParent->GetLocal()->getID() < getID()) // and make sure that only one client per pair initiates a request. { DoTCPSimultaneousOpen(pIO, C4Network2Address()); } std::set<int> interfaceIDs; if (addr.IsLocal()) interfaceIDs = Network.Clients.GetLocal()->getInterfaceIDs(); else interfaceIDs = {0}; for (auto id : interfaceIDs) { addr.SetScopeId(id); // log LogSilentF("Network: connecting client %s on %s...", getName(), addr.ToString().getData()); // connect if (pIO->Connect(addr, Addr[iBestAddress].getProtocol(), pClient->getCore())) return true; } return false; }
bool C4Network2Client::SendData(C4NetIOPacket rPkt) const { return getDataConn() && getDataConn()->Send(rPkt); }