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:
Dan Williams
2013-02-24 10:45:32 +01:00
parent 8e0b75eb0c
commit b69171061c
7 changed files with 207 additions and 113 deletions

View File

@@ -10,25 +10,13 @@ noinst_LTLIBRARIES = \
dbusservicedir = $(DBUS_SYS_DIR) dbusservicedir = $(DBUS_SYS_DIR)
dbusservice_DATA = \ dbusservice_DATA = \
nm-dhcp-client.conf \
nm-dispatcher.conf \ nm-dispatcher.conf \
nm-avahi-autoipd.conf nm-avahi-autoipd.conf
libexec_PROGRAMS = \ libexec_PROGRAMS = \
nm-dhcp-client.action \
nm-dispatcher.action \ nm-dispatcher.action \
nm-avahi-autoipd.action nm-avahi-autoipd.action
nm_dhcp_client_action_SOURCES = \
nm-dhcp-client-action.c
nm_dhcp_client_action_CPPFLAGS = \
$(DBUS_CFLAGS) \
-DNMCONFDIR=\"$(nmconfdir)\" \
-DLIBEXECDIR=\"$(libexecdir)\"
nm_dhcp_client_action_LDADD = $(DBUS_LIBS)
nm_avahi_autoipd_action_SOURCES = \ nm_avahi_autoipd_action_SOURCES = \
nm-avahi-autoipd-action.c nm-avahi-autoipd-action.c

View File

@@ -58,7 +58,8 @@ libdhcp_manager_la_CPPFLAGS = \
-DLOCALSTATEDIR=\"$(localstatedir)\" \ -DLOCALSTATEDIR=\"$(localstatedir)\" \
-DDHCLIENT_PATH=\"$(DHCLIENT_PATH)\" \ -DDHCLIENT_PATH=\"$(DHCLIENT_PATH)\" \
-DDHCPCD_PATH=\"$(DHCPCD_PATH)\" \ -DDHCPCD_PATH=\"$(DHCPCD_PATH)\" \
-DNMSTATEDIR=\"$(nmstatedir)\" -DNMSTATEDIR=\"$(nmstatedir)\" \
-DNMRUNDIR=\"$(nmrundir)\"
libdhcp_manager_la_LIBADD = \ libdhcp_manager_la_LIBADD = \
$(top_builddir)/src/logging/libnm-logging.la \ $(top_builddir)/src/logging/libnm-logging.la \
@@ -68,3 +69,20 @@ libdhcp_manager_la_LIBADD = \
$(DBUS_LIBS) \ $(DBUS_LIBS) \
$(GLIB_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)

View File

@@ -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 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 { typedef struct {
const char *path; const char *path;

View File

@@ -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 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 { typedef struct {
const char *path; const char *path;

View File

@@ -15,7 +15,7 @@
* with this program; if not, write to the Free Software Foundation, Inc., * with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* *
* Copyright (C) 2007 - 2012 Red Hat, Inc. * Copyright (C) 2007 - 2013 Red Hat, Inc.
*/ */
/* for environ */ /* for environ */
@@ -25,151 +25,147 @@
#include <unistd.h> #include <unistd.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <config.h>
#include <dbus/dbus.h> #include <dbus/dbus.h>
#define NM_DHCP_CLIENT_DBUS_SERVICE "org.freedesktop.nm_dhcp_client"
#define NM_DHCP_CLIENT_DBUS_IFACE "org.freedesktop.nm_dhcp_client" #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 * Start a dict in a dbus message. Should be paired with a call to
* {@link wpa_dbus_dict_close_write}. * _dbus_dict_close_write().
*
* @param iter A valid dbus message iterator
* @param iter_dict (out) A dict iterator to pass to further dict functions
* @return TRUE on success, FALSE on failure
* *
* Returns: %TRUE on success, %FALSE on failure
*/ */
static dbus_bool_t wpa_dbus_dict_open_write(DBusMessageIter *iter, static dbus_bool_t
DBusMessageIter *iter_dict) _dbus_dict_open_write (DBusMessageIter *iter, DBusMessageIter *iter_dict)
{ {
dbus_bool_t result;
if (!iter || !iter_dict) if (!iter || !iter_dict)
return FALSE; return FALSE;
result = dbus_message_iter_open_container( return dbus_message_iter_open_container (iter,
iter, DBUS_TYPE_ARRAY,
DBUS_TYPE_ARRAY, DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_STRING_AS_STRING
DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
DBUS_TYPE_VARIANT_AS_STRING DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
DBUS_DICT_ENTRY_END_CHAR_AS_STRING, iter_dict);
iter_dict);
return result;
} }
/** /**
* End a dict element in a dbus message. Should be paired with * _dbus_dict_close_write:
* a call to {@link wpa_dbus_dict_open_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()
* *
* @param iter valid dbus message iterator, same as passed to * End a dict element in a dbus message. Should be paired with a call to
* wpa_dbus_dict_open_write() * _dbus_dict_open_write().
* @param iter_dict a dbus dict iterator returned from
* {@link wpa_dbus_dict_open_write}
* @return TRUE on success, FALSE on failure
* *
* Returns: %TRUE on success, %FALSE on failure
*/ */
static dbus_bool_t wpa_dbus_dict_close_write(DBusMessageIter *iter, static dbus_bool_t
DBusMessageIter *iter_dict) _dbus_dict_close_write (DBusMessageIter *iter, DBusMessageIter *iter_dict)
{ {
if (!iter || !iter_dict) if (!iter || !iter_dict)
return FALSE; return FALSE;
return dbus_message_iter_close_container(iter, iter_dict); return dbus_message_iter_close_container (iter, iter_dict);
} }
static dbus_bool_t _wpa_dbus_add_dict_entry_start( static dbus_bool_t
DBusMessageIter *iter_dict, DBusMessageIter *iter_dict_entry, _dbus_add_dict_entry_start (DBusMessageIter *iter_dict,
const char *key, const int value_type) DBusMessageIter *iter_dict_entry,
const char *key,
const int value_type)
{ {
if (!dbus_message_iter_open_container(iter_dict, if (!dbus_message_iter_open_container (iter_dict, DBUS_TYPE_DICT_ENTRY, NULL, iter_dict_entry))
DBUS_TYPE_DICT_ENTRY, NULL,
iter_dict_entry))
return FALSE; return FALSE;
if (!dbus_message_iter_append_basic(iter_dict_entry, DBUS_TYPE_STRING, if (!dbus_message_iter_append_basic (iter_dict_entry, DBUS_TYPE_STRING, &key))
&key))
return FALSE; return FALSE;
return TRUE; return TRUE;
} }
static dbus_bool_t _wpa_dbus_add_dict_entry_end( static dbus_bool_t
DBusMessageIter *iter_dict, DBusMessageIter *iter_dict_entry, _dbus_add_dict_entry_end (DBusMessageIter *iter_dict,
DBusMessageIter *iter_dict_val) DBusMessageIter *iter_dict_entry,
DBusMessageIter *iter_dict_val)
{ {
if (!dbus_message_iter_close_container(iter_dict_entry, iter_dict_val)) if (!dbus_message_iter_close_container (iter_dict_entry, iter_dict_val))
return FALSE; return FALSE;
if (!dbus_message_iter_close_container(iter_dict, iter_dict_entry)) if (!dbus_message_iter_close_container (iter_dict, iter_dict_entry))
return FALSE; return FALSE;
return TRUE; return TRUE;
} }
static dbus_bool_t _wpa_dbus_add_dict_entry_byte_array( static dbus_bool_t
DBusMessageIter *iter_dict, const char *key, _dbus_add_dict_entry_byte_array (DBusMessageIter *iter_dict,
const char *value, const dbus_uint32_t value_len) const char *key,
const char *value,
const dbus_uint32_t value_len)
{ {
DBusMessageIter iter_dict_entry, iter_dict_val, iter_array; DBusMessageIter iter_dict_entry, iter_dict_val, iter_array;
dbus_uint32_t i; dbus_uint32_t i;
if (!_wpa_dbus_add_dict_entry_start(iter_dict, &iter_dict_entry, if (!_dbus_add_dict_entry_start (iter_dict, &iter_dict_entry, key, DBUS_TYPE_ARRAY))
key, DBUS_TYPE_ARRAY))
return FALSE; return FALSE;
if (!dbus_message_iter_open_container(&iter_dict_entry, if (!dbus_message_iter_open_container (&iter_dict_entry,
DBUS_TYPE_VARIANT, DBUS_TYPE_VARIANT,
DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_ARRAY_AS_STRING
DBUS_TYPE_BYTE_AS_STRING, DBUS_TYPE_BYTE_AS_STRING,
&iter_dict_val)) &iter_dict_val))
return FALSE; return FALSE;
if (!dbus_message_iter_open_container(&iter_dict_val, DBUS_TYPE_ARRAY, if (!dbus_message_iter_open_container (&iter_dict_val,
DBUS_TYPE_BYTE_AS_STRING, DBUS_TYPE_ARRAY,
&iter_array)) DBUS_TYPE_BYTE_AS_STRING,
&iter_array))
return FALSE; return FALSE;
for (i = 0; i < value_len; i++) { for (i = 0; i < value_len; i++) {
if (!dbus_message_iter_append_basic(&iter_array, if (!dbus_message_iter_append_basic (&iter_array, DBUS_TYPE_BYTE, &(value[i])))
DBUS_TYPE_BYTE,
&(value[i])))
return FALSE; return FALSE;
} }
if (!dbus_message_iter_close_container(&iter_dict_val, &iter_array)) if (!dbus_message_iter_close_container (&iter_dict_val, &iter_array))
return FALSE; return FALSE;
if (!_wpa_dbus_add_dict_entry_end(iter_dict, &iter_dict_entry, if (!_dbus_add_dict_entry_end (iter_dict, &iter_dict_entry, &iter_dict_val))
&iter_dict_val))
return FALSE; return FALSE;
return TRUE; 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. * Add a byte array entry to the dict.
* *
* @param iter_dict A valid DBusMessageIter returned from * Returns: %TRUE on success, %FALSE on failure
* {@link wpa_dbus_dict_open_write}
* @param key The key of the dict item
* @param value The byte array
* @param value_len The length of the byte array, in bytes
* @return TRUE on success, FALSE on failure
* *
*/ */
static dbus_bool_t wpa_dbus_dict_append_byte_array(DBusMessageIter *iter_dict, static dbus_bool_t
const char *key, _dbus_dict_append_byte_array (DBusMessageIter *iter_dict,
const char *value, const char *key,
const dbus_uint32_t value_len) const char *value,
const dbus_uint32_t value_len)
{ {
if (!key) if (!key)
return FALSE; return FALSE;
if (!value && (value_len != 0)) if (!value && (value_len != 0))
return FALSE; return FALSE;
return _wpa_dbus_add_dict_entry_byte_array(iter_dict, key, value, return _dbus_add_dict_entry_byte_array (iter_dict, key, value, value_len);
value_len);
} }
@@ -183,7 +179,7 @@ build_message (DBusMessage * message)
DBusMessageIter iter, iter_dict; DBusMessageIter iter, iter_dict;
dbus_message_iter_init_append (message, &iter); dbus_message_iter_init_append (message, &iter);
if (!wpa_dbus_dict_open_write (&iter, &iter_dict)) if (!_dbus_dict_open_write (&iter, &iter_dict))
goto out; goto out;
/* List environment and format for dbus dict */ /* List environment and format for dbus dict */
@@ -209,7 +205,7 @@ build_message (DBusMessage * message)
* no character encoding guarantees with DHCP, and D-Bus requires * no character encoding guarantees with DHCP, and D-Bus requires
* strings to be UTF-8. * strings to be UTF-8.
*/ */
if (!wpa_dbus_dict_append_byte_array (&iter_dict, if (!_dbus_dict_append_byte_array (&iter_dict,
name, name,
val ? val : "\0", val ? val : "\0",
val ? strlen (val) : 1)) { val ? strlen (val) : 1)) {
@@ -220,7 +216,7 @@ build_message (DBusMessage * message)
free (name); free (name);
} }
if (!wpa_dbus_dict_close_write (&iter, &iter_dict)) if (!_dbus_dict_close_write (&iter, &iter_dict))
goto out; goto out;
success = TRUE; success = TRUE;
@@ -229,8 +225,9 @@ out:
return success; return success;
} }
#if !HAVE_DBUS_GLIB_100
static DBusConnection * static DBusConnection *
dbus_init (void) shared_connection_init (void)
{ {
DBusConnection * connection; DBusConnection * connection;
DBusError error; DBusError error;
@@ -248,10 +245,8 @@ dbus_init (void)
goto error; goto error;
} }
dbus_connection_set_exit_on_disconnect (connection, FALSE);
dbus_error_init (&error); dbus_error_init (&error);
ret = dbus_bus_request_name (connection, NM_DHCP_CLIENT_DBUS_SERVICE, 0, &error); ret = dbus_bus_request_name (connection, "org.freedesktop.nm_dhcp_client", 0, &error);
if (dbus_error_is_set (&error)) { if (dbus_error_is_set (&error)) {
fprintf (stderr, "Error: Could not acquire the NM DHCP client service. " fprintf (stderr, "Error: Could not acquire the NM DHCP client service. "
"Message: (%s) %s\n", "Message: (%s) %s\n",
@@ -276,18 +271,32 @@ error:
dbus_connection_unref (connection); dbus_connection_unref (connection);
return NULL; return NULL;
} }
#endif
int int
main (int argc, char *argv[]) main (int argc, char *argv[])
{ {
DBusConnection * connection; DBusConnection *connection;
DBusMessage * message; DBusMessage *message;
dbus_bool_t result; dbus_bool_t result;
DBusError error;
/* Get a connection to the system bus */ dbus_connection_set_change_sigpipe (TRUE);
connection = dbus_init ();
if (connection == NULL) dbus_error_init (&error);
exit (1); 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"); message = dbus_message_new_signal ("/", NM_DHCP_CLIENT_DBUS_IFACE, "Event");
if (message == NULL) { if (message == NULL) {

View File

@@ -15,7 +15,7 @@
* with this program; if not, write to the Free Software Foundation, Inc., * with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * 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. * Copyright (C) 2006 - 2008 Novell, Inc.
* *
*/ */
@@ -56,11 +56,13 @@ nm_dhcp_manager_error_quark (void)
return ret; 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 NM_DHCP_CLIENT_DBUS_IFACE "org.freedesktop.nm_dhcp_client"
#define DHCP_TIMEOUT 45 /* default DHCP timeout, in seconds */ #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; static NMDHCPManager *singleton = NULL;
typedef GSList * (*GetLeaseConfigFunc) (const char *iface, const char *uuid, gboolean ipv6); typedef GSList * (*GetLeaseConfigFunc) (const char *iface, const char *uuid, gboolean ipv6);
@@ -70,6 +72,10 @@ typedef struct {
GetLeaseConfigFunc get_lease_config_func; GetLeaseConfigFunc get_lease_config_func;
NMDBusManager * dbus_mgr; NMDBusManager * dbus_mgr;
guint new_conn_id;
guint dis_conn_id;
GHashTable * proxies;
GHashTable * clients; GHashTable * clients;
DBusGProxy * proxy; DBusGProxy * proxy;
NMHostnameProvider *hostname_provider; NMHostnameProvider *hostname_provider;
@@ -240,6 +246,48 @@ out:
g_free (reason); 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 static GType
get_client_type (const char *client, GError **error) get_client_type (const char *client, GError **error)
{ {
@@ -297,9 +345,11 @@ NMDHCPManager *
nm_dhcp_manager_get (void) nm_dhcp_manager_get (void)
{ {
NMDHCPManagerPrivate *priv; NMDHCPManagerPrivate *priv;
DBusGConnection *g_connection;
const char *client; const char *client;
GError *error = NULL; GError *error = NULL;
#if !HAVE_DBUS_GLIB_100
DBusGConnection *g_connection;
#endif
if (singleton) if (singleton)
return g_object_ref (singleton); return g_object_ref (singleton);
@@ -326,23 +376,34 @@ nm_dhcp_manager_get (void)
g_assert (priv->clients); g_assert (priv->clients);
priv->dbus_mgr = nm_dbus_manager_get (); 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); g_connection = nm_dbus_manager_get_connection (priv->dbus_mgr);
priv->proxy = dbus_g_proxy_new_for_name (g_connection, 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); NM_DHCP_CLIENT_DBUS_IFACE);
g_assert (priv->proxy); g_assert (priv->proxy);
dbus_g_proxy_add_signal (priv->proxy, dbus_g_proxy_add_signal (priv->proxy,
"Event", "Event",
DBUS_TYPE_G_MAP_OF_VARIANT, DBUS_TYPE_G_MAP_OF_VARIANT,
G_TYPE_INVALID); G_TYPE_INVALID);
dbus_g_proxy_connect_signal (priv->proxy, "Event", dbus_g_proxy_connect_signal (priv->proxy, "Event",
G_CALLBACK (nm_dhcp_manager_handle_event), G_CALLBACK (nm_dhcp_manager_handle_event),
singleton, singleton,
NULL); NULL);
#endif
return singleton; return singleton;
} }
@@ -600,6 +661,10 @@ nm_dhcp_manager_test_ip4_options_to_config (const char *dhcp_client,
static void static void
nm_dhcp_manager_init (NMDHCPManager *manager) 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 static void
@@ -615,6 +680,24 @@ dispose (GObject *object)
g_list_free (values); 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); G_OBJECT_CLASS (nm_dhcp_manager_parent_class)->dispose (object);
} }
@@ -630,10 +713,6 @@ finalize (GObject *object)
if (priv->clients) if (priv->clients)
g_hash_table_destroy (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); G_OBJECT_CLASS (nm_dhcp_manager_parent_class)->finalize (object);
} }