diff --git a/firewall/dns.go b/firewall/dns.go index d8c4b582..ac4d4865 100644 --- a/firewall/dns.go +++ b/firewall/dns.go @@ -182,12 +182,12 @@ func FilterResolvedDNS( return rrCache } - // Only filter criticial things if request comes from the system resolver. + // Only filter critical things if request comes from the system resolver. sysResolver := conn.Process().IsSystemResolver() // Filter dns records and return if the query is blocked. rrCache = filterDNSResponse(ctx, conn, layeredProfile, rrCache, sysResolver) - if conn.Verdict == network.VerdictBlock { + if conn.Verdict.Current == network.VerdictBlock { return rrCache } diff --git a/firewall/inspection/inspection.go b/firewall/inspection/inspection.go index f42e4a30..dfe13d46 100644 --- a/firewall/inspection/inspection.go +++ b/firewall/inspection/inspection.go @@ -64,7 +64,7 @@ func RunInspectors(conn *network.Connection, pkt packet.Packet) (network.Verdict } // check if the current verdict is already past the inspection criteria. - if conn.Verdict > inspectVerdicts[key] { + if conn.Verdict.Current > inspectVerdicts[key] { activeInspectors[key] = true continue } @@ -86,11 +86,11 @@ func RunInspectors(conn *network.Connection, pkt packet.Packet) (network.Verdict continueInspection = true case BLOCK_CONN: conn.SetVerdict(network.VerdictBlock, "", "", nil) - verdict = conn.Verdict + verdict = conn.Verdict.Current activeInspectors[key] = true case DROP_CONN: conn.SetVerdict(network.VerdictDrop, "", "", nil) - verdict = conn.Verdict + verdict = conn.Verdict.Current activeInspectors[key] = true case STOP_INSPECTING: activeInspectors[key] = true diff --git a/firewall/interception.go b/firewall/interception.go index ec70e4a6..dc430fa5 100644 --- a/firewall/interception.go +++ b/firewall/interception.go @@ -44,18 +44,46 @@ var ( ownPID = os.Getpid() ) +const configChangeEvent = "config change" +const profileConfigChangeEvent = "profile config change" + func init() { // TODO: Move interception module to own package (dir). - interceptionModule = modules.Register("interception", interceptionPrep, interceptionStart, interceptionStop, "base", "updates", "network", "notifications") + interceptionModule = modules.Register("interception", interceptionPrep, interceptionStart, interceptionStop, "base", "updates", "network", "notifications", "profiles") network.SetDefaultFirewallHandler(defaultHandler) - captain.PreConnect = func(ctx context.Context) { - interception.CloseAllConnections() - } + + // setup event callback when spn has connected captain.ResetConnections = resetAllConnectionsVerdict } func interceptionPrep() error { + err := interceptionModule.RegisterEventHook( + "config", + configChangeEvent, + "firewall config change event", + func(ctx context.Context, _ interface{}) error { + resetAllConnections() + return nil + }, + ) + if err != nil { + _ = fmt.Errorf("failed registering event hook: %w", err) + } + + err = interceptionModule.RegisterEventHook( + "profiles", + profileConfigChangeEvent, + "firewall config change event", + func(ctx context.Context, _ interface{}) error { + resetAllConnections() + return nil + }, + ) + if err != nil { + _ = fmt.Errorf("failed registering event hook: %w", err) + } + if err := registerConfig(); err != nil { return err } @@ -63,6 +91,29 @@ func interceptionPrep() error { return prepAPIAuth() } +func resetAllConnections() { + log.Critical("Reseting all connections") + log.Info("interception: resetting all connections") + err := interception.DeleteAllConnections() + if err != nil { + log.Criticalf("failed to run ResetAllExternalConnections: %q", err) + } + for _, id := range network.GetAllIDs() { + conn, err := getConnectionByID(id) + if err != nil { + continue + } + + if !captain.IsExcepted(conn.Entity.IP) { + conn.SetFirewallHandler(initialHandler) + // Reset entity if it exists. + if conn.Entity != nil { + conn.Entity.ResetLists() + } + } + } +} + func interceptionStart() error { getConfig() @@ -168,10 +219,32 @@ func getConnection(pkt packet.Packet) (*network.Connection, error) { return conn, nil } +func getConnectionByID(id string) (*network.Connection, error) { + // Create or get connection in single inflight lock in order to prevent duplicates. + connPtr, _, _ := getConnectionSingleInflight.Do(id, func() (interface{}, error) { + // First, check for an existing connection. + conn, ok := network.GetConnection(id) + if ok { + return conn, nil + } + + // Else return nil + return nil, nil + }) + + if connPtr == nil { + return nil, errors.New("connection does not exist") + } + + connection := connPtr.(*network.Connection) + return connection, nil +} + func resetAllConnectionsVerdict(ctx context.Context) { + resetAllConnections() // interception.CloseAllConnections() - network.ClearConnections() - log.Critical("Clearing connections") + // network.ClearConnections() + // log.Critical("Clearing connections") // interception.CloseAllConnections() // ids := network.GetAllIDs() // for _, id := range ids { @@ -389,7 +462,7 @@ func initialHandler(conn *network.Connection, pkt packet.Packet) { conn.Entity.IPScope == netutils.LocalMulticast): // Reroute rogue dns queries back to Portmaster. - conn.Verdict = network.VerdictRerouteToNameserver + conn.SetVerdictDirectly(network.VerdictRerouteToNameserver) conn.Reason.Msg = "redirecting rogue dns query" conn.Internal = true // End directly, as no other processing is necessary. @@ -424,6 +497,8 @@ func initialHandler(conn *network.Connection, pkt packet.Packet) { // Check if connection should be tunneled. checkTunneling(pkt.Ctx(), conn, pkt) + updateVerdictBasedOnPreviousState(conn, pkt) + switch { case conn.Inspecting: log.Tracer(pkt.Ctx()).Trace("filter: start inspecting") @@ -462,8 +537,8 @@ func issueVerdict(conn *network.Connection, pkt packet.Packet, verdict network.V } // do not allow to circumvent decision: e.g. to ACCEPT packets from a DROP-ed connection - if verdict < conn.Verdict { - verdict = conn.Verdict + if verdict < conn.Verdict.Current { + verdict = conn.Verdict.Current } var err error @@ -509,6 +584,18 @@ func issueVerdict(conn *network.Connection, pkt packet.Packet, verdict network.V } } +func updateVerdictBasedOnPreviousState(conn *network.Connection, pkt packet.Packet) { + if conn.Verdict.Current == network.VerdictAccept { + if conn.Verdict.Previous == network.VerdictRerouteToTunnel && !conn.Tunneled { + conn.SetVerdictDirectly(network.VerdictBlock) + } else if conn.Verdict.Previous == network.VerdictAccept && conn.Tunneled { + conn.SetVerdictDirectly(network.VerdictBlock) + } else if conn.Tunneled { + conn.SetVerdictDirectly(network.VerdictRerouteToTunnel) + } + } +} + // func tunnelHandler(pkt packet.Packet) { // tunnelInfo := GetTunnelInfo(pkt.Info().Dst) // if tunnelInfo == nil { diff --git a/firewall/interception/connection_manager_linux.go b/firewall/interception/connection_manager_linux.go new file mode 100644 index 00000000..8f3b46fd --- /dev/null +++ b/firewall/interception/connection_manager_linux.go @@ -0,0 +1,95 @@ +package interception + +import ( + "encoding/binary" + "fmt" + "net" + + ct "github.com/florianl/go-conntrack" + + "github.com/safing/portbase/log" + "github.com/safing/portmaster/firewall/interception/nfq" +) + +// CloseAllConnections closes all active connection on conntrack. +func CloseAllConnections() error { + nfct, err := ct.Open(&ct.Config{}) + if err != nil { + return err + } + defer func() { _ = nfct.Close() }() + + connections, err := nfct.Dump(ct.Conntrack, ct.IPv4) + if err != nil { + return err + } + log.Criticalf("Number of connections: %d", len(connections)) + for _, connection := range connections { + fmt.Printf("[%2d] %s - %s\n", connection.Origin.Proto.Number, connection.Origin.Src, connection.Origin.Dst) + err := nfct.Delete(ct.Conntrack, ct.IPv4, connection) + log.Errorf("Error deleting connection %q", err) + } + + return nil +} + +// DeleteAllConnections deletes all entries from conntrack table. +func DeleteAllConnections() error { + nfct, err := ct.Open(&ct.Config{}) + if err != nil { + return err + } + defer func() { _ = nfct.Close() }() + + connections, err := getAllPermanentConnections(nfct) + + for _, connection := range connections { + _ = nfct.Delete(ct.Conntrack, ct.IPv4, connection) + } + + return err +} + +// DeleteConnection deletes a specific connection. +func DeleteConnection(sourceIP net.IP, sourcePort uint16, destinationIP net.IP, destinationPort uint16) error { + nfct, err := ct.Open(&ct.Config{}) + if err != nil { + return err + } + defer func() { _ = nfct.Close() }() + + filter := &ct.IPTuple{Src: &sourceIP, Dst: &destinationIP, Proto: &ct.ProtoTuple{SrcPort: &sourcePort, DstPort: &destinationPort}} + connectionFilter := ct.Con{ + Origin: filter, + } + + connections, _ := nfct.Get(ct.Conntrack, ct.IPv4, connectionFilter) + for _, connection := range connections { + _ = nfct.Delete(ct.Conntrack, ct.IPv4, connection) + } + + connectionFilter.Origin = nil + connectionFilter.Reply = filter + connections, err = nfct.Get(ct.Conntrack, ct.IPv4, connectionFilter) + for _, connection := range connections { + _ = nfct.Delete(ct.Conntrack, ct.IPv4, connection) + } + return err +} + +func getAllPermanentConnections(nfct *ct.Nfct) ([]ct.Con, error) { + permanentFlags := []uint32{nfq.MarkAccept, nfq.MarkBlock, nfq.MarkDrop, nfq.MarkAcceptAlways, nfq.MarkBlockAlways, nfq.MarkDropAlways, nfq.MarkRerouteSPN} + filter := ct.FilterAttr{} + filter.MarkMask = []byte{0xFF, 0xFF, 0xFF, 0xFF} + filter.Mark = []byte{0x00, 0x00, 0x00, 0x00} // 4 zeros starting value + connections := make([]ct.Con, 0) + for _, mark := range permanentFlags { + binary.BigEndian.PutUint32(filter.Mark, mark) // Little endian is in reverse not sure why. BigEndian makes it in correct order. + currentConnections, err := nfct.Query(ct.Conntrack, ct.IPv4, filter) + if err != nil { + return nil, err + } + connections = append(connections, currentConnections...) + } + return connections, nil +} diff --git a/firewall/interception/interception.go b/firewall/interception/interception.go index a50f57a1..f3cbd5c5 100644 --- a/firewall/interception/interception.go +++ b/firewall/interception/interception.go @@ -2,9 +2,6 @@ package interception import ( "flag" - "fmt" - - ct "github.com/florianl/go-conntrack" "github.com/safing/portbase/log" "github.com/safing/portmaster/network/packet" @@ -52,24 +49,3 @@ func Stop() error { return stop() } - -func CloseAllConnections() error { - nfct, err := ct.Open(&ct.Config{}) - if err != nil { - return err - } - defer func() { _ = nfct.Close() }() - - connections, err := nfct.Dump(ct.Conntrack, ct.IPv4) - if err != nil { - return err - } - log.Criticalf("Number of connections: %d", len(connections)) - for _, connection := range connections { - fmt.Printf("[%2d] %s - %s\n", connection.Origin.Proto.Number, connection.Origin.Src, connection.Origin.Dst) - err := nfct.Delete(ct.Conntrack, ct.IPv4, connection) - log.Errorf("Error deleting connection %q", err) - } - - return nil -} diff --git a/firewall/master.go b/firewall/master.go index fdcddd9f..20da6cc5 100644 --- a/firewall/master.go +++ b/firewall/master.go @@ -76,7 +76,7 @@ func DecideOnConnection(ctx context.Context, conn *network.Connection, pkt packe // Reset verdict for connection. log.Tracer(ctx).Infof("filter: re-evaluating verdict on %s", conn) - conn.Verdict = network.VerdictUndecided + // conn.SetVerdictDirectly(network.VerdictUndecided) // Reset entity if it exists. if conn.Entity != nil { diff --git a/firewall/tunnel.go b/firewall/tunnel.go index 694dfe5f..6c4c878f 100644 --- a/firewall/tunnel.go +++ b/firewall/tunnel.go @@ -28,7 +28,7 @@ func checkTunneling(ctx context.Context, conn *network.Connection, pkt packet.Pa case conn.Inbound: // Can't tunnel incoming connections. return - case conn.Verdict != network.VerdictAccept: + case conn.Verdict.Current != network.VerdictAccept: // Connection will be blocked. return case conn.Process().Pid == ownPID: @@ -156,7 +156,7 @@ func checkTunneling(ctx context.Context, conn *network.Connection, pkt packet.Pa conn.Failed("failed to request tunneling", "") } else { //log.Tracer(pkt.Ctx()).Trace("filter: tunneling requested") - conn.Verdict = network.VerdictRerouteToTunnel + //conn.SetVerdictDirectly(network.VerdictRerouteToTunnel) conn.Tunneled = true } } diff --git a/nameserver/nameserver.go b/nameserver/nameserver.go index f866eb47..81a36b91 100644 --- a/nameserver/nameserver.go +++ b/nameserver/nameserver.go @@ -189,7 +189,7 @@ func handleRequest(ctx context.Context, w dns.ResponseWriter, request *dns.Msg) conn.Resolver = rrCache.Resolver } - switch conn.Verdict { + switch conn.Verdict.Current { // 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: @@ -235,11 +235,11 @@ func handleRequest(ctx context.Context, w dns.ResponseWriter, request *dns.Msg) } // Check if there is a Verdict to act upon. - switch conn.Verdict { //nolint:exhaustive // Only checking for specific values. + switch conn.Verdict.Current { //nolint:exhaustive // Only checking for specific values. case network.VerdictBlock, network.VerdictDrop, network.VerdictFailed: tracer.Infof( "nameserver: returning %s response for %s to %s", - conn.Verdict.Verb(), + conn.Verdict.Current.Verb(), q.ID(), conn.Process(), ) @@ -315,11 +315,11 @@ func handleRequest(ctx context.Context, w dns.ResponseWriter, request *dns.Msg) } // Check if there is a Verdict to act upon. - switch conn.Verdict { //nolint:exhaustive // Only checking for specific values. + switch conn.Verdict.Current { //nolint:exhaustive // Only checking for specific values. case network.VerdictBlock, network.VerdictDrop, network.VerdictFailed: tracer.Infof( "nameserver: returning %s response for %s to %s", - conn.Verdict.Verb(), + conn.Verdict.Current.Verb(), q.ID(), conn.Process(), ) @@ -338,7 +338,7 @@ func handleRequest(ctx context.Context, w dns.ResponseWriter, request *dns.Msg) } tracer.Infof( "nameserver: returning %s response (%s%s) for %s to %s", - conn.Verdict.Verb(), + conn.Verdict.Current.Verb(), dns.RcodeToString[rrCache.RCode], noAnswerIndicator, q.ID(), diff --git a/netquery/manager.go b/netquery/manager.go index 8bd1e5cd..2c9e9fe2 100644 --- a/netquery/manager.go +++ b/netquery/manager.go @@ -155,7 +155,7 @@ func convertConnection(conn *network.Connection) (*Conn, error) { IPProtocol: conn.IPProtocol, LocalIP: conn.LocalIP.String(), LocalPort: conn.LocalPort, - Verdict: conn.Verdict, + Verdict: conn.Verdict.User, Started: time.Unix(conn.Started, 0), Tunneled: conn.Tunneled, Encrypted: conn.Encrypted, @@ -177,7 +177,7 @@ func convertConnection(conn *network.Connection) (*Conn, error) { c.Type = "" } - switch conn.Verdict { + switch conn.Verdict.User { case network.VerdictAccept, network.VerdictRerouteToNameserver, network.VerdictRerouteToTunnel: accepted := true c.Allowed = &accepted diff --git a/network/api.go b/network/api.go index 21fda11e..00b8ed9c 100644 --- a/network/api.go +++ b/network/api.go @@ -152,7 +152,7 @@ func AddNetworkDebugData(di *debug.Info, profile, where string) { // Count. total++ - switch conn.Verdict { //nolint:exhaustive + switch conn.Verdict.Current { //nolint:exhaustive case VerdictAccept, VerdictRerouteToNameserver, VerdictRerouteToTunnel: @@ -232,7 +232,7 @@ func (conn *Connection) debugInfoLine() string { return fmt.Sprintf( "% 14s %s%- 25s %s-%s P#%d [%s] %s - by %s @ %s", - conn.Verdict.Verb(), + conn.Verdict.Current.Verb(), connectionData, conn.fmtDomainComponent(), time.Unix(conn.Started, 0).Format("15:04:05"), diff --git a/network/api_test.go b/network/api_test.go index a595e854..0d37f022 100644 --- a/network/api_test.go +++ b/network/api_test.go @@ -40,7 +40,15 @@ var connectionTestData = []*Connection{ Country: "", ASN: 0, }, - Verdict: 4, + Verdict: struct { + Current Verdict + Previous Verdict + User Verdict + }{ + Current: 2, + Previous: 2, + User: 2, + }, Reason: Reason{ Msg: "incoming connection blocked by default", OptionKey: "filter/serviceEndpoints", @@ -80,7 +88,15 @@ var connectionTestData = []*Connection{ Country: "DE", ASN: 16509, }, - Verdict: 2, + Verdict: struct { + Current Verdict + Previous Verdict + User Verdict + }{ + Current: 2, + Previous: 2, + User: 2, + }, Reason: Reason{ Msg: "default permit", OptionKey: "filter/defaultAction", @@ -123,7 +139,15 @@ var connectionTestData = []*Connection{ Country: "US", ASN: 15169, }, - Verdict: 2, + Verdict: struct { + Current Verdict + Previous Verdict + User Verdict + }{ + Current: 2, + Previous: 2, + User: 2, + }, Reason: Reason{ Msg: "default permit", OptionKey: "filter/defaultAction", diff --git a/network/connection.go b/network/connection.go index cdcefed2..c774e52a 100644 --- a/network/connection.go +++ b/network/connection.go @@ -107,16 +107,23 @@ type Connection struct { //nolint:maligned // TODO: fix alignment // Resolver holds information about the resolver used to resolve // Entity.Domain. Resolver *resolver.ResolverInfo - // Verdict is the final decision that has been made for a connection. + // Verdict holds decisions that are made for a connection // The verdict may change so any access to it must be guarded by the // connection lock. - Verdict Verdict + Verdict struct { + // Current is the current decision that has been made for a connection. + Current Verdict + // PreviousVerdict holds the previous verdict value, if there wasn't previous it will hold VerdictUndecided + Previous Verdict + // UserVerdict holds the verdict that should be displayed in the user interface + User Verdict + } // Reason holds information justifying the verdict, as well as additional // information about the reason. // Access to Reason must be guarded by the connection lock. Reason Reason // Started holds the number of seconds in UNIX epoch time at which - // the connection has been initated and first seen by the portmaster. + // the connection has been initiated and first seen by the portmaster. // Started is only ever set when creating a new connection object // and is considered immutable afterwards. Started int64 @@ -142,7 +149,7 @@ type Connection struct { //nolint:maligned // TODO: fix alignment // TunnelOpts holds options for tunneling the connection. TunnelOpts *navigator.Options // ProcessContext holds additional information about the process - // that iniated the connection. It is set once when the connection + // that initiated the connection. It is set once when the connection // object is created and is considered immutable afterwards. ProcessContext ProcessContext // DNSContext holds additional information about the DNS request that was @@ -159,7 +166,7 @@ type Connection struct { //nolint:maligned // TODO: fix alignment // points and access to it must be guarded by the connection lock. Internal bool // process holds a reference to the actor process. That is, the - // process instance that initated the connection. + // process instance that initiated the connection. process *process.Process // pkgQueue is used to serialize packet handling for a single // connection and is served by the connections packetHandler. @@ -167,7 +174,7 @@ type Connection struct { //nolint:maligned // TODO: fix alignment // firewallHandler is the firewall handler that is called for // each packet sent to pktQueue. firewallHandler FirewallHandler - // saveWhenFinished can be set to drue during the life-time of + // saveWhenFinished can be set to true during the life-time of // a connection and signals the firewallHandler that a Save() // should be issued after processing the connection. saveWhenFinished bool @@ -519,8 +526,11 @@ func (conn *Connection) Failed(reason, reasonOptionKey string) { conn.FailedWithContext(reason, reasonOptionKey, nil) } +// Reset resets all values of the connection. func (conn *Connection) Reset(reason, reasonOptionKey string) { - conn.Verdict = VerdictUndecided + conn.Verdict.Current = VerdictUndecided + conn.Verdict.Previous = VerdictUndecided + conn.Verdict.User = VerdictUndecided conn.Reason.Msg = reason conn.Reason.Context = nil @@ -534,21 +544,37 @@ func (conn *Connection) Reset(reason, reasonOptionKey string) { // SetVerdict sets a new verdict for the connection, making sure it does not interfere with previous verdicts. func (conn *Connection) SetVerdict(newVerdict Verdict, reason, reasonOptionKey string, reasonCtx interface{}) (ok bool) { - if newVerdict >= conn.Verdict { - conn.Verdict = newVerdict - conn.Reason.Msg = reason - conn.Reason.Context = reasonCtx + // if newVerdict >= conn.Verdict.Current { + conn.SetVerdictDirectly(newVerdict) - conn.Reason.OptionKey = "" - conn.Reason.Profile = "" - if reasonOptionKey != "" && conn.Process() != nil { - conn.Reason.OptionKey = reasonOptionKey - conn.Reason.Profile = conn.Process().Profile().GetProfileSource(conn.Reason.OptionKey) - } + conn.Reason.Msg = reason + conn.Reason.Context = reasonCtx - return true + conn.Reason.OptionKey = "" + conn.Reason.Profile = "" + if reasonOptionKey != "" && conn.Process() != nil { + conn.Reason.OptionKey = reasonOptionKey + conn.Reason.Profile = conn.Process().Profile().GetProfileSource(conn.Reason.OptionKey) + } + + return true + // } + // return false +} + +// SetVerdictDirectly sets the new verdict and stores the previous value. +func (conn *Connection) SetVerdictDirectly(newVerdict Verdict) { + if newVerdict == conn.Verdict.Current { + return + } + // Save previous verdict and set new one + conn.Verdict.Previous = conn.Verdict.Current + conn.Verdict.Current = newVerdict + + // if a connection is accepted once it should always show as accepted + if conn.Verdict.User != VerdictAccept { + conn.Verdict.User = newVerdict } - return false } // Process returns the connection's process. @@ -675,7 +701,7 @@ func packetHandlerHandleConn(conn *Connection, pkt packet.Packet) { } // Log verdict. - log.Tracer(pkt.Ctx()).Infof("filter: connection %s %s: %s", conn, conn.Verdict.Verb(), conn.Reason.Msg) + log.Tracer(pkt.Ctx()).Infof("filter: connection %s %s: %s", conn, conn.Verdict.Current.Verb(), conn.Reason.Msg) // Submit trace logs. log.Tracer(pkt.Ctx()).Submit() diff --git a/network/dns.go b/network/dns.go index 6a4958c8..6638b5e8 100644 --- a/network/dns.go +++ b/network/dns.go @@ -115,7 +115,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 { + switch conn.Verdict.Current { case VerdictBlock: return nsutil.BlockIP().ReplyWithDNS(ctx, request) case VerdictDrop: @@ -136,7 +136,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 { + switch conn.Verdict.Current { case VerdictFailed: level = log.ErrorLevel case VerdictUndecided, VerdictUndeterminable, @@ -148,7 +148,7 @@ func (conn *Connection) GetExtraRRs(ctx context.Context, request *dns.Msg) []dns } // Create resource record with verdict and reason. - rr, err := nsutil.MakeMessageRecord(level, fmt.Sprintf("%s: %s", conn.Verdict.Verb(), conn.Reason.Msg)) + rr, err := nsutil.MakeMessageRecord(level, fmt.Sprintf("%s: %s", conn.Verdict.Current.Verb(), conn.Reason.Msg)) if err != nil { log.Tracer(ctx).Warningf("filter: failed to add informational record to reply: %s", err) return nil diff --git a/network/metrics.go b/network/metrics.go index 7867cea4..8729b509 100644 --- a/network/metrics.go +++ b/network/metrics.go @@ -119,7 +119,7 @@ func (conn *Connection) addToMetrics() { } // Check the verdict. - switch conn.Verdict { //nolint:exhaustive // Not critical. + switch conn.Verdict.Current { //nolint:exhaustive // Not critical. case VerdictBlock, VerdictDrop: blockedOutConnCounter.Inc() conn.addedToMetrics = true diff --git a/network/packet/packet.go b/network/packet/packet.go index 78ae237c..294a79c2 100644 --- a/network/packet/packet.go +++ b/network/packet/packet.go @@ -224,7 +224,7 @@ func (pkt *Base) FmtRemoteAddress() string { return fmt.Sprintf("%s:%s:%s", pkt.info.Protocol.String(), pkt.FmtRemoteIP(), pkt.FmtRemotePort()) } -// Packet is an interface to a network packet to provide object behaviour the same across all systems. +// Packet is an interface to a network packet to provide object behavior the same across all systems. type Packet interface { // Verdicts. Accept() error diff --git a/profile/database.go b/profile/database.go index 53be3405..2438d667 100644 --- a/profile/database.go +++ b/profile/database.go @@ -91,6 +91,7 @@ func startProfileUpdateChecker() error { if err == nil { newProfile.layeredProfile.Update() } + module.TriggerEvent(profileConfigChange, nil) } // Always increase the revision counter of the layer profile. @@ -104,6 +105,7 @@ func startProfileUpdateChecker() error { receivedProfile, err := EnsureProfile(r) if err != nil || !receivedProfile.savedInternally { activeProfile.outdated.Set() + module.TriggerEvent(profileConfigChange, nil) } case <-ctx.Done(): return nil diff --git a/profile/module.go b/profile/module.go index 31b52704..7a5fbef4 100644 --- a/profile/module.go +++ b/profile/module.go @@ -16,8 +16,13 @@ var ( updatesPath string ) +const ( + profileConfigChange = "profile config change" +) + func init() { module = modules.Register("profiles", prep, start, nil, "base", "updates") + module.RegisterEvent(profileConfigChange, true) } func prep() error { diff --git a/profile/profile.go b/profile/profile.go index bf0d3017..62d7da3f 100644 --- a/profile/profile.go +++ b/profile/profile.go @@ -322,15 +322,15 @@ func (profile *Profile) GetServiceEndpoints() endpoints.Endpoints { // AddEndpoint adds an endpoint to the endpoint list, saves the profile and reloads the configuration. func (profile *Profile) AddEndpoint(newEntry string) { - profile.addEndpointyEntry(CfgOptionEndpointsKey, newEntry) + profile.addEndpointEntry(CfgOptionEndpointsKey, newEntry) } // AddServiceEndpoint adds a service endpoint to the endpoint list, saves the profile and reloads the configuration. func (profile *Profile) AddServiceEndpoint(newEntry string) { - profile.addEndpointyEntry(CfgOptionServiceEndpointsKey, newEntry) + profile.addEndpointEntry(CfgOptionServiceEndpointsKey, newEntry) } -func (profile *Profile) addEndpointyEntry(cfgKey, newEntry string) { +func (profile *Profile) addEndpointEntry(cfgKey, newEntry string) { changed := false // When finished, save the profile. @@ -365,7 +365,7 @@ func (profile *Profile) addEndpointyEntry(cfgKey, newEntry string) { if entry == newEntry { // An identical entry is already in the list, abort. - log.Debugf("profile: ingoring new endpoint rule for %s, as identical is already present: %s", profile, newEntry) + log.Debugf("profile: ignoring new endpoint rule for %s, as identical is already present: %s", profile, newEntry) return } }