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
pull/1/head
Tatsuhiro Tsujikawa 2010-02-20 14:23:25 +00:00
parent aee471e52c
commit 9281f11264
29 changed files with 1191 additions and 11 deletions

View File

@ -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

View File

@ -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_

View File

@ -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 =

View File

@ -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

View File

@ -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_

65
src/LpdMessage.h Normal file
View File

@ -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_

View File

@ -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

View File

@ -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_

107
src/LpdMessageReceiver.cc Normal file
View File

@ -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

74
src/LpdMessageReceiver.h Normal file
View File

@ -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_

View File

@ -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

View File

@ -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_

View File

@ -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

View File

@ -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@

View File

@ -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,

View File

@ -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();

View File

@ -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;

View File

@ -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);
} }

View File

@ -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__

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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.")

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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@