mirror of https://github.com/aria2/aria2
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
parent
500e978628
commit
ebfdbefb7f
322
ChangeLog
322
ChangeLog
|
@ -1,3 +1,325 @@
|
|||
2006-05-09 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
||||
|
||||
Each peer message has its own class.
|
||||
|
||||
* src/PendingMessages.h: Removed.
|
||||
* src/PendingMessages.cc: Removed. The sending process was moved to
|
||||
each message class.
|
||||
* src/RequestSlotMan.h: Removed.
|
||||
* src/RequestSlotMan.cc: Removed. All functionarities were moved to
|
||||
SendMessageQueue.
|
||||
* src/RequestMessage.h: New class.
|
||||
* src/RequestMessage.cc: New class.
|
||||
* src/CancelMessage.h: New class.
|
||||
* src/CancelMessage.cc: New class.
|
||||
* src/BitfieldMessage.h: New class.
|
||||
* src/BitfieldMessage.cc: New class.
|
||||
* src/ChokeMessage.h: New class.
|
||||
* src/ChokeMessage.cc: New class.
|
||||
* src/KeepAliveMessage.h: New class.
|
||||
* src/KeepAliveMessage.cc: New class.
|
||||
* src/PortMessage.h: New class.
|
||||
* src/UnchokeMessage.h: New class.
|
||||
* src/UnchokeMessage.cc: New class.
|
||||
* src/PieceMessage.h: New class.
|
||||
* src/PieceMessage.cc: New class.
|
||||
* src/HaveMessage.h: New class.
|
||||
* src/HaveMessage.cc: New class.
|
||||
* src/BitfieldMessage.h: New class.
|
||||
* src/BitfieldMessage.cc: New class.
|
||||
* src/NotInterestedMessage.h: New class.
|
||||
* src/NotInterestedMessage.cc: New class.
|
||||
* src/InterestedMessage.h: New class.
|
||||
* src/InterestedMessage.cc: New class.
|
||||
* src/HandshakeMessage.h (sendMessageQueue): New variable.
|
||||
(getSendMessageQueue): New function.
|
||||
(setSendMessageQueue): New function.
|
||||
* src/HandshakeMessage.cc: New class.
|
||||
* src/PeerConnection.h (receiveMessage): Changed return value and
|
||||
arguments.
|
||||
(receiveHandshake): Changed return value and arguments.
|
||||
* src/PeerConnection.cc (receiveMessage): Do not create message class
|
||||
here.
|
||||
(receiveHandshake): Do not create handshake class here.
|
||||
* src/PeerInteractionCommand.h (peerConnection): Removed.
|
||||
(piece): Removed.
|
||||
(syncPiece): Removed.
|
||||
(sendInterest): Removed.
|
||||
(sendMessages): Removed.
|
||||
(createRequestPendingMessage): Removed.
|
||||
(checkPieceHash): Removed.
|
||||
(erasePieceOnDisk): Removed.
|
||||
(getNewPieceAndSendInterest): Removed.
|
||||
(onGotNewPice): Removed.
|
||||
(onGotWrongPiece): Removed.
|
||||
* src/PeerInteractionCommand.cc (PeerInteractionCommand):
|
||||
Removed peerConnection, piece.
|
||||
(~PeerInteractionCommand): Removed peerConnection.
|
||||
(executeInternal): Use sendMessageQueue instead of peerConnection.
|
||||
(syncPiece): Moved to SendMessageQueue.
|
||||
(decideChoking): Removed PendingMessage.
|
||||
(receiveMessage): Use sendMessageQueue instead of peerConnection.
|
||||
The action after receiving peer message was moved to each message
|
||||
class.
|
||||
(onGotNewPice): Moved to SendMessageQueue.
|
||||
(onGotWrongPiece): Moved to SendMessageQueue.
|
||||
(getNewPieceAndSendInterest): Moved to SendMessageQueue.
|
||||
(sendInterest): Moved to SendMessageQueue.
|
||||
(createRequestPendingMessage): Removed.
|
||||
(sendMessages): Moved to SendMessageQueue.
|
||||
(onAbort): Use SendMessageQueue::abortPiece()
|
||||
(keepAlive): Use sendMessageQueue instead of peerConnection.
|
||||
(beforeSocketCheck): Use sendMessageQueue instead of peerConnection.
|
||||
(checkPieceHash): Moved to SendMessageQueue.
|
||||
(erasePieceOnDisk): Moved to SendMessageQueue.
|
||||
* src/PeerMessageUtil.h
|
||||
(createBitfieldMessage): Removed.
|
||||
(createHaveMessage): Changed return value and arguments.
|
||||
(createBitfieldMessage): Changed return value and arguments.
|
||||
(createRequestCancelMessage): Removed.
|
||||
(createPieceMessage): Changed return value and arguments.
|
||||
(getShortIntParam): New function.
|
||||
(checkIndex): Changed arguments.
|
||||
(checkBegin): Changed arguments.
|
||||
(checkLength): Changed arguments.
|
||||
(checkPieceOffset): Removed.
|
||||
(checkRange): New function.
|
||||
(checkBitfield): Changed arguments.
|
||||
(createPeerMessage): Removed.
|
||||
(checkIntegrity): Removed.
|
||||
(createHandshakeMessage): Changed arguments.
|
||||
(createChokeMessage): New function.
|
||||
(createUnchokeMessage): New function.
|
||||
(createInterestedMessage): New function.
|
||||
(createNotInterestedMessage): New function.
|
||||
(createRequestMessage): New function.
|
||||
(createCancelMessage): New function.
|
||||
(createPortMessage): New function.
|
||||
* src/PeerMessageUtil.cc
|
||||
(createBitfieldMessage): Removed.
|
||||
(createHaveMessage): Changed return value and arguments.
|
||||
(createBitfieldMessage): Changed return value and arguments.
|
||||
(createRequestCancelMessage): Removed.
|
||||
(createPieceMessage): Changed return value and arguments.
|
||||
(getShortIntParam): New function.
|
||||
(checkIndex): Changed arguments.
|
||||
(checkBegin): Changed arguments.
|
||||
(checkLength): Changed arguments.
|
||||
(checkPieceOffset): Removed.
|
||||
(checkRange): New function.
|
||||
(checkBitfield): Changed arguments.
|
||||
(createPeerMessage): Removed.
|
||||
(checkIntegrity): Removed.
|
||||
(createHandshakeMessage): Changed arguments.
|
||||
(createChokeMessage): New function.
|
||||
(createUnchokeMessage): New function.
|
||||
(createInterestedMessage): New function.
|
||||
(createNotInterestedMessage): New function.
|
||||
(createRequestMessage): New function.
|
||||
(createCancelMessage): New function.
|
||||
(createPortMessage): New function.
|
||||
* src/PeerMessage.h
|
||||
(id): Removed.
|
||||
(index): Removed.
|
||||
(begin): Removed.
|
||||
(length): Removed.
|
||||
(bitfield): Removed.
|
||||
(bitfieldLength): Removed.
|
||||
(block): Removed.
|
||||
(blockLength): Removed.
|
||||
(inProgress): New variable.
|
||||
(cuid): New variable.
|
||||
(peer): New variable.
|
||||
(sendMessageQueue): New variable.
|
||||
(logger): New variable.
|
||||
(setBitfield): Removed.
|
||||
(getBitfield): Removed.
|
||||
(setBlock): Removed.
|
||||
(getBlock): Removed.
|
||||
(getBitfieldLength): Removed.
|
||||
(getBlockLength): Removed.
|
||||
(isInProgress): New function.
|
||||
(toString): Made pure virtual.
|
||||
(check): New function.
|
||||
(send): New function.
|
||||
(receivedAction): New function.
|
||||
(getId): Made pure virtual.
|
||||
(setId): Removed.
|
||||
(getIndex): Removed.
|
||||
(setIndex): Removed.
|
||||
(getBegin): Removed.
|
||||
(setBegin): Removed.
|
||||
(getLength): Removed.
|
||||
(setLength): Removed.
|
||||
(getCuid): New function.
|
||||
(setCuid): New function.
|
||||
(getPeer): New function.
|
||||
(setPeer): New function.
|
||||
(getSendMessageQueue): New function.
|
||||
(setSendMessageQueue): New function.
|
||||
(ID): Removed.
|
||||
* src/PeerMessage.cc
|
||||
(setBitfield): Removed.
|
||||
(setBlock): Removed.
|
||||
(toString): Removed.
|
||||
* src/TorrentMan.h
|
||||
(getPieceLength): New function.
|
||||
(getPieceLength): New function.
|
||||
* src/SendMessageQueue.h
|
||||
(REQUEST_TIME_OUT): New definition.
|
||||
(RequestSlots): New definition.
|
||||
(MessageQueue): New definition.
|
||||
(requestSlotMan): Removed.
|
||||
(pendingMessages): Removed.
|
||||
(requestSlots): New variable.
|
||||
(messageQueue): New variable.
|
||||
(torrentMan): New variable.
|
||||
(peerConnection): New variable.
|
||||
(peer): New variable.
|
||||
(piece): New variable.
|
||||
(getNewPieceAndSendInterest): New function.
|
||||
(createPeerMessage): New function.
|
||||
(createHandshakeMessage): New function.
|
||||
(send): Made private.
|
||||
(setPeerMessageCommonProperty): New function.
|
||||
(deleteAllRequestSlot): New function.
|
||||
(deleteRequestMessageInQueue): New function.
|
||||
(cancelAllRequest): Made private.
|
||||
(cancelAllRequest): Made private.
|
||||
(countRequestSlot): Made private.
|
||||
(addPendingMessage): Removed.
|
||||
(deletePendingPieceMessage): Removed.
|
||||
(deletePendingRequestMessage): Removed.
|
||||
(addMessage): New function.
|
||||
(deletePieceMessageInQueue): New function.
|
||||
(deleteTimeoutRequestSlot): Changed argument.
|
||||
(deleteCompletedRequestSlot): Changed argument.
|
||||
(getCorrespoindingRequestSlot): Renamed to getCorrespondingRequestSlot.
|
||||
(getCorrespondingRequestSlot): New function.
|
||||
(countPendingMessage): Removed.
|
||||
(countMessageInQueue): New function.
|
||||
(getTorrentMan): New function.
|
||||
(getPeerConnection): New function.
|
||||
(hasDownloadPiece): New function.
|
||||
(getDownloadPiece): New function.
|
||||
(setDownloadPiece): New function.
|
||||
(syncPiece): New function.
|
||||
(sendMessages): New function.
|
||||
(sendNow): New function.
|
||||
(trySendNow): New function.
|
||||
(abortPiece): New function.
|
||||
(sendHandshake): New function.
|
||||
(receiveMessage): New function.
|
||||
(receiveHandshake): New function.
|
||||
(createRequestMessage): New function.
|
||||
(createCancelMessage): New function.
|
||||
(createPieceMessage): New function.
|
||||
(createHaveMessage): New function.
|
||||
(createChokeMessage): New function.
|
||||
(createUnchokeMessage): New function.
|
||||
(createInterestedMessage): New function.
|
||||
(createNotInterestedMessage): New function.
|
||||
(createBitfieldMessage): New function.
|
||||
(createKeepAliveMessage): New function.
|
||||
* src/SendMessageQueue.cc
|
||||
(SendMessageQueue): Removed requestSlotMan.
|
||||
Instantiated peerConnection here.
|
||||
(~SendMessageQueue): Removed requestSlotMan.
|
||||
Added deletion of peerConnection and the contents of messageQueue.
|
||||
(send): Updated according to the change of messageQueue.
|
||||
(addPendingMessage): Renamed to addMessage.
|
||||
(addMessage): New function.
|
||||
(deletePendingPieceMessage): Renamed to deletePieceMessageInQueue.
|
||||
(deletePieceMessageInQueue): New function.
|
||||
(deletePendingRequestMessage): Renamed to deleteRequestMessageInQueue.
|
||||
(deleteRequestMessageInQueue): New function.
|
||||
(deleteRequestSlot): RequestSlotMan::deleteRequestSlot(...) was moved
|
||||
here.
|
||||
(deleteTimeoutRequestSlot): RequestSlotMan::deleteTimeoutRequestSlot
|
||||
(...) was moved here.
|
||||
(deleteAllRequestSlot): RequestSlotMan::deleteAllRequestSlot(...) was
|
||||
moved here.
|
||||
(deleteCompletedRequestSlot):
|
||||
RequestSlotMan::deleteCompletedRequestSlot(...) was moved here.
|
||||
(getCorrespondingRequestSlot):
|
||||
RequestSlotMan::getCorrespoindingRequestSlot(...) was moved here.
|
||||
And renamed to getCorrespondingRequestSlot, correcting a typo.
|
||||
(countPendingMessage): Renamed to countMessageInQueue.
|
||||
(countMessageInQueue): New function.
|
||||
(countRequestSlot): RequestSlotMan::countRequestSlot() was moved here.
|
||||
(receiveHandshake): New function.
|
||||
(createHandshakeMessage): New function.
|
||||
(receiveMessage): New function.
|
||||
(createPeerMessage): New function.
|
||||
(syncPiece): New function.
|
||||
(getNewPieceAndSendInterest): New function.
|
||||
(sendMessages): New function.
|
||||
(sendNow): New function.
|
||||
(trySendNow): New function.
|
||||
(sendHandshake): New function.
|
||||
(abortPiece): New function.
|
||||
(getDownloadPiece): New function.
|
||||
(getPeerMessageCommonProperty): New function.
|
||||
(createRequestMessage): New function.
|
||||
(createCancelMessage): New function.
|
||||
(createPieceMessage): New function.
|
||||
(createHaveMessage): New function.
|
||||
(createChokeMessage): New function.
|
||||
(createUnchokeMessage): New function.
|
||||
(createInterestedMessage): New function.
|
||||
(createNotInterestedMessage): New function.
|
||||
(createBitfieldMessage): New function.
|
||||
(createKeepAliveMessage): New function.
|
||||
|
||||
|
||||
To add simple Content-Disposition support:
|
||||
|
||||
* src/HttpResponseCommand.h (determinFilename): New function.
|
||||
* src/HttpResponseCommand.cc (executeInternal):
|
||||
Use determinFilename(headers) instead of req->getFile() when comparing
|
||||
filename.
|
||||
(determinFilename): New function.
|
||||
(handleDefaultEncoding): Use determinFilename(headers) instead of
|
||||
req->getFile().
|
||||
(handleOtherEncoding): Use determinFilename(headers) instead of
|
||||
req->getFile().
|
||||
* src/Util.h (getContentDispositionFilename): New function.
|
||||
* src/Util.cc (getContentDispositionFilename): New function.
|
||||
|
||||
* src/LogFactory.h (release): New function.
|
||||
* src/LogFactory.cc (release): New function.
|
||||
|
||||
To fix a bug that causes out-of-bound exception when HTTP status
|
||||
line is wrong:
|
||||
|
||||
* src/HttpConnection.cc (receiveResponse): Added a check for header
|
||||
size.
|
||||
|
||||
* src/common.h (Deleter): New class.
|
||||
|
||||
* src/SegmentMan.cc
|
||||
(~SegmentMan): Added deletion of splitter and diskWriter.
|
||||
* src/DownloadEngine.h
|
||||
(Commands): Use deque.
|
||||
(clearQueue): New function.
|
||||
* src/DownloadEngine.cc
|
||||
(~DownloadEngine): Added deletion of segmentMan.
|
||||
(cleanQueue): New function.
|
||||
* src/TorrentDownloadEngine.h
|
||||
(TorrentDownloadEngine): The implementation was moved to
|
||||
TorrentDownloadEngine.cc.
|
||||
(~TorrentDownloadEngine): The implementation was moved to
|
||||
TorrentDownloadEngine.cc.
|
||||
* src/TorrentDownloadEngine.cc
|
||||
(~TorrentDownloadEngine): Added deletion of torrentMan.
|
||||
* src/main.cc
|
||||
(clearRequest): Removed.
|
||||
(handler): Added deletion of e.
|
||||
(torrentHandler): Added deletion of te.
|
||||
(main): Do not share splitter.
|
||||
Use Deleter instead of clearRequest.
|
||||
Deletion of classes were updated.
|
||||
|
||||
2006-05-06 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
||||
|
||||
* src/main.cc (main): Fixed typo.
|
||||
|
|
2
TODO
2
TODO
|
@ -14,4 +14,4 @@
|
|||
* Add Mainline-compatible DHT support
|
||||
* Add Message stream encryption support
|
||||
* Add announce-list support
|
||||
* Add content-disposition support(NO MIME Encoding)
|
||||
* Add fast extension
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.59 for aria2c 0.4.1.
|
||||
# Generated by GNU Autoconf 2.59 for aria2c 0.4.2.
|
||||
#
|
||||
# Report bugs to <tujikawa@rednoah.com>.
|
||||
#
|
||||
|
@ -269,8 +269,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
|
|||
# Identity of this package.
|
||||
PACKAGE_NAME='aria2c'
|
||||
PACKAGE_TARNAME='aria2c'
|
||||
PACKAGE_VERSION='0.4.1'
|
||||
PACKAGE_STRING='aria2c 0.4.1'
|
||||
PACKAGE_VERSION='0.4.2'
|
||||
PACKAGE_STRING='aria2c 0.4.2'
|
||||
PACKAGE_BUGREPORT='tujikawa@rednoah.com'
|
||||
|
||||
ac_unique_file="src/Socket.h"
|
||||
|
@ -788,7 +788,7 @@ if test "$ac_init_help" = "long"; then
|
|||
# Omit some internal or obsolete options to make the list less imposing.
|
||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||
cat <<_ACEOF
|
||||
\`configure' configures aria2c 0.4.1 to adapt to many kinds of systems.
|
||||
\`configure' configures aria2c 0.4.2 to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
|
@ -854,7 +854,7 @@ fi
|
|||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of aria2c 0.4.1:";;
|
||||
short | recursive ) echo "Configuration of aria2c 0.4.2:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
|
@ -994,7 +994,7 @@ fi
|
|||
test -n "$ac_init_help" && exit 0
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
aria2c configure 0.4.1
|
||||
aria2c configure 0.4.2
|
||||
generated by GNU Autoconf 2.59
|
||||
|
||||
Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
|
@ -1008,7 +1008,7 @@ cat >&5 <<_ACEOF
|
|||
This file contains any messages produced by compilers while
|
||||
running configure, to aid debugging if configure makes a mistake.
|
||||
|
||||
It was created by aria2c $as_me 0.4.1, which was
|
||||
It was created by aria2c $as_me 0.4.2, which was
|
||||
generated by GNU Autoconf 2.59. Invocation command line was
|
||||
|
||||
$ $0 $@
|
||||
|
@ -1651,7 +1651,7 @@ fi
|
|||
|
||||
# Define the identity of the package.
|
||||
PACKAGE='aria2c'
|
||||
VERSION='0.4.1'
|
||||
VERSION='0.4.2'
|
||||
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
|
@ -11529,7 +11529,7 @@ _ASBOX
|
|||
} >&5
|
||||
cat >&5 <<_CSEOF
|
||||
|
||||
This file was extended by aria2c $as_me 0.4.1, which was
|
||||
This file was extended by aria2c $as_me 0.4.2, which was
|
||||
generated by GNU Autoconf 2.59. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
|
@ -11592,7 +11592,7 @@ _ACEOF
|
|||
|
||||
cat >>$CONFIG_STATUS <<_ACEOF
|
||||
ac_cs_version="\\
|
||||
aria2c config.status 0.4.1
|
||||
aria2c config.status 0.4.2
|
||||
configured by $0, generated by GNU Autoconf 2.59,
|
||||
with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# Process this file with autoconf to produce a configure script.
|
||||
#
|
||||
AC_PREREQ(2.59)
|
||||
AC_INIT(aria2c, 0.4.1, tujikawa@rednoah.com)
|
||||
AC_INIT(aria2c, 0.4.2, tujikawa@rednoah.com)
|
||||
AM_INIT_AUTOMAKE()
|
||||
AM_PATH_CPPUNIT(1.10.2)
|
||||
AC_CONFIG_SRCDIR([src/Socket.h])
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
# General Public License and is *not* in the public domain.
|
||||
|
||||
PACKAGE = aria2c
|
||||
VERSION = 0.4.1
|
||||
VERSION = 0.4.2
|
||||
|
||||
SHELL = /bin/sh
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: http://aria2.sourceforge.net/\n"
|
||||
"POT-Creation-Date: 2006-05-05 19:42+0900\n"
|
||||
"POT-Creation-Date: 2006-05-10 00:53+0900\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
|
@ -342,13 +342,13 @@ msgid ""
|
|||
"The download was not complete because of errors. Check the log.\n"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cc:92 src/main.cc:101
|
||||
#: src/main.cc:88 src/main.cc:99
|
||||
msgid ""
|
||||
"\n"
|
||||
"stopping application...\n"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cc:96 src/main.cc:111
|
||||
#: src/main.cc:94 src/main.cc:111
|
||||
msgid "done\n"
|
||||
msgstr ""
|
||||
|
||||
|
@ -704,10 +704,10 @@ msgstr ""
|
|||
msgid "daemon failed"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cc:671
|
||||
#: src/main.cc:670
|
||||
msgid "Files:"
|
||||
msgstr ""
|
||||
|
||||
#: src/main.cc:702
|
||||
#: src/main.cc:701
|
||||
msgid "Errors occurred while binding port.\n"
|
||||
msgstr ""
|
||||
|
|
10
po/de.po
10
po/de.po
|
@ -7,7 +7,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: de\n"
|
||||
"Report-Msgid-Bugs-To: http://aria2.sourceforge.net/\n"
|
||||
"POT-Creation-Date: 2006-05-05 19:42+0900\n"
|
||||
"POT-Creation-Date: 2006-05-10 00:53+0900\n"
|
||||
"PO-Revision-Date: 2006-05-05 19:44+0900\n"
|
||||
"Last-Translator: Hermann J. Beckers <hj.beckers@onlinehome.de>\n"
|
||||
"Language-Team: deutsch <de@li.org>\n"
|
||||
|
@ -355,7 +355,7 @@ msgstr ""
|
|||
"\n"
|
||||
"Abruf wegen Fehlern nicht vollständig. Überprüfen Sie die Log-Datei.\n"
|
||||
|
||||
#: src/main.cc:92 src/main.cc:101
|
||||
#: src/main.cc:88 src/main.cc:99
|
||||
msgid ""
|
||||
"\n"
|
||||
"stopping application...\n"
|
||||
|
@ -363,7 +363,7 @@ msgstr ""
|
|||
"\n"
|
||||
"Anwendung wird gestoppt ...\n"
|
||||
|
||||
#: src/main.cc:96 src/main.cc:111
|
||||
#: src/main.cc:94 src/main.cc:111
|
||||
msgid "done\n"
|
||||
msgstr "erledigt\n"
|
||||
|
||||
|
@ -820,10 +820,10 @@ msgstr "Geben Sie zumindest eine URL an"
|
|||
msgid "daemon failed"
|
||||
msgstr "Daemon-Start nicht erfolgreich"
|
||||
|
||||
#: src/main.cc:671
|
||||
#: src/main.cc:670
|
||||
msgid "Files:"
|
||||
msgstr "Dateien:"
|
||||
|
||||
#: src/main.cc:702
|
||||
#: src/main.cc:701
|
||||
msgid "Errors occurred while binding port.\n"
|
||||
msgstr "Fehler beim Binden an Port aufgetreten.\n"
|
||||
|
|
10
po/ja.po
10
po/ja.po
|
@ -7,7 +7,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: aria2c 0.2.1\n"
|
||||
"Report-Msgid-Bugs-To: http://aria2.sourceforge.net/\n"
|
||||
"POT-Creation-Date: 2006-05-05 19:42+0900\n"
|
||||
"POT-Creation-Date: 2006-05-10 00:53+0900\n"
|
||||
"PO-Revision-Date: 2006-05-05 19:45+0900\n"
|
||||
"Last-Translator: Tatsuhiro Tsujikawa <tujikawa@rednoah.com>\n"
|
||||
"Language-Team: Japanese <ja@li.org>\n"
|
||||
|
@ -358,7 +358,7 @@ msgstr ""
|
|||
"\n"
|
||||
"ダウンロードはエラーのため完了していません. ログを確認してください.\n"
|
||||
|
||||
#: src/main.cc:92 src/main.cc:101
|
||||
#: src/main.cc:88 src/main.cc:99
|
||||
msgid ""
|
||||
"\n"
|
||||
"stopping application...\n"
|
||||
|
@ -366,7 +366,7 @@ msgstr ""
|
|||
"\n"
|
||||
"アプリケーションを終了しています...\n"
|
||||
|
||||
#: src/main.cc:96 src/main.cc:111
|
||||
#: src/main.cc:94 src/main.cc:111
|
||||
msgid "done\n"
|
||||
msgstr "完了\n"
|
||||
|
||||
|
@ -847,10 +847,10 @@ msgstr "
|
|||
msgid "daemon failed"
|
||||
msgstr "デーモン起動に失敗"
|
||||
|
||||
#: src/main.cc:671
|
||||
#: src/main.cc:670
|
||||
msgid "Files:"
|
||||
msgstr "ファイル:"
|
||||
|
||||
#: src/main.cc:702
|
||||
#: src/main.cc:701
|
||||
msgid "Errors occurred while binding port.\n"
|
||||
msgstr "ポートをバインド中にエラーが発生しました.\n"
|
||||
|
|
|
@ -77,7 +77,7 @@ bool AbstractCommand::execute() {
|
|||
if(isTimeoutDetected()) {
|
||||
throw new DlRetryEx(EX_TIME_OUT);
|
||||
}
|
||||
e->commands.push(this);
|
||||
e->commands.push_back(this);
|
||||
return false;
|
||||
}
|
||||
updateCheckPoint();
|
||||
|
@ -118,10 +118,10 @@ bool AbstractCommand::execute() {
|
|||
bool AbstractCommand::prepareForRetry(int wait) {
|
||||
Command* command = InitiateConnectionCommandFactory::createInitiateConnectionCommand(cuid, req, e);
|
||||
if(wait == 0) {
|
||||
e->commands.push(command);
|
||||
e->commands.push_back(command);
|
||||
} else {
|
||||
SleepCommand* scom = new SleepCommand(cuid, e, command, wait);
|
||||
e->commands.push(scom);
|
||||
e->commands.push_back(scom);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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_
|
|
@ -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);
|
||||
}
|
|
@ -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_
|
|
@ -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";
|
||||
}
|
|
@ -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_
|
|
@ -82,7 +82,7 @@ bool DownloadCommand::executeInternal(Segment seg) {
|
|||
return prepareForNextSegment();
|
||||
} else {
|
||||
e->segmentMan->updateSegment(seg);
|
||||
e->commands.push(this);
|
||||
e->commands.push_back(this);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -37,6 +37,14 @@ DownloadEngine::DownloadEngine():noWait(false), segmentMan(NULL) {
|
|||
DownloadEngine::~DownloadEngine() {
|
||||
assert(rsockets.empty());
|
||||
assert(wsockets.empty());
|
||||
if(segmentMan != NULL) {
|
||||
delete segmentMan;
|
||||
}
|
||||
}
|
||||
|
||||
void DownloadEngine::cleanQueue() {
|
||||
for_each(commands.begin(), commands.end(), Deleter());
|
||||
commands.clear();
|
||||
}
|
||||
|
||||
void DownloadEngine::run() {
|
||||
|
@ -45,7 +53,7 @@ void DownloadEngine::run() {
|
|||
int max = commands.size();
|
||||
for(int i = 0; i < max; i++) {
|
||||
Command* com = commands.front();
|
||||
commands.pop();
|
||||
commands.pop_front();
|
||||
if(com->execute()) {
|
||||
delete(com);
|
||||
}
|
||||
|
|
|
@ -22,8 +22,6 @@
|
|||
#ifndef _D_DOWNLOAD_ENGINE_H_
|
||||
#define _D_DOWNLOAD_ENGINE_H_
|
||||
|
||||
#include <queue>
|
||||
#include <deque>
|
||||
#include "Command.h"
|
||||
#include "Socket.h"
|
||||
#include "SegmentMan.h"
|
||||
|
@ -31,11 +29,10 @@
|
|||
#include "Logger.h"
|
||||
#include "Option.h"
|
||||
#include <sys/time.h>
|
||||
|
||||
using namespace std;
|
||||
#include <deque>
|
||||
|
||||
typedef deque<Socket*> Sockets;
|
||||
typedef queue<Command*> Commands;
|
||||
typedef deque<Command*> Commands;
|
||||
|
||||
class DownloadEngine {
|
||||
private:
|
||||
|
@ -63,6 +60,8 @@ public:
|
|||
|
||||
void run();
|
||||
|
||||
void cleanQueue();
|
||||
|
||||
bool addSocketForReadCheck(Socket* socket);
|
||||
bool deleteSocketForReadCheck(Socket* socket);
|
||||
bool addSocketForWriteCheck(Socket* socket);
|
||||
|
|
|
@ -67,7 +67,7 @@ bool FtpInitiateConnectionCommand::executeInternal(Segment segment) {
|
|||
socket->establishConnection(req->getHost(), req->getPort());
|
||||
command = new FtpNegotiationCommand(cuid, req, e, socket);
|
||||
}
|
||||
e->commands.push(command);
|
||||
e->commands.push_back(command);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -51,10 +51,10 @@ bool FtpNegotiationCommand::executeInternal(Segment segment) {
|
|||
return prepareForRetry(0);
|
||||
} else if(sequence == SEQ_NEGOTIATION_COMPLETED) {
|
||||
FtpDownloadCommand* command = new FtpDownloadCommand(cuid, req, e, dataSocket, socket);
|
||||
e->commands.push(command);
|
||||
e->commands.push_back(command);
|
||||
return true;
|
||||
} else {
|
||||
e->commands.push(this);
|
||||
e->commands.push_back(this);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,6 +36,6 @@ bool FtpTunnelRequestCommand::executeInternal(Segment segment) {
|
|||
httpConnection.sendProxyRequest();
|
||||
|
||||
FtpTunnelResponseCommand* command = new FtpTunnelResponseCommand(cuid, req, e, socket);
|
||||
e->commands.push(command);
|
||||
e->commands.push_back(command);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -37,13 +37,13 @@ bool FtpTunnelResponseCommand::executeInternal(Segment segment) {
|
|||
int status = http->receiveResponse(headers);
|
||||
if(status == 0) {
|
||||
// we didn't receive all of headers yet.
|
||||
e->commands.push(this);
|
||||
e->commands.push_back(this);
|
||||
return false;
|
||||
}
|
||||
if(status != 200) {
|
||||
throw new DlRetryEx(EX_PROXY_CONNECTION_FAILED);
|
||||
}
|
||||
FtpNegotiationCommand* command = new FtpNegotiationCommand(cuid, req, e, socket);
|
||||
e->commands.push(command);
|
||||
e->commands.push_back(command);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
|
@ -23,7 +23,8 @@
|
|||
#define _D_HANDSHAKE_MESSAGE_H_
|
||||
|
||||
#include "common.h"
|
||||
#include "Util.h"
|
||||
|
||||
class SendMessageQueue;
|
||||
|
||||
#define PSTR "BitTorrent protocol"
|
||||
#define HANDSHAKE_MESSAGE_LENGTH 68
|
||||
|
@ -34,14 +35,16 @@ public:
|
|||
string pstr;
|
||||
unsigned char infoHash[20];
|
||||
char peerId[20];
|
||||
SendMessageQueue* sendMessageQueue;
|
||||
public:
|
||||
HandshakeMessage() {}
|
||||
~HandshakeMessage() {}
|
||||
|
||||
string toString() const {
|
||||
return "handshake peerId="+
|
||||
Util::urlencode((unsigned char*)peerId, sizeof(peerId));
|
||||
}
|
||||
SendMessageQueue* getSendMessageQueue() const { return sendMessageQueue; }
|
||||
void setSendMessageQueue(SendMessageQueue* sendMessageQueue);
|
||||
|
||||
string toString() const;
|
||||
void check();
|
||||
};
|
||||
|
||||
#endif // _D_HANDSHAKE_MESSAGE_H_
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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_
|
|
@ -120,7 +120,7 @@ int HttpConnection::findEndOfHeader(const char* buf, const char* substr, int buf
|
|||
int HttpConnection::receiveResponse(HttpHeader& headers) {
|
||||
//char buf[512];
|
||||
string header;
|
||||
int delimiterSwith = 0;
|
||||
int delimiterSwitch = 0;
|
||||
char* delimiters[] = { "\r\n", "\n" };
|
||||
|
||||
int size = HEADERBUF_SIZE-headerBufLength;
|
||||
|
@ -137,19 +137,20 @@ int HttpConnection::receiveResponse(HttpHeader& headers) {
|
|||
//header += buf;
|
||||
//string::size_type p;
|
||||
int eohIndex;
|
||||
|
||||
if((eohIndex = findEndOfHeader(headerBuf, "\r\n\r\n", hlenTemp)) == -1 &&
|
||||
(eohIndex = findEndOfHeader(headerBuf, "\n\n", hlenTemp)) == -1) {
|
||||
socket->readData(headerBuf+headerBufLength, size);
|
||||
} else {
|
||||
if(eohIndex[headerBuf] == '\n') {
|
||||
// for crapping non-standard HTTP server
|
||||
delimiterSwith = 1;
|
||||
delimiterSwitch = 1;
|
||||
} else {
|
||||
delimiterSwith = 0;
|
||||
delimiterSwitch = 0;
|
||||
}
|
||||
headerBuf[eohIndex+strlen(delimiters[delimiterSwith])*2] = '\0';
|
||||
headerBuf[eohIndex+strlen(delimiters[delimiterSwitch])*2] = '\0';
|
||||
header = headerBuf;
|
||||
size = eohIndex+strlen(delimiters[delimiterSwith])*2-headerBufLength;
|
||||
size = eohIndex+strlen(delimiters[delimiterSwitch])*2-headerBufLength;
|
||||
socket->readData(headerBuf+headerBufLength, size);
|
||||
}
|
||||
if(!Util::endsWith(header, "\r\n\r\n") && !Util::endsWith(header, "\n\n")) {
|
||||
|
@ -159,15 +160,18 @@ int HttpConnection::receiveResponse(HttpHeader& headers) {
|
|||
logger->info(MSG_RECEIVE_RESPONSE, cuid, header.c_str());
|
||||
string::size_type p, np;
|
||||
p = np = 0;
|
||||
np = header.find(delimiters[delimiterSwith], p);
|
||||
np = header.find(delimiters[delimiterSwitch], p);
|
||||
if(np == string::npos) {
|
||||
throw new DlRetryEx(EX_NO_STATUS_HEADER);
|
||||
}
|
||||
// check HTTP status value
|
||||
if(header.size() <= 12) {
|
||||
throw new DlRetryEx(EX_NO_STATUS_HEADER);
|
||||
}
|
||||
string status = header.substr(9, 3);
|
||||
p = np+2;
|
||||
// retreive status name-value pairs, then push these into map
|
||||
while((np = header.find(delimiters[delimiterSwith], p)) != string::npos && np != p) {
|
||||
while((np = header.find(delimiters[delimiterSwitch], p)) != string::npos && np != p) {
|
||||
string line = header.substr(p, np-p);
|
||||
p = np+2;
|
||||
pair<string, string> hp;
|
||||
|
|
|
@ -55,7 +55,7 @@ bool HttpInitiateConnectionCommand::executeInternal(Segment segment) {
|
|||
socket->establishConnection(req->getHost(), req->getPort());
|
||||
command = new HttpRequestCommand(cuid, req, e, socket);
|
||||
}
|
||||
e->commands.push(command);
|
||||
e->commands.push_back(command);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,6 +36,6 @@ bool HttpProxyRequestCommand::executeInternal(Segment segment) {
|
|||
httpConnection.sendProxyRequest();
|
||||
|
||||
HttpProxyResponseCommand* command = new HttpProxyResponseCommand(cuid, req, e, socket);
|
||||
e->commands.push(command);
|
||||
e->commands.push_back(command);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -37,14 +37,14 @@ bool HttpProxyResponseCommand::executeInternal(Segment segment) {
|
|||
int status = http->receiveResponse(headers);
|
||||
if(status == 0) {
|
||||
// we didn't receive all of headers yet.
|
||||
e->commands.push(this);
|
||||
e->commands.push_back(this);
|
||||
return false;
|
||||
}
|
||||
if(status != 200) {
|
||||
throw new DlRetryEx(EX_PROXY_CONNECTION_FAILED);
|
||||
}
|
||||
HttpRequestCommand* command = new HttpRequestCommand(cuid, req, e, socket);
|
||||
e->commands.push(command);
|
||||
e->commands.push_back(command);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ bool HttpRequestCommand::executeInternal(Segment seg) {
|
|||
http.sendRequest(seg);
|
||||
|
||||
Command* command = getNextCommand();
|
||||
e->commands.push(command);
|
||||
e->commands.push_back(command);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ bool HttpResponseCommand::executeInternal(Segment seg) {
|
|||
int status = http->receiveResponse(headers);
|
||||
if(status == 0) {
|
||||
// didn't receive header fully
|
||||
e->commands.push(this);
|
||||
e->commands.push_back(this);
|
||||
return false;
|
||||
}
|
||||
// check HTTP status number
|
||||
|
@ -65,7 +65,7 @@ bool HttpResponseCommand::executeInternal(Segment seg) {
|
|||
return handleDefaultEncoding(headers);
|
||||
}
|
||||
} else {
|
||||
if(req->getFile() != e->segmentMan->filename) {
|
||||
if(determinFilename(headers) != e->segmentMan->filename) {
|
||||
throw new DlAbortEx(EX_FILENAME_MISMATCH, req->getFile().c_str(), e->segmentMan->filename.c_str());
|
||||
}
|
||||
createHttpDownloadCommand();
|
||||
|
@ -91,6 +91,18 @@ bool HttpResponseCommand::handleRedirect(const string& url, const HttpHeader& he
|
|||
return prepareForRetry(0);
|
||||
}
|
||||
|
||||
string HttpResponseCommand::determinFilename(const HttpHeader& headers) {
|
||||
string contentDisposition =
|
||||
Util::getContentDispositionFilename(headers.getFirst("Content-Disposition"));
|
||||
if(contentDisposition.empty()) {
|
||||
return req->getFile();
|
||||
} else {
|
||||
logger->info("CUID#%d - Content-Disposition Detected. Use %s as filename",
|
||||
cuid, contentDisposition.c_str());
|
||||
return contentDisposition;
|
||||
}
|
||||
}
|
||||
|
||||
bool HttpResponseCommand::handleDefaultEncoding(const HttpHeader& headers) {
|
||||
// TODO quick and dirty way
|
||||
if(req->isTorrent) {
|
||||
|
@ -108,7 +120,7 @@ bool HttpResponseCommand::handleDefaultEncoding(const HttpHeader& headers) {
|
|||
throw new DlAbortEx(EX_TOO_LARGE_FILE, size);
|
||||
}
|
||||
e->segmentMan->isSplittable = !(size == 0);
|
||||
e->segmentMan->filename = req->getFile();
|
||||
e->segmentMan->filename = determinFilename(headers);
|
||||
bool segFileExists = e->segmentMan->segmentFileExists();
|
||||
e->segmentMan->downloadStarted = true;
|
||||
if(segFileExists) {
|
||||
|
@ -130,7 +142,7 @@ bool HttpResponseCommand::handleOtherEncoding(const string& transferEncoding, co
|
|||
// we ignore content-length when transfer-encoding is set
|
||||
e->segmentMan->downloadStarted = true;
|
||||
e->segmentMan->isSplittable = false;
|
||||
e->segmentMan->filename = req->getFile();
|
||||
e->segmentMan->filename = determinFilename(headers);
|
||||
e->segmentMan->totalSize = 0;
|
||||
Segment seg;
|
||||
e->segmentMan->getSegment(seg, cuid);
|
||||
|
@ -151,7 +163,7 @@ void HttpResponseCommand::createHttpDownloadCommand(const string& transferEncodi
|
|||
command->transferEncoding = transferEncoding;
|
||||
enc->init();
|
||||
}
|
||||
e->commands.push(command);
|
||||
e->commands.push_back(command);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ private:
|
|||
bool handleOtherEncoding(const string& transferEncoding, const HttpHeader& headers);
|
||||
void createHttpDownloadCommand(const string& transferEncoding = "");
|
||||
void retrieveCookie(const HttpHeader& headers);
|
||||
string determinFilename(const HttpHeader& headers);
|
||||
HttpConnection* http;
|
||||
protected:
|
||||
bool executeInternal(Segment segment);
|
||||
|
|
|
@ -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";
|
||||
}
|
|
@ -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_
|
|
@ -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();
|
||||
}
|
|
@ -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_
|
|
@ -37,3 +37,8 @@ Logger* LogFactory::getInstance() {
|
|||
}
|
||||
return logger;
|
||||
}
|
||||
|
||||
void LogFactory::release() {
|
||||
delete logger;
|
||||
logger = NULL;
|
||||
}
|
||||
|
|
|
@ -42,6 +42,11 @@ public:
|
|||
static void setLogFile(const string& name) {
|
||||
filename = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Releases used resources
|
||||
*/
|
||||
static void release();
|
||||
};
|
||||
|
||||
#endif // _D_LOG_FACTORY_H_
|
||||
|
|
|
@ -65,12 +65,10 @@ SRCS = Socket.cc Socket.h\
|
|||
TorrentDownloadEngine.cc TorrentDownloadEngine.h\
|
||||
TorrentConsoleDownloadEngine.cc TorrentConsoleDownloadEngine.h\
|
||||
PeerListenCommand.cc PeerListenCommand.h\
|
||||
PendingMessage.cc PendingMessage.h\
|
||||
PeerMessage.cc PeerMessage.h\
|
||||
HandshakeMessage.h\
|
||||
HandshakeMessage.cc HandshakeMessage.h\
|
||||
Piece.cc Piece.h\
|
||||
RequestSlot.cc RequestSlot.h\
|
||||
RequestSlotMan.cc RequestSlotMan.h\
|
||||
TorrentAutoSaveCommand.cc TorrentAutoSaveCommand.h\
|
||||
Directory.cc Directory.h\
|
||||
TrackerWatcherCommand.cc TrackerWatcherCommand.h\
|
||||
|
@ -85,7 +83,18 @@ SRCS = Socket.cc Socket.h\
|
|||
LogFactory.cc LogFactory.h\
|
||||
TrackerUpdateCommand.cc TrackerUpdateCommand.h\
|
||||
ByteArrayDiskWriter.cc ByteArrayDiskWriter.h\
|
||||
PeerChokeCommand.cc PeerChokeCommand.h
|
||||
PeerChokeCommand.cc PeerChokeCommand.h\
|
||||
ChokeMessage.cc ChokeMessage.h\
|
||||
UnchokeMessage.cc UnchokeMessage.h\
|
||||
InterestedMessage.cc InterestedMessage.h\
|
||||
NotInterestedMessage.cc NotInterestedMessage.h\
|
||||
HaveMessage.cc HaveMessage.h\
|
||||
BitfieldMessage.cc BitfieldMessage.h\
|
||||
RequestMessage.cc RequestMessage.h\
|
||||
PieceMessage.cc PieceMessage.h\
|
||||
CancelMessage.cc CancelMessage.h\
|
||||
KeepAliveMessage.cc KeepAliveMessage.h\
|
||||
PortMessage.h
|
||||
noinst_LIBRARIES = libaria2c.a
|
||||
libaria2c_a_SOURCES = $(SRCS)
|
||||
aria2c_LDADD = libaria2c.a @LIBINTL@ @ALLOCA@ @LIBGNUTLS_LIBS@\
|
||||
|
|
|
@ -92,15 +92,20 @@ am__objects_1 = Socket.$(OBJEXT) SocketCore.$(OBJEXT) \
|
|||
PeerInteractionCommand.$(OBJEXT) Peer.$(OBJEXT) \
|
||||
BitfieldMan.$(OBJEXT) TorrentDownloadEngine.$(OBJEXT) \
|
||||
TorrentConsoleDownloadEngine.$(OBJEXT) \
|
||||
PeerListenCommand.$(OBJEXT) PendingMessage.$(OBJEXT) \
|
||||
PeerMessage.$(OBJEXT) Piece.$(OBJEXT) RequestSlot.$(OBJEXT) \
|
||||
RequestSlotMan.$(OBJEXT) TorrentAutoSaveCommand.$(OBJEXT) \
|
||||
PeerListenCommand.$(OBJEXT) PeerMessage.$(OBJEXT) \
|
||||
HandshakeMessage.$(OBJEXT) Piece.$(OBJEXT) \
|
||||
RequestSlot.$(OBJEXT) TorrentAutoSaveCommand.$(OBJEXT) \
|
||||
Directory.$(OBJEXT) TrackerWatcherCommand.$(OBJEXT) \
|
||||
SendMessageQueue.$(OBJEXT) MultiDiskWriter.$(OBJEXT) \
|
||||
DiskAdaptor.$(OBJEXT) CopyDiskAdaptor.$(OBJEXT) \
|
||||
DirectDiskAdaptor.$(OBJEXT) MultiDiskAdaptor.$(OBJEXT) \
|
||||
LogFactory.$(OBJEXT) TrackerUpdateCommand.$(OBJEXT) \
|
||||
ByteArrayDiskWriter.$(OBJEXT) PeerChokeCommand.$(OBJEXT)
|
||||
ByteArrayDiskWriter.$(OBJEXT) PeerChokeCommand.$(OBJEXT) \
|
||||
ChokeMessage.$(OBJEXT) UnchokeMessage.$(OBJEXT) \
|
||||
InterestedMessage.$(OBJEXT) NotInterestedMessage.$(OBJEXT) \
|
||||
HaveMessage.$(OBJEXT) BitfieldMessage.$(OBJEXT) \
|
||||
RequestMessage.$(OBJEXT) PieceMessage.$(OBJEXT) \
|
||||
CancelMessage.$(OBJEXT) KeepAliveMessage.$(OBJEXT)
|
||||
am_libaria2c_a_OBJECTS = $(am__objects_1)
|
||||
libaria2c_a_OBJECTS = $(am_libaria2c_a_OBJECTS)
|
||||
am__installdirs = "$(DESTDIR)$(bindir)"
|
||||
|
@ -315,12 +320,10 @@ SRCS = Socket.cc Socket.h\
|
|||
TorrentDownloadEngine.cc TorrentDownloadEngine.h\
|
||||
TorrentConsoleDownloadEngine.cc TorrentConsoleDownloadEngine.h\
|
||||
PeerListenCommand.cc PeerListenCommand.h\
|
||||
PendingMessage.cc PendingMessage.h\
|
||||
PeerMessage.cc PeerMessage.h\
|
||||
HandshakeMessage.h\
|
||||
HandshakeMessage.cc HandshakeMessage.h\
|
||||
Piece.cc Piece.h\
|
||||
RequestSlot.cc RequestSlot.h\
|
||||
RequestSlotMan.cc RequestSlotMan.h\
|
||||
TorrentAutoSaveCommand.cc TorrentAutoSaveCommand.h\
|
||||
Directory.cc Directory.h\
|
||||
TrackerWatcherCommand.cc TrackerWatcherCommand.h\
|
||||
|
@ -335,7 +338,18 @@ SRCS = Socket.cc Socket.h\
|
|||
LogFactory.cc LogFactory.h\
|
||||
TrackerUpdateCommand.cc TrackerUpdateCommand.h\
|
||||
ByteArrayDiskWriter.cc ByteArrayDiskWriter.h\
|
||||
PeerChokeCommand.cc PeerChokeCommand.h
|
||||
PeerChokeCommand.cc PeerChokeCommand.h\
|
||||
ChokeMessage.cc ChokeMessage.h\
|
||||
UnchokeMessage.cc UnchokeMessage.h\
|
||||
InterestedMessage.cc InterestedMessage.h\
|
||||
NotInterestedMessage.cc NotInterestedMessage.h\
|
||||
HaveMessage.cc HaveMessage.h\
|
||||
BitfieldMessage.cc BitfieldMessage.h\
|
||||
RequestMessage.cc RequestMessage.h\
|
||||
PieceMessage.cc PieceMessage.h\
|
||||
CancelMessage.cc CancelMessage.h\
|
||||
KeepAliveMessage.cc KeepAliveMessage.h\
|
||||
PortMessage.h
|
||||
|
||||
noinst_LIBRARIES = libaria2c.a
|
||||
libaria2c_a_SOURCES = $(SRCS)
|
||||
|
@ -425,7 +439,10 @@ distclean-compile:
|
|||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AbstractDiskWriter.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Base64.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BitfieldMan.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BitfieldMessage.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ByteArrayDiskWriter.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CancelMessage.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ChokeMessage.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ChunkedEncoding.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ConsoleDownloadEngine.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CookieBox.Po@am__quote@
|
||||
|
@ -445,6 +462,8 @@ distclean-compile:
|
|||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FtpNegotiationCommand.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FtpTunnelRequestCommand.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FtpTunnelResponseCommand.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HandshakeMessage.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HaveMessage.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HttpConnection.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HttpDownloadCommand.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HttpHeader.Po@am__quote@
|
||||
|
@ -454,11 +473,14 @@ distclean-compile:
|
|||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HttpRequestCommand.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HttpResponseCommand.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/InitiateConnectionCommandFactory.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/InterestedMessage.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/KeepAliveMessage.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/List.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/LogFactory.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MetaFileUtil.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MultiDiskAdaptor.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MultiDiskWriter.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NotInterestedMessage.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Option.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Peer.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PeerAbstractCommand.Po@am__quote@
|
||||
|
@ -469,12 +491,12 @@ distclean-compile:
|
|||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PeerListenCommand.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PeerMessage.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PeerMessageUtil.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PendingMessage.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Piece.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PieceMessage.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PreAllocationDiskWriter.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Request.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RequestMessage.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RequestSlot.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RequestSlotMan.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SegmentMan.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SegmentSplitter.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SendMessageQueue.Po@am__quote@
|
||||
|
@ -491,6 +513,7 @@ distclean-compile:
|
|||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TorrentMan.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TrackerUpdateCommand.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TrackerWatcherCommand.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UnchokeMessage.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Util.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@
|
||||
|
||||
|
|
|
@ -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";
|
||||
}
|
|
@ -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_
|
|
@ -82,7 +82,7 @@ bool PeerAbstractCommand::execute() {
|
|||
checkPoint.tv_usec = 0;
|
||||
throw new DlRetryEx(EX_TIME_OUT);
|
||||
}
|
||||
e->commands.push(this);
|
||||
e->commands.push_back(this);
|
||||
return false;
|
||||
}
|
||||
updateCheckPoint();
|
||||
|
@ -95,24 +95,6 @@ bool PeerAbstractCommand::execute() {
|
|||
delete(err);
|
||||
return prepareForNextPeer(0);
|
||||
}
|
||||
/*catch(DlRetryEx* err) {
|
||||
logger->error(MSG_RESTARTING_DOWNLOAD, err, cuid);
|
||||
peer->tryCount++;
|
||||
bool isAbort = e->option->getAsInt(PREF_MAX_TRIES) != 0 &&
|
||||
peer->tryCount >= e->option->getAsInt(PREF_MAX_TRIES);
|
||||
int tryCount = peer->tryCount;
|
||||
if(isAbort) {
|
||||
onAbort(err);
|
||||
}
|
||||
delete(err);
|
||||
if(isAbort) {
|
||||
logger->error(MSG_MAX_TRY, cuid, tryCount);
|
||||
return true;
|
||||
} else {
|
||||
return prepareForRetry(e->option->getAsInt(PREF_RETRY_WAIT));
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// TODO this method removed when PeerBalancerCommand is implemented
|
||||
|
|
|
@ -131,7 +131,7 @@ bool PeerChokeCommand::execute() {
|
|||
setAllPeerResetDelta(e->torrentMan->getActivePeers());
|
||||
|
||||
SleepCommand* command = new SleepCommand(cuid, e, this, interval);
|
||||
e->commands.push(command);
|
||||
e->commands.push_back(command);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -300,9 +300,9 @@ void PeerConnection::sendCancel(int index, int begin, int length) const {
|
|||
socket->writeData(msg, sizeof(msg));
|
||||
}
|
||||
|
||||
PeerMessage* PeerConnection::receiveMessage() {
|
||||
bool PeerConnection::receiveMessage(char* msg, int& length) {
|
||||
if(!socket->isReadable(0)) {
|
||||
return NULL;
|
||||
return false;
|
||||
}
|
||||
if(resbufLength == 0 && lenbufLength != 4) {
|
||||
// read payload size, 4-byte integer
|
||||
|
@ -316,7 +316,7 @@ PeerMessage* PeerConnection::receiveMessage() {
|
|||
if(remain != temp) {
|
||||
// still 4-temp bytes to go
|
||||
lenbufLength += temp;
|
||||
return NULL;
|
||||
return false;
|
||||
}
|
||||
//payloadLen = ntohl(nPayloadLen);
|
||||
int payloadLength = ntohl(*((int*)lenbuf));
|
||||
|
@ -336,26 +336,21 @@ PeerMessage* PeerConnection::receiveMessage() {
|
|||
}
|
||||
resbufLength += remaining;
|
||||
if(currentPayloadLength != resbufLength) {
|
||||
return NULL;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// we got whole payload.
|
||||
resbufLength = 0;
|
||||
lenbufLength = 0;
|
||||
PeerMessage* peerMessage = PeerMessageUtil::createPeerMessage(resbuf, currentPayloadLength);
|
||||
try {
|
||||
PeerMessageUtil::checkIntegrity(peerMessage, torrentMan->pieceLength,
|
||||
torrentMan->pieces, torrentMan->getTotalLength());
|
||||
} catch(Exception* e) {
|
||||
delete peerMessage;
|
||||
throw;
|
||||
}
|
||||
return peerMessage;
|
||||
|
||||
memcpy(msg, resbuf, currentPayloadLength);
|
||||
length = currentPayloadLength;
|
||||
return true;
|
||||
}
|
||||
|
||||
HandshakeMessage* PeerConnection::receiveHandshake() {
|
||||
bool PeerConnection::receiveHandshake(char* msg, int& length) {
|
||||
if(!socket->isReadable(0)) {
|
||||
return NULL;
|
||||
return false;
|
||||
}
|
||||
int remain = HANDSHAKE_MESSAGE_LENGTH-resbufLength;
|
||||
int temp = remain;
|
||||
|
@ -366,16 +361,12 @@ HandshakeMessage* PeerConnection::receiveHandshake() {
|
|||
}
|
||||
if(remain != temp) {
|
||||
resbufLength += temp;
|
||||
return NULL;
|
||||
return false;
|
||||
}
|
||||
// we got whole handshake payload
|
||||
resbufLength = 0;
|
||||
HandshakeMessage* handshakeMessage = PeerMessageUtil::createHandshakeMessage(resbuf);
|
||||
try {
|
||||
PeerMessageUtil::checkHandshake(handshakeMessage, torrentMan->getInfoHash());
|
||||
} catch(Exception* e) {
|
||||
delete handshakeMessage;
|
||||
throw;
|
||||
}
|
||||
return handshakeMessage;
|
||||
|
||||
memcpy(msg, resbuf, HANDSHAKE_MESSAGE_LENGTH);
|
||||
length = HANDSHAKE_MESSAGE_LENGTH;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -73,8 +73,8 @@ public:
|
|||
void sendPieceHeader(int index, int begin, int length) const;
|
||||
int sendPieceData(long long int offset, int length) const;
|
||||
void sendCancel(int index, int begin, int length) const;
|
||||
PeerMessage* receiveMessage();
|
||||
HandshakeMessage* receiveHandshake();
|
||||
bool receiveMessage(char* msg, int& length);
|
||||
bool receiveHandshake(char* msg, int& length);
|
||||
|
||||
Peer* getPeer() const { return peer; }
|
||||
};
|
||||
|
|
|
@ -43,7 +43,7 @@ bool PeerInitiateConnectionCommand::executeInternal() {
|
|||
socket->establishConnection(peer->ipaddr, peer->port);
|
||||
command = new PeerInteractionCommand(cuid, peer, e, socket, PeerInteractionCommand::INITIATOR_SEND_HANDSHAKE);
|
||||
|
||||
e->commands.push(command);
|
||||
e->commands.push_back(command);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -54,13 +54,13 @@ bool PeerInitiateConnectionCommand::prepareForNextPeer(int wait) {
|
|||
int newCuid = e->torrentMan->getNewCuid();
|
||||
peer->cuid = newCuid;
|
||||
PeerInitiateConnectionCommand* command = new PeerInitiateConnectionCommand(newCuid, peer, e);
|
||||
e->commands.push(command);
|
||||
e->commands.push_back(command);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PeerInitiateConnectionCommand::prepareForRetry(int wait) {
|
||||
PeerInitiateConnectionCommand* command = new PeerInitiateConnectionCommand(cuid, peer, e);
|
||||
e->commands.push(command);
|
||||
e->commands.push_back(command);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -37,10 +37,9 @@ PeerInteractionCommand::PeerInteractionCommand(int cuid, Peer* peer,
|
|||
setWriteCheckSocket(socket);
|
||||
setTimeout(e->option->getAsInt(PREF_PEER_CONNECTION_TIMEOUT));
|
||||
}
|
||||
peerConnection = new PeerConnection(cuid, socket, e->option, peer, e->torrentMan);
|
||||
sendMessageQueue = new SendMessageQueue(cuid, peerConnection, e->torrentMan);
|
||||
sendMessageQueue = new SendMessageQueue(cuid, socket, e->option,
|
||||
e->torrentMan, this->peer);
|
||||
sendMessageQueue->setUploadLimit(e->option->getAsInt(PREF_UPLOAD_LIMIT));
|
||||
piece = Piece::nullPiece;
|
||||
keepAliveCheckPoint.tv_sec = 0;
|
||||
keepAliveCheckPoint.tv_usec = 0;
|
||||
chokeCheckPoint.tv_sec = 0;
|
||||
|
@ -54,7 +53,6 @@ PeerInteractionCommand::PeerInteractionCommand(int cuid, Peer* peer,
|
|||
}
|
||||
|
||||
PeerInteractionCommand::~PeerInteractionCommand() {
|
||||
delete peerConnection;
|
||||
delete sendMessageQueue;
|
||||
e->torrentMan->unadvertisePiece(cuid);
|
||||
e->torrentMan->deleteActivePeer(this->peer);
|
||||
|
@ -70,11 +68,11 @@ bool PeerInteractionCommand::executeInternal() {
|
|||
|
||||
switch(sequence) {
|
||||
case INITIATOR_SEND_HANDSHAKE:
|
||||
peerConnection->sendHandshake();
|
||||
sendMessageQueue->sendHandshake();
|
||||
sequence = INITIATOR_WAIT_HANDSHAKE;
|
||||
break;
|
||||
case INITIATOR_WAIT_HANDSHAKE: {
|
||||
HandshakeMessage* handshakeMessage = peerConnection->receiveHandshake();
|
||||
HandshakeMessage* handshakeMessage = sendMessageQueue->receiveHandshake();
|
||||
if(handshakeMessage == NULL) {
|
||||
break;
|
||||
}
|
||||
|
@ -84,13 +82,13 @@ bool PeerInteractionCommand::executeInternal() {
|
|||
handshakeMessage->toString().c_str());
|
||||
delete handshakeMessage;
|
||||
if(e->torrentMan->getDownloadLength() > 0) {
|
||||
peerConnection->sendBitfield();
|
||||
sendMessageQueue->sendNow(sendMessageQueue->createBitfieldMessage());
|
||||
}
|
||||
sequence = WIRED;
|
||||
break;
|
||||
}
|
||||
case RECEIVER_WAIT_HANDSHAKE: {
|
||||
HandshakeMessage* handshakeMessage = peerConnection->receiveHandshake();
|
||||
HandshakeMessage* handshakeMessage = sendMessageQueue->receiveHandshake();
|
||||
if(handshakeMessage == NULL) {
|
||||
break;
|
||||
}
|
||||
|
@ -99,9 +97,9 @@ bool PeerInteractionCommand::executeInternal() {
|
|||
peer->ipaddr.c_str(), peer->port,
|
||||
handshakeMessage->toString().c_str());
|
||||
delete handshakeMessage;
|
||||
peerConnection->sendHandshake();
|
||||
sendMessageQueue->sendHandshake();
|
||||
if(e->torrentMan->getDownloadLength() > 0) {
|
||||
peerConnection->sendBitfield();
|
||||
sendMessageQueue->sendNow(sendMessageQueue->createBitfieldMessage());
|
||||
}
|
||||
sequence = WIRED;
|
||||
break;
|
||||
|
@ -110,7 +108,7 @@ bool PeerInteractionCommand::executeInternal() {
|
|||
detectMessageFlooding();
|
||||
checkLongTimePeerChoking();
|
||||
checkInactiveConnection();
|
||||
syncPiece();
|
||||
sendMessageQueue->syncPiece();
|
||||
decideChoking();
|
||||
for(int i = 0; i < 10; i++) {
|
||||
if(!socket->isReadable(0)) {
|
||||
|
@ -118,16 +116,15 @@ bool PeerInteractionCommand::executeInternal() {
|
|||
}
|
||||
receiveMessage();
|
||||
}
|
||||
sendMessageQueue->deleteTimeoutRequestSlot(piece);
|
||||
sendMessageQueue->deleteCompletedRequestSlot(piece);
|
||||
sendInterest();
|
||||
sendMessages();
|
||||
sendMessageQueue->deleteTimeoutRequestSlot();
|
||||
sendMessageQueue->deleteCompletedRequestSlot();
|
||||
sendMessageQueue->sendMessages(e->getUploadSpeed());
|
||||
break;
|
||||
}
|
||||
if(sendMessageQueue->countPendingMessage() > 0) {
|
||||
if(sendMessageQueue->countMessageInQueue() > 0) {
|
||||
setWriteCheckSocket(socket);
|
||||
}
|
||||
e->commands.push(this);
|
||||
e->commands.push_back(this);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -184,109 +181,47 @@ void PeerInteractionCommand::checkLongTimePeerChoking() {
|
|||
}
|
||||
}
|
||||
|
||||
void PeerInteractionCommand::syncPiece() {
|
||||
if(Piece::isNull(piece)) {
|
||||
return;
|
||||
}
|
||||
e->torrentMan->syncPiece(piece);
|
||||
}
|
||||
|
||||
void PeerInteractionCommand::decideChoking() {
|
||||
if(peer->shouldBeChoking()) {
|
||||
if(!peer->amChoking) {
|
||||
PendingMessage pendingMessage(PeerMessage::CHOKE, peerConnection);
|
||||
sendMessageQueue->addPendingMessage(pendingMessage);
|
||||
sendMessageQueue->addMessage(sendMessageQueue->createChokeMessage());
|
||||
}
|
||||
} else {
|
||||
if(peer->amChoking) {
|
||||
PendingMessage pendingMessage(PeerMessage::UNCHOKE, peerConnection);
|
||||
sendMessageQueue->addPendingMessage(pendingMessage);
|
||||
sendMessageQueue->addMessage(sendMessageQueue->createUnchokeMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PeerInteractionCommand::receiveMessage() {
|
||||
PeerMessage* message = peerConnection->receiveMessage();
|
||||
PeerMessage* message = sendMessageQueue->receiveMessage();
|
||||
if(message == NULL) {
|
||||
return;
|
||||
}
|
||||
logger->info(MSG_RECEIVE_PEER_MESSAGE, cuid,
|
||||
peer->ipaddr.c_str(), peer->port,
|
||||
message->toString().c_str());
|
||||
// to detect flooding
|
||||
switch(message->getId()) {
|
||||
case KeepAliveMessage::ID:
|
||||
keepAliveCount++;
|
||||
break;
|
||||
case ChokeMessage::ID:
|
||||
if(!peer->peerChoking) {
|
||||
chokeUnchokeCount++;
|
||||
}
|
||||
break;
|
||||
case UnchokeMessage::ID:
|
||||
if(peer->peerChoking) {
|
||||
chokeUnchokeCount++;
|
||||
}
|
||||
break;
|
||||
case HaveMessage::ID:
|
||||
haveCount++;
|
||||
break;
|
||||
}
|
||||
try {
|
||||
switch(message->getId()) {
|
||||
case PeerMessage::KEEP_ALIVE:
|
||||
keepAliveCount++;
|
||||
break;
|
||||
case PeerMessage::CHOKE:
|
||||
if(!peer->peerChoking) {
|
||||
chokeUnchokeCount++;
|
||||
}
|
||||
peer->peerChoking = true;
|
||||
break;
|
||||
case PeerMessage::UNCHOKE:
|
||||
if(peer->peerChoking) {
|
||||
chokeUnchokeCount++;
|
||||
}
|
||||
peer->peerChoking = false;
|
||||
break;
|
||||
case PeerMessage::INTERESTED:
|
||||
peer->peerInterested = true;
|
||||
break;
|
||||
case PeerMessage::NOT_INTERESTED:
|
||||
peer->peerInterested = false;
|
||||
break;
|
||||
case PeerMessage::HAVE:
|
||||
haveCount++;
|
||||
peer->updateBitfield(message->getIndex(), 1);
|
||||
break;
|
||||
case PeerMessage::BITFIELD:
|
||||
peer->setBitfield(message->getBitfield(), message->getBitfieldLength());
|
||||
break;
|
||||
case PeerMessage::REQUEST:
|
||||
if(e->torrentMan->hasPiece(message->getIndex())) {
|
||||
PendingMessage pendingMessage
|
||||
= PendingMessage::createPieceMessage(message->getIndex(),
|
||||
message->getBegin(),
|
||||
message->getLength(),
|
||||
e->torrentMan->pieceLength,
|
||||
peerConnection);
|
||||
sendMessageQueue->addPendingMessage(pendingMessage);
|
||||
e->torrentMan->addUploadLength(message->getLength());
|
||||
e->torrentMan->addDeltaUploadLength(message->getLength());
|
||||
}
|
||||
break;
|
||||
case PeerMessage::CANCEL:
|
||||
sendMessageQueue->deletePendingPieceMessage(message);
|
||||
break;
|
||||
case PeerMessage::PIECE: {
|
||||
RequestSlot slot = sendMessageQueue->getCorrespoindingRequestSlot(message);
|
||||
peer->addPeerUpload(message->getBlockLength());
|
||||
if(!Piece::isNull(piece) && !RequestSlot::isNull(slot)) {
|
||||
long long int offset =
|
||||
((long long int)message->getIndex())*e->torrentMan->pieceLength+message->getBegin();
|
||||
logger->debug("CUID#%d - write block length = %d, offset=%lld",
|
||||
cuid, message->getBlockLength(), offset);
|
||||
e->torrentMan->diskAdaptor->writeData(message->getBlock(),
|
||||
message->getBlockLength(),
|
||||
offset);
|
||||
piece.completeBlock(slot.getBlockIndex());
|
||||
sendMessageQueue->deleteRequestSlot(slot);
|
||||
e->torrentMan->updatePiece(piece);
|
||||
logger->debug("CUID#%d - setting piece bit index=%d", cuid,
|
||||
slot.getBlockIndex());
|
||||
e->torrentMan->addDeltaDownloadLength(message->getBlockLength());
|
||||
if(piece.pieceComplete()) {
|
||||
if(checkPieceHash(piece)) {
|
||||
onGotNewPiece();
|
||||
} else {
|
||||
onGotWrongPiece();
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
message->receivedAction();
|
||||
delete message;
|
||||
} catch(Exception* ex) {
|
||||
delete message;
|
||||
|
@ -294,20 +229,6 @@ void PeerInteractionCommand::receiveMessage() {
|
|||
}
|
||||
}
|
||||
|
||||
void PeerInteractionCommand::onGotNewPiece() {
|
||||
logger->info(MSG_GOT_NEW_PIECE, cuid, piece.getIndex());
|
||||
e->torrentMan->completePiece(piece);
|
||||
e->torrentMan->advertisePiece(cuid, piece.getIndex());
|
||||
piece = Piece::nullPiece;
|
||||
}
|
||||
|
||||
void PeerInteractionCommand::onGotWrongPiece() {
|
||||
logger->error(MSG_GOT_WRONG_PIECE, cuid, piece.getIndex());
|
||||
erasePieceOnDisk(piece);
|
||||
piece.clearAllBlock();
|
||||
e->torrentMan->updatePiece(piece);
|
||||
}
|
||||
|
||||
// TODO this method removed when PeerBalancerCommand is implemented
|
||||
bool PeerInteractionCommand::prepareForNextPeer(int wait) {
|
||||
if(e->torrentMan->isPeerAvailable()) {
|
||||
|
@ -315,81 +236,18 @@ bool PeerInteractionCommand::prepareForNextPeer(int wait) {
|
|||
int newCuid = e->torrentMan->getNewCuid();
|
||||
peer->cuid = newCuid;
|
||||
PeerInitiateConnectionCommand* command = new PeerInitiateConnectionCommand(newCuid, peer, e);
|
||||
e->commands.push(command);
|
||||
e->commands.push_back(command);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PeerInteractionCommand::prepareForRetry(int wait) {
|
||||
e->commands.push(this);
|
||||
e->commands.push_back(this);
|
||||
return false;
|
||||
}
|
||||
|
||||
Piece PeerInteractionCommand::getNewPieceAndSendInterest() {
|
||||
sendMessageQueue->cancelAllRequest();
|
||||
Piece piece = e->torrentMan->getMissingPiece(peer);
|
||||
if(Piece::isNull(piece)) {
|
||||
logger->debug("CUID#%d - try to send not-interested", cuid);
|
||||
PendingMessage pendingMessage(PeerMessage::NOT_INTERESTED, peerConnection);
|
||||
sendMessageQueue->addPendingMessage(pendingMessage);
|
||||
} else {
|
||||
logger->debug("CUID#%d - starting download for piece index=%d (%d/%d completed)", cuid, piece.getIndex(), piece.countCompleteBlock(), piece.countBlock());
|
||||
logger->debug("CUID#%d - try to send interested", cuid);
|
||||
PendingMessage pendingMessage(PeerMessage::INTERESTED, peerConnection);
|
||||
sendMessageQueue->addPendingMessage(pendingMessage);
|
||||
}
|
||||
return piece;
|
||||
}
|
||||
|
||||
void PeerInteractionCommand::sendInterest() {
|
||||
if(Piece::isNull(piece)) {
|
||||
// retrive new piece from TorrentMan
|
||||
piece = getNewPieceAndSendInterest();
|
||||
} else if(peer->peerChoking) {
|
||||
sendMessageQueue->cancelAllRequest(piece);
|
||||
e->torrentMan->cancelPiece(piece);
|
||||
piece = Piece::nullPiece;
|
||||
} else if(piece.pieceComplete()) {
|
||||
piece = getNewPieceAndSendInterest();
|
||||
}
|
||||
}
|
||||
|
||||
void PeerInteractionCommand::createRequestPendingMessage(int blockIndex) {
|
||||
PendingMessage pendingMessage =
|
||||
PendingMessage::createRequestMessage(piece, blockIndex, peerConnection);
|
||||
sendMessageQueue->addPendingMessage(pendingMessage);
|
||||
}
|
||||
|
||||
void PeerInteractionCommand::sendMessages() {
|
||||
if(!Piece::isNull(piece) && !peer->peerChoking) {
|
||||
if(e->torrentMan->isEndGame()) {
|
||||
BlockIndexes missingBlockIndexes = piece.getAllMissingBlockIndexes();
|
||||
if(sendMessageQueue->countRequestSlot() == 0) {
|
||||
random_shuffle(missingBlockIndexes.begin(), missingBlockIndexes.end());
|
||||
int count = 0;
|
||||
for(PieceIndexes::const_iterator itr = missingBlockIndexes.begin();
|
||||
itr != missingBlockIndexes.end() && count < 6; itr++, count++) {
|
||||
createRequestPendingMessage(*itr);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for(int i = sendMessageQueue->countRequestSlot(); i < 6; i++) {
|
||||
int blockIndex = piece.getMissingUnusedBlockIndex();
|
||||
if(blockIndex == -1) {
|
||||
break;
|
||||
}
|
||||
e->torrentMan->updatePiece(piece);
|
||||
createRequestPendingMessage(blockIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sendMessageQueue->send(e->getUploadSpeed());
|
||||
}
|
||||
|
||||
void PeerInteractionCommand::onAbort(Exception* ex) {
|
||||
sendMessageQueue->cancelAllRequest(piece);
|
||||
e->torrentMan->cancelPiece(piece);
|
||||
sendMessageQueue->abortPiece();
|
||||
PeerAbstractCommand::onAbort(ex);
|
||||
}
|
||||
|
||||
|
@ -400,8 +258,8 @@ void PeerInteractionCommand::keepAlive() {
|
|||
struct timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
if(Util::difftv(now, keepAliveCheckPoint) >= (long long int)120*1000000) {
|
||||
if(sendMessageQueue->countPendingMessage() == 0) {
|
||||
peerConnection->sendKeepAlive();
|
||||
if(sendMessageQueue->countMessageInQueue() == 0) {
|
||||
sendMessageQueue->sendNow(sendMessageQueue->createKeepAliveMessage());
|
||||
}
|
||||
keepAliveCheckPoint = now;
|
||||
}
|
||||
|
@ -417,41 +275,12 @@ void PeerInteractionCommand::beforeSocketCheck() {
|
|||
|
||||
PieceIndexes indexes = e->torrentMan->getAdvertisedPieceIndexes(cuid);
|
||||
if(indexes.size() >= 20) {
|
||||
PendingMessage pendingMessage(PeerMessage::BITFIELD, peerConnection);
|
||||
sendMessageQueue->addPendingMessage(pendingMessage);
|
||||
sendMessageQueue->trySendNow(sendMessageQueue->createBitfieldMessage());
|
||||
} else {
|
||||
if(sendMessageQueue->countPendingMessage() == 0) {
|
||||
for(PieceIndexes::iterator itr = indexes.begin(); itr != indexes.end(); itr++) {
|
||||
peerConnection->sendHave(*itr);
|
||||
}
|
||||
} else {
|
||||
for(PieceIndexes::iterator itr = indexes.begin(); itr != indexes.end(); itr++) {
|
||||
PendingMessage pendingMessage = PendingMessage::createHaveMessage(*itr, peerConnection);
|
||||
sendMessageQueue->addPendingMessage(pendingMessage);
|
||||
}
|
||||
for(PieceIndexes::iterator itr = indexes.begin(); itr != indexes.end(); itr++) {
|
||||
sendMessageQueue->trySendNow(sendMessageQueue->createHaveMessage(*itr));
|
||||
}
|
||||
}
|
||||
keepAlive();
|
||||
}
|
||||
}
|
||||
|
||||
bool PeerInteractionCommand::checkPieceHash(const Piece& piece) {
|
||||
long long int offset = ((long long int)piece.getIndex())*e->torrentMan->pieceLength;
|
||||
return e->torrentMan->diskAdaptor->sha1Sum(offset, piece.getLength()) ==
|
||||
e->torrentMan->getPieceHash(piece.getIndex());
|
||||
}
|
||||
|
||||
void PeerInteractionCommand::erasePieceOnDisk(const Piece& piece) {
|
||||
int BUFSIZE = 4096;
|
||||
char buf[BUFSIZE];
|
||||
memset(buf, 0, BUFSIZE);
|
||||
long long int offset = ((long long int)piece.getIndex())*e->torrentMan->pieceLength;
|
||||
for(int i = 0; i < piece.getLength()/BUFSIZE; i++) {
|
||||
e->torrentMan->diskAdaptor->writeData(buf, BUFSIZE, offset);
|
||||
offset += BUFSIZE;
|
||||
}
|
||||
int r = piece.getLength()%BUFSIZE;
|
||||
if(r > 0) {
|
||||
e->torrentMan->diskAdaptor->writeData(buf, r, offset);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,9 +33,8 @@ using namespace std;
|
|||
class PeerInteractionCommand : public PeerAbstractCommand {
|
||||
private:
|
||||
int sequence;
|
||||
PeerConnection* peerConnection;
|
||||
SendMessageQueue* sendMessageQueue;
|
||||
Piece piece;
|
||||
|
||||
struct timeval keepAliveCheckPoint;
|
||||
struct timeval chokeCheckPoint;
|
||||
struct timeval freqCheckPoint;
|
||||
|
@ -46,18 +45,9 @@ private:
|
|||
void detectMessageFlooding();
|
||||
void checkLongTimePeerChoking();
|
||||
void checkInactiveConnection();
|
||||
void syncPiece();
|
||||
void detectTimeoutAndDuplicateBlock();
|
||||
void decideChoking();
|
||||
void sendInterest();
|
||||
void sendMessages();
|
||||
void createRequestPendingMessage(int blockIndex);
|
||||
bool checkPieceHash(const Piece& piece);
|
||||
void erasePieceOnDisk(const Piece& piece);
|
||||
void keepAlive();
|
||||
Piece getNewPieceAndSendInterest();
|
||||
void onGotNewPiece();
|
||||
void onGotWrongPiece();
|
||||
protected:
|
||||
bool executeInternal();
|
||||
bool prepareForRetry(int wait);
|
||||
|
|
|
@ -73,7 +73,7 @@ bool PeerListenCommand::execute() {
|
|||
PeerInteractionCommand* command =
|
||||
new PeerInteractionCommand(newCuid, peer, e, peerSocket,
|
||||
PeerInteractionCommand::RECEIVER_WAIT_HANDSHAKE);
|
||||
e->commands.push(command);
|
||||
e->commands.push_back(command);
|
||||
logger->debug("CUID#%d - incoming connection, adding new command CUID#%d", cuid, newCuid);
|
||||
} else {
|
||||
delete peer;
|
||||
|
@ -88,6 +88,6 @@ bool PeerListenCommand::execute() {
|
|||
}
|
||||
}
|
||||
}
|
||||
e->commands.push(this);
|
||||
e->commands.push_back(this);
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -20,53 +20,8 @@
|
|||
*/
|
||||
/* copyright --> */
|
||||
#include "PeerMessage.h"
|
||||
#include "Util.h"
|
||||
#include "LogFactory.h"
|
||||
|
||||
void PeerMessage::setBitfield(const unsigned char* bitfield, int bitfieldLength) {
|
||||
if(this->bitfield != NULL) {
|
||||
delete [] this->bitfield;
|
||||
}
|
||||
this->bitfieldLength = bitfieldLength;
|
||||
this->bitfield = new unsigned char[this->bitfieldLength];
|
||||
memcpy(this->bitfield, bitfield, this->bitfieldLength);
|
||||
PeerMessage::PeerMessage():inProgress(false) {
|
||||
logger = LogFactory::getInstance();
|
||||
}
|
||||
|
||||
void PeerMessage::setBlock(const char* block, int blockLength) {
|
||||
if(this->block != NULL) {
|
||||
delete [] this->block;
|
||||
}
|
||||
this->blockLength = blockLength;
|
||||
this->block = new char[this->blockLength];
|
||||
memcpy(this->block, block, this->blockLength);
|
||||
}
|
||||
|
||||
string PeerMessage::toString() const {
|
||||
switch(id) {
|
||||
case CHOKE:
|
||||
return "choke";
|
||||
case UNCHOKE:
|
||||
return "unchoke";
|
||||
case INTERESTED:
|
||||
return "interested";
|
||||
case NOT_INTERESTED:
|
||||
return "not interested";
|
||||
case HAVE:
|
||||
return "have index="+Util::itos(index);
|
||||
case BITFIELD:
|
||||
return "bitfield "+Util::toHex(bitfield, bitfieldLength);
|
||||
case REQUEST:
|
||||
return "request index="+Util::itos(index)+", begin="+Util::itos(begin)+
|
||||
", length="+Util::itos(length);
|
||||
case PIECE:
|
||||
return "piece index="+Util::itos(index)+", begin="+Util::itos(begin)+
|
||||
", length="+Util::itos(blockLength);
|
||||
case CANCEL:
|
||||
return "cancel index="+Util::itos(index)+", begin="+Util::itos(begin)+
|
||||
", length="+Util::itos(length);
|
||||
case KEEP_ALIVE:
|
||||
return "keep alive";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,61 +23,44 @@
|
|||
#define _D_PEER_MESSAGE_H_
|
||||
|
||||
#include "common.h"
|
||||
#include "Logger.h"
|
||||
#include "Peer.h"
|
||||
#include <string>
|
||||
|
||||
class SendMessageQueue;
|
||||
|
||||
class PeerMessage {
|
||||
private:
|
||||
int id;
|
||||
int index;
|
||||
int begin;
|
||||
int length;
|
||||
unsigned char* bitfield;
|
||||
int bitfieldLength;
|
||||
char* block;
|
||||
int blockLength;
|
||||
protected:
|
||||
bool inProgress;
|
||||
int cuid;
|
||||
Peer* peer;
|
||||
SendMessageQueue* sendMessageQueue;
|
||||
const Logger* logger;
|
||||
public:
|
||||
PeerMessage():bitfield(NULL), bitfieldLength(0),
|
||||
block(NULL), blockLength(0) {}
|
||||
~PeerMessage() {
|
||||
if(bitfield != NULL) {
|
||||
delete [] bitfield;
|
||||
}
|
||||
if(block != NULL) {
|
||||
delete [] block;
|
||||
}
|
||||
PeerMessage();
|
||||
|
||||
virtual ~PeerMessage() {}
|
||||
|
||||
bool isInProgress() const { return inProgress; }
|
||||
|
||||
int getCuid() const { return cuid; }
|
||||
void setCuid(int cuid) {
|
||||
this->cuid = cuid;
|
||||
}
|
||||
Peer* getPeer() const { return this->peer; }
|
||||
void setPeer(Peer* peer) {
|
||||
this->peer = peer;
|
||||
}
|
||||
SendMessageQueue* getSendMessageQueue() const { return sendMessageQueue; }
|
||||
void setSendMessageQueue(SendMessageQueue* sendMessageQueue) {
|
||||
this->sendMessageQueue = sendMessageQueue;
|
||||
}
|
||||
|
||||
void setBitfield(const unsigned char* bitfield, int bitfieldLength);
|
||||
const unsigned char* getBitfield() const { return bitfield; }
|
||||
|
||||
void setBlock(const char* block, int blockLength);
|
||||
const char* getBlock() const { return block; }
|
||||
|
||||
int getBitfieldLength() const { return bitfieldLength; }
|
||||
int getBlockLength() const { return blockLength; }
|
||||
|
||||
string toString() const;
|
||||
|
||||
int getId() const { return id; }
|
||||
void setId(int id) { this->id = id; }
|
||||
int getIndex() const { return index; }
|
||||
void setIndex(int index) { this->index = index; }
|
||||
int getBegin() const { return begin; }
|
||||
void setBegin(int begin) { this->begin = begin; }
|
||||
int getLength() const { return length; }
|
||||
void setLength(int length) { this->length = length; }
|
||||
|
||||
enum ID {
|
||||
CHOKE = 0,
|
||||
UNCHOKE = 1,
|
||||
INTERESTED = 2,
|
||||
NOT_INTERESTED = 3,
|
||||
HAVE = 4,
|
||||
BITFIELD = 5,
|
||||
REQUEST = 6,
|
||||
PIECE = 7,
|
||||
CANCEL = 8,
|
||||
KEEP_ALIVE = 99};
|
||||
virtual int getId() const = 0;
|
||||
virtual void receivedAction() = 0;
|
||||
virtual void send() = 0;
|
||||
virtual void check() const {}
|
||||
virtual string toString() const = 0;
|
||||
};
|
||||
|
||||
#endif // _D_PEER_MESSAGE_H_
|
||||
|
|
|
@ -24,94 +24,6 @@
|
|||
#include "Util.h"
|
||||
#include <netinet/in.h>
|
||||
|
||||
PeerMessage* PeerMessageUtil::createPeerMessage(const char* msg, int len) {
|
||||
PeerMessage* peerMessage;
|
||||
if(len == 0) {
|
||||
// keep-alive
|
||||
peerMessage = new PeerMessage();
|
||||
peerMessage->setId(PeerMessage::KEEP_ALIVE);
|
||||
return peerMessage;
|
||||
}
|
||||
int id = getId(msg);
|
||||
switch(id) {
|
||||
case PeerMessage::CHOKE:
|
||||
case PeerMessage::UNCHOKE:
|
||||
case PeerMessage::INTERESTED:
|
||||
case PeerMessage::NOT_INTERESTED:
|
||||
peerMessage = createBasicMessage(id, msg, len);
|
||||
break;
|
||||
case PeerMessage::HAVE:
|
||||
peerMessage = createHaveMessage(id, msg, len);
|
||||
break;
|
||||
case PeerMessage::BITFIELD:
|
||||
peerMessage = createBitfieldMessage(id, msg, len);
|
||||
break;
|
||||
case PeerMessage::REQUEST:
|
||||
case PeerMessage::CANCEL:
|
||||
peerMessage = createRequestCancelMessage(id, msg, len);
|
||||
break;
|
||||
case PeerMessage::PIECE:
|
||||
peerMessage = createPieceMessage(id, msg, len);
|
||||
break;
|
||||
default:
|
||||
throw new DlAbortEx("invalid message id. id = %d", id);
|
||||
}
|
||||
return peerMessage;
|
||||
}
|
||||
|
||||
PeerMessage* PeerMessageUtil::createBasicMessage(int id, const char* msg, int len) {
|
||||
if(len != 1) {
|
||||
throw new DlAbortEx("invalid payload size for ID%d, size = %d. It should be %d", id, len, 1);
|
||||
}
|
||||
PeerMessage* peerMessage = new PeerMessage();
|
||||
peerMessage->setId(id);
|
||||
return peerMessage;
|
||||
}
|
||||
|
||||
PeerMessage* PeerMessageUtil::createHaveMessage(int id, const char* msg, int len) {
|
||||
if(len != 5) {
|
||||
throw new DlAbortEx("invalid payload size for ID%d, size = %d. It should be %d", id, len, 5);
|
||||
}
|
||||
PeerMessage* peerMessage = new PeerMessage();
|
||||
peerMessage->setId(id);
|
||||
peerMessage->setIndex(getIntParam(msg, 1));
|
||||
return peerMessage;
|
||||
}
|
||||
|
||||
PeerMessage* PeerMessageUtil::createBitfieldMessage(int id, const char* msg, int len) {
|
||||
if(len <= 1) {
|
||||
throw new DlAbortEx("invalid payload size for ID%d, size = %d. It should be greater than %d", id, len, 1);
|
||||
}
|
||||
PeerMessage* peerMessage = new PeerMessage();
|
||||
peerMessage->setId(id);
|
||||
peerMessage->setBitfield((unsigned char*)msg+1, len-1);
|
||||
return peerMessage;
|
||||
}
|
||||
|
||||
PeerMessage* PeerMessageUtil::createRequestCancelMessage(int id, const char* msg, int len) {
|
||||
if(len != 13) {
|
||||
throw new DlAbortEx("invalid payload size for ID%d, size = %d. It should be %d", id, len, 13);
|
||||
}
|
||||
PeerMessage* peerMessage = new PeerMessage();
|
||||
peerMessage->setId(id);
|
||||
peerMessage->setIndex(getIntParam(msg, 1));
|
||||
peerMessage->setBegin(getIntParam(msg, 5));
|
||||
peerMessage->setLength(getIntParam(msg, 9));
|
||||
return peerMessage;
|
||||
}
|
||||
|
||||
PeerMessage* PeerMessageUtil::createPieceMessage(int id, const char* msg, int len) {
|
||||
if(len <= 9) {
|
||||
throw new DlAbortEx("invalid payload size for ID%d, size = %d. It should be greater than %d", id, len, 9);
|
||||
}
|
||||
PeerMessage* peerMessage = new PeerMessage();
|
||||
peerMessage->setId(id);
|
||||
peerMessage->setIndex(getIntParam(msg, 1));
|
||||
peerMessage->setBegin(getIntParam(msg, 5));
|
||||
peerMessage->setBlock(msg+9, len-9);
|
||||
return peerMessage;
|
||||
}
|
||||
|
||||
int PeerMessageUtil::getId(const char* msg) {
|
||||
return (int)msg[0];
|
||||
}
|
||||
|
@ -122,50 +34,145 @@ int PeerMessageUtil::getIntParam(const char* msg, int offset) {
|
|||
return ntohl(nParam);
|
||||
}
|
||||
|
||||
void PeerMessageUtil::checkIndex(const PeerMessage* message, int pieces) {
|
||||
if(!(0 <= message->getIndex() && message->getIndex() < pieces)) {
|
||||
throw new DlAbortEx("invalid index = %d", message->getIndex());
|
||||
int PeerMessageUtil::getShortIntParam(const char* msg, int offset) {
|
||||
short int nParam;
|
||||
memcpy(&nParam, msg+offset, 2);
|
||||
return ntohs(nParam);
|
||||
}
|
||||
|
||||
ChokeMessage* PeerMessageUtil::createChokeMessage(const char* msg, int len) {
|
||||
if(len != 1) {
|
||||
throw new DlAbortEx("invalid payload size for %s, size = %d. It should be %d", "choke", len, 1);
|
||||
}
|
||||
ChokeMessage* chokeMessage = new ChokeMessage();
|
||||
return chokeMessage;
|
||||
}
|
||||
|
||||
UnchokeMessage* PeerMessageUtil::createUnchokeMessage(const char* msg, int len) {
|
||||
if(len != 1) {
|
||||
throw new DlAbortEx("invalid payload size for %s, size = %d. It should be %d", "unchoke", len, 1);
|
||||
}
|
||||
UnchokeMessage* unchokeMessage = new UnchokeMessage();
|
||||
return unchokeMessage;
|
||||
}
|
||||
|
||||
InterestedMessage* PeerMessageUtil::createInterestedMessage(const char* msg, int len) {
|
||||
if(len != 1) {
|
||||
throw new DlAbortEx("invalid payload size for %s, size = %d. It should be %d", "interested", len, 1);
|
||||
}
|
||||
InterestedMessage* interestedMessage = new InterestedMessage();
|
||||
return interestedMessage;
|
||||
}
|
||||
|
||||
NotInterestedMessage* PeerMessageUtil::createNotInterestedMessage(const char* msg, int len) {
|
||||
if(len != 1) {
|
||||
throw new DlAbortEx("invalid payload size for %s, size = %d. It should be %d", "not interested", len, 1);
|
||||
}
|
||||
NotInterestedMessage* notInterestedMessage = new NotInterestedMessage();
|
||||
return notInterestedMessage;
|
||||
}
|
||||
|
||||
HaveMessage* PeerMessageUtil::createHaveMessage(const char* msg, int len) {
|
||||
if(len != 5) {
|
||||
throw new DlAbortEx("invalid payload size for %s, size = %d. It should be %d", "have", len, 5);
|
||||
}
|
||||
HaveMessage* haveMessage = new HaveMessage();
|
||||
haveMessage->setIndex(getIntParam(msg, 1));
|
||||
return haveMessage;
|
||||
}
|
||||
|
||||
BitfieldMessage* PeerMessageUtil::createBitfieldMessage(const char* msg, int len) {
|
||||
if(len <= 1) {
|
||||
throw new DlAbortEx("invalid payload size for %s, size = %d. It should be greater than %d", "bitfield", len, 1);
|
||||
}
|
||||
BitfieldMessage* bitfieldMessage = new BitfieldMessage();
|
||||
bitfieldMessage->setBitfield((unsigned char*)msg+1, len-1);
|
||||
return bitfieldMessage;
|
||||
}
|
||||
|
||||
RequestMessage* PeerMessageUtil::createRequestMessage(const char* msg, int len) {
|
||||
if(len != 13) {
|
||||
throw new DlAbortEx("invalid payload size for %s, size = %d. It should be %d", "request", len, 13);
|
||||
}
|
||||
RequestMessage* requestMessage = new RequestMessage();
|
||||
requestMessage->setIndex(getIntParam(msg, 1));
|
||||
requestMessage->setBegin(getIntParam(msg, 5));
|
||||
requestMessage->setLength(getIntParam(msg, 9));
|
||||
return requestMessage;
|
||||
}
|
||||
|
||||
CancelMessage* PeerMessageUtil::createCancelMessage(const char* msg, int len) {
|
||||
if(len != 13) {
|
||||
throw new DlAbortEx("invalid payload size for %s, size = %d. It should be %d", "cancel", len, 13);
|
||||
}
|
||||
CancelMessage* cancelMessage = new CancelMessage();
|
||||
cancelMessage->setIndex(getIntParam(msg, 1));
|
||||
cancelMessage->setBegin(getIntParam(msg, 5));
|
||||
cancelMessage->setLength(getIntParam(msg, 9));
|
||||
return cancelMessage;
|
||||
}
|
||||
|
||||
PieceMessage* PeerMessageUtil::createPieceMessage(const char* msg, int len) {
|
||||
if(len <= 9) {
|
||||
throw new DlAbortEx("invalid payload size for %s, size = %d. It should be greater than %d", "piece", len, 9);
|
||||
}
|
||||
PieceMessage* pieceMessage = new PieceMessage();
|
||||
pieceMessage->setIndex(getIntParam(msg, 1));
|
||||
pieceMessage->setBegin(getIntParam(msg, 5));
|
||||
pieceMessage->setBlock(msg+9, len-9);
|
||||
return pieceMessage;
|
||||
}
|
||||
|
||||
PortMessage* PeerMessageUtil::createPortMessage(const char* msg, int len) {
|
||||
if(len != 3) {
|
||||
throw new DlAbortEx("invalid payload size for %s, size = %d. It should be %d", "port", len, 3);
|
||||
}
|
||||
PortMessage* portMessage = new PortMessage();
|
||||
portMessage->setPort(getShortIntParam(msg, 1));
|
||||
return portMessage;
|
||||
}
|
||||
|
||||
void PeerMessageUtil::checkIndex(int index, int pieces) {
|
||||
if(!(0 <= index && index < pieces)) {
|
||||
throw new DlAbortEx("invalid index = %d", index);
|
||||
}
|
||||
}
|
||||
|
||||
void PeerMessageUtil::checkBegin(const PeerMessage* message, int pieceLength) {
|
||||
if(!(0 <= message->getBegin() && message->getBegin() < pieceLength)) {
|
||||
throw new DlAbortEx("invalid begin = %d", message->getBegin());
|
||||
}
|
||||
void PeerMessageUtil::checkBegin(int begin, int pieceLength) {
|
||||
if(!(0 <= begin && begin < pieceLength)) {
|
||||
throw new DlAbortEx("invalid begin = %d", begin);
|
||||
}
|
||||
}
|
||||
|
||||
void PeerMessageUtil::checkPieceOffset(const PeerMessage* message, int pieceLength, int pieces, long long int totalLength) {
|
||||
if(!(0 <= message->getBegin() && 0 < message->getLength())) {
|
||||
throw new DlAbortEx("invalid offset, begin = %d, length = %d", message->getBegin(), message->getLength());
|
||||
}
|
||||
int offset = message->getBegin()+message->getLength();
|
||||
int currentPieceLength;
|
||||
if(message->getIndex()+1 == pieces) {
|
||||
currentPieceLength = pieceLength-(pieces*pieceLength-totalLength);
|
||||
} else {
|
||||
currentPieceLength = pieceLength;
|
||||
}
|
||||
if(!(0 < offset && offset <= currentPieceLength)) {
|
||||
throw new DlAbortEx("invalid offset, begin = %d, length = %d", message->getBegin(), message->getLength());
|
||||
}
|
||||
}
|
||||
|
||||
void PeerMessageUtil::checkLength(const PeerMessage* message) {
|
||||
if(message->getLength() > MAX_BLOCK_LENGTH) {
|
||||
throw new DlAbortEx("too large length %d > %dKB", message->getLength(),
|
||||
void PeerMessageUtil::checkLength(int length) {
|
||||
if(length > MAX_BLOCK_LENGTH) {
|
||||
throw new DlAbortEx("too large length %d > %dKB", length,
|
||||
MAX_BLOCK_LENGTH/1024);
|
||||
}
|
||||
if(!Util::isPowerOf(message->getLength(), 2)) {
|
||||
if(!Util::isPowerOf(length, 2)) {
|
||||
throw new DlAbortEx("invalid length %d, which is not power of 2",
|
||||
message->getLength());
|
||||
length);
|
||||
}
|
||||
}
|
||||
|
||||
void PeerMessageUtil::checkBitfield(const PeerMessage* message, int pieces) {
|
||||
if(!(message->getBitfieldLength() == BITFIELD_LEN_FROM_PIECES(pieces))) {
|
||||
throw new DlAbortEx("invalid bitfield length = %d", message->getBitfieldLength());
|
||||
void PeerMessageUtil::checkRange(int begin, int length, int pieceLength) {
|
||||
if(!(0 <= begin && 0 < length)) {
|
||||
throw new DlAbortEx("invalid range, begin = %d, length = %d",
|
||||
begin, length);
|
||||
}
|
||||
char lastbyte = message->getBitfield()[message->getBitfieldLength()-1];
|
||||
int end = begin+length;
|
||||
if(!(0 < end && end <= pieceLength)) {
|
||||
throw new DlAbortEx("invalid range, begin = %d, length = %d",
|
||||
begin, length);
|
||||
}
|
||||
}
|
||||
|
||||
void PeerMessageUtil::checkBitfield(const unsigned char* bitfield, int bitfieldLength, int pieces) {
|
||||
if(!(bitfieldLength == BITFIELD_LEN_FROM_PIECES(pieces))) {
|
||||
throw new DlAbortEx("invalid bitfield length = %d",
|
||||
bitfieldLength);
|
||||
}
|
||||
char lastbyte = bitfield[bitfieldLength-1];
|
||||
for(int i = 0; i < 8-pieces%8 && pieces%8 != 0; i++) {
|
||||
if(!(((lastbyte >> i) & 1) == 0)) {
|
||||
throw new DlAbortEx("invalid bitfield");
|
||||
|
@ -173,42 +180,7 @@ void PeerMessageUtil::checkBitfield(const PeerMessage* message, int pieces) {
|
|||
}
|
||||
}
|
||||
|
||||
void PeerMessageUtil::checkIntegrity(const PeerMessage* message, int pieceLength, int pieces, long long int totalLength) {
|
||||
// 0 <= index < pieces
|
||||
// 0 <= begin < pieceLength
|
||||
// 0 < begin+length <= pieceLength
|
||||
// len of bitfield == pieces/8+(pieces%8 ? 1 : 0)
|
||||
// for(int i = 0; i < 8-pieces%8; i++) { ((lastbyteofbitfield >> i) & 1) == 0 }
|
||||
switch(message->getId()) {
|
||||
case PeerMessage::KEEP_ALIVE:
|
||||
case PeerMessage::CHOKE:
|
||||
case PeerMessage::UNCHOKE:
|
||||
case PeerMessage::INTERESTED:
|
||||
case PeerMessage::NOT_INTERESTED:
|
||||
break;
|
||||
case PeerMessage::HAVE:
|
||||
checkIndex(message, pieces);
|
||||
break;
|
||||
case PeerMessage::BITFIELD:
|
||||
checkBitfield(message, pieces);
|
||||
break;
|
||||
case PeerMessage::REQUEST:
|
||||
case PeerMessage::CANCEL:
|
||||
checkIndex(message, pieces);
|
||||
checkBegin(message, pieceLength);
|
||||
checkLength(message);
|
||||
checkPieceOffset(message, pieceLength, pieces, totalLength);
|
||||
break;
|
||||
case PeerMessage::PIECE:
|
||||
checkIndex(message, pieces);
|
||||
checkBegin(message, pieceLength);
|
||||
break;
|
||||
default:
|
||||
throw new DlAbortEx("invalid message id. id = %d", message->getId());
|
||||
}
|
||||
}
|
||||
|
||||
HandshakeMessage* PeerMessageUtil::createHandshakeMessage(const char* msg) {
|
||||
HandshakeMessage* PeerMessageUtil::createHandshakeMessage(const char* msg, int length) {
|
||||
HandshakeMessage* message = new HandshakeMessage();
|
||||
message->pstrlen = msg[0];
|
||||
char pstr[20];
|
||||
|
@ -220,6 +192,7 @@ HandshakeMessage* PeerMessageUtil::createHandshakeMessage(const char* msg) {
|
|||
return message;
|
||||
}
|
||||
|
||||
|
||||
void PeerMessageUtil::checkHandshake(const HandshakeMessage* message, const unsigned char* infoHash) {
|
||||
if(message->pstrlen != 19) {
|
||||
throw new DlAbortEx("invalid handshake pstrlen = %d", (int)message->pstrlen);
|
||||
|
@ -234,3 +207,4 @@ void PeerMessageUtil::checkHandshake(const HandshakeMessage* message, const unsi
|
|||
myInfoHash.c_str(), peerInfoHash.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,18 @@
|
|||
#ifndef _D_PEER_MESSAGE_UTIL_H_
|
||||
#define _D_PEER_MESSAGE_UTIL_H_
|
||||
|
||||
#include "ChokeMessage.h"
|
||||
#include "UnchokeMessage.h"
|
||||
#include "InterestedMessage.h"
|
||||
#include "NotInterestedMessage.h"
|
||||
#include "HaveMessage.h"
|
||||
#include "BitfieldMessage.h"
|
||||
#include "RequestMessage.h"
|
||||
#include "CancelMessage.h"
|
||||
#include "PieceMessage.h"
|
||||
#include "HandshakeMessage.h"
|
||||
#include "KeepAliveMessage.h"
|
||||
#include "PortMessage.h"
|
||||
#include "PeerConnection.h"
|
||||
|
||||
#define MAX_BLOCK_LENGTH (128*1024)
|
||||
|
@ -30,23 +42,29 @@ class PeerMessageUtil {
|
|||
private:
|
||||
PeerMessageUtil() {}
|
||||
|
||||
static PeerMessage* createBasicMessage(int id, const char* msg, int len);
|
||||
static PeerMessage* createHaveMessage(int id, const char* msg, int len);
|
||||
static PeerMessage* createBitfieldMessage(int id, const char* msg, int len);
|
||||
static PeerMessage* createRequestCancelMessage(int id, const char* msg, int len);
|
||||
static PeerMessage* createPieceMessage(int id, const char* msg, int len);
|
||||
static int getId(const char* msg);
|
||||
static int getIntParam(const char* msg, int offset);
|
||||
|
||||
static void checkIndex(const PeerMessage* message, int pieces);
|
||||
static void checkBegin(const PeerMessage* message, int pieceLength);
|
||||
static void checkLength(const PeerMessage* message);
|
||||
static void checkPieceOffset(const PeerMessage* message, int pieceLength, int pieces, long long int totalLength);
|
||||
static void checkBitfield(const PeerMessage* message, int pieces);
|
||||
static int getShortIntParam(const char* msg, int offset);
|
||||
public:
|
||||
static PeerMessage* createPeerMessage(const char* msg, int len);
|
||||
static void checkIntegrity(const PeerMessage* message, int pieceLength, int pieces, long long int totalLength);
|
||||
static HandshakeMessage* createHandshakeMessage(const char* msg);
|
||||
static int getId(const char* msg);
|
||||
|
||||
static ChokeMessage* createChokeMessage(const char* msg, int len);
|
||||
static UnchokeMessage* createUnchokeMessage(const char* msg, int len);
|
||||
static InterestedMessage* createInterestedMessage(const char* msg, int len);
|
||||
static NotInterestedMessage* createNotInterestedMessage(const char* msg, int len);
|
||||
static HaveMessage* createHaveMessage(const char* msg, int len);
|
||||
static BitfieldMessage* createBitfieldMessage(const char* msg, int len);
|
||||
static RequestMessage* createRequestMessage(const char* msg, int len);
|
||||
static CancelMessage* createCancelMessage(const char* msg, int len);
|
||||
static PieceMessage* createPieceMessage(const char* msg, int len);
|
||||
static PortMessage* createPortMessage(const char* msg, int len);
|
||||
|
||||
static void checkIndex(int index, int pieces);
|
||||
static void checkBegin(int begin, int pieceLength);
|
||||
static void checkLength(int length);
|
||||
static void checkRange(int begin, int length, int pieceLength);
|
||||
static void checkBitfield(const unsigned char* bitfield, int bitfieldLength, int pieces);
|
||||
|
||||
static HandshakeMessage* createHandshakeMessage(const char* msg, int length);
|
||||
static void checkHandshake(const HandshakeMessage* message, const unsigned char* infoHash);
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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_
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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_
|
|
@ -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_
|
|
@ -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);
|
||||
}
|
|
@ -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_
|
|
@ -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;
|
||||
}
|
|
@ -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_
|
|
@ -31,11 +31,23 @@
|
|||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
SegmentMan::SegmentMan():totalSize(0),isSplittable(true),downloadStarted(false),dir(".") {
|
||||
SegmentMan::SegmentMan():totalSize(0),
|
||||
isSplittable(true),
|
||||
downloadStarted(false),
|
||||
dir("."),
|
||||
splitter(NULL),
|
||||
diskWriter(NULL) {
|
||||
logger = LogFactory::getInstance();
|
||||
}
|
||||
|
||||
SegmentMan::~SegmentMan() {}
|
||||
SegmentMan::~SegmentMan() {
|
||||
if(splitter != NULL) {
|
||||
delete splitter;
|
||||
}
|
||||
if(diskWriter != NULL) {
|
||||
delete diskWriter;
|
||||
}
|
||||
}
|
||||
|
||||
void SegmentMan::unregisterId(int cuid) {
|
||||
for(Segments::iterator itr = segments.begin(); itr != segments.end(); itr++) {
|
||||
|
|
|
@ -21,94 +21,172 @@
|
|||
/* copyright --> */
|
||||
#include "SendMessageQueue.h"
|
||||
#include "LogFactory.h"
|
||||
#include "DlAbortEx.h"
|
||||
#include "KeepAliveMessage.h"
|
||||
#include "PeerMessageUtil.h"
|
||||
#include <netinet/in.h>
|
||||
|
||||
SendMessageQueue::SendMessageQueue(int cuid, PeerConnection* peerConnection,
|
||||
TorrentMan* torrentMan)
|
||||
:cuid(cuid), uploadLimit(0) {
|
||||
requestSlotMan = new RequestSlotMan(cuid, &pendingMessages, peerConnection,
|
||||
torrentMan);
|
||||
SendMessageQueue::SendMessageQueue(int cuid,
|
||||
const Socket* socket,
|
||||
const Option* op,
|
||||
TorrentMan* torrentMan,
|
||||
Peer* peer)
|
||||
:cuid(cuid),
|
||||
uploadLimit(0),
|
||||
torrentMan(torrentMan),
|
||||
peer(peer),
|
||||
piece(Piece::nullPiece) {
|
||||
peerConnection = new PeerConnection(cuid, socket, op, peer, this->torrentMan);
|
||||
logger = LogFactory::getInstance();
|
||||
}
|
||||
|
||||
SendMessageQueue::~SendMessageQueue() {
|
||||
delete requestSlotMan;
|
||||
delete peerConnection;
|
||||
for_each(messageQueue.begin(), messageQueue.end(), Deleter());
|
||||
}
|
||||
|
||||
void SendMessageQueue::send(int uploadSpeed) {
|
||||
int size = pendingMessages.size();
|
||||
int size = messageQueue.size();
|
||||
for(int i = 0; i < size; i++) {
|
||||
PendingMessage msg = pendingMessages.front();
|
||||
pendingMessages.pop_front();
|
||||
if(uploadLimit != 0 && uploadSpeed >= uploadLimit*1024 &&
|
||||
msg.getPeerMessageId() == PeerMessage::PIECE && !msg.isInProgress()) {
|
||||
pendingMessages.push_back(msg);
|
||||
PeerMessage* msg = messageQueue.front();
|
||||
messageQueue.pop_front();
|
||||
if(uploadLimit != 0 && uploadLimit*1024 <= uploadSpeed &&
|
||||
msg->getId() == PieceMessage::ID && !msg->isInProgress()) {
|
||||
messageQueue.push_back(msg);
|
||||
} else {
|
||||
if(!msg.processMessage()) {
|
||||
pendingMessages.push_front(msg);
|
||||
try {
|
||||
msg->send();
|
||||
} catch(Exception* ex) {
|
||||
delete msg;
|
||||
throw;
|
||||
}
|
||||
if(msg->isInProgress()) {
|
||||
messageQueue.push_front(msg);
|
||||
break;
|
||||
} else {
|
||||
delete msg;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SendMessageQueue::addPendingMessage(const PendingMessage& pendingMessage) {
|
||||
pendingMessages.push_back(pendingMessage);
|
||||
if(pendingMessage.getPeerMessageId() == PeerMessage::REQUEST) {
|
||||
RequestSlot requestSlot(pendingMessage.getIndex(),
|
||||
pendingMessage.getBegin(),
|
||||
pendingMessage.getLength(),
|
||||
pendingMessage.getBlockIndex());
|
||||
requestSlotMan->addRequestSlot(requestSlot);
|
||||
void SendMessageQueue::addMessage(PeerMessage* peerMessage) {
|
||||
messageQueue.push_back(peerMessage);
|
||||
if(peerMessage->getId() == RequestMessage::ID) {
|
||||
RequestMessage* requestMessage = (RequestMessage*)peerMessage;
|
||||
RequestSlot requestSlot(requestMessage->getIndex(),
|
||||
requestMessage->getBegin(),
|
||||
requestMessage->getLength(),
|
||||
requestMessage->getBlockIndex());
|
||||
requestSlots.push_back(requestSlot);
|
||||
}
|
||||
}
|
||||
|
||||
void SendMessageQueue::deletePendingPieceMessage(const PeerMessage* cancelMessage) {
|
||||
for(PendingMessages::iterator itr = pendingMessages.begin();
|
||||
itr != pendingMessages.end();) {
|
||||
PendingMessage& pendingMessage = *itr;
|
||||
if(pendingMessage.getPeerMessageId() == PeerMessage::PIECE &&
|
||||
pendingMessage.getIndex() == cancelMessage->getIndex() &&
|
||||
pendingMessage.getBegin() == cancelMessage->getBegin() &&
|
||||
pendingMessage.getLength() == cancelMessage->getLength() &&
|
||||
!pendingMessage.isInProgress()) {
|
||||
logger->debug("CUID#%d - deleting pending piece message because cancel message received. index=%d, begin=%d, length=%d",
|
||||
cuid,
|
||||
pendingMessage.getIndex(),
|
||||
pendingMessage.getBegin(),
|
||||
pendingMessage.getLength());
|
||||
itr = pendingMessages.erase(itr);
|
||||
void SendMessageQueue::deletePieceMessageInQueue(const CancelMessage* cancelMessage) {
|
||||
for(MessageQueue::iterator itr = messageQueue.begin();
|
||||
itr != messageQueue.end();) {
|
||||
if((*itr)->getId() == PieceMessage::ID) {
|
||||
PieceMessage* pieceMessage = (PieceMessage*)*itr;
|
||||
if(pieceMessage->getIndex() == cancelMessage->getIndex() &&
|
||||
pieceMessage->getBegin() == cancelMessage->getBegin() &&
|
||||
pieceMessage->getBlockLength() == cancelMessage->getLength() &&
|
||||
!pieceMessage->isInProgress()) {
|
||||
logger->debug("CUID#%d - deleting piece message in queue because cancel message received. index=%d, begin=%d, length=%d",
|
||||
cuid,
|
||||
cancelMessage->getIndex(),
|
||||
cancelMessage->getBegin(),
|
||||
cancelMessage->getLength());
|
||||
delete pieceMessage;
|
||||
itr = messageQueue.erase(itr);
|
||||
} else {
|
||||
itr++;
|
||||
}
|
||||
} else {
|
||||
itr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SendMessageQueue::deletePendingRequestMessage() {
|
||||
for(PendingMessages::iterator itr = pendingMessages.begin();
|
||||
itr != pendingMessages.end();) {
|
||||
PendingMessage& pendingMessage = *itr;
|
||||
if(pendingMessage.getPeerMessageId() == PeerMessage::REQUEST) {
|
||||
itr = pendingMessages.erase(itr);
|
||||
void SendMessageQueue::deleteRequestMessageInQueue() {
|
||||
for(MessageQueue::iterator itr = messageQueue.begin();
|
||||
itr != messageQueue.end();) {
|
||||
if((*itr)->getId() == RequestMessage::ID) {
|
||||
delete *itr;
|
||||
itr = messageQueue.erase(itr);
|
||||
} else {
|
||||
itr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SendMessageQueue::deleteRequestSlot(const RequestSlot& requestSlot) {
|
||||
requestSlotMan->deleteRequestSlot(requestSlot);
|
||||
// TODO use STL algorithm
|
||||
for(RequestSlots::iterator itr = requestSlots.begin();
|
||||
itr != requestSlots.end(); itr++) {
|
||||
if(*itr == requestSlot) {
|
||||
requestSlots.erase(itr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SendMessageQueue::deleteTimeoutRequestSlot(Piece& piece) {
|
||||
requestSlotMan->deleteTimeoutRequestSlot(piece);
|
||||
void SendMessageQueue::deleteAllRequestSlot(Piece& piece) {
|
||||
if(!Piece::isNull(piece)) {
|
||||
for(RequestSlots::const_iterator itr = requestSlots.begin();
|
||||
itr != requestSlots.end(); itr++) {
|
||||
if(itr->getIndex() == piece.getIndex()) {
|
||||
piece.cancelBlock(itr->getBlockIndex());
|
||||
}
|
||||
}
|
||||
torrentMan->updatePiece(piece);
|
||||
}
|
||||
requestSlots.clear();
|
||||
}
|
||||
|
||||
void SendMessageQueue::deleteCompletedRequestSlot(const Piece& piece) {
|
||||
requestSlotMan->deleteCompletedRequestSlot(piece);
|
||||
void SendMessageQueue::deleteTimeoutRequestSlot() {
|
||||
for(RequestSlots::iterator itr = requestSlots.begin();
|
||||
itr != requestSlots.end();) {
|
||||
if(itr->isTimeout(REQUEST_TIME_OUT)) {
|
||||
logger->debug("CUID#%d - deleting requestslot blockIndex=%d because of time out", cuid,
|
||||
itr->getBlockIndex());
|
||||
if(!Piece::isNull(piece)) {
|
||||
//addMessage(createCancelMessage(itr->getIndex(), itr->getBegin(), itr->getLength()));
|
||||
piece.cancelBlock(itr->getBlockIndex());
|
||||
}
|
||||
itr = requestSlots.erase(itr);
|
||||
} else {
|
||||
itr++;
|
||||
}
|
||||
}
|
||||
torrentMan->updatePiece(piece);
|
||||
}
|
||||
|
||||
RequestSlot SendMessageQueue::getCorrespoindingRequestSlot(const PeerMessage* pieceMessage) const {
|
||||
return requestSlotMan->getCorrespoindingRequestSlot(pieceMessage);
|
||||
void SendMessageQueue::deleteCompletedRequestSlot() {
|
||||
for(RequestSlots::iterator itr = requestSlots.begin();
|
||||
itr != requestSlots.end();) {
|
||||
if(Piece::isNull(piece) || piece.hasBlock(itr->getBlockIndex()) ||
|
||||
torrentMan->hasPiece(piece.getIndex())) {
|
||||
logger->debug("CUID#%d - deleting requestslot blockIndex=%d because the block is already acquired.", cuid,
|
||||
itr->getBlockIndex());
|
||||
addMessage(createCancelMessage(itr->getIndex(), itr->getBegin(), itr->getLength()));
|
||||
itr = requestSlots.erase(itr);
|
||||
} else {
|
||||
itr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RequestSlot SendMessageQueue::getCorrespondingRequestSlot(const PieceMessage* pieceMessage) const {
|
||||
for(RequestSlots::const_iterator itr = requestSlots.begin();
|
||||
itr != requestSlots.end(); itr++) {
|
||||
const RequestSlot& slot = *itr;
|
||||
if(slot.getIndex() == pieceMessage->getIndex() &&
|
||||
slot.getBegin() == pieceMessage->getBegin() &&
|
||||
slot.getLength() == pieceMessage->getBlockLength()) {
|
||||
return slot;
|
||||
}
|
||||
}
|
||||
return RequestSlot::nullSlot;
|
||||
}
|
||||
|
||||
void SendMessageQueue::cancelAllRequest() {
|
||||
|
@ -116,14 +194,274 @@ void SendMessageQueue::cancelAllRequest() {
|
|||
}
|
||||
|
||||
void SendMessageQueue::cancelAllRequest(Piece& piece) {
|
||||
deletePendingRequestMessage();
|
||||
requestSlotMan->deleteAllRequestSlot(piece);
|
||||
deleteRequestMessageInQueue();
|
||||
deleteAllRequestSlot(piece);
|
||||
}
|
||||
|
||||
int SendMessageQueue::countPendingMessage() const {
|
||||
return pendingMessages.size();
|
||||
int SendMessageQueue::countMessageInQueue() const {
|
||||
return messageQueue.size();
|
||||
}
|
||||
|
||||
int SendMessageQueue::countRequestSlot() const {
|
||||
return requestSlotMan->countRequestSlot();
|
||||
return requestSlots.size();
|
||||
}
|
||||
|
||||
HandshakeMessage* SendMessageQueue::receiveHandshake() {
|
||||
char msg[HANDSHAKE_MESSAGE_LENGTH];
|
||||
int msgLength = 0;
|
||||
if(!peerConnection->receiveHandshake(msg, msgLength)) {
|
||||
return NULL;
|
||||
}
|
||||
HandshakeMessage* handshakeMessage = createHandshakeMessage(msg, msgLength);
|
||||
try {
|
||||
handshakeMessage->check();
|
||||
} catch(Exception* e) {
|
||||
delete handshakeMessage;
|
||||
throw;
|
||||
}
|
||||
return handshakeMessage;
|
||||
}
|
||||
|
||||
HandshakeMessage* SendMessageQueue::createHandshakeMessage(const char* msg, int msgLength) {
|
||||
HandshakeMessage* message = PeerMessageUtil::createHandshakeMessage(msg, msgLength);
|
||||
message->setSendMessageQueue(this);
|
||||
return message;
|
||||
}
|
||||
|
||||
PeerMessage* SendMessageQueue::receiveMessage() {
|
||||
char msg[MAX_PAYLOAD_LEN];
|
||||
int msgLength = 0;
|
||||
if(!peerConnection->receiveMessage(msg, msgLength)) {
|
||||
return NULL;
|
||||
}
|
||||
PeerMessage* peerMessage = createPeerMessage(msg, msgLength);
|
||||
try {
|
||||
peerMessage->check();
|
||||
} catch(Exception* e) {
|
||||
delete peerMessage;
|
||||
throw;
|
||||
}
|
||||
return peerMessage;
|
||||
}
|
||||
|
||||
PeerMessage* SendMessageQueue::createPeerMessage(const char* msg, int msgLength) {
|
||||
PeerMessage* peerMessage;
|
||||
if(msgLength == 0) {
|
||||
// keep-alive
|
||||
peerMessage = new KeepAliveMessage();
|
||||
} else {
|
||||
int id = PeerMessageUtil::getId(msg);
|
||||
switch(id) {
|
||||
case ChokeMessage::ID:
|
||||
peerMessage = PeerMessageUtil::createChokeMessage(msg, msgLength);
|
||||
break;
|
||||
case UnchokeMessage::ID:
|
||||
peerMessage = PeerMessageUtil::createUnchokeMessage(msg, msgLength);
|
||||
break;
|
||||
case InterestedMessage::ID:
|
||||
peerMessage = PeerMessageUtil::createInterestedMessage(msg, msgLength);
|
||||
break;
|
||||
case NotInterestedMessage::ID:
|
||||
peerMessage = PeerMessageUtil::createNotInterestedMessage(msg, msgLength);
|
||||
break;
|
||||
case HaveMessage::ID:
|
||||
peerMessage = PeerMessageUtil::createHaveMessage(msg, msgLength);
|
||||
((HaveMessage*)peerMessage)->setPieces(torrentMan->pieces);
|
||||
break;
|
||||
case BitfieldMessage::ID:
|
||||
peerMessage = PeerMessageUtil::createBitfieldMessage(msg, msgLength);
|
||||
((BitfieldMessage*)peerMessage)->setPieces(torrentMan->pieces);
|
||||
break;
|
||||
case RequestMessage::ID:
|
||||
peerMessage = PeerMessageUtil::createRequestMessage(msg, msgLength);
|
||||
((RequestMessage*)peerMessage)->setPieces(torrentMan->pieces);
|
||||
((RequestMessage*)peerMessage)->setPieceLength(torrentMan->getPieceLength(((RequestMessage*)peerMessage)->getIndex()));
|
||||
break;
|
||||
case CancelMessage::ID:
|
||||
peerMessage = PeerMessageUtil::createCancelMessage(msg, msgLength);
|
||||
((CancelMessage*)peerMessage)->setPieces(torrentMan->pieces);
|
||||
((CancelMessage*)peerMessage)->setPieceLength(torrentMan->getPieceLength(((CancelMessage*)peerMessage)->getIndex()));
|
||||
break;
|
||||
case PieceMessage::ID:
|
||||
peerMessage = PeerMessageUtil::createPieceMessage(msg, msgLength);
|
||||
((PieceMessage*)peerMessage)->setPieces(torrentMan->pieces);
|
||||
((PieceMessage*)peerMessage)->setPieceLength(torrentMan->getPieceLength(((PieceMessage*)peerMessage)->getIndex()));
|
||||
break;
|
||||
case PortMessage::ID:
|
||||
peerMessage = PeerMessageUtil::createPortMessage(msg, msgLength);
|
||||
break;
|
||||
default:
|
||||
throw new DlAbortEx("invalid message id. id = %d", id);
|
||||
}
|
||||
}
|
||||
setPeerMessageCommonProperty(peerMessage);
|
||||
return peerMessage;
|
||||
}
|
||||
|
||||
|
||||
void SendMessageQueue::syncPiece() {
|
||||
if(Piece::isNull(piece)) {
|
||||
return;
|
||||
}
|
||||
torrentMan->syncPiece(piece);
|
||||
}
|
||||
|
||||
Piece SendMessageQueue::getNewPieceAndSendInterest() {
|
||||
cancelAllRequest();
|
||||
Piece piece = torrentMan->getMissingPiece(peer);
|
||||
if(Piece::isNull(piece)) {
|
||||
logger->debug("CUID#%d - not interested in the peer", cuid);
|
||||
addMessage(createNotInterestedMessage());
|
||||
} else {
|
||||
logger->debug("CUID#%d - starting download for piece index=%d (%d/%d completed)",
|
||||
cuid, piece.getIndex(), piece.countCompleteBlock(),
|
||||
piece.countBlock());
|
||||
logger->debug("CUID#%d - interested in the peer", cuid);
|
||||
addMessage(createInterestedMessage());
|
||||
}
|
||||
return piece;
|
||||
}
|
||||
|
||||
void SendMessageQueue::sendMessages(int currentUploadSpeed) {
|
||||
if(Piece::isNull(piece)) {
|
||||
// retrive new piece from TorrentMan
|
||||
piece = getNewPieceAndSendInterest();
|
||||
} else if(peer->peerChoking) {
|
||||
cancelAllRequest(piece);
|
||||
torrentMan->cancelPiece(piece);
|
||||
piece = Piece::nullPiece;
|
||||
} else if(piece.pieceComplete()) {
|
||||
piece = getNewPieceAndSendInterest();
|
||||
}
|
||||
if(!Piece::isNull(piece) && !peer->peerChoking) {
|
||||
if(torrentMan->isEndGame()) {
|
||||
BlockIndexes missingBlockIndexes = piece.getAllMissingBlockIndexes();
|
||||
if(countRequestSlot() == 0) {
|
||||
random_shuffle(missingBlockIndexes.begin(), missingBlockIndexes.end());
|
||||
int count = 0;
|
||||
for(BlockIndexes::const_iterator itr = missingBlockIndexes.begin();
|
||||
itr != missingBlockIndexes.end() && count < 6; itr++, count++) {
|
||||
addMessage(createRequestMessage(*itr));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for(int i = countRequestSlot(); i < 6; i++) {
|
||||
int blockIndex = piece.getMissingUnusedBlockIndex();
|
||||
if(blockIndex == -1) {
|
||||
break;
|
||||
}
|
||||
torrentMan->updatePiece(piece);
|
||||
addMessage(createRequestMessage(blockIndex));
|
||||
}
|
||||
}
|
||||
}
|
||||
send(currentUploadSpeed);
|
||||
}
|
||||
|
||||
void SendMessageQueue::sendNow(PeerMessage* peerMessage) {
|
||||
// ignore inProgress state
|
||||
peerMessage->send();
|
||||
delete peerMessage;
|
||||
}
|
||||
|
||||
void SendMessageQueue::trySendNow(PeerMessage* peerMessage) {
|
||||
if(countMessageInQueue() == 0) {
|
||||
sendNow(peerMessage);
|
||||
} else {
|
||||
addMessage(peerMessage);
|
||||
}
|
||||
}
|
||||
|
||||
void SendMessageQueue::sendHandshake() {
|
||||
peerConnection->sendHandshake();
|
||||
}
|
||||
|
||||
void SendMessageQueue::abortPiece() {
|
||||
cancelAllRequest(piece);
|
||||
torrentMan->cancelPiece(piece);
|
||||
}
|
||||
|
||||
Piece& SendMessageQueue::getDownloadPiece() {
|
||||
if(Piece::isNull(piece)) {
|
||||
throw new DlAbortEx("current piece is null");
|
||||
}
|
||||
return piece;
|
||||
}
|
||||
|
||||
void SendMessageQueue::setPeerMessageCommonProperty(PeerMessage* peerMessage) {
|
||||
peerMessage->setPeer(peer);
|
||||
peerMessage->setCuid(cuid);
|
||||
peerMessage->setSendMessageQueue(this);
|
||||
}
|
||||
|
||||
RequestMessage* SendMessageQueue::createRequestMessage(int blockIndex) {
|
||||
RequestMessage* msg = new RequestMessage();
|
||||
setPeerMessageCommonProperty(msg);
|
||||
msg->setIndex(piece.getIndex());
|
||||
msg->setBegin(blockIndex*piece.getBlockLength());
|
||||
msg->setLength(piece.getBlockLength(blockIndex));
|
||||
msg->setBlockIndex(blockIndex);
|
||||
return msg;
|
||||
}
|
||||
|
||||
CancelMessage* SendMessageQueue::createCancelMessage(int index, int begin, int length) {
|
||||
CancelMessage* msg = new CancelMessage();
|
||||
setPeerMessageCommonProperty(msg);
|
||||
msg->setIndex(index);
|
||||
msg->setBegin(begin);
|
||||
msg->setLength(length);
|
||||
return msg;
|
||||
}
|
||||
|
||||
PieceMessage* SendMessageQueue::createPieceMessage(int index, int begin, int length) {
|
||||
PieceMessage* msg = new PieceMessage();
|
||||
setPeerMessageCommonProperty(msg);
|
||||
msg->setIndex(index);
|
||||
msg->setBegin(begin);
|
||||
msg->setBlockLength(length);
|
||||
return msg;
|
||||
}
|
||||
|
||||
HaveMessage* SendMessageQueue::createHaveMessage(int index) {
|
||||
HaveMessage* msg = new HaveMessage();
|
||||
setPeerMessageCommonProperty(msg);
|
||||
msg->setIndex(index);
|
||||
return msg;
|
||||
}
|
||||
|
||||
ChokeMessage* SendMessageQueue::createChokeMessage() {
|
||||
ChokeMessage* msg = new ChokeMessage();
|
||||
setPeerMessageCommonProperty(msg);
|
||||
return msg;
|
||||
}
|
||||
|
||||
UnchokeMessage* SendMessageQueue::createUnchokeMessage() {
|
||||
UnchokeMessage* msg = new UnchokeMessage();
|
||||
setPeerMessageCommonProperty(msg);
|
||||
return msg;
|
||||
}
|
||||
|
||||
InterestedMessage* SendMessageQueue::createInterestedMessage() {
|
||||
InterestedMessage* msg = new InterestedMessage();
|
||||
setPeerMessageCommonProperty(msg);
|
||||
return msg;
|
||||
}
|
||||
|
||||
NotInterestedMessage* SendMessageQueue::createNotInterestedMessage() {
|
||||
NotInterestedMessage* msg = new NotInterestedMessage();
|
||||
setPeerMessageCommonProperty(msg);
|
||||
return msg;
|
||||
}
|
||||
|
||||
BitfieldMessage* SendMessageQueue::createBitfieldMessage() {
|
||||
BitfieldMessage* msg = new BitfieldMessage();
|
||||
setPeerMessageCommonProperty(msg);
|
||||
return msg;
|
||||
}
|
||||
|
||||
KeepAliveMessage* SendMessageQueue::createKeepAliveMessage() {
|
||||
KeepAliveMessage* msg = new KeepAliveMessage();
|
||||
setPeerMessageCommonProperty(msg);
|
||||
return msg;
|
||||
}
|
||||
|
||||
|
|
|
@ -23,40 +23,106 @@
|
|||
#define _D_SEND_MESSAGE_QUEUE_H_
|
||||
|
||||
#include "common.h"
|
||||
#include "RequestSlotMan.h"
|
||||
#include "PeerConnection.h"
|
||||
#include "ChokeMessage.h"
|
||||
#include "UnchokeMessage.h"
|
||||
#include "InterestedMessage.h"
|
||||
#include "NotInterestedMessage.h"
|
||||
#include "HaveMessage.h"
|
||||
#include "BitfieldMessage.h"
|
||||
#include "RequestMessage.h"
|
||||
#include "CancelMessage.h"
|
||||
#include "PieceMessage.h"
|
||||
#include "HandshakeMessage.h"
|
||||
#include "KeepAliveMessage.h"
|
||||
#include "PortMessage.h"
|
||||
#include "RequestSlot.h"
|
||||
|
||||
#define REQUEST_TIME_OUT 120
|
||||
|
||||
typedef deque<RequestSlot> RequestSlots;
|
||||
typedef deque<PeerMessage*> MessageQueue;
|
||||
|
||||
class SendMessageQueue {
|
||||
private:
|
||||
int cuid;
|
||||
RequestSlotMan* requestSlotMan;
|
||||
PendingMessages pendingMessages;
|
||||
const Logger* logger;
|
||||
RequestSlots requestSlots;
|
||||
MessageQueue messageQueue;
|
||||
// upload speed limit(byte/sec)
|
||||
int uploadLimit;
|
||||
public:
|
||||
SendMessageQueue(int cuid, PeerConnection* peerConnection,
|
||||
TorrentMan* torrentMan);
|
||||
~SendMessageQueue();
|
||||
TorrentMan* torrentMan;
|
||||
PeerConnection* peerConnection;
|
||||
Peer* peer;
|
||||
Piece piece;
|
||||
const Logger* logger;
|
||||
|
||||
Piece getNewPieceAndSendInterest();
|
||||
PeerMessage* createPeerMessage(const char* msg, int msgLength);
|
||||
HandshakeMessage* createHandshakeMessage(const char* msg, int msgLength);
|
||||
void send(int uploadSpeed);
|
||||
|
||||
void addPendingMessage(const PendingMessage& pendingMessage);
|
||||
void deletePendingPieceMessage(const PeerMessage* cancelMessage);
|
||||
void deletePendingRequestMessage();
|
||||
|
||||
void deleteRequestSlot(const RequestSlot& requestSlot);
|
||||
void deleteTimeoutRequestSlot(Piece& piece);
|
||||
void deleteCompletedRequestSlot(const Piece& piece);
|
||||
RequestSlot getCorrespoindingRequestSlot(const PeerMessage* pieceMessage) const;
|
||||
|
||||
void setPeerMessageCommonProperty(PeerMessage* peerMessage);
|
||||
void deleteAllRequestSlot(Piece& piece);
|
||||
void deleteRequestMessageInQueue();
|
||||
void cancelAllRequest();
|
||||
void cancelAllRequest(Piece& piece);
|
||||
|
||||
int countPendingMessage() const;
|
||||
int countRequestSlot() const;
|
||||
public:
|
||||
SendMessageQueue(int cuid,
|
||||
const Socket* socket,
|
||||
const Option* op,
|
||||
TorrentMan* torrentMan,
|
||||
Peer* peer);
|
||||
~SendMessageQueue();
|
||||
|
||||
void addMessage(PeerMessage* peerMessage);
|
||||
void deletePieceMessageInQueue(const CancelMessage* cancelMessage);
|
||||
|
||||
void deleteRequestSlot(const RequestSlot& requestSlot);
|
||||
void deleteTimeoutRequestSlot();
|
||||
void deleteCompletedRequestSlot();
|
||||
RequestSlot getCorrespondingRequestSlot(const PieceMessage* pieceMessage) const;
|
||||
|
||||
int countMessageInQueue() const;
|
||||
|
||||
void setUploadLimit(int uploadLimit) { this->uploadLimit = uploadLimit; }
|
||||
int getUploadLimit() const { return this->uploadLimit; }
|
||||
|
||||
TorrentMan* getTorrentMan() const { return torrentMan; }
|
||||
PeerConnection* getPeerConnection() const { return peerConnection; }
|
||||
// If this object has nullPiece, then return false, otherwise true
|
||||
bool hasDownloadPiece() const {
|
||||
return !Piece::isNull(piece);
|
||||
}
|
||||
// If the piece which this object has is nullPiece, then throws an exception.
|
||||
// So before calling this function, call hasDownloadPiece and make sure
|
||||
// this has valid piece, not nullPiece.
|
||||
Piece& getDownloadPiece();
|
||||
void setDownloadPiece(const Piece& piece) {
|
||||
this->piece = piece;
|
||||
}
|
||||
|
||||
void syncPiece();
|
||||
void sendMessages(int currentUploadSpeed);
|
||||
// after sending message, deletes peerMessage.
|
||||
// So don't use peerMessage after this function call.
|
||||
void sendNow(PeerMessage* peerMessage);
|
||||
void trySendNow(PeerMessage* peerMessage);
|
||||
void abortPiece();
|
||||
void sendHandshake();
|
||||
|
||||
PeerMessage* receiveMessage();
|
||||
HandshakeMessage* receiveHandshake();
|
||||
|
||||
RequestMessage* createRequestMessage(int blockIndex);
|
||||
CancelMessage* createCancelMessage(int index, int begin, int length);
|
||||
PieceMessage* createPieceMessage(int index, int begin, int length);
|
||||
HaveMessage* createHaveMessage(int index);
|
||||
ChokeMessage* createChokeMessage();
|
||||
UnchokeMessage* createUnchokeMessage();
|
||||
InterestedMessage* createInterestedMessage();
|
||||
NotInterestedMessage* createNotInterestedMessage();
|
||||
BitfieldMessage* createBitfieldMessage();
|
||||
KeepAliveMessage* createKeepAliveMessage();
|
||||
};
|
||||
|
||||
#endif // _D_SEND_MESSAGE_QUEUE_H_
|
||||
|
|
|
@ -37,11 +37,11 @@ bool SleepCommand::execute() {
|
|||
struct timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
if(Util::difftv(now, checkPoint) >= ((long long int)wait)*1000000) {
|
||||
engine->commands.push(nextCommand);
|
||||
engine->commands.push_back(nextCommand);
|
||||
nextCommand = NULL;
|
||||
return true;
|
||||
} else {
|
||||
engine->commands.push(this);
|
||||
engine->commands.push_back(this);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,6 +32,6 @@ bool TorrentAutoSaveCommand::execute() {
|
|||
}
|
||||
e->torrentMan->save();
|
||||
SleepCommand* sleepCommand = new SleepCommand(cuid, e, this, interval);
|
||||
e->commands.push(sleepCommand);
|
||||
e->commands.push_back(sleepCommand);
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -22,6 +22,15 @@
|
|||
#include "TorrentDownloadEngine.h"
|
||||
#include "Util.h"
|
||||
|
||||
TorrentDownloadEngine::TorrentDownloadEngine():filenameFixed(false),
|
||||
torrentMan(NULL) {}
|
||||
|
||||
TorrentDownloadEngine::~TorrentDownloadEngine() {
|
||||
if(torrentMan != NULL) {
|
||||
delete torrentMan;
|
||||
}
|
||||
}
|
||||
|
||||
void TorrentDownloadEngine::onEndOfRun() {
|
||||
torrentMan->diskAdaptor->closeFile();
|
||||
if(filenameFixed && torrentMan->downloadComplete()) {
|
||||
|
|
|
@ -59,8 +59,8 @@ protected:
|
|||
virtual void onSelectiveDownloadingCompletes() = 0;
|
||||
virtual void sendStatistics() = 0;
|
||||
public:
|
||||
TorrentDownloadEngine():filenameFixed(false) {}
|
||||
virtual ~TorrentDownloadEngine() {}
|
||||
TorrentDownloadEngine();
|
||||
virtual ~TorrentDownloadEngine();
|
||||
|
||||
TorrentMan* torrentMan;
|
||||
|
||||
|
|
|
@ -138,6 +138,11 @@ public:
|
|||
return bitfield->getBitfield();
|
||||
}
|
||||
int getBitfieldLength() const { return bitfield->getBitfieldLength(); }
|
||||
int getPieceLength(int index) const {
|
||||
return bitfield->getBlockLength(index);
|
||||
}
|
||||
int getPieceLength() const { return bitfield->getBlockLength(); }
|
||||
|
||||
void setInfoHash(const unsigned char* infoHash) {
|
||||
memcpy(this->infoHash, infoHash, INFO_HASH_LENGTH);
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ TrackerUpdateCommand::~TrackerUpdateCommand() {}
|
|||
|
||||
bool TrackerUpdateCommand::prepareForRetry() {
|
||||
Command* sleepCommand = new SleepCommand(cuid, e, this, 5);
|
||||
e->commands.push(sleepCommand);
|
||||
e->commands.push_back(sleepCommand);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -153,7 +153,7 @@ bool TrackerUpdateCommand::execute() {
|
|||
int newCuid = e->torrentMan->getNewCuid();
|
||||
peer->cuid = newCuid;
|
||||
PeerInitiateConnectionCommand* command = new PeerInitiateConnectionCommand(newCuid, peer, e);
|
||||
e->commands.push(command);
|
||||
e->commands.push_back(command);
|
||||
logger->debug("adding new command CUID#%d", newCuid);
|
||||
}
|
||||
if(e->torrentMan->req->getTrackerEvent() == Request::STARTED) {
|
||||
|
|
|
@ -76,13 +76,13 @@ bool TrackerWatcherCommand::execute() {
|
|||
}
|
||||
e->torrentMan->req->setUrl(url);
|
||||
Command* command = InitiateConnectionCommandFactory::createInitiateConnectionCommand(e->torrentMan->getNewCuid(), e->torrentMan->req, e);
|
||||
e->commands.push(command);
|
||||
e->commands.push_back(command);
|
||||
e->torrentMan->trackers++;
|
||||
logger->info("CUID#%d - creating new tracker request command #%d", cuid,
|
||||
command->getCuid());
|
||||
}
|
||||
SleepCommand* slpCommand = new SleepCommand(cuid, e, this,
|
||||
e->torrentMan->minInterval);
|
||||
e->commands.push(slpCommand);
|
||||
e->commands.push_back(slpCommand);
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -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";
|
||||
}
|
|
@ -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_
|
13
src/Util.cc
13
src/Util.cc
|
@ -342,3 +342,16 @@ void Util::unfoldRange(const string& src, Integers& range) {
|
|||
sort(range.begin(), range.end());
|
||||
range.erase(unique(range.begin(), range.end()), range.end());
|
||||
}
|
||||
|
||||
string Util::getContentDispositionFilename(const string& header) {
|
||||
string::size_type attributesp = header.find("filename=\"");
|
||||
if(attributesp == string::npos) {
|
||||
return "";
|
||||
}
|
||||
string::size_type filenamesp = attributesp+strlen("filename=\"");
|
||||
string::size_type filenameep = header.find("\"", filenamesp);
|
||||
if(filenameep == string::npos) {
|
||||
return "";
|
||||
}
|
||||
return trim(header.substr(filenamesp, filenameep-filenamesp));
|
||||
}
|
||||
|
|
|
@ -75,6 +75,9 @@ public:
|
|||
static int expandBuffer(char** pbuf, int curLength, int newLength);
|
||||
|
||||
static void unfoldRange(const string& src, Integers& range);
|
||||
|
||||
// this function temporarily put here
|
||||
static string getContentDispositionFilename(const string& header);
|
||||
};
|
||||
|
||||
#endif // _D_UTIL_H_
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <limits.h>
|
||||
#include <string>
|
||||
#include <deque>
|
||||
#include <algorithm>
|
||||
#if ENABLE_NLS
|
||||
# include <gettext.h>
|
||||
# define _(String) gettext (String)
|
||||
|
@ -47,6 +48,14 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
class Deleter {
|
||||
public:
|
||||
template<class T>
|
||||
void operator()(T* ptr) {
|
||||
delete ptr;
|
||||
}
|
||||
};
|
||||
|
||||
typedef deque<string> Strings;
|
||||
typedef deque<int> Integers;
|
||||
|
||||
|
|
50
src/main.cc
50
src/main.cc
|
@ -81,10 +81,6 @@ void setSignalHander(int signal, void (*handler)(int)) {
|
|||
sigaction(signal, &sigact, NULL);
|
||||
}
|
||||
|
||||
void clearRequest(Request* req) {
|
||||
delete(req);
|
||||
}
|
||||
|
||||
DownloadEngine* e;
|
||||
TorrentDownloadEngine* te;
|
||||
|
||||
|
@ -93,6 +89,8 @@ void handler(int signal) {
|
|||
fflush(stdout);
|
||||
e->segmentMan->save();
|
||||
e->segmentMan->diskWriter->closeFile();
|
||||
e->cleanQueue();
|
||||
delete e;
|
||||
printf(_("done\n"));
|
||||
exit(0);
|
||||
}
|
||||
|
@ -108,6 +106,8 @@ void torrentHandler(int signal) {
|
|||
} else {
|
||||
te->torrentMan->save();
|
||||
}
|
||||
te->cleanQueue();
|
||||
delete te;
|
||||
printf(_("done\n"));
|
||||
exit(0);
|
||||
}
|
||||
|
@ -116,7 +116,7 @@ void addCommand(int cuid, const string& url, string referer, Requests& requests)
|
|||
Request* req = new Request();
|
||||
req->setReferer(referer);
|
||||
if(req->setUrl(url)) {
|
||||
e->commands.push(InitiateConnectionCommandFactory::createInitiateConnectionCommand(cuid, req, e));
|
||||
e->commands.push_back(InitiateConnectionCommandFactory::createInitiateConnectionCommand(cuid, req, e));
|
||||
requests.push_back(req);
|
||||
} else {
|
||||
fprintf(stderr, _("Unrecognized URL or unsupported protocol: %s\n"), req->getUrl().c_str());
|
||||
|
@ -596,9 +596,6 @@ int main(int argc, char* argv[]) {
|
|||
exit(1);
|
||||
}
|
||||
|
||||
SegmentSplitter* splitter = new SplitSlowestSegmentSplitter();
|
||||
splitter->setMinSegmentSize(op->getAsLLInt(PREF_MIN_SEGMENT_SIZE));
|
||||
|
||||
setSignalHander(SIGPIPE, SIG_IGN);
|
||||
|
||||
bool readyToTorrentMode = false;
|
||||
|
@ -614,7 +611,9 @@ int main(int argc, char* argv[]) {
|
|||
e->segmentMan->dir = dir;
|
||||
e->segmentMan->ufilename = ufilename;
|
||||
e->segmentMan->option = op;
|
||||
e->segmentMan->splitter = splitter;
|
||||
e->segmentMan->splitter = new SplitSlowestSegmentSplitter();
|
||||
e->segmentMan->splitter->setMinSegmentSize(op->getAsLLInt(PREF_MIN_SEGMENT_SIZE));
|
||||
|
||||
|
||||
Requests requests;
|
||||
int cuidCounter = 1;
|
||||
|
@ -636,12 +635,11 @@ int main(int argc, char* argv[]) {
|
|||
} else {
|
||||
printDownloadAbortMessage();
|
||||
}
|
||||
for_each(requests.begin(), requests.end(), clearRequest);
|
||||
for_each(requests.begin(), requests.end(), Deleter());
|
||||
requests.clear();
|
||||
|
||||
delete(e->segmentMan);
|
||||
delete(e->segmentMan->diskWriter);
|
||||
delete(e);
|
||||
e->cleanQueue();
|
||||
delete e;
|
||||
}
|
||||
if(!torrentFile.empty() || followTorrent && readyToTorrentMode) {
|
||||
try {
|
||||
|
@ -658,7 +656,8 @@ int main(int argc, char* argv[]) {
|
|||
te->segmentMan = new SegmentMan();
|
||||
te->segmentMan->diskWriter = byteArrayDiskWriter;
|
||||
te->segmentMan->option = op;
|
||||
te->segmentMan->splitter = splitter;
|
||||
te->segmentMan->splitter = new SplitSlowestSegmentSplitter();
|
||||
te->segmentMan->splitter->setMinSegmentSize(op->getAsLLInt(PREF_MIN_SEGMENT_SIZE));
|
||||
te->torrentMan = new TorrentMan();
|
||||
te->torrentMan->setStoreDir(dir);
|
||||
te->torrentMan->option = op;
|
||||
|
@ -703,15 +702,15 @@ int main(int argc, char* argv[]) {
|
|||
exit(1);
|
||||
}
|
||||
te->torrentMan->setPort(port);
|
||||
te->commands.push(listenCommand);
|
||||
te->commands.push(new TrackerWatcherCommand(te->torrentMan->getNewCuid(),
|
||||
te->commands.push_back(listenCommand);
|
||||
te->commands.push_back(new TrackerWatcherCommand(te->torrentMan->getNewCuid(),
|
||||
te));
|
||||
te->commands.push(new TrackerUpdateCommand(te->torrentMan->getNewCuid(),
|
||||
te->commands.push_back(new TrackerUpdateCommand(te->torrentMan->getNewCuid(),
|
||||
te));
|
||||
te->commands.push(new TorrentAutoSaveCommand(te->torrentMan->getNewCuid(),
|
||||
te->commands.push_back(new TorrentAutoSaveCommand(te->torrentMan->getNewCuid(),
|
||||
te,
|
||||
op->getAsInt(PREF_AUTO_SAVE_INTERVAL)));
|
||||
te->commands.push(new PeerChokeCommand(te->torrentMan->getNewCuid(),
|
||||
te->commands.push_back(new PeerChokeCommand(te->torrentMan->getNewCuid(),
|
||||
10, te));
|
||||
te->run();
|
||||
|
||||
|
@ -720,20 +719,17 @@ int main(int argc, char* argv[]) {
|
|||
} else {
|
||||
printDownloadAbortMessage();
|
||||
}
|
||||
delete(req);
|
||||
delete(te->segmentMan);
|
||||
delete(te->segmentMan->diskWriter);
|
||||
delete(te->torrentMan);
|
||||
delete(te);
|
||||
delete req;
|
||||
te->cleanQueue();
|
||||
delete te;
|
||||
} catch(Exception* ex) {
|
||||
cerr << ex->getMsg() << endl;
|
||||
delete ex;
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
delete(op);
|
||||
delete(splitter);
|
||||
delete(LogFactory::getInstance());
|
||||
delete op;
|
||||
LogFactory::release();
|
||||
#ifdef HAVE_LIBGNUTLS
|
||||
gnutls_global_deinit();
|
||||
#endif // HAVE_LIBGNUTLS
|
||||
|
|
|
@ -8,7 +8,6 @@ using namespace std;
|
|||
class PeerMessageUtilTest:public CppUnit::TestFixture {
|
||||
|
||||
CPPUNIT_TEST_SUITE(PeerMessageUtilTest);
|
||||
CPPUNIT_TEST(testCreatePeerMessageKeepAlive);
|
||||
CPPUNIT_TEST(testCreatePeerMessageChoke);
|
||||
CPPUNIT_TEST(testCreatePeerMessageUnchoke);
|
||||
CPPUNIT_TEST(testCreatePeerMessageInterested);
|
||||
|
@ -18,6 +17,7 @@ class PeerMessageUtilTest:public CppUnit::TestFixture {
|
|||
CPPUNIT_TEST(testCreatePeerMessageRequest);
|
||||
CPPUNIT_TEST(testCreatePeerMessagePiece);
|
||||
CPPUNIT_TEST(testCreatePeerMessageCancel);
|
||||
CPPUNIT_TEST(testCreatePortMessage);
|
||||
CPPUNIT_TEST(testCheckIntegrityHave);
|
||||
CPPUNIT_TEST(testCheckIntegrityBitfield);
|
||||
CPPUNIT_TEST(testCheckIntegrityRequest);
|
||||
|
@ -28,7 +28,6 @@ public:
|
|||
void setUp() {
|
||||
}
|
||||
|
||||
void testCreatePeerMessageKeepAlive();
|
||||
void testCreatePeerMessageChoke();
|
||||
void testCreatePeerMessageUnchoke();
|
||||
void testCreatePeerMessageInterested();
|
||||
|
@ -38,7 +37,7 @@ public:
|
|||
void testCreatePeerMessageRequest();
|
||||
void testCreatePeerMessagePiece();
|
||||
void testCreatePeerMessageCancel();
|
||||
|
||||
void testCreatePortMessage();
|
||||
void testCheckIntegrityHave();
|
||||
void testCheckIntegrityBitfield();
|
||||
void testCheckIntegrityRequest();
|
||||
|
@ -52,29 +51,27 @@ void setIntParam(char* dest, int param) {
|
|||
memcpy(dest, &nParam, 4);
|
||||
}
|
||||
|
||||
void setShortIntParam(char* dest, int param) {
|
||||
short int nParam = htons(param);
|
||||
memcpy(dest, &nParam, 2);
|
||||
}
|
||||
|
||||
void createNLengthMessage(char* msg, int msgLen, int payloadLen, int id) {
|
||||
memset(msg, 0, msgLen);
|
||||
setIntParam(msg, payloadLen);
|
||||
msg[4] = (char)id;
|
||||
}
|
||||
|
||||
void PeerMessageUtilTest::testCreatePeerMessageKeepAlive() {
|
||||
char msg[4];
|
||||
memset(msg, 0, sizeof(msg));
|
||||
PeerMessage* pm = PeerMessageUtil::createPeerMessage(NULL, 0);
|
||||
CPPUNIT_ASSERT_EQUAL((int)PeerMessage::KEEP_ALIVE, pm->getId());
|
||||
}
|
||||
|
||||
void PeerMessageUtilTest::testCreatePeerMessageChoke() {
|
||||
char msg[5];
|
||||
createNLengthMessage(msg, sizeof(msg), 1, 0);
|
||||
PeerMessage* pm = PeerMessageUtil::createPeerMessage(&msg[4], 1);
|
||||
CPPUNIT_ASSERT_EQUAL((int)PeerMessage::CHOKE, pm->getId());
|
||||
PeerMessage* pm = PeerMessageUtil::createChokeMessage(&msg[4], 1);
|
||||
CPPUNIT_ASSERT_EQUAL((int)ChokeMessage::ID, pm->getId());
|
||||
|
||||
try {
|
||||
char msg[6];
|
||||
createNLengthMessage(msg, sizeof(msg), 2, 0);
|
||||
PeerMessageUtil::createPeerMessage(&msg[4], 2);
|
||||
PeerMessageUtil::createChokeMessage(&msg[4], 2);
|
||||
CPPUNIT_FAIL("exception must be throwed.");
|
||||
} catch(...) {
|
||||
}
|
||||
|
@ -83,13 +80,13 @@ void PeerMessageUtilTest::testCreatePeerMessageChoke() {
|
|||
void PeerMessageUtilTest::testCreatePeerMessageUnchoke() {
|
||||
char msg[5];
|
||||
createNLengthMessage(msg, sizeof(msg), 1, 1);
|
||||
PeerMessage* pm = PeerMessageUtil::createPeerMessage(&msg[4], 1);
|
||||
CPPUNIT_ASSERT_EQUAL((int)PeerMessage::UNCHOKE, pm->getId());
|
||||
PeerMessage* pm = PeerMessageUtil::createUnchokeMessage(&msg[4], 1);
|
||||
CPPUNIT_ASSERT_EQUAL((int)UnchokeMessage::ID, pm->getId());
|
||||
|
||||
try {
|
||||
char msg[6];
|
||||
createNLengthMessage(msg, sizeof(msg), 2, 1);
|
||||
PeerMessageUtil::createPeerMessage(&msg[4], 2);
|
||||
PeerMessageUtil::createUnchokeMessage(&msg[4], 2);
|
||||
CPPUNIT_FAIL("exception must be throwed.");
|
||||
} catch(...) {
|
||||
}
|
||||
|
@ -98,13 +95,13 @@ void PeerMessageUtilTest::testCreatePeerMessageUnchoke() {
|
|||
void PeerMessageUtilTest::testCreatePeerMessageInterested() {
|
||||
char msg[5];
|
||||
createNLengthMessage(msg, sizeof(msg), 1, 2);
|
||||
PeerMessage* pm = PeerMessageUtil::createPeerMessage(&msg[4], 1);
|
||||
CPPUNIT_ASSERT_EQUAL((int)PeerMessage::INTERESTED, pm->getId());
|
||||
PeerMessage* pm = PeerMessageUtil::createInterestedMessage(&msg[4], 1);
|
||||
CPPUNIT_ASSERT_EQUAL((int)InterestedMessage::ID, pm->getId());
|
||||
|
||||
try {
|
||||
char msg[6];
|
||||
createNLengthMessage(msg, sizeof(msg), 2, 2);
|
||||
PeerMessageUtil::createPeerMessage(&msg[4], 2);
|
||||
PeerMessageUtil::createInterestedMessage(&msg[4], 2);
|
||||
CPPUNIT_FAIL("exception must be throwed.");
|
||||
} catch(...) {
|
||||
}
|
||||
|
@ -113,13 +110,13 @@ void PeerMessageUtilTest::testCreatePeerMessageInterested() {
|
|||
void PeerMessageUtilTest::testCreatePeerMessageNotInterested() {
|
||||
char msg[5];
|
||||
createNLengthMessage(msg, sizeof(msg), 1, 3);
|
||||
PeerMessage* pm = PeerMessageUtil::createPeerMessage(&msg[4], 1);
|
||||
CPPUNIT_ASSERT_EQUAL((int)PeerMessage::NOT_INTERESTED, pm->getId());
|
||||
PeerMessage* pm = PeerMessageUtil::createNotInterestedMessage(&msg[4], 1);
|
||||
CPPUNIT_ASSERT_EQUAL((int)NotInterestedMessage::ID, pm->getId());
|
||||
|
||||
try {
|
||||
char msg[6];
|
||||
createNLengthMessage(msg, sizeof(msg), 2, 3);
|
||||
PeerMessageUtil::createPeerMessage(&msg[4], 2);
|
||||
PeerMessageUtil::createNotInterestedMessage(&msg[4], 2);
|
||||
CPPUNIT_FAIL("exception must be throwed.");
|
||||
} catch(...) {
|
||||
}
|
||||
|
@ -129,21 +126,21 @@ void PeerMessageUtilTest::testCreatePeerMessageHave() {
|
|||
char msg[9];
|
||||
createNLengthMessage(msg, sizeof(msg), 5, 4);
|
||||
setIntParam(&msg[5], 100);
|
||||
PeerMessage* pm = PeerMessageUtil::createPeerMessage(&msg[4], 5);
|
||||
CPPUNIT_ASSERT_EQUAL((int)PeerMessage::HAVE, pm->getId());
|
||||
HaveMessage* pm = PeerMessageUtil::createHaveMessage(&msg[4], 5);
|
||||
CPPUNIT_ASSERT_EQUAL((int)HaveMessage::ID, pm->getId());
|
||||
CPPUNIT_ASSERT_EQUAL(100, pm->getIndex());
|
||||
|
||||
try {
|
||||
char msg[8];
|
||||
createNLengthMessage(msg, sizeof(msg), 4, 4);
|
||||
PeerMessageUtil::createPeerMessage(&msg[4], 4);
|
||||
PeerMessageUtil::createHaveMessage(&msg[4], 4);
|
||||
CPPUNIT_FAIL("exception must be throwed.");
|
||||
} catch(...) {}
|
||||
|
||||
try {
|
||||
char msg[5];
|
||||
createNLengthMessage(msg, sizeof(msg), 1, 4);
|
||||
PeerMessageUtil::createPeerMessage(&msg[4], 1);
|
||||
PeerMessageUtil::createHaveMessage(&msg[4], 1);
|
||||
CPPUNIT_FAIL("exception must be throwed.");
|
||||
} catch(...) {}
|
||||
}
|
||||
|
@ -152,8 +149,8 @@ void PeerMessageUtilTest::testCreatePeerMessageBitfield() {
|
|||
int msgLen = 5+2;
|
||||
char* msg = new char[msgLen];
|
||||
createNLengthMessage(msg, msgLen, 3, 5);
|
||||
PeerMessage* pm = PeerMessageUtil::createPeerMessage(&msg[4], 3);
|
||||
CPPUNIT_ASSERT_EQUAL((int)PeerMessage::BITFIELD, pm->getId());
|
||||
BitfieldMessage* pm = PeerMessageUtil::createBitfieldMessage(&msg[4], 3);
|
||||
CPPUNIT_ASSERT_EQUAL((int)BitfieldMessage::ID, pm->getId());
|
||||
CPPUNIT_ASSERT_EQUAL((unsigned char)0, pm->getBitfield()[0]);
|
||||
CPPUNIT_ASSERT_EQUAL((unsigned char)0, pm->getBitfield()[1]);
|
||||
CPPUNIT_ASSERT_EQUAL(2, pm->getBitfieldLength());
|
||||
|
@ -162,7 +159,7 @@ void PeerMessageUtilTest::testCreatePeerMessageBitfield() {
|
|||
int msgLen = 5;
|
||||
char* msg = new char[msgLen];
|
||||
createNLengthMessage(msg, msgLen, 1, 5);
|
||||
PeerMessageUtil::createPeerMessage(&msg[4], 1);
|
||||
PeerMessageUtil::createBitfieldMessage(&msg[4], 1);
|
||||
CPPUNIT_FAIL("exception must be throwed.");
|
||||
} catch(...) {}
|
||||
}
|
||||
|
@ -173,8 +170,8 @@ void PeerMessageUtilTest::testCreatePeerMessageRequest() {
|
|||
setIntParam(&msg[5], 1);
|
||||
setIntParam(&msg[9], 16*1024);
|
||||
setIntParam(&msg[13], 16*1024-1);
|
||||
PeerMessage* pm = PeerMessageUtil::createPeerMessage(&msg[4], 13);
|
||||
CPPUNIT_ASSERT_EQUAL((int)PeerMessage::REQUEST, pm->getId());
|
||||
RequestMessage* pm = PeerMessageUtil::createRequestMessage(&msg[4], 13);
|
||||
CPPUNIT_ASSERT_EQUAL((int)RequestMessage::ID, pm->getId());
|
||||
CPPUNIT_ASSERT_EQUAL(1, pm->getIndex());
|
||||
CPPUNIT_ASSERT_EQUAL(16*1024, pm->getBegin());
|
||||
CPPUNIT_ASSERT_EQUAL(16*1024-1, pm->getLength());
|
||||
|
@ -184,7 +181,7 @@ void PeerMessageUtilTest::testCreatePeerMessageRequest() {
|
|||
createNLengthMessage(msg, sizeof(msg), 9, 6);
|
||||
setIntParam(&msg[5], 1);
|
||||
setIntParam(&msg[9], 16*1024);
|
||||
PeerMessageUtil::createPeerMessage(&msg[4], 9);
|
||||
PeerMessageUtil::createRequestMessage(&msg[4], 9);
|
||||
CPPUNIT_FAIL("exception must be throwed.");
|
||||
} catch(...) {}
|
||||
}
|
||||
|
@ -194,8 +191,8 @@ void PeerMessageUtilTest::testCreatePeerMessagePiece() {
|
|||
createNLengthMessage(msg, sizeof(msg), 9+10, 7);
|
||||
setIntParam(&msg[5], 1);
|
||||
setIntParam(&msg[9], 16*1024);
|
||||
PeerMessage* pm = PeerMessageUtil::createPeerMessage(&msg[4], 19);
|
||||
CPPUNIT_ASSERT_EQUAL((int)PeerMessage::PIECE, pm->getId());
|
||||
PieceMessage* pm = PeerMessageUtil::createPieceMessage(&msg[4], 19);
|
||||
CPPUNIT_ASSERT_EQUAL((int)PieceMessage::ID, pm->getId());
|
||||
CPPUNIT_ASSERT_EQUAL(1, pm->getIndex());
|
||||
CPPUNIT_ASSERT_EQUAL(16*1024, pm->getBegin());
|
||||
CPPUNIT_ASSERT_EQUAL(10, pm->getBlockLength());
|
||||
|
@ -208,7 +205,7 @@ void PeerMessageUtilTest::testCreatePeerMessagePiece() {
|
|||
createNLengthMessage(msg, sizeof(msg), 9, 7);
|
||||
setIntParam(&msg[5], 1);
|
||||
setIntParam(&msg[9], 16*1024);
|
||||
PeerMessageUtil::createPeerMessage(&msg[4], 9);
|
||||
PeerMessageUtil::createPieceMessage(&msg[4], 9);
|
||||
CPPUNIT_FAIL("exception must be throwed.");
|
||||
} catch(...) {}
|
||||
}
|
||||
|
@ -219,8 +216,8 @@ void PeerMessageUtilTest::testCreatePeerMessageCancel() {
|
|||
setIntParam(&msg[5], 1);
|
||||
setIntParam(&msg[9], 16*1024);
|
||||
setIntParam(&msg[13], 16*1024-1);
|
||||
PeerMessage* pm = PeerMessageUtil::createPeerMessage(&msg[4], 13);
|
||||
CPPUNIT_ASSERT_EQUAL((int)PeerMessage::CANCEL, pm->getId());
|
||||
CancelMessage* pm = PeerMessageUtil::createCancelMessage(&msg[4], 13);
|
||||
CPPUNIT_ASSERT_EQUAL((int)CancelMessage::ID, pm->getId());
|
||||
CPPUNIT_ASSERT_EQUAL(1, pm->getIndex());
|
||||
CPPUNIT_ASSERT_EQUAL(16*1024, pm->getBegin());
|
||||
CPPUNIT_ASSERT_EQUAL(16*1024-1, pm->getLength());
|
||||
|
@ -230,17 +227,27 @@ void PeerMessageUtilTest::testCreatePeerMessageCancel() {
|
|||
createNLengthMessage(msg, sizeof(msg), 9, 8);
|
||||
setIntParam(&msg[5], 1);
|
||||
setIntParam(&msg[9], 16*1024);
|
||||
PeerMessageUtil::createPeerMessage(&msg[4], 9);
|
||||
PeerMessageUtil::createCancelMessage(&msg[4], 9);
|
||||
CPPUNIT_FAIL("exception must be throwed.");
|
||||
} catch(...) {}
|
||||
}
|
||||
|
||||
void PeerMessageUtilTest::testCreatePortMessage() {
|
||||
char msg[7];
|
||||
createNLengthMessage(msg, sizeof(msg), 3, 9);
|
||||
setShortIntParam(&msg[5], 65535);
|
||||
PortMessage* pm = PeerMessageUtil::createPortMessage(&msg[4], 3);
|
||||
CPPUNIT_ASSERT_EQUAL((int)PortMessage::ID, pm->getId());
|
||||
CPPUNIT_ASSERT_EQUAL(65535, pm->getPort());
|
||||
}
|
||||
|
||||
void PeerMessageUtilTest::testCheckIntegrityHave() {
|
||||
PeerMessage* pm = new PeerMessage();
|
||||
pm->setId(PeerMessage::HAVE);
|
||||
HaveMessage* pm = new HaveMessage();
|
||||
pm->setIndex(119);
|
||||
pm->setPieces(120);
|
||||
try {
|
||||
PeerMessageUtil::checkIntegrity(pm, 256*1024, 120, 256*1024*120);
|
||||
//PeerMessageUtil::checkIntegrity(pm, 256*1024, 120, 256*1024*120);
|
||||
pm->check();
|
||||
} catch(Exception* ex) {
|
||||
cerr << ex->getMsg() << endl;
|
||||
CPPUNIT_FAIL("");
|
||||
|
@ -248,21 +255,23 @@ void PeerMessageUtilTest::testCheckIntegrityHave() {
|
|||
|
||||
pm->setIndex(120);
|
||||
try {
|
||||
PeerMessageUtil::checkIntegrity(pm, 256*1024, 120, 256*1024*120);
|
||||
//PeerMessageUtil::checkIntegrity(pm, 256*1024, 120, 256*1024*120);
|
||||
pm->check();
|
||||
CPPUNIT_FAIL("exception must be throwed.");
|
||||
} catch(...) {}
|
||||
}
|
||||
|
||||
|
||||
void PeerMessageUtilTest::testCheckIntegrityBitfield() {
|
||||
PeerMessage* pm = new PeerMessage();
|
||||
pm->setId(PeerMessage::BITFIELD);
|
||||
BitfieldMessage* pm = new BitfieldMessage();
|
||||
int bitfieldLength = 15;
|
||||
unsigned char* bitfield = new unsigned char[bitfieldLength];
|
||||
memset(bitfield, 0xff, bitfieldLength);
|
||||
pm->setBitfield(bitfield, bitfieldLength);
|
||||
pm->setPieces(120);
|
||||
try {
|
||||
PeerMessageUtil::checkIntegrity(pm, 256*1024, 120, 256*1024*120);
|
||||
//PeerMessageUtil::checkIntegrity(pm, 256*1024, 120, 256*1024*120);
|
||||
pm->check();
|
||||
} catch(Exception* ex) {
|
||||
cerr << ex->getMsg() << endl;
|
||||
CPPUNIT_FAIL("");
|
||||
|
@ -273,7 +282,8 @@ void PeerMessageUtilTest::testCheckIntegrityBitfield() {
|
|||
memset(bitfield, 0xff, bitfieldLength);
|
||||
pm->setBitfield(bitfield, bitfieldLength);
|
||||
try {
|
||||
PeerMessageUtil::checkIntegrity(pm, 256*1024, 120, 256*1024*120);
|
||||
//PeerMessageUtil::checkIntegrity(pm, 256*1024, 120, 256*1024*120);
|
||||
pm->check();
|
||||
CPPUNIT_FAIL("exception must be throwed.");
|
||||
} catch(Exception* ex) {
|
||||
}
|
||||
|
@ -283,7 +293,8 @@ void PeerMessageUtilTest::testCheckIntegrityBitfield() {
|
|||
memset(bitfield, 0xff, bitfieldLength);
|
||||
pm->setBitfield(bitfield, bitfieldLength);
|
||||
try {
|
||||
PeerMessageUtil::checkIntegrity(pm, 256*1024, 120, 256*1024*120);
|
||||
//PeerMessageUtil::checkIntegrity(pm, 256*1024, 120, 256*1024*120);
|
||||
pm->check();
|
||||
CPPUNIT_FAIL("exception must be throwed.");
|
||||
} catch(Exception* ex) {
|
||||
}
|
||||
|
@ -293,8 +304,10 @@ void PeerMessageUtilTest::testCheckIntegrityBitfield() {
|
|||
memset(bitfield, 0xff, bitfieldLength);
|
||||
bitfield[bitfieldLength-1] &= 0xfe;
|
||||
pm->setBitfield(bitfield, bitfieldLength);
|
||||
pm->setPieces(119);
|
||||
try {
|
||||
PeerMessageUtil::checkIntegrity(pm, 256*1024, 119, 256*1024*120);
|
||||
//PeerMessageUtil::checkIntegrity(pm, 256*1024, 119, 256*1024*120);
|
||||
pm->check();
|
||||
} catch(Exception* ex) {
|
||||
cerr << ex->getMsg() << endl;
|
||||
CPPUNIT_FAIL("");
|
||||
|
@ -305,7 +318,8 @@ void PeerMessageUtilTest::testCheckIntegrityBitfield() {
|
|||
memset(bitfield, 0xff, bitfieldLength);
|
||||
pm->setBitfield(bitfield, bitfieldLength);
|
||||
try {
|
||||
PeerMessageUtil::checkIntegrity(pm, 256*1024, 119, 256*1024*120);
|
||||
//PeerMessageUtil::checkIntegrity(pm, 256*1024, 119, 256*1024*120);
|
||||
pm->check();
|
||||
CPPUNIT_FAIL("exception must be throwed.");
|
||||
} catch(Exception* ex) {
|
||||
}
|
||||
|
@ -313,14 +327,15 @@ void PeerMessageUtilTest::testCheckIntegrityBitfield() {
|
|||
}
|
||||
|
||||
void PeerMessageUtilTest::testCheckIntegrityRequest() {
|
||||
PeerMessage* pm = new PeerMessage();
|
||||
pm->setId(PeerMessage::REQUEST);
|
||||
RequestMessage* pm = new RequestMessage();
|
||||
pm->setIndex(119);
|
||||
pm->setBegin(0);
|
||||
pm->setLength(16*1024);
|
||||
|
||||
pm->setPieces(120);
|
||||
pm->setPieceLength(256*1024);
|
||||
try {
|
||||
PeerMessageUtil::checkIntegrity(pm, 256*1024, 120, 256*1024*120);
|
||||
//PeerMessageUtil::checkIntegrity(pm, 256*1024, 120, 256*1024*120);
|
||||
pm->check();
|
||||
} catch(Exception* ex) {
|
||||
cerr << ex->getMsg() << endl;
|
||||
CPPUNIT_FAIL("");
|
||||
|
@ -329,21 +344,24 @@ void PeerMessageUtilTest::testCheckIntegrityRequest() {
|
|||
pm->setBegin(256*1024);
|
||||
pm->setLength(16*1024);
|
||||
try {
|
||||
PeerMessageUtil::checkIntegrity(pm, 256*1024, 120, 256*1024*120);
|
||||
//PeerMessageUtil::checkIntegrity(pm, 256*1024, 120, 256*1024*120);
|
||||
pm->check();
|
||||
CPPUNIT_FAIL("exception must be throwed.");
|
||||
} catch(Exception* ex) {}
|
||||
|
||||
pm->setBegin(0);
|
||||
pm->setLength(256*1024);
|
||||
try {
|
||||
PeerMessageUtil::checkIntegrity(pm, 256*1024, 120, 256*1024*120);
|
||||
//PeerMessageUtil::checkIntegrity(pm, 256*1024, 120, 256*1024*120);
|
||||
pm->check();
|
||||
CPPUNIT_FAIL("exception must be throwed.");
|
||||
} catch(Exception* ex) {}
|
||||
|
||||
pm->setBegin(0);
|
||||
pm->setLength(5);
|
||||
try {
|
||||
PeerMessageUtil::checkIntegrity(pm, 256*1024, 120, 256*1024*120);
|
||||
//PeerMessageUtil::checkIntegrity(pm, 256*1024, 120, 256*1024*120);
|
||||
pm->check();
|
||||
CPPUNIT_FAIL("exception must be throwed.");
|
||||
} catch(Exception* ex) {}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,8 @@ class UtilTest:public CppUnit::TestFixture {
|
|||
CPPUNIT_TEST(testEndsWith);
|
||||
CPPUNIT_TEST(testReplace);
|
||||
CPPUNIT_TEST(testStartsWith);
|
||||
// may be moved to other helper class in the future.
|
||||
CPPUNIT_TEST(testGetContentDispositionFilename);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
private:
|
||||
|
||||
|
@ -26,6 +28,8 @@ public:
|
|||
void testEndsWith();
|
||||
void testReplace();
|
||||
void testStartsWith();
|
||||
// may be moved to other helper class in the future.
|
||||
void testGetContentDispositionFilename();
|
||||
};
|
||||
|
||||
|
||||
|
@ -157,3 +161,17 @@ void UtilTest::testStartsWith() {
|
|||
CPPUNIT_ASSERT(Util::startsWith(target, part));
|
||||
|
||||
}
|
||||
|
||||
void UtilTest::testGetContentDispositionFilename() {
|
||||
string h1 = "attachment; filename=\"aria2.tar.bz2\"";
|
||||
CPPUNIT_ASSERT_EQUAL(string("aria2.tar.bz2"), Util::getContentDispositionFilename(h1));
|
||||
|
||||
string h2 = "attachment; filename=\"\"";
|
||||
CPPUNIT_ASSERT_EQUAL(string(""), Util::getContentDispositionFilename(h2));
|
||||
|
||||
string h3 = "attachment; filename=\"";
|
||||
CPPUNIT_ASSERT_EQUAL(string(""), Util::getContentDispositionFilename(h3));
|
||||
|
||||
string h4 = "attachment;";
|
||||
CPPUNIT_ASSERT_EQUAL(string(""), Util::getContentDispositionFilename(h4));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue