[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: extragear/network/ktorrent/libbtcore
From: Joris Guisson <joris.guisson () gmail ! com>
Date: 2009-11-21 15:47:51
Message-ID: 1258818471.156197.6145.nullmailer () svn ! kde ! org
[Download RAW message or body]
SVN commit 1052409 by guisson:
Added support for ut_metadata extension, first part of magnet implementation
M +4 -0 CMakeLists.txt
M +0 -20 peer/packetwriter.cpp
M +0 -3 peer/packetwriter.h
M +103 -47 peer/peer.cpp
M +12 -4 peer/peer.h
M +7 -0 peer/peermanager.cpp
A peer/peerprotocolextension.cpp [License: GPL (v2+)]
A peer/peerprotocolextension.h [License: GPL (v2+)]
A peer/utmetadata.cpp [License: GPL (v2+)]
A peer/utmetadata.h [License: GPL (v2+)]
M +4 -5 peer/utpex.cpp
M +4 -5 peer/utpex.h
M +3 -2 torrent/torrent.cpp
M +4 -0 torrent/torrent.h
--- trunk/extragear/network/ktorrent/libbtcore/CMakeLists.txt #1052408:1052409
@@ -89,7 +89,9 @@
peer/peeruploader.cpp
peer/packetwriter.cpp
peer/packetreader.cpp
+ peer/peerprotocolextension.cpp
peer/utpex.cpp
+ peer/utmetadata.cpp
peer/accessmanager.cpp
peer/badpeerslist.cpp
@@ -254,7 +256,9 @@
./peer/peermanager.h
./peer/authenticatebase.h
./peer/authenticate.h
+ ./peer/peerprotocolextension.h
./peer/utpex.h
+ ./peer/utmetadata.h
./peer/packetreader.h
./peer/authenticationmonitor.h
./peer/peerid.h
--- trunk/extragear/network/ktorrent/libbtcore/peer/packetwriter.cpp #1052408:1052409
@@ -197,26 +197,6 @@
}
}
- void PacketWriter::sendExtProtHandshake(Uint16 port,bool pex_on)
- {
- QByteArray arr;
- BEncoder enc(new BEncoderBufferOutput(arr));
- enc.beginDict();
- enc.write(QString("m"));
- // supported messages
- enc.beginDict();
- enc.write(QString("ut_pex"));enc.write((Uint32)(pex_on ? 1 : 0));
- enc.end();
- if (port > 0)
- {
- enc.write(QString("p"));
- enc.write((Uint32)port);
- }
- enc.write(QString("v")); enc.write(bt::GetVersionString());
- enc.end();
- sendExtProtMsg(0,arr);
- }
-
void PacketWriter::sendExtProtMsg(Uint8 id,const QByteArray & data)
{
queuePacket(new Packet(id,data));
--- trunk/extragear/network/ktorrent/libbtcore/peer/packetwriter.h #1052408:1052409
@@ -140,9 +140,6 @@
*/
void sendSuggestPiece(Uint32 index);
- /// Send the extension protocol handshake
- void sendExtProtHandshake(Uint16 port,bool pex_on = true);
-
/// Send an extended protocol message
void sendExtProtMsg(Uint8 id,const QByteArray & data);
--- trunk/extragear/network/ktorrent/libbtcore/peer/peer.cpp #1052408:1052409
@@ -20,6 +20,7 @@
#include "peer.h"
#include <math.h>
+#include <btversion.h>
#include <util/log.h>
#include <util/functions.h>
#include <net/address.h>
@@ -28,6 +29,7 @@
#include <download/piece.h>
#include <download/request.h>
#include <bcodec/bdecoder.h>
+#include <bcodec/bencoder.h>
#include <bcodec/bnode.h>
#include <torrent/server.h>
#include <torrent/torrent.h>
@@ -38,7 +40,9 @@
#include "utpex.h"
#include "peermanager.h"
#include <net/reverseresolver.h>
+#include "utmetadata.h"
+
using namespace net;
namespace bt
@@ -55,7 +59,7 @@
id = peer_id_counter;
peer_id_counter++;
- ut_pex = 0;
+ ut_pex_id = 0;
preader = new PacketReader(this);
stats.choked = true;
stats.interested = stats.am_interested = false;
@@ -99,7 +103,7 @@
sock->startMonitoring(preader,pwriter);
}
pex_allowed = stats.extension_protocol;
- utorrent_pex_id = 0;
+ extensions.setAutoDelete(true);
if (resolve_hostname)
{
@@ -112,7 +116,6 @@
Peer::~Peer()
{
- delete ut_pex;
delete uploader;
delete downloader;
delete sock;
@@ -349,50 +352,78 @@
void Peer::handleExtendedPacket(const Uint8* packet,Uint32 size)
{
- if (size <= 2 || packet[1] > 1)
+ if (size <= 2)
return;
- if (packet[1] == 1)
+ PeerProtocolExtension* ext = extensions.find(packet[1]);
+ if (ext)
{
- if (ut_pex)
- ut_pex->handlePexPacket(packet,size);
- return;
+ ext->handlePacket(packet,size);
}
-
+ else if (packet[1] == 0)
+ {
+ handleExtendedHandshake(packet,size);
+ }
+ }
+
+ void Peer::handleExtendedHandshake(const Uint8* packet,Uint32 size)
+ {
QByteArray tmp = QByteArray::fromRawData((const char*)packet,size);
BNode* node = 0;
try
{
BDecoder dec(tmp,false,2);
node = dec.decode();
- if (node && node->getType() == BNode::DICT)
+ if (!node || !node->getType() == BNode::DICT)
{
- BDictNode* dict = (BDictNode*)node;
-
- // handshake packet, so just check if the peer supports ut_pex
- dict = dict->getDict(QString("m"));
- BValueNode* val = 0;
- if (dict && (val = dict->getValue("ut_pex")) && UTPex::isEnabled())
+ delete node;
+ return;
+ }
+
+ BDictNode* dict = (BDictNode*)node;
+ BDictNode* mdict = dict->getDict(QString("m"));
+ if (!mdict)
+ {
+ delete node;
+ return;
+ }
+
+ BValueNode* val = 0;
+
+ if ((val = mdict->getValue("ut_pex")) && UTPex::isEnabled())
+ {
+ // ut_pex packet
+ ut_pex_id = val->data().toInt();
+ if (ut_pex_id == 0)
{
- utorrent_pex_id = val->data().toInt();
- if (ut_pex)
- {
- if (utorrent_pex_id > 0)
- ut_pex->changeID(utorrent_pex_id);
- else
- {
- // id 0 means disabled
- delete ut_pex;
- ut_pex = 0;
- }
- }
- else if (!ut_pex && utorrent_pex_id != 0 && pex_allowed)
- {
- // Don't create it when the id is 0
- ut_pex = new UTPex(this,utorrent_pex_id);
- }
+ extensions.erase(UT_PEX_ID);
}
+ else
+ {
+ PeerProtocolExtension* ext = extensions.find(UT_METADATA_ID);
+ if (ext)
+ ext->changeID(ut_pex_id);
+ else if (pex_allowed)
+ extensions.insert(UT_PEX_ID,new UTPex(this,ut_pex_id));
+ }
}
+ else if ((val = mdict->getValue("ut_metadata")))
+ {
+ // meta data
+ Uint32 ut_metadata_id = val->data().toInt();
+ if (ut_metadata_id == 0) // disabled by other side
+ {
+ extensions.erase(UT_METADATA_ID);
+ }
+ else
+ {
+ PeerProtocolExtension* ext = extensions.find(UT_METADATA_ID);
+ if (ext)
+ ext->changeID(id);
+ else
+ extensions.insert(UT_METADATA_ID,new UTMetaData(pman->getTorrent(),ut_metadata_id,this));
+ }
+ }
}
catch (...)
{
@@ -469,9 +500,14 @@
uploader->addUploadedBytes(data_bytes);
}
- if (ut_pex && ut_pex->needsUpdate())
- ut_pex->update(pman);
-
+ PtrMap<Uint32,PeerProtocolExtension>::iterator i = extensions.begin();
+ while (i != extensions.end())
+ {
+ if (i->second->needsUpdate())
+ i->second->update();
+ i++;
+ }
+
// if no data is being sent or recieved, and there are pending requests
// increment the connection stalled timer
if (getUploadRate() > 100 || getDownloadRate() > 100 ||
@@ -579,26 +615,46 @@
if (!stats.extension_protocol)
return;
- // send extension protocol handshake
- bt::Uint16 port = Globals::instance().getServer().getPortInUse();
-
- if (ut_pex && (!on || !UTPex::isEnabled()))
+ PeerProtocolExtension* ext = extensions.find(UT_PEX_ID);
+ if (ext && (!on || !UTPex::isEnabled()))
{
- delete ut_pex;
- ut_pex = 0;
-
+ extensions.erase(UT_PEX_ID);
}
- else if (!ut_pex && on && utorrent_pex_id > 0 && UTPex::isEnabled())
+ else if (!ext && on && ut_pex_id > 0 && UTPex::isEnabled())
{
// if the other side has enabled it to, create a new UTPex object
- ut_pex = new UTPex(this,utorrent_pex_id);
+ extensions.insert(UT_PEX_ID,new UTPex(this,ut_pex_id));
}
- pwriter->sendExtProtHandshake(port,on);
-
pex_allowed = on;
}
+ void Peer::sendExtProtHandshake(Uint16 port, Uint32 metadata_size)
+ {
+ if (!stats.extension_protocol)
+ return;
+
+ QByteArray arr;
+ BEncoder enc(new BEncoderBufferOutput(arr));
+ enc.beginDict();
+ enc.write(QString("m"));
+ // supported messages
+ enc.beginDict();
+ enc.write(QString("ut_pex"));enc.write((Uint32)(pex_allowed ? UT_PEX_ID : 0));
+ enc.write(QString("ut_metadata")); enc.write(UT_METADATA_ID);
+ enc.end();
+ if (port > 0)
+ {
+ enc.write(QString("p"));
+ enc.write((Uint32)port);
+ }
+ enc.write(QString("v")); enc.write(bt::GetVersionString());
+ enc.write(QString("metadata_size")); enc.write(metadata_size);
+ enc.end();
+ pwriter->sendExtProtMsg(0,arr);
+ }
+
+
void Peer::setGroupIDs(Uint32 up_gid,Uint32 down_gid)
{
sock->setGroupIDs(up_gid,down_gid);
--- trunk/extragear/network/ktorrent/libbtcore/peer/peer.h #1052408:1052409
@@ -25,8 +25,10 @@
#include <util/timer.h>
#include <interfaces/peerinterface.h>
#include <util/bitset.h>
+#include <util/ptrmap.h>
#include <btcore_export.h>
#include "peerid.h"
+#include "peerprotocolextension.h"
namespace net
{
@@ -48,11 +50,10 @@
class PeerDownloader;
class PeerUploader;
class PeerManager;
- class UTPex;
-
+
/**
* @author Joris Guisson
* @brief Manages the connection with a peer
@@ -142,6 +143,9 @@
/// Get the PeerUploader.
PeerUploader* getPeerUploader() {return uploader;}
+ /// Get the PeerManager
+ PeerManager* getPeerManager() {return pman;}
+
/**
* Send a chunk of data.
* @param data The data
@@ -223,6 +227,9 @@
/// Disable or enable pex
void setPexEnabled(bool on);
+ /// Send an extended protocol handshake
+ void sendExtProtHandshake(Uint16 port,Uint32 metadata_size);
+
/**
* Set the peer's group IDs for traffic
* @param up_gid The upload gid
@@ -239,6 +246,7 @@
private:
void packetReady(const Uint8* packet,Uint32 size);
void handleExtendedPacket(const Uint8* packet,Uint32 size);
+ void handleExtendedHandshake(const Uint8* packet,Uint32 size);
private:
mse::StreamSocket* sock;
@@ -256,10 +264,10 @@
PeerUploader* uploader;
mutable PeerInterface::Stats stats;
QTime connect_time;
- UTPex* ut_pex;
bool pex_allowed;
- Uint32 utorrent_pex_id;
PeerManager* pman;
+ PtrMap<Uint32,PeerProtocolExtension> extensions;
+ Uint32 ut_pex_id;
static bool resolve_hostname;
--- trunk/extragear/network/ktorrent/libbtcore/peer/peermanager.cpp #1052408:1052409
@@ -355,6 +355,9 @@
total_connections++;
newPeer(peer);
peer->setPexEnabled(pex_on);
+ // send extension protocol handshake
+ bt::Uint16 port = Globals::instance().getServer().getPortInUse();
+ peer->sendExtProtHandshake(port,tor.getMetaData().size());
}
bool PeerManager::connectedTo(const PeerID & peer_id)
@@ -650,7 +653,11 @@
{
Peer* p = *i;
if (!p->isKilled())
+ {
p->setPexEnabled(on);
+ bt::Uint16 port = Globals::instance().getServer().getPortInUse();
+ p->sendExtProtHandshake(port,tor.getMetaData().size());
+ }
i++;
}
pex_on = on;
--- trunk/extragear/network/ktorrent/libbtcore/peer/utpex.cpp #1052408:1052409
@@ -34,16 +34,14 @@
bool UTPex::pex_enabled = true;
- UTPex::UTPex(Peer* peer,Uint32 id) : peer(peer),id(id),last_updated(0)
+ UTPex::UTPex(Peer* peer,Uint32 id) : PeerProtocolExtension(id,peer),last_updated(0)
{}
UTPex::~UTPex()
{}
-
-
- void UTPex::handlePexPacket(const Uint8* packet,Uint32 size)
+ void UTPex::handlePacket(const Uint8* packet,Uint32 size)
{
if (size <= 2 || packet[1] != 1)
return;
@@ -80,8 +78,9 @@
return bt::GetCurrentTime() - last_updated >= 60*1000;
}
- void UTPex::update(PeerManager* pman)
+ void UTPex::update()
{
+ PeerManager* pman = peer->getPeerManager();
last_updated = bt::GetCurrentTime();
std::map<Uint32,net::Address> added;
--- trunk/extragear/network/ktorrent/libbtcore/peer/utpex.h #1052408:1052409
@@ -24,6 +24,7 @@
#include <btcore_export.h>
#include <net/address.h>
#include <util/constants.h>
+#include "peerprotocolextension.h"
namespace bt
{
@@ -36,7 +37,7 @@
*
* Class which handles µTorrent's peer exchange
*/
- class BTCORE_EXPORT UTPex
+ class BTCORE_EXPORT UTPex : public PeerProtocolExtension
{
public:
UTPex(Peer* peer,Uint32 id);
@@ -47,13 +48,13 @@
* @param packet The packet
* @param size The size of the packet
*/
- void handlePexPacket(const Uint8* packet,Uint32 size);
+ void handlePacket(const Uint8* packet,Uint32 size);
/// Do we need to update PEX (should happen every minute)
bool needsUpdate() const;
/// Send a new PEX packet to the Peer
- void update(PeerManager* pman);
+ void update();
/// Change the ID used in the extended packets
void changeID(Uint32 nid) {id = nid;}
@@ -68,8 +69,6 @@
void encodeFlags(BEncoder & enc,const std::map<Uint32,Uint8> & flags);
private:
- Peer* peer;
- Uint32 id;
std::map<Uint32,net::Address> peers;
TimeStamp last_updated;
static bool pex_enabled;
--- trunk/extragear/network/ktorrent/libbtcore/torrent/torrent.cpp #1052408:1052409
@@ -127,8 +127,9 @@
BNode* n = dict->getData("info");
SHA1HashGen hg;
- Uint8* info = (Uint8*)data.data();
- info_hash = hg.generate(info + n->getOffset(),n->getLength());
+ // save info dict
+ metadata = data.mid(n->getOffset(),n->getLength());
+ info_hash = hg.generate((const Uint8*)metadata.data(),metadata.size());
delete node;
}
catch (...)
--- trunk/extragear/network/ktorrent/libbtcore/torrent/torrent.h #1052408:1052409
@@ -247,6 +247,9 @@
/// Set the monitor
void setMonitor(MonitorInterface* m) {tmon = m;}
+
+ /// Get the metadata
+ const QByteArray & getMetaData() const {return metadata;}
private:
void loadInfo(BDictNode* node);
@@ -278,6 +281,7 @@
mutable Uint32 pos_cache_file;
MonitorInterface* tmon;
QString comments;
+ QByteArray metadata;
};
}
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic