void StartEndpoint(LocalForward localForward) { var startActivity = BridgeEventSource.NewActivity("LocalForwardBridgeStart", activity); Uri hybridConnectionUri = null; TcpLocalForwardBridge tcpListenerBridge = null; BridgeEventSource.Log.LocalForwardBridgeStarting(startActivity, localForward); var rcbs = localForward.RelayConnectionStringBuilder ?? new RelayConnectionStringBuilder(config.AzureRelayConnectionString); rcbs.EntityPath = localForward.RelayName; hybridConnectionUri = new Uri(rcbs.Endpoint, rcbs.EntityPath); try { IPHostEntry localHostEntry = Dns.GetHostEntry(Dns.GetHostName()); // Resolve the host name. Whether this is in the hosts file or in some // form of DNS server shouldn't matter for us here (means we do not touch // the hosts file in this process), but the address MUST resolve to a local // endpoint or to a loopback endpoint IPAddress bindToAddress; Random rnd = new Random(); if (!IPAddress.TryParse(localForward.BindAddress, out bindToAddress)) { IPHostEntry hostEntry = Dns.GetHostEntry(localForward.BindAddress); bindToAddress = hostEntry.AddressList[rnd.Next(hostEntry.AddressList.Length)]; } if (bindToAddress != null) { tcpListenerBridge = TcpLocalForwardBridge.FromConnectionString(rcbs); tcpListenerBridge.Run(new IPEndPoint(bindToAddress, localForward.BindPort)); this.listenerBridges.Add(hybridConnectionUri.AbsoluteUri, tcpListenerBridge); } BridgeEventSource.Log.LocalForwardBridgeStart(startActivity, bindToAddress, localForward); } catch (Exception e) { BridgeEventSource.Log.LocalForwardBridgeStartFailure(startActivity, localForward, e); if (!config.ExitOnForwardFailure.HasValue || config.ExitOnForwardFailure.Value) { throw; } } }
void StartEndpoint(LocalForward localForward, LocalForwardBinding binding) { var startActivity = BridgeEventSource.NewActivity("LocalForwardBridgeStart", activity); Uri hybridConnectionUri = null; BridgeEventSource.Log.LocalForwardBridgeStarting(startActivity, localForward); var rcbs = localForward.RelayConnectionStringBuilder ?? new RelayConnectionStringBuilder(config.AzureRelayConnectionString); rcbs.EntityPath = localForward.RelayName; hybridConnectionUri = new Uri(rcbs.Endpoint, rcbs.EntityPath); #if !NETFRAMEWORK if (!string.IsNullOrEmpty(binding.BindLocalSocket)) { if (Environment.OSVersion.Platform == PlatformID.Win32NT) { BridgeEventSource.Log.ThrowingException( new NotSupportedException("Unix sockets are not supported on Windows")); } SocketLocalForwardBridge socketListenerBridge = null; try { { socketListenerBridge = SocketLocalForwardBridge.FromConnectionString(this.config, rcbs, binding.PortName); socketListenerBridge.Run(binding.BindLocalSocket); this.socketListenerBridges.Add(hybridConnectionUri.AbsoluteUri, socketListenerBridge); } BridgeEventSource.Log.LocalForwardBridgeStart(startActivity, IPAddress.Any, localForward); } catch (Exception e) { BridgeEventSource.Log.LocalForwardBridgeStartFailure(startActivity, localForward, e); if (!config.ExitOnForwardFailure.HasValue || config.ExitOnForwardFailure.Value) { throw; } } return; } #endif if (binding.BindPort > 0) { TcpLocalForwardBridge tcpListenerBridge = null; try { IPHostEntry localHostEntry = Dns.GetHostEntry(Dns.GetHostName()); // Resolve the host name. Whether this is in the hosts file or in some // form of DNS server shouldn't matter for us here (means we do not touch // the hosts file in this process), but the address MUST resolve to a local // endpoint or to a loopback endpoint IPAddress bindToAddress; Random rnd = new Random(); if (!IPAddress.TryParse(binding.BindAddress, out bindToAddress)) { IPHostEntry hostEntry = Dns.GetHostEntry(binding.BindAddress); bindToAddress = hostEntry.AddressList[rnd.Next(hostEntry.AddressList.Length)]; } if (bindToAddress != null) { tcpListenerBridge = TcpLocalForwardBridge.FromConnectionString(this.config, rcbs, binding.PortName); tcpListenerBridge.Run(new IPEndPoint(bindToAddress, binding.BindPort)); this.listenerBridges.Add(hybridConnectionUri.AbsoluteUri, tcpListenerBridge); } BridgeEventSource.Log.LocalForwardBridgeStart(startActivity, bindToAddress, localForward); } catch (Exception e) { BridgeEventSource.Log.LocalForwardBridgeStartFailure(startActivity, localForward, e); if (!config.ExitOnForwardFailure.HasValue || config.ExitOnForwardFailure.Value) { throw; } } } else if (binding.BindPort < 0) { UdpLocalForwardBridge udpListenerBridge = null; try { IPHostEntry localHostEntry = Dns.GetHostEntry(Dns.GetHostName()); // Resolve the host name. Whether this is in the hosts file or in some // form of DNS server shouldn't matter for us here (means we do not touch // the hosts file in this process), but the address MUST resolve to a local // endpoint or to a loopback endpoint IPAddress bindToAddress; Random rnd = new Random(); if (!IPAddress.TryParse(binding.BindAddress, out bindToAddress)) { IPHostEntry hostEntry = Dns.GetHostEntry(binding.BindAddress); bindToAddress = hostEntry.AddressList[rnd.Next(hostEntry.AddressList.Length)]; } if (bindToAddress != null) { udpListenerBridge = UdpLocalForwardBridge.FromConnectionString(this.config, rcbs, binding.PortName); udpListenerBridge.Run(new IPEndPoint(bindToAddress, -binding.BindPort)); this.udpBridges.Add(hybridConnectionUri.AbsoluteUri, udpListenerBridge); } BridgeEventSource.Log.LocalForwardBridgeStart(startActivity, bindToAddress, localForward); } catch (Exception e) { BridgeEventSource.Log.LocalForwardBridgeStartFailure(startActivity, localForward, e); if (!config.ExitOnForwardFailure.HasValue || config.ExitOnForwardFailure.Value) { throw; } } } }
public void SocketBridge() { // not yet supported on Windows. if (Environment.OSVersion.Platform == PlatformID.Win32NT) { return; } // set up the bridge first Config cfg = new Config { AzureRelayConnectionString = Utilities.GetConnectionString(), ExitOnForwardFailure = true }; var lf = new LocalForward { BindLocalSocket = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()), RelayName = "a2", PortName = "test" }; var rf = new RemoteForward { LocalSocket = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()), RelayName = "a2", PortName = "test" }; cfg.LocalForward.Add(lf); cfg.RemoteForward.Add(rf); Host host = new Host(cfg); host.Start(); try { // now try to use it var l = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); l.Bind(new UnixDomainSocketEndPoint(rf.LocalSocket)); l.Listen(5); l.AcceptAsync().ContinueWith((t) => { var c = t.Result; using (var b = new StreamReader(new NetworkStream(c))) { var text = b.ReadLine(); using (var w = new StreamWriter(new NetworkStream(c))) { w.WriteLine(text); w.Flush(); } } }); var s = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); s.Connect(new UnixDomainSocketEndPoint(lf.BindLocalSocket)); var ns = new NetworkStream(s); using (var w = new StreamWriter(ns)) { w.WriteLine("Hello!"); w.Flush(); using (var b = new StreamReader(ns)) { string line = b.ReadLine(); Assert.Equal("Hello!", line); } } s.Close(0); l.Close(0); } finally { host.Stop(); } }