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