Network: Add ResolveError handling
Former-commit-id: 0dc3d109284e8b475577bf44cbaeb503c4baae73
This commit is contained in:
parent
5f0aa64555
commit
4ad1a47064
|
|
@ -9,6 +9,22 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
enum ResolveError
|
||||||
|
{
|
||||||
|
ResolveError_NoError,
|
||||||
|
|
||||||
|
ResolveError_Internal, //< An internal error occured
|
||||||
|
ResolveError_ResourceError, //< The operating system lacks the resources to proceed (insufficient memory)
|
||||||
|
ResolveError_NonRecoverable, //< An nonrecoverable error occured
|
||||||
|
ResolveError_NotFound, //< No such host is known
|
||||||
|
ResolveError_NotInitialized, //< Nazara network has not been initialized
|
||||||
|
ResolveError_ProtocolNotSupported, //< A specified protocol is not supported by the server
|
||||||
|
ResolveError_TemporaryFailure, //< A temporary failure occured, try again
|
||||||
|
ResolveError_Unknown, //< The last operation failed with an unlisted error code
|
||||||
|
|
||||||
|
ResolveError_Max = ResolveError_TemporaryFailure
|
||||||
|
};
|
||||||
|
|
||||||
enum NetProtocol
|
enum NetProtocol
|
||||||
{
|
{
|
||||||
NetProtocol_Any,
|
NetProtocol_Any,
|
||||||
|
|
|
||||||
|
|
@ -55,8 +55,8 @@ namespace Nz
|
||||||
IpAddress& operator=(const IpAddress&) = default;
|
IpAddress& operator=(const IpAddress&) = default;
|
||||||
IpAddress& operator=(IpAddress&&) = default;
|
IpAddress& operator=(IpAddress&&) = default;
|
||||||
|
|
||||||
static String ResolveAddress(const IpAddress& address, String* service = nullptr);
|
static String ResolveAddress(const IpAddress& address, String* service = nullptr, ResolveError* error = nullptr);
|
||||||
static std::vector<HostnameInfo> ResolveHostname(NetProtocol procol, const String& hostname, const String& protocol = "http");
|
static std::vector<HostnameInfo> ResolveHostname(NetProtocol procol, const String& hostname, const String& protocol = "http", ResolveError* error = nullptr);
|
||||||
|
|
||||||
inline friend std::ostream& operator<<(std::ostream& out, const IpAddress& address);
|
inline friend std::ostream& operator<<(std::ostream& out, const IpAddress& address);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -142,17 +142,17 @@ namespace Nz
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
String IpAddress::ResolveAddress(const IpAddress& address, String* service)
|
String IpAddress::ResolveAddress(const IpAddress& address, String* service, ResolveError* error)
|
||||||
{
|
{
|
||||||
String hostname;
|
String hostname;
|
||||||
IpAddressImpl::ResolveAddress(address, &hostname, service);
|
IpAddressImpl::ResolveAddress(address, &hostname, service, error);
|
||||||
|
|
||||||
return hostname;
|
return hostname;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<HostnameInfo> IpAddress::ResolveHostname(NetProtocol protocol, const String& hostname, const String& service)
|
std::vector<HostnameInfo> IpAddress::ResolveHostname(NetProtocol protocol, const String& hostname, const String& service, ResolveError* error)
|
||||||
{
|
{
|
||||||
return IpAddressImpl::ResolveHostname(protocol, hostname, service);
|
return IpAddressImpl::ResolveHostname(protocol, hostname, service, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
IpAddress IpAddress::AnyIpV4(0, 0, 0, 0);
|
IpAddress IpAddress::AnyIpV4(0, 0, 0, 0);
|
||||||
|
|
|
||||||
|
|
@ -147,15 +147,26 @@ namespace Nz
|
||||||
return IpAddress(rawIpV6[0], rawIpV6[1], rawIpV6[2], rawIpV6[3], rawIpV6[4], rawIpV6[5], rawIpV6[6], rawIpV6[7], ntohs(addressv6->sin6_port));
|
return IpAddress(rawIpV6[0], rawIpV6[1], rawIpV6[2], rawIpV6[3], rawIpV6[4], rawIpV6[5], rawIpV6[6], rawIpV6[7], ntohs(addressv6->sin6_port));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IpAddressImpl::ResolveAddress(const IpAddress& ipAddress, String* hostname, String* service)
|
bool IpAddressImpl::ResolveAddress(const IpAddress& ipAddress, String* hostname, String* service, ResolveError* error)
|
||||||
{
|
{
|
||||||
SockAddrBuffer socketAddress;
|
SockAddrBuffer socketAddress;
|
||||||
socklen_t socketAddressLen = ToSockAddr(ipAddress, socketAddress.data());
|
socklen_t socketAddressLen = ToSockAddr(ipAddress, socketAddress.data());
|
||||||
|
|
||||||
return Detail::GetHostnameInfo(reinterpret_cast<sockaddr*>(socketAddress.data()), socketAddressLen, hostname, service) == 0;
|
if (Detail::GetHostnameInfo(reinterpret_cast<sockaddr*>(socketAddress.data()), socketAddressLen, hostname, service) != 0)
|
||||||
|
{
|
||||||
|
if (error)
|
||||||
|
*error = TranslateWSAErrorToResolveError(WSAGetLastError());
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
*error = ResolveError_NoError;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<HostnameInfo> IpAddressImpl::ResolveHostname(NetProtocol procol, const String& hostname, const String& service)
|
std::vector<HostnameInfo> IpAddressImpl::ResolveHostname(NetProtocol procol, const String& hostname, const String& service, ResolveError* error)
|
||||||
{
|
{
|
||||||
std::vector<HostnameInfo> results;
|
std::vector<HostnameInfo> results;
|
||||||
|
|
||||||
|
|
@ -165,10 +176,11 @@ namespace Nz
|
||||||
hints.ai_socktype = SOCK_STREAM;
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
|
|
||||||
Detail::addrinfoImpl* servinfo;
|
Detail::addrinfoImpl* servinfo;
|
||||||
int rv;
|
if (Detail::GetAddressInfo(hostname, service, &hints, &servinfo) != 0)
|
||||||
if ((rv = Detail::GetAddressInfo(hostname, service, &hints, &servinfo)) != 0)
|
|
||||||
{
|
{
|
||||||
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
|
if (error)
|
||||||
|
*error = TranslateWSAErrorToResolveError(WSAGetLastError());
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -190,6 +202,9 @@ namespace Nz
|
||||||
results.push_back(result);
|
results.push_back(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
*error = ResolveError_NoError;
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -237,4 +252,41 @@ namespace Nz
|
||||||
NazaraError("Invalid ip address");
|
NazaraError("Invalid ip address");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ResolveError IpAddressImpl::TranslateWSAErrorToResolveError(int error)
|
||||||
|
{
|
||||||
|
switch (error)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
return ResolveError_NoError;
|
||||||
|
|
||||||
|
// Engine error
|
||||||
|
case WSAEFAULT:
|
||||||
|
case WSAEINVAL:
|
||||||
|
return ResolveError_Internal;
|
||||||
|
|
||||||
|
case WSAEAFNOSUPPORT:
|
||||||
|
case WSAESOCKTNOSUPPORT:
|
||||||
|
case WSASERVICE_NOT_FOUND:
|
||||||
|
return ResolveError_ProtocolNotSupported;
|
||||||
|
|
||||||
|
case WSAHOST_NOT_FOUND:
|
||||||
|
return ResolveError_NotFound;
|
||||||
|
|
||||||
|
case WSANO_RECOVERY:
|
||||||
|
return ResolveError_NonRecoverable;
|
||||||
|
|
||||||
|
case WSANOTINITIALISED:
|
||||||
|
return ResolveError_NotInitialized;
|
||||||
|
|
||||||
|
case WSA_NOT_ENOUGH_MEMORY:
|
||||||
|
return ResolveError_ResourceError;
|
||||||
|
|
||||||
|
case WSATRY_AGAIN:
|
||||||
|
return ResolveError_TemporaryFailure;
|
||||||
|
}
|
||||||
|
|
||||||
|
NazaraWarning("Unhandled WinSock error: " + Error::GetLastSystemError(error) + " (" + String::Number(error) + ')');
|
||||||
|
return ResolveError_Unknown;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,9 +22,10 @@ namespace Nz
|
||||||
static IpAddress FromSockAddr(const sockaddr_in* addressv4);
|
static IpAddress FromSockAddr(const sockaddr_in* addressv4);
|
||||||
static IpAddress FromSockAddr(const sockaddr_in6* addressv6);
|
static IpAddress FromSockAddr(const sockaddr_in6* addressv6);
|
||||||
|
|
||||||
static bool ResolveAddress(const IpAddress& ipAddress, String* hostname, String* service);
|
static bool ResolveAddress(const IpAddress& ipAddress, String* hostname, String* service, ResolveError* error);
|
||||||
static std::vector<HostnameInfo> ResolveHostname(NetProtocol procol, const String& hostname, const String& service);
|
static std::vector<HostnameInfo> ResolveHostname(NetProtocol procol, const String& hostname, const String& service, ResolveError* error);
|
||||||
|
|
||||||
static socklen_t ToSockAddr(const IpAddress& ipAddress, void* buffer);
|
static socklen_t ToSockAddr(const IpAddress& ipAddress, void* buffer);
|
||||||
|
static ResolveError TranslateWSAErrorToResolveError(int error);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue