From 3c05e81529818d4a5ee6904e7747189ac29c6793 Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Wed, 16 Feb 2011 07:41:44 +0000 Subject: [PATCH] support for receiving multi announce messages for local peer discovery --- ChangeLog | 1 + include/libtorrent/http_parser.hpp | 6 +-- src/http_parser.cpp | 2 +- src/lsd.cpp | 61 +++++++++++++++++------------- src/web_peer_connection.cpp | 4 +- test/test_http_connection.cpp | 2 +- 6 files changed, 43 insertions(+), 33 deletions(-) diff --git a/ChangeLog b/ChangeLog index 00a7c3cef..644ad030f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,4 @@ + * support for receiving multi announce messages for local peer discovery * added session::listen_no_system_port flag to prevent libtorrent from ever binding the listen socket to port 0 * added option to not recheck on missing or incomplete resume data * extended stats logging with statistics=on builds diff --git a/include/libtorrent/http_parser.hpp b/include/libtorrent/http_parser.hpp index 49ac8e296..4dbd944ce 100644 --- a/include/libtorrent/http_parser.hpp +++ b/include/libtorrent/http_parser.hpp @@ -69,7 +69,7 @@ namespace libtorrent std::string const& header(char const* key) const { static std::string empty; - std::map::const_iterator i + std::multimap::const_iterator i = m_header.find(key); if (i == m_header.end()) return empty; return i->second; @@ -115,7 +115,7 @@ namespace libtorrent // reset the whole state and start over void reset(); - std::map const& headers() const { return m_header; } + std::multimap const& headers() const { return m_header; } std::vector > const& chunks() const { return m_chunked_ranges; } private: @@ -132,7 +132,7 @@ namespace libtorrent enum { read_status, read_header, read_body, error_state } m_state; - std::map m_header; + std::multimap m_header; buffer::const_interval m_recv_buffer; int m_body_start_pos; diff --git a/src/http_parser.cpp b/src/http_parser.cpp index ae890d440..ab16a1e11 100644 --- a/src/http_parser.cpp +++ b/src/http_parser.cpp @@ -392,7 +392,7 @@ restart_response: // add them to the headers in the parser for (std::map::const_iterator i = tail_headers.begin(); i != tail_headers.end(); ++i) - m_header[i->first] = i->second; + m_header.insert(std::make_pair(i->first, i->second)); return true; } diff --git a/src/lsd.cpp b/src/lsd.cpp index 4b3a53ed7..12073f0b4 100644 --- a/src/lsd.cpp +++ b/src/lsd.cpp @@ -176,43 +176,52 @@ void lsd::on_announce(udp::endpoint const& from, char* buffer if (port_str.empty()) { #if defined(TORRENT_LOGGING) || defined(TORRENT_VERBOSE_LOGGING) - m_log << time_now_string() - << " <== announce: invalid BT-SEARCH, missing port" << std::endl; + m_log << time_now_string() + << " <== announce: invalid BT-SEARCH, missing port" << std::endl; #endif return; } - std::string const& ih_str = p.header("infohash"); - if (ih_str.empty()) - { -#if defined(TORRENT_LOGGING) || defined(TORRENT_VERBOSE_LOGGING) - m_log << time_now_string() - << " <== announce: invalid BT-SEARCH, missing infohash" << std::endl; -#endif - return; - } - - sha1_hash ih(0); - from_hex(ih_str.c_str(), 40, (char*)&ih[0]); int port = std::atoi(port_str.c_str()); - if (!ih.is_all_zeros() && port != 0) + typedef std::multimap headers_t; + headers_t const& headers = p.headers(); + std::pair ihs + = headers.equal_range("infohash"); + + for (headers_t::const_iterator i = ihs.first; i != ihs.second; ++i) { + std::string const& ih_str = i->second; + if (ih_str.size() != 40) + { #if defined(TORRENT_LOGGING) || defined(TORRENT_VERBOSE_LOGGING) - char msg[200]; - snprintf(msg, 200, "%s *** incoming local announce %s:%d ih: %s\n" - , time_now_string(), print_address(from.address()).c_str() - , port, ih_str.c_str()); + m_log << time_now_string() + << " <== announce: invalid BT-SEARCH, invalid infohash: " + << ih_str << std::endl; #endif - // we got an announce, pass it on through the callback -#ifndef BOOST_NO_EXCEPTIONS - try { -#endif - m_callback(tcp::endpoint(from.address(), port), ih); -#ifndef BOOST_NO_EXCEPTIONS + continue; } - catch (std::exception&) {} + + sha1_hash ih(0); + from_hex(ih_str.c_str(), 40, (char*)&ih[0]); + + if (!ih.is_all_zeros() && port != 0) + { +#if defined(TORRENT_LOGGING) || defined(TORRENT_VERBOSE_LOGGING) + char msg[200]; + snprintf(msg, 200, "%s *** incoming local announce %s:%d ih: %s\n" + , time_now_string(), print_address(from.address()).c_str() + , port, ih_str.c_str()); #endif + // we got an announce, pass it on through the callback +#ifndef BOOST_NO_EXCEPTIONS + try { +#endif + m_callback(tcp::endpoint(from.address(), port), ih); +#ifndef BOOST_NO_EXCEPTIONS + } catch (std::exception&) {} +#endif + } } } diff --git a/src/web_peer_connection.cpp b/src/web_peer_connection.cpp index 46dc4b846..004fba714 100644 --- a/src/web_peer_connection.cpp +++ b/src/web_peer_connection.cpp @@ -362,8 +362,8 @@ namespace libtorrent { #ifdef TORRENT_VERBOSE_LOGGING peer_log("*** STATUS: %d %s", m_parser.status_code(), m_parser.message().c_str()); - std::map const& headers = m_parser.headers(); - for (std::map::const_iterator i = headers.begin() + std::multimap const& headers = m_parser.headers(); + for (std::multimap::const_iterator i = headers.begin() , end(headers.end()); i != end; ++i) peer_log(" %s: %s", i->first.c_str(), i->second.c_str()); #endif diff --git a/test/test_http_connection.cpp b/test/test_http_connection.cpp index 38317a8c2..e84ee243a 100644 --- a/test/test_http_connection.cpp +++ b/test/test_http_connection.cpp @@ -57,7 +57,7 @@ void print_http_header(http_parser const& p) { std::cerr << " < " << p.status_code() << " " << p.message() << std::endl; - for (std::map::const_iterator i + for (std::multimap::const_iterator i = p.headers().begin(), end(p.headers().end()); i != end; ++i) { std::cerr << " < " << i->first << ": " << i->second << std::endl;