Exemple #1
0
	dht_direct_response_alert::dht_direct_response_alert(
		aux::stack_allocator& alloc, void* userdata_
		, udp::endpoint const& addr_, bdecode_node const& response)
		: userdata(userdata_), addr(addr_), m_alloc(alloc)
		, m_response_idx(alloc.copy_buffer(response.data_section().first, response.data_section().second))
		, m_response_size(response.data_section().second)
	{}
Exemple #2
0
bool item::assign(bdecode_node const& v, span<char const> salt
	, sequence_number const seq, public_key const& pk, signature const& sig)
{
	TORRENT_ASSERT(v.data_section().size() <= 1000);
	if (!verify_mutable_item(v.data_section(), salt, seq, pk, sig))
		return false;
	m_pk = pk;
	m_sig = sig;
	if (salt.size() > 0)
		m_salt.assign(salt.data(), salt.size());
	else
		m_salt.clear();
	m_seq = seq;
	m_mutable = true;

	m_value = v;
	return true;
}
void get_item::got_data(bdecode_node const& v,
	public_key const& pk,
	sequence_number const seq,
	signature const& sig)
{
	// we received data!
	// if no data_callback, we needn't care about the data we get.
	// only put_immutable_item no data_callback
	if (!m_data_callback) return;

	// for get_immutable_item
	if (m_immutable)
	{
		// If m_data isn't empty, we should have post alert.
		if (!m_data.empty()) return;

		sha1_hash incoming_target = item_target_id(v.data_section());
		if (incoming_target != target()) return;

		m_data.assign(v);

		// There can only be one true immutable item with a given id
		// Now that we've got it and the user doesn't want to do a put
		// there's no point in continuing to query other nodes
		m_data_callback(m_data, true);
		done();

		return;
	}

	// immutable data should have been handled before this line, only mutable
	// data can reach here, which means pk, sig and seq must be valid.

	std::string const salt_copy(m_data.salt());
	sha1_hash const incoming_target = item_target_id(salt_copy, pk);
	if (incoming_target != target()) return;

	// this is mutable data. If it passes the signature
	// check, remember it. Just keep the version with
	// the highest sequence number.
	if (m_data.empty() || m_data.seq() < seq)
	{
		if (!m_data.assign(v, salt_copy, seq, pk, sig))
			return;

		// for get_item, we should call callback when we get data,
		// even if the date is not authoritative, we can update later.
		// so caller can get response ASAP without waiting transaction
		// time-out (15 seconds).
		// for put_item, the callback function will do nothing
		// if the data is non-authoritative.
		m_data_callback(m_data, false);
	}
}
Exemple #4
0
bool item::assign(bdecode_node const& v
                  , std::pair<char const*, int> salt
                  , boost::uint64_t seq, char const* pk, char const* sig)
{
    TORRENT_ASSERT(v.data_section().second <= 1000);
    if (pk && sig)
    {
        if (!verify_mutable_item(v.data_section(), salt, seq, pk, sig))
            return false;
        memcpy(m_pk.c_array(), pk, item_pk_len);
        memcpy(m_sig.c_array(), sig, item_sig_len);
        if (salt.second > 0)
            m_salt.assign(salt.first, salt.second);
        else
            m_salt.clear();
        m_seq = seq;
        m_mutable = true;
    }
    else
        m_mutable = false;

    m_value = v;
    return true;
}