mirror of https://github.com/aria2/aria2
2006-05-18 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
To remove a wait from download loop: * src/DownloadEngine.cc (run): Comment out shortSleep. To rewrite the message handling: * src/CancelMessage.h: Derived from SimplePeerMessage. (msg): New variable. (create): New function. (send): Removed. (getMessage): New function. (getMessageLength): New function. * src/CancelMessage.cc (create): New function. (receivedAction): Replaced deleteRequestMessageInQueue with rejectPieceMessageInQueue. (send): Removed. (getMessage): New function. (getMessageLength): New function. * src/BitfieldMessage.h: Derived from SimplePeerMessage. (msg): New variable. (msgLength): New variable. (~BitfieldMessage): Deleted msg. (send): Removed. (getMessage): New function. (getMessageLength): New function. * src/BitfieldMessage.cc (create): New function. (send): Removed. (getMessage): New function. (getMessageLength): New function. * src/ChokeMessage.h: Derived from SimplePeerMessage. (msg): New variable. (sendPredicate): New function. (onSendComplete): New function. (send): Removed. (getMessage): New function. (getMessageLength): New function. (create): New function. * src/ChokeMessage.cc (create): New function. (send): Removed. (sendPredicate): New function. (getMessage): New function. (getMessageLength): New function. (onSendComplete): New function. * src/KeepAliveMessage.h: Derived from SimplePeerMessage. (msg): New variable. (send): Removed. (getMessage): New function. (getMessageLength): New function. * src/KeepAliveMessage.cc (send): Removed. (getMessage): New function. (getMessageLength): New function. * src/PortMessage.h (create): New function. (receivedAction): Updated log message. * src/PortMessage.cc: New file. * src/UnchokeMessage.h: Derived from SimplePeerMessage. (msg): New variable. (sendPredicate): New function. (onSendComplete): New function. (create): New function. (send): Removed. (getMessage): New function. (getMessageLength): New function. * src/UnchokeMessage.cc (create): New function. (send): Removed. (sendPredicate): New function. (getMessage): New function. (getMessageLength): New function. (onSendComplete): New function. * src/PieceMessage.h (leftPieceDataLength): Removed. (leftDataLength): New variable. (headerSend): New variable. (pendingCount): New variable. (msgHeader): New variable. (sendPieceData): New function. (incrementPendingCount): New function. (isPendingCountMax): New function. (create): New function. (getMessageHeader): New function. (getMessageHeaderLength): New function. * src/PieceMessage.cc (create): New function. (getMessageHeader): New function. (getMessageHeaderLength): New function. (send): Rewritten. (sendPieceData): New function. * src/HaveMessage.h: Derived from SimplePeerMessage. (msg): New variable. (create): New function. (getMessage): New function. (getMessageLength): New function. * src/HaveMessage.cc (create): New function. (send): Removed. (sendPieceData): New function. (getMessage): New function. (getMessageLength): New function. * src/RequestMessage.h: Derived from SimplePeerMessage. (msg): New variable. (create): New function. (send): Removed. (getMessage): New function. (getMessageLength): New function. * src/RequestMessage.cc (create): New function. (receivedAction): Added the handling of fast extension. Deleted torrentMan->addUploadLength, torrentMan->addDeltaUploadLength. (send): Removed. (getMessage): New function. (getMessageLength): New function. * src/InterestedMessage.h: Derived from SimplePeerMessage. (msg): New variable. (sendPredicate): New function. (onSendComplete): New function. (create): New function. (getMessage): New function. (getMessageLength): New function. * src/InterestedMessage.cc (create): New function. (send): Removed. (sendPieceData): New function. (getMessage): New function. (getMessageLength): New function. (onSendComplete): New function. * src/NotInterestedMessage.h: Derived from SimplePeerMessage. (msg): New variable. (sendPieceData): New function. (onSendComplete): New function. (create): New function. (send): Removed. (getMessage): New function. (getMessageLength): New function. * src/NotInterestedMessage.cc (create): New function. (send): Removed. (sendPredicate): New function. (getMessage): New function. (getMessageLength): New function. (onSendComplete): New function. * src/AllowedFastMessage.h: New class. * src/AllowedFastMessage.cc: New class. * src/RejectMessage.h: New class. * src/RejectMessage.cc: New class. * src/SuggestPieceMessage.h: New class. * src/SuggestPieceMessage.cc: New class. * src/HaveAllMessage.h: New class. * src/HaveAllMessage.cc: New class. * src/HaveNoneMessage.h: New class. * src/HaveNoneMessage.cc: New class. * src/HandshakeMessage.h: Derived from SimplePeerMessage. (msg): New variable. (reserved): New variable. (create): New function. (getId): New function. (receivedAction): New function. (getMessage): New function. (getMessageLength): New function. (isFastExtensionSupported): New function. * src/HandshakeMessage.cc (HandshakeMessage): Moved here from HandshakeMessage.h. (create): New function. (getMessage): New function. (getMessageLength): New function. (toString): Added the output of reserved field. (check): Added const qualifier. (isFastExtensionSupported): New function. * src/PeerMessageUtil.h (createChokeMessage): Removed. (createUnchokeMessage): Removed. (createInterestedMessage): Removed. (createNotInterestedMessage): Removed. (createHaveMessage): Removed. (createBitfieldMessage): Removed. (createRequestMessage): Removed. (createCancelMessage): Removed. (createPieceMessage): Removed. (createPortMessage): Removed. (createChokeMessage): Removed. (createUnchokeMessage): Removed. (createInterestedMessage): Removed. (createNotInterestedMessage): Removed. (createHaveMessage): Removed. (createBitfieldMessage): Removed. (createRequestMessage): Removed. (createCancelMessage): Removed. (createPieceMessage): Removed. (createKeepAliveMessage): Removed. (createHandshakeMessage): Removed. (setIntParam): New function. (createPeerMessageString): New function. * src/PeerMessageUtil.cc (createChokeMessage): Removed. (createUnchokeMessage): Removed. (createInterestedMessage): Removed. (createNotInterestedMessage): Removed. (createHaveMessage): Removed. (createBitfieldMessage): Removed. (createRequestMessage): Removed. (createCancelMessage): Removed. (createPieceMessage): Removed. (createPortMessage): Removed. (createRequestMessage): Removed. (createCancelMessage): Removed. (createPieceMessage): Removed. (createHaveMessage): Removed. (createChokeMessage): Removed. (createUnchokeMessage): Removed. (createInterestedMessage): Removed. (createNotInterestedMessage): Removed. (createBitfieldMessage): Removed. (createKeepAliveMessage): Removed. (createHandshakeMessage): Removed. (setIntParam): New function. (createPeerMessageString): New function. * src/PeerConnection.h (peer): Removed. (torrentMan): Removed. (createNLengthMessage): Removed. (setIntParam): Removed. (writeOutgoingMessageLog): Removed all overloaded functions. (PeerConnection): Deleted peer and torrentMan from its arguments. (sendMessage): New function. (sendHandshake): Removed. (sendKeepAlive): Removed. (sendChoke): Removed. (sendUnchoke): Removed. (sendInterested): Removed. (sendNotInterested): Removed. (sendHave): Removed. (sendBitfield): Removed. (sendRequest): Removed. (sendPiece): Removed. (sendPieceHeader): Removed. (sendPieceData): Removed. (sendCancel): Removed. (getPeer): Removed. * src/PeerConnection.cc (PeerConnection): Deleted peer and torrentMan from its arguments. (sendHandshake): Removed. (sendKeepAlive): Removed. (createNLengthMessage): Removed. (setIntParam): Removed. (writeOutgoingMessageLog): Removed all overloaded functions. (sendChoke): Removed. (sendUnchoke): Removed. (sendInterested): Removed. (sendNotInterested): Removed. (sendHave): Removed. (sendBitfield): Removed. (sendRequest): Removed. (sendPiece): Removed. (sendPieceHeader): Removed. (sendPieceData): Removed. (sendMessage): New function. (sendCancel): Removed. * src/PeerInteractionCommand.cc (PeerInteractionCommand): Call setUploadLimit. (executeInternal): Call setUploadLimit. Added the handling of "inProgress" state of handshake message. Call sendBitfield() or sendAllowdFast() instead of deprecated sendNow(). (keepAlive): Call addMessage and sendMessage instead of deprecated sendNow(). (beforeSocketCheck): Call addMessage instead of deprecated trySendNow() * src/TorrentMan.h (PEER_ID_LENGTH): New definition. (hasAllPieces): New function. * src/TorrentMan.cc (getMissingPiece): Added the handling of fast extension. (cancelPiece): Call updatePiece(). (hasAllPieces): New function. * src/PeerInteraction.h (fastSet): New variable. (getNewPieceAndSendInterest): Changed the return type to void. (send): Renamed as sendMessages. (deleteAllRequestSlot): Removed. (deleteRequestMessageInQueue): Renamed as rejectPieceMessageInQueue. (cancelAllRequest): Removed all overloaded functions. (deleteAllRequestSlot): Removed. (deletePieceMessageInQueue): Renamed as rejectAllPieceMessageInQueue. (rejectPieceMessageInQueue): New function. (rejectAllPieceMessageInQueue): New function. (onChoked): New function. (isSendingMessageInProgress): New function. (getCorrespondingRequestSlot): Changed its arguments. (isInFastSet): New function. (addFastSetIndex): New function. (addRequests): New function. (sendNow): Removed. (trySendNow): Removed. (sendBitfield): New function. (sendAllowdFast): New function. (createHaveAllMessage): New function. (createHaveNoneMessage): New function. (createRejectMessage): New function. (createAllowedFastMessage): New function. * src/PeerInteraction.cc (send): Renamed as sendMessages. (sendMessages): New function. (MsgPushBack): New class. (isSendingMessageInProgress): New function. (deletePieceMessageInQueue): Renamed as rejectAllPieceMessageInQueue. (rejectAllPieceMessageInQueue): New function. Added the handling of fast extension. (deleteRequestMessageInQueue): Renamed as rejectPieceMessageInQueue. (rejectPieceMessageInQueue): New function. Added the handling of fast extension. (deleteRequestSlot): Replaced for loop with std::find. (onChoked): New function. (deleteAllRequestSlot): Removed. (abortPiece): Rewirtten. (deleteTimeoutRequestSlot): Updated log messages. (getCorrespondingRequestSlot): Changed its arguments. (cancelAllRequest): Removed all overloaded functions. (receiveHandshake): Added the check to see whether an incoming peer supports fast extension. (createHandshakeMessage): Use HandshakeMessage::create instead of PeerMessageUtil. (createPeerMessage): Use create() of each message class instead of PeerMessageUtil. HaveAllMessage, HaveNoneMessage, RejectMessage, SuggestPieceMessage, AllowedFastMessage were added. (getNewPieceAndSendInterest): Changed its return value type to void. Added the handling of fast extension. (addRequests): New function. (sendNow): Removed. (sendHandshake): Rewritten. (trySendNow): Removed. (sendBitfield): New function. (sendAllowdFast): New function. (isInFastSet): New function. (addFastSetIndex): New function. (createRequestMessage): Use RequestMessage::create instead of PeerMessageUtil. (createCancelMessage): Use CancelMessage::create instead of PeerMessageUtil. (createPieceMessage): Use PieceMessage::create instead of PeerMessageUtil. (createHaveMessage): Use HaveMessage::create instead of PeerMessageUtil. (createChokeMessage): Use ChokeMessage::create instead of PeerMessageUtil. (createUnchokeMessage): Use UnchokeMessage::create instead of PeerMessageUtil. (createInterestedMessage): Use InterestedMessage::create instead of PeerMessageUtil. (createNotInterestedMessage): Use NotInterestedMessage::create instead of PeerMessageUtil. (createBitfieldMessage): Use BitfieldMessage::create instead of PeerMessageUtil. (createKeepAliveMessage): Use KeepAliveMessage::create instead of PeerMessageUtil. (createHaveAllMessage): New function. (createHaveNoneMessage): New function. (createRejectMessage): New function. (createAllowedFastMessage: New function. * src/Util.h (sha1Sum): New function. (computeFastSet): New function. * src/Util.cc (sha1Sum): New function. (computeFastSet): New function. * src/Peer.h (fastExtensionEnabled): New variable. (fastSet): New variable. (setAllBitfield): New function. (setFastExtensionEnabled): New function. (isFastExtensionEnabled): New function. (addFastSetIndex): New function. (getFastSet): New function. (isInFastSet): New function. (countFastSet): New function. * src/Peer.cc (isInFastSet): New function. (addFastSetIndex): New function. (setAllBitfield): New function. * src/AbstractCommand.cc (execute): Changed the procedure of checking sockets. * src/PeerAbstractCommand.cc (PeerAbstractCommand): Added the initialization for uploadLimitCheck and uploadLimit. (execute): Changed the procedure of checking sockets. The upload speed checking were added. (setUploadLimit): New function. (setUploadLimitCheck): New function. * src/PeerAbstractCommand.h (setUploadLimit): New function. (setUploadLimitCheck): New function. (uploadLimit): New variable. (uploadLimitCheck): New variable. To contact a tracker regularly: * src/TrackerWatcherCommand.h (interval): New variable. (checkPoint): New variable. (TrackerWatcherCommand): Added interval argument. * src/TrackerWatcherCommand.cc (TrackerWatcherCommand): Initialized checkPoint. (execute): Now a tracker is contacted in every specified period. If peer list is not needed, send request with numwant=0. * src/TrackerUpdateCommand.cc (execute): Updated log messages. * src/DownloadEngine.cc (~DownloadEngine): Removed two asserts. (waitData): Uncommented wfds. May be a bug fix.pull/1/head
parent
bd5d11da3c
commit
d018b3a609
418
ChangeLog
418
ChangeLog
|
@ -1,3 +1,421 @@
|
|||
2006-05-18 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
||||
|
||||
To remove a wait from download loop:
|
||||
|
||||
* src/DownloadEngine.cc
|
||||
(run): Comment out shortSleep.
|
||||
|
||||
To rewrite the message handling:
|
||||
|
||||
* src/CancelMessage.h: Derived from SimplePeerMessage.
|
||||
(msg): New variable.
|
||||
(create): New function.
|
||||
(send): Removed.
|
||||
(getMessage): New function.
|
||||
(getMessageLength): New function.
|
||||
* src/CancelMessage.cc
|
||||
(create): New function.
|
||||
(receivedAction): Replaced deleteRequestMessageInQueue with
|
||||
rejectPieceMessageInQueue.
|
||||
(send): Removed.
|
||||
(getMessage): New function.
|
||||
(getMessageLength): New function.
|
||||
* src/BitfieldMessage.h: Derived from SimplePeerMessage.
|
||||
(msg): New variable.
|
||||
(msgLength): New variable.
|
||||
(~BitfieldMessage): Deleted msg.
|
||||
(send): Removed.
|
||||
(getMessage): New function.
|
||||
(getMessageLength): New function.
|
||||
* src/BitfieldMessage.cc
|
||||
(create): New function.
|
||||
(send): Removed.
|
||||
(getMessage): New function.
|
||||
(getMessageLength): New function.
|
||||
* src/ChokeMessage.h: Derived from SimplePeerMessage.
|
||||
(msg): New variable.
|
||||
(sendPredicate): New function.
|
||||
(onSendComplete): New function.
|
||||
(send): Removed.
|
||||
(getMessage): New function.
|
||||
(getMessageLength): New function.
|
||||
(create): New function.
|
||||
* src/ChokeMessage.cc
|
||||
(create): New function.
|
||||
(send): Removed.
|
||||
(sendPredicate): New function.
|
||||
(getMessage): New function.
|
||||
(getMessageLength): New function.
|
||||
(onSendComplete): New function.
|
||||
* src/KeepAliveMessage.h: Derived from SimplePeerMessage.
|
||||
(msg): New variable.
|
||||
(send): Removed.
|
||||
(getMessage): New function.
|
||||
(getMessageLength): New function.
|
||||
* src/KeepAliveMessage.cc
|
||||
(send): Removed.
|
||||
(getMessage): New function.
|
||||
(getMessageLength): New function.
|
||||
* src/PortMessage.h
|
||||
(create): New function.
|
||||
(receivedAction): Updated log message.
|
||||
* src/PortMessage.cc: New file.
|
||||
* src/UnchokeMessage.h: Derived from SimplePeerMessage.
|
||||
(msg): New variable.
|
||||
(sendPredicate): New function.
|
||||
(onSendComplete): New function.
|
||||
(create): New function.
|
||||
(send): Removed.
|
||||
(getMessage): New function.
|
||||
(getMessageLength): New function.
|
||||
* src/UnchokeMessage.cc
|
||||
(create): New function.
|
||||
(send): Removed.
|
||||
(sendPredicate): New function.
|
||||
(getMessage): New function.
|
||||
(getMessageLength): New function.
|
||||
(onSendComplete): New function.
|
||||
* src/PieceMessage.h
|
||||
(leftPieceDataLength): Removed.
|
||||
(leftDataLength): New variable.
|
||||
(headerSend): New variable.
|
||||
(pendingCount): New variable.
|
||||
(msgHeader): New variable.
|
||||
(sendPieceData): New function.
|
||||
(incrementPendingCount): New function.
|
||||
(isPendingCountMax): New function.
|
||||
(create): New function.
|
||||
(getMessageHeader): New function.
|
||||
(getMessageHeaderLength): New function.
|
||||
* src/PieceMessage.cc
|
||||
(create): New function.
|
||||
(getMessageHeader): New function.
|
||||
(getMessageHeaderLength): New function.
|
||||
(send): Rewritten.
|
||||
(sendPieceData): New function.
|
||||
* src/HaveMessage.h: Derived from SimplePeerMessage.
|
||||
(msg): New variable.
|
||||
(create): New function.
|
||||
(getMessage): New function.
|
||||
(getMessageLength): New function.
|
||||
* src/HaveMessage.cc
|
||||
(create): New function.
|
||||
(send): Removed.
|
||||
(sendPieceData): New function.
|
||||
(getMessage): New function.
|
||||
(getMessageLength): New function.
|
||||
* src/RequestMessage.h: Derived from SimplePeerMessage.
|
||||
(msg): New variable.
|
||||
(create): New function.
|
||||
(send): Removed.
|
||||
(getMessage): New function.
|
||||
(getMessageLength): New function.
|
||||
* src/RequestMessage.cc
|
||||
(create): New function.
|
||||
(receivedAction): Added the handling of fast extension.
|
||||
Deleted torrentMan->addUploadLength, torrentMan->addDeltaUploadLength.
|
||||
(send): Removed.
|
||||
(getMessage): New function.
|
||||
(getMessageLength): New function.
|
||||
* src/InterestedMessage.h: Derived from SimplePeerMessage.
|
||||
(msg): New variable.
|
||||
(sendPredicate): New function.
|
||||
(onSendComplete): New function.
|
||||
(create): New function.
|
||||
(getMessage): New function.
|
||||
(getMessageLength): New function.
|
||||
* src/InterestedMessage.cc
|
||||
(create): New function.
|
||||
(send): Removed.
|
||||
(sendPieceData): New function.
|
||||
(getMessage): New function.
|
||||
(getMessageLength): New function.
|
||||
(onSendComplete): New function.
|
||||
* src/NotInterestedMessage.h: Derived from SimplePeerMessage.
|
||||
(msg): New variable.
|
||||
(sendPieceData): New function.
|
||||
(onSendComplete): New function.
|
||||
(create): New function.
|
||||
(send): Removed.
|
||||
(getMessage): New function.
|
||||
(getMessageLength): New function.
|
||||
* src/NotInterestedMessage.cc
|
||||
(create): New function.
|
||||
(send): Removed.
|
||||
(sendPredicate): New function.
|
||||
(getMessage): New function.
|
||||
(getMessageLength): New function.
|
||||
(onSendComplete): New function.
|
||||
* src/AllowedFastMessage.h: New class.
|
||||
* src/AllowedFastMessage.cc: New class.
|
||||
* src/RejectMessage.h: New class.
|
||||
* src/RejectMessage.cc: New class.
|
||||
* src/SuggestPieceMessage.h: New class.
|
||||
* src/SuggestPieceMessage.cc: New class.
|
||||
* src/HaveAllMessage.h: New class.
|
||||
* src/HaveAllMessage.cc: New class.
|
||||
* src/HaveNoneMessage.h: New class.
|
||||
* src/HaveNoneMessage.cc: New class.
|
||||
* src/HandshakeMessage.h: Derived from SimplePeerMessage.
|
||||
(msg): New variable.
|
||||
(reserved): New variable.
|
||||
(create): New function.
|
||||
(getId): New function.
|
||||
(receivedAction): New function.
|
||||
(getMessage): New function.
|
||||
(getMessageLength): New function.
|
||||
(isFastExtensionSupported): New function.
|
||||
* src/HandshakeMessage.cc
|
||||
(HandshakeMessage): Moved here from HandshakeMessage.h.
|
||||
(create): New function.
|
||||
(getMessage): New function.
|
||||
(getMessageLength): New function.
|
||||
(toString): Added the output of reserved field.
|
||||
(check): Added const qualifier.
|
||||
(isFastExtensionSupported): New function.
|
||||
* src/PeerMessageUtil.h
|
||||
(createChokeMessage): Removed.
|
||||
(createUnchokeMessage): Removed.
|
||||
(createInterestedMessage): Removed.
|
||||
(createNotInterestedMessage): Removed.
|
||||
(createHaveMessage): Removed.
|
||||
(createBitfieldMessage): Removed.
|
||||
(createRequestMessage): Removed.
|
||||
(createCancelMessage): Removed.
|
||||
(createPieceMessage): Removed.
|
||||
(createPortMessage): Removed.
|
||||
(createChokeMessage): Removed.
|
||||
(createUnchokeMessage): Removed.
|
||||
(createInterestedMessage): Removed.
|
||||
(createNotInterestedMessage): Removed.
|
||||
(createHaveMessage): Removed.
|
||||
(createBitfieldMessage): Removed.
|
||||
(createRequestMessage): Removed.
|
||||
(createCancelMessage): Removed.
|
||||
(createPieceMessage): Removed.
|
||||
(createKeepAliveMessage): Removed.
|
||||
(createHandshakeMessage): Removed.
|
||||
(setIntParam): New function.
|
||||
(createPeerMessageString): New function.
|
||||
* src/PeerMessageUtil.cc
|
||||
(createChokeMessage): Removed.
|
||||
(createUnchokeMessage): Removed.
|
||||
(createInterestedMessage): Removed.
|
||||
(createNotInterestedMessage): Removed.
|
||||
(createHaveMessage): Removed.
|
||||
(createBitfieldMessage): Removed.
|
||||
(createRequestMessage): Removed.
|
||||
(createCancelMessage): Removed.
|
||||
(createPieceMessage): Removed.
|
||||
(createPortMessage): Removed.
|
||||
(createRequestMessage): Removed.
|
||||
(createCancelMessage): Removed.
|
||||
(createPieceMessage): Removed.
|
||||
(createHaveMessage): Removed.
|
||||
(createChokeMessage): Removed.
|
||||
(createUnchokeMessage): Removed.
|
||||
(createInterestedMessage): Removed.
|
||||
(createNotInterestedMessage): Removed.
|
||||
(createBitfieldMessage): Removed.
|
||||
(createKeepAliveMessage): Removed.
|
||||
(createHandshakeMessage): Removed.
|
||||
(setIntParam): New function.
|
||||
(createPeerMessageString): New function.
|
||||
* src/PeerConnection.h
|
||||
(peer): Removed.
|
||||
(torrentMan): Removed.
|
||||
(createNLengthMessage): Removed.
|
||||
(setIntParam): Removed.
|
||||
(writeOutgoingMessageLog): Removed all overloaded functions.
|
||||
(PeerConnection): Deleted peer and torrentMan from its arguments.
|
||||
(sendMessage): New function.
|
||||
(sendHandshake): Removed.
|
||||
(sendKeepAlive): Removed.
|
||||
(sendChoke): Removed.
|
||||
(sendUnchoke): Removed.
|
||||
(sendInterested): Removed.
|
||||
(sendNotInterested): Removed.
|
||||
(sendHave): Removed.
|
||||
(sendBitfield): Removed.
|
||||
(sendRequest): Removed.
|
||||
(sendPiece): Removed.
|
||||
(sendPieceHeader): Removed.
|
||||
(sendPieceData): Removed.
|
||||
(sendCancel): Removed.
|
||||
(getPeer): Removed.
|
||||
* src/PeerConnection.cc
|
||||
(PeerConnection): Deleted peer and torrentMan from its arguments.
|
||||
(sendHandshake): Removed.
|
||||
(sendKeepAlive): Removed.
|
||||
(createNLengthMessage): Removed.
|
||||
(setIntParam): Removed.
|
||||
(writeOutgoingMessageLog): Removed all overloaded functions.
|
||||
(sendChoke): Removed.
|
||||
(sendUnchoke): Removed.
|
||||
(sendInterested): Removed.
|
||||
(sendNotInterested): Removed.
|
||||
(sendHave): Removed.
|
||||
(sendBitfield): Removed.
|
||||
(sendRequest): Removed.
|
||||
(sendPiece): Removed.
|
||||
(sendPieceHeader): Removed.
|
||||
(sendPieceData): Removed.
|
||||
(sendMessage): New function.
|
||||
(sendCancel): Removed.
|
||||
* src/PeerInteractionCommand.cc
|
||||
(PeerInteractionCommand): Call setUploadLimit.
|
||||
(executeInternal): Call setUploadLimit.
|
||||
Added the handling of "inProgress" state of handshake message.
|
||||
Call sendBitfield() or sendAllowdFast() instead of deprecated
|
||||
sendNow().
|
||||
(keepAlive): Call addMessage and sendMessage instead of deprecated
|
||||
sendNow().
|
||||
(beforeSocketCheck): Call addMessage instead of deprecated trySendNow()
|
||||
* src/TorrentMan.h
|
||||
(PEER_ID_LENGTH): New definition.
|
||||
(hasAllPieces): New function.
|
||||
* src/TorrentMan.cc
|
||||
(getMissingPiece): Added the handling of fast extension.
|
||||
(cancelPiece): Call updatePiece().
|
||||
(hasAllPieces): New function.
|
||||
* src/PeerInteraction.h
|
||||
(fastSet): New variable.
|
||||
(getNewPieceAndSendInterest): Changed the return type to void.
|
||||
(send): Renamed as sendMessages.
|
||||
(deleteAllRequestSlot): Removed.
|
||||
(deleteRequestMessageInQueue): Renamed as rejectPieceMessageInQueue.
|
||||
(cancelAllRequest): Removed all overloaded functions.
|
||||
(deleteAllRequestSlot): Removed.
|
||||
(deletePieceMessageInQueue): Renamed as rejectAllPieceMessageInQueue.
|
||||
(rejectPieceMessageInQueue): New function.
|
||||
(rejectAllPieceMessageInQueue): New function.
|
||||
(onChoked): New function.
|
||||
(isSendingMessageInProgress): New function.
|
||||
(getCorrespondingRequestSlot): Changed its arguments.
|
||||
(isInFastSet): New function.
|
||||
(addFastSetIndex): New function.
|
||||
(addRequests): New function.
|
||||
(sendNow): Removed.
|
||||
(trySendNow): Removed.
|
||||
(sendBitfield): New function.
|
||||
(sendAllowdFast): New function.
|
||||
(createHaveAllMessage): New function.
|
||||
(createHaveNoneMessage): New function.
|
||||
(createRejectMessage): New function.
|
||||
(createAllowedFastMessage): New function.
|
||||
* src/PeerInteraction.cc
|
||||
(send): Renamed as sendMessages.
|
||||
(sendMessages): New function.
|
||||
(MsgPushBack): New class.
|
||||
(isSendingMessageInProgress): New function.
|
||||
(deletePieceMessageInQueue): Renamed as rejectAllPieceMessageInQueue.
|
||||
(rejectAllPieceMessageInQueue): New function.
|
||||
Added the handling of fast extension.
|
||||
(deleteRequestMessageInQueue): Renamed as rejectPieceMessageInQueue.
|
||||
(rejectPieceMessageInQueue): New function.
|
||||
Added the handling of fast extension.
|
||||
(deleteRequestSlot): Replaced for loop with std::find.
|
||||
(onChoked): New function.
|
||||
(deleteAllRequestSlot): Removed.
|
||||
(abortPiece): Rewirtten.
|
||||
(deleteTimeoutRequestSlot): Updated log messages.
|
||||
(getCorrespondingRequestSlot): Changed its arguments.
|
||||
(cancelAllRequest): Removed all overloaded functions.
|
||||
(receiveHandshake): Added the check to see whether an incoming peer
|
||||
supports fast extension.
|
||||
(createHandshakeMessage): Use HandshakeMessage::create instead of
|
||||
PeerMessageUtil.
|
||||
(createPeerMessage): Use create() of each message class instead of
|
||||
PeerMessageUtil.
|
||||
HaveAllMessage, HaveNoneMessage, RejectMessage, SuggestPieceMessage,
|
||||
AllowedFastMessage were added.
|
||||
(getNewPieceAndSendInterest): Changed its return value type to void.
|
||||
Added the handling of fast extension.
|
||||
(addRequests): New function.
|
||||
(sendNow): Removed.
|
||||
(sendHandshake): Rewritten.
|
||||
(trySendNow): Removed.
|
||||
(sendBitfield): New function.
|
||||
(sendAllowdFast): New function.
|
||||
(isInFastSet): New function.
|
||||
(addFastSetIndex): New function.
|
||||
(createRequestMessage): Use RequestMessage::create instead of
|
||||
PeerMessageUtil.
|
||||
(createCancelMessage): Use CancelMessage::create instead of
|
||||
PeerMessageUtil.
|
||||
(createPieceMessage): Use PieceMessage::create instead of
|
||||
PeerMessageUtil.
|
||||
(createHaveMessage): Use HaveMessage::create instead of
|
||||
PeerMessageUtil.
|
||||
(createChokeMessage): Use ChokeMessage::create instead of
|
||||
PeerMessageUtil.
|
||||
(createUnchokeMessage): Use UnchokeMessage::create instead of
|
||||
PeerMessageUtil.
|
||||
(createInterestedMessage): Use InterestedMessage::create instead of
|
||||
PeerMessageUtil.
|
||||
(createNotInterestedMessage): Use NotInterestedMessage::create instead
|
||||
of PeerMessageUtil.
|
||||
(createBitfieldMessage): Use BitfieldMessage::create instead of
|
||||
PeerMessageUtil.
|
||||
(createKeepAliveMessage): Use KeepAliveMessage::create instead of
|
||||
PeerMessageUtil.
|
||||
(createHaveAllMessage): New function.
|
||||
(createHaveNoneMessage): New function.
|
||||
(createRejectMessage): New function.
|
||||
(createAllowedFastMessage: New function.
|
||||
* src/Util.h
|
||||
(sha1Sum): New function.
|
||||
(computeFastSet): New function.
|
||||
* src/Util.cc
|
||||
(sha1Sum): New function.
|
||||
(computeFastSet): New function.
|
||||
* src/Peer.h
|
||||
(fastExtensionEnabled): New variable.
|
||||
(fastSet): New variable.
|
||||
(setAllBitfield): New function.
|
||||
(setFastExtensionEnabled): New function.
|
||||
(isFastExtensionEnabled): New function.
|
||||
(addFastSetIndex): New function.
|
||||
(getFastSet): New function.
|
||||
(isInFastSet): New function.
|
||||
(countFastSet): New function.
|
||||
* src/Peer.cc
|
||||
(isInFastSet): New function.
|
||||
(addFastSetIndex): New function.
|
||||
(setAllBitfield): New function.
|
||||
|
||||
* src/AbstractCommand.cc (execute): Changed the procedure of checking
|
||||
sockets.
|
||||
* src/PeerAbstractCommand.cc
|
||||
(PeerAbstractCommand): Added the initialization for uploadLimitCheck
|
||||
and uploadLimit.
|
||||
(execute): Changed the procedure of checking sockets. The upload speed
|
||||
checking were added.
|
||||
(setUploadLimit): New function.
|
||||
(setUploadLimitCheck): New function.
|
||||
* src/PeerAbstractCommand.h
|
||||
(setUploadLimit): New function.
|
||||
(setUploadLimitCheck): New function.
|
||||
(uploadLimit): New variable.
|
||||
(uploadLimitCheck): New variable.
|
||||
|
||||
To contact a tracker regularly:
|
||||
|
||||
* src/TrackerWatcherCommand.h (interval): New variable.
|
||||
(checkPoint): New variable.
|
||||
(TrackerWatcherCommand): Added interval argument.
|
||||
* src/TrackerWatcherCommand.cc
|
||||
(TrackerWatcherCommand): Initialized checkPoint.
|
||||
(execute): Now a tracker is contacted in every specified period.
|
||||
If peer list is not needed, send request with numwant=0.
|
||||
|
||||
* src/TrackerUpdateCommand.cc
|
||||
(execute): Updated log messages.
|
||||
|
||||
* src/DownloadEngine.cc
|
||||
(~DownloadEngine): Removed two asserts.
|
||||
(waitData): Uncommented wfds. May be a bug fix.
|
||||
|
||||
2006-05-10 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
||||
|
||||
* src/PeerInteractionCommand.h
|
||||
|
|
5
TODO
5
TODO
|
@ -14,5 +14,6 @@
|
|||
* Add Mainline-compatible DHT support
|
||||
* Add Message stream encryption support
|
||||
* Add announce-list support
|
||||
* Add fast extension
|
||||
* Refacturing HttpConnection and FtpConnection
|
||||
* Refacturing HttpConnection and FtpConnection
|
||||
* HTTP/FTP downloading regression test
|
||||
* Fast extension test
|
|
@ -72,25 +72,28 @@ bool AbstractCommand::isTimeoutDetected() {
|
|||
|
||||
bool AbstractCommand::execute() {
|
||||
try {
|
||||
if(checkSocketIsReadable && !readCheckTarget->isReadable(0)
|
||||
|| checkSocketIsWritable && !writeCheckTarget->isWritable(0)) {
|
||||
if(checkSocketIsReadable && readCheckTarget->isReadable(0) ||
|
||||
checkSocketIsWritable && writeCheckTarget->isWritable(0) ||
|
||||
!checkSocketIsReadable && !checkSocketIsWritable) {
|
||||
|
||||
updateCheckPoint();
|
||||
Segment seg = { 0, 0, 0, false };
|
||||
if(e->segmentMan->downloadStarted) {
|
||||
// get segment information in order to set Range header.
|
||||
if(!e->segmentMan->getSegment(seg, cuid)) {
|
||||
// no segment available
|
||||
logger->info(MSG_NO_SEGMENT_AVAILABLE, cuid);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return executeInternal(seg);
|
||||
} else {
|
||||
if(isTimeoutDetected()) {
|
||||
throw new DlRetryEx(EX_TIME_OUT);
|
||||
}
|
||||
e->commands.push_back(this);
|
||||
return false;
|
||||
}
|
||||
updateCheckPoint();
|
||||
Segment seg = { 0, 0, 0, false };
|
||||
if(e->segmentMan->downloadStarted) {
|
||||
// get segment information in order to set Range header.
|
||||
if(!e->segmentMan->getSegment(seg, cuid)) {
|
||||
// no segment available
|
||||
logger->info(MSG_NO_SEGMENT_AVAILABLE, cuid);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return executeInternal(seg);
|
||||
} catch(DlAbortEx* err) {
|
||||
logger->error(MSG_DOWNLOAD_ABORTED, err, cuid);
|
||||
onAbort(err);
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
/* <!-- 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 "AllowedFastMessage.h"
|
||||
#include "PeerInteraction.h"
|
||||
#include "PeerMessageUtil.h"
|
||||
#include "Util.h"
|
||||
#include "DlAbortEx.h"
|
||||
|
||||
AllowedFastMessage* AllowedFastMessage::create(const char* data, int dataLength) {
|
||||
if(dataLength != 5) {
|
||||
throw new DlAbortEx("invalid payload size for %s, size = %d. It should be %d", "allowed fast", dataLength, 5);
|
||||
}
|
||||
int id = PeerMessageUtil::getId(data);
|
||||
if(id != ID) {
|
||||
throw new DlAbortEx("invalid ID=%d for %s. It should be %d.",
|
||||
id, "allowed fast", ID);
|
||||
}
|
||||
AllowedFastMessage* allowedFastMessage = new AllowedFastMessage();
|
||||
allowedFastMessage->setIndex(PeerMessageUtil::getIntParam(data, 1));
|
||||
return allowedFastMessage;
|
||||
}
|
||||
|
||||
void AllowedFastMessage::receivedAction() {
|
||||
if(!peer->isFastExtensionEnabled()) {
|
||||
throw new DlAbortEx("%s received while fast extension is disabled",
|
||||
toString().c_str());
|
||||
}
|
||||
peer->addFastSetIndex(index);
|
||||
}
|
||||
|
||||
const char* AllowedFastMessage::getMessage() {
|
||||
if(!inProgress) {
|
||||
/**
|
||||
* len --- 5, 4bytes
|
||||
* id --- 17, 1byte
|
||||
* piece index --- index, 4bytes
|
||||
* total: 9bytes
|
||||
*/
|
||||
PeerMessageUtil::createPeerMessageString(msg, sizeof(msg), 5, ID);
|
||||
PeerMessageUtil::setIntParam(&msg[5], index);
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
int AllowedFastMessage::getMessageLength() {
|
||||
return sizeof(msg);
|
||||
}
|
||||
|
||||
void AllowedFastMessage::onSendComplete() {
|
||||
peerInteraction->addFastSetIndex(index);
|
||||
}
|
||||
|
||||
void AllowedFastMessage::check() const {
|
||||
PeerMessageUtil::checkIndex(index, pieces);
|
||||
}
|
||||
|
||||
string AllowedFastMessage::toString() const {
|
||||
return "allowed fast index="+Util::itos(index);
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
/* <!-- 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_ALLOWED_FAST_MESSAGE_H_
|
||||
#define _D_ALLOWED_FAST_MESSAGE_H_
|
||||
|
||||
#include "SimplePeerMessage.h"
|
||||
|
||||
class AllowedFastMessage : public SimplePeerMessage {
|
||||
private:
|
||||
int index;
|
||||
// for check
|
||||
int pieces;
|
||||
char msg[9];
|
||||
protected:
|
||||
virtual void onSendComplete();
|
||||
public:
|
||||
AllowedFastMessage():SimplePeerMessage(), index(0), pieces(0) {}
|
||||
|
||||
virtual ~AllowedFastMessage() {}
|
||||
|
||||
enum ID {
|
||||
ID = 17
|
||||
};
|
||||
|
||||
void setIndex(int index) {
|
||||
this->index = index;
|
||||
}
|
||||
int getIndex() const { return index; }
|
||||
|
||||
void setPieces(int pieces) {
|
||||
this->pieces = pieces;
|
||||
}
|
||||
int getPieces() const { return pieces;}
|
||||
|
||||
static AllowedFastMessage* create(const char* data, int dataLength);
|
||||
|
||||
virtual int getId() const { return ID; }
|
||||
virtual void receivedAction();
|
||||
virtual const char* getMessage();
|
||||
virtual int getMessageLength();
|
||||
virtual void check() const;
|
||||
virtual string toString() const;
|
||||
};
|
||||
|
||||
#endif // _D_ALLOWED_FAST_MESSAGE_H_
|
|
@ -23,6 +23,7 @@
|
|||
#include "PeerInteraction.h"
|
||||
#include "PeerMessageUtil.h"
|
||||
#include "Util.h"
|
||||
#include "DlAbortEx.h"
|
||||
|
||||
void BitfieldMessage::setBitfield(const unsigned char* bitfield, int bitfieldLength) {
|
||||
if(this->bitfield != NULL) {
|
||||
|
@ -33,12 +34,44 @@ void BitfieldMessage::setBitfield(const unsigned char* bitfield, int bitfieldLen
|
|||
memcpy(this->bitfield, bitfield, this->bitfieldLength);
|
||||
}
|
||||
|
||||
BitfieldMessage* BitfieldMessage::create(const char* data, int dataLength) {
|
||||
if(dataLength <= 1) {
|
||||
throw new DlAbortEx("invalid payload size for %s, size = %d. It should be greater than %d", "bitfield", dataLength, 1);
|
||||
}
|
||||
int id = PeerMessageUtil::getId(data);
|
||||
if(id != ID) {
|
||||
throw new DlAbortEx("invalid ID=%d for %s. It should be %d.",
|
||||
id, "bitfield", ID);
|
||||
}
|
||||
BitfieldMessage* bitfieldMessage = new BitfieldMessage();
|
||||
bitfieldMessage->setBitfield((unsigned char*)data+1, dataLength-1);
|
||||
return bitfieldMessage;
|
||||
}
|
||||
|
||||
void BitfieldMessage::receivedAction() {
|
||||
peer->setBitfield(bitfield, bitfieldLength);
|
||||
}
|
||||
|
||||
void BitfieldMessage::send() {
|
||||
peerInteraction->getPeerConnection()->sendBitfield();
|
||||
const char* BitfieldMessage::getMessage() {
|
||||
if(!inProgress && msg == NULL) {
|
||||
/**
|
||||
* len --- 1+bitfieldLength, 4bytes
|
||||
* id --- 5, 1byte
|
||||
* bitfield --- bitfield, len bytes
|
||||
* total: 5+len bytes
|
||||
*/
|
||||
msgLength = 5+bitfieldLength;
|
||||
msg = new char[msgLength];
|
||||
PeerMessageUtil::createPeerMessageString(msg, msgLength,
|
||||
1+bitfieldLength, ID);
|
||||
memcpy(msg+5, bitfield, bitfieldLength);
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
int BitfieldMessage::getMessageLength() {
|
||||
getMessage();
|
||||
return msgLength;
|
||||
}
|
||||
|
||||
void BitfieldMessage::check() const {
|
||||
|
|
|
@ -22,23 +22,29 @@
|
|||
#ifndef _D_BITFIELD_MESSAGE_H_
|
||||
#define _D_BITFIELD_MESSAGE_H_
|
||||
|
||||
#include "PeerMessage.h"
|
||||
#include "SimplePeerMessage.h"
|
||||
|
||||
class BitfieldMessage : public PeerMessage {
|
||||
class BitfieldMessage : public SimplePeerMessage {
|
||||
private:
|
||||
unsigned char* bitfield;
|
||||
int bitfieldLength;
|
||||
// for check
|
||||
int pieces;
|
||||
|
||||
char* msg;
|
||||
int msgLength;
|
||||
public:
|
||||
BitfieldMessage():PeerMessage(),
|
||||
BitfieldMessage():SimplePeerMessage(),
|
||||
bitfield(NULL), bitfieldLength(0),
|
||||
pieces(0) {}
|
||||
pieces(0), msg(NULL), msgLength(0) {}
|
||||
|
||||
virtual ~BitfieldMessage() {
|
||||
if(bitfield != NULL) {
|
||||
delete [] bitfield;
|
||||
}
|
||||
if(msg != NULL) {
|
||||
delete [] msg;
|
||||
}
|
||||
}
|
||||
|
||||
enum ID {
|
||||
|
@ -55,9 +61,12 @@ public:
|
|||
}
|
||||
int getPieces() const { return pieces;}
|
||||
|
||||
static BitfieldMessage* create(const char* data, int dataLength);
|
||||
|
||||
virtual int getId() const { return ID; }
|
||||
virtual void receivedAction();
|
||||
virtual void send();
|
||||
virtual const char* getMessage();
|
||||
virtual int getMessageLength();
|
||||
virtual void check() const;
|
||||
virtual string toString() const;
|
||||
};
|
||||
|
|
|
@ -23,13 +23,48 @@
|
|||
#include "PeerInteraction.h"
|
||||
#include "PeerMessageUtil.h"
|
||||
#include "Util.h"
|
||||
#include "DlAbortEx.h"
|
||||
|
||||
void CancelMessage::receivedAction() {
|
||||
peerInteraction->deletePieceMessageInQueue(this);
|
||||
CancelMessage* CancelMessage::create(const char* data, int dataLength) {
|
||||
if(dataLength != 13) {
|
||||
throw new DlAbortEx("invalid payload size for %s, size = %d. It should be %d", "cancel", dataLength, 13);
|
||||
}
|
||||
int id = PeerMessageUtil::getId(data);
|
||||
if(id != ID) {
|
||||
throw new DlAbortEx("invalid ID=%d for %s. It should be %d.",
|
||||
id, "cancel", ID);
|
||||
}
|
||||
CancelMessage* cancelMessage = new CancelMessage();
|
||||
cancelMessage->setIndex(PeerMessageUtil::getIntParam(data, 1));
|
||||
cancelMessage->setBegin(PeerMessageUtil::getIntParam(data, 5));
|
||||
cancelMessage->setLength(PeerMessageUtil::getIntParam(data, 9));
|
||||
return cancelMessage;
|
||||
}
|
||||
|
||||
void CancelMessage::send() {
|
||||
peerInteraction->getPeerConnection()->sendCancel(index, begin, length);
|
||||
void CancelMessage::receivedAction() {
|
||||
peerInteraction->rejectPieceMessageInQueue(index, begin, length);
|
||||
}
|
||||
|
||||
const char* CancelMessage::getMessage() {
|
||||
if(!inProgress) {
|
||||
/**
|
||||
* len --- 13, 4bytes
|
||||
* id --- 8, 1byte
|
||||
* index --- index, 4bytes
|
||||
* begin --- begin, 4bytes
|
||||
* length -- length, 4bytes
|
||||
* total: 17bytes
|
||||
*/
|
||||
PeerMessageUtil::createPeerMessageString(msg, sizeof(msg), 13, ID);
|
||||
PeerMessageUtil::setIntParam(&msg[5], index);
|
||||
PeerMessageUtil::setIntParam(&msg[9], begin);
|
||||
PeerMessageUtil::setIntParam(&msg[13], length);
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
int CancelMessage::getMessageLength() {
|
||||
return sizeof(msg);
|
||||
}
|
||||
|
||||
void CancelMessage::check() const {
|
||||
|
|
|
@ -22,12 +22,10 @@
|
|||
#ifndef _D_CANCEL_MESSAGE_H_
|
||||
#define _D_CANCEL_MESSAGE_H_
|
||||
|
||||
#include "PeerMessage.h"
|
||||
#include "SimplePeerMessage.h"
|
||||
#include "TorrentMan.h"
|
||||
|
||||
class SendMessageQueue;
|
||||
|
||||
class CancelMessage : public PeerMessage {
|
||||
class CancelMessage : public SimplePeerMessage {
|
||||
private:
|
||||
int index;
|
||||
int begin;
|
||||
|
@ -35,8 +33,10 @@ private:
|
|||
// for check
|
||||
int pieces;
|
||||
int pieceLength;
|
||||
|
||||
char msg[17];
|
||||
public:
|
||||
CancelMessage():PeerMessage(),
|
||||
CancelMessage():SimplePeerMessage(),
|
||||
index(0), begin(0), length(0),
|
||||
pieces(0), pieceLength(0) {}
|
||||
|
||||
|
@ -63,9 +63,12 @@ public:
|
|||
}
|
||||
int getPieceLength() const { return pieceLength;}
|
||||
|
||||
static CancelMessage* create(const char* data, int dataLength);
|
||||
|
||||
virtual int getId() const { return ID; }
|
||||
virtual void receivedAction();
|
||||
virtual void send();
|
||||
virtual const char* getMessage();
|
||||
virtual int getMessageLength();
|
||||
virtual void check() const;
|
||||
virtual string toString() const;
|
||||
};
|
||||
|
|
|
@ -21,16 +21,51 @@
|
|||
/* copyright --> */
|
||||
#include "ChokeMessage.h"
|
||||
#include "PeerInteraction.h"
|
||||
#include "message.h"
|
||||
#include "PeerMessageUtil.h"
|
||||
#include "DlAbortEx.h"
|
||||
|
||||
ChokeMessage* ChokeMessage::create(const char* data, int dataLength) {
|
||||
if(dataLength != 1) {
|
||||
throw new DlAbortEx("invalid payload size for %s, size = %d. It should be %d", "choke", dataLength, 1);
|
||||
}
|
||||
int id = PeerMessageUtil::getId(data);
|
||||
if(id != ID) {
|
||||
throw new DlAbortEx("invalid ID=%d for %s. It should be %d.",
|
||||
id, "choke", ID);
|
||||
}
|
||||
ChokeMessage* chokeMessage = new ChokeMessage();
|
||||
return chokeMessage;
|
||||
}
|
||||
|
||||
void ChokeMessage::receivedAction() {
|
||||
peer->peerChoking = true;
|
||||
peerInteraction->onChoked();
|
||||
}
|
||||
|
||||
void ChokeMessage::send() {
|
||||
if(!peer->amChoking) {
|
||||
peerInteraction->getPeerConnection()->sendChoke();
|
||||
peer->amChoking = true;
|
||||
bool ChokeMessage::sendPredicate() const {
|
||||
return !peer->amChoking;
|
||||
}
|
||||
|
||||
const char* ChokeMessage::getMessage() {
|
||||
if(!inProgress) {
|
||||
/**
|
||||
* len --- 1, 4bytes
|
||||
* id --- 0, 1byte
|
||||
* total: 5bytes
|
||||
*/
|
||||
PeerMessageUtil::createPeerMessageString(msg, sizeof(msg), 1, ID);
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
int ChokeMessage::getMessageLength() {
|
||||
return sizeof(msg);
|
||||
}
|
||||
|
||||
void ChokeMessage::onSendComplete() {
|
||||
peer->amChoking = true;
|
||||
peerInteraction->rejectAllPieceMessageInQueue();
|
||||
}
|
||||
|
||||
string ChokeMessage::toString() const {
|
||||
|
|
|
@ -22,11 +22,16 @@
|
|||
#ifndef _D_CHOKE_MESSAGE_H_
|
||||
#define _D_CHOKE_MESSAGE_H_
|
||||
|
||||
#include "PeerMessage.h"
|
||||
#include "SimplePeerMessage.h"
|
||||
|
||||
class ChokeMessage : public PeerMessage {
|
||||
class ChokeMessage : public SimplePeerMessage {
|
||||
private:
|
||||
char msg[5];
|
||||
protected:
|
||||
virtual bool sendPredicate() const;
|
||||
virtual void onSendComplete();
|
||||
public:
|
||||
ChokeMessage():PeerMessage() {}
|
||||
ChokeMessage():SimplePeerMessage() {}
|
||||
virtual ~ChokeMessage() {}
|
||||
|
||||
enum ID {
|
||||
|
@ -35,9 +40,11 @@ public:
|
|||
|
||||
virtual int getId() const { return ID; }
|
||||
virtual void receivedAction();
|
||||
virtual void send();
|
||||
virtual const char* getMessage();
|
||||
virtual int getMessageLength();
|
||||
virtual string toString() const;
|
||||
|
||||
static ChokeMessage* create(const char* data, int dataLength);
|
||||
};
|
||||
|
||||
#endif // _D_CHOKE_MESSAGE_H_
|
||||
|
|
|
@ -35,8 +35,6 @@ DownloadEngine::DownloadEngine():noWait(false), segmentMan(NULL) {
|
|||
}
|
||||
|
||||
DownloadEngine::~DownloadEngine() {
|
||||
assert(rsockets.empty());
|
||||
assert(wsockets.empty());
|
||||
if(segmentMan != NULL) {
|
||||
delete segmentMan;
|
||||
}
|
||||
|
@ -59,7 +57,7 @@ void DownloadEngine::run() {
|
|||
}
|
||||
}
|
||||
afterEachIteration();
|
||||
shortSleep();
|
||||
//shortSleep();
|
||||
if(!noWait && !commands.empty()) {
|
||||
waitData();
|
||||
}
|
||||
|
@ -102,7 +100,7 @@ void DownloadEngine::waitData() {
|
|||
tv.tv_sec = 1;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
retval = select(max+1, &rfds, /*&wfds*/NULL, NULL, &tv);
|
||||
retval = select(max+1, &rfds, &wfds, NULL, &tv);
|
||||
}
|
||||
|
||||
bool DownloadEngine::addSocket(Sockets& sockets, Socket* socket) {
|
||||
|
|
|
@ -24,16 +24,53 @@
|
|||
#include "PeerMessageUtil.h"
|
||||
#include "Util.h"
|
||||
|
||||
void HandshakeMessage::setPeerInteraction(PeerInteraction* peerInteraction) {
|
||||
this->peerInteraction = peerInteraction;
|
||||
HandshakeMessage::HandshakeMessage() {
|
||||
this->pstrlen = 19;
|
||||
this->pstr = PSTR;
|
||||
memset(this->reserved, 0, sizeof(this->reserved));
|
||||
// fast extension
|
||||
this->reserved[7] |= 0x04;
|
||||
}
|
||||
|
||||
HandshakeMessage* HandshakeMessage::create(const char* data, int dataLength) {
|
||||
HandshakeMessage* message = new HandshakeMessage();
|
||||
message->pstrlen = data[0];
|
||||
char pstrTemp[20];
|
||||
memcpy(pstrTemp, &data[1], sizeof(pstrTemp)-1);
|
||||
pstrTemp[sizeof(pstrTemp)-1] = '\0';
|
||||
message->pstr = pstrTemp;
|
||||
memcpy(message->reserved, &data[20], 8);
|
||||
memcpy(message->infoHash, &data[28], 20);
|
||||
memcpy(message->peerId, &data[48], 20);
|
||||
return message;
|
||||
}
|
||||
|
||||
const char* HandshakeMessage::getMessage() {
|
||||
if(!inProgress) {
|
||||
msg[0] = pstrlen;
|
||||
memcpy(msg+1, pstr.c_str(), pstr.size());
|
||||
memcpy(msg+20, reserved, 8);
|
||||
memcpy(msg+28, infoHash, 20);
|
||||
memcpy(msg+48, peerId, 20);
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
int HandshakeMessage::getMessageLength() {
|
||||
return sizeof(msg);
|
||||
}
|
||||
|
||||
string HandshakeMessage::toString() const {
|
||||
return "handshake peerId="+
|
||||
Util::urlencode((unsigned char*)peerId, sizeof(peerId));
|
||||
Util::urlencode((unsigned char*)peerId, sizeof(peerId))+
|
||||
" reserved="+Util::toHex(reserved, sizeof(reserved));
|
||||
}
|
||||
|
||||
void HandshakeMessage::check() {
|
||||
void HandshakeMessage::check() const {
|
||||
PeerMessageUtil::checkHandshake(this,
|
||||
peerInteraction->getTorrentMan()->getInfoHash());
|
||||
}
|
||||
|
||||
bool HandshakeMessage::isFastExtensionSupported() const {
|
||||
return reserved[7]&0x04;
|
||||
}
|
||||
|
|
|
@ -22,29 +22,36 @@
|
|||
#ifndef _D_HANDSHAKE_MESSAGE_H_
|
||||
#define _D_HANDSHAKE_MESSAGE_H_
|
||||
|
||||
#include "common.h"
|
||||
|
||||
class PeerInteraction;
|
||||
#include "SimplePeerMessage.h"
|
||||
#include "TorrentMan.h"
|
||||
|
||||
#define PSTR "BitTorrent protocol"
|
||||
#define HANDSHAKE_MESSAGE_LENGTH 68
|
||||
|
||||
class HandshakeMessage {
|
||||
class HandshakeMessage : public SimplePeerMessage {
|
||||
private:
|
||||
char msg[HANDSHAKE_MESSAGE_LENGTH];
|
||||
public:
|
||||
char pstrlen;
|
||||
string pstr;
|
||||
unsigned char infoHash[20];
|
||||
char peerId[20];
|
||||
PeerInteraction* peerInteraction;
|
||||
unsigned char reserved[8];
|
||||
unsigned char infoHash[INFO_HASH_LENGTH];
|
||||
char peerId[PEER_ID_LENGTH];
|
||||
public:
|
||||
HandshakeMessage() {}
|
||||
~HandshakeMessage() {}
|
||||
HandshakeMessage();
|
||||
|
||||
PeerInteraction* getPeerInteraction() const { return peerInteraction; }
|
||||
void setPeerInteraction(PeerInteraction* peerInteraction);
|
||||
static HandshakeMessage* create(const char* data, int dataLength);
|
||||
|
||||
string toString() const;
|
||||
void check();
|
||||
virtual ~HandshakeMessage() {}
|
||||
|
||||
virtual int getId() const { return 999; }
|
||||
virtual void receivedAction() {};
|
||||
virtual const char* getMessage();
|
||||
virtual int getMessageLength();
|
||||
virtual void check() const;
|
||||
virtual string toString() const;
|
||||
|
||||
bool isFastExtensionSupported() const;
|
||||
};
|
||||
|
||||
#endif // _D_HANDSHAKE_MESSAGE_H_
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
/* <!-- 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 "HaveAllMessage.h"
|
||||
#include "DlAbortEx.h"
|
||||
#include "PeerInteraction.h"
|
||||
#include "PeerMessageUtil.h"
|
||||
|
||||
HaveAllMessage::HaveAllMessage() {}
|
||||
|
||||
HaveAllMessage::~HaveAllMessage() {}
|
||||
|
||||
HaveAllMessage* HaveAllMessage::create(const char* data, int dataLength) {
|
||||
if(dataLength != 1) {
|
||||
throw new DlAbortEx("invalid payload size for %s, size = %d. It should be %d", "have all", dataLength, 1);
|
||||
}
|
||||
int id = PeerMessageUtil::getId(data);
|
||||
if(id != ID) {
|
||||
throw new DlAbortEx("invalid ID=%d for %s. It should be %d.",
|
||||
id, "have all", ID);
|
||||
}
|
||||
HaveAllMessage* haveAllMessage = new HaveAllMessage();
|
||||
return haveAllMessage;
|
||||
}
|
||||
|
||||
void HaveAllMessage::receivedAction() {
|
||||
if(!peer->isFastExtensionEnabled()) {
|
||||
throw new DlAbortEx("%s received while fast extension is disabled",
|
||||
toString().c_str());
|
||||
}
|
||||
peer->setAllBitfield();
|
||||
}
|
||||
|
||||
const char* HaveAllMessage::getMessage() {
|
||||
if(!inProgress) {
|
||||
/**
|
||||
* len --- 1, 4bytes
|
||||
* id --- 14, 1byte
|
||||
* total: 5bytes
|
||||
*/
|
||||
PeerMessageUtil::createPeerMessageString(msg, sizeof(msg), 1, ID);
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
int HaveAllMessage::getMessageLength() {
|
||||
return sizeof(msg);
|
||||
}
|
||||
|
||||
void HaveAllMessage::check() const {}
|
||||
|
||||
string HaveAllMessage::toString() const {
|
||||
return "have all";
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
/* <!-- 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_ALL_MESSAGE_H_
|
||||
#define _D_HAVE_ALL_MESSAGE_H_
|
||||
|
||||
#include "SimplePeerMessage.h"
|
||||
|
||||
class HaveAllMessage : public SimplePeerMessage {
|
||||
private:
|
||||
char msg[5];
|
||||
public:
|
||||
HaveAllMessage();
|
||||
virtual ~HaveAllMessage();
|
||||
|
||||
enum ID {
|
||||
ID = 14
|
||||
};
|
||||
|
||||
static HaveAllMessage* create(const char* data, int dataLength);
|
||||
|
||||
virtual int getId() const { return ID; }
|
||||
virtual void receivedAction();
|
||||
virtual const char* getMessage();
|
||||
virtual int getMessageLength();
|
||||
virtual void check() const;
|
||||
virtual string toString() const;
|
||||
};
|
||||
|
||||
#endif // _D_HAVE_ALL_MESSAGE_H_
|
|
@ -23,15 +23,46 @@
|
|||
#include "PeerInteraction.h"
|
||||
#include "PeerMessageUtil.h"
|
||||
#include "Util.h"
|
||||
#include "DlAbortEx.h"
|
||||
|
||||
HaveMessage* HaveMessage::create(const char* data, int dataLength) {
|
||||
if(dataLength != 5) {
|
||||
throw new DlAbortEx("invalid payload size for %s, size = %d. It should be %d", "have", dataLength, 5);
|
||||
}
|
||||
int id = PeerMessageUtil::getId(data);
|
||||
if(id != ID) {
|
||||
throw new DlAbortEx("invalid ID=%d for %s. It should be %d.",
|
||||
id, "have", ID);
|
||||
}
|
||||
HaveMessage* haveMessage = new HaveMessage();
|
||||
haveMessage->setIndex(PeerMessageUtil::getIntParam(data, 1));
|
||||
return haveMessage;
|
||||
}
|
||||
|
||||
void HaveMessage::receivedAction() {
|
||||
peer->updateBitfield(index, 1);
|
||||
}
|
||||
|
||||
void HaveMessage::send() {
|
||||
if(!peer->hasPiece(index)) {
|
||||
peerInteraction->getPeerConnection()->sendHave(index);
|
||||
bool HaveMessage::sendPredicate() const {
|
||||
return !peer->hasPiece(index);
|
||||
}
|
||||
|
||||
const char* HaveMessage::getMessage() {
|
||||
if(!inProgress) {
|
||||
/**
|
||||
* len --- 5, 4bytes
|
||||
* id --- 4, 1byte
|
||||
* piece index --- index, 4bytes
|
||||
* total: 9bytes
|
||||
*/
|
||||
PeerMessageUtil::createPeerMessageString(msg, sizeof(msg), 5, ID);
|
||||
PeerMessageUtil::setIntParam(&msg[5], index);
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
int HaveMessage::getMessageLength() {
|
||||
return sizeof(msg);
|
||||
}
|
||||
|
||||
void HaveMessage::check() const {
|
||||
|
|
|
@ -22,15 +22,18 @@
|
|||
#ifndef _D_HAVE_MESSAGE_H_
|
||||
#define _D_HAVE_MESSAGE_H_
|
||||
|
||||
#include "PeerMessage.h"
|
||||
#include "SimplePeerMessage.h"
|
||||
|
||||
class HaveMessage : public PeerMessage {
|
||||
class HaveMessage : public SimplePeerMessage {
|
||||
private:
|
||||
int index;
|
||||
// for check
|
||||
int pieces;
|
||||
char msg[9];
|
||||
protected:
|
||||
virtual bool sendPredicate() const;
|
||||
public:
|
||||
HaveMessage():PeerMessage(), index(0), pieces(0) {}
|
||||
HaveMessage():SimplePeerMessage(), index(0), pieces(0) {}
|
||||
|
||||
virtual ~HaveMessage() {}
|
||||
|
||||
|
@ -48,9 +51,12 @@ public:
|
|||
}
|
||||
int getPieces() const { return pieces;}
|
||||
|
||||
static HaveMessage* create(const char* data, int dataLength);
|
||||
|
||||
virtual int getId() const { return ID; }
|
||||
virtual void receivedAction();
|
||||
virtual void send();
|
||||
virtual const char* getMessage();
|
||||
virtual int getMessageLength();
|
||||
virtual void check() const;
|
||||
virtual string toString() const;
|
||||
};
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
/* <!-- 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 "HaveNoneMessage.h"
|
||||
#include "DlAbortEx.h"
|
||||
#include "PeerInteraction.h"
|
||||
#include "PeerMessageUtil.h"
|
||||
|
||||
HaveNoneMessage::HaveNoneMessage() {}
|
||||
|
||||
HaveNoneMessage::~HaveNoneMessage() {}
|
||||
|
||||
HaveNoneMessage* HaveNoneMessage::create(const char* data, int dataLength) {
|
||||
if(dataLength != 1) {
|
||||
throw new DlAbortEx("invalid payload size for %s, size = %d. It should be %d", "have none", dataLength, 1);
|
||||
}
|
||||
int id = PeerMessageUtil::getId(data);
|
||||
if(id != ID) {
|
||||
throw new DlAbortEx("invalid ID=%d for %s. It should be %d.",
|
||||
id, "have none", ID);
|
||||
}
|
||||
HaveNoneMessage* haveNoneMessage = new HaveNoneMessage();
|
||||
return haveNoneMessage;
|
||||
}
|
||||
|
||||
void HaveNoneMessage::receivedAction() {
|
||||
if(!peer->isFastExtensionEnabled()) {
|
||||
throw new DlAbortEx("%s received while fast extension is disabled",
|
||||
toString().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
const char* HaveNoneMessage::getMessage() {
|
||||
if(!inProgress) {
|
||||
/**
|
||||
* len --- 1, 4bytes
|
||||
* id --- 15, 1byte
|
||||
* total: 5bytes
|
||||
*/
|
||||
PeerMessageUtil::createPeerMessageString(msg, sizeof(msg), 1, ID);
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
int HaveNoneMessage::getMessageLength() {
|
||||
return sizeof(msg);
|
||||
}
|
||||
|
||||
void HaveNoneMessage::check() const {}
|
||||
|
||||
string HaveNoneMessage::toString() const {
|
||||
return "have none";
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
/* <!-- 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_NONE_MESSAGE_H_
|
||||
#define _D_HAVE_NONE_MESSAGE_H_
|
||||
|
||||
#include "SimplePeerMessage.h"
|
||||
|
||||
class HaveNoneMessage : public SimplePeerMessage {
|
||||
private:
|
||||
char msg[5];
|
||||
public:
|
||||
HaveNoneMessage();
|
||||
virtual ~HaveNoneMessage();
|
||||
|
||||
enum ID {
|
||||
ID = 15
|
||||
};
|
||||
|
||||
static HaveNoneMessage* create(const char* data, int dataLength);
|
||||
|
||||
virtual int getId() const { return ID; }
|
||||
virtual void receivedAction();
|
||||
virtual const char* getMessage();
|
||||
virtual int getMessageLength();
|
||||
virtual void check() const;
|
||||
virtual string toString() const;
|
||||
};
|
||||
|
||||
#endif // _D_HAVE_NONE_MESSAGE_H_
|
|
@ -21,16 +21,48 @@
|
|||
/* copyright --> */
|
||||
#include "InterestedMessage.h"
|
||||
#include "PeerInteraction.h"
|
||||
#include "PeerMessageUtil.h"
|
||||
#include "DlAbortEx.h"
|
||||
|
||||
InterestedMessage* InterestedMessage::create(const char* data, int dataLength) {
|
||||
if(dataLength != 1) {
|
||||
throw new DlAbortEx("invalid payload size for %s, size = %d. It should be %d", "interested", dataLength, 1);
|
||||
}
|
||||
int id = PeerMessageUtil::getId(data);
|
||||
if(id != ID) {
|
||||
throw new DlAbortEx("invalid ID=%d for %s. It should be %d.",
|
||||
id, "interested", ID);
|
||||
}
|
||||
InterestedMessage* interestedMessage = new InterestedMessage();
|
||||
return interestedMessage;
|
||||
}
|
||||
|
||||
void InterestedMessage::receivedAction() {
|
||||
peer->peerInterested = true;
|
||||
}
|
||||
|
||||
void InterestedMessage::send() {
|
||||
if(!peer->amInterested) {
|
||||
peerInteraction->getPeerConnection()->sendInterested();
|
||||
peer->amInterested = true;
|
||||
bool InterestedMessage::sendPredicate() const {
|
||||
return !peer->amInterested;
|
||||
}
|
||||
|
||||
const char* InterestedMessage::getMessage() {
|
||||
if(!inProgress) {
|
||||
/**
|
||||
* len --- 1, 4bytes
|
||||
* id --- 2, 1byte
|
||||
* total: 5bytes
|
||||
*/
|
||||
PeerMessageUtil::createPeerMessageString(msg, sizeof(msg), 1, ID);
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
int InterestedMessage::getMessageLength() {
|
||||
return sizeof(msg);
|
||||
}
|
||||
|
||||
void InterestedMessage::onSendComplete() {
|
||||
peer->amInterested = true;
|
||||
}
|
||||
|
||||
string InterestedMessage::toString() const {
|
||||
|
|
|
@ -22,20 +22,28 @@
|
|||
#ifndef _D_INTERESTED_MESSAGE_H_
|
||||
#define _D_INTERESTED_MESSAGE_H_
|
||||
|
||||
#include "PeerMessage.h"
|
||||
#include "SimplePeerMessage.h"
|
||||
|
||||
class InterestedMessage : public PeerMessage {
|
||||
class InterestedMessage : public SimplePeerMessage {
|
||||
private:
|
||||
char msg[5];
|
||||
protected:
|
||||
virtual bool sendPredicate() const;
|
||||
virtual void onSendComplete();
|
||||
public:
|
||||
InterestedMessage():PeerMessage() {}
|
||||
InterestedMessage():SimplePeerMessage() {}
|
||||
virtual ~InterestedMessage() {}
|
||||
|
||||
enum ID {
|
||||
ID = 2
|
||||
};
|
||||
|
||||
static InterestedMessage* create(const char* data, int dataLength);
|
||||
|
||||
virtual int getId() const { return ID; }
|
||||
virtual void receivedAction();
|
||||
virtual void send();
|
||||
virtual const char* getMessage();
|
||||
virtual int getMessageLength();
|
||||
virtual string toString() const;
|
||||
};
|
||||
|
||||
|
|
|
@ -22,6 +22,17 @@
|
|||
#include "KeepAliveMessage.h"
|
||||
#include "PeerInteraction.h"
|
||||
|
||||
void KeepAliveMessage::send() {
|
||||
peerInteraction->getPeerConnection()->sendKeepAlive();
|
||||
const char* KeepAliveMessage::getMessage() {
|
||||
if(!inProgress) {
|
||||
/**
|
||||
* len --- 0, 4bytes
|
||||
* total: 4bytes
|
||||
*/
|
||||
memset(msg, 0, sizeof(msg));
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
int KeepAliveMessage::getMessageLength() {
|
||||
return sizeof(msg);
|
||||
}
|
||||
|
|
|
@ -22,11 +22,13 @@
|
|||
#ifndef _D_KEEP_ALIVE_MESSAGE_H_
|
||||
#define _D_KEEP_ALIVE_MESSAGE_H_
|
||||
|
||||
#include "PeerMessage.h"
|
||||
#include "SimplePeerMessage.h"
|
||||
|
||||
class KeepAliveMessage : public PeerMessage {
|
||||
class KeepAliveMessage : public SimplePeerMessage {
|
||||
private:
|
||||
char msg[4];
|
||||
public:
|
||||
KeepAliveMessage():PeerMessage() {}
|
||||
KeepAliveMessage():SimplePeerMessage() {}
|
||||
virtual ~KeepAliveMessage() {}
|
||||
|
||||
enum ID {
|
||||
|
@ -35,7 +37,8 @@ public:
|
|||
|
||||
virtual int getId() const { return ID; }
|
||||
virtual void receivedAction() {}
|
||||
virtual void send();
|
||||
virtual const char* getMessage();
|
||||
virtual int getMessageLength();
|
||||
virtual string toString() const {
|
||||
return "keep alive";
|
||||
}
|
||||
|
|
|
@ -94,7 +94,13 @@ SRCS = Socket.cc Socket.h\
|
|||
PieceMessage.cc PieceMessage.h\
|
||||
CancelMessage.cc CancelMessage.h\
|
||||
KeepAliveMessage.cc KeepAliveMessage.h\
|
||||
PortMessage.h
|
||||
PortMessage.cc PortMessage.h\
|
||||
HaveAllMessage.cc HaveAllMessage.h\
|
||||
HaveNoneMessage.cc HaveNoneMessage.h\
|
||||
RejectMessage.cc RejectMessage.h\
|
||||
AllowedFastMessage.cc AllowedFastMessage.h\
|
||||
SuggestPieceMessage.cc SuggestPieceMessage.h\
|
||||
SimplePeerMessage.cc SimplePeerMessage.h
|
||||
noinst_LIBRARIES = libaria2c.a
|
||||
libaria2c_a_SOURCES = $(SRCS)
|
||||
aria2c_LDADD = libaria2c.a @LIBINTL@ @ALLOCA@ @LIBGNUTLS_LIBS@\
|
||||
|
|
|
@ -105,7 +105,11 @@ am__objects_1 = Socket.$(OBJEXT) SocketCore.$(OBJEXT) \
|
|||
InterestedMessage.$(OBJEXT) NotInterestedMessage.$(OBJEXT) \
|
||||
HaveMessage.$(OBJEXT) BitfieldMessage.$(OBJEXT) \
|
||||
RequestMessage.$(OBJEXT) PieceMessage.$(OBJEXT) \
|
||||
CancelMessage.$(OBJEXT) KeepAliveMessage.$(OBJEXT)
|
||||
CancelMessage.$(OBJEXT) KeepAliveMessage.$(OBJEXT) \
|
||||
PortMessage.$(OBJEXT) HaveAllMessage.$(OBJEXT) \
|
||||
HaveNoneMessage.$(OBJEXT) RejectMessage.$(OBJEXT) \
|
||||
AllowedFastMessage.$(OBJEXT) SuggestPieceMessage.$(OBJEXT) \
|
||||
SimplePeerMessage.$(OBJEXT)
|
||||
am_libaria2c_a_OBJECTS = $(am__objects_1)
|
||||
libaria2c_a_OBJECTS = $(am_libaria2c_a_OBJECTS)
|
||||
am__installdirs = "$(DESTDIR)$(bindir)"
|
||||
|
@ -349,7 +353,13 @@ SRCS = Socket.cc Socket.h\
|
|||
PieceMessage.cc PieceMessage.h\
|
||||
CancelMessage.cc CancelMessage.h\
|
||||
KeepAliveMessage.cc KeepAliveMessage.h\
|
||||
PortMessage.h
|
||||
PortMessage.cc PortMessage.h\
|
||||
HaveAllMessage.cc HaveAllMessage.h\
|
||||
HaveNoneMessage.cc HaveNoneMessage.h\
|
||||
RejectMessage.cc RejectMessage.h\
|
||||
AllowedFastMessage.cc AllowedFastMessage.h\
|
||||
SuggestPieceMessage.cc SuggestPieceMessage.h\
|
||||
SimplePeerMessage.cc SimplePeerMessage.h
|
||||
|
||||
noinst_LIBRARIES = libaria2c.a
|
||||
libaria2c_a_SOURCES = $(SRCS)
|
||||
|
@ -437,6 +447,7 @@ distclean-compile:
|
|||
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/alloca.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AbstractCommand.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AbstractDiskWriter.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AllowedFastMessage.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@
|
||||
|
@ -463,7 +474,9 @@ distclean-compile:
|
|||
@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)/HaveAllMessage.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HaveMessage.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HaveNoneMessage.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@
|
||||
|
@ -494,7 +507,9 @@ distclean-compile:
|
|||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PeerMessageUtil.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Piece.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PieceMessage.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PortMessage.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PreAllocationDiskWriter.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RejectMessage.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@
|
||||
|
@ -502,11 +517,13 @@ distclean-compile:
|
|||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SegmentSplitter.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ShaVisitor.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SimpleLogger.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SimplePeerMessage.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SleepCommand.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Socket.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SocketCore.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SplitFirstSegmentSplitter.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SplitSlowestSegmentSplitter.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SuggestPieceMessage.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TorrentAutoSaveCommand.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TorrentConsoleDownloadEngine.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TorrentDownloadEngine.Po@am__quote@
|
||||
|
|
|
@ -21,16 +21,48 @@
|
|||
/* copyright --> */
|
||||
#include "NotInterestedMessage.h"
|
||||
#include "PeerInteraction.h"
|
||||
#include "PeerMessageUtil.h"
|
||||
#include "DlAbortEx.h"
|
||||
|
||||
NotInterestedMessage* NotInterestedMessage::create(const char* data, int dataLength) {
|
||||
if(dataLength != 1) {
|
||||
throw new DlAbortEx("invalid payload size for %s, size = %d. It should be %d", "not interested", dataLength, 1);
|
||||
}
|
||||
int id = PeerMessageUtil::getId(data);
|
||||
if(id != ID) {
|
||||
throw new DlAbortEx("invalid ID=%d for %s. It should be %d.",
|
||||
id, "not interested", ID);
|
||||
}
|
||||
NotInterestedMessage* notInterestedMessage = new NotInterestedMessage();
|
||||
return notInterestedMessage;
|
||||
}
|
||||
|
||||
void NotInterestedMessage::receivedAction() {
|
||||
peer->peerInterested = false;
|
||||
}
|
||||
|
||||
void NotInterestedMessage::send() {
|
||||
if(peer->amInterested) {
|
||||
peerInteraction->getPeerConnection()->sendNotInterested();
|
||||
peer->amInterested = false;
|
||||
bool NotInterestedMessage::sendPredicate() const {
|
||||
return peer->amInterested;
|
||||
}
|
||||
|
||||
const char* NotInterestedMessage::getMessage() {
|
||||
if(!inProgress) {
|
||||
/**
|
||||
* len --- 1, 4bytes
|
||||
* id --- 3, 1byte
|
||||
* total: 5bytes
|
||||
*/
|
||||
PeerMessageUtil::createPeerMessageString(msg, sizeof(msg), 1, ID);
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
int NotInterestedMessage::getMessageLength() {
|
||||
return sizeof(msg);
|
||||
}
|
||||
|
||||
void NotInterestedMessage::onSendComplete() {
|
||||
peer->amInterested = false;
|
||||
}
|
||||
|
||||
string NotInterestedMessage::toString() const {
|
||||
|
|
|
@ -22,20 +22,28 @@
|
|||
#ifndef _D_NOT_INTERESTED_MESSAGE_H_
|
||||
#define _D_NOT_INTERESTED_MESSAGE_H_
|
||||
|
||||
#include "PeerMessage.h"
|
||||
#include "SimplePeerMessage.h"
|
||||
|
||||
class NotInterestedMessage : public PeerMessage {
|
||||
class NotInterestedMessage : public SimplePeerMessage {
|
||||
private:
|
||||
char msg[5];
|
||||
protected:
|
||||
virtual bool sendPredicate() const;
|
||||
virtual void onSendComplete();
|
||||
public:
|
||||
NotInterestedMessage():PeerMessage() {}
|
||||
NotInterestedMessage():SimplePeerMessage() {}
|
||||
virtual ~NotInterestedMessage() {}
|
||||
|
||||
enum ID {
|
||||
ID = 3
|
||||
};
|
||||
|
||||
static NotInterestedMessage* create(const char* data, int dataLength);
|
||||
|
||||
virtual int getId() const { return ID; }
|
||||
virtual void receivedAction();
|
||||
virtual void send();
|
||||
virtual const char* getMessage();
|
||||
virtual int getMessageLength();
|
||||
virtual string toString() const;
|
||||
};
|
||||
|
||||
|
|
16
src/Peer.cc
16
src/Peer.cc
|
@ -59,4 +59,20 @@ void Peer::resetStatus() {
|
|||
resetDeltaDownload();
|
||||
chokingRequired = true;
|
||||
optUnchoking = false;
|
||||
fastExtensionEnabled = false;
|
||||
fastSet.clear();
|
||||
}
|
||||
|
||||
bool Peer::isInFastSet(int index) const {
|
||||
return find(fastSet.begin(), fastSet.end(), index) != fastSet.end();
|
||||
}
|
||||
|
||||
void Peer::addFastSetIndex(int index) {
|
||||
if(!isInFastSet(index)) {
|
||||
fastSet.push_back(index);
|
||||
}
|
||||
}
|
||||
|
||||
void Peer::setAllBitfield() {
|
||||
bitfield->setAllBit();
|
||||
}
|
||||
|
|
17
src/Peer.h
17
src/Peer.h
|
@ -48,6 +48,9 @@ public:
|
|||
private:
|
||||
char peerId[PEER_ID_LENGTH];
|
||||
BitfieldMan* bitfield;
|
||||
bool fastExtensionEnabled;
|
||||
// allowed fast indexes that peer has sent by Allowed Fast message
|
||||
Integers fastSet;
|
||||
long long int peerUpload;
|
||||
long long int peerDownload;
|
||||
int pieceLength;
|
||||
|
@ -62,6 +65,7 @@ public:
|
|||
tryCount(0), error(0), cuid(0),
|
||||
chokingRequired(true), optUnchoking(false),
|
||||
bitfield(NULL),
|
||||
fastExtensionEnabled(false),
|
||||
peerUpload(0), peerDownload(0),
|
||||
pieceLength(pieceLength), totalLength(totalLength),
|
||||
deltaUpload(0), deltaDownload(0) {
|
||||
|
@ -98,13 +102,14 @@ public:
|
|||
}
|
||||
const unsigned char* getBitfield() const { return bitfield->getBitfield(); }
|
||||
int getBitfieldLength() const { return bitfield->getBitfieldLength(); }
|
||||
void setAllBitfield();
|
||||
|
||||
/**
|
||||
* operation = 1: set index-th bit 1
|
||||
* operation = 0: set index-th bit 0
|
||||
*/
|
||||
void updateBitfield(int index, int operation);
|
||||
|
||||
|
||||
void addPeerUpload(int size) {
|
||||
peerUpload += size;
|
||||
addDeltaUpload(size);
|
||||
|
@ -119,6 +124,16 @@ public:
|
|||
void setPeerDownload(long long int size) { peerDownload = size; }
|
||||
long long int getPeerDownload() const { return peerDownload; }
|
||||
|
||||
void setFastExtensionEnabled(bool enabled) {
|
||||
fastExtensionEnabled = enabled;
|
||||
}
|
||||
bool isFastExtensionEnabled() const { return fastExtensionEnabled; }
|
||||
|
||||
void addFastSetIndex(int index);
|
||||
const Integers getFastSet() const { return fastSet; }
|
||||
bool isInFastSet(int index) const;
|
||||
int countFastSet() const { return fastSet.size(); }
|
||||
|
||||
bool shouldBeChoking() const;
|
||||
|
||||
bool hasPiece(int index) const;
|
||||
|
|
|
@ -28,7 +28,9 @@
|
|||
#include <sys/time.h>
|
||||
|
||||
PeerAbstractCommand::PeerAbstractCommand(int cuid, Peer* peer, TorrentDownloadEngine* e, const Socket* s):
|
||||
Command(cuid), e(e), peer(peer), checkSocketIsReadable(false), checkSocketIsWritable(false) {
|
||||
Command(cuid), e(e), peer(peer),
|
||||
checkSocketIsReadable(false), checkSocketIsWritable(false),
|
||||
uploadLimitCheck(false), uploadLimit(0) {
|
||||
|
||||
if(s != NULL) {
|
||||
socket = new Socket(*s);
|
||||
|
@ -74,8 +76,13 @@ bool PeerAbstractCommand::isTimeoutDetected() {
|
|||
bool PeerAbstractCommand::execute() {
|
||||
try {
|
||||
beforeSocketCheck();
|
||||
if(checkSocketIsReadable && !readCheckTarget->isReadable(0)
|
||||
|| checkSocketIsWritable && !writeCheckTarget->isWritable(0)) {
|
||||
if(uploadLimitCheck && e->getUploadSpeed() <= uploadLimit*1024 ||
|
||||
checkSocketIsReadable && readCheckTarget->isReadable(0) ||
|
||||
checkSocketIsWritable && writeCheckTarget->isWritable(0) ||
|
||||
!checkSocketIsReadable && !checkSocketIsWritable) {
|
||||
updateCheckPoint();
|
||||
return executeInternal();
|
||||
} else {
|
||||
if(isTimeoutDetected()) {
|
||||
// TODO
|
||||
checkPoint.tv_sec = 0;
|
||||
|
@ -85,10 +92,6 @@ bool PeerAbstractCommand::execute() {
|
|||
e->commands.push_back(this);
|
||||
return false;
|
||||
}
|
||||
updateCheckPoint();
|
||||
bool returnValue = executeInternal();
|
||||
//e->torrentMan->updatePeer(peer);
|
||||
return returnValue;
|
||||
} catch(Exception* err) {
|
||||
logger->error(MSG_DOWNLOAD_ABORTED, err, cuid);
|
||||
onAbort(err);
|
||||
|
@ -113,7 +116,7 @@ void PeerAbstractCommand::onAbort(Exception* ex) {
|
|||
peer->error += MAX_PEER_ERROR;
|
||||
}
|
||||
peer->resetStatus();
|
||||
logger->debug("CUID#%d - peer %s:%d banned.", cuid, peer->ipaddr.c_str(), peer->port);
|
||||
logger->debug("CUID#%d - Peer %s:%d banned.", cuid, peer->ipaddr.c_str(), peer->port);
|
||||
}
|
||||
|
||||
void PeerAbstractCommand::setReadCheckSocket(Socket* socket) {
|
||||
|
@ -159,3 +162,11 @@ void PeerAbstractCommand::setWriteCheckSocket(Socket* socket) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PeerAbstractCommand::setUploadLimit(int uploadLimit) {
|
||||
this->uploadLimit = uploadLimit;
|
||||
}
|
||||
|
||||
void PeerAbstractCommand::setUploadLimitCheck(bool check) {
|
||||
this->uploadLimitCheck = check;
|
||||
}
|
||||
|
|
|
@ -45,11 +45,15 @@ protected:
|
|||
virtual void beforeSocketCheck() {}
|
||||
void setReadCheckSocket(Socket* socket);
|
||||
void setWriteCheckSocket(Socket* socket);
|
||||
void setUploadLimit(int uploadLimit);
|
||||
void setUploadLimitCheck(bool check);
|
||||
private:
|
||||
bool checkSocketIsReadable;
|
||||
bool checkSocketIsWritable;
|
||||
Socket* readCheckTarget;
|
||||
Socket* writeCheckTarget;
|
||||
bool uploadLimitCheck;
|
||||
int uploadLimit;
|
||||
public:
|
||||
PeerAbstractCommand(int cuid, Peer* peer, TorrentDownloadEngine* e, const Socket* s = NULL);
|
||||
virtual ~PeerAbstractCommand();
|
||||
|
|
|
@ -27,279 +27,30 @@
|
|||
#include "LogFactory.h"
|
||||
#include <netinet/in.h>
|
||||
|
||||
PeerConnection::PeerConnection(int cuid, const Socket* socket,
|
||||
const Option* op,
|
||||
Peer* peer, TorrentMan* torrentMan)
|
||||
:cuid(cuid), socket(socket), option(op), logger(logger), peer(peer),
|
||||
torrentMan(torrentMan),
|
||||
resbufLength(0), currentPayloadLength(0), lenbufLength(0) {
|
||||
PeerConnection::PeerConnection(int cuid,
|
||||
const Socket* socket,
|
||||
const Option* op)
|
||||
:cuid(cuid),
|
||||
socket(socket),
|
||||
option(op),
|
||||
logger(logger),
|
||||
resbufLength(0),
|
||||
currentPayloadLength(0),
|
||||
lenbufLength(0) {
|
||||
logger = LogFactory::getInstance();
|
||||
}
|
||||
|
||||
PeerConnection::~PeerConnection() {}
|
||||
|
||||
void PeerConnection::sendHandshake() const {
|
||||
/**
|
||||
* pstrlen --- '19', 1byte
|
||||
* pstr --- "BitTorrent protocol", 19bytes
|
||||
* reserved --- \0 * 8, 8bytes
|
||||
* info_hash --- info_hash, 20bytes
|
||||
* peer_id --- peer_id, 20bytes
|
||||
* total: 68bytes
|
||||
*/
|
||||
char msg[HANDSHAKE_MESSAGE_LENGTH];
|
||||
memset(msg, 0, sizeof(msg));
|
||||
msg[0] = 19;
|
||||
memcpy(&msg[1], PSTR, strlen(PSTR));
|
||||
memcpy(&msg[28], torrentMan->getInfoHash(), 20);
|
||||
memcpy(&msg[48], torrentMan->peerId.c_str(), 20);
|
||||
writeOutgoingMessageLog("handshake");
|
||||
socket->writeData(msg, sizeof(msg));
|
||||
}
|
||||
|
||||
void PeerConnection::sendKeepAlive() const {
|
||||
/**
|
||||
* len --- 0, 4bytes
|
||||
* total: 4bytes
|
||||
*/
|
||||
char msg[4];
|
||||
memset(msg, 0, sizeof(msg));
|
||||
writeOutgoingMessageLog("keep alive");
|
||||
socket->writeData(msg, sizeof(msg));
|
||||
}
|
||||
|
||||
void PeerConnection::createNLengthMessage(char* msg, int msgLen, int payloadLen, int id) const {
|
||||
assert(msgLen >= 5);
|
||||
memset(msg, 0, msgLen);
|
||||
setIntParam(msg, payloadLen);
|
||||
msg[4] = (char)id;
|
||||
}
|
||||
|
||||
void PeerConnection::setIntParam(char* dest, int param) const {
|
||||
int nParam = htonl(param);
|
||||
memcpy(dest, &nParam, 4);
|
||||
}
|
||||
|
||||
void PeerConnection::writeOutgoingMessageLog(const char* msg) const {
|
||||
logger->info(MSG_SEND_PEER_MESSAGE, cuid, peer->ipaddr.c_str(), peer->port, msg);
|
||||
}
|
||||
|
||||
void PeerConnection::writeOutgoingMessageLog(const char* msg, int index) const {
|
||||
logger->info(MSG_SEND_PEER_MESSAGE_WITH_INDEX, cuid, peer->ipaddr.c_str(), peer->port, msg, index);
|
||||
}
|
||||
|
||||
void PeerConnection::writeOutgoingMessageLog(const char* msg, const unsigned char* bitfield, int bitfieldLength) const {
|
||||
logger->info(MSG_SEND_PEER_MESSAGE_WITH_BITFIELD, cuid, peer->ipaddr.c_str(), peer->port, msg, Util::toHex(bitfield, bitfieldLength).c_str());
|
||||
}
|
||||
|
||||
void PeerConnection::writeOutgoingMessageLog(const char* msg, int index, int begin, int length) const {
|
||||
logger->info(MSG_SEND_PEER_MESSAGE_WITH_INDEX_BEGIN_LENGTH, cuid, peer->ipaddr.c_str(), peer->port, msg, index, begin, length);
|
||||
}
|
||||
|
||||
void PeerConnection::sendChoke() const {
|
||||
/**
|
||||
* len --- 1, 4bytes
|
||||
* id --- 0, 1byte
|
||||
* total: 5bytes
|
||||
*/
|
||||
char msg[5];
|
||||
createNLengthMessage(msg, sizeof(msg), 1, 0);
|
||||
writeOutgoingMessageLog("choke");
|
||||
socket->writeData(msg, sizeof(msg));
|
||||
}
|
||||
|
||||
void PeerConnection::sendUnchoke() const {
|
||||
/**
|
||||
* len --- 1, 4bytes
|
||||
* id --- 1, 1byte
|
||||
* total: 5bytes
|
||||
*/
|
||||
char msg[5];
|
||||
createNLengthMessage(msg, sizeof(msg), 1, 1);
|
||||
writeOutgoingMessageLog("unchoke");
|
||||
socket->writeData(msg, sizeof(msg));
|
||||
}
|
||||
|
||||
void PeerConnection::sendInterested() const {
|
||||
/**
|
||||
* len --- 1, 4bytes
|
||||
* id --- 2, 1byte
|
||||
* total: 5bytes
|
||||
*/
|
||||
char msg[5];
|
||||
createNLengthMessage(msg, sizeof(msg), 1, 2);
|
||||
writeOutgoingMessageLog("interested");
|
||||
socket->writeData(msg, sizeof(msg));
|
||||
}
|
||||
|
||||
void PeerConnection::sendNotInterested() const {
|
||||
/**
|
||||
* len --- 1, 4bytes
|
||||
* id --- 3, 1byte
|
||||
* total: 5bytes
|
||||
*/
|
||||
char msg[5];
|
||||
createNLengthMessage(msg, sizeof(msg), 1, 3);
|
||||
writeOutgoingMessageLog("not interested");
|
||||
socket->writeData(msg, sizeof(msg));
|
||||
}
|
||||
|
||||
void PeerConnection::sendHave(int index) const {
|
||||
/**
|
||||
* len --- 5, 4bytes
|
||||
* id --- 4, 1byte
|
||||
* piece index --- index, 4bytes
|
||||
* total: 9bytes
|
||||
*/
|
||||
char msg[9];
|
||||
createNLengthMessage(msg, sizeof(msg), 5, 4);
|
||||
setIntParam(&msg[5], index);
|
||||
writeOutgoingMessageLog("have", index);
|
||||
socket->writeData(msg, sizeof(msg));
|
||||
}
|
||||
|
||||
void PeerConnection::sendBitfield() const {
|
||||
int len = torrentMan->getBitfieldLength();
|
||||
const unsigned char* bitfield = torrentMan->getBitfield();
|
||||
/**
|
||||
* len --- 1+len, 4bytes
|
||||
* id --- 5, 1byte
|
||||
* bitfield --- bitfield, len bytes
|
||||
* total: 5+len bytes
|
||||
*/
|
||||
int msgLen = 5+len;
|
||||
char* msg = new char[msgLen];
|
||||
try {
|
||||
createNLengthMessage(msg, msgLen, 1+len, 5);
|
||||
writeOutgoingMessageLog("bitfield", bitfield, len);
|
||||
socket->writeData(msg, msgLen);
|
||||
delete [] msg;
|
||||
} catch(Exception* ex) {
|
||||
delete [] msg;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void PeerConnection::sendRequest(int index, int begin, int length) const {
|
||||
/**
|
||||
* len --- 13, 4bytes
|
||||
* id --- 6, 1byte
|
||||
* index --- index, 4bytes
|
||||
* begin --- begin, 4bytes
|
||||
* length --- length, 4bytes
|
||||
* total: 17bytes
|
||||
*/
|
||||
char msg[17];
|
||||
createNLengthMessage(msg, sizeof(msg), 13, 6);
|
||||
setIntParam(&msg[5], index);
|
||||
setIntParam(&msg[9], begin);
|
||||
setIntParam(&msg[13], length);
|
||||
writeOutgoingMessageLog("request", index, begin, length);
|
||||
socket->writeData(msg, sizeof(msg));
|
||||
}
|
||||
|
||||
void PeerConnection::sendPiece(int index, int begin, int length) const {
|
||||
/**
|
||||
* len --- 9+length, 4bytes
|
||||
* id --- 7, 1byte
|
||||
* index --- index, 4bytes
|
||||
* begin --- begin, 4bytes
|
||||
* sub total: 13bytes
|
||||
* additionally,
|
||||
* block --- data, X bytes
|
||||
*/
|
||||
char msg[13];
|
||||
createNLengthMessage(msg, sizeof(msg), 9+length, 7);
|
||||
setIntParam(&msg[5], index);
|
||||
setIntParam(&msg[9], begin);
|
||||
writeOutgoingMessageLog("piece", index, begin, length);
|
||||
socket->writeData(msg, sizeof(msg));
|
||||
int BUF_SIZE = 4096;
|
||||
char buf[BUF_SIZE];
|
||||
int iteration = length/BUF_SIZE;
|
||||
long long int pieceOffset = ((long long int)index*torrentMan->pieceLength)+begin;
|
||||
for(int i = 0; i < iteration; i++) {
|
||||
if(torrentMan->diskAdaptor->readData(buf, BUF_SIZE, pieceOffset+i*BUF_SIZE) < BUF_SIZE) {
|
||||
throw new DlAbortEx("piece reading failed.");
|
||||
}
|
||||
socket->writeData(buf, BUF_SIZE);
|
||||
}
|
||||
int rem = length%BUF_SIZE;
|
||||
if(rem > 0) {
|
||||
if(torrentMan->diskAdaptor->readData(buf, rem, pieceOffset+iteration*BUF_SIZE) < rem) {
|
||||
throw new DlAbortEx("piece reading failed.");
|
||||
}
|
||||
socket->writeData(buf, rem);
|
||||
}
|
||||
}
|
||||
|
||||
void PeerConnection::sendPieceHeader(int index, int begin, int length) const {
|
||||
/**
|
||||
* len --- 9+length, 4bytes
|
||||
* id --- 7, 1byte
|
||||
* index --- index, 4bytes
|
||||
* begin --- begin, 4bytes
|
||||
* sub total: 13bytes
|
||||
* additionally,
|
||||
* block --- data, X bytes
|
||||
*/
|
||||
char msg[13];
|
||||
createNLengthMessage(msg, sizeof(msg), 9+length, 7);
|
||||
setIntParam(&msg[5], index);
|
||||
setIntParam(&msg[9], begin);
|
||||
writeOutgoingMessageLog("piece", index, begin, length);
|
||||
socket->writeData(msg, sizeof(msg));
|
||||
}
|
||||
|
||||
int PeerConnection::sendPieceData(long long int offset, int length) const {
|
||||
int BUF_SIZE = 256;
|
||||
char buf[BUF_SIZE];
|
||||
int iteration = length/BUF_SIZE;
|
||||
int PeerConnection::sendMessage(const char* msg, int length) {
|
||||
int writtenLength = 0;
|
||||
bool isWritable = true;
|
||||
for(int i = 0; i < iteration; i++) {
|
||||
isWritable = socket->isWritable(0);
|
||||
if(!isWritable) {
|
||||
return writtenLength;
|
||||
}
|
||||
if(torrentMan->diskAdaptor->readData(buf, BUF_SIZE, offset+i*BUF_SIZE) < BUF_SIZE) {
|
||||
throw new DlAbortEx("piece reading failed.");
|
||||
}
|
||||
socket->writeData(buf, BUF_SIZE);
|
||||
writtenLength += BUF_SIZE;
|
||||
}
|
||||
if(socket->isWritable(0)) {
|
||||
int rem = length%BUF_SIZE;
|
||||
if(rem > 0) {
|
||||
if(torrentMan->diskAdaptor->readData(buf, rem, offset+iteration*BUF_SIZE) < rem) {
|
||||
throw new DlAbortEx("piece reading failed.");
|
||||
}
|
||||
socket->writeData(buf, rem);
|
||||
writtenLength += rem;
|
||||
}
|
||||
socket->writeData(msg, length);
|
||||
writtenLength += length;
|
||||
}
|
||||
return writtenLength;
|
||||
}
|
||||
|
||||
|
||||
void PeerConnection::sendCancel(int index, int begin, int length) const {
|
||||
/**
|
||||
* len --- 13, 4bytes
|
||||
* id --- 8, 1byte
|
||||
* index --- index, 4bytes
|
||||
* begin --- begin, 4bytes
|
||||
* length -- length, 4bytes
|
||||
* total: 17bytes
|
||||
*/
|
||||
char msg[17];
|
||||
createNLengthMessage(msg, sizeof(msg), 13, 8);
|
||||
setIntParam(&msg[5], index);
|
||||
setIntParam(&msg[9], begin);
|
||||
setIntParam(&msg[13], length);
|
||||
writeOutgoingMessageLog("cancel", index, begin, length);
|
||||
socket->writeData(msg, sizeof(msg));
|
||||
}
|
||||
|
||||
bool PeerConnection::receiveMessage(char* msg, int& length) {
|
||||
if(!socket->isReadable(0)) {
|
||||
return false;
|
||||
|
|
|
@ -39,8 +39,6 @@ private:
|
|||
const Socket* socket;
|
||||
const Option* option;
|
||||
const Logger* logger;
|
||||
Peer* peer;
|
||||
TorrentMan* torrentMan;
|
||||
|
||||
char resbuf[MAX_PAYLOAD_LEN];
|
||||
int resbufLength;
|
||||
|
@ -48,35 +46,15 @@ private:
|
|||
char lenbuf[4];
|
||||
int lenbufLength;
|
||||
|
||||
void createNLengthMessage(char* msg, int msgLen, int payloadLen, int id) const;
|
||||
void setIntParam(char* dest, int param) const;
|
||||
|
||||
void writeOutgoingMessageLog(const char* msg) const;
|
||||
void writeOutgoingMessageLog(const char* msg, int index) const;
|
||||
void writeOutgoingMessageLog(const char* msg, const unsigned char* bitfield, int bitfieldLength) const;
|
||||
void writeOutgoingMessageLog(const char* msg, int index, int begin, int length) const;
|
||||
public:
|
||||
PeerConnection(int cuid, const Socket* socket, const Option* op,
|
||||
Peer* peer, TorrentMan* torrenMan);
|
||||
PeerConnection(int cuid, const Socket* socket, const Option* op);
|
||||
~PeerConnection();
|
||||
|
||||
// Returns the number of bytes written
|
||||
int sendMessage(const char* msg, int length);
|
||||
|
||||
void sendHandshake() const;
|
||||
void sendKeepAlive() const;
|
||||
void sendChoke() const;
|
||||
void sendUnchoke() const;
|
||||
void sendInterested() const;
|
||||
void sendNotInterested() const;
|
||||
void sendHave(int index) const;
|
||||
void sendBitfield() const;
|
||||
void sendRequest(int index, int begin, int length) const;
|
||||
void sendPiece(int index, int begin, int length) const;
|
||||
void sendPieceHeader(int index, int begin, int length) const;
|
||||
int sendPieceData(long long int offset, int length) const;
|
||||
void sendCancel(int index, int begin, int length) const;
|
||||
bool receiveMessage(char* msg, int& length);
|
||||
bool receiveHandshake(char* msg, int& length);
|
||||
|
||||
Peer* getPeer() const { return peer; }
|
||||
};
|
||||
|
||||
#endif // _D_PEER_CONNECTION_H_
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "DlAbortEx.h"
|
||||
#include "KeepAliveMessage.h"
|
||||
#include "PeerMessageUtil.h"
|
||||
#include "Util.h"
|
||||
#include <netinet/in.h>
|
||||
|
||||
PeerInteraction::PeerInteraction(int cuid,
|
||||
|
@ -36,7 +37,7 @@ PeerInteraction::PeerInteraction(int cuid,
|
|||
torrentMan(torrentMan),
|
||||
peer(peer),
|
||||
piece(Piece::nullPiece) {
|
||||
peerConnection = new PeerConnection(cuid, socket, op, peer, this->torrentMan);
|
||||
peerConnection = new PeerConnection(cuid, socket, op);
|
||||
logger = LogFactory::getInstance();
|
||||
}
|
||||
|
||||
|
@ -45,14 +46,37 @@ PeerInteraction::~PeerInteraction() {
|
|||
for_each(messageQueue.begin(), messageQueue.end(), Deleter());
|
||||
}
|
||||
|
||||
void PeerInteraction::send(int uploadSpeed) {
|
||||
int size = messageQueue.size();
|
||||
for(int i = 0; i < size; i++) {
|
||||
class MsgPushBack {
|
||||
private:
|
||||
MessageQueue* messageQueue;
|
||||
public:
|
||||
MsgPushBack(MessageQueue* messageQueue):messageQueue(messageQueue) {}
|
||||
|
||||
void operator()(PeerMessage* msg) {
|
||||
messageQueue->push_back(msg);
|
||||
}
|
||||
};
|
||||
|
||||
bool PeerInteraction::isSendingMessageInProgress() const {
|
||||
if(messageQueue.size() > 0) {
|
||||
PeerMessage* peerMessage = messageQueue.front();
|
||||
if(peerMessage->isInProgress()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void PeerInteraction::sendMessages(int uploadSpeed) {
|
||||
MessageQueue tempQueue;
|
||||
while(messageQueue.size() > 0) {
|
||||
PeerMessage* msg = messageQueue.front();
|
||||
messageQueue.pop_front();
|
||||
if(uploadLimit != 0 && uploadLimit*1024 <= uploadSpeed &&
|
||||
msg->getId() == PieceMessage::ID && !msg->isInProgress()) {
|
||||
messageQueue.push_back(msg);
|
||||
//!((PieceMessage*)msg)->isPendingCountMax()) {
|
||||
//((PieceMessage*)msg)->incrementPendingCount();
|
||||
tempQueue.push_back(msg);
|
||||
} else {
|
||||
try {
|
||||
msg->send();
|
||||
|
@ -68,6 +92,7 @@ void PeerInteraction::send(int uploadSpeed) {
|
|||
}
|
||||
}
|
||||
}
|
||||
for_each(tempQueue.begin(), tempQueue.end(), MsgPushBack(&messageQueue));
|
||||
}
|
||||
|
||||
void PeerInteraction::addMessage(PeerMessage* peerMessage) {
|
||||
|
@ -82,22 +107,51 @@ void PeerInteraction::addMessage(PeerMessage* peerMessage) {
|
|||
}
|
||||
}
|
||||
|
||||
void PeerInteraction::deletePieceMessageInQueue(const CancelMessage* cancelMessage) {
|
||||
void PeerInteraction::rejectAllPieceMessageInQueue() {
|
||||
MessageQueue tempQueue;
|
||||
for(MessageQueue::iterator itr = messageQueue.begin();
|
||||
itr != messageQueue.end();) {
|
||||
if((*itr)->getId() == PieceMessage::ID) {
|
||||
// Don't delete piece message which is in the allowed fast set.
|
||||
if((*itr)->getId() == PieceMessage::ID && !(*itr)->isInProgress()
|
||||
&& !isInFastSet(((PieceMessage*)*itr)->getIndex())) {
|
||||
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());
|
||||
logger->debug("CUID#%d - Reject piece message in queue because"
|
||||
" peer has been choked. index=%d, begin=%d, length=%d",
|
||||
cuid,
|
||||
pieceMessage->getIndex(),
|
||||
pieceMessage->getBegin(),
|
||||
pieceMessage->getBlockLength());
|
||||
if(peer->isFastExtensionEnabled()) {
|
||||
tempQueue.push_back(createRejectMessage(pieceMessage->getIndex(),
|
||||
pieceMessage->getBegin(),
|
||||
pieceMessage->getBlockLength()));
|
||||
}
|
||||
delete pieceMessage;
|
||||
itr = messageQueue.erase(itr);
|
||||
} else {
|
||||
itr++;
|
||||
}
|
||||
}
|
||||
for_each(tempQueue.begin(), tempQueue.end(), MsgPushBack(&messageQueue));
|
||||
}
|
||||
|
||||
void PeerInteraction::rejectPieceMessageInQueue(int index, int begin, int length) {
|
||||
MessageQueue tempQueue;
|
||||
for(MessageQueue::iterator itr = messageQueue.begin();
|
||||
itr != messageQueue.end();) {
|
||||
if((*itr)->getId() == PieceMessage::ID && !(*itr)->isInProgress()) {
|
||||
PieceMessage* pieceMessage = (PieceMessage*)*itr;
|
||||
if(pieceMessage->getIndex() == index &&
|
||||
pieceMessage->getBegin() == begin &&
|
||||
pieceMessage->getBlockLength() == length) {
|
||||
logger->debug("CUID#%d - Reject piece message in queue because cancel"
|
||||
" message received. index=%d, begin=%d, length=%d",
|
||||
cuid, index, begin, length);
|
||||
delete pieceMessage;
|
||||
itr = messageQueue.erase(itr);
|
||||
if(peer->isFastExtensionEnabled()) {
|
||||
tempQueue.push_back(createRejectMessage(index, begin, length));
|
||||
}
|
||||
} else {
|
||||
itr++;
|
||||
}
|
||||
|
@ -105,52 +159,59 @@ void PeerInteraction::deletePieceMessageInQueue(const CancelMessage* cancelMessa
|
|||
itr++;
|
||||
}
|
||||
}
|
||||
for_each(tempQueue.begin(), tempQueue.end(), MsgPushBack(&messageQueue));
|
||||
}
|
||||
|
||||
void PeerInteraction::deleteRequestMessageInQueue() {
|
||||
for(MessageQueue::iterator itr = messageQueue.begin();
|
||||
itr != messageQueue.end();) {
|
||||
if((*itr)->getId() == RequestMessage::ID) {
|
||||
delete *itr;
|
||||
itr = messageQueue.erase(itr);
|
||||
} else {
|
||||
itr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PeerInteraction::deleteRequestSlot(const RequestSlot& requestSlot) {
|
||||
// TODO use STL algorithm
|
||||
for(RequestSlots::iterator itr = requestSlots.begin();
|
||||
itr != requestSlots.end(); itr++) {
|
||||
if(*itr == requestSlot) {
|
||||
requestSlots.erase(itr);
|
||||
break;
|
||||
}
|
||||
void PeerInteraction::onChoked() {
|
||||
if(!Piece::isNull(piece) && !peer->isInFastSet(piece.getIndex())) {
|
||||
abortPiece();
|
||||
}
|
||||
}
|
||||
|
||||
void PeerInteraction::deleteAllRequestSlot(Piece& piece) {
|
||||
void PeerInteraction::abortPiece() {
|
||||
if(!Piece::isNull(piece)) {
|
||||
for(MessageQueue::iterator itr = messageQueue.begin();
|
||||
itr != messageQueue.end();) {
|
||||
if((*itr)->getId() == RequestMessage::ID
|
||||
&& !(*itr)->isInProgress()) {
|
||||
delete *itr;
|
||||
itr = messageQueue.erase(itr);
|
||||
} else {
|
||||
itr++;
|
||||
}
|
||||
}
|
||||
for(RequestSlots::const_iterator itr = requestSlots.begin();
|
||||
itr != requestSlots.end(); itr++) {
|
||||
if(itr->getIndex() == piece.getIndex()) {
|
||||
piece.cancelBlock(itr->getBlockIndex());
|
||||
}
|
||||
logger->debug("CUID#%d - Deleting request slot blockIndex=%d"
|
||||
" because piece was canceled",
|
||||
cuid,
|
||||
itr->getBlockIndex());
|
||||
piece.cancelBlock(itr->getBlockIndex());
|
||||
}
|
||||
torrentMan->updatePiece(piece);
|
||||
requestSlots.clear();
|
||||
torrentMan->cancelPiece(piece);
|
||||
piece = Piece::nullPiece;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PeerInteraction::deleteRequestSlot(const RequestSlot& requestSlot) {
|
||||
RequestSlots::iterator itr = find(requestSlots.begin(), requestSlots.end(),
|
||||
requestSlot);
|
||||
if(itr != requestSlots.end()) {
|
||||
requestSlots.erase(itr);
|
||||
}
|
||||
requestSlots.clear();
|
||||
}
|
||||
|
||||
void PeerInteraction::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,
|
||||
logger->debug("CUID#%d - Deleting request slot 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);
|
||||
|
@ -166,7 +227,8 @@ void PeerInteraction::deleteCompletedRequestSlot() {
|
|||
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,
|
||||
logger->debug("CUID#%d - Deleting request slot blockIndex=%d because"
|
||||
" the block has been acquired.", cuid,
|
||||
itr->getBlockIndex());
|
||||
addMessage(createCancelMessage(itr->getIndex(), itr->getBegin(), itr->getLength()));
|
||||
itr = requestSlots.erase(itr);
|
||||
|
@ -176,28 +238,21 @@ void PeerInteraction::deleteCompletedRequestSlot() {
|
|||
}
|
||||
}
|
||||
|
||||
RequestSlot PeerInteraction::getCorrespondingRequestSlot(const PieceMessage* pieceMessage) const {
|
||||
RequestSlot PeerInteraction::getCorrespondingRequestSlot(int index,
|
||||
int begin,
|
||||
int length) 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()) {
|
||||
if(slot.getIndex() == index &&
|
||||
slot.getBegin() == begin &&
|
||||
slot.getLength() == length) {
|
||||
return slot;
|
||||
}
|
||||
}
|
||||
return RequestSlot::nullSlot;
|
||||
}
|
||||
|
||||
void PeerInteraction::cancelAllRequest() {
|
||||
cancelAllRequest(Piece::nullPiece);
|
||||
}
|
||||
|
||||
void PeerInteraction::cancelAllRequest(Piece& piece) {
|
||||
deleteRequestMessageInQueue();
|
||||
deleteAllRequestSlot(piece);
|
||||
}
|
||||
|
||||
int PeerInteraction::countMessageInQueue() const {
|
||||
return messageQueue.size();
|
||||
}
|
||||
|
@ -219,12 +274,17 @@ HandshakeMessage* PeerInteraction::receiveHandshake() {
|
|||
delete handshakeMessage;
|
||||
throw;
|
||||
}
|
||||
if(handshakeMessage->isFastExtensionSupported()) {
|
||||
peer->setFastExtensionEnabled(true);
|
||||
logger->info("CUID#%d - Fast extension enabled.");
|
||||
}
|
||||
return handshakeMessage;
|
||||
}
|
||||
|
||||
HandshakeMessage* PeerInteraction::createHandshakeMessage(const char* msg, int msgLength) {
|
||||
HandshakeMessage* message = PeerMessageUtil::createHandshakeMessage(msg, msgLength);
|
||||
message->setPeerInteraction(this);
|
||||
HandshakeMessage* message = HandshakeMessage::create(msg, msgLength);
|
||||
|
||||
setPeerMessageCommonProperty(message);
|
||||
return message;
|
||||
}
|
||||
|
||||
|
@ -253,42 +313,61 @@ PeerMessage* PeerInteraction::createPeerMessage(const char* msg, int msgLength)
|
|||
int id = PeerMessageUtil::getId(msg);
|
||||
switch(id) {
|
||||
case ChokeMessage::ID:
|
||||
peerMessage = PeerMessageUtil::createChokeMessage(msg, msgLength);
|
||||
peerMessage = ChokeMessage::create(msg, msgLength);
|
||||
break;
|
||||
case UnchokeMessage::ID:
|
||||
peerMessage = PeerMessageUtil::createUnchokeMessage(msg, msgLength);
|
||||
peerMessage = UnchokeMessage::create(msg, msgLength);
|
||||
break;
|
||||
case InterestedMessage::ID:
|
||||
peerMessage = PeerMessageUtil::createInterestedMessage(msg, msgLength);
|
||||
peerMessage = InterestedMessage::create(msg, msgLength);
|
||||
break;
|
||||
case NotInterestedMessage::ID:
|
||||
peerMessage = PeerMessageUtil::createNotInterestedMessage(msg, msgLength);
|
||||
peerMessage = NotInterestedMessage::create(msg, msgLength);
|
||||
break;
|
||||
case HaveMessage::ID:
|
||||
peerMessage = PeerMessageUtil::createHaveMessage(msg, msgLength);
|
||||
peerMessage = HaveMessage::create(msg, msgLength);
|
||||
((HaveMessage*)peerMessage)->setPieces(torrentMan->pieces);
|
||||
break;
|
||||
case BitfieldMessage::ID:
|
||||
peerMessage = PeerMessageUtil::createBitfieldMessage(msg, msgLength);
|
||||
peerMessage = BitfieldMessage::create(msg, msgLength);
|
||||
((BitfieldMessage*)peerMessage)->setPieces(torrentMan->pieces);
|
||||
break;
|
||||
case RequestMessage::ID:
|
||||
peerMessage = PeerMessageUtil::createRequestMessage(msg, msgLength);
|
||||
peerMessage = RequestMessage::create(msg, msgLength);
|
||||
((RequestMessage*)peerMessage)->setPieces(torrentMan->pieces);
|
||||
((RequestMessage*)peerMessage)->setPieceLength(torrentMan->getPieceLength(((RequestMessage*)peerMessage)->getIndex()));
|
||||
break;
|
||||
case CancelMessage::ID:
|
||||
peerMessage = PeerMessageUtil::createCancelMessage(msg, msgLength);
|
||||
peerMessage = CancelMessage::create(msg, msgLength);
|
||||
((CancelMessage*)peerMessage)->setPieces(torrentMan->pieces);
|
||||
((CancelMessage*)peerMessage)->setPieceLength(torrentMan->getPieceLength(((CancelMessage*)peerMessage)->getIndex()));
|
||||
break;
|
||||
case PieceMessage::ID:
|
||||
peerMessage = PeerMessageUtil::createPieceMessage(msg, msgLength);
|
||||
peerMessage = PieceMessage::create(msg, msgLength);
|
||||
((PieceMessage*)peerMessage)->setPieces(torrentMan->pieces);
|
||||
((PieceMessage*)peerMessage)->setPieceLength(torrentMan->getPieceLength(((PieceMessage*)peerMessage)->getIndex()));
|
||||
break;
|
||||
case PortMessage::ID:
|
||||
peerMessage = PeerMessageUtil::createPortMessage(msg, msgLength);
|
||||
peerMessage = PortMessage::create(msg, msgLength);
|
||||
break;
|
||||
case HaveAllMessage::ID:
|
||||
peerMessage = HaveAllMessage::create(msg, msgLength);
|
||||
break;
|
||||
case HaveNoneMessage::ID:
|
||||
peerMessage = HaveNoneMessage::create(msg, msgLength);
|
||||
break;
|
||||
case RejectMessage::ID:
|
||||
peerMessage = RejectMessage::create(msg, msgLength);
|
||||
((RejectMessage*)peerMessage)->setPieces(torrentMan->pieces);
|
||||
((RejectMessage*)peerMessage)->setPieceLength(torrentMan->getPieceLength(((RejectMessage*)peerMessage)->getIndex()));
|
||||
break;
|
||||
case SuggestPieceMessage::ID:
|
||||
peerMessage = SuggestPieceMessage::create(msg, msgLength);
|
||||
((SuggestPieceMessage*)peerMessage)->setPieces(torrentMan->pieces);
|
||||
break;
|
||||
case AllowedFastMessage::ID:
|
||||
peerMessage = AllowedFastMessage::create(msg, msgLength);
|
||||
((AllowedFastMessage*)peerMessage)->setPieces(torrentMan->pieces);
|
||||
break;
|
||||
default:
|
||||
throw new DlAbortEx("invalid message id. id = %d", id);
|
||||
|
@ -306,34 +385,35 @@ void PeerInteraction::syncPiece() {
|
|||
torrentMan->syncPiece(piece);
|
||||
}
|
||||
|
||||
Piece PeerInteraction::getNewPieceAndSendInterest() {
|
||||
cancelAllRequest();
|
||||
Piece piece = torrentMan->getMissingPiece(peer);
|
||||
void PeerInteraction::getNewPieceAndSendInterest() {
|
||||
piece = torrentMan->getMissingPiece(peer);
|
||||
if(Piece::isNull(piece)) {
|
||||
logger->debug("CUID#%d - not interested in the peer", cuid);
|
||||
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);
|
||||
if(peer->peerChoking && !peer->isInFastSet(piece.getIndex())) {
|
||||
abortPiece();
|
||||
} else {
|
||||
logger->info("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 PeerInteraction::sendMessages(int currentUploadSpeed) {
|
||||
void PeerInteraction::addRequests() {
|
||||
if(Piece::isNull(piece)) {
|
||||
// retrive new piece from TorrentMan
|
||||
piece = getNewPieceAndSendInterest();
|
||||
} else if(peer->peerChoking) {
|
||||
cancelAllRequest(piece);
|
||||
torrentMan->cancelPiece(piece);
|
||||
piece = Piece::nullPiece;
|
||||
getNewPieceAndSendInterest();
|
||||
} else if(peer->peerChoking && !peer->isInFastSet(piece.getIndex())) {
|
||||
onChoked();
|
||||
} else if(piece.pieceComplete()) {
|
||||
piece = getNewPieceAndSendInterest();
|
||||
abortPiece();
|
||||
getNewPieceAndSendInterest();
|
||||
}
|
||||
if(!Piece::isNull(piece) && !peer->peerChoking) {
|
||||
if(!Piece::isNull(piece)) {
|
||||
if(torrentMan->isEndGame()) {
|
||||
BlockIndexes missingBlockIndexes = piece.getAllMissingBlockIndexes();
|
||||
if(countRequestSlot() == 0) {
|
||||
|
@ -355,30 +435,43 @@ void PeerInteraction::sendMessages(int currentUploadSpeed) {
|
|||
}
|
||||
}
|
||||
}
|
||||
send(currentUploadSpeed);
|
||||
}
|
||||
|
||||
void PeerInteraction::sendNow(PeerMessage* peerMessage) {
|
||||
// ignore inProgress state
|
||||
peerMessage->send();
|
||||
delete peerMessage;
|
||||
}
|
||||
|
||||
void PeerInteraction::trySendNow(PeerMessage* peerMessage) {
|
||||
if(countMessageInQueue() == 0) {
|
||||
sendNow(peerMessage);
|
||||
} else {
|
||||
addMessage(peerMessage);
|
||||
}
|
||||
}
|
||||
|
||||
void PeerInteraction::sendHandshake() {
|
||||
peerConnection->sendHandshake();
|
||||
HandshakeMessage* handshake = new HandshakeMessage();
|
||||
memcpy(handshake->infoHash, torrentMan->getInfoHash(), INFO_HASH_LENGTH);
|
||||
memcpy(handshake->peerId, torrentMan->peerId.c_str(), PEER_ID_LENGTH);
|
||||
setPeerMessageCommonProperty(handshake);
|
||||
addMessage(handshake);
|
||||
sendMessages(0);
|
||||
}
|
||||
|
||||
void PeerInteraction::abortPiece() {
|
||||
cancelAllRequest(piece);
|
||||
torrentMan->cancelPiece(piece);
|
||||
void PeerInteraction::sendBitfield() {
|
||||
if(peer->isFastExtensionEnabled()) {
|
||||
if(torrentMan->hasAllPieces()) {
|
||||
addMessage(createHaveAllMessage());
|
||||
} else if(torrentMan->getDownloadLength() > 0) {
|
||||
addMessage(createBitfieldMessage());
|
||||
} else {
|
||||
addMessage(createHaveNoneMessage());
|
||||
}
|
||||
} else {
|
||||
if(torrentMan->getDownloadLength() > 0) {
|
||||
addMessage(createBitfieldMessage());
|
||||
}
|
||||
}
|
||||
sendMessages(0);
|
||||
}
|
||||
|
||||
void PeerInteraction::sendAllowedFast() {
|
||||
if(peer->isFastExtensionEnabled()) {
|
||||
Integers fastSet = Util::computeFastSet(peer->ipaddr, torrentMan->getInfoHash(),
|
||||
torrentMan->pieces, ALLOWED_FAST_SET_SIZE);
|
||||
for(Integers::const_iterator itr = fastSet.begin();
|
||||
itr != fastSet.end(); itr++) {
|
||||
addMessage(createAllowedFastMessage(*itr));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Piece& PeerInteraction::getDownloadPiece() {
|
||||
|
@ -388,6 +481,16 @@ Piece& PeerInteraction::getDownloadPiece() {
|
|||
return piece;
|
||||
}
|
||||
|
||||
bool PeerInteraction::isInFastSet(int index) const {
|
||||
return find(fastSet.begin(), fastSet.end(), index) != fastSet.end();
|
||||
}
|
||||
|
||||
void PeerInteraction::addFastSetIndex(int index) {
|
||||
if(!isInFastSet(index)) {
|
||||
fastSet.push_back(index);
|
||||
}
|
||||
}
|
||||
|
||||
void PeerInteraction::setPeerMessageCommonProperty(PeerMessage* peerMessage) {
|
||||
peerMessage->setPeer(peer);
|
||||
peerMessage->setCuid(cuid);
|
||||
|
@ -395,68 +498,102 @@ void PeerInteraction::setPeerMessageCommonProperty(PeerMessage* peerMessage) {
|
|||
}
|
||||
|
||||
RequestMessage* PeerInteraction::createRequestMessage(int blockIndex) {
|
||||
RequestMessage* msg =
|
||||
PeerMessageUtil::createRequestMessage(piece.getIndex(),
|
||||
blockIndex*piece.getBlockLength(),
|
||||
piece.getBlockLength(blockIndex),
|
||||
blockIndex);
|
||||
RequestMessage* msg = new RequestMessage();
|
||||
msg->setIndex(piece.getIndex());
|
||||
msg->setBegin(blockIndex*piece.getBlockLength());
|
||||
msg->setLength(piece.getBlockLength(blockIndex));
|
||||
msg->setBlockIndex(blockIndex);
|
||||
setPeerMessageCommonProperty(msg);
|
||||
return msg;
|
||||
}
|
||||
|
||||
CancelMessage* PeerInteraction::createCancelMessage(int index, int begin, int length) {
|
||||
CancelMessage* msg =
|
||||
PeerMessageUtil::createCancelMessage(index, begin, length);
|
||||
CancelMessage* msg = new CancelMessage();
|
||||
msg->setIndex(index);
|
||||
msg->setBegin(begin);
|
||||
msg->setLength(length);
|
||||
setPeerMessageCommonProperty(msg);
|
||||
return msg;
|
||||
}
|
||||
|
||||
PieceMessage* PeerInteraction::createPieceMessage(int index, int begin, int length) {
|
||||
PieceMessage* msg =
|
||||
PeerMessageUtil::createPieceMessage(index, begin, length);
|
||||
PieceMessage* msg = new PieceMessage();
|
||||
msg->setIndex(index);
|
||||
msg->setBegin(begin);
|
||||
msg->setBlockLength(length);
|
||||
setPeerMessageCommonProperty(msg);
|
||||
return msg;
|
||||
}
|
||||
|
||||
HaveMessage* PeerInteraction::createHaveMessage(int index) {
|
||||
HaveMessage* msg = PeerMessageUtil::createHaveMessage(index);
|
||||
HaveMessage* msg = new HaveMessage();
|
||||
msg->setIndex(index);
|
||||
setPeerMessageCommonProperty(msg);
|
||||
return msg;
|
||||
}
|
||||
|
||||
ChokeMessage* PeerInteraction::createChokeMessage() {
|
||||
ChokeMessage* msg = PeerMessageUtil::createChokeMessage();
|
||||
ChokeMessage* msg = new ChokeMessage();
|
||||
setPeerMessageCommonProperty(msg);
|
||||
return msg;
|
||||
}
|
||||
|
||||
UnchokeMessage* PeerInteraction::createUnchokeMessage() {
|
||||
UnchokeMessage* msg = PeerMessageUtil::createUnchokeMessage();
|
||||
UnchokeMessage* msg = new UnchokeMessage();
|
||||
setPeerMessageCommonProperty(msg);
|
||||
return msg;
|
||||
}
|
||||
|
||||
InterestedMessage* PeerInteraction::createInterestedMessage() {
|
||||
InterestedMessage* msg = PeerMessageUtil::createInterestedMessage();
|
||||
InterestedMessage* msg = new InterestedMessage();
|
||||
setPeerMessageCommonProperty(msg);
|
||||
return msg;
|
||||
}
|
||||
|
||||
NotInterestedMessage* PeerInteraction::createNotInterestedMessage() {
|
||||
NotInterestedMessage* msg = PeerMessageUtil::createNotInterestedMessage();
|
||||
NotInterestedMessage* msg = new NotInterestedMessage();
|
||||
setPeerMessageCommonProperty(msg);
|
||||
return msg;
|
||||
}
|
||||
|
||||
BitfieldMessage* PeerInteraction::createBitfieldMessage() {
|
||||
BitfieldMessage* msg = PeerMessageUtil::createBitfieldMessage();
|
||||
BitfieldMessage* msg = new BitfieldMessage();
|
||||
msg->setBitfield(getTorrentMan()->getBitfield(),
|
||||
getTorrentMan()->getBitfieldLength());
|
||||
setPeerMessageCommonProperty(msg);
|
||||
return msg;
|
||||
}
|
||||
|
||||
KeepAliveMessage* PeerInteraction::createKeepAliveMessage() {
|
||||
KeepAliveMessage* msg = PeerMessageUtil::createKeepAliveMessage();
|
||||
KeepAliveMessage* msg = new KeepAliveMessage();
|
||||
setPeerMessageCommonProperty(msg);
|
||||
return msg;
|
||||
}
|
||||
|
||||
HaveAllMessage* PeerInteraction::createHaveAllMessage() {
|
||||
HaveAllMessage* msg = new HaveAllMessage();
|
||||
setPeerMessageCommonProperty(msg);
|
||||
return msg;
|
||||
}
|
||||
|
||||
HaveNoneMessage* PeerInteraction::createHaveNoneMessage() {
|
||||
HaveNoneMessage* msg = new HaveNoneMessage();
|
||||
setPeerMessageCommonProperty(msg);
|
||||
return msg;
|
||||
}
|
||||
|
||||
RejectMessage* PeerInteraction::createRejectMessage(int index, int begin, int length) {
|
||||
RejectMessage* msg = new RejectMessage();
|
||||
msg->setIndex(index);
|
||||
msg->setBegin(begin);
|
||||
msg->setLength(length);
|
||||
setPeerMessageCommonProperty(msg);
|
||||
return msg;
|
||||
}
|
||||
|
||||
AllowedFastMessage* PeerInteraction::createAllowedFastMessage(int index) {
|
||||
AllowedFastMessage* msg = new AllowedFastMessage();
|
||||
msg->setIndex(index);
|
||||
setPeerMessageCommonProperty(msg);
|
||||
return msg;
|
||||
}
|
||||
|
|
|
@ -36,9 +36,15 @@
|
|||
#include "HandshakeMessage.h"
|
||||
#include "KeepAliveMessage.h"
|
||||
#include "PortMessage.h"
|
||||
#include "HaveAllMessage.h"
|
||||
#include "HaveNoneMessage.h"
|
||||
#include "RejectMessage.h"
|
||||
#include "AllowedFastMessage.h"
|
||||
#include "SuggestPieceMessage.h"
|
||||
#include "RequestSlot.h"
|
||||
|
||||
#define REQUEST_TIME_OUT 120
|
||||
#define ALLOWED_FAST_SET_SIZE 10
|
||||
|
||||
typedef deque<RequestSlot> RequestSlots;
|
||||
typedef deque<PeerMessage*> MessageQueue;
|
||||
|
@ -54,17 +60,14 @@ private:
|
|||
PeerConnection* peerConnection;
|
||||
Peer* peer;
|
||||
Piece piece;
|
||||
// allowed fast piece indexes that local client has sent
|
||||
Integers fastSet;
|
||||
const Logger* logger;
|
||||
|
||||
Piece getNewPieceAndSendInterest();
|
||||
|
||||
void getNewPieceAndSendInterest();
|
||||
PeerMessage* createPeerMessage(const char* msg, int msgLength);
|
||||
HandshakeMessage* createHandshakeMessage(const char* msg, int msgLength);
|
||||
void send(int uploadSpeed);
|
||||
void setPeerMessageCommonProperty(PeerMessage* peerMessage);
|
||||
void deleteAllRequestSlot(Piece& piece);
|
||||
void deleteRequestMessageInQueue();
|
||||
void cancelAllRequest();
|
||||
void cancelAllRequest(Piece& piece);
|
||||
int countRequestSlot() const;
|
||||
public:
|
||||
PeerInteraction(int cuid,
|
||||
|
@ -75,12 +78,16 @@ public:
|
|||
~PeerInteraction();
|
||||
|
||||
void addMessage(PeerMessage* peerMessage);
|
||||
void deletePieceMessageInQueue(const CancelMessage* cancelMessage);
|
||||
|
||||
void rejectPieceMessageInQueue(int index, int begin, int length);
|
||||
void rejectAllPieceMessageInQueue();
|
||||
void onChoked();
|
||||
void abortPiece();
|
||||
|
||||
bool isSendingMessageInProgress() const;
|
||||
void deleteRequestSlot(const RequestSlot& requestSlot);
|
||||
void deleteTimeoutRequestSlot();
|
||||
void deleteCompletedRequestSlot();
|
||||
RequestSlot getCorrespondingRequestSlot(const PieceMessage* pieceMessage) const;
|
||||
RequestSlot getCorrespondingRequestSlot(int index, int begin, int length) const;
|
||||
|
||||
int countMessageInQueue() const;
|
||||
|
||||
|
@ -100,15 +107,16 @@ public:
|
|||
void setDownloadPiece(const Piece& piece) {
|
||||
this->piece = piece;
|
||||
}
|
||||
|
||||
bool isInFastSet(int index) const;
|
||||
void addFastSetIndex(int index);
|
||||
|
||||
void syncPiece();
|
||||
void addRequests();
|
||||
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();
|
||||
void sendBitfield();
|
||||
void sendAllowedFast();
|
||||
|
||||
PeerMessage* receiveMessage();
|
||||
HandshakeMessage* receiveHandshake();
|
||||
|
@ -123,6 +131,10 @@ public:
|
|||
NotInterestedMessage* createNotInterestedMessage();
|
||||
BitfieldMessage* createBitfieldMessage();
|
||||
KeepAliveMessage* createKeepAliveMessage();
|
||||
HaveAllMessage* createHaveAllMessage();
|
||||
HaveNoneMessage* createHaveNoneMessage();
|
||||
RejectMessage* createRejectMessage(int index, int begin, int length);
|
||||
AllowedFastMessage* createAllowedFastMessage(int index);
|
||||
};
|
||||
|
||||
#endif // _D_PEER_INTERACTION_H_
|
||||
|
|
|
@ -40,6 +40,7 @@ PeerInteractionCommand::PeerInteractionCommand(int cuid, Peer* peer,
|
|||
peerInteraction = new PeerInteraction(cuid, socket, e->option,
|
||||
e->torrentMan, this->peer);
|
||||
peerInteraction->setUploadLimit(e->option->getAsInt(PREF_UPLOAD_LIMIT));
|
||||
setUploadLimit(e->option->getAsInt(PREF_UPLOAD_LIMIT));
|
||||
keepAliveCheckPoint.tv_sec = 0;
|
||||
keepAliveCheckPoint.tv_usec = 0;
|
||||
chokeCheckPoint.tv_sec = 0;
|
||||
|
@ -65,6 +66,7 @@ bool PeerInteractionCommand::executeInternal() {
|
|||
setTimeout(e->option->getAsInt(PREF_TIMEOUT));
|
||||
}
|
||||
setWriteCheckSocket(NULL);
|
||||
setUploadLimitCheck(false);
|
||||
|
||||
switch(sequence) {
|
||||
case INITIATOR_SEND_HANDSHAKE:
|
||||
|
@ -72,6 +74,12 @@ bool PeerInteractionCommand::executeInternal() {
|
|||
sequence = INITIATOR_WAIT_HANDSHAKE;
|
||||
break;
|
||||
case INITIATOR_WAIT_HANDSHAKE: {
|
||||
if(peerInteraction->countMessageInQueue() > 0) {
|
||||
peerInteraction->sendMessages(e->getUploadSpeed());
|
||||
if(peerInteraction->countMessageInQueue() > 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
HandshakeMessage* handshakeMessage = peerInteraction->receiveHandshake();
|
||||
if(handshakeMessage == NULL) {
|
||||
break;
|
||||
|
@ -81,9 +89,8 @@ bool PeerInteractionCommand::executeInternal() {
|
|||
peer->ipaddr.c_str(), peer->port,
|
||||
handshakeMessage->toString().c_str());
|
||||
delete handshakeMessage;
|
||||
if(e->torrentMan->getDownloadLength() > 0) {
|
||||
peerInteraction->sendNow(peerInteraction->createBitfieldMessage());
|
||||
}
|
||||
peerInteraction->sendBitfield();
|
||||
peerInteraction->sendAllowedFast();
|
||||
sequence = WIRED;
|
||||
break;
|
||||
}
|
||||
|
@ -98,9 +105,8 @@ bool PeerInteractionCommand::executeInternal() {
|
|||
handshakeMessage->toString().c_str());
|
||||
delete handshakeMessage;
|
||||
peerInteraction->sendHandshake();
|
||||
if(e->torrentMan->getDownloadLength() > 0) {
|
||||
peerInteraction->sendNow(peerInteraction->createBitfieldMessage());
|
||||
}
|
||||
peerInteraction->sendBitfield();
|
||||
peerInteraction->sendAllowedFast();
|
||||
sequence = WIRED;
|
||||
break;
|
||||
}
|
||||
|
@ -115,11 +121,16 @@ bool PeerInteractionCommand::executeInternal() {
|
|||
}
|
||||
peerInteraction->deleteTimeoutRequestSlot();
|
||||
peerInteraction->deleteCompletedRequestSlot();
|
||||
peerInteraction->addRequests();
|
||||
peerInteraction->sendMessages(e->getUploadSpeed());
|
||||
break;
|
||||
}
|
||||
if(peerInteraction->countMessageInQueue() > 0) {
|
||||
setWriteCheckSocket(socket);
|
||||
if(peerInteraction->isSendingMessageInProgress()) {
|
||||
setWriteCheckSocket(socket);
|
||||
} else {
|
||||
setUploadLimitCheck(true);
|
||||
}
|
||||
}
|
||||
e->commands.push_back(this);
|
||||
return false;
|
||||
|
@ -246,7 +257,8 @@ void PeerInteractionCommand::keepAlive() {
|
|||
gettimeofday(&now, NULL);
|
||||
if(Util::difftv(now, keepAliveCheckPoint) >= (long long int)120*1000000) {
|
||||
if(peerInteraction->countMessageInQueue() == 0) {
|
||||
peerInteraction->sendNow(peerInteraction->createKeepAliveMessage());
|
||||
peerInteraction->addMessage(peerInteraction->createKeepAliveMessage());
|
||||
peerInteraction->sendMessages(e->getUploadSpeed());
|
||||
}
|
||||
keepAliveCheckPoint = now;
|
||||
}
|
||||
|
@ -261,10 +273,18 @@ void PeerInteractionCommand::beforeSocketCheck() {
|
|||
|
||||
PieceIndexes indexes = e->torrentMan->getAdvertisedPieceIndexes(cuid);
|
||||
if(indexes.size() >= 20) {
|
||||
peerInteraction->trySendNow(peerInteraction->createBitfieldMessage());
|
||||
if(peer->isFastExtensionEnabled()) {
|
||||
if(e->torrentMan->hasAllPieces()) {
|
||||
peerInteraction->addMessage(peerInteraction->createHaveAllMessage());
|
||||
} else {
|
||||
peerInteraction->addMessage(peerInteraction->createBitfieldMessage());
|
||||
}
|
||||
} else {
|
||||
peerInteraction->addMessage(peerInteraction->createBitfieldMessage());
|
||||
}
|
||||
} else {
|
||||
for(PieceIndexes::iterator itr = indexes.begin(); itr != indexes.end(); itr++) {
|
||||
peerInteraction->trySendNow(peerInteraction->createHaveMessage(*itr));
|
||||
peerInteraction->addMessage(peerInteraction->createHaveMessage(*itr));
|
||||
}
|
||||
}
|
||||
keepAlive();
|
||||
|
|
|
@ -40,162 +40,6 @@ int PeerMessageUtil::getShortIntParam(const char* msg, int offset) {
|
|||
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;
|
||||
}
|
||||
|
||||
RequestMessage* PeerMessageUtil::createRequestMessage(int index,
|
||||
int begin,
|
||||
int length,
|
||||
int blockIndex) {
|
||||
RequestMessage* msg = new RequestMessage();
|
||||
msg->setIndex(index);
|
||||
msg->setBegin(begin);
|
||||
msg->setLength(length);
|
||||
msg->setBlockIndex(blockIndex);
|
||||
return msg;
|
||||
}
|
||||
|
||||
CancelMessage* PeerMessageUtil::createCancelMessage(int index, int begin, int length) {
|
||||
CancelMessage* msg = new CancelMessage();
|
||||
msg->setIndex(index);
|
||||
msg->setBegin(begin);
|
||||
msg->setLength(length);
|
||||
return msg;
|
||||
}
|
||||
|
||||
PieceMessage* PeerMessageUtil::createPieceMessage(int index, int begin, int length) {
|
||||
PieceMessage* msg = new PieceMessage();
|
||||
msg->setIndex(index);
|
||||
msg->setBegin(begin);
|
||||
msg->setBlockLength(length);
|
||||
return msg;
|
||||
}
|
||||
|
||||
HaveMessage* PeerMessageUtil::createHaveMessage(int index) {
|
||||
HaveMessage* msg = new HaveMessage();
|
||||
msg->setIndex(index);
|
||||
return msg;
|
||||
}
|
||||
|
||||
ChokeMessage* PeerMessageUtil::createChokeMessage() {
|
||||
ChokeMessage* msg = new ChokeMessage();
|
||||
return msg;
|
||||
}
|
||||
|
||||
UnchokeMessage* PeerMessageUtil::createUnchokeMessage() {
|
||||
UnchokeMessage* msg = new UnchokeMessage();
|
||||
return msg;
|
||||
}
|
||||
|
||||
InterestedMessage* PeerMessageUtil::createInterestedMessage() {
|
||||
InterestedMessage* msg = new InterestedMessage();
|
||||
return msg;
|
||||
}
|
||||
|
||||
NotInterestedMessage* PeerMessageUtil::createNotInterestedMessage() {
|
||||
NotInterestedMessage* msg = new NotInterestedMessage();
|
||||
return msg;
|
||||
}
|
||||
|
||||
BitfieldMessage* PeerMessageUtil::createBitfieldMessage() {
|
||||
BitfieldMessage* msg = new BitfieldMessage();
|
||||
return msg;
|
||||
}
|
||||
|
||||
KeepAliveMessage* PeerMessageUtil::createKeepAliveMessage() {
|
||||
KeepAliveMessage* msg = new KeepAliveMessage();
|
||||
return msg;
|
||||
}
|
||||
|
||||
void PeerMessageUtil::checkIndex(int index, int pieces) {
|
||||
if(!(0 <= index && index < pieces)) {
|
||||
throw new DlAbortEx("invalid index = %d", index);
|
||||
|
@ -244,19 +88,6 @@ void PeerMessageUtil::checkBitfield(const unsigned char* bitfield, int bitfieldL
|
|||
}
|
||||
}
|
||||
|
||||
HandshakeMessage* PeerMessageUtil::createHandshakeMessage(const char* msg, int length) {
|
||||
HandshakeMessage* message = new HandshakeMessage();
|
||||
message->pstrlen = msg[0];
|
||||
char pstr[20];
|
||||
memcpy(pstr, &msg[1], sizeof(pstr)-1);
|
||||
pstr[sizeof(pstr)-1] = '\0';
|
||||
message->pstr = pstr;
|
||||
memcpy(message->infoHash, &msg[28], 20);
|
||||
memcpy(message->peerId, &msg[48], 20);
|
||||
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);
|
||||
|
@ -272,3 +103,16 @@ void PeerMessageUtil::checkHandshake(const HandshakeMessage* message, const unsi
|
|||
}
|
||||
}
|
||||
|
||||
void PeerMessageUtil::setIntParam(char* dest, int param) {
|
||||
int nParam = htonl(param);
|
||||
memcpy(dest, &nParam, 4);
|
||||
}
|
||||
|
||||
void PeerMessageUtil::createPeerMessageString(char* msg, int msgLength,
|
||||
int payloadLength,
|
||||
int messageId) {
|
||||
assert(msgLength >= 5);
|
||||
memset(msg, 0, msgLength);
|
||||
setIntParam(msg, payloadLength);
|
||||
msg[4] = (char)messageId;
|
||||
}
|
||||
|
|
|
@ -34,6 +34,8 @@
|
|||
#include "HandshakeMessage.h"
|
||||
#include "KeepAliveMessage.h"
|
||||
#include "PortMessage.h"
|
||||
#include "HaveAllMessage.h"
|
||||
#include "HaveNoneMessage.h"
|
||||
#include "PeerConnection.h"
|
||||
|
||||
#define MAX_BLOCK_LENGTH (128*1024)
|
||||
|
@ -41,36 +43,13 @@
|
|||
class PeerMessageUtil {
|
||||
private:
|
||||
PeerMessageUtil() {}
|
||||
|
||||
public:
|
||||
static int getIntParam(const char* msg, int offset);
|
||||
static int getShortIntParam(const char* msg, int offset);
|
||||
public:
|
||||
static void setIntParam(char* dest, int param);
|
||||
|
||||
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 ChokeMessage* createChokeMessage();
|
||||
static UnchokeMessage* createUnchokeMessage();
|
||||
static InterestedMessage* createInterestedMessage();
|
||||
static NotInterestedMessage* createNotInterestedMessage();
|
||||
static HaveMessage* createHaveMessage(int index);
|
||||
static BitfieldMessage* createBitfieldMessage();
|
||||
static RequestMessage* createRequestMessage(int index, int begin,
|
||||
int length, int blockIndex);
|
||||
static CancelMessage* createCancelMessage(int index, int begin, int length);
|
||||
static PieceMessage* createPieceMessage(int index, int begin, int length);
|
||||
static KeepAliveMessage* createKeepAliveMessage();
|
||||
|
||||
|
||||
static void checkIndex(int index, int pieces);
|
||||
static void checkBegin(int begin, int pieceLength);
|
||||
static void checkLength(int length);
|
||||
|
@ -79,9 +58,11 @@ public:
|
|||
int bitfieldLength,
|
||||
int pieces);
|
||||
|
||||
static HandshakeMessage* createHandshakeMessage(const char* msg, int length);
|
||||
static void checkHandshake(const HandshakeMessage* message,
|
||||
const unsigned char* infoHash);
|
||||
|
||||
static void createPeerMessageString(char* msg, int msgLength,
|
||||
int payloadLength, int messageId);
|
||||
};
|
||||
|
||||
#endif // _D_PEER_MESSAGE_UTIL_H_
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "PeerInteraction.h"
|
||||
#include "Util.h"
|
||||
#include "message.h"
|
||||
#include "DlAbortEx.h"
|
||||
|
||||
void PieceMessage::setBlock(const char* block, int blockLength) {
|
||||
if(this->block != NULL) {
|
||||
|
@ -34,16 +35,34 @@ void PieceMessage::setBlock(const char* block, int blockLength) {
|
|||
memcpy(this->block, block, this->blockLength);
|
||||
}
|
||||
|
||||
PieceMessage* PieceMessage::create(const char* data, int dataLength) {
|
||||
if(dataLength <= 9) {
|
||||
throw new DlAbortEx("invalid payload size for %s, size = %d. It should be greater than %d", "piece", dataLength, 9);
|
||||
}
|
||||
int id = PeerMessageUtil::getId(data);
|
||||
if(id != ID) {
|
||||
throw new DlAbortEx("invalid ID=%d for %s. It should be %d.",
|
||||
id, "piece", ID);
|
||||
}
|
||||
PieceMessage* pieceMessage = new PieceMessage();
|
||||
pieceMessage->setIndex(PeerMessageUtil::getIntParam(data, 1));
|
||||
pieceMessage->setBegin(PeerMessageUtil::getIntParam(data, 5));
|
||||
pieceMessage->setBlock(data+9, dataLength-9);
|
||||
return pieceMessage;
|
||||
}
|
||||
|
||||
void PieceMessage::receivedAction() {
|
||||
TorrentMan* torrentMan = peerInteraction->getTorrentMan();
|
||||
RequestSlot slot = peerInteraction->getCorrespondingRequestSlot(this);
|
||||
RequestSlot slot = peerInteraction->getCorrespondingRequestSlot(index,
|
||||
begin,
|
||||
blockLength);
|
||||
peer->addPeerUpload(blockLength);
|
||||
if(peerInteraction->hasDownloadPiece() &&
|
||||
!RequestSlot::isNull(slot)) {
|
||||
Piece& piece = peerInteraction->getDownloadPiece();
|
||||
long long int offset =
|
||||
((long long int)index)*torrentMan->pieceLength+begin;
|
||||
logger->debug("CUID#%d - write block length = %d, offset=%lld",
|
||||
logger->debug("CUID#%d - Writing the block length=%d, offset=%lld",
|
||||
cuid, blockLength, offset);
|
||||
torrentMan->diskAdaptor->writeData(block,
|
||||
blockLength,
|
||||
|
@ -51,7 +70,7 @@ void PieceMessage::receivedAction() {
|
|||
piece.completeBlock(slot.getBlockIndex());
|
||||
peerInteraction->deleteRequestSlot(slot);
|
||||
torrentMan->updatePiece(piece);
|
||||
logger->debug("CUID#%d - setting piece bit index=%d",
|
||||
logger->debug("CUID#%d - Setting piece block index=%d",
|
||||
cuid, slot.getBlockIndex());
|
||||
torrentMan->addDeltaDownloadLength(blockLength);
|
||||
if(piece.pieceComplete()) {
|
||||
|
@ -64,25 +83,95 @@ void PieceMessage::receivedAction() {
|
|||
}
|
||||
}
|
||||
|
||||
const char* PieceMessage::getMessageHeader() {
|
||||
if(!inProgress) {
|
||||
/**
|
||||
* len --- 9+blockLength, 4bytes
|
||||
* id --- 7, 1byte
|
||||
* index --- index, 4bytes
|
||||
* begin --- begin, 4bytes
|
||||
* total: 13bytes
|
||||
*/
|
||||
PeerMessageUtil::createPeerMessageString(msgHeader, sizeof(msgHeader),
|
||||
9+blockLength, ID);
|
||||
PeerMessageUtil::setIntParam(&msgHeader[5], index);
|
||||
PeerMessageUtil::setIntParam(&msgHeader[9], begin);
|
||||
}
|
||||
return msgHeader;
|
||||
}
|
||||
|
||||
int PieceMessage::getMessageHeaderLength() {
|
||||
return sizeof(msgHeader);
|
||||
}
|
||||
|
||||
void PieceMessage::send() {
|
||||
if((!peer->amChoking && peer->peerInterested) || inProgress) {
|
||||
PeerConnection* peerConnection = peerInteraction->getPeerConnection();
|
||||
TorrentMan* torrentMan = peerInteraction->getTorrentMan();
|
||||
PeerConnection* peerConnection = peerInteraction->getPeerConnection();
|
||||
if(!headerSent) {
|
||||
if(!inProgress) {
|
||||
peerConnection->sendPieceHeader(index, begin, blockLength);
|
||||
peer->addPeerDownload(blockLength);
|
||||
leftPieceDataLength = blockLength;
|
||||
}
|
||||
inProgress = false;
|
||||
int pieceLength = peerInteraction->getTorrentMan()->pieceLength;
|
||||
long long int pieceDataOffset =
|
||||
((long long int)index)*pieceLength+begin+blockLength-leftPieceDataLength;
|
||||
int writtenLength =
|
||||
peerConnection->sendPieceData(pieceDataOffset, leftPieceDataLength);
|
||||
if(writtenLength != leftPieceDataLength) {
|
||||
logger->info(MSG_SEND_PEER_MESSAGE,
|
||||
cuid, peer->ipaddr.c_str(), peer->port,
|
||||
toString().c_str());
|
||||
getMessageHeader();
|
||||
leftDataLength = getMessageHeaderLength();
|
||||
inProgress = true;
|
||||
leftPieceDataLength -= writtenLength;
|
||||
}
|
||||
int writtenLength
|
||||
= peerConnection->sendMessage(msgHeader+getMessageHeaderLength()-leftDataLength,
|
||||
leftDataLength);
|
||||
if(writtenLength == leftDataLength) {
|
||||
headerSent = true;
|
||||
leftDataLength = blockLength;
|
||||
} else {
|
||||
leftDataLength -= writtenLength;
|
||||
}
|
||||
}
|
||||
if(headerSent) {
|
||||
inProgress = false;
|
||||
int pieceLength = torrentMan->pieceLength;
|
||||
long long int pieceDataOffset =
|
||||
((long long int)index)*pieceLength+begin+blockLength-leftDataLength;
|
||||
int writtenLength =
|
||||
sendPieceData(pieceDataOffset, leftDataLength);
|
||||
peer->addPeerDownload(writtenLength);
|
||||
torrentMan->addUploadLength(writtenLength);
|
||||
torrentMan->addDeltaUploadLength(writtenLength);
|
||||
if(writtenLength != leftDataLength) {
|
||||
inProgress = true;
|
||||
}
|
||||
leftDataLength -= writtenLength;
|
||||
}
|
||||
}
|
||||
|
||||
int PieceMessage::sendPieceData(long long int offset, int length) const {
|
||||
int BUF_SIZE = 256;
|
||||
char buf[BUF_SIZE];
|
||||
int iteration = length/BUF_SIZE;
|
||||
int writtenLength = 0;
|
||||
TorrentMan* torrentMan = peerInteraction->getTorrentMan();
|
||||
PeerConnection* peerConnection = peerInteraction->getPeerConnection();
|
||||
for(int i = 0; i < iteration; i++) {
|
||||
if(torrentMan->diskAdaptor->readData(buf, BUF_SIZE, offset+i*BUF_SIZE) < BUF_SIZE) {
|
||||
throw new DlAbortEx("Failed to read data from disk.");
|
||||
}
|
||||
int ws = peerConnection->sendMessage(buf, BUF_SIZE);
|
||||
writtenLength += ws;
|
||||
if(ws != BUF_SIZE) {
|
||||
//logger->debug("CUID#%d - %d bytes written", cuid, writtenLength);
|
||||
return writtenLength;
|
||||
}
|
||||
}
|
||||
|
||||
int rem = length%BUF_SIZE;
|
||||
if(rem > 0) {
|
||||
if(torrentMan->diskAdaptor->readData(buf, rem, offset+iteration*BUF_SIZE) < rem) {
|
||||
throw new DlAbortEx("Failed to read data from disk.");
|
||||
}
|
||||
int ws = peerConnection->sendMessage(buf, rem);
|
||||
writtenLength += ws;
|
||||
}
|
||||
//logger->debug("CUID#%d - %d bytes written", cuid, writtenLength);
|
||||
return writtenLength;
|
||||
}
|
||||
|
||||
void PieceMessage::check() const {
|
||||
|
|
|
@ -31,19 +31,25 @@ private:
|
|||
int begin;
|
||||
char* block;
|
||||
int blockLength;
|
||||
int leftPieceDataLength;
|
||||
int leftDataLength;
|
||||
bool headerSent;
|
||||
int pendingCount;
|
||||
// for check
|
||||
int pieces;
|
||||
int pieceLength;
|
||||
|
||||
char msgHeader[13];
|
||||
|
||||
bool checkPieceHash(const Piece& piece);
|
||||
void onGotNewPiece(Piece& piece);
|
||||
void onGotWrongPiece(Piece& piece);
|
||||
void erasePieceOnDisk(const Piece& piece);
|
||||
int sendPieceData(long long int offset, int length) const;
|
||||
public:
|
||||
PieceMessage():PeerMessage(),
|
||||
index(0), begin(0), block(NULL), blockLength(0),
|
||||
leftPieceDataLength(0),
|
||||
leftDataLength(0), headerSent(false),
|
||||
pendingCount(0),
|
||||
pieces(0), pieceLength(0) {}
|
||||
|
||||
virtual ~PieceMessage() {
|
||||
|
@ -75,8 +81,15 @@ public:
|
|||
}
|
||||
int getPieceLength() const { return pieceLength;}
|
||||
|
||||
void incrementPendingCount() { pendingCount++; }
|
||||
bool isPendingCountMax() const { return pendingCount > 2; }
|
||||
|
||||
static PieceMessage* create(const char* data, int dataLength);
|
||||
|
||||
virtual int getId() const { return ID; }
|
||||
virtual void receivedAction();
|
||||
virtual const char* getMessageHeader();
|
||||
virtual int getMessageHeaderLength();
|
||||
virtual void send();
|
||||
virtual void check() const;
|
||||
virtual string toString() const;
|
||||
|
|
|
@ -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 "PortMessage.h"
|
||||
#include "PeerMessageUtil.h"
|
||||
#include "DlAbortEx.h"
|
||||
|
||||
PortMessage* PortMessage::create(const char* data, int dataLength) {
|
||||
if(dataLength != 3) {
|
||||
throw new DlAbortEx("invalid payload size for %s, size = %d. It should be %d", "port", dataLength, 3);
|
||||
}
|
||||
int id = PeerMessageUtil::getId(data);
|
||||
if(id != ID) {
|
||||
throw new DlAbortEx("invalid ID=%d for %s. It should be %d.",
|
||||
id, "piece", ID);
|
||||
}
|
||||
PortMessage* portMessage = new PortMessage();
|
||||
portMessage->setPort(PeerMessageUtil::getShortIntParam(data, 1));
|
||||
return portMessage;
|
||||
}
|
|
@ -39,14 +39,16 @@ public:
|
|||
void setPort(int port) { this->port = port; }
|
||||
|
||||
virtual int getId() const { return ID; }
|
||||
|
||||
static PortMessage* create(const char* data, int dataLength);
|
||||
|
||||
virtual void receivedAction() {
|
||||
logger->info("no DHT support right now.");
|
||||
logger->info("DHT is not supported yet.");
|
||||
}
|
||||
virtual void send() {}
|
||||
virtual string toString() const {
|
||||
return "port";
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif // _D_PORT_MESSAGE_H_
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
/* <!-- 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 "RejectMessage.h"
|
||||
#include "PeerInteraction.h"
|
||||
#include "PeerMessageUtil.h"
|
||||
#include "Util.h"
|
||||
#include "DlAbortEx.h"
|
||||
|
||||
RejectMessage* RejectMessage::create(const char* data, int dataLength) {
|
||||
if(dataLength != 13) {
|
||||
throw new DlAbortEx("invalid payload size for %s, size = %d. It should be %d", "reject", dataLength, 13);
|
||||
}
|
||||
int id = PeerMessageUtil::getId(data);
|
||||
if(id != ID) {
|
||||
throw new DlAbortEx("invalid ID=%d for %s. It should be %d.",
|
||||
id, "reject", ID);
|
||||
}
|
||||
RejectMessage* rejectMessage = new RejectMessage();
|
||||
rejectMessage->setIndex(PeerMessageUtil::getIntParam(data, 1));
|
||||
rejectMessage->setBegin(PeerMessageUtil::getIntParam(data, 5));
|
||||
rejectMessage->setLength(PeerMessageUtil::getIntParam(data, 9));
|
||||
return rejectMessage;
|
||||
}
|
||||
|
||||
void RejectMessage::receivedAction() {
|
||||
if(!peer->isFastExtensionEnabled()) {
|
||||
throw new DlAbortEx("%s received while fast extension is disabled",
|
||||
toString().c_str());
|
||||
}
|
||||
// TODO Current implementation does not close a connection even if
|
||||
// a request for this reject message is never sent.
|
||||
RequestSlot slot =
|
||||
peerInteraction->getCorrespondingRequestSlot(index, begin, length);
|
||||
if(RequestSlot::isNull(slot)) {
|
||||
//throw new DlAbortEx("reject recieved, but it is not in the request slots.");
|
||||
} else {
|
||||
peerInteraction->deleteRequestSlot(slot);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const char* RejectMessage::getMessage() {
|
||||
if(!inProgress) {
|
||||
/**
|
||||
* len --- 13, 4bytes
|
||||
* id --- 16, 1byte
|
||||
* index --- index, 4bytes
|
||||
* begin --- begin, 4bytes
|
||||
* length -- length, 4bytes
|
||||
* total: 17bytes
|
||||
*/
|
||||
PeerMessageUtil::createPeerMessageString(msg, sizeof(msg), 13, ID);
|
||||
PeerMessageUtil::setIntParam(&msg[5], index);
|
||||
PeerMessageUtil::setIntParam(&msg[9], begin);
|
||||
PeerMessageUtil::setIntParam(&msg[13], length);
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
int RejectMessage::getMessageLength() {
|
||||
return sizeof(msg);
|
||||
}
|
||||
|
||||
void RejectMessage::check() const {
|
||||
PeerMessageUtil::checkIndex(index, pieces);
|
||||
PeerMessageUtil::checkBegin(begin, pieceLength);
|
||||
PeerMessageUtil::checkLength(length);
|
||||
PeerMessageUtil::checkRange(begin, length, pieceLength);
|
||||
}
|
||||
|
||||
string RejectMessage::toString() const {
|
||||
return "reject index="+Util::itos(index)+", begin="+Util::itos(begin)+
|
||||
", length="+Util::itos(length);
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
/* <!-- 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_REJECT_MESSAGE_H_
|
||||
#define _D_REJECT_MESSAGE_H_
|
||||
|
||||
#include "SimplePeerMessage.h"
|
||||
#include "TorrentMan.h"
|
||||
|
||||
class RejectMessage : public SimplePeerMessage {
|
||||
private:
|
||||
int index;
|
||||
int begin;
|
||||
int length;
|
||||
// for check
|
||||
int pieces;
|
||||
int pieceLength;
|
||||
|
||||
char msg[17];
|
||||
public:
|
||||
RejectMessage():SimplePeerMessage(),
|
||||
index(0), begin(0), length(0),
|
||||
pieces(0), pieceLength(0) {}
|
||||
|
||||
virtual ~RejectMessage() {}
|
||||
|
||||
enum ID {
|
||||
ID = 16
|
||||
};
|
||||
|
||||
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;}
|
||||
|
||||
static RejectMessage* create(const char* data, int dataLength);
|
||||
|
||||
virtual int getId() const { return ID; }
|
||||
virtual void receivedAction();
|
||||
virtual const char* getMessage();
|
||||
virtual int getMessageLength();
|
||||
virtual void check() const;
|
||||
virtual string toString() const;
|
||||
};
|
||||
|
||||
#endif // _D_REJECT_MESSAGE_H_
|
|
@ -23,20 +23,57 @@
|
|||
#include "PeerInteraction.h"
|
||||
#include "PeerMessageUtil.h"
|
||||
#include "Util.h"
|
||||
#include "DlAbortEx.h"
|
||||
|
||||
RequestMessage* RequestMessage::create(const char* data, int dataLength) {
|
||||
if(dataLength != 13) {
|
||||
throw new DlAbortEx("invalid payload size for %s, size = %d. It should be %d", "request", dataLength, 13);
|
||||
}
|
||||
int id = PeerMessageUtil::getId(data);
|
||||
if(id != ID) {
|
||||
throw new DlAbortEx("invalid ID=%d for %s. It should be %d.",
|
||||
id, "request", ID);
|
||||
}
|
||||
RequestMessage* requestMessage = new RequestMessage();
|
||||
requestMessage->setIndex(PeerMessageUtil::getIntParam(data, 1));
|
||||
requestMessage->setBegin(PeerMessageUtil::getIntParam(data, 5));
|
||||
requestMessage->setLength(PeerMessageUtil::getIntParam(data, 9));
|
||||
return requestMessage;
|
||||
}
|
||||
|
||||
void RequestMessage::receivedAction() {
|
||||
TorrentMan* torrentMan = peerInteraction->getTorrentMan();
|
||||
if(torrentMan->hasPiece(index)) {
|
||||
if(torrentMan->hasPiece(index) &&
|
||||
(!peer->amChoking ||
|
||||
peer->amChoking && peerInteraction->isInFastSet(index))) {
|
||||
peerInteraction->addMessage(peerInteraction->createPieceMessage(index, begin, length));
|
||||
torrentMan->addUploadLength(length);
|
||||
torrentMan->addDeltaUploadLength(length);
|
||||
} else {
|
||||
if(peer->isFastExtensionEnabled()) {
|
||||
peerInteraction->addMessage(peerInteraction->createRejectMessage(index, begin, length));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RequestMessage::send() {
|
||||
if(!peer->peerChoking) {
|
||||
peerInteraction->getPeerConnection()->sendRequest(index, begin, length);
|
||||
const char* RequestMessage::getMessage() {
|
||||
if(!inProgress) {
|
||||
/**
|
||||
* len --- 13, 4bytes
|
||||
* id --- 6, 1byte
|
||||
* index --- index, 4bytes
|
||||
* begin --- begin, 4bytes
|
||||
* length --- length, 4bytes
|
||||
* total: 17bytes
|
||||
*/
|
||||
PeerMessageUtil::createPeerMessageString(msg, sizeof(msg), 13, ID);
|
||||
PeerMessageUtil::setIntParam(&msg[5], index);
|
||||
PeerMessageUtil::setIntParam(&msg[9], begin);
|
||||
PeerMessageUtil::setIntParam(&msg[13], length);
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
int RequestMessage::getMessageLength() {
|
||||
return sizeof(msg);
|
||||
}
|
||||
|
||||
void RequestMessage::check() const {
|
||||
|
|
|
@ -22,10 +22,10 @@
|
|||
#ifndef _D_REQUEST_MESSAGE_H_
|
||||
#define _D_REQUEST_MESSAGE_H_
|
||||
|
||||
#include "PeerMessage.h"
|
||||
#include "SimplePeerMessage.h"
|
||||
#include "TorrentMan.h"
|
||||
|
||||
class RequestMessage : public PeerMessage {
|
||||
class RequestMessage : public SimplePeerMessage {
|
||||
private:
|
||||
int index;
|
||||
int begin;
|
||||
|
@ -34,8 +34,10 @@ private:
|
|||
// for check
|
||||
int pieces;
|
||||
int pieceLength;
|
||||
|
||||
char msg[17];
|
||||
public:
|
||||
RequestMessage():PeerMessage(),
|
||||
RequestMessage():SimplePeerMessage(),
|
||||
index(0), begin(0), length(0), blockIndex(0),
|
||||
pieces(0), pieceLength(0) {}
|
||||
virtual ~RequestMessage() {}
|
||||
|
@ -63,9 +65,12 @@ public:
|
|||
}
|
||||
int getPieceLength() const { return pieceLength;}
|
||||
|
||||
static RequestMessage* create(const char* data, int dataLength);
|
||||
|
||||
virtual int getId() const { return ID; }
|
||||
virtual void receivedAction();
|
||||
virtual void send();
|
||||
virtual const char* getMessage();
|
||||
virtual int getMessageLength();
|
||||
virtual void check() const;
|
||||
virtual string toString() const;
|
||||
};
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
/* <!-- 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 "SuggestPieceMessage.h"
|
||||
#include "PeerInteraction.h"
|
||||
#include "PeerMessageUtil.h"
|
||||
#include "Util.h"
|
||||
#include "DlAbortEx.h"
|
||||
|
||||
SuggestPieceMessage* SuggestPieceMessage::create(const char* data, int dataLength) {
|
||||
if(dataLength != 5) {
|
||||
throw new DlAbortEx("invalid payload size for %s, size = %d. It should be %d", "suggest piece", dataLength, 5);
|
||||
}
|
||||
int id = PeerMessageUtil::getId(data);
|
||||
if(id != ID) {
|
||||
throw new DlAbortEx("invalid ID=%d for %s. It should be %d.",
|
||||
id, "suggest piece", ID);
|
||||
}
|
||||
SuggestPieceMessage* suggestPieceMessage = new SuggestPieceMessage();
|
||||
suggestPieceMessage->setIndex(PeerMessageUtil::getIntParam(data, 1));
|
||||
return suggestPieceMessage;
|
||||
}
|
||||
|
||||
void SuggestPieceMessage::receivedAction() {
|
||||
// TODO Current implementation ignores this message.
|
||||
}
|
||||
|
||||
const char* SuggestPieceMessage::getMessage() {
|
||||
if(!inProgress) {
|
||||
/**
|
||||
* len --- 5, 4bytes
|
||||
* id --- 13, 1byte
|
||||
* piece index --- index, 4bytes
|
||||
* total: 9bytes
|
||||
*/
|
||||
PeerMessageUtil::createPeerMessageString(msg, sizeof(msg), 5, ID);
|
||||
PeerMessageUtil::setIntParam(&msg[5], index);
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
int SuggestPieceMessage::getMessageLength() {
|
||||
return sizeof(msg);
|
||||
}
|
||||
|
||||
void SuggestPieceMessage::check() const {
|
||||
PeerMessageUtil::checkIndex(index, pieces);
|
||||
}
|
||||
|
||||
string SuggestPieceMessage::toString() const {
|
||||
return "suggest piece index="+Util::itos(index);
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
/* <!-- 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_SUGGEST_PIECE_MESSAGE_H_
|
||||
#define _D_SUGGEST_PIECE_MESSAGE_H_
|
||||
|
||||
#include "SimplePeerMessage.h"
|
||||
|
||||
class SuggestPieceMessage : public SimplePeerMessage {
|
||||
private:
|
||||
int index;
|
||||
// for check
|
||||
int pieces;
|
||||
char msg[9];
|
||||
public:
|
||||
SuggestPieceMessage():SimplePeerMessage(), index(0), pieces(0) {}
|
||||
|
||||
virtual ~SuggestPieceMessage() {}
|
||||
|
||||
enum ID {
|
||||
ID = 13
|
||||
};
|
||||
|
||||
void setIndex(int index) {
|
||||
this->index = index;
|
||||
}
|
||||
int getIndex() const { return index; }
|
||||
|
||||
void setPieces(int pieces) {
|
||||
this->pieces = pieces;
|
||||
}
|
||||
int getPieces() const { return pieces;}
|
||||
|
||||
static SuggestPieceMessage* create(const char* data, int dataLength);
|
||||
|
||||
virtual int getId() const { return ID; }
|
||||
virtual void receivedAction();
|
||||
virtual const char* getMessage();
|
||||
virtual int getMessageLength();
|
||||
virtual void check() const;
|
||||
virtual string toString() const;
|
||||
};
|
||||
|
||||
#endif // _D_SUGGEST_PIECE_MESSAGE_H_
|
|
@ -147,10 +147,30 @@ bool TorrentMan::isEndGame() const {
|
|||
|
||||
Piece TorrentMan::getMissingPiece(const Peer* peer) {
|
||||
int index = -1;
|
||||
if(isEndGame()) {
|
||||
index = bitfield->getMissingIndex(peer->getBitfield(), peer->getBitfieldLength());
|
||||
} else {
|
||||
index = bitfield->getMissingUnusedIndex(peer->getBitfield(), peer->getBitfieldLength());
|
||||
if(peer->isFastExtensionEnabled() && peer->countFastSet() > 0) {
|
||||
BitfieldMan tempBitfield(pieceLength, totalLength);
|
||||
for(Integers::const_iterator itr = peer->getFastSet().begin();
|
||||
itr != peer->getFastSet().end(); itr++) {
|
||||
if(!hasPiece(*itr) && peer->hasPiece(*itr)) {
|
||||
tempBitfield.setBit(*itr);
|
||||
}
|
||||
}
|
||||
if(isEndGame()) {
|
||||
index = bitfield->getMissingIndex(tempBitfield.getBitfield(),
|
||||
tempBitfield.getBitfieldLength());
|
||||
} else {
|
||||
index = bitfield->getMissingUnusedIndex(tempBitfield.getBitfield(),
|
||||
tempBitfield.getBitfieldLength());
|
||||
}
|
||||
}
|
||||
if(index == -1) {
|
||||
if(isEndGame()) {
|
||||
index = bitfield->getMissingIndex(peer->getBitfield(),
|
||||
peer->getBitfieldLength());
|
||||
} else {
|
||||
index = bitfield->getMissingUnusedIndex(peer->getBitfield(),
|
||||
peer->getBitfieldLength());
|
||||
}
|
||||
}
|
||||
if(index == -1) {
|
||||
return Piece::nullPiece;
|
||||
|
@ -248,6 +268,7 @@ void TorrentMan::cancelPiece(const Piece& piece) {
|
|||
if(Piece::isNull(piece)) {
|
||||
return;
|
||||
}
|
||||
updatePiece(piece);
|
||||
bitfield->unsetUseBit(piece.getIndex());
|
||||
if(!isEndGame()) {
|
||||
if(piece.countCompleteBlock() == 0) {
|
||||
|
@ -303,6 +324,10 @@ bool TorrentMan::downloadComplete() const {
|
|||
return bitfield->isAllBitSet();
|
||||
}
|
||||
|
||||
bool TorrentMan::hasAllPieces() const {
|
||||
return bitfield->getTotalLength() == downloadLength;
|
||||
}
|
||||
|
||||
void TorrentMan::readFileEntry(FileEntries& fileEntries, Directory** pTopDir, const Dictionary* infoDic, const string& defaultName) {
|
||||
Data* topName = (Data*)infoDic->get("name");
|
||||
if(topName != NULL) {
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
using namespace std;
|
||||
|
||||
#define INFO_HASH_LENGTH 20
|
||||
#define PEER_ID_LENGTH 20
|
||||
#define DEFAULT_ANNOUNCE_INTERVAL 300
|
||||
#define DEFAULT_ANNOUNCE_MIN_INTERVAL 300
|
||||
#define MAX_PEERS 55
|
||||
|
@ -93,6 +94,7 @@ private:
|
|||
public:
|
||||
int pieceLength;
|
||||
int pieces;
|
||||
// TODO type char* would be better
|
||||
string peerId;
|
||||
string announce;
|
||||
string trackerId;
|
||||
|
@ -133,6 +135,7 @@ public:
|
|||
void initBitfield();
|
||||
bool isEndGame() const;
|
||||
bool downloadComplete() const;
|
||||
bool hasAllPieces() const;
|
||||
void setBitfield(unsigned char* bitfield, int len);
|
||||
const unsigned char* getBitfield() const {
|
||||
return bitfield->getBitfield();
|
||||
|
|
|
@ -99,17 +99,19 @@ bool TrackerUpdateCommand::execute() {
|
|||
Data* trackerId = (Data*)response->get("tracker id");
|
||||
if(trackerId != NULL) {
|
||||
e->torrentMan->trackerId = trackerId->toString();
|
||||
logger->debug("Tracker ID:%s", e->torrentMan->trackerId.c_str());
|
||||
logger->debug("CUID#%d - Tracker ID:%s",
|
||||
cuid, e->torrentMan->trackerId.c_str());
|
||||
}
|
||||
Data* interval = (Data*)response->get("interval");
|
||||
if(interval != NULL) {
|
||||
e->torrentMan->interval = interval->toInt();
|
||||
logger->debug("interval:%d", e->torrentMan->interval);
|
||||
logger->debug("CUID#%d - Interval:%d", cuid, e->torrentMan->interval);
|
||||
}
|
||||
Data* minInterval = (Data*)response->get("min interval");
|
||||
if(minInterval != NULL) {
|
||||
e->torrentMan->minInterval = minInterval->toInt();
|
||||
logger->debug("min interval:%d", e->torrentMan->minInterval);
|
||||
logger->debug("CUID#%d - Min interval:%d",
|
||||
cuid, e->torrentMan->minInterval);
|
||||
}
|
||||
if(e->torrentMan->minInterval > e->torrentMan->interval) {
|
||||
e->torrentMan->minInterval = e->torrentMan->interval;
|
||||
|
@ -117,12 +119,13 @@ bool TrackerUpdateCommand::execute() {
|
|||
Data* complete = (Data*)response->get("complete");
|
||||
if(complete != NULL) {
|
||||
e->torrentMan->complete = complete->toInt();
|
||||
logger->debug("complete:%d", e->torrentMan->complete);
|
||||
logger->debug("CUID#%d - Complete:%d", cuid, e->torrentMan->complete);
|
||||
}
|
||||
Data* incomplete = (Data*)response->get("incomplete");
|
||||
if(incomplete != NULL) {
|
||||
e->torrentMan->incomplete = incomplete->toInt();
|
||||
logger->debug("incomplete:%d", e->torrentMan->incomplete);
|
||||
logger->debug("CUID#%d - Incomplete:%d",
|
||||
cuid, e->torrentMan->incomplete);
|
||||
}
|
||||
Data* peers = (Data*)response->get("peers");
|
||||
if(peers != NULL) {
|
||||
|
@ -139,13 +142,14 @@ bool TrackerUpdateCommand::execute() {
|
|||
Peer* peer = new Peer(ipaddr, port, e->torrentMan->pieceLength,
|
||||
e->torrentMan->getTotalLength());
|
||||
if(e->torrentMan->addPeer(peer)) {
|
||||
logger->debug("adding peer %s:%d", peer->ipaddr.c_str(), peer->port);
|
||||
logger->debug("CUID#%d - Adding peer %s:%d",
|
||||
cuid, peer->ipaddr.c_str(), peer->port);
|
||||
} else {
|
||||
delete peer;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
logger->info("no peer list received.");
|
||||
logger->info("CUID#%d - No peer list received.", cuid);
|
||||
}
|
||||
while(e->torrentMan->isPeerAvailable() &&
|
||||
e->torrentMan->connections < MAX_PEER_UPDATE) {
|
||||
|
@ -154,7 +158,7 @@ bool TrackerUpdateCommand::execute() {
|
|||
peer->cuid = newCuid;
|
||||
PeerInitiateConnectionCommand* command = new PeerInitiateConnectionCommand(newCuid, peer, e);
|
||||
e->commands.push_back(command);
|
||||
logger->debug("adding new command CUID#%d", newCuid);
|
||||
logger->debug("CUID#%d - Adding new command CUID#%d", cuid, newCuid);
|
||||
}
|
||||
if(e->torrentMan->req->getTrackerEvent() == Request::STARTED) {
|
||||
e->torrentMan->req->setTrackerEvent(Request::AUTO);
|
||||
|
|
|
@ -25,16 +25,27 @@
|
|||
#include "Util.h"
|
||||
|
||||
TrackerWatcherCommand::TrackerWatcherCommand(int cuid,
|
||||
TorrentDownloadEngine* e):
|
||||
Command(cuid), e(e) {
|
||||
TorrentDownloadEngine* e,
|
||||
int interval):
|
||||
Command(cuid), e(e), interval(interval) {
|
||||
checkPoint.tv_sec = 0;
|
||||
checkPoint.tv_usec = 0;
|
||||
}
|
||||
|
||||
TrackerWatcherCommand::~TrackerWatcherCommand() {}
|
||||
|
||||
bool TrackerWatcherCommand::execute() {
|
||||
if(e->torrentMan->trackers == 0 && e->torrentMan->connections < MIN_PEERS) {
|
||||
struct timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
|
||||
if(e->torrentMan->trackers == 0 &&
|
||||
Util::difftvsec(now, checkPoint) >= interval) {
|
||||
checkPoint = now;
|
||||
e->torrentMan->req->resetTryCount();
|
||||
|
||||
int numWant = 50;
|
||||
if(e->torrentMan->connections >= MIN_PEERS) {
|
||||
numWant = 0;
|
||||
}
|
||||
if(e->torrentMan->downloadComplete()) {
|
||||
if(e->torrentMan->req->getTrackerEvent() == Request::COMPLETED) {
|
||||
e->torrentMan->req->setTrackerEvent(Request::AFTER_COMPLETED);
|
||||
|
@ -67,7 +78,8 @@ bool TrackerWatcherCommand::execute() {
|
|||
"left="+(e->torrentMan->getTotalLength()-e->torrentMan->getDownloadLength() <= 0
|
||||
? "0" : Util::llitos(e->torrentMan->getTotalLength()-e->torrentMan->getDownloadLength()))+"&"+
|
||||
"compact=1"+"&"+
|
||||
"key="+e->torrentMan->peerId;
|
||||
"key="+e->torrentMan->peerId+"&"+
|
||||
"numwant="+Util::itos(numWant);
|
||||
if(!event.empty()) {
|
||||
url += string("&")+"event="+event;
|
||||
}
|
||||
|
@ -81,8 +93,7 @@ bool TrackerWatcherCommand::execute() {
|
|||
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_back(slpCommand);
|
||||
interval = e->torrentMan->minInterval;
|
||||
e->commands.push_back(this);
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -24,14 +24,17 @@
|
|||
|
||||
#include "Command.h"
|
||||
#include "TorrentDownloadEngine.h"
|
||||
#include <sys/time.h>
|
||||
|
||||
#define MIN_PEERS 15
|
||||
|
||||
class TrackerWatcherCommand : public Command {
|
||||
private:
|
||||
TorrentDownloadEngine* e;
|
||||
int interval;
|
||||
struct timeval checkPoint;
|
||||
public:
|
||||
TrackerWatcherCommand(int cuid, TorrentDownloadEngine* e);
|
||||
TrackerWatcherCommand(int cuid, TorrentDownloadEngine* e, int interval);
|
||||
~TrackerWatcherCommand();
|
||||
|
||||
bool execute();
|
||||
|
|
|
@ -21,16 +21,48 @@
|
|||
/* copyright --> */
|
||||
#include "UnchokeMessage.h"
|
||||
#include "PeerInteraction.h"
|
||||
#include "PeerMessageUtil.h"
|
||||
#include "DlAbortEx.h"
|
||||
|
||||
UnchokeMessage* UnchokeMessage::create(const char* data, int dataLength) {
|
||||
if(dataLength != 1) {
|
||||
throw new DlAbortEx("invalid payload size for %s, size = %d. It should be %d", "unchoke", dataLength, 1);
|
||||
}
|
||||
int id = PeerMessageUtil::getId(data);
|
||||
if(id != ID) {
|
||||
throw new DlAbortEx("invalid ID=%d for %s. It should be %d.",
|
||||
id, "unchoke", ID);
|
||||
}
|
||||
UnchokeMessage* unchokeMessage = new UnchokeMessage();
|
||||
return unchokeMessage;
|
||||
}
|
||||
|
||||
void UnchokeMessage::receivedAction() {
|
||||
peer->peerChoking = false;
|
||||
}
|
||||
|
||||
void UnchokeMessage::send() {
|
||||
if(peer->amChoking) {
|
||||
peerInteraction->getPeerConnection()->sendUnchoke();
|
||||
peer->amChoking = false;
|
||||
bool UnchokeMessage::sendPredicate() const {
|
||||
return peer->amChoking;
|
||||
}
|
||||
|
||||
const char* UnchokeMessage::getMessage() {
|
||||
if(!inProgress) {
|
||||
/**
|
||||
* len --- 1, 4bytes
|
||||
* id --- 1, 1byte
|
||||
* total: 5bytes
|
||||
*/
|
||||
PeerMessageUtil::createPeerMessageString(msg, sizeof(msg), 1, ID);
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
int UnchokeMessage::getMessageLength() {
|
||||
return sizeof(msg);
|
||||
}
|
||||
|
||||
void UnchokeMessage::onSendComplete() {
|
||||
peer->amChoking = false;
|
||||
}
|
||||
|
||||
string UnchokeMessage::toString() const {
|
||||
|
|
|
@ -22,21 +22,28 @@
|
|||
#ifndef _D_UNCHOKE_MESSAGE_H_
|
||||
#define _D_UNCHOKE_MESSAGE_H_
|
||||
|
||||
#include "PeerMessage.h"
|
||||
#include "SimplePeerMessage.h"
|
||||
|
||||
class UnchokeMessage : public PeerMessage {
|
||||
class UnchokeMessage : public SimplePeerMessage {
|
||||
private:
|
||||
char msg[5];
|
||||
protected:
|
||||
virtual bool sendPredicate() const;
|
||||
virtual void onSendComplete();
|
||||
public:
|
||||
UnchokeMessage():PeerMessage() {}
|
||||
UnchokeMessage():SimplePeerMessage() {}
|
||||
virtual ~UnchokeMessage() {}
|
||||
|
||||
enum ID {
|
||||
ID = 1
|
||||
};
|
||||
|
||||
static UnchokeMessage* create(const char* data, int dataLength);
|
||||
|
||||
virtual int getId() const { return ID; }
|
||||
virtual void receivedAction();
|
||||
virtual void send();
|
||||
|
||||
virtual const char* getMessage();
|
||||
virtual int getMessageLength();
|
||||
virtual string toString() const;
|
||||
};
|
||||
|
||||
|
|
55
src/Util.cc
55
src/Util.cc
|
@ -23,10 +23,17 @@
|
|||
#include "DlAbortEx.h"
|
||||
#include "File.h"
|
||||
#include "message.h"
|
||||
#ifdef ENABLE_SHA1DIGEST
|
||||
#include "messageDigest.h"
|
||||
#endif // ENABLE_SHA1DIGEST
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
string Util::itos(int value, bool comma) {
|
||||
string str = llitos(value, comma);
|
||||
|
@ -355,3 +362,51 @@ string Util::getContentDispositionFilename(const string& header) {
|
|||
}
|
||||
return trim(header.substr(filenamesp, filenameep-filenamesp));
|
||||
}
|
||||
|
||||
void Util::sha1Sum(unsigned char* digest, const void* data, int dataLength) {
|
||||
#ifdef ENABLE_SHA1DIGEST
|
||||
MessageDigestContext ctx;
|
||||
sha1DigestInit(ctx);
|
||||
sha1DigestReset(ctx);
|
||||
sha1DigestUpdate(ctx, data, dataLength);
|
||||
sha1DigestFinal(ctx, digest);
|
||||
sha1DigestFree(ctx);
|
||||
#endif // ENABLE_SHA1DIGEST
|
||||
}
|
||||
|
||||
Integers Util::computeFastSet(string ipaddr, const unsigned char* infoHash,
|
||||
int pieces, int fastSetSize) {
|
||||
Integers fastSet;
|
||||
struct in_addr saddr;
|
||||
if(inet_aton(ipaddr.c_str(), &saddr) == 0) {
|
||||
abort();
|
||||
}
|
||||
unsigned char tx[24];
|
||||
memcpy(tx, (void*)&saddr.s_addr, 4);
|
||||
if((tx[0] & 0x80) == 0 || (tx[0] & 0x40) == 0) {
|
||||
tx[2] = 0x00;
|
||||
tx[3] = 0x00;
|
||||
} else {
|
||||
tx[3] = 0x00;
|
||||
}
|
||||
memcpy(tx+4, infoHash, 20);
|
||||
unsigned char x[20];
|
||||
sha1Sum(x, tx, 24);
|
||||
while((int)fastSet.size() < fastSetSize) {
|
||||
for(int i = 0; i < 5 && (int)fastSet.size() < fastSetSize; i++) {
|
||||
int j = i*4;
|
||||
unsigned int ny;
|
||||
memcpy(&ny, x+j, 4);
|
||||
unsigned int y = ntohl(ny);
|
||||
int index = y%pieces;
|
||||
if(find(fastSet.begin(), fastSet.end(), index) == fastSet.end()) {
|
||||
fastSet.push_back(index);
|
||||
}
|
||||
}
|
||||
unsigned char temp[20];
|
||||
sha1Sum(temp, x, 20);
|
||||
memcpy(x, temp, sizeof(x));
|
||||
}
|
||||
return fastSet;
|
||||
}
|
||||
|
||||
|
|
|
@ -78,6 +78,12 @@ public:
|
|||
|
||||
// this function temporarily put here
|
||||
static string getContentDispositionFilename(const string& header);
|
||||
|
||||
// digest must be at least 20 bytes long.
|
||||
static void sha1Sum(unsigned char* digest, const void* data, int dataLength);
|
||||
|
||||
static Integers computeFastSet(string ipaddr, const unsigned char* infoHash,
|
||||
int pieces, int fastSetSize);
|
||||
};
|
||||
|
||||
#endif // _D_UTIL_H_
|
||||
|
|
|
@ -704,7 +704,8 @@ int main(int argc, char* argv[]) {
|
|||
te->torrentMan->setPort(port);
|
||||
te->commands.push_back(listenCommand);
|
||||
te->commands.push_back(new TrackerWatcherCommand(te->torrentMan->getNewCuid(),
|
||||
te));
|
||||
te,
|
||||
te->torrentMan->minInterval));
|
||||
te->commands.push_back(new TrackerUpdateCommand(te->torrentMan->getNewCuid(),
|
||||
te));
|
||||
te->commands.push_back(new TorrentAutoSaveCommand(te->torrentMan->getNewCuid(),
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
#include "AllowedFastMessage.h"
|
||||
#include "PeerMessageUtil.h"
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class AllowedFastMessageTest:public CppUnit::TestFixture {
|
||||
|
||||
CPPUNIT_TEST_SUITE(AllowedFastMessageTest);
|
||||
CPPUNIT_TEST(testCreate);
|
||||
CPPUNIT_TEST(testGetMessage);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
private:
|
||||
|
||||
public:
|
||||
void setUp() {
|
||||
}
|
||||
|
||||
void testCreate();
|
||||
void testGetMessage();
|
||||
};
|
||||
|
||||
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION(AllowedFastMessageTest);
|
||||
|
||||
void AllowedFastMessageTest::testCreate() {
|
||||
char msg[9];
|
||||
PeerMessageUtil::createPeerMessageString(msg, sizeof(msg), 5, 17);
|
||||
PeerMessageUtil::setIntParam(&msg[5], 12345);
|
||||
AllowedFastMessage* pm = AllowedFastMessage::create(&msg[4], 5);
|
||||
CPPUNIT_ASSERT_EQUAL(17, pm->getId());
|
||||
CPPUNIT_ASSERT_EQUAL(12345, pm->getIndex());
|
||||
|
||||
// case: payload size is wrong
|
||||
try {
|
||||
char msg[10];
|
||||
PeerMessageUtil::createPeerMessageString(msg, sizeof(msg), 6, 17);
|
||||
AllowedFastMessage::create(&msg[4], 6);
|
||||
CPPUNIT_FAIL("exception must be threw.");
|
||||
} catch(...) {
|
||||
}
|
||||
// case: id is wrong
|
||||
try {
|
||||
char msg[9];
|
||||
PeerMessageUtil::createPeerMessageString(msg, sizeof(msg), 5, 18);
|
||||
AllowedFastMessage::create(&msg[4], 5);
|
||||
CPPUNIT_FAIL("exception must be threw.");
|
||||
} catch(...) {
|
||||
}
|
||||
}
|
||||
|
||||
void AllowedFastMessageTest::testGetMessage() {
|
||||
AllowedFastMessage msg;
|
||||
msg.setIndex(12345);
|
||||
char data[9];
|
||||
PeerMessageUtil::createPeerMessageString(data, sizeof(data), 5, 17);
|
||||
PeerMessageUtil::setIntParam(&data[5], 12345);
|
||||
CPPUNIT_ASSERT(memcmp(msg.getMessage(), data, 9) == 0);
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
#include "BitfieldMessage.h"
|
||||
#include "PeerMessageUtil.h"
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class BitfieldMessageTest:public CppUnit::TestFixture {
|
||||
|
||||
CPPUNIT_TEST_SUITE(BitfieldMessageTest);
|
||||
CPPUNIT_TEST(testCreate);
|
||||
CPPUNIT_TEST(testGetMessage);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
private:
|
||||
|
||||
public:
|
||||
void setUp() {
|
||||
}
|
||||
|
||||
void testCreate();
|
||||
void testGetMessage();
|
||||
};
|
||||
|
||||
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION(BitfieldMessageTest);
|
||||
|
||||
void BitfieldMessageTest::testCreate() {
|
||||
char msg[5+2];
|
||||
PeerMessageUtil::createPeerMessageString(msg, sizeof(msg), 3, 5);
|
||||
unsigned char bitfield[2];
|
||||
memset(bitfield, 0xff, sizeof(bitfield));
|
||||
memcpy(&msg[5], bitfield, sizeof(bitfield));
|
||||
BitfieldMessage* pm = BitfieldMessage::create(&msg[4], 3);
|
||||
CPPUNIT_ASSERT_EQUAL(5, pm->getId());
|
||||
CPPUNIT_ASSERT(memcmp(bitfield, pm->getBitfield(), sizeof(bitfield)) == 0);
|
||||
CPPUNIT_ASSERT_EQUAL(2, pm->getBitfieldLength());
|
||||
// case: payload size is wrong
|
||||
try {
|
||||
char msg[5];
|
||||
PeerMessageUtil::createPeerMessageString(msg, sizeof(msg), 1, 5);
|
||||
BitfieldMessage::create(&msg[4], 1);
|
||||
CPPUNIT_FAIL("exception must be threw.");
|
||||
} catch(...) {
|
||||
}
|
||||
// case: id is wrong
|
||||
try {
|
||||
char msg[5+2];
|
||||
PeerMessageUtil::createPeerMessageString(msg, sizeof(msg), 3, 6);
|
||||
BitfieldMessage::create(&msg[4], 3);
|
||||
CPPUNIT_FAIL("exception must be threw.");
|
||||
} catch(...) {
|
||||
}
|
||||
}
|
||||
|
||||
void BitfieldMessageTest::testGetMessage() {
|
||||
BitfieldMessage msg;
|
||||
unsigned char bitfield[2];
|
||||
memset(bitfield, 0xff, sizeof(bitfield));
|
||||
msg.setBitfield(bitfield, sizeof(bitfield));
|
||||
char data[5+2];
|
||||
PeerMessageUtil::createPeerMessageString(data, sizeof(data), 3, 5);
|
||||
memcpy(&data[5], bitfield, sizeof(bitfield));
|
||||
CPPUNIT_ASSERT(memcmp(msg.getMessage(), data, 7) == 0);
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
#include "CancelMessage.h"
|
||||
#include "PeerMessageUtil.h"
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class CancelMessageTest:public CppUnit::TestFixture {
|
||||
|
||||
CPPUNIT_TEST_SUITE(CancelMessageTest);
|
||||
CPPUNIT_TEST(testCreate);
|
||||
CPPUNIT_TEST(testGetMessage);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
private:
|
||||
|
||||
public:
|
||||
void setUp() {
|
||||
}
|
||||
|
||||
void testCreate();
|
||||
void testGetMessage();
|
||||
};
|
||||
|
||||
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION(CancelMessageTest);
|
||||
|
||||
void CancelMessageTest::testCreate() {
|
||||
char msg[17];
|
||||
PeerMessageUtil::createPeerMessageString(msg, sizeof(msg), 13, 8);
|
||||
PeerMessageUtil::setIntParam(&msg[5], 12345);
|
||||
PeerMessageUtil::setIntParam(&msg[9], 256);
|
||||
PeerMessageUtil::setIntParam(&msg[13], 1024);
|
||||
CancelMessage* pm = CancelMessage::create(&msg[4], 13);
|
||||
CPPUNIT_ASSERT_EQUAL(8, pm->getId());
|
||||
CPPUNIT_ASSERT_EQUAL(12345, pm->getIndex());
|
||||
CPPUNIT_ASSERT_EQUAL(256, pm->getBegin());
|
||||
CPPUNIT_ASSERT_EQUAL(1024, pm->getLength());
|
||||
|
||||
// case: payload size is wrong
|
||||
try {
|
||||
char msg[18];
|
||||
PeerMessageUtil::createPeerMessageString(msg, sizeof(msg), 14, 8);
|
||||
CancelMessage::create(&msg[4], 14);
|
||||
CPPUNIT_FAIL("exception must be threw.");
|
||||
} catch(...) {
|
||||
}
|
||||
// case: id is wrong
|
||||
try {
|
||||
char msg[17];
|
||||
PeerMessageUtil::createPeerMessageString(msg, sizeof(msg), 13, 9);
|
||||
CancelMessage::create(&msg[4], 13);
|
||||
CPPUNIT_FAIL("exception must be threw.");
|
||||
} catch(...) {
|
||||
}
|
||||
}
|
||||
|
||||
void CancelMessageTest::testGetMessage() {
|
||||
CancelMessage msg;
|
||||
msg.setIndex(12345);
|
||||
msg.setBegin(256);
|
||||
msg.setLength(1024);
|
||||
char data[17];
|
||||
PeerMessageUtil::createPeerMessageString(data, sizeof(data), 13, 8);
|
||||
PeerMessageUtil::setIntParam(&data[5], 12345);
|
||||
PeerMessageUtil::setIntParam(&data[9], 256);
|
||||
PeerMessageUtil::setIntParam(&data[13], 1024);
|
||||
CPPUNIT_ASSERT(memcmp(msg.getMessage(), data, 17) == 0);
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
#include "ChokeMessage.h"
|
||||
#include "PeerMessageUtil.h"
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class ChokeMessageTest:public CppUnit::TestFixture {
|
||||
|
||||
CPPUNIT_TEST_SUITE(ChokeMessageTest);
|
||||
CPPUNIT_TEST(testCreate);
|
||||
CPPUNIT_TEST(testGetMessage);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
private:
|
||||
|
||||
public:
|
||||
void setUp() {
|
||||
}
|
||||
|
||||
void testCreate();
|
||||
void testGetMessage();
|
||||
};
|
||||
|
||||
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION(ChokeMessageTest);
|
||||
|
||||
void ChokeMessageTest::testCreate() {
|
||||
char msg[5];
|
||||
PeerMessageUtil::createPeerMessageString(msg, sizeof(msg), 1, 0);
|
||||
PeerMessage* pm = ChokeMessage::create(&msg[4], 1);
|
||||
CPPUNIT_ASSERT_EQUAL(0, pm->getId());
|
||||
|
||||
// case: payload size is wrong
|
||||
try {
|
||||
char msg[6];
|
||||
PeerMessageUtil::createPeerMessageString(msg, sizeof(msg), 2, 0);
|
||||
ChokeMessage::create(&msg[4], 2);
|
||||
CPPUNIT_FAIL("exception must be threw.");
|
||||
} catch(...) {
|
||||
}
|
||||
// case: id is wrong
|
||||
try {
|
||||
char msg[5];
|
||||
PeerMessageUtil::createPeerMessageString(msg, sizeof(msg), 1, 1);
|
||||
ChokeMessage::create(&msg[4], 1);
|
||||
CPPUNIT_FAIL("exception must be threw.");
|
||||
} catch(...) {
|
||||
}
|
||||
}
|
||||
|
||||
void ChokeMessageTest::testGetMessage() {
|
||||
ChokeMessage msg;
|
||||
char data[5];
|
||||
PeerMessageUtil::createPeerMessageString(data, sizeof(data), 1, 0);
|
||||
CPPUNIT_ASSERT(memcmp(msg.getMessage(), data, 5) == 0);
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
#include "HaveAllMessage.h"
|
||||
#include "PeerMessageUtil.h"
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class HaveAllMessageTest:public CppUnit::TestFixture {
|
||||
|
||||
CPPUNIT_TEST_SUITE(HaveAllMessageTest);
|
||||
CPPUNIT_TEST(testCreate);
|
||||
CPPUNIT_TEST(testGetMessage);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
private:
|
||||
|
||||
public:
|
||||
void setUp() {
|
||||
}
|
||||
|
||||
void testCreate();
|
||||
void testGetMessage();
|
||||
};
|
||||
|
||||
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION(HaveAllMessageTest);
|
||||
|
||||
void HaveAllMessageTest::testCreate() {
|
||||
char msg[5];
|
||||
PeerMessageUtil::createPeerMessageString(msg, sizeof(msg), 1, 14);
|
||||
PeerMessage* pm = HaveAllMessage::create(&msg[4], 1);
|
||||
CPPUNIT_ASSERT_EQUAL(14, pm->getId());
|
||||
|
||||
// case: payload size is wrong
|
||||
try {
|
||||
char msg[6];
|
||||
PeerMessageUtil::createPeerMessageString(msg, sizeof(msg), 2, 14);
|
||||
HaveAllMessage::create(&msg[4], 2);
|
||||
CPPUNIT_FAIL("exception must be threw.");
|
||||
} catch(...) {
|
||||
}
|
||||
// case: id is wrong
|
||||
try {
|
||||
char msg[5];
|
||||
PeerMessageUtil::createPeerMessageString(msg, sizeof(msg), 1, 15);
|
||||
HaveAllMessage::create(&msg[4], 1);
|
||||
CPPUNIT_FAIL("exception must be threw.");
|
||||
} catch(...) {
|
||||
}
|
||||
}
|
||||
|
||||
void HaveAllMessageTest::testGetMessage() {
|
||||
HaveAllMessage msg;
|
||||
char data[5];
|
||||
PeerMessageUtil::createPeerMessageString(data, sizeof(data), 1, 14);
|
||||
CPPUNIT_ASSERT(memcmp(msg.getMessage(), data, 5) == 0);
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
#include "HaveMessage.h"
|
||||
#include "PeerMessageUtil.h"
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class HaveMessageTest:public CppUnit::TestFixture {
|
||||
|
||||
CPPUNIT_TEST_SUITE(HaveMessageTest);
|
||||
CPPUNIT_TEST(testCreate);
|
||||
CPPUNIT_TEST(testGetMessage);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
private:
|
||||
|
||||
public:
|
||||
void setUp() {
|
||||
}
|
||||
|
||||
void testCreate();
|
||||
void testGetMessage();
|
||||
};
|
||||
|
||||
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION(HaveMessageTest);
|
||||
|
||||
void HaveMessageTest::testCreate() {
|
||||
char msg[9];
|
||||
PeerMessageUtil::createPeerMessageString(msg, sizeof(msg), 5, 4);
|
||||
PeerMessageUtil::setIntParam(&msg[5], 12345);
|
||||
HaveMessage* pm = HaveMessage::create(&msg[4], 5);
|
||||
CPPUNIT_ASSERT_EQUAL(4, pm->getId());
|
||||
CPPUNIT_ASSERT_EQUAL(12345, pm->getIndex());
|
||||
|
||||
// case: payload size is wrong
|
||||
try {
|
||||
char msg[10];
|
||||
PeerMessageUtil::createPeerMessageString(msg, sizeof(msg), 6, 4);
|
||||
HaveMessage::create(&msg[4], 2);
|
||||
CPPUNIT_FAIL("exception must be threw.");
|
||||
} catch(...) {
|
||||
}
|
||||
// case: id is wrong
|
||||
try {
|
||||
char msg[9];
|
||||
PeerMessageUtil::createPeerMessageString(msg, sizeof(msg), 5, 5);
|
||||
HaveMessage::create(&msg[4], 1);
|
||||
CPPUNIT_FAIL("exception must be threw.");
|
||||
} catch(...) {
|
||||
}
|
||||
}
|
||||
|
||||
void HaveMessageTest::testGetMessage() {
|
||||
HaveMessage msg;
|
||||
msg.setIndex(12345);
|
||||
char data[9];
|
||||
PeerMessageUtil::createPeerMessageString(data, sizeof(data), 5, 4);
|
||||
PeerMessageUtil::setIntParam(&data[5], 12345);
|
||||
CPPUNIT_ASSERT(memcmp(msg.getMessage(), data, 9) == 0);
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
#include "HaveNoneMessage.h"
|
||||
#include "PeerMessageUtil.h"
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class HaveNoneMessageTest:public CppUnit::TestFixture {
|
||||
|
||||
CPPUNIT_TEST_SUITE(HaveNoneMessageTest);
|
||||
CPPUNIT_TEST(testCreate);
|
||||
CPPUNIT_TEST(testGetMessage);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
private:
|
||||
|
||||
public:
|
||||
void setUp() {
|
||||
}
|
||||
|
||||
void testCreate();
|
||||
void testGetMessage();
|
||||
};
|
||||
|
||||
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION(HaveNoneMessageTest);
|
||||
|
||||
void HaveNoneMessageTest::testCreate() {
|
||||
char msg[5];
|
||||
PeerMessageUtil::createPeerMessageString(msg, sizeof(msg), 1, 15);
|
||||
PeerMessage* pm = HaveNoneMessage::create(&msg[4], 1);
|
||||
CPPUNIT_ASSERT_EQUAL(15, pm->getId());
|
||||
|
||||
// case: payload size is wrong
|
||||
try {
|
||||
char msg[6];
|
||||
PeerMessageUtil::createPeerMessageString(msg, sizeof(msg), 2, 15);
|
||||
HaveNoneMessage::create(&msg[4], 2);
|
||||
CPPUNIT_FAIL("exception must be threw.");
|
||||
} catch(...) {
|
||||
}
|
||||
// case: id is wrong
|
||||
try {
|
||||
char msg[5];
|
||||
PeerMessageUtil::createPeerMessageString(msg, sizeof(msg), 1, 16);
|
||||
HaveNoneMessage::create(&msg[4], 1);
|
||||
CPPUNIT_FAIL("exception must be threw.");
|
||||
} catch(...) {
|
||||
}
|
||||
}
|
||||
|
||||
void HaveNoneMessageTest::testGetMessage() {
|
||||
HaveNoneMessage msg;
|
||||
char data[5];
|
||||
PeerMessageUtil::createPeerMessageString(data, sizeof(data), 1, 15);
|
||||
CPPUNIT_ASSERT(memcmp(msg.getMessage(), data, 5) == 0);
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
#include "InterestedMessage.h"
|
||||
#include "PeerMessageUtil.h"
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class InterestedMessageTest:public CppUnit::TestFixture {
|
||||
|
||||
CPPUNIT_TEST_SUITE(InterestedMessageTest);
|
||||
CPPUNIT_TEST(testCreate);
|
||||
CPPUNIT_TEST(testGetMessage);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
private:
|
||||
|
||||
public:
|
||||
void setUp() {
|
||||
}
|
||||
|
||||
void testCreate();
|
||||
void testGetMessage();
|
||||
};
|
||||
|
||||
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION(InterestedMessageTest);
|
||||
|
||||
void InterestedMessageTest::testCreate() {
|
||||
char msg[5];
|
||||
PeerMessageUtil::createPeerMessageString(msg, sizeof(msg), 1, 2);
|
||||
PeerMessage* pm = InterestedMessage::create(&msg[4], 1);
|
||||
CPPUNIT_ASSERT_EQUAL(2, pm->getId());
|
||||
|
||||
// case: payload size is wrong
|
||||
try {
|
||||
char msg[6];
|
||||
PeerMessageUtil::createPeerMessageString(msg, sizeof(msg), 2, 2);
|
||||
InterestedMessage::create(&msg[4], 2);
|
||||
CPPUNIT_FAIL("exception must be threw.");
|
||||
} catch(...) {
|
||||
}
|
||||
// case: id is wrong
|
||||
try {
|
||||
char msg[5];
|
||||
PeerMessageUtil::createPeerMessageString(msg, sizeof(msg), 1, 3);
|
||||
InterestedMessage::create(&msg[4], 1);
|
||||
CPPUNIT_FAIL("exception must be threw.");
|
||||
} catch(...) {
|
||||
}
|
||||
}
|
||||
|
||||
void InterestedMessageTest::testGetMessage() {
|
||||
InterestedMessage msg;
|
||||
char data[5];
|
||||
PeerMessageUtil::createPeerMessageString(data, sizeof(data), 1, 2);
|
||||
CPPUNIT_ASSERT(memcmp(msg.getMessage(), data, 5) == 0);
|
||||
}
|
|
@ -17,7 +17,21 @@ aria2c_SOURCES = AllTest.cc\
|
|||
PeerMessageUtilTest.cc\
|
||||
BitfieldManTest.cc\
|
||||
DefaultDiskWriterTest.cc\
|
||||
MultiDiskWriterTest.cc
|
||||
MultiDiskWriterTest.cc\
|
||||
ChokeMessageTest.cc\
|
||||
UnchokeMessageTest.cc\
|
||||
HaveAllMessageTest.cc\
|
||||
HaveNoneMessageTest.cc\
|
||||
InterestedMessageTest.cc\
|
||||
NotInterestedMessageTest.cc\
|
||||
HaveMessageTest.cc\
|
||||
BitfieldMessageTest.cc\
|
||||
RequestMessageTest.cc\
|
||||
CancelMessageTest.cc\
|
||||
PieceMessageTest.cc\
|
||||
RejectMessageTest.cc\
|
||||
AllowedFastMessageTest.cc\
|
||||
SuggestPieceMessageTest.cc
|
||||
#aria2c_CXXFLAGS = ${CPPUNIT_CFLAGS} -I../src -I../lib -Wall -D_FILE_OFFSET_BITS=64
|
||||
#aria2c_LDFLAGS = ${CPPUNIT_LIBS}
|
||||
|
||||
|
|
|
@ -64,7 +64,14 @@ am_aria2c_OBJECTS = AllTest.$(OBJEXT) RequestTest.$(OBJEXT) \
|
|||
MetaFileUtilTest.$(OBJEXT) ShaVisitorTest.$(OBJEXT) \
|
||||
TorrentManTest.$(OBJEXT) PeerMessageUtilTest.$(OBJEXT) \
|
||||
BitfieldManTest.$(OBJEXT) DefaultDiskWriterTest.$(OBJEXT) \
|
||||
MultiDiskWriterTest.$(OBJEXT)
|
||||
MultiDiskWriterTest.$(OBJEXT) ChokeMessageTest.$(OBJEXT) \
|
||||
UnchokeMessageTest.$(OBJEXT) HaveAllMessageTest.$(OBJEXT) \
|
||||
HaveNoneMessageTest.$(OBJEXT) InterestedMessageTest.$(OBJEXT) \
|
||||
NotInterestedMessageTest.$(OBJEXT) HaveMessageTest.$(OBJEXT) \
|
||||
BitfieldMessageTest.$(OBJEXT) RequestMessageTest.$(OBJEXT) \
|
||||
CancelMessageTest.$(OBJEXT) PieceMessageTest.$(OBJEXT) \
|
||||
RejectMessageTest.$(OBJEXT) AllowedFastMessageTest.$(OBJEXT) \
|
||||
SuggestPieceMessageTest.$(OBJEXT)
|
||||
aria2c_OBJECTS = $(am_aria2c_OBJECTS)
|
||||
am__DEPENDENCIES_1 =
|
||||
aria2c_DEPENDENCIES = ../src/libaria2c.a $(am__DEPENDENCIES_1)
|
||||
|
@ -222,7 +229,21 @@ aria2c_SOURCES = AllTest.cc\
|
|||
PeerMessageUtilTest.cc\
|
||||
BitfieldManTest.cc\
|
||||
DefaultDiskWriterTest.cc\
|
||||
MultiDiskWriterTest.cc
|
||||
MultiDiskWriterTest.cc\
|
||||
ChokeMessageTest.cc\
|
||||
UnchokeMessageTest.cc\
|
||||
HaveAllMessageTest.cc\
|
||||
HaveNoneMessageTest.cc\
|
||||
InterestedMessageTest.cc\
|
||||
NotInterestedMessageTest.cc\
|
||||
HaveMessageTest.cc\
|
||||
BitfieldMessageTest.cc\
|
||||
RequestMessageTest.cc\
|
||||
CancelMessageTest.cc\
|
||||
PieceMessageTest.cc\
|
||||
RejectMessageTest.cc\
|
||||
AllowedFastMessageTest.cc\
|
||||
SuggestPieceMessageTest.cc
|
||||
|
||||
#aria2c_CXXFLAGS = ${CPPUNIT_CFLAGS} -I../src -I../lib -Wall -D_FILE_OFFSET_BITS=64
|
||||
#aria2c_LDFLAGS = ${CPPUNIT_LIBS}
|
||||
|
@ -284,22 +305,36 @@ distclean-compile:
|
|||
-rm -f *.tab.c
|
||||
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AllTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AllowedFastMessageTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Base64Test.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BitfieldManTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BitfieldMessageTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CancelMessageTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ChokeMessageTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ChunkedEncodingTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CookieBoxTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DataTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultDiskWriterTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DictionaryTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FileTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HaveAllMessageTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HaveMessageTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HaveNoneMessageTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/InterestedMessageTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ListTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MetaFileUtilTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MultiDiskWriterTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NotInterestedMessageTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/OptionTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PeerMessageUtilTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PieceMessageTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RejectMessageTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RequestMessageTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RequestTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ShaVisitorTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SuggestPieceMessageTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TorrentManTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UnchokeMessageTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UtilTest.Po@am__quote@
|
||||
|
||||
.cc.o:
|
||||
|
|
|
@ -37,41 +37,41 @@ void MetaFileUtilTest::testBdecoding() {
|
|||
try {
|
||||
char* str = "5:abcd";
|
||||
MetaEntry* entry = MetaFileUtil::bdecoding(str, strlen(str));
|
||||
CPPUNIT_FAIL("DlAbortEx exception must be throwed.");
|
||||
CPPUNIT_FAIL("DlAbortEx exception must be threw.");
|
||||
} catch(DlAbortEx* ex) {
|
||||
delete ex;
|
||||
} catch(...) {
|
||||
CPPUNIT_FAIL("DlAbortEx exception must be throwed.");
|
||||
CPPUNIT_FAIL("DlAbortEx exception must be threw.");
|
||||
}
|
||||
|
||||
try {
|
||||
char* str = "i1234";
|
||||
MetaEntry* entry = MetaFileUtil::bdecoding(str, strlen(str));
|
||||
CPPUNIT_FAIL("DlAbortEx exception must be throwed.");
|
||||
CPPUNIT_FAIL("DlAbortEx exception must be threw.");
|
||||
} catch(DlAbortEx* ex) {
|
||||
delete ex;
|
||||
} catch(...) {
|
||||
CPPUNIT_FAIL("DlAbortEx exception must be throwed.");
|
||||
CPPUNIT_FAIL("DlAbortEx exception must be threw.");
|
||||
}
|
||||
|
||||
try {
|
||||
char* str = "5abcd";
|
||||
MetaEntry* entry = MetaFileUtil::bdecoding(str, strlen(str));
|
||||
CPPUNIT_FAIL("DlAbortEx exception must be throwed.");
|
||||
CPPUNIT_FAIL("DlAbortEx exception must be threw.");
|
||||
} catch(DlAbortEx* ex) {
|
||||
delete ex;
|
||||
} catch(...) {
|
||||
CPPUNIT_FAIL("DlAbortEx exception must be throwed.");
|
||||
CPPUNIT_FAIL("DlAbortEx exception must be threw.");
|
||||
}
|
||||
|
||||
try {
|
||||
char* str = "d";
|
||||
MetaEntry* entry = MetaFileUtil::bdecoding(str, strlen(str));
|
||||
CPPUNIT_FAIL("DlAbortEx exception must be throwed.");
|
||||
CPPUNIT_FAIL("DlAbortEx exception must be threw.");
|
||||
} catch(DlAbortEx* ex) {
|
||||
delete ex;
|
||||
} catch(...) {
|
||||
CPPUNIT_FAIL("DlAbortEx exception must be throwed.");
|
||||
CPPUNIT_FAIL("DlAbortEx exception must be threw.");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
#include "NotInterestedMessage.h"
|
||||
#include "PeerMessageUtil.h"
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class NotInterestedMessageTest:public CppUnit::TestFixture {
|
||||
|
||||
CPPUNIT_TEST_SUITE(NotInterestedMessageTest);
|
||||
CPPUNIT_TEST(testCreate);
|
||||
CPPUNIT_TEST(testGetMessage);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
private:
|
||||
|
||||
public:
|
||||
void setUp() {
|
||||
}
|
||||
|
||||
void testCreate();
|
||||
void testGetMessage();
|
||||
};
|
||||
|
||||
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION(NotInterestedMessageTest);
|
||||
|
||||
void NotInterestedMessageTest::testCreate() {
|
||||
char msg[5];
|
||||
PeerMessageUtil::createPeerMessageString(msg, sizeof(msg), 1, 3);
|
||||
PeerMessage* pm = NotInterestedMessage::create(&msg[4], 1);
|
||||
CPPUNIT_ASSERT_EQUAL(3, pm->getId());
|
||||
|
||||
// case: payload size is wrong
|
||||
try {
|
||||
char msg[6];
|
||||
PeerMessageUtil::createPeerMessageString(msg, sizeof(msg), 2, 3);
|
||||
NotInterestedMessage::create(&msg[4], 2);
|
||||
CPPUNIT_FAIL("exception must be threw.");
|
||||
} catch(...) {
|
||||
}
|
||||
// case: id is wrong
|
||||
try {
|
||||
char msg[5];
|
||||
PeerMessageUtil::createPeerMessageString(msg, sizeof(msg), 1, 4);
|
||||
NotInterestedMessage::create(&msg[4], 1);
|
||||
CPPUNIT_FAIL("exception must be threw.");
|
||||
} catch(...) {
|
||||
}
|
||||
}
|
||||
|
||||
void NotInterestedMessageTest::testGetMessage() {
|
||||
NotInterestedMessage msg;
|
||||
char data[5];
|
||||
PeerMessageUtil::createPeerMessageString(data, sizeof(data), 1, 3);
|
||||
CPPUNIT_ASSERT(memcmp(msg.getMessage(), data, 5) == 0);
|
||||
}
|
|
@ -8,16 +8,6 @@ using namespace std;
|
|||
class PeerMessageUtilTest:public CppUnit::TestFixture {
|
||||
|
||||
CPPUNIT_TEST_SUITE(PeerMessageUtilTest);
|
||||
CPPUNIT_TEST(testCreatePeerMessageChoke);
|
||||
CPPUNIT_TEST(testCreatePeerMessageUnchoke);
|
||||
CPPUNIT_TEST(testCreatePeerMessageInterested);
|
||||
CPPUNIT_TEST(testCreatePeerMessageNotInterested);
|
||||
CPPUNIT_TEST(testCreatePeerMessageHave);
|
||||
CPPUNIT_TEST(testCreatePeerMessageBitfield);
|
||||
CPPUNIT_TEST(testCreatePeerMessageRequest);
|
||||
CPPUNIT_TEST(testCreatePeerMessagePiece);
|
||||
CPPUNIT_TEST(testCreatePeerMessageCancel);
|
||||
CPPUNIT_TEST(testCreatePortMessage);
|
||||
CPPUNIT_TEST(testCheckIntegrityHave);
|
||||
CPPUNIT_TEST(testCheckIntegrityBitfield);
|
||||
CPPUNIT_TEST(testCheckIntegrityRequest);
|
||||
|
@ -28,7 +18,6 @@ public:
|
|||
void setUp() {
|
||||
}
|
||||
|
||||
void testCreatePeerMessageChoke();
|
||||
void testCreatePeerMessageUnchoke();
|
||||
void testCreatePeerMessageInterested();
|
||||
void testCreatePeerMessageNotInterested();
|
||||
|
@ -62,191 +51,11 @@ void createNLengthMessage(char* msg, int msgLen, int payloadLen, int id) {
|
|||
msg[4] = (char)id;
|
||||
}
|
||||
|
||||
void PeerMessageUtilTest::testCreatePeerMessageChoke() {
|
||||
char msg[5];
|
||||
createNLengthMessage(msg, sizeof(msg), 1, 0);
|
||||
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::createChokeMessage(&msg[4], 2);
|
||||
CPPUNIT_FAIL("exception must be throwed.");
|
||||
} catch(...) {
|
||||
}
|
||||
}
|
||||
|
||||
void PeerMessageUtilTest::testCreatePeerMessageUnchoke() {
|
||||
char msg[5];
|
||||
createNLengthMessage(msg, sizeof(msg), 1, 1);
|
||||
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::createUnchokeMessage(&msg[4], 2);
|
||||
CPPUNIT_FAIL("exception must be throwed.");
|
||||
} catch(...) {
|
||||
}
|
||||
}
|
||||
|
||||
void PeerMessageUtilTest::testCreatePeerMessageInterested() {
|
||||
char msg[5];
|
||||
createNLengthMessage(msg, sizeof(msg), 1, 2);
|
||||
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::createInterestedMessage(&msg[4], 2);
|
||||
CPPUNIT_FAIL("exception must be throwed.");
|
||||
} catch(...) {
|
||||
}
|
||||
}
|
||||
|
||||
void PeerMessageUtilTest::testCreatePeerMessageNotInterested() {
|
||||
char msg[5];
|
||||
createNLengthMessage(msg, sizeof(msg), 1, 3);
|
||||
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::createNotInterestedMessage(&msg[4], 2);
|
||||
CPPUNIT_FAIL("exception must be throwed.");
|
||||
} catch(...) {
|
||||
}
|
||||
}
|
||||
|
||||
void PeerMessageUtilTest::testCreatePeerMessageHave() {
|
||||
char msg[9];
|
||||
createNLengthMessage(msg, sizeof(msg), 5, 4);
|
||||
setIntParam(&msg[5], 100);
|
||||
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::createHaveMessage(&msg[4], 4);
|
||||
CPPUNIT_FAIL("exception must be throwed.");
|
||||
} catch(...) {}
|
||||
|
||||
try {
|
||||
char msg[5];
|
||||
createNLengthMessage(msg, sizeof(msg), 1, 4);
|
||||
PeerMessageUtil::createHaveMessage(&msg[4], 1);
|
||||
CPPUNIT_FAIL("exception must be throwed.");
|
||||
} catch(...) {}
|
||||
}
|
||||
|
||||
void PeerMessageUtilTest::testCreatePeerMessageBitfield() {
|
||||
int msgLen = 5+2;
|
||||
char* msg = new char[msgLen];
|
||||
createNLengthMessage(msg, msgLen, 3, 5);
|
||||
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());
|
||||
|
||||
try {
|
||||
int msgLen = 5;
|
||||
char* msg = new char[msgLen];
|
||||
createNLengthMessage(msg, msgLen, 1, 5);
|
||||
PeerMessageUtil::createBitfieldMessage(&msg[4], 1);
|
||||
CPPUNIT_FAIL("exception must be throwed.");
|
||||
} catch(...) {}
|
||||
}
|
||||
|
||||
void PeerMessageUtilTest::testCreatePeerMessageRequest() {
|
||||
char msg[17];
|
||||
createNLengthMessage(msg, sizeof(msg), 13, 6);
|
||||
setIntParam(&msg[5], 1);
|
||||
setIntParam(&msg[9], 16*1024);
|
||||
setIntParam(&msg[13], 16*1024-1);
|
||||
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());
|
||||
|
||||
try {
|
||||
char msg[13];
|
||||
createNLengthMessage(msg, sizeof(msg), 9, 6);
|
||||
setIntParam(&msg[5], 1);
|
||||
setIntParam(&msg[9], 16*1024);
|
||||
PeerMessageUtil::createRequestMessage(&msg[4], 9);
|
||||
CPPUNIT_FAIL("exception must be throwed.");
|
||||
} catch(...) {}
|
||||
}
|
||||
|
||||
void PeerMessageUtilTest::testCreatePeerMessagePiece() {
|
||||
char msg[23];
|
||||
createNLengthMessage(msg, sizeof(msg), 9+10, 7);
|
||||
setIntParam(&msg[5], 1);
|
||||
setIntParam(&msg[9], 16*1024);
|
||||
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());
|
||||
for(int i = 0; i < 10; i++) {
|
||||
CPPUNIT_ASSERT_EQUAL((char)0, pm->getBlock()[i]);
|
||||
}
|
||||
|
||||
try {
|
||||
char msg[13];
|
||||
createNLengthMessage(msg, sizeof(msg), 9, 7);
|
||||
setIntParam(&msg[5], 1);
|
||||
setIntParam(&msg[9], 16*1024);
|
||||
PeerMessageUtil::createPieceMessage(&msg[4], 9);
|
||||
CPPUNIT_FAIL("exception must be throwed.");
|
||||
} catch(...) {}
|
||||
}
|
||||
|
||||
void PeerMessageUtilTest::testCreatePeerMessageCancel() {
|
||||
char msg[17];
|
||||
createNLengthMessage(msg, sizeof(msg), 13, 8);
|
||||
setIntParam(&msg[5], 1);
|
||||
setIntParam(&msg[9], 16*1024);
|
||||
setIntParam(&msg[13], 16*1024-1);
|
||||
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());
|
||||
|
||||
try {
|
||||
char msg[13];
|
||||
createNLengthMessage(msg, sizeof(msg), 9, 8);
|
||||
setIntParam(&msg[5], 1);
|
||||
setIntParam(&msg[9], 16*1024);
|
||||
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() {
|
||||
HaveMessage* pm = new HaveMessage();
|
||||
pm->setIndex(119);
|
||||
pm->setPieces(120);
|
||||
try {
|
||||
//PeerMessageUtil::checkIntegrity(pm, 256*1024, 120, 256*1024*120);
|
||||
pm->check();
|
||||
} catch(Exception* ex) {
|
||||
cerr << ex->getMsg() << endl;
|
||||
|
@ -255,9 +64,8 @@ void PeerMessageUtilTest::testCheckIntegrityHave() {
|
|||
|
||||
pm->setIndex(120);
|
||||
try {
|
||||
//PeerMessageUtil::checkIntegrity(pm, 256*1024, 120, 256*1024*120);
|
||||
pm->check();
|
||||
CPPUNIT_FAIL("exception must be throwed.");
|
||||
CPPUNIT_FAIL("exception must be threw.");
|
||||
} catch(...) {}
|
||||
}
|
||||
|
||||
|
@ -270,7 +78,6 @@ void PeerMessageUtilTest::testCheckIntegrityBitfield() {
|
|||
pm->setBitfield(bitfield, bitfieldLength);
|
||||
pm->setPieces(120);
|
||||
try {
|
||||
//PeerMessageUtil::checkIntegrity(pm, 256*1024, 120, 256*1024*120);
|
||||
pm->check();
|
||||
} catch(Exception* ex) {
|
||||
cerr << ex->getMsg() << endl;
|
||||
|
@ -282,9 +89,8 @@ void PeerMessageUtilTest::testCheckIntegrityBitfield() {
|
|||
memset(bitfield, 0xff, bitfieldLength);
|
||||
pm->setBitfield(bitfield, bitfieldLength);
|
||||
try {
|
||||
//PeerMessageUtil::checkIntegrity(pm, 256*1024, 120, 256*1024*120);
|
||||
pm->check();
|
||||
CPPUNIT_FAIL("exception must be throwed.");
|
||||
CPPUNIT_FAIL("exception must be threw.");
|
||||
} catch(Exception* ex) {
|
||||
}
|
||||
delete [] bitfield;
|
||||
|
@ -293,9 +99,8 @@ void PeerMessageUtilTest::testCheckIntegrityBitfield() {
|
|||
memset(bitfield, 0xff, bitfieldLength);
|
||||
pm->setBitfield(bitfield, bitfieldLength);
|
||||
try {
|
||||
//PeerMessageUtil::checkIntegrity(pm, 256*1024, 120, 256*1024*120);
|
||||
pm->check();
|
||||
CPPUNIT_FAIL("exception must be throwed.");
|
||||
CPPUNIT_FAIL("exception must be threw.");
|
||||
} catch(Exception* ex) {
|
||||
}
|
||||
delete [] bitfield;
|
||||
|
@ -306,7 +111,6 @@ void PeerMessageUtilTest::testCheckIntegrityBitfield() {
|
|||
pm->setBitfield(bitfield, bitfieldLength);
|
||||
pm->setPieces(119);
|
||||
try {
|
||||
//PeerMessageUtil::checkIntegrity(pm, 256*1024, 119, 256*1024*120);
|
||||
pm->check();
|
||||
} catch(Exception* ex) {
|
||||
cerr << ex->getMsg() << endl;
|
||||
|
@ -318,9 +122,8 @@ void PeerMessageUtilTest::testCheckIntegrityBitfield() {
|
|||
memset(bitfield, 0xff, bitfieldLength);
|
||||
pm->setBitfield(bitfield, bitfieldLength);
|
||||
try {
|
||||
//PeerMessageUtil::checkIntegrity(pm, 256*1024, 119, 256*1024*120);
|
||||
pm->check();
|
||||
CPPUNIT_FAIL("exception must be throwed.");
|
||||
CPPUNIT_FAIL("exception must be threw.");
|
||||
} catch(Exception* ex) {
|
||||
}
|
||||
delete [] bitfield;
|
||||
|
@ -334,7 +137,6 @@ void PeerMessageUtilTest::testCheckIntegrityRequest() {
|
|||
pm->setPieces(120);
|
||||
pm->setPieceLength(256*1024);
|
||||
try {
|
||||
//PeerMessageUtil::checkIntegrity(pm, 256*1024, 120, 256*1024*120);
|
||||
pm->check();
|
||||
} catch(Exception* ex) {
|
||||
cerr << ex->getMsg() << endl;
|
||||
|
@ -344,24 +146,21 @@ void PeerMessageUtilTest::testCheckIntegrityRequest() {
|
|||
pm->setBegin(256*1024);
|
||||
pm->setLength(16*1024);
|
||||
try {
|
||||
//PeerMessageUtil::checkIntegrity(pm, 256*1024, 120, 256*1024*120);
|
||||
pm->check();
|
||||
CPPUNIT_FAIL("exception must be throwed.");
|
||||
CPPUNIT_FAIL("exception must be threw.");
|
||||
} catch(Exception* ex) {}
|
||||
|
||||
pm->setBegin(0);
|
||||
pm->setLength(256*1024);
|
||||
try {
|
||||
//PeerMessageUtil::checkIntegrity(pm, 256*1024, 120, 256*1024*120);
|
||||
pm->check();
|
||||
CPPUNIT_FAIL("exception must be throwed.");
|
||||
CPPUNIT_FAIL("exception must be threw.");
|
||||
} catch(Exception* ex) {}
|
||||
|
||||
pm->setBegin(0);
|
||||
pm->setLength(5);
|
||||
try {
|
||||
//PeerMessageUtil::checkIntegrity(pm, 256*1024, 120, 256*1024*120);
|
||||
pm->check();
|
||||
CPPUNIT_FAIL("exception must be throwed.");
|
||||
CPPUNIT_FAIL("exception must be threw.");
|
||||
} catch(Exception* ex) {}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
#include "PieceMessage.h"
|
||||
#include "PeerMessageUtil.h"
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class PieceMessageTest:public CppUnit::TestFixture {
|
||||
|
||||
CPPUNIT_TEST_SUITE(PieceMessageTest);
|
||||
CPPUNIT_TEST(testCreate);
|
||||
CPPUNIT_TEST(testGetMessageHeader);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
private:
|
||||
|
||||
public:
|
||||
void setUp() {
|
||||
}
|
||||
|
||||
void testCreate();
|
||||
void testGetMessageHeader();
|
||||
};
|
||||
|
||||
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION(PieceMessageTest);
|
||||
|
||||
void PieceMessageTest::testCreate() {
|
||||
char msg[13+2];
|
||||
char data[2];
|
||||
memset(data, 0xff, sizeof(data));
|
||||
PeerMessageUtil::createPeerMessageString(msg, sizeof(msg), 11, 7);
|
||||
PeerMessageUtil::setIntParam(&msg[5], 12345);
|
||||
PeerMessageUtil::setIntParam(&msg[9], 256);
|
||||
memcpy(&msg[13], data, sizeof(data));
|
||||
PieceMessage* pm = PieceMessage::create(&msg[4], 11);
|
||||
CPPUNIT_ASSERT_EQUAL(7, pm->getId());
|
||||
CPPUNIT_ASSERT_EQUAL(12345, pm->getIndex());
|
||||
CPPUNIT_ASSERT_EQUAL(256, pm->getBegin());
|
||||
CPPUNIT_ASSERT(memcmp(data, pm->getBlock(), sizeof(data)) == 0);
|
||||
CPPUNIT_ASSERT_EQUAL(2, pm->getBlockLength());
|
||||
|
||||
// case: payload size is wrong
|
||||
try {
|
||||
char msg[13];
|
||||
PeerMessageUtil::createPeerMessageString(msg, sizeof(msg), 9, 7);
|
||||
PieceMessage::create(&msg[4], 9);
|
||||
CPPUNIT_FAIL("exception must be threw.");
|
||||
} catch(...) {
|
||||
}
|
||||
// case: id is wrong
|
||||
try {
|
||||
char msg[13+2];
|
||||
PeerMessageUtil::createPeerMessageString(msg, sizeof(msg), 11, 8);
|
||||
PieceMessage::create(&msg[4], 11);
|
||||
CPPUNIT_FAIL("exception must be threw.");
|
||||
} catch(...) {
|
||||
}
|
||||
}
|
||||
|
||||
void PieceMessageTest::testGetMessageHeader() {
|
||||
PieceMessage msg;
|
||||
msg.setIndex(12345);
|
||||
msg.setBegin(256);
|
||||
msg.setBlockLength(1024);
|
||||
char data[13];
|
||||
PeerMessageUtil::createPeerMessageString(data, sizeof(data), 9+1024, 7);
|
||||
PeerMessageUtil::setIntParam(&data[5], 12345);
|
||||
PeerMessageUtil::setIntParam(&data[9], 256);
|
||||
CPPUNIT_ASSERT(memcmp(msg.getMessageHeader(), data, 13) == 0);
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
#include "RejectMessage.h"
|
||||
#include "PeerMessageUtil.h"
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class RejectMessageTest:public CppUnit::TestFixture {
|
||||
|
||||
CPPUNIT_TEST_SUITE(RejectMessageTest);
|
||||
CPPUNIT_TEST(testCreate);
|
||||
CPPUNIT_TEST(testGetMessage);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
private:
|
||||
|
||||
public:
|
||||
void setUp() {
|
||||
}
|
||||
|
||||
void testCreate();
|
||||
void testGetMessage();
|
||||
};
|
||||
|
||||
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION(RejectMessageTest);
|
||||
|
||||
void RejectMessageTest::testCreate() {
|
||||
char msg[17];
|
||||
PeerMessageUtil::createPeerMessageString(msg, sizeof(msg), 13, 16);
|
||||
PeerMessageUtil::setIntParam(&msg[5], 12345);
|
||||
PeerMessageUtil::setIntParam(&msg[9], 256);
|
||||
PeerMessageUtil::setIntParam(&msg[13], 1024);
|
||||
RejectMessage* pm = RejectMessage::create(&msg[4], 13);
|
||||
CPPUNIT_ASSERT_EQUAL(16, pm->getId());
|
||||
CPPUNIT_ASSERT_EQUAL(12345, pm->getIndex());
|
||||
CPPUNIT_ASSERT_EQUAL(256, pm->getBegin());
|
||||
CPPUNIT_ASSERT_EQUAL(1024, pm->getLength());
|
||||
|
||||
// case: payload size is wrong
|
||||
try {
|
||||
char msg[18];
|
||||
PeerMessageUtil::createPeerMessageString(msg, sizeof(msg), 14, 16);
|
||||
RejectMessage::create(&msg[4], 14);
|
||||
CPPUNIT_FAIL("exception must be threw.");
|
||||
} catch(...) {
|
||||
}
|
||||
// case: id is wrong
|
||||
try {
|
||||
char msg[17];
|
||||
PeerMessageUtil::createPeerMessageString(msg, sizeof(msg), 13, 17);
|
||||
RejectMessage::create(&msg[4], 13);
|
||||
CPPUNIT_FAIL("exception must be threw.");
|
||||
} catch(...) {
|
||||
}
|
||||
}
|
||||
|
||||
void RejectMessageTest::testGetMessage() {
|
||||
RejectMessage msg;
|
||||
msg.setIndex(12345);
|
||||
msg.setBegin(256);
|
||||
msg.setLength(1024);
|
||||
char data[17];
|
||||
PeerMessageUtil::createPeerMessageString(data, sizeof(data), 13, 16);
|
||||
PeerMessageUtil::setIntParam(&data[5], 12345);
|
||||
PeerMessageUtil::setIntParam(&data[9], 256);
|
||||
PeerMessageUtil::setIntParam(&data[13], 1024);
|
||||
CPPUNIT_ASSERT(memcmp(msg.getMessage(), data, 17) == 0);
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
#include "RequestMessage.h"
|
||||
#include "PeerMessageUtil.h"
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class RequestMessageTest:public CppUnit::TestFixture {
|
||||
|
||||
CPPUNIT_TEST_SUITE(RequestMessageTest);
|
||||
CPPUNIT_TEST(testCreate);
|
||||
CPPUNIT_TEST(testGetMessage);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
private:
|
||||
|
||||
public:
|
||||
void setUp() {
|
||||
}
|
||||
|
||||
void testCreate();
|
||||
void testGetMessage();
|
||||
};
|
||||
|
||||
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION(RequestMessageTest);
|
||||
|
||||
void RequestMessageTest::testCreate() {
|
||||
char msg[17];
|
||||
PeerMessageUtil::createPeerMessageString(msg, sizeof(msg), 13, 6);
|
||||
PeerMessageUtil::setIntParam(&msg[5], 12345);
|
||||
PeerMessageUtil::setIntParam(&msg[9], 256);
|
||||
PeerMessageUtil::setIntParam(&msg[13], 1024);
|
||||
RequestMessage* pm = RequestMessage::create(&msg[4], 13);
|
||||
CPPUNIT_ASSERT_EQUAL(6, pm->getId());
|
||||
CPPUNIT_ASSERT_EQUAL(12345, pm->getIndex());
|
||||
CPPUNIT_ASSERT_EQUAL(256, pm->getBegin());
|
||||
CPPUNIT_ASSERT_EQUAL(1024, pm->getLength());
|
||||
|
||||
// case: payload size is wrong
|
||||
try {
|
||||
char msg[18];
|
||||
PeerMessageUtil::createPeerMessageString(msg, sizeof(msg), 14, 6);
|
||||
RequestMessage::create(&msg[4], 14);
|
||||
CPPUNIT_FAIL("exception must be threw.");
|
||||
} catch(...) {
|
||||
}
|
||||
// case: id is wrong
|
||||
try {
|
||||
char msg[17];
|
||||
PeerMessageUtil::createPeerMessageString(msg, sizeof(msg), 13, 7);
|
||||
RequestMessage::create(&msg[4], 13);
|
||||
CPPUNIT_FAIL("exception must be threw.");
|
||||
} catch(...) {
|
||||
}
|
||||
}
|
||||
|
||||
void RequestMessageTest::testGetMessage() {
|
||||
RequestMessage msg;
|
||||
msg.setIndex(12345);
|
||||
msg.setBegin(256);
|
||||
msg.setLength(1024);
|
||||
char data[17];
|
||||
PeerMessageUtil::createPeerMessageString(data, sizeof(data), 13, 6);
|
||||
PeerMessageUtil::setIntParam(&data[5], 12345);
|
||||
PeerMessageUtil::setIntParam(&data[9], 256);
|
||||
PeerMessageUtil::setIntParam(&data[13], 1024);
|
||||
CPPUNIT_ASSERT(memcmp(msg.getMessage(), data, 17) == 0);
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
#include "SuggestPieceMessage.h"
|
||||
#include "PeerMessageUtil.h"
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class SuggestPieceMessageTest:public CppUnit::TestFixture {
|
||||
|
||||
CPPUNIT_TEST_SUITE(SuggestPieceMessageTest);
|
||||
CPPUNIT_TEST(testCreate);
|
||||
CPPUNIT_TEST(testGetMessage);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
private:
|
||||
|
||||
public:
|
||||
void setUp() {
|
||||
}
|
||||
|
||||
void testCreate();
|
||||
void testGetMessage();
|
||||
};
|
||||
|
||||
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION(SuggestPieceMessageTest);
|
||||
|
||||
void SuggestPieceMessageTest::testCreate() {
|
||||
char msg[9];
|
||||
PeerMessageUtil::createPeerMessageString(msg, sizeof(msg), 5, 13);
|
||||
PeerMessageUtil::setIntParam(&msg[5], 12345);
|
||||
SuggestPieceMessage* pm = SuggestPieceMessage::create(&msg[4], 5);
|
||||
CPPUNIT_ASSERT_EQUAL(13, pm->getId());
|
||||
CPPUNIT_ASSERT_EQUAL(12345, pm->getIndex());
|
||||
|
||||
// case: payload size is wrong
|
||||
try {
|
||||
char msg[10];
|
||||
PeerMessageUtil::createPeerMessageString(msg, sizeof(msg), 6, 13);
|
||||
SuggestPieceMessage::create(&msg[4], 2);
|
||||
CPPUNIT_FAIL("exception must be threw.");
|
||||
} catch(...) {
|
||||
}
|
||||
// case: id is wrong
|
||||
try {
|
||||
char msg[9];
|
||||
PeerMessageUtil::createPeerMessageString(msg, sizeof(msg), 5, 14);
|
||||
SuggestPieceMessage::create(&msg[4], 1);
|
||||
CPPUNIT_FAIL("exception must be threw.");
|
||||
} catch(...) {
|
||||
}
|
||||
}
|
||||
|
||||
void SuggestPieceMessageTest::testGetMessage() {
|
||||
SuggestPieceMessage msg;
|
||||
msg.setIndex(12345);
|
||||
char data[9];
|
||||
PeerMessageUtil::createPeerMessageString(data, sizeof(data), 5, 13);
|
||||
PeerMessageUtil::setIntParam(&data[5], 12345);
|
||||
CPPUNIT_ASSERT(memcmp(msg.getMessage(), data, 9) == 0);
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
#include "UnchokeMessage.h"
|
||||
#include "PeerMessageUtil.h"
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class UnchokeMessageTest:public CppUnit::TestFixture {
|
||||
|
||||
CPPUNIT_TEST_SUITE(UnchokeMessageTest);
|
||||
CPPUNIT_TEST(testCreate);
|
||||
CPPUNIT_TEST(testGetMessage);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
private:
|
||||
|
||||
public:
|
||||
void setUp() {
|
||||
}
|
||||
|
||||
void testCreate();
|
||||
void testGetMessage();
|
||||
};
|
||||
|
||||
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION(UnchokeMessageTest);
|
||||
|
||||
void UnchokeMessageTest::testCreate() {
|
||||
char msg[5];
|
||||
PeerMessageUtil::createPeerMessageString(msg, sizeof(msg), 1, 1);
|
||||
PeerMessage* pm = UnchokeMessage::create(&msg[4], 1);
|
||||
CPPUNIT_ASSERT_EQUAL(1, pm->getId());
|
||||
|
||||
// case: payload size is wrong
|
||||
try {
|
||||
char msg[6];
|
||||
PeerMessageUtil::createPeerMessageString(msg, sizeof(msg), 2, 1);
|
||||
UnchokeMessage::create(&msg[4], 2);
|
||||
CPPUNIT_FAIL("exception must be threw.");
|
||||
} catch(...) {
|
||||
}
|
||||
// case: id is wrong
|
||||
try {
|
||||
char msg[5];
|
||||
PeerMessageUtil::createPeerMessageString(msg, sizeof(msg), 1, 2);
|
||||
UnchokeMessage::create(&msg[4], 1);
|
||||
CPPUNIT_FAIL("exception must be threw.");
|
||||
} catch(...) {
|
||||
}
|
||||
}
|
||||
|
||||
void UnchokeMessageTest::testGetMessage() {
|
||||
UnchokeMessage msg;
|
||||
char data[5];
|
||||
PeerMessageUtil::createPeerMessageString(data, sizeof(data), 1, 1);
|
||||
CPPUNIT_ASSERT(memcmp(msg.getMessage(), data, 5) == 0);
|
||||
}
|
|
@ -15,6 +15,7 @@ class UtilTest:public CppUnit::TestFixture {
|
|||
CPPUNIT_TEST(testStartsWith);
|
||||
// may be moved to other helper class in the future.
|
||||
CPPUNIT_TEST(testGetContentDispositionFilename);
|
||||
CPPUNIT_TEST(testComputeFastSet);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
private:
|
||||
|
||||
|
@ -28,6 +29,7 @@ public:
|
|||
void testEndsWith();
|
||||
void testReplace();
|
||||
void testStartsWith();
|
||||
void testComputeFastSet();
|
||||
// may be moved to other helper class in the future.
|
||||
void testGetContentDispositionFilename();
|
||||
};
|
||||
|
@ -175,3 +177,34 @@ void UtilTest::testGetContentDispositionFilename() {
|
|||
string h4 = "attachment;";
|
||||
CPPUNIT_ASSERT_EQUAL(string(""), Util::getContentDispositionFilename(h4));
|
||||
}
|
||||
|
||||
class Printer {
|
||||
public:
|
||||
template<class T>
|
||||
void operator()(T t) {
|
||||
cerr << t << ", ";
|
||||
}
|
||||
};
|
||||
|
||||
void UtilTest::testComputeFastSet() {
|
||||
string ipaddr = "192.168.0.1";
|
||||
unsigned char infoHash[20];
|
||||
memset(infoHash, 0, sizeof(infoHash));
|
||||
infoHash[0] = 0xff;
|
||||
|
||||
int pieces = 1000;
|
||||
int fastSetSize = 10;
|
||||
|
||||
Integers fastSet = Util::computeFastSet(ipaddr, infoHash, pieces, fastSetSize);
|
||||
//for_each(fastSet.begin(), fastSet.end(), Printer());
|
||||
//cerr << endl;
|
||||
int ans1[] = { 686, 459, 278, 200, 404, 834, 64, 203, 760, 950 };
|
||||
Integers ansSet1(&ans1[0], &ans1[10]);
|
||||
CPPUNIT_ASSERT(equal(fastSet.begin(), fastSet.end(), ansSet1.begin()));
|
||||
|
||||
ipaddr = "10.0.0.1";
|
||||
fastSet = Util::computeFastSet(ipaddr, infoHash, pieces, fastSetSize);
|
||||
int ans2[] = { 568, 188, 466, 452, 550, 662, 109, 226, 398, 11 };
|
||||
Integers ansSet2(&ans2[0], &ans2[10]);
|
||||
CPPUNIT_ASSERT(equal(fastSet.begin(), fastSet.end(), ansSet2.begin()));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue