void NetInterface::sendPunchPackets(NetConnection *conn) { ConnectionParameters &theParams = conn->getConnectionParameters(); PacketStream out; out.write(U8(Punch)); if(theParams.mIsInitiator) theParams.mNonce.write(&out); else theParams.mServerNonce.write(&out); U32 encryptPos = out.getBytePosition(); out.setBytePosition(encryptPos); if(theParams.mIsInitiator) theParams.mServerNonce.write(&out); else { theParams.mNonce.write(&out); if(out.writeFlag(mRequiresKeyExchange || (theParams.mRequestKeyExchange && !mPrivateKey.isNull()))) { if(out.writeFlag(theParams.mRequestCertificate && !mCertificate.isNull())) out.write(mCertificate); else out.write(mPrivateKey->getPublicKey()); } } SymmetricCipher theCipher(theParams.mArrangedSecret); out.hashAndEncrypt(NetConnection::MessageSignatureBytes, encryptPos, &theCipher); for(S32 i = 0; i < theParams.mPossibleAddresses.size(); i++) { out.sendto(mSocket, theParams.mPossibleAddresses[i]); TNLLogMessageV(LogNetInterface, ("Sending punch packet (%s, %s) to %s", ByteBuffer(theParams.mNonce.data, Nonce::NonceSize).encodeBase64()->getBuffer(), ByteBuffer(theParams.mServerNonce.data, Nonce::NonceSize).encodeBase64()->getBuffer(), theParams.mPossibleAddresses[i].toString())); } conn->mConnectSendCount++; conn->mConnectLastSendTime = getCurrentTime(); }
void NetInterface::disconnect(NetConnection *conn, NetConnection::TerminationReason reason, const char *reasonString) { // If we're still connecting... if(conn->getConnectionState() == NetConnection::NotConnected || conn->getConnectionState() == NetConnection::AwaitingChallengeResponse || conn->getConnectionState() == NetConnection::AwaitingConnectResponse || conn->getConnectionState() == NetConnection::SendingPunchPackets || conn->getConnectionState() == NetConnection::ComputingPuzzleSolution) { conn->onConnectTerminated(reason, reasonString); removePendingConnection(conn); } // If we're already connected else if(conn->getConnectionState() == NetConnection::Connected) { conn->setConnectionState(NetConnection::Disconnected); conn->onConnectionTerminated(reason, reasonString); if(conn->isNetworkConnection()) { // send a disconnect packet... PacketStream out; out.write(U8(Disconnect)); ConnectionParameters &theParams = conn->getConnectionParameters(); theParams.mNonce.write(&out); theParams.mServerNonce.write(&out); U32 encryptPos = out.getBytePosition(); out.setBytePosition(encryptPos); out.writeEnum(reason, NetConnection::TerminationReasons); out.writeString(reasonString); if(theParams.mUsingCrypto) { SymmetricCipher theCipher(theParams.mSharedSecret); out.hashAndEncrypt(NetConnection::MessageSignatureBytes, encryptPos, &theCipher); } out.sendto(mSocket, conn->getNetAddress()); } removeConnection(conn); } }
void NetInterface::sendConnectAccept(NetConnection *conn) { TNLLogMessageV(LogNetInterface, ("Sending Connect Accept - connection established.")); PacketStream out; out.write(U8(ConnectAccept)); ConnectionParameters &theParams = conn->getConnectionParameters(); theParams.mNonce.write(&out); theParams.mServerNonce.write(&out); U32 encryptPos = out.getBytePosition(); out.setBytePosition(encryptPos); out.write(conn->getInitialSendSequence()); conn->writeConnectAccept(&out); if(theParams.mUsingCrypto) { out.write(SymmetricCipher::KeySize, theParams.mInitVector); SymmetricCipher theCipher(theParams.mSharedSecret); out.hashAndEncrypt(NetConnection::MessageSignatureBytes, encryptPos, &theCipher); } out.sendto(mSocket, conn->getNetAddress()); }