Hi,

We have a bunch of local patches to keep osrtspproxy running.  I
would like to commit them to OpenBSD.  On top of that I have fixed
linker warnings about unsave string operations.  I have talked to
grunk@, he appreciates to transfer maintainer to me.

Upstream is dead, but even if we decide to delete this beast, it
is better to have those patches in attic.

ok?

bluhm

Index: net/osrtspproxy/Makefile
===================================================================
RCS file: /data/mirror/openbsd/cvs/ports/net/osrtspproxy/Makefile,v
retrieving revision 1.3
diff -u -p -r1.3 Makefile
--- net/osrtspproxy/Makefile    11 Mar 2013 11:35:50 -0000      1.3
+++ net/osrtspproxy/Makefile    7 Jan 2015 22:21:52 -0000
@@ -4,10 +4,11 @@ COMMENT=              RTSP proxy reference implement
 
 DISTNAME=              osrtspproxy_2_0
 PKGNAME=               osrtspproxy-2.0
+REVISION=              1
 CATEGORIES=            net
 HOMEPAGE=              http://www.rtsp.org/
 
-MAINTAINER=            Alexander von Gernler <gr...@pestilenz.org>
+MAINTAINER=            Alexander Bluhm <bl...@openbsd.org>
 
 # Real Networks license, permits modification and distribution
 PERMIT_PACKAGE_CDROM=  Yes
Index: net/osrtspproxy/patches/patch-configure
===================================================================
RCS file: 
/data/mirror/openbsd/cvs/ports/net/osrtspproxy/patches/patch-configure,v
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 patch-configure
--- net/osrtspproxy/patches/patch-configure     10 Jan 2007 10:37:07 -0000      
1.1.1.1
+++ net/osrtspproxy/patches/patch-configure     30 Jun 2015 18:29:34 -0000
@@ -1,15 +1,24 @@
-$OpenBSD: patch-configure,v 1.1.1.1 2007/01/10 10:37:07 grunk Exp $
+$OpenBSD$
 --- configure.orig     Fri Feb  9 07:07:26 2001
-+++ configure  Wed Jan 10 10:56:04 2007
-@@ -135,6 +135,14 @@ case "$UNAME_S" in
++++ configure  Tue Nov 11 19:12:06 2014
+@@ -135,6 +135,23 @@ case "$UNAME_S" in
      ARFLAGS="-rc"
      SYSLIBS="-lnsl -lsocket"
      ;;
 +  OpenBSD)
++    CC=gcc
++    CXX=g++
 +    AR=ar
 +    ARFLAGS="-rc"
-+    CFLAGS="${CFLAGS} -DNDEBUG -D_UNIX"
-+    CXXFLAGS="${CXXFLAGS} -DNDEBUG -D_UNIX"
++    if [ "$DEBUG" -ne 0 ]; then
++      CCDBG="-g -Wall"
++      LDDBG="-g -Wall"
++    else
++      CCDBG="-DNDEBUG"
++      LDDBG=""
++    fi
++    CFLAGS="${CCDBG} ${CFLAGS} -D_UNIX"
++    CXXFLAGS="${CCDBG} ${CXXFLAGS} -D_UNIX"
 +    LD=ld
 +    SYSLIBS="-pthread"
 +    ;;
Index: net/osrtspproxy/patches/patch-libapp_bitset_cpp
===================================================================
RCS file: net/osrtspproxy/patches/patch-libapp_bitset_cpp
diff -N net/osrtspproxy/patches/patch-libapp_bitset_cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ net/osrtspproxy/patches/patch-libapp_bitset_cpp     23 Dec 2014 13:35:08 
-0000
@@ -0,0 +1,11 @@
+$OpenBSD$
+--- libapp/bitset.cpp.orig     Tue Jan 30 22:24:19 2001
++++ libapp/bitset.cpp  Tue Nov 11 19:12:06 2014
+@@ -72,6 +72,7 @@ CBitSet::CBitSet( CPBYTE pbuf, size_t bitlen )
+ CBitSet::~CBitSet( void )
+ {
+     delete[] m_buf;
++    m_buf = NULL;
+ }
+ 
+ CBitSet& CBitSet::operator=( const CBitSet& other )
Index: net/osrtspproxy/patches/patch-libapp_dbg_cpp
===================================================================
RCS file: net/osrtspproxy/patches/patch-libapp_dbg_cpp
diff -N net/osrtspproxy/patches/patch-libapp_dbg_cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ net/osrtspproxy/patches/patch-libapp_dbg_cpp        8 Jan 2015 20:02:26 
-0000
@@ -0,0 +1,328 @@
+$OpenBSD$
+--- libapp/dbg.cpp.orig        Fri Feb  9 07:06:37 2001
++++ libapp/dbg.cpp     Thu Jan  8 21:02:01 2015
+@@ -20,321 +20,14 @@ void dbgout( const char* fmt, ... )
+     char str[4096];
+     va_list v;
+     va_start( v, fmt );
+-    vsprintf( str, fmt, v );
+-    strcat( str, "\n" );
++    vsnprintf( str, sizeof(str), fmt, v );
++    va_end(v);
+ #ifdef _UNIX
+-    fputs( str, stderr );
++    fprintf( stderr, "%s\n", str );
+ #endif
+ #ifdef _WIN32
+     ::OutputDebugString( str );
+ #endif
+-}
+-
+-/*
+- * Heap management using operator new/delete.  These routines use unbalanced
+- * binary trees to keep track of allocations in an attempt to make them fast
+- * yet simple.
+- *
+- * The trees for scalar and vector allocations are completely separate so
+- * that trying to deallocate memory with the wrong version of operator
+- * delete will always fail.
+- *
+- * Global operator new is redefined to pass the file and line where the
+- * allocation occurred to facilitate memory leak debugging.  Unfortunately,
+- * it doesn't seem to be possible to redefine operator delete.
+- *
+- * Each block of memory consists of an alloc_node header, the requested
+- * memory block, and two-byte guards before and after the requested memory
+- * block.  The requested memory block is filled with a semi-random byte
+- * value to ensure that the caller does not rely on any particular initial
+- * bit pattern (eg. a block of zeros or NULLs).  It is refilled with a
+- * (possibly different) byte value after deallocation to ensure that the
+- * caller doesn't attempt to use the freed memory.
+- *
+- * NOTES:
+- * It is perfectly valid to allocate a block of length zero.  The returned
+- * block should have a length of 1.  This simplifies algorithms, especially
+- * those that do vector allocation based on an unsigned input parameter.  It
+- * is also valid to delete a NULL block.  This simplifies object destruction
+- * by alleviating the need for if() guards.  These rules have been around
+- * since C++ was born but most people don't seem to know or care.
+- */
+-
+-struct alloc_node
+-{
+-    alloc_node* lptr;
+-    alloc_node* rptr;
+-    size_t      len;
+-    CPCHAR      file;
+-    UINT        line;
+-};
+-
+-static alloc_node* g_heap = NULL;
+-static alloc_node* g_vector_heap = NULL;
+-
+-// Our magic guard bytes
+-static BYTE g_guard[] =
+-{
+-    0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF,
+-    0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF
+-};
+-
+-void* operator new( size_t n, CPCHAR file, UINT line )
+-{
+-    BYTE* pmem = NULL;
+-    if( !n ) n = 1;
+-    alloc_node* pnode = (alloc_node*)malloc( n + 2*sizeof(g_guard) + 
sizeof(alloc_node) );
+-    if( pnode )
+-    {
+-        pmem = (BYTE*)pnode + sizeof(alloc_node) + sizeof(g_guard);
+-        memcpy( pmem - sizeof(g_guard), g_guard, sizeof(g_guard) );
+-        memset( pmem, time(NULL), n );
+-        memcpy( pmem + n, g_guard, sizeof(g_guard) );
+-
+-        pnode->lptr = pnode->rptr = NULL;
+-        pnode->len = n;
+-        pnode->file = file;
+-        pnode->line = line;
+-        alloc_node** ppuplink = &g_heap;
+-        alloc_node* pcur = g_heap;
+-        while( pcur )
+-        {
+-            if( pnode == pcur )
+-            {
+-                dbgout( "*** FATAL: duplicate memory allocated ***" );
+-                assert( false );
+-                exit( -1 );
+-            }
+-            if( pnode < pcur )
+-            {
+-                ppuplink = &pcur->lptr;
+-                pcur = pcur->lptr;
+-            }
+-            else
+-            {
+-                ppuplink = &pcur->rptr;
+-                pcur = pcur->rptr;
+-            }
+-        }
+-        *ppuplink = pnode;
+-    }
+-
+-    return pmem;
+-}
+-
+-void* operator new[]( size_t n, CPCHAR file, UINT line )
+-{
+-    BYTE* pmem = NULL;
+-    if( !n ) n = 1;
+-    alloc_node* pnode = (alloc_node*)malloc( n + 2*sizeof(g_guard) + 
sizeof(alloc_node) );
+-    if( pnode )
+-    {
+-        pmem = (BYTE*)pnode + sizeof(alloc_node) + sizeof(g_guard);
+-        memcpy( pmem - sizeof(g_guard), g_guard, sizeof(g_guard) );
+-        memset( pmem, time(NULL), n );
+-        memcpy( pmem + n, g_guard, sizeof(g_guard) );
+-
+-        pnode->lptr = pnode->rptr = NULL;
+-        pnode->len = n;
+-        pnode->file = file;
+-        pnode->line = line;
+-        alloc_node** ppuplink = &g_vector_heap;
+-        alloc_node* pcur = g_vector_heap;
+-        while( pcur )
+-        {
+-            if( pnode == pcur )
+-            {
+-                dbgout( "*** FATAL: duplicate memory allocated ***" );
+-                assert( false );
+-                exit( -1 );
+-            }
+-            if( pnode < pcur )
+-            {
+-                ppuplink = &pcur->lptr;
+-                pcur = pcur->lptr;
+-            }
+-            else
+-            {
+-                ppuplink = &pcur->rptr;
+-                pcur = pcur->rptr;
+-            }
+-        }
+-        *ppuplink = pnode;
+-    }
+-
+-    return pmem;
+-}
+-
+-void operator delete( void* p )
+-{
+-    if( !p ) return;
+-    if( !g_heap )
+-    {
+-        dbgout( "*** FATAL: delete with empty heap ***" );
+-        assert( false );
+-        exit( -1 );
+-    }
+-
+-    alloc_node* pcur = g_heap;
+-    alloc_node** ppuplink = &g_heap;
+-    while( pcur )
+-    {
+-        void* pcurblk = (char*)pcur + sizeof(alloc_node) + sizeof(g_guard);
+-        if( p == pcurblk )
+-        {
+-            BYTE* pmem = (BYTE*)p;
+-            if( memcmp( pmem - sizeof(g_guard), g_guard, sizeof(g_guard) ) != 
0 ||
+-                memcmp( pmem + pcur->len, g_guard, sizeof(g_guard) ) != 0 )
+-            {
+-                dbgout( "*** FATAL: corrupted memory at %08X", p );
+-                assert( false );
+-                exit( -1 );
+-            }
+-            memset( pmem, time(NULL), pcur->len );
+-            if( pcur->lptr && pcur->rptr )
+-            {
+-                // node has both ptrs so replace it with left child and move
+-                // right child to bottom right of left child's tree
+-                alloc_node* pend = pcur->lptr;
+-                while( pend->rptr ) pend = pend->rptr;
+-                *ppuplink = pcur->lptr;
+-                pend->rptr = pcur->rptr;
+-            }
+-            else
+-            {
+-                // move child up
+-                *ppuplink = (pcur->lptr) ? pcur->lptr : pcur->rptr;
+-            }
+-            free( pcur );
+-            return;
+-        }
+-        if( p < pcurblk )
+-        {
+-            ppuplink = &pcur->lptr;
+-            pcur = pcur->lptr;
+-        }
+-        else
+-        {
+-            ppuplink = &pcur->rptr;
+-            pcur = pcur->rptr;
+-        }
+-    }
+-
+-    dbgout( "*** FATAL: delete on unalloced memory ***" );
+-    assert( false );
+-    exit( -1 );
+-}
+-
+-void operator delete[]( void* p )
+-{
+-    if( !p ) return;
+-    if( !g_vector_heap )
+-    {
+-        dbgout( "*** FATAL: delete with empty heap ***" );
+-        assert( false );
+-        exit( -1 );
+-    }
+-
+-    alloc_node* pcur = g_vector_heap;
+-    alloc_node** ppuplink = &g_vector_heap;
+-    while( pcur )
+-    {
+-        void* pcurblk = (char*)pcur + sizeof(alloc_node) + sizeof(g_guard);
+-        if( p == pcurblk )
+-        {
+-            BYTE* pmem = (BYTE*)p;
+-            if( memcmp( pmem - sizeof(g_guard), g_guard, sizeof(g_guard) ) != 
0 ||
+-                memcmp( pmem + pcur->len, g_guard, sizeof(g_guard) ) != 0 )
+-            {
+-                dbgout( "*** FATAL: corrupted memory at %08X", p );
+-                assert( false );
+-                exit( -1 );
+-            }
+-            memset( pmem, time(NULL), pcur->len );
+-            if( pcur->lptr && pcur->rptr )
+-            {
+-                // node has both ptrs so replace it with left child and move
+-                // right child to bottom right of left child's tree
+-                alloc_node* pend = pcur->lptr;
+-                while( pend->rptr ) pend = pend->rptr;
+-                *ppuplink = pcur->lptr;
+-                pend->rptr = pcur->rptr;
+-            }
+-            else
+-            {
+-                // move child up
+-                *ppuplink = (pcur->lptr) ? pcur->lptr : pcur->rptr;
+-            }
+-            free( pcur );
+-            return;
+-        }
+-        if( p < pcurblk )
+-        {
+-            ppuplink = &pcur->lptr;
+-            pcur = pcur->lptr;
+-        }
+-        else
+-        {
+-            ppuplink = &pcur->rptr;
+-            pcur = pcur->rptr;
+-        }
+-    }
+-
+-    dbgout( "*** FATAL: delete on unalloced memory ***" );
+-    assert( false );
+-    exit( -1 );
+-}
+-
+-void* operator new( size_t n )
+-{
+-    return ::operator new( n, "(unknown)", 0 );
+-}
+-
+-void* operator new[]( size_t n )
+-{
+-    return ::operator new[]( n, "(unknown)", 0 );
+-}
+-
+-static void walk_alloc_tree( alloc_node* pcur, size_t* pttl )
+-{
+-    if( pcur )
+-    {
+-        walk_alloc_tree( pcur->lptr, pttl );
+-        dbgout( "%s(%u): %u bytes at %08X", pcur->file, pcur->line,
+-                pcur->len, (char*)pcur + sizeof(alloc_node) );
+-        *pttl += pcur->len;
+-        walk_alloc_tree( pcur->rptr, pttl );
+-    }
+-}
+-
+-void dump_alloc_heaps( void )
+-{
+-    if( g_heap || g_vector_heap )
+-    {
+-        size_t ttl = 0;
+-        dbgout( "Memory leaks detected" );
+-        dbgout( "=====================" );
+-        dbgout( "" );
+-
+-        if( g_heap )
+-        {
+-            dbgout( "Scalar objects" );
+-            dbgout( "--------------" );
+-            walk_alloc_tree( g_heap, &ttl );
+-            dbgout( "" );
+-        }
+-        if( g_vector_heap )
+-        {
+-            dbgout( "Vector objects" );
+-            dbgout( "--------------" );
+-            walk_alloc_tree( g_vector_heap, &ttl );
+-            dbgout( "" );
+-        }
+-
+-        dbgout( "=====================" );
+-        dbgout( "Total bytes: %u", ttl );
+-        dbgout( "=====================" );
+-    }
+ }
+ 
+ #endif
Index: net/osrtspproxy/patches/patch-libapp_dbg_h
===================================================================
RCS file: net/osrtspproxy/patches/patch-libapp_dbg_h
diff -N net/osrtspproxy/patches/patch-libapp_dbg_h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ net/osrtspproxy/patches/patch-libapp_dbg_h  23 Dec 2014 13:35:08 -0000
@@ -0,0 +1,23 @@
+$OpenBSD$
+--- libapp/dbg.h.orig  Tue Jan 30 22:24:19 2001
++++ libapp/dbg.h       Tue Nov 11 19:12:06 2014
+@@ -16,18 +16,10 @@
+ 
+ #ifdef NDEBUG
+ inline void dbgout( const char* fmt, ... ) {}
+-inline void dump_alloc_heaps( void ) {}
+ #else
+ void dbgout( const char* fmt, ... );
+-void* operator new( size_t n, CPCHAR file, UINT line );
+-void* operator new[]( size_t n, CPCHAR file, UINT line );
+-void  operator delete( void* p );
+-void  operator delete[]( void* p );
+-void* operator new( size_t n );
+-void* operator new[]( size_t n );
+-#define new new(__FILE__,__LINE__)
+-void dump_alloc_heaps( void );
+ #endif
++inline void dump_alloc_heaps( void ) {}
+ 
+ #define assert_or_ret(cond) { assert(cond); if( !(cond) ) return; }
+ #define assert_or_retv(val,cond) { assert(cond); if( !(cond) ) return (val); }
Index: net/osrtspproxy/patches/patch-libapp_resolver_cpp
===================================================================
RCS file: net/osrtspproxy/patches/patch-libapp_resolver_cpp
diff -N net/osrtspproxy/patches/patch-libapp_resolver_cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ net/osrtspproxy/patches/patch-libapp_resolver_cpp   7 Jan 2015 23:10:52 
-0000
@@ -0,0 +1,596 @@
+$OpenBSD$
+--- 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;
+         }
+     }
Index: net/osrtspproxy/patches/patch-libapp_resolver_h
===================================================================
RCS file: net/osrtspproxy/patches/patch-libapp_resolver_h
diff -N net/osrtspproxy/patches/patch-libapp_resolver_h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ net/osrtspproxy/patches/patch-libapp_resolver_h     23 Dec 2014 13:35:08 
-0000
@@ -0,0 +1,282 @@
+$OpenBSD$
+--- libapp/resolver.h.orig     Thu Feb  8 00:45:57 2001
++++ libapp/resolver.h  Tue Nov 11 19:12:07 2014
+@@ -11,13 +11,16 @@
+ #define _RESOLVER_H
+ 
+ #include "types.h"
+-#include "ttree.h"
++#include <map>
++#include <list>
+ #include "str.h"
+ #include "sock.h"
+ #include "timer.h"
+ 
+ #include <string.h>
+ 
++using namespace std;
++
+ /*
+  * Locations found in the WinNT registry:
+  *  \\HKLM\System\CurrentControlSet\Services\Tcpip\Parameters\
+@@ -33,6 +36,8 @@
+ class CResolverResponse
+ {
+ public:
++    // XXX Leere Funktionen, da mit abstrakten Funktionen der Einsatz von
++    // list nicht moeglich ist
+     virtual void GetHostDone( int err, const CString& strQuery, in_addr 
addrResult ) = 0;
+     virtual void GetHostDone( int err, in_addr addrQuery, const CString& 
strResult ) = 0;
+ };
+@@ -96,7 +101,9 @@ class CResolver : public CTimerResponse, (protected)
+     bool DecodeName( PCHAR pname, const CBuffer& rbuf, size_t& rpos );
+ 
+ protected:
+-    typedef TSingleList<CResolverResponse*> CResolverResponseList;
++    // XXX typedef TSingleList<CResolverResponse*> CResolverResponseList;
++    typedef list<CResolverResponse*> CResolverResponseList;
++    // TODO Eventuell hier auch die STL-Liste benutzen?
+     typedef TSingleList<CSockAddr> CNameserverList;
+     typedef TSingleList<CString> CDomainList;
+ 
+@@ -107,6 +114,12 @@ class CResolver : public CTimerResponse, (protected)
+             m_tExpire(0), m_strName(strName) { m_addr.s_addr = INADDR_NONE; }
+         CHostInfo( time_t tExpire, const CString& strName, struct in_addr 
addr ) :
+             m_tExpire(tExpire), m_strName(strName), m_addr(addr) {}
++      CHostInfo() 
++      {
++          m_tExpire = 0;
++          m_strName = CString();
++          m_addr.s_addr = INADDR_NONE;
++      }
+ 
+         CHostInfo& operator=( const CHostInfo& other )
+         {
+@@ -123,8 +136,18 @@ class CResolver : public CTimerResponse, (protected)
+         CString         m_strName;
+         struct in_addr  m_addr;
+     };
+-    typedef AvlTree<CHostInfo> CHostInfoTree;
+ 
++    // Vergleichsoperator
++    struct HostCompare
++    {
++      bool operator()(const CString h1, const CString h2) const
++      {
++          return h1 < h2;
++      }
++    };
++    
++    typedef map<const CString, CHostInfo, HostCompare> CHostInfoMap;
++
+     class CAddrInfo
+     {
+     public:
+@@ -133,6 +156,12 @@ class CResolver : public CTimerResponse, (protected)
+             m_tExpire(0), m_addr(addr) {}
+         CAddrInfo( time_t tExpire, struct in_addr addr, const CString& 
strName ) :
+             m_tExpire(tExpire), m_addr(addr), m_strName(strName) {}
++      CAddrInfo() 
++      {
++          m_tExpire = 0;
++          m_addr.s_addr = INADDR_NONE;
++          m_strName = CString();
++      }
+ 
+         CAddrInfo& operator=( const CAddrInfo& other )
+         {
+@@ -149,16 +178,39 @@ class CResolver : public CTimerResponse, (protected)
+         struct in_addr  m_addr;
+         CString         m_strName;
+     };
+-    typedef AvlTree<CAddrInfo> CAddrInfoTree;
+ 
++    struct AddrCompare
++    {
++      bool operator()(const struct in_addr a1, const struct in_addr a2) const
++      {
++          return a1.s_addr < a2.s_addr;
++      }
++    };
++    
++    typedef map<const struct in_addr, CAddrInfo, AddrCompare> CAddrInfoMap;
++
+     class CHostQuery
+     {
+     public:
+         CHostQuery(const CString& strHost) :
+             m_tExpire(0), m_tDelta(4), m_strHost(strHost), m_strFQDN(strHost) 
{}
+-        void AddResponse( CResolverResponse* pResponse )
+-            { m_listResponses.InsertTail( pResponse ); }
++      CHostQuery() 
++      {
++          m_tExpire           = 0;
++          m_tDelta            = 0;
++          m_strHost           = CString();
++          m_strFQDN           = CString();
++          m_itrDomain         = CDomainList::Iterator();
++          m_itrServer         = CNameserverList::Iterator();
++          m_listResponses     = CResolverResponseList();
++      }
+ 
++        void AddResponse( CResolverResponse& pResponse )
++            { 
++              // XXX m_listResponses.InsertTail( pResponse ); 
++              m_listResponses.push_back( &pResponse );
++          }
++
+         //XXX: this is soooooo lame
+         CHostQuery( const CHostQuery& other )
+         {
+@@ -168,28 +220,36 @@ class CResolver : public CTimerResponse, (protected)
+             m_strFQDN = other.m_strFQDN;
+             m_itrDomain = other.m_itrDomain;
+             m_itrServer = other.m_itrServer;
++          m_listResponses = other.m_listResponses;
++          // XXX
++          /*
+             CResolverResponseList::ConstIterator itr( 
other.m_listResponses.Begin() );
+             while( itr )
+             {
+                 m_listResponses.InsertTail( *itr );
+                 itr++;
+             }
++          */
+         }
+         CHostQuery& operator=( const CHostQuery& other )
+         {
+-            while( ! m_listResponses.IsEmpty() ) m_listResponses.RemoveHead();
++            while( ! m_listResponses.empty() ) m_listResponses.pop_front();
+             m_tExpire = other.m_tExpire;
+             m_tDelta = other.m_tDelta;
+             m_strHost = other.m_strHost;
+             m_strFQDN = other.m_strFQDN;
+             m_itrDomain = other.m_itrDomain;
+             m_itrServer = other.m_itrServer;
++          m_listResponses = other.m_listResponses;
++          // XXX
++          /*
+             CResolverResponseList::ConstIterator itr( 
other.m_listResponses.Begin() );
+             while( itr )
+             {
+                 m_listResponses.InsertTail( *itr );
+                 itr++;
+             }
++          */
+             return *this;
+         }
+         int operator==( const CHostQuery& other ) const { return ( 
strcasecmp( m_strHost, other.m_strHost ) == 0 ); }
+@@ -204,15 +264,33 @@ class CResolver : public CTimerResponse, (protected)
+         CNameserverList::Iterator   m_itrServer;
+         CResolverResponseList       m_listResponses;
+     };
+-    typedef AvlTree<CHostQuery> CHostQueryTree;
+ 
++    struct HostQueryCompare
++    {
++      bool operator()(const CString& h1, const CString& h2) const
++      {
++          return h1 < h2;
++      }
++    };
++    
++    typedef map<const CString, CHostQuery, HostQueryCompare> CHostQueryMap;
++
+     class CAddrQuery
+     {
+     public:
+         CAddrQuery( struct in_addr addr ) :
+             m_tExpire(0), m_tDelta(4), m_addr(addr) {}
+-        void AddResponse( CResolverResponse* pResponse )
+-            { m_listResponses.InsertTail( pResponse ); }
++      CAddrQuery() 
++      {
++          m_tExpire           = 0;
++          m_tDelta            = 0;
++          m_addr.s_addr       = INADDR_NONE;
++          m_itrServer         = CNameserverList::Iterator();
++          m_listResponses     = CResolverResponseList();
++      }
++      
++        void AddResponse( CResolverResponse& pResponse )
++            { m_listResponses.push_back( &pResponse ); }
+ 
+         //XXX: this is soooooo lame
+         CAddrQuery( const CAddrQuery& other )
+@@ -221,27 +299,35 @@ class CResolver : public CTimerResponse, (protected)
+             m_tDelta = other.m_tDelta;
+             m_addr = other.m_addr;
+             m_itrServer = other.m_itrServer;
++          m_listResponses = other.m_listResponses;
++          // XXX
++          /* 
+             CResolverResponseList::ConstIterator itr( 
other.m_listResponses.Begin() );
+             while( itr )
+             {
+                 m_listResponses.InsertTail( *itr );
+                 itr++;
+             }
++          */
+             m_addr = other.m_addr;
+         }
+         CAddrQuery& operator=( const CAddrQuery& other )
+         {
+-            while( ! m_listResponses.IsEmpty() ) m_listResponses.RemoveHead();
++            while( ! m_listResponses.empty() ) m_listResponses.pop_front();
+             m_tExpire = other.m_tExpire;
+             m_tDelta = other.m_tDelta;
+             m_addr = other.m_addr;
+             m_itrServer = other.m_itrServer;
++          m_listResponses = other.m_listResponses;
++          // XXX
++          /*
+             CResolverResponseList::ConstIterator itr( 
other.m_listResponses.Begin() );
+             while( itr )
+             {
+                 m_listResponses.InsertTail( *itr );
+                 itr++;
+             }
++          */
+             return *this;
+         }
+         int operator==( const CAddrQuery& other ) const { return ( 
m_addr.s_addr == other.m_addr.s_addr ); }
+@@ -254,11 +340,20 @@ class CResolver : public CTimerResponse, (protected)
+         CNameserverList::Iterator   m_itrServer;
+         CResolverResponseList       m_listResponses;
+     };
+-    typedef AvlTree<CAddrQuery> CAddrQueryTree;
+ 
+-    void WalkHostTree( AvlNode<CHostQuery>* pNode );
+-    void WalkAddrTree( AvlNode<CAddrQuery>* pNode );
++    struct AddrQueryCompare
++    {
++      bool operator()(const struct in_addr a1, const struct in_addr a2) const
++      {
++          return a1.s_addr < a2.s_addr;
++      }
++    };
++    
++    typedef map<const struct in_addr, CAddrQuery, AddrQueryCompare> 
CAddrQueryMap;
+ 
++    void IterateHostMap();
++    void IterateAddrMap();
++
+ protected:
+     CUdpSocket      m_sock;
+     CTimer          m_timer;
+@@ -266,11 +361,11 @@ class CResolver : public CTimerResponse, (protected)
+     CNameserverList m_listServers;
+     CDomainList     m_listDomains;
+ 
+-    CHostInfoTree   m_treeHostInfo;
+-    CAddrInfoTree   m_treeAddrInfo;
++    CHostInfoMap   m_treeHostInfo;
++    CAddrInfoMap   m_treeAddrInfo;
+ 
+-    CHostQueryTree  m_treeHostQueries;
+-    CAddrQueryTree  m_treeAddrQueries;
++    CHostQueryMap  m_treeHostQueries;
++    CAddrQueryMap  m_treeAddrQueries;
+ 
+     static CResolver * m_pResolver;
+ };
Index: net/osrtspproxy/patches/patch-libapp_sock_cpp
===================================================================
RCS file: net/osrtspproxy/patches/patch-libapp_sock_cpp
diff -N net/osrtspproxy/patches/patch-libapp_sock_cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ net/osrtspproxy/patches/patch-libapp_sock_cpp       7 Jan 2015 23:07:24 
-0000
@@ -0,0 +1,116 @@
+$OpenBSD$
+--- libapp/sock.cpp.orig       Thu Feb  8 00:45:57 2001
++++ libapp/sock.cpp    Tue Nov 11 20:08:05 2014
+@@ -48,9 +48,9 @@ int inet_aton( const char* cp, struct in_addr* inp )
+ static void socket_nonblock( sockobj_t sock )
+ {
+     int tmp;
+-    fcntl( sock, F_GETFL, &tmp );
++    tmp = fcntl( sock, F_GETFL);
+     tmp |= O_NONBLOCK;
+-    fcntl( sock, F_SETFL, &tmp );
++    fcntl( sock, F_SETFL, tmp );
+ }
+ #endif
+ #if defined(_WIN32)
+@@ -75,6 +75,7 @@ static void socket_reuseaddr( sockobj_t sock )
+ 
+ CInetAddr::CInetAddr( void )
+ {
++    memset(&m_addr, 0, sizeof(m_addr));
+     m_addr.sin_family = AF_INET;
+     m_addr.sin_addr.s_addr = INADDR_NONE;
+     m_addr.sin_port = 0;
+@@ -82,6 +83,7 @@ CInetAddr::CInetAddr( void )
+ 
+ CInetAddr::CInetAddr( const in_addr& host )
+ {
++    memset(&m_addr, 0, sizeof(m_addr));
+     m_addr.sin_family = AF_INET;
+     m_addr.sin_addr = host;
+     m_addr.sin_port = 0;
+@@ -319,18 +321,74 @@ size_t CSocket::Write( CPVOID pbuf, size_t nLen )
+ {
+     assert_or_retv( 0, (pbuf != NULL && IsOpen()) );
+ 
+-    m_err = SOCKERR_NONE;
+-    ssize_t n = send( m_sock, (const char*)pbuf, nLen, 0 );
+-    if( n == SOCKET_ERROR )
++    fd_set writefds;
++    FD_ZERO(&writefds);
++    FD_SET(m_sock,&writefds);
++
++    int retries = 3;
++    int readyfds = 0;
++    int offset = 0;
++    int len = nLen;
++    ssize_t n = 0;
++    timeval timer;
++    timer.tv_sec = 1;
++    timer.tv_usec = 0;
++      
++    // XXX Fix for the problem with incomplete writes to socket
++    while( FD_ISSET(m_sock,&writefds) && len > 0 ) 
+     {
+-        n = 0;
+-        m_err = SOCK_LAST_ERROR();
+-        if( m_err != SOCKERR_WOULDBLOCK )
+-        {
+-            n = SOCKERR_EOF;
+-        }
+-    }
++      readyfds = select(m_sock+1, NULL, &writefds, NULL, &timer);
++      // Fehler
++      if ( readyfds < 0 ) 
++      {
++          if ( errno != EINTR ) 
++          {
++              dbgout("Problem while writing data to socket: %s", 
strerror(errno));
++              return 0;
++          }
++      }
++      // Kein Socket bereit
++      if ( readyfds == 0 ) 
++      {
++          if ( !FD_ISSET(m_sock, &writefds) ) 
++              retries--;
++          if ( !retries ) 
++          {
++              dbgout("Timeout while writing to socket");
++              return 0;
++          }
++      } 
++      // Socket bereit, nun wird geschrieben
++      else 
++      {
++          m_err = 0;
++          n = send( m_sock, (const char*)pbuf+offset, len, 0 );
+ 
++          // Fehler?
++          if( n == -1 )
++          {
++              //XXX DEBUG
++              dbgout("CSocket::Write: Error %s (%i) occured", 
strerror(errno), errno);
++              n = 0;
++              m_err = errno;
++              if( m_err != EAGAIN )
++              {
++                  n = SOCKERR_EOF;
++              }
++              break;
++          }
++          // Daten nicht komplett geschrieben
++          else if ( n < len )
++          {
++              len = len - n;
++              offset += n;
++          }
++          // Daten komplett, dann raus aus der Schleife
++          else {
++              break;
++          }
++      }
++    } 
+     return n;
+ }
+ 
Index: net/osrtspproxy/patches/patch-libapp_str_cpp
===================================================================
RCS file: net/osrtspproxy/patches/patch-libapp_str_cpp
diff -N net/osrtspproxy/patches/patch-libapp_str_cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ net/osrtspproxy/patches/patch-libapp_str_cpp        30 Jun 2015 18:23:24 
-0000
@@ -0,0 +1,85 @@
+$OpenBSD$
+--- libapp/str.cpp.orig        Tue Jan 30 22:24:19 2001
++++ libapp/str.cpp     Thu Jan  8 20:42:59 2015
+@@ -63,6 +63,7 @@ CBuffer::~CBuffer( void )
+ {
+     if( m_buf ) memset( m_buf, 0xDD, m_nAlloc );
+     delete[] m_buf;
++    m_buf = NULL;
+ }
+ 
+ CBuffer& CBuffer::operator=( const CBuffer& other )
+@@ -187,14 +188,18 @@ CString::CString( void )
+ CString::CString( const CString& other )
+ {
+     assert( other.m_sz );
+-    m_sz = new char[ strlen(other.m_sz) + 1 ];
+-    strcpy( m_sz, other.m_sz );
++    size_t len = strlen(other.m_sz);
++    m_sz = new char[ len + 1 ];
++    memcpy( m_sz, other.m_sz, len );
++    m_sz[len] = '\0';
+ }
+ 
+ CString::CString( CPCHAR sz )
+ {
+-    m_sz = new char[ strlen(sz) + 1 ];
+-    strcpy( m_sz, sz );
++    size_t len = strlen(sz);
++    m_sz = new char[ len + 1 ];
++    memcpy( m_sz, sz, len );
++    m_sz[len] = '\0';
+ }
+ 
+ CString::CString( CPCHAR buf, size_t len )
+@@ -215,14 +220,17 @@ CString::~CString( void )
+ {
+     if( m_sz ) memset( m_sz, 0xDD, strlen(m_sz)+1 );
+     delete[] m_sz;
++    m_sz = NULL;
+ }
+ 
+ CString& CString::operator=( const CString& other )
+ {
+     assert( other.m_sz );
+     delete[] m_sz;
+-    m_sz = new char[ strlen(other.m_sz) + 1 ];
+-    strcpy( m_sz, other.m_sz );
++    size_t len = strlen(other.m_sz);
++    m_sz = new char[ len + 1 ];
++    memcpy( m_sz, other.m_sz, len );
++    m_sz[len] = '\0';
+ 
+     return *this;
+ }
+@@ -230,10 +238,11 @@ CString& CString::operator=( const CString& other )
+ CString& CString::operator=( CPCHAR sz )
+ {
+     assert( sz );
+-
+     delete[] m_sz;
+-    m_sz = new char[ strlen(sz) + 1 ];
+-    strcpy( m_sz, sz );
++    size_t len = strlen(sz);
++    m_sz = new char[ len + 1 ];
++    memcpy( m_sz, sz, len );
++    m_sz[len] = '\0';
+ 
+     return *this;
+ }
+@@ -306,9 +315,12 @@ void CString::Append( CPCHAR sz )
+ 
+     if( *sz )
+     {
+-        PCHAR sznew = new char[ strlen(m_sz) + strlen(sz) + 1 ];
+-        strcpy( sznew, m_sz );
+-        strcat( sznew, sz );
++        size_t ml = strlen(m_sz);
++        size_t l = strlen(sz);
++        PCHAR sznew = new char[ ml + l + 1 ];
++        memcpy( sznew, m_sz, ml );
++        memcpy( sznew + ml, sz, l );
++        sznew[ ml + l ] = '\0';
+         delete[] m_sz;
+         m_sz = sznew;
+     }
Index: net/osrtspproxy/patches/patch-libapp_stream_h
===================================================================
RCS file: net/osrtspproxy/patches/patch-libapp_stream_h
diff -N net/osrtspproxy/patches/patch-libapp_stream_h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ net/osrtspproxy/patches/patch-libapp_stream_h       23 Dec 2014 13:35:08 
-0000
@@ -0,0 +1,27 @@
+$OpenBSD$
+--- libapp/stream.h.orig       Tue Jan 30 22:24:19 2001
++++ libapp/stream.h    Tue Nov 11 19:12:07 2014
+@@ -13,6 +13,7 @@
+ #include "types.h"
+ #include "str.h"
+ #include "tlist.h"
++#include <list>
+ 
+ #ifdef _UNIX
+     // some custom bits (we rely on pollfd events being a 16-bit type)
+@@ -53,6 +54,7 @@ class CStreamResponse (public)
+     virtual void OnWriteReady ( void ) = 0;
+     virtual void OnExceptReady( void ) = 0;
+     virtual void OnClosed     ( void ) = 0;
++    virtual ~CStreamResponse ( void ) { };
+ };
+ 
+ class CStream
+@@ -83,6 +85,6 @@ class CStream (protected)
+ protected:
+     CStreamResponse* m_pResponse;
+ };
+-typedef TDoubleList<CStream*> CStreamList;
++typedef std::list<CStream> CStreamList;
+ 
+ #endif //ndef _STREAM_H
Index: net/osrtspproxy/patches/patch-libapp_thread_cpp
===================================================================
RCS file: net/osrtspproxy/patches/patch-libapp_thread_cpp
diff -N net/osrtspproxy/patches/patch-libapp_thread_cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ net/osrtspproxy/patches/patch-libapp_thread_cpp     7 Jan 2015 23:10:55 
-0000
@@ -0,0 +1,13 @@
+$OpenBSD$
+--- libapp/thread.cpp.orig     Wed Feb 14 03:03:11 2001
++++ libapp/thread.cpp  Thu Jan  8 00:10:40 2015
+@@ -254,6 +254,9 @@ CEventThread::~CEventThread( void )
+     delete[] m_ppTimers;
+     delete[] m_pWaitObjs;
+     delete[] m_ppSocks;
++    m_ppSocks = NULL;
++    m_pWaitObjs = NULL;
++    m_ppTimers = NULL;
+ }
+ 
+ void CEventThread::Run( void )
Index: net/osrtspproxy/patches/patch-libapp_timer_h
===================================================================
RCS file: net/osrtspproxy/patches/patch-libapp_timer_h
diff -N net/osrtspproxy/patches/patch-libapp_timer_h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ net/osrtspproxy/patches/patch-libapp_timer_h        23 Dec 2014 13:35:08 
-0000
@@ -0,0 +1,19 @@
+$OpenBSD$
+--- libapp/timer.h.orig        Tue Jan 30 22:24:19 2001
++++ libapp/timer.h     Tue Nov 11 19:12:07 2014
+@@ -12,6 +12,7 @@
+ 
+ #include "types.h"
+ #include "tlist.h"
++#include <list>
+ 
+ class CTimerResponse
+ {
+@@ -50,6 +51,6 @@ class CTimer (private)
+     UINT32          m_interval;
+ };
+ 
+-typedef TDoubleList<CTimer*> CTimerList;
++typedef std::list<CTimer> CTimerList;
+ 
+ #endif //ndef _TIMER_H
Index: net/osrtspproxy/patches/patch-librtsp_rtspprot_cpp
===================================================================
RCS file: net/osrtspproxy/patches/patch-librtsp_rtspprot_cpp
diff -N net/osrtspproxy/patches/patch-librtsp_rtspprot_cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ net/osrtspproxy/patches/patch-librtsp_rtspprot_cpp  23 Dec 2014 13:35:08 
-0000
@@ -0,0 +1,200 @@
+$OpenBSD$
+--- librtsp/rtspprot.cpp.orig  Tue Feb  6 20:20:12 2001
++++ librtsp/rtspprot.cpp       Tue Nov 11 19:12:07 2014
+@@ -15,6 +15,14 @@
+ #include "app.h"
+ #include "rtspprot.h"
+ 
++#ifndef min
++#define min(a,b) ( ((a)<(b)) ? (a) : (b) )
++#endif
++#ifndef max
++#define max(a,b) ( ((a)>(b)) ? (a) : (b) )
++#endif
++
++#include "Avl.h"
+ #include "dbg.h"
+ 
+ /**************************************
+@@ -45,6 +53,7 @@ CRtspInterleavedSocket::~CRtspInterleavedSocket( void 
+ {
+     Close();
+     delete m_pbuf;
++    m_pbuf = NULL;
+ }
+ 
+ bool CRtspInterleavedSocket::IsOpen( void )
+@@ -56,7 +65,9 @@ void CRtspInterleavedSocket::Close( void )
+ {
+     if( m_pProt )
+     {
+-        m_pProt->m_ppSockets[m_chan] = NULL;
++      // XXX FIX Wenn m_pProt an der Stell eh schon geloescht wurde, ist das
++      // entfernen der Sockets eigentlichh sinnlos
++        // m_pProt->m_ppSockets[m_chan] = NULL;
+         m_pProt = NULL;
+         if( m_pResponse ) m_pResponse->OnClosed();
+     }
+@@ -68,7 +79,7 @@ size_t CRtspInterleavedSocket::Read( PVOID pbuf, size_
+ 
+     // We will treat the read as a datagram -- copy as much as will fit and
+     // discard any remainder
+-    size_t copylen = min( nLen, m_pbuf->GetSize() );
++    size_t copylen = MIN( nLen, m_pbuf->GetSize() );
+ 
+     memcpy( pbuf, m_pbuf->GetBuffer(), copylen );
+     delete m_pbuf; m_pbuf = NULL;
+@@ -154,6 +165,9 @@ CRtspProtocol::~CRtspProtocol( void )
+     delete m_psock;
+     delete[] m_pReadBuf;
+     delete m_pmsg;
++    m_psock = NULL;
++    m_pReadBuf = NULL;
++    m_pmsg = NULL;
+ }
+ 
+ void CRtspProtocol::Init( CSocket* pSocket )
+@@ -174,7 +188,8 @@ void CRtspProtocol::SendRequest( CRtspRequestMsg* pmsg
+     {
+         char buf[16];
+         cseq = GetNextCseq();
+-        sprintf( buf, "%u", cseq );
++        size_t n = snprintf( buf, sizeof(buf), "%u", cseq );
++      assert( sizeof(buf) >= n );
+         pmsg->SetHdr( "CSeq", buf );
+     }
+     else
+@@ -190,28 +205,62 @@ void CRtspProtocol::SendRequest( CRtspRequestMsg* pmsg
+     // <verb> SP <url> SP "RTSP/1.0" CRLF
+     // <headers> CRLF <buf>
+     size_t len = FUDGE + strlen(pVerb)+1+strlen(pUrl)+1+8 + 2 + nHdrLen + 2 + 
nBufLen;
+-    char* pbuf = new char[ FUDGE + strlen(pVerb)+1+strlen(pUrl)+1+8 + 2 +
+-                           nHdrLen + 2 + nBufLen ];
++    size_t bufferLength = FUDGE + strlen(pVerb) + 1 + strlen(pUrl) + 1 + 8 + 
2 + nHdrLen + 2 + nBufLen;
++    char* pbuf = new char[ bufferLength ];
+     char* p = pbuf;
++    size_t writtenChars = 0;
++    size_t leftBufferSpace = bufferLength;
+     if( !pbuf )
+     {
+         printf( "Out of memory\n" );
+         exit( -1 );
+     }
+ 
+-    p += sprintf( pbuf, "%s %s RTSP/1.0\r\n", pVerb, pUrl );
++    writtenChars = snprintf( pbuf, bufferLength, "%s %s RTSP/1.0\r\n", pVerb, 
pUrl );
++    if ( writtenChars > leftBufferSpace )
++    {
++      printf( "Possible request buffer overflow!\n" );
++      exit( -1 );
++    }
++      
++    leftBufferSpace -= writtenChars;
++    assert ( leftBufferSpace > 0 );
++    p += writtenChars;
+     for( UINT n = 0; n < pmsg->GetHdrCount(); n++ )
+     {
+         CRtspHdr* pHdr = pmsg->GetHdr( n );
+-        p += sprintf( p, "%s: %s\r\n", (CPCHAR)pHdr->GetKey(), 
(CPCHAR)pHdr->GetVal() );
++      writtenChars = snprintf( p, leftBufferSpace, "%s: %s\r\n", 
(CPCHAR)pHdr->GetKey(), (CPCHAR)pHdr->GetVal() );
++      if ( writtenChars > leftBufferSpace )
++      {
++          printf( "Possible request buffer overflow!\n" );
++          exit( -1 );
++      }
++          
++      leftBufferSpace -= writtenChars;
++      assert( leftBufferSpace > 0 );
++        p += writtenChars;
+     }
+-    p += sprintf( p, "\r\n" );
++    assert( leftBufferSpace >= 3 );
++
++    if ( leftBufferSpace < 3 )
++    {
++      printf( "Possible request buffer overflow!\n" );
++      exit( -1 );
++    } 
++    
++    p += snprintf( p, leftBufferSpace, "\r\n" );
+     if( nBufLen )
+     {
++      assert( leftBufferSpace >= nBufLen );
++      if ( leftBufferSpace < nBufLen )
++      {
++          printf( "Possible request buffer overflow!\n" );
++          exit( -1 );
++      }       
+         memcpy( p, pmsg->GetBuf(), nBufLen );
+         p += nBufLen;
+     }
+-assert( p-pbuf <= len );
++    assert( static_cast<size_t>( p-pbuf ) <= len );
+     m_psock->Write( pbuf, p-pbuf );
+     delete[] pbuf;
+ 
+@@ -232,21 +281,52 @@ void CRtspProtocol::SendResponse( CRtspResponseMsg* pm
+     if( 0 == nBufLen ) nResponseLen++;
+     char* pbuf = new char[ nResponseLen ];
+     char* p = pbuf;
++    size_t writtenChars = 0;
++    size_t leftBufferSpace = nResponseLen;
+     if( !pbuf )
+     {
+         printf( "Out of memory\n" );
+         exit( -1 );
+     }
+ 
+-    p += sprintf( pbuf, "RTSP/1.0 %u %s\r\n", nCode, pReason );
++    writtenChars = snprintf( pbuf, leftBufferSpace, "RTSP/1.0 %u %s\r\n", 
nCode, pReason );
++    if ( writtenChars > leftBufferSpace )
++    {
++      printf( "Possible request buffer overflow!\n" );
++      exit( -1 );
++    } 
++
++    leftBufferSpace -= writtenChars;
++    assert( leftBufferSpace > 0 );
++    p += writtenChars;
+     for( UINT n = 0; n < pmsg->GetHdrCount(); n++ )
+     {
+         CRtspHdr* pHdr = pmsg->GetHdr( n );
+-        p += sprintf( p, "%s: %s\r\n", (CPCHAR)pHdr->GetKey(), 
(CPCHAR)pHdr->GetVal() );
++      writtenChars = snprintf( p, leftBufferSpace, "%s: %s\r\n", 
(CPCHAR)pHdr->GetKey(), (CPCHAR)pHdr->GetVal() );
++      if ( writtenChars > leftBufferSpace )
++      {
++          printf( "Possible request buffer overflow!\n" );
++          exit( -1 );
++      }       
++      leftBufferSpace -= writtenChars;
++      assert( leftBufferSpace > 0 );
++        p += writtenChars;
+     }
+-    p += sprintf( p, "\r\n" );
++    assert( leftBufferSpace >=3 );
++    if ( leftBufferSpace < 3 )
++    {
++      printf( "Possible request buffer overflow!\n" );
++      exit( -1 );
++    } 
++    p += snprintf( p, leftBufferSpace, "\r\n" );
+     if( nBufLen )
+     {
++      assert( leftBufferSpace >= nBufLen );
++      if ( leftBufferSpace < nBufLen )
++      {
++          printf( "Possible request buffer overflow!\n" );
++          exit( -1 );
++      }       
+         memcpy( p, pmsg->GetBuf(), nBufLen );
+         p += nBufLen;
+     }
+@@ -672,7 +752,7 @@ void CRtspProtocol::OnExceptReady( void )
+ 
+ void CRtspProtocol::OnClosed( void )
+ {
+-    assert( m_pResponse );
++    assert( m_pResponse != NULL );
+     dbgout( "CRtspProtocol::OnClosed: Socket closed" );
+     m_pResponse->OnError( RTSPE_CLOSED );
+ }
Index: net/osrtspproxy/patches/patch-rtspproxy_proxysession_cpp
===================================================================
RCS file: net/osrtspproxy/patches/patch-rtspproxy_proxysession_cpp
diff -N net/osrtspproxy/patches/patch-rtspproxy_proxysession_cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ net/osrtspproxy/patches/patch-rtspproxy_proxysession_cpp    7 Jan 2015 
23:10:58 -0000
@@ -0,0 +1,12 @@
+$OpenBSD$
+--- rtspproxy/proxysession.cpp.orig    Thu Feb  8 01:07:28 2001
++++ rtspproxy/proxysession.cpp Thu Jan  8 00:10:40 2015
+@@ -239,7 +239,7 @@ void CRtspProxySession::SetSessionID( const CString& s
+     m_clientSessionID = strSessionID;
+ 
+     char szSessionIndex[20];
+-    sprintf( szSessionIndex, "%u", sessionIndex );
++    snprintf( szSessionIndex, sizeof(szSessionIndex), "%u", sessionIndex );
+     m_clientSessionID.Append( szSessionIndex );
+ }
+ 
Index: net/osrtspproxy/patches/patch-rtspproxy_rtspproxy_cpp
===================================================================
RCS file: net/osrtspproxy/patches/patch-rtspproxy_rtspproxy_cpp
diff -N net/osrtspproxy/patches/patch-rtspproxy_rtspproxy_cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ net/osrtspproxy/patches/patch-rtspproxy_rtspproxy_cpp       8 Jan 2015 
20:04:12 -0000
@@ -0,0 +1,83 @@
+$OpenBSD$
+--- rtspproxy/rtspproxy.cpp.orig       Sat Feb 10 00:38:53 2001
++++ rtspproxy/rtspproxy.cpp    Thu Jan  8 21:03:47 2015
+@@ -27,9 +27,9 @@ void OutputDebugInfo( const char* fmt, ... )
+     char str[4096];
+     va_list v;
+     va_start( v, fmt );
+-    vsprintf( str, fmt, v );
+-    strcat( str, "\n" );
+-    printf( str );
++    vsnprintf( str, sizeof(str), fmt, v );
++    va_end( v );
++    printf( "%s\n", str );
+ }
+ 
+ /**************************************
+@@ -57,7 +57,7 @@ CClientCnx::CClientCnx( CRtspProxyCnx* pOwner, CTcpSoc
+ 
+ CClientCnx::~CClientCnx( void )
+ {
+-
++    Close();
+ }
+ 
+ void CClientCnx::Close( void )
+@@ -102,7 +102,7 @@ void CClientCnx::sendResponse( UINT code, UINT cseq )
+     if( cseq )
+     {
+         char buf[20];
+-        sprintf( buf, "%d", cseq );
++        snprintf( buf,sizeof(buf) , "%d", cseq );
+         msg.SetHdr( "CSeq", buf );
+     }
+     sendResponse( &msg );
+@@ -285,7 +285,7 @@ CServerCnx::CServerCnx( CRtspProxyCnx* pOwner, CString
+ 
+ CServerCnx::~CServerCnx( void )
+ {
+-
++    Close();
+ }
+ 
+ void CServerCnx::Close( void )
+@@ -667,7 +667,7 @@ void CRtspProxyCnx::PassToClient( CRtspRequestMsg* pms
+ 
+     CString strCSeq = pmsg->GetHdr( "CSeq" );
+     char buf[20];
+-    sprintf( buf, "%u", m_cseqToClient++ );
++    snprintf( buf, sizeof(buf), "%u", m_cseqToClient++ );
+ 
+     CCSeqPair* pPair = new CCSeqPair( buf, strCSeq, 
pServerCnx->GetHostName(), pServerCnx->GetPort() );
+     m_listCCSeqPairList.InsertTail( pPair );
+@@ -895,7 +895,7 @@ void CRtspProxyCnx::PassSetupRequestMsgToServer( CRtsp
+                 nBlocksize = nClientBlocksize;
+             }
+         }
+-        sprintf( buf, "%d", nBlocksize );
++        snprintf( buf, sizeof(buf), "%d", nBlocksize );
+         pmsg->SetHdr( "Blocksize", buf );
+     }
+     PassToServer( pmsg );
+@@ -1190,7 +1190,7 @@ bool CRtspProxyApp::Init( void )
+ {
+     if( ! CApp::Init() ) return false;
+ 
+-    CSockAddr addr( CInetAddr::Any(), m_port );
++    CSockAddr addr( "127.0.0.1", m_port );
+     if( ! m_sock.Listen( addr ) )
+     {
+         printf( "Port %d not available. Exit!\n", m_port );
+@@ -1199,9 +1199,11 @@ bool CRtspProxyApp::Init( void )
+     printf( "Listening on port %hu\n", m_port );
+ 
+ //    Daemonize();
++    if (! g_DebugFlagTurnedOn)
++      daemon(0,0);
+ 
+     addr = m_sock.GetLocalAddr();
+-    sprintf(m_viaHdrValue, "RTSP/1.0 %lx", 
addr.GetHost().s_addr^time(NULL)^rand());
++    snprintf(m_viaHdrValue, sizeof(m_viaHdrValue), "RTSP/1.0 %lx", 
static_cast<long>(arc4random()));
+ 
+     return true;
+ }
Index: net/osrtspproxy/patches/patch-rtspproxy_tranhdr_cpp
===================================================================
RCS file: net/osrtspproxy/patches/patch-rtspproxy_tranhdr_cpp
diff -N net/osrtspproxy/patches/patch-rtspproxy_tranhdr_cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ net/osrtspproxy/patches/patch-rtspproxy_tranhdr_cpp 23 Dec 2014 13:35:08 
-0000
@@ -0,0 +1,43 @@
+$OpenBSD$
+--- rtspproxy/tranhdr.cpp.orig Fri Feb  9 23:32:35 2001
++++ rtspproxy/tranhdr.cpp      Tue Nov 11 19:12:07 2014
+@@ -178,31 +178,31 @@ CPCHAR CSingleTransportHdr::GetHdrString( void )
+         if( field.type & RTSP_TRANSPORTHDR_CLIENTPORT )
+         {
+             if( m_nClientPorts == 2 )
+-                p += sprintf( p, "client_port=%hu-%hu", m_clientBasePort, 
m_clientBasePort+1 );
++                p += snprintf( p, sizeof(strRet), "client_port=%hu-%hu", 
m_clientBasePort, m_clientBasePort+1 );
+             else if( m_nClientPorts == 1 )
+-                p += sprintf( p, "client_port=%hu", m_clientBasePort );
++                p += snprintf( p, sizeof(strRet),  "client_port=%hu", 
m_clientBasePort );
+         }
+         else if( field.type & RTSP_TRANSPORTHDR_SERVERPORT )
+         {
+             if( m_nServerPorts == 2 )
+-                p += sprintf( p, "server_port=%hu-%hu", m_serverBasePort, 
m_serverBasePort+1 );
++                p += snprintf( p, sizeof(char) * 255, "server_port=%hu-%hu", 
m_serverBasePort, m_serverBasePort+1 );
+             else if( m_nServerPorts == 1 )
+-                p += sprintf( p, "server_port=%hu", m_serverBasePort );
++                p += snprintf( p, sizeof(char) * 255, "server_port=%hu", 
m_serverBasePort );
+         }
+         else if( field.type & RTSP_TRANSPORTHDR_SOURCE )
+         {
+-            p += sprintf( p, "source=%s", inet_ntoa(m_addrSource) );
++            p += snprintf( p, sizeof(strRet), "source=%s", 
inet_ntoa(m_addrSource) );
+         }
+         else if( field.type & RTSP_TRANSPORTHDR_INTERLEAVED )
+         {
+             if( m_nServerPorts == 2 )
+-                p += sprintf( p, "interleaved=%hu-%hu", m_serverBasePort, 
m_serverBasePort+1 );
++                p += snprintf( p, sizeof(strRet), "interleaved=%hu-%hu", 
m_serverBasePort, m_serverBasePort+1 );
+             else if( m_nServerPorts == 1 )
+-                p += sprintf( p, "interleaved=%hu", m_serverBasePort );
++                p += snprintf( p, sizeof(strRet), "interleaved=%hu", 
m_serverBasePort );
+         }
+         else
+         {
+-            p += sprintf( p, "%s", ( CPCHAR )field.strField );
++            p += snprintf( p, sizeof(strRet), "%s", ( CPCHAR )field.strField 
);
+         }
+         itr++;
+         if( itr )
Index: net/osrtspproxy/pkg/PLIST
===================================================================
RCS file: /data/mirror/openbsd/cvs/ports/net/osrtspproxy/pkg/PLIST,v
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 PLIST
--- net/osrtspproxy/pkg/PLIST   10 Jan 2007 10:37:07 -0000      1.1.1.1
+++ net/osrtspproxy/pkg/PLIST   7 Jan 2015 22:22:32 -0000
@@ -1,5 +1,5 @@
 @comment $OpenBSD: PLIST,v 1.1.1.1 2007/01/10 10:37:07 grunk Exp $
-sbin/rtspproxy
+@bin sbin/rtspproxy
 share/doc/osrtspproxy/
 share/doc/osrtspproxy/LICENSE
 share/doc/osrtspproxy/graphics/

Reply via email to