[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