From b80bb6393a903c96d1aab2e20ab65bb72646282d Mon Sep 17 00:00:00 2001 From: Matt Joiner Date: Mon, 4 Apr 2016 13:01:31 +1000 Subject: [PATCH] Use metainfo.Hash for piece and info hashes --- client.go | 40 +++++++++++++++++++-------------------- client_test.go | 2 +- metainfo/metainfo.go | 15 ++++++++------- misc.go | 4 ---- piece.go | 2 +- storage/mmap.go | 4 ++-- t.go | 2 +- torrent.go | 4 ++-- util/dirwatch/dirwatch.go | 26 ++++++++++++------------- 9 files changed, 48 insertions(+), 51 deletions(-) diff --git a/client.go b/client.go index 9c4f587b..ee46ab20 100644 --- a/client.go +++ b/client.go @@ -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") diff --git a/client_test.go b/client_test.go index 108357d6..bc20fed3 100644 --- a/client_test.go +++ b/client_test.go @@ -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 }()) diff --git a/metainfo/metainfo.go b/metainfo/metainfo.go index 8b99fc3e..bbe8652d 100644 --- a/metainfo/metainfo.go +++ b/metainfo/metainfo.go @@ -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[:]) } diff --git a/misc.go b/misc.go index aec997d4..147b657c 100644 --- a/misc.go +++ b/misc.go @@ -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 diff --git a/piece.go b/piece.go index 015ffb2f..ab0e5666 100644 --- a/piece.go +++ b/piece.go @@ -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 diff --git a/storage/mmap.go b/storage/mmap.go index 07faa191..d5327a9b 100644 --- a/storage/mmap.go +++ b/storage/mmap.go @@ -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 diff --git a/t.go b/t.go index fffdb858..e207a09a 100644 --- a/t.go +++ b/t.go @@ -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 } diff --git a/torrent.go b/torrent.go index 790be4d5..993a7e32 100644 --- a/torrent.go +++ b/torrent.go @@ -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() diff --git a/util/dirwatch/dirwatch.go b/util/dirwatch/dirwatch.go index 3ae70487..fa0edc3c 100644 --- a/util/dirwatch/dirwatch.go +++ b/util/dirwatch/dirwatch.go @@ -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()