2
0
mirror of synced 2025-02-23 06:08:07 +00:00

Only allow chunk size to be set for new Torrents

(cherry picked from commit 09e73e9fce139cd78da48c442e8610501b6fd26b)
This commit is contained in:
Matt Joiner 2021-10-10 11:22:29 +11:00
parent 6f196c8d33
commit d19079e698
2 changed files with 73 additions and 13 deletions

View File

@ -1095,15 +1095,23 @@ func (cl *Client) badPeerIPPort(ip net.IP, port int) bool {
// Return a Torrent ready for insertion into a Client.
func (cl *Client) newTorrent(ih metainfo.Hash, specStorage storage.ClientImpl) (t *Torrent) {
return cl.newTorrentOpt(addTorrentOpts{
InfoHash: ih,
Storage: specStorage,
})
}
// Return a Torrent ready for insertion into a Client.
func (cl *Client) newTorrentOpt(opts addTorrentOpts) (t *Torrent) {
// use provided storage, if provided
storageClient := cl.defaultStorage
if specStorage != nil {
storageClient = storage.NewClient(specStorage)
if opts.Storage != nil {
storageClient = storage.NewClient(opts.Storage)
}
t = &Torrent{
cl: cl,
infoHash: ih,
infoHash: opts.InfoHash,
peers: prioritizedPeers{
om: btree.New(32),
getPrio: func(p PeerInfo) peerPriority {
@ -1128,7 +1136,10 @@ func (cl *Client) newTorrent(ih metainfo.Hash, specStorage storage.ClientImpl) (
t.networkingEnabled.Set()
t._pendingPieces.NewSet = priorityBitmapStableNewSet
t.logger = cl.logger.WithContextValue(t)
t.setChunkSize(defaultChunkSize)
if opts.ChunkSize == 0 {
opts.ChunkSize = defaultChunkSize
}
t.setChunkSize(opts.ChunkSize)
return
}
@ -1170,11 +1181,54 @@ func (cl *Client) AddTorrentInfoHashWithStorage(infoHash metainfo.Hash, specStor
return
}
// Adds a torrent by InfoHash with a custom Storage implementation.
// If the torrent already exists then this Storage is ignored and the
// existing torrent returned with `new` set to `false`
func (cl *Client) AddTorrentOpt(opts addTorrentOpts) (t *Torrent, new bool) {
infoHash := opts.InfoHash
cl.lock()
defer cl.unlock()
t, ok := cl.torrents[infoHash]
if ok {
return
}
new = true
t = cl.newTorrentOpt(opts)
cl.eachDhtServer(func(s DhtServer) {
if cl.config.PeriodicallyAnnounceTorrentsToDht {
go t.dhtAnnouncer(s)
}
})
cl.torrents[infoHash] = t
cl.clearAcceptLimits()
t.updateWantPeersEvent()
// Tickle Client.waitAccept, new torrent may want conns.
cl.event.Broadcast()
return
}
type addTorrentOpts struct {
InfoHash InfoHash
Storage storage.ClientImpl
ChunkSize pp.Integer
}
// Add or merge a torrent spec. Returns new if the torrent wasn't already in the client. See also
// Torrent.MergeSpec.
func (cl *Client) AddTorrentSpec(spec *TorrentSpec) (t *Torrent, new bool, err error) {
t, new = cl.AddTorrentInfoHashWithStorage(spec.InfoHash, spec.Storage)
err = t.MergeSpec(spec)
t, new = cl.AddTorrentOpt(addTorrentOpts{
InfoHash: spec.InfoHash,
Storage: spec.Storage,
ChunkSize: spec.ChunkSize,
})
modSpec := *spec
if new {
// ChunkSize was already applied by adding a new Torrent, and MergeSpec disallows changing
// it.
modSpec.ChunkSize = 0
}
err = t.MergeSpec(&modSpec)
if err != nil && new {
t.Drop()
}
@ -1218,7 +1272,7 @@ func (t *Torrent) MergeSpec(spec *TorrentSpec) error {
})
}
if spec.ChunkSize != 0 {
t.setChunkSize(pp.Integer(spec.ChunkSize))
panic("chunk size cannot be changed for existing Torrent")
}
t.addTrackers(spec.Trackers)
t.maybeNewConns()

18
spec.go
View File

@ -4,14 +4,17 @@ import (
"fmt"
"github.com/anacrolix/torrent/metainfo"
pp "github.com/anacrolix/torrent/peer_protocol"
"github.com/anacrolix/torrent/storage"
)
// Specifies a new torrent for adding to a client. There are helpers for magnet URIs and torrent
// metainfo files.
// Specifies a new torrent for adding to a client, or additions to an existing Torrent. There are
// constructor functions for magnet URIs and torrent metainfo files. TODO: This type should be
// dismantled into a new Torrent option type, and separate Torrent mutate method(s).
type TorrentSpec struct {
// The tiered tracker URIs.
Trackers [][]string
Trackers [][]string
// TODO: Move into a "new" Torrent opt type.
InfoHash metainfo.Hash
InfoBytes []byte
// The name to use if the Name field from the Info isn't available.
@ -22,10 +25,13 @@ type TorrentSpec struct {
// The combination of the "xs" and "as" fields in magnet links, for now.
Sources []string
// The chunk size to use for outbound requests. Defaults to 16KiB if not set.
ChunkSize int
// The chunk size to use for outbound requests. Defaults to 16KiB if not set. Can only be set
// for new Torrents. TODO: Move into a "new" Torrent opt type.
ChunkSize pp.Integer
// TODO: Move into a "new" Torrent opt type.
Storage storage.ClientImpl
DisableInitialPieceCheck bool
Storage storage.ClientImpl
// Whether to allow data download or upload
DisallowDataUpload bool