mirror of
https://github.com/moonlight-stream/GS-IPv6-Forwarder.git
synced 2025-07-01 15:25:31 +00:00
Use dynamically allocated buffer for GetAdaptersAddresses()
This commit is contained in:
parent
6fc14fa95e
commit
851eac0e72
@ -25,6 +25,7 @@
|
|||||||
#include "../version.h"
|
#include "../version.h"
|
||||||
|
|
||||||
#define SERVICE_NAME L"GSv6FwdSvc"
|
#define SERVICE_NAME L"GSv6FwdSvc"
|
||||||
|
#define GAA_INITIAL_SIZE 8192
|
||||||
|
|
||||||
LPFN_WSARECVMSG WSARecvMsg;
|
LPFN_WSARECVMSG WSARecvMsg;
|
||||||
|
|
||||||
@ -132,44 +133,66 @@ TcpRelayThreadProc(LPVOID Context)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
PIP_ADAPTER_ADDRESSES
|
||||||
|
AllocAndGetAdaptersAddresses(ULONG Family, ULONG Flags)
|
||||||
|
{
|
||||||
|
PIP_ADAPTER_ADDRESSES addresses;
|
||||||
|
ULONG length;
|
||||||
|
ULONG error;
|
||||||
|
|
||||||
|
addresses = NULL;
|
||||||
|
length = GAA_INITIAL_SIZE;
|
||||||
|
do {
|
||||||
|
free(addresses);
|
||||||
|
addresses = (PIP_ADAPTER_ADDRESSES)malloc(length);
|
||||||
|
if (addresses == NULL) {
|
||||||
|
printf("malloc(%u) failed\n", length);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = GetAdaptersAddresses(Family, Flags, NULL, addresses, &length);
|
||||||
|
} while (error == ERROR_BUFFER_OVERFLOW);
|
||||||
|
|
||||||
|
if (error != ERROR_SUCCESS) {
|
||||||
|
printf("GetAdaptersAddresses() failed: %d\n", error);
|
||||||
|
free(addresses);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return addresses;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
FindLocalAddressBySocket(SOCKET s, PIN_ADDR targetAddress)
|
FindLocalAddressBySocket(SOCKET s, PIN_ADDR targetAddress)
|
||||||
{
|
{
|
||||||
union {
|
PIP_ADAPTER_ADDRESSES addresses;
|
||||||
IP_ADAPTER_ADDRESSES addresses;
|
|
||||||
char buffer[8192];
|
|
||||||
};
|
|
||||||
ULONG error;
|
|
||||||
ULONG length;
|
|
||||||
PIP_ADAPTER_ADDRESSES currentAdapter;
|
PIP_ADAPTER_ADDRESSES currentAdapter;
|
||||||
PIP_ADAPTER_UNICAST_ADDRESS currentAddress;
|
PIP_ADAPTER_UNICAST_ADDRESS currentAddress;
|
||||||
SOCKADDR_IN6 localSockAddr;
|
SOCKADDR_IN6 localSockAddr;
|
||||||
int localSockAddrLen;
|
int localSockAddrLen;
|
||||||
|
|
||||||
|
// If we fail to find an address, return the loopback address
|
||||||
|
targetAddress->S_un.S_addr = htonl(INADDR_LOOPBACK);
|
||||||
|
|
||||||
// Get local address of the accepted socket so we can find the interface
|
// Get local address of the accepted socket so we can find the interface
|
||||||
localSockAddrLen = sizeof(localSockAddr);
|
localSockAddrLen = sizeof(localSockAddr);
|
||||||
if (getsockname(s, (PSOCKADDR)&localSockAddr, &localSockAddrLen) == SOCKET_ERROR) {
|
if (getsockname(s, (PSOCKADDR)&localSockAddr, &localSockAddrLen) == SOCKET_ERROR) {
|
||||||
printf("getsockname() failed: %d\n", WSAGetLastError());
|
printf("getsockname() failed: %d\n", WSAGetLastError());
|
||||||
return WSAGetLastError();
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get a list of all interfaces and addresses on the system
|
// Get a list of all interfaces and addresses on the system
|
||||||
length = sizeof(buffer);
|
addresses = AllocAndGetAdaptersAddresses(AF_UNSPEC,
|
||||||
error = GetAdaptersAddresses(AF_UNSPEC,
|
|
||||||
GAA_FLAG_SKIP_ANYCAST |
|
GAA_FLAG_SKIP_ANYCAST |
|
||||||
GAA_FLAG_SKIP_MULTICAST |
|
GAA_FLAG_SKIP_MULTICAST |
|
||||||
GAA_FLAG_SKIP_DNS_SERVER |
|
GAA_FLAG_SKIP_DNS_SERVER |
|
||||||
GAA_FLAG_SKIP_FRIENDLY_NAME,
|
GAA_FLAG_SKIP_FRIENDLY_NAME);
|
||||||
NULL,
|
if (addresses == NULL) {
|
||||||
&addresses,
|
return;
|
||||||
&length);
|
|
||||||
if (error != ERROR_SUCCESS) {
|
|
||||||
printf("GetAdaptersAddresses() failed: %d\n", error);
|
|
||||||
return error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// First, find the interface that owns the incoming address
|
// First, find the interface that owns the incoming address
|
||||||
currentAdapter = &addresses;
|
currentAdapter = addresses;
|
||||||
while (currentAdapter != NULL) {
|
while (currentAdapter != NULL) {
|
||||||
// Check if this interface has the IP address we want
|
// Check if this interface has the IP address we want
|
||||||
currentAddress = currentAdapter->FirstUnicastAddress;
|
currentAddress = currentAdapter->FirstUnicastAddress;
|
||||||
@ -196,7 +219,7 @@ FindLocalAddressBySocket(SOCKET s, PIN_ADDR targetAddress)
|
|||||||
if (currentAdapter == NULL) {
|
if (currentAdapter == NULL) {
|
||||||
// Hopefully the error is caused by transient interface reconfiguration
|
// Hopefully the error is caused by transient interface reconfiguration
|
||||||
printf("Unable to find incoming interface\n");
|
printf("Unable to find incoming interface\n");
|
||||||
return WSAENETDOWN;
|
goto Exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now find an IPv4 address on this interface
|
// Now find an IPv4 address on this interface
|
||||||
@ -205,7 +228,7 @@ FindLocalAddressBySocket(SOCKET s, PIN_ADDR targetAddress)
|
|||||||
if (currentAddress->Address.lpSockaddr->sa_family == AF_INET) {
|
if (currentAddress->Address.lpSockaddr->sa_family == AF_INET) {
|
||||||
PSOCKADDR_IN ifaceAddrV4 = (PSOCKADDR_IN)currentAddress->Address.lpSockaddr;
|
PSOCKADDR_IN ifaceAddrV4 = (PSOCKADDR_IN)currentAddress->Address.lpSockaddr;
|
||||||
*targetAddress = ifaceAddrV4->sin_addr;
|
*targetAddress = ifaceAddrV4->sin_addr;
|
||||||
return 0;
|
goto Exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
currentAddress = currentAddress->Next;
|
currentAddress = currentAddress->Next;
|
||||||
@ -216,9 +239,10 @@ FindLocalAddressBySocket(SOCKET s, PIN_ADDR targetAddress)
|
|||||||
// has no IPv4 connectivity. In this case, we can preserve most
|
// has no IPv4 connectivity. In this case, we can preserve most
|
||||||
// functionality by forwarding via localhost. WoL won't work but
|
// functionality by forwarding via localhost. WoL won't work but
|
||||||
// the basic stuff will.
|
// the basic stuff will.
|
||||||
printf("WARNING: No IPv4 connectivity on incoming interface\n");
|
|
||||||
targetAddress->S_un.S_addr = htonl(INADDR_LOOPBACK);
|
Exit:
|
||||||
return 0;
|
free(addresses);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD
|
DWORD
|
||||||
@ -250,11 +274,7 @@ TcpListenerThreadProc(LPVOID Context)
|
|||||||
RtlZeroMemory(&targetAddress, sizeof(targetAddress));
|
RtlZeroMemory(&targetAddress, sizeof(targetAddress));
|
||||||
targetAddress.sin_family = AF_INET;
|
targetAddress.sin_family = AF_INET;
|
||||||
targetAddress.sin_port = htons(tuple->port);
|
targetAddress.sin_port = htons(tuple->port);
|
||||||
if (FindLocalAddressBySocket(acceptedSocket, &targetAddress.sin_addr) != 0) {
|
FindLocalAddressBySocket(acceptedSocket, &targetAddress.sin_addr);
|
||||||
closesocket(acceptedSocket);
|
|
||||||
closesocket(targetSocket);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (connect(targetSocket, (PSOCKADDR)&targetAddress, sizeof(targetAddress)) == SOCKET_ERROR) {
|
if (connect(targetSocket, (PSOCKADDR)&targetAddress, sizeof(targetAddress)) == SOCKET_ERROR) {
|
||||||
// FIXME: This can race with reopening stdout and cause a crash in the CRT
|
// FIXME: This can race with reopening stdout and cause a crash in the CRT
|
||||||
@ -595,12 +615,7 @@ void UPnPCreatePinholeForPort(struct UPNPUrls* urls, struct IGDdatas* data, int
|
|||||||
|
|
||||||
void UPnPCreatePinholesForInterface(struct UPNPUrls* urls, struct IGDdatas* data, const char* tmpAddr)
|
void UPnPCreatePinholesForInterface(struct UPNPUrls* urls, struct IGDdatas* data, const char* tmpAddr)
|
||||||
{
|
{
|
||||||
union {
|
PIP_ADAPTER_ADDRESSES addresses;
|
||||||
IP_ADAPTER_ADDRESSES addresses;
|
|
||||||
char buffer[8192];
|
|
||||||
};
|
|
||||||
ULONG error;
|
|
||||||
ULONG length;
|
|
||||||
PIP_ADAPTER_ADDRESSES currentAdapter;
|
PIP_ADAPTER_ADDRESSES currentAdapter;
|
||||||
PIP_ADAPTER_UNICAST_ADDRESS currentAddress;
|
PIP_ADAPTER_UNICAST_ADDRESS currentAddress;
|
||||||
in6_addr targetAddress;
|
in6_addr targetAddress;
|
||||||
@ -608,21 +623,16 @@ void UPnPCreatePinholesForInterface(struct UPNPUrls* urls, struct IGDdatas* data
|
|||||||
inet_pton(AF_INET6, tmpAddr, &targetAddress);
|
inet_pton(AF_INET6, tmpAddr, &targetAddress);
|
||||||
|
|
||||||
// Get a list of all interfaces with IPv6 addresses on the system
|
// Get a list of all interfaces with IPv6 addresses on the system
|
||||||
length = sizeof(buffer);
|
addresses = AllocAndGetAdaptersAddresses(AF_INET6,
|
||||||
error = GetAdaptersAddresses(AF_INET6,
|
|
||||||
GAA_FLAG_SKIP_ANYCAST |
|
GAA_FLAG_SKIP_ANYCAST |
|
||||||
GAA_FLAG_SKIP_MULTICAST |
|
GAA_FLAG_SKIP_MULTICAST |
|
||||||
GAA_FLAG_SKIP_DNS_SERVER |
|
GAA_FLAG_SKIP_DNS_SERVER |
|
||||||
GAA_FLAG_SKIP_FRIENDLY_NAME,
|
GAA_FLAG_SKIP_FRIENDLY_NAME);
|
||||||
NULL,
|
if (addresses == NULL) {
|
||||||
&addresses,
|
|
||||||
&length);
|
|
||||||
if (error != ERROR_SUCCESS) {
|
|
||||||
printf("GetAdaptersAddresses() failed: %d\n", error);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
currentAdapter = &addresses;
|
currentAdapter = addresses;
|
||||||
currentAddress = nullptr;
|
currentAddress = nullptr;
|
||||||
while (currentAdapter != nullptr) {
|
while (currentAdapter != nullptr) {
|
||||||
// First, search for the adapter
|
// First, search for the adapter
|
||||||
@ -650,7 +660,7 @@ void UPnPCreatePinholesForInterface(struct UPNPUrls* urls, struct IGDdatas* data
|
|||||||
|
|
||||||
if (currentAdapter == nullptr) {
|
if (currentAdapter == nullptr) {
|
||||||
printf("No adapter found with IPv6 address: %s\n", tmpAddr);
|
printf("No adapter found with IPv6 address: %s\n", tmpAddr);
|
||||||
return;
|
goto Exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now currentAdapter is the adapter we reached the IGD with. Create pinholes for all
|
// Now currentAdapter is the adapter we reached the IGD with. Create pinholes for all
|
||||||
@ -677,6 +687,10 @@ void UPnPCreatePinholesForInterface(struct UPNPUrls* urls, struct IGDdatas* data
|
|||||||
|
|
||||||
currentAddress = currentAddress->Next;
|
currentAddress = currentAddress->Next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Exit:
|
||||||
|
free(addresses);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateUpnpPinholes()
|
void UpdateUpnpPinholes()
|
||||||
@ -744,32 +758,22 @@ void UpdateUpnpPinholes()
|
|||||||
|
|
||||||
void UpdatePcpPinholes()
|
void UpdatePcpPinholes()
|
||||||
{
|
{
|
||||||
union {
|
PIP_ADAPTER_ADDRESSES addresses;
|
||||||
IP_ADAPTER_ADDRESSES addresses;
|
|
||||||
char buffer[8192];
|
|
||||||
};
|
|
||||||
ULONG error;
|
|
||||||
ULONG length;
|
|
||||||
PIP_ADAPTER_ADDRESSES currentAdapter;
|
PIP_ADAPTER_ADDRESSES currentAdapter;
|
||||||
PIP_ADAPTER_UNICAST_ADDRESS currentAddress;
|
PIP_ADAPTER_UNICAST_ADDRESS currentAddress;
|
||||||
|
|
||||||
// Get all IPv6 interfaces
|
// Get all IPv6 interfaces
|
||||||
length = sizeof(buffer);
|
addresses = AllocAndGetAdaptersAddresses(AF_INET6,
|
||||||
error = GetAdaptersAddresses(AF_INET6,
|
|
||||||
GAA_FLAG_SKIP_ANYCAST |
|
GAA_FLAG_SKIP_ANYCAST |
|
||||||
GAA_FLAG_SKIP_MULTICAST |
|
GAA_FLAG_SKIP_MULTICAST |
|
||||||
GAA_FLAG_SKIP_DNS_SERVER |
|
GAA_FLAG_SKIP_DNS_SERVER |
|
||||||
GAA_FLAG_SKIP_FRIENDLY_NAME |
|
GAA_FLAG_SKIP_FRIENDLY_NAME |
|
||||||
GAA_FLAG_INCLUDE_GATEWAYS,
|
GAA_FLAG_INCLUDE_GATEWAYS);
|
||||||
NULL,
|
if (addresses == NULL) {
|
||||||
&addresses,
|
|
||||||
&length);
|
|
||||||
if (error != ERROR_SUCCESS) {
|
|
||||||
printf("GetAdaptersAddresses() failed: %d\n", error);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
currentAdapter = &addresses;
|
currentAdapter = addresses;
|
||||||
while (currentAdapter != NULL) {
|
while (currentAdapter != NULL) {
|
||||||
// Skip over interfaces with no gateway
|
// Skip over interfaces with no gateway
|
||||||
if (currentAdapter->FirstGatewayAddress == NULL) {
|
if (currentAdapter->FirstGatewayAddress == NULL) {
|
||||||
@ -825,6 +829,8 @@ void UpdatePcpPinholes()
|
|||||||
|
|
||||||
currentAdapter = currentAdapter->Next;
|
currentAdapter = currentAdapter->Next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(addresses);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResetLogFile()
|
void ResetLogFile()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user