This commit is contained in:
mzz2017 2023-02-04 18:18:06 +08:00
parent e203ad1590
commit 69f897b7e9
4 changed files with 37 additions and 16 deletions

View File

@ -18,6 +18,7 @@ import (
"os" "os"
"reflect" "reflect"
"strings" "strings"
"sync"
) )
type _bpfLpmKey struct { type _bpfLpmKey struct {
@ -67,16 +68,22 @@ func cidrToBpfLpmKey(prefix netip.Prefix) _bpfLpmKey {
} }
} }
var (
CheckBatchUpdateFeatureOnce sync.Once
SimulateBatchUpdate bool
)
func BatchUpdate(m *ebpf.Map, keys interface{}, values interface{}, opts *ebpf.BatchOptions) (n int, err error) { func BatchUpdate(m *ebpf.Map, keys interface{}, values interface{}, opts *ebpf.BatchOptions) (n int, err error) {
var old bool CheckBatchUpdateFeatureOnce.Do(func() {
version, e := internal.KernelVersion() version, e := internal.KernelVersion()
if e != nil || version.Less(consts.UserspaceBatchUpdateFeatureVersion) { if e != nil || version.Less(consts.UserspaceBatchUpdateFeatureVersion) {
old = true SimulateBatchUpdate = true
} }
if m.Type() == ebpf.LPMTrie && version.Less(consts.UserspaceBatchUpdateLpmTrieFeatureVersion) { if m.Type() == ebpf.LPMTrie && version.Less(consts.UserspaceBatchUpdateLpmTrieFeatureVersion) {
old = true SimulateBatchUpdate = true
} }
if !old { })
if !SimulateBatchUpdate {
return m.BatchUpdate(keys, values, opts) return m.BatchUpdate(keys, values, opts)
} else { } else {
vKeys := reflect.ValueOf(keys) vKeys := reflect.ValueOf(keys)

View File

@ -90,7 +90,7 @@ func NewControlPlane(
log.Infof("Loading eBPF programs and maps into the kernel") log.Infof("Loading eBPF programs and maps into the kernel")
var bpf bpfObjects var bpf bpfObjects
var ProgramOptions ebpf.ProgramOptions var ProgramOptions ebpf.ProgramOptions
if log.IsLevelEnabled(logrus.TraceLevel) { if log.Level == logrus.PanicLevel {
ProgramOptions = ebpf.ProgramOptions{ ProgramOptions = ebpf.ProgramOptions{
LogLevel: ebpf.LogLevelBranch | ebpf.LogLevelStats, LogLevel: ebpf.LogLevelBranch | ebpf.LogLevelStats,
//LogLevel: ebpf.LogLevelInstruction | ebpf.LogLevelStats, //LogLevel: ebpf.LogLevelInstruction | ebpf.LogLevelStats,
@ -127,11 +127,11 @@ retryLoadBpf:
goto retryLoadBpf goto retryLoadBpf
} }
// Get detailed log from ebpf.internal.(*VerifierError) // Get detailed log from ebpf.internal.(*VerifierError)
if log.IsLevelEnabled(logrus.TraceLevel) { if log.Level == logrus.PanicLevel {
if v := reflect.Indirect(reflect.ValueOf(errors.Unwrap(errors.Unwrap(err)))); v.Kind() == reflect.Struct { if v := reflect.Indirect(reflect.ValueOf(errors.Unwrap(errors.Unwrap(err)))); v.Kind() == reflect.Struct {
if _log := v.FieldByName("Log"); _log.IsValid() { if _log := v.FieldByName("Log"); _log.IsValid() {
if strSlice, ok := _log.Interface().([]string); ok { if strSlice, ok := _log.Interface().([]string); ok {
log.Traceln(strings.Join(strSlice, "\n")) log.Panicln(strings.Join(strSlice, "\n"))
} }
} }
} }

View File

@ -9,6 +9,8 @@ import (
"encoding/binary" "encoding/binary"
"fmt" "fmt"
"github.com/cilium/ebpf" "github.com/cilium/ebpf"
"github.com/mohae/deepcopy"
"github.com/sirupsen/logrus"
"github.com/v2rayA/dae/common" "github.com/v2rayA/dae/common"
"github.com/v2rayA/dae/common/consts" "github.com/v2rayA/dae/common/consts"
"golang.org/x/net/dns/dnsmessage" "golang.org/x/net/dns/dnsmessage"
@ -26,7 +28,15 @@ type dnsCache struct {
} }
func (c *dnsCache) FillInto(req *dnsmessage.Message) { func (c *dnsCache) FillInto(req *dnsmessage.Message) {
req.Answers = c.Answers req.Answers = deepcopy.Copy(c.Answers).([]dnsmessage.Resource)
// Align question and answer Name.
if len(req.Questions) > 0 {
q := req.Questions[0]
if len(req.Answers) > 0 &&
strings.EqualFold(req.Answers[0].Header.Name.String(), q.Name.String()) {
req.Answers[0].Header.Name.Data = q.Name.Data
}
}
req.RCode = dnsmessage.RCodeSuccess req.RCode = dnsmessage.RCodeSuccess
req.Response = true req.Response = true
req.RecursionAvailable = true req.RecursionAvailable = true
@ -137,9 +147,8 @@ func (c *ControlPlane) DnsRespHandler(data []byte) (newData []byte, err error) {
return data, nil return data, nil
} }
q := msg.Questions[0] q := msg.Questions[0]
// If first answer is CNAME type, replace the Name with flipping-backed Name. // Align question and answer Name.
if len(msg.Answers) > 0 && if len(msg.Answers) > 0 &&
msg.Answers[0].Header.Type == dnsmessage.TypeCNAME &&
strings.EqualFold(msg.Answers[0].Header.Name.String(), q.Name.String()) { strings.EqualFold(msg.Answers[0].Header.Name.String(), q.Name.String()) {
msg.Answers[0].Header.Name.Data = q.Name.Data msg.Answers[0].Header.Name.Data = q.Name.Data
} }
@ -174,6 +183,10 @@ func (c *ControlPlane) DnsRespHandler(data []byte) (newData []byte, err error) {
} }
// Update dnsCache. // Update dnsCache.
c.log.WithFields(logrus.Fields{
"qname": q.Name,
"ans": msg.Answers,
}).Tracef("Update DNS record cache")
c.mutex.Lock() c.mutex.Lock()
fqdn := strings.ToLower(q.Name.String()) fqdn := strings.ToLower(q.Name.String())
cacheKey := fqdn + q.Type.String() cacheKey := fqdn + q.Type.String()

View File

@ -8,6 +8,7 @@ global {
# Now only support UDP and IP:Port. # Now only support UDP and IP:Port.
# Please make sure DNS traffic will go through and be forwarded by dae. # Please make sure DNS traffic will go through and be forwarded by dae.
# The upstream DNS answer MUST NOT be polluted.
# The request to dns upstream follows routing defined below. # The request to dns upstream follows routing defined below.
dns_upstream: '8.8.8.8:53' dns_upstream: '8.8.8.8:53'
@ -62,7 +63,7 @@ group {
routing { routing {
# See routing.md for full examples. # See routing.md for full examples.
ip(8.8.8.8) && port(53) -> direct ip(8.8.8.8, 1.1.1.1) && port(53) -> my_group
pname(firefox) && domain(ip.sb) -> direct pname(firefox) && domain(ip.sb) -> direct
pname(curl) && domain(ip.sb) -> my_group pname(curl) && domain(ip.sb) -> my_group