mirror of
https://github.com/daeuniverse/dae.git
synced 2025-02-22 04:29:38 +07:00
fix: ip matching problem and add control plane direct
This commit is contained in:
parent
799cd006c0
commit
14b215752f
@ -10,8 +10,7 @@ As a successor of [v2rayA](https://github.com/v2rayA/v2rayA), dae abandoned v2ra
|
||||
|
||||
## TODO
|
||||
|
||||
1. Control plane does support MAC and other matching yet.
|
||||
1. Control plane does not support MAC and other matching yet.
|
||||
1. Dns upstream. Check dns upstream and source loop (whether upstream is also a client of us) and remind user to add source rule.
|
||||
1. Control plane route.
|
||||
1. Routing performance optimization.
|
||||
1. ...
|
||||
1. ...
|
||||
|
@ -50,17 +50,17 @@ const (
|
||||
type OutboundIndex uint8
|
||||
|
||||
const (
|
||||
OutboundDirect OutboundIndex = 0
|
||||
OutboundControlPlaneRoute OutboundIndex = 0xFE
|
||||
OutboundLogicalAnd OutboundIndex = 0xFF
|
||||
OutboundDirect OutboundIndex = 0
|
||||
OutboundControlPlaneDirect OutboundIndex = 0xFE
|
||||
OutboundLogicalAnd OutboundIndex = 0xFF
|
||||
)
|
||||
|
||||
func (i OutboundIndex) String() string {
|
||||
switch i {
|
||||
case OutboundDirect:
|
||||
return "direct"
|
||||
case OutboundControlPlaneRoute:
|
||||
return "<Control Plane Route>"
|
||||
case OutboundControlPlaneDirect:
|
||||
return "<Control Plane Direct>"
|
||||
case OutboundLogicalAnd:
|
||||
return "<AND>"
|
||||
default:
|
||||
|
@ -111,26 +111,6 @@ retry_load:
|
||||
//}
|
||||
|
||||
/**/
|
||||
|
||||
rules, final, err := routing.Parse(routingA)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("routingA error:\n%w", err)
|
||||
}
|
||||
if rules, err = routing.ApplyRulesOptimizers(rules,
|
||||
&routing.RefineFunctionParamKeyOptimizer{},
|
||||
&routing.DatReaderOptimizer{Logger: log},
|
||||
&routing.MergeAndSortRulesOptimizer{},
|
||||
&routing.DeduplicateParamsOptimizer{},
|
||||
); err != nil {
|
||||
return nil, fmt.Errorf("ApplyRulesOptimizers error: \n %w", err)
|
||||
}
|
||||
if log.IsLevelEnabled(logrus.TraceLevel) {
|
||||
var debugBuilder strings.Builder
|
||||
for _, rule := range rules {
|
||||
debugBuilder.WriteString(rule.String(true))
|
||||
}
|
||||
log.Tracef("RoutingA:\n%vfinal: %v\n", debugBuilder.String(), final)
|
||||
}
|
||||
// TODO:
|
||||
d, err := dialer.NewFromLink("socks5://localhost:1080#proxy")
|
||||
if err != nil {
|
||||
@ -158,6 +138,27 @@ retry_load:
|
||||
outboundName2Id[o.Name] = uint8(i)
|
||||
}
|
||||
builder := NewRoutingMatcherBuilder(outboundName2Id, &bpf)
|
||||
|
||||
// Routing.
|
||||
rules, final, err := routing.Parse(routingA)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("routingA error:\n%w", err)
|
||||
}
|
||||
if rules, err = routing.ApplyRulesOptimizers(rules,
|
||||
&routing.RefineFunctionParamKeyOptimizer{},
|
||||
&routing.DatReaderOptimizer{Logger: log},
|
||||
&routing.MergeAndSortRulesOptimizer{},
|
||||
&routing.DeduplicateParamsOptimizer{},
|
||||
); err != nil {
|
||||
return nil, fmt.Errorf("ApplyRulesOptimizers error: \n %w", err)
|
||||
}
|
||||
if log.IsLevelEnabled(logrus.TraceLevel) {
|
||||
var debugBuilder strings.Builder
|
||||
for _, rule := range rules {
|
||||
debugBuilder.WriteString(rule.String(true))
|
||||
}
|
||||
log.Tracef("RoutingA:\n%vfinal: %v\n", debugBuilder.String(), final)
|
||||
}
|
||||
if err := routing.ApplyMatcherBuilder(builder, rules, final); err != nil {
|
||||
return nil, fmt.Errorf("ApplyMatcherBuilder: %w", err)
|
||||
}
|
||||
|
@ -47,7 +47,7 @@
|
||||
#define IPV6_MAX_EXTENSIONS 4
|
||||
|
||||
#define OUTBOUND_DIRECT 0
|
||||
#define OUTBOUND_CONTROL_PLANE_ROUTE 0xFE
|
||||
#define OUTBOUND_CONTROL_PLANE_DIRECT 0xFE
|
||||
#define OUTBOUND_LOGICAL_AND 0xFF
|
||||
|
||||
enum {
|
||||
@ -753,10 +753,6 @@ static long routing(__u8 flag[2], void *l4_hdr, __be32 saddr[4],
|
||||
h_dport = bpf_ntohs(((struct udphdr *)l4_hdr)->dest);
|
||||
h_sport = bpf_ntohs(((struct udphdr *)l4_hdr)->source);
|
||||
}
|
||||
// Redirect all DNS packet to control plane.
|
||||
if (_network == NETWORK_TYPE_UDP && h_dport == 53) {
|
||||
return OUTBOUND_CONTROL_PLANE_ROUTE;
|
||||
}
|
||||
struct lpm_key lpm_key_saddr, lpm_key_daddr, lpm_key_mac, *lpm_key;
|
||||
lpm_key_saddr.trie_key.prefixlen = IPV6_BYTE_LENGTH * 8;
|
||||
lpm_key_daddr.trie_key.prefixlen = IPV6_BYTE_LENGTH * 8;
|
||||
@ -775,7 +771,7 @@ static long routing(__u8 flag[2], void *l4_hdr, __be32 saddr[4],
|
||||
/// this branch will never hit.
|
||||
// if (domain_routing && domain_routing->epoch != *epoch) {
|
||||
// // Dirty (epoch dismatch) traffic should be routed by the control plane.
|
||||
// return OUTBOUND_CONTROL_PLANE_ROUTE;
|
||||
// return OUTBOUND_CONTROL_PLANE_DIRECT;
|
||||
// }
|
||||
|
||||
#pragma unroll
|
||||
@ -790,10 +786,10 @@ static long routing(__u8 flag[2], void *l4_hdr, __be32 saddr[4],
|
||||
}
|
||||
/// NOTICE: switch is not implemented efficiently by clang yet.
|
||||
if (likely(routing->type == ROUTING_TYPE_IP_SET)) {
|
||||
lpm_key = &lpm_key_saddr;
|
||||
lpm_key = &lpm_key_daddr;
|
||||
goto lookup_lpm;
|
||||
} else if (routing->type == ROUTING_TYPE_SOURCE_IP_SET) {
|
||||
lpm_key = &lpm_key_daddr;
|
||||
lpm_key = &lpm_key_saddr;
|
||||
lookup_lpm:
|
||||
lpm = bpf_map_lookup_elem(&lpm_array_map, &routing->index);
|
||||
if (unlikely(!lpm)) {
|
||||
@ -802,6 +798,9 @@ static long routing(__u8 flag[2], void *l4_hdr, __be32 saddr[4],
|
||||
if (!bpf_map_lookup_elem(lpm, lpm_key)) {
|
||||
// Routing not hit.
|
||||
bad_rule = true;
|
||||
bpf_printk("index: %u not hit", routing->index);
|
||||
} else {
|
||||
bpf_printk("index: %u hit", routing->index);
|
||||
}
|
||||
} else if (routing->type == ROUTING_TYPE_DOMAIN_SET) {
|
||||
// Bottleneck of insns limit.
|
||||
@ -842,7 +841,8 @@ static long routing(__u8 flag[2], void *l4_hdr, __be32 saddr[4],
|
||||
lpm_key = &lpm_key_mac;
|
||||
goto lookup_lpm;
|
||||
} else if (routing->type == ROUTING_TYPE_FINAL) {
|
||||
return routing->outbound;
|
||||
// Redirect all DNS packet to control plane.
|
||||
bad_rule = false;
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -852,11 +852,18 @@ static long routing(__u8 flag[2], void *l4_hdr, __be32 saddr[4],
|
||||
// Tail of a rule (line).
|
||||
// Decide whether to hit.
|
||||
if (!bad_rule) {
|
||||
if (routing->outbound == OUTBOUND_DIRECT && h_dport == 53 &&
|
||||
_network == NETWORK_TYPE_UDP) {
|
||||
// DNS packet should go through control plane.
|
||||
return OUTBOUND_CONTROL_PLANE_DIRECT;
|
||||
}
|
||||
return routing->outbound;
|
||||
}
|
||||
bad_rule = false;
|
||||
}
|
||||
}
|
||||
bpf_printk(
|
||||
"Did coder forget to sync common/consts/ebpf.go with enum ROUTING_TYPE?");
|
||||
return -EPERM;
|
||||
#undef _network
|
||||
#undef _ip_version
|
||||
|
@ -7,10 +7,10 @@ package control
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/cilium/ebpf"
|
||||
"github.com/v2rayA/dae/common"
|
||||
"github.com/v2rayA/dae/common/consts"
|
||||
"github.com/v2rayA/dae/component/routing"
|
||||
"github.com/cilium/ebpf"
|
||||
"net/netip"
|
||||
"strconv"
|
||||
)
|
||||
@ -88,6 +88,9 @@ func (b *RoutingMatcherBuilder) AddIp(values []netip.Prefix, outbound string) {
|
||||
}
|
||||
|
||||
func (b *RoutingMatcherBuilder) AddFinal(outbound string) {
|
||||
if b.err != nil {
|
||||
return
|
||||
}
|
||||
b.Final = outbound
|
||||
b.rules = append(b.rules, bpfRouting{
|
||||
Type: uint8(consts.RoutingType_Final),
|
||||
|
@ -37,11 +37,10 @@ func (c *ControlPlane) handleConn(lConn net.Conn) (err error) {
|
||||
|
||||
switch consts.OutboundIndex(value.Outbound) {
|
||||
case consts.OutboundDirect:
|
||||
case consts.OutboundControlPlaneRoute:
|
||||
// FIXME: check and re-route.
|
||||
case consts.OutboundControlPlaneDirect:
|
||||
value.Outbound = uint8(consts.OutboundDirect)
|
||||
c.log.Debugf("outbound: %v => %v",
|
||||
consts.OutboundControlPlaneRoute.String(),
|
||||
consts.OutboundControlPlaneDirect.String(),
|
||||
consts.OutboundIndex(value.Outbound).String(),
|
||||
)
|
||||
default:
|
||||
|
@ -91,12 +91,11 @@ func (c *ControlPlane) RelayToUDP(lConn *net.UDPConn, to netip.AddrPort, isDNS b
|
||||
func (c *ControlPlane) handlePkt(data []byte, lConn *net.UDPConn, lAddrPort netip.AddrPort, addrHdr *AddrHdr) (err error) {
|
||||
switch consts.OutboundIndex(addrHdr.Outbound) {
|
||||
case consts.OutboundDirect:
|
||||
case consts.OutboundControlPlaneRoute:
|
||||
// FIXME: check and re-route.
|
||||
case consts.OutboundControlPlaneDirect:
|
||||
addrHdr.Outbound = uint8(consts.OutboundDirect)
|
||||
|
||||
c.log.Debugf("outbound: %v => %v",
|
||||
consts.OutboundControlPlaneRoute.String(),
|
||||
consts.OutboundControlPlaneDirect.String(),
|
||||
consts.OutboundIndex(addrHdr.Outbound).String(),
|
||||
)
|
||||
default:
|
||||
|
@ -6,8 +6,8 @@
|
||||
package control
|
||||
|
||||
import (
|
||||
"github.com/v2rayA/dae/common"
|
||||
"github.com/cilium/ebpf"
|
||||
"github.com/v2rayA/dae/common"
|
||||
"net/netip"
|
||||
)
|
||||
|
||||
@ -17,7 +17,13 @@ type bpfLpmKey struct {
|
||||
}
|
||||
|
||||
func (o *bpfObjects) NewLpmMap(keys []bpfLpmKey, values []uint32) (m *ebpf.Map, err error) {
|
||||
m, err = o.UnusedLpmType.Clone()
|
||||
m, err = ebpf.NewMap(&ebpf.MapSpec{
|
||||
Type: ebpf.LPMTrie,
|
||||
Flags: o.UnusedLpmType.Flags(),
|
||||
MaxEntries: o.UnusedLpmType.MaxEntries(),
|
||||
KeySize: o.UnusedLpmType.KeySize(),
|
||||
ValueSize: o.UnusedLpmType.ValueSize(),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -35,10 +41,10 @@ func swap16(a uint16) uint16 {
|
||||
|
||||
func cidrToBpfLpmKey(prefix netip.Prefix) bpfLpmKey {
|
||||
bits := prefix.Bits()
|
||||
ip := prefix.Addr().As16()
|
||||
if prefix.Addr().Is4() {
|
||||
bits += 96
|
||||
}
|
||||
ip := prefix.Addr().As16()
|
||||
return bpfLpmKey{
|
||||
PrefixLen: uint32(bits),
|
||||
Data: common.Ipv6ByteSliceToUint32Array(ip[:]),
|
||||
|
2
main.go
2
main.go
@ -26,6 +26,8 @@ func main() {
|
||||
log.Println("Running")
|
||||
t, err := control.NewControlPlane(log, `
|
||||
default:proxy
|
||||
ip(119.29.29.29) -> proxy
|
||||
ip(223.5.5.5) -> direct
|
||||
ip(geoip:cn) -> direct
|
||||
domain(geosite:cn, domain:"ip.sb") -> direct
|
||||
ip("91.105.192.0/23","91.108.4.0/22","91.108.8.0/21","91.108.16.0/21","91.108.56.0/22","95.161.64.0/20","149.154.160.0/20","185.76.151.0/24")->proxy
|
||||
|
Loading…
Reference in New Issue
Block a user