1 /**
2 * Parse a serialized wdns_rrset_t.
3 *
4 * \param[out] rrset parsed RRset
5 * \param[in] buf serialized RRset
6 * \param[in] sz length of buf
7 */
8
9 wdns_res
wdns_deserialize_rrset(wdns_rrset_t * rrset,const uint8_t * buf,size_t sz)10 wdns_deserialize_rrset(wdns_rrset_t *rrset, const uint8_t *buf, size_t sz)
11 {
12
13 #define copy_bytes(ptr, len) do { \
14 if (bytes_read + len > sz) { \
15 wdns_clear_rrset(rrset); \
16 return (wdns_res_overflow); \
17 } \
18 memcpy(ptr, buf, len); \
19 buf += len; \
20 bytes_read += len; \
21 } while(0)
22
23 size_t bytes_read = 0;
24
25 memset(rrset, 0, sizeof(*rrset));
26
27 /* length of name */
28 copy_bytes(&rrset->name.len, 1);
29
30 /* name */
31 rrset->name.data = my_malloc(rrset->name.len);
32 copy_bytes(rrset->name.data, rrset->name.len);
33
34 /* type */
35 copy_bytes(&rrset->rrtype, 2);
36
37 /* class */
38 copy_bytes(&rrset->rrclass, 2);
39
40 /* ttl */
41 copy_bytes(&rrset->rrttl, 4);
42
43 /* number of rdatas */
44 copy_bytes(&rrset->n_rdatas, 2);
45
46 /* rdatas */
47 rrset->rdatas = my_calloc(1, sizeof(void *) * rrset->n_rdatas);
48 for (size_t i = 0; i < rrset->n_rdatas; i++) {
49 uint16_t rdlen;
50
51 copy_bytes(&rdlen, 2);
52 rrset->rdatas[i] = my_malloc(sizeof(rrset->rdatas[i]) + rdlen);
53 rrset->rdatas[i]->len = rdlen;
54 copy_bytes(&rrset->rdatas[i]->data, rdlen);
55 }
56
57 return (wdns_res_success);
58 }
59