The complete source code of IdealIRC http://www.idealirc.org/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
idealirc/NATUtils/PublicAddress.cpp

60 lines
1.6 KiB

/*
* IdealIRC - Internet Relay Chat client
* Copyright (c) 2022 Tom-Andre Barstad.
* This software is licensed under the Software Attribution License.
* See LICENSE for more information.
*/
#include "PublicAddress.h"
#include <natpmp.h>
#include <chrono>
#include <thread>
std::optional<std::uint32_t> NATPublicAddress::get()
{
natpmp_t request;
natpmpresp_t response;
if (initnatpmp(&request, 0, 0) != 0)
return std::nullopt;
auto retry = 10;
auto res = sendpublicaddressrequest(&request);
while (res != 2 && retry > 0) {
if (res == NATPMP_ERR_NOGATEWAYSUPPORT)
return std::nullopt;
std::this_thread::sleep_for( std::chrono::milliseconds(10) );
res = sendpublicaddressrequest(&request);
--retry;
}
if (retry == 0)
return std::nullopt;
auto readres = readnatpmpresponseorretry(&request, &response);
retry = 10;
while (readres != 0 && retry > 0) {
std::this_thread::sleep_for( std::chrono::milliseconds(10) );
readres = readnatpmpresponseorretry(&request, &response);
--retry;
}
if (retry == 0)
return std::nullopt;
/*
* It appears that the DCC requests wants the IP address bytes in reversed order,
* therefore s_addr comes out with the bytes in the reversed order of what we want them.
*/
uint32_t address = response.pnu.publicaddress.addr.s_addr;
uint32_t ret = address & 0xFF;
for (auto i = 1; i < 4; ++i) {
ret <<= 8;
address >>= 8;
ret |= address & 0xFF;
}
return ret;
}