void NetInterface::sendConnectChallengeResponse(const Address &addr, Nonce &clientNonce, bool wantsKeyExchange, bool wantsCertificate) { PacketStream out; out.write(U8(ConnectChallengeResponse)); clientNonce.write(&out); U32 identityToken = computeClientIdentityToken(addr, clientNonce); out.write(identityToken); // write out a client puzzle Nonce serverNonce = mPuzzleManager.getCurrentNonce(); U32 difficulty = mPuzzleManager.getCurrentDifficulty(); serverNonce.write(&out); out.write(difficulty); if(out.writeFlag(mRequiresKeyExchange || (wantsKeyExchange && !mPrivateKey.isNull()))) { if(out.writeFlag(wantsCertificate && !mCertificate.isNull())) out.write(mCertificate); else out.write(mPrivateKey->getPublicKey()); } TNLLogMessageV(LogNetInterface, ("Sending Challenge Response: %8x", identityToken)); out.sendto(mSocket, addr); }
static void handleQuery(Game *game, const Address &remoteAddress, Socket &socket, BitStream *stream) { TNLAssert(game->isServer(), "Expected this to be a server!"); Nonce nonce; U32 clientIdentityToken; nonce.read(stream); stream->read(&clientIdentityToken); if(clientIdentityToken == computeSimpleToken(nonce)) { PacketStream queryResponse; queryResponse.write(U8(GameNetInterface::QueryResponse)); nonce.write(&queryResponse); queryResponse.writeStringTableEntry(game->getSettings()->getHostName()); queryResponse.writeStringTableEntry(game->getSettings()->getHostDescr()); queryResponse.write(game->getPlayerCount()); queryResponse.write(game->getMaxPlayers()); queryResponse.write(game->getRobotCount()); queryResponse.writeFlag(game->isDedicated()); queryResponse.writeFlag(game->isTestServer()); queryResponse.writeFlag(game->getSettings()->getServerPassword() != ""); queryResponse.write(game->getClientId()); // older 019 ignore this or won't read this queryResponse.sendto(socket, remoteAddress); } }
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()); }
int main(int argc, const char **argv) { if(argc < 2) { printf("Usage: tnlping <remoteAddress> [sourceAddress]\n\n" "Example 1: Simple usage expecting port 28000\n tnlping 192.168.1.2\n\n" "Example 2: Advanced usage with specific port\n tnlping 192.168.1.2:28001\n\n"); return 1; } U8 randData[sizeof(U32) + sizeof(S64)]; *((U32 *) randData) = Platform::getRealMilliseconds(); *((S64 *) (randData + sizeof(U32))) = Platform::getHighPrecisionTimerValue(); TNL::Random::addEntropy(randData, sizeof(randData)); Address remoteAddress(argv[1]); Address sourceAddress(argc > 2 ? argv[2] : "IP:Any:0"); Nonce clientNonce; clientNonce.getRandom(); Socket sourceSocket(sourceAddress); PacketStream out; out.write(U8(NetInterface::ConnectChallengeRequest)); clientNonce.write(&out); out.writeFlag(false); out.writeFlag(false); for(U32 tryCount = 0; tryCount < 5; tryCount++) { U32 time = Platform::getRealMilliseconds(); out.sendto(sourceSocket, remoteAddress); for(;;) { PacketStream incoming; Address incomingAddress; if(incoming.recvfrom(sourceSocket, &incomingAddress) == NoError) { U8 packetType; Nonce theNonce; incoming.read(&packetType); theNonce.read(&incoming); if(packetType == NetInterface::ConnectChallengeResponse && theNonce == clientNonce) { printf("TNL Service is UP (pingtime = %d)\n", Platform::getRealMilliseconds() - time); return 0; } } Platform::sleep(1); if(Platform::getRealMilliseconds() - time > 1000) break; } } printf("TNL Service is DOWN\n"); return 1; }
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::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::sendConnectChallengeRequest(NetConnection *conn) { TNLLogMessageV(LogNetInterface, ("Sending Connect Challenge Request to %s", conn->getNetAddress().toString())); PacketStream out; out.write(U8(ConnectChallengeRequest)); ConnectionParameters ¶ms = conn->getConnectionParameters(); params.mNonce.write(&out); out.writeFlag(params.mRequestKeyExchange); out.writeFlag(params.mRequestCertificate); conn->mConnectSendCount++; conn->mConnectLastSendTime = getCurrentTime(); out.sendto(mSocket, conn->getNetAddress()); }