Example #1
0
	tcp::endpoint utp_socket_manager::local_endpoint(address const& remote, error_code& ec) const
	{
		tcp::endpoint socket_ep = m_sock.local_endpoint(ec);

		// first enumerate the routes in the routing table
		if (time_now() - m_last_route_update > seconds(60))
		{
			m_last_route_update = time_now();
			error_code ec;
			m_routes = enum_routes(m_sock.get_io_service(), ec);
			if (ec) return socket_ep;
		}

		if (m_routes.empty()) return socket_ep;
		// then find the best match
		ip_route* best = &m_routes[0];
		for (std::vector<ip_route>::iterator i = m_routes.begin()
			, end(m_routes.end()); i != end; ++i)
		{
			if (is_any(i->destination) && i->destination.is_v4() == remote.is_v4())
			{
				best = &*i;
				continue;
			}

			if (match_addr_mask(remote, i->destination, i->netmask))
			{
				best = &*i;
				continue;
			}
		}

		// best now tells us which interface we would send over
		// for this target. Now figure out what the local address
		// is for that interface

		if (time_now() - m_last_if_update > seconds(60))
		{
			m_last_if_update = time_now();
			error_code ec;
			m_interfaces = enum_net_interfaces(m_sock.get_io_service(), ec);
			if (ec) return socket_ep;
		}

		for (std::vector<ip_interface>::iterator i = m_interfaces.begin()
			, end(m_interfaces.end()); i != end; ++i)
		{
			if (i->interface_address.is_v4() != remote.is_v4())
				continue;

			if (strcmp(best->name, i->name) == 0)
				return tcp::endpoint(i->interface_address, socket_ep.port());
		}
		return socket_ep;
	}
	address get_default_gateway(io_service& ios, error_code& ec)
	{
		std::vector<ip_route> ret = enum_routes(ios, ec);
#if defined TORRENT_WINDOWS || defined TORRENT_MINGW
		std::vector<ip_route>::iterator i = std::find_if(ret.begin(), ret.end()
			, boost::bind(&is_loopback, boost::bind(&ip_route::destination, _1)));
#else
		std::vector<ip_route>::iterator i = std::find_if(ret.begin(), ret.end()
			, boost::bind(&ip_route::destination, _1) == address());
#endif
		if (i == ret.end()) return address();
		return i->gateway;
	}
Example #3
0
	void utp_socket_manager::mtu_for_dest(address const& addr, int& link_mtu, int& utp_mtu)
	{
		if (time_now() - m_last_route_update > seconds(60))
		{
			m_last_route_update = time_now();
			error_code ec;
			m_routes = enum_routes(m_sock.get_io_service(), ec);
		}

		int mtu = 0;
		if (!m_routes.empty())
		{
			for (std::vector<ip_route>::iterator i = m_routes.begin()
				, end(m_routes.end()); i != end; ++i)
			{
				if (!match_addr_mask(addr, i->destination, i->netmask)) continue;

				// assume that we'll actually use the route with the largest
				// MTU (seems like a reasonable assumption).
				// this could however be improved by using the route metrics
				// and the prefix length of the netmask to order the matches
				if (mtu < i->mtu) mtu = i->mtu;
			}
		}

		if (mtu == 0)
		{
			if (is_teredo(addr)) mtu = TORRENT_TEREDO_MTU;
			else mtu = TORRENT_ETHERNET_MTU;
		}

		// clamp the MTU within reasonable bounds
		if (mtu < TORRENT_INET_MIN_MTU) mtu = TORRENT_INET_MIN_MTU;
		else if (mtu > TORRENT_INET_MAX_MTU) mtu = TORRENT_INET_MAX_MTU;

		link_mtu = mtu;

		mtu -= TORRENT_UDP_HEADER;

		if (m_sock.get_proxy_settings().type == proxy_settings::socks5
			|| m_sock.get_proxy_settings().type == proxy_settings::socks5_pw)
		{
			// this is for the IP layer
			address proxy_addr = m_sock.proxy_addr().address();
			if (proxy_addr.is_v4()) mtu -= TORRENT_IPV4_HEADER;
			else mtu -= TORRENT_IPV6_HEADER;

			// this is for the SOCKS layer
			mtu -= TORRENT_SOCKS5_HEADER;

			// the address field in the SOCKS header
			if (addr.is_v4()) mtu -= 4;
			else mtu -= 16;

		}
		else
		{
			if (addr.is_v4()) mtu -= TORRENT_IPV4_HEADER;
			else mtu -= TORRENT_IPV6_HEADER;
		}

		utp_mtu = mtu;
	}