Improved UPnP code - now works more often

This commit is contained in:
Souryo 2016-01-21 17:32:39 -05:00
parent b3c10edf67
commit 28cad4416d
2 changed files with 37 additions and 26 deletions

View file

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

View file

@ -13,7 +13,7 @@ enum class IPProtocol
class UPnPPortMapper class UPnPPortMapper
{ {
private: private:
static wstring GetLocalIP(); static vector<wstring> GetLocalIPs();
public: public:
static bool AddNATPortMapping(uint16_t internalPort, uint16_t externalPort, IPProtocol protocol); static bool AddNATPortMapping(uint16_t internalPort, uint16_t externalPort, IPProtocol protocol);