コード例 #1
0
	void dht_tracker::start(entry const& bootstrap)
	{
		std::vector<udp::endpoint> initial_nodes;

		if (bootstrap.type() == entry::dictionary_t)
		{
			try
			{
			if (entry const* nodes = bootstrap.find_key("nodes"))
				read_endpoint_list<udp::endpoint>(nodes, initial_nodes);
			} catch (std::exception&) {}
		}

		error_code ec;
		m_timer.expires_from_now(seconds(1), ec);
		m_timer.async_wait(bind(&dht_tracker::tick, self(), _1));

		m_connection_timer.expires_from_now(seconds(10), ec);
		m_connection_timer.async_wait(
			bind(&dht_tracker::connection_timeout, self(), _1));

		m_refresh_timer.expires_from_now(seconds(5), ec);
		m_refresh_timer.async_wait(bind(&dht_tracker::refresh_timeout, self(), _1));

		m_dht.bootstrap(initial_nodes, boost::bind(&dht_tracker::on_bootstrap, self()));
	}
コード例 #2
0
	void extract_single_file(const entry& dict, file_entry& target
		, std::string const& root_dir)
	{
		target.size = dict["length"].integer();
		target.path = root_dir;


		// prefer the name.utf-8
		// because if it exists, it is more
		// likely to be correctly encoded

		const entry::list_type* list = 0;
		if (entry const* p = dict.find_key("path.utf-8"))
		{
			list = &p->list();
		}
		else
		{
			list = &dict["path"].list();
		}

		for (entry::list_type::const_iterator i = list->begin();
			i != list->end(); ++i)
		{
			if (i->string() != "..")
				target.path /= i->string();
		}
		verify_encoding(target);
		if (target.path.is_complete()) throw std::runtime_error("torrent contains "
			"a file with an absolute path: '"
			+ target.path.native_file_string() + "'");
	}
コード例 #3
0
	bool http_tracker_connection::extract_peer_info(const entry& info, peer_entry& ret)
	{
		// extract peer id (if any)
		if (info.type() != entry::dictionary_t)
		{
			fail(-1, "invalid response from tracker (invalid peer entry)");
			return false;
		}
		entry const* i = info.find_key("peer id");
		if (i != 0)
		{
			if (i->type() != entry::string_t || i->string().length() != 20)
			{
				fail(-1, "invalid response from tracker (invalid peer id)");
				return false;
			}
			std::copy(i->string().begin(), i->string().end(), ret.pid.begin());
		}
		else
		{
			// if there's no peer_id, just initialize it to a bunch of zeroes
			std::fill_n(ret.pid.begin(), 20, 0);
		}

		// extract ip
		i = info.find_key("ip");
		if (i == 0 || i->type() != entry::string_t)
		{
			fail(-1, "invalid response from tracker");
			return false;
		}
		ret.ip = i->string();

		// extract port
		i = info.find_key("port");
		if (i == 0 || i->type() != entry::int_t)
		{
			fail(-1, "invalid response from tracker");
			return false;
		}
		ret.port = (unsigned short)i->integer();

		return true;
	}
コード例 #4
0
void dht_tracker::start(entry const& bootstrap)
{
    std::vector<udp::endpoint> initial_nodes;

    if (bootstrap.type() == entry::dictionary_t)
    {
        TORRENT_TRY {
            if (entry const* nodes = bootstrap.find_key("nodes"))
                read_endpoint_list<udp::endpoint>(nodes, initial_nodes);
        } TORRENT_CATCH(std::exception&) {}
    }
コード例 #5
0
ファイル: dht_tracker.cpp プロジェクト: hejin/libtorrent
	void dht_tracker::start(entry const& bootstrap
		, find_data::nodes_callback const& f)
	{
		std::vector<udp::endpoint> initial_nodes;
#if TORRENT_USE_IPV6
		std::vector<udp::endpoint> initial_nodes6;
#endif

		if (bootstrap.type() == entry::dictionary_t)
		{
			TORRENT_TRY {
				if (entry const* nodes = bootstrap.find_key("nodes"))
					read_endpoint_list<udp::endpoint>(nodes, initial_nodes);
			} TORRENT_CATCH(std::exception&) {}
#if TORRENT_USE_IPV6
			TORRENT_TRY{
				if (entry const* nodes = bootstrap.find_key("nodes6"))
					read_endpoint_list<udp::endpoint>(nodes, initial_nodes6);
			} TORRENT_CATCH(std::exception&) {}
#endif
		}
コード例 #6
0
ファイル: dht_tracker.cpp プロジェクト: kknet/PopcornTV
void dht_tracker::start(entry const& bootstrap
                        , find_data::nodes_callback const& f)
{
    TORRENT_ASSERT(m_ses.is_network_thread());
    std::vector<udp::endpoint> initial_nodes;

    if (bootstrap.type() == entry::dictionary_t)
    {
        TORRENT_TRY {
            if (entry const* nodes = bootstrap.find_key("nodes"))
                read_endpoint_list<udp::endpoint>(nodes, initial_nodes);
        } TORRENT_CATCH(std::exception&) {}
    }
コード例 #7
0
	// class that puts the networking and the kademlia node in a single
	// unit and connecting them together.
	dht_tracker::dht_tracker(asio::io_service& ios, dht_settings const& settings
		, asio::ip::address listen_interface, entry const& bootstrap)
		: m_strand(ios)
		, m_socket(ios, udp::endpoint(listen_interface, settings.service_port))
		, m_dht(bind(&dht_tracker::send_packet, this, _1), settings
			, read_id(bootstrap))
		, m_buffer(0)
		, m_last_new_key(time_now() - minutes(key_refresh))
		, m_timer(ios)
		, m_connection_timer(ios)
		, m_refresh_timer(ios)
		, m_settings(settings)
		, m_refresh_bucket(160)
		, m_abort(false)
		, m_host_resolver(ios)
		, m_refs(0)
	{
		using boost::bind;

		m_in_buf[0].resize(1000);
		m_in_buf[1].resize(1000);
#ifdef TORRENT_DHT_VERBOSE_LOGGING
		m_counter = 0;
		std::fill_n(m_replies_bytes_sent, 5, 0);
		std::fill_n(m_queries_bytes_received, 5, 0);
		std::fill_n(m_replies_sent, 5, 0);
		std::fill_n(m_queries_received, 5, 0);
		m_announces = 0;
		m_failed_announces = 0;
		m_total_message_input = 0;
		m_ut_message_input = 0;
		m_lt_message_input = 0;
		m_mp_message_input = 0;
		m_gr_message_input = 0;
		m_mo_message_input = 0;
		m_total_in_bytes = 0;
		m_total_out_bytes = 0;
		m_queries_out_bytes = 0;
		
		// turns on and off individual components' logging

//		rpc_log().enable(false);
//		node_log().enable(false);
//		traversal_log().enable(false);
//		dht_tracker_log.enable(false);

#endif
		std::vector<udp::endpoint> initial_nodes;

		if (bootstrap.type() == entry::dictionary_t)
		{
			try
			{
			if (entry const* nodes = bootstrap.find_key("nodes"))
				read_endpoint_list<udp::endpoint>(nodes, initial_nodes);
			} catch (std::exception&) {}
		}

		m_socket.async_receive_from(asio::buffer(&m_in_buf[m_buffer][0]
			, m_in_buf[m_buffer].size()), m_remote_endpoint[m_buffer]
			, m_strand.wrap(bind(&dht_tracker::on_receive, self(), _1, _2)));
		m_timer.expires_from_now(seconds(1));
		m_timer.async_wait(m_strand.wrap(bind(&dht_tracker::tick, self(), _1)));

		m_connection_timer.expires_from_now(seconds(10));
		m_connection_timer.async_wait(m_strand.wrap(
			bind(&dht_tracker::connection_timeout, self(), _1)));

		m_refresh_timer.expires_from_now(seconds(5));
		m_refresh_timer.async_wait(m_strand.wrap(bind(&dht_tracker::refresh_timeout, self(), _1)));

		m_dht.bootstrap(initial_nodes, bind(&dht_tracker::on_bootstrap, self()));
	}
コード例 #8
0
	void http_tracker_connection::parse(int status_code, entry const& e)
	{
		boost::shared_ptr<request_callback> cb = requester();
		if (!cb) return;

		// parse the response
		entry const* failure = e.find_key("failure reason");
		if (failure && failure->type() == entry::string_t)
		{
			fail(status_code, failure->string().c_str());
			return;
		}

		entry const* warning = e.find_key("warning message");
		if (warning && warning->type() == entry::string_t)
		{
			cb->tracker_warning(tracker_req(), warning->string());
		}

		std::vector<peer_entry> peer_list;

		if (tracker_req().kind == tracker_request::scrape_request)
		{
			std::string ih = tracker_req().info_hash.to_string();

			entry const* files = e.find_key("files");
			if (files == 0 || files->type() != entry::dictionary_t)
			{
				fail(-1, "invalid or missing 'files' entry in scrape response");
				return;
			}

			entry const* scrape_data = files->find_key(ih);
			if (scrape_data == 0 || scrape_data->type() != entry::dictionary_t)
			{
				fail(-1, "missing or invalid info-hash entry in scrape response");
				return;
			}
			entry const* complete = scrape_data->find_key("complete");
			entry const* incomplete = scrape_data->find_key("incomplete");
			entry const* downloaded = scrape_data->find_key("downloaded");
			if (complete == 0 || incomplete == 0 || downloaded == 0
				|| complete->type() != entry::int_t
				|| incomplete->type() != entry::int_t
				|| downloaded->type() != entry::int_t)
			{
				fail(-1, "missing 'complete' or 'incomplete' entries in scrape response");
				return;
			}
			cb->tracker_scrape_response(tracker_req(), int(complete->integer())
				, int(incomplete->integer()), int(downloaded->integer()));
			return;
		}

		entry const* interval = e.find_key("interval");
		if (interval == 0 || interval->type() != entry::int_t)
		{
			fail(-1, "missing or invalid 'interval' entry in tracker response");
			return;
		}

		entry const* peers_ent = e.find_key("peers");
		if (peers_ent && peers_ent->type() == entry::string_t)
		{
			std::string const& peers = peers_ent->string();
			for (std::string::const_iterator i = peers.begin();
				i != peers.end();)
			{
				if (std::distance(i, peers.end()) < 6) break;

				peer_entry p;
				p.pid.clear();
				error_code ec;
				p.ip = detail::read_v4_address(i).to_string(ec);
				if (ec) continue;
				p.port = detail::read_uint16(i);
				peer_list.push_back(p);
			}
		}
		else if (peers_ent && peers_ent->type() == entry::list_t)
		{
			entry::list_type const& l = peers_ent->list();
			for(entry::list_type::const_iterator i = l.begin(); i != l.end(); ++i)
			{
				peer_entry p;
				if (!extract_peer_info(*i, p)) return;
				peer_list.push_back(p);
			}
		}
		else
		{
			peers_ent = 0;
		}

		entry const* ipv6_peers = e.find_key("peers6");
		if (ipv6_peers && ipv6_peers->type() == entry::string_t)
		{
			std::string const& peers = ipv6_peers->string();
			for (std::string::const_iterator i = peers.begin();
				i != peers.end();)
			{
				if (std::distance(i, peers.end()) < 18) break;

				peer_entry p;
				p.pid.clear();
				error_code ec;
				p.ip = detail::read_v6_address(i).to_string(ec);
				if (ec) continue;
				p.port = detail::read_uint16(i);
				peer_list.push_back(p);
			}
		}
		else
		{
			ipv6_peers = 0;
		}

		if (peers_ent == 0 && ipv6_peers == 0)
		{
			fail(-1, "missing 'peers' and 'peers6' entry in tracker response");
			return;
		}


		// look for optional scrape info
		int complete = -1;
		int incomplete = -1;
		address external_ip;

		entry const* ip_ent = e.find_key("external ip");
		if (ip_ent && ip_ent->type() == entry::string_t)
		{
			std::string const& ip = ip_ent->string();
			char const* p = &ip[0];
			if (ip.size() == address_v4::bytes_type::static_size)
				external_ip = detail::read_v4_address(p);
			else if (ip.size() == address_v6::bytes_type::static_size)
				external_ip = detail::read_v6_address(p);
		}
		
		entry const* complete_ent = e.find_key("complete");
		if (complete_ent && complete_ent->type() == entry::int_t)
			complete = int(complete_ent->integer());

		entry const* incomplete_ent = e.find_key("incomplete");
		if (incomplete_ent && incomplete_ent->type() == entry::int_t)
			incomplete = int(incomplete_ent->integer());

		cb->tracker_response(tracker_req(), peer_list, interval->integer(), complete
			, incomplete, external_ip);
	}