Add support for verdict and decision reason context

This commit is contained in:
Patrick Pacher
2020-04-20 17:19:48 +02:00
parent eeb358425d
commit 8c5526a69b
17 changed files with 246 additions and 148 deletions

View File

@@ -31,9 +31,10 @@ type Connection struct { //nolint:maligned // TODO: fix alignment
Entity *intel.Entity // needs locking, instance is never shared
process *process.Process
Verdict Verdict
Reason string
ReasonID string // format source[:id[:id]] // TODO
Verdict Verdict
Reason string
ReasonContext interface{}
ReasonID string // format source[:id[:id]] // TODO
Started int64
Ended int64
@@ -164,59 +165,82 @@ func GetConnection(id string) (*Connection, bool) {
return conn, ok
}
// Accept accepts the connection.
func (conn *Connection) Accept(reason string) {
if conn.SetVerdict(VerdictAccept) {
conn.Reason = reason
// AcceptWithContext accepts the connection.
func (conn *Connection) AcceptWithContext(reason string, ctx interface{}) {
if conn.SetVerdict(VerdictAccept, reason, ctx) {
log.Infof("filter: granting connection %s, %s", conn, conn.Reason)
} else {
log.Warningf("filter: tried to accept %s, but current verdict is %s", conn, conn.Verdict)
}
}
// Block blocks the connection.
func (conn *Connection) Block(reason string) {
if conn.SetVerdict(VerdictBlock) {
conn.Reason = reason
// Accept is like AcceptWithContext but only accepts a reason.
func (conn *Connection) Accept(reason string) {
conn.AcceptWithContext(reason, nil)
}
// BlockWithContext blocks the connection.
func (conn *Connection) BlockWithContext(reason string, ctx interface{}) {
if conn.SetVerdict(VerdictBlock, reason, ctx) {
log.Infof("filter: blocking connection %s, %s", conn, conn.Reason)
} else {
log.Warningf("filter: tried to block %s, but current verdict is %s", conn, conn.Verdict)
}
}
// Drop drops the connection.
func (conn *Connection) Drop(reason string) {
if conn.SetVerdict(VerdictDrop) {
conn.Reason = reason
// Block is like BlockWithContext but does only accepts a reason.
func (conn *Connection) Block(reason string) {
conn.BlockWithContext(reason, nil)
}
// DropWithContext drops the connection.
func (conn *Connection) DropWithContext(reason string, ctx interface{}) {
if conn.SetVerdict(VerdictDrop, reason, ctx) {
log.Infof("filter: dropping connection %s, %s", conn, conn.Reason)
} else {
log.Warningf("filter: tried to drop %s, but current verdict is %s", conn, conn.Verdict)
}
}
// Deny blocks or drops the link depending on the connection direction.
func (conn *Connection) Deny(reason string) {
// Drop is like DropWithContext but does only accepts a reason.
func (conn *Connection) Drop(reason string) {
conn.DropWithContext(reason, nil)
}
// DenyWithContext blocks or drops the link depending on the connection direction.
func (conn *Connection) DenyWithContext(reason string, ctx interface{}) {
if conn.Inbound {
conn.Drop(reason)
conn.DropWithContext(reason, ctx)
} else {
conn.Block(reason)
conn.BlockWithContext(reason, ctx)
}
}
// Failed marks the connection with VerdictFailed and stores the reason.
func (conn *Connection) Failed(reason string) {
if conn.SetVerdict(VerdictFailed) {
conn.Reason = reason
// Deny is like DenyWithContext but only accepts a reason.
func (conn *Connection) Deny(reason string) {
conn.DenyWithContext(reason, nil)
}
// FailedWithContext marks the connection with VerdictFailed and stores the reason.
func (conn *Connection) FailedWithContext(reason string, ctx interface{}) {
if conn.SetVerdict(VerdictFailed, reason, ctx) {
log.Infof("filter: dropping connection %s because of an internal error: %s", conn, reason)
} else {
log.Warningf("filter: tried to drop %s due to error but current verdict is %s", conn, conn.Verdict)
}
}
// Failed is like FailedWithContext but only accepts a string.
func (conn *Connection) Failed(reason string) {
conn.FailedWithContext(reason, nil)
}
// SetVerdict sets a new verdict for the connection, making sure it does not interfere with previous verdicts.
func (conn *Connection) SetVerdict(newVerdict Verdict) (ok bool) {
func (conn *Connection) SetVerdict(newVerdict Verdict, reason string, ctx interface{}) (ok bool) {
if newVerdict >= conn.Verdict {
conn.Verdict = newVerdict
conn.Reason = reason
conn.ReasonContext = ctx
return true
}
return false