public void ShouldCreateDualModeIpv6Socket_WhenIPv6Enabled() { var client = TcpConnectionFactory.CreateTcpClient(AddressFamily.InterNetworkV6); client.Client.AddressFamily.Should().Be(AddressFamily.InterNetworkV6); client.Client.DualMode.Should().BeTrue(); }
public void ClientShouldMoveStateToLinkErrorIfServerDoesntExist() { using var connectionLinkErrorEvent = new AutoResetEvent(false); using var connectionOkEvent = new AutoResetEvent(false); using var client = TcpConnectionFactory.CreateClient(IPAddress.Loopback, 15005); client.Start(connectionStateChangedAction: (connection, fromState, toState) => { if (toState == ConnectionState.LinkError) { connectionLinkErrorEvent.Set(); } else if (toState == ConnectionState.Connected) { connectionOkEvent.Set(); } }, receivedActionStreamAsync: (connection, stream, cancellationToken) => { System.Diagnostics.Debug.Assert(false); return(Task.CompletedTask); }); connectionLinkErrorEvent.WaitOne(10000).ShouldBeTrue(); var server = TcpConnectionFactory.CreateServer(15005); server.Start(); connectionOkEvent.WaitOne(10000).ShouldBeTrue(); }
/// <summary>Ensure <paramref name="process"/> is actually running.</summary> private async Task <bool> EnsureRunningAsync(ProcessAsync process, CancellationToken token) { int i = 0; while (true) { i++; bool isRunning = await TcpConnectionFactory.IsTorRunningAsync().ConfigureAwait(false); if (isRunning) { return(true); } if (process.HasExited) { Logger.LogError("Tor process failed to start!"); return(false); } const int MaxAttempts = 25; if (i >= MaxAttempts) { Logger.LogError($"All {MaxAttempts} attempts to connect to Tor failed."); return(false); } // Wait 250 milliseconds between attempts. await Task.Delay(250, token).ConfigureAwait(false); } }
public async Task MessageReceivedWithStreamAndUsingBufferStreamShouldWork() { var serverReceivedDataEvent = new AsyncAutoResetEvent(false); int currentMessageSize = -1; using var server = TcpConnectionFactory.CreateServer(15022, new ServerConnectionSettings(useBufferedStream: true)); using var client = TcpConnectionFactory.CreateClient(IPAddress.Loopback, 15022, new ClientConnectionSettings(useBufferedStream: true)); client.Start(connectionStateChangedAction: (connection, fromState, toState) => { }); server.Start(receivedActionStreamAsync: async(connection, stream, cancellationToken) => { var bytesRead = await stream.ReadAsync(new byte[stream.Length], 0, (int)stream.Length, cancellationToken); Assert.AreEqual(currentMessageSize, bytesRead); serverReceivedDataEvent.Set(); }, connectionStateChangedAction: (connection, fromState, toState) => { }); await client.WaitForStateAsync(ConnectionState.Connected); await server.WaitForStateAsync(ConnectionState.Connected); await client.SendDataAsync(new byte[currentMessageSize = 10]); (await serverReceivedDataEvent.WaitAsync(10000)).ShouldBeTrue(); await client.SendDataAsync(new byte[currentMessageSize = 120]); (await serverReceivedDataEvent.WaitAsync(10000)).ShouldBeTrue(); }
/// <summary> /// Constructor. /// </summary> /// <param name="rootCertificateName">Name of root certificate.</param> /// <param name="rootCertificateIssuerName">Name of root certificate issuer.</param> public ProxyServer(string rootCertificateName, string rootCertificateIssuerName) { //default values ConnectionTimeOutSeconds = 30; CertificateCacheTimeOutMinutes = 60; ProxyEndPoints = new List <ProxyEndPoint>(); tcpConnectionFactory = new TcpConnectionFactory(); #if NET45 if (!RunTime.IsRunningOnMono) { systemProxySettingsManager = new SystemProxyManager(); } #endif CertificateManager = new CertificateManager(ExceptionFunc); if (rootCertificateName != null) { RootCertificateName = rootCertificateName; } if (rootCertificateIssuerName != null) { RootCertificateIssuerName = rootCertificateIssuerName; } }
public void ClientShouldMoveStateToLinkErrorIfServerDoesntExist() { using var connectionLinkErrorEvent = new AutoResetEvent(false); using var connectionOkEvent = new AutoResetEvent(false); using var client = TcpConnectionFactory.CreateClient(IPAddress.Loopback, 15005); client.Start(connectionStateChangedAction: (connection, fromState, toState) => { if (toState == ConnectionState.LinkError) { connectionLinkErrorEvent.Set(); } else if (toState == ConnectionState.Connected) { connectionOkEvent.Set(); } }); connectionLinkErrorEvent.WaitOne(10000).ShouldBeTrue(); var server = TcpConnectionFactory.CreateServer(15005); server.Start(); connectionOkEvent.WaitOne(10000).ShouldBeTrue(); }
public void ServerShouldMoveStateToLinkErrorIfClientDoesntConnect() { using var connectionLinkErrorEvent = new AutoResetEvent(false); using var connectionOkEvent = new AutoResetEvent(false); using var server = TcpConnectionFactory.CreateServer(15006, new ServerConnectionSettings(connectionTimeoutMilliseconds: 1000)); server.Start(connectionStateChangedAction: (connection, fromState, toState) => { if (toState == ConnectionState.LinkError) { connectionLinkErrorEvent.Set(); } else if (toState == ConnectionState.Connected) { connectionOkEvent.Set(); } }); connectionLinkErrorEvent.WaitOne(10000).ShouldBeTrue(); var client = TcpConnectionFactory.CreateClient(IPAddress.Loopback, 15006); client.Start(); connectionOkEvent.WaitOne(10000).ShouldBeTrue(); }
public async Task MessageLargerThan64KBShouldBeTransimittedWithoutProblems() { var serverReceivedDataEvent = new AsyncAutoResetEvent(false); const int messageSize = 1024 * 128; //128kb using var server = TcpConnectionFactory.CreateServer(15010); using var client = TcpConnectionFactory.CreateClient(IPAddress.Loopback, 15010); client.Start(connectionStateChangedAction: (connection, fromState, toState) => { }); server.Start((connection, data) => { Assert.AreEqual(messageSize, data.Length); serverReceivedDataEvent.Set(); }, connectionStateChangedAction: (connection, fromState, toState) => { }); await client.WaitForStateAsync(ConnectionState.Connected); await server.WaitForStateAsync(ConnectionState.Connected); await client.SendDataAsync(new byte[messageSize]); (await serverReceivedDataEvent.WaitAsync(10000)).ShouldBeTrue(); }
public void StartServerAfterClientShouldWork() { using var server = TcpConnectionFactory.CreateServer( 15003); using var client = TcpConnectionFactory.CreateClient( IPAddress.Loopback, 15003); client.Start(connectionStateChangedAction: (connection, fromState, toState) => { }); server.Start(connectionStateChangedAction: (connection, fromState, toState) => { }); AssertEx.IsTrue(() => server.State == ConnectionState.Connected); AssertEx.IsTrue(() => client.State == ConnectionState.Connected); server.Stop(); client.Stop(); AssertEx.IsTrue(() => server.State == ConnectionState.Disconnected); AssertEx.IsTrue(() => server.State == ConnectionState.Disconnected); }
/// <summary> /// Initializes a new instance of ProxyServer class with provided parameters. /// </summary> /// <param name="rootCertificateName">Name of the root certificate.</param> /// <param name="rootCertificateIssuerName">Name of the root certificate issuer.</param> public ProxyServer(string?rootCertificateName, string?rootCertificateIssuerName) { BufferPool = new DefaultBufferPool(); ProxyEndPoints = new List <ProxyEndPoint>(); tcpConnectionFactory = new TcpConnectionFactory(this); CertificateManager = new CertificateManager(rootCertificateName, rootCertificateIssuerName, ExceptionFunc); }
public async Task ServerAndClientShouldJustWorkInSsl() { using var server = TcpConnectionFactory.CreateSslServer(11000, new SslServerConnectionSettings( sslCertificate: new X509Certificate(Utils.LoadResourceAsByteArray("transact-tcp_pfx"), "password") )); using var client = TcpConnectionFactory.CreateSslClient(IPAddress.Loopback, 11000, connectionSettings: new SslClientConnectionSettings( sslServerHost: "transact-tcp", sslValidateServerCertificateCallback: ( object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) => true //pass everything )); var receivedFromClientEvent = new AsyncAutoResetEvent(false); var receivedFromServerEvent = new AsyncAutoResetEvent(false); client.Start( receivedAction: (c, data) => { if (Encoding.UTF8.GetString(data) == "SENT FROM SERVER") { receivedFromServerEvent.Set(); } }, connectionStateChangedAction: (c, fromState, toState) => { } ); server.Start( receivedAction: (c, data) => { if (Encoding.UTF8.GetString(data) == "SENT FROM CLIENT") { receivedFromClientEvent.Set(); } }, connectionStateChangedAction: (c, fromState, toState) => { } ); //WaitHandle.WaitAll(new[] { clientConnectedEvent, serverConnectedEvent }, 4000).ShouldBeTrue(); await client.WaitForStateAsync(ConnectionState.Connected); await server.WaitForStateAsync(ConnectionState.Connected); await client.SendDataAsync(Encoding.UTF8.GetBytes("SENT FROM CLIENT")); await server.SendDataAsync(Encoding.UTF8.GetBytes("SENT FROM SERVER")); //WaitHandle.WaitAll(new[] { receivedFromClientEvent, receivedFromServerEvent }, 4000).ShouldBeTrue(); (await receivedFromClientEvent.WaitAsync(10000)).ShouldBeTrue(); (await receivedFromServerEvent.WaitAsync(10000)).ShouldBeTrue(); }
private static void RunServer() { using var server = TcpConnectionFactory.CreateServer(15000); server.Start( receivedAction: (connection, data) => Console.WriteLine($"Message from client: {Encoding.UTF8.GetString(data)}"), connectionStateChangedAction: (connection, fromState, toState) => Console.WriteLine($"Server connection state changed from {fromState} to {toState}")); RunConnection(server); }
public void ShouldCreateIpv4Socket_WhenIPv6Disabled() { var client = TcpConnectionFactory.CreateTcpClient(AddressFamily.InterNetwork); client.Client.AddressFamily.Should().Be(AddressFamily.InterNetwork); client.Invoking(c => { var dualMode = c.Client.DualMode; }).ShouldThrow <NotSupportedException>(); }
private static void RunClient() { using var client = TcpConnectionFactory.CreateClient(IPAddress.Loopback, 15000); client.Start( receivedAction: (connection, data) => Console.WriteLine($"Message from server: {Encoding.UTF8.GetString(data)}"), connectionStateChangedAction: (connection, fromState, toState) => Console.WriteLine($"Client connection state changed from {fromState} to {toState}")); RunConnection(client); }
public async Task CancelServerPendingConnectionShouldJustWork() { using var server = TcpConnectionFactory.CreateServer(15001); server.Start(connectionStateChangedAction: (connection, fromState, toState) => { }); server.Stop(); await server.WaitForStateAsync(ConnectionState.Disconnected); }
public void CancelClientPendingConnectionShouldJustWork() { using var client = TcpConnectionFactory.CreateClient(IPAddress.Loopback, 15002); client.Start(connectionStateChangedAction: (connection, fromState, toState) => { }); client.Stop(); AssertEx.IsTrue(() => client.State == ConnectionState.Disconnected); }
/// <summary> /// relays the input clientStream to the server at the specified host name & port with the given httpCmd & headers as prefix /// Usefull for websocket requests /// </summary> /// <param name="bufferSize"></param> /// <param name="connectionTimeOutSeconds"></param> /// <param name="remoteHostName"></param> /// <param name="httpCmd"></param> /// <param name="httpVersion"></param> /// <param name="requestHeaders"></param> /// <param name="isHttps"></param> /// <param name="remotePort"></param> /// <param name="supportedProtocols"></param> /// <param name="remoteCertificateValidationCallback"></param> /// <param name="localCertificateSelectionCallback"></param> /// <param name="clientStream"></param> /// <param name="tcpConnectionFactory"></param> /// <returns></returns> internal static async Task SendRaw(int bufferSize, int connectionTimeOutSeconds, string remoteHostName, int remotePort, string httpCmd, Version httpVersion, Dictionary <string, HttpHeader> requestHeaders, bool isHttps, SslProtocols supportedProtocols, RemoteCertificateValidationCallback remoteCertificateValidationCallback, LocalCertificateSelectionCallback localCertificateSelectionCallback, Stream clientStream, TcpConnectionFactory tcpConnectionFactory, IPEndPoint upStreamEndPoint) { //prepare the prefix content StringBuilder sb = null; if (httpCmd != null || requestHeaders != null) { sb = new StringBuilder(); if (httpCmd != null) { sb.Append(httpCmd); sb.Append(ProxyConstants.NewLine); } if (requestHeaders != null) { foreach (var header in requestHeaders.Select(t => t.Value.ToString())) { sb.Append(header); sb.Append(ProxyConstants.NewLine); } } sb.Append(ProxyConstants.NewLine); } var tcpConnection = await tcpConnectionFactory.CreateClient(bufferSize, connectionTimeOutSeconds, remoteHostName, remotePort, httpVersion, isHttps, supportedProtocols, remoteCertificateValidationCallback, localCertificateSelectionCallback, null, null, clientStream, upStreamEndPoint); try { Stream tunnelStream = tcpConnection.Stream; //Now async relay all server=>client & client=>server data var sendRelay = clientStream.CopyToAsync(sb?.ToString() ?? string.Empty, tunnelStream); var receiveRelay = tunnelStream.CopyToAsync(string.Empty, clientStream); await Task.WhenAll(sendRelay, receiveRelay); } finally { tcpConnection.Dispose(); } }
public async Task ConnectionListenerShouldAcceptNewConnection() { using var multiPeerServer = TcpConnectionFactory.CreateMultiPeerServer(14000); using var client = TcpConnectionFactory.CreateClient(IPAddress.Loopback, 14000); var receivedBackFromServerEvent = new AsyncAutoResetEvent(false); IConnection newConnection = null; multiPeerServer.Start((listener, c) => { newConnection = c; newConnection.Start( receivedActionStreamAsync: async(connection, stream, cancellationToken) => { using var memoryOwner = MemoryPool <byte> .Shared.Rent(4); var buffer = memoryOwner.Memory.Slice(0, 4); await stream.ReadAsync(buffer, cancellationToken); var pingString = Encoding.UTF8.GetString(buffer.Span); await connection.SendDataAsync( new Memory <byte>(Encoding.UTF8.GetBytes($"SERVER RECEIVED: {pingString}"))); }, connectionStateChangedAction: (c, fromState, toState) => { } ); }); client.Start( receivedActionStreamAsync: async(connection, stream, cancellationToken) => { using var memoryOwner = MemoryPool <byte> .Shared.Rent(21); var buffer = memoryOwner.Memory.Slice(0, 21); await stream.ReadAsync(buffer, cancellationToken); if (Encoding.UTF8.GetString(buffer.Span) == "SERVER RECEIVED: PING") { receivedBackFromServerEvent.Set(); } }, connectionStateChangedAction: (c, fromState, toState) => { } ); await client.WaitForStateAsync(ConnectionState.Connected); await client.SendDataAsync(new Memory <byte>(Encoding.UTF8.GetBytes("PING"))); (await receivedBackFromServerEvent.WaitAsync(100000)).ShouldBeTrue(); multiPeerServer.Stop(); }
public async Task SendMessagesUsingMemoryBuffer() { using var server = TcpConnectionFactory.CreateServer(11001); using var client = TcpConnectionFactory.CreateClient(IPAddress.Loopback, 11001); var receivedFromClientEvent = new AsyncAutoResetEvent(false); var receivedFromServerEvent = new AsyncAutoResetEvent(false); client.Start( receivedActionStreamAsync: async(connection, stream, cancellationToken) => { using var memoryOwner = MemoryPool <byte> .Shared.Rent((int)stream.Length); await stream.ReadAsync(memoryOwner.Memory, cancellationToken); if (Encoding.UTF8.GetString(memoryOwner.Memory.Span) == "SENT FROM SERVER") { receivedFromServerEvent.Set(); } }, connectionStateChangedAction: (c, fromState, toState) => { } ); server.Start( receivedActionStreamAsync: async(connection, stream, cancellationToken) => { using var memoryOwner = MemoryPool <byte> .Shared.Rent((int)stream.Length); await stream.ReadAsync(memoryOwner.Memory, cancellationToken); if (Encoding.UTF8.GetString(memoryOwner.Memory.Span) == "SENT FROM CLIENT") { receivedFromClientEvent.Set(); } }, connectionStateChangedAction: (c, fromState, toState) => { } ); //WaitHandle.WaitAll(new[] { clientConnectedEvent, serverConnectedEvent }, 4000).ShouldBeTrue(); await client.WaitForStateAsync(ConnectionState.Connected); await server.WaitForStateAsync(ConnectionState.Connected); await client.SendDataAsync(new Memory <byte>(Encoding.UTF8.GetBytes("SENT FROM CLIENT"))); await server.SendDataAsync(new Memory <byte>(Encoding.UTF8.GetBytes("SENT FROM SERVER"))); //WaitHandle.WaitAll(new[] { receivedFromClientEvent, receivedFromServerEvent }, 10000).ShouldBeTrue(); (await receivedFromClientEvent.WaitAsync(10000)).ShouldBe(true); (await receivedFromServerEvent.WaitAsync(10000)).ShouldBe(true); }
/// <summary> /// Initializes a new instance of ProxyServer class with provided parameters. /// </summary> /// <param name="rootCertificateName">Name of the root certificate.</param> /// <param name="rootCertificateIssuerName">Name of the root certificate issuer.</param> /// <param name="userTrustRootCertificate"> /// Should fake HTTPS certificate be trusted by this machine's user certificate /// store? /// </param> /// <param name="machineTrustRootCertificate">Should fake HTTPS certificate be trusted by this machine's certificate store?</param> /// <param name="trustRootCertificateAsAdmin"> /// Should we attempt to trust certificates with elevated permissions by /// prompting for UAC if required? /// </param> public ProxyServer(string?rootCertificateName, string?rootCertificateIssuerName, bool userTrustRootCertificate = true, bool machineTrustRootCertificate = false, bool trustRootCertificateAsAdmin = false) { BufferPool = new DefaultBufferPool(); ProxyEndPoints = new List <ProxyEndPoint>(); tcpConnectionFactory = new TcpConnectionFactory(this); if (RunTime.IsWindows && !RunTime.IsUwpOnWindows) { systemProxySettingsManager = new SystemProxyManager(); } CertificateManager = new CertificateManager(rootCertificateName, rootCertificateIssuerName, userTrustRootCertificate, machineTrustRootCertificate, trustRootCertificateAsAdmin, ExceptionFunc); }
/// <summary> /// Initializes a new instance of the <see cref="FahClientConnection"/> class. /// </summary> /// <param name="host">The name of the remote host. The host can be an IP address or DNS name.</param> /// <param name="port">The port number of the remote host.</param> /// <param name="tcpConnectionFactory">The factory that will be used to create connections for TCP network services.</param> /// <exception cref="ArgumentNullException">The <paramref name="host" /> parameter is null.</exception> /// <exception cref="ArgumentOutOfRangeException">The <paramref name="port" /> parameter is not between zero and <see cref="Int16.MaxValue"/>.</exception> public FahClientConnection(string host, int port, TcpConnectionFactory tcpConnectionFactory) { if (host is null) { throw new ArgumentNullException(nameof(host)); } if (!TcpPort.Validate(port)) { throw new ArgumentOutOfRangeException(nameof(port)); } Host = host; Port = port; _tcpConnectionFactory = tcpConnectionFactory; }
public ProxyServer(string rootCertificateName, string rootCertificateIssuerName) { RootCertificateName = rootCertificateName; RootCertificateIssuerName = rootCertificateIssuerName; //default values ConnectionTimeOutSeconds = 120; CertificateCacheTimeOutMinutes = 60; ProxyEndPoints = new List <ProxyEndPoint>(); tcpConnectionFactory = new TcpConnectionFactory(); systemProxySettingsManager = new SystemProxyManager(); firefoxProxySettingsManager = new FireFoxProxySettingsManager(); RootCertificateName = RootCertificateName ?? "Titanium Root Certificate Authority"; RootCertificateIssuerName = RootCertificateIssuerName ?? "Titanium"; }
/// <summary> /// Initializes a new instance of ProxyServer class with provided parameters. /// </summary> /// <param name="rootCertificateName">Name of the root certificate.</param> /// <param name="rootCertificateIssuerName">Name of the root certificate issuer.</param> /// <param name="userTrustRootCertificate"> /// Should fake HTTPS certificate be trusted by this machine's user certificate /// store? /// </param> /// <param name="machineTrustRootCertificate">Should fake HTTPS certificate be trusted by this machine's certificate store?</param> /// <param name="trustRootCertificateAsAdmin"> /// Should we attempt to trust certificates with elevated permissions by /// prompting for UAC if required? /// </param> public ProxyServer(string rootCertificateName, string rootCertificateIssuerName, bool userTrustRootCertificate = true, bool machineTrustRootCertificate = false, bool trustRootCertificateAsAdmin = false) { // default values ConnectionTimeOutSeconds = 60; ProxyEndPoints = new List <ProxyEndPoint>(); tcpConnectionFactory = new TcpConnectionFactory(); if (!RunTime.IsRunningOnMono && RunTime.IsWindows) { systemProxySettingsManager = new SystemProxyManager(); } CertificateManager = new CertificateManager(rootCertificateName, rootCertificateIssuerName, userTrustRootCertificate, machineTrustRootCertificate, trustRootCertificateAsAdmin, ExceptionFunc); }
private static void RunClient() { using var client = TcpConnectionFactory.CreateClient(IPAddress.Loopback, 15000); client.Start( receivedAction: (connection, data) => Console.WriteLine($"Message from server: {Encoding.UTF8.GetString(data)}"), connectionStateChangedAction: (connection, fromState, toState) => Console.WriteLine($"Client connection state changed from {fromState} to {toState}")); while (true) { var message = Console.ReadLine(); if (message == null) { break; } client.SendDataAsync(Encoding.UTF8.GetBytes(message)).Wait(); } }
public void TcpConnectionShouldBeFullDuplex() { using var server = TcpConnectionFactory.CreateMultiPeerServer(15025); using var client = TcpConnectionFactory.CreateClient(IPAddress.Loopback, 15025); server.Start((listener, connection) => { connection.Start(async(connection, stream, cancellationToken) => { var buffer = new byte[10]; stream.Read(buffer, 0, 10); await connection.SendAsync((outStream, outCancellationToken) => { outStream.Write(buffer, 0, 10); return(Task.CompletedTask); }); }); }); int receivedMessageBackCount = 0; client.Start((connection, stream, cancellationToken) => { stream.Read(new byte[10], 0, 10); receivedMessageBackCount++; return(Task.CompletedTask); }); client.WaitForState(ConnectionState.Connected); for (int i = 0; i < 1000; i++) { client.SendAsync((stream, cancellationToken) => { stream.Write(new byte[10], 0, 10); return(Task.CompletedTask); }); } AssertEx.IsTrue(() => receivedMessageBackCount == 1000); }
public void ClientShouldReconnectToServerAfterServerRestart() { _logger.Verbose("Begin test ClientShouldReconnectToServerAfterServerRestart"); using var server = TcpConnectionFactory.CreateServer(15004); using var client = TcpConnectionFactory.CreateClient(IPAddress.Loopback, 15004); server.Start(connectionStateChangedAction: (connection, fromState, toState) => { _logger.Verbose($"Server state change from {fromState} to {toState}"); }); client.Start(connectionStateChangedAction: (connection, fromState, toState) => { _logger.Verbose($"Client state change from {fromState} to {toState}"); }); AssertEx.IsTrue(() => server.State == ConnectionState.Connected); AssertEx.IsTrue(() => client.State == ConnectionState.Connected); _logger.Verbose($"Stop server"); server.Stop(); AssertEx.IsTrue(() => server.State == ConnectionState.Disconnected); AssertEx.IsTrue(() => client.State == ConnectionState.LinkError); _logger.Verbose($"Start server"); server.Start(); _logger.Verbose($"Stop server"); server.Stop(); _logger.Verbose($"Stop client"); client.Stop(); AssertEx.IsTrue(() => server.State == ConnectionState.Disconnected); AssertEx.IsTrue(() => client.State == ConnectionState.Disconnected); _logger.Verbose("End test ClientShouldReconnectToServerAfterServerRestart"); }
private static void RunServer() { Console.WriteLine("Starting server..."); using var server = TcpConnectionFactory.CreateMultiPeerServer(15000); server.Start( connectionCreated: (listener, newClientConnection) => { Console.WriteLine($"Client connection accepted"); _connectedClients.TryAdd(newClientConnection, newClientConnection); newClientConnection.Start( receivedAction: (connection, data) => { foreach (var clientConnection in _connectedClients.Keys.Except(new[] { connection })) { clientConnection.SendDataAsync(data).Wait(); } }, connectionStateChangedAction: (connection, fromState, toState) => { if (toState == ConnectionState.Connected) { connection.SendDataAsync(Encoding.UTF8.GetBytes("Welcome from server!")).Wait(); } else if (toState == ConnectionState.LinkError) { _connectedClients.TryRemove(connection, out var _); } }); }); Console.ReadLine(); Console.WriteLine("Closing server..."); }
internal RetryPolicy(int retries, TcpConnectionFactory tcpConnectionFactory) { this.retries = retries; this.tcpConnectionFactory = tcpConnectionFactory; }
public async Task MessagesShouldPassThruRedundantChannelWhenNotAllChildConnectionsAreSlowOrDown() { var toxiproxyServerPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "TransactTcp.Tests", "toxiproxy-server-windows-amd64.exe"); foreach (var existentToxiserverProcess in Process.GetProcessesByName("toxiproxy-server-windows-amd64").ToList()) { existentToxiserverProcess.Kill(); } Directory.CreateDirectory(Path.GetDirectoryName(toxiproxyServerPath)); await File.WriteAllBytesAsync(toxiproxyServerPath, Utils.LoadResourceAsByteArray("toxiproxy-server-windows-amd64.exe")); using var toxyproxyServerProcess = Process.Start(toxiproxyServerPath); try { //Setting up Toxiproxy proxies var connection = new Connection(); var client = connection.Client(); var interface1Proxy = new Proxy() { Name = "interface1Proxy", Enabled = true, Listen = "127.0.0.1:12000", Upstream = "127.0.0.1:12001" }; await client.AddAsync(interface1Proxy); var interface2Proxy = new Proxy() { Name = "interface2Proxy", Enabled = true, Listen = "127.0.0.1:13000", Upstream = "127.0.0.1:13001" }; await client.AddAsync(interface2Proxy); using var serverConnection = TcpConnectionFactory.CreateRedundantServer(new[] { new IPEndPoint(IPAddress.Parse("127.0.0.1"), 12001), new IPEndPoint(IPAddress.Parse("127.0.0.1"), 13001) }); using var clientConnection = TcpConnectionFactory.CreateRedundantClient(new[] { new IPEndPoint(IPAddress.Parse("127.0.0.1"), 12000), new IPEndPoint(IPAddress.Parse("127.0.0.1"), 13000) }); using var serverConnectedEvent = new AutoResetEvent(false); using var clientConnectedEvent = new AutoResetEvent(false); using var errorsOnServerSideEvent = new AutoResetEvent(false); using var errorsOnClientSideEvent = new AutoResetEvent(false); int counterOfMessagesArrivedAtServer = 0; serverConnection.Start( receivedAction: (c, data) => { if (BitConverter.ToInt32(data) != counterOfMessagesArrivedAtServer) { errorsOnServerSideEvent.Set(); } counterOfMessagesArrivedAtServer++; }, connectionStateChangedAction: (c, fromState, toState) => { if (toState == ConnectionState.Connected) { serverConnectedEvent.Set(); } }); int counterOfMessagesArrivedAtClient = 0; clientConnection.Start( receivedAction: (c, data) => { if (BitConverter.ToInt32(data) != counterOfMessagesArrivedAtClient) { errorsOnClientSideEvent.Set(); } counterOfMessagesArrivedAtClient++; }, connectionStateChangedAction: (c, fromState, toState) => { if (toState == ConnectionState.Connected) { clientConnectedEvent.Set(); } }); WaitHandle.WaitAll(new[] { serverConnectedEvent, clientConnectedEvent }, 5000).ShouldBeTrue(); var cancellationTokenSource = new CancellationTokenSource(); #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed Task.Run(async() => { var counter = 0; while (!cancellationTokenSource.IsCancellationRequested) { await clientConnection.SendDataAsync(BitConverter.GetBytes(counter)); await serverConnection.SendDataAsync(BitConverter.GetBytes(counter)); await Task.Delay(500, cancellationTokenSource.Token); counter++; } }, cancellationTokenSource.Token); #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed await Task.Delay(1000); interface1Proxy.Enabled = false; await client.UpdateAsync(interface1Proxy); WaitHandle.WaitAll(new[] { errorsOnServerSideEvent, errorsOnClientSideEvent }, 2000).ShouldBeFalse(); interface1Proxy.Enabled = true; await client.UpdateAsync(interface1Proxy); interface2Proxy.Enabled = false; await client.UpdateAsync(interface2Proxy); WaitHandle.WaitAll(new[] { errorsOnServerSideEvent, errorsOnClientSideEvent }, 2000).ShouldBeFalse(); interface2Proxy.Enabled = true; await client.UpdateAsync(interface2Proxy); var latencyProxy = new LatencyToxic() { Name = "latencyToxicInterface2", Stream = ToxicDirection.DownStream, Toxicity = 1.0, }; latencyProxy.Attributes.Jitter = 100; latencyProxy.Attributes.Latency = 300; await interface1Proxy.AddAsync(latencyProxy); WaitHandle.WaitAll(new[] { errorsOnServerSideEvent, errorsOnClientSideEvent }, 2000).ShouldBeFalse(); var slicerToxic = new SlicerToxic() { Name = "slicerToxicInterface1", Stream = ToxicDirection.UpStream, Toxicity = 1.0, }; slicerToxic.Attributes.AverageSize = 10; slicerToxic.Attributes.Delay = 5; slicerToxic.Attributes.SizeVariation = 1; await interface1Proxy.AddAsync(slicerToxic); WaitHandle.WaitAll(new[] { errorsOnServerSideEvent, errorsOnClientSideEvent }, 4000).ShouldBeFalse(); interface2Proxy.Enabled = false; await client.UpdateAsync(interface2Proxy); WaitHandle.WaitAll(new[] { errorsOnServerSideEvent, errorsOnClientSideEvent }, 2000).ShouldBeFalse(); cancellationTokenSource.Cancel(); } finally { toxyproxyServerProcess.Kill(); } }
/// <summary> /// relays the input clientStream to the server at the specified host name and port with the given httpCmd and headers as prefix /// Usefull for websocket requests /// </summary> /// <param name="server"></param> /// <param name="remoteHostName"></param> /// <param name="remotePort"></param> /// <param name="httpCmd"></param> /// <param name="httpVersion"></param> /// <param name="requestHeaders"></param> /// <param name="isHttps"></param> /// <param name="clientStream"></param> /// <param name="tcpConnectionFactory"></param> /// <param name="connection"></param> /// <returns></returns> internal static async Task SendRaw(ProxyServer server, string remoteHostName, int remotePort, string httpCmd, Version httpVersion, Dictionary <string, HttpHeader> requestHeaders, bool isHttps, Stream clientStream, TcpConnectionFactory tcpConnectionFactory, TcpConnection connection = null) { //prepare the prefix content StringBuilder sb = null; if (httpCmd != null || requestHeaders != null) { sb = new StringBuilder(); if (httpCmd != null) { sb.Append(httpCmd); sb.Append(ProxyConstants.NewLine); } if (requestHeaders != null) { foreach (var header in requestHeaders.Select(t => t.Value.ToString())) { sb.Append(header); sb.Append(ProxyConstants.NewLine); } } sb.Append(ProxyConstants.NewLine); } bool connectionCreated = false; TcpConnection tcpConnection; //create new connection if connection is null if (connection == null) { tcpConnection = await tcpConnectionFactory.CreateClient(server, remoteHostName, remotePort, httpVersion, isHttps, null, null); connectionCreated = true; } else { tcpConnection = connection; } try { Stream tunnelStream = tcpConnection.Stream; //Now async relay all server=>client & client=>server data var sendRelay = clientStream.CopyToAsync(sb?.ToString() ?? string.Empty, tunnelStream); var receiveRelay = tunnelStream.CopyToAsync(string.Empty, clientStream); await Task.WhenAll(sendRelay, receiveRelay); } finally { //if connection was null //then a new connection was created //so dispose the new connection if (connectionCreated) { tcpConnection.Dispose(); Interlocked.Decrement(ref server.serverConnectionCount); } } }