diff --git a/common/ip_util.cpp b/common/ip_util.cpp index 4bb906bb54..47689a2fab 100644 --- a/common/ip_util.cpp +++ b/common/ip_util.cpp @@ -81,45 +81,79 @@ bool IpUtil::IsIpInPrivateRfc1918(const std::string &ip) ); } -/** - * Gets local address - pings google to inspect what interface was used locally - * @return - */ + +#ifdef _WIN32 +#include + #include + #pragma comment(lib, "Ws2_32.lib") +#else +#include +#include +#include +#include +#include +#endif + +#include +#include +#include + std::string IpUtil::GetLocalIPAddress() { - char my_ip_address[16]; - unsigned int my_port; +#ifdef _WIN32 + WSADATA wsaData; + if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { + return ""; + } +#endif + + char my_ip_address[INET_ADDRSTRLEN]; struct sockaddr_in server_address{}; struct sockaddr_in my_address{}; - int sockfd; - - // Connect to server - if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + int sockfd; + + // Create a UDP socket +#ifdef _WIN32 + sockfd = socket(AF_INET, SOCK_DGRAM, 0); + if (sockfd == INVALID_SOCKET) { + WSACleanup(); + return ""; + } +#else + sockfd = socket(AF_INET, SOCK_DGRAM, 0); + if (sockfd < 0) { return ""; } +#endif - // Set server_addr + // Set server_addr (dummy address) memset(&server_address, 0, sizeof(server_address)); - server_address.sin_family = AF_INET; - server_address.sin_addr.s_addr = inet_addr("172.217.160.99"); - server_address.sin_port = htons(80); + server_address.sin_family = AF_INET; + server_address.sin_addr.s_addr = inet_addr("8.8.8.8"); // Google DNS + server_address.sin_port = htons(53); // DNS port - // Connect to server - if (connect(sockfd, (struct sockaddr *) &server_address, sizeof(server_address)) < 0) { - close(sockfd); - return ""; - } + // Perform a dummy connection to the server (UDP) + connect(sockfd, (struct sockaddr *) &server_address, sizeof(server_address)); - // Get my ip address and port + // Get my IP address memset(&my_address, 0, sizeof(my_address)); socklen_t len = sizeof(my_address); getsockname(sockfd, (struct sockaddr *) &my_address, &len); inet_ntop(AF_INET, &my_address.sin_addr, my_ip_address, sizeof(my_ip_address)); - my_port = ntohs(my_address.sin_port); - return fmt::format("{}", my_ip_address); +#ifdef _WIN32 + closesocket(sockfd); + WSACleanup(); +#else + close(sockfd); +#endif + + LogInfo("Local IP Address [{}]", my_ip_address); + + return std::string(my_ip_address); } + /** * Gets public address * Uses various websites as options to return raw public IP back to the client