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); }
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."); }
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); }