2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-29 05:28:00 +00:00

Fixed bug introduced when TCP mode added.

Now supports AXFR.
This commit is contained in:
Michael Sawyer 2000-04-20 20:55:45 +00:00
parent ec371edc34
commit ae72c54ef1
3 changed files with 124 additions and 82 deletions

View File

@ -56,8 +56,6 @@ extern int h_errno;
#include <dig/dig.h> #include <dig/dig.h>
#include <dig/printmsg.h> #include <dig/printmsg.h>
#define DEBUG
ISC_LIST(dig_lookup_t) lookup_list; ISC_LIST(dig_lookup_t) lookup_list;
ISC_LIST(dig_server_t) server_list; ISC_LIST(dig_server_t) server_list;
@ -215,6 +213,7 @@ parse_args(isc_boolean_t is_batchfile, int argc, char **argv) {
lookup->name=NULL; lookup->name=NULL;
lookup->timer = NULL; lookup->timer = NULL;
lookup->xfr_q = NULL; lookup->xfr_q = NULL;
lookup->doing_xfr = ISC_FALSE;
ISC_LIST_INIT(lookup->q); ISC_LIST_INIT(lookup->q);
ISC_LIST_APPEND(lookup_list, lookup, link); ISC_LIST_APPEND(lookup_list, lookup, link);
have_host = ISC_TRUE; have_host = ISC_TRUE;
@ -249,6 +248,7 @@ parse_args(isc_boolean_t is_batchfile, int argc, char **argv) {
lookup->name=NULL; lookup->name=NULL;
lookup->timer = NULL; lookup->timer = NULL;
lookup->xfr_q = NULL; lookup->xfr_q = NULL;
lookup->doing_xfr = ISC_FALSE;
ISC_LIST_INIT(lookup->q); ISC_LIST_INIT(lookup->q);
strcpy (lookup->textname,"."); strcpy (lookup->textname,".");
strcpy (lookup->rttext, "NS"); strcpy (lookup->rttext, "NS");
@ -265,7 +265,7 @@ setup_system() {
dig_server_t *srv; dig_server_t *srv;
port = 53; port = 53;
timeout = 5; timeout = 10;
id = getpid()<<8; id = getpid()<<8;
if (server_list.head == NULL) { if (server_list.head == NULL) {
@ -493,10 +493,16 @@ check_next_lookup (dig_lookup_t *lookup) {
dig_query_t *query; dig_query_t *query;
isc_boolean_t still_working=ISC_FALSE; isc_boolean_t still_working=ISC_FALSE;
#ifdef DEBUG
puts ("In check_next_lookup");
#endif
for (query = ISC_LIST_HEAD(lookup->q); for (query = ISC_LIST_HEAD(lookup->q);
query != NULL; query != NULL;
query = ISC_LIST_NEXT(query, link)) { query = ISC_LIST_NEXT(query, link)) {
if (query->working) { if (query->working) {
#ifdef DEBUG
puts ("Still have a worker.");
#endif
still_working=ISC_TRUE; still_working=ISC_TRUE;
} }
} }
@ -554,7 +560,6 @@ connect_timeout (isc_task_t *task, isc_event_t *event) {
isc_timer_detach (&lookup->timer); isc_timer_detach (&lookup->timer);
isc_buffer_free (&b); isc_buffer_free (&b);
isc_event_free (&event); isc_event_free (&event);
lookup->pending = ISC_FALSE;
} }
static void static void
@ -620,13 +625,13 @@ tcp_length_done (isc_task_t *task, isc_event_t *event) {
query); query);
check_result (result, "isc_socket_recvv"); check_result (result, "isc_socket_recvv");
#ifdef DEBUG #ifdef DEBUG
printf ("Resubmitted request with length %d\n",length); printf ("Resubmitted recv request with length %d\n",length);
#endif #endif
isc_event_free (&event); isc_event_free (&event);
} }
static void static void
launch_next_query(dig_query_t *query) { launch_next_query(dig_query_t *query, isc_boolean_t include_question) {
isc_result_t result; isc_result_t result;
if (!query->lookup->pending) { if (!query->lookup->pending) {
@ -640,15 +645,22 @@ launch_next_query(dig_query_t *query) {
return; return;
} }
isc_buffer_clear(&query->slbuf);
isc_buffer_clear(&query->lengthbuf);
isc_buffer_putuint16(&query->slbuf, query->lookup->sendbuf.used); isc_buffer_putuint16(&query->slbuf, query->lookup->sendbuf.used);
ISC_LIST_ENQUEUE(query->sendlist, &query->slbuf, link); ISC_LIST_ENQUEUE(query->sendlist, &query->slbuf, link);
ISC_LIST_ENQUEUE(query->sendlist, &query->lookup->sendbuf, link); if (include_question)
ISC_LIST_ENQUEUE(query->sendlist, &query->lookup->sendbuf,
link);
ISC_LIST_ENQUEUE(query->lengthlist, &query->lengthbuf, link); ISC_LIST_ENQUEUE(query->lengthlist, &query->lengthbuf, link);
result = isc_socket_recvv(query->sock, &query->lengthlist, 0, task, result = isc_socket_recvv(query->sock, &query->lengthlist, 0, task,
tcp_length_done, query); tcp_length_done, query);
check_result (result, "isc_socket_recvv"); check_result (result, "isc_socket_recvv");
sendcount++; sendcount++;
#ifdef DEBUG
puts ("Sending a request.");
#endif
result = isc_socket_sendv(query->sock, &query->sendlist, task, result = isc_socket_sendv(query->sock, &query->sendlist, task,
send_done, query); send_done, query);
check_result (result, "isc_socket_recvv"); check_result (result, "isc_socket_recvv");
@ -689,27 +701,24 @@ connect_done (isc_task_t *task, isc_event_t *event) {
(int)r.length, r.base, query->lookup->textname, (int)r.length, r.base, query->lookup->textname,
isc_result_totext(sevent->result)); isc_result_totext(sevent->result));
isc_buffer_free(&b); isc_buffer_free(&b);
check_next_lookup(query->lookup);
isc_event_free (&event);
check_next_lookup(query->lookup);
query->working = ISC_FALSE; query->working = ISC_FALSE;
query->waiting_connect = ISC_FALSE; query->waiting_connect = ISC_FALSE;
check_next_lookup(query->lookup);
isc_event_free (&event);
return; return;
} }
launch_next_query (query);
isc_event_free (&event); isc_event_free (&event);
launch_next_query (query, ISC_TRUE);
} }
static isc_boolean_t static isc_boolean_t
msg_contains_soa(dns_message_t *msg, dig_query_t *query) { msg_contains_soa(dns_message_t *msg, dig_query_t *query) {
isc_result_t result; isc_result_t result;
dns_rdataset_t *rd=NULL;
dns_name_t *name=NULL; dns_name_t *name=NULL;
result = dns_message_findname (msg, DNS_SECTION_ANSWER, result = dns_message_findname (msg, DNS_SECTION_ANSWER,
query->lookup->name, dns_rdatatype_soa, query->lookup->name, dns_rdatatype_soa,
dns_rdatatype_any, &name, &rd); 0, &name, NULL);
if (result == ISC_R_SUCCESS) { if (result == ISC_R_SUCCESS) {
#ifdef DEBUG #ifdef DEBUG
puts ("Found SOA"); puts ("Found SOA");
@ -717,7 +726,8 @@ msg_contains_soa(dns_message_t *msg, dig_query_t *query) {
return (ISC_TRUE); return (ISC_TRUE);
} else { } else {
#ifdef DEBUG #ifdef DEBUG
puts ("Didn't find SOA"); printf ("Didn't find SOA, result=%d:%s\n",
result, dns_result_totext(result));
#endif #endif
return (ISC_FALSE); return (ISC_FALSE);
} }
@ -752,6 +762,7 @@ recv_done (isc_task_t *task, isc_event_t *event) {
#endif #endif
query->working = ISC_FALSE; query->working = ISC_FALSE;
query->waiting_connect = ISC_FALSE; query->waiting_connect = ISC_FALSE;
cancel_lookup (query->lookup);
check_next_lookup(query->lookup); check_next_lookup(query->lookup);
isc_event_free (&event); isc_event_free (&event);
return; return;
@ -769,32 +780,47 @@ recv_done (isc_task_t *task, isc_event_t *event) {
check_result (result, "dns_message_parse"); check_result (result, "dns_message_parse");
if (query->lookup->xfr_q == NULL) if (query->lookup->xfr_q == NULL)
query->lookup->xfr_q = query; query->lookup->xfr_q = query;
if (query->lookup->xfr_q == query) if (query->lookup->xfr_q == query) {
printmessage(msg); if (query->first_soa_rcvd &&
/* XXXMWS Will need a more complex pending check once query->lookup->doing_xfr)
TCP mode comes in and we need to deal with printmessage(msg, ISC_FALSE);
XFR transfers. */ else
printmessage (msg, ISC_TRUE);
}
#ifdef DEBUG #ifdef DEBUG
if (query->lookup->pending) if (query->lookup->pending)
puts ("Still pending."); puts ("Still pending.");
#endif #endif
if (query->lookup->doing_xfr) { if (query->lookup->doing_xfr) {
if (msg_contains_soa(msg,query)) { if (!query->first_soa_rcvd) {
if (query->first_soa_rcvd) { if (!msg_contains_soa(msg,query)) {
cancel_lookup (query->lookup); puts ("; Transfer failed. Didn't start with SOA answer.");
query->lookup->pending = ISC_FALSE;
query->working = ISC_FALSE; query->working = ISC_FALSE;
check_next_lookup (query->lookup);
isc_event_free (&event);
return;
} }
else { else {
query->first_soa_rcvd = ISC_TRUE; query->first_soa_rcvd = ISC_TRUE;
launch_next_query(query); launch_next_query (query, ISC_FALSE);
}
}
else {
if (msg_contains_soa(msg, query)) {
cancel_lookup (query->lookup);
query->working = ISC_FALSE;
check_next_lookup (query->lookup);
isc_event_free (&event);
return;
}
else {
launch_next_query (query, ISC_FALSE);
} }
} else {
launch_next_query(query);
} }
} }
else { else {
query->lookup->pending = ISC_FALSE; query->working = ISC_FALSE;
cancel_lookup (query->lookup);
} }
if (!query->lookup->pending) { if (!query->lookup->pending) {
isc_buffer_init (&ab, abspace, MXNAME, isc_buffer_init (&ab, abspace, MXNAME,

View File

@ -20,6 +20,6 @@
#include <dns/message.h> #include <dns/message.h>
isc_result_t printmessage(dns_message_t *message); isc_result_t printmessage(dns_message_t *message, isc_boolean_t headers);
#endif /* TEST_PRINTMSG_H */ #endif /* TEST_PRINTMSG_H */

View File

@ -81,7 +81,8 @@ static char *rcodetext[] = {
}; };
static isc_result_t static isc_result_t
printsection(dns_message_t *msg, dns_section_t sectionid, char *section_name) printsection(dns_message_t *msg, dns_section_t sectionid, char *section_name,
isc_boolean_t headers)
{ {
dns_name_t *name, *print_name; dns_name_t *name, *print_name;
dns_rdataset_t *rdataset; dns_rdataset_t *rdataset;
@ -98,7 +99,8 @@ printsection(dns_message_t *msg, dns_section_t sectionid, char *section_name)
else else
no_rdata = ISC_FALSE; no_rdata = ISC_FALSE;
printf(";; %s SECTION:\n", section_name); if (headers)
printf(";; %s SECTION:\n", section_name);
dns_name_init(&empty_name, NULL); dns_name_init(&empty_name, NULL);
@ -134,7 +136,10 @@ printsection(dns_message_t *msg, dns_section_t sectionid, char *section_name)
#endif #endif
} }
isc_buffer_used(&target, &r); isc_buffer_used(&target, &r);
printf("%.*s", (int)r.length, (char *)r.base); if (no_rdata)
printf(";%.*s", (int)r.length, (char *)r.base);
else
printf("%.*s", (int)r.length, (char *)r.base);
result = dns_message_nextname(msg, sectionid); result = dns_message_nextname(msg, sectionid);
if (result == ISC_R_NOMORE) if (result == ISC_R_NOMORE)
@ -148,7 +153,7 @@ printsection(dns_message_t *msg, dns_section_t sectionid, char *section_name)
static isc_result_t static isc_result_t
printrdata(dns_message_t *msg, dns_rdataset_t *rdataset, dns_name_t *owner, printrdata(dns_message_t *msg, dns_rdataset_t *rdataset, dns_name_t *owner,
char *set_name) char *set_name, isc_boolean_t headers)
{ {
isc_buffer_t target; isc_buffer_t target;
isc_result_t result; isc_result_t result;
@ -156,7 +161,8 @@ printrdata(dns_message_t *msg, dns_rdataset_t *rdataset, dns_name_t *owner,
char t[4096]; char t[4096];
UNUSED(msg); UNUSED(msg);
printf(";; %s SECTION:\n", set_name); if (headers)
printf(";; %s SECTION:\n", set_name);
isc_buffer_init(&target, t, sizeof t, ISC_BUFFERTYPE_TEXT); isc_buffer_init(&target, t, sizeof t, ISC_BUFFERTYPE_TEXT);
@ -171,7 +177,7 @@ printrdata(dns_message_t *msg, dns_rdataset_t *rdataset, dns_name_t *owner,
} }
isc_result_t isc_result_t
printmessage(dns_message_t *msg) { printmessage(dns_message_t *msg, isc_boolean_t headers) {
isc_boolean_t did_flag = ISC_FALSE; isc_boolean_t did_flag = ISC_FALSE;
isc_result_t result; isc_result_t result;
dns_rdataset_t *opt, *tsig; dns_rdataset_t *opt, *tsig;
@ -179,43 +185,45 @@ printmessage(dns_message_t *msg) {
result = ISC_R_SUCCESS; result = ISC_R_SUCCESS;
printf(";; ->>HEADER<<- opcode: %s, status: %s, id: %u\n", if (headers) {
opcodetext[msg->opcode], rcodetext[msg->rcode], msg->id); printf(";; ->>HEADER<<- opcode: %s, status: %s, id: %u\n",
opcodetext[msg->opcode], rcodetext[msg->rcode],
printf(";; flags: "); msg->id);
if ((msg->flags & DNS_MESSAGEFLAG_QR) != 0) { printf(";; flags: ");
printf("qr"); if ((msg->flags & DNS_MESSAGEFLAG_QR) != 0) {
did_flag = ISC_TRUE; printf("qr");
did_flag = ISC_TRUE;
}
if ((msg->flags & DNS_MESSAGEFLAG_AA) != 0) {
printf("%saa", did_flag ? " " : "");
did_flag = ISC_TRUE;
}
if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
printf("%stc", did_flag ? " " : "");
did_flag = ISC_TRUE;
}
if ((msg->flags & DNS_MESSAGEFLAG_RD) != 0) {
printf("%srd", did_flag ? " " : "");
did_flag = ISC_TRUE;
}
if ((msg->flags & DNS_MESSAGEFLAG_RA) != 0) {
printf("%sra", did_flag ? " " : "");
did_flag = ISC_TRUE;
}
if ((msg->flags & DNS_MESSAGEFLAG_AD) != 0) {
printf("%sad", did_flag ? " " : "");
did_flag = ISC_TRUE;
}
if ((msg->flags & DNS_MESSAGEFLAG_CD) != 0) {
printf("%scd", did_flag ? " " : "");
did_flag = ISC_TRUE;
}
printf("; QUERY: %u, ANSWER: %u, AUTHORITY: %u, ADDITIONAL: %u\n",
msg->counts[DNS_SECTION_QUESTION],
msg->counts[DNS_SECTION_ANSWER],
msg->counts[DNS_SECTION_AUTHORITY],
msg->counts[DNS_SECTION_ADDITIONAL]);
} }
if ((msg->flags & DNS_MESSAGEFLAG_AA) != 0) {
printf("%saa", did_flag ? " " : "");
did_flag = ISC_TRUE;
}
if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
printf("%stc", did_flag ? " " : "");
did_flag = ISC_TRUE;
}
if ((msg->flags & DNS_MESSAGEFLAG_RD) != 0) {
printf("%srd", did_flag ? " " : "");
did_flag = ISC_TRUE;
}
if ((msg->flags & DNS_MESSAGEFLAG_RA) != 0) {
printf("%sra", did_flag ? " " : "");
did_flag = ISC_TRUE;
}
if ((msg->flags & DNS_MESSAGEFLAG_AD) != 0) {
printf("%sad", did_flag ? " " : "");
did_flag = ISC_TRUE;
}
if ((msg->flags & DNS_MESSAGEFLAG_CD) != 0) {
printf("%scd", did_flag ? " " : "");
did_flag = ISC_TRUE;
}
printf("; QUERY: %u, ANSWER: %u, AUTHORITY: %u, ADDITIONAL: %u\n",
msg->counts[DNS_SECTION_QUESTION],
msg->counts[DNS_SECTION_ANSWER],
msg->counts[DNS_SECTION_AUTHORITY],
msg->counts[DNS_SECTION_ADDITIONAL]);
opt = dns_message_getopt(msg); opt = dns_message_getopt(msg);
if (opt != NULL) if (opt != NULL)
printf(";; EDNS: version: %u, udp=%u\n", printf(";; EDNS: version: %u, udp=%u\n",
@ -226,39 +234,47 @@ printmessage(dns_message_t *msg) {
tsig = dns_message_gettsig(msg, &tsigname); tsig = dns_message_gettsig(msg, &tsigname);
if (tsig != NULL) if (tsig != NULL)
printf(";; PSEUDOSECTIONS: TSIG\n"); printf(";; PSEUDOSECTIONS: TSIG\n");
if (! ISC_LIST_EMPTY(msg->sections[DNS_SECTION_QUESTION])) { if (! ISC_LIST_EMPTY(msg->sections[DNS_SECTION_QUESTION]) &&
headers ) {
printf("\n"); printf("\n");
result = printsection(msg, DNS_SECTION_QUESTION, "QUESTION"); result = printsection(msg, DNS_SECTION_QUESTION, "QUESTION",
ISC_TRUE);
if (result != ISC_R_SUCCESS) if (result != ISC_R_SUCCESS)
return (result); return (result);
} }
if (! ISC_LIST_EMPTY(msg->sections[DNS_SECTION_ANSWER])) { if (! ISC_LIST_EMPTY(msg->sections[DNS_SECTION_ANSWER])) {
printf("\n"); if (headers)
result = printsection(msg, DNS_SECTION_ANSWER, "ANSWER"); printf("\n");
result = printsection(msg, DNS_SECTION_ANSWER, "ANSWER",
headers);
if (result != ISC_R_SUCCESS) if (result != ISC_R_SUCCESS)
return (result); return (result);
} }
if (! ISC_LIST_EMPTY(msg->sections[DNS_SECTION_AUTHORITY])) { if (! ISC_LIST_EMPTY(msg->sections[DNS_SECTION_AUTHORITY]) &&
headers ) {
printf("\n"); printf("\n");
result = printsection(msg, DNS_SECTION_AUTHORITY, "AUTHORITY"); result = printsection(msg, DNS_SECTION_AUTHORITY, "AUTHORITY",
ISC_TRUE);
if (result != ISC_R_SUCCESS) if (result != ISC_R_SUCCESS)
return (result); return (result);
} }
if (! ISC_LIST_EMPTY(msg->sections[DNS_SECTION_ADDITIONAL])) { if (! ISC_LIST_EMPTY(msg->sections[DNS_SECTION_ADDITIONAL]) &&
headers ) {
printf("\n"); printf("\n");
result = printsection(msg, DNS_SECTION_ADDITIONAL, result = printsection(msg, DNS_SECTION_ADDITIONAL,
"ADDITIONAL"); "ADDITIONAL", ISC_TRUE);
if (result != ISC_R_SUCCESS) if (result != ISC_R_SUCCESS)
return (result); return (result);
} }
if (tsig != NULL) { if ((tsig != NULL) && headers) {
printf("\n"); printf("\n");
result = printrdata(msg, tsig, tsigname, result = printrdata(msg, tsig, tsigname,
"PSEUDOSECTION TSIG"); "PSEUDOSECTION TSIG", ISC_TRUE);
if (result != ISC_R_SUCCESS) if (result != ISC_R_SUCCESS)
return (result); return (result);
} }
printf("\n"); if (headers)
printf("\n");
return (result); return (result);
} }