Esempio n. 1
0
 protected override void Dispose(bool disposing)
 {
     try
     {
         if (_proxyRequestHandler != null)
         {
             _proxyRequestHandler.Dispose();
             _proxyRequestHandler = null;
         }
     }
     finally
     {
         base.Dispose(disposing);
     }
 }
        protected override WebResponse GetWebResponse(WebRequest request)
        {
            HttpWebResponse response      = null;
            int             redirectCount = -1;

            while (redirectCount < _maximumAutomaticRedirections)
            {
                try
                {
                    response = request.GetResponse() as HttpWebResponse;
                }
                finally
                {
                    if (_proxyRequestHandler != null)
                    {
                        _proxyRequestHandler.Dispose();
                        _proxyRequestHandler = null;
                    }
                }

                switch (response.StatusCode)
                {
                case HttpStatusCode.MovedPermanently:
                case HttpStatusCode.Found:
                case HttpStatusCode.SeeOther:
                    request = GetWebRequest(new Uri(response.Headers["location"]));
                    break;

                case HttpStatusCode.RedirectKeepVerb:
                    string method = request.Method;
                    request        = GetWebRequest(new Uri(response.Headers["location"]));
                    request.Method = method;
                    break;

                default:
                    return(response);
                }

                redirectCount++;
            }

            throw new WebException("Too many automatic redirections were attempted.", null, WebExceptionStatus.ProtocolError, response);
        }
        public Connection MakeConnection(IPEndPoint remotePeerEP)
        {
            if (NetUtilities.IsIPv4MappedIPv6Address(remotePeerEP.Address))
            {
                remotePeerEP = new IPEndPoint(NetUtilities.ConvertFromIPv4MappedIPv6Address(remotePeerEP.Address), remotePeerEP.Port);
            }

            //prevent multiple connection requests to same remote end-point
            lock (_makeConnectionList)
            {
                if (_makeConnectionList.ContainsKey(remotePeerEP))
                {
                    throw new BitChatException("Connection attempt for end-point already in progress.");
                }

                _makeConnectionList.Add(remotePeerEP, null);
            }

            try
            {
                //check if self
                if (remotePeerEP.Equals(this.ExternalEndPoint))
                {
                    throw new IOException("Cannot connect to remote port: self connection.");
                }

                //check existing connection
                Connection existingConnection = GetExistingConnection(remotePeerEP);
                if (existingConnection != null)
                {
                    return(existingConnection);
                }

                try
                {
                    //try new tcp connection

                    Socket client;

                    if (_profile.Proxy != null)
                    {
                        switch (_profile.Proxy.Type)
                        {
                        case NetProxyType.Http:
                            client = _profile.Proxy.HttpProxy.Connect(remotePeerEP);
                            break;

                        case NetProxyType.Socks5:
                            using (SocksConnectRequestHandler requestHandler = _profile.Proxy.SocksProxy.Connect(remotePeerEP))
                            {
                                client = requestHandler.GetSocket();
                            }
                            break;

                        default:
                            throw new NotSupportedException("Proxy type not supported.");
                        }
                    }
                    else
                    {
                        client = new Socket(remotePeerEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
                        client.Connect(remotePeerEP);
                    }

                    client.NoDelay        = true;
                    client.SendTimeout    = SOCKET_SEND_TIMEOUT;
                    client.ReceiveTimeout = SOCKET_RECV_TIMEOUT;

                    return(MakeConnectionInitiateProtocol(new NetworkStream(client, true), remotePeerEP));
                }
                catch (SocketException)
                {
                    //try virtual connection
                    return(MakeVirtualConnection(remotePeerEP));
                }
            }
            finally
            {
                lock (_makeConnectionList)
                {
                    _makeConnectionList.Remove(remotePeerEP);
                }
            }
        }
        protected override WebRequest GetWebRequest(Uri address)
        {
            HttpWebRequest request = null;

            if (_proxy == null)
            {
                switch (_networkType)
                {
                case WebClientExNetworkType.IPv4Only:
                    if (IPAddress.TryParse(address.Host, out IPAddress ipv4))
                    {
                        if (ipv4.AddressFamily != System.Net.Sockets.AddressFamily.InterNetwork)
                        {
                            throw new WebException("WebClientEx current network type does not allow url address family: " + ipv4.AddressFamily.ToString());
                        }

                        request = base.GetWebRequest(address) as HttpWebRequest;
                    }
                    else
                    {
                        try
                        {
                            DnsClient   dns         = new DnsClient();
                            IPAddress[] ipAddresses = dns.ResolveIP(address.Host);

                            if (ipAddresses.Length == 0)
                            {
                                throw new WebException("WebClientEx could not resolve IPv4 address for host: " + address.Host);
                            }

                            foreach (IPAddress ipAddress in ipAddresses)
                            {
                                if (ipAddress.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                                {
                                    Uri newAddress = new Uri(address.Scheme + "://" + ipAddress.ToString() + ":" + address.Port + address.PathAndQuery);
                                    request      = base.GetWebRequest(newAddress) as HttpWebRequest;
                                    request.Host = address.Host;
                                    break;
                                }
                            }
                        }
                        catch (DnsClientException ex)
                        {
                            throw new WebException("WebClientEx could not resolve IPv4 address for host: " + address.Host, ex);
                        }

                        if (request == null)
                        {
                            throw new WebException("WebClientEx could not resolve IPv4 address for host: " + address.Host);
                        }
                    }
                    break;

                case WebClientExNetworkType.IPv6Only:
                    if (IPAddress.TryParse(address.Host, out IPAddress ipv6))
                    {
                        if (ipv6.AddressFamily != System.Net.Sockets.AddressFamily.InterNetworkV6)
                        {
                            throw new WebException("WebClientEx current network type does not allow url address family: " + ipv6.AddressFamily.ToString());
                        }

                        request = base.GetWebRequest(address) as HttpWebRequest;
                    }
                    else
                    {
                        try
                        {
                            DnsClient   dns         = new DnsClient(true);
                            IPAddress[] ipAddresses = dns.ResolveIP(address.Host, true);

                            if (ipAddresses.Length == 0)
                            {
                                throw new WebException("WebClientEx could not resolve IPv6 address for host: " + address.Host);
                            }

                            foreach (IPAddress ipAddress in ipAddresses)
                            {
                                if (ipAddress.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6)
                                {
                                    Uri newAddress = new Uri(address.Scheme + "://[" + ipAddress.ToString() + "]:" + address.Port + address.PathAndQuery);
                                    request      = base.GetWebRequest(newAddress) as HttpWebRequest;
                                    request.Host = address.Host;
                                    break;
                                }
                            }
                        }
                        catch (DnsClientException ex)
                        {
                            throw new WebException("WebClientEx could not resolve IPv6 address for host: " + address.Host, ex);
                        }

                        if (request == null)
                        {
                            throw new WebException("WebClientEx could not resolve IPv6 address for host: " + address.Host);
                        }
                    }
                    break;

                default:
                    request = base.GetWebRequest(address) as HttpWebRequest;
                    break;
                }
            }
            else
            {
                switch (_proxy.Type)
                {
                case NetProxyType.Http:
                    request       = base.GetWebRequest(address) as HttpWebRequest;
                    request.Proxy = _proxy.HttpProxy;
                    break;

                case NetProxyType.Socks5:
                    _proxyRequestHandler = _proxy.SocksProxy.Connect(address.Host, address.Port);

                    if (address.Scheme == "https")
                    {
                        IWebProxy httpProxy = _proxyRequestHandler.CreateLocalHttpProxyConnectTunnel();

                        request       = base.GetWebRequest(address) as HttpWebRequest;
                        request.Proxy = httpProxy;
                    }
                    else
                    {
                        IPEndPoint localTunnelEP = _proxyRequestHandler.CreateLocalTunnel();
                        Uri        proxyUri      = new Uri("http://" + localTunnelEP.Address.ToString() + ":" + localTunnelEP.Port + address.PathAndQuery);

                        request      = base.GetWebRequest(proxyUri) as HttpWebRequest;
                        request.Host = address.Host;
                    }
                    break;

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

            if (_timeout > 0)
            {
                request.Timeout = _timeout;
            }

            request.CookieContainer = _cookie;

            if (_ifModifiedSince > (new DateTime()))
            {
                request.IfModifiedSince = _ifModifiedSince;
            }

            if (_userAgent != null)
            {
                request.UserAgent = _userAgent;
            }

            request.KeepAlive = _keepAlive;

            request.AllowAutoRedirect = false;

            foreach (KeyValuePair <string, string> header in _headers)
            {
                switch (header.Key.ToLower())
                {
                case "accept":
                    request.Accept = header.Value;
                    break;

                case "connection":
                    request.KeepAlive = (header.Value.ToLower() == "keep-alive");
                    break;

                case "content-type":
                    request.ContentType = header.Value;
                    break;

                case "user-agent":
                    request.UserAgent = header.Value;
                    break;

                default:
                    request.Headers.Add(header.Key, header.Value);
                    break;
                }
            }

            return(request);
        }
Esempio n. 5
0
        public DnsDatagram Resolve(DnsDatagram request)
        {
            int bytesRecv;

            byte[] responseBuffer  = null;
            int    nextServerIndex = 0;
            int    retries         = _retries;

            byte[]    requestBuffer;
            IDnsCache dnsCache = null;

            //serialize request
            using (MemoryStream mS = new MemoryStream(32))
            {
                if (_tcp)
                {
                    mS.Position = 2;
                }

                //write dns datagram
                request.WriteTo(mS);

                requestBuffer = mS.ToArray();

                if (_tcp)
                {
                    byte[] length = BitConverter.GetBytes(Convert.ToUInt16(requestBuffer.Length - 2));

                    requestBuffer[0] = length[1];
                    requestBuffer[1] = length[0];
                }
            }

            //init server selection parameters
            if (_servers.Length > 1)
            {
                retries = retries * _servers.Length; //retries on per server basis

                byte[] select = new byte[1];
                _rnd.GetBytes(select);

                nextServerIndex = select[0] % _servers.Length;
            }

            int retry = 0;

            while (retry < retries)
            {
                //select server
                NameServerAddress server;

                if (_servers.Length > 1)
                {
                    server          = _servers[nextServerIndex];
                    nextServerIndex = (nextServerIndex + 1) % _servers.Length;
                }
                else
                {
                    server = _servers[0];
                }

                if (server.EndPoint == null)
                {
                    if (dnsCache == null)
                    {
                        dnsCache = new SimpleDnsCache();
                    }

                    server.ResolveAddress(dnsCache, _proxy, _preferIPv6, _tcp, _retries);

                    if (server.EndPoint == null)
                    {
                        retry++;
                        continue;
                    }
                }

                //query server
                Socket _socket = null;
                SocksUdpAssociateRequestHandler proxyRequestHandler = null;

                try
                {
                    retry++;

                    DateTime sentAt = DateTime.UtcNow;
                    bool     dnsTcp;

                    if (_proxy == null)
                    {
                        if (_tcp)
                        {
                            _socket = new Socket(server.EndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

                            _socket.NoDelay        = true;
                            _socket.SendTimeout    = _sendTimeout;
                            _socket.ReceiveTimeout = _recvTimeout;

                            IAsyncResult result = _socket.BeginConnect(server.EndPoint, null, null);
                            if (!result.AsyncWaitHandle.WaitOne(_connectionTimeout))
                            {
                                throw new SocketException((int)SocketError.TimedOut);
                            }

                            if (!_socket.Connected)
                            {
                                throw new SocketException((int)SocketError.ConnectionRefused);
                            }
                        }
                        else
                        {
                            _socket = new Socket(server.EndPoint.AddressFamily, SocketType.Dgram, ProtocolType.Udp);

                            _socket.SendTimeout    = _sendTimeout;
                            _socket.ReceiveTimeout = _recvTimeout;
                        }

                        dnsTcp = _tcp;
                    }
                    else
                    {
                        switch (_proxy.Type)
                        {
                        case NetProxyType.Http:
                            _socket = _proxy.HttpProxy.Connect(server.EndPoint, _connectionTimeout);

                            _socket.NoDelay        = true;
                            _socket.SendTimeout    = _sendTimeout;
                            _socket.ReceiveTimeout = _recvTimeout;

                            dnsTcp = true;
                            break;

                        case NetProxyType.Socks5:
                            if (!_tcp)
                            {
                                try
                                {
                                    proxyRequestHandler = _proxy.SocksProxy.UdpAssociate(_connectionTimeout);
                                    proxyRequestHandler.ReceiveTimeout = _recvTimeout;

                                    dnsTcp = false;
                                    break;
                                }
                                catch (SocksClientException)
                                { }
                            }

                            using (SocksConnectRequestHandler requestHandler = _proxy.SocksProxy.Connect(server.EndPoint, _connectionTimeout))
                            {
                                _socket = requestHandler.GetSocket();

                                _socket.NoDelay        = true;
                                _socket.SendTimeout    = _sendTimeout;
                                _socket.ReceiveTimeout = _recvTimeout;

                                dnsTcp = true;
                            }

                            break;

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

                    if (dnsTcp)
                    {
                        _socket.Send(requestBuffer);

                        if ((responseBuffer == null) || (responseBuffer.Length == 512))
                        {
                            responseBuffer = new byte[64 * 1024];
                        }

                        bytesRecv = _socket.Receive(responseBuffer, 0, 2, SocketFlags.None);
                        if (bytesRecv < 1)
                        {
                            throw new SocketException((int)SocketError.ConnectionReset);
                        }

                        Array.Reverse(responseBuffer, 0, 2);
                        ushort length = BitConverter.ToUInt16(responseBuffer, 0);

                        int offset = 0;
                        while (offset < length)
                        {
                            bytesRecv = _socket.Receive(responseBuffer, offset, length, SocketFlags.None);
                            if (bytesRecv < 1)
                            {
                                throw new SocketException((int)SocketError.ConnectionReset);
                            }

                            offset += bytesRecv;
                        }

                        bytesRecv = length;
                    }
                    else
                    {
                        if (responseBuffer == null)
                        {
                            responseBuffer = new byte[512];
                        }

                        if (proxyRequestHandler == null)
                        {
                            _socket.SendTo(requestBuffer, server.EndPoint);

                            EndPoint remoteEP;

                            if (server.EndPoint.AddressFamily == AddressFamily.InterNetworkV6)
                            {
                                remoteEP = new IPEndPoint(IPAddress.IPv6Any, 0);
                            }
                            else
                            {
                                remoteEP = new IPEndPoint(IPAddress.Any, 0);
                            }

                            bytesRecv = _socket.ReceiveFrom(responseBuffer, ref remoteEP);
                        }
                        else
                        {
                            proxyRequestHandler.SendTo(requestBuffer, 0, requestBuffer.Length, new SocksEndPoint(server.EndPoint));

                            bytesRecv = proxyRequestHandler.ReceiveFrom(responseBuffer, 0, responseBuffer.Length, out SocksEndPoint socksRemoteEP);
                        }
                    }

                    //parse response
                    using (MemoryStream mS = new MemoryStream(responseBuffer, 0, bytesRecv, false))
                    {
                        double      rtt      = (DateTime.UtcNow - sentAt).TotalMilliseconds;
                        DnsDatagram response = new DnsDatagram(mS, server, (_tcp ? ProtocolType.Tcp : ProtocolType.Udp), rtt);

                        if (response.Header.Identifier == request.Header.Identifier)
                        {
                            return(response);
                        }
                    }
                }
                catch (SocketException)
                { }
                finally
                {
                    if (_socket != null)
                    {
                        _socket.Dispose();
                    }

                    if (proxyRequestHandler != null)
                    {
                        proxyRequestHandler.Dispose();
                    }
                }
            }

            throw new DnsClientException("DnsClient failed to resolve the request: no response from name servers.");
        }
Esempio n. 6
0
        protected override WebRequest GetWebRequest(Uri address)
        {
            HttpWebRequest request;

            if (_proxy == null)
            {
                request = base.GetWebRequest(address) as HttpWebRequest;
            }
            else
            {
                switch (_proxy.Type)
                {
                case NetProxyType.Http:
                    request       = base.GetWebRequest(address) as HttpWebRequest;
                    request.Proxy = _proxy.HttpProxy;
                    break;

                case NetProxyType.Socks5:
                    _proxyRequestHandler = _proxy.SocksProxy.Connect(address.Host, address.Port);

                    if (address.Scheme == "https")
                    {
                        IWebProxy httpProxy = _proxyRequestHandler.CreateLocalHttpProxyConnectTunnel();

                        request       = base.GetWebRequest(address) as HttpWebRequest;
                        request.Proxy = httpProxy;
                    }
                    else
                    {
                        IPEndPoint localTunnelEP = _proxyRequestHandler.CreateLocalTunnel();
                        Uri        proxyUri      = new Uri("http://" + localTunnelEP.Address.ToString() + ":" + localTunnelEP.Port + address.PathAndQuery);

                        request      = base.GetWebRequest(proxyUri) as HttpWebRequest;
                        request.Host = address.Host;
                    }
                    break;

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

            if (_timeout > 0)
            {
                request.Timeout = _timeout;
            }

            request.CookieContainer = _cookie;

            if (_ifModifiedSince > (new DateTime()))
            {
                request.IfModifiedSince = _ifModifiedSince;
            }

            if (_userAgent != null)
            {
                request.UserAgent = _userAgent;
            }

            request.KeepAlive = _keepAlive;

            request.AllowAutoRedirect = false;

            foreach (KeyValuePair <string, string> header in _headers)
            {
                switch (header.Key.ToLower())
                {
                case "accept":
                    request.Accept = header.Value;
                    break;

                case "connection":
                    request.KeepAlive = (header.Value.ToLower() == "keep-alive");
                    break;

                case "content-type":
                    request.ContentType = header.Value;
                    break;

                case "user-agent":
                    request.UserAgent = header.Value;
                    break;

                default:
                    request.Headers.Add(header.Key, header.Value);
                    break;
                }
            }

            return(request);
        }