void utp_socket_manager::mtu_for_dest(address const& addr, int& link_mtu, int& utp_mtu) { int mtu = 0; if (is_teredo(addr)) mtu = TORRENT_TEREDO_MTU; else mtu = TORRENT_ETHERNET_MTU; #if defined __APPLE__ // apple has a very strange loopback. It appears you can't // send messages of the reported MTU size, and you don't get // EWOULDBLOCK either. if (is_loopback(addr)) { if (is_teredo(addr)) mtu = TORRENT_TEREDO_MTU; else mtu = TORRENT_ETHERNET_MTU; } #endif // 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 == settings_pack::socks5 || m_sock.get_proxy_settings().type == settings_pack::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 = (std::min)(mtu, restrict_mtu()); }
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; }