diff --git a/chihaya.go b/chihaya.go index 260b035..2d5dd2a 100644 --- a/chihaya.go +++ b/chihaya.go @@ -23,17 +23,15 @@ import ( ) var ( - maxProcs int - profile string - configPath string - whitelistPath string + maxProcs int + profile string + configPath string ) func init() { flag.IntVar(&maxProcs, "maxprocs", runtime.NumCPU(), "maximum parallel threads") flag.StringVar(&profile, "profile", "", "if non-empty, path to write profiling data") flag.StringVar(&configPath, "config", "", "path to the configuration file") - flag.StringVar(&whitelistPath, "whitelist", "", "path to a client whitelist") } // Boot starts Chihaya. By exporting this function, anyone can import their own @@ -80,13 +78,6 @@ func Boot() { glog.Fatal("New: ", err) } - if whitelistPath != "" { - err = tkr.LoadApprovedClients(whitelistPath) - if err != nil { - glog.Fatal("Failed to load whitelist: ", err.Error()) - } - } - http.Serve(cfg, tkr) glog.Info("Gracefully shut down") } diff --git a/config/config.go b/config/config.go index 62203a5..b1b4661 100644 --- a/config/config.go +++ b/config/config.go @@ -65,9 +65,8 @@ type Config struct { Tracker DriverConfig `json:"tracker"` Backend DriverConfig `json:"backend"` - Private bool `json:"private_tracker"` - Freeleech bool `json:"freeleech"` - Whitelist bool `json:"whitelist"` + PrivateEnabled bool `json:"private_enabled"` + FreeleechEnabled bool `json:"freeleech_enabled"` PurgeInactiveTorrents bool `json:"purge_inactive_torrents"` Announce Duration `json:"announce"` @@ -75,6 +74,9 @@ type Config struct { RequestTimeout Duration `json:"request_timeout"` NumWantFallback int `json:"default_num_want"` + ClientWhitelistEnabled bool `json:"client_whitelist_enabled"` + ClientWhitelist []string `json:"client_whitelist,omitempty"` + StatsConfig NetConfig } @@ -91,9 +93,8 @@ var DefaultConfig = Config{ Name: "noop", }, - Private: false, - Freeleech: false, - Whitelist: false, + PrivateEnabled: false, + FreeleechEnabled: false, PurgeInactiveTorrents: true, Announce: Duration{30 * time.Minute}, @@ -113,6 +114,8 @@ var DefaultConfig = Config{ AllowIPSpoofing: true, DualStackedPeers: true, }, + + ClientWhitelistEnabled: false, } // Open is a shortcut to open a file, read it, and generate a Config. diff --git a/example_config.json b/example_config.json index 0334810..1d0267b 100644 --- a/example_config.json +++ b/example_config.json @@ -9,9 +9,8 @@ "driver": "noop" }, - "private_tracker": false, - "freeleech": false, - "whitelist": false, + "private_enabled": false, + "freeleech_enabled": false, "purge_inactive_torrents": true, "announce": "30m", @@ -29,6 +28,21 @@ "stats_buffer_size": 0, "include_mem_stats": true, "verbose_mem_stats": false, - "mem_stats_interval": "5s" + "mem_stats_interval": "5s", + "client_whitelist_enabled": false, + "client_whitelist": [ + "UT340-", + "AZ2500", + "exbc0J", + "FUTB0L", + "XBT054", + "OP1011", + "ML2.7.", + "BOWA0C", + "Q1-0-0", + "Q1-10-", + "346---", + "QVOD00" + ] } diff --git a/example_whitelist.json b/example_whitelist.json deleted file mode 100644 index 856a0c3..0000000 --- a/example_whitelist.json +++ /dev/null @@ -1,14 +0,0 @@ -[ - "UT340-", - "AZ2500", - "exbc0J", - "FUTB0L", - "XBT054", - "OP1011", - "ML2.7.", - "BOWA0C", - "Q1-0-0", - "Q1-10-", - "346---", - "QVOD00" -] diff --git a/http/announce_test.go b/http/announce_test.go index 9c4652c..047db3f 100644 --- a/http/announce_test.go +++ b/http/announce_test.go @@ -124,7 +124,7 @@ func TestStalePeerPurging(t *testing.T) { func TestPrivateAnnounce(t *testing.T) { cfg := config.DefaultConfig - cfg.Private = true + cfg.PrivateEnabled = true tkr, err := tracker.New(&cfg) if err != nil { diff --git a/http/http.go b/http/http.go index 0aa764c..6f01ee5 100644 --- a/http/http.go +++ b/http/http.go @@ -66,7 +66,7 @@ func makeHandler(handler ResponseHandler) httprouter.Handle { func newRouter(s *Server) *httprouter.Router { r := httprouter.New() - if s.config.Private { + if s.config.PrivateEnabled { r.GET("/users/:passkey/announce", makeHandler(s.serveAnnounce)) r.GET("/users/:passkey/scrape", makeHandler(s.serveScrape)) @@ -77,7 +77,7 @@ func newRouter(s *Server) *httprouter.Router { r.GET("/scrape", makeHandler(s.serveScrape)) } - if s.config.Whitelist { + if s.config.ClientWhitelistEnabled { r.PUT("/clients/:clientID", makeHandler(s.putClient)) r.DELETE("/clients/:clientID", makeHandler(s.delClient)) } diff --git a/tracker/announce.go b/tracker/announce.go index a9e8b83..ec21676 100644 --- a/tracker/announce.go +++ b/tracker/announce.go @@ -21,14 +21,14 @@ func (tkr *Tracker) HandleAnnounce(ann *models.Announce, w Writer) error { defer conn.Close() - if tkr.cfg.Whitelist { + if tkr.cfg.ClientWhitelistEnabled { if err = conn.FindClient(ann.ClientID()); err != nil { return err } } var user *models.User - if tkr.cfg.Private { + if tkr.cfg.PrivateEnabled { if user, err = conn.FindUser(ann.Passkey); err != nil { return err } @@ -37,7 +37,7 @@ func (tkr *Tracker) HandleAnnounce(ann *models.Announce, w Writer) error { var torrent *models.Torrent torrent, err = conn.FindTorrent(ann.Infohash) switch { - case !tkr.cfg.Private && err == models.ErrTorrentDNE: + case !tkr.cfg.PrivateEnabled && err == models.ErrTorrentDNE: torrent = &models.Torrent{ Infohash: ann.Infohash, Seeders: models.PeerMap{}, @@ -66,7 +66,7 @@ func (tkr *Tracker) HandleAnnounce(ann *models.Announce, w Writer) error { return err } - if tkr.cfg.Private { + if tkr.cfg.PrivateEnabled { delta := models.NewAnnounceDelta(ann, peer, user, torrent, created, snatched) err = tkr.backend.RecordAnnounce(delta) if err != nil { @@ -160,7 +160,7 @@ func handleEvent(c Conn, ann *models.Announce, p *models.Peer, u *models.User, t } t.Snatches++ - if ann.Config.Private { + if ann.Config.PrivateEnabled { err = c.IncrementUserSnatches(u.Passkey) if err != nil { return diff --git a/tracker/models/models.go b/tracker/models/models.go index 280bcf7..eaed0d9 100644 --- a/tracker/models/models.go +++ b/tracker/models/models.go @@ -214,7 +214,7 @@ func NewAnnounceDelta(a *Announce, p *Peer, u *User, t *Torrent, created, snatch rawDeltaDown uint64 ) - if !a.Config.Freeleech { + if !a.Config.FreeleechEnabled { rawDeltaDown = p.Downloaded - a.Downloaded } diff --git a/tracker/scrape.go b/tracker/scrape.go index e915bf8..e1980bb 100644 --- a/tracker/scrape.go +++ b/tracker/scrape.go @@ -16,7 +16,7 @@ func (tkr *Tracker) HandleScrape(scrape *models.Scrape, w Writer) (err error) { defer conn.Close() - if tkr.cfg.Private { + if tkr.cfg.PrivateEnabled { if _, err = conn.FindUser(scrape.Passkey); err != nil { return err } diff --git a/tracker/tracker.go b/tracker/tracker.go index 3716aac..5f70f18 100644 --- a/tracker/tracker.go +++ b/tracker/tracker.go @@ -7,8 +7,6 @@ package tracker import ( - "encoding/json" - "os" "time" "github.com/golang/glog" @@ -46,11 +44,17 @@ func New(cfg *config.Config) (*Tracker, error) { cfg.Announce.Duration, ) - return &Tracker{ + tkr := &Tracker{ cfg: cfg, Pool: pool, backend: bc, - }, nil + } + + if cfg.ClientWhitelistEnabled { + tkr.LoadApprovedClients(cfg.ClientWhitelist) + } + + return tkr, nil } // Close gracefully shutdowns a Tracker by closing any database connections. @@ -68,25 +72,8 @@ func (tkr *Tracker) Close() (err error) { return } -// LoadApprovedClients takes a path to a JSON file containing a list of clients -// and inserts them into the tracker's data store. -func (tkr *Tracker) LoadApprovedClients(path string) error { - if path == "" { - return nil - } - - f, err := os.Open(os.ExpandEnv(path)) - if err != nil { - return err - } - defer f.Close() - - var clients []string - err = json.NewDecoder(f).Decode(&clients) - if err != nil { - return err - } - +// LoadApprovedClients loads a list of client IDs into the tracker's storage. +func (tkr *Tracker) LoadApprovedClients(clients []string) error { conn, err := tkr.Pool.Get() if err != nil { return err