Esempio n. 1
0
// NewProgressEmitter creates a new progress emitter which emits
// DownloadProgress events every interval.
func NewProgressEmitter(cfg *config.Wrapper) *ProgressEmitter {
	t := &ProgressEmitter{
		stop:     make(chan struct{}),
		registry: make(map[string]*sharedPullerState),
		last:     make(map[string]map[string]*pullerProgress),
		timer:    time.NewTimer(time.Millisecond),
		mut:      sync.NewMutex(),
	}

	t.CommitConfiguration(config.Configuration{}, cfg.Raw())
	cfg.Subscribe(t)

	return t
}
Esempio n. 2
0
func newUsageReportingManager(cfg *config.Wrapper, m *model.Model) *usageReportingManager {
	mgr := &usageReportingManager{
		cfg:   cfg,
		model: m,
	}

	// Start UR if it's enabled.
	mgr.CommitConfiguration(config.Configuration{}, cfg.Raw())

	// Listen to future config changes so that we can start and stop as
	// appropriate.
	cfg.Subscribe(mgr)

	return mgr
}
Esempio n. 3
0
func NewService(cfg *config.Wrapper, tlsCfg *tls.Config) *Service {
	conns := make(chan *tls.Conn)

	service := &Service{
		Supervisor: suture.New("Service", suture.Spec{
			Log: func(log string) {
				l.Debugln(log)
			},
			FailureBackoff:   5 * time.Minute,
			FailureDecay:     float64((10 * time.Minute) / time.Second),
			FailureThreshold: 5,
		}),
		cfg:    cfg,
		tlsCfg: tlsCfg,

		tokens:      make(map[string]suture.ServiceToken),
		clients:     make(map[string]client.RelayClient),
		mut:         sync.NewRWMutex(),
		invitations: make(chan protocol.SessionInvitation),
		conns:       conns,
	}

	rcfg := cfg.Raw()
	service.CommitConfiguration(rcfg, rcfg)
	cfg.Subscribe(service)

	receiver := &invitationReceiver{
		tlsCfg:      tlsCfg,
		conns:       conns,
		invitations: service.invitations,
		stop:        make(chan struct{}),
	}

	eventBc := &eventBroadcaster{
		Service: service,
		stop:    make(chan struct{}),
	}

	service.Add(receiver)
	service.Add(eventBc)

	return service
}
Esempio n. 4
0
func setupGUI(mainService *suture.Supervisor, cfg *config.Wrapper, m *model.Model, apiSub *events.BufferedSubscription, discoverer *discover.CachingMux, relayService *relay.Service, errors, systemLog *logger.Recorder, runtimeOptions RuntimeOptions) {
	guiCfg := cfg.GUI()

	if !guiCfg.Enabled {
		return
	}

	if guiCfg.InsecureAdminAccess {
		l.Warnln("Insecure admin access is enabled.")
	}

	api, err := newAPIService(myID, cfg, runtimeOptions.assetDir, m, apiSub, discoverer, relayService, errors, systemLog)
	if err != nil {
		l.Fatalln("Cannot start GUI:", err)
	}
	cfg.Subscribe(api)
	mainService.Add(api)

	if cfg.Options().StartBrowser && !runtimeOptions.noBrowser && !runtimeOptions.stRestarting {
		// Can potentially block if the utility we are invoking doesn't
		// fork, and just execs, hence keep it in it's own routine.
		go openURL(guiCfg.URL())
	}
}
Esempio n. 5
0
func NewConnectionService(cfg *config.Wrapper, myID protocol.DeviceID, mdl Model, tlsCfg *tls.Config, discoverer discover.Finder, relayService *relay.Service,
	bepProtocolName string, tlsDefaultCommonName string, lans []*net.IPNet) suture.Service {
	service := &connectionService{
		Supervisor:           suture.NewSimple("connectionService"),
		cfg:                  cfg,
		myID:                 myID,
		model:                mdl,
		tlsCfg:               tlsCfg,
		discoverer:           discoverer,
		relayService:         relayService,
		conns:                make(chan model.IntermediateConnection),
		bepProtocolName:      bepProtocolName,
		tlsDefaultCommonName: tlsDefaultCommonName,
		lans:                 lans,

		connType:       make(map[protocol.DeviceID]model.ConnectionType),
		relaysEnabled:  cfg.Options().RelaysEnabled,
		lastRelayCheck: make(map[protocol.DeviceID]time.Time),
	}
	cfg.Subscribe(service)

	if service.cfg.Options().MaxSendKbps > 0 {
		service.writeRateLimit = ratelimit.NewBucketWithRate(float64(1000*service.cfg.Options().MaxSendKbps), int64(5*1000*service.cfg.Options().MaxSendKbps))
	}
	if service.cfg.Options().MaxRecvKbps > 0 {
		service.readRateLimit = ratelimit.NewBucketWithRate(float64(1000*service.cfg.Options().MaxRecvKbps), int64(5*1000*service.cfg.Options().MaxRecvKbps))
	}

	// There are several moving parts here; one routine per listening address
	// to handle incoming connections, one routine to periodically attempt
	// outgoing connections, one routine to the the common handling
	// regardless of whether the connection was incoming or outgoing.
	// Furthermore, a relay connectionService which handles incoming requests to connect
	// via the relays.
	//
	// TODO: Clean shutdown, and/or handling config changes on the fly. We
	// partly do this now - new devices and addresses will be picked up, but
	// not new listen addresses and we don't support disconnecting devices
	// that are removed and so on...

	service.Add(serviceFunc(service.connect))
	for _, addr := range service.cfg.Options().ListenAddress {
		uri, err := url.Parse(addr)
		if err != nil {
			l.Infoln("Failed to parse listen address:", addr, err)
			continue
		}

		listener, ok := listeners[uri.Scheme]
		if !ok {
			l.Infoln("Unknown listen address scheme:", uri.String())
			continue
		}

		l.Debugln("listening on", uri)

		service.Add(serviceFunc(func() {
			listener(uri, service.tlsCfg, service.conns)
		}))
	}
	service.Add(serviceFunc(service.handle))

	if service.relayService != nil {
		service.Add(serviceFunc(service.acceptRelayConns))
	}

	return service
}