Exemplo n.º 1
0
/////////////////////////////////////////////////////////////////////////////////
// Adds a NAT Port Mapping
// Params:
//		UPNPNAT_MAPPING *mapping  ->  Port Mapping Data
//			If mapping->externalPort is 0, then
//			mapping->externalPort gets the value of mapping->internalPort
//		bool tryRandom:
//			If If mapping->externalPort is in use, tries to find a free
//			random external port.
//
// Return:
//		UNAT_OK:
//			Successfull.
//		UNAT_EXTERNAL_PORT_IN_USE:
//			Error, you are trying to add a port mapping with an external port
//			in use.
//		UNAT_NOT_IN_LAN:
//			Error, you aren't in a LAN -> no router or firewall
//		UNAT_ERROR:
//			Error, use GetLastError() to get an error description.
/////////////////////////////////////////////////////////////////////////////////
MyUPnP::UPNPNAT_RETURN MyUPnP::AddNATPortMapping(UPNPNAT_MAPPING *mapping, bool tryRandom)
{
	CString	ProtoStr, Proto;

	if(!IsLANIP(GetLocalIP())){
		SetLastError(GetResString(IDS_UPNPSTATUS_NOTINLAN)); //zz_fly :: localize output
		return UNAT_NOT_IN_LAN;
	}
	
	if (!isComplete()) {
		Search();
		if (!isComplete()) {
			SetLastError(GetResString(IDS_UPNPSTATUS_ERROR)); //zz_fly :: localize output
			return UNAT_ERROR;
		}
	}

	if (mapping->protocol == UNAT_TCP){
		Proto = _T("TCP");
		ProtoStr = _T("TCP");
	}
	else {
		Proto = _T("UDP");
		ProtoStr = _T("UDP");
	}

	if(mapping->externalPort == 0)
		mapping->externalPort = mapping->internalPort;

	//WORD rndPort = mapping->externalPort;
	for (int retries = 200; retries>0; retries--) {
		CString Desc;
		Desc.Format(_T("eMule (%s) [%s: %u]"), mapping->description, ProtoStr, mapping->externalPort);

		if (addPortmap(mapping->externalPort, mapping->internalPort, GetLocalIPStr(), Desc, Proto)) {
			m_Mappings.AddTail(*mapping);
			SetLastError(GetResString(IDS_UPNPSTATUS_OK)); //zz_fly :: localize output
			return UNAT_OK;
		}

		if (!tryRandom) {
			SetLastError(GetResString(IDS_UPNPSTATUS_PORTINUSE)); //zz_fly :: localize output
			return UNAT_EXTERNAL_PORT_IN_USE;
		}

		mapping->externalPort = (WORD)(2049 + (65535 - 2049) * rand() / (RAND_MAX + 1));
	}

	SetLastError(GetResString(IDS_UPNPSTATUS_PORTINUSE2)); //zz_fly :: localize output
	return UNAT_EXTERNAL_PORT_IN_USE;
}
Exemplo n.º 2
0
/////////////////////////////////////////////////////////////////////////////////
// Removes a NAT Port Mapping
// Params:
//		UPNPNAT_MAPPING *mapping  ->  Port Mapping Data
//			Should be the same struct passed to AddNATPortMapping
//		bool removeFromList	-> Remove the port mapping from the internal list
//			Should by allways true (dafault value if not passed).
//			If you set it to false can cause an unexpected error.
//
//
// Return:
//		UNAT_OK:
//			Successfull.
//		UNAT_NOT_OWNED_PORTMAPPING:
//			Error, you are trying to remove a port mapping not owned by this class
//		UNAT_NOT_IN_LAN:
//			Error, you aren't in a LAN -> no router or firewall
//		UNAT_ERROR:
//			Error, use GetLastError() to get an error description.
/////////////////////////////////////////////////////////////////////////////////
MyUPnP::UPNPNAT_RETURN MyUPnP::RemoveNATPortMapping(UPNPNAT_MAPPING mapping, bool removeFromList)
{
	if(!IsLANIP(GetLocalIP())){
		SetLastError(GetResString(IDS_UPNPSTATUS_NOTINLAN)); //zz_fly :: localize output
		return UNAT_NOT_IN_LAN;
	}

	if (!isComplete()) {
		Search();
		if (!isComplete()) {
			SetLastError(GetResString(IDS_UPNPSTATUS_ERROR)); //zz_fly :: localize output
			return UNAT_ERROR;
		}
	}

	for(POSITION pos = m_Mappings.GetHeadPosition(); pos!=NULL; m_Mappings.GetNext(pos)){
		UPNPNAT_MAPPING search = m_Mappings.GetAt(pos);

		if (search.externalPort == mapping.externalPort 
			&& search.protocol == mapping.protocol)
		{
			CString Proto;

			if (mapping.protocol == UNAT_TCP)
				Proto = _T("TCP");
			else
				Proto = _T("UDP");

			if (deletePortmap(mapping.externalPort, Proto)) {
				if(removeFromList)
					m_Mappings.RemoveAt(pos);
				SetLastError(_T("Removed"));
				return UNAT_OK;
			} else {
				SetLastError(_T("Error getting StaticPortMappingCollection"));
				return UNAT_ERROR;
			}
		}
	}

	SetLastError(_T("Port mapping not owned by this class"));
	return UNAT_NOT_OWNED_PORTMAPPING;
}
Exemplo n.º 3
0
HRESULT CUPnpMgr::AddNATPortMapping(CUPnpNatMapping &mapping, BOOL bTryRandom)
{
	CSingleLock		localLock(&m_cs, TRUE);
	
	if(!IsLANIP(GetLocalIP()))
		return E_UNAT_NOT_IN_LAN;

	if (FAILED(m_nat.SearchDevice()))
		return E_UNAT_CANNOT_FIND_ROUTER;

	
	HRESULT		hr;
	CString		strDesc;
	int			i;

	if(0 == mapping.m_wExternalPort)
		mapping.m_wExternalPort = mapping.m_wInternalPort;

	mapping.m_strInternalClient = GetLocalIPStr();

	for (i = 0; i < RANDOM_RETRY_TIMES; i++)
	{
		strDesc.Format(_T("%s [%s: %u]"), mapping.m_strDescription, mapping.m_strProtocol, mapping.m_wExternalPort);

		hr = m_nat.AddPortMapping(CString(_T("")),
									mapping.m_wExternalPort, mapping.m_strProtocol,
									mapping.m_wInternalPort, mapping.m_strInternalClient,
									strDesc);


		switch(hr)
		{
		case S_OK:
			{
				CString		strInternalClient;
				hr = m_nat.GetSpecificPortMappingEntry(CString(_T("")),
														mapping.m_wExternalPort, mapping.m_strProtocol,
														NULL, &strInternalClient, NULL, NULL, NULL);
				if (SUCCEEDED(hr)
					&& strInternalClient == mapping.m_strInternalClient)			//	看PortMapping是否真的加进去了。
				{
					CUPnpNatMappingKey key;
					key.m_strRemoteHost.Empty();
					key.m_usExternalPort = mapping.m_wExternalPort;
					key.m_strProtocol = mapping.m_strProtocol;
					m_setAddedMapping.insert(key);

					WriteAddedMappingToFile();

					return S_OK;
				}
				else											//	如果添加请求成功返回而又不在列表中,则有可能是列表已满。
					return E_UNAT_ENTRY_MAYBE_FULL;

				break;
			}
		case E_UNAT_ACTION_HTTP_ERRORCODE:
			{
				if (718 == m_nat.GetLastActionErrorCode() && bTryRandom)
					mapping.m_wExternalPort = (WORD)(2049 + (65535 - 2049) * 1 *rand() / (RAND_MAX + 1));
				else
					return E_UNAT_ACTION_HTTP_ERRORCODE;
				break;
			}
		case E_UNAT_TIMEOUT:
			{
				//	为防止可能出现“实际加上了”但等待回复超时的情况,凡是执行了操作的都记下来,以便之后尝试清除一下。
				
				CUPnpNatMappingKey key;
				key.m_strRemoteHost.Empty();
				key.m_usExternalPort = mapping.m_wExternalPort;
				key.m_strProtocol = mapping.m_strProtocol;
				m_setAddedMapping.insert(key);

				WriteAddedMappingToFile();

				return E_UNAT_TIMEOUT;		//	超时未返回则直接返回,而不去重试。(因为此刻可能实际上添加成功,而不停去添加,可能造成路由器表项充满。)
				break;
			}
		default:
			return hr;
		}
	}

	return E_UNAT_REACH_RAND_PORT_RETRY_TIMES;
}