DotNetDupe 4.0.6
C++17/20 Implementation of the .NET Base Class Library (BCL)
Loading...
Searching...
No Matches
Dns.cpp
Go to the documentation of this file.
1#include "pch.h"
2#include "System/String.h"
3#include "System/Net/Dns.h"
6#include <vector>
7#include <mutex>
8
9#if defined(_WIN32)
10 #include <winsock2.h>
11 #include <ws2tcpip.h>
12#else
13 #include <sys/socket.h>
14 #include <sys/types.h>
15 #include <netdb.h>
16 #include <arpa/inet.h>
17 #include <cstring>
18#endif
19
20namespace DotNetDupe {
21 namespace System {
22 namespace Net {
23
24 void Dns::InitializeSockets() {
25#if defined(_WIN32)
26 static bool bInitialized = false;
27 static std::mutex mutexInit;
28 std::lock_guard<std::mutex> lock(mutexInit);
29 if (!bInitialized) {
30 WSADATA wsaData;
31 int iErr = WSAStartup(MAKEWORD(2, 2), &wsaData);
32 if (iErr != 0) {
33 throw Sockets::SocketException(iErr, "WSAStartup failed in Dns initialization.");
34 }
35 bInitialized = true;
36 }
37#endif
38 }
39
41 static std::vector<String> CollectIpv4Addresses(struct addrinfo* result) {
42 std::vector<String> addresses;
43
45 for (struct addrinfo* ptr = result; ptr != nullptr; ptr = ptr->ai_next) {
46 if (ptr->ai_family == AF_INET) {
47 auto* ipv4 = reinterpret_cast<struct sockaddr_in*>(ptr->ai_addr);
48 char ipAddress[INET_ADDRSTRLEN];
49 inet_ntop(AF_INET, &(ipv4->sin_addr), ipAddress, INET_ADDRSTRLEN);
50 addresses.push_back(String(ipAddress));
51 }
52 }
53 return addresses;
54 }
55
57 static struct addrinfo* ResolveHostAddrInfo(const char* host) {
58 struct addrinfo hints;
59 std::memset(&hints, 0, sizeof(hints));
60 hints.ai_family = AF_INET;
61 hints.ai_socktype = SOCK_STREAM;
62 struct addrinfo* result = nullptr;
63
65 if (getaddrinfo(host, nullptr, &hints, &result) != 0) {
66 throw Sockets::SocketException(-1, "Failed to resolve host.");
67 }
68 return result;
69 }
70
73 if (hostName.IsEmpty()) throw ArgumentException("hostName cannot be empty.");
74
76 InitializeSockets();
77 struct addrinfo* result = ResolveHostAddrInfo(hostName.GetRawString());
78 std::vector<String> addresses = CollectIpv4Addresses(result);
79 freeaddrinfo(result);
80
82 if (addresses.empty()) throw Sockets::SocketException(-1, String("No addresses found for host."));
83 Array<String> arrAddresses(static_cast<int>(addresses.size()));
84 for (size_t i = 0; i < addresses.size(); ++i) arrAddresses[static_cast<int>(i)] = addresses[i];
85 return arrAddresses;
86 }
87 }
88 }
89}
Defines the exception thrown when an invalid argument is provided to a method.
Provides simple domain name resolution functionality.
Exception thrown when a network socket error occurs per RFC 793 / RFC 768.
High-performance UTF-8 / UTF-16 string manipulation class mirroring .NET System.String.
ArgumentException(const String &sMessage)
Initializes a new instance of the ArgumentException class with a specified error message.
Provides methods for creating, manipulating, searching, and sorting arrays, thereby serving as the ba...
Definition Array.h:29
static Array< String > GetHostAddresses(const String &hostName)
Returns the Internet Protocol (IP) addresses for the specified host.
Definition Dns.cpp:71
Exception thrown when a socket error occurs during network communications.
Represents text as a sequence of UTF-8 code units with culture-invariant operations.
Definition String.h:74
String()
Initializes a new instance of the String class to an empty string.
Definition String.cpp:64
const char * GetRawString() const
Definition String.cpp:230
static struct addrinfo * ResolveHostAddrInfo(const char *host)
Query system DNS resolver via getaddrinfo.
Definition Dns.cpp:57
static std::vector< String > CollectIpv4Addresses(struct addrinfo *result)
Extract IPv4 string representations from linked addrinfo structures.
Definition Dns.cpp:41