3

I'm astonished by the lack of documentation on miniupnp, I believe there's a lot of people using it, but almost no documentation at all, I found a piece of code in the source of RakNet to guide me.

Now I'm having a conceptual issue...

I'm developing an app that connects to a server via UDP (the server should be accessible, the server UDP port is a specific one which is open, and I can test this using any open port checker), then the server puts two or more clients talking to each other (p2p), so I need to circumvent NAT in the clients for that to work.

I already have NAT punch through working, and that already solves lots of cases.

Now, I want to add the UPNP functionality, to attack the NAT issue with this too.

I'm using miniupnpc, and I handle the connections with Boost.Asio.

struct UPNPDev * devlist = 0;
devlist = upnpDiscover(2000, 0, 0, 0, 0, 0);
if (devlist) {
    std::cout << "\nList of UPNP devices found on the network :\n";

    struct UPNPDev * device;
    for(device = devlist; device; device = device->pNext) {
        std::cout << "\ndesc: " << device->descURL << "\n st: " << device->st << "\n";
    }

    char lanaddr[64];   /* my ip address on the LAN */
    struct UPNPUrls urls;
    struct IGDdatas data;
    if (UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr)) == 1) {
        string port = lexical_cast<string>(socket->local_endpoint().port());

        int r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
            port.c_str(), port.c_str(), lanaddr, 0, "UDP", 0, "0");

        if (r != UPNPCOMMAND_SUCCESS) {
            std::cout << "\nupnp fail";
        }

        char intPort[6];
        char intClient[16];

        char desc[128];
        char enabled[128];
        char leaseDuration[128];
        r = UPNP_GetSpecificPortMappingEntry(urls.controlURL,
            data.first.servicetype,
            port.c_str(), "UDP", 0,
            intClient, intPort,
            desc, enabled, leaseDuration);

        if (r != UPNPCOMMAND_SUCCESS) {
            std::cout << "\nupnp fail";
        }else {
            std::cout << "\nupnp success on port " << port;
        }
    }
}

As you can see, I execute the UPNP after having bound the socket (I bind it without an specific port, like this:)

asio::udp::socket socket(*this->ioService, asio::udp::endpoint());

My question is, does this UPNP execution makes any sense? Will this socket actually use the UPNP port map if I execute the UPNP on the random port bound to the socket AFTER I bind it?

Thanks guys!

Tanner Sansbury
  • 51,153
  • 9
  • 112
  • 169
Aymar Fisherman
  • 388
  • 1
  • 8

0 Answers0