Пример #1
0
bool dht_tracker::incoming_packet(udp::endpoint const& ep
                                  , span<char const> const buf)
{
    int const buf_size = int(buf.size());
    if (buf_size <= 20
            || buf.front() != 'd'
            || buf.back() != 'e') return false;

    m_counters.inc_stats_counter(counters::dht_bytes_in, buf_size);
    // account for IP and UDP overhead
    m_counters.inc_stats_counter(counters::recv_ip_overhead_bytes
                                 , ep.address().is_v6() ? 48 : 28);
    m_counters.inc_stats_counter(counters::dht_messages_in);

    if (m_settings.ignore_dark_internet && ep.address().is_v4())
    {
        address_v4::bytes_type b = ep.address().to_v4().to_bytes();

        // these are class A networks not available to the public
        // if we receive messages from here, that seems suspicious
        static std::uint8_t const class_a[] = { 3, 6, 7, 9, 11, 19, 21, 22, 25
                                                , 26, 28, 29, 30, 33, 34, 48, 51, 56
                                              };

        if (std::find(std::begin(class_a), std::end(class_a), b[0]) != std::end(class_a))
        {
            m_counters.inc_stats_counter(counters::dht_messages_in_dropped);
            return true;
        }
    }

    if (!m_blocker.incoming(ep.address(), clock_type::now(), m_log))
    {
        m_counters.inc_stats_counter(counters::dht_messages_in_dropped);
        return true;
    }

    TORRENT_ASSERT(buf_size > 0);

    int pos;
    error_code err;
    int ret = bdecode(buf.data(), buf.data() + buf_size, m_msg, err, &pos, 10, 500);
    if (ret != 0)
    {
        m_counters.inc_stats_counter(counters::dht_messages_in_dropped);
#ifndef TORRENT_DISABLE_LOGGING
        m_log->log_packet(dht_logger::incoming_message, buf, ep);
#endif
        return false;
    }

    if (m_msg.type() != bdecode_node::dict_t)
    {
        m_counters.inc_stats_counter(counters::dht_messages_in_dropped);
#ifndef TORRENT_DISABLE_LOGGING
        m_log->log_packet(dht_logger::incoming_message, buf, ep);
#endif
        // it's not a good idea to send a response to an invalid messages
        return false;
    }

#ifndef TORRENT_DISABLE_LOGGING
    m_log->log_packet(dht_logger::incoming_message, buf, ep);
#endif

    libtorrent::dht::msg m(m_msg, ep);
    m_dht.incoming(m);
#if TORRENT_USE_IPV6
    m_dht6.incoming(m);
#endif
    return true;
}