summaryrefslogtreecommitdiff
path: root/src/modules
diff options
context:
space:
mode:
Diffstat (limited to 'src/modules')
-rw-r--r--src/modules/netlib/netlib.cpp56
-rw-r--r--src/modules/netlib/netlib.h14
-rw-r--r--src/modules/netlib/netlibbind.cpp129
-rw-r--r--src/modules/netlib/netlibhttp.cpp4
-rw-r--r--src/modules/netlib/netlibopenconn.cpp204
-rw-r--r--src/modules/netlib/netlibsock.cpp280
-rw-r--r--src/modules/updatenotify/updatenotify.cpp14
7 files changed, 490 insertions, 211 deletions
diff --git a/src/modules/netlib/netlib.cpp b/src/modules/netlib/netlib.cpp
index 000639474f..7cd39b1d7a 100644
--- a/src/modules/netlib/netlib.cpp
+++ b/src/modules/netlib/netlib.cpp
@@ -242,9 +242,11 @@ void NetlibDoClose(NetlibConnection *nlc, bool noShutdown)
INT_PTR NetlibCloseHandle(WPARAM wParam, LPARAM)
{
- switch(GetNetlibHandleType(wParam)) {
+ switch(GetNetlibHandleType(wParam))
+ {
case NLH_USER:
- { struct NetlibUser *nlu=(struct NetlibUser*)wParam;
+ {
+ struct NetlibUser *nlu=(struct NetlibUser*)wParam;
int i;
EnterCriticalSection(&csNetlibUser);
@@ -323,21 +325,24 @@ INT_PTR NetlibCloseHandle(WPARAM wParam, LPARAM)
static INT_PTR NetlibGetSocket(WPARAM wParam, LPARAM)
{
SOCKET s;
- if(wParam==0) {
- s=INVALID_SOCKET;
+ if (wParam == 0)
+ {
+ s = INVALID_SOCKET;
SetLastError(ERROR_INVALID_PARAMETER);
}
- else {
+ else
+ {
WaitForSingleObject(hConnectionHeaderMutex,INFINITE);
- switch(GetNetlibHandleType(wParam)) {
+ switch (GetNetlibHandleType(wParam))
+ {
case NLH_CONNECTION:
- s=((struct NetlibConnection*)wParam)->s;
+ s = ((struct NetlibConnection*)wParam)->s;
break;
case NLH_BOUNDPORT:
- s=((struct NetlibBoundPort*)wParam)->s;
+ s = ((struct NetlibBoundPort*)wParam)->s;
break;
default:
- s=INVALID_SOCKET;
+ s = INVALID_SOCKET;
SetLastError(ERROR_INVALID_PARAMETER);
break;
}
@@ -346,6 +351,35 @@ static INT_PTR NetlibGetSocket(WPARAM wParam, LPARAM)
return s;
}
+INT_PTR NetlibStringToAddressSrv(WPARAM wParam, LPARAM lParam)
+{
+ return (INT_PTR)!NetlibStringToAddress((char*)wParam, (SOCKADDR_INET_M*)lParam);
+}
+
+INT_PTR NetlibAddressToStringSrv(WPARAM wParam, LPARAM lParam)
+{
+ if (wParam)
+ {
+ SOCKADDR_INET_M iaddr = {0};
+ iaddr.Ipv4.sin_family = AF_INET;
+ iaddr.Ipv4.sin_addr.s_addr = htonl((unsigned)lParam);
+ return (INT_PTR)NetlibAddressToString(&iaddr);
+ }
+ else
+ return (INT_PTR)NetlibAddressToString((SOCKADDR_INET_M*)lParam);
+}
+
+INT_PTR NetlibGetConnectionInfoSrv(WPARAM wParam, LPARAM lParam)
+{
+ NetlibGetConnectionInfo((NetlibConnection*)wParam, (NETLIBCONNINFO*)lParam);
+ return 0;
+}
+
+INT_PTR NetlibGetMyIp(WPARAM wParam, LPARAM)
+{
+ return (INT_PTR)GetMyIp((unsigned)wParam);
+}
+
INT_PTR NetlibShutdown(WPARAM wParam, LPARAM)
{
if (wParam)
@@ -623,6 +657,10 @@ int LoadNetlibModule(void)
CreateServiceFunction(MS_NETLIB_GETMOREPACKETS,NetlibPacketRecverGetMore);
CreateServiceFunction(MS_NETLIB_SETPOLLINGTIMEOUT,NetlibHttpSetPollingTimeout);
CreateServiceFunction(MS_NETLIB_STARTSSL,NetlibStartSsl);
+ CreateServiceFunction(MS_NETLIB_STARINGTOADDRESS,NetlibStringToAddressSrv);
+ CreateServiceFunction(MS_NETLIB_ADDRESSTOSTRING,NetlibAddressToStringSrv);
+ CreateServiceFunction(MS_NETLIB_GETCONNECTIONINFO,NetlibGetConnectionInfoSrv);
+ CreateServiceFunction(MS_NETLIB_GETMYIP,NetlibGetMyIp);
hRecvEvent = CreateHookableEvent(ME_NETLIB_FASTRECV);
hSendEvent = CreateHookableEvent(ME_NETLIB_FASTSEND);
diff --git a/src/modules/netlib/netlib.h b/src/modules/netlib/netlib.h
index 575e77f18c..8939e7fafc 100644
--- a/src/modules/netlib/netlib.h
+++ b/src/modules/netlib/netlib.h
@@ -52,6 +52,12 @@ struct NetlibHTTPProxyPacketQueue
int dataBufferLen;
};
+typedef union _SOCKADDR_INET_M {
+ SOCKADDR_IN Ipv4;
+ SOCKADDR_IN6 Ipv6;
+ USHORT si_family;
+} SOCKADDR_INET_M, *PSOCKADDR_INET_M;
+
struct NetlibConnection
{
int handleType;
@@ -83,6 +89,7 @@ struct NetlibConnection
struct NetlibBoundPort {
int handleType;
SOCKET s;
+ SOCKET s6;
WORD wPort;
WORD wExPort;
struct NetlibUser *nlu;
@@ -123,7 +130,7 @@ bool NetlibGetIeProxyConn(NetlibConnection *nlc, bool forceHttps);
//netlibbind.c
int NetlibFreeBoundPort(struct NetlibBoundPort *nlbp);
INT_PTR NetlibBindPort(WPARAM wParam,LPARAM lParam);
-bool BindSocketToPort(const char *szPorts, SOCKET s, int* portn);
+bool BindSocketToPort(const char *szPorts, SOCKET s, SOCKET s6, int* portn);
//netlibhttp.c
INT_PTR NetlibHttpSendRequest(WPARAM wParam,LPARAM lParam);
@@ -179,6 +186,11 @@ INT_PTR NetlibSelect(WPARAM wParam,LPARAM lParam);
INT_PTR NetlibSelectEx(WPARAM wParam,LPARAM lParam);
INT_PTR NetlibShutdown(WPARAM wParam,LPARAM lParam);
+bool NetlibStringToAddress(const char* str, SOCKADDR_INET_M* addr);
+char* NetlibAddressToString(SOCKADDR_INET_M* addr);
+void NetlibGetConnectionInfo(NetlibConnection* nlc, NETLIBCONNINFO *connInfo);
+NETLIBIPLIST* GetMyIp(unsigned flags);
+
//netlibupnp.c
bool NetlibUPnPAddPortMapping(WORD intport, char *proto,
WORD *extport, DWORD *extip, bool search);
diff --git a/src/modules/netlib/netlibbind.cpp b/src/modules/netlib/netlibbind.cpp
index 6c0c4c19e9..5fb9c252cc 100644
--- a/src/modules/netlib/netlibbind.cpp
+++ b/src/modules/netlib/netlibbind.cpp
@@ -2,7 +2,7 @@
Miranda IM: the free IM client for Microsoft* Windows*
-Copyright 2000-2009 Miranda ICQ/IM project,
+Copyright 2000-2012 Miranda ICQ/IM project,
all portions of this codebase are copyrighted to the people
listed in contributors.txt.
@@ -23,17 +23,19 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "commonheaders.h"
#include "netlib.h"
-bool BindSocketToPort(const char *szPorts, SOCKET s, int* portn)
+bool BindSocketToPort(const char *szPorts, SOCKET s, SOCKET s6, int* portn)
{
SOCKADDR_IN sin = {0};
sin.sin_family = AF_INET;
- sin.sin_addr.s_addr = htonl(INADDR_ANY);
+
+ SOCKADDR_IN6 sin6 = {0};
+ sin6.sin6_family = AF_INET6;
EnterCriticalSection(&csNetlibUser);
- if (--*portn < 0 && s != INVALID_SOCKET)
+ if (--*portn < 0 && (s != INVALID_SOCKET || s6 != INVALID_SOCKET))
{
- BindSocketToPort(szPorts, INVALID_SOCKET, portn);
+ BindSocketToPort(szPorts, INVALID_SOCKET, INVALID_SOCKET, portn);
if (*portn == 0)
{
LeaveCriticalSection(&csNetlibUser);
@@ -88,7 +90,12 @@ bool BindSocketToPort(const char *szPorts, SOCKET s, int* portn)
}
sin.sin_port = htons((WORD)port);
- if (bind(s, (SOCKADDR*)&sin, sizeof(sin)) == 0)
+ bool bV4Mapped = s == INVALID_SOCKET || bind(s, (SOCKADDR*)&sin, sizeof(sin)) == 0;
+
+ sin6.sin6_port = htons((WORD)port);
+ bool bV6Mapped = s6 == INVALID_SOCKET || bind(s6, (PSOCKADDR)&sin6, sizeof(sin6)) == 0;
+
+ if (bV4Mapped && bV6Mapped)
{
LeaveCriticalSection(&csNetlibUser);
*portn = portnum + 1;
@@ -111,10 +118,10 @@ bool BindSocketToPort(const char *szPorts, SOCKET s, int* portn)
}
}
-
int NetlibFreeBoundPort(struct NetlibBoundPort *nlbp)
{
closesocket(nlbp->s);
+ closesocket(nlbp->s6);
WaitForSingleObject(nlbp->hThread,INFINITE);
CloseHandle(nlbp->hThread);
NetlibLogf(nlbp->nlu, "(%u) Port %u closed for incoming connections", nlbp->s, nlbp->wPort);
@@ -125,18 +132,39 @@ int NetlibFreeBoundPort(struct NetlibBoundPort *nlbp)
static unsigned __stdcall NetlibBindAcceptThread(void* param)
{
SOCKET s;
- SOCKADDR_IN sin;
+ SOCKADDR_INET_M 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(;;)
+ for (;;)
{
+ 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)
+ break;
+
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);
+ memset(&sin, 0, sizeof(sin));
+
+ if (FD_ISSET(nlbp->s, &r))
+ {
+ s = accept(nlbp->s, (struct sockaddr*)&sin, &sinLen);
+ if (s == INVALID_SOCKET) break;
+ }
+ else if (FD_ISSET(nlbp->s6, &r))
+ {
+ s = accept(nlbp->s6, (struct sockaddr*)&sin, &sinLen);
+ if (s == INVALID_SOCKET) 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));
nlc->handleType = NLH_CONNECTION;
nlc->nlu = nlbp->nlu;
@@ -144,21 +172,22 @@ static unsigned __stdcall NetlibBindAcceptThread(void* param)
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);
+
+ if (nlbp->pfnNewConnectionV2) nlbp->pfnNewConnectionV2(nlc, ntohl(sin.Ipv4.sin_addr.S_un.S_addr), nlbp->pExtra);
}
NetlibUPnPDeletePortMapping(nlbp->wExPort, "TCP");
return 0;
}
-INT_PTR NetlibBindPort(WPARAM wParam,LPARAM lParam)
+INT_PTR NetlibBindPort(WPARAM wParam, LPARAM lParam)
{
NETLIBBIND *nlb = (NETLIBBIND*)lParam;
struct NetlibUser *nlu = (struct NetlibUser*)wParam;
struct NetlibBoundPort *nlbp;
- SOCKADDR_IN sin;
+ SOCKADDR_IN sin = {0};
+ SOCKADDR_IN6 sin6 = {0};
int foundPort = 0;
UINT dwThreadId;
@@ -178,23 +207,24 @@ INT_PTR NetlibBindPort(WPARAM wParam,LPARAM lParam)
nlbp->handleType = NLH_BOUNDPORT;
nlbp->nlu = nlu;
nlbp->pfnNewConnectionV2 = nlb->pfnNewConnectionV2;
- nlbp->s = socket(AF_INET, SOCK_STREAM, 0);
+
+ 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)
+ 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;
}
sin.sin_family = AF_INET;
- sin.sin_addr.s_addr = htonl(INADDR_ANY);
- sin.sin_port = 0;
+ sin6.sin6_family = AF_INET6;
/* 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, &nlu->outportnum))
+ if (!BindSocketToPort(nlu->settings.szIncomingPorts, nlbp->s, nlbp->s6, &nlu->outportnum))
{
NetlibLogf(nlu, "Netlib bind: Not enough ports for incoming connections specified");
SetLastError(WSAEADDRINUSE);
@@ -210,52 +240,78 @@ INT_PTR NetlibBindPort(WPARAM wParam,LPARAM lParam)
{
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};
+ int len = sizeof(sin);
+ if (!getsockname(nlbp->s, (PSOCKADDR)&sin, &len))
+ sin6.sin6_port = sin.sin_port;
+ foundPort = 1;
+ }
+
+ if (bind(nlbp->s6, (PSOCKADDR)&sin6, sizeof(sin6)) == 0)
foundPort = 1;
}
if (!foundPort)
{
NetlibLogf(nlu,"%s %d: %s() failed (%u)",__FILE__,__LINE__,"bind",WSAGetLastError());
closesocket(nlbp->s);
+ closesocket(nlbp->s6);
mir_free(nlbp);
return 0;
}
- if (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);
mir_free(nlbp);
return 0;
}
- { int len;
- DWORD extIP;
+ 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);
+ mir_free(nlbp);
+ return 0;
+ }
- ZeroMemory(&sin,sizeof(sin));
- len = sizeof(sin);
- if (getsockname(nlbp->s,(SOCKADDR *)&sin,&len))
+ {
+ 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;
}
- nlb->wPort = ntohs(sin.sin_port);
nlbp->wPort = nlb->wPort;
- nlb->dwInternalIP = ntohl(sin.sin_addr.S_un.S_addr);
if (nlb->dwInternalIP == 0)
{
- char hostname[64];
- struct hostent *he;
-
+ char hostname[64] = "";
gethostname(hostname, SIZEOF(hostname));
- he = gethostbyname(hostname);
- if (he && he->h_addr_list[0])
- nlb->dwInternalIP = ntohl(*(PDWORD)he->h_addr_list[0]);
- }
+
+ 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))
{
@@ -282,6 +338,7 @@ INT_PTR NetlibBindPort(WPARAM wParam,LPARAM lParam)
}
}
}
+
nlbp->hThread = (HANDLE)forkthreadex(NULL, 0, NetlibBindAcceptThread, 0, nlbp, &dwThreadId);
return (INT_PTR)nlbp;
}
diff --git a/src/modules/netlib/netlibhttp.cpp b/src/modules/netlib/netlibhttp.cpp
index 970a28cb10..2893344ade 100644
--- a/src/modules/netlib/netlibhttp.cpp
+++ b/src/modules/netlib/netlibhttp.cpp
@@ -525,9 +525,9 @@ INT_PTR NetlibHttpSendRequest(WPARAM wParam, LPARAM lParam)
if (ip && szHost)
{
mir_free(szHost);
- szHost = (char*)mir_alloc(30);
+ szHost = (char*)mir_alloc(64);
if (cln) *cln = ':';
- mir_snprintf(szHost, 30, "%s%s", inet_ntoa(*(PIN_ADDR)&ip), cln ? cln : "");
+ mir_snprintf(szHost, 64, "%s%s", inet_ntoa(*(PIN_ADDR)&ip), cln ? cln : "");
}
/*
if (ip && pszUrl[0] != '/')
diff --git a/src/modules/netlib/netlibopenconn.cpp b/src/modules/netlib/netlibopenconn.cpp
index b9d4753b9a..f24906b20c 100644
--- a/src/modules/netlib/netlibopenconn.cpp
+++ b/src/modules/netlib/netlibopenconn.cpp
@@ -219,15 +219,19 @@ static int NetlibInitSocks5Connection(struct NetlibConnection *nlc,struct Netlib
int nHostLen;
DWORD hostIP;
- if(nlc->dnsThroughProxy) {
- if((hostIP=inet_addr(nloc->szHost))==INADDR_NONE)
- nHostLen=lstrlenA(nloc->szHost)+1;
- else nHostLen=4;
+ if (nlc->dnsThroughProxy)
+ {
+ hostIP = inet_addr(nloc->szHost);
+ if(hostIP == INADDR_NONE)
+ nHostLen = lstrlenA(nloc->szHost)+1;
+ else nHostLen = 4;
}
- else {
- if((hostIP=DnsLookup(nlu,nloc->szHost))==0)
+ else
+ {
+ hostIP = DnsLookup(nlu,nloc->szHost);
+ if (hostIP == 0)
return 0;
- nHostLen=4;
+ nHostLen = 4;
}
pInit=(PBYTE)mir_alloc(6+nHostLen);
pInit[0]=5; //SOCKS5
@@ -394,8 +398,9 @@ static bool my_connectIPv4(NetlibConnection *nlc, NETLIBOPENCONNECTION * nloc)
if (Miranda_Terminated()) return false;
}
- SOCKADDR_IN sin = {0};
- sin.sin_family = AF_INET;
+ PHOSTENT he;
+ SOCKADDR_IN sin = {0};
+ sin.sin_family = AF_INET;
if (nlc->proxyType)
{
@@ -405,107 +410,124 @@ static bool my_connectIPv4(NetlibConnection *nlc, NETLIBOPENCONNECTION * nloc)
NetlibLogf(nlc->nlu,"(%p) Connecting to proxy %s:%d for %s:%d ....", nlc, nlc->szProxyServer, nlc->wProxyPort, nloc->szHost, nloc->wPort);
else
NetlibLogf(nlc->nlu,"(%p) Connecting to proxy %s:%d ....", nlc, nlc->szProxyServer, nlc->wProxyPort);
-
+
sin.sin_port = htons(nlc->wProxyPort);
- sin.sin_addr.s_addr = DnsLookup(nlc->nlu, nlc->szProxyServer);
+ he = gethostbyname(nlc->szProxyServer);
}
else
{
- if (!nloc || !nloc->szHost) return false;
+ if (!nloc || !nloc->szHost || nloc->szHost[0] == '[' || strchr(nloc->szHost, ':')) return false;
NetlibLogf(nlc->nlu,"(%p) Connecting to server %s:%d....", nlc, nloc->szHost, nloc->wPort);
sin.sin_port = htons(nloc->wPort);
- sin.sin_addr.s_addr = DnsLookup(nlc->nlu, nloc->szHost);
+ he = gethostbyname(nloc->szHost);
}
-retry:
- nlc->s = socket(AF_INET,nloc->flags & NLOCF_UDP ? SOCK_DGRAM : SOCK_STREAM, 0);
- if (nlc->s == INVALID_SOCKET) return false;
+ for (char** har = he->h_addr_list; *har && !Miranda_Terminated(); ++har)
+ {
+ sin.sin_addr.s_addr = *(u_long*)*har;
- // return the socket to non blocking
- if (ioctlsocket(nlc->s, FIONBIO, &notblocking) != 0) return false;
+ char* szIp = NetlibAddressToString((SOCKADDR_INET_M*)&sin);
+ NetlibLogf(nlc->nlu,"(%p) Connecting to ip %s ....", nlc, szIp);
+ mir_free(szIp);
- if (nlc->nlu->settings.specifyOutgoingPorts && nlc->nlu->settings.szOutgoingPorts && nlc->nlu->settings.szOutgoingPorts[0])
- {
- if (!BindSocketToPort(nlc->nlu->settings.szOutgoingPorts, nlc->s, &nlc->nlu->inportnum))
- NetlibLogf(nlc->nlu,"Netlib connect: Not enough ports for outgoing connections specified");
- }
+retry:
+ nlc->s = socket(AF_INET, nloc->flags & NLOCF_UDP ? SOCK_DGRAM : SOCK_STREAM, 0);
+ if (nlc->s == INVALID_SOCKET) return false;
- // try a connect
- if (connect(nlc->s, (LPSOCKADDR)&sin, sizeof(sin)) == 0)
- {
- goto unblock;
- }
+ // return the socket to non blocking
+ if (ioctlsocket(nlc->s, FIONBIO, &notblocking) != 0) return false;
- // didn't work, was it cos of nonblocking?
- if (WSAGetLastError() != WSAEWOULDBLOCK)
- {
- rc = SOCKET_ERROR;
- goto unblock;
- }
+ if (nlc->nlu->settings.specifyOutgoingPorts && nlc->nlu->settings.szOutgoingPorts && nlc->nlu->settings.szOutgoingPorts[0])
+ {
+ if (!BindSocketToPort(nlc->nlu->settings.szOutgoingPorts, nlc->s, INVALID_SOCKET, &nlc->nlu->inportnum))
+ NetlibLogf(nlc->nlu,"Netlib connect: Not enough ports for outgoing connections specified");
+ }
- for (;;)
- {
- fd_set r, w, e;
- FD_ZERO(&r); FD_ZERO(&w); FD_ZERO(&e);
- FD_SET(nlc->s, &r);
- FD_SET(nlc->s, &w);
- FD_SET(nlc->s, &e);
- if ((rc = select(0, &r, &w, &e, &tv)) == SOCKET_ERROR)
+ // try a connect
+ if (connect(nlc->s, (LPSOCKADDR)&sin, sizeof(sin)) == 0)
+ {
+ rc = 0;
break;
+ }
+
+ // didn't work, was it cos of nonblocking?
+ if (WSAGetLastError() != WSAEWOULDBLOCK)
+ {
+ rc = SOCKET_ERROR;
+
+ closesocket(nlc->s);
+ nlc->s = INVALID_SOCKET;
+ continue;
+ }
+
+ for (;;)
+ {
+ fd_set r, w, e;
+ FD_ZERO(&r); FD_ZERO(&w); FD_ZERO(&e);
+ FD_SET(nlc->s, &r);
+ FD_SET(nlc->s, &w);
+ FD_SET(nlc->s, &e);
+ if ((rc = select(0, &r, &w, &e, &tv)) == SOCKET_ERROR)
+ break;
- if (rc > 0)
- {
- if (FD_ISSET(nlc->s, &w))
+ if (rc > 0)
+ {
+ if (FD_ISSET(nlc->s, &w))
+ {
+ // connection was successful
+ rc = 0;
+ }
+ if (FD_ISSET(nlc->s, &r))
+ {
+ // connection was closed
+ rc = SOCKET_ERROR;
+ lasterr = WSAECONNRESET;
+ }
+ if (FD_ISSET(nlc->s, &e))
+ {
+ // connection failed.
+ int len = sizeof(lasterr);
+ rc = SOCKET_ERROR;
+ getsockopt(nlc->s, SOL_SOCKET, SO_ERROR, (char*)&lasterr, &len);
+ if (lasterr == WSAEADDRINUSE && ++retrycnt <= 2)
+ {
+ closesocket(nlc->s);
+ goto retry;
+ }
+ }
+ break;
+ }
+ else if (Miranda_Terminated())
{
- // connection was successful
- rc = 0;
- }
- if (FD_ISSET(nlc->s, &r))
+ rc = SOCKET_ERROR;
+ lasterr = ERROR_TIMEOUT;
+ break;
+ }
+ else if (nloc->cbSize == sizeof(NETLIBOPENCONNECTION) && nloc->flags & NLOCF_V2 &&
+ nloc->waitcallback != NULL && nloc->waitcallback(&dwTimeout) == 0)
{
- // connection was closed
rc = SOCKET_ERROR;
- lasterr = WSAECONNRESET;
+ lasterr = ERROR_TIMEOUT;
+ break;
}
- if (FD_ISSET(nlc->s, &e))
+ if (--dwTimeout == 0)
{
- // connection failed.
- int len = sizeof(lasterr);
rc = SOCKET_ERROR;
- getsockopt(nlc->s, SOL_SOCKET, SO_ERROR, (char*)&lasterr, &len);
- if (lasterr == WSAEADDRINUSE && ++retrycnt <= 2)
- {
- closesocket(nlc->s);
- goto retry;
- }
+ lasterr = ERROR_TIMEOUT;
+ break;
}
- break;
- }
- else if (Miranda_Terminated())
- {
- rc = SOCKET_ERROR;
- lasterr = ERROR_TIMEOUT;
- break;
- }
- else if (nloc->cbSize == sizeof(NETLIBOPENCONNECTION) && nloc->flags & NLOCF_V2 &&
- nloc->waitcallback != NULL && nloc->waitcallback(&dwTimeout) == 0)
- {
- rc = SOCKET_ERROR;
- lasterr = ERROR_TIMEOUT;
- break;
- }
- if (--dwTimeout == 0)
- {
- rc = SOCKET_ERROR;
- lasterr = ERROR_TIMEOUT;
- break;
}
+
+ if (rc == 0) break;
+
+ closesocket(nlc->s);
+ nlc->s = INVALID_SOCKET;
}
-unblock:
notblocking = 0;
- ioctlsocket(nlc->s, FIONBIO, &notblocking);
- if (lasterr) SetLastError(lasterr);
+ if (nlc->s != INVALID_SOCKET) ioctlsocket(nlc->s, FIONBIO, &notblocking);
+ if (rc && lasterr) SetLastError(lasterr);
return rc == 0;
}
@@ -548,7 +570,7 @@ static bool my_connectIPv6(NetlibConnection *nlc, NETLIBOPENCONNECTION * nloc)
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
}
-
+
if (nlc->proxyType)
{
if (!nlc->szProxyServer) return false;
@@ -579,8 +601,11 @@ static bool my_connectIPv6(NetlibConnection *nlc, NETLIBOPENCONNECTION * nloc)
}
}
- for (ai = air; ai && !Miranda_Terminated(); ai = ai->ai_next)
+ for (ai = air; ai && !Miranda_Terminated(); ai = ai->ai_next)
{
+ char* szIp = NetlibAddressToString((SOCKADDR_INET_M*)ai->ai_addr);
+ NetlibLogf(nlc->nlu,"(%p) Connecting to ip %s ....", nlc, szIp);
+ mir_free(szIp);
retry:
nlc->s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
if (nlc->s == INVALID_SOCKET) return false;
@@ -590,7 +615,9 @@ retry:
if (nlc->nlu->settings.specifyOutgoingPorts && nlc->nlu->settings.szOutgoingPorts && nlc->nlu->settings.szOutgoingPorts[0])
{
- if (!BindSocketToPort(nlc->nlu->settings.szOutgoingPorts, nlc->s, &nlc->nlu->inportnum))
+ SOCKET s = ai->ai_family == AF_INET ? nlc->s : INVALID_SOCKET;
+ SOCKET s6 = ai->ai_family == AF_INET6 ? nlc->s : INVALID_SOCKET;
+ if (!BindSocketToPort(nlc->nlu->settings.szOutgoingPorts, s, s6, &nlc->nlu->inportnum))
NetlibLogf(nlc->nlu,"Netlib connect: Not enough ports for outgoing connections specified");
}
@@ -605,7 +632,10 @@ retry:
if (WSAGetLastError() != WSAEWOULDBLOCK)
{
rc = SOCKET_ERROR;
- break;
+
+ closesocket(nlc->s);
+ nlc->s = INVALID_SOCKET;
+ continue;
}
for (;;) // timeout loop
diff --git a/src/modules/netlib/netlibsock.cpp b/src/modules/netlib/netlibsock.cpp
index 875c47b0a1..8ec6a473f5 100644
--- a/src/modules/netlib/netlibsock.cpp
+++ b/src/modules/netlib/netlibsock.cpp
@@ -2,7 +2,7 @@
Miranda IM: the free IM client for Microsoft* Windows*
-Copyright 2000-2009 Miranda ICQ/IM project,
+Copyright 2000-2012 Miranda ICQ/IM project,
all portions of this codebase are copyrighted to the people
listed in contributors.txt.
@@ -23,69 +23,73 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "commonheaders.h"
#include "netlib.h"
-extern HANDLE hConnectionHeaderMutex,hSendEvent,hRecvEvent;
+extern HANDLE hConnectionHeaderMutex, hSendEvent, hRecvEvent;
-INT_PTR NetlibSend(WPARAM wParam,LPARAM lParam)
+INT_PTR NetlibSend(WPARAM wParam, LPARAM lParam)
{
- struct NetlibConnection *nlc=(struct NetlibConnection*)wParam;
- NETLIBBUFFER *nlb=(NETLIBBUFFER*)lParam;
+ NetlibConnection *nlc = (NetlibConnection*)wParam;
+ NETLIBBUFFER *nlb = (NETLIBBUFFER*)lParam;
INT_PTR result;
- if ( nlb == NULL ) {
+ if (nlb == NULL)
+ {
SetLastError(ERROR_INVALID_PARAMETER);
return SOCKET_ERROR;
}
- if ( !NetlibEnterNestedCS( nlc, NLNCS_SEND ))
+ if (!NetlibEnterNestedCS(nlc, NLNCS_SEND))
return SOCKET_ERROR;
- if ( nlc->usingHttpGateway && !( nlb->flags & MSG_RAW )) {
- if ( !( nlb->flags & MSG_NOHTTPGATEWAYWRAP ) && nlc->nlu->user.pfnHttpGatewayWrapSend ) {
- NetlibDumpData( nlc, ( PBYTE )nlb->buf, nlb->len, 1, nlb->flags );
- result = nlc->nlu->user.pfnHttpGatewayWrapSend(( HANDLE )nlc, ( PBYTE )nlb->buf, nlb->len, nlb->flags | MSG_NOHTTPGATEWAYWRAP, NetlibSend );
+ if (nlc->usingHttpGateway && !(nlb->flags & MSG_RAW))
+ {
+ if (!(nlb->flags & MSG_NOHTTPGATEWAYWRAP) && nlc->nlu->user.pfnHttpGatewayWrapSend)
+ {
+ NetlibDumpData(nlc, (PBYTE)nlb->buf, nlb->len, 1, nlb->flags);
+ result = nlc->nlu->user.pfnHttpGatewayWrapSend((HANDLE)nlc, (PBYTE)nlb->buf, nlb->len, nlb->flags | MSG_NOHTTPGATEWAYWRAP, NetlibSend);
}
- else result = NetlibHttpGatewayPost( nlc, nlb->buf, nlb->len, nlb->flags );
+ else result = NetlibHttpGatewayPost(nlc, nlb->buf, nlb->len, nlb->flags);
}
else {
- NetlibDumpData( nlc, ( PBYTE )nlb->buf, nlb->len, 1, nlb->flags );
+ NetlibDumpData(nlc, (PBYTE)nlb->buf, nlb->len, 1, nlb->flags);
if (nlc->hSsl)
- result = si.write( nlc->hSsl, nlb->buf, nlb->len );
+ result = si.write(nlc->hSsl, nlb->buf, nlb->len);
else
- result = send( nlc->s, nlb->buf, nlb->len, nlb->flags & 0xFFFF );
+ result = send(nlc->s, nlb->buf, nlb->len, nlb->flags & 0xFFFF);
}
- NetlibLeaveNestedCS( &nlc->ncsSend );
+ NetlibLeaveNestedCS(&nlc->ncsSend);
- if ((( THook* )hSendEvent)->subscriberCount ) {
+ if (((THook*)hSendEvent)->subscriberCount)
+ {
NETLIBNOTIFY nln = { nlb, result };
- CallHookSubscribers( hSendEvent, (WPARAM)&nln, (LPARAM)&nlc->nlu->user );
+ CallHookSubscribers(hSendEvent, (WPARAM)&nln, (LPARAM)&nlc->nlu->user);
}
return result;
}
-INT_PTR NetlibRecv(WPARAM wParam,LPARAM lParam)
+INT_PTR NetlibRecv(WPARAM wParam, LPARAM lParam)
{
- struct NetlibConnection *nlc = (struct NetlibConnection*)wParam;
- NETLIBBUFFER* nlb = ( NETLIBBUFFER* )lParam;
+ NetlibConnection *nlc = (NetlibConnection*)wParam;
+ NETLIBBUFFER* nlb = (NETLIBBUFFER*)lParam;
int recvResult;
- if ( nlb == NULL ) {
- SetLastError( ERROR_INVALID_PARAMETER );
+ if (nlb == NULL) {
+ SetLastError(ERROR_INVALID_PARAMETER);
return SOCKET_ERROR;
}
- if ( !NetlibEnterNestedCS( nlc, NLNCS_RECV ))
+ if (!NetlibEnterNestedCS(nlc, NLNCS_RECV))
return SOCKET_ERROR;
- if ( nlc->usingHttpGateway && !( nlb->flags & MSG_RAW ))
- recvResult = NetlibHttpGatewayRecv( nlc, nlb->buf, nlb->len, nlb->flags );
+ if (nlc->usingHttpGateway && !(nlb->flags & MSG_RAW))
+ recvResult = NetlibHttpGatewayRecv(nlc, nlb->buf, nlb->len, nlb->flags);
else
{
if (nlc->hSsl)
- recvResult = si.read( nlc->hSsl, nlb->buf, nlb->len, (nlb->flags & MSG_PEEK) != 0 );
+ recvResult = si.read(nlc->hSsl, nlb->buf, nlb->len, (nlb->flags & MSG_PEEK) != 0);
else
- recvResult = recv( nlc->s, nlb->buf, nlb->len, nlb->flags & 0xFFFF );
+ recvResult = recv(nlc->s, nlb->buf, nlb->len, nlb->flags & 0xFFFF);
}
- NetlibLeaveNestedCS( &nlc->ncsRecv );
+ NetlibLeaveNestedCS(&nlc->ncsRecv);
if (recvResult <= 0)
return recvResult;
@@ -101,18 +105,20 @@ INT_PTR NetlibRecv(WPARAM wParam,LPARAM lParam)
static int ConnectionListToSocketList(HANDLE *hConns, fd_set *fd, int& pending)
{
- struct NetlibConnection *nlcCheck;
+ NetlibConnection *nlcCheck;
int i;
FD_ZERO(fd);
- for(i=0;hConns[i] && hConns[i]!=INVALID_HANDLE_VALUE && i<FD_SETSIZE;i++) {
- nlcCheck=(struct NetlibConnection*)hConns[i];
- if (nlcCheck->handleType!=NLH_CONNECTION && nlcCheck->handleType!=NLH_BOUNDPORT) {
+ for (i = 0; hConns[i] && hConns[i] != INVALID_HANDLE_VALUE && i < FD_SETSIZE; i++)
+ {
+ nlcCheck = (NetlibConnection*)hConns[i];
+ if (nlcCheck->handleType != NLH_CONNECTION && nlcCheck->handleType != NLH_BOUNDPORT)
+ {
SetLastError(ERROR_INVALID_DATA);
return 0;
}
FD_SET(nlcCheck->s,fd);
- if ( si.pending( nlcCheck->hSsl ))
+ if (si.pending(nlcCheck->hSsl))
pending++;
}
return 1;
@@ -120,8 +126,9 @@ static int ConnectionListToSocketList(HANDLE *hConns, fd_set *fd, int& pending)
INT_PTR NetlibSelect(WPARAM,LPARAM lParam)
{
- NETLIBSELECT *nls=(NETLIBSELECT*)lParam;
- if (nls==NULL || nls->cbSize!=sizeof(NETLIBSELECT)) {
+ NETLIBSELECT *nls = (NETLIBSELECT*)lParam;
+ if (nls == NULL || nls->cbSize != sizeof(NETLIBSELECT))
+ {
SetLastError(ERROR_INVALID_PARAMETER);
return SOCKET_ERROR;
}
@@ -132,54 +139,58 @@ INT_PTR NetlibSelect(WPARAM,LPARAM lParam)
int pending = 0;
fd_set readfd, writefd, exceptfd;
- WaitForSingleObject(hConnectionHeaderMutex,INFINITE);
- if (!ConnectionListToSocketList(nls->hReadConns,&readfd,pending)
- || !ConnectionListToSocketList(nls->hWriteConns,&writefd,pending)
- || !ConnectionListToSocketList(nls->hExceptConns,&exceptfd,pending)) {
- ReleaseMutex(hConnectionHeaderMutex);
- return SOCKET_ERROR;
+ WaitForSingleObject(hConnectionHeaderMutex, INFINITE);
+ if (!ConnectionListToSocketList(nls->hReadConns, &readfd, pending)
+ || !ConnectionListToSocketList(nls->hWriteConns, &writefd, pending)
+ || !ConnectionListToSocketList(nls->hExceptConns, &exceptfd, pending))
+ {
+ ReleaseMutex(hConnectionHeaderMutex);
+ return SOCKET_ERROR;
}
ReleaseMutex(hConnectionHeaderMutex);
if (pending)
return 1;
- return select(0,&readfd,&writefd,&exceptfd,nls->dwTimeout==INFINITE?NULL:&tv);
+ return select(0, &readfd, &writefd, &exceptfd, nls->dwTimeout == INFINITE ? NULL : &tv);
}
INT_PTR NetlibSelectEx(WPARAM, LPARAM lParam)
{
- NETLIBSELECTEX *nls=(NETLIBSELECTEX*)lParam;
- if (nls==NULL || nls->cbSize!=sizeof(NETLIBSELECTEX)) {
+ NETLIBSELECTEX *nls = (NETLIBSELECTEX*)lParam;
+ if (nls == NULL || nls->cbSize != sizeof(NETLIBSELECTEX))
+ {
SetLastError(ERROR_INVALID_PARAMETER);
return SOCKET_ERROR;
}
TIMEVAL tv;
- tv.tv_sec=nls->dwTimeout/1000;
- tv.tv_usec=(nls->dwTimeout%1000)*1000;
- WaitForSingleObject(hConnectionHeaderMutex,INFINITE);
+ tv.tv_sec = nls->dwTimeout / 1000;
+ tv.tv_usec = (nls->dwTimeout % 1000) * 1000;
+ WaitForSingleObject(hConnectionHeaderMutex, INFINITE);
int pending = 0;
- fd_set readfd,writefd,exceptfd;
- if (!ConnectionListToSocketList(nls->hReadConns,&readfd,pending)
- || !ConnectionListToSocketList(nls->hWriteConns,&writefd,pending)
- || !ConnectionListToSocketList(nls->hExceptConns,&exceptfd,pending)) {
- ReleaseMutex(hConnectionHeaderMutex);
- return SOCKET_ERROR;
+ fd_set readfd, writefd, exceptfd;
+ if (!ConnectionListToSocketList(nls->hReadConns, &readfd, pending)
+ || !ConnectionListToSocketList(nls->hWriteConns, &writefd, pending)
+ || !ConnectionListToSocketList(nls->hExceptConns, &exceptfd, pending))
+ {
+ ReleaseMutex(hConnectionHeaderMutex);
+ return SOCKET_ERROR;
}
ReleaseMutex(hConnectionHeaderMutex);
- int rc = (pending) ? pending : select(0,&readfd,&writefd,&exceptfd,nls->dwTimeout==INFINITE?NULL:&tv);
+ int rc = (pending) ? pending : select(0, &readfd, &writefd, &exceptfd, nls->dwTimeout == INFINITE ? NULL : &tv);
- WaitForSingleObject(hConnectionHeaderMutex,INFINITE);
+ WaitForSingleObject(hConnectionHeaderMutex, INFINITE);
/* go thru each passed HCONN array and grab its socket handle, then give it to FD_ISSET()
to see if an event happened for that socket, if it has it will be returned as TRUE (otherwise not)
This happens for read/write/except */
- struct NetlibConnection *conn=NULL;
+ NetlibConnection *conn = NULL;
int j;
- for (j=0; j<FD_SETSIZE; j++) {
- conn=(struct NetlibConnection*)nls->hReadConns[j];
- if (conn==NULL || conn==INVALID_HANDLE_VALUE) break;
+ for (j = 0; j < FD_SETSIZE; j++)
+ {
+ conn = (NetlibConnection*)nls->hReadConns[j];
+ if (conn == NULL || conn == INVALID_HANDLE_VALUE) break;
if (si.pending(conn->hSsl))
nls->hReadStatus[j] = TRUE;
@@ -188,16 +199,153 @@ INT_PTR NetlibSelectEx(WPARAM, LPARAM lParam)
else
nls->hReadStatus[j] = FD_ISSET(conn->s,&readfd);
}
- for (j=0; j<FD_SETSIZE; j++) {
- conn=(struct NetlibConnection*)nls->hWriteConns[j];
- if (conn==NULL || conn==INVALID_HANDLE_VALUE) break;
+ for (j = 0; j < FD_SETSIZE; j++)
+ {
+ conn = (NetlibConnection*)nls->hWriteConns[j];
+ if (conn == NULL || conn == INVALID_HANDLE_VALUE) break;
nls->hWriteStatus[j] = FD_ISSET(conn->s,&writefd);
}
- for (j=0; j<FD_SETSIZE; j++) {
- conn=(struct NetlibConnection*)nls->hExceptConns[j];
- if (conn==NULL || conn==INVALID_HANDLE_VALUE) break;
+ for (j = 0; j < FD_SETSIZE; j++)
+ {
+ conn = (NetlibConnection*)nls->hExceptConns[j];
+ if (conn == NULL || conn == INVALID_HANDLE_VALUE) break;
nls->hExceptStatus[j] = FD_ISSET(conn->s,&exceptfd);
}
ReleaseMutex(hConnectionHeaderMutex);
return rc;
}
+
+bool NetlibStringToAddress(const char* str, SOCKADDR_INET_M* addr)
+{
+ if (!str) return false;
+
+ if (MyWSAStringToAddress)
+ {
+ int len = sizeof(SOCKADDR_INET_M);
+ return !MyWSAStringToAddress((char*)str, AF_INET6, NULL, (PSOCKADDR)addr, &len);
+ }
+ else
+ {
+ unsigned iaddr = inet_addr(str);
+ if (!iaddr) return false;
+
+ addr->Ipv4.sin_addr.s_addr = iaddr;
+ addr->Ipv4.sin_family = AF_INET;
+ return true;
+ }
+}
+
+char* NetlibAddressToString(SOCKADDR_INET_M* addr)
+{
+ char saddr[128];
+
+ if (MyWSAAddressToString)
+ {
+ DWORD len = sizeof(saddr);
+ if (!MyWSAAddressToString((PSOCKADDR)addr, sizeof(*addr), NULL, saddr, &len))
+ return mir_strdup(saddr);
+ }
+ else if (addr->si_family == AF_INET)
+ {
+ char *szIp = inet_ntoa(addr->Ipv4.sin_addr);
+ if (addr->Ipv4.sin_port != 0)
+ {
+ mir_snprintf(saddr, sizeof(saddr), "%s:%d", szIp, htons(addr->Ipv4.sin_port));
+ return mir_strdup(saddr);
+ }
+ else
+ return mir_strdup(szIp);
+ }
+ return NULL;
+}
+
+void NetlibGetConnectionInfo(NetlibConnection* nlc, NETLIBCONNINFO *connInfo)
+{
+ if (!nlc || !connInfo || connInfo->cbSize < sizeof(NETLIBCONNINFO)) return;
+
+ SOCKADDR_INET_M sin = {0};
+ int len = sizeof(sin);
+
+ if (!getsockname(nlc->s, (PSOCKADDR)&sin, &len))
+ {
+ connInfo->wPort = ntohs(sin.Ipv4.sin_port);
+ connInfo->dwIpv4 = sin.si_family == AF_INET ? htonl(sin.Ipv4.sin_addr.s_addr) : 0;
+
+ char *szTmp = NetlibAddressToString(&sin);
+ strncpy(connInfo->szIpPort, szTmp, sizeof(connInfo->szIpPort));
+ connInfo->szIpPort[sizeof(connInfo->szIpPort) - 1] = 0;
+ mir_free(szTmp);
+ }
+}
+
+inline bool IsAddrGlobal(const IN6_ADDR *a)
+{
+ unsigned char High = a->s6_bytes[0] & 0xf0;
+ return High != 0 && High != 0xf0;
+}
+
+static NETLIBIPLIST* GetMyIpv6(unsigned flags)
+{
+ addrinfo *air = NULL, *ai, hints = {0};
+ const char *szMyHost = "";
+
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_flags = AI_PASSIVE;
+
+ if (MyGetaddrinfo(szMyHost, NULL, &hints, &air))
+ return NULL;
+
+ unsigned n = 0;
+ for (ai = air; ai; ai = ai->ai_next)
+ {
+ SOCKADDR_INET_M* iaddr = (SOCKADDR_INET_M*)ai->ai_addr;
+ if (ai->ai_family == AF_INET ||
+ (ai->ai_family == AF_INET6 &&
+ (!(flags & 1) || IsAddrGlobal(&iaddr->Ipv6.sin6_addr))))
+ ++n;
+ }
+
+ NETLIBIPLIST *addr = (NETLIBIPLIST*)mir_calloc(n * 64 + 4);
+ addr->cbNum = n;
+
+ unsigned i = 0;
+ for (ai = air; ai; ai = ai->ai_next)
+ {
+ SOCKADDR_INET_M* iaddr = (SOCKADDR_INET_M*)ai->ai_addr;
+ if (ai->ai_family == AF_INET ||
+ (ai->ai_family == AF_INET6 &&
+ (!(flags & 1) || IsAddrGlobal(&iaddr->Ipv6.sin6_addr))))
+ {
+
+ char* szIp = NetlibAddressToString(iaddr);
+ if (szIp) strcpy(addr->szIp[i++], szIp);
+ mir_free(szIp);
+ }
+ }
+ MyFreeaddrinfo(air);
+ return addr;
+}
+
+static NETLIBIPLIST* GetMyIpv4(void)
+{
+ char hostname[256] = "";
+
+ gethostname(hostname, sizeof(hostname));
+ PHOSTENT he = gethostbyname(hostname);
+
+ unsigned n;
+ for (n = 0; he->h_addr_list[n]; ++n) ;
+
+ NETLIBIPLIST *addr = (NETLIBIPLIST*)mir_calloc(n * 64 + 4);
+ addr->cbNum = n;
+
+ for (unsigned i = 0; i < n; ++i)
+ strcpy(addr->szIp[i], inet_ntoa(*(PIN_ADDR)he->h_addr_list[i]));
+
+ return addr;
+}
+
+NETLIBIPLIST* GetMyIp(unsigned flags)
+{
+ return (MyGetaddrinfo && MyFreeaddrinfo) ? GetMyIpv6(flags) : GetMyIpv4();
+}
diff --git a/src/modules/updatenotify/updatenotify.cpp b/src/modules/updatenotify/updatenotify.cpp
index ef955ba3c5..5b2162a041 100644
--- a/src/modules/updatenotify/updatenotify.cpp
+++ b/src/modules/updatenotify/updatenotify.cpp
@@ -214,17 +214,11 @@ static DWORD UpdateNotifyMakeVersion(char *str) {
return PLUGIN_MAKE_VERSION(a1, a2, a3, a4);
}
-static int UpdateNotifyIsNewer(DWORD dwCurrent, DWORD dwTest) {
- if (dwTest>dwCurrent)
- return 1;
- return 0;
-}
+inline bool UpdateNotifyIsNewer(DWORD dwCurrent, DWORD dwTest)
+{ return dwTest > dwCurrent; }
-static int UpdateNotifyReleaseDataValid(UpdateNotifyReleaseData *d) {
- if (d&&d->szVersionPublic&&d->szVersion&&d->szDownload&&d->szNotes)
- return 1;
- return 0;
-}
+inline bool UpdateNotifyReleaseDataValid(UpdateNotifyReleaseData *d)
+{ return d && d->szVersionPublic && d->szVersion && d->szDownload && d->szNotes; }
static void UpdateNotifyFreeReleaseData(UpdateNotifyReleaseData *d) {
if (!d)