2006-05-09 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>

Each peer message has its own class.
	
	* src/PendingMessages.h: Removed.
	* src/PendingMessages.cc: Removed. The sending process was moved 
to
	each message class.
	* src/RequestSlotMan.h: Removed.
	* src/RequestSlotMan.cc: Removed. All functionarities were moved 
to
	SendMessageQueue.
	* src/RequestMessage.h: New class.
	* src/RequestMessage.cc: New class.
	* src/CancelMessage.h: New class.
	* src/CancelMessage.cc: New class.
	* src/BitfieldMessage.h: New class.
	* src/BitfieldMessage.cc: New class.
	* src/ChokeMessage.h: New class.
	* src/ChokeMessage.cc: New class.
	* src/KeepAliveMessage.h: New class.
	* src/KeepAliveMessage.cc: New class.
	* src/PortMessage.h: New class.
	* src/UnchokeMessage.h: New class.
	* src/UnchokeMessage.cc: New class.
	* src/PieceMessage.h: New class.
	* src/PieceMessage.cc: New class.
	* src/HaveMessage.h: New class.
	* src/HaveMessage.cc: New class.
	* src/BitfieldMessage.h: New class.
	* src/BitfieldMessage.cc: New class.
	* src/NotInterestedMessage.h: New class.
	* src/NotInterestedMessage.cc: New class.
	* src/InterestedMessage.h: New class.
	* src/InterestedMessage.cc: New class.
	* src/HandshakeMessage.h (sendMessageQueue): New variable.
	(getSendMessageQueue): New function.
	(setSendMessageQueue): New function.
	* src/HandshakeMessage.cc: New class.
	* src/PeerConnection.h (receiveMessage): Changed return value 
and
	arguments.
	(receiveHandshake): Changed return value and arguments.
	* src/PeerConnection.cc (receiveMessage): Do not create message 
class
	here.
	(receiveHandshake): Do not create handshake class here.
	* src/PeerInteractionCommand.h (peerConnection): Removed.
	(piece): Removed.
	(syncPiece): Removed.
	(sendInterest): Removed.
	(sendMessages): Removed.
	(createRequestPendingMessage): Removed.
	(checkPieceHash): Removed.
	(erasePieceOnDisk): Removed.
	(getNewPieceAndSendInterest): Removed.
	(onGotNewPice): Removed.
	(onGotWrongPiece): Removed.
	* src/PeerInteractionCommand.cc (PeerInteractionCommand):
	Removed peerConnection, piece.
	(~PeerInteractionCommand): Removed peerConnection.
	(executeInternal): Use sendMessageQueue instead of 
peerConnection.
	(syncPiece): Moved to SendMessageQueue.
	(decideChoking): Removed PendingMessage.
	(receiveMessage): Use sendMessageQueue instead of 
peerConnection.
	The action after receiving peer message was moved to each 
message
	class.
	(onGotNewPice): Moved to SendMessageQueue.
	(onGotWrongPiece): Moved to SendMessageQueue.
	(getNewPieceAndSendInterest): Moved to SendMessageQueue.
	(sendInterest): Moved to SendMessageQueue.
	(createRequestPendingMessage): Removed.
	(sendMessages): Moved to SendMessageQueue.
	(onAbort): Use SendMessageQueue::abortPiece()
	(keepAlive): Use sendMessageQueue instead of peerConnection.
	(beforeSocketCheck): Use sendMessageQueue instead of 
peerConnection.
	(checkPieceHash): Moved to SendMessageQueue.
	(erasePieceOnDisk): Moved to SendMessageQueue.
	* src/PeerMessageUtil.h
	(createBitfieldMessage): Removed.
	(createHaveMessage): Changed return value and arguments.
	(createBitfieldMessage): Changed return value and arguments.
	(createRequestCancelMessage): Removed.
	(createPieceMessage): Changed return value and arguments.
	(getShortIntParam): New function.
	(checkIndex): Changed arguments.
	(checkBegin): Changed arguments.
	(checkLength): Changed arguments.
	(checkPieceOffset): Removed.
	(checkRange): New function.
	(checkBitfield): Changed arguments.
	(createPeerMessage): Removed.
	(checkIntegrity): Removed.
	(createHandshakeMessage): Changed arguments.
	(createChokeMessage): New function.
	(createUnchokeMessage): New function.
	(createInterestedMessage): New function.
	(createNotInterestedMessage): New function.
	(createRequestMessage): New function.
	(createCancelMessage): New function.
	(createPortMessage): New function.
	* src/PeerMessageUtil.cc
	(createBitfieldMessage): Removed.
	(createHaveMessage): Changed return value and arguments.
	(createBitfieldMessage): Changed return value and arguments.
	(createRequestCancelMessage): Removed.
	(createPieceMessage): Changed return value and arguments.
	(getShortIntParam): New function.
	(checkIndex): Changed arguments.
	(checkBegin): Changed arguments.
	(checkLength): Changed arguments.
	(checkPieceOffset): Removed.
	(checkRange): New function.
	(checkBitfield): Changed arguments.
	(createPeerMessage): Removed.
	(checkIntegrity): Removed.
	(createHandshakeMessage): Changed arguments.
	(createChokeMessage): New function.
	(createUnchokeMessage): New function.
	(createInterestedMessage): New function.
	(createNotInterestedMessage): New function.
	(createRequestMessage): New function.
	(createCancelMessage): New function.
	(createPortMessage): New function.
	* src/PeerMessage.h
	(id): Removed.
	(index): Removed.
	(begin): Removed.
	(length): Removed.
	(bitfield): Removed.
	(bitfieldLength): Removed.
	(block): Removed.
	(blockLength): Removed.
	(inProgress): New variable.
	(cuid): New variable.
	(peer): New variable.
	(sendMessageQueue): New variable.
	(logger): New variable.
	(setBitfield): Removed.
	(getBitfield): Removed.
	(setBlock): Removed.
	(getBlock): Removed.
	(getBitfieldLength): Removed.
	(getBlockLength): Removed.
	(isInProgress): New function.
	(toString): Made pure virtual.
	(check): New function.
	(send): New function.
	(receivedAction): New function.
	(getId): Made pure virtual.
	(setId): Removed.
	(getIndex): Removed.
	(setIndex): Removed.
	(getBegin): Removed.
	(setBegin): Removed.
	(getLength): Removed.
	(setLength): Removed.
	(getCuid): New function.
	(setCuid): New function.
	(getPeer): New function.
	(setPeer): New function.
	(getSendMessageQueue): New function.
	(setSendMessageQueue): New function.
	(ID): Removed.
	* src/PeerMessage.cc
	(setBitfield): Removed.
	(setBlock): Removed.
	(toString): Removed.
	* src/TorrentMan.h
	(getPieceLength): New function.
	(getPieceLength): New function.
	* src/SendMessageQueue.h
	(REQUEST_TIME_OUT): New definition.
	(RequestSlots): New definition.
	(MessageQueue): New definition.
	(requestSlotMan): Removed.
	(pendingMessages): Removed.
	(requestSlots): New variable.
	(messageQueue): New variable.
	(torrentMan): New variable.
	(peerConnection): New variable.
	(peer): New variable.
	(piece): New variable.
	(getNewPieceAndSendInterest): New function.
	(createPeerMessage): New function.
	(createHandshakeMessage): New function.
	(send): Made private.
	(setPeerMessageCommonProperty): New function.
	(deleteAllRequestSlot): New function.
	(deleteRequestMessageInQueue): New function.
	(cancelAllRequest): Made private.
	(cancelAllRequest): Made private.
	(countRequestSlot): Made private.
	(addPendingMessage): Removed.
	(deletePendingPieceMessage): Removed.
	(deletePendingRequestMessage): Removed.
	(addMessage): New function.
	(deletePieceMessageInQueue): New function.
	(deleteTimeoutRequestSlot): Changed argument.
	(deleteCompletedRequestSlot): Changed argument.
	(getCorrespoindingRequestSlot): Renamed to 
getCorrespondingRequestSlot.
	(getCorrespondingRequestSlot): New function.
	(countPendingMessage): Removed.
	(countMessageInQueue): New function.
	(getTorrentMan): New function.
	(getPeerConnection): New function.
	(hasDownloadPiece): New function.
	(getDownloadPiece): New function.
	(setDownloadPiece): New function.
	(syncPiece): New function.
	(sendMessages): New function.
	(sendNow): New function.
	(trySendNow): New function.
	(abortPiece): New function.
	(sendHandshake): New function.
	(receiveMessage): New function.
	(receiveHandshake): New function.
	(createRequestMessage): New function.
	(createCancelMessage): New function.
	(createPieceMessage): New function.
	(createHaveMessage): New function.
	(createChokeMessage): New function.
	(createUnchokeMessage): New function.
	(createInterestedMessage): New function.
	(createNotInterestedMessage): New function.
	(createBitfieldMessage): New function.
	(createKeepAliveMessage): New function.
	* src/SendMessageQueue.cc
	(SendMessageQueue): Removed requestSlotMan.
	Instantiated peerConnection here.
	(~SendMessageQueue): Removed requestSlotMan.
	Added deletion of peerConnection and the contents of 
messageQueue.
	(send): Updated according to the change of messageQueue.
	(addPendingMessage): Renamed to addMessage.
	(addMessage): New function.
	(deletePendingPieceMessage): Renamed to 
deletePieceMessageInQueue.
	(deletePieceMessageInQueue): New function.
	(deletePendingRequestMessage): Renamed to 
deleteRequestMessageInQueue.
	(deleteRequestMessageInQueue): New function.
	(deleteRequestSlot): RequestSlotMan::deleteRequestSlot(...) was 
moved
	here.
	(deleteTimeoutRequestSlot): 
RequestSlotMan::deleteTimeoutRequestSlot
	(...) was moved here.
	(deleteAllRequestSlot): 
RequestSlotMan::deleteAllRequestSlot(...) was
	moved here.
	(deleteCompletedRequestSlot):
	RequestSlotMan::deleteCompletedRequestSlot(...) was moved here.
	(getCorrespondingRequestSlot):
	RequestSlotMan::getCorrespoindingRequestSlot(...) was moved 
here.
	And renamed to getCorrespondingRequestSlot, correcting a typo.
	(countPendingMessage): Renamed to countMessageInQueue.
	(countMessageInQueue): New function.
	(countRequestSlot): RequestSlotMan::countRequestSlot() was moved 
here.
	(receiveHandshake): New function.
	(createHandshakeMessage): New function.
	(receiveMessage): New function.
	(createPeerMessage): New function.
	(syncPiece): New function.
	(getNewPieceAndSendInterest): New function.
	(sendMessages): New function.
	(sendNow): New function.
	(trySendNow): New function.
	(sendHandshake): New function.
	(abortPiece): New function.
	(getDownloadPiece): New function.
	(getPeerMessageCommonProperty): New function.
	(createRequestMessage): New function.
	(createCancelMessage): New function.
	(createPieceMessage): New function.
	(createHaveMessage): New function.
	(createChokeMessage): New function.
	(createUnchokeMessage): New function.
	(createInterestedMessage): New function.
	(createNotInterestedMessage): New function.
	(createBitfieldMessage): New function.
	(createKeepAliveMessage): New function.
	
	
	To add simple Content-Disposition support:

	* src/HttpResponseCommand.h (determinFilename): New function.
	* src/HttpResponseCommand.cc (executeInternal):
	Use determinFilename(headers) instead of req->getFile() when 
comparing
	filename.
	(determinFilename): New function.
	(handleDefaultEncoding): Use determinFilename(headers) instead 
of
	req->getFile().
	(handleOtherEncoding): Use determinFilename(headers) instead of
	req->getFile().
	* src/Util.h (getContentDispositionFilename): New function.
	* src/Util.cc (getContentDispositionFilename): New function.
	
	* src/LogFactory.h (release): New function.
	* src/LogFactory.cc (release): New function.

	To fix a bug that causes out-of-bound exception when HTTP status
	line is wrong:
	
	* src/HttpConnection.cc (receiveResponse): Added a check for 
header
	size.

	* src/common.h (Deleter): New class.

	* src/SegmentMan.cc
	(~SegmentMan): Added deletion of splitter and diskWriter.
	* src/DownloadEngine.h
	(Commands): Use deque.
	(clearQueue): New function.
	* src/DownloadEngine.cc
	(~DownloadEngine): Added deletion of segmentMan.
	(cleanQueue): New function.
	* src/TorrentDownloadEngine.h
	(TorrentDownloadEngine): The implementation was moved to
	TorrentDownloadEngine.cc.
	(~TorrentDownloadEngine): The implementation was moved to
	TorrentDownloadEngine.cc.
	* src/TorrentDownloadEngine.cc
	(~TorrentDownloadEngine): Added deletion of torrentMan.
	* src/main.cc
	(clearRequest): Removed.
	(handler): Added deletion of e.
	(torrentHandler): Added deletion of te.
	(main): Do not share splitter.
	Use Deleter instead of clearRequest.
	Deletion of classes were updated.
pull/1/head
Tatsuhiro Tsujikawa 2006-05-09 15:54:14 +00:00
parent 500e978628
commit ebfdbefb7f
84 changed files with 2563 additions and 1175 deletions

322
ChangeLog
View File

@ -1,3 +1,325 @@
2006-05-09 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Each peer message has its own class.
* src/PendingMessages.h: Removed.
* src/PendingMessages.cc: Removed. The sending process was moved to
each message class.
* src/RequestSlotMan.h: Removed.
* src/RequestSlotMan.cc: Removed. All functionarities were moved to
SendMessageQueue.
* src/RequestMessage.h: New class.
* src/RequestMessage.cc: New class.
* src/CancelMessage.h: New class.
* src/CancelMessage.cc: New class.
* src/BitfieldMessage.h: New class.
* src/BitfieldMessage.cc: New class.
* src/ChokeMessage.h: New class.
* src/ChokeMessage.cc: New class.
* src/KeepAliveMessage.h: New class.
* src/KeepAliveMessage.cc: New class.
* src/PortMessage.h: New class.
* src/UnchokeMessage.h: New class.
* src/UnchokeMessage.cc: New class.
* src/PieceMessage.h: New class.
* src/PieceMessage.cc: New class.
* src/HaveMessage.h: New class.
* src/HaveMessage.cc: New class.
* src/BitfieldMessage.h: New class.
* src/BitfieldMessage.cc: New class.
* src/NotInterestedMessage.h: New class.
* src/NotInterestedMessage.cc: New class.
* src/InterestedMessage.h: New class.
* src/InterestedMessage.cc: New class.
* src/HandshakeMessage.h (sendMessageQueue): New variable.
(getSendMessageQueue): New function.
(setSendMessageQueue): New function.
* src/HandshakeMessage.cc: New class.
* src/PeerConnection.h (receiveMessage): Changed return value and
arguments.
(receiveHandshake): Changed return value and arguments.
* src/PeerConnection.cc (receiveMessage): Do not create message class
here.
(receiveHandshake): Do not create handshake class here.
* src/PeerInteractionCommand.h (peerConnection): Removed.
(piece): Removed.
(syncPiece): Removed.
(sendInterest): Removed.
(sendMessages): Removed.
(createRequestPendingMessage): Removed.
(checkPieceHash): Removed.
(erasePieceOnDisk): Removed.
(getNewPieceAndSendInterest): Removed.
(onGotNewPice): Removed.
(onGotWrongPiece): Removed.
* src/PeerInteractionCommand.cc (PeerInteractionCommand):
Removed peerConnection, piece.
(~PeerInteractionCommand): Removed peerConnection.
(executeInternal): Use sendMessageQueue instead of peerConnection.
(syncPiece): Moved to SendMessageQueue.
(decideChoking): Removed PendingMessage.
(receiveMessage): Use sendMessageQueue instead of peerConnection.
The action after receiving peer message was moved to each message
class.
(onGotNewPice): Moved to SendMessageQueue.
(onGotWrongPiece): Moved to SendMessageQueue.
(getNewPieceAndSendInterest): Moved to SendMessageQueue.
(sendInterest): Moved to SendMessageQueue.
(createRequestPendingMessage): Removed.
(sendMessages): Moved to SendMessageQueue.
(onAbort): Use SendMessageQueue::abortPiece()
(keepAlive): Use sendMessageQueue instead of peerConnection.
(beforeSocketCheck): Use sendMessageQueue instead of peerConnection.
(checkPieceHash): Moved to SendMessageQueue.
(erasePieceOnDisk): Moved to SendMessageQueue.
* src/PeerMessageUtil.h
(createBitfieldMessage): Removed.
(createHaveMessage): Changed return value and arguments.
(createBitfieldMessage): Changed return value and arguments.
(createRequestCancelMessage): Removed.
(createPieceMessage): Changed return value and arguments.
(getShortIntParam): New function.
(checkIndex): Changed arguments.
(checkBegin): Changed arguments.
(checkLength): Changed arguments.
(checkPieceOffset): Removed.
(checkRange): New function.
(checkBitfield): Changed arguments.
(createPeerMessage): Removed.
(checkIntegrity): Removed.
(createHandshakeMessage): Changed arguments.
(createChokeMessage): New function.
(createUnchokeMessage): New function.
(createInterestedMessage): New function.
(createNotInterestedMessage): New function.
(createRequestMessage): New function.
(createCancelMessage): New function.
(createPortMessage): New function.
* src/PeerMessageUtil.cc
(createBitfieldMessage): Removed.
(createHaveMessage): Changed return value and arguments.
(createBitfieldMessage): Changed return value and arguments.
(createRequestCancelMessage): Removed.
(createPieceMessage): Changed return value and arguments.
(getShortIntParam): New function.
(checkIndex): Changed arguments.
(checkBegin): Changed arguments.
(checkLength): Changed arguments.
(checkPieceOffset): Removed.
(checkRange): New function.
(checkBitfield): Changed arguments.
(createPeerMessage): Removed.
(checkIntegrity): Removed.
(createHandshakeMessage): Changed arguments.
(createChokeMessage): New function.
(createUnchokeMessage): New function.
(createInterestedMessage): New function.
(createNotInterestedMessage): New function.
(createRequestMessage): New function.
(createCancelMessage): New function.
(createPortMessage): New function.
* src/PeerMessage.h
(id): Removed.
(index): Removed.
(begin): Removed.
(length): Removed.
(bitfield): Removed.
(bitfieldLength): Removed.
(block): Removed.
(blockLength): Removed.
(inProgress): New variable.
(cuid): New variable.
(peer): New variable.
(sendMessageQueue): New variable.
(logger): New variable.
(setBitfield): Removed.
(getBitfield): Removed.
(setBlock): Removed.
(getBlock): Removed.
(getBitfieldLength): Removed.
(getBlockLength): Removed.
(isInProgress): New function.
(toString): Made pure virtual.
(check): New function.
(send): New function.
(receivedAction): New function.
(getId): Made pure virtual.
(setId): Removed.
(getIndex): Removed.
(setIndex): Removed.
(getBegin): Removed.
(setBegin): Removed.
(getLength): Removed.
(setLength): Removed.
(getCuid): New function.
(setCuid): New function.
(getPeer): New function.
(setPeer): New function.
(getSendMessageQueue): New function.
(setSendMessageQueue): New function.
(ID): Removed.
* src/PeerMessage.cc
(setBitfield): Removed.
(setBlock): Removed.
(toString): Removed.
* src/TorrentMan.h
(getPieceLength): New function.
(getPieceLength): New function.
* src/SendMessageQueue.h
(REQUEST_TIME_OUT): New definition.
(RequestSlots): New definition.
(MessageQueue): New definition.
(requestSlotMan): Removed.
(pendingMessages): Removed.
(requestSlots): New variable.
(messageQueue): New variable.
(torrentMan): New variable.
(peerConnection): New variable.
(peer): New variable.
(piece): New variable.
(getNewPieceAndSendInterest): New function.
(createPeerMessage): New function.
(createHandshakeMessage): New function.
(send): Made private.
(setPeerMessageCommonProperty): New function.
(deleteAllRequestSlot): New function.
(deleteRequestMessageInQueue): New function.
(cancelAllRequest): Made private.
(cancelAllRequest): Made private.
(countRequestSlot): Made private.
(addPendingMessage): Removed.
(deletePendingPieceMessage): Removed.
(deletePendingRequestMessage): Removed.
(addMessage): New function.
(deletePieceMessageInQueue): New function.
(deleteTimeoutRequestSlot): Changed argument.
(deleteCompletedRequestSlot): Changed argument.
(getCorrespoindingRequestSlot): Renamed to getCorrespondingRequestSlot.
(getCorrespondingRequestSlot): New function.
(countPendingMessage): Removed.
(countMessageInQueue): New function.
(getTorrentMan): New function.
(getPeerConnection): New function.
(hasDownloadPiece): New function.
(getDownloadPiece): New function.
(setDownloadPiece): New function.
(syncPiece): New function.
(sendMessages): New function.
(sendNow): New function.
(trySendNow): New function.
(abortPiece): New function.
(sendHandshake): New function.
(receiveMessage): New function.
(receiveHandshake): New function.
(createRequestMessage): New function.
(createCancelMessage): New function.
(createPieceMessage): New function.
(createHaveMessage): New function.
(createChokeMessage): New function.
(createUnchokeMessage): New function.
(createInterestedMessage): New function.
(createNotInterestedMessage): New function.
(createBitfieldMessage): New function.
(createKeepAliveMessage): New function.
* src/SendMessageQueue.cc
(SendMessageQueue): Removed requestSlotMan.
Instantiated peerConnection here.
(~SendMessageQueue): Removed requestSlotMan.
Added deletion of peerConnection and the contents of messageQueue.
(send): Updated according to the change of messageQueue.
(addPendingMessage): Renamed to addMessage.
(addMessage): New function.
(deletePendingPieceMessage): Renamed to deletePieceMessageInQueue.
(deletePieceMessageInQueue): New function.
(deletePendingRequestMessage): Renamed to deleteRequestMessageInQueue.
(deleteRequestMessageInQueue): New function.
(deleteRequestSlot): RequestSlotMan::deleteRequestSlot(...) was moved
here.
(deleteTimeoutRequestSlot): RequestSlotMan::deleteTimeoutRequestSlot
(...) was moved here.
(deleteAllRequestSlot): RequestSlotMan::deleteAllRequestSlot(...) was
moved here.
(deleteCompletedRequestSlot):
RequestSlotMan::deleteCompletedRequestSlot(...) was moved here.
(getCorrespondingRequestSlot):
RequestSlotMan::getCorrespoindingRequestSlot(...) was moved here.
And renamed to getCorrespondingRequestSlot, correcting a typo.
(countPendingMessage): Renamed to countMessageInQueue.
(countMessageInQueue): New function.
(countRequestSlot): RequestSlotMan::countRequestSlot() was moved here.
(receiveHandshake): New function.
(createHandshakeMessage): New function.
(receiveMessage): New function.
(createPeerMessage): New function.
(syncPiece): New function.
(getNewPieceAndSendInterest): New function.
(sendMessages): New function.
(sendNow): New function.
(trySendNow): New function.
(sendHandshake): New function.
(abortPiece): New function.
(getDownloadPiece): New function.
(getPeerMessageCommonProperty): New function.
(createRequestMessage): New function.
(createCancelMessage): New function.
(createPieceMessage): New function.
(createHaveMessage): New function.
(createChokeMessage): New function.
(createUnchokeMessage): New function.
(createInterestedMessage): New function.
(createNotInterestedMessage): New function.
(createBitfieldMessage): New function.
(createKeepAliveMessage): New function.
To add simple Content-Disposition support:
* src/HttpResponseCommand.h (determinFilename): New function.
* src/HttpResponseCommand.cc (executeInternal):
Use determinFilename(headers) instead of req->getFile() when comparing
filename.
(determinFilename): New function.
(handleDefaultEncoding): Use determinFilename(headers) instead of
req->getFile().
(handleOtherEncoding): Use determinFilename(headers) instead of
req->getFile().
* src/Util.h (getContentDispositionFilename): New function.
* src/Util.cc (getContentDispositionFilename): New function.
* src/LogFactory.h (release): New function.
* src/LogFactory.cc (release): New function.
To fix a bug that causes out-of-bound exception when HTTP status
line is wrong:
* src/HttpConnection.cc (receiveResponse): Added a check for header
size.
* src/common.h (Deleter): New class.
* src/SegmentMan.cc
(~SegmentMan): Added deletion of splitter and diskWriter.
* src/DownloadEngine.h
(Commands): Use deque.
(clearQueue): New function.
* src/DownloadEngine.cc
(~DownloadEngine): Added deletion of segmentMan.
(cleanQueue): New function.
* src/TorrentDownloadEngine.h
(TorrentDownloadEngine): The implementation was moved to
TorrentDownloadEngine.cc.
(~TorrentDownloadEngine): The implementation was moved to
TorrentDownloadEngine.cc.
* src/TorrentDownloadEngine.cc
(~TorrentDownloadEngine): Added deletion of torrentMan.
* src/main.cc
(clearRequest): Removed.
(handler): Added deletion of e.
(torrentHandler): Added deletion of te.
(main): Do not share splitter.
Use Deleter instead of clearRequest.
Deletion of classes were updated.
2006-05-06 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
* src/main.cc (main): Fixed typo.

2
TODO
View File

@ -14,4 +14,4 @@
* Add Mainline-compatible DHT support
* Add Message stream encryption support
* Add announce-list support
* Add content-disposition support(NO MIME Encoding)
* Add fast extension

20
configure vendored
View File

@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.59 for aria2c 0.4.1.
# Generated by GNU Autoconf 2.59 for aria2c 0.4.2.
#
# Report bugs to <tujikawa@rednoah.com>.
#
@ -269,8 +269,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
# Identity of this package.
PACKAGE_NAME='aria2c'
PACKAGE_TARNAME='aria2c'
PACKAGE_VERSION='0.4.1'
PACKAGE_STRING='aria2c 0.4.1'
PACKAGE_VERSION='0.4.2'
PACKAGE_STRING='aria2c 0.4.2'
PACKAGE_BUGREPORT='tujikawa@rednoah.com'
ac_unique_file="src/Socket.h"
@ -788,7 +788,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
\`configure' configures aria2c 0.4.1 to adapt to many kinds of systems.
\`configure' configures aria2c 0.4.2 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@ -854,7 +854,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of aria2c 0.4.1:";;
short | recursive ) echo "Configuration of aria2c 0.4.2:";;
esac
cat <<\_ACEOF
@ -994,7 +994,7 @@ fi
test -n "$ac_init_help" && exit 0
if $ac_init_version; then
cat <<\_ACEOF
aria2c configure 0.4.1
aria2c configure 0.4.2
generated by GNU Autoconf 2.59
Copyright (C) 2003 Free Software Foundation, Inc.
@ -1008,7 +1008,7 @@ cat >&5 <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by aria2c $as_me 0.4.1, which was
It was created by aria2c $as_me 0.4.2, which was
generated by GNU Autoconf 2.59. Invocation command line was
$ $0 $@
@ -1651,7 +1651,7 @@ fi
# Define the identity of the package.
PACKAGE='aria2c'
VERSION='0.4.1'
VERSION='0.4.2'
cat >>confdefs.h <<_ACEOF
@ -11529,7 +11529,7 @@ _ASBOX
} >&5
cat >&5 <<_CSEOF
This file was extended by aria2c $as_me 0.4.1, which was
This file was extended by aria2c $as_me 0.4.2, which was
generated by GNU Autoconf 2.59. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@ -11592,7 +11592,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF
ac_cs_version="\\
aria2c config.status 0.4.1
aria2c config.status 0.4.2
configured by $0, generated by GNU Autoconf 2.59,
with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"

View File

@ -2,7 +2,7 @@
# Process this file with autoconf to produce a configure script.
#
AC_PREREQ(2.59)
AC_INIT(aria2c, 0.4.1, tujikawa@rednoah.com)
AC_INIT(aria2c, 0.4.2, tujikawa@rednoah.com)
AM_INIT_AUTOMAKE()
AM_PATH_CPPUNIT(1.10.2)
AC_CONFIG_SRCDIR([src/Socket.h])

View File

@ -9,7 +9,7 @@
# General Public License and is *not* in the public domain.
PACKAGE = aria2c
VERSION = 0.4.1
VERSION = 0.4.2
SHELL = /bin/sh

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: http://aria2.sourceforge.net/\n"
"POT-Creation-Date: 2006-05-05 19:42+0900\n"
"POT-Creation-Date: 2006-05-10 00:53+0900\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -342,13 +342,13 @@ msgid ""
"The download was not complete because of errors. Check the log.\n"
msgstr ""
#: src/main.cc:92 src/main.cc:101
#: src/main.cc:88 src/main.cc:99
msgid ""
"\n"
"stopping application...\n"
msgstr ""
#: src/main.cc:96 src/main.cc:111
#: src/main.cc:94 src/main.cc:111
msgid "done\n"
msgstr ""
@ -704,10 +704,10 @@ msgstr ""
msgid "daemon failed"
msgstr ""
#: src/main.cc:671
#: src/main.cc:670
msgid "Files:"
msgstr ""
#: src/main.cc:702
#: src/main.cc:701
msgid "Errors occurred while binding port.\n"
msgstr ""

BIN
po/de.gmo

Binary file not shown.

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: de\n"
"Report-Msgid-Bugs-To: http://aria2.sourceforge.net/\n"
"POT-Creation-Date: 2006-05-05 19:42+0900\n"
"POT-Creation-Date: 2006-05-10 00:53+0900\n"
"PO-Revision-Date: 2006-05-05 19:44+0900\n"
"Last-Translator: Hermann J. Beckers <hj.beckers@onlinehome.de>\n"
"Language-Team: deutsch <de@li.org>\n"
@ -355,7 +355,7 @@ msgstr ""
"\n"
"Abruf wegen Fehlern nicht vollständig. Überprüfen Sie die Log-Datei.\n"
#: src/main.cc:92 src/main.cc:101
#: src/main.cc:88 src/main.cc:99
msgid ""
"\n"
"stopping application...\n"
@ -363,7 +363,7 @@ msgstr ""
"\n"
"Anwendung wird gestoppt ...\n"
#: src/main.cc:96 src/main.cc:111
#: src/main.cc:94 src/main.cc:111
msgid "done\n"
msgstr "erledigt\n"
@ -820,10 +820,10 @@ msgstr "Geben Sie zumindest eine URL an"
msgid "daemon failed"
msgstr "Daemon-Start nicht erfolgreich"
#: src/main.cc:671
#: src/main.cc:670
msgid "Files:"
msgstr "Dateien:"
#: src/main.cc:702
#: src/main.cc:701
msgid "Errors occurred while binding port.\n"
msgstr "Fehler beim Binden an Port aufgetreten.\n"

BIN
po/ja.gmo

Binary file not shown.

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: aria2c 0.2.1\n"
"Report-Msgid-Bugs-To: http://aria2.sourceforge.net/\n"
"POT-Creation-Date: 2006-05-05 19:42+0900\n"
"POT-Creation-Date: 2006-05-10 00:53+0900\n"
"PO-Revision-Date: 2006-05-05 19:45+0900\n"
"Last-Translator: Tatsuhiro Tsujikawa <tujikawa@rednoah.com>\n"
"Language-Team: Japanese <ja@li.org>\n"
@ -358,7 +358,7 @@ msgstr ""
"\n"
"ダウンロードはエラーのため完了していません. ログを確認してください.\n"
#: src/main.cc:92 src/main.cc:101
#: src/main.cc:88 src/main.cc:99
msgid ""
"\n"
"stopping application...\n"
@ -366,7 +366,7 @@ msgstr ""
"\n"
"アプリケーションを終了しています...\n"
#: src/main.cc:96 src/main.cc:111
#: src/main.cc:94 src/main.cc:111
msgid "done\n"
msgstr "完了\n"
@ -847,10 +847,10 @@ msgstr "
msgid "daemon failed"
msgstr "デーモン起動に失敗"
#: src/main.cc:671
#: src/main.cc:670
msgid "Files:"
msgstr "ファイル:"
#: src/main.cc:702
#: src/main.cc:701
msgid "Errors occurred while binding port.\n"
msgstr "ポートをバインド中にエラーが発生しました.\n"

View File

@ -77,7 +77,7 @@ bool AbstractCommand::execute() {
if(isTimeoutDetected()) {
throw new DlRetryEx(EX_TIME_OUT);
}
e->commands.push(this);
e->commands.push_back(this);
return false;
}
updateCheckPoint();
@ -118,10 +118,10 @@ bool AbstractCommand::execute() {
bool AbstractCommand::prepareForRetry(int wait) {
Command* command = InitiateConnectionCommandFactory::createInitiateConnectionCommand(cuid, req, e);
if(wait == 0) {
e->commands.push(command);
e->commands.push_back(command);
} else {
SleepCommand* scom = new SleepCommand(cuid, e, command, wait);
e->commands.push(scom);
e->commands.push_back(scom);
}
return true;
}

50
src/BitfieldMessage.cc Normal file
View File

@ -0,0 +1,50 @@
/* <!-- 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 "BitfieldMessage.h"
#include "SendMessageQueue.h"
#include "PeerMessageUtil.h"
#include "Util.h"
void BitfieldMessage::setBitfield(const unsigned char* bitfield, int bitfieldLength) {
if(this->bitfield != NULL) {
delete [] this->bitfield;
}
this->bitfieldLength = bitfieldLength;
this->bitfield = new unsigned char[this->bitfieldLength];
memcpy(this->bitfield, bitfield, this->bitfieldLength);
}
void BitfieldMessage::receivedAction() {
peer->setBitfield(bitfield, bitfieldLength);
}
void BitfieldMessage::send() {
sendMessageQueue->getPeerConnection()->sendBitfield();
}
void BitfieldMessage::check() const {
PeerMessageUtil::checkBitfield(bitfield, bitfieldLength, pieces);
}
string BitfieldMessage::toString() const {
return "bitfield "+Util::toHex(bitfield, bitfieldLength);
}

65
src/BitfieldMessage.h Normal file
View File

@ -0,0 +1,65 @@
/* <!-- 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_BITFIELD_MESSAGE_H_
#define _D_BITFIELD_MESSAGE_H_
#include "PeerMessage.h"
class BitfieldMessage : public PeerMessage {
private:
unsigned char* bitfield;
int bitfieldLength;
// for check
int pieces;
public:
BitfieldMessage():PeerMessage(),
bitfield(NULL), bitfieldLength(0),
pieces(0) {}
virtual ~BitfieldMessage() {
if(bitfield != NULL) {
delete [] bitfield;
}
}
enum ID {
ID = 5
};
void setBitfield(const unsigned char* bitfield, int bitfieldLength);
const unsigned char* getBitfield() const { return bitfield; }
int getBitfieldLength() const { return bitfieldLength; }
void setPieces(int pieces) {
this->pieces = pieces;
}
int getPieces() const { return pieces;}
virtual int getId() const { return ID; }
virtual void receivedAction();
virtual void send();
virtual void check() const;
virtual string toString() const;
};
#endif // _D_BITFIELD_MESSAGE_H_

45
src/CancelMessage.cc Normal file
View File

@ -0,0 +1,45 @@
/* <!-- 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 "CancelMessage.h"
#include "SendMessageQueue.h"
#include "PeerMessageUtil.h"
#include "Util.h"
void CancelMessage::receivedAction() {
sendMessageQueue->deletePieceMessageInQueue(this);
}
void CancelMessage::send() {
sendMessageQueue->getPeerConnection()->sendCancel(index, begin, length);
}
void CancelMessage::check() const {
PeerMessageUtil::checkIndex(index, pieces);
PeerMessageUtil::checkBegin(begin, pieceLength);
PeerMessageUtil::checkLength(length);
PeerMessageUtil::checkRange(begin, length, pieceLength);
}
string CancelMessage::toString() const {
return "cancel index="+Util::itos(index)+", begin="+Util::itos(begin)+
", length="+Util::itos(length);
}

73
src/CancelMessage.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_CANCEL_MESSAGE_H_
#define _D_CANCEL_MESSAGE_H_
#include "PeerMessage.h"
#include "TorrentMan.h"
class SendMessageQueue;
class CancelMessage : public PeerMessage {
private:
int index;
int begin;
int length;
// for check
int pieces;
int pieceLength;
public:
CancelMessage():PeerMessage(),
index(0), begin(0), length(0),
pieces(0), pieceLength(0) {}
virtual ~CancelMessage() {}
enum ID {
ID = 8
};
int getIndex() const { return index; }
void setIndex(int index) { this->index = index; }
int getBegin() const { return begin; }
void setBegin(int begin) { this->begin = begin; }
int getLength() const { return length; }
void setLength(int length) { this->length = length; }
void setPieces(int pieces) {
this->pieces = pieces;
}
int getPieces() const { return pieces;}
void setPieceLength(int pieceLength) {
this->pieceLength = pieceLength;
}
int getPieceLength() const { return pieceLength;}
virtual int getId() const { return ID; }
virtual void receivedAction();
virtual void send();
virtual void check() const;
virtual string toString() const;
};
#endif // _D_CANCEL_MESSAGE_H_

38
src/ChokeMessage.cc Normal file
View File

@ -0,0 +1,38 @@
/* <!-- 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 "ChokeMessage.h"
#include "SendMessageQueue.h"
void ChokeMessage::receivedAction() {
peer->peerChoking = true;
}
void ChokeMessage::send() {
if(!peer->amChoking) {
sendMessageQueue->getPeerConnection()->sendChoke();
peer->amChoking = true;
}
}
string ChokeMessage::toString() const {
return "choke";
}

43
src/ChokeMessage.h Normal file
View File

@ -0,0 +1,43 @@
/* <!-- 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_CHOKE_MESSAGE_H_
#define _D_CHOKE_MESSAGE_H_
#include "PeerMessage.h"
class ChokeMessage : public PeerMessage {
public:
ChokeMessage():PeerMessage() {}
virtual ~ChokeMessage() {}
enum ID {
ID = 0
};
virtual int getId() const { return ID; }
virtual void receivedAction();
virtual void send();
virtual string toString() const;
};
#endif // _D_CHOKE_MESSAGE_H_

View File

@ -82,7 +82,7 @@ bool DownloadCommand::executeInternal(Segment seg) {
return prepareForNextSegment();
} else {
e->segmentMan->updateSegment(seg);
e->commands.push(this);
e->commands.push_back(this);
return false;
}

View File

@ -37,6 +37,14 @@ DownloadEngine::DownloadEngine():noWait(false), segmentMan(NULL) {
DownloadEngine::~DownloadEngine() {
assert(rsockets.empty());
assert(wsockets.empty());
if(segmentMan != NULL) {
delete segmentMan;
}
}
void DownloadEngine::cleanQueue() {
for_each(commands.begin(), commands.end(), Deleter());
commands.clear();
}
void DownloadEngine::run() {
@ -45,7 +53,7 @@ void DownloadEngine::run() {
int max = commands.size();
for(int i = 0; i < max; i++) {
Command* com = commands.front();
commands.pop();
commands.pop_front();
if(com->execute()) {
delete(com);
}

View File

@ -22,8 +22,6 @@
#ifndef _D_DOWNLOAD_ENGINE_H_
#define _D_DOWNLOAD_ENGINE_H_
#include <queue>
#include <deque>
#include "Command.h"
#include "Socket.h"
#include "SegmentMan.h"
@ -31,11 +29,10 @@
#include "Logger.h"
#include "Option.h"
#include <sys/time.h>
using namespace std;
#include <deque>
typedef deque<Socket*> Sockets;
typedef queue<Command*> Commands;
typedef deque<Command*> Commands;
class DownloadEngine {
private:
@ -63,6 +60,8 @@ public:
void run();
void cleanQueue();
bool addSocketForReadCheck(Socket* socket);
bool deleteSocketForReadCheck(Socket* socket);
bool addSocketForWriteCheck(Socket* socket);

View File

@ -67,7 +67,7 @@ bool FtpInitiateConnectionCommand::executeInternal(Segment segment) {
socket->establishConnection(req->getHost(), req->getPort());
command = new FtpNegotiationCommand(cuid, req, e, socket);
}
e->commands.push(command);
e->commands.push_back(command);
return true;
}

View File

@ -51,10 +51,10 @@ bool FtpNegotiationCommand::executeInternal(Segment segment) {
return prepareForRetry(0);
} else if(sequence == SEQ_NEGOTIATION_COMPLETED) {
FtpDownloadCommand* command = new FtpDownloadCommand(cuid, req, e, dataSocket, socket);
e->commands.push(command);
e->commands.push_back(command);
return true;
} else {
e->commands.push(this);
e->commands.push_back(this);
return false;
}
}

View File

@ -36,6 +36,6 @@ bool FtpTunnelRequestCommand::executeInternal(Segment segment) {
httpConnection.sendProxyRequest();
FtpTunnelResponseCommand* command = new FtpTunnelResponseCommand(cuid, req, e, socket);
e->commands.push(command);
e->commands.push_back(command);
return true;
}

View File

@ -37,13 +37,13 @@ bool FtpTunnelResponseCommand::executeInternal(Segment segment) {
int status = http->receiveResponse(headers);
if(status == 0) {
// we didn't receive all of headers yet.
e->commands.push(this);
e->commands.push_back(this);
return false;
}
if(status != 200) {
throw new DlRetryEx(EX_PROXY_CONNECTION_FAILED);
}
FtpNegotiationCommand* command = new FtpNegotiationCommand(cuid, req, e, socket);
e->commands.push(command);
e->commands.push_back(command);
return true;
}

39
src/HandshakeMessage.cc Normal file
View File

@ -0,0 +1,39 @@
/* <!-- 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 "HandshakeMessage.h"
#include "SendMessageQueue.h"
#include "PeerMessageUtil.h"
#include "Util.h"
void HandshakeMessage::setSendMessageQueue(SendMessageQueue* sendMessageQueue) {
this->sendMessageQueue = sendMessageQueue;
}
string HandshakeMessage::toString() const {
return "handshake peerId="+
Util::urlencode((unsigned char*)peerId, sizeof(peerId));
}
void HandshakeMessage::check() {
PeerMessageUtil::checkHandshake(this,
sendMessageQueue->getTorrentMan()->getInfoHash());
}

View File

@ -23,7 +23,8 @@
#define _D_HANDSHAKE_MESSAGE_H_
#include "common.h"
#include "Util.h"
class SendMessageQueue;
#define PSTR "BitTorrent protocol"
#define HANDSHAKE_MESSAGE_LENGTH 68
@ -34,14 +35,16 @@ public:
string pstr;
unsigned char infoHash[20];
char peerId[20];
SendMessageQueue* sendMessageQueue;
public:
HandshakeMessage() {}
~HandshakeMessage() {}
string toString() const {
return "handshake peerId="+
Util::urlencode((unsigned char*)peerId, sizeof(peerId));
}
SendMessageQueue* getSendMessageQueue() const { return sendMessageQueue; }
void setSendMessageQueue(SendMessageQueue* sendMessageQueue);
string toString() const;
void check();
};
#endif // _D_HANDSHAKE_MESSAGE_H_

43
src/HaveMessage.cc Normal file
View File

@ -0,0 +1,43 @@
/* <!-- 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 "HaveMessage.h"
#include "SendMessageQueue.h"
#include "PeerMessageUtil.h"
#include "Util.h"
void HaveMessage::receivedAction() {
peer->updateBitfield(index, 1);
}
void HaveMessage::send() {
if(!peer->hasPiece(index)) {
sendMessageQueue->getPeerConnection()->sendHave(index);
}
}
void HaveMessage::check() const {
PeerMessageUtil::checkIndex(index, pieces);
}
string HaveMessage::toString() const {
return "have index="+Util::itos(index);
}

58
src/HaveMessage.h Normal file
View File

@ -0,0 +1,58 @@
/* <!-- 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_HAVE_MESSAGE_H_
#define _D_HAVE_MESSAGE_H_
#include "PeerMessage.h"
class HaveMessage : public PeerMessage {
private:
int index;
// for check
int pieces;
public:
HaveMessage():PeerMessage(), index(0), pieces(0) {}
virtual ~HaveMessage() {}
enum ID {
ID = 4
};
void setIndex(int index) {
this->index = index;
}
int getIndex() const { return index; }
void setPieces(int pieces) {
this->pieces = pieces;
}
int getPieces() const { return pieces;}
virtual int getId() const { return ID; }
virtual void receivedAction();
virtual void send();
virtual void check() const;
virtual string toString() const;
};
#endif // _D_HAVE_MESSAGE_H_

View File

@ -120,7 +120,7 @@ int HttpConnection::findEndOfHeader(const char* buf, const char* substr, int buf
int HttpConnection::receiveResponse(HttpHeader& headers) {
//char buf[512];
string header;
int delimiterSwith = 0;
int delimiterSwitch = 0;
char* delimiters[] = { "\r\n", "\n" };
int size = HEADERBUF_SIZE-headerBufLength;
@ -137,19 +137,20 @@ int HttpConnection::receiveResponse(HttpHeader& headers) {
//header += buf;
//string::size_type p;
int eohIndex;
if((eohIndex = findEndOfHeader(headerBuf, "\r\n\r\n", hlenTemp)) == -1 &&
(eohIndex = findEndOfHeader(headerBuf, "\n\n", hlenTemp)) == -1) {
socket->readData(headerBuf+headerBufLength, size);
} else {
if(eohIndex[headerBuf] == '\n') {
// for crapping non-standard HTTP server
delimiterSwith = 1;
delimiterSwitch = 1;
} else {
delimiterSwith = 0;
delimiterSwitch = 0;
}
headerBuf[eohIndex+strlen(delimiters[delimiterSwith])*2] = '\0';
headerBuf[eohIndex+strlen(delimiters[delimiterSwitch])*2] = '\0';
header = headerBuf;
size = eohIndex+strlen(delimiters[delimiterSwith])*2-headerBufLength;
size = eohIndex+strlen(delimiters[delimiterSwitch])*2-headerBufLength;
socket->readData(headerBuf+headerBufLength, size);
}
if(!Util::endsWith(header, "\r\n\r\n") && !Util::endsWith(header, "\n\n")) {
@ -159,15 +160,18 @@ int HttpConnection::receiveResponse(HttpHeader& headers) {
logger->info(MSG_RECEIVE_RESPONSE, cuid, header.c_str());
string::size_type p, np;
p = np = 0;
np = header.find(delimiters[delimiterSwith], p);
np = header.find(delimiters[delimiterSwitch], p);
if(np == string::npos) {
throw new DlRetryEx(EX_NO_STATUS_HEADER);
}
// check HTTP status value
if(header.size() <= 12) {
throw new DlRetryEx(EX_NO_STATUS_HEADER);
}
string status = header.substr(9, 3);
p = np+2;
// retreive status name-value pairs, then push these into map
while((np = header.find(delimiters[delimiterSwith], p)) != string::npos && np != p) {
while((np = header.find(delimiters[delimiterSwitch], p)) != string::npos && np != p) {
string line = header.substr(p, np-p);
p = np+2;
pair<string, string> hp;

View File

@ -55,7 +55,7 @@ bool HttpInitiateConnectionCommand::executeInternal(Segment segment) {
socket->establishConnection(req->getHost(), req->getPort());
command = new HttpRequestCommand(cuid, req, e, socket);
}
e->commands.push(command);
e->commands.push_back(command);
return true;
}

View File

@ -36,6 +36,6 @@ bool HttpProxyRequestCommand::executeInternal(Segment segment) {
httpConnection.sendProxyRequest();
HttpProxyResponseCommand* command = new HttpProxyResponseCommand(cuid, req, e, socket);
e->commands.push(command);
e->commands.push_back(command);
return true;
}

View File

@ -37,14 +37,14 @@ bool HttpProxyResponseCommand::executeInternal(Segment segment) {
int status = http->receiveResponse(headers);
if(status == 0) {
// we didn't receive all of headers yet.
e->commands.push(this);
e->commands.push_back(this);
return false;
}
if(status != 200) {
throw new DlRetryEx(EX_PROXY_CONNECTION_FAILED);
}
HttpRequestCommand* command = new HttpRequestCommand(cuid, req, e, socket);
e->commands.push(command);
e->commands.push_back(command);
return true;
}

View File

@ -41,7 +41,7 @@ bool HttpRequestCommand::executeInternal(Segment seg) {
http.sendRequest(seg);
Command* command = getNextCommand();
e->commands.push(command);
e->commands.push_back(command);
return true;
}

View File

@ -45,7 +45,7 @@ bool HttpResponseCommand::executeInternal(Segment seg) {
int status = http->receiveResponse(headers);
if(status == 0) {
// didn't receive header fully
e->commands.push(this);
e->commands.push_back(this);
return false;
}
// check HTTP status number
@ -65,7 +65,7 @@ bool HttpResponseCommand::executeInternal(Segment seg) {
return handleDefaultEncoding(headers);
}
} else {
if(req->getFile() != e->segmentMan->filename) {
if(determinFilename(headers) != e->segmentMan->filename) {
throw new DlAbortEx(EX_FILENAME_MISMATCH, req->getFile().c_str(), e->segmentMan->filename.c_str());
}
createHttpDownloadCommand();
@ -91,6 +91,18 @@ bool HttpResponseCommand::handleRedirect(const string& url, const HttpHeader& he
return prepareForRetry(0);
}
string HttpResponseCommand::determinFilename(const HttpHeader& headers) {
string contentDisposition =
Util::getContentDispositionFilename(headers.getFirst("Content-Disposition"));
if(contentDisposition.empty()) {
return req->getFile();
} else {
logger->info("CUID#%d - Content-Disposition Detected. Use %s as filename",
cuid, contentDisposition.c_str());
return contentDisposition;
}
}
bool HttpResponseCommand::handleDefaultEncoding(const HttpHeader& headers) {
// TODO quick and dirty way
if(req->isTorrent) {
@ -108,7 +120,7 @@ bool HttpResponseCommand::handleDefaultEncoding(const HttpHeader& headers) {
throw new DlAbortEx(EX_TOO_LARGE_FILE, size);
}
e->segmentMan->isSplittable = !(size == 0);
e->segmentMan->filename = req->getFile();
e->segmentMan->filename = determinFilename(headers);
bool segFileExists = e->segmentMan->segmentFileExists();
e->segmentMan->downloadStarted = true;
if(segFileExists) {
@ -130,7 +142,7 @@ bool HttpResponseCommand::handleOtherEncoding(const string& transferEncoding, co
// we ignore content-length when transfer-encoding is set
e->segmentMan->downloadStarted = true;
e->segmentMan->isSplittable = false;
e->segmentMan->filename = req->getFile();
e->segmentMan->filename = determinFilename(headers);
e->segmentMan->totalSize = 0;
Segment seg;
e->segmentMan->getSegment(seg, cuid);
@ -151,7 +163,7 @@ void HttpResponseCommand::createHttpDownloadCommand(const string& transferEncodi
command->transferEncoding = transferEncoding;
enc->init();
}
e->commands.push(command);
e->commands.push_back(command);
}
}

View File

@ -33,6 +33,7 @@ private:
bool handleOtherEncoding(const string& transferEncoding, const HttpHeader& headers);
void createHttpDownloadCommand(const string& transferEncoding = "");
void retrieveCookie(const HttpHeader& headers);
string determinFilename(const HttpHeader& headers);
HttpConnection* http;
protected:
bool executeInternal(Segment segment);

38
src/InterestedMessage.cc Normal file
View File

@ -0,0 +1,38 @@
/* <!-- 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 "InterestedMessage.h"
#include "SendMessageQueue.h"
void InterestedMessage::receivedAction() {
peer->peerInterested = true;
}
void InterestedMessage::send() {
if(!peer->amInterested) {
sendMessageQueue->getPeerConnection()->sendInterested();
peer->amInterested = true;
}
}
string InterestedMessage::toString() const {
return "interested";
}

42
src/InterestedMessage.h Normal file
View File

@ -0,0 +1,42 @@
/* <!-- 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_INTERESTED_MESSAGE_H_
#define _D_INTERESTED_MESSAGE_H_
#include "PeerMessage.h"
class InterestedMessage : public PeerMessage {
public:
InterestedMessage():PeerMessage() {}
virtual ~InterestedMessage() {}
enum ID {
ID = 2
};
virtual int getId() const { return ID; }
virtual void receivedAction();
virtual void send();
virtual string toString() const;
};
#endif // _D_INTERESTED_MESSAGE_H_

27
src/KeepAliveMessage.cc Normal file
View File

@ -0,0 +1,27 @@
/* <!-- 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 "KeepAliveMessage.h"
#include "SendMessageQueue.h"
void KeepAliveMessage::send() {
sendMessageQueue->getPeerConnection()->sendKeepAlive();
}

44
src/KeepAliveMessage.h Normal file
View File

@ -0,0 +1,44 @@
/* <!-- 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_KEEP_ALIVE_MESSAGE_H_
#define _D_KEEP_ALIVE_MESSAGE_H_
#include "PeerMessage.h"
class KeepAliveMessage : public PeerMessage {
public:
KeepAliveMessage():PeerMessage() {}
virtual ~KeepAliveMessage() {}
enum ID {
ID = 99
};
virtual int getId() const { return ID; }
virtual void receivedAction() {}
virtual void send();
virtual string toString() const {
return "keep alive";
}
};
#endif // _D_KEEP_ALIVE_MESSAGE_H_

View File

@ -37,3 +37,8 @@ Logger* LogFactory::getInstance() {
}
return logger;
}
void LogFactory::release() {
delete logger;
logger = NULL;
}

View File

@ -42,6 +42,11 @@ public:
static void setLogFile(const string& name) {
filename = name;
}
/**
* Releases used resources
*/
static void release();
};
#endif // _D_LOG_FACTORY_H_

View File

@ -65,12 +65,10 @@ SRCS = Socket.cc Socket.h\
TorrentDownloadEngine.cc TorrentDownloadEngine.h\
TorrentConsoleDownloadEngine.cc TorrentConsoleDownloadEngine.h\
PeerListenCommand.cc PeerListenCommand.h\
PendingMessage.cc PendingMessage.h\
PeerMessage.cc PeerMessage.h\
HandshakeMessage.h\
HandshakeMessage.cc HandshakeMessage.h\
Piece.cc Piece.h\
RequestSlot.cc RequestSlot.h\
RequestSlotMan.cc RequestSlotMan.h\
TorrentAutoSaveCommand.cc TorrentAutoSaveCommand.h\
Directory.cc Directory.h\
TrackerWatcherCommand.cc TrackerWatcherCommand.h\
@ -85,7 +83,18 @@ SRCS = Socket.cc Socket.h\
LogFactory.cc LogFactory.h\
TrackerUpdateCommand.cc TrackerUpdateCommand.h\
ByteArrayDiskWriter.cc ByteArrayDiskWriter.h\
PeerChokeCommand.cc PeerChokeCommand.h
PeerChokeCommand.cc PeerChokeCommand.h\
ChokeMessage.cc ChokeMessage.h\
UnchokeMessage.cc UnchokeMessage.h\
InterestedMessage.cc InterestedMessage.h\
NotInterestedMessage.cc NotInterestedMessage.h\
HaveMessage.cc HaveMessage.h\
BitfieldMessage.cc BitfieldMessage.h\
RequestMessage.cc RequestMessage.h\
PieceMessage.cc PieceMessage.h\
CancelMessage.cc CancelMessage.h\
KeepAliveMessage.cc KeepAliveMessage.h\
PortMessage.h
noinst_LIBRARIES = libaria2c.a
libaria2c_a_SOURCES = $(SRCS)
aria2c_LDADD = libaria2c.a @LIBINTL@ @ALLOCA@ @LIBGNUTLS_LIBS@\

View File

@ -92,15 +92,20 @@ am__objects_1 = Socket.$(OBJEXT) SocketCore.$(OBJEXT) \
PeerInteractionCommand.$(OBJEXT) Peer.$(OBJEXT) \
BitfieldMan.$(OBJEXT) TorrentDownloadEngine.$(OBJEXT) \
TorrentConsoleDownloadEngine.$(OBJEXT) \
PeerListenCommand.$(OBJEXT) PendingMessage.$(OBJEXT) \
PeerMessage.$(OBJEXT) Piece.$(OBJEXT) RequestSlot.$(OBJEXT) \
RequestSlotMan.$(OBJEXT) TorrentAutoSaveCommand.$(OBJEXT) \
PeerListenCommand.$(OBJEXT) PeerMessage.$(OBJEXT) \
HandshakeMessage.$(OBJEXT) Piece.$(OBJEXT) \
RequestSlot.$(OBJEXT) TorrentAutoSaveCommand.$(OBJEXT) \
Directory.$(OBJEXT) TrackerWatcherCommand.$(OBJEXT) \
SendMessageQueue.$(OBJEXT) MultiDiskWriter.$(OBJEXT) \
DiskAdaptor.$(OBJEXT) CopyDiskAdaptor.$(OBJEXT) \
DirectDiskAdaptor.$(OBJEXT) MultiDiskAdaptor.$(OBJEXT) \
LogFactory.$(OBJEXT) TrackerUpdateCommand.$(OBJEXT) \
ByteArrayDiskWriter.$(OBJEXT) PeerChokeCommand.$(OBJEXT)
ByteArrayDiskWriter.$(OBJEXT) PeerChokeCommand.$(OBJEXT) \
ChokeMessage.$(OBJEXT) UnchokeMessage.$(OBJEXT) \
InterestedMessage.$(OBJEXT) NotInterestedMessage.$(OBJEXT) \
HaveMessage.$(OBJEXT) BitfieldMessage.$(OBJEXT) \
RequestMessage.$(OBJEXT) PieceMessage.$(OBJEXT) \
CancelMessage.$(OBJEXT) KeepAliveMessage.$(OBJEXT)
am_libaria2c_a_OBJECTS = $(am__objects_1)
libaria2c_a_OBJECTS = $(am_libaria2c_a_OBJECTS)
am__installdirs = "$(DESTDIR)$(bindir)"
@ -315,12 +320,10 @@ SRCS = Socket.cc Socket.h\
TorrentDownloadEngine.cc TorrentDownloadEngine.h\
TorrentConsoleDownloadEngine.cc TorrentConsoleDownloadEngine.h\
PeerListenCommand.cc PeerListenCommand.h\
PendingMessage.cc PendingMessage.h\
PeerMessage.cc PeerMessage.h\
HandshakeMessage.h\
HandshakeMessage.cc HandshakeMessage.h\
Piece.cc Piece.h\
RequestSlot.cc RequestSlot.h\
RequestSlotMan.cc RequestSlotMan.h\
TorrentAutoSaveCommand.cc TorrentAutoSaveCommand.h\
Directory.cc Directory.h\
TrackerWatcherCommand.cc TrackerWatcherCommand.h\
@ -335,7 +338,18 @@ SRCS = Socket.cc Socket.h\
LogFactory.cc LogFactory.h\
TrackerUpdateCommand.cc TrackerUpdateCommand.h\
ByteArrayDiskWriter.cc ByteArrayDiskWriter.h\
PeerChokeCommand.cc PeerChokeCommand.h
PeerChokeCommand.cc PeerChokeCommand.h\
ChokeMessage.cc ChokeMessage.h\
UnchokeMessage.cc UnchokeMessage.h\
InterestedMessage.cc InterestedMessage.h\
NotInterestedMessage.cc NotInterestedMessage.h\
HaveMessage.cc HaveMessage.h\
BitfieldMessage.cc BitfieldMessage.h\
RequestMessage.cc RequestMessage.h\
PieceMessage.cc PieceMessage.h\
CancelMessage.cc CancelMessage.h\
KeepAliveMessage.cc KeepAliveMessage.h\
PortMessage.h
noinst_LIBRARIES = libaria2c.a
libaria2c_a_SOURCES = $(SRCS)
@ -425,7 +439,10 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AbstractDiskWriter.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Base64.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BitfieldMan.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BitfieldMessage.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ByteArrayDiskWriter.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CancelMessage.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ChokeMessage.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ChunkedEncoding.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ConsoleDownloadEngine.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CookieBox.Po@am__quote@
@ -445,6 +462,8 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FtpNegotiationCommand.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FtpTunnelRequestCommand.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FtpTunnelResponseCommand.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HandshakeMessage.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HaveMessage.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HttpConnection.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HttpDownloadCommand.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HttpHeader.Po@am__quote@
@ -454,11 +473,14 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HttpRequestCommand.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HttpResponseCommand.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/InitiateConnectionCommandFactory.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/InterestedMessage.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/KeepAliveMessage.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/List.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/LogFactory.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MetaFileUtil.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MultiDiskAdaptor.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MultiDiskWriter.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NotInterestedMessage.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Option.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Peer.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PeerAbstractCommand.Po@am__quote@
@ -469,12 +491,12 @@ distclean-compile:
@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)/PeerMessageUtil.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PendingMessage.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)/PreAllocationDiskWriter.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Request.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RequestMessage.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RequestSlot.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RequestSlotMan.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SegmentMan.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SegmentSplitter.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SendMessageQueue.Po@am__quote@
@ -491,6 +513,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TorrentMan.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TrackerUpdateCommand.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TrackerWatcherCommand.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UnchokeMessage.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Util.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@

View File

@ -0,0 +1,38 @@
/* <!-- 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 "NotInterestedMessage.h"
#include "SendMessageQueue.h"
void NotInterestedMessage::receivedAction() {
peer->peerInterested = false;
}
void NotInterestedMessage::send() {
if(peer->amInterested) {
sendMessageQueue->getPeerConnection()->sendNotInterested();
peer->amInterested = false;
}
}
string NotInterestedMessage::toString() const {
return "not interested";
}

View File

@ -0,0 +1,42 @@
/* <!-- 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_NOT_INTERESTED_MESSAGE_H_
#define _D_NOT_INTERESTED_MESSAGE_H_
#include "PeerMessage.h"
class NotInterestedMessage : public PeerMessage {
public:
NotInterestedMessage():PeerMessage() {}
virtual ~NotInterestedMessage() {}
enum ID {
ID = 3
};
virtual int getId() const { return ID; }
virtual void receivedAction();
virtual void send();
virtual string toString() const;
};
#endif // _D_NOT_INTERESTED_MESSAGE_H_

View File

@ -82,7 +82,7 @@ bool PeerAbstractCommand::execute() {
checkPoint.tv_usec = 0;
throw new DlRetryEx(EX_TIME_OUT);
}
e->commands.push(this);
e->commands.push_back(this);
return false;
}
updateCheckPoint();
@ -95,24 +95,6 @@ bool PeerAbstractCommand::execute() {
delete(err);
return prepareForNextPeer(0);
}
/*catch(DlRetryEx* err) {
logger->error(MSG_RESTARTING_DOWNLOAD, err, cuid);
peer->tryCount++;
bool isAbort = e->option->getAsInt(PREF_MAX_TRIES) != 0 &&
peer->tryCount >= e->option->getAsInt(PREF_MAX_TRIES);
int tryCount = peer->tryCount;
if(isAbort) {
onAbort(err);
}
delete(err);
if(isAbort) {
logger->error(MSG_MAX_TRY, cuid, tryCount);
return true;
} else {
return prepareForRetry(e->option->getAsInt(PREF_RETRY_WAIT));
}
}
*/
}
// TODO this method removed when PeerBalancerCommand is implemented

View File

@ -131,7 +131,7 @@ bool PeerChokeCommand::execute() {
setAllPeerResetDelta(e->torrentMan->getActivePeers());
SleepCommand* command = new SleepCommand(cuid, e, this, interval);
e->commands.push(command);
e->commands.push_back(command);
return false;
}

View File

@ -300,9 +300,9 @@ void PeerConnection::sendCancel(int index, int begin, int length) const {
socket->writeData(msg, sizeof(msg));
}
PeerMessage* PeerConnection::receiveMessage() {
bool PeerConnection::receiveMessage(char* msg, int& length) {
if(!socket->isReadable(0)) {
return NULL;
return false;
}
if(resbufLength == 0 && lenbufLength != 4) {
// read payload size, 4-byte integer
@ -316,7 +316,7 @@ PeerMessage* PeerConnection::receiveMessage() {
if(remain != temp) {
// still 4-temp bytes to go
lenbufLength += temp;
return NULL;
return false;
}
//payloadLen = ntohl(nPayloadLen);
int payloadLength = ntohl(*((int*)lenbuf));
@ -336,26 +336,21 @@ PeerMessage* PeerConnection::receiveMessage() {
}
resbufLength += remaining;
if(currentPayloadLength != resbufLength) {
return NULL;
return false;
}
}
// we got whole payload.
resbufLength = 0;
lenbufLength = 0;
PeerMessage* peerMessage = PeerMessageUtil::createPeerMessage(resbuf, currentPayloadLength);
try {
PeerMessageUtil::checkIntegrity(peerMessage, torrentMan->pieceLength,
torrentMan->pieces, torrentMan->getTotalLength());
} catch(Exception* e) {
delete peerMessage;
throw;
}
return peerMessage;
memcpy(msg, resbuf, currentPayloadLength);
length = currentPayloadLength;
return true;
}
HandshakeMessage* PeerConnection::receiveHandshake() {
bool PeerConnection::receiveHandshake(char* msg, int& length) {
if(!socket->isReadable(0)) {
return NULL;
return false;
}
int remain = HANDSHAKE_MESSAGE_LENGTH-resbufLength;
int temp = remain;
@ -366,16 +361,12 @@ HandshakeMessage* PeerConnection::receiveHandshake() {
}
if(remain != temp) {
resbufLength += temp;
return NULL;
return false;
}
// we got whole handshake payload
resbufLength = 0;
HandshakeMessage* handshakeMessage = PeerMessageUtil::createHandshakeMessage(resbuf);
try {
PeerMessageUtil::checkHandshake(handshakeMessage, torrentMan->getInfoHash());
} catch(Exception* e) {
delete handshakeMessage;
throw;
}
return handshakeMessage;
memcpy(msg, resbuf, HANDSHAKE_MESSAGE_LENGTH);
length = HANDSHAKE_MESSAGE_LENGTH;
return true;
}

View File

@ -73,8 +73,8 @@ public:
void sendPieceHeader(int index, int begin, int length) const;
int sendPieceData(long long int offset, int length) const;
void sendCancel(int index, int begin, int length) const;
PeerMessage* receiveMessage();
HandshakeMessage* receiveHandshake();
bool receiveMessage(char* msg, int& length);
bool receiveHandshake(char* msg, int& length);
Peer* getPeer() const { return peer; }
};

View File

@ -43,7 +43,7 @@ bool PeerInitiateConnectionCommand::executeInternal() {
socket->establishConnection(peer->ipaddr, peer->port);
command = new PeerInteractionCommand(cuid, peer, e, socket, PeerInteractionCommand::INITIATOR_SEND_HANDSHAKE);
e->commands.push(command);
e->commands.push_back(command);
return true;
}
@ -54,13 +54,13 @@ bool PeerInitiateConnectionCommand::prepareForNextPeer(int wait) {
int newCuid = e->torrentMan->getNewCuid();
peer->cuid = newCuid;
PeerInitiateConnectionCommand* command = new PeerInitiateConnectionCommand(newCuid, peer, e);
e->commands.push(command);
e->commands.push_back(command);
}
return true;
}
bool PeerInitiateConnectionCommand::prepareForRetry(int wait) {
PeerInitiateConnectionCommand* command = new PeerInitiateConnectionCommand(cuid, peer, e);
e->commands.push(command);
e->commands.push_back(command);
return true;
}

View File

@ -37,10 +37,9 @@ PeerInteractionCommand::PeerInteractionCommand(int cuid, Peer* peer,
setWriteCheckSocket(socket);
setTimeout(e->option->getAsInt(PREF_PEER_CONNECTION_TIMEOUT));
}
peerConnection = new PeerConnection(cuid, socket, e->option, peer, e->torrentMan);
sendMessageQueue = new SendMessageQueue(cuid, peerConnection, e->torrentMan);
sendMessageQueue = new SendMessageQueue(cuid, socket, e->option,
e->torrentMan, this->peer);
sendMessageQueue->setUploadLimit(e->option->getAsInt(PREF_UPLOAD_LIMIT));
piece = Piece::nullPiece;
keepAliveCheckPoint.tv_sec = 0;
keepAliveCheckPoint.tv_usec = 0;
chokeCheckPoint.tv_sec = 0;
@ -54,7 +53,6 @@ PeerInteractionCommand::PeerInteractionCommand(int cuid, Peer* peer,
}
PeerInteractionCommand::~PeerInteractionCommand() {
delete peerConnection;
delete sendMessageQueue;
e->torrentMan->unadvertisePiece(cuid);
e->torrentMan->deleteActivePeer(this->peer);
@ -70,11 +68,11 @@ bool PeerInteractionCommand::executeInternal() {
switch(sequence) {
case INITIATOR_SEND_HANDSHAKE:
peerConnection->sendHandshake();
sendMessageQueue->sendHandshake();
sequence = INITIATOR_WAIT_HANDSHAKE;
break;
case INITIATOR_WAIT_HANDSHAKE: {
HandshakeMessage* handshakeMessage = peerConnection->receiveHandshake();
HandshakeMessage* handshakeMessage = sendMessageQueue->receiveHandshake();
if(handshakeMessage == NULL) {
break;
}
@ -84,13 +82,13 @@ bool PeerInteractionCommand::executeInternal() {
handshakeMessage->toString().c_str());
delete handshakeMessage;
if(e->torrentMan->getDownloadLength() > 0) {
peerConnection->sendBitfield();
sendMessageQueue->sendNow(sendMessageQueue->createBitfieldMessage());
}
sequence = WIRED;
break;
}
case RECEIVER_WAIT_HANDSHAKE: {
HandshakeMessage* handshakeMessage = peerConnection->receiveHandshake();
HandshakeMessage* handshakeMessage = sendMessageQueue->receiveHandshake();
if(handshakeMessage == NULL) {
break;
}
@ -99,9 +97,9 @@ bool PeerInteractionCommand::executeInternal() {
peer->ipaddr.c_str(), peer->port,
handshakeMessage->toString().c_str());
delete handshakeMessage;
peerConnection->sendHandshake();
sendMessageQueue->sendHandshake();
if(e->torrentMan->getDownloadLength() > 0) {
peerConnection->sendBitfield();
sendMessageQueue->sendNow(sendMessageQueue->createBitfieldMessage());
}
sequence = WIRED;
break;
@ -110,7 +108,7 @@ bool PeerInteractionCommand::executeInternal() {
detectMessageFlooding();
checkLongTimePeerChoking();
checkInactiveConnection();
syncPiece();
sendMessageQueue->syncPiece();
decideChoking();
for(int i = 0; i < 10; i++) {
if(!socket->isReadable(0)) {
@ -118,16 +116,15 @@ bool PeerInteractionCommand::executeInternal() {
}
receiveMessage();
}
sendMessageQueue->deleteTimeoutRequestSlot(piece);
sendMessageQueue->deleteCompletedRequestSlot(piece);
sendInterest();
sendMessages();
sendMessageQueue->deleteTimeoutRequestSlot();
sendMessageQueue->deleteCompletedRequestSlot();
sendMessageQueue->sendMessages(e->getUploadSpeed());
break;
}
if(sendMessageQueue->countPendingMessage() > 0) {
if(sendMessageQueue->countMessageInQueue() > 0) {
setWriteCheckSocket(socket);
}
e->commands.push(this);
e->commands.push_back(this);
return false;
}
@ -184,109 +181,47 @@ void PeerInteractionCommand::checkLongTimePeerChoking() {
}
}
void PeerInteractionCommand::syncPiece() {
if(Piece::isNull(piece)) {
return;
}
e->torrentMan->syncPiece(piece);
}
void PeerInteractionCommand::decideChoking() {
if(peer->shouldBeChoking()) {
if(!peer->amChoking) {
PendingMessage pendingMessage(PeerMessage::CHOKE, peerConnection);
sendMessageQueue->addPendingMessage(pendingMessage);
sendMessageQueue->addMessage(sendMessageQueue->createChokeMessage());
}
} else {
if(peer->amChoking) {
PendingMessage pendingMessage(PeerMessage::UNCHOKE, peerConnection);
sendMessageQueue->addPendingMessage(pendingMessage);
sendMessageQueue->addMessage(sendMessageQueue->createUnchokeMessage());
}
}
}
void PeerInteractionCommand::receiveMessage() {
PeerMessage* message = peerConnection->receiveMessage();
PeerMessage* message = sendMessageQueue->receiveMessage();
if(message == NULL) {
return;
}
logger->info(MSG_RECEIVE_PEER_MESSAGE, cuid,
peer->ipaddr.c_str(), peer->port,
message->toString().c_str());
// to detect flooding
switch(message->getId()) {
case KeepAliveMessage::ID:
keepAliveCount++;
break;
case ChokeMessage::ID:
if(!peer->peerChoking) {
chokeUnchokeCount++;
}
break;
case UnchokeMessage::ID:
if(peer->peerChoking) {
chokeUnchokeCount++;
}
break;
case HaveMessage::ID:
haveCount++;
break;
}
try {
switch(message->getId()) {
case PeerMessage::KEEP_ALIVE:
keepAliveCount++;
break;
case PeerMessage::CHOKE:
if(!peer->peerChoking) {
chokeUnchokeCount++;
}
peer->peerChoking = true;
break;
case PeerMessage::UNCHOKE:
if(peer->peerChoking) {
chokeUnchokeCount++;
}
peer->peerChoking = false;
break;
case PeerMessage::INTERESTED:
peer->peerInterested = true;
break;
case PeerMessage::NOT_INTERESTED:
peer->peerInterested = false;
break;
case PeerMessage::HAVE:
haveCount++;
peer->updateBitfield(message->getIndex(), 1);
break;
case PeerMessage::BITFIELD:
peer->setBitfield(message->getBitfield(), message->getBitfieldLength());
break;
case PeerMessage::REQUEST:
if(e->torrentMan->hasPiece(message->getIndex())) {
PendingMessage pendingMessage
= PendingMessage::createPieceMessage(message->getIndex(),
message->getBegin(),
message->getLength(),
e->torrentMan->pieceLength,
peerConnection);
sendMessageQueue->addPendingMessage(pendingMessage);
e->torrentMan->addUploadLength(message->getLength());
e->torrentMan->addDeltaUploadLength(message->getLength());
}
break;
case PeerMessage::CANCEL:
sendMessageQueue->deletePendingPieceMessage(message);
break;
case PeerMessage::PIECE: {
RequestSlot slot = sendMessageQueue->getCorrespoindingRequestSlot(message);
peer->addPeerUpload(message->getBlockLength());
if(!Piece::isNull(piece) && !RequestSlot::isNull(slot)) {
long long int offset =
((long long int)message->getIndex())*e->torrentMan->pieceLength+message->getBegin();
logger->debug("CUID#%d - write block length = %d, offset=%lld",
cuid, message->getBlockLength(), offset);
e->torrentMan->diskAdaptor->writeData(message->getBlock(),
message->getBlockLength(),
offset);
piece.completeBlock(slot.getBlockIndex());
sendMessageQueue->deleteRequestSlot(slot);
e->torrentMan->updatePiece(piece);
logger->debug("CUID#%d - setting piece bit index=%d", cuid,
slot.getBlockIndex());
e->torrentMan->addDeltaDownloadLength(message->getBlockLength());
if(piece.pieceComplete()) {
if(checkPieceHash(piece)) {
onGotNewPiece();
} else {
onGotWrongPiece();
}
}
}
break;
}
}
message->receivedAction();
delete message;
} catch(Exception* ex) {
delete message;
@ -294,20 +229,6 @@ void PeerInteractionCommand::receiveMessage() {
}
}
void PeerInteractionCommand::onGotNewPiece() {
logger->info(MSG_GOT_NEW_PIECE, cuid, piece.getIndex());
e->torrentMan->completePiece(piece);
e->torrentMan->advertisePiece(cuid, piece.getIndex());
piece = Piece::nullPiece;
}
void PeerInteractionCommand::onGotWrongPiece() {
logger->error(MSG_GOT_WRONG_PIECE, cuid, piece.getIndex());
erasePieceOnDisk(piece);
piece.clearAllBlock();
e->torrentMan->updatePiece(piece);
}
// TODO this method removed when PeerBalancerCommand is implemented
bool PeerInteractionCommand::prepareForNextPeer(int wait) {
if(e->torrentMan->isPeerAvailable()) {
@ -315,81 +236,18 @@ bool PeerInteractionCommand::prepareForNextPeer(int wait) {
int newCuid = e->torrentMan->getNewCuid();
peer->cuid = newCuid;
PeerInitiateConnectionCommand* command = new PeerInitiateConnectionCommand(newCuid, peer, e);
e->commands.push(command);
e->commands.push_back(command);
}
return true;
}
bool PeerInteractionCommand::prepareForRetry(int wait) {
e->commands.push(this);
e->commands.push_back(this);
return false;
}
Piece PeerInteractionCommand::getNewPieceAndSendInterest() {
sendMessageQueue->cancelAllRequest();
Piece piece = e->torrentMan->getMissingPiece(peer);
if(Piece::isNull(piece)) {
logger->debug("CUID#%d - try to send not-interested", cuid);
PendingMessage pendingMessage(PeerMessage::NOT_INTERESTED, peerConnection);
sendMessageQueue->addPendingMessage(pendingMessage);
} else {
logger->debug("CUID#%d - starting download for piece index=%d (%d/%d completed)", cuid, piece.getIndex(), piece.countCompleteBlock(), piece.countBlock());
logger->debug("CUID#%d - try to send interested", cuid);
PendingMessage pendingMessage(PeerMessage::INTERESTED, peerConnection);
sendMessageQueue->addPendingMessage(pendingMessage);
}
return piece;
}
void PeerInteractionCommand::sendInterest() {
if(Piece::isNull(piece)) {
// retrive new piece from TorrentMan
piece = getNewPieceAndSendInterest();
} else if(peer->peerChoking) {
sendMessageQueue->cancelAllRequest(piece);
e->torrentMan->cancelPiece(piece);
piece = Piece::nullPiece;
} else if(piece.pieceComplete()) {
piece = getNewPieceAndSendInterest();
}
}
void PeerInteractionCommand::createRequestPendingMessage(int blockIndex) {
PendingMessage pendingMessage =
PendingMessage::createRequestMessage(piece, blockIndex, peerConnection);
sendMessageQueue->addPendingMessage(pendingMessage);
}
void PeerInteractionCommand::sendMessages() {
if(!Piece::isNull(piece) && !peer->peerChoking) {
if(e->torrentMan->isEndGame()) {
BlockIndexes missingBlockIndexes = piece.getAllMissingBlockIndexes();
if(sendMessageQueue->countRequestSlot() == 0) {
random_shuffle(missingBlockIndexes.begin(), missingBlockIndexes.end());
int count = 0;
for(PieceIndexes::const_iterator itr = missingBlockIndexes.begin();
itr != missingBlockIndexes.end() && count < 6; itr++, count++) {
createRequestPendingMessage(*itr);
}
}
} else {
for(int i = sendMessageQueue->countRequestSlot(); i < 6; i++) {
int blockIndex = piece.getMissingUnusedBlockIndex();
if(blockIndex == -1) {
break;
}
e->torrentMan->updatePiece(piece);
createRequestPendingMessage(blockIndex);
}
}
}
sendMessageQueue->send(e->getUploadSpeed());
}
void PeerInteractionCommand::onAbort(Exception* ex) {
sendMessageQueue->cancelAllRequest(piece);
e->torrentMan->cancelPiece(piece);
sendMessageQueue->abortPiece();
PeerAbstractCommand::onAbort(ex);
}
@ -400,8 +258,8 @@ void PeerInteractionCommand::keepAlive() {
struct timeval now;
gettimeofday(&now, NULL);
if(Util::difftv(now, keepAliveCheckPoint) >= (long long int)120*1000000) {
if(sendMessageQueue->countPendingMessage() == 0) {
peerConnection->sendKeepAlive();
if(sendMessageQueue->countMessageInQueue() == 0) {
sendMessageQueue->sendNow(sendMessageQueue->createKeepAliveMessage());
}
keepAliveCheckPoint = now;
}
@ -417,41 +275,12 @@ void PeerInteractionCommand::beforeSocketCheck() {
PieceIndexes indexes = e->torrentMan->getAdvertisedPieceIndexes(cuid);
if(indexes.size() >= 20) {
PendingMessage pendingMessage(PeerMessage::BITFIELD, peerConnection);
sendMessageQueue->addPendingMessage(pendingMessage);
sendMessageQueue->trySendNow(sendMessageQueue->createBitfieldMessage());
} else {
if(sendMessageQueue->countPendingMessage() == 0) {
for(PieceIndexes::iterator itr = indexes.begin(); itr != indexes.end(); itr++) {
peerConnection->sendHave(*itr);
}
} else {
for(PieceIndexes::iterator itr = indexes.begin(); itr != indexes.end(); itr++) {
PendingMessage pendingMessage = PendingMessage::createHaveMessage(*itr, peerConnection);
sendMessageQueue->addPendingMessage(pendingMessage);
}
for(PieceIndexes::iterator itr = indexes.begin(); itr != indexes.end(); itr++) {
sendMessageQueue->trySendNow(sendMessageQueue->createHaveMessage(*itr));
}
}
keepAlive();
}
}
bool PeerInteractionCommand::checkPieceHash(const Piece& piece) {
long long int offset = ((long long int)piece.getIndex())*e->torrentMan->pieceLength;
return e->torrentMan->diskAdaptor->sha1Sum(offset, piece.getLength()) ==
e->torrentMan->getPieceHash(piece.getIndex());
}
void PeerInteractionCommand::erasePieceOnDisk(const Piece& piece) {
int BUFSIZE = 4096;
char buf[BUFSIZE];
memset(buf, 0, BUFSIZE);
long long int offset = ((long long int)piece.getIndex())*e->torrentMan->pieceLength;
for(int i = 0; i < piece.getLength()/BUFSIZE; i++) {
e->torrentMan->diskAdaptor->writeData(buf, BUFSIZE, offset);
offset += BUFSIZE;
}
int r = piece.getLength()%BUFSIZE;
if(r > 0) {
e->torrentMan->diskAdaptor->writeData(buf, r, offset);
}
}

View File

@ -33,9 +33,8 @@ using namespace std;
class PeerInteractionCommand : public PeerAbstractCommand {
private:
int sequence;
PeerConnection* peerConnection;
SendMessageQueue* sendMessageQueue;
Piece piece;
struct timeval keepAliveCheckPoint;
struct timeval chokeCheckPoint;
struct timeval freqCheckPoint;
@ -46,18 +45,9 @@ private:
void detectMessageFlooding();
void checkLongTimePeerChoking();
void checkInactiveConnection();
void syncPiece();
void detectTimeoutAndDuplicateBlock();
void decideChoking();
void sendInterest();
void sendMessages();
void createRequestPendingMessage(int blockIndex);
bool checkPieceHash(const Piece& piece);
void erasePieceOnDisk(const Piece& piece);
void keepAlive();
Piece getNewPieceAndSendInterest();
void onGotNewPiece();
void onGotWrongPiece();
protected:
bool executeInternal();
bool prepareForRetry(int wait);

View File

@ -73,7 +73,7 @@ bool PeerListenCommand::execute() {
PeerInteractionCommand* command =
new PeerInteractionCommand(newCuid, peer, e, peerSocket,
PeerInteractionCommand::RECEIVER_WAIT_HANDSHAKE);
e->commands.push(command);
e->commands.push_back(command);
logger->debug("CUID#%d - incoming connection, adding new command CUID#%d", cuid, newCuid);
} else {
delete peer;
@ -88,6 +88,6 @@ bool PeerListenCommand::execute() {
}
}
}
e->commands.push(this);
e->commands.push_back(this);
return false;
}

View File

@ -20,53 +20,8 @@
*/
/* copyright --> */
#include "PeerMessage.h"
#include "Util.h"
#include "LogFactory.h"
void PeerMessage::setBitfield(const unsigned char* bitfield, int bitfieldLength) {
if(this->bitfield != NULL) {
delete [] this->bitfield;
}
this->bitfieldLength = bitfieldLength;
this->bitfield = new unsigned char[this->bitfieldLength];
memcpy(this->bitfield, bitfield, this->bitfieldLength);
PeerMessage::PeerMessage():inProgress(false) {
logger = LogFactory::getInstance();
}
void PeerMessage::setBlock(const char* block, int blockLength) {
if(this->block != NULL) {
delete [] this->block;
}
this->blockLength = blockLength;
this->block = new char[this->blockLength];
memcpy(this->block, block, this->blockLength);
}
string PeerMessage::toString() const {
switch(id) {
case CHOKE:
return "choke";
case UNCHOKE:
return "unchoke";
case INTERESTED:
return "interested";
case NOT_INTERESTED:
return "not interested";
case HAVE:
return "have index="+Util::itos(index);
case BITFIELD:
return "bitfield "+Util::toHex(bitfield, bitfieldLength);
case REQUEST:
return "request index="+Util::itos(index)+", begin="+Util::itos(begin)+
", length="+Util::itos(length);
case PIECE:
return "piece index="+Util::itos(index)+", begin="+Util::itos(begin)+
", length="+Util::itos(blockLength);
case CANCEL:
return "cancel index="+Util::itos(index)+", begin="+Util::itos(begin)+
", length="+Util::itos(length);
case KEEP_ALIVE:
return "keep alive";
default:
return "unknown";
}
}

View File

@ -23,61 +23,44 @@
#define _D_PEER_MESSAGE_H_
#include "common.h"
#include "Logger.h"
#include "Peer.h"
#include <string>
class SendMessageQueue;
class PeerMessage {
private:
int id;
int index;
int begin;
int length;
unsigned char* bitfield;
int bitfieldLength;
char* block;
int blockLength;
protected:
bool inProgress;
int cuid;
Peer* peer;
SendMessageQueue* sendMessageQueue;
const Logger* logger;
public:
PeerMessage():bitfield(NULL), bitfieldLength(0),
block(NULL), blockLength(0) {}
~PeerMessage() {
if(bitfield != NULL) {
delete [] bitfield;
}
if(block != NULL) {
delete [] block;
}
PeerMessage();
virtual ~PeerMessage() {}
bool isInProgress() const { return inProgress; }
int getCuid() const { return cuid; }
void setCuid(int cuid) {
this->cuid = cuid;
}
Peer* getPeer() const { return this->peer; }
void setPeer(Peer* peer) {
this->peer = peer;
}
SendMessageQueue* getSendMessageQueue() const { return sendMessageQueue; }
void setSendMessageQueue(SendMessageQueue* sendMessageQueue) {
this->sendMessageQueue = sendMessageQueue;
}
void setBitfield(const unsigned char* bitfield, int bitfieldLength);
const unsigned char* getBitfield() const { return bitfield; }
void setBlock(const char* block, int blockLength);
const char* getBlock() const { return block; }
int getBitfieldLength() const { return bitfieldLength; }
int getBlockLength() const { return blockLength; }
string toString() const;
int getId() const { return id; }
void setId(int id) { this->id = id; }
int getIndex() const { return index; }
void setIndex(int index) { this->index = index; }
int getBegin() const { return begin; }
void setBegin(int begin) { this->begin = begin; }
int getLength() const { return length; }
void setLength(int length) { this->length = length; }
enum ID {
CHOKE = 0,
UNCHOKE = 1,
INTERESTED = 2,
NOT_INTERESTED = 3,
HAVE = 4,
BITFIELD = 5,
REQUEST = 6,
PIECE = 7,
CANCEL = 8,
KEEP_ALIVE = 99};
virtual int getId() const = 0;
virtual void receivedAction() = 0;
virtual void send() = 0;
virtual void check() const {}
virtual string toString() const = 0;
};
#endif // _D_PEER_MESSAGE_H_

View File

@ -24,94 +24,6 @@
#include "Util.h"
#include <netinet/in.h>
PeerMessage* PeerMessageUtil::createPeerMessage(const char* msg, int len) {
PeerMessage* peerMessage;
if(len == 0) {
// keep-alive
peerMessage = new PeerMessage();
peerMessage->setId(PeerMessage::KEEP_ALIVE);
return peerMessage;
}
int id = getId(msg);
switch(id) {
case PeerMessage::CHOKE:
case PeerMessage::UNCHOKE:
case PeerMessage::INTERESTED:
case PeerMessage::NOT_INTERESTED:
peerMessage = createBasicMessage(id, msg, len);
break;
case PeerMessage::HAVE:
peerMessage = createHaveMessage(id, msg, len);
break;
case PeerMessage::BITFIELD:
peerMessage = createBitfieldMessage(id, msg, len);
break;
case PeerMessage::REQUEST:
case PeerMessage::CANCEL:
peerMessage = createRequestCancelMessage(id, msg, len);
break;
case PeerMessage::PIECE:
peerMessage = createPieceMessage(id, msg, len);
break;
default:
throw new DlAbortEx("invalid message id. id = %d", id);
}
return peerMessage;
}
PeerMessage* PeerMessageUtil::createBasicMessage(int id, const char* msg, int len) {
if(len != 1) {
throw new DlAbortEx("invalid payload size for ID%d, size = %d. It should be %d", id, len, 1);
}
PeerMessage* peerMessage = new PeerMessage();
peerMessage->setId(id);
return peerMessage;
}
PeerMessage* PeerMessageUtil::createHaveMessage(int id, const char* msg, int len) {
if(len != 5) {
throw new DlAbortEx("invalid payload size for ID%d, size = %d. It should be %d", id, len, 5);
}
PeerMessage* peerMessage = new PeerMessage();
peerMessage->setId(id);
peerMessage->setIndex(getIntParam(msg, 1));
return peerMessage;
}
PeerMessage* PeerMessageUtil::createBitfieldMessage(int id, const char* msg, int len) {
if(len <= 1) {
throw new DlAbortEx("invalid payload size for ID%d, size = %d. It should be greater than %d", id, len, 1);
}
PeerMessage* peerMessage = new PeerMessage();
peerMessage->setId(id);
peerMessage->setBitfield((unsigned char*)msg+1, len-1);
return peerMessage;
}
PeerMessage* PeerMessageUtil::createRequestCancelMessage(int id, const char* msg, int len) {
if(len != 13) {
throw new DlAbortEx("invalid payload size for ID%d, size = %d. It should be %d", id, len, 13);
}
PeerMessage* peerMessage = new PeerMessage();
peerMessage->setId(id);
peerMessage->setIndex(getIntParam(msg, 1));
peerMessage->setBegin(getIntParam(msg, 5));
peerMessage->setLength(getIntParam(msg, 9));
return peerMessage;
}
PeerMessage* PeerMessageUtil::createPieceMessage(int id, const char* msg, int len) {
if(len <= 9) {
throw new DlAbortEx("invalid payload size for ID%d, size = %d. It should be greater than %d", id, len, 9);
}
PeerMessage* peerMessage = new PeerMessage();
peerMessage->setId(id);
peerMessage->setIndex(getIntParam(msg, 1));
peerMessage->setBegin(getIntParam(msg, 5));
peerMessage->setBlock(msg+9, len-9);
return peerMessage;
}
int PeerMessageUtil::getId(const char* msg) {
return (int)msg[0];
}
@ -122,50 +34,145 @@ int PeerMessageUtil::getIntParam(const char* msg, int offset) {
return ntohl(nParam);
}
void PeerMessageUtil::checkIndex(const PeerMessage* message, int pieces) {
if(!(0 <= message->getIndex() && message->getIndex() < pieces)) {
throw new DlAbortEx("invalid index = %d", message->getIndex());
int PeerMessageUtil::getShortIntParam(const char* msg, int offset) {
short int nParam;
memcpy(&nParam, msg+offset, 2);
return ntohs(nParam);
}
ChokeMessage* PeerMessageUtil::createChokeMessage(const char* msg, int len) {
if(len != 1) {
throw new DlAbortEx("invalid payload size for %s, size = %d. It should be %d", "choke", len, 1);
}
ChokeMessage* chokeMessage = new ChokeMessage();
return chokeMessage;
}
UnchokeMessage* PeerMessageUtil::createUnchokeMessage(const char* msg, int len) {
if(len != 1) {
throw new DlAbortEx("invalid payload size for %s, size = %d. It should be %d", "unchoke", len, 1);
}
UnchokeMessage* unchokeMessage = new UnchokeMessage();
return unchokeMessage;
}
InterestedMessage* PeerMessageUtil::createInterestedMessage(const char* msg, int len) {
if(len != 1) {
throw new DlAbortEx("invalid payload size for %s, size = %d. It should be %d", "interested", len, 1);
}
InterestedMessage* interestedMessage = new InterestedMessage();
return interestedMessage;
}
NotInterestedMessage* PeerMessageUtil::createNotInterestedMessage(const char* msg, int len) {
if(len != 1) {
throw new DlAbortEx("invalid payload size for %s, size = %d. It should be %d", "not interested", len, 1);
}
NotInterestedMessage* notInterestedMessage = new NotInterestedMessage();
return notInterestedMessage;
}
HaveMessage* PeerMessageUtil::createHaveMessage(const char* msg, int len) {
if(len != 5) {
throw new DlAbortEx("invalid payload size for %s, size = %d. It should be %d", "have", len, 5);
}
HaveMessage* haveMessage = new HaveMessage();
haveMessage->setIndex(getIntParam(msg, 1));
return haveMessage;
}
BitfieldMessage* PeerMessageUtil::createBitfieldMessage(const char* msg, int len) {
if(len <= 1) {
throw new DlAbortEx("invalid payload size for %s, size = %d. It should be greater than %d", "bitfield", len, 1);
}
BitfieldMessage* bitfieldMessage = new BitfieldMessage();
bitfieldMessage->setBitfield((unsigned char*)msg+1, len-1);
return bitfieldMessage;
}
RequestMessage* PeerMessageUtil::createRequestMessage(const char* msg, int len) {
if(len != 13) {
throw new DlAbortEx("invalid payload size for %s, size = %d. It should be %d", "request", len, 13);
}
RequestMessage* requestMessage = new RequestMessage();
requestMessage->setIndex(getIntParam(msg, 1));
requestMessage->setBegin(getIntParam(msg, 5));
requestMessage->setLength(getIntParam(msg, 9));
return requestMessage;
}
CancelMessage* PeerMessageUtil::createCancelMessage(const char* msg, int len) {
if(len != 13) {
throw new DlAbortEx("invalid payload size for %s, size = %d. It should be %d", "cancel", len, 13);
}
CancelMessage* cancelMessage = new CancelMessage();
cancelMessage->setIndex(getIntParam(msg, 1));
cancelMessage->setBegin(getIntParam(msg, 5));
cancelMessage->setLength(getIntParam(msg, 9));
return cancelMessage;
}
PieceMessage* PeerMessageUtil::createPieceMessage(const char* msg, int len) {
if(len <= 9) {
throw new DlAbortEx("invalid payload size for %s, size = %d. It should be greater than %d", "piece", len, 9);
}
PieceMessage* pieceMessage = new PieceMessage();
pieceMessage->setIndex(getIntParam(msg, 1));
pieceMessage->setBegin(getIntParam(msg, 5));
pieceMessage->setBlock(msg+9, len-9);
return pieceMessage;
}
PortMessage* PeerMessageUtil::createPortMessage(const char* msg, int len) {
if(len != 3) {
throw new DlAbortEx("invalid payload size for %s, size = %d. It should be %d", "port", len, 3);
}
PortMessage* portMessage = new PortMessage();
portMessage->setPort(getShortIntParam(msg, 1));
return portMessage;
}
void PeerMessageUtil::checkIndex(int index, int pieces) {
if(!(0 <= index && index < pieces)) {
throw new DlAbortEx("invalid index = %d", index);
}
}
void PeerMessageUtil::checkBegin(const PeerMessage* message, int pieceLength) {
if(!(0 <= message->getBegin() && message->getBegin() < pieceLength)) {
throw new DlAbortEx("invalid begin = %d", message->getBegin());
}
void PeerMessageUtil::checkBegin(int begin, int pieceLength) {
if(!(0 <= begin && begin < pieceLength)) {
throw new DlAbortEx("invalid begin = %d", begin);
}
}
void PeerMessageUtil::checkPieceOffset(const PeerMessage* message, int pieceLength, int pieces, long long int totalLength) {
if(!(0 <= message->getBegin() && 0 < message->getLength())) {
throw new DlAbortEx("invalid offset, begin = %d, length = %d", message->getBegin(), message->getLength());
}
int offset = message->getBegin()+message->getLength();
int currentPieceLength;
if(message->getIndex()+1 == pieces) {
currentPieceLength = pieceLength-(pieces*pieceLength-totalLength);
} else {
currentPieceLength = pieceLength;
}
if(!(0 < offset && offset <= currentPieceLength)) {
throw new DlAbortEx("invalid offset, begin = %d, length = %d", message->getBegin(), message->getLength());
}
}
void PeerMessageUtil::checkLength(const PeerMessage* message) {
if(message->getLength() > MAX_BLOCK_LENGTH) {
throw new DlAbortEx("too large length %d > %dKB", message->getLength(),
void PeerMessageUtil::checkLength(int length) {
if(length > MAX_BLOCK_LENGTH) {
throw new DlAbortEx("too large length %d > %dKB", length,
MAX_BLOCK_LENGTH/1024);
}
if(!Util::isPowerOf(message->getLength(), 2)) {
if(!Util::isPowerOf(length, 2)) {
throw new DlAbortEx("invalid length %d, which is not power of 2",
message->getLength());
length);
}
}
void PeerMessageUtil::checkBitfield(const PeerMessage* message, int pieces) {
if(!(message->getBitfieldLength() == BITFIELD_LEN_FROM_PIECES(pieces))) {
throw new DlAbortEx("invalid bitfield length = %d", message->getBitfieldLength());
void PeerMessageUtil::checkRange(int begin, int length, int pieceLength) {
if(!(0 <= begin && 0 < length)) {
throw new DlAbortEx("invalid range, begin = %d, length = %d",
begin, length);
}
char lastbyte = message->getBitfield()[message->getBitfieldLength()-1];
int end = begin+length;
if(!(0 < end && end <= pieceLength)) {
throw new DlAbortEx("invalid range, begin = %d, length = %d",
begin, length);
}
}
void PeerMessageUtil::checkBitfield(const unsigned char* bitfield, int bitfieldLength, int pieces) {
if(!(bitfieldLength == BITFIELD_LEN_FROM_PIECES(pieces))) {
throw new DlAbortEx("invalid bitfield length = %d",
bitfieldLength);
}
char lastbyte = bitfield[bitfieldLength-1];
for(int i = 0; i < 8-pieces%8 && pieces%8 != 0; i++) {
if(!(((lastbyte >> i) & 1) == 0)) {
throw new DlAbortEx("invalid bitfield");
@ -173,42 +180,7 @@ void PeerMessageUtil::checkBitfield(const PeerMessage* message, int pieces) {
}
}
void PeerMessageUtil::checkIntegrity(const PeerMessage* message, int pieceLength, int pieces, long long int totalLength) {
// 0 <= index < pieces
// 0 <= begin < pieceLength
// 0 < begin+length <= pieceLength
// len of bitfield == pieces/8+(pieces%8 ? 1 : 0)
// for(int i = 0; i < 8-pieces%8; i++) { ((lastbyteofbitfield >> i) & 1) == 0 }
switch(message->getId()) {
case PeerMessage::KEEP_ALIVE:
case PeerMessage::CHOKE:
case PeerMessage::UNCHOKE:
case PeerMessage::INTERESTED:
case PeerMessage::NOT_INTERESTED:
break;
case PeerMessage::HAVE:
checkIndex(message, pieces);
break;
case PeerMessage::BITFIELD:
checkBitfield(message, pieces);
break;
case PeerMessage::REQUEST:
case PeerMessage::CANCEL:
checkIndex(message, pieces);
checkBegin(message, pieceLength);
checkLength(message);
checkPieceOffset(message, pieceLength, pieces, totalLength);
break;
case PeerMessage::PIECE:
checkIndex(message, pieces);
checkBegin(message, pieceLength);
break;
default:
throw new DlAbortEx("invalid message id. id = %d", message->getId());
}
}
HandshakeMessage* PeerMessageUtil::createHandshakeMessage(const char* msg) {
HandshakeMessage* PeerMessageUtil::createHandshakeMessage(const char* msg, int length) {
HandshakeMessage* message = new HandshakeMessage();
message->pstrlen = msg[0];
char pstr[20];
@ -220,6 +192,7 @@ HandshakeMessage* PeerMessageUtil::createHandshakeMessage(const char* msg) {
return message;
}
void PeerMessageUtil::checkHandshake(const HandshakeMessage* message, const unsigned char* infoHash) {
if(message->pstrlen != 19) {
throw new DlAbortEx("invalid handshake pstrlen = %d", (int)message->pstrlen);
@ -234,3 +207,4 @@ void PeerMessageUtil::checkHandshake(const HandshakeMessage* message, const unsi
myInfoHash.c_str(), peerInfoHash.c_str());
}
}

View File

@ -22,6 +22,18 @@
#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 "PeerConnection.h"
#define MAX_BLOCK_LENGTH (128*1024)
@ -30,23 +42,29 @@ class PeerMessageUtil {
private:
PeerMessageUtil() {}
static PeerMessage* createBasicMessage(int id, const char* msg, int len);
static PeerMessage* createHaveMessage(int id, const char* msg, int len);
static PeerMessage* createBitfieldMessage(int id, const char* msg, int len);
static PeerMessage* createRequestCancelMessage(int id, const char* msg, int len);
static PeerMessage* createPieceMessage(int id, const char* msg, int len);
static int getId(const char* msg);
static int getIntParam(const char* msg, int offset);
static void checkIndex(const PeerMessage* message, int pieces);
static void checkBegin(const PeerMessage* message, int pieceLength);
static void checkLength(const PeerMessage* message);
static void checkPieceOffset(const PeerMessage* message, int pieceLength, int pieces, long long int totalLength);
static void checkBitfield(const PeerMessage* message, int pieces);
static int getShortIntParam(const char* msg, int offset);
public:
static PeerMessage* createPeerMessage(const char* msg, int len);
static void checkIntegrity(const PeerMessage* message, int pieceLength, int pieces, long long int totalLength);
static HandshakeMessage* createHandshakeMessage(const char* msg);
static int getId(const char* msg);
static ChokeMessage* createChokeMessage(const char* msg, int len);
static UnchokeMessage* createUnchokeMessage(const char* msg, int len);
static InterestedMessage* createInterestedMessage(const char* msg, int len);
static NotInterestedMessage* createNotInterestedMessage(const char* msg, int len);
static HaveMessage* createHaveMessage(const char* msg, int len);
static BitfieldMessage* createBitfieldMessage(const char* msg, int len);
static RequestMessage* createRequestMessage(const char* msg, int len);
static CancelMessage* createCancelMessage(const char* msg, int len);
static PieceMessage* createPieceMessage(const char* msg, int len);
static PortMessage* createPortMessage(const char* msg, int len);
static void checkIndex(int index, int pieces);
static void checkBegin(int begin, int pieceLength);
static void checkLength(int length);
static void checkRange(int begin, int length, int pieceLength);
static void checkBitfield(const unsigned char* bitfield, int bitfieldLength, int pieces);
static HandshakeMessage* createHandshakeMessage(const char* msg, int length);
static void checkHandshake(const HandshakeMessage* message, const unsigned char* infoHash);
};

View File

@ -1,124 +0,0 @@
/* <!-- 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 "PendingMessage.h"
bool PendingMessage::processMessage() {
bool retval = true;
switch(peerMessageId) {
case PeerMessage::HAVE:
if(!peerConnection->getPeer()->hasPiece(index)) {
peerConnection->sendHave(index);
}
break;
case PeerMessage::BITFIELD:
peerConnection->sendBitfield();
break;
case PeerMessage::UNCHOKE:
if(peerConnection->getPeer()->amChoking) {
peerConnection->sendUnchoke();
peerConnection->getPeer()->amChoking = false;
}
break;
case PeerMessage::CHOKE:
if(!peerConnection->getPeer()->amChoking) {
peerConnection->sendChoke();
peerConnection->getPeer()->amChoking = true;
}
break;
case PeerMessage::NOT_INTERESTED:
if(peerConnection->getPeer()->amInterested) {
peerConnection->sendNotInterested();
peerConnection->getPeer()->amInterested = false;
}
break;
case PeerMessage::INTERESTED:
if(!peerConnection->getPeer()->amInterested) {
peerConnection->sendInterested();
peerConnection->getPeer()->amInterested = true;
}
break;
case PeerMessage::PIECE:
if((!peerConnection->getPeer()->amChoking &&
peerConnection->getPeer()->peerInterested) || inProgress) {
if(!inProgress) {
peerConnection->sendPieceHeader(index, begin, length);
peerConnection->getPeer()->addPeerDownload(length);
}
inProgress = false;
int writtenLength = peerConnection->sendPieceData(pieceDataOffset, leftPieceDataLength);
if(writtenLength != leftPieceDataLength) {
inProgress = true;
leftPieceDataLength -= writtenLength;
pieceDataOffset += writtenLength;
retval = false;
}
}
break;
case PeerMessage::REQUEST:
if(!peerConnection->getPeer()->peerChoking) {
peerConnection->sendRequest(index, begin, length);
}
break;
case PeerMessage::CANCEL:
peerConnection->sendCancel(index, begin, length);
break;
default:
break;
}
return retval;
}
PendingMessage PendingMessage::createRequestMessage(const Piece& piece,
int blockIndex,
PeerConnection* peerConnection) {
PendingMessage pendingMessage(PeerMessage::REQUEST, peerConnection);
pendingMessage.setIndex(piece.getIndex());
pendingMessage.setBegin(blockIndex*piece.getBlockLength());
pendingMessage.setLength(piece.getBlockLength(blockIndex));
pendingMessage.setBlockIndex(blockIndex);
return pendingMessage;
}
PendingMessage PendingMessage::createCancelMessage(int index, int begin, int length, PeerConnection* peerConnection) {
PendingMessage pendingMessage(PeerMessage::CANCEL, peerConnection);
pendingMessage.setIndex(index);
pendingMessage.setBegin(begin);
pendingMessage.setLength(length);
return pendingMessage;
}
PendingMessage PendingMessage::createPieceMessage(int index, int begin, int length, int pieceLength, PeerConnection* peerConnection) {
PendingMessage pendingMessage(PeerMessage::PIECE, peerConnection);
pendingMessage.setIndex(index);
pendingMessage.setBegin(begin);
pendingMessage.setLength(length);
pendingMessage.setPieceDataOffset(((long long int)index)*pieceLength+begin);
pendingMessage.setLeftPieceDataLength(length);
return pendingMessage;
}
PendingMessage PendingMessage::createHaveMessage(int index, PeerConnection* peerConnection) {
PendingMessage pendingMessage(PeerMessage::HAVE, peerConnection);
pendingMessage.setIndex(index);
return pendingMessage;
}

View File

@ -1,74 +0,0 @@
/* <!-- 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_PENDING_MESSAGE_H_
#define _D_PENDING_MESSAGE_H_
#include "common.h"
#include "PeerConnection.h"
#include <deque>
class PendingMessage {
private:
int peerMessageId;
int index;
int begin;
int length;
int blockIndex;
long long int pieceDataOffset;
int leftPieceDataLength;
bool inProgress;
PeerConnection* peerConnection;
public:
PendingMessage(int peerMessageId, PeerConnection* peerConnection):peerMessageId(peerMessageId), inProgress(false), peerConnection(peerConnection) {}
~PendingMessage() {}
void setPeerMessageId(int peerMessageId) { this->peerMessageId = peerMessageId; }
int getPeerMessageId() const { return peerMessageId; }
void setPieceDataOffset(long long int offset) { this->pieceDataOffset = offset; }
long long int getPieceDataOffset() const { return pieceDataOffset; }
void setLeftPieceDataLength(int length) { this->leftPieceDataLength = length; }
int getLeftPieceDataLength() const { return leftPieceDataLength; }
void setInProgress(bool inprogress) { this->inProgress = inProgress; }
bool isInProgress() const { return inProgress; }
void setIndex(int index) { this->index = index; }
int getIndex() const { return index; }
void setBegin(int begin) { this->begin = begin; }
int getBegin() const { return begin; }
void setLength(int length) { this->length = length; }
int getLength() const { return length; }
void setBlockIndex(int blockIndex) { this->blockIndex = blockIndex; }
int getBlockIndex() const { return blockIndex; }
bool processMessage();
static PendingMessage createRequestMessage(const Piece& piece, int blockIndex, PeerConnection* peerConnection);
static PendingMessage createCancelMessage(int index, int begin, int length, PeerConnection* peerConnection);
static PendingMessage createPieceMessage(int index, int begin, int length, int pieceLength, PeerConnection* peerConnection);
static PendingMessage createHaveMessage(int index, PeerConnection* peerConnectioin);
};
typedef deque<PendingMessage> PendingMessages;
#endif // _D_PENDING_MESSAGE_H_

137
src/PieceMessage.cc Normal file
View File

@ -0,0 +1,137 @@
/* <!-- 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 "PieceMessage.h"
#include "PeerMessageUtil.h"
#include "SendMessageQueue.h"
#include "Util.h"
#include "message.h"
void PieceMessage::setBlock(const char* block, int blockLength) {
if(this->block != NULL) {
delete [] this->block;
}
this->blockLength = blockLength;
this->block = new char[this->blockLength];
memcpy(this->block, block, this->blockLength);
}
void PieceMessage::receivedAction() {
TorrentMan* torrentMan = sendMessageQueue->getTorrentMan();
RequestSlot slot = sendMessageQueue->getCorrespondingRequestSlot(this);
peer->addPeerUpload(blockLength);
if(sendMessageQueue->hasDownloadPiece() &&
!RequestSlot::isNull(slot)) {
Piece& piece = sendMessageQueue->getDownloadPiece();
long long int offset =
((long long int)index)*torrentMan->pieceLength+begin;
logger->debug("CUID#%d - write block length = %d, offset=%lld",
cuid, blockLength, offset);
torrentMan->diskAdaptor->writeData(block,
blockLength,
offset);
piece.completeBlock(slot.getBlockIndex());
sendMessageQueue->deleteRequestSlot(slot);
torrentMan->updatePiece(piece);
logger->debug("CUID#%d - setting piece bit index=%d",
cuid, slot.getBlockIndex());
torrentMan->addDeltaDownloadLength(blockLength);
if(piece.pieceComplete()) {
if(checkPieceHash(piece)) {
onGotNewPiece(piece);
} else {
onGotWrongPiece(piece);
}
}
}
}
void PieceMessage::send() {
if((!peer->amChoking && peer->peerInterested) || inProgress) {
PeerConnection* peerConnection = sendMessageQueue->getPeerConnection();
if(!inProgress) {
peerConnection->sendPieceHeader(index, begin, blockLength);
peer->addPeerDownload(blockLength);
leftPieceDataLength = blockLength;
}
inProgress = false;
int pieceLength = sendMessageQueue->getTorrentMan()->pieceLength;
long long int pieceDataOffset =
((long long int)index)*pieceLength+begin+blockLength-leftPieceDataLength;
int writtenLength =
peerConnection->sendPieceData(pieceDataOffset, leftPieceDataLength);
if(writtenLength != leftPieceDataLength) {
inProgress = true;
leftPieceDataLength -= writtenLength;
}
}
}
void PieceMessage::check() const {
PeerMessageUtil::checkIndex(index, pieces);
PeerMessageUtil::checkBegin(begin, pieceLength);
}
string PieceMessage::toString() const {
return "piece index="+Util::itos(index)+", begin="+Util::itos(begin)+
", length="+Util::itos(blockLength);
}
bool PieceMessage::checkPieceHash(const Piece& piece) {
TorrentMan* torrentMan = sendMessageQueue->getTorrentMan();
long long int offset =
((long long int)piece.getIndex())*torrentMan->pieceLength;
return torrentMan->diskAdaptor->sha1Sum(offset, piece.getLength()) ==
torrentMan->getPieceHash(piece.getIndex());
}
void PieceMessage::onGotNewPiece(Piece& piece) {
TorrentMan* torrentMan = sendMessageQueue->getTorrentMan();
logger->info(MSG_GOT_NEW_PIECE, cuid, piece.getIndex());
torrentMan->completePiece(piece);
torrentMan->advertisePiece(cuid, piece.getIndex());
piece = Piece::nullPiece;
}
void PieceMessage::onGotWrongPiece(Piece& piece) {
TorrentMan* torrentMan = sendMessageQueue->getTorrentMan();
logger->error(MSG_GOT_WRONG_PIECE, cuid, piece.getIndex());
erasePieceOnDisk(piece);
piece.clearAllBlock();
torrentMan->updatePiece(piece);
}
void PieceMessage::erasePieceOnDisk(const Piece& piece) {
TorrentMan* torrentMan = sendMessageQueue->getTorrentMan();
int BUFSIZE = 4096;
char buf[BUFSIZE];
memset(buf, 0, BUFSIZE);
long long int offset = ((long long int)piece.getIndex())*torrentMan->pieceLength;
for(int i = 0; i < piece.getLength()/BUFSIZE; i++) {
torrentMan->diskAdaptor->writeData(buf, BUFSIZE, offset);
offset += BUFSIZE;
}
int r = piece.getLength()%BUFSIZE;
if(r > 0) {
torrentMan->diskAdaptor->writeData(buf, r, offset);
}
}

87
src/PieceMessage.h Normal file
View File

@ -0,0 +1,87 @@
/* <!-- 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_PIECE_MESSAGE_H_
#define _D_PIECE_MESSAGE_H_
#include "PeerMessage.h"
#include "TorrentMan.h"
class SendMessageQueue;
class PieceMessage : public PeerMessage {
private:
int index;
int begin;
char* block;
int blockLength;
int leftPieceDataLength;
// for check
int pieces;
int pieceLength;
bool checkPieceHash(const Piece& piece);
void onGotNewPiece(Piece& piece);
void onGotWrongPiece(Piece& piece);
void erasePieceOnDisk(const Piece& piece);
public:
PieceMessage():PeerMessage(),
index(0), begin(0), block(NULL), blockLength(0),
leftPieceDataLength(0),
pieces(0), pieceLength(0) {}
virtual ~PieceMessage() {
if(block != NULL) {
delete [] block;
}
}
enum ID {
ID = 7
};
int getIndex() const { return index; }
void setIndex(int index) { this->index = index; }
int getBegin() const { return begin; }
void setBegin(int begin) { this->begin = begin; }
const char* getBlock() const { return block; }
void setBlock(const char* block, int blockLength);
int getBlockLength() const { return blockLength; }
void setBlockLength(int blockLength) { this->blockLength = blockLength; }
void setPieces(int pieces) {
this->pieces = pieces;
}
int getPieces() const { return pieces;}
void setPieceLength(int pieceLength) {
this->pieceLength = pieceLength;
}
int getPieceLength() const { return pieceLength;}
virtual int getId() const { return ID; }
virtual void receivedAction();
virtual void send();
virtual void check() const;
virtual string toString() const;
};
#endif // _D_PIECE_MESSAGE_H_

52
src/PortMessage.h Normal file
View File

@ -0,0 +1,52 @@
/* <!-- 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_PORT_MESSAGE_H_
#define _D_PORT_MESSAGE_H_
#include "PeerMessage.h"
class PortMessage : public PeerMessage {
private:
int port;
public:
PortMessage():PeerMessage() {}
virtual ~PortMessage() {}
enum ID {
ID = 9
};
int getPort() const { return port; }
void setPort(int port) { this->port = port; }
virtual int getId() const { return ID; }
virtual void receivedAction() {
logger->info("no DHT support right now.");
}
virtual void send() {}
virtual string toString() const {
return "port";
}
};
#endif // _D_PORT_MESSAGE_H_

52
src/RequestMessage.cc Normal file
View File

@ -0,0 +1,52 @@
/* <!-- 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 "RequestMessage.h"
#include "SendMessageQueue.h"
#include "PeerMessageUtil.h"
#include "Util.h"
void RequestMessage::receivedAction() {
TorrentMan* torrentMan = sendMessageQueue->getTorrentMan();
if(torrentMan->hasPiece(index)) {
sendMessageQueue->addMessage(sendMessageQueue->createPieceMessage(index, begin, length));
torrentMan->addUploadLength(length);
torrentMan->addDeltaUploadLength(length);
}
}
void RequestMessage::send() {
if(!peer->peerChoking) {
sendMessageQueue->getPeerConnection()->sendRequest(index, begin, length);
}
}
void RequestMessage::check() const {
PeerMessageUtil::checkIndex(index, pieces);
PeerMessageUtil::checkBegin(begin, pieceLength);
PeerMessageUtil::checkLength(length);
PeerMessageUtil::checkRange(begin, length, pieceLength);
}
string RequestMessage::toString() const {
return "request index="+Util::itos(index)+", begin="+Util::itos(begin)+
", length="+Util::itos(length);
}

73
src/RequestMessage.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_REQUEST_MESSAGE_H_
#define _D_REQUEST_MESSAGE_H_
#include "PeerMessage.h"
#include "TorrentMan.h"
class RequestMessage : public PeerMessage {
private:
int index;
int begin;
int length;
int blockIndex;
// for check
int pieces;
int pieceLength;
public:
RequestMessage():PeerMessage(),
index(0), begin(0), length(0), blockIndex(0),
pieces(0), pieceLength(0) {}
virtual ~RequestMessage() {}
enum ID {
ID = 6
};
int getIndex() const { return index; }
void setIndex(int index) { this->index = index; }
int getBegin() const { return begin; }
void setBegin(int begin) { this->begin = begin; }
int getLength() const { return length; }
void setLength(int length) { this->length = length; }
int getBlockIndex() const { return blockIndex; }
void setBlockIndex(int blockIndex) { this->blockIndex = blockIndex; }
void setPieces(int pieces) {
this->pieces = pieces;
}
int getPieces() const { return pieces;}
void setPieceLength(int pieceLength) {
this->pieceLength = pieceLength;
}
int getPieceLength() const { return pieceLength;}
virtual int getId() const { return ID; }
virtual void receivedAction();
virtual void send();
virtual void check() const;
virtual string toString() const;
};
#endif // _D_REQUEST_MESSAGE_H_

View File

@ -1,112 +0,0 @@
/* <!-- 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 "RequestSlotMan.h"
#include "LogFactory.h"
RequestSlotMan::RequestSlotMan(int cuid,
PendingMessages* pendingMessages,
PeerConnection* peerConnection,
TorrentMan* torrentMan):
cuid(cuid),
timeout(DEFAULT_TIME_OUT),
pendingMessages(pendingMessages),
peerConnection(peerConnection),
torrentMan(torrentMan) {
logger = LogFactory::getInstance();
}
void RequestSlotMan::addRequestSlot(const RequestSlot& requestSlot) {
requestSlots.push_back(requestSlot);
}
void RequestSlotMan::deleteRequestSlot(const RequestSlot& requestSlot) {
for(RequestSlots::iterator itr = requestSlots.begin();
itr != requestSlots.end(); itr++) {
if(*itr == requestSlot) {
requestSlots.erase(itr);
break;
}
}
}
void RequestSlotMan::deleteAllRequestSlot(Piece& piece) {
if(!Piece::isNull(piece)) {
for(RequestSlots::const_iterator itr = requestSlots.begin();
itr != requestSlots.end(); itr++) {
if(itr->getIndex() == piece.getIndex()) {
piece.cancelBlock(itr->getBlockIndex());
}
}
torrentMan->updatePiece(piece);
}
requestSlots.clear();
}
void RequestSlotMan::deleteTimeoutRequestSlot(Piece& piece) {
for(RequestSlots::iterator itr = requestSlots.begin();
itr != requestSlots.end();) {
if(itr->isTimeout(timeout)) {
logger->debug("CUID#%d - deleting requestslot blockIndex %d because of time out", cuid,
itr->getBlockIndex());
if(!Piece::isNull(piece)) {
piece.cancelBlock(itr->getBlockIndex());
}
itr = requestSlots.erase(itr);
} else {
itr++;
}
}
torrentMan->updatePiece(piece);
}
void RequestSlotMan::deleteCompletedRequestSlot(const Piece& piece) {
for(RequestSlots::iterator itr = requestSlots.begin();
itr != requestSlots.end();) {
if(Piece::isNull(piece) || piece.hasBlock(itr->getBlockIndex()) ||
torrentMan->hasPiece(piece.getIndex())) {
logger->debug("CUID#%d - deleting requestslot blockIndex %d because the block is already acquired.", cuid,
itr->getBlockIndex());
PendingMessage pendingMessage =
PendingMessage::createCancelMessage(itr->getIndex(),
itr->getBegin(),
itr->getLength(),
peerConnection);
pendingMessages->push_back(pendingMessage);
itr = requestSlots.erase(itr);
} else {
itr++;
}
}
}
RequestSlot RequestSlotMan::getCorrespoindingRequestSlot(const PeerMessage* pieceMessage) const {
for(RequestSlots::const_iterator itr = requestSlots.begin();
itr != requestSlots.end(); itr++) {
const RequestSlot& slot = *itr;
if(slot.getIndex() == pieceMessage->getIndex() &&
slot.getBegin() == pieceMessage->getBegin() &&
slot.getLength() == pieceMessage->getBlockLength()) {
return slot;
}
}
return RequestSlot::nullSlot;
}

View File

@ -1,69 +0,0 @@
/* <!-- 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_REQUEST_SLOT_MAN_H_
#define _D_REQUEST_SLOT_MAN_H_
#include "RequestSlot.h"
#include "common.h"
#include "PeerMessage.h"
#include "Logger.h"
#include "PeerConnection.h"
#include "PendingMessage.h"
#include "TorrentMan.h"
#include <deque>
#define DEFAULT_TIME_OUT 120
typedef deque<RequestSlot> RequestSlots;
class RequestSlotMan {
private:
int cuid;
RequestSlots requestSlots;
int timeout;
PendingMessages* pendingMessages;
PeerConnection* peerConnection;
TorrentMan* torrentMan;
const Logger* logger;
public:
RequestSlotMan(int cuid,
PendingMessages* pendingMessages,
PeerConnection* peerConnection,
TorrentMan* torrentMan);
~RequestSlotMan() {}
void addRequestSlot(const RequestSlot& requestSlot);
void deleteRequestSlot(const RequestSlot& requestSlot);
void deleteAllRequestSlot(Piece& piece);
void deleteTimeoutRequestSlot(Piece& piece);
void deleteCompletedRequestSlot(const Piece& piece);
RequestSlot getCorrespoindingRequestSlot(const PeerMessage* pieceMessage) const;
bool isEmpty() { return requestSlots.empty(); }
int countRequestSlot() const { return requestSlots.size(); }
void setTimeout(int timeout) { this->timeout = timeout; }
int getTimeout() const { return timeout; }
};
#endif // _D_REQUEST_SLOT_MAN_H_

View File

@ -31,11 +31,23 @@
#include <unistd.h>
#include <errno.h>
SegmentMan::SegmentMan():totalSize(0),isSplittable(true),downloadStarted(false),dir(".") {
SegmentMan::SegmentMan():totalSize(0),
isSplittable(true),
downloadStarted(false),
dir("."),
splitter(NULL),
diskWriter(NULL) {
logger = LogFactory::getInstance();
}
SegmentMan::~SegmentMan() {}
SegmentMan::~SegmentMan() {
if(splitter != NULL) {
delete splitter;
}
if(diskWriter != NULL) {
delete diskWriter;
}
}
void SegmentMan::unregisterId(int cuid) {
for(Segments::iterator itr = segments.begin(); itr != segments.end(); itr++) {

View File

@ -21,94 +21,172 @@
/* copyright --> */
#include "SendMessageQueue.h"
#include "LogFactory.h"
#include "DlAbortEx.h"
#include "KeepAliveMessage.h"
#include "PeerMessageUtil.h"
#include <netinet/in.h>
SendMessageQueue::SendMessageQueue(int cuid, PeerConnection* peerConnection,
TorrentMan* torrentMan)
:cuid(cuid), uploadLimit(0) {
requestSlotMan = new RequestSlotMan(cuid, &pendingMessages, peerConnection,
torrentMan);
SendMessageQueue::SendMessageQueue(int cuid,
const Socket* socket,
const Option* op,
TorrentMan* torrentMan,
Peer* peer)
:cuid(cuid),
uploadLimit(0),
torrentMan(torrentMan),
peer(peer),
piece(Piece::nullPiece) {
peerConnection = new PeerConnection(cuid, socket, op, peer, this->torrentMan);
logger = LogFactory::getInstance();
}
SendMessageQueue::~SendMessageQueue() {
delete requestSlotMan;
delete peerConnection;
for_each(messageQueue.begin(), messageQueue.end(), Deleter());
}
void SendMessageQueue::send(int uploadSpeed) {
int size = pendingMessages.size();
int size = messageQueue.size();
for(int i = 0; i < size; i++) {
PendingMessage msg = pendingMessages.front();
pendingMessages.pop_front();
if(uploadLimit != 0 && uploadSpeed >= uploadLimit*1024 &&
msg.getPeerMessageId() == PeerMessage::PIECE && !msg.isInProgress()) {
pendingMessages.push_back(msg);
PeerMessage* msg = messageQueue.front();
messageQueue.pop_front();
if(uploadLimit != 0 && uploadLimit*1024 <= uploadSpeed &&
msg->getId() == PieceMessage::ID && !msg->isInProgress()) {
messageQueue.push_back(msg);
} else {
if(!msg.processMessage()) {
pendingMessages.push_front(msg);
try {
msg->send();
} catch(Exception* ex) {
delete msg;
throw;
}
if(msg->isInProgress()) {
messageQueue.push_front(msg);
break;
} else {
delete msg;
}
}
}
}
void SendMessageQueue::addPendingMessage(const PendingMessage& pendingMessage) {
pendingMessages.push_back(pendingMessage);
if(pendingMessage.getPeerMessageId() == PeerMessage::REQUEST) {
RequestSlot requestSlot(pendingMessage.getIndex(),
pendingMessage.getBegin(),
pendingMessage.getLength(),
pendingMessage.getBlockIndex());
requestSlotMan->addRequestSlot(requestSlot);
void SendMessageQueue::addMessage(PeerMessage* peerMessage) {
messageQueue.push_back(peerMessage);
if(peerMessage->getId() == RequestMessage::ID) {
RequestMessage* requestMessage = (RequestMessage*)peerMessage;
RequestSlot requestSlot(requestMessage->getIndex(),
requestMessage->getBegin(),
requestMessage->getLength(),
requestMessage->getBlockIndex());
requestSlots.push_back(requestSlot);
}
}
void SendMessageQueue::deletePendingPieceMessage(const PeerMessage* cancelMessage) {
for(PendingMessages::iterator itr = pendingMessages.begin();
itr != pendingMessages.end();) {
PendingMessage& pendingMessage = *itr;
if(pendingMessage.getPeerMessageId() == PeerMessage::PIECE &&
pendingMessage.getIndex() == cancelMessage->getIndex() &&
pendingMessage.getBegin() == cancelMessage->getBegin() &&
pendingMessage.getLength() == cancelMessage->getLength() &&
!pendingMessage.isInProgress()) {
logger->debug("CUID#%d - deleting pending piece message because cancel message received. index=%d, begin=%d, length=%d",
cuid,
pendingMessage.getIndex(),
pendingMessage.getBegin(),
pendingMessage.getLength());
itr = pendingMessages.erase(itr);
void SendMessageQueue::deletePieceMessageInQueue(const CancelMessage* cancelMessage) {
for(MessageQueue::iterator itr = messageQueue.begin();
itr != messageQueue.end();) {
if((*itr)->getId() == PieceMessage::ID) {
PieceMessage* pieceMessage = (PieceMessage*)*itr;
if(pieceMessage->getIndex() == cancelMessage->getIndex() &&
pieceMessage->getBegin() == cancelMessage->getBegin() &&
pieceMessage->getBlockLength() == cancelMessage->getLength() &&
!pieceMessage->isInProgress()) {
logger->debug("CUID#%d - deleting piece message in queue because cancel message received. index=%d, begin=%d, length=%d",
cuid,
cancelMessage->getIndex(),
cancelMessage->getBegin(),
cancelMessage->getLength());
delete pieceMessage;
itr = messageQueue.erase(itr);
} else {
itr++;
}
} else {
itr++;
}
}
}
void SendMessageQueue::deletePendingRequestMessage() {
for(PendingMessages::iterator itr = pendingMessages.begin();
itr != pendingMessages.end();) {
PendingMessage& pendingMessage = *itr;
if(pendingMessage.getPeerMessageId() == PeerMessage::REQUEST) {
itr = pendingMessages.erase(itr);
void SendMessageQueue::deleteRequestMessageInQueue() {
for(MessageQueue::iterator itr = messageQueue.begin();
itr != messageQueue.end();) {
if((*itr)->getId() == RequestMessage::ID) {
delete *itr;
itr = messageQueue.erase(itr);
} else {
itr++;
}
}
}
}
void SendMessageQueue::deleteRequestSlot(const RequestSlot& requestSlot) {
requestSlotMan->deleteRequestSlot(requestSlot);
// TODO use STL algorithm
for(RequestSlots::iterator itr = requestSlots.begin();
itr != requestSlots.end(); itr++) {
if(*itr == requestSlot) {
requestSlots.erase(itr);
break;
}
}
}
void SendMessageQueue::deleteTimeoutRequestSlot(Piece& piece) {
requestSlotMan->deleteTimeoutRequestSlot(piece);
void SendMessageQueue::deleteAllRequestSlot(Piece& piece) {
if(!Piece::isNull(piece)) {
for(RequestSlots::const_iterator itr = requestSlots.begin();
itr != requestSlots.end(); itr++) {
if(itr->getIndex() == piece.getIndex()) {
piece.cancelBlock(itr->getBlockIndex());
}
}
torrentMan->updatePiece(piece);
}
requestSlots.clear();
}
void SendMessageQueue::deleteCompletedRequestSlot(const Piece& piece) {
requestSlotMan->deleteCompletedRequestSlot(piece);
void SendMessageQueue::deleteTimeoutRequestSlot() {
for(RequestSlots::iterator itr = requestSlots.begin();
itr != requestSlots.end();) {
if(itr->isTimeout(REQUEST_TIME_OUT)) {
logger->debug("CUID#%d - deleting requestslot blockIndex=%d because of time out", cuid,
itr->getBlockIndex());
if(!Piece::isNull(piece)) {
//addMessage(createCancelMessage(itr->getIndex(), itr->getBegin(), itr->getLength()));
piece.cancelBlock(itr->getBlockIndex());
}
itr = requestSlots.erase(itr);
} else {
itr++;
}
}
torrentMan->updatePiece(piece);
}
RequestSlot SendMessageQueue::getCorrespoindingRequestSlot(const PeerMessage* pieceMessage) const {
return requestSlotMan->getCorrespoindingRequestSlot(pieceMessage);
void SendMessageQueue::deleteCompletedRequestSlot() {
for(RequestSlots::iterator itr = requestSlots.begin();
itr != requestSlots.end();) {
if(Piece::isNull(piece) || piece.hasBlock(itr->getBlockIndex()) ||
torrentMan->hasPiece(piece.getIndex())) {
logger->debug("CUID#%d - deleting requestslot blockIndex=%d because the block is already acquired.", cuid,
itr->getBlockIndex());
addMessage(createCancelMessage(itr->getIndex(), itr->getBegin(), itr->getLength()));
itr = requestSlots.erase(itr);
} else {
itr++;
}
}
}
RequestSlot SendMessageQueue::getCorrespondingRequestSlot(const PieceMessage* pieceMessage) const {
for(RequestSlots::const_iterator itr = requestSlots.begin();
itr != requestSlots.end(); itr++) {
const RequestSlot& slot = *itr;
if(slot.getIndex() == pieceMessage->getIndex() &&
slot.getBegin() == pieceMessage->getBegin() &&
slot.getLength() == pieceMessage->getBlockLength()) {
return slot;
}
}
return RequestSlot::nullSlot;
}
void SendMessageQueue::cancelAllRequest() {
@ -116,14 +194,274 @@ void SendMessageQueue::cancelAllRequest() {
}
void SendMessageQueue::cancelAllRequest(Piece& piece) {
deletePendingRequestMessage();
requestSlotMan->deleteAllRequestSlot(piece);
deleteRequestMessageInQueue();
deleteAllRequestSlot(piece);
}
int SendMessageQueue::countPendingMessage() const {
return pendingMessages.size();
int SendMessageQueue::countMessageInQueue() const {
return messageQueue.size();
}
int SendMessageQueue::countRequestSlot() const {
return requestSlotMan->countRequestSlot();
return requestSlots.size();
}
HandshakeMessage* SendMessageQueue::receiveHandshake() {
char msg[HANDSHAKE_MESSAGE_LENGTH];
int msgLength = 0;
if(!peerConnection->receiveHandshake(msg, msgLength)) {
return NULL;
}
HandshakeMessage* handshakeMessage = createHandshakeMessage(msg, msgLength);
try {
handshakeMessage->check();
} catch(Exception* e) {
delete handshakeMessage;
throw;
}
return handshakeMessage;
}
HandshakeMessage* SendMessageQueue::createHandshakeMessage(const char* msg, int msgLength) {
HandshakeMessage* message = PeerMessageUtil::createHandshakeMessage(msg, msgLength);
message->setSendMessageQueue(this);
return message;
}
PeerMessage* SendMessageQueue::receiveMessage() {
char msg[MAX_PAYLOAD_LEN];
int msgLength = 0;
if(!peerConnection->receiveMessage(msg, msgLength)) {
return NULL;
}
PeerMessage* peerMessage = createPeerMessage(msg, msgLength);
try {
peerMessage->check();
} catch(Exception* e) {
delete peerMessage;
throw;
}
return peerMessage;
}
PeerMessage* SendMessageQueue::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 = PeerMessageUtil::createChokeMessage(msg, msgLength);
break;
case UnchokeMessage::ID:
peerMessage = PeerMessageUtil::createUnchokeMessage(msg, msgLength);
break;
case InterestedMessage::ID:
peerMessage = PeerMessageUtil::createInterestedMessage(msg, msgLength);
break;
case NotInterestedMessage::ID:
peerMessage = PeerMessageUtil::createNotInterestedMessage(msg, msgLength);
break;
case HaveMessage::ID:
peerMessage = PeerMessageUtil::createHaveMessage(msg, msgLength);
((HaveMessage*)peerMessage)->setPieces(torrentMan->pieces);
break;
case BitfieldMessage::ID:
peerMessage = PeerMessageUtil::createBitfieldMessage(msg, msgLength);
((BitfieldMessage*)peerMessage)->setPieces(torrentMan->pieces);
break;
case RequestMessage::ID:
peerMessage = PeerMessageUtil::createRequestMessage(msg, msgLength);
((RequestMessage*)peerMessage)->setPieces(torrentMan->pieces);
((RequestMessage*)peerMessage)->setPieceLength(torrentMan->getPieceLength(((RequestMessage*)peerMessage)->getIndex()));
break;
case CancelMessage::ID:
peerMessage = PeerMessageUtil::createCancelMessage(msg, msgLength);
((CancelMessage*)peerMessage)->setPieces(torrentMan->pieces);
((CancelMessage*)peerMessage)->setPieceLength(torrentMan->getPieceLength(((CancelMessage*)peerMessage)->getIndex()));
break;
case PieceMessage::ID:
peerMessage = PeerMessageUtil::createPieceMessage(msg, msgLength);
((PieceMessage*)peerMessage)->setPieces(torrentMan->pieces);
((PieceMessage*)peerMessage)->setPieceLength(torrentMan->getPieceLength(((PieceMessage*)peerMessage)->getIndex()));
break;
case PortMessage::ID:
peerMessage = PeerMessageUtil::createPortMessage(msg, msgLength);
break;
default:
throw new DlAbortEx("invalid message id. id = %d", id);
}
}
setPeerMessageCommonProperty(peerMessage);
return peerMessage;
}
void SendMessageQueue::syncPiece() {
if(Piece::isNull(piece)) {
return;
}
torrentMan->syncPiece(piece);
}
Piece SendMessageQueue::getNewPieceAndSendInterest() {
cancelAllRequest();
Piece piece = torrentMan->getMissingPiece(peer);
if(Piece::isNull(piece)) {
logger->debug("CUID#%d - not interested in the peer", cuid);
addMessage(createNotInterestedMessage());
} else {
logger->debug("CUID#%d - starting download for piece index=%d (%d/%d completed)",
cuid, piece.getIndex(), piece.countCompleteBlock(),
piece.countBlock());
logger->debug("CUID#%d - interested in the peer", cuid);
addMessage(createInterestedMessage());
}
return piece;
}
void SendMessageQueue::sendMessages(int currentUploadSpeed) {
if(Piece::isNull(piece)) {
// retrive new piece from TorrentMan
piece = getNewPieceAndSendInterest();
} else if(peer->peerChoking) {
cancelAllRequest(piece);
torrentMan->cancelPiece(piece);
piece = Piece::nullPiece;
} else if(piece.pieceComplete()) {
piece = getNewPieceAndSendInterest();
}
if(!Piece::isNull(piece) && !peer->peerChoking) {
if(torrentMan->isEndGame()) {
BlockIndexes missingBlockIndexes = piece.getAllMissingBlockIndexes();
if(countRequestSlot() == 0) {
random_shuffle(missingBlockIndexes.begin(), missingBlockIndexes.end());
int count = 0;
for(BlockIndexes::const_iterator itr = missingBlockIndexes.begin();
itr != missingBlockIndexes.end() && count < 6; itr++, count++) {
addMessage(createRequestMessage(*itr));
}
}
} else {
for(int i = countRequestSlot(); i < 6; i++) {
int blockIndex = piece.getMissingUnusedBlockIndex();
if(blockIndex == -1) {
break;
}
torrentMan->updatePiece(piece);
addMessage(createRequestMessage(blockIndex));
}
}
}
send(currentUploadSpeed);
}
void SendMessageQueue::sendNow(PeerMessage* peerMessage) {
// ignore inProgress state
peerMessage->send();
delete peerMessage;
}
void SendMessageQueue::trySendNow(PeerMessage* peerMessage) {
if(countMessageInQueue() == 0) {
sendNow(peerMessage);
} else {
addMessage(peerMessage);
}
}
void SendMessageQueue::sendHandshake() {
peerConnection->sendHandshake();
}
void SendMessageQueue::abortPiece() {
cancelAllRequest(piece);
torrentMan->cancelPiece(piece);
}
Piece& SendMessageQueue::getDownloadPiece() {
if(Piece::isNull(piece)) {
throw new DlAbortEx("current piece is null");
}
return piece;
}
void SendMessageQueue::setPeerMessageCommonProperty(PeerMessage* peerMessage) {
peerMessage->setPeer(peer);
peerMessage->setCuid(cuid);
peerMessage->setSendMessageQueue(this);
}
RequestMessage* SendMessageQueue::createRequestMessage(int blockIndex) {
RequestMessage* msg = new RequestMessage();
setPeerMessageCommonProperty(msg);
msg->setIndex(piece.getIndex());
msg->setBegin(blockIndex*piece.getBlockLength());
msg->setLength(piece.getBlockLength(blockIndex));
msg->setBlockIndex(blockIndex);
return msg;
}
CancelMessage* SendMessageQueue::createCancelMessage(int index, int begin, int length) {
CancelMessage* msg = new CancelMessage();
setPeerMessageCommonProperty(msg);
msg->setIndex(index);
msg->setBegin(begin);
msg->setLength(length);
return msg;
}
PieceMessage* SendMessageQueue::createPieceMessage(int index, int begin, int length) {
PieceMessage* msg = new PieceMessage();
setPeerMessageCommonProperty(msg);
msg->setIndex(index);
msg->setBegin(begin);
msg->setBlockLength(length);
return msg;
}
HaveMessage* SendMessageQueue::createHaveMessage(int index) {
HaveMessage* msg = new HaveMessage();
setPeerMessageCommonProperty(msg);
msg->setIndex(index);
return msg;
}
ChokeMessage* SendMessageQueue::createChokeMessage() {
ChokeMessage* msg = new ChokeMessage();
setPeerMessageCommonProperty(msg);
return msg;
}
UnchokeMessage* SendMessageQueue::createUnchokeMessage() {
UnchokeMessage* msg = new UnchokeMessage();
setPeerMessageCommonProperty(msg);
return msg;
}
InterestedMessage* SendMessageQueue::createInterestedMessage() {
InterestedMessage* msg = new InterestedMessage();
setPeerMessageCommonProperty(msg);
return msg;
}
NotInterestedMessage* SendMessageQueue::createNotInterestedMessage() {
NotInterestedMessage* msg = new NotInterestedMessage();
setPeerMessageCommonProperty(msg);
return msg;
}
BitfieldMessage* SendMessageQueue::createBitfieldMessage() {
BitfieldMessage* msg = new BitfieldMessage();
setPeerMessageCommonProperty(msg);
return msg;
}
KeepAliveMessage* SendMessageQueue::createKeepAliveMessage() {
KeepAliveMessage* msg = new KeepAliveMessage();
setPeerMessageCommonProperty(msg);
return msg;
}

View File

@ -23,40 +23,106 @@
#define _D_SEND_MESSAGE_QUEUE_H_
#include "common.h"
#include "RequestSlotMan.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 "RequestSlot.h"
#define REQUEST_TIME_OUT 120
typedef deque<RequestSlot> RequestSlots;
typedef deque<PeerMessage*> MessageQueue;
class SendMessageQueue {
private:
int cuid;
RequestSlotMan* requestSlotMan;
PendingMessages pendingMessages;
const Logger* logger;
RequestSlots requestSlots;
MessageQueue messageQueue;
// upload speed limit(byte/sec)
int uploadLimit;
public:
SendMessageQueue(int cuid, PeerConnection* peerConnection,
TorrentMan* torrentMan);
~SendMessageQueue();
TorrentMan* torrentMan;
PeerConnection* peerConnection;
Peer* peer;
Piece piece;
const Logger* logger;
Piece getNewPieceAndSendInterest();
PeerMessage* createPeerMessage(const char* msg, int msgLength);
HandshakeMessage* createHandshakeMessage(const char* msg, int msgLength);
void send(int uploadSpeed);
void addPendingMessage(const PendingMessage& pendingMessage);
void deletePendingPieceMessage(const PeerMessage* cancelMessage);
void deletePendingRequestMessage();
void deleteRequestSlot(const RequestSlot& requestSlot);
void deleteTimeoutRequestSlot(Piece& piece);
void deleteCompletedRequestSlot(const Piece& piece);
RequestSlot getCorrespoindingRequestSlot(const PeerMessage* pieceMessage) const;
void setPeerMessageCommonProperty(PeerMessage* peerMessage);
void deleteAllRequestSlot(Piece& piece);
void deleteRequestMessageInQueue();
void cancelAllRequest();
void cancelAllRequest(Piece& piece);
int countPendingMessage() const;
int countRequestSlot() const;
public:
SendMessageQueue(int cuid,
const Socket* socket,
const Option* op,
TorrentMan* torrentMan,
Peer* peer);
~SendMessageQueue();
void addMessage(PeerMessage* peerMessage);
void deletePieceMessageInQueue(const CancelMessage* cancelMessage);
void deleteRequestSlot(const RequestSlot& requestSlot);
void deleteTimeoutRequestSlot();
void deleteCompletedRequestSlot();
RequestSlot getCorrespondingRequestSlot(const PieceMessage* pieceMessage) const;
int countMessageInQueue() const;
void setUploadLimit(int uploadLimit) { this->uploadLimit = uploadLimit; }
int getUploadLimit() const { return this->uploadLimit; }
TorrentMan* getTorrentMan() const { return torrentMan; }
PeerConnection* getPeerConnection() const { return peerConnection; }
// If this object has nullPiece, then return false, otherwise true
bool hasDownloadPiece() const {
return !Piece::isNull(piece);
}
// If the piece which this object has is nullPiece, then throws an exception.
// So before calling this function, call hasDownloadPiece and make sure
// this has valid piece, not nullPiece.
Piece& getDownloadPiece();
void setDownloadPiece(const Piece& piece) {
this->piece = piece;
}
void syncPiece();
void sendMessages(int currentUploadSpeed);
// after sending message, deletes peerMessage.
// So don't use peerMessage after this function call.
void sendNow(PeerMessage* peerMessage);
void trySendNow(PeerMessage* peerMessage);
void abortPiece();
void sendHandshake();
PeerMessage* receiveMessage();
HandshakeMessage* receiveHandshake();
RequestMessage* createRequestMessage(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();
};
#endif // _D_SEND_MESSAGE_QUEUE_H_

View File

@ -37,11 +37,11 @@ bool SleepCommand::execute() {
struct timeval now;
gettimeofday(&now, NULL);
if(Util::difftv(now, checkPoint) >= ((long long int)wait)*1000000) {
engine->commands.push(nextCommand);
engine->commands.push_back(nextCommand);
nextCommand = NULL;
return true;
} else {
engine->commands.push(this);
engine->commands.push_back(this);
return false;
}
}

View File

@ -32,6 +32,6 @@ bool TorrentAutoSaveCommand::execute() {
}
e->torrentMan->save();
SleepCommand* sleepCommand = new SleepCommand(cuid, e, this, interval);
e->commands.push(sleepCommand);
e->commands.push_back(sleepCommand);
return false;
}

View File

@ -22,6 +22,15 @@
#include "TorrentDownloadEngine.h"
#include "Util.h"
TorrentDownloadEngine::TorrentDownloadEngine():filenameFixed(false),
torrentMan(NULL) {}
TorrentDownloadEngine::~TorrentDownloadEngine() {
if(torrentMan != NULL) {
delete torrentMan;
}
}
void TorrentDownloadEngine::onEndOfRun() {
torrentMan->diskAdaptor->closeFile();
if(filenameFixed && torrentMan->downloadComplete()) {

View File

@ -59,8 +59,8 @@ protected:
virtual void onSelectiveDownloadingCompletes() = 0;
virtual void sendStatistics() = 0;
public:
TorrentDownloadEngine():filenameFixed(false) {}
virtual ~TorrentDownloadEngine() {}
TorrentDownloadEngine();
virtual ~TorrentDownloadEngine();
TorrentMan* torrentMan;

View File

@ -138,6 +138,11 @@ public:
return bitfield->getBitfield();
}
int getBitfieldLength() const { return bitfield->getBitfieldLength(); }
int getPieceLength(int index) const {
return bitfield->getBlockLength(index);
}
int getPieceLength() const { return bitfield->getBlockLength(); }
void setInfoHash(const unsigned char* infoHash) {
memcpy(this->infoHash, infoHash, INFO_HASH_LENGTH);
}

View File

@ -37,7 +37,7 @@ TrackerUpdateCommand::~TrackerUpdateCommand() {}
bool TrackerUpdateCommand::prepareForRetry() {
Command* sleepCommand = new SleepCommand(cuid, e, this, 5);
e->commands.push(sleepCommand);
e->commands.push_back(sleepCommand);
return false;
}
@ -153,7 +153,7 @@ bool TrackerUpdateCommand::execute() {
int newCuid = e->torrentMan->getNewCuid();
peer->cuid = newCuid;
PeerInitiateConnectionCommand* command = new PeerInitiateConnectionCommand(newCuid, peer, e);
e->commands.push(command);
e->commands.push_back(command);
logger->debug("adding new command CUID#%d", newCuid);
}
if(e->torrentMan->req->getTrackerEvent() == Request::STARTED) {

View File

@ -76,13 +76,13 @@ bool TrackerWatcherCommand::execute() {
}
e->torrentMan->req->setUrl(url);
Command* command = InitiateConnectionCommandFactory::createInitiateConnectionCommand(e->torrentMan->getNewCuid(), e->torrentMan->req, e);
e->commands.push(command);
e->commands.push_back(command);
e->torrentMan->trackers++;
logger->info("CUID#%d - creating new tracker request command #%d", cuid,
command->getCuid());
}
SleepCommand* slpCommand = new SleepCommand(cuid, e, this,
e->torrentMan->minInterval);
e->commands.push(slpCommand);
e->commands.push_back(slpCommand);
return false;
}

38
src/UnchokeMessage.cc Normal file
View File

@ -0,0 +1,38 @@
/* <!-- 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 "UnchokeMessage.h"
#include "SendMessageQueue.h"
void UnchokeMessage::receivedAction() {
peer->peerChoking = false;
}
void UnchokeMessage::send() {
if(peer->amChoking) {
sendMessageQueue->getPeerConnection()->sendUnchoke();
peer->amChoking = false;
}
}
string UnchokeMessage::toString() const {
return "unchoke";
}

43
src/UnchokeMessage.h Normal file
View File

@ -0,0 +1,43 @@
/* <!-- 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_UNCHOKE_MESSAGE_H_
#define _D_UNCHOKE_MESSAGE_H_
#include "PeerMessage.h"
class UnchokeMessage : public PeerMessage {
public:
UnchokeMessage():PeerMessage() {}
virtual ~UnchokeMessage() {}
enum ID {
ID = 1
};
virtual int getId() const { return ID; }
virtual void receivedAction();
virtual void send();
virtual string toString() const;
};
#endif // _D_UNCHOKE_MESSAGE_H_

View File

@ -342,3 +342,16 @@ void Util::unfoldRange(const string& src, Integers& range) {
sort(range.begin(), range.end());
range.erase(unique(range.begin(), range.end()), range.end());
}
string Util::getContentDispositionFilename(const string& header) {
string::size_type attributesp = header.find("filename=\"");
if(attributesp == string::npos) {
return "";
}
string::size_type filenamesp = attributesp+strlen("filename=\"");
string::size_type filenameep = header.find("\"", filenamesp);
if(filenameep == string::npos) {
return "";
}
return trim(header.substr(filenamesp, filenameep-filenamesp));
}

View File

@ -75,6 +75,9 @@ public:
static int expandBuffer(char** pbuf, int curLength, int newLength);
static void unfoldRange(const string& src, Integers& range);
// this function temporarily put here
static string getContentDispositionFilename(const string& header);
};
#endif // _D_UTIL_H_

View File

@ -29,6 +29,7 @@
#include <limits.h>
#include <string>
#include <deque>
#include <algorithm>
#if ENABLE_NLS
# include <gettext.h>
# define _(String) gettext (String)
@ -47,6 +48,14 @@
using namespace std;
class Deleter {
public:
template<class T>
void operator()(T* ptr) {
delete ptr;
}
};
typedef deque<string> Strings;
typedef deque<int> Integers;

View File

@ -81,10 +81,6 @@ void setSignalHander(int signal, void (*handler)(int)) {
sigaction(signal, &sigact, NULL);
}
void clearRequest(Request* req) {
delete(req);
}
DownloadEngine* e;
TorrentDownloadEngine* te;
@ -93,6 +89,8 @@ void handler(int signal) {
fflush(stdout);
e->segmentMan->save();
e->segmentMan->diskWriter->closeFile();
e->cleanQueue();
delete e;
printf(_("done\n"));
exit(0);
}
@ -108,6 +106,8 @@ void torrentHandler(int signal) {
} else {
te->torrentMan->save();
}
te->cleanQueue();
delete te;
printf(_("done\n"));
exit(0);
}
@ -116,7 +116,7 @@ void addCommand(int cuid, const string& url, string referer, Requests& requests)
Request* req = new Request();
req->setReferer(referer);
if(req->setUrl(url)) {
e->commands.push(InitiateConnectionCommandFactory::createInitiateConnectionCommand(cuid, req, e));
e->commands.push_back(InitiateConnectionCommandFactory::createInitiateConnectionCommand(cuid, req, e));
requests.push_back(req);
} else {
fprintf(stderr, _("Unrecognized URL or unsupported protocol: %s\n"), req->getUrl().c_str());
@ -596,9 +596,6 @@ int main(int argc, char* argv[]) {
exit(1);
}
SegmentSplitter* splitter = new SplitSlowestSegmentSplitter();
splitter->setMinSegmentSize(op->getAsLLInt(PREF_MIN_SEGMENT_SIZE));
setSignalHander(SIGPIPE, SIG_IGN);
bool readyToTorrentMode = false;
@ -614,7 +611,9 @@ int main(int argc, char* argv[]) {
e->segmentMan->dir = dir;
e->segmentMan->ufilename = ufilename;
e->segmentMan->option = op;
e->segmentMan->splitter = splitter;
e->segmentMan->splitter = new SplitSlowestSegmentSplitter();
e->segmentMan->splitter->setMinSegmentSize(op->getAsLLInt(PREF_MIN_SEGMENT_SIZE));
Requests requests;
int cuidCounter = 1;
@ -636,12 +635,11 @@ int main(int argc, char* argv[]) {
} else {
printDownloadAbortMessage();
}
for_each(requests.begin(), requests.end(), clearRequest);
for_each(requests.begin(), requests.end(), Deleter());
requests.clear();
delete(e->segmentMan);
delete(e->segmentMan->diskWriter);
delete(e);
e->cleanQueue();
delete e;
}
if(!torrentFile.empty() || followTorrent && readyToTorrentMode) {
try {
@ -658,7 +656,8 @@ int main(int argc, char* argv[]) {
te->segmentMan = new SegmentMan();
te->segmentMan->diskWriter = byteArrayDiskWriter;
te->segmentMan->option = op;
te->segmentMan->splitter = splitter;
te->segmentMan->splitter = new SplitSlowestSegmentSplitter();
te->segmentMan->splitter->setMinSegmentSize(op->getAsLLInt(PREF_MIN_SEGMENT_SIZE));
te->torrentMan = new TorrentMan();
te->torrentMan->setStoreDir(dir);
te->torrentMan->option = op;
@ -703,15 +702,15 @@ int main(int argc, char* argv[]) {
exit(1);
}
te->torrentMan->setPort(port);
te->commands.push(listenCommand);
te->commands.push(new TrackerWatcherCommand(te->torrentMan->getNewCuid(),
te->commands.push_back(listenCommand);
te->commands.push_back(new TrackerWatcherCommand(te->torrentMan->getNewCuid(),
te));
te->commands.push(new TrackerUpdateCommand(te->torrentMan->getNewCuid(),
te->commands.push_back(new TrackerUpdateCommand(te->torrentMan->getNewCuid(),
te));
te->commands.push(new TorrentAutoSaveCommand(te->torrentMan->getNewCuid(),
te->commands.push_back(new TorrentAutoSaveCommand(te->torrentMan->getNewCuid(),
te,
op->getAsInt(PREF_AUTO_SAVE_INTERVAL)));
te->commands.push(new PeerChokeCommand(te->torrentMan->getNewCuid(),
te->commands.push_back(new PeerChokeCommand(te->torrentMan->getNewCuid(),
10, te));
te->run();
@ -720,20 +719,17 @@ int main(int argc, char* argv[]) {
} else {
printDownloadAbortMessage();
}
delete(req);
delete(te->segmentMan);
delete(te->segmentMan->diskWriter);
delete(te->torrentMan);
delete(te);
delete req;
te->cleanQueue();
delete te;
} catch(Exception* ex) {
cerr << ex->getMsg() << endl;
delete ex;
exit(1);
}
}
delete(op);
delete(splitter);
delete(LogFactory::getInstance());
delete op;
LogFactory::release();
#ifdef HAVE_LIBGNUTLS
gnutls_global_deinit();
#endif // HAVE_LIBGNUTLS

View File

@ -8,7 +8,6 @@ using namespace std;
class PeerMessageUtilTest:public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(PeerMessageUtilTest);
CPPUNIT_TEST(testCreatePeerMessageKeepAlive);
CPPUNIT_TEST(testCreatePeerMessageChoke);
CPPUNIT_TEST(testCreatePeerMessageUnchoke);
CPPUNIT_TEST(testCreatePeerMessageInterested);
@ -18,6 +17,7 @@ class PeerMessageUtilTest:public CppUnit::TestFixture {
CPPUNIT_TEST(testCreatePeerMessageRequest);
CPPUNIT_TEST(testCreatePeerMessagePiece);
CPPUNIT_TEST(testCreatePeerMessageCancel);
CPPUNIT_TEST(testCreatePortMessage);
CPPUNIT_TEST(testCheckIntegrityHave);
CPPUNIT_TEST(testCheckIntegrityBitfield);
CPPUNIT_TEST(testCheckIntegrityRequest);
@ -28,7 +28,6 @@ public:
void setUp() {
}
void testCreatePeerMessageKeepAlive();
void testCreatePeerMessageChoke();
void testCreatePeerMessageUnchoke();
void testCreatePeerMessageInterested();
@ -38,7 +37,7 @@ public:
void testCreatePeerMessageRequest();
void testCreatePeerMessagePiece();
void testCreatePeerMessageCancel();
void testCreatePortMessage();
void testCheckIntegrityHave();
void testCheckIntegrityBitfield();
void testCheckIntegrityRequest();
@ -52,29 +51,27 @@ void setIntParam(char* dest, int param) {
memcpy(dest, &nParam, 4);
}
void setShortIntParam(char* dest, int param) {
short int nParam = htons(param);
memcpy(dest, &nParam, 2);
}
void createNLengthMessage(char* msg, int msgLen, int payloadLen, int id) {
memset(msg, 0, msgLen);
setIntParam(msg, payloadLen);
msg[4] = (char)id;
}
void PeerMessageUtilTest::testCreatePeerMessageKeepAlive() {
char msg[4];
memset(msg, 0, sizeof(msg));
PeerMessage* pm = PeerMessageUtil::createPeerMessage(NULL, 0);
CPPUNIT_ASSERT_EQUAL((int)PeerMessage::KEEP_ALIVE, pm->getId());
}
void PeerMessageUtilTest::testCreatePeerMessageChoke() {
char msg[5];
createNLengthMessage(msg, sizeof(msg), 1, 0);
PeerMessage* pm = PeerMessageUtil::createPeerMessage(&msg[4], 1);
CPPUNIT_ASSERT_EQUAL((int)PeerMessage::CHOKE, pm->getId());
PeerMessage* pm = PeerMessageUtil::createChokeMessage(&msg[4], 1);
CPPUNIT_ASSERT_EQUAL((int)ChokeMessage::ID, pm->getId());
try {
char msg[6];
createNLengthMessage(msg, sizeof(msg), 2, 0);
PeerMessageUtil::createPeerMessage(&msg[4], 2);
PeerMessageUtil::createChokeMessage(&msg[4], 2);
CPPUNIT_FAIL("exception must be throwed.");
} catch(...) {
}
@ -83,13 +80,13 @@ void PeerMessageUtilTest::testCreatePeerMessageChoke() {
void PeerMessageUtilTest::testCreatePeerMessageUnchoke() {
char msg[5];
createNLengthMessage(msg, sizeof(msg), 1, 1);
PeerMessage* pm = PeerMessageUtil::createPeerMessage(&msg[4], 1);
CPPUNIT_ASSERT_EQUAL((int)PeerMessage::UNCHOKE, pm->getId());
PeerMessage* pm = PeerMessageUtil::createUnchokeMessage(&msg[4], 1);
CPPUNIT_ASSERT_EQUAL((int)UnchokeMessage::ID, pm->getId());
try {
char msg[6];
createNLengthMessage(msg, sizeof(msg), 2, 1);
PeerMessageUtil::createPeerMessage(&msg[4], 2);
PeerMessageUtil::createUnchokeMessage(&msg[4], 2);
CPPUNIT_FAIL("exception must be throwed.");
} catch(...) {
}
@ -98,13 +95,13 @@ void PeerMessageUtilTest::testCreatePeerMessageUnchoke() {
void PeerMessageUtilTest::testCreatePeerMessageInterested() {
char msg[5];
createNLengthMessage(msg, sizeof(msg), 1, 2);
PeerMessage* pm = PeerMessageUtil::createPeerMessage(&msg[4], 1);
CPPUNIT_ASSERT_EQUAL((int)PeerMessage::INTERESTED, pm->getId());
PeerMessage* pm = PeerMessageUtil::createInterestedMessage(&msg[4], 1);
CPPUNIT_ASSERT_EQUAL((int)InterestedMessage::ID, pm->getId());
try {
char msg[6];
createNLengthMessage(msg, sizeof(msg), 2, 2);
PeerMessageUtil::createPeerMessage(&msg[4], 2);
PeerMessageUtil::createInterestedMessage(&msg[4], 2);
CPPUNIT_FAIL("exception must be throwed.");
} catch(...) {
}
@ -113,13 +110,13 @@ void PeerMessageUtilTest::testCreatePeerMessageInterested() {
void PeerMessageUtilTest::testCreatePeerMessageNotInterested() {
char msg[5];
createNLengthMessage(msg, sizeof(msg), 1, 3);
PeerMessage* pm = PeerMessageUtil::createPeerMessage(&msg[4], 1);
CPPUNIT_ASSERT_EQUAL((int)PeerMessage::NOT_INTERESTED, pm->getId());
PeerMessage* pm = PeerMessageUtil::createNotInterestedMessage(&msg[4], 1);
CPPUNIT_ASSERT_EQUAL((int)NotInterestedMessage::ID, pm->getId());
try {
char msg[6];
createNLengthMessage(msg, sizeof(msg), 2, 3);
PeerMessageUtil::createPeerMessage(&msg[4], 2);
PeerMessageUtil::createNotInterestedMessage(&msg[4], 2);
CPPUNIT_FAIL("exception must be throwed.");
} catch(...) {
}
@ -129,21 +126,21 @@ void PeerMessageUtilTest::testCreatePeerMessageHave() {
char msg[9];
createNLengthMessage(msg, sizeof(msg), 5, 4);
setIntParam(&msg[5], 100);
PeerMessage* pm = PeerMessageUtil::createPeerMessage(&msg[4], 5);
CPPUNIT_ASSERT_EQUAL((int)PeerMessage::HAVE, pm->getId());
HaveMessage* pm = PeerMessageUtil::createHaveMessage(&msg[4], 5);
CPPUNIT_ASSERT_EQUAL((int)HaveMessage::ID, pm->getId());
CPPUNIT_ASSERT_EQUAL(100, pm->getIndex());
try {
char msg[8];
createNLengthMessage(msg, sizeof(msg), 4, 4);
PeerMessageUtil::createPeerMessage(&msg[4], 4);
PeerMessageUtil::createHaveMessage(&msg[4], 4);
CPPUNIT_FAIL("exception must be throwed.");
} catch(...) {}
try {
char msg[5];
createNLengthMessage(msg, sizeof(msg), 1, 4);
PeerMessageUtil::createPeerMessage(&msg[4], 1);
PeerMessageUtil::createHaveMessage(&msg[4], 1);
CPPUNIT_FAIL("exception must be throwed.");
} catch(...) {}
}
@ -152,8 +149,8 @@ void PeerMessageUtilTest::testCreatePeerMessageBitfield() {
int msgLen = 5+2;
char* msg = new char[msgLen];
createNLengthMessage(msg, msgLen, 3, 5);
PeerMessage* pm = PeerMessageUtil::createPeerMessage(&msg[4], 3);
CPPUNIT_ASSERT_EQUAL((int)PeerMessage::BITFIELD, pm->getId());
BitfieldMessage* pm = PeerMessageUtil::createBitfieldMessage(&msg[4], 3);
CPPUNIT_ASSERT_EQUAL((int)BitfieldMessage::ID, pm->getId());
CPPUNIT_ASSERT_EQUAL((unsigned char)0, pm->getBitfield()[0]);
CPPUNIT_ASSERT_EQUAL((unsigned char)0, pm->getBitfield()[1]);
CPPUNIT_ASSERT_EQUAL(2, pm->getBitfieldLength());
@ -162,7 +159,7 @@ void PeerMessageUtilTest::testCreatePeerMessageBitfield() {
int msgLen = 5;
char* msg = new char[msgLen];
createNLengthMessage(msg, msgLen, 1, 5);
PeerMessageUtil::createPeerMessage(&msg[4], 1);
PeerMessageUtil::createBitfieldMessage(&msg[4], 1);
CPPUNIT_FAIL("exception must be throwed.");
} catch(...) {}
}
@ -173,8 +170,8 @@ void PeerMessageUtilTest::testCreatePeerMessageRequest() {
setIntParam(&msg[5], 1);
setIntParam(&msg[9], 16*1024);
setIntParam(&msg[13], 16*1024-1);
PeerMessage* pm = PeerMessageUtil::createPeerMessage(&msg[4], 13);
CPPUNIT_ASSERT_EQUAL((int)PeerMessage::REQUEST, pm->getId());
RequestMessage* pm = PeerMessageUtil::createRequestMessage(&msg[4], 13);
CPPUNIT_ASSERT_EQUAL((int)RequestMessage::ID, pm->getId());
CPPUNIT_ASSERT_EQUAL(1, pm->getIndex());
CPPUNIT_ASSERT_EQUAL(16*1024, pm->getBegin());
CPPUNIT_ASSERT_EQUAL(16*1024-1, pm->getLength());
@ -184,7 +181,7 @@ void PeerMessageUtilTest::testCreatePeerMessageRequest() {
createNLengthMessage(msg, sizeof(msg), 9, 6);
setIntParam(&msg[5], 1);
setIntParam(&msg[9], 16*1024);
PeerMessageUtil::createPeerMessage(&msg[4], 9);
PeerMessageUtil::createRequestMessage(&msg[4], 9);
CPPUNIT_FAIL("exception must be throwed.");
} catch(...) {}
}
@ -194,8 +191,8 @@ void PeerMessageUtilTest::testCreatePeerMessagePiece() {
createNLengthMessage(msg, sizeof(msg), 9+10, 7);
setIntParam(&msg[5], 1);
setIntParam(&msg[9], 16*1024);
PeerMessage* pm = PeerMessageUtil::createPeerMessage(&msg[4], 19);
CPPUNIT_ASSERT_EQUAL((int)PeerMessage::PIECE, pm->getId());
PieceMessage* pm = PeerMessageUtil::createPieceMessage(&msg[4], 19);
CPPUNIT_ASSERT_EQUAL((int)PieceMessage::ID, pm->getId());
CPPUNIT_ASSERT_EQUAL(1, pm->getIndex());
CPPUNIT_ASSERT_EQUAL(16*1024, pm->getBegin());
CPPUNIT_ASSERT_EQUAL(10, pm->getBlockLength());
@ -208,7 +205,7 @@ void PeerMessageUtilTest::testCreatePeerMessagePiece() {
createNLengthMessage(msg, sizeof(msg), 9, 7);
setIntParam(&msg[5], 1);
setIntParam(&msg[9], 16*1024);
PeerMessageUtil::createPeerMessage(&msg[4], 9);
PeerMessageUtil::createPieceMessage(&msg[4], 9);
CPPUNIT_FAIL("exception must be throwed.");
} catch(...) {}
}
@ -219,8 +216,8 @@ void PeerMessageUtilTest::testCreatePeerMessageCancel() {
setIntParam(&msg[5], 1);
setIntParam(&msg[9], 16*1024);
setIntParam(&msg[13], 16*1024-1);
PeerMessage* pm = PeerMessageUtil::createPeerMessage(&msg[4], 13);
CPPUNIT_ASSERT_EQUAL((int)PeerMessage::CANCEL, pm->getId());
CancelMessage* pm = PeerMessageUtil::createCancelMessage(&msg[4], 13);
CPPUNIT_ASSERT_EQUAL((int)CancelMessage::ID, pm->getId());
CPPUNIT_ASSERT_EQUAL(1, pm->getIndex());
CPPUNIT_ASSERT_EQUAL(16*1024, pm->getBegin());
CPPUNIT_ASSERT_EQUAL(16*1024-1, pm->getLength());
@ -230,17 +227,27 @@ void PeerMessageUtilTest::testCreatePeerMessageCancel() {
createNLengthMessage(msg, sizeof(msg), 9, 8);
setIntParam(&msg[5], 1);
setIntParam(&msg[9], 16*1024);
PeerMessageUtil::createPeerMessage(&msg[4], 9);
PeerMessageUtil::createCancelMessage(&msg[4], 9);
CPPUNIT_FAIL("exception must be throwed.");
} catch(...) {}
}
void PeerMessageUtilTest::testCreatePortMessage() {
char msg[7];
createNLengthMessage(msg, sizeof(msg), 3, 9);
setShortIntParam(&msg[5], 65535);
PortMessage* pm = PeerMessageUtil::createPortMessage(&msg[4], 3);
CPPUNIT_ASSERT_EQUAL((int)PortMessage::ID, pm->getId());
CPPUNIT_ASSERT_EQUAL(65535, pm->getPort());
}
void PeerMessageUtilTest::testCheckIntegrityHave() {
PeerMessage* pm = new PeerMessage();
pm->setId(PeerMessage::HAVE);
HaveMessage* pm = new HaveMessage();
pm->setIndex(119);
pm->setPieces(120);
try {
PeerMessageUtil::checkIntegrity(pm, 256*1024, 120, 256*1024*120);
//PeerMessageUtil::checkIntegrity(pm, 256*1024, 120, 256*1024*120);
pm->check();
} catch(Exception* ex) {
cerr << ex->getMsg() << endl;
CPPUNIT_FAIL("");
@ -248,21 +255,23 @@ void PeerMessageUtilTest::testCheckIntegrityHave() {
pm->setIndex(120);
try {
PeerMessageUtil::checkIntegrity(pm, 256*1024, 120, 256*1024*120);
//PeerMessageUtil::checkIntegrity(pm, 256*1024, 120, 256*1024*120);
pm->check();
CPPUNIT_FAIL("exception must be throwed.");
} catch(...) {}
}
void PeerMessageUtilTest::testCheckIntegrityBitfield() {
PeerMessage* pm = new PeerMessage();
pm->setId(PeerMessage::BITFIELD);
BitfieldMessage* pm = new BitfieldMessage();
int bitfieldLength = 15;
unsigned char* bitfield = new unsigned char[bitfieldLength];
memset(bitfield, 0xff, bitfieldLength);
pm->setBitfield(bitfield, bitfieldLength);
pm->setPieces(120);
try {
PeerMessageUtil::checkIntegrity(pm, 256*1024, 120, 256*1024*120);
//PeerMessageUtil::checkIntegrity(pm, 256*1024, 120, 256*1024*120);
pm->check();
} catch(Exception* ex) {
cerr << ex->getMsg() << endl;
CPPUNIT_FAIL("");
@ -273,7 +282,8 @@ void PeerMessageUtilTest::testCheckIntegrityBitfield() {
memset(bitfield, 0xff, bitfieldLength);
pm->setBitfield(bitfield, bitfieldLength);
try {
PeerMessageUtil::checkIntegrity(pm, 256*1024, 120, 256*1024*120);
//PeerMessageUtil::checkIntegrity(pm, 256*1024, 120, 256*1024*120);
pm->check();
CPPUNIT_FAIL("exception must be throwed.");
} catch(Exception* ex) {
}
@ -283,7 +293,8 @@ void PeerMessageUtilTest::testCheckIntegrityBitfield() {
memset(bitfield, 0xff, bitfieldLength);
pm->setBitfield(bitfield, bitfieldLength);
try {
PeerMessageUtil::checkIntegrity(pm, 256*1024, 120, 256*1024*120);
//PeerMessageUtil::checkIntegrity(pm, 256*1024, 120, 256*1024*120);
pm->check();
CPPUNIT_FAIL("exception must be throwed.");
} catch(Exception* ex) {
}
@ -293,8 +304,10 @@ void PeerMessageUtilTest::testCheckIntegrityBitfield() {
memset(bitfield, 0xff, bitfieldLength);
bitfield[bitfieldLength-1] &= 0xfe;
pm->setBitfield(bitfield, bitfieldLength);
pm->setPieces(119);
try {
PeerMessageUtil::checkIntegrity(pm, 256*1024, 119, 256*1024*120);
//PeerMessageUtil::checkIntegrity(pm, 256*1024, 119, 256*1024*120);
pm->check();
} catch(Exception* ex) {
cerr << ex->getMsg() << endl;
CPPUNIT_FAIL("");
@ -305,7 +318,8 @@ void PeerMessageUtilTest::testCheckIntegrityBitfield() {
memset(bitfield, 0xff, bitfieldLength);
pm->setBitfield(bitfield, bitfieldLength);
try {
PeerMessageUtil::checkIntegrity(pm, 256*1024, 119, 256*1024*120);
//PeerMessageUtil::checkIntegrity(pm, 256*1024, 119, 256*1024*120);
pm->check();
CPPUNIT_FAIL("exception must be throwed.");
} catch(Exception* ex) {
}
@ -313,14 +327,15 @@ void PeerMessageUtilTest::testCheckIntegrityBitfield() {
}
void PeerMessageUtilTest::testCheckIntegrityRequest() {
PeerMessage* pm = new PeerMessage();
pm->setId(PeerMessage::REQUEST);
RequestMessage* pm = new RequestMessage();
pm->setIndex(119);
pm->setBegin(0);
pm->setLength(16*1024);
pm->setPieces(120);
pm->setPieceLength(256*1024);
try {
PeerMessageUtil::checkIntegrity(pm, 256*1024, 120, 256*1024*120);
//PeerMessageUtil::checkIntegrity(pm, 256*1024, 120, 256*1024*120);
pm->check();
} catch(Exception* ex) {
cerr << ex->getMsg() << endl;
CPPUNIT_FAIL("");
@ -329,21 +344,24 @@ void PeerMessageUtilTest::testCheckIntegrityRequest() {
pm->setBegin(256*1024);
pm->setLength(16*1024);
try {
PeerMessageUtil::checkIntegrity(pm, 256*1024, 120, 256*1024*120);
//PeerMessageUtil::checkIntegrity(pm, 256*1024, 120, 256*1024*120);
pm->check();
CPPUNIT_FAIL("exception must be throwed.");
} catch(Exception* ex) {}
pm->setBegin(0);
pm->setLength(256*1024);
try {
PeerMessageUtil::checkIntegrity(pm, 256*1024, 120, 256*1024*120);
//PeerMessageUtil::checkIntegrity(pm, 256*1024, 120, 256*1024*120);
pm->check();
CPPUNIT_FAIL("exception must be throwed.");
} catch(Exception* ex) {}
pm->setBegin(0);
pm->setLength(5);
try {
PeerMessageUtil::checkIntegrity(pm, 256*1024, 120, 256*1024*120);
//PeerMessageUtil::checkIntegrity(pm, 256*1024, 120, 256*1024*120);
pm->check();
CPPUNIT_FAIL("exception must be throwed.");
} catch(Exception* ex) {}
}

View File

@ -13,6 +13,8 @@ class UtilTest:public CppUnit::TestFixture {
CPPUNIT_TEST(testEndsWith);
CPPUNIT_TEST(testReplace);
CPPUNIT_TEST(testStartsWith);
// may be moved to other helper class in the future.
CPPUNIT_TEST(testGetContentDispositionFilename);
CPPUNIT_TEST_SUITE_END();
private:
@ -26,6 +28,8 @@ public:
void testEndsWith();
void testReplace();
void testStartsWith();
// may be moved to other helper class in the future.
void testGetContentDispositionFilename();
};
@ -157,3 +161,17 @@ void UtilTest::testStartsWith() {
CPPUNIT_ASSERT(Util::startsWith(target, part));
}
void UtilTest::testGetContentDispositionFilename() {
string h1 = "attachment; filename=\"aria2.tar.bz2\"";
CPPUNIT_ASSERT_EQUAL(string("aria2.tar.bz2"), Util::getContentDispositionFilename(h1));
string h2 = "attachment; filename=\"\"";
CPPUNIT_ASSERT_EQUAL(string(""), Util::getContentDispositionFilename(h2));
string h3 = "attachment; filename=\"";
CPPUNIT_ASSERT_EQUAL(string(""), Util::getContentDispositionFilename(h3));
string h4 = "attachment;";
CPPUNIT_ASSERT_EQUAL(string(""), Util::getContentDispositionFilename(h4));
}