dhcp: use private socket to return status if available
Allows DHCP to work when a bus daemon isn't running. This also fixes a race condition where when multiple interfaces are attempting to get a DHCP lease at the same time, if one DHCP client instance triggers the callout, that instance gets the bus name, and any other client triggering the callout at that time will fail because the bus name is already taken. Since this commit allows using a private socket, where no process has a bus name, this race is avoided. Also move the DHCP helper from callouts/ to src/dhcp-manager/ to consolidate all the DHCP stuff and clean up some of the helper's code.
This commit is contained in:
@@ -58,7 +58,8 @@ libdhcp_manager_la_CPPFLAGS = \
|
||||
-DLOCALSTATEDIR=\"$(localstatedir)\" \
|
||||
-DDHCLIENT_PATH=\"$(DHCLIENT_PATH)\" \
|
||||
-DDHCPCD_PATH=\"$(DHCPCD_PATH)\" \
|
||||
-DNMSTATEDIR=\"$(nmstatedir)\"
|
||||
-DNMSTATEDIR=\"$(nmstatedir)\" \
|
||||
-DNMRUNDIR=\"$(nmrundir)\"
|
||||
|
||||
libdhcp_manager_la_LIBADD = \
|
||||
$(top_builddir)/src/logging/libnm-logging.la \
|
||||
@@ -68,3 +69,20 @@ libdhcp_manager_la_LIBADD = \
|
||||
$(DBUS_LIBS) \
|
||||
$(GLIB_LIBS)
|
||||
|
||||
################### dhclient helper ###################
|
||||
|
||||
libexec_PROGRAMS = nm-dhcp-helper
|
||||
|
||||
nm_dhcp_helper_SOURCES = nm-dhcp-helper.c
|
||||
|
||||
nm_dhcp_helper_CPPFLAGS = $(DBUS_CFLAGS) -DNMRUNDIR=\"$(nmrundir)\"
|
||||
|
||||
nm_dhcp_helper_LDADD = $(DBUS_LIBS)
|
||||
|
||||
|
||||
# FIXME: remove when dbus-glib >= 0.100 is required
|
||||
dbusservicedir = $(DBUS_SYS_DIR)
|
||||
dbusservice_DATA = nm-dhcp-helper.conf
|
||||
|
||||
EXTRA_DIST = $(dbusservice_DATA)
|
||||
|
||||
|
@@ -45,7 +45,7 @@ G_DEFINE_TYPE (NMDHCPDhclient, nm_dhcp_dhclient, NM_TYPE_DHCP_CLIENT)
|
||||
|
||||
#define NM_DHCP_DHCLIENT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DHCP_DHCLIENT, NMDHCPDhclientPrivate))
|
||||
|
||||
#define ACTION_SCRIPT_PATH LIBEXECDIR "/nm-dhcp-client.action"
|
||||
#define ACTION_SCRIPT_PATH LIBEXECDIR "/nm-dhcp-helper"
|
||||
|
||||
typedef struct {
|
||||
const char *path;
|
||||
|
@@ -41,7 +41,7 @@ G_DEFINE_TYPE (NMDHCPDhcpcd, nm_dhcp_dhcpcd, NM_TYPE_DHCP_CLIENT)
|
||||
|
||||
#define NM_DHCP_DHCPCD_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DHCP_DHCPCD, NMDHCPDhcpcdPrivate))
|
||||
|
||||
#define ACTION_SCRIPT_PATH LIBEXECDIR "/nm-dhcp-client.action"
|
||||
#define ACTION_SCRIPT_PATH LIBEXECDIR "/nm-dhcp-helper"
|
||||
|
||||
typedef struct {
|
||||
const char *path;
|
||||
|
327
src/dhcp-manager/nm-dhcp-helper.c
Normal file
327
src/dhcp-manager/nm-dhcp-helper.c
Normal file
@@ -0,0 +1,327 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
||||
/* NetworkManager -- Network link manager
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright (C) 2007 - 2013 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
/* for environ */
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <config.h>
|
||||
|
||||
#include <dbus/dbus.h>
|
||||
|
||||
#define NM_DHCP_CLIENT_DBUS_IFACE "org.freedesktop.nm_dhcp_client"
|
||||
|
||||
/**
|
||||
* _dbus_dict_open_write:
|
||||
* @iter: A valid dbus message iterator
|
||||
* @iter_dict: on return, a dict iterator to pass to further dict functions
|
||||
*
|
||||
* Start a dict in a dbus message. Should be paired with a call to
|
||||
* _dbus_dict_close_write().
|
||||
*
|
||||
* Returns: %TRUE on success, %FALSE on failure
|
||||
*/
|
||||
static dbus_bool_t
|
||||
_dbus_dict_open_write (DBusMessageIter *iter, DBusMessageIter *iter_dict)
|
||||
{
|
||||
if (!iter || !iter_dict)
|
||||
return FALSE;
|
||||
|
||||
return dbus_message_iter_open_container (iter,
|
||||
DBUS_TYPE_ARRAY,
|
||||
DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
|
||||
DBUS_TYPE_STRING_AS_STRING
|
||||
DBUS_TYPE_VARIANT_AS_STRING
|
||||
DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
|
||||
iter_dict);
|
||||
}
|
||||
|
||||
/**
|
||||
* _dbus_dict_close_write:
|
||||
* @iter: valid dbus message iterator, same as passed to _dbus_dict_open_write()
|
||||
* @iter_dict: a dbus dict iterator returned from _dbus_dict_open_write()
|
||||
*
|
||||
* End a dict element in a dbus message. Should be paired with a call to
|
||||
* _dbus_dict_open_write().
|
||||
*
|
||||
* Returns: %TRUE on success, %FALSE on failure
|
||||
*/
|
||||
static dbus_bool_t
|
||||
_dbus_dict_close_write (DBusMessageIter *iter, DBusMessageIter *iter_dict)
|
||||
{
|
||||
if (!iter || !iter_dict)
|
||||
return FALSE;
|
||||
|
||||
return dbus_message_iter_close_container (iter, iter_dict);
|
||||
}
|
||||
|
||||
static dbus_bool_t
|
||||
_dbus_add_dict_entry_start (DBusMessageIter *iter_dict,
|
||||
DBusMessageIter *iter_dict_entry,
|
||||
const char *key,
|
||||
const int value_type)
|
||||
{
|
||||
if (!dbus_message_iter_open_container (iter_dict, DBUS_TYPE_DICT_ENTRY, NULL, iter_dict_entry))
|
||||
return FALSE;
|
||||
|
||||
if (!dbus_message_iter_append_basic (iter_dict_entry, DBUS_TYPE_STRING, &key))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static dbus_bool_t
|
||||
_dbus_add_dict_entry_end (DBusMessageIter *iter_dict,
|
||||
DBusMessageIter *iter_dict_entry,
|
||||
DBusMessageIter *iter_dict_val)
|
||||
{
|
||||
if (!dbus_message_iter_close_container (iter_dict_entry, iter_dict_val))
|
||||
return FALSE;
|
||||
if (!dbus_message_iter_close_container (iter_dict, iter_dict_entry))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static dbus_bool_t
|
||||
_dbus_add_dict_entry_byte_array (DBusMessageIter *iter_dict,
|
||||
const char *key,
|
||||
const char *value,
|
||||
const dbus_uint32_t value_len)
|
||||
{
|
||||
DBusMessageIter iter_dict_entry, iter_dict_val, iter_array;
|
||||
dbus_uint32_t i;
|
||||
|
||||
if (!_dbus_add_dict_entry_start (iter_dict, &iter_dict_entry, key, DBUS_TYPE_ARRAY))
|
||||
return FALSE;
|
||||
|
||||
if (!dbus_message_iter_open_container (&iter_dict_entry,
|
||||
DBUS_TYPE_VARIANT,
|
||||
DBUS_TYPE_ARRAY_AS_STRING
|
||||
DBUS_TYPE_BYTE_AS_STRING,
|
||||
&iter_dict_val))
|
||||
return FALSE;
|
||||
|
||||
if (!dbus_message_iter_open_container (&iter_dict_val,
|
||||
DBUS_TYPE_ARRAY,
|
||||
DBUS_TYPE_BYTE_AS_STRING,
|
||||
&iter_array))
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < value_len; i++) {
|
||||
if (!dbus_message_iter_append_basic (&iter_array, DBUS_TYPE_BYTE, &(value[i])))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!dbus_message_iter_close_container (&iter_dict_val, &iter_array))
|
||||
return FALSE;
|
||||
|
||||
if (!_dbus_add_dict_entry_end (iter_dict, &iter_dict_entry, &iter_dict_val))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* _dbus_dict_append_byte_array:
|
||||
* @iter_dict: A valid %DBusMessageIter returned from _dbus_dict_open_write()
|
||||
* @key: The key of the dict item
|
||||
* @value: The byte array
|
||||
* @value_len: The length of the byte array, in bytes
|
||||
*
|
||||
* Add a byte array entry to the dict.
|
||||
*
|
||||
* Returns: %TRUE on success, %FALSE on failure
|
||||
*
|
||||
*/
|
||||
static dbus_bool_t
|
||||
_dbus_dict_append_byte_array (DBusMessageIter *iter_dict,
|
||||
const char *key,
|
||||
const char *value,
|
||||
const dbus_uint32_t value_len)
|
||||
{
|
||||
if (!key)
|
||||
return FALSE;
|
||||
if (!value && (value_len != 0))
|
||||
return FALSE;
|
||||
return _dbus_add_dict_entry_byte_array (iter_dict, key, value, value_len);
|
||||
}
|
||||
|
||||
|
||||
static const char * ignore[] = {"PATH", "SHLVL", "_", "PWD", "dhc_dbus", NULL};
|
||||
|
||||
static dbus_bool_t
|
||||
build_message (DBusMessage * message)
|
||||
{
|
||||
char **item;
|
||||
dbus_bool_t success = FALSE;
|
||||
DBusMessageIter iter, iter_dict;
|
||||
|
||||
dbus_message_iter_init_append (message, &iter);
|
||||
if (!_dbus_dict_open_write (&iter, &iter_dict))
|
||||
goto out;
|
||||
|
||||
/* List environment and format for dbus dict */
|
||||
for (item = environ; *item; item++) {
|
||||
char *name, *val, **p;
|
||||
|
||||
/* Split on the = */
|
||||
name = strdup (*item);
|
||||
val = strchr (name, '=');
|
||||
if (!val)
|
||||
goto next;
|
||||
*val++ = '\0';
|
||||
if (!strlen (val))
|
||||
val = NULL;
|
||||
|
||||
/* Ignore non-DCHP-related environment variables */
|
||||
for (p = (char **) ignore; *p; p++) {
|
||||
if (strncmp (name, *p, strlen (*p)) == 0)
|
||||
goto next;
|
||||
}
|
||||
|
||||
/* Value passed as a byte array rather than a string, because there are
|
||||
* no character encoding guarantees with DHCP, and D-Bus requires
|
||||
* strings to be UTF-8.
|
||||
*/
|
||||
if (!_dbus_dict_append_byte_array (&iter_dict,
|
||||
name,
|
||||
val ? val : "\0",
|
||||
val ? strlen (val) : 1)) {
|
||||
fprintf (stderr, "Error: failed to add item '%s' to signal\n", name);
|
||||
}
|
||||
|
||||
next:
|
||||
free (name);
|
||||
}
|
||||
|
||||
if (!_dbus_dict_close_write (&iter, &iter_dict))
|
||||
goto out;
|
||||
|
||||
success = TRUE;
|
||||
|
||||
out:
|
||||
return success;
|
||||
}
|
||||
|
||||
#if !HAVE_DBUS_GLIB_100
|
||||
static DBusConnection *
|
||||
shared_connection_init (void)
|
||||
{
|
||||
DBusConnection * connection;
|
||||
DBusError error;
|
||||
int ret;
|
||||
|
||||
dbus_connection_set_change_sigpipe (TRUE);
|
||||
|
||||
dbus_error_init (&error);
|
||||
connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
|
||||
if (dbus_error_is_set (&error)) {
|
||||
fprintf (stderr, "Error: could not get the system bus. Make sure "
|
||||
"the message bus daemon is running! Message: (%s) %s\n",
|
||||
error.name,
|
||||
error.message);
|
||||
goto error;
|
||||
}
|
||||
|
||||
dbus_error_init (&error);
|
||||
ret = dbus_bus_request_name (connection, "org.freedesktop.nm_dhcp_client", 0, &error);
|
||||
if (dbus_error_is_set (&error)) {
|
||||
fprintf (stderr, "Error: Could not acquire the NM DHCP client service. "
|
||||
"Message: (%s) %s\n",
|
||||
error.name,
|
||||
error.message);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
|
||||
fprintf (stderr, "Error: Could not acquire the NM DHCP client service "
|
||||
"as it is already taken. Return: %d\n",
|
||||
ret);
|
||||
goto error;
|
||||
}
|
||||
|
||||
return connection;
|
||||
|
||||
error:
|
||||
if (dbus_error_is_set (&error))
|
||||
dbus_error_free (&error);
|
||||
if (connection)
|
||||
dbus_connection_unref (connection);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
DBusConnection *connection;
|
||||
DBusMessage *message;
|
||||
dbus_bool_t result;
|
||||
DBusError error;
|
||||
|
||||
dbus_connection_set_change_sigpipe (TRUE);
|
||||
|
||||
dbus_error_init (&error);
|
||||
connection = dbus_connection_open_private ("unix:path=" NMRUNDIR "/private-dhcp", &error);
|
||||
if (!connection) {
|
||||
#if !HAVE_DBUS_GLIB_100
|
||||
connection = shared_connection_init ();
|
||||
#endif
|
||||
if (!connection) {
|
||||
fprintf (stderr, "Error: could not connect to NetworkManager DBus socket: (%s) %s\n",
|
||||
error.name, error.message);
|
||||
dbus_error_free (&error);
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
dbus_connection_set_exit_on_disconnect (connection, FALSE);
|
||||
|
||||
message = dbus_message_new_signal ("/", NM_DHCP_CLIENT_DBUS_IFACE, "Event");
|
||||
if (message == NULL) {
|
||||
fprintf (stderr, "Error: Not enough memory to send DHCP Event signal.\n");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
/* Dump environment variables into the message */
|
||||
result = build_message (message);
|
||||
if (result == FALSE) {
|
||||
fprintf (stderr, "Error: Not enough memory to send DHCP Event signal.\n");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
/* queue the message */
|
||||
result = dbus_connection_send (connection, message, NULL);
|
||||
if (!result) {
|
||||
fprintf (stderr, "Error: Could not send send DHCP Event signal.\n");
|
||||
exit (1);
|
||||
}
|
||||
dbus_message_unref (message);
|
||||
|
||||
/* Send out the message */
|
||||
dbus_connection_flush (connection);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
13
src/dhcp-manager/nm-dhcp-helper.conf
Normal file
13
src/dhcp-manager/nm-dhcp-helper.conf
Normal file
@@ -0,0 +1,13 @@
|
||||
<!DOCTYPE busconfig PUBLIC
|
||||
"-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
|
||||
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
|
||||
<busconfig>
|
||||
<policy user="root">
|
||||
<allow own="org.freedesktop.nm_dhcp_client"/>
|
||||
</policy>
|
||||
<policy context="default">
|
||||
<deny own="org.freedesktop.nm_dhcp_client"/>
|
||||
<deny send_destination="org.freedesktop.nm_dhcp_client"/>
|
||||
</policy>
|
||||
</busconfig>
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright (C) 2005 - 2010 Red Hat, Inc.
|
||||
* Copyright (C) 2005 - 2013 Red Hat, Inc.
|
||||
* Copyright (C) 2006 - 2008 Novell, Inc.
|
||||
*
|
||||
*/
|
||||
@@ -56,11 +56,13 @@ nm_dhcp_manager_error_quark (void)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define NM_DHCP_CLIENT_DBUS_SERVICE "org.freedesktop.nm_dhcp_client"
|
||||
#define NM_DHCP_CLIENT_DBUS_IFACE "org.freedesktop.nm_dhcp_client"
|
||||
|
||||
#define DHCP_TIMEOUT 45 /* default DHCP timeout, in seconds */
|
||||
|
||||
#define PRIV_SOCK_PATH NMRUNDIR "/private-dhcp"
|
||||
#define PRIV_SOCK_TAG "dhcp"
|
||||
|
||||
static NMDHCPManager *singleton = NULL;
|
||||
|
||||
typedef GSList * (*GetLeaseConfigFunc) (const char *iface, const char *uuid, gboolean ipv6);
|
||||
@@ -70,6 +72,10 @@ typedef struct {
|
||||
GetLeaseConfigFunc get_lease_config_func;
|
||||
|
||||
NMDBusManager * dbus_mgr;
|
||||
guint new_conn_id;
|
||||
guint dis_conn_id;
|
||||
GHashTable * proxies;
|
||||
|
||||
GHashTable * clients;
|
||||
DBusGProxy * proxy;
|
||||
NMHostnameProvider *hostname_provider;
|
||||
@@ -240,6 +246,48 @@ out:
|
||||
g_free (reason);
|
||||
}
|
||||
|
||||
#if HAVE_DBUS_GLIB_100
|
||||
static void
|
||||
new_connection_cb (NMDBusManager *mgr,
|
||||
DBusGConnection *connection,
|
||||
NMDHCPManager *self)
|
||||
{
|
||||
NMDHCPManagerPrivate *priv = NM_DHCP_MANAGER_GET_PRIVATE (self);
|
||||
DBusGProxy *proxy;
|
||||
|
||||
/* Create a new proxy for the client */
|
||||
proxy = dbus_g_proxy_new_for_peer (connection, "/", NM_DHCP_CLIENT_DBUS_IFACE);
|
||||
dbus_g_proxy_add_signal (proxy,
|
||||
"Event",
|
||||
DBUS_TYPE_G_MAP_OF_VARIANT,
|
||||
G_TYPE_INVALID);
|
||||
dbus_g_proxy_connect_signal (proxy,
|
||||
"Event",
|
||||
G_CALLBACK (nm_dhcp_manager_handle_event),
|
||||
self,
|
||||
NULL);
|
||||
g_hash_table_insert (priv->proxies, connection, proxy);
|
||||
}
|
||||
|
||||
static void
|
||||
dis_connection_cb (NMDBusManager *mgr,
|
||||
DBusGConnection *connection,
|
||||
NMDHCPManager *self)
|
||||
{
|
||||
NMDHCPManagerPrivate *priv = NM_DHCP_MANAGER_GET_PRIVATE (self);
|
||||
DBusGProxy *proxy;
|
||||
|
||||
proxy = g_hash_table_lookup (priv->proxies, connection);
|
||||
if (proxy) {
|
||||
dbus_g_proxy_disconnect_signal (proxy,
|
||||
"Event",
|
||||
G_CALLBACK (nm_dhcp_manager_handle_event),
|
||||
self);
|
||||
g_hash_table_remove (priv->proxies, connection);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static GType
|
||||
get_client_type (const char *client, GError **error)
|
||||
{
|
||||
@@ -297,9 +345,11 @@ NMDHCPManager *
|
||||
nm_dhcp_manager_get (void)
|
||||
{
|
||||
NMDHCPManagerPrivate *priv;
|
||||
DBusGConnection *g_connection;
|
||||
const char *client;
|
||||
GError *error = NULL;
|
||||
#if !HAVE_DBUS_GLIB_100
|
||||
DBusGConnection *g_connection;
|
||||
#endif
|
||||
|
||||
if (singleton)
|
||||
return g_object_ref (singleton);
|
||||
@@ -326,23 +376,34 @@ nm_dhcp_manager_get (void)
|
||||
g_assert (priv->clients);
|
||||
|
||||
priv->dbus_mgr = nm_dbus_manager_get ();
|
||||
|
||||
#if HAVE_DBUS_GLIB_100
|
||||
/* Register the socket our DHCP clients will return lease info on */
|
||||
nm_dbus_manager_private_server_register (priv->dbus_mgr, PRIV_SOCK_PATH, PRIV_SOCK_TAG);
|
||||
priv->new_conn_id = g_signal_connect (priv->dbus_mgr,
|
||||
NM_DBUS_MANAGER_PRIVATE_CONNECTION_NEW "::" PRIV_SOCK_TAG,
|
||||
(GCallback) new_connection_cb,
|
||||
singleton);
|
||||
priv->dis_conn_id = g_signal_connect (priv->dbus_mgr,
|
||||
NM_DBUS_MANAGER_PRIVATE_CONNECTION_DISCONNECTED "::" PRIV_SOCK_TAG,
|
||||
(GCallback) dis_connection_cb,
|
||||
singleton);
|
||||
#else
|
||||
g_connection = nm_dbus_manager_get_connection (priv->dbus_mgr);
|
||||
priv->proxy = dbus_g_proxy_new_for_name (g_connection,
|
||||
NM_DHCP_CLIENT_DBUS_SERVICE,
|
||||
"org.freedesktop.nm_dhcp_client",
|
||||
"/",
|
||||
NM_DHCP_CLIENT_DBUS_IFACE);
|
||||
g_assert (priv->proxy);
|
||||
|
||||
dbus_g_proxy_add_signal (priv->proxy,
|
||||
"Event",
|
||||
DBUS_TYPE_G_MAP_OF_VARIANT,
|
||||
G_TYPE_INVALID);
|
||||
|
||||
dbus_g_proxy_connect_signal (priv->proxy, "Event",
|
||||
G_CALLBACK (nm_dhcp_manager_handle_event),
|
||||
singleton,
|
||||
NULL);
|
||||
|
||||
#endif
|
||||
return singleton;
|
||||
}
|
||||
|
||||
@@ -600,6 +661,10 @@ nm_dhcp_manager_test_ip4_options_to_config (const char *dhcp_client,
|
||||
static void
|
||||
nm_dhcp_manager_init (NMDHCPManager *manager)
|
||||
{
|
||||
NMDHCPManagerPrivate *priv = NM_DHCP_MANAGER_GET_PRIVATE (manager);
|
||||
|
||||
/* Maps DBusGConnection :: DBusGProxy */
|
||||
priv->proxies = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_object_unref);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -615,6 +680,24 @@ dispose (GObject *object)
|
||||
g_list_free (values);
|
||||
}
|
||||
|
||||
if (priv->new_conn_id) {
|
||||
g_signal_handler_disconnect (priv->dbus_mgr, priv->new_conn_id);
|
||||
priv->new_conn_id = 0;
|
||||
}
|
||||
if (priv->dis_conn_id) {
|
||||
g_signal_handler_disconnect (priv->dbus_mgr, priv->dis_conn_id);
|
||||
priv->dis_conn_id = 0;
|
||||
}
|
||||
g_object_unref (priv->dbus_mgr);
|
||||
priv->dbus_mgr = NULL;
|
||||
|
||||
if (priv->proxies) {
|
||||
g_hash_table_destroy (priv->proxies);
|
||||
priv->proxies = NULL;
|
||||
}
|
||||
if (priv->proxy)
|
||||
g_object_unref (priv->proxy);
|
||||
|
||||
G_OBJECT_CLASS (nm_dhcp_manager_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
@@ -630,10 +713,6 @@ finalize (GObject *object)
|
||||
|
||||
if (priv->clients)
|
||||
g_hash_table_destroy (priv->clients);
|
||||
if (priv->proxy)
|
||||
g_object_unref (priv->proxy);
|
||||
if (priv->dbus_mgr)
|
||||
g_object_unref (priv->dbus_mgr);
|
||||
|
||||
G_OBJECT_CLASS (nm_dhcp_manager_parent_class)->finalize (object);
|
||||
}
|
||||
|
Reference in New Issue
Block a user