diff --git a/GS-IPv6-Forwarder b/GS-IPv6-Forwarder index 6fc14fa..851eac0 160000 --- a/GS-IPv6-Forwarder +++ b/GS-IPv6-Forwarder @@ -1 +1 @@ -Subproject commit 6fc14fa95e6d3c6bc620e3147735ea61891b6110 +Subproject commit 851eac0e727301e93dc424559bb17118c0e77f6e diff --git a/miss/miss.cpp b/miss/miss.cpp index a5bb525..baa4f90 100644 --- a/miss/miss.cpp +++ b/miss/miss.cpp @@ -39,6 +39,7 @@ bool PCPMapPort(PSOCKADDR_STORAGE localAddr, int localAddrLen, PSOCKADDR_STORAGE #define POLLING_DELAY_SEC 120 #define PORT_MAPPING_DURATION_SEC 3600 #define UPNP_DISCOVERY_DELAY_MS 5000 +#define GAA_INITIAL_SIZE 8192 static struct port_entry { int proto; @@ -233,10 +234,7 @@ bool UPnPMapPort(struct UPNPUrls* urls, struct IGDdatas* data, int proto, const bool GetIP4OnLinkPrefixLength(char* lanAddressString, int* prefixLength) { - union { - IP_ADAPTER_ADDRESSES addresses; - char buffer[8192]; - }; + PIP_ADAPTER_ADDRESSES addresses; ULONG error; ULONG length; PIP_ADAPTER_ADDRESSES currentAdapter; @@ -245,22 +243,34 @@ bool GetIP4OnLinkPrefixLength(char* lanAddressString, int* prefixLength) inet_pton(AF_INET, lanAddressString, &targetAddress); - // Get a list of all interfaces with IPv4 addresses on the system - length = sizeof(buffer); - error = GetAdaptersAddresses(AF_INET, - GAA_FLAG_SKIP_ANYCAST | - GAA_FLAG_SKIP_MULTICAST | - GAA_FLAG_SKIP_DNS_SERVER | - GAA_FLAG_SKIP_FRIENDLY_NAME, - NULL, - &addresses, - &length); + addresses = NULL; + length = GAA_INITIAL_SIZE; + do { + free(addresses); + addresses = (PIP_ADAPTER_ADDRESSES)malloc(length); + if (addresses == NULL) { + printf("malloc(%u) failed" NL, length); + return false; + } + + // Get a list of all interfaces with IPv4 addresses on the system + error = GetAdaptersAddresses(AF_INET, + GAA_FLAG_SKIP_ANYCAST | + GAA_FLAG_SKIP_MULTICAST | + GAA_FLAG_SKIP_DNS_SERVER | + GAA_FLAG_SKIP_FRIENDLY_NAME, + NULL, + addresses, + &length); + } while (error == ERROR_BUFFER_OVERFLOW); + if (error != ERROR_SUCCESS) { printf("GetAdaptersAddresses() failed: %d" NL, error); + free(addresses); return false; } - currentAdapter = &addresses; + currentAdapter = addresses; currentAddress = nullptr; while (currentAdapter != nullptr) { currentAddress = currentAdapter->FirstUnicastAddress; @@ -271,6 +281,7 @@ bool GetIP4OnLinkPrefixLength(char* lanAddressString, int* prefixLength) if (RtlEqualMemory(¤tAddrV4->sin_addr, &targetAddress, sizeof(targetAddress))) { *prefixLength = currentAddress->OnLinkPrefixLength; + free(addresses); return true; } @@ -281,6 +292,7 @@ bool GetIP4OnLinkPrefixLength(char* lanAddressString, int* prefixLength) } printf("No adapter found with IPv4 address: %s" NL, lanAddressString); + free(addresses); return false; } diff --git a/mist/mist.cpp b/mist/mist.cpp index 2b932b2..7a0b30c 100644 --- a/mist/mist.cpp +++ b/mist/mist.cpp @@ -29,6 +29,8 @@ #define LOOPBACK_SERVER_PORT_OFFSET -10000 +#define GAA_INITIAL_SIZE 8192 + static struct port_entry { int proto; int port; @@ -864,31 +866,40 @@ bool FindLocalInterfaceIPAddress(int family, PSOCKADDR_STORAGE addr) bool FindZeroTierInterfaceAddress(PSOCKADDR_STORAGE addr) { - union { - IP_ADAPTER_ADDRESSES addresses; - char buffer[8192]; - }; + PIP_ADAPTER_ADDRESSES addresses; ULONG error; ULONG length; PIP_ADAPTER_ADDRESSES currentAdapter; PIP_ADAPTER_UNICAST_ADDRESS currentAddress; - // Get all IPv4 interfaces - length = sizeof(buffer); - error = GetAdaptersAddresses(AF_INET, - GAA_FLAG_SKIP_ANYCAST | - GAA_FLAG_SKIP_MULTICAST | - GAA_FLAG_SKIP_DNS_SERVER | - GAA_FLAG_SKIP_FRIENDLY_NAME, - NULL, - &addresses, - &length); + addresses = NULL; + length = GAA_INITIAL_SIZE; + do { + free(addresses); + addresses = (PIP_ADAPTER_ADDRESSES)malloc(length); + if (addresses == NULL) { + fprintf(LOG_OUT, "malloc(%u) failed\n", length); + return false; + } + + // Get all IPv4 interfaces + error = GetAdaptersAddresses(AF_INET, + GAA_FLAG_SKIP_ANYCAST | + GAA_FLAG_SKIP_MULTICAST | + GAA_FLAG_SKIP_DNS_SERVER | + GAA_FLAG_SKIP_FRIENDLY_NAME, + NULL, + addresses, + &length); + } while (error == ERROR_BUFFER_OVERFLOW); + if (error != ERROR_SUCCESS) { fprintf(LOG_OUT, "GetAdaptersAddresses() failed: %d\n", error); + free(addresses); return false; } - currentAdapter = &addresses; + currentAdapter = addresses; while (currentAdapter != NULL) { // Look for ones that correspond to a ZeroTier device if (wcsstr(currentAdapter->Description, L"ZeroTier")) { @@ -897,6 +908,7 @@ bool FindZeroTierInterfaceAddress(PSOCKADDR_STORAGE addr) while (currentAddress != NULL) { if (currentAddress->Address.lpSockaddr->sa_family == AF_INET) { RtlCopyMemory(addr, currentAddress->Address.lpSockaddr, currentAddress->Address.iSockaddrLength); + free(addresses); return true; } @@ -907,15 +919,13 @@ bool FindZeroTierInterfaceAddress(PSOCKADDR_STORAGE addr) currentAdapter = currentAdapter->Next; } + free(addresses); return false; } bool FindDuplicateDefaultInterfaces(void) { - union { - IP_ADAPTER_ADDRESSES addresses; - char buffer[8192]; - }; + PIP_ADAPTER_ADDRESSES addresses; ULONG error; ULONG length; MIB_IPFORWARDROW defaultRoute; @@ -928,24 +938,36 @@ bool FindDuplicateDefaultInterfaces(void) return false; } - // Get all IPv4 interfaces - length = sizeof(buffer); - error = GetAdaptersAddresses(AF_INET, - GAA_FLAG_SKIP_UNICAST | - GAA_FLAG_SKIP_ANYCAST | - GAA_FLAG_SKIP_MULTICAST | - GAA_FLAG_SKIP_DNS_SERVER | - GAA_FLAG_INCLUDE_GATEWAYS | - GAA_FLAG_SKIP_FRIENDLY_NAME, - NULL, - &addresses, - &length); + addresses = NULL; + length = GAA_INITIAL_SIZE; + do { + free(addresses); + addresses = (PIP_ADAPTER_ADDRESSES)malloc(length); + if (addresses == NULL) { + fprintf(LOG_OUT, "malloc(%u) failed\n", length); + return false; + } + + // Get all IPv4 interfaces + error = GetAdaptersAddresses(AF_INET, + GAA_FLAG_SKIP_UNICAST | + GAA_FLAG_SKIP_ANYCAST | + GAA_FLAG_SKIP_MULTICAST | + GAA_FLAG_SKIP_DNS_SERVER | + GAA_FLAG_INCLUDE_GATEWAYS | + GAA_FLAG_SKIP_FRIENDLY_NAME, + NULL, + addresses, + &length); + } while (error == ERROR_BUFFER_OVERFLOW); + if (error != ERROR_SUCCESS) { fprintf(LOG_OUT, "GetAdaptersAddresses() failed: %d\n", error); + free(addresses); return false; } - currentAdapter = &addresses; + currentAdapter = addresses; while (currentAdapter != NULL) { if (currentAdapter->OperStatus == IfOperStatusUp && currentAdapter->FirstGatewayAddress != NULL && @@ -958,6 +980,7 @@ bool FindDuplicateDefaultInterfaces(void) currentAdapter = currentAdapter->Next; } + free(addresses); return matchingInterfaces > 1; }