Skip to content

Commit c4e7e4c

Browse files
committed
dnsx/alg: per-app (uid) alg translations
1 parent ca3c8a1 commit c4e7e4c

6 files changed

Lines changed: 308 additions & 154 deletions

File tree

intra/common.go

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -153,28 +153,31 @@ func (h *baseHandler) onFlow(localaddr, target netip.AddrPort) (fm *Mark, undidA
153153
dst := target.String()
154154

155155
var pdoms, blocklists string
156-
var pre *PreMark
157-
var ok bool
158156

159-
// alg happens after nat64, and so, alg knows nat-ed ips
160-
// that is, real ips ("ips") are un-nated
161-
undidAlg, ips, doms, pdoms, blocklists = h.undoAlg(target.Addr())
157+
pre, _ := core.Grx(h.proto+".preflow", func(_ context.Context) (*PreMark, error) {
158+
return h.listener.Preflow(proto, int32(uid), src, dst, doms), nil
159+
}, onFlowTimeout)
160+
161+
hasPre := pre != nil
162+
preuid := UNKNOWN_UID_STR
163+
if hasPre && len(pre.UID) > 0 {
164+
preuid = pre.UID
165+
}
166+
167+
// alg happens after nat64, and so, alg knows nat-ed ips and un-nats them;
168+
// that is, real ips ("ips") are already un-nated where applicable.
169+
undidAlg, ips, doms, pdoms, blocklists = h.undoAlg(target.Addr(), preuid)
162170
hasOldIPs := len(ips) > 0
163171
if undidAlg && !hasOldIPs {
164-
pre, ok = core.Grx(h.proto+".preflow", func(_ context.Context) (*PreMark, error) {
165-
return h.listener.Preflow(proto, int32(uid), src, dst, doms), nil
166-
}, onFlowTimeout)
167-
168172
hasNewIPs := false
169-
hasPre := pre != nil
170-
if ok && hasPre {
173+
if hasPre {
171174
for d := range strings.SplitSeq(doms, ",") {
172175
if len(d) <= 0 {
173176
log.V("com: %s: onFlow: preflow: empty domain in %v from %v => %v for %s; skip!",
174-
h.proto, doms, src, target, pre.UID)
177+
h.proto, doms, src, target, preuid)
175178
continue
176179
}
177-
newips, err := dialers.ResolveFor(d, pre.UID)
180+
newips, err := dialers.ResolveFor(d, preuid)
178181
hasNewIPs = err == nil && len(newips) > 0
179182
if hasNewIPs { // already unalg'd by ipmapper
180183
// _, ips, doms, pdoms, blocklists = h.undoAlg(target.Addr())
@@ -184,9 +187,9 @@ func (h *baseHandler) onFlow(localaddr, target netip.AddrPort) (fm *Mark, undidA
184187
}
185188
} // else: either no known transport or preflow failed
186189

187-
if !ok || !hasPre || !hasNewIPs {
188-
log.E("com: %s: onFlow: alg, but no preflow? %t / %t, ips? %t for %v; uid: %s; block!",
189-
h.proto, ok, hasPre, hasNewIPs, doms, pre)
190+
if !hasPre || !hasNewIPs {
191+
log.E("com: %s: onFlow: alg, but no preflow? %t, ips? %t for %v; uid: %s; block!",
192+
h.proto, hasPre, hasNewIPs, doms, pre)
190193
// either optionsBase (BlockModeNone) or optionsBlock
191194
return fm, undidAlg, "", ""
192195
} // else: if we've got target and/or old ips, dial them
@@ -199,7 +202,7 @@ func (h *baseHandler) onFlow(localaddr, target netip.AddrPort) (fm *Mark, undidA
199202
h.proto, ips, doms, pdoms, localaddr, target)
200203
}
201204

202-
fm, ok = core.Grx(h.proto+".flow", func(_ context.Context) (*Mark, error) {
205+
fm, ok := core.Grx(h.proto+".flow", func(_ context.Context) (*Mark, error) {
203206
return h.listener.Flow(proto, int32(uid), src, dst, ips, doms, pdoms, blocklists), nil
204207
}, onFlowTimeout)
205208

@@ -471,7 +474,7 @@ func makeIPPorts(ips []netip.Addr, origipp netip.AddrPort, cap int) []netip.Addr
471474
// algip may or may not be an actual alg ip.
472475
// returned realips may be incoming algip itself or translated from algip,
473476
// depending on whether alg is enabled (ref: undidAlg).
474-
func (h *baseHandler) undoAlg(algip netip.Addr, tids ...string) (undidAlg bool, realips, domains, probableDomains, blocklists string) {
477+
func (h *baseHandler) undoAlg(algip netip.Addr, uid string, tids ...string) (undidAlg bool, realips, domains, probableDomains, blocklists string) {
475478
r := h.resolver
476479
didForce := false
477480
forcePTR := true // force PTR (realip => algans) translation?
@@ -482,16 +485,16 @@ func (h *baseHandler) undoAlg(algip netip.Addr, tids ...string) (undidAlg bool,
482485
}
483486
var ips []netip.Addr
484487
// ips will contain the incoming "algip" arg, in cases where alg is NOT enabled.
485-
ips, undidAlg = gw.X(algip, tids...)
488+
ips, undidAlg = gw.X(algip, uid, tids...)
486489
realips = dnsx.Netip2Csv(ips)
487490
blocklists = gw.RDNSBL(algip)
488491
} else {
489-
log.W("com: %s: alg: undoAlg: for %v; no gw(%t) or dst(%v)", h.proto, tids, gw == nil, algip)
492+
log.W("com: %s: alg: undoAlg: for %v[%s]; no gw(%t) or dst(%v)", h.proto, tids, uid, gw == nil, algip)
490493
return
491494
}
492495

493-
log.VV("com: %s: alg: undoAlg: for %v (ok? %t, force? %t, withForce? %t) %s => %v (for %s / block: %s)",
494-
h.proto, tids, undidAlg, didForce, forcePTR, algip, realips, domains, blocklists)
496+
log.VV("com: %s: alg: undoAlg: for %v[%s] (ok? %t, force? %t, withForce? %t) %s => %v (for %s / block: %s)",
497+
h.proto, tids, uid, undidAlg, didForce, forcePTR, algip, realips, domains, blocklists)
495498
return
496499
}
497500

intra/core/proto.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
const (
1919
UNKNOWN_UID = -1
2020
UNKNOWN_UID_STR = "-1"
21+
DNS_UID_STR = "1051"
2122
UNSUPPORTED_NETWORK = -1
2223
)
2324

intra/dns53/ipmapper.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -247,26 +247,26 @@ func (m *ipmapper) locallookup(q []byte) func() (answer, error) {
247247
}
248248
}
249249

250-
func (m *ipmapper) undoAlg(ip64 []netip.Addr, tid string) []netip.Addr {
250+
func (m *ipmapper) undoAlg(ip64 []netip.Addr, tid, uid string) []netip.Addr {
251251
// unlike common.go:undoAlg, we do not filter out ipaddrs
252252
// based on dialers.Use4/Use6. This is because the ipmapper
253253
// is used for DNS queries, and the dialers are used for
254254
// actual connections. The dialers will filter out ipaddrs
255255
// based on the dialers.Use4/Use6 settings.
256256
gw := m.r.Gateway()
257257
if gw == nil {
258-
log.V("ipmapper: undoAlg: no-op for %v on %s; no gateway", ip64, tid)
258+
log.V("ipmapper: undoAlg: no-op for %v on %s[%s]; no gateway", ip64, tid, uid)
259259
return ip64
260260
}
261261
realips := make([]netip.Addr, 0, len(ip64))
262262
for _, addr := range ip64 {
263-
if xips, undidAlg := gw.X(addr, tid); len(xips) > 0 {
263+
if xips, undidAlg := gw.X(addr, uid, tid); len(xips) > 0 {
264264
// may contain duplicates due to how alg maps domains and ips
265265
realips = append(realips, xips...)
266266
continue // skip log.W below
267267
} else {
268-
log.W("ipmapper: undoAlg: no algip => realip? (%s => %v); undidAlg? %t; tid? %s",
269-
addr, xips, undidAlg, tid)
268+
log.W("ipmapper: undoAlg: no algip => realip? (%s => %v); undidAlg? %t; tid? %s[%s]",
269+
addr, xips, undidAlg, tid, uid)
270270
}
271271
}
272272
return realips // no dups

0 commit comments

Comments
 (0)