Skip to content

Commit

Permalink
intra: accept nil default dns to use goos
Browse files Browse the repository at this point in the history
  • Loading branch information
ignoramous committed Jan 24, 2025
1 parent 869a372 commit fada457
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 20 deletions.
75 changes: 56 additions & 19 deletions intra/bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@ import (
)

const (
bootid = dnsx.Bootstrap
specialHostname = protect.UidSelf
bootid = dnsx.Bootstrap
protectedHostname = protect.UidSelf // or protect.UidSystem
builtinHostname = protect.Localhost
)

var (
Expand Down Expand Up @@ -77,28 +78,50 @@ func NewDefaultDNS(typ, url, ips string) (DefaultDNS, error) {
return b, nil
}

func newDefaultDohTransport(ctx context.Context, url string, ipcsv string, p ipn.Proxies) (dnsx.Transport, error) {
ips := strings.Split(ipcsv, ",")
if len(url) > 0 && len(ips) > 0 {
return doh.NewTransport(ctx, bootid, url, ips, p)
// NewBuiltinDefaultDNS creates a new DefaultDNS resolver of type dnsx.DNS53.
// It may either use OS provided or network provided DNS resolver, & will not
// work if the tunnel is in "Loopback" mode; create w/ NewDefaultDNS instead.
func NewBuiltinDefaultDNS() (DefaultDNS, error) {
b := new(bootstrap)
b.ctx = context.TODO()

if err := b.reinit("", "", ""); err != nil {
return nil, err
}

// context.AfterFunc(b.ctx, func() { b.Stop() })
log.I("dns: default: built-in")

return b, nil
}

func (b *bootstrap) newDefaultDohTransport() (dnsx.Transport, error) {
ips := strings.Split(b.ipports, ",")
if len(b.url) > 0 && len(ips) > 0 {
return doh.NewTransport(b.ctx, bootid, b.url, ips, b.proxies)
}
return nil, errCannotStart
}

func newDefaultTransport(ctx context.Context, ipcsv string, p ipn.Proxies) (dnsx.Transport, error) {
if len(ipcsv) > 0 {
return dns53.NewTransportFromHostname(ctx, bootid, specialHostname, ipcsv, p)
func (b *bootstrap) newDefaultTransport() (dnsx.Transport, error) {
if ipcsv := b.ipports; len(ipcsv) > 0 {
return dns53.NewTransportFromHostname(b.ctx, bootid, b.hostname, ipcsv, b.proxies)
}
return nil, errCannotStart
}

func (b *bootstrap) reinit(trtype, ippOrUrl, ipcsv string) error {
if len(ippOrUrl) <= 0 {
log.E("dns: default: reinit: empty url %s! ips? %s", ippOrUrl, ipcsv)
return dnsx.ErrNotDefaultTransport
}
if len(trtype) <= 0 && len(ippOrUrl) <= 0 && len(ipcsv) <= 0 {
b.url = ""
b.hostname = builtinHostname
b.ipports = localip4 + "," + localip6
b.typ = dnsx.DNS53
} else if trtype == dnsx.DOH {
if len(ippOrUrl) <= 0 {
log.E("dns: default: reinit: empty url %s! ips? %s", ippOrUrl, ipcsv)
return dnsx.ErrNotDefaultTransport
}

if trtype == dnsx.DOH {
// note: plain ip4 address is a valid url; ex: 1.2.3.4
if parsed, err := url.Parse(ippOrUrl); err != nil { // ippOrUrl is a url?
log.E("dns: default: reinit: not %s url %s", trtype, ippOrUrl)
Expand All @@ -121,9 +144,19 @@ func (b *bootstrap) reinit(trtype, ippOrUrl, ipcsv string) error {
log.E("dns: default: reinit: ipport %s; %s != %s", ippOrUrl, trtype, dnsx.DNS53)
return dnsx.ErrNotDefaultTransport
}
if len(ippOrUrl) <= 0 {
log.I("dns: default: reinit: empty ipport %s; using: ", ippOrUrl, ipcsv)
ippOrUrl = ipcsv
}
if len(ippOrUrl) <= 0 {
log.E("dns: default: reinit: empty url %s! ips? %s", ippOrUrl, ipcsv)
return dnsx.ErrNotDefaultTransport
}

// may be set to localhost (in which case it is equivalent to x.Goos)
// when no other system resolver could be determined
if strings.HasPrefix(ippOrUrl, "localhost") {
if strings.HasPrefix(ippOrUrl, builtinHostname) {
// note: this is not goos; for goos, trtype, ippOrUrl, ipcsv are all empty!
log.I("dns: default: reinit: loopback %s", ippOrUrl)
ippOrUrl = localip4 + "," + localip6 // see also dns53/ipmapper.go
}
Expand All @@ -138,8 +171,8 @@ func (b *bootstrap) reinit(trtype, ippOrUrl, ipcsv string) error {
return err
} else {
b.url = ""
b.hostname = specialHostname
b.ipports = ippOrUrl // always ipaddrs or csv(ipaddrs), never empty
b.hostname = protectedHostname // override all incoming hostnames
b.ipports = ippOrUrl // always ipaddrs or csv(ipaddrs), never empty
b.typ = dnsx.DNS53
}
}
Expand Down Expand Up @@ -167,9 +200,13 @@ func (b *bootstrap) kickstart(px ipn.Proxies) error {
var err error
switch b.typ {
case dnsx.DNS53:
tr, err = newDefaultTransport(b.ctx, b.ipports, px)
if b.hostname == builtinHostname {
tr, err = dns53.NewGoosTransport(b.ctx, px)
} else {
tr, err = b.newDefaultTransport()
}
case dnsx.DOH:
tr, err = newDefaultDohTransport(b.ctx, b.url, b.ipports, px)
tr, err = b.newDefaultDohTransport()
default:
err = errDefaultTransportType
}
Expand Down
2 changes: 1 addition & 1 deletion intra/tun2socks.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ func init() {
// `mtu` is the MTU of the TUN device.
// `fakedns` are the DNS servers that the system believes it is using, in "host:port" style.
// `bdg` is a kotlin object that implements the Bridge interface.
// `dtr` is a kotlin object that implements the DefaultDNS interface.
// `dtr` is the DefaultDNS (see: intra.NewDefaultDNS); can be nil. Changeable via intra.AddDefaultTransport.
// Throws an exception if the TUN file descriptor cannot be opened, or if the tunnel fails to
// connect.
func Connect(fd, mtu int, fakedns string, dtr DefaultDNS, bdg Bridge) (t Tunnel, err error) {
Expand Down
4 changes: 4 additions & 0 deletions intra/tunnel.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,10 @@ type rtunnel struct {
func NewTunnel(fd, mtu int, fakedns string, tunmode *settings.TunMode, dtr DefaultDNS, bdg Bridge) (t Tunnel, err error) {
defer core.Recover(core.Exit11, "i.newTunnel")

if dtr == nil || core.IsNil(dtr) {
dtr, _ = NewBuiltinDefaultDNS()
}

if bdg == nil || dtr == nil {
return nil, fmt.Errorf("tun: no bridge? %t or default-dns? %t", bdg == nil, dtr == nil)
}
Expand Down

2 comments on commit fada457

@ignoramous
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ignoramous
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Allow using dnsx.Goos explicitly as System DNS is not always retrieved as expected: celzero/rethink-app#1503

Please sign in to comment.