diff options
Diffstat (limited to 'source3/libaddns/dnssock.c')
-rw-r--r-- | source3/libaddns/dnssock.c | 771 |
1 files changed, 182 insertions, 589 deletions
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 <sys/time.h> +#include <unistd.h> + +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 ); -} - |