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); } }
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 GameNetInterface::sendQuery(const Address &theAddress, const Nonce &clientNonce, U32 identityToken) { PacketStream packet; packet.write(U8(Query)); clientNonce.write(&packet); packet.write(identityToken); packet.sendto(mSocket, theAddress); }
// Send ping to the server. If server has different PROTOCOL_VERSION, the packet will be ignored. This prevents players // from seeing servers they are incompatible with. void GameNetInterface::sendPing(const Address &theAddress, const Nonce &clientNonce) { PacketStream packet; packet.write(U8(Ping)); clientNonce.write(&packet); packet.write(CS_PROTOCOL_VERSION); packet.sendto(mSocket, theAddress); }
static void handlePing(Game *game, const Address &remoteAddress, Socket &socket, BitStream *stream, S32 clientId) { TNLAssert(game->isServer(), "Expected this to be a server!"); Nonce clientNonce; clientNonce.read(stream); U32 protocolVersion; stream->read(&protocolVersion); if(protocolVersion != CS_PROTOCOL_VERSION) // Ignore pings from incompatible versions return; U32 clientIdentityToken = computeSimpleToken(clientNonce); PacketStream pingResponse; pingResponse.write(U8(GameNetInterface::PingResponse)); clientNonce.write(&pingResponse); pingResponse.write(clientIdentityToken); pingResponse.write(clientId); // older 019 ignore this or won't read this pingResponse.sendto(socket, remoteAddress); }