From: Miek Gieben Date: Tue, 9 Aug 2005 12:01:55 +0000 (+0000) Subject: implement insert_rr. Also found subtle bug in rr_list pop (of by 1) X-Git-Tag: release-1.0.0~342 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ea4c267ee1edc11a2eec3d6161855207a0c13bd6;p=thirdparty%2Fldns.git implement insert_rr. Also found subtle bug in rr_list pop (of by 1) --- diff --git a/ldns/packet.h b/ldns/packet.h index fb8e7b49..7d0c99f2 100644 --- a/ldns/packet.h +++ b/ldns/packet.h @@ -278,6 +278,8 @@ ldns_pkt *ldns_pkt_clone(ldns_pkt *pkt); /* lua helper stuff */ ldns_rr * ldns_pkt_get_rr(ldns_pkt *p, uint16_t n); ldns_rr * ldns_pkt_set_rr(ldns_pkt *p, ldns_rr *rr, uint16_t n); +bool ldns_pkt_insert_rr(ldns_pkt *p, ldns_rr *rr, uint16_t n); + #define LDNS_MAX_PACKETLEN 65535 diff --git a/ldns/rr.h b/ldns/rr.h index 3a364cd9..ff7bed90 100644 --- a/ldns/rr.h +++ b/ldns/rr.h @@ -623,4 +623,7 @@ ldns_rdf_type ldns_rr_descriptor_field_type(const ldns_rr_descriptor *descriptor */ ldns_rr_list *ldns_rr_list_subtype_by_rdf(ldns_rr_list *l, ldns_rdf *r, uint16_t pos); +/* added while doing lua */ +bool ldns_rr_list_insert_rr(ldns_rr_list *rr_list, ldns_rr *r, uint16_t count); + #endif /* _LDNS_RR_H */ diff --git a/packet.c b/packet.c index 3e277295..64b4f2d6 100644 --- a/packet.c +++ b/packet.c @@ -435,6 +435,77 @@ success: return r; } +/* insert rr after n */ +bool +ldns_pkt_insert_rr(ldns_pkt *p, ldns_rr *rr, uint16_t n) +{ + ldns_rr_list *sec; + ldns_pkt_section where; + uint16_t count; + + /* i break a layer here -- sue me */ + + /* retrieve the correct section */ + count = ldns_pkt_qdcount(p); + if (n < count) { + sec = ldns_pkt_question(p); + where = LDNS_SECTION_QUESTION; + goto success; + } + count = ldns_pkt_qdcount(p) + ldns_pkt_ancount(p); + if (n < count) { + sec = ldns_pkt_answer(p); + where = LDNS_SECTION_ANSWER; + goto success; + } + count = ldns_pkt_qdcount(p) + ldns_pkt_ancount(p) + + ldns_pkt_nscount(p); + if (n < count) { + sec = ldns_pkt_authority(p); + where = LDNS_SECTION_AUTHORITY; + goto success; + } + count = ldns_pkt_qdcount(p) + ldns_pkt_ancount(p) + + ldns_pkt_nscount(p) + ldns_pkt_arcount(p); + if (n < count) { + sec = ldns_pkt_additional(p); + where = LDNS_SECTION_ADDITIONAL; + goto success; + } + /* still not ?? */ + return false; + +success: + if (ldns_rr_list_insert_rr(sec, rr, count - n - 1)) { + /* inc the section counter */ + switch(where) { + case LDNS_SECTION_QUESTION: + ldns_pkt_set_qdcount(p, + ldns_pkt_qdcount(p) + 1); + break; + case LDNS_SECTION_ANSWER: + ldns_pkt_set_ancount(p, + ldns_pkt_ancount(p) + 1); + break; + case LDNS_SECTION_AUTHORITY: + ldns_pkt_set_nscount(p, + ldns_pkt_nscount(p) + 1); + break; + case LDNS_SECTION_ADDITIONAL: + ldns_pkt_set_arcount(p, + ldns_pkt_arcount(p) + 1); + break; + default: + /* do nothing, this is here to avoid compile warn */ + break; + } + return true; + + } else { + return false; + } +} + uint16_t ldns_pkt_section_count(const ldns_pkt *packet, ldns_pkt_section s) { diff --git a/rr.c b/rr.c index db2d8bc1..119f1639 100644 --- a/rr.c +++ b/rr.c @@ -444,6 +444,31 @@ ldns_rr_list_set_rr(ldns_rr_list *rr_list, ldns_rr *r, uint16_t count) return old; } +bool +ldns_rr_list_insert_rr(ldns_rr_list *rr_list, ldns_rr *r, uint16_t count) +{ + uint16_t c, i; + ldns_rr *pop[101]; /* WRONG AMOUNT */ + + c = ldns_rr_list_rr_count(rr_list); + + if (count > c || count > 100) { + return false; + } + + /* chip off the top */ + for (i = c - 1; i >= count; i--) { + pop[c - 1 - i] = ldns_rr_list_pop_rr(rr_list); + } + + /* add the rr and then the popped stuff */ + ldns_rr_list_push_rr(rr_list, r); + + for (i = count; i < c; i++) { + ldns_rr_list_push_rr(rr_list, pop[count - i]); + } + return true; +} void ldns_rr_list_set_rr_count(ldns_rr_list *rr_list, uint16_t count) @@ -640,7 +665,7 @@ ldns_rr_list_pop_rr(ldns_rr_list *rr_list) return NULL; } - pop = ldns_rr_list_rr(rr_list, rr_count); + pop = ldns_rr_list_rr(rr_list, rr_count - 1); /* shrink the array */ rr_list->_rrs = LDNS_XREALLOC(