func archiveAndSaveConfig(cfg *config.Wrapper) error { // Copy the existing config to an archive copy archivePath := cfg.ConfigPath() + fmt.Sprintf(".v%d", cfg.Raw().OriginalVersion) l.Infoln("Archiving a copy of old config file format at:", archivePath) if err := copyFile(cfg.ConfigPath(), archivePath); err != nil { return err } // Do a regular atomic config sve return cfg.Save() }
func archiveAndSaveConfig(cfg *config.Wrapper) error { // To prevent previous config from being cleaned up, quickly touch it too now := time.Now() _ = os.Chtimes(cfg.ConfigPath(), now, now) // May return error on Android etc; no worries archivePath := cfg.ConfigPath() + fmt.Sprintf(".v%d", cfg.Raw().OriginalVersion) l.Infoln("Archiving a copy of old config file format at:", archivePath) if err := osutil.Rename(cfg.ConfigPath(), archivePath); err != nil { return err } return cfg.Save() }
func NewService(cfg *config.Wrapper, myID protocol.DeviceID, mdl Model, tlsCfg *tls.Config, discoverer discover.Finder, bepProtocolName string, tlsDefaultCommonName string, lans []*net.IPNet) *Service { service := &Service{ Supervisor: suture.NewSimple("connections.Service"), cfg: cfg, myID: myID, model: mdl, tlsCfg: tlsCfg, discoverer: discoverer, conns: make(chan IntermediateConnection), bepProtocolName: bepProtocolName, tlsDefaultCommonName: tlsDefaultCommonName, lans: lans, natService: nat.NewService(myID, cfg), listenersMut: sync.NewRWMutex(), listeners: make(map[string]genericListener), listenerTokens: make(map[string]suture.ServiceToken), curConMut: sync.NewMutex(), currentConnection: make(map[protocol.DeviceID]Connection), } cfg.Subscribe(service) // The rate variables are in KiB/s in the UI (despite the camel casing // of the name). We multiply by 1024 here to get B/s. options := service.cfg.Options() if options.MaxSendKbps > 0 { service.writeRateLimit = ratelimit.NewBucketWithRate(float64(1024*options.MaxSendKbps), int64(5*1024*options.MaxSendKbps)) } if options.MaxRecvKbps > 0 { service.readRateLimit = ratelimit.NewBucketWithRate(float64(1024*options.MaxRecvKbps), int64(5*1024*options.MaxRecvKbps)) } // There are several moving parts here; one routine per listening address // (handled in configuration changing) 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. service.Add(serviceFunc(service.connect)) service.Add(serviceFunc(service.handle)) raw := cfg.Raw() // Actually starts the listeners and NAT service service.CommitConfiguration(raw, raw) return service }
func newUsageReportingManager(m *model.Model, cfg *config.Wrapper) *usageReportingManager { mgr := &usageReportingManager{ 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 }
// 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 }
// 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), timer: time.NewTimer(time.Millisecond), sentDownloadStates: make(map[protocol.DeviceID]*sentDownloadState), connections: make(map[string][]protocol.Connection), mut: sync.NewMutex(), } t.CommitConfiguration(config.Configuration{}, cfg.Raw()) cfg.Subscribe(t) return t }
func NewBlockFinder(db *leveldb.DB, cfg *config.Wrapper) *BlockFinder { if blockFinder != nil { return blockFinder } f := &BlockFinder{ db: db, mut: sync.NewRWMutex(), } f.CommitConfiguration(config.Configuration{}, cfg.Raw()) cfg.Subscribe(f) return f }
func NewSvc(cfg *config.Wrapper, tlsCfg *tls.Config) *Svc { conns := make(chan *tls.Conn) svc := &Svc{ Supervisor: suture.New("Svc", suture.Spec{ Log: func(log string) { if debug { 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.ProtocolClient), mut: sync.NewRWMutex(), invitations: make(chan protocol.SessionInvitation), conns: conns, } rcfg := cfg.Raw() svc.CommitConfiguration(rcfg, rcfg) cfg.Subscribe(svc) receiver := &invitationReceiver{ tlsCfg: tlsCfg, conns: conns, invitations: svc.invitations, stop: make(chan struct{}), } eventBc := &eventBroadcaster{ svc: svc, } svc.Add(receiver) svc.Add(eventBc) return svc }