Simple wrapper for a DNS query
*********************************************************************/
+#define DNS_FAILED_WAITTIME 30
+
static NTSTATUS dns_send_req( TALLOC_CTX *ctx, const char *name, int q_type,
uint8 **buf, int *resp_length )
{
uint8 *buffer = NULL;
size_t buf_len;
int resp_len = NS_PACKETSZ;
-
+ static time_t last_dns_check = 0;
+ static NTSTATUS last_dns_status = NT_STATUS_OK;
+ time_t now = time(NULL);
+
+ /* Try to prevent bursts of DNS lookups if the server is down */
+
+ /* Protect against large clock changes */
+
+ if ( last_dns_check > now )
+ last_dns_check = 0;
+
+ /* IF we had a DNS timeout or a bad server and we are still
+ in the 30 second cache window, just return the previous
+ status and save the network timeout. */
+
+ if ( (NT_STATUS_EQUAL(last_dns_status,NT_STATUS_IO_TIMEOUT) ||
+ NT_STATUS_EQUAL(last_dns_status,NT_STATUS_CONNECTION_REFUSED)) &&
+ (last_dns_check+DNS_FAILED_WAITTIME) > now )
+ {
+ DEBUG(10,("last_dns_check: Returning cached status (%s)\n",
+ nt_errstr(last_dns_status) ));
+ return last_dns_status;
+ }
+
+ /* Send the Query */
do {
if ( buffer )
TALLOC_FREE( buffer );
buf_len = resp_len * sizeof(uint8);
- if ( (buffer = TALLOC_ARRAY(ctx, uint8, buf_len)) == NULL ) {
- DEBUG(0,("ads_dns_lookup_srv: talloc() failed!\n"));
- return NT_STATUS_NO_MEMORY;
+ if (buf_len) {
+ if ( (buffer = TALLOC_ARRAY(ctx, uint8, buf_len)) == NULL ) {
+ DEBUG(0,("ads_dns_lookup_srv: talloc() failed!\n"));
+ last_dns_status = NT_STATUS_NO_MEMORY;
+ last_dns_check = time(NULL);
+ return last_dns_status;
+ }
}
if ( (resp_len = res_query(name, C_IN, q_type, buffer, buf_len)) < 0 ) {
DEBUG(3,("ads_dns_lookup_srv: Failed to resolve %s (%s)\n", name, strerror(errno)));
TALLOC_FREE( buffer );
+ last_dns_status = NT_STATUS_UNSUCCESSFUL;
+
if (errno == ETIMEDOUT) {
- return NT_STATUS_IO_TIMEOUT;
+ last_dns_status = NT_STATUS_IO_TIMEOUT;
}
if (errno == ECONNREFUSED) {
- return NT_STATUS_CONNECTION_REFUSED;
+ last_dns_status = NT_STATUS_CONNECTION_REFUSED;
}
- return NT_STATUS_UNSUCCESSFUL;
+ last_dns_check = time(NULL);
+ return last_dns_status;
}
} while ( buf_len < resp_len && resp_len < MAX_DNS_PACKET_SIZE );
*buf = buffer;
*resp_length = resp_len;
- return NT_STATUS_OK;
+ last_dns_check = time(NULL);
+ last_dns_status = NT_STATUS_OK;
+ return last_dns_status;
}
/*********************************************************************
DEBUG(4,("ads_dns_lookup_srv: %d records returned in the answer section.\n",
answer_count));
- if ( (dcs = TALLOC_ZERO_ARRAY(ctx, struct dns_rr_srv, answer_count)) == NULL ) {
- DEBUG(0,("ads_dns_lookup_srv: talloc() failure for %d char*'s\n",
- answer_count));
- return NT_STATUS_NO_MEMORY;
+ if (answer_count) {
+ if ( (dcs = TALLOC_ZERO_ARRAY(ctx, struct dns_rr_srv, answer_count)) == NULL ) {
+ DEBUG(0,("ads_dns_lookup_srv: talloc() failure for %d char*'s\n",
+ answer_count));
+ return NT_STATUS_NO_MEMORY;
+ }
+ } else {
+ dcs = NULL;
}
/* now skip the header */
DEBUG(4,("ads_dns_lookup_ns: %d records returned in the answer section.\n",
answer_count));
- if ( (nsarray = TALLOC_ARRAY(ctx, struct dns_rr_ns, answer_count)) == NULL ) {
- DEBUG(0,("ads_dns_lookup_ns: talloc() failure for %d char*'s\n",
- answer_count));
- return NT_STATUS_NO_MEMORY;
+ if (answer_count) {
+ if ( (nsarray = TALLOC_ARRAY(ctx, struct dns_rr_ns, answer_count)) == NULL ) {
+ DEBUG(0,("ads_dns_lookup_ns: talloc() failure for %d char*'s\n",
+ answer_count));
+ return NT_STATUS_NO_MEMORY;
+ }
+ } else {
+ nsarray = NULL;
}
/* now skip the header */
/****************************************************************************
Store the AD client sitename.
We store indefinately as every new CLDAP query will re-write this.
- If the sitename is "Default-First-Site-Name" we don't store it
- as this isn't a valid DNS name.
****************************************************************************/
BOOL sitename_store(const char *realm, const char *sitename)
}
if (!realm || (strlen(realm) == 0)) {
- DEBUG(0,("no realm\n"));
+ DEBUG(0,("sitename_store: no realm\n"));
return False;
}
char *new_sitename;
if (!realm || (strlen(realm) == 0)) {
- DEBUG(0,("no realm\n"));
+ DEBUG(0,("stored_sitename_changed: no realm\n"));
return False;
}