Skip to content

Commit

Permalink
dns53/ipmapper: use default or system transports
Browse files Browse the repository at this point in the history
  • Loading branch information
ignoramous committed Oct 11, 2023
1 parent fc36f7e commit 0b3f502
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 12 deletions.
4 changes: 2 additions & 2 deletions intra/dns.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ import (
"github.com/celzero/firestack/intra/log"
)

func addIPMapper(r dnsx.Resolver) {
dns53.AddIPMapper(r)
func addIPMapper(r dnsx.Resolver, l dnsx.DNSListener) {
dns53.AddIPMapper(r, l)
}

func AddDNSProxy(t Tunnel, id, ip, port string) error {
Expand Down
76 changes: 67 additions & 9 deletions intra/dns53/ipmapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ import (
"context"
"errors"
"net/netip"
"time"

"github.com/celzero/firestack/intra/core"
"github.com/celzero/firestack/intra/dnsx"
"github.com/celzero/firestack/intra/log"
"github.com/celzero/firestack/intra/split"
Expand All @@ -22,32 +24,74 @@ var (
errNoHost = errors.New("no hostname")
errNoAns = errors.New("no answer")
errNoIps = errors.New("no ips")
ttl5s = 5 * time.Second
)

type ipmapper struct {
r dnsx.Resolver
id string
r dnsx.Resolver
l dnsx.DNSListener
ba *core.Barrier
}

func AddIPMapper(r dnsx.Resolver) {
m := &ipmapper{r}
func AddIPMapper(r dnsx.Resolver, l dnsx.DNSListener) {
m := &ipmapper{dnsx.IpMapper, r, l, core.NewBarrier(ttl5s)}
split.Mapper(m)
}

func (m *ipmapper) LookupNetIP(ctx context.Context, network, host string) ([]netip.Addr, error) {
func (m *ipmapper) LookupNetIP(ctx context.Context, network, host string) (_ []netip.Addr, err error) {
if len(host) <= 0 {
return nil, errNoHost
}

q4, err4 := query(host, dns.TypeA)
q6, err6 := query(host, dns.TypeAAAA)
q4, err4 := dnsmsg(host, dns.TypeA)
q6, err6 := dnsmsg(host, dns.TypeAAAA)
if err4 != nil || err6 != nil {
return nil, errors.Join(err4, err6)
}
r4, err4 := m.r.Forward(q4)
r6, err6 := m.r.Forward(q6)

ssu4 := &dnsx.Summary{
QName: host,
QType: int(dns.TypeA),
Status: dnsx.Start,
}
ssu6 := &dnsx.Summary{
QName: host,
QType: int(dns.TypeAAAA),
Status: dnsx.Start,
}

defer func() {
if err != nil && !errors.Is(err, errNoIps) {
log.W("ipmapper: lookup(%s), err: %v", host, err)
ssu4.RCode = dns.RcodeServerFailure
ssu4.RData = xdns.GetInterestingRData(nil)
ssu4.Status = dnsx.SendFailed
ssu4.ID = m.id
ssu6.RCode = dns.RcodeServerFailure
ssu6.RData = xdns.GetInterestingRData(nil)
ssu6.Status = dnsx.SendFailed
ssu6.ID = m.id
}
go m.l.OnResponse(ssu4)
go m.l.OnResponse(ssu6)
}()

// TODO: m.l.OnQuery() to determine transport with suggested_id?
tr, errtr := m.determineTransport()
if errtr != nil {
return nil, errtr
}

r4, err4 := tr.Query(dnsx.NetTypeUDP, q4, ssu4)
r6, err6 := tr.Query(dnsx.NetTypeUDP, q6, ssu6)

if len(r4) <= 0 && len(r6) <= 0 {
return nil, errors.Join(errNoAns, err4, err6)
} else if err4 != nil && err6 != nil {
return nil, errors.Join(err4, err6)
}

ips := make([]netip.Addr, 0, len(r4)+len(r6))
ip4 := addrs(r4)
ip6 := addrs(r6)
Expand All @@ -59,6 +103,20 @@ func (m *ipmapper) LookupNetIP(ctx context.Context, network, host string) ([]net
return ips, nil
}

func (m *ipmapper) determineTransport() (tr dnsx.Transport, err error) {
dtr, derr := m.r.Get(dnsx.Default)
if derr == nil && dtr.ID() != dnsx.BlockAll {
tr = dtr
} else {
str, serr := m.r.Get(dnsx.System)
if serr != nil {
return nil, errors.Join(serr, derr)
}
tr = str
}
return
}

func addrs(a []byte) []netip.Addr {
msg := xdns.AsMsg(a)
if msg == nil {
Expand All @@ -82,7 +140,7 @@ func addrs(a []byte) []netip.Addr {
return ips
}

func query(host string, qtype uint16) ([]byte, error) {
func dnsmsg(host string, qtype uint16) ([]byte, error) {
msg := dns.Msg{
MsgHdr: dns.MsgHdr{
RecursionDesired: true,
Expand Down
1 change: 1 addition & 0 deletions intra/dnsx/transport.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ const (
BlockAll = "BlockAll" // all blocks
Alg = "Alg" // dns application-level gateway
DcProxy = "DcProxy" // dnscrypt.Proxy as a transport
IpMapper = "IpMapper" // dns resolver for dns resolvers

invalidQname = "invalid.query"

Expand Down
2 changes: 1 addition & 1 deletion intra/tunnel.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ func NewTunnel(fd, mtu int, fakedns string, tunmode *settings.TunMode, bdg Bridg
resolver.Add(newDNSCryptTransport(proxies, bdg)) // fixed
resolver.Add(newMDNSTransport(l3)) // fixed

addIPMapper(resolver) // namespace aware resolver for pkg split
addIPMapper(resolver, bdg) // namespace aware resolver for pkg split

tcph := NewTCPHandler(resolver, proxies, tunmode, bdg, bdg)
udph := NewUDPHandler(resolver, proxies, tunmode, bdg, bdg)
Expand Down

0 comments on commit 0b3f502

Please sign in to comment.