Added new DNS::Resolve static method and organized it per OS.

This commit is contained in:
Arron David Nelson 2024-07-09 16:41:43 -07:00
parent 126fc92fae
commit 4e887b1ac2
23 changed files with 545 additions and 96 deletions

View File

@ -122,7 +122,7 @@ set(EHS_SOURCES
src/io/socket/Request.cpp include/ehs/io/socket/Request.h
src/io/socket/Response.cpp include/ehs/io/socket/Response.h
src/io/socket/DNS.cpp include/ehs/io/socket/DNS.h
src/io/socket/DNS_LNX.cpp include/ehs/io/socket/DNS_LNX.h
src/io/socket/BaseUDP.cpp include/ehs/io/socket/BaseUDP.h
src/io/socket/BaseTCP.cpp include/ehs/io/socket/BaseTCP.h
src/io/socket/SSL.cpp include/ehs/io/socket/SSL.h
@ -176,12 +176,16 @@ set(EHS_SOURCES
include/ehs/io/BaseDirectory.h
src/io/BaseDirectory.cpp
include/ehs/io/Directory.h
include/ehs/io/socket/BaseDNS.h
src/io/socket/BaseDNS.cpp
include/ehs/io/socket/DNS.h
)
if (IS_OS_WINDOWS)
list(APPEND EHS_SOURCES
src/io/socket/UDP_W32.cpp include/ehs/io/socket/UDP_W32.h
src/io/socket/TCP_W32.cpp include/ehs/io/socket/TCP_W32.h
src/io/socket/DNS_W32.cpp include/ehs/io/socket/DNS_W32.h
src/system/Semaphore_W32.cpp include/ehs/system/Semaphore_W32.h
src/system/System_W32.cpp include/ehs/system/System_W32.h
src/system/Mutex_W32.cpp include/ehs/system/Mutex_W32.h
@ -198,6 +202,7 @@ elseif (IS_OS_LINUX)
list(APPEND EHS_SOURCES
src/io/socket/UDP_BSD.cpp include/ehs/io/socket/UDP_BSD.h
src/io/socket/TCP_BSD.cpp include/ehs/io/socket/TCP_BSD.h
src/io/socket/DNS_LNX.cpp include/ehs/io/socket/DNS_LNX.h
src/system/Semaphore_P.cpp include/ehs/system/Semaphore_P.h
src/system/System_LNX.cpp include/ehs/system/System_LNX.h
src/system/Open_UNX.cpp include/ehs/system/Open_UNX.h

View File

@ -0,0 +1,18 @@
#pragma once
#include "Socket.h"
#include "ehs/Str.h"
namespace ehs
{
class BaseDNS
{
public:
static Str_8 Resolve(AddrType type, const Str_8 &hostname);
/// Resolves a hostname to an ip address.
/// @param [in] hostname The given hostname to resolve.
/// @returns The resulting ip address.
static Str_8 Resolve(const Str_8 &hostname);
};
}

View File

@ -146,6 +146,10 @@ namespace ehs
/// @returns The result.
virtual bool IsBlocking() const = 0;
virtual void SetIPv6Only(bool value) = 0;
virtual bool IsIPv6Only() const = 0;
/// Retrieves whether or not this socket was initialized.
/// @returns The result.
virtual bool IsValid() const = 0;

View File

@ -69,6 +69,10 @@ namespace ehs
/// @returns The result.
virtual bool IsBlocking() const = 0;
virtual void SetIPv6Only(bool value) = 0;
virtual bool IsIPv6Only() const = 0;
/// Retrieves the bound ip version.
/// @returns The result.
AddrType GetLocalAddressType() const;

View File

@ -1,17 +1,9 @@
#pragma once
#include "ehs/EHS.h"
#include "ehs/Str.h"
#include "Socket.h"
#include "ehs/system/OS.h"
namespace ehs
{
class DNS
{
public:
/// Resolves a hostname to an ip address.
/// @param [in] hostname The given hostname to resolve.
/// @returns The resulting ip address.
static Str_8 Resolve(const Str_8& hostname);
};
}
#if defined(EHS_OS_WINDOWS)
#include "DNS_W32.h"
#elif defined(EHS_OS_LINUX)
#include "DNS_LNX.h"
#endif

View File

@ -0,0 +1,17 @@
#pragma once
#include "BaseDNS.h"
#include "ehs/EHS.h"
#include "ehs/Str.h"
#include "Socket.h"
namespace ehs
{
class DNS final : public BaseDNS
{
public:
static Str_8 Resolve(AddrType type, const Str_8 &hostname);
static Str_8 Resolve(const Str_8 &hostname);
};
}

View File

@ -0,0 +1,14 @@
#pragma once
#include "BaseDNS.h"
namespace ehs
{
class DNS final : public BaseDNS
{
public:
static Str_8 Resolve(AddrType type, const Str_8 &hostname);
static Str_8 Resolve(const Str_8 &hostname);
};
}

View File

@ -80,6 +80,10 @@ namespace ehs
/// @returns The result.
bool IsBlocking() const override;
void SetIPv6Only(bool value) override;
bool IsIPv6Only() const override;
bool IsValid() const override;
private:

View File

@ -80,6 +80,10 @@ namespace ehs
/// @returns The result.
bool IsBlocking() const override;
void SetIPv6Only(bool value) override;
bool IsIPv6Only() const override;
bool IsValid() const override;
private:

View File

@ -68,6 +68,10 @@ namespace ehs
/// @returns The result.
bool IsBlocking() const override;
void SetIPv6Only(bool value) override;
bool IsIPv6Only() const override;
bool IsValid() const override;
private:

View File

@ -68,6 +68,10 @@ namespace ehs
/// @returns The result.
bool IsBlocking() const override;
void SetIPv6Only(bool value) override;
bool IsIPv6Only() const override;
bool IsValid() const override;
private:

View File

@ -12,9 +12,9 @@ namespace ehs
{
xdg_surface_ack_configure(xdg_surface, serial);
Window* win = (Window *)data;
//Window* win = (Window *)data;
wl_surface_commit(win->wlSurface);
//wl_surface_commit(win->wlSurface);
}
void Window::ShellPing(void* data, xdg_wm_base* shell, UInt_32 serial)
@ -225,6 +225,8 @@ namespace ehs
xdg_wm_base_add_listener(xdgShell, &xdg_shell_listener, nullptr);
wl_display_roundtrip(display);
wlSurface = wl_compositor_create_surface(compositor);
if (!wlSurface)
{
@ -240,6 +242,8 @@ namespace ehs
xdg_surface_add_listener(xdgSurface, &surfaceListener, this);
wl_display_roundtrip(display);
xdgToplevel = xdg_surface_get_toplevel(xdgSurface);
static constexpr xdg_toplevel_listener topLevelListener = {
@ -249,12 +253,18 @@ namespace ehs
xdg_toplevel_add_listener(xdgToplevel, &topLevelListener, this);
wl_display_roundtrip(display);
xdg_toplevel_set_title(xdgToplevel, title);
xdg_toplevel_set_app_id(xdgToplevel, title);
wl_display_roundtrip(display);
dec = zxdg_decoration_manager_v1_get_toplevel_decoration(decManager, xdgToplevel);
zxdg_toplevel_decoration_v1_set_mode(dec, ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE);
wl_display_roundtrip(display);
static constexpr wl_seat_listener seat_listener = {
.capabilities = SeatCapabilitiesEvent
};

18
src/io/socket/BaseDNS.cpp Normal file
View File

@ -0,0 +1,18 @@
#include "ehs/io/socket/BaseDNS.h"
#include "ehs/Log.h"
namespace ehs
{
Str_8 BaseDNS::Resolve(const AddrType type, const Str_8 &hostname)
{
EHS_LOG_INT(LogType::ERR, 0, "Unsupported Operating System.");
return {};
}
Str_8 BaseDNS::Resolve(const Str_8 &hostname)
{
EHS_LOG_INT(LogType::ERR, 0, "Unsupported Operating System.");
return {};
}
}

View File

@ -1,73 +0,0 @@
#include "ehs/io/socket/DNS.h"
#include "ehs/Log.h"
#if defined(EHS_OS_WINDOWS)
#include <WinSock2.h>
#include <WS2tcpip.h>
#elif defined(EHS_OS_LINUX)
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#endif
namespace ehs
{
Str_8 DNS::Resolve(const Str_8& hostname)
{
#if defined(EHS_OS_WINDOWS)
WSADATA data = {};
Int_32 wsaCode = WSAStartup(MAKEWORD(2, 2), &data);
if (wsaCode)
{
EHS_LOG_INT(LogType::ERR, 0, "Failed to start WSA with error #" + Str_8::FromNum(wsaCode) + ".");
return {};
}
#endif
addrinfo* result = nullptr;
Int_32 code = getaddrinfo(hostname, nullptr, nullptr, &result);
if (code)
{
EHS_LOG_INT(LogType::ERR, 1, "Failed to resolve host with error #" + Str_8::FromNum(code) + ".");
return {};
}
#if defined(EHS_OS_WINDOWS)
if (WSACleanup() == SOCKET_ERROR)
{
EHS_LOG_INT(LogType::ERR, 2, "Failed to shutdown WSA with error #" + Str_8::FromNum(WSAGetLastError()) + ".");
return {};
}
#endif
if (result->ai_family == AF_INET6)
{
Str_8 ipResult(INET6_ADDRSTRLEN);
inet_ntop(result->ai_family, &((sockaddr_in6*)result->ai_addr)->sin6_addr, ipResult, INET6_ADDRSTRLEN);
ipResult.ExactSize();
freeaddrinfo(result);
return ipResult;
}
else if (result->ai_family == AF_INET)
{
Str_8 ipResult(INET_ADDRSTRLEN);
inet_ntop(result->ai_family, &((sockaddr_in*)result->ai_addr)->sin_addr, ipResult, INET_ADDRSTRLEN);
ipResult.ExactSize();
freeaddrinfo(result);
return ipResult;
}
return {};
}
}

106
src/io/socket/DNS_LNX.cpp Normal file
View File

@ -0,0 +1,106 @@
#include "ehs/io/socket/DNS_LNX.h"
#include "ehs/Log.h"
#if defined(EHS_OS_WINDOWS)
#include <WinSock2.h>
#include <WS2tcpip.h>
#elif defined(EHS_OS_LINUX)
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#endif
namespace ehs
{
Str_8 DNS::Resolve(const AddrType type, const Str_8 &hostname)
{
addrinfo* result = nullptr;
addrinfo req = {};
if (type == AddrType::IPV6)
req.ai_family = AF_INET6;
else if (type == AddrType::IPV4)
req.ai_family = AF_INET;
Int_32 code = getaddrinfo(hostname, nullptr, &req, &result);
if (code)
{
EHS_LOG_INT(LogType::ERR, 1, "Failed to resolve host with error #" + Str_8::FromNum(code) + ".");
return {};
}
if (result->ai_family == AF_INET6)
{
Str_8 ipResult(INET6_ADDRSTRLEN);
inet_ntop(result->ai_family, &((sockaddr_in6*)result->ai_addr)->sin6_addr, ipResult, INET6_ADDRSTRLEN);
ipResult.ExactSize();
freeaddrinfo(result);
EHS_LOG_SUCCESS();
return ipResult;
}
else if (result->ai_family == AF_INET)
{
Str_8 ipResult(INET_ADDRSTRLEN);
inet_ntop(result->ai_family, &((sockaddr_in*)result->ai_addr)->sin_addr, ipResult, INET_ADDRSTRLEN);
ipResult.ExactSize();
freeaddrinfo(result);
EHS_LOG_SUCCESS();
return ipResult;
}
return {};
}
Str_8 DNS::Resolve(const Str_8 &hostname)
{
addrinfo* result = nullptr;
Int_32 code = getaddrinfo(hostname, nullptr, nullptr, &result);
if (code)
{
EHS_LOG_INT(LogType::ERR, 1, "Failed to resolve host with error #" + Str_8::FromNum(code) + ".");
return {};
}
if (result->ai_family == AF_INET6)
{
Str_8 ipResult(INET6_ADDRSTRLEN);
inet_ntop(result->ai_family, &((sockaddr_in6*)result->ai_addr)->sin6_addr, ipResult, INET6_ADDRSTRLEN);
ipResult.ExactSize();
freeaddrinfo(result);
EHS_LOG_SUCCESS();
return ipResult;
}
else if (result->ai_family == AF_INET)
{
Str_8 ipResult(INET_ADDRSTRLEN);
inet_ntop(result->ai_family, &((sockaddr_in*)result->ai_addr)->sin_addr, ipResult, INET_ADDRSTRLEN);
ipResult.ExactSize();
freeaddrinfo(result);
EHS_LOG_SUCCESS();
return ipResult;
}
return {};
}
}

122
src/io/socket/DNS_W32.cpp Normal file
View File

@ -0,0 +1,122 @@
#include "ehs/io/socket/DNS_W32.h"
namespace ehs
{
Str_8 DNS::Resolve(const AddrType type, const Str_8 &hostname)
{
WSADATA data = {};
Int_32 wsaCode = WSAStartup(MAKEWORD(2, 2), &data);
if (wsaCode)
{
EHS_LOG_INT(LogType::ERR, 0, "Failed to start WSA with error #" + Str_8::FromNum(wsaCode) + ".");
return {};
}
addrinfo* result = nullptr;
addrinfo req = {};
if (type == AddrType::IPV6)
req.ai_family = AF_INET6;
else if (type == AddrType::IPV4)
req.ai_family = AF_INET;
Int_32 code = getaddrinfo(hostname, nullptr, &req, &result);
if (code)
{
EHS_LOG_INT(LogType::ERR, 1, "Failed to resolve host with error #" + Str_8::FromNum(code) + ".");
return {};
}
if (WSACleanup() == SOCKET_ERROR)
{
EHS_LOG_INT(LogType::ERR, 2, "Failed to shutdown WSA with error #" + Str_8::FromNum(WSAGetLastError()) + ".");
return {};
}
if (result->ai_family == AF_INET6)
{
Str_8 ipResult(INET6_ADDRSTRLEN);
inet_ntop(result->ai_family, &((sockaddr_in6*)result->ai_addr)->sin6_addr, ipResult, INET6_ADDRSTRLEN);
ipResult.ExactSize();
freeaddrinfo(result);
EHS_LOG_SUCCESS();
return ipResult;
}
else if (result->ai_family == AF_INET)
{
Str_8 ipResult(INET_ADDRSTRLEN);
inet_ntop(result->ai_family, &((sockaddr_in*)result->ai_addr)->sin_addr, ipResult, INET_ADDRSTRLEN);
ipResult.ExactSize();
freeaddrinfo(result);
EHS_LOG_SUCCESS();
return ipResult;
}
return {};
}
Str_8 DNS::Resolve(const Str_8 &hostname)
{
WSADATA data = {};
Int_32 wsaCode = WSAStartup(MAKEWORD(2, 2), &data);
if (wsaCode)
{
EHS_LOG_INT(LogType::ERR, 0, "Failed to start WSA with error #" + Str_8::FromNum(wsaCode) + ".");
return {};
}
addrinfo* result = nullptr;
Int_32 code = getaddrinfo(hostname, nullptr, nullptr, &result);
if (code)
{
EHS_LOG_INT(LogType::ERR, 1, "Failed to resolve host with error #" + Str_8::FromNum(code) + ".");
return {};
}
if (WSACleanup() == SOCKET_ERROR)
{
EHS_LOG_INT(LogType::ERR, 2, "Failed to shutdown WSA with error #" + Str_8::FromNum(WSAGetLastError()) + ".");
return {};
}
if (result->ai_family == AF_INET6)
{
Str_8 ipResult(INET6_ADDRSTRLEN);
inet_ntop(result->ai_family, &((sockaddr_in6*)result->ai_addr)->sin6_addr, ipResult, INET6_ADDRSTRLEN);
ipResult.ExactSize();
freeaddrinfo(result);
return ipResult;
}
else if (result->ai_family == AF_INET)
{
Str_8 ipResult(INET_ADDRSTRLEN);
inet_ntop(result->ai_family, &((sockaddr_in*)result->ai_addr)->sin_addr, ipResult, INET_ADDRSTRLEN);
ipResult.ExactSize();
freeaddrinfo(result);
return ipResult;
}
return {};
}
}

View File

@ -1,5 +1,5 @@
#include "ehs/io/socket/TCP_BSD.h"
#include "ehs/io/socket/DNS.h"
#include "ehs/io/socket/DNS_LNX.h"
#include <sys/socket.h>
#include <netinet/in.h>
@ -326,6 +326,55 @@ namespace ehs
return !(flags & O_NONBLOCK);
}
void TCP::SetIPv6Only(const bool value)
{
if (addrType != AddrType::IPV6)
{
EHS_LOG_INT(LogType::WARN, 0, "Cannot set IPv6 only mode while socket is not using IPv6.");
return;
}
if (!IsValid())
{
EHS_LOG_INT(LogType::WARN, 1, "Attempted to set IPv6 only mode while socket is not initialized.");
return;
}
const int result = (int)value;
if (setsockopt(hdl, IPPROTO_IPV6, IPV6_V6ONLY, &result, sizeof(int)) == -1)
{
EHS_LOG_INT(LogType::ERR, 2, "Failed to set IPv6 only mode with error #" + Str_8::FromNum(errno) + ".");
return;
}
EHS_LOG_SUCCESS();
}
bool TCP::IsIPv6Only() const
{
if (addrType != AddrType::IPV6)
return false;
if (!IsValid())
{
EHS_LOG_INT(LogType::WARN, 1, "Attempted to set IPv6 only mode while socket is not initialized.");
return false;
}
int result;
socklen_t len = sizeof(int);
if (getsockopt(hdl, IPPROTO_IPV6, IPV6_V6ONLY, &result, &len) == -1)
{
EHS_LOG_INT(LogType::ERR, 2, "Failed to set IPv6 only mode with error #" + Str_8::FromNum(errno) + ".");
return false;
}
EHS_LOG_SUCCESS();
return result;
}
bool TCP::IsValid() const
{
return hdl != EHS_INVALID_SOCKET;

View File

@ -347,6 +347,55 @@ namespace ehs
return (bool)r;
}
void TCP::SetIPv6Only(const bool value)
{
if (addrType != AddrType::IPV6)
{
EHS_LOG_INT(LogType::WARN, 0, "Cannot set IPv6 only mode while socket is not using IPv6.");
return;
}
if (!IsValid())
{
EHS_LOG_INT(LogType::WARN, 1, "Attempted to set IPv6 only mode while socket is not initialized.");
return;
}
const int result = (int)value;
if (setsockopt(hdl, IPPROTO_IPV6, IPV6_V6ONLY, &result, sizeof(int)) == -1)
{
EHS_LOG_INT(LogType::ERR, 2, "Failed to set IPv6 only mode with error #" + Str_8::FromNum(errno) + ".");
return;
}
EHS_LOG_SUCCESS();
}
bool TCP::IsIPv6Only() const
{
if (addrType != AddrType::IPV6)
return false;
if (!IsValid())
{
EHS_LOG_INT(LogType::WARN, 1, "Attempted to set IPv6 only mode while socket is not initialized.");
return false;
}
int result;
socklen_t len = sizeof(int);
if (getsockopt(hdl, IPPROTO_IPV6, IPV6_V6ONLY, &result, &len) == -1)
{
EHS_LOG_INT(LogType::ERR, 2, "Failed to set IPv6 only mode with error #" + Str_8::FromNum(errno) + ".");
return false;
}
EHS_LOG_SUCCESS();
return result;
}
bool TCP::IsValid() const
{
return hdl != EHS_INVALID_SOCKET;

View File

@ -203,6 +203,55 @@ namespace ehs
return (bool)fcntl(hdl, F_GETFL, O_NONBLOCK);
}
void UDP::SetIPv6Only(const bool value)
{
if (type != AddrType::IPV6)
{
EHS_LOG_INT(LogType::WARN, 0, "Cannot set IPv6 only mode while socket is not using IPv6.");
return;
}
if (!IsValid())
{
EHS_LOG_INT(LogType::WARN, 1, "Attempted to set IPv6 only mode while socket is not initialized.");
return;
}
const int result = (int)value;
if (setsockopt(hdl, IPPROTO_IPV6, IPV6_V6ONLY, &result, sizeof(int)) == -1)
{
EHS_LOG_INT(LogType::ERR, 2, "Failed to set IPv6 only mode with error #" + Str_8::FromNum(errno) + ".");
return;
}
EHS_LOG_SUCCESS();
}
bool UDP::IsIPv6Only() const
{
if (type != AddrType::IPV6)
return false;
if (!IsValid())
{
EHS_LOG_INT(LogType::WARN, 1, "Attempted to set IPv6 only mode while socket is not initialized.");
return false;
}
int result;
socklen_t len = sizeof(int);
if (getsockopt(hdl, IPPROTO_IPV6, IPV6_V6ONLY, &result, &len) == -1)
{
EHS_LOG_INT(LogType::ERR, 2, "Failed to set IPv6 only mode with error #" + Str_8::FromNum(errno) + ".");
return false;
}
EHS_LOG_SUCCESS();
return result;
}
bool UDP::IsValid() const
{
return hdl != EHS_INVALID_SOCKET;

View File

@ -223,6 +223,55 @@ namespace ehs
return (bool)r;
}
void UDP::SetIPv6Only(const bool value)
{
if (type != AddrType::IPV6)
{
EHS_LOG_INT(LogType::WARN, 0, "Cannot set IPv6 only mode while socket is not using IPv6.");
return;
}
if (!IsValid())
{
EHS_LOG_INT(LogType::WARN, 1, "Attempted to set IPv6 only mode while socket is not initialized.");
return;
}
const int result = (int)value;
if (setsockopt(hdl, IPPROTO_IPV6, IPV6_V6ONLY, &result, sizeof(int)) == -1)
{
EHS_LOG_INT(LogType::ERR, 2, "Failed to set IPv6 only mode with error #" + Str_8::FromNum(errno) + ".");
return;
}
EHS_LOG_SUCCESS();
}
bool UDP::IsIPv6Only() const
{
if (type != AddrType::IPV6)
return false;
if (!IsValid())
{
EHS_LOG_INT(LogType::WARN, 1, "Attempted to set IPv6 only mode while socket is not initialized.");
return false;
}
int result;
socklen_t len = sizeof(int);
if (getsockopt(hdl, IPPROTO_IPV6, IPV6_V6ONLY, &result, &len) == -1)
{
EHS_LOG_INT(LogType::ERR, 2, "Failed to set IPv6 only mode with error #" + Str_8::FromNum(errno) + ".");
return false;
}
EHS_LOG_SUCCESS();
return result;
}
bool UDP::IsValid() const
{
return hdl != EHS_INVALID_SOCKET;

View File

@ -1,5 +1,5 @@
#include "ehs/io/socket/rest/Spotify.h"
#include "ehs/io/socket/DNS.h"
#include "ehs/io/socket/DNS_LNX.h"
#include "ehs/system/System.h"
#include "ehs/URI.h"
@ -42,7 +42,7 @@ namespace ehs
TCP server(AddrType::IPV4);
server.Initialize();
server.Bind(DNS::Resolve("localhost"), 65534);
server.Bind("", 65534);
server.Listen();
System::OpenURI(uri);

View File

@ -1,5 +1,5 @@
#include "ehs/io/socket/rest/Twitch.h"
#include "ehs/io/socket/DNS.h"
#include "ehs/io/socket/DNS_LNX.h"
#include "ehs/system/System.h"
#include "ehs/URI.h"
@ -39,7 +39,7 @@ namespace ehs
scopesFinal;
TCP server(AddrType::IPV4);
server.Bind(DNS::Resolve("localhost"), 65535);
server.Bind("", 65535);
server.Listen();
System::OpenURI(uri);

View File

@ -1,5 +1,5 @@
#include "ehs/io/socket/rest/TwitchChat.h"
#include "ehs/io/socket/DNS.h"
#include "ehs/io/socket/DNS_LNX.h"
#include "ehs/io/Console.h"
namespace ehs