mirror of
https://github.com/safing/portmaster
synced 2026-04-26 10:31:36 +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.RerouteToNs:
|
||||
case Verdict.RerouteToTunnel:
|
||||
case Verdict.RerouteToSplitTun:
|
||||
case Verdict.Undeterminable:
|
||||
stats.size += res.totalCount
|
||||
stats.countAllowed += res.totalCount;
|
||||
|
|
|
|||
|
|
@ -8,7 +8,8 @@ export enum Verdict {
|
|||
Drop = 4,
|
||||
RerouteToNs = 5,
|
||||
RerouteToTunnel = 6,
|
||||
Failed = 7
|
||||
Failed = 7,
|
||||
RerouteToSplitTun = 8
|
||||
}
|
||||
|
||||
export enum IPProtocol {
|
||||
|
|
|
|||
|
|
@ -1206,7 +1206,8 @@ export class SfngNetqueryViewer implements OnInit, OnDestroy, AfterViewInit {
|
|||
$in: [
|
||||
Verdict.Accept,
|
||||
Verdict.RerouteToNs,
|
||||
Verdict.RerouteToTunnel
|
||||
Verdict.RerouteToTunnel,
|
||||
Verdict.RerouteToSplitTun
|
||||
],
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -28,7 +28,8 @@ span.verdict {
|
|||
|
||||
&.accept,
|
||||
&.reroutetons,
|
||||
&.reroutetotunnel {
|
||||
&.reroutetotunnel,
|
||||
&.reroutetosplittun {
|
||||
--bg-color: theme('colors.info.green');
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -65,3 +65,8 @@ func (p *tracedPacket) RerouteToTunnel() error {
|
|||
defer p.markServed("reroute-tunnel")
|
||||
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
|
||||
}
|
||||
|
||||
// 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
|
||||
case network.VerdictRerouteToTunnel:
|
||||
return kextinterface.VerdictRerouteToTunnel
|
||||
case network.VerdictRerouteToSplitTun:
|
||||
return kextinterface.VerdictRerouteToSplitTun
|
||||
case network.VerdictFailed:
|
||||
return kextinterface.VerdictFailed
|
||||
}
|
||||
|
|
|
|||
|
|
@ -140,3 +140,11 @@ func (pkt *Packet) RerouteToTunnel() error {
|
|||
}
|
||||
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()
|
||||
case network.VerdictRerouteToTunnel:
|
||||
err = pkt.RerouteToTunnel()
|
||||
case network.VerdictRerouteToSplitTun:
|
||||
err = pkt.RerouteToSplitTun()
|
||||
case network.VerdictFailed:
|
||||
atomic.AddUint64(packetsFailed, 1)
|
||||
err = pkt.Drop()
|
||||
|
|
|
|||
|
|
@ -205,7 +205,8 @@ func handleRequest(ctx context.Context, w dns.ResponseWriter, request *dns.Msg)
|
|||
switch conn.Verdict {
|
||||
// We immediately save blocked, dropped or failed verdicts so
|
||||
// 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()
|
||||
|
||||
// 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
|
||||
case VerdictAccept,
|
||||
VerdictRerouteToNameserver,
|
||||
VerdictRerouteToSplitTun,
|
||||
VerdictRerouteToTunnel:
|
||||
|
||||
accepted++
|
||||
|
|
|
|||
|
|
@ -795,7 +795,7 @@ func (conn *Connection) Save() {
|
|||
|
||||
// nolint:exhaustive
|
||||
switch conn.Verdict {
|
||||
case VerdictAccept, VerdictRerouteToNameserver:
|
||||
case VerdictAccept, VerdictRerouteToNameserver, VerdictRerouteToSplitTun:
|
||||
conn.ConnectionEstablished = true
|
||||
case VerdictRerouteToTunnel:
|
||||
// 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.
|
||||
case VerdictFailed:
|
||||
return nsutil.BlockIP().ReplyWithDNS(ctx, request)
|
||||
case VerdictUndecided, VerdictUndeterminable,
|
||||
VerdictAccept, VerdictRerouteToNameserver, VerdictRerouteToTunnel:
|
||||
fallthrough
|
||||
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)
|
||||
nsutil.AddMessagesToReply(ctx, reply, log.ErrorLevel, "INTERNAL ERROR: incorrect use of Connection DNS Responder")
|
||||
return reply
|
||||
|
|
@ -233,10 +233,6 @@ func (conn *Connection) GetExtraRRs(ctx context.Context, request *dns.Msg) []dns
|
|||
switch conn.Verdict {
|
||||
case VerdictFailed:
|
||||
level = log.ErrorLevel
|
||||
case VerdictUndecided, VerdictUndeterminable,
|
||||
VerdictAccept, VerdictBlock, VerdictDrop,
|
||||
VerdictRerouteToNameserver, VerdictRerouteToTunnel:
|
||||
fallthrough
|
||||
default:
|
||||
level = log.InfoLevel
|
||||
}
|
||||
|
|
|
|||
|
|
@ -145,7 +145,7 @@ func (conn *Connection) addToMetrics() {
|
|||
blockedOutConnCounter.Inc()
|
||||
conn.addedToMetrics = true
|
||||
return
|
||||
case VerdictAccept, VerdictRerouteToTunnel:
|
||||
case VerdictAccept, VerdictRerouteToTunnel, VerdictRerouteToSplitTun:
|
||||
// Continue to next section.
|
||||
default:
|
||||
// Connection is not counted.
|
||||
|
|
|
|||
|
|
@ -74,4 +74,8 @@ func (pkt *InfoPacket) RerouteToTunnel() error {
|
|||
return ErrInfoOnlyPacket
|
||||
}
|
||||
|
||||
func (pkt *InfoPacket) RerouteToSplitTun() error {
|
||||
return ErrInfoOnlyPacket
|
||||
}
|
||||
|
||||
var _ Packet = &InfoPacket{}
|
||||
|
|
|
|||
|
|
@ -231,6 +231,7 @@ type Packet interface {
|
|||
PermanentDrop() error
|
||||
RerouteToNameserver() error
|
||||
RerouteToTunnel() error
|
||||
RerouteToSplitTun() error
|
||||
FastTrackedByIntegration() bool
|
||||
InfoOnly() bool
|
||||
ExpectInfo() bool
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ const (
|
|||
VerdictRerouteToNameserver Verdict = 5
|
||||
VerdictRerouteToTunnel Verdict = 6
|
||||
VerdictFailed Verdict = 7
|
||||
VerdictRerouteToSplitTun Verdict = 8
|
||||
)
|
||||
|
||||
func (v Verdict) String() string {
|
||||
|
|
@ -33,6 +34,8 @@ func (v Verdict) String() string {
|
|||
return "RerouteToNameserver"
|
||||
case VerdictRerouteToTunnel:
|
||||
return "RerouteToTunnel"
|
||||
case VerdictRerouteToSplitTun:
|
||||
return "RerouteToSplitTun"
|
||||
case VerdictFailed:
|
||||
return "Failed"
|
||||
default:
|
||||
|
|
@ -57,6 +60,8 @@ func (v Verdict) Verb() string {
|
|||
return "redirected to nameserver"
|
||||
case VerdictRerouteToTunnel:
|
||||
return "tunneled"
|
||||
case VerdictRerouteToSplitTun:
|
||||
return "split tunneled"
|
||||
case VerdictFailed:
|
||||
return "failed"
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ const (
|
|||
VerdictRerouteToNameserver KextVerdict = 8
|
||||
VerdictRerouteToTunnel KextVerdict = 9
|
||||
VerdictFailed KextVerdict = 10
|
||||
VerdictRerouteToSplitTun KextVerdict = 11
|
||||
)
|
||||
|
||||
type Verdict struct {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue