summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGeorge Hazan <george.hazan@gmail.com>2014-07-13 16:42:47 +0000
committerGeorge Hazan <george.hazan@gmail.com>2014-07-13 16:42:47 +0000
commitd80bdbbc068a75b592f48921414006d64d0d0268 (patch)
treeaca90913f71cd3c6bd83ce4dd545e6c4e934dca7 /src
parent90a99f237d2332a5d882c0dcd3e2b4572b04944f (diff)
fix for borkred listening ports
git-svn-id: http://svn.miranda-ng.org/main/trunk@9787 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'src')
-rw-r--r--src/modules/netlib/netlibbind.cpp190
1 files changed, 87 insertions, 103 deletions
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);