void compare(struct dns_info *d1, struct dns_info *d2) { ldns_pkt *p1, *p2, *pq; bool diff = false; char *pstr1, *pstr2; struct timeval now; char *compare_result; size_t file_nr; gettimeofday(&now, NULL); if (verbosity > 0) { printf("Id: %u\n", (unsigned int) d1->seq); } if (strcmp(d1->qdata, d2->qdata) != 0) { fprintf(stderr, "Query differs!\n"); fprintf(stdout, "q: %d:%d\n%s\n%s\n%s\n", (int)d1->seq, (int)d2->seq, d1->qdata, d1->qdata, d2->qdata); } else { if (strcmp(d1->adata, d2->adata) != 0) { if (advanced_match) { /* try to read the packet and sort the sections */ p1 = read_hex_pkt(d1->adata); p2 = read_hex_pkt(d2->adata); if (p1) { ldns_pkt_set_timestamp(p1, now); } if (p2) { ldns_pkt_set_timestamp(p2, now); } if (p1 && ldns_pkt_qdcount(p1) > 0) { ldns_rr_list2canonical(ldns_pkt_question(p1)); ldns_rr_list_sort(ldns_pkt_question(p1)); } if (p1 && ldns_pkt_ancount(p1) > 0) { ldns_rr_list2canonical(ldns_pkt_answer(p1)); ldns_rr_list_sort(ldns_pkt_answer(p1)); } if (p1 && ldns_pkt_nscount(p1) > 0) { ldns_rr_list2canonical(ldns_pkt_authority(p1)); ldns_rr_list_sort(ldns_pkt_authority(p1)); } if (p1 && ldns_pkt_arcount(p1) > 0) { ldns_rr_list2canonical(ldns_pkt_additional(p1)); ldns_rr_list_sort(ldns_pkt_additional(p1)); } if (p2 && ldns_pkt_qdcount(p2) > 0) { ldns_rr_list2canonical(ldns_pkt_question(p2)); ldns_rr_list_sort(ldns_pkt_question(p2)); } if (p2 && ldns_pkt_ancount(p2) > 0) { ldns_rr_list2canonical(ldns_pkt_answer(p2)); ldns_rr_list_sort(ldns_pkt_answer(p2)); } if (p2 && ldns_pkt_nscount(p2) > 0) { ldns_rr_list2canonical(ldns_pkt_authority(p2)); ldns_rr_list_sort(ldns_pkt_authority(p2)); } if (p2 && ldns_pkt_arcount(p2) > 0) { ldns_rr_list2canonical(ldns_pkt_additional(p2)); ldns_rr_list_sort(ldns_pkt_additional(p2)); } /* simply do string comparison first */ pstr1 = ldns_pkt2str(p1); pstr2 = ldns_pkt2str(p2); if ((!p1 && !p2) || strcmp(pstr1, pstr2) != 0) { /* okay strings still differ, get the query and do a match for the match files */ pq = read_hex_pkt(d1->qdata); compare_result = compare_to_file(pq, p1, p2); if (compare_result != NULL) { /*fprintf(stderr, compare_result);*/ if (compare_result[strlen(compare_result)-1] == '\n') { compare_result[strlen(compare_result)-1] = 0; } file_nr = add_known_difference(compare_result); if (store_known_differences) { fprintf(known_differences[file_nr].file, "q: %d:%d\n%s\n%s\n%s\n", (int)d1->seq, (int)d2->seq, d1->qdata, d1->adata, d2->adata); } free(compare_result); diff = false; } else { diff=false; printf("Error: Unknown difference in packet number %u:\n", (unsigned int) total_nr_of_packets); ldns_pkt_print(stdout, pq); printf("\n"); ldns_pkt_print(stdout, p1); printf("\n"); ldns_pkt_print(stdout, p2); printf("Quitting at packet %u\n", (unsigned int) d1->seq); exit(1); } ldns_pkt_free(pq); } else { sames++; } if (diff) { if (show_originals) { fprintf(stdout, "%d:%d\n%s\n%s\n%s\n", (int)d1->seq, (int)d2->seq, d1->qdata, d1->adata, d2->adata); } else { fprintf(stdout, "%d:%d\n", (int)d1->seq, (int)d2->seq); if (!dump_hex(stdout, p1)) { fprintf(stdout, "%s", d1->adata); } fprintf(stdout, "\n"); if (!dump_hex(stdout, p2)) { fprintf(stdout, "%s", d2->adata); } fprintf(stdout, "\n"); } } LDNS_FREE(pstr1); LDNS_FREE(pstr2); ldns_pkt_free(p1); ldns_pkt_free(p2); } else { fprintf(stdout, "%d:%d\n%s\n%s\n%s\n", (int)d1->seq, (int)d2->seq, d1->qdata, d1->adata, d2->adata); } } else { sames++; bytesames++; } } }
ldns_status ldns_send_buffer(ldns_pkt **result, ldns_resolver *r, ldns_buffer *qb, ldns_rdf *tsig_mac) { uint8_t i; struct sockaddr_storage *src = NULL; size_t src_len; struct sockaddr_storage *ns; size_t ns_len; struct timeval tv_s; struct timeval tv_e; ldns_rdf **ns_array; size_t *rtt; ldns_pkt *reply; bool all_servers_rtt_inf; uint8_t retries; uint8_t *reply_bytes = NULL; size_t reply_size = 0; ldns_status status, send_status; assert(r != NULL); status = LDNS_STATUS_OK; rtt = ldns_resolver_rtt(r); ns_array = ldns_resolver_nameservers(r); reply = NULL; ns_len = 0; all_servers_rtt_inf = true; if (ldns_resolver_random(r)) { ldns_resolver_nameservers_randomize(r); } if(ldns_resolver_source(r)) { src = ldns_rdf2native_sockaddr_storage_port( ldns_resolver_source(r), 0, &src_len); } /* loop through all defined nameservers */ for (i = 0; i < ldns_resolver_nameserver_count(r); i++) { if (rtt[i] == LDNS_RESOLV_RTT_INF) { /* not reachable nameserver! */ continue; } /* maybe verbosity setting? printf("Sending to "); ldns_rdf_print(stdout, ns_array[i]); printf("\n"); */ ns = ldns_rdf2native_sockaddr_storage(ns_array[i], ldns_resolver_port(r), &ns_len); #ifndef S_SPLINT_S if ((ns->ss_family == AF_INET) && (ldns_resolver_ip6(r) == LDNS_RESOLV_INET6)) { /* not reachable */ LDNS_FREE(ns); continue; } if ((ns->ss_family == AF_INET6) && (ldns_resolver_ip6(r) == LDNS_RESOLV_INET)) { /* not reachable */ LDNS_FREE(ns); continue; } #endif all_servers_rtt_inf = false; gettimeofday(&tv_s, NULL); send_status = LDNS_STATUS_ERR; /* reply_bytes implicitly handles our error */ if (ldns_resolver_usevc(r)) { for (retries = ldns_resolver_retry(r); retries > 0; retries--) { send_status = ldns_tcp_send_from(&reply_bytes, qb, ns, (socklen_t)ns_len, src, (socklen_t)src_len, ldns_resolver_timeout(r), &reply_size); if (send_status == LDNS_STATUS_OK) { break; } } } else { for (retries = ldns_resolver_retry(r); retries > 0; retries--) { /* ldns_rdf_print(stdout, ns_array[i]); */ send_status = ldns_udp_send_from(&reply_bytes, qb, ns, (socklen_t)ns_len, src, (socklen_t)src_len, ldns_resolver_timeout(r), &reply_size); if (send_status == LDNS_STATUS_OK) { break; } } } if (send_status != LDNS_STATUS_OK) { ldns_resolver_set_nameserver_rtt(r, i, LDNS_RESOLV_RTT_INF); status = send_status; } /* obey the fail directive */ if (!reply_bytes) { /* the current nameserver seems to have a problem, blacklist it */ if (ldns_resolver_fail(r)) { LDNS_FREE(ns); return LDNS_STATUS_ERR; } else { LDNS_FREE(ns); continue; } } status = ldns_wire2pkt(&reply, reply_bytes, reply_size); if (status != LDNS_STATUS_OK) { LDNS_FREE(reply_bytes); LDNS_FREE(ns); return status; } LDNS_FREE(ns); gettimeofday(&tv_e, NULL); if (reply) { ldns_pkt_set_querytime(reply, (uint32_t) ((tv_e.tv_sec - tv_s.tv_sec) * 1000) + (tv_e.tv_usec - tv_s.tv_usec) / 1000); ldns_pkt_set_answerfrom(reply, ldns_rdf_clone(ns_array[i])); ldns_pkt_set_timestamp(reply, tv_s); ldns_pkt_set_size(reply, reply_size); break; } else { if (ldns_resolver_fail(r)) { /* if fail is set bail out, after the first * one */ break; } } /* wait retrans seconds... */ sleep((unsigned int) ldns_resolver_retrans(r)); } if(src) { LDNS_FREE(src); } if (all_servers_rtt_inf) { LDNS_FREE(reply_bytes); return LDNS_STATUS_RES_NO_NS; } #ifdef HAVE_SSL if (tsig_mac && reply && reply_bytes) { if (!ldns_pkt_tsig_verify(reply, reply_bytes, reply_size, ldns_resolver_tsig_keyname(r), ldns_resolver_tsig_keydata(r), tsig_mac)) { status = LDNS_STATUS_CRYPTO_TSIG_BOGUS; } } #else (void)tsig_mac; #endif /* HAVE_SSL */ LDNS_FREE(reply_bytes); if (result) { *result = reply; } return status; }