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);
            }
        }
Beispiel #5
0
        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);
            }
        }