7a3f6e945d
Refactors TCP and UDP flow managers to enhance analyzer selection and flow binding accuracy, including O(1) UDP stream rebinding by 5-tuple. Introduces runtime stats tracking for engine and ruleset operations, exposing new APIs for granular performance and error metrics. Optimizes GeoMatcher with result caching and supports efficient geosite set matching, reducing redundant computation in ruleset expressions.
133 lines
3.1 KiB
Go
133 lines
3.1 KiB
Go
package ruleset
|
|
|
|
import (
|
|
"context"
|
|
"net"
|
|
"strconv"
|
|
"sync/atomic"
|
|
|
|
"git.difuse.io/Difuse/Mellaris/analyzer"
|
|
"git.difuse.io/Difuse/Mellaris/modifier"
|
|
)
|
|
|
|
type Action int
|
|
|
|
const (
|
|
// ActionMaybe indicates that the ruleset hasn't seen anything worth blocking based on
|
|
// current information, but that may change if volatile fields change in the future.
|
|
ActionMaybe Action = iota
|
|
// ActionAllow indicates that the stream should be allowed regardless of future changes.
|
|
ActionAllow
|
|
// ActionBlock indicates that the stream should be blocked.
|
|
ActionBlock
|
|
// ActionDrop indicates that the current packet should be dropped,
|
|
// but the stream should be allowed to continue.
|
|
// Only valid for UDP streams. Equivalent to ActionBlock for TCP streams.
|
|
ActionDrop
|
|
// ActionModify indicates that the current packet should be modified,
|
|
// and the stream should be allowed to continue.
|
|
// Only valid for UDP streams. Equivalent to ActionMaybe for TCP streams.
|
|
ActionModify
|
|
)
|
|
|
|
func (a Action) String() string {
|
|
switch a {
|
|
case ActionMaybe:
|
|
return "maybe"
|
|
case ActionAllow:
|
|
return "allow"
|
|
case ActionBlock:
|
|
return "block"
|
|
case ActionDrop:
|
|
return "drop"
|
|
case ActionModify:
|
|
return "modify"
|
|
default:
|
|
return "unknown"
|
|
}
|
|
}
|
|
|
|
type Protocol int
|
|
|
|
func (p Protocol) String() string {
|
|
switch p {
|
|
case ProtocolTCP:
|
|
return "tcp"
|
|
case ProtocolUDP:
|
|
return "udp"
|
|
default:
|
|
return "unknown"
|
|
}
|
|
}
|
|
|
|
const (
|
|
ProtocolTCP Protocol = iota
|
|
ProtocolUDP
|
|
)
|
|
|
|
type StreamInfo struct {
|
|
ID int64
|
|
Protocol Protocol
|
|
SrcMAC, DstMAC net.HardwareAddr
|
|
SrcIP, DstIP net.IP
|
|
SrcPort, DstPort uint16
|
|
Props analyzer.CombinedPropMap
|
|
}
|
|
|
|
func (i StreamInfo) SrcString() string {
|
|
return net.JoinHostPort(i.SrcIP.String(), strconv.Itoa(int(i.SrcPort)))
|
|
}
|
|
|
|
func (i StreamInfo) DstString() string {
|
|
return net.JoinHostPort(i.DstIP.String(), strconv.Itoa(int(i.DstPort)))
|
|
}
|
|
|
|
type MatchResult struct {
|
|
Action Action
|
|
ModInstance modifier.Instance
|
|
}
|
|
|
|
type Ruleset interface {
|
|
// Analyzers returns the list of analyzers to use for a stream.
|
|
// It must be safe for concurrent use by multiple workers.
|
|
Analyzers(StreamInfo) []analyzer.Analyzer
|
|
// Match matches a stream against the ruleset and returns the result.
|
|
// It must be safe for concurrent use by multiple workers.
|
|
Match(StreamInfo) MatchResult
|
|
}
|
|
|
|
type Stats struct {
|
|
MatchCalls uint64
|
|
MatchErrors uint64
|
|
MatchLatencyNanos uint64
|
|
LookupCalls uint64
|
|
LookupErrors uint64
|
|
LookupLatencyNanos uint64
|
|
}
|
|
|
|
type statsCounters struct {
|
|
MatchCalls atomic.Uint64
|
|
MatchErrors atomic.Uint64
|
|
MatchLatencyNanos atomic.Uint64
|
|
LookupCalls atomic.Uint64
|
|
LookupErrors atomic.Uint64
|
|
LookupLatencyNanos atomic.Uint64
|
|
}
|
|
|
|
type StatsProvider interface {
|
|
Stats() Stats
|
|
}
|
|
|
|
// Logger is the logging interface for the ruleset.
|
|
type Logger interface {
|
|
Log(info StreamInfo, name string)
|
|
MatchError(info StreamInfo, name string, err error)
|
|
}
|
|
|
|
type BuiltinConfig struct {
|
|
Logger Logger
|
|
GeoSiteFilename string
|
|
GeoIpFilename string
|
|
ProtectedDialContext func(ctx context.Context, network, address string) (net.Conn, error)
|
|
}
|