| 150 | |
| 151 | #ifdef USE_UPNP |
| 152 | static bool ProcessUpnp() |
| 153 | { |
| 154 | bool ret = false; |
| 155 | std::string port = strprintf("%u", GetListenPort()); |
| 156 | const char * multicastif = nullptr; |
| 157 | const char * minissdpdpath = nullptr; |
| 158 | struct UPNPDev * devlist = nullptr; |
| 159 | char lanaddr[64]; |
| 160 | |
| 161 | int error = 0; |
| 162 | #if MINIUPNPC_API_VERSION < 14 |
| 163 | devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error); |
| 164 | #else |
| 165 | devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, 2, &error); |
| 166 | #endif |
| 167 | |
| 168 | struct UPNPUrls urls; |
| 169 | struct IGDdatas data; |
| 170 | int r; |
| 171 | #if MINIUPNPC_API_VERSION <= 17 |
| 172 | r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr)); |
| 173 | #else |
| 174 | r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr), nullptr, 0); |
| 175 | #endif |
| 176 | if (r == 1) |
| 177 | { |
| 178 | if (fDiscover) { |
| 179 | char externalIPAddress[40]; |
| 180 | r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress); |
| 181 | if (r != UPNPCOMMAND_SUCCESS) { |
| 182 | LogPrintf("UPnP: GetExternalIPAddress() returned %d\n", r); |
| 183 | } else { |
| 184 | if (externalIPAddress[0]) { |
| 185 | CNetAddr resolved; |
| 186 | if (LookupHost(externalIPAddress, resolved, false)) { |
| 187 | LogPrintf("UPnP: ExternalIPAddress = %s\n", resolved.ToString()); |
| 188 | AddLocal(resolved, LOCAL_MAPPED); |
| 189 | } |
| 190 | } else { |
| 191 | LogPrintf("UPnP: GetExternalIPAddress failed.\n"); |
| 192 | } |
| 193 | } |
| 194 | } |
| 195 | |
| 196 | std::string strDesc = PACKAGE_NAME " " + FormatFullVersion(); |
| 197 | |
| 198 | do { |
| 199 | r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0, "0"); |
| 200 | |
| 201 | if (r != UPNPCOMMAND_SUCCESS) { |
| 202 | ret = false; |
| 203 | LogPrintf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n", port, port, lanaddr, r, strupnperror(r)); |
| 204 | break; |
| 205 | } else { |
| 206 | ret = true; |
| 207 | LogPrintf("UPnP Port Mapping successful.\n"); |
| 208 | } |
| 209 | } while (g_mapport_interrupt.sleep_for(PORT_MAPPING_REANNOUNCE_PERIOD)); |
no test coverage detected