diff --git a/src/Renci.SshNet/Connection/Socks5Connector.cs b/src/Renci.SshNet/Connection/Socks5Connector.cs index 40ee547be..4382d5899 100644 --- a/src/Renci.SshNet/Connection/Socks5Connector.cs +++ b/src/Renci.SshNet/Connection/Socks5Connector.cs @@ -1,6 +1,8 @@ using System; +using System.Diagnostics; using System.Net; using System.Net.Sockets; +using System.Text; using Renci.SshNet.Abstractions; using Renci.SshNet.Common; @@ -244,25 +246,29 @@ private static byte[] CreateSocks5ConnectionRequest(string hostname, ushort port private static byte[] GetSocks5DestinationAddress(string hostname, out byte addressType) { - var ip = Dns.GetHostAddresses(hostname)[0]; + if (IPAddress.TryParse(hostname, out var ipAddress)) + { + Debug.Assert(ipAddress.AddressFamily is AddressFamily.InterNetwork or AddressFamily.InterNetworkV6); + + addressType = ipAddress.AddressFamily == AddressFamily.InterNetwork + ? (byte)0x01 // IPv4 + : (byte)0x04; // IPv6 + + return ipAddress.GetAddressBytes(); + } + + addressType = 0x03; // Domain name - byte[] address; + var byteCount = Encoding.UTF8.GetByteCount(hostname); -#pragma warning disable IDE0010 // Add missing cases - switch (ip.AddressFamily) + if (byteCount > byte.MaxValue) { - case AddressFamily.InterNetwork: - addressType = 0x01; // IPv4 - address = ip.GetAddressBytes(); - break; - case AddressFamily.InterNetworkV6: - addressType = 0x04; // IPv6 - address = ip.GetAddressBytes(); - break; - default: - throw new ProxyException(string.Format("SOCKS5: IP address '{0}' is not supported.", ip)); + throw new ProxyException(string.Format("SOCKS5: SOCKS 5 cannot support host names longer than 255 chars ('{0}').", hostname)); } -#pragma warning restore IDE0010 // Add missing cases + + var address = new byte[1 + byteCount]; + address[0] = (byte)byteCount; + _ = Encoding.UTF8.GetBytes(hostname, 0, hostname.Length, address, 1); return address; }