Beispiel #1
0
func applyClientConfig(client *client.Client, cfg *config.Config) {
	cfgMutex.Lock()
	defer cfgMutex.Unlock()

	autoupdate.Configure(cfg)
	logging.Configure(cfg.Addr, cfg.CloudConfigCA, cfg.InstanceId,
		version, revisionDate)
	settings.Configure(cfg, version, revisionDate, buildDate)
	proxiedsites.Configure(cfg.ProxiedSites)
	analytics.Configure(cfg, version)
	log.Debugf("Proxy all traffic or not: %v", cfg.Client.ProxyAll)
	ServeProxyAllPacFile(cfg.Client.ProxyAll)
	// Note - we deliberately ignore the error from statreporter.Configure here
	_ = statreporter.Configure(cfg.Stats)

	// Update client configuration and get the highest QOS dialer available.
	hqfd := client.Configure(cfg.Client)
	if hqfd == nil {
		log.Errorf("No fronted dialer available, not enabling geolocation, config lookup, or stats")
	} else {
		// Give everyone their own *http.Client that uses the highest QOS dialer. Separate
		// clients for everyone avoids data races configuring those clients.
		config.Configure(hqfd.NewDirectDomainFronter())
		geolookup.Configure(hqfd.NewDirectDomainFronter())
		statserver.Configure(hqfd.NewDirectDomainFronter())
		// Note we don't call Configure on analytics here, as that would
		// result in an extra analytics call and double counting.
	}
}
Beispiel #2
0
// Run runs a client proxy. It blocks as long as the proxy is running.
func Run(httpProxyAddr string,
	socksProxyAddr string,
	configDir string,
	stickyConfig bool,
	proxyAll func() bool,
	flagsAsMap map[string]interface{},
	beforeStart func(cfg *config.Config) bool,
	afterStart func(cfg *config.Config),
	onConfigUpdate func(cfg *config.Config),
	onError func(err error)) error {
	displayVersion()

	log.Debug("Initializing configuration")
	cfg, err := config.Init(PackageVersion, configDir, stickyConfig, flagsAsMap)
	if err != nil {
		return fmt.Errorf("Unable to initialize configuration: %v", err)
	}

	client := client.NewClient()

	if beforeStart(cfg) {
		log.Debug("Preparing to start client proxy")
		geolookup.Configure(client.Addr)
		cfgMutex.Lock()
		applyClientConfig(client, cfg, proxyAll)
		cfgMutex.Unlock()

		go func() {
			err := config.Run(func(updated *config.Config) {
				log.Debug("Applying updated configuration")
				cfgMutex.Lock()
				applyClientConfig(client, updated, proxyAll)
				onConfigUpdate(updated)
				cfgMutex.Unlock()
				log.Debug("Applied updated configuration")
			})
			if err != nil {
				onError(err)
			}
		}()

		if socksProxyAddr != "" {
			go func() {
				log.Debug("Starting client SOCKS5 proxy")
				err = client.ListenAndServeSOCKS5(socksProxyAddr)
				if err != nil {
					log.Errorf("Unable to start SOCKS5 proxy: %v", err)
				}
			}()
		}

		log.Debug("Starting client HTTP proxy")
		err = client.ListenAndServeHTTP(httpProxyAddr, func() {
			log.Debug("Started client HTTP proxy")
			// We finally tell the config package to start polling for new configurations.
			// This is the final step because the config polling itself uses the full
			// proxying capabilities of Lantern, so it needs everything to be properly
			// set up with at least an initial bootstrap config (on first run) to
			// complete successfully.
			config.StartPolling()
			afterStart(cfg)
		})
		if err != nil {
			log.Errorf("Error starting client proxy: %v", err)
			onError(err)
		}
	}

	return nil
}