/** * Create new domain name. * */ dname_type* dname_create(region_type* r, const char* str) { uint8_t wire[DNAME_MAXLEN]; uint8_t label_offsets[DNAME_MAXLEN]; uint8_t label_count = 0; size_t size = 0; const uint8_t* label = wire; dname_type *dname; ssize_t i; assert(r); assert(str); if (!dname_str2wire(wire, str)) { fprintf(stderr, "[%s] error: parse dname %s failed", logstr, str); return NULL; } while (1) { if (label_is_pointer(label)) { return NULL; } label_offsets[label_count] = (uint8_t) (label - wire); ++label_count; size += label_length(label) + 1; if (label_is_root(label)) { break; } label = label_next(label); } if (size > DNAME_MAXLEN) { return NULL; } assert(label_count <= DNAME_MAXLEN / 2 + 1); /* reverse label offsets. */ /* reverse label offsets. */ for (i = 0; i < label_count / 2; ++i) { uint8_t tmp = label_offsets[i]; label_offsets[i] = label_offsets[label_count - i - 1]; label_offsets[label_count - i - 1] = tmp; } dname = (dname_type *) region_alloc(r, (sizeof(dname_type) + (label_count + size) * sizeof(uint8_t))); dname->size = size; dname->label_count = label_count; memcpy((uint8_t *) dname_label_offsets(dname), label_offsets, label_count * sizeof(uint8_t)); memcpy((uint8_t *) dname_name(dname), wire, size * sizeof(uint8_t)); return dname; }
const dname_type * dname_make(region_type *region, const uint8_t *name, int normalize) { size_t name_size = 0; uint8_t label_offsets[MAXDOMAINLEN]; uint8_t label_count = 0; const uint8_t *label = name; dname_type *result; ssize_t i; assert(name); while (1) { if (label_is_pointer(label)) return NULL; label_offsets[label_count] = (uint8_t) (label - name); ++label_count; name_size += label_length(label) + 1; if (label_is_root(label)) break; label = label_next(label); } if (name_size > MAXDOMAINLEN) return NULL; assert(label_count <= MAXDOMAINLEN / 2 + 1); /* Reverse label offsets. */ for (i = 0; i < label_count / 2; ++i) { uint8_t tmp = label_offsets[i]; label_offsets[i] = label_offsets[label_count - i - 1]; label_offsets[label_count - i - 1] = tmp; } result = (dname_type *) region_alloc( region, (sizeof(dname_type) + (label_count + name_size) * sizeof(uint8_t))); result->name_size = name_size; result->label_count = label_count; memcpy((uint8_t *) dname_label_offsets(result), label_offsets, label_count * sizeof(uint8_t)); if (normalize) { uint8_t *dst = (uint8_t *) dname_name(result); const uint8_t *src = name; while (!label_is_root(src)) { ssize_t len = label_length(src); *dst++ = *src++; for (i = 0; i < len; ++i) { *dst++ = DNAME_NORMALIZE(*src++); } } *dst = *src; } else { memcpy((uint8_t *) dname_name(result), name, name_size * sizeof(uint8_t)); } return result; }