Revamped verdict handling
This commit is contained in:
@@ -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),
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user