From 5693e6c599a586b1bb19eea375c6b1e22526031c Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 24 Aug 2006 15:43:32 +0000 Subject: r17798: Beginnings of a standalone libaddns library released under the LGPL. Original code by Krishna Ganugapati . Additional work by me. It's still got some warts, but non-secure updates do currently work. There are at least four things left to really clean up. 1. Change the memory management to use talloc() rather than malloc() and cleanup the leaks. 2. Fix the error code reporting (see initial changes to dnserr.h) 3. Fix the secure updates 4. Define a public interface in addns.h 5. Move the code in libads/dns.c into the libaddns/ directory (and under the LGPL). A few notes: * Enable the new code by compiling with --with-dnsupdate * Also adds the command 'net ads dns register' * Requires -luuid (included in the e2fsprogs-devel package). * Has only been tested on Linux platforms so there may be portability issues. (This used to be commit 36f04674aeefd93c5a0408b8967dcd48b86fdbc1) --- source3/libaddns/dnssock.c | 766 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 766 insertions(+) create mode 100644 source3/libaddns/dnssock.c (limited to 'source3/libaddns/dnssock.c') diff --git a/source3/libaddns/dnssock.c b/source3/libaddns/dnssock.c new file mode 100644 index 0000000000..0af30cc1be --- /dev/null +++ b/source3/libaddns/dnssock.c @@ -0,0 +1,766 @@ +/* + Linux DNS client library implementation + + Copyright (C) 2006 Krishna Ganugapati + Copyright (C) 2006 Gerald Carter + + ** NOTE! The following LGPL license applies to the libaddns + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#include "dns.h" + +/******************************************************************** +********************************************************************/ + +static DNS_ERROR DNSTCPOpen( char *nameserver, HANDLE * phDNSServer ) +{ + DNS_ERROR dwError = ERROR_DNS_INVALID_PARAMETER; + int sockServer; + unsigned long ulAddress; + struct hostent *pHost; + struct sockaddr_in s_in; + DNS_CONNECTION_CONTEXT *pDNSContext = NULL; + + if ( (pDNSContext = TALLOC_P( NULL, DNS_CONNECTION_CONTEXT )) == NULL ) { + return ERROR_DNS_NO_MEMORY; + } + + if ( (ulAddress = inet_addr( nameserver )) == INADDR_NONE ) { + if ( (pHost = gethostbyname( nameserver )) == NULL ) { + dwError = ERROR_DNS_INVALID_NAME_SERVER; + BAIL_ON_DNS_ERROR( dwError ); + } + memcpy( &ulAddress, pHost->h_addr, pHost->h_length ); + } + + if ( (sockServer = socket( PF_INET, SOCK_STREAM, 0 )) == INVALID_SOCKET ) { + dwError = ERROR_DNS_NO_MEMORY; + BAIL_ON_DNS_ERROR( dwError ); + } + + s_in.sin_family = AF_INET; + s_in.sin_addr.s_addr = ulAddress; + s_in.sin_port = htons( DNS_TCP_PORT ); + + if ( (connect( sockServer, &s_in, sizeof( s_in ))) == SOCKET_ERROR ) { + dwError = ERROR_DNS_CONNECTION_FAILED; + BAIL_ON_DNS_ERROR( dwError ); + } + + pDNSContext->s = sockServer; + pDNSContext->hType = DNS_TCP; + + *phDNSServer = ( HANDLE ) pDNSContext; + + dwError = ERROR_DNS_SUCCESS; + + return dwError; + +error: + TALLOC_FREE( pDNSContext ); + *phDNSServer = ( HANDLE ) NULL; + + return dwError; +} + +/******************************************************************** +********************************************************************/ + +static DNS_ERROR DNSUDPOpen( char *nameserver, HANDLE * phDNSServer ) +{ + DNS_ERROR dwError = ERROR_DNS_INVALID_PARAMETER; + int SendSocket; + unsigned long ulAddress; + struct hostent *pHost; + struct sockaddr_in RecvAddr; + DNS_CONNECTION_CONTEXT *pDNSContext = NULL; + + if ( (pDNSContext = TALLOC_P( NULL, DNS_CONNECTION_CONTEXT )) == NULL ) { + return ERROR_DNS_NO_MEMORY; + } + + if ( (ulAddress = inet_addr( nameserver )) == INADDR_NONE ) { + if ( (pHost = gethostbyname( nameserver )) == NULL ) { + dwError = ERROR_DNS_INVALID_NAME_SERVER; + BAIL_ON_DNS_ERROR( dwError ); + } + memcpy( &ulAddress, pHost->h_addr, pHost->h_length ); + } + + /* Create a socket for sending data */ + + SendSocket = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP ); + + /* Set up the RecvAddr structure with the IP address of + the receiver (in this example case "123.456.789.1") + and the specified port number. */ + + RecvAddr.sin_family = AF_INET; + RecvAddr.sin_port = htons( DNS_UDP_PORT ); + RecvAddr.sin_addr.s_addr = ulAddress; + + pDNSContext->s = SendSocket; + pDNSContext->hType = DNS_UDP; + memcpy( &pDNSContext->RecvAddr, &RecvAddr, sizeof( struct sockaddr_in ) ); + + *phDNSServer = ( HANDLE ) pDNSContext; + + dwError = ERROR_DNS_SUCCESS; + + return dwError; + +error: + TALLOC_FREE( pDNSContext ); + *phDNSServer = ( HANDLE ) NULL; + + return dwError; +} + +/******************************************************************** +********************************************************************/ + +DNS_ERROR DNSOpen( char *nameserver, int32 dwType, HANDLE * phDNSServer ) +{ + switch ( dwType ) { + case DNS_TCP: + return DNSTCPOpen( nameserver, phDNSServer ); + case DNS_UDP: + return DNSUDPOpen( nameserver, phDNSServer ); + } + + return ERROR_DNS_INVALID_PARAMETER; +} + +/******************************************************************** +********************************************************************/ + +static int32 DNSSendTCPRequest( HANDLE hDNSHandle, + uint8 * pDNSSendBuffer, + int32 dwBufferSize, int32 * pdwBytesSent ) +{ + int32 dwError = 0; + int32 dwBytesSent = 0; + DNS_CONNECTION_CONTEXT *pDNSContext = NULL; + + + pDNSContext = ( DNS_CONNECTION_CONTEXT * ) hDNSHandle; + + dwBytesSent = send( pDNSContext->s, pDNSSendBuffer, dwBufferSize, 0 ); + if ( dwBytesSent == SOCKET_ERROR ) { + dwError = WSAGetLastError( ); + BAIL_ON_ERROR( dwError ); + } + + *pdwBytesSent = dwBytesSent; + + return dwError; + + error: + *pdwBytesSent = 0; + return dwError; +} + +/******************************************************************** +********************************************************************/ + +static int32 DNSSendUDPRequest( HANDLE hDNSHandle, + uint8 * pDNSSendBuffer, + int32 dwBufferSize, int32 * pdwBytesSent ) +{ + int32 dwError = 0; + int32 dwBytesSent = 0; + DNS_CONNECTION_CONTEXT *pDNSContext = NULL; + + pDNSContext = ( DNS_CONNECTION_CONTEXT * ) hDNSHandle; + + dwBytesSent = sendto( pDNSContext->s, + pDNSSendBuffer, + dwBufferSize, + 0, + ( struct sockaddr * ) & pDNSContext->RecvAddr, + sizeof( pDNSContext->RecvAddr ) + ); + if ( dwBytesSent == SOCKET_ERROR ) { + dwError = WSAGetLastError( ); + BAIL_ON_ERROR( dwError ); + } else { + *pdwBytesSent = dwBytesSent; + } + + return dwError; + + error: + *pdwBytesSent = 0; + return dwError; +} + +/******************************************************************** +********************************************************************/ + +static int32 DNSSelect( HANDLE hDNSHandle ) +{ + int32 dwError = 0; + fd_set rfds; + struct timeval tv; + int32 dwNumSockets = 0; + DNS_CONNECTION_CONTEXT *pDNSContext = NULL; + + pDNSContext = ( DNS_CONNECTION_CONTEXT * ) hDNSHandle; + FD_ZERO( &rfds ); + FD_SET( pDNSContext->s, &rfds ); + + tv.tv_sec = 10; + tv.tv_usec = 0; + dwNumSockets = select( pDNSContext->s + 1, &rfds, NULL, NULL, &tv ); + if ( dwNumSockets == SOCKET_ERROR ) { + dwError = WSAGetLastError( ); + BAIL_ON_ERROR( dwError ); + } + + if ( !dwNumSockets ) { +#ifndef WIN32 + dwError = ETIMEDOUT; +#elif + dwError = WSAETIMEDOUT; +#endif + } + + error: + + return dwError; +} + +/******************************************************************** +********************************************************************/ + +static int32 DNSTCPReceiveBufferContext( HANDLE hDNSHandle, + HANDLE hDNSRecvBuffer, int32 * pdwBytesRead ) +{ + int32 dwError = 0; + int32 dwRead = 0; + int16 wBytesToRead = 0; + int16 wnBytesToRead = 0; + DNS_CONNECTION_CONTEXT *pDNSContext = NULL; + DNS_RECEIVEBUFFER_CONTEXT *pDNSRecvContext = NULL; + + pDNSContext = ( DNS_CONNECTION_CONTEXT * ) hDNSHandle; + pDNSRecvContext = ( DNS_RECEIVEBUFFER_CONTEXT * ) hDNSRecvBuffer; + + dwError = DNSSelect( hDNSHandle ); + BAIL_ON_ERROR( dwError ); + + dwRead = recv( pDNSContext->s, ( char * ) &wnBytesToRead, + sizeof( int16 ), 0 ); + if ( dwRead == SOCKET_ERROR ) { + dwError = WSAGetLastError( ); + BAIL_ON_ERROR( dwError ); + } + + wBytesToRead = ntohs( wnBytesToRead ); + + dwError = DNSSelect( hDNSHandle ); + BAIL_ON_ERROR( dwError ); + + dwRead = recv( pDNSContext->s, + ( char * ) pDNSRecvContext->pRecvBuffer, wBytesToRead, + 0 ); + if ( dwRead == SOCKET_ERROR ) { + dwError = WSAGetLastError( ); + BAIL_ON_ERROR( dwError ); + } + + pDNSRecvContext->dwBytesRecvd = dwRead; + + *pdwBytesRead = ( int32 ) dwRead; + + return dwError; + + error: + + return dwError; +} + +/******************************************************************** +********************************************************************/ + +static int32 DNSUDPReceiveBufferContext( HANDLE hDNSHandle, + HANDLE hDNSRecvBuffer, int32 * pdwBytesRead ) +{ + int32 dwError = 0; + int32 dwRead = 0; + DNS_CONNECTION_CONTEXT *pDNSContext = NULL; + DNS_RECEIVEBUFFER_CONTEXT *pDNSRecvContext = NULL; + + pDNSContext = ( DNS_CONNECTION_CONTEXT * ) hDNSHandle; + pDNSRecvContext = ( DNS_RECEIVEBUFFER_CONTEXT * ) hDNSRecvBuffer; + + dwError = DNSSelect( hDNSHandle ); + BAIL_ON_ERROR( dwError ); + + dwRead = recv( pDNSContext->s, + ( char * ) pDNSRecvContext->pRecvBuffer, 512, 0 ); + if ( dwRead == SOCKET_ERROR ) { + dwError = WSAGetLastError( ); + BAIL_ON_ERROR( dwError ); + } + + pDNSRecvContext->dwBytesRecvd = dwRead; + + *pdwBytesRead = ( int32 ) dwRead; + + error: + + return dwError; +} + +/******************************************************************** +********************************************************************/ + +int32 DNSReceiveBufferContext( HANDLE hDNSHandle, + HANDLE hDNSRecvBuffer, int32 * pdwBytesRead ) +{ + int32 dwError = 0; + DNS_CONNECTION_CONTEXT *pDNSContext = NULL; + + pDNSContext = ( DNS_CONNECTION_CONTEXT * ) hDNSHandle; + + switch ( pDNSContext->hType ) { + case DNS_TCP: + dwError = + DNSTCPReceiveBufferContext( hDNSHandle, + hDNSRecvBuffer, + pdwBytesRead ); + break; + case DNS_UDP: + dwError = + DNSUDPReceiveBufferContext( hDNSHandle, + hDNSRecvBuffer, + pdwBytesRead ); + break; + } + return dwError; +} + +/******************************************************************** +********************************************************************/ + +int32 DNSCreateSendBuffer( HANDLE * phDNSSendBuffer ) +{ + int32 dwError = 0; + DNS_SENDBUFFER_CONTEXT *pDNSContext = NULL; + uint8 *pSendBuffer = NULL; + + dwError = DNSAllocateMemory( sizeof( DNS_SENDBUFFER_CONTEXT ), + ( void ** ) &pDNSContext ); + BAIL_ON_ERROR( dwError ); + + dwError = + DNSAllocateMemory( SENDBUFFER_SIZE, + ( void ** ) &pSendBuffer ); + BAIL_ON_ERROR( dwError ); + + pDNSContext->pSendBuffer = pSendBuffer; + pDNSContext->dwBufferSize = SENDBUFFER_SIZE; + + /* We will offset into the buffer by 2 bytes + If we are doing a TCP write; we will fill in these + two bytes and send + 2 bytes + If we are doing a UDP write; we will start our send + +2 bytes and only send dwWritten; */ + + pDNSContext->dwBufferOffset += 2; + + *phDNSSendBuffer = ( HANDLE ) pDNSContext; + + return dwError; + + error: + + if ( pSendBuffer ) { + DNSFreeMemory( pSendBuffer ); + } + if ( pDNSContext ) { + DNSFreeMemory( pDNSContext ); + } + *phDNSSendBuffer = ( HANDLE ) NULL; + + return dwError; +} + + +/******************************************************************** +********************************************************************/ + +int32 DNSMarshallBuffer( HANDLE hDNSSendBuffer, + uint8 * pDNSSendBuffer, + int32 dwBufferSize, int32 * pdwBytesWritten ) +{ + int32 dwError = 0; + uint8 *pTemp = NULL; + DNS_SENDBUFFER_CONTEXT *pDNSContext = NULL; + +/* BugBug - we need to check for amount of space remaining in the +SendBuffer Context - if its insufficent, we want to realloc the +Buffer and copy the context; Right now the assumption is we have a big +enough buffer */ + + pDNSContext = ( DNS_SENDBUFFER_CONTEXT * ) hDNSSendBuffer; + + pTemp = pDNSContext->pSendBuffer + pDNSContext->dwBufferOffset; + + memcpy( pTemp, pDNSSendBuffer, dwBufferSize ); + + pDNSContext->dwBytesWritten += dwBufferSize; + pDNSContext->dwBufferOffset += dwBufferSize; + + *pdwBytesWritten = dwBufferSize; + + return dwError; +} + +/******************************************************************** +********************************************************************/ + +static int32 DNSTCPSendBufferContext( HANDLE hDNSServer, + HANDLE hSendBuffer, int32 * pdwBytesSent ) +{ + DNS_SENDBUFFER_CONTEXT *pSendBufferContext = NULL; + int32 dwError = 0; + int16 wBytesWritten = 0; + int16 wnBytesWritten = 0; + + pSendBufferContext = ( DNS_SENDBUFFER_CONTEXT * ) hSendBuffer; + + wBytesWritten = ( int16 ) pSendBufferContext->dwBytesWritten; + wnBytesWritten = htons( wBytesWritten ); + + memcpy( pSendBufferContext->pSendBuffer, &wnBytesWritten, + sizeof( int16 ) ); + + dwError = DNSSendTCPRequest( hDNSServer, + pSendBufferContext->pSendBuffer, + pSendBufferContext->dwBytesWritten + 2, + pdwBytesSent ); + BAIL_ON_ERROR( dwError ); + + error: + + return dwError; +} + +/******************************************************************** +********************************************************************/ + +static int32 DNSUDPSendBufferContext( HANDLE hDNSServer, + HANDLE hSendBuffer, int32 * pdwBytesSent ) +{ + DNS_SENDBUFFER_CONTEXT *pSendBufferContext = NULL; + int32 dwError = 0; + + pSendBufferContext = ( DNS_SENDBUFFER_CONTEXT * ) hSendBuffer; + + /* Now remember to send 2 bytes ahead of pSendBuffer; because + we ignore the 2 bytes size field. */ + + dwError = DNSSendUDPRequest( hDNSServer, + pSendBufferContext->pSendBuffer + 2, + pSendBufferContext->dwBytesWritten, + pdwBytesSent ); + BAIL_ON_ERROR( dwError ); + + error: + + return dwError; +} + +/******************************************************************** +********************************************************************/ + +int32 DNSSendBufferContext( HANDLE hDNSServer, + HANDLE hSendBuffer, int32 * pdwBytesSent ) +{ + DNS_CONNECTION_CONTEXT *pDNSContext = NULL; + int32 dwError = 0; + + pDNSContext = ( DNS_CONNECTION_CONTEXT * ) hDNSServer; + + switch ( pDNSContext->hType ) { + case DNS_TCP: + dwError = DNSTCPSendBufferContext( hDNSServer, + hSendBuffer, + pdwBytesSent ); + BAIL_ON_ERROR( dwError ); + break; + + case DNS_UDP: + dwError = DNSUDPSendBufferContext( hDNSServer, + hSendBuffer, + pdwBytesSent ); + BAIL_ON_ERROR( dwError ); + break; + } + error: + + return dwError; +} + +/******************************************************************** +********************************************************************/ + +int32 DNSDumpSendBufferContext( HANDLE hSendBuffer ) +{ + DNS_SENDBUFFER_CONTEXT *pSendBufferContext = NULL; + int32 dwError = 0; + int32 dwCurLine = 0; + int32 i = 0; + + pSendBufferContext = ( DNS_SENDBUFFER_CONTEXT * ) hSendBuffer; + printf( "\n" ); + printf( "Buffer Size is: %d\n", pSendBufferContext->dwBytesWritten ); + while ( i < pSendBufferContext->dwBytesWritten ) { + if ( ( i / 16 ) > dwCurLine ) { + printf( "\n" ); + dwCurLine++; + } + if ( ( i % 8 ) == 0 ) { + printf( " " ); + } + printf( "%.2x ", pSendBufferContext->pSendBuffer[i] ); + i++; + } + return dwError; +} + +/******************************************************************** +********************************************************************/ + +int32 DNSDumpRecvBufferContext( HANDLE hRecvBuffer ) +{ + DNS_RECEIVEBUFFER_CONTEXT *pRecvBufferContext = NULL; + int32 dwError = 0; + int32 dwCurLine = 0; + int32 i = 0; + + pRecvBufferContext = ( DNS_RECEIVEBUFFER_CONTEXT * ) hRecvBuffer; + + printf( "\n" ); + printf( "Buffer Size is: %d\n", pRecvBufferContext->dwBytesRecvd ); + + while ( i < pRecvBufferContext->dwBytesRecvd ) { + if ( ( i / 16 ) > dwCurLine ) { + printf( "\n" ); + dwCurLine++; + } + if ( ( i % 8 ) == 0 ) { + printf( " " ); + } + printf( "%.2x ", pRecvBufferContext->pRecvBuffer[i] ); + i++; + } + return dwError; +} + +/******************************************************************** +********************************************************************/ + +int32 DNSCreateReceiveBuffer( HANDLE * phDNSRecvBuffer ) +{ + int32 dwError = 0; + DNS_RECEIVEBUFFER_CONTEXT *pDNSContext = NULL; + uint8 *pRecvBuffer = NULL; + + dwError = DNSAllocateMemory( sizeof( DNS_RECEIVEBUFFER_CONTEXT ), + ( void ** ) &pDNSContext ); + BAIL_ON_ERROR( dwError ); + + dwError = + DNSAllocateMemory( RECVBUFFER_SIZE, + ( void ** ) &pRecvBuffer ); + BAIL_ON_ERROR( dwError ); + + pDNSContext->pRecvBuffer = pRecvBuffer; + pDNSContext->dwBufferSize = RECVBUFFER_SIZE; + + *phDNSRecvBuffer = ( HANDLE ) pDNSContext; + + return dwError; + + error: + + if ( pRecvBuffer ) { + DNSFreeMemory( pRecvBuffer ); + } + if ( pDNSContext ) { + DNSFreeMemory( pDNSContext ); + } + *phDNSRecvBuffer = ( HANDLE ) NULL; + + return dwError; +} + +/******************************************************************** +********************************************************************/ + +int32 DNSUnmarshallBuffer( HANDLE hDNSRecvBuffer, + uint8 * pDNSRecvBuffer, + int32 dwBufferSize, int32 * pdwBytesRead ) +{ + int32 dwError = 0; + uint8 *pTemp = NULL; + DNS_RECEIVEBUFFER_CONTEXT *pDNSContext = NULL; + +/* BugBug - we need to check for amount of space remaining in the +SendBuffer Context - if its insufficent, we want to realloc the +Buffer and copy the context; Right now the assumption is we have a big +enough buffer */ + + pDNSContext = ( DNS_RECEIVEBUFFER_CONTEXT * ) hDNSRecvBuffer; + + pTemp = pDNSContext->pRecvBuffer + pDNSContext->dwBytesRead; + + memcpy( pDNSRecvBuffer, pTemp, dwBufferSize ); + + pDNSContext->dwBytesRead += dwBufferSize; + + *pdwBytesRead = dwBufferSize; + + return dwError; +} + +/******************************************************************** +********************************************************************/ + +int32 DNSUnmarshallDomainNameAtOffset( HANDLE hRecvBuffer, + int16 wOffset, + DNS_DOMAIN_NAME ** ppDomainName ) +{ + int32 dwError = 0; + DNS_DOMAIN_LABEL *pLabel = NULL; + DNS_DOMAIN_LABEL *pLabelList = NULL; + DNS_DOMAIN_NAME *pDomainName = NULL; + char *pszLabel = NULL; + char szLabel[65]; + uint8 uLen = 0; + int32 dwCurrent = 0; + DNS_RECEIVEBUFFER_CONTEXT *pRecvContext = NULL; + + pRecvContext = ( DNS_RECEIVEBUFFER_CONTEXT * ) hRecvBuffer; + dwCurrent = wOffset; + + while ( 1 ) { + + memcpy( &uLen, pRecvContext->pRecvBuffer + dwCurrent, + sizeof( char ) ); + dwCurrent++; + + if ( uLen == 0 ) { + break; + } + + memset( szLabel, 0, 65 ); + memcpy( szLabel, pRecvContext->pRecvBuffer + dwCurrent, + uLen ); + dwCurrent += uLen; + + dwError = DNSAllocateString( szLabel, &pszLabel ); + BAIL_ON_ERROR( dwError ); + + dwError = + DNSAllocateMemory( sizeof( DNS_DOMAIN_LABEL ), + ( void ** ) &pLabel ); + BAIL_ON_ERROR( dwError ); + + pLabel->pszLabel = pszLabel; + dwError = DNSAppendLabel( pLabelList, pLabel, &pLabelList ); + BAIL_ON_ERROR( dwError ); + } + + dwError = + DNSAllocateMemory( sizeof( DNS_DOMAIN_NAME ), + ( void ** ) &pDomainName ); + BAIL_ON_ERROR( dwError ); + pDomainName->pLabelList = pLabelList; + + *ppDomainName = pDomainName; + + return dwError; + + error: + + *ppDomainName = NULL; + return dwError; +} + +/******************************************************************** +********************************************************************/ + +int32 DNSReceiveBufferMoveBackIndex( HANDLE hRecvBuffer, int16 wOffset ) +{ + int32 dwError = 0; + DNS_RECEIVEBUFFER_CONTEXT *pDNSContext = NULL; + + pDNSContext = ( DNS_RECEIVEBUFFER_CONTEXT * ) hRecvBuffer; + pDNSContext->dwBytesRead -= wOffset; + + return dwError; +} + +/******************************************************************** +********************************************************************/ + +void DNSFreeSendBufferContext( HANDLE hSendBuffer ) +{ + DNS_SENDBUFFER_CONTEXT *pSendBufferContext = NULL; + + pSendBufferContext = ( DNS_SENDBUFFER_CONTEXT * ) hSendBuffer; + + if ( pSendBufferContext->pSendBuffer ) { + DNSFreeMemory( pSendBufferContext->pSendBuffer ); + } + if ( pSendBufferContext ) { + DNSFreeMemory( pSendBufferContext ); + } +} + +/******************************************************************** +********************************************************************/ + +int32 DNSGetSendBufferContextSize( HANDLE hSendBuffer ) +{ + DNS_SENDBUFFER_CONTEXT *pSendBufferContext = NULL; + + pSendBufferContext = ( DNS_SENDBUFFER_CONTEXT * ) hSendBuffer; + + return ( pSendBufferContext->dwBytesWritten ); + +} + +/******************************************************************** +********************************************************************/ + +uint8 *DNSGetSendBufferContextBuffer( HANDLE hSendBuffer ) +{ + DNS_SENDBUFFER_CONTEXT *pSendBufferContext = NULL; + + pSendBufferContext = ( DNS_SENDBUFFER_CONTEXT * ) hSendBuffer; + + return ( pSendBufferContext->pSendBuffer ); +} + -- cgit From 0d1e4dc5b01323282d24c61da78add5030cf545c Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 24 Aug 2006 18:48:44 +0000 Subject: r17803: finally get the new libaddns code to build on Solaris 9 (This used to be commit 6a4f4ce016dc47ff4b433208266c4616be7e2770) --- source3/libaddns/dnssock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libaddns/dnssock.c') diff --git a/source3/libaddns/dnssock.c b/source3/libaddns/dnssock.c index 0af30cc1be..713d56c703 100644 --- a/source3/libaddns/dnssock.c +++ b/source3/libaddns/dnssock.c @@ -59,7 +59,7 @@ static DNS_ERROR DNSTCPOpen( char *nameserver, HANDLE * phDNSServer ) s_in.sin_addr.s_addr = ulAddress; s_in.sin_port = htons( DNS_TCP_PORT ); - if ( (connect( sockServer, &s_in, sizeof( s_in ))) == SOCKET_ERROR ) { + if ( (connect( sockServer, (struct sockaddr*)&s_in, sizeof( s_in ))) == SOCKET_ERROR ) { dwError = ERROR_DNS_CONNECTION_FAILED; BAIL_ON_DNS_ERROR( dwError ); } -- cgit From 49a3f72ebbf2ace388d0b6a488a9ae0b2c5675ac Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 24 Aug 2006 20:17:59 +0000 Subject: r17805: Sorry Jerry, I could not stand the warnings... :-) (This used to be commit f5fcafd77e8a749659ef90296402c5130f45419b) --- source3/libaddns/dnssock.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source3/libaddns/dnssock.c') diff --git a/source3/libaddns/dnssock.c b/source3/libaddns/dnssock.c index 713d56c703..88bd44e0e2 100644 --- a/source3/libaddns/dnssock.c +++ b/source3/libaddns/dnssock.c @@ -368,12 +368,12 @@ int32 DNSCreateSendBuffer( HANDLE * phDNSSendBuffer ) uint8 *pSendBuffer = NULL; dwError = DNSAllocateMemory( sizeof( DNS_SENDBUFFER_CONTEXT ), - ( void ** ) &pDNSContext ); + ( void * ) &pDNSContext ); BAIL_ON_ERROR( dwError ); dwError = DNSAllocateMemory( SENDBUFFER_SIZE, - ( void ** ) &pSendBuffer ); + ( void * ) &pSendBuffer ); BAIL_ON_ERROR( dwError ); pDNSContext->pSendBuffer = pSendBuffer; @@ -587,12 +587,12 @@ int32 DNSCreateReceiveBuffer( HANDLE * phDNSRecvBuffer ) uint8 *pRecvBuffer = NULL; dwError = DNSAllocateMemory( sizeof( DNS_RECEIVEBUFFER_CONTEXT ), - ( void ** ) &pDNSContext ); + ( void * ) &pDNSContext ); BAIL_ON_ERROR( dwError ); dwError = DNSAllocateMemory( RECVBUFFER_SIZE, - ( void ** ) &pRecvBuffer ); + ( void * ) &pRecvBuffer ); BAIL_ON_ERROR( dwError ); pDNSContext->pRecvBuffer = pRecvBuffer; @@ -684,7 +684,7 @@ int32 DNSUnmarshallDomainNameAtOffset( HANDLE hRecvBuffer, dwError = DNSAllocateMemory( sizeof( DNS_DOMAIN_LABEL ), - ( void ** ) &pLabel ); + ( void * ) &pLabel ); BAIL_ON_ERROR( dwError ); pLabel->pszLabel = pszLabel; @@ -694,7 +694,7 @@ int32 DNSUnmarshallDomainNameAtOffset( HANDLE hRecvBuffer, dwError = DNSAllocateMemory( sizeof( DNS_DOMAIN_NAME ), - ( void ** ) &pDomainName ); + ( void * ) &pDomainName ); BAIL_ON_ERROR( dwError ); pDomainName->pLabelList = pLabelList; -- cgit From d59fe2834e2bfe6112ceed4938b992be66b55ea7 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 25 Aug 2006 15:08:05 +0000 Subject: r17833: Next step to fix the build farm. Jerry, why don't you include "includes.h"? Thanks, Volker (This used to be commit c02970c27251d7cd1f5a14a8ac7671d8e4325f5d) --- source3/libaddns/dnssock.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libaddns/dnssock.c') diff --git a/source3/libaddns/dnssock.c b/source3/libaddns/dnssock.c index 88bd44e0e2..3d0991a1aa 100644 --- a/source3/libaddns/dnssock.c +++ b/source3/libaddns/dnssock.c @@ -25,6 +25,7 @@ */ #include "dns.h" +#include /******************************************************************** ********************************************************************/ -- cgit From 9230c659f66df3da9fda5e7cae1717f19c9c08c7 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 25 Aug 2006 18:24:43 +0000 Subject: r17835: Fix Coverity bugs 306, 309, 310. Jeremy, you might want to look at the trans2 one. Volker (This used to be commit d727fc681c073a1b09accd31a07341b58e10eebb) --- source3/libaddns/dnssock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libaddns/dnssock.c') diff --git a/source3/libaddns/dnssock.c b/source3/libaddns/dnssock.c index 3d0991a1aa..d3223b9bd8 100644 --- a/source3/libaddns/dnssock.c +++ b/source3/libaddns/dnssock.c @@ -732,7 +732,7 @@ void DNSFreeSendBufferContext( HANDLE hSendBuffer ) pSendBufferContext = ( DNS_SENDBUFFER_CONTEXT * ) hSendBuffer; - if ( pSendBufferContext->pSendBuffer ) { + if ( pSendBufferContext && pSendBufferContext->pSendBuffer ) { DNSFreeMemory( pSendBufferContext->pSendBuffer ); } if ( pSendBufferContext ) { -- cgit From 2868e7f99b42c407fbe1a0fa482e70a436f16315 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 27 Aug 2006 16:14:31 +0000 Subject: r17851: Fix a warning & attempt to fix the Tru64 build (This used to be commit b05cac3cb5b35fa305f3d881012cc8e7eca87bd8) --- source3/libaddns/dnssock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libaddns/dnssock.c') diff --git a/source3/libaddns/dnssock.c b/source3/libaddns/dnssock.c index d3223b9bd8..ac66a6d1b4 100644 --- a/source3/libaddns/dnssock.c +++ b/source3/libaddns/dnssock.c @@ -238,7 +238,7 @@ static int32 DNSSelect( HANDLE hDNSHandle ) if ( !dwNumSockets ) { #ifndef WIN32 dwError = ETIMEDOUT; -#elif +#else dwError = WSAETIMEDOUT; #endif } -- cgit From c2aae726ea3f697c50f8d2304e2a9e69c56ab90f Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 17 Nov 2006 21:46:26 +0000 Subject: r19762: libaddns/*[ch] code fixes donated by Centeris Corporation (http://www.centeris.com/) under my copyright. * Rework error reporting to use DNS_ERROR instead of int32 * Convert memory allocation to use talloc() * Generalize the DNS request/response packet marshalling * Fix the secure update requests (This used to be commit c78798333616c3f823514df0f58da2eb3a30a988) --- source3/libaddns/dnssock.c | 771 +++++++++++---------------------------------- 1 file changed, 182 insertions(+), 589 deletions(-) (limited to 'source3/libaddns/dnssock.c') diff --git a/source3/libaddns/dnssock.c b/source3/libaddns/dnssock.c index ac66a6d1b4..597a7ebf07 100644 --- a/source3/libaddns/dnssock.c +++ b/source3/libaddns/dnssock.c @@ -26,88 +26,95 @@ #include "dns.h" #include +#include + +static int destroy_dns_connection(struct dns_connection *conn) +{ + return close(conn->s); +} /******************************************************************** ********************************************************************/ -static DNS_ERROR DNSTCPOpen( char *nameserver, HANDLE * phDNSServer ) +static DNS_ERROR dns_tcp_open( const char *nameserver, + TALLOC_CTX *mem_ctx, + struct dns_connection **result ) { - DNS_ERROR dwError = ERROR_DNS_INVALID_PARAMETER; - int sockServer; - unsigned long ulAddress; + uint32_t ulAddress; struct hostent *pHost; struct sockaddr_in s_in; - DNS_CONNECTION_CONTEXT *pDNSContext = NULL; + struct dns_connection *conn; + int res; - if ( (pDNSContext = TALLOC_P( NULL, DNS_CONNECTION_CONTEXT )) == NULL ) { + if (!(conn = talloc(mem_ctx, struct dns_connection))) { return ERROR_DNS_NO_MEMORY; } if ( (ulAddress = inet_addr( nameserver )) == INADDR_NONE ) { if ( (pHost = gethostbyname( nameserver )) == NULL ) { - dwError = ERROR_DNS_INVALID_NAME_SERVER; - BAIL_ON_DNS_ERROR( dwError ); + TALLOC_FREE(conn); + return ERROR_DNS_INVALID_NAME_SERVER; } memcpy( &ulAddress, pHost->h_addr, pHost->h_length ); } - if ( (sockServer = socket( PF_INET, SOCK_STREAM, 0 )) == INVALID_SOCKET ) { - dwError = ERROR_DNS_NO_MEMORY; - BAIL_ON_DNS_ERROR( dwError ); + conn->s = socket( PF_INET, SOCK_STREAM, 0 ); + if (conn->s == -1) { + TALLOC_FREE(conn); + return ERROR_DNS_CONNECTION_FAILED; } + talloc_set_destructor(conn, destroy_dns_connection); + s_in.sin_family = AF_INET; s_in.sin_addr.s_addr = ulAddress; s_in.sin_port = htons( DNS_TCP_PORT ); - if ( (connect( sockServer, (struct sockaddr*)&s_in, sizeof( s_in ))) == SOCKET_ERROR ) { - dwError = ERROR_DNS_CONNECTION_FAILED; - BAIL_ON_DNS_ERROR( dwError ); + res = connect(conn->s, (struct sockaddr*)&s_in, sizeof( s_in )); + if (res == -1) { + TALLOC_FREE(conn); + return ERROR_DNS_CONNECTION_FAILED; } - - pDNSContext->s = sockServer; - pDNSContext->hType = DNS_TCP; - - *phDNSServer = ( HANDLE ) pDNSContext; - dwError = ERROR_DNS_SUCCESS; + conn->hType = DNS_TCP; - return dwError; - -error: - TALLOC_FREE( pDNSContext ); - *phDNSServer = ( HANDLE ) NULL; - - return dwError; + *result = conn; + return ERROR_DNS_SUCCESS; } /******************************************************************** ********************************************************************/ -static DNS_ERROR DNSUDPOpen( char *nameserver, HANDLE * phDNSServer ) +static DNS_ERROR dns_udp_open( const char *nameserver, + TALLOC_CTX *mem_ctx, + struct dns_connection **result ) { - DNS_ERROR dwError = ERROR_DNS_INVALID_PARAMETER; - int SendSocket; unsigned long ulAddress; struct hostent *pHost; struct sockaddr_in RecvAddr; - DNS_CONNECTION_CONTEXT *pDNSContext = NULL; + struct dns_connection *conn; - if ( (pDNSContext = TALLOC_P( NULL, DNS_CONNECTION_CONTEXT )) == NULL ) { + if (!(conn = talloc(NULL, struct dns_connection))) { return ERROR_DNS_NO_MEMORY; } if ( (ulAddress = inet_addr( nameserver )) == INADDR_NONE ) { if ( (pHost = gethostbyname( nameserver )) == NULL ) { - dwError = ERROR_DNS_INVALID_NAME_SERVER; - BAIL_ON_DNS_ERROR( dwError ); + TALLOC_FREE(conn); + return ERROR_DNS_INVALID_NAME_SERVER; } memcpy( &ulAddress, pHost->h_addr, pHost->h_length ); } /* Create a socket for sending data */ - SendSocket = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP ); + conn->s = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP ); + if (conn->s == -1) { + TALLOC_FREE(conn); + return ERROR_DNS_CONNECTION_FAILED; + } + + talloc_set_destructor(conn, destroy_dns_connection); /* Set up the RecvAddr structure with the IP address of the receiver (in this example case "123.456.789.1") @@ -117,651 +124,237 @@ static DNS_ERROR DNSUDPOpen( char *nameserver, HANDLE * phDNSServer ) RecvAddr.sin_port = htons( DNS_UDP_PORT ); RecvAddr.sin_addr.s_addr = ulAddress; - pDNSContext->s = SendSocket; - pDNSContext->hType = DNS_UDP; - memcpy( &pDNSContext->RecvAddr, &RecvAddr, sizeof( struct sockaddr_in ) ); - - *phDNSServer = ( HANDLE ) pDNSContext; - - dwError = ERROR_DNS_SUCCESS; + conn->hType = DNS_UDP; + memcpy( &conn->RecvAddr, &RecvAddr, sizeof( struct sockaddr_in ) ); - return dwError; - -error: - TALLOC_FREE( pDNSContext ); - *phDNSServer = ( HANDLE ) NULL; - - return dwError; + *result = conn; + return ERROR_DNS_SUCCESS; } /******************************************************************** ********************************************************************/ -DNS_ERROR DNSOpen( char *nameserver, int32 dwType, HANDLE * phDNSServer ) +DNS_ERROR dns_open( const char *nameserver, int32 dwType, + TALLOC_CTX *mem_ctx, + struct dns_connection **conn ) { switch ( dwType ) { case DNS_TCP: - return DNSTCPOpen( nameserver, phDNSServer ); + return dns_tcp_open( nameserver, mem_ctx, conn ); case DNS_UDP: - return DNSUDPOpen( nameserver, phDNSServer ); + return dns_udp_open( nameserver, mem_ctx, conn ); } return ERROR_DNS_INVALID_PARAMETER; } -/******************************************************************** -********************************************************************/ - -static int32 DNSSendTCPRequest( HANDLE hDNSHandle, - uint8 * pDNSSendBuffer, - int32 dwBufferSize, int32 * pdwBytesSent ) +static DNS_ERROR write_all(int fd, uint8 *data, size_t len) { - int32 dwError = 0; - int32 dwBytesSent = 0; - DNS_CONNECTION_CONTEXT *pDNSContext = NULL; - + size_t total = 0; - pDNSContext = ( DNS_CONNECTION_CONTEXT * ) hDNSHandle; + while (total < len) { - dwBytesSent = send( pDNSContext->s, pDNSSendBuffer, dwBufferSize, 0 ); - if ( dwBytesSent == SOCKET_ERROR ) { - dwError = WSAGetLastError( ); - BAIL_ON_ERROR( dwError ); - } - - *pdwBytesSent = dwBytesSent; - - return dwError; + ssize_t ret = write(fd, data + total, len - total); - error: - *pdwBytesSent = 0; - return dwError; -} - -/******************************************************************** -********************************************************************/ + if (ret <= 0) { + /* + * EOF or error + */ + return ERROR_DNS_SOCKET_ERROR; + } -static int32 DNSSendUDPRequest( HANDLE hDNSHandle, - uint8 * pDNSSendBuffer, - int32 dwBufferSize, int32 * pdwBytesSent ) -{ - int32 dwError = 0; - int32 dwBytesSent = 0; - DNS_CONNECTION_CONTEXT *pDNSContext = NULL; - - pDNSContext = ( DNS_CONNECTION_CONTEXT * ) hDNSHandle; - - dwBytesSent = sendto( pDNSContext->s, - pDNSSendBuffer, - dwBufferSize, - 0, - ( struct sockaddr * ) & pDNSContext->RecvAddr, - sizeof( pDNSContext->RecvAddr ) - ); - if ( dwBytesSent == SOCKET_ERROR ) { - dwError = WSAGetLastError( ); - BAIL_ON_ERROR( dwError ); - } else { - *pdwBytesSent = dwBytesSent; + total += ret; } - return dwError; - - error: - *pdwBytesSent = 0; - return dwError; + return ERROR_DNS_SUCCESS; } -/******************************************************************** -********************************************************************/ - -static int32 DNSSelect( HANDLE hDNSHandle ) +static DNS_ERROR dns_send_tcp(struct dns_connection *conn, + const struct dns_buffer *buf) { - int32 dwError = 0; - fd_set rfds; - struct timeval tv; - int32 dwNumSockets = 0; - DNS_CONNECTION_CONTEXT *pDNSContext = NULL; - - pDNSContext = ( DNS_CONNECTION_CONTEXT * ) hDNSHandle; - FD_ZERO( &rfds ); - FD_SET( pDNSContext->s, &rfds ); - - tv.tv_sec = 10; - tv.tv_usec = 0; - dwNumSockets = select( pDNSContext->s + 1, &rfds, NULL, NULL, &tv ); - if ( dwNumSockets == SOCKET_ERROR ) { - dwError = WSAGetLastError( ); - BAIL_ON_ERROR( dwError ); - } - - if ( !dwNumSockets ) { -#ifndef WIN32 - dwError = ETIMEDOUT; -#else - dwError = WSAETIMEDOUT; -#endif - } + uint16 len = htons(buf->offset); + DNS_ERROR err; - error: + err = write_all(conn->s, (uint8 *)&len, sizeof(len)); + if (!ERR_DNS_IS_OK(err)) return err; - return dwError; + return write_all(conn->s, buf->data, buf->offset); } -/******************************************************************** -********************************************************************/ - -static int32 DNSTCPReceiveBufferContext( HANDLE hDNSHandle, - HANDLE hDNSRecvBuffer, int32 * pdwBytesRead ) +static DNS_ERROR dns_send_udp(struct dns_connection *conn, + const struct dns_buffer *buf) { - int32 dwError = 0; - int32 dwRead = 0; - int16 wBytesToRead = 0; - int16 wnBytesToRead = 0; - DNS_CONNECTION_CONTEXT *pDNSContext = NULL; - DNS_RECEIVEBUFFER_CONTEXT *pDNSRecvContext = NULL; - - pDNSContext = ( DNS_CONNECTION_CONTEXT * ) hDNSHandle; - pDNSRecvContext = ( DNS_RECEIVEBUFFER_CONTEXT * ) hDNSRecvBuffer; - - dwError = DNSSelect( hDNSHandle ); - BAIL_ON_ERROR( dwError ); - - dwRead = recv( pDNSContext->s, ( char * ) &wnBytesToRead, - sizeof( int16 ), 0 ); - if ( dwRead == SOCKET_ERROR ) { - dwError = WSAGetLastError( ); - BAIL_ON_ERROR( dwError ); - } - - wBytesToRead = ntohs( wnBytesToRead ); + ssize_t ret; - dwError = DNSSelect( hDNSHandle ); - BAIL_ON_ERROR( dwError ); + ret = sendto(conn->s, buf->data, buf->offset, 0, + (struct sockaddr *)&conn->RecvAddr, + sizeof(conn->RecvAddr)); - dwRead = recv( pDNSContext->s, - ( char * ) pDNSRecvContext->pRecvBuffer, wBytesToRead, - 0 ); - if ( dwRead == SOCKET_ERROR ) { - dwError = WSAGetLastError( ); - BAIL_ON_ERROR( dwError ); + if (ret != buf->offset) { + return ERROR_DNS_SOCKET_ERROR; } - pDNSRecvContext->dwBytesRecvd = dwRead; - - *pdwBytesRead = ( int32 ) dwRead; - - return dwError; - - error: - - return dwError; + return ERROR_DNS_SUCCESS; } -/******************************************************************** -********************************************************************/ - -static int32 DNSUDPReceiveBufferContext( HANDLE hDNSHandle, - HANDLE hDNSRecvBuffer, int32 * pdwBytesRead ) +DNS_ERROR dns_send(struct dns_connection *conn, const struct dns_buffer *buf) { - int32 dwError = 0; - int32 dwRead = 0; - DNS_CONNECTION_CONTEXT *pDNSContext = NULL; - DNS_RECEIVEBUFFER_CONTEXT *pDNSRecvContext = NULL; - - pDNSContext = ( DNS_CONNECTION_CONTEXT * ) hDNSHandle; - pDNSRecvContext = ( DNS_RECEIVEBUFFER_CONTEXT * ) hDNSRecvBuffer; - - dwError = DNSSelect( hDNSHandle ); - BAIL_ON_ERROR( dwError ); - - dwRead = recv( pDNSContext->s, - ( char * ) pDNSRecvContext->pRecvBuffer, 512, 0 ); - if ( dwRead == SOCKET_ERROR ) { - dwError = WSAGetLastError( ); - BAIL_ON_ERROR( dwError ); + if (conn->hType == DNS_TCP) { + return dns_send_tcp(conn, buf); } - pDNSRecvContext->dwBytesRecvd = dwRead; - - *pdwBytesRead = ( int32 ) dwRead; - - error: - - return dwError; -} - -/******************************************************************** -********************************************************************/ - -int32 DNSReceiveBufferContext( HANDLE hDNSHandle, - HANDLE hDNSRecvBuffer, int32 * pdwBytesRead ) -{ - int32 dwError = 0; - DNS_CONNECTION_CONTEXT *pDNSContext = NULL; - - pDNSContext = ( DNS_CONNECTION_CONTEXT * ) hDNSHandle; - - switch ( pDNSContext->hType ) { - case DNS_TCP: - dwError = - DNSTCPReceiveBufferContext( hDNSHandle, - hDNSRecvBuffer, - pdwBytesRead ); - break; - case DNS_UDP: - dwError = - DNSUDPReceiveBufferContext( hDNSHandle, - hDNSRecvBuffer, - pdwBytesRead ); - break; + if (conn->hType == DNS_UDP) { + return dns_send_udp(conn, buf); } - return dwError; -} - -/******************************************************************** -********************************************************************/ - -int32 DNSCreateSendBuffer( HANDLE * phDNSSendBuffer ) -{ - int32 dwError = 0; - DNS_SENDBUFFER_CONTEXT *pDNSContext = NULL; - uint8 *pSendBuffer = NULL; - - dwError = DNSAllocateMemory( sizeof( DNS_SENDBUFFER_CONTEXT ), - ( void * ) &pDNSContext ); - BAIL_ON_ERROR( dwError ); - - dwError = - DNSAllocateMemory( SENDBUFFER_SIZE, - ( void * ) &pSendBuffer ); - BAIL_ON_ERROR( dwError ); - - pDNSContext->pSendBuffer = pSendBuffer; - pDNSContext->dwBufferSize = SENDBUFFER_SIZE; - - /* We will offset into the buffer by 2 bytes - If we are doing a TCP write; we will fill in these - two bytes and send + 2 bytes - If we are doing a UDP write; we will start our send - +2 bytes and only send dwWritten; */ - - pDNSContext->dwBufferOffset += 2; - - *phDNSSendBuffer = ( HANDLE ) pDNSContext; - - return dwError; - error: - - if ( pSendBuffer ) { - DNSFreeMemory( pSendBuffer ); - } - if ( pDNSContext ) { - DNSFreeMemory( pDNSContext ); - } - *phDNSSendBuffer = ( HANDLE ) NULL; - - return dwError; + return ERROR_DNS_INVALID_PARAMETER; } - -/******************************************************************** -********************************************************************/ - -int32 DNSMarshallBuffer( HANDLE hDNSSendBuffer, - uint8 * pDNSSendBuffer, - int32 dwBufferSize, int32 * pdwBytesWritten ) +static DNS_ERROR read_all(int fd, uint8 *data, size_t len) { - int32 dwError = 0; - uint8 *pTemp = NULL; - DNS_SENDBUFFER_CONTEXT *pDNSContext = NULL; + size_t total = 0; -/* BugBug - we need to check for amount of space remaining in the -SendBuffer Context - if its insufficent, we want to realloc the -Buffer and copy the context; Right now the assumption is we have a big -enough buffer */ + while (total < len) { - pDNSContext = ( DNS_SENDBUFFER_CONTEXT * ) hDNSSendBuffer; + ssize_t ret = read(fd, data + total, len - total); - pTemp = pDNSContext->pSendBuffer + pDNSContext->dwBufferOffset; - - memcpy( pTemp, pDNSSendBuffer, dwBufferSize ); - - pDNSContext->dwBytesWritten += dwBufferSize; - pDNSContext->dwBufferOffset += dwBufferSize; + if (ret <= 0) { + /* + * EOF or error + */ + return ERROR_DNS_SOCKET_ERROR; + } - *pdwBytesWritten = dwBufferSize; + total += ret; + } - return dwError; + return ERROR_DNS_SUCCESS; } -/******************************************************************** -********************************************************************/ - -static int32 DNSTCPSendBufferContext( HANDLE hDNSServer, - HANDLE hSendBuffer, int32 * pdwBytesSent ) +static DNS_ERROR dns_receive_tcp(TALLOC_CTX *mem_ctx, + struct dns_connection *conn, + struct dns_buffer **presult) { - DNS_SENDBUFFER_CONTEXT *pSendBufferContext = NULL; - int32 dwError = 0; - int16 wBytesWritten = 0; - int16 wnBytesWritten = 0; - - pSendBufferContext = ( DNS_SENDBUFFER_CONTEXT * ) hSendBuffer; - - wBytesWritten = ( int16 ) pSendBufferContext->dwBytesWritten; - wnBytesWritten = htons( wBytesWritten ); - - memcpy( pSendBufferContext->pSendBuffer, &wnBytesWritten, - sizeof( int16 ) ); - - dwError = DNSSendTCPRequest( hDNSServer, - pSendBufferContext->pSendBuffer, - pSendBufferContext->dwBytesWritten + 2, - pdwBytesSent ); - BAIL_ON_ERROR( dwError ); - - error: - - return dwError; -} + struct dns_buffer *buf; + DNS_ERROR err; + uint16 len; -/******************************************************************** -********************************************************************/ - -static int32 DNSUDPSendBufferContext( HANDLE hDNSServer, - HANDLE hSendBuffer, int32 * pdwBytesSent ) -{ - DNS_SENDBUFFER_CONTEXT *pSendBufferContext = NULL; - int32 dwError = 0; + if (!(buf = TALLOC_ZERO_P(mem_ctx, struct dns_buffer))) { + return ERROR_DNS_NO_MEMORY; + } - pSendBufferContext = ( DNS_SENDBUFFER_CONTEXT * ) hSendBuffer; + err = read_all(conn->s, (uint8 *)&len, sizeof(len)); + if (!ERR_DNS_IS_OK(err)) { + return err; + } - /* Now remember to send 2 bytes ahead of pSendBuffer; because - we ignore the 2 bytes size field. */ + buf->size = ntohs(len); - dwError = DNSSendUDPRequest( hDNSServer, - pSendBufferContext->pSendBuffer + 2, - pSendBufferContext->dwBytesWritten, - pdwBytesSent ); - BAIL_ON_ERROR( dwError ); + if (!(buf->data = TALLOC_ARRAY(buf, uint8, buf->size))) { + TALLOC_FREE(buf); + return ERROR_DNS_NO_MEMORY; + } - error: + err = read_all(conn->s, buf->data, buf->size); + if (!ERR_DNS_IS_OK(err)) { + TALLOC_FREE(buf); + return err; + } - return dwError; + *presult = buf; + return ERROR_DNS_SUCCESS; } -/******************************************************************** -********************************************************************/ - -int32 DNSSendBufferContext( HANDLE hDNSServer, - HANDLE hSendBuffer, int32 * pdwBytesSent ) +static DNS_ERROR dns_receive_udp(TALLOC_CTX *mem_ctx, + struct dns_connection *conn, + struct dns_buffer **presult) { - DNS_CONNECTION_CONTEXT *pDNSContext = NULL; - int32 dwError = 0; - - pDNSContext = ( DNS_CONNECTION_CONTEXT * ) hDNSServer; - - switch ( pDNSContext->hType ) { - case DNS_TCP: - dwError = DNSTCPSendBufferContext( hDNSServer, - hSendBuffer, - pdwBytesSent ); - BAIL_ON_ERROR( dwError ); - break; + struct dns_buffer *buf; + ssize_t received; - case DNS_UDP: - dwError = DNSUDPSendBufferContext( hDNSServer, - hSendBuffer, - pdwBytesSent ); - BAIL_ON_ERROR( dwError ); - break; + if (!(buf = TALLOC_ZERO_P(mem_ctx, struct dns_buffer))) { + return ERROR_DNS_NO_MEMORY; } - error: - return dwError; -} - -/******************************************************************** -********************************************************************/ + /* + * UDP based DNS can only be 512 bytes + */ -int32 DNSDumpSendBufferContext( HANDLE hSendBuffer ) -{ - DNS_SENDBUFFER_CONTEXT *pSendBufferContext = NULL; - int32 dwError = 0; - int32 dwCurLine = 0; - int32 i = 0; - - pSendBufferContext = ( DNS_SENDBUFFER_CONTEXT * ) hSendBuffer; - printf( "\n" ); - printf( "Buffer Size is: %d\n", pSendBufferContext->dwBytesWritten ); - while ( i < pSendBufferContext->dwBytesWritten ) { - if ( ( i / 16 ) > dwCurLine ) { - printf( "\n" ); - dwCurLine++; - } - if ( ( i % 8 ) == 0 ) { - printf( " " ); - } - printf( "%.2x ", pSendBufferContext->pSendBuffer[i] ); - i++; + if (!(buf->data = TALLOC_ARRAY(buf, uint8, 512))) { + TALLOC_FREE(buf); + return ERROR_DNS_NO_MEMORY; } - return dwError; -} - -/******************************************************************** -********************************************************************/ -int32 DNSDumpRecvBufferContext( HANDLE hRecvBuffer ) -{ - DNS_RECEIVEBUFFER_CONTEXT *pRecvBufferContext = NULL; - int32 dwError = 0; - int32 dwCurLine = 0; - int32 i = 0; - - pRecvBufferContext = ( DNS_RECEIVEBUFFER_CONTEXT * ) hRecvBuffer; - - printf( "\n" ); - printf( "Buffer Size is: %d\n", pRecvBufferContext->dwBytesRecvd ); + received = recv(conn->s, (void *)buf->data, 512, 0); - while ( i < pRecvBufferContext->dwBytesRecvd ) { - if ( ( i / 16 ) > dwCurLine ) { - printf( "\n" ); - dwCurLine++; - } - if ( ( i % 8 ) == 0 ) { - printf( " " ); - } - printf( "%.2x ", pRecvBufferContext->pRecvBuffer[i] ); - i++; + if (received == -1) { + TALLOC_FREE(buf); + return ERROR_DNS_SOCKET_ERROR; } - return dwError; -} -/******************************************************************** -********************************************************************/ - -int32 DNSCreateReceiveBuffer( HANDLE * phDNSRecvBuffer ) -{ - int32 dwError = 0; - DNS_RECEIVEBUFFER_CONTEXT *pDNSContext = NULL; - uint8 *pRecvBuffer = NULL; - - dwError = DNSAllocateMemory( sizeof( DNS_RECEIVEBUFFER_CONTEXT ), - ( void * ) &pDNSContext ); - BAIL_ON_ERROR( dwError ); - - dwError = - DNSAllocateMemory( RECVBUFFER_SIZE, - ( void * ) &pRecvBuffer ); - BAIL_ON_ERROR( dwError ); - - pDNSContext->pRecvBuffer = pRecvBuffer; - pDNSContext->dwBufferSize = RECVBUFFER_SIZE; - - *phDNSRecvBuffer = ( HANDLE ) pDNSContext; - - return dwError; - - error: - - if ( pRecvBuffer ) { - DNSFreeMemory( pRecvBuffer ); - } - if ( pDNSContext ) { - DNSFreeMemory( pDNSContext ); + if (received > 512) { + TALLOC_FREE(buf); + return ERROR_DNS_BAD_RESPONSE; } - *phDNSRecvBuffer = ( HANDLE ) NULL; - return dwError; -} - -/******************************************************************** -********************************************************************/ - -int32 DNSUnmarshallBuffer( HANDLE hDNSRecvBuffer, - uint8 * pDNSRecvBuffer, - int32 dwBufferSize, int32 * pdwBytesRead ) -{ - int32 dwError = 0; - uint8 *pTemp = NULL; - DNS_RECEIVEBUFFER_CONTEXT *pDNSContext = NULL; - -/* BugBug - we need to check for amount of space remaining in the -SendBuffer Context - if its insufficent, we want to realloc the -Buffer and copy the context; Right now the assumption is we have a big -enough buffer */ - - pDNSContext = ( DNS_RECEIVEBUFFER_CONTEXT * ) hDNSRecvBuffer; - - pTemp = pDNSContext->pRecvBuffer + pDNSContext->dwBytesRead; - - memcpy( pDNSRecvBuffer, pTemp, dwBufferSize ); - - pDNSContext->dwBytesRead += dwBufferSize; - - *pdwBytesRead = dwBufferSize; + buf->size = received; + buf->offset = 0; - return dwError; + *presult = buf; + return ERROR_DNS_SUCCESS; } -/******************************************************************** -********************************************************************/ - -int32 DNSUnmarshallDomainNameAtOffset( HANDLE hRecvBuffer, - int16 wOffset, - DNS_DOMAIN_NAME ** ppDomainName ) +DNS_ERROR dns_receive(TALLOC_CTX *mem_ctx, struct dns_connection *conn, + struct dns_buffer **presult) { - int32 dwError = 0; - DNS_DOMAIN_LABEL *pLabel = NULL; - DNS_DOMAIN_LABEL *pLabelList = NULL; - DNS_DOMAIN_NAME *pDomainName = NULL; - char *pszLabel = NULL; - char szLabel[65]; - uint8 uLen = 0; - int32 dwCurrent = 0; - DNS_RECEIVEBUFFER_CONTEXT *pRecvContext = NULL; - - pRecvContext = ( DNS_RECEIVEBUFFER_CONTEXT * ) hRecvBuffer; - dwCurrent = wOffset; - - while ( 1 ) { - - memcpy( &uLen, pRecvContext->pRecvBuffer + dwCurrent, - sizeof( char ) ); - dwCurrent++; - - if ( uLen == 0 ) { - break; - } - - memset( szLabel, 0, 65 ); - memcpy( szLabel, pRecvContext->pRecvBuffer + dwCurrent, - uLen ); - dwCurrent += uLen; - - dwError = DNSAllocateString( szLabel, &pszLabel ); - BAIL_ON_ERROR( dwError ); - - dwError = - DNSAllocateMemory( sizeof( DNS_DOMAIN_LABEL ), - ( void * ) &pLabel ); - BAIL_ON_ERROR( dwError ); - - pLabel->pszLabel = pszLabel; - dwError = DNSAppendLabel( pLabelList, pLabel, &pLabelList ); - BAIL_ON_ERROR( dwError ); + if (conn->hType == DNS_TCP) { + return dns_receive_tcp(mem_ctx, conn, presult); } - dwError = - DNSAllocateMemory( sizeof( DNS_DOMAIN_NAME ), - ( void * ) &pDomainName ); - BAIL_ON_ERROR( dwError ); - pDomainName->pLabelList = pLabelList; - - *ppDomainName = pDomainName; - - return dwError; - - error: + if (conn->hType == DNS_UDP) { + return dns_receive_udp(mem_ctx, conn, presult); + } - *ppDomainName = NULL; - return dwError; + return ERROR_DNS_INVALID_PARAMETER; } -/******************************************************************** -********************************************************************/ - -int32 DNSReceiveBufferMoveBackIndex( HANDLE hRecvBuffer, int16 wOffset ) +DNS_ERROR dns_transaction(TALLOC_CTX *mem_ctx, struct dns_connection *conn, + const struct dns_request *req, + struct dns_request **resp) { - int32 dwError = 0; - DNS_RECEIVEBUFFER_CONTEXT *pDNSContext = NULL; - - pDNSContext = ( DNS_RECEIVEBUFFER_CONTEXT * ) hRecvBuffer; - pDNSContext->dwBytesRead -= wOffset; + struct dns_buffer *buf = NULL; + DNS_ERROR err; - return dwError; -} + err = dns_marshall_request(conn, req, &buf); + if (!ERR_DNS_IS_OK(err)) goto error; -/******************************************************************** -********************************************************************/ + err = dns_send(conn, buf); + if (!ERR_DNS_IS_OK(err)) goto error; + TALLOC_FREE(buf); -void DNSFreeSendBufferContext( HANDLE hSendBuffer ) -{ - DNS_SENDBUFFER_CONTEXT *pSendBufferContext = NULL; + err = dns_receive(mem_ctx, conn, &buf); + if (!ERR_DNS_IS_OK(err)) goto error; - pSendBufferContext = ( DNS_SENDBUFFER_CONTEXT * ) hSendBuffer; + err = dns_unmarshall_request(mem_ctx, buf, resp); - if ( pSendBufferContext && pSendBufferContext->pSendBuffer ) { - DNSFreeMemory( pSendBufferContext->pSendBuffer ); - } - if ( pSendBufferContext ) { - DNSFreeMemory( pSendBufferContext ); - } + error: + TALLOC_FREE(buf); + return err; } -/******************************************************************** -********************************************************************/ - -int32 DNSGetSendBufferContextSize( HANDLE hSendBuffer ) +DNS_ERROR dns_update_transaction(TALLOC_CTX *mem_ctx, + struct dns_connection *conn, + struct dns_update_request *up_req, + struct dns_update_request **up_resp) { - DNS_SENDBUFFER_CONTEXT *pSendBufferContext = NULL; + struct dns_request *resp; + DNS_ERROR err; - pSendBufferContext = ( DNS_SENDBUFFER_CONTEXT * ) hSendBuffer; + err = dns_transaction(mem_ctx, conn, dns_update2request(up_req), + &resp); - return ( pSendBufferContext->dwBytesWritten ); + if (!ERR_DNS_IS_OK(err)) return err; + *up_resp = dns_request2update(resp); + return ERROR_DNS_SUCCESS; } - -/******************************************************************** -********************************************************************/ - -uint8 *DNSGetSendBufferContextBuffer( HANDLE hSendBuffer ) -{ - DNS_SENDBUFFER_CONTEXT *pSendBufferContext = NULL; - - pSendBufferContext = ( DNS_SENDBUFFER_CONTEXT * ) hSendBuffer; - - return ( pSendBufferContext->pSendBuffer ); -} - -- cgit From 1beb6f6038560920dcb6944993bf1d28b238598a Mon Sep 17 00:00:00 2001 From: James Peach Date: Sun, 31 Dec 2006 06:45:24 +0000 Subject: r20427: Rename dnp_open. This conflicts with the dns_open symbol in libSystem on Mac OS X. (This used to be commit 585ee7f31d2fb169e9dc37fd786faa8049be5e52) --- source3/libaddns/dnssock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libaddns/dnssock.c') diff --git a/source3/libaddns/dnssock.c b/source3/libaddns/dnssock.c index 597a7ebf07..2f48df1bbd 100644 --- a/source3/libaddns/dnssock.c +++ b/source3/libaddns/dnssock.c @@ -134,7 +134,7 @@ static DNS_ERROR dns_udp_open( const char *nameserver, /******************************************************************** ********************************************************************/ -DNS_ERROR dns_open( const char *nameserver, int32 dwType, +DNS_ERROR dns_open_connection( const char *nameserver, int32 dwType, TALLOC_CTX *mem_ctx, struct dns_connection **conn ) { -- cgit From 19f85cd9b96f291600012354ab668dbb0043c814 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 2 Jan 2007 21:20:40 +0000 Subject: r20485: Add select with a 10 second timeout when reading DSN update responses. (This used to be commit cb6c6a49e257d60318101c897e8d2b86de08a846) --- source3/libaddns/dnssock.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) (limited to 'source3/libaddns/dnssock.c') diff --git a/source3/libaddns/dnssock.c b/source3/libaddns/dnssock.c index 2f48df1bbd..5dbedc4fd5 100644 --- a/source3/libaddns/dnssock.c +++ b/source3/libaddns/dnssock.c @@ -213,15 +213,29 @@ DNS_ERROR dns_send(struct dns_connection *conn, const struct dns_buffer *buf) static DNS_ERROR read_all(int fd, uint8 *data, size_t len) { size_t total = 0; + fd_set rfds; + struct timeval tv; while (total < len) { + ssize_t ret; + int fd_ready; + + FD_ZERO( &rfds ); + FD_SET( fd, &rfds ); + + /* 10 second timeout */ + tv.tv_sec = 10; + tv.tv_usec = 0; + + fd_ready = select( fd+1, &rfds, NULL, NULL, &tv ); + if ( fd_ready == 0 ) { + /* read timeout */ + return ERROR_DNS_SOCKET_ERROR; + } - ssize_t ret = read(fd, data + total, len - total); - + ret = read(fd, data + total, len - total); if (ret <= 0) { - /* - * EOF or error - */ + /* EOF or error */ return ERROR_DNS_SOCKET_ERROR; } -- cgit From be8b0685a55700c6bce3681734800ec6434b0364 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 30 Apr 2007 02:39:34 +0000 Subject: r22589: Make TALLOC_ARRAY consistent across all uses. Jeremy. (This used to be commit 8968808c3b5b0208cbad9ac92eaf948f2c546dd9) --- source3/libaddns/dnssock.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'source3/libaddns/dnssock.c') diff --git a/source3/libaddns/dnssock.c b/source3/libaddns/dnssock.c index 5dbedc4fd5..6ceefb4e32 100644 --- a/source3/libaddns/dnssock.c +++ b/source3/libaddns/dnssock.c @@ -264,9 +264,13 @@ static DNS_ERROR dns_receive_tcp(TALLOC_CTX *mem_ctx, buf->size = ntohs(len); - if (!(buf->data = TALLOC_ARRAY(buf, uint8, buf->size))) { - TALLOC_FREE(buf); - return ERROR_DNS_NO_MEMORY; + if (buf->size) { + if (!(buf->data = TALLOC_ARRAY(buf, uint8, buf->size))) { + TALLOC_FREE(buf); + return ERROR_DNS_NO_MEMORY; + } + } else { + buf->data = NULL; } err = read_all(conn->s, buf->data, buf->size); -- cgit From 674b835241c53af7d31af402bd900e95ac83fcca Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 03:52:17 +0000 Subject: r23799: updated old Franklin Street FSF addresses to new URL (This used to be commit 43cd589773148fe3d243892768ce187604dd0c33) --- source3/libaddns/dnssock.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'source3/libaddns/dnssock.c') diff --git a/source3/libaddns/dnssock.c b/source3/libaddns/dnssock.c index 6ceefb4e32..72bbf60d45 100644 --- a/source3/libaddns/dnssock.c +++ b/source3/libaddns/dnssock.c @@ -19,9 +19,7 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301 USA + License along with this library; if not, see . */ #include "dns.h" -- cgit From 7215b1f69aad2f12a8bc1e3647eaf0425d45f63b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 6 Mar 2008 11:42:48 +0100 Subject: Fix an uninitialized variable, Coverity ID 481 (This used to be commit 9e4f576abfdd5605f4db9bb87c22ec68c94ff850) --- source3/libaddns/dnssock.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libaddns/dnssock.c') diff --git a/source3/libaddns/dnssock.c b/source3/libaddns/dnssock.c index 72bbf60d45..7c8bd418e5 100644 --- a/source3/libaddns/dnssock.c +++ b/source3/libaddns/dnssock.c @@ -118,6 +118,7 @@ static DNS_ERROR dns_udp_open( const char *nameserver, the receiver (in this example case "123.456.789.1") and the specified port number. */ + ZERO_STRUCT(RecvAddr); RecvAddr.sin_family = AF_INET; RecvAddr.sin_port = htons( DNS_UDP_PORT ); RecvAddr.sin_addr.s_addr = ulAddress; -- cgit