From d80bdbbc068a75b592f48921414006d64d0d0268 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Sun, 13 Jul 2014 16:42:47 +0000 Subject: fix for borkred listening ports git-svn-id: http://svn.miranda-ng.org/main/trunk@9787 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- src/modules/netlib/netlibbind.cpp | 190 +++++++++++++++++--------------------- 1 file changed, 87 insertions(+), 103 deletions(-) (limited to 'src') diff --git a/src/modules/netlib/netlibbind.cpp b/src/modules/netlib/netlibbind.cpp index 382a00ee37..4d5e7b6ca8 100644 --- a/src/modules/netlib/netlibbind.cpp +++ b/src/modules/netlib/netlibbind.cpp @@ -113,7 +113,8 @@ int NetlibFreeBoundPort(struct NetlibBoundPort *nlbp) { closesocket(nlbp->s); closesocket(nlbp->s6); - WaitForSingleObject(nlbp->hThread, INFINITE); + if (nlbp->hThread) + WaitForSingleObject(nlbp->hThread, INFINITE); NetlibLogf(nlbp->nlu, "(%u) Port %u closed for incoming connections", nlbp->s, nlbp->wPort); mir_free(nlbp); return 1; @@ -121,41 +122,44 @@ int NetlibFreeBoundPort(struct NetlibBoundPort *nlbp) static void NetlibBindAcceptThread(void* param) { - SOCKET s; - SOCKADDR_INET_M sin; - int sinLen; - NetlibConnection *nlc; - struct NetlibBoundPort *nlbp = (NetlibBoundPort*)param; - + NetlibBoundPort *nlbp = (NetlibBoundPort*)param; NetlibLogf(nlbp->nlu, "(%u) Port %u opened for incoming connections", nlbp->s, nlbp->wPort); - while(true) - { + + while (true) { fd_set r; FD_ZERO(&r); - FD_SET(nlbp->s, &r); - FD_SET(nlbp->s6, &r); - - if (select(0, &r, NULL, NULL, NULL) == SOCKET_ERROR) + if (nlbp->s != INVALID_SOCKET) + FD_SET(nlbp->s, &r); + if (nlbp->s6 != INVALID_SOCKET) + FD_SET(nlbp->s6, &r); + if (select(0, &r, NULL, NULL, NULL) == SOCKET_ERROR) { + NetlibLogf(nlbp->nlu, "NetlibBindAcceptThread (%p): select failed (%d)", nlbp->s, GetLastError()); break; + } - sinLen = sizeof(sin); + SOCKADDR_INET_M sin; + int sinLen = sizeof(sin); memset(&sin, 0, sizeof(sin)); - if (FD_ISSET(nlbp->s, &r)) - { - s = accept(nlbp->s, (struct sockaddr*)&sin, &sinLen); - if (s == INVALID_SOCKET) break; + SOCKET s; + if (FD_ISSET(nlbp->s, &r)) { + s = accept(nlbp->s, (sockaddr*)&sin, &sinLen); + if (s == INVALID_SOCKET) { + NetlibLogf(nlbp->nlu, "NetlibBindAcceptThread (%p): accept V4 failed (%d)", nlbp->s, GetLastError()); + break; + } } - else if (FD_ISSET(nlbp->s6, &r)) - { - s = accept(nlbp->s6, (struct sockaddr*)&sin, &sinLen); - if (s == INVALID_SOCKET) break; + else if (FD_ISSET(nlbp->s6, &r)) { + s = accept(nlbp->s6, (sockaddr*)&sin, &sinLen); + if (s == INVALID_SOCKET) { + NetlibLogf(nlbp->nlu, "NetlibBindAcceptThread (%p): accept V6 failed (%d)", nlbp->s, GetLastError()); + break; + } } - char *szHostA = NetlibAddressToString(&sin); - NetlibLogf(nlbp->nlu, "New incoming connection on port %u from %s (%p)", nlbp->wPort, szHostA, s); - mir_free(szHostA); - nlc = (NetlibConnection*)mir_calloc(sizeof(NetlibConnection)); + NetlibLogf(nlbp->nlu, "New incoming connection on port %u from %s (%p)", nlbp->wPort, ptrA(NetlibAddressToString(&sin)), s); + + NetlibConnection *nlc = (NetlibConnection*)mir_calloc(sizeof(NetlibConnection)); nlc->handleType = NLH_CONNECTION; nlc->nlu = nlbp->nlu; nlc->s = s; @@ -168,7 +172,11 @@ static void NetlibBindAcceptThread(void* param) if (nlbp->pfnNewConnectionV2) nlbp->pfnNewConnectionV2(nlc, ntohl(sin.Ipv4.sin_addr.S_un.S_addr), nlbp->pExtra); } + NetlibUPnPDeletePortMapping(nlbp->wExPort, "TCP"); + nlbp->hThread = 0; + + NetlibLogf(nlbp->nlu, "NetlibBindAcceptThread: (%p) thread for port %u closed", nlbp->s, nlbp->wPort); } INT_PTR NetlibBindPort(WPARAM wParam, LPARAM lParam) @@ -176,13 +184,12 @@ INT_PTR NetlibBindPort(WPARAM wParam, LPARAM lParam) NETLIBBIND *nlb = (NETLIBBIND*)lParam; NetlibUser *nlu = (NetlibUser*)wParam; struct NetlibBoundPort *nlbp; - SOCKADDR_IN sin = {0}; - SOCKADDR_IN6 sin6 = {0}; + SOCKADDR_IN sin = { 0 }; + SOCKADDR_IN6 sin6 = { 0 }; int foundPort = 0; if (GetNetlibHandleType(nlu) != NLH_USER || !(nlu->user.flags & NUF_INCOMING) || - nlb == NULL || nlb->pfnNewConnection == NULL) - { + nlb == NULL || nlb->pfnNewConnection == NULL) { SetLastError(ERROR_INVALID_PARAMETER); return 0; } @@ -196,9 +203,8 @@ INT_PTR NetlibBindPort(WPARAM wParam, LPARAM lParam) nlbp->s = socket(PF_INET, SOCK_STREAM, 0); nlbp->s6 = socket(PF_INET6, SOCK_STREAM, 0); - nlbp->pExtra = (nlb->cbSize != NETLIBBIND_SIZEOF_V1) ? nlb->pExtra : NULL; - if (nlbp->s == INVALID_SOCKET && nlbp->s6 == INVALID_SOCKET) - { + nlbp->pExtra = nlb->pExtra; + if (nlbp->s == INVALID_SOCKET && nlbp->s6 == INVALID_SOCKET) { NetlibLogf(nlu, "%s %d: %s() failed (%u)", __FILE__, __LINE__, "socket", WSAGetLastError()); mir_free(nlbp); return 0; @@ -208,29 +214,24 @@ INT_PTR NetlibBindPort(WPARAM wParam, LPARAM lParam) /* if the netlib user wanted a free port given in the range, then they better have given wPort == 0, let's hope so */ - if (nlu->settings.specifyIncomingPorts && nlu->settings.szIncomingPorts && nlb->wPort == 0) - { - if (!BindSocketToPort(nlu->settings.szIncomingPorts, nlbp->s, nlbp->s6, &nlu->outportnum)) - { + if (nlu->settings.specifyIncomingPorts && nlu->settings.szIncomingPorts && nlb->wPort == 0) { + if (!BindSocketToPort(nlu->settings.szIncomingPorts, nlbp->s, nlbp->s6, &nlu->outportnum)) { NetlibLogf(nlu, "Netlib bind: Not enough ports for incoming connections specified"); SetLastError(WSAEADDRINUSE); } - else - foundPort = 1; + else foundPort = 1; } - else - { + else { /* if ->wPort == 0 then they'll get any free port, otherwise they'll be asking for whatever was in nlb->wPort*/ - if (nlb->wPort != 0) - { + if (nlb->wPort != 0) { NetlibLogf(nlu, "%s %d: trying to bind port %d, this 'feature' can be abused, please be sure you want to allow it.", __FILE__, __LINE__, nlb->wPort); sin.sin_port = htons(nlb->wPort); sin6.sin6_port = htons(nlb->wPort); } - if (bind(nlbp->s, (PSOCKADDR)&sin, sizeof(sin)) == 0) - { - SOCKADDR_IN sin = {0}; + + if (bind(nlbp->s, (PSOCKADDR)&sin, sizeof(sin)) == 0) { + SOCKADDR_IN sin = { 0 }; int len = sizeof(sin); if (!getsockname(nlbp->s, (PSOCKADDR)&sin, &len)) sin6.sin6_port = sin.sin_port; @@ -240,8 +241,7 @@ INT_PTR NetlibBindPort(WPARAM wParam, LPARAM lParam) if (bind(nlbp->s6, (PSOCKADDR)&sin6, sizeof(sin6)) == 0) foundPort = 1; } - if (!foundPort) - { + if (!foundPort) { NetlibLogf(nlu, "%s %d: %s() failed (%u)", __FILE__, __LINE__, "bind", WSAGetLastError()); closesocket(nlbp->s); closesocket(nlbp->s6); @@ -249,8 +249,7 @@ INT_PTR NetlibBindPort(WPARAM wParam, LPARAM lParam) return 0; } - if (nlbp->s != INVALID_SOCKET && listen(nlbp->s, 5)) - { + if (nlbp->s != INVALID_SOCKET && listen(nlbp->s, 5)) { NetlibLogf(nlu, "%s %d: %s() failed (%u)", __FILE__, __LINE__, "listen", WSAGetLastError()); closesocket(nlbp->s); closesocket(nlbp->s6); @@ -258,8 +257,7 @@ INT_PTR NetlibBindPort(WPARAM wParam, LPARAM lParam) return 0; } - if (nlbp->s6 != INVALID_SOCKET && listen(nlbp->s6, 5)) - { + if (nlbp->s6 != INVALID_SOCKET && listen(nlbp->s6, 5)) { NetlibLogf(nlu, "%s %d: %s() failed (%u)", __FILE__, __LINE__, "listen", WSAGetLastError()); closesocket(nlbp->s); closesocket(nlbp->s6); @@ -267,61 +265,47 @@ INT_PTR NetlibBindPort(WPARAM wParam, LPARAM lParam) return 0; } - { - SOCKADDR_INET_M sin = {0}; - int len = sizeof(sin); - if (!getsockname(nlbp->s, (PSOCKADDR)&sin, &len)) - { - nlb->wPort = ntohs(sin.Ipv4.sin_port); - nlb->dwInternalIP = ntohl(sin.Ipv4.sin_addr.S_un.S_addr); - } - else if (!getsockname(nlbp->s6, (PSOCKADDR)&sin, &len)) - nlb->wPort = ntohs(sin.Ipv6.sin6_port); - else - { - NetlibLogf(nlu, "%s %d: %s() failed (%u)", __FILE__, __LINE__, "getsockname", WSAGetLastError()); - closesocket(nlbp->s); - closesocket(nlbp->s6); - mir_free(nlbp); - return 0; - } - nlbp->wPort = nlb->wPort; + SOCKADDR_INET_M sinm = { 0 }; + int len = sizeof(sinm); + if (!getsockname(nlbp->s, (PSOCKADDR)&sinm, &len)) { + nlb->wPort = ntohs(sinm.Ipv4.sin_port); + nlb->dwInternalIP = ntohl(sinm.Ipv4.sin_addr.S_un.S_addr); + } + else if (!getsockname(nlbp->s6, (PSOCKADDR)&sinm, &len)) + nlb->wPort = ntohs(sinm.Ipv6.sin6_port); + else { + NetlibLogf(nlu, "%s %d: %s() failed (%u)", __FILE__, __LINE__, "getsockname", WSAGetLastError()); + closesocket(nlbp->s); + closesocket(nlbp->s6); + mir_free(nlbp); + return 0; + } + nlbp->wPort = nlb->wPort; - if (nlb->dwInternalIP == 0) - { - char hostname[64] = ""; - gethostname(hostname, SIZEOF(hostname)); + if (nlb->dwInternalIP == 0) { + char hostname[64] = ""; + gethostname(hostname, SIZEOF(hostname)); - PHOSTENT he = gethostbyname(hostname); - if (he && he->h_addr) - nlb->dwInternalIP = ntohl(*(PDWORD)he->h_addr); - } + PHOSTENT he = gethostbyname(hostname); + if (he && he->h_addr) + nlb->dwInternalIP = ntohl(*(PDWORD)he->h_addr); + } - DWORD extIP; - if (nlu->settings.enableUPnP && - NetlibUPnPAddPortMapping(nlb->wPort, "TCP", &nlbp->wExPort, &extIP, nlb->cbSize > NETLIBBIND_SIZEOF_V2)) - { - NetlibLogf(NULL, "UPnP port mapping succeeded. Internal Port: %u External Port: %u\n", - nlb->wPort, nlbp->wExPort); - if (nlb->cbSize > NETLIBBIND_SIZEOF_V2) - { - nlb->wExPort = nlbp->wExPort; - nlb->dwExternalIP = extIP; - } - } + DWORD extIP; + if (nlu->settings.enableUPnP && NetlibUPnPAddPortMapping(nlb->wPort, "TCP", &nlbp->wExPort, &extIP, true)) { + NetlibLogf(NULL, "UPnP port mapping succeeded. Internal Port: %u External Port: %u\n", nlb->wPort, nlbp->wExPort); + nlb->wExPort = nlbp->wExPort; + nlb->dwExternalIP = extIP; + } + else { + if (nlu->settings.enableUPnP) + NetlibLogf(NULL, "UPnP port mapping failed. Internal Port: %u\n", nlb->wPort); else - { - if (nlu->settings.enableUPnP) - NetlibLogf(NULL, "UPnP port mapping failed. Internal Port: %u\n", nlb->wPort); - else - NetlibLogf(NULL, "UPnP disabled. Internal Port: %u\n", nlb->wPort); - - nlbp->wExPort = 0; - if (nlb->cbSize > NETLIBBIND_SIZEOF_V2) { - nlb->wExPort = nlb->wPort; - nlb->dwExternalIP = nlb->dwInternalIP; - } - } + NetlibLogf(NULL, "UPnP disabled. Internal Port: %u\n", nlb->wPort); + + nlbp->wExPort = 0; + nlb->wExPort = nlb->wPort; + nlb->dwExternalIP = nlb->dwInternalIP; } nlbp->hThread = mir_forkthread(NetlibBindAcceptThread, nlbp); -- cgit v1.2.3