package main import ( "flag" "fmt" "log" "os" "os/signal" "syscall" "dns-server/config" "dns-server/dns" "dns-server/http" "dns-server/logger" "dns-server/shield" ) func main() { // 命令行参数解析 var configFile string var daemonMode bool flag.StringVar(&configFile, "config", "config.json", "配置文件路径") flag.BoolVar(&daemonMode, "daemon", false, "以守护进程模式运行") flag.Parse() // 如果是守护进程模式,创建守护进程 if daemonMode { if err := daemonize(); err != nil { log.Fatalf("创建守护进程失败: %v", err) } // 父进程退出 os.Exit(0) } // 初始化配置 var cfg *config.Config var err error cfg, err = config.LoadConfig(configFile) if err != nil { log.Fatalf("加载配置失败: %v", err) } // 初始化日志系统 if err := logger.InitLogger(cfg.Log.File, cfg.Log.Level, 0, 0, 0); err != nil { log.Fatalf("初始化日志系统失败: %v", err) } defer logger.Close() // 初始化屏蔽管理系统 shieldManager := shield.NewShieldManager(&cfg.Shield) if err := shieldManager.LoadRules(); err != nil { logger.Error("加载屏蔽规则失败", "error", err) } // 启动DNS服务器 dnsServer := dns.NewServer(&cfg.DNS, &cfg.Shield, shieldManager) go func() { if err := dnsServer.Start(); err != nil { logger.Error("DNS服务器启动失败", "error", err) os.Exit(1) } }() // 启动HTTP控制台服务器 httpServer := http.NewServer(cfg, dnsServer, shieldManager) go func() { if err := httpServer.Start(); err != nil { logger.Error("HTTP控制台服务器启动失败", "error", err) } }() // 启动定时更新任务 go shieldManager.StartAutoUpdate() logger.Info(fmt.Sprintf("DNS服务器已启动,监听端口: %d", cfg.DNS.Port)) logger.Info(fmt.Sprintf("HTTP控制台已启动,监听端口: %d", cfg.HTTP.Port)) // 监听信号 sigCh := make(chan os.Signal, 1) signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM) <-sigCh // 清理资源 log.Println("正在关闭服务...") dnsServer.Stop() httpServer.Stop() shieldManager.StopAutoUpdate() // 守护进程模式下不需要删除PID文件 log.Println("服务已关闭") } // daemonize 创建守护进程 func daemonize() error { // 使用更简单的方式创建守护进程:直接在当前进程中进行守护化处理 // 1. 重定向标准输入、输出、错误 nullFile, err := os.OpenFile("/dev/null", os.O_RDWR, 0) if err != nil { return fmt.Errorf("打开/dev/null失败: %w", err) } defer nullFile.Close() // 重定向文件描述符 err = syscall.Dup2(int(nullFile.Fd()), int(os.Stdin.Fd())) if err != nil { return fmt.Errorf("重定向stdin失败: %w", err) } err = syscall.Dup2(int(nullFile.Fd()), int(os.Stdout.Fd())) if err != nil { return fmt.Errorf("重定向stdout失败: %w", err) } err = syscall.Dup2(int(nullFile.Fd()), int(os.Stderr.Fd())) if err != nil { return fmt.Errorf("重定向stderr失败: %w", err) } // 2. 创建新的会话和进程组 _, err = syscall.Setsid() if err != nil { return fmt.Errorf("创建新会话失败: %w", err) } fmt.Println("守护进程已启动") return nil }