Failing to download pieces different than 0 #nd2

This is the traffic I receive when I ask for piece 0:

peer: 165.232.35.114:51531
...
recv: [0 0 0 2 5 224] # bitfield message receive
send: [0 0 0 2 2 0] # respond with an interested
recv: [0 0 0 1 1] # receive an unchoke
send: [0 0 0 13 6 0 0 0 0 0 0 0 0 0 0 64 0] # I ask for piece 0
recv[ block 0 ]: 16397 length
recv[ block 1 ]: 16397 length

but when I ask for piece 1 I just get length 0 messages but not the piece block

peer: 165.232.35.114:51531
...
recv: [0 0 0 2 5 224] # bitfield message receive
send: [0 0 0 2 2 0] # respond with an interested
recv: [0 0 0 1 1] # receive an unchoke
send: [0 0 0 13 6 0 0 0 1 0 0 0 0 0 0 64 0] # I ask for piece 1
recv[ block 0 ]: 0 length
send: [0 0 0 13 6 0 0 0 1 0 0 0 0 0 0 64 0] # I ask again for piece 1
recv[ block 0 ]: 0 length

Hey @adecora, would you mind pushing your latest code so that I can take a closer look?

Yes here is the code,sorry about the mess I’m hardcoding few things in order to try to get some answer for the peers

peerMsg := PeerMessage{}
		peerMsg.Read(conn)
		fmt.Println("recv:", peerMsg.Bytes())
		assert(peerMsg.Id == 5, "First message must always be os type 5 bitfield")

		// We send an interested message
		peerMsg = PeerMessage{
			Length:  2,
			Id:      2,
			Payload: make([]byte, 1),
		}

		_, err = conn.Write(peerMsg.Bytes())
		if err != nil {
			return err
		}
		fmt.Println("send:", peerMsg.Bytes())
		peerMsg.Read(conn)
		fmt.Println("recv:", peerMsg.Bytes())
		assert(peerMsg.Id == 1, "Peer always send unchoke")

		allPiece := make([]byte, torrent.Info.PieceLength)
               
                // BlockSize = 2**14
 		// + (BlockSize - 1) rounds up
		PieceLength := torrent.Info.PieceLength
		if piece == len(piecesHash)-1 {
			PieceLength = torrent.Info.Length % torrent.Info.PieceLength
		}
		fmt.Println(pieceAddress)
		fmt.Println("piece lenght:", PieceLength)
		var nblocks uint = (uint(PieceLength) + (BlockSize - 1)) / BlockSize
		for block := uint(0); block < nblocks; block++ {
			length := BlockSize
			if (block == nblocks-1) && (uint(PieceLength)%BlockSize != 0) {
				length = uint(PieceLength) % BlockSize
			}

			for {
				reqPayload := PieceRequest{}
				reqPayload.New(piece, block*BlockSize, length)

				peerMsg = PeerMessage{
					Length:  13,
					Id:      6,
					Payload: reqPayload.Bytes(),
				}
				fmt.Println("send:", peerMsg.Bytes())
				_, err = conn.Write(peerMsg.Bytes())
				if err != nil {
					return err
				}
				fmt.Println("writed")
				peerMsg.Read(conn)
				fmt.Println("recv[", block, "]:", len(peerMsg.Bytes()))
				copy(allPiece[block*BlockSize:block*BlockSize+length], peerMsg.Bytes())
				if peerMsg.Length != 0 {
					break
				}
			}

These are the auxiliar functions.

func (p *PeerMessage) Read(conn net.Conn) error {
	header := make([]byte, 4)
	_, err := io.ReadFull(conn, header)
	if err != nil {
		return err
	}

	length := binary.BigEndian.Uint32(header)
	p.Length = length

	if length == 0 {
		p.Id = 0
		p.Payload = nil
		return nil
	}

	body := make([]byte, length)
	_, err = io.ReadFull(conn, body)
	if err != nil {
		return err
	}

	p.Id = body[0]
	p.Payload = body[1:]

	return nil
}

func (p *PeerMessage) Bytes() []byte {
	var peerMsg bytes.Buffer

	buff := make([]byte, 4)
	binary.BigEndian.PutUint32(buff, p.Length)

	peerMsg.Write(buff)
	peerMsg.WriteByte(p.Id)
	peerMsg.Write(p.Payload)

	return peerMsg.Bytes()
}

func (p *PieceRequest) New(index int, offset uint, length uint) {
	p.Index = uint32(index)
	p.Begin = uint32(offset)
	p.Length = uint32(length)
}

func (p *PieceRequest) Bytes() []byte {
	buf := make([]byte, 12)

	binary.BigEndian.PutUint32(buf[0:4], p.Index)
	binary.BigEndian.PutUint32(buf[4:8], p.Begin)
	binary.BigEndian.PutUint32(buf[8:12], p.Length)

	return buf
}

@adecora It’s a bit tricky to debug a partial code snippet. :sweat_smile:

We have access to your submissions, but the latest one is from five days ago.

If you could push your most recent code, that’d make it much easier to debug. I’ll be able to run it directly and help more effectively. :handshake:

Sorry :see_no_evil_monkey: I’m already push a commit with the buggy download_piece implementation.

1 Like