async Task BridgeSocketConnectionAsync(TcpClient tcpClient) { EventTraceActivity bridgeActivity = BridgeEventSource.NewActivity("LocalForwardBridgeConnection"); try { BridgeEventSource.Log.LocalForwardBridgeConnectionStarting(bridgeActivity, tcpClient, HybridConnectionClient); using (var hybridConnectionStream = await HybridConnectionClient.CreateConnectionAsync()) { // read and write 4-byte header byte[] rd = new byte[4]; int read = 0; hybridConnectionStream.Write(new byte[] { 1, 0, 0, 0 }, 0, 4); for (; read < 4; read += hybridConnectionStream.Read(rd, read, 4 - read)) { ; } BridgeEventSource.Log.LocalForwardBridgeConnectionStart(bridgeActivity, tcpClient, HybridConnectionClient); if (tcpClient.Connected) { await Task.WhenAll( StreamPump.RunAsync(hybridConnectionStream, tcpClient.GetStream(), () => tcpClient.Client.Shutdown(SocketShutdown.Send), cancellationTokenSource.Token), StreamPump.RunAsync(tcpClient.GetStream(), hybridConnectionStream, () => hybridConnectionStream.Shutdown(), cancellationTokenSource.Token)); } } BridgeEventSource.Log.LocalForwardBridgeConnectionStop(bridgeActivity, tcpClient, HybridConnectionClient); } catch (Exception e) { BridgeEventSource.Log.LocalForwardBridgeConnectionFailed(bridgeActivity, e); throw; } }
public async Task HandleConnectionAsync(Microsoft.Azure.Relay.HybridConnectionStream hybridConnectionStream) { using (Socket socket = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP)) { socket.SendBufferSize = socket.ReceiveBufferSize = 65536; socket.SendTimeout = 60000; await socket.ConnectAsync(new UnixDomainSocketEndPoint(targetServer)); var tcpstream = new NetworkStream(socket); CancellationTokenSource socketAbort = new CancellationTokenSource(); await Task.WhenAll( StreamPump.RunAsync(hybridConnectionStream, tcpstream, () => socket.Shutdown(SocketShutdown.Send), socketAbort.Token) .ContinueWith((t) => socketAbort.Cancel(), TaskContinuationOptions.OnlyOnFaulted), StreamPump.RunAsync(tcpstream, hybridConnectionStream, () => hybridConnectionStream.Shutdown(), socketAbort.Token)) .ContinueWith((t) => socketAbort.Cancel(), TaskContinuationOptions.OnlyOnFaulted); } }
public async Task HandleConnectionAsync(HybridConnectionStream hybridConnectionStream) { using (TcpClient client = new TcpClient()) { client.NoDelay = true; client.SendBufferSize = client.ReceiveBufferSize = 65536; client.SendTimeout = 60000; if (config.BindAddress != null) { var computerProperties = IPGlobalProperties.GetIPGlobalProperties(); var unicastAddresses = computerProperties.GetUnicastAddresses(); IList <IPAddress> ipAddresses = null; ipAddresses = IPAddress.TryParse(config.BindAddress, out var ipAddress) ? new[] { ipAddress } : Dns.GetHostEntry(config.BindAddress).AddressList; List <IPAddress> eligibleAddresses = new List <IPAddress>(); eligibleAddresses.AddRange(from hostAddress in ipAddresses where IPAddress.IsLoopback(hostAddress) select hostAddress); eligibleAddresses.AddRange(from unicastAddress in unicastAddresses join hostAddress in ipAddresses on unicastAddress.Address equals hostAddress where !IPAddress.IsLoopback(hostAddress) select hostAddress); // pick one of those eligible endpoints client.Client.Bind(new IPEndPoint(eligibleAddresses[rnd.Next(eligibleAddresses.Count)], 0)); } await client.ConnectAsync(targetServer, targetPort); var tcpstream = client.GetStream(); CancellationTokenSource socketAbort = new CancellationTokenSource(); await Task.WhenAll( StreamPump.RunAsync(hybridConnectionStream, tcpstream, () => client.Client.Shutdown(SocketShutdown.Send), socketAbort.Token) .ContinueWith((t) => socketAbort.Cancel(), TaskContinuationOptions.OnlyOnFaulted), StreamPump.RunAsync(tcpstream, hybridConnectionStream, () => hybridConnectionStream.Shutdown(), socketAbort.Token)) .ContinueWith((t) => socketAbort.Cancel(), TaskContinuationOptions.OnlyOnFaulted); } }
async Task ConnectionPumpLoopAsync(Microsoft.Azure.Relay.HybridConnectionStream hybridConnectionStream) { try { // read and write 4-byte header byte[] rd = new byte[4]; int read = 0; for (; read < 4; read += hybridConnectionStream.Read(rd, read, 4 - read)) { ; } hybridConnectionStream.Write(new byte[] { 1, 0, 0, 0 }, 0, 4); using (hybridConnectionStream) { using (TcpClient client = new TcpClient()) { await client.ConnectAsync(targetServer, targetPort); var tcpstream = client.GetStream(); await Task.WhenAll( StreamPump.RunAsync(hybridConnectionStream, tcpstream, () => client.Client.Shutdown(SocketShutdown.Send), shuttingDown.Token), StreamPump.RunAsync(tcpstream, hybridConnectionStream, () => hybridConnectionStream.Shutdown(), shuttingDown.Token)); } } } catch (Exception e) { BridgeEventSource.Log.HandledExceptionAsWarning(activity, e); } using (var cts = new CancellationTokenSource(TimeSpan.FromMinutes(1))) { await hybridConnectionStream.CloseAsync(cts.Token); } }
async Task BridgeSocketConnectionAsync(Socket socket) { EventTraceActivity bridgeActivity = BridgeEventSource.NewActivity("LocalForwardBridgeConnection"); try { BridgeEventSource.Log.LocalForwardBridgeConnectionStarting(bridgeActivity, localEndpoint, HybridConnectionClient); socket.SendBufferSize = socket.ReceiveBufferSize = 65536; socket.SendTimeout = 60000; var tcpstream = new NetworkStream(socket); using (var hybridConnectionStream = await HybridConnectionClient.CreateConnectionAsync()) { // read and write 4-byte header hybridConnectionStream.WriteTimeout = 60000; // write the 1.0 header with the portname for this connection byte[] portNameBytes = Encoding.UTF8.GetBytes(PortName); byte[] preamble = { /*major*/ 1, /*minor*/ 0, /*stream */ 0, (byte)portNameBytes.Length }; await hybridConnectionStream.WriteAsync(preamble, 0, preamble.Length); await hybridConnectionStream.WriteAsync(portNameBytes, 0, portNameBytes.Length); byte[] replyPreamble = new byte[3]; for (int read = 0; read < replyPreamble.Length;) { var r = await hybridConnectionStream.ReadAsync(replyPreamble, read, replyPreamble.Length - read); if (r == 0) { await hybridConnectionStream.ShutdownAsync(CancellationToken.None); await hybridConnectionStream.CloseAsync(CancellationToken.None); throw new InvalidOperationException($"Malformed preamble from server"); } read += r; } if (!(replyPreamble[0] == 1 && replyPreamble[1] == 0 && replyPreamble[2] == 0)) { // version not supported await hybridConnectionStream.ShutdownAsync(CancellationToken.None); await hybridConnectionStream.CloseAsync(CancellationToken.None); throw new InvalidOperationException($"Unsupported protocol version: Server reply {replyPreamble[0]} {replyPreamble[1]} {replyPreamble[2]}"); } BridgeEventSource.Log.LocalForwardBridgeConnectionStart(bridgeActivity, localEndpoint, HybridConnectionClient); try { CancellationTokenSource socketAbort = new CancellationTokenSource(); await Task.WhenAll( StreamPump.RunAsync(hybridConnectionStream, tcpstream, () => socket.Shutdown(SocketShutdown.Send), socketAbort.Token) .ContinueWith((t) => socketAbort.Cancel(), TaskContinuationOptions.OnlyOnFaulted), StreamPump.RunAsync(tcpstream, hybridConnectionStream, () => hybridConnectionStream?.Shutdown(), socketAbort.Token)) .ContinueWith((t) => socketAbort.Cancel(), TaskContinuationOptions.OnlyOnFaulted); using (var cts = new CancellationTokenSource(TimeSpan.FromMinutes(1))) { await hybridConnectionStream.CloseAsync(cts.Token); } } catch { if (socket.Connected) { socket.Close(0); } throw; } } BridgeEventSource.Log.LocalForwardBridgeConnectionStop(bridgeActivity, localEndpoint, HybridConnectionClient); } catch (Exception e) { BridgeEventSource.Log.LocalForwardBridgeConnectionFailed(bridgeActivity, e); } }