protected void HandleConnectRequest(IPEndPoint address, BitStream stream) { if (!AllowConnections) { return; } var cParams = new ConnectionParameters(); cParams.Nonce.Read(stream); cParams.ServerNonce.Read(stream); stream.Read(out cParams.ClientIdentity); if (cParams.ClientIdentity != ComputeClientIdentityToken(address, cParams.Nonce)) { return; } stream.Read(out cParams.PuzzleDifficulty); stream.Read(out cParams.PuzzleSolution); var connect = FindConnection(address); if (connect != null) { var cp = connect.GetConnectionParameters(); if (cp.Nonce == cParams.Nonce && cp.ServerNonce == cParams.ServerNonce) { SendConnectAccept(connect); return; } } var result = PuzzleManager.CheckSolution(cParams.PuzzleSolution, cParams.Nonce, cParams.ServerNonce, cParams.PuzzleDifficulty, cParams.ClientIdentity); if (result != ErrorCode.Success) { SendConnectReject(cParams, address, "Puzzle"); return; } if (stream.ReadFlag()) { if (PrivateKey == null) { return; } cParams.UsingCrypto = true; cParams.PublicKey = new AsymmetricKey(stream); cParams.PrivateKey = PrivateKey; var decryptPos = stream.GetBytePosition(); stream.SetBytePosition(decryptPos); cParams.SharedSecret = cParams.PrivateKey.ComputeSharedSecretKey(cParams.PublicKey); var theCipher = new SymmetricCipher(cParams.SharedSecret); if (!stream.DecryptAndCheckHash(NetConnection.MessageSignatureBytes, decryptPos, theCipher)) { return; } stream.Read(SymmetricCipher.KeySize, cParams.SymmetricKey); RandomUtil.Read(cParams.InitVector, SymmetricCipher.KeySize); } cParams.DebugObjectSizes = stream.ReadFlag(); stream.Read(out uint connectSequence); if (connect != null) { Disconnect(connect, TerminationReason.ReasonSelfDisconnect, "NewConnection"); } stream.ReadString(out string connectionClass); var conn = NetConnectionRep.Create(connectionClass); if (conn == null) { return; } conn.SetConnectionParameters(cParams); conn.SetNetAddress(address); conn.SetInitialRecvSequence(connectSequence); conn.SetInterface(this); if (cParams.UsingCrypto) { conn.SetSymmetricCipher(new SymmetricCipher(cParams.SymmetricKey, cParams.InitVector)); } string errorString = null; if (!conn.ReadConnectRequest(stream, ref errorString)) { SendConnectReject(cParams, address, errorString); return; } AddConnection(conn); conn.ConnectionState = NetConnectionState.Connected; conn.OnConnectionEstablished(); SendConnectAccept(conn); }
public static void ImplementNetConnection <T>(out NetClassRepInstance <T> rep, out NetConnectionRep connRep, bool canRemoteCreate) where T : BaseObject, new() { ImplementClass(out rep); connRep = new NetConnectionRep(rep, canRemoteCreate); }