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  }