Example #1
0
// Ensure that it's an error for a peer to send an invalid have message.
func TestPeerInvalidHave(t *testing.T) {
	cl, err := NewClient(&TestingConfig)
	require.NoError(t, err)
	defer cl.Close()
	ie := metainfo.InfoEx{
		Info: metainfo.Info{
			PieceLength: 1,
			Pieces:      make([]byte, 20),
			Files:       []metainfo.FileInfo{{Length: 1}},
		},
	}
	ie.UpdateBytes()
	tt, _new, err := cl.AddTorrentSpec(&TorrentSpec{
		Info:     &ie,
		InfoHash: ie.Hash(),
	})
	require.NoError(t, err)
	assert.True(t, _new)
	defer tt.Drop()
	cn := &connection{
		t: tt,
	}
	assert.NoError(t, cn.peerSentHave(0))
	assert.Error(t, cn.peerSentHave(1))
}
Example #2
0
// We read from a piece which is marked completed, but is missing data.
func TestCompletedPieceWrongSize(t *testing.T) {
	cfg := TestingConfig
	cfg.DefaultStorage = badStorage{}
	cl, err := NewClient(&cfg)
	require.NoError(t, err)
	defer cl.Close()
	ie := metainfo.InfoEx{
		Info: metainfo.Info{
			PieceLength: 15,
			Pieces:      make([]byte, 20),
			Files: []metainfo.FileInfo{
				metainfo.FileInfo{Path: []string{"greeting"}, Length: 13},
			},
		},
	}
	ie.UpdateBytes()
	tt, new, err := cl.AddTorrentSpec(&TorrentSpec{
		Info:     &ie,
		InfoHash: ie.Hash(),
	})
	require.NoError(t, err)
	defer tt.Drop()
	assert.True(t, new)
	r := tt.NewReader()
	defer r.Close()
	b, err := ioutil.ReadAll(r)
	assert.Len(t, b, 13)
	assert.NoError(t, err)
}
Example #3
0
// Called when metadata for a torrent becomes available.
func (t *Torrent) setInfoBytes(b []byte) error {
	if t.haveInfo() {
		return nil
	}
	var ie *metainfo.InfoEx
	err := bencode.Unmarshal(b, &ie)
	if err != nil {
		return fmt.Errorf("error unmarshalling info bytes: %s", err)
	}
	if ie.Hash() != t.infoHash {
		return errors.New("info bytes have wrong hash")
	}
	err = validateInfo(&ie.Info)
	if err != nil {
		return fmt.Errorf("bad info: %s", err)
	}
	defer t.updateWantPeersEvent()
	t.info = ie
	t.cl.event.Broadcast()
	t.gotMetainfo.Set()
	t.storage, err = t.storageOpener.OpenTorrent(t.info)
	if err != nil {
		return fmt.Errorf("error opening torrent storage: %s", err)
	}
	t.length = 0
	for _, f := range t.info.UpvertedFiles() {
		t.length += f.Length
	}
	t.metadataBytes = b
	t.metadataCompletedChunks = nil
	hashes := infoPieceHashes(&t.info.Info)
	t.pieces = make([]piece, len(hashes))
	for i, hash := range hashes {
		piece := &t.pieces[i]
		piece.t = t
		piece.index = i
		piece.noPendingWrites.L = &piece.pendingWritesMutex
		missinggo.CopyExact(piece.Hash[:], hash)
	}
	for _, conn := range t.conns {
		if err := conn.setNumPieces(t.numPieces()); err != nil {
			log.Printf("closing connection: %s", err)
			conn.Close()
		}
	}
	for i := range t.pieces {
		t.updatePieceCompletion(i)
		t.pieces[i].QueuedForHash = true
	}
	go func() {
		for i := range t.pieces {
			t.verifyPiece(i)
		}
	}()
	return nil
}
Example #4
0
// Called when metadata for a torrent becomes available.
func (t *Torrent) setInfoBytes(b []byte) error {
	if t.haveInfo() {
		return nil
	}
	var ie *metainfo.InfoEx
	err := bencode.Unmarshal(b, &ie)
	if err != nil {
		return fmt.Errorf("error unmarshalling info bytes: %s", err)
	}
	if ie.Hash() != t.infoHash {
		return errors.New("info bytes have wrong hash")
	}
	err = validateInfo(&ie.Info)
	if err != nil {
		return fmt.Errorf("bad info: %s", err)
	}
	defer t.updateWantPeersEvent()
	t.info = ie
	t.displayName = "" // Save a few bytes lol.
	t.cl.event.Broadcast()
	t.gotMetainfo.Set()
	t.storage, err = t.storageOpener.OpenTorrent(t.info)
	if err != nil {
		return fmt.Errorf("error opening torrent storage: %s", err)
	}
	t.length = 0
	for _, f := range t.info.UpvertedFiles() {
		t.length += f.Length
	}
	t.metadataBytes = b
	t.metadataCompletedChunks = nil
	t.makePieces()
	for _, conn := range t.conns {
		if err := conn.setNumPieces(t.numPieces()); err != nil {
			log.Printf("closing connection: %s", err)
			conn.Close()
		}
	}
	for i := range t.pieces {
		t.updatePieceCompletion(i)
		t.pieces[i].QueuedForHash = true
	}
	go func() {
		for i := range t.pieces {
			t.verifyPiece(i)
		}
	}()
	return nil
}
Example #5
0
func writeTorrentData(ts storage.Torrent, info *metainfo.InfoEx, b []byte) {
	for i := range iter.N(info.NumPieces()) {
		n, _ := ts.Piece(info.Piece(i)).WriteAt(b, 0)
		b = b[n:]
	}
}