Feature: support fakeip

This commit is contained in:
Dreamacro
2019-05-03 00:05:14 +08:00
parent 762f227512
commit f352f4479e
9 changed files with 180 additions and 4 deletions

View File

@ -11,6 +11,7 @@ import (
"github.com/Dreamacro/clash/common/cache"
"github.com/Dreamacro/clash/common/picker"
"github.com/Dreamacro/clash/component/fakeip"
C "github.com/Dreamacro/clash/constant"
D "github.com/miekg/dns"
@ -28,6 +29,8 @@ var (
type Resolver struct {
ipv6 bool
mapping bool
fakeip bool
pool *fakeip.Pool
fallback []*nameserver
main []*nameserver
cache *cache.Cache
@ -209,6 +212,10 @@ func (r *Resolver) IsMapping() bool {
return r.mapping
}
func (r *Resolver) IsFakeIP() bool {
return r.fakeip
}
type NameServer struct {
Net string
Addr string
@ -223,6 +230,7 @@ type Config struct {
Main, Fallback []NameServer
IPv6 bool
EnhancedMode EnhancedMode
Pool *fakeip.Pool
}
func transform(servers []NameServer) []*nameserver {
@ -252,6 +260,8 @@ func New(config Config) *Resolver {
ipv6: config.IPv6,
cache: cache.New(time.Second * 60),
mapping: config.EnhancedMode == MAPPING,
fakeip: config.EnhancedMode == FAKEIP,
pool: config.Pool,
}
if config.Fallback != nil {
r.fallback = transform(config.Fallback)

View File

@ -1,16 +1,21 @@
package dns
import (
"errors"
"fmt"
"net"
"time"
"github.com/Dreamacro/clash/log"
"github.com/miekg/dns"
D "github.com/miekg/dns"
)
var (
address string
server = &Server{}
dnsDefaultTTL uint32 = 600
)
type Server struct {
@ -19,6 +24,17 @@ type Server struct {
}
func (s *Server) ServeDNS(w D.ResponseWriter, r *D.Msg) {
if s.r.IsFakeIP() {
msg, err := s.handleFakeIP(r)
if err != nil {
D.HandleFailed(w, r)
return
}
msg.SetReply(r)
w.WriteMsg(msg)
return
}
msg, err := s.r.Exchange(r)
if err != nil {
@ -34,6 +50,40 @@ func (s *Server) ServeDNS(w D.ResponseWriter, r *D.Msg) {
w.WriteMsg(msg)
}
func (s *Server) handleFakeIP(r *D.Msg) (msg *D.Msg, err error) {
if len(r.Question) == 0 {
err = errors.New("should have one question at least")
return
}
q := r.Question[0]
cache, expireTime := s.r.cache.GetWithExpire("fakeip:" + q.String())
if cache != nil {
msg = cache.(*D.Msg).Copy()
setMsgTTL(msg, uint32(expireTime.Sub(time.Now()).Seconds()))
return
}
var ip net.IP
defer func() {
if msg == nil {
return
}
putMsgToCache(s.r.cache, "fakeip:"+q.String(), msg)
putMsgToCache(s.r.cache, ip.String(), msg)
}()
rr := &D.A{}
rr.Hdr = dns.RR_Header{Name: r.Question[0].Name, Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: dnsDefaultTTL}
ip = s.r.pool.Get()
rr.A = ip
msg = r.Copy()
msg.Answer = []D.RR{rr}
return
}
func (s *Server) setReslover(r *Resolver) {
s.r = r
}

View File

@ -70,7 +70,7 @@ func (e EnhancedMode) String() string {
case NORMAL:
return "normal"
case FAKEIP:
return "fakeip"
return "fake-ip"
case MAPPING:
return "redir-host"
default: