diff options
Diffstat (limited to 'protocols/MSN/src/msn_natdetect.cpp')
| -rw-r--r-- | protocols/MSN/src/msn_natdetect.cpp | 471 | 
1 files changed, 0 insertions, 471 deletions
diff --git a/protocols/MSN/src/msn_natdetect.cpp b/protocols/MSN/src/msn_natdetect.cpp deleted file mode 100644 index 35f518b51b..0000000000 --- a/protocols/MSN/src/msn_natdetect.cpp +++ /dev/null @@ -1,471 +0,0 @@ -/*
 -Plugin of Miranda IM for communicating with users of the MSN Messenger protocol.
 -
 -Copyright (c) 2012-2017 Miranda NG Team
 -Copyright (c) 2007-2012 Boris Krasnovskiy.
 -
 -This program is free software; you can redistribute it and/or
 -modify it under the terms of the GNU General Public License
 -as published by the Free Software Foundation; either version 2
 -of the License, or (at your option) any later version.
 -
 -This program is distributed in the hope that it will be useful,
 -but WITHOUT ANY WARRANTY; without even the implied warranty of
 -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 -GNU General Public License for more details.
 -
 -You should have received a copy of the GNU General Public License
 -along with this program.  If not, see <http://www.gnu.org/licenses/>.
 -*/
 -
 -#include "stdafx.h"
 -#include "msn_proto.h"
 -#include <netfw.h>
 -#ifdef OBSOLETE
 -
 -#ifndef CLSID_NetFwMgr
 -#define MDEF_CLSID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
 -	const CLSID name = { l, w1, w2, { b1, b2,  b3,  b4,  b5,  b6,  b7,  b8 } }
 -
 -	MDEF_CLSID(CLSID_NetFwMgr, 0x304ce942, 0x6e39, 0x40d8, 0x94, 0x3a, 0xb9, 0x13, 0xc4, 0x0c, 0x9c, 0xd4);
 -	MDEF_CLSID(IID_INetFwMgr, 0xf7898af5, 0xcac4, 0x4632, 0xa2, 0xec, 0xda ,0x06, 0xe5, 0x11, 0x1a, 0xf2);
 -#endif
 -
 -
 -MyConnectionType MyConnection;
 -
 -const char* conStr[] =
 -{
 -	"Unknown-Connect",
 -	"Direct-Connect",
 -	"Unknown-NAT",
 -	"IP-Restrict-NAT",
 -	"Port-Restrict-NAT",
 -	"Symmetric-NAT",
 -	"Firewall",
 -	"ISALike"
 -};
 -
 -
 -void CMsnProto::DecryptEchoPacket(UDPProbePkt& pkt)
 -{
 -	pkt.clientPort ^= 0x3141;
 -	pkt.discardPort ^= 0x3141;
 -	pkt.testPort ^= 0x3141;
 -	pkt.clientIP ^= 0x31413141;
 -	pkt.testIP ^= 0x31413141;
 -
 -
 -	IN_ADDR addr;
 -	debugLogA("Echo packet: version: 0x%x  service code: 0x%x  transaction ID: 0x%x",
 -		pkt.version, pkt.serviceCode, pkt.trId);
 -	addr.S_un.S_addr = pkt.clientIP;
 -	debugLogA("Echo packet: client port: %u  client addr: %s",
 -		pkt.clientPort, inet_ntoa(addr));
 -	addr.S_un.S_addr = pkt.testIP;
 -	debugLogA("Echo packet: discard port: %u  test port: %u test addr: %s",
 -		pkt.discardPort, pkt.testPort, inet_ntoa(addr));
 -}
 -
 -
 -static void DiscardExtraPackets(SOCKET s)
 -{
 -	Sleep(3000);
 -
 -	static const TIMEVAL tv = { 0, 0 };
 -	unsigned buf;
 -
 -	for (;;) {
 -		if (g_bTerminated) break;
 -
 -		fd_set fd;
 -		FD_ZERO(&fd);
 -		FD_SET(s, &fd);
 -
 -		if (select(1, &fd, NULL, NULL, &tv) == 1)
 -			recv(s, (char*)&buf, sizeof(buf), 0);
 -		else
 -			break;
 -	}
 -}
 -
 -
 -void CMsnProto::MSNatDetect(void)
 -{
 -	PHOSTENT host = gethostbyname("echo.edge.messenger.live.com");
 -	if (host == NULL) {
 -		debugLogA("P2PNAT could not find echo server \"echo.edge.messenger.live.com\"");
 -		return;
 -	}
 -
 -	SOCKADDR_IN addr;
 -	addr.sin_family = AF_INET;
 -	addr.sin_port = _htons(7001);
 -	addr.sin_addr = *(PIN_ADDR)host->h_addr_list[0];
 -
 -	debugLogA("P2PNAT Detected echo server IP %d.%d.%d.%d",
 -		addr.sin_addr.S_un.S_un_b.s_b1, addr.sin_addr.S_un.S_un_b.s_b2,
 -		addr.sin_addr.S_un.S_un_b.s_b3, addr.sin_addr.S_un.S_un_b.s_b4);
 -
 -	SOCKET s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
 -	if (connect(s, (SOCKADDR*)&addr, sizeof(addr)) == SOCKET_ERROR) {
 -		debugLogA("P2PNAT could not connect to echo server \"echo.edge.messenger.live.com\"");
 -		closesocket(s);
 -		return;
 -	}
 -
 -	UDPProbePkt pkt = { 0 }, pkt2;
 -
 -	// Detect My IP
 -	pkt.version = 2;
 -	pkt.serviceCode = 4;
 -	send(s, (char*)&pkt, sizeof(pkt), 0);
 -
 -	SOCKADDR_IN  myaddr;
 -	int szname = sizeof(myaddr);
 -	getsockname(s, (SOCKADDR*)&myaddr, &szname);
 -
 -	MyConnection.intIP = myaddr.sin_addr.S_un.S_addr;
 -	debugLogA("P2PNAT Detected IP facing internet %d.%d.%d.%d",
 -		myaddr.sin_addr.S_un.S_un_b.s_b1, myaddr.sin_addr.S_un.S_un_b.s_b2,
 -		myaddr.sin_addr.S_un.S_un_b.s_b3, myaddr.sin_addr.S_un.S_un_b.s_b4);
 -
 -	SOCKET s1 = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
 -
 -	pkt.version = 2;
 -	pkt.serviceCode = 1;
 -	pkt.clientPort = 0x3141;
 -	pkt.clientIP = 0x31413141;
 -
 -	UDPProbePkt rpkt = { 0 };
 -
 -	// NAT detection
 -	unsigned i;
 -	for (i = 0; i < 4; ++i) {
 -		if (g_bTerminated) break;
 -
 -		// Send echo request to server 1
 -		debugLogA("P2PNAT Request 1 attempt %d sent", i);
 -		sendto(s1, (char*)&pkt, sizeof(pkt), 0, (SOCKADDR*)&addr, sizeof(addr));
 -
 -		fd_set fd;
 -		FD_ZERO(&fd);
 -		FD_SET(s1, &fd);
 -		TIMEVAL tv = { 0, 200000 * (1 << i) };
 -
 -		if (select(1, &fd, NULL, NULL, &tv) == 1) {
 -			debugLogA("P2PNAT Request 1 attempt %d response", i);
 -			recv(s1, (char*)&rpkt, sizeof(rpkt), 0);
 -			pkt2 = rpkt;
 -			DecryptEchoPacket(rpkt);
 -			break;
 -		}
 -		else debugLogA("P2PNAT Request 1 attempt %d timeout", i);
 -	}
 -
 -	closesocket(s);
 -
 -	// Server did not respond
 -	if (i >= 4) {
 -		MyConnection.udpConType = conFirewall;
 -		closesocket(s1);
 -		return;
 -	}
 -
 -	MyConnection.extIP = rpkt.clientIP;
 -
 -	// Check if NAT not found
 -	if (MyConnection.extIP == MyConnection.intIP) {
 -		if (msnExternalIP != NULL && inet_addr(msnExternalIP) != MyConnection.extIP)
 -			MyConnection.udpConType = conISALike;
 -		else
 -			MyConnection.udpConType = conDirect;
 -
 -		closesocket(s1);
 -		return;
 -	}
 -
 -	// Detect UPnP NAT
 -	NETLIBBIND nlb = { 0 };
 -	nlb.cbSize = sizeof(nlb);
 -	nlb.pfnNewConnectionV2 = MSN_ConnectionProc;
 -	nlb.pExtra = this;
 -
 -	HANDLE sb = (HANDLE)CallService(MS_NETLIB_BINDPORT, (WPARAM)m_hNetlibUser, (LPARAM)&nlb);
 -	if (sb != NULL) {
 -		MyConnection.upnpNAT = htonl(nlb.dwExternalIP) == MyConnection.extIP;
 -		Sleep(100);
 -		Netlib_CloseHandle(sb);
 -	}
 -
 -	DiscardExtraPackets(s1);
 -
 -	// Start IP Restricted NAT detection
 -	UDPProbePkt rpkt2 = { 0 };
 -	pkt2.serviceCode = 3;
 -	SOCKADDR_IN addr2 = addr;
 -	addr2.sin_addr.S_un.S_addr = rpkt.testIP;
 -	addr2.sin_port = rpkt.discardPort;
 -	for (i = 0; i < 4; ++i) {
 -		if (g_bTerminated) break;
 -
 -		debugLogA("P2PNAT Request 2 attempt %d sent", i);
 -		// Remove IP restriction for server 2
 -		sendto(s1, NULL, 0, 0, (SOCKADDR*)&addr2, sizeof(addr2));
 -		// Send echo request to server 1 for server 2
 -		sendto(s1, (char*)&pkt2, sizeof(pkt2), 0, (SOCKADDR*)&addr, sizeof(addr));
 -
 -		fd_set fd;
 -		FD_ZERO(&fd);
 -		FD_SET(s1, &fd);
 -		TIMEVAL tv = { 0, 200000 * (1 << i) };
 -
 -		if (select(1, &fd, NULL, NULL, &tv) == 1) {
 -			debugLogA("P2PNAT Request 2 attempt %d response", i);
 -			recv(s1, (char*)&rpkt2, sizeof(rpkt2), 0);
 -			DecryptEchoPacket(rpkt2);
 -			break;
 -		}
 -		else
 -			debugLogA("P2PNAT Request 2 attempt %d timeout", i);
 -	}
 -
 -	// Response recieved so it's an IP Restricted NAT (Restricted Cone NAT)
 -	// (MSN does not detect Full Cone NAT and consider it as IP Restricted NAT)
 -	if (i < 4) {
 -		MyConnection.udpConType = conIPRestrictNAT;
 -		closesocket(s1);
 -		return;
 -	}
 -
 -	DiscardExtraPackets(s1);
 -
 -	// Symmetric NAT detection
 -	addr2.sin_port = rpkt.testPort;
 -	for (i = 0; i < 4; ++i) {
 -		if (g_bTerminated) break;
 -
 -		debugLogA("P2PNAT Request 3 attempt %d sent", i);
 -		// Send echo request to server 1
 -		sendto(s1, (char*)&pkt, sizeof(pkt), 0, (SOCKADDR*)&addr2, sizeof(addr2));
 -
 -		fd_set fd;
 -		FD_ZERO(&fd);
 -		FD_SET(s1, &fd);
 -		TIMEVAL tv = { 1 << i, 0 };
 -
 -		if (select(1, &fd, NULL, NULL, &tv) == 1) {
 -			debugLogA("P2PNAT Request 3 attempt %d response", i);
 -			recv(s1, (char*)&rpkt2, sizeof(rpkt2), 0);
 -			DecryptEchoPacket(rpkt2);
 -			break;
 -		}
 -		else
 -			debugLogA("P2PNAT Request 3 attempt %d timeout", i);
 -	}
 -	if (i < 4) {
 -		// If ports different it's symmetric NAT
 -		MyConnection.udpConType = rpkt.clientPort == rpkt2.clientPort ?
 -conPortRestrictNAT : conSymmetricNAT;
 -	}
 -	closesocket(s1);
 -}
 -
 -
 -static bool IsIcfEnabled(void)
 -{
 -	HRESULT hr;
 -	VARIANT_BOOL fwEnabled = VARIANT_FALSE;
 -
 -	INetFwProfile* fwProfile = NULL;
 -	INetFwMgr* fwMgr = NULL;
 -	INetFwPolicy* fwPolicy = NULL;
 -	INetFwAuthorizedApplication* fwApp = NULL;
 -	INetFwAuthorizedApplications* fwApps = NULL;
 -	BSTR fwBstrProcessImageFileName = NULL;
 -	wchar_t *wszFileName = NULL;
 -
 -	hr = CoInitialize(NULL);
 -	if (FAILED(hr)) return false;
 -
 -	// Create an instance of the firewall settings manager.
 -	hr = CoCreateInstance(CLSID_NetFwMgr, NULL, CLSCTX_INPROC_SERVER,
 -		IID_INetFwMgr, (void**)&fwMgr);
 -	if (FAILED(hr)) goto error;
 -
 -	// Retrieve the local firewall policy.
 -	hr = fwMgr->get_LocalPolicy(&fwPolicy);
 -	if (FAILED(hr)) goto error;
 -
 -	// Retrieve the firewall profile currently in effect.
 -	hr = fwPolicy->get_CurrentProfile(&fwProfile);
 -	if (FAILED(hr)) goto error;
 -
 -	// Get the current state of the firewall.
 -	hr = fwProfile->get_FirewallEnabled(&fwEnabled);
 -	if (FAILED(hr)) goto error;
 -
 -	if (fwEnabled == VARIANT_FALSE) goto error;
 -
 -	// Retrieve the authorized application collection.
 -	hr = fwProfile->get_AuthorizedApplications(&fwApps);
 -	if (FAILED(hr)) goto error;
 -
 -	wchar_t szFileName[MAX_PATH];
 -	GetModuleFileName(NULL, szFileName, _countof(szFileName));
 -
 -	wszFileName = mir_wstrdup(szFileName);
 -
 -	// Allocate a BSTR for the process image file name.
 -	fwBstrProcessImageFileName = SysAllocString(wszFileName);
 -	if (FAILED(hr)) goto error;
 -
 -	// Attempt to retrieve the authorized application.
 -	hr = fwApps->Item(fwBstrProcessImageFileName, &fwApp);
 -	if (SUCCEEDED(hr)) {
 -		// Find out if the authorized application is enabled.
 -		fwApp->get_Enabled(&fwEnabled);
 -		fwEnabled = ~fwEnabled;
 -	}
 -
 -error:
 -	// Free the BSTR.
 -	SysFreeString(fwBstrProcessImageFileName);
 -	mir_free(wszFileName);
 -
 -	// Release the authorized application instance.
 -	if (fwApp != NULL) fwApp->Release();
 -
 -	// Release the authorized application collection.
 -	if (fwApps != NULL) fwApps->Release();
 -
 -	// Release the firewall profile.
 -	if (fwProfile != NULL) fwProfile->Release();
 -
 -	// Release the local firewall policy.
 -	if (fwPolicy != NULL) fwPolicy->Release();
 -
 -	// Release the firewall settings manager.
 -	if (fwMgr != NULL) fwMgr->Release();
 -
 -	CoUninitialize();
 -
 -	return fwEnabled != VARIANT_FALSE;
 -}
 -
 -void CMsnProto::MSNConnDetectThread(void*)
 -{
 -	char parBuf[512] = "";
 -
 -	memset(&MyConnection, 0, sizeof(MyConnection));
 -
 -	MyConnection.icf = IsIcfEnabled();
 -	bool portsMapped = getByte("NLSpecifyIncomingPorts", 0) != 0;
 -
 -	unsigned gethst = getByte("AutoGetHost", 1);
 -	switch (gethst) {
 -	case 0:
 -		debugLogA("P2PNAT User overwrote IP connection is guessed by user settings only");
 -
 -		// User specified host by himself so check if it matches MSN information
 -		// if it does, move to connection type autodetection,
 -		// if it does not, guess connection type from available info
 -		db_get_static(NULL, m_szModuleName, "YourHost", parBuf, sizeof(parBuf));
 -		if (msnExternalIP == NULL || mir_strcmp(msnExternalIP, parBuf) != 0) {
 -			MyConnection.extIP = inet_addr(parBuf);
 -			if (MyConnection.extIP == INADDR_NONE) {
 -				PHOSTENT myhost = gethostbyname(parBuf);
 -				if (myhost != NULL)
 -					MyConnection.extIP = ((PIN_ADDR)myhost->h_addr)->S_un.S_addr;
 -				else
 -					setByte("AutoGetHost", 1);
 -			}
 -			if (MyConnection.extIP != INADDR_NONE) {
 -				MyConnection.intIP = MyConnection.extIP;
 -				MyConnection.udpConType = MyConnection.extIP ? (ConEnum)portsMapped : conUnknown;
 -				MyConnection.CalculateWeight();
 -				return;
 -			}
 -			else
 -				MyConnection.extIP = 0;
 -		}
 -		break;
 -
 -	case 1:
 -		if (msnExternalIP != NULL)
 -			MyConnection.extIP = inet_addr(msnExternalIP);
 -		else {
 -			gethostname(parBuf, sizeof(parBuf));
 -			PHOSTENT myhost = gethostbyname(parBuf);
 -			if (myhost != NULL)
 -				MyConnection.extIP = ((PIN_ADDR)myhost->h_addr)->S_un.S_addr;
 -		}
 -		MyConnection.intIP = MyConnection.extIP;
 -		break;
 -
 -	case 2:
 -		MyConnection.udpConType = conUnknown;
 -		MyConnection.CalculateWeight();
 -		return;
 -	}
 -
 -	if (getByte("NLSpecifyOutgoingPorts", 0)) {
 -		// User specified outgoing ports so the connection must be firewalled
 -		// do not autodetect and guess connection type from available info
 -		MyConnection.intIP = MyConnection.extIP;
 -		MyConnection.udpConType = (ConEnum)portsMapped;
 -		MyConnection.upnpNAT = false;
 -		MyConnection.CalculateWeight();
 -		return;
 -	}
 -
 -	MSNatDetect();
 -
 -	// If user mapped incoming ports consider direct connection
 -	if (portsMapped) {
 -		debugLogA("P2PNAT User manually mapped ports for incoming connection");
 -		switch (MyConnection.udpConType) {
 -		case conUnknown:
 -		case conFirewall:
 -		case conISALike:
 -			MyConnection.udpConType = conDirect;
 -			break;
 -
 -		case conUnknownNAT:
 -		case conPortRestrictNAT:
 -		case conIPRestrictNAT:
 -		case conSymmetricNAT:
 -			MyConnection.upnpNAT = true;
 -			break;
 -		}
 -	}
 -
 -	debugLogA("P2PNAT Connection %s found UPnP: %d ICF: %d", conStr[MyConnection.udpConType],
 -		MyConnection.upnpNAT, MyConnection.icf);
 -
 -	MyConnection.CalculateWeight();
 -}
 -
 -void MyConnectionType::SetUdpCon(const char* str)
 -{
 -	for (unsigned i = 0; i < sizeof(conStr) / sizeof(char*); ++i) {
 -		if (mir_strcmp(conStr[i], str) == 0) {
 -			udpConType = (ConEnum)i;
 -			break;
 -		}
 -	}
 -}
 -
 -void MyConnectionType::CalculateWeight(void)
 -{
 -	if (icf) weight = 0;
 -	else if (udpConType == conDirect) weight = 6;
 -	else if (udpConType >= conIPRestrictNAT && udpConType <= conSymmetricNAT)
 -		weight = upnpNAT ? 5 : 2;
 -	else if (udpConType == conUnknownNAT)
 -		weight = upnpNAT ? 4 : 1;
 -	else if (udpConType == conUnknown) weight = 1;
 -	else if (udpConType == conFirewall) weight = 2;
 -	else if (udpConType == conISALike) weight = 3;
 -}
 -#endif
  | 
