public void TestSingleClientConnection() { var connectionEstablished = new ManualResetEventSlim(); var connectionLost = new ManualResetEventSlim(); SecureTransport serverTransport = null; SecureTransport clientTransport = null; try { serverTransport = CreateTransport(); serverTransport.StartServer(this.serverListenPort); clientTransport = CreateTransport(); clientTransport.OnNewConnection = _ => connectionEstablished.Set(); clientTransport.OnConnectionLost = () => connectionLost.Set(); clientTransport.StartClient(this.clientEndPoints); connectionEstablished.Wait(); } finally { try { serverTransport.Dispose(); Assert.IsTrue(connectionLost.Wait(5000)); } finally { clientTransport?.Dispose(); } } }
public void TestMaxConnectionIdleTime() { var connection1Established = new ManualResetEventSlim(); var connection1Lost = new ManualResetEventSlim(); var configuration = new SecureTransport.Configuration { MaxConnectionIdleTime = TimeSpan.FromSeconds(5), CommunicationProtocolVersion = 1, }; using (var cancellationTokenSource = new CancellationTokenSource()) using (var serverTransport = new SecureTransport(configuration, null, cancellationTokenSource.Token)) { serverTransport.StartServer(this.serverListenPort); using (var clientTransport1 = CreateTransport()) { serverTransport.OnNewConnection = _ => connection1Established.Set(); clientTransport1.OnConnectionLost = () => connection1Lost.Set(); clientTransport1.StartClient(this.clientEndPoints); connection1Established.Wait(); // The connections should be terminated after 5 seconds Trace.TraceInformation("Waiting for connection to be lost"); connection1Lost.Wait(); } } }
private void Run(int port) { var protocol = new RingMasterCommunicationProtocol(); this.CreateBackend(); using (var cancel = new CancellationTokenSource()) { this.ringMasterServer = new RingMasterServer(protocol, null, cancel.Token); var transportConfig = new SecureTransport.Configuration { UseSecureConnection = false, IsClientCertificateRequired = false, CommunicationProtocolVersion = RingMasterCommunicationProtocol.MaximumSupportedVersion, }; using (var serverTransport = new SecureTransport(transportConfig)) { this.ringMasterServer.RegisterTransport(serverTransport); this.ringMasterServer.OnInitSession = initRequest => { return(new CoreRequestHandler(this.backend, initRequest)); }; serverTransport.StartServer(port); Console.WriteLine("Press ENTER to exit..."); Console.ReadLine(); cancel.Cancel(); } } }
public void TestClientConnectionRetrySameServer() { var connectionEstablished = new ManualResetEventSlim(); var connectionLost = new ManualResetEventSlim(); SecureTransport serverTransport = null; SecureTransport clientTransport = null; try { serverTransport = CreateTransport(); serverTransport.StartServer(this.serverListenPort); clientTransport = CreateTransport(); clientTransport.OnNewConnection = _ => connectionEstablished.Set(); clientTransport.OnConnectionLost = () => connectionLost.Set(); clientTransport.StartClient(this.clientEndPoints); connectionEstablished.Wait(); // Now stop the server to break the established connection serverTransport.Stop(); connectionLost.Wait(); connectionEstablished.Reset(); connectionLost.Reset(); // Restart the server and verify that the client automatically connects to it serverTransport.StartServer(this.serverListenPort); connectionEstablished.Wait(); } finally { try { serverTransport.Dispose(); Assert.IsTrue(connectionLost.Wait(5000)); } finally { clientTransport?.Dispose(); } } }
public void TestClientConnectionRetryDifferentServer() { var connectionEstablished = new ManualResetEventSlim(); var connectionLost = new ManualResetEventSlim(); int server1ListenPort = GetAvailablePort(9997); int server2ListenPort = GetAvailablePort(server1ListenPort + 1); IPEndPoint[] clientEndPoints = SecureTransport.ParseConnectionString(string.Format("127.0.0.1:{0},127.0.0.1:{1}", server1ListenPort, server2ListenPort)); SecureTransport serverTransport1 = null; SecureTransport clientTransport = null; try { serverTransport1 = CreateTransport(); serverTransport1.StartServer(server1ListenPort); clientTransport = CreateTransport(); clientTransport.OnNewConnection = _ => connectionEstablished.Set(); clientTransport.OnConnectionLost = () => connectionLost.Set(); clientTransport.StartClient(clientEndPoints); connectionEstablished.Wait(); // Now stop the server to break the established connection serverTransport1.Stop(); connectionLost.Wait(); connectionEstablished.Reset(); connectionLost.Reset(); using (var serverTransport2 = CreateTransport()) { // Start a new server at a different port and verify that the client automatically connects to it serverTransport2.StartServer(server2ListenPort); connectionEstablished.Wait(); } } finally { try { serverTransport1.Dispose(); Assert.IsTrue(connectionLost.Wait(5000)); } finally { clientTransport?.Dispose(); } } }
public void TestMultipleServerConnections() { var connection1Established = new ManualResetEventSlim(); var connection1Lost = new ManualResetEventSlim(); var connection2Established = new ManualResetEventSlim(); var connection2Lost = new ManualResetEventSlim(); var port = GetAvailablePort(10000); var clientEndpoint = SecureTransport.ParseConnectionString($"127.0.0.1:{port}"); SecureTransport serverTransport = null; SecureTransport clientTransport1 = null; SecureTransport clientTransport2 = null; try { serverTransport = CreateTransport(); serverTransport.StartServer(port); clientTransport1 = CreateTransport(); serverTransport.OnNewConnection = _ => connection1Established.Set(); clientTransport1.OnConnectionLost = () => connection1Lost.Set(); clientTransport1.StartClient(clientEndpoint); connection1Established.Wait(); clientTransport2 = CreateTransport(); serverTransport.OnNewConnection = _ => connection2Established.Set(); clientTransport2.OnConnectionLost = () => connection2Lost.Set(); clientTransport2.StartClient(clientEndpoint); connection2Established.Wait(); } finally { try { serverTransport.Dispose(); Assert.IsTrue(connection1Lost.Wait(5000)); Assert.IsTrue(connection2Lost.Wait(5000)); } finally { clientTransport1?.Dispose(); clientTransport2?.Dispose(); } } }
public static void Setup(TestContext context) { var path = System.Reflection.Assembly.GetExecutingAssembly().Location; var builder = new ConfigurationBuilder().SetBasePath(Path.GetDirectoryName(path)).AddJsonFile("appSettings.json"); IConfiguration appSettings = builder.Build(); Helpers.SetupTraceLog(Path.Combine(appSettings["LogFolder"], "VegaInMemoryPerf.LogPath")); log = s => Trace.TraceInformation(s); // If a parameter is specified as follows: // te.exe VegaInMemoryPerf.dll /p:ServerAddress=127.0.0.1:99 if (!context.Properties.ContainsKey("ServerAddress")) { backendCore = CreateBackend(); backendServer = new RingMasterServer(protocol, null, CancellationToken.None); var transportConfig = new SecureTransport.Configuration { UseSecureConnection = false, IsClientCertificateRequired = false, CommunicationProtocolVersion = RingMasterCommunicationProtocol.MaximumSupportedVersion, }; serverTransport = new SecureTransport(transportConfig); backendServer.RegisterTransport(serverTransport); backendServer.OnInitSession = initRequest => { return(new CoreRequestHandler(backendCore, initRequest)); }; serverTransport.StartServer(10009); serverAddress = "127.0.0.1:10009"; } else { serverAddress = context.Properties["ServerAddress"] as string; } // Read the app settings minPayloadSize = int.Parse(appSettings["MinPayloadSize"]); maxPayloadSize = int.Parse(appSettings["MaxPayloadSize"]); threadCount = int.Parse(appSettings["ThreadCount"]); }
public void TestServerCertificateSelectionCallback() { var certificates = GetLocalCertificates(2); X509Certificate[] clientCertificates = new X509Certificate[] { certificates[0] }; X509Certificate[] serverCertificates = new X509Certificate[] { certificates[1] }; int port = TestSecureTransport.GetAvailablePort(10000); var serverAcceptedClient = new ManualResetEventSlim(); var clientConnected = new ManualResetEventSlim(); var serverCertificateSelectionCallbackCalled = new ManualResetEventSlim(); var configuration = new SecureTransport.Configuration() { UseSecureConnection = true, ClientCertificates = certificates, ServerCertificates = serverCertificates, CommunicationProtocolVersion = 1, MustCheckCertificateTrustChain = false, LocalCertificateSelectionCallback = (sender, targetHost, localCertificates, remoteCertificate, acceptableIssuers) => { serverCertificateSelectionCallbackCalled.Set(); return(certificates[1]); } }; using (var server = new SecureTransport(configuration, null, CancellationToken.None)) using (var client = CreateTransport(clientCertificates, serverCertificates)) { server.OnNewConnection = _ => serverAcceptedClient.Set(); client.OnNewConnection = _ => clientConnected.Set(); server.StartServer(port); client.StartClient(new IPEndPoint(IPAddress.Loopback, port)); // Server certificate selection callback must be called before // the server accepts the connection. serverCertificateSelectionCallbackCalled.Wait(3000).Should().BeTrue(); serverAcceptedClient.Wait(30000).Should().BeTrue(); clientConnected.Wait(30000).Should().BeTrue(); } }
private static void SecureTransportInternal(Action <string> log, string testCaseName, int numberOfClients) { var packetCount = 0; log($"Starting {testCaseName} ..."); SecureTransport server = null; SecureTransport[] clients = new SecureTransport[0]; try { // Start the service server = new SecureTransport(new SecureTransport.Configuration { UseSecureConnection = false, IsClientCertificateRequired = false, CommunicationProtocolVersion = RingMasterCommunicationProtocol.MaximumSupportedVersion, }); var serverSendTask = Task.CompletedTask; server.OnNewConnection = connection => { connection.OnPacketReceived = packet => { Interlocked.Increment(ref packetCount); serverSendTask.GetAwaiter().GetResult(); serverSendTask = connection.SendAsync(packet); }; Trace.TraceInformation("Server accepted a new connection: {0}", connection.RemoteIdentity); }; server.StartServer(Port); // Start the client clients = Enumerable.Range(0, numberOfClients).Select( _ => new SecureTransport(new SecureTransport.Configuration { UseSecureConnection = false, IsClientCertificateRequired = false, CommunicationProtocolVersion = RingMasterCommunicationProtocol.MaximumSupportedVersion, })) .ToArray(); Parallel.ForEach( clients, client => client.OnNewConnection = connection => { var clientSendTask = Task.CompletedTask; connection.OnPacketReceived = packet => { clientSendTask.GetAwaiter().GetResult(); clientSendTask = connection.SendAsync(packet); }; clientSendTask = connection.SendAsync(new byte[PacketLength]); }); Parallel.ForEach( clients, client => client.StartClient(new IPEndPoint(IPAddress.Loopback, Port))); log($" Warming up for {WarmupMilliSeconds / 1000} seconds"); Thread.Sleep(WarmupMilliSeconds); log($" Start measuring for {MeasureMilliSeconds} seconds"); var sw = new Stopwatch(); int gen0 = GC.CollectionCount(0), gen1 = GC.CollectionCount(1), gen2 = GC.CollectionCount(2); sw.Start(); Interlocked.Exchange(ref packetCount, 0); for (int i = 0; i < MeasureMilliSeconds / PrintStatusInterval; i++) { Thread.Sleep(PrintStatusInterval); log($" {DateTime.Now.ToString()} count={packetCount}"); } sw.Stop(); var totalCount = packetCount; var rate = totalCount / sw.Elapsed.TotalSeconds; Parallel.ForEach(clients, client => client.Close()); server.Close(); log($"{testCaseName}: {totalCount} in {sw.Elapsed} with {numberOfClients} clients. QPS={rate}"); log($" Gen0={GC.CollectionCount(0) - gen0} Gen1={GC.CollectionCount(1) - gen1} Gen2={GC.CollectionCount(2) - gen2}\n"); log(string.Empty); } finally { server?.Dispose(); Parallel.ForEach(clients, client => client.Dispose()); } }
/// <summary> /// Defines the entry point of the application. /// </summary> /// <param name="args">Command line arguments</param> public static void Main(string[] args) { Trace.Listeners.Add(new TextWriterTraceListener(Console.Out)); if (args == null || args.Length < 1) { Trace.TraceError("USAGE: SecureTransportServiceTool.exe <port>"); return; } int port = int.Parse(args[0]); var configuration = new SecureTransport.Configuration(); var path = System.Reflection.Assembly.GetExecutingAssembly().Location; var builder = new ConfigurationBuilder().SetBasePath(Path.GetDirectoryName(path)).AddJsonFile("appSettings.json"); IConfiguration appSettings = builder.Build(); int maxConcurrentRequests = int.Parse(appSettings["MaxConcurrentRequests"]); configuration.UseSecureConnection = bool.Parse(appSettings["SSL.UseSSL"]); configuration.SendBufferSize = int.Parse(appSettings["SendBufferSize"]); configuration.ReceiveBufferSize = int.Parse(appSettings["ReceiveBufferSize"]); if (configuration.UseSecureConnection) { string[] clientThumbprints = appSettings["SSL.ClientCerts"].Split(new char[] { ';', ',' }); string[] serviceThumbprints = appSettings["SSL.ServerCerts"].Split(new char[] { ';', ',' }); configuration.ClientCertificates = SecureTransport.GetCertificatesFromThumbPrintOrFileName(clientThumbprints); configuration.ServerCertificates = SecureTransport.GetCertificatesFromThumbPrintOrFileName(serviceThumbprints); } Trace.TraceInformation( "Listening on port {0}. Using SSL={1}, MaxConcurentRequests={2}, SendBufferSize={3}, ReceiveBufferSize={4}", port, configuration.UseSecureConnection, maxConcurrentRequests, configuration.SendBufferSize, configuration.ReceiveBufferSize); using (var transport = new SecureTransport(configuration)) { var timer = Stopwatch.StartNew(); long activeConnections = 0; long packetsReceived = 0; Task serverTask = transport.StartServer(port); Console.CancelKeyPress += (sender, eventArgs) => { Trace.TraceInformation("Attempting to close server transport"); transport.Close(); }; var semaphore = new SemaphoreSlim(maxConcurrentRequests, maxConcurrentRequests); transport.OnNewConnection = connection => { Trace.TraceInformation("Connection Established with {0}", connection.RemoteEndPoint); Interlocked.Increment(ref activeConnections); connection.OnPacketReceived = packet => { semaphore.Wait(); Interlocked.Increment(ref packetsReceived); connection.SendAsync(packet).ContinueWith(_ => semaphore.Release()); }; connection.OnConnectionLost = () => { Trace.TraceInformation("Connection with {0} was lost", connection.RemoteEndPoint); Interlocked.Decrement(ref activeConnections); }; }; while (!serverTask.Wait(5000)) { timer.Stop(); long rate = (long)(packetsReceived * 1000) / timer.ElapsedMilliseconds; int inflightCount = maxConcurrentRequests - semaphore.CurrentCount; Trace.TraceInformation($"ActiveConnections={activeConnections}, RequestRate {rate} InFlight count={inflightCount}"); packetsReceived = 0; timer.Restart(); } } }