diff options
| -rw-r--r-- | include/m_netlib.h | 42 | ||||
| -rw-r--r-- | protocols/AimOscar/client.cpp | 9 | ||||
| -rw-r--r-- | protocols/IcqOscarJ/oscar_filetransfer.cpp | 2 | ||||
| -rw-r--r-- | protocols/JabberG/jabber_byte.cpp | 54 | ||||
| -rw-r--r-- | protocols/JabberG/jabber_file.cpp | 43 | ||||
| -rw-r--r-- | protocols/JabberG/jabber_proto.h | 1 | ||||
| -rw-r--r-- | protocols/JabberG/jabber_thread.cpp | 22 | ||||
| -rw-r--r-- | protocols/MSN/msn_commands.cpp | 30 | ||||
| -rw-r--r-- | protocols/MSN/msn_global.h | 1 | ||||
| -rw-r--r-- | protocols/MSN/msn_mime.cpp | 2 | ||||
| -rw-r--r-- | protocols/MSN/msn_misc.cpp | 106 | ||||
| -rw-r--r-- | protocols/MSN/msn_p2p.cpp | 311 | ||||
| -rw-r--r-- | protocols/MSN/msn_proto.h | 2 | ||||
| -rw-r--r-- | src/core/commonheaders.h | 2 | ||||
| -rw-r--r-- | src/core/miranda.cpp | 12 | ||||
| -rw-r--r-- | src/core/miranda.h | 9 | ||||
| -rw-r--r-- | src/modules/netlib/netlib.cpp | 56 | ||||
| -rw-r--r-- | src/modules/netlib/netlib.h | 14 | ||||
| -rw-r--r-- | src/modules/netlib/netlibbind.cpp | 129 | ||||
| -rw-r--r-- | src/modules/netlib/netlibhttp.cpp | 4 | ||||
| -rw-r--r-- | src/modules/netlib/netlibopenconn.cpp | 204 | ||||
| -rw-r--r-- | src/modules/netlib/netlibsock.cpp | 280 | ||||
| -rw-r--r-- | src/modules/updatenotify/updatenotify.cpp | 14 | 
23 files changed, 831 insertions, 518 deletions
diff --git a/include/m_netlib.h b/include/m_netlib.h index af9f21e51e..34a6647c66 100644 --- a/include/m_netlib.h +++ b/include/m_netlib.h @@ -424,6 +424,48 @@ typedef struct {  #define Netlib_GetBase64EncodedBufferSize(cbDecoded)  (((cbDecoded)*4+11)/12*4+1)
  #define MS_NETLIB_BASE64ENCODE   "Netlib/Base64Encode"
 +// Converts string representation of IP and port into numerical SOCKADDR_INET
 +// IPv4 could supplied in formats address:port or address
 +// IPv6 could supplied in formats [address]:port or [address]
 +// wParam=(WPARAM)(char*) string to convert
 +// lParam=(LPARAM)(SOCKADDR_INET*) numeric IP address structure
 +// Returns 0 on success
 +#define MS_NETLIB_STARINGTOADDRESS "Netlib/StringToAddress"
 +
 +// Converts numerical representation of IP in SOCKADDR_INET into string representation with IP and port
 +// IPv4 will be supplied in formats address:port or address
 +// IPv6 will be supplied in formats [address]:port or [address]
 +// wParam=(WPARAM)(int) 0 - lParam - (sockaddr_gen*); 1 - lParam - (unsigned) in host byte order
 +// lParam=(LPARAM)(sockaddr_gen*) or (unsigned) numeric IP address structure
 +// Returns pointer to the string or NULL if not successful
 +#define MS_NETLIB_ADDRESSTOSTRING  "Netlib/AddressToString"
 +
 +typedef struct {
 +	int cbSize;
 +	char szIpPort[64];
 +	unsigned dwIpv4;
 +	WORD wPort;
 +} NETLIBCONNINFO;
 +
 +// Get connection Information
 +// IPv4 will be supplied in formats address:port or address
 +// IPv6 will be supplied in formats [address]:port or [address]
 +// wParam=(WPARAM)(HANDLE)hConnection
 +// lParam=(LPARAM)(NETLIBCONNINFO*) pointer to the connection information structure to fill
 +// Returns 0 if successful
 +#define MS_NETLIB_GETCONNECTIONINFO  "Netlib/GetConnectionInfo"
 +
 +typedef struct {
 +	unsigned cbNum;
 +	char szIp[1][64];
 +} NETLIBIPLIST;
 +
 +// Get connection Information
 +// wParam=(WPARAM)IP filter 1 - return global only IPv6 address, 0 all IPs
 +// Returns (INT_PTR)(NETLIBIPLIST*) numeric IP address address array
 +// the last element of the array is all 0s, 0 if not successful
 +#define MS_NETLIB_GETMYIP  "Netlib/GetMyIP"
 +
  //Send an HTTP request over a connection
  //wParam=(WPARAM)(HANDLE)hConnection
  //lParam=(LPARAM)(NETLIBHTTPREQUEST*)&nlhr
 diff --git a/protocols/AimOscar/client.cpp b/protocols/AimOscar/client.cpp index 6c3dbfb86a..2fc4333728 100644 --- a/protocols/AimOscar/client.cpp +++ b/protocols/AimOscar/client.cpp @@ -260,12 +260,15 @@ int CAimProto::aim_client_ready(HANDLE hServerConn,unsigned short &seqno)  	if (hDirectBoundPort == NULL)
  	{
  		ShowPopup(LPGEN("Aim was unable to bind to a port. File transfers may not succeed in some cases."), ERROR_POPUP);
 +		local_port = 0;
  	}
  	else
 -	{
  		local_port = nlb.wPort;
 -		internal_ip = nlb.dwInternalIP;
 -	}
 +
 +	NETLIBCONNINFO connInfo = { sizeof(connInfo) }; 
 +	CallService(MS_NETLIB_GETCONNECTIONINFO, (WPARAM)hServerConn, (LPARAM)&connInfo);
 +	
 +	internal_ip = connInfo.dwIpv4;
  	char buf[SNAC_SIZE+TLV_HEADER_SIZE*22];
  	aim_writesnac(0x01,0x02,offset,buf);
 diff --git a/protocols/IcqOscarJ/oscar_filetransfer.cpp b/protocols/IcqOscarJ/oscar_filetransfer.cpp index b6dd52cf5f..bc359f0fa1 100644 --- a/protocols/IcqOscarJ/oscar_filetransfer.cpp +++ b/protocols/IcqOscarJ/oscar_filetransfer.cpp @@ -885,7 +885,7 @@ HANDLE CIcqProto::oftInitTransfer(HANDLE hContact, DWORD dwUin, char* szUid, con  		}
  	}
 -	for (int i = 0; i < filesCount; i++)
 +	for (i = 0; i < filesCount; i++)
  		SAFE_FREE(&filesUtf[i]);
  	SAFE_FREE((void**)&filesUtf);
 diff --git a/protocols/JabberG/jabber_byte.cpp b/protocols/JabberG/jabber_byte.cpp index 67015b3bcd..aa030aa7e8 100644 --- a/protocols/JabberG/jabber_byte.cpp +++ b/protocols/JabberG/jabber_byte.cpp @@ -85,10 +85,6 @@ void CJabberProto::IqResultProxyDiscovery( HXML iqNode, CJabberIqInfo* pInfo )  void JabberByteSendConnection( HANDLE hConn, DWORD /*dwRemoteIP*/, void* extra )
  {
  	CJabberProto* ppro = ( CJabberProto* )extra;
 -	SOCKET s;
 -	SOCKADDR_IN saddr;
 -	int len;
 -	WORD localPort;
  	TCHAR szPort[8];
  	JABBER_BYTE_TRANSFER *jbt;
  	int recvResult, bytesParsed;
 @@ -97,20 +93,11 @@ void JabberByteSendConnection( HANDLE hConn, DWORD /*dwRemoteIP*/, void* extra )  	char* buffer;
  	int datalen;
 -	localPort = 0;
 -	if (( s = JCallService( MS_NETLIB_GETSOCKET, ( WPARAM ) hConn, 0 )) != INVALID_SOCKET ) {
 -		len = sizeof( saddr );
 -		if ( getsockname( s, ( SOCKADDR * ) &saddr, &len ) != SOCKET_ERROR )
 -			localPort = ntohs( saddr.sin_port );
 -	}
 -	if ( localPort == 0 ) {
 -		ppro->Log( "bytestream_send_connection unable to determine the local port, connection closed." );
 -		Netlib_CloseHandle( hConn );
 -		return;
 -	}
 +	NETLIBCONNINFO connInfo = { sizeof(connInfo) }; 
 +	CallService(MS_NETLIB_GETCONNECTIONINFO, (WPARAM)hConn, (LPARAM)&connInfo);
 -	mir_sntprintf( szPort, SIZEOF( szPort ), _T("%d"), localPort );
 -	ppro->Log( "bytestream_send_connection incoming connection accepted: local_port=" TCHAR_STR_PARAM, szPort );
 +	mir_sntprintf( szPort, SIZEOF( szPort ), _T("%u"), connInfo.wPort );
 +	ppro->Log( "bytestream_send_connection incoming connection accepted: %s", connInfo.szIpPort );
  	if (( item = ppro->ListGetItemPtr( LIST_BYTE, szPort )) == NULL ) {
  		ppro->Log( "No bytestream session is currently active, connection closed." );
 @@ -157,9 +144,7 @@ void JabberByteSendConnection( HANDLE hConn, DWORD /*dwRemoteIP*/, void* extra )  void CJabberProto::ByteSendThread( JABBER_BYTE_TRANSFER *jbt )
  {
 -	char* localAddr;
 -	char* localAddrInternal;
 -	struct in_addr in;
 +	char* localAddr = NULL;
  	DBVARIANT dbv;
  	TCHAR szPort[8];
  	HANDLE hEvent = NULL;
 @@ -216,12 +201,10 @@ void CJabberProto::ByteSendThread( JABBER_BYTE_TRANSFER *jbt )  		HXML query = iq << XQUERY( _T(JABBER_FEAT_BYTESTREAMS)) << XATTR( _T("sid"), jbt->sid );
  		if ( bDirect ) {
 -			localAddr = NULL;
 -			if ( m_options.BsDirectManual == TRUE ) {
 -				if ( !DBGetContactSettingString( NULL, m_szModuleName, "BsDirectAddr", &dbv )) {
 -					localAddr = NEWSTR_ALLOCA( dbv.pszVal );
 -					JFreeVariant( &dbv );
 -			}	}
 +			if ( m_options.BsDirectManual ) {
 +				if ( !DBGetContactSettingString( NULL, m_szModuleName, "BsDirectAddr", &dbv ))
 +					localAddr = dbv.pszVal;
 +			}
  			NETLIBBIND nlb = {0};
  			nlb.cbSize = sizeof( NETLIBBIND );
 @@ -234,12 +217,9 @@ void CJabberProto::ByteSendThread( JABBER_BYTE_TRANSFER *jbt )  				delete jbt;
  				return;
  			}
 -			if ( localAddr == NULL ) {
 -				in.S_un.S_addr = htonl(nlb.dwExternalIP);
 -				localAddr = NEWSTR_ALLOCA( inet_ntoa( in ));
 -			}
 -			in.S_un.S_addr = htonl(nlb.dwInternalIP);
 -			localAddrInternal = NEWSTR_ALLOCA( inet_ntoa( in ));
 +
 +			if ( localAddr == NULL )
 +				localAddr = (char*)CallService( MS_NETLIB_ADDRESSTOSTRING, 1, nlb.dwExternalIP );
  			mir_sntprintf( szPort, SIZEOF( szPort ), _T("%d"), nlb.wPort );
  			JABBER_LIST_ITEM *item = ListAdd( LIST_BYTE, szPort );
 @@ -248,8 +228,14 @@ void CJabberProto::ByteSendThread( JABBER_BYTE_TRANSFER *jbt )  			jbt->hEvent = hEvent;
  			jbt->hSendEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
  			query << XCHILD( _T("streamhost")) << XATTR( _T("jid"), m_ThreadInfo->fullJID ) << XATTR( _T("host"), _A2T(localAddr)) << XATTRI( _T("port"), nlb.wPort );
 -			if ( strcmp( localAddr, localAddrInternal ))
 -				query << XCHILD( _T("streamhost")) << XATTR( _T("jid"), m_ThreadInfo->fullJID ) << XATTR( _T("host"), _A2T(localAddrInternal)) << XATTRI( _T("port"), nlb.wPort );
 +
 +			NETLIBIPLIST* ihaddr = ( NETLIBIPLIST* )CallService( MS_NETLIB_GETMYIP, 1, 0 );
 +			for ( unsigned i = 0; i < ihaddr->cbNum; ++i )
 +				if ( strcmp( localAddr, ihaddr->szIp[i] ))
 +					query << XCHILD( _T("streamhost")) << XATTR( _T("jid"), m_ThreadInfo->fullJID ) << XATTR( _T("host"), _A2T(ihaddr->szIp[i])) << XATTRI( _T("port"), nlb.wPort );
 +
 +			mir_free( ihaddr );
 +			mir_free( localAddr );
  		}
  		if ( jbt->bProxyDiscovered )
 diff --git a/protocols/JabberG/jabber_file.cpp b/protocols/JabberG/jabber_file.cpp index 9577c310e9..3cce546bef 100644 --- a/protocols/JabberG/jabber_file.cpp +++ b/protocols/JabberG/jabber_file.cpp @@ -196,24 +196,13 @@ int CJabberProto::FileReceiveParse( filetransfer* ft, char* buffer, int datalen  void JabberFileServerConnection( JABBER_SOCKET hConnection, DWORD /*dwRemoteIP*/, void* extra )
  {
  	CJabberProto* ppro = ( CJabberProto* )extra;
 -	WORD localPort = 0;
 -	SOCKET s = JCallService( MS_NETLIB_GETSOCKET, ( WPARAM ) hConnection, 0 ); 
 -	if ( s != INVALID_SOCKET ) {
 -		SOCKADDR_IN saddr;
 -		int len = sizeof( saddr );
 -		if ( getsockname( s, ( SOCKADDR * ) &saddr, &len ) != SOCKET_ERROR ) {
 -			localPort = ntohs( saddr.sin_port );
 -		}
 -	}
 -	if ( localPort == 0 ) {
 -		ppro->Log( "Unable to determine the local port, file server connection closed." );
 -		Netlib_CloseHandle( hConnection );
 -		return;
 -	}
 -	TCHAR szPort[20];
 -	mir_sntprintf( szPort, SIZEOF( szPort ), _T("%d"), localPort );
 -	ppro->Log( "File server incoming connection accepted: local_port=" TCHAR_STR_PARAM, szPort );
 +	NETLIBCONNINFO connInfo = { sizeof(connInfo) }; 
 +	CallService(MS_NETLIB_GETCONNECTIONINFO, (WPARAM)hConnection, (LPARAM)&connInfo);
 +
 +	TCHAR szPort[10];
 +	mir_sntprintf( szPort, SIZEOF( szPort ), _T("%d"), connInfo.wPort );
 +	ppro->Log( "File server incoming connection accepted: %s", connInfo.szIpPort );
  	JABBER_LIST_ITEM *item = ppro->ListGetItemPtr( LIST_FILE, szPort );
  	if ( item == NULL ) {
 @@ -311,9 +300,6 @@ void __cdecl CJabberProto::FileServerThread( filetransfer* ft )  			else
  				p = ft->std.ptszFiles[i];
 -			in_addr in;
 -			in.S_un.S_addr = m_dwJabberLocalIP;
 -		
  			TCHAR* pFileName = JabberHttpUrlEncode( p );
  			if ( pFileName != NULL ) {
  				int id = SerialNext();
 @@ -321,20 +307,22 @@ void __cdecl CJabberProto::FileServerThread( filetransfer* ft )  				ft->iqId = ( TCHAR* )mir_alloc( sizeof(TCHAR)*( strlen( JABBER_IQID )+20 ));
  				wsprintf( ft->iqId, _T(JABBER_IQID)_T("%d"), id );
 -				char *myAddr;
 +				char *myAddr = NULL;
  				DBVARIANT dbv;
  				if (m_options.BsDirect && m_options.BsDirectManual) {
 -					if ( !DBGetContactSettingString( NULL, m_szModuleName, "BsDirectAddr", &dbv )) {
 -						myAddr = NEWSTR_ALLOCA( dbv.pszVal );
 -						JFreeVariant( &dbv );
 -					}
 -					else myAddr = inet_ntoa( in );
 +					if ( !DBGetContactSettingString( NULL, m_szModuleName, "BsDirectAddr", &dbv ))
 +						myAddr = dbv.pszVal;
  				}
 -				else myAddr = inet_ntoa( in );
 +
 +				if ( myAddr == NULL )
 +					myAddr = (char*)CallService( MS_NETLIB_ADDRESSTOSTRING, 1, nlb.dwExternalIP );
  				char szAddr[ 256 ];
  				mir_snprintf( szAddr, sizeof(szAddr), "http://%s:%d/%s", myAddr, nlb.wPort, pFileName );
 +				mir_free( pFileName );
 +				mir_free( myAddr );
 +
  				int len = lstrlen(ptszResource) + lstrlen(ft->jid) + 2;
  				TCHAR* fulljid = ( TCHAR* )alloca( sizeof( TCHAR )*len );
  				wsprintf( fulljid, _T("%s/%s"), ft->jid, ptszResource );
 @@ -347,7 +335,6 @@ void __cdecl CJabberProto::FileServerThread( filetransfer* ft )  				Log( "Waiting for the file to be sent..." );
  				WaitForSingleObject( hEvent, INFINITE );
 -				mir_free( pFileName );
  			}
  			Log( "File sent, advancing to the next file..." );
  			JSendBroadcast( ft->std.hContact, ACKTYPE_FILE, ACKRESULT_NEXTFILE, ft, 0 );
 diff --git a/protocols/JabberG/jabber_proto.h b/protocols/JabberG/jabber_proto.h index 9947fd155b..663c1d3ecd 100644 --- a/protocols/JabberG/jabber_proto.h +++ b/protocols/JabberG/jabber_proto.h @@ -260,7 +260,6 @@ struct CJabberProto : public PROTO_INTERFACE  	TCHAR* m_szJabberJID;
  	char*  m_szStreamId;
 -	DWORD  m_dwJabberLocalIP;
  	BOOL   m_bJabberConnected; // TCP connection to jabber server established
  	BOOL   m_bJabberOnline; // XMPP connection initialized and we can send XMPP packets
  	int    m_nJabberSearchID;
 diff --git a/protocols/JabberG/jabber_thread.cpp b/protocols/JabberG/jabber_thread.cpp index 68712157ab..3c343600c8 100644 --- a/protocols/JabberG/jabber_thread.cpp +++ b/protocols/JabberG/jabber_thread.cpp @@ -132,7 +132,8 @@ void CJabberProto::OnPingReply( HXML, CJabberIqInfo* pInfo )  		return;
  	if ( pInfo->GetIqType() == JABBER_IQ_TYPE_FAIL ) {
  		// disconnect because of timeout
 -		SetStatus(ID_STATUS_OFFLINE);
 +		m_ThreadInfo->send( "</stream:stream>" );
 +		m_ThreadInfo->shutdown();
  	}
  }
 @@ -428,17 +429,6 @@ LBL_FatalError:  	}
  	// Determine local IP
 -	int socket = JCallService( MS_NETLIB_GETSOCKET, ( WPARAM ) info->s, 0 );
 -	if ( info->type==JABBER_SESSION_NORMAL && socket!=INVALID_SOCKET ) {
 -		struct sockaddr_in saddr;
 -		int len;
 -
 -		len = sizeof( saddr );
 -		getsockname( socket, ( struct sockaddr * ) &saddr, &len );
 -		m_dwJabberLocalIP = saddr.sin_addr.S_un.S_addr;
 -		Log( "Local IP = %s", inet_ntoa( saddr.sin_addr ));
 -	}
 -
  	if ( info->useSSL ) {
  		Log( "Intializing SSL connection" );
  		if (!JCallService( MS_NETLIB_STARTSSL, ( WPARAM )info->s, 0)) {
 @@ -1012,12 +1002,8 @@ void CJabberProto::OnProcessProceed( HXML node, ThreadData* info )  		ssl.host = isHosted ? info->manualHost : info->server;
  		if (!JCallService( MS_NETLIB_STARTSSL, ( WPARAM )info->s, ( LPARAM )&ssl)) {
  			Log( "SSL initialization failed" );
 -			if (info->type == JABBER_SESSION_REGISTER) {
 -				info->send( "</stream:stream>" );
 -				info->shutdown();
 -			} 
 -			else
 -				SetStatus(ID_STATUS_OFFLINE);
 +			info->send( "</stream:stream>" );
 +			info->shutdown();
  		}
  		else
  			xmlStreamInitialize( "after successful StartTLS" );
 diff --git a/protocols/MSN/msn_commands.cpp b/protocols/MSN/msn_commands.cpp index 04d2ad7981..a85ff46fe4 100644 --- a/protocols/MSN/msn_commands.cpp +++ b/protocols/MSN/msn_commands.cpp @@ -30,30 +30,20 @@ void MSN_ConnectionProc(HANDLE hNewConnection, DWORD /* dwRemoteIP */, void* ext  	proto->MSN_DebugLog("File transfer connection accepted");
 -	WORD localPort = 0;
 -	SOCKET s = MSN_CallService(MS_NETLIB_GETSOCKET, (WPARAM)hNewConnection, 0);
 -	if (s != INVALID_SOCKET) 
 +	NETLIBCONNINFO connInfo = { sizeof(connInfo) }; 
 +	CallService(MS_NETLIB_GETCONNECTIONINFO, (WPARAM)hNewConnection, (LPARAM)&connInfo);
 +
 +	ThreadData* T = proto->MSN_GetThreadByPort(connInfo.wPort);
 +	if (T != NULL && T->s == NULL) 
  	{
 -		SOCKADDR_IN saddr;
 -		int len = sizeof(saddr);
 -		if (getsockname(s, (SOCKADDR*)&saddr, &len) != SOCKET_ERROR)
 -			localPort = ntohs(saddr.sin_port);
 +		T->s = hNewConnection;
 +		ReleaseSemaphore(T->hWaitEvent, 1, NULL);
  	}
 -
 -	if (localPort != 0) 
 +	else
  	{
 -		ThreadData* T = proto->MSN_GetThreadByPort(localPort);
 -		if (T != NULL && T->s == NULL) 
 -		{
 -			T->s = hNewConnection;
 -			ReleaseSemaphore(T->hWaitEvent, 1, NULL);
 -			return;
 -		}
 -		proto->MSN_DebugLog("There's no registered file transfers for incoming port #%d, connection closed", localPort);
 +		proto->MSN_DebugLog("There's no registered file transfers for incoming port #%u, connection closed", connInfo.wPort);
 +		Netlib_CloseHandle(hNewConnection);
  	}
 -	else proto->MSN_DebugLog("Unable to determine the local port, file server connection closed.");
 -
 -	Netlib_CloseHandle(hNewConnection);
  }
 diff --git a/protocols/MSN/msn_global.h b/protocols/MSN/msn_global.h index 317b834afa..a2c1ba6dd6 100644 --- a/protocols/MSN/msn_global.h +++ b/protocols/MSN/msn_global.h @@ -167,6 +167,7 @@ void		stripColorCode(char* src);  void		parseWLID(char* wlid, char** net, char** email, char** inst);
  char*		MSN_Base64Decode(const char* str);
 +char*		GetGlobalIp(void);
  template <class chartype> void UrlDecode(chartype* str);
 diff --git a/protocols/MSN/msn_mime.cpp b/protocols/MSN/msn_mime.cpp index 8351673308..b925e101bb 100644 --- a/protocols/MSN/msn_mime.cpp +++ b/protocols/MSN/msn_mime.cpp @@ -71,6 +71,8 @@ unsigned MimeHeaders::allocSlot(void)  void MimeHeaders::addString(const char* name, const char* szValue, unsigned flags)
  {
 +	if (szValue == NULL) return;
 +	
  	MimeHeader& H = mVals[allocSlot()];
  	H.name = name;
  	H.value = szValue; 
 diff --git a/protocols/MSN/msn_misc.cpp b/protocols/MSN/msn_misc.cpp index 0780361b2c..80d9fd46ec 100644 --- a/protocols/MSN/msn_misc.cpp +++ b/protocols/MSN/msn_misc.cpp @@ -125,7 +125,7 @@ void  CMsnProto::MSN_AddAuthRequest(const char *email, const char *nick, const c  	//blob is: UIN=0(DWORD), hContact(DWORD), nick(ASCIIZ), ""(ASCIIZ), ""(ASCIIZ), email(ASCIIZ), ""(ASCIIZ)
  	HANDLE hContact = MSN_HContactFromEmail(email, nick, true, true);
 -	
 +
  	int emaillen = (int)strlen(email);
  	if (nick == NULL) nick = "";
 @@ -294,7 +294,7 @@ void  CMsnProto::MSN_GetAvatarFileName(HANDLE hContact, TCHAR* pszDest, size_t c  			} while(_tfindnext(hFile, &c_file) == 0);
  			_findclose( hFile );
  		}
 -		
 +
  		if (!found) pszDest[0] = 0;
  	}
  	else
 @@ -334,17 +334,17 @@ int MSN_GetImageFormat(void* buf, const TCHAR** ext)  int MSN_GetImageFormat(const TCHAR* file)
  {
 -   const TCHAR *ext = _tcsrchr(file, '.');
 -   if (ext == NULL) 
 -	   return PA_FORMAT_UNKNOWN;
 -   if (_tcsicmp(ext, _T(".gif")) == 0)
 -	   return PA_FORMAT_GIF;
 -   else if (_tcsicmp(ext, _T(".bmp")) == 0)
 -	   return PA_FORMAT_BMP;
 -   else if (_tcsicmp(ext, _T(".png")) == 0)
 -	   return PA_FORMAT_PNG;
 -   else
 -	   return PA_FORMAT_JPEG;
 +	const TCHAR *ext = _tcsrchr(file, '.');
 +	if (ext == NULL) 
 +		return PA_FORMAT_UNKNOWN;
 +	if (_tcsicmp(ext, _T(".gif")) == 0)
 +		return PA_FORMAT_GIF;
 +	else if (_tcsicmp(ext, _T(".bmp")) == 0)
 +		return PA_FORMAT_BMP;
 +	else if (_tcsicmp(ext, _T(".png")) == 0)
 +		return PA_FORMAT_PNG;
 +	else
 +		return PA_FORMAT_JPEG;
  }
  int  CMsnProto::MSN_SetMyAvatar(const TCHAR* sztFname, void* pData, size_t cbLen)
 @@ -363,10 +363,10 @@ int  CMsnProto::MSN_SetMyAvatar(const TCHAR* sztFname, void* pData, size_t cbLen  		NETLIBBASE64 nlb = { szSha1d, sizeof(szSha1d), (PBYTE)sha1d, sizeof(sha1d) };
  		MSN_CallService(MS_NETLIB_BASE64ENCODE, 0, LPARAM(&nlb));
  	}
 -	
 +
  	mir_sha1_init(&sha1ctx);
  	ezxml_t xmlp = ezxml_new("msnobj");
 -	
 +
  	mir_sha1_append(&sha1ctx, (PBYTE)"Creator", 7);
  	mir_sha1_append(&sha1ctx, (PBYTE)MyOptions.szEmail, (int)strlen(MyOptions.szEmail));
  	ezxml_set_attr(xmlp, "Creator", MyOptions.szEmail);
 @@ -392,15 +392,15 @@ int  CMsnProto::MSN_SetMyAvatar(const TCHAR* sztFname, void* pData, size_t cbLen  	mir_sha1_append(&sha1ctx, (PBYTE)"SHA1D", 5);
  	mir_sha1_append(&sha1ctx, (PBYTE)szSha1d, (int)strlen(szSha1d));
  	ezxml_set_attr(xmlp, "SHA1D", szSha1d);
 -		
 +
  	mir_sha1_finish(&sha1ctx, sha1c);
  	{
  		NETLIBBASE64 nlb = { szSha1c, sizeof(szSha1c), (PBYTE)sha1c, sizeof(sha1c) };
  		MSN_CallService(MS_NETLIB_BASE64ENCODE, 0, LPARAM(&nlb));
  	}
 -	
 -//	ezxml_set_attr(xmlp, "SHA1C", szSha1c);
 +
 +	//	ezxml_set_attr(xmlp, "SHA1C", szSha1c);
  	char* szBuffer = ezxml_toxml(xmlp, false);
  	ezxml_free(xmlp);
 @@ -475,7 +475,7 @@ void  CMsnProto::MSN_GetCustomSmileyFileName(HANDLE hContact, TCHAR* pszDest, si  			dbv.ptszVal = (TCHAR*)mir_alloc(11);
  			_ui64tot((UINT_PTR)hContact, dbv.ptszVal, 10);
  		}
 -		
 +
  		tPathLen += mir_sntprintf(pszDest + tPathLen, cbLen - tPathLen, _T("\\%s"), dbv.ptszVal);
  		DBFreeVariant(&dbv);
  	}
 @@ -485,9 +485,9 @@ void  CMsnProto::MSN_GetCustomSmileyFileName(HANDLE hContact, TCHAR* pszDest, si  		tPathLen += mir_sntprintf(pszDest + tPathLen, cbLen - tPathLen, _T("\\%s"), tszModuleName);
  		mir_free(tszModuleName);
  	}
 -		
 +
  	bool exist = _taccess(pszDest, 0) == 0;
 -	
 +
  	if (type == 0)
  	{
  		if (!exist) pszDest[0] = 0;
 @@ -607,10 +607,10 @@ int ThreadData::sendMessage(int msgType, const char* email, int netId, const cha  	int seq;
  	if (netId == NETID_YAHOO || netId == NETID_MOB || (parFlags & MSG_OFFLINE))
  		seq = sendPacket("UUM", "%s %d %c %d\r\n%s%s", email, netId, msgType, 
 -			strlen(parMsg)+off, buf, parMsg);
 +		strlen(parMsg)+off, buf, parMsg);
  	else
  		seq = sendPacket("MSG", "%c %d\r\n%s%s", msgType, 
 -			strlen(parMsg)+off, buf, parMsg);
 +		strlen(parMsg)+off, buf, parMsg);
  	return seq;
  }
 @@ -699,8 +699,8 @@ void  CMsnProto::MSN_StartStopTyping(ThreadData* info, bool start)  		MSN_SendTyping(info, NULL, 1);
  	}
  	else if (!start && info->mTimerId != 0) {
 -			KillTimer(NULL, info->mTimerId);
 -			info->mTimerId = 0;
 +		KillTimer(NULL, info->mTimerId);
 +		info->mTimerId = 0;
  	}
  }
 @@ -770,10 +770,10 @@ void  CMsnProto::MSN_SendStatusMessage(const char* msg)  		sz = mir_snprintf(szMsg, sizeof szMsg, 
  			"<Data>"
 -				"<PSM>%s</PSM>"
 -				"<CurrentMedia>%s\\0%s\\01\\0%s\\0%s\\0%s\\0%s\\0%s\\0%s\\0%s\\0%s\\0%s\\0%s\\0\\0</CurrentMedia>"
 -				"<MachineGuid>%s</MachineGuid><DDP></DDP><SignatureSound></SignatureSound><Scene></Scene><ColorScheme></ColorScheme>"
 -				"<DDP></DDP><SignatureSound></SignatureSound><Scene></Scene><ColorScheme></ColorScheme>"
 +			"<PSM>%s</PSM>"
 +			"<CurrentMedia>%s\\0%s\\01\\0%s\\0%s\\0%s\\0%s\\0%s\\0%s\\0%s\\0%s\\0%s\\0%s\\0\\0</CurrentMedia>"
 +			"<MachineGuid>%s</MachineGuid><DDP></DDP><SignatureSound></SignatureSound><Scene></Scene><ColorScheme></ColorScheme>"
 +			"<DDP></DDP><SignatureSound></SignatureSound><Scene></Scene><ColorScheme></ColorScheme>"
  			"</Data>", 
  			msgEnc, szPlayer, szType, szFormatEnc, szTitle, szArtist, szAlbum, szTrack, szYear, szGenre, 
  			szLength, szPlayer, szType, MyOptions.szMachineGuid);
 @@ -856,7 +856,7 @@ void  CMsnProto::MSN_SetServerStatus(int newStatus)  	{
  		DBVARIANT msnObject = {0};
  		if (ServiceExists(MS_AV_SETMYAVATAR)) 
 -			 getString("PictObject", &msnObject);
 +			getString("PictObject", &msnObject);
  		// Capabilties: WLM 2009, Chunking, UUN Bootstrap 
  		myFlags = 0xA0000000 | cap_SupportsChunking | cap_SupportsP2PBootstrap | cap_SupportsSipInvite;
 @@ -898,10 +898,10 @@ void  CMsnProto::MSN_SetServerStatus(int newStatus)  		int sz = mir_snprintf(szMsg, sizeof(szMsg), 
  			"<PrivateEndpointData>"
 -				"<EpName>%s</EpName>"
 -				"<Idle>%s</Idle>"
 -				"<ClientType>1</ClientType>"
 -				"<State>%s</State>"
 +			"<EpName>%s</EpName>"
 +			"<Idle>%s</Idle>"
 +			"<ClientType>1</ClientType>"
 +			"<State>%s</State>"
  			"</PrivateEndpointData>", 
  			szPlace, newStatus == ID_STATUS_IDLE ? "true" : "false", szStatusName);
  		msnNsThread->sendPacket("UUX", "%d\r\n%s", sz, szMsg);
 @@ -932,7 +932,7 @@ void CMsnProto::MsnInvokeMyURL(bool ismail, const char* url)  	static const char postdataM[] = "ct=%u&bver=7&wa=wsignin1.0&ru=%s&pl=MBI";
  	static const char postdataS[] = "ct=%u&bver=7&id=73625&ru=%s&js=yes&pl=%%3Fid%%3D73625";
  	const char *postdata = ismail ? postdataM : postdataS;
 -	  
 +
  	char passport[256];
  	if (getStaticString(NULL, "MsnPassportHost", passport, 256))
  		strcpy(passport, "https://login.live.com/");
 @@ -943,7 +943,7 @@ void CMsnProto::MsnInvokeMyURL(bool ismail, const char* url)  	char ruenc[256];
  	UrlEncode(url, ruenc, sizeof(ruenc));
 - 
 +
  	const size_t fnpstlen = strlen(postdata) +  strlen(ruenc) + 30;
  	char* fnpst = (char*)alloca(fnpstlen);
 @@ -1121,7 +1121,7 @@ void CALLBACK sttMainThreadCallback(PVOID dwParam)  		ppd.ptszText = pud->text;
  		ppd.PluginData = pud;
  		ppd.pszClassName = name;
 -		
 +
  		if (pud->flags & MSN_SHOW_ERROR)
  			mir_snprintf(name, SIZEOF(name), "%s_%s", pud->proto->m_szModuleName, "Error");
  		else if (pud->flags & (MSN_HOTMAIL_POPUP | MSN_ALERT_POPUP))
 @@ -1228,8 +1228,8 @@ int filetransfer::create(void)  	if (fileId == -1)
  		proto->MSN_ShowError("Cannot create file '%s' during a file transfer", std.tszCurrentFile);
 -//	else if (std.currentFileSize != 0)
 -//		_chsize(fileId, std.currentFileSize);
 +	//	else if (std.currentFileSize != 0)
 +	//		_chsize(fileId, std.currentFileSize);
  	return fileId;
  }
 @@ -1261,7 +1261,7 @@ int filetransfer::openNext(void)  		{
  			std.currentFileSize = _filelengthi64(fileId);
  			std.currentFileProgress = 0;
 -			
 +
  			p2p_sendmsgid = 0;
  			p2p_byemsgid = 0;
  			tType = SERVER_NOTIFICATION;
 @@ -1343,8 +1343,7 @@ void directconnection::xNonceToBin(UUID* nonce)  /////////////////////////////////////////////////////////////////////////////////////////
  // TWinErrorCode class
 -TWinErrorCode::TWinErrorCode() :
 -	mErrorText(NULL)
 +TWinErrorCode::TWinErrorCode() : mErrorText(NULL)
  {
  	mErrorCode = ::GetLastError();
  }
 @@ -1363,8 +1362,8 @@ char* TWinErrorCode::getText()  		if (tBytes == 0)
  			tBytes = FormatMessageA(
 -				FORMAT_MESSAGE_FROM_SYSTEM, NULL,
 -				mErrorCode, LANG_NEUTRAL, mErrorText, 256, NULL);
 +			FORMAT_MESSAGE_FROM_SYSTEM, NULL,
 +			mErrorCode, LANG_NEUTRAL, mErrorText, 256, NULL);
  		if (tBytes == 0)
  		{
 @@ -1424,14 +1423,14 @@ bool CMsnProto::MSN_IsMeByContact(HANDLE hContact, char* szEmail)  	*emailPtr = 0;
  	if (getStaticString(hContact, "e-mail", emailPtr, sizeof(tEmail))) 
  		return false;
 -	
 +
  	return _stricmp(emailPtr, MyOptions.szEmail) == 0;
  }
  bool MSN_MsgWndExist(HANDLE hContact)
  {
  	MessageWindowInputData msgWinInData = 
 -		{ sizeof(MessageWindowInputData), hContact, MSG_WINDOW_UFLAG_MSG_BOTH };
 +	{ sizeof(MessageWindowInputData), hContact, MSG_WINDOW_UFLAG_MSG_BOTH };
  	MessageWindowData msgWinData = {0};
  	msgWinData.cbSize = sizeof(MessageWindowData);
 @@ -1471,7 +1470,8 @@ void MSN_MakeDigest(const char* chl, char* dgst)  	LONGLONG high=0, low=0;
  	int* chlStringArray = (int*)chlString;
 -	for (i=0; i < strlen(chlString)/4; i += 2) {
 +	for (i=0; i < strlen(chlString) / 4; i += 2)
 +	{
  		LONGLONG temp = chlStringArray[i];
  		temp = (0x0E79A9C1 * temp) % 0x7FFFFFFF;
 @@ -1498,3 +1498,15 @@ void MSN_MakeDigest(const char* chl, char* dgst)  	strcpy(dgst, str);
  	mir_free(str);
  }
 +
 +char* GetGlobalIp(void)
 +{
 +	NETLIBIPLIST* ihaddr = (NETLIBIPLIST*)CallService(MS_NETLIB_GETMYIP, 1, 0);
 +	for (unsigned i = 0; i < ihaddr->cbNum; ++i)
 +	{
 +		if (strchr(ihaddr->szIp[i], ':'))
 +			return mir_strdup(ihaddr->szIp[i]);
 +	}
 +	mir_free(ihaddr);
 +	return NULL;
 +}
 diff --git a/protocols/MSN/msn_p2p.cpp b/protocols/MSN/msn_p2p.cpp index 1e3215b2e5..9c805eb530 100644 --- a/protocols/MSN/msn_p2p.cpp +++ b/protocols/MSN/msn_p2p.cpp @@ -81,7 +81,7 @@ void P2PV2_Header::logHeader(CMsnProto *ppro)  bool CMsnProto::p2p_createListener(filetransfer* ft, directconnection *dc, MimeHeaders& chdrs)
  {
  	if (MyConnection.extIP == 0) return false;
 -	
 +
  	NETLIBBIND nlb = {0};
  	nlb.cbSize = sizeof(nlb);
  	nlb.pfnNewConnectionV2 = MSN_ConnectionProc;
 @@ -103,22 +103,29 @@ bool CMsnProto::p2p_createListener(filetransfer* ft, directconnection *dc, MimeH  	newThread->startThread(&CMsnProto::p2p_filePassiveThread, this);
 -	char hostname[256] = "";
 -
 -	gethostname(hostname, sizeof(hostname));
 -	PHOSTENT he = gethostbyname(hostname);
 +	char szIpv4[256] = "";
 +	char szIpv6[256] = "";
 +	const char *szExtIp = MyConnection.GetMyExtIPStr(); 
 -	hostname[0] = 0;
  	bool ipInt = false;
 -	for (unsigned i = 0; i < sizeof(hostname) / 16; ++i) 
 -	{
 -		const PIN_ADDR addr = (PIN_ADDR)he->h_addr_list[i];
 +	int i4 = 0, i6 = 0;
 -		if (addr == NULL) break;
 -		if (i != 0) strcat(hostname, " ");
 -		ipInt |= (addr->S_un.S_addr == MyConnection.extIP);
 -		strcat(hostname, inet_ntoa(*addr));
 +	NETLIBIPLIST* ihaddr = (NETLIBIPLIST*)CallService(MS_NETLIB_GETMYIP, 1, 0);
 +	for (unsigned i = 0; i < ihaddr->cbNum; ++i)
 +	{
 +		if (strchr(ihaddr->szIp[i], ':'))
 +		{
 +			if (i6++ != 0) strcat(szIpv6, " ");
 +			strcat(szIpv6, ihaddr->szIp[i]);
 +		}
 +		else
 +		{
 +			if (i4++ != 0) strcat(szIpv4, " ");
 +			ipInt |= (strcmp(ihaddr->szIp[i], szExtIp) == 0);
 +			strcat(szIpv4, ihaddr->szIp[i]);
 +		}
  	}
 +	mir_free(ihaddr);
  	chdrs.addString("Bridge", "TCPv1");
  	chdrs.addBool("Listening", true);
 @@ -135,8 +142,13 @@ bool CMsnProto::p2p_createListener(filetransfer* ft, directconnection *dc, MimeH  		chdrs.addString("IPv4External-Addrs", mir_strdup(MyConnection.GetMyExtIPStr()), bUbnCall ? 6 : 2);
  		chdrs.addLong("IPv4External-Port", nlb.wExPort, bUbnCall ? 4 : 0);
  	}
 -	chdrs.addString("IPv4Internal-Addrs", mir_strdup(hostname), bUbnCall ? 6 : 2);
 +	chdrs.addString("IPv4Internal-Addrs", mir_strdup(szIpv4), bUbnCall ? 6 : 2);
  	chdrs.addLong("IPv4Internal-Port", nlb.wPort, bUbnCall ? 4 : 0);
 +	if (szIpv6[0])
 +	{
 +		chdrs.addString("IPv6-Addrs", mir_strdup(szIpv6), 2);
 +		chdrs.addLong("IPv6-Port", nlb.wPort);
 +	}
  	chdrs.addULong("SessionID", ft->p2p_sessionid);
  	chdrs.addString("SChannelState", "0");
  	chdrs.addString("Capabilities-Flags", "1");
 @@ -382,19 +394,19 @@ void  CMsnProto::p2p_sendMsg(ThreadData* info, const char *wlid, unsigned appId,  		char* szEmail;
  		switch (msgType) 
  		{
 -			case 0:
 -				parseWLID(NEWSTR_ALLOCA(wlid), NULL, &szEmail, NULL);
 -				MsgQueue_Add(szEmail, 'D', buf, p - buf);
 -				break;
 +		case 0:
 +			parseWLID(NEWSTR_ALLOCA(wlid), NULL, &szEmail, NULL);
 +			MsgQueue_Add(szEmail, 'D', buf, p - buf);
 +			break;
 -			case 1: 
 -				*(unsigned*)buf = (unsigned)(p - buf - sizeof(unsigned));
 -				info->send(buf, p - buf);
 -				break;
 +		case 1: 
 +			*(unsigned*)buf = (unsigned)(p - buf - sizeof(unsigned));
 +			info->send(buf, p - buf);
 +			break;
 -			case 2:
 -				info->sendRawMessage('D', buf, p - buf);
 -				break;
 +		case 2:
 +			info->sendRawMessage('D', buf, p - buf);
 +			break;
  		}
  		offset += portion;
  	} 
 @@ -522,7 +534,7 @@ void  CMsnProto::p2p_sendSlp(int iKind, filetransfer *ft, MimeHeaders &pHeaders,  		case 1603: p += sprintf(p, "MSNSLP/1.0 603 Decline"); break;
  		default: return;
  	}
 -	
 +
  	if (iKind < 0) 
  	{
  		mir_free(ft->p2p_branch);
 @@ -565,9 +577,9 @@ void  CMsnProto::p2p_sendSlp(int iKind, filetransfer *ft, MimeHeaders &pHeaders,  			switch (iKind) 
  			{
 -				case -1: case 500: case 603: 
 -					ft->p2p_byemsgid  = tHdr.mID; 
 -					break;
 +			case -1: case 500: case 603: 
 +				ft->p2p_byemsgid  = tHdr.mID; 
 +				break;
  			}
  		}
 @@ -622,7 +634,7 @@ void  CMsnProto::p2p_sendNoCall(filetransfer* ft)  		MSN_DebugLog(sttVoidSession);
  		return;
  	}
 -	 
 +
  	MimeHeaders tHeaders(8);
  	tHeaders.addString("CSeq", "0 ");
  	tHeaders.addString("Call-ID", ft->p2p_callID);
 @@ -882,7 +894,7 @@ LONG  CMsnProto::p2p_sendPortion(filetransfer* ft, ThreadData* T, bool isV2)  	// Compute the amount of data to send
  	unsigned fportion = T->mType == SERVER_P2P_DIRECT ? 1352 : 1202;
  	if (isV2) fportion += 4;
 -	
 +
  	const unsigned __int64 dt = ft->std.currentFileSize - ft->std.currentFileProgress;
  	const unsigned portion = dt > fportion ? fportion : dt;
 @@ -975,9 +987,9 @@ void __cdecl CMsnProto::p2p_sendFeedThread(void* arg)  	switch(WaitForSingleObject(info->hWaitEvent, 6000)) 
  	{
 -		case WAIT_FAILED:
 -			MSN_DebugLog("File send wait failed");
 -			return;
 +	case WAIT_FAILED:
 +		MSN_DebugLog("File send wait failed");
 +		return;
  	}
  	HANDLE hLockHandle = NULL;
 @@ -1036,7 +1048,7 @@ void __cdecl CMsnProto::p2p_sendFeedThread(void* arg)  			WaitForSingleObject(T->hWaitEvent, 5000);
  	}
  	ReleaseMutex(hLockHandle);
 -	
 +
  	if (ft->p2p_appID == MSN_APPID_FILE)
  		SendBroadcast(ft->std.hContact, ACKTYPE_FILE, ACKRESULT_DATA, ft, (LPARAM)&ft->std);
 @@ -1213,7 +1225,7 @@ void CMsnProto::p2p_InitFileTransfer(  	replaceStr(ft->p2p_branch, szBranch);
  	ft->p2p_dest = mir_strdup(wlid);
  	ft->p2p_isV2 = strchr(wlid, ';') != NULL;
 - 	ft->std.hContact = MSN_HContactFromEmail(wlid);
 +	ft->std.hContact = MSN_HContactFromEmail(wlid);
  	p2p_registerSession(ft);
 @@ -1292,15 +1304,14 @@ void CMsnProto::p2p_InitFileTransfer(  		if (!_stricmp(szEufGuid, "{5D3E02AB-6190-11D3-BBBB-00C04F795683}")) 
  		{
  			wchar_t* wszFileName = ((HFileContext*)szContext)->wszFileName;
 -			{	for (wchar_t* p = wszFileName; *p != 0; p++)
 -				{	
 -					switch(*p) 
 -					{
 -					case ':': case '?': case '/': case '\\': case '*':
 -						*p = '_';
 -					}	
 +			for (wchar_t* p = wszFileName; *p != 0; p++)
 +			{	
 +				switch(*p) 
 +				{
 +				case ':': case '?': case '/': case '\\': case '*':
 +					*p = '_';
  				}	
 -			}
 +			}	
  			mir_free(ft->std.tszCurrentFile);
  			ft->std.tszCurrentFile = mir_u2t(wszFileName);
 @@ -1363,12 +1374,12 @@ void CMsnProto::p2p_InitFileTransfer(  void CMsnProto::p2p_InitDirectTransfer(MimeHeaders& tFileInfo, MimeHeaders& tFileInfo2, const char* wlid)
  {
 -	const char	*szCallID = tFileInfo["Call-ID"],
 -				*szBranch = tFileInfo["Via"],
 -				*szConnType = tFileInfo2["Conn-Type"],
 -				*szUPnPNat = tFileInfo2["UPnPNat"],
 -				*szNetID = tFileInfo2["NetID"],
 -				*szICF = tFileInfo2["ICF"],
 +	const char	*szCallID      = tFileInfo["Call-ID"],
 +				*szBranch      = tFileInfo["Via"],
 +				*szConnType    = tFileInfo2["Conn-Type"],
 +				*szUPnPNat     = tFileInfo2["UPnPNat"],
 +				*szNetID       = tFileInfo2["NetID"],
 +				*szICF         = tFileInfo2["ICF"],
  				*szHashedNonce = tFileInfo2["Hashed-Nonce"];
  	if (szBranch != NULL) 
 @@ -1408,8 +1419,8 @@ void CMsnProto::p2p_InitDirectTransfer(MimeHeaders& tFileInfo, MimeHeaders& tFil  /*
  		if (p2p_isAvatarOnly(ft->std.hContact)) 
  		{
 -	//		p2p_sendStatus(ft, 1603);
 -	//		return;
 +			p2p_sendStatus(ft, 1603);
 +			return;
  		}
  		else
  			SendBroadcast(ft->std.hContact, ACKTYPE_FILE, ACKRESULT_INITIALISING, ft, 0);
 @@ -1475,7 +1486,7 @@ void CMsnProto::p2p_InitDirectTransfer(MimeHeaders& tFileInfo, MimeHeaders& tFil  }
 -void CMsnProto::p2p_startConnect(const char* wlid, const char* szCallID, const char* addr, const char* port)
 +void CMsnProto::p2p_startConnect(const char* wlid, const char* szCallID, const char* addr, const char* port, bool ipv6)
  {
  	if (port == NULL) return;
 @@ -1489,7 +1500,8 @@ void CMsnProto::p2p_startConnect(const char* wlid, const char* szCallID, const c  		newThread->mType = SERVER_P2P_DIRECT;
  		newThread->mInitialContactWLID = mir_strdup(wlid);
  		mir_snprintf(newThread->mCookie, sizeof(newThread->mCookie), "%s", szCallID);
 -		mir_snprintf(newThread->mServer, sizeof(newThread->mServer), "%s:%s", addr, port);
 +		mir_snprintf(newThread->mServer, sizeof(newThread->mServer),
 +			ipv6 ? "[%s]:%s" : "%s:%s", addr, port);
  		newThread->startThread(&CMsnProto::p2p_fileActiveThread, this);
 @@ -1499,14 +1511,16 @@ void CMsnProto::p2p_startConnect(const char* wlid, const char* szCallID, const c  void CMsnProto::p2p_InitDirectTransfer2(MimeHeaders& tFileInfo, MimeHeaders& tFileInfo2, const char* wlid)
  {
 -	const char  *szCallID = tFileInfo["Call-ID"],
 +	const char  *szCallID          = tFileInfo["Call-ID"],
  				*szInternalAddress = tFileInfo2["IPv4Internal-Addrs"],
 -				*szInternalPort = tFileInfo2["IPv4Internal-Port"],
 +				*szInternalPort    = tFileInfo2["IPv4Internal-Port"],
  				*szExternalAddress = tFileInfo2["IPv4External-Addrs"],
 -				*szExternalPort = tFileInfo2["IPv4External-Port"],
 -				*szNonce = tFileInfo2["Nonce"],
 -				*szHashedNonce = tFileInfo2["Hashed-Nonce"],
 -				*szListening = tFileInfo2["Listening"];
 +				*szExternalPort    = tFileInfo2["IPv4External-Port"],
 +				*szNonce           = tFileInfo2["Nonce"],
 +				*szHashedNonce     = tFileInfo2["Hashed-Nonce"],
 +				*szListening       = tFileInfo2["Listening"],
 +				*szV6Address       = tFileInfo2["IPv6-Addrs"],
 +				*szV6Port          = tFileInfo2["IPv6-Port" ];
  	if ((szNonce == NULL && szHashedNonce == NULL) || szListening == NULL) 
  	{
 @@ -1526,8 +1540,9 @@ void CMsnProto::p2p_InitDirectTransfer2(MimeHeaders& tFileInfo, MimeHeaders& tFi  	if (!strcmp(szListening, "true") && strcmp(dc->xNonce, sttVoidUid)) 
  	{
 -		p2p_startConnect(wlid, szCallID, szInternalAddress, szInternalPort);
 -		p2p_startConnect(wlid, szCallID, szExternalAddress, szExternalPort);
 +		p2p_startConnect(wlid, szCallID, szV6Address, szV6Port, true);
 +		p2p_startConnect(wlid, szCallID, szInternalAddress, szInternalPort, false);
 +		p2p_startConnect(wlid, szCallID, szExternalAddress, szExternalPort, false);
  	}
  }
 @@ -1622,6 +1637,7 @@ LBL_Close:  		chdrs.addString("Conn-Type", MyConnection.GetMyUdpConStr());
  		chdrs.addBool("UPnPNat", MyConnection.upnpNAT);
  		chdrs.addBool("ICF", MyConnection.icf);
 +		chdrs.addString("IPv6-global", GetGlobalIp(), 2);
  		chdrs.addString("Hashed-Nonce", dc->mNonceToHash(), 2);
  	}
  	else if (!strcmp(szOldContentType, "application/x-msnmsgr-transrespbody")) 
 @@ -1632,7 +1648,10 @@ LBL_Close:  					*szExternalAddress = tFileInfo2["IPv4External-Addrs"],
  					*szExternalPort    = tFileInfo2["IPv4External-Port" ],
  					*szInternalAddress = tFileInfo2["IPv4Internal-Addrs"],
 -					*szInternalPort    = tFileInfo2["IPv4Internal-Port" ];
 +					*szInternalPort    = tFileInfo2["IPv4Internal-Port" ],
 +					*szV6Address       = tFileInfo2["IPv6-Addrs"],
 +					*szV6Port          = tFileInfo2["IPv6-Port" ];
 +
  		if ((szNonce == NULL && szHashedNonce == NULL) || szListening == NULL) 
  		{
  			MSN_DebugLog("Invalid data packet, exiting...");
 @@ -1653,8 +1672,9 @@ LBL_Close:  		// another side reported that it will be a server.
  		if (!strcmp(szListening, "true") && (szNonce == NULL || strcmp(szNonce, sttVoidUid))) 
  		{
 -			p2p_startConnect(ft->p2p_dest, szCallID, szInternalAddress, szInternalPort);
 -			p2p_startConnect(ft->p2p_dest, szCallID, szExternalAddress, szExternalPort);
 +			p2p_startConnect(ft->p2p_dest, szCallID, szV6Address, szV6Port, true);
 +			p2p_startConnect(ft->p2p_dest, szCallID, szInternalAddress, szInternalPort, false);
 +			p2p_startConnect(ft->p2p_dest, szCallID, szExternalAddress, szExternalPort, false);
  			return;
  		}
 @@ -1788,8 +1808,8 @@ void CMsnProto::p2p_processSIP(ThreadData* info, char* msgbody, P2PB_Header* hdr  			const char* callID = tFileInfo["Call-ID"];
  //			application/x-msnmsgr-session-failure-respbody
 -			
 -  			directconnection *dc = p2p_getDCByCallID(callID, wlid);
 +
 +			directconnection *dc = p2p_getDCByCallID(callID, wlid);
  			if (dc != NULL)
  			{
  				p2p_unregisterDC(dc);
 @@ -1830,7 +1850,7 @@ void CMsnProto::p2p_processSIP(ThreadData* info, char* msgbody, P2PB_Header* hdr  void  CMsnProto::p2p_processMsgV2(ThreadData* info,  char* msgbody, const char* wlid)
  {
  	P2PV2_Header hdrdata;
 -	
 +
  	char *msg = hdrdata.parseMsg(msgbody);
  	hdrdata.logHeader(this);
 @@ -1864,7 +1884,7 @@ void  CMsnProto::p2p_processMsgV2(ThreadData* info,  char* msgbody, const char*  			if (hdrdata.mRemSize == 0)
  			{
 -	  			size_t newsize;
 +				size_t newsize;
  				if (getCachedMsg(idx, msgbody, newsize))
  				{
  					unsigned id = hdrdata.mID;
 @@ -1942,9 +1962,9 @@ void  CMsnProto::p2p_processMsg(ThreadData* info,  char* msgbody, const char* wl  	//---- if we got a message
  	if (LOWORD(hdrdata.mFlags) == 0 && hdrdata.mSessionID == 0)
  	{
 -//		MsnContact *cont = Lists_Get(wlid);
 -//		if (cont && cont->places.getCount())
 -//			return;
 +		//		MsnContact *cont = Lists_Get(wlid);
 +		//		if (cont && cont->places.getCount())
 +		//			return;
  		if (hdrdata.mPacketLen < hdrdata.mTotalSize)
  		{
 @@ -2039,7 +2059,7 @@ void  CMsnProto::p2p_processMsg(ThreadData* info,  char* msgbody, const char* wl  	if (LOWORD(hdrdata.mFlags) == 0) 
  	{
  		//---- accept the data preparation message ------
 -//		const unsigned* pLongs = (unsigned*)msgbody;
 +		//		const unsigned* pLongs = (unsigned*)msgbody;
  		if (hdrdata.mPacketLen == 4 && hdrdata.mTotalSize == 4) 
  		{
  			p2p_sendAck(ft->p2p_dest, &hdrdata);
 @@ -2151,84 +2171,84 @@ void  CMsnProto::p2p_invite(unsigned iAppID, filetransfer* ft, const char *wlid)  	switch (iAppID) 
  	{
 -		case MSN_APPID_FILE:
 +	case MSN_APPID_FILE:
 +		{
 +			cbContext = sizeof(HFileContext);
 +			pContext = (char*)malloc(cbContext);
 +			HFileContext* ctx = (HFileContext*)pContext;
 +			memset(pContext, 0, cbContext);
 +			if (ft->p2p_isV2)
  			{
 -				cbContext = sizeof(HFileContext);
 -				pContext = (char*)malloc(cbContext);
 -				HFileContext* ctx = (HFileContext*)pContext;
 -				memset(pContext, 0, cbContext);
 -				if (ft->p2p_isV2)
 -				{
 -					cbContext -= 64;
 -					ctx->ver = 2; 
 -				}
 -				else
 -				{
 -					ctx->ver = 3; 
 -					ctx->id = 0xffffffff;
 -				}
 -				ctx->len = (unsigned)cbContext;
 -				ctx->type = MSN_TYPEID_FTNOPREVIEW;
 -				ctx->dwSize = ft->std.currentFileSize;
 +				cbContext -= 64;
 +				ctx->ver = 2; 
 +			}
 +			else
 +			{
 +				ctx->ver = 3; 
 +				ctx->id = 0xffffffff;
 +			}
 +			ctx->len = (unsigned)cbContext;
 +			ctx->type = MSN_TYPEID_FTNOPREVIEW;
 +			ctx->dwSize = ft->std.currentFileSize;
 -				TCHAR* pszFiles = _tcsrchr(ft->std.tszCurrentFile, '\\');
 -				if (pszFiles)
 -					pszFiles++;
 -				else
 -					pszFiles = ft->std.tszCurrentFile;
 +			TCHAR* pszFiles = _tcsrchr(ft->std.tszCurrentFile, '\\');
 +			if (pszFiles)
 +				pszFiles++;
 +			else
 +				pszFiles = ft->std.tszCurrentFile;
 -				wchar_t *fname = mir_t2u(pszFiles);
 -				wcsncpy(ctx->wszFileName, fname, MAX_PATH);
 -				mir_free(fname);
 +			wchar_t *fname = mir_t2u(pszFiles);
 +			wcsncpy(ctx->wszFileName, fname, MAX_PATH);
 +			mir_free(fname);
 -				ft->p2p_appID = MSN_APPID_FILE;
 -			}
 -			break;
 +			ft->p2p_appID = MSN_APPID_FILE;
 +		}
 +		break;
 -		default:
 -			ft->p2p_appID = MSN_APPID_AVATAR2;
 +	default:
 +		ft->p2p_appID = MSN_APPID_AVATAR2;
 -			if (ft->p2p_object == NULL)
 -			{
 -				delete ft;
 -				return;
 -			}
 +		if (ft->p2p_object == NULL)
 +		{
 +			delete ft;
 +			return;
 +		}
 -			ezxml_t xmlo = ezxml_parse_str(NEWSTR_ALLOCA(ft->p2p_object), strlen(ft->p2p_object));
 -			ezxml_t xmlr = ezxml_new("msnobj");
 -				
 -			const char* p;
 -			p = ezxml_attr(xmlo, "Creator");
 -			if (p != NULL)
 -				ezxml_set_attr(xmlr, "Creator", p);
 -			p = ezxml_attr(xmlo, "Size");
 -			if (p != NULL) {
 -				ezxml_set_attr(xmlr, "Size", p);
 -				ft->std.totalBytes = ft->std.currentFileSize = _atoi64(p);
 -			}
 -			p = ezxml_attr(xmlo, "Type");
 -			if (p != NULL)
 -				ezxml_set_attr(xmlr, "Type", p);
 -			p = ezxml_attr(xmlo, "Location");
 -			if (p != NULL)
 -				ezxml_set_attr(xmlr, "Location", p);
 -			p = ezxml_attr(xmlo, "Friendly");
 -			if (p != NULL)
 -				ezxml_set_attr(xmlr, "Friendly", p);
 -			p = ezxml_attr(xmlo, "SHA1D");
 -			if (p != NULL)
 -				ezxml_set_attr(xmlr, "SHA1D", p);
 -			p = ezxml_attr(xmlo, "SHA1C");
 -			if (p != NULL)
 -				ezxml_set_attr(xmlr, "SHA1C", p);
 -
 -			pContext = ezxml_toxml(xmlr, false);
 -			cbContext = strlen(pContext)+1;
 -
 -			ezxml_free(xmlr);
 -			ezxml_free(xmlo);
 +		ezxml_t xmlo = ezxml_parse_str(NEWSTR_ALLOCA(ft->p2p_object), strlen(ft->p2p_object));
 +		ezxml_t xmlr = ezxml_new("msnobj");
 +
 +		const char* p;
 +		p = ezxml_attr(xmlo, "Creator");
 +		if (p != NULL)
 +			ezxml_set_attr(xmlr, "Creator", p);
 +		p = ezxml_attr(xmlo, "Size");
 +		if (p != NULL) {
 +			ezxml_set_attr(xmlr, "Size", p);
 +			ft->std.totalBytes = ft->std.currentFileSize = _atoi64(p);
 +		}
 +		p = ezxml_attr(xmlo, "Type");
 +		if (p != NULL)
 +			ezxml_set_attr(xmlr, "Type", p);
 +		p = ezxml_attr(xmlo, "Location");
 +		if (p != NULL)
 +			ezxml_set_attr(xmlr, "Location", p);
 +		p = ezxml_attr(xmlo, "Friendly");
 +		if (p != NULL)
 +			ezxml_set_attr(xmlr, "Friendly", p);
 +		p = ezxml_attr(xmlo, "SHA1D");
 +		if (p != NULL)
 +			ezxml_set_attr(xmlr, "SHA1D", p);
 +		p = ezxml_attr(xmlo, "SHA1C");
 +		if (p != NULL)
 +			ezxml_set_attr(xmlr, "SHA1C", p);
 +
 +		pContext = ezxml_toxml(xmlr, false);
 +		cbContext = strlen(pContext)+1;
 +
 +		ezxml_free(xmlr);
 +		ezxml_free(xmlo);
 -			break;
 +		break;
  	}
  	bool sessionExist = p2p_sessionRegistered(ft);
 @@ -2335,6 +2355,7 @@ void CMsnProto::p2p_inviteDc(filetransfer* ft, const char *wlid)  	chdrs.addString("Conn-Type", MyConnection.GetMyUdpConStr());
  	chdrs.addBool("UPnPNat", MyConnection.upnpNAT);
  	chdrs.addBool("ICF", MyConnection.icf);
 +	chdrs.addString("IPv6-global", GetGlobalIp(), 2);
  	chdrs.addString("Hashed-Nonce", dc->mNonceToHash(), 2);
  	chdrs.addString("SessionID", "0");
  	chdrs.addString("SChannelState", "0");
 @@ -2452,7 +2473,7 @@ char* P2PV2_Header::createMsg(char *buf, const char* wlid, CMsnProto *ppro)  	*(unsigned*)(buf + 4) = _htonl(mID);
  	char *buf1 = buf + 8;
 -	
 +
  	if (mAckUniqueID)
  	{
  		*(unsigned char*)buf1 = 2;
 @@ -2475,7 +2496,7 @@ char* P2PV2_Header::createMsg(char *buf, const char* wlid, CMsnProto *ppro)  	*(unsigned char*)(buf1 + 1) = mTFCode;
  	*(unsigned short*)(buf1 + 2) = _htons(mPacketNum);
  	*(unsigned*)(buf1 + 4) = _htonl(mSessionID);
 -	
 +
  	if (mRemSize)
  	{
  		*(unsigned char*)(buf1 + 8) = 1;
 diff --git a/protocols/MSN/msn_proto.h b/protocols/MSN/msn_proto.h index f09ec82ef7..8f6ddfbfd4 100644 --- a/protocols/MSN/msn_proto.h +++ b/protocols/MSN/msn_proto.h @@ -369,7 +369,7 @@ struct CMsnProto : public PROTO_INTERFACE  	void  p2p_savePicture2disk(filetransfer* ft);
  	bool  p2p_createListener(filetransfer* ft, directconnection *dc, MimeHeaders& chdrs);
 -	void  p2p_startConnect(const char* wlid, const char* szCallID, const char* addr, const char* port);
 +	void  p2p_startConnect(const char* wlid, const char* szCallID, const char* addr, const char* port, bool ipv6);
  	void  p2p_sendAbortSession(filetransfer* ft);
  	void  p2p_sendAck(const char *wlid, P2PB_Header* hdrdata);
 diff --git a/src/core/commonheaders.h b/src/core/commonheaders.h index b70c0bab04..8603a42ffd 100644 --- a/src/core/commonheaders.h +++ b/src/core/commonheaders.h @@ -31,6 +31,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.  #define _WIN32_WINNT 0x0700
  #define _WIN32_IE 0x0601
 +#define INCL_WINSOCK_API_TYPEDEFS 1
 +
  #include "m_stdhdr.h"
  #include <winsock2.h>
 diff --git a/src/core/miranda.cpp b/src/core/miranda.cpp index fe38d096e1..8ce9c0b0be 100644 --- a/src/core/miranda.cpp +++ b/src/core/miranda.cpp @@ -77,8 +77,10 @@ pfnGetBufferedPaintBits getBufferedPaintBits;  pfnDwmExtendFrameIntoClientArea dwmExtendFrameIntoClientArea;
  pfnDwmIsCompositionEnabled dwmIsCompositionEnabled;
 -pfnGetaddrinfo MyGetaddrinfo;
 -pfnFreeaddrinfo MyFreeaddrinfo;
 +LPFN_GETADDRINFO MyGetaddrinfo;
 +LPFN_FREEADDRINFO MyFreeaddrinfo;
 +LPFN_WSASTRINGTOADDRESSA MyWSAStringToAddress;
 +LPFN_WSAADDRESSTOSTRINGA MyWSAAddressToString;
  ITaskbarList3 * pTaskbarInterface;
 @@ -630,8 +632,10 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int )  	}
  	HMODULE hWinSock = GetModuleHandleA("ws2_32");
 -	MyGetaddrinfo = (pfnGetaddrinfo)GetProcAddress(hWinSock, "getaddrinfo");
 -	MyFreeaddrinfo = (pfnFreeaddrinfo)GetProcAddress(hWinSock, "freeaddrinfo");
 +	MyGetaddrinfo = (LPFN_GETADDRINFO)GetProcAddress(hWinSock, "getaddrinfo");
 +	MyFreeaddrinfo = (LPFN_FREEADDRINFO)GetProcAddress(hWinSock, "freeaddrinfo");
 +	MyWSAStringToAddress = (LPFN_WSASTRINGTOADDRESSA)GetProcAddress(hWinSock, "WSAStringToAddressA");
 +	MyWSAAddressToString = (LPFN_WSAADDRESSTOSTRINGA)GetProcAddress(hWinSock, "WSAAddressToStringA");
  	if (bufferedPaintInit) bufferedPaintInit();
 diff --git a/src/core/miranda.h b/src/core/miranda.h index 850e2a78c8..81c7c6d41f 100644 --- a/src/core/miranda.h +++ b/src/core/miranda.h @@ -108,11 +108,10 @@ typedef HRESULT ( STDAPICALLTYPE *pfnDwmIsCompositionEnabled )( BOOL * );  extern pfnDwmExtendFrameIntoClientArea dwmExtendFrameIntoClientArea;
  extern pfnDwmIsCompositionEnabled dwmIsCompositionEnabled;
 -typedef INT (STDAPICALLTYPE *pfnGetaddrinfo)(PCSTR pNodeName, PCSTR pServiceName, const ADDRINFOA * pHints, PADDRINFOA * ppResult);
 -typedef INT (STDAPICALLTYPE *pfnFreeaddrinfo)(PADDRINFOA pAddrInfo);
 -
 -extern pfnGetaddrinfo MyGetaddrinfo;
 -extern pfnFreeaddrinfo MyFreeaddrinfo;
 +extern LPFN_GETADDRINFO MyGetaddrinfo;
 +extern LPFN_FREEADDRINFO MyFreeaddrinfo;
 +extern LPFN_WSASTRINGTOADDRESSA MyWSAStringToAddress;
 +extern LPFN_WSAADDRESSTOSTRINGA MyWSAAddressToString;
  /**** file.c ***************************************************************************/
 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, ¬blocking) != 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, ¬blocking) != 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, ¬blocking);
 -	if (lasterr) SetLastError(lasterr);
 +	if (nlc->s != INVALID_SOCKET) ioctlsocket(nlc->s, FIONBIO, ¬blocking);
 +	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) 
  | 
