forked from premiere/premiere-libtorrent
optimize logging of DHT packets by deferring copying and printing, to only do it if the alert category is enabled
This commit is contained in:
parent
27cbfa164e
commit
e44c8e9002
|
@ -2319,12 +2319,48 @@ namespace libtorrent
|
|||
int m_msg_idx;
|
||||
};
|
||||
|
||||
// This alert is posted every time a DHT message is sent or received. It is
|
||||
// only posted if the ``alert::dht_log_notification`` alert category is
|
||||
// enabled. It contains a verbatim copy of the message.
|
||||
struct TORRENT_EXPORT dht_pkt_alert : alert
|
||||
{
|
||||
enum direction_t
|
||||
{ incoming, outgoing };
|
||||
|
||||
dht_pkt_alert(aux::stack_allocator& alloc, char const* buf, int size
|
||||
, dht_pkt_alert::direction_t d, udp::endpoint ep);
|
||||
|
||||
static const int static_category = alert::dht_log_notification;
|
||||
TORRENT_DEFINE_ALERT(dht_pkt_alert, 86)
|
||||
|
||||
virtual std::string message() const;
|
||||
|
||||
// returns a pointer to the packet buffer and size of the packet,
|
||||
// respectively. This buffer is only valid for as long as the alert itself
|
||||
// is valid, which is owned by libtorrent and reclaimed whenever
|
||||
// pop_alerts() is called on the session.
|
||||
char const* pkt_buf() const;
|
||||
int pkt_size() const;
|
||||
|
||||
// whether this is an incoming or outgoing packet.
|
||||
direction_t dir;
|
||||
|
||||
// the DHT node we received this packet from, or sent this packet to
|
||||
// (depending on ``dir``).
|
||||
udp::endpoint node;
|
||||
|
||||
private:
|
||||
aux::stack_allocator& m_alloc;
|
||||
int m_msg_idx;
|
||||
int m_size;
|
||||
};
|
||||
|
||||
#undef TORRENT_DEFINE_ALERT_IMPL
|
||||
#undef TORRENT_DEFINE_ALERT
|
||||
#undef TORRENT_DEFINE_ALERT_PRIO
|
||||
#undef TORRENT_CLONE
|
||||
|
||||
enum { num_alert_types = 86 };
|
||||
enum { num_alert_types = 87 };
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -566,8 +566,8 @@ namespace libtorrent
|
|||
, sha1_hash const& sent_target, udp::endpoint const& ep) TORRENT_OVERRIDE;
|
||||
virtual void log(libtorrent::dht::dht_logger::module_t m, char const* fmt, ...)
|
||||
TORRENT_OVERRIDE TORRENT_FORMAT(3,4);
|
||||
virtual void log_message(message_direction_t dir, char const* pkt, int len
|
||||
, char const* fmt, ...) TORRENT_OVERRIDE TORRENT_FORMAT(5, 6);
|
||||
virtual void log_packet(message_direction_t dir, char const* pkt, int len
|
||||
, udp::endpoint node) TORRENT_OVERRIDE;
|
||||
|
||||
void set_external_address(address const& ip
|
||||
, int source_type, address const& source);
|
||||
|
|
|
@ -53,14 +53,12 @@ namespace libtorrent { namespace dht
|
|||
enum message_direction_t
|
||||
{
|
||||
incoming_message,
|
||||
outgoing_message,
|
||||
incoming_message_error,
|
||||
outgoing_message_error
|
||||
outgoing_message
|
||||
};
|
||||
|
||||
virtual void log(module_t m, char const* fmt, ...) TORRENT_FORMAT(3,4) = 0;
|
||||
virtual void log_message(message_direction_t dir, char const* pkt, int len
|
||||
, char const* fmt, ...) TORRENT_FORMAT(5, 6) = 0;
|
||||
virtual void log_packet(message_direction_t dir, char const* pkt, int len
|
||||
, udp::endpoint node) = 0;
|
||||
|
||||
protected:
|
||||
~dht_logger() {}
|
||||
|
|
|
@ -59,6 +59,14 @@ namespace libtorrent { namespace aux
|
|||
return ret;
|
||||
}
|
||||
|
||||
int copy_buffer(char const* buf, int size)
|
||||
{
|
||||
int ret = int(m_storage.size());
|
||||
m_storage.resize(ret + size);
|
||||
memcpy(&m_storage[ret], buf, size);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int allocate(int bytes)
|
||||
{
|
||||
int ret = int(m_storage.size());
|
||||
|
|
|
@ -1739,5 +1739,43 @@ namespace libtorrent {
|
|||
return ret;
|
||||
}
|
||||
|
||||
dht_pkt_alert::dht_pkt_alert(aux::stack_allocator& alloc
|
||||
, char const* buf, int size, dht_pkt_alert::direction_t d, udp::endpoint ep)
|
||||
: dir(d)
|
||||
, node(ep)
|
||||
, m_alloc(alloc)
|
||||
, m_msg_idx(alloc.copy_buffer(buf, size))
|
||||
, m_size(size)
|
||||
{}
|
||||
|
||||
char const* dht_pkt_alert::pkt_buf() const
|
||||
{
|
||||
return m_alloc.ptr(m_msg_idx);
|
||||
}
|
||||
|
||||
int dht_pkt_alert::pkt_size() const
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
std::string dht_pkt_alert::message() const
|
||||
{
|
||||
bdecode_node print;
|
||||
error_code ec;
|
||||
|
||||
// ignore errors here. This is best-effort. It may be a broken encoding
|
||||
// but at least we'll print the valid parts
|
||||
bdecode(pkt_buf(), pkt_buf() + pkt_size(), print, ec, NULL, 100, 100);
|
||||
|
||||
std::string msg = print_entry(print, true);
|
||||
|
||||
char const* prefix[2] = { "<==", "==>"};
|
||||
char buf[1024];
|
||||
snprintf(buf, sizeof(buf), "%s [%s] %s", prefix[dir]
|
||||
, print_endpoint(node).c_str(), msg.c_str());
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
} // namespace libtorrent
|
||||
|
||||
|
|
|
@ -403,10 +403,7 @@ namespace libtorrent { namespace dht
|
|||
if (ret != 0)
|
||||
{
|
||||
#ifndef TORRENT_DISABLE_LOGGING
|
||||
m_log->log_message(dht_logger::incoming_message_error, buf
|
||||
, size, "%s ERROR: %s pos: %d"
|
||||
, print_endpoint(ep).c_str(), err.message().c_str()
|
||||
, int(pos));
|
||||
m_log->log_packet(dht_logger::incoming_message, buf, size, ep);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
@ -414,9 +411,7 @@ namespace libtorrent { namespace dht
|
|||
if (m_msg.type() != bdecode_node::dict_t)
|
||||
{
|
||||
#ifndef TORRENT_DISABLE_LOGGING
|
||||
m_log->log_message(dht_logger::incoming_message_error, buf
|
||||
, size, "%s ERROR: not a dictionary"
|
||||
, print_endpoint(ep).c_str());
|
||||
m_log->log_packet(dht_logger::incoming_message, buf, size, ep);
|
||||
#endif
|
||||
// it's not a good idea to send invalid messages
|
||||
// especially not in response to an invalid message
|
||||
|
@ -427,8 +422,8 @@ namespace libtorrent { namespace dht
|
|||
}
|
||||
|
||||
#ifndef TORRENT_DISABLE_LOGGING
|
||||
m_log->log_message(dht_logger::incoming_message, buf
|
||||
, size, "%s", print_endpoint(ep).c_str());
|
||||
m_log->log_packet(dht_logger::incoming_message, buf
|
||||
, size, ep);
|
||||
#endif
|
||||
|
||||
libtorrent::dht::msg m(m_msg, ep);
|
||||
|
@ -523,9 +518,8 @@ namespace libtorrent { namespace dht
|
|||
{
|
||||
m_counters.inc_stats_counter(counters::dht_messages_out_dropped);
|
||||
#ifndef TORRENT_DISABLE_LOGGING
|
||||
m_log->log_message(dht_logger::outgoing_message, &m_send_buf[0]
|
||||
, m_send_buf.size(), "%s DROPPED (%s)"
|
||||
, print_endpoint(addr).c_str(), ec.message().c_str());
|
||||
m_log->log_packet(dht_logger::outgoing_message, &m_send_buf[0]
|
||||
, m_send_buf.size(), addr);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
@ -536,9 +530,8 @@ namespace libtorrent { namespace dht
|
|||
, addr.address().is_v6() ? 48 : 28);
|
||||
m_counters.inc_stats_counter(counters::dht_messages_out);
|
||||
#ifndef TORRENT_DISABLE_LOGGING
|
||||
m_log->log_message(dht_logger::outgoing_message, &m_send_buf[0]
|
||||
, m_send_buf.size(), "%s"
|
||||
, print_endpoint(addr).c_str());
|
||||
m_log->log_packet(dht_logger::outgoing_message, &m_send_buf[0]
|
||||
, m_send_buf.size(), addr);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
@ -547,9 +540,8 @@ namespace libtorrent { namespace dht
|
|||
m_counters.inc_stats_counter(counters::dht_messages_out_dropped);
|
||||
|
||||
#ifndef TORRENT_DISABLE_LOGGING
|
||||
m_log->log_message(dht_logger::outgoing_message, &m_send_buf[0]
|
||||
, m_send_buf.size(), "%s"
|
||||
, print_endpoint(addr).c_str());
|
||||
m_log->log_packet(dht_logger::outgoing_message, &m_send_buf[0]
|
||||
, m_send_buf.size(), addr);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -6493,43 +6493,15 @@ retry:
|
|||
m_alerts.emplace_alert<dht_log_alert>((dht_log_alert::dht_module_t)m, buf);
|
||||
}
|
||||
|
||||
TORRENT_FORMAT(5, 6)
|
||||
void session_impl::log_message(message_direction_t dir, char const* pkt, int len
|
||||
, char const* fmt, ...)
|
||||
void session_impl::log_packet(message_direction_t dir, char const* pkt, int len
|
||||
, udp::endpoint node)
|
||||
{
|
||||
if (!m_alerts.should_post<dht_log_alert>()) return;
|
||||
if (!m_alerts.should_post<dht_pkt_alert>()) return;
|
||||
|
||||
char buf[1024];
|
||||
int offset = 0;
|
||||
char const* prefix[] =
|
||||
{ "<== ", "==> ", "<== ERROR ", "==> ERROR " };
|
||||
offset += snprintf(&buf[offset], sizeof(buf) - offset, prefix[dir]);
|
||||
dht_pkt_alert::direction_t d = dir == dht_logger::incoming_message
|
||||
? dht_pkt_alert::incoming : dht_pkt_alert::outgoing;
|
||||
|
||||
va_list v;
|
||||
va_start(v, fmt);
|
||||
offset += vsnprintf(&buf[offset], sizeof(buf) - offset, fmt, v);
|
||||
va_end(v);
|
||||
|
||||
if (offset < sizeof(buf) - 1)
|
||||
{
|
||||
buf[offset++] = ' ';
|
||||
|
||||
bdecode_node print;
|
||||
error_code ec;
|
||||
|
||||
// ignore errors here. This is best-effort. It may be a broken encoding
|
||||
// but at least we'll print the valid parts
|
||||
bdecode(pkt, pkt + len, print, ec, NULL, 100, 100);
|
||||
|
||||
// TODO: 3 there should be a separate dht_log_alert for messages that
|
||||
// contains the raw packet separately. This printing should be moved
|
||||
// down to the ::message() function of that alert
|
||||
std::string msg = print_entry(print, true);
|
||||
|
||||
strncpy(&buf[offset], msg.c_str(), sizeof(buf) - offset);
|
||||
}
|
||||
|
||||
m_alerts.emplace_alert<dht_log_alert>(dht_log_alert::tracker, buf);
|
||||
m_alerts.emplace_alert<dht_pkt_alert>(pkt, len, d, node);
|
||||
}
|
||||
|
||||
void session_impl::set_external_address(address const& ip
|
||||
|
|
|
@ -434,8 +434,8 @@ struct obs : dht::dht_observer
|
|||
, sha1_hash const& sent_target, udp::endpoint const& ep) TORRENT_OVERRIDE {}
|
||||
virtual void announce(sha1_hash const& ih, address const& addr, int port) TORRENT_OVERRIDE {}
|
||||
virtual void log(dht_logger::module_t l, char const* fmt, ...) TORRENT_OVERRIDE {}
|
||||
virtual void log_message(message_direction_t dir, char const* pkt, int len
|
||||
, char const* fmt, ...) TORRENT_OVERRIDE {}
|
||||
virtual void log_packet(message_direction_t dir, char const* pkt, int len
|
||||
, udp::endpoint node) TORRENT_OVERRIDE {}
|
||||
};
|
||||
|
||||
// TODO: test obfuscated_get_peers
|
||||
|
|
|
@ -37,6 +37,9 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/kademlia/dos_blocker.hpp"
|
||||
#include "libtorrent/kademlia/dht_observer.hpp"
|
||||
#include "libtorrent/error_code.hpp"
|
||||
#include "libtorrent/socket_io.hpp" // for print_endpoint
|
||||
|
||||
using namespace libtorrent;
|
||||
|
||||
struct log_t : libtorrent::dht::dht_logger
|
||||
{
|
||||
|
@ -49,31 +52,25 @@ struct log_t : libtorrent::dht::dht_logger
|
|||
va_end(v);
|
||||
}
|
||||
|
||||
virtual void log_message(message_direction_t dir, char const* pkt, int len
|
||||
, char const* fmt, ...) TORRENT_OVERRIDE TORRENT_FORMAT(5, 6)
|
||||
virtual void log_packet(message_direction_t dir, char const* pkt, int len
|
||||
, udp::endpoint node) TORRENT_OVERRIDE
|
||||
{
|
||||
char const* prefix[] =
|
||||
{ "<== ", "<== ERROR ", "==> ", "==> ERROR " };
|
||||
printf(prefix[dir]);
|
||||
|
||||
va_list v;
|
||||
va_start(v, fmt);
|
||||
vprintf(fmt, v);
|
||||
va_end(v);
|
||||
|
||||
libtorrent::bdecode_node print;
|
||||
libtorrent::error_code ec;
|
||||
int ret = bdecode(pkt, pkt + len, print, ec, NULL, 100, 100);
|
||||
|
||||
std::string msg = print_entry(print, true);
|
||||
printf("%s", msg.c_str());
|
||||
|
||||
char const* prefix[2] = { "<==", "==>"};
|
||||
printf("%s [%s] %s", prefix[dir], print_endpoint(node).c_str()
|
||||
, msg.c_str());
|
||||
}
|
||||
};
|
||||
|
||||
int test_main()
|
||||
{
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
using namespace libtorrent;
|
||||
using namespace libtorrent::dht;
|
||||
|
||||
log_t l;
|
||||
|
|
Loading…
Reference in New Issue