static int read_rdata_atom(namedb_type *db, uint16_t type, int index, uint32_t domain_count, domain_type **domains, rdata_atom_type *result) { uint8_t data[65536]; if (rdata_atom_is_domain(type, index)) { result->domain = read_domain(db, domain_count, domains); if (!result->domain) return 0; } else { uint16_t size; if (fread(&size, sizeof(size), 1, db->fd) != 1) return 0; size = ntohs(size); if (fread(data, sizeof(uint8_t), size, db->fd) != size) return 0; result->data = (uint16_t *) region_alloc( db->region, sizeof(uint16_t) + size); memcpy(result->data, &size, sizeof(uint16_t)); memcpy((uint8_t *) result->data + sizeof(uint16_t), data, size); } return 1; }
static void add_rdata_to_recyclebin(namedb_type* db, rr_type* rr) { /* add rdatas to recycle bin. */ size_t i; for(i=0; i<rr->rdata_count; i++) { if(!rdata_atom_is_domain(rr->type, i)) region_recycle(db->region, rr->rdatas[i].data, rdata_atom_size(rr->rdatas[i]) + sizeof(uint16_t)); } region_recycle(db->region, rr->rdatas, sizeof(rdata_atom_type)*rr->rdata_count); }
size_t rdata_maximum_wireformat_size(rrtype_descriptor_type *descriptor, size_t rdata_count, rdata_atom_type *rdatas) { size_t result = 0; size_t i; for (i = 0; i < rdata_count; ++i) { if (rdata_atom_is_domain(descriptor->type, i)) { result += domain_dname(rdata_atom_domain(rdatas[i]))->name_size; } else { result += rdata_atom_size(rdatas[i]); } } return result; }
/* * Compares two rdata arrays. * * Returns: * * zero if they are equal * non-zero if not * */ static int zrdatacmp(uint16_t type, rr_type *a, rr_type *b) { int i = 0; assert(a); assert(b); /* One is shorter than another */ if (a->rdata_count != b->rdata_count) return 1; /* Compare element by element */ for (i = 0; i < a->rdata_count; ++i) { if (rdata_atom_is_domain(type, i)) { if (rdata_atom_domain(a->rdatas[i]) != rdata_atom_domain(b->rdatas[i])) { return 1; } } else if(rdata_atom_is_literal_domain(type, i)) { if (rdata_atom_size(a->rdatas[i]) != rdata_atom_size(b->rdatas[i])) return 1; if (!dname_equal_nocase(rdata_atom_data(a->rdatas[i]), rdata_atom_data(b->rdatas[i]), rdata_atom_size(a->rdatas[i]))) return 1; } else { if (rdata_atom_size(a->rdatas[i]) != rdata_atom_size(b->rdatas[i])) { return 1; } if (memcmp(rdata_atom_data(a->rdatas[i]), rdata_atom_data(b->rdatas[i]), rdata_atom_size(a->rdatas[i])) != 0) { return 1; } } } /* Otherwise they are equal */ return 0; }
static int rdatas_equal(rdata_atom_type *a, rdata_atom_type *b, int num, uint16_t type) { int k; for(k = 0; k < num; k++) { if(rdata_atom_is_domain(type, k)) { if(dname_compare(domain_dname(a[k].domain), domain_dname(b[k].domain))!=0) return 0; } else { /* check length */ if(a[k].data[0] != b[k].data[0]) return 0; /* check data */ if(memcmp(a[k].data+1, b[k].data+1, a[k].data[0])!=0) return 0; } } return 1; }
int rdata_atoms_to_unknown_string(buffer_type *output, rrtype_descriptor_type *descriptor, size_t rdata_count, rdata_atom_type *rdatas) { size_t i; size_t size = rdata_maximum_wireformat_size(descriptor, rdata_count, rdatas); buffer_printf(output, " \\# %lu ", (unsigned long) size); for (i = 0; i < rdata_count; ++i) { if (rdata_atom_is_domain(descriptor->type, i)) { const dname_type *dname = domain_dname(rdata_atom_domain(rdatas[i])); hex_to_string( output, dname_name(dname), dname->name_size); } else { hex_to_string(output, rdata_atom_data(rdatas[i]), rdata_atom_size(rdatas[i])); } } return 1; }
void parse_unknown_rdata(uint16_t type, uint16_t *wireformat) { buffer_type packet; uint16_t size; ssize_t rdata_count; ssize_t i; rdata_atom_type *rdatas; if (wireformat) { size = *wireformat; } else { return; } buffer_create_from(&packet, wireformat + 1, *wireformat); rdata_count = rdata_wireformat_to_rdata_atoms(parser->region, parser->db->domains, type, size, &packet, &rdatas); if (rdata_count == -1) { zc_error_prev_line("bad unknown RDATA"); return; } for (i = 0; i < rdata_count; ++i) { if (rdata_atom_is_domain(type, i)) { zadd_rdata_domain(rdatas[i].domain); } else { zadd_rdata_wireformat(rdatas[i].data); } } region_recycle(parser->region, rdatas, rdata_count*sizeof(rdata_atom_type)); }