This commit is contained in:
mzz2017
2023-02-28 21:25:15 +08:00
parent 215b9202ea
commit 741a8dedb4
19 changed files with 98 additions and 56 deletions

View File

@ -6,6 +6,7 @@ import (
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/v2rayA/dae/cmd/internal" "github.com/v2rayA/dae/cmd/internal"
"github.com/v2rayA/dae/common/subscription"
"github.com/v2rayA/dae/config" "github.com/v2rayA/dae/config"
"github.com/v2rayA/dae/control" "github.com/v2rayA/dae/control"
"github.com/v2rayA/dae/pkg/logger" "github.com/v2rayA/dae/pkg/logger"
@ -25,13 +26,13 @@ const (
func init() { func init() {
runCmd.PersistentFlags().StringVarP(&cfgFile, "config", "c", "", "config file") runCmd.PersistentFlags().StringVarP(&cfgFile, "config", "c", "", "config file")
runCmd.PersistentFlags().BoolVarP(&disableTimestamp, "disable-timestamp", "", false, "disable timestamp") runCmd.PersistentFlags().BoolVarP(&disableTimestamp, "disable-timestamp", "", false, "disable timestamp")
runCmd.PersistentFlags().BoolVarP(&disableTimestamp, "disable-runfile", "", false, "not generate /var/run/dae.pid") runCmd.PersistentFlags().BoolVarP(&disableTimestamp, "disable-pidfile", "", false, "not generate /var/run/dae.pid")
} }
var ( var (
cfgFile string cfgFile string
disableTimestamp bool disableTimestamp bool
disableRunFile bool disablePidFile bool
runCmd = &cobra.Command{ runCmd = &cobra.Command{
Use: "run", Use: "run",
@ -80,7 +81,7 @@ func Run(log *logrus.Logger, conf *config.Config) (err error) {
go func() { go func() {
<-readyChan <-readyChan
sdnotify.Ready() sdnotify.Ready()
if !disableRunFile { if !disablePidFile {
_ = os.WriteFile(PidFilePath, []byte(strconv.Itoa(os.Getpid())), 0644) _ = os.WriteFile(PidFilePath, []byte(strconv.Itoa(os.Getpid())), 0644)
} }
}() }()
@ -169,7 +170,7 @@ func newControlPlane(log *logrus.Logger, bpf interface{}, conf *config.Config) (
// Resolve subscriptions to nodes. // Resolve subscriptions to nodes.
resolvingfailed := false resolvingfailed := false
for _, sub := range conf.Subscription { for _, sub := range conf.Subscription {
tag, nodes, err := internal.ResolveSubscription(log, filepath.Dir(cfgFile), string(sub)) tag, nodes, err := subscription.ResolveSubscription(log, filepath.Dir(cfgFile), string(sub))
if err != nil { if err != nil {
log.Warnf(`failed to resolve subscription "%v": %v`, sub, err) log.Warnf(`failed to resolve subscription "%v": %v`, sub, err)
resolvingfailed = true resolvingfailed = true

View File

@ -1,4 +1,9 @@
package internal /*
* SPDX-License-Identifier: AGPL-3.0-only
* Copyright (c) 2023, v2rayA Organization <team@v2raya.org>
*/
package subscription
import ( import (
"bufio" "bufio"
@ -35,7 +40,7 @@ type sip008Server struct {
PluginOpts string `json:"plugin_opts"` PluginOpts string `json:"plugin_opts"`
} }
func resolveSubscriptionAsBase64(log *logrus.Logger, b []byte) (nodes []string) { func ResolveSubscriptionAsBase64(log *logrus.Logger, b []byte) (nodes []string) {
log.Debugln("Try to resolve as base64") log.Debugln("Try to resolve as base64")
// base64 decode // base64 decode
@ -60,7 +65,7 @@ func resolveSubscriptionAsBase64(log *logrus.Logger, b []byte) (nodes []string)
return nodes return nodes
} }
func resolveSubscriptionAsSIP008(log *logrus.Logger, b []byte) (nodes []string, err error) { func ResolveSubscriptionAsSIP008(log *logrus.Logger, b []byte) (nodes []string, err error) {
log.Debugln("Try to resolve as sip008") log.Debugln("Try to resolve as sip008")
var sip sip008 var sip sip008
@ -84,7 +89,7 @@ func resolveSubscriptionAsSIP008(log *logrus.Logger, b []byte) (nodes []string,
return nodes, nil return nodes, nil
} }
func resolveFile(u *url.URL, configDir string) (b []byte, err error) { func ResolveFile(u *url.URL, configDir string) (b []byte, err error) {
if u.Host == "" { if u.Host == "" {
return nil, fmt.Errorf("not support absolute path") return nil, fmt.Errorf("not support absolute path")
} }
@ -147,7 +152,7 @@ func ResolveSubscription(log *logrus.Logger, configDir string, subscription stri
) )
switch u.Scheme { switch u.Scheme {
case "file": case "file":
b, err = resolveFile(u, configDir) b, err = ResolveFile(u, configDir)
if err != nil { if err != nil {
return "", nil, err return "", nil, err
} }
@ -164,10 +169,10 @@ func ResolveSubscription(log *logrus.Logger, configDir string, subscription stri
return "", nil, err return "", nil, err
} }
resolve: resolve:
if nodes, err = resolveSubscriptionAsSIP008(log, b); err == nil { if nodes, err = ResolveSubscriptionAsSIP008(log, b); err == nil {
return tag, nodes, nil return tag, nodes, nil
} else { } else {
log.Debugln(err) log.Debugln(err)
} }
return tag, resolveSubscriptionAsBase64(log, b), nil return tag, ResolveSubscriptionAsBase64(log, b), nil
} }

View File

@ -102,7 +102,7 @@ func (a *AliveDialerSet) printLatencies() {
if !ok { if !ok {
continue continue
} }
builder.WriteString(fmt.Sprintf("%v: %v\n", d.Name(), latency.String())) builder.WriteString(fmt.Sprintf("%v: %v\n", d.property.Name, latency.String()))
} }
a.log.Traceln(builder.String()) a.log.Traceln(builder.String())
} }
@ -138,7 +138,7 @@ func (a *AliveDialerSet) NotifyLatencyChange(dialer *Dialer, alive bool) {
// Dialer: not alive -> alive. // Dialer: not alive -> alive.
if index == -NotAlive { if index == -NotAlive {
a.log.WithFields(logrus.Fields{ a.log.WithFields(logrus.Fields{
"dialer": dialer.Name(), "dialer": dialer.property.Name,
"group": a.dialerGroupName, "group": a.dialerGroupName,
"network": a.CheckTyp.StringWithoutDns(), "network": a.CheckTyp.StringWithoutDns(),
}).Infoln("NOT ALIVE -> ALIVE:") }).Infoln("NOT ALIVE -> ALIVE:")
@ -151,7 +151,7 @@ func (a *AliveDialerSet) NotifyLatencyChange(dialer *Dialer, alive bool) {
if index >= 0 { if index >= 0 {
// Dialer: alive -> not alive. // Dialer: alive -> not alive.
a.log.WithFields(logrus.Fields{ a.log.WithFields(logrus.Fields{
"dialer": dialer.Name(), "dialer": dialer.property.Name,
"group": a.dialerGroupName, "group": a.dialerGroupName,
"network": a.CheckTyp.StringWithoutDns(), "network": a.CheckTyp.StringWithoutDns(),
}).Infoln("ALIVE -> NOT ALIVE:") }).Infoln("ALIVE -> NOT ALIVE:")
@ -210,13 +210,13 @@ func (a *AliveDialerSet) NotifyLatencyChange(dialer *Dialer, alive bool) {
re = "" re = ""
oldDialerName = "<nil>" oldDialerName = "<nil>"
} else { } else {
oldDialerName = bakOldBestDialer.Name() oldDialerName = bakOldBestDialer.property.Name
} }
a.log.WithFields(logrus.Fields{ a.log.WithFields(logrus.Fields{
string(a.selectionPolicy): a.minLatency.latency, string(a.selectionPolicy): a.minLatency.latency,
"group": a.dialerGroupName, "group": a.dialerGroupName,
"network": a.CheckTyp.String(), "network": a.CheckTyp.String(),
"new_dialer": a.minLatency.dialer.Name(), "new_dialer": a.minLatency.dialer.property.Name,
"old_dialer": oldDialerName, "old_dialer": oldDialerName,
}).Infof("Group %vselects dialer", re) }).Infof("Group %vselects dialer", re)
@ -239,7 +239,7 @@ func (a *AliveDialerSet) NotifyLatencyChange(dialer *Dialer, alive bool) {
a.log.WithFields(logrus.Fields{ a.log.WithFields(logrus.Fields{
"group": a.dialerGroupName, "group": a.dialerGroupName,
"network": a.CheckTyp.String(), "network": a.CheckTyp.String(),
"dialer": a.minLatency.dialer.Name(), "dialer": a.minLatency.dialer.property.Name,
}).Infof("Group selects dialer") }).Infof("Group selects dialer")
} }
} }

View File

@ -40,5 +40,10 @@ func (d *blockDialer) DialUdp(addr string) (c netproxy.PacketConn, err error) {
} }
func NewBlockDialer(option *GlobalOption, dialCallback func()) *Dialer { func NewBlockDialer(option *GlobalOption, dialCallback func()) *Dialer {
return NewDialer(&blockDialer{DialCallback: dialCallback}, option, InstanceOption{CheckEnabled: false}, "block", "block", "") return NewDialer(&blockDialer{DialCallback: dialCallback}, option, InstanceOption{CheckEnabled: false}, Property{
Name: "block",
Address: "",
Protocol: "",
Link: "",
})
} }

View File

@ -455,7 +455,7 @@ func (d *Dialer) Check(timeout time.Duration,
d.Log.WithFields(logrus.Fields{ d.Log.WithFields(logrus.Fields{
"network": opts.networkType.String(), "network": opts.networkType.String(),
"node": d.name, "node": d.property.Name,
"last": latency.Truncate(time.Millisecond), "last": latency.Truncate(time.Millisecond),
"avg_10": avg.Truncate(time.Millisecond), "avg_10": avg.Truncate(time.Millisecond),
"mov_avg": collection.MovingAverage.Truncate(time.Millisecond), "mov_avg": collection.MovingAverage.Truncate(time.Millisecond),
@ -471,7 +471,7 @@ func (d *Dialer) Check(timeout time.Duration,
} }
d.Log.WithFields(logrus.Fields{ d.Log.WithFields(logrus.Fields{
"network": opts.networkType.String(), "network": opts.networkType.String(),
"node": d.name, "node": d.property.Name,
"err": err.Error(), "err": err.Error(),
}).Debugln("Connectivity Check Failed") }).Debugln("Connectivity Check Failed")
} }

View File

@ -18,9 +18,7 @@ type Dialer struct {
*GlobalOption *GlobalOption
instanceOption InstanceOption instanceOption InstanceOption
netproxy.Dialer netproxy.Dialer
name string property Property
protocol string
link string
collectionFineMu sync.Mutex collectionFineMu sync.Mutex
collections [6]*collection collections [6]*collection
@ -46,10 +44,17 @@ type InstanceOption struct {
CheckEnabled bool CheckEnabled bool
} }
type Property struct {
Name string
Address string
Protocol string
Link string
}
type AliveDialerSetSet map[*AliveDialerSet]int type AliveDialerSetSet map[*AliveDialerSet]int
// NewDialer is for register in general. // NewDialer is for register in general.
func NewDialer(dialer netproxy.Dialer, option *GlobalOption, iOption InstanceOption, name string, protocol string, link string) *Dialer { func NewDialer(dialer netproxy.Dialer, option *GlobalOption, iOption InstanceOption, property Property) *Dialer {
var collections [6]*collection var collections [6]*collection
for i := range collections { for i := range collections {
collections[i] = newCollection() collections[i] = newCollection()
@ -59,9 +64,7 @@ func NewDialer(dialer netproxy.Dialer, option *GlobalOption, iOption InstanceOpt
GlobalOption: option, GlobalOption: option,
instanceOption: iOption, instanceOption: iOption,
Dialer: dialer, Dialer: dialer,
name: name, property: property,
protocol: protocol,
link: link,
collectionFineMu: sync.Mutex{}, collectionFineMu: sync.Mutex{},
collections: collections, collections: collections,
tickerMu: sync.Mutex{}, tickerMu: sync.Mutex{},
@ -87,14 +90,6 @@ func (d *Dialer) Close() error {
return nil return nil
} }
func (d *Dialer) Name() string { func (d *Dialer) Property() Property {
return d.name return d.property
}
func (d *Dialer) Protocol() string {
return d.protocol
}
func (d *Dialer) Link() string {
return d.link
} }

View File

@ -5,9 +5,15 @@ import (
) )
func NewDirectDialer(option *GlobalOption, fullcone bool) *Dialer { func NewDirectDialer(option *GlobalOption, fullcone bool) *Dialer {
property := Property{
Name: "direct",
Address: "",
Protocol: "",
Link: "",
}
if fullcone { if fullcone {
return NewDialer(softwindDirect.FullconeDirect, option, InstanceOption{CheckEnabled: false}, "direct", "direct", "") return NewDialer(softwindDirect.FullconeDirect, option, InstanceOption{CheckEnabled: false}, property)
} else { } else {
return NewDialer(softwindDirect.SymmetricDirect, option, InstanceOption{CheckEnabled: false}, "direct", "direct", "") return NewDialer(softwindDirect.SymmetricDirect, option, InstanceOption{CheckEnabled: false}, property)
} }
} }

View File

@ -71,7 +71,12 @@ func (s *HTTP) Dialer(option *dialer.GlobalOption, iOption dialer.InstanceOption
if err != nil { if err != nil {
return nil, err return nil, err
} }
return dialer.NewDialer(d, option, iOption, s.Name, s.Protocol, u.String()), nil return dialer.NewDialer(d, option, iOption, dialer.Property{
Name: s.Name,
Address: net.JoinHostPort(s.Server, strconv.Itoa(s.Port)),
Protocol: s.Protocol,
Link: u.String(),
}), nil
} }
func (s *HTTP) URL() url.URL { func (s *HTTP) URL() url.URL {

View File

@ -33,7 +33,7 @@ func NewFromLink(gOption *GlobalOption, iOption InstanceOption, link string) (di
} }
// Overwrite node name using user given tag. // Overwrite node name using user given tag.
if overwrittenName != "" { if overwrittenName != "" {
node.name = overwrittenName node.property.Name = overwrittenName
} }
return node, err return node, err
} else { } else {

View File

@ -93,7 +93,12 @@ func (s *Shadowsocks) Dialer(option *dialer.GlobalOption, iOption dialer.Instanc
if err != nil { if err != nil {
return nil, err return nil, err
} }
return dialer.NewDialer(d, option, iOption, s.Name, s.Protocol, s.ExportToURL()), nil return dialer.NewDialer(d, option, iOption, dialer.Property{
Name: s.Name,
Address: net.JoinHostPort(s.Server, strconv.Itoa(s.Port)),
Protocol: s.Protocol,
Link: s.ExportToURL(),
}), nil
} }
func ParseSSURL(u string) (data *Shadowsocks, err error) { func ParseSSURL(u string) (data *Shadowsocks, err error) {

View File

@ -70,7 +70,12 @@ func (s *ShadowsocksR) Dialer(option *dialer.GlobalOption, iOption dialer.Instan
ObfsOverhead: obfsDialer.ObfsOverhead(), ObfsOverhead: obfsDialer.ObfsOverhead(),
} }
return dialer.NewDialer(d, option, iOption, s.Name, s.Protocol, s.ExportToURL()), nil return dialer.NewDialer(d, option, iOption, dialer.Property{
Name: s.Name,
Address: net.JoinHostPort(s.Server, strconv.Itoa(s.Port)),
Protocol: s.Protocol,
Link: s.ExportToURL(),
}), nil
} }
func ParseSSRURL(u string) (data *ShadowsocksR, err error) { func ParseSSRURL(u string) (data *ShadowsocksR, err error) {

View File

@ -43,7 +43,12 @@ func (s *Socks) Dialer(option *dialer.GlobalOption, iOption dialer.InstanceOptio
if err != nil { if err != nil {
return nil, err return nil, err
} }
return dialer.NewDialer(d, option, iOption, s.Name, s.Protocol, link), nil return dialer.NewDialer(d, option, iOption, dialer.Property{
Name: s.Name,
Address: net.JoinHostPort(s.Server, strconv.Itoa(s.Port)),
Protocol: s.Protocol,
Link: link,
}), nil
//case "socks4", "socks4a": //case "socks4", "socks4a":
// d, err := socks4.NewSocks4Dialer(link, &proxy.Direct{}) // d, err := socks4.NewSocks4Dialer(link, &proxy.Direct{})
// if err != nil { // if err != nil {

View File

@ -105,7 +105,12 @@ func (s *Trojan) Dialer(option *dialer.GlobalOption, iOption dialer.InstanceOpti
}); err != nil { }); err != nil {
return nil, err return nil, err
} }
return dialer.NewDialer(d, option, iOption, s.Name, s.Protocol, s.ExportToURL()), nil return dialer.NewDialer(d, option, iOption, dialer.Property{
Name: s.Name,
Address: net.JoinHostPort(s.Server, strconv.Itoa(s.Port)),
Protocol: s.Protocol,
Link: s.ExportToURL(),
}), nil
} }
func ParseTrojanURL(u string, option *dialer.GlobalOption) (data *Trojan, err error) { func ParseTrojanURL(u string, option *dialer.GlobalOption) (data *Trojan, err error) {

View File

@ -152,7 +152,12 @@ func (s *V2Ray) Dialer(option *dialer.GlobalOption, iOption dialer.InstanceOptio
}); err != nil { }); err != nil {
return nil, err return nil, err
} }
return dialer.NewDialer(d, option, iOption, s.Ps, s.Protocol, s.ExportToURL()), nil return dialer.NewDialer(d, option, iOption, dialer.Property{
Name: s.Ps,
Address: net.JoinHostPort(s.Add, s.Port),
Protocol: s.Protocol,
Link: s.ExportToURL(),
}), nil
} }
func ParseVlessURL(vless string, option *dialer.GlobalOption) (data *V2Ray, err error) { func ParseVlessURL(vless string, option *dialer.GlobalOption) (data *V2Ray, err error) {

View File

@ -71,19 +71,19 @@ func (s *DialerSet) filterHit(dialer *dialer.Dialer, filters []*config_parser.Fu
for _, param := range filter.Params { for _, param := range filter.Params {
switch param.Key { switch param.Key {
case FilterKey_Name_Regex: case FilterKey_Name_Regex:
matched, _ := regexp.MatchString(param.Val, dialer.Name()) matched, _ := regexp.MatchString(param.Val, dialer.Property().Name)
//logrus.Warnln(param.Val, matched, dialer.Name()) //logrus.Warnln(param.Val, matched, dialer.Name())
if matched { if matched {
subFilterHit = true subFilterHit = true
break break
} }
case FilterKey_Name_Keyword: case FilterKey_Name_Keyword:
if strings.Contains(dialer.Name(), param.Val) { if strings.Contains(dialer.Property().Name, param.Val) {
subFilterHit = true subFilterHit = true
break break
} }
case "": case "":
if dialer.Name() == param.Val { if dialer.Property().Name == param.Val {
subFilterHit = true subFilterHit = true
break break
} }

View File

@ -235,7 +235,7 @@ func NewControlPlane(
// Convert node links to dialers. // Convert node links to dialers.
log.Infof(`Group "%v" node list:`, group.Name) log.Infof(`Group "%v" node list:`, group.Name)
for _, d := range dialers { for _, d := range dialers {
log.Infoln("\t" + d.Name()) log.Infoln("\t" + d.Property().Name)
// We only activate check of nodes that have a group. // We only activate check of nodes that have a group.
d.ActivateCheck() d.ActivateCheck()
} }

View File

@ -366,7 +366,7 @@ func (c *DnsController) dialSend(req *udpRequest, data []byte, upstream *dns.Ups
// We only validate rush-ans when outbound is direct and pkt does not send to a home device. // We only validate rush-ans when outbound is direct and pkt does not send to a home device.
// Because additional record OPT may not be supported by home router. // Because additional record OPT may not be supported by home router.
// So se should trust home devices even if they make rush-answer (or looks like). // So se should trust home devices even if they make rush-answer (or looks like).
return dialArgument.bestDialer.Name() == "direct" && !from.Addr().IsPrivate() return dialArgument.bestDialer.Property().Name == "direct" && !from.Addr().IsPrivate()
}) })
// Dial and send. // Dial and send.
var respMsg *dnsmessage.Message var respMsg *dnsmessage.Message
@ -420,7 +420,7 @@ func (c *DnsController) dialSend(req *udpRequest, data []byte, upstream *dns.Ups
// Wait for response. // Wait for response.
n, err := conn.Read(respBuf) n, err := conn.Read(respBuf)
if err != nil { if err != nil {
return fmt.Errorf("failed to read from: %v (dialer: %v): %w", dialArgument.bestTarget, dialArgument.bestDialer.Name(), err) return fmt.Errorf("failed to read from: %v (dialer: %v): %w", dialArgument.bestTarget, dialArgument.bestDialer.Property().Name, err)
} }
respMsg, err = dnsRespHandler(respBuf[:n], dialArgument.bestTarget) respMsg, err = dnsRespHandler(respBuf[:n], dialArgument.bestTarget)
if err != nil { if err != nil {
@ -530,7 +530,7 @@ func (c *DnsController) dialSend(req *udpRequest, data []byte, upstream *dns.Ups
"network": networkType.String(), "network": networkType.String(),
"outbound": dialArgument.bestOutbound.Name, "outbound": dialArgument.bestOutbound.Name,
"policy": dialArgument.bestOutbound.GetSelectionPolicy(), "policy": dialArgument.bestOutbound.GetSelectionPolicy(),
"dialer": dialArgument.bestDialer.Name(), "dialer": dialArgument.bestDialer.Property().Name,
"qname": qname, "qname": qname,
"qtype": qtype, "qtype": qtype,
"pid": req.routingResult.Pid, "pid": req.routingResult.Pid,

View File

@ -103,7 +103,7 @@ func (c *ControlPlane) handleConn(lConn net.Conn) (err error) {
"network": networkType.String(), "network": networkType.String(),
"outbound": outbound.Name, "outbound": outbound.Name,
"policy": outbound.GetSelectionPolicy(), "policy": outbound.GetSelectionPolicy(),
"dialer": d.Name(), "dialer": d.Property().Name,
"domain": domain, "domain": domain,
"pid": routingResult.Pid, "pid": routingResult.Pid,
"pname": ProcessName2String(routingResult.Pname[:]), "pname": ProcessName2String(routingResult.Pname[:]),

View File

@ -224,7 +224,7 @@ getNew:
c.log.WithFields(logrus.Fields{ c.log.WithFields(logrus.Fields{
"src": RefineSourceToShow(realSrc, realDst.Addr(), lanWanFlag), "src": RefineSourceToShow(realSrc, realDst.Addr(), lanWanFlag),
"network": networkType.String(), "network": networkType.String(),
"dialer": ue.Dialer.Name(), "dialer": ue.Dialer.Property().Name,
"retry": retry, "retry": retry,
}).Debugln("Old udp endpoint was not alive and removed.") }).Debugln("Old udp endpoint was not alive and removed.")
} }
@ -261,7 +261,7 @@ getNew:
"network": networkType.StringWithoutDns(), "network": networkType.StringWithoutDns(),
"outbound": outbound.Name, "outbound": outbound.Name,
"policy": outbound.GetSelectionPolicy(), "policy": outbound.GetSelectionPolicy(),
"dialer": ue.Dialer.Name(), "dialer": ue.Dialer.Property().Name,
"domain": domain, "domain": domain,
"pid": routingResult.Pid, "pid": routingResult.Pid,
"pname": ProcessName2String(routingResult.Pname[:]), "pname": ProcessName2String(routingResult.Pname[:]),