Skip to content
Snippets Groups Projects
Commit fb5099c5 authored by Lubos Slovak's avatar Lubos Slovak
Browse files

RDATA modifications.

The previous approach made converting RDATA  to wire format too
  complex. Now RDATA items distinguish only between domain name
  and other data. The format is given by a descriptor.

TODO: Consider saving the length of the data to the byte array
      always, so getting it would not require that huge switch.

refs #119
parent 9f91e89e
Branches
Tags
No related merge requests found
......@@ -142,34 +142,8 @@ uint dnslib_rdata_wire_size( const dnslib_rdata_t *rdata,
case DNSLIB_RDATA_WF_LITERAL_DNAME:
size += dnslib_dname_size(rdata->items[i].dname);
break;
case DNSLIB_RDATA_WF_BYTE:
size += 1;
break;
case DNSLIB_RDATA_WF_SHORT:
size += 2;
break;
case DNSLIB_RDATA_WF_LONG:
size += 4;
break;
case DNSLIB_RDATA_WF_A:
size += 4;
break;
case DNSLIB_RDATA_WF_AAAA:
size += 16;
break;
case DNSLIB_RDATA_WF_TEXT:
case DNSLIB_RDATA_WF_BINARYWITHLENGTH:
// size stored in the first byte, but the first byte also counts
size += rdata->items[i].raw_data[0] + 1;
break;
case DNSLIB_RDATA_WF_BINARY:
case DNSLIB_RDATA_WF_APL: // saved as binary
case DNSLIB_RDATA_WF_IPSECGATEWAY: // saved as binary
// size stored in the first byte, first byte doesn't count
size += rdata->items[i].raw_data[0];
break;
default:
assert(0);
size += rdata->items[i].raw_data[0];
}
}
return size;
......@@ -187,74 +161,55 @@ int dnslib_rdata_to_wire( const dnslib_rdata_t *rdata, const uint8_t *format,
for (int i = 0; i < rdata->count; ++i) {
assert(copied < MAX_RDATA_WIRE_SIZE);
const uint8_t *from = rdata->items[i].raw_data;
uint size = 0;
switch (format[i]) {
case DNSLIB_RDATA_WF_COMPRESSED_DNAME:
case DNSLIB_RDATA_WF_UNCOMPRESSED_DNAME:
case DNSLIB_RDATA_WF_LITERAL_DNAME: {
uint size = dnslib_dname_size(rdata->items[i].dname);
memcpy(to, dnslib_dname_name(rdata->items[i].dname), size);
to += size;
copied += size;
} break;
case DNSLIB_RDATA_WF_LITERAL_DNAME:
size = dnslib_dname_size(rdata->items[i].dname);
from = dnslib_dname_name(rdata->items[i].dname);
break;
case DNSLIB_RDATA_WF_BYTE:
*(to++) = rdata->items[i].int8;
++copied;
size = 1;
break;
case DNSLIB_RDATA_WF_SHORT:
size = 2;
break;
case DNSLIB_RDATA_WF_LONG:
size = 4;
break;
case DNSLIB_RDATA_WF_A:
size = 4;
break;
case DNSLIB_RDATA_WF_AAAA:
size = 16;
break;
case DNSLIB_RDATA_WF_SHORT: {
const uint8_t *from = (uint8_t *)(&rdata->items[i].int16);
// copy from last byte to first (little to big endian)
// TODO: check endianness of the machine
from += 1;
for (int i = 0; i < 2; ++i) {
*(to++) = *(from--);
++copied;
}
} break;
case DNSLIB_RDATA_WF_LONG: {
const uint8_t *from = (uint8_t *)(&rdata->items[i].int32);
// copy from last byte to first (little to big endian)
// TODO: check endianness of the machine
from += 3;
for (int i = 0; i < 4; ++i) {
*(to++) = *(from--);
++copied;
}
} break;
case DNSLIB_RDATA_WF_A: {
const uint8_t *from = rdata->items[i].a;
for (int i = 0; i < 4; ++i) {
*(to++) = *(from++);
++copied;
}
} break;
case DNSLIB_RDATA_WF_AAAA: {
const uint8_t *from = rdata->items[i].raw_data;
for (int i = 0; i < 16; ++i) {
*(to++) = *(from++);
++copied;
}
} break;
case DNSLIB_RDATA_WF_TEXT:
case DNSLIB_RDATA_WF_BINARYWITHLENGTH:
// size stored in the first byte, but the first byte also needs to
// be copied
memcpy(to, rdata->items[i].raw_data,
rdata->items[i].raw_data[0] + 1);
copied += rdata->items[i].raw_data[0] + 1;
to += rdata->items[i].raw_data[0] + 1;
size = rdata->items[i].raw_data[0] + 1;
break;
case DNSLIB_RDATA_WF_BINARY:
case DNSLIB_RDATA_WF_APL: // saved as binary
case DNSLIB_RDATA_WF_IPSECGATEWAY: // saved as binary
// size stored in the first byte, first byte must not be copied
memcpy(to, &(rdata->items[i].raw_data[1]),
rdata->items[i].raw_data[0]);
copied += rdata->items[i].raw_data[0];
to += rdata->items[i].raw_data[0];
size = rdata->items[i].raw_data[0];
++to;
break;
default:
assert(0);
}
assert(size != 0);
assert(copied + size < MAX_RDATA_WIRE_SIZE);
memcpy(to, from, size);
to += size;
copied += size;
}
if (copied > buf_size) {
......@@ -278,53 +233,54 @@ int dnslib_rdata_compare( const dnslib_rdata_t *r1, const dnslib_rdata_t *r2,
int cmp = 0;
for (int i = 0; i < count; ++i) {
dnslib_rdata_item_t *item1 = &r2->items[i];
dnslib_rdata_item_t *item1 = &r1->items[i];
dnslib_rdata_item_t *item2 = &r2->items[i];
const uint8_t *data1 = r1->items[i].raw_data;
const uint8_t *data2 = r2->items[i].raw_data;
int size1, size2;
switch (format[i]) {
case DNSLIB_RDATA_WF_COMPRESSED_DNAME:
case DNSLIB_RDATA_WF_UNCOMPRESSED_DNAME:
case DNSLIB_RDATA_WF_LITERAL_DNAME:
cmp = dnslib_rdata_compare_binary(
dnslib_dname_name(item1->dname),
dnslib_dname_name(item2->dname),
dnslib_dname_size(item1->dname),
dnslib_dname_size(item2->dname));
data1 = dnslib_dname_name(item1->dname);
size1 = dnslib_dname_size(item1->dname);
data2 = dnslib_dname_name(item2->dname);
size2 = dnslib_dname_size(item2->dname);
break;
case DNSLIB_RDATA_WF_BYTE:
cmp = (item1->int8 == item2->int8) ? 0 : (
(r1->items[i].int8 < item2->int8) ? -1 : 1);
size1 = size2 = 1;
break;
case DNSLIB_RDATA_WF_SHORT:
cmp = (item1->int16 == item2->int16) ? 0 : (
(item1->int16 < item2->int16) ? -1 : 1);
size1 = size2 = 2;
break;
case DNSLIB_RDATA_WF_LONG:
cmp = (item1->int32 == item2->int32) ? 0 : (
(item1->int32 < item2->int32) ? -1 : 1);
size1 = size2 = 4;
break;
case DNSLIB_RDATA_WF_A:
cmp = dnslib_rdata_compare_binary(item1->a, item2->a, 4, 4);
size1 = size2 = 4;
break;
case DNSLIB_RDATA_WF_AAAA:
cmp = dnslib_rdata_compare_binary(item1->raw_data, item2->raw_data,
16, 16);
size1 = size2 = 16;
break;
case DNSLIB_RDATA_WF_TEXT:
case DNSLIB_RDATA_WF_BINARYWITHLENGTH:
cmp = dnslib_rdata_compare_binary(&item1->raw_data[1],
&item2->raw_data[1], (int)item1->raw_data[0],
(int)item2->raw_data[0]);
size1 = (int)item1->raw_data[0] + 1;
size2 = (int)item1->raw_data[0] + 1;
break;
case DNSLIB_RDATA_WF_BINARY:
case DNSLIB_RDATA_WF_APL: // saved as binary
case DNSLIB_RDATA_WF_IPSECGATEWAY: // saved as binary
cmp = dnslib_rdata_compare_binary(item1->a, item2->a, -1, -1);
size1 = -1;
size2 = -1;
break;
default:
assert(0);
}
cmp = dnslib_rdata_compare_binary(data1, data2, size1, size2);
if (cmp != 0) {
return cmp;
}
......
......@@ -27,16 +27,16 @@
*/
union dnslib_rdata_item {
dnslib_dname_t *dname; /*!< RDATA item represented as a domain name. */
uint8_t int8; /*!< 8bit unsigned integer */
uint16_t int16; /*!< 16bit unsigned integer */
uint32_t int32; /*!< 32bit unsigned integer */
uint8_t a[4]; /*!< A address - four 8bit integers */
/*!
* \brief RDATA item represented as raw array of octets.
*
* In most cases the first octet will be the length of the array. The only
* now known exception will be when storing AAAA address which has known
* length (sixteen 8bit integers), so there is no need to store the lenght.
* In some cases the first octet will be the length of the array.
* In other, the size is determined by the type (i.e. 4 bytes in case of
* IPv4 address).
*
* In some cases this length is also used in the wire format of RDATA
* (e.g. character-data as defined in RFC1035).
*/
uint8_t *raw_data;
};
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment