github.com/database64128/shadowsocks-go@v1.10.2-0.20240315062903-143a773533f1/service/service.go (about) 1 package service 2 3 import ( 4 "context" 5 "errors" 6 "fmt" 7 8 "github.com/database64128/shadowsocks-go/api" 9 "github.com/database64128/shadowsocks-go/conn" 10 "github.com/database64128/shadowsocks-go/cred" 11 "github.com/database64128/shadowsocks-go/dns" 12 "github.com/database64128/shadowsocks-go/router" 13 "github.com/database64128/shadowsocks-go/stats" 14 "github.com/database64128/shadowsocks-go/zerocopy" 15 "go.uber.org/zap" 16 ) 17 18 var errNetworkDisabled = errors.New("this network (tcp or udp) is disabled") 19 20 // Relay is a relay service that accepts incoming connections/sessions on a server 21 // and dispatches them to a client selected by the router. 22 type Relay interface { 23 // String returns the relay service's name. 24 String() string 25 26 // Start starts the relay service. 27 Start(ctx context.Context) error 28 29 // Stop stops the relay service. 30 Stop() error 31 } 32 33 // Config is the main configuration structure. 34 // It may be marshaled as or unmarshaled from JSON. 35 type Config struct { 36 Servers []ServerConfig `json:"servers"` 37 Clients []ClientConfig `json:"clients"` 38 DNS []dns.ResolverConfig `json:"dns"` 39 Router router.Config `json:"router"` 40 Stats stats.Config `json:"stats"` 41 API api.Config `json:"api"` 42 } 43 44 // Manager initializes the service manager. 45 // 46 // Initialization order: clients -> DNS -> router -> servers 47 func (sc *Config) Manager(logger *zap.Logger) (*Manager, error) { 48 if len(sc.Servers) == 0 { 49 return nil, errors.New("no services to start") 50 } 51 52 if len(sc.Clients) == 0 { 53 sc.Clients = []ClientConfig{ 54 { 55 Name: "direct", 56 Protocol: "direct", 57 EnableTCP: true, 58 DialerTFO: true, 59 EnableUDP: true, 60 MTU: 1500, 61 }, 62 } 63 } 64 65 listenConfigCache := conn.NewListenConfigCache() 66 dialerCache := conn.NewDialerCache() 67 tcpClientMap := make(map[string]zerocopy.TCPClient, len(sc.Clients)) 68 udpClientMap := make(map[string]zerocopy.UDPClient, len(sc.Clients)) 69 var maxClientPackerHeadroom zerocopy.Headroom 70 71 for i := range sc.Clients { 72 clientConfig := &sc.Clients[i] 73 clientName := clientConfig.Name 74 if err := clientConfig.Initialize(listenConfigCache, dialerCache, logger); err != nil { 75 return nil, fmt.Errorf("failed to initialize client %s: %w", clientName, err) 76 } 77 78 tcpClient, err := clientConfig.TCPClient() 79 switch err { 80 case errNetworkDisabled: 81 case nil: 82 tcpClientMap[clientName] = tcpClient 83 default: 84 return nil, fmt.Errorf("failed to create TCP client for %s: %w", clientName, err) 85 } 86 87 udpClient, err := clientConfig.UDPClient() 88 switch err { 89 case errNetworkDisabled: 90 case nil: 91 udpClientMap[clientName] = udpClient 92 maxClientPackerHeadroom = zerocopy.MaxHeadroom(maxClientPackerHeadroom, udpClient.Info().PackerHeadroom) 93 default: 94 return nil, fmt.Errorf("failed to create UDP client for %s: %w", clientName, err) 95 } 96 } 97 98 resolvers := make([]dns.SimpleResolver, len(sc.DNS)) 99 resolverMap := make(map[string]dns.SimpleResolver, len(sc.DNS)) 100 101 for i := range sc.DNS { 102 resolver, err := sc.DNS[i].SimpleResolver(tcpClientMap, udpClientMap, logger) 103 if err != nil { 104 return nil, fmt.Errorf("failed to create DNS resolver %s: %w", sc.DNS[i].Name, err) 105 } 106 107 resolvers[i] = resolver 108 resolverMap[sc.DNS[i].Name] = resolver 109 } 110 111 serverIndexByName := make(map[string]int, len(sc.Servers)) 112 113 for i := range sc.Servers { 114 serverIndexByName[sc.Servers[i].Name] = i 115 } 116 117 router, err := sc.Router.Router(logger, resolvers, resolverMap, tcpClientMap, udpClientMap, serverIndexByName) 118 if err != nil { 119 return nil, fmt.Errorf("failed to create router: %w", err) 120 } 121 122 credman := cred.NewManager(logger) 123 apiServer, apiSM, err := sc.API.Server(logger) 124 if err != nil { 125 return nil, fmt.Errorf("failed to create API server: %w", err) 126 } 127 128 services := make([]Relay, 0, 2+2*len(sc.Servers)) 129 services = append(services, credman) 130 if apiServer != nil { 131 services = append(services, apiServer) 132 } 133 134 for i := range sc.Servers { 135 serverConfig := &sc.Servers[i] 136 collector := sc.Stats.Collector() 137 if err := serverConfig.Initialize(listenConfigCache, collector, router, logger, i); err != nil { 138 return nil, fmt.Errorf("failed to initialize server %s: %w", serverConfig.Name, err) 139 } 140 141 tcpRelay, err := serverConfig.TCPRelay() 142 switch err { 143 case errNetworkDisabled: 144 case nil: 145 services = append(services, tcpRelay) 146 default: 147 return nil, fmt.Errorf("failed to create TCP relay service for %s: %w", serverConfig.Name, err) 148 } 149 150 udpRelay, err := serverConfig.UDPRelay(maxClientPackerHeadroom) 151 switch err { 152 case errNetworkDisabled: 153 case nil: 154 services = append(services, udpRelay) 155 default: 156 return nil, fmt.Errorf("failed to create UDP relay service for %s: %w", serverConfig.Name, err) 157 } 158 159 if err = serverConfig.PostInit(credman, apiSM); err != nil { 160 return nil, fmt.Errorf("failed to post-initialize server %s: %w", serverConfig.Name, err) 161 } 162 } 163 164 return &Manager{services, router, logger}, nil 165 } 166 167 // Manager manages the services. 168 type Manager struct { 169 services []Relay 170 router *router.Router 171 logger *zap.Logger 172 } 173 174 // Start starts all configured services. 175 func (m *Manager) Start(ctx context.Context) error { 176 for _, s := range m.services { 177 if err := s.Start(ctx); err != nil { 178 return fmt.Errorf("failed to start %s: %w", s.String(), err) 179 } 180 } 181 return nil 182 } 183 184 // Stop stops all running services. 185 func (m *Manager) Stop() { 186 for _, s := range m.services { 187 if err := s.Stop(); err != nil { 188 m.logger.Warn("Failed to stop service", 189 zap.Stringer("service", s), 190 zap.Error(err), 191 ) 192 } 193 m.logger.Info("Stopped service", zap.Stringer("service", s)) 194 } 195 } 196 197 // Close closes the manager. 198 func (m *Manager) Close() { 199 if err := m.router.Close(); err != nil { 200 m.logger.Warn("Failed to close router", zap.Error(err)) 201 } 202 }