void C4Network2ClientListBox::ConnectionListItem::Update() { C4Network2IOConnection *pConn = GetConnection(); if (!pConn) { // No connection: Shouldn't happen pDesc->SetText("???"); pPing->SetText("???"); return; } // update connection ping int iPing = pConn->getLag(); pPing->SetText(FormatString("%d ms", iPing).getData()); // update description // get connection usage const char *szConnType; C4Network2Client *pNetClient = ::Network.Clients.GetClientByID(iClientID); if (pNetClient->getDataConn() == pNetClient->getMsgConn()) szConnType = "Data/Msg"; else if (iConnID) szConnType = "Msg"; else szConnType = "Data"; // display info pDesc->SetText(FormatString("%s: %s (%s l%d)", szConnType, ::Network.NetIO.getNetIOName(pConn->getNetClass()), pConn->getPeerAddr().ToString().getData(), pConn->getPacketLoss()).getData()); }
C4Network2IOConnection *C4Network2IO::GetConnection(const C4NetIO::addr_t &addr, C4NetIO *pNetIO) // by both { CStdLock ConnListLock(&ConnListCSec); // search for (C4Network2IOConnection *pConn = pConnList; pConn; pConn = pConn->pNext) if (pConn->getNetClass() == pNetIO && AddrEqual(pConn->getPeerAddr(), addr)) return pConn; return NULL; }
bool C4Network2IO::doAutoAccept(const C4ClientCore &CCore, const C4Network2IOConnection &Conn) { CStdLock AALock(&AutoAcceptCSec); // check if connection with the given client should be allowed for (AutoAccept *pAcc = pAutoAcceptList; pAcc; pAcc = pAcc->Next) // core match? if (CCore.getDiffLevel(pAcc->CCore) <= C4ClientCoreDL_IDMatch) { // check: already got another connection for this client? Peer IP must match, then. for (C4Network2IOConnection *pConn = pConnList; pConn; pConn = pConn->pNext) if (pConn->isAccepted() && pConn->getCCore().getDiffLevel(CCore) <= C4ClientCoreDL_IDMatch && pConn->getPeerAddr().sin_addr.s_addr != Conn.getPeerAddr().sin_addr.s_addr) return false; // not found or IP matches? Let pass return true; } return false; }
void C4Network2IO::CheckTimeout() { // acquire lock CStdLock ConnListLock(&ConnListCSec); // check all connections for timeout (use deletion-safe iteration method just in case) for (C4Network2IOConnection *pConn = pConnList, *pNext; pConn; pConn = pNext) { pNext = pConn->pNext; // status timeout if (!pConn->isClosed() && !pConn->isAccepted()) if (difftime(time(NULL), pConn->getTimestamp()) > C4NetAcceptTimeout) { Application.InteractiveThread.ThreadLogS("Network: connection accept timeout to %s:%d", inet_ntoa(pConn->getPeerAddr().sin_addr), htons(pConn->getPeerAddr().sin_port)); pConn->Close(); } // ping timeout if (pConn->isAccepted()) if ((pConn->getLag() != -1 ? pConn->getLag() : 1000 * difftime(time(NULL), pConn->getTimestamp())) > C4NetPingTimeout) { Application.InteractiveThread.ThreadLogS("%d %d %d", (int)pConn->getLag(), (int)time(NULL), (int)pConn->getTimestamp()); Application.InteractiveThread.ThreadLogS("Network: ping timeout to %s:%d", inet_ntoa(pConn->getPeerAddr().sin_addr), htons(pConn->getPeerAddr().sin_port)); pConn->Close(); } // delayed connection removal if (pConn->isClosed()) if (difftime(time(NULL), pConn->getTimestamp()) > C4NetAcceptTimeout) RemoveConnection(pConn); } }