Ejemplo n.º 1
0
void find_data_observer::reply(msg const& m)
{
	bdecode_node r = m.message.dict_find_dict("r");
	if (!r)
	{
#ifndef TORRENT_DISABLE_LOGGING
		get_observer()->log(dht_logger::traversal, "[%u] missing response dict"
			, algorithm()->id());
#endif
		timeout();
		return;
	}

	bdecode_node id = r.dict_find_string("id");
	if (!id || id.string_length() != 20)
	{
#ifndef TORRENT_DISABLE_LOGGING
		get_observer()->log(dht_logger::traversal, "[%u] invalid id in response"
			, algorithm()->id());
#endif
		timeout();
		return;
	}
	bdecode_node token = r.dict_find_string("token");
	if (token)
	{
		static_cast<find_data*>(algorithm())->got_write_token(
			node_id(id.string_ptr()), token.string_value().to_string());
	}

	traversal_observer::reply(m);
	done();
}
Ejemplo n.º 2
0
void get_item_observer::reply(msg const& m)
{
	public_key pk;
	signature sig;
	sequence_number seq{0};

	bdecode_node const r = m.message.dict_find_dict("r");
	if (!r)
	{
#ifndef TORRENT_DISABLE_LOGGING
		get_observer()->log(dht_logger::traversal, "[%p] missing response dict"
			, static_cast<void*>(algorithm()));
#endif
		timeout();
		return;
	}

	bdecode_node const k = r.dict_find_string("k");
	if (k && k.string_length() == public_key::len)
		std::memcpy(pk.bytes.data(), k.string_ptr(), public_key::len);

	bdecode_node const s = r.dict_find_string("sig");
	if (s && s.string_length() == signature::len)
		std::memcpy(sig.bytes.data(), s.string_ptr(), signature::len);

	bdecode_node const q = r.dict_find_int("seq");
	if (q)
	{
		seq = sequence_number(q.int_value());
	}
	else if (k && s)
	{
		timeout();
		return;
	}

	bdecode_node v = r.dict_find("v");
	if (v)
	{
		static_cast<get_item*>(algorithm())->got_data(v, pk, seq, sig);
	}

	find_data_observer::reply(m);
}
Ejemplo n.º 3
0
        WHEN("0 last values are taken") {

            auto res = w.start(
            [xs]() {
                return xs
                       | rxo::take_last(0)
                       // forget type to workaround lambda deduction bug on msvc 2013
                       | rxo::as_dynamic();
            }
                       );

            THEN("the output only contains the completion event") {
                auto required = rxu::to_vector({
                    on.completed(250)
                });
                auto actual = res.get_observer().messages();
                REQUIRE(required == actual);
            }

            THEN("there was 1 subscription/unsubscription to the source") {
                auto required = rxu::to_vector({
                    on.subscribe(200, 250)
                });
                auto actual = xs.subscriptions();
                REQUIRE(required == actual);
            }

        }
    }
}
Ejemplo n.º 4
0
void traversal_observer::reply(msg const& m)
{
	bdecode_node r = m.message.dict_find_dict("r");
	if (!r)
	{
#ifndef TORRENT_DISABLE_LOGGING
		if (get_observer() != nullptr)
		{
			get_observer()->log(dht_logger::traversal
				, "[%p] missing response dict"
				, static_cast<void*>(algorithm()));
		}
#endif
		return;
	}

#ifndef TORRENT_DISABLE_LOGGING
	dht_observer* logger = get_observer();
	if (logger != nullptr && logger->should_log(dht_logger::traversal))
	{
		bdecode_node nid = r.dict_find_string("id");
		char hex_id[41];
		aux::to_hex({nid.string_ptr(), 20}, hex_id);
		logger->log(dht_logger::traversal
			, "[%p] RESPONSE id: %s invoke-count: %d addr: %s type: %s"
			, static_cast<void*>(algorithm()), hex_id, algorithm()->invoke_count()
			, print_endpoint(target_ep()).c_str(), algorithm()->name());
	}
#endif

	// look for nodes
#if TORRENT_USE_IPV6
	udp protocol = algorithm()->get_node().protocol();
#endif
	char const* nodes_key = algorithm()->get_node().protocol_nodes_key();
	bdecode_node n = r.dict_find_string(nodes_key);
	if (n)
	{
		char const* nodes = n.string_ptr();
		char const* end = nodes + n.string_length();

		while (end - nodes >= 20 + detail::address_size(protocol) + 2)
		{
			node_id id;
			std::copy(nodes, nodes + 20, id.begin());
			nodes += 20;
			udp::endpoint ep;
#if TORRENT_USE_IPV6
			if (protocol == udp::v6())
				ep = detail::read_v6_endpoint<udp::endpoint>(nodes);
			else
#endif
				ep = detail::read_v4_endpoint<udp::endpoint>(nodes);
			algorithm()->traverse(id, ep);
		}
	}

	bdecode_node id = r.dict_find_string("id");
	if (!id || id.string_length() != 20)
	{
#ifndef TORRENT_DISABLE_LOGGING
		if (get_observer() != nullptr)
		{
			get_observer()->log(dht_logger::traversal, "[%p] invalid id in response"
				, static_cast<void*>(algorithm()));
		}
#endif
		return;
	}

	// in case we didn't know the id of this peer when we sent the message to
	// it. For instance if it's a bootstrap node.
	set_id(node_id(id.string_ptr()));
}