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> 2006-05-06 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
* src/main.cc (main): Fixed typo. * src/main.cc (main): Fixed typo.

2
TODO
View File

@ -14,4 +14,4 @@
* Add Mainline-compatible DHT support * Add Mainline-compatible DHT support
* Add Message stream encryption support * Add Message stream encryption support
* Add announce-list 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 #! /bin/sh
# Guess values for system-dependent variables and create Makefiles. # 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>. # Report bugs to <tujikawa@rednoah.com>.
# #
@ -269,8 +269,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
# Identity of this package. # Identity of this package.
PACKAGE_NAME='aria2c' PACKAGE_NAME='aria2c'
PACKAGE_TARNAME='aria2c' PACKAGE_TARNAME='aria2c'
PACKAGE_VERSION='0.4.1' PACKAGE_VERSION='0.4.2'
PACKAGE_STRING='aria2c 0.4.1' PACKAGE_STRING='aria2c 0.4.2'
PACKAGE_BUGREPORT='tujikawa@rednoah.com' PACKAGE_BUGREPORT='tujikawa@rednoah.com'
ac_unique_file="src/Socket.h" 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. # 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. # This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF 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]... Usage: $0 [OPTION]... [VAR=VALUE]...
@ -854,7 +854,7 @@ fi
if test -n "$ac_init_help"; then if test -n "$ac_init_help"; then
case $ac_init_help in case $ac_init_help in
short | recursive ) echo "Configuration of aria2c 0.4.1:";; short | recursive ) echo "Configuration of aria2c 0.4.2:";;
esac esac
cat <<\_ACEOF cat <<\_ACEOF
@ -994,7 +994,7 @@ fi
test -n "$ac_init_help" && exit 0 test -n "$ac_init_help" && exit 0
if $ac_init_version; then if $ac_init_version; then
cat <<\_ACEOF cat <<\_ACEOF
aria2c configure 0.4.1 aria2c configure 0.4.2
generated by GNU Autoconf 2.59 generated by GNU Autoconf 2.59
Copyright (C) 2003 Free Software Foundation, Inc. Copyright (C) 2003 Free Software Foundation, Inc.
@ -1008,7 +1008,7 @@ cat >&5 <<_ACEOF
This file contains any messages produced by compilers while This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake. 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 generated by GNU Autoconf 2.59. Invocation command line was
$ $0 $@ $ $0 $@
@ -1651,7 +1651,7 @@ fi
# Define the identity of the package. # Define the identity of the package.
PACKAGE='aria2c' PACKAGE='aria2c'
VERSION='0.4.1' VERSION='0.4.2'
cat >>confdefs.h <<_ACEOF cat >>confdefs.h <<_ACEOF
@ -11529,7 +11529,7 @@ _ASBOX
} >&5 } >&5
cat >&5 <<_CSEOF 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 generated by GNU Autoconf 2.59. Invocation command line was
CONFIG_FILES = $CONFIG_FILES CONFIG_FILES = $CONFIG_FILES
@ -11592,7 +11592,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF cat >>$CONFIG_STATUS <<_ACEOF
ac_cs_version="\\ ac_cs_version="\\
aria2c config.status 0.4.1 aria2c config.status 0.4.2
configured by $0, generated by GNU Autoconf 2.59, configured by $0, generated by GNU Autoconf 2.59,
with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" 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. # Process this file with autoconf to produce a configure script.
# #
AC_PREREQ(2.59) 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_INIT_AUTOMAKE()
AM_PATH_CPPUNIT(1.10.2) AM_PATH_CPPUNIT(1.10.2)
AC_CONFIG_SRCDIR([src/Socket.h]) AC_CONFIG_SRCDIR([src/Socket.h])

View File

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

View File

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

BIN
po/de.gmo

Binary file not shown.

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: de\n" "Project-Id-Version: de\n"
"Report-Msgid-Bugs-To: http://aria2.sourceforge.net/\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" "PO-Revision-Date: 2006-05-05 19:44+0900\n"
"Last-Translator: Hermann J. Beckers <hj.beckers@onlinehome.de>\n" "Last-Translator: Hermann J. Beckers <hj.beckers@onlinehome.de>\n"
"Language-Team: deutsch <de@li.org>\n" "Language-Team: deutsch <de@li.org>\n"
@ -355,7 +355,7 @@ msgstr ""
"\n" "\n"
"Abruf wegen Fehlern nicht vollständig. Überprüfen Sie die Log-Datei.\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 "" msgid ""
"\n" "\n"
"stopping application...\n" "stopping application...\n"
@ -363,7 +363,7 @@ msgstr ""
"\n" "\n"
"Anwendung wird gestoppt ...\n" "Anwendung wird gestoppt ...\n"
#: src/main.cc:96 src/main.cc:111 #: src/main.cc:94 src/main.cc:111
msgid "done\n" msgid "done\n"
msgstr "erledigt\n" msgstr "erledigt\n"
@ -820,10 +820,10 @@ msgstr "Geben Sie zumindest eine URL an"
msgid "daemon failed" msgid "daemon failed"
msgstr "Daemon-Start nicht erfolgreich" msgstr "Daemon-Start nicht erfolgreich"
#: src/main.cc:671 #: src/main.cc:670
msgid "Files:" msgid "Files:"
msgstr "Dateien:" msgstr "Dateien:"
#: src/main.cc:702 #: src/main.cc:701
msgid "Errors occurred while binding port.\n" msgid "Errors occurred while binding port.\n"
msgstr "Fehler beim Binden an Port aufgetreten.\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 "" msgstr ""
"Project-Id-Version: aria2c 0.2.1\n" "Project-Id-Version: aria2c 0.2.1\n"
"Report-Msgid-Bugs-To: http://aria2.sourceforge.net/\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" "PO-Revision-Date: 2006-05-05 19:45+0900\n"
"Last-Translator: Tatsuhiro Tsujikawa <tujikawa@rednoah.com>\n" "Last-Translator: Tatsuhiro Tsujikawa <tujikawa@rednoah.com>\n"
"Language-Team: Japanese <ja@li.org>\n" "Language-Team: Japanese <ja@li.org>\n"
@ -358,7 +358,7 @@ msgstr ""
"\n" "\n"
"ダウンロードはエラーのため完了していません. ログを確認してください.\n" "ダウンロードはエラーのため完了していません. ログを確認してください.\n"
#: src/main.cc:92 src/main.cc:101 #: src/main.cc:88 src/main.cc:99
msgid "" msgid ""
"\n" "\n"
"stopping application...\n" "stopping application...\n"
@ -366,7 +366,7 @@ msgstr ""
"\n" "\n"
"アプリケーションを終了しています...\n" "アプリケーションを終了しています...\n"
#: src/main.cc:96 src/main.cc:111 #: src/main.cc:94 src/main.cc:111
msgid "done\n" msgid "done\n"
msgstr "完了\n" msgstr "完了\n"
@ -847,10 +847,10 @@ msgstr "
msgid "daemon failed" msgid "daemon failed"
msgstr "デーモン起動に失敗" msgstr "デーモン起動に失敗"
#: src/main.cc:671 #: src/main.cc:670
msgid "Files:" msgid "Files:"
msgstr "ファイル:" msgstr "ファイル:"
#: src/main.cc:702 #: src/main.cc:701
msgid "Errors occurred while binding port.\n" msgid "Errors occurred while binding port.\n"
msgstr "ポートをバインド中にエラーが発生しました.\n" msgstr "ポートをバインド中にエラーが発生しました.\n"

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -37,13 +37,13 @@ bool FtpTunnelResponseCommand::executeInternal(Segment segment) {
int status = http->receiveResponse(headers); int status = http->receiveResponse(headers);
if(status == 0) { if(status == 0) {
// we didn't receive all of headers yet. // we didn't receive all of headers yet.
e->commands.push(this); e->commands.push_back(this);
return false; return false;
} }
if(status != 200) { if(status != 200) {
throw new DlRetryEx(EX_PROXY_CONNECTION_FAILED); throw new DlRetryEx(EX_PROXY_CONNECTION_FAILED);
} }
FtpNegotiationCommand* command = new FtpNegotiationCommand(cuid, req, e, socket); FtpNegotiationCommand* command = new FtpNegotiationCommand(cuid, req, e, socket);
e->commands.push(command); e->commands.push_back(command);
return true; 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_ #define _D_HANDSHAKE_MESSAGE_H_
#include "common.h" #include "common.h"
#include "Util.h"
class SendMessageQueue;
#define PSTR "BitTorrent protocol" #define PSTR "BitTorrent protocol"
#define HANDSHAKE_MESSAGE_LENGTH 68 #define HANDSHAKE_MESSAGE_LENGTH 68
@ -34,14 +35,16 @@ public:
string pstr; string pstr;
unsigned char infoHash[20]; unsigned char infoHash[20];
char peerId[20]; char peerId[20];
SendMessageQueue* sendMessageQueue;
public: public:
HandshakeMessage() {} HandshakeMessage() {}
~HandshakeMessage() {} ~HandshakeMessage() {}
string toString() const { SendMessageQueue* getSendMessageQueue() const { return sendMessageQueue; }
return "handshake peerId="+ void setSendMessageQueue(SendMessageQueue* sendMessageQueue);
Util::urlencode((unsigned char*)peerId, sizeof(peerId));
} string toString() const;
void check();
}; };
#endif // _D_HANDSHAKE_MESSAGE_H_ #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) { int HttpConnection::receiveResponse(HttpHeader& headers) {
//char buf[512]; //char buf[512];
string header; string header;
int delimiterSwith = 0; int delimiterSwitch = 0;
char* delimiters[] = { "\r\n", "\n" }; char* delimiters[] = { "\r\n", "\n" };
int size = HEADERBUF_SIZE-headerBufLength; int size = HEADERBUF_SIZE-headerBufLength;
@ -137,19 +137,20 @@ int HttpConnection::receiveResponse(HttpHeader& headers) {
//header += buf; //header += buf;
//string::size_type p; //string::size_type p;
int eohIndex; int eohIndex;
if((eohIndex = findEndOfHeader(headerBuf, "\r\n\r\n", hlenTemp)) == -1 && if((eohIndex = findEndOfHeader(headerBuf, "\r\n\r\n", hlenTemp)) == -1 &&
(eohIndex = findEndOfHeader(headerBuf, "\n\n", hlenTemp)) == -1) { (eohIndex = findEndOfHeader(headerBuf, "\n\n", hlenTemp)) == -1) {
socket->readData(headerBuf+headerBufLength, size); socket->readData(headerBuf+headerBufLength, size);
} else { } else {
if(eohIndex[headerBuf] == '\n') { if(eohIndex[headerBuf] == '\n') {
// for crapping non-standard HTTP server // for crapping non-standard HTTP server
delimiterSwith = 1; delimiterSwitch = 1;
} else { } else {
delimiterSwith = 0; delimiterSwitch = 0;
} }
headerBuf[eohIndex+strlen(delimiters[delimiterSwith])*2] = '\0'; headerBuf[eohIndex+strlen(delimiters[delimiterSwitch])*2] = '\0';
header = headerBuf; header = headerBuf;
size = eohIndex+strlen(delimiters[delimiterSwith])*2-headerBufLength; size = eohIndex+strlen(delimiters[delimiterSwitch])*2-headerBufLength;
socket->readData(headerBuf+headerBufLength, size); socket->readData(headerBuf+headerBufLength, size);
} }
if(!Util::endsWith(header, "\r\n\r\n") && !Util::endsWith(header, "\n\n")) { 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()); logger->info(MSG_RECEIVE_RESPONSE, cuid, header.c_str());
string::size_type p, np; string::size_type p, np;
p = np = 0; p = np = 0;
np = header.find(delimiters[delimiterSwith], p); np = header.find(delimiters[delimiterSwitch], p);
if(np == string::npos) { if(np == string::npos) {
throw new DlRetryEx(EX_NO_STATUS_HEADER); throw new DlRetryEx(EX_NO_STATUS_HEADER);
} }
// check HTTP status value // check HTTP status value
if(header.size() <= 12) {
throw new DlRetryEx(EX_NO_STATUS_HEADER);
}
string status = header.substr(9, 3); string status = header.substr(9, 3);
p = np+2; p = np+2;
// retreive status name-value pairs, then push these into map // 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); string line = header.substr(p, np-p);
p = np+2; p = np+2;
pair<string, string> hp; pair<string, string> hp;

View File

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

View File

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

View File

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

View File

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

View File

@ -45,7 +45,7 @@ bool HttpResponseCommand::executeInternal(Segment seg) {
int status = http->receiveResponse(headers); int status = http->receiveResponse(headers);
if(status == 0) { if(status == 0) {
// didn't receive header fully // didn't receive header fully
e->commands.push(this); e->commands.push_back(this);
return false; return false;
} }
// check HTTP status number // check HTTP status number
@ -65,7 +65,7 @@ bool HttpResponseCommand::executeInternal(Segment seg) {
return handleDefaultEncoding(headers); return handleDefaultEncoding(headers);
} }
} else { } 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()); throw new DlAbortEx(EX_FILENAME_MISMATCH, req->getFile().c_str(), e->segmentMan->filename.c_str());
} }
createHttpDownloadCommand(); createHttpDownloadCommand();
@ -91,6 +91,18 @@ bool HttpResponseCommand::handleRedirect(const string& url, const HttpHeader& he
return prepareForRetry(0); 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) { bool HttpResponseCommand::handleDefaultEncoding(const HttpHeader& headers) {
// TODO quick and dirty way // TODO quick and dirty way
if(req->isTorrent) { if(req->isTorrent) {
@ -108,7 +120,7 @@ bool HttpResponseCommand::handleDefaultEncoding(const HttpHeader& headers) {
throw new DlAbortEx(EX_TOO_LARGE_FILE, size); throw new DlAbortEx(EX_TOO_LARGE_FILE, size);
} }
e->segmentMan->isSplittable = !(size == 0); e->segmentMan->isSplittable = !(size == 0);
e->segmentMan->filename = req->getFile(); e->segmentMan->filename = determinFilename(headers);
bool segFileExists = e->segmentMan->segmentFileExists(); bool segFileExists = e->segmentMan->segmentFileExists();
e->segmentMan->downloadStarted = true; e->segmentMan->downloadStarted = true;
if(segFileExists) { if(segFileExists) {
@ -130,7 +142,7 @@ bool HttpResponseCommand::handleOtherEncoding(const string& transferEncoding, co
// we ignore content-length when transfer-encoding is set // we ignore content-length when transfer-encoding is set
e->segmentMan->downloadStarted = true; e->segmentMan->downloadStarted = true;
e->segmentMan->isSplittable = false; e->segmentMan->isSplittable = false;
e->segmentMan->filename = req->getFile(); e->segmentMan->filename = determinFilename(headers);
e->segmentMan->totalSize = 0; e->segmentMan->totalSize = 0;
Segment seg; Segment seg;
e->segmentMan->getSegment(seg, cuid); e->segmentMan->getSegment(seg, cuid);
@ -151,7 +163,7 @@ void HttpResponseCommand::createHttpDownloadCommand(const string& transferEncodi
command->transferEncoding = transferEncoding; command->transferEncoding = transferEncoding;
enc->init(); 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); bool handleOtherEncoding(const string& transferEncoding, const HttpHeader& headers);
void createHttpDownloadCommand(const string& transferEncoding = ""); void createHttpDownloadCommand(const string& transferEncoding = "");
void retrieveCookie(const HttpHeader& headers); void retrieveCookie(const HttpHeader& headers);
string determinFilename(const HttpHeader& headers);
HttpConnection* http; HttpConnection* http;
protected: protected:
bool executeInternal(Segment segment); 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; return logger;
} }
void LogFactory::release() {
delete logger;
logger = NULL;
}

View File

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

View File

@ -65,12 +65,10 @@ SRCS = Socket.cc Socket.h\
TorrentDownloadEngine.cc TorrentDownloadEngine.h\ TorrentDownloadEngine.cc TorrentDownloadEngine.h\
TorrentConsoleDownloadEngine.cc TorrentConsoleDownloadEngine.h\ TorrentConsoleDownloadEngine.cc TorrentConsoleDownloadEngine.h\
PeerListenCommand.cc PeerListenCommand.h\ PeerListenCommand.cc PeerListenCommand.h\
PendingMessage.cc PendingMessage.h\
PeerMessage.cc PeerMessage.h\ PeerMessage.cc PeerMessage.h\
HandshakeMessage.h\ HandshakeMessage.cc HandshakeMessage.h\
Piece.cc Piece.h\ Piece.cc Piece.h\
RequestSlot.cc RequestSlot.h\ RequestSlot.cc RequestSlot.h\
RequestSlotMan.cc RequestSlotMan.h\
TorrentAutoSaveCommand.cc TorrentAutoSaveCommand.h\ TorrentAutoSaveCommand.cc TorrentAutoSaveCommand.h\
Directory.cc Directory.h\ Directory.cc Directory.h\
TrackerWatcherCommand.cc TrackerWatcherCommand.h\ TrackerWatcherCommand.cc TrackerWatcherCommand.h\
@ -85,7 +83,18 @@ SRCS = Socket.cc Socket.h\
LogFactory.cc LogFactory.h\ LogFactory.cc LogFactory.h\
TrackerUpdateCommand.cc TrackerUpdateCommand.h\ TrackerUpdateCommand.cc TrackerUpdateCommand.h\
ByteArrayDiskWriter.cc ByteArrayDiskWriter.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 noinst_LIBRARIES = libaria2c.a
libaria2c_a_SOURCES = $(SRCS) libaria2c_a_SOURCES = $(SRCS)
aria2c_LDADD = libaria2c.a @LIBINTL@ @ALLOCA@ @LIBGNUTLS_LIBS@\ aria2c_LDADD = libaria2c.a @LIBINTL@ @ALLOCA@ @LIBGNUTLS_LIBS@\

View File

@ -92,15 +92,20 @@ am__objects_1 = Socket.$(OBJEXT) SocketCore.$(OBJEXT) \
PeerInteractionCommand.$(OBJEXT) Peer.$(OBJEXT) \ PeerInteractionCommand.$(OBJEXT) Peer.$(OBJEXT) \
BitfieldMan.$(OBJEXT) TorrentDownloadEngine.$(OBJEXT) \ BitfieldMan.$(OBJEXT) TorrentDownloadEngine.$(OBJEXT) \
TorrentConsoleDownloadEngine.$(OBJEXT) \ TorrentConsoleDownloadEngine.$(OBJEXT) \
PeerListenCommand.$(OBJEXT) PendingMessage.$(OBJEXT) \ PeerListenCommand.$(OBJEXT) PeerMessage.$(OBJEXT) \
PeerMessage.$(OBJEXT) Piece.$(OBJEXT) RequestSlot.$(OBJEXT) \ HandshakeMessage.$(OBJEXT) Piece.$(OBJEXT) \
RequestSlotMan.$(OBJEXT) TorrentAutoSaveCommand.$(OBJEXT) \ RequestSlot.$(OBJEXT) TorrentAutoSaveCommand.$(OBJEXT) \
Directory.$(OBJEXT) TrackerWatcherCommand.$(OBJEXT) \ Directory.$(OBJEXT) TrackerWatcherCommand.$(OBJEXT) \
SendMessageQueue.$(OBJEXT) MultiDiskWriter.$(OBJEXT) \ SendMessageQueue.$(OBJEXT) MultiDiskWriter.$(OBJEXT) \
DiskAdaptor.$(OBJEXT) CopyDiskAdaptor.$(OBJEXT) \ DiskAdaptor.$(OBJEXT) CopyDiskAdaptor.$(OBJEXT) \
DirectDiskAdaptor.$(OBJEXT) MultiDiskAdaptor.$(OBJEXT) \ DirectDiskAdaptor.$(OBJEXT) MultiDiskAdaptor.$(OBJEXT) \
LogFactory.$(OBJEXT) TrackerUpdateCommand.$(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) am_libaria2c_a_OBJECTS = $(am__objects_1)
libaria2c_a_OBJECTS = $(am_libaria2c_a_OBJECTS) libaria2c_a_OBJECTS = $(am_libaria2c_a_OBJECTS)
am__installdirs = "$(DESTDIR)$(bindir)" am__installdirs = "$(DESTDIR)$(bindir)"
@ -315,12 +320,10 @@ SRCS = Socket.cc Socket.h\
TorrentDownloadEngine.cc TorrentDownloadEngine.h\ TorrentDownloadEngine.cc TorrentDownloadEngine.h\
TorrentConsoleDownloadEngine.cc TorrentConsoleDownloadEngine.h\ TorrentConsoleDownloadEngine.cc TorrentConsoleDownloadEngine.h\
PeerListenCommand.cc PeerListenCommand.h\ PeerListenCommand.cc PeerListenCommand.h\
PendingMessage.cc PendingMessage.h\
PeerMessage.cc PeerMessage.h\ PeerMessage.cc PeerMessage.h\
HandshakeMessage.h\ HandshakeMessage.cc HandshakeMessage.h\
Piece.cc Piece.h\ Piece.cc Piece.h\
RequestSlot.cc RequestSlot.h\ RequestSlot.cc RequestSlot.h\
RequestSlotMan.cc RequestSlotMan.h\
TorrentAutoSaveCommand.cc TorrentAutoSaveCommand.h\ TorrentAutoSaveCommand.cc TorrentAutoSaveCommand.h\
Directory.cc Directory.h\ Directory.cc Directory.h\
TrackerWatcherCommand.cc TrackerWatcherCommand.h\ TrackerWatcherCommand.cc TrackerWatcherCommand.h\
@ -335,7 +338,18 @@ SRCS = Socket.cc Socket.h\
LogFactory.cc LogFactory.h\ LogFactory.cc LogFactory.h\
TrackerUpdateCommand.cc TrackerUpdateCommand.h\ TrackerUpdateCommand.cc TrackerUpdateCommand.h\
ByteArrayDiskWriter.cc ByteArrayDiskWriter.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 noinst_LIBRARIES = libaria2c.a
libaria2c_a_SOURCES = $(SRCS) 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)/AbstractDiskWriter.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Base64.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)/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)/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)/ChunkedEncoding.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ConsoleDownloadEngine.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@ @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)/FtpNegotiationCommand.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FtpTunnelRequestCommand.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)/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)/HttpConnection.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HttpDownloadCommand.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@ @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)/HttpRequestCommand.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HttpResponseCommand.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)/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)/List.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/LogFactory.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)/MetaFileUtil.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MultiDiskAdaptor.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)/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)/Option.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Peer.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@ @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)/PeerListenCommand.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PeerMessage.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PeerMessage.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PeerMessageUtil.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)/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)/PreAllocationDiskWriter.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Request.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)/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)/SegmentMan.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SegmentSplitter.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@ @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)/TorrentMan.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TrackerUpdateCommand.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)/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)/Util.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.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; checkPoint.tv_usec = 0;
throw new DlRetryEx(EX_TIME_OUT); throw new DlRetryEx(EX_TIME_OUT);
} }
e->commands.push(this); e->commands.push_back(this);
return false; return false;
} }
updateCheckPoint(); updateCheckPoint();
@ -95,24 +95,6 @@ bool PeerAbstractCommand::execute() {
delete(err); delete(err);
return prepareForNextPeer(0); 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 // TODO this method removed when PeerBalancerCommand is implemented

View File

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

View File

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

View File

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

View File

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

View File

@ -37,10 +37,9 @@ PeerInteractionCommand::PeerInteractionCommand(int cuid, Peer* peer,
setWriteCheckSocket(socket); setWriteCheckSocket(socket);
setTimeout(e->option->getAsInt(PREF_PEER_CONNECTION_TIMEOUT)); setTimeout(e->option->getAsInt(PREF_PEER_CONNECTION_TIMEOUT));
} }
peerConnection = new PeerConnection(cuid, socket, e->option, peer, e->torrentMan); sendMessageQueue = new SendMessageQueue(cuid, socket, e->option,
sendMessageQueue = new SendMessageQueue(cuid, peerConnection, e->torrentMan); e->torrentMan, this->peer);
sendMessageQueue->setUploadLimit(e->option->getAsInt(PREF_UPLOAD_LIMIT)); sendMessageQueue->setUploadLimit(e->option->getAsInt(PREF_UPLOAD_LIMIT));
piece = Piece::nullPiece;
keepAliveCheckPoint.tv_sec = 0; keepAliveCheckPoint.tv_sec = 0;
keepAliveCheckPoint.tv_usec = 0; keepAliveCheckPoint.tv_usec = 0;
chokeCheckPoint.tv_sec = 0; chokeCheckPoint.tv_sec = 0;
@ -54,7 +53,6 @@ PeerInteractionCommand::PeerInteractionCommand(int cuid, Peer* peer,
} }
PeerInteractionCommand::~PeerInteractionCommand() { PeerInteractionCommand::~PeerInteractionCommand() {
delete peerConnection;
delete sendMessageQueue; delete sendMessageQueue;
e->torrentMan->unadvertisePiece(cuid); e->torrentMan->unadvertisePiece(cuid);
e->torrentMan->deleteActivePeer(this->peer); e->torrentMan->deleteActivePeer(this->peer);
@ -70,11 +68,11 @@ bool PeerInteractionCommand::executeInternal() {
switch(sequence) { switch(sequence) {
case INITIATOR_SEND_HANDSHAKE: case INITIATOR_SEND_HANDSHAKE:
peerConnection->sendHandshake(); sendMessageQueue->sendHandshake();
sequence = INITIATOR_WAIT_HANDSHAKE; sequence = INITIATOR_WAIT_HANDSHAKE;
break; break;
case INITIATOR_WAIT_HANDSHAKE: { case INITIATOR_WAIT_HANDSHAKE: {
HandshakeMessage* handshakeMessage = peerConnection->receiveHandshake(); HandshakeMessage* handshakeMessage = sendMessageQueue->receiveHandshake();
if(handshakeMessage == NULL) { if(handshakeMessage == NULL) {
break; break;
} }
@ -84,13 +82,13 @@ bool PeerInteractionCommand::executeInternal() {
handshakeMessage->toString().c_str()); handshakeMessage->toString().c_str());
delete handshakeMessage; delete handshakeMessage;
if(e->torrentMan->getDownloadLength() > 0) { if(e->torrentMan->getDownloadLength() > 0) {
peerConnection->sendBitfield(); sendMessageQueue->sendNow(sendMessageQueue->createBitfieldMessage());
} }
sequence = WIRED; sequence = WIRED;
break; break;
} }
case RECEIVER_WAIT_HANDSHAKE: { case RECEIVER_WAIT_HANDSHAKE: {
HandshakeMessage* handshakeMessage = peerConnection->receiveHandshake(); HandshakeMessage* handshakeMessage = sendMessageQueue->receiveHandshake();
if(handshakeMessage == NULL) { if(handshakeMessage == NULL) {
break; break;
} }
@ -99,9 +97,9 @@ bool PeerInteractionCommand::executeInternal() {
peer->ipaddr.c_str(), peer->port, peer->ipaddr.c_str(), peer->port,
handshakeMessage->toString().c_str()); handshakeMessage->toString().c_str());
delete handshakeMessage; delete handshakeMessage;
peerConnection->sendHandshake(); sendMessageQueue->sendHandshake();
if(e->torrentMan->getDownloadLength() > 0) { if(e->torrentMan->getDownloadLength() > 0) {
peerConnection->sendBitfield(); sendMessageQueue->sendNow(sendMessageQueue->createBitfieldMessage());
} }
sequence = WIRED; sequence = WIRED;
break; break;
@ -110,7 +108,7 @@ bool PeerInteractionCommand::executeInternal() {
detectMessageFlooding(); detectMessageFlooding();
checkLongTimePeerChoking(); checkLongTimePeerChoking();
checkInactiveConnection(); checkInactiveConnection();
syncPiece(); sendMessageQueue->syncPiece();
decideChoking(); decideChoking();
for(int i = 0; i < 10; i++) { for(int i = 0; i < 10; i++) {
if(!socket->isReadable(0)) { if(!socket->isReadable(0)) {
@ -118,16 +116,15 @@ bool PeerInteractionCommand::executeInternal() {
} }
receiveMessage(); receiveMessage();
} }
sendMessageQueue->deleteTimeoutRequestSlot(piece); sendMessageQueue->deleteTimeoutRequestSlot();
sendMessageQueue->deleteCompletedRequestSlot(piece); sendMessageQueue->deleteCompletedRequestSlot();
sendInterest(); sendMessageQueue->sendMessages(e->getUploadSpeed());
sendMessages();
break; break;
} }
if(sendMessageQueue->countPendingMessage() > 0) { if(sendMessageQueue->countMessageInQueue() > 0) {
setWriteCheckSocket(socket); setWriteCheckSocket(socket);
} }
e->commands.push(this); e->commands.push_back(this);
return false; return false;
} }
@ -184,109 +181,47 @@ void PeerInteractionCommand::checkLongTimePeerChoking() {
} }
} }
void PeerInteractionCommand::syncPiece() {
if(Piece::isNull(piece)) {
return;
}
e->torrentMan->syncPiece(piece);
}
void PeerInteractionCommand::decideChoking() { void PeerInteractionCommand::decideChoking() {
if(peer->shouldBeChoking()) { if(peer->shouldBeChoking()) {
if(!peer->amChoking) { if(!peer->amChoking) {
PendingMessage pendingMessage(PeerMessage::CHOKE, peerConnection); sendMessageQueue->addMessage(sendMessageQueue->createChokeMessage());
sendMessageQueue->addPendingMessage(pendingMessage);
} }
} else { } else {
if(peer->amChoking) { if(peer->amChoking) {
PendingMessage pendingMessage(PeerMessage::UNCHOKE, peerConnection); sendMessageQueue->addMessage(sendMessageQueue->createUnchokeMessage());
sendMessageQueue->addPendingMessage(pendingMessage);
} }
} }
} }
void PeerInteractionCommand::receiveMessage() { void PeerInteractionCommand::receiveMessage() {
PeerMessage* message = peerConnection->receiveMessage(); PeerMessage* message = sendMessageQueue->receiveMessage();
if(message == NULL) { if(message == NULL) {
return; return;
} }
logger->info(MSG_RECEIVE_PEER_MESSAGE, cuid, logger->info(MSG_RECEIVE_PEER_MESSAGE, cuid,
peer->ipaddr.c_str(), peer->port, peer->ipaddr.c_str(), peer->port,
message->toString().c_str()); message->toString().c_str());
try { // to detect flooding
switch(message->getId()) { switch(message->getId()) {
case PeerMessage::KEEP_ALIVE: case KeepAliveMessage::ID:
keepAliveCount++; keepAliveCount++;
break; break;
case PeerMessage::CHOKE: case ChokeMessage::ID:
if(!peer->peerChoking) { if(!peer->peerChoking) {
chokeUnchokeCount++; chokeUnchokeCount++;
} }
peer->peerChoking = true;
break; break;
case PeerMessage::UNCHOKE: case UnchokeMessage::ID:
if(peer->peerChoking) { if(peer->peerChoking) {
chokeUnchokeCount++; chokeUnchokeCount++;
} }
peer->peerChoking = false;
break; break;
case PeerMessage::INTERESTED: case HaveMessage::ID:
peer->peerInterested = true;
break;
case PeerMessage::NOT_INTERESTED:
peer->peerInterested = false;
break;
case PeerMessage::HAVE:
haveCount++; 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; break;
} }
} try {
message->receivedAction();
delete message; delete message;
} catch(Exception* ex) { } catch(Exception* ex) {
delete message; 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 // TODO this method removed when PeerBalancerCommand is implemented
bool PeerInteractionCommand::prepareForNextPeer(int wait) { bool PeerInteractionCommand::prepareForNextPeer(int wait) {
if(e->torrentMan->isPeerAvailable()) { if(e->torrentMan->isPeerAvailable()) {
@ -315,81 +236,18 @@ bool PeerInteractionCommand::prepareForNextPeer(int wait) {
int newCuid = e->torrentMan->getNewCuid(); int newCuid = e->torrentMan->getNewCuid();
peer->cuid = newCuid; peer->cuid = newCuid;
PeerInitiateConnectionCommand* command = new PeerInitiateConnectionCommand(newCuid, peer, e); PeerInitiateConnectionCommand* command = new PeerInitiateConnectionCommand(newCuid, peer, e);
e->commands.push(command); e->commands.push_back(command);
} }
return true; return true;
} }
bool PeerInteractionCommand::prepareForRetry(int wait) { bool PeerInteractionCommand::prepareForRetry(int wait) {
e->commands.push(this); e->commands.push_back(this);
return false; 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) { void PeerInteractionCommand::onAbort(Exception* ex) {
sendMessageQueue->cancelAllRequest(piece); sendMessageQueue->abortPiece();
e->torrentMan->cancelPiece(piece);
PeerAbstractCommand::onAbort(ex); PeerAbstractCommand::onAbort(ex);
} }
@ -400,8 +258,8 @@ void PeerInteractionCommand::keepAlive() {
struct timeval now; struct timeval now;
gettimeofday(&now, NULL); gettimeofday(&now, NULL);
if(Util::difftv(now, keepAliveCheckPoint) >= (long long int)120*1000000) { if(Util::difftv(now, keepAliveCheckPoint) >= (long long int)120*1000000) {
if(sendMessageQueue->countPendingMessage() == 0) { if(sendMessageQueue->countMessageInQueue() == 0) {
peerConnection->sendKeepAlive(); sendMessageQueue->sendNow(sendMessageQueue->createKeepAliveMessage());
} }
keepAliveCheckPoint = now; keepAliveCheckPoint = now;
} }
@ -417,41 +275,12 @@ void PeerInteractionCommand::beforeSocketCheck() {
PieceIndexes indexes = e->torrentMan->getAdvertisedPieceIndexes(cuid); PieceIndexes indexes = e->torrentMan->getAdvertisedPieceIndexes(cuid);
if(indexes.size() >= 20) { if(indexes.size() >= 20) {
PendingMessage pendingMessage(PeerMessage::BITFIELD, peerConnection); sendMessageQueue->trySendNow(sendMessageQueue->createBitfieldMessage());
sendMessageQueue->addPendingMessage(pendingMessage);
} else {
if(sendMessageQueue->countPendingMessage() == 0) {
for(PieceIndexes::iterator itr = indexes.begin(); itr != indexes.end(); itr++) {
peerConnection->sendHave(*itr);
}
} else { } else {
for(PieceIndexes::iterator itr = indexes.begin(); itr != indexes.end(); itr++) { for(PieceIndexes::iterator itr = indexes.begin(); itr != indexes.end(); itr++) {
PendingMessage pendingMessage = PendingMessage::createHaveMessage(*itr, peerConnection); sendMessageQueue->trySendNow(sendMessageQueue->createHaveMessage(*itr));
sendMessageQueue->addPendingMessage(pendingMessage);
}
} }
} }
keepAlive(); 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 { class PeerInteractionCommand : public PeerAbstractCommand {
private: private:
int sequence; int sequence;
PeerConnection* peerConnection;
SendMessageQueue* sendMessageQueue; SendMessageQueue* sendMessageQueue;
Piece piece;
struct timeval keepAliveCheckPoint; struct timeval keepAliveCheckPoint;
struct timeval chokeCheckPoint; struct timeval chokeCheckPoint;
struct timeval freqCheckPoint; struct timeval freqCheckPoint;
@ -46,18 +45,9 @@ private:
void detectMessageFlooding(); void detectMessageFlooding();
void checkLongTimePeerChoking(); void checkLongTimePeerChoking();
void checkInactiveConnection(); void checkInactiveConnection();
void syncPiece();
void detectTimeoutAndDuplicateBlock(); void detectTimeoutAndDuplicateBlock();
void decideChoking(); void decideChoking();
void sendInterest();
void sendMessages();
void createRequestPendingMessage(int blockIndex);
bool checkPieceHash(const Piece& piece);
void erasePieceOnDisk(const Piece& piece);
void keepAlive(); void keepAlive();
Piece getNewPieceAndSendInterest();
void onGotNewPiece();
void onGotWrongPiece();
protected: protected:
bool executeInternal(); bool executeInternal();
bool prepareForRetry(int wait); bool prepareForRetry(int wait);

View File

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

View File

@ -20,53 +20,8 @@
*/ */
/* copyright --> */ /* copyright --> */
#include "PeerMessage.h" #include "PeerMessage.h"
#include "Util.h" #include "LogFactory.h"
void PeerMessage::setBitfield(const unsigned char* bitfield, int bitfieldLength) { PeerMessage::PeerMessage():inProgress(false) {
if(this->bitfield != NULL) { logger = LogFactory::getInstance();
delete [] this->bitfield;
} }
this->bitfieldLength = bitfieldLength;
this->bitfield = new unsigned char[this->bitfieldLength];
memcpy(this->bitfield, bitfield, this->bitfieldLength);
}
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_ #define _D_PEER_MESSAGE_H_
#include "common.h" #include "common.h"
#include "Logger.h"
#include "Peer.h"
#include <string> #include <string>
class SendMessageQueue;
class PeerMessage { class PeerMessage {
private: protected:
int id; bool inProgress;
int index; int cuid;
int begin; Peer* peer;
int length; SendMessageQueue* sendMessageQueue;
unsigned char* bitfield; const Logger* logger;
int bitfieldLength;
char* block;
int blockLength;
public: public:
PeerMessage():bitfield(NULL), bitfieldLength(0), PeerMessage();
block(NULL), blockLength(0) {}
~PeerMessage() { virtual ~PeerMessage() {}
if(bitfield != NULL) {
delete [] bitfield; bool isInProgress() const { return inProgress; }
int getCuid() const { return cuid; }
void setCuid(int cuid) {
this->cuid = cuid;
} }
if(block != NULL) { Peer* getPeer() const { return this->peer; }
delete [] block; 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); virtual int getId() const = 0;
const unsigned char* getBitfield() const { return bitfield; } virtual void receivedAction() = 0;
virtual void send() = 0;
void setBlock(const char* block, int blockLength); virtual void check() const {}
const char* getBlock() const { return block; } virtual string toString() const = 0;
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};
}; };
#endif // _D_PEER_MESSAGE_H_ #endif // _D_PEER_MESSAGE_H_

View File

@ -24,94 +24,6 @@
#include "Util.h" #include "Util.h"
#include <netinet/in.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) { int PeerMessageUtil::getId(const char* msg) {
return (int)msg[0]; return (int)msg[0];
} }
@ -122,50 +34,145 @@ int PeerMessageUtil::getIntParam(const char* msg, int offset) {
return ntohl(nParam); return ntohl(nParam);
} }
void PeerMessageUtil::checkIndex(const PeerMessage* message, int pieces) { int PeerMessageUtil::getShortIntParam(const char* msg, int offset) {
if(!(0 <= message->getIndex() && message->getIndex() < pieces)) { short int nParam;
throw new DlAbortEx("invalid index = %d", message->getIndex()); 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) { void PeerMessageUtil::checkBegin(int begin, int pieceLength) {
if(!(0 <= message->getBegin() && message->getBegin() < pieceLength)) { if(!(0 <= begin && begin < pieceLength)) {
throw new DlAbortEx("invalid begin = %d", message->getBegin()); throw new DlAbortEx("invalid begin = %d", begin);
} }
} }
void PeerMessageUtil::checkPieceOffset(const PeerMessage* message, int pieceLength, int pieces, long long int totalLength) { void PeerMessageUtil::checkLength(int length) {
if(!(0 <= message->getBegin() && 0 < message->getLength())) { if(length > MAX_BLOCK_LENGTH) {
throw new DlAbortEx("invalid offset, begin = %d, length = %d", message->getBegin(), message->getLength()); throw new DlAbortEx("too large length %d > %dKB", length,
}
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(),
MAX_BLOCK_LENGTH/1024); 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", throw new DlAbortEx("invalid length %d, which is not power of 2",
message->getLength()); length);
} }
} }
void PeerMessageUtil::checkBitfield(const PeerMessage* message, int pieces) { void PeerMessageUtil::checkRange(int begin, int length, int pieceLength) {
if(!(message->getBitfieldLength() == BITFIELD_LEN_FROM_PIECES(pieces))) { if(!(0 <= begin && 0 < length)) {
throw new DlAbortEx("invalid bitfield length = %d", message->getBitfieldLength()); 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++) { for(int i = 0; i < 8-pieces%8 && pieces%8 != 0; i++) {
if(!(((lastbyte >> i) & 1) == 0)) { if(!(((lastbyte >> i) & 1) == 0)) {
throw new DlAbortEx("invalid bitfield"); 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) { HandshakeMessage* PeerMessageUtil::createHandshakeMessage(const char* msg, int length) {
// 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* message = new HandshakeMessage(); HandshakeMessage* message = new HandshakeMessage();
message->pstrlen = msg[0]; message->pstrlen = msg[0];
char pstr[20]; char pstr[20];
@ -220,6 +192,7 @@ HandshakeMessage* PeerMessageUtil::createHandshakeMessage(const char* msg) {
return message; return message;
} }
void PeerMessageUtil::checkHandshake(const HandshakeMessage* message, const unsigned char* infoHash) { void PeerMessageUtil::checkHandshake(const HandshakeMessage* message, const unsigned char* infoHash) {
if(message->pstrlen != 19) { if(message->pstrlen != 19) {
throw new DlAbortEx("invalid handshake pstrlen = %d", (int)message->pstrlen); 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()); myInfoHash.c_str(), peerInfoHash.c_str());
} }
} }

View File

@ -22,6 +22,18 @@
#ifndef _D_PEER_MESSAGE_UTIL_H_ #ifndef _D_PEER_MESSAGE_UTIL_H_
#define _D_PEER_MESSAGE_UTIL_H_ #define _D_PEER_MESSAGE_UTIL_H_
#include "ChokeMessage.h"
#include "UnchokeMessage.h"
#include "InterestedMessage.h"
#include "NotInterestedMessage.h"
#include "HaveMessage.h"
#include "BitfieldMessage.h"
#include "RequestMessage.h"
#include "CancelMessage.h"
#include "PieceMessage.h"
#include "HandshakeMessage.h"
#include "KeepAliveMessage.h"
#include "PortMessage.h"
#include "PeerConnection.h" #include "PeerConnection.h"
#define MAX_BLOCK_LENGTH (128*1024) #define MAX_BLOCK_LENGTH (128*1024)
@ -30,23 +42,29 @@ class PeerMessageUtil {
private: private:
PeerMessageUtil() {} 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 int getIntParam(const char* msg, int offset);
static int getShortIntParam(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);
public: public:
static PeerMessage* createPeerMessage(const char* msg, int len); static int getId(const char* msg);
static void checkIntegrity(const PeerMessage* message, int pieceLength, int pieces, long long int totalLength);
static HandshakeMessage* createHandshakeMessage(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); 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 <unistd.h>
#include <errno.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(); logger = LogFactory::getInstance();
} }
SegmentMan::~SegmentMan() {} SegmentMan::~SegmentMan() {
if(splitter != NULL) {
delete splitter;
}
if(diskWriter != NULL) {
delete diskWriter;
}
}
void SegmentMan::unregisterId(int cuid) { void SegmentMan::unregisterId(int cuid) {
for(Segments::iterator itr = segments.begin(); itr != segments.end(); itr++) { for(Segments::iterator itr = segments.begin(); itr != segments.end(); itr++) {

View File

@ -21,74 +21,98 @@
/* copyright --> */ /* copyright --> */
#include "SendMessageQueue.h" #include "SendMessageQueue.h"
#include "LogFactory.h" #include "LogFactory.h"
#include "DlAbortEx.h"
#include "KeepAliveMessage.h"
#include "PeerMessageUtil.h"
#include <netinet/in.h>
SendMessageQueue::SendMessageQueue(int cuid, PeerConnection* peerConnection, SendMessageQueue::SendMessageQueue(int cuid,
TorrentMan* torrentMan) const Socket* socket,
:cuid(cuid), uploadLimit(0) { const Option* op,
requestSlotMan = new RequestSlotMan(cuid, &pendingMessages, peerConnection, TorrentMan* 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(); logger = LogFactory::getInstance();
} }
SendMessageQueue::~SendMessageQueue() { SendMessageQueue::~SendMessageQueue() {
delete requestSlotMan; delete peerConnection;
for_each(messageQueue.begin(), messageQueue.end(), Deleter());
} }
void SendMessageQueue::send(int uploadSpeed) { void SendMessageQueue::send(int uploadSpeed) {
int size = pendingMessages.size(); int size = messageQueue.size();
for(int i = 0; i < size; i++) { for(int i = 0; i < size; i++) {
PendingMessage msg = pendingMessages.front(); PeerMessage* msg = messageQueue.front();
pendingMessages.pop_front(); messageQueue.pop_front();
if(uploadLimit != 0 && uploadSpeed >= uploadLimit*1024 && if(uploadLimit != 0 && uploadLimit*1024 <= uploadSpeed &&
msg.getPeerMessageId() == PeerMessage::PIECE && !msg.isInProgress()) { msg->getId() == PieceMessage::ID && !msg->isInProgress()) {
pendingMessages.push_back(msg); messageQueue.push_back(msg);
} else { } else {
if(!msg.processMessage()) { try {
pendingMessages.push_front(msg); msg->send();
} catch(Exception* ex) {
delete msg;
throw;
}
if(msg->isInProgress()) {
messageQueue.push_front(msg);
break; break;
} else {
delete msg;
} }
} }
} }
} }
void SendMessageQueue::addPendingMessage(const PendingMessage& pendingMessage) { void SendMessageQueue::addMessage(PeerMessage* peerMessage) {
pendingMessages.push_back(pendingMessage); messageQueue.push_back(peerMessage);
if(pendingMessage.getPeerMessageId() == PeerMessage::REQUEST) { if(peerMessage->getId() == RequestMessage::ID) {
RequestSlot requestSlot(pendingMessage.getIndex(), RequestMessage* requestMessage = (RequestMessage*)peerMessage;
pendingMessage.getBegin(), RequestSlot requestSlot(requestMessage->getIndex(),
pendingMessage.getLength(), requestMessage->getBegin(),
pendingMessage.getBlockIndex()); requestMessage->getLength(),
requestSlotMan->addRequestSlot(requestSlot); requestMessage->getBlockIndex());
requestSlots.push_back(requestSlot);
} }
} }
void SendMessageQueue::deletePendingPieceMessage(const PeerMessage* cancelMessage) { void SendMessageQueue::deletePieceMessageInQueue(const CancelMessage* cancelMessage) {
for(PendingMessages::iterator itr = pendingMessages.begin(); for(MessageQueue::iterator itr = messageQueue.begin();
itr != pendingMessages.end();) { itr != messageQueue.end();) {
PendingMessage& pendingMessage = *itr; if((*itr)->getId() == PieceMessage::ID) {
if(pendingMessage.getPeerMessageId() == PeerMessage::PIECE && PieceMessage* pieceMessage = (PieceMessage*)*itr;
pendingMessage.getIndex() == cancelMessage->getIndex() && if(pieceMessage->getIndex() == cancelMessage->getIndex() &&
pendingMessage.getBegin() == cancelMessage->getBegin() && pieceMessage->getBegin() == cancelMessage->getBegin() &&
pendingMessage.getLength() == cancelMessage->getLength() && pieceMessage->getBlockLength() == cancelMessage->getLength() &&
!pendingMessage.isInProgress()) { !pieceMessage->isInProgress()) {
logger->debug("CUID#%d - deleting pending piece message because cancel message received. index=%d, begin=%d, length=%d", logger->debug("CUID#%d - deleting piece message in queue because cancel message received. index=%d, begin=%d, length=%d",
cuid, cuid,
pendingMessage.getIndex(), cancelMessage->getIndex(),
pendingMessage.getBegin(), cancelMessage->getBegin(),
pendingMessage.getLength()); cancelMessage->getLength());
itr = pendingMessages.erase(itr); delete pieceMessage;
itr = messageQueue.erase(itr);
} else {
itr++;
}
} else { } else {
itr++; itr++;
} }
} }
} }
void SendMessageQueue::deletePendingRequestMessage() { void SendMessageQueue::deleteRequestMessageInQueue() {
for(PendingMessages::iterator itr = pendingMessages.begin(); for(MessageQueue::iterator itr = messageQueue.begin();
itr != pendingMessages.end();) { itr != messageQueue.end();) {
PendingMessage& pendingMessage = *itr; if((*itr)->getId() == RequestMessage::ID) {
if(pendingMessage.getPeerMessageId() == PeerMessage::REQUEST) { delete *itr;
itr = pendingMessages.erase(itr); itr = messageQueue.erase(itr);
} else { } else {
itr++; itr++;
} }
@ -96,19 +120,73 @@ void SendMessageQueue::deletePendingRequestMessage() {
} }
void SendMessageQueue::deleteRequestSlot(const RequestSlot& requestSlot) { 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) { void SendMessageQueue::deleteAllRequestSlot(Piece& piece) {
requestSlotMan->deleteTimeoutRequestSlot(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) { void SendMessageQueue::deleteTimeoutRequestSlot() {
requestSlotMan->deleteCompletedRequestSlot(piece); 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 { void SendMessageQueue::deleteCompletedRequestSlot() {
return requestSlotMan->getCorrespoindingRequestSlot(pieceMessage); 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() { void SendMessageQueue::cancelAllRequest() {
@ -116,14 +194,274 @@ void SendMessageQueue::cancelAllRequest() {
} }
void SendMessageQueue::cancelAllRequest(Piece& piece) { void SendMessageQueue::cancelAllRequest(Piece& piece) {
deletePendingRequestMessage(); deleteRequestMessageInQueue();
requestSlotMan->deleteAllRequestSlot(piece); deleteAllRequestSlot(piece);
} }
int SendMessageQueue::countPendingMessage() const { int SendMessageQueue::countMessageInQueue() const {
return pendingMessages.size(); return messageQueue.size();
} }
int SendMessageQueue::countRequestSlot() const { 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_ #define _D_SEND_MESSAGE_QUEUE_H_
#include "common.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 { class SendMessageQueue {
private: private:
int cuid; int cuid;
RequestSlotMan* requestSlotMan; RequestSlots requestSlots;
PendingMessages pendingMessages; MessageQueue messageQueue;
const Logger* logger;
// upload speed limit(byte/sec) // upload speed limit(byte/sec)
int uploadLimit; int uploadLimit;
public: TorrentMan* torrentMan;
SendMessageQueue(int cuid, PeerConnection* peerConnection, PeerConnection* peerConnection;
TorrentMan* torrentMan); Peer* peer;
~SendMessageQueue(); 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 send(int uploadSpeed);
void setPeerMessageCommonProperty(PeerMessage* peerMessage);
void addPendingMessage(const PendingMessage& pendingMessage); void deleteAllRequestSlot(Piece& piece);
void deletePendingPieceMessage(const PeerMessage* cancelMessage); void deleteRequestMessageInQueue();
void deletePendingRequestMessage();
void deleteRequestSlot(const RequestSlot& requestSlot);
void deleteTimeoutRequestSlot(Piece& piece);
void deleteCompletedRequestSlot(const Piece& piece);
RequestSlot getCorrespoindingRequestSlot(const PeerMessage* pieceMessage) const;
void cancelAllRequest(); void cancelAllRequest();
void cancelAllRequest(Piece& piece); void cancelAllRequest(Piece& piece);
int countPendingMessage() const;
int countRequestSlot() 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; } void setUploadLimit(int uploadLimit) { this->uploadLimit = uploadLimit; }
int getUploadLimit() const { return this->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_ #endif // _D_SEND_MESSAGE_QUEUE_H_

View File

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

View File

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

View File

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

View File

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

View File

@ -138,6 +138,11 @@ public:
return bitfield->getBitfield(); return bitfield->getBitfield();
} }
int getBitfieldLength() const { return bitfield->getBitfieldLength(); } 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) { void setInfoHash(const unsigned char* infoHash) {
memcpy(this->infoHash, infoHash, INFO_HASH_LENGTH); memcpy(this->infoHash, infoHash, INFO_HASH_LENGTH);
} }

View File

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

View File

@ -76,13 +76,13 @@ bool TrackerWatcherCommand::execute() {
} }
e->torrentMan->req->setUrl(url); e->torrentMan->req->setUrl(url);
Command* command = InitiateConnectionCommandFactory::createInitiateConnectionCommand(e->torrentMan->getNewCuid(), e->torrentMan->req, e); Command* command = InitiateConnectionCommandFactory::createInitiateConnectionCommand(e->torrentMan->getNewCuid(), e->torrentMan->req, e);
e->commands.push(command); e->commands.push_back(command);
e->torrentMan->trackers++; e->torrentMan->trackers++;
logger->info("CUID#%d - creating new tracker request command #%d", cuid, logger->info("CUID#%d - creating new tracker request command #%d", cuid,
command->getCuid()); command->getCuid());
} }
SleepCommand* slpCommand = new SleepCommand(cuid, e, this, SleepCommand* slpCommand = new SleepCommand(cuid, e, this,
e->torrentMan->minInterval); e->torrentMan->minInterval);
e->commands.push(slpCommand); e->commands.push_back(slpCommand);
return false; 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()); sort(range.begin(), range.end());
range.erase(unique(range.begin(), range.end()), 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 int expandBuffer(char** pbuf, int curLength, int newLength);
static void unfoldRange(const string& src, Integers& range); static void unfoldRange(const string& src, Integers& range);
// this function temporarily put here
static string getContentDispositionFilename(const string& header);
}; };
#endif // _D_UTIL_H_ #endif // _D_UTIL_H_

View File

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

View File

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

View File

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

View File

@ -13,6 +13,8 @@ class UtilTest:public CppUnit::TestFixture {
CPPUNIT_TEST(testEndsWith); CPPUNIT_TEST(testEndsWith);
CPPUNIT_TEST(testReplace); CPPUNIT_TEST(testReplace);
CPPUNIT_TEST(testStartsWith); CPPUNIT_TEST(testStartsWith);
// may be moved to other helper class in the future.
CPPUNIT_TEST(testGetContentDispositionFilename);
CPPUNIT_TEST_SUITE_END(); CPPUNIT_TEST_SUITE_END();
private: private:
@ -26,6 +28,8 @@ public:
void testEndsWith(); void testEndsWith();
void testReplace(); void testReplace();
void testStartsWith(); 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)); 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));
}