コード例 #1
0
BOOL CDownloadWithSources::AddSourceHit(const CQueryHit* pHit, BOOL bForce)
{
	CQuickLock oLock( Transfers.m_pSection );

	if ( ! AddSource( pHit, bForce ) )
		return FALSE;

	if ( Settings.Downloads.Metadata && m_pXML == NULL && pHit->m_pXML && pHit->m_pSchema )
	{
		m_pXML = pHit->m_pSchema->Instantiate( TRUE );
		m_pXML->AddElement( pHit->m_pXML->Clone() );
		pHit->m_pSchema->Validate( m_pXML, TRUE );
	}

	//if ( pHit->m_nProtocol == PROTOCOL_ED2K )
	//	Neighbours.FindDonkeySources( pHit->m_oED2K,
	//		(IN_ADDR*)pHit->m_oClientID.begin(), (WORD)pHit->m_oClientID.begin()[1] );

	// No URL, stop now with success
	if ( ! pHit->m_sURL.IsEmpty() &&
		 ! AddSourceInternal( new CDownloadSource( (CDownload*)this, pHit ) ) )
		return FALSE;

	return TRUE;
}
コード例 #2
0
BOOL CDownloadWithSources::AddSourceBT(const Hashes::BtGuid& oGUID, const IN_ADDR* pAddress, WORD nPort)
{
	// Unreachable (Push) BT sources should never be added.
	if ( Network.IsFirewalledAddress( pAddress, Settings.Connection.IgnoreOwnIP ) )
		return FALSE;

	return AddSourceInternal( new CDownloadSource( (CDownload*)this, oGUID, pAddress, nPort ) );
}
コード例 #3
0
BOOL CDownloadWithSources::AddSourceBT(SHA1* pGUID, IN_ADDR* pAddress, WORD nPort)
{
	// Unreachable (Push) BT sources should never be added.
	if ( Network.IsFirewalledAddress( pAddress, Settings.Connection.IgnoreOwnIP ) )
		return FALSE;
	
	// Check for own IP, in case IgnoreLocalIP is not set
	if ( ( Settings.Connection.IgnoreOwnIP ) && ( pAddress->S_un.S_addr == Network.m_pHost.sin_addr.S_un.S_addr ) ) 
		return FALSE;

	return AddSourceInternal( new CDownloadSource( (CDownload*)this, pGUID, pAddress, nPort ) );
}
コード例 #4
0
BOOL CDownloadWithSources::AddSourceURL(LPCTSTR pszURL, BOOL bURN, FILETIME* pLastSeen)
{
	if ( pszURL == NULL ) return FALSE;
	if ( *pszURL == 0 ) return FALSE;
	
	BOOL bHashAuth = FALSE;
	CSourceURL pURL;
	
	if ( *pszURL == '@' )
	{
		bHashAuth = TRUE;
		pszURL++;
	}
	
	if ( ! pURL.Parse( pszURL ) ) return FALSE;
	
	if ( bURN )
	{
		if ( pURL.m_pAddress.S_un.S_addr == Network.m_pHost.sin_addr.S_un.S_addr ) return FALSE;
		if ( Network.IsFirewalledAddress( &pURL.m_pAddress, TRUE ) ) return FALSE;
	}
	
	if ( m_pFailedSources.Find( pszURL ) != NULL ) return FALSE;
	
	if ( pURL.m_bSHA1 && m_bSHA1 )
	{
		if ( m_pSHA1 != pURL.m_pSHA1 ) return FALSE;
	}
	
	if ( m_sRemoteName.IsEmpty() && _tcslen( pszURL ) > 9 )
	{
		m_sRemoteName = &pszURL[8];
		
		int nPos = m_sRemoteName.ReverseFind( '/' );
		
		if ( nPos >= 0 )
		{
			m_sRemoteName = m_sRemoteName.Mid( nPos + 1 ).SpanExcluding( _T("?") );
			m_sRemoteName = CTransfer::URLDecode( m_sRemoteName );
		}
		else
		{
			m_sRemoteName.Empty();
		}
		
		if ( m_sRemoteName.IsEmpty() ) m_sRemoteName = _T("default.htm");
	}
	
	return AddSourceInternal( new CDownloadSource( (CDownload*)this, pszURL, bURN, bHashAuth, pLastSeen ) );
}
コード例 #5
0
BOOL CDownloadWithSources::AddSourceED2K(DWORD nClientID, WORD nClientPort, DWORD nServerIP, WORD nServerPort, GGUID* pGUID)
{
	return AddSourceInternal( new CDownloadSource( (CDownload*)this, nClientID, nClientPort, nServerIP, nServerPort, pGUID ) );
}
コード例 #6
0
BOOL CDownloadWithSources::AddSourceHit(CQueryHit* pHit, BOOL bForce)
{
	BOOL bHash = FALSE;
	
	if ( ! bForce )
	{
		if ( m_bSHA1 && pHit->m_bSHA1 )
		{
			if ( m_pSHA1 != pHit->m_pSHA1 ) return FALSE;
			bHash = TRUE;
		}
		else if ( m_bTiger && pHit->m_bTiger )
		{
			if ( m_pTiger != pHit->m_pTiger ) return FALSE;
			bHash = TRUE;
		}
		if ( m_bED2K && pHit->m_bED2K )
		{
			if ( m_pED2K != pHit->m_pED2K ) return FALSE;
			bHash = TRUE;
		}
		if ( m_bBTH && pHit->m_bBTH )
		{
			if ( m_pBTH != pHit->m_pBTH ) return FALSE;
			bHash = TRUE;
		}
	}
	
	if ( ! bHash && ! bForce )
	{
		if ( Settings.General.HashIntegrity ) return FALSE;
		
		if ( m_sRemoteName.IsEmpty() || pHit->m_sName.IsEmpty() ) return FALSE;
		if ( m_nSize == SIZE_UNKNOWN || ! pHit->m_bSize ) return FALSE;
		
		if ( m_nSize != pHit->m_nSize ) return FALSE;
		if ( m_sRemoteName.CompareNoCase( pHit->m_sName ) ) return FALSE;
	}
	
	if ( ! m_bSHA1 && pHit->m_bSHA1 )
	{
		m_bSHA1 = TRUE;
		m_pSHA1 = pHit->m_pSHA1;
	}
	if ( ! m_bTiger && pHit->m_bTiger )
	{
		m_bTiger = TRUE;
		m_pTiger = pHit->m_pTiger;
	}
	if ( ! m_bED2K && pHit->m_bED2K )
	{
		m_bED2K = TRUE;
		m_pED2K = pHit->m_pED2K;
	}
	
	if ( m_nSize == SIZE_UNKNOWN && pHit->m_bSize )
	{
		m_nSize = pHit->m_nSize;
	}
	
	if ( m_sRemoteName.IsEmpty() && pHit->m_sName.GetLength() )
	{
		m_sRemoteName = pHit->m_sName;
	}
	
	if ( Settings.Downloads.Metadata && m_pXML == NULL )
	{
		if ( pHit->m_pXML != NULL && pHit->m_sSchemaPlural.GetLength() )
		{
			m_pXML = new CXMLElement( NULL, pHit->m_sSchemaPlural );
			m_pXML->AddAttribute( _T("xmlns:xsi"), CXMLAttribute::xmlnsInstance );
			m_pXML->AddAttribute( CXMLAttribute::schemaName, pHit->m_sSchemaURI );
			m_pXML->AddElement( pHit->m_pXML->Clone() );
			
			if ( CSchema* pSchema = SchemaCache.Get( pHit->m_sSchemaURI ) )
			{
				pSchema->Validate( m_pXML, TRUE );
			}
		}
	}

	/*
	if ( pHit->m_nProtocol == PROTOCOL_ED2K )
	{
		Neighbours.FindDonkeySources( &pHit->m_pED2K,
			(IN_ADDR*)pHit->m_pClientID.w, (WORD)pHit->m_pClientID.w[1] );
	}
	*/

	// No URL, stop now with success
	if ( pHit->m_sURL.IsEmpty() ) return TRUE;
	
	return AddSourceInternal( new CDownloadSource( (CDownload*)this, pHit ) );
}
コード例 #7
0
BOOL CDownloadWithSources::AddSourceInternal(CDownloadSource* pSource)
{
	if ( ! pSource )
		return FALSE;	// Out of memory

	if ( GetEffectiveSourceCount() > Settings.Downloads.SourcesWanted )
	{
		delete pSource;
		return FALSE;	// Too many sources
	}

	// Check/Reject if source is invalid
	if ( ! pSource->m_bPushOnly )
	{
		// Reject invalid IPs (Sometimes ed2k sends invalid 0.x.x.x sources)
		if ( pSource->m_pAddress.S_un.S_un_b.s_b1 == 0 || pSource->m_nPort == 0 )
		{
			delete pSource;
			return FALSE;
		}

		// Reject if source is the local IP/port
		if ( Network.IsSelfIP( pSource->m_pAddress ) )
		{
			if ( Settings.Connection.IgnoreOwnIP ||
				( pSource->m_nServerPort == 0 &&
				Settings.Connection.InPort == pSource->m_nPort ) )
			{
				delete pSource;
				return FALSE;
			}
		}
	}
	else if ( pSource->m_nProtocol == PROTOCOL_ED2K )
	{
		// Reject invalid server IPs (Sometimes ed2k sends invalid 0.x.x.x sources)
		if ( pSource->m_pServerAddress.S_un.S_un_b.s_b1 == 0 )
		{
			delete pSource;
			return FALSE;
		}
	}

	CQuickLock pLock( Transfers.m_pSection );

	if ( pSource->m_nRedirectionCount == 0 )	// Don't check for existing sources if source is a redirection
	{
		bool bDeleteSource = false;
		bool bHTTPSource = pSource->IsHTTPSource();
		bool bNeedHTTPSource = ! bHTTPSource &&
			Settings.Gnutella2.Enabled &&
			VendorCache.IsExtended( pSource->m_sServer );

		// Remove unneeded sources
		for ( POSITION posSource = GetIterator() ; posSource ; )
		{
			CDownloadSource* pExisting = GetNext( posSource );

			ASSERT( pSource != pExisting );
			if ( pExisting->Equals( pSource ) ) 	// IPs and ports are equal
			{
				bool bExistingHTTPSource = pExisting->IsHTTPSource();

				if ( bNeedHTTPSource && bExistingHTTPSource )
					bNeedHTTPSource = false;

				if ( ( pExisting->m_nProtocol == pSource->m_nProtocol ) ||
					 ( bExistingHTTPSource && bHTTPSource ) )
				{
					bDeleteSource = true;			// Same protocol
				}
				else if ( ! pExisting->IsIdle() )
				{
					// Already downloading so we can remove new non-HTTP source
					if ( bExistingHTTPSource && ! bHTTPSource )
						bDeleteSource = true;
				}
				else // We are not downloading
				{
					// ...So we can replace non-HTTP source with a new one
					if ( ! bExistingHTTPSource && bHTTPSource )
					{
						// Set connection delay the same as for the old source
						pSource->m_tAttempt = pExisting->m_tAttempt;
						pExisting->Remove( TRUE, FALSE );
					}
				}
			}
		}

		if ( bDeleteSource )
		{
			delete pSource;

			SetModified();

			return FALSE;
		}

		// Make additional G2 source from the existing non-HTTP PeerProject source
		if ( bNeedHTTPSource )
		{
			CString strURL = GetURL( pSource->m_pAddress, pSource->m_nPort );
			if ( ! strURL.IsEmpty() )
			{
				if ( CDownloadSource* pG2Source = new CDownloadSource( (CDownload*)this, strURL ) )
				{
					pG2Source->m_sServer = pSource->m_sServer;		// Copy user-agent
					pG2Source->m_tAttempt = pSource->m_tAttempt;	// Set the same connection delay
					pG2Source->m_nProtocol = PROTOCOL_HTTP;

					AddSourceInternal( pG2Source );
				}
			}
		}
	}

	InternalAdd( pSource );

	SetModified();

	return TRUE;
}
コード例 #8
0
BOOL CDownloadWithSources::AddSourceURL(LPCTSTR pszURL, BOOL bURN, FILETIME* pLastSeen, int nRedirectionCount, BOOL bFailed)
{
	if ( pszURL == NULL || *pszURL == 0 )
		return FALSE;

	if ( nRedirectionCount > 5 )
		return FALSE;	// No more than 5 redirections

	BOOL bHashAuth = FALSE;
	BOOL bValidated = FALSE;
	CPeerProjectURL pURL;

	if ( *pszURL == '@' )
	{
		bHashAuth = TRUE;
		pszURL++;
	}

	if ( ! pURL.Parse( pszURL ) )
		return FALSE;	// Wrong URL

	if ( pURL.m_nAction == CPeerProjectURL::uriHost &&
		 pURL.m_nProtocol == PROTOCOL_DC )
	{
		// Connect to specified DC++ hub for future searches
		Network.ConnectTo( pURL.m_sName, pURL.m_nPort, PROTOCOL_DC );
		return FALSE;
	}

	if ( pURL.m_nAction != CPeerProjectURL::uriDownload &&
		 pURL.m_nAction != CPeerProjectURL::uriSource )
		return FALSE;	// Wrong URL type

	if ( bURN )
	{
		if ( Network.IsFirewalledAddress( &pURL.m_pAddress, TRUE ) ||
			 Network.IsReserved( &pURL.m_pAddress ) )
			return FALSE;
	}

	CQuickLock pLock( Transfers.m_pSection );

	CFailedSource* pBadSource = LookupFailedSource( pszURL );
	if ( pBadSource )
	{
		// Add a positive vote, add to downloads if negative votes compose less than 2/3 of total.
		int nTotal = pBadSource->m_nPositiveVotes + pBadSource->m_nNegativeVotes + 1;
		if ( bFailed )
			pBadSource->m_nNegativeVotes++;
		else
			pBadSource->m_nPositiveVotes++;

		if ( nTotal > 30 && pBadSource->m_nNegativeVotes / nTotal > 2 / 3 )
			return FALSE;
	}
	else if ( bFailed )
	{
		AddFailedSource( pszURL, false );
		VoteSource( pszURL, false );
		return TRUE;
	}

	// Validate SHA1
	if ( pURL.m_oSHA1 && m_oSHA1 )
	{
		if ( m_oSHA1 != pURL.m_oSHA1 ) return FALSE;
		bValidated = TRUE;
	}
	// Validate Tiger
	if ( pURL.m_oTiger && m_oTiger )
	{
		if ( m_oTiger != pURL.m_oTiger ) return FALSE;
		bValidated = TRUE;
	}
	// Validate ED2K
	if ( pURL.m_oED2K && m_oED2K )
	{
		if ( m_oED2K != pURL.m_oED2K ) return FALSE;
		bValidated = TRUE;
	}
	// Validate MD5
	if ( pURL.m_oMD5 && m_oMD5 )
	{
		if ( m_oMD5 != pURL.m_oMD5 ) return FALSE;
		bValidated = TRUE;
	}
	// Validate BTH
	if ( pURL.m_oBTH && m_oBTH && ! bValidated )
	{
		if ( m_oBTH != pURL.m_oBTH ) return FALSE;
		bValidated = TRUE;
	}
	// Validate size
	if ( m_nSize != SIZE_UNKNOWN && pURL.m_bSize && pURL.m_nSize != SIZE_UNKNOWN )
	{
		if ( m_nSize != pURL.m_nSize ) return FALSE;
	}

	// Get SHA1
	if ( pURL.m_oSHA1 && ! m_oSHA1 )
		m_oSHA1 = pURL.m_oSHA1;

	// Get Tiger
	if ( pURL.m_oTiger && ! m_oTiger )
		m_oTiger = pURL.m_oTiger;

	// Get ED2K
	if ( pURL.m_oED2K && ! m_oED2K )
		m_oED2K = pURL.m_oED2K;

	// Get MD5
	if ( pURL.m_oMD5 && ! m_oMD5 )
		m_oMD5 = pURL.m_oMD5;

	// Get BTH
	if ( pURL.m_oBTH && ! m_oBTH )
		m_oBTH = pURL.m_oBTH;

	// Get size
	if ( m_nSize == SIZE_UNKNOWN &&	pURL.m_bSize && pURL.m_nSize && pURL.m_nSize != SIZE_UNKNOWN )
		m_nSize = pURL.m_nSize;

	// Get name
	if ( m_sName.IsEmpty() && ! pURL.m_sName.IsEmpty() )
		Rename( pURL.m_sName );

	return AddSourceInternal( new CDownloadSource( static_cast< const CDownload* >( this ),
		pszURL, bURN, bHashAuth, pLastSeen, nRedirectionCount ) );
}
コード例 #9
0
BOOL CDownloadWithSources::AddSourceED2K(DWORD nClientID, WORD nClientPort, DWORD nServerIP, WORD nServerPort, const Hashes::Guid& oGUID)
{
	return AddSourceInternal( new CDownloadSource( (CDownload*)this, nClientID, nClientPort, nServerIP, nServerPort, oGUID ) );
}