openbsd-ports/net/osrtspproxy/patches/patch-libapp_resolver_cpp
bluhm 54748039df Apply a bunch of patches to get osrtspproxy running. Upstream is
dead, so keep patches locally.  On top of that, fix linker warnings
about unsave string operations.  Take maintainer.
OK ajacoutot@
2015-07-01 11:33:50 +00:00

597 lines
21 KiB
Plaintext

$OpenBSD: patch-libapp_resolver_cpp,v 1.1 2015/07/01 11:33:50 bluhm Exp $
--- libapp/resolver.cpp.orig Tue Feb 13 00:55:08 2001
+++ libapp/resolver.cpp Thu Jan 8 00:10:40 2015
@@ -11,6 +11,7 @@
#include "parser.h"
#include "app.h"
+#include "Avl.h"
#include "dbg.h"
#include <errno.h>
@@ -162,7 +163,7 @@ static char* inet_ntoa_rev( struct in_addr in )
static char host[29]; // aaa.bbb.ccc.ddd.in-addr.arpa\0
BYTE qa[4];
memcpy( qa, &in.s_addr, 4 );
- sprintf( host, "%u.%u.%u.%u.in-addr.arpa", qa[3], qa[2], qa[1], qa[0] );
+ snprintf( host, sizeof(host), "%u.%u.%u.%u.in-addr.arpa", qa[3], qa[2], qa[1], qa[0] );
return host;
}
@@ -196,9 +197,7 @@ CResolver * CResolver::GetResolver( void )
bool CResolver::GetHost( CResolverResponse* pResponse, const CString& strHost )
{
-dbgout( "CResolver::GetHost: query for %s", (CPCHAR)strHost );
- CHostInfo* pInfo;
-
+ dbgout( "CResolver::GetHost: query for %s", (CPCHAR)strHost );
// Determine if this is a number or name
bool bIsNumeric = true;
CPCHAR p = strHost;
@@ -224,16 +223,16 @@ dbgout( "CResolver::GetHost: query for %s", (CPCHAR)st
}
// First search for name as given
- CHostInfo info( strHost );
- pInfo = m_treeHostInfo.Search( info );
- if( pInfo )
+ CHostInfo pInfo = m_treeHostInfo[strHost];
+
+ if( pInfo.m_strName != "" )
{
- if( pInfo->m_tExpire > time(NULL) )
+ if( pInfo.m_tExpire > time(NULL) )
{
- pResponse->GetHostDone( 0, strHost, pInfo->m_addr );
+ pResponse->GetHostDone( 0, strHost, pInfo.m_addr );
return true;
}
- m_treeHostInfo.Delete( info );
+ m_treeHostInfo.erase( strHost );
}
// Not found - if it's unqualified, search the domain list
@@ -254,15 +253,16 @@ dbgout( "CResolver::GetHost: query for %s", (CPCHAR)st
strFQDN.Append( "." );
strFQDN.Append( *itr );
CHostInfo info( strFQDN );
- CHostInfo* pInfo = m_treeHostInfo.Search( info );
- if( pInfo )
+ CHostInfo pInfo = m_treeHostInfo[strFQDN];
+
+ if ( pInfo.m_strName != "" )
{
- if( pInfo->m_tExpire > time(NULL) )
+ if( pInfo.m_tExpire > time(NULL) )
{
- pResponse->GetHostDone( 0, strHost, pInfo->m_addr );
+ pResponse->GetHostDone( 0, strHost, pInfo.m_addr );
return true;
}
- m_treeHostInfo.Delete( info );
+ m_treeHostInfo.erase( strFQDN );
}
itr++;
}
@@ -270,143 +270,162 @@ dbgout( "CResolver::GetHost: query for %s", (CPCHAR)st
// Looks like we have to send a query
CHostQuery query( strHost );
- CHostQuery* pQuery = m_treeHostQueries.Insert( query );
- if( ! pQuery )
+ CHostQuery pQuery = (*m_treeHostQueries.insert( pair<CString,CHostQuery>( strHost,query ) ).first).second;
+
+ if ( pQuery.m_strHost != "" )
{
- pQuery = m_treeHostQueries.Search( query );
- assert( pQuery );
-
- pQuery->m_tExpire = time(NULL) + 4;
- pQuery->m_tDelta = 4;
+ pQuery.m_tExpire = time(NULL) + 4;
+ pQuery.m_tDelta = 4;
if( !strchr( strHost, '.' ) )
{
// Unqualified - search the domain list
CDomainList::Iterator itr( m_listDomains.Begin() );
assert( itr ); // should have caught this already
- pQuery->m_strFQDN = strHost;
- pQuery->m_strFQDN.Append( "." );
- pQuery->m_strFQDN.Append( *itr );
- pQuery->m_itrDomain = itr;
+ pQuery.m_strFQDN = strHost;
+ pQuery.m_strFQDN.Append( "." );
+ pQuery.m_strFQDN.Append( *itr );
+ pQuery.m_itrDomain = itr;
}
- pQuery->m_itrServer = m_listServers.Begin();
+ pQuery.m_itrServer = m_listServers.Begin();
- SendQuery( *pQuery->m_itrServer, pQuery->m_strFQDN, RR_A );
+ SendQuery( *pQuery.m_itrServer, pQuery.m_strFQDN, RR_A );
}
+ pQuery.AddResponse( *pResponse );
- pQuery->AddResponse( pResponse );
+ // Speichern des geaenderten Objekts
+ m_treeHostQueries[strHost] = pQuery;
return true;
}
bool CResolver::GetHost( CResolverResponse* pResponse, struct in_addr addr )
{
-dbgout( "CResolver::GetHost: query for %s", inet_ntoa(addr) );
+ dbgout( "CResolver::GetHost: query for %s", inet_ntoa(addr) );
CAddrInfo info( addr );
// See if we already have it
- CAddrInfo* pInfo = m_treeAddrInfo.Search( info );
- if( pInfo )
+ CAddrInfo pInfo = m_treeAddrInfo[addr];
+
+ if( pInfo.m_addr.s_addr != INADDR_NONE )
{
- if( pInfo->m_tExpire > time(NULL) )
+ if( pInfo.m_tExpire > time(NULL) )
{
- pResponse->GetHostDone( 0, addr, pInfo->m_strName );
+ pResponse->GetHostDone( 0, addr, pInfo.m_strName );
return true;
}
- m_treeAddrInfo.Delete( info );
+ m_treeAddrInfo.erase( addr );
}
// Nope, gotta send a query
CAddrQuery query( addr );
- CAddrQuery* pQuery = m_treeAddrQueries.Insert( query );
- if( ! pQuery )
- {
- pQuery = m_treeAddrQueries.Search( query );
- assert( pQuery );
+ CAddrQuery pQuery = (*(m_treeAddrQueries.insert( pair<in_addr,CAddrQuery>( addr, query ) ).first)).second;
- pQuery->m_tExpire = time(NULL) + 4;
- pQuery->m_tDelta = 4;
- pQuery->m_itrServer = m_listServers.Begin();
- SendQuery( *pQuery->m_itrServer, inet_ntoa_rev(addr), RR_PTR );
+ if ( pQuery.m_addr.s_addr != INADDR_NONE )
+ {
+ pQuery.m_tExpire = time(NULL) + 4;
+ pQuery.m_tDelta = 4;
+ pQuery.m_itrServer = m_listServers.Begin();
+ SendQuery( *pQuery.m_itrServer, inet_ntoa_rev(addr), RR_PTR );
}
+ pQuery.AddResponse( *pResponse );
- pQuery->AddResponse( pResponse );
+ // Speichern des geaenderten Objekts
+ m_treeAddrQueries[addr] = pQuery;
return true;
}
-void CResolver::WalkHostTree( AvlNode<CHostQuery>* pNode )
+void CResolver::IterateHostMap()
{
- if( !pNode ) return;
- WalkHostTree( pNode->Subtree(LEFT) );
- WalkHostTree( pNode->Subtree(RIGHT) );
- CHostQuery& rquery = pNode->Key();
- if( rquery.m_tExpire < time(NULL) )
+ // Empty map
+ if ( m_treeHostQueries.empty() ) return;
+
+ CHostQueryMap::iterator itr = m_treeHostQueries.begin();
+ // Iterate over all hostname queries
+ while ( itr != m_treeHostQueries.end() )
{
- // Timed out, next nameserver
- rquery.m_itrServer++;
- if( rquery.m_itrServer )
- {
- rquery.m_tExpire = time(NULL)+4;
- rquery.m_tDelta = 4;
- SendQuery( *rquery.m_itrServer, rquery.m_strHost, RR_A );
- return;
- }
+ CHostQuery rquery = (*itr).second;
+ if( rquery.m_tExpire < time(NULL) )
+ {
+ dbgout("Nameserver timed out");
+ // Timed out, next nameserver
+ rquery.m_itrServer++;
+ if( rquery.m_itrServer )
+ {
+ rquery.m_tExpire = time(NULL)+4;
+ rquery.m_tDelta = 4;
+ SendQuery( *rquery.m_itrServer, rquery.m_strHost, RR_A );
+ return;
+ }
- // Exhausted server list, so bump the timeout and start over
- rquery.m_tExpire += rquery.m_tDelta;
- rquery.m_tDelta *= 2;
- rquery.m_itrServer = m_listServers.Begin();
- if( rquery.m_tDelta > 30 )
- {
- // Everything timed out - we're all alone, and it's getting dark!
- struct in_addr addr;
- addr.s_addr = INADDR_NONE;
- CResolverResponseList::Iterator itr( rquery.m_listResponses.Begin() );
- while( itr )
- {
- (*itr)->GetHostDone( EAGAIN, rquery.m_strHost, addr );
- itr++;
- }
- m_treeHostQueries.Delete( rquery );
- }
+ dbgout("No more name servers left. Starting over");
+ // Exhausted server list, so bump the timeout and start over
+ rquery.m_tExpire += rquery.m_tDelta;
+ rquery.m_tDelta *= 2;
+ rquery.m_itrServer = m_listServers.Begin();
+ if( rquery.m_tDelta > 30 )
+ {
+ dbgout("Everything timed out!");
+ // Everything timed out - we're all alone, and it's getting dark!
+ struct in_addr addr;
+ addr.s_addr = INADDR_NONE;
+ CResolverResponseList::iterator itr( rquery.m_listResponses.begin() );
+ while( itr != rquery.m_listResponses.end() )
+ {
+ (*itr)->GetHostDone( EAGAIN, rquery.m_strHost, addr );
+ itr++;
+ }
+ m_treeHostQueries.erase( rquery.m_strHost );
+ }
+ }
+ ++itr;
}
}
-void CResolver::WalkAddrTree( AvlNode<CAddrQuery>* pNode )
+void CResolver::IterateAddrMap()
{
- if( !pNode ) return;
- WalkAddrTree( pNode->Subtree(LEFT) );
- WalkAddrTree( pNode->Subtree(RIGHT) );
- CAddrQuery& rquery = pNode->Key();
- if( rquery.m_tExpire < time(NULL) )
+ if ( m_treeAddrQueries.empty() ) return;
+
+ CAddrQueryMap::iterator itr = m_treeAddrQueries.begin();
+
+ // Iterate over all address queries
+ while ( itr != m_treeAddrQueries.end() )
{
- // Timed out, next nameserver
- rquery.m_itrServer++;
- if( rquery.m_itrServer )
- {
- rquery.m_tExpire = time(NULL)+4;
- rquery.m_tDelta = 4;
- SendQuery( *rquery.m_itrServer, inet_ntoa_rev(rquery.m_addr), RR_PTR );
- return;
- }
+ CAddrQuery rquery = (*itr).second;
+ if( rquery.m_tExpire < time(NULL) )
+ {
+ dbgout("Nameserver timed out");
+ // Timed out, next nameserver
+ rquery.m_itrServer++;
+ if( rquery.m_itrServer )
+ {
+ rquery.m_tExpire = time(NULL)+4;
+ rquery.m_tDelta = 4;
+ SendQuery( *rquery.m_itrServer, inet_ntoa_rev(rquery.m_addr), RR_PTR );
+ return;
+ }
- // Exhausted server list, so bump the timeout and start over
- rquery.m_tExpire += rquery.m_tDelta;
- rquery.m_tDelta *= 2;
- rquery.m_itrServer = m_listServers.Begin();
- if( rquery.m_tDelta > 30 )
- {
- // Everything timed out - we're all alone, and it's getting dark!
- CString host;
- CResolverResponseList::Iterator itr( rquery.m_listResponses.Begin() );
- while( itr )
- {
- (*itr)->GetHostDone( EAGAIN, rquery.m_addr, host );
- itr++;
- }
- m_treeAddrQueries.Delete( rquery );
- }
+ dbgout("No more name servers left. Starting over");
+ // Exhausted server list, so bump the timeout and start over
+ rquery.m_tExpire += rquery.m_tDelta;
+ rquery.m_tDelta *= 2;
+ rquery.m_itrServer = m_listServers.Begin();
+ if( rquery.m_tDelta > 30 )
+ {
+ dbgout("Everything timed out!");
+ // Everything timed out - we're all alone, and it's getting dark!
+ CString host;
+ CResolverResponseList::iterator itr( rquery.m_listResponses.begin() );
+ while( itr != rquery.m_listResponses.end() )
+ {
+ (*itr)->GetHostDone( EAGAIN, rquery.m_addr, host );
+ itr++;
+ }
+ m_treeAddrQueries.erase( rquery.m_addr );
+ }
+ }
+ ++itr;
}
}
@@ -415,12 +434,12 @@ void CResolver::OnTimer( void )
dbgout( "CResolver::OnTimer" );
// iterate through queries, remove stale ones and respond fail
- WalkHostTree( m_treeHostQueries.GetRoot() );
- WalkAddrTree( m_treeAddrQueries.GetRoot() );
+ IterateHostMap();
+ IterateAddrMap();
- if( m_treeHostQueries.IsEmpty() && m_treeAddrQueries.IsEmpty() )
+ if ( m_treeHostQueries.empty() && m_treeAddrQueries.empty() )
{
-dbgout( "CResolver::OnTimer: no more queries" );
+ dbgout( "CResolver::OnTimer: no more queries" );
m_sock.Close();
m_timer.Disable();
}
@@ -433,7 +452,7 @@ void CResolver::OnConnectDone( int err )
void CResolver::OnReadReady( void )
{
-dbgout( "CResolver::OnReadReady" );
+ dbgout( "CResolver::OnReadReady" );
CBuffer buf;
buf.SetSize( 513 );
if( !m_sock.Read( &buf ) )
@@ -498,9 +517,9 @@ dbgout( "CResolver::OnReadReady" );
if( qrhdr.qtype == RR_A )
{
// Does not exist - try next domain
- CHostQuery query( qrhdr.strHost );
- CHostQuery* pQuery = m_treeHostQueries.Search( query );
- if( ! pQuery )
+ CHostQuery pQuery = m_treeHostQueries[qrhdr.strHost];
+
+ if( pQuery.m_strHost == "" )
{
dbgout( "CResolver::OnReadReady: received rc=%u for unexpected host '%s'",
rc, (CPCHAR)qrhdr.strHost );
@@ -508,29 +527,32 @@ dbgout( "CResolver::OnReadReady" );
}
// If query was unqualified, bump the domain iterator
- if( pQuery->m_itrDomain ) pQuery->m_itrDomain++;
+ if( pQuery.m_itrDomain ) pQuery.m_itrDomain++;
- if( ! pQuery->m_itrDomain )
+ if( ! pQuery.m_itrDomain )
{
// Exhausted search list
struct in_addr addr;
addr.s_addr = INADDR_NONE;
- CResolverResponseList::Iterator itr( pQuery->m_listResponses.Begin() );
- while( itr )
+ CResolverResponseList::iterator itr( pQuery.m_listResponses.begin() );
+ while( itr != pQuery.m_listResponses.end() )
{
(*itr)->GetHostDone( ENOENT, qrhdr.strHost, addr );
itr++;
}
- m_treeHostQueries.Delete( query );
+ m_treeHostQueries.erase( qrhdr.strHost );
}
else
{
- pQuery->m_strFQDN = pQuery->m_strHost;
- pQuery->m_strFQDN.Append( "." );
- pQuery->m_strFQDN.Append( *pQuery->m_itrDomain );
- pQuery->m_itrDomain++;
+ pQuery.m_strFQDN = pQuery.m_strHost;
+ pQuery.m_strFQDN.Append( "." );
+ pQuery.m_strFQDN.Append( *pQuery.m_itrDomain );
+ pQuery.m_itrDomain++;
//XXX: reset query's server iterator here?
- SendQuery( *pQuery->m_itrServer, pQuery->m_strFQDN, RR_A );
+ SendQuery( *pQuery.m_itrServer, pQuery.m_strFQDN, RR_A );
+
+ // Speichern des geaenderten Objekts
+ m_treeHostQueries[qrhdr.strHost] = pQuery;
}
}
else if( qrhdr.qtype == RR_PTR )
@@ -538,9 +560,9 @@ dbgout( "CResolver::OnReadReady" );
struct in_addr addr;
if( inet_aton_rev( qrhdr.strHost, &addr ) )
{
- CAddrQuery query( addr );
- CAddrQuery* pQuery = m_treeAddrQueries.Search( query );
- if( ! pQuery )
+ CAddrQuery pQuery = m_treeAddrQueries[addr];
+
+ if( pQuery.m_addr.s_addr == INADDR_NONE )
{
dbgout( "CResolver::OnReadReady: received rc=%u for unexpected host '%s'",
rc, (CPCHAR)qrhdr.strHost );
@@ -548,13 +570,13 @@ dbgout( "CResolver::OnReadReady" );
}
CString host;
- CResolverResponseList::Iterator itr( pQuery->m_listResponses.Begin() );
- while( itr )
+ CResolverResponseList::iterator itr( pQuery.m_listResponses.begin() );
+ while( itr != pQuery.m_listResponses.end() )
{
(*itr)->GetHostDone( ENOENT, addr, host );
itr++;
}
- m_treeAddrQueries.Delete( query );
+ m_treeAddrQueries.erase( addr );
}
}
else
@@ -607,9 +629,9 @@ dbgout( "CResolver::OnReadReady" );
// Ignore authority and additional RR's
- if( m_treeHostQueries.IsEmpty() && m_treeAddrQueries.IsEmpty() )
+ if( m_treeHostQueries.empty() && m_treeAddrQueries.empty() )
{
-dbgout( "CResolver::OnReadReady: no more queries" );
+ dbgout( "CResolver::OnReadReady: no more queries" );
m_sock.Close();
m_timer.Disable();
}
@@ -656,7 +678,7 @@ dbgout( "CResolver::SendQuery: host %s", (CPCHAR)strHo
}
if( CTimer::Repeating != m_timer.GetMode() )
{
-dbgout( "CResolver::SendQuery: setting timer" );
+ dbgout( "CResolver::SendQuery: setting timer" );
m_timer.SetRepeating( 2*1000 );
}
@@ -688,59 +710,67 @@ dbgout( "CResolver::SendQuery: setting timer" );
void CResolver::AddHostEntry( time_t tExpire, const CString& strHost, struct in_addr addr )
{
-dbgout( "AddHostEntry: host %s = %s", (CPCHAR)strHost, inet_ntoa(addr) );
- // Add host to our host tree
- m_treeHostInfo.Insert( CHostInfo( tExpire, strHost, addr ) );
+ dbgout( "AddHostEntry: host %s = %s", (CPCHAR)strHost, inet_ntoa(addr) );
+ // Add host to our host map
+ m_treeHostInfo[strHost] = CHostInfo( tExpire, strHost, addr);
- // Add addr to our addr tree
- m_treeAddrInfo.Insert( CAddrInfo( tExpire, addr, strHost ) );
+ // Add addr to our addr map
+ m_treeAddrInfo[addr] = CAddrInfo( tExpire, addr, strHost );
// See if anyone is waiting for this host
CHostQuery queryHost( strHost );
- CHostQuery* pHostQuery = m_treeHostQueries.Search( queryHost );
- if( pHostQuery )
+ CHostQuery pHostQuery;
+
+ CHostQueryMap::iterator hqitr = m_treeHostQueries.find( strHost );
+
+ if ( hqitr != m_treeHostQueries.end() )
{
-dbgout( "\tfound host query in tree, calling responses" );
- CResolverResponseList::Iterator itr( pHostQuery->m_listResponses.Begin() );
- while( itr )
+ pHostQuery = (*hqitr).second;
+ dbgout( "\tfound host query in tree, calling responses" );
+ CResolverResponseList::iterator itr( pHostQuery.m_listResponses.begin() );
+ while( itr != pHostQuery.m_listResponses.end() )
{
+ dbgout("Calling GetHost done for host=%s and address=%s", (CPCHAR) strHost, inet_ntoa(addr));
(*itr)->GetHostDone( 0, strHost, addr );
itr++;
}
- m_treeHostQueries.Delete( queryHost );
+ m_treeHostQueries.erase( strHost );
}
CPCHAR pdot;
if( (pdot = strchr( strHost, '.' )) )
{
// Perhaps someone is waiting on the unqualified name
queryHost.m_strHost.Set( strHost, pdot - (CPCHAR)strHost );
- pHostQuery = m_treeHostQueries.Search( queryHost );
- if( pHostQuery )
+ hqitr = m_treeHostQueries.find( queryHost.m_strHost );
+
+ if ( hqitr != m_treeHostQueries.end() )
{
-dbgout( "\tfound bare host query in tree, calling responses" );
- CResolverResponseList::Iterator itr( pHostQuery->m_listResponses.Begin() );
- while( itr )
+ pHostQuery = (*hqitr).second;
+ dbgout( "\tfound bare host query in tree, calling responses" );
+ CResolverResponseList::iterator itr( pHostQuery.m_listResponses.begin() );
+ while( itr != pHostQuery.m_listResponses.end() )
{
(*itr)->GetHostDone( 0, strHost, addr );
itr++;
}
- m_treeHostQueries.Delete( queryHost );
+ m_treeHostQueries.erase( queryHost.m_strHost );
}
}
// See if anyone is waiting for this addr
- CAddrQuery queryAddr( addr );
- CAddrQuery* pAddrQuery = m_treeAddrQueries.Search( queryAddr );
- if( pAddrQuery )
+ CAddrQueryMap::iterator adritr = m_treeAddrQueries.find( addr );
+
+ if ( adritr != m_treeAddrQueries.end() )
{
-dbgout( "\tfound addr query in tree, calling responses" );
- CResolverResponseList::Iterator itr( pAddrQuery->m_listResponses.Begin() );
- while( itr )
+ CAddrQuery pAddrQuery = (*adritr).second;
+ dbgout( "\tfound addr query in tree, calling responses" );
+ CResolverResponseList::iterator itr( pAddrQuery.m_listResponses.begin() );
+ while( itr != pAddrQuery.m_listResponses.end() )
{
(*itr)->GetHostDone( 0, addr, strHost );
itr++;
}
- m_treeAddrQueries.Delete( queryAddr );
+ m_treeAddrQueries.erase( addr );
}
}
@@ -953,7 +983,7 @@ bool CResolver::EncodeName( CPCHAR szName, PBYTE& rpbu
{
CPCHAR pLabel = szName;
BYTE nLabelLen = 0;
- BYTE nOverLen = min( 64, rlen-1 );
+ BYTE nOverLen = MIN( 64, rlen-1 );
while( *szName && '.' != *szName && nLabelLen < nOverLen )
{
nLabelLen++;
@@ -1012,15 +1042,18 @@ bool CResolver::ParseAnswerHeader( dns_rr_hdr* phdr, c
bool CResolver::DecodeName( PCHAR pname, const CBuffer& buf, size_t& rpos )
{
- CPBYTE pbuf = buf.GetBuffer();
- size_t buflen = buf.GetSize();
+ const CPBYTE pbuf = buf.GetBuffer();
+ const size_t buflen = buf.GetSize();
size_t pos = rpos;
size_t namelen = 0;
+ size_t iteration = 0;
assert( buflen > 0 && buflen <= 512 && pos < buflen );
bool bHasPtr = false;
while( pbuf[pos] )
{
+ if( iteration++ >= buflen ) return false;
+
UINT8 len = pbuf[pos];
if( !(len & 0xC0) )
{
@@ -1041,7 +1074,7 @@ bool CResolver::DecodeName( PCHAR pname, const CBuffer
if( (len & 0xC0) != 0xC0 || pos > buflen-2 ) return false;
pos = (UINT16)(pbuf[pos] & 0x3F)*256 + (UINT16)(pbuf[pos+1]);
if( pos >= buflen-1 ) return false;
- rpos += 2;
+ if( !bHasPtr ) rpos += 2;
bHasPtr = true;
}
}