Skip to content
This repository has been archived by the owner on Apr 3, 2021. It is now read-only.

Commit

Permalink
refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
eycorsican committed Mar 17, 2019
1 parent 61ca15b commit ed8a680
Show file tree
Hide file tree
Showing 8 changed files with 76 additions and 72 deletions.
20 changes: 4 additions & 16 deletions common/dns/dns.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package dns

import (
"encoding/binary"
"net"
)

Expand All @@ -17,23 +16,12 @@ type DnsCache interface {
}

type FakeDns interface {
// GenerateFakeResponse generates a response for the specify request with a fake IP address.
// GenerateFakeResponse generates a fake dns response for the specify request.
GenerateFakeResponse(request []byte) ([]byte, error)

// QueryDomain returns the corresponding domain for IP.
// QueryDomain returns the corresponding domain for the given IP.
QueryDomain(ip net.IP) string
}

const (
// We set fake dns response ttl to 1, 256 fake ips should be suffice.
MinFakeIPCursor = 4043309056 // 241.0.0.0
MaxFakeIPCursor = 4043309311 // 241.0.0.255
)

func IsFakeIP(ip net.IP) bool {
n := binary.BigEndian.Uint32([]byte(ip)[net.IPv6len-net.IPv4len:])
if n >= MinFakeIPCursor && n <= MaxFakeIPCursor {
return true
}
return false
// IsFakeIP checks if the given ip is a fake IP.
IsFakeIP(ip net.IP) bool
}
118 changes: 67 additions & 51 deletions common/dns/fakedns/fakedns.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,25 @@ import (
"github.com/eycorsican/go-tun2socks/core"
)

const (
// If fake dns response ttl is set to 1, 256 fake ips should be suffice.
MinFakeIPCursor uint32 = 0xf1000000 // 241.0.0.0
MaxFakeIPCursor uint32 = 0xf10000ff // 241.0.0.255
FakeResponseTtl uint32 = 1 // in sec
)

type simpleFakeDns struct {
sync.Mutex

// TODO cleanup map
ip2domain map[uint32]string

// Cursor is an IPv4 address represent in uint32 type.
cursor uint32
minCursor uint32
maxCursor uint32

fakeTtl uint32
}

func canHandleDnsQuery(data []byte) bool {
Expand Down Expand Up @@ -53,11 +66,7 @@ func canHandleDnsQuery(data []byte) bool {
}

func uint322ip(n uint32) net.IP {
b1 := (n & 0xff000000) >> 24
b2 := (n & 0x00ff0000) >> 16
b3 := (n & 0x0000ff00) >> 8
b4 := (n & 0x000000ff)
return net.IPv4(byte(b1), byte(b2), byte(b3), byte(b4))
return net.IPv4(byte(n>>24), byte(n>>16), byte(n>>8), byte(n))
}

func ip2uint32(ip net.IP) uint32 {
Expand All @@ -67,7 +76,7 @@ func ip2uint32(ip net.IP) uint32 {
func NewSimpleFakeDns() cdns.FakeDns {
return &simpleFakeDns{
ip2domain: make(map[uint32]string, 64),
cursor: cdns.MinFakeIPCursor,
cursor: MinFakeIPCursor,
}
}

Expand All @@ -77,8 +86,8 @@ func (f *simpleFakeDns) allocateIP(domain string) net.IP {
f.ip2domain[f.cursor] = domain
ip := uint322ip(f.cursor)
f.cursor += 1
if f.cursor > cdns.MaxFakeIPCursor {
f.cursor = cdns.MinFakeIPCursor
if f.cursor > MaxFakeIPCursor {
f.cursor = MinFakeIPCursor
}
return ip
}
Expand All @@ -94,49 +103,56 @@ func (f *simpleFakeDns) QueryDomain(ip net.IP) string {
}

func (f *simpleFakeDns) GenerateFakeResponse(request []byte) ([]byte, error) {
if canHandleDnsQuery(request) {
req := new(dns.Msg)
req.Unpack(request)
qtype := req.Question[0].Qtype
fqdn := req.Question[0].Name
domain := fqdn[:len(fqdn)-1]
ip := f.allocateIP(domain)
log.Debugf("fake dns allocated ip %v for domain %v", ip, domain)
resp := new(dns.Msg)
resp = resp.SetReply(req)
if qtype == dns.TypeA {
resp.Answer = append(resp.Answer, &dns.A{
Hdr: dns.RR_Header{
Name: fqdn,
Rrtype: dns.TypeA,
Class: dns.ClassINET,
Ttl: 1,
Rdlength: net.IPv4len,
},
A: ip,
})
} else if qtype == dns.TypeAAAA {
resp.Answer = append(resp.Answer, &dns.AAAA{
Hdr: dns.RR_Header{
Name: fqdn,
Rrtype: dns.TypeAAAA,
Class: dns.ClassINET,
Ttl: 1,
Rdlength: net.IPv6len,
},
AAAA: ip,
})
} else {
return nil, fmt.Errorf("unexcepted dns qtype %v", qtype)
}
buf := core.NewBytes(core.BufSize)
defer core.FreeBytes(buf)
dnsAnswer, err := resp.PackBuffer(buf)
if err != nil {
return nil, fmt.Errorf("failed to pack dns answer: %v", err)
}
return append([]byte(nil), dnsAnswer...), nil
} else {
if !canHandleDnsQuery(request) {
return nil, errors.New("cannot handle DNS request")
}
req := new(dns.Msg)
req.Unpack(request)
qtype := req.Question[0].Qtype
fqdn := req.Question[0].Name
domain := fqdn[:len(fqdn)-1]
ip := f.allocateIP(domain)
log.Debugf("fake dns allocated ip %v for domain %v", ip, domain)
resp := new(dns.Msg)
resp = resp.SetReply(req)
if qtype == dns.TypeA {
resp.Answer = append(resp.Answer, &dns.A{
Hdr: dns.RR_Header{
Name: fqdn,
Rrtype: dns.TypeA,
Class: dns.ClassINET,
Ttl: FakeResponseTtl,
Rdlength: net.IPv4len,
},
A: ip,
})
} else if qtype == dns.TypeAAAA {
resp.Answer = append(resp.Answer, &dns.AAAA{
Hdr: dns.RR_Header{
Name: fqdn,
Rrtype: dns.TypeAAAA,
Class: dns.ClassINET,
Ttl: FakeResponseTtl,
Rdlength: net.IPv6len,
},
AAAA: ip,
})
} else {
return nil, fmt.Errorf("unexcepted dns qtype %v", qtype)
}
buf := core.NewBytes(core.BufSize)
defer core.FreeBytes(buf)
dnsAnswer, err := resp.PackBuffer(buf)
if err != nil {
return nil, fmt.Errorf("failed to pack dns answer: %v", err)
}
return append([]byte(nil), dnsAnswer...), nil
}

func (f *simpleFakeDns) IsFakeIP(ip net.IP) bool {
c := ip2uint32(ip)
if c >= MinFakeIPCursor && c <= MaxFakeIPCursor {
return true
}
return false
}
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion proxy/shadowsocks/tcp.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ func (h *tcpHandler) Connect(conn core.TCPConn, target net.Addr) error {
var targetHost string = host
if h.fakeDns != nil {
if ip := net.ParseIP(host); ip != nil {
if dns.IsFakeIP(ip) {
if h.fakeDns.IsFakeIP(ip) {
targetHost = h.fakeDns.QueryDomain(ip)
}
}
Expand Down
2 changes: 1 addition & 1 deletion proxy/shadowsocks/udp.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ func (h *udpHandler) DidReceiveTo(conn core.UDPConn, data []byte, addr net.Addr)
var targetHost string = host
if h.fakeDns != nil {
if ip := net.ParseIP(host); ip != nil {
if dns.IsFakeIP(ip) {
if h.fakeDns.IsFakeIP(ip) {
targetHost = h.fakeDns.QueryDomain(ip)
}
}
Expand Down
2 changes: 1 addition & 1 deletion proxy/socks/tcp.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ func (h *tcpHandler) Connect(conn core.TCPConn, target net.Addr) error {
var targetHost string = host
if h.fakeDns != nil {
if ip := net.ParseIP(host); ip != nil {
if dns.IsFakeIP(ip) {
if h.fakeDns.IsFakeIP(ip) {
targetHost = h.fakeDns.QueryDomain(ip)
}
}
Expand Down
4 changes: 2 additions & 2 deletions proxy/socks/udp.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ func (h *udpHandler) Connect(conn core.UDPConn, target net.Addr) error {
return nil // skip dns
}
if ip := net.ParseIP(host); ip != nil {
if dns.IsFakeIP(ip) {
if h.fakeDns.IsFakeIP(ip) {
targetHost = h.fakeDns.QueryDomain(ip)
}
}
Expand Down Expand Up @@ -249,7 +249,7 @@ func (h *udpHandler) DidReceiveTo(conn core.UDPConn, data []byte, addr net.Addr)
var targetHost string = host
if h.fakeDns != nil {
if ip := net.ParseIP(host); ip != nil {
if dns.IsFakeIP(ip) {
if h.fakeDns.IsFakeIP(ip) {
targetHost = h.fakeDns.QueryDomain(ip)
}
}
Expand Down

0 comments on commit ed8a680

Please sign in to comment.