Meow
2026-05-02 09:54:34 +08:00
committed by RPRX
parent 7ab0a3ccb7
commit 4e87f59628
26 changed files with 538 additions and 225 deletions

View File

@@ -148,7 +148,7 @@ func TestUDPServerSubnet(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },
@@ -210,7 +210,7 @@ func TestUDPServer(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },
@@ -350,7 +350,7 @@ func TestPrioritizedDomain(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },
@@ -421,7 +421,7 @@ func TestUDPServerIPv6(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },
@@ -490,7 +490,7 @@ func TestStaticHostDomain(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },
@@ -577,7 +577,7 @@ func TestIPMatch(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },
@@ -696,7 +696,7 @@ func TestLocalDomain(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },
@@ -953,7 +953,7 @@ func TestMultiMatchPrioritizedDomain(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },

View File

@@ -48,7 +48,7 @@ func TestOutboundWithoutStatCounter(t *testing.T) {
ctx = session.ContextWithOutbounds(ctx, []*session.Outbound{{}}) ctx = session.ContextWithOutbounds(ctx, []*session.Outbound{{}})
h, _ := NewHandler(ctx, &core.OutboundHandlerConfig{ h, _ := NewHandler(ctx, &core.OutboundHandlerConfig{
Tag: "tag", Tag: "tag",
ProxySettings: serial.ToTypedMessage(&freedom.Config{}), ProxySettings: serial.ToTypedMessage(&freedom.Config{FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}}}),
}) })
conn, _ := h.(*Handler).Dial(ctx, net.TCPDestination(net.DomainAddress("localhost"), 13146)) conn, _ := h.(*Handler).Dial(ctx, net.TCPDestination(net.DomainAddress("localhost"), 13146))
_, ok := conn.(*stat.CounterConnection) _, ok := conn.(*stat.CounterConnection)
@@ -78,7 +78,7 @@ func TestOutboundWithStatCounter(t *testing.T) {
ctx = session.ContextWithOutbounds(ctx, []*session.Outbound{{}}) ctx = session.ContextWithOutbounds(ctx, []*session.Outbound{{}})
h, _ := NewHandler(ctx, &core.OutboundHandlerConfig{ h, _ := NewHandler(ctx, &core.OutboundHandlerConfig{
Tag: "tag", Tag: "tag",
ProxySettings: serial.ToTypedMessage(&freedom.Config{}), ProxySettings: serial.ToTypedMessage(&freedom.Config{FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}}}),
}) })
conn, _ := h.(*Handler).Dial(ctx, net.TCPDestination(net.DomainAddress("localhost"), 13146)) conn, _ := h.(*Handler).Dial(ctx, net.TCPDestination(net.DomainAddress("localhost"), 13146))
_, ok := conn.(*stat.CounterConnection) _, ok := conn.(*stat.CounterConnection)
@@ -118,7 +118,7 @@ func TestTagsCache(t *testing.T) {
tag := fmt.Sprintf("%s%d", tags_prefix, idx) tag := fmt.Sprintf("%s%d", tags_prefix, idx)
cfg := &core.OutboundHandlerConfig{ cfg := &core.OutboundHandlerConfig{
Tag: tag, Tag: tag,
ProxySettings: serial.ToTypedMessage(&freedom.Config{}), ProxySettings: serial.ToTypedMessage(&freedom.Config{FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}}}),
} }
if h, err := NewHandler(ctx, cfg); err == nil { if h, err := NewHandler(ctx, cfg); err == nil {
if err := ohm.AddHandler(ctx, h); err == nil { if err := ohm.AddHandler(ctx, h); err == nil {

View File

@@ -53,7 +53,7 @@ func TestXrayDial(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },
@@ -105,7 +105,7 @@ func TestXrayDialUDPConn(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },
@@ -174,7 +174,7 @@ func TestXrayDialUDP(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },

View File

@@ -84,7 +84,7 @@ func (c *DNSOutboundConfig) Build() (proto.Message, error) {
if c.Rules != nil { if c.Rules != nil {
return nil, errors.New("legacy nonIPQuery and blockTypes cannot be mixed with rules") return nil, errors.New("legacy nonIPQuery and blockTypes cannot be mixed with rules")
} }
errors.PrintDeprecatedFeatureWarning(`"nonIPQuery" and "blockTypes" in DNS outbound`, `"rules"`) errors.PrintDeprecatedFeatureWarning(`"nonIPQuery" and "blockTypes"`, `"rules"`)
rules, err := c.buildLegacyDNSPolicy() rules, err := c.buildLegacyDNSPolicy()
if err != nil { if err != nil {
return nil, err return nil, err

View File

@@ -1,6 +1,7 @@
package conf package conf
import ( import (
"context"
"encoding/base64" "encoding/base64"
"encoding/hex" "encoding/hex"
"net" "net"
@@ -8,7 +9,7 @@ import (
"github.com/xtls/xray-core/common/errors" "github.com/xtls/xray-core/common/errors"
"github.com/xtls/xray-core/common/geodata" "github.com/xtls/xray-core/common/geodata"
v2net "github.com/xtls/xray-core/common/net" xnet "github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/common/protocol" "github.com/xtls/xray-core/common/protocol"
"github.com/xtls/xray-core/proxy/freedom" "github.com/xtls/xray-core/proxy/freedom"
"github.com/xtls/xray-core/transport/internet" "github.com/xtls/xray-core/transport/internet"
@@ -16,15 +17,16 @@ import (
) )
type FreedomConfig struct { type FreedomConfig struct {
TargetStrategy string `json:"targetStrategy"` TargetStrategy string `json:"targetStrategy"`
DomainStrategy string `json:"domainStrategy"` DomainStrategy string `json:"domainStrategy"`
Redirect string `json:"redirect"` Redirect string `json:"redirect"`
UserLevel uint32 `json:"userLevel"` UserLevel uint32 `json:"userLevel"`
Fragment *Fragment `json:"fragment"` Fragment *Fragment `json:"fragment"`
Noise *Noise `json:"noise"` Noise *Noise `json:"noise"`
Noises []*Noise `json:"noises"` Noises []*Noise `json:"noises"`
ProxyProtocol uint32 `json:"proxyProtocol"` ProxyProtocol uint32 `json:"proxyProtocol"`
IPsBlocked *StringList `json:"ipsBlocked"` IPsBlocked *StringList `json:"ipsBlocked"`
FinalRules []*FreedomFinalRuleConfig `json:"finalRules"`
} }
type Fragment struct { type Fragment struct {
@@ -41,8 +43,20 @@ type Noise struct {
ApplyTo string `json:"applyTo"` ApplyTo string `json:"applyTo"`
} }
type FreedomFinalRuleConfig struct {
Action string `json:"action"`
Network *NetworkList `json:"network"`
Port *PortList `json:"port"`
IP *StringList `json:"ip"`
}
// Build implements Buildable // Build implements Buildable
func (c *FreedomConfig) Build() (proto.Message, error) { func (c *FreedomConfig) Build() (proto.Message, error) {
if c.IPsBlocked != nil {
// todo: remove legacy
errors.LogWarning(context.Background(), `The feature "ipsBlocked" has been removed and migrated to "finalRules". Please update your config(s) according to release note and documentation.`)
}
config := new(freedom.Config) config := new(freedom.Config)
targetStrategy := c.TargetStrategy targetStrategy := c.TargetStrategy
if targetStrategy == "" { if targetStrategy == "" {
@@ -142,12 +156,13 @@ func (c *FreedomConfig) Build() (proto.Message, error) {
} }
config.UserLevel = c.UserLevel config.UserLevel = c.UserLevel
if len(c.Redirect) > 0 { if len(c.Redirect) > 0 {
host, portStr, err := net.SplitHostPort(c.Redirect) host, portStr, err := net.SplitHostPort(c.Redirect)
if err != nil { if err != nil {
return nil, errors.New("invalid redirect address: ", c.Redirect, ": ", err).Base(err) return nil, errors.New("invalid redirect address: ", c.Redirect, ": ", err).Base(err)
} }
port, err := v2net.PortFromString(portStr) port, err := xnet.PortFromString(portStr)
if err != nil { if err != nil {
return nil, errors.New("invalid redirect port: ", c.Redirect, ": ", err).Base(err) return nil, errors.New("invalid redirect port: ", c.Redirect, ": ", err).Base(err)
} }
@@ -158,19 +173,22 @@ func (c *FreedomConfig) Build() (proto.Message, error) {
} }
if len(host) > 0 { if len(host) > 0 {
config.DestinationOverride.Server.Address = v2net.NewIPOrDomain(v2net.ParseAddress(host)) config.DestinationOverride.Server.Address = xnet.NewIPOrDomain(xnet.ParseAddress(host))
} }
} }
if c.ProxyProtocol > 0 && c.ProxyProtocol <= 2 { if c.ProxyProtocol > 0 && c.ProxyProtocol <= 2 {
config.ProxyProtocol = c.ProxyProtocol config.ProxyProtocol = c.ProxyProtocol
} }
if c.IPsBlocked != nil {
rules, err := geodata.ParseIPRules(*c.IPsBlocked) for _, r := range c.FinalRules {
rule, err := r.Build()
if err != nil { if err != nil {
return nil, err return nil, err
} }
config.IpsBlocked = &freedom.IPRules{Rules: rules} config.FinalRules = append(config.FinalRules, rule)
} }
return config, nil return config, nil
} }
@@ -229,3 +247,34 @@ func ParseNoise(noise *Noise) (*freedom.Noise, error) {
} }
return NConfig, nil return NConfig, nil
} }
func (c *FreedomFinalRuleConfig) Build() (*freedom.FinalRuleConfig, error) {
rule := &freedom.FinalRuleConfig{}
switch strings.ToLower(c.Action) {
case "allow":
rule.Action = freedom.RuleAction_Allow
case "block":
rule.Action = freedom.RuleAction_Block
default:
return nil, errors.New("unknown action: ", c.Action)
}
if c.Network != nil {
rule.Networks = c.Network.Build()
}
if c.Port != nil {
rule.PortList = c.Port.Build()
}
if c.IP != nil {
rules, err := geodata.ParseIPRules(*c.IP)
if err != nil {
return nil, err
}
rule.Ip = rules
}
return rule, nil
}

View File

@@ -3,6 +3,7 @@ package conf_test
import ( import (
"testing" "testing"
"github.com/xtls/xray-core/common/geodata"
"github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/common/protocol" "github.com/xtls/xray-core/common/protocol"
. "github.com/xtls/xray-core/infra/conf" . "github.com/xtls/xray-core/infra/conf"
@@ -38,5 +39,59 @@ func TestFreedomConfig(t *testing.T) {
UserLevel: 1, UserLevel: 1,
}, },
}, },
{
Input: `{
"finalRules": [{
"action": "block",
"network": "tcp,udp",
"port": "53,443",
"ip": ["10.0.0.0/8", "2001:db8::/32"]
}, {
"action": "allow",
"network": ["udp"]
}]
}`,
Parser: loadJSON(creator),
Output: &freedom.Config{
FinalRules: []*freedom.FinalRuleConfig{
{
Action: freedom.RuleAction_Block,
Networks: []net.Network{net.Network_TCP, net.Network_UDP},
PortList: &net.PortList{
Range: []*net.PortRange{
{From: 53, To: 53},
{From: 443, To: 443},
},
},
Ip: []*geodata.IPRule{
{
Value: &geodata.IPRule_Custom{
Custom: &geodata.CIDRRule{
Cidr: &geodata.CIDR{
Ip: []byte{10, 0, 0, 0},
Prefix: 8,
},
},
},
},
{
Value: &geodata.IPRule_Custom{
Custom: &geodata.CIDRRule{
Cidr: &geodata.CIDR{
Ip: net.ParseAddress("2001:db8::").IP(),
Prefix: 32,
},
},
},
},
},
},
{
Action: freedom.RuleAction_Allow,
Networks: []net.Network{net.Network_UDP},
},
},
},
},
}) })
} }

View File

@@ -1 +0,0 @@
package freedom

View File

@@ -8,6 +8,7 @@ package freedom
import ( import (
geodata "github.com/xtls/xray-core/common/geodata" geodata "github.com/xtls/xray-core/common/geodata"
net "github.com/xtls/xray-core/common/net"
protocol "github.com/xtls/xray-core/common/protocol" protocol "github.com/xtls/xray-core/common/protocol"
internet "github.com/xtls/xray-core/transport/internet" internet "github.com/xtls/xray-core/transport/internet"
protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoreflect "google.golang.org/protobuf/reflect/protoreflect"
@@ -24,6 +25,52 @@ const (
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
) )
type RuleAction int32
const (
RuleAction_Allow RuleAction = 0
RuleAction_Block RuleAction = 1
)
// Enum value maps for RuleAction.
var (
RuleAction_name = map[int32]string{
0: "Allow",
1: "Block",
}
RuleAction_value = map[string]int32{
"Allow": 0,
"Block": 1,
}
)
func (x RuleAction) Enum() *RuleAction {
p := new(RuleAction)
*p = x
return p
}
func (x RuleAction) String() string {
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}
func (RuleAction) Descriptor() protoreflect.EnumDescriptor {
return file_proxy_freedom_config_proto_enumTypes[0].Descriptor()
}
func (RuleAction) Type() protoreflect.EnumType {
return &file_proxy_freedom_config_proto_enumTypes[0]
}
func (x RuleAction) Number() protoreflect.EnumNumber {
return protoreflect.EnumNumber(x)
}
// Deprecated: Use RuleAction.Descriptor instead.
func (RuleAction) EnumDescriptor() ([]byte, []int) {
return file_proxy_freedom_config_proto_rawDescGZIP(), []int{0}
}
type DestinationOverride struct { type DestinationOverride struct {
state protoimpl.MessageState `protogen:"open.v1"` state protoimpl.MessageState `protogen:"open.v1"`
Server *protocol.ServerEndpoint `protobuf:"bytes,1,opt,name=server,proto3" json:"server,omitempty"` Server *protocol.ServerEndpoint `protobuf:"bytes,1,opt,name=server,proto3" json:"server,omitempty"`
@@ -252,27 +299,30 @@ func (x *Noise) GetApplyTo() string {
return "" return ""
} }
type IPRules struct { type FinalRuleConfig struct {
state protoimpl.MessageState `protogen:"open.v1"` state protoimpl.MessageState `protogen:"open.v1"`
Rules []*geodata.IPRule `protobuf:"bytes,1,rep,name=rules,proto3" json:"rules,omitempty"` Action RuleAction `protobuf:"varint,1,opt,name=action,proto3,enum=xray.proxy.freedom.RuleAction" json:"action,omitempty"`
Networks []net.Network `protobuf:"varint,2,rep,packed,name=networks,proto3,enum=xray.common.net.Network" json:"networks,omitempty"`
PortList *net.PortList `protobuf:"bytes,3,opt,name=port_list,json=portList,proto3" json:"port_list,omitempty"`
Ip []*geodata.IPRule `protobuf:"bytes,4,rep,name=ip,proto3" json:"ip,omitempty"`
unknownFields protoimpl.UnknownFields unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
} }
func (x *IPRules) Reset() { func (x *FinalRuleConfig) Reset() {
*x = IPRules{} *x = FinalRuleConfig{}
mi := &file_proxy_freedom_config_proto_msgTypes[3] mi := &file_proxy_freedom_config_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
func (x *IPRules) String() string { func (x *FinalRuleConfig) String() string {
return protoimpl.X.MessageStringOf(x) return protoimpl.X.MessageStringOf(x)
} }
func (*IPRules) ProtoMessage() {} func (*FinalRuleConfig) ProtoMessage() {}
func (x *IPRules) ProtoReflect() protoreflect.Message { func (x *FinalRuleConfig) ProtoReflect() protoreflect.Message {
mi := &file_proxy_freedom_config_proto_msgTypes[3] mi := &file_proxy_freedom_config_proto_msgTypes[3]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -284,14 +334,35 @@ func (x *IPRules) ProtoReflect() protoreflect.Message {
return mi.MessageOf(x) return mi.MessageOf(x)
} }
// Deprecated: Use IPRules.ProtoReflect.Descriptor instead. // Deprecated: Use FinalRuleConfig.ProtoReflect.Descriptor instead.
func (*IPRules) Descriptor() ([]byte, []int) { func (*FinalRuleConfig) Descriptor() ([]byte, []int) {
return file_proxy_freedom_config_proto_rawDescGZIP(), []int{3} return file_proxy_freedom_config_proto_rawDescGZIP(), []int{3}
} }
func (x *IPRules) GetRules() []*geodata.IPRule { func (x *FinalRuleConfig) GetAction() RuleAction {
if x != nil { if x != nil {
return x.Rules return x.Action
}
return RuleAction_Allow
}
func (x *FinalRuleConfig) GetNetworks() []net.Network {
if x != nil {
return x.Networks
}
return nil
}
func (x *FinalRuleConfig) GetPortList() *net.PortList {
if x != nil {
return x.PortList
}
return nil
}
func (x *FinalRuleConfig) GetIp() []*geodata.IPRule {
if x != nil {
return x.Ip
} }
return nil return nil
} }
@@ -304,7 +375,7 @@ type Config struct {
Fragment *Fragment `protobuf:"bytes,5,opt,name=fragment,proto3" json:"fragment,omitempty"` Fragment *Fragment `protobuf:"bytes,5,opt,name=fragment,proto3" json:"fragment,omitempty"`
ProxyProtocol uint32 `protobuf:"varint,6,opt,name=proxy_protocol,json=proxyProtocol,proto3" json:"proxy_protocol,omitempty"` ProxyProtocol uint32 `protobuf:"varint,6,opt,name=proxy_protocol,json=proxyProtocol,proto3" json:"proxy_protocol,omitempty"`
Noises []*Noise `protobuf:"bytes,7,rep,name=noises,proto3" json:"noises,omitempty"` Noises []*Noise `protobuf:"bytes,7,rep,name=noises,proto3" json:"noises,omitempty"`
IpsBlocked *IPRules `protobuf:"bytes,8,opt,name=ips_blocked,json=ipsBlocked,proto3,oneof" json:"ips_blocked,omitempty"` FinalRules []*FinalRuleConfig `protobuf:"bytes,8,rep,name=final_rules,json=finalRules,proto3" json:"final_rules,omitempty"`
unknownFields protoimpl.UnknownFields unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
} }
@@ -381,9 +452,9 @@ func (x *Config) GetNoises() []*Noise {
return nil return nil
} }
func (x *Config) GetIpsBlocked() *IPRules { func (x *Config) GetFinalRules() []*FinalRuleConfig {
if x != nil { if x != nil {
return x.IpsBlocked return x.FinalRules
} }
return nil return nil
} }
@@ -392,7 +463,7 @@ var File_proxy_freedom_config_proto protoreflect.FileDescriptor
const file_proxy_freedom_config_proto_rawDesc = "" + const file_proxy_freedom_config_proto_rawDesc = "" +
"\n" + "\n" +
"\x1aproxy/freedom/config.proto\x12\x12xray.proxy.freedom\x1a!common/protocol/server_spec.proto\x1a\x1ftransport/internet/config.proto\x1a\x1bcommon/geodata/geodat.proto\"S\n" + "\x1aproxy/freedom/config.proto\x12\x12xray.proxy.freedom\x1a!common/protocol/server_spec.proto\x1a\x1ftransport/internet/config.proto\x1a\x15common/net/port.proto\x1a\x18common/net/network.proto\x1a\x1bcommon/geodata/geodat.proto\"S\n" +
"\x13DestinationOverride\x12<\n" + "\x13DestinationOverride\x12<\n" +
"\x06server\x18\x01 \x01(\v2$.xray.common.protocol.ServerEndpointR\x06server\"\x98\x02\n" + "\x06server\x18\x01 \x01(\v2$.xray.common.protocol.ServerEndpointR\x06server\"\x98\x02\n" +
"\bFragment\x12!\n" + "\bFragment\x12!\n" +
@@ -415,9 +486,12 @@ const file_proxy_freedom_config_proto_rawDesc = "" +
"\tdelay_min\x18\x03 \x01(\x04R\bdelayMin\x12\x1b\n" + "\tdelay_min\x18\x03 \x01(\x04R\bdelayMin\x12\x1b\n" +
"\tdelay_max\x18\x04 \x01(\x04R\bdelayMax\x12\x16\n" + "\tdelay_max\x18\x04 \x01(\x04R\bdelayMax\x12\x16\n" +
"\x06packet\x18\x05 \x01(\fR\x06packet\x12\x19\n" + "\x06packet\x18\x05 \x01(\fR\x06packet\x12\x19\n" +
"\bapply_to\x18\x06 \x01(\tR\aapplyTo\"<\n" + "\bapply_to\x18\x06 \x01(\tR\aapplyTo\"\xe4\x01\n" +
"\aIPRules\x121\n" + "\x0fFinalRuleConfig\x126\n" +
"\x05rules\x18\x01 \x03(\v2\x1b.xray.common.geodata.IPRuleR\x05rules\"\xbc\x03\n" + "\x06action\x18\x01 \x01(\x0e2\x1e.xray.proxy.freedom.RuleActionR\x06action\x124\n" +
"\bnetworks\x18\x02 \x03(\x0e2\x18.xray.common.net.NetworkR\bnetworks\x126\n" +
"\tport_list\x18\x03 \x01(\v2\x19.xray.common.net.PortListR\bportList\x12+\n" +
"\x02ip\x18\x04 \x03(\v2\x1b.xray.common.geodata.IPRuleR\x02ip\"\xaf\x03\n" +
"\x06Config\x12P\n" + "\x06Config\x12P\n" +
"\x0fdomain_strategy\x18\x01 \x01(\x0e2'.xray.transport.internet.DomainStrategyR\x0edomainStrategy\x12Z\n" + "\x0fdomain_strategy\x18\x01 \x01(\x0e2'.xray.transport.internet.DomainStrategyR\x0edomainStrategy\x12Z\n" +
"\x14destination_override\x18\x03 \x01(\v2'.xray.proxy.freedom.DestinationOverrideR\x13destinationOverride\x12\x1d\n" + "\x14destination_override\x18\x03 \x01(\v2'.xray.proxy.freedom.DestinationOverrideR\x13destinationOverride\x12\x1d\n" +
@@ -425,10 +499,13 @@ const file_proxy_freedom_config_proto_rawDesc = "" +
"user_level\x18\x04 \x01(\rR\tuserLevel\x128\n" + "user_level\x18\x04 \x01(\rR\tuserLevel\x128\n" +
"\bfragment\x18\x05 \x01(\v2\x1c.xray.proxy.freedom.FragmentR\bfragment\x12%\n" + "\bfragment\x18\x05 \x01(\v2\x1c.xray.proxy.freedom.FragmentR\bfragment\x12%\n" +
"\x0eproxy_protocol\x18\x06 \x01(\rR\rproxyProtocol\x121\n" + "\x0eproxy_protocol\x18\x06 \x01(\rR\rproxyProtocol\x121\n" +
"\x06noises\x18\a \x03(\v2\x19.xray.proxy.freedom.NoiseR\x06noises\x12A\n" + "\x06noises\x18\a \x03(\v2\x19.xray.proxy.freedom.NoiseR\x06noises\x12D\n" +
"\vips_blocked\x18\b \x01(\v2\x1b.xray.proxy.freedom.IPRulesH\x00R\n" + "\vfinal_rules\x18\b \x03(\v2#.xray.proxy.freedom.FinalRuleConfigR\n" +
"ipsBlocked\x88\x01\x01B\x0e\n" + "finalRules*\"\n" +
"\f_ips_blockedBX\n" + "\n" +
"RuleAction\x12\t\n" +
"\x05Allow\x10\x00\x12\t\n" +
"\x05Block\x10\x01BX\n" +
"\x16com.xray.proxy.freedomP\x01Z'github.com/xtls/xray-core/proxy/freedom\xaa\x02\x12Xray.Proxy.Freedomb\x06proto3" "\x16com.xray.proxy.freedomP\x01Z'github.com/xtls/xray-core/proxy/freedom\xaa\x02\x12Xray.Proxy.Freedomb\x06proto3"
var ( var (
@@ -443,30 +520,37 @@ func file_proxy_freedom_config_proto_rawDescGZIP() []byte {
return file_proxy_freedom_config_proto_rawDescData return file_proxy_freedom_config_proto_rawDescData
} }
var file_proxy_freedom_config_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_proxy_freedom_config_proto_msgTypes = make([]protoimpl.MessageInfo, 5) var file_proxy_freedom_config_proto_msgTypes = make([]protoimpl.MessageInfo, 5)
var file_proxy_freedom_config_proto_goTypes = []any{ var file_proxy_freedom_config_proto_goTypes = []any{
(*DestinationOverride)(nil), // 0: xray.proxy.freedom.DestinationOverride (RuleAction)(0), // 0: xray.proxy.freedom.RuleAction
(*Fragment)(nil), // 1: xray.proxy.freedom.Fragment (*DestinationOverride)(nil), // 1: xray.proxy.freedom.DestinationOverride
(*Noise)(nil), // 2: xray.proxy.freedom.Noise (*Fragment)(nil), // 2: xray.proxy.freedom.Fragment
(*IPRules)(nil), // 3: xray.proxy.freedom.IPRules (*Noise)(nil), // 3: xray.proxy.freedom.Noise
(*Config)(nil), // 4: xray.proxy.freedom.Config (*FinalRuleConfig)(nil), // 4: xray.proxy.freedom.FinalRuleConfig
(*protocol.ServerEndpoint)(nil), // 5: xray.common.protocol.ServerEndpoint (*Config)(nil), // 5: xray.proxy.freedom.Config
(*geodata.IPRule)(nil), // 6: xray.common.geodata.IPRule (*protocol.ServerEndpoint)(nil), // 6: xray.common.protocol.ServerEndpoint
(internet.DomainStrategy)(0), // 7: xray.transport.internet.DomainStrategy (net.Network)(0), // 7: xray.common.net.Network
(*net.PortList)(nil), // 8: xray.common.net.PortList
(*geodata.IPRule)(nil), // 9: xray.common.geodata.IPRule
(internet.DomainStrategy)(0), // 10: xray.transport.internet.DomainStrategy
} }
var file_proxy_freedom_config_proto_depIdxs = []int32{ var file_proxy_freedom_config_proto_depIdxs = []int32{
5, // 0: xray.proxy.freedom.DestinationOverride.server:type_name -> xray.common.protocol.ServerEndpoint 6, // 0: xray.proxy.freedom.DestinationOverride.server:type_name -> xray.common.protocol.ServerEndpoint
6, // 1: xray.proxy.freedom.IPRules.rules:type_name -> xray.common.geodata.IPRule 0, // 1: xray.proxy.freedom.FinalRuleConfig.action:type_name -> xray.proxy.freedom.RuleAction
7, // 2: xray.proxy.freedom.Config.domain_strategy:type_name -> xray.transport.internet.DomainStrategy 7, // 2: xray.proxy.freedom.FinalRuleConfig.networks:type_name -> xray.common.net.Network
0, // 3: xray.proxy.freedom.Config.destination_override:type_name -> xray.proxy.freedom.DestinationOverride 8, // 3: xray.proxy.freedom.FinalRuleConfig.port_list:type_name -> xray.common.net.PortList
1, // 4: xray.proxy.freedom.Config.fragment:type_name -> xray.proxy.freedom.Fragment 9, // 4: xray.proxy.freedom.FinalRuleConfig.ip:type_name -> xray.common.geodata.IPRule
2, // 5: xray.proxy.freedom.Config.noises:type_name -> xray.proxy.freedom.Noise 10, // 5: xray.proxy.freedom.Config.domain_strategy:type_name -> xray.transport.internet.DomainStrategy
3, // 6: xray.proxy.freedom.Config.ips_blocked:type_name -> xray.proxy.freedom.IPRules 1, // 6: xray.proxy.freedom.Config.destination_override:type_name -> xray.proxy.freedom.DestinationOverride
7, // [7:7] is the sub-list for method output_type 2, // 7: xray.proxy.freedom.Config.fragment:type_name -> xray.proxy.freedom.Fragment
7, // [7:7] is the sub-list for method input_type 3, // 8: xray.proxy.freedom.Config.noises:type_name -> xray.proxy.freedom.Noise
7, // [7:7] is the sub-list for extension type_name 4, // 9: xray.proxy.freedom.Config.final_rules:type_name -> xray.proxy.freedom.FinalRuleConfig
7, // [7:7] is the sub-list for extension extendee 10, // [10:10] is the sub-list for method output_type
0, // [0:7] is the sub-list for field type_name 10, // [10:10] is the sub-list for method input_type
10, // [10:10] is the sub-list for extension type_name
10, // [10:10] is the sub-list for extension extendee
0, // [0:10] is the sub-list for field type_name
} }
func init() { file_proxy_freedom_config_proto_init() } func init() { file_proxy_freedom_config_proto_init() }
@@ -474,19 +558,19 @@ func file_proxy_freedom_config_proto_init() {
if File_proxy_freedom_config_proto != nil { if File_proxy_freedom_config_proto != nil {
return return
} }
file_proxy_freedom_config_proto_msgTypes[4].OneofWrappers = []any{}
type x struct{} type x struct{}
out := protoimpl.TypeBuilder{ out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{ File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(), GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_proxy_freedom_config_proto_rawDesc), len(file_proxy_freedom_config_proto_rawDesc)), RawDescriptor: unsafe.Slice(unsafe.StringData(file_proxy_freedom_config_proto_rawDesc), len(file_proxy_freedom_config_proto_rawDesc)),
NumEnums: 0, NumEnums: 1,
NumMessages: 5, NumMessages: 5,
NumExtensions: 0, NumExtensions: 0,
NumServices: 0, NumServices: 0,
}, },
GoTypes: file_proxy_freedom_config_proto_goTypes, GoTypes: file_proxy_freedom_config_proto_goTypes,
DependencyIndexes: file_proxy_freedom_config_proto_depIdxs, DependencyIndexes: file_proxy_freedom_config_proto_depIdxs,
EnumInfos: file_proxy_freedom_config_proto_enumTypes,
MessageInfos: file_proxy_freedom_config_proto_msgTypes, MessageInfos: file_proxy_freedom_config_proto_msgTypes,
}.Build() }.Build()
File_proxy_freedom_config_proto = out.File File_proxy_freedom_config_proto = out.File

View File

@@ -8,6 +8,8 @@ option java_multiple_files = true;
import "common/protocol/server_spec.proto"; import "common/protocol/server_spec.proto";
import "transport/internet/config.proto"; import "transport/internet/config.proto";
import "common/net/port.proto";
import "common/net/network.proto";
import "common/geodata/geodat.proto"; import "common/geodata/geodat.proto";
message DestinationOverride { message DestinationOverride {
@@ -24,6 +26,7 @@ message Fragment {
uint64 max_split_min = 7; uint64 max_split_min = 7;
uint64 max_split_max = 8; uint64 max_split_max = 8;
} }
message Noise { message Noise {
uint64 length_min = 1; uint64 length_min = 1;
uint64 length_max = 2; uint64 length_max = 2;
@@ -33,8 +36,16 @@ message Noise {
string apply_to = 6; string apply_to = 6;
} }
message IPRules { enum RuleAction {
repeated xray.common.geodata.IPRule rules = 1; Allow = 0;
Block = 1;
}
message FinalRuleConfig {
RuleAction action = 1;
repeated xray.common.net.Network networks = 2;
xray.common.net.PortList port_list = 3;
repeated xray.common.geodata.IPRule ip = 4;
} }
message Config { message Config {
@@ -44,5 +55,5 @@ message Config {
Fragment fragment = 5; Fragment fragment = 5;
uint32 proxy_protocol = 6; uint32 proxy_protocol = 6;
repeated Noise noises = 7; repeated Noise noises = 7;
optional IPRules ips_blocked = 8; repeated FinalRuleConfig final_rules = 8;
} }

View File

@@ -31,32 +31,9 @@ import (
) )
var useSplice bool var useSplice bool
var allNetworks [8]bool
var defaultPrivateBlockIP = []string{ var defaultBlockPrivateRule *FinalRule
"0.0.0.0/8", var defaultBlockAllRule *FinalRule
"10.0.0.0/8",
"100.64.0.0/10",
"127.0.0.0/8",
"169.254.0.0/16",
"172.16.0.0/12",
"192.0.0.0/24",
"192.0.2.0/24",
"192.88.99.0/24",
"192.168.0.0/16",
"198.18.0.0/15",
"198.51.100.0/24",
"203.0.113.0/24",
"224.0.0.0/3",
"::/127",
"fc00::/7",
"fe80::/10",
"ff00::/8",
}
var defaultPrivateBlockIPMatcher = func() geodata.IPMatcher {
rules := common.Must2(geodata.ParseIPRules(defaultPrivateBlockIP))
return common.Must2(geodata.IPReg.BuildIPMatcher(rules))
}()
func init() { func init() {
common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) { common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
@@ -68,31 +45,175 @@ func init() {
} }
return h, nil return h, nil
})) }))
const defaultFlagValue = "NOT_DEFINED_AT_ALL" const defaultFlagValue = "NOT_DEFINED_AT_ALL"
value := platform.NewEnvFlag(platform.UseFreedomSplice).GetValue(func() string { return defaultFlagValue }) value := platform.NewEnvFlag(platform.UseFreedomSplice).GetValue(func() string { return defaultFlagValue })
switch value { switch value {
case defaultFlagValue, "auto", "enable": case defaultFlagValue, "auto", "enable":
useSplice = true useSplice = true
} }
for i := range allNetworks {
allNetworks[i] = true
}
defaultBlockPrivateRule = &FinalRule{
action: RuleAction_Block,
network: allNetworks,
ip: common.Must2(geodata.IPReg.BuildIPMatcher(common.Must2(geodata.ParseIPRules([]string{
"0.0.0.0/8",
"10.0.0.0/8",
"100.64.0.0/10",
"127.0.0.0/8",
"169.254.0.0/16",
"172.16.0.0/12",
"192.0.0.0/24",
"192.0.2.0/24",
"192.88.99.0/24",
"192.168.0.0/16",
"198.18.0.0/15",
"198.51.100.0/24",
"203.0.113.0/24",
"224.0.0.0/3",
"::/127",
"fc00::/7",
"fe80::/10",
"ff00::/8",
})))),
}
defaultBlockAllRule = &FinalRule{
action: RuleAction_Block,
network: allNetworks,
}
}
type FinalRule struct {
action RuleAction
network [8]bool
port net.MemoryPortList
ip geodata.IPMatcher
} }
// Handler handles Freedom connections. // Handler handles Freedom connections.
type Handler struct { type Handler struct {
policyManager policy.Manager policyManager policy.Manager
config *Config config *Config
blockedIPMatcher geodata.IPMatcher finalRules []*FinalRule
}
func buildFinalRule(config *FinalRuleConfig) (*FinalRule, error) {
rule := &FinalRule{
action: config.GetAction(),
}
if len(config.Networks) == 0 {
rule.network = allNetworks
} else {
for _, network := range config.Networks {
rule.network[int(network)] = true
}
}
if config.PortList != nil {
rule.port = net.PortListFromProto(config.PortList)
}
if len(config.Ip) > 0 {
matcher, err := geodata.IPReg.BuildIPMatcher(config.Ip)
if err != nil {
return nil, err
}
rule.ip = matcher
}
return rule, nil
}
func (r *FinalRule) matchNetwork(network net.Network) bool {
return r.network[int(network)]
}
func (r *FinalRule) matchPort(port net.Port) bool {
if len(r.port) == 0 {
return true
}
return r.port.Contains(port)
}
func (r *FinalRule) matchIP(addr net.Address) bool {
if r.ip == nil {
return true
}
return addr != nil && addr.Family().IsIP() && r.ip.Match(addr.IP())
}
func (r *FinalRule) Apply(network net.Network, address net.Address, port net.Port) bool {
if !r.matchNetwork(network) {
return false
}
if !r.matchPort(port) {
return false
}
return r.matchIP(address)
}
func getDefaultFinalRule(inbound *session.Inbound) *FinalRule {
if inbound == nil {
return nil
}
switch inbound.Name {
case "vless-reverse":
return defaultBlockAllRule
case "vless", "vmess", "trojan", "hysteria", "wireguard":
return defaultBlockPrivateRule
default:
if strings.HasPrefix(inbound.Name, "shadowsocks") {
return defaultBlockPrivateRule
}
}
return nil
}
func (h *Handler) shouldResolveDomainBeforeFinalRules(dialDest net.Destination, defaultRule *FinalRule) bool {
if dialDest.Network != net.Network_TCP || !dialDest.Address.Family().IsDomain() {
return false
}
if len(h.finalRules) > 0 {
rule := h.finalRules[0]
if rule.action == RuleAction_Allow && rule.network[dialDest.Network] && len(rule.port) == 0 && rule.ip == nil {
return false
}
}
if defaultRule != nil || len(h.finalRules) > 0 {
return true
}
return false
}
func (h *Handler) applyFinalRules(network net.Network, address net.Address, port net.Port, defaultRule *FinalRule) RuleAction {
for _, rule := range h.finalRules {
if rule.Apply(network, address, port) {
return rule.action
}
}
if defaultRule != nil && defaultRule.Apply(network, address, port) {
return defaultRule.action
}
return RuleAction_Allow
} }
// Init initializes the Handler with necessary parameters. // Init initializes the Handler with necessary parameters.
func (h *Handler) Init(config *Config, pm policy.Manager) error { func (h *Handler) Init(config *Config, pm policy.Manager) error {
h.config = config h.config = config
h.policyManager = pm h.policyManager = pm
if config.IpsBlocked != nil && len(config.IpsBlocked.Rules) > 0 { h.finalRules = make([]*FinalRule, 0, len(config.FinalRules))
m, err := geodata.IPReg.BuildIPMatcher(config.IpsBlocked.Rules) for _, rc := range config.FinalRules {
rule, err := buildFinalRule(rc)
if err != nil { if err != nil {
return errors.New("failed to build blocked ip matcher").Base(err) return errors.New("failed to build final rule").Base(err)
} }
h.blockedIPMatcher = m h.finalRules = append(h.finalRules, rule)
} }
return nil return nil
} }
@@ -111,32 +232,6 @@ func isValidAddress(addr *net.IPOrDomain) bool {
return a != net.AnyIP && a != net.AnyIPv6 return a != net.AnyIP && a != net.AnyIPv6
} }
func (h *Handler) getBlockedIPMatcher(ctx context.Context, inbound *session.Inbound) geodata.IPMatcher {
if h.blockedIPMatcher != nil {
return h.blockedIPMatcher
}
if h.config.IpsBlocked != nil && len(h.config.IpsBlocked.Rules) == 0 { // "ipsBlocked": []
return nil
}
if inbound == nil {
return nil
}
switch inbound.Name {
case "vmess", "trojan", "hysteria", "wireguard":
errors.LogInfo(ctx, "applying default private IP blocking policy for inbound ", inbound.Name)
return defaultPrivateBlockIPMatcher
}
if strings.HasPrefix(inbound.Name, "vless") || strings.HasPrefix(inbound.Name, "shadowsocks") {
errors.LogInfo(ctx, "applying default private IP blocking policy for inbound ", inbound.Name)
return defaultPrivateBlockIPMatcher
}
return nil
}
func isBlockedAddress(matcher geodata.IPMatcher, addr net.Address) bool {
return matcher != nil && addr != nil && addr.Family().IsIP() && matcher.Match(addr.IP())
}
// Process implements proxy.Outbound. // Process implements proxy.Outbound.
func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer internet.Dialer) error { func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer internet.Dialer) error {
outbounds := session.OutboundsFromContext(ctx) outbounds := session.OutboundsFromContext(ctx)
@@ -147,7 +242,7 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
ob.Name = "freedom" ob.Name = "freedom"
ob.CanSpliceCopy = 1 ob.CanSpliceCopy = 1
inbound := session.InboundFromContext(ctx) inbound := session.InboundFromContext(ctx)
blockedIPMatcher := h.getBlockedIPMatcher(ctx, inbound) defaultRule := getDefaultFinalRule(inbound)
destination := ob.Target destination := ob.Target
origTargetAddr := ob.OriginalTarget.Address origTargetAddr := ob.OriginalTarget.Address
@@ -173,6 +268,7 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
output := link.Writer output := link.Writer
var conn stat.Connection var conn stat.Connection
var blockedDest *net.Destination
err := retry.ExponentialBackoff(5, 100).On(func() error { err := retry.ExponentialBackoff(5, 100).On(func() error {
dialDest := destination dialDest := destination
if h.config.DomainStrategy.HasStrategy() && dialDest.Address.Family().IsDomain() { if h.config.DomainStrategy.HasStrategy() && dialDest.Address.Family().IsDomain() {
@@ -194,6 +290,20 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
} }
errors.LogInfo(ctx, "dialing to ", dialDest) errors.LogInfo(ctx, "dialing to ", dialDest)
} }
} else if h.shouldResolveDomainBeforeFinalRules(dialDest, defaultRule) {
addrs, err := net.DefaultResolver.LookupIPAddr(ctx, dialDest.Address.Domain())
if err != nil {
errors.LogInfoInner(ctx, err, "failed to get IP address for domain ", dialDest.Address.Domain())
} else if len(addrs) > 0 {
if addr := net.IPAddress(addrs[dice.Roll(len(addrs))].IP); addr != nil {
dialDest.Address = addr
errors.LogInfo(ctx, "dialing to ", dialDest)
}
}
}
if dialDest.Network == net.Network_TCP && h.applyFinalRules(dialDest.Network, dialDest.Address, dialDest.Port, defaultRule) == RuleAction_Block {
blockedDest = &dialDest
return nil
} }
rawConn, err := dialer.Dial(ctx, dialDest) rawConn, err := dialer.Dial(ctx, dialDest)
@@ -207,10 +317,13 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
if err != nil { if err != nil {
return errors.New("failed to open connection to ", destination).Base(err) return errors.New("failed to open connection to ", destination).Base(err)
} }
if remoteAddr := net.DestinationFromAddr(conn.RemoteAddr()).Address; isBlockedAddress(blockedIPMatcher, remoteAddr) { if blockedDest != nil {
conn.Close() return errors.New("blocked target: ", *blockedDest).AtInfo()
return errors.New("blocked target IP: ", remoteAddr).AtInfo()
} }
// if remoteDest := net.DestinationFromAddr(conn.RemoteAddr()); h.applyFinalRules(remoteDest.Network, remoteDest.Address, remoteDest.Port, defaultRule) == RuleAction_Block {
// conn.Close()
// return errors.New("blocked target: ", remoteDest).AtInfo()
// }
if h.config.ProxyProtocol > 0 && h.config.ProxyProtocol <= 2 { if h.config.ProxyProtocol > 0 && h.config.ProxyProtocol <= 2 {
version := byte(h.config.ProxyProtocol) version := byte(h.config.ProxyProtocol)
srcAddr := inbound.Source.RawNetAddr() srcAddr := inbound.Source.RawNetAddr()
@@ -255,7 +368,7 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
writer = buf.NewWriter(conn) writer = buf.NewWriter(conn)
} }
} else { } else {
writer = NewPacketWriter(conn, h, UDPOverride, destination, blockedIPMatcher) writer = NewPacketWriter(conn, h, defaultRule, UDPOverride, destination)
if h.config.Noises != nil { if h.config.Noises != nil {
errors.LogDebug(ctx, "NOISE", h.config.Noises) errors.LogDebug(ctx, "NOISE", h.config.Noises)
writer = &NoisePacketWriter{ writer = &NoisePacketWriter{
@@ -290,7 +403,7 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
if destination.Network == net.Network_TCP { if destination.Network == net.Network_TCP {
reader = buf.NewReader(conn) reader = buf.NewReader(conn)
} else { } else {
reader = NewPacketReader(conn, UDPOverride, destination, blockedIPMatcher) reader = NewPacketReader(conn, h, defaultRule, UDPOverride, destination)
} }
if err := buf.Copy(reader, output, buf.UpdateActivity(timer)); err != nil { if err := buf.Copy(reader, output, buf.UpdateActivity(timer)); err != nil {
return errors.New("failed to process response").Base(err) return errors.New("failed to process response").Base(err)
@@ -309,7 +422,7 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
return nil return nil
} }
func NewPacketReader(conn net.Conn, UDPOverride net.Destination, DialDest net.Destination, blockedIPMatcher geodata.IPMatcher) buf.Reader { func NewPacketReader(conn net.Conn, h *Handler, defaultRule *FinalRule, UDPOverride net.Destination, DialDest net.Destination) buf.Reader {
iConn := conn iConn := conn
statConn, ok := iConn.(*stat.CounterConnection) statConn, ok := iConn.(*stat.CounterConnection)
if ok { if ok {
@@ -328,7 +441,8 @@ func NewPacketReader(conn net.Conn, UDPOverride net.Destination, DialDest net.De
return &PacketReader{ return &PacketReader{
PacketConnWrapper: c, PacketConnWrapper: c,
Counter: counter, Counter: counter,
BlockedIPMatcher: blockedIPMatcher, Handler: h,
DefaultRule: defaultRule,
IsOverridden: isOverridden, IsOverridden: isOverridden,
InitUnchangedAddr: DialDest.Address, InitUnchangedAddr: DialDest.Address,
InitChangedAddr: net.DestinationFromAddr(conn.RemoteAddr()).Address, InitChangedAddr: net.DestinationFromAddr(conn.RemoteAddr()).Address,
@@ -340,7 +454,8 @@ func NewPacketReader(conn net.Conn, UDPOverride net.Destination, DialDest net.De
type PacketReader struct { type PacketReader struct {
*internet.PacketConnWrapper *internet.PacketConnWrapper
stats.Counter stats.Counter
BlockedIPMatcher geodata.IPMatcher Handler *Handler
DefaultRule *FinalRule
IsOverridden bool IsOverridden bool
InitUnchangedAddr net.Address InitUnchangedAddr net.Address
InitChangedAddr net.Address InitChangedAddr net.Address
@@ -357,7 +472,7 @@ func (r *PacketReader) ReadMultiBuffer() (buf.MultiBuffer, error) {
} }
udpAddr := d.(*net.UDPAddr) udpAddr := d.(*net.UDPAddr)
sourceAddr := net.IPAddress(udpAddr.IP) sourceAddr := net.IPAddress(udpAddr.IP)
if isBlockedAddress(r.BlockedIPMatcher, sourceAddr) { if r.Handler.applyFinalRules(net.Network_UDP, sourceAddr, net.Port(udpAddr.Port), r.DefaultRule) == RuleAction_Block {
continue continue
} }
b.Resize(0, int32(n)) b.Resize(0, int32(n))
@@ -382,7 +497,7 @@ func (r *PacketReader) ReadMultiBuffer() (buf.MultiBuffer, error) {
} }
// DialDest means the dial target used in the dialer when creating conn // DialDest means the dial target used in the dialer when creating conn
func NewPacketWriter(conn net.Conn, h *Handler, UDPOverride net.Destination, DialDest net.Destination, blockedIPMatcher geodata.IPMatcher) buf.Writer { func NewPacketWriter(conn net.Conn, h *Handler, defaultRule *FinalRule, UDPOverride net.Destination, DialDest net.Destination) buf.Writer {
iConn := conn iConn := conn
statConn, ok := iConn.(*stat.CounterConnection) statConn, ok := iConn.(*stat.CounterConnection)
if ok { if ok {
@@ -403,7 +518,7 @@ func NewPacketWriter(conn net.Conn, h *Handler, UDPOverride net.Destination, Dia
PacketConnWrapper: c, PacketConnWrapper: c,
Counter: counter, Counter: counter,
Handler: h, Handler: h,
BlockedIPMatcher: blockedIPMatcher, DefaultRule: defaultRule,
UDPOverride: UDPOverride, UDPOverride: UDPOverride,
ResolvedUDPAddr: resolvedUDPAddr, ResolvedUDPAddr: resolvedUDPAddr,
LocalAddr: net.DestinationFromAddr(conn.LocalAddr()).Address, LocalAddr: net.DestinationFromAddr(conn.LocalAddr()).Address,
@@ -417,8 +532,8 @@ type PacketWriter struct {
*internet.PacketConnWrapper *internet.PacketConnWrapper
stats.Counter stats.Counter
*Handler *Handler
BlockedIPMatcher geodata.IPMatcher DefaultRule *FinalRule
UDPOverride net.Destination UDPOverride net.Destination
// Dest of udp packets might be a domain, we will resolve them to IP // Dest of udp packets might be a domain, we will resolve them to IP
// But resolver will return a random one if the domain has many IPs // But resolver will return a random one if the domain has many IPs
@@ -476,7 +591,7 @@ func (w *PacketWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {
} }
} }
} }
if isBlockedAddress(w.BlockedIPMatcher, b.UDP.Address) { if w.applyFinalRules(net.Network_UDP, b.UDP.Address, b.UDP.Port, w.DefaultRule) == RuleAction_Block {
b.Release() b.Release()
continue continue
} }

View File

@@ -71,7 +71,7 @@ func TestCommanderListenConfigurationItem(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
Tag: "default-outbound", Tag: "default-outbound",
ProxySettings: serial.ToTypedMessage(&freedom.Config{}), ProxySettings: serial.ToTypedMessage(&freedom.Config{FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}}}),
}, },
}, },
} }
@@ -166,7 +166,7 @@ func TestCommanderRemoveHandler(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
Tag: "default-outbound", Tag: "default-outbound",
ProxySettings: serial.ToTypedMessage(&freedom.Config{}), ProxySettings: serial.ToTypedMessage(&freedom.Config{FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}}}),
}, },
}, },
} }
@@ -262,7 +262,7 @@ func TestCommanderListHandlers(t *testing.T) {
{ {
Tag: "default-outbound", Tag: "default-outbound",
SenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{}), SenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{}),
ProxySettings: serial.ToTypedMessage(&freedom.Config{}), ProxySettings: serial.ToTypedMessage(&freedom.Config{FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}}}),
}, },
}, },
} }
@@ -388,7 +388,7 @@ func TestCommanderAddRemoveUser(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },
@@ -428,7 +428,7 @@ func TestCommanderAddRemoveUser(t *testing.T) {
Receiver: &protocol.ServerEndpoint{ Receiver: &protocol.ServerEndpoint{
Address: net.NewIPOrDomain(net.LocalHostIP), Address: net.NewIPOrDomain(net.LocalHostIP),
Port: uint32(serverPort), Port: uint32(serverPort),
User: &protocol.User{ User: &protocol.User{
Account: serial.ToTypedMessage(&vmess.Account{ Account: serial.ToTypedMessage(&vmess.Account{
Id: u2.String(), Id: u2.String(),
SecuritySettings: &protocol.SecurityConfig{ SecuritySettings: &protocol.SecurityConfig{
@@ -576,7 +576,7 @@ func TestCommanderStats(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },
@@ -603,7 +603,7 @@ func TestCommanderStats(t *testing.T) {
Receiver: &protocol.ServerEndpoint{ Receiver: &protocol.ServerEndpoint{
Address: net.NewIPOrDomain(net.LocalHostIP), Address: net.NewIPOrDomain(net.LocalHostIP),
Port: uint32(serverPort), Port: uint32(serverPort),
User: &protocol.User{ User: &protocol.User{
Account: serial.ToTypedMessage(&vmess.Account{ Account: serial.ToTypedMessage(&vmess.Account{
Id: userID.String(), Id: userID.String(),
SecuritySettings: &protocol.SecurityConfig{ SecuritySettings: &protocol.SecurityConfig{

View File

@@ -60,7 +60,7 @@ func TestDokodemoTCP(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },
@@ -160,7 +160,7 @@ func TestDokodemoUDP(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },

View File

@@ -62,7 +62,7 @@ func TestPassiveConnection(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },
@@ -123,7 +123,7 @@ func TestProxy(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },
@@ -152,7 +152,7 @@ func TestProxy(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },
@@ -252,7 +252,7 @@ func TestProxyOverKCP(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },
@@ -281,7 +281,7 @@ func TestProxyOverKCP(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
SenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{ SenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{
StreamSettings: &internet.StreamConfig{ StreamSettings: &internet.StreamConfig{
@@ -400,7 +400,7 @@ func TestBlackhole(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
Tag: "direct", Tag: "direct",
ProxySettings: serial.ToTypedMessage(&freedom.Config{}), ProxySettings: serial.ToTypedMessage(&freedom.Config{FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}}}),
}, },
{ {
Tag: "blocked", Tag: "blocked",
@@ -515,7 +515,7 @@ func TestUDPConnection(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },
@@ -580,7 +580,7 @@ func TestDomainSniffing(t *testing.T) {
}, },
{ {
Tag: "direct", Tag: "direct",
ProxySettings: serial.ToTypedMessage(&freedom.Config{}), ProxySettings: serial.ToTypedMessage(&freedom.Config{FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}}}),
}, },
}, },
App: []*serial.TypedMessage{ App: []*serial.TypedMessage{
@@ -667,7 +667,7 @@ func TestDialXray(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },

View File

@@ -48,7 +48,7 @@ func TestHttpConformance(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },
@@ -111,7 +111,7 @@ func TestHttpError(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },
@@ -161,7 +161,7 @@ func TestHTTPConnectMethod(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },
@@ -243,7 +243,7 @@ func TestHttpPost(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },
@@ -315,7 +315,7 @@ func TestHttpBasicAuth(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },

View File

@@ -63,7 +63,7 @@ func TestMetrics(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
Tag: "default-outbound", Tag: "default-outbound",
ProxySettings: serial.ToTypedMessage(&freedom.Config{}), ProxySettings: serial.ToTypedMessage(&freedom.Config{FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}}}),
}, },
}, },
} }

View File

@@ -85,7 +85,7 @@ func TestVMessClosing(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },
@@ -193,7 +193,7 @@ func TestZeroBuffer(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },

View File

@@ -151,7 +151,7 @@ func TestReverseProxy(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
Tag: "freedom", Tag: "freedom",
ProxySettings: serial.ToTypedMessage(&freedom.Config{}), ProxySettings: serial.ToTypedMessage(&freedom.Config{FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}}}),
}, },
{ {
Tag: "reverse", Tag: "reverse",
@@ -340,7 +340,7 @@ func TestReverseProxyLongRunning(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
Tag: "freedom", Tag: "freedom",
ProxySettings: serial.ToTypedMessage(&freedom.Config{}), ProxySettings: serial.ToTypedMessage(&freedom.Config{FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}}}),
}, },
{ {
Tag: "reverse", Tag: "reverse",

View File

@@ -82,7 +82,7 @@ func testShadowsocks2022Tcp(t *testing.T, method string, password string) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },
@@ -167,7 +167,7 @@ func testShadowsocks2022Udp(t *testing.T, method string, password string) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },

View File

@@ -53,7 +53,7 @@ func TestShadowsocksChaCha20Poly1305TCP(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },
@@ -141,7 +141,7 @@ func TestShadowsocksAES256GCMTCP(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },
@@ -236,7 +236,7 @@ func TestShadowsocksAES128GCMUDP(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },
@@ -330,7 +330,7 @@ func TestShadowsocksAES128GCMUDPMux(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },
@@ -425,7 +425,7 @@ func TestShadowsocksNone(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },

View File

@@ -51,7 +51,7 @@ func TestSocksBridgeTCP(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },
@@ -128,7 +128,7 @@ func TestSocksWithHttpRequest(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },
@@ -217,7 +217,7 @@ func TestSocksBridageUDP(t *testing.T) {
}, },
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{}), ProxySettings: serial.ToTypedMessage(&freedom.Config{FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}}}),
}, },
}, },
} }
@@ -332,7 +332,7 @@ func TestSocksBridageUDPWithRouting(t *testing.T) {
}, },
{ {
Tag: "out", Tag: "out",
ProxySettings: serial.ToTypedMessage(&freedom.Config{}), ProxySettings: serial.ToTypedMessage(&freedom.Config{FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}}}),
}, },
}, },
} }
@@ -429,7 +429,7 @@ func TestSocksConformanceMod(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },

View File

@@ -69,7 +69,7 @@ func TestSimpleTLSConnection(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },
@@ -182,7 +182,7 @@ func TestAutoIssuingCertificate(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },
@@ -287,7 +287,7 @@ func TestTLSOverKCP(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },
@@ -387,7 +387,7 @@ func TestTLSOverWebSocket(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },
@@ -503,7 +503,7 @@ func TestGRPC(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },
@@ -619,7 +619,7 @@ func TestGRPCMultiMode(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },
@@ -728,7 +728,7 @@ func TestSimpleTLSConnectionPinned(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },
@@ -827,7 +827,7 @@ func TestSimpleTLSConnectionPinnedWrongCert(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },
@@ -925,7 +925,7 @@ func TestUTLSConnectionPinned(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },
@@ -1025,7 +1025,7 @@ func TestUTLSConnectionPinnedWrongCert(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },

View File

@@ -63,7 +63,7 @@ func TestHTTPConnectionHeader(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },

View File

@@ -67,7 +67,7 @@ func TestVless(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },
@@ -172,7 +172,7 @@ func TestVlessTls(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },
@@ -295,7 +295,7 @@ func TestVlessXtlsVision(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },
@@ -427,7 +427,7 @@ func TestVlessXtlsVisionReality(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },
@@ -566,7 +566,7 @@ func TestVlessRealityFingerprints(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },

View File

@@ -62,7 +62,7 @@ func TestVMessGCM(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },
@@ -162,7 +162,7 @@ func TestVMessGCMReadv(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },
@@ -265,7 +265,7 @@ func TestVMessGCMUDP(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },
@@ -362,7 +362,7 @@ func TestVMessChacha20(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },
@@ -460,7 +460,7 @@ func TestVMessNone(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },
@@ -560,7 +560,7 @@ func TestVMessKCP(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },
@@ -665,7 +665,7 @@ func TestVMessKCPLarge(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },
@@ -771,7 +771,7 @@ func TestVMessGCMMux(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },
@@ -884,7 +884,7 @@ func TestVMessGCMMuxUDP(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },
@@ -1007,7 +1007,7 @@ func TestVMessZero(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },
@@ -1104,7 +1104,7 @@ func TestVMessGCMLengthAuth(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },
@@ -1206,7 +1206,7 @@ func TestVMessGCMLengthAuthPlusNoTerminationSignal(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },

View File

@@ -63,7 +63,7 @@ func TestWireguard(t *testing.T) {
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ {
ProxySettings: serial.ToTypedMessage(&freedom.Config{ ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
}), }),
}, },
}, },

View File

@@ -279,7 +279,7 @@ func runVLESSRealityCase(t *testing.T, bin string, mode trafficMode, payloadSize
}, },
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ProxySettings: serial.ToTypedMessage(&freedom.Config{ {ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
})}, })},
}, },
}) })
@@ -399,7 +399,7 @@ func runHysteria2Case(t *testing.T, bin string, mode trafficMode, payloadSize in
}, },
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ProxySettings: serial.ToTypedMessage(&freedom.Config{ {ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
})}, })},
}, },
}) })
@@ -517,7 +517,7 @@ func runVLesseEncCase(t *testing.T, bin string, mode trafficMode, payloadSize in
}, },
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ProxySettings: serial.ToTypedMessage(&freedom.Config{ {ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
})}, })},
}, },
}) })
@@ -617,7 +617,7 @@ func runVLESSXHTTPCase(t *testing.T, bin string, mode trafficMode, payloadSize i
}, },
Outbound: []*core.OutboundHandlerConfig{ Outbound: []*core.OutboundHandlerConfig{
{ProxySettings: serial.ToTypedMessage(&freedom.Config{ {ProxySettings: serial.ToTypedMessage(&freedom.Config{
IpsBlocked: &freedom.IPRules{}, FinalRules: []*freedom.FinalRuleConfig{{Action: freedom.RuleAction_Allow}},
})}, })},
}, },
}) })