110 lines
3.4 KiB
Go
110 lines
3.4 KiB
Go
package torrent
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"log/slog"
|
|
"os"
|
|
|
|
"git.kmsign.ru/royalcat/tstor/src/config"
|
|
"git.kmsign.ru/royalcat/tstor/src/logwrap"
|
|
"github.com/anacrolix/dht/v2/bep44"
|
|
tlog "github.com/anacrolix/log"
|
|
"github.com/anacrolix/torrent"
|
|
"github.com/anacrolix/torrent/storage"
|
|
"github.com/anacrolix/torrent/types/infohash"
|
|
)
|
|
|
|
func newClientConfig(st storage.ClientImpl, fis bep44.Store, cfg *config.TorrentClient, id [20]byte) *torrent.ClientConfig {
|
|
l := slog.With("component", "torrent-client")
|
|
|
|
// TODO download and upload limits
|
|
torrentCfg := torrent.NewDefaultClientConfig()
|
|
torrentCfg.PeerID = string(id[:])
|
|
torrentCfg.DefaultStorage = st
|
|
// torrentCfg.AlwaysWantConns = true
|
|
torrentCfg.DropMutuallyCompletePeers = true
|
|
// torrentCfg.TorrentPeersLowWater = 100
|
|
// torrentCfg.TorrentPeersHighWater = 1000
|
|
// torrentCfg.AcceptPeerConnections = true
|
|
torrentCfg.Seed = true
|
|
torrentCfg.DisableAggressiveUpload = false
|
|
|
|
torrentCfg.PeriodicallyAnnounceTorrentsToDht = true
|
|
// torrentCfg.ConfigureAnacrolixDhtServer = func(cfg *dht.ServerConfig) {
|
|
// cfg.Store = fis
|
|
// cfg.Exp = dhtTTL
|
|
// cfg.PeerStore = fis
|
|
// }
|
|
|
|
tl := tlog.NewLogger("torrent-client")
|
|
tl.SetHandlers(&logwrap.Torrent{L: l})
|
|
|
|
torrentCfg.Logger = tl
|
|
torrentCfg.Callbacks.NewPeer = append(torrentCfg.Callbacks.NewPeer, func(p *torrent.Peer) {
|
|
l.With(peerAttrs(p)...).Debug("new peer")
|
|
})
|
|
torrentCfg.Callbacks.PeerClosed = append(torrentCfg.Callbacks.PeerClosed, func(p *torrent.Peer) {
|
|
l.With(peerAttrs(p)...).Debug("peer closed")
|
|
})
|
|
torrentCfg.Callbacks.CompletedHandshake = func(pc *torrent.PeerConn, ih infohash.T) {
|
|
attrs := append(peerAttrs(&pc.Peer), slog.String("infohash", ih.HexString()))
|
|
l.With(attrs...).Debug("completed handshake")
|
|
}
|
|
torrentCfg.Callbacks.PeerConnAdded = append(torrentCfg.Callbacks.PeerConnAdded, func(pc *torrent.PeerConn) {
|
|
l.With(peerAttrs(&pc.Peer)...).Debug("peer conn added")
|
|
})
|
|
torrentCfg.Callbacks.PeerConnClosed = func(pc *torrent.PeerConn) {
|
|
l.With(peerAttrs(&pc.Peer)...).Debug("peer conn closed")
|
|
}
|
|
torrentCfg.Callbacks.CompletedHandshake = func(pc *torrent.PeerConn, ih infohash.T) {
|
|
attrs := append(peerAttrs(&pc.Peer), slog.String("infohash", ih.HexString()))
|
|
l.With(attrs...).Debug("completed handshake")
|
|
}
|
|
torrentCfg.Callbacks.ReceivedRequested = append(torrentCfg.Callbacks.ReceivedRequested, func(pme torrent.PeerMessageEvent) {
|
|
l.With(peerAttrs(pme.Peer)...).Debug("received requested")
|
|
})
|
|
torrentCfg.Callbacks.ReceivedUsefulData = append(torrentCfg.Callbacks.ReceivedUsefulData, func(pme torrent.PeerMessageEvent) {
|
|
l.With(peerAttrs(pme.Peer)...).Debug("received useful data")
|
|
})
|
|
|
|
return torrentCfg
|
|
}
|
|
|
|
var emptyBytes [20]byte
|
|
|
|
func getOrCreatePeerID(p string) ([20]byte, error) {
|
|
idb, err := os.ReadFile(p)
|
|
if err == nil {
|
|
var out [20]byte
|
|
copy(out[:], idb)
|
|
|
|
return out, nil
|
|
}
|
|
|
|
if !os.IsNotExist(err) {
|
|
return emptyBytes, err
|
|
}
|
|
|
|
var out [20]byte
|
|
_, err = rand.Read(out[:])
|
|
if err != nil {
|
|
return emptyBytes, err
|
|
}
|
|
|
|
return out, os.WriteFile(p, out[:], 0755)
|
|
}
|
|
|
|
func peerAttrs(peer *torrent.Peer) []any {
|
|
out := []any{
|
|
slog.String("ip", peer.RemoteAddr.String()),
|
|
slog.String("discovery", string(peer.Discovery)),
|
|
slog.Int("max-requests", peer.PeerMaxRequests),
|
|
slog.Bool("prefers-encryption", peer.PeerPrefersEncryption),
|
|
}
|
|
|
|
if peer.Torrent() != nil {
|
|
out = append(out, slog.String("torrent", peer.Torrent().Name()))
|
|
}
|
|
|
|
return out
|
|
}
|