-
Notifications
You must be signed in to change notification settings - Fork 0
/
context.go
81 lines (73 loc) · 2.34 KB
/
context.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
package dhtup
import (
"net"
"path/filepath"
"github.com/anacrolix/dht/v2"
"github.com/anacrolix/squirrel"
"github.com/anacrolix/torrent"
"github.com/anacrolix/torrent/metainfo"
"github.com/anacrolix/torrent/storage"
sqliteStorage "github.com/anacrolix/torrent/storage/sqlite"
"github.com/getlantern/golog"
)
var log = golog.LoggerFor("dhtup")
type Context struct {
DhtServer *dht.Server
TorrentClient *torrent.Client
TorrentStorage storage.ClientImplCloser
}
func NewContext(publicIp net.IP, cacheDir string) (_ Context, err error) {
dhtCfg := dht.NewDefaultServerConfig()
// This is used to secure the local node ID. If our IP changes it is bad luck, and not a huge
// deal.
dhtCfg.PublicIP = publicIp
ds, err := dht.NewServer(nil)
if err != nil {
return
}
cfg := torrent.NewDefaultClientConfig()
// We could set the torrent public IPs, but it mainly uses them to configure its implicit DHT
// instances, of which we have none. The IPs the client use should track any changes.
// Because we add our own, and maintain it manually.
cfg.NoDHT = true
// Avoid predictable port assignment, and avoid colliding with the Replica UI server.
cfg.ListenPort = 0
cfg.Debug = false
cfg.Seed = true
cfg.DropMutuallyCompletePeers = true
ts := makeStorage(cacheDir)
cfg.DefaultStorage = ts
tc, err := torrent.NewClient(cfg)
if err != nil {
ds.Close()
ts.Close()
return
}
tc.AddDhtServer(torrent.AnacrolixDhtServerWrapper{Server: ds})
return Context{
DhtServer: ds,
TorrentClient: tc,
TorrentStorage: ts,
}, nil
}
func (c Context) Close() {
c.DhtServer.Close()
c.TorrentClient.Close()
c.TorrentStorage.Close()
}
func makeStorage(cacheDir string) (s storage.ClientImplCloser) {
// No path means a temporary file that is removed from the disk after opening. Perfect.
s, err := sqliteStorage.NewDirectStorage(squirrel.NewCacheOpts{})
if err == nil {
return
}
log.Errorf("creating dht config sqlite storage: %v", err)
return storage.NewFileOpts(storage.NewFileClientOpts{
ClientBaseDir: filepath.Join(cacheDir, "data"),
// Since many of our torrents will be iterations of the same resources, we divide them
// up based on infohash to avoid info name collisions.
TorrentDirMaker: func(baseDir string, info *metainfo.Info, infoHash metainfo.Hash) string {
return filepath.Join(baseDir, infoHash.HexString())
},
})
}