Skip to content

Commit

Permalink
tcp,udp,icmp: on just-in-time split-tunnel (dnsx.Fixed), undo alg per…
Browse files Browse the repository at this point in the history
… tid
  • Loading branch information
ignoramous committed Nov 4, 2024
1 parent fecffef commit 55b8ff2
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 13 deletions.
6 changes: 3 additions & 3 deletions intra/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ func (h *baseHandler) onFlow(localaddr, target netip.AddrPort) (fm *Mark, undidA
newips, err := dialers.ResolveOn(d, tids...)
hasNewIPs = err == nil && len(newips) > 0
if hasNewIPs { // fetch alg result if resolve succeeded
_, ips, doms, pdoms, blocklists = h.undoAlg(target.Addr())
_, ips, doms, pdoms, blocklists = h.undoAlg(target.Addr(), tids...)
break
} // else: either no known transport or preflow failed
}
Expand Down Expand Up @@ -473,7 +473,7 @@ func makeIPPorts(realips string, origipp netip.AddrPort, cap int) []netip.AddrPo
}

// algip may or may not be an actual alg ip.
func (h *baseHandler) undoAlg(algip netip.Addr) (undidAlg bool, realips, domains, probableDomains, blocklists string) {
func (h *baseHandler) undoAlg(algip netip.Addr, tids ...string) (undidAlg bool, realips, domains, probableDomains, blocklists string) {
r := h.resolver
didForce := false
forcePTR := true // force PTR resolution?
Expand All @@ -487,7 +487,7 @@ func (h *baseHandler) undoAlg(algip netip.Addr) (undidAlg bool, realips, domains
// but we end up dailing into a v6 (or v4) address (which was unaccounted for).
// Dialing into v6 (or v4) address may succeed in such scenarios thereby
// resulting in a perceived "leak".
realips, undidAlg = gw.X(algip)
realips, undidAlg = gw.X(algip, tids...)
realips = filterFamilyForDialing(realips)
blocklists = gw.RDNSBL(algip)
} else {
Expand Down
41 changes: 31 additions & 10 deletions intra/dnsx/alg.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ func isAlgErr(err error) bool {

type Gateway interface {
// given an alg or real ip, retrieves assoc real ips as csv, if any
X(maybeAlg netip.Addr) (realipcsv string, undidAlg bool)
X(maybeAlg netip.Addr, tids ...string) (realipcsv string, undidAlg bool)
// given an alg or real ip, retrieves assoc dns names as csv, if any
PTR(maybeAlg netip.Addr, force bool) (domaincsv string, didForce bool)
// given domain, retrieve assoc alg ips or real ips as csv, if any
Expand Down Expand Up @@ -132,14 +132,22 @@ func flatten[K comparable, V any](m map[K][]V, upto uint) ([]K, []V) {
return outk, outv
}

func (p *xips) primary() []netip.Addr {
p.mu.RLock()
defer p.mu.RUnlock()

_, v := flatten(p.pri, 0)
return v
}

// x returns ips to translated to
func (p *xips) x() []netip.Addr {
_, s := flatten(p.pri, 0)
pri := p.primary()

if p.block() {
return append(s, anyaddr4, anyaddr6)
return append(pri, anyaddr4, anyaddr6)
}
return s
return pri
}

// all returns all translatabale ips
Expand All @@ -149,7 +157,7 @@ func (p *xips) all() []netip.Addr {

func (p *xips) of(tid string) []netip.Addr {
if tid == notransport {
return p.all()
return p.x()
}
p.mu.RLock()
defer p.mu.RUnlock()
Expand All @@ -175,6 +183,7 @@ func (p *xips) block() bool {
return false
}

// each iterates over each pri and aux ip
func (p *xips) each(f func(ip netip.Addr)) {
for _, ip := range p.all() {
f(ip)
Expand Down Expand Up @@ -920,13 +929,13 @@ func gen6Locked(k string, hop int) netip.Addr {
return netip.AddrFrom16(b16)
}

func (t *dnsgateway) X(maybeAlg netip.Addr) (ips string, undidAlg bool) {
func (t *dnsgateway) X(maybeAlg netip.Addr, tids ...string) (ips string, undidAlg bool) {
t.RLock()
defer t.RUnlock()

// stale IPs are okay iff !mod; as then maybeAlg itself is a realip
usestale := !t.mod.Load()
rip, undidAlg := t.xLocked(maybeAlg, usestale)
rip, undidAlg := t.xLocked(maybeAlg, usestale, tids...)
return netip2csv(rip), undidAlg // rip may be 0 len
}

Expand Down Expand Up @@ -962,14 +971,20 @@ func (t *dnsgateway) RDNSBL(algip netip.Addr) (blocklists string) {
return t.rdnsblLocked(algip, !t.mod.Load())
}

func (t *dnsgateway) xLocked(maybeAlg netip.Addr, usestale bool) ([]netip.Addr, bool) {
func (t *dnsgateway) xLocked(maybeAlg netip.Addr, usestale bool, tids ...string) ([]netip.Addr, bool) {
var realips []netip.Addr
var undidAlg, fresh bool
// alg ips are always unmappped; see take4Locked
unmapped := maybeAlg.Unmap() // aligip may also be origip / realip
if ans, ok := t.nat[unmapped]; ok {
if fresh = time.Until(ans.ttl) > 0; fresh || usestale {
realips = ans.ips.x()
if len(tids) <= 0 {
realips = ans.ips.x()
} else {
for _, tid := range tids {
realips = append(realips, ans.ips.of(tid)...)
}
}
}
undidAlg = true
} else if ans, ok := t.ptr[unmapped]; ok {
Expand All @@ -979,7 +994,13 @@ func (t *dnsgateway) xLocked(maybeAlg netip.Addr, usestale bool) ([]netip.Addr,
// nb: both realips & secondaryips may be nil, but that's okay:
// go.dev/play/p/fSjRjMSAS2m
if fresh = time.Until(ans.ttl) > 0; fresh || usestale {
realips = ans.ips.x()
if len(tids) <= 0 {
realips = ans.ips.x()
} else {
for _, tid := range tids {
realips = append(realips, ans.ips.of(tid)...)
}
}
}
}
var unnated []netip.Addr
Expand Down

1 comment on commit 55b8ff2

@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.

Please sign in to comment.