From 0fe086993b01f7d53c8b226bd1eb5665c1d0c18f Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Sun, 17 Jul 2016 03:05:33 +0200 Subject: Replace InfoHash with Raw --- bencode/bdecode.go | 22 ++++++++-------------- cmd/btcheck/main.go | 2 +- meta/info.go | 5 +++++ meta/torrent.go | 3 +-- meta/torrent_test.go | 10 ++++++++++ tracker/messages.go | 27 ++++++++++++++------------- 6 files changed, 39 insertions(+), 30 deletions(-) diff --git a/bencode/bdecode.go b/bencode/bdecode.go index 4c7302d..e542f9b 100644 --- a/bencode/bdecode.go +++ b/bencode/bdecode.go @@ -2,7 +2,6 @@ package bencode import ( "bytes" - "crypto/sha1" "errors" "reflect" "strconv" @@ -46,28 +45,23 @@ func (d *decodeState) unmarshalDict(v reflect.Value) error { if d.data[d.off] != 'd' { return ErrValue } + + rawStart := d.off d.off++ - var infoOff, infoEnd int for d.data[d.off] != 'e' { key, n := parseString(d.data[d.off:]) d.off += n - if key == "info" { - infoOff = d.off - } d.unmarshalField(findKey(key, v)) - if key == "info" { - infoEnd = d.off - } } - if v.CanSet() { - if ih := v.FieldByName("InfoHash"); ih.IsValid() && infoEnd > infoOff { - sum := sha1.Sum(d.data[infoOff:infoEnd]) - ih.SetBytes(sum[:]) - } - } d.off++ + rawEnd := d.off + + if raw := v.FieldByName("Raw"); raw.IsValid() && rawEnd > rawStart { + raw.SetBytes(d.data[rawStart:rawEnd]) + } + return nil } diff --git a/cmd/btcheck/main.go b/cmd/btcheck/main.go index 680bd5b..ce65fa0 100644 --- a/cmd/btcheck/main.go +++ b/cmd/btcheck/main.go @@ -33,7 +33,7 @@ func main() { id, _ := peer.NewID() req := tracker.Request{ - InfoHash: tor.InfoHash, + InfoHash: tor.Info.Hash(), PeerID: []byte(id), Compact: true, } diff --git a/meta/info.go b/meta/info.go index c3f26d9..a537b46 100644 --- a/meta/info.go +++ b/meta/info.go @@ -19,6 +19,11 @@ type Info struct { Pieces []byte `bencode:"pieces"` // compact mode Private bool `bencode:"private"` // BEP-0027 RootHash []byte `bencode:"root hash"` // BEP-0030 + Raw []byte `bencode:"-"` +} + +func (i Info) Hash() [sha1.Size]byte { + return sha1.Sum(i.Raw) } // NPieces returns number of all pieces diff --git a/meta/torrent.go b/meta/torrent.go index 80c987b..41323a8 100644 --- a/meta/torrent.go +++ b/meta/torrent.go @@ -21,7 +21,6 @@ type Torrent struct { Encoding string `bencode:"encoding,optional"` HTTPSeeds []string `bencode:"httpseeds,optional"` // BEP-0017 Info Info `bencode:"info"` - InfoHash []byte `bencode:"-"` //Nodes Nodes `bencode:"nodes"` // BEP-0005 //URLList []string `bencode:"url-list,optional"` } @@ -31,7 +30,7 @@ func (t Torrent) String() string { s += fmt.Sprintf("comment: %s\n", t.Comment) s += fmt.Sprintf("date: %s\n", t.CreationDate) s += fmt.Sprintf("%v", t.Info) - s += fmt.Sprintf("info hash: % x", t.InfoHash) + s += fmt.Sprintf("info hash: % x", t.Info.Hash()) return s } diff --git a/meta/torrent_test.go b/meta/torrent_test.go index 3dd8595..d8706e0 100644 --- a/meta/torrent_test.go +++ b/meta/torrent_test.go @@ -9,6 +9,16 @@ var tors = map[string]string{ "mul": "multi.torrent", } +func TestHash(t *testing.T) { + tor, err := New("../examples/" + tors["bsd"]) + if err != nil { + t.Error(err) + } + if tor.Info.Hash() != [20]byte{0xe8, 0x40, 0x03, 0x8d, 0xea, 0x19, 0x98, 0xc3, 0x96, 0x14, 0xdc, 0xd2, 0x85, 0x94, 0x50, 0x1d, 0xf0, 0x2b, 0xd3, 0x2d} { + t.Errorf("wrong info hash %x", tor.Info.Hash()) + } +} + func TestPieces(t *testing.T) { tor, err := New("../examples/" + tors["mul"]) if err != nil { diff --git a/tracker/messages.go b/tracker/messages.go index 5f96286..2df0367 100644 --- a/tracker/messages.go +++ b/tracker/messages.go @@ -2,6 +2,7 @@ package tracker import ( "bytes" + "crypto/sha1" "encoding/binary" "io/ioutil" "net" @@ -22,19 +23,19 @@ const ( ) type Request struct { - InfoHash []byte `query:"info_hash"` // info_hash - PeerID []byte `query:"peer_id"` // peer_id - Port int `query:"port,optional"` - Uploaded int `query:"uploaded,optional"` - Downloaded int `query:"downloaded,optional"` - Left int `query:"left,optional"` - Compact bool `query:"compact,optional"` // always true - NoPeerID bool `query:"no_peer_id,optional"` - Event Event `query:"event,optional"` - IP net.IPAddr `query:"ip,optional"` - NumWant int `query:"numwant,optional"` - Key []byte `query:"key,optional"` - TrackerID []byte `query:"tracker_id,optional"` + InfoHash [sha1.Size]byte `query:"info_hash"` // info_hash + PeerID []byte `query:"peer_id"` // peer_id + Port int `query:"port,optional"` + Uploaded int `query:"uploaded,optional"` + Downloaded int `query:"downloaded,optional"` + Left int `query:"left,optional"` + Compact bool `query:"compact,optional"` // always true + NoPeerID bool `query:"no_peer_id,optional"` + Event Event `query:"event,optional"` + IP net.IPAddr `query:"ip,optional"` + NumWant int `query:"numwant,optional"` + Key []byte `query:"key,optional"` + TrackerID []byte `query:"tracker_id,optional"` } // we support only compact mode -- cgit v1.2.3