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 {
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
// 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) {

View File

@ -42,7 +42,7 @@ func New(cfg *config.Config) *Server {
func (s *Server) Start() (err error) {
err = s.Firewall.Setup(s.cfg)
if err != nil {
slog.Error("Firewall.Setup", slog.Any("error", err))
slog.Error("s.Firewall.Setup", slog.Any("error", err))
return err
}
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 {
return fmt.Errorf("net.Listen: %w", err)
}
var client net.Conn
for {
if client, err = s.listener.Accept(); err != nil {
if errors.Is(err, syscall.EMFILE) {
time.Sleep(time.Second)
} else if errors.Is(err, net.ErrClosed) {
return nil
go func() {
var client net.Conn
for {
if client, err = s.listener.Accept(); err != nil {
if errors.Is(err, syscall.EMFILE) {
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))
continue
slog.Debug("Accept connection", slog.String("addr", client.RemoteAddr().String()))
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 {

View File

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

View File

@ -64,7 +64,7 @@ func (s *Server) Start() error {
err = s.Firewall.Setup(s.Cfg)
if err != nil {
slog.Error(fmt.Sprintf("s.Firewall.Setup: %v", err))
slog.Error("s.Firewall.Setup", slog.Any("error", err))
return err
}
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 {
return fmt.Errorf("net.Listen: %w", err)
}
var client net.Conn
for {
if client, err = s.listener.Accept(); err != nil {
if errors.Is(err, syscall.EMFILE) {
time.Sleep(time.Second)
} else if errors.Is(err, net.ErrClosed) {
return nil
go func() {
var client net.Conn
for {
if client, err = s.listener.Accept(); err != nil {
if errors.Is(err, syscall.EMFILE) {
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))
continue
slog.Debug(fmt.Sprintf("Accept connection from %s", client.RemoteAddr().String()))
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 {

View File

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