libnm: add NMSockAddrEndpoint API
NMSockAddrEndpoint is an immutable structure that contains the endpoint string of a service. It also includes the (naive) parsing of the host and port/service parts. This will be used for the endpoint of WireGuard's peers. But since endpoints are not something specific to WireGuard, give it a general name (and purpose) independent from WireGuard. Essentially, this structure takes a string in a manner that libnm understands, and uses it for node and service arguments for getaddrinfo(). NMSockAddrEndpoint allows to have endpoints that are not parsable into a host and port part. That is useful because our settings need to be able to hold invalid values. That is for forward compatibility (server sends a new endpoint format) and for better error handling (have invalid settings that can be constructed without loss, but fail later during the NMSetting:verify() step).
This commit is contained in:
@@ -614,6 +614,25 @@ gboolean _nm_setting_sriov_sort_vfs (NMSettingSriov *setting);
|
|||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
typedef struct _NMSockAddrEndpoint NMSockAddrEndpoint;
|
||||||
|
|
||||||
|
NMSockAddrEndpoint *nm_sock_addr_endpoint_new (const char *endpoint);
|
||||||
|
|
||||||
|
NMSockAddrEndpoint *nm_sock_addr_endpoint_ref (NMSockAddrEndpoint *self);
|
||||||
|
void nm_sock_addr_endpoint_unref (NMSockAddrEndpoint *self);
|
||||||
|
|
||||||
|
const char *nm_sock_addr_endpoint_get_endpoint (NMSockAddrEndpoint *self);
|
||||||
|
const char *nm_sock_addr_endpoint_get_host (NMSockAddrEndpoint *self);
|
||||||
|
gint32 nm_sock_addr_endpoint_get_port (NMSockAddrEndpoint *self);
|
||||||
|
|
||||||
|
gboolean nm_sock_addr_endpoint_get_fixed_sockaddr (NMSockAddrEndpoint *self,
|
||||||
|
gpointer sockaddr);
|
||||||
|
|
||||||
|
#define nm_auto_unref_sockaddrendpoint nm_auto(_nm_auto_unref_sockaddrendpoint)
|
||||||
|
NM_AUTO_DEFINE_FCN_VOID0 (NMSockAddrEndpoint *, _nm_auto_unref_sockaddrendpoint, nm_sock_addr_endpoint_unref)
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
typedef struct _NMSettInfoSetting NMSettInfoSetting;
|
typedef struct _NMSettInfoSetting NMSettInfoSetting;
|
||||||
typedef struct _NMSettInfoProperty NMSettInfoProperty;
|
typedef struct _NMSettInfoProperty NMSettInfoProperty;
|
||||||
|
|
||||||
|
@@ -59,6 +59,277 @@
|
|||||||
* access points and devices, among other things.
|
* access points and devices, among other things.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
struct _NMSockAddrEndpoint {
|
||||||
|
const char *host;
|
||||||
|
guint16 port;
|
||||||
|
guint refcount;
|
||||||
|
char endpoint[];
|
||||||
|
};
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
NM_IS_SOCK_ADDR_ENDPOINT (const NMSockAddrEndpoint *self)
|
||||||
|
{
|
||||||
|
return self && self->refcount > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
_parse_endpoint (char *str,
|
||||||
|
guint16 *out_port)
|
||||||
|
{
|
||||||
|
char *s;
|
||||||
|
const char *s_port;
|
||||||
|
gint16 port;
|
||||||
|
|
||||||
|
/* Like
|
||||||
|
* - https://git.zx2c4.com/WireGuard/tree/src/tools/config.c?id=5e99a6d43fe2351adf36c786f5ea2086a8fe7ab8#n192
|
||||||
|
* - https://github.com/systemd/systemd/blob/911649fdd43f3a9158b847947724a772a5a45c34/src/network/netdev/wireguard.c#L614
|
||||||
|
*/
|
||||||
|
|
||||||
|
g_strstrip (str);
|
||||||
|
|
||||||
|
if (!str[0])
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (str[0] == '[') {
|
||||||
|
str++;
|
||||||
|
s = strchr (str, ']');
|
||||||
|
if (!s)
|
||||||
|
return NULL;
|
||||||
|
if (s == str)
|
||||||
|
return NULL;
|
||||||
|
if (s[1] != ':')
|
||||||
|
return NULL;
|
||||||
|
if (!s[2])
|
||||||
|
return NULL;
|
||||||
|
*s = '\0';
|
||||||
|
s_port = &s[2];
|
||||||
|
} else {
|
||||||
|
s = strrchr (str, ':');
|
||||||
|
if (!s)
|
||||||
|
return NULL;
|
||||||
|
if (s == str)
|
||||||
|
return NULL;
|
||||||
|
if (!s[1])
|
||||||
|
return NULL;
|
||||||
|
*s = '\0';
|
||||||
|
s_port = &s[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!NM_STRCHAR_ALL (s_port, ch, (ch >= '0' && ch <= '9')))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
port = _nm_utils_ascii_str_to_int64 (s_port, 10, 1, G_MAXUINT16, 0);
|
||||||
|
if (port == 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
*out_port = port;
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nm_sock_addr_endpoint_new:
|
||||||
|
* @endpoint: the endpoint string.
|
||||||
|
*
|
||||||
|
* This function cannot fail, even if the @endpoint is invalid.
|
||||||
|
* The reason is to allow NMSockAddrEndpoint also to be used
|
||||||
|
* for tracking invalid endpoints. Use nm_sock_addr_endpoint_get_host()
|
||||||
|
* to determine whether the endpoint is valid.
|
||||||
|
*
|
||||||
|
* Returns: (transfer full): the new #NMSockAddrEndpoint endpoint.
|
||||||
|
*/
|
||||||
|
NMSockAddrEndpoint *
|
||||||
|
nm_sock_addr_endpoint_new (const char *endpoint)
|
||||||
|
{
|
||||||
|
NMSockAddrEndpoint *ep;
|
||||||
|
gsize l_endpoint;
|
||||||
|
gsize l_host = 0;
|
||||||
|
gsize i;
|
||||||
|
gs_free char *host_clone = NULL;
|
||||||
|
const char *host;
|
||||||
|
guint16 port;
|
||||||
|
|
||||||
|
g_return_val_if_fail (endpoint, NULL);
|
||||||
|
|
||||||
|
l_endpoint = strlen (endpoint) + 1;
|
||||||
|
|
||||||
|
host = _parse_endpoint (nm_strndup_a (200, endpoint, l_endpoint - 1, &host_clone),
|
||||||
|
&port);
|
||||||
|
|
||||||
|
if (host)
|
||||||
|
l_host = strlen (host) + 1;
|
||||||
|
|
||||||
|
ep = g_malloc (sizeof (NMSockAddrEndpoint) + l_endpoint + l_host);
|
||||||
|
ep->refcount = 1;
|
||||||
|
memcpy (ep->endpoint, endpoint, l_endpoint);
|
||||||
|
if (host) {
|
||||||
|
i = l_endpoint;
|
||||||
|
memcpy (&ep->endpoint[i], host, l_host);
|
||||||
|
ep->host = &ep->endpoint[i];
|
||||||
|
ep->port = port;
|
||||||
|
} else {
|
||||||
|
ep->host = NULL;
|
||||||
|
ep->port = 0;
|
||||||
|
}
|
||||||
|
return ep;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nm_sock_addr_endpoint_ref:
|
||||||
|
* @self: (allow-none): the #NMSockAddrEndpoint
|
||||||
|
*/
|
||||||
|
NMSockAddrEndpoint *
|
||||||
|
nm_sock_addr_endpoint_ref (NMSockAddrEndpoint *self)
|
||||||
|
{
|
||||||
|
if (!self)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
g_return_val_if_fail (NM_IS_SOCK_ADDR_ENDPOINT (self), NULL);
|
||||||
|
|
||||||
|
nm_assert (self->refcount < G_MAXUINT);
|
||||||
|
|
||||||
|
self->refcount++;
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nm_sock_addr_endpoint_unref:
|
||||||
|
* @self: (allow-none): the #NMSockAddrEndpoint
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
nm_sock_addr_endpoint_unref (NMSockAddrEndpoint *self)
|
||||||
|
{
|
||||||
|
if (!self)
|
||||||
|
return;
|
||||||
|
|
||||||
|
g_return_if_fail (NM_IS_SOCK_ADDR_ENDPOINT (self));
|
||||||
|
|
||||||
|
if (--self->refcount == 0)
|
||||||
|
g_free (self);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nm_sock_addr_endpoint_get_endpoint:
|
||||||
|
* @self: the #NMSockAddrEndpoint
|
||||||
|
*
|
||||||
|
* Gives the endpoint string. Since #NMSockAddrEndpoint's only
|
||||||
|
* information is the endpoint string, this can be used for comparing
|
||||||
|
* to instances for equality and order them lexically.
|
||||||
|
*
|
||||||
|
* Returns: (transfer none): the endpoint.
|
||||||
|
*/
|
||||||
|
const char *
|
||||||
|
nm_sock_addr_endpoint_get_endpoint (NMSockAddrEndpoint *self)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (NM_IS_SOCK_ADDR_ENDPOINT (self), NULL);
|
||||||
|
|
||||||
|
return self->endpoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nm_sock_addr_endpoint_get_host:
|
||||||
|
* @self: the #NMSockAddrEndpoint
|
||||||
|
*
|
||||||
|
* Returns: (transfer none): the parsed host part of the endpoint.
|
||||||
|
* If the endpoint is invalid, %NULL will be returned.
|
||||||
|
*/
|
||||||
|
const char *
|
||||||
|
nm_sock_addr_endpoint_get_host (NMSockAddrEndpoint *self)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (NM_IS_SOCK_ADDR_ENDPOINT (self), NULL);
|
||||||
|
|
||||||
|
return self->host;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nm_sock_addr_endpoint_get_port:
|
||||||
|
* @self: the #NMSockAddrEndpoint
|
||||||
|
*
|
||||||
|
* Returns: the parsed port part of the endpoint (the service).
|
||||||
|
* If the endpoint is invalid, -1 will be returned.
|
||||||
|
*/
|
||||||
|
gint32
|
||||||
|
nm_sock_addr_endpoint_get_port (NMSockAddrEndpoint *self)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (NM_IS_SOCK_ADDR_ENDPOINT (self), -1);
|
||||||
|
|
||||||
|
return self->host ? (int) self->port : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
nm_sock_addr_endpoint_get_fixed_sockaddr (NMSockAddrEndpoint *self,
|
||||||
|
gpointer sockaddr)
|
||||||
|
{
|
||||||
|
int addr_family;
|
||||||
|
NMIPAddr addrbin;
|
||||||
|
const char *s;
|
||||||
|
guint scope_id = 0;
|
||||||
|
|
||||||
|
g_return_val_if_fail (NM_IS_SOCK_ADDR_ENDPOINT (self), FALSE);
|
||||||
|
g_return_val_if_fail (sockaddr, FALSE);
|
||||||
|
|
||||||
|
if (!self->host)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (nm_utils_parse_inaddr_bin (AF_UNSPEC, self->host, &addr_family, &addrbin))
|
||||||
|
goto good;
|
||||||
|
|
||||||
|
/* See if there is an IPv6 scope-id...
|
||||||
|
*
|
||||||
|
* Note that it does not make sense to persist connection profiles to disk,
|
||||||
|
* that refenrence a scope-id (because the interface's ifindex changes on
|
||||||
|
* reboot). However, we also support runtime only changes like `nmcli device modify`
|
||||||
|
* where nothing is persisted to disk. At least in that case, passing a scope-id
|
||||||
|
* might be reasonable. So, parse that too. */
|
||||||
|
s = strchr (self->host, '%');
|
||||||
|
if (!s)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if ( s[1] == '\0'
|
||||||
|
|| !NM_STRCHAR_ALL (&s[1], ch, (ch >= '0' && ch <= '9')))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
scope_id = _nm_utils_ascii_str_to_int64 (&s[1], 10, 0, G_MAXINT32, G_MAXUINT);
|
||||||
|
if (scope_id == G_MAXUINT && errno)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
{
|
||||||
|
gs_free char *tmp_str = NULL;
|
||||||
|
const char *host_part;
|
||||||
|
|
||||||
|
host_part = nm_strndup_a (200, self->host, s - self->host, &tmp_str);
|
||||||
|
if (nm_utils_parse_inaddr_bin (AF_INET6, host_part, &addr_family, &addrbin))
|
||||||
|
goto good;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
good:
|
||||||
|
switch (addr_family) {
|
||||||
|
case AF_INET:
|
||||||
|
*((struct sockaddr_in *) sockaddr) = (struct sockaddr_in) {
|
||||||
|
.sin_family = AF_INET,
|
||||||
|
.sin_addr = addrbin.addr4_struct,
|
||||||
|
.sin_port = htons (self->port),
|
||||||
|
};
|
||||||
|
return TRUE;
|
||||||
|
case AF_INET6:
|
||||||
|
*((struct sockaddr_in6 *) sockaddr) = (struct sockaddr_in6) {
|
||||||
|
.sin6_family = AF_INET6,
|
||||||
|
.sin6_addr = addrbin.addr6,
|
||||||
|
.sin6_port = htons (self->port),
|
||||||
|
.sin6_scope_id = scope_id,
|
||||||
|
.sin6_flowinfo = 0,
|
||||||
|
};
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
struct IsoLangToEncodings
|
struct IsoLangToEncodings
|
||||||
{
|
{
|
||||||
const char *lang;
|
const char *lang;
|
||||||
|
@@ -40,6 +40,8 @@
|
|||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
typedef struct _NMVariantAttributeSpec NMVariantAttributeSpec;
|
typedef struct _NMVariantAttributeSpec NMVariantAttributeSpec;
|
||||||
|
|
||||||
/* SSID helpers */
|
/* SSID helpers */
|
||||||
|
@@ -5522,6 +5522,158 @@ test_setting_user_data (void)
|
|||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
typedef union {
|
||||||
|
struct sockaddr sa;
|
||||||
|
struct sockaddr_in in;
|
||||||
|
struct sockaddr_in6 in6;
|
||||||
|
} SockAddrUnion;
|
||||||
|
|
||||||
|
static void
|
||||||
|
_sock_addr_endpoint (const char *endpoint,
|
||||||
|
const char *host,
|
||||||
|
gint32 port)
|
||||||
|
{
|
||||||
|
nm_auto_unref_sockaddrendpoint NMSockAddrEndpoint *ep = NULL;
|
||||||
|
const char *s_endpoint;
|
||||||
|
const char *s_host;
|
||||||
|
gint32 s_port;
|
||||||
|
SockAddrUnion sockaddr = { };
|
||||||
|
|
||||||
|
g_assert (endpoint);
|
||||||
|
g_assert (!host == (port == -1));
|
||||||
|
g_assert (port >= -1 && port <= G_MAXUINT16);
|
||||||
|
|
||||||
|
ep = nm_sock_addr_endpoint_new (endpoint);
|
||||||
|
g_assert (ep);
|
||||||
|
|
||||||
|
s_endpoint = nm_sock_addr_endpoint_get_endpoint (ep);
|
||||||
|
s_host = nm_sock_addr_endpoint_get_host (ep);
|
||||||
|
s_port = nm_sock_addr_endpoint_get_port (ep);
|
||||||
|
g_assert_cmpstr (endpoint, ==, s_endpoint);
|
||||||
|
g_assert_cmpstr (host, ==, s_host);
|
||||||
|
g_assert_cmpint (port, ==, s_port);
|
||||||
|
|
||||||
|
g_assert (!nm_sock_addr_endpoint_get_fixed_sockaddr (ep, &sockaddr));
|
||||||
|
|
||||||
|
if (endpoint[0] != ' ') {
|
||||||
|
gs_free char *endpoint2 = NULL;
|
||||||
|
|
||||||
|
/* also test with a leading space */
|
||||||
|
endpoint2 = g_strdup_printf (" %s", endpoint);
|
||||||
|
_sock_addr_endpoint (endpoint2, host, port);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (endpoint[0] && endpoint[strlen (endpoint) - 1] != ' ') {
|
||||||
|
gs_free char *endpoint2 = NULL;
|
||||||
|
|
||||||
|
/* also test with a trailing space */
|
||||||
|
endpoint2 = g_strdup_printf ("%s ", endpoint);
|
||||||
|
_sock_addr_endpoint (endpoint2, host, port);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_sock_addr_endpoint_fixed (const char *endpoint,
|
||||||
|
const char *host,
|
||||||
|
guint16 port,
|
||||||
|
guint scope_id)
|
||||||
|
{
|
||||||
|
nm_auto_unref_sockaddrendpoint NMSockAddrEndpoint *ep = NULL;
|
||||||
|
const char *s_endpoint;
|
||||||
|
const char *s_host;
|
||||||
|
gint32 s_port;
|
||||||
|
int addr_family;
|
||||||
|
NMIPAddr addrbin;
|
||||||
|
SockAddrUnion sockaddr = { };
|
||||||
|
|
||||||
|
g_assert (endpoint);
|
||||||
|
g_assert (host);
|
||||||
|
g_assert (port > 0);
|
||||||
|
|
||||||
|
if (!nm_utils_parse_inaddr_bin (AF_UNSPEC, host, &addr_family, &addrbin))
|
||||||
|
g_assert_not_reached ();
|
||||||
|
|
||||||
|
ep = nm_sock_addr_endpoint_new (endpoint);
|
||||||
|
g_assert (ep);
|
||||||
|
|
||||||
|
s_endpoint = nm_sock_addr_endpoint_get_endpoint (ep);
|
||||||
|
s_host = nm_sock_addr_endpoint_get_host (ep);
|
||||||
|
s_port = nm_sock_addr_endpoint_get_port (ep);
|
||||||
|
g_assert_cmpstr (endpoint, ==, s_endpoint);
|
||||||
|
g_assert_cmpstr (NULL, !=, s_host);
|
||||||
|
g_assert_cmpint (port, ==, s_port);
|
||||||
|
|
||||||
|
if (!nm_sock_addr_endpoint_get_fixed_sockaddr (ep, &sockaddr))
|
||||||
|
g_assert_not_reached ();
|
||||||
|
|
||||||
|
g_assert_cmpint (sockaddr.sa.sa_family, ==, addr_family);
|
||||||
|
if (addr_family == AF_INET) {
|
||||||
|
const SockAddrUnion s = {
|
||||||
|
.in = {
|
||||||
|
.sin_family = AF_INET,
|
||||||
|
.sin_addr = addrbin.addr4_struct,
|
||||||
|
.sin_port = htons (port),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
g_assert_cmpint (sockaddr.in.sin_addr.s_addr, ==, addrbin.addr4);
|
||||||
|
g_assert_cmpint (sockaddr.in.sin_port, ==, htons (port));
|
||||||
|
g_assert (memcmp (&s, &sockaddr, sizeof (s.in)) == 0);
|
||||||
|
} else if (addr_family == AF_INET6) {
|
||||||
|
const SockAddrUnion s = {
|
||||||
|
.in6 = {
|
||||||
|
.sin6_family = AF_INET6,
|
||||||
|
.sin6_addr = addrbin.addr6,
|
||||||
|
.sin6_scope_id = scope_id,
|
||||||
|
.sin6_port = htons (port),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
g_assert (memcmp (&sockaddr.in6.sin6_addr, &addrbin, sizeof (addrbin.addr6)) == 0);
|
||||||
|
g_assert_cmpint (sockaddr.in6.sin6_port, ==, htons (port));
|
||||||
|
g_assert_cmpint (sockaddr.in6.sin6_scope_id, ==, scope_id);
|
||||||
|
g_assert_cmpint (sockaddr.in6.sin6_flowinfo, ==, 0);
|
||||||
|
g_assert (memcmp (&s, &sockaddr, sizeof (s.in6)) == 0);
|
||||||
|
} else
|
||||||
|
g_assert_not_reached ();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_sock_addr_endpoint (void)
|
||||||
|
{
|
||||||
|
_sock_addr_endpoint ("", NULL, -1);
|
||||||
|
_sock_addr_endpoint (":", NULL, -1);
|
||||||
|
_sock_addr_endpoint ("a", NULL, -1);
|
||||||
|
_sock_addr_endpoint ("a:", NULL, -1);
|
||||||
|
_sock_addr_endpoint (":a", NULL, -1);
|
||||||
|
_sock_addr_endpoint ("[]:a", NULL, -1);
|
||||||
|
_sock_addr_endpoint ("[]a", NULL, -1);
|
||||||
|
_sock_addr_endpoint ("[]:", NULL, -1);
|
||||||
|
_sock_addr_endpoint ("[a]b", NULL, -1);
|
||||||
|
_sock_addr_endpoint ("[a:b", NULL, -1);
|
||||||
|
_sock_addr_endpoint ("[a[:b", NULL, -1);
|
||||||
|
_sock_addr_endpoint ("a:6", "a", 6);
|
||||||
|
_sock_addr_endpoint ("a:6", "a", 6);
|
||||||
|
_sock_addr_endpoint ("[a]:6", "a", 6);
|
||||||
|
_sock_addr_endpoint ("[a]:6", "a", 6);
|
||||||
|
_sock_addr_endpoint ("[a]:655", "a", 655);
|
||||||
|
_sock_addr_endpoint ("[ab]:][6", NULL, -1);
|
||||||
|
_sock_addr_endpoint ("[ab]:]:[6", NULL, -1);
|
||||||
|
_sock_addr_endpoint ("[a[]:b", NULL, -1);
|
||||||
|
_sock_addr_endpoint ("[192.169.6.x]:6", "192.169.6.x", 6);
|
||||||
|
_sock_addr_endpoint ("[192.169.6.x]:0", NULL, -1);
|
||||||
|
_sock_addr_endpoint ("192.169.6.7:0", NULL, -1);
|
||||||
|
|
||||||
|
_sock_addr_endpoint_fixed ("192.169.6.7:6", "192.169.6.7", 6, 0);
|
||||||
|
_sock_addr_endpoint_fixed ("[192.169.6.7]:6", "192.169.6.7", 6, 0);
|
||||||
|
_sock_addr_endpoint_fixed ("[a:b::]:6", "a:b::", 6, 0);
|
||||||
|
_sock_addr_endpoint_fixed ("[a:b::%7]:6", "a:b::", 6, 7);
|
||||||
|
_sock_addr_endpoint_fixed ("a:b::1%75:6", "a:b::1", 6, 75);
|
||||||
|
_sock_addr_endpoint_fixed ("a:b::1%0:64", "a:b::1", 64, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_hexstr2bin (void)
|
test_hexstr2bin (void)
|
||||||
{
|
{
|
||||||
@@ -7735,6 +7887,8 @@ int main (int argc, char **argv)
|
|||||||
g_test_add_func ("/core/general/test_setting_compare_default_strv", test_setting_compare_default_strv);
|
g_test_add_func ("/core/general/test_setting_compare_default_strv", test_setting_compare_default_strv);
|
||||||
g_test_add_func ("/core/general/test_setting_user_data", test_setting_user_data);
|
g_test_add_func ("/core/general/test_setting_user_data", test_setting_user_data);
|
||||||
|
|
||||||
|
g_test_add_func ("/core/general/test_sock_addr_endpoint", test_sock_addr_endpoint);
|
||||||
|
|
||||||
g_test_add_func ("/core/general/hexstr2bin", test_hexstr2bin);
|
g_test_add_func ("/core/general/hexstr2bin", test_hexstr2bin);
|
||||||
g_test_add_func ("/core/general/nm_strquote", test_nm_strquote);
|
g_test_add_func ("/core/general/nm_strquote", test_nm_strquote);
|
||||||
g_test_add_func ("/core/general/test_nm_utils_uuid_generate_from_string", test_nm_utils_uuid_generate_from_string);
|
g_test_add_func ("/core/general/test_nm_utils_uuid_generate_from_string", test_nm_utils_uuid_generate_from_string);
|
||||||
|
Reference in New Issue
Block a user