Use metainfo.Hash for piece and info hashes

This commit is contained in:
Matt Joiner 2016-04-04 13:01:31 +10:00
parent 00f33c848e
commit b80bb6393a
9 changed files with 48 additions and 51 deletions

View File

@ -143,7 +143,7 @@ type Client struct {
utpSock *utp.Socket
dHT *dht.Server
ipBlockList iplist.Ranger
bannedTorrents map[metainfo.InfoHash]struct{}
bannedTorrents map[metainfo.Hash]struct{}
config Config
pruneTimer *time.Timer
extensionBytes peerExtensionBytes
@ -158,7 +158,7 @@ type Client struct {
event sync.Cond
closed missinggo.Event
torrents map[metainfo.InfoHash]*Torrent
torrents map[metainfo.Hash]*Torrent
}
func (me *Client) IPBlockList() iplist.Ranger {
@ -189,7 +189,7 @@ func (me *Client) ListenAddr() (addr net.Addr) {
}
type hashSorter struct {
Hashes []metainfo.InfoHash
Hashes []metainfo.Hash
}
func (me hashSorter) Len() int {
@ -337,7 +337,7 @@ func (cl *Client) initBannedTorrents() error {
}
defer f.Close()
scanner := bufio.NewScanner(f)
cl.bannedTorrents = make(map[metainfo.InfoHash]struct{})
cl.bannedTorrents = make(map[metainfo.Hash]struct{})
for scanner.Scan() {
if strings.HasPrefix(strings.TrimSpace(scanner.Text()), "#") {
continue
@ -353,7 +353,7 @@ func (cl *Client) initBannedTorrents() error {
if len(ihs) != 20 {
return errors.New("bad infohash")
}
var ih metainfo.InfoHash
var ih metainfo.Hash
missinggo.CopyExact(&ih, ihs)
cl.bannedTorrents[ih] = struct{}{}
}
@ -379,7 +379,7 @@ func NewClient(cfg *Config) (cl *Client, err error) {
config: *cfg,
defaultStorage: cfg.DefaultStorage,
dopplegangerAddrs: make(map[string]struct{}),
torrents: make(map[metainfo.InfoHash]*Torrent),
torrents: make(map[metainfo.Hash]*Torrent),
}
missinggo.CopyExact(&cl.extensionBytes, defaultExtensionBytes)
cl.event.L = &cl.mu
@ -576,14 +576,14 @@ func (cl *Client) incomingConnection(nc net.Conn, utp bool) {
}
// Returns a handle to the given torrent, if it's present in the client.
func (cl *Client) Torrent(ih metainfo.InfoHash) (t *Torrent, ok bool) {
func (cl *Client) Torrent(ih metainfo.Hash) (t *Torrent, ok bool) {
cl.mu.Lock()
defer cl.mu.Unlock()
t, ok = cl.torrents[ih]
return
}
func (me *Client) torrent(ih metainfo.InfoHash) *Torrent {
func (me *Client) torrent(ih metainfo.Hash) *Torrent {
return me.torrents[ih]
}
@ -849,14 +849,14 @@ func (me *peerExtensionBytes) SupportsFast() bool {
type handshakeResult struct {
peerExtensionBytes
peerID
metainfo.InfoHash
metainfo.Hash
}
// ih is nil if we expect the peer to declare the InfoHash, such as when the
// peer initiated the connection. Returns ok if the handshake was successful,
// and err if there was an unexpected condition other than the peer simply
// abandoning the handshake.
func handshake(sock io.ReadWriter, ih *metainfo.InfoHash, peerID [20]byte, extensions peerExtensionBytes) (res handshakeResult, ok bool, err error) {
func handshake(sock io.ReadWriter, ih *metainfo.Hash, peerID [20]byte, extensions peerExtensionBytes) (res handshakeResult, ok bool, err error) {
// Bytes to be sent to the peer. Should never block the sender.
postCh := make(chan []byte, 4)
// A single error value sent when the writer completes.
@ -903,7 +903,7 @@ func handshake(sock io.ReadWriter, ih *metainfo.InfoHash, peerID [20]byte, exten
return
}
missinggo.CopyExact(&res.peerExtensionBytes, b[20:28])
missinggo.CopyExact(&res.InfoHash, b[28:48])
missinggo.CopyExact(&res.Hash, b[28:48])
missinggo.CopyExact(&res.peerID, b[48:68])
peerExtensions.Add(hex.EncodeToString(res.peerExtensionBytes[:]), 1)
@ -911,7 +911,7 @@ func handshake(sock io.ReadWriter, ih *metainfo.InfoHash, peerID [20]byte, exten
// could prevent them trying to reconnect, falsely believing there was
// just a problem.
if ih == nil { // We were waiting for the peer to tell us what they wanted.
post(res.InfoHash[:])
post(res.Hash[:])
post(peerID[:])
}
@ -1020,12 +1020,12 @@ func (cl *Client) receiveHandshakes(c *connection) (t *Torrent, err error) {
}
// Returns !ok if handshake failed for valid reasons.
func (cl *Client) connBTHandshake(c *connection, ih *metainfo.InfoHash) (ret metainfo.InfoHash, ok bool, err error) {
func (cl *Client) connBTHandshake(c *connection, ih *metainfo.Hash) (ret metainfo.Hash, ok bool, err error) {
res, ok, err := handshake(c.rw, ih, cl.peerID, cl.extensionBytes)
if err != nil || !ok {
return
}
ret = res.InfoHash
ret = res.Hash
c.PeerExtensionBytes = res.peerExtensionBytes
c.PeerID = res.peerID
c.completedHandshake = time.Now()
@ -1187,7 +1187,7 @@ func (cl *Client) requestPendingMetadata(t *Torrent, c *connection) {
func (cl *Client) completedMetadata(t *Torrent) {
h := sha1.New()
h.Write(t.metadataBytes)
var ih metainfo.InfoHash
var ih metainfo.Hash
missinggo.CopyExact(&ih, h.Sum(nil))
if ih != t.infoHash {
log.Print("bad metadata")
@ -1678,7 +1678,7 @@ func (me *Client) addPeers(t *Torrent, peers []Peer) {
}
}
func (cl *Client) cachedMetaInfoFilename(ih metainfo.InfoHash) string {
func (cl *Client) cachedMetaInfoFilename(ih metainfo.Hash) string {
return filepath.Join(cl.configDir(), "torrents", ih.HexString()+".torrent")
}
@ -1725,7 +1725,7 @@ func (cl *Client) setMetaData(t *Torrent, md *metainfo.Info, bytes []byte) (err
// Prepare a Torrent without any attachment to a Client. That means we can
// initialize fields all fields that don't require the Client without locking
// it.
func newTorrent(ih metainfo.InfoHash) (t *Torrent) {
func newTorrent(ih metainfo.Hash) (t *Torrent) {
t = &Torrent{
infoHash: ih,
chunkSize: defaultChunkSize,
@ -1849,7 +1849,7 @@ func (t *Torrent) DownloadAll() {
// Returns nil metainfo if it isn't in the cache. Checks that the retrieved
// metainfo has the correct infohash.
func (cl *Client) torrentCacheMetaInfo(ih metainfo.InfoHash) (mi *metainfo.MetaInfo, err error) {
func (cl *Client) torrentCacheMetaInfo(ih metainfo.Hash) (mi *metainfo.MetaInfo, err error) {
if cl.config.DisableMetainfoCache {
return
}
@ -1878,7 +1878,7 @@ func (cl *Client) torrentCacheMetaInfo(ih metainfo.InfoHash) (mi *metainfo.MetaI
type TorrentSpec struct {
// The tiered tracker URIs.
Trackers [][]string
InfoHash metainfo.InfoHash
InfoHash metainfo.Hash
Info *metainfo.InfoEx
// The name to use if the Name field from the Info isn't available.
DisplayName string
@ -1989,7 +1989,7 @@ func (cl *Client) AddTorrentSpec(spec *TorrentSpec) (t *Torrent, new bool, err e
return
}
func (me *Client) dropTorrent(infoHash metainfo.InfoHash) (err error) {
func (me *Client) dropTorrent(infoHash metainfo.Hash) (err error) {
t, ok := me.torrents[infoHash]
if !ok {
err = fmt.Errorf("no such torrent")

View File

@ -87,7 +87,7 @@ func TestPieceHashSize(t *testing.T) {
func TestTorrentInitialState(t *testing.T) {
dir, mi := testutil.GreetingTestTorrent()
defer os.RemoveAll(dir)
tor := newTorrent(func() (ih metainfo.InfoHash) {
tor := newTorrent(func() (ih metainfo.Hash) {
missinggo.CopyExact(ih[:], mi.Info.Hash)
return
}())

View File

@ -172,7 +172,7 @@ func (me Piece) Offset() int64 {
return int64(me.i) * me.Info.PieceLength
}
func (me Piece) Hash() (ret InfoHash) {
func (me Piece) Hash() (ret Hash) {
missinggo.CopyExact(&ret, me.Info.Pieces[me.i*20:(me.i+1)*20])
return
}
@ -204,7 +204,7 @@ func (i *Info) UpvertedFiles() []FileInfo {
// important to Bittorrent.
type InfoEx struct {
Info
Hash *InfoHash
Hash *Hash
Bytes []byte
}
@ -220,7 +220,7 @@ func (this *InfoEx) UnmarshalBencode(data []byte) error {
if err != nil {
panic(err)
}
this.Hash = new(InfoHash)
this.Hash = new(Hash)
missinggo.CopyExact(this.Hash, h.Sum(nil))
return bencode.Unmarshal(data, &this.Info)
}
@ -257,16 +257,17 @@ func (mi *MetaInfo) SetDefaults() {
mi.Info.PieceLength = 256 * 1024
}
type InfoHash [20]byte
// 20-byte SHA1 hash used for info and pieces.
type Hash [20]byte
func (me InfoHash) Bytes() []byte {
func (me Hash) Bytes() []byte {
return me[:]
}
func (ih *InfoHash) AsString() string {
func (ih *Hash) AsString() string {
return string(ih[:])
}
func (ih InfoHash) HexString() string {
func (ih Hash) HexString() string {
return fmt.Sprintf("%x", ih[:])
}

View File

@ -21,10 +21,6 @@ const (
minDialTimeout = 5 * time.Second
)
type (
pieceSum [20]byte
)
func lastChunkSpec(pieceLength, chunkSize pp.Integer) (cs chunkSpec) {
cs.Begin = (pieceLength - 1) / chunkSize * chunkSize
cs.Length = pieceLength - cs.Begin

View File

@ -30,7 +30,7 @@ const (
type piece struct {
// The completed piece SHA1 hash, from the metainfo "pieces" field.
Hash pieceSum
Hash metainfo.Hash
t *Torrent
index int
// Chunks we've written to since the last check. The chunk offset and

View File

@ -33,7 +33,7 @@ func (me *mmapStorage) OpenTorrent(info *metainfo.InfoEx) (t Torrent, err error)
type mmapTorrentStorage struct {
span mmap_span.MMapSpan
completed map[metainfo.InfoHash]bool
completed map[metainfo.Hash]bool
}
func (me *mmapTorrentStorage) Piece(p metainfo.Piece) Piece {
@ -63,7 +63,7 @@ func (me mmapStoragePiece) GetIsComplete() bool {
func (me mmapStoragePiece) MarkComplete() error {
if me.storage.completed == nil {
me.storage.completed = make(map[metainfo.InfoHash]bool)
me.storage.completed = make(map[metainfo.Hash]bool)
}
me.storage.completed[me.p.Hash()] = true
return nil

2
t.go
View File

@ -8,7 +8,7 @@ import (
// The torrent's infohash. This is fixed and cannot change. It uniquely
// identifies a torrent.
func (t *Torrent) InfoHash() metainfo.InfoHash {
func (t *Torrent) InfoHash() metainfo.Hash {
return t.infoHash
}

View File

@ -45,7 +45,7 @@ type Torrent struct {
// announcing, and communicating with peers.
ceasingNetworking chan struct{}
infoHash metainfo.InfoHash
infoHash metainfo.Hash
pieces []piece
// Values are the piece indices that changed.
pieceStateChanges *pubsub.PubSub
@ -656,7 +656,7 @@ func (t *Torrent) pieceLength(piece int) (len_ pp.Integer) {
return
}
func (t *Torrent) hashPiece(piece int) (ret pieceSum) {
func (t *Torrent) hashPiece(piece int) (ret metainfo.Hash) {
hash := pieceHash.New()
p := &t.pieces[piece]
p.waitNoPendingWrites()

View File

@ -27,11 +27,11 @@ type Event struct {
MagnetURI string
Change
TorrentFilePath string
InfoHash metainfo.InfoHash
InfoHash metainfo.Hash
}
type entity struct {
metainfo.InfoHash
metainfo.Hash
MagnetURI string
TorrentFilePath string
}
@ -40,7 +40,7 @@ type Instance struct {
w *fsnotify.Watcher
dirName string
Events chan Event
dirState map[metainfo.InfoHash]entity
dirState map[metainfo.Hash]entity
}
func (me *Instance) Close() {
@ -65,7 +65,7 @@ func (me *Instance) handleErrors() {
}
}
func torrentFileInfoHash(fileName string) (ih metainfo.InfoHash, ok bool) {
func torrentFileInfoHash(fileName string) (ih metainfo.Hash, ok bool) {
mi, _ := metainfo.LoadFromFile(fileName)
if mi == nil {
return
@ -75,7 +75,7 @@ func torrentFileInfoHash(fileName string) (ih metainfo.InfoHash, ok bool) {
return
}
func scanDir(dirName string) (ee map[metainfo.InfoHash]entity) {
func scanDir(dirName string) (ee map[metainfo.Hash]entity) {
d, err := os.Open(dirName)
if err != nil {
log.Print(err)
@ -87,15 +87,15 @@ func scanDir(dirName string) (ee map[metainfo.InfoHash]entity) {
log.Print(err)
return
}
ee = make(map[metainfo.InfoHash]entity, len(names))
ee = make(map[metainfo.Hash]entity, len(names))
addEntity := func(e entity) {
e0, ok := ee[e.InfoHash]
e0, ok := ee[e.Hash]
if ok {
if e0.MagnetURI == "" || len(e.MagnetURI) < len(e0.MagnetURI) {
return
}
}
ee[e.InfoHash] = e
ee[e.Hash] = e
}
for _, n := range names {
fullName := filepath.Join(dirName, n)
@ -108,7 +108,7 @@ func scanDir(dirName string) (ee map[metainfo.InfoHash]entity) {
e := entity{
TorrentFilePath: fullName,
}
missinggo.CopyExact(&e.InfoHash, ih)
missinggo.CopyExact(&e.Hash, ih)
addEntity(e)
case ".magnet":
uris, err := magnetFileURIs(fullName)
@ -123,7 +123,7 @@ func scanDir(dirName string) (ee map[metainfo.InfoHash]entity) {
continue
}
addEntity(entity{
InfoHash: m.InfoHash,
Hash: m.InfoHash,
MagnetURI: uri,
})
}
@ -151,7 +151,7 @@ func magnetFileURIs(name string) (uris []string, err error) {
return
}
func (me *Instance) torrentRemoved(ih metainfo.InfoHash) {
func (me *Instance) torrentRemoved(ih metainfo.Hash) {
me.Events <- Event{
InfoHash: ih,
Change: Removed,
@ -160,7 +160,7 @@ func (me *Instance) torrentRemoved(ih metainfo.InfoHash) {
func (me *Instance) torrentAdded(e entity) {
me.Events <- Event{
InfoHash: e.InfoHash,
InfoHash: e.Hash,
Change: Added,
MagnetURI: e.MagnetURI,
TorrentFilePath: e.TorrentFilePath,
@ -203,7 +203,7 @@ func New(dirName string) (i *Instance, err error) {
w: w,
dirName: dirName,
Events: make(chan Event),
dirState: make(map[metainfo.InfoHash]entity, 0),
dirState: make(map[metainfo.Hash]entity, 0),
}
go func() {
i.refresh()