void NetInterface::handleConnectReject(const Address &address, BitStream *stream) { Nonce nonce; Nonce serverNonce; nonce.read(stream); serverNonce.read(stream); NetConnection *conn = findPendingConnection(address); if(!conn || (conn->getConnectionState() != NetConnection::AwaitingChallengeResponse && conn->getConnectionState() != NetConnection::AwaitingConnectResponse)) return; ConnectionParameters &p = conn->getConnectionParameters(); if(p.mNonce != nonce || p.mServerNonce != serverNonce) return; NetConnection::TerminationReason reason = (NetConnection::TerminationReason) stream->readEnum(NetConnection::TerminationReasons); char reasonStr[256]; stream->readString(reasonStr); logprintf(LogConsumer::LogNetInterface, "Received Connect Reject - reason code %d (%s)", reason, reasonStr); // If the reason is a bad puzzle solution, try once more with a new nonce if(reason == NetConnection::ReasonPuzzle && !p.mPuzzleRetried) { p.mPuzzleRetried = true; conn->setConnectionState(NetConnection::AwaitingChallengeResponse); conn->mConnectSendCount = 0; p.mNonce.getRandom(); // Generate new nonce sendConnectChallengeRequest(conn); return; } conn->setConnectionState(NetConnection::ConnectRejected); conn->onConnectTerminated(reason, reasonStr); removePendingConnection(conn); }
void NetInterface::handleConnectReject(const Address &address, BitStream *stream) { Nonce nonce; Nonce serverNonce; nonce.read(stream); serverNonce.read(stream); NetConnection *conn = findPendingConnection(address); if(!conn || (conn->getConnectionState() != NetConnection::AwaitingChallengeResponse && conn->getConnectionState() != NetConnection::AwaitingConnectResponse)) return; ConnectionParameters &p = conn->getConnectionParameters(); if(p.mNonce != nonce || p.mServerNonce != serverNonce) return; char reason[256]; stream->readString(reason); TNLLogMessageV(LogNetInterface, ("Received Connect Reject - reason %s", reason)); // if the reason is a bad puzzle solution, try once more with a // new nonce. if(!strcmp(reason, "Puzzle") && !p.mPuzzleRetried) { p.mPuzzleRetried = true; conn->setConnectionState(NetConnection::AwaitingChallengeResponse); conn->mConnectSendCount = 0; p.mNonce.getRandom(); sendConnectChallengeRequest(conn); return; } conn->setConnectionState(NetConnection::ConnectRejected); conn->onConnectTerminated(NetConnection::ReasonRemoteHostRejectedConnection, reason); removePendingConnection(conn); }
void NetInterface::processConnections() { mCurrentTime = Platform::getRealMilliseconds(); mPuzzleManager.tick(mCurrentTime); // first see if there are any delayed packets that need to be sent... while(mSendPacketList && mSendPacketList->sendTime < getCurrentTime()) { DelaySendPacket *next = mSendPacketList->nextPacket; mSocket.sendto(mSendPacketList->remoteAddress, mSendPacketList->packetData, mSendPacketList->packetSize); free(mSendPacketList); mSendPacketList = next; } NetObject::collapseDirtyList(); // collapse all the mask bits... for(S32 i = 0; i < mConnectionList.size(); i++) mConnectionList[i]->checkPacketSend(false, getCurrentTime()); if(getCurrentTime() > mLastTimeoutCheckTime + TimeoutCheckInterval) { for(S32 i = 0; i < mPendingConnections.size();) { NetConnection *pending = mPendingConnections[i]; if(pending->getConnectionState() == NetConnection::AwaitingChallengeResponse && getCurrentTime() > pending->mConnectLastSendTime + ChallengeRetryTime) { if(pending->mConnectSendCount > ChallengeRetryCount) { pending->setConnectionState(NetConnection::ConnectTimedOut); pending->onConnectTerminated(NetConnection::ReasonTimedOut, "Timeout"); removePendingConnection(pending); continue; } else sendConnectChallengeRequest(pending); } else if(pending->getConnectionState() == NetConnection::AwaitingConnectResponse && getCurrentTime() > pending->mConnectLastSendTime + ConnectRetryTime) { if(pending->mConnectSendCount > ConnectRetryCount) { pending->setConnectionState(NetConnection::ConnectTimedOut); pending->onConnectTerminated(NetConnection::ReasonTimedOut, "Timeout"); removePendingConnection(pending); continue; } else { if(pending->getConnectionParameters().mIsArranged) sendArrangedConnectRequest(pending); else sendConnectRequest(pending); } } else if(pending->getConnectionState() == NetConnection::SendingPunchPackets && getCurrentTime() > pending->mConnectLastSendTime + PunchRetryTime) { if(pending->mConnectSendCount > PunchRetryCount) { pending->setConnectionState(NetConnection::ConnectTimedOut); pending->onConnectTerminated(NetConnection::ReasonTimedOut, "Timeout"); removePendingConnection(pending); continue; } else sendPunchPackets(pending); } else if(pending->getConnectionState() == NetConnection::ComputingPuzzleSolution && getCurrentTime() > pending->mConnectLastSendTime + PuzzleSolutionTimeout) { pending->setConnectionState(NetConnection::ConnectTimedOut); pending->onConnectTerminated(NetConnection::ReasonTimedOut, "Timeout"); removePendingConnection(pending); } i++; } mLastTimeoutCheckTime = getCurrentTime(); for(S32 i = 0; i < mConnectionList.size();) { if(mConnectionList[i]->checkTimeout(getCurrentTime())) { mConnectionList[i]->setConnectionState(NetConnection::TimedOut); mConnectionList[i]->onConnectionTerminated(NetConnection::ReasonTimedOut, "Timeout"); removeConnection(mConnectionList[i]); } else i++; } } // check if we're trying to solve any client connection puzzles for(S32 i = 0; i < mPendingConnections.size(); i++) { if(mPendingConnections[i]->getConnectionState() == NetConnection::ComputingPuzzleSolution) { continuePuzzleSolution(mPendingConnections[i]); break; } } }