|
|
@ -405,63 +405,7 @@ namespace http |
|
|
|
|
|
|
|
|
|
|
|
namespace net |
|
|
|
namespace net |
|
|
|
{ |
|
|
|
{ |
|
|
|
#if defined(__linux__) || defined(__FreeBSD_kernel__) || defined(__APPLE__) || defined(__OpenBSD__) |
|
|
|
#ifdef WIN32 |
|
|
|
|
|
|
|
|
|
|
|
int GetMTUUnix(const boost::asio::ip::address& localAddress, int fallback) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
ifaddrs* ifaddr, *ifa = nullptr; |
|
|
|
|
|
|
|
if(getifaddrs(&ifaddr) == -1) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
LogPrint(eLogError, "NetIface: Can't call getifaddrs(): ", strerror(errno)); |
|
|
|
|
|
|
|
return fallback; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int family = 0; |
|
|
|
|
|
|
|
// look for interface matching local address
|
|
|
|
|
|
|
|
for(ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if(!ifa->ifa_addr) |
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
family = ifa->ifa_addr->sa_family; |
|
|
|
|
|
|
|
if(family == AF_INET && localAddress.is_v4()) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
sockaddr_in* sa = (sockaddr_in*) ifa->ifa_addr; |
|
|
|
|
|
|
|
if(!memcmp(&sa->sin_addr, localAddress.to_v4().to_bytes().data(), 4)) |
|
|
|
|
|
|
|
break; // address matches
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else if(family == AF_INET6 && localAddress.is_v6()) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
sockaddr_in6* sa = (sockaddr_in6*) ifa->ifa_addr; |
|
|
|
|
|
|
|
if(!memcmp(&sa->sin6_addr, localAddress.to_v6().to_bytes().data(), 16)) |
|
|
|
|
|
|
|
break; // address matches
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
int mtu = fallback; |
|
|
|
|
|
|
|
if(ifa && family) |
|
|
|
|
|
|
|
{ // interface found?
|
|
|
|
|
|
|
|
int fd = socket(family, SOCK_DGRAM, 0); |
|
|
|
|
|
|
|
if(fd > 0) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
ifreq ifr; |
|
|
|
|
|
|
|
strncpy(ifr.ifr_name, ifa->ifa_name, IFNAMSIZ); // set interface for query
|
|
|
|
|
|
|
|
if(ioctl(fd, SIOCGIFMTU, &ifr) >= 0) |
|
|
|
|
|
|
|
mtu = ifr.ifr_mtu; // MTU
|
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
LogPrint (eLogError, "NetIface: Failed to run ioctl: ", strerror(errno)); |
|
|
|
|
|
|
|
close(fd); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
LogPrint(eLogError, "NetIface: Failed to create datagram socket"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
LogPrint(eLogWarning, "NetIface: interface for local address", localAddress.to_string(), " not found"); |
|
|
|
|
|
|
|
freeifaddrs(ifaddr); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return mtu; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#elif defined(_WIN32) |
|
|
|
|
|
|
|
int GetMTUWindowsIpv4(sockaddr_in inputAddress, int fallback) |
|
|
|
int GetMTUWindowsIpv4(sockaddr_in inputAddress, int fallback) |
|
|
|
{ |
|
|
|
{ |
|
|
|
ULONG outBufLen = 0; |
|
|
|
ULONG outBufLen = 0; |
|
|
@ -593,6 +537,60 @@ namespace net |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
#else // assume unix
|
|
|
|
|
|
|
|
int GetMTUUnix(const boost::asio::ip::address& localAddress, int fallback) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
ifaddrs* ifaddr, *ifa = nullptr; |
|
|
|
|
|
|
|
if(getifaddrs(&ifaddr) == -1) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
LogPrint(eLogError, "NetIface: Can't call getifaddrs(): ", strerror(errno)); |
|
|
|
|
|
|
|
return fallback; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int family = 0; |
|
|
|
|
|
|
|
// look for interface matching local address
|
|
|
|
|
|
|
|
for(ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if(!ifa->ifa_addr) |
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
family = ifa->ifa_addr->sa_family; |
|
|
|
|
|
|
|
if(family == AF_INET && localAddress.is_v4()) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
sockaddr_in* sa = (sockaddr_in*) ifa->ifa_addr; |
|
|
|
|
|
|
|
if(!memcmp(&sa->sin_addr, localAddress.to_v4().to_bytes().data(), 4)) |
|
|
|
|
|
|
|
break; // address matches
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else if(family == AF_INET6 && localAddress.is_v6()) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
sockaddr_in6* sa = (sockaddr_in6*) ifa->ifa_addr; |
|
|
|
|
|
|
|
if(!memcmp(&sa->sin6_addr, localAddress.to_v6().to_bytes().data(), 16)) |
|
|
|
|
|
|
|
break; // address matches
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
int mtu = fallback; |
|
|
|
|
|
|
|
if(ifa && family) |
|
|
|
|
|
|
|
{ // interface found?
|
|
|
|
|
|
|
|
int fd = socket(family, SOCK_DGRAM, 0); |
|
|
|
|
|
|
|
if(fd > 0) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
ifreq ifr; |
|
|
|
|
|
|
|
strncpy(ifr.ifr_name, ifa->ifa_name, IFNAMSIZ); // set interface for query
|
|
|
|
|
|
|
|
if(ioctl(fd, SIOCGIFMTU, &ifr) >= 0) |
|
|
|
|
|
|
|
mtu = ifr.ifr_mtu; // MTU
|
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
LogPrint (eLogError, "NetIface: Failed to run ioctl: ", strerror(errno)); |
|
|
|
|
|
|
|
close(fd); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
LogPrint(eLogError, "NetIface: Failed to create datagram socket"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
LogPrint(eLogWarning, "NetIface: interface for local address", localAddress.to_string(), " not found"); |
|
|
|
|
|
|
|
freeifaddrs(ifaddr); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return mtu; |
|
|
|
|
|
|
|
} |
|
|
|
#endif // WIN32
|
|
|
|
#endif // WIN32
|
|
|
|
|
|
|
|
|
|
|
|
int GetMTU(const boost::asio::ip::address& localAddress) |
|
|
|
int GetMTU(const boost::asio::ip::address& localAddress) |
|
|
|