Revamped verdict handling

This commit is contained in:
Patrick Pacher
2023-11-16 12:52:39 +01:00
parent f2839c274a
commit 923ce2aa24
13 changed files with 55 additions and 154 deletions

View File

@@ -139,8 +139,8 @@ func AddNetworkDebugData(di *debug.Info, profile, where string) {
debugConns []*Connection
accepted int
total int
transitioning int
)
for maybeConn := range it.Next {
// Switch to correct type.
conn, ok := maybeConn.(*Connection)
@@ -169,15 +169,13 @@ func AddNetworkDebugData(di *debug.Info, profile, where string) {
// Count.
total++
switch conn.Verdict.Firewall { //nolint:exhaustive
switch conn.Verdict { //nolint:exhaustive
case VerdictAccept,
VerdictRerouteToNameserver,
VerdictRerouteToTunnel:
accepted++
}
if conn.Verdict.Active != conn.Verdict.Firewall {
transitioning++
}
// Add to list.
debugConns = append(debugConns, conn)
@@ -186,10 +184,9 @@ func AddNetworkDebugData(di *debug.Info, profile, where string) {
// Add it all.
di.AddSection(
fmt.Sprintf(
"Network: %d/%d [~%d] Connections",
"Network: %d/%d Connections",
accepted,
total,
transitioning,
),
debug.UseCodeSection|debug.AddContentLineBreaks,
buildNetworkDebugInfoData(debugConns),

View File

@@ -40,15 +40,7 @@ var connectionTestData = []*Connection{
Country: "",
ASN: 0,
},
Verdict: struct {
Worst Verdict
Active Verdict
Firewall Verdict
}{
Worst: 2,
Active: 2,
Firewall: 2,
},
Verdict: 2,
Reason: Reason{
Msg: "incoming connection blocked by default",
OptionKey: "filter/serviceEndpoints",
@@ -88,15 +80,7 @@ var connectionTestData = []*Connection{
Country: "DE",
ASN: 16509,
},
Verdict: struct {
Worst Verdict
Active Verdict
Firewall Verdict
}{
Worst: 2,
Active: 2,
Firewall: 2,
},
Verdict: 2,
Reason: Reason{
Msg: "default permit",
OptionKey: "filter/defaultAction",
@@ -139,15 +123,7 @@ var connectionTestData = []*Connection{
Country: "US",
ASN: 15169,
},
Verdict: struct {
Worst Verdict
Active Verdict
Firewall Verdict
}{
Worst: 2,
Active: 2,
Firewall: 2,
},
Verdict: 2,
Reason: Reason{
Msg: "default permit",
OptionKey: "filter/defaultAction",

View File

@@ -121,17 +121,9 @@ type Connection struct { //nolint:maligned // TODO: fix alignment
// Verdict holds the decisions that are made for a connection
// The verdict may change so any access to it must be guarded by the
// connection lock.
Verdict struct {
// Worst verdict holds the worst verdict that was assigned to this
// connection from a privacy/security perspective.
Worst Verdict
// Active verdict holds the verdict that Portmaster will respond with.
// This is different from the Firewall verdict in order to guarantee proper
// transition between verdicts that need the connection to be re-established.
Active Verdict
// Firewall holds the last (most recent) decision by the firewall.
Firewall Verdict
}
Verdict Verdict
// Whether or not the connection has been established at least once.
ConnectionEstablished bool
// Reason holds information justifying the verdict, as well as additional
// information about the reason.
// Access to Reason must be guarded by the connection lock.
@@ -722,22 +714,15 @@ func (conn *Connection) SetVerdict(newVerdict Verdict, reason, reasonOptionKey s
return true // TODO: remove
}
// SetVerdictDirectly sets the firewall verdict.
// SetVerdictDirectly sets the verdict.
func (conn *Connection) SetVerdictDirectly(newVerdict Verdict) {
conn.Verdict.Firewall = newVerdict
conn.Verdict = newVerdict
}
// VerdictVerb returns the verdict as a verb, while taking any special states
// into account.
func (conn *Connection) VerdictVerb() string {
if conn.Verdict.Firewall == conn.Verdict.Active {
return conn.Verdict.Firewall.Verb()
}
return fmt.Sprintf(
"%s (transitioning to %s)",
conn.Verdict.Active.Verb(),
conn.Verdict.Firewall.Verb(),
)
return conn.Verdict.Verb()
}
// DataIsComplete returns whether all information about the connection is
@@ -766,6 +751,14 @@ func (conn *Connection) SaveWhenFinished() {
func (conn *Connection) Save() {
conn.UpdateMeta()
switch conn.Verdict {
case VerdictAccept, VerdictRerouteToNameserver:
conn.ConnectionEstablished = true
case VerdictRerouteToTunnel:
// this is already handled when the connection tunnel has been
// established.
}
// Do not save/update until data is complete.
if !conn.DataIsComplete() {
return
@@ -1003,7 +996,7 @@ func packetHandlerHandleConn(ctx context.Context, conn *Connection, pkt packet.P
switch {
case conn.DataIsComplete():
tracer.Infof("filter: connection %s %s: %s", conn, conn.VerdictVerb(), conn.Reason.Msg)
case conn.Verdict.Firewall != VerdictUndecided:
case conn.Verdict != VerdictUndecided:
tracer.Debugf("filter: connection %s fast-tracked", pkt)
default:
tracer.Debugf("filter: gathered data on connection %s", conn)

View File

@@ -208,7 +208,7 @@ func writeOpenDNSRequestsToDB() {
// ReplyWithDNS creates a new reply to the given request with the data from the RRCache, and additional informational records.
func (conn *Connection) ReplyWithDNS(ctx context.Context, request *dns.Msg) *dns.Msg {
// Select request responder.
switch conn.Verdict.Active {
switch conn.Verdict {
case VerdictBlock:
return nsutil.BlockIP().ReplyWithDNS(ctx, request)
case VerdictDrop:
@@ -229,7 +229,7 @@ func (conn *Connection) ReplyWithDNS(ctx context.Context, request *dns.Msg) *dns
func (conn *Connection) GetExtraRRs(ctx context.Context, request *dns.Msg) []dns.RR {
// Select level to add the verdict record with.
var level log.Severity
switch conn.Verdict.Active {
switch conn.Verdict {
case VerdictFailed:
level = log.ErrorLevel
case VerdictUndecided, VerdictUndeterminable,

View File

@@ -140,7 +140,7 @@ func (conn *Connection) addToMetrics() {
}
// Check the verdict.
switch conn.Verdict.Firewall { //nolint:exhaustive // Not critical.
switch conn.Verdict { //nolint:exhaustive // Not critical.
case VerdictBlock, VerdictDrop:
blockedOutConnCounter.Inc()
conn.addedToMetrics = true