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  }