diff --git a/Utilities/UPnPPortMapper.cpp b/Utilities/UPnPPortMapper.cpp index e2a7dd2a..b64e58f8 100644 --- a/Utilities/UPnPPortMapper.cpp +++ b/Utilities/UPnPPortMapper.cpp @@ -35,24 +35,27 @@ bool UPnPPortMapper::AddNATPortMapping(uint16_t internalPort, uint16_t externalP if(!SUCCEEDED(hResult) || spm == nullptr) { std::cout << "Attempting to automatically forward port via UPnP..." << std::endl; - wstring localIP = GetLocalIP(); + vector localIPs = GetLocalIPs(); BSTR desc = SysAllocString(L"Mesen NetPlay"); - BSTR clientStr = SysAllocString(localIP.c_str()); - hResult = spmc->Add(externalPort, proto, internalPort, clientStr, true, desc, &spm); - SysFreeString(clientStr); - SysFreeString(desc); - - if(SUCCEEDED(hResult) && spm) { - //Successfully added a new port mapping - std::cout << std::dec << "Forwarded port " << externalPort << " to IP "; - std::wcout << localIP.c_str() << std::endl; - spm->Release(); - result = true; - } else { - std::cout << "Unable to add UPnP port mapping. "; - std::cout << "IP: "; - std::wcout << localIP.c_str(); - std::cout << " HRESULT: 0x" << std::hex << hResult << std::endl; + spm = nullptr; + + for(size_t i = 0, len = localIPs.size(); i < len; i++) { + BSTR clientStr = SysAllocString(localIPs[i].c_str()); + hResult = spmc->Add(externalPort, proto, internalPort, clientStr, true, desc, &spm); + SysFreeString(clientStr); + SysFreeString(desc); + + if(SUCCEEDED(hResult) && spm) { + //Successfully added a new port mapping + std::cout << std::dec << "Forwarded port " << externalPort << " to IP " << utf8::utf8::encode(localIPs[i]) << std::endl; + result = true; + } else { + std::cout << "Unable to add UPnP port mapping. IP: " << utf8::utf8::encode(localIPs[i]) << " HRESULT: 0x" << std::hex << hResult << std::endl; + } + + if(spm) { + spm->Release(); + } } } else { std::cout << "Unable to add UPnP port mapping." << std::endl; @@ -98,11 +101,11 @@ bool UPnPPortMapper::RemoveNATPortMapping(uint16_t externalPort, IPProtocol prot return result; } -wstring UPnPPortMapper::GetLocalIP() +vector UPnPPortMapper::GetLocalIPs() { - wstring localIP; - + vector localIPs; ADDRINFOW *result = nullptr; + ADDRINFOW *current = nullptr; ADDRINFOW hints; ZeroMemory(&hints, sizeof(hints)); @@ -115,14 +118,22 @@ wstring UPnPPortMapper::GetLocalIP() GetComputerName(hostName, &hostSize); if(GetAddrInfoW(hostName, nullptr, &hints, &result) == 0) { - wchar_t ipAddr[255]; - DWORD ipSize = 255; - if(WSAAddressToString(result->ai_addr, (DWORD)result->ai_addrlen, nullptr, ipAddr, &ipSize) == 0) { - localIP = ipAddr; + current = result; + while(current != nullptr) { + wchar_t ipAddr[255]; + DWORD ipSize = 255; + + if(WSAAddressToString(current->ai_addr, (DWORD)current->ai_addrlen, nullptr, ipAddr, &ipSize) == 0) { + if(std::find(localIPs.begin(), localIPs.end(), ipAddr) == localIPs.end()) { + localIPs.push_back(ipAddr); + } + } + current = current->ai_next; } FreeAddrInfoW(result); } - return localIP; + + return localIPs; } #else diff --git a/Utilities/UPnPPortMapper.h b/Utilities/UPnPPortMapper.h index c284ad31..82f13012 100644 --- a/Utilities/UPnPPortMapper.h +++ b/Utilities/UPnPPortMapper.h @@ -13,7 +13,7 @@ enum class IPProtocol class UPnPPortMapper { private: - static wstring GetLocalIP(); + static vector GetLocalIPs(); public: static bool AddNATPortMapping(uint16_t internalPort, uint16_t externalPort, IPProtocol protocol);