refactor: restructure server start procedure

This commit is contained in:
SunBK201 2025-11-27 22:20:23 +08:00
parent a3a11f2a11
commit 17d7b7aae9
7 changed files with 79 additions and 66 deletions

View File

@ -64,11 +64,6 @@ func (s *NfqueueServer) Start() error {
if err != nil { if err != nil {
return fmt.Errorf("nfq.Open: %w", err) return fmt.Errorf("nfq.Open: %w", err)
} }
defer func() {
if cerr := nf.Close(); cerr != nil {
slog.Error("nf.Close", slog.Any("error", cerr))
}
}()
s.Nf = nf s.Nf = nf
// Ignore ENOBUFS to prevent queue drop logs // Ignore ENOBUFS to prevent queue drop logs

View File

@ -44,7 +44,12 @@ func (s *Server) Start() (err error) {
} }
}), }),
} }
return server.ListenAndServe() go func() {
if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
slog.Error("server.ListenAndServe", slog.Any("error", err))
}
}()
return nil
} }
func (s *Server) Close() (err error) { func (s *Server) Close() (err error) {

View File

@ -42,7 +42,7 @@ func New(cfg *config.Config) *Server {
func (s *Server) Start() (err error) { func (s *Server) Start() (err error) {
err = s.Firewall.Setup(s.cfg) err = s.Firewall.Setup(s.cfg)
if err != nil { if err != nil {
slog.Error("Firewall.Setup", slog.Any("error", err)) slog.Error("s.Firewall.Setup", slog.Any("error", err))
return err return err
} }
if s.cfg.DelTCPTimestamp || s.cfg.SetIPID { if s.cfg.DelTCPTimestamp || s.cfg.SetIPID {

View File

@ -56,20 +56,24 @@ func (s *Server) Start() (err error) {
if s.listener, err = net.Listen("tcp", s.Cfg.ListenAddr); err != nil { if s.listener, err = net.Listen("tcp", s.Cfg.ListenAddr); err != nil {
return fmt.Errorf("net.Listen: %w", err) return fmt.Errorf("net.Listen: %w", err)
} }
var client net.Conn
for { go func() {
if client, err = s.listener.Accept(); err != nil { var client net.Conn
if errors.Is(err, syscall.EMFILE) { for {
time.Sleep(time.Second) if client, err = s.listener.Accept(); err != nil {
} else if errors.Is(err, net.ErrClosed) { if errors.Is(err, syscall.EMFILE) {
return nil time.Sleep(time.Second)
} else if errors.Is(err, net.ErrClosed) {
return
}
slog.Error("s.listener.Accept", slog.Any("error", err))
continue
} }
slog.Error("s.listener.Accept", slog.Any("error", err)) slog.Debug("Accept connection", slog.String("addr", client.RemoteAddr().String()))
continue go s.HandleClient(client)
} }
slog.Debug("Accept connection", slog.String("addr", client.RemoteAddr().String())) }()
go s.HandleClient(client) return nil
}
} }
func (s *Server) Close() error { func (s *Server) Close() error {

View File

@ -63,20 +63,24 @@ func (s *Server) Start() (err error) {
if s.listener, err = net.Listen("tcp", s.Cfg.ListenAddr); err != nil { if s.listener, err = net.Listen("tcp", s.Cfg.ListenAddr); err != nil {
return fmt.Errorf("net.Listen: %w", err) return fmt.Errorf("net.Listen: %w", err)
} }
var client net.Conn
for { go func() {
if client, err = s.listener.Accept(); err != nil { var client net.Conn
if errors.Is(err, syscall.EMFILE) { for {
time.Sleep(time.Second) if client, err = s.listener.Accept(); err != nil {
} else if errors.Is(err, net.ErrClosed) { if errors.Is(err, syscall.EMFILE) {
return nil time.Sleep(time.Second)
} else if errors.Is(err, net.ErrClosed) {
return
}
slog.Error("s.listener.Accept", slog.Any("error", err))
continue
} }
slog.Error("s.listener.Accept", slog.Any("error", err)) slog.Debug("Accept connection", slog.String("addr", client.RemoteAddr().String()))
continue go s.HandleClient(client)
} }
slog.Debug("Accept connection", slog.String("addr", client.RemoteAddr().String())) }()
go s.HandleClient(client) return nil
}
} }
// handleClient performs SOCKS5 negotiation and dispatches TCP/UDP handling. // handleClient performs SOCKS5 negotiation and dispatches TCP/UDP handling.

View File

@ -64,7 +64,7 @@ func (s *Server) Start() error {
err = s.Firewall.Setup(s.Cfg) err = s.Firewall.Setup(s.Cfg)
if err != nil { if err != nil {
slog.Error(fmt.Sprintf("s.Firewall.Setup: %v", err)) slog.Error("s.Firewall.Setup", slog.Any("error", err))
return err return err
} }
lc := net.ListenConfig{ lc := net.ListenConfig{
@ -87,20 +87,24 @@ func (s *Server) Start() error {
if s.listener, err = lc.Listen(context.TODO(), "tcp", s.Cfg.ListenAddr); err != nil { if s.listener, err = lc.Listen(context.TODO(), "tcp", s.Cfg.ListenAddr); err != nil {
return fmt.Errorf("net.Listen: %w", err) return fmt.Errorf("net.Listen: %w", err)
} }
var client net.Conn
for { go func() {
if client, err = s.listener.Accept(); err != nil { var client net.Conn
if errors.Is(err, syscall.EMFILE) { for {
time.Sleep(time.Second) if client, err = s.listener.Accept(); err != nil {
} else if errors.Is(err, net.ErrClosed) { if errors.Is(err, syscall.EMFILE) {
return nil time.Sleep(time.Second)
} else if errors.Is(err, net.ErrClosed) {
return
}
slog.Error(fmt.Sprintf("s.listener.Accept: %v", err))
continue
} }
slog.Error(fmt.Sprintf("s.listener.Accept: %v", err)) slog.Debug(fmt.Sprintf("Accept connection from %s", client.RemoteAddr().String()))
continue go s.HandleClient(client)
} }
slog.Debug(fmt.Sprintf("Accept connection from %s", client.RemoteAddr().String())) }()
go s.HandleClient(client) return nil
}
} }
func (s *Server) Close() error { func (s *Server) Close() error {

View File

@ -5,7 +5,6 @@ import (
"log/slog" "log/slog"
"os" "os"
"os/signal" "os/signal"
"sync"
"syscall" "syscall"
"github.com/sunbk201/ua3f/internal/config" "github.com/sunbk201/ua3f/internal/config"
@ -57,34 +56,36 @@ func main() {
return return
} }
cleanup := make(chan os.Signal, 1)
signal.Notify(cleanup, syscall.SIGQUIT, syscall.SIGINT, syscall.SIGTERM)
var shutdownOnce sync.Once
shutdown := func() { shutdown := func() {
shutdownOnce.Do(func() { if err := helper.Close(); err != nil {
if err := helper.Close(); err != nil { slog.Error("helper.Close", slog.Any("error", err))
slog.Error("helper.Close", slog.Any("error", err)) }
} if err := srv.Close(); err != nil {
if err := srv.Close(); err != nil { slog.Error("srv.Close", slog.Any("error", err))
slog.Error("srv.Close", slog.Any("error", err)) }
} slog.Info("UA3F exit")
slog.Info("UA3F exited gracefully")
})
} }
go statistics.StartRecorder() go statistics.StartRecorder()
go func() {
<-cleanup
shutdown()
os.Exit(0)
}()
defer shutdown()
if err := srv.Start(); err != nil { if err := srv.Start(); err != nil {
slog.Error("srv.Start", slog.Any("error", err)) slog.Error("srv.Start", slog.Any("error", err))
shutdown()
return return
} }
cleanup := make(chan os.Signal, 1)
signal.Notify(cleanup, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGINT, syscall.SIGTERM)
for {
s := <-cleanup
slog.Info("Received signal", slog.String("signal", s.String()))
switch s {
case syscall.SIGQUIT, syscall.SIGINT, syscall.SIGTERM:
shutdown()
return
case syscall.SIGHUP:
default:
return
}
}
} }