public virtual async Task ConnectSocket(Socket socket, EndPoint endpoint, NodeConnectionParameters nodeConnectionParameters, CancellationToken cancellationToken) { var isTor = endpoint.IsTor(); var socksSettings = nodeConnectionParameters.TemplateBehaviors.Find <SocksSettingsBehavior>(); var socketEndpoint = endpoint; var useSocks = isTor || socksSettings?.OnlyForOnionHosts is false; if (useSocks) { if (socksSettings?.SocksEndpoint == null) { throw new InvalidOperationException("SocksSettingsBehavior.SocksEndpoint is not set but the connection is expecting using socks proxy"); } if (!isTor && State.AllowOnlyTorEndpoints) { throw new InvalidOperationException($"The Endpoint connector is configured to allow only Tor endpoints and the '{endpoint}' enpoint is not one"); } socketEndpoint = socksSettings.SocksEndpoint; } if (socketEndpoint is IPEndPoint mappedv4 && mappedv4.Address.IsIPv4MappedToIPv6Ex()) { socketEndpoint = new IPEndPoint(mappedv4.Address.MapToIPv4Ex(), mappedv4.Port); } await socket.ConnectAsync(socketEndpoint, cancellationToken).ConfigureAwait(false); if (useSocks) { await SocksHelper.Handshake(socket, endpoint, GenerateCredentials(), cancellationToken).ConfigureAwait(false); } }
public async Task ConnectSocket(Socket socket, EndPoint endpoint, NodeConnectionParameters nodeConnectionParameters, CancellationToken cancellationToken) { var isTor = endpoint.IsTor(); if (AllowOnlyTorEndpoints && !isTor) { throw new InvalidOperationException($"The Endpoint connector is configured to allow only Tor endpoints and the '{endpoint}' enpoint is not one"); } var socksSettings = nodeConnectionParameters.TemplateBehaviors.Find <SocksSettingsBehavior>(); bool socks = isTor || socksSettings?.OnlyForOnionHosts is false; if (socks && socksSettings?.SocksEndpoint == null) { throw new InvalidOperationException("SocksSettingsBehavior.SocksEndpoint is not set but the connection is expecting using socks proxy"); } var socketEndpoint = socks ? socksSettings.SocksEndpoint : endpoint; if (socketEndpoint is IPEndPoint mappedv4 && mappedv4.Address.IsIPv4MappedToIPv6Ex()) { socketEndpoint = new IPEndPoint(mappedv4.Address.MapToIPv4Ex(), mappedv4.Port); } #if NETCORE await socket.ConnectAsync(socketEndpoint).WithCancellation(cancellationToken).ConfigureAwait(false); #else await socket.ConnectAsync(socketEndpoint, cancellationToken).ConfigureAwait(false); #endif if (!socks) { return; } await SocksHelper.Handshake(socket, endpoint, cancellationToken); }
public async Task ConnectSocket(Socket socket, EndPoint endpoint, NodeConnectionParameters nodeConnectionParameters, CancellationToken cancellationToken) { var socksSettings = nodeConnectionParameters.TemplateBehaviors.Find <SocksSettingsBehavior>(); var socketEndpoint = endpoint; var useSocks = endpoint.IsTor() || socksSettings?.OnlyForOnionHosts is false; if (useSocks) { if (socksSettings?.SocksEndpoint == null) { throw new InvalidOperationException("SocksSettingsBehavior.SocksEndpoint is not set but the connection is expecting using socks proxy"); } socketEndpoint = socksSettings.SocksEndpoint; } if (socketEndpoint is IPEndPoint mappedv4 && mappedv4.Address.IsIPv4MappedToIPv6Ex()) { socketEndpoint = new IPEndPoint(mappedv4.Address.MapToIPv4Ex(), mappedv4.Port); } await socket.ConnectAsync(socketEndpoint, cancellationToken).ConfigureAwait(false); if (!useSocks) { return; } await SocksHelper.Handshake(socket, endpoint, socksSettings.GetCredentials(), cancellationToken).ConfigureAwait(false); }
public async Task <IPAddress[]> GetHostAddressesAsync(string hostNameOrAddress, CancellationToken cancellationToken) { // https://gitweb.torproject.org/torspec.git/tree/socks-extensions.txt#n44 if (string.IsNullOrEmpty(hostNameOrAddress)) { throw new ArgumentNullException(nameof(hostNameOrAddress)); } var ascii = Encoding.ASCII.GetBytes(hostNameOrAddress); if (ascii.Length > 255) { throw new ArgumentException("hostNameOrAddress should be less than 256 chars", nameof(hostNameOrAddress)); } using var socket = new Socket(SocketType.Stream, ProtocolType.Tcp); await socket.ConnectAsync(SocksEndpoint, cancellationToken).ConfigureAwait(false); await SocksHelper.Handshake(socket, GetCredentials(), cancellationToken).ConfigureAwait(false); var req = new byte[7 + ascii.Length]; int o = 0; req[o++] = 0x05; req[o++] = 0xf0; req[o++] = 0x00; req[o++] = 0x03; req[o++] = (byte)ascii.Length; ascii.CopyTo(req, o); o += ascii.Length; req[o++] = 0x00; req[o++] = 0x00; NetworkStream stream = new NetworkStream(socket, false); await stream.WriteAsync(req, 0, req.Length).WithCancellation(cancellationToken).ConfigureAwait(false); await stream.ReadAsync(req, 0, 4).WithCancellation(cancellationToken).ConfigureAwait(false); var ipLen = req[3] == 1 ? 4 : req[3] == 4 ? 16 : throw new SocketException(11001); var ip = new byte[ipLen]; await stream.ReadAsync(ip, 0, ipLen).WithCancellation(cancellationToken).ConfigureAwait(false); var address = new IPAddress(ip); await stream.ReadAsync(req, 0, 2).WithCancellation(cancellationToken).ConfigureAwait(false); return(new[] { address }); }
public async Task ConnectSocket(Socket socket, EndPoint endpoint, NodeConnectionParameters nodeConnectionParameters, CancellationToken cancellationToken) { var isTor = endpoint.IsTor(); if (AllowOnlyTorEndpoints && !isTor) { throw new InvalidOperationException($"The Endpoint connector is configured to allow only Tor endpoints and the '{endpoint}' enpoint is not one"); } var socksSettings = nodeConnectionParameters.TemplateBehaviors.Find <SocksSettingsBehavior>(); var socketEndpoint = endpoint; var useSocks = isTor || socksSettings?.OnlyForOnionHosts is false || endpoint.IsI2P(); if (useSocks) { if (socksSettings?.SocksEndpoint == null) { throw new InvalidOperationException("SocksSettingsBehavior.SocksEndpoint is not set but the connection is expecting using socks proxy"); } socketEndpoint = NormalizeEndpoint(socksSettings.SocksEndpoint); await socket.ConnectAsync(socketEndpoint, cancellationToken).ConfigureAwait(false); await SocksHelper.Handshake(socket, endpoint, socksSettings.GetCredentials(), cancellationToken).ConfigureAwait(false); } else { if (socketEndpoint is DnsEndPoint dnsEndpoint) { IDnsResolver resolver = DnsResolver.Instance; if (socksSettings?.SocksEndpoint != null) { resolver = socksSettings.CreateDnsResolver(); } var address = (await resolver.GetHostAddressesAsync(dnsEndpoint.Host, cancellationToken)).First(); socketEndpoint = new IPEndPoint(address, dnsEndpoint.Port); } socketEndpoint = NormalizeEndpoint(socketEndpoint); await socket.ConnectAsync(socketEndpoint, cancellationToken).ConfigureAwait(false); } }