|
@@ -170,10 +170,11 @@ static int get_dns_idx();
|
|
|
static int cache_find(const char *);
|
|
static int cache_find(const char *);
|
|
|
//static int dns_on_read(void *client_data, int idx, char *buf, int len);
|
|
//static int dns_on_read(void *client_data, int idx, char *buf, int len);
|
|
|
//static int dns_on_eof(void *client_data, int idx, int err, const char *errmsg);
|
|
//static int dns_on_eof(void *client_data, int idx, int err, const char *errmsg);
|
|
|
|
|
+static void dns_read(int idx, char*, int&, bool blocking = 0);
|
|
|
static void dns_on_read(int idx, char *buf, int atr);
|
|
static void dns_on_read(int idx, char *buf, int atr);
|
|
|
static void dns_on_eof(int idx);
|
|
static void dns_on_eof(int idx);
|
|
|
static const char *dns_next_server();
|
|
static const char *dns_next_server();
|
|
|
-static int parse_reply(char *response, size_t nbytes, const char* server_ip);
|
|
|
|
|
|
|
+static int parse_reply(char *response, size_t nbytes, const char* server_ip, bool blocking = 0);
|
|
|
|
|
|
|
|
interval_t async_lookup_timeout = 10;
|
|
interval_t async_lookup_timeout = 10;
|
|
|
interval_t async_server_timeout = 40;
|
|
interval_t async_server_timeout = 40;
|
|
@@ -285,6 +286,17 @@ static void async_timeout(void *client_data)
|
|
|
|
|
|
|
|
char s1_7[3] = "",s2_3[3] = "",s2_2[3] = "";
|
|
char s1_7[3] = "",s2_3[3] = "",s2_2[3] = "";
|
|
|
|
|
|
|
|
|
|
+static void free_query(dns_query_t*& q) {
|
|
|
|
|
+ if (q->ip)
|
|
|
|
|
+ free(q->ip);
|
|
|
|
|
+ if (q->answer)
|
|
|
|
|
+ delete q->answer;
|
|
|
|
|
+ if (q->query)
|
|
|
|
|
+ free(q->query);
|
|
|
|
|
+ free(q);
|
|
|
|
|
+ q = NULL;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
static dns_query_t *alloc_query(void *client_data, dns_callback_t callback, const char *query)
|
|
static dns_query_t *alloc_query(void *client_data, dns_callback_t callback, const char *query)
|
|
|
{
|
|
{
|
|
|
dns_query_t *q = (dns_query_t *) my_calloc(1, sizeof(*q));
|
|
dns_query_t *q = (dns_query_t *) my_calloc(1, sizeof(*q));
|
|
@@ -345,7 +357,7 @@ static int get_dns_idx()
|
|
|
return 1;
|
|
return 1;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-void egg_dns_send(char *query, int len)
|
|
|
|
|
|
|
+void egg_dns_send(char *query, int len, bool blocking)
|
|
|
{
|
|
{
|
|
|
if (dns_idx >= 0 && dcc[dns_idx].sock == -1) {
|
|
if (dns_idx >= 0 && dcc[dns_idx].sock == -1) {
|
|
|
lostdcc(dns_idx);
|
|
lostdcc(dns_idx);
|
|
@@ -362,6 +374,9 @@ void egg_dns_send(char *query, int len)
|
|
|
sdprintf("SETTING TIMEOUT to %d", async_server_timeout);
|
|
sdprintf("SETTING TIMEOUT to %d", async_server_timeout);
|
|
|
dcc[dns_idx].timeval = now;
|
|
dcc[dns_idx].timeval = now;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ if (blocking)
|
|
|
|
|
+ socket_set_nonblock(dcc[dns_idx].sock, 0);
|
|
|
if (write(dcc[dns_idx].sock, query, len) == -1) {
|
|
if (write(dcc[dns_idx].sock, query, len) == -1) {
|
|
|
;
|
|
;
|
|
|
}
|
|
}
|
|
@@ -378,7 +393,8 @@ dns_query_t *find_query(const char *host)
|
|
|
return NULL;
|
|
return NULL;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-static void dns_send_query(dns_query_t *q, int type = (DNS_LOOKUP_A|DNS_LOOKUP_AAAA))
|
|
|
|
|
|
|
+#define DEFAULT_DNS_TYPE (DNS_LOOKUP_A|DNS_LOOKUP_AAAA)
|
|
|
|
|
+static void dns_send_query(dns_query_t *q, int type = DEFAULT_DNS_TYPE, bool blocking = 0)
|
|
|
{
|
|
{
|
|
|
char buf[512] = "";
|
|
char buf[512] = "";
|
|
|
int len;
|
|
int len;
|
|
@@ -394,7 +410,7 @@ static void dns_send_query(dns_query_t *q, int type = (DNS_LOOKUP_A|DNS_LOOKUP_A
|
|
|
buf[len] = 0; len++; buf[len] = DNS_A; len++;
|
|
buf[len] = 0; len++; buf[len] = DNS_A; len++;
|
|
|
buf[len] = 0; len++; buf[len] = 1; len++;
|
|
buf[len] = 0; len++; buf[len] = 1; len++;
|
|
|
|
|
|
|
|
- egg_dns_send(buf, len);
|
|
|
|
|
|
|
+ egg_dns_send(buf, len, blocking);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#ifdef USE_IPV6
|
|
#ifdef USE_IPV6
|
|
@@ -406,7 +422,7 @@ static void dns_send_query(dns_query_t *q, int type = (DNS_LOOKUP_A|DNS_LOOKUP_A
|
|
|
buf[len] = 0; len++; buf[len] = DNS_AAAA; len++;
|
|
buf[len] = 0; len++; buf[len] = DNS_AAAA; len++;
|
|
|
buf[len] = 0; len++; buf[len] = 1; len++;
|
|
buf[len] = 0; len++; buf[len] = 1; len++;
|
|
|
|
|
|
|
|
- egg_dns_send(buf, len);
|
|
|
|
|
|
|
+ egg_dns_send(buf, len, blocking);
|
|
|
}
|
|
}
|
|
|
#endif
|
|
#endif
|
|
|
} else if (q->ip) {
|
|
} else if (q->ip) {
|
|
@@ -416,10 +432,15 @@ static void dns_send_query(dns_query_t *q, int type = (DNS_LOOKUP_A|DNS_LOOKUP_A
|
|
|
buf[len] = 0; len++; buf[len] = DNS_PTR; len++;
|
|
buf[len] = 0; len++; buf[len] = DNS_PTR; len++;
|
|
|
buf[len] = 0; len++; buf[len] = 1; len++;
|
|
buf[len] = 0; len++; buf[len] = 1; len++;
|
|
|
|
|
|
|
|
- egg_dns_send(buf, len);
|
|
|
|
|
|
|
+ egg_dns_send(buf, len, blocking);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+static void dns_send_query_blocking(dns_query_t* q, int type = DEFAULT_DNS_TYPE) {
|
|
|
|
|
+ dns_send_query(q, type, 1);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
/*
|
|
/*
|
|
|
void dns_resend_queries()
|
|
void dns_resend_queries()
|
|
|
{
|
|
{
|
|
@@ -505,11 +526,12 @@ int egg_dns_lookup(const char *host, interval_t timeout, dns_callback_t callback
|
|
|
return(q->id);
|
|
return(q->id);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-bd::Array<bd::String> dns_lookup_block(const char *host, interval_t timeout, void *client_data, int type)
|
|
|
|
|
|
|
+bd::Array<bd::String> dns_lookup_block(const char *host, interval_t timeout, int type)
|
|
|
{
|
|
{
|
|
|
|
|
+ bd::Array<bd::String> answer;
|
|
|
|
|
+
|
|
|
if (is_dotted_ip(host)) {
|
|
if (is_dotted_ip(host)) {
|
|
|
/* If it's already an ip, we're done. */
|
|
/* If it's already an ip, we're done. */
|
|
|
- bd::Array<bd::String> answer;
|
|
|
|
|
sdprintf("egg_dns_lookup(%s, %d): Already an ip.", host, timeout);
|
|
sdprintf("egg_dns_lookup(%s, %d): Already an ip.", host, timeout);
|
|
|
answer << host;
|
|
answer << host;
|
|
|
return answer;
|
|
return answer;
|
|
@@ -518,7 +540,6 @@ bd::Array<bd::String> dns_lookup_block(const char *host, interval_t timeout, voi
|
|
|
/* Ok, now see if it's in our host cache. */
|
|
/* Ok, now see if it's in our host cache. */
|
|
|
for (int i = 0; i < nhosts; i++) {
|
|
for (int i = 0; i < nhosts; i++) {
|
|
|
if (!strcasecmp(host, hosts[i].host)) {
|
|
if (!strcasecmp(host, hosts[i].host)) {
|
|
|
- bd::Array<bd::String> answer;
|
|
|
|
|
sdprintf("egg_dns_lookup(%s, %d): Found in hosts -> %s", host, timeout, hosts[i].ip);
|
|
sdprintf("egg_dns_lookup(%s, %d): Found in hosts -> %s", host, timeout, hosts[i].ip);
|
|
|
answer << hosts[i].ip;
|
|
answer << hosts[i].ip;
|
|
|
return answer;
|
|
return answer;
|
|
@@ -531,14 +552,46 @@ bd::Array<bd::String> dns_lookup_block(const char *host, interval_t timeout, voi
|
|
|
sdprintf("egg_dns_lookup(%s, %d): Found in cache -> %s", host, timeout, cache[cache_id].answer->join(',').c_str());
|
|
sdprintf("egg_dns_lookup(%s, %d): Found in cache -> %s", host, timeout, cache[cache_id].answer->join(',').c_str());
|
|
|
return *(cache[cache_id].answer);
|
|
return *(cache[cache_id].answer);
|
|
|
}
|
|
}
|
|
|
-#ifdef incomplete
|
|
|
|
|
/* Allocate our query struct. */
|
|
/* Allocate our query struct. */
|
|
|
- dns_query_t *q = alloc_query(client_data, callback, host);
|
|
|
|
|
|
|
+ dns_query_t *q = alloc_query(NULL, NULL, host);
|
|
|
|
|
|
|
|
- sdprintf("egg_dns_lookup(%s, %d) -> %d", host, timeout, q->id);
|
|
|
|
|
- dns_send_query(q, type);
|
|
|
|
|
- return(q->id);
|
|
|
|
|
-#endif
|
|
|
|
|
|
|
+ sdprintf("dns_lookup_block(%s, %d) -> %d", host, timeout, q->id);
|
|
|
|
|
+ dns_send_query_blocking(q, type);
|
|
|
|
|
+
|
|
|
|
|
+ char buf[512] = "";
|
|
|
|
|
+ int atr;
|
|
|
|
|
+ bool read_error = 0;
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ /* Now the key difference, call read() on the socket to block until it returns */
|
|
|
|
|
+ if (!setjmp(alarmret)) {
|
|
|
|
|
+read_more:
|
|
|
|
|
+ alarm(timeout);
|
|
|
|
|
+
|
|
|
|
|
+ dns_read(dns_idx, buf, atr, 1);
|
|
|
|
|
+ read_error = errno ? 1 : 0;
|
|
|
|
|
+
|
|
|
|
|
+ alarm(0);
|
|
|
|
|
+
|
|
|
|
|
+ if (!read_error) {
|
|
|
|
|
+ dcc[dns_idx].timeval = now;
|
|
|
|
|
+ if (parse_reply(buf, atr, dns_ip, 1)) {
|
|
|
|
|
+ dns_on_eof(dns_idx);
|
|
|
|
|
+ } else if (errno == EAGAIN) {
|
|
|
|
|
+ goto read_more;
|
|
|
|
|
+ } else if (q->answer) {
|
|
|
|
|
+ answer = *(q->answer);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (q)
|
|
|
|
|
+ free_query(q);
|
|
|
|
|
+
|
|
|
|
|
+ // Disable blocking on the dns socket.
|
|
|
|
|
+ socket_set_nonblock(dcc[dns_idx].sock, 1);
|
|
|
|
|
+
|
|
|
|
|
+ return answer;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/* Perform an async dns reverse lookup. This does ip -> host. For host -> ip
|
|
/* Perform an async dns reverse lookup. This does ip -> host. For host -> ip
|
|
@@ -614,10 +667,30 @@ sdprintf("reversed ipv6 ip: %s", q->ip);
|
|
|
return(q->id);
|
|
return(q->id);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-//static int dns_on_read(void *client_data, int idx, char *buf, int len)
|
|
|
|
|
-static void dns_on_read(int idx, char *buf, int atr)
|
|
|
|
|
|
|
+static void dns_read(int idx, char* buf, int& atr, bool blocking) {
|
|
|
|
|
+ atr = read(dcc[idx].sock, buf, 512);
|
|
|
|
|
+
|
|
|
|
|
+ if (atr == -1) {
|
|
|
|
|
+ if (errno == EAGAIN) {
|
|
|
|
|
+ do {
|
|
|
|
|
+ atr = read(dcc[idx].sock, buf, 512);
|
|
|
|
|
+ } while (errno == EAGAIN && blocking);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (atr == -1) {
|
|
|
|
|
+ dns_on_eof(idx);
|
|
|
|
|
+ errno = EPIPE;
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ sdprintf("SETTING TIMEOUT to 0: Received reply.");
|
|
|
|
|
+ dns_handler.timeout_val = 0;
|
|
|
|
|
+ errno = 0;
|
|
|
|
|
+ return;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+static void dns_on_read(int idx, char* buf, int atr)
|
|
|
{
|
|
{
|
|
|
- dcc[idx].timeval = now;
|
|
|
|
|
|
|
+ dcc[idx].timeval = now;
|
|
|
|
|
|
|
|
// if (resend_on_read) {
|
|
// if (resend_on_read) {
|
|
|
// resend_on_read = 0;
|
|
// resend_on_read = 0;
|
|
@@ -625,23 +698,13 @@ static void dns_on_read(int idx, char *buf, int atr)
|
|
|
// return;
|
|
// return;
|
|
|
// }
|
|
// }
|
|
|
|
|
|
|
|
- atr = read(dcc[idx].sock, buf, 512);
|
|
|
|
|
-
|
|
|
|
|
- if (atr == -1) {
|
|
|
|
|
- if (errno == EAGAIN)
|
|
|
|
|
- atr = read(dcc[idx].sock, buf, 512);
|
|
|
|
|
- if (atr == -1) {
|
|
|
|
|
- dns_on_eof(idx);
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- sdprintf("SETTING TIMEOUT to 0");
|
|
|
|
|
- dns_handler.timeout_val = 0;
|
|
|
|
|
|
|
+ dns_read(idx, buf, atr);
|
|
|
if (parse_reply(buf, atr, dns_ip))
|
|
if (parse_reply(buf, atr, dns_ip))
|
|
|
- dns_on_eof(idx);
|
|
|
|
|
|
|
+ dns_on_eof(idx);
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+
|
|
|
static void dns_on_eof(int idx)
|
|
static void dns_on_eof(int idx)
|
|
|
{
|
|
{
|
|
|
sdprintf("EOF on dns idx: %d sock: %d (%s)", idx, dcc[idx].sock, dcc[idx].host);
|
|
sdprintf("EOF on dns idx: %d sock: %d (%s)", idx, dcc[idx].sock, dcc[idx].host);
|
|
@@ -871,7 +934,7 @@ int egg_dns_cancel(int id, int issue_callback)
|
|
|
if (prev) prev->next = q->next;
|
|
if (prev) prev->next = q->next;
|
|
|
else query_head = q->next;
|
|
else query_head = q->next;
|
|
|
sdprintf("Cancelling query: %s", q->query);
|
|
sdprintf("Cancelling query: %s", q->query);
|
|
|
- if (issue_callback) {
|
|
|
|
|
|
|
+ if (issue_callback && q->callback) {
|
|
|
if (q->answer->size() > 0) {
|
|
if (q->answer->size() > 0) {
|
|
|
cache_add(q->query, *(q->answer), q->lowest_ttl);
|
|
cache_add(q->query, *(q->answer), q->lowest_ttl);
|
|
|
|
|
|
|
@@ -881,10 +944,7 @@ int egg_dns_cancel(int id, int issue_callback)
|
|
|
q->callback(q->id, q->client_data, q->query, empty);
|
|
q->callback(q->id, q->client_data, q->query, empty);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- if (q->ip)
|
|
|
|
|
- free(q->ip);
|
|
|
|
|
- free(q->query);
|
|
|
|
|
- free(q);
|
|
|
|
|
|
|
+ free_query(q);
|
|
|
return(0);
|
|
return(0);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -928,14 +988,13 @@ void print_reply(dns_rr_t &reply)
|
|
|
}
|
|
}
|
|
|
*/
|
|
*/
|
|
|
|
|
|
|
|
-static int parse_reply(char *response, size_t nbytes, const char* server_ip)
|
|
|
|
|
|
|
+static int parse_reply(char *response, size_t nbytes, const char* server_ip, bool blocking)
|
|
|
{
|
|
{
|
|
|
dns_header_t header;
|
|
dns_header_t header;
|
|
|
dns_query_t *q = NULL, *prev = NULL;
|
|
dns_query_t *q = NULL, *prev = NULL;
|
|
|
- dns_rr_t reply;
|
|
|
|
|
char result[512] = "";
|
|
char result[512] = "";
|
|
|
short rr;
|
|
short rr;
|
|
|
- int r = -1;
|
|
|
|
|
|
|
+ dns_rr_t reply;
|
|
|
unsigned const char *eop = (unsigned char *) response + nbytes;
|
|
unsigned const char *eop = (unsigned char *) response + nbytes;
|
|
|
unsigned char *ptr = (unsigned char *) response;
|
|
unsigned char *ptr = (unsigned char *) response;
|
|
|
int return_code = 0;
|
|
int return_code = 0;
|
|
@@ -984,6 +1043,7 @@ static int parse_reply(char *response, size_t nbytes, const char* server_ip)
|
|
|
sdprintf("Ignoring reply(%d) from %s: no recusion available.", header.id, server_ip);
|
|
sdprintf("Ignoring reply(%d) from %s: no recusion available.", header.id, server_ip);
|
|
|
return_code = 1; /* get a new server */
|
|
return_code = 1; /* get a new server */
|
|
|
q->remaining = 0; /* Force this query to be removed, any further answers are ignored */
|
|
q->remaining = 0; /* Force this query to be removed, any further answers are ignored */
|
|
|
|
|
+ errno = EACCES;
|
|
|
goto callback;
|
|
goto callback;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -992,9 +1052,11 @@ static int parse_reply(char *response, size_t nbytes, const char* server_ip)
|
|
|
switch (GET_RCODE(header.flags)) {
|
|
switch (GET_RCODE(header.flags)) {
|
|
|
case 1: /* Format error */
|
|
case 1: /* Format error */
|
|
|
sdprintf("Ignoring reply(%d) from %s: Format error.", header.id, server_ip);
|
|
sdprintf("Ignoring reply(%d) from %s: Format error.", header.id, server_ip);
|
|
|
|
|
+ errno = EINVAL;
|
|
|
break;
|
|
break;
|
|
|
case 2: /* Server error */
|
|
case 2: /* Server error */
|
|
|
sdprintf("Ignoring reply(%d) from %s: Server error.", header.id, server_ip);
|
|
sdprintf("Ignoring reply(%d) from %s: Server error.", header.id, server_ip);
|
|
|
|
|
+ errno = EINVAL;
|
|
|
return_code = 1; /* get a new server */
|
|
return_code = 1; /* get a new server */
|
|
|
q->remaining = 0; /* Force this query to be removed, any further answers are ignored */
|
|
q->remaining = 0; /* Force this query to be removed, any further answers are ignored */
|
|
|
break;
|
|
break;
|
|
@@ -1002,14 +1064,17 @@ static int parse_reply(char *response, size_t nbytes, const char* server_ip)
|
|
|
sdprintf("Ignoring reply(%d) from %s: NXDOMAIN.", header.id, server_ip);
|
|
sdprintf("Ignoring reply(%d) from %s: NXDOMAIN.", header.id, server_ip);
|
|
|
/* Ignore the incoming AAAA or A reply as it will still be NXDOMAIN */
|
|
/* Ignore the incoming AAAA or A reply as it will still be NXDOMAIN */
|
|
|
q->remaining = 0; /* Force this query to be removed, any further answers are ignored */
|
|
q->remaining = 0; /* Force this query to be removed, any further answers are ignored */
|
|
|
|
|
+ errno = ENOENT;
|
|
|
break;
|
|
break;
|
|
|
case 4:
|
|
case 4:
|
|
|
sdprintf("Ignoring reply(%d) from %s: Query not supported", header.id, server_ip);
|
|
sdprintf("Ignoring reply(%d) from %s: Query not supported", header.id, server_ip);
|
|
|
|
|
+ errno = EINVAL;
|
|
|
break;
|
|
break;
|
|
|
case 5:
|
|
case 5:
|
|
|
sdprintf("Ignoring reply(%d) from %s: REFUSED", header.id, server_ip);
|
|
sdprintf("Ignoring reply(%d) from %s: REFUSED", header.id, server_ip);
|
|
|
return_code = 1; /* get a new server */
|
|
return_code = 1; /* get a new server */
|
|
|
q->remaining = 0; /* Force this query to be removed, any further answers are ignored */
|
|
q->remaining = 0; /* Force this query to be removed, any further answers are ignored */
|
|
|
|
|
+ errno = EACCES;
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -1062,9 +1127,7 @@ static int parse_reply(char *response, size_t nbytes, const char* server_ip)
|
|
|
#endif /* USE_IPV6 */
|
|
#endif /* USE_IPV6 */
|
|
|
break;
|
|
break;
|
|
|
case DNS_PTR:
|
|
case DNS_PTR:
|
|
|
- r = my_dn_expand((const unsigned char *) response, eop, ptr, result, sizeof(result));
|
|
|
|
|
-
|
|
|
|
|
- if (r != -1 && result[0]) {
|
|
|
|
|
|
|
+ if ((my_dn_expand((const unsigned char *) response, eop, ptr, result, sizeof(result)) != -1) && result[0]) {
|
|
|
*(q->answer) << result;
|
|
*(q->answer) << result;
|
|
|
sdprintf("Reply(%d): %s. \t %d \t IN PTR \t %s", header.id, q->query, reply.ttl, result);
|
|
sdprintf("Reply(%d): %s. \t %d \t IN PTR \t %s", header.id, q->query, reply.ttl, result);
|
|
|
}
|
|
}
|
|
@@ -1084,7 +1147,13 @@ static int parse_reply(char *response, size_t nbytes, const char* server_ip)
|
|
|
|
|
|
|
|
callback:
|
|
callback:
|
|
|
/* Don't continue if we haven't gotten all expected replies. */
|
|
/* Don't continue if we haven't gotten all expected replies. */
|
|
|
- if (--q->remaining > 0) return 0;
|
|
|
|
|
|
|
+ if (--q->remaining > 0) {
|
|
|
|
|
+ sdprintf("Waiting on query(%d) for more replies.", header.id);
|
|
|
|
|
+ errno = EAGAIN;
|
|
|
|
|
+ return 0;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ errno = 0;
|
|
|
|
|
|
|
|
/* Ok, we have, so now issue the callback with the answers. */
|
|
/* Ok, we have, so now issue the callback with the answers. */
|
|
|
if (prev) prev->next = q->next;
|
|
if (prev) prev->next = q->next;
|
|
@@ -1093,16 +1162,15 @@ callback:
|
|
|
if (q->answer->size() > 0) {
|
|
if (q->answer->size() > 0) {
|
|
|
cache_add(q->query, *(q->answer), q->lowest_ttl);
|
|
cache_add(q->query, *(q->answer), q->lowest_ttl);
|
|
|
|
|
|
|
|
- q->callback(q->id, q->client_data, q->query, *(q->answer));
|
|
|
|
|
- } else {
|
|
|
|
|
|
|
+ if (q->callback)
|
|
|
|
|
+ q->callback(q->id, q->client_data, q->query, *(q->answer));
|
|
|
|
|
+ } else if (q->callback) {
|
|
|
bd::Array<bd::String> empty;
|
|
bd::Array<bd::String> empty;
|
|
|
q->callback(q->id, q->client_data, q->query, empty);
|
|
q->callback(q->id, q->client_data, q->query, empty);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- free(q->query);
|
|
|
|
|
- if (q->ip)
|
|
|
|
|
- free(q->ip);
|
|
|
|
|
- free(q);
|
|
|
|
|
|
|
+ if (!blocking)
|
|
|
|
|
+ free_query(q);
|
|
|
|
|
|
|
|
return return_code;
|
|
return return_code;
|
|
|
}
|
|
}
|