diff options
| author | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2010-02-20 14:23:25 +0000 |
|---|---|---|
| committer | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2010-02-20 14:23:25 +0000 |
| commit | 9281f1126471fa90e2d6fe094c4c6eba00073ea6 (patch) | |
| tree | db2dc360e785cf78fd67f565d061cc24dc68f388 /src/LpdMessageReceiver.cc | |
| parent | aee471e52c6f7ac06817600e2c21b400ef375ecb (diff) | |
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
Diffstat (limited to 'src/LpdMessageReceiver.cc')
| -rw-r--r-- | src/LpdMessageReceiver.cc | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/src/LpdMessageReceiver.cc b/src/LpdMessageReceiver.cc new file mode 100644 index 00000000..3d9567f2 --- /dev/null +++ b/src/LpdMessageReceiver.cc @@ -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 |
