Commit 578c4af9 authored by Thomas Haller's avatar Thomas Haller

dhcp: refactor type of NMDhcpClient duid to be GBytes

GBytes is immutable. It's better suited to contain the duid parameter
then a GByteArray.
parent b0e98561
......@@ -69,7 +69,7 @@ typedef struct _NMDhcpClientPrivate {
char * iface;
GBytes * hwaddr;
char * uuid;
GByteArray * duid;
GBytes * duid;
GBytes * client_id;
char * hostname;
pid_t pid;
......@@ -139,7 +139,7 @@ nm_dhcp_client_get_uuid (NMDhcpClient *self)
return NM_DHCP_CLIENT_GET_PRIVATE (self)->uuid;
}
const GByteArray *
GBytes *
nm_dhcp_client_get_duid (NMDhcpClient *self)
{
g_return_val_if_fail (NM_IS_DHCP_CLIENT (self), NULL);
......@@ -354,7 +354,7 @@ nm_dhcp_client_stop_pid (pid_t pid, const char *iface)
}
static void
stop (NMDhcpClient *self, gboolean release, const GByteArray *duid)
stop (NMDhcpClient *self, gboolean release, GBytes *duid)
{
NMDhcpClientPrivate *priv;
......@@ -527,10 +527,11 @@ nm_dhcp_client_start_ip4 (NMDhcpClient *self,
return NM_DHCP_CLIENT_GET_CLASS (self)->ip4_start (self, dhcp_anycast_addr, last_ip4_address);
}
static GByteArray *
static GBytes *
generate_duid_from_machine_id (void)
{
GByteArray *duid;
const int DUID_SIZE = 18;
guint8 *duid_buffer;
GChecksum *sum;
guint8 buffer[32]; /* SHA256 digest size */
gsize sumlen = sizeof (buffer);
......@@ -538,6 +539,7 @@ generate_duid_from_machine_id (void)
uuid_t uuid;
gs_free char *machine_id_s = NULL;
gs_free char *str = NULL;
GBytes *duid;
machine_id_s = nm_utils_machine_id_read ();
if (nm_utils_machine_id_parse (machine_id_s, uuid)) {
......@@ -560,36 +562,31 @@ generate_duid_from_machine_id (void)
* u16: type (DUID-UUID = 4)
* u8[16]: UUID bytes
*/
duid = g_byte_array_sized_new (18);
g_byte_array_append (duid, (guint8 *) &duid_type, sizeof (duid_type));
duid_buffer = g_malloc (DUID_SIZE);
G_STATIC_ASSERT_EXPR (sizeof (duid_type) == 2);
memcpy (&duid_buffer[0], &duid_type, 2);
/* Since SHA256 is 256 bits, but UUID is 128 bits, we just take the first
* 128 bits of the SHA256 as the DUID-UUID.
*/
g_byte_array_append (duid, buffer, 16);
memcpy (&duid_buffer[2], buffer, 16);
duid = g_bytes_new_take (duid_buffer, DUID_SIZE);
nm_log_dbg (LOGD_DHCP, "dhcp: generated DUID %s",
(str = nm_dhcp_utils_duid_to_string (duid)));
return duid;
}
static GByteArray *
static GBytes *
get_duid (NMDhcpClient *self)
{
static GByteArray *duid = NULL;
GByteArray *copy = NULL;
static GBytes *duid = NULL;
if (G_UNLIKELY (duid == NULL)) {
if (G_UNLIKELY (!duid))
duid = generate_duid_from_machine_id ();
g_assert (duid);
}
if (G_LIKELY (duid)) {
copy = g_byte_array_sized_new (duid->len);
g_byte_array_append (copy, duid->data, duid->len);
}
return copy;
return g_bytes_ref (duid);
}
gboolean
......@@ -1019,11 +1016,7 @@ dispose (GObject *object)
g_clear_pointer (&priv->uuid, g_free);
g_clear_pointer (&priv->client_id, g_bytes_unref);
g_clear_pointer (&priv->hwaddr, g_bytes_unref);
if (priv->duid) {
g_byte_array_free (priv->duid, TRUE);
priv->duid = NULL;
}
g_clear_pointer (&priv->duid, g_bytes_unref);
G_OBJECT_CLASS (nm_dhcp_client_parent_class)->dispose (object);
......
......@@ -86,12 +86,12 @@ typedef struct {
const char *anycast_addr,
const struct in6_addr *ll_addr,
NMSettingIP6ConfigPrivacy privacy,
const GByteArray *duid,
GBytes *duid,
guint needed_prefixes);
void (*stop) (NMDhcpClient *self,
gboolean release,
const GByteArray *duid);
GBytes *duid);
/**
* get_duid:
......@@ -102,7 +102,7 @@ typedef struct {
* representation of the DUID. If no DUID is found, %NULL should be
* returned.
*/
GByteArray * (*get_duid) (NMDhcpClient *self);
GBytes *(*get_duid) (NMDhcpClient *self);
/* Signals */
void (*state_changed) (NMDhcpClient *self,
......@@ -125,7 +125,7 @@ int nm_dhcp_client_get_ifindex (NMDhcpClient *self);
const char *nm_dhcp_client_get_uuid (NMDhcpClient *self);
const GByteArray *nm_dhcp_client_get_duid (NMDhcpClient *self);
GBytes *nm_dhcp_client_get_duid (NMDhcpClient *self);
GBytes *nm_dhcp_client_get_hw_addr (NMDhcpClient *self);
......
......@@ -447,14 +447,20 @@ nm_dhcp_dhclient_create_config (const char *interface,
/* Roughly follow what dhclient's quotify_buf() and pretty_escape() functions do */
char *
nm_dhcp_dhclient_escape_duid (const GByteArray *duid)
nm_dhcp_dhclient_escape_duid (GBytes *duid)
{
char *escaped;
const guint8 *s = duid->data;
const guint8 *s, *s0;
gsize len;
char *d;
d = escaped = g_malloc0 ((duid->len * 4) + 1);
while (s < (duid->data + duid->len)) {
g_return_val_if_fail (duid, NULL);
s0 = g_bytes_get_data (duid, &len);
s = s0;
d = escaped = g_malloc ((len * 4) + 1);
while (s < (s0 + len)) {
if (!g_ascii_isprint (*s)) {
*d++ = '\\';
*d++ = '0' + ((*s >> 6) & 0x7);
......@@ -468,6 +474,7 @@ nm_dhcp_dhclient_escape_duid (const GByteArray *duid)
} else
*d++ = *s++;
}
*d++ = '\0';
return escaped;
}
......@@ -479,7 +486,7 @@ isoctal (const guint8 *p)
&& p[2] >= '0' && p[2] <= '7');
}
GByteArray *
GBytes *
nm_dhcp_dhclient_unescape_duid (const char *duid)
{
GByteArray *unescaped;
......@@ -510,7 +517,7 @@ nm_dhcp_dhclient_unescape_duid (const char *duid)
g_byte_array_append (unescaped, &p[i], 1);
}
return unescaped;
return g_byte_array_free_to_bytes (unescaped);
error:
g_byte_array_free (unescaped, TRUE);
......@@ -519,10 +526,10 @@ error:
#define DUID_PREFIX "default-duid \""
GByteArray *
GBytes *
nm_dhcp_dhclient_read_duid (const char *leasefile, GError **error)
{
GByteArray *duid = NULL;
GBytes *duid = NULL;
char *contents;
char **line, **split, *p, *e;
......
......@@ -33,11 +33,11 @@ char *nm_dhcp_dhclient_create_config (const char *interface,
const char *orig_contents,
GBytes **out_new_client_id);
char *nm_dhcp_dhclient_escape_duid (const GByteArray *duid);
char *nm_dhcp_dhclient_escape_duid (GBytes *duid);
GByteArray *nm_dhcp_dhclient_unescape_duid (const char *duid);
GBytes *nm_dhcp_dhclient_unescape_duid (const char *duid);
GByteArray *nm_dhcp_dhclient_read_duid (const char *leasefile, GError **error);
GBytes *nm_dhcp_dhclient_read_duid (const char *leasefile, GError **error);
gboolean nm_dhcp_dhclient_save_duid (const char *leasefile,
const char *escaped_duid,
......
......@@ -338,7 +338,7 @@ create_dhclient_config (NMDhcpDhclient *self,
static gboolean
dhclient_start (NMDhcpClient *client,
const char *mode_opt,
const GByteArray *duid,
GBytes *duid,
gboolean release,
pid_t *out_pid,
int prefixes)
......@@ -534,7 +534,7 @@ ip6_start (NMDhcpClient *client,
const char *dhcp_anycast_addr,
const struct in6_addr *ll_addr,
NMSettingIP6ConfigPrivacy privacy,
const GByteArray *duid,
GBytes *duid,
guint needed_prefixes)
{
NMDhcpDhclient *self = NM_DHCP_DHCLIENT (client);
......@@ -562,7 +562,7 @@ ip6_start (NMDhcpClient *client,
}
static void
stop (NMDhcpClient *client, gboolean release, const GByteArray *duid)
stop (NMDhcpClient *client, gboolean release, GBytes *duid)
{
NMDhcpDhclient *self = NM_DHCP_DHCLIENT (client);
NMDhcpDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE (self);
......@@ -607,12 +607,12 @@ state_changed (NMDhcpClient *client,
nm_dhcp_client_set_client_id (client, client_id);
}
static GByteArray *
static GBytes *
get_duid (NMDhcpClient *client)
{
NMDhcpDhclient *self = NM_DHCP_DHCLIENT (client);
NMDhcpDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE (self);
GByteArray *duid = NULL;
GBytes *duid = NULL;
char *leasefile;
GError *error = NULL;
......@@ -646,7 +646,7 @@ get_duid (NMDhcpClient *client)
}
/* return our DUID, otherwise let the parent class make a default DUID */
return duid ? duid : NM_DHCP_CLIENT_CLASS (nm_dhcp_dhclient_parent_class)->get_duid (client);
return duid ?: NM_DHCP_CLIENT_CLASS (nm_dhcp_dhclient_parent_class)->get_duid (client);
}
/*****************************************************************************/
......
......@@ -80,7 +80,7 @@ nm_dhcp_dhcpcanon_get_path (void)
static gboolean
dhcpcanon_start (NMDhcpClient *client,
const char *mode_opt,
const GByteArray *duid,
GBytes *duid,
gboolean release,
pid_t *out_pid,
int prefixes)
......@@ -180,7 +180,7 @@ ip6_start (NMDhcpClient *client,
const char *dhcp_anycast_addr,
const struct in6_addr *ll_addr,
NMSettingIP6ConfigPrivacy privacy,
const GByteArray *duid,
GBytes *duid,
guint needed_prefixes)
{
NMDhcpDhcpcanon *self = NM_DHCP_DHCPCANON (client);
......@@ -189,7 +189,7 @@ ip6_start (NMDhcpClient *client,
return FALSE;
}
static void
stop (NMDhcpClient *client, gboolean release, const GByteArray *duid)
stop (NMDhcpClient *client, gboolean release, GBytes *duid)
{
NMDhcpDhcpcanon *self = NM_DHCP_DHCPCANON (client);
NMDhcpDhcpcanonPrivate *priv = NM_DHCP_DHCPCANON_GET_PRIVATE (self);
......
......@@ -178,7 +178,7 @@ ip6_start (NMDhcpClient *client,
const char *dhcp_anycast_addr,
const struct in6_addr *ll_addr,
NMSettingIP6ConfigPrivacy privacy,
const GByteArray *duid,
GBytes *duid,
guint needed_prefixes)
{
NMDhcpDhcpcd *self = NM_DHCP_DHCPCD (client);
......@@ -188,7 +188,7 @@ ip6_start (NMDhcpClient *client,
}
static void
stop (NMDhcpClient *client, gboolean release, const GByteArray *duid)
stop (NMDhcpClient *client, gboolean release, GBytes *duid)
{
NMDhcpDhcpcd *self = NM_DHCP_DHCPCD (client);
NMDhcpDhcpcdPrivate *priv = NM_DHCP_DHCPCD_GET_PRIVATE (self);
......
......@@ -899,7 +899,7 @@ ip6_start (NMDhcpClient *client,
const char *dhcp_anycast_addr,
const struct in6_addr *ll_addr,
NMSettingIP6ConfigPrivacy privacy,
const GByteArray *duid,
GBytes *duid,
guint needed_prefixes)
{
NMDhcpSystemd *self = NM_DHCP_SYSTEMD (client);
......@@ -908,11 +908,18 @@ ip6_start (NMDhcpClient *client,
GBytes *hwaddr;
const char *hostname;
int r, i;
const guint16 *duid_arr;
gsize duid_len;
g_assert (priv->client4 == NULL);
g_assert (priv->client6 == NULL);
g_return_val_if_fail (duid != NULL, FALSE);
G_STATIC_ASSERT_EXPR (sizeof (duid_arr[0]) == 2);
duid_arr = g_bytes_get_data (duid, &duid_len);
if (!duid_arr || duid_len < 2)
g_return_val_if_reached (FALSE);
g_free (priv->lease_file);
priv->lease_file = get_leasefile_path (AF_INET6, iface, nm_dhcp_client_get_uuid (client));
......@@ -936,9 +943,9 @@ ip6_start (NMDhcpClient *client,
* wants the type passed separately from the following data.
*/
r = sd_dhcp6_client_set_duid (priv->client6,
ntohs (((const guint16 *) duid->data)[0]),
duid->data + 2,
duid->len - 2);
ntohs (duid_arr[0]),
&duid_arr[1],
duid_len - 2);
if (r < 0) {
_LOGW ("failed to set DUID (%d)", r);
return FALSE;
......@@ -1014,7 +1021,7 @@ error:
}
static void
stop (NMDhcpClient *client, gboolean release, const GByteArray *duid)
stop (NMDhcpClient *client, gboolean release, GBytes *duid)
{
NMDhcpSystemd *self = NM_DHCP_SYSTEMD (client);
NMDhcpSystemdPrivate *priv = NM_DHCP_SYSTEMD_GET_PRIVATE (self);
......
......@@ -721,11 +721,15 @@ error:
}
char *
nm_dhcp_utils_duid_to_string (const GByteArray *duid)
nm_dhcp_utils_duid_to_string (GBytes *duid)
{
gconstpointer data;
gsize len;
g_return_val_if_fail (duid != NULL, NULL);
return _nm_utils_bin2str (duid->data, duid->len, FALSE);
data = g_bytes_get_data (duid, &len);
return _nm_utils_bin2str (data, len, FALSE);
}
/**
......
......@@ -39,7 +39,7 @@ NMIP6Config *nm_dhcp_utils_ip6_config_from_options (struct _NMDedupMultiIndex *m
NMPlatformIP6Address nm_dhcp_utils_ip6_prefix_from_options (GHashTable *options);
char * nm_dhcp_utils_duid_to_string (const GByteArray *duid);
char *nm_dhcp_utils_duid_to_string (GBytes *duid);
GBytes * nm_dhcp_utils_client_id_string_to_bytes (const char *client_id);
......
......@@ -585,23 +585,26 @@ test_existing_multiline_alsoreq (void)
static void
test_one_duid (const char *escaped, const guint8 *unescaped, guint len)
{
GByteArray *t;
GBytes *t;
char *w;
gsize t_len;
gconstpointer t_arr;
t = nm_dhcp_dhclient_unescape_duid (escaped);
g_assert (t);
g_assert_cmpint (t->len, ==, len);
g_assert_cmpint (memcmp (t->data, unescaped, len), ==, 0);
g_byte_array_free (t, TRUE);
t_arr = g_bytes_get_data (t, &t_len);
g_assert (t_arr);
g_assert_cmpint (t_len, ==, len);
g_assert_cmpint (memcmp (t_arr, unescaped, len), ==, 0);
g_bytes_unref (t);
t = g_byte_array_sized_new (len);
g_byte_array_append (t, unescaped, len);
t = g_bytes_new_static (unescaped, len);
w = nm_dhcp_dhclient_escape_duid (t);
g_assert (w);
g_assert_cmpint (strlen (escaped), ==, strlen (w));
g_assert_cmpstr (escaped, ==, w);
g_byte_array_free (t, TRUE);
g_bytes_unref (t);
g_free (w);
}
......@@ -640,22 +643,23 @@ test_read_duid_from_leasefile (void)
{
const guint8 expected[] = { 0x00, 0x01, 0x00, 0x01, 0x18, 0x79, 0xa6,
0x13, 0x60, 0x67, 0x20, 0xec, 0x4c, 0x70 };
GByteArray *duid;
gs_unref_bytes GBytes *duid = NULL;
GError *error = NULL;
gconstpointer duid_arr;
gsize duid_len;
duid = nm_dhcp_dhclient_read_duid (TESTDIR "/test-dhclient-duid.leases", &error);
g_assert_no_error (error);
g_assert (duid);
g_assert_cmpint (duid->len, ==, sizeof (expected));
g_assert_cmpint (memcmp (duid->data, expected, duid->len), ==, 0);
g_byte_array_free (duid, TRUE);
duid_arr = g_bytes_get_data (duid, &duid_len);
g_assert_cmpint (duid_len, ==, sizeof (expected));
g_assert_cmpint (memcmp (duid_arr, expected, duid_len), ==, 0);
}
static void
test_read_commented_duid_from_leasefile (void)
{
GByteArray *duid;
GBytes *duid;
GError *error = NULL;
duid = nm_dhcp_dhclient_read_duid (TESTDIR "/test-dhclient-commented-duid.leases", &error);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment