support source-hint from routing table, where supported

This commit is contained in:
arvidn 2020-01-19 23:22:39 +01:00 committed by Arvid Norberg
parent bc0274ed6a
commit 208d71ba77
3 changed files with 12 additions and 2 deletions

View File

@ -74,6 +74,7 @@ namespace libtorrent {
address destination;
address netmask;
address gateway;
address source_hint;
char name[64]{};
int mtu;
};

View File

@ -281,6 +281,9 @@ namespace {
case RTA_DST:
rt_info->destination = to_address(rt_msg->rtm_family, RTA_DATA(rt_attr));
break;
case RTA_PREFSRC:
rt_info->source_hint = to_address(rt_msg->rtm_family, RTA_DATA(rt_attr));
break;
}
}
#ifdef __clang__
@ -396,6 +399,7 @@ int _System __libsocket_sysctl(int* mib, u_int namelen, void *oldp, size_t *oldl
rt_info->netmask = sockaddr_to_address(rti_info[RTAX_NETMASK]
, rt_info->destination.is_v4() ? AF_INET : AF_INET6);
if_indextoname(rtm->rtm_index, rt_info->name);
if (rti_info[RTAX_IFA]) rt_info->source_hint = sockaddr_to_address(rti_info[RTAX_IFA]);
return true;
}
#endif
@ -798,6 +802,10 @@ int _System __libsocket_sysctl(int* mib, u_int namelen, void *oldp, size_t *oldl
// interface, but they are addressed by the local network address
// space. So this check only works for IPv4.
&& (!v4 || match_addr_mask(r.gateway, iface.interface_address, iface.netmask))
// in case there are multiple networks on the same networking
// device, the source hint may be the only thing telling them
// apart
&& (r.source_hint.is_unspecified() || r.source_hint == iface.interface_address)
&& strcmp(r.name, iface.name) == 0;
});
if (it != routes.end()) return it->gateway;

View File

@ -50,15 +50,16 @@ int main()
return 1;
}
std::printf("%-18s%-18s%-35s%-7sinterface\n", "destination", "network", "gateway", "mtu");
std::printf("%-18s%-18s%-35s%-7s%-18sinterface\n", "destination", "network", "gateway", "mtu", "source-hint");
for (auto const& r : routes)
{
std::printf("%-18s%-18s%-35s%-7d%s\n"
std::printf("%-18s%-18s%-35s%-7d%-18s%s\n"
, r.destination.to_string(ec).c_str()
, r.netmask.to_string(ec).c_str()
, r.gateway.is_unspecified() ? "-" : r.gateway.to_string(ec).c_str()
, r.mtu
, r.source_hint.is_unspecified() ? "-" : r.source_hint.to_string(ec).c_str()
, r.name);
}