From 1b8f15e25994c9d0dfc4f5931b551278144563bf Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Tue, 6 Nov 2018 20:24:45 -0800 Subject: [PATCH] Wait for the NAT-PMP response when deleting a conflicting entry --- miss/miss.cpp | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/miss/miss.cpp b/miss/miss.cpp index f69bf54..e502d64 100644 --- a/miss/miss.cpp +++ b/miss/miss.cpp @@ -417,8 +417,41 @@ bool NATPMPMapPort(natpmp_t* natpmp, int proto, int port, bool enable) // It couldn't assign us the external port we requested and gave us an alternate external port. // We can't use this alternate mapping, so immediately release it. - sendnewportmappingrequest(natpmp, natPmpProto, response.pnu.newportmapping.privateport, 0, 0); - return false; + printf("Deleting unwanted NAT-PMP mapping %s %d...", proto == IPPROTO_TCP ? "TCP" : "UDP", response.pnu.newportmapping.mappedpublicport); + err = sendnewportmappingrequest(natpmp, natPmpProto, response.pnu.newportmapping.privateport, 0, 0); + if (err < 0) { + printf("ERROR %d" NL, err); + return false; + } + else { + do { + fd_set fds; + struct timeval timeout; + + FD_ZERO(&fds); + FD_SET(natpmp->s, &fds); + + err = getnatpmprequesttimeout(natpmp, &timeout); + if (err != 0) { + assert(err == 0); + printf("WAIT FAILED: %d" NL, err); + return false; + } + + select(0, &fds, nullptr, nullptr, &timeout); + + err = readnatpmpresponseorretry(natpmp, &response); + } while (err == NATPMP_TRYAGAIN); + + if (err == 0) { + printf("DONE" NL); + return false; + } + else { + printf("FAILED %d" NL, err); + return false; + } + } } else { printf("OK (%d seconds remaining)" NL, response.pnu.newportmapping.lifetime);