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/peer.h

326 lines
8.0 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 BTPEER_H
#define BTPEER_H
#include <tqobject.h>
#include <tqdatetime.h>
#include <util/timer.h>
#include <interfaces/peerinterface.h>
#include <util/bitset.h>
#include "globals.h"
#include "peerid.h"
namespace net
{
class Address;
}
namespace mse
{
class RC4Encryptor;
class StreamSocket;
}
namespace bt
{
class Chunk;
class Peer;
class Request;
class Piece;
class PacketReader;
class PacketWriter;
class PeerDownloader;
class PeerUploader;
class PeerManager;
class UTPex;
/**
* @author Joris Guisson
* @brief Manages the connection with a peer
*
* This class manages a connection with a peer in the P2P network.
* It provides functions for sending packets. Packets it receives
* get relayed to the outside world using a bunch of signals.
*/
class Peer : public TQObject, public kt::PeerInterface
//,public Object
{
Q_OBJECT
TQ_OBJECT
public:
/**
* Constructor, set the socket.
* The socket is already opened.
* @param sock The socket
* @param peer_id The Peer's BitTorrent ID
* @param num_chunks The number of chunks in the file
* @param chunk_size Size of each chunk
* @param support Which extensions the peer supports
* @param local Wether or not it is a local peer
*/
Peer(mse::StreamSocket* sock,
const PeerID & peer_id,
Uint32 num_chunks,
Uint32 chunk_size,
Uint32 support,
bool local);
virtual ~Peer();
/// Get the peer's unique ID.
Uint32 getID() const {return id;}
/// Get the IP address of the Peer.
TQString getIPAddresss() const;
/// Get the port of the Peer
Uint16 getPort() const;
/// Get the address of the peer
net::Address getAddress() const;
/// See if the peer has been killed.
bool isKilled() const {return killed;}
/// Get the PacketWriter
PacketWriter & getPacketWriter() {return *pwriter;}
/// Is the Peer choked
bool isChoked() const {return choked;}
/// Is the Peer interested
bool isInterested() const {return interested;}
/// Are we interested in the Peer
bool areWeInterested() const {return am_interested;}
/// Are we choked for the Peer
bool areWeChoked() const {return am_choked;}
/// Are we being snubbed by the Peer
bool isSnubbed() const;
/// Get the upload rate in bytes per sec
Uint32 getUploadRate() const;
/// Get the download rate in bytes per sec
Uint32 getDownloadRate() const;
/// Get the Peer's BitSet
const BitSet & getBitSet() const {return pieces;}
/// Get the Peer's ID
const PeerID & getPeerID() const {return peer_id;}
/// Update the up- and down- speed and handle incoming packets
void update(PeerManager* pman);
/// Get the PeerDownloader.
PeerDownloader* getPeerDownloader() {return downloader;}
/// Get the PeerUploader.
PeerUploader* getPeerUploader() {return uploader;}
/**
* Send a chunk of data.
* @param data The data
* @param len The length
* @param proto Indicates wether the packed is data or a protocol message
* @return Number of bytes written
*/
Uint32 sendData(const Uint8* data,Uint32 len);
/**
* Reads data from the peer.
* @param buf The buffer to store the data
* @param len The maximum number of bytes to read
* @return The number of bytes read
*/
Uint32 readData(Uint8* buf,Uint32 len);
/// Get the number of bytes available to read.
Uint32 bytesAvailable() const;
/**
* See if all previously written data, has been sent.
*/
bool readyToSend() const;
/**
* Close the peers connection.
*/
void closeConnection();
/**
* Kill the Peer.
*/
void kill();
/**
* Get the time when this Peer was choked.
*/
TimeStamp getChokeTime() const {return time_choked;}
/**
* Get the time when this Peer was unchoked.
*/
TimeStamp getUnchokeTime() const {return time_unchoked;}
/**
* See if the peer is a seeder.
*/
bool isSeeder() const;
/// Get the time in milliseconds since the last time a piece was received.
Uint32 getTimeSinceLastPiece() const;
/// Get the time the peer connection was established.
const TQTime & getConnectTime() const {return connect_time;}
/**
* Get the percentual amount of data available from peer.
*/
float percentAvailable() const;
/// See if the peer supports DHT
bool isDHTSupported() const {return stats.dht_support;}
/// Set the ACA score
void setACAScore(double s);
/// Get the stats of the peer
virtual const Stats & getStats() const;
/// Choke the peer
void choke();
/**
* Emit the port packet signal.
*/
void emitPortPacket();
/**
* Emit the pex signal
*/
void emitPex(const TQByteArray & data);
/// Disable or enable pex
void setPexEnabled(bool on);
/**
* Set the peer's group IDs for traffic
* @param up_gid The upload gid
* @param down_gid The download gid
*/
void setGroupIDs(Uint32 up_gid,Uint32 down_gid);
private slots:
void dataWritten(int bytes);
signals:
/**
* The Peer has a Chunk.
* @param p The Peer
* @param index Index of Chunk
*/
void haveChunk(Peer* p,Uint32 index);
/**
* The Peer sent a request.
* @param req The Request
*/
void request(const Request & req);
/**
* The Peer sent a cancel.
* @param req The Request
*/
void canceled(const Request & req);
/**
* The Peer sent a piece of a Chunk.
* @param p The Piece
*/
void piece(const Piece & p);
/**
* Recieved a BitSet
* @param bs The BitSet
*/
void bitSetRecieved(const BitSet & bs);
/**
* Emitted when the peer is unchoked and interested changes value.
*/
void rerunChoker();
/**
* Got a port packet from this peer.
* @param ip The IP
* @param port The port
*/
void gotPortPacket(const TQString & ip,Uint16 port);
/**
* A Peer Exchange has been received, the TQByteArray contains the data.
*/
void pex(const TQByteArray & data);
private:
void packetReady(const Uint8* packet,Uint32 size);
void handleExtendedPacket(const Uint8* packet,Uint32 size);
private:
mse::StreamSocket* sock;
bool choked;
bool interested;
bool am_choked;
bool am_interested;
bool killed;
TimeStamp time_choked;
TimeStamp time_unchoked;
Uint32 id;
BitSet pieces;
PeerID peer_id;
Timer snub_timer;
PacketReader* preader;
PacketWriter* pwriter;
PeerDownloader* downloader;
PeerUploader* uploader;
mutable kt::PeerInterface::Stats stats;
TQTime connect_time;
UTPex* ut_pex;
bool pex_allowed;
Uint32 utorrent_pex_id;
friend class PacketWriter;
friend class PacketReader;
friend class PeerDownloader;
};
}
#endif