Example #1
0
func doMain() error {
	if err := logging.Init(); err != nil {
		return err
	}

	// Schedule cleanup actions
	handleSignals()
	addExitFunc(func() {
		if err := logging.Close(); err != nil {
			log.Debugf("Error closing log: %v", err)
		}
	})
	addExitFunc(quitSystray)

	i18nInit()
	if showui {
		if err := configureSystemTray(); err != nil {
			return err
		}
	}
	displayVersion()

	parseFlags()

	cfg, err := config.Init(packageVersion)
	if err != nil {
		return fmt.Errorf("Unable to initialize configuration: %v", err)
	}
	go func() {
		err := config.Run(func(updated *config.Config) {
			configUpdates <- updated
		})
		if err != nil {
			exit(err)
		}
	}()
	if *help || cfg.Addr == "" || (cfg.Role != "server" && cfg.Role != "client") {
		flag.Usage()
		return fmt.Errorf("Wrong arguments")
	}

	finishProfiling := profiling.Start(cfg.CpuProfile, cfg.MemProfile)
	defer finishProfiling()

	// Configure stats initially
	if err := statreporter.Configure(cfg.Stats); err != nil {
		return err
	}

	log.Debug("Running proxy")
	if cfg.IsDownstream() {
		// This will open a proxy on the address and port given by -addr
		go runClientProxy(cfg)
	} else {
		go runServerProxy(cfg)
	}

	return waitForExit()
}
Example #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
}