libnm-core: add new functions for DNS parsing
Introduce new functions to parse and normalize name servers. Their name contains "dns_uri" because they also support a URI-like syntax as: "dns+tls://192.0.2.0:553#example.org".
This commit is contained in:
@@ -810,6 +810,299 @@ nm_utils_dnsname_normalize(int addr_family, const char *dns, char **out_free)
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/*
|
||||
* nm_dns_uri_parse:
|
||||
* @addr_family: the address family, or AF_UNSPEC to autodetect it
|
||||
* @str: the name server URI string to parse
|
||||
* @dns: the name server descriptor to fill, or %NULL
|
||||
*
|
||||
* Parses the given name server URI string. Each name server is represented
|
||||
* by the following grammar:
|
||||
*
|
||||
* NAMESERVER := { PLAIN | TLS_URI | UDP_URI }
|
||||
* PLAIN := { ipv4address | ipv6address } [ '#' SERVERNAME ]
|
||||
* TLS_URI := 'dns+tls://' URI_ADDRESS [ ':' PORT ] [ '#' SERVERNAME ]
|
||||
* UDP_URI := 'dns+udp://' URI_ADDRESS [ ':' PORT ]
|
||||
* URI_ADDRESS := { ipv4address | '[' ipv6address [ '%' ifname ] ']' }
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* 192.0.2.0
|
||||
* 192.0.2.0#example.com
|
||||
* 2001:db8::1
|
||||
* dns+tls://192.0.2.0
|
||||
* dns+tls://[2001:db8::1]
|
||||
* dns+tls://192.0.2.0:53#example.com
|
||||
* dns+udp://[fe80::1%enp1s0]
|
||||
*
|
||||
* Note that on return, the lifetime of the members in the @dns struct is
|
||||
* the same as the input string @str.
|
||||
*
|
||||
* Returns: %TRUE on success, %FALSE on failure
|
||||
*/
|
||||
gboolean
|
||||
nm_dns_uri_parse(int addr_family, const char *str, NMDnsServer *dns)
|
||||
{
|
||||
NMDnsServer dns_stack;
|
||||
gs_free char *addr_port_heap = NULL;
|
||||
gs_free char *addr_heap = NULL;
|
||||
const char *addr_port;
|
||||
const char *addr;
|
||||
const char *name;
|
||||
const char *port;
|
||||
|
||||
nm_assert_addr_family_or_unspec(addr_family);
|
||||
|
||||
if (!dns)
|
||||
dns = &dns_stack;
|
||||
|
||||
if (!str)
|
||||
return FALSE;
|
||||
|
||||
*dns = (NMDnsServer) {
|
||||
.port = -1,
|
||||
};
|
||||
|
||||
if (NM_STR_HAS_PREFIX(str, "dns+tls://")) {
|
||||
dns->scheme = NM_DNS_URI_SCHEME_TLS;
|
||||
str += NM_STRLEN("dns+tls://");
|
||||
} else if (NM_STR_HAS_PREFIX(str, "dns+udp://")) {
|
||||
dns->scheme = NM_DNS_URI_SCHEME_UDP;
|
||||
str += NM_STRLEN("dns+udp://");
|
||||
} else {
|
||||
name = strchr(str, '#');
|
||||
if (name) {
|
||||
str = nm_strndup_a(200, str, name - str, &addr_heap);
|
||||
name++;
|
||||
}
|
||||
|
||||
if (name && name[0] == '\0') {
|
||||
/* empty DoT server name is not allowed */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!nm_inet_parse_bin(addr_family, str, &dns->addr_family, &dns->addr))
|
||||
return FALSE;
|
||||
|
||||
dns->servername = name;
|
||||
dns->scheme = NM_DNS_URI_SCHEME_NONE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
addr_port = str;
|
||||
name = strrchr(addr_port, '#');
|
||||
if (name) {
|
||||
addr_port = nm_strndup_a(100, addr_port, name - addr_port, &addr_port_heap);
|
||||
name++;
|
||||
if (*name == '\0') {
|
||||
/* empty DoT server name not allowed */
|
||||
return FALSE;
|
||||
}
|
||||
dns->servername = name;
|
||||
}
|
||||
|
||||
if (addr_family != AF_INET && *addr_port == '[') {
|
||||
const char *end;
|
||||
char *perc;
|
||||
|
||||
addr_family = AF_INET6;
|
||||
addr_port++;
|
||||
end = strchr(addr_port, ']');
|
||||
if (!end)
|
||||
return FALSE;
|
||||
addr = nm_strndup_a(100, addr_port, end - addr_port, &addr_heap);
|
||||
|
||||
/* IPv6 link-local scope-id */
|
||||
perc = strchr(addr, '%');
|
||||
if (perc) {
|
||||
*perc = '\0';
|
||||
if (g_strlcpy(dns->interface, perc + 1, sizeof(dns->interface))
|
||||
>= sizeof(dns->interface))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* port */
|
||||
end++;
|
||||
if (*end == ':') {
|
||||
end++;
|
||||
dns->port = _nm_utils_ascii_str_to_int64(end, 10, 0, 65535, G_MAXINT32);
|
||||
if (dns->port == G_MAXINT32)
|
||||
return FALSE;
|
||||
}
|
||||
} else if (addr_family != AF_INET6) {
|
||||
/* square brackets are mandatory for IPv6, so it must be IPv4 */
|
||||
|
||||
addr_family = AF_INET;
|
||||
addr = addr_port;
|
||||
|
||||
/* port */
|
||||
port = strchr(addr_port, ':');
|
||||
if (port) {
|
||||
addr = nm_strndup_a(100, addr_port, port - addr_port, &addr_heap);
|
||||
port++;
|
||||
dns->port = _nm_utils_ascii_str_to_int64(port, 10, 0, 65535, G_MAXINT32);
|
||||
if (dns->port == G_MAXINT32)
|
||||
return FALSE;
|
||||
}
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!nm_inet_parse_bin(addr_family, addr, &dns->addr_family, &dns->addr))
|
||||
return FALSE;
|
||||
|
||||
if (dns->scheme != NM_DNS_URI_SCHEME_TLS && dns->servername)
|
||||
return FALSE;
|
||||
|
||||
/* For now, allow the interface only for IPv6 link-local addresses */
|
||||
if (dns->interface[0]
|
||||
&& (dns->addr_family != AF_INET6 || !IN6_IS_ADDR_LINKLOCAL(&dns->addr.addr6)))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* @nm_dns_uri_parse_plain:
|
||||
* @addr_family: the address family, or AF_UNSPEC to autodetect it
|
||||
* @str: the name server URI string
|
||||
* @out_addrstr: the buffer to fill with the address string on return,
|
||||
* or %NULL. Must be of size at least NM_INET_ADDRSTRLEN.
|
||||
* @out_addr: the %NMIPAddr struct to fill on return, or %NULL
|
||||
*
|
||||
* Returns whether the string contains a "plain" (DNS over UDP on port 53)
|
||||
* name server. In such case, it fills the arguments with the address
|
||||
* of the name server.
|
||||
*
|
||||
* Returns: %TRUE on success, %FALSE if the string can't be parsed or
|
||||
* if it's not a plain name server.
|
||||
*/
|
||||
gboolean
|
||||
nm_dns_uri_parse_plain(int addr_family, const char *str, char *out_addrstr, NMIPAddr *out_addr)
|
||||
{
|
||||
NMDnsServer dns;
|
||||
|
||||
if (!nm_dns_uri_parse(addr_family, str, &dns))
|
||||
return FALSE;
|
||||
|
||||
switch (dns.scheme) {
|
||||
case NM_DNS_URI_SCHEME_TLS:
|
||||
return FALSE;
|
||||
case NM_DNS_URI_SCHEME_NONE:
|
||||
NM_SET_OUT(out_addr, dns.addr);
|
||||
if (out_addrstr) {
|
||||
nm_inet_ntop(dns.addr_family, &dns.addr, out_addrstr);
|
||||
}
|
||||
return TRUE;
|
||||
case NM_DNS_URI_SCHEME_UDP:
|
||||
if (dns.port != -1 && dns.port != 53)
|
||||
return FALSE;
|
||||
if (dns.interface[0])
|
||||
return FALSE;
|
||||
NM_SET_OUT(out_addr, dns.addr);
|
||||
if (out_addrstr) {
|
||||
nm_inet_ntop(dns.addr_family, &dns.addr, out_addrstr);
|
||||
}
|
||||
return TRUE;
|
||||
case NM_DNS_URI_SCHEME_UNKNOWN:
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* @nm_dns_uri_normalize:
|
||||
* @addr_family: the address family, or AF_UNSPEC to autodetect it
|
||||
* @str: the name server URI string
|
||||
* @out_free: the newly-allocated string to set on return, or %NULL
|
||||
*
|
||||
* Returns the "normal" representation for the given name server URI.
|
||||
* Note that a plain name server (DNS over UDP on port 53) is always
|
||||
* represented in the "legacy" (non-URI) form.
|
||||
*
|
||||
* Returns: the normalized DNS URI
|
||||
*/
|
||||
const char *
|
||||
nm_dns_uri_normalize(int addr_family, const char *str, char **out_free)
|
||||
{
|
||||
NMDnsServer dns;
|
||||
char addrstr[NM_INET_ADDRSTRLEN];
|
||||
char portstr[32];
|
||||
char *ret;
|
||||
gsize len;
|
||||
|
||||
nm_assert_addr_family_or_unspec(addr_family);
|
||||
nm_assert(str);
|
||||
nm_assert(out_free && !*out_free);
|
||||
|
||||
if (!nm_dns_uri_parse(addr_family, str, &dns))
|
||||
return NULL;
|
||||
|
||||
nm_inet_ntop(dns.addr_family, &dns.addr, addrstr);
|
||||
|
||||
if (dns.port != -1) {
|
||||
nm_assert(dns.port >= 0 && dns.port <= 65535);
|
||||
g_snprintf(portstr, sizeof(portstr), "%d", dns.port);
|
||||
}
|
||||
|
||||
switch (dns.scheme) {
|
||||
case NM_DNS_URI_SCHEME_NONE:
|
||||
len = strlen(addrstr);
|
||||
/* In the vast majority of cases, the name is in fact normalized. Check
|
||||
* whether it is, and don't duplicate the string. */
|
||||
if (strncmp(str, addrstr, len) == 0) {
|
||||
if (dns.servername) {
|
||||
if (str[len] == '#' && nm_streq(&str[len + 1], dns.servername))
|
||||
return str;
|
||||
} else {
|
||||
if (str[len] == '\0')
|
||||
return str;
|
||||
}
|
||||
}
|
||||
|
||||
if (!dns.servername)
|
||||
ret = g_strdup(addrstr);
|
||||
else
|
||||
ret = g_strconcat(addrstr, "#", dns.servername, NULL);
|
||||
break;
|
||||
case NM_DNS_URI_SCHEME_UDP:
|
||||
if (dns.interface[0] || dns.port != -1) {
|
||||
ret = g_strdup_printf("dns+udp://%s%s%s%s%s%s%s",
|
||||
dns.addr_family == AF_INET6 ? "[" : "",
|
||||
addrstr,
|
||||
dns.interface[0] ? "%" : "",
|
||||
dns.interface[0] ? dns.interface : "",
|
||||
dns.addr_family == AF_INET6 ? "]" : "",
|
||||
dns.port != -1 ? ":" : "",
|
||||
dns.port != -1 ? portstr : "");
|
||||
break;
|
||||
}
|
||||
ret = g_strdup_printf("%s%s%s", addrstr, dns.servername ? "#" : "", dns.servername ?: "");
|
||||
break;
|
||||
case NM_DNS_URI_SCHEME_TLS:
|
||||
ret = g_strdup_printf("dns+tls://%s%s%s%s%s%s%s%s%s",
|
||||
dns.addr_family == AF_INET6 ? "[" : "",
|
||||
addrstr,
|
||||
dns.interface[0] ? "%%" : "",
|
||||
dns.interface[0] ? dns.interface : "",
|
||||
dns.addr_family == AF_INET6 ? "]" : "",
|
||||
dns.port != -1 ? ":" : "",
|
||||
dns.port != -1 ? portstr : "",
|
||||
dns.servername ? "#" : "",
|
||||
dns.servername ?: "");
|
||||
break;
|
||||
case NM_DNS_URI_SCHEME_UNKNOWN:
|
||||
default:
|
||||
nm_assert_not_reached();
|
||||
ret = NULL;
|
||||
}
|
||||
|
||||
*out_free = ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
* nm_setting_ovs_other_config_check_key:
|
||||
* @key: (nullable): the key to check
|
||||
|
@@ -341,6 +341,29 @@ const char *nm_utils_dnsname_normalize(int addr_family, const char *dns, char **
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef enum {
|
||||
NM_DNS_URI_SCHEME_UNKNOWN,
|
||||
NM_DNS_URI_SCHEME_NONE,
|
||||
NM_DNS_URI_SCHEME_UDP,
|
||||
NM_DNS_URI_SCHEME_TLS,
|
||||
} NMDnsUriScheme;
|
||||
|
||||
typedef struct {
|
||||
NMIPAddr addr;
|
||||
const char *servername;
|
||||
char interface[NM_IFNAMSIZ];
|
||||
NMDnsUriScheme scheme;
|
||||
int addr_family;
|
||||
int port;
|
||||
} NMDnsServer;
|
||||
|
||||
gboolean nm_dns_uri_parse(int addr_family, const char *str, NMDnsServer *out_dns);
|
||||
gboolean
|
||||
nm_dns_uri_parse_plain(int addr_family, const char *str, char *out_addrstr, NMIPAddr *out_addr);
|
||||
const char *nm_dns_uri_normalize(int addr_family, const char *str, char **out_free);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
gboolean nm_setting_ovs_other_config_check_key(const char *key, GError **error);
|
||||
gboolean nm_setting_ovs_other_config_check_val(const char *val, GError **error);
|
||||
|
||||
|
@@ -11571,6 +11571,184 @@ test_dnsname(void)
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
t_dns_0(const char *str)
|
||||
{
|
||||
NMDnsServer server = {};
|
||||
gboolean ret;
|
||||
|
||||
ret = nm_dns_uri_parse(AF_UNSPEC, str, &server);
|
||||
|
||||
g_assert(!ret);
|
||||
}
|
||||
|
||||
static void
|
||||
dns_uri_parse_ok(const char *str,
|
||||
int addr_family,
|
||||
NMDnsUriScheme scheme,
|
||||
const char *addr,
|
||||
int port,
|
||||
const char *sname,
|
||||
const char *ifname)
|
||||
{
|
||||
NMDnsServer dns = {};
|
||||
char addrstr[NM_INET_ADDRSTRLEN];
|
||||
gboolean ret;
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
gboolean af_unspec = i;
|
||||
|
||||
ret = nm_dns_uri_parse(af_unspec ? AF_UNSPEC : addr_family, str, &dns);
|
||||
g_assert(ret);
|
||||
|
||||
g_assert_cmpint(addr_family, ==, dns.addr_family);
|
||||
g_assert_cmpint(port, ==, dns.port);
|
||||
g_assert_cmpstr(sname, ==, dns.servername);
|
||||
g_assert_cmpstr(ifname ?: "", ==, dns.interface);
|
||||
|
||||
nm_inet_ntop(dns.addr_family, &dns.addr, addrstr);
|
||||
g_assert_cmpstr(addrstr, ==, addr);
|
||||
|
||||
/* Parse with the wrong address family must fail */
|
||||
ret = nm_dns_uri_parse(addr_family == AF_INET ? AF_INET6 : AF_INET, str, &dns);
|
||||
g_assert(!ret);
|
||||
}
|
||||
}
|
||||
|
||||
#define t_dns_1(str, af, scheme, addr, port, sname, ifname) \
|
||||
dns_uri_parse_ok((str), \
|
||||
(AF_##af), \
|
||||
(NM_DNS_URI_SCHEME_##scheme), \
|
||||
(addr), \
|
||||
(port), \
|
||||
(sname), \
|
||||
(ifname))
|
||||
|
||||
static void
|
||||
test_dns_uri_parse(void)
|
||||
{
|
||||
/* clang-format off */
|
||||
t_dns_1("dns+tls://8.8.8.8", INET, TLS, "8.8.8.8", -1, NULL, NULL);
|
||||
t_dns_1("dns+tls://8.8.8.8", INET, TLS, "8.8.8.8", -1, NULL, NULL);
|
||||
t_dns_1("dns+tls://1.2.3.4#name", INET, TLS, "1.2.3.4", -1, "name", NULL);
|
||||
t_dns_1("dns+tls://1.2.3.4#a.b.c", INET, TLS, "1.2.3.4", -1, "a.b.c", NULL);
|
||||
t_dns_1("dns+tls://1.2.3.4:53", INET, TLS, "1.2.3.4", 53, NULL, NULL);
|
||||
t_dns_1("dns+tls://1.2.3.4:53#foobar", INET, TLS, "1.2.3.4", 53, "foobar", NULL);
|
||||
t_dns_1("dns+tls://192.168.120.250:99", INET, TLS, "192.168.120.250", 99, NULL, NULL);
|
||||
t_dns_1("dns+udp://8.8.8.8:65535", INET, UDP, "8.8.8.8", 65535, NULL, NULL);
|
||||
|
||||
t_dns_1("dns+udp://[fd01::1]", INET6, UDP, "fd01::1", -1, NULL, NULL);
|
||||
t_dns_1("dns+tls://[fd01::2]:5353", INET6, UDP, "fd01::2", 5353, NULL, NULL);
|
||||
t_dns_1("dns+tls://[::1]#name", INET6, UDP, "::1", -1, "name", NULL);
|
||||
t_dns_1("dns+tls://[::2]:65535#name", INET6, UDP, "::2", 65535, "name", NULL);
|
||||
t_dns_1("dns+udp://[::ffff:1.2.3.4]", INET6, UDP, "::ffff:1.2.3.4", -1, NULL, NULL);
|
||||
t_dns_1("dns+tls://[fe80::1%eth0]", INET6, UDP, "fe80::1", -1, NULL, "eth0");
|
||||
t_dns_1("dns+tls://[fe80::2%en1]:53#a", INET6, UDP, "fe80::2", 53, "a", "en1");
|
||||
t_dns_1("dns+tls://[fe80::1%en3456789012345]", INET6, UDP, "fe80::1", -1, NULL, "en3456789012345");
|
||||
|
||||
t_dns_1("1.2.3.4", INET, NONE, "1.2.3.4", -1, NULL, NULL);
|
||||
t_dns_1("1.2.3.4#foo", INET, NONE, "1.2.3.4", -1, "foo", NULL);
|
||||
t_dns_1("1::#x", INET6, NONE, "1::", -1, "x", NULL);
|
||||
t_dns_1("1::0#x", INET6, NONE, "1::", -1, "x", NULL);
|
||||
t_dns_1("192.168.0.1", INET, NONE, "192.168.0.1", -1, NULL, NULL);
|
||||
t_dns_1("192.168.0.1#tst.com", INET, NONE, "192.168.0.1", -1, "tst.com", NULL);
|
||||
t_dns_1("fe80::18", INET6, NONE, "fe80::18", -1, NULL, NULL);
|
||||
t_dns_1("fe80::18#foo.com", INET6, NONE, "fe80::18", -1, "foo.com", NULL);
|
||||
/* clang-format on */
|
||||
|
||||
t_dns_0("http://8.8.8.8"); /* unsupported schema */
|
||||
t_dns_0("dns+udp://1.2.3.4#name"); /* servername not supported for plain UDP */
|
||||
t_dns_0("dns+tls://1.2.3"); /* invalid address */
|
||||
t_dns_0("dns+tls://fd01::1"); /* IPv6 requires brackets */
|
||||
t_dns_0("dns+tls://[fd13:a:aaaa]"); /* invalid address */
|
||||
t_dns_0("dns+tls://1.2.3.4:1:1"); /* invalid syntax */
|
||||
t_dns_0("dns+tls://1.2.3.4#name#name"); /* invalid syntax */
|
||||
t_dns_0("dns+tls://1.2.3.4%eth0"); /* interface only allowed for IPv6 */
|
||||
t_dns_0("dns+tls://[2001::1%eth0]"); /* interface only allowed for IPv6 link-local */
|
||||
t_dns_0("dns+tls://[fe80::1%en34567890123456]"); /* interface name too long */
|
||||
t_dns_0("1.2.3.4#");
|
||||
t_dns_0("1::0#");
|
||||
t_dns_0("192.168.0.1:53");
|
||||
t_dns_0("192.168.0.1:53#example.com");
|
||||
t_dns_0("fe80::18%19");
|
||||
t_dns_0("fe80::18%lo");
|
||||
t_dns_0("[fe80::18]:53");
|
||||
t_dns_0("[fe80::18]:53%19");
|
||||
t_dns_0("[fe80::18]:53%lo");
|
||||
t_dns_0("fe80::18%19#hoge.com");
|
||||
t_dns_0("[fe80::18]:53#hoge.com");
|
||||
t_dns_0("[fe80::18]:53%19");
|
||||
t_dns_0("[fe80::18]:53%19#hoge.com");
|
||||
t_dns_0("[fe80::18]:53%lo");
|
||||
t_dns_0("[fe80::18]:53%lo#hoge.com");
|
||||
}
|
||||
|
||||
static void
|
||||
test_dns_uri_parse_plain(void)
|
||||
{
|
||||
struct {
|
||||
const char *input;
|
||||
int input_af;
|
||||
gboolean result;
|
||||
const char *addrstr;
|
||||
} values[] = {
|
||||
{"1.2.3.4", AF_INET, TRUE, "1.2.3.4"},
|
||||
{"1.2.3.4", AF_INET6, FALSE, NULL},
|
||||
{"1.2.3.4", AF_UNSPEC, TRUE, "1.2.3.4"},
|
||||
{"1234:5555:ffff:dddd::4321", AF_INET, FALSE, NULL},
|
||||
{"1234:5555:ffff:dddd::4321", AF_INET6, TRUE, "1234:5555:ffff:dddd::4321"},
|
||||
{"1234:5555:ffff:dddd::4321", AF_UNSPEC, TRUE, "1234:5555:ffff:dddd::4321"},
|
||||
{"192.0.2.1#example.com", AF_INET, TRUE, "192.0.2.1"},
|
||||
{"192.0.2.1#example.com", AF_UNSPEC, TRUE, "192.0.2.1"},
|
||||
{"192.0.2.1#example.com", AF_INET6, FALSE, NULL},
|
||||
{"dns+tls://1.2.3.4", AF_INET, FALSE, NULL},
|
||||
{"dns+tls://[fd01::1]", AF_INET, FALSE, NULL},
|
||||
{"dns+udp://1.2.3.4:53", AF_INET, TRUE, "1.2.3.4"},
|
||||
{"dns+udp://1.2.3.4:54", AF_INET, FALSE, NULL},
|
||||
{"dns+udp://[fd01::1]", AF_INET6, TRUE, "fd01::1"},
|
||||
{"dns+udp://[fd01::1]:53", AF_INET6, TRUE, "fd01::1"},
|
||||
{"dns+udp://[fd01::1]:60000", AF_INET, FALSE, NULL},
|
||||
};
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS(values); i++) {
|
||||
char addrstr[NM_INET_ADDRSTRLEN];
|
||||
gboolean result;
|
||||
NMIPAddr addr;
|
||||
|
||||
result = nm_dns_uri_parse_plain(values[i].input_af, values[i].input, addrstr, &addr);
|
||||
g_assert_cmpint(result, ==, values[i].result);
|
||||
if (result) {
|
||||
char buf[NM_INET_ADDRSTRLEN];
|
||||
|
||||
nm_inet_ntop(strchr(addrstr, ':') ? AF_INET6 : AF_INET, addr.addr_ptr, buf);
|
||||
g_assert_cmpstr(buf, ==, addrstr);
|
||||
g_assert_cmpstr(addrstr, ==, values[i].addrstr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
t_dns_uri_normalize(const char *input, const char *expected)
|
||||
{
|
||||
const char *str;
|
||||
gs_free char *str_free = NULL;
|
||||
|
||||
str = nm_dns_uri_normalize(AF_UNSPEC, input, &str_free);
|
||||
g_assert_cmpstr(str, ==, expected);
|
||||
}
|
||||
|
||||
static void
|
||||
test_dns_uri_normalize(void)
|
||||
{
|
||||
t_dns_uri_normalize("8.8.8.8", "8.8.8.8");
|
||||
t_dns_uri_normalize("dns+tls://[2001:0:0::1234]:999#name", "dns+tls://[2001::1234]:999#name");
|
||||
t_dns_uri_normalize("dns+udp://[0::1]:0123", "dns+udp://[::1]:123");
|
||||
t_dns_uri_normalize("8.8.8.888", NULL);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
test_dhcp_iaid_hexstr(void)
|
||||
{
|
||||
@@ -11946,6 +12124,9 @@ main(int argc, char **argv)
|
||||
g_test_add_func("/core/general/test_direct_string_is_refstr", test_direct_string_is_refstr);
|
||||
g_test_add_func("/core/general/test_connection_path", test_connection_path);
|
||||
g_test_add_func("/core/general/test_dnsname", test_dnsname);
|
||||
g_test_add_func("/core/general/test_dns_uri_parse", test_dns_uri_parse);
|
||||
g_test_add_func("/core/general/test_dns_uri_get_legacy", test_dns_uri_parse_plain);
|
||||
g_test_add_func("/core/general/test_dns_uri_normalize", test_dns_uri_normalize);
|
||||
g_test_add_func("/core/general/test_dhcp_iaid_hexstr", test_dhcp_iaid_hexstr);
|
||||
|
||||
return g_test_run();
|
||||
|
Reference in New Issue
Block a user