Improve: simple dns prefetch

This commit is contained in:
Dreamacro 2018-06-11 18:36:39 +08:00
parent 4f192ef575
commit 4f769debe7
8 changed files with 30 additions and 21 deletions

View file

@ -31,7 +31,7 @@ type Direct struct {
} }
func (d *Direct) Generator(addr *C.Addr) (adapter C.ProxyAdapter, err error) { func (d *Direct) Generator(addr *C.Addr) (adapter C.ProxyAdapter, err error) {
c, err := net.Dial("tcp", net.JoinHostPort(addr.Host, addr.Port)) c, err := net.Dial("tcp", net.JoinHostPort(addr.String(), addr.Port))
if err != nil { if err != nil {
return return
} }

View file

@ -87,10 +87,10 @@ func serializesSocksAddr(addr *C.Addr) []byte {
host := []byte(addr.Host) host := []byte(addr.Host)
buf = [][]byte{[]byte{aType, len}, host, port} buf = [][]byte{[]byte{aType, len}, host, port}
case socks.AtypIPv4: case socks.AtypIPv4:
host := net.ParseIP(addr.Host).To4() host := addr.IP.To4()
buf = [][]byte{[]byte{aType}, host, port} buf = [][]byte{[]byte{aType}, host, port}
case socks.AtypIPv6: case socks.AtypIPv6:
host := net.ParseIP(addr.Host).To16() host := addr.IP.To16()
buf = [][]byte{[]byte{aType}, host, port} buf = [][]byte{[]byte{aType}, host, port}
} }
return bytes.Join(buf, []byte("")) return bytes.Join(buf, []byte(""))

View file

@ -1,5 +1,9 @@
package constant package constant
import (
"net"
)
// Socks addr type // Socks addr type
const ( const (
AtypIPv4 = 1 AtypIPv4 = 1
@ -11,5 +15,13 @@ const (
type Addr struct { type Addr struct {
AddrType int AddrType int
Host string Host string
IP *net.IP
Port string Port string
} }
func (addr *Addr) String() string {
if addr.Host == "" {
return addr.IP.String()
}
return addr.Host
}

View file

@ -90,7 +90,7 @@ func (h *HttpAdapter) Addr() *constant.Addr {
func parseHttpAddr(target string) *constant.Addr { func parseHttpAddr(target string) *constant.Addr {
host, port, _ := net.SplitHostPort(target) host, port, _ := net.SplitHostPort(target)
ipAddr, _ := net.ResolveIPAddr("ip", host)
var addType int var addType int
ip := net.ParseIP(host) ip := net.ParseIP(host)
switch { switch {
@ -105,6 +105,7 @@ func parseHttpAddr(target string) *constant.Addr {
return &constant.Addr{ return &constant.Addr{
AddrType: addType, AddrType: addType,
Host: host, Host: host,
IP: &ipAddr.IP,
Port: port, Port: port,
} }
} }

View file

@ -65,22 +65,28 @@ func (s *SocksAdapter) Addr() *constant.Addr {
func parseSocksAddr(target socks.Addr) *constant.Addr { func parseSocksAddr(target socks.Addr) *constant.Addr {
var host, port string var host, port string
var ip net.IP
switch target[0] { switch target[0] {
case socks.AtypDomainName: case socks.AtypDomainName:
host = string(target[2 : 2+target[1]]) host = string(target[2 : 2+target[1]])
port = strconv.Itoa((int(target[2+target[1]]) << 8) | int(target[2+target[1]+1])) port = strconv.Itoa((int(target[2+target[1]]) << 8) | int(target[2+target[1]+1]))
ipAddr, err := net.ResolveIPAddr("ip", host)
if err == nil {
ip = ipAddr.IP
}
case socks.AtypIPv4: case socks.AtypIPv4:
host = net.IP(target[1 : 1+net.IPv4len]).String() ip = net.IP(target[1 : 1+net.IPv4len])
port = strconv.Itoa((int(target[1+net.IPv4len]) << 8) | int(target[1+net.IPv4len+1])) port = strconv.Itoa((int(target[1+net.IPv4len]) << 8) | int(target[1+net.IPv4len+1]))
case socks.AtypIPv6: case socks.AtypIPv6:
host = net.IP(target[1 : 1+net.IPv6len]).String() ip = net.IP(target[1 : 1+net.IPv6len])
port = strconv.Itoa((int(target[1+net.IPv6len]) << 8) | int(target[1+net.IPv6len+1])) port = strconv.Itoa((int(target[1+net.IPv6len]) << 8) | int(target[1+net.IPv6len+1]))
} }
return &constant.Addr{ return &constant.Addr{
AddrType: int(target[0]), AddrType: int(target[0]),
Host: host, Host: host,
IP: &ip,
Port: port, Port: port,
} }
} }

View file

@ -1,8 +1,6 @@
package rules package rules
import ( import (
"net"
C "github.com/Dreamacro/clash/constant" C "github.com/Dreamacro/clash/constant"
"github.com/oschwald/geoip2-golang" "github.com/oschwald/geoip2-golang"
@ -29,14 +27,10 @@ func (g *GEOIP) RuleType() C.RuleType {
} }
func (g *GEOIP) IsMatch(addr *C.Addr) bool { func (g *GEOIP) IsMatch(addr *C.Addr) bool {
if addr.AddrType == C.AtypDomainName { if addr.IP == nil {
return false return false
} }
dstIP := net.ParseIP(addr.Host) record, _ := mmdb.Country(*addr.IP)
if dstIP == nil {
return false
}
record, _ := mmdb.Country(dstIP)
return record.Country.IsoCode == g.country return record.Country.IsoCode == g.country
} }

View file

@ -16,15 +16,11 @@ func (i *IPCIDR) RuleType() C.RuleType {
} }
func (i *IPCIDR) IsMatch(addr *C.Addr) bool { func (i *IPCIDR) IsMatch(addr *C.Addr) bool {
if addr.AddrType == C.AtypDomainName { if addr.IP == nil {
return false
}
ip := net.ParseIP(addr.Host)
if ip == nil {
return false return false
} }
return i.ipnet.Contains(ip) return i.ipnet.Contains(*addr.IP)
} }
func (g *IPCIDR) Adapter() string { func (g *IPCIDR) Adapter() string {

View file

@ -117,7 +117,7 @@ func (t *Tunnel) match(addr *C.Addr) C.Proxy {
if !ok { if !ok {
continue continue
} }
t.logCh <- newLog(INFO, "%v match %d using %s", addr.Host, rule.RuleType(), rule.Adapter()) t.logCh <- newLog(INFO, "%v match %d using %s", addr.String(), rule.RuleType(), rule.Adapter())
return a return a
} }
} }