Lines 156-161
Link Here
|
156 |
return LDNS_STATUS_MEM_ERR; |
156 |
return LDNS_STATUS_MEM_ERR; |
157 |
} |
157 |
} |
158 |
|
158 |
|
|
|
159 |
static uint32_t |
160 |
ldns_rr_soa_get_serial(const ldns_rr *rr) |
161 |
{ |
162 |
const ldns_rdf *rdf; |
163 |
|
164 |
if (ldns_rr_get_type(rr) != LDNS_RR_TYPE_SOA) return 0; |
165 |
if (ldns_rr_rd_count(rr) != 7) return 0; |
166 |
rdf = ldns_rr_rdf(rr, 2); |
167 |
if (ldns_rdf_get_type(rdf) != LDNS_RDF_TYPE_INT32) return 0; |
168 |
if (ldns_rdf_size(rdf) != 4) return 0; |
169 |
return ldns_rdf2native_int32(rdf); |
170 |
} |
171 |
|
159 |
static ldns_status |
172 |
static ldns_status |
160 |
ldns_tcp_start(ldns_resolver *res, ldns_pkt *qpkt, int nameserver) { |
173 |
ldns_tcp_start(ldns_resolver *res, ldns_pkt *qpkt, int nameserver) { |
161 |
/* This routine is based on ldns_axfr_start, with the major |
174 |
/* This routine is based on ldns_axfr_start, with the major |
Lines 873-879
Link Here
|
873 |
ldns_rdf *dname; |
886 |
ldns_rdf *dname; |
874 |
ldns_rr_type rrtype; |
887 |
ldns_rr_type rrtype; |
875 |
ldns_rr_list *rrl; |
888 |
ldns_rr_list *rrl; |
876 |
int i, nsoa = 0; |
889 |
ldns_rr *rr; |
|
|
890 |
size_t i, nsoa = 0; |
891 |
uint32_t first_serial; |
877 |
|
892 |
|
878 |
rrtype = o_rrtype; |
893 |
rrtype = o_rrtype; |
879 |
o_rrtype = (o_mode == M_AXFR) ? LDNS_RR_TYPE_AXFR : LDNS_RR_TYPE_IXFR; |
894 |
o_rrtype = (o_mode == M_AXFR) ? LDNS_RR_TYPE_AXFR : LDNS_RR_TYPE_IXFR; |
Lines 880-890
Link Here
|
880 |
dname = search(res, domain, &pkt, absolute, false); |
895 |
dname = search(res, domain, &pkt, absolute, false); |
881 |
|
896 |
|
882 |
for (;;) { |
897 |
for (;;) { |
883 |
rrl = ldns_pkt_answer(pkt); |
898 |
rrl = ldns_rr_list_clone(ldns_pkt_answer(pkt)); |
884 |
for (i = ldns_rr_list_rr_count(rrl) - 1; i >= 0; i--) { |
|
|
885 |
if (ldns_rr_get_type(ldns_rr_list_rr(rrl, i)) == LDNS_RR_TYPE_SOA) |
886 |
nsoa++; |
887 |
} |
888 |
ldns_pkt_filter_answer(pkt, rrtype); |
899 |
ldns_pkt_filter_answer(pkt, rrtype); |
889 |
report(res, dname != NULL ? dname : domain, pkt); |
900 |
report(res, dname != NULL ? dname : domain, pkt); |
890 |
if ((dname == NULL) || |
901 |
if ((dname == NULL) || |
Lines 893-901
Link Here
|
893 |
ldns_tcp_close(res); |
904 |
ldns_tcp_close(res); |
894 |
return false; |
905 |
return false; |
895 |
} |
906 |
} |
896 |
if (nsoa >= 2) { |
907 |
for (i = 0; i < ldns_rr_list_rr_count(rrl); i++) { |
897 |
ldns_tcp_close(res); |
908 |
rr = ldns_rr_list_rr(rrl, i); |
898 |
return true; |
909 |
if (nsoa == 0) { |
|
|
910 |
if (ldns_rr_get_type(rr) != LDNS_RR_TYPE_SOA) { |
911 |
printf("; Transfer failed. " |
912 |
"Didn't start with SOA answer.\n"); |
913 |
ldns_tcp_close(res); |
914 |
return false; |
915 |
} |
916 |
first_serial = ldns_rr_soa_get_serial(rr); |
917 |
if ((o_mode == M_IXFR) && (first_serial <= o_ixfr_serial)) { |
918 |
ldns_tcp_close(res); |
919 |
return true; |
920 |
} |
921 |
} |
922 |
if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_SOA) { |
923 |
nsoa = nsoa < 2 ? nsoa + 1 : 1; |
924 |
if ((nsoa == 2) && |
925 |
(ldns_rr_soa_get_serial(rr) == first_serial)) { |
926 |
ldns_tcp_close(res); |
927 |
return true; |
928 |
} |
929 |
} |
899 |
} |
930 |
} |
900 |
if (ldns_tcp_read(&nextpkt, res) != LDNS_STATUS_OK) { |
931 |
if (ldns_tcp_read(&nextpkt, res) != LDNS_STATUS_OK) { |
901 |
printf("; Transfer failed.\n"); |
932 |
printf("; Transfer failed.\n"); |
Lines 904-909
Link Here
|
904 |
ldns_pkt_set_answerfrom(nextpkt, |
935 |
ldns_pkt_set_answerfrom(nextpkt, |
905 |
ldns_rdf_clone(ldns_pkt_answerfrom(pkt))); |
936 |
ldns_rdf_clone(ldns_pkt_answerfrom(pkt))); |
906 |
ldns_pkt_free(pkt); |
937 |
ldns_pkt_free(pkt); |
|
|
938 |
ldns_rr_list_free(rrl); |
907 |
pkt = nextpkt; |
939 |
pkt = nextpkt; |
908 |
} |
940 |
} |
909 |
} |
941 |
} |