void NetInterface::disconnect(NetConnection *conn, NetConnection::TerminationReason reason, const char *reasonString) { if(conn->getConnectionState() == NetConnection::AwaitingChallengeResponse || conn->getConnectionState() == NetConnection::AwaitingConnectResponse) { conn->onConnectTerminated(reason, reasonString); removePendingConnection(conn); } 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.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) { logprintf(LogConsumer::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()); }
void NetInterface::sendArrangedConnectRequest(NetConnection *conn) { TNLLogMessageV(LogNetInterface, ("Sending Arranged Connect Request")); PacketStream out; ConnectionParameters &theParams = conn->getConnectionParameters(); out.write(U8(ArrangedConnectRequest)); theParams.mNonce.write(&out); U32 encryptPos = out.getBytePosition(); U32 innerEncryptPos = 0; out.setBytePosition(encryptPos); theParams.mServerNonce.write(&out); if(out.writeFlag(theParams.mUsingCrypto)) { out.write(theParams.mPrivateKey->getPublicKey()); innerEncryptPos = out.getBytePosition(); out.setBytePosition(innerEncryptPos); out.write(SymmetricCipher::KeySize, theParams.mSymmetricKey); } out.writeFlag(theParams.mDebugObjectSizes); out.write(conn->getInitialSendSequence()); conn->writeConnectRequest(&out); if(innerEncryptPos) { SymmetricCipher theCipher(theParams.mSharedSecret); out.hashAndEncrypt(NetConnection::MessageSignatureBytes, innerEncryptPos, &theCipher); } SymmetricCipher theCipher(theParams.mArrangedSecret); out.hashAndEncrypt(NetConnection::MessageSignatureBytes, encryptPos, &theCipher); conn->mConnectSendCount++; conn->mConnectLastSendTime = getCurrentTime(); out.sendto(mSocket, conn->getNetAddress()); }
void NetInterface::sendConnectRequest(NetConnection *conn) { PacketStream out; ConnectionParameters &theParams = conn->getConnectionParameters(); const char *destDescr; if(theParams.mIsLocal) destDescr = "local in-process server"; else destDescr = conn->getNetAddress().toString(); logprintf(LogConsumer::LogNetInterface, "Sending connect request to %s", destDescr); out.write(U8(ConnectRequest)); theParams.mNonce.write(&out); theParams.mServerNonce.write(&out); out.write(theParams.mClientIdentity); out.write(theParams.mPuzzleDifficulty); out.write(theParams.mPuzzleSolution); U32 encryptPos = 0; if(out.writeFlag(theParams.mUsingCrypto)) { out.write(theParams.mPrivateKey->getPublicKey()); encryptPos = out.getBytePosition(); out.setBytePosition(encryptPos); out.write(SymmetricCipher::KeySize, theParams.mSymmetricKey); } out.writeFlag(theParams.mDebugObjectSizes); out.write(conn->getInitialSendSequence()); out.writeString(conn->getClassName()); conn->writeConnectRequest(&out); if(encryptPos) { // if we're using crypto on this connection, // then write a hash of everything we wrote into the packet // key. Then we'll symmetrically encrypt the packet from // the end of the public key to the end of the signature. SymmetricCipher theCipher(theParams.mSharedSecret); out.hashAndEncrypt(NetConnection::MessageSignatureBytes, encryptPos, &theCipher); } conn->mConnectSendCount++; conn->mConnectLastSendTime = getCurrentTime(); out.sendto(mSocket, conn->getNetAddress()); }
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(); }