list of connections per piece. send bitfield

This commit is contained in:
orignal
2026-07-15 20:37:28 -04:00
parent 361bee9480
commit 8971c22c16
2 changed files with 33 additions and 1 deletions
+28 -1
View File
@@ -194,6 +194,7 @@ namespace torrents
f.write ((const char *)m_Data, m_Size);
delete[] m_Data; m_Data = nullptr;
if (m_Missing) BN_free (m_Missing);
m_Connections.clear ();
}
}
@@ -230,6 +231,11 @@ namespace torrents
return { 0, 0 };
}
void Piece::AddConnection (std::shared_ptr<PeerConnection> connection)
{
m_Connections.emplace_back (connection);
}
Torrent::Torrent (std::string_view buf):
m_Length (0), m_PieceLength (0), m_Interval (0)
{
@@ -560,8 +566,13 @@ namespace torrents
return 0;
}
m_RemotePeerID = std::string_view ((const char *)(m_ReceiveBuffer + 48), 20);
// respond wiith handshake if incoming
if (!m_IsHandshakeSent)
SendHandshakeMsg ();
// send bitfield if not empty
auto bitfield = m_Torrent->CreateBitfield ();
if (bitfield.size ())
SendBitfieldMsg (bitfield.data (), bitfield.size ());
m_IsEstablished = true;
return HANDSHAKE_MSG_LENGTH;
}
@@ -596,6 +607,22 @@ namespace torrents
BN_free (m_RemoteBitfield);
m_RemoteBitfield = newBitfield;
}
if (m_Torrent)
{
size_t numPieces = m_Torrent->GetNumPieces ();
for (size_t i = 0; i < numPieces; i++)
if (BN_is_bit_set (m_RemoteBitfield, numPieces - i - 1))
m_Torrent->GetPiece (i).AddConnection (shared_from_this ());
}
}
void PeerConnection::SendBitfieldMsg (const uint8_t * bitfield, size_t bitfieldLen)
{
std::vector<uint8_t> sendBuffer(bitfieldLen + 5);
htobe32buf (sendBuffer.data (), bitfieldLen + 1); // length
sendBuffer[4] = eMessageTypeBitfield; // msg ID
memcpy (sendBuffer.data () + 5, bitfield, bitfieldLen);
WriteToStream (sendBuffer.data (), sendBuffer.size ());
}
void PeerConnection::HandlePieceMsg (const uint8_t * buf, size_t len)
@@ -617,7 +644,7 @@ namespace torrents
void PeerConnection::SendPieceMsg (uint32_t index, uint32_t offset, const uint8_t * data, size_t len)
{
std::vector<uint8_t> sendBuffer(len + 8 + 5);
htobe32buf (sendBuffer.data (), len + 8); // length
htobe32buf (sendBuffer.data (), len + 8 + 1); // length
sendBuffer[4] = eMessageTypePiece; // msg ID
htobe32buf (sendBuffer.data () + 5, index);
htobe32buf (sendBuffer.data () + 9, offset);
+5
View File
@@ -43,6 +43,7 @@ namespace torrents
eMessageTypePiece = 7
};
class PeerConnection;
class Piece final
{
public:
@@ -60,6 +61,8 @@ namespace torrents
size_t GetSize () const { return m_Size; }
std::pair<size_t, size_t> GetAvailableBuffer (size_t offset, size_t len) const; // return (offset, len) of available data
void AddConnection (std::shared_ptr<PeerConnection> connection);
private:
bool IsAvailable (int block) const;
@@ -70,6 +73,7 @@ namespace torrents
size_t m_Size;
uint8_t * m_Data, m_Hash[SHA_DIGEST_LENGTH];
BIGNUM * m_Missing; // bit is set if block is missing
std::list<std::weak_ptr<PeerConnection> > m_Connections; // for incomplete pieces only
};
class Torrent final
@@ -136,6 +140,7 @@ namespace torrents
void SendHandshakeMsg ();
void HandleBitfieldMsg (const uint8_t * buf, size_t len);
void SendBitfieldMsg (const uint8_t * bitfield, size_t bitfieldLen);
void HandlePieceMsg (const uint8_t * buf, size_t len);
void SendPieceMsg (uint32_t index, uint32_t offset, const uint8_t * data, size_t len);
void HandleRequestMsg (const uint8_t * buf, size_t len);