dae/cmd/run.go

112 lines
2.5 KiB
Go
Raw Normal View History

2023-01-28 00:50:21 +07:00
package cmd
import (
"fmt"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/v2rayA/dae/cmd/internal"
2023-01-28 00:50:21 +07:00
"github.com/v2rayA/dae/component/control"
"github.com/v2rayA/dae/config"
"github.com/v2rayA/dae/pkg/config_parser"
"github.com/v2rayA/dae/pkg/logger"
"os"
"os/signal"
"syscall"
)
var (
cfgFile string
runCmd = &cobra.Command{
Use: "run",
Short: "Run dae in the foreground",
Run: func(cmd *cobra.Command, args []string) {
if cfgFile == "" {
logrus.Fatalln("Argument \"--config\" or \"-c\" is required but not provided.")
}
2023-01-28 00:50:21 +07:00
if err := Run(); err != nil {
logrus.Fatalln(err)
}
},
}
)
func init() {
runCmd.PersistentFlags().StringVarP(&cfgFile, "config", "c", "", "config file")
2023-01-28 00:50:21 +07:00
}
func Run() (err error) {
logrus.SetLevel(logrus.DebugLevel)
log := logger.NewLogger(2)
2023-02-04 14:02:44 +07:00
// Require "sudo" if necessary.
internal.AutoSu()
2023-01-28 00:50:21 +07:00
// Read config from --config cfgFile.
param, err := readConfig()
if err != nil {
return fmt.Errorf("readConfig: %w", err)
}
// Resolve subscriptions to nodes.
nodeList := make([]string, len(param.Node))
copy(nodeList, param.Node)
for _, sub := range param.Subscription {
nodes, err := internal.ResolveSubscription(log, sub)
2023-01-28 00:50:21 +07:00
if err != nil {
log.Warnf(`failed to resolve subscription "%v": %v`, sub, err)
}
nodeList = append(nodeList, nodes...)
}
2023-02-01 11:30:26 +07:00
if len(param.Global.LanInterface) == 0 && len(param.Global.WanInterface) == 0 {
2023-02-01 09:59:57 +07:00
return fmt.Errorf("LanInterface and WanInterface cannot both be empty")
}
2023-01-28 00:50:21 +07:00
// New ControlPlane.
t, err := control.NewControlPlane(
log,
nodeList,
param.Group,
&param.Routing,
param.Global.DnsUpstream,
param.Global.CheckUrl,
2023-01-28 14:47:43 +07:00
param.Global.CheckInterval,
param.Global.LanInterface,
param.Global.WanInterface,
2023-01-28 00:50:21 +07:00
)
if err != nil {
return err
}
// Serve tproxy TCP/UDP server util signals.
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGKILL, syscall.SIGILL)
go func() {
if err := t.ListenAndServe(param.Global.TproxyPort); err != nil {
log.Errorln("ListenAndServe:", err)
sigs <- nil
}
}()
<-sigs
if e := t.Close(); e != nil {
return fmt.Errorf("close control plane: %w", e)
}
return nil
}
func readConfig() (params *config.Params, err error) {
b, err := os.ReadFile(cfgFile)
if err != nil {
return nil, err
}
sections, err := config_parser.Parse(string(b))
if err != nil {
return nil, fmt.Errorf("\n%w", err)
2023-01-28 00:50:21 +07:00
}
if params, err = config.New(sections); err != nil {
return nil, err
}
return params, nil
}