mirror of
https://github.com/safing/portmaster
synced 2026-04-28 03:20:31 +00:00
feat: add VerdictRerouteToSplitTun verdict type
Add a new verdict (value 8) for routing connections through the split tunnel. This prepares the infrastructure for the upcoming split-tunneling feature without implementing the full feature yet. Changes: - Define VerdictRerouteToSplitTun in network/status.go with String() and Verb() - Add RerouteToSplitTun() to the Packet interface and InfoPacket stub - Implement RerouteToSplitTun() for windowskext (v1) and windowskext2 (v2) packets - Map VerdictRerouteToSplitTun to KextVerdict 11 in kextinterface and kext2 - Handle the verdict in packet_handler.go dispatch, connection.go, api.go, metrics.go and nameserver.go - Add VerdictRerouteToSplitTun = 8 to Angular Verdict enum and update stats counting, filter queries and verdict CSS class (WIP) Note: Linux (nfq) implementation not updated yet. Therefore Linux build will fail.
This commit is contained in:
parent
52bfe1750f
commit
933323d5f9
18 changed files with 51 additions and 13 deletions
|
|
@ -459,6 +459,7 @@ export class Netquery {
|
||||||
case Verdict.Accept:
|
case Verdict.Accept:
|
||||||
case Verdict.RerouteToNs:
|
case Verdict.RerouteToNs:
|
||||||
case Verdict.RerouteToTunnel:
|
case Verdict.RerouteToTunnel:
|
||||||
|
case Verdict.RerouteToSplitTun:
|
||||||
case Verdict.Undeterminable:
|
case Verdict.Undeterminable:
|
||||||
stats.size += res.totalCount
|
stats.size += res.totalCount
|
||||||
stats.countAllowed += res.totalCount;
|
stats.countAllowed += res.totalCount;
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,8 @@ export enum Verdict {
|
||||||
Drop = 4,
|
Drop = 4,
|
||||||
RerouteToNs = 5,
|
RerouteToNs = 5,
|
||||||
RerouteToTunnel = 6,
|
RerouteToTunnel = 6,
|
||||||
Failed = 7
|
Failed = 7,
|
||||||
|
RerouteToSplitTun = 8
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum IPProtocol {
|
export enum IPProtocol {
|
||||||
|
|
|
||||||
|
|
@ -1206,7 +1206,8 @@ export class SfngNetqueryViewer implements OnInit, OnDestroy, AfterViewInit {
|
||||||
$in: [
|
$in: [
|
||||||
Verdict.Accept,
|
Verdict.Accept,
|
||||||
Verdict.RerouteToNs,
|
Verdict.RerouteToNs,
|
||||||
Verdict.RerouteToTunnel
|
Verdict.RerouteToTunnel,
|
||||||
|
Verdict.RerouteToSplitTun
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,8 @@ span.verdict {
|
||||||
|
|
||||||
&.accept,
|
&.accept,
|
||||||
&.reroutetons,
|
&.reroutetons,
|
||||||
&.reroutetotunnel {
|
&.reroutetotunnel,
|
||||||
|
&.reroutetosplittun {
|
||||||
--bg-color: theme('colors.info.green');
|
--bg-color: theme('colors.info.green');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -65,3 +65,8 @@ func (p *tracedPacket) RerouteToTunnel() error {
|
||||||
defer p.markServed("reroute-tunnel")
|
defer p.markServed("reroute-tunnel")
|
||||||
return p.Packet.RerouteToTunnel()
|
return p.Packet.RerouteToTunnel()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *tracedPacket) RerouteToSplitTun() error {
|
||||||
|
defer p.markServed("reroute-splittun")
|
||||||
|
return p.Packet.RerouteToSplitTun()
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -135,3 +135,11 @@ func (pkt *Packet) RerouteToTunnel() error {
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RerouteToSplitTun permanently reroutes the connection to the split tunnel (and the current packet).
|
||||||
|
func (pkt *Packet) RerouteToSplitTun() error {
|
||||||
|
if pkt.verdictSet.SetToIf(false, true) {
|
||||||
|
return SetVerdict(pkt, network.VerdictRerouteToSplitTun)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -183,6 +183,8 @@ func getKextVerdictFromConnection(conn *network.Connection) kextinterface.KextVe
|
||||||
return kextinterface.VerdictRerouteToNameserver
|
return kextinterface.VerdictRerouteToNameserver
|
||||||
case network.VerdictRerouteToTunnel:
|
case network.VerdictRerouteToTunnel:
|
||||||
return kextinterface.VerdictRerouteToTunnel
|
return kextinterface.VerdictRerouteToTunnel
|
||||||
|
case network.VerdictRerouteToSplitTun:
|
||||||
|
return kextinterface.VerdictRerouteToSplitTun
|
||||||
case network.VerdictFailed:
|
case network.VerdictFailed:
|
||||||
return kextinterface.VerdictFailed
|
return kextinterface.VerdictFailed
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -140,3 +140,11 @@ func (pkt *Packet) RerouteToTunnel() error {
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RerouteToSplitTun permanently reroutes the connection to the local split tunnel entrypoint (and the current packet).
|
||||||
|
func (pkt *Packet) RerouteToSplitTun() error {
|
||||||
|
if pkt.verdictSet.SetToIf(false, true) {
|
||||||
|
return SetVerdict(pkt, kextinterface.VerdictRerouteToSplitTun)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -844,6 +844,8 @@ func issueVerdict(conn *network.Connection, pkt packet.Packet, verdict network.V
|
||||||
err = pkt.RerouteToNameserver()
|
err = pkt.RerouteToNameserver()
|
||||||
case network.VerdictRerouteToTunnel:
|
case network.VerdictRerouteToTunnel:
|
||||||
err = pkt.RerouteToTunnel()
|
err = pkt.RerouteToTunnel()
|
||||||
|
case network.VerdictRerouteToSplitTun:
|
||||||
|
err = pkt.RerouteToSplitTun()
|
||||||
case network.VerdictFailed:
|
case network.VerdictFailed:
|
||||||
atomic.AddUint64(packetsFailed, 1)
|
atomic.AddUint64(packetsFailed, 1)
|
||||||
err = pkt.Drop()
|
err = pkt.Drop()
|
||||||
|
|
|
||||||
|
|
@ -205,7 +205,8 @@ func handleRequest(ctx context.Context, w dns.ResponseWriter, request *dns.Msg)
|
||||||
switch conn.Verdict {
|
switch conn.Verdict {
|
||||||
// We immediately save blocked, dropped or failed verdicts so
|
// We immediately save blocked, dropped or failed verdicts so
|
||||||
// they pop up in the UI.
|
// they pop up in the UI.
|
||||||
case network.VerdictBlock, network.VerdictDrop, network.VerdictFailed, network.VerdictRerouteToNameserver, network.VerdictRerouteToTunnel:
|
case network.VerdictBlock, network.VerdictDrop, network.VerdictFailed,
|
||||||
|
network.VerdictRerouteToNameserver, network.VerdictRerouteToTunnel, network.VerdictRerouteToSplitTun:
|
||||||
conn.Save()
|
conn.Save()
|
||||||
|
|
||||||
// For undecided or accepted connections we don't save them yet, because
|
// For undecided or accepted connections we don't save them yet, because
|
||||||
|
|
|
||||||
|
|
@ -167,6 +167,7 @@ func AddNetworkDebugData(di *debug.Info, profile, where string) {
|
||||||
switch conn.Verdict { //nolint:exhaustive
|
switch conn.Verdict { //nolint:exhaustive
|
||||||
case VerdictAccept,
|
case VerdictAccept,
|
||||||
VerdictRerouteToNameserver,
|
VerdictRerouteToNameserver,
|
||||||
|
VerdictRerouteToSplitTun,
|
||||||
VerdictRerouteToTunnel:
|
VerdictRerouteToTunnel:
|
||||||
|
|
||||||
accepted++
|
accepted++
|
||||||
|
|
|
||||||
|
|
@ -795,7 +795,7 @@ func (conn *Connection) Save() {
|
||||||
|
|
||||||
// nolint:exhaustive
|
// nolint:exhaustive
|
||||||
switch conn.Verdict {
|
switch conn.Verdict {
|
||||||
case VerdictAccept, VerdictRerouteToNameserver:
|
case VerdictAccept, VerdictRerouteToNameserver, VerdictRerouteToSplitTun:
|
||||||
conn.ConnectionEstablished = true
|
conn.ConnectionEstablished = true
|
||||||
case VerdictRerouteToTunnel:
|
case VerdictRerouteToTunnel:
|
||||||
// this is already handled when the connection tunnel has been
|
// this is already handled when the connection tunnel has been
|
||||||
|
|
|
||||||
|
|
@ -216,10 +216,10 @@ func (conn *Connection) ReplyWithDNS(ctx context.Context, request *dns.Msg) *dns
|
||||||
return nil // Do not respond to request.
|
return nil // Do not respond to request.
|
||||||
case VerdictFailed:
|
case VerdictFailed:
|
||||||
return nsutil.BlockIP().ReplyWithDNS(ctx, request)
|
return nsutil.BlockIP().ReplyWithDNS(ctx, request)
|
||||||
case VerdictUndecided, VerdictUndeterminable,
|
|
||||||
VerdictAccept, VerdictRerouteToNameserver, VerdictRerouteToTunnel:
|
|
||||||
fallthrough
|
|
||||||
default:
|
default:
|
||||||
|
// ReplyWithDNS is called when a DNS response to a DNS message is
|
||||||
|
// crafted because the request is either denied or blocked.
|
||||||
|
// So, other verdicts are not expected here.
|
||||||
reply := nsutil.ServerFailure().ReplyWithDNS(ctx, request)
|
reply := nsutil.ServerFailure().ReplyWithDNS(ctx, request)
|
||||||
nsutil.AddMessagesToReply(ctx, reply, log.ErrorLevel, "INTERNAL ERROR: incorrect use of Connection DNS Responder")
|
nsutil.AddMessagesToReply(ctx, reply, log.ErrorLevel, "INTERNAL ERROR: incorrect use of Connection DNS Responder")
|
||||||
return reply
|
return reply
|
||||||
|
|
@ -233,10 +233,6 @@ func (conn *Connection) GetExtraRRs(ctx context.Context, request *dns.Msg) []dns
|
||||||
switch conn.Verdict {
|
switch conn.Verdict {
|
||||||
case VerdictFailed:
|
case VerdictFailed:
|
||||||
level = log.ErrorLevel
|
level = log.ErrorLevel
|
||||||
case VerdictUndecided, VerdictUndeterminable,
|
|
||||||
VerdictAccept, VerdictBlock, VerdictDrop,
|
|
||||||
VerdictRerouteToNameserver, VerdictRerouteToTunnel:
|
|
||||||
fallthrough
|
|
||||||
default:
|
default:
|
||||||
level = log.InfoLevel
|
level = log.InfoLevel
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -145,7 +145,7 @@ func (conn *Connection) addToMetrics() {
|
||||||
blockedOutConnCounter.Inc()
|
blockedOutConnCounter.Inc()
|
||||||
conn.addedToMetrics = true
|
conn.addedToMetrics = true
|
||||||
return
|
return
|
||||||
case VerdictAccept, VerdictRerouteToTunnel:
|
case VerdictAccept, VerdictRerouteToTunnel, VerdictRerouteToSplitTun:
|
||||||
// Continue to next section.
|
// Continue to next section.
|
||||||
default:
|
default:
|
||||||
// Connection is not counted.
|
// Connection is not counted.
|
||||||
|
|
|
||||||
|
|
@ -74,4 +74,8 @@ func (pkt *InfoPacket) RerouteToTunnel() error {
|
||||||
return ErrInfoOnlyPacket
|
return ErrInfoOnlyPacket
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (pkt *InfoPacket) RerouteToSplitTun() error {
|
||||||
|
return ErrInfoOnlyPacket
|
||||||
|
}
|
||||||
|
|
||||||
var _ Packet = &InfoPacket{}
|
var _ Packet = &InfoPacket{}
|
||||||
|
|
|
||||||
|
|
@ -231,6 +231,7 @@ type Packet interface {
|
||||||
PermanentDrop() error
|
PermanentDrop() error
|
||||||
RerouteToNameserver() error
|
RerouteToNameserver() error
|
||||||
RerouteToTunnel() error
|
RerouteToTunnel() error
|
||||||
|
RerouteToSplitTun() error
|
||||||
FastTrackedByIntegration() bool
|
FastTrackedByIntegration() bool
|
||||||
InfoOnly() bool
|
InfoOnly() bool
|
||||||
ExpectInfo() bool
|
ExpectInfo() bool
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ const (
|
||||||
VerdictRerouteToNameserver Verdict = 5
|
VerdictRerouteToNameserver Verdict = 5
|
||||||
VerdictRerouteToTunnel Verdict = 6
|
VerdictRerouteToTunnel Verdict = 6
|
||||||
VerdictFailed Verdict = 7
|
VerdictFailed Verdict = 7
|
||||||
|
VerdictRerouteToSplitTun Verdict = 8
|
||||||
)
|
)
|
||||||
|
|
||||||
func (v Verdict) String() string {
|
func (v Verdict) String() string {
|
||||||
|
|
@ -33,6 +34,8 @@ func (v Verdict) String() string {
|
||||||
return "RerouteToNameserver"
|
return "RerouteToNameserver"
|
||||||
case VerdictRerouteToTunnel:
|
case VerdictRerouteToTunnel:
|
||||||
return "RerouteToTunnel"
|
return "RerouteToTunnel"
|
||||||
|
case VerdictRerouteToSplitTun:
|
||||||
|
return "RerouteToSplitTun"
|
||||||
case VerdictFailed:
|
case VerdictFailed:
|
||||||
return "Failed"
|
return "Failed"
|
||||||
default:
|
default:
|
||||||
|
|
@ -57,6 +60,8 @@ func (v Verdict) Verb() string {
|
||||||
return "redirected to nameserver"
|
return "redirected to nameserver"
|
||||||
case VerdictRerouteToTunnel:
|
case VerdictRerouteToTunnel:
|
||||||
return "tunneled"
|
return "tunneled"
|
||||||
|
case VerdictRerouteToSplitTun:
|
||||||
|
return "split tunneled"
|
||||||
case VerdictFailed:
|
case VerdictFailed:
|
||||||
return "failed"
|
return "failed"
|
||||||
default:
|
default:
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@ const (
|
||||||
VerdictRerouteToNameserver KextVerdict = 8
|
VerdictRerouteToNameserver KextVerdict = 8
|
||||||
VerdictRerouteToTunnel KextVerdict = 9
|
VerdictRerouteToTunnel KextVerdict = 9
|
||||||
VerdictFailed KextVerdict = 10
|
VerdictFailed KextVerdict = 10
|
||||||
|
VerdictRerouteToSplitTun KextVerdict = 11
|
||||||
)
|
)
|
||||||
|
|
||||||
type Verdict struct {
|
type Verdict struct {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue