public int IsHandle(byte[] firstPacket, int length, Socket socket) { if (length >= 7 && _config.proxyRuleMode != (int)ProxyRuleMode.Disable) { IPAddress ipAddress = null; if (firstPacket[0] == 1) { byte[] addr = new byte[4]; Array.Copy(firstPacket, 1, addr, 0, addr.Length); ipAddress = new IPAddress(addr); } else if (firstPacket[0] == 3) { int len = firstPacket[1]; byte[] addr = new byte[len]; if (length >= len + 2) { Array.Copy(firstPacket, 2, addr, 0, addr.Length); string host = Encoding.UTF8.GetString(firstPacket, 2, len); if (IPAddress.TryParse(host, out ipAddress)) { //pass } else { if ((_config.proxyRuleMode == (int)ProxyRuleMode.BypassLanAndChina || _config.proxyRuleMode == (int)ProxyRuleMode.BypassLanAndNotChina) && _IPRange != null || _config.proxyRuleMode == (int)ProxyRuleMode.UserCustom) { if (!IPAddress.TryParse(host, out ipAddress)) { if (_config.proxyRuleMode == (int)ProxyRuleMode.UserCustom) { HostMap hostMap = HostMap.Instance(); string host_addr; if (hostMap.GetHost(host, out host_addr)) { if (!String.IsNullOrEmpty(host_addr)) { string lower_host_addr = host_addr.ToLower(); if (lower_host_addr.StartsWith("reject") || lower_host_addr.StartsWith("direct") ) { return(CONNECT_DIRECT); } else if (lower_host_addr.StartsWith("localproxy")) { return(CONNECT_LOCALPROXY); } else if (lower_host_addr.StartsWith("remoteproxy")) { return(CONNECT_REMOTEPROXY); } else if (lower_host_addr.IndexOf('.') >= 0 || lower_host_addr.IndexOf(':') >= 0) { if (!IPAddress.TryParse(lower_host_addr, out ipAddress)) { // } } } } } if (ipAddress == null) { ipAddress = Utils.DnsBuffer.Get(host); } } if (ipAddress == null) { if (host.IndexOf('.') >= 0) { ipAddress = Util.Utils.QueryDns(host, _config.dnsServer); } else { ipAddress = Utils.QueryDns(host, null); } if (ipAddress != null) { Utils.DnsBuffer.Set(host, new IPAddress(ipAddress.GetAddressBytes())); if (host.IndexOf('.') >= 0) { if (Util.Utils.isLAN(ipAddress)) // assume that it is polution if return LAN address { return(CONNECT_REMOTEPROXY); } } } else { Logging.Log(LogLevel.Debug, "DNS query fail: " + host); } } } } } } else if (firstPacket[0] == 4) { byte[] addr = new byte[16]; Array.Copy(firstPacket, 1, addr, 0, addr.Length); ipAddress = new IPAddress(addr); } if (ipAddress != null) { if (_config.proxyRuleMode == (int)ProxyRuleMode.UserCustom) { Shadowsocks.Model.HostMap hostMap = HostMap.Instance(); string host_addr; if (hostMap.GetIP(ipAddress, out host_addr)) { string lower_host_addr = host_addr.ToLower(); if (lower_host_addr.StartsWith("reject") || lower_host_addr.StartsWith("direct") ) { return(CONNECT_DIRECT); } else if (lower_host_addr.StartsWith("localproxy")) { return(CONNECT_LOCALPROXY); } else if (lower_host_addr.StartsWith("remoteproxy")) { return(CONNECT_REMOTEPROXY); } } } else { if (Utils.isLAN(ipAddress)) { return(CONNECT_DIRECT); } if ((_config.proxyRuleMode == (int)ProxyRuleMode.BypassLanAndChina || _config.proxyRuleMode == (int)ProxyRuleMode.BypassLanAndNotChina) && _IPRange != null && ipAddress.AddressFamily == AddressFamily.InterNetwork ) { if (_IPRange.IsInIPRange(ipAddress)) { return(CONNECT_LOCALPROXY); } Utils.DnsBuffer.Sweep(); } } } } return(CONNECT_REMOTEPROXY); }
private void Connect() { try { IPAddress ipAddress = null; int _targetPort = 0; { if (_firstPacket[0] == 1) { byte[] addr = new byte[4]; Array.Copy(_firstPacket, 1, addr, 0, addr.Length); ipAddress = new IPAddress(addr); _targetPort = (_firstPacket[5] << 8) | _firstPacket[6]; _remote_host = ipAddress.ToString(); Logging.Info((_local_proxy ? "Local proxy" : "Direct") + " connect " + _remote_host + ":" + _targetPort.ToString()); } else if (_firstPacket[0] == 4) { byte[] addr = new byte[16]; Array.Copy(_firstPacket, 1, addr, 0, addr.Length); ipAddress = new IPAddress(addr); _targetPort = (_firstPacket[17] << 8) | _firstPacket[18]; _remote_host = ipAddress.ToString(); Logging.Info((_local_proxy ? "Local proxy" : "Direct") + " connect " + _remote_host + ":" + _targetPort.ToString()); } else if (_firstPacket[0] == 3) { int len = _firstPacket[1]; byte[] addr = new byte[len]; Array.Copy(_firstPacket, 2, addr, 0, addr.Length); _remote_host = Encoding.UTF8.GetString(_firstPacket, 2, len); _targetPort = (_firstPacket[len + 2] << 8) | _firstPacket[len + 3]; Logging.Info((_local_proxy ? "Local proxy" : "Direct") + " connect " + _remote_host + ":" + _targetPort.ToString()); //if (!_local_proxy) { if (!IPAddress.TryParse(_remote_host, out ipAddress)) { if (_config.proxyRuleMode == (int)ProxyRuleMode.UserCustom) { Shadowsocks.Model.HostMap hostMap = HostMap.Instance(); if (hostMap.GetHost(_remote_host, out var host_addr)) { if (!string.IsNullOrEmpty(host_addr)) { string lower_host_addr = host_addr.ToLower(); if (lower_host_addr.StartsWith("reject")) { Close(); return; } else if (lower_host_addr.IndexOf('.') >= 0 || lower_host_addr.IndexOf(':') >= 0) { if (!IPAddress.TryParse(lower_host_addr, out ipAddress)) { // } } } } } if (ipAddress == null) { ipAddress = Utils.LocalDnsBuffer.Get(_remote_host); } } if (ipAddress == null) { ipAddress = Utils.QueryDns(_remote_host, _remote_host.IndexOf('.') >= 0 ? _config.localDnsServer : null); } if (ipAddress != null) { Utils.LocalDnsBuffer.Set(_remote_host, new IPAddress(ipAddress.GetAddressBytes())); Utils.LocalDnsBuffer.Sweep(); } else { if (!_local_proxy) { throw new SocketException((int)SocketError.HostNotFound); } } } } _remote_port = _targetPort; } if (ipAddress != null && _config.proxyRuleMode == (int)ProxyRuleMode.UserCustom) { Shadowsocks.Model.HostMap hostMap = HostMap.Instance(); string host_addr; if (hostMap.GetIP(ipAddress, out host_addr)) { string lower_host_addr = host_addr.ToLower(); if (lower_host_addr.StartsWith("reject") ) { Close(); return; } } } if (_local_proxy) { IPAddress.TryParse(_config.proxyHost, out ipAddress); _targetPort = _config.proxyPort; } // ProxyAuth recv only socks5 head, so don't need to save anything else IPEndPoint remoteEP = new IPEndPoint(ipAddress, _targetPort); _remote = new ProxySocketTun(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp); _remote.GetSocket().NoDelay = true; // Connect to the remote endpoint. _remote.BeginConnect(remoteEP, ConnectCallback, null); } catch (Exception e) { Logging.LogUsefulException(e); Close(); } }