Skip to content

Conversation

@happyharryh
Copy link

When compiling ZeroTierOne with MSVC140, the EWOULDBLOCK macro is defined as 140 in errno.h by default, while WSAEWOULDBLOCK is defined as 10035 in winsock2.h. According to the current code, EWOULDBLOCK ultimately resolves to 140. When WSAGetLastError() is used later, the timeout return value is 10035, so it is not handled correctly by the existing logic.

#ifdef WIN32
switch(WSAGetLastError()) {
#else
switch(errno) {
#endif
/*case EAGAIN:*/
case EWOULDBLOCK:
n = NATPMP_TRYAGAIN;
break;
case ECONNREFUSED:
n = NATPMP_ERR_NOGATEWAYSUPPORT;
break;
default:
n = NATPMP_ERR_RECVFROM;
}

As a result, when ZeroTierOne encounters an intermittent timeout from the NAT-PMP service, it immediately tries the next tryPort instead of continuing to retry on the current tryPort for up to 10 seconds as expected.

sendnewportmappingrequest(&natpmp, NATPMP_PROTOCOL_UDP, localPort, tryPort, (ZT_PORTMAPPER_REFRESH_DELAY * 2) / 1000);
myTimeout = OSUtils::now() + 10000;
do {
fd_set fds;
struct timeval timeout;
FD_ZERO(&fds);
FD_SET(natpmp.s, &fds);
getnatpmprequesttimeout(&natpmp, &timeout);
select(FD_SETSIZE, &fds, NULL, NULL, &timeout);
r = readnatpmpresponseorretry(&natpmp, &response);
if (OSUtils::now() >= myTimeout)
break;
} while (r == NATPMP_TRYAGAIN);

This PR redefines EWOULDBLOCK to WSAEWOULDBLOCK (i.e., 10035) so that ZeroTierOne can correctly handle NAT-PMP service timeout events.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant