X-Git-Url: https://git.reactos.org/?p=reactos.git;a=blobdiff_plain;f=reactos%2Flib%2Fdnsapi%2Fdnsapi%2Fquery.c;h=d8b7fae4d487d91cf603f8b6551a19eaac022946;hp=0806af1693bea6a3e7b3d4b27ae6ff449bd62ae1;hb=0c0ecd45ea61f80c7e254aa5ef307ee5ac189ddf;hpb=3ad6d76cf9058a75c84d295e5cce9e2aac132429 diff --git a/reactos/lib/dnsapi/dnsapi/query.c b/reactos/lib/dnsapi/dnsapi/query.c index 0806af1693b..d8b7fae4d48 100644 --- a/reactos/lib/dnsapi/dnsapi/query.c +++ b/reactos/lib/dnsapi/dnsapi/query.c @@ -8,13 +8,10 @@ * 12/15/03 -- Created */ -#include -#include -#include -#include -#include -#define NTOS_MODE_USER -#include +#include "precomp.h" + +#define NDEBUG +#include /* DnsQuery **************************** * Begin a DNS query, and allow the result to be placed in the application @@ -37,8 +34,10 @@ char *xstrsave(const char *str) { char *p; - p= RtlAllocateHeap( RtlGetProcessHeap(), 0, strlen(str)+1 ); - strcpy(p,str); + p = RtlAllocateHeap( RtlGetProcessHeap(), 0, strlen(str)+1 ); + if ( NULL != p ) { + strcpy(p,str); + } return p; } @@ -53,6 +52,8 @@ DNS_STATUS WINAPI DnsQuery_A int quflags = 0; int adns_error; adns_answer *answer; + LPSTR CurrentName; + unsigned CNameLoop; *QueryResultSet = 0; @@ -67,31 +68,78 @@ DNS_STATUS WINAPI DnsQuery_A return DnsIntTranslateAdnsToDNS_STATUS( adns_error ); } - adns_error = adns_synchronous( astate, - Name, - adns_r_addr, - quflags, - &answer ); + /* + * adns doesn't resolve chained CNAME records (a CNAME which points to + * another CNAME pointing to another... pointing to an A record), according + * to a mailing list thread the authors believe that chained CNAME records + * are invalid and the DNS entries should be fixed. That's a nice academic + * standpoint, but there certainly are chained CNAME records out there, + * even some fairly major ones (at the time of this writing + * download.mozilla.org is a chained CNAME). Everyone else seems to resolve + * these fine, so we should too. So we loop here to try to resolve CNAME + * chains ourselves. Of course, there must be a limit to protect against + * CNAME loops. + */ + +#define CNAME_LOOP_MAX 16 + + CurrentName = (LPSTR) Name; + for ( CNameLoop = 0; CNameLoop < CNAME_LOOP_MAX; CNameLoop++ ) { + adns_error = adns_synchronous( astate, + CurrentName, + adns_r_addr, + quflags, + &answer ); - if( adns_error != adns_s_ok ) { - adns_finish( astate ); - return DnsIntTranslateAdnsToDNS_STATUS( adns_error ); - } + if( adns_error != adns_s_ok ) { + adns_finish( astate ); + if ( CurrentName != Name ) { + RtlFreeHeap( CurrentName, 0, GetProcessHeap() ); + } + return DnsIntTranslateAdnsToDNS_STATUS( adns_error ); + } - if( answer && answer->rrs.addr ) { - *QueryResultSet = - (PDNS_RECORD)RtlAllocateHeap( RtlGetProcessHeap(), 0, - sizeof( DNS_RECORD ) ); - (*QueryResultSet)->pNext = NULL; - (*QueryResultSet)->wType = Type; - (*QueryResultSet)->pName = xstrsave( Name ); - (*QueryResultSet)->wDataLength = sizeof(DNS_A_DATA); - (*QueryResultSet)->Data.A.IpAddress = - answer->rrs.addr->addr.inet.sin_addr.s_addr; - adns_finish( astate ); - return ERROR_SUCCESS; - } else - return ERROR_FILE_NOT_FOUND; + if( answer && answer->rrs.addr ) { + if ( CurrentName != Name ) { + RtlFreeHeap( CurrentName, 0, GetProcessHeap() ); + } + *QueryResultSet = + (PDNS_RECORD)RtlAllocateHeap( RtlGetProcessHeap(), 0, + sizeof( DNS_RECORD ) ); + if ( NULL == *QueryResultSet ) { + adns_finish( astate ); + return ERROR_OUTOFMEMORY; + } + (*QueryResultSet)->pNext = NULL; + (*QueryResultSet)->wType = Type; + (*QueryResultSet)->wDataLength = sizeof(DNS_A_DATA); + (*QueryResultSet)->Data.A.IpAddress = + answer->rrs.addr->addr.inet.sin_addr.s_addr; + adns_finish( astate ); + (*QueryResultSet)->pName = xstrsave( Name ); + return NULL != (*QueryResultSet)->pName ? ERROR_SUCCESS : + ERROR_OUTOFMEMORY; + } + if ( NULL == answer || adns_s_prohibitedcname != answer->status || + NULL == answer->cname ) { + adns_finish( astate ); + if ( CurrentName != Name ) { + RtlFreeHeap( CurrentName, 0, GetProcessHeap() ); + } + return ERROR_FILE_NOT_FOUND; + } + if ( CurrentName != Name ) { + RtlFreeHeap( CurrentName, 0, GetProcessHeap() ); + } + CurrentName = xstrsave( answer->cname ); + if ( NULL == CurrentName ) { + adns_finish( astate ); + return ERROR_OUTOFMEMORY; + } + } + adns_finish( astate ); + RtlFreeHeap( CurrentName, 0, GetProcessHeap() ); + return ERROR_FILE_NOT_FOUND; default: return ERROR_OUTOFMEMORY; /* XXX arty: find a better error code. */ } @@ -119,7 +167,7 @@ DNS_STATUS WINAPI DnsQuery_W PIP4_ARRAY Servers, PDNS_RECORD *QueryResultSet, PVOID *Reserved ) { - int i; + UINT i; PCHAR Buffer; DNS_STATUS Status; PDNS_RECORD QueryResultWide; @@ -302,7 +350,7 @@ DNS_STATUS WINAPI DnsQuery_UTF8 } void DnsIntFreeRecordList( PDNS_RECORD ToDelete ) { - int i; + UINT i; PDNS_RECORD next = 0; while( ToDelete ) {