mirror of https://github.com/aria2/aria2
2007-12-22 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Added uTorrent compatible Peer Exchange. * src/BencodeVisitor.{h, cc} * test/BencodeVisitorTest.cc * src/BtConstants.h * src/BtContext.h: Added 'private' flag. * src/BtExtendedMessage.{h, cc} * test/BtExtendedMessageTest.cc * src/BtHandshakeMessage.{h, cc}: Set extended messaging bit in reserved field. * test/BtHandshakeMessageTest.cc * src/BtMessageFactory.h * src/BtRegistry.h * src/BtRuntime.h: This class holds default extension message IDs for aria2. By default, aria2 uses ID 8 for ut_pex. * src/DefaultBtContext.cc * src/DefaultBtInteractive.{h, cc}: This class holds _utPexEnabled. When it is true, aria2 enables ut_pex. This value is set by PeerInteractionCommand. * src/DefaultBtMessageFactory.{h, cc} * test/DefaultBtMessageFactoryTest.cc * src/DefaultBtMessageReceiver.cc: Moved the code of fast extension handling to DefaultBtInteractive class. * src/DefaultExtensionMessageFactory.{h, cc} * test/DefaultExtensionMessageFactoryTest.cc * src/DefaultPeerStorage.cc: Returns false if a peer is already in the container(peers and incomingPeers. The equality is determined by Peer::id). * test/DefaultPeerStorageTest.cc * src/ExtensionMessage.h * test/MockExtensionMessage.h * src/ExtensionMessageFactory.h * test/MockExtensionMessageFactory.h * src/HandshakeExtensionMessage.{h, cc} * test/HandshakeExtensionMessageTest.cc * src/MetaEntry.h * src/Peer.{h, cc} * src/PeerInteractionCommand.cc * src/PeerReceiveHandshakeCommand.cc: Evaluate the return value of addIncomingPeer. * src/PeerMessageUtil.{h, cc} * src/PeerObject.h * src/UTPexExtensionMessage.{h, cc} * test/UTPexExtensionMessageTest.cc * src/message.h * src/prefs.h Fixed the bug that returns incomplete data when it contains null character. A convenient constructor was also added. * src/Data.{h, cc} Rewritten. * src/CompactPeerListProcessor.cc Fixed typos. * src/message.h * src/MetaFileUtil.ccpull/1/head
parent
c25f4cffc0
commit
286f34cb3f
59
ChangeLog
59
ChangeLog
|
@ -1,3 +1,62 @@
|
|||
2007-12-22 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
||||
|
||||
Added uTorrent compatible Peer Exchange.
|
||||
* src/BencodeVisitor.{h, cc}
|
||||
* test/BencodeVisitorTest.cc
|
||||
* src/BtConstants.h
|
||||
* src/BtContext.h: Added 'private' flag.
|
||||
* src/BtExtendedMessage.{h, cc}
|
||||
* test/BtExtendedMessageTest.cc
|
||||
* src/BtHandshakeMessage.{h, cc}: Set extended messaging bit in
|
||||
reserved field.
|
||||
* test/BtHandshakeMessageTest.cc
|
||||
* src/BtMessageFactory.h
|
||||
* src/BtRegistry.h
|
||||
* src/BtRuntime.h: This class holds default extension message IDs for
|
||||
aria2. By default, aria2 uses ID 8 for ut_pex.
|
||||
* src/DefaultBtContext.cc
|
||||
* src/DefaultBtInteractive.{h, cc}: This class holds _utPexEnabled.
|
||||
When it is true, aria2 enables ut_pex. This value is set by
|
||||
PeerInteractionCommand.
|
||||
* src/DefaultBtMessageFactory.{h, cc}
|
||||
* test/DefaultBtMessageFactoryTest.cc
|
||||
* src/DefaultBtMessageReceiver.cc: Moved the code of fast extension
|
||||
handling to DefaultBtInteractive class.
|
||||
* src/DefaultExtensionMessageFactory.{h, cc}
|
||||
* test/DefaultExtensionMessageFactoryTest.cc
|
||||
* src/DefaultPeerStorage.cc: Returns false if a peer is already in
|
||||
the container(peers and incomingPeers. The equality is determined by
|
||||
Peer::id).
|
||||
* test/DefaultPeerStorageTest.cc
|
||||
* src/ExtensionMessage.h
|
||||
* test/MockExtensionMessage.h
|
||||
* src/ExtensionMessageFactory.h
|
||||
* test/MockExtensionMessageFactory.h
|
||||
* src/HandshakeExtensionMessage.{h, cc}
|
||||
* test/HandshakeExtensionMessageTest.cc
|
||||
* src/MetaEntry.h
|
||||
* src/Peer.{h, cc}
|
||||
* src/PeerInteractionCommand.cc
|
||||
* src/PeerReceiveHandshakeCommand.cc: Evaluate the return value of
|
||||
addIncomingPeer.
|
||||
* src/PeerMessageUtil.{h, cc}
|
||||
* src/PeerObject.h
|
||||
* src/UTPexExtensionMessage.{h, cc}
|
||||
* test/UTPexExtensionMessageTest.cc
|
||||
* src/message.h
|
||||
* src/prefs.h
|
||||
|
||||
Fixed the bug that returns incomplete data when it contains null
|
||||
character. A convenient constructor was also added.
|
||||
* src/Data.{h, cc}
|
||||
|
||||
Rewritten.
|
||||
* src/CompactPeerListProcessor.cc
|
||||
|
||||
Fixed typos.
|
||||
* src/message.h
|
||||
* src/MetaFileUtil.cc
|
||||
|
||||
2007-12-16 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
||||
|
||||
Added "Status Legend" label to the explanation text of 'stat' in
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
/* <!-- copyright */
|
||||
/*
|
||||
* aria2 - The high speed download utility
|
||||
*
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* In addition, as a special exception, the copyright holders give
|
||||
* permission to link the code of portions of this program with the
|
||||
* OpenSSL library under certain conditions as described in each
|
||||
* individual source file, and distribute linked combinations
|
||||
* including the two.
|
||||
* You must obey the GNU General Public License in all respects
|
||||
* for all of the code used other than OpenSSL. If you modify
|
||||
* file(s) with this exception, you may extend this exception to your
|
||||
* version of the file(s), but you are not obligated to do so. If you
|
||||
* do not wish to do so, delete this exception statement from your
|
||||
* version. If you delete this exception statement from all source
|
||||
* files in the program, then also delete it here.
|
||||
*/
|
||||
/* copyright --> */
|
||||
#include "BencodeVisitor.h"
|
||||
#include "Data.h"
|
||||
#include "List.h"
|
||||
#include "Dictionary.h"
|
||||
#include "Util.h"
|
||||
|
||||
BencodeVisitor::BencodeVisitor() {}
|
||||
|
||||
BencodeVisitor::~BencodeVisitor() {}
|
||||
|
||||
void BencodeVisitor::visit(const Data* d)
|
||||
{
|
||||
if(d->isNumber()) {
|
||||
_bencodedData += "i"+d->toString()+"e";
|
||||
} else {
|
||||
_bencodedData += Util::itos(d->getLen())+":"+d->toString();
|
||||
}
|
||||
}
|
||||
|
||||
void BencodeVisitor::visit(const List* l)
|
||||
{
|
||||
_bencodedData += "l";
|
||||
for_each(l->getList().begin(), l->getList().end(),
|
||||
bind2nd(mem_fun(&MetaEntry::accept), this));
|
||||
_bencodedData += "e";
|
||||
}
|
||||
|
||||
void BencodeVisitor::visit(const Dictionary* d)
|
||||
{
|
||||
_bencodedData += "d";
|
||||
|
||||
for(Order::const_iterator itr = d->getOrder().begin(); itr != d->getOrder().end(); ++itr) {
|
||||
_bencodedData += Util::itos((int32_t)(*itr).size());
|
||||
_bencodedData += ":";
|
||||
_bencodedData += *itr;
|
||||
d->get(*itr)->accept(this);
|
||||
}
|
||||
_bencodedData += "e";
|
||||
}
|
||||
|
||||
void BencodeVisitor::visit(const MetaEntry* e)
|
||||
{
|
||||
if(dynamic_cast<const Data*>(e) != 0) {
|
||||
visit((const Data*)e);
|
||||
} else if(dynamic_cast<const List*>(e) != 0) {
|
||||
visit((const List*)e);
|
||||
} else if(dynamic_cast<const Dictionary*>(e) != 0) {
|
||||
visit((const Dictionary*)e);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
/* <!-- copyright */
|
||||
/*
|
||||
* aria2 - The high speed download utility
|
||||
*
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* In addition, as a special exception, the copyright holders give
|
||||
* permission to link the code of portions of this program with the
|
||||
* OpenSSL library under certain conditions as described in each
|
||||
* individual source file, and distribute linked combinations
|
||||
* including the two.
|
||||
* You must obey the GNU General Public License in all respects
|
||||
* for all of the code used other than OpenSSL. If you modify
|
||||
* file(s) with this exception, you may extend this exception to your
|
||||
* version of the file(s), but you are not obligated to do so. If you
|
||||
* do not wish to do so, delete this exception statement from your
|
||||
* version. If you delete this exception statement from all source
|
||||
* files in the program, then also delete it here.
|
||||
*/
|
||||
/* copyright --> */
|
||||
#ifndef _D_BENCODE_VISITOR_H_
|
||||
#define _D_BENCODE_VISITOR_H_
|
||||
|
||||
#include "MetaEntryVisitor.h"
|
||||
|
||||
class Data;
|
||||
class Dictionary;
|
||||
class List;
|
||||
class MetaEntry;
|
||||
|
||||
class BencodeVisitor : public MetaEntryVisitor {
|
||||
private:
|
||||
string _bencodedData;
|
||||
public:
|
||||
BencodeVisitor();
|
||||
~BencodeVisitor();
|
||||
|
||||
void visit(const Data* d);
|
||||
void visit(const Dictionary* d);
|
||||
void visit(const List* l);
|
||||
|
||||
virtual void visit(const MetaEntry* e);
|
||||
|
||||
const string& getBencodedData() const
|
||||
{
|
||||
return _bencodedData;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // _D_BENCODE_VISITOR_H_
|
|
@ -0,0 +1,43 @@
|
|||
/* <!-- copyright */
|
||||
/*
|
||||
* aria2 - The high speed download utility
|
||||
*
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* In addition, as a special exception, the copyright holders give
|
||||
* permission to link the code of portions of this program with the
|
||||
* OpenSSL library under certain conditions as described in each
|
||||
* individual source file, and distribute linked combinations
|
||||
* including the two.
|
||||
* You must obey the GNU General Public License in all respects
|
||||
* for all of the code used other than OpenSSL. If you modify
|
||||
* file(s) with this exception, you may extend this exception to your
|
||||
* version of the file(s), but you are not obligated to do so. If you
|
||||
* do not wish to do so, delete this exception statement from your
|
||||
* version. If you delete this exception statement from all source
|
||||
* files in the program, then also delete it here.
|
||||
*/
|
||||
/* copyright --> */
|
||||
#ifndef _D_BT_CONSTANTS_
|
||||
#define _D_BT_CONSTANTS_
|
||||
|
||||
#include "common.h"
|
||||
#include <map>
|
||||
|
||||
typedef map<string, uint8_t> Extensions;
|
||||
|
||||
#endif // _D_BT_CONSTANTS_
|
|
@ -48,7 +48,11 @@ typedef deque<AnnounceTierHandle> AnnounceTiers;
|
|||
class RequestGroup;
|
||||
|
||||
class BtContext:public DownloadContext {
|
||||
protected:
|
||||
bool _private;
|
||||
public:
|
||||
BtContext():_private(false) {}
|
||||
|
||||
virtual ~BtContext() {}
|
||||
|
||||
virtual const unsigned char* getInfoHash() const = 0;
|
||||
|
@ -66,6 +70,11 @@ public:
|
|||
*/
|
||||
virtual const unsigned char* getPeerId() = 0;
|
||||
|
||||
bool isPrivate() const
|
||||
{
|
||||
return _private;
|
||||
}
|
||||
|
||||
virtual Integers computeFastSet(const string& ipaddr, int32_t fastSetSize) = 0;
|
||||
|
||||
virtual RequestGroup* getOwnerRequestGroup() = 0;
|
||||
|
|
|
@ -0,0 +1,115 @@
|
|||
/* <!-- copyright */
|
||||
/*
|
||||
* aria2 - The high speed download utility
|
||||
*
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* In addition, as a special exception, the copyright holders give
|
||||
* permission to link the code of portions of this program with the
|
||||
* OpenSSL library under certain conditions as described in each
|
||||
* individual source file, and distribute linked combinations
|
||||
* including the two.
|
||||
* You must obey the GNU General Public License in all respects
|
||||
* for all of the code used other than OpenSSL. If you modify
|
||||
* file(s) with this exception, you may extend this exception to your
|
||||
* version of the file(s), but you are not obligated to do so. If you
|
||||
* do not wish to do so, delete this exception statement from your
|
||||
* version. If you delete this exception statement from all source
|
||||
* files in the program, then also delete it here.
|
||||
*/
|
||||
/* copyright --> */
|
||||
#include "BtExtendedMessage.h"
|
||||
#include "BtRegistry.h"
|
||||
#include "ExtensionMessage.h"
|
||||
#include "PeerMessageUtil.h"
|
||||
#include "DlAbortEx.h"
|
||||
#include "message.h"
|
||||
#include "Util.h"
|
||||
|
||||
BtExtendedMessage::BtExtendedMessage(const ExtensionMessageHandle& extensionMessage):_extensionMessage(extensionMessage), _msg(0), _msgLength(0)
|
||||
{}
|
||||
|
||||
BtExtendedMessage::~BtExtendedMessage()
|
||||
{
|
||||
delete [] _msg;
|
||||
}
|
||||
|
||||
const unsigned char* BtExtendedMessage::getMessage() {
|
||||
if(!_msg) {
|
||||
/**
|
||||
* len --- 2+extpayload.length, 4bytes
|
||||
* id --- 20, 1byte
|
||||
* extmsgid --- extmsgid, 1byte
|
||||
* extpayload --- extpayload, nbytes
|
||||
* total: 6+extpayload.length bytes
|
||||
*/
|
||||
string payload = _extensionMessage->getBencodedData();
|
||||
_msgLength = 6+payload.size();
|
||||
_msg = new unsigned char[_msgLength];
|
||||
PeerMessageUtil::createPeerMessageString(_msg, _msgLength, 2+payload.size(), ID);
|
||||
*(_msg+5) = _extensionMessage->getExtensionMessageID();
|
||||
memcpy(_msg+6, payload.c_str(), payload.size());
|
||||
}
|
||||
return _msg;
|
||||
}
|
||||
|
||||
int32_t BtExtendedMessage::getMessageLength() {
|
||||
getMessage();
|
||||
return _msgLength;
|
||||
}
|
||||
|
||||
bool BtExtendedMessage::sendPredicate() const
|
||||
{
|
||||
return peer->isExtendedMessagingEnabled();
|
||||
}
|
||||
|
||||
string BtExtendedMessage::toString() const {
|
||||
return "extended "+_extensionMessage->toString();
|
||||
}
|
||||
|
||||
BtExtendedMessageHandle
|
||||
BtExtendedMessage::create(const BtContextHandle& btContext,
|
||||
const PeerHandle& peer,
|
||||
const char* data, size_t dataLength)
|
||||
{
|
||||
if(dataLength < 2) {
|
||||
throw new DlAbortEx(MSG_TOO_SMALL_PAYLOAD_SIZE, "extended", dataLength);
|
||||
}
|
||||
int8_t id = PeerMessageUtil::getId((const unsigned char*)data);
|
||||
if(id != ID) {
|
||||
throw new DlAbortEx(EX_INVALID_BT_MESSAGE_ID, id, "extended", ID);
|
||||
}
|
||||
ExtensionMessageFactoryHandle factory = EXTENSION_MESSAGE_FACTORY(btContext,
|
||||
peer);
|
||||
assert(!factory.isNull());
|
||||
ExtensionMessageHandle extmsg = factory->createMessage(data+1,
|
||||
dataLength-1);
|
||||
BtExtendedMessageHandle message = new BtExtendedMessage(extmsg);
|
||||
return message;
|
||||
}
|
||||
|
||||
void BtExtendedMessage::doReceivedAction()
|
||||
{
|
||||
if(!_extensionMessage.isNull()) {
|
||||
_extensionMessage->doReceivedAction();
|
||||
}
|
||||
}
|
||||
|
||||
ExtensionMessageHandle BtExtendedMessage::getExtensionMessage() const
|
||||
{
|
||||
return _extensionMessage;
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
/* <!-- copyright */
|
||||
/*
|
||||
* aria2 - The high speed download utility
|
||||
*
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* In addition, as a special exception, the copyright holders give
|
||||
* permission to link the code of portions of this program with the
|
||||
* OpenSSL library under certain conditions as described in each
|
||||
* individual source file, and distribute linked combinations
|
||||
* including the two.
|
||||
* You must obey the GNU General Public License in all respects
|
||||
* for all of the code used other than OpenSSL. If you modify
|
||||
* file(s) with this exception, you may extend this exception to your
|
||||
* version of the file(s), but you are not obligated to do so. If you
|
||||
* do not wish to do so, delete this exception statement from your
|
||||
* version. If you delete this exception statement from all source
|
||||
* files in the program, then also delete it here.
|
||||
*/
|
||||
/* copyright --> */
|
||||
#ifndef _D_BT_EXTENDED_MESSAGE_H_
|
||||
#define _D_BT_EXTENDED_MESSAGE_H_
|
||||
#include "SimpleBtMessage.h"
|
||||
|
||||
class BtExtendedMessage;
|
||||
typedef SharedHandle<BtExtendedMessage> BtExtendedMessageHandle;
|
||||
class ExtensionMessage;
|
||||
typedef SharedHandle<ExtensionMessage> ExtensionMessageHandle;
|
||||
|
||||
class BtExtendedMessage:public SimpleBtMessage
|
||||
{
|
||||
private:
|
||||
ExtensionMessageHandle _extensionMessage;
|
||||
|
||||
unsigned char* _msg;
|
||||
|
||||
size_t _msgLength;
|
||||
public:
|
||||
BtExtendedMessage(const ExtensionMessageHandle& extensionMessage = 0);
|
||||
|
||||
virtual ~BtExtendedMessage();
|
||||
|
||||
static const uint8_t ID = 20;
|
||||
|
||||
static BtExtendedMessageHandle create(const BtContextHandle& btContext,
|
||||
const PeerHandle& peer,
|
||||
const char* data,
|
||||
size_t dataLength);
|
||||
|
||||
virtual int8_t getId() { return ID; }
|
||||
|
||||
virtual void doReceivedAction();
|
||||
|
||||
virtual const unsigned char* getMessage();
|
||||
|
||||
virtual int32_t getMessageLength();
|
||||
|
||||
virtual bool sendPredicate() const;
|
||||
|
||||
virtual string toString() const;
|
||||
|
||||
ExtensionMessageHandle getExtensionMessage() const;
|
||||
};
|
||||
|
||||
#endif // _D_BT_EXTENDED_MESSAGE_H_
|
|
@ -61,6 +61,8 @@ void BtHandshakeMessage::init() {
|
|||
memset(this->reserved, 0, RESERVED_LENGTH);
|
||||
// fast extension
|
||||
this->reserved[7] |= 0x04;
|
||||
// extended messaging
|
||||
this->reserved[5] |= 0x10;
|
||||
}
|
||||
|
||||
BtHandshakeMessageHandle BtHandshakeMessage::create(const unsigned char* data, int32_t dataLength) {
|
||||
|
@ -98,3 +100,8 @@ string BtHandshakeMessage::toString() const {
|
|||
bool BtHandshakeMessage::isFastExtensionSupported() const {
|
||||
return reserved[7]&0x04;
|
||||
}
|
||||
|
||||
bool BtHandshakeMessage::isExtendedMessagingEnabled() const
|
||||
{
|
||||
return reserved[5]&0x10;
|
||||
}
|
||||
|
|
|
@ -87,6 +87,8 @@ public:
|
|||
|
||||
bool isFastExtensionSupported() const;
|
||||
|
||||
bool isExtendedMessagingEnabled() const;
|
||||
|
||||
int8_t getPstrlen() const {
|
||||
return pstrlen;
|
||||
}
|
||||
|
|
|
@ -39,6 +39,9 @@
|
|||
#include "BtMessage.h"
|
||||
#include "Piece.h"
|
||||
|
||||
class ExtensionMessage;
|
||||
typedef SharedHandle<ExtensionMessage> ExensionMessageHandle;
|
||||
|
||||
class BtMessageFactory {
|
||||
public:
|
||||
virtual ~BtMessageFactory() {}
|
||||
|
@ -84,6 +87,8 @@ public:
|
|||
createRejectMessage(int32_t index, int32_t begin, int32_t length) = 0;
|
||||
|
||||
virtual BtMessageHandle createAllowedFastMessage(int32_t index) = 0;
|
||||
|
||||
virtual BtMessageHandle createBtExtendedMessage(const ExensionMessageHandle& msg) = 0;
|
||||
};
|
||||
|
||||
typedef SharedHandle<BtMessageFactory> BtMessageFactoryHandle;
|
||||
|
|
|
@ -146,4 +146,7 @@ PEER_OBJECT(btContext, peer)->btRequestFactory
|
|||
#define PEER_CONNECTION(btContext, peer) \
|
||||
PEER_OBJECT(btContext, peer)->peerConnection
|
||||
|
||||
#define EXTENSION_MESSAGE_FACTORY(btContext, peer) \
|
||||
PEER_OBJECT(btContext, peer)->extensionMessageFactory
|
||||
|
||||
#endif // _D_BT_REGISTRY_H_
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
#define _D_BT_RUNTIME_H_
|
||||
|
||||
#include "common.h"
|
||||
#include "SharedHandle.h"
|
||||
#include "BtConstants.h"
|
||||
|
||||
#define MIN_PEERS 40
|
||||
|
||||
|
@ -47,6 +47,8 @@ private:
|
|||
bool halt;
|
||||
int32_t connections;
|
||||
bool _ready;
|
||||
|
||||
Extensions _extensions;
|
||||
public:
|
||||
BtRuntime():
|
||||
uploadLengthAtStartup(0),
|
||||
|
@ -54,7 +56,9 @@ public:
|
|||
halt(false),
|
||||
connections(0),
|
||||
_ready(false)
|
||||
{}
|
||||
{
|
||||
_extensions["ut_pex"] = 8;
|
||||
}
|
||||
~BtRuntime() {}
|
||||
|
||||
int64_t getUploadLengthAtStartup() const {
|
||||
|
@ -90,6 +94,33 @@ public:
|
|||
bool ready() { return _ready; }
|
||||
|
||||
void setReady(bool go) { _ready = go; }
|
||||
|
||||
const Extensions& getExtensions() const
|
||||
{
|
||||
return _extensions;
|
||||
}
|
||||
|
||||
uint8_t getExtensionMessageID(const string& name)
|
||||
{
|
||||
Extensions::const_iterator itr = _extensions.find(name);
|
||||
if(itr == _extensions.end()) {
|
||||
return 0;
|
||||
} else {
|
||||
return (*itr).second;
|
||||
}
|
||||
}
|
||||
|
||||
string getExtensionName(uint8_t id)
|
||||
{
|
||||
for(Extensions::const_iterator itr = _extensions.begin();
|
||||
itr != _extensions.end(); ++itr) {
|
||||
const Extensions::value_type& p = *itr;
|
||||
if(p.second == id) {
|
||||
return p.first;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
};
|
||||
|
||||
typedef SharedHandle<BtRuntime> BtRuntimeHandle;
|
||||
|
|
|
@ -43,19 +43,13 @@ Peers CompactPeerListProcessor::extractPeer(const MetaEntry* peersEntry) {
|
|||
Peers peers;
|
||||
|
||||
const Data* peersData = (const Data*)peersEntry;
|
||||
if(peersData->getLen() > 0) {
|
||||
if(peersData->getLen()%6 == 0) {
|
||||
for(int32_t i = 0; i < peersData->getLen(); i += 6) {
|
||||
uint32_t ipaddr1 = (unsigned char)*(peersData->getData()+i);
|
||||
uint32_t ipaddr2 = (unsigned char)*(peersData->getData()+i+1);
|
||||
uint32_t ipaddr3 = (unsigned char)*(peersData->getData()+i+2);
|
||||
uint32_t ipaddr4 = (unsigned char)*(peersData->getData()+i+3);
|
||||
int32_t port = ntohs(*(uint16_t*)(peersData->getData()+i+4));
|
||||
char ipaddr[16];
|
||||
|
||||
snprintf(ipaddr, sizeof(ipaddr), "%d.%d.%d.%d",
|
||||
ipaddr1, ipaddr2, ipaddr3, ipaddr4);
|
||||
struct in_addr in;
|
||||
in.s_addr = *(uint32_t*)(peersData->getData()+i);
|
||||
string ipaddr = inet_ntoa(in);
|
||||
uint16_t port = ntohs(*(uint16_t*)(peersData->getData()+i+4));
|
||||
PeerHandle peer = new Peer(ipaddr, port, pieceLength, totalLength);
|
||||
|
||||
peers.push_back(peer);
|
||||
}
|
||||
}
|
||||
|
|
23
src/Data.cc
23
src/Data.cc
|
@ -46,21 +46,24 @@ Data::Data(const char* data, int32_t len, bool number):number(number) {
|
|||
}
|
||||
}
|
||||
|
||||
Data::Data(const string& data, bool number):number(number)
|
||||
{
|
||||
if(data.empty()) {
|
||||
this->data = 0;
|
||||
this->len = 0;
|
||||
} else {
|
||||
this->data = new char[data.size()];
|
||||
memcpy(this->data, data.c_str(), data.size());
|
||||
this->len = data.size();
|
||||
}
|
||||
}
|
||||
|
||||
Data::~Data() {
|
||||
delete [] data;
|
||||
}
|
||||
|
||||
string Data::toString() const {
|
||||
if(len == 0) {
|
||||
return "";
|
||||
} else {
|
||||
char* temp = new char[len+1];
|
||||
memcpy(temp, data, len);
|
||||
temp[len] = '\0';
|
||||
string str(temp);
|
||||
delete [] temp;
|
||||
return str;
|
||||
}
|
||||
return string(&data[0], &data[len]);
|
||||
}
|
||||
|
||||
const char* Data::getData() const {
|
||||
|
|
|
@ -51,6 +51,9 @@ public:
|
|||
* memory of data.
|
||||
*/
|
||||
Data(const char* data, int32_t len, bool number = false);
|
||||
|
||||
Data(const string& data, bool number = false);
|
||||
|
||||
~Data();
|
||||
|
||||
string toString() const;
|
||||
|
|
|
@ -84,6 +84,7 @@ void DefaultBtContext::clear() {
|
|||
numPieces = 0;
|
||||
name = "";
|
||||
announceTiers.clear();
|
||||
_private = false;
|
||||
}
|
||||
|
||||
void DefaultBtContext::extractPieceHash(const unsigned char* hashData,
|
||||
|
@ -240,6 +241,12 @@ void DefaultBtContext::processMetaInfo(const MetaEntry* rootEntry, const string&
|
|||
extractPieceHash((unsigned char*)pieceHashData->getData(),
|
||||
pieceHashData->getLen(),
|
||||
PIECE_HASH_LENGTH);
|
||||
const Data* privateFlag = dynamic_cast<const Data*>(infoDic->get("private"));
|
||||
if(privateFlag) {
|
||||
if(privateFlag->toString() == "1") {
|
||||
_private = true;
|
||||
}
|
||||
}
|
||||
// retrieve uri-list.
|
||||
// This implemantation obeys HTTP-Seeding specification:
|
||||
// see http://www.getright.com/seedtorrent.html
|
||||
|
|
|
@ -43,9 +43,15 @@
|
|||
#include "BtRequestMessage.h"
|
||||
#include "BtPieceMessage.h"
|
||||
#include "DlAbortEx.h"
|
||||
#include "BtExtendedMessage.h"
|
||||
#include "HandshakeExtensionMessage.h"
|
||||
#include "UTPexExtensionMessage.h"
|
||||
#include "DefaultExtensionMessageFactory.h"
|
||||
#include "BtRegistry.h"
|
||||
|
||||
void DefaultBtInteractive::initiateHandshake() {
|
||||
BtMessageHandle message = messageFactory->createHandshakeMessage(btContext->getInfoHash(),
|
||||
BtHandshakeMessageHandle message =
|
||||
messageFactory->createHandshakeMessage(btContext->getInfoHash(),
|
||||
btContext->getPeerId());
|
||||
dispatcher->addMessageToQueue(message);
|
||||
dispatcher->sendMessages();
|
||||
|
@ -58,6 +64,18 @@ BtMessageHandle DefaultBtInteractive::receiveHandshake(bool quickReply) {
|
|||
return 0;
|
||||
}
|
||||
peer->setPeerId(message->getPeerId());
|
||||
|
||||
if(message->isFastExtensionSupported()) {
|
||||
peer->setFastExtensionEnabled(true);
|
||||
logger->info(MSG_FAST_EXTENSION_ENABLED, cuid);
|
||||
}
|
||||
if(message->isExtendedMessagingEnabled()) {
|
||||
peer->setExtendedMessagingEnabled(true);
|
||||
PEER_OBJECT(btContext, peer)->extensionMessageFactory =
|
||||
new DefaultExtensionMessageFactory(btContext, peer);
|
||||
logger->info(MSG_EXTENDED_MESSAGING_ENABLED, cuid);
|
||||
}
|
||||
|
||||
logger->info(MSG_RECEIVE_PEER_MESSAGE, cuid,
|
||||
peer->ipaddr.c_str(), peer->port,
|
||||
message->toString().c_str());
|
||||
|
@ -73,11 +91,28 @@ void DefaultBtInteractive::doPostHandshakeProcessing() {
|
|||
haveCheckPoint.reset();
|
||||
keepAliveCheckPoint.reset();
|
||||
floodingCheckPoint.reset();
|
||||
_pexCheckPoint.setTimeInSec(0);
|
||||
if(peer->isExtendedMessagingEnabled()) {
|
||||
addHandshakeExtendedMessageToQueue();
|
||||
}
|
||||
addBitfieldMessageToQueue();
|
||||
addAllowedFastMessageToQueue();
|
||||
sendPendingMessage();
|
||||
}
|
||||
|
||||
void DefaultBtInteractive::addHandshakeExtendedMessageToQueue()
|
||||
{
|
||||
HandshakeExtensionMessageHandle m = new HandshakeExtensionMessage();
|
||||
m->setClientVersion("aria2");
|
||||
m->setTCPPort(btRuntime->getListenPort());
|
||||
m->setExtensions(btRuntime->getExtensions());
|
||||
|
||||
BtExtendedMessageHandle msg =
|
||||
messageFactory->createBtExtendedMessage(m);
|
||||
|
||||
dispatcher->addMessageToQueue(msg);
|
||||
}
|
||||
|
||||
void DefaultBtInteractive::addBitfieldMessageToQueue() {
|
||||
if(peer->isFastExtensionEnabled()) {
|
||||
if(pieceStorage->allDownloadFinished()) {
|
||||
|
@ -283,6 +318,45 @@ void DefaultBtInteractive::checkActiveInteraction()
|
|||
}
|
||||
}
|
||||
|
||||
void DefaultBtInteractive::addPeerExchangeMessage()
|
||||
{
|
||||
time_t interval = 60;
|
||||
if(_pexCheckPoint.elapsed(interval)) {
|
||||
UTPexExtensionMessageHandle m =
|
||||
new UTPexExtensionMessage(peer->getExtensionMessageID("ut_pex"));
|
||||
const Peers& peers = peerStorage->getPeers();
|
||||
{
|
||||
size_t max = 30;
|
||||
for(Peers::const_iterator i = peers.begin();
|
||||
i != peers.end() && max; ++i) {
|
||||
const PeerHandle& cpeer = *i;
|
||||
if(peer->ipaddr != cpeer->ipaddr &&
|
||||
!cpeer->getFirstContactTime().elapsed(interval) &&
|
||||
Util::isNumbersAndDotsNotation(cpeer->ipaddr)) {
|
||||
m->addFreshPeer(cpeer);
|
||||
--max;
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
size_t max = 10;
|
||||
for(Peers::const_reverse_iterator i = peers.rbegin();
|
||||
i != peers.rend() && max; ++i) {
|
||||
const PeerHandle& cpeer = *i;
|
||||
if(peer->ipaddr != cpeer->ipaddr &&
|
||||
!cpeer->getBadConditionStartTime().elapsed(interval) &&
|
||||
Util::isNumbersAndDotsNotation(cpeer->ipaddr)) {
|
||||
m->addDroppedPeer(cpeer);
|
||||
--max;
|
||||
}
|
||||
}
|
||||
}
|
||||
BtExtendedMessageHandle msg = messageFactory->createBtExtendedMessage(m);
|
||||
dispatcher->addMessageToQueue(msg);
|
||||
_pexCheckPoint.reset();
|
||||
}
|
||||
}
|
||||
|
||||
void DefaultBtInteractive::doInteractionProcessing() {
|
||||
checkActiveInteraction();
|
||||
|
||||
|
@ -304,5 +378,10 @@ void DefaultBtInteractive::doInteractionProcessing() {
|
|||
if(!pieceStorage->downloadFinished()) {
|
||||
addRequests();
|
||||
}
|
||||
|
||||
if(peer->getExtensionMessageID("ut_pex") && _utPexEnabled) {
|
||||
addPeerExchangeMessage();
|
||||
}
|
||||
|
||||
sendPendingMessage();
|
||||
}
|
||||
|
|
|
@ -102,13 +102,16 @@ private:
|
|||
Time floodingCheckPoint;
|
||||
FloodingStat floodingStat;
|
||||
Time inactiveCheckPoint;
|
||||
Time _pexCheckPoint;
|
||||
int32_t keepAliveInterval;
|
||||
int32_t maxDownloadSpeedLimit;
|
||||
bool _utPexEnabled;
|
||||
|
||||
static const int32_t FLOODING_CHECK_INTERVAL = 5;
|
||||
|
||||
void addBitfieldMessageToQueue();
|
||||
void addAllowedFastMessageToQueue();
|
||||
void addHandshakeExtendedMessageToQueue();
|
||||
void decideChoking();
|
||||
void checkHave();
|
||||
void sendKeepAlive();
|
||||
|
@ -117,6 +120,7 @@ private:
|
|||
void addRequests();
|
||||
void detectMessageFlooding();
|
||||
void checkActiveInteraction();
|
||||
void addPeerExchangeMessage();
|
||||
|
||||
public:
|
||||
DefaultBtInteractive():peer(0),
|
||||
|
@ -131,7 +135,8 @@ public:
|
|||
logger(LogFactory::getInstance()),
|
||||
allowedFastSetSize(10),
|
||||
keepAliveInterval(120),
|
||||
maxDownloadSpeedLimit(0)
|
||||
maxDownloadSpeedLimit(0),
|
||||
_utPexEnabled(false)
|
||||
{}
|
||||
|
||||
virtual ~DefaultBtInteractive() {}
|
||||
|
@ -202,6 +207,11 @@ public:
|
|||
void setBtMessageFactory(const BtMessageFactoryWeakHandle& factory) {
|
||||
this->messageFactory = factory;
|
||||
}
|
||||
|
||||
void setUTPexEnabled(bool f)
|
||||
{
|
||||
_utPexEnabled = f;
|
||||
}
|
||||
};
|
||||
|
||||
typedef SharedHandle<DefaultBtInteractive> DefaultBtInteractiveHandle;
|
||||
|
|
|
@ -61,6 +61,8 @@
|
|||
#include "BtAllowedFastMessageValidator.h"
|
||||
#include "BtHandshakeMessage.h"
|
||||
#include "BtHandshakeMessageValidator.h"
|
||||
#include "BtExtendedMessage.h"
|
||||
#include "ExtensionMessage.h"
|
||||
|
||||
BtMessageHandle
|
||||
DefaultBtMessageFactory::createBtMessage(const unsigned char* data, int32_t dataLength)
|
||||
|
@ -161,6 +163,14 @@ DefaultBtMessageFactory::createBtMessage(const unsigned char* data, int32_t data
|
|||
msg = temp;
|
||||
break;
|
||||
}
|
||||
case BtExtendedMessage::ID: {
|
||||
if(peer->isExtendedMessagingEnabled()) {
|
||||
msg = BtExtendedMessage::create(btContext, peer, (const char*)data, dataLength);
|
||||
} else {
|
||||
throw new DlAbortEx("Received extended message from peer during a session with extended messaging disabled.");
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new DlAbortEx("Invalid message ID. id=%d", id);
|
||||
}
|
||||
|
@ -349,3 +359,11 @@ DefaultBtMessageFactory::createAllowedFastMessage(int32_t index)
|
|||
setCommonProperty(msg);
|
||||
return msg;
|
||||
}
|
||||
|
||||
BtMessageHandle
|
||||
DefaultBtMessageFactory::createBtExtendedMessage(const ExensionMessageHandle& msg)
|
||||
{
|
||||
BtExtendedMessageHandle m = new BtExtendedMessage(msg);
|
||||
setCommonProperty(m);
|
||||
return m;
|
||||
}
|
||||
|
|
|
@ -110,6 +110,8 @@ public:
|
|||
|
||||
virtual BtMessageHandle createAllowedFastMessage(int32_t index);
|
||||
|
||||
virtual BtMessageHandle createBtExtendedMessage(const ExensionMessageHandle& msg);
|
||||
|
||||
void setPeer(const PeerHandle& peer) {
|
||||
this->peer = peer;
|
||||
}
|
||||
|
|
|
@ -53,14 +53,7 @@ BtMessageHandle DefaultBtMessageReceiver::receiveHandshake(bool quickReply) {
|
|||
}
|
||||
BtHandshakeMessageHandle msg = messageFactory->createHandshakeMessage(data, dataLength);
|
||||
Errors errors;
|
||||
if(msg->validate(errors)) {
|
||||
if(msg->isFastExtensionSupported()) {
|
||||
peer->setFastExtensionEnabled(true);
|
||||
logger->info(MSG_FAST_EXTENSION_ENABLED, cuid);
|
||||
}
|
||||
} else {
|
||||
// TODO throw exception here based on errors
|
||||
}
|
||||
msg->validate(errors);
|
||||
return msg;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
/* <!-- copyright */
|
||||
/*
|
||||
* aria2 - The high speed download utility
|
||||
*
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* In addition, as a special exception, the copyright holders give
|
||||
* permission to link the code of portions of this program with the
|
||||
* OpenSSL library under certain conditions as described in each
|
||||
* individual source file, and distribute linked combinations
|
||||
* including the two.
|
||||
* You must obey the GNU General Public License in all respects
|
||||
* for all of the code used other than OpenSSL. If you modify
|
||||
* file(s) with this exception, you may extend this exception to your
|
||||
* version of the file(s), but you are not obligated to do so. If you
|
||||
* do not wish to do so, delete this exception statement from your
|
||||
* version. If you delete this exception statement from all source
|
||||
* files in the program, then also delete it here.
|
||||
*/
|
||||
/* copyright --> */
|
||||
#include "DefaultExtensionMessageFactory.h"
|
||||
#include "BtContext.h"
|
||||
#include "Peer.h"
|
||||
#include "DlAbortEx.h"
|
||||
#include "HandshakeExtensionMessage.h"
|
||||
#include "UTPexExtensionMessage.h"
|
||||
#include "LogFactory.h"
|
||||
#include "BtRegistry.h"
|
||||
|
||||
DefaultExtensionMessageFactory::DefaultExtensionMessageFactory():
|
||||
_btContext(0),
|
||||
_peer(0),
|
||||
_logger(LogFactory::getInstance()) {}
|
||||
|
||||
DefaultExtensionMessageFactory::DefaultExtensionMessageFactory(const BtContextHandle& btContext,
|
||||
const PeerHandle& peer):
|
||||
_btContext(btContext),
|
||||
_peer(peer),
|
||||
_logger(LogFactory::getInstance()) {}
|
||||
|
||||
DefaultExtensionMessageFactory::~DefaultExtensionMessageFactory() {}
|
||||
|
||||
ExtensionMessageHandle
|
||||
DefaultExtensionMessageFactory::createMessage(const char* data, size_t length)
|
||||
{
|
||||
uint8_t extensionMessageID = *data;
|
||||
if(extensionMessageID == 0) {
|
||||
// handshake
|
||||
HandshakeExtensionMessageHandle m = HandshakeExtensionMessage::create(data, length);
|
||||
m->setBtContext(_btContext);
|
||||
m->setPeer(_peer);
|
||||
return m;
|
||||
} else {
|
||||
string extensionName = BT_RUNTIME(_btContext)->getExtensionName(extensionMessageID);
|
||||
if(extensionName.empty()) {
|
||||
throw new DlAbortEx("No extension registered for extended message ID %u",
|
||||
extensionMessageID);
|
||||
}
|
||||
if(extensionName == "ut_pex") {
|
||||
// uTorrent compatible Peer-Exchange
|
||||
UTPexExtensionMessageHandle m =
|
||||
UTPexExtensionMessage::create(_btContext, data, length);
|
||||
m->setBtContext(_btContext);
|
||||
return m;
|
||||
} else {
|
||||
throw new DlAbortEx("Unsupported extension message received. extensionMessageID=%u, extensionName=%s", extensionMessageID, extensionName.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DefaultExtensionMessageFactory::setBtContext(const BtContextHandle& btContext)
|
||||
{
|
||||
_btContext = btContext;
|
||||
}
|
||||
|
||||
void DefaultExtensionMessageFactory::setPeer(const PeerHandle& peer)
|
||||
{
|
||||
_peer = peer;
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
/* <!-- copyright */
|
||||
/*
|
||||
* aria2 - The high speed download utility
|
||||
*
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* In addition, as a special exception, the copyright holders give
|
||||
* permission to link the code of portions of this program with the
|
||||
* OpenSSL library under certain conditions as described in each
|
||||
* individual source file, and distribute linked combinations
|
||||
* including the two.
|
||||
* You must obey the GNU General Public License in all respects
|
||||
* for all of the code used other than OpenSSL. If you modify
|
||||
* file(s) with this exception, you may extend this exception to your
|
||||
* version of the file(s), but you are not obligated to do so. If you
|
||||
* do not wish to do so, delete this exception statement from your
|
||||
* version. If you delete this exception statement from all source
|
||||
* files in the program, then also delete it here.
|
||||
*/
|
||||
/* copyright --> */
|
||||
#ifndef _D_DEFAULT_EXTENSION_MESSAGE_FACTORY_H_
|
||||
#define _D_DEFAULT_EXTENSION_MESSAGE_FACTORY_H_
|
||||
|
||||
#include "ExtensionMessageFactory.h"
|
||||
|
||||
class BtContext;
|
||||
typedef SharedHandle<BtContext> BtContextHandle;
|
||||
class Peer;
|
||||
typedef SharedHandle<Peer> PeerHandle;
|
||||
class Logger;
|
||||
|
||||
class DefaultExtensionMessageFactory:public ExtensionMessageFactory {
|
||||
private:
|
||||
BtContextHandle _btContext;
|
||||
|
||||
PeerHandle _peer;
|
||||
|
||||
const Logger* _logger;
|
||||
|
||||
public:
|
||||
DefaultExtensionMessageFactory();
|
||||
|
||||
DefaultExtensionMessageFactory(const BtContextHandle& btContext,
|
||||
const PeerHandle& peer);
|
||||
|
||||
virtual ~DefaultExtensionMessageFactory();
|
||||
|
||||
virtual ExtensionMessageHandle createMessage(const char* data, size_t length);
|
||||
|
||||
void setBtContext(const BtContextHandle& btContext);
|
||||
|
||||
void setPeer(const PeerHandle& peer);
|
||||
};
|
||||
|
||||
typedef SharedHandle<DefaultExtensionMessageFactory> DefaultExtensionMessageFactoryHandle;
|
||||
#endif // _D_DEFAULT_EXTENSION_MESSAGE_FACTORY_H_
|
|
@ -52,30 +52,35 @@ DefaultPeerStorage::DefaultPeerStorage(BtContextHandle btContext,
|
|||
|
||||
DefaultPeerStorage::~DefaultPeerStorage() {}
|
||||
|
||||
bool DefaultPeerStorage::isPeerAlreadyAdded(const PeerHandle& peer)
|
||||
{
|
||||
return find(peers.begin(), peers.end(), peer) != peers.end() ||
|
||||
find(incomingPeers.begin(), incomingPeers.end(), peer) != incomingPeers.end();
|
||||
}
|
||||
|
||||
bool DefaultPeerStorage::addPeer(const PeerHandle& peer) {
|
||||
Peers::iterator itr = find(peers.begin(), peers.end(), peer);
|
||||
if(itr == peers.end()) {
|
||||
if(isPeerAlreadyAdded(peer)) {
|
||||
logger->debug("Adding %s:%u is rejected because it is already in PeerStorage.", peer->ipaddr.c_str(), peer->port);
|
||||
return false;
|
||||
} else {
|
||||
if(peers.size() >= (size_t)maxPeerListSize) {
|
||||
deleteUnusedPeer(peers.size()-maxPeerListSize+1);
|
||||
}
|
||||
peers.push_front(peer);
|
||||
return true;
|
||||
} else {
|
||||
const PeerHandle& peer = *itr;
|
||||
if(!peer->isGood() || peer->cuid != 0) {
|
||||
return false;
|
||||
} else {
|
||||
*itr = peer;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool DefaultPeerStorage::addIncomingPeer(const PeerHandle& peer)
|
||||
{
|
||||
if(isPeerAlreadyAdded(peer)) {
|
||||
logger->debug("Adding %s:%u is rejected because it is already in PeerStorage.", peer->ipaddr.c_str(), peer->port);
|
||||
return false;
|
||||
} else {
|
||||
incomingPeers.push_back(peer);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void DefaultPeerStorage::addPeer(const Peers& peers) {
|
||||
for(Peers::const_iterator itr = peers.begin();
|
||||
|
|
|
@ -55,6 +55,8 @@ private:
|
|||
BtRuntimeHandle btRuntime;
|
||||
int64_t removedPeerSessionDownloadLength;
|
||||
int64_t removedPeerSessionUploadLength;
|
||||
|
||||
bool isPeerAlreadyAdded(const PeerHandle& peer);
|
||||
public:
|
||||
DefaultPeerStorage(BtContextHandle btContext, const Option* option);
|
||||
virtual ~DefaultPeerStorage();
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
/* <!-- copyright */
|
||||
/*
|
||||
* aria2 - The high speed download utility
|
||||
*
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* In addition, as a special exception, the copyright holders give
|
||||
* permission to link the code of portions of this program with the
|
||||
* OpenSSL library under certain conditions as described in each
|
||||
* individual source file, and distribute linked combinations
|
||||
* including the two.
|
||||
* You must obey the GNU General Public License in all respects
|
||||
* for all of the code used other than OpenSSL. If you modify
|
||||
* file(s) with this exception, you may extend this exception to your
|
||||
* version of the file(s), but you are not obligated to do so. If you
|
||||
* do not wish to do so, delete this exception statement from your
|
||||
* version. If you delete this exception statement from all source
|
||||
* files in the program, then also delete it here.
|
||||
*/
|
||||
/* copyright --> */
|
||||
#ifndef _D_EXTENSION_MESSAGE_H_
|
||||
#define _D_EXTENSION_MESSAGE_H_
|
||||
|
||||
#include "common.h"
|
||||
|
||||
class ExtensionMessage {
|
||||
public:
|
||||
virtual ~ExtensionMessage() {}
|
||||
|
||||
virtual string getBencodedData() = 0;
|
||||
|
||||
virtual uint8_t getExtensionMessageID() = 0;
|
||||
|
||||
virtual const string& getExtensionName() const = 0;
|
||||
|
||||
virtual string toString() const = 0;
|
||||
|
||||
virtual void doReceivedAction() = 0;
|
||||
};
|
||||
|
||||
typedef SharedHandle<ExtensionMessage> ExtensionMessageHandle;
|
||||
|
||||
#endif // _D_EXTENSION_MESSAGE_H_
|
|
@ -0,0 +1,51 @@
|
|||
/* <!-- copyright */
|
||||
/*
|
||||
* aria2 - The high speed download utility
|
||||
*
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* In addition, as a special exception, the copyright holders give
|
||||
* permission to link the code of portions of this program with the
|
||||
* OpenSSL library under certain conditions as described in each
|
||||
* individual source file, and distribute linked combinations
|
||||
* including the two.
|
||||
* You must obey the GNU General Public License in all respects
|
||||
* for all of the code used other than OpenSSL. If you modify
|
||||
* file(s) with this exception, you may extend this exception to your
|
||||
* version of the file(s), but you are not obligated to do so. If you
|
||||
* do not wish to do so, delete this exception statement from your
|
||||
* version. If you delete this exception statement from all source
|
||||
* files in the program, then also delete it here.
|
||||
*/
|
||||
/* copyright --> */
|
||||
#ifndef _D_EXTENSION_MESSAGE_FACTORY_H_
|
||||
#define _D_EXTENSION_MESSAGE_FACTORY_H_
|
||||
|
||||
#include "common.h"
|
||||
|
||||
class ExtensionMessage;
|
||||
typedef SharedHandle<ExtensionMessage> ExtensionMessageHandle;
|
||||
|
||||
class ExtensionMessageFactory {
|
||||
public:
|
||||
virtual ~ExtensionMessageFactory() {}
|
||||
|
||||
virtual ExtensionMessageHandle createMessage(const char* data, size_t length) = 0;
|
||||
};
|
||||
|
||||
typedef SharedHandle<ExtensionMessageFactory> ExtensionMessageFactoryHandle;
|
||||
#endif // _D_EXTENSION_MESSAGE_FACTORY_H_
|
|
@ -0,0 +1,174 @@
|
|||
/* <!-- copyright */
|
||||
/*
|
||||
* aria2 - The high speed download utility
|
||||
*
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* In addition, as a special exception, the copyright holders give
|
||||
* permission to link the code of portions of this program with the
|
||||
* OpenSSL library under certain conditions as described in each
|
||||
* individual source file, and distribute linked combinations
|
||||
* including the two.
|
||||
* You must obey the GNU General Public License in all respects
|
||||
* for all of the code used other than OpenSSL. If you modify
|
||||
* file(s) with this exception, you may extend this exception to your
|
||||
* version of the file(s), but you are not obligated to do so. If you
|
||||
* do not wish to do so, delete this exception statement from your
|
||||
* version. If you delete this exception statement from all source
|
||||
* files in the program, then also delete it here.
|
||||
*/
|
||||
/* copyright --> */
|
||||
#include "HandshakeExtensionMessage.h"
|
||||
#include "Peer.h"
|
||||
#include "BtContext.h"
|
||||
#include "Dictionary.h"
|
||||
#include "Data.h"
|
||||
#include "Util.h"
|
||||
#include "BencodeVisitor.h"
|
||||
#include "BtRegistry.h"
|
||||
#include "MetaFileUtil.h"
|
||||
#include "DlAbortEx.h"
|
||||
#include "LogFactory.h"
|
||||
#include "message.h"
|
||||
|
||||
const string HandshakeExtensionMessage::EXTENSION_NAME = "handshake";
|
||||
|
||||
HandshakeExtensionMessage::HandshakeExtensionMessage():_tcpPort(0),
|
||||
_btContext(0),
|
||||
_peer(0),
|
||||
_logger(LogFactory::getInstance())
|
||||
{}
|
||||
|
||||
HandshakeExtensionMessage::~HandshakeExtensionMessage() {}
|
||||
|
||||
string HandshakeExtensionMessage::getBencodedData()
|
||||
{
|
||||
SharedHandle<Dictionary> dic = new Dictionary();
|
||||
if(!_clientVersion.empty()) {
|
||||
Data* v = new Data(_clientVersion);
|
||||
dic->put("v", v);
|
||||
}
|
||||
if(_tcpPort > 0) {
|
||||
string portStr = Util::itos(_tcpPort);
|
||||
Data* p = new Data(portStr, true);
|
||||
dic->put("p", p);
|
||||
}
|
||||
Dictionary* exts = new Dictionary();
|
||||
dic->put("m", exts);
|
||||
for(map<string, uint8_t>::const_iterator itr = _extensions.begin();
|
||||
itr != _extensions.end(); ++itr) {
|
||||
const map<string, uint8_t>::value_type& vt = *itr;
|
||||
string idStr = Util::uitos((uint32_t)vt.second);
|
||||
exts->put(vt.first, new Data(idStr, true));
|
||||
}
|
||||
BencodeVisitor v;
|
||||
dic->accept(&v);
|
||||
return v.getBencodedData();
|
||||
}
|
||||
|
||||
string HandshakeExtensionMessage::toString() const
|
||||
{
|
||||
string s = getExtensionName();
|
||||
if(!_clientVersion.empty()) {
|
||||
s += " client="+Util::urlencode(_clientVersion);
|
||||
}
|
||||
if(_tcpPort > 0) {
|
||||
s += ", tcpPort="+Util::itos(_tcpPort);
|
||||
}
|
||||
for(map<string, uint8_t>::const_iterator itr = _extensions.begin();
|
||||
itr != _extensions.end(); ++itr) {
|
||||
const map<string, uint8_t>::value_type& vt = *itr;
|
||||
s += ", "+vt.first+"="+Util::uitos((uint32_t)vt.second);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
void HandshakeExtensionMessage::doReceivedAction()
|
||||
{
|
||||
if(_tcpPort > 0) {
|
||||
_peer->port = _tcpPort;
|
||||
}
|
||||
for(map<string, uint8_t>::const_iterator itr = _extensions.begin();
|
||||
itr != _extensions.end(); ++itr) {
|
||||
const map<string, uint8_t>::value_type& vt = *itr;
|
||||
_peer->setExtension(vt.first, vt.second);
|
||||
}
|
||||
if(_peer->port > 0) {
|
||||
// This is needed when _peer is a connection initiator, listen port of
|
||||
// _peer is now available, which is initially unknown.
|
||||
// If _peer is a receiver or already its port is known, _peer has to be
|
||||
// already added to PeerStorage using addPeer() and call
|
||||
// PeerStorage::addPeer() here does nothing and just returns false.
|
||||
PEER_STORAGE(_btContext)->addPeer(_peer);
|
||||
}
|
||||
}
|
||||
|
||||
void HandshakeExtensionMessage::setPeer(const PeerHandle& peer)
|
||||
{
|
||||
_peer = peer;
|
||||
}
|
||||
|
||||
void HandshakeExtensionMessage::setBtContext(const BtContextHandle& btContext)
|
||||
{
|
||||
_btContext = btContext;
|
||||
}
|
||||
|
||||
uint8_t HandshakeExtensionMessage::getExtensionMessageID(const string& name) const
|
||||
{
|
||||
map<string, uint8_t>::const_iterator i = _extensions.find(name);
|
||||
if(i == _extensions.end()) {
|
||||
return 0;
|
||||
} else {
|
||||
return (*i).second;
|
||||
}
|
||||
}
|
||||
|
||||
HandshakeExtensionMessageHandle
|
||||
HandshakeExtensionMessage::create(const char* data, size_t length)
|
||||
{
|
||||
if(length < 1) {
|
||||
throw new DlAbortEx(MSG_TOO_SMALL_PAYLOAD_SIZE,
|
||||
EXTENSION_NAME.c_str(), length);
|
||||
}
|
||||
HandshakeExtensionMessageHandle msg = new HandshakeExtensionMessage();
|
||||
msg->_logger->debug("Creating HandshakeExtensionMessage from %s",
|
||||
Util::urlencode((const unsigned char*)data, length).c_str());
|
||||
SharedHandle<MetaEntry> root = MetaFileUtil::bdecoding(data+1, length-1);
|
||||
Dictionary* d = dynamic_cast<Dictionary*>(root.get());
|
||||
if(d == 0) {
|
||||
throw new DlAbortEx("Unexpected payload format for extended message handshake");
|
||||
}
|
||||
const Data* p = dynamic_cast<const Data*>(d->get("p"));
|
||||
if(p) {
|
||||
msg->_tcpPort = p->toInt();
|
||||
}
|
||||
const Data* v = dynamic_cast<const Data*>(d->get("v"));
|
||||
if(v) {
|
||||
msg->_clientVersion = v->toString();
|
||||
}
|
||||
const Dictionary* m = dynamic_cast<const Dictionary*>(d->get("m"));
|
||||
if(m) {
|
||||
const Order& order = m->getOrder();
|
||||
for(Order::const_iterator i = order.begin(); i != order.end(); ++i) {
|
||||
const Data* e = dynamic_cast<const Data*>(m->get(*i));
|
||||
if(e) {
|
||||
msg->_extensions[*i] = e->toInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
return msg;
|
||||
}
|
|
@ -0,0 +1,128 @@
|
|||
/* <!-- copyright */
|
||||
/*
|
||||
* aria2 - The high speed download utility
|
||||
*
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* In addition, as a special exception, the copyright holders give
|
||||
* permission to link the code of portions of this program with the
|
||||
* OpenSSL library under certain conditions as described in each
|
||||
* individual source file, and distribute linked combinations
|
||||
* including the two.
|
||||
* You must obey the GNU General Public License in all respects
|
||||
* for all of the code used other than OpenSSL. If you modify
|
||||
* file(s) with this exception, you may extend this exception to your
|
||||
* version of the file(s), but you are not obligated to do so. If you
|
||||
* do not wish to do so, delete this exception statement from your
|
||||
* version. If you delete this exception statement from all source
|
||||
* files in the program, then also delete it here.
|
||||
*/
|
||||
/* copyright --> */
|
||||
#ifndef _D_HANDSHAKE_EXTENSION_MESSAGE_H_
|
||||
#define _D_HANDSHAKE_EXTENSION_MESSAGE_H_
|
||||
|
||||
#include "ExtensionMessage.h"
|
||||
#include "BtConstants.h"
|
||||
|
||||
class BtContext;
|
||||
typedef SharedHandle<BtContext> BtContextHandle;
|
||||
class Peer;
|
||||
typedef SharedHandle<Peer> PeerHandle;
|
||||
class HandshakeExtensionMessage;
|
||||
typedef SharedHandle<HandshakeExtensionMessage> HandshakeExtensionMessageHandle;
|
||||
class Logger;
|
||||
|
||||
class HandshakeExtensionMessage:public ExtensionMessage {
|
||||
private:
|
||||
string _clientVersion;
|
||||
|
||||
uint16_t _tcpPort;
|
||||
|
||||
map<string, uint8_t> _extensions;
|
||||
|
||||
BtContextHandle _btContext;
|
||||
|
||||
PeerHandle _peer;
|
||||
|
||||
const Logger* _logger;
|
||||
|
||||
public:
|
||||
HandshakeExtensionMessage();
|
||||
|
||||
virtual ~HandshakeExtensionMessage();
|
||||
|
||||
virtual string getBencodedData();
|
||||
|
||||
virtual uint8_t getExtensionMessageID()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual const string& getExtensionName() const
|
||||
{
|
||||
return EXTENSION_NAME;
|
||||
}
|
||||
|
||||
static const string EXTENSION_NAME;
|
||||
|
||||
virtual string toString() const;
|
||||
|
||||
virtual void doReceivedAction();
|
||||
|
||||
void setClientVersion(const string& version)
|
||||
{
|
||||
_clientVersion = version;
|
||||
}
|
||||
|
||||
const string& getClientVersion() const
|
||||
{
|
||||
return _clientVersion;
|
||||
}
|
||||
|
||||
void setTCPPort(uint16_t port)
|
||||
{
|
||||
_tcpPort = port;
|
||||
}
|
||||
|
||||
uint16_t getTCPPort() const
|
||||
{
|
||||
return _tcpPort;
|
||||
}
|
||||
|
||||
void setExtension(const string& name, uint8_t id)
|
||||
{
|
||||
_extensions[name] = id;
|
||||
}
|
||||
|
||||
void setExtensions(const Extensions& extensions)
|
||||
{
|
||||
_extensions = extensions;
|
||||
}
|
||||
|
||||
uint8_t getExtensionMessageID(const string& name) const;
|
||||
|
||||
void setPeer(const PeerHandle& peer);
|
||||
|
||||
void setBtContext(const BtContextHandle& btContext);
|
||||
|
||||
static HandshakeExtensionMessageHandle create(const char* data,
|
||||
size_t dataLength);
|
||||
|
||||
};
|
||||
|
||||
typedef SharedHandle<HandshakeExtensionMessage> HandshakeExtensionMessageHandle;
|
||||
#endif // _D_HANDSHAKE_EXTENSION_MESSAGE_H_
|
|
@ -167,6 +167,7 @@ SRCS += MetaEntry.h\
|
|||
MetaFileUtil.cc MetaFileUtil.h\
|
||||
MetaEntryVisitor.h\
|
||||
ShaVisitor.cc ShaVisitor.h\
|
||||
BencodeVisitor.cc\
|
||||
PeerMessageUtil.cc PeerMessageUtil.h\
|
||||
PeerAbstractCommand.cc PeerAbstractCommand.h\
|
||||
PeerInitiateConnectionCommand.cc PeerInitiateConnectionCommand.h\
|
||||
|
@ -248,7 +249,11 @@ SRCS += MetaEntry.h\
|
|||
BtSetup.cc BtSetup.h\
|
||||
BtFileAllocationEntry.cc BtFileAllocationEntry.h\
|
||||
BtPostDownloadHandler.cc BtPostDownloadHandler.h\
|
||||
BtCheckIntegrityEntry.cc BtCheckIntegrityEntry.h
|
||||
BtCheckIntegrityEntry.cc BtCheckIntegrityEntry.h\
|
||||
BtExtendedMessage.cc\
|
||||
DefaultExtensionMessageFactory.cc\
|
||||
HandshakeExtensionMessage.cc\
|
||||
UTPexExtensionMessage.cc
|
||||
endif # ENABLE_BITTORRENT
|
||||
|
||||
if ENABLE_METALINK
|
||||
|
|
|
@ -54,6 +54,7 @@ bin_PROGRAMS = aria2c$(EXEEXT)
|
|||
@ENABLE_BITTORRENT_TRUE@ MetaFileUtil.cc MetaFileUtil.h\
|
||||
@ENABLE_BITTORRENT_TRUE@ MetaEntryVisitor.h\
|
||||
@ENABLE_BITTORRENT_TRUE@ ShaVisitor.cc ShaVisitor.h\
|
||||
@ENABLE_BITTORRENT_TRUE@ BencodeVisitor.cc\
|
||||
@ENABLE_BITTORRENT_TRUE@ PeerMessageUtil.cc PeerMessageUtil.h\
|
||||
@ENABLE_BITTORRENT_TRUE@ PeerAbstractCommand.cc PeerAbstractCommand.h\
|
||||
@ENABLE_BITTORRENT_TRUE@ PeerInitiateConnectionCommand.cc PeerInitiateConnectionCommand.h\
|
||||
|
@ -135,7 +136,11 @@ bin_PROGRAMS = aria2c$(EXEEXT)
|
|||
@ENABLE_BITTORRENT_TRUE@ BtSetup.cc BtSetup.h\
|
||||
@ENABLE_BITTORRENT_TRUE@ BtFileAllocationEntry.cc BtFileAllocationEntry.h\
|
||||
@ENABLE_BITTORRENT_TRUE@ BtPostDownloadHandler.cc BtPostDownloadHandler.h\
|
||||
@ENABLE_BITTORRENT_TRUE@ BtCheckIntegrityEntry.cc BtCheckIntegrityEntry.h
|
||||
@ENABLE_BITTORRENT_TRUE@ BtCheckIntegrityEntry.cc BtCheckIntegrityEntry.h\
|
||||
@ENABLE_BITTORRENT_TRUE@ BtExtendedMessage.cc\
|
||||
@ENABLE_BITTORRENT_TRUE@ DefaultExtensionMessageFactory.cc\
|
||||
@ENABLE_BITTORRENT_TRUE@ HandshakeExtensionMessage.cc\
|
||||
@ENABLE_BITTORRENT_TRUE@ UTPexExtensionMessage.cc
|
||||
|
||||
@ENABLE_METALINK_TRUE@am__append_3 = Metalinker.cc Metalinker.h\
|
||||
@ENABLE_METALINK_TRUE@ MetalinkEntry.cc MetalinkEntry.h\
|
||||
|
@ -303,8 +308,9 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
|
|||
MessageDigestHelper.h MetaEntry.h Data.cc Data.h Dictionary.cc \
|
||||
Dictionary.h List.cc List.h MetaFileUtil.cc MetaFileUtil.h \
|
||||
MetaEntryVisitor.h ShaVisitor.cc ShaVisitor.h \
|
||||
PeerMessageUtil.cc PeerMessageUtil.h PeerAbstractCommand.cc \
|
||||
PeerAbstractCommand.h PeerInitiateConnectionCommand.cc \
|
||||
BencodeVisitor.cc PeerMessageUtil.cc PeerMessageUtil.h \
|
||||
PeerAbstractCommand.cc PeerAbstractCommand.h \
|
||||
PeerInitiateConnectionCommand.cc \
|
||||
PeerInitiateConnectionCommand.h PeerInteractionCommand.cc \
|
||||
PeerInteractionCommand.h PeerListenCommand.cc \
|
||||
PeerListenCommand.h RequestSlot.cc RequestSlot.h Directory.cc \
|
||||
|
@ -355,8 +361,10 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
|
|||
PeerReceiveHandshakeCommand.h BtSetup.cc BtSetup.h \
|
||||
BtFileAllocationEntry.cc BtFileAllocationEntry.h \
|
||||
BtPostDownloadHandler.cc BtPostDownloadHandler.h \
|
||||
BtCheckIntegrityEntry.cc BtCheckIntegrityEntry.h Metalinker.cc \
|
||||
Metalinker.h MetalinkEntry.cc MetalinkEntry.h \
|
||||
BtCheckIntegrityEntry.cc BtCheckIntegrityEntry.h \
|
||||
BtExtendedMessage.cc DefaultExtensionMessageFactory.cc \
|
||||
HandshakeExtensionMessage.cc UTPexExtensionMessage.cc \
|
||||
Metalinker.cc Metalinker.h MetalinkEntry.cc MetalinkEntry.h \
|
||||
MetalinkResource.cc MetalinkResource.h MetalinkProcessor.h \
|
||||
MetalinkProcessorFactory.cc MetalinkParserController.cc \
|
||||
MetalinkParserStateMachine.cc InitialMetalinkParserState.cc \
|
||||
|
@ -385,6 +393,7 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
|
|||
@ENABLE_BITTORRENT_TRUE@ Dictionary.$(OBJEXT) List.$(OBJEXT) \
|
||||
@ENABLE_BITTORRENT_TRUE@ MetaFileUtil.$(OBJEXT) \
|
||||
@ENABLE_BITTORRENT_TRUE@ ShaVisitor.$(OBJEXT) \
|
||||
@ENABLE_BITTORRENT_TRUE@ BencodeVisitor.$(OBJEXT) \
|
||||
@ENABLE_BITTORRENT_TRUE@ PeerMessageUtil.$(OBJEXT) \
|
||||
@ENABLE_BITTORRENT_TRUE@ PeerAbstractCommand.$(OBJEXT) \
|
||||
@ENABLE_BITTORRENT_TRUE@ PeerInitiateConnectionCommand.$(OBJEXT) \
|
||||
|
@ -433,7 +442,11 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
|
|||
@ENABLE_BITTORRENT_TRUE@ BtSetup.$(OBJEXT) \
|
||||
@ENABLE_BITTORRENT_TRUE@ BtFileAllocationEntry.$(OBJEXT) \
|
||||
@ENABLE_BITTORRENT_TRUE@ BtPostDownloadHandler.$(OBJEXT) \
|
||||
@ENABLE_BITTORRENT_TRUE@ BtCheckIntegrityEntry.$(OBJEXT)
|
||||
@ENABLE_BITTORRENT_TRUE@ BtCheckIntegrityEntry.$(OBJEXT) \
|
||||
@ENABLE_BITTORRENT_TRUE@ BtExtendedMessage.$(OBJEXT) \
|
||||
@ENABLE_BITTORRENT_TRUE@ DefaultExtensionMessageFactory.$(OBJEXT) \
|
||||
@ENABLE_BITTORRENT_TRUE@ HandshakeExtensionMessage.$(OBJEXT) \
|
||||
@ENABLE_BITTORRENT_TRUE@ UTPexExtensionMessage.$(OBJEXT)
|
||||
@ENABLE_METALINK_TRUE@am__objects_3 = Metalinker.$(OBJEXT) \
|
||||
@ENABLE_METALINK_TRUE@ MetalinkEntry.$(OBJEXT) \
|
||||
@ENABLE_METALINK_TRUE@ MetalinkResource.$(OBJEXT) \
|
||||
|
@ -935,6 +948,7 @@ distclean-compile:
|
|||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AuthConfigFactory.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AutoSaveCommand.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Base64.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BencodeVisitor.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BitfieldMan.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BitfieldManFactory.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BtAllowedFastMessage.Po@am__quote@
|
||||
|
@ -944,6 +958,7 @@ distclean-compile:
|
|||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BtChokeMessage.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BtContextAwareCommand.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BtDependency.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BtExtendedMessage.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BtFileAllocationEntry.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BtHandshakeMessage.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BtHaveAllMessage.Po@am__quote@
|
||||
|
@ -987,6 +1002,7 @@ distclean-compile:
|
|||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultBtProgressInfoFile.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultBtRequestFactory.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultDiskWriter.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultExtensionMessageFactory.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultPeerListProcessor.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultPeerStorage.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultPieceStorage.Po@am__quote@
|
||||
|
@ -1022,6 +1038,7 @@ 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)/GrowSegment.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HandshakeExtensionMessage.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HashMetalinkParserState.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HaveEraseCommand.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HttpConnection.Po@am__quote@
|
||||
|
@ -1111,6 +1128,7 @@ distclean-compile:
|
|||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TrackerWatcherCommand.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TransferStat.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/URLMetalinkParserState.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UTPexExtensionMessage.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UnknownLengthPieceStorage.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UriListParser.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Util.Po@am__quote@
|
||||
|
|
|
@ -49,4 +49,5 @@ public:
|
|||
|
||||
};
|
||||
|
||||
typedef SharedHandle<MetaEntry> MetaEntryHandle;
|
||||
#endif // _D_META_ENTRY_H_
|
||||
|
|
|
@ -83,7 +83,7 @@ MetaEntry* MetaFileUtil::bdecoding(const char* buf, int32_t len) {
|
|||
|
||||
MetaEntry* MetaFileUtil::bdecodingR(const char** pp, const char* end) {
|
||||
if(*pp >= end) {
|
||||
throw new DlAbortEx("mulformed metainfo");
|
||||
throw new DlAbortEx("Malformed metainfo");
|
||||
}
|
||||
MetaEntry* e;
|
||||
switch(**pp) {
|
||||
|
@ -107,7 +107,7 @@ MetaEntry* MetaFileUtil::bdecodingR(const char** pp, const char* end) {
|
|||
|
||||
Dictionary* MetaFileUtil::parseDictionaryTree(const char** pp, const char* end) {
|
||||
if(*pp >= end) {
|
||||
throw new DlAbortEx("mulformed metainfo");
|
||||
throw new DlAbortEx("Malformed metainfo");
|
||||
}
|
||||
Dictionary* dic = new Dictionary();
|
||||
try {
|
||||
|
@ -129,7 +129,7 @@ Dictionary* MetaFileUtil::parseDictionaryTree(const char** pp, const char* end)
|
|||
|
||||
List* MetaFileUtil::parseListTree(const char** pp, const char* end) {
|
||||
if(*pp >= end) {
|
||||
throw new DlAbortEx("mulformed metainfo");
|
||||
throw new DlAbortEx("Malformed metainfo");
|
||||
}
|
||||
List* lis = new List();
|
||||
try {
|
||||
|
@ -150,12 +150,12 @@ List* MetaFileUtil::parseListTree(const char** pp, const char* end) {
|
|||
|
||||
Data* MetaFileUtil::decodeInt(const char** pp, const char* end) {
|
||||
if(*pp >= end) {
|
||||
throw new DlAbortEx(EX_MULFORMED_META_INFO);
|
||||
throw new DlAbortEx(EX_MALFORMED_META_INFO);
|
||||
}
|
||||
char* endTerm = (char*)memchr(*pp, 'e', end-*pp);
|
||||
// TODO if endTerm is null
|
||||
if(endTerm == NULL) {
|
||||
throw new DlAbortEx(EX_MULFORMED_META_INFO);
|
||||
throw new DlAbortEx(EX_MALFORMED_META_INFO);
|
||||
}
|
||||
int32_t numSize = endTerm-*pp;
|
||||
|
||||
|
@ -166,12 +166,12 @@ Data* MetaFileUtil::decodeInt(const char** pp, const char* end) {
|
|||
|
||||
Data* MetaFileUtil::decodeWord(const char** pp, const char* end) {
|
||||
if(*pp >= end) {
|
||||
throw new DlAbortEx("mulformed metainfo");
|
||||
throw new DlAbortEx("Malformed metainfo");
|
||||
}
|
||||
char* delim = (char*)memchr(*pp, ':', end-*pp);
|
||||
// TODO if delim is null
|
||||
if(delim == *pp || delim == NULL) {
|
||||
throw new DlAbortEx(EX_MULFORMED_META_INFO);
|
||||
throw new DlAbortEx(EX_MALFORMED_META_INFO);
|
||||
}
|
||||
int32_t numSize = delim-*pp;
|
||||
char* temp = new char[numSize+1];
|
||||
|
@ -181,12 +181,12 @@ Data* MetaFileUtil::decodeWord(const char** pp, const char* end) {
|
|||
int32_t size = strtol(temp, &endptr, 10);
|
||||
if(*endptr != '\0') {
|
||||
delete [] temp;
|
||||
throw new DlAbortEx(EX_MULFORMED_META_INFO);
|
||||
throw new DlAbortEx(EX_MALFORMED_META_INFO);
|
||||
}
|
||||
delete [] temp;
|
||||
|
||||
if(delim+1+size > end) {
|
||||
throw new DlAbortEx(EX_MULFORMED_META_INFO);
|
||||
throw new DlAbortEx(EX_MALFORMED_META_INFO);
|
||||
}
|
||||
|
||||
Data* data = new Data(delim+1, size);
|
||||
|
|
31
src/Peer.cc
31
src/Peer.cc
|
@ -39,7 +39,7 @@
|
|||
# include "MessageDigestHelper.h"
|
||||
#endif // ENABLE_MESSAGE_DIGEST
|
||||
|
||||
Peer::Peer(string ipaddr, int32_t port, int32_t pieceLength, int64_t totalLength):
|
||||
Peer::Peer(string ipaddr, uint16_t port, int32_t pieceLength, int64_t totalLength):
|
||||
ipaddr(ipaddr),
|
||||
port(port),
|
||||
sessionUploadLength(0),
|
||||
|
@ -113,6 +113,8 @@ void Peer::resetStatus() {
|
|||
optUnchoking = false;
|
||||
snubbing = false;
|
||||
fastExtensionEnabled = false;
|
||||
_extendedMessagingEnabled = false;
|
||||
_extensions.clear();
|
||||
latency = DEFAULT_LATENCY;
|
||||
peerAllowedIndexSet.clear();
|
||||
amAllowedIndexSet.clear();
|
||||
|
@ -158,3 +160,30 @@ bool Peer::isGood() const
|
|||
{
|
||||
return _badConditionStartTime.elapsed(_badConditionInterval);
|
||||
}
|
||||
|
||||
uint8_t Peer::getExtensionMessageID(const string& name)
|
||||
{
|
||||
Extensions::const_iterator itr = _extensions.find(name);
|
||||
if(itr == _extensions.end()) {
|
||||
return 0;
|
||||
} else {
|
||||
return (*itr).second;
|
||||
}
|
||||
}
|
||||
|
||||
string Peer::getExtensionName(uint8_t id)
|
||||
{
|
||||
for(Extensions::const_iterator itr = _extensions.begin();
|
||||
itr != _extensions.end(); ++itr) {
|
||||
const Extensions::value_type& p = *itr;
|
||||
if(p.second == id) {
|
||||
return p.first;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
void Peer::setExtension(const string& name, uint8_t id)
|
||||
{
|
||||
_extensions[name] = id;
|
||||
}
|
||||
|
|
34
src/Peer.h
34
src/Peer.h
|
@ -39,6 +39,7 @@
|
|||
#include "BitfieldMan.h"
|
||||
#include "PeerStat.h"
|
||||
#include "TimeA2.h"
|
||||
#include "BtConstants.h"
|
||||
#include <string.h>
|
||||
|
||||
#define PEER_ID_LENGTH 20
|
||||
|
@ -49,7 +50,7 @@ class Peer {
|
|||
friend bool operator!=(const Peer& p1, const Peer& p2);
|
||||
public:
|
||||
string ipaddr;
|
||||
int32_t port;
|
||||
uint16_t port;
|
||||
bool amChoking;
|
||||
bool amInterested;
|
||||
bool peerChoking;
|
||||
|
@ -67,6 +68,8 @@ private:
|
|||
Integers peerAllowedIndexSet;
|
||||
// fast index set which localhost has sent to a peer.
|
||||
Integers amAllowedIndexSet;
|
||||
bool _extendedMessagingEnabled;
|
||||
Extensions _extensions;
|
||||
PeerStat peerStat;
|
||||
int64_t sessionUploadLength;
|
||||
int64_t sessionDownloadLength;
|
||||
|
@ -74,10 +77,11 @@ private:
|
|||
int32_t latency;
|
||||
bool active;
|
||||
string id;
|
||||
Time _firstContactTime;
|
||||
Time _badConditionStartTime;
|
||||
int32_t _badConditionInterval;
|
||||
public:
|
||||
Peer(string ipaddr, int32_t port, int32_t pieceLength, int64_t totalLength);
|
||||
Peer(string ipaddr, uint16_t port, int32_t pieceLength, int64_t totalLength);
|
||||
|
||||
~Peer() {
|
||||
delete bitfield;
|
||||
|
@ -193,6 +197,16 @@ public:
|
|||
void addAmAllowedIndex(int32_t index);
|
||||
bool isInAmAllowedIndexSet(int32_t index) const;
|
||||
|
||||
void setExtendedMessagingEnabled(bool enabled)
|
||||
{
|
||||
_extendedMessagingEnabled = enabled;
|
||||
}
|
||||
|
||||
bool isExtendedMessagingEnabled() const
|
||||
{
|
||||
return _extendedMessagingEnabled;
|
||||
}
|
||||
|
||||
bool shouldBeChoking() const;
|
||||
|
||||
bool hasPiece(int32_t index) const;
|
||||
|
@ -211,6 +225,22 @@ public:
|
|||
bool isGood() const;
|
||||
|
||||
void reconfigure(int32_t pieceLength, int64_t totalLength);
|
||||
|
||||
Time getFirstContactTime() const
|
||||
{
|
||||
return _firstContactTime;
|
||||
}
|
||||
|
||||
Time getBadConditionStartTime() const
|
||||
{
|
||||
return _badConditionStartTime;
|
||||
}
|
||||
|
||||
uint8_t getExtensionMessageID(const string& name);
|
||||
|
||||
string getExtensionName(uint8_t id);
|
||||
|
||||
void setExtension(const string& name, uint8_t id);
|
||||
};
|
||||
|
||||
typedef SharedHandle<Peer> PeerHandle;
|
||||
|
|
|
@ -112,6 +112,9 @@ PeerInteractionCommand::PeerInteractionCommand(int32_t cuid,
|
|||
btInteractive->setKeepAliveInterval(e->option->getAsInt(PREF_BT_KEEP_ALIVE_INTERVAL));
|
||||
btInteractive->setMaxDownloadSpeedLimit(e->option->getAsInt(PREF_MAX_DOWNLOAD_LIMIT));
|
||||
btInteractive->setBtMessageFactory(factory);
|
||||
if(!btContext->isPrivate() && e->option->getAsBool(PREF_ENABLE_PEER_EXCHANGE)) {
|
||||
btInteractive->setUTPexEnabled(true);
|
||||
}
|
||||
this->btInteractive = btInteractive;
|
||||
|
||||
// reverse depends
|
||||
|
|
|
@ -125,3 +125,17 @@ void PeerMessageUtil::createPeerMessageString(unsigned char* msg,
|
|||
setIntParam(msg, payloadLength);
|
||||
msg[4] = messageId;
|
||||
}
|
||||
|
||||
bool PeerMessageUtil::createcompact(char* compact, const string& addr, uint16_t port)
|
||||
{
|
||||
struct in_addr in;
|
||||
if(inet_aton(addr.c_str(), &in) == 0) {
|
||||
return false;
|
||||
}
|
||||
uint32_t* addrp = (uint32_t*)compact;
|
||||
*addrp = in.s_addr;
|
||||
uint16_t* portp = (uint16_t*)(compact+4);
|
||||
*portp = htons(port);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -65,6 +65,16 @@ public:
|
|||
int32_t msgLength,
|
||||
int32_t payloadLength,
|
||||
int8_t messageId);
|
||||
|
||||
/**
|
||||
* Creates compact tracker format(6bytes for ipv4 address and port)
|
||||
* and stores the results in compact.
|
||||
* compact must be at least 6 bytes and pre-allocated.
|
||||
* Returns true if creation is successful, otherwise returns false.
|
||||
* The example of failure reason is that addr is not numbers-and-dots
|
||||
* notation.
|
||||
*/
|
||||
static bool createcompact(char* compact, const string& addr, uint16_t port);
|
||||
};
|
||||
|
||||
#endif // _D_PEER_MESSAGE_UTIL_H_
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include "BtMessageDispatcher.h"
|
||||
#include "PeerConnection.h"
|
||||
#include "BtMessageReceiver.h"
|
||||
#include "ExtensionMessageFactory.h"
|
||||
|
||||
class PeerObject {
|
||||
public:
|
||||
|
@ -48,13 +49,15 @@ public:
|
|||
btRequestFactory(0),
|
||||
btMessageDispatcher(0),
|
||||
btMessageReceiver(0),
|
||||
peerConnection(0) {}
|
||||
peerConnection(0),
|
||||
extensionMessageFactory(0) {}
|
||||
|
||||
BtMessageFactoryHandle btMessageFactory;
|
||||
BtRequestFactoryHandle btRequestFactory;
|
||||
BtMessageDispatcherHandle btMessageDispatcher;
|
||||
BtMessageReceiverHandle btMessageReceiver;
|
||||
PeerConnectionHandle peerConnection;
|
||||
ExtensionMessageFactoryHandle extensionMessageFactory;
|
||||
};
|
||||
|
||||
typedef SharedHandle<PeerObject> PeerObjectHandle;
|
||||
|
|
|
@ -77,7 +77,7 @@ bool PeerReceiveHandshakeCommand::executeInternal()
|
|||
if(!PIECE_STORAGE(btContext)->downloadFinished() && tstat.getDownloadSpeed() < _lowestSpeedLimit ||
|
||||
BT_RUNTIME(btContext)->getConnections() < MAX_PEERS) {
|
||||
peer->reconfigure(btContext->getPieceLength(), btContext->getTotalLength());
|
||||
PEER_STORAGE(btContext)->addIncomingPeer(peer);
|
||||
if(PEER_STORAGE(btContext)->addIncomingPeer(peer)) {
|
||||
|
||||
peer->cuid = cuid;
|
||||
|
||||
|
@ -93,6 +93,7 @@ bool PeerReceiveHandshakeCommand::executeInternal()
|
|||
e->commands.push_back(command);
|
||||
logger->debug(MSG_INCOMING_PEER_CONNECTION, cuid, peer->cuid);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
e->commands.push_back(this);
|
||||
|
|
|
@ -0,0 +1,149 @@
|
|||
/* <!-- copyright */
|
||||
/*
|
||||
* aria2 - The high speed download utility
|
||||
*
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* In addition, as a special exception, the copyright holders give
|
||||
* permission to link the code of portions of this program with the
|
||||
* OpenSSL library under certain conditions as described in each
|
||||
* individual source file, and distribute linked combinations
|
||||
* including the two.
|
||||
* You must obey the GNU General Public License in all respects
|
||||
* for all of the code used other than OpenSSL. If you modify
|
||||
* file(s) with this exception, you may extend this exception to your
|
||||
* version of the file(s), but you are not obligated to do so. If you
|
||||
* do not wish to do so, delete this exception statement from your
|
||||
* version. If you delete this exception statement from all source
|
||||
* files in the program, then also delete it here.
|
||||
*/
|
||||
/* copyright --> */
|
||||
#include "UTPexExtensionMessage.h"
|
||||
#include "Peer.h"
|
||||
#include "BtContext.h"
|
||||
#include "Dictionary.h"
|
||||
#include "Data.h"
|
||||
#include "BencodeVisitor.h"
|
||||
#include "a2netcompat.h"
|
||||
#include "Util.h"
|
||||
#include "PeerMessageUtil.h"
|
||||
#include "BtRegistry.h"
|
||||
#include "CompactPeerListProcessor.h"
|
||||
#include "MetaFileUtil.h"
|
||||
#include "DlAbortEx.h"
|
||||
#include "message.h"
|
||||
|
||||
const string UTPexExtensionMessage::EXTENSION_NAME = "ut_pex";
|
||||
|
||||
UTPexExtensionMessage::UTPexExtensionMessage(uint8_t extensionMessageID):
|
||||
_extensionMessageID(extensionMessageID),
|
||||
_btContext(0) {}
|
||||
|
||||
UTPexExtensionMessage::~UTPexExtensionMessage() {}
|
||||
|
||||
string UTPexExtensionMessage::getBencodedData()
|
||||
{
|
||||
SharedHandle<Dictionary> d = new Dictionary();
|
||||
pair<string, string> freshPeerPair = createCompactPeerListAndFlag(_freshPeers);
|
||||
pair<string, string> droppedPeerPair = createCompactPeerListAndFlag(_droppedPeers);
|
||||
d->put("added", new Data(freshPeerPair.first));
|
||||
d->put("added.f", new Data(freshPeerPair.second));
|
||||
d->put("dropped", new Data(droppedPeerPair.first));
|
||||
|
||||
BencodeVisitor v;
|
||||
d->accept(&v);
|
||||
return v.getBencodedData();
|
||||
}
|
||||
|
||||
pair<string, string> UTPexExtensionMessage::createCompactPeerListAndFlag(const Peers& peers)
|
||||
{
|
||||
string addrstring;
|
||||
string flagstring;
|
||||
for(Peers::const_iterator itr = peers.begin(); itr != peers.end(); ++itr) {
|
||||
char compact[6];
|
||||
if(PeerMessageUtil::createcompact(compact, (*itr)->ipaddr, (*itr)->port)) {
|
||||
addrstring.append(&compact[0], &compact[6]);
|
||||
flagstring += (*itr)->isSeeder() ? "2" : "0";
|
||||
}
|
||||
}
|
||||
return pair<string, string>(addrstring, flagstring);
|
||||
}
|
||||
|
||||
string UTPexExtensionMessage::toString() const
|
||||
{
|
||||
return "ut_pex added="+Util::uitos(_freshPeers.size())+", dropped="+
|
||||
Util::uitos(_droppedPeers.size());
|
||||
}
|
||||
|
||||
void UTPexExtensionMessage::doReceivedAction()
|
||||
{
|
||||
PEER_STORAGE(_btContext)->addPeer(_freshPeers);
|
||||
}
|
||||
|
||||
void UTPexExtensionMessage::addFreshPeer(const PeerHandle& peer)
|
||||
{
|
||||
_freshPeers.push_back(peer);
|
||||
}
|
||||
|
||||
const Peers& UTPexExtensionMessage::getFreshPeers() const
|
||||
{
|
||||
return _freshPeers;
|
||||
}
|
||||
|
||||
void UTPexExtensionMessage::addDroppedPeer(const PeerHandle& peer)
|
||||
{
|
||||
_droppedPeers.push_back(peer);
|
||||
}
|
||||
|
||||
const Peers& UTPexExtensionMessage::getDroppedPeers() const
|
||||
{
|
||||
return _droppedPeers;
|
||||
}
|
||||
|
||||
void UTPexExtensionMessage::setBtContext(const BtContextHandle& btContext)
|
||||
{
|
||||
_btContext = btContext;
|
||||
}
|
||||
|
||||
UTPexExtensionMessageHandle
|
||||
UTPexExtensionMessage::create(const BtContextHandle& btContext,
|
||||
const char* data, size_t len)
|
||||
{
|
||||
if(len < 1) {
|
||||
throw new DlAbortEx(MSG_TOO_SMALL_PAYLOAD_SIZE,
|
||||
EXTENSION_NAME.c_str(), len);
|
||||
}
|
||||
UTPexExtensionMessageHandle msg = new UTPexExtensionMessage(*data);
|
||||
SharedHandle<MetaEntry> root = MetaFileUtil::bdecoding(data+1, len-1);
|
||||
if(root.isNull()) {
|
||||
return msg;
|
||||
}
|
||||
const Dictionary* d = dynamic_cast<const Dictionary*>(root.get());
|
||||
if(d) {
|
||||
CompactPeerListProcessor proc(btContext->getPieceLength(),
|
||||
btContext->getTotalLength());
|
||||
const Data* added = dynamic_cast<const Data*>(d->get("added"));
|
||||
if(added) {
|
||||
msg->_freshPeers = proc.extractPeer(added);
|
||||
}
|
||||
const Data* dropped = dynamic_cast<const Data*>(d->get("dropped"));
|
||||
if(dropped) {
|
||||
msg->_droppedPeers = proc.extractPeer(dropped);
|
||||
}
|
||||
}
|
||||
return msg;
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
/* <!-- copyright */
|
||||
/*
|
||||
* aria2 - The high speed download utility
|
||||
*
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* In addition, as a special exception, the copyright holders give
|
||||
* permission to link the code of portions of this program with the
|
||||
* OpenSSL library under certain conditions as described in each
|
||||
* individual source file, and distribute linked combinations
|
||||
* including the two.
|
||||
* You must obey the GNU General Public License in all respects
|
||||
* for all of the code used other than OpenSSL. If you modify
|
||||
* file(s) with this exception, you may extend this exception to your
|
||||
* version of the file(s), but you are not obligated to do so. If you
|
||||
* do not wish to do so, delete this exception statement from your
|
||||
* version. If you delete this exception statement from all source
|
||||
* files in the program, then also delete it here.
|
||||
*/
|
||||
/* copyright --> */
|
||||
#ifndef _D_UT_PEX_EXTENSION_MESSAGE_H_
|
||||
#define _D_UT_PEX_EXTENSION_MESSAGE_H_
|
||||
|
||||
#include "ExtensionMessage.h"
|
||||
|
||||
class BtContext;
|
||||
typedef SharedHandle<BtContext> BtContextHandle;
|
||||
class Peer;
|
||||
typedef SharedHandle<Peer> PeerHandle;
|
||||
typedef deque<PeerHandle> Peers;
|
||||
class UTPexExtensionMessage;
|
||||
typedef SharedHandle<UTPexExtensionMessage> UTPexExtensionMessageHandle;
|
||||
|
||||
class UTPexExtensionMessage:public ExtensionMessage {
|
||||
private:
|
||||
uint8_t _extensionMessageID;
|
||||
|
||||
Peers _freshPeers;
|
||||
|
||||
Peers _droppedPeers;
|
||||
|
||||
BtContextHandle _btContext;
|
||||
|
||||
pair<string, string> createCompactPeerListAndFlag(const Peers& peers);
|
||||
|
||||
public:
|
||||
UTPexExtensionMessage(uint8_t extensionMessageID);
|
||||
|
||||
virtual ~UTPexExtensionMessage();
|
||||
|
||||
virtual string getBencodedData();
|
||||
|
||||
virtual uint8_t getExtensionMessageID()
|
||||
{
|
||||
return _extensionMessageID;
|
||||
}
|
||||
|
||||
virtual const string& getExtensionName() const
|
||||
{
|
||||
return EXTENSION_NAME;
|
||||
}
|
||||
|
||||
static const string EXTENSION_NAME;
|
||||
|
||||
virtual string toString() const;
|
||||
|
||||
virtual void doReceivedAction();
|
||||
|
||||
void addFreshPeer(const PeerHandle& peer);
|
||||
|
||||
const Peers& getFreshPeers() const;
|
||||
|
||||
void addDroppedPeer(const PeerHandle& peer);
|
||||
|
||||
const Peers& getDroppedPeers() const;
|
||||
|
||||
void setBtContext(const BtContextHandle& btContext);
|
||||
|
||||
static UTPexExtensionMessageHandle create(const BtContextHandle& btContext,
|
||||
const char* data, size_t len);
|
||||
};
|
||||
|
||||
typedef SharedHandle<UTPexExtensionMessage> UTPexExtensionMessageHandle;
|
||||
|
||||
#endif // _D_UT_PEX_EXTENSION_MESSAGE_H_
|
|
@ -78,6 +78,7 @@
|
|||
#define MSG_DELETING_REQUEST_SLOT_TIMEOUT _("CUID#%d - Deleting request slot blockIndex=%d because of time out")
|
||||
#define MSG_DELETING_REQUEST_SLOT_ACQUIRED _("CUID#%d - Deleting request slot blockIndex=%d because the block has been acquired.")
|
||||
#define MSG_FAST_EXTENSION_ENABLED _("CUID#%d - Fast extension enabled.")
|
||||
#define MSG_EXTENDED_MESSAGING_ENABLED _("CUID#%d - Extended Messaging enabled.")
|
||||
#define MSG_FILE_ALLOCATION_FAILURE _("CUID#%d - Exception caught while allocating file space.")
|
||||
#define MSG_CONTENT_DISPOSITION_DETECTED _("CUID#%d - Content-Disposition detected. Use %s as filename")
|
||||
#define MSG_PEER_BANNED _("CUID#%d - Peer %s:%d banned.")
|
||||
|
@ -131,6 +132,7 @@
|
|||
#define MSG_RESOURCE_NOT_FOUND _("Resource not found")
|
||||
#define MSG_FILE_RENAMED _("File already exists. Renamed to %s.")
|
||||
#define MSG_CANNOT_PARSE_METALINK _("Cannot parse metalink XML file. XML may be malformed.")
|
||||
#define MSG_TOO_SMALL_PAYLOAD_SIZE _("Too small payload size for %s, size=%d.")
|
||||
|
||||
#define EX_TIME_OUT _("Timeout.")
|
||||
#define EX_INVALID_CHUNK_SIZE _("Invalid chunk size.")
|
||||
|
@ -154,7 +156,7 @@
|
|||
#define EX_AUTH_FAILED _("Authorization failed.")
|
||||
#define EX_GOT_EOF _("Got EOF from the server.")
|
||||
#define EX_EOF_FROM_PEER _("Got EOF from peer.")
|
||||
#define EX_MULFORMED_META_INFO _("Malformed meta info.")
|
||||
#define EX_MALFORMED_META_INFO _("Malformed meta info.")
|
||||
|
||||
#define EX_FILE_OPEN _("Failed to open the file %s, cause: %s")
|
||||
#define EX_FILE_WRITE _("Failed to write into the file %s, cause: %s")
|
||||
|
|
|
@ -129,6 +129,7 @@ Option* option_processing(int argc, char* const argv[])
|
|||
op->put(PREF_ENABLE_DIRECT_IO, V_FALSE);
|
||||
op->put(PREF_ALLOW_PIECE_LENGTH_CHANGE, V_FALSE);
|
||||
op->put(PREF_METALINK_PREFERRED_PROTOCOL, V_NONE);
|
||||
op->put(PREF_ENABLE_PEER_EXCHANGE, V_TRUE);
|
||||
while(1) {
|
||||
int optIndex = 0;
|
||||
int lopt;
|
||||
|
|
|
@ -207,6 +207,8 @@
|
|||
#define PREF_BT_KEEP_ALIVE_INTERVAL "bt-keep-alive-interval"
|
||||
// values: a string, less than or equals to 20 bytes length
|
||||
#define PREF_PEER_ID_PREFIX "peer-id-prefix"
|
||||
// values: true | false
|
||||
#define PREF_ENABLE_PEER_EXCHANGE "enable-peer-exchange"
|
||||
|
||||
/**
|
||||
* Metalink related preferences
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
#include "BencodeVisitor.h"
|
||||
#include "Data.h"
|
||||
#include "List.h"
|
||||
#include "Dictionary.h"
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
|
||||
class BencodeVisitorTest:public CppUnit::TestFixture {
|
||||
|
||||
CPPUNIT_TEST_SUITE(BencodeVisitorTest);
|
||||
CPPUNIT_TEST(testVisit_data);
|
||||
CPPUNIT_TEST(testVisit_list);
|
||||
CPPUNIT_TEST(testVisit_dictionary);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
private:
|
||||
|
||||
public:
|
||||
void setUp() {
|
||||
}
|
||||
|
||||
void testVisit_data();
|
||||
void testVisit_list();
|
||||
void testVisit_dictionary();
|
||||
};
|
||||
|
||||
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION( BencodeVisitorTest );
|
||||
|
||||
void BencodeVisitorTest::testVisit_data()
|
||||
{
|
||||
{
|
||||
BencodeVisitor v;
|
||||
string str = "apple";
|
||||
MetaEntryHandle m = new Data(str.c_str(), str.size());
|
||||
m->accept(&v);
|
||||
CPPUNIT_ASSERT_EQUAL(string("5:apple"), v.getBencodedData());
|
||||
}
|
||||
{
|
||||
BencodeVisitor v;
|
||||
string str = "123";
|
||||
MetaEntryHandle m = new Data(str.c_str(), str.size(), true);
|
||||
m->accept(&v);
|
||||
CPPUNIT_ASSERT_EQUAL(string("i123e"), v.getBencodedData());
|
||||
}
|
||||
}
|
||||
|
||||
void BencodeVisitorTest::testVisit_list()
|
||||
{
|
||||
BencodeVisitor v;
|
||||
List l;
|
||||
string s1 = "alpha";
|
||||
l.add(new Data(s1.c_str(), s1.size()));
|
||||
string s2 = "bravo";
|
||||
l.add(new Data(s2.c_str(), s2.size()));
|
||||
string s3 = "123";
|
||||
l.add(new Data(s3.c_str(), s3.size(), true));
|
||||
l.accept(&v);
|
||||
CPPUNIT_ASSERT_EQUAL(string("l5:alpha5:bravoi123ee"), v.getBencodedData());
|
||||
}
|
||||
|
||||
void BencodeVisitorTest::testVisit_dictionary()
|
||||
{
|
||||
BencodeVisitor v;
|
||||
Dictionary d;
|
||||
string s1 = "alpha";
|
||||
d.put("team", new Data(s1.c_str(), s1.size()));
|
||||
string s2 = "123";
|
||||
d.put("score", new Data(s2.c_str(), s2.size(), true));
|
||||
d.accept(&v);
|
||||
CPPUNIT_ASSERT_EQUAL(string("d4:team5:alpha5:scorei123ee"), v.getBencodedData());
|
||||
}
|
|
@ -0,0 +1,121 @@
|
|||
#include "BtExtendedMessage.h"
|
||||
#include "PeerMessageUtil.h"
|
||||
#include "MockBtContext.h"
|
||||
#include "MockExtensionMessageFactory.h"
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class BtExtendedMessageTest:public CppUnit::TestFixture {
|
||||
|
||||
CPPUNIT_TEST_SUITE(BtExtendedMessageTest);
|
||||
CPPUNIT_TEST(testCreate);
|
||||
CPPUNIT_TEST(testGetMessage);
|
||||
CPPUNIT_TEST(testDoReceivedAction);
|
||||
CPPUNIT_TEST(testToString);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
private:
|
||||
|
||||
public:
|
||||
void setUp()
|
||||
{
|
||||
BtRegistry::unregisterAll();
|
||||
}
|
||||
|
||||
void tearDown()
|
||||
{
|
||||
BtRegistry::unregisterAll();
|
||||
}
|
||||
|
||||
void testCreate();
|
||||
void testGetMessage();
|
||||
void testDoReceivedAction();
|
||||
void testToString();
|
||||
};
|
||||
|
||||
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION(BtExtendedMessageTest);
|
||||
|
||||
void BtExtendedMessageTest::testCreate() {
|
||||
PeerHandle peer = new Peer("192.168.0.1", 6969, 16*1024, 256*1024);
|
||||
peer->setExtension("charlie", 1);
|
||||
MockBtContextHandle ctx = new MockBtContext();
|
||||
unsigned char infohash[20];
|
||||
memset(infohash, 0, sizeof(infohash));
|
||||
ctx->setInfoHash(infohash);
|
||||
MockExtensionMessageFactoryHandle exmsgFactory = new MockExtensionMessageFactory();
|
||||
|
||||
|
||||
BtRegistry::registerPeerObjectCluster(ctx->getInfoHashAsString(), new PeerObjectCluster());
|
||||
PeerObjectHandle peerObject = new PeerObject();
|
||||
peerObject->extensionMessageFactory = exmsgFactory;
|
||||
|
||||
PEER_OBJECT_CLUSTER(ctx)->registerHandle(peer->getId(), peerObject);
|
||||
|
||||
// payload:{4:name3:foo}->11bytes
|
||||
string payload = "4:name3:foo";
|
||||
char msg[17];// 6+11bytes
|
||||
PeerMessageUtil::createPeerMessageString((unsigned char*)msg, sizeof(msg), 13, 20);
|
||||
msg[5] = 1; // Set dummy extended message ID 1
|
||||
memcpy(msg+6, payload.c_str(), payload.size());
|
||||
BtExtendedMessageHandle pm = BtExtendedMessage::create(ctx,
|
||||
peer,
|
||||
&msg[4], 13);
|
||||
CPPUNIT_ASSERT_EQUAL((int8_t)20, pm->getId());
|
||||
|
||||
// case: payload size is wrong
|
||||
try {
|
||||
char msg[5];
|
||||
PeerMessageUtil::createPeerMessageString((unsigned char*)msg, sizeof(msg), 1, 20);
|
||||
BtExtendedMessage::create(ctx, peer, &msg[4], 1);
|
||||
CPPUNIT_FAIL("exception must be thrown.");
|
||||
} catch(Exception* e) {
|
||||
cerr << *e << endl;
|
||||
delete e;
|
||||
}
|
||||
// case: id is wrong
|
||||
try {
|
||||
char msg[6];
|
||||
PeerMessageUtil::createPeerMessageString((unsigned char*)msg, sizeof(msg), 2, 21);
|
||||
BtExtendedMessage::create(ctx, peer, &msg[4], 2);
|
||||
CPPUNIT_FAIL("exception must be thrown.");
|
||||
} catch(Exception* e) {
|
||||
cerr << *e << endl;
|
||||
delete e;
|
||||
}
|
||||
}
|
||||
|
||||
void BtExtendedMessageTest::testGetMessage() {
|
||||
string payload = "4:name3:foo";
|
||||
uint8_t extendedMessageID = 1;
|
||||
MockExtensionMessageHandle exmsg =
|
||||
new MockExtensionMessage("charlie", extendedMessageID,
|
||||
payload.c_str(),
|
||||
payload.size());
|
||||
BtExtendedMessage msg(exmsg);
|
||||
|
||||
char data[17];
|
||||
PeerMessageUtil::createPeerMessageString((unsigned char*)data, sizeof(data), 13, 20);
|
||||
*(data+5) = extendedMessageID;
|
||||
memcpy(data+6, payload.c_str(), payload.size());
|
||||
CPPUNIT_ASSERT(memcmp(msg.getMessage(), data, 17) == 0);
|
||||
}
|
||||
|
||||
void BtExtendedMessageTest::testDoReceivedAction() {
|
||||
MockExtensionMessageHandle exmsg =
|
||||
new MockExtensionMessage("charlie", 1, "", 0);
|
||||
BtExtendedMessage msg(exmsg);
|
||||
msg.doReceivedAction();
|
||||
CPPUNIT_ASSERT(exmsg->_doReceivedActionCalled);
|
||||
}
|
||||
|
||||
void BtExtendedMessageTest::testToString() {
|
||||
string payload = "4:name3:foo";
|
||||
uint8_t extendedMessageID = 1;
|
||||
MockExtensionMessageHandle exmsg =
|
||||
new MockExtensionMessage("charlie", extendedMessageID,
|
||||
payload.c_str(),
|
||||
payload.size());
|
||||
BtExtendedMessage msg(exmsg);
|
||||
CPPUNIT_ASSERT_EQUAL(string("extended charlie"), msg.toString());
|
||||
}
|
|
@ -34,7 +34,7 @@ void createHandshakeMessageData(unsigned char* msg) {
|
|||
msg[0] = 19;
|
||||
memcpy(&msg[1], BtHandshakeMessageTest::BTPSTR.c_str(),
|
||||
BtHandshakeMessageTest::BTPSTR.size());
|
||||
unsigned char reserved[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04 };
|
||||
unsigned char reserved[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x04 };
|
||||
memcpy(&msg[20], reserved, sizeof(reserved));
|
||||
unsigned char infoHash[] = { 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
|
@ -56,7 +56,7 @@ void BtHandshakeMessageTest::testCreate() {
|
|||
CPPUNIT_ASSERT_EQUAL((int8_t)19, message->getPstrlen());
|
||||
CPPUNIT_ASSERT_EQUAL(Util::toHex((const unsigned char*)BTPSTR.c_str(), BTPSTR.size()),
|
||||
Util::toHex(message->getPstr(), BtHandshakeMessage::PSTR_LENGTH));
|
||||
CPPUNIT_ASSERT_EQUAL(string("0000000000000004"),
|
||||
CPPUNIT_ASSERT_EQUAL(string("0000000000100004"),
|
||||
Util::toHex(message->getReserved(), BtHandshakeMessage::RESERVED_LENGTH));
|
||||
CPPUNIT_ASSERT_EQUAL(string("ffffffffffffffffffffffffffffffffffffffff"),
|
||||
Util::toHex(message->getInfoHash(), INFO_HASH_LENGTH));
|
||||
|
@ -98,5 +98,5 @@ void BtHandshakeMessageTest::testToString() {
|
|||
msg.setInfoHash(infoHash);
|
||||
msg.setPeerId(peerId);
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL(string("handshake peerId=%f0%f0%f0%f0%f0%f0%f0%f0%f0%f0%f0%f0%f0%f0%f0%f0%f0%f0%f0%f0, reserved=0000000000000004"), msg.toString());
|
||||
CPPUNIT_ASSERT_EQUAL(string("handshake peerId=%f0%f0%f0%f0%f0%f0%f0%f0%f0%f0%f0%f0%f0%f0%f0%f0%f0%f0%f0%f0, reserved=0000000000100004"), msg.toString());
|
||||
}
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
#include "DefaultBtMessageFactory.h"
|
||||
#include "Peer.h"
|
||||
#include "PeerMessageUtil.h"
|
||||
#include "BtRegistry.h"
|
||||
#include "MockBtContext.h"
|
||||
#include "MockExtensionMessageFactory.h"
|
||||
#include "BtExtendedMessage.h"
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
|
||||
class DefaultBtMessageFactoryTest:public CppUnit::TestFixture {
|
||||
|
||||
CPPUNIT_TEST_SUITE(DefaultBtMessageFactoryTest);
|
||||
CPPUNIT_TEST(testCreateBtMessage_BtExtendedMessage);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
private:
|
||||
MockBtContextHandle _btContext;
|
||||
PeerHandle _peer;
|
||||
public:
|
||||
DefaultBtMessageFactoryTest():_btContext(0), _peer(0) {}
|
||||
|
||||
void setUp()
|
||||
{
|
||||
BtRegistry::unregisterAll();
|
||||
MockBtContextHandle btContext = new MockBtContext();
|
||||
unsigned char infohash[20];
|
||||
memset(infohash, 0, sizeof(infohash));
|
||||
btContext->setInfoHash(infohash);
|
||||
_btContext = btContext;
|
||||
|
||||
_peer = new Peer("192.168.0.1", 6969, 16*1024, 256*1024);
|
||||
_peer->setExtendedMessagingEnabled(true);
|
||||
|
||||
MockExtensionMessageFactoryHandle exmsgFactory = new MockExtensionMessageFactory();
|
||||
BtRegistry::registerPeerObjectCluster(_btContext->getInfoHashAsString(),
|
||||
new PeerObjectCluster());
|
||||
PeerObjectHandle peerObject = new PeerObject();
|
||||
peerObject->extensionMessageFactory = exmsgFactory;
|
||||
|
||||
PEER_OBJECT_CLUSTER(_btContext)->registerHandle(_peer->getId(), peerObject);
|
||||
}
|
||||
|
||||
void tearDown()
|
||||
{
|
||||
BtRegistry::unregisterAll();
|
||||
}
|
||||
|
||||
void testCreateBtMessage_BtExtendedMessage();
|
||||
};
|
||||
|
||||
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION(DefaultBtMessageFactoryTest);
|
||||
|
||||
void DefaultBtMessageFactoryTest::testCreateBtMessage_BtExtendedMessage()
|
||||
{
|
||||
|
||||
DefaultBtMessageFactory factory;
|
||||
factory.setBtContext(_btContext);
|
||||
factory.setPeer(_peer);
|
||||
|
||||
// payload:{4:name3:foo}->11bytes
|
||||
string payload = "4:name3:foo";
|
||||
char msg[17];// 6+11bytes
|
||||
PeerMessageUtil::createPeerMessageString((unsigned char*)msg, sizeof(msg), 13, 20);
|
||||
msg[5] = 1; // Set dummy extended message ID 1
|
||||
memcpy(msg+6, payload.c_str(), payload.size());
|
||||
|
||||
BtExtendedMessageHandle m = factory.createBtMessage((const unsigned char*)msg+4, sizeof(msg));
|
||||
|
||||
try {
|
||||
// disable extended messaging
|
||||
_peer->setExtendedMessagingEnabled(false);
|
||||
factory.createBtMessage((const unsigned char*)msg+4, sizeof(msg));
|
||||
CPPUNIT_FAIL("exception must be thrown.");
|
||||
} catch(Exception* e) {
|
||||
cerr << *e << endl;
|
||||
delete e;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,113 @@
|
|||
#include "DefaultExtensionMessageFactory.h"
|
||||
#include "Peer.h"
|
||||
#include "MockBtContext.h"
|
||||
#include "PeerMessageUtil.h"
|
||||
#include "HandshakeExtensionMessage.h"
|
||||
#include "UTPexExtensionMessage.h"
|
||||
#include "Exception.h"
|
||||
#include "BtRegistry.h"
|
||||
#include "BtRuntime.h"
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
|
||||
class DefaultExtensionMessageFactoryTest:public CppUnit::TestFixture {
|
||||
|
||||
CPPUNIT_TEST_SUITE(DefaultExtensionMessageFactoryTest);
|
||||
CPPUNIT_TEST(testCreateMessage_unknown);
|
||||
CPPUNIT_TEST(testCreateMessage_Handshake);
|
||||
CPPUNIT_TEST(testCreateMessage_UTPex);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
private:
|
||||
MockBtContextHandle _btContext;
|
||||
PeerHandle _peer;
|
||||
public:
|
||||
DefaultExtensionMessageFactoryTest():_btContext(0), _peer(0) {}
|
||||
|
||||
void setUp()
|
||||
{
|
||||
BtRegistry::unregisterAll();
|
||||
MockBtContextHandle btContext = new MockBtContext();
|
||||
unsigned char infohash[20];
|
||||
memset(infohash, 0, sizeof(infohash));
|
||||
btContext->setInfoHash(infohash);
|
||||
_btContext = btContext;
|
||||
|
||||
BtRuntimeHandle btRuntime = new BtRuntime();
|
||||
BtRegistry::registerBtRuntime(_btContext->getInfoHashAsString(),
|
||||
btRuntime);
|
||||
|
||||
_peer = new Peer("192.168.0.1", 6969, 16*1024, 256*1024);
|
||||
_peer->setExtension("ut_pex", 1);
|
||||
}
|
||||
|
||||
void tearDown()
|
||||
{
|
||||
BtRegistry::unregisterAll();
|
||||
}
|
||||
|
||||
void testCreateMessage_unknown();
|
||||
void testCreateMessage_Handshake();
|
||||
void testCreateMessage_UTPex();
|
||||
};
|
||||
|
||||
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION(DefaultExtensionMessageFactoryTest);
|
||||
|
||||
void DefaultExtensionMessageFactoryTest::testCreateMessage_unknown()
|
||||
{
|
||||
DefaultExtensionMessageFactory factory;
|
||||
factory.setBtContext(_btContext);
|
||||
factory.setPeer(_peer);
|
||||
_peer->setExtension("foo", 255);
|
||||
|
||||
char id[1] = { 255 };
|
||||
|
||||
string data = string(&id[0], &id[1]);
|
||||
try {
|
||||
factory.createMessage(data.c_str(), data.size());
|
||||
CPPUNIT_FAIL("exception must be thrown.");
|
||||
} catch(Exception* e) {
|
||||
cerr << *e << endl;
|
||||
delete e;
|
||||
}
|
||||
}
|
||||
|
||||
void DefaultExtensionMessageFactoryTest::testCreateMessage_Handshake()
|
||||
{
|
||||
DefaultExtensionMessageFactory factory;
|
||||
factory.setBtContext(_btContext);
|
||||
factory.setPeer(_peer);
|
||||
|
||||
char id[1] = { 0 };
|
||||
|
||||
string data = string(&id[0], &id[1])+"d1:v5:aria2e";
|
||||
HandshakeExtensionMessageHandle m = factory.createMessage(data.c_str(), data.size());
|
||||
CPPUNIT_ASSERT_EQUAL(string("aria2"), m->getClientVersion());
|
||||
}
|
||||
|
||||
void DefaultExtensionMessageFactoryTest::testCreateMessage_UTPex()
|
||||
{
|
||||
DefaultExtensionMessageFactory factory;
|
||||
factory.setBtContext(_btContext);
|
||||
factory.setPeer(_peer);
|
||||
|
||||
char c1[6];
|
||||
char c2[6];
|
||||
char c3[6];
|
||||
char c4[6];
|
||||
PeerMessageUtil::createcompact(c1, "192.168.0.1", 6881);
|
||||
PeerMessageUtil::createcompact(c2, "10.1.1.2", 9999);
|
||||
PeerMessageUtil::createcompact(c3, "192.168.0.2", 6882);
|
||||
PeerMessageUtil::createcompact(c4, "10.1.1.3",10000);
|
||||
|
||||
char id[1] = { BT_RUNTIME(_btContext)->getExtensionMessageID("ut_pex") };
|
||||
|
||||
string data = string(&id[0], &id[1])+"d5:added12:"+
|
||||
string(&c1[0], &c1[6])+string(&c2[0], &c2[6])+
|
||||
"7:added.f2:207:dropped12:"+
|
||||
string(&c3[0], &c3[6])+string(&c4[0], &c4[6])+
|
||||
"e";
|
||||
|
||||
UTPexExtensionMessageHandle m = factory.createMessage(data.c_str(), data.size());
|
||||
CPPUNIT_ASSERT_EQUAL(BT_RUNTIME(_btContext)->getExtensionMessageID("ut_pex"),
|
||||
m->getExtensionMessageID());
|
||||
}
|
|
@ -36,7 +36,7 @@ void DefaultPeerListProcessorTest::testExtractPeer() {
|
|||
CPPUNIT_ASSERT_EQUAL((size_t)1, peers.size());
|
||||
PeerHandle peer = *peers.begin();
|
||||
CPPUNIT_ASSERT_EQUAL(string("192.168.0.1"), peer->ipaddr);
|
||||
CPPUNIT_ASSERT_EQUAL((int32_t)2006, peer->port);
|
||||
CPPUNIT_ASSERT_EQUAL((uint16_t)2006, peer->port);
|
||||
}
|
||||
|
||||
void DefaultPeerListProcessorTest::testExtract2Peers() {
|
||||
|
@ -49,9 +49,9 @@ void DefaultPeerListProcessorTest::testExtract2Peers() {
|
|||
CPPUNIT_ASSERT_EQUAL((size_t)2, peers.size());
|
||||
PeerHandle peer = *peers.begin();
|
||||
CPPUNIT_ASSERT_EQUAL(string("192.168.0.1"), peer->ipaddr);
|
||||
CPPUNIT_ASSERT_EQUAL((int32_t)2006, peer->port);
|
||||
CPPUNIT_ASSERT_EQUAL((uint16_t)2006, peer->port);
|
||||
|
||||
peer = *(peers.begin()+1);
|
||||
CPPUNIT_ASSERT_EQUAL(string("192.168.0.2"), peer->ipaddr);
|
||||
CPPUNIT_ASSERT_EQUAL((int32_t)2007, peer->port);
|
||||
CPPUNIT_ASSERT_EQUAL((uint16_t)2007, peer->port);
|
||||
}
|
||||
|
|
|
@ -113,9 +113,8 @@ void DefaultPeerStorageTest::testAddPeer() {
|
|||
|
||||
CPPUNIT_ASSERT_EQUAL((int32_t)3, ps.countPeer());
|
||||
|
||||
// this is true, because peer1 in the container has no errors and
|
||||
// it is replaced by peer1(self assignment).
|
||||
CPPUNIT_ASSERT_EQUAL(true, ps.addPeer(peer1));
|
||||
// this returns false, because peer1 is already in the container
|
||||
CPPUNIT_ASSERT_EQUAL(false, ps.addPeer(peer1));
|
||||
// the number of peers doesn't change.
|
||||
CPPUNIT_ASSERT_EQUAL((int32_t)3, ps.countPeer());
|
||||
|
||||
|
|
|
@ -0,0 +1,155 @@
|
|||
#include "HandshakeExtensionMessage.h"
|
||||
#include "Peer.h"
|
||||
#include "MockBtContext.h"
|
||||
#include "MockPeerStorage.h"
|
||||
#include "BtRegistry.h"
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
|
||||
class HandshakeExtensionMessageTest:public CppUnit::TestFixture {
|
||||
|
||||
CPPUNIT_TEST_SUITE(HandshakeExtensionMessageTest);
|
||||
CPPUNIT_TEST(testGetExtensionMessageID);
|
||||
CPPUNIT_TEST(testGetExtensionName);
|
||||
CPPUNIT_TEST(testGetBencodedData);
|
||||
CPPUNIT_TEST(testToString);
|
||||
CPPUNIT_TEST(testDoReceivedAction);
|
||||
CPPUNIT_TEST(testCreate);
|
||||
CPPUNIT_TEST(testCreate_stringnum);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
private:
|
||||
BtContextHandle _btContext;
|
||||
public:
|
||||
HandshakeExtensionMessageTest():_btContext(0) {}
|
||||
|
||||
void setUp()
|
||||
{
|
||||
BtRegistry::unregisterAll();
|
||||
MockBtContextHandle btContext = new MockBtContext();
|
||||
unsigned char infohash[20];
|
||||
memset(infohash, 0, sizeof(infohash));
|
||||
btContext->setInfoHash(infohash);
|
||||
_btContext = btContext;
|
||||
MockPeerStorageHandle peerStorage = new MockPeerStorage();
|
||||
BtRegistry::registerPeerStorage(_btContext->getInfoHashAsString(),
|
||||
peerStorage);
|
||||
}
|
||||
|
||||
void tearDown()
|
||||
{
|
||||
BtRegistry::unregisterAll();
|
||||
}
|
||||
|
||||
void testGetExtensionMessageID();
|
||||
void testGetExtensionName();
|
||||
void testGetBencodedData();
|
||||
void testToString();
|
||||
void testDoReceivedAction();
|
||||
void testCreate();
|
||||
void testCreate_stringnum();
|
||||
};
|
||||
|
||||
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION(HandshakeExtensionMessageTest);
|
||||
|
||||
void HandshakeExtensionMessageTest::testGetExtensionMessageID()
|
||||
{
|
||||
HandshakeExtensionMessage msg;
|
||||
CPPUNIT_ASSERT_EQUAL((uint8_t)0, msg.getExtensionMessageID());
|
||||
}
|
||||
|
||||
void HandshakeExtensionMessageTest::testGetExtensionName()
|
||||
{
|
||||
HandshakeExtensionMessage msg;
|
||||
CPPUNIT_ASSERT_EQUAL(string("handshake"), msg.getExtensionName());
|
||||
}
|
||||
|
||||
void HandshakeExtensionMessageTest::testGetBencodedData()
|
||||
{
|
||||
HandshakeExtensionMessage msg;
|
||||
msg.setClientVersion("aria2");
|
||||
msg.setTCPPort(6889);
|
||||
msg.setExtension("ut_pex", 1);
|
||||
msg.setExtension("a2_dht", 2);
|
||||
CPPUNIT_ASSERT_EQUAL(string("d1:v5:aria21:pi6889e1:md6:a2_dhti2e6:ut_pexi1eee"), msg.getBencodedData());
|
||||
}
|
||||
|
||||
void HandshakeExtensionMessageTest::testToString()
|
||||
{
|
||||
HandshakeExtensionMessage msg;
|
||||
msg.setClientVersion("aria2");
|
||||
msg.setTCPPort(6889);
|
||||
msg.setExtension("ut_pex", 1);
|
||||
msg.setExtension("a2_dht", 2);
|
||||
CPPUNIT_ASSERT_EQUAL(string("handshake client=aria2, tcpPort=6889, a2_dht=2, ut_pex=1"), msg.toString());
|
||||
}
|
||||
|
||||
void HandshakeExtensionMessageTest::testDoReceivedAction()
|
||||
{
|
||||
PeerHandle peer = new Peer("192.168.0.1", 0, 1, 1);
|
||||
HandshakeExtensionMessage msg;
|
||||
msg.setClientVersion("aria2");
|
||||
msg.setTCPPort(6889);
|
||||
msg.setExtension("ut_pex", 1);
|
||||
msg.setExtension("a2_dht", 2);
|
||||
msg.setPeer(peer);
|
||||
msg.setBtContext(_btContext);
|
||||
|
||||
msg.doReceivedAction();
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL((uint16_t)6889, peer->port);
|
||||
CPPUNIT_ASSERT_EQUAL((uint8_t)1, peer->getExtensionMessageID("ut_pex"));
|
||||
CPPUNIT_ASSERT_EQUAL((uint8_t)2, peer->getExtensionMessageID("a2_dht"));
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL((size_t)1, PEER_STORAGE(_btContext)->getPeers().size());
|
||||
PeerHandle p1 = PEER_STORAGE(_btContext)->getPeers().front();
|
||||
CPPUNIT_ASSERT_EQUAL(string("192.168.0.1"), p1->ipaddr);
|
||||
CPPUNIT_ASSERT_EQUAL((uint16_t)6889, p1->port);
|
||||
}
|
||||
|
||||
void HandshakeExtensionMessageTest::testCreate()
|
||||
{
|
||||
string in = "0d1:pi6881e1:v5:aria21:md6:ut_pexi1eee";
|
||||
HandshakeExtensionMessageHandle m =
|
||||
HandshakeExtensionMessage::create(in.c_str(), in.size());
|
||||
CPPUNIT_ASSERT_EQUAL(string("aria2"), m->getClientVersion());
|
||||
CPPUNIT_ASSERT_EQUAL((uint16_t)6881, m->getTCPPort());
|
||||
CPPUNIT_ASSERT_EQUAL((uint8_t)1, m->getExtensionMessageID("ut_pex"));
|
||||
|
||||
try {
|
||||
// bad payload format
|
||||
string in = "011:hello world";
|
||||
HandshakeExtensionMessage::create(in.c_str(), in.size());
|
||||
CPPUNIT_FAIL("exception must be thrown.");
|
||||
} catch(Exception* e) {
|
||||
cerr << *e << endl;
|
||||
delete e;
|
||||
}
|
||||
try {
|
||||
// malformed dencoded message
|
||||
string in = "011:hello";
|
||||
HandshakeExtensionMessage::create(in.c_str(), in.size());
|
||||
CPPUNIT_FAIL("exception must be thrown.");
|
||||
} catch(Exception* e) {
|
||||
cerr << *e << endl;
|
||||
delete e;
|
||||
}
|
||||
try {
|
||||
// 0 length data
|
||||
string in = "";
|
||||
HandshakeExtensionMessage::create(in.c_str(), in.size());
|
||||
CPPUNIT_FAIL("exception must be thrown.");
|
||||
} catch(Exception* e) {
|
||||
cerr << *e << endl;
|
||||
delete e;
|
||||
}
|
||||
}
|
||||
|
||||
void HandshakeExtensionMessageTest::testCreate_stringnum()
|
||||
{
|
||||
string in = "0d1:p4:68811:v5:aria21:md6:ut_pex1:1ee";
|
||||
HandshakeExtensionMessageHandle m =
|
||||
HandshakeExtensionMessage::create(in.c_str(), in.size());
|
||||
CPPUNIT_ASSERT_EQUAL(string("aria2"), m->getClientVersion());
|
||||
CPPUNIT_ASSERT_EQUAL((uint16_t)6881, m->getTCPPort());
|
||||
CPPUNIT_ASSERT_EQUAL((uint8_t)1, m->getExtensionMessageID("ut_pex"));
|
||||
}
|
|
@ -95,7 +95,13 @@ aria2c_SOURCES += BtAllowedFastMessageTest.cc\
|
|||
BtDependencyTest.cc\
|
||||
BtPostDownloadHandlerTest.cc\
|
||||
DownloadHandlerFactoryTest.cc\
|
||||
TimeSeedCriteriaTest.cc
|
||||
TimeSeedCriteriaTest.cc\
|
||||
BencodeVisitorTest.cc\
|
||||
BtExtendedMessageTest.cc\
|
||||
HandshakeExtensionMessageTest.cc\
|
||||
UTPexExtensionMessageTest.cc\
|
||||
DefaultBtMessageFactoryTest.cc\
|
||||
DefaultExtensionMessageFactoryTest.cc
|
||||
endif # ENABLE_BITTORRENT
|
||||
|
||||
if ENABLE_METALINK
|
||||
|
|
|
@ -83,7 +83,13 @@ check_PROGRAMS = $(am__EXEEXT_1)
|
|||
@ENABLE_BITTORRENT_TRUE@ BtDependencyTest.cc\
|
||||
@ENABLE_BITTORRENT_TRUE@ BtPostDownloadHandlerTest.cc\
|
||||
@ENABLE_BITTORRENT_TRUE@ DownloadHandlerFactoryTest.cc\
|
||||
@ENABLE_BITTORRENT_TRUE@ TimeSeedCriteriaTest.cc
|
||||
@ENABLE_BITTORRENT_TRUE@ TimeSeedCriteriaTest.cc\
|
||||
@ENABLE_BITTORRENT_TRUE@ BencodeVisitorTest.cc\
|
||||
@ENABLE_BITTORRENT_TRUE@ BtExtendedMessageTest.cc\
|
||||
@ENABLE_BITTORRENT_TRUE@ HandshakeExtensionMessageTest.cc\
|
||||
@ENABLE_BITTORRENT_TRUE@ UTPexExtensionMessageTest.cc\
|
||||
@ENABLE_BITTORRENT_TRUE@ DefaultBtMessageFactoryTest.cc\
|
||||
@ENABLE_BITTORRENT_TRUE@ DefaultExtensionMessageFactoryTest.cc
|
||||
|
||||
@ENABLE_METALINK_TRUE@am__append_3 = MetalinkerTest.cc\
|
||||
@ENABLE_METALINK_TRUE@ MetalinkEntryTest.cc\
|
||||
|
@ -156,8 +162,11 @@ am__aria2c_SOURCES_DIST = AllTest.cc Base64Test.cc SequenceTest.cc \
|
|||
PeerMessageUtilTest.cc ShareRatioSeedCriteriaTest.cc \
|
||||
BtRegistryTest.cc BtDependencyTest.cc \
|
||||
BtPostDownloadHandlerTest.cc DownloadHandlerFactoryTest.cc \
|
||||
TimeSeedCriteriaTest.cc MetalinkerTest.cc MetalinkEntryTest.cc \
|
||||
Metalink2RequestGroupTest.cc \
|
||||
TimeSeedCriteriaTest.cc BencodeVisitorTest.cc \
|
||||
BtExtendedMessageTest.cc HandshakeExtensionMessageTest.cc \
|
||||
UTPexExtensionMessageTest.cc DefaultBtMessageFactoryTest.cc \
|
||||
DefaultExtensionMessageFactoryTest.cc MetalinkerTest.cc \
|
||||
MetalinkEntryTest.cc Metalink2RequestGroupTest.cc \
|
||||
MetalinkPostDownloadHandlerTest.cc MetalinkHelperTest.cc \
|
||||
MetalinkParserControllerTest.cc MetalinkProcessorTest.cc
|
||||
@ENABLE_MESSAGE_DIGEST_TRUE@am__objects_1 = \
|
||||
|
@ -203,7 +212,13 @@ am__aria2c_SOURCES_DIST = AllTest.cc Base64Test.cc SequenceTest.cc \
|
|||
@ENABLE_BITTORRENT_TRUE@ BtDependencyTest.$(OBJEXT) \
|
||||
@ENABLE_BITTORRENT_TRUE@ BtPostDownloadHandlerTest.$(OBJEXT) \
|
||||
@ENABLE_BITTORRENT_TRUE@ DownloadHandlerFactoryTest.$(OBJEXT) \
|
||||
@ENABLE_BITTORRENT_TRUE@ TimeSeedCriteriaTest.$(OBJEXT)
|
||||
@ENABLE_BITTORRENT_TRUE@ TimeSeedCriteriaTest.$(OBJEXT) \
|
||||
@ENABLE_BITTORRENT_TRUE@ BencodeVisitorTest.$(OBJEXT) \
|
||||
@ENABLE_BITTORRENT_TRUE@ BtExtendedMessageTest.$(OBJEXT) \
|
||||
@ENABLE_BITTORRENT_TRUE@ HandshakeExtensionMessageTest.$(OBJEXT) \
|
||||
@ENABLE_BITTORRENT_TRUE@ UTPexExtensionMessageTest.$(OBJEXT) \
|
||||
@ENABLE_BITTORRENT_TRUE@ DefaultBtMessageFactoryTest.$(OBJEXT) \
|
||||
@ENABLE_BITTORRENT_TRUE@ DefaultExtensionMessageFactoryTest.$(OBJEXT)
|
||||
@ENABLE_METALINK_TRUE@am__objects_3 = MetalinkerTest.$(OBJEXT) \
|
||||
@ENABLE_METALINK_TRUE@ MetalinkEntryTest.$(OBJEXT) \
|
||||
@ENABLE_METALINK_TRUE@ Metalink2RequestGroupTest.$(OBJEXT) \
|
||||
|
@ -518,12 +533,14 @@ distclean-compile:
|
|||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AnnounceListTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AuthConfigFactoryTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Base64Test.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BencodeVisitorTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BitfieldManTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BtAllowedFastMessageTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BtBitfieldMessageTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BtCancelMessageTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BtChokeMessageTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BtDependencyTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BtExtendedMessageTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BtHandshakeMessageTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BtHaveAllMessageTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BtHaveMessageTest.Po@am__quote@
|
||||
|
@ -549,9 +566,11 @@ distclean-compile:
|
|||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultBtAnnounceTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultBtContextTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultBtMessageDispatcherTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultBtMessageFactoryTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultBtProgressInfoFileTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultBtRequestFactoryTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultDiskWriterTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultExtensionMessageFactoryTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultPeerListProcessorTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultPeerStorageTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultPieceStorageTest.Po@am__quote@
|
||||
|
@ -562,6 +581,7 @@ distclean-compile:
|
|||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FileTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FileUriListParserTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GrowSegmentTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HandshakeExtensionMessageTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HttpHeaderProcessorTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HttpHeaderTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HttpRequestTest.Po@am__quote@
|
||||
|
@ -604,6 +624,7 @@ distclean-compile:
|
|||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SpeedCalcTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/StreamUriListParserTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TimeSeedCriteriaTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UTPexExtensionMessageTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UtilTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/a2functionalTest.Po@am__quote@
|
||||
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
|
||||
#include "BtMessageFactory.h"
|
||||
|
||||
class ExtensionMessage;
|
||||
typedef SharedHandle<ExtensionMessage> ExensionMessageHandle;
|
||||
|
||||
class MockBtMessageFactory : public BtMessageFactory {
|
||||
public:
|
||||
MockBtMessageFactory() {}
|
||||
|
@ -84,6 +87,11 @@ public:
|
|||
virtual BtMessageHandle createAllowedFastMessage(int32_t index) {
|
||||
return BtMessageHandle(0);
|
||||
}
|
||||
|
||||
virtual BtMessageHandle createBtExtendedMessage(const ExensionMessageHandle&)
|
||||
{
|
||||
return BtMessageHandle(0);
|
||||
}
|
||||
};
|
||||
|
||||
typedef SharedHandle<MockBtMessageFactory> MockBtMessageFactoryHandle;
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
#ifndef _D_MOCK_EXTENSION_MESSAGE_H_
|
||||
#define _D_MOCK_EXTENSION_MESSAGE_H_
|
||||
|
||||
#include "ExtensionMessage.h"
|
||||
|
||||
class MockExtensionMessage:public ExtensionMessage {
|
||||
public:
|
||||
string _extensionName;
|
||||
uint8_t _extensionMessageID;
|
||||
string _data;
|
||||
bool _doReceivedActionCalled;
|
||||
public:
|
||||
MockExtensionMessage(const string& extensionName,
|
||||
uint8_t extensionMessageID,
|
||||
const char* data,
|
||||
size_t length):_extensionName(extensionName),
|
||||
_extensionMessageID(extensionMessageID),
|
||||
_data(&data[0], &data[length]),
|
||||
_doReceivedActionCalled(false) {}
|
||||
|
||||
virtual ~MockExtensionMessage() {}
|
||||
|
||||
virtual string getBencodedData()
|
||||
{
|
||||
return _data;
|
||||
}
|
||||
|
||||
virtual uint8_t getExtensionMessageID()
|
||||
{
|
||||
return _extensionMessageID;
|
||||
}
|
||||
|
||||
virtual const string& getExtensionName() const
|
||||
{
|
||||
return _extensionName;
|
||||
}
|
||||
|
||||
virtual string toString() const
|
||||
{
|
||||
return _extensionName;
|
||||
}
|
||||
|
||||
virtual void doReceivedAction()
|
||||
{
|
||||
_doReceivedActionCalled = true;
|
||||
}
|
||||
};
|
||||
|
||||
typedef SharedHandle<MockExtensionMessage> MockExtensionMessageHandle;
|
||||
|
||||
#endif // _D_MOCK_EXTENSION_MESSAGE_H_
|
|
@ -0,0 +1,20 @@
|
|||
#ifndef _D_MOCK_EXTENSION_MESSAGE_FACTORY_H_
|
||||
#define _D_MOCK_EXTENSION_MESSAGE_FACTORY_H_
|
||||
|
||||
#include "ExtensionMessageFactory.h"
|
||||
#include "MockExtensionMessage.h"
|
||||
|
||||
class MockExtensionMessageFactory:public ExtensionMessageFactory {
|
||||
public:
|
||||
virtual ~MockExtensionMessageFactory() {}
|
||||
|
||||
virtual ExtensionMessageHandle createMessage(const char* data,
|
||||
size_t length)
|
||||
{
|
||||
return new MockExtensionMessage("a2_mock", *data, data+1, length-1);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
typedef SharedHandle<MockExtensionMessageFactory> MockExtensionMessageFactoryHandle;
|
||||
#endif // _D_MOCK_EXTENSION_MESSAGE_FACTORY_H_
|
|
@ -51,12 +51,13 @@ void ShaVisitorTest::testVisit() {
|
|||
|
||||
void ShaVisitorTest::testVisitCompound() {
|
||||
ShaVisitor v;
|
||||
MetaEntry* e = MetaFileUtil::parseMetaFile("test.torrent");
|
||||
string data = "d4:name5:aria24:listli123eee";
|
||||
MetaEntry* e = MetaFileUtil::bdecoding(data.c_str(), data.size());
|
||||
e->accept(&v);
|
||||
unsigned char md[20];
|
||||
int len = 0;
|
||||
v.getHash(md, len);
|
||||
string hashHex = hexHash(md, len);
|
||||
CPPUNIT_ASSERT_EQUAL(string("5a2bf55fb6ec71a9cd3e06537aa7795cafccffab"),
|
||||
CPPUNIT_ASSERT_EQUAL(string("75538fbac9a074bb98c6a19b6bca3bc87ef9bf8e"),
|
||||
hashHex);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,187 @@
|
|||
#include "UTPexExtensionMessage.h"
|
||||
#include "Peer.h"
|
||||
#include "a2netcompat.h"
|
||||
#include "Util.h"
|
||||
#include "PeerMessageUtil.h"
|
||||
#include "BtRegistry.h"
|
||||
#include "MockBtContext.h"
|
||||
#include "MockPeerStorage.h"
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
|
||||
class UTPexExtensionMessageTest:public CppUnit::TestFixture {
|
||||
|
||||
CPPUNIT_TEST_SUITE(UTPexExtensionMessageTest);
|
||||
CPPUNIT_TEST(testGetExtensionMessageID);
|
||||
CPPUNIT_TEST(testGetExtensionName);
|
||||
CPPUNIT_TEST(testGetBencodedData);
|
||||
CPPUNIT_TEST(testToString);
|
||||
CPPUNIT_TEST(testDoReceivedAction);
|
||||
CPPUNIT_TEST(testCreate);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
private:
|
||||
MockBtContextHandle _btContext;
|
||||
public:
|
||||
UTPexExtensionMessageTest():_btContext(0) {}
|
||||
|
||||
void setUp()
|
||||
{
|
||||
BtRegistry::unregisterAll();
|
||||
MockBtContextHandle btContext = new MockBtContext();
|
||||
unsigned char infohash[20];
|
||||
memset(infohash, 0, sizeof(infohash));
|
||||
btContext->setInfoHash(infohash);
|
||||
_btContext = btContext;
|
||||
MockPeerStorageHandle peerStorage = new MockPeerStorage();
|
||||
BtRegistry::registerPeerStorage(_btContext->getInfoHashAsString(),
|
||||
peerStorage);
|
||||
}
|
||||
|
||||
void tearDown()
|
||||
{
|
||||
BtRegistry::unregisterAll();
|
||||
}
|
||||
|
||||
void testGetExtensionMessageID();
|
||||
void testGetExtensionName();
|
||||
void testGetBencodedData();
|
||||
void testToString();
|
||||
void testDoReceivedAction();
|
||||
void testCreate();
|
||||
};
|
||||
|
||||
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION(UTPexExtensionMessageTest);
|
||||
|
||||
void UTPexExtensionMessageTest::testGetExtensionMessageID()
|
||||
{
|
||||
UTPexExtensionMessage msg(1);
|
||||
CPPUNIT_ASSERT_EQUAL((uint8_t)1, msg.getExtensionMessageID());
|
||||
}
|
||||
|
||||
void UTPexExtensionMessageTest::testGetExtensionName()
|
||||
{
|
||||
UTPexExtensionMessage msg(1);
|
||||
CPPUNIT_ASSERT_EQUAL(string("ut_pex"), msg.getExtensionName());
|
||||
}
|
||||
|
||||
void UTPexExtensionMessageTest::testGetBencodedData()
|
||||
{
|
||||
UTPexExtensionMessage msg(1);
|
||||
PeerHandle p1 = new Peer("192.168.0.1", 6881, 1, 1);
|
||||
p1->setAllBitfield();
|
||||
msg.addFreshPeer(p1);// added seeder, check add.f flag
|
||||
PeerHandle p2 = new Peer("10.1.1.2", 9999, 1, 1);
|
||||
msg.addFreshPeer(p2);
|
||||
PeerHandle p3 = new Peer("192.168.0.2", 6882, 1, 1);
|
||||
msg.addDroppedPeer(p3);
|
||||
PeerHandle p4 = new Peer("10.1.1.3", 10000, 1, 1);
|
||||
msg.addDroppedPeer(p4);
|
||||
|
||||
char c1[6];
|
||||
char c2[6];
|
||||
char c3[6];
|
||||
char c4[6];
|
||||
PeerMessageUtil::createcompact(c1, p1->ipaddr, p1->port);
|
||||
PeerMessageUtil::createcompact(c2, p2->ipaddr, p2->port);
|
||||
PeerMessageUtil::createcompact(c3, p3->ipaddr, p3->port);
|
||||
PeerMessageUtil::createcompact(c4, p4->ipaddr, p4->port);
|
||||
|
||||
string expected = "d5:added12:"+
|
||||
string(&c1[0], &c1[6])+string(&c2[0], &c2[6])+
|
||||
"7:added.f2:207:dropped12:"+
|
||||
string(&c3[0], &c3[6])+string(&c4[0], &c4[6])+
|
||||
"e";
|
||||
string bd = msg.getBencodedData();
|
||||
CPPUNIT_ASSERT_EQUAL(Util::urlencode(expected),
|
||||
Util::urlencode(bd));
|
||||
}
|
||||
|
||||
void UTPexExtensionMessageTest::testToString()
|
||||
{
|
||||
UTPexExtensionMessage msg(1);
|
||||
PeerHandle p1 = new Peer("192.168.0.1", 6881, 1, 1);
|
||||
p1->setAllBitfield();
|
||||
msg.addFreshPeer(p1);// added seeder, check add.f flag
|
||||
PeerHandle p2 = new Peer("10.1.1.2", 9999, 1, 1);
|
||||
msg.addFreshPeer(p2);
|
||||
PeerHandle p3 = new Peer("192.168.0.2", 6882, 1, 1);
|
||||
msg.addDroppedPeer(p3);
|
||||
PeerHandle p4 = new Peer("10.1.1.3", 10000, 1, 1);
|
||||
msg.addDroppedPeer(p4);
|
||||
CPPUNIT_ASSERT_EQUAL(string("ut_pex added=2, dropped=2"), msg.toString());
|
||||
}
|
||||
|
||||
void UTPexExtensionMessageTest::testDoReceivedAction()
|
||||
{
|
||||
UTPexExtensionMessage msg(1);
|
||||
PeerHandle p1 = new Peer("192.168.0.1", 6881, 1, 1);
|
||||
p1->setAllBitfield();
|
||||
msg.addFreshPeer(p1);// added seeder, check add.f flag
|
||||
PeerHandle p2 = new Peer("10.1.1.2", 9999, 1, 1);
|
||||
msg.addFreshPeer(p2);
|
||||
PeerHandle p3 = new Peer("192.168.0.2", 6882, 1, 1);
|
||||
msg.addDroppedPeer(p3);
|
||||
PeerHandle p4 = new Peer("10.1.1.3", 10000, 1, 1);
|
||||
msg.addDroppedPeer(p4);
|
||||
msg.setBtContext(_btContext);
|
||||
|
||||
msg.doReceivedAction();
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL((size_t)2, PEER_STORAGE(_btContext)->getPeers().size());
|
||||
{
|
||||
PeerHandle p = PEER_STORAGE(_btContext)->getPeers()[0];
|
||||
CPPUNIT_ASSERT_EQUAL(string("192.168.0.1"), p->ipaddr);
|
||||
CPPUNIT_ASSERT_EQUAL((uint16_t)6881, p->port);
|
||||
}
|
||||
{
|
||||
PeerHandle p = PEER_STORAGE(_btContext)->getPeers()[1];
|
||||
CPPUNIT_ASSERT_EQUAL(string("10.1.1.2"), p->ipaddr);
|
||||
CPPUNIT_ASSERT_EQUAL((uint16_t)9999, p->port);
|
||||
}
|
||||
}
|
||||
|
||||
void UTPexExtensionMessageTest::testCreate()
|
||||
{
|
||||
_btContext->setPieceLength(256*1024);
|
||||
_btContext->setTotalLength(1024*1024);
|
||||
|
||||
char c1[6];
|
||||
char c2[6];
|
||||
char c3[6];
|
||||
char c4[6];
|
||||
PeerMessageUtil::createcompact(c1, "192.168.0.1", 6881);
|
||||
PeerMessageUtil::createcompact(c2, "10.1.1.2", 9999);
|
||||
PeerMessageUtil::createcompact(c3, "192.168.0.2", 6882);
|
||||
PeerMessageUtil::createcompact(c4, "10.1.1.3",10000);
|
||||
|
||||
char id[1] = { 1 };
|
||||
|
||||
string data = string(&id[0], &id[1])+"d5:added12:"+
|
||||
string(&c1[0], &c1[6])+string(&c2[0], &c2[6])+
|
||||
"7:added.f2:207:dropped12:"+
|
||||
string(&c3[0], &c3[6])+string(&c4[0], &c4[6])+
|
||||
"e";
|
||||
|
||||
UTPexExtensionMessageHandle msg =
|
||||
UTPexExtensionMessage::create(_btContext, data.c_str(), data.size());
|
||||
CPPUNIT_ASSERT_EQUAL((uint8_t)1, msg->getExtensionMessageID());
|
||||
CPPUNIT_ASSERT_EQUAL((size_t)2, msg->getFreshPeers().size());
|
||||
CPPUNIT_ASSERT_EQUAL(string("192.168.0.1"), msg->getFreshPeers()[0]->ipaddr);
|
||||
CPPUNIT_ASSERT_EQUAL((uint16_t)6881, msg->getFreshPeers()[0]->port);
|
||||
CPPUNIT_ASSERT_EQUAL(string("10.1.1.2"), msg->getFreshPeers()[1]->ipaddr);
|
||||
CPPUNIT_ASSERT_EQUAL((uint16_t)9999, msg->getFreshPeers()[1]->port);
|
||||
CPPUNIT_ASSERT_EQUAL((size_t)2, msg->getDroppedPeers().size());
|
||||
CPPUNIT_ASSERT_EQUAL(string("192.168.0.2"), msg->getDroppedPeers()[0]->ipaddr);
|
||||
CPPUNIT_ASSERT_EQUAL((uint16_t)6882, msg->getDroppedPeers()[0]->port);
|
||||
CPPUNIT_ASSERT_EQUAL(string("10.1.1.3"), msg->getDroppedPeers()[1]->ipaddr);
|
||||
CPPUNIT_ASSERT_EQUAL((uint16_t)10000, msg->getDroppedPeers()[1]->port);
|
||||
try {
|
||||
// 0 length data
|
||||
string in = "";
|
||||
UTPexExtensionMessage::create(_btContext, in.c_str(), in.size());
|
||||
CPPUNIT_FAIL("exception must be thrown.");
|
||||
} catch(Exception* e) {
|
||||
cerr << *e << endl;
|
||||
delete e;
|
||||
}
|
||||
}
|
|
@ -1 +1 @@
|
|||
d8:announce36:http://aria.rednoah.com/announce.php13:announce-listll16:http://tracker1 el15:http://tracker2el15:http://tracker3ee7:comment17:REDNOAH.COM RULES13:creation datei1123456789e4:infod5:filesld6:lengthi284e4:pathl5:aria23:src6:aria2ceed6:lengthi100e4:pathl19:aria2-0.2.2.tar.bz2eee4:name10:aria2-test12:piece lengthi128e6:pieces60:AAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCee
|
||||
d8:announce36:http://aria.rednoah.com/announce.php13:announce-listll16:http://tracker1 el15:http://tracker2el15:http://tracker3ee7:privatei1e7:comment17:REDNOAH.COM RULES13:creation datei1123456789e4:infod5:filesld6:lengthi284e4:pathl5:aria23:src6:aria2ceed6:lengthi100e4:pathl19:aria2-0.2.2.tar.bz2eee4:name10:aria2-test12:piece lengthi128e6:pieces60:AAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCee
|
Loading…
Reference in New Issue