2006-07-27 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>

* src/PeerMessage.h
	(Piece.h): Included.
	(SharedHandle.h): Included.
	(invalidate): New variable.
	(uploading): New variable.
	(isInvalidate): New function.
	(isUploading): New function.
	(onPush): New function.
	(onChoked): New function.
	(onCanceled): New function.
	(onAbortPiece): New function.
	(PeerMessageHandle): New type definition.
	
	* src/PeerMessage.cc
	(PeerMessage): Added the initialization for invalidate and 
uploading.
	
	* src/CancelMessage.h
	(CancelMessage): Rewritten.

	* src/RejectMessage.h
	(RejectMessage): Rewritten.

	* src/Metalinker.h
	(operator=): Defined.
	
	* src/MetaEntry.h
	(operator=): Defined.

	* src/MetalinkResource.h
	(operator=): Defined.
	
	* src/AllowedFastMessage.h
	(AllowedFastMessage): Rewritten.

	* src/HandshakeMessage.h
	(HandshakeMessage): New function(overload).
	
	* src/HandshakeMessage.cc
	(HandshakeMessage): Rewritten.
	(init): New function.

	* src/HaveMessage.h
	(HaveMessage): Rewritten.
	
	* src/Time.h
	(operator=): Defined the function body here.
	* src/Time.cc
	(operator=): Removed.
	
	* src/SocketCore.h
	(operator==): Defined here.
	(operator!=): Defined here.
	(operator<): Defined here.
	* src/SocketCore.cc
	(operator==): Removed.
	(operator<): Removed.

	* src/BitfieldMan.h
	(operator=): Defined the function body here.
	* src/BitfieldMan.cc
	(operator=): Removed.

	* src/TorrentMan.h
	(deleteErrorPeer): Removed.
	(deleteUnusedPeer); New function.
	* src/TorrentMan.cc
	(addPeer): Call deleteUnusedPeer.
	(deleteErrorPeer): Removed.
	(deleteUnusedPeer): New function.

	* src/PeerAbstractCommand.h
	(setNoCheck): New function.
	(noCheck): New variable.
	* src/PeerAbstractCommand.cc
	(PeerAbstractCommand): Added the initialization of noCheck.
	(execute): Added a check for noCheck.
	(setNoCheck): New function.

	* src/Util.h
	(stdio.h): Included.
	* src/Util.cc
	(unistd.h): Included.

	* src/DefaultDiskWriter.cc
	(unistd.h): Included.

	* src/Peer.h
	(operator==): Defined the function body here.
	(operator!=): Defined the function body here.
	* src/Peer.cc
	(operator==): Removed.
	(operator!=): Removed.

	* src/Piece.h
	(Piece): Defined the function body here(copy constructor).
	(operator=): Defined the function body here.
	(operator==): Defined the function body here.
	* src/Piece.cc
	(Piece): Removed(copy constructor).
	(operator=): Removed.
	(operator==): Removed.
	
	* src/PeerMessageUtil.h
	(ChokeMessage.h): Removed.
	(UnchokeMessage.h): Removed.
	(InterestedMessage.h): Removed.
	(NotInterestedMessage.h): Removed.
	(HaveMessage.h): Removed.
	(BitfieldMessage.h): Removed.
	(RequestMessage.h): Removed.
	(CancelMessage.h): Removed.
	(PieceMessage.h): Removed.
	(HandshakeMessage.h): Removed.
	(KeepAliveMessage.h): Removed.
	(PortMessage.h): Removed.
	(HaveAllMessage.h): Removed.
	(HaveNoneMessage.h): Removed.
	(PeerConnection.h): Removed.
	(HandshakeMessage.h): Included.

	* src/BitfieldMessage.h
	(init): New function.
	(BitfieldMessage): Rewritten.
	(BitfieldMessage): New function(overload).

	* src/RequestSlot.h
	(operator=): Defined the function body here.
	(operator==): Defined the function body here.
	* src/RequestSlot.cc
	(operator=): Removed.
	(operator==): Removed.
	
	To remove the dependency on the PeerMessage subclass from
	PeerInteraction:

	* src/PeerMessageFactory.h: New class.
	* src/PeerMessageFactory.cc: New class.
	* src/SimplePeerMessage.cc
	(send): If invalidate is true then do nothing.
	* src/PeerInteractionCommand.cc
	(HandshakeMessage.h): Included.
	(KeepAliveMessage.h): Included.
	(ChokeMessage.h): Included.
	(UnchokeMessage.h): Included.
	(HaveMessage.h): Included.
	(executeInternal): Call setNoCheck().
	Removed setWriteCheckSocket(socket).
	* src/PeerInteraction.h
	(ChokeMessage.h): Removed.
	(UnchokeMessage.h): Removed.
	(InterestedMessage.h): Removed.
	(NotInterestedMessage.h): Removed.
	(HaveMessage.h): Removed.
	(BitfieldMessage.h): Removed.
	(RequestMessage.h): Removed.
	(CancelMessage.h): Removed.
	(PieceMessage.h): Removed.
	(HandshakeMessage.h): Removed.
	(KeepAliveMessage.h): Removed.
	(PortMessage.h): Removed.
	(HaveAllMessage.h): Removed.
	(HaveNoneMessage.h): Removed.
	(RejectMessage.h): Removed.
	(AllowedFastMessage.h): Removed.
	(SuggestPieceMessage.h): Removed.
	(PeerMessageFactory.h): Included.
	(PeerMessageHandle): Removed typedef of PeerMessageHandle.
	(HandshakeMessageHandle): Removed typedef of 
HandshakeMessageHandle.
	(PeerMessageFactory): New variable.
	(createPeerMessage): Removed.
	(createHandshakeMessage): Removed.
	(setPeerMessageCommonProperty): Removed.
	(addRequestSlot): New function.
	(receiveHandshake): Changed the return value type to 
PeerMessageHandle.
	(getPeerMessageFactory): New function.
	(createRequestMessage): Removed.
	(createCancelMessage): Removed.
	(createPieceMessage): Removed.
	(createHaveMessage): Removed.
	(createChokeMessage): Removed.
	(createUnchokeMessage): Removed.
	(createInterestedMessage): Removed.
	(createNotInterestedMessage): Removed.
	(createBitfieldMessage): Removed.
	(createKeepAliveMessage): Removed.
	(createHaveAllMessage): Removed.
	(createHaveNoneMessage): Removed.
	(createRejectMessage): Removed.
	(createAllowedFastMessage): Removed.	
	* src/PeerInteraction.cc
	(PeerInteraction): Allocate PeerMessageFactory here.
	(~PeerInteraction): Deallocate PeerMessageFactory here.
	(sendMessages): Use msg->isUploading() instead of msg->getId() 
==
	PieceMessage::ID.
	(addMessage): Simplified by using PeerMessage::onPush().
	(addRequestSlot): New function.
	(rejectAllPieceMessageInQueue): Simplified by using
	PeerMessage::onChoked().
	(rejectPieceMessageInQueue): Simplified by using
	PeerMessage::onCanceled().
	(abortPiece): Simplified by using PeerMessage::abortPiece().
	(receiveHandshake): Changed the return value type to 
PeerMessageHandle.
	(createHandshakeMessage): Removed.
	(createPeerMessage): Removed.
	(sendHandshake): Call 
PeerMessageFactory::createHandshakeMessage().
	(setPeerMessageCommonProperty): Removed.
	(createRequestMessage): Removed.
	(createCancelMessage): Removed.
	(createPieceMessage): Removed.
	(createHaveMessage): Removed.
	(createChokeMessage): Removed.
	(createUnchokeMessage): Removed.
	(createInterestedMessage): Removed.
	(createNotInterestedMessage): Removed.
	(createBitfieldMessage): Removed.
	(createKeepAliveMessage): Removed.
	(createHaveAllMessage): Removed.
	(createHaveNoneMessage): Removed.
	(createRejectMessage): Removed.
	(createAllowedFastMessage): Removed.
	* src/PieceMessage.h
	(createRejectMessage): New function.
	(PieceMessage): Rewritten.
	(onChoked): New function.
	(onCanceled): New function.
	* src/PieceMessage.cc
	(send): If invalidate is true then do nothing, just return.
	(createRejectMessage): New function.
	(onChoked): New function.
	(onCanceled): New function.
	* src/RequestMessage.h
	(RequestMessage): Rewritten.
	(onPush): New function.
	(onAbortPiece): New function.
	* src/RequestMessage.cc
	(onPush): New function.
	(onAbortPiece): New function.
	
	Update fd_set when a socket is added or deleted in order to 
improve
	performance:

	* src/DownloadEngine.h
	(rfdset): New variable.
	(wfdset): New variable.
	(updateFdSet): New function.
	* src/DownloadEngine.cc
	(SetDescriptor::operator()): Use SockCmdMap::value_type.
	(AccumulateActiveCommandUuid::operator()): Use 
SockCmdMap::value_type.
	(waitData): Copy rfdset and wfdset.
	(updateFdSet): New function.
	(addSocket): Call updateFdSet.
	(deleteSocket): Call updateFdSet.
pull/1/head
Tatsuhiro Tsujikawa 2006-07-28 14:06:47 +00:00
parent 793d9b75ce
commit ba4e5b776b
47 changed files with 1044 additions and 523 deletions

255
ChangeLog
View File

@ -1,3 +1,258 @@
2006-07-27 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
* src/PeerMessage.h
(Piece.h): Included.
(SharedHandle.h): Included.
(invalidate): New variable.
(uploading): New variable.
(isInvalidate): New function.
(isUploading): New function.
(onPush): New function.
(onChoked): New function.
(onCanceled): New function.
(onAbortPiece): New function.
(PeerMessageHandle): New type definition.
* src/PeerMessage.cc
(PeerMessage): Added the initialization for invalidate and uploading.
* src/CancelMessage.h
(CancelMessage): Rewritten.
* src/RejectMessage.h
(RejectMessage): Rewritten.
* src/Metalinker.h
(operator=): Defined.
* src/MetaEntry.h
(operator=): Defined.
* src/MetalinkResource.h
(operator=): Defined.
* src/AllowedFastMessage.h
(AllowedFastMessage): Rewritten.
* src/HandshakeMessage.h
(HandshakeMessage): New function(overload).
* src/HandshakeMessage.cc
(HandshakeMessage): Rewritten.
(init): New function.
* src/HaveMessage.h
(HaveMessage): Rewritten.
* src/Time.h
(operator=): Defined the function body here.
* src/Time.cc
(operator=): Removed.
* src/SocketCore.h
(operator==): Defined here.
(operator!=): Defined here.
(operator<): Defined here.
* src/SocketCore.cc
(operator==): Removed.
(operator<): Removed.
* src/BitfieldMan.h
(operator=): Defined the function body here.
* src/BitfieldMan.cc
(operator=): Removed.
* src/TorrentMan.h
(deleteErrorPeer): Removed.
(deleteUnusedPeer); New function.
* src/TorrentMan.cc
(addPeer): Call deleteUnusedPeer.
(deleteErrorPeer): Removed.
(deleteUnusedPeer): New function.
* src/PeerAbstractCommand.h
(setNoCheck): New function.
(noCheck): New variable.
* src/PeerAbstractCommand.cc
(PeerAbstractCommand): Added the initialization of noCheck.
(execute): Added a check for noCheck.
(setNoCheck): New function.
* src/Util.h
(stdio.h): Included.
* src/Util.cc
(unistd.h): Included.
* src/DefaultDiskWriter.cc
(unistd.h): Included.
* src/Peer.h
(operator==): Defined the function body here.
(operator!=): Defined the function body here.
* src/Peer.cc
(operator==): Removed.
(operator!=): Removed.
* src/Piece.h
(Piece): Defined the function body here(copy constructor).
(operator=): Defined the function body here.
(operator==): Defined the function body here.
* src/Piece.cc
(Piece): Removed(copy constructor).
(operator=): Removed.
(operator==): Removed.
* src/PeerMessageUtil.h
(ChokeMessage.h): Removed.
(UnchokeMessage.h): Removed.
(InterestedMessage.h): Removed.
(NotInterestedMessage.h): Removed.
(HaveMessage.h): Removed.
(BitfieldMessage.h): Removed.
(RequestMessage.h): Removed.
(CancelMessage.h): Removed.
(PieceMessage.h): Removed.
(HandshakeMessage.h): Removed.
(KeepAliveMessage.h): Removed.
(PortMessage.h): Removed.
(HaveAllMessage.h): Removed.
(HaveNoneMessage.h): Removed.
(PeerConnection.h): Removed.
(HandshakeMessage.h): Included.
* src/BitfieldMessage.h
(init): New function.
(BitfieldMessage): Rewritten.
(BitfieldMessage): New function(overload).
* src/RequestSlot.h
(operator=): Defined the function body here.
(operator==): Defined the function body here.
* src/RequestSlot.cc
(operator=): Removed.
(operator==): Removed.
To remove the dependency on the PeerMessage subclass from
PeerInteraction:
* src/PeerMessageFactory.h: New class.
* src/PeerMessageFactory.cc: New class.
* src/SimplePeerMessage.cc
(send): If invalidate is true then do nothing.
* src/PeerInteractionCommand.cc
(HandshakeMessage.h): Included.
(KeepAliveMessage.h): Included.
(ChokeMessage.h): Included.
(UnchokeMessage.h): Included.
(HaveMessage.h): Included.
(executeInternal): Call setNoCheck().
Removed setWriteCheckSocket(socket).
* src/PeerInteraction.h
(ChokeMessage.h): Removed.
(UnchokeMessage.h): Removed.
(InterestedMessage.h): Removed.
(NotInterestedMessage.h): Removed.
(HaveMessage.h): Removed.
(BitfieldMessage.h): Removed.
(RequestMessage.h): Removed.
(CancelMessage.h): Removed.
(PieceMessage.h): Removed.
(HandshakeMessage.h): Removed.
(KeepAliveMessage.h): Removed.
(PortMessage.h): Removed.
(HaveAllMessage.h): Removed.
(HaveNoneMessage.h): Removed.
(RejectMessage.h): Removed.
(AllowedFastMessage.h): Removed.
(SuggestPieceMessage.h): Removed.
(PeerMessageFactory.h): Included.
(PeerMessageHandle): Removed typedef of PeerMessageHandle.
(HandshakeMessageHandle): Removed typedef of HandshakeMessageHandle.
(PeerMessageFactory): New variable.
(createPeerMessage): Removed.
(createHandshakeMessage): Removed.
(setPeerMessageCommonProperty): Removed.
(addRequestSlot): New function.
(receiveHandshake): Changed the return value type to PeerMessageHandle.
(getPeerMessageFactory): New function.
(createRequestMessage): Removed.
(createCancelMessage): Removed.
(createPieceMessage): Removed.
(createHaveMessage): Removed.
(createChokeMessage): Removed.
(createUnchokeMessage): Removed.
(createInterestedMessage): Removed.
(createNotInterestedMessage): Removed.
(createBitfieldMessage): Removed.
(createKeepAliveMessage): Removed.
(createHaveAllMessage): Removed.
(createHaveNoneMessage): Removed.
(createRejectMessage): Removed.
(createAllowedFastMessage): Removed.
* src/PeerInteraction.cc
(PeerInteraction): Allocate PeerMessageFactory here.
(~PeerInteraction): Deallocate PeerMessageFactory here.
(sendMessages): Use msg->isUploading() instead of msg->getId() ==
PieceMessage::ID.
(addMessage): Simplified by using PeerMessage::onPush().
(addRequestSlot): New function.
(rejectAllPieceMessageInQueue): Simplified by using
PeerMessage::onChoked().
(rejectPieceMessageInQueue): Simplified by using
PeerMessage::onCanceled().
(abortPiece): Simplified by using PeerMessage::abortPiece().
(receiveHandshake): Changed the return value type to PeerMessageHandle.
(createHandshakeMessage): Removed.
(createPeerMessage): Removed.
(sendHandshake): Call PeerMessageFactory::createHandshakeMessage().
(setPeerMessageCommonProperty): Removed.
(createRequestMessage): Removed.
(createCancelMessage): Removed.
(createPieceMessage): Removed.
(createHaveMessage): Removed.
(createChokeMessage): Removed.
(createUnchokeMessage): Removed.
(createInterestedMessage): Removed.
(createNotInterestedMessage): Removed.
(createBitfieldMessage): Removed.
(createKeepAliveMessage): Removed.
(createHaveAllMessage): Removed.
(createHaveNoneMessage): Removed.
(createRejectMessage): Removed.
(createAllowedFastMessage): Removed.
* src/PieceMessage.h
(createRejectMessage): New function.
(PieceMessage): Rewritten.
(onChoked): New function.
(onCanceled): New function.
* src/PieceMessage.cc
(send): If invalidate is true then do nothing, just return.
(createRejectMessage): New function.
(onChoked): New function.
(onCanceled): New function.
* src/RequestMessage.h
(RequestMessage): Rewritten.
(onPush): New function.
(onAbortPiece): New function.
* src/RequestMessage.cc
(onPush): New function.
(onAbortPiece): New function.
Update fd_set when a socket is added or deleted in order to improve
performance:
* src/DownloadEngine.h
(rfdset): New variable.
(wfdset): New variable.
(updateFdSet): New function.
* src/DownloadEngine.cc
(SetDescriptor::operator()): Use SockCmdMap::value_type.
(AccumulateActiveCommandUuid::operator()): Use SockCmdMap::value_type.
(waitData): Copy rfdset and wfdset.
(updateFdSet): New function.
(addSocket): Call updateFdSet.
(deleteSocket): Call updateFdSet.
2006-07-21 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
To add the support for Metalink3.0 backward compatible links:

View File

@ -33,7 +33,10 @@ private:
protected:
virtual void onSendComplete();
public:
AllowedFastMessage():SimplePeerMessage(), index(0), pieces(0) {}
AllowedFastMessage(int index = 0)
:SimplePeerMessage(),
index(index),
pieces(0) {}
virtual ~AllowedFastMessage() {}

View File

@ -62,35 +62,6 @@ BitfieldMan::~BitfieldMan() {
}
}
BitfieldMan& BitfieldMan::operator=(const BitfieldMan& bitfieldMan) {
if(this != &bitfieldMan) {
blockLength = bitfieldMan.blockLength;
totalLength = bitfieldMan.totalLength;
if(bitfieldLength != bitfieldMan.bitfieldLength) {
delete [] bitfield;
delete [] useBitfield;
bitfield = new unsigned char[bitfieldMan.bitfieldLength];
useBitfield = new unsigned char[bitfieldMan.bitfieldLength];
}
blocks = bitfieldMan.blocks;
bitfieldLength = bitfieldMan.bitfieldLength;
memcpy(bitfield, bitfieldMan.bitfield, bitfieldLength);
memcpy(useBitfield, bitfieldMan.useBitfield, bitfieldLength);
filterEnabled = bitfieldMan.filterEnabled;
if(bitfieldLength != bitfieldMan.bitfieldLength) {
delete [] filterBitfield;
filterBitfield = 0;
}
if(bitfieldMan.filterBitfield) {
if(!filterBitfield) {
filterBitfield = new unsigned char[bitfieldLength];
}
memcpy(filterBitfield, bitfieldMan.filterBitfield, bitfieldLength);
}
}
return *this;
}
int BitfieldMan::countSetBit(const unsigned char* bitfield, int len) const {
int count = 0;
int size = sizeof(unsigned int);

View File

@ -48,7 +48,34 @@ public:
BitfieldMan(const BitfieldMan& bitfieldMan);
~BitfieldMan();
BitfieldMan& operator=(const BitfieldMan& bitfieldMan);
BitfieldMan& operator=(const BitfieldMan& bitfieldMan) {
if(this != &bitfieldMan) {
blockLength = bitfieldMan.blockLength;
totalLength = bitfieldMan.totalLength;
if(bitfieldLength != bitfieldMan.bitfieldLength) {
delete [] bitfield;
delete [] useBitfield;
bitfield = new unsigned char[bitfieldMan.bitfieldLength];
useBitfield = new unsigned char[bitfieldMan.bitfieldLength];
}
blocks = bitfieldMan.blocks;
bitfieldLength = bitfieldMan.bitfieldLength;
memcpy(bitfield, bitfieldMan.bitfield, bitfieldLength);
memcpy(useBitfield, bitfieldMan.useBitfield, bitfieldLength);
filterEnabled = bitfieldMan.filterEnabled;
if(bitfieldLength != bitfieldMan.bitfieldLength) {
delete [] filterBitfield;
filterBitfield = 0;
}
if(bitfieldMan.filterBitfield) {
if(!filterBitfield) {
filterBitfield = new unsigned char[bitfieldLength];
}
memcpy(filterBitfield, bitfieldMan.filterBitfield, bitfieldLength);
}
}
return *this;
}
int getBlockLength() const { return blockLength; }
int getLastBlockLength() const {

View File

@ -33,10 +33,28 @@ private:
char* msg;
int msgLength;
void init() {
bitfield = 0;
bitfieldLength = 0;
pieces = 0;
msg = 0;
msgLength = 0;
}
public:
BitfieldMessage():SimplePeerMessage(),
bitfield(NULL), bitfieldLength(0),
pieces(0), msg(NULL), msgLength(0) {}
BitfieldMessage()
:SimplePeerMessage()
{
init();
}
BitfieldMessage(const unsigned char* bitfield,
int bitfieldLength)
:SimplePeerMessage()
{
init();
setBitfield(bitfield, bitfieldLength);
}
virtual ~BitfieldMessage() {
if(bitfield != NULL) {

View File

@ -36,9 +36,13 @@ private:
char msg[17];
public:
CancelMessage():SimplePeerMessage(),
index(0), begin(0), length(0),
pieces(0), pieceLength(0) {}
CancelMessage(int index = 0, int begin = 0, int length = 0)
:SimplePeerMessage(),
index(index),
begin(begin),
length(length),
pieces(0),
pieceLength(0) {}
virtual ~CancelMessage() {}

View File

@ -22,6 +22,7 @@
#include "DefaultDiskWriter.h"
#include "DlAbortEx.h"
#include <errno.h>
#include <unistd.h>
DefaultDiskWriter::DefaultDiskWriter():AbstractDiskWriter(), totalLength(0) {}

View File

@ -119,7 +119,7 @@ public:
SetDescriptor(int* max_ptr, fd_set* fds_ptr)
:fds_ptr(fds_ptr), max_ptr(max_ptr) {}
void operator()(const pair<SocketHandle, CommandUuid>& pa) {
void operator()(const SockCmdMap::value_type& pa) {
int fd = pa.first->getSockfd();
FD_SET(fd, fds_ptr);
if(*max_ptr < fd) {
@ -137,7 +137,7 @@ public:
fd_set* fds_ptr)
:activeCommandUuids_ptr(activeCommandUuids_ptr), fds_ptr(fds_ptr) {}
void operator()(const pair<SocketHandle, CommandUuid>& pa) {
void operator()(const SockCmdMap::value_type& pa) {
if(FD_ISSET(pa.first->getSockfd(), fds_ptr)) {
activeCommandUuids_ptr->push_back(pa.second);
}
@ -151,15 +151,12 @@ void DownloadEngine::waitData(CommandUuids& activeCommandUuids) {
while(1) {
struct timeval tv;
FD_ZERO(&rfds);
FD_ZERO(&wfds);
int max = 0;
for_each(rsockmap.begin(), rsockmap.end(), SetDescriptor(&max, &rfds));
for_each(wsockmap.begin(), wsockmap.end(), SetDescriptor(&max, &wfds));
memcpy(&rfds, &rfdset, sizeof(fd_set));
memcpy(&wfds, &wfdset, sizeof(fd_set));
tv.tv_sec = 1;
tv.tv_usec = 0;
retval = select(max+1, &rfds, &wfds, NULL, &tv);
retval = select(fdmax+1, &rfds, &wfds, NULL, &tv);
if(retval != -1 || errno != EINTR) {
break;
}
@ -176,6 +173,14 @@ void DownloadEngine::waitData(CommandUuids& activeCommandUuids) {
}
}
void DownloadEngine::updateFdSet() {
fdmax = 0;
FD_ZERO(&rfdset);
FD_ZERO(&wfdset);
for_each(rsockmap.begin(), rsockmap.end(), SetDescriptor(&fdmax, &rfdset));
for_each(wsockmap.begin(), wsockmap.end(), SetDescriptor(&fdmax, &wfdset));
}
bool DownloadEngine::addSocket(SockCmdMap& sockmap,
const SocketHandle& socket,
const CommandUuid& commandUuid) {
@ -184,6 +189,7 @@ bool DownloadEngine::addSocket(SockCmdMap& sockmap,
if(itr == sockmap.end()) {
SockCmdMap::value_type vt(socket, commandUuid);
sockmap.insert(vt);
updateFdSet();
return true;
} else {
return false;
@ -199,6 +205,7 @@ bool DownloadEngine::deleteSocket(SockCmdMap& sockmap,
return false;
} else {
sockmap.erase(itr);
updateFdSet();
return true;
}
}

View File

@ -39,6 +39,9 @@ private:
void waitData(CommandUuids& activeCommandUuids);
SockCmdMap rsockmap;
SockCmdMap wsockmap;
fd_set rfdset;
fd_set wfdset;
int fdmax;
void shortSleep() const;
bool addSocket(SockCmdMap& sockmap, const SocketHandle& socket,
@ -64,6 +67,8 @@ public:
void cleanQueue();
void updateFdSet();
bool addSocketForReadCheck(const SocketHandle& socket,
const CommandUuid& commandUuid);
bool deleteSocketForReadCheck(const SocketHandle& socket,

View File

@ -25,6 +25,18 @@
#include "Util.h"
HandshakeMessage::HandshakeMessage() {
init();
}
HandshakeMessage::HandshakeMessage(const unsigned char* infoHash,
const char* peerId)
{
init();
memcpy(this->infoHash, infoHash, INFO_HASH_LENGTH);
memcpy(this->peerId, peerId, PEER_ID_LENGTH);
}
void HandshakeMessage::init() {
this->pstrlen = 19;
this->pstr = PSTR;
memset(this->reserved, 0, sizeof(this->reserved));

View File

@ -31,6 +31,7 @@
class HandshakeMessage : public SimplePeerMessage {
private:
char msg[HANDSHAKE_MESSAGE_LENGTH];
void init();
public:
char pstrlen;
string pstr;
@ -39,6 +40,7 @@ public:
char peerId[PEER_ID_LENGTH];
public:
HandshakeMessage();
HandshakeMessage(const unsigned char* infoHash, const char* peerId);
static HandshakeMessage* create(const char* data, int dataLength);

View File

@ -33,7 +33,10 @@ private:
protected:
virtual bool sendPredicate() const;
public:
HaveMessage():SimplePeerMessage(), index(0), pieces(0) {}
HaveMessage(int index = 0)
:SimplePeerMessage(),
index(index),
pieces(0) {}
virtual ~HaveMessage() {}

View File

@ -50,7 +50,8 @@ SRCS = Socket.h\
messageDigest.h\
LogFactory.cc LogFactory.h\
NullLogger.h\
Time.cc Time.h
Time.cc Time.h\
SharedHandle.h
if ENABLE_BITTORRENT
SRCS += MetaEntry.h\
@ -105,7 +106,7 @@ SRCS += MetaEntry.h\
AllowedFastMessage.cc AllowedFastMessage.h\
SuggestPieceMessage.cc SuggestPieceMessage.h\
SimplePeerMessage.cc SimplePeerMessage.h\
SharedHandle.h
PeerMessageFactory.cc PeerMessageFactory.h
endif # ENABLE_BITTORRENT
if ENABLE_METALINK
@ -120,7 +121,8 @@ noinst_LIBRARIES = libaria2c.a
libaria2c_a_SOURCES = $(SRCS)
aria2c_LDADD = libaria2c.a @LIBINTL@ @ALLOCA@ @LIBGNUTLS_LIBS@\
@LIBGCRYPT_LIBS@ @OPENSSL_LIBS@ @XML_LIBS@
#aria2c_LDFLAGS = -pg
AM_CPPFLAGS = -Wall\
-I../lib -I../intl -I$(top_srcdir)/intl\
@LIBGNUTLS_CFLAGS@ @LIBGCRYPT_CFLAGS@ @OPENSSL_CFLAGS@ @XML_CPPFLAGS@\
-D_FILE_OFFSET_BITS=64 -DLOCALEDIR=\"$(localedir)\" @DEFS@
-D_FILE_OFFSET_BITS=64 -DLOCALEDIR=\"$(localedir)\" @DEFS@# -pg

View File

@ -90,7 +90,7 @@ bin_PROGRAMS = aria2c$(EXEEXT)
@ENABLE_BITTORRENT_TRUE@ AllowedFastMessage.cc AllowedFastMessage.h\
@ENABLE_BITTORRENT_TRUE@ SuggestPieceMessage.cc SuggestPieceMessage.h\
@ENABLE_BITTORRENT_TRUE@ SimplePeerMessage.cc SimplePeerMessage.h\
@ENABLE_BITTORRENT_TRUE@ SharedHandle.h
@ENABLE_BITTORRENT_TRUE@ PeerMessageFactory.cc PeerMessageFactory.h
@ENABLE_METALINK_TRUE@am__append_2 = Metalinker.cc Metalinker.h\
@ENABLE_METALINK_TRUE@ MetalinkEntry.cc MetalinkEntry.h\
@ -154,12 +154,12 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
AbstractDiskWriter.h File.cc File.h Option.cc Option.h \
Base64.cc Base64.h CookieBox.cc CookieBox.h messageDigest.h \
LogFactory.cc LogFactory.h NullLogger.h Time.cc Time.h \
MetaEntry.h Data.cc Data.h Dictionary.cc Dictionary.h List.cc \
List.h MetaFileUtil.cc MetaFileUtil.h MetaEntryVisitor.h \
ShaVisitor.cc ShaVisitor.h TorrentMan.cc TorrentMan.h \
PeerConnection.cc PeerConnection.h PeerMessageUtil.cc \
PeerMessageUtil.h PeerAbstractCommand.cc PeerAbstractCommand.h \
PeerInitiateConnectionCommand.cc \
SharedHandle.h MetaEntry.h Data.cc Data.h Dictionary.cc \
Dictionary.h List.cc List.h MetaFileUtil.cc MetaFileUtil.h \
MetaEntryVisitor.h ShaVisitor.cc ShaVisitor.h TorrentMan.cc \
TorrentMan.h PeerConnection.cc PeerConnection.h \
PeerMessageUtil.cc PeerMessageUtil.h PeerAbstractCommand.cc \
PeerAbstractCommand.h PeerInitiateConnectionCommand.cc \
PeerInitiateConnectionCommand.h PeerInteractionCommand.cc \
PeerInteractionCommand.h Peer.cc Peer.h BitfieldMan.cc \
BitfieldMan.h TorrentDownloadEngine.cc TorrentDownloadEngine.h \
@ -187,9 +187,10 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
HaveNoneMessage.cc HaveNoneMessage.h RejectMessage.cc \
RejectMessage.h AllowedFastMessage.cc AllowedFastMessage.h \
SuggestPieceMessage.cc SuggestPieceMessage.h \
SimplePeerMessage.cc SimplePeerMessage.h SharedHandle.h \
Metalinker.cc Metalinker.h MetalinkEntry.cc MetalinkEntry.h \
MetalinkResource.cc MetalinkResource.h MetalinkProcessor.h \
SimplePeerMessage.cc SimplePeerMessage.h PeerMessageFactory.cc \
PeerMessageFactory.h Metalinker.cc Metalinker.h \
MetalinkEntry.cc MetalinkEntry.h MetalinkResource.cc \
MetalinkResource.h MetalinkProcessor.h \
Xml2MetalinkProcessor.cc Xml2MetalinkProcessor.h
@ENABLE_BITTORRENT_TRUE@am__objects_1 = Data.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ Dictionary.$(OBJEXT) List.$(OBJEXT) \
@ -236,7 +237,8 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
@ENABLE_BITTORRENT_TRUE@ RejectMessage.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ AllowedFastMessage.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ SuggestPieceMessage.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ SimplePeerMessage.$(OBJEXT)
@ENABLE_BITTORRENT_TRUE@ SimplePeerMessage.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ PeerMessageFactory.$(OBJEXT)
@ENABLE_METALINK_TRUE@am__objects_2 = Metalinker.$(OBJEXT) \
@ENABLE_METALINK_TRUE@ MetalinkEntry.$(OBJEXT) \
@ENABLE_METALINK_TRUE@ MetalinkResource.$(OBJEXT) \
@ -453,16 +455,17 @@ SRCS = Socket.h SocketCore.cc SocketCore.h Command.cc Command.h \
AbstractDiskWriter.h File.cc File.h Option.cc Option.h \
Base64.cc Base64.h CookieBox.cc CookieBox.h messageDigest.h \
LogFactory.cc LogFactory.h NullLogger.h Time.cc Time.h \
$(am__append_1) $(am__append_2)
SharedHandle.h $(am__append_1) $(am__append_2)
noinst_LIBRARIES = libaria2c.a
libaria2c_a_SOURCES = $(SRCS)
aria2c_LDADD = libaria2c.a @LIBINTL@ @ALLOCA@ @LIBGNUTLS_LIBS@\
@LIBGCRYPT_LIBS@ @OPENSSL_LIBS@ @XML_LIBS@
#aria2c_LDFLAGS = -pg
AM_CPPFLAGS = -Wall\
-I../lib -I../intl -I$(top_srcdir)/intl\
@LIBGNUTLS_CFLAGS@ @LIBGCRYPT_CFLAGS@ @OPENSSL_CFLAGS@ @XML_CPPFLAGS@\
-D_FILE_OFFSET_BITS=64 -DLOCALEDIR=\"$(localedir)\" @DEFS@
-D_FILE_OFFSET_BITS=64 -DLOCALEDIR=\"$(localedir)\" @DEFS@# -pg
all: all-am
@ -601,6 +604,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PeerInteractionCommand.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PeerListenCommand.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PeerMessage.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PeerMessageFactory.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PeerMessageUtil.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Piece.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PieceMessage.Po@am__quote@

View File

@ -43,7 +43,18 @@ public:
MetalinkEntry();
~MetalinkEntry();
MetalinkEntry& operator=(const MetalinkEntry& metalinkEntry);
MetalinkEntry& operator=(const MetalinkEntry& metalinkEntry) {
if(this != &metalinkEntry) {
this->filename = metalinkEntry.filename;
this->version = metalinkEntry.version;
this->language = metalinkEntry.language;
this->os = metalinkEntry.os;
this->size = metalinkEntry.size;
this->md5 = metalinkEntry.md5;
this->sha1 = metalinkEntry.sha1;
}
return *this;
}
bool check(const string& filename) const;

View File

@ -41,7 +41,15 @@ public:
MetalinkResource();
~MetalinkResource();
MetalinkResource& operator=(const MetalinkResource& metalinkResource);
MetalinkResource& operator=(const MetalinkResource& metalinkResource) {
if(this != &metalinkResource) {
this->url = metalinkResource.url;
this->type = metalinkResource.type;
this->location = metalinkResource.location;
this->preference = metalinkResource.preference;
}
return *this;
}
};
#endif // _D_METALINK_RESOURCE_H_

View File

@ -37,7 +37,12 @@ public:
Metalinker();
~Metalinker();
Metalinker& operator=(const Metalinker& metalinker);
Metalinker& operator=(const Metalinker& metalinker) {
if(this != &metalinker) {
this->entries = metalinker.entries;
}
return *this;
}
MetalinkEntry* queryEntry(const string& version, const string& language,
const string& os) const;

View File

@ -82,11 +82,3 @@ void Peer::setAllBitfield() {
void Peer::updateLatency(int latency) {
this->latency = (this->latency*20+latency*80)/200;
}
bool operator==(const Peer& p1, const Peer& p2) {
return p1.ipaddr == p2.ipaddr && p1.port == p2.port;
}
bool operator!=(const Peer& p1, const Peer& p2) {
return !(p1 == p2);
}

View File

@ -83,6 +83,14 @@ public:
}
}
bool operator==(const Peer& p) {
return ipaddr == p.ipaddr && port == p.port;
}
bool operator!=(const Peer& p) {
return !(*this == p);
}
void resetStatus();
void addDeltaUpload(int length) {
@ -149,9 +157,6 @@ public:
int getLatency() const { return latency; }
};
bool operator==(const Peer& p1, const Peer& p2);
bool operator!=(const Peer& p1, const Peer& p2);
typedef SharedHandle<Peer> PeerHandle;
#endif // _D_PEER_H_

View File

@ -31,7 +31,7 @@ PeerAbstractCommand::PeerAbstractCommand(int cuid, const PeerHandle& peer,
const SocketHandle& s)
:Command(cuid), e(e), socket(s), peer(peer),
checkSocketIsReadable(false), checkSocketIsWritable(false),
uploadLimitCheck(false), uploadLimit(0) {
uploadLimitCheck(false), uploadLimit(0), noCheck(false) {
setReadCheckSocket(socket);
timeout = e->option->getAsInt(PREF_TIMEOUT);
e->torrentMan->connections++;
@ -48,7 +48,8 @@ bool PeerAbstractCommand::execute() {
return true;
}
try {
if(uploadLimitCheck && (uploadLimit == 0 ||
if(noCheck ||
uploadLimitCheck && (uploadLimit == 0 ||
e->getUploadSpeed() <= uploadLimit*1024) ||
checkSocketIsReadable && readCheckTarget->isReadable(0) ||
checkSocketIsWritable && writeCheckTarget->isWritable(0)) {
@ -144,3 +145,7 @@ void PeerAbstractCommand::setUploadLimit(int uploadLimit) {
void PeerAbstractCommand::setUploadLimitCheck(bool check) {
this->uploadLimitCheck = check;
}
void PeerAbstractCommand::setNoCheck(bool check) {
this->noCheck = check;
}

View File

@ -46,6 +46,7 @@ protected:
void disableWriteCheckSocket();
void setUploadLimit(int uploadLimit);
void setUploadLimitCheck(bool check);
void setNoCheck(bool check);
private:
bool checkSocketIsReadable;
bool checkSocketIsWritable;
@ -53,6 +54,7 @@ private:
SocketHandle writeCheckTarget;
bool uploadLimitCheck;
int uploadLimit;
bool noCheck;
public:
PeerAbstractCommand(int cuid, const PeerHandle& peer,
TorrentDownloadEngine* e,

View File

@ -38,11 +38,13 @@ PeerInteraction::PeerInteraction(int cuid,
peer(peer),
quickReplied(false) {
peerConnection = new PeerConnection(cuid, socket, op);
peerMessageFactory = new PeerMessageFactory(cuid, this, peer);
logger = LogFactory::getInstance();
}
PeerInteraction::~PeerInteraction() {
delete peerConnection;
delete peerMessageFactory;
}
bool PeerInteraction::isSendingMessageInProgress() const {
@ -61,9 +63,7 @@ void PeerInteraction::sendMessages(int uploadSpeed) {
PeerMessageHandle msg = messageQueue.front();
messageQueue.pop_front();
if(uploadLimit != 0 && uploadLimit*1024 <= uploadSpeed &&
msg->getId() == PieceMessage::ID && !msg->isInProgress()) {
//!((PieceMessage*)msg)->isPendingCountMax()) {
//((PieceMessage*)msg)->incrementPendingCount();
msg->isUploading() && !msg->isInProgress()) {
tempQueue.push_back(msg);
} else {
msg->send();
@ -77,68 +77,26 @@ void PeerInteraction::sendMessages(int uploadSpeed) {
}
void PeerInteraction::addMessage(const PeerMessageHandle& peerMessage) {
peerMessage->onPush();
messageQueue.push_back(peerMessage);
if(peerMessage->getId() == RequestMessage::ID) {
RequestMessage* requestMessage = (RequestMessage*)peerMessage.get();
RequestSlot requestSlot(requestMessage->getIndex(),
requestMessage->getBegin(),
requestMessage->getLength(),
requestMessage->getBlockIndex());
requestSlots.push_back(requestSlot);
}
}
void PeerInteraction::addRequestSlot(const RequestSlot& requestSlot) {
requestSlots.push_back(requestSlot);
}
void PeerInteraction::rejectAllPieceMessageInQueue() {
MessageQueue tempQueue;
for(MessageQueue::iterator itr = messageQueue.begin();
itr != messageQueue.end();) {
// Don't delete piece message which is in the allowed fast set.
if((*itr)->getId() == PieceMessage::ID && !(*itr)->isInProgress()
&& !isInFastSet(((PieceMessage*)(*itr).get())->getIndex())) {
PieceMessage* pieceMessage = (PieceMessage*)(*itr).get();
logger->debug("CUID#%d - Reject piece message in queue because"
" peer has been choked. index=%d, begin=%d, length=%d",
cuid,
pieceMessage->getIndex(),
pieceMessage->getBegin(),
pieceMessage->getBlockLength());
if(peer->isFastExtensionEnabled()) {
tempQueue.push_back(createRejectMessage(pieceMessage->getIndex(),
pieceMessage->getBegin(),
pieceMessage->getBlockLength()));
}
itr = messageQueue.erase(itr);
} else {
itr++;
}
int size = messageQueue.size();
for(int i = 0; i < size; i++) {
messageQueue.at(i)->onChoked();
}
copy(tempQueue.begin(), tempQueue.end(), back_inserter(messageQueue));
}
void PeerInteraction::rejectPieceMessageInQueue(int index, int begin, int length) {
MessageQueue tempQueue;
for(MessageQueue::iterator itr = messageQueue.begin();
itr != messageQueue.end();) {
if((*itr)->getId() == PieceMessage::ID && !(*itr)->isInProgress()) {
PieceMessage* pieceMessage = (PieceMessage*)(*itr).get();
if(pieceMessage->getIndex() == index &&
pieceMessage->getBegin() == begin &&
pieceMessage->getBlockLength() == length) {
logger->debug("CUID#%d - Reject piece message in queue because cancel"
" message received. index=%d, begin=%d, length=%d",
cuid, index, begin, length);
itr = messageQueue.erase(itr);
if(peer->isFastExtensionEnabled()) {
tempQueue.push_back(createRejectMessage(index, begin, length));
}
} else {
itr++;
}
} else {
itr++;
}
int size = messageQueue.size();
for(int i = 0; i < size; i++) {
messageQueue.at(i)->onCanceled(index, begin, length);
}
copy(tempQueue.begin(), tempQueue.end(), back_inserter(messageQueue));
}
void PeerInteraction::onChoked() {
@ -162,15 +120,9 @@ void PeerInteraction::abortAllPieces() {
void PeerInteraction::abortPiece(Piece& piece) {
if(!Piece::isNull(piece)) {
for(MessageQueue::iterator itr = messageQueue.begin();
itr != messageQueue.end();) {
if((*itr)->getId() == RequestMessage::ID &&
!(*itr)->isInProgress() &&
((RequestMessage*)(*itr).get())->getIndex() == piece.getIndex()) {
itr = messageQueue.erase(itr);
} else {
itr++;
}
int size = messageQueue.size();
for(int i = 0; i < size; i++) {
messageQueue.at(i)->onAbortPiece(piece);
}
for(RequestSlots::iterator itr = requestSlots.begin();
itr != requestSlots.end();) {
@ -218,9 +170,9 @@ void PeerInteraction::checkRequestSlot() {
logger->debug("CUID#%d - Deleting request slot blockIndex=%d because"
" the block has been acquired.", cuid,
slot.getBlockIndex());
addMessage(createCancelMessage(slot.getIndex(),
slot.getBegin(),
slot.getLength()));
addMessage(peerMessageFactory->createCancelMessage(slot.getIndex(),
slot.getBegin(),
slot.getLength()));
itr = requestSlots.erase(itr);
} else {
itr++;
@ -264,7 +216,7 @@ int PeerInteraction::countRequestSlot() const {
return requestSlots.size();
}
HandshakeMessageHandle PeerInteraction::receiveHandshake(bool quickReply) {
PeerMessageHandle PeerInteraction::receiveHandshake(bool quickReply) {
char msg[HANDSHAKE_MESSAGE_LENGTH];
int msgLength = HANDSHAKE_MESSAGE_LENGTH;
bool retval = peerConnection->receiveHandshake(msg, msgLength);
@ -279,107 +231,27 @@ HandshakeMessageHandle PeerInteraction::receiveHandshake(bool quickReply) {
if(!retval) {
return NULL;
}
HandshakeMessageHandle handshakeMessage(createHandshakeMessage(msg, msgLength));
PeerMessageHandle handshakeMessage(peerMessageFactory->createHandshakeMessage(msg, msgLength));
handshakeMessage->check();
if(handshakeMessage->isFastExtensionSupported()) {
if(((HandshakeMessage*)handshakeMessage.get())->isFastExtensionSupported()) {
peer->setFastExtensionEnabled(true);
logger->info("CUID#%d - Fast extension enabled.", cuid);
}
return handshakeMessage;
}
HandshakeMessageHandle PeerInteraction::createHandshakeMessage(const char* msg, int msgLength) {
HandshakeMessage* message = HandshakeMessage::create(msg, msgLength);
setPeerMessageCommonProperty(message);
return message;
}
PeerMessageHandle PeerInteraction::receiveMessage() {
char msg[MAX_PAYLOAD_LEN];
int msgLength = 0;
if(!peerConnection->receiveMessage(msg, msgLength)) {
return NULL;
}
PeerMessageHandle peerMessage(createPeerMessage(msg, msgLength));
PeerMessageHandle peerMessage =
peerMessageFactory->createPeerMessage(msg, msgLength);
peerMessage->check();
return peerMessage;
}
PeerMessageHandle PeerInteraction::createPeerMessage(const char* msg, int msgLength) {
PeerMessage* peerMessage;
if(msgLength == 0) {
// keep-alive
peerMessage = new KeepAliveMessage();
} else {
int id = PeerMessageUtil::getId(msg);
switch(id) {
case ChokeMessage::ID:
peerMessage = ChokeMessage::create(msg, msgLength);
break;
case UnchokeMessage::ID:
peerMessage = UnchokeMessage::create(msg, msgLength);
break;
case InterestedMessage::ID:
peerMessage = InterestedMessage::create(msg, msgLength);
break;
case NotInterestedMessage::ID:
peerMessage = NotInterestedMessage::create(msg, msgLength);
break;
case HaveMessage::ID:
peerMessage = HaveMessage::create(msg, msgLength);
((HaveMessage*)peerMessage)->setPieces(torrentMan->pieces);
break;
case BitfieldMessage::ID:
peerMessage = BitfieldMessage::create(msg, msgLength);
((BitfieldMessage*)peerMessage)->setPieces(torrentMan->pieces);
break;
case RequestMessage::ID:
peerMessage = RequestMessage::create(msg, msgLength);
((RequestMessage*)peerMessage)->setPieces(torrentMan->pieces);
((RequestMessage*)peerMessage)->setPieceLength(torrentMan->getPieceLength(((RequestMessage*)peerMessage)->getIndex()));
break;
case CancelMessage::ID:
peerMessage = CancelMessage::create(msg, msgLength);
((CancelMessage*)peerMessage)->setPieces(torrentMan->pieces);
((CancelMessage*)peerMessage)->setPieceLength(torrentMan->getPieceLength(((CancelMessage*)peerMessage)->getIndex()));
break;
case PieceMessage::ID:
peerMessage = PieceMessage::create(msg, msgLength);
((PieceMessage*)peerMessage)->setPieces(torrentMan->pieces);
((PieceMessage*)peerMessage)->setPieceLength(torrentMan->getPieceLength(((PieceMessage*)peerMessage)->getIndex()));
break;
case PortMessage::ID:
peerMessage = PortMessage::create(msg, msgLength);
break;
case HaveAllMessage::ID:
peerMessage = HaveAllMessage::create(msg, msgLength);
break;
case HaveNoneMessage::ID:
peerMessage = HaveNoneMessage::create(msg, msgLength);
break;
case RejectMessage::ID:
peerMessage = RejectMessage::create(msg, msgLength);
((RejectMessage*)peerMessage)->setPieces(torrentMan->pieces);
((RejectMessage*)peerMessage)->setPieceLength(torrentMan->getPieceLength(((RejectMessage*)peerMessage)->getIndex()));
break;
case SuggestPieceMessage::ID:
peerMessage = SuggestPieceMessage::create(msg, msgLength);
((SuggestPieceMessage*)peerMessage)->setPieces(torrentMan->pieces);
break;
case AllowedFastMessage::ID:
peerMessage = AllowedFastMessage::create(msg, msgLength);
((AllowedFastMessage*)peerMessage)->setPieces(torrentMan->pieces);
break;
default:
throw new DlAbortEx("Invalid message id. id = %d", id);
}
}
setPeerMessageCommonProperty(peerMessage);
return peerMessage;
}
void PeerInteraction::syncPiece() {
for(Pieces::iterator itr = pieces.begin(); itr != pieces.end(); itr++) {
torrentMan->syncPiece(*itr);
@ -396,7 +268,7 @@ void PeerInteraction::getNewPieceAndSendInterest(int pieceNum) {
if(pieces.empty() && !torrentMan->hasMissingPiece(peer)) {
if(peer->amInterested) {
logger->debug("CUID#%d - Not interested in the peer", cuid);
addMessage(createNotInterestedMessage());
addMessage(peerMessageFactory->createNotInterestedMessage());
}
} else {
if(peer->peerChoking) {
@ -423,7 +295,7 @@ void PeerInteraction::getNewPieceAndSendInterest(int pieceNum) {
}
if(!peer->amInterested) {
logger->debug("CUID#%d - Interested in the peer", cuid);
addMessage(createInterestedMessage());
addMessage(peerMessageFactory->createInterestedMessage());
}
}
}
@ -466,7 +338,8 @@ void PeerInteraction::addRequests() {
bitr++) {
int blockIndex = *bitr;
if(!isInRequestSlot(piece.getIndex(), blockIndex)) {
addMessage(createRequestMessage(piece.getIndex(), blockIndex));
addMessage(peerMessageFactory->createRequestMessage(piece,
blockIndex));
count++;
}
}
@ -476,7 +349,8 @@ void PeerInteraction::addRequests() {
if(blockIndex == -1) {
break;
}
addMessage(createRequestMessage(piece.getIndex(), blockIndex));
addMessage(peerMessageFactory->createRequestMessage(piece,
blockIndex));
}
}
if(countRequestSlot() >= MAX_PENDING_REQUEST) {
@ -487,26 +361,25 @@ void PeerInteraction::addRequests() {
}
void PeerInteraction::sendHandshake() {
HandshakeMessage* handshake = new HandshakeMessage();
memcpy(handshake->infoHash, torrentMan->getInfoHash(), INFO_HASH_LENGTH);
memcpy(handshake->peerId, torrentMan->peerId.c_str(), PEER_ID_LENGTH);
setPeerMessageCommonProperty(handshake);
addMessage(handshake);
PeerMessageHandle handle =
peerMessageFactory->createHandshakeMessage(torrentMan->getInfoHash(),
torrentMan->peerId.c_str());
addMessage(handle);
sendMessages(0);
}
void PeerInteraction::sendBitfield() {
if(peer->isFastExtensionEnabled()) {
if(torrentMan->hasAllPieces()) {
addMessage(createHaveAllMessage());
addMessage(peerMessageFactory->createHaveAllMessage());
} else if(torrentMan->getDownloadLength() > 0) {
addMessage(createBitfieldMessage());
addMessage(peerMessageFactory->createBitfieldMessage());
} else {
addMessage(createHaveNoneMessage());
addMessage(peerMessageFactory->createHaveNoneMessage());
}
} else {
if(torrentMan->getDownloadLength() > 0) {
addMessage(createBitfieldMessage());
addMessage(peerMessageFactory->createBitfieldMessage());
}
}
sendMessages(0);
@ -518,7 +391,7 @@ void PeerInteraction::sendAllowedFast() {
torrentMan->pieces, ALLOWED_FAST_SET_SIZE);
for(Integers::const_iterator itr = fastSet.begin();
itr != fastSet.end(); itr++) {
addMessage(createAllowedFastMessage(*itr));
addMessage(peerMessageFactory->createAllowedFastMessage(*itr));
}
}
}
@ -550,111 +423,3 @@ void PeerInteraction::addFastSetIndex(int index) {
fastSet.push_back(index);
}
}
void PeerInteraction::setPeerMessageCommonProperty(PeerMessage* peerMessage) {
peerMessage->setPeer(peer);
peerMessage->setCuid(cuid);
peerMessage->setPeerInteraction(this);
}
RequestMessage* PeerInteraction::createRequestMessage(int index, int blockIndex) {
RequestMessage* msg = new RequestMessage();
Piece piece = getDownloadPiece(index);
msg->setIndex(piece.getIndex());
msg->setBegin(blockIndex*piece.getBlockLength());
msg->setLength(piece.getBlockLength(blockIndex));
msg->setBlockIndex(blockIndex);
setPeerMessageCommonProperty(msg);
return msg;
}
CancelMessage* PeerInteraction::createCancelMessage(int index, int begin, int length) {
CancelMessage* msg = new CancelMessage();
msg->setIndex(index);
msg->setBegin(begin);
msg->setLength(length);
setPeerMessageCommonProperty(msg);
return msg;
}
PieceMessage* PeerInteraction::createPieceMessage(int index, int begin, int length) {
PieceMessage* msg = new PieceMessage();
msg->setIndex(index);
msg->setBegin(begin);
msg->setBlockLength(length);
setPeerMessageCommonProperty(msg);
return msg;
}
HaveMessage* PeerInteraction::createHaveMessage(int index) {
HaveMessage* msg = new HaveMessage();
msg->setIndex(index);
setPeerMessageCommonProperty(msg);
return msg;
}
ChokeMessage* PeerInteraction::createChokeMessage() {
ChokeMessage* msg = new ChokeMessage();
setPeerMessageCommonProperty(msg);
return msg;
}
UnchokeMessage* PeerInteraction::createUnchokeMessage() {
UnchokeMessage* msg = new UnchokeMessage();
setPeerMessageCommonProperty(msg);
return msg;
}
InterestedMessage* PeerInteraction::createInterestedMessage() {
InterestedMessage* msg = new InterestedMessage();
setPeerMessageCommonProperty(msg);
return msg;
}
NotInterestedMessage* PeerInteraction::createNotInterestedMessage() {
NotInterestedMessage* msg = new NotInterestedMessage();
setPeerMessageCommonProperty(msg);
return msg;
}
BitfieldMessage* PeerInteraction::createBitfieldMessage() {
BitfieldMessage* msg = new BitfieldMessage();
msg->setBitfield(getTorrentMan()->getBitfield(),
getTorrentMan()->getBitfieldLength());
setPeerMessageCommonProperty(msg);
return msg;
}
KeepAliveMessage* PeerInteraction::createKeepAliveMessage() {
KeepAliveMessage* msg = new KeepAliveMessage();
setPeerMessageCommonProperty(msg);
return msg;
}
HaveAllMessage* PeerInteraction::createHaveAllMessage() {
HaveAllMessage* msg = new HaveAllMessage();
setPeerMessageCommonProperty(msg);
return msg;
}
HaveNoneMessage* PeerInteraction::createHaveNoneMessage() {
HaveNoneMessage* msg = new HaveNoneMessage();
setPeerMessageCommonProperty(msg);
return msg;
}
RejectMessage* PeerInteraction::createRejectMessage(int index, int begin, int length) {
RejectMessage* msg = new RejectMessage();
msg->setIndex(index);
msg->setBegin(begin);
msg->setLength(length);
setPeerMessageCommonProperty(msg);
return msg;
}
AllowedFastMessage* PeerInteraction::createAllowedFastMessage(int index) {
AllowedFastMessage* msg = new AllowedFastMessage();
msg->setIndex(index);
setPeerMessageCommonProperty(msg);
return msg;
}

View File

@ -24,31 +24,13 @@
#include "common.h"
#include "PeerConnection.h"
#include "ChokeMessage.h"
#include "UnchokeMessage.h"
#include "InterestedMessage.h"
#include "NotInterestedMessage.h"
#include "HaveMessage.h"
#include "BitfieldMessage.h"
#include "RequestMessage.h"
#include "CancelMessage.h"
#include "PieceMessage.h"
#include "HandshakeMessage.h"
#include "KeepAliveMessage.h"
#include "PortMessage.h"
#include "HaveAllMessage.h"
#include "HaveNoneMessage.h"
#include "RejectMessage.h"
#include "AllowedFastMessage.h"
#include "SuggestPieceMessage.h"
#include "RequestSlot.h"
#include "SharedHandle.h"
#include "PeerMessageFactory.h"
#define REQUEST_TIME_OUT 60
#define ALLOWED_FAST_SET_SIZE 10
typedef SharedHandle<PeerMessage> PeerMessageHandle;
typedef SharedHandle<HandshakeMessage> HandshakeMessageHandle;
typedef deque<RequestSlot> RequestSlots;
typedef deque<PeerMessageHandle> MessageQueue;
@ -63,15 +45,13 @@ private:
PeerConnection* peerConnection;
PeerHandle peer;
Pieces pieces;
PeerMessageFactory* peerMessageFactory;
// allowed fast piece indexes that local client has sent
Integers fastSet;
bool quickReplied;
const Logger* logger;
void getNewPieceAndSendInterest(int pieceNum);
PeerMessageHandle createPeerMessage(const char* msg, int msgLength);
HandshakeMessageHandle createHandshakeMessage(const char* msg, int msgLength);
void setPeerMessageCommonProperty(PeerMessage* peerMessage);
int countRequestSlot() const;
public:
PeerInteraction(int cuid,
@ -82,6 +62,7 @@ public:
~PeerInteraction();
void addMessage(const PeerMessageHandle& peerMessage);
void addRequestSlot(const RequestSlot& requestSlot);
void rejectPieceMessageInQueue(int index, int begin, int length);
void rejectAllPieceMessageInQueue();
void onChoked();
@ -120,22 +101,11 @@ public:
void sendAllowedFast();
PeerMessageHandle receiveMessage();
HandshakeMessageHandle receiveHandshake(bool quickReply = false);
PeerMessageHandle receiveHandshake(bool quickReply = false);
RequestMessage* createRequestMessage(int index, int blockIndex);
CancelMessage* createCancelMessage(int index, int begin, int length);
PieceMessage* createPieceMessage(int index, int begin, int length);
HaveMessage* createHaveMessage(int index);
ChokeMessage* createChokeMessage();
UnchokeMessage* createUnchokeMessage();
InterestedMessage* createInterestedMessage();
NotInterestedMessage* createNotInterestedMessage();
BitfieldMessage* createBitfieldMessage();
KeepAliveMessage* createKeepAliveMessage();
HaveAllMessage* createHaveAllMessage();
HaveNoneMessage* createHaveNoneMessage();
RejectMessage* createRejectMessage(int index, int begin, int length);
AllowedFastMessage* createAllowedFastMessage(int index);
const PeerMessageFactory* getPeerMessageFactory() const {
return peerMessageFactory;
}
};
#endif // _D_PEER_INTERACTION_H_

View File

@ -22,6 +22,11 @@
#include "PeerInteractionCommand.h"
#include "PeerInitiateConnectionCommand.h"
#include "PeerMessageUtil.h"
#include "HandshakeMessage.h"
#include "KeepAliveMessage.h"
#include "ChokeMessage.h"
#include "UnchokeMessage.h"
#include "HaveMessage.h"
#include "DlAbortEx.h"
#include "Util.h"
#include "message.h"
@ -62,6 +67,7 @@ bool PeerInteractionCommand::executeInternal() {
}
disableWriteCheckSocket();
setUploadLimitCheck(false);
setNoCheck(false);
switch(sequence) {
case INITIATOR_SEND_HANDSHAKE:
@ -75,12 +81,12 @@ bool PeerInteractionCommand::executeInternal() {
break;
}
}
HandshakeMessageHandle handshakeMessage =
PeerMessageHandle handshakeMessage =
peerInteraction->receiveHandshake();
if(handshakeMessage.get() == NULL) {
if(handshakeMessage.get() == 0) {
break;
}
peer->setPeerId(handshakeMessage->peerId);
peer->setPeerId(((HandshakeMessage*)handshakeMessage.get())->peerId);
logger->info(MSG_RECEIVE_PEER_MESSAGE, cuid,
peer->ipaddr.c_str(), peer->port,
handshakeMessage->toString().c_str());
@ -91,12 +97,12 @@ bool PeerInteractionCommand::executeInternal() {
break;
}
case RECEIVER_WAIT_HANDSHAKE: {
HandshakeMessageHandle handshakeMessage =
PeerMessageHandle handshakeMessage =
peerInteraction->receiveHandshake(true);
if(handshakeMessage.get() == NULL) {
if(handshakeMessage.get() == 0) {
break;
}
peer->setPeerId(handshakeMessage->peerId);
peer->setPeerId(((HandshakeMessage*)handshakeMessage.get())->peerId);
logger->info(MSG_RECEIVE_PEER_MESSAGE, cuid,
peer->ipaddr.c_str(), peer->port,
handshakeMessage->toString().c_str());
@ -121,10 +127,9 @@ bool PeerInteractionCommand::executeInternal() {
}
if(peerInteraction->countMessageInQueue() > 0) {
if(peerInteraction->isSendingMessageInProgress()) {
setWriteCheckSocket(socket);
} else {
setUploadLimitCheck(true);
}
setNoCheck(true);
}
e->commands.push_back(this);
return false;
@ -164,11 +169,13 @@ void PeerInteractionCommand::checkLongTimePeerChoking() {
void PeerInteractionCommand::decideChoking() {
if(peer->shouldBeChoking()) {
if(!peer->amChoking) {
peerInteraction->addMessage(peerInteraction->createChokeMessage());
peerInteraction->addMessage(peerInteraction->getPeerMessageFactory()->
createChokeMessage());
}
} else {
if(peer->amChoking) {
peerInteraction->addMessage(peerInteraction->createUnchokeMessage());
peerInteraction->addMessage(peerInteraction->getPeerMessageFactory()->
createUnchokeMessage());
}
}
}
@ -231,7 +238,8 @@ void PeerInteractionCommand::onAbort(Exception* ex) {
void PeerInteractionCommand::sendKeepAlive() {
if(keepAliveCheckPoint.elapsed(KEEP_ALIVE_INTERVAL)) {
if(peerInteraction->countMessageInQueue() == 0) {
peerInteraction->addMessage(peerInteraction->createKeepAliveMessage());
peerInteraction->addMessage(peerInteraction->getPeerMessageFactory()->
createKeepAliveMessage());
peerInteraction->sendMessages(e->getUploadSpeed());
}
keepAliveCheckPoint.reset();
@ -245,16 +253,20 @@ void PeerInteractionCommand::checkHave() {
if(indexes.size() >= 20) {
if(peer->isFastExtensionEnabled()) {
if(e->torrentMan->hasAllPieces()) {
peerInteraction->addMessage(peerInteraction->createHaveAllMessage());
peerInteraction->addMessage(peerInteraction->getPeerMessageFactory()->
createHaveAllMessage());
} else {
peerInteraction->addMessage(peerInteraction->createBitfieldMessage());
peerInteraction->addMessage(peerInteraction->getPeerMessageFactory()->
createBitfieldMessage());
}
} else {
peerInteraction->addMessage(peerInteraction->createBitfieldMessage());
peerInteraction->addMessage(peerInteraction->getPeerMessageFactory()->
createBitfieldMessage());
}
} else {
for(PieceIndexes::iterator itr = indexes.begin(); itr != indexes.end(); itr++) {
peerInteraction->addMessage(peerInteraction->createHaveMessage(*itr));
peerInteraction->addMessage(peerInteraction->getPeerMessageFactory()->
createHaveMessage(*itr));
}
}
}

View File

@ -22,6 +22,9 @@
#include "PeerMessage.h"
#include "LogFactory.h"
PeerMessage::PeerMessage():inProgress(false) {
PeerMessage::PeerMessage()
:inProgress(false),
invalidate(false),
uploading(false) {
logger = LogFactory::getInstance();
}

View File

@ -25,6 +25,8 @@
#include "common.h"
#include "Logger.h"
#include "Peer.h"
#include "Piece.h"
#include "SharedHandle.h"
#include <string>
class PeerInteraction;
@ -32,6 +34,8 @@ class PeerInteraction;
class PeerMessage {
protected:
bool inProgress;
bool invalidate;
bool uploading;
int cuid;
PeerHandle peer;
PeerInteraction* peerInteraction;
@ -42,6 +46,8 @@ public:
virtual ~PeerMessage() {}
bool isInProgress() const { return inProgress; }
bool isInvalidate() const { return invalidate; }
bool isUploading() const { return uploading; }
int getCuid() const { return cuid; }
void setCuid(int cuid) {
@ -61,6 +67,12 @@ public:
virtual void send() = 0;
virtual void check() const {}
virtual string toString() const = 0;
virtual void onPush() {}
virtual void onChoked() {}
virtual void onCanceled(int index, int begin, int blockLength) {}
virtual void onAbortPiece(const Piece& piece) {}
};
typedef SharedHandle<PeerMessage> PeerMessageHandle;
#endif // _D_PEER_MESSAGE_H_

268
src/PeerMessageFactory.cc Normal file
View File

@ -0,0 +1,268 @@
/* <!-- copyright */
/*
* aria2 - a simple utility for downloading files faster
*
* Copyright (C) 2006 Tatsuhiro Tsujikawa
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* copyright --> */
#include "PeerMessageFactory.h"
#include "PeerInteraction.h"
#include "PeerMessageUtil.h"
#include "ChokeMessage.h"
#include "UnchokeMessage.h"
#include "InterestedMessage.h"
#include "NotInterestedMessage.h"
#include "HaveMessage.h"
#include "BitfieldMessage.h"
#include "RequestMessage.h"
#include "CancelMessage.h"
#include "PieceMessage.h"
#include "HandshakeMessage.h"
#include "KeepAliveMessage.h"
#include "PortMessage.h"
#include "HaveAllMessage.h"
#include "HaveNoneMessage.h"
#include "RejectMessage.h"
#include "AllowedFastMessage.h"
#include "SuggestPieceMessage.h"
#include "RequestSlot.h"
#include "DlAbortEx.h"
PeerMessageFactory::PeerMessageFactory(int cuid,
PeerInteraction* peerInteraction,
const PeerHandle& peer)
:cuid(cuid),
peerInteraction(peerInteraction),
peer(peer) {}
PeerMessageFactory::~PeerMessageFactory() {}
PeerMessageHandle PeerMessageFactory::createPeerMessage(const char* msg, int msgLength) const {
PeerMessage* peerMessage;
if(msgLength == 0) {
// keep-alive
peerMessage = new KeepAliveMessage();
} else {
int id = PeerMessageUtil::getId(msg);
switch(id) {
case ChokeMessage::ID:
peerMessage = ChokeMessage::create(msg, msgLength);
break;
case UnchokeMessage::ID:
peerMessage = UnchokeMessage::create(msg, msgLength);
break;
case InterestedMessage::ID:
peerMessage = InterestedMessage::create(msg, msgLength);
break;
case NotInterestedMessage::ID:
peerMessage = NotInterestedMessage::create(msg, msgLength);
break;
case HaveMessage::ID:
peerMessage = HaveMessage::create(msg, msgLength);
((HaveMessage*)peerMessage)->setPieces(peerInteraction->getTorrentMan()->
pieces);
break;
case BitfieldMessage::ID:
peerMessage = BitfieldMessage::create(msg, msgLength);
((BitfieldMessage*)peerMessage)->setPieces(peerInteraction->
getTorrentMan()->pieces);
break;
case RequestMessage::ID:
peerMessage = RequestMessage::create(msg, msgLength);
((RequestMessage*)peerMessage)->setPieces(peerInteraction->
getTorrentMan()->pieces);
((RequestMessage*)peerMessage)->setPieceLength(peerInteraction->getTorrentMan()->getPieceLength(((RequestMessage*)peerMessage)->getIndex()));
break;
case CancelMessage::ID:
peerMessage = CancelMessage::create(msg, msgLength);
((CancelMessage*)peerMessage)->setPieces(peerInteraction->getTorrentMan()->pieces);
((CancelMessage*)peerMessage)->setPieceLength(peerInteraction->getTorrentMan()->getPieceLength(((CancelMessage*)peerMessage)->getIndex()));
break;
case PieceMessage::ID:
peerMessage = PieceMessage::create(msg, msgLength);
((PieceMessage*)peerMessage)->setPieces(peerInteraction->getTorrentMan()->pieces);
((PieceMessage*)peerMessage)->setPieceLength(peerInteraction->getTorrentMan()->getPieceLength(((PieceMessage*)peerMessage)->getIndex()));
break;
case PortMessage::ID:
peerMessage = PortMessage::create(msg, msgLength);
break;
case HaveAllMessage::ID:
peerMessage = HaveAllMessage::create(msg, msgLength);
break;
case HaveNoneMessage::ID:
peerMessage = HaveNoneMessage::create(msg, msgLength);
break;
case RejectMessage::ID:
peerMessage = RejectMessage::create(msg, msgLength);
((RejectMessage*)peerMessage)->setPieces(peerInteraction->getTorrentMan()->pieces);
((RejectMessage*)peerMessage)->setPieceLength(peerInteraction->getTorrentMan()->getPieceLength(((RejectMessage*)peerMessage)->getIndex()));
break;
case SuggestPieceMessage::ID:
peerMessage = SuggestPieceMessage::create(msg, msgLength);
((SuggestPieceMessage*)peerMessage)->setPieces(peerInteraction->getTorrentMan()->pieces);
break;
case AllowedFastMessage::ID:
peerMessage = AllowedFastMessage::create(msg, msgLength);
((AllowedFastMessage*)peerMessage)->setPieces(peerInteraction->getTorrentMan()->pieces);
break;
default:
throw new DlAbortEx("Invalid message id. id = %d", id);
}
}
PeerMessageHandle handle = PeerMessageHandle(peerMessage);
setPeerMessageCommonProperty(handle);
return handle;
}
PeerMessageHandle
PeerMessageFactory::createHandshakeMessage(const char* msg, int msgLength) const
{
PeerMessageHandle handle =
PeerMessageHandle(HandshakeMessage::create(msg, msgLength));
setPeerMessageCommonProperty(handle);
return handle;
}
PeerMessageHandle
PeerMessageFactory::createHandshakeMessage(const unsigned char* infoHash,
const char* peerId) const
{
PeerMessageHandle handle =
PeerMessageHandle(new HandshakeMessage(infoHash, peerId));
setPeerMessageCommonProperty(handle);
return handle;
}
void
PeerMessageFactory::setPeerMessageCommonProperty(PeerMessageHandle& peerMessage) const
{
peerMessage->setPeer(peer);
peerMessage->setCuid(cuid);
peerMessage->setPeerInteraction(peerInteraction);
}
PeerMessageHandle PeerMessageFactory::createRequestMessage(const Piece& piece,
int blockIndex) const {
PeerMessageHandle handle =
PeerMessageHandle(new RequestMessage(piece.getIndex(),
blockIndex*piece.getBlockLength(),
piece.getBlockLength(blockIndex),
blockIndex));
setPeerMessageCommonProperty(handle);
return handle;
}
PeerMessageHandle PeerMessageFactory::createCancelMessage(int index,
int begin,
int length) const {
PeerMessageHandle handle =
PeerMessageHandle(new CancelMessage(index, begin, length));
setPeerMessageCommonProperty(handle);
return handle;
}
PeerMessageHandle PeerMessageFactory::createPieceMessage(int index,
int begin,
int length) const {
PeerMessageHandle handle =
PeerMessageHandle(new PieceMessage(index, begin, length));
setPeerMessageCommonProperty(handle);
return handle;
}
PeerMessageHandle PeerMessageFactory::createHaveMessage(int index) const {
PeerMessageHandle handle =
PeerMessageHandle(new HaveMessage(index));
setPeerMessageCommonProperty(handle);
return handle;
}
PeerMessageHandle PeerMessageFactory::createChokeMessage() const {
PeerMessageHandle handle =
PeerMessageHandle(new ChokeMessage());
setPeerMessageCommonProperty(handle);
return handle;
}
PeerMessageHandle PeerMessageFactory::createUnchokeMessage() const {
PeerMessageHandle handle =
PeerMessageHandle(new UnchokeMessage());
setPeerMessageCommonProperty(handle);
return handle;
}
PeerMessageHandle PeerMessageFactory::createInterestedMessage() const {
PeerMessageHandle handle =
PeerMessageHandle(new InterestedMessage());
setPeerMessageCommonProperty(handle);
return handle;
}
PeerMessageHandle PeerMessageFactory::createNotInterestedMessage() const {
PeerMessageHandle handle =
PeerMessageHandle(new NotInterestedMessage());
setPeerMessageCommonProperty(handle);
return handle;
}
PeerMessageHandle PeerMessageFactory::createBitfieldMessage() const {
PeerMessageHandle handle =
PeerMessageHandle(new BitfieldMessage(peerInteraction->getTorrentMan()->
getBitfield(),
peerInteraction->getTorrentMan()->
getBitfieldLength()));
setPeerMessageCommonProperty(handle);
return handle;
}
PeerMessageHandle PeerMessageFactory::createKeepAliveMessage() const {
PeerMessageHandle handle =
PeerMessageHandle(new KeepAliveMessage());
setPeerMessageCommonProperty(handle);
return handle;
}
PeerMessageHandle PeerMessageFactory::createHaveAllMessage() const {
PeerMessageHandle handle =
PeerMessageHandle(new HaveAllMessage());
setPeerMessageCommonProperty(handle);
return handle;
}
PeerMessageHandle PeerMessageFactory::createHaveNoneMessage() const {
PeerMessageHandle handle =
PeerMessageHandle(new HaveNoneMessage());
setPeerMessageCommonProperty(handle);
return handle;
}
PeerMessageHandle PeerMessageFactory::createRejectMessage(int index,
int begin,
int length) const {
PeerMessageHandle handle =
PeerMessageHandle(new RejectMessage(index, begin, length));
setPeerMessageCommonProperty(handle);
return handle;
}
PeerMessageHandle PeerMessageFactory::createAllowedFastMessage(int index) const {
PeerMessageHandle handle =
PeerMessageHandle(new AllowedFastMessage(index));
setPeerMessageCommonProperty(handle);
return handle;
}

73
src/PeerMessageFactory.h Normal file
View File

@ -0,0 +1,73 @@
/* <!-- copyright */
/*
* aria2 - a simple utility for downloading files faster
*
* Copyright (C) 2006 Tatsuhiro Tsujikawa
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* copyright --> */
#ifndef _D_PEER_MESSAGE_FACTORY_H_
#define _D_PEER_MESSAGE_FACTORY_H_
#include "common.h"
#include "PeerMessage.h"
#include "HandshakeMessage.h"
class PeerInteraction;
class PeerMessageFactory {
private:
int cuid;
PeerInteraction* peerInteraction;
PeerHandle peer;
void setPeerMessageCommonProperty(PeerMessageHandle& peerMessage) const;
public:
PeerMessageFactory(int cuid,
PeerInteraction* peerInteraction,
const PeerHandle& peer);
~PeerMessageFactory();
PeerMessageHandle
createPeerMessage(const char* msg, int msgLength) const;
PeerMessageHandle
createHandshakeMessage(const char* msg,
int msgLength) const;
PeerMessageHandle
createHandshakeMessage(const unsigned char* infoHash,
const char* peerId) const;
PeerMessageHandle createRequestMessage(const Piece& piece,
int blockIndex) const;
PeerMessageHandle createCancelMessage(int index, int begin, int length) const;
PeerMessageHandle createPieceMessage(int index, int begin, int length) const;
PeerMessageHandle createHaveMessage(int index) const;
PeerMessageHandle createChokeMessage() const;
PeerMessageHandle createUnchokeMessage() const;
PeerMessageHandle createInterestedMessage() const;
PeerMessageHandle createNotInterestedMessage() const;
PeerMessageHandle createBitfieldMessage() const;
PeerMessageHandle createKeepAliveMessage() const;
PeerMessageHandle createHaveAllMessage() const;
PeerMessageHandle createHaveNoneMessage() const;
PeerMessageHandle createRejectMessage(int index, int begin, int length) const;
PeerMessageHandle createAllowedFastMessage(int index) const;
};
#endif // _D_PEER_MESSAGE_FACTORY_H_

View File

@ -22,22 +22,8 @@
#ifndef _D_PEER_MESSAGE_UTIL_H_
#define _D_PEER_MESSAGE_UTIL_H_
#include "ChokeMessage.h"
#include "UnchokeMessage.h"
#include "InterestedMessage.h"
#include "NotInterestedMessage.h"
#include "HaveMessage.h"
#include "BitfieldMessage.h"
#include "RequestMessage.h"
#include "CancelMessage.h"
#include "PieceMessage.h"
#include "HandshakeMessage.h"
#include "KeepAliveMessage.h"
#include "PortMessage.h"
#include "HaveAllMessage.h"
#include "HaveNoneMessage.h"
#include "PeerConnection.h"
#include "common.h"
#include "HandshakeMessage.h"
#define MAX_BLOCK_LENGTH (128*1024)

View File

@ -23,36 +23,6 @@
Piece Piece::nullPiece;
Piece::Piece(const Piece& piece) {
index = piece.index;
length = piece.length;
if(piece.bitfield == NULL) {
bitfield = NULL;
} else {
bitfield = new BitfieldMan(*piece.bitfield);
}
}
Piece& Piece::operator=(const Piece& piece) {
if(this != &piece) {
index = piece.index;
length = piece.length;
if(bitfield != NULL) {
delete bitfield;
}
if(piece.bitfield == NULL) {
bitfield = NULL;
} else {
bitfield = new BitfieldMan(*piece.bitfield);
}
}
return *this;
}
bool Piece::operator==(const Piece& piece) const {
return index == piece.index;
}
void Piece::completeBlock(int blockIndex) {
bitfield->setBit(blockIndex);
bitfield->unsetUseBit(blockIndex);

View File

@ -37,13 +37,40 @@ public:
Piece(int index, int length):index(index), length(length) {
bitfield = new BitfieldMan(BLOCK_LENGTH, length);
}
Piece(const Piece& piece);
Piece(const Piece& piece) {
index = piece.index;
length = piece.length;
if(piece.bitfield == NULL) {
bitfield = NULL;
} else {
bitfield = new BitfieldMan(*piece.bitfield);
}
}
~Piece() {
delete bitfield;
}
Piece& operator=(const Piece& piece);
bool operator==(const Piece& piece) const;
Piece& operator=(const Piece& piece) {
if(this != &piece) {
index = piece.index;
length = piece.length;
if(bitfield != NULL) {
delete bitfield;
}
if(piece.bitfield == NULL) {
bitfield = NULL;
} else {
bitfield = new BitfieldMan(*piece.bitfield);
}
}
return *this;
}
bool operator==(const Piece& piece) const {
return index == piece.index;
}
int getMissingUnusedBlockIndex() const;
int getMissingBlockIndex() const;

View File

@ -109,6 +109,9 @@ int PieceMessage::getMessageHeaderLength() {
}
void PieceMessage::send() {
if(invalidate) {
return;
}
TorrentMan* torrentMan = peerInteraction->getTorrentMan();
PeerConnection* peerConnection = peerInteraction->getPeerConnection();
if(!headerSent) {
@ -227,3 +230,49 @@ void PieceMessage::erasePieceOnDisk(const Piece& piece) {
}
}
PeerMessageHandle PieceMessage::createRejectMessage(int index,
int begin,
int blockLength) const {
return peerInteraction->getPeerMessageFactory()->
createRejectMessage(index,
begin,
blockLength);
}
void PieceMessage::onChoked() {
if(!invalidate &&
!inProgress &&
!peerInteraction->isInFastSet(index)) {
logger->debug("CUID#%d - Reject piece message in queue because"
" the peer has been choked. index=%d, begin=%d, length=%d",
cuid,
index,
begin,
blockLength);
if(peer->isFastExtensionEnabled()) {
peerInteraction->addMessage(createRejectMessage(index,
begin,
blockLength));
}
invalidate = true;
}
}
void PieceMessage::onCanceled(int index, int begin, int blockLength) {
if(!invalidate &&
!inProgress &&
this->index == index &&
this->begin == begin &&
this->blockLength == blockLength) {
logger->debug("CUID#%d - Reject piece message in queue because cancel"
" message received. index=%d, begin=%d, length=%d",
cuid, index, begin, blockLength);
if(peer->isFastExtensionEnabled()) {
peerInteraction->addMessage(createRejectMessage(index,
begin,
blockLength));
}
invalidate = true;
}
}

View File

@ -45,12 +45,22 @@ private:
void onGotWrongPiece(Piece& piece);
void erasePieceOnDisk(const Piece& piece);
int sendPieceData(long long int offset, int length) const;
PeerMessageHandle createRejectMessage(int index, int begin, int blockLength) const;
public:
PieceMessage():PeerMessage(),
index(0), begin(0), block(NULL), blockLength(0),
leftDataLength(0), headerSent(false),
pendingCount(0),
pieces(0), pieceLength(0) {}
PieceMessage(int index = 0, int begin = 0, int blockLength = 0)
:PeerMessage(),
index(index),
begin(begin),
block(0),
blockLength(blockLength),
leftDataLength(0),
headerSent(false),
pendingCount(0),
pieces(0),
pieceLength(0)
{
uploading = true;
}
virtual ~PieceMessage() {
if(block != NULL) {
@ -93,6 +103,8 @@ public:
virtual void send();
virtual void check() const;
virtual string toString() const;
virtual void onChoked();
virtual void onCanceled(int index, int begin, int blockLength);
};
#endif // _D_PIECE_MESSAGE_H_

View File

@ -36,9 +36,13 @@ private:
char msg[17];
public:
RejectMessage():SimplePeerMessage(),
index(0), begin(0), length(0),
pieces(0), pieceLength(0) {}
RejectMessage(int index = 0, int begin = 0, int length = 0)
:SimplePeerMessage(),
index(index),
begin(begin),
length(length),
pieces(0),
pieceLength(0) {}
virtual ~RejectMessage() {}

View File

@ -46,10 +46,12 @@ void RequestMessage::receivedAction() {
if(torrentMan->hasPiece(index) &&
(!peer->amChoking ||
peer->amChoking && peerInteraction->isInFastSet(index))) {
peerInteraction->addMessage(peerInteraction->createPieceMessage(index, begin, length));
peerInteraction->addMessage(peerInteraction->getPeerMessageFactory()->
createPieceMessage(index, begin, length));
} else {
if(peer->isFastExtensionEnabled()) {
peerInteraction->addMessage(peerInteraction->createRejectMessage(index, begin, length));
peerInteraction->addMessage(peerInteraction->getPeerMessageFactory()->
createRejectMessage(index, begin, length));
}
}
}
@ -87,3 +89,16 @@ string RequestMessage::toString() const {
return "request index="+Util::itos(index)+", begin="+Util::itos(begin)+
", length="+Util::itos(length);
}
void RequestMessage::onPush() {
RequestSlot requestSlot(index, begin, length, blockIndex);
peerInteraction->addRequestSlot(requestSlot);
}
void RequestMessage::onAbortPiece(const Piece& piece) {
if(!invalidate &&
!inProgress &&
this->index == piece.getIndex()) {
invalidate = true;
}
}

View File

@ -37,9 +37,16 @@ private:
char msg[17];
public:
RequestMessage():SimplePeerMessage(),
index(0), begin(0), length(0), blockIndex(0),
pieces(0), pieceLength(0) {}
RequestMessage(int index = 0, int begin = 0, int length = 0,
int blockIndex = 0)
:SimplePeerMessage(),
index(index),
begin(begin),
length(length),
blockIndex(blockIndex),
pieces(0),
pieceLength(0) {}
virtual ~RequestMessage() {}
enum ID_t {
@ -73,6 +80,8 @@ public:
virtual int getMessageLength();
virtual void check() const;
virtual string toString() const;
virtual void onPush();
virtual void onAbortPiece(const Piece& piece);
};
#endif // _D_REQUEST_MESSAGE_H_

View File

@ -29,13 +29,6 @@ RequestSlot::RequestSlot(const RequestSlot& requestSlot) {
copy(requestSlot);
}
RequestSlot& RequestSlot::operator=(const RequestSlot& requestSlot) {
if(this != &requestSlot) {
copy(requestSlot);
}
return *this;
}
void RequestSlot::copy(const RequestSlot& requestSlot) {
index = requestSlot.index;
begin = requestSlot.begin;
@ -62,9 +55,3 @@ bool RequestSlot::isNull(const RequestSlot& requestSlot) {
return requestSlot.index == 0 && requestSlot.begin == 0&&
requestSlot.length == 0;
}
bool RequestSlot::operator==(const RequestSlot& requestSlot) const {
return index == requestSlot.index &&
begin == requestSlot.begin &&
length == requestSlot.length;
}

View File

@ -38,15 +38,24 @@ public:
RequestSlot(const RequestSlot& requestSlot);
~RequestSlot() {}
RequestSlot& operator=(const RequestSlot& requestSlot);
RequestSlot& operator=(const RequestSlot& requestSlot) {
if(this != &requestSlot) {
copy(requestSlot);
}
return *this;
}
bool operator==(const RequestSlot& requestSlot) const {
return index == requestSlot.index &&
begin == requestSlot.begin &&
length == requestSlot.length;
}
void setDispatchedTime();
bool isTimeout(int timeoutSec) const;
int getLatencyInMillis() const;
bool operator==(const RequestSlot& requestSlot) const;
int getIndex() const { return index; }
void setIndex(int index) { this->index = index; }
int getBegin() const { return begin; }

View File

@ -28,6 +28,9 @@ SimplePeerMessage::SimplePeerMessage():leftDataLength(0) {}
SimplePeerMessage::~SimplePeerMessage() {}
void SimplePeerMessage::send() {
if(invalidate) {
return;
}
if(sendPredicate() || inProgress) {
const char* msg = getMessage();
int msgLength = getMessageLength();

View File

@ -455,15 +455,3 @@ void SocketCore::initiateSecureConnection() {
}
#endif // HAVE_LIBGNUTLS
}
bool operator==(const SocketCore& s1, const SocketCore& s2) {
return s1.sockfd == s2.sockfd;
}
bool operator!=(const SocketCore& s1, const SocketCore& s2) {
return s1.sockfd != s2.sockfd;
}
bool operator<(const SocketCore& s1, const SocketCore& s2) {
return s1.sockfd < s2.sockfd;
}

View File

@ -182,5 +182,18 @@ public:
* connection must be established before calling this method.
*/
void initiateSecureConnection() ;
bool operator==(const SocketCore& s) {
return sockfd == s.sockfd;
}
bool operator!=(const SocketCore& s) {
return !(*this == s);
}
bool operator<(const SocketCore& s) {
return sockfd < s.sockfd;
}
};
#endif // _D_SOCKET_CORE_H_

View File

@ -32,13 +32,6 @@ Time::Time(const Time& time) {
Time::~Time() {}
Time& Time::operator=(const Time& time) {
if(this != &time) {
tv = time.tv;
}
return *this;
}
void Time::reset() {
gettimeofday(&tv, 0);
}

View File

@ -35,7 +35,13 @@ public:
// this object was created.
Time();
Time(const Time& time);
Time& operator=(const Time& time);
Time& operator=(const Time& time) {
if(this != &time) {
tv = time.tv;
}
return *this;
}
~Time();

View File

@ -82,7 +82,7 @@ void TorrentMan::updatePeers(const Peers& peers) {
bool TorrentMan::addPeer(const PeerHandle& peer) {
if(peers.size() >= MAX_PEER_LIST_SIZE) {
deleteErrorPeer();
deleteUnusedPeer(peers.size()-MAX_PEER_LIST_SIZE+15);
}
Peers::iterator itr = find(peers.begin(), peers.end(), peer);
if(itr == peers.end()) {
@ -117,11 +117,13 @@ bool TorrentMan::isPeerAvailable() const {
return getPeer() != nullPeer;
}
void TorrentMan::deleteErrorPeer() {
for(Peers::iterator itr = peers.begin(); itr != peers.end();) {
void TorrentMan::deleteUnusedPeer(int delSize) {
for(Peers::iterator itr = peers.begin();
itr != peers.end() && delSize > 0;) {
const PeerHandle& p = *itr;
if(p->error > 0 && p->cuid == 0) {
if(p->cuid == 0) {
itr = peers.erase(itr);
delSize--;
} else {
itr++;
}
@ -656,18 +658,19 @@ void TorrentMan::advertisePiece(int cuid, int index) {
haves.push_front(entry);
};
PieceIndexes TorrentMan::getAdvertisedPieceIndexes(int myCuid,
const Time& lastCheckTime) const {
PieceIndexes indexes;
for(Haves::const_iterator itr = haves.begin(); itr != haves.end(); itr++) {
const Haves::value_type& have = *itr;
if(have.cuid == myCuid) {
continue;
}
if(lastCheckTime.isNewer(have.registeredTime)) {
break;
}
indexes.push_back(have.index);
PieceIndexes
TorrentMan::getAdvertisedPieceIndexes(int myCuid,
const Time& lastCheckTime) const {
PieceIndexes indexes;
for(Haves::const_iterator itr = haves.begin(); itr != haves.end(); itr++) {
const Haves::value_type& have = *itr;
if(have.cuid == myCuid) {
continue;
}
return indexes;
if(lastCheckTime.isNewer(have.registeredTime)) {
break;
}
indexes.push_back(have.index);
}
return indexes;
}

View File

@ -138,7 +138,7 @@ public:
const Peers& getPeers() const { return peers; }
PeerHandle getPeer() const;
bool isPeerAvailable() const;
void deleteErrorPeer();
void deleteUnusedPeer(int delSize);
bool hasMissingPiece(const PeerHandle& peer) const;
int getMissingPieceIndex(const PeerHandle& peer) const;

View File

@ -31,6 +31,7 @@
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
string Util::itos(int value, bool comma) {
string str = llitos(value, comma);

View File

@ -30,6 +30,7 @@
#include <utility>
#include <deque>
#include <sys/time.h>
#include <stdio.h>
using namespace std;