Merge pull request #30952 from rpigott/resolved-dnr
RFC9463: Discovery of Network-designated Resolvers
This commit is contained in:
@@ -905,6 +905,75 @@ int dns_name_to_wire_format(const char *domain, uint8_t *buffer, size_t len, boo
|
||||
return out - buffer;
|
||||
}
|
||||
|
||||
/* Decode a domain name according to RFC 1035 Section 3.1, without compression */
|
||||
int dns_name_from_wire_format(const uint8_t **data, size_t *len, char **ret) {
|
||||
_cleanup_free_ char *domain = NULL;
|
||||
const uint8_t *optval;
|
||||
size_t optlen, n = 0;
|
||||
int r;
|
||||
|
||||
assert(data);
|
||||
assert(len);
|
||||
assert(*data || *len == 0);
|
||||
assert(ret);
|
||||
|
||||
optval = *data;
|
||||
optlen = *len;
|
||||
|
||||
for (;;) {
|
||||
const char *label;
|
||||
uint8_t c;
|
||||
|
||||
/* Unterminated name */
|
||||
if (optlen == 0)
|
||||
return -EBADMSG;
|
||||
|
||||
/* RFC 1035 § 3.1 total length of encoded name is limited to 255 octets */
|
||||
if (*len - optlen > 255)
|
||||
return -EMSGSIZE;
|
||||
|
||||
c = *optval;
|
||||
optval++;
|
||||
optlen--;
|
||||
|
||||
if (c == 0)
|
||||
/* End label */
|
||||
break;
|
||||
if (c > DNS_LABEL_MAX)
|
||||
return -EBADMSG;
|
||||
if (c > optlen)
|
||||
return -EMSGSIZE;
|
||||
|
||||
/* Literal label */
|
||||
label = (const char*) optval;
|
||||
optval += c;
|
||||
optlen -= c;
|
||||
|
||||
if (!GREEDY_REALLOC(domain, n + (n != 0) + DNS_LABEL_ESCAPED_MAX))
|
||||
return -ENOMEM;
|
||||
|
||||
if (n != 0)
|
||||
domain[n++] = '.';
|
||||
|
||||
r = dns_label_escape(label, c, domain + n, DNS_LABEL_ESCAPED_MAX);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
n += r;
|
||||
}
|
||||
|
||||
if (!GREEDY_REALLOC(domain, n + 1))
|
||||
return -ENOMEM;
|
||||
|
||||
domain[n] = '\0';
|
||||
|
||||
*ret = TAKE_PTR(domain);
|
||||
*data = optval;
|
||||
*len = optlen;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
static bool srv_type_label_is_valid(const char *label, size_t n) {
|
||||
assert(label);
|
||||
|
||||
|
||||
@@ -79,6 +79,7 @@ bool dns_name_is_root(const char *name);
|
||||
bool dns_name_is_single_label(const char *name);
|
||||
|
||||
int dns_name_to_wire_format(const char *domain, uint8_t *buffer, size_t len, bool canonical);
|
||||
int dns_name_from_wire_format(const uint8_t **data, size_t *len, char **ret);
|
||||
|
||||
bool dns_srv_type_is_valid(const char *name);
|
||||
bool dnssd_srv_type_is_valid(const char *name);
|
||||
|
||||
@@ -347,6 +347,15 @@ struct in_addr_full *in_addr_full_free(struct in_addr_full *a) {
|
||||
return mfree(a);
|
||||
}
|
||||
|
||||
void in_addr_full_array_free(struct in_addr_full *addrs[], size_t n) {
|
||||
assert(addrs || n == 0);
|
||||
|
||||
FOREACH_ARRAY(a, addrs, n)
|
||||
in_addr_full_freep(a);
|
||||
|
||||
free(addrs);
|
||||
}
|
||||
|
||||
int in_addr_full_new(
|
||||
int family,
|
||||
const union in_addr_union *a,
|
||||
|
||||
@@ -39,6 +39,7 @@ struct in_addr_full {
|
||||
|
||||
struct in_addr_full *in_addr_full_free(struct in_addr_full *a);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(struct in_addr_full*, in_addr_full_free);
|
||||
void in_addr_full_array_free(struct in_addr_full *addrs[], size_t n);
|
||||
int in_addr_full_new(int family, const union in_addr_union *a, uint16_t port, int ifindex, const char *server_name, struct in_addr_full **ret);
|
||||
int in_addr_full_new_from_string(const char *s, struct in_addr_full **ret);
|
||||
const char* in_addr_full_to_string(struct in_addr_full *a);
|
||||
|
||||
Reference in New Issue
Block a user