diff --git a/include/libtorrent/alert_types.hpp b/include/libtorrent/alert_types.hpp index 8eab84ed8..ca5fb4256 100644 --- a/include/libtorrent/alert_types.hpp +++ b/include/libtorrent/alert_types.hpp @@ -2247,9 +2247,28 @@ namespace libtorrent std::string msg; }; + // posted if the local service discovery socket fails to start properly. + // it's categorized as ``error_notification``. + struct TORRENT_EXPORT lsd_error_alert : alert + { + // internal + lsd_error_alert(error_code const& ec) + : alert() + , error(ec) + {} + + TORRENT_DEFINE_ALERT(lsd_error_alert, 82); + + const static int static_category = alert::error_notification; + virtual std::string message() const; + + // The error code + error_code error; + }; + #undef TORRENT_DEFINE_ALERT - enum { num_alert_types = 82 }; + enum { num_alert_types = 83 }; } diff --git a/include/libtorrent/aux_/session_impl.hpp b/include/libtorrent/aux_/session_impl.hpp index 2d4e62b6e..bca9a54da 100644 --- a/include/libtorrent/aux_/session_impl.hpp +++ b/include/libtorrent/aux_/session_impl.hpp @@ -346,6 +346,9 @@ namespace libtorrent void on_port_map_log(char const* msg, int map_transport); void on_lsd_announce(error_code const& e); +#if defined TORRENT_LOGGING + void on_lsd_log(char const* log); +#endif // called when a port mapping is successful, or a router returns // a failure to map a port diff --git a/include/libtorrent/lsd.hpp b/include/libtorrent/lsd.hpp index 68b2566cc..406e05082 100644 --- a/include/libtorrent/lsd.hpp +++ b/include/libtorrent/lsd.hpp @@ -44,21 +44,28 @@ POSSIBILITY OF SUCH DAMAGE. #include #if defined TORRENT_LOGGING -#include +#include #endif namespace libtorrent { typedef boost::function peer_callback_t; +#if defined TORRENT_LOGGING +typedef boost::function log_callback_t; +#endif class lsd : public boost::enable_shared_from_this { public: - lsd(io_service& ios, peer_callback_t const& cb); + lsd(io_service& ios, peer_callback_t const& cb +#if defined TORRENT_LOGGING + , log_callback_t const& log +#endif + ); ~lsd(); - void start(); + void start(error_code& ec); void announce(sha1_hash const& ih, int listen_port, bool broadcast = false); void close(); @@ -82,6 +89,10 @@ private: #if TORRENT_USE_IPV6 broadcast_socket m_socket6; #endif +#if defined TORRENT_LOGGING + log_callback_t m_log_cb; + void debug_log(char const* fmt, ...) const; +#endif // used to resend udp packets in case // they time out @@ -98,9 +109,6 @@ private: #if TORRENT_USE_IPV6 bool m_disabled6; #endif -#if defined TORRENT_LOGGING - FILE* m_log; -#endif }; } diff --git a/src/alert.cpp b/src/alert.cpp index ec30ff64d..96d779f16 100644 --- a/src/alert.cpp +++ b/src/alert.cpp @@ -730,5 +730,10 @@ namespace libtorrent { return torrent_alert::message() + " [" + print_endpoint(ip) + "] " + msg; } + std::string lsd_error_alert::message() const + { + return "Local Service Discovery error: " + error.message(); + } + } // namespace libtorrent diff --git a/src/lsd.cpp b/src/lsd.cpp index 429b9a2b6..145542a92 100644 --- a/src/lsd.cpp +++ b/src/lsd.cpp @@ -65,11 +65,18 @@ namespace libtorrent static error_code ec; -lsd::lsd(io_service& ios, peer_callback_t const& cb) +lsd::lsd(io_service& ios, peer_callback_t const& cb +#if defined TORRENT_LOGGING + , log_callback_t const& log +#endif + ) : m_callback(cb) , m_socket(udp::endpoint(address_v4::from_string("239.192.152.143", ec), 6771)) #if TORRENT_USE_IPV6 , m_socket6(udp::endpoint(address_v6::from_string("ff15::efc0:988f", ec), 6771)) +#endif +#if defined TORRENT_LOGGING + , m_log_cb(log) #endif , m_broadcast_timer(ios) , m_cookie(random()) @@ -77,55 +84,35 @@ lsd::lsd(io_service& ios, peer_callback_t const& cb) #if TORRENT_USE_IPV6 , m_disabled6(false) #endif -#if defined TORRENT_LOGGING - , m_log(NULL) -#endif { } -void lsd::start() -{ #if defined TORRENT_LOGGING - // TODO: 3 instead if writing to a file, post alerts. Or call a log callback - m_log = fopen("lsd.log", "w+"); - if (m_log == NULL) - { - fprintf(stderr, "failed to open 'lsd.log': (%d) %s" - , errno, strerror(errno)); - } +void lsd::debug_log(char const* fmt, ...) const +{ + va_list v; + va_start(v, fmt); + + char buf[1024]; + vsnprintf(buf, sizeof(buf), fmt, v); + va_end(v); + m_log_cb(buf); +} #endif - error_code ec; +void lsd::start(error_code& ec) +{ m_socket.open(boost::bind(&lsd::on_announce, self(), _1, _2, _3) , m_broadcast_timer.get_io_service(), ec); - -#if defined TORRENT_LOGGING - if (ec) - { - if (m_log) fprintf(m_log, "FAILED TO OPEN SOCKET: (%d) %s\n" - , ec.value(), ec.message().c_str()); - } -#endif + if (ec) return; #if TORRENT_USE_IPV6 m_socket6.open(boost::bind(&lsd::on_announce, self(), _1, _2, _3) , m_broadcast_timer.get_io_service(), ec); -#if defined TORRENT_LOGGING - if (ec) - { - if (m_log) fprintf(m_log, "FAILED TO OPEN SOCKET6: (%d) %s\n" - , ec.value(), ec.message().c_str()); - } -#endif #endif } -lsd::~lsd() -{ -#if defined TORRENT_LOGGING - if (m_log) fclose(m_log); -#endif -} +lsd::~lsd() {} int render_lsd_packet(char* dst, int len, int listen_port , char const* info_hash_hex, int m_cookie, char const* host) @@ -158,8 +145,7 @@ void lsd::announce_impl(sha1_hash const& ih, int listen_port, bool broadcast char msg[200]; #if defined TORRENT_LOGGING - if (m_log) fprintf(m_log, "%s ==> announce: ih: %s port: %u\n" - , time_now_string(), ih_hex, listen_port); + debug_log("==> announce: ih: %s port: %u\n", ih_hex, listen_port); #endif error_code ec; @@ -172,8 +158,8 @@ void lsd::announce_impl(sha1_hash const& ih, int listen_port, bool broadcast { m_disabled = true; #if defined TORRENT_LOGGING - if (m_log) fprintf(m_log, "%s failed to send message: (%d) %s" - , time_now_string(), ec.value(), ec.message().c_str()); + debug_log("failed to send message: (%d) %s", ec.value() + , ec.message().c_str()); #endif } } @@ -188,8 +174,8 @@ void lsd::announce_impl(sha1_hash const& ih, int listen_port, bool broadcast { m_disabled6 = true; #if defined TORRENT_LOGGING - if (m_log) fprintf(m_log, "%s failed to send message6: (%d) %s" - , time_now_string(), ec.value(), ec.message().c_str()); + debug_log("failed to send message6: (%d) %s", ec.value() + , ec.message().c_str()); #endif } } @@ -237,7 +223,7 @@ void lsd::on_announce(udp::endpoint const& from, char* buffer if (!p.header_finished() || error) { #if defined TORRENT_LOGGING - if (m_log) fprintf(m_log, "%s <== announce: incomplete HTTP message\n", time_now_string()); + debug_log("<== announce: incomplete HTTP message\n"); #endif return; } @@ -245,8 +231,7 @@ void lsd::on_announce(udp::endpoint const& from, char* buffer if (p.method() != "bt-search") { #if defined TORRENT_LOGGING - if (m_log) fprintf(m_log, "%s <== announce: invalid HTTP method: %s\n" - , time_now_string(), p.method().c_str()); + debug_log("<== announce: invalid HTTP method: %s\n", p.method().c_str()); #endif return; } @@ -255,8 +240,7 @@ void lsd::on_announce(udp::endpoint const& from, char* buffer if (port_str.empty()) { #if defined TORRENT_LOGGING - if (m_log) fprintf(m_log, "%s <== announce: invalid BT-SEARCH, missing port\n" - , time_now_string()); + debug_log("<== announce: invalid BT-SEARCH, missing port\n"); #endif return; } @@ -275,8 +259,8 @@ void lsd::on_announce(udp::endpoint const& from, char* buffer if (cookie == m_cookie) { #if defined TORRENT_LOGGING - if (m_log) fprintf(m_log, "%s <== announce: ignoring packet (cookie matched our own): %x == %x\n" - , time_now_string(), cookie, m_cookie); + debug_log("<== announce: ignoring packet (cookie matched our own): %x == %x\n" + , cookie, m_cookie); #endif return; } @@ -291,8 +275,8 @@ void lsd::on_announce(udp::endpoint const& from, char* buffer if (ih_str.size() != 40) { #if defined TORRENT_LOGGING - if (m_log) fprintf(m_log, "%s <== announce: invalid BT-SEARCH, invalid infohash: %s\n" - , time_now_string(), ih_str.c_str()); + debug_log("<== announce: invalid BT-SEARCH, invalid infohash: %s\n" + , ih_str.c_str()); #endif continue; } @@ -303,8 +287,8 @@ void lsd::on_announce(udp::endpoint const& from, char* buffer if (!ih.is_all_zeros() && port != 0) { #if defined TORRENT_LOGGING - if (m_log) fprintf(m_log, "%s *** incoming local announce %s:%d ih: %s\n" - , time_now_string(), print_address(from.address()).c_str() + debug_log("*** incoming local announce %s:%d ih: %s\n" + , print_address(from.address()).c_str() , port, ih_str.c_str()); #endif // we got an announce, pass it on through the callback diff --git a/src/session_impl.cpp b/src/session_impl.cpp index e03a7ec52..68932884f 100644 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -4279,7 +4279,6 @@ retry: char buf[1024]; vsnprintf(buf, sizeof(buf), fmt, v); - va_end(v); m_alerts.post_alert(log_alert(buf)); } @@ -6216,9 +6215,25 @@ retry: if (m_lsd) return; m_lsd = boost::make_shared(boost::ref(m_io_service) - , boost::bind(&session_impl::on_lsd_peer, this, _1, _2)); + , boost::bind(&session_impl::on_lsd_peer, this, _1, _2) +#if defined TORRENT_LOGGING + , boost::bind(&session_impl::on_lsd_log, this, _1) +#endif + ); + error_code ec; + m_lsd->start(ec); + if (ec && m_alerts.should_post()) + m_alerts.post_alert(lsd_error_alert(ec)); } +#if defined TORRENT_LOGGING + void session_impl::on_lsd_log(char const* log) + { + if (!m_alerts.should_post()) return; + m_alerts.post_alert(log_alert(log)); + } +#endif + natpmp* session_impl::start_natpmp() { INVARIANT_CHECK;