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); } }
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); } }