Merge pull request #30952 from rpigott/resolved-dnr

RFC9463: Discovery of Network-designated Resolvers
This commit is contained in:
Lennart Poettering
2024-10-22 09:05:36 +02:00
committed by GitHub
46 changed files with 2029 additions and 124 deletions
+69
View File
@@ -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);
+1
View File
@@ -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);
+9
View File
@@ -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,
+1
View File
@@ -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);