Skip to content

Commit

Permalink
partial ipv6 support 9
Browse files Browse the repository at this point in the history
  • Loading branch information
ivan386 committed Dec 15, 2017
1 parent ddc4932 commit 10198c3
Show file tree
Hide file tree
Showing 6 changed files with 264 additions and 21 deletions.
8 changes: 7 additions & 1 deletion shareaza/DlgSecureRule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,13 @@ void CSecureRuleDlg::OnSelChangeRuleType()
UpdateData();

ShowGroup( &m_wndGroupNetwork, m_nType == 0 );
ShowGroup( &m_wndGroupContent, m_nType >= 1 );
ShowGroup( &m_wndGroupContent, m_nType == 1 );

if ( m_nType == 2 )
{
m_wndGroupNetwork.ShowWindow( SW_SHOW );
m_wndContent.ShowWindow( SW_SHOW );
}

if ( m_nType == 0 )
{
Expand Down
15 changes: 14 additions & 1 deletion shareaza/HostCache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -510,14 +510,27 @@ CHostCacheHostPtr CHostCacheList::Add(const IN_ADDR* pAddress, WORD nPort, const
return pHost;
}

CHostCacheHostPtr CHostCacheList::AddIPv6(const IN6_ADDR* pAddress, WORD nPort, const IN6_ADDR* /* pFromAddress */, DWORD tSeen, LPCTSTR pszVendor, DWORD nUptime, DWORD nCurrentLeaves, DWORD nLeafLimit, LPCTSTR szAddress)
CHostCacheHostPtr CHostCacheList::AddIPv6(const IN6_ADDR* pAddress, WORD nPort, const IN6_ADDR* pFromAddress, DWORD tSeen, LPCTSTR pszVendor, DWORD nUptime, DWORD nCurrentLeaves, DWORD nLeafLimit, LPCTSTR szAddress)
{
ASSERT( pAddress );

if ( ! nPort )
// Use default port
nPort = protocolPorts[ m_nProtocol ];

// Don't add invalid addresses
// check against IANA Reserved address.
if ( Network.IsReserved( pAddress ) ||
// Don't add own firewalled IPs
Network.IsFirewalledAddress( pAddress, TRUE ) ||
// Check address is valid
( pFromAddress != NULL && ! Network.IsValidAddressFor( pFromAddress, pAddress ) ) ||
// Check security settings, don't add blocked IPs
Security.IsDenied( pAddress ) )
// Bad IP
return NULL;


// Check if we already have the host
CHostCacheHostPtr pHost = Find( pAddress );

Expand Down
92 changes: 84 additions & 8 deletions shareaza/Security.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,11 +104,12 @@ void CSecurity::Add(CSecureRule* pRule)
{
CQuickLock oLock( m_pSection );

pRule->MaskFix();

// If an address rule is added, the mask fix is performed and the miss cache is cleared either in whole or just the relevant address
// erase does support ranges but this should cover auto bans and get reasonable performance without tripping on incorrect masks
if ( pRule->m_nType == CSecureRule::srAddress )
{
pRule->MaskFix();
if ( *(DWORD*)pRule->m_nMask == 0xffffffff )
{
m_Cache.erase( *(DWORD*)pRule->m_nIP );
Expand All @@ -118,8 +119,17 @@ void CSecurity::Add(CSecureRule* pRule)
m_Cache.clear();
}
}

pRule->MaskFix();
else if ( pRule->m_nType == CSecureRule::srAddressIPv6 )
{
if ( pRule->m_nIPv6PrefixLen == 128 )
{
m_CacheIPv6.erase( pRule->m_nIPv6 );
}
else
{
m_CacheIPv6.clear();
}
}

// special treatment for single IP security rules
if ( pRule->m_nType == CSecureRule::srAddress &&
Expand All @@ -138,6 +148,22 @@ void CSecurity::Add(CSecureRule* pRule)
delete pOldRule;
}
}
else if ( pRule->m_nType == CSecureRule::srAddressIPv6 &&
pRule->m_nIPv6PrefixLen == 128 )
{
CAddressIPv6RuleMap::iterator i = m_pIPv6Rules.find( pRule->m_nIPv6 );
if ( i == m_pIPv6Rules.end() )
{
m_pIPv6Rules[ pRule->m_nIPv6 ] = pRule;
}
else if ( (*i).second != pRule )
{
// replace old rule with new one.
CSecureRule* pOldRule = (*i).second;
(*i).second = pRule;
delete pOldRule;
}
}
else // default procedure for everything else
{
CSecureRule* pExistingRule = GetGUID( pRule->m_pGUID );
Expand Down Expand Up @@ -420,13 +446,13 @@ void CSecurity::Ban(const IN6_ADDR* pAddress, int nBanLength, BOOL bMessage, LPC
CQuickLock oLock( m_pSection );

DWORD tNow = static_cast< DWORD >( time( NULL ) );


for ( POSITION pos = m_pRules.GetHeadPosition() ; pos ; )
CAddressIPv6RuleMap::const_iterator i = m_pIPv6Rules.find( *pAddress );
if ( i != m_pIPv6Rules.end() )
{
CSecureRule* pIPRule = m_pRules.GetNext( pos );
CSecureRule* pIPRule = (*i).second;

if ( IN6_ADDR_EQUAL( &pIPRule->m_nIPv6, pAddress ) && pIPRule->m_nAction == CSecureRule::srDeny )
if ( pIPRule->m_nAction == CSecureRule::srDeny )
{
if ( ( nBanLength == banWeek ) && ( pIPRule->m_nExpire < tNow + 604000 ) )
{
Expand Down Expand Up @@ -607,6 +633,37 @@ BOOL CSecurity::IsDenied(const IN6_ADDR* pAddress)

DWORD nNow = static_cast< DWORD >( time( NULL ) );

// First check the fast IP lookup map.
CAddressIPv6RuleMap::const_iterator i = m_pIPv6Rules.find( *pAddress );
if ( i != m_pIPv6Rules.end() )
{
CSecureRule* pIPRule = (*i).second;
if ( pIPRule->IsExpired( nNow ) )
{
m_pIPv6Rules.erase( i );
}
else
{
pIPRule->m_nToday ++;
pIPRule->m_nEver ++;

if ( pIPRule->m_nExpire > CSecureRule::srSession && pIPRule->m_nExpire < nNow + 300 )
// Add 5 min penalty for early access
pIPRule->m_nExpire = nNow + 300;

if ( pIPRule->m_nAction == CSecureRule::srAccept )
return FALSE;
else if ( pIPRule->m_nAction == CSecureRule::srDeny )
return TRUE;
}
}


// Second, check the miss cache if the IP has already been checked and found to be OK.
// if the address is in cache, it is a miss and no lookup is needed
if ( m_CacheIPv6.count( *pAddress ) )
return m_bDenyPolicy;

// Third, check whether the IP is still stored in one of the old rules or the IP range blocking rules.
for ( POSITION pos = GetIterator() ; pos ; )
{
Expand All @@ -633,6 +690,10 @@ BOOL CSecurity::IsDenied(const IN6_ADDR* pAddress)
return TRUE;
}
}

// If the IP is clean, add it to the miss cache
m_CacheIPv6.insert( *pAddress );

return FALSE;
}

Expand Down Expand Up @@ -919,6 +980,11 @@ void CSecurity::Serialize(CArchive& ar)
{
(*i).second->Serialize( ar, nVersion );
}

for ( CAddressIPv6RuleMap::const_iterator i = m_pIPv6Rules.begin(); i != m_pIPv6Rules.end(); ++i )
{
(*i).second->Serialize( ar, nVersion );
}
}
else
{
Expand Down Expand Up @@ -946,6 +1012,11 @@ void CSecurity::Serialize(CArchive& ar)
{
m_pIPRules[ *(DWORD*)pRule->m_nIP ] = pRule;
}
else if( pRule->m_nType == CSecureRule::srAddressIPv6 &&
pRule->m_nIPv6PrefixLen == 128 )
{
m_pIPv6Rules[ pRule->m_nIPv6 ] = pRule;
}
else
{
m_pRules.AddTail( pRule );
Expand Down Expand Up @@ -1276,6 +1347,11 @@ CLiveList* CSecurity::GetList() const
(*i).second->ToList( pLiveList, nCount, tNow );
}

for ( CAddressIPv6RuleMap::const_iterator i = m_pIPv6Rules.begin(); i != m_pIPv6Rules.end(); ++i, ++nCount )
{
(*i).second->ToList( pLiveList, nCount, tNow );
}

return pLiveList;
}

Expand Down
13 changes: 13 additions & 0 deletions shareaza/Security.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,19 @@ class CSecurity
typedef std::map< DWORD, CSecureRule* > CAddressRuleMap;
CAddressRuleMap m_pIPRules;

struct ipv6_compare {
inline bool operator()(const IN6_ADDR& _Left, const IN6_ADDR& _Right) const throw()
{
return ( memcmp( &_Left, &_Right, sizeof( IN6_ADDR ) ) > 0 );
}
};

typedef std::set< IN6_ADDR, ipv6_compare > CAddressIPv6Map;
CAddressIPv6Map m_CacheIPv6; // miss cache

typedef std::map< IN6_ADDR, CSecureRule*, ipv6_compare > CAddressIPv6RuleMap;
CAddressIPv6RuleMap m_pIPv6Rules;

// Operations
public:
POSITION GetIterator() const;
Expand Down
Loading

0 comments on commit 10198c3

Please sign in to comment.