Network: Fix posix implementation
This commit is contained in:
parent
d827477de2
commit
cb1bc956b2
|
|
@ -13,64 +13,6 @@
|
|||
|
||||
namespace Nz
|
||||
{
|
||||
namespace Detail
|
||||
{
|
||||
using addrinfoImpl = addrinfo;
|
||||
|
||||
int GetAddressInfo(const std::string& hostname, const std::string& service, const addrinfoImpl* hints, addrinfoImpl** results)
|
||||
{
|
||||
return getaddrinfo(hostname.c_str(), service.c_str(), hints, results);
|
||||
}
|
||||
|
||||
int GetHostnameInfo(sockaddr* socketAddress, socklen_t socketLen, std::string* hostname, std::string* service, int flags)
|
||||
{
|
||||
std::array<char, NI_MAXHOST> hostnameBuffer;
|
||||
std::array<char, NI_MAXSERV> serviceBuffer;
|
||||
|
||||
int result = getnameinfo(socketAddress, socketLen, hostnameBuffer.data(), hostnameBuffer.size(), serviceBuffer.data(), serviceBuffer.size(), flags);
|
||||
if (result == 0)
|
||||
{
|
||||
if (hostname)
|
||||
hostname->assign(hostnameBuffer.data());
|
||||
|
||||
if (service)
|
||||
service->assign(serviceBuffer.data());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void FreeAddressInfo(addrinfoImpl* results)
|
||||
{
|
||||
freeaddrinfo(results);
|
||||
}
|
||||
|
||||
IpAddress::IPv4 convertSockaddrToIPv4(const in_addr& addr)
|
||||
{
|
||||
union byteToInt
|
||||
{
|
||||
UInt8 b[sizeof(uint32_t)];
|
||||
uint32_t i;
|
||||
};
|
||||
|
||||
byteToInt hostOrder;
|
||||
hostOrder.i = ntohl(addr.s_addr);
|
||||
|
||||
return { {hostOrder.b[3], hostOrder.b[2], hostOrder.b[1], hostOrder.b[0]} };
|
||||
}
|
||||
|
||||
IpAddress::IPv6 convertSockaddr6ToIPv6(const in6_addr& addr)
|
||||
{
|
||||
auto& rawIpV6 = addr.s6_addr;
|
||||
|
||||
IpAddress::IPv6 ipv6;
|
||||
for (unsigned int i = 0; i < 8; ++i)
|
||||
ipv6[i] = Nz::UInt16(rawIpV6[i * 2]) << 8 | rawIpV6[i * 2 + 1];
|
||||
|
||||
return ipv6;
|
||||
}
|
||||
}
|
||||
|
||||
IpAddress IpAddressImpl::FromAddrinfo(const addrinfo* info)
|
||||
{
|
||||
switch (info->ai_family)
|
||||
|
|
@ -109,14 +51,21 @@ namespace Nz
|
|||
|
||||
IpAddress IpAddressImpl::FromSockAddr(const sockaddr_in* addressv4)
|
||||
{
|
||||
IpAddress::IPv4 ip4Address = Detail::convertSockaddrToIPv4(addressv4->sin_addr);
|
||||
return IpAddress(ip4Address, ntohs(addressv4->sin_port));
|
||||
IpAddress::IPv4 ipv4;
|
||||
std::memcpy(&ipv4[0], &addressv4->sin_addr.s_addr, sizeof(uint32_t)); //< addr.s_addr is in big-endian so its already correctly ordered
|
||||
|
||||
return IpAddress(ipv4, ntohs(addressv4->sin_port));
|
||||
}
|
||||
|
||||
IpAddress IpAddressImpl::FromSockAddr(const sockaddr_in6* addressv6)
|
||||
{
|
||||
IpAddress::IPv6 ip6Address = Detail::convertSockaddr6ToIPv6(addressv6->sin6_addr);
|
||||
return IpAddress(ip6Address, ntohs(addressv6->sin6_port));
|
||||
auto& rawIpV6 = addressv6->sin6_addr.s6_addr;
|
||||
|
||||
IpAddress::IPv6 ipv6;
|
||||
for (unsigned int i = 0; i < 8; ++i)
|
||||
ipv6[i] = UInt16(rawIpV6[i * 2]) << 8 | rawIpV6[i * 2 + 1];
|
||||
|
||||
return IpAddress(ipv6, ntohs(addressv6->sin6_port));
|
||||
}
|
||||
|
||||
bool IpAddressImpl::ResolveAddress(const IpAddress& ipAddress, std::string* hostname, std::string* service, ResolveError* error)
|
||||
|
|
@ -124,7 +73,10 @@ namespace Nz
|
|||
SockAddrBuffer socketAddress;
|
||||
socklen_t socketAddressLen = ToSockAddr(ipAddress, socketAddress.data());
|
||||
|
||||
if (Detail::GetHostnameInfo(reinterpret_cast<sockaddr*>(socketAddress.data()), socketAddressLen, hostname, service, NI_NUMERICSERV) != 0)
|
||||
std::array<char, NI_MAXHOST> hostnameBuffer;
|
||||
std::array<char, NI_MAXSERV> serviceBuffer;
|
||||
|
||||
if (getnameinfo(reinterpret_cast<sockaddr*>(socketAddress.data()), socketAddressLen, hostnameBuffer.data(), hostnameBuffer.size(), serviceBuffer.data(), serviceBuffer.size(), NI_NUMERICSERV) != 0)
|
||||
{
|
||||
if (error)
|
||||
*error = TranslateEAIErrorToResolveError(errno);
|
||||
|
|
@ -132,6 +84,12 @@ namespace Nz
|
|||
return false;
|
||||
}
|
||||
|
||||
if (hostname)
|
||||
hostname->assign(hostnameBuffer.data());
|
||||
|
||||
if (service)
|
||||
service->assign(serviceBuffer.data());
|
||||
|
||||
if (error)
|
||||
*error = ResolveError::NoError;
|
||||
|
||||
|
|
@ -142,14 +100,14 @@ namespace Nz
|
|||
{
|
||||
std::vector<HostnameInfo> results;
|
||||
|
||||
Detail::addrinfoImpl hints;
|
||||
std::memset(&hints, 0, sizeof(Detail::addrinfoImpl));
|
||||
addrinfo hints;
|
||||
std::memset(&hints, 0, sizeof(addrinfo));
|
||||
hints.ai_family = SocketImpl::TranslateNetProtocolToAF(procol);
|
||||
hints.ai_flags = AI_CANONNAME;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
|
||||
Detail::addrinfoImpl* servinfo;
|
||||
if (Detail::GetAddressInfo(hostname, service, &hints, &servinfo) != 0)
|
||||
addrinfo* servinfo;
|
||||
if (getaddrinfo(hostname.c_str(), service.c_str(), &hints, &servinfo) != 0)
|
||||
{
|
||||
if (error)
|
||||
*error = TranslateEAIErrorToResolveError(errno);
|
||||
|
|
@ -159,18 +117,20 @@ namespace Nz
|
|||
|
||||
CallOnExit onExit([servinfo]()
|
||||
{
|
||||
Detail::FreeAddressInfo(servinfo);
|
||||
freeaddrinfo(servinfo);
|
||||
});
|
||||
|
||||
// loop through all the results and connect to the first we can
|
||||
for (Detail::addrinfoImpl* p = servinfo; p != nullptr; p = p->ai_next)
|
||||
for (addrinfo* p = servinfo; p != nullptr; p = p->ai_next)
|
||||
{
|
||||
HostnameInfo result;
|
||||
result.address = FromAddrinfo(p);
|
||||
result.canonicalName = p->ai_canonname;
|
||||
result.protocol = TranslatePFToNetProtocol(p->ai_family);
|
||||
result.socketType = TranslateSockToNetProtocol(p->ai_socktype);
|
||||
|
||||
if (p->ai_canonname)
|
||||
result.canonicalName = p->ai_canonname;
|
||||
|
||||
results.push_back(result);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -211,8 +211,8 @@ namespace Nz
|
|||
{
|
||||
NazaraAssert(handle != InvalidHandle, "Invalid handle");
|
||||
|
||||
u_long availableBytes;
|
||||
if (ioctl(handle, FIONREAD, &availableBytes) == -1)
|
||||
int availableBytes;
|
||||
if (ioctl(handle, FIONREAD, &availableBytes) != 0)
|
||||
{
|
||||
if (error)
|
||||
*error = TranslateErrorToSocketError(errno);
|
||||
|
|
@ -223,7 +223,7 @@ namespace Nz
|
|||
if (error)
|
||||
*error = SocketError::NoError;
|
||||
|
||||
return availableBytes;
|
||||
return SafeCast<std::size_t>(availableBytes);
|
||||
}
|
||||
|
||||
bool SocketImpl::QueryBroadcasting(SocketHandle handle, SocketError* error)
|
||||
|
|
@ -266,25 +266,9 @@ namespace Nz
|
|||
|
||||
std::size_t SocketImpl::QueryMaxDatagramSize(SocketHandle handle, SocketError* error)
|
||||
{
|
||||
int code;
|
||||
socklen_t codeLength = sizeof(code);
|
||||
|
||||
#if defined(NAZARA_PLATFORM_MACOSX)
|
||||
return 0; //No IP_MTU on macosx
|
||||
#else
|
||||
if (getsockopt(handle, IPPROTO_IP, IP_MTU, &code, &codeLength) == -1)
|
||||
{
|
||||
if (error)
|
||||
*error = TranslateErrorToSocketError(errno);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (error)
|
||||
*error = SocketError::NoError;
|
||||
|
||||
return code;
|
||||
// There's no SO_MAX_MSG_SIZE on POSIX
|
||||
// We could use IP_MTU but it requires a connected socket
|
||||
return std::min<std::size_t>(QuerySendBufferSize(handle, error), 65507); //< Max IPv4 value (IPv6 is 65527)
|
||||
}
|
||||
|
||||
bool SocketImpl::QueryNoDelay(SocketHandle handle, SocketError* error)
|
||||
|
|
|
|||
|
|
@ -57,9 +57,6 @@ namespace Nz
|
|||
|
||||
std::string TranslateCanonicalName(const wchar_t* str)
|
||||
{
|
||||
if (!str)
|
||||
return {};
|
||||
|
||||
return FromWideString(str);
|
||||
}
|
||||
#else
|
||||
|
|
@ -95,9 +92,6 @@ namespace Nz
|
|||
|
||||
std::string TranslateCanonicalName(const char* str)
|
||||
{
|
||||
if (!str)
|
||||
return {};
|
||||
|
||||
return str;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -225,13 +219,13 @@ namespace Nz
|
|||
|
||||
for (Detail::addrinfoImpl* p = servinfo; p != nullptr; p = p->ai_next)
|
||||
{
|
||||
HostnameInfo result;
|
||||
HostnameInfo& result = results.emplace_back();
|
||||
result.address = FromAddrinfo(p);
|
||||
result.canonicalName = Detail::TranslateCanonicalName(p->ai_canonname);
|
||||
result.protocol = TranslatePFToNetProtocol(p->ai_family);
|
||||
result.socketType = TranslateSockToNetProtocol(p->ai_socktype);
|
||||
|
||||
results.push_back(result);
|
||||
if (p->ai_canonname)
|
||||
result.canonicalName = Detail::TranslateCanonicalName(p->ai_canonname);
|
||||
}
|
||||
|
||||
if (error)
|
||||
|
|
|
|||
Loading…
Reference in New Issue