public async Task ResolveDomainNameAsync(IReadOnlyList <NameServerAddress> nameServers = null, NetProxy proxy = null, bool preferIPv6 = false, bool randomizeName = false, int retries = 2, int timeout = 2000)
        {
            if (_ipEndPoint != null)
            {
                DnsClient dnsClient;

                if (nameServers == null)
                {
                    dnsClient = new DnsClient();
                }
                else
                {
                    dnsClient = new DnsClient(nameServers);
                }

                dnsClient.Proxy         = proxy;
                dnsClient.PreferIPv6    = preferIPv6;
                dnsClient.RandomizeName = randomizeName;
                dnsClient.Retries       = retries;
                dnsClient.Timeout       = timeout;

                try
                {
                    IReadOnlyList <string> ptrDomains = await dnsClient.ResolvePTRAsync(_ipEndPoint.Address);

                    if (ptrDomains != null)
                    {
                        _domainEndPoint = new DomainEndPoint(ptrDomains[0], _ipEndPoint.Port);
                    }
                }
                catch
                { }
            }
        }
Beispiel #2
0
        public Socket Connect(EndPoint remoteEP, Socket viaSocket)
        {
            switch (remoteEP.AddressFamily)
            {
            case AddressFamily.InterNetwork:
            {
                IPEndPoint ep = remoteEP as IPEndPoint;
                return(Connect(ep.Address.ToString(), ep.Port, viaSocket));
            }

            case AddressFamily.InterNetworkV6:
            {
                IPEndPoint ep = remoteEP as IPEndPoint;
                return(Connect("[" + ep.Address.ToString() + "]", ep.Port, viaSocket));
            }

            case AddressFamily.Unspecified:     //domain
            {
                DomainEndPoint ep = remoteEP as DomainEndPoint;
                return(Connect(ep.Address, ep.Port, viaSocket));
            }

            default:
                throw new NotSupportedException("AddressFamily not supported.");
            }
        }
Beispiel #3
0
        public NameServerAddress(EndPoint endPoint)
        {
            switch (endPoint.AddressFamily)
            {
            case AddressFamily.InterNetwork:
            case AddressFamily.InterNetworkV6:
                _ipEndPoint = endPoint as IPEndPoint;
                break;

            case AddressFamily.Unspecified:
                _domainEndPoint = endPoint as DomainEndPoint;
                break;

            default:
                throw new NotSupportedException("AddressFamily not supported.");
            }

            if (endPoint.AddressFamily == AddressFamily.InterNetworkV6)
            {
                _originalAddress = "[" + (endPoint as IPEndPoint).Address.ToString() + "]:" + (endPoint as IPEndPoint).Port;
            }
            else
            {
                _originalAddress = endPoint.ToString();
            }
        }
Beispiel #4
0
        private ICollection <EndPoint> RemoveSelfEndPoint(EndPoint[] peers, EndPoint selfEndPoint)
        {
            switch (selfEndPoint.AddressFamily)
            {
            case AddressFamily.InterNetwork:
            case AddressFamily.InterNetworkV6:
                selfEndPoint = new IPEndPoint((selfEndPoint as IPEndPoint).Address, _localServicePort);
                break;

            case AddressFamily.Unspecified:
                selfEndPoint = new DomainEndPoint((selfEndPoint as DomainEndPoint).Address, _localServicePort);
                break;

            default:
                return(peers);
            }

            List <EndPoint> newList = new List <EndPoint>();

            foreach (EndPoint peer in peers)
            {
                if (!selfEndPoint.Equals(peer))
                {
                    newList.Add(peer);
                }
            }

            return(newList);
        }
Beispiel #5
0
        public void ResolveDomainName(NameServerAddress[] nameServers = null, NetProxy proxy = null, bool preferIPv6 = false, DnsTransportProtocol protocol = DnsTransportProtocol.Udp, int retries = 2, int timeout = 2000)
        {
            if (_ipEndPoint != null)
            {
                DnsClient dnsClient;

                if (nameServers == null)
                {
                    dnsClient = new DnsClient();
                }
                else
                {
                    dnsClient = new DnsClient(nameServers);
                }

                dnsClient.Proxy      = proxy;
                dnsClient.PreferIPv6 = preferIPv6;
                dnsClient.Protocol   = protocol;
                dnsClient.Retries    = retries;
                dnsClient.Timeout    = timeout;

                try
                {
                    string domain = dnsClient.ResolvePTR(_ipEndPoint.Address);
                    _domainEndPoint = new DomainEndPoint(domain, _ipEndPoint.Port);
                }
                catch
                { }
            }
        }
Beispiel #6
0
        private static byte[] CreateUdpDatagram(byte[] buffer, int offset, int size, EndPoint dstAddr)
        {
            //get type, address bytes & port bytes
            SocksAddressType type;

            byte[] address;
            ushort port;

            switch (dstAddr.AddressFamily)
            {
            case AddressFamily.InterNetwork:
            {
                type = SocksAddressType.IPv4Address;

                IPEndPoint ep = dstAddr as IPEndPoint;
                address = ep.Address.GetAddressBytes();
                port    = Convert.ToUInt16(ep.Port);
            }
            break;

            case AddressFamily.InterNetworkV6:
            {
                type = SocksAddressType.IPv6Address;

                IPEndPoint ep = dstAddr as IPEndPoint;
                address = ep.Address.GetAddressBytes();
                port    = Convert.ToUInt16(ep.Port);
            }
            break;

            case AddressFamily.Unspecified:
            {
                type = SocksAddressType.DomainName;

                DomainEndPoint ep = dstAddr as DomainEndPoint;
                address = ep.GetAddressBytes();
                port    = Convert.ToUInt16(ep.Port);
            }
            break;

            default:
                throw new NotSupportedException("AddressFamily not supported.");
            }

            //create datagram
            byte[] datagram = new byte[address.Length + 6 + size];

            datagram[2] = 0x00;
            datagram[3] = (byte)type;

            Buffer.BlockCopy(address, 0, datagram, 4, address.Length);

            byte[] portBytes = BitConverter.GetBytes(port);
            Array.Reverse(portBytes);
            Buffer.BlockCopy(portBytes, 0, datagram, 4 + address.Length, 2);

            Buffer.BlockCopy(buffer, offset, datagram, 4 + address.Length + 2, size);

            return(datagram);
        }
Beispiel #7
0
        private static byte[] CreateRequest(SocksRequestCommand command, EndPoint dstAddr)
        {
            //get type, address bytes & port bytes
            SocksAddressType type;

            byte[] address;
            ushort port;

            switch (dstAddr.AddressFamily)
            {
            case AddressFamily.InterNetwork:
            {
                type = SocksAddressType.IPv4Address;

                IPEndPoint ep = dstAddr as IPEndPoint;
                address = ep.Address.GetAddressBytes();
                port    = Convert.ToUInt16(ep.Port);
            }
            break;

            case AddressFamily.InterNetworkV6:
            {
                type = SocksAddressType.IPv6Address;

                IPEndPoint ep = dstAddr as IPEndPoint;
                address = ep.Address.GetAddressBytes();
                port    = Convert.ToUInt16(ep.Port);
            }
            break;

            case AddressFamily.Unspecified:
            {
                type = SocksAddressType.DomainName;

                DomainEndPoint ep = dstAddr as DomainEndPoint;
                address = ep.GetAddressBytes();
                port    = Convert.ToUInt16(ep.Port);
            }
            break;

            default:
                throw new NotSupportedException("AddressFamily not supported.");
            }

            //create request
            byte[] request = new byte[address.Length + 6];

            request[0] = SOCKS_VERSION;
            request[1] = (byte)command;
            request[3] = (byte)type;

            Buffer.BlockCopy(address, 0, request, 4, address.Length);

            byte[] portBytes = BitConverter.GetBytes(port);
            Array.Reverse(portBytes);
            Buffer.BlockCopy(portBytes, 0, request, 4 + address.Length, 2);

            return(request);
        }
Beispiel #8
0
        internal static async Task WriteEndPointAsync(EndPoint endPoint, Stream s)
        {
            SocksAddressType addressType;

            byte[] address;
            ushort port;

            switch (endPoint.AddressFamily)
            {
            case AddressFamily.InterNetwork:
            {
                addressType = SocksAddressType.IPv4Address;

                IPEndPoint ep = endPoint as IPEndPoint;
                address = ep.Address.GetAddressBytes();
                port    = Convert.ToUInt16(ep.Port);
            }
            break;

            case AddressFamily.InterNetworkV6:
            {
                addressType = SocksAddressType.IPv6Address;

                IPEndPoint ep = endPoint as IPEndPoint;
                address = ep.Address.GetAddressBytes();
                port    = Convert.ToUInt16(ep.Port);
            }
            break;

            case AddressFamily.Unspecified:
            {
                addressType = SocksAddressType.DomainName;

                DomainEndPoint ep = endPoint as DomainEndPoint;
                if (ep == null)
                {
                    throw new NotSupportedException("AddressFamily not supported.");
                }

                address = ep.GetAddressBytes();
                port    = Convert.ToUInt16(ep.Port);
            }
            break;

            default:
                throw new NotSupportedException("AddressFamily not supported.");
            }

            byte[] portBytes = BitConverter.GetBytes(port);
            Array.Reverse(portBytes);

            await s.WriteAsync(new byte[] { (byte)addressType });

            await s.WriteAsync(address, 0, address.Length);

            await s.WriteAsync(portBytes, 0, 2);
        }
        public NameServerAddress(NameServerAddress nameServer, DnsTransportProtocol protocol)
        {
            _protocol        = protocol;
            _originalAddress = nameServer._originalAddress;

            _dohEndPoint    = nameServer._dohEndPoint;
            _domainEndPoint = nameServer._domainEndPoint;
            _ipEndPoint     = nameServer._ipEndPoint;

            _ipEndPointExpires   = nameServer._ipEndPointExpires;
            _ipEndPointExpiresOn = nameServer._ipEndPointExpiresOn;

            ValidateProtocol();
        }
        public NameServerAddress(BinaryReader bR)
        {
            switch (bR.ReadByte())
            {
            case 1:
                if (bR.ReadBoolean())
                {
                    _dohEndPoint = new Uri(bR.ReadShortString());
                }

                if (bR.ReadBoolean())
                {
                    _domainEndPoint = EndPointExtension.Parse(bR) as DomainEndPoint;
                }

                if (bR.ReadBoolean())
                {
                    _ipEndPoint = EndPointExtension.Parse(bR) as IPEndPoint;
                }

                if (_dohEndPoint != null)
                {
                    _originalAddress = _dohEndPoint.AbsoluteUri;
                }
                else if (_ipEndPoint != null)
                {
                    _originalAddress = _ipEndPoint.ToString();
                }
                else if (_domainEndPoint != null)
                {
                    _originalAddress = _domainEndPoint.ToString();
                }

                GuessProtocol();
                break;

            case 2:
                Parse(bR.ReadShortString());
                GuessProtocol();
                break;

            case 3:
                _protocol = (DnsTransportProtocol)bR.ReadByte();
                Parse(bR.ReadShortString());
                break;

            default:
                throw new InvalidDataException("NameServerAddress version not supported");
            }
        }
Beispiel #11
0
        public NameServerAddress(string domain, IPEndPoint ipEndPoint)
        {
            _domainEndPoint = new DomainEndPoint(domain, ipEndPoint.Port);
            _ipEndPoint     = ipEndPoint;

            if (ipEndPoint.AddressFamily == AddressFamily.InterNetworkV6)
            {
                _originalAddress = domain + " ([" + ipEndPoint.Address.ToString() + "]:" + ipEndPoint.Port + ")";
            }
            else
            {
                _originalAddress = domain + " (" + ipEndPoint.ToString() + ")";
            }
        }
Beispiel #12
0
        public NameServerAddress(string domain, IPAddress address)
        {
            _domainEndPoint = new DomainEndPoint(domain, 53);
            _ipEndPoint     = new IPEndPoint(address, 53);

            if (address.AddressFamily == AddressFamily.InterNetworkV6)
            {
                _originalAddress = domain + " ([" + address.ToString() + "])";
            }
            else
            {
                _originalAddress = domain + " (" + address.ToString() + ")";
            }
        }
Beispiel #13
0
        public Socket Connect(string address, int port, int timeout = 10000)
        {
            EndPoint remoteEP;

            if (IPAddress.TryParse(address, out IPAddress ipAddr))
            {
                remoteEP = new IPEndPoint(ipAddr, port);
            }
            else
            {
                remoteEP = new DomainEndPoint(address, port);
            }

            return(Connect(remoteEP, timeout));
        }
Beispiel #14
0
        public TunnelProxy CreateLocalTunnelProxy(string address, int port, int timeout = 10000, bool enableSsl = false, bool ignoreCertificateErrors = false)
        {
            EndPoint remoteEP;

            if (IPAddress.TryParse(address, out IPAddress ipAddr))
            {
                remoteEP = new IPEndPoint(ipAddr, port);
            }
            else
            {
                remoteEP = new DomainEndPoint(address, port);
            }

            return(CreateLocalTunnelProxy(remoteEP, timeout, enableSsl, ignoreCertificateErrors));
        }
Beispiel #15
0
 public void RecursiveResolveDomainName(DnsCache cache = null, NetProxy proxy = null, bool preferIPv6 = false, int retries = 2, int timeout = 2000, bool useTcp = false)
 {
     if (_ipEndPoint != null)
     {
         try
         {
             string ptrDomain = DnsClient.ParseResponsePTR(DnsClient.RecursiveQuery(new DnsQuestionRecord(_ipEndPoint.Address, DnsClass.IN), cache, proxy, preferIPv6, retries, timeout, useTcp));
             if (ptrDomain != null)
             {
                 _domainEndPoint = new DomainEndPoint(ptrDomain, _ipEndPoint.Port);
             }
         }
         catch
         { }
     }
 }
 public async Task RecursiveResolveDomainNameAsync(IDnsCache cache = null, NetProxy proxy = null, bool preferIPv6 = false, bool randomizeName = false, int retries = 2, int timeout = 2000)
 {
     if (_ipEndPoint != null)
     {
         try
         {
             IReadOnlyList <string> ptrDomains = DnsClient.ParseResponsePTR(await DnsClient.RecursiveResolveQueryAsync(new DnsQuestionRecord(_ipEndPoint.Address, DnsClass.IN), cache, proxy, preferIPv6, randomizeName, retries, timeout));
             if (ptrDomains != null)
             {
                 _domainEndPoint = new DomainEndPoint(ptrDomains[0], _ipEndPoint.Port);
             }
         }
         catch
         { }
     }
 }
Beispiel #17
0
 public void RecursiveResolveDomainName(DnsCache cache = null, NetProxy proxy = null, bool preferIPv6 = false, DnsTransportProtocol protocol = DnsTransportProtocol.Udp, int retries = 2, int timeout = 2000, DnsTransportProtocol recursiveResolveProtocol = DnsTransportProtocol.Udp)
 {
     if (_ipEndPoint != null)
     {
         try
         {
             DnsDatagram nsResponse = DnsClient.RecursiveResolve(new DnsQuestionRecord(_ipEndPoint.Address, DnsClass.IN), null, cache, proxy, preferIPv6, protocol, retries, timeout, recursiveResolveProtocol);
             if ((nsResponse.Header.RCODE == DnsResponseCode.NoError) && (nsResponse.Answer.Length > 0) && (nsResponse.Answer[0].Type == DnsResourceRecordType.PTR))
             {
                 _domainEndPoint = new DomainEndPoint((nsResponse.Answer[0].RDATA as DnsPTRRecord).PTRDomainName, _ipEndPoint.Port);
             }
         }
         catch
         { }
     }
 }
        public NameServerAddress(string domain, IPAddress address, DnsTransportProtocol protocol = DnsTransportProtocol.Udp)
        {
            _domainEndPoint = new DomainEndPoint(domain, 53);
            _ipEndPoint     = new IPEndPoint(address, 53);

            _protocol = protocol;

            if (address.AddressFamily == AddressFamily.InterNetworkV6)
            {
                _originalAddress = domain + " ([" + address.ToString() + "])";
            }
            else
            {
                _originalAddress = domain + " (" + address.ToString() + ")";
            }

            ValidateProtocol();
        }
        public NameServerAddress(string domain, IPEndPoint ipEndPoint, DnsTransportProtocol protocol = DnsTransportProtocol.Udp)
        {
            _domainEndPoint = new DomainEndPoint(domain, ipEndPoint.Port);
            _ipEndPoint     = ipEndPoint;

            _protocol = protocol;

            if (ipEndPoint.AddressFamily == AddressFamily.InterNetworkV6)
            {
                _originalAddress = domain + " ([" + ipEndPoint.Address.ToString() + "]:" + ipEndPoint.Port + ")";
            }
            else
            {
                _originalAddress = domain + " (" + ipEndPoint.ToString() + ")";
            }

            ValidateProtocol();
        }
Beispiel #20
0
        public async Task <UdpReceiveFromResult> ReceiveFromAsync(byte[] buffer, int offset, int count)
        {
            byte[] datagram = new byte[262 + count];

            UdpReceiveFromResult result = await _udpSocket.ReceiveFromAsync(datagram);

            if (result.BytesReceived < 10)
            {
                throw new SocksProxyException("Incomplete SOCKS5 datagram was received.");
            }

            EndPoint remoteEP;

            switch ((SocksAddressType)datagram[3])
            {
            case SocksAddressType.IPv4Address:
            {
                byte[] address = new byte[4];
                Buffer.BlockCopy(datagram, 3 + 1, address, 0, 4);

                byte[] port = new byte[2];
                Buffer.BlockCopy(datagram, 3 + 1 + 4, port, 0, 2);
                Array.Reverse(port);

                remoteEP = new IPEndPoint(new IPAddress(address), BitConverter.ToUInt16(port, 0));
            }
            break;

            case SocksAddressType.IPv6Address:
            {
                byte[] address = new byte[16];
                Buffer.BlockCopy(datagram, 3 + 1, address, 0, 16);

                byte[] port = new byte[2];
                Buffer.BlockCopy(datagram, 3 + 1 + 16, port, 0, 2);
                Array.Reverse(port);

                remoteEP = new IPEndPoint(new IPAddress(address), BitConverter.ToUInt16(port, 0));
            }
            break;

            case SocksAddressType.DomainName:
            {
                int length = datagram[3 + 1];

                byte[] address = new byte[length];
                Buffer.BlockCopy(datagram, 3 + 1 + 1, address, 0, length);

                byte[] port = new byte[2];
                Buffer.BlockCopy(datagram, 3 + 1 + 1 + length, port, 0, 2);
                Array.Reverse(port);

                remoteEP = new DomainEndPoint(Encoding.ASCII.GetString(address), BitConverter.ToUInt16(port, 0));
            }
            break;

            default:
                throw new NotSupportedException("SocksAddressType not supported.");
            }

            int addressSize;

            switch (remoteEP.AddressFamily)
            {
            case AddressFamily.InterNetwork:
                addressSize = 4;
                break;

            case AddressFamily.InterNetworkV6:
                addressSize = 16;
                break;

            case AddressFamily.Unspecified:
                addressSize = 1 + (remoteEP as DomainEndPoint).Address.Length;
                break;

            default:
                throw new NotSupportedException("AddressFamily not supported.");
            }

            int dataOffset = 6 + addressSize;
            int dataSize   = result.BytesReceived - dataOffset;

            if (dataSize > count)
            {
                dataSize = count;
            }

            Buffer.BlockCopy(datagram, dataOffset, buffer, offset, dataSize);

            if (_relayEP == null)
            {
                _relayEP = result.RemoteEndPoint; //set new relay ep
            }
            return(new UdpReceiveFromResult(dataSize, remoteEP));
        }
Beispiel #21
0
        private Socket GetProxyConnection(int timeout)
        {
            Socket     socket;
            IPEndPoint hostEP;

            switch (_proxyEP.AddressFamily)
            {
            case AddressFamily.InterNetwork:
                socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                hostEP = _proxyEP as IPEndPoint;
                break;

            case AddressFamily.InterNetworkV6:
                socket = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp);
                hostEP = _proxyEP as IPEndPoint;
                break;

            case AddressFamily.Unspecified:
                DomainEndPoint ep = _proxyEP as DomainEndPoint;

                IPAddress[] ipAddresses = System.Net.Dns.GetHostAddresses(ep.Address);
                if (ipAddresses.Length == 0)
                {
                    throw new SocketException((int)SocketError.HostNotFound);
                }

                hostEP = new IPEndPoint(ipAddresses[0], ep.Port);

                switch (hostEP.AddressFamily)
                {
                case AddressFamily.InterNetwork:
                    socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    break;

                case AddressFamily.InterNetworkV6:
                    socket = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp);
                    break;

                default:
                    throw new SocksClientException("Invalid socks address type.");
                }

                break;

            default:
                throw new SocksClientException("Invalid socks address type.");
            }

            IAsyncResult result = socket.BeginConnect(hostEP, null, null);

            if (!result.AsyncWaitHandle.WaitOne(timeout))
            {
                throw new SocketException((int)SocketError.TimedOut);
            }

            if (!socket.Connected)
            {
                throw new SocketException((int)SocketError.ConnectionRefused);
            }

            return(socket);
        }
        public Task <int> SendToAsync(ArraySegment <byte> buffer, EndPoint remoteEP)
        {
            if (_relayEP == null)
            {
                return(Task.FromResult(0)); //relay ep not known yet
            }
            //get type, address bytes & port bytes
            SocksAddressType type;

            byte[] address;
            ushort port;

            switch (remoteEP.AddressFamily)
            {
            case AddressFamily.InterNetwork:
            {
                type = SocksAddressType.IPv4Address;

                IPEndPoint ep = remoteEP as IPEndPoint;
                address = ep.Address.GetAddressBytes();
                port    = Convert.ToUInt16(ep.Port);
            }
            break;

            case AddressFamily.InterNetworkV6:
            {
                type = SocksAddressType.IPv6Address;

                IPEndPoint ep = remoteEP as IPEndPoint;
                address = ep.Address.GetAddressBytes();
                port    = Convert.ToUInt16(ep.Port);
            }
            break;

            case AddressFamily.Unspecified:
            {
                type = SocksAddressType.DomainName;

                DomainEndPoint ep = remoteEP as DomainEndPoint;
                address = ep.GetAddressBytes();
                port    = Convert.ToUInt16(ep.Port);
            }
            break;

            default:
                throw new NotSupportedException("AddressFamily not supported.");
            }

            //create datagram
            byte[] datagram = new byte[address.Length + 6 + buffer.Count];

            datagram[2] = 0x00;
            datagram[3] = (byte)type;

            Buffer.BlockCopy(address, 0, datagram, 4, address.Length);

            byte[] portBytes = BitConverter.GetBytes(port);
            Array.Reverse(portBytes);
            Buffer.BlockCopy(portBytes, 0, datagram, 4 + address.Length, 2);

            buffer.CopyTo(datagram, 4 + address.Length + 2);

            //send datagram
            return(_udpSocket.SendToAsync(datagram, SocketFlags.None, _relayEP));
        }
        public async Task <SocketReceiveFromResult> ReceiveFromAsync(ArraySegment <byte> buffer)
        {
            byte[] datagram = new byte[262 + buffer.Count];

            SocketReceiveFromResult result = await _udpSocket.ReceiveFromAsync(datagram, SocketFlags.None, SocketExtension.GetEndPointAnyFor(_udpSocket.AddressFamily));

            if (result.ReceivedBytes < 10)
            {
                throw new SocksProxyException("Incomplete SOCKS5 datagram was received.");
            }

            EndPoint remoteEP;

            switch ((SocksAddressType)datagram[3])
            {
            case SocksAddressType.IPv4Address:
            {
                byte[] address = new byte[4];
                Buffer.BlockCopy(datagram, 3 + 1, address, 0, 4);

                byte[] port = new byte[2];
                Buffer.BlockCopy(datagram, 3 + 1 + 4, port, 0, 2);
                Array.Reverse(port);

                remoteEP = new IPEndPoint(new IPAddress(address), BitConverter.ToUInt16(port, 0));
            }
            break;

            case SocksAddressType.IPv6Address:
            {
                byte[] address = new byte[16];
                Buffer.BlockCopy(datagram, 3 + 1, address, 0, 16);

                byte[] port = new byte[2];
                Buffer.BlockCopy(datagram, 3 + 1 + 16, port, 0, 2);
                Array.Reverse(port);

                remoteEP = new IPEndPoint(new IPAddress(address), BitConverter.ToUInt16(port, 0));
            }
            break;

            case SocksAddressType.DomainName:
            {
                int length = datagram[3 + 1];

                byte[] address = new byte[length];
                Buffer.BlockCopy(datagram, 3 + 1 + 1, address, 0, length);

                byte[] port = new byte[2];
                Buffer.BlockCopy(datagram, 3 + 1 + 1 + length, port, 0, 2);
                Array.Reverse(port);

                remoteEP = new DomainEndPoint(Encoding.ASCII.GetString(address), BitConverter.ToUInt16(port, 0));
            }
            break;

            default:
                throw new NotSupportedException("SocksAddressType not supported.");
            }

            int addressSize;

            switch (remoteEP.AddressFamily)
            {
            case AddressFamily.InterNetwork:
                addressSize = 4;
                break;

            case AddressFamily.InterNetworkV6:
                addressSize = 16;
                break;

            case AddressFamily.Unspecified:
                addressSize = 1 + (remoteEP as DomainEndPoint).Address.Length;
                break;

            default:
                throw new NotSupportedException("AddressFamily not supported.");
            }

            int dataOffset = 6 + addressSize;
            int dataSize   = result.ReceivedBytes - dataOffset;

            if (dataSize > buffer.Count)
            {
                dataSize = buffer.Count;
            }

            ArraySegment <byte> recvData = new ArraySegment <byte>(datagram, dataOffset, dataSize);

            recvData.CopyTo(buffer);

            if (_relayEP == null)
            {
                _relayEP = result.RemoteEndPoint; //set new relay ep
            }
            return(new SocketReceiveFromResult()
            {
                ReceivedBytes = dataSize, RemoteEndPoint = remoteEP
            });
        }
        protected override async Task UpdateTrackerAsync(TrackerClientEvent @event, IPEndPoint clientEP)
        {
            SocksProxyUdpAssociateHandler proxyHandler = null;
            Socket   udpSocket = null;
            EndPoint trackerEP = new DomainEndPoint(_trackerURI.Host, _trackerURI.Port);

            if (_proxy == null)
            {
                trackerEP = await trackerEP.GetIPEndPointAsync();

                udpSocket = new Socket(trackerEP.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
            }
            else
            {
                switch (_proxy.Type)
                {
                case NetProxyType.Socks5:
                    proxyHandler = await(_proxy as SocksProxy).UdpAssociateAsync();
                    break;

                default:
                    throw new NotSupportedException("Proxy type is not supported by Udp tracker.");
                }
            }

            try
            {
                for (int n = 0; n < 2; n++)
                {
                    if ((_connectionId == null) || (_connectionIdExpires <= DateTime.UtcNow))
                    {
                        //GET CONNECTION ID
                        _rnd.GetBytes(_transactionID);
                        _connectionId = await GetConnectionIdAsync(udpSocket, proxyHandler, trackerEP, _transactionID);

                        _connectionIdExpires = DateTime.UtcNow.AddMinutes(1);
                    }

                    try
                    {
                        _rnd.GetBytes(_transactionID);
                        byte[] announceResponse = await GetAnnounceResponseAsync(udpSocket, proxyHandler, trackerEP, _transactionID, _connectionId, @event, clientEP);

                        byte[] buffer = new byte[4];

                        Buffer.BlockCopy(announceResponse, 8, buffer, 0, 4);
                        Array.Reverse(buffer);
                        _interval = BitConverter.ToInt32(buffer, 0);

                        Buffer.BlockCopy(announceResponse, 12, buffer, 0, 4);
                        Array.Reverse(buffer);
                        _leachers = BitConverter.ToInt32(buffer, 0);

                        Buffer.BlockCopy(announceResponse, 16, buffer, 0, 4);
                        Array.Reverse(buffer);
                        _seeders = BitConverter.ToInt32(buffer, 0);

                        _peers.Clear();

                        if (_proxy == null)
                        {
                            if (udpSocket.AddressFamily == AddressFamily.InterNetworkV6)
                            {
                                ParsePeersIPv6(announceResponse, announceResponse.Length, _peers);
                            }
                            else
                            {
                                ParsePeersIPv4(announceResponse, announceResponse.Length, _peers);
                            }
                        }
                        else
                        {
                            int x = (announceResponse.Length - 26) % 6;

                            if (x == 0)
                            {
                                ParsePeersIPv4(announceResponse, announceResponse.Length, _peers);
                            }
                            else
                            {
                                ParsePeersIPv6(announceResponse, announceResponse.Length, _peers);
                            }
                        }

                        return;
                    }
                    catch (SocketException ex)
                    {
                        if (ex.ErrorCode != (int)SocketError.TimedOut)
                        {
                            throw new TrackerClientException(ex.Message, ex);
                        }
                    }
                }

                throw new TrackerClientException("No response from tracker.");
            }
            finally
            {
                if (proxyHandler != null)
                {
                    proxyHandler.Dispose();
                }

                if (udpSocket != null)
                {
                    udpSocket.Close();
                }
            }
        }
Beispiel #25
0
        private void Parse(string address)
        {
            _originalAddress = address;

            //parse
            string domainName = null;
            int    domainPort = 0;
            string host       = null;
            int    port       = 0;
            bool   ipv6Host   = false;

            int posRoundBracketStart = address.IndexOf('(');

            if (posRoundBracketStart > -1)
            {
                int posRoundBracketEnd = address.IndexOf(')', posRoundBracketStart + 1);
                if (posRoundBracketEnd < 0)
                {
                    throw new ArgumentException("Invalid name server address was encountered: " + _originalAddress);
                }

                {
                    string strDomainPart = address.Substring(0, posRoundBracketStart).Trim();

                    if (strDomainPart.StartsWith("https://", StringComparison.OrdinalIgnoreCase) || strDomainPart.StartsWith("http://", StringComparison.OrdinalIgnoreCase))
                    {
                        _dohEndPoint = new Uri(strDomainPart);
                    }
                    else
                    {
                        string[] strParts = strDomainPart.Split(':');

                        domainName = strParts[0];

                        if (strParts.Length > 1)
                        {
                            domainPort = int.Parse(strParts[1]);
                        }
                    }
                }

                address = address.Substring(posRoundBracketStart + 1, posRoundBracketEnd - posRoundBracketStart - 1);
            }

            if (address.StartsWith("https://", StringComparison.OrdinalIgnoreCase) || address.StartsWith("http://", StringComparison.OrdinalIgnoreCase))
            {
                _dohEndPoint = new Uri(address);
            }
            else if (address.StartsWith("["))
            {
                //ipv6
                if (address.EndsWith("]"))
                {
                    host = address.Trim('[', ']');
                }
                else
                {
                    int posBracketEnd = address.LastIndexOf(']');

                    host = address.Substring(1, posBracketEnd - 1);

                    int posCollon = address.IndexOf(':', posBracketEnd + 1);
                    if (posCollon > -1)
                    {
                        port = int.Parse(address.Substring(posCollon + 1));
                    }
                }

                ipv6Host = true;
            }
            else
            {
                string[] strParts = address.Split(':');

                host = strParts[0].Trim();

                if (strParts.Length > 1)
                {
                    port = int.Parse(strParts[1]);
                }
            }

            if (_dohEndPoint == null)
            {
                if ((domainPort == 0) && (port == 0))
                {
                    domainPort = 53;
                    port       = 53;
                }
                else if (domainPort == 0)
                {
                    domainPort = port;
                }
                else if (port == 0)
                {
                    port = domainPort;
                }
                else if (domainPort != port)
                {
                    throw new ArgumentException("Invalid name server address was encountered: " + _originalAddress);
                }

                if (domainName != null)
                {
                    _domainEndPoint = new DomainEndPoint(domainName, domainPort);
                }

                if (IPAddress.TryParse(host, out IPAddress ipAddress))
                {
                    _ipEndPoint = new IPEndPoint(ipAddress, port);
                }
                else if ((_domainEndPoint != null) || ipv6Host)
                {
                    throw new ArgumentException("Invalid name server address was encountered: " + _originalAddress);
                }
                else
                {
                    _domainEndPoint = new DomainEndPoint(host, port);
                }
            }
            else if (host != null)
            {
                if (port == 0)
                {
                    port = _dohEndPoint.Port;
                }
                else if (_dohEndPoint.Port != port)
                {
                    throw new ArgumentException("Invalid name server address was encountered: " + _originalAddress);
                }

                if (IPAddress.TryParse(host, out IPAddress ipAddress))
                {
                    _ipEndPoint = new IPEndPoint(ipAddress, port);
                }
                else
                {
                    throw new ArgumentException("Invalid name server address was encountered: " + _originalAddress);
                }
            }
        }
Beispiel #26
0
        public Task SendToAsync(byte[] buffer, int offset, int count, EndPoint remoteEP)
        {
            //get type, address bytes & port bytes
            SocksAddressType type;

            byte[] address;
            ushort port;

            switch (remoteEP.AddressFamily)
            {
            case AddressFamily.InterNetwork:
            {
                type = SocksAddressType.IPv4Address;

                IPEndPoint ep = remoteEP as IPEndPoint;
                address = ep.Address.GetAddressBytes();
                port    = Convert.ToUInt16(ep.Port);
            }
            break;

            case AddressFamily.InterNetworkV6:
            {
                type = SocksAddressType.IPv6Address;

                IPEndPoint ep = remoteEP as IPEndPoint;
                address = ep.Address.GetAddressBytes();
                port    = Convert.ToUInt16(ep.Port);
            }
            break;

            case AddressFamily.Unspecified:
            {
                type = SocksAddressType.DomainName;

                DomainEndPoint ep = remoteEP as DomainEndPoint;
                address = ep.GetAddressBytes();
                port    = Convert.ToUInt16(ep.Port);
            }
            break;

            default:
                throw new NotSupportedException("AddressFamily not supported.");
            }

            //create datagram
            byte[] datagram = new byte[address.Length + 6 + count];

            datagram[2] = 0x00;
            datagram[3] = (byte)type;

            Buffer.BlockCopy(address, 0, datagram, 4, address.Length);

            byte[] portBytes = BitConverter.GetBytes(port);
            Array.Reverse(portBytes);
            Buffer.BlockCopy(portBytes, 0, datagram, 4 + address.Length, 2);

            Buffer.BlockCopy(buffer, offset, datagram, 4 + address.Length + 2, count);

            //send datagram
            return(_udpSocket.SendToAsync(datagram, 0, datagram.Length, _relayEP));
        }
Beispiel #27
0
        public new void Send(MailMessage message)
        {
            if (DeliveryMethod == SmtpDeliveryMethod.Network)
            {
                if (string.IsNullOrEmpty(this.Host))
                {
                    if (_dnsClient == null)
                    {
                        _dnsClient = new DnsClient();
                    }

                    string[] mxServers = _dnsClient.ResolveMX(message.To[0]);
                    if (mxServers.Length > 0)
                    {
                        this.Host = mxServers[0];
                    }
                    else
                    {
                        this.Host = message.To[0].Host;
                    }

                    this.Port        = 25;
                    this.Credentials = null;
                }

                if (_proxy == null)
                {
                    base.Send(message);
                }
                else
                {
                    EndPoint remoteEP;

                    if (IPAddress.TryParse(_host, out IPAddress address))
                    {
                        remoteEP = new IPEndPoint(address, _port);
                    }
                    else
                    {
                        remoteEP = new DomainEndPoint(_host, _port);
                    }

                    if ((_tunnelProxy != null) && !_tunnelProxy.RemoteEndPoint.Equals(remoteEP))
                    {
                        _tunnelProxy.Dispose();
                    }

                    if ((_tunnelProxy == null) || _tunnelProxy.Disposed)
                    {
                        _tunnelProxy = _proxy.CreateLocalTunnelProxy(remoteEP, base.Timeout);
                    }

                    base.Host = _tunnelProxy.TunnelEndPoint.Address.ToString();
                    base.Port = _tunnelProxy.TunnelEndPoint.Port;

                    base.Send(message);
                }
            }
            else
            {
                base.Send(message);
            }
        }
Beispiel #28
0
        public override async Task <Socket> ConnectAsync(EndPoint remoteEP)
        {
            Network network;

            {
                switch (_networks.Count)
                {
                case 0:
                    network = null;
                    break;

                case 1:
                    network = _networks[0];
                    break;

                default:
                    network = _networks[GetRandomNumber() % _networks.Count];
                    break;
                }
            }

            if (remoteEP.AddressFamily == AddressFamily.Unspecified)
            {
                DomainEndPoint domainEndPoint = remoteEP as DomainEndPoint;
                if (domainEndPoint == null)
                {
                    throw new NotSupportedException();
                }

                bool preferIPv6 = (network != null) && network.HasIPv6Access;

                IReadOnlyList <IPAddress> addresses = await _dnsClient.ResolveIPAsync(domainEndPoint.Address, preferIPv6);

                if (addresses.Count == 0)
                {
                    throw new SocketException((int)SocketError.HostNotFound);
                }

                remoteEP = new IPEndPoint(addresses[0], domainEndPoint.Port);
            }

            Socket socket = new Socket(remoteEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

            if (network != null)
            {
                IPEndPoint bindEP = network.GetBindEndPoint(remoteEP);
                socket.Bind(bindEP);
            }

            try
            {
                await socket.ConnectAsync(remoteEP);
            }
            catch (SocketException ex)
            {
                switch (ex.SocketErrorCode)
                {
                case SocketError.NetworkUnreachable:
                case SocketError.HostUnreachable:
                    if ((network != null) && (_networks.Count > 0))
                    {
                        if (Monitor.TryEnter(_removeNetworkLock))
                        {
                            try
                            {
                                List <Network> networks = new List <Network>();

                                foreach (Network n in _networks)
                                {
                                    if (n.Equals(network))
                                    {
                                        continue;
                                    }

                                    networks.Add(n);
                                }

                                _networks = networks;
                            }
                            finally
                            {
                                Monitor.Exit(_removeNetworkLock);
                            }
                        }
                    }
                    break;
                }

                throw;
            }

            socket.NoDelay = true;

            return(socket);
        }