void NetInterface::checkTimeouts() { U32 time = Platform::getVirtualMilliseconds(); if(time > mLastTimeoutCheckTime + TimeoutCheckInterval) { for(U32 i = 0; i < mPendingConnections.size();) { NetConnection *pending = mPendingConnections[i]; if(pending->getConnectionState() == NetConnection::AwaitingChallengeResponse && time > pending->mConnectLastSendTime + ChallengeRetryTime) { if(pending->mConnectSendCount > ChallengeRetryCount) { pending->onConnectTimedOut(); removePendingConnection(pending); pending->deleteObject(); continue; } else sendConnectChallengeRequest(pending); } else if(pending->getConnectionState() == NetConnection::AwaitingConnectResponse && time > pending->mConnectLastSendTime + ConnectRetryTime) { if(pending->mConnectSendCount > ConnectRetryCount) { pending->onConnectTimedOut(); removePendingConnection(pending); pending->deleteObject(); continue; } else sendConnectRequest(pending); } i++; } mLastTimeoutCheckTime = time; NetConnection *walk = NetConnection::getConnectionList(); while(walk) { NetConnection *next = walk->getNext(); if(walk->checkTimeout(time)) { // this baddie timed out walk->onTimedOut(); walk->deleteObject(); } walk = next; } } }
void NetInterface::handleConnectReject(const NetAddress *address, BitStream *stream) { U32 connectSequence; stream->read(&connectSequence); NetConnection *conn = findPendingConnection(address, connectSequence); if(!conn || (conn->getConnectionState() != NetConnection::AwaitingChallengeResponse && conn->getConnectionState() != NetConnection::AwaitingConnectResponse)) return; removePendingConnection(conn); char reason[256]; stream->readString(reason); conn->onConnectionRejected(reason); conn->deleteObject(); }
void NetInterface::handleDisconnect(const NetAddress *address, BitStream *stream) { NetConnection *conn = NetConnection::lookup(address); if(!conn) return; U32 connectSequence; char reason[256]; stream->read(&connectSequence); stream->readString(reason); if(conn->getSequence() != connectSequence) return; conn->onDisconnect(reason); conn->deleteObject(); }
void NetInterface::handleConnectAccept(const NetAddress *address, BitStream *stream) { U32 connectSequence; stream->read(&connectSequence); NetConnection *conn = findPendingConnection(address, connectSequence); if(!conn || conn->getConnectionState() != NetConnection::AwaitingConnectResponse) return; const char *errorString = NULL; if(!conn->readConnectAccept(stream, &errorString)) { conn->handleStartupError(errorString); removePendingConnection(conn); conn->deleteObject(); return; } removePendingConnection(conn); // remove from the pending connection list conn->setNetworkConnection(true); conn->onConnectionEstablished(true); // notify the connection that it has been established conn->setEstablished(); // installs the connection in the connection table, and causes pings/timeouts to happen conn->setConnectSequence(connectSequence); }
void NetInterface::handleConnectRequest(const NetAddress *address, BitStream *stream) { if(!mAllowConnections) return; Con::printf("Got Connect Request"); U32 connectSequence; stream->read(&connectSequence); // see if the connection is in the main connection table: NetConnection *connect = NetConnection::lookup(address); if(connect && connect->getSequence() == connectSequence) { sendConnectAccept(connect); return; } U32 addressDigest[4]; U32 computedAddressDigest[4]; stream->read(&addressDigest[0]); stream->read(&addressDigest[1]); stream->read(&addressDigest[2]); stream->read(&addressDigest[3]); computeNetMD5(address, connectSequence, computedAddressDigest); if(addressDigest[0] != computedAddressDigest[0] || addressDigest[1] != computedAddressDigest[1] || addressDigest[2] != computedAddressDigest[2] || addressDigest[3] != computedAddressDigest[3]) return; // bogus connection attempt if(connect) { if(connect->getSequence() > connectSequence) return; // the existing connection should be kept - the incoming request is stale. else connect->deleteObject(); // disconnect this one, and allow the new one to be created. } char connectionClass[255]; stream->readString(connectionClass); ConsoleObject *co = ConsoleObject::create(connectionClass); NetConnection *conn = dynamic_cast<NetConnection *>(co); if(!conn || !conn->canRemoteCreate()) { delete co; return; } conn->registerObject(); conn->setNetAddress(address); conn->setNetworkConnection(true); conn->setSequence(connectSequence); const char *errorString = NULL; if(!conn->readConnectRequest(stream, &errorString)) { sendConnectReject(conn, errorString); conn->deleteObject(); return; } conn->setNetworkConnection(true); conn->onConnectionEstablished(false); conn->setEstablished(); conn->setConnectSequence(connectSequence); sendConnectAccept(conn); }