You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ktorrent/libktorrent/torrent/peermanager.h

253 lines
6.6 KiB

/***************************************************************************
* Copyright (C) 2005 by Joris Guisson *
* joris.guisson@gmail.com *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#ifndef BTPEERMANAGER_H
#define BTPEERMANAGER_H
#include <map>
#include <tqobject.h>
#include <tqptrlist.h>
#include <util/ptrmap.h>
#include "globals.h"
#include "peerid.h"
#include <util/bitset.h>
#include <interfaces/peersource.h>
namespace mse
{
class StreamSocket;
}
namespace bt
{
class Peer;
class ChunkManager;
class Torrent;
class Authenticate;
class ChunkCounter;
const Uint32 MAX_SIMULTANIOUS_AUTHS = 20;
/**
* @author Joris Guisson
* @brief Manages all the Peers
*
* This class manages all Peer objects.
* It can also open connections to other peers.
*/
class PeerManager : public TQObject
{
Q_OBJECT
TQ_OBJECT
public:
/**
* Constructor.
* @param tor The Torrent
*/
PeerManager(Torrent & tor);
virtual ~PeerManager();
/**
* Check for new connections, update down and upload speed of each Peer.
* Initiate new connections.
*/
void update();
/**
* Remove dead peers.
* @return The number of dead ones removed
*/
Uint32 clearDeadPeers();
/**
* Get the i'th Peer.
* @param index
* @return Peer or 0 if out of range
*/
Peer* getPeer(Uint32 index) {return peer_list.at(index);}
/**
* Find a Peer based on it's ID
* @param peer_id The ID
* @return A Peer or 0, if nothing could be found
*/
Peer* findPeer(Uint32 peer_id);
/**
* Try to connect to some peers
*/
void connectToPeers();
/**
* Close all Peer connections.
*/
void closeAllConnections();
/**
* Start listening to incoming requests.
*/
void start();
/**
* Stop listening to incoming requests.
*/
void stop();
/**
* Kill all peers who have been choked longer then @a older_then time.
* @param older_then Time in milliseconds
*/
void killChokedPeers(Uint32 older_then);
Uint32 getNumConnectedPeers() const {return peer_list.count();}
Uint32 getNumPending() const {return num_pending;}
static void setMaxConnections(Uint32 max);
static Uint32 getMaxConnections() {return max_connections;}
static void setMaxTotalConnections(Uint32 max);
static Uint32 getMaxTotalConnections() {return max_total_connections;}
static Uint32 getTotalConnections() {return total_connections;}
/// Is the peer manager started
bool isStarted() const {return started;}
/// Get the Torrent
Torrent & getTorrent() {return tor;}
/**
* A new connection is ready for this PeerManager.
* @param sock The socket
* @param peer_id The Peer's ID
* @param support What extensions the peer supports
*/
void newConnection(mse::StreamSocket* sock,const PeerID & peer_id,Uint32 support);
/**
* Add a potential peer
* @param pp The PotentialPeer
*/
void addPotentialPeer(const kt::PotentialPeer & pp);
/**
* Kills all connections to seeders.
* This is used when torrent download gets finished
* and we should drop all connections to seeders
*/
void killSeeders();
/**
* Kills all peers that are not interested for a long time.
* This should be used when torrent is seeding ONLY.
*/
void killUninterested();
/// Get a BitSet of all available chunks
const BitSet & getAvailableChunksBitSet() const {return available_chunks;}
/// Get the chunk counter.
ChunkCounter & getChunkCounter() {return *cnt;};
/// Are we connected to a Peer given it's PeerID ?
bool connectedTo(const PeerID & peer_id);
/**
* A peer has authenticated.
* @param auth The Authenticate object
* @param ok Wether or not the attempt was succesfull
*/
void peerAuthenticated(Authenticate* auth,bool ok);
/**
* Save the IP's and port numbers of all peers.
*/
void savePeerList(const TQString & file);
/**
* Load the peer list again and add them to the potential peers
*/
void loadPeerList(const TQString & file);
typedef TQPtrList<Peer>::const_iterator CItr;
CItr beginPeerList() const {return peer_list.begin();}
CItr endPeerList() const {return peer_list.end();}
/// Is PEX eanbled
bool isPexEnabled() const {return pex_on;}
/// Enable or disable PEX
void setPexEnabled(bool on);
/// Set the group IDs of each peer
void setGroupIDs(Uint32 up,Uint32 down);
public slots:
/**
* A PeerSource, has new potential peers.
* @param ps The PeerSource
*/
void peerSourceReady(kt::PeerSource* ps);
private:
void updateAvailableChunks();
bool killBadPeer();
void createPeer(mse::StreamSocket* sock,const PeerID & peer_id,Uint32 support,bool local);
bool connectedTo(const TQString & ip,Uint16 port) const;
private slots:
void onHave(Peer* p,Uint32 index);
void onBitSetRecieved(const BitSet & bs);
void onRerunChoker();
void pex(const TQByteArray & arr);
signals:
void newPeer(Peer* p);
void peerKilled(Peer* p);
void stopped();
private:
PtrMap<Uint32,Peer> peer_map;
TQPtrList<Peer> peer_list;
TQPtrList<Peer> killed;
Torrent & tor;
bool started;
BitSet available_chunks;
ChunkCounter* cnt;
Uint32 num_pending;
bool pex_on;
static Uint32 max_connections;
static Uint32 max_total_connections;
static Uint32 total_connections;
std::multimap<TQString,kt::PotentialPeer> potential_peers;
typedef std::multimap<TQString,kt::PotentialPeer>::iterator PPItr;
};
}
#endif