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