func test(peer *Peer, torrent *Torrent) (err error) { log.Debugf("Fired!") err = peer.Connect() if err != nil || peer.Conn == nil { return } err = peer.SendHandshake(torrent.InfoHash, string(torrent.ClientId)) if err != nil { log.Errorf("%v", err) } err = peer.SendUnchoke() if err != nil { log.Errorf("%v", err) } err = peer.SendInterested() if err != nil { log.Errorf("%v", err) } err = peer.RequestBlock(300, 0, uint32(PieceChunkLenght)) if err != nil { log.Errorf("%v", err) } err = peer.ReadHandshake() log.Debugf("Receiving Data...") err = peer.ReceiveData() if err != nil { log.Errorf("%v", err) } peer.ParseData() return }
func (torrent *Torrent) UpdatePeers() { trackerResponse, err := torrent.Tracker.Peers( torrent.InfoHash, torrent.ClientId, torrent.Port, torrent.Uploaded, torrent.Downloaded, torrent.Length, ) if err != nil { log.Errorf("Unable to retrieve the peers: %v", err) } addresses := make(map[string]bool) for _, peer := range torrent.Peers { addresses[peer.Addr.String()] = true } for _, peerAddr := range trackerResponse.PeerAddresses { if _, ok := addresses[peerAddr.String()]; !ok { log.Debugf("Found Peer: %v", peerAddr) torrent.AddPeer(peerAddr) } } }
func (peer *Peer) ReadHandshake() (err error) { buf := make([]byte, messages.HandshakeLength) n, err := peer.Conn.Read(buf) if err != nil || n != messages.HandshakeLength { log.Errorf("Cannot read the handshake: %v", err) return err } var hand messages.Handshake err = binary.Read(bytes.NewBuffer(buf), binary.BigEndian, &hand) if err != nil { log.Errorf("%v", err) } log.Debugf("Handshake from peer %v", peer.Addr.String()) log.Debugf(hand.String()) return err }
func (peer *Peer) ReceiveData() (err error) { nBytes := 0 buf := make([]byte, 65536) for { peer.Conn.SetReadDeadline(time.Now().Add(5 * time.Second)) n, err := peer.Conn.Read(buf) readed := buf[:n] nBytes += n if err == io.EOF || n == 0 { break } if err != nil { log.Errorf("Error in reading: %v", err) return err } peer.Data = append(peer.Data, readed...) } log.Debugf("Readed %v, byte(s)", nBytes) //log.Debugf("%v", peer.Data) return }
func (peer *Peer) ParseData() { for { if len(peer.Data) < 4 { break /*peer.SendUnchoke() peer.SendInterested() log.Debugf("Trying to request piece #%v", i) peer.RequestBlock(300, 0, uint32(PieceChunkLenght)) peer.ReceiveData() i++*/ } var message messages.Message err := binary.Read(bytes.NewBuffer(peer.Data[:4]), binary.BigEndian, &message.Length) if err != nil { panic(err) } if message.Length == 0 { log.Debugf("Keep alive") peer.Data = peer.Data[4:] } else { message.Id = peer.Data[4] data := peer.Data[:4+message.Length] switch message.Id { case messages.ChokeId: log.Debugf("Choke") case messages.UnchokeId: log.Debugf("Unchoke") case messages.InterestedId: log.Debugf("Interested") case messages.NotInterestedId: log.Debugf("NotInterested") case messages.HaveId: var haveMsg messages.Have err = binary.Read(bytes.NewBuffer(data), binary.BigEndian, &haveMsg) log.Debugf("Peer %v - Have piece #%v", peer.Addr.String(), haveMsg.PieceIndex) if haveMsg.PieceIndex > peer.PieceCount { log.Errorf("Invalid piece index, piece index: %v, piece count: %v", haveMsg.PieceIndex, peer.PieceCount) break } peer.BitField.Set(int(haveMsg.PieceIndex), true) log.Debugf("Peer %v - BitField updated", peer.Addr.String()) case messages.BitFieldId: log.Debugf("BitField") var bitMsg messages.BitArray err = binary.Read(bytes.NewBuffer(data), binary.BigEndian, &bitMsg) bitMsg.BitField = data[:message.Length-1] bitCount := (message.Length - 1) * 8 if peer.PieceCount > bitCount { log.Errorf("Invalid BitField, bit count: %v, piece count: %v", bitCount, peer.PieceCount) break } peer.BitField = bitarray.NewFromBytes(bitMsg.BitField, int(peer.PieceCount)) log.Debugf("Peer %v - New BitField:", peer.Addr.String()) case messages.RequestId: log.Debugf("Request") case messages.PieceId: log.Debugf("Piece") var pieceMsg messages.Piece err = binary.Read(bytes.NewBuffer(data), binary.BigEndian, &pieceMsg) pieceMsg.BlockData = data[:message.Length-9] log.Debugf("Peer %v - Found a new block - PieceIndex: %v BlockOffset: %v", peer.Addr.String(), pieceMsg.PieceIndex, pieceMsg.BlockOffset) case messages.CancelId: log.Debugf("Cancel") case messages.PortId: log.Debugf("Port") } peer.Data = peer.Data[4+message.Length:] } } return }