mirror of https://github.com/aria2/aria2
2010-02-20 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Added Local Peer Discovery. It is disabled by default. Use --bt-enable-lpd to enable the function. * src/BtConstants.h * src/BtSetup.cc * src/LpdDispatchMessageCommand.cc * src/LpdDispatchMessageCommand.h * src/LpdMessage.h * src/LpdMessageDispatcher.cc * src/LpdMessageDispatcher.h * src/LpdMessageReceiver.cc * src/LpdMessageReceiver.h * src/LpdReceiveMessageCommand.cc * src/LpdReceiveMessageCommand.h * src/Makefile.am * src/OptionHandlerFactory.cc * src/Peer.cc * src/Peer.h * src/PeerInteractionCommand.cc * src/SocketCore.cc * src/SocketCore.h * src/prefs.cc * src/prefs.h * src/usage_text.h * src/util.cc * src/util.h * test/LpdMessageDispatcherTest.cc * test/LpdMessageReceiverTest.cc * test/Makefile.ampull/1/head
parent
aee471e52c
commit
9281f11264
31
ChangeLog
31
ChangeLog
|
@ -1,3 +1,34 @@
|
||||||
|
2010-02-20 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
|
||||||
|
|
||||||
|
Added Local Peer Discovery. It is disabled by default. Use
|
||||||
|
--bt-enable-lpd to enable the function.
|
||||||
|
* src/BtConstants.h
|
||||||
|
* src/BtSetup.cc
|
||||||
|
* src/LpdDispatchMessageCommand.cc
|
||||||
|
* src/LpdDispatchMessageCommand.h
|
||||||
|
* src/LpdMessage.h
|
||||||
|
* src/LpdMessageDispatcher.cc
|
||||||
|
* src/LpdMessageDispatcher.h
|
||||||
|
* src/LpdMessageReceiver.cc
|
||||||
|
* src/LpdMessageReceiver.h
|
||||||
|
* src/LpdReceiveMessageCommand.cc
|
||||||
|
* src/LpdReceiveMessageCommand.h
|
||||||
|
* src/Makefile.am
|
||||||
|
* src/OptionHandlerFactory.cc
|
||||||
|
* src/Peer.cc
|
||||||
|
* src/Peer.h
|
||||||
|
* src/PeerInteractionCommand.cc
|
||||||
|
* src/SocketCore.cc
|
||||||
|
* src/SocketCore.h
|
||||||
|
* src/prefs.cc
|
||||||
|
* src/prefs.h
|
||||||
|
* src/usage_text.h
|
||||||
|
* src/util.cc
|
||||||
|
* src/util.h
|
||||||
|
* test/LpdMessageDispatcherTest.cc
|
||||||
|
* test/LpdMessageReceiverTest.cc
|
||||||
|
* test/Makefile.am
|
||||||
|
|
||||||
2010-02-20 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
|
2010-02-20 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
|
||||||
|
|
||||||
User-defined custom request headers specified by --header option
|
User-defined custom request headers specified by --header option
|
||||||
|
|
|
@ -58,4 +58,8 @@ typedef std::map<std::string, uint8_t> Extensions;
|
||||||
|
|
||||||
#define METADATA_PIECE_SIZE (16*1024)
|
#define METADATA_PIECE_SIZE (16*1024)
|
||||||
|
|
||||||
|
#define LPD_MULTICAST_ADDR "239.192.152.143"
|
||||||
|
|
||||||
|
#define LPD_MULTICAST_PORT 6771
|
||||||
|
|
||||||
#endif // _D_BT_CONSTANTS_
|
#endif // _D_BT_CONSTANTS_
|
||||||
|
|
|
@ -60,6 +60,12 @@
|
||||||
#include "BtRuntime.h"
|
#include "BtRuntime.h"
|
||||||
#include "bittorrent_helper.h"
|
#include "bittorrent_helper.h"
|
||||||
#include "BtStopDownloadCommand.h"
|
#include "BtStopDownloadCommand.h"
|
||||||
|
#include "LpdReceiveMessageCommand.h"
|
||||||
|
#include "LpdDispatchMessageCommand.h"
|
||||||
|
#include "LpdMessageReceiver.h"
|
||||||
|
#include "LpdMessageDispatcher.h"
|
||||||
|
#include "message.h"
|
||||||
|
#include "SocketCore.h"
|
||||||
|
|
||||||
namespace aria2 {
|
namespace aria2 {
|
||||||
|
|
||||||
|
@ -164,6 +170,39 @@ void BtSetup::setup(std::deque<Command*>& commands,
|
||||||
PeerListenCommand* listenCommand = PeerListenCommand::getInstance(e);
|
PeerListenCommand* listenCommand = PeerListenCommand::getInstance(e);
|
||||||
btRuntime->setListenPort(listenCommand->getPort());
|
btRuntime->setListenPort(listenCommand->getPort());
|
||||||
}
|
}
|
||||||
|
if(option->getAsBool(PREF_BT_ENABLE_LPD) &&
|
||||||
|
(metadataGetMode || torrentAttrs[bittorrent::PRIVATE].i() == 0)) {
|
||||||
|
if(LpdReceiveMessageCommand::getNumInstance() == 0) {
|
||||||
|
SharedHandle<LpdMessageReceiver> receiver
|
||||||
|
(new LpdMessageReceiver(LPD_MULTICAST_ADDR, LPD_MULTICAST_PORT));
|
||||||
|
try {
|
||||||
|
receiver->init();
|
||||||
|
receiver->getSocket()->setMulticastTtl(1);
|
||||||
|
} catch(RecoverableException& e) {
|
||||||
|
_logger->info(EX_EXCEPTION_CAUGHT, e);
|
||||||
|
receiver.reset();
|
||||||
|
}
|
||||||
|
if(!receiver.isNull()) {
|
||||||
|
LpdReceiveMessageCommand* cmd =
|
||||||
|
LpdReceiveMessageCommand::getInstance(e, receiver);
|
||||||
|
e->commands.push_back(cmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(LpdReceiveMessageCommand::getNumInstance()) {
|
||||||
|
const unsigned char* infoHash =
|
||||||
|
bittorrent::getInfoHash(requestGroup->getDownloadContext());
|
||||||
|
SharedHandle<LpdMessageDispatcher> dispatcher
|
||||||
|
(new LpdMessageDispatcher
|
||||||
|
(std::string(&infoHash[0], &infoHash[INFO_HASH_LENGTH]),
|
||||||
|
btRuntime->getListenPort(),
|
||||||
|
LPD_MULTICAST_ADDR, LPD_MULTICAST_PORT,
|
||||||
|
LpdReceiveMessageCommand::getInstance()->getReceiverSocket()));
|
||||||
|
LpdDispatchMessageCommand* cmd =
|
||||||
|
new LpdDispatchMessageCommand(e->newCUID(), dispatcher, e);
|
||||||
|
cmd->setBtRuntime(btRuntime);
|
||||||
|
e->commands.push_back(cmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
time_t btStopTimeout = option->getAsInt(PREF_BT_STOP_TIMEOUT);
|
time_t btStopTimeout = option->getAsInt(PREF_BT_STOP_TIMEOUT);
|
||||||
if(btStopTimeout > 0) {
|
if(btStopTimeout > 0) {
|
||||||
BtStopDownloadCommand* stopDownloadCommand =
|
BtStopDownloadCommand* stopDownloadCommand =
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
/* <!-- copyright */
|
||||||
|
/*
|
||||||
|
* aria2 - The high speed download utility
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 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 "LpdDispatchMessageCommand.h"
|
||||||
|
#include "LpdMessageDispatcher.h"
|
||||||
|
#include "DownloadEngine.h"
|
||||||
|
#include "BtRuntime.h"
|
||||||
|
#include "Logger.h"
|
||||||
|
#include "RecoverableException.h"
|
||||||
|
#include "SocketCore.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
namespace aria2 {
|
||||||
|
|
||||||
|
LpdDispatchMessageCommand::LpdDispatchMessageCommand
|
||||||
|
(int cuid,
|
||||||
|
const SharedHandle<LpdMessageDispatcher>& dispatcher,
|
||||||
|
DownloadEngine* e):
|
||||||
|
Command(cuid),
|
||||||
|
_dispatcher(dispatcher),
|
||||||
|
_e(e),
|
||||||
|
_tryCount(0) {}
|
||||||
|
|
||||||
|
bool LpdDispatchMessageCommand::execute()
|
||||||
|
{
|
||||||
|
if(_btRuntime->isHalt()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(_dispatcher->isAnnounceReady()) {
|
||||||
|
try {
|
||||||
|
logger->info("Dispatching LPD message for infohash=%s",
|
||||||
|
util::toHex(_dispatcher->getInfoHash()).c_str());
|
||||||
|
if(_dispatcher->sendMessage()) {
|
||||||
|
logger->info("Sending LPD message is complete.");
|
||||||
|
_dispatcher->resetAnnounceTimer();
|
||||||
|
_tryCount = 0;
|
||||||
|
} else {
|
||||||
|
++_tryCount;
|
||||||
|
if(_tryCount >= 5) {
|
||||||
|
logger->info("Sending LPD message %u times but all failed.");
|
||||||
|
_dispatcher->resetAnnounceTimer();
|
||||||
|
_tryCount = 0;
|
||||||
|
} else {
|
||||||
|
logger->info("Could not send LPD message, retry shortly.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch(RecoverableException& e) {
|
||||||
|
logger->info("Failed to send LPD message.", e);
|
||||||
|
_dispatcher->resetAnnounceTimer();
|
||||||
|
_tryCount = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_e->commands.push_back(this);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace aria2
|
|
@ -0,0 +1,69 @@
|
||||||
|
/* <!-- copyright */
|
||||||
|
/*
|
||||||
|
* aria2 - The high speed download utility
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 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_LPD_DISPATCH_MESSAGE_COMMAND_H_
|
||||||
|
#define _D_LPD_DISPATCH_MESSAGE_COMMAND_H_
|
||||||
|
|
||||||
|
#include "Command.h"
|
||||||
|
#include "SharedHandle.h"
|
||||||
|
|
||||||
|
namespace aria2 {
|
||||||
|
|
||||||
|
class LpdMessageDispatcher;
|
||||||
|
class DownloadEngine;
|
||||||
|
class BtRuntime;
|
||||||
|
|
||||||
|
class LpdDispatchMessageCommand:public Command {
|
||||||
|
private:
|
||||||
|
SharedHandle<LpdMessageDispatcher> _dispatcher;
|
||||||
|
DownloadEngine* _e;
|
||||||
|
unsigned int _tryCount;
|
||||||
|
SharedHandle<BtRuntime> _btRuntime;
|
||||||
|
public:
|
||||||
|
LpdDispatchMessageCommand
|
||||||
|
(int cuid,
|
||||||
|
const SharedHandle<LpdMessageDispatcher>& dispatcher,
|
||||||
|
DownloadEngine* e);
|
||||||
|
|
||||||
|
virtual bool execute();
|
||||||
|
|
||||||
|
void setBtRuntime(const SharedHandle<BtRuntime>& btRuntime)
|
||||||
|
{
|
||||||
|
_btRuntime = btRuntime;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace aria2
|
||||||
|
|
||||||
|
#endif // _D_LPD_DISPATCH_MESSAGE_COMMAND_H_
|
|
@ -0,0 +1,65 @@
|
||||||
|
/*
|
||||||
|
* aria2 - The high speed download utility
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 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.
|
||||||
|
*/
|
||||||
|
#ifndef _D_LPD_MESSAGE_H_
|
||||||
|
#define _D_LPD_MESSAGE_H_
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "Peer.h"
|
||||||
|
|
||||||
|
namespace aria2 {
|
||||||
|
|
||||||
|
class LpdMessage {
|
||||||
|
private:
|
||||||
|
SharedHandle<Peer> _peer;
|
||||||
|
std::string _infoHash;
|
||||||
|
public:
|
||||||
|
LpdMessage(const SharedHandle<Peer>& peer, const std::string& infoHash):
|
||||||
|
_peer(peer), _infoHash(infoHash) {}
|
||||||
|
|
||||||
|
const SharedHandle<Peer>& getPeer() const
|
||||||
|
{
|
||||||
|
return _peer;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& getInfoHash() const
|
||||||
|
{
|
||||||
|
return _infoHash;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace aria2
|
||||||
|
|
||||||
|
#endif // _D_LPD_MESSAGE_H_
|
|
@ -0,0 +1,95 @@
|
||||||
|
/*
|
||||||
|
* aria2 - The high speed download utility
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 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.
|
||||||
|
*/
|
||||||
|
#include "LpdMessageDispatcher.h"
|
||||||
|
#include "SocketCore.h"
|
||||||
|
#include "A2STR.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "Logger.h"
|
||||||
|
#include "LogFactory.h"
|
||||||
|
#include "BtConstants.h"
|
||||||
|
#include "RecoverableException.h"
|
||||||
|
|
||||||
|
namespace aria2 {
|
||||||
|
|
||||||
|
LpdMessageDispatcher::LpdMessageDispatcher
|
||||||
|
(const std::string& infoHash, uint16_t port,
|
||||||
|
const std::string& multicastAddress, uint16_t multicastPort,
|
||||||
|
const SharedHandle<SocketCore>& socket,
|
||||||
|
time_t interval):
|
||||||
|
_infoHash(infoHash),
|
||||||
|
_port(port),
|
||||||
|
_socket(socket),
|
||||||
|
_multicastAddress(multicastAddress),
|
||||||
|
_multicastPort(multicastPort),
|
||||||
|
_timer(0),
|
||||||
|
_interval(interval),
|
||||||
|
_request(bittorrent::createLpdRequest(_multicastAddress, _multicastPort,
|
||||||
|
_infoHash, _port)),
|
||||||
|
_logger(LogFactory::getInstance()) {}
|
||||||
|
|
||||||
|
bool LpdMessageDispatcher::sendMessage()
|
||||||
|
{
|
||||||
|
return
|
||||||
|
_socket->writeData(_request.c_str(), _request.size(),
|
||||||
|
_multicastAddress, _multicastPort)
|
||||||
|
== (ssize_t)_request.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LpdMessageDispatcher::isAnnounceReady() const
|
||||||
|
{
|
||||||
|
return _timer.elapsed(_interval);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LpdMessageDispatcher::resetAnnounceTimer()
|
||||||
|
{
|
||||||
|
_timer.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace bittorrent {
|
||||||
|
|
||||||
|
std::string createLpdRequest
|
||||||
|
(const std::string& multicastAddress, uint16_t multicastPort,
|
||||||
|
const std::string& infoHash, uint16_t port)
|
||||||
|
{
|
||||||
|
std::string req = "BT-SEARCH * HTTP/1.1\r\n";
|
||||||
|
strappend(req, "Host: ", multicastAddress, A2STR::COLON_C,
|
||||||
|
util::uitos(multicastPort), A2STR::CRLF);
|
||||||
|
strappend(req, "Port: ", util::uitos(port), A2STR::CRLF);
|
||||||
|
strappend(req, "Infohash: ", util::toHex(infoHash), A2STR::CRLF);
|
||||||
|
req += "\r\n\r\n";
|
||||||
|
return req;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace bittorrent
|
||||||
|
|
||||||
|
} // namespac aria2
|
|
@ -0,0 +1,98 @@
|
||||||
|
/*
|
||||||
|
* aria2 - The high speed download utility
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 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.
|
||||||
|
*/
|
||||||
|
#ifndef _D_LPD_MESSAGE_DISPATCHER_H_
|
||||||
|
#define _D_LPD_MESSAGE_DISPATCHER_H_
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "SharedHandle.h"
|
||||||
|
#include "TimeA2.h"
|
||||||
|
|
||||||
|
namespace aria2 {
|
||||||
|
|
||||||
|
class SocketCore;
|
||||||
|
class Logger;
|
||||||
|
|
||||||
|
class LpdMessageDispatcher {
|
||||||
|
private:
|
||||||
|
std::string _infoHash;
|
||||||
|
uint16_t _port;
|
||||||
|
SharedHandle<SocketCore> _socket;
|
||||||
|
std::string _multicastAddress;
|
||||||
|
uint16_t _multicastPort;
|
||||||
|
Time _timer;
|
||||||
|
time_t _interval;
|
||||||
|
std::string _request;
|
||||||
|
Logger* _logger;
|
||||||
|
public:
|
||||||
|
LpdMessageDispatcher
|
||||||
|
(const std::string& infoHash, uint16_t port,
|
||||||
|
const std::string& multicastAddr, uint16_t multicastPort,
|
||||||
|
const SharedHandle<SocketCore>& socket,
|
||||||
|
time_t interval = 5*60);
|
||||||
|
|
||||||
|
// Returns true if _timer reached announce interval, which is by
|
||||||
|
// default 5mins.
|
||||||
|
bool isAnnounceReady() const;
|
||||||
|
|
||||||
|
// Sends LPD message. If message is sent returns true. Otherwise
|
||||||
|
// returns false.
|
||||||
|
bool sendMessage();
|
||||||
|
|
||||||
|
// Reset _timer to the current time.
|
||||||
|
void resetAnnounceTimer();
|
||||||
|
|
||||||
|
const std::string& getInfoHash() const
|
||||||
|
{
|
||||||
|
return _infoHash;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t getPort() const
|
||||||
|
{
|
||||||
|
return _port;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace bittorrent {
|
||||||
|
|
||||||
|
std::string createLpdRequest
|
||||||
|
(const std::string& multicastAddress, uint16_t multicastPort,
|
||||||
|
const std::string& infoHash, uint16_t port);
|
||||||
|
|
||||||
|
} // namespace bittorrent
|
||||||
|
|
||||||
|
} // namespace aria2
|
||||||
|
|
||||||
|
#endif // _D_LPD_MESSAGE_DISPATCHER_H_
|
|
@ -0,0 +1,107 @@
|
||||||
|
/*
|
||||||
|
* aria2 - The high speed download utility
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 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.
|
||||||
|
*/
|
||||||
|
#include "LpdMessageReceiver.h"
|
||||||
|
#include "SocketCore.h"
|
||||||
|
#include "Logger.h"
|
||||||
|
#include "LogFactory.h"
|
||||||
|
#include "HttpHeaderProcessor.h"
|
||||||
|
#include "HttpHeader.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "LpdMessage.h"
|
||||||
|
#include "RecoverableException.h"
|
||||||
|
|
||||||
|
namespace aria2 {
|
||||||
|
|
||||||
|
LpdMessageReceiver::LpdMessageReceiver
|
||||||
|
(const std::string& multicastAddress, uint16_t multicastPort):
|
||||||
|
_multicastAddress(multicastAddress),
|
||||||
|
_multicastPort(multicastPort),
|
||||||
|
_logger(LogFactory::getInstance()) {}
|
||||||
|
|
||||||
|
bool LpdMessageReceiver::init()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
_socket.reset(new SocketCore(SOCK_DGRAM));
|
||||||
|
// SocketCore::bind(port, flags) cannot be used here, because it
|
||||||
|
// is affected by --interface option.
|
||||||
|
_socket->bindWithFamily(_multicastPort, AF_INET);
|
||||||
|
_socket->joinMulticastGroup(_multicastAddress, _multicastPort);
|
||||||
|
_socket->setNonBlockingMode();
|
||||||
|
_logger->info("Listening multicast group (%s:%u) packet",
|
||||||
|
_multicastAddress.c_str(), _multicastPort);
|
||||||
|
return true;
|
||||||
|
} catch(RecoverableException& e) {
|
||||||
|
_logger->error("Failed to initialize LPD message receiver.", e);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SharedHandle<LpdMessage> LpdMessageReceiver::receiveMessage()
|
||||||
|
{
|
||||||
|
SharedHandle<LpdMessage> msg;
|
||||||
|
try {
|
||||||
|
unsigned char buf[200];
|
||||||
|
std::pair<std::string, uint16_t> peerAddr;
|
||||||
|
ssize_t length = _socket->readDataFrom(buf, sizeof(buf), peerAddr);
|
||||||
|
if(length == 0) {
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
HttpHeaderProcessor proc;
|
||||||
|
proc.update(buf, length);
|
||||||
|
if(!proc.eoh()) {
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
SharedHandle<HttpHeader> header = proc.getHttpRequestHeader();
|
||||||
|
std::string infoHashString = header->getFirst("Infohash");
|
||||||
|
uint16_t port = header->getFirstAsUInt("Port");
|
||||||
|
_logger->info("LPD message received infohash=%s, port=%u from %s",
|
||||||
|
infoHashString.c_str(), port, peerAddr.first.c_str());
|
||||||
|
std::string infoHash;
|
||||||
|
if(infoHashString.size() != 40 ||
|
||||||
|
(infoHash = util::fromHex(infoHashString)).empty() ||
|
||||||
|
port == 0) {
|
||||||
|
_logger->info("LPD bad request. infohash=%s", infoHashString.c_str());
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
SharedHandle<Peer> peer(new Peer(peerAddr.first, port, false));
|
||||||
|
if(util::inPrivateAddress(peerAddr.first)) {
|
||||||
|
peer->setLocalPeer(true);
|
||||||
|
}
|
||||||
|
msg.reset(new LpdMessage(peer, infoHash));
|
||||||
|
} catch(RecoverableException& e) {
|
||||||
|
_logger->info("Failed to receive LPD message.", e);
|
||||||
|
}
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace aria2
|
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
* aria2 - The high speed download utility
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 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.
|
||||||
|
*/
|
||||||
|
#ifndef _LPD_MESSAGE_RECEIVER_H_
|
||||||
|
#define _LPD_MESSAGE_RECEIVER_H_
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "SharedHandle.h"
|
||||||
|
|
||||||
|
namespace aria2 {
|
||||||
|
|
||||||
|
class SocketCore;
|
||||||
|
class Logger;
|
||||||
|
class LpdMessage;
|
||||||
|
|
||||||
|
class LpdMessageReceiver {
|
||||||
|
private:
|
||||||
|
SharedHandle<SocketCore> _socket;
|
||||||
|
std::string _multicastAddress;
|
||||||
|
uint16_t _multicastPort;
|
||||||
|
Logger* _logger;
|
||||||
|
public:
|
||||||
|
// Currently only IPv4 multicastAddresses are supported.
|
||||||
|
LpdMessageReceiver
|
||||||
|
(const std::string& multicastAddress, uint16_t multicastPort);
|
||||||
|
|
||||||
|
// No throw.
|
||||||
|
bool init();
|
||||||
|
|
||||||
|
// Receives LPD message and process it. Returns false if message is
|
||||||
|
// not available.
|
||||||
|
SharedHandle<LpdMessage> receiveMessage();
|
||||||
|
|
||||||
|
SharedHandle<SocketCore> getSocket() const
|
||||||
|
{
|
||||||
|
return _socket;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace aria2
|
||||||
|
|
||||||
|
#endif // _LPD_MESSAGE_RECEIVER_H_
|
|
@ -0,0 +1,154 @@
|
||||||
|
/* <!-- copyright */
|
||||||
|
/*
|
||||||
|
* aria2 - The high speed download utility
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 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 "LpdReceiveMessageCommand.h"
|
||||||
|
#include "DownloadEngine.h"
|
||||||
|
#include "SocketCore.h"
|
||||||
|
#include "LpdMessageReceiver.h"
|
||||||
|
#include "RequestGroupMan.h"
|
||||||
|
#include "DownloadContext.h"
|
||||||
|
#include "PeerStorage.h"
|
||||||
|
#include "Peer.h"
|
||||||
|
#include "RequestGroup.h"
|
||||||
|
#include "BtRegistry.h"
|
||||||
|
#include "Logger.h"
|
||||||
|
#include "PieceStorage.h"
|
||||||
|
#include "BtRuntime.h"
|
||||||
|
#include "BtProgressInfoFile.h"
|
||||||
|
#include "BtAnnounce.h"
|
||||||
|
#include "LpdMessage.h"
|
||||||
|
#include "bittorrent_helper.h"
|
||||||
|
|
||||||
|
namespace aria2 {
|
||||||
|
|
||||||
|
unsigned int LpdReceiveMessageCommand::__numInstance = 0;
|
||||||
|
|
||||||
|
LpdReceiveMessageCommand* LpdReceiveMessageCommand::__instance = 0;
|
||||||
|
|
||||||
|
LpdReceiveMessageCommand::LpdReceiveMessageCommand
|
||||||
|
(int32_t cuid, const SharedHandle<LpdMessageReceiver>& receiver,
|
||||||
|
DownloadEngine* e):Command(cuid), _receiver(receiver), _e(e)
|
||||||
|
{
|
||||||
|
_e->addSocketForReadCheck(_receiver->getSocket(), this);
|
||||||
|
++__numInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
LpdReceiveMessageCommand::~LpdReceiveMessageCommand()
|
||||||
|
{
|
||||||
|
_e->deleteSocketForReadCheck(_receiver->getSocket(), this);
|
||||||
|
--__numInstance;
|
||||||
|
if(__numInstance == 0) {
|
||||||
|
__instance = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LpdReceiveMessageCommand::execute()
|
||||||
|
{
|
||||||
|
if(_e->_requestGroupMan->downloadFinished() || _e->isHaltRequested()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
for(size_t i = 0; i < 20; ++i) {
|
||||||
|
SharedHandle<LpdMessage> m = _receiver->receiveMessage();
|
||||||
|
if(m.isNull()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
SharedHandle<BtRegistry> reg = _e->getBtRegistry();
|
||||||
|
SharedHandle<DownloadContext> dctx =
|
||||||
|
reg->getDownloadContext(m->getInfoHash());
|
||||||
|
if(dctx.isNull()) {
|
||||||
|
if(logger->debug()) {
|
||||||
|
logger->debug("Download Context is null for infohash=%s.",
|
||||||
|
util::toHex(m->getInfoHash()).c_str());
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const BDE& torrentAttrs = dctx->getAttribute(bittorrent::BITTORRENT);
|
||||||
|
if(torrentAttrs.containsKey(bittorrent::PRIVATE)) {
|
||||||
|
if(torrentAttrs[bittorrent::PRIVATE].i() == 1) {
|
||||||
|
if(logger->debug()) {
|
||||||
|
logger->debug("Ignore LPD message because the torrent is private.");
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RequestGroup* group = dctx->getOwnerRequestGroup();
|
||||||
|
assert(group);
|
||||||
|
BtObject btobj = reg->get(group->getGID());
|
||||||
|
assert(!btobj.isNull());
|
||||||
|
SharedHandle<PeerStorage> peerStorage = btobj._peerStorage;
|
||||||
|
assert(!peerStorage.isNull());
|
||||||
|
SharedHandle<Peer> peer = m->getPeer();
|
||||||
|
if(peerStorage->addPeer(peer)) {
|
||||||
|
if(logger->debug()) {
|
||||||
|
logger->debug("LPD peer %s:%u local=%d added.",
|
||||||
|
peer->ipaddr.c_str(), peer->port,
|
||||||
|
peer->isLocalPeer()?1:0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(logger->debug()) {
|
||||||
|
logger->debug("LPD peer %s:%u local=%d not added.",
|
||||||
|
peer->ipaddr.c_str(), peer->port,
|
||||||
|
peer->isLocalPeer()?1:0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_e->commands.push_back(this);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SharedHandle<SocketCore> LpdReceiveMessageCommand::getReceiverSocket() const
|
||||||
|
{
|
||||||
|
return _receiver->getSocket();
|
||||||
|
}
|
||||||
|
|
||||||
|
LpdReceiveMessageCommand*
|
||||||
|
LpdReceiveMessageCommand::getInstance
|
||||||
|
(DownloadEngine* e, const SharedHandle<LpdMessageReceiver>& receiver)
|
||||||
|
{
|
||||||
|
if(__numInstance == 0) {
|
||||||
|
__instance = new LpdReceiveMessageCommand(e->newCUID(), receiver, e);
|
||||||
|
}
|
||||||
|
return __instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
LpdReceiveMessageCommand* LpdReceiveMessageCommand::getInstance()
|
||||||
|
{
|
||||||
|
if(__numInstance == 0) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return __instance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace aria2
|
|
@ -0,0 +1,84 @@
|
||||||
|
/* <!-- copyright */
|
||||||
|
/*
|
||||||
|
* aria2 - The high speed download utility
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 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_LPD_RECEIVE_MESSAGE_COMMAND_H_
|
||||||
|
#define _D_LPD_RECEIVE_MESSAGE_COMMAND_H_
|
||||||
|
|
||||||
|
#include "Command.h"
|
||||||
|
#include "SharedHandle.h"
|
||||||
|
|
||||||
|
namespace aria2 {
|
||||||
|
|
||||||
|
class LpdMessageReceiver;
|
||||||
|
class DownloadEngine;
|
||||||
|
class SocketCore;
|
||||||
|
|
||||||
|
class LpdReceiveMessageCommand:public Command {
|
||||||
|
private:
|
||||||
|
SharedHandle<LpdMessageReceiver> _receiver;
|
||||||
|
|
||||||
|
static unsigned int __numInstance;
|
||||||
|
|
||||||
|
static LpdReceiveMessageCommand* __instance;
|
||||||
|
|
||||||
|
LpdReceiveMessageCommand
|
||||||
|
(int32_t cuid, const SharedHandle<LpdMessageReceiver>& receiver,
|
||||||
|
DownloadEngine* e);
|
||||||
|
protected:
|
||||||
|
DownloadEngine* _e;
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual ~LpdReceiveMessageCommand();
|
||||||
|
|
||||||
|
virtual bool execute();
|
||||||
|
|
||||||
|
SharedHandle<SocketCore> getReceiverSocket() const;
|
||||||
|
|
||||||
|
static LpdReceiveMessageCommand*
|
||||||
|
getInstance
|
||||||
|
(DownloadEngine* e, const SharedHandle<LpdMessageReceiver>& receiver);
|
||||||
|
|
||||||
|
// If __numInstance is 0, then return 0. If __numInstance > 0, it
|
||||||
|
// returns __instance
|
||||||
|
static LpdReceiveMessageCommand* getInstance();
|
||||||
|
|
||||||
|
static unsigned int getNumInstance()
|
||||||
|
{
|
||||||
|
return __numInstance;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace aria2
|
||||||
|
|
||||||
|
#endif // _D_LPD_RECEIVE_MESSAGE_COMMAND_H_
|
|
@ -440,7 +440,12 @@ SRCS += PeerAbstractCommand.cc PeerAbstractCommand.h\
|
||||||
bencode.cc bencode.h\
|
bencode.cc bencode.h\
|
||||||
bittorrent_helper.cc bittorrent_helper.h\
|
bittorrent_helper.cc bittorrent_helper.h\
|
||||||
BtStopDownloadCommand.cc BtStopDownloadCommand.h\
|
BtStopDownloadCommand.cc BtStopDownloadCommand.h\
|
||||||
PriorityPieceSelector.cc PriorityPieceSelector.h
|
PriorityPieceSelector.cc PriorityPieceSelector.h\
|
||||||
|
LpdMessageDispatcher.cc LpdMessageDispatcher.h\
|
||||||
|
LpdMessageReceiver.cc LpdMessageReceiver.h\
|
||||||
|
LpdMessage.h\
|
||||||
|
LpdReceiveMessageCommand.cc LpdReceiveMessageCommand.h\
|
||||||
|
LpdDispatchMessageCommand.cc LpdDispatchMessageCommand.h
|
||||||
endif # ENABLE_BITTORRENT
|
endif # ENABLE_BITTORRENT
|
||||||
|
|
||||||
if ENABLE_METALINK
|
if ENABLE_METALINK
|
||||||
|
|
|
@ -243,7 +243,12 @@ bin_PROGRAMS = aria2c$(EXEEXT)
|
||||||
@ENABLE_BITTORRENT_TRUE@ bencode.cc bencode.h\
|
@ENABLE_BITTORRENT_TRUE@ bencode.cc bencode.h\
|
||||||
@ENABLE_BITTORRENT_TRUE@ bittorrent_helper.cc bittorrent_helper.h\
|
@ENABLE_BITTORRENT_TRUE@ bittorrent_helper.cc bittorrent_helper.h\
|
||||||
@ENABLE_BITTORRENT_TRUE@ BtStopDownloadCommand.cc BtStopDownloadCommand.h\
|
@ENABLE_BITTORRENT_TRUE@ BtStopDownloadCommand.cc BtStopDownloadCommand.h\
|
||||||
@ENABLE_BITTORRENT_TRUE@ PriorityPieceSelector.cc PriorityPieceSelector.h
|
@ENABLE_BITTORRENT_TRUE@ PriorityPieceSelector.cc PriorityPieceSelector.h\
|
||||||
|
@ENABLE_BITTORRENT_TRUE@ LpdMessageDispatcher.cc LpdMessageDispatcher.h\
|
||||||
|
@ENABLE_BITTORRENT_TRUE@ LpdMessageReceiver.cc LpdMessageReceiver.h\
|
||||||
|
@ENABLE_BITTORRENT_TRUE@ LpdMessage.h\
|
||||||
|
@ENABLE_BITTORRENT_TRUE@ LpdReceiveMessageCommand.cc LpdReceiveMessageCommand.h\
|
||||||
|
@ENABLE_BITTORRENT_TRUE@ LpdDispatchMessageCommand.cc LpdDispatchMessageCommand.h
|
||||||
|
|
||||||
@ENABLE_METALINK_TRUE@am__append_14 = Metalinker.cc Metalinker.h\
|
@ENABLE_METALINK_TRUE@am__append_14 = Metalinker.cc Metalinker.h\
|
||||||
@ENABLE_METALINK_TRUE@ MetalinkEntry.cc MetalinkEntry.h\
|
@ENABLE_METALINK_TRUE@ MetalinkEntry.cc MetalinkEntry.h\
|
||||||
|
@ -570,8 +575,12 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
|
||||||
IndexBtMessageValidator.h ExtensionMessageRegistry.h \
|
IndexBtMessageValidator.h ExtensionMessageRegistry.h \
|
||||||
bencode.cc bencode.h bittorrent_helper.cc bittorrent_helper.h \
|
bencode.cc bencode.h bittorrent_helper.cc bittorrent_helper.h \
|
||||||
BtStopDownloadCommand.cc BtStopDownloadCommand.h \
|
BtStopDownloadCommand.cc BtStopDownloadCommand.h \
|
||||||
PriorityPieceSelector.cc PriorityPieceSelector.h Metalinker.cc \
|
PriorityPieceSelector.cc PriorityPieceSelector.h \
|
||||||
Metalinker.h MetalinkEntry.cc MetalinkEntry.h \
|
LpdMessageDispatcher.cc LpdMessageDispatcher.h \
|
||||||
|
LpdMessageReceiver.cc LpdMessageReceiver.h LpdMessage.h \
|
||||||
|
LpdReceiveMessageCommand.cc LpdReceiveMessageCommand.h \
|
||||||
|
LpdDispatchMessageCommand.cc LpdDispatchMessageCommand.h \
|
||||||
|
Metalinker.cc Metalinker.h MetalinkEntry.cc MetalinkEntry.h \
|
||||||
MetalinkResource.cc MetalinkResource.h MetalinkProcessor.h \
|
MetalinkResource.cc MetalinkResource.h MetalinkProcessor.h \
|
||||||
MetalinkParserController.cc MetalinkParserController.h \
|
MetalinkParserController.cc MetalinkParserController.h \
|
||||||
MetalinkParserStateMachine.cc MetalinkParserStateMachine.h \
|
MetalinkParserStateMachine.cc MetalinkParserStateMachine.h \
|
||||||
|
@ -734,7 +743,11 @@ am__objects_6 =
|
||||||
@ENABLE_BITTORRENT_TRUE@ bencode.$(OBJEXT) \
|
@ENABLE_BITTORRENT_TRUE@ bencode.$(OBJEXT) \
|
||||||
@ENABLE_BITTORRENT_TRUE@ bittorrent_helper.$(OBJEXT) \
|
@ENABLE_BITTORRENT_TRUE@ bittorrent_helper.$(OBJEXT) \
|
||||||
@ENABLE_BITTORRENT_TRUE@ BtStopDownloadCommand.$(OBJEXT) \
|
@ENABLE_BITTORRENT_TRUE@ BtStopDownloadCommand.$(OBJEXT) \
|
||||||
@ENABLE_BITTORRENT_TRUE@ PriorityPieceSelector.$(OBJEXT)
|
@ENABLE_BITTORRENT_TRUE@ PriorityPieceSelector.$(OBJEXT) \
|
||||||
|
@ENABLE_BITTORRENT_TRUE@ LpdMessageDispatcher.$(OBJEXT) \
|
||||||
|
@ENABLE_BITTORRENT_TRUE@ LpdMessageReceiver.$(OBJEXT) \
|
||||||
|
@ENABLE_BITTORRENT_TRUE@ LpdReceiveMessageCommand.$(OBJEXT) \
|
||||||
|
@ENABLE_BITTORRENT_TRUE@ LpdDispatchMessageCommand.$(OBJEXT)
|
||||||
@ENABLE_METALINK_TRUE@am__objects_14 = Metalinker.$(OBJEXT) \
|
@ENABLE_METALINK_TRUE@am__objects_14 = Metalinker.$(OBJEXT) \
|
||||||
@ENABLE_METALINK_TRUE@ MetalinkEntry.$(OBJEXT) \
|
@ENABLE_METALINK_TRUE@ MetalinkEntry.$(OBJEXT) \
|
||||||
@ENABLE_METALINK_TRUE@ MetalinkResource.$(OBJEXT) \
|
@ENABLE_METALINK_TRUE@ MetalinkResource.$(OBJEXT) \
|
||||||
|
@ -1465,6 +1478,10 @@ distclean-compile:
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/LogFactory.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/LogFactory.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Logger.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Logger.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/LongestSequencePieceSelector.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/LongestSequencePieceSelector.Po@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/LpdDispatchMessageCommand.Po@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/LpdMessageDispatcher.Po@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/LpdMessageReceiver.Po@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/LpdReceiveMessageCommand.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MSEHandshake.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MSEHandshake.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MemoryBufferPreDownloadHandler.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MemoryBufferPreDownloadHandler.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MessageDigestHelper.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MessageDigestHelper.Po@am__quote@
|
||||||
|
|
|
@ -942,6 +942,15 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
|
||||||
#endif // ENABLE_BITTORRENT || ENABLE_METALINK
|
#endif // ENABLE_BITTORRENT || ENABLE_METALINK
|
||||||
// BitTorrent Specific Options
|
// BitTorrent Specific Options
|
||||||
#ifdef ENABLE_BITTORRENT
|
#ifdef ENABLE_BITTORRENT
|
||||||
|
{
|
||||||
|
SharedHandle<OptionHandler> op(new BooleanOptionHandler
|
||||||
|
(PREF_BT_ENABLE_LPD,
|
||||||
|
TEXT_BT_ENABLE_LPD,
|
||||||
|
V_FALSE,
|
||||||
|
OptionHandler::OPT_ARG));
|
||||||
|
op->addTag(TAG_BITTORRENT);
|
||||||
|
handlers.push_back(op);
|
||||||
|
}
|
||||||
{
|
{
|
||||||
SharedHandle<OptionHandler> op(new DefaultOptionHandler
|
SharedHandle<OptionHandler> op(new DefaultOptionHandler
|
||||||
(PREF_BT_EXTERNAL_IP,
|
(PREF_BT_EXTERNAL_IP,
|
||||||
|
|
|
@ -55,7 +55,8 @@ Peer::Peer(std::string ipaddr, uint16_t port, bool incoming):
|
||||||
_badConditionStartTime(0),
|
_badConditionStartTime(0),
|
||||||
_seeder(false),
|
_seeder(false),
|
||||||
_res(0),
|
_res(0),
|
||||||
_incoming(incoming)
|
_incoming(incoming),
|
||||||
|
_localPeer(false)
|
||||||
{
|
{
|
||||||
memset(_peerId, 0, PEER_ID_LENGTH);
|
memset(_peerId, 0, PEER_ID_LENGTH);
|
||||||
resetStatus();
|
resetStatus();
|
||||||
|
|
13
src/Peer.h
13
src/Peer.h
|
@ -78,6 +78,9 @@ private:
|
||||||
// If true, port is assumed not to be a listening port.
|
// If true, port is assumed not to be a listening port.
|
||||||
bool _incoming;
|
bool _incoming;
|
||||||
|
|
||||||
|
// If true, this peer is from local network.
|
||||||
|
bool _localPeer;
|
||||||
|
|
||||||
// Before calling updateSeeder(), make sure that
|
// Before calling updateSeeder(), make sure that
|
||||||
// allocateSessionResource() is called and _res is created.
|
// allocateSessionResource() is called and _res is created.
|
||||||
// Otherwise assertion fails.
|
// Otherwise assertion fails.
|
||||||
|
@ -282,6 +285,16 @@ public:
|
||||||
|
|
||||||
void setIncomingPeer(bool incoming);
|
void setIncomingPeer(bool incoming);
|
||||||
|
|
||||||
|
bool isLocalPeer() const
|
||||||
|
{
|
||||||
|
return _localPeer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setLocalPeer(bool flag)
|
||||||
|
{
|
||||||
|
_localPeer = flag;
|
||||||
|
}
|
||||||
|
|
||||||
void setBtMessageDispatcher(const WeakHandle<BtMessageDispatcher>& dpt);
|
void setBtMessageDispatcher(const WeakHandle<BtMessageDispatcher>& dpt);
|
||||||
|
|
||||||
size_t countOutstandingUpload() const;
|
size_t countOutstandingUpload() const;
|
||||||
|
|
|
@ -189,7 +189,8 @@ PeerInteractionCommand::PeerInteractionCommand
|
||||||
(getOption()->getAsInt(PREF_BT_KEEP_ALIVE_INTERVAL));
|
(getOption()->getAsInt(PREF_BT_KEEP_ALIVE_INTERVAL));
|
||||||
btInteractive->setRequestGroupMan(e->_requestGroupMan);
|
btInteractive->setRequestGroupMan(e->_requestGroupMan);
|
||||||
btInteractive->setBtMessageFactory(factory);
|
btInteractive->setBtMessageFactory(factory);
|
||||||
if(metadataGetMode || torrentAttrs[bittorrent::PRIVATE].i() == 0) {
|
if((metadataGetMode || torrentAttrs[bittorrent::PRIVATE].i() == 0) &&
|
||||||
|
!peer->isLocalPeer()) {
|
||||||
if(getOption()->getAsBool(PREF_ENABLE_PEER_EXCHANGE)) {
|
if(getOption()->getAsBool(PREF_ENABLE_PEER_EXCHANGE)) {
|
||||||
btInteractive->setUTPexEnabled(true);
|
btInteractive->setUTPexEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -253,6 +253,18 @@ static sock_t bindTo
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SocketCore::bindWithFamily(uint16_t port, int family, int flags)
|
||||||
|
{
|
||||||
|
closeConnection();
|
||||||
|
std::string error;
|
||||||
|
sock_t fd = bindTo(0, port, family, _sockType, flags, error);
|
||||||
|
if(fd == (sock_t) -1) {
|
||||||
|
throw DL_ABORT_EX(StringFormat(EX_SOCKET_BIND, error.c_str()).str());
|
||||||
|
} else {
|
||||||
|
sockfd = fd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SocketCore::bind(uint16_t port, int flags)
|
void SocketCore::bind(uint16_t port, int flags)
|
||||||
{
|
{
|
||||||
closeConnection();
|
closeConnection();
|
||||||
|
@ -403,6 +415,28 @@ void SocketCore::establishConnection(const std::string& host, uint16_t port)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SocketCore::setSockOpt
|
||||||
|
(int level, int optname, void* optval, socklen_t optlen)
|
||||||
|
{
|
||||||
|
if(setsockopt(sockfd, level, optname, optval, optlen) < 0) {
|
||||||
|
throw DL_ABORT_EX(StringFormat(EX_SOCKET_SET_OPT, errorMsg()).str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SocketCore::setMulticastTtl(unsigned char ttl)
|
||||||
|
{
|
||||||
|
setSockOpt(IPPROTO_IP, IP_MULTICAST_TTL, (a2_sockopt_t)&ttl, sizeof(ttl));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SocketCore::joinMulticastGroup(const std::string& ipaddr, uint16_t port)
|
||||||
|
{
|
||||||
|
struct ip_mreq mreq;
|
||||||
|
memset(&mreq, 0, sizeof(mreq));
|
||||||
|
mreq.imr_multiaddr.s_addr = inet_addr(ipaddr.c_str());
|
||||||
|
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
|
||||||
|
setSockOpt(IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
|
||||||
|
}
|
||||||
|
|
||||||
void SocketCore::setNonBlockingMode()
|
void SocketCore::setNonBlockingMode()
|
||||||
{
|
{
|
||||||
#ifdef __MINGW32__
|
#ifdef __MINGW32__
|
||||||
|
|
|
@ -135,6 +135,8 @@ private:
|
||||||
|
|
||||||
#endif // HAVE_EPOLL
|
#endif // HAVE_EPOLL
|
||||||
|
|
||||||
|
void setSockOpt(int level, int optname, void* optval, socklen_t optlen);
|
||||||
|
|
||||||
SocketCore(sock_t sockfd, int sockType);
|
SocketCore(sock_t sockfd, int sockType);
|
||||||
public:
|
public:
|
||||||
SocketCore(int sockType = SOCK_STREAM);
|
SocketCore(int sockType = SOCK_STREAM);
|
||||||
|
@ -144,6 +146,12 @@ public:
|
||||||
|
|
||||||
bool isOpen() const { return sockfd != (sock_t) -1; }
|
bool isOpen() const { return sockfd != (sock_t) -1; }
|
||||||
|
|
||||||
|
void setMulticastTtl(unsigned char ttl);
|
||||||
|
|
||||||
|
void joinMulticastGroup(const std::string& ipaddr, uint16_t port);
|
||||||
|
|
||||||
|
void bindWithFamily(uint16_t port, int family, int flags = AI_PASSIVE);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a socket and bind it with locahost's address and port.
|
* Creates a socket and bind it with locahost's address and port.
|
||||||
* flags is set to struct addrinfo's ai_flags.
|
* flags is set to struct addrinfo's ai_flags.
|
||||||
|
|
|
@ -316,6 +316,8 @@ const std::string PREF_BT_PRIORITIZE_PIECE("bt-prioritize-piece");
|
||||||
const std::string PREF_BT_SAVE_METADATA("bt-save-metadata");
|
const std::string PREF_BT_SAVE_METADATA("bt-save-metadata");
|
||||||
// values: true | false
|
// values: true | false
|
||||||
const std::string PREF_BT_METADATA_ONLY("bt-metadata-only");
|
const std::string PREF_BT_METADATA_ONLY("bt-metadata-only");
|
||||||
|
// values: true | false
|
||||||
|
const std::string PREF_BT_ENABLE_LPD("bt-enable-lpd");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Metalink related preferences
|
* Metalink related preferences
|
||||||
|
|
|
@ -320,6 +320,8 @@ extern const std::string PREF_BT_PRIORITIZE_PIECE;
|
||||||
extern const std::string PREF_BT_SAVE_METADATA;
|
extern const std::string PREF_BT_SAVE_METADATA;
|
||||||
// values: true | false
|
// values: true | false
|
||||||
extern const std::string PREF_BT_METADATA_ONLY;
|
extern const std::string PREF_BT_METADATA_ONLY;
|
||||||
|
// values: true | false
|
||||||
|
extern const std::string PREF_BT_ENABLE_LPD;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Metalink related preferences
|
* Metalink related preferences
|
||||||
|
|
|
@ -608,3 +608,5 @@
|
||||||
#define TEXT_HUMAN_READABLE \
|
#define TEXT_HUMAN_READABLE \
|
||||||
_(" --human-readable[=true|false] Print sizes and speed in human readable format\n" \
|
_(" --human-readable[=true|false] Print sizes and speed in human readable format\n" \
|
||||||
" (e.g., 1.2Ki, 3.4Mi) in the console readout.")
|
" (e.g., 1.2Ki, 3.4Mi) in the console readout.")
|
||||||
|
#define TEXT_BT_ENABLE_LPD \
|
||||||
|
_(" --bt-enable-lpd[=true|false] Enable Local Peer Discovery.")
|
||||||
|
|
22
src/util.cc
22
src/util.cc
|
@ -1172,6 +1172,28 @@ void generateRandomKey(unsigned char* key)
|
||||||
#endif // !ENABLE_MESSAGE_DIGEST
|
#endif // !ENABLE_MESSAGE_DIGEST
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns true is given numeric ipv4addr is in Private Address Space.
|
||||||
|
//
|
||||||
|
// From Section.3 RFC1918
|
||||||
|
// 10.0.0.0 - 10.255.255.255 (10/8 prefix)
|
||||||
|
// 172.16.0.0 - 172.31.255.255 (172.16/12 prefix)
|
||||||
|
// 192.168.0.0 - 192.168.255.255 (192.168/16 prefix)
|
||||||
|
bool inPrivateAddress(const std::string& ipv4addr)
|
||||||
|
{
|
||||||
|
if(util::startsWith(ipv4addr, "10.") ||
|
||||||
|
util::startsWith(ipv4addr, "192.168.")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(util::startsWith(ipv4addr, "172.")) {
|
||||||
|
for(int i = 16; i <= 31; ++i) {
|
||||||
|
if(util::startsWith(ipv4addr, "172."+util::itos(i)+".")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace util
|
} // namespace util
|
||||||
|
|
||||||
} // namespace aria2
|
} // namespace aria2
|
||||||
|
|
|
@ -378,6 +378,9 @@ std::string fixTaintedBasename(const std::string& src);
|
||||||
// by key. Caller must allocate at least 20 bytes for generated key.
|
// by key. Caller must allocate at least 20 bytes for generated key.
|
||||||
void generateRandomKey(unsigned char* key);
|
void generateRandomKey(unsigned char* key);
|
||||||
|
|
||||||
|
// Returns true is given numeric ipv4addr is in Private Address Space.
|
||||||
|
bool inPrivateAddress(const std::string& ipv4addr);
|
||||||
|
|
||||||
} // namespace util
|
} // namespace util
|
||||||
|
|
||||||
} // namespace aria2
|
} // namespace aria2
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
#include "LpdMessageDispatcher.h"
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#include <cppunit/extensions/HelperMacros.h>
|
||||||
|
|
||||||
|
#include "Exception.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "LpdMessageDispatcher.h"
|
||||||
|
#include "SocketCore.h"
|
||||||
|
#include "BtConstants.h"
|
||||||
|
|
||||||
|
namespace aria2 {
|
||||||
|
|
||||||
|
class LpdMessageDispatcherTest:public CppUnit::TestFixture {
|
||||||
|
|
||||||
|
CPPUNIT_TEST_SUITE(LpdMessageDispatcherTest);
|
||||||
|
CPPUNIT_TEST(testCreateLpdRequest);
|
||||||
|
CPPUNIT_TEST(testSendMessage);
|
||||||
|
CPPUNIT_TEST_SUITE_END();
|
||||||
|
public:
|
||||||
|
void testCreateLpdRequest();
|
||||||
|
void testSendMessage();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
CPPUNIT_TEST_SUITE_REGISTRATION(LpdMessageDispatcherTest);
|
||||||
|
|
||||||
|
void LpdMessageDispatcherTest::testCreateLpdRequest()
|
||||||
|
{
|
||||||
|
std::string infoHashString = "cd41c7fdddfd034a15a04d7ff881216e01c4ceaf";
|
||||||
|
CPPUNIT_ASSERT_EQUAL
|
||||||
|
(std::string("BT-SEARCH * HTTP/1.1\r\n"
|
||||||
|
"Host: 239.192.152.143:6771\r\n"
|
||||||
|
"Port: 6000\r\n"
|
||||||
|
"Infohash: cd41c7fdddfd034a15a04d7ff881216e01c4ceaf\r\n"
|
||||||
|
"\r\n\r\n"),
|
||||||
|
bittorrent::createLpdRequest("239.192.152.143", 6771,
|
||||||
|
util::fromHex(infoHashString), 6000));
|
||||||
|
}
|
||||||
|
|
||||||
|
void LpdMessageDispatcherTest::testSendMessage()
|
||||||
|
{
|
||||||
|
SharedHandle<SocketCore> recvsock(new SocketCore(SOCK_DGRAM));
|
||||||
|
recvsock->bind(LPD_MULTICAST_PORT);
|
||||||
|
recvsock->joinMulticastGroup(LPD_MULTICAST_ADDR, LPD_MULTICAST_PORT);
|
||||||
|
recvsock->setMulticastTtl(0);
|
||||||
|
LpdMessageDispatcher d("cd41c7fdddfd034a15a04d7ff881216e01c4ceaf", 6000,
|
||||||
|
LPD_MULTICAST_ADDR, LPD_MULTICAST_PORT,
|
||||||
|
recvsock);
|
||||||
|
|
||||||
|
CPPUNIT_ASSERT(d.sendMessage());
|
||||||
|
|
||||||
|
unsigned char buf[200];
|
||||||
|
|
||||||
|
std::pair<std::string, uint16_t> peer;
|
||||||
|
ssize_t nbytes = recvsock->readDataFrom(buf, sizeof(buf), peer);
|
||||||
|
buf[nbytes] = '\0';
|
||||||
|
std::stringstream temp;
|
||||||
|
temp << "BT-SEARCH * HTTP/1.1\r\n"
|
||||||
|
<< "Host: " << LPD_MULTICAST_ADDR << ":" << LPD_MULTICAST_PORT << "\r\n"
|
||||||
|
<< "Port: " << d.getPort() << "\r\n"
|
||||||
|
<< "Infohash: " << util::toHex(d.getInfoHash()) << "\r\n"
|
||||||
|
<< "\r\n\r\n";
|
||||||
|
CPPUNIT_ASSERT_EQUAL(temp.str(), std::string(&buf[0], &buf[nbytes]));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace aria2
|
|
@ -0,0 +1,75 @@
|
||||||
|
#include "LpdMessageReceiver.h"
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
#include <cppunit/extensions/HelperMacros.h>
|
||||||
|
|
||||||
|
#include "Exception.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "LpdMessageReceiver.h"
|
||||||
|
#include "SocketCore.h"
|
||||||
|
#include "BtConstants.h"
|
||||||
|
#include "LpdMessage.h"
|
||||||
|
#include "LpdMessageDispatcher.h"
|
||||||
|
|
||||||
|
namespace aria2 {
|
||||||
|
|
||||||
|
class LpdMessageReceiverTest:public CppUnit::TestFixture {
|
||||||
|
|
||||||
|
CPPUNIT_TEST_SUITE(LpdMessageReceiverTest);
|
||||||
|
CPPUNIT_TEST(testReceiveMessage);
|
||||||
|
CPPUNIT_TEST_SUITE_END();
|
||||||
|
public:
|
||||||
|
void testReceiveMessage();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
CPPUNIT_TEST_SUITE_REGISTRATION(LpdMessageReceiverTest);
|
||||||
|
|
||||||
|
void LpdMessageReceiverTest::testReceiveMessage()
|
||||||
|
{
|
||||||
|
LpdMessageReceiver rcv(LPD_MULTICAST_ADDR, LPD_MULTICAST_PORT);
|
||||||
|
CPPUNIT_ASSERT(rcv.init());
|
||||||
|
|
||||||
|
SharedHandle<SocketCore> sendsock = rcv.getSocket();
|
||||||
|
sendsock->setMulticastTtl(0);
|
||||||
|
|
||||||
|
std::string infoHashString = "cd41c7fdddfd034a15a04d7ff881216e01c4ceaf";
|
||||||
|
std::string infoHash = util::fromHex(infoHashString);
|
||||||
|
std::string request =
|
||||||
|
bittorrent::createLpdRequest(LPD_MULTICAST_ADDR, LPD_MULTICAST_PORT,
|
||||||
|
infoHash,
|
||||||
|
6000);
|
||||||
|
|
||||||
|
sendsock->writeData(request.c_str(), request.size(),
|
||||||
|
LPD_MULTICAST_ADDR, LPD_MULTICAST_PORT);
|
||||||
|
|
||||||
|
SharedHandle<LpdMessage> msg = rcv.receiveMessage();
|
||||||
|
CPPUNIT_ASSERT(!msg.isNull());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(std::string("cd41c7fdddfd034a15a04d7ff881216e01c4ceaf"),
|
||||||
|
util::toHex(msg->getInfoHash()));
|
||||||
|
CPPUNIT_ASSERT_EQUAL((uint16_t)6000, msg->getPeer()->port);
|
||||||
|
|
||||||
|
// Bad infohash
|
||||||
|
std::string badInfoHashString = "cd41c7fdddfd034a15a04d7ff881216e01c4ce";
|
||||||
|
request =
|
||||||
|
bittorrent::createLpdRequest(LPD_MULTICAST_ADDR, LPD_MULTICAST_PORT,
|
||||||
|
util::fromHex(badInfoHashString),
|
||||||
|
6000);
|
||||||
|
sendsock->writeData(request.c_str(), request.size(),
|
||||||
|
LPD_MULTICAST_ADDR, LPD_MULTICAST_PORT);
|
||||||
|
|
||||||
|
CPPUNIT_ASSERT(rcv.receiveMessage().isNull());
|
||||||
|
|
||||||
|
// Bad port
|
||||||
|
request =
|
||||||
|
bittorrent::createLpdRequest(LPD_MULTICAST_ADDR, LPD_MULTICAST_PORT,
|
||||||
|
infoHash,
|
||||||
|
0);
|
||||||
|
sendsock->writeData(request.c_str(), request.size(),
|
||||||
|
LPD_MULTICAST_ADDR, LPD_MULTICAST_PORT);
|
||||||
|
|
||||||
|
CPPUNIT_ASSERT(rcv.receiveMessage().isNull());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace aria2
|
|
@ -191,7 +191,9 @@ aria2c_SOURCES += BtAllowedFastMessageTest.cc\
|
||||||
BittorrentHelperTest.cc\
|
BittorrentHelperTest.cc\
|
||||||
PriorityPieceSelectorTest.cc\
|
PriorityPieceSelectorTest.cc\
|
||||||
MockPieceSelector.h\
|
MockPieceSelector.h\
|
||||||
extension_message_test_helper.h
|
extension_message_test_helper.h\
|
||||||
|
LpdMessageDispatcherTest.cc\
|
||||||
|
LpdMessageReceiverTest.cc
|
||||||
endif # ENABLE_BITTORRENT
|
endif # ENABLE_BITTORRENT
|
||||||
|
|
||||||
if ENABLE_METALINK
|
if ENABLE_METALINK
|
||||||
|
|
|
@ -141,7 +141,9 @@ check_PROGRAMS = $(am__EXEEXT_1)
|
||||||
@ENABLE_BITTORRENT_TRUE@ BittorrentHelperTest.cc\
|
@ENABLE_BITTORRENT_TRUE@ BittorrentHelperTest.cc\
|
||||||
@ENABLE_BITTORRENT_TRUE@ PriorityPieceSelectorTest.cc\
|
@ENABLE_BITTORRENT_TRUE@ PriorityPieceSelectorTest.cc\
|
||||||
@ENABLE_BITTORRENT_TRUE@ MockPieceSelector.h\
|
@ENABLE_BITTORRENT_TRUE@ MockPieceSelector.h\
|
||||||
@ENABLE_BITTORRENT_TRUE@ extension_message_test_helper.h
|
@ENABLE_BITTORRENT_TRUE@ extension_message_test_helper.h\
|
||||||
|
@ENABLE_BITTORRENT_TRUE@ LpdMessageDispatcherTest.cc\
|
||||||
|
@ENABLE_BITTORRENT_TRUE@ LpdMessageReceiverTest.cc
|
||||||
|
|
||||||
@ENABLE_METALINK_TRUE@am__append_7 = MetalinkerTest.cc\
|
@ENABLE_METALINK_TRUE@am__append_7 = MetalinkerTest.cc\
|
||||||
@ENABLE_METALINK_TRUE@ MetalinkEntryTest.cc\
|
@ENABLE_METALINK_TRUE@ MetalinkEntryTest.cc\
|
||||||
|
@ -266,7 +268,8 @@ am__aria2c_SOURCES_DIST = AllTest.cc TestUtil.cc TestUtil.h \
|
||||||
MockExtensionMessage.h MockExtensionMessageFactory.h \
|
MockExtensionMessage.h MockExtensionMessageFactory.h \
|
||||||
MockPieceStorage.h BencodeTest.cc BittorrentHelperTest.cc \
|
MockPieceStorage.h BencodeTest.cc BittorrentHelperTest.cc \
|
||||||
PriorityPieceSelectorTest.cc MockPieceSelector.h \
|
PriorityPieceSelectorTest.cc MockPieceSelector.h \
|
||||||
extension_message_test_helper.h MetalinkerTest.cc \
|
extension_message_test_helper.h LpdMessageDispatcherTest.cc \
|
||||||
|
LpdMessageReceiverTest.cc MetalinkerTest.cc \
|
||||||
MetalinkEntryTest.cc Metalink2RequestGroupTest.cc \
|
MetalinkEntryTest.cc Metalink2RequestGroupTest.cc \
|
||||||
MetalinkPostDownloadHandlerTest.cc MetalinkHelperTest.cc \
|
MetalinkPostDownloadHandlerTest.cc MetalinkHelperTest.cc \
|
||||||
MetalinkParserControllerTest.cc MetalinkProcessorTest.cc
|
MetalinkParserControllerTest.cc MetalinkProcessorTest.cc
|
||||||
|
@ -356,7 +359,9 @@ am__aria2c_SOURCES_DIST = AllTest.cc TestUtil.cc TestUtil.h \
|
||||||
@ENABLE_BITTORRENT_TRUE@ MSEHandshakeTest.$(OBJEXT) \
|
@ENABLE_BITTORRENT_TRUE@ MSEHandshakeTest.$(OBJEXT) \
|
||||||
@ENABLE_BITTORRENT_TRUE@ BencodeTest.$(OBJEXT) \
|
@ENABLE_BITTORRENT_TRUE@ BencodeTest.$(OBJEXT) \
|
||||||
@ENABLE_BITTORRENT_TRUE@ BittorrentHelperTest.$(OBJEXT) \
|
@ENABLE_BITTORRENT_TRUE@ BittorrentHelperTest.$(OBJEXT) \
|
||||||
@ENABLE_BITTORRENT_TRUE@ PriorityPieceSelectorTest.$(OBJEXT)
|
@ENABLE_BITTORRENT_TRUE@ PriorityPieceSelectorTest.$(OBJEXT) \
|
||||||
|
@ENABLE_BITTORRENT_TRUE@ LpdMessageDispatcherTest.$(OBJEXT) \
|
||||||
|
@ENABLE_BITTORRENT_TRUE@ LpdMessageReceiverTest.$(OBJEXT)
|
||||||
@ENABLE_METALINK_TRUE@am__objects_7 = MetalinkerTest.$(OBJEXT) \
|
@ENABLE_METALINK_TRUE@am__objects_7 = MetalinkerTest.$(OBJEXT) \
|
||||||
@ENABLE_METALINK_TRUE@ MetalinkEntryTest.$(OBJEXT) \
|
@ENABLE_METALINK_TRUE@ MetalinkEntryTest.$(OBJEXT) \
|
||||||
@ENABLE_METALINK_TRUE@ Metalink2RequestGroupTest.$(OBJEXT) \
|
@ENABLE_METALINK_TRUE@ Metalink2RequestGroupTest.$(OBJEXT) \
|
||||||
|
@ -824,6 +829,8 @@ distclean-compile:
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/IteratableChecksumValidatorTest.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/IteratableChecksumValidatorTest.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/IteratableChunkChecksumValidatorTest.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/IteratableChunkChecksumValidatorTest.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/LongestSequencePieceSelectorTest.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/LongestSequencePieceSelectorTest.Po@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/LpdMessageDispatcherTest.Po@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/LpdMessageReceiverTest.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MSEHandshakeTest.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MSEHandshakeTest.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MagnetTest.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MagnetTest.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MessageDigestHelperTest.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MessageDigestHelperTest.Po@am__quote@
|
||||||
|
|
Loading…
Reference in New Issue