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> 2006-07-21 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
To add the support for Metalink3.0 backward compatible links: To add the support for Metalink3.0 backward compatible links:

View File

@ -33,7 +33,10 @@ private:
protected: protected:
virtual void onSendComplete(); virtual void onSendComplete();
public: public:
AllowedFastMessage():SimplePeerMessage(), index(0), pieces(0) {} AllowedFastMessage(int index = 0)
:SimplePeerMessage(),
index(index),
pieces(0) {}
virtual ~AllowedFastMessage() {} 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 BitfieldMan::countSetBit(const unsigned char* bitfield, int len) const {
int count = 0; int count = 0;
int size = sizeof(unsigned int); int size = sizeof(unsigned int);

View File

@ -48,7 +48,34 @@ public:
BitfieldMan(const BitfieldMan& bitfieldMan); BitfieldMan(const BitfieldMan& 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 getBlockLength() const { return blockLength; }
int getLastBlockLength() const { int getLastBlockLength() const {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -25,6 +25,18 @@
#include "Util.h" #include "Util.h"
HandshakeMessage::HandshakeMessage() { 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->pstrlen = 19;
this->pstr = PSTR; this->pstr = PSTR;
memset(this->reserved, 0, sizeof(this->reserved)); memset(this->reserved, 0, sizeof(this->reserved));

View File

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

View File

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

View File

@ -50,7 +50,8 @@ SRCS = Socket.h\
messageDigest.h\ messageDigest.h\
LogFactory.cc LogFactory.h\ LogFactory.cc LogFactory.h\
NullLogger.h\ NullLogger.h\
Time.cc Time.h Time.cc Time.h\
SharedHandle.h
if ENABLE_BITTORRENT if ENABLE_BITTORRENT
SRCS += MetaEntry.h\ SRCS += MetaEntry.h\
@ -105,7 +106,7 @@ SRCS += MetaEntry.h\
AllowedFastMessage.cc AllowedFastMessage.h\ AllowedFastMessage.cc AllowedFastMessage.h\
SuggestPieceMessage.cc SuggestPieceMessage.h\ SuggestPieceMessage.cc SuggestPieceMessage.h\
SimplePeerMessage.cc SimplePeerMessage.h\ SimplePeerMessage.cc SimplePeerMessage.h\
SharedHandle.h PeerMessageFactory.cc PeerMessageFactory.h
endif # ENABLE_BITTORRENT endif # ENABLE_BITTORRENT
if ENABLE_METALINK if ENABLE_METALINK
@ -120,7 +121,8 @@ noinst_LIBRARIES = libaria2c.a
libaria2c_a_SOURCES = $(SRCS) libaria2c_a_SOURCES = $(SRCS)
aria2c_LDADD = libaria2c.a @LIBINTL@ @ALLOCA@ @LIBGNUTLS_LIBS@\ aria2c_LDADD = libaria2c.a @LIBINTL@ @ALLOCA@ @LIBGNUTLS_LIBS@\
@LIBGCRYPT_LIBS@ @OPENSSL_LIBS@ @XML_LIBS@ @LIBGCRYPT_LIBS@ @OPENSSL_LIBS@ @XML_LIBS@
#aria2c_LDFLAGS = -pg
AM_CPPFLAGS = -Wall\ AM_CPPFLAGS = -Wall\
-I../lib -I../intl -I$(top_srcdir)/intl\ -I../lib -I../intl -I$(top_srcdir)/intl\
@LIBGNUTLS_CFLAGS@ @LIBGCRYPT_CFLAGS@ @OPENSSL_CFLAGS@ @XML_CPPFLAGS@\ @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@ AllowedFastMessage.cc AllowedFastMessage.h\
@ENABLE_BITTORRENT_TRUE@ SuggestPieceMessage.cc SuggestPieceMessage.h\ @ENABLE_BITTORRENT_TRUE@ SuggestPieceMessage.cc SuggestPieceMessage.h\
@ENABLE_BITTORRENT_TRUE@ SimplePeerMessage.cc SimplePeerMessage.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@am__append_2 = Metalinker.cc Metalinker.h\
@ENABLE_METALINK_TRUE@ MetalinkEntry.cc MetalinkEntry.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 \ AbstractDiskWriter.h File.cc File.h Option.cc Option.h \
Base64.cc Base64.h CookieBox.cc CookieBox.h messageDigest.h \ Base64.cc Base64.h CookieBox.cc CookieBox.h messageDigest.h \
LogFactory.cc LogFactory.h NullLogger.h Time.cc Time.h \ LogFactory.cc LogFactory.h NullLogger.h Time.cc Time.h \
MetaEntry.h Data.cc Data.h Dictionary.cc Dictionary.h List.cc \ SharedHandle.h MetaEntry.h Data.cc Data.h Dictionary.cc \
List.h MetaFileUtil.cc MetaFileUtil.h MetaEntryVisitor.h \ Dictionary.h List.cc List.h MetaFileUtil.cc MetaFileUtil.h \
ShaVisitor.cc ShaVisitor.h TorrentMan.cc TorrentMan.h \ MetaEntryVisitor.h ShaVisitor.cc ShaVisitor.h TorrentMan.cc \
PeerConnection.cc PeerConnection.h PeerMessageUtil.cc \ TorrentMan.h PeerConnection.cc PeerConnection.h \
PeerMessageUtil.h PeerAbstractCommand.cc PeerAbstractCommand.h \ PeerMessageUtil.cc PeerMessageUtil.h PeerAbstractCommand.cc \
PeerInitiateConnectionCommand.cc \ PeerAbstractCommand.h PeerInitiateConnectionCommand.cc \
PeerInitiateConnectionCommand.h PeerInteractionCommand.cc \ PeerInitiateConnectionCommand.h PeerInteractionCommand.cc \
PeerInteractionCommand.h Peer.cc Peer.h BitfieldMan.cc \ PeerInteractionCommand.h Peer.cc Peer.h BitfieldMan.cc \
BitfieldMan.h TorrentDownloadEngine.cc TorrentDownloadEngine.h \ 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 \ HaveNoneMessage.cc HaveNoneMessage.h RejectMessage.cc \
RejectMessage.h AllowedFastMessage.cc AllowedFastMessage.h \ RejectMessage.h AllowedFastMessage.cc AllowedFastMessage.h \
SuggestPieceMessage.cc SuggestPieceMessage.h \ SuggestPieceMessage.cc SuggestPieceMessage.h \
SimplePeerMessage.cc SimplePeerMessage.h SharedHandle.h \ SimplePeerMessage.cc SimplePeerMessage.h PeerMessageFactory.cc \
Metalinker.cc Metalinker.h MetalinkEntry.cc MetalinkEntry.h \ PeerMessageFactory.h Metalinker.cc Metalinker.h \
MetalinkResource.cc MetalinkResource.h MetalinkProcessor.h \ MetalinkEntry.cc MetalinkEntry.h MetalinkResource.cc \
MetalinkResource.h MetalinkProcessor.h \
Xml2MetalinkProcessor.cc Xml2MetalinkProcessor.h Xml2MetalinkProcessor.cc Xml2MetalinkProcessor.h
@ENABLE_BITTORRENT_TRUE@am__objects_1 = Data.$(OBJEXT) \ @ENABLE_BITTORRENT_TRUE@am__objects_1 = Data.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ Dictionary.$(OBJEXT) List.$(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@ RejectMessage.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ AllowedFastMessage.$(OBJEXT) \ @ENABLE_BITTORRENT_TRUE@ AllowedFastMessage.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ SuggestPieceMessage.$(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@am__objects_2 = Metalinker.$(OBJEXT) \
@ENABLE_METALINK_TRUE@ MetalinkEntry.$(OBJEXT) \ @ENABLE_METALINK_TRUE@ MetalinkEntry.$(OBJEXT) \
@ENABLE_METALINK_TRUE@ MetalinkResource.$(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 \ AbstractDiskWriter.h File.cc File.h Option.cc Option.h \
Base64.cc Base64.h CookieBox.cc CookieBox.h messageDigest.h \ Base64.cc Base64.h CookieBox.cc CookieBox.h messageDigest.h \
LogFactory.cc LogFactory.h NullLogger.h Time.cc Time.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 noinst_LIBRARIES = libaria2c.a
libaria2c_a_SOURCES = $(SRCS) libaria2c_a_SOURCES = $(SRCS)
aria2c_LDADD = libaria2c.a @LIBINTL@ @ALLOCA@ @LIBGNUTLS_LIBS@\ aria2c_LDADD = libaria2c.a @LIBINTL@ @ALLOCA@ @LIBGNUTLS_LIBS@\
@LIBGCRYPT_LIBS@ @OPENSSL_LIBS@ @XML_LIBS@ @LIBGCRYPT_LIBS@ @OPENSSL_LIBS@ @XML_LIBS@
#aria2c_LDFLAGS = -pg
AM_CPPFLAGS = -Wall\ AM_CPPFLAGS = -Wall\
-I../lib -I../intl -I$(top_srcdir)/intl\ -I../lib -I../intl -I$(top_srcdir)/intl\
@LIBGNUTLS_CFLAGS@ @LIBGCRYPT_CFLAGS@ @OPENSSL_CFLAGS@ @XML_CPPFLAGS@\ @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 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)/PeerInteractionCommand.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PeerListenCommand.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)/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)/PeerMessageUtil.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Piece.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@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PieceMessage.Po@am__quote@

View File

@ -43,7 +43,18 @@ public:
MetalinkEntry(); MetalinkEntry();
~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; bool check(const string& filename) const;

View File

@ -41,7 +41,15 @@ public:
MetalinkResource(); MetalinkResource();
~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_ #endif // _D_METALINK_RESOURCE_H_

View File

@ -37,7 +37,12 @@ public:
Metalinker(); Metalinker();
~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, MetalinkEntry* queryEntry(const string& version, const string& language,
const string& os) const; const string& os) const;

View File

@ -82,11 +82,3 @@ void Peer::setAllBitfield() {
void Peer::updateLatency(int latency) { void Peer::updateLatency(int latency) {
this->latency = (this->latency*20+latency*80)/200; 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 resetStatus();
void addDeltaUpload(int length) { void addDeltaUpload(int length) {
@ -149,9 +157,6 @@ public:
int getLatency() const { return latency; } 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; typedef SharedHandle<Peer> PeerHandle;
#endif // _D_PEER_H_ #endif // _D_PEER_H_

View File

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

View File

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

View File

@ -38,11 +38,13 @@ PeerInteraction::PeerInteraction(int cuid,
peer(peer), peer(peer),
quickReplied(false) { quickReplied(false) {
peerConnection = new PeerConnection(cuid, socket, op); peerConnection = new PeerConnection(cuid, socket, op);
peerMessageFactory = new PeerMessageFactory(cuid, this, peer);
logger = LogFactory::getInstance(); logger = LogFactory::getInstance();
} }
PeerInteraction::~PeerInteraction() { PeerInteraction::~PeerInteraction() {
delete peerConnection; delete peerConnection;
delete peerMessageFactory;
} }
bool PeerInteraction::isSendingMessageInProgress() const { bool PeerInteraction::isSendingMessageInProgress() const {
@ -61,9 +63,7 @@ void PeerInteraction::sendMessages(int uploadSpeed) {
PeerMessageHandle msg = messageQueue.front(); PeerMessageHandle msg = messageQueue.front();
messageQueue.pop_front(); messageQueue.pop_front();
if(uploadLimit != 0 && uploadLimit*1024 <= uploadSpeed && if(uploadLimit != 0 && uploadLimit*1024 <= uploadSpeed &&
msg->getId() == PieceMessage::ID && !msg->isInProgress()) { msg->isUploading() && !msg->isInProgress()) {
//!((PieceMessage*)msg)->isPendingCountMax()) {
//((PieceMessage*)msg)->incrementPendingCount();
tempQueue.push_back(msg); tempQueue.push_back(msg);
} else { } else {
msg->send(); msg->send();
@ -77,68 +77,26 @@ void PeerInteraction::sendMessages(int uploadSpeed) {
} }
void PeerInteraction::addMessage(const PeerMessageHandle& peerMessage) { void PeerInteraction::addMessage(const PeerMessageHandle& peerMessage) {
peerMessage->onPush();
messageQueue.push_back(peerMessage); 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() { void PeerInteraction::rejectAllPieceMessageInQueue() {
MessageQueue tempQueue; int size = messageQueue.size();
for(MessageQueue::iterator itr = messageQueue.begin(); for(int i = 0; i < size; i++) {
itr != messageQueue.end();) { messageQueue.at(i)->onChoked();
// 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++;
}
}
copy(tempQueue.begin(), tempQueue.end(), back_inserter(messageQueue));
} }
void PeerInteraction::rejectPieceMessageInQueue(int index, int begin, int length) { void PeerInteraction::rejectPieceMessageInQueue(int index, int begin, int length) {
MessageQueue tempQueue; int size = messageQueue.size();
for(MessageQueue::iterator itr = messageQueue.begin(); for(int i = 0; i < size; i++) {
itr != messageQueue.end();) { messageQueue.at(i)->onCanceled(index, begin, length);
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++;
}
}
copy(tempQueue.begin(), tempQueue.end(), back_inserter(messageQueue));
} }
void PeerInteraction::onChoked() { void PeerInteraction::onChoked() {
@ -162,15 +120,9 @@ void PeerInteraction::abortAllPieces() {
void PeerInteraction::abortPiece(Piece& piece) { void PeerInteraction::abortPiece(Piece& piece) {
if(!Piece::isNull(piece)) { if(!Piece::isNull(piece)) {
for(MessageQueue::iterator itr = messageQueue.begin(); int size = messageQueue.size();
itr != messageQueue.end();) { for(int i = 0; i < size; i++) {
if((*itr)->getId() == RequestMessage::ID && messageQueue.at(i)->onAbortPiece(piece);
!(*itr)->isInProgress() &&
((RequestMessage*)(*itr).get())->getIndex() == piece.getIndex()) {
itr = messageQueue.erase(itr);
} else {
itr++;
}
} }
for(RequestSlots::iterator itr = requestSlots.begin(); for(RequestSlots::iterator itr = requestSlots.begin();
itr != requestSlots.end();) { itr != requestSlots.end();) {
@ -218,7 +170,7 @@ void PeerInteraction::checkRequestSlot() {
logger->debug("CUID#%d - Deleting request slot blockIndex=%d because" logger->debug("CUID#%d - Deleting request slot blockIndex=%d because"
" the block has been acquired.", cuid, " the block has been acquired.", cuid,
slot.getBlockIndex()); slot.getBlockIndex());
addMessage(createCancelMessage(slot.getIndex(), addMessage(peerMessageFactory->createCancelMessage(slot.getIndex(),
slot.getBegin(), slot.getBegin(),
slot.getLength())); slot.getLength()));
itr = requestSlots.erase(itr); itr = requestSlots.erase(itr);
@ -264,7 +216,7 @@ int PeerInteraction::countRequestSlot() const {
return requestSlots.size(); return requestSlots.size();
} }
HandshakeMessageHandle PeerInteraction::receiveHandshake(bool quickReply) { PeerMessageHandle PeerInteraction::receiveHandshake(bool quickReply) {
char msg[HANDSHAKE_MESSAGE_LENGTH]; char msg[HANDSHAKE_MESSAGE_LENGTH];
int msgLength = HANDSHAKE_MESSAGE_LENGTH; int msgLength = HANDSHAKE_MESSAGE_LENGTH;
bool retval = peerConnection->receiveHandshake(msg, msgLength); bool retval = peerConnection->receiveHandshake(msg, msgLength);
@ -279,107 +231,27 @@ HandshakeMessageHandle PeerInteraction::receiveHandshake(bool quickReply) {
if(!retval) { if(!retval) {
return NULL; return NULL;
} }
HandshakeMessageHandle handshakeMessage(createHandshakeMessage(msg, msgLength)); PeerMessageHandle handshakeMessage(peerMessageFactory->createHandshakeMessage(msg, msgLength));
handshakeMessage->check(); handshakeMessage->check();
if(handshakeMessage->isFastExtensionSupported()) { if(((HandshakeMessage*)handshakeMessage.get())->isFastExtensionSupported()) {
peer->setFastExtensionEnabled(true); peer->setFastExtensionEnabled(true);
logger->info("CUID#%d - Fast extension enabled.", cuid); logger->info("CUID#%d - Fast extension enabled.", cuid);
} }
return handshakeMessage; return handshakeMessage;
} }
HandshakeMessageHandle PeerInteraction::createHandshakeMessage(const char* msg, int msgLength) {
HandshakeMessage* message = HandshakeMessage::create(msg, msgLength);
setPeerMessageCommonProperty(message);
return message;
}
PeerMessageHandle PeerInteraction::receiveMessage() { PeerMessageHandle PeerInteraction::receiveMessage() {
char msg[MAX_PAYLOAD_LEN]; char msg[MAX_PAYLOAD_LEN];
int msgLength = 0; int msgLength = 0;
if(!peerConnection->receiveMessage(msg, msgLength)) { if(!peerConnection->receiveMessage(msg, msgLength)) {
return NULL; return NULL;
} }
PeerMessageHandle peerMessage(createPeerMessage(msg, msgLength)); PeerMessageHandle peerMessage =
peerMessageFactory->createPeerMessage(msg, msgLength);
peerMessage->check(); peerMessage->check();
return peerMessage; 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() { void PeerInteraction::syncPiece() {
for(Pieces::iterator itr = pieces.begin(); itr != pieces.end(); itr++) { for(Pieces::iterator itr = pieces.begin(); itr != pieces.end(); itr++) {
torrentMan->syncPiece(*itr); torrentMan->syncPiece(*itr);
@ -396,7 +268,7 @@ void PeerInteraction::getNewPieceAndSendInterest(int pieceNum) {
if(pieces.empty() && !torrentMan->hasMissingPiece(peer)) { if(pieces.empty() && !torrentMan->hasMissingPiece(peer)) {
if(peer->amInterested) { if(peer->amInterested) {
logger->debug("CUID#%d - Not interested in the peer", cuid); logger->debug("CUID#%d - Not interested in the peer", cuid);
addMessage(createNotInterestedMessage()); addMessage(peerMessageFactory->createNotInterestedMessage());
} }
} else { } else {
if(peer->peerChoking) { if(peer->peerChoking) {
@ -423,7 +295,7 @@ void PeerInteraction::getNewPieceAndSendInterest(int pieceNum) {
} }
if(!peer->amInterested) { if(!peer->amInterested) {
logger->debug("CUID#%d - Interested in the peer", cuid); logger->debug("CUID#%d - Interested in the peer", cuid);
addMessage(createInterestedMessage()); addMessage(peerMessageFactory->createInterestedMessage());
} }
} }
} }
@ -466,7 +338,8 @@ void PeerInteraction::addRequests() {
bitr++) { bitr++) {
int blockIndex = *bitr; int blockIndex = *bitr;
if(!isInRequestSlot(piece.getIndex(), blockIndex)) { if(!isInRequestSlot(piece.getIndex(), blockIndex)) {
addMessage(createRequestMessage(piece.getIndex(), blockIndex)); addMessage(peerMessageFactory->createRequestMessage(piece,
blockIndex));
count++; count++;
} }
} }
@ -476,7 +349,8 @@ void PeerInteraction::addRequests() {
if(blockIndex == -1) { if(blockIndex == -1) {
break; break;
} }
addMessage(createRequestMessage(piece.getIndex(), blockIndex)); addMessage(peerMessageFactory->createRequestMessage(piece,
blockIndex));
} }
} }
if(countRequestSlot() >= MAX_PENDING_REQUEST) { if(countRequestSlot() >= MAX_PENDING_REQUEST) {
@ -487,26 +361,25 @@ void PeerInteraction::addRequests() {
} }
void PeerInteraction::sendHandshake() { void PeerInteraction::sendHandshake() {
HandshakeMessage* handshake = new HandshakeMessage(); PeerMessageHandle handle =
memcpy(handshake->infoHash, torrentMan->getInfoHash(), INFO_HASH_LENGTH); peerMessageFactory->createHandshakeMessage(torrentMan->getInfoHash(),
memcpy(handshake->peerId, torrentMan->peerId.c_str(), PEER_ID_LENGTH); torrentMan->peerId.c_str());
setPeerMessageCommonProperty(handshake); addMessage(handle);
addMessage(handshake);
sendMessages(0); sendMessages(0);
} }
void PeerInteraction::sendBitfield() { void PeerInteraction::sendBitfield() {
if(peer->isFastExtensionEnabled()) { if(peer->isFastExtensionEnabled()) {
if(torrentMan->hasAllPieces()) { if(torrentMan->hasAllPieces()) {
addMessage(createHaveAllMessage()); addMessage(peerMessageFactory->createHaveAllMessage());
} else if(torrentMan->getDownloadLength() > 0) { } else if(torrentMan->getDownloadLength() > 0) {
addMessage(createBitfieldMessage()); addMessage(peerMessageFactory->createBitfieldMessage());
} else { } else {
addMessage(createHaveNoneMessage()); addMessage(peerMessageFactory->createHaveNoneMessage());
} }
} else { } else {
if(torrentMan->getDownloadLength() > 0) { if(torrentMan->getDownloadLength() > 0) {
addMessage(createBitfieldMessage()); addMessage(peerMessageFactory->createBitfieldMessage());
} }
} }
sendMessages(0); sendMessages(0);
@ -518,7 +391,7 @@ void PeerInteraction::sendAllowedFast() {
torrentMan->pieces, ALLOWED_FAST_SET_SIZE); torrentMan->pieces, ALLOWED_FAST_SET_SIZE);
for(Integers::const_iterator itr = fastSet.begin(); for(Integers::const_iterator itr = fastSet.begin();
itr != fastSet.end(); itr++) { itr != fastSet.end(); itr++) {
addMessage(createAllowedFastMessage(*itr)); addMessage(peerMessageFactory->createAllowedFastMessage(*itr));
} }
} }
} }
@ -550,111 +423,3 @@ void PeerInteraction::addFastSetIndex(int index) {
fastSet.push_back(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 "common.h"
#include "PeerConnection.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 "RequestSlot.h"
#include "SharedHandle.h" #include "SharedHandle.h"
#include "PeerMessageFactory.h"
#define REQUEST_TIME_OUT 60 #define REQUEST_TIME_OUT 60
#define ALLOWED_FAST_SET_SIZE 10 #define ALLOWED_FAST_SET_SIZE 10
typedef SharedHandle<PeerMessage> PeerMessageHandle;
typedef SharedHandle<HandshakeMessage> HandshakeMessageHandle;
typedef deque<RequestSlot> RequestSlots; typedef deque<RequestSlot> RequestSlots;
typedef deque<PeerMessageHandle> MessageQueue; typedef deque<PeerMessageHandle> MessageQueue;
@ -63,15 +45,13 @@ private:
PeerConnection* peerConnection; PeerConnection* peerConnection;
PeerHandle peer; PeerHandle peer;
Pieces pieces; Pieces pieces;
PeerMessageFactory* peerMessageFactory;
// allowed fast piece indexes that local client has sent // allowed fast piece indexes that local client has sent
Integers fastSet; Integers fastSet;
bool quickReplied; bool quickReplied;
const Logger* logger; const Logger* logger;
void getNewPieceAndSendInterest(int pieceNum); 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; int countRequestSlot() const;
public: public:
PeerInteraction(int cuid, PeerInteraction(int cuid,
@ -82,6 +62,7 @@ public:
~PeerInteraction(); ~PeerInteraction();
void addMessage(const PeerMessageHandle& peerMessage); void addMessage(const PeerMessageHandle& peerMessage);
void addRequestSlot(const RequestSlot& requestSlot);
void rejectPieceMessageInQueue(int index, int begin, int length); void rejectPieceMessageInQueue(int index, int begin, int length);
void rejectAllPieceMessageInQueue(); void rejectAllPieceMessageInQueue();
void onChoked(); void onChoked();
@ -120,22 +101,11 @@ public:
void sendAllowedFast(); void sendAllowedFast();
PeerMessageHandle receiveMessage(); PeerMessageHandle receiveMessage();
HandshakeMessageHandle receiveHandshake(bool quickReply = false); PeerMessageHandle receiveHandshake(bool quickReply = false);
RequestMessage* createRequestMessage(int index, int blockIndex); const PeerMessageFactory* getPeerMessageFactory() const {
CancelMessage* createCancelMessage(int index, int begin, int length); return peerMessageFactory;
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);
}; };
#endif // _D_PEER_INTERACTION_H_ #endif // _D_PEER_INTERACTION_H_

View File

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

View File

@ -25,6 +25,8 @@
#include "common.h" #include "common.h"
#include "Logger.h" #include "Logger.h"
#include "Peer.h" #include "Peer.h"
#include "Piece.h"
#include "SharedHandle.h"
#include <string> #include <string>
class PeerInteraction; class PeerInteraction;
@ -32,6 +34,8 @@ class PeerInteraction;
class PeerMessage { class PeerMessage {
protected: protected:
bool inProgress; bool inProgress;
bool invalidate;
bool uploading;
int cuid; int cuid;
PeerHandle peer; PeerHandle peer;
PeerInteraction* peerInteraction; PeerInteraction* peerInteraction;
@ -42,6 +46,8 @@ public:
virtual ~PeerMessage() {} virtual ~PeerMessage() {}
bool isInProgress() const { return inProgress; } bool isInProgress() const { return inProgress; }
bool isInvalidate() const { return invalidate; }
bool isUploading() const { return uploading; }
int getCuid() const { return cuid; } int getCuid() const { return cuid; }
void setCuid(int cuid) { void setCuid(int cuid) {
@ -61,6 +67,12 @@ public:
virtual void send() = 0; virtual void send() = 0;
virtual void check() const {} virtual void check() const {}
virtual string toString() const = 0; 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_ #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_ #ifndef _D_PEER_MESSAGE_UTIL_H_
#define _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 "common.h"
#include "HandshakeMessage.h"
#define MAX_BLOCK_LENGTH (128*1024) #define MAX_BLOCK_LENGTH (128*1024)

View File

@ -23,36 +23,6 @@
Piece Piece::nullPiece; 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) { void Piece::completeBlock(int blockIndex) {
bitfield->setBit(blockIndex); bitfield->setBit(blockIndex);
bitfield->unsetUseBit(blockIndex); bitfield->unsetUseBit(blockIndex);

View File

@ -37,13 +37,40 @@ public:
Piece(int index, int length):index(index), length(length) { Piece(int index, int length):index(index), length(length) {
bitfield = new BitfieldMan(BLOCK_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() { ~Piece() {
delete bitfield; delete bitfield;
} }
Piece& operator=(const Piece& piece); Piece& operator=(const Piece& piece) {
bool operator==(const Piece& piece) const; 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 getMissingUnusedBlockIndex() const;
int getMissingBlockIndex() const; int getMissingBlockIndex() const;

View File

@ -109,6 +109,9 @@ int PieceMessage::getMessageHeaderLength() {
} }
void PieceMessage::send() { void PieceMessage::send() {
if(invalidate) {
return;
}
TorrentMan* torrentMan = peerInteraction->getTorrentMan(); TorrentMan* torrentMan = peerInteraction->getTorrentMan();
PeerConnection* peerConnection = peerInteraction->getPeerConnection(); PeerConnection* peerConnection = peerInteraction->getPeerConnection();
if(!headerSent) { 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 onGotWrongPiece(Piece& piece);
void erasePieceOnDisk(const Piece& piece); void erasePieceOnDisk(const Piece& piece);
int sendPieceData(long long int offset, int length) const; int sendPieceData(long long int offset, int length) const;
PeerMessageHandle createRejectMessage(int index, int begin, int blockLength) const;
public: public:
PieceMessage():PeerMessage(), PieceMessage(int index = 0, int begin = 0, int blockLength = 0)
index(0), begin(0), block(NULL), blockLength(0), :PeerMessage(),
leftDataLength(0), headerSent(false), index(index),
begin(begin),
block(0),
blockLength(blockLength),
leftDataLength(0),
headerSent(false),
pendingCount(0), pendingCount(0),
pieces(0), pieceLength(0) {} pieces(0),
pieceLength(0)
{
uploading = true;
}
virtual ~PieceMessage() { virtual ~PieceMessage() {
if(block != NULL) { if(block != NULL) {
@ -93,6 +103,8 @@ public:
virtual void send(); virtual void send();
virtual void check() const; virtual void check() const;
virtual string toString() const; virtual string toString() const;
virtual void onChoked();
virtual void onCanceled(int index, int begin, int blockLength);
}; };
#endif // _D_PIECE_MESSAGE_H_ #endif // _D_PIECE_MESSAGE_H_

View File

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

View File

@ -46,10 +46,12 @@ void RequestMessage::receivedAction() {
if(torrentMan->hasPiece(index) && if(torrentMan->hasPiece(index) &&
(!peer->amChoking || (!peer->amChoking ||
peer->amChoking && peerInteraction->isInFastSet(index))) { peer->amChoking && peerInteraction->isInFastSet(index))) {
peerInteraction->addMessage(peerInteraction->createPieceMessage(index, begin, length)); peerInteraction->addMessage(peerInteraction->getPeerMessageFactory()->
createPieceMessage(index, begin, length));
} else { } else {
if(peer->isFastExtensionEnabled()) { 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)+ return "request index="+Util::itos(index)+", begin="+Util::itos(begin)+
", length="+Util::itos(length); ", 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]; char msg[17];
public: public:
RequestMessage():SimplePeerMessage(), RequestMessage(int index = 0, int begin = 0, int length = 0,
index(0), begin(0), length(0), blockIndex(0), int blockIndex = 0)
pieces(0), pieceLength(0) {} :SimplePeerMessage(),
index(index),
begin(begin),
length(length),
blockIndex(blockIndex),
pieces(0),
pieceLength(0) {}
virtual ~RequestMessage() {} virtual ~RequestMessage() {}
enum ID_t { enum ID_t {
@ -73,6 +80,8 @@ public:
virtual int getMessageLength(); virtual int getMessageLength();
virtual void check() const; virtual void check() const;
virtual string toString() const; virtual string toString() const;
virtual void onPush();
virtual void onAbortPiece(const Piece& piece);
}; };
#endif // _D_REQUEST_MESSAGE_H_ #endif // _D_REQUEST_MESSAGE_H_

View File

@ -29,13 +29,6 @@ RequestSlot::RequestSlot(const RequestSlot& requestSlot) {
copy(requestSlot); copy(requestSlot);
} }
RequestSlot& RequestSlot::operator=(const RequestSlot& requestSlot) {
if(this != &requestSlot) {
copy(requestSlot);
}
return *this;
}
void RequestSlot::copy(const RequestSlot& requestSlot) { void RequestSlot::copy(const RequestSlot& requestSlot) {
index = requestSlot.index; index = requestSlot.index;
begin = requestSlot.begin; begin = requestSlot.begin;
@ -62,9 +55,3 @@ bool RequestSlot::isNull(const RequestSlot& requestSlot) {
return requestSlot.index == 0 && requestSlot.begin == 0&& return requestSlot.index == 0 && requestSlot.begin == 0&&
requestSlot.length == 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(const RequestSlot& 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(); void setDispatchedTime();
bool isTimeout(int timeoutSec) const; bool isTimeout(int timeoutSec) const;
int getLatencyInMillis() const; int getLatencyInMillis() const;
bool operator==(const RequestSlot& requestSlot) const;
int getIndex() const { return index; } int getIndex() const { return index; }
void setIndex(int index) { this->index = index; } void setIndex(int index) { this->index = index; }
int getBegin() const { return begin; } int getBegin() const { return begin; }

View File

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

View File

@ -455,15 +455,3 @@ void SocketCore::initiateSecureConnection() {
} }
#endif // HAVE_LIBGNUTLS #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. * connection must be established before calling this method.
*/ */
void initiateSecureConnection() ; 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_ #endif // _D_SOCKET_CORE_H_

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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