github.com/mysteriumnetwork/node@v0.0.0-20240516044423-365054f76801/cmd/di_desktop.go (about)

     1  /*
     2   * Copyright (C) 2018 The "MysteriumNetwork/node" Authors.
     3   *
     4   * This program is free software: you can redistribute it and/or modify
     5   * it under the terms of the GNU General Public License as published by
     6   * the Free Software Foundation, either version 3 of the License, or
     7   * (at your option) any later version.
     8   *
     9   * This program is distributed in the hope that it will be useful,
    10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12   * GNU General Public License for more details.
    13   *
    14   * You should have received a copy of the GNU General Public License
    15   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    16   */
    17  
    18  package cmd
    19  
    20  import (
    21  	"time"
    22  
    23  	"github.com/mysteriumnetwork/node/core/policy/requested"
    24  
    25  	"github.com/pkg/errors"
    26  	"github.com/rs/zerolog/log"
    27  
    28  	"github.com/mysteriumnetwork/node/config"
    29  	"github.com/mysteriumnetwork/node/core/connection"
    30  	"github.com/mysteriumnetwork/node/core/node"
    31  	"github.com/mysteriumnetwork/node/core/policy/localcopy"
    32  	"github.com/mysteriumnetwork/node/core/service"
    33  	"github.com/mysteriumnetwork/node/core/service/servicestate"
    34  	"github.com/mysteriumnetwork/node/dns"
    35  	"github.com/mysteriumnetwork/node/mmn"
    36  	"github.com/mysteriumnetwork/node/nat"
    37  	"github.com/mysteriumnetwork/node/p2p"
    38  	"github.com/mysteriumnetwork/node/services/datatransfer"
    39  	"github.com/mysteriumnetwork/node/services/dvpn"
    40  	service_noop "github.com/mysteriumnetwork/node/services/noop"
    41  	service_openvpn "github.com/mysteriumnetwork/node/services/openvpn"
    42  	openvpn_service "github.com/mysteriumnetwork/node/services/openvpn/service"
    43  	"github.com/mysteriumnetwork/node/services/scraping"
    44  	"github.com/mysteriumnetwork/node/services/wireguard"
    45  	wireguard_connection "github.com/mysteriumnetwork/node/services/wireguard/connection"
    46  	"github.com/mysteriumnetwork/node/services/wireguard/endpoint"
    47  	netstack_provider "github.com/mysteriumnetwork/node/services/wireguard/endpoint/netstack-provider"
    48  	"github.com/mysteriumnetwork/node/services/wireguard/resources"
    49  	wireguard_service "github.com/mysteriumnetwork/node/services/wireguard/service"
    50  	"github.com/mysteriumnetwork/node/session/pingpong"
    51  )
    52  
    53  // bootstrapServices loads all the components required for running services
    54  func (di *Dependencies) bootstrapServices(nodeOptions node.Options) error {
    55  	if nodeOptions.Consumer {
    56  		log.Debug().Msg("Skipping services bootstrap for consumer mode")
    57  		return nil
    58  	}
    59  
    60  	err := di.bootstrapServiceComponents(nodeOptions)
    61  	if err != nil {
    62  		return errors.Wrap(err, "service bootstrap failed")
    63  	}
    64  
    65  	if config.GetBool(config.FlagUserspace) {
    66  		netstack_provider.InitUserspaceShaper(di.EventBus)
    67  	}
    68  	di.bootstrapServiceOpenvpn(nodeOptions)
    69  	di.bootstrapServiceNoop(nodeOptions)
    70  	resourcesAllocator := resources.NewAllocator(di.PortPool, wireguard_service.GetOptions().Subnet)
    71  
    72  	dnsHandler, err := dns.ResolveViaSystem()
    73  	if err != nil {
    74  		log.Error().Err(err).Msg("Provider DNS are not available")
    75  		return err
    76  	}
    77  
    78  	di.dnsProxy = dns.NewProxy("", config.GetInt(config.FlagDNSListenPort), dnsHandler)
    79  
    80  	// disable for mobile
    81  	if !nodeOptions.Mobile {
    82  		di.bootstrapServiceWireguard(nodeOptions, resourcesAllocator, di.WireguardClientFactory)
    83  	}
    84  	di.bootstrapServiceScraping(nodeOptions, resourcesAllocator, di.WireguardClientFactory)
    85  	di.bootstrapServiceDataTransfer(nodeOptions, resourcesAllocator, di.WireguardClientFactory)
    86  	di.bootstrapServiceDVPN(nodeOptions, resourcesAllocator, di.WireguardClientFactory)
    87  
    88  	return nil
    89  }
    90  
    91  func (di *Dependencies) bootstrapServiceWireguard(nodeOptions node.Options, resourcesAllocator *resources.Allocator, wgClientFactory *endpoint.WgClientFactory) {
    92  	di.ServiceRegistry.Register(
    93  		wireguard.ServiceType,
    94  		func(serviceOptions service.Options) (service.Service, error) {
    95  			loc, err := di.LocationResolver.DetectLocation()
    96  			if err != nil {
    97  				return nil, err
    98  			}
    99  
   100  			svc := wireguard_service.NewManager(
   101  				di.IPResolver,
   102  				loc.Country,
   103  				di.NATService,
   104  				di.EventBus,
   105  				di.ServiceFirewall,
   106  				resourcesAllocator,
   107  				wgClientFactory,
   108  				di.dnsProxy,
   109  			)
   110  			return svc, nil
   111  		},
   112  	)
   113  }
   114  
   115  func (di *Dependencies) bootstrapServiceScraping(nodeOptions node.Options, resourcesAllocator *resources.Allocator, wgClientFactory *endpoint.WgClientFactory) {
   116  	di.ServiceRegistry.Register(
   117  		scraping.ServiceType,
   118  		func(serviceOptions service.Options) (service.Service, error) {
   119  			loc, err := di.LocationResolver.DetectLocation()
   120  			if err != nil {
   121  				return nil, err
   122  			}
   123  
   124  			svc := wireguard_service.NewManager(
   125  				di.IPResolver,
   126  				loc.Country,
   127  				di.NATService,
   128  				di.EventBus,
   129  				di.ServiceFirewall,
   130  				resourcesAllocator,
   131  				wgClientFactory,
   132  				di.dnsProxy,
   133  			)
   134  			return svc, nil
   135  		},
   136  	)
   137  }
   138  
   139  func (di *Dependencies) bootstrapServiceDataTransfer(nodeOptions node.Options, resourcesAllocator *resources.Allocator, wgClientFactory *endpoint.WgClientFactory) {
   140  	di.ServiceRegistry.Register(
   141  		datatransfer.ServiceType,
   142  		func(serviceOptions service.Options) (service.Service, error) {
   143  			loc, err := di.LocationResolver.DetectLocation()
   144  			if err != nil {
   145  				return nil, err
   146  			}
   147  
   148  			svc := wireguard_service.NewManager(
   149  				di.IPResolver,
   150  				loc.Country,
   151  				di.NATService,
   152  				di.EventBus,
   153  				di.ServiceFirewall,
   154  				resourcesAllocator,
   155  				wgClientFactory,
   156  				di.dnsProxy,
   157  			)
   158  			return svc, nil
   159  		},
   160  	)
   161  }
   162  
   163  func (di *Dependencies) bootstrapServiceDVPN(nodeOptions node.Options, resourcesAllocator *resources.Allocator, wgClientFactory *endpoint.WgClientFactory) {
   164  	di.ServiceRegistry.Register(
   165  		dvpn.ServiceType,
   166  		func(serviceOptions service.Options) (service.Service, error) {
   167  			loc, err := di.LocationResolver.DetectLocation()
   168  			if err != nil {
   169  				return nil, err
   170  			}
   171  
   172  			svc := wireguard_service.NewManager(
   173  				di.IPResolver,
   174  				loc.Country,
   175  				di.NATService,
   176  				di.EventBus,
   177  				di.ServiceFirewall,
   178  				resourcesAllocator,
   179  				wgClientFactory,
   180  				di.dnsProxy,
   181  			)
   182  			return svc, nil
   183  		},
   184  	)
   185  }
   186  
   187  func (di *Dependencies) bootstrapServiceOpenvpn(nodeOptions node.Options) {
   188  	createService := func(serviceOptions service.Options) (service.Service, error) {
   189  		if err := nodeOptions.Openvpn.Check(); err != nil {
   190  			return nil, err
   191  		}
   192  
   193  		loc, err := di.LocationResolver.DetectLocation()
   194  		if err != nil {
   195  			return nil, err
   196  		}
   197  
   198  		transportOptions := serviceOptions.(openvpn_service.Options)
   199  
   200  		manager := openvpn_service.NewManager(
   201  			nodeOptions,
   202  			transportOptions,
   203  			loc.Country,
   204  			di.IPResolver,
   205  			di.ServiceSessions,
   206  			di.NATService,
   207  			di.PortPool,
   208  			di.EventBus,
   209  			di.ServiceFirewall,
   210  		)
   211  		return manager, nil
   212  	}
   213  	di.ServiceRegistry.Register(service_openvpn.ServiceType, createService)
   214  }
   215  
   216  func (di *Dependencies) bootstrapServiceNoop(nodeOptions node.Options) {
   217  	di.ServiceRegistry.Register(
   218  		service_noop.ServiceType,
   219  		func(serviceOptions service.Options) (service.Service, error) {
   220  			return service_noop.NewManager(), nil
   221  		},
   222  	)
   223  }
   224  
   225  func (di *Dependencies) bootstrapHermesPromiseSettler(nodeOptions node.Options) error {
   226  	di.HermesChannelRepository = pingpong.NewHermesChannelRepository(
   227  		di.HermesPromiseStorage,
   228  		di.BCHelper,
   229  		di.EventBus,
   230  		di.BeneficiaryProvider,
   231  		di.HermesCaller,
   232  		di.AddressProvider,
   233  		di.SignerFactory,
   234  		di.Keystore,
   235  	)
   236  
   237  	if err := di.HermesChannelRepository.Subscribe(di.EventBus); err != nil {
   238  		log.Error().Err(err).Msg("Failed to subscribe channel repository")
   239  		return errors.Wrap(err, "could not subscribe channel repository to relevant events")
   240  	}
   241  
   242  	settler := pingpong.NewHermesPromiseSettler(
   243  		di.Transactor,
   244  		di.HermesPromiseStorage,
   245  		di.HermesPromiseHandler,
   246  		di.AddressProvider,
   247  		func(hermesURL string) pingpong.HermesHTTPRequester {
   248  			return pingpong.NewHermesCaller(di.HTTPClient, hermesURL)
   249  		},
   250  		di.HermesURLGetter,
   251  		di.HermesChannelRepository,
   252  		di.BCHelper,
   253  		di.IdentityRegistry,
   254  		di.Keystore,
   255  		di.SettlementHistoryStorage,
   256  		di.EventBus,
   257  		di.ObserverAPI,
   258  		di.BeneficiaryAddressStorage,
   259  		pingpong.HermesPromiseSettlerConfig{
   260  			BalanceThreshold:        nodeOptions.Payments.HermesPromiseSettlingThreshold,
   261  			MaxFeeThreshold:         nodeOptions.Payments.MaxFeeSettlingThreshold,
   262  			MinAutoSettleAmount:     nodeOptions.Payments.MinAutoSettleAmount,
   263  			MaxUnSettledAmount:      nodeOptions.Payments.MaxUnSettledAmount,
   264  			SettlementCheckTimeout:  nodeOptions.Payments.SettlementTimeout,
   265  			SettlementCheckInterval: nodeOptions.Payments.SettlementRecheckInterval,
   266  			L1ChainID:               nodeOptions.Chains.Chain1.ChainID,
   267  			L2ChainID:               nodeOptions.Chains.Chain2.ChainID,
   268  		},
   269  	)
   270  	if err := settler.Subscribe(di.EventBus); err != nil {
   271  		return errors.Wrap(err, "could not subscribe promise settler to relevant events")
   272  	}
   273  
   274  	di.HermesPromiseSettler = settler
   275  	return nil
   276  }
   277  
   278  // bootstrapServiceComponents initiates ServicesManager dependency
   279  func (di *Dependencies) bootstrapServiceComponents(nodeOptions node.Options) error {
   280  	di.NATService = nat.NewService()
   281  	if err := di.NATService.Enable(); err != nil {
   282  		log.Warn().Err(err).Msg("Failed to enable NAT forwarding")
   283  	}
   284  	di.ServiceRegistry = service.NewRegistry()
   285  
   286  	di.ServiceSessions = service.NewSessionPool(di.EventBus)
   287  
   288  	di.PolicyOracle = localcopy.NewOracle(
   289  		di.HTTPClient,
   290  		config.GetString(config.FlagAccessPolicyAddress),
   291  		config.GetDuration(config.FlagAccessPolicyFetchInterval),
   292  		config.GetBool(config.FlagAccessPolicyFetchingEnabled),
   293  	)
   294  	go di.PolicyOracle.Start()
   295  
   296  	di.PolicyProvider = requested.NewRequestedProvider(
   297  		di.HTTPClient,
   298  		config.GetString(config.FlagAccessPolicyAddress),
   299  	)
   300  
   301  	di.HermesStatusChecker = pingpong.NewHermesStatusChecker(di.BCHelper, di.ObserverAPI, nodeOptions.Payments.HermesStatusRecheckInterval)
   302  
   303  	newP2PSessionHandler := func(serviceInstance *service.Instance, channel p2p.Channel) *service.SessionManager {
   304  		paymentEngineFactory := pingpong.InvoiceFactoryCreator(
   305  			channel, nodeOptions.Payments.ProviderInvoiceFrequency, nodeOptions.Payments.ProviderLimitInvoiceFrequency,
   306  			pingpong.PromiseWaitTimeout, di.ProviderInvoiceStorage,
   307  			pingpong.DefaultHermesFailureCount,
   308  			uint16(nodeOptions.Payments.MaxAllowedPaymentPercentile),
   309  			nodeOptions.Payments.MaxUnpaidInvoiceValue,
   310  			nodeOptions.Payments.LimitUnpaidInvoiceValue,
   311  			di.HermesStatusChecker,
   312  			di.EventBus,
   313  			di.HermesPromiseHandler,
   314  			di.AddressProvider,
   315  			di.ObserverAPI,
   316  		)
   317  		return service.NewSessionManager(
   318  			serviceInstance,
   319  			di.ServiceSessions,
   320  			paymentEngineFactory,
   321  			di.EventBus,
   322  			channel,
   323  			service.DefaultConfig(),
   324  			di.PricingHelper,
   325  		)
   326  	}
   327  
   328  	di.ServicesManager = service.NewManager(
   329  		di.ServiceRegistry,
   330  		di.DiscoveryFactory,
   331  		di.EventBus,
   332  		di.PolicyOracle,
   333  		di.PolicyProvider,
   334  		di.P2PListener,
   335  		newP2PSessionHandler,
   336  		di.SessionConnectivityStatusStorage,
   337  		di.LocationResolver,
   338  	)
   339  
   340  	serviceCleaner := service.Cleaner{SessionStorage: di.ServiceSessions}
   341  	if err := di.EventBus.Subscribe(servicestate.AppTopicServiceStatus, serviceCleaner.HandleServiceStatus); err != nil {
   342  		log.Error().Err(err).Msg("Failed to subscribe service cleaner")
   343  	}
   344  
   345  	return nil
   346  }
   347  
   348  func (di *Dependencies) registerConnections(nodeOptions node.Options) {
   349  	di.registerOpenvpnConnection(nodeOptions)
   350  	di.registerNoopConnection()
   351  
   352  	resourceAllocator := resources.NewAllocator(nil, wireguard_service.DefaultOptions.Subnet)
   353  
   354  	di.registerWireguardConnection(nodeOptions, resourceAllocator, di.WireguardClientFactory)
   355  	di.registerScrapingConnection(nodeOptions, resourceAllocator, di.WireguardClientFactory)
   356  	di.registerDataTransferConnection(nodeOptions, resourceAllocator, di.WireguardClientFactory)
   357  	di.registerDVPNConnection(nodeOptions, resourceAllocator, di.WireguardClientFactory)
   358  }
   359  
   360  func (di *Dependencies) registerWireguardConnection(nodeOptions node.Options, resourceAllocator *resources.Allocator, wgClientFactory *endpoint.WgClientFactory) {
   361  	wireguard.Bootstrap()
   362  	handshakeWaiter := wireguard_connection.NewHandshakeWaiter()
   363  	endpointFactory := func() (wireguard.ConnectionEndpoint, error) {
   364  		return endpoint.NewConnectionEndpoint(resourceAllocator, wgClientFactory)
   365  	}
   366  	connFactory := func() (connection.Connection, error) {
   367  		opts := wireguard_connection.Options{
   368  			DNSScriptDir:     nodeOptions.Directories.Script,
   369  			HandshakeTimeout: 1 * time.Minute,
   370  		}
   371  		return wireguard_connection.NewConnection(opts, di.IPResolver, endpointFactory, handshakeWaiter)
   372  	}
   373  	di.ConnectionRegistry.Register(wireguard.ServiceType, connFactory)
   374  }
   375  
   376  func (di *Dependencies) registerScrapingConnection(nodeOptions node.Options, resourceAllocator *resources.Allocator, wgClientFactory *endpoint.WgClientFactory) {
   377  	scraping.Bootstrap()
   378  	handshakeWaiter := wireguard_connection.NewHandshakeWaiter()
   379  	endpointFactory := func() (wireguard.ConnectionEndpoint, error) {
   380  		return endpoint.NewConnectionEndpoint(resourceAllocator, wgClientFactory)
   381  	}
   382  	connFactory := func() (connection.Connection, error) {
   383  		opts := wireguard_connection.Options{
   384  			DNSScriptDir:     nodeOptions.Directories.Script,
   385  			HandshakeTimeout: 1 * time.Minute,
   386  		}
   387  		return wireguard_connection.NewConnection(opts, di.IPResolver, endpointFactory, handshakeWaiter)
   388  	}
   389  	di.ConnectionRegistry.Register(scraping.ServiceType, connFactory)
   390  }
   391  
   392  func (di *Dependencies) registerDataTransferConnection(nodeOptions node.Options, resourceAllocator *resources.Allocator, wgClientFactory *endpoint.WgClientFactory) {
   393  	datatransfer.Bootstrap()
   394  	handshakeWaiter := wireguard_connection.NewHandshakeWaiter()
   395  	endpointFactory := func() (wireguard.ConnectionEndpoint, error) {
   396  		return endpoint.NewConnectionEndpoint(resourceAllocator, wgClientFactory)
   397  	}
   398  	connFactory := func() (connection.Connection, error) {
   399  		opts := wireguard_connection.Options{
   400  			DNSScriptDir:     nodeOptions.Directories.Script,
   401  			HandshakeTimeout: 1 * time.Minute,
   402  		}
   403  		return wireguard_connection.NewConnection(opts, di.IPResolver, endpointFactory, handshakeWaiter)
   404  	}
   405  	di.ConnectionRegistry.Register(datatransfer.ServiceType, connFactory)
   406  }
   407  
   408  func (di *Dependencies) registerDVPNConnection(nodeOptions node.Options, resourceAllocator *resources.Allocator, wgClientFactory *endpoint.WgClientFactory) {
   409  	dvpn.Bootstrap()
   410  	handshakeWaiter := wireguard_connection.NewHandshakeWaiter()
   411  	endpointFactory := func() (wireguard.ConnectionEndpoint, error) {
   412  		return endpoint.NewConnectionEndpoint(resourceAllocator, wgClientFactory)
   413  	}
   414  	connFactory := func() (connection.Connection, error) {
   415  		opts := wireguard_connection.Options{
   416  			DNSScriptDir:     nodeOptions.Directories.Script,
   417  			HandshakeTimeout: 1 * time.Minute,
   418  		}
   419  		return wireguard_connection.NewConnection(opts, di.IPResolver, endpointFactory, handshakeWaiter)
   420  	}
   421  	di.ConnectionRegistry.Register(dvpn.ServiceType, connFactory)
   422  }
   423  
   424  func (di *Dependencies) bootstrapMMN() error {
   425  	client := mmn.NewClient(di.HTTPClient, config.GetString(config.FlagMMNAPIAddress), di.SignerFactory)
   426  
   427  	di.MMN = mmn.NewMMN(di.IPResolver, client)
   428  	return di.MMN.Subscribe(di.EventBus)
   429  }