static unsigned __stdcall NetlibBindAcceptThread(void* param) { SOCKET s; SOCKADDR_IN sin; int sinLen; struct NetlibConnection *nlc; struct NetlibBoundPort *nlbp = (NetlibBoundPort*)param; NetlibLogf(nlbp->nlu, "(%u) Port %u opened for incoming connections", nlbp->s, nlbp->wPort); for(;;) { sinLen = sizeof(sin); s = accept(nlbp->s, (struct sockaddr*)&sin, &sinLen); if (s == INVALID_SOCKET) break; NetlibLogf(nlbp->nlu, "New incoming connection on port %u from %s (%d)", nlbp->wPort, inet_ntoa(sin.sin_addr), s); nlc = (NetlibConnection*)mir_calloc(sizeof(NetlibConnection)); nlc->handleType = NLH_CONNECTION; nlc->nlu = nlbp->nlu; nlc->s = s; nlc->s2 = INVALID_SOCKET; InitializeCriticalSection(&nlc->csHttpSequenceNums); nlc->hOkToCloseEvent = CreateEvent(NULL, TRUE, TRUE, NULL); nlc->dontCloseNow = 0; NetlibInitializeNestedCS(&nlc->ncsSend); NetlibInitializeNestedCS(&nlc->ncsRecv); nlbp->pfnNewConnectionV2((HANDLE)nlc,ntohl(sin.sin_addr.S_un.S_addr), nlbp->pExtra); } NetlibUPnPDeletePortMapping(nlbp->wExPort, "TCP"); return 0; }
void NetlibUPnPCleanup(void*) { // upnp is disabled globally, no need for a cleanup if (db_get_b(NULL, "Netlib", "NLEnableUPnP", 1) == 0) return; { int incoming = 0; mir_cslock lck(csNetlibUser); for (int i = 0; i < netlibUser.getCount(); i++) if (netlibUser[i]->user.flags & NUF_INCOMING) { incoming = 1; break; } if (!incoming) return; } if (findUPnPGateway()) { char *szData = (char*)alloca(4096); char buf[50], lip[50]; unsigned j = 0, k, num = 100; strncpy_s(lip, inet_ntoa(locIP.sin_addr), _TRUNCATE); WaitForSingleObject(portListMutex, INFINITE); if (httpTransact(szCtlUrl, szData, 4096, "PortMappingNumberOfEntries", ControlQuery) == 200 && txtParseParam(szData, "QueryStateVariableResponse", "<return>", "<", buf, sizeof(buf))) num = atol(buf); WORD ports[30]; for (unsigned i = 0; i < num && !Miranda_Terminated(); i++) { mir_snprintf(szData, 4096, get_port_mapping, i); ReleaseMutex(portListMutex); WaitForSingleObject(portListMutex, INFINITE); if (httpTransact(szCtlUrl, szData, 4096, "GetGenericPortMappingEntry", ControlAction) != 200) break; if (!txtParseParam(szData, "<NewPortMappingDescription", ">", "<", buf, sizeof(buf)) || mir_strcmp(buf, "Miranda") != 0) continue; if (!txtParseParam(szData, "<NewInternalClient", ">", "<", buf, sizeof(buf)) || mir_strcmp(buf, lip) != 0) continue; if (txtParseParam(szData, "<NewExternalPort", ">", "<", buf, sizeof(buf))) { WORD mport = (WORD)atol(buf); if (j >= _countof(ports)) break; for (k = 0; k < numports; ++k) if (portList[k] == mport) break; if (k >= numports) ports[j++] = mport; } } ReleaseMutex(portListMutex); for (unsigned i = 0; i < j && !Miranda_Terminated(); i++) NetlibUPnPDeletePortMapping(ports[i], "TCP"); } }