github.com/mtibben/androiddnsfix@v0.0.0-20200907095054-ff0280446354/dnsconfig_androiddnsfix.go (about)

     1  // +build androiddnsfix
     2  
     3  package androiddnsfix
     4  
     5  import (
     6  	_ "net"
     7  	"sync"
     8  	"time"
     9  	_ "unsafe"
    10  )
    11  
    12  // DNS resolve workaround for Android & iOS in pure go
    13  
    14  //go:linkname defaultNS net.defaultNS
    15  var defaultNS []string
    16  
    17  // need to keep sync with go version
    18  //go:linkname resolvConf net.resolvConf
    19  var resolvConf resolverConfig
    20  
    21  // copy from /src/net/dnsconfig_unix.go
    22  type dnsConfig struct {
    23  	servers    []string      // server addresses (in host:port form) to use
    24  	search     []string      // rooted suffixes to append to local name
    25  	ndots      int           // number of dots in name to trigger absolute lookup
    26  	timeout    time.Duration // wait before giving up on a query, including retries
    27  	attempts   int           // lost packets before giving up on server
    28  	rotate     bool          // round robin among servers
    29  	unknownOpt bool          // anything unknown was encountered
    30  	lookup     []string      // OpenBSD top-level database "lookup" order
    31  	err        error         // any error that occurs during open of resolv.conf
    32  	mtime      time.Time     // time of resolv.conf modification
    33  	soffset    uint32        // used by serverOffset
    34  }
    35  
    36  // copy from /src/net/dnsclient_unix.go
    37  type resolverConfig struct {
    38  	initOnce sync.Once // guards init of resolverConfig
    39  
    40  	// ch is used as a semaphore that only allows one lookup at a
    41  	// time to recheck resolv.conf.
    42  	ch          chan struct{} // guards lastChecked and modTime
    43  	lastChecked time.Time     // last time resolv.conf was checked
    44  
    45  	mu        sync.RWMutex // protects dnsConfig
    46  	dnsConfig *dnsConfig   // parsed resolv.conf structure used in lookups
    47  }
    48  
    49  //go:linkname (*resolverConfig).tryUpdate net.(*resolverConfig).tryUpdate
    50  func (*resolverConfig) tryUpdate(string)
    51  
    52  // Need an empty .s file (dnsconfig_empty.s)
    53  
    54  func setDefaultNS(addrs []string, loadFromSystem bool) {
    55  	if resolvConf.dnsConfig == nil {
    56  		resolvConf.tryUpdate("")
    57  	}
    58  
    59  	if loadFromSystem {
    60  		now := time.Now()
    61  		resolvConf.lastChecked = now.Add(-6 * time.Second)
    62  		resolvConf.dnsConfig.mtime = now
    63  	}
    64  
    65  	resolvConf.dnsConfig.servers = addrs
    66  }
    67  
    68  func SetDNSPair(primary, secondary string, loadFromSystem bool) {
    69  	setDefaultNS([]string{primary, secondary}, loadFromSystem)
    70  }
    71  
    72  func init() {
    73  	SetDNSPair("1.1.1.1:53", "8.8.8.8:53", false)
    74  }