1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2025-01-02 07:26:24 -05:00

overrideable dns

This commit is contained in:
Darien Raymond 2017-12-19 23:55:09 +01:00
parent 7d11286d80
commit ab4f245313
No known key found for this signature in database
GPG Key ID: 7251FFA14BB18169
11 changed files with 74 additions and 85 deletions

View File

@ -1,23 +1,3 @@
package dns
//go:generate go run $GOPATH/src/v2ray.com/core/common/errors/errorgen/main.go -pkg dns -path App,DNS
import (
"net"
"v2ray.com/core/app"
)
// A Server is a DNS server for responding DNS queries.
type Server interface {
Get(domain string) []net.IP
}
// FromSpace fetches a DNS server from context.
func FromSpace(space app.Space) Server {
app := space.GetApplication((*Server)(nil))
if app == nil {
return nil
}
return app.(Server)
}

View File

@ -1,4 +1,4 @@
package server
package dns
import (
"context"
@ -203,7 +203,8 @@ func (*LocalNameServer) QueryA(domain string) <-chan *ARecord {
go func() {
defer close(response)
ips, err := net.LookupIP(domain)
resolver := net.SystemIPResolver()
ips, err := resolver.LookupIP(domain)
if err != nil {
newError("failed to lookup IPs for domain ", domain).Base(err).WriteToLog()
return

View File

@ -1,4 +1,4 @@
package server
package dns
//go:generate go run $GOPATH/src/v2ray.com/core/common/errors/errorgen/main.go -pkg server -path App,DNS,Server
@ -10,7 +10,6 @@ import (
dnsmsg "github.com/miekg/dns"
"v2ray.com/core/app"
"v2ray.com/core/app/dispatcher"
"v2ray.com/core/app/dns"
"v2ray.com/core/common"
"v2ray.com/core/common/net"
)
@ -41,7 +40,7 @@ type CacheServer struct {
servers []NameServer
}
func NewCacheServer(ctx context.Context, config *dns.Config) (*CacheServer, error) {
func NewCacheServer(ctx context.Context, config *Config) (*CacheServer, error) {
space := app.SpaceFromContext(ctx)
if space == nil {
return nil, newError("no space in context")
@ -79,10 +78,11 @@ func NewCacheServer(ctx context.Context, config *dns.Config) (*CacheServer, erro
}
func (*CacheServer) Interface() interface{} {
return (*dns.Server)(nil)
return (*CacheServer)(nil)
}
func (*CacheServer) Start() error {
func (s *CacheServer) Start() error {
net.RegisterIPResolver(s)
return nil
}
@ -116,15 +116,15 @@ func (s *CacheServer) tryCleanup() {
}
}
func (s *CacheServer) Get(domain string) []net.IP {
func (s *CacheServer) LookupIP(domain string) ([]net.IP, error) {
if ip, found := s.hosts[domain]; found {
return []net.IP{ip}
return []net.IP{ip}, nil
}
domain = dnsmsg.Fqdn(domain)
ips := s.GetCached(domain)
if ips != nil {
return ips
return ips, nil
}
s.tryCleanup()
@ -144,17 +144,16 @@ func (s *CacheServer) Get(domain string) []net.IP {
}
s.Unlock()
newError("returning ", len(a.IPs), " IPs for domain ", domain).AtDebug().WriteToLog()
return a.IPs
return a.IPs, nil
case <-time.After(QueryTimeout):
}
}
newError("returning nil for domain ", domain).AtDebug().WriteToLog()
return nil
return nil, newError("returning nil for domain ", domain)
}
func init() {
common.Must(common.RegisterConfig((*dns.Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
return NewCacheServer(ctx, config.(*dns.Config))
common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
return NewCacheServer(ctx, config.(*Config))
}))
}

View File

@ -1,7 +0,0 @@
package server
import "v2ray.com/core/common/errors"
func newError(values ...interface{}) *errors.Error {
return errors.New(values...).Path("App", "DNS", "Server")
}

View File

@ -1,4 +1,4 @@
package server_test
package dns_test
import (
"context"
@ -8,7 +8,6 @@ import (
"v2ray.com/core/app/dispatcher"
_ "v2ray.com/core/app/dispatcher/impl"
. "v2ray.com/core/app/dns"
_ "v2ray.com/core/app/dns/server"
"v2ray.com/core/app/policy"
_ "v2ray.com/core/app/policy/manager"
"v2ray.com/core/app/proxyman"

View File

@ -6,7 +6,6 @@ import (
"context"
"v2ray.com/core/app"
"v2ray.com/core/app/dns"
"v2ray.com/core/common"
"v2ray.com/core/common/net"
"v2ray.com/core/proxy"
@ -19,7 +18,6 @@ var (
type Router struct {
domainStrategy Config_DomainStrategy
rules []Rule
dnsServer dns.Server
}
func NewRouter(ctx context.Context, config *Config) (*Router, error) {
@ -41,11 +39,6 @@ func NewRouter(ctx context.Context, config *Config) (*Router, error) {
}
r.rules[idx].Condition = cond
}
r.dnsServer = dns.FromSpace(space)
if r.dnsServer == nil {
return newError("DNS is not found in the space")
}
return nil
})
return r, nil
@ -55,7 +48,6 @@ type ipResolver struct {
ip []net.Address
domain string
resolved bool
dnsServer dns.Server
}
func (r *ipResolver) Resolve() []net.Address {
@ -65,7 +57,10 @@ func (r *ipResolver) Resolve() []net.Address {
newError("looking for IP for domain: ", r.domain).WriteToLog()
r.resolved = true
ips := r.dnsServer.Get(r.domain)
ips, err := net.LookupIP(r.domain)
if err != nil {
newError("failed to get IP address").Base(err).WriteToLog()
}
if len(ips) == 0 {
return nil
}
@ -77,9 +72,7 @@ func (r *ipResolver) Resolve() []net.Address {
}
func (r *Router) TakeDetour(ctx context.Context) (string, error) {
resolver := &ipResolver{
dnsServer: r.dnsServer,
}
resolver := &ipResolver{}
if r.domainStrategy == Config_IpOnDemand {
if dest, ok := proxy.TargetFromContext(ctx); ok && dest.Address.Family().IsDomain() {
resolver.domain = dest.Address.Domain()

44
common/net/dns.go Normal file
View File

@ -0,0 +1,44 @@
package net
import (
"net"
"sync/atomic"
"unsafe"
)
// IPResolver is the interface to resolve host name to IPs.
type IPResolver interface {
LookupIP(host string) ([]net.IP, error)
}
type systemIPResolver int
func (s systemIPResolver) LookupIP(host string) ([]net.IP, error) {
return net.LookupIP(host)
}
const (
systemIPResolverInstance = systemIPResolver(0)
)
// SystemIPResolver returns an IPResolver that resolves IP through underlying system.
func SystemIPResolver() IPResolver {
return systemIPResolverInstance
}
var (
ipResolver unsafe.Pointer
)
func LookupIP(host string) ([]net.IP, error) {
r := (*IPResolver)(atomic.LoadPointer(&ipResolver))
return (*r).LookupIP(host)
}
func RegisterIPResolver(resolver IPResolver) {
atomic.StorePointer(&ipResolver, unsafe.Pointer(&resolver))
}
func init() {
RegisterIPResolver(systemIPResolverInstance)
}

View File

@ -13,7 +13,6 @@ var ListenUDP = net.ListenUDP
var FileConn = net.FileConn
var LookupIP = net.LookupIP
var ParseIP = net.ParseIP
var SplitHostPort = net.SplitHostPort

View File

@ -3,7 +3,8 @@ package all
import (
// The following are necessary as they register handlers in their init functions.
_ "v2ray.com/core/app/dispatcher/impl"
_ "v2ray.com/core/app/dns/server"
_ "v2ray.com/core/app/dns"
_ "v2ray.com/core/app/log"
_ "v2ray.com/core/app/policy/manager"
_ "v2ray.com/core/app/proxyman/inbound"
_ "v2ray.com/core/app/proxyman/outbound"

View File

@ -6,7 +6,6 @@ import (
"context"
"v2ray.com/core/app"
"v2ray.com/core/app/dns"
"v2ray.com/core/app/policy"
"v2ray.com/core/common"
"v2ray.com/core/common/buf"
@ -23,7 +22,6 @@ import (
type Handler struct {
domainStrategy Config_DomainStrategy
timeout uint32
dns dns.Server
destOverride *DestinationOverride
policy policy.Policy
}
@ -40,12 +38,6 @@ func New(ctx context.Context, config *Config) (*Handler, error) {
destOverride: config.DestinationOverride,
}
space.On(app.SpaceInitializing, func(interface{}) error {
if config.DomainStrategy == Config_USE_IP {
f.dns = dns.FromSpace(space)
if f.dns == nil {
return newError("DNS server is not found in the space")
}
}
pm := policy.FromSpace(space)
if pm == nil {
return newError("Policy not found in space.")
@ -68,7 +60,10 @@ func (h *Handler) resolveIP(ctx context.Context, domain string) net.Address {
return ips[dice.Roll(len(ips))]
}
ips := h.dns.Get(domain)
ips, err := net.LookupIP(domain)
if err != nil {
newError("failed to get IP address for domain ", domain).Base(err).WriteToLog()
}
if len(ips) == 0 {
return nil
}

View File

@ -5,11 +5,9 @@ import (
"v2ray.com/core/app"
"v2ray.com/core/app/dispatcher"
"v2ray.com/core/app/dns"
"v2ray.com/core/app/policy"
"v2ray.com/core/app/proxyman"
"v2ray.com/core/common"
"v2ray.com/core/common/net"
)
// Server is an instance of V2Ray. At any time, there must be at most one Server instance running.
@ -84,19 +82,6 @@ func newSimpleServer(config *Config) (*simpleServer, error) {
inboundHandlerManager = o.(proxyman.InboundHandlerManager)
}
if dns.FromSpace(space) == nil {
dnsConfig := &dns.Config{
NameServers: []*net.Endpoint{{
Address: net.NewIPOrDomain(net.LocalHostDomain),
}},
}
d, err := app.CreateAppFromConfig(ctx, dnsConfig)
if err != nil {
return nil, err
}
common.Must(space.AddApplication(d))
}
if disp := dispatcher.FromSpace(space); disp == nil {
d, err := app.CreateAppFromConfig(ctx, new(dispatcher.Config))
if err != nil {