diff --git a/src/context.c b/src/context.c index a623cec5..b586cc2e 100644 --- a/src/context.c +++ b/src/context.c @@ -2191,7 +2191,7 @@ ub_setup_recursing(struct ub_ctx *ctx, getdns_context *context) , context->trust_anchors_len) ; rr ; rr = _getdns_rr_iter_next(rr) ) { - (void) gldns_wire2str_rr_buf(rr->pos, + (void) gldns_wire2str_rr_buf((UNCONST_UINT8_p)rr->pos, rr->nxt - rr->pos, ta_str, sizeof(ta_str)); (void) ub_ctx_add_ta(ctx, ta_str); } @@ -2379,8 +2379,7 @@ _getdns_strdup(const struct mem_funcs *mfs, const char *s) } struct getdns_bindata * -_getdns_bindata_copy(struct mem_funcs *mfs, - const struct getdns_bindata *src) +_getdns_bindata_copy(struct mem_funcs *mfs, size_t size, const uint8_t *data) { /* Don't know why, but nodata allows * empty bindatas with the python bindings @@ -2388,20 +2387,16 @@ _getdns_bindata_copy(struct mem_funcs *mfs, static uint8_t nodata[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; struct getdns_bindata *dst; - if (!src) - return NULL; - if (!(dst = GETDNS_MALLOC(*mfs, struct getdns_bindata))) return NULL; - dst->size = src->size; - if ((dst->size = src->size)) { - dst->data = GETDNS_XMALLOC(*mfs, uint8_t, src->size); + if ((dst->size = size)) { + dst->data = GETDNS_XMALLOC(*mfs, uint8_t, size); if (!dst->data) { GETDNS_FREE(*mfs, dst); return NULL; } - (void) memcpy(dst->data, src->data, src->size); + (void) memcpy(dst->data, data, size); } else { dst->data = nodata; } diff --git a/src/context.h b/src/context.h index 1e489d2d..d888ed4d 100644 --- a/src/context.h +++ b/src/context.h @@ -240,8 +240,7 @@ getdns_return_t _getdns_context_cancel_request(struct getdns_context *context, char *_getdns_strdup(const struct mem_funcs *mfs, const char *str); struct getdns_bindata *_getdns_bindata_copy( - struct mem_funcs *mfs, - const struct getdns_bindata *src); + struct mem_funcs *mfs, size_t size, const uint8_t *data); void _getdns_bindata_destroy( struct mem_funcs *mfs, diff --git a/src/dict.c b/src/dict.c index 822d5deb..d70381b7 100644 --- a/src/dict.c +++ b/src/dict.c @@ -574,17 +574,17 @@ getdns_dict_set_list( /*---------------------------------------- getdns_dict_set_bindata */ getdns_return_t -getdns_dict_set_bindata( - getdns_dict *dict, const char *name, const getdns_bindata *child_bindata) +_getdns_dict_set_const_bindata( + getdns_dict *dict, const char *name, size_t size, const uint8_t *data) { getdns_item *item; getdns_bindata *newbindata; getdns_return_t r; - if (!dict || !name || !child_bindata) + if (!dict || !name) return GETDNS_RETURN_INVALID_PARAMETER; - if (!(newbindata = _getdns_bindata_copy(&dict->mf, child_bindata))) + if (!(newbindata = _getdns_bindata_copy(&dict->mf, size, data))) return GETDNS_RETURN_MEMORY_ERROR; if ((r = _getdns_dict_find_and_add(dict, name, &item))) { @@ -596,6 +596,15 @@ getdns_dict_set_bindata( return GETDNS_RETURN_GOOD; } /* getdns_dict_set_bindata */ +getdns_return_t +getdns_dict_set_bindata( + getdns_dict *dict, const char *name, const getdns_bindata *child_bindata) +{ + return !child_bindata ? GETDNS_RETURN_INVALID_PARAMETER + : _getdns_dict_set_const_bindata( + dict, name, child_bindata->size, child_bindata->data); +} + /*---------------------------------------- getdns_dict_set_bindata */ getdns_return_t getdns_dict_util_set_string(getdns_dict *dict, char *name, const char *value) diff --git a/src/dnssec.c b/src/dnssec.c index 3fdff91b..59de8e46 100644 --- a/src/dnssec.c +++ b/src/dnssec.c @@ -219,16 +219,16 @@ /******************* Frequently Used Utility Functions ********************* *****************************************************************************/ -inline static size_t _dname_len(uint8_t *name) +inline static size_t _dname_len(const uint8_t *name) { - uint8_t *p; + const uint8_t *p; for (p = name; *p; p += *p + 1) /* pass */ ; return p - name + 1; } -inline static size_t _dname_label_count(uint8_t *name) +inline static size_t _dname_label_count(const uint8_t *name) { size_t c; for (c = 0; *name; name += *name + 1, c++) @@ -267,20 +267,24 @@ static uint8_t *_dname_label_copy(uint8_t *dst, const uint8_t *src, size_t dst_l return r; } -inline static void _dname_canonicalize(uint8_t *dname) +inline void _dname_canonicalize(const uint8_t *src, uint8_t *dst) { - uint8_t *next_label; + const uint8_t *next_label; - while (*dname) { - next_label = dname + *dname + 1; - dname += 1; - while (dname < next_label) { - *dname = (uint8_t)tolower((unsigned char)*dname); - dname++; - } + while (*src) { + next_label = src + *src + 1; + *dst++ = *src++; + while (src < next_label) + *dst++ = (uint8_t)tolower((unsigned char)*src++); } } +inline void _dname_canonicalize2(uint8_t *dname) +{ + _dname_canonicalize(dname, dname); +} + + /* Fills the array pointed to by labels (of at least 128 uint8_t * pointers) * with pointers to labels in given dname in reversed order. So that * labels[0] will point to the root. @@ -294,7 +298,8 @@ inline static void _dname_canonicalize(uint8_t *dname) * labels[3] will be "www.getdnsapi.net." * The returned value will be &labels[4] */ -static uint8_t **reverse_labels(uint8_t *dname, uint8_t **labels) +static const uint8_t **reverse_labels( + const uint8_t *dname, const uint8_t **labels) { if (*dname) labels = reverse_labels(dname + *dname + 1, labels); @@ -302,10 +307,12 @@ static uint8_t **reverse_labels(uint8_t *dname, uint8_t **labels) return labels + 1; } -static uint8_t *dname_shared_parent(uint8_t *left, uint8_t *right) +static const uint8_t *dname_shared_parent( + const uint8_t *left, const uint8_t *right) { - uint8_t *llabels[128], *rlabels[128], **last_llabel, **last_rlabel, - **llabel, **rlabel, *l, *r, sz; + const uint8_t *llabels[128], *rlabels[128], **last_llabel, **last_rlabel, + **llabel, **rlabel, *l, *r; + uint8_t sz; last_llabel = reverse_labels(left, llabels); last_rlabel = reverse_labels(right, rlabels); @@ -333,10 +340,11 @@ static uint8_t *dname_shared_parent(uint8_t *left, uint8_t *right) return llabel[-1]; } -static int dname_compare(uint8_t *left, uint8_t *right) +static int dname_compare(const uint8_t *left, const uint8_t *right) { - uint8_t *llabels[128], *rlabels[128], **last_llabel, **last_rlabel, - **llabel, **rlabel, *l, *r, lsz, rsz; + const uint8_t *llabels[128], *rlabels[128], **last_llabel, **last_rlabel, + **llabel, **rlabel, *l, *r; + uint8_t lsz, rsz; last_llabel = reverse_labels(left, llabels); last_rlabel = reverse_labels(right, rlabels); @@ -373,7 +381,7 @@ static int dname_compare(uint8_t *left, uint8_t *right) static int bitmap_has_type(_getdns_rdf_iter *bitmap, uint16_t rr_type) { - uint8_t *dptr, *dend; + const uint8_t *dptr, *dend; uint8_t window = rr_type >> 8; uint8_t subtype = rr_type & 0xFF; @@ -442,9 +450,10 @@ static inline uint16_t rr_iter_class(_getdns_rr_iter *rr) { return rr->rr_type + 4 <= rr->nxt ? gldns_read_uint16(rr->rr_type + 2) : 0; } /* Utility function to compare owner name of rr with name */ -static int rr_owner_equal(_getdns_rr_iter *rr, uint8_t *name) +static int rr_owner_equal(_getdns_rr_iter *rr, const uint8_t *name) { - uint8_t owner_spc[256], *owner; + uint8_t owner_spc[256]; + const uint8_t *owner; size_t owner_len = sizeof(owner_spc); return (owner = _getdns_owner_if_or_as_decompressed(rr, owner_spc @@ -470,7 +479,7 @@ static _getdns_rr_iter *rr_iter_ansauth(_getdns_rr_iter *rr) /* Filter that only iterates over RRs with a certain name/class/type */ static _getdns_rr_iter *rr_iter_name_class_type(_getdns_rr_iter *rr, - uint8_t *name, uint16_t rr_class, uint16_t rr_type) + const uint8_t *name, uint16_t rr_class, uint16_t rr_type) { while (rr_iter_ansauth(rr) && !( rr_iter_type(rr) == rr_type && @@ -484,7 +493,7 @@ static _getdns_rr_iter *rr_iter_name_class_type(_getdns_rr_iter *rr, /* Filter that only iterates over RRs that do not have a name/class/type */ static _getdns_rr_iter *rr_iter_not_name_class_type(_getdns_rr_iter *rr, - uint8_t *name, uint16_t rr_class, uint16_t rr_type) + const uint8_t *name, uint16_t rr_class, uint16_t rr_type) { while (rr_iter_ansauth(rr) && ( rr_iter_type(rr) == GETDNS_RRTYPE_RRSIG || ( @@ -501,7 +510,7 @@ static _getdns_rr_iter *rr_iter_not_name_class_type(_getdns_rr_iter *rr, * a RRset with a certain name/class/type */ static _getdns_rr_iter *rr_iter_rrsig_covering(_getdns_rr_iter *rr, - uint8_t *name, uint16_t rr_class, uint16_t rr_type) + const uint8_t *name, uint16_t rr_class, uint16_t rr_type) { while (rr_iter_ansauth(rr) && !( rr_iter_type(rr) == GETDNS_RRTYPE_RRSIG && @@ -516,11 +525,11 @@ static _getdns_rr_iter *rr_iter_rrsig_covering(_getdns_rr_iter *rr, } typedef struct getdns_rrset { - uint8_t *name; - uint16_t rr_class; - uint16_t rr_type; - uint8_t *pkt; - size_t pkt_len; + const uint8_t *name; + uint16_t rr_class; + uint16_t rr_type; + uint8_t *pkt; + size_t pkt_len; } getdns_rrset; typedef struct rrtype_iter { @@ -764,23 +773,24 @@ struct chain_node { * to equip the chain nodes with their RR sets are done alongside construction. * Hence they need to be enumerated before the construction functions. */ -static void val_chain_sched(chain_head *head, uint8_t *dname); -static void val_chain_sched_ds(chain_head *head, uint8_t *dname); +static void val_chain_sched(chain_head *head, const uint8_t *dname); +static void val_chain_sched_ds(chain_head *head, const uint8_t *dname); static void val_chain_sched_signer(chain_head *head, rrsig_iter *rrsig); -static void val_chain_sched_soa(chain_head *head, uint8_t *dname); +static void val_chain_sched_soa(chain_head *head, const uint8_t *dname); static chain_head *add_rrset2val_chain(struct mem_funcs *mf, chain_head **chain_p, getdns_rrset *rrset, getdns_network_req *netreq) { chain_head *head; - uint8_t *labels[128], **last_label, **label; + const uint8_t *labels[128], **last_label, **label; size_t max_labels; /* max labels in common */ chain_head *max_head; chain_node *max_node; size_t dname_len, head_sz, node_count, n; - uint8_t *dname, *region; + const uint8_t *dname; + uint8_t *region; chain_node *node; last_label = reverse_labels(rrset->name, labels); @@ -906,10 +916,11 @@ static int is_synthesized_cname(getdns_rrset *cname) _getdns_rdf_iter rdf_spc, *rdf; rrtype_iter drr_spc, *drr; _getdns_rdf_iter drdf_spc, *drdf; - uint8_t cname_rdata_spc[256], *cname_rdata, - dname_rdata_spc[256], *dname_rdata, + uint8_t cname_rdata_spc[256], + dname_rdata_spc[256], synth_name[256], - *synth_name_end = synth_name + sizeof(synth_name) - 1, *s, *c; + *synth_name_end = synth_name + sizeof(synth_name) - 1, *s; + const uint8_t *cname_rdata, *dname_rdata, *c; size_t cname_rdata_len = sizeof(cname_rdata_spc), dname_rdata_len = sizeof(dname_rdata_len), cname_labels, dname_labels; @@ -1049,7 +1060,7 @@ static void add_pkt2val_chain(struct mem_funcs *mf, */ static void add_question2val_chain(struct mem_funcs *mf, chain_head **chain_p, uint8_t *pkt, size_t pkt_len, - uint8_t *qname, uint16_t qtype, uint16_t qclass, + const uint8_t *qname, uint16_t qtype, uint16_t qclass, getdns_network_req *netreq) { getdns_rrset q_rrset; @@ -1133,7 +1144,8 @@ static void val_chain_sched_soa_node(chain_node *node) context = node->chains->netreq->owner->context; loop = node->chains->netreq->owner->loop; - if (!gldns_wire2str_dname_buf(node->ds.name, 256, name, sizeof(name))) + if (!gldns_wire2str_dname_buf( + (UNCONST_UINT8_p)node->ds.name, 256, name, sizeof(name))) return; DEBUG_SEC("schedule SOA lookup for %s\n", name); @@ -1151,7 +1163,7 @@ static void val_chain_sched_soa_node(chain_node *node) * answer, then a DS/DNSKEY lookup will follow the acquire the link of the * authentication chain. */ -static void val_chain_sched_soa(chain_head *head, uint8_t *dname) +static void val_chain_sched_soa(chain_head *head, const uint8_t *dname) { chain_node *node; @@ -1180,7 +1192,8 @@ static void val_chain_sched_node(chain_node *node) context = node->chains->netreq->owner->context; loop = node->chains->netreq->owner->loop; - if (!gldns_wire2str_dname_buf(node->ds.name, 256, name, sizeof(name))) + if (!gldns_wire2str_dname_buf( + (UNCONST_UINT8_p)node->ds.name, 256, name, sizeof(name))) return; DEBUG_SEC("schedule DS & DNSKEY lookup for %s\n", name); @@ -1200,7 +1213,7 @@ static void val_chain_sched_node(chain_node *node) node->ds_req = dnsreq->netreqs[0]; } -static void val_chain_sched(chain_head *head, uint8_t *dname) +static void val_chain_sched(chain_head *head, const uint8_t *dname) { chain_node *node; @@ -1224,7 +1237,9 @@ static void val_chain_sched_ds_node(chain_node *node) context = node->chains->netreq->owner->context; loop = node->chains->netreq->owner->loop; - if (!gldns_wire2str_dname_buf(node->ds.name, 256, name, sizeof(name))) + if (!gldns_wire2str_dname_buf( + (UNCONST_UINT8_p)node->ds.name, 256, name, sizeof(name))) + return; DEBUG_SEC("schedule DS lookup for %s\n", name); @@ -1237,7 +1252,7 @@ static void val_chain_sched_ds_node(chain_node *node) node->ds_req = ds_req->netreqs[0]; } -static void val_chain_sched_ds(chain_head *head, uint8_t *dname) +static void val_chain_sched_ds(chain_head *head, const uint8_t *dname) { chain_node *node; @@ -1254,8 +1269,9 @@ static void val_chain_sched_ds(chain_head *head, uint8_t *dname) static void val_chain_sched_signer_node(chain_node *node, rrsig_iter *rrsig) { _getdns_rdf_iter rdf_spc, *rdf; - uint8_t signer_spc[256], *signer; - size_t signer_len; + uint8_t signer_spc[256]; + const uint8_t *signer; + size_t signer_len; if (!(rdf = _getdns_rdf_iter_init_at(&rdf_spc, &rrsig->rr_i, 7))) return; @@ -1369,7 +1385,8 @@ static int key_matches_signer(getdns_rrset *dnskey, getdns_rrset *rrset) rrsig_iter rrsig_spc, *rrsig; uint16_t keytag; _getdns_rdf_iter rdf_spc, *rdf; - uint8_t signer_spc[256], *signer; + uint8_t signer_spc[256]; + const uint8_t *signer; size_t signer_len = sizeof(signer_spc); assert(dnskey->rr_type == GETDNS_RRTYPE_DNSKEY); @@ -1384,8 +1401,9 @@ static int key_matches_signer(getdns_rrset *dnskey, getdns_rrset *rrset) continue; /* Then we have at least 4 bytes to calculate keytag */ - keytag = gldns_calc_keytag_raw(rr->rr_i.rr_type + 10, - rr->rr_i.nxt - rr->rr_i.rr_type - 10); + keytag = gldns_calc_keytag_raw( + (UNCONST_UINT8_p)rr->rr_i.rr_type + 10, + rr->rr_i.nxt - rr->rr_i.rr_type - 10); for ( rrsig = rrsig_iter_init(&rrsig_spc, rrset) ; rrsig ; rrsig = rrsig_iter_next(rrsig) ) { @@ -1457,7 +1475,7 @@ typedef struct canon_rdata_iter { _getdns_rdf_iter rdf_spc; _getdns_rdf_iter *rdf; uint8_t cdname[256]; /* Canonical dname */ - uint8_t *pos; + const uint8_t *pos; size_t len; } canon_rdata_iter; @@ -1467,8 +1485,10 @@ inline static void canon_rdata_iter_field_init(canon_rdata_iter *i) if ((i->rdf->rdd_pos->type & GETDNS_RDF_N) == GETDNS_RDF_N) { i->len = sizeof(i->cdname); if ((i->pos = _getdns_rdf_if_or_as_decompressed( - i->rdf, i->cdname, &i->len))) - _dname_canonicalize(i->pos); + i->rdf, i->cdname, &i->len))) { + _dname_canonicalize(i->pos, i->cdname); + i->pos = i->cdname; + } } else { i->pos = i->rdf->pos; i->len = i->rdf->nxt - i->rdf->pos; @@ -1558,7 +1578,7 @@ static int _rr_iter_rdata_cmp(const void *a, const void *b) */ #define VAL_RRSET_SPC_SZ 1024 static int _getdns_verify_rrsig(struct mem_funcs *mf, - getdns_rrset *rrset, rrsig_iter *rrsig, rrtype_iter *key, uint8_t **nc_name) + getdns_rrset *rrset, rrsig_iter *rrsig, rrtype_iter *key, const uint8_t **nc_name) { int r; int to_skip; @@ -1568,7 +1588,8 @@ static int _getdns_verify_rrsig(struct mem_funcs *mf, size_t n_rrs, i, valbuf_sz, owner_len; _getdns_rdf_iter *signer, signer_spc, *rdf, rdf_spc; uint8_t valbuf_spc[4096], *valbuf_buf = valbuf_spc; - uint8_t cdname_spc[256], *cdname, owner[256]; + uint8_t cdname_spc[256], owner[256]; + const uint8_t *cdname; size_t cdname_len, pos; uint32_t orig_ttl; gldns_buffer valbuf; @@ -1620,12 +1641,12 @@ static int _getdns_verify_rrsig(struct mem_funcs *mf, gldns_buffer_init_frm_data(&valbuf, valbuf_buf, valbuf_sz); gldns_buffer_write(&valbuf, rrsig->rr_i.rr_type + 10, signer->nxt - rrsig->rr_i.rr_type - 10); - _dname_canonicalize(gldns_buffer_at(&valbuf, 18)); + _dname_canonicalize2(gldns_buffer_at(&valbuf, 18)); orig_ttl = gldns_read_uint32(rrsig->rr_i.rr_type + 14); (void) memcpy(owner, rrset->name, owner_len); - _dname_canonicalize(owner); + _dname_canonicalize2(owner); if (!_dnssec_rdata_to_canonicalize(rrset->rr_type)) for (i = 0; i < n_rrs; i++) { @@ -1656,7 +1677,7 @@ static int _getdns_verify_rrsig(struct mem_funcs *mf, rdf, cdname_spc, &cdname_len))) continue; gldns_buffer_write(&valbuf, cdname, cdname_len); - _dname_canonicalize( + _dname_canonicalize2( gldns_buffer_current(&valbuf) - cdname_len); } gldns_buffer_write_u16_at(&valbuf, pos, @@ -1667,8 +1688,9 @@ static int _getdns_verify_rrsig(struct mem_funcs *mf, assert(gldns_buffer_position(&valbuf) == valbuf_sz); r = _getdns_verify_canonrrset(&valbuf, key->rr_i.rr_type[13], - signer->nxt, rrsig->rr_i.nxt - signer->nxt, - key->rr_i.rr_type+14, key->rr_i.nxt - key->rr_i.rr_type-14, + (UNCONST_UINT8_p)signer->nxt, rrsig->rr_i.nxt - signer->nxt, + (UNCONST_UINT8_p)key->rr_i.rr_type+14, + key->rr_i.nxt - key->rr_i.rr_type-14, &reason); #if defined(SEC_DEBUG) && SEC_DEBUG @@ -1710,7 +1732,8 @@ static int _getdns_verify_rrsig(struct mem_funcs *mf, /* Calculates NSEC3 hash for name, and stores that into label */ static uint8_t *_getdns_nsec3_hash_label(uint8_t *label, size_t label_len, - uint8_t *name, uint8_t algorithm, uint16_t iterations, uint8_t *salt) + const uint8_t *name, uint8_t algorithm, + uint16_t iterations, const uint8_t *salt) { uint8_t buf[512], *dst, *eob; const uint8_t *src; @@ -1747,11 +1770,12 @@ static uint8_t *_getdns_nsec3_hash_label(uint8_t *label, size_t label_len, } static uint8_t *name2nsec3_label( - getdns_rrset *nsec3, uint8_t *name, uint8_t *label, size_t label_len) + getdns_rrset *nsec3, const uint8_t *name, uint8_t *label, size_t label_len) { rrsig_iter rrsig_spc, *rrsig; _getdns_rdf_iter rdf_spc, *rdf; - uint8_t signer_spc[256], *signer; + uint8_t signer_spc[256]; + const uint8_t *signer; size_t signer_len = sizeof(signer_spc); rrtype_iter rr_spc, *rr; @@ -1832,11 +1856,12 @@ static int check_dates(int32_t now, int32_t skew, int32_t exp, int32_t inc) * expansion, nc_name will point to the next closer part of the name in rrset. */ static int dnskey_signed_rrset(struct mem_funcs *mf, time_t now, uint32_t skew, - rrtype_iter *dnskey, getdns_rrset *rrset, uint8_t **nc_name) + rrtype_iter *dnskey, getdns_rrset *rrset, const uint8_t **nc_name) { rrsig_iter rrsig_spc, *rrsig; _getdns_rdf_iter rdf_spc, *rdf; - uint8_t signer_spc[256], *signer; + uint8_t signer_spc[256]; + const uint8_t *signer; size_t signer_len = sizeof(signer_spc); uint16_t keytag; @@ -1850,7 +1875,7 @@ static int dnskey_signed_rrset(struct mem_funcs *mf, time_t now, uint32_t skew, return 0; /* Then we have at least 4 bytes to calculate keytag */ - keytag = gldns_calc_keytag_raw(dnskey->rr_i.rr_type + 10, + keytag = gldns_calc_keytag_raw((UNCONST_UINT8_p)dnskey->rr_i.rr_type + 10, dnskey->rr_i.nxt - dnskey->rr_i.rr_type - 10); for ( rrsig = rrsig_iter_init(&rrsig_spc, rrset) @@ -1899,15 +1924,15 @@ static int dnskey_signed_rrset(struct mem_funcs *mf, time_t now, uint32_t skew, } static int find_nsec_covering_name( - struct mem_funcs *mf, time_t now, uint32_t skew, - getdns_rrset *dnskey, getdns_rrset *rrset, uint8_t *name, int *opt_out); + struct mem_funcs *mf, time_t now, uint32_t skew, getdns_rrset *dnskey, + getdns_rrset *rrset, const uint8_t *name, int *opt_out); /* Returns whether a dnskey for keyset signed rrset. */ static int a_key_signed_rrset(struct mem_funcs *mf, time_t now, uint32_t skew, getdns_rrset *keyset, getdns_rrset *rrset) { rrtype_iter dnskey_spc, *dnskey; - uint8_t *nc_name; + const uint8_t *nc_name; int keytag; assert(keyset->rr_type == GETDNS_RRTYPE_DNSKEY); @@ -1949,7 +1974,7 @@ static int ds_authenticates_keys(struct mem_funcs *mf, rrtype_iter dnskey_spc, *dnskey; rrtype_iter ds_spc, *ds; uint16_t keytag; - uint8_t *nc_name; + const uint8_t *nc_name; size_t valid_dsses = 0, supported_dsses = 0; uint8_t max_supported_digest = 0; int max_supported_result = 0; @@ -1972,7 +1997,7 @@ static int ds_authenticates_keys(struct mem_funcs *mf, return 0; (void) memcpy(digest_buf_spc, dnskey_set->name, dnskey_owner_len); - _dname_canonicalize(digest_buf_spc); + _dname_canonicalize2(digest_buf_spc); for ( dnskey = rrtype_iter_init(&dnskey_spc, dnskey_set) ; dnskey ; dnskey = rrtype_iter_next(dnskey)) { @@ -1981,8 +2006,9 @@ static int ds_authenticates_keys(struct mem_funcs *mf, if (dnskey->rr_i.nxt < dnskey->rr_i.rr_type + 14) continue; - keytag = gldns_calc_keytag_raw(dnskey->rr_i.rr_type + 10, - dnskey->rr_i.nxt - dnskey->rr_i.rr_type - 10); + keytag = gldns_calc_keytag_raw( + (UNCONST_UINT8_p) dnskey->rr_i.rr_type + 10, + dnskey->rr_i.nxt - dnskey->rr_i.rr_type - 10); for ( ds = rrtype_iter_init(&ds_spc, ds_set) ; ds ; ds = rrtype_iter_next(ds)) { @@ -2105,16 +2131,16 @@ static int ds_authenticates_keys(struct mem_funcs *mf, } static int nsec_covers_name( - getdns_rrset *nsec, uint8_t *name, uint8_t **ce_name) + getdns_rrset *nsec, const uint8_t *name, const uint8_t **ce_name) { - uint8_t owner_spc[256], *owner; - size_t owner_len = sizeof(owner_spc); - uint8_t next_spc[256], *next; - size_t next_len = sizeof(next_spc); + uint8_t owner_spc[256], next_spc[256]; + const uint8_t *owner, *next; + size_t owner_len = sizeof(owner_spc), next_len = sizeof(next_spc); + rrtype_iter rr_spc, *rr; _getdns_rdf_iter rdf_spc, *rdf; int nsec_cmp; - uint8_t *common1, *common2; + const uint8_t *common1, *common2; if (/* Get owner and next, nicely decompressed */ !(rr = rrtype_iter_init(&rr_spc, nsec)) @@ -2163,7 +2189,7 @@ static int nsec_covers_name( } } -static int nsec3_matches_name(getdns_rrset *nsec3, uint8_t *name) +static int nsec3_matches_name(getdns_rrset *nsec3, const uint8_t *name) { uint8_t label[64], owner[64]; @@ -2176,7 +2202,8 @@ static int nsec3_matches_name(getdns_rrset *nsec3, uint8_t *name) return 0; } -static int nsec3_covers_name(getdns_rrset *nsec3, uint8_t *name, int *opt_out) +static int nsec3_covers_name( + getdns_rrset *nsec3, const uint8_t *name, int *opt_out) { uint8_t label[65], next[65], owner[65]; rrtype_iter rr_spc, *rr; @@ -2227,8 +2254,8 @@ static int nsec3_covers_name(getdns_rrset *nsec3, uint8_t *name, int *opt_out) } static int find_nsec_covering_name( - struct mem_funcs *mf, time_t now, uint32_t skew, - getdns_rrset *dnskey, getdns_rrset *rrset, uint8_t *name, int *opt_out) + struct mem_funcs *mf, time_t now, uint32_t skew, getdns_rrset *dnskey, + getdns_rrset *rrset, const uint8_t *name, int *opt_out) { rrset_iter i_spc, *i; getdns_rrset *n; @@ -2325,7 +2352,8 @@ static int find_nsec_covering_name( static int nsec3_find_next_closer( struct mem_funcs *mf, time_t now, uint32_t skew, - getdns_rrset *dnskey, getdns_rrset *rrset, uint8_t *nc_name, int *opt_out) + getdns_rrset *dnskey, getdns_rrset *rrset, + const uint8_t *nc_name, int *opt_out) { uint8_t wc_name[256] = { 1, (uint8_t)'*' }; int my_opt_out, keytag; @@ -2382,7 +2410,7 @@ static int key_proves_nonexistance( rrtype_iter nsec_spc, *nsec_rr; _getdns_rdf_iter bitmap_spc, *bitmap; rrset_iter i_spc, *i; - uint8_t *ce_name, *nc_name; + const uint8_t *ce_name, *nc_name; uint8_t wc_name[256] = { 1, (uint8_t)'*' }; int keytag; @@ -3044,7 +3072,7 @@ static void append_empty_ds2val_chain_list( return; bindata.size = _dname_len(ds->name); - bindata.data = ds->name; + bindata.data = (UNCONST_UINT8_p)ds->name; (void) getdns_dict_set_bindata(rr_dict, "name", &bindata); (void) getdns_dict_set_int(rr_dict, "class", ds->rr_class); (void) getdns_dict_set_int(rr_dict, "type", ds->rr_type); @@ -3225,7 +3253,8 @@ static int wire_validate_dnssec(struct mem_funcs *mf, chain_head *chain, *head, *next_head; chain_node *node; - uint8_t qname_spc[256], *qname = NULL; + uint8_t qname_spc[256]; + const uint8_t *qname = NULL; size_t qname_len = sizeof(qname_spc); uint16_t qtype = 0, qclass = GETDNS_RRCLASS_IN; diff --git a/src/list.c b/src/list.c index be4886aa..660b962e 100644 --- a/src/list.c +++ b/src/list.c @@ -545,17 +545,17 @@ getdns_list_set_list( } /* getdns_list_set_list */ /*---------------------------------------- getdns_list_set_bindata */ -getdns_return_t -getdns_list_set_bindata( - getdns_list *list, size_t index, const getdns_bindata *child_bindata) +static getdns_return_t +_getdns_list_set_const_bindata( + getdns_list *list, size_t index, size_t size, const uint8_t *data) { getdns_bindata *newbindata; getdns_return_t r; - if (!list || !child_bindata) + if (!list) return GETDNS_RETURN_INVALID_PARAMETER; - if (!(newbindata = _getdns_bindata_copy(&list->mf, child_bindata))) + if (!(newbindata = _getdns_bindata_copy(&list->mf, size, data))) return GETDNS_RETURN_MEMORY_ERROR; if ((r = _getdns_list_request_index(list, index))) { @@ -567,6 +567,15 @@ getdns_list_set_bindata( return GETDNS_RETURN_GOOD; } /* getdns_list_set_bindata */ +getdns_return_t +getdns_list_set_bindata( + getdns_list *list, size_t index, const getdns_bindata *child_bindata) +{ + return !child_bindata ? GETDNS_RETURN_INVALID_PARAMETER + : _getdns_list_set_const_bindata( + list, index, child_bindata->size, child_bindata->data); +} + /*----------------------------------------- getdns_list_set_string */ static getdns_return_t getdns_list_set_string(getdns_list *list, size_t index, const char *value) @@ -631,6 +640,13 @@ _getdns_list_append_bindata(getdns_list *list, const getdns_bindata *child_binda return getdns_list_set_bindata(list, list->numinuse, child_bindata); } getdns_return_t +_getdns_list_append_const_bindata( + getdns_list *list, size_t size, const uint8_t *data) +{ + if (!list) return GETDNS_RETURN_INVALID_PARAMETER; + return _getdns_list_set_const_bindata(list, list->numinuse, size, data); +} +getdns_return_t _getdns_list_append_string(getdns_list *list, const char *value) { if (!list) return GETDNS_RETURN_INVALID_PARAMETER; diff --git a/src/rr-dict.c b/src/rr-dict.c index 4fe30794..5e616ce7 100644 --- a/src/rr-dict.c +++ b/src/rr-dict.c @@ -44,18 +44,18 @@ #define ALEN(a) (sizeof(a)/sizeof(a[0])) #define UNKNOWN_RDATA NULL -static uint8_t * -apl_n_rdf_end(uint8_t *pkt, uint8_t *pkt_end, uint8_t *rdf) +static const uint8_t * +apl_n_rdf_end(const uint8_t *pkt, const uint8_t *pkt_end, const uint8_t *rdf) { return rdf < pkt_end ? rdf + 1 : NULL; } static getdns_return_t -apl_n_dict_set_value(getdns_dict *dict, uint8_t *rdf) +apl_n_dict_set_value(getdns_dict *dict, const uint8_t *rdf) { return getdns_dict_set_int(dict, "n", (*rdf >> 7)); } static getdns_return_t -apl_n_list_append_value(getdns_list *list, uint8_t *rdf) +apl_n_list_append_value(getdns_list *list, const uint8_t *rdf) { return _getdns_list_append_int(list, (*rdf >> 7)); } @@ -63,33 +63,34 @@ static _getdns_rdf_special apl_n = { apl_n_rdf_end, apl_n_dict_set_value, apl_n_list_append_value }; -static uint8_t * -apl_afdpart_rdf_end(uint8_t *pkt, uint8_t *pkt_end, uint8_t *rdf) +static const uint8_t * +apl_afdpart_rdf_end( + const uint8_t *pkt, const uint8_t *pkt_end, const uint8_t *rdf) { - uint8_t *end = rdf + (rdf[-1] & 0x7F); + const uint8_t *end = rdf + (rdf[-1] & 0x7F); return end <= pkt_end ? end : NULL; } static getdns_return_t -apl_afdpart_dict_set_value(getdns_dict *dict, uint8_t *rdf) +apl_afdpart_dict_set_value(getdns_dict *dict, const uint8_t *rdf) { - getdns_bindata bindata = { (rdf[-1] & 0x7F), rdf }; - return getdns_dict_set_bindata(dict, "afdpart", &bindata); + return _getdns_dict_set_const_bindata( + dict, "afdpart", (rdf[-1] & 0x7F), rdf); } static getdns_return_t -apl_afdpart_list_append_value(getdns_list *list, uint8_t *rdf) +apl_afdpart_list_append_value(getdns_list *list, const uint8_t *rdf) { - getdns_bindata bindata = { (rdf[-1] & 0x7F), rdf }; - return _getdns_list_append_bindata(list, &bindata); + return _getdns_list_append_const_bindata(list, (rdf[-1] & 0x7F), rdf); } static _getdns_rdf_special apl_afdpart = { apl_afdpart_rdf_end, apl_afdpart_dict_set_value, apl_afdpart_list_append_value }; -static uint8_t * -ipseckey_gateway_rdf_end(uint8_t *pkt, uint8_t *pkt_end, uint8_t *rdf) +static const uint8_t * +ipseckey_gateway_rdf_end( + const uint8_t *pkt, const uint8_t *pkt_end, const uint8_t *rdf) { - uint8_t *end; + const uint8_t *end; if (rdf - 5 < pkt) return NULL; @@ -116,15 +117,16 @@ ipseckey_gateway_rdf_end(uint8_t *pkt, uint8_t *pkt_end, uint8_t *rdf) return end <= pkt_end ? end : NULL; } static getdns_return_t -ipseckey_gateway_equip_bindata(uint8_t *rdf, getdns_bindata *bindata) +ipseckey_gateway_equip_const_bindata( + const uint8_t *rdf, size_t *size, const uint8_t **data) { - bindata->data = rdf; + *data = rdf; switch (rdf[-2]) { - case 0: bindata->size = 0; + case 0: *size = 0; break; - case 1: bindata->size = 4; + case 1: *size = 4; break; - case 2: bindata->size = 16; + case 2: *size = 16; break; case 3: while (*rdf) if ((*rdf & 0xC0) == 0xC0) @@ -133,59 +135,62 @@ ipseckey_gateway_equip_bindata(uint8_t *rdf, getdns_bindata *bindata) return GETDNS_RETURN_GENERIC_ERROR; else rdf += *rdf + 1; - bindata->size = rdf + 1 - bindata->data; + *size = rdf + 1 - *data; break; default: return GETDNS_RETURN_GENERIC_ERROR; } return GETDNS_RETURN_GOOD; - } -static getdns_return_t -ipseckey_gateway_dict_set_value(getdns_dict *dict, uint8_t *rdf) -{ - getdns_bindata bindata; - if (ipseckey_gateway_equip_bindata(rdf, &bindata)) +static getdns_return_t +ipseckey_gateway_dict_set_value(getdns_dict *dict, const uint8_t *rdf) +{ + size_t size; + const uint8_t *data; + + if (ipseckey_gateway_equip_const_bindata(rdf, &size, &data)) return GETDNS_RETURN_GENERIC_ERROR; - else if (! bindata.size) + else if (! size) return GETDNS_RETURN_GOOD; else - return getdns_dict_set_bindata(dict, "gateway", &bindata); + return _getdns_dict_set_const_bindata(dict, "gateway", size, data); } static getdns_return_t -ipseckey_gateway_list_append_value(getdns_list *list, uint8_t *rdf) +ipseckey_gateway_list_append_value(getdns_list *list, const uint8_t *rdf) { - getdns_bindata bindata; + size_t size; + const uint8_t *data; - if (ipseckey_gateway_equip_bindata(rdf, &bindata)) + if (ipseckey_gateway_equip_const_bindata(rdf, &size, &data)) return GETDNS_RETURN_GENERIC_ERROR; - else if (! bindata.size) + else if (!size) return GETDNS_RETURN_GOOD; else - return _getdns_list_append_bindata(list, &bindata); + return _getdns_list_append_const_bindata(list, size, data); } static _getdns_rdf_special ipseckey_gateway = { ipseckey_gateway_rdf_end, ipseckey_gateway_dict_set_value, ipseckey_gateway_list_append_value }; -static uint8_t * -hip_pk_algorithm_rdf_end(uint8_t *pkt, uint8_t *pkt_end, uint8_t *rdf) +static const uint8_t * +hip_pk_algorithm_rdf_end( + const uint8_t *pkt, const uint8_t *pkt_end, const uint8_t *rdf) { return rdf + 4 > pkt_end ? NULL : rdf + 4 + *rdf + gldns_read_uint16(rdf + 2) > pkt_end ? NULL : rdf + 1; } static getdns_return_t -hip_pk_algorithm_dict_set_value(getdns_dict *dict, uint8_t *rdf) +hip_pk_algorithm_dict_set_value(getdns_dict *dict, const uint8_t *rdf) { return getdns_dict_set_int(dict, "pk_algorithm", rdf[1]); } static getdns_return_t -hip_pk_algorithm_list_append_value(getdns_list *list, uint8_t *rdf) +hip_pk_algorithm_list_append_value(getdns_list *list, const uint8_t *rdf) { return _getdns_list_append_int(list, rdf[1]); } @@ -194,47 +199,46 @@ static _getdns_rdf_special hip_pk_algorithm = { hip_pk_algorithm_dict_set_value, hip_pk_algorithm_list_append_value }; -static uint8_t * -hip_hit_rdf_end(uint8_t *pkt, uint8_t *pkt_end, uint8_t *rdf) +static const uint8_t * +hip_hit_rdf_end(const uint8_t *pkt, const uint8_t *pkt_end, const uint8_t *rdf) { return rdf + 3 > pkt_end ? NULL : rdf + 3 + rdf[-1] + gldns_read_uint16(rdf + 1) > pkt_end ? NULL : rdf + 1; } static getdns_return_t -hip_hit_dict_set_value(getdns_dict *dict, uint8_t *rdf) +hip_hit_dict_set_value(getdns_dict *dict, const uint8_t *rdf) { - getdns_bindata bindata = { rdf[-1], rdf + 3 }; - return getdns_dict_set_bindata(dict, "hit", &bindata); + return _getdns_dict_set_const_bindata(dict, "hit", rdf[-1], rdf + 3); } static getdns_return_t -hip_hit_list_append_value(getdns_list *list, uint8_t *rdf) +hip_hit_list_append_value(getdns_list *list, const uint8_t *rdf) { - getdns_bindata bindata = { rdf[-1], rdf + 3 }; - return _getdns_list_append_bindata(list, &bindata); + return _getdns_list_append_const_bindata(list, rdf[-1], rdf + 3); } static _getdns_rdf_special hip_hit = { hip_hit_rdf_end, hip_hit_dict_set_value, hip_hit_list_append_value }; -static uint8_t * -hip_public_key_rdf_end(uint8_t *pkt, uint8_t *pkt_end, uint8_t *rdf) +static const uint8_t * +hip_public_key_rdf_end( + const uint8_t *pkt, const uint8_t *pkt_end, const uint8_t *rdf) { return rdf + 2 > pkt_end ? NULL : rdf + 2 + rdf[-2] + gldns_read_uint16(rdf) > pkt_end ? NULL : rdf + 2 + rdf[-2] + gldns_read_uint16(rdf); } static getdns_return_t -hip_public_key_dict_set_value(getdns_dict *dict, uint8_t *rdf) +hip_public_key_dict_set_value(getdns_dict *dict, const uint8_t *rdf) { - getdns_bindata bindata = { gldns_read_uint16(rdf), rdf + 2 + rdf[-2] }; - return getdns_dict_set_bindata(dict, "public_key", &bindata); + return _getdns_dict_set_const_bindata( + dict, "public_key", gldns_read_uint16(rdf), rdf + 2 + rdf[-2]); } static getdns_return_t -hip_public_key_list_append_value(getdns_list *list, uint8_t *rdf) +hip_public_key_list_append_value(getdns_list *list, const uint8_t *rdf) { - getdns_bindata bindata = { gldns_read_uint16(rdf), rdf + 2 + rdf[-2] }; - return _getdns_list_append_bindata(list, &bindata); + return _getdns_list_append_const_bindata( + list, gldns_read_uint16(rdf), rdf + 2 + rdf[-2]); } static _getdns_rdf_special hip_public_key = { hip_public_key_rdf_end, @@ -742,7 +746,7 @@ _getdns_rr_type_name(int rr_type) } getdns_return_t -_getdns_rr_dict2wire(getdns_dict *rr_dict, gldns_buffer *buf) +_getdns_rr_dict2wire(const getdns_dict *rr_dict, gldns_buffer *buf) { getdns_return_t r = GETDNS_RETURN_GOOD; struct getdns_bindata *name; @@ -780,7 +784,7 @@ _getdns_rr_dict2wire(getdns_dict *rr_dict, gldns_buffer *buf) */ rr_def = _getdns_rr_def_lookup(rr_type); for ( rd_def = rr_def->rdata - , n_rdata_fields = rr_def->n_rdata_fields + , n_rdata_fields = rr_def->n_rdata_fields + 1 ; n_rdata_fields ; n_rdata_fields-- , rd_def++ ) { if (rd_def->type & GETDNS_RDF_COMPRESSED) diff --git a/src/rr-dict.h b/src/rr-dict.h index 633433c5..6d2e809b 100644 --- a/src/rr-dict.h +++ b/src/rr-dict.h @@ -36,13 +36,13 @@ #include "getdns/getdns.h" #include "gldns/gbuffer.h" -typedef uint8_t *(*_getdns_rdf_end_t)( - uint8_t *pkt, uint8_t *pkt_end, uint8_t *rdf); +typedef const uint8_t *(*_getdns_rdf_end_t)( + const uint8_t *pkt, const uint8_t *pkt_end, const uint8_t *rdf); /* Limit checks are already done with _getdns_rdf_end_t */ typedef getdns_return_t (*_getdns_rdf_dict_set_value_t)( - getdns_dict *dict, uint8_t *rdf); + getdns_dict *dict, const uint8_t *rdf); typedef getdns_return_t (*_getdns_rdf_list_append_value_t)( - getdns_list *list, uint8_t *rdf); + getdns_list *list, const uint8_t *rdf); typedef struct _getdns_rdf_special { _getdns_rdf_end_t rdf_end; @@ -134,7 +134,7 @@ typedef struct _getdns_rr_def { const _getdns_rr_def *_getdns_rr_def_lookup(uint16_t rr_type); getdns_return_t _getdns_rr_dict2wire( - getdns_dict *rr_dict, gldns_buffer *buf); + const getdns_dict *rr_dict, gldns_buffer *buf); const char *_getdns_rr_type_name(int rr_type); diff --git a/src/rr-iter.c b/src/rr-iter.c index bfd7c7d6..7ecff8f3 100644 --- a/src/rr-iter.c +++ b/src/rr-iter.c @@ -39,6 +39,10 @@ rr_iter_find_nxt(_getdns_rr_iter *i) assert(i); assert(i->rr_type); + if (!i->pkt) { + i->nxt = i->pkt_end; + return; + } i->nxt = i->n < GLDNS_QDCOUNT(i->pkt) ? i->rr_type + 4 : i->rr_type + 10 > i->pkt_end @@ -51,13 +55,14 @@ rr_iter_find_nxt(_getdns_rr_iter *i) static _getdns_rr_iter * find_rrtype(_getdns_rr_iter *i) { - uint8_t *pos; + const uint8_t *pos; assert(i); assert(i->pos); /* Past the last RR in the pkt */ - if (GLDNS_QDCOUNT(i->pkt) + GLDNS_ANCOUNT(i->pkt) + + if (i->pkt && + GLDNS_QDCOUNT(i->pkt) + GLDNS_ANCOUNT(i->pkt) + GLDNS_NSCOUNT(i->pkt) + GLDNS_ARCOUNT(i->pkt) <= i->n) goto done; @@ -83,7 +88,7 @@ done: } _getdns_rr_iter * -_getdns_rr_iter_init(_getdns_rr_iter *i, uint8_t *pkt, size_t pkt_len) +_getdns_rr_iter_init(_getdns_rr_iter *i, const uint8_t *pkt, size_t pkt_len) { assert(i); @@ -99,6 +104,25 @@ _getdns_rr_iter_init(_getdns_rr_iter *i, uint8_t *pkt, size_t pkt_len) return find_rrtype(i); } +_getdns_rr_iter * +_getdns_single_rr_iter_init( + _getdns_rr_iter *i, const uint8_t *wire, size_t wire_len) +{ + assert(i); + + if (!wire || wire_len < 5 /* name + type + class */) { + i->pos = NULL; + return NULL; + } + i->pkt = NULL; + i->pos = wire; + i->pkt_end = wire + wire_len; + i->n = 0; + + return find_rrtype(i); +} + + _getdns_rr_iter * _getdns_rr_iter_rewind(_getdns_rr_iter *i) { @@ -121,12 +145,13 @@ _getdns_rr_iter_next(_getdns_rr_iter *i) return find_rrtype(i); } -static uint8_t * -dname_if_or_as_decompressed(uint8_t *pkt, uint8_t *pkt_end, uint8_t *pos, - uint8_t *buf, size_t *len, size_t refs) +static const uint8_t * +dname_if_or_as_decompressed(const uint8_t *pkt, const uint8_t *pkt_end, + const uint8_t *pos, uint8_t *buf, size_t *len, size_t refs) { uint16_t offset; - uint8_t *start, *dst; + const uint8_t *start; + uint8_t *dst; assert(pkt); assert(pkt_end); @@ -138,7 +163,7 @@ dname_if_or_as_decompressed(uint8_t *pkt, uint8_t *pkt_end, uint8_t *pos, goto error; if ((*pos & 0xC0) == 0xC0) { - if (pos + 1 >= pkt_end) + if (!pkt || pos + 1 >= pkt_end) goto error; offset = gldns_read_uint16(pos) & 0x3FFF; if (pkt + offset >= pkt_end) @@ -175,7 +200,7 @@ dname_if_or_as_decompressed(uint8_t *pkt, uint8_t *pkt_end, uint8_t *pos, start = pos; } if ((*pos & 0xC0) == 0xC0) { - if (pos + 1 >= pkt_end) + if (!pkt || pos + 1 >= pkt_end) goto error; offset = gldns_read_uint16(pos) & 0x3FFF; if (pkt + offset >= pkt_end) @@ -204,7 +229,7 @@ error: return NULL; } -uint8_t * +const uint8_t * _getdns_owner_if_or_as_decompressed(_getdns_rr_iter *i, uint8_t *ff_bytes, size_t *len) { @@ -215,7 +240,7 @@ _getdns_owner_if_or_as_decompressed(_getdns_rr_iter *i, static _getdns_rdf_iter * rdf_iter_find_nxt(_getdns_rdf_iter *i) { - uint8_t *pos; + const uint8_t *pos; assert(i); assert(i->pos); @@ -334,7 +359,7 @@ _getdns_rdf_iter_init_at( return i; } -uint8_t * +const uint8_t * _getdns_rdf_if_or_as_decompressed( _getdns_rdf_iter *i, uint8_t *ff_bytes, size_t *len) { diff --git a/src/rr-iter.h b/src/rr-iter.h index b8f492e8..85f70509 100644 --- a/src/rr-iter.h +++ b/src/rr-iter.h @@ -38,8 +38,8 @@ #include "gldns/gbuffer.h" typedef struct _getdns_rr_iter { - uint8_t *pkt; - uint8_t *pkt_end; + const uint8_t *pkt; + const uint8_t *pkt_end; /* Which RR are we currently at */ size_t n; @@ -47,32 +47,37 @@ typedef struct _getdns_rr_iter { /* pos points to start of the owner name the RR. * Or is NULL when there are no RR's left. */ - uint8_t *pos; + const uint8_t *pos; /* rr_type will point to the rr_type right after the RR's owner name. * rr_type is guaranteed to have a value when pos has a value */ - uint8_t *rr_type; + const uint8_t *rr_type; /* nxt point to the owner name of the next RR or to pkt_end */ - uint8_t *nxt; + const uint8_t *nxt; } _getdns_rr_iter; _getdns_rr_iter *_getdns_rr_iter_init(_getdns_rr_iter *i, - uint8_t *pkt, size_t pkt_len); + const uint8_t *pkt, const size_t pkt_len); + +_getdns_rr_iter *_getdns_single_rr_iter_init(_getdns_rr_iter *i, + const uint8_t *wire, const size_t wire_len); _getdns_rr_iter *_getdns_rr_iter_rewind(_getdns_rr_iter *i); _getdns_rr_iter *_getdns_rr_iter_next(_getdns_rr_iter *i); -uint8_t *_getdns_owner_if_or_as_decompressed( +const uint8_t *_getdns_owner_if_or_as_decompressed( _getdns_rr_iter *i, uint8_t *ff_bytes, size_t *len); static inline gldns_pkt_section _getdns_rr_iter_section(_getdns_rr_iter *i) { - return i->n < GLDNS_QDCOUNT(i->pkt) ? GLDNS_SECTION_QUESTION + return !i->pkt ? (i->nxt - i->rr_type == 4 ? GLDNS_SECTION_QUESTION + : GLDNS_SECTION_ANSWER ) + : i->n < GLDNS_QDCOUNT(i->pkt) ? GLDNS_SECTION_QUESTION : i->n < GLDNS_QDCOUNT(i->pkt) + GLDNS_ANCOUNT(i->pkt) ? GLDNS_SECTION_ANSWER : i->n < GLDNS_QDCOUNT(i->pkt) @@ -86,14 +91,14 @@ _getdns_rr_iter_section(_getdns_rr_iter *i) } typedef struct piv_getdns_rdf_iter { - uint8_t *pkt; - uint8_t *pkt_end; + const uint8_t *pkt; + const uint8_t *pkt_end; const _getdns_rdata_def *rdd_pos; const _getdns_rdata_def *rdd_end; const _getdns_rdata_def *rdd_repeat; - uint8_t *pos; - uint8_t *end; - uint8_t *nxt; + const uint8_t *pos; + const uint8_t *end; + const uint8_t *nxt; } _getdns_rdf_iter; _getdns_rdf_iter *_getdns_rdf_iter_init(_getdns_rdf_iter *i, @@ -104,7 +109,7 @@ _getdns_rdf_iter *_getdns_rdf_iter_next(_getdns_rdf_iter *i); _getdns_rdf_iter *_getdns_rdf_iter_init_at(_getdns_rdf_iter *i, _getdns_rr_iter *rr, size_t pos); -uint8_t *_getdns_rdf_if_or_as_decompressed( +const uint8_t *_getdns_rdf_if_or_as_decompressed( _getdns_rdf_iter *i, uint8_t *ff_bytes, size_t *len); #endif diff --git a/src/stub.c b/src/stub.c index c0c254cc..af1250a7 100644 --- a/src/stub.c +++ b/src/stub.c @@ -187,7 +187,7 @@ match_and_process_server_cookie( getdns_upstream *upstream, uint8_t *response, size_t response_len) { _getdns_rr_iter rr_iter_storage, *rr_iter; - uint8_t *pos; + const uint8_t *pos; uint16_t rdata_len, opt_code = 0, opt_len = 0; /* Search for the OPT RR (if any) */ @@ -287,8 +287,8 @@ is_starttls_response(getdns_network_req *netreq) _getdns_rdf_iter rdf_iter_storage, *rdf_iter; uint16_t rr_type; gldns_pkt_section section; - uint8_t starttls_name_space[256], *starttls_name; - uint8_t owner_name_space[256], *owner_name; + uint8_t starttls_name_space[256], owner_name_space[256]; + const uint8_t *owner_name, *starttls_name; size_t starttls_name_len = sizeof(starttls_name_space); size_t owner_name_len = sizeof(owner_name_space);; diff --git a/src/util-internal.c b/src/util-internal.c index 07672bd7..f14425dc 100644 --- a/src/util-internal.c +++ b/src/util-internal.c @@ -172,7 +172,8 @@ getdns_dict * _getdns_rr_iter2rr_dict(struct mem_funcs *mf, _getdns_rr_iter *i) { getdns_dict *rr_dict, *rdata_dict; - getdns_bindata bindata; + const uint8_t *bin_data; + size_t bin_size; uint32_t int_val = 0; getdns_data_type val_type; _getdns_rdf_iter rdf_storage, *rdf; @@ -185,8 +186,8 @@ _getdns_rr_iter2rr_dict(struct mem_funcs *mf, _getdns_rr_iter *i) if (!(rr_dict = _getdns_dict_create_with_mf(mf))) return NULL; - bindata.data = _getdns_owner_if_or_as_decompressed( - i, ff_bytes, &bindata.size); + bin_data = _getdns_owner_if_or_as_decompressed( + i, ff_bytes, &bin_size); /* question */ if (_getdns_rr_iter_section(i) == GLDNS_SECTION_QUESTION) { @@ -197,7 +198,8 @@ _getdns_rr_iter2rr_dict(struct mem_funcs *mf, _getdns_rr_iter *i) getdns_dict_set_int(rr_dict, "qclass", (uint32_t) gldns_read_uint16(i->rr_type + 2)) || - getdns_dict_set_bindata(rr_dict, "qname", &bindata)) { + _getdns_dict_set_const_bindata( + rr_dict, "qname", bin_size, bin_data)) { goto error; } @@ -234,7 +236,8 @@ _getdns_rr_iter2rr_dict(struct mem_funcs *mf, _getdns_rr_iter *i) getdns_dict_set_int(rr_dict, "ttl", (uint32_t) gldns_read_uint32(i->rr_type + 4)) || - getdns_dict_set_bindata(rr_dict, "name", &bindata)) { + _getdns_dict_set_const_bindata( + rr_dict, "name", bin_size, bin_data)) { goto error; } @@ -242,9 +245,10 @@ _getdns_rr_iter2rr_dict(struct mem_funcs *mf, _getdns_rr_iter *i) return NULL; if (i->rr_type + 10 <= i->nxt) { - bindata.size = i->nxt - (i->rr_type + 10); - bindata.data = i->rr_type + 10; - if (getdns_dict_set_bindata(rdata_dict, "rdata_raw", &bindata)) + bin_size = i->nxt - (i->rr_type + 10); + bin_data = i->rr_type + 10; + if (_getdns_dict_set_const_bindata( + rdata_dict, "rdata_raw", bin_size, bin_data)) goto rdata_error; } for ( rdf = _getdns_rdf_iter_init(&rdf_storage, i) @@ -264,28 +268,28 @@ _getdns_rr_iter2rr_dict(struct mem_funcs *mf, _getdns_rr_iter *i) } else if (rdf->rdd_pos->type & GETDNS_RDF_DNAME) { val_type = t_bindata; - bindata.data = _getdns_rdf_if_or_as_decompressed( - rdf, ff_bytes, &bindata.size); + bin_data = _getdns_rdf_if_or_as_decompressed( + rdf, ff_bytes, &bin_size); } else if (rdf->rdd_pos->type & GETDNS_RDF_BINDATA) { val_type = t_bindata; if (rdf->rdd_pos->type & GETDNS_RDF_FIXEDSZ) { - bindata.size = rdf->rdd_pos->type - & GETDNS_RDF_FIXEDSZ; - bindata.data = rdf->pos; + bin_size = rdf->rdd_pos->type + & GETDNS_RDF_FIXEDSZ; + bin_data = rdf->pos; } else switch(rdf->rdd_pos->type & GETDNS_RDF_LEN_VAL){ case 0x100: - bindata.size = *rdf->pos; - bindata.data = rdf->pos + 1; + bin_size = *rdf->pos; + bin_data = rdf->pos + 1; break; case 0x200: - bindata.size = gldns_read_uint16(rdf->pos); - bindata.data = rdf->pos + 2; + bin_size = gldns_read_uint16(rdf->pos); + bin_data = rdf->pos + 2; break; default: - bindata.size = rdf->nxt - rdf->pos; - bindata.data = rdf->pos; + bin_size = rdf->nxt - rdf->pos; + bin_data = rdf->pos; break; } } else if (rdf->rdd_pos->type == GETDNS_RDF_SPECIAL) @@ -302,8 +306,8 @@ _getdns_rr_iter2rr_dict(struct mem_funcs *mf, _getdns_rr_iter *i) goto rdata_error; break; case t_bindata: - if (getdns_dict_set_bindata(rdata_dict, - rdf->rdd_pos->name, &bindata)) + if (_getdns_dict_set_const_bindata(rdata_dict, + rdf->rdd_pos->name, bin_size, bin_data)) goto rdata_error; break; case t_dict: @@ -330,8 +334,8 @@ _getdns_rr_iter2rr_dict(struct mem_funcs *mf, _getdns_rr_iter *i) goto rdata_error; break; case t_bindata: - if (_getdns_list_append_bindata(repeat_list, - &bindata)) + if (_getdns_list_append_const_bindata( + repeat_list, bin_size, bin_data)) goto rdata_error; break; case t_dict: @@ -369,8 +373,8 @@ _getdns_rr_iter2rr_dict(struct mem_funcs *mf, _getdns_rr_iter *i) goto rdata_error; break; case t_bindata: - if (getdns_dict_set_bindata(repeat_dict, - rdf->rdd_pos->name, &bindata)) + if (_getdns_dict_set_const_bindata(repeat_dict, + rdf->rdd_pos->name, bin_size, bin_data)) goto rdata_error; break; case t_dict: @@ -497,11 +501,11 @@ _getdns_create_reply_dict(getdns_context *context, getdns_network_req *req, getdns_dict *rr_dict = NULL; _getdns_rr_iter rr_iter_storage, *rr_iter; _getdns_rdf_iter rdf_iter_storage, *rdf_iter; - getdns_bindata bindata; + size_t bin_size; + const uint8_t *bin_data; gldns_pkt_section section; - uint8_t canonical_name_space[256], - *canonical_name = canonical_name_space; - uint8_t owner_name_space[256], *owner_name; + uint8_t canonical_name_space[256], owner_name_space[256]; + const uint8_t *canonical_name = canonical_name_space, *owner_name; size_t canonical_name_len = sizeof(canonical_name_space), owner_name_len = sizeof(owner_name_space); int new_canonical = 0; @@ -592,14 +596,15 @@ _getdns_create_reply_dict(getdns_context *context, getdns_network_req *req, &rdf_iter_storage, rr_iter))) continue; - bindata.size = rdf_iter->nxt - rdf_iter->pos; - bindata.data = rdf_iter->pos; + bin_size = rdf_iter->nxt - rdf_iter->pos; + bin_data = rdf_iter->pos; if (!set_dict(&rr_dict, getdns_dict_create_with_context(context)) || getdns_dict_util_set_string(rr_dict, "address_type", rr_type == GETDNS_RRTYPE_A ? "IPv4" : "IPv6" ) || - getdns_dict_set_bindata(rr_dict,"address_data",&bindata) || + _getdns_dict_set_const_bindata( + rr_dict, "address_data", bin_size, bin_data) || (just_addrs && _getdns_list_append_dict(just_addrs, rr_dict))) { @@ -656,9 +661,8 @@ _getdns_create_reply_dict(getdns_context *context, getdns_network_req *req, new_canonical = 1; } } - bindata.data = canonical_name; - bindata.size = canonical_name_len; - if (getdns_dict_set_bindata(result, "canonical_name", &bindata)) + if (_getdns_dict_set_const_bindata( + result, "canonical_name", canonical_name_len, canonical_name)) goto error; goto success; diff --git a/src/util-internal.h b/src/util-internal.h index b6db818a..fece4860 100644 --- a/src/util-internal.h +++ b/src/util-internal.h @@ -42,6 +42,7 @@ #include "context.h" #include "rr-iter.h" +#define UNCONST_UINT8_p uint8_t * #ifdef S_SPLINT_S # define INLINE @@ -81,6 +82,12 @@ getdns_return_t _getdns_list_append_string(getdns_list *list, getdns_return_t _getdns_list_append_int(getdns_list *list, uint32_t child_uint32); +getdns_return_t _getdns_list_append_const_bindata(getdns_list *list, + size_t size, const uint8_t *data); + +getdns_return_t _getdns_dict_set_const_bindata(getdns_dict *dict, + const char *name, size_t size, const uint8_t *data); + /** * private function (API users should not be calling this), this uses library * routines to make a copy of the list - would be faster to make the copy directly