浏览代码

On SOCKS5 proxy: set hostname, not always IP (#1072)

* On SOCKS5 proxy:
The library always resolves the hostname to the IP. Some SOCKS5 proxies don't allow you to specify the IP, they want to resolve the hostname themselves.

The patch sends the proxy the same specified value, IP, or hostname.

* refactor

---------

Co-authored-by: Jordi Vaca <jjvaca@indra.es>
Co-authored-by: Rob Hague <rob.hague00@gmail.com>
Jordi Vaca 1 年之前
父节点
当前提交
27fad71353
共有 1 个文件被更改,包括 21 次插入15 次删除
  1. 21 15
      src/Renci.SshNet/Connection/Socks5Connector.cs

+ 21 - 15
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 @@ namespace Renci.SshNet.Connection
 
         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;
         }