Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3ec5456e86 | ||
|
|
b51ea5fa07 | ||
|
|
2ac8783eb6 | ||
|
|
5014523ae0 | ||
|
|
dabcc9566c | ||
|
|
c453020349 | ||
|
|
0daaa32fc6 | ||
|
|
5e15fd6dd9 | ||
|
|
76c0f47832 | ||
|
|
70fee14103 | ||
|
|
abd7725fed | ||
|
|
f01b79e625 | ||
|
|
94387450cf | ||
|
|
5723490a6c | ||
|
|
d7506264ad | ||
|
|
245ac46b65 | ||
|
|
107e29ee20 |
@@ -17,6 +17,7 @@ import (
|
|||||||
"github.com/apernet/OpenGFW/modifier"
|
"github.com/apernet/OpenGFW/modifier"
|
||||||
modUDP "github.com/apernet/OpenGFW/modifier/udp"
|
modUDP "github.com/apernet/OpenGFW/modifier/udp"
|
||||||
"github.com/apernet/OpenGFW/ruleset"
|
"github.com/apernet/OpenGFW/ruleset"
|
||||||
|
"github.com/apernet/OpenGFW/ruleset/builtins/geo"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
@@ -259,8 +260,7 @@ func runMain(cmd *cobra.Command, args []string) {
|
|||||||
}
|
}
|
||||||
rsConfig := &ruleset.BuiltinConfig{
|
rsConfig := &ruleset.BuiltinConfig{
|
||||||
Logger: &rulesetLogger{},
|
Logger: &rulesetLogger{},
|
||||||
GeoSiteFilename: config.Ruleset.GeoSite,
|
GeoMatcher: geo.NewGeoMatcher(config.Ruleset.GeoSite, config.Ruleset.GeoIp),
|
||||||
GeoIpFilename: config.Ruleset.GeoIp,
|
|
||||||
ProtectedDialContext: engineConfig.IO.ProtectedDialContext,
|
ProtectedDialContext: engineConfig.IO.ProtectedDialContext,
|
||||||
}
|
}
|
||||||
rs, err := ruleset.CompileExprRules(rawRs, analyzers, modifiers, rsConfig)
|
rs, err := ruleset.CompileExprRules(rawRs, analyzers, modifiers, rsConfig)
|
||||||
|
|||||||
@@ -102,9 +102,11 @@ func (e *engine) dispatch(p io.Packet) bool {
|
|||||||
_ = e.io.SetVerdict(p, io.VerdictAcceptStream, nil)
|
_ = e.io.SetVerdict(p, io.VerdictAcceptStream, nil)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
// Convert to gopacket.Packet
|
||||||
|
packet := gopacket.NewPacket(data, layerType, gopacket.DecodeOptions{Lazy: true, NoCopy: true})
|
||||||
|
packet.Metadata().Timestamp = p.Timestamp()
|
||||||
// Load balance by stream ID
|
// Load balance by stream ID
|
||||||
index := p.StreamID() % uint32(len(e.workers))
|
index := p.StreamID() % uint32(len(e.workers))
|
||||||
packet := gopacket.NewPacket(data, layerType, gopacket.DecodeOptions{Lazy: true, NoCopy: true})
|
|
||||||
e.workers[index].Feed(&workerPacket{
|
e.workers[index].Feed(&workerPacket{
|
||||||
StreamID: p.StreamID(),
|
StreamID: p.StreamID(),
|
||||||
Packet: packet,
|
Packet: packet,
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package io
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"net"
|
"net"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Verdict int
|
type Verdict int
|
||||||
@@ -24,6 +25,8 @@ const (
|
|||||||
type Packet interface {
|
type Packet interface {
|
||||||
// StreamID is the ID of the stream the packet belongs to.
|
// StreamID is the ID of the stream the packet belongs to.
|
||||||
StreamID() uint32
|
StreamID() uint32
|
||||||
|
// Timestamp is the time the packet was received.
|
||||||
|
Timestamp() time.Time
|
||||||
// Data is the raw packet data, starting with the IP header.
|
// Data is the raw packet data, starting with the IP header.
|
||||||
Data() []byte
|
Data() []byte
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/coreos/go-iptables/iptables"
|
"github.com/coreos/go-iptables/iptables"
|
||||||
"github.com/florianl/go-nfqueue"
|
"github.com/florianl/go-nfqueue"
|
||||||
@@ -189,6 +190,12 @@ func (n *nfqueuePacketIO) Register(ctx context.Context, cb PacketCallback) error
|
|||||||
streamID: ctIDFromCtBytes(*a.Ct),
|
streamID: ctIDFromCtBytes(*a.Ct),
|
||||||
data: *a.Payload,
|
data: *a.Payload,
|
||||||
}
|
}
|
||||||
|
// Use timestamp from attribute if available, otherwise use current time as fallback
|
||||||
|
if a.Timestamp != nil {
|
||||||
|
p.timestamp = *a.Timestamp
|
||||||
|
} else {
|
||||||
|
p.timestamp = time.Now()
|
||||||
|
}
|
||||||
return okBoolToInt(cb(p, nil))
|
return okBoolToInt(cb(p, nil))
|
||||||
},
|
},
|
||||||
func(e error) int {
|
func(e error) int {
|
||||||
@@ -312,15 +319,20 @@ func (n *nfqueuePacketIO) setupIpt(local, rst, remove bool) error {
|
|||||||
var _ Packet = (*nfqueuePacket)(nil)
|
var _ Packet = (*nfqueuePacket)(nil)
|
||||||
|
|
||||||
type nfqueuePacket struct {
|
type nfqueuePacket struct {
|
||||||
id uint32
|
id uint32
|
||||||
streamID uint32
|
streamID uint32
|
||||||
data []byte
|
timestamp time.Time
|
||||||
|
data []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *nfqueuePacket) StreamID() uint32 {
|
func (p *nfqueuePacket) StreamID() uint32 {
|
||||||
return p.streamID
|
return p.streamID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *nfqueuePacket) Timestamp() time.Time {
|
||||||
|
return p.timestamp
|
||||||
|
}
|
||||||
|
|
||||||
func (p *nfqueuePacket) Data() []byte {
|
func (p *nfqueuePacket) Data() []byte {
|
||||||
return p.data
|
return p.data
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ import (
|
|||||||
"github.com/apernet/OpenGFW/analyzer"
|
"github.com/apernet/OpenGFW/analyzer"
|
||||||
"github.com/apernet/OpenGFW/modifier"
|
"github.com/apernet/OpenGFW/modifier"
|
||||||
"github.com/apernet/OpenGFW/ruleset/builtins"
|
"github.com/apernet/OpenGFW/ruleset/builtins"
|
||||||
"github.com/apernet/OpenGFW/ruleset/builtins/geo"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ExprRule is the external representation of an expression rule.
|
// ExprRule is the external representation of an expression rule.
|
||||||
@@ -302,23 +301,22 @@ type Function struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func buildFunctionMap(config *BuiltinConfig) map[string]*Function {
|
func buildFunctionMap(config *BuiltinConfig) map[string]*Function {
|
||||||
geoMatcher := geo.NewGeoMatcher(config.GeoSiteFilename, config.GeoIpFilename)
|
|
||||||
return map[string]*Function{
|
return map[string]*Function{
|
||||||
"geoip": {
|
"geoip": {
|
||||||
InitFunc: geoMatcher.LoadGeoIP,
|
InitFunc: config.GeoMatcher.LoadGeoIP,
|
||||||
PatchFunc: nil,
|
PatchFunc: nil,
|
||||||
Func: func(params ...any) (any, error) {
|
Func: func(params ...any) (any, error) {
|
||||||
return geoMatcher.MatchGeoIp(params[0].(string), params[1].(string)), nil
|
return config.GeoMatcher.MatchGeoIp(params[0].(string), params[1].(string)), nil
|
||||||
},
|
},
|
||||||
Types: []reflect.Type{reflect.TypeOf(geoMatcher.MatchGeoIp)},
|
Types: []reflect.Type{reflect.TypeOf(config.GeoMatcher.MatchGeoIp)},
|
||||||
},
|
},
|
||||||
"geosite": {
|
"geosite": {
|
||||||
InitFunc: geoMatcher.LoadGeoSite,
|
InitFunc: config.GeoMatcher.LoadGeoSite,
|
||||||
PatchFunc: nil,
|
PatchFunc: nil,
|
||||||
Func: func(params ...any) (any, error) {
|
Func: func(params ...any) (any, error) {
|
||||||
return geoMatcher.MatchGeoSite(params[0].(string), params[1].(string)), nil
|
return config.GeoMatcher.MatchGeoSite(params[0].(string), params[1].(string)), nil
|
||||||
},
|
},
|
||||||
Types: []reflect.Type{reflect.TypeOf(geoMatcher.MatchGeoSite)},
|
Types: []reflect.Type{reflect.TypeOf(config.GeoMatcher.MatchGeoSite)},
|
||||||
},
|
},
|
||||||
"cidr": {
|
"cidr": {
|
||||||
InitFunc: nil,
|
InitFunc: nil,
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import (
|
|||||||
|
|
||||||
"github.com/apernet/OpenGFW/analyzer"
|
"github.com/apernet/OpenGFW/analyzer"
|
||||||
"github.com/apernet/OpenGFW/modifier"
|
"github.com/apernet/OpenGFW/modifier"
|
||||||
|
"github.com/apernet/OpenGFW/ruleset/builtins/geo"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Action int
|
type Action int
|
||||||
@@ -102,7 +103,6 @@ type Logger interface {
|
|||||||
|
|
||||||
type BuiltinConfig struct {
|
type BuiltinConfig struct {
|
||||||
Logger Logger
|
Logger Logger
|
||||||
GeoSiteFilename string
|
GeoMatcher *geo.GeoMatcher
|
||||||
GeoIpFilename string
|
|
||||||
ProtectedDialContext func(ctx context.Context, network, address string) (net.Conn, error)
|
ProtectedDialContext func(ctx context.Context, network, address string) (net.Conn, error)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user