mirror of
https://github.com/daeuniverse/dae.git
synced 2024-12-23 01:14:46 +07:00
feat: support must_xxx outbounds
This commit is contained in:
parent
3e55f85d91
commit
006b7fbfd2
@ -64,14 +64,13 @@ const (
|
|||||||
OutboundDirect OutboundIndex = iota
|
OutboundDirect OutboundIndex = iota
|
||||||
OutboundBlock
|
OutboundBlock
|
||||||
|
|
||||||
OutboundMustDirect OutboundIndex = 0xFC
|
|
||||||
OutboundControlPlaneRouting OutboundIndex = 0xFD
|
OutboundControlPlaneRouting OutboundIndex = 0xFD
|
||||||
OutboundLogicalOr OutboundIndex = 0xFE
|
OutboundLogicalOr OutboundIndex = 0xFE
|
||||||
OutboundLogicalAnd OutboundIndex = 0xFF
|
OutboundLogicalAnd OutboundIndex = 0xFF
|
||||||
OutboundLogicalMask OutboundIndex = 0xFE
|
OutboundLogicalMask OutboundIndex = 0xFE
|
||||||
|
|
||||||
OutboundMax = OutboundLogicalAnd
|
OutboundMax = OutboundLogicalAnd
|
||||||
OutboundUserDefinedMax = OutboundMustDirect - 1
|
OutboundUserDefinedMax = OutboundControlPlaneRouting - 1
|
||||||
)
|
)
|
||||||
|
|
||||||
func (i OutboundIndex) String() string {
|
func (i OutboundIndex) String() string {
|
||||||
@ -80,8 +79,6 @@ func (i OutboundIndex) String() string {
|
|||||||
return "direct"
|
return "direct"
|
||||||
case OutboundBlock:
|
case OutboundBlock:
|
||||||
return "block"
|
return "block"
|
||||||
case OutboundMustDirect:
|
|
||||||
return "must_direct"
|
|
||||||
case OutboundControlPlaneRouting:
|
case OutboundControlPlaneRouting:
|
||||||
return "<Control Plane Routing>"
|
return "<Control Plane Routing>"
|
||||||
case OutboundLogicalOr:
|
case OutboundLogicalOr:
|
||||||
|
@ -112,6 +112,12 @@ func (b *RequestMatcherBuilder) addFallback(fallbackOutbound config.FunctionOrSt
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if upstream.Must {
|
||||||
|
return fmt.Errorf("unsupported param: must")
|
||||||
|
}
|
||||||
|
if upstream.Mark != 0 {
|
||||||
|
return fmt.Errorf("unsupported param: mark")
|
||||||
|
}
|
||||||
upstreamId, err := b.upstreamToId(upstream.Name)
|
upstreamId, err := b.upstreamToId(upstream.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -195,6 +195,12 @@ func (b *ResponseMatcherBuilder) addFallback(fallbackOutbound config.FunctionOrS
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if upstream.Must {
|
||||||
|
return fmt.Errorf("unsupported param: must")
|
||||||
|
}
|
||||||
|
if upstream.Mark != 0 {
|
||||||
|
return fmt.Errorf("unsupported param: mark")
|
||||||
|
}
|
||||||
upstreamId, err := b.upstreamToId(upstream.Name)
|
upstreamId, err := b.upstreamToId(upstream.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -7,11 +7,11 @@ package domain_matcher
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
"github.com/daeuniverse/dae/common/consts"
|
"github.com/daeuniverse/dae/common/consts"
|
||||||
"github.com/daeuniverse/dae/component/routing"
|
"github.com/daeuniverse/dae/component/routing"
|
||||||
"github.com/daeuniverse/dae/config"
|
"github.com/daeuniverse/dae/config"
|
||||||
"github.com/daeuniverse/dae/pkg/config_parser"
|
"github.com/daeuniverse/dae/pkg/config_parser"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
"hash/fnv"
|
"hash/fnv"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"reflect"
|
"reflect"
|
||||||
@ -132,7 +132,7 @@ func getDomain() (simulatedDomainSet []routing.DomainSet, err error) {
|
|||||||
sections, err := config_parser.Parse(`
|
sections, err := config_parser.Parse(`
|
||||||
routing {
|
routing {
|
||||||
domain(geosite:bing)->us
|
domain(geosite:bing)->us
|
||||||
domain(full:dns.google) -> direct
|
domain(full:dns.google.com) -> direct
|
||||||
domain(geosite:category-ads-all) -> block
|
domain(geosite:category-ads-all) -> block
|
||||||
domain(geosite:cn) -> direct
|
domain(geosite:cn) -> direct
|
||||||
}`)
|
}`)
|
||||||
|
@ -7,9 +7,9 @@ package routing
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
"github.com/daeuniverse/dae/common/consts"
|
"github.com/daeuniverse/dae/common/consts"
|
||||||
"github.com/daeuniverse/dae/pkg/config_parser"
|
"github.com/daeuniverse/dae/pkg/config_parser"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
"strconv"
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -22,6 +22,7 @@ type DomainSet struct {
|
|||||||
type Outbound struct {
|
type Outbound struct {
|
||||||
Name string
|
Name string
|
||||||
Mark uint32
|
Mark uint32
|
||||||
|
Must bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type RulesBuilder struct {
|
type RulesBuilder struct {
|
||||||
@ -62,6 +63,7 @@ func (b *RulesBuilder) Apply(rules []*config_parser.RoutingRule) (err error) {
|
|||||||
overrideOutbound := &Outbound{
|
overrideOutbound := &Outbound{
|
||||||
Name: consts.OutboundLogicalOr.String(),
|
Name: consts.OutboundLogicalOr.String(),
|
||||||
Mark: outbound.Mark,
|
Mark: outbound.Mark,
|
||||||
|
Must: outbound.Must,
|
||||||
}
|
}
|
||||||
if jMatchSet == len(keyOrder)-1 {
|
if jMatchSet == len(keyOrder)-1 {
|
||||||
overrideOutbound.Name = consts.OutboundLogicalAnd.String()
|
overrideOutbound.Name = consts.OutboundLogicalAnd.String()
|
||||||
@ -103,6 +105,7 @@ func ParseOutbound(rawOutbound *config_parser.Function) (outbound *Outbound, err
|
|||||||
outbound = &Outbound{
|
outbound = &Outbound{
|
||||||
Name: rawOutbound.Name,
|
Name: rawOutbound.Name,
|
||||||
Mark: 0,
|
Mark: 0,
|
||||||
|
Must: false,
|
||||||
}
|
}
|
||||||
for _, p := range rawOutbound.Params {
|
for _, p := range rawOutbound.Params {
|
||||||
switch p.Key {
|
switch p.Key {
|
||||||
@ -113,8 +116,14 @@ func ParseOutbound(rawOutbound *config_parser.Function) (outbound *Outbound, err
|
|||||||
return nil, fmt.Errorf("failed to parse mark: %v", err)
|
return nil, fmt.Errorf("failed to parse mark: %v", err)
|
||||||
}
|
}
|
||||||
outbound.Mark = uint32(_mark)
|
outbound.Mark = uint32(_mark)
|
||||||
|
case "":
|
||||||
|
if p.Val == "must" {
|
||||||
|
outbound.Must = true
|
||||||
|
} else {
|
||||||
|
return nil, fmt.Errorf("unknown outbound param: %v", p.Val)
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("unknown outbound param: %v", p.Key)
|
return nil, fmt.Errorf("unknown outbound param key: %v", p.Key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return outbound, nil
|
return outbound, nil
|
||||||
|
@ -18,7 +18,7 @@ type Global struct {
|
|||||||
// We use DirectTcpCheckUrl to check (tcp)*(ipv4/ipv6) connectivity for direct.
|
// We use DirectTcpCheckUrl to check (tcp)*(ipv4/ipv6) connectivity for direct.
|
||||||
//DirectTcpCheckUrl string `mapstructure:"direct_tcp_check_url" default:"http://www.qualcomm.cn/generate_204"`
|
//DirectTcpCheckUrl string `mapstructure:"direct_tcp_check_url" default:"http://www.qualcomm.cn/generate_204"`
|
||||||
TcpCheckUrl string `mapstructure:"tcp_check_url" default:"http://keep-alv.google.com/generate_204"`
|
TcpCheckUrl string `mapstructure:"tcp_check_url" default:"http://keep-alv.google.com/generate_204"`
|
||||||
UdpCheckDns string `mapstructure:"udp_check_dns" default:"dns.google:53"`
|
UdpCheckDns string `mapstructure:"udp_check_dns" default:"dns.google.com:53"`
|
||||||
CheckInterval time.Duration `mapstructure:"check_interval" default:"30s"`
|
CheckInterval time.Duration `mapstructure:"check_interval" default:"30s"`
|
||||||
CheckTolerance time.Duration `mapstructure:"check_tolerance" default:"0"`
|
CheckTolerance time.Duration `mapstructure:"check_tolerance" default:"0"`
|
||||||
LanInterface []string `mapstructure:"lan_interface"`
|
LanInterface []string `mapstructure:"lan_interface"`
|
||||||
|
@ -7,12 +7,15 @@ package config
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/daeuniverse/dae/common/consts"
|
"github.com/daeuniverse/dae/common/consts"
|
||||||
|
"github.com/daeuniverse/dae/pkg/config_parser"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type patch func(params *Config) error
|
type patch func(params *Config) error
|
||||||
|
|
||||||
var patches = []patch{
|
var patches = []patch{
|
||||||
patchEmptyDns,
|
patchEmptyDns,
|
||||||
|
patchMustOutbound,
|
||||||
}
|
}
|
||||||
|
|
||||||
func patchEmptyDns(params *Config) error {
|
func patchEmptyDns(params *Config) error {
|
||||||
@ -24,3 +27,22 @@ func patchEmptyDns(params *Config) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func patchMustOutbound(params *Config) error {
|
||||||
|
for i := range params.Routing.Rules {
|
||||||
|
if strings.HasPrefix(params.Routing.Rules[i].Outbound.Name, "must_") {
|
||||||
|
params.Routing.Rules[i].Outbound.Name = strings.TrimPrefix(params.Routing.Rules[i].Outbound.Name, "must_")
|
||||||
|
params.Routing.Rules[i].Outbound.Params = append(params.Routing.Rules[i].Outbound.Params, &config_parser.Param{
|
||||||
|
Val: "must",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if f := FunctionOrStringToFunction(params.Routing.Fallback); strings.HasPrefix(f.Name, "must_") {
|
||||||
|
f.Name = strings.TrimPrefix(f.Name, "must_")
|
||||||
|
f.Params = append(f.Params, &config_parser.Param{
|
||||||
|
Val: "must",
|
||||||
|
})
|
||||||
|
params.Routing.Fallback = f
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -757,10 +757,6 @@ func (c *ControlPlane) chooseBestDnsDialer(
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// Already "must direct".
|
|
||||||
if outboundIndex == consts.OutboundMustDirect {
|
|
||||||
outboundIndex = consts.OutboundDirect
|
|
||||||
}
|
|
||||||
if int(outboundIndex) >= len(c.outbounds) {
|
if int(outboundIndex) >= len(c.outbounds) {
|
||||||
return nil, fmt.Errorf("bad outbound index: %v", outboundIndex)
|
return nil, fmt.Errorf("bad outbound index: %v", outboundIndex)
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,6 @@
|
|||||||
|
|
||||||
#define OUTBOUND_DIRECT 0
|
#define OUTBOUND_DIRECT 0
|
||||||
#define OUTBOUND_BLOCK 1
|
#define OUTBOUND_BLOCK 1
|
||||||
#define OUTBOUND_MUST_DIRECT 0xFC
|
|
||||||
#define OUTBOUND_CONTROL_PLANE_ROUTING 0xFD
|
#define OUTBOUND_CONTROL_PLANE_ROUTING 0xFD
|
||||||
#define OUTBOUND_LOGICAL_OR 0xFE
|
#define OUTBOUND_LOGICAL_OR 0xFE
|
||||||
#define OUTBOUND_LOGICAL_AND 0xFF
|
#define OUTBOUND_LOGICAL_AND 0xFF
|
||||||
@ -135,6 +134,7 @@ struct ip_port {
|
|||||||
|
|
||||||
struct routing_result {
|
struct routing_result {
|
||||||
__u32 mark;
|
__u32 mark;
|
||||||
|
__u8 must;
|
||||||
__u8 mac[6];
|
__u8 mac[6];
|
||||||
__u8 outbound;
|
__u8 outbound;
|
||||||
__u8 pname[TASK_COMM_LEN];
|
__u8 pname[TASK_COMM_LEN];
|
||||||
@ -307,7 +307,7 @@ struct match_set {
|
|||||||
bool not ; // A subrule flag (this is not a match_set flag).
|
bool not ; // A subrule flag (this is not a match_set flag).
|
||||||
enum MatchType type;
|
enum MatchType type;
|
||||||
__u8 outbound; // User-defined value range is [0, 252].
|
__u8 outbound; // User-defined value range is [0, 252].
|
||||||
__u8 unused;
|
bool must;
|
||||||
__u32 mark;
|
__u32 mark;
|
||||||
};
|
};
|
||||||
struct {
|
struct {
|
||||||
@ -1133,11 +1133,13 @@ routing(const __u32 flag[6], const void *l4hdr, const __be32 saddr[4],
|
|||||||
|
|
||||||
// DNS requests should routed by control plane if outbound is not
|
// DNS requests should routed by control plane if outbound is not
|
||||||
// must_direct.
|
// must_direct.
|
||||||
if (match_set->outbound != OUTBOUND_MUST_DIRECT && h_dport == 53 &&
|
if (!match_set->must && h_dport == 53 &&
|
||||||
_l4proto_type == L4ProtoType_UDP) {
|
_l4proto_type == L4ProtoType_UDP) {
|
||||||
return OUTBOUND_CONTROL_PLANE_ROUTING | (match_set->mark << 8);
|
return (__s64)OUTBOUND_CONTROL_PLANE_ROUTING |
|
||||||
|
((__s64)match_set->mark << 8) | ((__s64)match_set->must << 40);
|
||||||
}
|
}
|
||||||
return match_set->outbound | (match_set->mark << 8);
|
return (__s64)match_set->outbound | ((__s64)match_set->mark << 8) |
|
||||||
|
((__s64)match_set->must << 40);
|
||||||
}
|
}
|
||||||
bad_rule = false;
|
bad_rule = false;
|
||||||
}
|
}
|
||||||
@ -1325,14 +1327,16 @@ new_connection:
|
|||||||
bpf_htonl((ethh.h_source[2] << 24) + (ethh.h_source[3] << 16) +
|
bpf_htonl((ethh.h_source[2] << 24) + (ethh.h_source[3] << 16) +
|
||||||
(ethh.h_source[4] << 8) + (ethh.h_source[5])),
|
(ethh.h_source[4] << 8) + (ethh.h_source[5])),
|
||||||
};
|
};
|
||||||
if ((ret = routing(flag, l4hdr, tuples.sip.u6_addr32, tuples.dip.u6_addr32,
|
__s64 s64_ret;
|
||||||
mac)) < 0) {
|
if ((s64_ret = routing(flag, l4hdr, tuples.sip.u6_addr32,
|
||||||
bpf_printk("shot routing: %d", ret);
|
tuples.dip.u6_addr32, mac)) < 0) {
|
||||||
|
bpf_printk("shot routing: %d", s64_ret);
|
||||||
return TC_ACT_SHOT;
|
return TC_ACT_SHOT;
|
||||||
}
|
}
|
||||||
struct routing_result routing_result = {0};
|
struct routing_result routing_result = {0};
|
||||||
routing_result.outbound = ret;
|
routing_result.outbound = s64_ret;
|
||||||
routing_result.mark = ret >> 8;
|
routing_result.mark = s64_ret >> 8;
|
||||||
|
routing_result.must = (s64_ret >> 40) & 1;
|
||||||
__builtin_memcpy(routing_result.mac, ethh.h_source,
|
__builtin_memcpy(routing_result.mac, ethh.h_source,
|
||||||
sizeof(routing_result.mac));
|
sizeof(routing_result.mac));
|
||||||
/// NOTICE: No pid pname info for LAN packet.
|
/// NOTICE: No pid pname info for LAN packet.
|
||||||
@ -1361,8 +1365,7 @@ new_connection:
|
|||||||
bpf_ntohs(tuples.dport));
|
bpf_ntohs(tuples.dport));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (routing_result.outbound == OUTBOUND_DIRECT ||
|
if (routing_result.outbound == OUTBOUND_DIRECT) {
|
||||||
routing_result.outbound == OUTBOUND_MUST_DIRECT) {
|
|
||||||
skb->mark = routing_result.mark;
|
skb->mark = routing_result.mark;
|
||||||
goto direct;
|
goto direct;
|
||||||
} else if (unlikely(routing_result.outbound == OUTBOUND_BLOCK)) {
|
} else if (unlikely(routing_result.outbound == OUTBOUND_BLOCK)) {
|
||||||
@ -1593,6 +1596,7 @@ int tproxy_wan_egress(struct __sk_buff *skb) {
|
|||||||
__builtin_memcpy(&key_src.ip, &tuples.dip, IPV6_BYTE_LENGTH);
|
__builtin_memcpy(&key_src.ip, &tuples.dip, IPV6_BYTE_LENGTH);
|
||||||
key_src.port = tcph.source;
|
key_src.port = tcph.source;
|
||||||
__u8 outbound;
|
__u8 outbound;
|
||||||
|
bool must;
|
||||||
__u32 mark;
|
__u32 mark;
|
||||||
struct pid_pname *pid_pname = NULL;
|
struct pid_pname *pid_pname = NULL;
|
||||||
if (unlikely(tcp_state_syn)) {
|
if (unlikely(tcp_state_syn)) {
|
||||||
@ -1618,14 +1622,16 @@ int tproxy_wan_egress(struct __sk_buff *skb) {
|
|||||||
bpf_htonl((ethh.h_source[2] << 24) + (ethh.h_source[3] << 16) +
|
bpf_htonl((ethh.h_source[2] << 24) + (ethh.h_source[3] << 16) +
|
||||||
(ethh.h_source[4] << 8) + (ethh.h_source[5])),
|
(ethh.h_source[4] << 8) + (ethh.h_source[5])),
|
||||||
};
|
};
|
||||||
if ((ret = routing(flag, &tcph, tuples.sip.u6_addr32,
|
__s64 s64_ret;
|
||||||
tuples.dip.u6_addr32, mac)) < 0) {
|
if ((s64_ret = routing(flag, &tcph, tuples.sip.u6_addr32,
|
||||||
bpf_printk("shot routing: %d", ret);
|
tuples.dip.u6_addr32, mac)) < 0) {
|
||||||
|
bpf_printk("shot routing: %d", s64_ret);
|
||||||
return TC_ACT_SHOT;
|
return TC_ACT_SHOT;
|
||||||
}
|
}
|
||||||
|
|
||||||
outbound = ret;
|
outbound = s64_ret;
|
||||||
mark = ret >> 8;
|
mark = s64_ret >> 8;
|
||||||
|
must = (s64_ret >> 40) & 1;
|
||||||
|
|
||||||
#if defined(__DEBUG_ROUTING) || defined(__PRINT_ROUTING_RESULT)
|
#if defined(__DEBUG_ROUTING) || defined(__PRINT_ROUTING_RESULT)
|
||||||
// Print only new connection.
|
// Print only new connection.
|
||||||
@ -1646,9 +1652,10 @@ int tproxy_wan_egress(struct __sk_buff *skb) {
|
|||||||
}
|
}
|
||||||
outbound = dst->routing_result.outbound;
|
outbound = dst->routing_result.outbound;
|
||||||
mark = dst->routing_result.mark;
|
mark = dst->routing_result.mark;
|
||||||
|
must = dst->routing_result.must;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((outbound == OUTBOUND_DIRECT || outbound == OUTBOUND_MUST_DIRECT) &&
|
if (outbound == OUTBOUND_DIRECT &&
|
||||||
mark == 0 // If mark is not zero, we should re-route it, so we send it
|
mark == 0 // If mark is not zero, we should re-route it, so we send it
|
||||||
// to control plane in WAN.
|
// to control plane in WAN.
|
||||||
) {
|
) {
|
||||||
@ -1678,6 +1685,7 @@ int tproxy_wan_egress(struct __sk_buff *skb) {
|
|||||||
routing_info.port = tcph.dest;
|
routing_info.port = tcph.dest;
|
||||||
routing_info.routing_result.outbound = outbound;
|
routing_info.routing_result.outbound = outbound;
|
||||||
routing_info.routing_result.mark = mark;
|
routing_info.routing_result.mark = mark;
|
||||||
|
routing_info.routing_result.must = must;
|
||||||
__builtin_memcpy(routing_info.routing_result.mac, ethh.h_source,
|
__builtin_memcpy(routing_info.routing_result.mac, ethh.h_source,
|
||||||
sizeof(ethh.h_source));
|
sizeof(ethh.h_source));
|
||||||
if (pid_pname) {
|
if (pid_pname) {
|
||||||
@ -1726,9 +1734,10 @@ int tproxy_wan_egress(struct __sk_buff *skb) {
|
|||||||
bpf_htonl((ethh.h_source[2] << 24) + (ethh.h_source[3] << 16) +
|
bpf_htonl((ethh.h_source[2] << 24) + (ethh.h_source[3] << 16) +
|
||||||
(ethh.h_source[4] << 8) + (ethh.h_source[5])),
|
(ethh.h_source[4] << 8) + (ethh.h_source[5])),
|
||||||
};
|
};
|
||||||
if ((ret = routing(flag, &udph, tuples.sip.u6_addr32,
|
__s64 s64_ret;
|
||||||
tuples.dip.u6_addr32, mac)) < 0) {
|
if ((s64_ret = routing(flag, &udph, tuples.sip.u6_addr32,
|
||||||
bpf_printk("shot routing: %d", ret);
|
tuples.dip.u6_addr32, mac)) < 0) {
|
||||||
|
bpf_printk("shot routing: %d", s64_ret);
|
||||||
return TC_ACT_SHOT;
|
return TC_ACT_SHOT;
|
||||||
}
|
}
|
||||||
// Construct new hdr to encap.
|
// Construct new hdr to encap.
|
||||||
@ -1736,8 +1745,9 @@ int tproxy_wan_egress(struct __sk_buff *skb) {
|
|||||||
__builtin_memset(&new_hdr, 0, sizeof(new_hdr));
|
__builtin_memset(&new_hdr, 0, sizeof(new_hdr));
|
||||||
__builtin_memcpy(new_hdr.ip, &tuples.dip, IPV6_BYTE_LENGTH);
|
__builtin_memcpy(new_hdr.ip, &tuples.dip, IPV6_BYTE_LENGTH);
|
||||||
new_hdr.port = udph.dest;
|
new_hdr.port = udph.dest;
|
||||||
new_hdr.routing_result.outbound = ret;
|
new_hdr.routing_result.outbound = s64_ret;
|
||||||
new_hdr.routing_result.mark = ret >> 8;
|
new_hdr.routing_result.mark = s64_ret >> 8;
|
||||||
|
new_hdr.routing_result.must = (s64_ret >> 40) & 1;
|
||||||
__builtin_memcpy(new_hdr.routing_result.mac, ethh.h_source,
|
__builtin_memcpy(new_hdr.routing_result.mac, ethh.h_source,
|
||||||
sizeof(ethh.h_source));
|
sizeof(ethh.h_source));
|
||||||
if (pid_pname) {
|
if (pid_pname) {
|
||||||
@ -1754,8 +1764,7 @@ int tproxy_wan_egress(struct __sk_buff *skb) {
|
|||||||
bpf_ntohs(tuples.dport));
|
bpf_ntohs(tuples.dport));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ((new_hdr.routing_result.outbound == OUTBOUND_DIRECT ||
|
if (new_hdr.routing_result.outbound == OUTBOUND_DIRECT &&
|
||||||
new_hdr.routing_result.outbound == OUTBOUND_MUST_DIRECT) &&
|
|
||||||
new_hdr.routing_result.mark ==
|
new_hdr.routing_result.mark ==
|
||||||
0 // If mark is not zero, we should re-route it, so we
|
0 // If mark is not zero, we should re-route it, so we
|
||||||
// send it to control plane in WAN.
|
// send it to control plane in WAN.
|
||||||
|
@ -56,8 +56,6 @@ func NewRoutingMatcherBuilder(log *logrus.Logger, rules []*config_parser.Routing
|
|||||||
func (b *RoutingMatcherBuilder) outboundToId(outbound string) (uint8, error) {
|
func (b *RoutingMatcherBuilder) outboundToId(outbound string) (uint8, error) {
|
||||||
var outboundId uint8
|
var outboundId uint8
|
||||||
switch outbound {
|
switch outbound {
|
||||||
case consts.OutboundMustDirect.String():
|
|
||||||
outboundId = uint8(consts.OutboundMustDirect)
|
|
||||||
case consts.OutboundLogicalOr.String():
|
case consts.OutboundLogicalOr.String():
|
||||||
outboundId = uint8(consts.OutboundLogicalOr)
|
outboundId = uint8(consts.OutboundLogicalOr)
|
||||||
case consts.OutboundLogicalAnd.String():
|
case consts.OutboundLogicalAnd.String():
|
||||||
@ -95,6 +93,7 @@ func (b *RoutingMatcherBuilder) addDomain(f *config_parser.Function, key string,
|
|||||||
Not: f.Not,
|
Not: f.Not,
|
||||||
Outbound: outboundId,
|
Outbound: outboundId,
|
||||||
Mark: outbound.Mark,
|
Mark: outbound.Mark,
|
||||||
|
Must: outbound.Must,
|
||||||
})
|
})
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -119,6 +118,7 @@ func (b *RoutingMatcherBuilder) addSourceMac(f *config_parser.Function, macAddrs
|
|||||||
Not: f.Not,
|
Not: f.Not,
|
||||||
Outbound: outboundId,
|
Outbound: outboundId,
|
||||||
Mark: outbound.Mark,
|
Mark: outbound.Mark,
|
||||||
|
Must: outbound.Must,
|
||||||
}
|
}
|
||||||
binary.LittleEndian.PutUint32(set.Value[:], uint32(lpmTrieIndex))
|
binary.LittleEndian.PutUint32(set.Value[:], uint32(lpmTrieIndex))
|
||||||
b.rules = append(b.rules, set)
|
b.rules = append(b.rules, set)
|
||||||
@ -138,6 +138,7 @@ func (b *RoutingMatcherBuilder) addIp(f *config_parser.Function, values []netip.
|
|||||||
Not: f.Not,
|
Not: f.Not,
|
||||||
Outbound: outboundId,
|
Outbound: outboundId,
|
||||||
Mark: outbound.Mark,
|
Mark: outbound.Mark,
|
||||||
|
Must: outbound.Must,
|
||||||
}
|
}
|
||||||
binary.LittleEndian.PutUint32(set.Value[:], uint32(lpmTrieIndex))
|
binary.LittleEndian.PutUint32(set.Value[:], uint32(lpmTrieIndex))
|
||||||
b.rules = append(b.rules, set)
|
b.rules = append(b.rules, set)
|
||||||
@ -163,6 +164,7 @@ func (b *RoutingMatcherBuilder) addPort(f *config_parser.Function, values [][2]u
|
|||||||
Not: f.Not,
|
Not: f.Not,
|
||||||
Outbound: outboundId,
|
Outbound: outboundId,
|
||||||
Mark: outbound.Mark,
|
Mark: outbound.Mark,
|
||||||
|
Must: outbound.Must,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -181,6 +183,7 @@ func (b *RoutingMatcherBuilder) addSourceIp(f *config_parser.Function, values []
|
|||||||
Not: f.Not,
|
Not: f.Not,
|
||||||
Outbound: outboundId,
|
Outbound: outboundId,
|
||||||
Mark: outbound.Mark,
|
Mark: outbound.Mark,
|
||||||
|
Must: outbound.Must,
|
||||||
}
|
}
|
||||||
binary.LittleEndian.PutUint32(set.Value[:], uint32(lpmTrieIndex))
|
binary.LittleEndian.PutUint32(set.Value[:], uint32(lpmTrieIndex))
|
||||||
b.rules = append(b.rules, set)
|
b.rules = append(b.rules, set)
|
||||||
@ -206,6 +209,7 @@ func (b *RoutingMatcherBuilder) addSourcePort(f *config_parser.Function, values
|
|||||||
Not: f.Not,
|
Not: f.Not,
|
||||||
Outbound: outboundId,
|
Outbound: outboundId,
|
||||||
Mark: outbound.Mark,
|
Mark: outbound.Mark,
|
||||||
|
Must: outbound.Must,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -222,6 +226,7 @@ func (b *RoutingMatcherBuilder) addL4Proto(f *config_parser.Function, values con
|
|||||||
Not: f.Not,
|
Not: f.Not,
|
||||||
Outbound: outboundId,
|
Outbound: outboundId,
|
||||||
Mark: outbound.Mark,
|
Mark: outbound.Mark,
|
||||||
|
Must: outbound.Must,
|
||||||
})
|
})
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -237,6 +242,7 @@ func (b *RoutingMatcherBuilder) addIpVersion(f *config_parser.Function, values c
|
|||||||
Not: f.Not,
|
Not: f.Not,
|
||||||
Outbound: outboundId,
|
Outbound: outboundId,
|
||||||
Mark: outbound.Mark,
|
Mark: outbound.Mark,
|
||||||
|
Must: outbound.Must,
|
||||||
})
|
})
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -256,6 +262,7 @@ func (b *RoutingMatcherBuilder) addProcessName(f *config_parser.Function, values
|
|||||||
Not: f.Not,
|
Not: f.Not,
|
||||||
Outbound: outboundId,
|
Outbound: outboundId,
|
||||||
Mark: outbound.Mark,
|
Mark: outbound.Mark,
|
||||||
|
Must: outbound.Must,
|
||||||
}
|
}
|
||||||
copy(matchSet.Value[:], value[:])
|
copy(matchSet.Value[:], value[:])
|
||||||
b.rules = append(b.rules, matchSet)
|
b.rules = append(b.rules, matchSet)
|
||||||
@ -276,6 +283,7 @@ func (b *RoutingMatcherBuilder) addFallback(fallbackOutbound config.FunctionOrSt
|
|||||||
Type: uint8(consts.MatchType_Fallback),
|
Type: uint8(consts.MatchType_Fallback),
|
||||||
Outbound: outboundId,
|
Outbound: outboundId,
|
||||||
Mark: outbound.Mark,
|
Mark: outbound.Mark,
|
||||||
|
Must: outbound.Must,
|
||||||
})
|
})
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -70,8 +70,6 @@ func (c *ControlPlane) handleConn(lConn net.Conn) (err error) {
|
|||||||
|
|
||||||
switch outboundIndex {
|
switch outboundIndex {
|
||||||
case consts.OutboundDirect:
|
case consts.OutboundDirect:
|
||||||
case consts.OutboundMustDirect:
|
|
||||||
outboundIndex = consts.OutboundDirect
|
|
||||||
case consts.OutboundControlPlaneRouting:
|
case consts.OutboundControlPlaneRouting:
|
||||||
if outboundIndex, routingResult.Mark, err = c.Route(src, dst, domain, consts.L4ProtoType_TCP, routingResult); err != nil {
|
if outboundIndex, routingResult.Mark, err = c.Route(src, dst, domain, consts.L4ProtoType_TCP, routingResult); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -143,11 +143,11 @@ func (c *ControlPlane) handlePkt(lConn *net.UDPConn, data []byte, src, pktDst, r
|
|||||||
outboundIndex = consts.OutboundControlPlaneRouting
|
outboundIndex = consts.OutboundControlPlaneRouting
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if routingResult.Must > 0 {
|
||||||
|
isDns = false // Regard as plain traffic.
|
||||||
|
}
|
||||||
switch outboundIndex {
|
switch outboundIndex {
|
||||||
case consts.OutboundDirect:
|
case consts.OutboundDirect:
|
||||||
case consts.OutboundMustDirect:
|
|
||||||
outboundIndex = consts.OutboundDirect
|
|
||||||
isDns = false // Regard as plain traffic.
|
|
||||||
case consts.OutboundControlPlaneRouting:
|
case consts.OutboundControlPlaneRouting:
|
||||||
if isDns {
|
if isDns {
|
||||||
// Routing of DNS packets are managed by DNS controller.
|
// Routing of DNS packets are managed by DNS controller.
|
||||||
|
@ -15,7 +15,7 @@ dns {
|
|||||||
# If dial_mode is "ip", the upstream DNS answer SHOULD NOT be polluted, so domestic public DNS is not recommended.
|
# If dial_mode is "ip", the upstream DNS answer SHOULD NOT be polluted, so domestic public DNS is not recommended.
|
||||||
|
|
||||||
alidns: 'udp://dns.alidns.com:53'
|
alidns: 'udp://dns.alidns.com:53'
|
||||||
googledns: 'tcp+udp://dns.google:53'
|
googledns: 'tcp+udp://dns.google.com:53'
|
||||||
}
|
}
|
||||||
# The routing format of 'request' and 'response' is similar with section 'routing'.
|
# The routing format of 'request' and 'response' is similar with section 'routing'.
|
||||||
# See https://github.com/daeuniverse/dae/blob/main/docs/routing.md
|
# See https://github.com/daeuniverse/dae/blob/main/docs/routing.md
|
||||||
@ -64,7 +64,7 @@ dns {
|
|||||||
# Use alidns for China mainland domains and googledns for others.
|
# Use alidns for China mainland domains and googledns for others.
|
||||||
dns {
|
dns {
|
||||||
upstream {
|
upstream {
|
||||||
googledns: 'tcp+udp://dns.google:53'
|
googledns: 'tcp+udp://dns.google.com:53'
|
||||||
alidns: 'udp://dns.alidns.com:53'
|
alidns: 'udp://dns.alidns.com:53'
|
||||||
}
|
}
|
||||||
routing {
|
routing {
|
||||||
@ -84,7 +84,7 @@ dns {
|
|||||||
# Use alidns for all DNS queries and fallback to googledns if pollution result detected.
|
# Use alidns for all DNS queries and fallback to googledns if pollution result detected.
|
||||||
dns {
|
dns {
|
||||||
upstream {
|
upstream {
|
||||||
googledns: 'tcp+udp://dns.google:53'
|
googledns: 'tcp+udp://dns.google.com:53'
|
||||||
alidns: 'udp://dns.alidns.com:53'
|
alidns: 'udp://dns.alidns.com:53'
|
||||||
}
|
}
|
||||||
routing {
|
routing {
|
||||||
|
@ -137,7 +137,7 @@ subscription {
|
|||||||
# See https://github.com/daeuniverse/dae/blob/main/docs/dns.md for full examples.
|
# See https://github.com/daeuniverse/dae/blob/main/docs/dns.md for full examples.
|
||||||
dns {
|
dns {
|
||||||
upstream {
|
upstream {
|
||||||
googledns: 'tcp+udp://dns.google:53'
|
googledns: 'tcp+udp://dns.google.com:53'
|
||||||
alidns: 'udp://dns.alidns.com:53'
|
alidns: 'udp://dns.alidns.com:53'
|
||||||
}
|
}
|
||||||
routing {
|
routing {
|
||||||
|
@ -133,7 +133,7 @@ subscription {
|
|||||||
# 更多的 DNS 样例见 https://github.com/daeuniverse/dae/blob/main/docs/dns.md
|
# 更多的 DNS 样例见 https://github.com/daeuniverse/dae/blob/main/docs/dns.md
|
||||||
dns {
|
dns {
|
||||||
upstream {
|
upstream {
|
||||||
googledns: 'tcp+udp://dns.google:53'
|
googledns: 'tcp+udp://dns.google.com:53'
|
||||||
alidns: 'udp://dns.alidns.com:53'
|
alidns: 'udp://dns.alidns.com:53'
|
||||||
}
|
}
|
||||||
routing {
|
routing {
|
||||||
@ -174,7 +174,7 @@ routing {
|
|||||||
```shell
|
```shell
|
||||||
dns {
|
dns {
|
||||||
upstream {
|
upstream {
|
||||||
googledns: 'tcp+udp://dns.google:53'
|
googledns: 'tcp+udp://dns.google.com:53'
|
||||||
alidns: 'udp://dns.alidns.com:53'
|
alidns: 'udp://dns.alidns.com:53'
|
||||||
}
|
}
|
||||||
routing {
|
routing {
|
||||||
|
@ -7,13 +7,13 @@ If you use a external DNS like AdguardHome, you could refer to the following gui
|
|||||||
|
|
||||||
## External DNS on localhost
|
## External DNS on localhost
|
||||||
|
|
||||||
If you set up a external DNS on localhost, you may want to let the DNS queries to dns.google proxied. For example, if you have following configuration in AdguardHome:
|
If you set up a external DNS on localhost, you may want to let the DNS queries to dns.google.com proxied. For example, if you have following configuration in AdguardHome:
|
||||||
|
|
||||||
```
|
```
|
||||||
Listen on: the same machine with dae, port 53.
|
Listen on: the same machine with dae, port 53.
|
||||||
|
|
||||||
China mainland: udp://223.5.5.5:53
|
China mainland: udp://223.5.5.5:53
|
||||||
Others: https://dns.google/dns-query
|
Others: https://dns.google.com/dns-query
|
||||||
```
|
```
|
||||||
|
|
||||||
You should configure dae as follows:
|
You should configure dae as follows:
|
||||||
@ -26,7 +26,7 @@ You should configure dae as follows:
|
|||||||
pname(AdGuardHome) && l4proto(udp) && dport(53) -> must_direct
|
pname(AdGuardHome) && l4proto(udp) && dport(53) -> must_direct
|
||||||
```
|
```
|
||||||
|
|
||||||
And make sure domain `dns.google` will be proxied in routing rules.
|
And make sure domain `dns.google.com` will be proxied in routing rules.
|
||||||
|
|
||||||
3. Add upstream and request to section "dns".
|
3. Add upstream and request to section "dns".
|
||||||
|
|
||||||
@ -51,13 +51,13 @@ You should configure dae as follows:
|
|||||||
|
|
||||||
## External DNS on another machine in LAN
|
## External DNS on another machine in LAN
|
||||||
|
|
||||||
If you set up a external DNS on another machine in LAN, you may want to let the DNS queries to dns.google proxied. For example, if you have following configuration in AdguardHome:
|
If you set up a external DNS on another machine in LAN, you may want to let the DNS queries to dns.google.com proxied. For example, if you have following configuration in AdguardHome:
|
||||||
|
|
||||||
```
|
```
|
||||||
Listen on: 192.168.30.3:53 (mac address: 8c:16:45:36:1c:5a)
|
Listen on: 192.168.30.3:53 (mac address: 8c:16:45:36:1c:5a)
|
||||||
|
|
||||||
China mainland: udp://223.5.5.5:53
|
China mainland: udp://223.5.5.5:53
|
||||||
Others: https://dns.google/dns-query
|
Others: https://dns.google.com/dns-query
|
||||||
```
|
```
|
||||||
|
|
||||||
You should configure dae as follows:
|
You should configure dae as follows:
|
||||||
@ -72,7 +72,7 @@ You should configure dae as follows:
|
|||||||
# mac(8c:16:45:36:1c:5a) && l4proto(udp) && dport(53) -> must_direct
|
# mac(8c:16:45:36:1c:5a) && l4proto(udp) && dport(53) -> must_direct
|
||||||
```
|
```
|
||||||
|
|
||||||
And make sure domain `dns.google` will be proxied in routing rules.
|
And make sure domain `dns.google.com` will be proxied in routing rules.
|
||||||
|
|
||||||
3. Add upstream and request to section "dns".
|
3. Add upstream and request to section "dns".
|
||||||
|
|
||||||
|
@ -3,9 +3,11 @@
|
|||||||
## Examples:
|
## Examples:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
### Built-in outbounds: block, direct, must_direct
|
### Built-in outbounds: block, direct
|
||||||
# The difference between "direct" and "must_direct" is that "direct" will intercept and process DNS request (for traffic
|
# The difference between "direct" and "must_direct" is that "direct" will hijack and process DNS request (for traffic
|
||||||
# split use), but "must_direct" will not. "must_direct" is useful when there are traffic loops of DNS requests.
|
# split use), but "must_direct" will not. "must_direct" is useful when there are traffic loops of DNS requests.
|
||||||
|
# "must_direct" can be written as "direct(must)".
|
||||||
|
# Similarly, "must_groupname" is also supported to NOT hijack and process DNS traffic, which equals to "groupname(must)".
|
||||||
|
|
||||||
### fallback outbound
|
### fallback outbound
|
||||||
# If no rule matches, traffic will go through the outbound defined by fallback.
|
# If no rule matches, traffic will go through the outbound defined by fallback.
|
||||||
@ -14,7 +16,7 @@ fallback: my_group
|
|||||||
### Domain rule
|
### Domain rule
|
||||||
domain(suffix: v2raya.org) -> my_group
|
domain(suffix: v2raya.org) -> my_group
|
||||||
# equals to domain(v2raya.org) -> my_group
|
# equals to domain(v2raya.org) -> my_group
|
||||||
domain(full: dns.google) -> my_group
|
domain(full: dns.google.com) -> my_group
|
||||||
domain(keyword: facebook) -> my_group
|
domain(keyword: facebook) -> my_group
|
||||||
domain(regexp: '\.goo.*\.com$') -> my_group
|
domain(regexp: '\.goo.*\.com$') -> my_group
|
||||||
domain(geosite:category-ads) -> block
|
domain(geosite:category-ads) -> block
|
||||||
|
@ -15,7 +15,7 @@ global {
|
|||||||
# This DNS will be used to check UDP connectivity of nodes. And if dns_upstream below contains tcp, it also be used to check
|
# This DNS will be used to check UDP connectivity of nodes. And if dns_upstream below contains tcp, it also be used to check
|
||||||
# TCP DNS connectivity of nodes.
|
# TCP DNS connectivity of nodes.
|
||||||
# This DNS should have both IPv4 and IPv6 if you have double stack in local.
|
# This DNS should have both IPv4 and IPv6 if you have double stack in local.
|
||||||
udp_check_dns: 'dns.google:53'
|
udp_check_dns: 'dns.google.com:53'
|
||||||
|
|
||||||
check_interval: 30s
|
check_interval: 30s
|
||||||
|
|
||||||
@ -87,7 +87,7 @@ dns {
|
|||||||
# If dial_mode is "ip", the upstream DNS answer SHOULD NOT be polluted, so domestic public DNS is not recommended.
|
# If dial_mode is "ip", the upstream DNS answer SHOULD NOT be polluted, so domestic public DNS is not recommended.
|
||||||
|
|
||||||
alidns: 'udp://dns.alidns.com:53'
|
alidns: 'udp://dns.alidns.com:53'
|
||||||
googledns: 'tcp+udp://dns.google:53'
|
googledns: 'tcp+udp://dns.google.com:53'
|
||||||
}
|
}
|
||||||
routing {
|
routing {
|
||||||
# According to the request of dns query, decide to use which DNS upstream.
|
# According to the request of dns query, decide to use which DNS upstream.
|
||||||
|
Loading…
Reference in New Issue
Block a user