summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorZhang zhengguang <zhengguang.zhang@intel.com>2014-07-17 10:37:39 +0800
committerZhang zhengguang <zhengguang.zhang@intel.com>2014-07-17 10:37:39 +0800
commit1b9d0a62f59bb48c8deb2f0b98d9acdffdd9abe7 (patch)
tree6e991827d28537f7f40f20786c2354fd04a9fdad /src
parentfbe905ab58ecc31fe64c410c5f580cadc30e7f04 (diff)
downloadconnman-1b9d0a62f59bb48c8deb2f0b98d9acdffdd9abe7.tar.gz
connman-1b9d0a62f59bb48c8deb2f0b98d9acdffdd9abe7.tar.bz2
connman-1b9d0a62f59bb48c8deb2f0b98d9acdffdd9abe7.zip
Imported Upstream version 1.24upstream/1.24
Diffstat (limited to 'src')
-rw-r--r--src/6to4.c42
-rw-r--r--src/agent-connman.c113
-rw-r--r--src/agent.c531
-rw-r--r--src/bridge.c16
-rw-r--r--src/clock.c48
-rw-r--r--src/config.c540
-rw-r--r--src/connection.c347
-rw-r--r--src/connman.h269
-rw-r--r--src/connman.service.in4
-rw-r--r--src/counter.c14
-rw-r--r--src/dbus.c87
-rw-r--r--src/detect.c8
-rw-r--r--src/device.c313
-rw-r--r--src/dhcp.c400
-rw-r--r--src/dhcpv6.c1712
-rw-r--r--src/dnsproxy.c730
-rw-r--r--src/eduroam.config5
-rw-r--r--src/error.c2
-rw-r--r--src/firewall.c37
-rw-r--r--src/inet.c999
-rw-r--r--src/inotify.c18
-rw-r--r--src/ipaddress.c30
-rw-r--r--src/ipconfig.c656
-rw-r--r--src/ippool.c54
-rw-r--r--src/iptables.c379
-rw-r--r--src/ipv6pd.c383
-rw-r--r--src/log.c48
-rw-r--r--src/main.c174
-rw-r--r--src/main.conf8
-rw-r--r--src/manager.c92
-rw-r--r--src/nat.c62
-rw-r--r--src/net.connman.service.in5
-rw-r--r--src/network.c499
-rw-r--r--src/notifier.c58
-rw-r--r--src/ntp.c85
-rw-r--r--src/peer.c317
-rw-r--r--src/plugin.c66
-rw-r--r--src/provider.c138
-rw-r--r--src/proxy.c20
-rw-r--r--src/resolver.c118
-rw-r--r--src/rfkill.c10
-rw-r--r--src/rtnl.c180
-rw-r--r--src/service.c2408
-rw-r--r--src/session.c1768
-rw-r--r--src/shared/debugfs.c66
-rw-r--r--src/shared/debugfs.h24
-rw-r--r--src/shared/netlink.c666
-rw-r--r--src/shared/netlink.h53
-rw-r--r--src/shared/util.h19
-rw-r--r--src/stats.c60
-rw-r--r--src/storage.c110
-rw-r--r--src/task.c43
-rw-r--r--src/technology.c925
-rw-r--r--src/tethering.c70
-rw-r--r--src/timeserver.c67
-rw-r--r--src/timezone.c38
-rw-r--r--src/utsname.c8
-rw-r--r--src/wispr.c152
-rw-r--r--src/wpad.c26
59 files changed, 10209 insertions, 5911 deletions
diff --git a/src/6to4.c b/src/6to4.c
index 340b69e5..0e3a7a15 100644
--- a/src/6to4.c
+++ b/src/6to4.c
@@ -77,21 +77,23 @@ static int tunnel_create(struct in_addr *addr)
p.iph.protocol = IPPROTO_IPV6;
p.iph.saddr = addr->s_addr;
p.iph.ttl = 64;
- strncpy(p.name, "tun6to4", IFNAMSIZ);
+ strncpy(p.name, "tun6to4", sizeof(p.name) - 1);
- strncpy(ifr.ifr_name, "sit0", IFNAMSIZ);
+ strncpy(ifr.ifr_name, "sit0", sizeof(ifr.ifr_name) - 1);
ifr.ifr_ifru.ifru_data = (void *)&p;
fd = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
+ if (fd < 0)
+ return -errno;
ret = ioctl(fd, SIOCADDTUNNEL, &ifr);
if (ret)
connman_error("add tunnel %s failed: %s", ifr.ifr_name,
strerror(errno));
close(fd);
- return ret;
+ return -ret;
}
-static void tunnel_destroy()
+static void tunnel_destroy(void)
{
struct ip_tunnel_parm p;
struct ifreq ifr;
@@ -109,9 +111,9 @@ static void tunnel_destroy()
p.iph.version = 4;
p.iph.ihl = 5;
p.iph.protocol = IPPROTO_IPV6;
- strncpy(p.name, "tun6to4", IFNAMSIZ);
+ strncpy(p.name, "tun6to4", sizeof(p.name) - 1);
- strncpy(ifr.ifr_name, "tun6to4", IFNAMSIZ);
+ strncpy(ifr.ifr_name, "tun6to4", sizeof(ifr.ifr_name) - 1);
ifr.ifr_ifru.ifru_data = (void *)&p;
fd = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
if (fd < 0) {
@@ -133,7 +135,7 @@ static void tunnel_destroy()
tunnel_ip_address = NULL;
}
-static int tunnel_add_route()
+static int tunnel_add_route(void)
{
struct __connman_inet_rtnl_handle rth;
struct in6_addr addr6;
@@ -231,12 +233,12 @@ static gboolean unref_web(gpointer user_data)
return FALSE;
}
-static gboolean web_result(GWebResult *result, gpointer user_data)
+static bool web_result(GWebResult *result, gpointer user_data)
{
guint16 status;
if (web_request_id == 0)
- return FALSE;
+ return false;
status = g_web_result_get_status(result);
@@ -251,7 +253,7 @@ static gboolean web_result(GWebResult *result, gpointer user_data)
g_timeout_add_seconds(1, unref_web, NULL);
- return FALSE;
+ return false;
}
static void web_debug(const char *str, void *data)
@@ -303,7 +305,7 @@ static void tun_newlink(unsigned flags, unsigned change, void *user_data)
}
web = g_web_new(index);
- if (web == NULL) {
+ if (!web) {
tunnel_destroy();
return;
}
@@ -384,7 +386,7 @@ static void receive_rs_reply(struct nd_router_advert *reply,
/* We try to create tunnel if autoconfiguration did not work i.e.,
* we did not receive any reply to router solicitation message.
*/
- if (reply == NULL && inet_aton(address, &ip4addr) != 0)
+ if (!reply && inet_aton(address, &ip4addr) != 0)
init_6to4(&ip4addr);
g_free(address);
@@ -406,15 +408,15 @@ int __connman_6to4_probe(struct connman_service *service)
if (tunnel_created || tunnel_pending)
return 0;
- if (service == NULL)
+ if (!service)
return -1;
ip4config = __connman_service_get_ip4config(service);
- if (ip4config == NULL)
+ if (!ip4config)
return -1;
ip6config = __connman_service_get_ip6config(service);
- if (ip6config == NULL)
+ if (!ip6config)
return -1;
method = __connman_ipconfig_get_method(ip6config);
@@ -422,7 +424,7 @@ int __connman_6to4_probe(struct connman_service *service)
return -1;
address = __connman_ipconfig_get_local(ip4config);
- if (address == NULL)
+ if (!address)
return -1;
if (inet_aton(address, &ip4addr) == 0)
@@ -455,11 +457,11 @@ void __connman_6to4_remove(struct connman_ipconfig *ip4config)
DBG("tunnel ip address %s", tunnel_ip_address);
- if (ip4config == NULL)
+ if (!ip4config)
return;
address = __connman_ipconfig_get_local(ip4config);
- if (address == NULL)
+ if (!address)
return;
if (g_strcmp0(address, tunnel_ip_address) != 0)
@@ -473,14 +475,14 @@ int __connman_6to4_check(struct connman_ipconfig *ip4config)
{
const char *address;
- if (ip4config == NULL || tunnel_created == 0 ||
+ if (!ip4config || tunnel_created == 0 ||
tunnel_pending == 1)
return -1;
DBG("tunnel ip address %s", tunnel_ip_address);
address = __connman_ipconfig_get_local(ip4config);
- if (address == NULL)
+ if (!address)
return -1;
if (g_strcmp0(address, tunnel_ip_address) == 0)
diff --git a/src/agent-connman.c b/src/agent-connman.c
index 9ccba72e..ab538f38 100644
--- a/src/agent-connman.c
+++ b/src/agent-connman.c
@@ -2,7 +2,7 @@
*
* Connection Manager
*
- * Copyright (C) 2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2012-2013 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -34,7 +34,7 @@
#include "connman.h"
-static connman_bool_t check_reply_has_dict(DBusMessage *reply)
+static bool check_reply_has_dict(DBusMessage *reply)
{
const char *signature = DBUS_TYPE_ARRAY_AS_STRING
DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
@@ -42,8 +42,8 @@ static connman_bool_t check_reply_has_dict(DBusMessage *reply)
DBUS_TYPE_VARIANT_AS_STRING
DBUS_DICT_ENTRY_END_CHAR_AS_STRING;
- if (dbus_message_has_signature(reply, signature) == TRUE)
- return TRUE;
+ if (dbus_message_has_signature(reply, signature))
+ return true;
connman_warn("Reply %s to %s from %s has wrong signature %s",
signature,
@@ -51,7 +51,7 @@ static connman_bool_t check_reply_has_dict(DBusMessage *reply)
dbus_message_get_sender(reply),
dbus_message_get_signature(reply));
- return FALSE;
+ return false;
}
struct request_input_reply {
@@ -63,8 +63,8 @@ struct request_input_reply {
static void request_input_passphrase_reply(DBusMessage *reply, void *user_data)
{
struct request_input_reply *passphrase_reply = user_data;
- connman_bool_t values_received = FALSE;
- connman_bool_t wps = FALSE;
+ bool values_received = false;
+ bool wps = false;
const char *error = NULL;
char *identity = NULL;
char *passphrase = NULL;
@@ -74,15 +74,18 @@ static void request_input_passphrase_reply(DBusMessage *reply, void *user_data)
int name_len = 0;
DBusMessageIter iter, dict;
+ if (!reply)
+ goto out;
+
if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) {
error = dbus_message_get_error_name(reply);
goto done;
}
- if (check_reply_has_dict(reply) == FALSE)
+ if (!check_reply_has_dict(reply))
goto done;
- values_received = TRUE;
+ values_received = true;
dbus_message_iter_init(reply, &iter);
dbus_message_iter_recurse(&iter, &dict);
@@ -105,13 +108,14 @@ static void request_input_passphrase_reply(DBusMessage *reply, void *user_data)
} else if (g_str_equal(key, "Passphrase")) {
dbus_message_iter_next(&entry);
- if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_VARIANT)
+ if (dbus_message_iter_get_arg_type(&entry)
+ != DBUS_TYPE_VARIANT)
break;
dbus_message_iter_recurse(&entry, &value);
dbus_message_iter_get_basic(&value, &passphrase);
} else if (g_str_equal(key, "WPS")) {
- wps = TRUE;
+ wps = true;
dbus_message_iter_next(&entry);
if (dbus_message_iter_get_arg_type(&entry)
@@ -152,6 +156,8 @@ done:
identity, passphrase,
wps, wpspin, error,
passphrase_reply->user_data);
+
+out:
g_free(passphrase_reply);
}
@@ -161,14 +167,14 @@ static void request_input_append_alternates(DBusMessageIter *iter,
const char *str = user_data;
char **alternates, **alternative;
- if (str == NULL)
+ if (!str)
return;
alternates = g_strsplit(str, ",", 0);
- if (alternates == NULL)
+ if (!alternates)
return;
- for (alternative = alternates; *alternative != NULL; alternative++)
+ for (alternative = alternates; *alternative; alternative++)
dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING,
alternative);
@@ -204,9 +210,9 @@ static void request_input_append_passphrase(DBusMessageIter *iter,
case CONNMAN_SERVICE_SECURITY_8021X:
phase2 = __connman_service_get_phase2(service);
- if (phase2 != NULL && (
- g_str_has_suffix(phase2, "GTC") == TRUE ||
- g_str_has_suffix(phase2, "OTP") == TRUE))
+ if (phase2 && (
+ g_str_has_suffix(phase2, "GTC") ||
+ g_str_has_suffix(phase2, "OTP")))
value = "response";
else
value = "passphrase";
@@ -222,7 +228,7 @@ static void request_input_append_passphrase(DBusMessageIter *iter,
connman_dbus_dict_append_basic(iter, "Requirement",
DBUS_TYPE_STRING, &value);
- if (__connman_service_wps_enabled(service) == TRUE) {
+ if (__connman_service_wps_enabled(service)) {
connman_dbus_dict_append_array(iter, "Alternates",
DBUS_TYPE_STRING,
request_input_append_alternates,
@@ -310,12 +316,12 @@ static void previous_passphrase_handler(DBusMessageIter *iter,
network = __connman_service_get_network(service);
data.passphrase = connman_network_get_string(network, "WiFi.PinWPS");
- if (connman_network_get_bool(network, "WiFi.UseWPS") == TRUE &&
- data.passphrase != NULL) {
+ if (connman_network_get_bool(network, "WiFi.UseWPS") &&
+ data.passphrase) {
data.type = "wpspin";
} else {
data.passphrase = __connman_service_get_passphrase(service);
- if (data.passphrase == NULL)
+ if (!data.passphrase)
return;
security = __connman_service_get_security(service);
@@ -342,21 +348,24 @@ static void request_input_login_reply(DBusMessage *reply, void *user_data)
{
struct request_input_reply *username_password_reply = user_data;
const char *error = NULL;
- connman_bool_t values_received = FALSE;
+ bool values_received = false;
char *username = NULL;
char *password = NULL;
char *key;
DBusMessageIter iter, dict;
+ if (!reply)
+ goto out;
+
if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) {
error = dbus_message_get_error_name(reply);
goto done;
}
- if (check_reply_has_dict(reply) == FALSE)
+ if (!check_reply_has_dict(reply))
goto done;
- values_received = TRUE;
+ values_received = true;
dbus_message_iter_init(reply, &iter);
dbus_message_iter_recurse(&iter, &dict);
@@ -395,11 +404,14 @@ done:
username, password,
FALSE, NULL, error,
username_password_reply->user_data);
+
+out:
g_free(username_password_reply);
}
int __connman_agent_request_passphrase_input(struct connman_service *service,
- authentication_cb_t callback, void *user_data)
+ authentication_cb_t callback,
+ const char *dbus_sender, void *user_data)
{
DBusMessage *message;
const char *path, *agent_sender, *agent_path;
@@ -407,16 +419,20 @@ int __connman_agent_request_passphrase_input(struct connman_service *service,
DBusMessageIter dict;
struct request_input_reply *passphrase_reply;
int err;
+ void *agent;
- connman_agent_get_info(&agent_sender, &agent_path);
+ agent = connman_agent_get_info(dbus_sender, &agent_sender,
+ &agent_path);
- if (service == NULL || agent_path == NULL || callback == NULL)
+ DBG("agent %p service %p path %s", agent, service, agent_path);
+
+ if (!service || !agent || !agent_path || !callback)
return -ESRCH;
message = dbus_message_new_method_call(agent_sender, agent_path,
CONNMAN_AGENT_INTERFACE,
"RequestInput");
- if (message == NULL)
+ if (!message)
return -ENOMEM;
dbus_message_iter_init_append(message, &iter);
@@ -443,20 +459,19 @@ int __connman_agent_request_passphrase_input(struct connman_service *service,
if (__connman_service_get_security(service) !=
CONNMAN_SERVICE_SECURITY_NONE) {
connman_dbus_dict_append_dict(&dict, "Passphrase",
- request_input_append_passphrase, service);
+ request_input_append_passphrase, service);
previous_passphrase_handler(&dict, service);
}
- if (__connman_service_wps_enabled(service) == TRUE) {
- connman_dbus_dict_append_dict(&dict, "WPS",
+ if (__connman_service_wps_enabled(service))
+ connman_dbus_dict_append_dict(&dict, "WPS",
request_input_append_wps, NULL);
- }
connman_dbus_dict_close(&iter, &dict);
passphrase_reply = g_try_new0(struct request_input_reply, 1);
- if (passphrase_reply == NULL) {
+ if (!passphrase_reply) {
dbus_message_unref(message);
return -ENOMEM;
}
@@ -468,7 +483,7 @@ int __connman_agent_request_passphrase_input(struct connman_service *service,
err = connman_agent_queue_message(service, message,
connman_timeout_input_request(),
request_input_passphrase_reply,
- passphrase_reply);
+ passphrase_reply, agent);
if (err < 0 && err != -EBUSY) {
DBG("error %d sending agent message", err);
@@ -491,16 +506,17 @@ int __connman_agent_request_login_input(struct connman_service *service,
DBusMessageIter dict;
struct request_input_reply *username_password_reply;
int err;
+ void *agent;
- connman_agent_get_info(&agent_sender, &agent_path);
+ agent = connman_agent_get_info(NULL, &agent_sender, &agent_path);
- if (service == NULL || agent_path == NULL || callback == NULL)
+ if (!service || !agent || !agent_path || !callback)
return -ESRCH;
message = dbus_message_new_method_call(agent_sender, agent_path,
CONNMAN_AGENT_INTERFACE,
"RequestInput");
- if (message == NULL)
+ if (!message)
return -ENOMEM;
dbus_message_iter_init_append(message, &iter);
@@ -520,7 +536,7 @@ int __connman_agent_request_login_input(struct connman_service *service,
connman_dbus_dict_close(&iter, &dict);
username_password_reply = g_try_new0(struct request_input_reply, 1);
- if (username_password_reply == NULL) {
+ if (!username_password_reply) {
dbus_message_unref(message);
return -ENOMEM;
}
@@ -531,7 +547,8 @@ int __connman_agent_request_login_input(struct connman_service *service,
err = connman_agent_queue_message(service, message,
connman_timeout_input_request(),
- request_input_login_reply, username_password_reply);
+ request_input_login_reply, username_password_reply,
+ agent);
if (err < 0 && err != -EBUSY) {
DBG("error %d sending agent request", err);
dbus_message_unref(message);
@@ -553,7 +570,7 @@ struct request_browser_reply_data {
static void request_browser_reply(DBusMessage *reply, void *user_data)
{
struct request_browser_reply_data *browser_reply_data = user_data;
- connman_bool_t result = FALSE;
+ bool result = false;
const char *error = NULL;
if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) {
@@ -561,7 +578,7 @@ static void request_browser_reply(DBusMessage *reply, void *user_data)
goto done;
}
- result = TRUE;
+ result = true;
done:
browser_reply_data->callback(browser_reply_data->service, result,
@@ -578,19 +595,20 @@ int __connman_agent_request_browser(struct connman_service *service,
DBusMessageIter iter;
const char *path, *agent_sender, *agent_path;
int err;
+ void *agent;
- connman_agent_get_info(&agent_sender, &agent_path);
+ agent = connman_agent_get_info(NULL, &agent_sender, &agent_path);
- if (service == NULL || agent_path == NULL || callback == NULL)
+ if (!service || !agent || !agent_path || !callback)
return -ESRCH;
- if (url == NULL)
+ if (!url)
url = "";
message = dbus_message_new_method_call(agent_sender, agent_path,
CONNMAN_AGENT_INTERFACE,
"RequestBrowser");
- if (message == NULL)
+ if (!message)
return -ENOMEM;
dbus_message_iter_init_append(message, &iter);
@@ -601,7 +619,7 @@ int __connman_agent_request_browser(struct connman_service *service,
dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &url);
browser_reply_data = g_try_new0(struct request_browser_reply_data, 1);
- if (browser_reply_data == NULL) {
+ if (!browser_reply_data) {
dbus_message_unref(message);
return -ENOMEM;
}
@@ -612,7 +630,8 @@ int __connman_agent_request_browser(struct connman_service *service,
err = connman_agent_queue_message(service, message,
connman_timeout_browser_launch(),
- request_browser_reply, browser_reply_data);
+ request_browser_reply, browser_reply_data,
+ agent);
if (err < 0 && err != -EBUSY) {
DBG("error %d sending browser request", err);
diff --git a/src/agent.c b/src/agent.c
index 5c3bd28c..37cf5247 100644
--- a/src/agent.c
+++ b/src/agent.c
@@ -2,7 +2,7 @@
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2013 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -33,12 +33,25 @@
#include "connman.h"
+#define agent_ref(agent) \
+ agent_ref_debug(agent, __FILE__, __LINE__, __func__)
+#define agent_unref(agent) \
+ agent_unref_debug(agent, __FILE__, __LINE__, __func__)
+
static DBusConnection *connection = NULL;
-static guint agent_watch = 0;
-static gchar *agent_path = NULL;
-static gchar *agent_sender = NULL;
+static GHashTable *agent_hash = NULL;
+static struct connman_agent *default_agent = NULL;
struct connman_agent {
+ int refcount;
+ char *owner;
+ char *path;
+ struct connman_agent_request *pending;
+ GList *queue; /* queued requests for this agent */
+ guint watch;
+};
+
+struct connman_agent_request {
void *user_context;
void *user_data;
DBusMessage *msg;
@@ -48,119 +61,150 @@ struct connman_agent {
struct connman_agent_driver *driver;
};
-static GList *agent_queue = NULL;
-static struct connman_agent *agent_request = NULL;
static GSList *driver_list = NULL;
-void connman_agent_get_info(const char **sender, const char **path)
+void *connman_agent_get_info(const char *dbus_sender, const char **sender,
+ const char **path)
{
- *sender = agent_sender;
- *path = agent_path;
+ struct connman_agent *agent;
+
+ if (!dbus_sender)
+ agent = default_agent;
+ else {
+ agent = g_hash_table_lookup(agent_hash, dbus_sender);
+ if (!agent)
+ agent = default_agent;
+ }
+
+ if (agent) {
+ if (sender)
+ *sender = agent->owner;
+ if (path)
+ *path = agent->path;
+ } else {
+ if (sender)
+ *sender = NULL;
+ if (path)
+ *path = NULL;
+ }
+
+ return agent;
}
-static void agent_data_free(struct connman_agent *data)
+static void agent_request_free(struct connman_agent_request *request)
{
- if (data == NULL)
+ if (!request)
return;
- if (data->user_context != NULL) {
- if (data->driver != NULL && data->driver->context_unref != NULL)
- data->driver->context_unref(data->user_context);
+
+ if (request->user_context) {
+ if (request->driver && request->driver->context_unref)
+ request->driver->context_unref(request->user_context);
+ }
+
+ if (request->msg)
+ dbus_message_unref(request->msg);
+
+ if (request->call) {
+ dbus_pending_call_cancel(request->call);
+ dbus_pending_call_unref(request->call);
}
- if (data->msg != NULL)
- dbus_message_unref(data->msg);
- if (data->call != NULL)
- dbus_pending_call_cancel(data->call);
- g_free(data);
+ g_free(request);
+}
+
+static void agent_finalize_pending(struct connman_agent *agent,
+ DBusMessage *reply)
+{
+ struct connman_agent_request *pending = agent->pending;
+ if (pending) {
+ agent->pending = NULL;
+ pending->callback(reply, pending->user_data);
+ agent_request_free(pending);
+ }
}
static void agent_receive_message(DBusPendingCall *call, void *user_data);
-static int agent_send_next_request(void)
+static int agent_send_next_request(struct connman_agent *agent)
{
- if (agent_request != NULL)
+ if (agent->pending)
return -EBUSY;
- if (agent_queue == NULL)
+ if (!agent->queue)
return 0;
- agent_request = agent_queue->data;
- agent_queue = g_list_remove(agent_queue, agent_request);
+ agent->pending = agent->queue->data;
+ agent->queue = g_list_remove(agent->queue, agent->pending);
+
+ if (!agent->pending->msg)
+ goto fail;
- if (dbus_connection_send_with_reply(connection, agent_request->msg,
- &agent_request->call,
- agent_request->timeout) == FALSE)
+ if (!dbus_connection_send_with_reply(connection, agent->pending->msg,
+ &agent->pending->call,
+ agent->pending->timeout))
goto fail;
- if (agent_request->call == NULL)
+ if (!agent->pending->call)
goto fail;
- if (dbus_pending_call_set_notify(agent_request->call,
- agent_receive_message, agent_request, NULL) == FALSE)
+ if (!dbus_pending_call_set_notify(agent->pending->call,
+ agent_receive_message,
+ agent, NULL))
goto fail;
- dbus_message_unref(agent_request->msg);
- agent_request->msg = NULL;
+ dbus_message_unref(agent->pending->msg);
+ agent->pending->msg = NULL;
return 0;
fail:
- agent_data_free(agent_request);
- agent_request = NULL;
+ agent_finalize_pending(agent, NULL);
return -ESRCH;
}
-static int agent_send_cancel(struct connman_agent *agent)
+static int send_cancel_request(struct connman_agent *agent,
+ struct connman_agent_request *request)
{
DBusMessage *message;
- if (agent_sender == NULL || agent == NULL || agent->driver == NULL)
- return 0;
+ DBG("send cancel req to %s %s", agent->owner, agent->path);
- message = dbus_message_new_method_call(agent_sender, agent_path,
- agent->driver->interface, "Cancel");
- if (message != NULL) {
- dbus_message_set_no_reply(message, TRUE);
- g_dbus_send_message(connection, message);
- return 0;
+ message = dbus_message_new_method_call(agent->owner,
+ agent->path,
+ request->driver->interface,
+ "Cancel");
+ if (!message) {
+ connman_error("Couldn't allocate D-Bus message");
+ return -ENOMEM;
}
- connman_warn("Failed to send Cancel message to agent");
- return -ESRCH;
+ g_dbus_send_message(connection, message);
+ return 0;
}
static void agent_receive_message(DBusPendingCall *call, void *user_data)
{
- struct connman_agent *queue_data = user_data;
+ struct connman_agent *agent = user_data;
DBusMessage *reply;
int err;
- DBG("waiting for %p received %p", agent_request, queue_data);
-
- if (agent_request != queue_data) {
- connman_error("Agent callback expected %p got %p",
- agent_request, queue_data);
- return;
- }
+ DBG("agent %p req %p", agent, agent->pending);
reply = dbus_pending_call_steal_reply(call);
dbus_pending_call_unref(call);
- queue_data->call = NULL;
+ agent->pending->call = NULL;
if (dbus_message_is_error(reply,
- "org.freedesktop.DBus.Error.Timeout") == TRUE ||
+ "org.freedesktop.DBus.Error.Timeout") ||
dbus_message_is_error(reply,
- "org.freedesktop.DBus.Error.TimedOut") == TRUE) {
- agent_send_cancel(queue_data->user_context);
+ "org.freedesktop.DBus.Error.TimedOut")) {
+ send_cancel_request(agent, agent->pending);
}
- queue_data->callback(reply, queue_data->user_data);
+ agent_finalize_pending(agent, reply);
dbus_message_unref(reply);
- agent_data_free(queue_data);
- agent_request = NULL;
-
- err = agent_send_next_request();
- if (err < 0)
+ err = agent_send_next_request(agent);
+ if (err < 0 && err != -EBUSY)
DBG("send next request failed (%s/%d)", strerror(-err), -err);
}
@@ -171,23 +215,25 @@ static struct connman_agent_driver *get_driver(void)
int connman_agent_queue_message(void *user_context,
DBusMessage *msg, int timeout,
- agent_queue_cb callback, void *user_data)
+ agent_queue_cb callback, void *user_data,
+ void *agent_data)
{
- struct connman_agent *queue_data;
+ struct connman_agent_request *queue_data;
struct connman_agent_driver *driver;
+ struct connman_agent *agent = agent_data;
int err;
- if (user_context == NULL || callback == NULL)
+ if (!user_context || !callback)
return -EBADMSG;
- queue_data = g_new0(struct connman_agent, 1);
- if (queue_data == NULL)
+ queue_data = g_new0(struct connman_agent_request, 1);
+ if (!queue_data)
return -ENOMEM;
driver = get_driver();
DBG("driver %p", driver);
- if (driver != NULL && driver->context_ref != NULL) {
+ if (driver && driver->context_ref) {
queue_data->user_context = driver->context_ref(user_context);
queue_data->driver = driver;
} else
@@ -197,103 +243,97 @@ int connman_agent_queue_message(void *user_context,
queue_data->timeout = timeout;
queue_data->callback = callback;
queue_data->user_data = user_data;
- agent_queue = g_list_append(agent_queue, queue_data);
+ agent->queue = g_list_append(agent->queue, queue_data);
- err = agent_send_next_request();
- if (err < 0)
+ err = agent_send_next_request(agent);
+ if (err < 0 && err != -EBUSY)
DBG("send next request failed (%s/%d)", strerror(-err), -err);
return err;
}
-void connman_agent_cancel(void *user_context)
+static void set_default_agent(void)
{
- GList *item, *next;
- struct connman_agent *queued_req;
- int err;
-
- DBG("context %p", user_context);
-
- item = agent_queue;
-
- while (item != NULL) {
- next = g_list_next(item);
- queued_req = item->data;
-
- if (queued_req->user_context == user_context ||
- user_context == NULL) {
- agent_data_free(queued_req);
- agent_queue = g_list_delete_link(agent_queue, item);
- }
-
- item = next;
- }
+ struct connman_agent *agent = NULL;
+ GHashTableIter iter;
+ gpointer key, value;
- if (agent_request == NULL)
+ if (default_agent)
return;
- if (agent_request->user_context != user_context &&
- user_context != NULL)
- return;
-
- agent_send_cancel(agent_request);
+ g_hash_table_iter_init(&iter, agent_hash);
+ if (g_hash_table_iter_next(&iter, &key, &value))
+ agent = value;
- agent_data_free(agent_request);
- agent_request = NULL;
+ if (agent)
+ DBG("default agent set to %s %s", agent->owner, agent->path);
+ else
+ DBG("default agent cleared");
- err = agent_send_next_request();
- if (err < 0)
- DBG("send next request failed (%s/%d)", strerror(-err), -err);
+ default_agent = agent;
}
-static void agent_free(void)
+static void agent_disconnect(DBusConnection *conn, void *user_data)
{
- if (agent_watch > 0)
- g_dbus_remove_watch(connection, agent_watch);
+ struct connman_agent *agent = user_data;
- agent_watch = 0;
+ DBG("agent %s disconnected", agent->owner);
- g_free(agent_sender);
- agent_sender = NULL;
-
- g_free(agent_path);
- agent_path = NULL;
+ if (agent->watch > 0) {
+ g_dbus_remove_watch(conn, agent->watch);
+ agent->watch = 0;
+ }
- connman_agent_cancel(NULL);
+ g_hash_table_remove(agent_hash, agent->owner);
}
-static void agent_disconnect(DBusConnection *conn, void *data)
+static struct connman_agent *agent_ref_debug(struct connman_agent *agent,
+ const char *file, int line, const char *caller)
{
- DBG("data %p", data);
- agent_free();
+ DBG("%p ref %d by %s:%d:%s()", agent, agent->refcount + 1,
+ file, line, caller);
+
+ __sync_fetch_and_add(&agent->refcount, 1);
+
+ return agent;
}
-int connman_agent_register(const char *sender, const char *path)
+static struct connman_agent *agent_create(const char *name, const char *path)
{
- DBG("sender %s path %s", sender, path);
- if (agent_path != NULL)
- return -EEXIST;
+ struct connman_agent *agent;
- agent_sender = g_strdup(sender);
- agent_path = g_strdup(path);
+ agent = g_new0(struct connman_agent, 1);
- agent_watch = g_dbus_add_disconnect_watch(connection, sender,
- agent_disconnect, NULL, NULL);
+ agent->owner = g_strdup(name);
+ agent->path = g_strdup(path);
- return 0;
+ agent->watch = g_dbus_add_disconnect_watch(connection,
+ name, agent_disconnect,
+ agent, NULL);
+
+ return agent_ref(agent);
}
-int connman_agent_unregister(const char *sender, const char *path)
+int connman_agent_register(const char *sender, const char *path)
{
+ struct connman_agent *agent;
+
DBG("sender %s path %s", sender, path);
- if (agent_path == NULL)
- return -ESRCH;
+ agent = g_hash_table_lookup(agent_hash, sender);
+ if (agent)
+ return -EEXIST;
+
+ agent = agent_create(sender, path);
+ if (!agent)
+ return -EINVAL;
- if (agent_watch > 0)
- g_dbus_remove_watch(connection, agent_watch);
+ DBG("agent %s", agent->owner);
- agent_free();
+ g_hash_table_replace(agent_hash, agent->owner, agent);
+
+ if (!default_agent)
+ set_default_agent();
return 0;
}
@@ -307,15 +347,15 @@ struct report_error_data {
static void report_error_reply(DBusMessage *reply, void *user_data)
{
struct report_error_data *report_error = user_data;
- gboolean retry = FALSE;
+ bool retry = false;
const char *dbus_err;
if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) {
dbus_err = dbus_message_get_error_name(reply);
- if (dbus_err != NULL &&
+ if (dbus_err &&
strcmp(dbus_err,
CONNMAN_AGENT_INTERFACE ".Error.Retry") == 0)
- retry = TRUE;
+ retry = true;
}
report_error->callback(report_error->user_context, retry,
@@ -325,21 +365,27 @@ static void report_error_reply(DBusMessage *reply, void *user_data)
int connman_agent_report_error(void *user_context, const char *path,
const char *error,
- report_error_cb_t callback, void *user_data)
+ report_error_cb_t callback,
+ const char *dbus_sender, void *user_data)
{
DBusMessage *message;
DBusMessageIter iter;
struct report_error_data *report_error;
+ struct connman_agent *agent;
int err;
- if (user_context == NULL || agent_path == NULL || error == NULL ||
- callback == NULL)
+ agent = connman_agent_get_info(dbus_sender, NULL, NULL);
+
+ DBG("agent %p sender %s context %p path %s", agent,
+ dbus_sender, user_context, agent ? agent->path : "-");
+
+ if (!user_context || !agent || !agent->path || !error || !callback)
return -ESRCH;
- message = dbus_message_new_method_call(agent_sender, agent_path,
+ message = dbus_message_new_method_call(agent->owner, agent->path,
CONNMAN_AGENT_INTERFACE,
"ReportError");
- if (message == NULL)
+ if (!message)
return -ENOMEM;
dbus_message_iter_init_append(message, &iter);
@@ -350,7 +396,7 @@ int connman_agent_report_error(void *user_context, const char *path,
DBUS_TYPE_STRING, &error);
report_error = g_try_new0(struct report_error_data, 1);
- if (report_error == NULL) {
+ if (!report_error) {
dbus_message_unref(message);
return -ENOMEM;
}
@@ -361,7 +407,8 @@ int connman_agent_report_error(void *user_context, const char *path,
err = connman_agent_queue_message(user_context, message,
connman_timeout_input_request(),
- report_error_reply, report_error);
+ report_error_reply, report_error,
+ agent);
if (err < 0 && err != -EBUSY) {
DBG("error %d sending error request", err);
g_free(report_error);
@@ -400,6 +447,143 @@ int connman_agent_driver_register(struct connman_agent_driver *driver)
return 0;
}
+static void release_driver(void)
+{
+ connman_agent_driver_unregister(get_driver());
+}
+
+static void cancel_all_requests(struct connman_agent *agent)
+{
+ GList *list;
+
+ DBG("request %p pending %p", agent->pending, agent->queue);
+
+ if (agent->pending) {
+ if (agent->pending->call)
+ send_cancel_request(agent, agent->pending);
+
+ agent_finalize_pending(agent, NULL);
+ }
+
+ for (list = agent->queue; list; list = list->next) {
+ struct connman_agent_request *request = list->data;
+
+ if (!request)
+ continue;
+
+ request->callback(NULL, request->user_data);
+ agent_request_free(request);
+ }
+
+ g_list_free(agent->queue);
+ agent->queue = NULL;
+}
+
+void connman_agent_cancel(void *user_context)
+{
+ GHashTableIter iter;
+ gpointer key, value;
+ int err;
+
+ DBG("context %p", user_context);
+
+ g_hash_table_iter_init(&iter, agent_hash);
+ while (g_hash_table_iter_next(&iter, &key, &value)) {
+ GList *list;
+ struct connman_agent *agent = value;
+
+ /*
+ * Cancel all the pending requests to a given agent and service
+ */
+ list = agent->queue;
+ while (list) {
+ struct connman_agent_request *request = list->data;
+
+ if (request && request->user_context &&
+ request->user_context ==
+ user_context) {
+ DBG("cancel pending %p", request);
+
+ request->callback(NULL, request->user_data);
+
+ agent_request_free(request);
+
+ agent->queue = list->next;
+ list = g_list_delete_link(list, list);
+ } else
+ list = list->next;
+ }
+
+ /*
+ * If there is a request from client to a given service,
+ * we need to cancel it.
+ */
+ if (agent->pending && agent->pending->user_context &&
+ agent->pending->user_context == user_context) {
+ DBG("cancel request %p", agent->pending);
+
+ if (agent->pending->call)
+ send_cancel_request(agent, agent->pending);
+
+ agent_finalize_pending(agent, NULL);
+
+ err = agent_send_next_request(agent);
+ if (err < 0 && err != -EBUSY)
+ DBG("send next request failed (%s/%d)",
+ strerror(-err), -err);
+ }
+ }
+}
+
+static void agent_unref_debug(struct connman_agent *agent,
+ const char *file, int line, const char *caller)
+{
+ DBG("%p ref %d by %s:%d:%s()", agent, agent->refcount - 1,
+ file, line, caller);
+
+ if (__sync_fetch_and_sub(&agent->refcount, 1) != 1)
+ return;
+
+ cancel_all_requests(agent);
+
+ g_free(agent->owner);
+ g_free(agent->path);
+
+ if (agent == default_agent) {
+ default_agent = NULL;
+ set_default_agent();
+ }
+
+ g_free(agent);
+}
+
+static void agent_release(struct connman_agent *agent, const char *interface)
+{
+ DBusMessage *message;
+
+ DBG("release agent %s %s", agent->owner, agent->path);
+
+ message = dbus_message_new_method_call(agent->owner, agent->path,
+ interface, "Release");
+ if (message == NULL) {
+ connman_error("Couldn't allocate D-Bus message");
+ return;
+ }
+
+ dbus_message_set_no_reply(message, TRUE);
+ g_dbus_send_message(connection, message);
+}
+
+static void release_agents(void)
+{
+ GHashTableIter iter;
+ gpointer key, value;
+
+ g_hash_table_iter_init(&iter, agent_hash);
+ while (g_hash_table_iter_next(&iter, &key, &value))
+ agent_release(value, get_driver()->interface);
+}
+
/**
* connman_agent_driver_unregister:
* @driver: Agent driver definition
@@ -410,47 +594,46 @@ void connman_agent_driver_unregister(struct connman_agent_driver *driver)
{
GSList *list;
- if (driver == NULL)
+ if (!driver)
return;
DBG("Unregistering driver %p name %s", driver, driver->name);
- if (agent_sender == NULL && agent_path == NULL)
- goto out;
+ release_agents();
for (list = driver_list; list; list = list->next) {
- DBusMessage *message;
-
if (driver != list->data)
continue;
- DBG("Sending release to %s path %s iface %s", agent_sender,
- agent_path, driver->interface);
+ g_hash_table_remove_all(agent_hash);
+ break;
+ }
- message = dbus_message_new_method_call(agent_sender, agent_path,
- driver->interface, "Release");
- if (message != NULL) {
- dbus_message_set_no_reply(message, TRUE);
- g_dbus_send_message(connection, message);
- }
+ driver_list = g_slist_remove(driver_list, driver);
+}
- agent_free();
+static void agent_destroy(gpointer data)
+{
+ struct connman_agent *agent = data;
- /*
- * ATM agent_free() unsets the agent_sender and agent_path
- * variables so we can unregister only once.
- * This needs proper fix later.
- */
- break;
+ DBG("agent %s req %p", agent->owner, agent->pending);
+
+ if (agent->watch > 0) {
+ g_dbus_remove_watch(connection, agent->watch);
+ agent->watch = 0;
}
-out:
- driver_list = g_slist_remove(driver_list, driver);
+ agent_unref(agent);
}
-static void release_all_agents(void)
+int connman_agent_unregister(const char *sender, const char *path)
{
- connman_agent_driver_unregister(get_driver());
+ DBG("sender %s path %s", sender, path);
+
+ if (!g_hash_table_remove(agent_hash, sender))
+ return -ESRCH;
+
+ return 0;
}
int __connman_agent_init(void)
@@ -458,8 +641,13 @@ int __connman_agent_init(void)
DBG("");
connection = connman_dbus_get_connection();
- if (connection == NULL)
- return -1;
+ if (!connection)
+ return -EINVAL;
+
+ agent_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
+ NULL, agent_destroy);
+ if (!agent_hash)
+ return -ENOMEM;
return 0;
}
@@ -468,13 +656,12 @@ void __connman_agent_cleanup(void)
{
DBG("");
- if (connection == NULL)
+ if (!connection)
return;
- if (agent_watch > 0)
- g_dbus_remove_watch(connection, agent_watch);
+ g_hash_table_destroy(agent_hash);
- release_all_agents();
+ release_driver();
dbus_connection_unref(connection);
connection = NULL;
diff --git a/src/bridge.c b/src/bridge.c
index e46cdda6..034fa139 100644
--- a/src/bridge.c
+++ b/src/bridge.c
@@ -2,8 +2,8 @@
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
- * Copyright (C) 2012 BMW Car IT GmbH. All rights reserved.
+ * Copyright (C) 2007-2013 Intel Corporation. All rights reserved.
+ * Copyright (C) 2012-2013 BMW Car IT GmbH. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -46,14 +46,14 @@ static int set_forward_delay(const char *name, unsigned int delay)
forward_delay_path =
g_strdup_printf("/sys/class/net/%s/bridge/forward_delay", name);
- if (forward_delay_path == NULL)
+ if (!forward_delay_path)
return -ENOMEM;
f = fopen(forward_delay_path, "r+");
g_free(forward_delay_path);
- if (f == NULL)
+ if (!f)
return -errno;
fprintf(f, "%d", delay);
@@ -111,8 +111,8 @@ int __connman_bridge_remove(const char *name)
return 0;
}
-int __connman_bridge_enable(const char *name, const char *gateway,
- const char *broadcast)
+int __connman_bridge_enable(const char *name, const char *ip_address,
+ int prefix_len, const char *broadcast)
{
int err, index;
@@ -121,8 +121,8 @@ int __connman_bridge_enable(const char *name, const char *gateway,
return index;
err = __connman_inet_modify_address(RTM_NEWADDR,
- NLM_F_REPLACE | NLM_F_ACK, index, AF_INET,
- gateway, NULL, 24, broadcast);
+ NLM_F_REPLACE | NLM_F_ACK, index, AF_INET,
+ ip_address, NULL, prefix_len, broadcast);
if (err < 0)
return err;
diff --git a/src/clock.c b/src/clock.c
index 2ce61d9e..0fde2c34 100644
--- a/src/clock.c
+++ b/src/clock.c
@@ -2,7 +2,7 @@
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2013 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -96,7 +96,7 @@ static void clock_properties_load(void)
enum timezone_updates timezone_value;
keyfile = __connman_storage_load_global();
- if (keyfile == NULL)
+ if (!keyfile)
return;
str = g_key_file_get_string(keyfile, "global", "TimeUpdates", NULL);
@@ -125,17 +125,17 @@ static void clock_properties_save(void)
const char *str;
keyfile = __connman_storage_load_global();
- if (keyfile == NULL)
+ if (!keyfile)
keyfile = g_key_file_new();
str = time_updates2string(time_updates_config);
- if (str != NULL)
+ if (str)
g_key_file_set_string(keyfile, "global", "TimeUpdates", str);
else
g_key_file_remove_key(keyfile, "global", "TimeUpdates", NULL);
str = timezone_updates2string(timezone_updates_config);
- if (str != NULL)
+ if (str)
g_key_file_set_string(keyfile, "global", "TimezoneUpdates",
str);
else
@@ -157,10 +157,10 @@ static void append_timeservers(DBusMessageIter *iter, void *user_data)
int i;
char **timeservers = __connman_timeserver_system_get();
- if (timeservers == NULL)
+ if (!timeservers)
return;
- for (i = 0; timeservers[i] != NULL; i++) {
+ for (i = 0; timeservers[i]; i++) {
dbus_message_iter_append_basic(iter,
DBUS_TYPE_STRING, &timeservers[i]);
}
@@ -179,7 +179,7 @@ static DBusMessage *get_properties(DBusConnection *conn,
DBG("conn %p", conn);
reply = dbus_message_new_method_return(msg);
- if (reply == NULL)
+ if (!reply)
return NULL;
dbus_message_iter_init_append(reply, &array);
@@ -194,16 +194,16 @@ static DBusMessage *get_properties(DBusConnection *conn,
}
str = time_updates2string(time_updates_config);
- if (str != NULL)
+ if (str)
connman_dbus_dict_append_basic(&dict, "TimeUpdates",
DBUS_TYPE_STRING, &str);
- if (timezone_config != NULL)
+ if (timezone_config)
connman_dbus_dict_append_basic(&dict, "Timezone",
DBUS_TYPE_STRING, &timezone_config);
str = timezone_updates2string(timezone_updates_config);
- if (str != NULL)
+ if (str)
connman_dbus_dict_append_basic(&dict, "TimezoneUpdates",
DBUS_TYPE_STRING, &str);
@@ -224,7 +224,7 @@ static DBusMessage *set_property(DBusConnection *conn,
DBG("conn %p", conn);
- if (dbus_message_iter_init(msg, &iter) == FALSE)
+ if (!dbus_message_iter_init(msg, &iter))
return __connman_error_invalid_arguments(msg);
if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
@@ -240,7 +240,7 @@ static DBusMessage *set_property(DBusConnection *conn,
type = dbus_message_iter_get_arg_type(&value);
- if (g_str_equal(name, "Time") == TRUE) {
+ if (g_str_equal(name, "Time")) {
struct timeval tv;
dbus_uint64_t newval;
@@ -261,7 +261,7 @@ static DBusMessage *set_property(DBusConnection *conn,
connman_dbus_property_changed_basic(CONNMAN_MANAGER_PATH,
CONNMAN_CLOCK_INTERFACE, "Time",
DBUS_TYPE_UINT64, &newval);
- } else if (g_str_equal(name, "TimeUpdates") == TRUE) {
+ } else if (g_str_equal(name, "TimeUpdates")) {
const char *strval;
enum time_updates newval;
@@ -283,7 +283,7 @@ static DBusMessage *set_property(DBusConnection *conn,
connman_dbus_property_changed_basic(CONNMAN_MANAGER_PATH,
CONNMAN_CLOCK_INTERFACE, "TimeUpdates",
DBUS_TYPE_STRING, &strval);
- } else if (g_str_equal(name, "Timezone") == TRUE) {
+ } else if (g_str_equal(name, "Timezone")) {
const char *strval;
if (type != DBUS_TYPE_STRING)
@@ -295,8 +295,8 @@ static DBusMessage *set_property(DBusConnection *conn,
dbus_message_iter_get_basic(&value, &strval);
if (__connman_timezone_change(strval) < 0)
- return __connman_error_invalid_arguments(msg);
- } else if (g_str_equal(name, "TimezoneUpdates") == TRUE) {
+ return __connman_error_invalid_arguments(msg);
+ } else if (g_str_equal(name, "TimezoneUpdates")) {
const char *strval;
enum timezone_updates newval;
@@ -318,7 +318,7 @@ static DBusMessage *set_property(DBusConnection *conn,
connman_dbus_property_changed_basic(CONNMAN_MANAGER_PATH,
CONNMAN_CLOCK_INTERFACE, "TimezoneUpdates",
DBUS_TYPE_STRING, &strval);
- } else if (g_str_equal(name, "Timeservers") == TRUE) {
+ } else if (g_str_equal(name, "Timeservers")) {
DBusMessageIter entry;
char **str = NULL;
GSList *list = NULL;
@@ -344,10 +344,10 @@ static DBusMessage *set_property(DBusConnection *conn,
dbus_message_iter_next(&entry);
}
- if (list != NULL) {
+ if (list) {
str = g_new0(char *, count+1);
- while (list != NULL) {
+ while (list) {
count--;
str[count] = list->data;
list = g_slist_delete_link(list, list);
@@ -356,7 +356,7 @@ static DBusMessage *set_property(DBusConnection *conn,
__connman_timeserver_system_set(str);
- if (str != NULL)
+ if (str)
g_strfreev(str);
connman_dbus_property_changed_array(CONNMAN_MANAGER_PATH,
@@ -393,7 +393,7 @@ void __connman_clock_update_timezone(void)
g_free(timezone_config);
timezone_config = __connman_timezone_lookup();
- if (timezone_config == NULL)
+ if (!timezone_config)
return;
connman_dbus_property_changed_basic(CONNMAN_MANAGER_PATH,
@@ -406,7 +406,7 @@ int __connman_clock_init(void)
DBG("");
connection = connman_dbus_get_connection();
- if (connection == NULL)
+ if (!connection)
return -1;
__connman_timezone_init();
@@ -426,7 +426,7 @@ void __connman_clock_cleanup(void)
{
DBG("");
- if (connection == NULL)
+ if (!connection)
return;
g_dbus_unregister_interface(connection, CONNMAN_MANAGER_PATH,
diff --git a/src/config.c b/src/config.c
index e5c9c7ec..330ae817 100644
--- a/src/config.c
+++ b/src/config.c
@@ -2,7 +2,7 @@
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2013 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -55,8 +55,8 @@ struct connman_config_service {
GSList *service_identifiers;
char *config_ident; /* file prefix */
char *config_entry; /* entry name */
- connman_bool_t hidden;
- connman_bool_t virtual;
+ bool hidden;
+ bool virtual;
char *virtual_file;
char *ipv4_address;
char *ipv4_netmask;
@@ -81,7 +81,7 @@ struct connman_config {
static GHashTable *config_table = NULL;
-static connman_bool_t cleanup = FALSE;
+static bool cleanup = false;
/* Definition of possible strings in the .config files */
#define CONFIG_KEY_NAME "Name"
@@ -162,38 +162,40 @@ static void unregister_service(gpointer data)
char *service_id;
GSList *list;
- if (cleanup == TRUE)
+ if (cleanup)
goto free_only;
connman_info("Removing service configuration %s",
config_service->ident);
- if (config_service->virtual == TRUE)
+ if (config_service->virtual)
goto free_only;
- for (list = config_service->service_identifiers; list != NULL;
+ for (list = config_service->service_identifiers; list;
list = list->next) {
service_id = list->data;
service = __connman_service_lookup_from_ident(service_id);
- if (service != NULL) {
- __connman_service_set_immutable(service, FALSE);
+ if (service) {
+ __connman_service_set_immutable(service, false);
__connman_service_set_config(service, NULL, NULL);
__connman_service_remove(service);
/*
- * Ethernet service cannot be removed by
+ * Ethernet or gadget service cannot be removed by
* __connman_service_remove() so reset the ipconfig
* here.
*/
if (connman_service_get_type(service) ==
- CONNMAN_SERVICE_TYPE_ETHERNET) {
+ CONNMAN_SERVICE_TYPE_ETHERNET ||
+ connman_service_get_type(service) ==
+ CONNMAN_SERVICE_TYPE_GADGET) {
__connman_service_disconnect(service);
__connman_service_reset_ipconfig(service,
CONNMAN_IPCONFIG_TYPE_IPV4, NULL, NULL);
__connman_service_reset_ipconfig(service,
CONNMAN_IPCONFIG_TYPE_IPV6, NULL, NULL);
- __connman_service_set_ignore(service, TRUE);
+ __connman_service_set_ignore(service, true);
/*
* After these operations, user needs to
@@ -203,7 +205,7 @@ static void unregister_service(gpointer data)
}
}
- if (__connman_storage_remove_service(service_id) == FALSE)
+ if (!__connman_storage_remove_service(service_id))
DBG("Could not remove all files for service %s",
service_id);
}
@@ -247,7 +249,7 @@ static void check_keys(GKeyFile *keyfile, const char *group,
gsize nb_avail_keys, i, j;
avail_keys = g_key_file_get_keys(keyfile, group, &nb_avail_keys, NULL);
- if (avail_keys == NULL)
+ if (!avail_keys)
return;
/*
@@ -259,7 +261,7 @@ static void check_keys(GKeyFile *keyfile, const char *group,
if (g_strcmp0(avail_keys[i], possible_keys[j]) == 0)
break;
- if (possible_keys[j] == NULL)
+ if (!possible_keys[j])
connman_warn("Unknown configuration key %s in [%s]",
avail_keys[i], group);
}
@@ -313,11 +315,11 @@ static int parse_address(const char *address_str, int address_family,
char **route;
route = g_strsplit(address_str, "/", 0);
- if (route == NULL)
+ if (!route)
return -EINVAL;
addr_str = route[0];
- if (addr_str == NULL || addr_str[0] == '\0') {
+ if (!addr_str || addr_str[0] == '\0') {
err = -EINVAL;
goto out;
}
@@ -326,20 +328,17 @@ static int parse_address(const char *address_str, int address_family,
goto out;
mask_str = route[1];
- if (mask_str == NULL || mask_str[0] == '\0') {
+ if (!mask_str || mask_str[0] == '\0') {
err = -EINVAL;
goto out;
}
gw_str = route[2];
- if (gw_str == NULL || gw_str[0] == '\0') {
- err = -EINVAL;
- goto out;
+ if (gw_str && gw_str[0]) {
+ if ((err = check_family(gw_str, address_family)) < 0)
+ goto out;
}
- if ((err = check_family(gw_str, address_family)) < 0)
- goto out;
-
g_free(*address);
*address = g_strdup(addr_str);
@@ -349,7 +348,10 @@ static int parse_address(const char *address_str, int address_family,
g_free(*gateway);
*gateway = g_strdup(gw_str);
- DBG("address %s/%s via %s", *address, *netmask, *gateway);
+ if (*gateway)
+ DBG("address %s/%s via %s", *address, *netmask, *gateway);
+ else
+ DBG("address %s/%s", *address, *netmask);
out:
g_strfreev(route);
@@ -357,19 +359,19 @@ out:
return err;
}
-static connman_bool_t check_address(char *address_str, char **address)
+static bool check_address(char *address_str, char **address)
{
if (g_ascii_strcasecmp(address_str, "auto") == 0 ||
g_ascii_strcasecmp(address_str, "dhcp") == 0 ||
g_ascii_strcasecmp(address_str, "off") == 0) {
*address = address_str;
- return FALSE;
+ return false;
}
- return TRUE;
+ return true;
}
-static connman_bool_t load_service_generic(GKeyFile *keyfile,
+static bool load_service_generic(GKeyFile *keyfile,
const char *group, struct connman_config *config,
struct connman_config_service *service)
{
@@ -377,8 +379,8 @@ static connman_bool_t load_service_generic(GKeyFile *keyfile,
char **strlist;
gsize length;
- str = g_key_file_get_string(keyfile, group, SERVICE_KEY_IPv4, NULL);
- if (str != NULL && check_address(str, &service->ipv4_address) == TRUE) {
+ str = __connman_config_get_string(keyfile, group, SERVICE_KEY_IPv4, NULL);
+ if (str && check_address(str, &service->ipv4_address)) {
mask = NULL;
if (parse_address(str, AF_INET, &service->ipv4_address,
@@ -389,7 +391,7 @@ static connman_bool_t load_service_generic(GKeyFile *keyfile,
goto err;
}
- if (g_strrstr(mask, ".") == NULL) {
+ if (!g_strrstr(mask, ".")) {
/* We have netmask length */
in_addr_t addr;
struct in_addr netmask_in;
@@ -412,8 +414,8 @@ static connman_bool_t load_service_generic(GKeyFile *keyfile,
g_free(str);
}
- str = g_key_file_get_string(keyfile, group, SERVICE_KEY_IPv6, NULL);
- if (str != NULL && check_address(str, &service->ipv6_address) == TRUE) {
+ str = __connman_config_get_string(keyfile, group, SERVICE_KEY_IPv6, NULL);
+ if (str && check_address(str, &service->ipv6_address)) {
long int value;
char *ptr;
@@ -437,29 +439,29 @@ static connman_bool_t load_service_generic(GKeyFile *keyfile,
g_free(str);
}
- str = g_key_file_get_string(keyfile, group, SERVICE_KEY_IPv6_PRIVACY,
+ str = __connman_config_get_string(keyfile, group, SERVICE_KEY_IPv6_PRIVACY,
NULL);
- if (str != NULL) {
+ if (str) {
g_free(service->ipv6_privacy);
service->ipv6_privacy = str;
}
- str = g_key_file_get_string(keyfile, group, SERVICE_KEY_MAC, NULL);
- if (str != NULL) {
+ str = __connman_config_get_string(keyfile, group, SERVICE_KEY_MAC, NULL);
+ if (str) {
g_free(service->mac);
service->mac = str;
}
- str = g_key_file_get_string(keyfile, group, SERVICE_KEY_DOMAIN, NULL);
- if (str != NULL) {
+ str = __connman_config_get_string(keyfile, group, SERVICE_KEY_DOMAIN, NULL);
+ if (str) {
g_free(service->domain_name);
service->domain_name = str;
}
- strlist = g_key_file_get_string_list(keyfile, group,
+ strlist = __connman_config_get_string_list(keyfile, group,
SERVICE_KEY_NAMESERVERS,
&length, NULL);
- if (strlist != NULL) {
+ if (strlist) {
if (length != 0) {
g_strfreev(service->nameservers);
service->nameservers = strlist;
@@ -467,10 +469,10 @@ static connman_bool_t load_service_generic(GKeyFile *keyfile,
g_strfreev(strlist);
}
- strlist = g_key_file_get_string_list(keyfile, group,
+ strlist = __connman_config_get_string_list(keyfile, group,
SERVICE_KEY_SEARCH_DOMAINS,
&length, NULL);
- if (strlist != NULL) {
+ if (strlist) {
if (length != 0) {
g_strfreev(service->search_domains);
service->search_domains = strlist;
@@ -478,10 +480,10 @@ static connman_bool_t load_service_generic(GKeyFile *keyfile,
g_strfreev(strlist);
}
- strlist = g_key_file_get_string_list(keyfile, group,
+ strlist = __connman_config_get_string_list(keyfile, group,
SERVICE_KEY_TIMESERVERS,
&length, NULL);
- if (strlist != NULL) {
+ if (strlist) {
if (length != 0) {
g_strfreev(service->timeservers);
service->timeservers = strlist;
@@ -489,7 +491,7 @@ static connman_bool_t load_service_generic(GKeyFile *keyfile,
g_strfreev(strlist);
}
- return TRUE;
+ return true;
err:
g_free(service->ident);
@@ -502,39 +504,39 @@ err:
g_free(service->mac);
g_free(service);
- return FALSE;
+ return false;
}
-static connman_bool_t load_service(GKeyFile *keyfile, const char *group,
+static bool load_service(GKeyFile *keyfile, const char *group,
struct connman_config *config)
{
struct connman_config_service *service;
const char *ident;
char *str, *hex_ssid;
- gboolean service_created = FALSE;
+ bool service_created = false;
/* Strip off "service_" prefix */
ident = group + 8;
if (strlen(ident) < 1)
- return FALSE;
+ return false;
/* Verify that provided keys are good */
check_keys(keyfile, group, service_possible_keys);
service = g_hash_table_lookup(config->service_table, ident);
- if (service == NULL) {
+ if (!service) {
service = g_try_new0(struct connman_config_service, 1);
- if (service == NULL)
- return FALSE;
+ if (!service)
+ return false;
service->ident = g_strdup(ident);
- service_created = TRUE;
+ service_created = true;
}
- str = g_key_file_get_string(keyfile, group, SERVICE_KEY_TYPE, NULL);
- if (str != NULL) {
+ str = __connman_config_get_string(keyfile, group, SERVICE_KEY_TYPE, NULL);
+ if (str) {
g_free(service->type);
service->type = str;
} else {
@@ -543,8 +545,8 @@ static connman_bool_t load_service(GKeyFile *keyfile, const char *group,
goto err;
}
- if (load_service_generic(keyfile, group, config, service) == FALSE)
- return FALSE;
+ if (!load_service_generic(keyfile, group, config, service))
+ return false;
if (g_strcmp0(str, "ethernet") == 0) {
service->config_ident = g_strdup(config->ident);
@@ -553,24 +555,24 @@ static connman_bool_t load_service(GKeyFile *keyfile, const char *group,
g_hash_table_insert(config->service_table, service->ident,
service);
- return 0;
+ return true;
}
- str = g_key_file_get_string(keyfile, group, SERVICE_KEY_NAME, NULL);
- if (str != NULL) {
+ str = __connman_config_get_string(keyfile, group, SERVICE_KEY_NAME, NULL);
+ if (str) {
g_free(service->name);
service->name = str;
}
- hex_ssid = g_key_file_get_string(keyfile, group, SERVICE_KEY_SSID,
+ hex_ssid = __connman_config_get_string(keyfile, group, SERVICE_KEY_SSID,
NULL);
- if (hex_ssid != NULL) {
+ if (hex_ssid) {
char *ssid;
unsigned int i, j = 0, hex;
size_t hex_ssid_len = strlen(hex_ssid);
ssid = g_try_malloc0(hex_ssid_len / 2);
- if (ssid == NULL) {
+ if (!ssid) {
g_free(hex_ssid);
goto err;
}
@@ -590,13 +592,13 @@ static connman_bool_t load_service(GKeyFile *keyfile, const char *group,
g_free(service->ssid);
service->ssid = ssid;
service->ssid_len = hex_ssid_len / 2;
- } else if (service->name != NULL) {
+ } else if (service->name) {
char *ssid;
unsigned int ssid_len;
ssid_len = strlen(service->name);
ssid = g_try_malloc0(ssid_len);
- if (ssid == NULL)
+ if (!ssid)
goto err;
memcpy(ssid, service->name, ssid_len);
@@ -605,59 +607,59 @@ static connman_bool_t load_service(GKeyFile *keyfile, const char *group,
service->ssid_len = ssid_len;
}
- str = g_key_file_get_string(keyfile, group, SERVICE_KEY_EAP, NULL);
- if (str != NULL) {
+ str = __connman_config_get_string(keyfile, group, SERVICE_KEY_EAP, NULL);
+ if (str) {
g_free(service->eap);
service->eap = str;
}
- str = g_key_file_get_string(keyfile, group, SERVICE_KEY_CA_CERT, NULL);
- if (str != NULL) {
+ str = __connman_config_get_string(keyfile, group, SERVICE_KEY_CA_CERT, NULL);
+ if (str) {
g_free(service->ca_cert_file);
service->ca_cert_file = str;
}
- str = g_key_file_get_string(keyfile, group, SERVICE_KEY_CL_CERT, NULL);
- if (str != NULL) {
+ str = __connman_config_get_string(keyfile, group, SERVICE_KEY_CL_CERT, NULL);
+ if (str) {
g_free(service->client_cert_file);
service->client_cert_file = str;
}
- str = g_key_file_get_string(keyfile, group, SERVICE_KEY_PRV_KEY, NULL);
- if (str != NULL) {
+ str = __connman_config_get_string(keyfile, group, SERVICE_KEY_PRV_KEY, NULL);
+ if (str) {
g_free(service->private_key_file);
service->private_key_file = str;
}
- str = g_key_file_get_string(keyfile, group,
+ str = __connman_config_get_string(keyfile, group,
SERVICE_KEY_PRV_KEY_PASS, NULL);
- if (str != NULL) {
+ if (str) {
g_free(service->private_key_passphrase);
service->private_key_passphrase = str;
}
- str = g_key_file_get_string(keyfile, group,
+ str = __connman_config_get_string(keyfile, group,
SERVICE_KEY_PRV_KEY_PASS_TYPE, NULL);
- if (str != NULL) {
+ if (str) {
g_free(service->private_key_passphrase_type);
service->private_key_passphrase_type = str;
}
- str = g_key_file_get_string(keyfile, group, SERVICE_KEY_IDENTITY, NULL);
- if (str != NULL) {
+ str = __connman_config_get_string(keyfile, group, SERVICE_KEY_IDENTITY, NULL);
+ if (str) {
g_free(service->identity);
service->identity = str;
}
- str = g_key_file_get_string(keyfile, group, SERVICE_KEY_PHASE2, NULL);
- if (str != NULL) {
+ str = __connman_config_get_string(keyfile, group, SERVICE_KEY_PHASE2, NULL);
+ if (str) {
g_free(service->phase2);
service->phase2 = str;
}
- str = g_key_file_get_string(keyfile, group, SERVICE_KEY_PASSPHRASE,
+ str = __connman_config_get_string(keyfile, group, SERVICE_KEY_PASSPHRASE,
NULL);
- if (str != NULL) {
+ if (str) {
g_free(service->passphrase);
service->passphrase = str;
}
@@ -665,7 +667,7 @@ static connman_bool_t load_service(GKeyFile *keyfile, const char *group,
service->config_ident = g_strdup(config->ident);
service->config_entry = g_strdup_printf("service_%s", service->ident);
- service->hidden = g_key_file_get_boolean(keyfile, group,
+ service->hidden = __connman_config_get_bool(keyfile, group,
SERVICE_KEY_HIDDEN, NULL);
if (service_created)
@@ -674,10 +676,10 @@ static connman_bool_t load_service(GKeyFile *keyfile, const char *group,
connman_info("Adding service configuration %s", service->ident);
- return TRUE;
+ return true;
err:
- if (service_created == TRUE) {
+ if (service_created) {
g_free(service->ident);
g_free(service->type);
g_free(service->name);
@@ -685,23 +687,23 @@ err:
g_free(service);
}
- return FALSE;
+ return false;
}
-static connman_bool_t load_service_from_keyfile(GKeyFile *keyfile,
+static bool load_service_from_keyfile(GKeyFile *keyfile,
struct connman_config *config)
{
- connman_bool_t found = FALSE;
+ bool found = false;
char **groups;
int i;
groups = g_key_file_get_groups(keyfile, NULL);
- for (i = 0; groups[i] != NULL; i++) {
- if (g_str_has_prefix(groups[i], "service_") == FALSE)
+ for (i = 0; groups[i]; i++) {
+ if (!g_str_has_prefix(groups[i], "service_"))
continue;
- if (load_service(keyfile, groups[i], config) == TRUE)
- found = TRUE;
+ if (load_service(keyfile, groups[i], config))
+ found = true;
}
g_strfreev(groups);
@@ -717,25 +719,27 @@ static int load_config(struct connman_config *config)
DBG("config %p", config);
keyfile = __connman_storage_load_config(config->ident);
- if (keyfile == NULL)
+ if (!keyfile)
return -EIO;
+ g_key_file_set_list_separator(keyfile, ',');
+
/* Verify keys validity of the global section */
check_keys(keyfile, "global", config_possible_keys);
- str = g_key_file_get_string(keyfile, "global", CONFIG_KEY_NAME, NULL);
- if (str != NULL) {
+ str = __connman_config_get_string(keyfile, "global", CONFIG_KEY_NAME, NULL);
+ if (str) {
g_free(config->name);
config->name = str;
}
- str = g_key_file_get_string(keyfile, "global", CONFIG_KEY_DESC, NULL);
- if (str != NULL) {
+ str = __connman_config_get_string(keyfile, "global", CONFIG_KEY_DESC, NULL);
+ if (str) {
g_free(config->description);
config->description = str;
}
- if (load_service_from_keyfile(keyfile, config) == FALSE)
+ if (!load_service_from_keyfile(keyfile, config))
connman_warn("Config file %s/%s.config does not contain any "
"configuration that can be provisioned!",
STORAGEDIR, config->ident);
@@ -751,11 +755,11 @@ static struct connman_config *create_config(const char *ident)
DBG("ident %s", ident);
- if (g_hash_table_lookup(config_table, ident) != NULL)
+ if (g_hash_table_lookup(config_table, ident))
return NULL;
config = g_try_new0(struct connman_config, 1);
- if (config == NULL)
+ if (!config)
return NULL;
config->ident = g_strdup(ident);
@@ -770,18 +774,18 @@ static struct connman_config *create_config(const char *ident)
return config;
}
-static connman_bool_t validate_ident(const char *ident)
+static bool validate_ident(const char *ident)
{
unsigned int i;
- if (ident == NULL)
- return FALSE;
+ if (!ident)
+ return false;
for (i = 0; i < strlen(ident); i++)
- if (g_ascii_isprint(ident[i]) == FALSE)
- return FALSE;
+ if (!g_ascii_isprint(ident[i]))
+ return false;
- return TRUE;
+ return true;
}
static int read_configs(void)
@@ -791,31 +795,31 @@ static int read_configs(void)
DBG("");
dir = g_dir_open(STORAGEDIR, 0, NULL);
- if (dir != NULL) {
+ if (dir) {
const gchar *file;
- while ((file = g_dir_read_name(dir)) != NULL) {
+ while ((file = g_dir_read_name(dir))) {
GString *str;
gchar *ident;
- if (g_str_has_suffix(file, ".config") == FALSE)
+ if (!g_str_has_suffix(file, ".config"))
continue;
ident = g_strrstr(file, ".config");
- if (ident == NULL)
+ if (!ident)
continue;
str = g_string_new_len(file, ident - file);
- if (str == NULL)
+ if (!str)
continue;
ident = g_string_free(str, FALSE);
- if (validate_ident(ident) == TRUE) {
+ if (validate_ident(ident)) {
struct connman_config *config;
config = create_config(ident);
- if (config != NULL)
+ if (config)
load_config(config);
} else {
connman_error("Invalid config ident %s", ident);
@@ -834,19 +838,19 @@ static void config_notify_handler(struct inotify_event *event,
{
char *ext;
- if (ident == NULL)
+ if (!ident)
return;
- if (g_str_has_suffix(ident, ".config") == FALSE)
+ if (!g_str_has_suffix(ident, ".config"))
return;
ext = g_strrstr(ident, ".config");
- if (ext == NULL)
+ if (!ext)
return;
*ext = '\0';
- if (validate_ident(ident) == FALSE) {
+ if (!validate_ident(ident)) {
connman_error("Invalid config ident %s", ident);
return;
}
@@ -858,7 +862,7 @@ static void config_notify_handler(struct inotify_event *event,
struct connman_config *config;
config = g_hash_table_lookup(config_table, ident);
- if (config != NULL) {
+ if (config) {
int ret;
g_hash_table_remove_all(config->service_table);
@@ -896,14 +900,61 @@ void __connman_config_cleanup(void)
{
DBG("");
- cleanup = TRUE;
+ cleanup = true;
connman_inotify_unregister(STORAGEDIR, config_notify_handler);
g_hash_table_destroy(config_table);
config_table = NULL;
- cleanup = FALSE;
+ cleanup = false;
+}
+
+char *__connman_config_get_string(GKeyFile *key_file,
+ const char *group_name, const char *key, GError **error)
+{
+ char *str = g_key_file_get_string(key_file, group_name, key, error);
+ if (!str)
+ return NULL;
+
+ return g_strchomp(str);
+}
+
+char **__connman_config_get_string_list(GKeyFile *key_file,
+ const char *group_name, const char *key, gsize *length, GError **error)
+{
+ char **p;
+ char **strlist = g_key_file_get_string_list(key_file, group_name, key,
+ length, error);
+ if (!strlist)
+ return NULL;
+
+ p = strlist;
+ while (*p) {
+ *p = g_strstrip(*p);
+ p++;
+ }
+
+ return strlist;
+}
+
+bool __connman_config_get_bool(GKeyFile *key_file,
+ const char *group_name, const char *key, GError **error)
+{
+ char *valstr;
+ bool val = false;
+
+ valstr = g_key_file_get_value(key_file, group_name, key, error);
+ if (!valstr)
+ return false;
+
+ valstr = g_strchomp(valstr);
+ if (strcmp(valstr, "true") == 0 || strcmp(valstr, "1") == 0)
+ val = true;
+
+ g_free(valstr);
+
+ return val;
}
static char *config_pem_fsid(const char *pem_file)
@@ -912,7 +963,7 @@ static char *config_pem_fsid(const char *pem_file)
unsigned *fsid = (unsigned *) &buf.f_fsid;
unsigned long long fsid64;
- if (pem_file == NULL)
+ if (!pem_file)
return NULL;
if (statfs(pem_file, &buf) < 0) {
@@ -926,44 +977,43 @@ static char *config_pem_fsid(const char *pem_file)
return g_strdup_printf("%llx", fsid64);
}
-static void provision_service_wifi(gpointer key,
- struct connman_config_service *config,
+static void provision_service_wifi(struct connman_config_service *config,
struct connman_service *service,
struct connman_network *network,
const void *ssid, unsigned int ssid_len)
{
- if (config->eap != NULL)
+ if (config->eap)
__connman_service_set_string(service, "EAP", config->eap);
- if (config->identity != NULL)
+ if (config->identity)
__connman_service_set_string(service, "Identity",
config->identity);
- if (config->ca_cert_file != NULL)
+ if (config->ca_cert_file)
__connman_service_set_string(service, "CACertFile",
config->ca_cert_file);
- if (config->client_cert_file != NULL)
+ if (config->client_cert_file)
__connman_service_set_string(service, "ClientCertFile",
config->client_cert_file);
- if (config->private_key_file != NULL)
+ if (config->private_key_file)
__connman_service_set_string(service, "PrivateKeyFile",
config->private_key_file);
if (g_strcmp0(config->private_key_passphrase_type, "fsid") == 0 &&
- config->private_key_file != NULL) {
+ config->private_key_file) {
char *fsid;
fsid = config_pem_fsid(config->private_key_file);
- if (fsid == NULL)
+ if (!fsid)
return;
g_free(config->private_key_passphrase);
config->private_key_passphrase = fsid;
}
- if (config->private_key_passphrase != NULL) {
+ if (config->private_key_passphrase) {
__connman_service_set_string(service, "PrivateKeyPassphrase",
config->private_key_passphrase);
/*
@@ -975,13 +1025,14 @@ static void provision_service_wifi(gpointer key,
*/
}
- if (config->phase2 != NULL)
+ if (config->phase2)
__connman_service_set_string(service, "Phase2", config->phase2);
- if (config->passphrase != NULL)
- __connman_service_set_string(service, "Passphrase", config->passphrase);
+ if (config->passphrase)
+ __connman_service_set_string(service, "Passphrase",
+ config->passphrase);
- if (config->hidden == TRUE)
+ if (config->hidden)
__connman_service_set_hidden(service);
}
@@ -994,7 +1045,8 @@ static gboolean remove_virtual_config(gpointer user_data)
{
struct connect_virtual *virtual = user_data;
- __connman_service_connect(virtual->service);
+ __connman_service_connect(virtual->service,
+ CONNMAN_SERVICE_CONNECT_REASON_AUTO);
g_hash_table_remove(config_table, virtual->vfile);
g_free(virtual);
@@ -1002,11 +1054,9 @@ static gboolean remove_virtual_config(gpointer user_data)
return FALSE;
}
-static void provision_service(gpointer key, gpointer value,
- gpointer user_data)
+static int try_provision_service(struct connman_config_service *config,
+ struct connman_service *service)
{
- struct connman_service *service = user_data;
- struct connman_config_service *config = value;
struct connman_network *network;
const void *service_id;
enum connman_service_type type;
@@ -1016,32 +1066,36 @@ static void provision_service(gpointer key, gpointer value,
type = connman_service_get_type(service);
if (type == CONNMAN_SERVICE_TYPE_WIFI &&
g_strcmp0(config->type, "wifi") != 0)
- return;
+ return -ENOENT;
if (type == CONNMAN_SERVICE_TYPE_ETHERNET &&
g_strcmp0(config->type, "ethernet") != 0)
- return;
+ return -ENOENT;
+
+ if (type == CONNMAN_SERVICE_TYPE_GADGET &&
+ g_strcmp0(config->type, "gadget") != 0)
+ return -ENOENT;
DBG("service %p ident %s", service,
__connman_service_get_ident(service));
network = __connman_service_get_network(service);
- if (network == NULL) {
+ if (!network) {
connman_error("Service has no network set");
- return;
+ return -EINVAL;
}
DBG("network %p ident %s", network,
connman_network_get_identifier(network));
- if (config->mac != NULL) {
+ if (config->mac) {
struct connman_device *device;
const char *device_addr;
device = connman_network_get_device(network);
- if (device == NULL) {
+ if (!device) {
connman_error("Network device is missing");
- return;
+ return -ENODEV;
}
device_addr = connman_device_get_string(device, "Address");
@@ -1049,26 +1103,26 @@ static void provision_service(gpointer key, gpointer value,
DBG("wants %s has %s", config->mac, device_addr);
if (g_ascii_strcasecmp(device_addr, config->mac) != 0)
- return;
+ return -ENOENT;
}
if (g_strcmp0(config->type, "wifi") == 0 &&
type == CONNMAN_SERVICE_TYPE_WIFI) {
ssid = connman_network_get_blob(network, "WiFi.SSID",
&ssid_len);
- if (ssid == NULL) {
+ if (!ssid) {
connman_error("Network SSID not set");
- return;
+ return -EINVAL;
}
- if (config->ssid == NULL || ssid_len != config->ssid_len)
- return;
+ if (!config->ssid || ssid_len != config->ssid_len)
+ return -ENOENT;
if (memcmp(config->ssid, ssid, ssid_len) != 0)
- return;
+ return -ENOENT;
}
- if (config->ipv6_address == NULL) {
+ if (!config->ipv6_address) {
connman_network_set_ipv6_method(network,
CONNMAN_IPCONFIG_METHOD_AUTO);
} else if (g_ascii_strcasecmp(config->ipv6_address, "off") == 0) {
@@ -1081,15 +1135,14 @@ static void provision_service(gpointer key, gpointer value,
} else {
struct connman_ipaddress *address;
- if (config->ipv6_prefix_length == 0 ||
- config->ipv6_gateway == NULL) {
- DBG("IPv6 prefix or gateway missing");
- return;
+ if (config->ipv6_prefix_length == 0) {
+ DBG("IPv6 prefix missing");
+ return -EINVAL;
}
address = connman_ipaddress_alloc(AF_INET6);
- if (address == NULL)
- return;
+ if (!address)
+ return -ENOENT;
connman_ipaddress_set_ipv6(address, config->ipv6_address,
config->ipv6_prefix_length,
@@ -1105,16 +1158,16 @@ static void provision_service(gpointer key, gpointer value,
connman_ipaddress_free(address);
}
- if (config->ipv6_privacy != NULL) {
+ if (config->ipv6_privacy) {
struct connman_ipconfig *ipconfig;
ipconfig = __connman_service_get_ip6config(service);
- if (ipconfig != NULL)
+ if (ipconfig)
__connman_ipconfig_ipv6_set_privacy(ipconfig,
config->ipv6_privacy);
}
- if (config->ipv4_address == NULL) {
+ if (!config->ipv4_address) {
connman_network_set_ipv4_method(network,
CONNMAN_IPCONFIG_METHOD_DHCP);
} else if (g_ascii_strcasecmp(config->ipv4_address, "off") == 0) {
@@ -1127,15 +1180,14 @@ static void provision_service(gpointer key, gpointer value,
} else {
struct connman_ipaddress *address;
- if (config->ipv4_netmask == 0 ||
- config->ipv4_gateway == NULL) {
- DBG("IPv4 netmask or gateway missing");
- return;
+ if (!config->ipv4_netmask) {
+ DBG("IPv4 netmask missing");
+ return -EINVAL;
}
address = connman_ipaddress_alloc(AF_INET);
- if (address == NULL)
- return;
+ if (!address)
+ return -ENOENT;
connman_ipaddress_set_ipv4(address, config->ipv4_address,
config->ipv4_netmask,
@@ -1158,48 +1210,49 @@ static void provision_service(gpointer key, gpointer value,
g_slist_prepend(config->service_identifiers,
g_strdup(service_id));
- if (config->virtual == FALSE)
- __connman_service_set_immutable(service, TRUE);
+ if (!config->virtual)
+ __connman_service_set_immutable(service, true);
- __connman_service_set_favorite_delayed(service, TRUE, TRUE);
+ __connman_service_set_favorite_delayed(service, true, true);
__connman_service_set_config(service, config->config_ident,
config->config_entry);
- if (config->domain_name != NULL)
+ if (config->domain_name)
__connman_service_set_domainname(service, config->domain_name);
- if (config->nameservers != NULL) {
+ if (config->nameservers) {
int i;
__connman_service_nameserver_clear(service);
- for (i = 0; config->nameservers[i] != NULL; i++) {
+ for (i = 0; config->nameservers[i]; i++) {
__connman_service_nameserver_append(service,
- config->nameservers[i], FALSE);
+ config->nameservers[i], false);
}
}
- if (config->search_domains != NULL)
+ if (config->search_domains)
__connman_service_set_search_domains(service,
config->search_domains);
- if (config->timeservers != NULL)
+ if (config->timeservers)
__connman_service_set_timeservers(service,
config->timeservers);
if (g_strcmp0(config->type, "wifi") == 0 &&
type == CONNMAN_SERVICE_TYPE_WIFI) {
- provision_service_wifi(key, config, service, network,
+ provision_service_wifi(config, service, network,
ssid, ssid_len);
} else
- __connman_service_connect(service);
+ __connman_service_connect(service,
+ CONNMAN_SERVICE_CONNECT_REASON_AUTO);
__connman_service_mark_dirty();
- __connman_service_save(service);
+ __connman_service_load_modifiable(service);
- if (config->virtual == TRUE) {
+ if (config->virtual) {
struct connect_virtual *virtual;
virtual = g_malloc0(sizeof(struct connect_virtual));
@@ -1208,34 +1261,47 @@ static void provision_service(gpointer key, gpointer value,
g_timeout_add(0, remove_virtual_config, virtual);
} else
- __connman_service_auto_connect();
+ __connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO);
+
+ return 0;
+}
+
+static int find_and_provision_service(struct connman_service *service)
+{
+ GHashTableIter iter, iter_service;
+ gpointer value, key, value_service, key_service;
+
+ g_hash_table_iter_init(&iter, config_table);
+
+ while (g_hash_table_iter_next(&iter, &key, &value)) {
+ struct connman_config *config = value;
+
+ g_hash_table_iter_init(&iter_service, config->service_table);
+ while (g_hash_table_iter_next(&iter_service, &key_service,
+ &value_service)) {
+ if (!try_provision_service(value_service, service))
+ return 0;
+ }
+ }
+
+ return -ENOENT;
}
int __connman_config_provision_service(struct connman_service *service)
{
enum connman_service_type type;
- GHashTableIter iter;
- gpointer value, key;
- /* For now only WiFi and Ethernet services are supported */
+ /* For now only WiFi, Gadget and Ethernet services are supported */
type = connman_service_get_type(service);
DBG("service %p type %d", service, type);
if (type != CONNMAN_SERVICE_TYPE_WIFI &&
- type != CONNMAN_SERVICE_TYPE_ETHERNET)
+ type != CONNMAN_SERVICE_TYPE_ETHERNET &&
+ type != CONNMAN_SERVICE_TYPE_GADGET)
return -ENOSYS;
- g_hash_table_iter_init(&iter, config_table);
-
- while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
- struct connman_config *config = value;
-
- g_hash_table_foreach(config->service_table,
- provision_service, service);
- }
-
- return 0;
+ return find_and_provision_service(service);
}
int __connman_config_provision_service_ident(struct connman_service *service,
@@ -1245,20 +1311,21 @@ int __connman_config_provision_service_ident(struct connman_service *service,
struct connman_config *config;
int ret = 0;
- /* For now only WiFi and Ethernet services are supported */
+ /* For now only WiFi, Gadget and Ethernet services are supported */
type = connman_service_get_type(service);
DBG("service %p type %d", service, type);
if (type != CONNMAN_SERVICE_TYPE_WIFI &&
- type != CONNMAN_SERVICE_TYPE_ETHERNET)
+ type != CONNMAN_SERVICE_TYPE_ETHERNET &&
+ type != CONNMAN_SERVICE_TYPE_GADGET)
return -ENOSYS;
config = g_hash_table_lookup(config_table, ident);
- if (config != NULL) {
+ if (config) {
GHashTableIter iter;
gpointer value, key;
- gboolean found = FALSE;
+ bool found = false;
g_hash_table_iter_init(&iter, config->service_table);
@@ -1266,9 +1333,9 @@ int __connman_config_provision_service_ident(struct connman_service *service,
* Check if we need to remove individual service if it
* is missing from config file.
*/
- if (file != NULL && entry != NULL) {
+ if (file && entry) {
while (g_hash_table_iter_next(&iter, &key,
- &value) == TRUE) {
+ &value)) {
struct connman_config_service *config_service;
config_service = value;
@@ -1281,14 +1348,14 @@ int __connman_config_provision_service_ident(struct connman_service *service,
entry) != 0)
continue;
- found = TRUE;
+ found = true;
break;
}
DBG("found %d ident %s file %s entry %s", found, ident,
file, entry);
- if (found == FALSE) {
+ if (!found) {
/*
* The entry+8 will skip "service_" prefix
*/
@@ -1298,8 +1365,7 @@ int __connman_config_provision_service_ident(struct connman_service *service,
}
}
- g_hash_table_foreach(config->service_table,
- provision_service, service);
+ find_and_provision_service(service);
}
return ret;
@@ -1337,16 +1403,16 @@ int connman_config_provision_mutable_service(GKeyFile *keyfile)
vfile = g_strdup_printf("service_mutable_%s.config", rstr);
config = create_config(vfile);
- if (config == NULL)
+ if (!config)
return -ENOMEM;
- if (load_service_from_keyfile(keyfile, config) == FALSE)
+ if (!load_service_from_keyfile(keyfile, config))
goto error;
group = g_key_file_get_start_group(keyfile);
service_config = g_hash_table_lookup(config->service_table, group+8);
- if (service_config == NULL)
+ if (!service_config)
goto error;
/* Specific to non file based config: */
@@ -1355,7 +1421,7 @@ int connman_config_provision_mutable_service(GKeyFile *keyfile)
g_free(service_config->config_entry);
service_config->config_entry = NULL;
- service_config->virtual = TRUE;
+ service_config->virtual = true;
service_config->virtual_file = vfile;
__connman_service_provision_changed(vfile);
@@ -1381,35 +1447,35 @@ struct connman_config_entry **connman_config_get_entries(const char *type)
int i = 0, count;
g_hash_table_iter_init(&iter_file, config_table);
- while (g_hash_table_iter_next(&iter_file, &key, &value) == TRUE) {
+ while (g_hash_table_iter_next(&iter_file, &key, &value)) {
struct connman_config *config_file = value;
count = g_hash_table_size(config_file->service_table);
entries = g_try_realloc(entries, (i + count + 1) *
sizeof(struct connman_config_entry *));
- if (entries == NULL)
+ if (!entries)
return NULL;
g_hash_table_iter_init(&iter_config,
config_file->service_table);
while (g_hash_table_iter_next(&iter_config, &key,
- &value) == TRUE) {
+ &value)) {
struct connman_config_service *config = value;
- if (type != NULL &&
+ if (type &&
g_strcmp0(config->type, type) != 0)
continue;
entries[i] = g_try_new0(struct connman_config_entry,
1);
- if (entries[i] == NULL)
+ if (!entries[i])
goto cleanup;
entries[i]->ident = g_strdup(config->ident);
entries[i]->name = g_strdup(config->name);
entries[i]->ssid = g_try_malloc0(config->ssid_len + 1);
- if (entries[i]->ssid == NULL)
+ if (!entries[i]->ssid)
goto cleanup;
memcpy(entries[i]->ssid, config->ssid,
@@ -1421,10 +1487,10 @@ struct connman_config_entry **connman_config_get_entries(const char *type)
}
}
- if (entries != NULL) {
+ if (entries) {
entries = g_try_realloc(entries, (i + 1) *
sizeof(struct connman_config_entry *));
- if (entries == NULL)
+ if (!entries)
return NULL;
entries[i] = NULL;
@@ -1443,7 +1509,7 @@ void connman_config_free_entries(struct connman_config_entry **entries)
{
int i;
- if (entries == NULL)
+ if (!entries)
return;
for (i = 0; entries[i]; i++) {
@@ -1456,3 +1522,31 @@ void connman_config_free_entries(struct connman_config_entry **entries)
g_free(entries);
return;
}
+
+bool __connman_config_address_provisioned(const char *address,
+ const char *netmask)
+{
+ GHashTableIter iter, siter;
+ gpointer value, key, svalue, skey;
+
+ if (!address || !netmask)
+ return false;
+
+ g_hash_table_iter_init(&iter, config_table);
+
+ while (g_hash_table_iter_next(&iter, &key, &value)) {
+ struct connman_config *config = value;
+
+ g_hash_table_iter_init(&siter, config->service_table);
+ while (g_hash_table_iter_next(&siter, &skey, &svalue)) {
+ struct connman_config_service *service = svalue;
+
+ if (!g_strcmp0(address, service->ipv4_address) &&
+ !g_strcmp0(netmask,
+ service->ipv4_netmask))
+ return true;
+ }
+ }
+
+ return false;
+}
diff --git a/src/connection.c b/src/connection.c
index c7b1f620..e98ccb5c 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -2,8 +2,8 @@
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
- * Copyright (C) 2011 BMW Car IT GmbH. All rights reserved.
+ * Copyright (C) 2007-2013 Intel Corporation. All rights reserved.
+ * Copyright (C) 2011-2013 BMW Car IT GmbH. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -33,11 +33,11 @@
#include "connman.h"
struct gateway_config {
- gboolean active;
+ bool active;
char *gateway;
/* VPN extra data */
- gboolean vpn;
+ bool vpn;
char *vpn_ip;
int vpn_phy_index;
char *vpn_phy_ip;
@@ -49,7 +49,7 @@ struct gateway_data {
unsigned int order;
struct gateway_config *ipv4_gateway;
struct gateway_config *ipv6_gateway;
- connman_bool_t default_checked;
+ bool default_checked;
};
static GHashTable *gateway_hash = NULL;
@@ -59,22 +59,22 @@ static struct gateway_config *find_gateway(int index, const char *gateway)
GHashTableIter iter;
gpointer value, key;
- if (gateway == NULL)
+ if (!gateway)
return NULL;
g_hash_table_iter_init(&iter, gateway_hash);
- while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
+ while (g_hash_table_iter_next(&iter, &key, &value)) {
struct gateway_data *data = value;
- if (data->ipv4_gateway != NULL && data->index == index &&
+ if (data->ipv4_gateway && data->index == index &&
g_str_equal(data->ipv4_gateway->gateway,
- gateway) == TRUE)
+ gateway))
return data->ipv4_gateway;
- if (data->ipv6_gateway != NULL && data->index == index &&
+ if (data->ipv6_gateway && data->index == index &&
g_str_equal(data->ipv6_gateway->gateway,
- gateway) == TRUE)
+ gateway))
return data->ipv6_gateway;
}
@@ -86,19 +86,19 @@ static struct gateway_data *lookup_gateway_data(struct gateway_config *config)
GHashTableIter iter;
gpointer value, key;
- if (config == NULL)
+ if (!config)
return NULL;
g_hash_table_iter_init(&iter, gateway_hash);
- while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
+ while (g_hash_table_iter_next(&iter, &key, &value)) {
struct gateway_data *data = value;
- if (data->ipv4_gateway != NULL &&
+ if (data->ipv4_gateway &&
data->ipv4_gateway == config)
return data;
- if (data->ipv6_gateway != NULL &&
+ if (data->ipv6_gateway &&
data->ipv6_gateway == config)
return data;
}
@@ -111,22 +111,22 @@ static struct gateway_data *find_vpn_gateway(int index, const char *gateway)
GHashTableIter iter;
gpointer value, key;
- if (gateway == NULL)
+ if (!gateway)
return NULL;
g_hash_table_iter_init(&iter, gateway_hash);
- while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
+ while (g_hash_table_iter_next(&iter, &key, &value)) {
struct gateway_data *data = value;
- if (data->ipv4_gateway != NULL && data->index == index &&
+ if (data->ipv4_gateway && data->index == index &&
g_str_equal(data->ipv4_gateway->gateway,
- gateway) == TRUE)
+ gateway))
return data;
- if (data->ipv6_gateway != NULL && data->index == index &&
+ if (data->ipv6_gateway && data->index == index &&
g_str_equal(data->ipv6_gateway->gateway,
- gateway) == TRUE)
+ gateway))
return data;
}
@@ -152,7 +152,7 @@ static void get_gateway_cb(const char *gateway, int index, void *user_data)
params->vpn_index, params->vpn_gateway);
data = find_vpn_gateway(params->vpn_index, params->vpn_gateway);
- if (data == NULL) {
+ if (!data) {
DBG("Cannot find VPN link route, index %d addr %s",
params->vpn_index, params->vpn_gateway);
goto out;
@@ -199,18 +199,18 @@ static void set_vpn_routes(struct gateway_data *new_gateway,
} else
return;
- if (config != NULL) {
+ if (config) {
int index = __connman_ipconfig_get_index(ipconfig);
struct get_gateway_params *params;
- config->vpn = TRUE;
- if (peer != NULL)
+ config->vpn = true;
+ if (peer)
config->vpn_ip = g_strdup(peer);
- else if (gateway != NULL)
+ else if (gateway)
config->vpn_ip = g_strdup(gateway);
params = g_try_malloc(sizeof(struct get_gateway_params));
- if (params == NULL)
+ if (!params)
return;
params->vpn_index = index;
@@ -222,7 +222,7 @@ static void set_vpn_routes(struct gateway_data *new_gateway,
__connman_inet_get_route(gateway, get_gateway_cb, params);
}
- if (active_gateway == NULL)
+ if (!active_gateway)
return;
if (type == CONNMAN_IPCONFIG_TYPE_IPV4) {
@@ -232,7 +232,7 @@ static void set_vpn_routes(struct gateway_data *new_gateway,
* the VPN. The route might already exist depending
* on network topology.
*/
- if (active_gateway->ipv4_gateway == NULL)
+ if (!active_gateway->ipv4_gateway)
return;
DBG("active gw %s", active_gateway->ipv4_gateway->gateway);
@@ -248,7 +248,7 @@ static void set_vpn_routes(struct gateway_data *new_gateway,
} else if (type == CONNMAN_IPCONFIG_TYPE_IPV6) {
- if (active_gateway->ipv6_gateway == NULL)
+ if (!active_gateway->ipv6_gateway)
return;
DBG("active gw %s", active_gateway->ipv6_gateway->gateway);
@@ -268,17 +268,17 @@ static int del_routes(struct gateway_data *data,
enum connman_ipconfig_type type)
{
int status4 = 0, status6 = 0;
- int do_ipv4 = FALSE, do_ipv6 = FALSE;
+ bool do_ipv4 = false, do_ipv6 = false;
if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
- do_ipv4 = TRUE;
+ do_ipv4 = true;
else if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
- do_ipv6 = TRUE;
+ do_ipv6 = true;
else
- do_ipv4 = do_ipv6 = TRUE;
+ do_ipv4 = do_ipv6 = true;
- if (do_ipv4 == TRUE && data->ipv4_gateway != NULL) {
- if (data->ipv4_gateway->vpn == TRUE) {
+ if (do_ipv4 && data->ipv4_gateway) {
+ if (data->ipv4_gateway->vpn) {
status4 = connman_inet_clear_gateway_address(
data->index,
data->ipv4_gateway->vpn_ip);
@@ -296,8 +296,8 @@ static int del_routes(struct gateway_data *data,
}
}
- if (do_ipv6 == TRUE && data->ipv6_gateway != NULL) {
- if (data->ipv6_gateway->vpn == TRUE) {
+ if (do_ipv6 && data->ipv6_gateway) {
+ if (data->ipv6_gateway->vpn) {
status6 = connman_inet_clear_ipv6_gateway_address(
data->index,
data->ipv6_gateway->vpn_ip);
@@ -320,20 +320,20 @@ static int del_routes(struct gateway_data *data,
static int disable_gateway(struct gateway_data *data,
enum connman_ipconfig_type type)
{
- gboolean active = FALSE;
+ bool active = false;
if (type == CONNMAN_IPCONFIG_TYPE_IPV4) {
- if (data->ipv4_gateway != NULL)
+ if (data->ipv4_gateway)
active = data->ipv4_gateway->active;
} else if (type == CONNMAN_IPCONFIG_TYPE_IPV6) {
- if (data->ipv6_gateway != NULL)
+ if (data->ipv6_gateway)
active = data->ipv6_gateway->active;
} else
- active = TRUE;
+ active = true;
DBG("type %d active %d", type, active);
- if (active == TRUE)
+ if (active)
return del_routes(data, type);
return 0;
@@ -346,17 +346,17 @@ static struct gateway_data *add_gateway(struct connman_service *service,
struct gateway_data *data, *old;
struct gateway_config *config;
- if (gateway == NULL || strlen(gateway) == 0)
+ if (!gateway || strlen(gateway) == 0)
return NULL;
data = g_try_new0(struct gateway_data, 1);
- if (data == NULL)
+ if (!data)
return NULL;
data->index = index;
config = g_try_new0(struct gateway_config, 1);
- if (config == NULL) {
+ if (!config) {
g_free(data);
return NULL;
}
@@ -364,9 +364,9 @@ static struct gateway_data *add_gateway(struct connman_service *service,
config->gateway = g_strdup(gateway);
config->vpn_ip = NULL;
config->vpn_phy_ip = NULL;
- config->vpn = FALSE;
+ config->vpn = false;
config->vpn_phy_index = -1;
- config->active = FALSE;
+ config->active = false;
if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
data->ipv4_gateway = config;
@@ -390,7 +390,7 @@ static struct gateway_data *add_gateway(struct connman_service *service,
* from old gateway settings.
*/
old = g_hash_table_lookup(gateway_hash, service);
- if (old != NULL) {
+ if (old) {
DBG("Replacing gw %p ipv4 %p ipv6 %p", old,
old->ipv4_gateway, old->ipv6_gateway);
disable_gateway(old, type);
@@ -418,22 +418,22 @@ static void set_default_gateway(struct gateway_data *data,
{
int index;
int status4 = 0, status6 = 0;
- int do_ipv4 = FALSE, do_ipv6 = FALSE;
+ bool do_ipv4 = false, do_ipv6 = false;
if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
- do_ipv4 = TRUE;
+ do_ipv4 = true;
else if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
- do_ipv6 = TRUE;
+ do_ipv6 = true;
else
- do_ipv4 = do_ipv6 = TRUE;
+ do_ipv4 = do_ipv6 = true;
DBG("type %d gateway ipv4 %p ipv6 %p", type, data->ipv4_gateway,
data->ipv6_gateway);
- if (do_ipv4 == TRUE && data->ipv4_gateway != NULL &&
- data->ipv4_gateway->vpn == TRUE) {
+ if (do_ipv4 && data->ipv4_gateway &&
+ data->ipv4_gateway->vpn) {
connman_inet_set_gateway_interface(data->index);
- data->ipv4_gateway->active = TRUE;
+ data->ipv4_gateway->active = true;
DBG("set %p index %d vpn %s index %d phy %s",
data, data->index, data->ipv4_gateway->vpn_ip,
@@ -445,10 +445,10 @@ static void set_default_gateway(struct gateway_data *data,
return;
}
- if (do_ipv6 == TRUE && data->ipv6_gateway != NULL &&
- data->ipv6_gateway->vpn == TRUE) {
+ if (do_ipv6 && data->ipv6_gateway &&
+ data->ipv6_gateway->vpn) {
connman_inet_set_ipv6_gateway_interface(data->index);
- data->ipv6_gateway->active = TRUE;
+ data->ipv6_gateway->active = true;
DBG("set %p index %d vpn %s index %d phy %s",
data, data->index, data->ipv6_gateway->vpn_ip,
@@ -462,7 +462,7 @@ static void set_default_gateway(struct gateway_data *data,
index = __connman_service_get_index(data->service);
- if (do_ipv4 == TRUE && data->ipv4_gateway != NULL &&
+ if (do_ipv4 && data->ipv4_gateway &&
g_strcmp0(data->ipv4_gateway->gateway,
"0.0.0.0") == 0) {
if (connman_inet_set_gateway_interface(index) < 0)
@@ -470,7 +470,7 @@ static void set_default_gateway(struct gateway_data *data,
goto done;
}
- if (do_ipv6 == TRUE && data->ipv6_gateway != NULL &&
+ if (do_ipv6 && data->ipv6_gateway &&
g_strcmp0(data->ipv6_gateway->gateway,
"::") == 0) {
if (connman_inet_set_ipv6_gateway_interface(index) < 0)
@@ -478,13 +478,13 @@ static void set_default_gateway(struct gateway_data *data,
goto done;
}
- if (do_ipv6 == TRUE && data->ipv6_gateway != NULL)
- status6 = connman_inet_set_ipv6_gateway_address(index,
- data->ipv6_gateway->gateway);
+ if (do_ipv6 && data->ipv6_gateway)
+ status6 = __connman_inet_add_default_to_table(RT_TABLE_MAIN,
+ index, data->ipv6_gateway->gateway);
- if (do_ipv4 == TRUE && data->ipv4_gateway != NULL)
- status4 = connman_inet_set_gateway_address(index,
- data->ipv4_gateway->gateway);
+ if (do_ipv4 && data->ipv4_gateway)
+ status4 = __connman_inet_add_default_to_table(RT_TABLE_MAIN,
+ index, data->ipv4_gateway->gateway);
if (status4 < 0 || status6 < 0)
return;
@@ -497,22 +497,22 @@ static void unset_default_gateway(struct gateway_data *data,
enum connman_ipconfig_type type)
{
int index;
- int do_ipv4 = FALSE, do_ipv6 = FALSE;
+ bool do_ipv4 = false, do_ipv6 = false;
if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
- do_ipv4 = TRUE;
+ do_ipv4 = true;
else if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
- do_ipv6 = TRUE;
+ do_ipv6 = true;
else
- do_ipv4 = do_ipv6 = TRUE;
+ do_ipv4 = do_ipv6 = true;
DBG("type %d gateway ipv4 %p ipv6 %p", type, data->ipv4_gateway,
data->ipv6_gateway);
- if (do_ipv4 == TRUE && data->ipv4_gateway != NULL &&
- data->ipv4_gateway->vpn == TRUE) {
+ if (do_ipv4 && data->ipv4_gateway &&
+ data->ipv4_gateway->vpn) {
connman_inet_clear_gateway_interface(data->index);
- data->ipv4_gateway->active = FALSE;
+ data->ipv4_gateway->active = false;
DBG("unset %p index %d vpn %s index %d phy %s",
data, data->index, data->ipv4_gateway->vpn_ip,
@@ -522,10 +522,10 @@ static void unset_default_gateway(struct gateway_data *data,
return;
}
- if (do_ipv6 == TRUE && data->ipv6_gateway != NULL &&
- data->ipv6_gateway->vpn == TRUE) {
+ if (do_ipv6 && data->ipv6_gateway &&
+ data->ipv6_gateway->vpn) {
connman_inet_clear_ipv6_gateway_interface(data->index);
- data->ipv6_gateway->active = FALSE;
+ data->ipv6_gateway->active = false;
DBG("unset %p index %d vpn %s index %d phy %s",
data, data->index, data->ipv6_gateway->vpn_ip,
@@ -537,25 +537,25 @@ static void unset_default_gateway(struct gateway_data *data,
index = __connman_service_get_index(data->service);
- if (do_ipv4 == TRUE && data->ipv4_gateway != NULL &&
+ if (do_ipv4 && data->ipv4_gateway &&
g_strcmp0(data->ipv4_gateway->gateway,
"0.0.0.0") == 0) {
connman_inet_clear_gateway_interface(index);
return;
}
- if (do_ipv6 == TRUE && data->ipv6_gateway != NULL &&
+ if (do_ipv6 && data->ipv6_gateway &&
g_strcmp0(data->ipv6_gateway->gateway,
"::") == 0) {
connman_inet_clear_ipv6_gateway_interface(index);
return;
}
- if (do_ipv6 == TRUE && data->ipv6_gateway != NULL)
+ if (do_ipv6 && data->ipv6_gateway)
connman_inet_clear_ipv6_gateway_address(index,
data->ipv6_gateway->gateway);
- if (do_ipv4 == TRUE && data->ipv4_gateway != NULL)
+ if (do_ipv4 && data->ipv4_gateway)
connman_inet_clear_gateway_address(index,
data->ipv4_gateway->gateway);
}
@@ -569,10 +569,10 @@ static struct gateway_data *find_default_gateway(void)
g_hash_table_iter_init(&iter, gateway_hash);
- while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
+ while (g_hash_table_iter_next(&iter, &key, &value)) {
struct gateway_data *data = value;
- if (found == NULL || data->order > order) {
+ if (!found || data->order > order) {
found = data;
order = data->order;
@@ -583,48 +583,48 @@ static struct gateway_data *find_default_gateway(void)
return found;
}
-static gboolean choose_default_gateway(struct gateway_data *data,
+static bool choose_default_gateway(struct gateway_data *data,
struct gateway_data *candidate)
{
- gboolean downgraded = FALSE;
+ bool downgraded = false;
/*
* If the current default is not active, then we mark
* this one as default. If the other one is already active
* we mark this one as non default.
*/
- if (data->ipv4_gateway != NULL) {
- if (candidate->ipv4_gateway != NULL &&
- candidate->ipv4_gateway->active == FALSE) {
+ if (data->ipv4_gateway) {
+ if (candidate->ipv4_gateway &&
+ !candidate->ipv4_gateway->active) {
DBG("ipv4 downgrading %p", candidate);
unset_default_gateway(candidate,
CONNMAN_IPCONFIG_TYPE_IPV4);
}
- if (candidate->ipv4_gateway != NULL &&
- candidate->ipv4_gateway->active == TRUE &&
+ if (candidate->ipv4_gateway &&
+ candidate->ipv4_gateway->active &&
candidate->order > data->order) {
DBG("ipv4 downgrading this %p", data);
unset_default_gateway(data,
CONNMAN_IPCONFIG_TYPE_IPV4);
- downgraded = TRUE;
+ downgraded = true;
}
}
- if (data->ipv6_gateway != NULL) {
- if (candidate->ipv6_gateway != NULL &&
- candidate->ipv6_gateway->active == FALSE) {
+ if (data->ipv6_gateway) {
+ if (candidate->ipv6_gateway &&
+ !candidate->ipv6_gateway->active) {
DBG("ipv6 downgrading %p", candidate);
unset_default_gateway(candidate,
CONNMAN_IPCONFIG_TYPE_IPV6);
}
- if (candidate->ipv6_gateway != NULL &&
- candidate->ipv6_gateway->active == TRUE &&
+ if (candidate->ipv6_gateway &&
+ candidate->ipv6_gateway->active &&
candidate->order > data->order) {
DBG("ipv6 downgrading this %p", data);
unset_default_gateway(data,
CONNMAN_IPCONFIG_TYPE_IPV6);
- downgraded = TRUE;
+ downgraded = true;
}
}
@@ -637,15 +637,15 @@ static void connection_newgateway(int index, const char *gateway)
struct gateway_data *data;
GHashTableIter iter;
gpointer value, key;
- gboolean found = FALSE;
+ bool found = false;
DBG("index %d gateway %s", index, gateway);
config = find_gateway(index, gateway);
- if (config == NULL)
+ if (!config)
return;
- config->active = TRUE;
+ config->active = true;
/*
* It is possible that we have two default routes atm
@@ -653,10 +653,10 @@ static void connection_newgateway(int index, const char *gateway)
* same time.
*/
data = lookup_gateway_data(config);
- if (data == NULL)
+ if (!data)
return;
- if (data->default_checked == TRUE)
+ if (data->default_checked)
return;
/*
@@ -666,26 +666,26 @@ static void connection_newgateway(int index, const char *gateway)
g_hash_table_iter_init(&iter, gateway_hash);
- while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
+ while (g_hash_table_iter_next(&iter, &key, &value)) {
struct gateway_data *candidate = value;
if (candidate == data)
continue;
found = choose_default_gateway(data, candidate);
- if (found == TRUE)
+ if (found)
break;
}
- if (found == FALSE) {
- if (data->ipv4_gateway != NULL)
+ if (!found) {
+ if (data->ipv4_gateway)
set_default_gateway(data, CONNMAN_IPCONFIG_TYPE_IPV4);
- if (data->ipv6_gateway != NULL)
+ if (data->ipv6_gateway)
set_default_gateway(data, CONNMAN_IPCONFIG_TYPE_IPV6);
}
- data->default_checked = TRUE;
+ data->default_checked = true;
}
static void remove_gateway(gpointer user_data)
@@ -694,14 +694,14 @@ static void remove_gateway(gpointer user_data)
DBG("gateway ipv4 %p ipv6 %p", data->ipv4_gateway, data->ipv6_gateway);
- if (data->ipv4_gateway != NULL) {
+ if (data->ipv4_gateway) {
g_free(data->ipv4_gateway->gateway);
g_free(data->ipv4_gateway->vpn_ip);
g_free(data->ipv4_gateway->vpn_phy_ip);
g_free(data->ipv4_gateway);
}
- if (data->ipv6_gateway != NULL) {
+ if (data->ipv6_gateway) {
g_free(data->ipv6_gateway->gateway);
g_free(data->ipv6_gateway->vpn_ip);
g_free(data->ipv6_gateway->vpn_phy_ip);
@@ -719,11 +719,11 @@ static void connection_delgateway(int index, const char *gateway)
DBG("index %d gateway %s", index, gateway);
config = find_gateway(index, gateway);
- if (config != NULL)
- config->active = FALSE;
+ if (config)
+ config->active = false;
data = find_default_gateway();
- if (data != NULL)
+ if (data)
set_default_gateway(data, CONNMAN_IPCONFIG_TYPE_ALL);
}
@@ -742,15 +742,15 @@ static struct gateway_data *find_active_gateway(void)
g_hash_table_iter_init(&iter, gateway_hash);
- while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
+ while (g_hash_table_iter_next(&iter, &key, &value)) {
struct gateway_data *data = value;
- if (data->ipv4_gateway != NULL &&
- data->ipv4_gateway->active == TRUE)
+ if (data->ipv4_gateway &&
+ data->ipv4_gateway->active)
return data;
- if (data->ipv6_gateway != NULL &&
- data->ipv6_gateway->active == TRUE)
+ if (data->ipv6_gateway &&
+ data->ipv6_gateway->active)
return data;
}
@@ -766,7 +766,7 @@ static void update_order(void)
g_hash_table_iter_init(&iter, gateway_hash);
- while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
+ while (g_hash_table_iter_next(&iter, &key, &value)) {
struct gateway_data *data = value;
data->order = __connman_service_get_order(data->service);
@@ -779,16 +779,16 @@ void __connman_connection_gateway_activate(struct connman_service *service,
struct gateway_data *data = NULL;
data = g_hash_table_lookup(gateway_hash, service);
- if (data == NULL)
+ if (!data)
return;
DBG("gateway %p/%p type %d", data->ipv4_gateway,
data->ipv6_gateway, type);
if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
- data->ipv4_gateway->active = TRUE;
+ data->ipv4_gateway->active = true;
else if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
- data->ipv6_gateway->active = TRUE;
+ data->ipv6_gateway->active = true;
}
static void add_host_route(int family, int index, const char *gateway,
@@ -859,17 +859,17 @@ int __connman_connection_gateway_add(struct connman_service *service,
* gateway for ipv4 is 0.0.0.0 and for ipv6 is ::, meaning the
* interface
*/
- if (gateway == NULL && type == CONNMAN_IPCONFIG_TYPE_IPV4)
+ if (!gateway && type == CONNMAN_IPCONFIG_TYPE_IPV4)
gateway = "0.0.0.0";
- if (gateway == NULL && type == CONNMAN_IPCONFIG_TYPE_IPV6)
+ if (!gateway && type == CONNMAN_IPCONFIG_TYPE_IPV6)
gateway = "::";
DBG("service %p index %d gateway %s vpn ip %s type %d",
service, index, gateway, peer, type);
new_gateway = add_gateway(service, index, gateway, type);
- if (new_gateway == NULL)
+ if (!new_gateway)
return -EINVAL;
active_gateway = find_active_gateway();
@@ -878,7 +878,7 @@ int __connman_connection_gateway_add(struct connman_service *service,
active_gateway ? active_gateway->index : -1, new_gateway);
if (type == CONNMAN_IPCONFIG_TYPE_IPV4 &&
- new_gateway->ipv4_gateway != NULL) {
+ new_gateway->ipv4_gateway) {
add_host_route(AF_INET, index, gateway, service_type);
__connman_service_nameserver_add_routes(service,
new_gateway->ipv4_gateway->gateway);
@@ -886,7 +886,7 @@ int __connman_connection_gateway_add(struct connman_service *service,
}
if (type == CONNMAN_IPCONFIG_TYPE_IPV6 &&
- new_gateway->ipv6_gateway != NULL) {
+ new_gateway->ipv6_gateway) {
add_host_route(AF_INET6, index, gateway, service_type);
__connman_service_nameserver_add_routes(service,
new_gateway->ipv6_gateway->gateway);
@@ -900,34 +900,32 @@ int __connman_connection_gateway_add(struct connman_service *service,
} else {
if (type == CONNMAN_IPCONFIG_TYPE_IPV4 &&
- new_gateway->ipv4_gateway != NULL)
- new_gateway->ipv4_gateway->vpn = FALSE;
+ new_gateway->ipv4_gateway)
+ new_gateway->ipv4_gateway->vpn = false;
if (type == CONNMAN_IPCONFIG_TYPE_IPV6 &&
- new_gateway->ipv6_gateway != NULL)
- new_gateway->ipv6_gateway->vpn = FALSE;
+ new_gateway->ipv6_gateway)
+ new_gateway->ipv6_gateway->vpn = false;
}
- if (active_gateway == NULL) {
+ if (!active_gateway) {
set_default_gateway(new_gateway, type);
goto done;
}
if (type == CONNMAN_IPCONFIG_TYPE_IPV4 &&
- new_gateway->ipv4_gateway != NULL &&
- new_gateway->ipv4_gateway->vpn == TRUE) {
- if (__connman_service_is_split_routing(new_gateway->service) ==
- FALSE)
+ new_gateway->ipv4_gateway &&
+ new_gateway->ipv4_gateway->vpn) {
+ if (!__connman_service_is_split_routing(new_gateway->service))
connman_inet_clear_gateway_address(
active_gateway->index,
active_gateway->ipv4_gateway->gateway);
}
if (type == CONNMAN_IPCONFIG_TYPE_IPV6 &&
- new_gateway->ipv6_gateway != NULL &&
- new_gateway->ipv6_gateway->vpn == TRUE) {
- if (__connman_service_is_split_routing(new_gateway->service) ==
- FALSE)
+ new_gateway->ipv6_gateway &&
+ new_gateway->ipv6_gateway->vpn) {
+ if (!__connman_service_is_split_routing(new_gateway->service))
connman_inet_clear_ipv6_gateway_address(
active_gateway->index,
active_gateway->ipv6_gateway->gateway);
@@ -950,29 +948,29 @@ void __connman_connection_gateway_remove(struct connman_service *service,
enum connman_ipconfig_type type)
{
struct gateway_data *data = NULL;
- gboolean set_default4 = FALSE, set_default6 = FALSE;
- int do_ipv4 = FALSE, do_ipv6 = FALSE;
+ bool set_default4 = false, set_default6 = false;
+ bool do_ipv4 = false, do_ipv6 = false;
int err;
DBG("service %p type %d", service, type);
if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
- do_ipv4 = TRUE;
+ do_ipv4 = true;
else if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
- do_ipv6 = TRUE;
+ do_ipv6 = true;
else
- do_ipv4 = do_ipv6 = TRUE;
+ do_ipv4 = do_ipv6 = true;
__connman_service_nameserver_del_routes(service, type);
data = g_hash_table_lookup(gateway_hash, service);
- if (data == NULL)
+ if (!data)
return;
- if (do_ipv4 == TRUE && data->ipv4_gateway != NULL)
+ if (do_ipv4 && data->ipv4_gateway)
set_default4 = data->ipv4_gateway->vpn;
- if (do_ipv6 == TRUE && data->ipv6_gateway != NULL)
+ if (do_ipv6 && data->ipv6_gateway)
set_default6 = data->ipv6_gateway->vpn;
DBG("ipv4 gateway %s ipv6 gateway %s vpn %d/%d",
@@ -980,14 +978,15 @@ void __connman_connection_gateway_remove(struct connman_service *service,
data->ipv6_gateway ? data->ipv6_gateway->gateway : "<null>",
set_default4, set_default6);
- if (do_ipv4 == TRUE && data->ipv4_gateway != NULL &&
- data->ipv4_gateway->vpn == TRUE && data->index >= 0)
- connman_inet_del_host_route(data->index,
+ if (do_ipv4 && data->ipv4_gateway &&
+ data->ipv4_gateway->vpn && data->index >= 0)
+ connman_inet_del_host_route(data->ipv4_gateway->vpn_phy_index,
data->ipv4_gateway->gateway);
- if (do_ipv6 == TRUE && data->ipv6_gateway != NULL &&
- data->ipv6_gateway->vpn == TRUE && data->index >= 0)
- connman_inet_del_ipv6_host_route(data->index,
+ if (do_ipv6 && data->ipv6_gateway &&
+ data->ipv6_gateway->vpn && data->index >= 0)
+ connman_inet_del_ipv6_host_route(
+ data->ipv6_gateway->vpn_phy_index,
data->ipv6_gateway->gateway);
err = disable_gateway(data, type);
@@ -997,10 +996,10 @@ void __connman_connection_gateway_remove(struct connman_service *service,
* settings are to be removed.
*/
if (do_ipv4 == do_ipv6 ||
- (data->ipv4_gateway != NULL && data->ipv6_gateway == NULL
- && do_ipv4 == TRUE) ||
- (data->ipv6_gateway != NULL && data->ipv4_gateway == NULL
- && do_ipv6 == TRUE)
+ (data->ipv4_gateway && !data->ipv6_gateway
+ && do_ipv4) ||
+ (data->ipv6_gateway && !data->ipv4_gateway
+ && do_ipv6)
) {
connman_service_unref(service);
g_hash_table_remove(gateway_hash, service);
@@ -1016,19 +1015,19 @@ void __connman_connection_gateway_remove(struct connman_service *service,
*/
if (set_default4 || set_default6 || err < 0) {
data = find_default_gateway();
- if (data != NULL)
+ if (data)
set_default_gateway(data, type);
}
}
-gboolean __connman_connection_update_gateway(void)
+bool __connman_connection_update_gateway(void)
{
struct gateway_data *default_gateway;
- gboolean updated = FALSE;
+ bool updated = false;
GHashTableIter iter;
gpointer value, key;
- if (gateway_hash == NULL)
+ if (!gateway_hash)
return updated;
update_order();
@@ -1045,30 +1044,30 @@ gboolean __connman_connection_update_gateway(void)
*/
g_hash_table_iter_init(&iter, gateway_hash);
- while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
+ while (g_hash_table_iter_next(&iter, &key, &value)) {
struct gateway_data *active_gateway = value;
if (active_gateway == default_gateway)
continue;
- if (active_gateway->ipv4_gateway != NULL &&
- active_gateway->ipv4_gateway->active == TRUE) {
+ if (active_gateway->ipv4_gateway &&
+ active_gateway->ipv4_gateway->active) {
unset_default_gateway(active_gateway,
CONNMAN_IPCONFIG_TYPE_IPV4);
- updated = TRUE;
+ updated = true;
}
- if (active_gateway->ipv6_gateway != NULL &&
- active_gateway->ipv6_gateway->active == TRUE) {
+ if (active_gateway->ipv6_gateway &&
+ active_gateway->ipv6_gateway->active) {
unset_default_gateway(active_gateway,
CONNMAN_IPCONFIG_TYPE_IPV6);
- updated = TRUE;
+ updated = true;
}
}
- if (updated && default_gateway != NULL) {
+ if (updated && default_gateway) {
if (default_gateway->ipv4_gateway)
set_default_gateway(default_gateway,
CONNMAN_IPCONFIG_TYPE_IPV4);
@@ -1088,14 +1087,14 @@ int __connman_connection_get_vpn_index(int phy_index)
g_hash_table_iter_init(&iter, gateway_hash);
- while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
+ while (g_hash_table_iter_next(&iter, &key, &value)) {
struct gateway_data *data = value;
- if (data->ipv4_gateway != NULL &&
+ if (data->ipv4_gateway &&
data->ipv4_gateway->vpn_phy_index == phy_index)
return data->index;
- if (data->ipv6_gateway != NULL &&
+ if (data->ipv6_gateway &&
data->ipv6_gateway->vpn_phy_index == phy_index)
return data->index;
}
@@ -1130,7 +1129,7 @@ void __connman_connection_cleanup(void)
g_hash_table_iter_init(&iter, gateway_hash);
- while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
+ while (g_hash_table_iter_next(&iter, &key, &value)) {
struct gateway_data *data = value;
disable_gateway(data, CONNMAN_IPCONFIG_TYPE_ALL);
diff --git a/src/connman.h b/src/connman.h
index 75f136fb..24db5f8d 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -2,7 +2,7 @@
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2014 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -19,6 +19,8 @@
*
*/
+#include <stdbool.h>
+
#include <glib.h>
#define CONNMAN_API_SUBJECT_TO_CHANGE
@@ -26,7 +28,9 @@
#include <connman/dbus.h>
dbus_bool_t __connman_dbus_append_objpath_dict_array(DBusMessage *msg,
- connman_dbus_append_cb_t function, void *user_data);
+ connman_dbus_append_cb_t function, void *user_data);
+dbus_bool_t __connman_dbus_append_objpath_array(DBusMessage *msg,
+ connman_dbus_append_cb_t function, void *user_data);
int __connman_dbus_init(DBusConnection *conn);
void __connman_dbus_cleanup(void);
@@ -51,8 +55,6 @@ DBusMessage *__connman_error_operation_timeout(DBusMessage *msg);
DBusMessage *__connman_error_invalid_service(DBusMessage *msg);
DBusMessage *__connman_error_invalid_property(DBusMessage *msg);
-#include <connman/types.h>
-
int __connman_manager_init(void);
void __connman_manager_cleanup(void);
@@ -93,16 +95,17 @@ void __connman_agent_cancel(struct connman_service *service);
int __connman_service_add_passphrase(struct connman_service *service,
const gchar *passphrase);
typedef void (* authentication_cb_t) (struct connman_service *service,
- connman_bool_t values_received,
+ bool values_received,
const char *name, int name_len,
const char *identifier, const char *secret,
- gboolean wps, const char *wpspin,
+ bool wps, const char *wpspin,
const char *error, void *user_data);
typedef void (* browser_authentication_cb_t) (struct connman_service *service,
- connman_bool_t authentication_done,
+ bool authentication_done,
const char *error, void *user_data);
int __connman_agent_request_passphrase_input(struct connman_service *service,
- authentication_cb_t callback, void *user_data);
+ authentication_cb_t callback,
+ const char *dbus_sender, void *user_data);
int __connman_agent_request_login_input(struct connman_service *service,
authentication_cb_t callback, void *user_data);
int __connman_agent_request_browser(struct connman_service *service,
@@ -112,9 +115,9 @@ int __connman_agent_request_browser(struct connman_service *service,
#include <connman/log.h>
int __connman_log_init(const char *program, const char *debug,
- connman_bool_t detach, connman_bool_t backtrace,
+ gboolean detach, gboolean backtrace,
const char *program_name, const char *program_version);
-void __connman_log_cleanup(connman_bool_t backtrace);
+void __connman_log_cleanup(gboolean backtrace);
void __connman_log_enable(struct connman_debug_desc *start,
struct connman_debug_desc *stop);
@@ -141,6 +144,7 @@ int __connman_inet_modify_address(int cmd, int flags, int index, int family,
unsigned char prefixlen,
const char *broadcast);
int __connman_inet_get_interface_address(int index, int family, void *address);
+int __connman_inet_get_interface_ll_address(int index, int family, void *address);
#include <netinet/ip6.h>
#include <netinet/icmp6.h>
@@ -150,8 +154,25 @@ typedef void (*__connman_inet_rs_cb_t) (struct nd_router_advert *reply,
int __connman_inet_ipv6_send_rs(int index, int timeout,
__connman_inet_rs_cb_t callback, void *user_data);
+int __connman_inet_ipv6_send_ra(int index, struct in6_addr *src_addr,
+ GSList *prefixes, int router_lifetime);
-int __connman_refresh_rs_ipv6(struct connman_network *network, int index);
+typedef void (*__connman_inet_ns_cb_t) (struct nd_neighbor_advert *reply,
+ unsigned int length,
+ struct in6_addr *addr,
+ void *user_data);
+int __connman_inet_ipv6_do_dad(int index, int timeout_ms,
+ struct in6_addr *addr,
+ __connman_inet_ns_cb_t callback, void *user_data);
+
+typedef void (*__connman_inet_recv_rs_cb_t) (struct nd_router_solicit *reply,
+ unsigned int length, void *user_data);
+int __connman_inet_ipv6_start_recv_rs(int index,
+ __connman_inet_recv_rs_cb_t callback,
+ void *user_data, void **context);
+void __connman_inet_ipv6_stop_recv_rs(void *context);
+
+int __connman_network_refresh_rs_ipv6(struct connman_network *network, int index);
GSList *__connman_inet_ipv6_get_prefixes(struct nd_router_advert *hdr,
unsigned int length);
@@ -200,9 +221,16 @@ int __connman_inet_rtnl_addattr_l(struct nlmsghdr *n, size_t max_length,
int __connman_inet_rtnl_addattr32(struct nlmsghdr *n, size_t maxlen,
int type, __u32 data);
+int __connman_inet_add_fwmark_rule(uint32_t table_id, int family, uint32_t fwmark);
+int __connman_inet_del_fwmark_rule(uint32_t table_id, int family, uint32_t fwmark);
+int __connman_inet_add_default_to_table(uint32_t table_id, int ifindex, const char *gateway);
+int __connman_inet_del_default_from_table(uint32_t table_id, int ifindex, const char *gateway);
+int __connman_inet_get_address_netmask(int ifindex,
+ struct sockaddr_in *address, struct sockaddr_in *netmask);
+
#include <connman/resolver.h>
-int __connman_resolver_init(connman_bool_t dnsproxy);
+int __connman_resolver_init(gboolean dnsproxy);
void __connman_resolver_cleanup(void);
int __connman_resolvfile_append(int index, const char *domain, const char *server);
int __connman_resolvfile_remove(int index, const char *domain, const char *server);
@@ -220,9 +248,9 @@ GKeyFile *__connman_storage_open_service(const char *ident);
int __connman_storage_save_service(GKeyFile *keyfile, const char *ident);
GKeyFile *__connman_storage_load_provider(const char *identifier);
void __connman_storage_save_provider(GKeyFile *keyfile, const char *identifier);
-gboolean __connman_storage_remove_provider(const char *identifier);
+bool __connman_storage_remove_provider(const char *identifier);
char **__connman_storage_get_providers(void);
-gboolean __connman_storage_remove_service(const char *service_id);
+bool __connman_storage_remove_service(const char *service_id);
int __connman_detect_init(void);
void __connman_detect_cleanup(void);
@@ -249,14 +277,14 @@ struct connman_ipaddress {
};
struct connman_ipconfig_ops {
- void (*up) (struct connman_ipconfig *ipconfig);
- void (*down) (struct connman_ipconfig *ipconfig);
- void (*lower_up) (struct connman_ipconfig *ipconfig);
- void (*lower_down) (struct connman_ipconfig *ipconfig);
- void (*ip_bound) (struct connman_ipconfig *ipconfig);
- void (*ip_release) (struct connman_ipconfig *ipconfig);
- void (*route_set) (struct connman_ipconfig *ipconfig);
- void (*route_unset) (struct connman_ipconfig *ipconfig);
+ void (*up) (struct connman_ipconfig *ipconfig, const char *ifname);
+ void (*down) (struct connman_ipconfig *ipconfig, const char *ifname);
+ void (*lower_up) (struct connman_ipconfig *ipconfig, const char *ifname);
+ void (*lower_down) (struct connman_ipconfig *ipconfig, const char *ifname);
+ void (*ip_bound) (struct connman_ipconfig *ipconfig, const char *ifname);
+ void (*ip_release) (struct connman_ipconfig *ipconfig, const char *ifname);
+ void (*route_set) (struct connman_ipconfig *ipconfig, const char *ifname);
+ void (*route_unset) (struct connman_ipconfig *ipconfig, const char *ifname);
};
struct connman_ipconfig *__connman_ipconfig_create(int index,
@@ -278,7 +306,6 @@ void *__connman_ipconfig_get_data(struct connman_ipconfig *ipconfig);
void __connman_ipconfig_set_data(struct connman_ipconfig *ipconfig, void *data);
int __connman_ipconfig_get_index(struct connman_ipconfig *ipconfig);
-const char *__connman_ipconfig_get_ifname(struct connman_ipconfig *ipconfig);
void __connman_ipconfig_set_ops(struct connman_ipconfig *ipconfig,
const struct connman_ipconfig_ops *ops);
@@ -329,7 +356,7 @@ void __connman_ipconfig_set_prefixlen(struct connman_ipconfig *ipconfig, unsigne
int __connman_ipconfig_enable(struct connman_ipconfig *ipconfig);
int __connman_ipconfig_disable(struct connman_ipconfig *ipconfig);
-connman_bool_t __connman_ipconfig_is_usable(struct connman_ipconfig *ipconfig);
+bool __connman_ipconfig_is_usable(struct connman_ipconfig *ipconfig);
const char *__connman_ipconfig_method2string(enum connman_ipconfig_method method);
const char *__connman_ipconfig_type2string(enum connman_ipconfig_type type);
@@ -364,14 +391,18 @@ const char *__connman_ipconfig_get_proxy_autoconfig(struct connman_ipconfig *ipc
void __connman_ipconfig_set_dhcp_address(struct connman_ipconfig *ipconfig,
const char *address);
char *__connman_ipconfig_get_dhcp_address(struct connman_ipconfig *ipconfig);
+void __connman_ipconfig_set_dhcpv6_prefixes(struct connman_ipconfig *ipconfig,
+ char **prefixes);
+char **__connman_ipconfig_get_dhcpv6_prefixes(struct connman_ipconfig *ipconfig);
int __connman_ipconfig_load(struct connman_ipconfig *ipconfig,
GKeyFile *keyfile, const char *identifier, const char *prefix);
int __connman_ipconfig_save(struct connman_ipconfig *ipconfig,
GKeyFile *keyfile, const char *identifier, const char *prefix);
-gboolean __connman_ipconfig_ipv6_privacy_enabled(struct connman_ipconfig *ipconfig);
+bool __connman_ipconfig_ipv6_privacy_enabled(struct connman_ipconfig *ipconfig);
int __connman_ipconfig_ipv6_set_privacy(struct connman_ipconfig *ipconfig,
const char *value);
+bool __connman_ipconfig_ipv6_is_enabled(struct connman_ipconfig *ipconfig);
int __connman_ipconfig_set_rp_filter();
void __connman_ipconfig_unset_rp_filter(int old_value);
@@ -394,8 +425,17 @@ GSList *__connman_timeserver_get_all(struct connman_service *service);
int __connman_timeserver_sync(struct connman_service *service);
void __connman_timeserver_sync_next();
+enum __connman_dhcpv6_status {
+ CONNMAN_DHCPV6_STATUS_FAIL = 0,
+ CONNMAN_DHCPV6_STATUS_SUCCEED = 1,
+ CONNMAN_DHCPV6_STATUS_RESTART = 2,
+};
+
+typedef void (* dhcpv6_cb) (struct connman_network *network,
+ enum __connman_dhcpv6_status status, gpointer data);
+
typedef void (* dhcp_cb) (struct connman_network *network,
- connman_bool_t success);
+ bool success, gpointer data);
int __connman_dhcp_start(struct connman_network *network, dhcp_cb callback);
void __connman_dhcp_stop(struct connman_network *network);
int __connman_dhcp_init(void);
@@ -403,14 +443,20 @@ void __connman_dhcp_cleanup(void);
int __connman_dhcpv6_init(void);
void __connman_dhcpv6_cleanup(void);
int __connman_dhcpv6_start_info(struct connman_network *network,
- dhcp_cb callback);
+ dhcpv6_cb callback);
void __connman_dhcpv6_stop(struct connman_network *network);
int __connman_dhcpv6_start(struct connman_network *network,
- GSList *prefixes, dhcp_cb callback);
+ GSList *prefixes, dhcpv6_cb callback);
int __connman_dhcpv6_start_renew(struct connman_network *network,
- dhcp_cb callback);
+ dhcpv6_cb callback);
int __connman_dhcpv6_start_release(struct connman_network *network,
- dhcp_cb callback);
+ dhcpv6_cb callback);
+int __connman_dhcpv6_start_pd(int index, GSList *prefixes, dhcpv6_cb callback);
+void __connman_dhcpv6_stop_pd(int index);
+int __connman_dhcpv6_start_pd_renew(struct connman_network *network,
+ dhcpv6_cb callback);
+int __connman_dhcpv6_start_pd_release(struct connman_network *network,
+ dhcpv6_cb callback);
int __connman_ipv4_init(void);
void __connman_ipv4_cleanup(void);
@@ -426,7 +472,7 @@ void __connman_connection_gateway_remove(struct connman_service *service,
enum connman_ipconfig_type type);
int __connman_connection_get_vpn_index(int phy_index);
-gboolean __connman_connection_update_gateway(void);
+bool __connman_connection_update_gateway(void);
void __connman_connection_gateway_activate(struct connman_service *service,
enum connman_ipconfig_type type);
@@ -452,28 +498,29 @@ int __connman_technology_add_device(struct connman_device *device);
int __connman_technology_remove_device(struct connman_device *device);
int __connman_technology_enabled(enum connman_service_type type);
int __connman_technology_disabled(enum connman_service_type type);
-int __connman_technology_set_offlinemode(connman_bool_t offlinemode);
-connman_bool_t __connman_technology_get_offlinemode(void);
+int __connman_technology_set_offlinemode(bool offlinemode);
+bool __connman_technology_get_offlinemode(void);
void __connman_technology_set_connected(enum connman_service_type type,
- connman_bool_t connected);
+ bool connected);
int __connman_technology_add_rfkill(unsigned int index,
enum connman_service_type type,
- connman_bool_t softblock,
- connman_bool_t hardblock);
+ bool softblock,
+ bool hardblock);
int __connman_technology_update_rfkill(unsigned int index,
enum connman_service_type type,
- connman_bool_t softblock,
- connman_bool_t hardblock);
+ bool softblock,
+ bool hardblock);
int __connman_technology_remove_rfkill(unsigned int index,
enum connman_service_type type);
void __connman_technology_scan_started(struct connman_device *device);
-void __connman_technology_scan_stopped(struct connman_device *device);
+void __connman_technology_scan_stopped(struct connman_device *device,
+ enum connman_service_type type);
void __connman_technology_add_interface(enum connman_service_type type,
- int index, const char *name, const char *ident);
+ int index, const char *ident);
void __connman_technology_remove_interface(enum connman_service_type type,
- int index, const char *name, const char *ident);
+ int index, const char *ident);
void __connman_technology_notify_regdom_by_device(struct connman_device *device,
int result, const char *alpha2);
@@ -490,9 +537,9 @@ int __connman_device_request_scan(enum connman_service_type type);
int __connman_device_request_hidden_scan(struct connman_device *device,
const char *ssid, unsigned int ssid_len,
const char *identity, const char *passphrase,
- gpointer user_data);
+ const char *security, void *user_data);
-connman_bool_t __connman_device_isfiltered(const char *devname);
+bool __connman_device_isfiltered(const char *devname);
void __connman_device_set_network(struct connman_device *device,
struct connman_network *network);
@@ -502,17 +549,13 @@ int __connman_device_enable(struct connman_device *device);
int __connman_device_disable(struct connman_device *device);
int __connman_device_disconnect(struct connman_device *device);
-connman_bool_t __connman_device_has_driver(struct connman_device *device);
-
-void __connman_device_set_reconnect(struct connman_device *device,
- connman_bool_t reconnect);
-connman_bool_t __connman_device_get_reconnect(struct connman_device *device);
+bool __connman_device_has_driver(struct connman_device *device);
const char *__connman_device_get_type(struct connman_device *device);
int __connman_rfkill_init(void);
void __connman_rfkill_cleanup(void);
-int __connman_rfkill_block(enum connman_service_type type, connman_bool_t block);
+int __connman_rfkill_block(enum connman_service_type type, bool block);
#include <connman/network.h>
@@ -533,16 +576,28 @@ int __connman_network_set_ipconfig(struct connman_network *network,
const char *__connman_network_get_type(struct connman_network *network);
const char *__connman_network_get_group(struct connman_network *network);
const char *__connman_network_get_ident(struct connman_network *network);
-connman_bool_t __connman_network_get_weakness(struct connman_network *network);
+bool __connman_network_get_weakness(struct connman_network *network);
int __connman_config_init();
void __connman_config_cleanup(void);
-int __connman_config_load_service(GKeyFile *keyfile, const char *group, connman_bool_t persistent);
+int __connman_config_load_service(GKeyFile *keyfile, const char *group,
+ bool persistent);
int __connman_config_provision_service(struct connman_service *service);
int __connman_config_provision_service_ident(struct connman_service *service,
const char *ident, const char *file, const char *entry);
+char *__connman_config_get_string(GKeyFile *key_file,
+ const char *group_name, const char *key, GError **error);
+
+char **__connman_config_get_string_list(GKeyFile *key_file,
+ const char *group_name, const char *key, gsize *length, GError **error);
+
+bool __connman_config_get_bool(GKeyFile *key_file,
+ const char *group_name, const char *key, GError **error);
+bool __connman_config_address_provisioned(const char *address,
+ const char *netmask);
+
int __connman_tethering_init(void);
void __connman_tethering_cleanup(void);
@@ -553,13 +608,17 @@ void __connman_tethering_set_disabled(void);
int __connman_private_network_request(DBusMessage *msg, const char *owner);
int __connman_private_network_release(const char *path);
+int __connman_ipv6pd_setup(const char *bridge);
+void __connman_ipv6pd_cleanup(void);
+
#include <connman/provider.h>
-connman_bool_t __connman_provider_check_routes(struct connman_provider *provider);
+bool __connman_provider_check_routes(struct connman_provider *provider);
int __connman_provider_append_user_route(struct connman_provider *provider,
int family, const char *network, const char *netmask);
void __connman_provider_append_properties(struct connman_provider *provider, DBusMessageIter *iter);
void __connman_provider_list(DBusMessageIter *iter, void *user_data);
+bool __connman_provider_is_immutable(struct connman_provider *provider);
int __connman_provider_create_and_connect(DBusMessage *msg);
const char * __connman_provider_get_ident(struct connman_provider *provider);
int __connman_provider_indicate_state(struct connman_provider *provider,
@@ -575,6 +634,7 @@ int __connman_provider_init(void);
int __connman_service_init(void);
void __connman_service_cleanup(void);
+int __connman_service_load_modifiable(struct connman_service *service);
void __connman_service_list_struct(DBusMessageIter *iter);
@@ -582,6 +642,7 @@ struct connman_service *__connman_service_lookup_from_index(int index);
struct connman_service *__connman_service_lookup_from_ident(const char *identifier);
struct connman_service *__connman_service_create_from_network(struct connman_network *network);
struct connman_service *__connman_service_create_from_provider(struct connman_provider *provider);
+bool __connman_service_index_is_default(int index);
struct connman_service *__connman_service_get_default(void);
void __connman_service_update_from_network(struct connman_network *network);
void __connman_service_remove_from_network(struct connman_network *network);
@@ -594,29 +655,31 @@ struct connman_ipconfig *__connman_service_get_ip6config(
struct connman_service *service);
struct connman_ipconfig *__connman_service_get_ipconfig(
struct connman_service *service, int family);
-connman_bool_t __connman_service_is_connected_state(struct connman_service *service,
+bool __connman_service_is_connected_state(struct connman_service *service,
enum connman_ipconfig_type type);
const char *__connman_service_get_ident(struct connman_service *service);
const char *__connman_service_get_path(struct connman_service *service);
+const char *__connman_service_get_name(struct connman_service *service);
unsigned int __connman_service_get_order(struct connman_service *service);
+enum connman_service_state __connman_service_get_state(struct connman_service *service);
void __connman_service_update_ordering(void);
struct connman_network *__connman_service_get_network(struct connman_service *service);
enum connman_service_security __connman_service_get_security(struct connman_service *service);
const char *__connman_service_get_phase2(struct connman_service *service);
-connman_bool_t __connman_service_wps_enabled(struct connman_service *service);
+bool __connman_service_wps_enabled(struct connman_service *service);
int __connman_service_set_favorite(struct connman_service *service,
- connman_bool_t favorite);
+ bool favorite);
int __connman_service_set_favorite_delayed(struct connman_service *service,
- connman_bool_t favorite,
- gboolean delay_ordering);
+ bool favorite,
+ bool delay_ordering);
int __connman_service_set_immutable(struct connman_service *service,
- connman_bool_t immutable);
+ bool immutable);
int __connman_service_set_ignore(struct connman_service *service,
- connman_bool_t ignore);
-void __connman_service_set_userconnect(struct connman_service *service,
- connman_bool_t userconnect);
+ bool ignore);
void __connman_service_set_search_domains(struct connman_service *service,
char **domains);
+void __connman_service_update_search_domains(struct connman_service *service,
+ char **domains);
void __connman_service_set_string(struct connman_service *service,
const char *key, const char *value);
@@ -634,12 +697,14 @@ int __connman_service_indicate_error(struct connman_service *service,
int __connman_service_clear_error(struct connman_service *service);
int __connman_service_indicate_default(struct connman_service *service);
-int __connman_service_connect(struct connman_service *service);
+int __connman_service_connect(struct connman_service *service,
+ enum connman_service_connect_reason reason);
int __connman_service_disconnect(struct connman_service *service);
int __connman_service_disconnect_all(void);
-void __connman_service_auto_connect(void);
-gboolean __connman_service_remove(struct connman_service *service);
-connman_bool_t __connman_service_is_provider_pending(struct connman_service *service);
+void __connman_service_set_active_session(bool enable, GSList *list);
+void __connman_service_auto_connect(enum connman_service_connect_reason reason);
+bool __connman_service_remove(struct connman_service *service);
+bool __connman_service_is_provider_pending(struct connman_service *service);
void __connman_service_set_provider_pending(struct connman_service *service,
DBusMessage *msg);
void __connman_service_set_hidden_data(struct connman_service *service,
@@ -657,9 +722,9 @@ const char *__connman_service_type2string(enum connman_service_type type);
enum connman_service_type __connman_service_string2type(const char *str);
int __connman_service_nameserver_append(struct connman_service *service,
- const char *nameserver, gboolean is_auto);
+ const char *nameserver, bool is_auto);
int __connman_service_nameserver_remove(struct connman_service *service,
- const char *nameserver, gboolean is_auto);
+ const char *nameserver, bool is_auto);
void __connman_service_nameserver_clear(struct connman_service *service);
void __connman_service_nameserver_add_routes(struct connman_service *service,
const char *gw);
@@ -675,13 +740,16 @@ void __connman_service_timeserver_changed(struct connman_service *service,
GSList *ts_list);
void __connman_service_set_pac(struct connman_service *service,
const char *pac);
-connman_bool_t __connman_service_is_hidden(struct connman_service *service);
-connman_bool_t __connman_service_is_split_routing(struct connman_service *service);
+bool __connman_service_is_hidden(struct connman_service *service);
+bool __connman_service_is_split_routing(struct connman_service *service);
+bool __connman_service_index_is_split_routing(int index);
int __connman_service_get_index(struct connman_service *service);
void __connman_service_set_hidden(struct connman_service *service);
+void __connman_service_set_hostname(struct connman_service *service,
+ const char *hostname);
+const char *__connman_service_get_hostname(struct connman_service *service);
void __connman_service_set_domainname(struct connman_service *service,
const char *domainname);
-const char *__connman_service_get_domainname(struct connman_service *service);
const char *__connman_service_get_nameserver(struct connman_service *service);
void __connman_service_set_proxy_autoconfig(struct connman_service *service,
const char *url);
@@ -693,8 +761,6 @@ void __connman_service_set_agent_identity(struct connman_service *service,
int __connman_service_set_passphrase(struct connman_service *service,
const char *passphrase);
const char *__connman_service_get_passphrase(struct connman_service *service);
-void __connman_service_set_agent_passphrase(struct connman_service *service,
- const char *agent_passphrase);
int __connman_service_reset_ipconfig(struct connman_service *service,
enum connman_ipconfig_type type, DBusMessageIter *array,
enum connman_service_state *new_state);
@@ -708,17 +774,20 @@ void __connman_service_notify(struct connman_service *service,
int __connman_service_counter_register(const char *counter);
void __connman_service_counter_unregister(const char *counter);
+#include <connman/peer.h>
+
+int __connman_peer_init(void);
+void __connman_peer_cleanup(void);
+
+void __connman_peer_list_struct(DBusMessageIter *array);
+
#include <connman/session.h>
typedef void (* service_iterate_cb) (struct connman_service *service,
- const char *name,
- enum connman_service_state state,
void *user_data);
int __connman_service_iterate_services(service_iterate_cb cb, void *user_data);
-void __connman_service_session_inc(struct connman_service *service);
-connman_bool_t __connman_service_session_dec(struct connman_service *service);
void __connman_service_mark_dirty();
void __connman_service_save(struct connman_service *service);
@@ -737,7 +806,7 @@ void __connman_notifier_enter_online(enum connman_service_type type);
void __connman_notifier_leave_online(enum connman_service_type type);
void __connman_notifier_connect(enum connman_service_type type);
void __connman_notifier_disconnect(enum connman_service_type type);
-void __connman_notifier_offlinemode(connman_bool_t enabled);
+void __connman_notifier_offlinemode(bool enabled);
void __connman_notifier_default_changed(struct connman_service *service);
void __connman_notifier_proxy_changed(struct connman_service *service);
void __connman_notifier_service_state_changed(struct connman_service *service,
@@ -745,7 +814,7 @@ void __connman_notifier_service_state_changed(struct connman_service *service,
void __connman_notifier_ipconfig_changed(struct connman_service *service,
struct connman_ipconfig *ipconfig);
-connman_bool_t __connman_notifier_is_connected(void);
+bool __connman_notifier_is_connected(void);
const char *__connman_notifier_get_state(void);
#include <connman/rtnl.h>
@@ -760,8 +829,7 @@ unsigned int __connman_rtnl_update_interval_remove(unsigned int interval);
int __connman_rtnl_request_update(void);
int __connman_rtnl_send(const void *buf, size_t len);
-connman_bool_t __connman_session_mode();
-void __connman_session_set_mode(connman_bool_t enable);
+bool __connman_session_policy_autoconnect(enum connman_service_connect_reason reason);
int __connman_session_create(DBusMessage *msg);
int __connman_session_destroy(DBusMessage *msg);
@@ -786,10 +854,10 @@ void __connman_stats_cleanup(void);
int __connman_stats_service_register(struct connman_service *service);
void __connman_stats_service_unregister(struct connman_service *service);
int __connman_stats_update(struct connman_service *service,
- connman_bool_t roaming,
+ bool roaming,
struct connman_stats_data *data);
int __connman_stats_get(struct connman_service *service,
- connman_bool_t roaming,
+ bool roaming,
struct connman_stats_data *data);
int __connman_iptables_dump(const char *table_name);
@@ -871,8 +939,8 @@ void __connman_ippool_deladdr(int index, const char *address,
int __connman_bridge_create(const char *name);
int __connman_bridge_remove(const char *name);
-int __connman_bridge_enable(const char *name, const char *gateway,
- const char *broadcast);
+int __connman_bridge_enable(const char *name, const char *ip_address,
+ int prefix_len, const char *broadcast);
int __connman_bridge_disable(const char *name);
int __connman_nat_init(void);
@@ -892,6 +960,39 @@ int __connman_firewall_add_rule(struct firewall_context *ctx,
const char *rule_fmt, ...);
int __connman_firewall_enable(struct firewall_context *ctx);
int __connman_firewall_disable(struct firewall_context *ctx);
+bool __connman_firewall_is_up(void);
int __connman_firewall_init(void);
void __connman_firewall_cleanup(void);
+
+typedef int (* connman_nfacct_flush_cb_t) (unsigned int error, void *user_data);
+
+int __connman_nfacct_flush(connman_nfacct_flush_cb_t cb, void *user_data);
+
+struct nfacct_context;
+
+typedef void (* connman_nfacct_enable_cb_t) (unsigned int error,
+ struct nfacct_context *ctx,
+ void *user_data);
+typedef void (* connman_nfacct_disable_cb_t) (unsigned int error,
+ struct nfacct_context *ctx,
+ void *user_data);
+typedef void (* connman_nfacct_stats_cb_t) (struct nfacct_context *ctx,
+ uint64_t packets,
+ uint64_t bytes,
+ void *user_data);
+
+struct nfacct_context *__connman_nfacct_create_context(void);
+void __connman_nfacct_destroy_context(struct nfacct_context *ctx);
+
+int __connman_nfacct_add(struct nfacct_context *ctx, const char *name,
+ connman_nfacct_stats_cb_t cb,
+ void *user_data);
+int __connman_nfacct_enable(struct nfacct_context *ctx,
+ connman_nfacct_enable_cb_t cb,
+ void *user_data);
+int __connman_nfacct_disable(struct nfacct_context *ctx,
+ connman_nfacct_disable_cb_t cb,
+ void *user_data);
+
+void __connman_nfacct_cleanup(void);
diff --git a/src/connman.service.in b/src/connman.service.in
index 2e9e4d53..7b6195e9 100644
--- a/src/connman.service.in
+++ b/src/connman.service.in
@@ -1,6 +1,8 @@
[Unit]
Description=Connection service
-After=syslog.target
+Requires=dbus.socket
+After=dbus.socket
+Before=remote-fs.target
[Service]
Type=dbus
diff --git a/src/counter.c b/src/counter.c
index 76d91d48..06e5daff 100644
--- a/src/counter.c
+++ b/src/counter.c
@@ -75,11 +75,11 @@ int __connman_counter_register(const char *owner, const char *path,
DBG("owner %s path %s interval %u", owner, path, interval);
counter = g_hash_table_lookup(counter_table, path);
- if (counter != NULL)
+ if (counter)
return -EEXIST;
counter = g_try_new0(struct connman_counter, 1);
- if (counter == NULL)
+ if (!counter)
return -ENOMEM;
counter->owner = g_strdup(owner);
@@ -112,7 +112,7 @@ int __connman_counter_unregister(const char *owner, const char *path)
DBG("owner %s path %s", owner, path);
counter = g_hash_table_lookup(counter_table, path);
- if (counter == NULL)
+ if (!counter)
return -ESRCH;
if (g_strcmp0(owner, counter->owner) != 0)
@@ -133,7 +133,7 @@ void __connman_counter_send_usage(const char *path,
struct connman_counter *counter;
counter = g_hash_table_lookup(counter_table, path);
- if (counter == NULL)
+ if (!counter)
return;
dbus_message_set_destination(message, counter->owner);
@@ -157,7 +157,7 @@ static void release_counter(gpointer key, gpointer value, gpointer user_data)
message = dbus_message_new_method_call(counter->owner, counter->path,
CONNMAN_COUNTER_INTERFACE, "Release");
- if (message == NULL)
+ if (!message)
return;
dbus_message_set_no_reply(message, TRUE);
@@ -170,7 +170,7 @@ int __connman_counter_init(void)
DBG("");
connection = connman_dbus_get_connection();
- if (connection == NULL)
+ if (!connection)
return -1;
counter_table = g_hash_table_new_full(g_str_hash, g_str_equal,
@@ -185,7 +185,7 @@ void __connman_counter_cleanup(void)
{
DBG("");
- if (connection == NULL)
+ if (!connection)
return;
g_hash_table_foreach(counter_table, release_counter, NULL);
diff --git a/src/dbus.c b/src/dbus.c
index 5cc61061..4fa0b362 100644
--- a/src/dbus.c
+++ b/src/dbus.c
@@ -33,7 +33,7 @@ dbus_bool_t connman_dbus_validate_ident(const char *ident)
{
unsigned int i;
- if (ident == NULL)
+ if (!ident)
return FALSE;
for (i = 0; i < strlen(ident); i++) {
@@ -54,13 +54,13 @@ char *connman_dbus_encode_string(const char *value)
GString *str;
unsigned int i, size;
- if (value == NULL)
+ if (!value)
return NULL;
size = strlen(value);
str = g_string_new(NULL);
- if (str == NULL)
+ if (!str)
return NULL;
for (i = 0; i < size; i++) {
@@ -183,11 +183,13 @@ void connman_dbus_property_append_array(DBusMessageIter *iter,
switch (type) {
case DBUS_TYPE_STRING:
- variant_sig = DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING;
+ variant_sig = DBUS_TYPE_ARRAY_AS_STRING
+ DBUS_TYPE_STRING_AS_STRING;
array_sig = DBUS_TYPE_STRING_AS_STRING;
break;
case DBUS_TYPE_OBJECT_PATH:
- variant_sig = DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_OBJECT_PATH_AS_STRING;
+ variant_sig = DBUS_TYPE_ARRAY_AS_STRING
+ DBUS_TYPE_OBJECT_PATH_AS_STRING;
array_sig = DBUS_TYPE_OBJECT_PATH_AS_STRING;
break;
case DBUS_TYPE_DICT_ENTRY:
@@ -234,11 +236,11 @@ dbus_bool_t connman_dbus_property_changed_basic(const char *path,
DBusMessage *signal;
DBusMessageIter iter;
- if (path == NULL)
+ if (!path)
return FALSE;
signal = dbus_message_new_signal(path, interface, "PropertyChanged");
- if (signal == NULL)
+ if (!signal)
return FALSE;
dbus_message_iter_init_append(signal, &iter);
@@ -256,11 +258,11 @@ dbus_bool_t connman_dbus_property_changed_dict(const char *path,
DBusMessage *signal;
DBusMessageIter iter;
- if (path == NULL)
+ if (!path)
return FALSE;
signal = dbus_message_new_signal(path, interface, "PropertyChanged");
- if (signal == NULL)
+ if (!signal)
return FALSE;
dbus_message_iter_init_append(signal, &iter);
@@ -278,11 +280,11 @@ dbus_bool_t connman_dbus_property_changed_array(const char *path,
DBusMessage *signal;
DBusMessageIter iter;
- if (path == NULL)
+ if (!path)
return FALSE;
signal = dbus_message_new_signal(path, interface, "PropertyChanged");
- if (signal == NULL)
+ if (!signal)
return FALSE;
dbus_message_iter_init_append(signal, &iter);
@@ -301,13 +303,13 @@ dbus_bool_t connman_dbus_setting_changed_basic(const char *owner,
DBusMessage *msg;
DBusMessageIter array, dict;
- if (owner == NULL || path == NULL)
+ if (!owner || !path)
return FALSE;
msg = dbus_message_new_method_call(owner, path,
CONNMAN_NOTIFICATION_INTERFACE,
"Update");
- if (msg == NULL)
+ if (!msg)
return FALSE;
dbus_message_iter_init_append(msg, &array);
@@ -330,13 +332,13 @@ dbus_bool_t connman_dbus_setting_changed_dict(const char *owner,
DBusMessage *msg;
DBusMessageIter array, dict;
- if (owner == NULL || path == NULL)
+ if (!owner || !path)
return FALSE;
msg = dbus_message_new_method_call(owner, path,
CONNMAN_NOTIFICATION_INTERFACE,
"Update");
- if (msg == NULL)
+ if (!msg)
return FALSE;
dbus_message_iter_init_append(msg, &array);
@@ -359,13 +361,13 @@ dbus_bool_t connman_dbus_setting_changed_array(const char *owner,
DBusMessage *msg;
DBusMessageIter array, dict;
- if (owner == NULL || path == NULL)
+ if (!owner || !path)
return FALSE;
msg = dbus_message_new_method_call(owner, path,
CONNMAN_NOTIFICATION_INTERFACE,
"Update");
- if (msg == NULL)
+ if (!msg)
return FALSE;
dbus_message_iter_init_append(msg, &array);
@@ -385,7 +387,7 @@ dbus_bool_t __connman_dbus_append_objpath_dict_array(DBusMessage *msg,
{
DBusMessageIter iter, array;
- if (msg == NULL || function == NULL)
+ if (!msg || !function)
return FALSE;
dbus_message_iter_init_append(msg, &iter);
@@ -406,6 +408,25 @@ dbus_bool_t __connman_dbus_append_objpath_dict_array(DBusMessage *msg,
return TRUE;
}
+dbus_bool_t __connman_dbus_append_objpath_array(DBusMessage *msg,
+ connman_dbus_append_cb_t function, void *user_data)
+{
+ DBusMessageIter iter, array;
+
+ if (!msg || !function)
+ return FALSE;
+
+ dbus_message_iter_init_append(msg, &iter);
+ dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
+ DBUS_TYPE_OBJECT_PATH_AS_STRING, &array);
+
+ function(&array, user_data);
+
+ dbus_message_iter_close_container(&iter, &array);
+
+ return TRUE;
+}
+
struct callback_data {
void *cb;
void *user_data;
@@ -419,7 +440,7 @@ static void get_connection_unix_user_reply(DBusPendingCall *call,
DBusMessageIter iter;
DBusMessage *reply;
int err = 0;
- unsigned int uid;
+ unsigned int uid = 0;
reply = dbus_pending_call_steal_reply(call);
@@ -429,7 +450,7 @@ static void get_connection_unix_user_reply(DBusPendingCall *call,
goto done;
}
- if (dbus_message_has_signature(reply, "u") == FALSE) {
+ if (!dbus_message_has_signature(reply, "u")) {
DBG("Message signature is wrong");
err = -EINVAL;
goto done;
@@ -457,7 +478,7 @@ int connman_dbus_get_connection_unix_user(DBusConnection *connection,
int err;
data = g_try_new0(struct callback_data, 1);
- if (data == NULL) {
+ if (!data) {
DBG("Can't allocate data structure");
return -ENOMEM;
}
@@ -465,7 +486,7 @@ int connman_dbus_get_connection_unix_user(DBusConnection *connection,
msg = dbus_message_new_method_call(DBUS_SERVICE_DBUS, DBUS_PATH_DBUS,
DBUS_INTERFACE_DBUS,
"GetConnectionUnixUser");
- if (msg == NULL) {
+ if (!msg) {
DBG("Can't allocate new message");
err = -ENOMEM;
goto err;
@@ -474,14 +495,13 @@ int connman_dbus_get_connection_unix_user(DBusConnection *connection,
dbus_message_append_args(msg, DBUS_TYPE_STRING, &bus_name,
DBUS_TYPE_INVALID);
- if (dbus_connection_send_with_reply(connection, msg,
- &call, -1) == FALSE) {
+ if (!dbus_connection_send_with_reply(connection, msg, &call, -1)) {
DBG("Failed to execute method call");
err = -EINVAL;
goto err;
}
- if (call == NULL) {
+ if (!call) {
DBG("D-Bus connection not available");
err = -EINVAL;
goto err;
@@ -522,7 +542,7 @@ static unsigned char *parse_context(DBusMessage *msg)
return NULL;
ctx = g_try_malloc0(size + 1);
- if (ctx == NULL)
+ if (!ctx)
return NULL;
p = ctx;
@@ -555,7 +575,7 @@ static void selinux_get_context_reply(DBusPendingCall *call, void *user_data)
goto done;
}
- if (dbus_message_has_signature(reply, "ay") == FALSE) {
+ if (!dbus_message_has_signature(reply, "ay")) {
DBG("Message signature is wrong");
err = -EINVAL;
goto done;
@@ -583,11 +603,11 @@ int connman_dbus_get_selinux_context(DBusConnection *connection,
DBusMessage *msg = NULL;
int err;
- if (func == NULL)
+ if (!func)
return -EINVAL;
data = g_try_new0(struct callback_data, 1);
- if (data == NULL) {
+ if (!data) {
DBG("Can't allocate data structure");
return -ENOMEM;
}
@@ -595,7 +615,7 @@ int connman_dbus_get_selinux_context(DBusConnection *connection,
msg = dbus_message_new_method_call(DBUS_SERVICE_DBUS, DBUS_PATH_DBUS,
DBUS_INTERFACE_DBUS,
"GetConnectionSELinuxSecurityContext");
- if (msg == NULL) {
+ if (!msg) {
DBG("Can't allocate new message");
err = -ENOMEM;
goto err;
@@ -604,14 +624,13 @@ int connman_dbus_get_selinux_context(DBusConnection *connection,
dbus_message_append_args(msg, DBUS_TYPE_STRING, &service,
DBUS_TYPE_INVALID);
- if (dbus_connection_send_with_reply(connection, msg,
- &call, -1) == FALSE) {
+ if (!dbus_connection_send_with_reply(connection, msg, &call, -1)) {
DBG("Failed to execute method call");
err = -EINVAL;
goto err;
}
- if (call == NULL) {
+ if (!call) {
DBG("D-Bus connection not available");
err = -EINVAL;
goto err;
@@ -636,7 +655,7 @@ err:
DBusConnection *connman_dbus_get_connection(void)
{
- if (connection == NULL)
+ if (!connection)
return NULL;
return dbus_connection_ref(connection);
diff --git a/src/detect.c b/src/detect.c
index 5bf44af1..6c039206 100644
--- a/src/detect.c
+++ b/src/detect.c
@@ -2,7 +2,7 @@
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2013 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -67,11 +67,11 @@ static void detect_newlink(unsigned short type, int index,
}
device = find_device(index);
- if (device != NULL)
+ if (device)
return;
device = connman_device_create_from_index(index);
- if (device == NULL)
+ if (!device)
return;
if (connman_device_register(device) < 0) {
@@ -90,7 +90,7 @@ static void detect_dellink(unsigned short type, int index,
DBG("type %d index %d", type, index);
device = find_device(index);
- if (device == NULL)
+ if (!device)
return;
device_list = g_slist_remove(device_list, device);
diff --git a/src/device.c b/src/device.c
index 5feeee12..a97d790e 100644
--- a/src/device.c
+++ b/src/device.c
@@ -2,7 +2,7 @@
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2014 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -48,18 +48,18 @@ struct connman_device {
int refcount;
enum connman_device_type type;
enum connman_pending_type powered_pending; /* Indicates a pending
- enable/disable request */
- connman_bool_t powered;
- connman_bool_t scanning;
- connman_bool_t disconnected;
- connman_bool_t reconnect;
+ * enable/disable
+ * request
+ */
+ bool powered;
+ bool scanning;
+ bool disconnected;
char *name;
char *node;
char *address;
char *interface;
char *ident;
char *path;
- char *devname;
int index;
guint pending_timeout;
@@ -127,7 +127,8 @@ static const char *type2string(enum connman_device_type type)
return NULL;
}
-enum connman_service_type __connman_device_get_service_type(struct connman_device *device)
+enum connman_service_type __connman_device_get_service_type(
+ struct connman_device *device)
{
enum connman_device_type type = connman_device_get_type(device);
@@ -181,7 +182,7 @@ int __connman_device_enable(struct connman_device *device)
if (device->powered_pending == PENDING_ENABLE)
return -EALREADY;
- if (device->powered_pending == PENDING_NONE && device->powered == TRUE)
+ if (device->powered_pending == PENDING_NONE && device->powered)
return -EALREADY;
device->powered_pending = PENDING_ENABLE;
@@ -192,13 +193,13 @@ int __connman_device_enable(struct connman_device *device)
* Invoke the callback
*/
if (err == 0) {
- connman_device_set_powered(device, TRUE);
+ connman_device_set_powered(device, true);
goto done;
}
if (err == -EALREADY) {
/* If device is already powered, but connman is not updated */
- connman_device_set_powered(device, TRUE);
+ connman_device_set_powered(device, true);
goto done;
}
/*
@@ -219,9 +220,6 @@ int __connman_device_disable(struct connman_device *device)
DBG("device %p", device);
- if (!device->driver || !device->driver->disable)
- return -EOPNOTSUPP;
-
/* Ongoing power enable request */
if (device->powered_pending == PENDING_ENABLE)
return -EBUSY;
@@ -229,25 +227,27 @@ int __connman_device_disable(struct connman_device *device)
if (device->powered_pending == PENDING_DISABLE)
return -EALREADY;
- if (device->powered_pending == PENDING_NONE && device->powered == FALSE)
+ if (device->powered_pending == PENDING_NONE && !device->powered)
return -EALREADY;
device->powered_pending = PENDING_DISABLE;
- device->reconnect = FALSE;
if (device->network) {
struct connman_service *service =
connman_service_lookup_from_network(device->network);
- if (service != NULL)
+ if (service)
__connman_service_disconnect(service);
else
- connman_network_set_connected(device->network, FALSE);
+ connman_network_set_connected(device->network, false);
}
+ if (!device->driver || !device->driver->disable)
+ return -EOPNOTSUPP;
+
err = device->driver->disable(device);
if (err == 0 || err == -EALREADY) {
- connman_device_set_powered(device, FALSE);
+ connman_device_set_powered(device, false);
goto done;
}
@@ -264,10 +264,10 @@ static void probe_driver(struct connman_device_driver *driver)
DBG("driver %p name %s", driver, driver->name);
- for (list = device_list; list != NULL; list = list->next) {
+ for (list = device_list; list; list = list->next) {
struct connman_device *device = list->data;
- if (device->driver != NULL)
+ if (device->driver)
continue;
if (driver->type != device->type)
@@ -302,7 +302,7 @@ static void remove_driver(struct connman_device_driver *driver)
DBG("driver %p name %s", driver, driver->name);
- for (list = device_list; list != NULL; list = list->next) {
+ for (list = device_list; list; list = list->next) {
struct connman_device *device = list->data;
if (device->driver == driver)
@@ -310,12 +310,12 @@ static void remove_driver(struct connman_device_driver *driver)
}
}
-connman_bool_t __connman_device_has_driver(struct connman_device *device)
+bool __connman_device_has_driver(struct connman_device *device)
{
- if (device == NULL || device->driver == NULL)
- return FALSE;
+ if (!device || !device->driver)
+ return false;
- return TRUE;
+ return true;
}
static GSList *driver_list = NULL;
@@ -385,7 +385,6 @@ static void device_destruct(struct connman_device *device)
g_free(device->address);
g_free(device->interface);
g_free(device->path);
- g_free(device->devname);
g_free(device->last_network);
@@ -412,7 +411,7 @@ struct connman_device *connman_device_create(const char *node,
DBG("node %s type %d", node, type);
device = g_try_new0(struct connman_device, 1);
- if (device == NULL)
+ if (!device)
return NULL;
DBG("device %p", device);
@@ -521,15 +520,12 @@ int connman_device_get_index(struct connman_device *device)
void connman_device_set_interface(struct connman_device *device,
const char *interface)
{
- g_free(device->devname);
- device->devname = g_strdup(interface);
-
g_free(device->interface);
device->interface = g_strdup(interface);
- if (device->name == NULL) {
+ if (!device->name) {
const char *str = type2description(device->type);
- if (str != NULL && device->interface != NULL)
+ if (str && device->interface)
device->name = g_strdup_printf("%s (%s)", str,
device->interface);
}
@@ -562,7 +558,7 @@ const char *connman_device_get_ident(struct connman_device *device)
* Change power state of device
*/
int connman_device_set_powered(struct connman_device *device,
- connman_bool_t powered)
+ bool powered)
{
enum connman_service_type type;
@@ -579,36 +575,39 @@ int connman_device_set_powered(struct connman_device *device,
type = __connman_device_get_service_type(device);
- if (device->powered == FALSE) {
+ if (!device->powered) {
__connman_technology_disabled(type);
return 0;
}
__connman_technology_enabled(type);
- connman_device_set_disconnected(device, FALSE);
- device->scanning = FALSE;
+ connman_device_set_disconnected(device, false);
+ device->scanning = false;
if (device->driver && device->driver->scan)
- device->driver->scan(device, NULL, 0, NULL, NULL, NULL);
+ device->driver->scan(CONNMAN_SERVICE_TYPE_UNKNOWN, device,
+ NULL, 0, NULL, NULL, NULL, NULL);
return 0;
}
-connman_bool_t connman_device_get_powered(struct connman_device *device)
+bool connman_device_get_powered(struct connman_device *device)
{
return device->powered;
}
-static int device_scan(struct connman_device *device)
+static int device_scan(enum connman_service_type type,
+ struct connman_device *device)
{
if (!device->driver || !device->driver->scan)
return -EOPNOTSUPP;
- if (device->powered == FALSE)
+ if (!device->powered)
return -ENOLINK;
- return device->driver->scan(device, NULL, 0, NULL, NULL, NULL);
+ return device->driver->scan(type, device, NULL, 0,
+ NULL, NULL, NULL, NULL);
}
int __connman_device_disconnect(struct connman_device *device)
@@ -618,14 +617,14 @@ int __connman_device_disconnect(struct connman_device *device)
DBG("device %p", device);
- connman_device_set_disconnected(device, TRUE);
+ connman_device_set_disconnected(device, true);
g_hash_table_iter_init(&iter, device->networks);
- while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
+ while (g_hash_table_iter_next(&iter, &key, &value)) {
struct connman_network *network = value;
- if (connman_network_get_connecting(network) == TRUE) {
+ if (connman_network_get_connecting(network)) {
/*
* Skip network in the process of connecting.
* This is a workaround for WiFi networks serviced
@@ -647,32 +646,11 @@ int __connman_device_disconnect(struct connman_device *device)
return 0;
}
-int connman_device_disconnect_service(struct connman_device *device)
-{
- DBG("device %p", device);
-
- device->reconnect = FALSE;
-
- if (device->network) {
- struct connman_service *service =
- connman_service_lookup_from_network(device->network);
-
- if (service != NULL)
- __connman_service_disconnect(service);
- else
- connman_network_set_connected(device->network, FALSE);
- }
-
- return 0;
-}
-
int connman_device_reconnect_service(struct connman_device *device)
{
DBG("device %p", device);
- device->reconnect = TRUE;
-
- __connman_service_auto_connect();
+ __connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO);
return 0;
}
@@ -682,7 +660,7 @@ static void mark_network_available(gpointer key, gpointer value,
{
struct connman_network *network = value;
- connman_network_set_available(network, TRUE);
+ connman_network_set_available(network, true);
}
static void mark_network_unavailable(gpointer key, gpointer value,
@@ -690,11 +668,11 @@ static void mark_network_unavailable(gpointer key, gpointer value,
{
struct connman_network *network = value;
- if (connman_network_get_connected(network) == TRUE ||
- connman_network_get_connecting(network) == TRUE)
+ if (connman_network_get_connected(network) ||
+ connman_network_get_connecting(network))
return;
- connman_network_set_available(network, FALSE);
+ connman_network_set_available(network, false);
}
static gboolean remove_unavailable_network(gpointer key, gpointer value,
@@ -702,10 +680,10 @@ static gboolean remove_unavailable_network(gpointer key, gpointer value,
{
struct connman_network *network = value;
- if (connman_network_get_connected(network) == TRUE)
+ if (connman_network_get_connected(network))
return FALSE;
- if (connman_network_get_available(network) == TRUE)
+ if (connman_network_get_available(network))
return FALSE;
return TRUE;
@@ -717,7 +695,7 @@ void __connman_device_cleanup_networks(struct connman_device *device)
remove_unavailable_network, NULL);
}
-connman_bool_t connman_device_get_scanning(struct connman_device *device)
+bool connman_device_get_scanning(struct connman_device *device)
{
return device->scanning;
}
@@ -736,7 +714,7 @@ void connman_device_reset_scanning(struct connman_device *device)
* Change scanning state of device
*/
int connman_device_set_scanning(struct connman_device *device,
- connman_bool_t scanning)
+ enum connman_service_type type, bool scanning)
{
DBG("device %p scanning %d", device, scanning);
@@ -748,7 +726,7 @@ int connman_device_set_scanning(struct connman_device *device,
device->scanning = scanning;
- if (scanning == TRUE) {
+ if (scanning) {
__connman_technology_scan_started(device);
g_hash_table_foreach(device->networks,
@@ -759,9 +737,9 @@ int connman_device_set_scanning(struct connman_device *device,
__connman_device_cleanup_networks(device);
- __connman_technology_scan_stopped(device);
+ __connman_technology_scan_stopped(device, type);
- __connman_service_auto_connect();
+ __connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO);
return 0;
}
@@ -774,7 +752,7 @@ int connman_device_set_scanning(struct connman_device *device,
* Change disconnected state of device (only for device with networks)
*/
int connman_device_set_disconnected(struct connman_device *device,
- connman_bool_t disconnected)
+ bool disconnected)
{
DBG("device %p disconnected %d", device, disconnected);
@@ -792,7 +770,7 @@ int connman_device_set_disconnected(struct connman_device *device,
*
* Get device disconnected state
*/
-connman_bool_t connman_device_get_disconnected(struct connman_device *device)
+bool connman_device_get_disconnected(struct connman_device *device)
{
return device->disconnected;
}
@@ -810,16 +788,16 @@ int connman_device_set_string(struct connman_device *device,
{
DBG("device %p key %s value %s", device, key, value);
- if (g_str_equal(key, "Address") == TRUE) {
+ if (g_str_equal(key, "Address")) {
g_free(device->address);
device->address = g_strdup(value);
- } else if (g_str_equal(key, "Name") == TRUE) {
+ } else if (g_str_equal(key, "Name")) {
g_free(device->name);
device->name = g_strdup(value);
- } else if (g_str_equal(key, "Node") == TRUE) {
+ } else if (g_str_equal(key, "Node")) {
g_free(device->node);
device->node = g_strdup(value);
- } else if (g_str_equal(key, "Path") == TRUE) {
+ } else if (g_str_equal(key, "Path")) {
g_free(device->path);
device->path = g_strdup(value);
} else {
@@ -841,15 +819,15 @@ const char *connman_device_get_string(struct connman_device *device,
{
DBG("device %p key %s", device, key);
- if (g_str_equal(key, "Address") == TRUE)
+ if (g_str_equal(key, "Address"))
return device->address;
- else if (g_str_equal(key, "Name") == TRUE)
+ else if (g_str_equal(key, "Name"))
return device->name;
- else if (g_str_equal(key, "Node") == TRUE)
+ else if (g_str_equal(key, "Node"))
return device->node;
- else if (g_str_equal(key, "Interface") == TRUE)
+ else if (g_str_equal(key, "Interface"))
return device->interface;
- else if (g_str_equal(key, "Path") == TRUE)
+ else if (g_str_equal(key, "Path"))
return device->path;
return NULL;
@@ -869,7 +847,7 @@ int connman_device_add_network(struct connman_device *device,
DBG("device %p network %p", device, network);
- if (identifier == NULL)
+ if (!identifier)
return -EINVAL;
connman_network_ref(network);
@@ -911,7 +889,7 @@ int connman_device_remove_network(struct connman_device *device,
DBG("device %p network %p", device, network);
- if (network == NULL)
+ if (!network)
return 0;
identifier = connman_network_get_identifier(network);
@@ -920,23 +898,18 @@ int connman_device_remove_network(struct connman_device *device,
return 0;
}
-void connman_device_remove_all_networks(struct connman_device *device)
-{
- g_hash_table_remove_all(device->networks);
-}
-
void __connman_device_set_network(struct connman_device *device,
struct connman_network *network)
{
const char *name;
- if (device == NULL)
+ if (!device)
return;
if (device->network == network)
return;
- if (network != NULL) {
+ if (network) {
name = connman_network_get_string(network, "Name");
g_free(device->last_network);
device->last_network = g_strdup(name);
@@ -950,26 +923,14 @@ void __connman_device_set_network(struct connman_device *device,
}
}
-void __connman_device_set_reconnect(struct connman_device *device,
- connman_bool_t reconnect)
-{
- device->reconnect = reconnect;
-}
-
-connman_bool_t __connman_device_get_reconnect(
- struct connman_device *device)
-{
- return device->reconnect;
-}
-
-static gboolean match_driver(struct connman_device *device,
+static bool match_driver(struct connman_device *device,
struct connman_device_driver *driver)
{
if (device->type == driver->type ||
driver->type == CONNMAN_DEVICE_TYPE_UNKNOWN)
- return TRUE;
+ return true;
- return FALSE;
+ return false;
}
/**
@@ -984,13 +945,13 @@ int connman_device_register(struct connman_device *device)
DBG("device %p name %s", device, device->name);
- if (device->driver != NULL)
+ if (device->driver)
return -EALREADY;
for (list = driver_list; list; list = list->next) {
struct connman_device_driver *driver = list->data;
- if (match_driver(device, driver) == FALSE)
+ if (!match_driver(device, driver))
continue;
DBG("driver %p name %s", driver, driver->name);
@@ -1001,7 +962,7 @@ int connman_device_register(struct connman_device *device)
}
}
- if (device->driver == NULL)
+ if (!device->driver)
return 0;
return __connman_technology_add_device(device);
@@ -1017,7 +978,7 @@ void connman_device_unregister(struct connman_device *device)
{
DBG("device %p name %s", device, device->name);
- if (device->driver == NULL)
+ if (!device->driver)
return;
remove_device(device);
@@ -1051,7 +1012,7 @@ struct connman_device *__connman_device_find_device(
{
GSList *list;
- for (list = device_list; list != NULL; list = list->next) {
+ for (list = device_list; list; list = list->next) {
struct connman_device *device = list->data;
enum connman_service_type service_type =
__connman_device_get_service_type(device);
@@ -1069,7 +1030,7 @@ struct connman_device *connman_device_find_by_index(int index)
{
GSList *list;
- for (list = device_list; list != NULL; list = list->next) {
+ for (list = device_list; list; list = list->next) {
struct connman_device *device = list->data;
if (device->index == index)
return device;
@@ -1088,10 +1049,10 @@ struct connman_device *connman_device_find_by_index(int index)
int connman_device_set_regdom(struct connman_device *device,
const char *alpha2)
{
- if (device->driver == NULL || device->driver->set_regdom == NULL)
+ if (!device->driver || !device->driver->set_regdom)
return -ENOTSUP;
- if (device->powered == FALSE)
+ if (!device->powered)
return -EINVAL;
return device->driver->set_regdom(device, alpha2);
@@ -1112,7 +1073,7 @@ void connman_device_regdom_notify(struct connman_device *device,
int __connman_device_request_scan(enum connman_service_type type)
{
- connman_bool_t success = FALSE;
+ bool success = false;
int last_err = -ENOSYS;
GSList *list;
int err;
@@ -1128,29 +1089,33 @@ int __connman_device_request_scan(enum connman_service_type type)
case CONNMAN_SERVICE_TYPE_GADGET:
return -EOPNOTSUPP;
case CONNMAN_SERVICE_TYPE_WIFI:
+ case CONNMAN_SERVICE_TYPE_P2P:
break;
}
- for (list = device_list; list != NULL; list = list->next) {
+ for (list = device_list; list; list = list->next) {
struct connman_device *device = list->data;
enum connman_service_type service_type =
__connman_device_get_service_type(device);
- if (service_type != CONNMAN_SERVICE_TYPE_UNKNOWN &&
- service_type != type) {
- continue;
+ if (service_type != CONNMAN_SERVICE_TYPE_UNKNOWN) {
+ if (type == CONNMAN_SERVICE_TYPE_P2P) {
+ if (service_type != CONNMAN_SERVICE_TYPE_WIFI)
+ continue;
+ } else if (service_type != type)
+ continue;
}
- err = device_scan(device);
+ err = device_scan(type, device);
if (err == 0 || err == -EALREADY || err == -EINPROGRESS) {
- success = TRUE;
+ success = true;
} else {
last_err = err;
DBG("device %p err %d", device, err);
}
}
- if (success == TRUE)
+ if (success)
return 0;
return last_err;
@@ -1159,19 +1124,17 @@ int __connman_device_request_scan(enum connman_service_type type)
int __connman_device_request_hidden_scan(struct connman_device *device,
const char *ssid, unsigned int ssid_len,
const char *identity, const char *passphrase,
- void *user_data)
+ const char *security, void *user_data)
{
DBG("device %p", device);
- if (device == NULL || device->driver == NULL ||
- device->driver->scan == NULL)
+ if (!device || !device->driver ||
+ !device->driver->scan)
return -EINVAL;
- if (device->scanning == TRUE)
- return -EALREADY;
-
- return device->driver->scan(device, ssid, ssid_len,
- identity, passphrase, user_data);
+ return device->driver->scan(CONNMAN_SERVICE_TYPE_UNKNOWN,
+ device, ssid, ssid_len, identity,
+ passphrase, security, user_data);
}
static char *index2ident(int index, const char *prefix)
@@ -1274,10 +1237,10 @@ struct connman_device *connman_device_create_from_index(int index)
return NULL;
devname = connman_inet_ifname(index);
- if (devname == NULL)
+ if (!devname)
return NULL;
- if (__connman_device_isfiltered(devname) == TRUE) {
+ if (__connman_device_isfiltered(devname)) {
connman_info("Ignoring interface %s (filtered)", devname);
g_free(devname);
return NULL;
@@ -1305,7 +1268,7 @@ struct connman_device *connman_device_create_from_index(int index)
}
device = connman_device_create(name, type);
- if (device == NULL)
+ if (!device)
goto done;
switch (type) {
@@ -1330,7 +1293,7 @@ struct connman_device *connman_device_create_from_index(int index)
connman_device_set_index(device, index);
connman_device_set_interface(device, devname);
- if (ident != NULL) {
+ if (ident) {
connman_device_set_ident(device, ident);
g_free(ident);
}
@@ -1345,57 +1308,57 @@ done:
return device;
}
-connman_bool_t __connman_device_isfiltered(const char *devname)
+bool __connman_device_isfiltered(const char *devname)
{
char **pattern;
char **blacklisted_interfaces;
- gboolean match;
+ bool match;
- if (device_filter == NULL)
+ if (!device_filter)
goto nodevice;
- for (pattern = device_filter, match = FALSE; *pattern; pattern++) {
- if (g_pattern_match_simple(*pattern, devname) == TRUE) {
- match = TRUE;
+ for (pattern = device_filter, match = false; *pattern; pattern++) {
+ if (g_pattern_match_simple(*pattern, devname)) {
+ match = true;
break;
}
}
- if (match == FALSE) {
+ if (!match) {
DBG("ignoring device %s (match)", devname);
- return TRUE;
+ return true;
}
nodevice:
- if (g_pattern_match_simple("dummy*", devname) == TRUE) {
+ if (g_pattern_match_simple("dummy*", devname)) {
DBG("ignoring dummy networking devices");
- return TRUE;
+ return true;
}
- if (nodevice_filter == NULL)
+ if (!nodevice_filter)
goto list;
for (pattern = nodevice_filter; *pattern; pattern++) {
- if (g_pattern_match_simple(*pattern, devname) == TRUE) {
+ if (g_pattern_match_simple(*pattern, devname)) {
DBG("ignoring device %s (no match)", devname);
- return TRUE;
+ return true;
}
}
list:
blacklisted_interfaces =
connman_setting_get_string_list("NetworkInterfaceBlacklist");
- if (blacklisted_interfaces == NULL)
- return FALSE;
+ if (!blacklisted_interfaces)
+ return false;
for (pattern = blacklisted_interfaces; *pattern; pattern++) {
- if (g_str_has_prefix(devname, *pattern) == TRUE) {
+ if (g_str_has_prefix(devname, *pattern)) {
DBG("ignoring device %s (blacklist)", devname);
- return TRUE;
+ return true;
}
}
- return FALSE;
+ return false;
}
static void cleanup_devices(void)
@@ -1418,21 +1381,41 @@ static void cleanup_devices(void)
interfaces = __connman_inet_get_running_interfaces();
- if (interfaces == NULL)
+ if (!interfaces)
return;
- for (i = 0; interfaces[i] != NULL; i++) {
- connman_bool_t filtered;
+ for (i = 0; interfaces[i]; i++) {
+ bool filtered;
int index;
+ struct sockaddr_in sin_addr, sin_mask;
filtered = __connman_device_isfiltered(interfaces[i]);
- if (filtered == TRUE)
+ if (filtered)
continue;
index = connman_inet_ifindex(interfaces[i]);
if (index < 0)
continue;
+ if (!__connman_inet_get_address_netmask(index, &sin_addr,
+ &sin_mask)) {
+ char *address = g_strdup(inet_ntoa(sin_addr.sin_addr));
+ char *netmask = g_strdup(inet_ntoa(sin_mask.sin_addr));
+
+ if (__connman_config_address_provisioned(address,
+ netmask)) {
+ DBG("Skip %s which is already provisioned "
+ "with %s/%s", interfaces[i], address,
+ netmask);
+ g_free(address);
+ g_free(netmask);
+ continue;
+ }
+
+ g_free(address);
+ g_free(netmask);
+ }
+
DBG("cleaning up %s index %d", interfaces[i], index);
connman_inet_ifdown(index);
@@ -1450,10 +1433,10 @@ int __connman_device_init(const char *device, const char *nodevice)
{
DBG("");
- if (device != NULL)
+ if (device)
device_filter = g_strsplit(device, ",", -1);
- if (nodevice != NULL)
+ if (nodevice)
nodevice_filter = g_strsplit(nodevice, ",", -1);
cleanup_devices();
diff --git a/src/dhcp.c b/src/dhcp.c
index f32bfaef..83d7dfb3 100644
--- a/src/dhcp.c
+++ b/src/dhcp.c
@@ -2,7 +2,7 @@
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2013 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -36,6 +36,8 @@
#include "connman.h"
+#define RATE_LIMIT_INTERVAL 60 /* delay between successive attempts */
+
struct connman_dhcp {
struct connman_network *network;
dhcp_cb callback;
@@ -44,10 +46,16 @@ struct connman_dhcp {
char **timeservers;
char *pac;
+ unsigned int timeout;
+
+ GDHCPClient *ipv4ll_client;
GDHCPClient *dhcp_client;
+ char *ipv4ll_debug_prefix;
+ char *dhcp_debug_prefix;
};
static GHashTable *network_table;
+static bool ipv4ll_running;
static void dhcp_free(struct connman_dhcp *dhcp)
{
@@ -58,6 +66,8 @@ static void dhcp_free(struct connman_dhcp *dhcp)
dhcp->nameservers = NULL;
dhcp->timeservers = NULL;
dhcp->pac = NULL;
+
+ g_free(dhcp);
}
/**
@@ -72,7 +82,7 @@ static void dhcp_free(struct connman_dhcp *dhcp)
* service state due to the IP configuration change implied by this
* invalidation.
*/
-static void dhcp_invalidate(struct connman_dhcp *dhcp, connman_bool_t callback)
+static void dhcp_invalidate(struct connman_dhcp *dhcp, bool callback)
{
struct connman_service *service;
struct connman_ipconfig *ipconfig;
@@ -80,33 +90,33 @@ static void dhcp_invalidate(struct connman_dhcp *dhcp, connman_bool_t callback)
DBG("dhcp %p callback %u", dhcp, callback);
- if (dhcp == NULL)
+ if (!dhcp)
return;
service = connman_service_lookup_from_network(dhcp->network);
- if (service == NULL)
- goto out;
+ if (!service)
+ return;
ipconfig = __connman_service_get_ip4config(service);
- if (ipconfig == NULL)
- goto out;
+ if (!ipconfig)
+ return;
__connman_6to4_remove(ipconfig);
__connman_service_set_domainname(service, NULL);
__connman_service_set_pac(service, NULL);
- if (dhcp->timeservers != NULL) {
- for (i = 0; dhcp->timeservers[i] != NULL; i++) {
+ if (dhcp->timeservers) {
+ for (i = 0; dhcp->timeservers[i]; i++) {
__connman_service_timeserver_remove(service,
dhcp->timeservers[i]);
}
}
- if (dhcp->nameservers != NULL) {
- for (i = 0; dhcp->nameservers[i] != NULL; i++) {
+ if (dhcp->nameservers) {
+ for (i = 0; dhcp->nameservers[i]; i++) {
__connman_service_nameserver_remove(service,
- dhcp->nameservers[i], FALSE);
+ dhcp->nameservers[i], false);
}
}
@@ -121,26 +131,125 @@ static void dhcp_invalidate(struct connman_dhcp *dhcp, connman_bool_t callback)
__connman_ipconfig_set_gateway(ipconfig, NULL);
__connman_ipconfig_set_prefixlen(ipconfig, 0);
- if (dhcp->callback != NULL && callback)
- dhcp->callback(dhcp->network, FALSE);
-
-out:
- dhcp_free(dhcp);
+ if (dhcp->callback && callback)
+ dhcp->callback(dhcp->network, false, NULL);
}
static void dhcp_valid(struct connman_dhcp *dhcp)
{
- if (dhcp->callback != NULL)
- dhcp->callback(dhcp->network, TRUE);
+ if (dhcp->callback)
+ dhcp->callback(dhcp->network, true, NULL);
+}
+
+static void dhcp_debug(const char *str, void *data)
+{
+ connman_info("%s: %s", (const char *) data, str);
+}
+
+static void ipv4ll_stop_client(struct connman_dhcp *dhcp)
+{
+ if (!dhcp->ipv4ll_client)
+ return;
+
+ g_dhcp_client_stop(dhcp->ipv4ll_client);
+ g_dhcp_client_unref(dhcp->ipv4ll_client);
+ dhcp->ipv4ll_client = NULL;
+ ipv4ll_running = false;
+
+ g_free(dhcp->ipv4ll_debug_prefix);
+ dhcp->ipv4ll_debug_prefix = NULL;
+}
+
+static void ipv4ll_lost_cb(GDHCPClient *dhcp_client, gpointer user_data);
+static void ipv4ll_available_cb(GDHCPClient *ipv4ll_client, gpointer user_data);
+
+static int ipv4ll_start_client(struct connman_dhcp *dhcp)
+{
+ GDHCPClient *ipv4ll_client;
+ GDHCPClientError error;
+ const char *hostname;
+ int index;
+ int err;
+
+ if (dhcp->ipv4ll_client)
+ return -EALREADY;
+
+ index = connman_network_get_index(dhcp->network);
+
+ ipv4ll_client = g_dhcp_client_new(G_DHCP_IPV4LL, index, &error);
+ if (error != G_DHCP_CLIENT_ERROR_NONE)
+ return -EINVAL;
+
+ if (getenv("CONNMAN_DHCP_DEBUG")) {
+ dhcp->ipv4ll_debug_prefix = g_strdup_printf("IPv4LL index %d",
+ index);
+ g_dhcp_client_set_debug(ipv4ll_client, dhcp_debug,
+ dhcp->ipv4ll_debug_prefix);
+ }
+
+ g_dhcp_client_set_id(ipv4ll_client);
+
+ hostname = connman_utsname_get_hostname();
+ if (hostname)
+ g_dhcp_client_set_send(ipv4ll_client, G_DHCP_HOST_NAME,
+ hostname);
+
+ g_dhcp_client_register_event(ipv4ll_client,
+ G_DHCP_CLIENT_EVENT_IPV4LL_LOST, ipv4ll_lost_cb, dhcp);
+
+ g_dhcp_client_register_event(ipv4ll_client,
+ G_DHCP_CLIENT_EVENT_IPV4LL_AVAILABLE,
+ ipv4ll_available_cb, dhcp);
+
+ dhcp->ipv4ll_client = ipv4ll_client;
+
+ err = g_dhcp_client_start(dhcp->ipv4ll_client, NULL);
+ if (err < 0) {
+ ipv4ll_stop_client(dhcp);
+ return err;
+ }
+
+ ipv4ll_running = true;
+ return 0;
+}
+
+static gboolean dhcp_retry_cb(gpointer user_data)
+{
+ struct connman_dhcp *dhcp = user_data;
+ struct connman_service *service;
+ struct connman_ipconfig *ipconfig;
+
+ dhcp->timeout = 0;
+
+ service = connman_service_lookup_from_network(dhcp->network);
+ ipconfig = __connman_service_get_ip4config(service);
+
+ g_dhcp_client_start(dhcp->dhcp_client,
+ __connman_ipconfig_get_dhcp_address(ipconfig));
+
+ return FALSE;
}
static void no_lease_cb(GDHCPClient *dhcp_client, gpointer user_data)
{
struct connman_dhcp *dhcp = user_data;
+ int err;
- DBG("No lease available");
+ DBG("No lease available ipv4ll %d client %p", ipv4ll_running,
+ dhcp->ipv4ll_client);
- dhcp_invalidate(dhcp, TRUE);
+ dhcp->timeout = g_timeout_add_seconds(RATE_LIMIT_INTERVAL,
+ dhcp_retry_cb,
+ dhcp);
+ if (ipv4ll_running)
+ return;
+
+ err = ipv4ll_start_client(dhcp);
+ if (err < 0)
+ DBG("Cannot start ipv4ll client (%d/%s)", err, strerror(-err));
+
+ /* Only notify upper layer if we have a problem */
+ dhcp_invalidate(dhcp, !ipv4ll_running);
}
static void lease_lost_cb(GDHCPClient *dhcp_client, gpointer user_data)
@@ -149,7 +258,8 @@ static void lease_lost_cb(GDHCPClient *dhcp_client, gpointer user_data)
DBG("Lease lost");
- dhcp_invalidate(dhcp, TRUE);
+ /* Upper layer will decide what to do, e.g. nothing or retry. */
+ dhcp_invalidate(dhcp, true);
}
static void ipv4ll_lost_cb(GDHCPClient *dhcp_client, gpointer user_data)
@@ -158,27 +268,32 @@ static void ipv4ll_lost_cb(GDHCPClient *dhcp_client, gpointer user_data)
DBG("Lease lost");
- dhcp_invalidate(dhcp, TRUE);
-}
+ ipv4ll_stop_client(dhcp);
+ /*
+ * Since we lost our IPv4LL configuration we might as notify
+ * the upper layers.
+ */
+ dhcp_invalidate(dhcp, true);
+}
-static gboolean compare_string_arrays(char **array_a, char **array_b)
+static bool compare_string_arrays(char **array_a, char **array_b)
{
int i;
- if (array_a == NULL || array_b == NULL)
- return FALSE;
+ if (!array_a || !array_b)
+ return false;
if (g_strv_length(array_a) != g_strv_length(array_b))
- return FALSE;
+ return false;
- for (i = 0; array_a[i] != NULL &&
- array_b[i] != NULL; i++) {
+ for (i = 0; array_a[i] &&
+ array_b[i]; i++) {
if (g_strcmp0(array_a[i], array_b[i]) != 0)
- return FALSE;
+ return false;
}
- return TRUE;
+ return true;
}
static void lease_available_cb(GDHCPClient *dhcp_client, gpointer user_data)
@@ -187,25 +302,29 @@ static void lease_available_cb(GDHCPClient *dhcp_client, gpointer user_data)
GList *list, *option = NULL;
char *address, *netmask = NULL, *gateway = NULL;
const char *c_address, *c_gateway;
- char *domainname = NULL, *hostname = NULL;
char **nameservers, **timeservers, *pac = NULL;
int ns_entries;
struct connman_ipconfig *ipconfig;
struct connman_service *service;
unsigned char prefixlen, c_prefixlen;
- gboolean ip_change;
+ bool ip_change;
int i;
DBG("Lease available");
+ if (dhcp->ipv4ll_client) {
+ ipv4ll_stop_client(dhcp);
+ dhcp_invalidate(dhcp, false);
+ }
+
service = connman_service_lookup_from_network(dhcp->network);
- if (service == NULL) {
+ if (!service) {
connman_error("Can not lookup service");
return;
}
ipconfig = __connman_service_get_ip4config(service);
- if (ipconfig == NULL) {
+ if (!ipconfig) {
connman_error("Could not lookup ipconfig");
return;
}
@@ -220,11 +339,11 @@ static void lease_available_cb(GDHCPClient *dhcp_client, gpointer user_data)
DBG("last address %s", address);
option = g_dhcp_client_get_option(dhcp_client, G_DHCP_SUBNET);
- if (option != NULL)
+ if (option)
netmask = g_strdup(option->data);
option = g_dhcp_client_get_option(dhcp_client, G_DHCP_ROUTER);
- if (option != NULL)
+ if (option)
gateway = g_strdup(option->data);
prefixlen = __connman_ipaddress_netmask_prefix_len(netmask);
@@ -233,83 +352,78 @@ static void lease_available_cb(GDHCPClient *dhcp_client, gpointer user_data)
DBG("c_address %s", c_address);
- if (address != NULL && c_address != NULL &&
- g_strcmp0(address, c_address) != 0)
- ip_change = TRUE;
- else if (gateway != NULL && c_gateway != NULL &&
- g_strcmp0(gateway, c_gateway) != 0)
- ip_change = TRUE;
+ if (address && c_address && g_strcmp0(address, c_address) != 0)
+ ip_change = true;
+ else if (gateway && c_gateway && g_strcmp0(gateway, c_gateway) != 0)
+ ip_change = true;
else if (prefixlen != c_prefixlen)
- ip_change = TRUE;
- else if (c_address == NULL || c_gateway == NULL)
- ip_change = TRUE;
+ ip_change = true;
+ else if (!c_address || !c_gateway)
+ ip_change = true;
else
- ip_change = FALSE;
+ ip_change = false;
option = g_dhcp_client_get_option(dhcp_client, G_DHCP_DNS_SERVER);
ns_entries = g_list_length(option);
nameservers = g_try_new0(char *, ns_entries + 1);
- if (nameservers != NULL) {
+ if (nameservers) {
for (i = 0, list = option; list; list = list->next, i++)
nameservers[i] = g_strdup(list->data);
nameservers[ns_entries] = NULL;
}
option = g_dhcp_client_get_option(dhcp_client, G_DHCP_DOMAIN_NAME);
- if (option != NULL)
- domainname = g_strdup(option->data);
-
- if (connman_setting_get_bool("AllowHostnameUpdates") == TRUE) {
- option = g_dhcp_client_get_option(dhcp_client,
- G_DHCP_HOST_NAME);
- if (option != NULL)
- hostname = g_strdup(option->data);
- }
+ if (option)
+ __connman_service_set_domainname(service, option->data);
+
+ option = g_dhcp_client_get_option(dhcp_client, G_DHCP_HOST_NAME);
+ if (option)
+ __connman_service_set_hostname(service, option->data);
option = g_dhcp_client_get_option(dhcp_client, G_DHCP_NTP_SERVER);
ns_entries = g_list_length(option);
timeservers = g_try_new0(char *, ns_entries + 1);
- if (timeservers != NULL) {
+ if (timeservers) {
for (i = 0, list = option; list; list = list->next, i++)
timeservers[i] = g_strdup(list->data);
timeservers[ns_entries] = NULL;
}
option = g_dhcp_client_get_option(dhcp_client, 252);
- if (option != NULL)
+ if (option)
pac = g_strdup(option->data);
__connman_ipconfig_set_method(ipconfig, CONNMAN_IPCONFIG_METHOD_DHCP);
- if (ip_change == TRUE) {
+ if (ip_change) {
__connman_ipconfig_set_local(ipconfig, address);
__connman_ipconfig_set_prefixlen(ipconfig, prefixlen);
__connman_ipconfig_set_gateway(ipconfig, gateway);
}
- if (compare_string_arrays(nameservers, dhcp->nameservers) == FALSE) {
- if (dhcp->nameservers != NULL) {
- for (i = 0; dhcp->nameservers[i] != NULL; i++) {
+ if (!compare_string_arrays(nameservers, dhcp->nameservers)) {
+ if (dhcp->nameservers) {
+ for (i = 0; dhcp->nameservers[i]; i++) {
__connman_service_nameserver_remove(service,
- dhcp->nameservers[i], FALSE);
+ dhcp->nameservers[i], false);
}
g_strfreev(dhcp->nameservers);
}
dhcp->nameservers = nameservers;
- for (i = 0; dhcp->nameservers != NULL &&
- dhcp->nameservers[i] != NULL; i++) {
+ for (i = 0; dhcp->nameservers &&
+ dhcp->nameservers[i]; i++) {
__connman_service_nameserver_append(service,
- dhcp->nameservers[i], FALSE);
+ dhcp->nameservers[i], false);
}
} else {
g_strfreev(nameservers);
}
- if (compare_string_arrays(timeservers, dhcp->timeservers) == FALSE) {
- if (dhcp->timeservers != NULL) {
- for (i = 0; dhcp->timeservers[i] != NULL; i++) {
+ if (!compare_string_arrays(timeservers, dhcp->timeservers)) {
+ if (dhcp->timeservers) {
+ for (i = 0; dhcp->timeservers[i]; i++) {
__connman_service_timeserver_remove(service,
dhcp->timeservers[i]);
}
@@ -318,8 +432,8 @@ static void lease_available_cb(GDHCPClient *dhcp_client, gpointer user_data)
dhcp->timeservers = timeservers;
- for (i = 0; dhcp->timeservers != NULL &&
- dhcp->timeservers[i] != NULL; i++) {
+ for (i = 0; dhcp->timeservers &&
+ dhcp->timeservers[i]; i++) {
__connman_service_timeserver_append(service,
dhcp->timeservers[i]);
}
@@ -334,15 +448,7 @@ static void lease_available_cb(GDHCPClient *dhcp_client, gpointer user_data)
__connman_service_set_pac(service, dhcp->pac);
}
- __connman_service_set_domainname(service, domainname);
-
- if (domainname != NULL)
- __connman_utsname_set_domainname(domainname);
-
- if (hostname != NULL)
- __connman_utsname_set_hostname(hostname);
-
- if (ip_change == TRUE)
+ if (ip_change)
dhcp_valid(dhcp);
__connman_6to4_probe(service);
@@ -350,11 +456,9 @@ static void lease_available_cb(GDHCPClient *dhcp_client, gpointer user_data)
g_free(address);
g_free(netmask);
g_free(gateway);
- g_free(domainname);
- g_free(hostname);
}
-static void ipv4ll_available_cb(GDHCPClient *dhcp_client, gpointer user_data)
+static void ipv4ll_available_cb(GDHCPClient *ipv4ll_client, gpointer user_data)
{
struct connman_dhcp *dhcp = user_data;
char *address, *netmask;
@@ -365,15 +469,15 @@ static void ipv4ll_available_cb(GDHCPClient *dhcp_client, gpointer user_data)
DBG("IPV4LL available");
service = connman_service_lookup_from_network(dhcp->network);
- if (service == NULL)
+ if (!service)
return;
ipconfig = __connman_service_get_ip4config(service);
- if (ipconfig == NULL)
+ if (!ipconfig)
return;
- address = g_dhcp_client_get_address(dhcp_client);
- netmask = g_dhcp_client_get_netmask(dhcp_client);
+ address = g_dhcp_client_get_address(ipv4ll_client);
+ netmask = g_dhcp_client_get_netmask(ipv4ll_client);
prefixlen = __connman_ipaddress_netmask_prefix_len(netmask);
@@ -388,15 +492,9 @@ static void ipv4ll_available_cb(GDHCPClient *dhcp_client, gpointer user_data)
g_free(netmask);
}
-static void dhcp_debug(const char *str, void *data)
-{
- connman_info("%s: %s\n", (const char *) data, str);
-}
-
-static int dhcp_request(struct connman_dhcp *dhcp)
+static int dhcp_initialize(struct connman_dhcp *dhcp)
{
struct connman_service *service;
- struct connman_ipconfig *ipconfig;
GDHCPClient *dhcp_client;
GDHCPClientError error;
const char *hostname;
@@ -410,13 +508,22 @@ static int dhcp_request(struct connman_dhcp *dhcp)
if (error != G_DHCP_CLIENT_ERROR_NONE)
return -EINVAL;
- if (getenv("CONNMAN_DHCP_DEBUG"))
- g_dhcp_client_set_debug(dhcp_client, dhcp_debug, "DHCP");
+ if (getenv("CONNMAN_DHCP_DEBUG")) {
+ dhcp->dhcp_debug_prefix = g_strdup_printf("DHCP index %d",
+ index);
+ g_dhcp_client_set_debug(dhcp_client, dhcp_debug,
+ dhcp->dhcp_debug_prefix);
+ }
g_dhcp_client_set_id(dhcp_client);
- hostname = connman_utsname_get_hostname();
- if (hostname != NULL)
+ service = connman_service_lookup_from_network(dhcp->network);
+
+ hostname = __connman_service_get_hostname(service);
+ if (!hostname)
+ hostname = connman_utsname_get_hostname();
+
+ if (hostname)
g_dhcp_client_set_send(dhcp_client, G_DHCP_HOST_NAME, hostname);
g_dhcp_client_set_request(dhcp_client, G_DHCP_HOST_NAME);
@@ -432,89 +539,92 @@ static int dhcp_request(struct connman_dhcp *dhcp)
lease_available_cb, dhcp);
g_dhcp_client_register_event(dhcp_client,
- G_DHCP_CLIENT_EVENT_IPV4LL_AVAILABLE,
- ipv4ll_available_cb, dhcp);
-
- g_dhcp_client_register_event(dhcp_client,
G_DHCP_CLIENT_EVENT_LEASE_LOST, lease_lost_cb, dhcp);
g_dhcp_client_register_event(dhcp_client,
- G_DHCP_CLIENT_EVENT_IPV4LL_LOST, ipv4ll_lost_cb, dhcp);
-
- g_dhcp_client_register_event(dhcp_client,
G_DHCP_CLIENT_EVENT_NO_LEASE, no_lease_cb, dhcp);
dhcp->dhcp_client = dhcp_client;
- service = connman_service_lookup_from_network(dhcp->network);
- ipconfig = __connman_service_get_ip4config(service);
-
- /*
- * Clear the addresses at startup so that lease callback will
- * take the lease and set ip address properly.
- */
- __connman_ipconfig_clear_address(ipconfig);
-
- return g_dhcp_client_start(dhcp_client,
- __connman_ipconfig_get_dhcp_address(ipconfig));
+ return 0;
}
static int dhcp_release(struct connman_dhcp *dhcp)
{
DBG("dhcp %p", dhcp);
- if (dhcp->dhcp_client == NULL)
- return 0;
+ if (dhcp->timeout > 0)
+ g_source_remove(dhcp->timeout);
- g_dhcp_client_stop(dhcp->dhcp_client);
- g_dhcp_client_unref(dhcp->dhcp_client);
+ if (dhcp->dhcp_client) {
+ g_dhcp_client_stop(dhcp->dhcp_client);
+ g_dhcp_client_unref(dhcp->dhcp_client);
+ }
dhcp->dhcp_client = NULL;
- return 0;
-}
+ g_free(dhcp->dhcp_debug_prefix);
+ dhcp->dhcp_debug_prefix = NULL;
-static void remove_network(gpointer user_data)
-{
- struct connman_dhcp *dhcp = user_data;
-
- DBG("dhcp %p", dhcp);
+ ipv4ll_stop_client(dhcp);
- dhcp_invalidate(dhcp, FALSE);
- dhcp_release(dhcp);
-
- g_free(dhcp);
+ return 0;
}
int __connman_dhcp_start(struct connman_network *network, dhcp_cb callback)
{
+ struct connman_service *service;
+ struct connman_ipconfig *ipconfig;
+ const char *last_addr = NULL;
struct connman_dhcp *dhcp;
DBG("");
- dhcp = g_try_new0(struct connman_dhcp, 1);
- if (dhcp == NULL)
- return -ENOMEM;
+ service = connman_service_lookup_from_network(network);
+ if (!service)
+ return -EINVAL;
- dhcp->network = network;
- dhcp->callback = callback;
+ ipconfig = __connman_service_get_ip4config(service);
+ if (ipconfig)
+ last_addr = __connman_ipconfig_get_dhcp_address(ipconfig);
+
+ dhcp = g_hash_table_lookup(network_table, network);
+ if (!dhcp) {
- connman_network_ref(network);
+ dhcp = g_try_new0(struct connman_dhcp, 1);
+ if (!dhcp)
+ return -ENOMEM;
- g_hash_table_replace(network_table, network, dhcp);
+ dhcp->network = network;
+ connman_network_ref(network);
- return dhcp_request(dhcp);
+ g_hash_table_insert(network_table, network, dhcp);
+
+ dhcp_initialize(dhcp);
+ }
+
+ dhcp->callback = callback;
+
+ return g_dhcp_client_start(dhcp->dhcp_client, last_addr);
}
void __connman_dhcp_stop(struct connman_network *network)
{
- DBG("");
+ struct connman_dhcp *dhcp;
+
+ DBG("network_table %p network %p", network_table, network);
- if (network_table == NULL)
+ if (!network_table)
return;
- if (g_hash_table_remove(network_table, network) == TRUE)
+ dhcp = g_hash_table_lookup(network_table, network);
+ if (dhcp) {
+ g_hash_table_remove(network_table, network);
connman_network_unref(network);
+ dhcp_release(dhcp);
+ dhcp_invalidate(dhcp, false);
+ dhcp_free(dhcp);
+ }
}
int __connman_dhcp_init(void)
@@ -522,7 +632,7 @@ int __connman_dhcp_init(void)
DBG("");
network_table = g_hash_table_new_full(g_direct_hash, g_direct_equal,
- NULL, remove_network);
+ NULL, NULL);
return 0;
}
diff --git a/src/dhcpv6.c b/src/dhcpv6.c
index bff57d44..2ede854e 100644
--- a/src/dhcpv6.c
+++ b/src/dhcpv6.c
@@ -2,7 +2,7 @@
*
* Connection Manager
*
- * Copyright (C) 2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2012-2013 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -26,6 +26,7 @@
#include <errno.h>
#include <string.h>
#include <stdlib.h>
+#include <net/if.h>
#include <connman/ipconfig.h>
#include <connman/storage.h>
@@ -54,11 +55,18 @@
#define CNF_TIMEOUT (1 * 1000)
#define CNF_MAX_RT (4 * 1000)
#define CNF_MAX_RD (10 * 1000)
+#define DEC_TIMEOUT (1 * 1000)
+#define DEC_MAX_RC 5
+enum request_type {
+ REQ_REQUEST = 1,
+ REQ_REBIND = 2,
+ REQ_RENEW = 3,
+};
struct connman_dhcpv6 {
struct connman_network *network;
- dhcp_cb callback;
+ dhcpv6_cb callback;
char **nameservers;
char **timeservers;
@@ -68,16 +76,21 @@ struct connman_dhcpv6 {
guint timeout; /* operation timeout in msec */
guint MRD; /* max operation timeout in msec */
guint RT; /* in msec */
- gboolean use_ta; /* set to TRUE if IPv6 privacy is enabled */
- GSList *prefixes; /* network prefixes from radvd */
+ bool use_ta; /* set to TRUE if IPv6 privacy is enabled */
+ GSList *prefixes; /* network prefixes from radvd or dhcpv6 pd */
int request_count; /* how many times REQUEST have been sent */
- gboolean stateless; /* TRUE if stateless DHCPv6 is used */
- gboolean started; /* TRUE if we have DHCPv6 started */
+ bool stateless; /* TRUE if stateless DHCPv6 is used */
+ bool started; /* TRUE if we have DHCPv6 started */
};
static GHashTable *network_table;
+static GHashTable *network_pd_table;
-static int dhcpv6_request(struct connman_dhcpv6 *dhcp, gboolean add_addresses);
+static int dhcpv6_request(struct connman_dhcpv6 *dhcp, bool add_addresses);
+static int dhcpv6_pd_request(struct connman_dhcpv6 *dhcp);
+static gboolean start_solicitation(gpointer user_data);
+static int dhcpv6_renew(struct connman_dhcpv6 *dhcp);
+static int dhcpv6_rebind(struct connman_dhcpv6 *dhcp);
static void clear_timer(struct connman_dhcpv6 *dhcp)
{
@@ -92,7 +105,7 @@ static void clear_timer(struct connman_dhcpv6 *dhcp)
}
}
-static inline float get_random()
+static inline float get_random(void)
{
return (rand() % 200 - 100) / 1000.0;
}
@@ -113,7 +126,7 @@ static guint calc_delay(guint RT, guint MRT)
return (guint)rt;
}
-static void free_prefix(gpointer data, gpointer user_data)
+static void free_prefix(gpointer data)
{
g_free(data);
}
@@ -125,27 +138,26 @@ static void dhcpv6_free(struct connman_dhcpv6 *dhcp)
dhcp->nameservers = NULL;
dhcp->timeservers = NULL;
- dhcp->started = FALSE;
+ dhcp->started = false;
- g_slist_foreach(dhcp->prefixes, free_prefix, NULL);
- g_slist_free(dhcp->prefixes);
+ g_slist_free_full(dhcp->prefixes, free_prefix);
}
-static gboolean compare_string_arrays(char **array_a, char **array_b)
+static bool compare_string_arrays(char **array_a, char **array_b)
{
int i;
- if (array_a == NULL || array_b == NULL)
- return FALSE;
+ if (!array_a || !array_b)
+ return false;
if (g_strv_length(array_a) != g_strv_length(array_b))
- return FALSE;
+ return false;
- for (i = 0; array_a[i] != NULL && array_b[i] != NULL; i++)
+ for (i = 0; array_a[i] && array_b[i]; i++)
if (g_strcmp0(array_a[i], array_b[i]) != 0)
- return FALSE;
+ return false;
- return TRUE;
+ return true;
}
static void dhcpv6_debug(const char *str, void *data)
@@ -158,7 +170,7 @@ static gchar *convert_to_hex(unsigned char *buf, int len)
gchar *ret = g_try_malloc(len * 2 + 1);
int i;
- for (i = 0; ret != NULL && i < len; i++)
+ for (i = 0; ret && i < len; i++)
g_snprintf(ret + i * 2, 3, "%02x", buf[i]);
return ret;
@@ -181,17 +193,17 @@ static int set_duid(struct connman_service *service,
ident = __connman_service_get_ident(service);
keyfile = connman_storage_load_service(ident);
- if (keyfile == NULL)
+ if (!keyfile)
return -EINVAL;
hex_duid = g_key_file_get_string(keyfile, ident, "IPv6.DHCP.DUID",
NULL);
- if (hex_duid != NULL) {
+ if (hex_duid) {
unsigned int i, j = 0, hex;
size_t hex_duid_len = strlen(hex_duid);
duid = g_try_malloc0(hex_duid_len / 2);
- if (duid == NULL) {
+ if (!duid) {
g_key_file_free(keyfile);
g_free(hex_duid);
return -ENOMEM;
@@ -215,7 +227,7 @@ static int set_duid(struct connman_service *service,
}
hex_duid = convert_to_hex(duid, duid_len);
- if (hex_duid == NULL) {
+ if (!hex_duid) {
g_key_file_free(keyfile);
return -ENOMEM;
}
@@ -265,6 +277,10 @@ static void clear_callbacks(GDHCPClient *dhcp_client)
NULL, NULL);
g_dhcp_client_register_event(dhcp_client,
+ G_DHCP_CLIENT_EVENT_DECLINE,
+ NULL, NULL);
+
+ g_dhcp_client_register_event(dhcp_client,
G_DHCP_CLIENT_EVENT_INFORMATION_REQ,
NULL, NULL);
}
@@ -280,7 +296,7 @@ static void info_req_cb(GDHCPClient *dhcp_client, gpointer user_data)
DBG("dhcpv6 information-request %p", dhcp);
service = connman_service_lookup_from_network(dhcp->network);
- if (service == NULL) {
+ if (!service) {
connman_error("Can not lookup service");
return;
}
@@ -291,27 +307,27 @@ static void info_req_cb(GDHCPClient *dhcp_client, gpointer user_data)
entries = g_list_length(option);
nameservers = g_try_new0(char *, entries + 1);
- if (nameservers != NULL) {
+ if (nameservers) {
for (i = 0, list = option; list; list = list->next, i++)
nameservers[i] = g_strdup(list->data);
}
- if (compare_string_arrays(nameservers, dhcp->nameservers) == FALSE) {
- if (dhcp->nameservers != NULL) {
- for (i = 0; dhcp->nameservers[i] != NULL; i++)
+ if (!compare_string_arrays(nameservers, dhcp->nameservers)) {
+ if (dhcp->nameservers) {
+ for (i = 0; dhcp->nameservers[i]; i++)
__connman_service_nameserver_remove(service,
dhcp->nameservers[i],
- FALSE);
+ false);
g_strfreev(dhcp->nameservers);
}
dhcp->nameservers = nameservers;
- for (i = 0; dhcp->nameservers != NULL &&
- dhcp->nameservers[i] != NULL; i++)
+ for (i = 0; dhcp->nameservers &&
+ dhcp->nameservers[i]; i++)
__connman_service_nameserver_append(service,
dhcp->nameservers[i],
- FALSE);
+ false);
} else
g_strfreev(nameservers);
@@ -320,14 +336,14 @@ static void info_req_cb(GDHCPClient *dhcp_client, gpointer user_data)
entries = g_list_length(option);
timeservers = g_try_new0(char *, entries + 1);
- if (timeservers != NULL) {
+ if (timeservers) {
for (i = 0, list = option; list; list = list->next, i++)
timeservers[i] = g_strdup(list->data);
}
- if (compare_string_arrays(timeservers, dhcp->timeservers) == FALSE) {
- if (dhcp->timeservers != NULL) {
- for (i = 0; dhcp->timeservers[i] != NULL; i++)
+ if (!compare_string_arrays(timeservers, dhcp->timeservers)) {
+ if (dhcp->timeservers) {
+ for (i = 0; dhcp->timeservers[i]; i++)
__connman_service_timeserver_remove(service,
dhcp->timeservers[i]);
g_strfreev(dhcp->timeservers);
@@ -335,17 +351,20 @@ static void info_req_cb(GDHCPClient *dhcp_client, gpointer user_data)
dhcp->timeservers = timeservers;
- for (i = 0; dhcp->timeservers != NULL &&
- dhcp->timeservers[i] != NULL; i++)
+ for (i = 0; dhcp->timeservers &&
+ dhcp->timeservers[i]; i++)
__connman_service_timeserver_append(service,
dhcp->timeservers[i]);
} else
g_strfreev(timeservers);
- if (dhcp->callback != NULL) {
+ if (dhcp->callback) {
uint16_t status = g_dhcpv6_client_get_status(dhcp_client);
- dhcp->callback(dhcp->network, status == 0 ? TRUE : FALSE);
+ dhcp->callback(dhcp->network, status == 0 ?
+ CONNMAN_DHCPV6_STATUS_SUCCEED :
+ CONNMAN_DHCPV6_STATUS_FAIL,
+ NULL);
}
}
@@ -370,7 +389,7 @@ static int dhcpv6_info_request(struct connman_dhcpv6 *dhcp)
g_dhcp_client_set_debug(dhcp_client, dhcpv6_debug, "DHCPv6");
service = connman_service_lookup_from_network(dhcp->network);
- if (service == NULL) {
+ if (!service) {
clear_timer(dhcp);
g_dhcp_client_unref(dhcp_client);
return -EINVAL;
@@ -412,11 +431,14 @@ static int check_ipv6_addr_prefix(GSList *prefixes, char *address)
0xF0, 0xE0, 0xC0, 0x80 };
int left, count, i, plen;
- if (slash == NULL)
+ if (!slash)
continue;
prefix = g_strndup(prefix, slash - prefix);
len = strtol(slash + 1, NULL, 10);
+ if (len < 3 || len > 128)
+ break;
+
plen = 128 - len;
count = plen / 8;
@@ -445,54 +467,62 @@ static int check_ipv6_addr_prefix(GSList *prefixes, char *address)
return ret;
}
-static int set_addresses(GDHCPClient *dhcp_client,
+static int set_other_addresses(GDHCPClient *dhcp_client,
struct connman_dhcpv6 *dhcp)
{
struct connman_service *service;
- struct connman_ipconfig *ipconfig;
int entries, i;
GList *option, *list;
char **nameservers, **timeservers;
- const char *c_address;
- char *address = NULL;
service = connman_service_lookup_from_network(dhcp->network);
- if (service == NULL) {
+ if (!service) {
connman_error("Can not lookup service");
return -EINVAL;
}
- ipconfig = __connman_service_get_ip6config(service);
- if (ipconfig == NULL) {
- connman_error("Could not lookup ip6config");
- return -EINVAL;
+ /*
+ * Check domains before nameservers so that the nameserver append
+ * function will update domain list in service.c
+ */
+ option = g_dhcp_client_get_option(dhcp_client, G_DHCPV6_DOMAIN_LIST);
+ entries = g_list_length(option);
+ if (entries > 0) {
+ char **domains = g_try_new0(char *, entries + 1);
+ if (domains) {
+ for (i = 0, list = option; list;
+ list = list->next, i++)
+ domains[i] = g_strdup(list->data);
+ __connman_service_update_search_domains(service, domains);
+ g_strfreev(domains);
+ }
}
option = g_dhcp_client_get_option(dhcp_client, G_DHCPV6_DNS_SERVERS);
entries = g_list_length(option);
nameservers = g_try_new0(char *, entries + 1);
- if (nameservers != NULL) {
+ if (nameservers) {
for (i = 0, list = option; list; list = list->next, i++)
nameservers[i] = g_strdup(list->data);
}
- if (compare_string_arrays(nameservers, dhcp->nameservers) == FALSE) {
- if (dhcp->nameservers != NULL) {
- for (i = 0; dhcp->nameservers[i] != NULL; i++)
+ if (!compare_string_arrays(nameservers, dhcp->nameservers)) {
+ if (dhcp->nameservers) {
+ for (i = 0; dhcp->nameservers[i]; i++)
__connman_service_nameserver_remove(service,
dhcp->nameservers[i],
- FALSE);
+ false);
g_strfreev(dhcp->nameservers);
}
dhcp->nameservers = nameservers;
- for (i = 0; dhcp->nameservers != NULL &&
- dhcp->nameservers[i] != NULL; i++)
+ for (i = 0; dhcp->nameservers &&
+ dhcp->nameservers[i]; i++)
__connman_service_nameserver_append(service,
dhcp->nameservers[i],
- FALSE);
+ false);
} else
g_strfreev(nameservers);
@@ -501,14 +531,14 @@ static int set_addresses(GDHCPClient *dhcp_client,
entries = g_list_length(option);
timeservers = g_try_new0(char *, entries + 1);
- if (timeservers != NULL) {
+ if (timeservers) {
for (i = 0, list = option; list; list = list->next, i++)
timeservers[i] = g_strdup(list->data);
}
- if (compare_string_arrays(timeservers, dhcp->timeservers) == FALSE) {
- if (dhcp->timeservers != NULL) {
- for (i = 0; dhcp->timeservers[i] != NULL; i++)
+ if (!compare_string_arrays(timeservers, dhcp->timeservers)) {
+ if (dhcp->timeservers) {
+ for (i = 0; dhcp->timeservers[i]; i++)
__connman_service_timeserver_remove(service,
dhcp->timeservers[i]);
g_strfreev(dhcp->timeservers);
@@ -516,33 +546,90 @@ static int set_addresses(GDHCPClient *dhcp_client,
dhcp->timeservers = timeservers;
- for (i = 0; dhcp->timeservers != NULL &&
- dhcp->timeservers[i] != NULL; i++)
+ for (i = 0; dhcp->timeservers &&
+ dhcp->timeservers[i]; i++)
__connman_service_timeserver_append(service,
dhcp->timeservers[i]);
} else
g_strfreev(timeservers);
+ return 0;
+}
- option = g_dhcp_client_get_option(dhcp_client, G_DHCPV6_IA_NA);
- if (option != NULL)
- address = g_strdup(option->data);
- else {
- option = g_dhcp_client_get_option(dhcp_client, G_DHCPV6_IA_TA);
- if (option != NULL)
- address = g_strdup(option->data);
- }
+static GSList *copy_prefixes(GSList *prefixes)
+{
+ GSList *list, *copy = NULL;
+
+ for (list = prefixes; list; list = list->next)
+ copy = g_slist_prepend(copy, g_strdup(list->data));
+
+ return copy;
+}
+
+/*
+ * Helper struct for doing DAD (duplicate address detection).
+ * It is refcounted and freed after all reply's to neighbor
+ * discovery request are received.
+ */
+struct own_address {
+ int refcount;
+
+ int ifindex;
+ GDHCPClient *dhcp_client;
+ struct connman_ipconfig *ipconfig;
+ GSList *prefixes;
+ dhcpv6_cb callback;
+
+ GSList *dad_failed;
+ GSList *dad_succeed;
+};
+
+static void free_own_address(struct own_address *data)
+{
+ g_dhcp_client_unref(data->dhcp_client);
+ __connman_ipconfig_unref(data->ipconfig);
+ g_slist_free_full(data->prefixes, free_prefix);
+ g_slist_free_full(data->dad_failed, g_free);
+ g_slist_free_full(data->dad_succeed, g_free);
+
+ g_free(data);
+}
+
+static struct own_address *ref_own_address(struct own_address *address)
+{
+ DBG("%p ref %d", address, address->refcount + 1);
+
+ __sync_fetch_and_add(&address->refcount, 1);
+
+ return address;
+}
+
+static void unref_own_address(struct own_address *address)
+{
+ if (!address)
+ return;
+
+ DBG("%p ref %d", address, address->refcount - 1);
+
+ if (__sync_fetch_and_sub(&address->refcount, 1) != 1)
+ return;
+
+ free_own_address(address);
+}
+
+static void set_address(int ifindex, struct connman_ipconfig *ipconfig,
+ GSList *prefixes, char *address)
+{
+ const char *c_address;
c_address = __connman_ipconfig_get_local(ipconfig);
- if (address != NULL &&
- ((c_address != NULL &&
- g_strcmp0(address, c_address) != 0) ||
- (c_address == NULL))) {
+ if (address && ((c_address && g_strcmp0(address, c_address) != 0) ||
+ !c_address)) {
int prefix_len;
/* Is this prefix part of the subnet we are suppose to use? */
- prefix_len = check_ipv6_addr_prefix(dhcp->prefixes, address);
+ prefix_len = check_ipv6_addr_prefix(prefixes, address);
__connman_ipconfig_set_local(ipconfig, address);
__connman_ipconfig_set_prefixlen(ipconfig, prefix_len);
@@ -550,39 +637,480 @@ static int set_addresses(GDHCPClient *dhcp_client,
DBG("new address %s/%d", address, prefix_len);
__connman_ipconfig_set_dhcp_address(ipconfig, address);
- __connman_service_save(service);
+ __connman_service_save(
+ __connman_service_lookup_from_index(ifindex));
}
+}
- g_free(address);
- return 0;
+/*
+ * Helper struct that is used when waiting a reply to DECLINE message.
+ */
+struct decline_cb_data {
+ GDHCPClient *dhcp_client;
+ dhcpv6_cb callback;
+ int ifindex;
+ guint timeout;
+};
+
+static void decline_reply_callback(struct decline_cb_data *data)
+{
+ struct connman_network *network;
+ struct connman_service *service;
+
+ service = __connman_service_lookup_from_index(data->ifindex);
+ network = __connman_service_get_network(service);
+
+ if (data->callback)
+ data->callback(network, CONNMAN_DHCPV6_STATUS_RESTART, NULL);
+
+ g_dhcp_client_unref(data->dhcp_client);
+}
+
+static gboolean decline_timeout(gpointer user_data)
+{
+ struct decline_cb_data *data = user_data;
+
+ DBG("ifindex %d", data->ifindex);
+
+ /*
+ * We ignore all DECLINE replies that are received after the timeout
+ */
+ g_dhcp_client_register_event(data->dhcp_client,
+ G_DHCP_CLIENT_EVENT_DECLINE,
+ NULL, NULL);
+
+ decline_reply_callback(data);
+
+ g_free(data);
+
+ return FALSE;
+}
+
+static void decline_cb(GDHCPClient *dhcp_client, gpointer user_data)
+{
+ struct decline_cb_data *data = user_data;
+
+ DBG("ifindex %d", data->ifindex);
+
+ g_dhcpv6_client_clear_retransmit(dhcp_client);
+
+ if (data->timeout)
+ g_source_remove(data->timeout);
+
+ decline_reply_callback(data);
+
+ g_free(data);
+}
+
+static int dhcpv6_decline(GDHCPClient *dhcp_client, int ifindex,
+ dhcpv6_cb callback, GSList *failed)
+{
+ struct decline_cb_data *data;
+ GList *option;
+ int code;
+
+ DBG("dhcp_client %p", dhcp_client);
+
+ g_dhcp_client_clear_requests(dhcp_client);
+
+ g_dhcpv6_client_clear_send(dhcp_client, G_DHCPV6_ORO);
+
+ g_dhcp_client_set_request(dhcp_client, G_DHCPV6_CLIENTID);
+ g_dhcp_client_set_request(dhcp_client, G_DHCPV6_SERVERID);
+
+ option = g_dhcp_client_get_option(dhcp_client, G_DHCPV6_IA_NA);
+ if (!option) {
+ option = g_dhcp_client_get_option(dhcp_client, G_DHCPV6_IA_TA);
+ if (option)
+ code = G_DHCPV6_IA_TA;
+ else
+ return -EINVAL;
+ } else
+ code = G_DHCPV6_IA_NA;
+
+ g_dhcpv6_client_clear_send(dhcp_client, code);
+
+ g_dhcpv6_client_set_ias(dhcp_client, ifindex, code, NULL, NULL,
+ failed);
+
+ clear_callbacks(dhcp_client);
+
+ data = g_try_new(struct decline_cb_data, 1);
+ if (!data)
+ return -ENOMEM;
+
+ data->ifindex = ifindex;
+ data->callback = callback;
+ data->dhcp_client = g_dhcp_client_ref(dhcp_client);
+ data->timeout = g_timeout_add(DEC_TIMEOUT, decline_timeout, data);
+
+ g_dhcp_client_register_event(dhcp_client, G_DHCP_CLIENT_EVENT_DECLINE,
+ decline_cb, data);
+
+ return g_dhcp_client_start(dhcp_client, NULL);
+}
+
+static void dad_reply(struct nd_neighbor_advert *reply,
+ unsigned int length, struct in6_addr *addr, void *user_data)
+{
+ struct own_address *data = user_data;
+ GSList *list;
+ char address[INET6_ADDRSTRLEN];
+ enum __connman_dhcpv6_status status = CONNMAN_DHCPV6_STATUS_FAIL;
+
+ inet_ntop(AF_INET6, addr, address, INET6_ADDRSTRLEN);
+
+ DBG("user %p reply %p len %d address %s index %d data %p", user_data,
+ reply, length, address, data->ifindex, data);
+
+ if (!reply) {
+ if (length == 0)
+ DBG("DAD succeed for %s", address);
+ else
+ DBG("DAD cannot be done for %s", address);
+
+ data->dad_succeed = g_slist_prepend(data->dad_succeed,
+ g_strdup(address));
+
+ } else {
+ DBG("DAD failed for %s", address);
+
+ data->dad_failed = g_slist_prepend(data->dad_failed,
+ g_strdup(address));
+ }
+
+ /*
+ * If refcount == 1 then we got the final reply and can continue.
+ */
+ if (data->refcount > 1)
+ return;
+
+ for (list = data->dad_succeed; list; list = list->next)
+ set_address(data->ifindex, data->ipconfig, data->prefixes,
+ list->data);
+
+ if (data->dad_failed) {
+ dhcpv6_decline(data->dhcp_client, data->ifindex,
+ data->callback, data->dad_failed);
+ } else {
+ if (data->dad_succeed)
+ status = CONNMAN_DHCPV6_STATUS_SUCCEED;
+
+ if (data->callback) {
+ struct connman_network *network;
+ struct connman_service *service;
+
+ service = __connman_service_lookup_from_index(
+ data->ifindex);
+ network = __connman_service_get_network(service);
+ data->callback(network, status, NULL);
+ }
+ }
+
+ unref_own_address(data);
+}
+
+/*
+ * Is the kernel configured to do DAD? If 0, then do not do DAD.
+ * See also RFC 4862 chapter 5.4 about DupAddrDetectTransmits
+ */
+static int dad_transmits(int ifindex)
+{
+ char name[IF_NAMESIZE];
+ gchar *path;
+ int value = 1;
+ FILE *f;
+
+ if (!if_indextoname(ifindex, name))
+ return value;
+
+ path = g_strdup_printf("/proc/sys/net/ipv6/conf/%s/dad_transmits",
+ name);
+
+ if (!path)
+ return value;
+
+ f = fopen(path, "r");
+
+ g_free(path);
+
+ if (f) {
+ if (fscanf(f, "%d", &value) < 0)
+ value = 1;
+
+ fclose(f);
+ }
+
+ return value;
+}
+
+static void do_dad(GDHCPClient *dhcp_client, struct connman_dhcpv6 *dhcp)
+{
+ struct connman_service *service;
+ struct connman_ipconfig *ipconfig;
+ int ifindex;
+ GList *option, *list;
+ struct own_address *user_data;
+
+ option = g_dhcp_client_get_option(dhcp_client, G_DHCPV6_IA_NA);
+ if (!option)
+ option = g_dhcp_client_get_option(dhcp_client, G_DHCPV6_IA_TA);
+
+ /*
+ * Even if we didn't had any addresses, just try to set
+ * the other options.
+ */
+ set_other_addresses(dhcp_client, dhcp);
+
+ if (!option) {
+ DBG("Skip DAD as no addresses found in reply");
+ if (dhcp->callback)
+ dhcp->callback(dhcp->network,
+ CONNMAN_DHCPV6_STATUS_SUCCEED, NULL);
+
+ return;
+ }
+
+ ifindex = connman_network_get_index(dhcp->network);
+
+ DBG("index %d", ifindex);
+
+ service = connman_service_lookup_from_network(dhcp->network);
+ if (!service) {
+ connman_error("Can not lookup service for index %d", ifindex);
+ goto error;
+ }
+
+ ipconfig = __connman_service_get_ip6config(service);
+ if (!ipconfig) {
+ connman_error("Could not lookup ip6config for index %d",
+ ifindex);
+ goto error;
+ }
+
+ if (!dad_transmits(ifindex)) {
+ DBG("Skip DAD because of kernel configuration");
+
+ for (list = option; list; list = list->next)
+ set_address(ifindex, ipconfig, dhcp->prefixes,
+ option->data);
+
+ if (dhcp->callback)
+ dhcp->callback(dhcp->network,
+ CONNMAN_DHCPV6_STATUS_SUCCEED, NULL);
+
+ return;
+ }
+
+ if (g_list_length(option) == 0) {
+ DBG("No addresses when doing DAD");
+ if (dhcp->callback)
+ dhcp->callback(dhcp->network,
+ CONNMAN_DHCPV6_STATUS_SUCCEED, NULL);
+
+ return;
+ }
+
+ user_data = g_try_new0(struct own_address, 1);
+ if (!user_data)
+ goto error;
+
+ user_data->refcount = 0;
+ user_data->ifindex = ifindex;
+ user_data->dhcp_client = g_dhcp_client_ref(dhcp_client);
+ user_data->ipconfig = __connman_ipconfig_ref(ipconfig);
+ user_data->prefixes = copy_prefixes(dhcp->prefixes);
+ user_data->callback = dhcp->callback;
+
+ /*
+ * We send one neighbor discovery request / address
+ * and after all checks are done, then report the status
+ * via dhcp callback.
+ */
+
+ for (list = option; list; list = list->next) {
+ char *address = option->data;
+ struct in6_addr addr;
+ int ret;
+
+ ref_own_address(user_data);
+
+ if (inet_pton(AF_INET6, address, &addr) < 0) {
+ DBG("Invalid IPv6 address %s %d/%s", address,
+ -errno, strerror(errno));
+ goto fail;
+ }
+
+ DBG("user %p address %s client %p ipconfig %p prefixes %p",
+ user_data, address,
+ user_data->dhcp_client, user_data->ipconfig,
+ user_data->prefixes);
+
+ ret = __connman_inet_ipv6_do_dad(ifindex, 1000,
+ &addr,
+ dad_reply,
+ user_data);
+ if (ret < 0) {
+ DBG("Could not send neighbor solicitation for %s",
+ address);
+ dad_reply(NULL, -1, &addr, user_data);
+ } else {
+ DBG("Sent neighbor solicitation %d bytes", ret);
+ }
+ }
+
+ return;
+
+fail:
+ unref_own_address(user_data);
+
+error:
+ if (dhcp->callback)
+ dhcp->callback(dhcp->network, CONNMAN_DHCPV6_STATUS_FAIL,
+ NULL);
}
-static void re_cb(GDHCPClient *dhcp_client, gpointer user_data)
+static gboolean timeout_request_resend(gpointer user_data)
{
struct connman_dhcpv6 *dhcp = user_data;
- uint16_t status;
- int ret;
- ret = set_addresses(dhcp_client, dhcp);
+ if (dhcp->request_count >= REQ_MAX_RC) {
+ DBG("max request retry attempts %d", dhcp->request_count);
+ dhcp->request_count = 0;
+ if (dhcp->callback)
+ dhcp->callback(dhcp->network,
+ CONNMAN_DHCPV6_STATUS_FAIL, NULL);
+ return FALSE;
+ }
- status = g_dhcpv6_client_get_status(dhcp_client);
+ dhcp->request_count++;
+
+ dhcp->RT = calc_delay(dhcp->RT, REQ_MAX_RT);
+ DBG("request resend RT timeout %d msec", dhcp->RT);
+ dhcp->timeout = g_timeout_add(dhcp->RT, timeout_request_resend, dhcp);
- DBG("dhcpv6 cb msg %p ret %d status %d", dhcp, ret, status);
+ g_dhcpv6_client_set_retransmit(dhcp->dhcp_client);
- if (ret < 0) {
- if (dhcp->callback != NULL)
- dhcp->callback(dhcp->network, FALSE);
+ g_dhcp_client_start(dhcp->dhcp_client, NULL);
+
+ return FALSE;
+}
+
+static gboolean request_resend(gpointer user_data)
+{
+ struct connman_dhcpv6 *dhcp = user_data;
+
+ g_dhcpv6_client_set_retransmit(dhcp->dhcp_client);
+
+ dhcp->RT = calc_delay(dhcp->RT, REQ_MAX_RT);
+ DBG("request resend RT timeout %d msec", dhcp->RT);
+ dhcp->timeout = g_timeout_add(dhcp->RT, timeout_request_resend, dhcp);
+
+ dhcpv6_request(dhcp, true);
+
+ return FALSE;
+}
+
+static void do_resend_request(struct connman_dhcpv6 *dhcp)
+{
+ if (dhcp->request_count >= REQ_MAX_RC) {
+ DBG("max request retry attempts %d", dhcp->request_count);
+ dhcp->request_count = 0;
+ if (dhcp->callback)
+ dhcp->callback(dhcp->network,
+ CONNMAN_DHCPV6_STATUS_FAIL, NULL);
return;
}
+ dhcp->request_count++;
+
+ dhcp->RT = calc_delay(dhcp->RT, REQ_MAX_RT);
+ DBG("resending request after %d msec", dhcp->RT);
+ dhcp->timeout = g_timeout_add(dhcp->RT, request_resend, dhcp);
+}
+
+static void re_cb(enum request_type req_type, GDHCPClient *dhcp_client,
+ gpointer user_data)
+{
+ struct connman_dhcpv6 *dhcp = user_data;
+ uint16_t status;
+
+ clear_timer(dhcp);
+
+ status = g_dhcpv6_client_get_status(dhcp_client);
+
+ DBG("dhcpv6 cb msg %p status %d", dhcp, status);
+
+ /*
+ * RFC 3315, 18.1.8 handle the resend if error
+ */
if (status == G_DHCPV6_ERROR_BINDING) {
- /* RFC 3315, 18.1.8 */
- dhcpv6_request(dhcp, FALSE);
+ dhcpv6_request(dhcp, false);
+ } else if (status == G_DHCPV6_ERROR_MCAST) {
+ switch (req_type) {
+ case REQ_REQUEST:
+ dhcpv6_request(dhcp, true);
+ break;
+ case REQ_REBIND:
+ dhcpv6_rebind(dhcp);
+ break;
+ case REQ_RENEW:
+ dhcpv6_renew(dhcp);
+ break;
+ }
+ } else if (status == G_DHCPV6_ERROR_LINK) {
+ if (req_type == REQ_REQUEST) {
+ g_dhcp_client_unref(dhcp->dhcp_client);
+ start_solicitation(dhcp);
+ } else {
+ if (dhcp->callback)
+ dhcp->callback(dhcp->network,
+ CONNMAN_DHCPV6_STATUS_FAIL, NULL);
+ }
+ } else if (status == G_DHCPV6_ERROR_FAILURE) {
+ if (req_type == REQ_REQUEST) {
+ /* Rate limit the resend of request message */
+ do_resend_request(dhcp);
+ } else {
+ if (dhcp->callback)
+ dhcp->callback(dhcp->network,
+ CONNMAN_DHCPV6_STATUS_FAIL, NULL);
+ }
} else {
- if (dhcp->callback != NULL)
+
+ /*
+ * If we did not got any addresses, then re-send
+ * a request.
+ */
+ GList *option;
+
+ option = g_dhcp_client_get_option(dhcp->dhcp_client,
+ G_DHCPV6_IA_NA);
+ if (!option) {
+ option = g_dhcp_client_get_option(dhcp->dhcp_client,
+ G_DHCPV6_IA_TA);
+ if (!option) {
+ switch (req_type) {
+ case REQ_REQUEST:
+ dhcpv6_request(dhcp, true);
+ break;
+ case REQ_REBIND:
+ dhcpv6_rebind(dhcp);
+ break;
+ case REQ_RENEW:
+ dhcpv6_renew(dhcp);
+ break;
+ }
+ return;
+ }
+ }
+
+ if (status == G_DHCPV6_ERROR_SUCCESS)
+ do_dad(dhcp_client, dhcp);
+ else if (dhcp->callback)
dhcp->callback(dhcp->network,
- status == 0 ? TRUE : FALSE);
+ CONNMAN_DHCPV6_STATUS_FAIL, NULL);
}
}
@@ -590,11 +1118,9 @@ static void rebind_cb(GDHCPClient *dhcp_client, gpointer user_data)
{
DBG("");
- g_dhcpv6_client_reset_rebind(dhcp_client);
- g_dhcpv6_client_reset_renew(dhcp_client);
g_dhcpv6_client_clear_retransmit(dhcp_client);
- re_cb(dhcp_client, user_data);
+ re_cb(REQ_REBIND, dhcp_client, user_data);
}
static int dhcpv6_rebind(struct connman_dhcpv6 *dhcp)
@@ -617,8 +1143,8 @@ static int dhcpv6_rebind(struct connman_dhcpv6 *dhcp)
g_dhcpv6_client_set_ia(dhcp_client,
connman_network_get_index(dhcp->network),
- dhcp->use_ta == TRUE ? G_DHCPV6_IA_TA : G_DHCPV6_IA_NA,
- NULL, NULL, FALSE, NULL);
+ dhcp->use_ta ? G_DHCPV6_IA_TA : G_DHCPV6_IA_NA,
+ NULL, NULL, TRUE, NULL);
clear_callbacks(dhcp_client);
@@ -634,8 +1160,9 @@ static gboolean dhcpv6_restart(gpointer user_data)
{
struct connman_dhcpv6 *dhcp = user_data;
- if (dhcp->callback != NULL)
- dhcp->callback(dhcp->network, FALSE);
+ if (dhcp->callback)
+ dhcp->callback(dhcp->network, CONNMAN_DHCPV6_STATUS_FAIL,
+ NULL);
return FALSE;
}
@@ -649,10 +1176,10 @@ static int check_restart(struct connman_dhcpv6 *dhcp)
time_t current, expired;
g_dhcpv6_client_get_timeouts(dhcp->dhcp_client, NULL, NULL,
- NULL, NULL, &expired);
+ NULL, &expired);
current = time(NULL);
- if (current > expired) {
+ if (current >= expired) {
DBG("expired by %d secs", (int)(current - expired));
g_timeout_add(0, dhcpv6_restart, dhcp);
@@ -687,6 +1214,9 @@ static gboolean start_rebind(gpointer user_data)
{
struct connman_dhcpv6 *dhcp = user_data;
+ if (check_restart(dhcp) < 0)
+ return FALSE;
+
dhcp->RT = REB_TIMEOUT * (1 + get_random());
DBG("rebind initial RT timeout %d msec", dhcp->RT);
@@ -702,13 +1232,14 @@ static void request_cb(GDHCPClient *dhcp_client, gpointer user_data)
{
DBG("");
+ g_dhcpv6_client_reset_request(dhcp_client);
g_dhcpv6_client_clear_retransmit(dhcp_client);
- re_cb(dhcp_client, user_data);
+ re_cb(REQ_REQUEST, dhcp_client, user_data);
}
static int dhcpv6_request(struct connman_dhcpv6 *dhcp,
- gboolean add_addresses)
+ bool add_addresses)
{
GDHCPClient *dhcp_client;
uint32_t T1, T2;
@@ -728,10 +1259,10 @@ static int dhcpv6_request(struct connman_dhcpv6 *dhcp,
g_dhcpv6_client_set_oro(dhcp_client, 3, G_DHCPV6_DNS_SERVERS,
G_DHCPV6_DOMAIN_LIST, G_DHCPV6_SNTP_SERVERS);
- g_dhcpv6_client_get_timeouts(dhcp_client, &T1, &T2, NULL, NULL, NULL);
+ g_dhcpv6_client_get_timeouts(dhcp_client, &T1, &T2, NULL, NULL);
g_dhcpv6_client_set_ia(dhcp_client,
connman_network_get_index(dhcp->network),
- dhcp->use_ta == TRUE ? G_DHCPV6_IA_TA : G_DHCPV6_IA_NA,
+ dhcp->use_ta ? G_DHCPV6_IA_TA : G_DHCPV6_IA_NA,
&T1, &T2, add_addresses, NULL);
clear_callbacks(dhcp_client);
@@ -751,8 +1282,9 @@ static gboolean timeout_request(gpointer user_data)
if (dhcp->request_count >= REQ_MAX_RC) {
DBG("max request retry attempts %d", dhcp->request_count);
dhcp->request_count = 0;
- if (dhcp->callback != NULL)
- dhcp->callback(dhcp->network, FALSE);
+ if (dhcp->callback)
+ dhcp->callback(dhcp->network,
+ CONNMAN_DHCPV6_STATUS_FAIL, NULL);
return FALSE;
}
@@ -773,10 +1305,9 @@ static void renew_cb(GDHCPClient *dhcp_client, gpointer user_data)
{
DBG("");
- g_dhcpv6_client_reset_renew(dhcp_client);
g_dhcpv6_client_clear_retransmit(dhcp_client);
- re_cb(dhcp_client, user_data);
+ re_cb(REQ_RENEW, dhcp_client, user_data);
}
static int dhcpv6_renew(struct connman_dhcpv6 *dhcp)
@@ -799,10 +1330,10 @@ static int dhcpv6_renew(struct connman_dhcpv6 *dhcp)
g_dhcpv6_client_set_oro(dhcp_client, 3, G_DHCPV6_DNS_SERVERS,
G_DHCPV6_DOMAIN_LIST, G_DHCPV6_SNTP_SERVERS);
- g_dhcpv6_client_get_timeouts(dhcp_client, &T1, &T2, NULL, NULL, NULL);
+ g_dhcpv6_client_get_timeouts(dhcp_client, &T1, &T2, NULL, NULL);
g_dhcpv6_client_set_ia(dhcp_client,
connman_network_get_index(dhcp->network),
- dhcp->use_ta == TRUE ? G_DHCPV6_IA_TA : G_DHCPV6_IA_NA,
+ dhcp->use_ta ? G_DHCPV6_IA_TA : G_DHCPV6_IA_NA,
&T1, &T2, TRUE, NULL);
clear_callbacks(dhcp_client);
@@ -818,10 +1349,23 @@ static int dhcpv6_renew(struct connman_dhcpv6 *dhcp)
static gboolean timeout_renew(gpointer user_data)
{
struct connman_dhcpv6 *dhcp = user_data;
+ time_t last_rebind, current;
+ uint32_t T2;
if (check_restart(dhcp) < 0)
return FALSE;
+ g_dhcpv6_client_get_timeouts(dhcp->dhcp_client, NULL, &T2,
+ &last_rebind, NULL);
+ current = time(NULL);
+ if ((unsigned)current >= (unsigned)last_rebind + T2) {
+ /*
+ * Do rebind instead if past T2
+ */
+ start_rebind(dhcp);
+ return FALSE;
+ }
+
dhcp->RT = calc_delay(dhcp->RT, REN_MAX_RT);
DBG("renew RT timeout %d msec", dhcp->RT);
@@ -851,14 +1395,14 @@ static gboolean start_renew(gpointer user_data)
}
int __connman_dhcpv6_start_renew(struct connman_network *network,
- dhcp_cb callback)
+ dhcpv6_cb callback)
{
struct connman_dhcpv6 *dhcp;
uint32_t T1, T2;
- time_t last_renew, last_rebind, current, expired;
+ time_t started, current, expired;
dhcp = g_hash_table_lookup(network_table, network);
- if (dhcp == NULL)
+ if (!dhcp)
return -ENOENT;
DBG("network %p dhcp %p", network, dhcp);
@@ -866,12 +1410,12 @@ int __connman_dhcpv6_start_renew(struct connman_network *network,
clear_timer(dhcp);
g_dhcpv6_client_get_timeouts(dhcp->dhcp_client, &T1, &T2,
- &last_renew, &last_rebind, &expired);
+ &started, &expired);
current = time(NULL);
- DBG("T1 %u T2 %u expires %lu current %lu", T1, T2,
- (unsigned long)expired, current);
+ DBG("T1 %u T2 %u expires %lu current %lu started %lu", T1, T2,
+ (unsigned long)expired, current, started);
if (T1 == 0xffffffff)
/* RFC 3315, 22.4 */
@@ -883,35 +1427,34 @@ int __connman_dhcpv6_start_renew(struct connman_network *network,
*/
T1 = 1800;
+ dhcp->callback = callback;
+
/* RFC 3315, 18.1.4, start solicit if expired */
- if (current > expired) {
- DBG("expired by %d secs", (int)(current - expired));
- return -ETIMEDOUT;
- }
+ if (check_restart(dhcp) < 0)
+ return 0;
- dhcp->callback = callback;
+ if (T2 != 0xffffffff && T2 > 0) {
+ if ((unsigned)current >= (unsigned)started + T2) {
+ /* RFC 3315, chapter 18.1.3, start rebind */
+ DBG("rebind after %d secs", T2);
- if (T2 != 0xffffffff && T2 > 0 &&
- (unsigned)current > (unsigned)last_rebind + T2) {
- int timeout;
+ dhcp->timeout = g_timeout_add_seconds(T2, start_rebind,
+ dhcp);
- /* RFC 3315, chapter 18.1.3, start rebind */
- if ((unsigned)current > (unsigned)last_renew + T1)
- timeout = 0;
- else
- timeout = last_renew - current + T1;
+ } else if ((unsigned)current < (unsigned)started + T1) {
+ DBG("renew after %d secs", T1);
- /*
- * If we just did a renew, do not restart the rebind
- * immediately.
- */
- dhcp->timeout = g_timeout_add_seconds(timeout, start_rebind,
- dhcp);
- } else {
- DBG("renew after %d secs", T1);
+ dhcp->timeout = g_timeout_add_seconds(T1, start_renew,
+ dhcp);
+ } else {
+ DBG("rebind after %d secs", T2 - T1);
- dhcp->timeout = g_timeout_add_seconds(T1, start_renew, dhcp);
+ dhcp->timeout = g_timeout_add_seconds(T2 - T1,
+ start_rebind,
+ dhcp);
+ }
}
+
return 0;
}
@@ -921,28 +1464,28 @@ static void release_cb(GDHCPClient *dhcp_client, gpointer user_data)
}
int __connman_dhcpv6_start_release(struct connman_network *network,
- dhcp_cb callback)
+ dhcpv6_cb callback)
{
struct connman_dhcpv6 *dhcp;
GDHCPClient *dhcp_client;
- if (network_table == NULL)
+ if (!network_table)
return 0; /* we are already released */
dhcp = g_hash_table_lookup(network_table, network);
- if (dhcp == NULL)
+ if (!dhcp)
return -ENOENT;
DBG("network %p dhcp %p client %p stateless %d", network, dhcp,
dhcp->dhcp_client, dhcp->stateless);
- if (dhcp->stateless == TRUE)
+ if (dhcp->stateless)
return -EINVAL;
clear_timer(dhcp);
dhcp_client = dhcp->dhcp_client;
- if (dhcp_client == NULL) {
+ if (!dhcp_client) {
/*
* We had started the DHCPv6 handshaking i.e., we have called
* __connman_dhcpv6_start() but it has not yet sent
@@ -961,7 +1504,7 @@ int __connman_dhcpv6_start_release(struct connman_network *network,
g_dhcpv6_client_set_ia(dhcp_client,
connman_network_get_index(dhcp->network),
- dhcp->use_ta == TRUE ? G_DHCPV6_IA_TA : G_DHCPV6_IA_NA,
+ dhcp->use_ta ? G_DHCPV6_IA_TA : G_DHCPV6_IA_NA,
NULL, NULL, TRUE, NULL);
clear_callbacks(dhcp_client);
@@ -991,7 +1534,7 @@ static int dhcpv6_release(struct connman_dhcpv6 *dhcp)
dhcpv6_free(dhcp);
- if (dhcp->dhcp_client == NULL)
+ if (!dhcp->dhcp_client)
return 0;
g_dhcp_client_stop(dhcp->dhcp_client);
@@ -1047,27 +1590,27 @@ static gboolean start_info_req(gpointer user_data)
}
int __connman_dhcpv6_start_info(struct connman_network *network,
- dhcp_cb callback)
+ dhcpv6_cb callback)
{
struct connman_dhcpv6 *dhcp;
int delay;
DBG("");
- if (network_table != NULL) {
+ if (network_table) {
dhcp = g_hash_table_lookup(network_table, network);
- if (dhcp != NULL && dhcp->started == TRUE)
+ if (dhcp && dhcp->started)
return -EBUSY;
}
dhcp = g_try_new0(struct connman_dhcpv6, 1);
- if (dhcp == NULL)
+ if (!dhcp)
return -ENOMEM;
dhcp->network = network;
dhcp->callback = callback;
- dhcp->stateless = TRUE;
- dhcp->started = TRUE;
+ dhcp->stateless = true;
+ dhcp->started = true;
connman_network_ref(network);
@@ -1094,8 +1637,9 @@ static void advertise_cb(GDHCPClient *dhcp_client, gpointer user_data)
g_dhcpv6_client_clear_retransmit(dhcp_client);
if (g_dhcpv6_client_get_status(dhcp_client) != 0) {
- if (dhcp->callback != NULL)
- dhcp->callback(dhcp->network, FALSE);
+ if (dhcp->callback)
+ dhcp->callback(dhcp->network,
+ CONNMAN_DHCPV6_STATUS_FAIL, NULL);
return;
}
@@ -1105,7 +1649,7 @@ static void advertise_cb(GDHCPClient *dhcp_client, gpointer user_data)
dhcp->request_count = 1;
- dhcpv6_request(dhcp, TRUE);
+ dhcpv6_request(dhcp, true);
}
static void solicitation_cb(GDHCPClient *dhcp_client, gpointer user_data)
@@ -1117,7 +1661,7 @@ static void solicitation_cb(GDHCPClient *dhcp_client, gpointer user_data)
clear_timer(dhcp);
- set_addresses(dhcp_client, dhcp);
+ do_dad(dhcp_client, dhcp);
g_dhcpv6_client_clear_retransmit(dhcp_client);
}
@@ -1161,7 +1705,7 @@ static int dhcpv6_solicitation(struct connman_dhcpv6 *dhcp)
g_dhcp_client_set_debug(dhcp_client, dhcpv6_debug, "DHCPv6");
service = connman_service_lookup_from_network(dhcp->network);
- if (service == NULL) {
+ if (!service) {
clear_timer(dhcp);
g_dhcp_client_unref(dhcp_client);
return -EINVAL;
@@ -1187,7 +1731,7 @@ static int dhcpv6_solicitation(struct connman_dhcpv6 *dhcp)
dhcp->use_ta = __connman_ipconfig_ipv6_privacy_enabled(ipconfig_ipv6);
g_dhcpv6_client_set_ia(dhcp_client, index,
- dhcp->use_ta == TRUE ? G_DHCPV6_IA_TA : G_DHCPV6_IA_NA,
+ dhcp->use_ta ? G_DHCPV6_IA_TA : G_DHCPV6_IA_NA,
NULL, NULL, FALSE, NULL);
clear_callbacks(dhcp_client);
@@ -1230,8 +1774,6 @@ static void confirm_cb(GDHCPClient *dhcp_client, gpointer user_data)
clear_timer(dhcp);
- set_addresses(dhcp_client, dhcp);
-
g_dhcpv6_client_clear_retransmit(dhcp_client);
/*
@@ -1240,8 +1782,9 @@ static void confirm_cb(GDHCPClient *dhcp_client, gpointer user_data)
if (status != 0) {
g_dhcp_client_unref(dhcp->dhcp_client);
start_solicitation(dhcp);
- } else if (dhcp->callback != NULL)
- dhcp->callback(dhcp->network, TRUE);
+ } else {
+ do_dad(dhcp_client, dhcp);
+ }
}
static int dhcpv6_confirm(struct connman_dhcpv6 *dhcp)
@@ -1266,7 +1809,7 @@ static int dhcpv6_confirm(struct connman_dhcpv6 *dhcp)
g_dhcp_client_set_debug(dhcp_client, dhcpv6_debug, "DHCPv6");
service = connman_service_lookup_from_network(dhcp->network);
- if (service == NULL) {
+ if (!service) {
clear_timer(dhcp);
g_dhcp_client_unref(dhcp_client);
return -EINVAL;
@@ -1281,18 +1824,12 @@ static int dhcpv6_confirm(struct connman_dhcpv6 *dhcp)
g_dhcp_client_set_request(dhcp_client, G_DHCPV6_CLIENTID);
g_dhcp_client_set_request(dhcp_client, G_DHCPV6_RAPID_COMMIT);
- g_dhcp_client_set_request(dhcp_client, G_DHCPV6_DNS_SERVERS);
- g_dhcp_client_set_request(dhcp_client, G_DHCPV6_DOMAIN_LIST);
- g_dhcp_client_set_request(dhcp_client, G_DHCPV6_SNTP_SERVERS);
-
- g_dhcpv6_client_set_oro(dhcp_client, 3, G_DHCPV6_DNS_SERVERS,
- G_DHCPV6_DOMAIN_LIST, G_DHCPV6_SNTP_SERVERS);
ipconfig_ipv6 = __connman_service_get_ip6config(service);
dhcp->use_ta = __connman_ipconfig_ipv6_privacy_enabled(ipconfig_ipv6);
g_dhcpv6_client_set_ia(dhcp_client, index,
- dhcp->use_ta == TRUE ? G_DHCPV6_IA_TA : G_DHCPV6_IA_NA,
+ dhcp->use_ta ? G_DHCPV6_IA_TA : G_DHCPV6_IA_NA,
NULL, NULL, TRUE,
__connman_ipconfig_get_dhcp_address(ipconfig_ipv6));
@@ -1336,8 +1873,9 @@ static gboolean timeout_max_confirm(gpointer user_data)
g_dhcpv6_client_clear_retransmit(dhcp->dhcp_client);
- if (dhcp->callback != NULL)
- dhcp->callback(dhcp->network, FALSE);
+ if (dhcp->callback)
+ dhcp->callback(dhcp->network, CONNMAN_DHCPV6_STATUS_FAIL,
+ NULL);
return FALSE;
}
@@ -1360,7 +1898,7 @@ static gboolean start_confirm(gpointer user_data)
}
int __connman_dhcpv6_start(struct connman_network *network,
- GSList *prefixes, dhcp_cb callback)
+ GSList *prefixes, dhcpv6_cb callback)
{
struct connman_service *service;
struct connman_ipconfig *ipconfig_ipv6;
@@ -1370,24 +1908,24 @@ int __connman_dhcpv6_start(struct connman_network *network,
DBG("");
- if (network_table != NULL) {
+ if (network_table) {
dhcp = g_hash_table_lookup(network_table, network);
- if (dhcp != NULL && dhcp->started == TRUE)
+ if (dhcp && dhcp->started)
return -EBUSY;
}
service = connman_service_lookup_from_network(network);
- if (service == NULL)
+ if (!service)
return -EINVAL;
dhcp = g_try_new0(struct connman_dhcpv6, 1);
- if (dhcp == NULL)
+ if (!dhcp)
return -ENOMEM;
dhcp->network = network;
dhcp->callback = callback;
dhcp->prefixes = prefixes;
- dhcp->started = TRUE;
+ dhcp->started = true;
connman_network_ref(network);
@@ -1401,7 +1939,7 @@ int __connman_dhcpv6_start(struct connman_network *network,
ipconfig_ipv6 = __connman_service_get_ip6config(service);
last_address = __connman_ipconfig_get_dhcp_address(ipconfig_ipv6);
- if (prefixes != NULL && last_address != NULL &&
+ if (prefixes && last_address &&
check_ipv6_addr_prefix(prefixes,
last_address) != 128) {
/*
@@ -1424,10 +1962,810 @@ void __connman_dhcpv6_stop(struct connman_network *network)
{
DBG("");
- if (network_table == NULL)
+ if (!network_table)
return;
- if (g_hash_table_remove(network_table, network) == TRUE)
+ if (g_hash_table_remove(network_table, network))
+ connman_network_unref(network);
+}
+
+static int save_prefixes(struct connman_ipconfig *ipconfig,
+ GSList *prefixes)
+{
+ GSList *list;
+ int i = 0, count = g_slist_length(prefixes);
+ char **array;
+
+ if (count == 0)
+ return 0;
+
+ array = g_try_new0(char *, count + 1);
+ if (!array)
+ return -ENOMEM;
+
+ for (list = prefixes; list; list = list->next) {
+ char *elem, addr_str[INET6_ADDRSTRLEN];
+ GDHCPIAPrefix *prefix = list->data;
+
+ elem = g_strdup_printf("%s/%d", inet_ntop(AF_INET6,
+ &prefix->prefix, addr_str, INET6_ADDRSTRLEN),
+ prefix->prefixlen);
+ if (!elem) {
+ g_strfreev(array);
+ return -ENOMEM;
+ }
+
+ array[i++] = elem;
+ }
+
+ __connman_ipconfig_set_dhcpv6_prefixes(ipconfig, array);
+ return 0;
+}
+
+static GSList *load_prefixes(struct connman_ipconfig *ipconfig)
+{
+ int i;
+ GSList *list = NULL;
+ char **array = __connman_ipconfig_get_dhcpv6_prefixes(ipconfig);
+
+ if (!array)
+ return NULL;
+
+ for (i = 0; array[i]; i++) {
+ GDHCPIAPrefix *prefix;
+ long int value;
+ char *ptr, **elems = g_strsplit(array[i], "/", 0);
+
+ if (!elems)
+ return list;
+
+ value = strtol(elems[1], &ptr, 10);
+ if (ptr != elems[1] && *ptr == '\0' && value <= 128) {
+ struct in6_addr addr;
+
+ if (inet_pton(AF_INET6, elems[0], &addr) == 1) {
+ prefix = g_try_new0(GDHCPIAPrefix, 1);
+ if (!prefix) {
+ g_strfreev(elems);
+ return list;
+ }
+ memcpy(&prefix->prefix, &addr,
+ sizeof(struct in6_addr));
+ prefix->prefixlen = value;
+
+ list = g_slist_prepend(list, prefix);
+ }
+ }
+
+ g_strfreev(elems);
+ }
+
+ return list;
+}
+
+static GDHCPIAPrefix *copy_prefix(gpointer data)
+{
+ GDHCPIAPrefix *copy, *prefix = data;
+
+ copy = g_try_new(GDHCPIAPrefix, 1);
+ if (!copy)
+ return NULL;
+
+ memcpy(copy, prefix, sizeof(GDHCPIAPrefix));
+
+ return copy;
+}
+
+static GSList *copy_and_convert_prefixes(GList *prefixes)
+{
+ GSList *copy = NULL;
+ GList *list;
+
+ for (list = prefixes; list; list = list->next)
+ copy = g_slist_prepend(copy, copy_prefix(list->data));
+
+ return copy;
+}
+
+static int set_prefixes(GDHCPClient *dhcp_client, struct connman_dhcpv6 *dhcp)
+{
+ if (dhcp->prefixes)
+ g_slist_free_full(dhcp->prefixes, free_prefix);
+
+ dhcp->prefixes =
+ copy_and_convert_prefixes(g_dhcp_client_get_option(dhcp_client,
+ G_DHCPV6_IA_PD));
+
+ DBG("Got %d prefix", g_slist_length(dhcp->prefixes));
+
+ if (dhcp->callback) {
+ uint16_t status = g_dhcpv6_client_get_status(dhcp_client);
+ if (status == G_DHCPV6_ERROR_NO_PREFIX)
+ dhcp->callback(dhcp->network,
+ CONNMAN_DHCPV6_STATUS_FAIL, NULL);
+ else {
+ struct connman_service *service;
+ struct connman_ipconfig *ipconfig;
+ int ifindex = connman_network_get_index(dhcp->network);
+
+ service = __connman_service_lookup_from_index(ifindex);
+ if (service) {
+ ipconfig = __connman_service_get_ip6config(
+ service);
+ save_prefixes(ipconfig, dhcp->prefixes);
+ __connman_service_save(service);
+ }
+
+ dhcp->callback(dhcp->network,
+ CONNMAN_DHCPV6_STATUS_SUCCEED, dhcp->prefixes);
+ }
+ } else {
+ g_slist_free_full(dhcp->prefixes, free_prefix);
+ dhcp->prefixes = NULL;
+ }
+
+ return 0;
+}
+
+static void re_pd_cb(GDHCPClient *dhcp_client, gpointer user_data)
+{
+ struct connman_dhcpv6 *dhcp = user_data;
+ uint16_t status;
+ int ret;
+
+ status = g_dhcpv6_client_get_status(dhcp_client);
+
+ DBG("dhcpv6 cb msg %p status %d", dhcp, status);
+
+ if (status == G_DHCPV6_ERROR_BINDING) {
+ /* RFC 3315, 18.1.8 */
+ dhcpv6_pd_request(dhcp);
+ } else {
+ ret = set_prefixes(dhcp_client, dhcp);
+ if (ret < 0) {
+ if (dhcp->callback)
+ dhcp->callback(dhcp->network,
+ CONNMAN_DHCPV6_STATUS_FAIL, NULL);
+ return;
+ }
+ }
+}
+
+static void rebind_pd_cb(GDHCPClient *dhcp_client, gpointer user_data)
+{
+ DBG("");
+
+ g_dhcpv6_client_clear_retransmit(dhcp_client);
+
+ re_pd_cb(dhcp_client, user_data);
+}
+
+static GDHCPClient *create_pd_client(struct connman_dhcpv6 *dhcp, int *err)
+{
+ GDHCPClient *dhcp_client;
+ GDHCPClientError error;
+ struct connman_service *service;
+ int index, ret;
+ uint32_t iaid;
+
+ index = connman_network_get_index(dhcp->network);
+
+ dhcp_client = g_dhcp_client_new(G_DHCP_IPV6, index, &error);
+ if (error != G_DHCP_CLIENT_ERROR_NONE) {
+ *err = -EINVAL;
+ return NULL;
+ }
+
+ if (getenv("CONNMAN_DHCPV6_DEBUG"))
+ g_dhcp_client_set_debug(dhcp_client, dhcpv6_debug, "DHCPv6:PD");
+
+ service = connman_service_lookup_from_network(dhcp->network);
+ if (!service) {
+ g_dhcp_client_unref(dhcp_client);
+ *err = -EINVAL;
+ return NULL;
+ }
+
+ ret = set_duid(service, dhcp->network, dhcp_client, index);
+ if (ret < 0) {
+ g_dhcp_client_unref(dhcp_client);
+ *err = ret;
+ return NULL;
+ }
+
+ g_dhcpv6_client_create_iaid(dhcp_client, index, (unsigned char *)&iaid);
+ g_dhcpv6_client_set_iaid(dhcp_client, iaid);
+
+ return dhcp_client;
+}
+
+static int dhcpv6_pd_rebind(struct connman_dhcpv6 *dhcp)
+{
+ GDHCPClient *dhcp_client;
+ uint32_t T1, T2;
+
+ DBG("dhcp %p", dhcp);
+
+ if (!dhcp->dhcp_client) {
+ /*
+ * We skipped the solicitation phase
+ */
+ int err;
+
+ dhcp->dhcp_client = create_pd_client(dhcp, &err);
+ if (!dhcp->dhcp_client) {
+ clear_timer(dhcp);
+ return err;
+ }
+ }
+
+ dhcp_client = dhcp->dhcp_client;
+
+ g_dhcp_client_clear_requests(dhcp_client);
+
+ g_dhcp_client_set_request(dhcp_client, G_DHCPV6_CLIENTID);
+ g_dhcp_client_set_request(dhcp_client, G_DHCPV6_DNS_SERVERS);
+ g_dhcp_client_set_request(dhcp_client, G_DHCPV6_SNTP_SERVERS);
+
+ g_dhcpv6_client_get_timeouts(dhcp_client, &T1, &T2, NULL, NULL);
+ g_dhcpv6_client_set_pd(dhcp_client, &T1, &T2, dhcp->prefixes);
+
+ clear_callbacks(dhcp_client);
+
+ g_dhcp_client_register_event(dhcp_client, G_DHCP_CLIENT_EVENT_REBIND,
+ rebind_pd_cb, dhcp);
+
+ return g_dhcp_client_start(dhcp_client, NULL);
+}
+
+static void renew_pd_cb(GDHCPClient *dhcp_client, gpointer user_data)
+{
+ DBG("");
+
+ g_dhcpv6_client_clear_retransmit(dhcp_client);
+
+ re_pd_cb(dhcp_client, user_data);
+}
+
+static int dhcpv6_pd_renew(struct connman_dhcpv6 *dhcp)
+{
+ GDHCPClient *dhcp_client;
+ uint32_t T1, T2;
+
+ DBG("dhcp %p", dhcp);
+
+ dhcp_client = dhcp->dhcp_client;
+
+ g_dhcp_client_clear_requests(dhcp_client);
+
+ g_dhcp_client_set_request(dhcp_client, G_DHCPV6_CLIENTID);
+ g_dhcp_client_set_request(dhcp_client, G_DHCPV6_SERVERID);
+ g_dhcp_client_set_request(dhcp_client, G_DHCPV6_DNS_SERVERS);
+ g_dhcp_client_set_request(dhcp_client, G_DHCPV6_SNTP_SERVERS);
+
+ g_dhcpv6_client_get_timeouts(dhcp_client, &T1, &T2, NULL, NULL);
+ g_dhcpv6_client_set_pd(dhcp_client, &T1, &T2, dhcp->prefixes);
+
+ clear_callbacks(dhcp_client);
+
+ g_dhcp_client_register_event(dhcp_client, G_DHCP_CLIENT_EVENT_RENEW,
+ renew_pd_cb, dhcp);
+
+ return g_dhcp_client_start(dhcp_client, NULL);
+}
+
+/*
+ * Check if we need to restart the solicitation procedure. This
+ * is done if all the prefixes have expired.
+ */
+static int check_pd_restart(struct connman_dhcpv6 *dhcp)
+{
+ time_t current, expired;
+
+ g_dhcpv6_client_get_timeouts(dhcp->dhcp_client, NULL, NULL,
+ NULL, &expired);
+ current = time(NULL);
+
+ if (current > expired) {
+ DBG("expired by %d secs", (int)(current - expired));
+
+ g_timeout_add(0, dhcpv6_restart, dhcp);
+
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+
+static gboolean timeout_pd_rebind(gpointer user_data)
+{
+ struct connman_dhcpv6 *dhcp = user_data;
+
+ if (check_pd_restart(dhcp) < 0)
+ return FALSE;
+
+ dhcp->RT = calc_delay(dhcp->RT, REB_MAX_RT);
+
+ DBG("rebind RT timeout %d msec", dhcp->RT);
+
+ dhcp->timeout = g_timeout_add(dhcp->RT, timeout_pd_rebind, dhcp);
+
+ g_dhcpv6_client_set_retransmit(dhcp->dhcp_client);
+
+ g_dhcp_client_start(dhcp->dhcp_client, NULL);
+
+ return FALSE;
+}
+
+static gboolean start_pd_rebind(gpointer user_data)
+{
+ struct connman_dhcpv6 *dhcp = user_data;
+
+ if (check_pd_restart(dhcp) < 0)
+ return FALSE;
+
+ dhcp->RT = REB_TIMEOUT * (1 + get_random());
+
+ DBG("rebind initial RT timeout %d msec", dhcp->RT);
+
+ dhcp->timeout = g_timeout_add(dhcp->RT, timeout_pd_rebind, dhcp);
+
+ dhcpv6_pd_rebind(dhcp);
+
+ return FALSE;
+}
+
+static gboolean timeout_pd_rebind_confirm(gpointer user_data)
+{
+ struct connman_dhcpv6 *dhcp = user_data;
+
+ dhcp->RT = calc_delay(dhcp->RT, CNF_MAX_RT);
+
+ DBG("rebind with confirm RT timeout %d msec", dhcp->RT);
+
+ dhcp->timeout = g_timeout_add(dhcp->RT,
+ timeout_pd_rebind_confirm, dhcp);
+
+ g_dhcpv6_client_set_retransmit(dhcp->dhcp_client);
+
+ g_dhcp_client_start(dhcp->dhcp_client, NULL);
+
+ return FALSE;
+}
+
+static gboolean timeout_pd_max_confirm(gpointer user_data)
+{
+ struct connman_dhcpv6 *dhcp = user_data;
+
+ dhcp->MRD = 0;
+
+ clear_timer(dhcp);
+
+ DBG("rebind with confirm max retransmit duration timeout");
+
+ g_dhcpv6_client_clear_retransmit(dhcp->dhcp_client);
+
+ if (dhcp->callback)
+ dhcp->callback(dhcp->network,
+ CONNMAN_DHCPV6_STATUS_FAIL, NULL);
+
+ return FALSE;
+}
+
+static gboolean start_pd_rebind_with_confirm(gpointer user_data)
+{
+ struct connman_dhcpv6 *dhcp = user_data;
+
+ dhcp->RT = CNF_TIMEOUT * (1 + get_random());
+
+ DBG("rebind with confirm initial RT timeout %d msec", dhcp->RT);
+
+ dhcp->timeout = g_timeout_add(dhcp->RT,
+ timeout_pd_rebind_confirm, dhcp);
+ dhcp->MRD = g_timeout_add(CNF_MAX_RD, timeout_pd_max_confirm, dhcp);
+
+ dhcpv6_pd_rebind(dhcp);
+
+ return FALSE;
+}
+
+static gboolean timeout_pd_renew(gpointer user_data)
+{
+ struct connman_dhcpv6 *dhcp = user_data;
+
+ if (check_pd_restart(dhcp) < 0)
+ return FALSE;
+
+ dhcp->RT = calc_delay(dhcp->RT, REN_MAX_RT);
+
+ DBG("renew RT timeout %d msec", dhcp->RT);
+
+ dhcp->timeout = g_timeout_add(dhcp->RT, timeout_renew, dhcp);
+
+ g_dhcpv6_client_set_retransmit(dhcp->dhcp_client);
+
+ g_dhcp_client_start(dhcp->dhcp_client, NULL);
+
+ return FALSE;
+}
+
+static gboolean start_pd_renew(gpointer user_data)
+{
+ struct connman_dhcpv6 *dhcp = user_data;
+
+ dhcp->RT = REN_TIMEOUT * (1 + get_random());
+
+ DBG("renew initial RT timeout %d msec", dhcp->RT);
+
+ dhcp->timeout = g_timeout_add(dhcp->RT, timeout_pd_renew, dhcp);
+
+ dhcpv6_pd_renew(dhcp);
+
+ return FALSE;
+}
+
+int __connman_dhcpv6_start_pd_renew(struct connman_network *network,
+ dhcpv6_cb callback)
+{
+ struct connman_dhcpv6 *dhcp;
+ uint32_t T1, T2;
+ time_t started, current, expired;
+
+ dhcp = g_hash_table_lookup(network_pd_table, network);
+ if (!dhcp)
+ return -ENOENT;
+
+ DBG("network %p dhcp %p", network, dhcp);
+
+ clear_timer(dhcp);
+
+ g_dhcpv6_client_get_timeouts(dhcp->dhcp_client, &T1, &T2,
+ &started, &expired);
+
+ current = time(NULL);
+
+ DBG("T1 %u T2 %u expires %lu current %lu started %lu", T1, T2,
+ expired, current, started);
+
+ if (T1 == 0xffffffff)
+ /* RFC 3633, ch 9 */
+ return 0;
+
+ if (T1 == 0)
+ /* RFC 3633, ch 9
+ * Client can choose the timeout.
+ */
+ T1 = 120;
+
+ dhcp->callback = callback;
+
+ /* RFC 3315, 18.1.4, start solicit if expired */
+ if (check_pd_restart(dhcp) < 0)
+ return 0;
+
+ if (T2 != 0xffffffff && T2 > 0) {
+ if ((unsigned)current >= (unsigned)started + T2) {
+ /* RFC 3315, chapter 18.1.3, start rebind */
+ DBG("rebind after %d secs", T2);
+
+ dhcp->timeout = g_timeout_add_seconds(T2,
+ start_pd_rebind,
+ dhcp);
+
+ } else if ((unsigned)current < (unsigned)started + T1) {
+ DBG("renew after %d secs", T1);
+
+ dhcp->timeout = g_timeout_add_seconds(T1,
+ start_pd_renew,
+ dhcp);
+ } else {
+ DBG("rebind after %d secs", T2 - T1);
+
+ dhcp->timeout = g_timeout_add_seconds(T2 - T1,
+ start_pd_rebind,
+ dhcp);
+ }
+ }
+
+ return 0;
+}
+
+static void release_pd_cb(GDHCPClient *dhcp_client, gpointer user_data)
+{
+ DBG("");
+}
+
+int __connman_dhcpv6_start_pd_release(struct connman_network *network,
+ dhcpv6_cb callback)
+{
+ struct connman_dhcpv6 *dhcp;
+ GDHCPClient *dhcp_client;
+ uint32_t T1, T2;
+
+ if (!network_table)
+ return 0; /* we are already released */
+
+ dhcp = g_hash_table_lookup(network_pd_table, network);
+ if (!dhcp)
+ return -ENOENT;
+
+ DBG("network %p dhcp %p client %p", network, dhcp, dhcp->dhcp_client);
+
+ clear_timer(dhcp);
+
+ dhcp_client = dhcp->dhcp_client;
+ if (!dhcp_client) {
+ DBG("DHCPv6 PD was not started");
+ return 0;
+ }
+
+ g_dhcp_client_clear_requests(dhcp_client);
+ g_dhcp_client_clear_values(dhcp_client);
+
+ g_dhcp_client_set_request(dhcp_client, G_DHCPV6_CLIENTID);
+ g_dhcp_client_set_request(dhcp_client, G_DHCPV6_SERVERID);
+
+ g_dhcpv6_client_get_timeouts(dhcp_client, &T1, &T2, NULL, NULL);
+ g_dhcpv6_client_set_pd(dhcp_client, &T1, &T2, dhcp->prefixes);
+
+ clear_callbacks(dhcp_client);
+
+ g_dhcp_client_register_event(dhcp_client, G_DHCP_CLIENT_EVENT_RELEASE,
+ release_pd_cb, dhcp);
+
+ dhcp->dhcp_client = dhcp_client;
+
+ return g_dhcp_client_start(dhcp_client, NULL);
+}
+
+static gboolean timeout_pd_request(gpointer user_data)
+{
+ struct connman_dhcpv6 *dhcp = user_data;
+
+ if (dhcp->request_count >= REQ_MAX_RC) {
+ DBG("max request retry attempts %d", dhcp->request_count);
+ dhcp->request_count = 0;
+ if (dhcp->callback)
+ dhcp->callback(dhcp->network,
+ CONNMAN_DHCPV6_STATUS_FAIL, NULL);
+ return FALSE;
+ }
+
+ dhcp->request_count++;
+
+ dhcp->RT = calc_delay(dhcp->RT, REQ_MAX_RT);
+ DBG("request RT timeout %d msec", dhcp->RT);
+ dhcp->timeout = g_timeout_add(dhcp->RT, timeout_pd_request, dhcp);
+
+ g_dhcpv6_client_set_retransmit(dhcp->dhcp_client);
+
+ g_dhcp_client_start(dhcp->dhcp_client, NULL);
+
+ return FALSE;
+}
+
+static void request_pd_cb(GDHCPClient *dhcp_client, gpointer user_data)
+{
+ struct connman_dhcpv6 *dhcp = user_data;
+ uint16_t status;
+
+ DBG("");
+
+ g_dhcpv6_client_clear_retransmit(dhcp_client);
+
+ status = g_dhcpv6_client_get_status(dhcp_client);
+
+ DBG("dhcpv6 pd cb msg %p status %d", dhcp, status);
+
+ if (status == G_DHCPV6_ERROR_BINDING) {
+ /* RFC 3315, 18.1.8 */
+ dhcpv6_pd_request(dhcp);
+ } else {
+ set_prefixes(dhcp_client, dhcp);
+ }
+}
+
+static int dhcpv6_pd_request(struct connman_dhcpv6 *dhcp)
+{
+ GDHCPClient *dhcp_client;
+ uint32_t T1 = 0, T2 = 0;
+
+ DBG("dhcp %p", dhcp);
+
+ dhcp_client = dhcp->dhcp_client;
+
+ g_dhcp_client_clear_requests(dhcp_client);
+
+ g_dhcp_client_set_request(dhcp_client, G_DHCPV6_CLIENTID);
+ g_dhcp_client_set_request(dhcp_client, G_DHCPV6_SERVERID);
+ g_dhcp_client_set_request(dhcp_client, G_DHCPV6_DNS_SERVERS);
+ g_dhcp_client_set_request(dhcp_client, G_DHCPV6_SNTP_SERVERS);
+
+ g_dhcpv6_client_get_timeouts(dhcp_client, &T1, &T2, NULL, NULL);
+ g_dhcpv6_client_set_pd(dhcp_client, &T1, &T2, dhcp->prefixes);
+
+ clear_callbacks(dhcp_client);
+
+ g_dhcp_client_register_event(dhcp_client, G_DHCP_CLIENT_EVENT_REQUEST,
+ request_pd_cb, dhcp);
+
+ return g_dhcp_client_start(dhcp_client, NULL);
+}
+
+static void advertise_pd_cb(GDHCPClient *dhcp_client, gpointer user_data)
+{
+ struct connman_dhcpv6 *dhcp = user_data;
+
+ DBG("dhcpv6 advertise pd msg %p", dhcp);
+
+ clear_timer(dhcp);
+
+ g_dhcpv6_client_clear_retransmit(dhcp_client);
+
+ if (g_dhcpv6_client_get_status(dhcp_client) != 0) {
+ if (dhcp->callback)
+ dhcp->callback(dhcp->network,
+ CONNMAN_DHCPV6_STATUS_FAIL, NULL);
+ return;
+ }
+
+ dhcp->RT = REQ_TIMEOUT * (1 + get_random());
+ DBG("request initial RT timeout %d msec", dhcp->RT);
+ dhcp->timeout = g_timeout_add(dhcp->RT, timeout_pd_request, dhcp);
+
+ dhcp->request_count = 1;
+
+ dhcpv6_pd_request(dhcp);
+}
+
+static void solicitation_pd_cb(GDHCPClient *dhcp_client, gpointer user_data)
+{
+ /*
+ * This callback is here so that g_dhcp_client_start()
+ * will enter the proper L3 mode.
+ */
+ DBG("DHCPv6 %p solicitation msg received, ignoring it", user_data);
+}
+
+static int dhcpv6_pd_solicitation(struct connman_dhcpv6 *dhcp)
+{
+ GDHCPClient *dhcp_client;
+ int ret;
+
+ DBG("dhcp %p", dhcp);
+
+ dhcp_client = create_pd_client(dhcp, &ret);
+ if (!dhcp_client) {
+ clear_timer(dhcp);
+ return ret;
+ }
+
+ g_dhcp_client_set_request(dhcp_client, G_DHCPV6_CLIENTID);
+
+ g_dhcpv6_client_set_pd(dhcp_client, NULL, NULL, NULL);
+
+ clear_callbacks(dhcp_client);
+
+ g_dhcp_client_register_event(dhcp_client,
+ G_DHCP_CLIENT_EVENT_ADVERTISE,
+ advertise_pd_cb, dhcp);
+
+ g_dhcp_client_register_event(dhcp_client,
+ G_DHCP_CLIENT_EVENT_SOLICITATION,
+ solicitation_pd_cb, dhcp);
+
+ dhcp->dhcp_client = dhcp_client;
+
+ return g_dhcp_client_start(dhcp_client, NULL);
+}
+
+static gboolean start_pd_solicitation(gpointer user_data)
+{
+ struct connman_dhcpv6 *dhcp = user_data;
+
+ /* Set the retransmission timeout, RFC 3315 chapter 14 */
+ dhcp->RT = SOL_TIMEOUT * (1 + get_random());
+
+ DBG("solicit initial RT timeout %d msec", dhcp->RT);
+
+ dhcp->timeout = g_timeout_add(dhcp->RT, timeout_solicitation, dhcp);
+
+ dhcpv6_pd_solicitation(dhcp);
+
+ return FALSE;
+}
+
+int __connman_dhcpv6_start_pd(int index, GSList *prefixes, dhcpv6_cb callback)
+{
+ struct connman_service *service;
+ struct connman_network *network;
+ struct connman_dhcpv6 *dhcp;
+
+ if (index < 0)
+ return 0;
+
+ DBG("index %d", index);
+
+ service = __connman_service_lookup_from_index(index);
+ if (!service)
+ return -EINVAL;
+
+ network = __connman_service_get_network(service);
+ if (!network)
+ return -EINVAL;
+
+ if (network_pd_table) {
+ dhcp = g_hash_table_lookup(network_pd_table, network);
+ if (dhcp && dhcp->started)
+ return -EBUSY;
+ }
+
+ dhcp = g_try_new0(struct connman_dhcpv6, 1);
+ if (!dhcp)
+ return -ENOMEM;
+
+ dhcp->network = network;
+ dhcp->callback = callback;
+ dhcp->started = true;
+
+ if (!prefixes) {
+ /*
+ * Try to load the earlier prefixes if caller did not supply
+ * any that we could use.
+ */
+ struct connman_ipconfig *ipconfig;
+ ipconfig = __connman_service_get_ip6config(service);
+
+ dhcp->prefixes = load_prefixes(ipconfig);
+ } else
+ dhcp->prefixes = prefixes;
+
+ connman_network_ref(network);
+
+ DBG("replace network %p dhcp %p", network, dhcp);
+
+ g_hash_table_replace(network_pd_table, network, dhcp);
+
+ if (!dhcp->prefixes) {
+ /*
+ * Refresh start, try to get prefixes.
+ */
+ start_pd_solicitation(dhcp);
+ } else {
+ /*
+ * We used to have prefixes, try to use them again.
+ * We need to use timeouts from confirm msg, RFC 3633, ch 12.1
+ */
+ start_pd_rebind_with_confirm(dhcp);
+ }
+
+ return 0;
+}
+
+void __connman_dhcpv6_stop_pd(int index)
+{
+ struct connman_service *service;
+ struct connman_network *network;
+
+ if (index < 0)
+ return;
+
+ DBG("index %d", index);
+
+ if (!network_pd_table)
+ return;
+
+ service = __connman_service_lookup_from_index(index);
+ if (!service)
+ return;
+
+ network = __connman_service_get_network(service);
+ if (!network)
+ return;
+
+ __connman_dhcpv6_start_pd_release(network, NULL);
+
+ if (g_hash_table_remove(network_pd_table, network))
connman_network_unref(network);
}
@@ -1440,6 +2778,9 @@ int __connman_dhcpv6_init(void)
network_table = g_hash_table_new_full(g_direct_hash, g_direct_equal,
NULL, remove_network);
+ network_pd_table = g_hash_table_new_full(g_direct_hash, g_direct_equal,
+ NULL, remove_network);
+
return 0;
}
@@ -1449,4 +2790,7 @@ void __connman_dhcpv6_cleanup(void)
g_hash_table_destroy(network_table);
network_table = NULL;
+
+ g_hash_table_destroy(network_pd_table);
+ network_pd_table = NULL;
}
diff --git a/src/dnsproxy.c b/src/dnsproxy.c
index 9030a355..7232b987 100644
--- a/src/dnsproxy.c
+++ b/src/dnsproxy.c
@@ -2,7 +2,7 @@
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2014 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -93,8 +93,8 @@ struct server_data {
GIOChannel *channel;
guint watch;
guint timeout;
- gboolean enabled;
- gboolean connected;
+ bool enabled;
+ bool connected;
struct partial_reply *incoming_reply;
};
@@ -120,7 +120,7 @@ struct request_data {
gpointer resp;
gsize resplen;
struct listener_data *ifdata;
- gboolean append_domain;
+ bool append_domain;
};
struct listener_data {
@@ -164,7 +164,7 @@ struct cache_data {
struct cache_entry {
char *key;
- int want_refresh;
+ bool want_refresh;
int hits;
struct cache_data *ipv4;
struct cache_data *ipv6;
@@ -216,7 +216,7 @@ static GHashTable *listener_table = NULL;
static time_t next_refresh;
static GHashTable *partial_tcp_req_table;
-static guint16 get_id()
+static guint16 get_id(void)
{
return random();
}
@@ -283,16 +283,16 @@ static struct server_data *find_server(int index,
struct server_data *data = list->data;
if (index < 0 && data->index < 0 &&
- g_str_equal(data->server, server) == TRUE &&
+ g_str_equal(data->server, server) &&
data->protocol == protocol)
return data;
if (index < 0 ||
- data->index < 0 || data->server == NULL)
+ data->index < 0 || !data->server)
continue;
if (data->index == index &&
- g_str_equal(data->server, server) == TRUE &&
+ g_str_equal(data->server, server) &&
data->protocol == protocol)
return data;
}
@@ -315,26 +315,26 @@ static void refresh_dns_entry(struct cache_entry *entry, char *name)
{
int age = 1;
- if (ipv4_resolve == NULL) {
+ if (!ipv4_resolve) {
ipv4_resolve = g_resolv_new(0);
g_resolv_set_address_family(ipv4_resolve, AF_INET);
g_resolv_add_nameserver(ipv4_resolve, "127.0.0.1", 53, 0);
}
- if (ipv6_resolve == NULL) {
+ if (!ipv6_resolve) {
ipv6_resolve = g_resolv_new(0);
g_resolv_set_address_family(ipv6_resolve, AF_INET6);
g_resolv_add_nameserver(ipv6_resolve, "::1", 53, 0);
}
- if (entry->ipv4 == NULL) {
+ if (!entry->ipv4) {
DBG("Refresing A record for %s", name);
g_resolv_lookup_hostname(ipv4_resolve, name,
dummy_resolve_func, NULL);
age = 4;
}
- if (entry->ipv6 == NULL) {
+ if (!entry->ipv6) {
DBG("Refresing AAAA record for %s", name);
g_resolv_lookup_hostname(ipv6_resolve, name,
dummy_resolve_func, NULL);
@@ -505,7 +505,7 @@ static int get_req_udp_socket(struct request_data *req)
else
channel = req->ifdata->udp6_listener_channel;
- if (channel == NULL)
+ if (!channel)
return -1;
return g_io_channel_unix_get_fd(channel);
@@ -526,7 +526,7 @@ static gboolean request_timeout(gpointer user_data)
{
struct request_data *req = user_data;
- if (req == NULL)
+ if (!req)
return FALSE;
DBG("id 0x%04x", req->srcid);
@@ -534,7 +534,7 @@ static gboolean request_timeout(gpointer user_data)
request_list = g_slist_remove(request_list, req);
req->numserv--;
- if (req->resplen > 0 && req->resp != NULL) {
+ if (req->resplen > 0 && req->resp) {
int sk, err;
if (req->protocol == IPPROTO_UDP) {
@@ -599,11 +599,11 @@ static int append_query(unsigned char *buf, unsigned int size,
DBG("query %s domain %s", query, domain);
- while (query != NULL) {
+ while (query) {
const char *tmp;
tmp = strchr(query, '.');
- if (tmp == NULL) {
+ if (!tmp) {
len = strlen(query);
if (len == 0)
break;
@@ -620,11 +620,11 @@ static int append_query(unsigned char *buf, unsigned int size,
query = tmp + 1;
}
- while (domain != NULL) {
+ while (domain) {
const char *tmp;
tmp = strchr(domain, '.');
- if (tmp == NULL) {
+ if (!tmp) {
len = strlen(domain);
if (len == 0)
break;
@@ -646,16 +646,16 @@ static int append_query(unsigned char *buf, unsigned int size,
return ptr - buf;
}
-static gboolean cache_check_is_valid(struct cache_data *data,
+static bool cache_check_is_valid(struct cache_data *data,
time_t current_time)
{
- if (data == NULL)
- return FALSE;
+ if (!data)
+ return false;
if (data->cache_until < current_time)
- return FALSE;
+ return false;
- return TRUE;
+ return true;
}
/*
@@ -665,7 +665,7 @@ static void cache_enforce_validity(struct cache_entry *entry)
{
time_t current_time = time(NULL);
- if (cache_check_is_valid(entry->ipv4, current_time) == FALSE
+ if (!cache_check_is_valid(entry->ipv4, current_time)
&& entry->ipv4) {
DBG("cache timeout \"%s\" type A", entry->key);
g_free(entry->ipv4->data);
@@ -674,7 +674,7 @@ static void cache_enforce_validity(struct cache_entry *entry)
}
- if (cache_check_is_valid(entry->ipv6, current_time) == FALSE
+ if (!cache_check_is_valid(entry->ipv6, current_time)
&& entry->ipv6) {
DBG("cache timeout \"%s\" type AAAA", entry->key);
g_free(entry->ipv6->data);
@@ -687,32 +687,31 @@ static uint16_t cache_check_validity(char *question, uint16_t type,
struct cache_entry *entry)
{
time_t current_time = time(NULL);
- int want_refresh = 0;
+ bool want_refresh = false;
/*
* if we have a popular entry, we want a refresh instead of
* total destruction of the entry.
*/
if (entry->hits > 2)
- want_refresh = 1;
+ want_refresh = true;
cache_enforce_validity(entry);
switch (type) {
case 1: /* IPv4 */
- if (cache_check_is_valid(entry->ipv4, current_time) == FALSE) {
+ if (!cache_check_is_valid(entry->ipv4, current_time)) {
DBG("cache %s \"%s\" type A", entry->ipv4 ?
"timeout" : "entry missing", question);
if (want_refresh)
- entry->want_refresh = 1;
+ entry->want_refresh = true;
/*
* We do not remove cache entry if there is still
* valid IPv6 entry found in the cache.
*/
- if (cache_check_is_valid(entry->ipv6, current_time)
- == FALSE && want_refresh == FALSE) {
+ if (!cache_check_is_valid(entry->ipv6, current_time) && !want_refresh) {
g_hash_table_remove(cache, question);
type = 0;
}
@@ -720,15 +719,14 @@ static uint16_t cache_check_validity(char *question, uint16_t type,
break;
case 28: /* IPv6 */
- if (cache_check_is_valid(entry->ipv6, current_time) == FALSE) {
+ if (!cache_check_is_valid(entry->ipv6, current_time)) {
DBG("cache %s \"%s\" type AAAA", entry->ipv6 ?
"timeout" : "entry missing", question);
if (want_refresh)
- entry->want_refresh = 1;
+ entry->want_refresh = true;
- if (cache_check_is_valid(entry->ipv4, current_time)
- == FALSE && want_refresh == FALSE) {
+ if (!cache_check_is_valid(entry->ipv4, current_time) && !want_refresh) {
g_hash_table_remove(cache, question);
type = 0;
}
@@ -743,15 +741,15 @@ static void cache_element_destroy(gpointer value)
{
struct cache_entry *entry = value;
- if (entry == NULL)
+ if (!entry)
return;
- if (entry->ipv4 != NULL) {
+ if (entry->ipv4) {
g_free(entry->ipv4->data);
g_free(entry->ipv4);
}
- if (entry->ipv6 != NULL) {
+ if (entry->ipv6) {
g_free(entry->ipv6->data);
g_free(entry->ipv6);
}
@@ -775,7 +773,7 @@ static gboolean try_remove_cache(gpointer user_data)
return FALSE;
}
-static void create_cache()
+static void create_cache(void)
{
if (__sync_fetch_and_add(&cache_refcount, 1) == 0)
cache = g_hash_table_new_full(g_str_hash,
@@ -792,7 +790,7 @@ static struct cache_entry *cache_check(gpointer request, int *qtype, int proto)
uint16_t type;
int offset, proto_offset;
- if (request == NULL)
+ if (!request)
return NULL;
proto_offset = protocol_offset(proto);
@@ -809,13 +807,13 @@ static struct cache_entry *cache_check(gpointer request, int *qtype, int proto)
if (type != 1 && type != 28)
return NULL;
- if (cache == NULL) {
+ if (!cache) {
create_cache();
return NULL;
}
entry = g_hash_table_lookup(cache, question);
- if (entry == NULL)
+ if (!entry)
return NULL;
type = cache_check_validity(question, type, entry);
@@ -852,7 +850,7 @@ static int get_name(int counter,
if (offset >= max - pkt)
return -ENOBUFS;
- if (*end == NULL)
+ if (!*end)
*end = p + 2;
return get_name(counter + 1, pkt, pkt + offset, max,
@@ -882,7 +880,7 @@ static int get_name(int counter,
p += label_len + 1;
- if (*end == NULL)
+ if (!*end)
*end = p;
if (p >= max)
@@ -916,7 +914,7 @@ static int parse_rr(unsigned char *buf, unsigned char *start,
rr = (void *) (*end);
- if (rr == NULL)
+ if (!rr)
return -EINVAL;
*type = ntohs(rr->type);
@@ -944,19 +942,19 @@ static int parse_rr(unsigned char *buf, unsigned char *start,
return 0;
}
-static gboolean check_alias(GSList *aliases, char *name)
+static bool check_alias(GSList *aliases, char *name)
{
GSList *list;
- if (aliases != NULL) {
+ if (aliases) {
for (list = aliases; list; list = list->next) {
int len = strlen((char *)list->data);
if (strncmp((char *)list->data, name, len) == 0)
- return TRUE;
+ return true;
}
}
- return FALSE;
+ return false;
}
static int parse_response(unsigned char *buf, int buflen,
@@ -1007,6 +1005,8 @@ static int parse_response(unsigned char *buf, int buflen,
*response_len = 0;
*answers = 0;
+ memset(name, 0, sizeof(name));
+
/*
* We have a bunch of answers (like A, AAAA, CNAME etc) to
* A or AAAA question. We traverse the answers and parse the
@@ -1120,8 +1120,8 @@ static int parse_response(unsigned char *buf, int buflen,
/*
* We found correct type (A or AAAA)
*/
- if (check_alias(aliases, name) == TRUE ||
- (aliases == NULL && strncmp(question, name,
+ if (check_alias(aliases, name) ||
+ (!aliases && strncmp(question, name,
qlen) == 0)) {
/*
* We found an alias or the name of the rr
@@ -1176,7 +1176,7 @@ static gboolean cache_check_entry(gpointer key, gpointer value,
* remove both from the cache.
*/
- if (entry->ipv4 != NULL && entry->ipv4->timeout > 0) {
+ if (entry->ipv4 && entry->ipv4->timeout > 0) {
max_timeout = entry->ipv4->cache_until;
if (max_timeout > data->max_timeout)
data->max_timeout = max_timeout;
@@ -1185,7 +1185,7 @@ static gboolean cache_check_entry(gpointer key, gpointer value,
return TRUE;
}
- if (entry->ipv6 != NULL && entry->ipv6->timeout > 0) {
+ if (entry->ipv6 && entry->ipv6->timeout > 0) {
max_timeout = entry->ipv6->cache_until;
if (max_timeout > data->max_timeout)
data->max_timeout = max_timeout;
@@ -1257,7 +1257,7 @@ static gboolean cache_invalidate_entry(gpointer key, gpointer value,
/* if anything is not expired, mark the entry for refresh */
if (entry->hits > 0 && (entry->ipv4 || entry->ipv6))
- entry->want_refresh = 1;
+ entry->want_refresh = true;
/* delete the cached data */
if (entry->ipv4) {
@@ -1289,7 +1289,7 @@ static void cache_invalidate(void)
{
DBG("Invalidating the DNS cache %p", cache);
- if (cache == NULL)
+ if (!cache)
return;
g_hash_table_foreach_remove(cache, cache_invalidate_entry, NULL);
@@ -1300,15 +1300,15 @@ static void cache_refresh_entry(struct cache_entry *entry)
cache_enforce_validity(entry);
- if (entry->hits > 2 && entry->ipv4 == NULL)
- entry->want_refresh = 1;
- if (entry->hits > 2 && entry->ipv6 == NULL)
- entry->want_refresh = 1;
+ if (entry->hits > 2 && !entry->ipv4)
+ entry->want_refresh = true;
+ if (entry->hits > 2 && !entry->ipv6)
+ entry->want_refresh = true;
if (entry->want_refresh) {
char *c;
char dns_name[NS_MAXDNAME + 1];
- entry->want_refresh = 0;
+ entry->want_refresh = false;
/* turn a DNS name into a hostname with dots */
strncpy(dns_name, entry->key, NS_MAXDNAME);
@@ -1335,7 +1335,7 @@ static void cache_refresh_iterator(gpointer key, gpointer value,
static void cache_refresh(void)
{
- if (cache == NULL)
+ if (!cache)
return;
g_hash_table_foreach(cache, cache_refresh_iterator, NULL);
@@ -1378,7 +1378,7 @@ static int cache_update(struct server_data *srv, unsigned char *msg,
unsigned char response[NS_MAXDNAME + 1];
unsigned char *ptr;
unsigned int rsplen;
- gboolean new_entry = TRUE;
+ bool new_entry = true;
time_t current_time;
if (cache_size >= MAX_CACHE_SIZE) {
@@ -1404,6 +1404,9 @@ static int cache_update(struct server_data *srv, unsigned char *msg,
if (hdr->rcode != 0)
return 0;
+ if (!cache)
+ create_cache();
+
rsplen = sizeof(response) - 1;
question[sizeof(question) - 1] = '\0';
@@ -1420,16 +1423,12 @@ static int cache_update(struct server_data *srv, unsigned char *msg,
if ((err == -ENOMSG || err == -ENOBUFS) &&
reply_query_type(msg + offset,
msg_len - offset) == 28) {
- if (cache == NULL) {
- create_cache();
- entry = NULL;
- } else
- entry = g_hash_table_lookup(cache, question);
- if (entry && entry->ipv4 && entry->ipv6 == NULL) {
+ entry = g_hash_table_lookup(cache, question);
+ if (entry && entry->ipv4 && !entry->ipv6) {
int cache_offset = 0;
data = g_try_new(struct cache_data, 1);
- if (data == NULL)
+ if (!data)
return -ENOMEM;
data->inserted = entry->ipv4->inserted;
data->type = type;
@@ -1471,20 +1470,20 @@ static int cache_update(struct server_data *srv, unsigned char *msg,
* records for the same name.
*/
entry = g_hash_table_lookup(cache, question);
- if (entry == NULL) {
+ if (!entry) {
entry = g_try_new(struct cache_entry, 1);
- if (entry == NULL)
+ if (!entry)
return -ENOMEM;
data = g_try_new(struct cache_data, 1);
- if (data == NULL) {
+ if (!data) {
g_free(entry);
return -ENOMEM;
}
entry->key = g_strdup(question);
entry->ipv4 = entry->ipv6 = NULL;
- entry->want_refresh = 0;
+ entry->want_refresh = false;
entry->hits = 0;
if (type == 1)
@@ -1492,14 +1491,14 @@ static int cache_update(struct server_data *srv, unsigned char *msg,
else
entry->ipv6 = data;
} else {
- if (type == 1 && entry->ipv4 != NULL)
+ if (type == 1 && entry->ipv4)
return 0;
- if (type == 28 && entry->ipv6 != NULL)
+ if (type == 28 && entry->ipv6)
return 0;
data = g_try_new(struct cache_data, 1);
- if (data == NULL)
+ if (!data)
return -ENOMEM;
if (type == 1)
@@ -1515,7 +1514,7 @@ static int cache_update(struct server_data *srv, unsigned char *msg,
if (entry->hits < 0)
entry->hits = 0;
- new_entry = FALSE;
+ new_entry = false;
}
if (ttl < MIN_CACHE_TTL)
@@ -1543,7 +1542,7 @@ static int cache_update(struct server_data *srv, unsigned char *msg,
data->cache_until = round_down_ttl(current_time + ttl, ttl);
- if (data->data == NULL) {
+ if (!data->data) {
g_free(entry->key);
g_free(data);
g_free(entry);
@@ -1574,7 +1573,7 @@ static int cache_update(struct server_data *srv, unsigned char *msg,
memcpy(ptr + offset + 12 + qlen + 1 + sizeof(struct domain_question),
response, rsplen);
- if (new_entry == TRUE) {
+ if (new_entry) {
g_hash_table_replace(cache, entry->key, entry);
cache_size++;
}
@@ -1601,7 +1600,7 @@ static int ns_resolv(struct server_data *server, struct request_data *req,
struct cache_entry *entry;
entry = cache_check(request, &type, req->protocol);
- if (entry != NULL) {
+ if (entry) {
int ttl_left = 0;
struct cache_data *data;
@@ -1616,16 +1615,19 @@ static int ns_resolv(struct server_data *server, struct request_data *req,
entry->hits++;
}
- if (data != NULL && req->protocol == IPPROTO_TCP) {
+ if (data && req->protocol == IPPROTO_TCP) {
send_cached_response(req->client_sk, data->data,
data->data_len, NULL, 0, IPPROTO_TCP,
req->srcid, data->answers, ttl_left);
return 1;
}
- if (data != NULL && req->protocol == IPPROTO_UDP) {
+ if (data && req->protocol == IPPROTO_UDP) {
int udp_sk = get_req_udp_socket(req);
+ if (udp_sk < 0)
+ return -EIO;
+
send_cached_response(udp_sk, data->data,
data->data_len, &req->sa, req->sa_len,
IPPROTO_UDP, req->srcid, data->answers,
@@ -1650,11 +1652,11 @@ static int ns_resolv(struct server_data *server, struct request_data *req,
/* If we have more than one dot, we don't add domains */
dot = strchr(lookup, '.');
- if (dot != NULL && dot != lookup + strlen(lookup) - 1)
+ if (dot && dot != lookup + strlen(lookup) - 1)
return 0;
- if (server->domains != NULL && server->domains->data != NULL)
- req->append_domain = TRUE;
+ if (server->domains && server->domains->data)
+ req->append_domain = true;
for (list = server->domains; list; list = list->next) {
char *domain;
@@ -1664,7 +1666,7 @@ static int ns_resolv(struct server_data *server, struct request_data *req,
domain = list->data;
- if (domain == NULL)
+ if (!domain)
continue;
offset = protocol_offset(server->protocol);
@@ -1712,6 +1714,176 @@ static int ns_resolv(struct server_data *server, struct request_data *req,
return 0;
}
+static char *convert_label(char *start, char *end, char *ptr, char *uptr,
+ int remaining_len, int *used_comp, int *used_uncomp)
+{
+ int pos, comp_pos;
+ char name[NS_MAXLABEL];
+
+ pos = dn_expand((u_char *)start, (u_char *)end, (u_char *)ptr,
+ name, NS_MAXLABEL);
+ if (pos < 0) {
+ DBG("uncompress error [%d/%s]", errno, strerror(errno));
+ goto out;
+ }
+
+ /*
+ * We need to compress back the name so that we get back to internal
+ * label presentation.
+ */
+ comp_pos = dn_comp(name, (u_char *)uptr, remaining_len, NULL, NULL);
+ if (comp_pos < 0) {
+ DBG("compress error [%d/%s]", errno, strerror(errno));
+ goto out;
+ }
+
+ *used_comp = pos;
+ *used_uncomp = comp_pos;
+
+ return ptr;
+
+out:
+ return NULL;
+}
+
+static char *uncompress(int16_t field_count, char *start, char *end,
+ char *ptr, char *uncompressed, int uncomp_len,
+ char **uncompressed_ptr)
+{
+ char *uptr = *uncompressed_ptr; /* position in result buffer */
+
+ DBG("count %d ptr %p end %p uptr %p", field_count, ptr, end, uptr);
+
+ while (field_count-- > 0 && ptr < end) {
+ int dlen; /* data field length */
+ int ulen; /* uncompress length */
+ int pos; /* position in compressed string */
+ char name[NS_MAXLABEL]; /* tmp label */
+ uint16_t dns_type, dns_class;
+
+ pos = dn_expand((const u_char *)start, (u_char *)end,
+ (u_char *)ptr, name, NS_MAXLABEL);
+ if (pos < 0) {
+ DBG("uncompress error [%d/%s]", errno,
+ strerror(errno));
+ goto out;
+ }
+
+ /*
+ * Copy the uncompressed resource record, type, class and \0 to
+ * tmp buffer.
+ */
+
+ ulen = strlen(name);
+ *uptr++ = ulen;
+ strncpy(uptr, name, uncomp_len - (uptr - uncompressed));
+
+ DBG("pos %d ulen %d left %d name %s", pos, ulen,
+ (int)(uncomp_len - (uptr - uncompressed)), uptr);
+
+ uptr += ulen;
+ *uptr++ = '\0';
+
+ ptr += pos;
+
+ /*
+ * We copy also the fixed portion of the result (type, class,
+ * ttl, address length and the address)
+ */
+ memcpy(uptr, ptr, NS_RRFIXEDSZ);
+
+ dns_type = uptr[0] << 8 | uptr[1];
+ dns_class = uptr[2] << 8 | uptr[3];
+
+ if (dns_class != ns_c_in)
+ goto out;
+
+ ptr += NS_RRFIXEDSZ;
+ uptr += NS_RRFIXEDSZ;
+
+ /*
+ * Then the variable portion of the result (data length).
+ * Typically this portion is also compressed
+ * so we need to uncompress it also when necessary.
+ */
+ if (dns_type == ns_t_cname) {
+ int comp_pos;
+
+ if (!convert_label(start, end, ptr, uptr,
+ uncomp_len - (uptr - uncompressed),
+ &pos, &comp_pos))
+ goto out;
+
+ uptr[-2] = comp_pos << 8;
+ uptr[-1] = comp_pos & 0xff;
+
+ uptr += comp_pos;
+ ptr += pos;
+
+ } else if (dns_type == ns_t_a || dns_type == ns_t_aaaa) {
+ dlen = uptr[-2] << 8 | uptr[-1];
+
+ if (ptr + dlen > end) {
+ DBG("data len %d too long", dlen);
+ goto out;
+ }
+
+ memcpy(uptr, ptr, dlen);
+ uptr += dlen;
+ ptr += dlen;
+
+ } else if (dns_type == ns_t_soa) {
+ int comp_pos;
+ int total_len = 0;
+ char *len_ptr;
+
+ /* Primary name server expansion */
+ if (!convert_label(start, end, ptr, uptr,
+ uncomp_len - (uptr - uncompressed),
+ &pos, &comp_pos))
+ goto out;
+
+ total_len += comp_pos;
+ len_ptr = &uptr[-2];
+ ptr += pos;
+ uptr += comp_pos;
+
+ /* Responsible authority's mailbox */
+ if (!convert_label(start, end, ptr, uptr,
+ uncomp_len - (uptr - uncompressed),
+ &pos, &comp_pos))
+ goto out;
+
+ total_len += comp_pos;
+ ptr += pos;
+ uptr += comp_pos;
+
+ /*
+ * Copy rest of the soa fields (serial number,
+ * refresh interval, retry interval, expiration
+ * limit and minimum ttl). They are 20 bytes long.
+ */
+ memcpy(uptr, ptr, 20);
+ uptr += 20;
+ ptr += 20;
+ total_len += 20;
+
+ /*
+ * Finally fix the length of the data part
+ */
+ len_ptr[0] = total_len << 8;
+ len_ptr[1] = total_len & 0xff;
+ }
+
+ *uncompressed_ptr = uptr;
+ }
+
+ return ptr;
+
+out:
+ return NULL;
+}
+
static int forward_dns_reply(unsigned char *reply, int reply_len, int protocol,
struct server_data *data)
{
@@ -1728,7 +1900,7 @@ static int forward_dns_reply(unsigned char *reply, int reply_len, int protocol,
DBG("Received %d bytes (id 0x%04x)", reply_len, dns_id);
req = find_request(dns_id);
- if (req == NULL)
+ if (!req)
return -EINVAL;
DBG("req %p dstid 0x%04x altid 0x%04x rcode %d",
@@ -1739,70 +1911,163 @@ static int forward_dns_reply(unsigned char *reply, int reply_len, int protocol,
req->numresp++;
- if (hdr->rcode == 0 || req->resp == NULL) {
+ if (hdr->rcode == 0 || !req->resp) {
+ unsigned char *new_reply = NULL;
/*
* If the domain name was append
* remove it before forwarding the reply.
+ * If there were more than one question, then this
+ * domain name ripping can be hairy so avoid that
+ * and bail out in that that case.
+ *
+ * The reason we are doing this magic is that if the
+ * user's DNS client tries to resolv hostname without
+ * domain part, it also expects to get the result without
+ * a domain name part.
*/
- if (req->append_domain == TRUE) {
- unsigned int domain_len = 0;
- unsigned char *ptr;
- uint8_t host_len;
- unsigned int header_len;
+ if (req->append_domain && ntohs(hdr->qdcount) == 1) {
+ uint16_t domain_len = 0;
+ uint16_t header_len;
+ uint16_t dns_type, dns_class;
+ uint8_t host_len, dns_type_pos;
+ char uncompressed[NS_MAXDNAME], *uptr;
+ char *ptr, *eom = (char *)reply + reply_len;
/*
* ptr points to the first char of the hostname.
* ->hostname.domain.net
*/
header_len = offset + sizeof(struct domain_hdr);
- ptr = reply + header_len;
+ ptr = (char *)reply + header_len;
+
host_len = *ptr;
if (host_len > 0)
- domain_len = strnlen((const char *)ptr + 1 +
- host_len,
+ domain_len = strnlen(ptr + 1 + host_len,
reply_len - header_len);
-
- DBG("host len %d domain len %d", host_len, domain_len);
+ /*
+ * If the query type is anything other than A or AAAA,
+ * then bail out and pass the message as is.
+ * We only want to deal with IPv4 or IPv6 addresses.
+ */
+ dns_type_pos = host_len + 1 + domain_len + 1;
+
+ dns_type = ptr[dns_type_pos] << 8 |
+ ptr[dns_type_pos + 1];
+ dns_class = ptr[dns_type_pos + 2] << 8 |
+ ptr[dns_type_pos + 3];
+ if (dns_type != ns_t_a && dns_type != ns_t_aaaa &&
+ dns_class != ns_c_in) {
+ DBG("Pass msg dns type %d class %d",
+ dns_type, dns_class);
+ goto pass;
+ }
/*
* Remove the domain name and replace it by the end
* of reply. Check if the domain is really there
- * before trying to copy the data. The domain_len can
- * be 0 because if the original query did not contain
- * a domain name, then we are sending two packets,
- * first without the domain name and the second packet
- * with domain name. The append_domain is set to true
- * even if we sent the first packet without domain
- * name. In this case we end up in this branch.
+ * before trying to copy the data. We also need to
+ * uncompress the answers if necessary.
+ * The domain_len can be 0 because if the original
+ * query did not contain a domain name, then we are
+ * sending two packets, first without the domain name
+ * and the second packet with domain name.
+ * The append_domain is set to true even if we sent
+ * the first packet without domain name. In this
+ * case we end up in this branch.
*/
if (domain_len > 0) {
+ int len = host_len + 1;
+
+ /*
+ * First copy host (without domain name) into
+ * tmp buffer.
+ */
+ uptr = &uncompressed[0];
+ memcpy(uptr, ptr, len);
+
+ uptr[len] = '\0'; /* host termination */
+ uptr += len + 1;
+
+ /*
+ * Copy type and class fields of the question.
+ */
+ ptr += len + domain_len + 1;
+ memcpy(uptr, ptr, NS_QFIXEDSZ);
+
+ /*
+ * ptr points to answers after this
+ */
+ ptr += NS_QFIXEDSZ;
+ uptr += NS_QFIXEDSZ;
+
+ /*
+ * We then uncompress the result to buffer
+ * so that we can rip off the domain name
+ * part from the question. First answers,
+ * then name server (authority) information,
+ * and finally additional record info.
+ */
+
+ ptr = uncompress(ntohs(hdr->ancount),
+ (char *)reply + offset, eom,
+ ptr, uncompressed, NS_MAXDNAME,
+ &uptr);
+ if (ptr == NULL)
+ goto out;
+
+ ptr = uncompress(ntohs(hdr->nscount),
+ (char *)reply + offset, eom,
+ ptr, uncompressed, NS_MAXDNAME,
+ &uptr);
+ if (ptr == NULL)
+ goto out;
+
+ ptr = uncompress(ntohs(hdr->arcount),
+ (char *)reply + offset, eom,
+ ptr, uncompressed, NS_MAXDNAME,
+ &uptr);
+ if (ptr == NULL)
+ goto out;
+
/*
- * Note that we must use memmove() here,
- * because the memory areas can overlap.
+ * Because we have now uncompressed the answers
+ * we must create a bigger buffer to hold all
+ * that data.
*/
- memmove(ptr + host_len + 1,
- ptr + host_len + domain_len + 1,
- reply_len - header_len - domain_len);
- reply_len = reply_len - domain_len;
+ new_reply = g_try_malloc(header_len +
+ uptr - uncompressed);
+ if (!new_reply)
+ return -ENOMEM;
+
+ memcpy(new_reply, reply, header_len);
+ memcpy(new_reply + header_len, uncompressed,
+ uptr - uncompressed);
+
+ reply = new_reply;
+ reply_len = header_len + uptr - uncompressed;
}
}
+ pass:
g_free(req->resp);
req->resplen = 0;
req->resp = g_try_malloc(reply_len);
- if (req->resp == NULL)
+ if (!req->resp)
return -ENOMEM;
memcpy(req->resp, reply, reply_len);
req->resplen = reply_len;
cache_update(data, reply, reply_len);
+
+ g_free(new_reply);
}
+out:
if (hdr->rcode > 0 && req->numresp < req->numserv)
return -EINVAL;
@@ -1810,8 +2075,12 @@ static int forward_dns_reply(unsigned char *reply, int reply_len, int protocol,
if (protocol == IPPROTO_UDP) {
sk = get_req_udp_socket(req);
- err = sendto(sk, req->resp, req->resplen, 0,
- &req->sa, req->sa_len);
+ if (sk < 0) {
+ errno = -EIO;
+ err = -EIO;
+ } else
+ err = sendto(sk, req->resp, req->resplen, 0,
+ &req->sa, req->sa_len);
} else {
sk = req->client_sk;
err = send(sk, req->resp, req->resplen, MSG_NOSIGNAL);
@@ -1843,7 +2112,7 @@ static void server_destroy_socket(struct server_data *data)
data->timeout = 0;
}
- if (data->channel != NULL) {
+ if (data->channel) {
g_io_channel_shutdown(data->channel, TRUE, NULL);
g_io_channel_unref(data->channel);
data->channel = NULL;
@@ -1855,10 +2124,8 @@ static void server_destroy_socket(struct server_data *data)
static void destroy_server(struct server_data *server)
{
- GList *list;
-
DBG("index %d server %s sock %d", server->index, server->server,
- server->channel != NULL ?
+ server->channel ?
g_io_channel_unix_get_fd(server->channel): -1);
server_list = g_slist_remove(server_list, server);
@@ -1868,12 +2135,7 @@ static void destroy_server(struct server_data *server)
DBG("Removing DNS server %s", server->server);
g_free(server->server);
- for (list = server->domains; list; list = list->next) {
- char *domain = list->data;
-
- server->domains = g_list_remove(server->domains, domain);
- g_free(domain);
- }
+ g_list_free_full(server->domains, g_free);
g_free(server->server_addr);
/*
@@ -1945,7 +2207,7 @@ hangup:
if (req->protocol == IPPROTO_UDP)
continue;
- if (req->request == NULL)
+ if (!req->request)
continue;
/*
@@ -1972,12 +2234,12 @@ hangup:
if ((condition & G_IO_OUT) && !server->connected) {
GSList *list;
GList *domains;
- int no_request_sent = TRUE;
+ bool no_request_sent = true;
struct server_data *udp_server;
udp_server = find_server(server->index, server->server,
IPPROTO_UDP);
- if (udp_server != NULL) {
+ if (udp_server) {
for (domains = udp_server->domains; domains;
domains = domains->next) {
char *dom = domains->data;
@@ -1990,7 +2252,7 @@ hangup:
}
}
- server->connected = TRUE;
+ server->connected = true;
server_list = g_slist_append(server_list, server);
if (server->timeout > 0) {
@@ -2027,7 +2289,7 @@ hangup:
continue;
}
- no_request_sent = FALSE;
+ no_request_sent = false;
if (req->timeout > 0)
g_source_remove(req->timeout);
@@ -2037,7 +2299,7 @@ hangup:
list = list->next;
}
- if (no_request_sent == TRUE) {
+ if (no_request_sent) {
destroy_server(server);
return FALSE;
}
@@ -2115,7 +2377,7 @@ static gboolean tcp_idle_timeout(gpointer user_data)
DBG("");
- if (server == NULL)
+ if (!server)
return FALSE;
destroy_server(server);
@@ -2145,7 +2407,7 @@ static int server_create_socket(struct server_data *data)
DBG("sk %d", sk);
interface = connman_inet_ifname(data->index);
- if (interface != NULL) {
+ if (interface) {
if (setsockopt(sk, SOL_SOCKET, SO_BINDTODEVICE,
interface,
strlen(interface) + 1) < 0) {
@@ -2162,7 +2424,7 @@ static int server_create_socket(struct server_data *data)
}
data->channel = g_io_channel_unix_new(sk);
- if (data->channel == NULL) {
+ if (!data->channel) {
connman_error("Failed to create server %s channel",
data->server);
close(sk);
@@ -2213,7 +2475,7 @@ static struct server_data *create_server(int index,
DBG("index %d server %s", index, server);
data = g_try_new0(struct server_data, 1);
- if (data == NULL) {
+ if (!data) {
connman_error("Failed to allocate server %s data", server);
return NULL;
}
@@ -2269,7 +2531,7 @@ static struct server_data *create_server(int index,
connman_error("Wrong address family %d", rp->ai_family);
break;
}
- if (data->server_addr == NULL) {
+ if (!data->server_addr) {
freeaddrinfo(rp);
destroy_server(data);
return NULL;
@@ -2283,9 +2545,12 @@ static struct server_data *create_server(int index,
}
if (protocol == IPPROTO_UDP) {
- /* Enable new servers by default */
- data->enabled = TRUE;
- DBG("Adding DNS server %s", data->server);
+ if (__connman_service_index_is_default(data->index) ||
+ __connman_service_index_is_split_routing(
+ data->index)) {
+ data->enabled = true;
+ DBG("Adding DNS server %s", data->server);
+ }
server_list = g_slist_append(server_list, data);
}
@@ -2293,7 +2558,7 @@ static struct server_data *create_server(int index,
return data;
}
-static gboolean resolv(struct request_data *req,
+static bool resolv(struct request_data *req,
gpointer request, gpointer name)
{
GSList *list;
@@ -2308,10 +2573,10 @@ static gboolean resolv(struct request_data *req,
DBG("server %s enabled %d", data->server, data->enabled);
- if (data->enabled == FALSE)
+ if (!data->enabled)
continue;
- if (data->channel == NULL && data->protocol == IPPROTO_UDP) {
+ if (!data->channel && data->protocol == IPPROTO_UDP) {
if (server_create_socket(data) < 0) {
DBG("socket creation failed while resolving");
continue;
@@ -2319,10 +2584,10 @@ static gboolean resolv(struct request_data *req,
}
if (ns_resolv(data, req, request, name) > 0)
- return TRUE;
+ return true;
}
- return FALSE;
+ return false;
}
static void append_domain(int index, const char *domain)
@@ -2331,14 +2596,14 @@ static void append_domain(int index, const char *domain)
DBG("index %d domain %s", index, domain);
- if (domain == NULL)
+ if (!domain)
return;
for (list = server_list; list; list = list->next) {
struct server_data *data = list->data;
GList *dom_list;
char *dom;
- gboolean dom_found = FALSE;
+ bool dom_found = false;
if (data->index < 0)
continue;
@@ -2351,12 +2616,12 @@ static void append_domain(int index, const char *domain)
dom = dom_list->data;
if (g_str_equal(dom, domain)) {
- dom_found = TRUE;
+ dom_found = true;
break;
}
}
- if (dom_found == FALSE) {
+ if (!dom_found) {
data->domains =
g_list_append(data->domains, g_strdup(domain));
}
@@ -2370,29 +2635,29 @@ int __connman_dnsproxy_append(int index, const char *domain,
DBG("index %d server %s", index, server);
- if (server == NULL && domain == NULL)
+ if (!server && !domain)
return -EINVAL;
- if (server == NULL) {
+ if (!server) {
append_domain(index, domain);
return 0;
}
- if (g_str_equal(server, "127.0.0.1") == TRUE)
+ if (g_str_equal(server, "127.0.0.1"))
return -ENODEV;
- if (g_str_equal(server, "::1") == TRUE)
+ if (g_str_equal(server, "::1"))
return -ENODEV;
data = find_server(index, server, IPPROTO_UDP);
- if (data != NULL) {
+ if (data) {
append_domain(index, domain);
return 0;
}
data = create_server(index, domain, server, IPPROTO_UDP);
- if (data == NULL)
+ if (!data)
return -EIO;
return 0;
@@ -2404,7 +2669,7 @@ static void remove_server(int index, const char *domain,
struct server_data *data;
data = find_server(index, server, protocol);
- if (data == NULL)
+ if (!data)
return;
destroy_server(data);
@@ -2415,13 +2680,13 @@ int __connman_dnsproxy_remove(int index, const char *domain,
{
DBG("index %d server %s", index, server);
- if (server == NULL)
+ if (!server)
return -EINVAL;
- if (g_str_equal(server, "127.0.0.1") == TRUE)
+ if (g_str_equal(server, "127.0.0.1"))
return -ENODEV;
- if (g_str_equal(server, "::1") == TRUE)
+ if (g_str_equal(server, "::1"))
return -ENODEV;
remove_server(index, domain, server, IPPROTO_UDP);
@@ -2440,7 +2705,7 @@ void __connman_dnsproxy_flush(void)
list = list->next;
- if (resolv(req, req->request, req->name) == TRUE) {
+ if (resolv(req, req->request, req->name)) {
/*
* A cached result was sent,
* so the request can be released
@@ -2457,7 +2722,7 @@ void __connman_dnsproxy_flush(void)
}
}
-static void dnsproxy_offline_mode(connman_bool_t enabled)
+static void dnsproxy_offline_mode(bool enabled)
{
GSList *list;
@@ -2466,14 +2731,14 @@ static void dnsproxy_offline_mode(connman_bool_t enabled)
for (list = server_list; list; list = list->next) {
struct server_data *data = list->data;
- if (enabled == FALSE) {
+ if (!enabled) {
DBG("Enabling DNS server %s", data->server);
- data->enabled = TRUE;
+ data->enabled = true;
cache_invalidate();
cache_refresh();
} else {
DBG("Disabling DNS server %s", data->server);
- data->enabled = FALSE;
+ data->enabled = false;
cache_invalidate();
}
}
@@ -2489,9 +2754,9 @@ static void dnsproxy_default_changed(struct connman_service *service)
/* DNS has changed, invalidate the cache */
cache_invalidate();
- if (service == NULL) {
+ if (!service) {
/* When no services are active, then disable DNS proxying */
- dnsproxy_offline_mode(TRUE);
+ dnsproxy_offline_mode(true);
return;
}
@@ -2504,10 +2769,10 @@ static void dnsproxy_default_changed(struct connman_service *service)
if (data->index == index) {
DBG("Enabling DNS server %s", data->server);
- data->enabled = TRUE;
+ data->enabled = true;
} else {
DBG("Disabling DNS server %s", data->server);
- data->enabled = FALSE;
+ data->enabled = false;
}
}
@@ -2596,10 +2861,10 @@ static int parse_request(unsigned char *buf, int len,
static void client_reset(struct tcp_partial_client_data *client)
{
- if (client == NULL)
+ if (!client)
return;
- if (client->channel != NULL) {
+ if (client->channel) {
DBG("client %d closing",
g_io_channel_unix_get_fd(client->channel));
@@ -2628,7 +2893,7 @@ static unsigned int get_msg_len(unsigned char *buf)
return buf[0]<<8 | buf[1];
}
-static gboolean read_tcp_data(struct tcp_partial_client_data *client,
+static bool read_tcp_data(struct tcp_partial_client_data *client,
void *client_addr, socklen_t client_addr_len,
int read_len)
{
@@ -2637,7 +2902,8 @@ static gboolean read_tcp_data(struct tcp_partial_client_data *client,
int client_sk, err;
unsigned int msg_len;
GSList *list;
- int waiting_for_connect = FALSE, qtype = 0;
+ bool waiting_for_connect = false;
+ int qtype = 0;
struct cache_entry *entry;
client_sk = g_io_channel_unix_get_fd(client->channel);
@@ -2647,7 +2913,7 @@ static gboolean read_tcp_data(struct tcp_partial_client_data *client,
client_sk, client->buf_end);
g_hash_table_remove(partial_tcp_req_table,
GINT_TO_POINTER(client_sk));
- return FALSE;
+ return false;
}
DBG("client %d received %d bytes", client_sk, read_len);
@@ -2655,14 +2921,14 @@ static gboolean read_tcp_data(struct tcp_partial_client_data *client,
client->buf_end += read_len;
if (client->buf_end < 2)
- return TRUE;
+ return true;
msg_len = get_msg_len(client->buf);
if (msg_len > TCP_MAX_BUF_LEN) {
DBG("client %d sent too much data %d", client_sk, msg_len);
g_hash_table_remove(partial_tcp_req_table,
GINT_TO_POINTER(client_sk));
- return FALSE;
+ return false;
}
read_another:
@@ -2673,7 +2939,7 @@ read_another:
DBG("client %d still missing %d bytes",
client_sk,
msg_len + 2 - client->buf_end);
- return TRUE;
+ return true;
}
DBG("client %d all data %d received", client_sk, msg_len);
@@ -2683,12 +2949,12 @@ read_another:
if (err < 0 || (g_slist_length(server_list) == 0)) {
send_response(client_sk, client->buf, msg_len + 2,
NULL, 0, IPPROTO_TCP);
- return TRUE;
+ return true;
}
req = g_try_new0(struct request_data, 1);
- if (req == NULL)
- return TRUE;
+ if (!req)
+ return true;
memcpy(&req->sa, client_addr, client_addr_len);
req->sa_len = client_addr_len;
@@ -2706,14 +2972,14 @@ read_another:
req->numserv = 0;
req->ifdata = client->ifdata;
- req->append_domain = FALSE;
+ req->append_domain = false;
/*
* Check if the answer is found in the cache before
* creating sockets to the server.
*/
entry = cache_check(client->buf, &qtype, IPPROTO_TCP);
- if (entry != NULL) {
+ if (entry) {
int ttl_left = 0;
struct cache_data *data;
@@ -2723,7 +2989,7 @@ read_another:
else
data = entry->ipv6;
- if (data != NULL) {
+ if (data) {
ttl_left = data->valid_until - time(NULL);
entry->hits++;
@@ -2740,22 +3006,22 @@ read_another:
for (list = server_list; list; list = list->next) {
struct server_data *data = list->data;
- if (data->protocol != IPPROTO_UDP || data->enabled == FALSE)
+ if (data->protocol != IPPROTO_UDP || !data->enabled)
continue;
- if(create_server(data->index, NULL,
- data->server, IPPROTO_TCP) == NULL)
+ if (!create_server(data->index, NULL, data->server,
+ IPPROTO_TCP))
continue;
- waiting_for_connect = TRUE;
+ waiting_for_connect = true;
}
- if (waiting_for_connect == FALSE) {
+ if (!waiting_for_connect) {
/* No server is waiting for connect */
send_response(client_sk, client->buf,
req->request_len, NULL, 0, IPPROTO_TCP);
g_free(req);
- return TRUE;
+ return true;
}
/*
@@ -2765,7 +3031,7 @@ read_another:
* properly connected over TCP to the nameserver.
*/
req->request = g_try_malloc0(req->request_len);
- if (req->request == NULL) {
+ if (!req->request) {
send_response(client_sk, client->buf,
req->request_len, NULL, 0, IPPROTO_TCP);
g_free(req);
@@ -2774,7 +3040,7 @@ read_another:
memcpy(req->request, client->buf, req->request_len);
req->name = g_try_malloc0(sizeof(query));
- if (req->name == NULL) {
+ if (!req->name) {
send_response(client_sk, client->buf,
req->request_len, NULL, 0, IPPROTO_TCP);
g_free(req->request);
@@ -2824,7 +3090,7 @@ out:
client->timeout = 0;
}
- return TRUE;
+ return true;
}
static gboolean tcp_client_event(GIOChannel *channel, GIOCondition condition,
@@ -2896,7 +3162,7 @@ static gboolean client_timeout(gpointer user_data)
return FALSE;
}
-static gboolean tcp_listener_event(GIOChannel *channel, GIOCondition condition,
+static bool tcp_listener_event(GIOChannel *channel, GIOCondition condition,
struct listener_data *ifdata, int family,
guint *listener_watch)
{
@@ -2922,7 +3188,7 @@ static gboolean tcp_listener_event(GIOChannel *channel, GIOCondition condition,
connman_error("Error with TCP listener channel");
- return FALSE;
+ return false;
}
sk = g_io_channel_unix_get_fd(channel);
@@ -2945,23 +3211,25 @@ static gboolean tcp_listener_event(GIOChannel *channel, GIOCondition condition,
DBG("client %d accepted", client_sk);
} else {
DBG("No data to read from master %d, waiting.", sk);
- return TRUE;
+ return true;
}
if (client_sk < 0) {
connman_error("Accept failure on TCP listener");
*listener_watch = 0;
- return FALSE;
+ return false;
}
fcntl(client_sk, F_SETFL, O_NONBLOCK);
client = g_hash_table_lookup(partial_tcp_req_table,
GINT_TO_POINTER(client_sk));
- if (client == NULL) {
+ if (!client) {
client = g_try_new0(struct tcp_partial_client_data, 1);
- if (client == NULL)
- return FALSE;
+ if (!client) {
+ close(client_sk);
+ return false;
+ }
g_hash_table_insert(partial_tcp_req_table,
GINT_TO_POINTER(client_sk),
@@ -2981,10 +3249,10 @@ static gboolean tcp_listener_event(GIOChannel *channel, GIOCondition condition,
DBG("client %d already exists %p", client_sk, client);
}
- if (client->buf == NULL) {
+ if (!client->buf) {
client->buf = g_try_malloc(TCP_MAX_BUF_LEN);
- if (client->buf == NULL)
- return FALSE;
+ if (!client->buf)
+ return false;
}
memset(client->buf, 0, TCP_MAX_BUF_LEN);
client->buf_end = 0;
@@ -3003,20 +3271,20 @@ static gboolean tcp_listener_event(GIOChannel *channel, GIOCondition condition,
if (len < 0) {
if (errno == EAGAIN || errno == EWOULDBLOCK) {
DBG("client %d no data to read, waiting", client_sk);
- return TRUE;
+ return true;
}
DBG("client %d cannot read errno %d/%s", client_sk, -errno,
strerror(errno));
g_hash_table_remove(partial_tcp_req_table,
GINT_TO_POINTER(client_sk));
- return TRUE;
+ return true;
}
if (len < 2) {
DBG("client %d not enough data to read, waiting", client_sk);
client->buf_end += len;
- return TRUE;
+ return true;
}
msg_len = get_msg_len(client->buf);
@@ -3025,7 +3293,7 @@ static gboolean tcp_listener_event(GIOChannel *channel, GIOCondition condition,
client_sk, msg_len);
g_hash_table_remove(partial_tcp_req_table,
GINT_TO_POINTER(client_sk));
- return TRUE;
+ return true;
}
/*
@@ -3037,7 +3305,7 @@ static gboolean tcp_listener_event(GIOChannel *channel, GIOCondition condition,
client_sk, len, msg_len + 2, msg_len + 2 - len);
client->buf_end += len;
- return TRUE;
+ return true;
}
return read_tcp_data(client, client_addr, *client_addr_len, len);
@@ -3061,7 +3329,7 @@ static gboolean tcp6_listener_event(GIOChannel *channel, GIOCondition condition,
&ifdata->tcp6_listener_watch);
}
-static gboolean udp_listener_event(GIOChannel *channel, GIOCondition condition,
+static bool udp_listener_event(GIOChannel *channel, GIOCondition condition,
struct listener_data *ifdata, int family,
guint *listener_watch)
{
@@ -3079,7 +3347,7 @@ static gboolean udp_listener_event(GIOChannel *channel, GIOCondition condition,
if (condition & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
connman_error("Error with UDP listener channel");
*listener_watch = 0;
- return FALSE;
+ return false;
}
sk = g_io_channel_unix_get_fd(channel);
@@ -3095,7 +3363,7 @@ static gboolean udp_listener_event(GIOChannel *channel, GIOCondition condition,
memset(client_addr, 0, *client_addr_len);
len = recvfrom(sk, buf, sizeof(buf), 0, client_addr, client_addr_len);
if (len < 2)
- return TRUE;
+ return true;
DBG("Received %d bytes (id 0x%04x)", len, buf[0] | buf[1] << 8);
@@ -3103,12 +3371,12 @@ static gboolean udp_listener_event(GIOChannel *channel, GIOCondition condition,
if (err < 0 || (g_slist_length(server_list) == 0)) {
send_response(sk, buf, len, client_addr,
*client_addr_len, IPPROTO_UDP);
- return TRUE;
+ return true;
}
req = g_try_new0(struct request_data, 1);
- if (req == NULL)
- return TRUE;
+ if (!req)
+ return true;
memcpy(&req->sa, client_addr, *client_addr_len);
req->sa_len = *client_addr_len;
@@ -3126,18 +3394,18 @@ static gboolean udp_listener_event(GIOChannel *channel, GIOCondition condition,
req->numserv = 0;
req->ifdata = ifdata;
- req->append_domain = FALSE;
+ req->append_domain = false;
- if (resolv(req, buf, query) == TRUE) {
+ if (resolv(req, buf, query)) {
/* a cached result was sent, so the request can be released */
g_free(req);
- return TRUE;
+ return true;
}
req->timeout = g_timeout_add_seconds(5, request_timeout, req);
request_list = g_slist_append(request_list, req);
- return TRUE;
+ return true;
}
static gboolean udp4_listener_event(GIOChannel *channel, GIOCondition condition,
@@ -3200,7 +3468,7 @@ static GIOChannel *get_listener(int family, int protocol, int index)
}
interface = connman_inet_ifname(index);
- if (interface == NULL || setsockopt(sk, SOL_SOCKET, SO_BINDTODEVICE,
+ if (!interface || setsockopt(sk, SOL_SOCKET, SO_BINDTODEVICE,
interface,
strlen(interface) + 1) < 0) {
connman_error("Failed to bind %s listener interface "
@@ -3266,7 +3534,7 @@ static GIOChannel *get_listener(int family, int protocol, int index)
}
channel = g_io_channel_unix_new(sk);
- if (channel == NULL) {
+ if (!channel) {
connman_error("Failed to create %s listener channel", proto);
close(sk);
return NULL;
@@ -3293,7 +3561,7 @@ static int create_dns_listener(int protocol, struct listener_data *ifdata)
if (protocol == IPPROTO_TCP) {
ifdata->tcp4_listener_channel = get_listener(AF_INET, protocol,
ifdata->index);
- if (ifdata->tcp4_listener_channel != NULL)
+ if (ifdata->tcp4_listener_channel)
ifdata->tcp4_listener_watch =
g_io_add_watch(ifdata->tcp4_listener_channel,
G_IO_IN, tcp4_listener_event,
@@ -3303,7 +3571,7 @@ static int create_dns_listener(int protocol, struct listener_data *ifdata)
ifdata->tcp6_listener_channel = get_listener(AF_INET6, protocol,
ifdata->index);
- if (ifdata->tcp6_listener_channel != NULL)
+ if (ifdata->tcp6_listener_channel)
ifdata->tcp6_listener_watch =
g_io_add_watch(ifdata->tcp6_listener_channel,
G_IO_IN, tcp6_listener_event,
@@ -3313,7 +3581,7 @@ static int create_dns_listener(int protocol, struct listener_data *ifdata)
} else {
ifdata->udp4_listener_channel = get_listener(AF_INET, protocol,
ifdata->index);
- if (ifdata->udp4_listener_channel != NULL)
+ if (ifdata->udp4_listener_channel)
ifdata->udp4_listener_watch =
g_io_add_watch(ifdata->udp4_listener_channel,
G_IO_IN, udp4_listener_event,
@@ -3323,7 +3591,7 @@ static int create_dns_listener(int protocol, struct listener_data *ifdata)
ifdata->udp6_listener_channel = get_listener(AF_INET6, protocol,
ifdata->index);
- if (ifdata->udp6_listener_channel != NULL)
+ if (ifdata->udp6_listener_channel)
ifdata->udp6_listener_watch =
g_io_add_watch(ifdata->udp6_listener_channel,
G_IO_IN, udp6_listener_event,
@@ -3345,9 +3613,9 @@ static void destroy_udp_listener(struct listener_data *ifdata)
if (ifdata->udp6_listener_watch > 0)
g_source_remove(ifdata->udp6_listener_watch);
- if (ifdata->udp4_listener_channel != NULL)
+ if (ifdata->udp4_listener_channel)
g_io_channel_unref(ifdata->udp4_listener_channel);
- if (ifdata->udp6_listener_channel != NULL)
+ if (ifdata->udp6_listener_channel)
g_io_channel_unref(ifdata->udp6_listener_channel);
}
@@ -3360,9 +3628,9 @@ static void destroy_tcp_listener(struct listener_data *ifdata)
if (ifdata->tcp6_listener_watch > 0)
g_source_remove(ifdata->tcp6_listener_watch);
- if (ifdata->tcp4_listener_channel != NULL)
+ if (ifdata->tcp4_listener_channel)
g_io_channel_unref(ifdata->tcp4_listener_channel);
- if (ifdata->tcp6_listener_channel != NULL)
+ if (ifdata->tcp6_listener_channel)
g_io_channel_unref(ifdata->tcp6_listener_channel);
}
@@ -3429,14 +3697,14 @@ int __connman_dnsproxy_add_listener(int index)
if (index < 0)
return -EINVAL;
- if (listener_table == NULL)
+ if (!listener_table)
return -ENOENT;
- if (g_hash_table_lookup(listener_table, GINT_TO_POINTER(index)) != NULL)
+ if (g_hash_table_lookup(listener_table, GINT_TO_POINTER(index)))
return 0;
ifdata = g_try_new0(struct listener_data, 1);
- if (ifdata == NULL)
+ if (!ifdata)
return -ENOMEM;
ifdata->index = index;
@@ -3467,11 +3735,11 @@ void __connman_dnsproxy_remove_listener(int index)
DBG("index %d", index);
- if (listener_table == NULL)
+ if (!listener_table)
return;
ifdata = g_hash_table_lookup(listener_table, GINT_TO_POINTER(index));
- if (ifdata == NULL)
+ if (!ifdata)
return;
destroy_listener(ifdata);
diff --git a/src/eduroam.config b/src/eduroam.config
new file mode 100644
index 00000000..768b7b40
--- /dev/null
+++ b/src/eduroam.config
@@ -0,0 +1,5 @@
+[service_eduroam]
+Type = wifi
+Name = eduroam
+EAP = peap
+Phase2 = MSCHAPV2
diff --git a/src/error.c b/src/error.c
index 955b4b88..4f24ae25 100644
--- a/src/error.c
+++ b/src/error.c
@@ -2,7 +2,7 @@
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2013 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/src/firewall.c b/src/firewall.c
index c235d861..90c3d3c1 100644
--- a/src/firewall.c
+++ b/src/firewall.c
@@ -57,6 +57,8 @@ struct firewall_context {
static GSList *managed_tables;
+static bool firewall_is_up;
+
static int chain_to_index(const char *chain_name)
{
if (!g_strcmp0(builtin_chains[NF_IP_PRE_ROUTING], chain_name))
@@ -75,7 +77,7 @@ static int chain_to_index(const char *chain_name)
static int managed_chain_to_index(const char *chain_name)
{
- if (g_str_has_prefix(chain_name, CHAIN_PREFIX) == FALSE)
+ if (!g_str_has_prefix(chain_name, CHAIN_PREFIX))
return -1;
return chain_to_index(chain_name + strlen(CHAIN_PREFIX));
@@ -146,7 +148,7 @@ static int insert_managed_rule(const char *table_name,
goto out;
}
- for (list = managed_tables; list != NULL; list = list->next) {
+ for (list = managed_tables; list; list = list->next) {
mtable = list->data;
if (g_strcmp0(mtable->name, table_name) == 0)
@@ -155,7 +157,7 @@ static int insert_managed_rule(const char *table_name,
mtable = NULL;
}
- if (mtable == NULL) {
+ if (!mtable) {
mtable = g_new0(struct connman_managed_table, 1);
mtable->name = g_strdup(table_name);
@@ -203,7 +205,7 @@ static int delete_managed_rule(const char *table_name,
err = __connman_iptables_delete(table_name, managed_chain,
rule_spec);
- for (list = managed_tables; list != NULL; list = list->next) {
+ for (list = managed_tables; list; list = list->next) {
mtable = list->data;
if (g_strcmp0(mtable->name, table_name) == 0)
@@ -212,7 +214,7 @@ static int delete_managed_rule(const char *table_name,
mtable = NULL;
}
- if (mtable == NULL) {
+ if (!mtable) {
err = -ENOENT;
goto out;
}
@@ -297,7 +299,7 @@ static int firewall_disable(GList *rules)
GList *list;
int err;
- for (list = rules; list != NULL; list = g_list_previous(list)) {
+ for (list = rules; list; list = g_list_previous(list)) {
rule = list->data;
err = delete_managed_rule(rule->table,
@@ -325,7 +327,7 @@ int __connman_firewall_enable(struct firewall_context *ctx)
GList *list;
int err;
- for (list = g_list_first(ctx->rules); list != NULL;
+ for (list = g_list_first(ctx->rules); list;
list = g_list_next(list)) {
rule = list->data;
@@ -341,6 +343,8 @@ int __connman_firewall_enable(struct firewall_context *ctx)
goto err;
}
+ firewall_is_up = true;
+
return 0;
err:
@@ -356,6 +360,11 @@ int __connman_firewall_disable(struct firewall_context *ctx)
return firewall_disable(g_list_last(ctx->rules));
}
+bool __connman_firewall_is_up(void)
+{
+ return firewall_is_up;
+}
+
static void iterate_chains_cb(const char *chain_name, void *user_data)
{
GSList **chains = user_data;
@@ -377,7 +386,7 @@ static void flush_table(const char *table_name)
__connman_iptables_iterate_chains(table_name, iterate_chains_cb,
&chains);
- for (list = chains; list != NULL; list = list->next) {
+ for (list = chains; list; list = list->next) {
id = GPOINTER_TO_INT(list->data);
managed_chain = g_strdup_printf("%s%s", CHAIN_PREFIX,
@@ -417,7 +426,17 @@ static void flush_table(const char *table_name)
static void flush_all_tables(void)
{
- /* Flush the tables ConnMan might have modified */
+ /* Flush the tables ConnMan might have modified
+ * But do so if only ConnMan has done something with
+ * iptables */
+
+ if (!g_file_test("/proc/net/ip_tables_names",
+ G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) {
+ firewall_is_up = false;
+ return;
+ }
+
+ firewall_is_up = true;
flush_table("filter");
flush_table("mangle");
diff --git a/src/inet.c b/src/inet.c
index 51965760..61116297 100644
--- a/src/inet.c
+++ b/src/inet.c
@@ -2,7 +2,7 @@
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2013 Intel Corporation. All rights reserved.
* Copyright (C) 2003-2005 Go-Core Project
* Copyright (C) 2003-2006 Helsinki University of Technology
*
@@ -46,8 +46,10 @@
#include <linux/if_tun.h>
#include <ctype.h>
#include <ifaddrs.h>
+#include <linux/fib_rules.h>
#include "connman.h"
+#include <gdhcp/gdhcp.h>
#define NLMSG_TAIL(nmsg) \
((struct rtattr *) (((uint8_t*) (nmsg)) + \
@@ -96,7 +98,7 @@ int __connman_inet_modify_address(int cmd, int flags,
"prefixlen %hhu broadcast %s", cmd, flags, index, family,
address, peer, prefixlen, broadcast);
- if (address == NULL)
+ if (!address)
return -EINVAL;
if (family != AF_INET && family != AF_INET6)
@@ -121,13 +123,13 @@ int __connman_inet_modify_address(int cmd, int flags,
if (inet_pton(AF_INET, address, &ipv4_addr) < 1)
return -1;
- if (broadcast != NULL)
+ if (broadcast)
inet_pton(AF_INET, broadcast, &ipv4_bcast);
else
ipv4_bcast.s_addr = ipv4_addr.s_addr |
htonl(0xfffffffflu >> prefixlen);
- if (peer != NULL) {
+ if (peer) {
if (inet_pton(AF_INET, peer, &ipv4_dest) < 1)
return -1;
@@ -193,7 +195,7 @@ int connman_inet_ifindex(const char *name)
struct ifreq ifr;
int sk, err;
- if (name == NULL)
+ if (!name)
return -1;
sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
@@ -201,7 +203,7 @@ int connman_inet_ifindex(const char *name)
return -1;
memset(&ifr, 0, sizeof(ifr));
- strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
+ strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name) - 1);
err = ioctl(sk, SIOCGIFINDEX, &ifr);
@@ -334,7 +336,7 @@ int connman_inet_ifdown(int index)
}
memset(&addr_ifr, 0, sizeof(addr_ifr));
- memcpy(&addr_ifr.ifr_name, &ifr.ifr_name, sizeof(ifr.ifr_name));
+ memcpy(&addr_ifr.ifr_name, &ifr.ifr_name, sizeof(ifr.ifr_name) - 1);
addr = (struct sockaddr_in *)&addr_ifr.ifr_addr;
addr->sin_family = AF_INET;
if (ioctl(sk, SIOCSIFADDR, &addr_ifr) < 0)
@@ -358,9 +360,9 @@ done:
return err;
}
-connman_bool_t connman_inet_is_cfg80211(int index)
+bool connman_inet_is_cfg80211(int index)
{
- connman_bool_t result = FALSE;
+ bool result = false;
char phy80211_path[PATH_MAX];
struct stat st;
struct ifreq ifr;
@@ -368,7 +370,7 @@ connman_bool_t connman_inet_is_cfg80211(int index)
sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
if (sk < 0)
- return FALSE;
+ return false;
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_ifindex = index;
@@ -380,7 +382,7 @@ connman_bool_t connman_inet_is_cfg80211(int index)
"/sys/class/net/%s/phy80211", ifr.ifr_name);
if (stat(phy80211_path, &st) == 0 && (st.st_mode & S_IFDIR))
- result = TRUE;
+ result = true;
done:
close(sk);
@@ -401,7 +403,7 @@ int connman_inet_set_ipv6_address(int index,
unsigned char prefix_len;
const char *address;
- if (ipaddress->local == NULL)
+ if (!ipaddress->local)
return 0;
prefix_len = ipaddress->prefixlen;
@@ -426,7 +428,7 @@ int connman_inet_set_address(int index, struct connman_ipaddress *ipaddress)
unsigned char prefix_len;
const char *address, *broadcast, *peer;
- if (ipaddress->local == NULL)
+ if (!ipaddress->local)
return -1;
prefix_len = ipaddress->prefixlen;
@@ -454,6 +456,9 @@ int connman_inet_clear_ipv6_address(int index, const char *address,
DBG("index %d address %s prefix_len %d", index, address, prefix_len);
+ if (!address)
+ return -EINVAL;
+
err = __connman_inet_modify_address(RTM_DELADDR, 0, index, AF_INET6,
address, NULL, prefix_len, NULL);
if (err < 0) {
@@ -477,6 +482,9 @@ int connman_inet_clear_address(int index, struct connman_ipaddress *ipaddress)
DBG("index %d address %s prefix_len %d", index, address, prefix_len);
+ if (!address)
+ return -EINVAL;
+
err = __connman_inet_modify_address(RTM_DELADDR, 0, index, AF_INET,
address, peer, prefix_len, broadcast);
if (err < 0) {
@@ -529,9 +537,9 @@ int connman_inet_add_network_route(int index, const char *host,
memset(&rt, 0, sizeof(rt));
rt.rt_flags = RTF_UP;
- if (gateway != NULL)
+ if (gateway)
rt.rt_flags |= RTF_GATEWAY;
- if (netmask == NULL)
+ if (!netmask)
rt.rt_flags |= RTF_HOST;
memset(&addr, 0, sizeof(addr));
@@ -541,7 +549,7 @@ int connman_inet_add_network_route(int index, const char *host,
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
- if (gateway != NULL)
+ if (gateway)
addr.sin_addr.s_addr = inet_addr(gateway);
else
addr.sin_addr.s_addr = INADDR_ANY;
@@ -550,7 +558,7 @@ int connman_inet_add_network_route(int index, const char *host,
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
- if (netmask != NULL)
+ if (netmask)
addr.sin_addr.s_addr = inet_addr(netmask);
else
addr.sin_addr.s_addr = INADDR_ANY;
@@ -628,7 +636,7 @@ int connman_inet_del_ipv6_network_route(int index, const char *host,
DBG("index %d host %s", index, host);
- if (host == NULL)
+ if (!host)
return -EINVAL;
memset(&rt, 0, sizeof(rt));
@@ -678,7 +686,7 @@ int connman_inet_add_ipv6_network_route(int index, const char *host,
DBG("index %d host %s gateway %s", index, host, gateway);
- if (host == NULL)
+ if (!host)
return -EINVAL;
memset(&rt, 0, sizeof(rt));
@@ -692,7 +700,7 @@ int connman_inet_add_ipv6_network_route(int index, const char *host,
rt.rtmsg_flags = RTF_UP | RTF_HOST;
- if (gateway != NULL) {
+ if (gateway) {
rt.rtmsg_flags |= RTF_GATEWAY;
inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway);
}
@@ -725,47 +733,6 @@ int connman_inet_add_ipv6_host_route(int index, const char *host,
return connman_inet_add_ipv6_network_route(index, host, gateway, 128);
}
-int connman_inet_set_ipv6_gateway_address(int index, const char *gateway)
-{
- struct in6_rtmsg rt;
- int sk, err = 0;
-
- DBG("index %d gateway %s", index, gateway);
-
- if (gateway == NULL)
- return -EINVAL;
-
- memset(&rt, 0, sizeof(rt));
-
- if (inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway) < 0) {
- err = -errno;
- goto out;
- }
-
- rt.rtmsg_flags = RTF_UP | RTF_GATEWAY;
- rt.rtmsg_metric = 1;
- rt.rtmsg_dst_len = 0;
- rt.rtmsg_ifindex = index;
-
- sk = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
- if (sk < 0) {
- err = -errno;
- goto out;
- }
-
- if (ioctl(sk, SIOCADDRT, &rt) < 0 && errno != EEXIST)
- err = -errno;
-
- close(sk);
-
-out:
- if (err < 0)
- connman_error("Set default IPv6 gateway error (%s)",
- strerror(-err));
-
- return err;
-}
-
int connman_inet_clear_ipv6_gateway_address(int index, const char *gateway)
{
struct in6_rtmsg rt;
@@ -773,7 +740,7 @@ int connman_inet_clear_ipv6_gateway_address(int index, const char *gateway)
DBG("index %d gateway %s", index, gateway);
- if (gateway == NULL)
+ if (!gateway)
return -EINVAL;
memset(&rt, 0, sizeof(rt));
@@ -807,63 +774,6 @@ out:
return err;
}
-int connman_inet_set_gateway_address(int index, const char *gateway)
-{
- struct ifreq ifr;
- struct rtentry rt;
- struct sockaddr_in addr;
- int sk, err = 0;
-
- DBG("index %d gateway %s", index, gateway);
-
- sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
- if (sk < 0) {
- err = -errno;
- goto out;
- }
-
- memset(&ifr, 0, sizeof(ifr));
- ifr.ifr_ifindex = index;
-
- if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
- err = -errno;
- close(sk);
- goto out;
- }
-
- DBG("ifname %s", ifr.ifr_name);
-
- memset(&rt, 0, sizeof(rt));
- rt.rt_flags = RTF_UP | RTF_GATEWAY;
-
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = INADDR_ANY;
- memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
-
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = inet_addr(gateway);
- memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
-
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = INADDR_ANY;
- memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
-
- if (ioctl(sk, SIOCADDRT, &rt) < 0 && errno != EEXIST)
- err = -errno;
-
- close(sk);
-
-out:
- if (err < 0)
- connman_error("Setting default gateway route failed (%s)",
- strerror(-err));
-
- return err;
-}
-
int connman_inet_set_gateway_interface(int index)
{
struct ifreq ifr;
@@ -1131,7 +1041,7 @@ out:
return err;
}
-connman_bool_t connman_inet_compare_subnet(int index, const char *host)
+bool connman_inet_compare_subnet(int index, const char *host)
{
struct ifreq ifr;
struct in_addr _host_addr;
@@ -1141,8 +1051,8 @@ connman_bool_t connman_inet_compare_subnet(int index, const char *host)
DBG("host %s", host);
- if (host == NULL)
- return FALSE;
+ if (!host)
+ return false;
if (inet_aton(host, &_host_addr) == 0)
return -1;
@@ -1150,19 +1060,19 @@ connman_bool_t connman_inet_compare_subnet(int index, const char *host)
sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
if (sk < 0)
- return FALSE;
+ return false;
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_ifindex = index;
if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
close(sk);
- return FALSE;
+ return false;
}
if (ioctl(sk, SIOCGIFNETMASK, &ifr) < 0) {
close(sk);
- return FALSE;
+ return false;
}
netmask = (struct sockaddr_in *)&ifr.ifr_netmask;
@@ -1170,7 +1080,7 @@ connman_bool_t connman_inet_compare_subnet(int index, const char *host)
if (ioctl(sk, SIOCGIFADDR, &ifr) < 0) {
close(sk);
- return FALSE;
+ return false;
}
close(sk);
@@ -1186,7 +1096,7 @@ int connman_inet_remove_from_bridge(int index, const char *bridge)
struct ifreq ifr;
int sk, err = 0;
- if (bridge == NULL)
+ if (!bridge)
return -EINVAL;
sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
@@ -1196,7 +1106,7 @@ int connman_inet_remove_from_bridge(int index, const char *bridge)
}
memset(&ifr, 0, sizeof(ifr));
- strncpy(ifr.ifr_name, bridge, IFNAMSIZ - 1);
+ strncpy(ifr.ifr_name, bridge, sizeof(ifr.ifr_name) - 1);
ifr.ifr_ifindex = index;
if (ioctl(sk, SIOCBRDELIF, &ifr) < 0)
@@ -1217,7 +1127,7 @@ int connman_inet_add_to_bridge(int index, const char *bridge)
struct ifreq ifr;
int sk, err = 0;
- if (bridge == NULL)
+ if (!bridge)
return -EINVAL;
sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
@@ -1227,7 +1137,7 @@ int connman_inet_add_to_bridge(int index, const char *bridge)
}
memset(&ifr, 0, sizeof(ifr));
- strncpy(ifr.ifr_name, bridge, IFNAMSIZ - 1);
+ strncpy(ifr.ifr_name, bridge, sizeof(ifr.ifr_name) - 1);
ifr.ifr_ifindex = index;
if (ioctl(sk, SIOCBRADDIF, &ifr) < 0)
@@ -1272,7 +1182,7 @@ int connman_inet_setup_tunnel(char *tunnel, int mtu)
__u32 mask;
__u32 flags;
- if (tunnel == NULL)
+ if (!tunnel)
return -EINVAL;
sk = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
@@ -1286,7 +1196,7 @@ int connman_inet_setup_tunnel(char *tunnel, int mtu)
goto done;
memset(&ifr, 0, sizeof(ifr));
- strncpy(ifr.ifr_name, tunnel, IFNAMSIZ);
+ strncpy(ifr.ifr_name, tunnel, sizeof(ifr.ifr_name) - 1);
err = ioctl(sk, SIOCGIFFLAGS, &ifr);
if (err)
goto done;
@@ -1342,11 +1252,15 @@ int connman_inet_create_tunnel(char **iface)
return fd;
}
-struct rs_cb_data {
+/*
+ * This callback struct is used when sending router and neighbor
+ * solicitation and advertisement messages.
+ */
+struct xs_cb_data {
GIOChannel *channel;
- __connman_inet_rs_cb_t callback;
+ void *callback;
struct sockaddr_in6 addr;
- guint rs_timeout;
+ guint timeout;
guint watch_id;
void *user_data;
};
@@ -1361,16 +1275,16 @@ static const struct in6_addr in6addr_all_nodes_mc = IN6ADDR_ALL_NODES_MC_INIT;
static const struct in6_addr in6addr_all_routers_mc =
IN6ADDR_ALL_ROUTERS_MC_INIT;
-static void rs_cleanup(struct rs_cb_data *data)
+static void xs_cleanup(struct xs_cb_data *data)
{
- if (data->channel != NULL) {
+ if (data->channel) {
g_io_channel_shutdown(data->channel, TRUE, NULL);
g_io_channel_unref(data->channel);
data->channel = NULL;
}
- if (data->rs_timeout > 0)
- g_source_remove(data->rs_timeout);
+ if (data->timeout > 0)
+ g_source_remove(data->timeout);
if (data->watch_id > 0)
g_source_remove(data->watch_id);
@@ -1380,18 +1294,20 @@ static void rs_cleanup(struct rs_cb_data *data)
static gboolean rs_timeout_cb(gpointer user_data)
{
- struct rs_cb_data *data = user_data;
+ struct xs_cb_data *data = user_data;
DBG("user data %p", user_data);
- if (data == NULL)
+ if (!data)
return FALSE;
- if (data->callback != NULL)
- data->callback(NULL, 0, data->user_data);
+ if (data->callback) {
+ __connman_inet_rs_cb_t cb = data->callback;
+ cb(NULL, 0, data->user_data);
+ }
- data->rs_timeout = 0;
- rs_cleanup(data);
+ data->timeout = 0;
+ xs_cleanup(data);
return FALSE;
}
@@ -1401,10 +1317,11 @@ static int icmpv6_recv(int fd, gpointer user_data)
struct iovec iov;
unsigned char chdr[CMSG_BUF_LEN];
unsigned char buf[1540];
- struct rs_cb_data *data = user_data;
+ struct xs_cb_data *data = user_data;
struct nd_router_advert *hdr;
struct sockaddr_in6 saddr;
ssize_t len;
+ __connman_inet_rs_cb_t cb = data->callback;
DBG("");
@@ -1413,6 +1330,7 @@ static int icmpv6_recv(int fd, gpointer user_data)
mhdr.msg_name = (void *)&saddr;
mhdr.msg_namelen = sizeof(struct sockaddr_in6);
+ mhdr.msg_flags = 0;
mhdr.msg_iov = &iov;
mhdr.msg_iovlen = 1;
mhdr.msg_control = (void *)chdr;
@@ -1420,8 +1338,8 @@ static int icmpv6_recv(int fd, gpointer user_data)
len = recvmsg(fd, &mhdr, 0);
if (len < 0) {
- data->callback(NULL, 0, data->user_data);
- rs_cleanup(data);
+ cb(NULL, 0, data->user_data);
+ xs_cleanup(data);
return -errno;
}
@@ -1431,14 +1349,13 @@ static int icmpv6_recv(int fd, gpointer user_data)
if (hdr->nd_ra_code != 0)
return 0;
- data->callback(hdr, len, data->user_data);
- rs_cleanup(data);
+ cb(hdr, len, data->user_data);
+ xs_cleanup(data);
return len;
}
-static gboolean icmpv6_event(GIOChannel *chan, GIOCondition cond,
- gpointer data)
+static gboolean icmpv6_event(GIOChannel *chan, GIOCondition cond, gpointer data)
{
int fd, ret;
@@ -1456,7 +1373,8 @@ static gboolean icmpv6_event(GIOChannel *chan, GIOCondition cond,
}
/* Adapted from RFC 1071 "C" Implementation Example */
-static uint16_t csum(const void *phdr, const void *data, socklen_t datalen)
+static uint16_t csum(const void *phdr, const void *data, socklen_t datalen,
+ const void *extra_data, socklen_t extra_datalen)
{
register unsigned long sum = 0;
socklen_t count;
@@ -1477,13 +1395,25 @@ static uint16_t csum(const void *phdr, const void *data, socklen_t datalen)
count -= 2;
}
+ if (extra_data) {
+ count = extra_datalen;
+ addr = (uint16_t *)extra_data;
+
+ while (count > 1) {
+ sum += *(addr++);
+ count -= 2;
+ }
+ }
+
while (sum >> 16)
sum = (sum & 0xffff) + (sum >> 16);
return (uint16_t)~sum;
}
-static int ndisc_send_unspec(int type, int oif, const struct in6_addr *dest)
+static int ndisc_send_unspec(int type, int oif, const struct in6_addr *dest,
+ const struct in6_addr *source,
+ unsigned char *buf, size_t len, uint16_t lifetime)
{
struct _phdr {
struct in6_addr src;
@@ -1499,16 +1429,17 @@ static int ndisc_send_unspec(int type, int oif, const struct in6_addr *dest)
struct icmp6_hdr icmp;
struct nd_neighbor_solicit ns;
struct nd_router_solicit rs;
+ struct nd_router_advert ra;
} i;
} frame;
struct msghdr msgh;
struct cmsghdr *cmsg;
struct in6_pktinfo *pinfo;
- struct sockaddr_in6 dst;
+ struct sockaddr_in6 dst, src;
char cbuf[CMSG_SPACE(sizeof(*pinfo))];
- struct iovec iov;
- int fd, datalen, ret;
+ struct iovec iov[2];
+ int fd, datalen, ret, iovlen = 1;
DBG("");
@@ -1519,35 +1450,60 @@ static int ndisc_send_unspec(int type, int oif, const struct in6_addr *dest)
memset(&frame, 0, sizeof(frame));
memset(&dst, 0, sizeof(dst));
- datalen = sizeof(frame.i.rs); /* 8, csum() safe */
+ if (type == ND_ROUTER_SOLICIT)
+ datalen = sizeof(frame.i.rs); /* 8, csum() safe */
+ else if (type == ND_ROUTER_ADVERT) {
+ datalen = sizeof(frame.i.ra); /* 16, csum() safe */
+ frame.i.ra.nd_ra_router_lifetime = htons(lifetime);
+ } else if (type == ND_NEIGHBOR_SOLICIT) {
+ datalen = sizeof(frame.i.ns); /* 24, csum() safe */
+ memcpy(&frame.i.ns.nd_ns_target, buf, sizeof(struct in6_addr));
+ } else {
+ close(fd);
+ return -EINVAL;
+ }
+
dst.sin6_addr = *dest;
+ if (source)
+ src.sin6_addr = *source;
+ else
+ src.sin6_addr = in6addr_any;
+
/* Fill in the IPv6 header */
frame.ip.ip6_vfc = 0x60;
- frame.ip.ip6_plen = htons(datalen);
+ frame.ip.ip6_plen = htons(datalen + len);
frame.ip.ip6_nxt = IPPROTO_ICMPV6;
frame.ip.ip6_hlim = 255;
frame.ip.ip6_dst = dst.sin6_addr;
+ frame.ip.ip6_src = src.sin6_addr;
/* all other fields are already set to zero */
/* Prepare pseudo header for csum */
memset(&phdr, 0, sizeof(phdr));
phdr.dst = dst.sin6_addr;
- phdr.plen = htonl(datalen);
+ phdr.src = src.sin6_addr;
+ phdr.plen = htonl(datalen + len);
phdr.nxt = IPPROTO_ICMPV6;
/* Fill in remaining ICMP header fields */
frame.i.icmp.icmp6_type = type;
- frame.i.icmp.icmp6_cksum = csum(&phdr, &frame.i, datalen);
+ frame.i.icmp.icmp6_cksum = csum(&phdr, &frame.i, datalen, buf, len);
- iov.iov_base = &frame;
- iov.iov_len = sizeof(frame.ip) + datalen;
+ iov[0].iov_base = &frame;
+ iov[0].iov_len = sizeof(frame.ip) + datalen;
+
+ if (buf) {
+ iov[1].iov_base = buf;
+ iov[1].iov_len = len;
+ iovlen = 2;
+ }
dst.sin6_family = AF_INET6;
msgh.msg_name = &dst;
msgh.msg_namelen = sizeof(dst);
- msgh.msg_iov = &iov;
- msgh.msg_iovlen = 1;
+ msgh.msg_iov = iov;
+ msgh.msg_iovlen = iovlen;
msgh.msg_flags = 0;
memset(cbuf, 0, CMSG_SPACE(sizeof(*pinfo)));
@@ -1597,39 +1553,49 @@ static int if_mc_group(int sock, int ifindex, const struct in6_addr *mc_addr,
ret = setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP,
&val, sizeof(int));
+ if (ret < 0) {
+ ret = -errno;
+ DBG("Cannot set IPV6_MULTICAST_LOOP %d/%s", ret,
+ strerror(-ret));
+ return ret;
+ }
- if (ret < 0)
+ ret = setsockopt(sock, IPPROTO_IPV6, cmd, &mreq, sizeof(mreq));
+ if (ret < 0) {
+ ret = -errno;
+ DBG("Cannot set option %d %d/%s", cmd, ret, strerror(-ret));
return ret;
+ }
- return setsockopt(sock, IPPROTO_IPV6, cmd, &mreq, sizeof(mreq));
+ return 0;
}
int __connman_inet_ipv6_send_rs(int index, int timeout,
__connman_inet_rs_cb_t callback, void *user_data)
{
- struct rs_cb_data *data;
+ struct xs_cb_data *data;
struct icmp6_filter filter;
struct in6_addr solicit;
struct in6_addr dst = in6addr_all_routers_mc;
int sk;
- DBG("");
-
if (timeout <= 0)
return -EINVAL;
- data = g_try_malloc0(sizeof(struct rs_cb_data));
- if (data == NULL)
+ data = g_try_malloc0(sizeof(struct xs_cb_data));
+ if (!data)
return -ENOMEM;
data->callback = callback;
data->user_data = user_data;
- data->rs_timeout = g_timeout_add_seconds(timeout, rs_timeout_cb, data);
+ data->timeout = g_timeout_add_seconds(timeout, rs_timeout_cb, data);
sk = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_ICMPV6);
if (sk < 0)
return -errno;
+ DBG("sock %d", sk);
+
ICMP6_FILTER_SETBLOCKALL(&filter);
ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filter);
@@ -1650,11 +1616,399 @@ int __connman_inet_ipv6_send_rs(int index, int timeout,
G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
icmpv6_event, data);
- ndisc_send_unspec(ND_ROUTER_SOLICIT, index, &dst);
+ ndisc_send_unspec(ND_ROUTER_SOLICIT, index, &dst, NULL, NULL, 0, 0);
+
+ return 0;
+}
+
+static inline void ipv6_addr_advert_mult(const struct in6_addr *addr,
+ struct in6_addr *advert)
+{
+ ipv6_addr_set(advert, htonl(0xFF020000), 0, htonl(0x2),
+ htonl(0xFF000000) | addr->s6_addr32[3]);
+}
+
+#define MSG_SIZE_SEND 1452
+
+static int inc_len(int len, int inc)
+{
+ if (len > MSG_SIZE_SEND)
+ return -EINVAL;
+
+ len += inc;
+ return len;
+}
+
+int __connman_inet_ipv6_send_ra(int index, struct in6_addr *src_addr,
+ GSList *prefixes, int router_lifetime)
+{
+ GSList *list;
+ struct in6_addr src, *source;
+ struct in6_addr dst = in6addr_all_nodes_mc;
+ GDHCPIAPrefix *prefix;
+ unsigned char buf[MSG_SIZE_SEND];
+ char addr_str[INET6_ADDRSTRLEN];
+ int sk, err = 0;
+ int len, count = 0;
+
+ if (!prefixes)
+ return -EINVAL;
+
+ sk = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_ICMPV6);
+ if (sk < 0)
+ return -errno;
+
+ if (!src_addr) {
+ __connman_inet_get_interface_ll_address(index, AF_INET6, &src);
+ source = &src;
+ } else
+ source = src_addr;
+
+ DBG("sock %d index %d prefixes %p src %s lifetime %d", sk, index,
+ prefixes, inet_ntop(AF_INET6, source, addr_str,
+ INET6_ADDRSTRLEN),
+ router_lifetime);
+
+ memset(buf, 0, MSG_SIZE_SEND);
+ len = 0;
+
+ for (list = prefixes; list; list = list->next) {
+ struct nd_opt_prefix_info *pinfo;
+
+ prefix = list->data;
+ pinfo = (struct nd_opt_prefix_info *)(buf + len);
+
+ len = inc_len(len, sizeof(*pinfo));
+ if (len < 0) {
+ err = len;
+ goto out;
+ }
+
+ pinfo->nd_opt_pi_type = ND_OPT_PREFIX_INFORMATION;
+ pinfo->nd_opt_pi_len = 4;
+ pinfo->nd_opt_pi_prefix_len = prefix->prefixlen;
+ pinfo->nd_opt_pi_flags_reserved = ND_OPT_PI_FLAG_ONLINK;
+ pinfo->nd_opt_pi_flags_reserved |= ND_OPT_PI_FLAG_AUTO;
+ if (router_lifetime > 0) {
+ pinfo->nd_opt_pi_valid_time = htonl(prefix->valid);
+ pinfo->nd_opt_pi_preferred_time =
+ htonl(prefix->preferred);
+ }
+ pinfo->nd_opt_pi_reserved2 = 0;
+
+ memcpy(&pinfo->nd_opt_pi_prefix, &prefix->prefix,
+ sizeof(struct in6_addr));
+
+ DBG("[%d] index %d prefix %s/%d", count, index,
+ inet_ntop(AF_INET6, &prefix->prefix, addr_str,
+ INET6_ADDRSTRLEN), prefix->prefixlen);
+
+ count++;
+ }
+
+ if (count > 0) {
+ err = ndisc_send_unspec(ND_ROUTER_ADVERT, index, &dst, source,
+ buf, len, router_lifetime);
+ if (err < 0)
+ DBG("cannot send RA %d/%s", err, strerror(-err));
+ }
+
+out:
+ close(sk);
+ return err;
+}
+
+void __connman_inet_ipv6_stop_recv_rs(void *context)
+{
+ if (!context)
+ return;
+
+ xs_cleanup(context);
+}
+
+static int icmpv6_rs_recv(int fd, gpointer user_data)
+{
+ struct msghdr mhdr;
+ struct iovec iov;
+ unsigned char chdr[CMSG_BUF_LEN];
+ unsigned char buf[1540];
+ struct xs_cb_data *data = user_data;
+ struct nd_router_solicit *hdr;
+ struct sockaddr_in6 saddr;
+ ssize_t len;
+ __connman_inet_recv_rs_cb_t cb = data->callback;
+
+ DBG("");
+
+ iov.iov_len = sizeof(buf);
+ iov.iov_base = buf;
+
+ mhdr.msg_name = (void *)&saddr;
+ mhdr.msg_namelen = sizeof(struct sockaddr_in6);
+ mhdr.msg_flags = 0;
+ mhdr.msg_iov = &iov;
+ mhdr.msg_iovlen = 1;
+ mhdr.msg_control = (void *)chdr;
+ mhdr.msg_controllen = CMSG_BUF_LEN;
+
+ len = recvmsg(fd, &mhdr, 0);
+ if (len < 0) {
+ cb(NULL, 0, data->user_data);
+ return -errno;
+ }
+
+ hdr = (struct nd_router_solicit *)buf;
+ DBG("code %d len %zd hdr %zd", hdr->nd_rs_code, len,
+ sizeof(struct nd_router_solicit));
+ if (hdr->nd_rs_code != 0)
+ return 0;
+
+ cb(hdr, len, data->user_data);
+ return len;
+}
+
+static gboolean icmpv6_rs_event(GIOChannel *chan, GIOCondition cond,
+ gpointer data)
+{
+ int fd, ret;
+
+ DBG("");
+
+ if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
+ return FALSE;
+
+ fd = g_io_channel_unix_get_fd(chan);
+ ret = icmpv6_rs_recv(fd, data);
+ if (ret == 0)
+ return TRUE;
+
+ return FALSE;
+}
+
+int __connman_inet_ipv6_start_recv_rs(int index,
+ __connman_inet_recv_rs_cb_t callback,
+ void *user_data,
+ void **context)
+{
+ struct xs_cb_data *data;
+ struct icmp6_filter filter;
+ char addr_str[INET6_ADDRSTRLEN];
+ int sk, err;
+
+ data = g_try_malloc0(sizeof(struct xs_cb_data));
+ if (!data)
+ return -ENOMEM;
+
+ data->callback = callback;
+ data->user_data = user_data;
+
+ sk = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_ICMPV6);
+ if (sk < 0) {
+ g_free(data);
+ return -errno;
+ }
+
+ DBG("sock %d", sk);
+
+ ICMP6_FILTER_SETBLOCKALL(&filter);
+ ICMP6_FILTER_SETPASS(ND_ROUTER_SOLICIT, &filter);
+
+ setsockopt(sk, IPPROTO_ICMPV6, ICMP6_FILTER, &filter,
+ sizeof(struct icmp6_filter));
+
+ err = if_mc_group(sk, index, &in6addr_all_routers_mc, IPV6_JOIN_GROUP);
+ if (err < 0)
+ DBG("Cannot join mc %s %d/%s", inet_ntop(AF_INET6,
+ &in6addr_all_routers_mc, addr_str, INET6_ADDRSTRLEN),
+ err, strerror(-err));
+
+ data->channel = g_io_channel_unix_new(sk);
+ g_io_channel_set_close_on_unref(data->channel, TRUE);
+
+ g_io_channel_set_encoding(data->channel, NULL, NULL);
+ g_io_channel_set_buffered(data->channel, FALSE);
+
+ data->watch_id = g_io_add_watch(data->channel,
+ G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
+ icmpv6_rs_event, data);
+
+ *context = data;
return 0;
}
+static gboolean ns_timeout_cb(gpointer user_data)
+{
+ struct xs_cb_data *data = user_data;
+
+ DBG("user data %p", user_data);
+
+ if (!data)
+ return FALSE;
+
+ if (data->callback) {
+ __connman_inet_ns_cb_t cb = data->callback;
+ cb(NULL, 0, &data->addr.sin6_addr, data->user_data);
+ }
+
+ data->timeout = 0;
+ xs_cleanup(data);
+ return FALSE;
+}
+
+static int icmpv6_nd_recv(int fd, gpointer user_data)
+{
+ struct msghdr mhdr;
+ struct iovec iov;
+ unsigned char chdr[CMSG_BUF_LEN];
+ unsigned char buf[1540];
+ struct xs_cb_data *data = user_data;
+ struct nd_neighbor_advert *hdr;
+ struct sockaddr_in6 saddr;
+ ssize_t len;
+ __connman_inet_ns_cb_t cb = data->callback;
+
+ DBG("");
+
+ iov.iov_len = sizeof(buf);
+ iov.iov_base = buf;
+
+ mhdr.msg_name = (void *)&saddr;
+ mhdr.msg_namelen = sizeof(struct sockaddr_in6);
+ mhdr.msg_flags = 0;
+ mhdr.msg_iov = &iov;
+ mhdr.msg_iovlen = 1;
+ mhdr.msg_control = (void *)chdr;
+ mhdr.msg_controllen = CMSG_BUF_LEN;
+
+ len = recvmsg(fd, &mhdr, 0);
+ if (len < 0) {
+ cb(NULL, 0, &data->addr.sin6_addr, data->user_data);
+ xs_cleanup(data);
+ return -errno;
+ }
+
+ hdr = (struct nd_neighbor_advert *)buf;
+ DBG("code %d len %zd hdr %zd", hdr->nd_na_code, len,
+ sizeof(struct nd_neighbor_advert));
+ if (hdr->nd_na_code != 0)
+ return 0;
+
+ /*
+ * We can receive any neighbor advertisement so we need to check if the
+ * packet was meant for us and ignore the packet otherwise.
+ */
+ if (memcmp(&data->addr.sin6_addr, &hdr->nd_na_target,
+ sizeof(struct in6_addr)))
+ return 0;
+
+ cb(hdr, len, &data->addr.sin6_addr, data->user_data);
+ xs_cleanup(data);
+
+ return len;
+}
+
+static gboolean icmpv6_nd_event(GIOChannel *chan, GIOCondition cond,
+ gpointer data)
+{
+ int fd, ret;
+
+ DBG("");
+
+ if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
+ return FALSE;
+
+ fd = g_io_channel_unix_get_fd(chan);
+ ret = icmpv6_nd_recv(fd, data);
+ if (ret == 0)
+ return TRUE;
+
+ return FALSE;
+}
+
+int __connman_inet_ipv6_do_dad(int index, int timeout_ms,
+ struct in6_addr *addr,
+ __connman_inet_ns_cb_t callback,
+ void *user_data)
+{
+ struct xs_cb_data *data;
+ struct icmp6_filter filter;
+ struct in6_addr solicit;
+ int sk, err, val = 1;
+
+ if (timeout_ms <= 0)
+ return -EINVAL;
+
+ data = g_try_malloc0(sizeof(struct xs_cb_data));
+ if (!data)
+ return -ENOMEM;
+
+ data->callback = callback;
+ data->user_data = user_data;
+ data->timeout = g_timeout_add_full(G_PRIORITY_DEFAULT,
+ (guint)timeout_ms,
+ ns_timeout_cb,
+ data,
+ NULL);
+ memcpy(&data->addr.sin6_addr, addr, sizeof(struct in6_addr));
+
+ sk = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_ICMPV6);
+ if (sk < 0)
+ return -errno;
+
+ DBG("sock %d", sk);
+
+ ICMP6_FILTER_SETBLOCKALL(&filter);
+ ICMP6_FILTER_SETPASS(ND_NEIGHBOR_ADVERT, &filter);
+
+ setsockopt(sk, IPPROTO_ICMPV6, ICMP6_FILTER, &filter,
+ sizeof(struct icmp6_filter));
+
+ if (setsockopt(sk, IPPROTO_IPV6, IPV6_RECVPKTINFO,
+ &val, sizeof(val)) < 0) {
+ err = -errno;
+ DBG("Cannot set IPV6_RECVPKTINFO %d/%s", err,
+ strerror(-err));
+ close(sk);
+ return err;
+ }
+
+ if (setsockopt(sk, IPPROTO_IPV6, IPV6_RECVHOPLIMIT,
+ &val, sizeof(val)) < 0) {
+ err = -errno;
+ DBG("Cannot set IPV6_RECVHOPLIMIT %d/%s", err,
+ strerror(-err));
+ close(sk);
+ return err;
+ }
+
+ val = 0;
+ setsockopt(sk, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &val, sizeof(val));
+
+ ipv6_addr_solict_mult(addr, &solicit);
+ if_mc_group(sk, index, &in6addr_all_nodes_mc, IPV6_JOIN_GROUP);
+ if_mc_group(sk, index, &solicit, IPV6_JOIN_GROUP);
+
+ data->channel = g_io_channel_unix_new(sk);
+ g_io_channel_set_close_on_unref(data->channel, TRUE);
+
+ g_io_channel_set_encoding(data->channel, NULL, NULL);
+ g_io_channel_set_buffered(data->channel, FALSE);
+
+ data->watch_id = g_io_add_watch(data->channel,
+ G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
+ icmpv6_nd_event, data);
+
+ err = ndisc_send_unspec(ND_NEIGHBOR_SOLICIT, index, &solicit, NULL,
+ (unsigned char *)addr, 0, 0);
+ if (err < 0) {
+ DBG("Cannot send NS %d/%s", err, strerror(-err));
+ xs_cleanup(data);
+ }
+
+ return err;
+}
+
GSList *__connman_inet_ipv6_get_prefixes(struct nd_router_advert *hdr,
unsigned int length)
{
@@ -1686,7 +2040,7 @@ GSList *__connman_inet_ipv6_get_prefixes(struct nd_router_advert *hdr,
pinfo = (struct nd_opt_prefix_info *)pos;
prefix = inet_ntop(AF_INET6, &pinfo->nd_opt_pi_prefix,
prefix_str, INET6_ADDRSTRLEN);
- if (prefix == NULL)
+ if (!prefix)
break;
str = g_strdup_printf("%s/%d", prefix,
@@ -1759,7 +2113,7 @@ static int get_dest_addr(int family, int index, char *buf, int len)
return -errno;
}
- if (inet_ntop(family, addr, buf, len) == NULL) {
+ if (!inet_ntop(family, addr, buf, len)) {
DBG("error %d/%s", errno, strerror(errno));
return -errno;
}
@@ -1854,7 +2208,7 @@ static void inet_rtnl_cleanup(struct inet_rtnl_cb_data *data)
{
struct __connman_inet_rtnl_handle *rth = data->rtnl;
- if (data->channel != NULL) {
+ if (data->channel) {
g_io_channel_shutdown(data->channel, TRUE, NULL);
g_io_channel_unref(data->channel);
data->channel = NULL;
@@ -1868,7 +2222,7 @@ static void inet_rtnl_cleanup(struct inet_rtnl_cb_data *data)
if (data->watch_id > 0)
g_source_remove(data->watch_id);
- if (rth != NULL) {
+ if (rth) {
__connman_inet_rtnl_close(rth);
g_free(rth);
}
@@ -1882,10 +2236,10 @@ static gboolean inet_rtnl_timeout_cb(gpointer user_data)
DBG("user data %p", user_data);
- if (data == NULL)
+ if (!data)
return FALSE;
- if (data->callback != NULL)
+ if (data->callback)
data->callback(NULL, data->user_data);
data->rtnl_timeout = 0;
@@ -2006,9 +2360,9 @@ int __connman_inet_rtnl_talk(struct __connman_inet_rtnl_handle *rtnl,
n->nlmsg_seq = seq = ++rtnl->seq;
- if (callback != NULL) {
+ if (callback) {
data = g_try_malloc0(sizeof(struct inet_rtnl_cb_data));
- if (data == NULL)
+ if (!data)
return -ENOMEM;
data->callback = callback;
@@ -2031,9 +2385,10 @@ int __connman_inet_rtnl_talk(struct __connman_inet_rtnl_handle *rtnl,
err = sendto(rtnl->fd, &rtnl->req.n, rtnl->req.n.nlmsg_len, 0,
(struct sockaddr *) &nladdr, sizeof(nladdr));
- DBG("handle %p len %d err %d", rtnl, rtnl->req.n.nlmsg_len, err);
+ DBG("handle %p len %d", rtnl, rtnl->req.n.nlmsg_len);
if (err < 0) {
- connman_error("Can not talk to rtnetlink");
+ connman_error("Can not talk to rtnetlink err %d %s",
+ -errno, strerror(errno));
return -errno;
}
@@ -2105,7 +2460,7 @@ static void get_route_cb(struct nlmsghdr *answer, void *user_data)
DBG("answer %p data %p", answer, user_data);
- if (answer == NULL)
+ if (!answer)
goto out;
len = answer->nlmsg_len;
@@ -2126,10 +2481,10 @@ static void get_route_cb(struct nlmsghdr *answer, void *user_data)
parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len);
- if (tb[RTA_OIF] != NULL)
+ if (tb[RTA_OIF])
index = *(int *)RTA_DATA(tb[RTA_OIF]);
- if (tb[RTA_GATEWAY] != NULL)
+ if (tb[RTA_GATEWAY])
addr = inet_ntop(r->rtm_family,
RTA_DATA(tb[RTA_GATEWAY]),
abuf, sizeof(abuf));
@@ -2137,7 +2492,7 @@ static void get_route_cb(struct nlmsghdr *answer, void *user_data)
DBG("addr %s index %d user %p", addr, index, data->user_data);
out:
- if (data != NULL && data->callback != NULL)
+ if (data && data->callback)
data->callback(addr, index, data->user_data);
g_free(data);
@@ -2158,7 +2513,7 @@ int __connman_inet_get_route(const char *dest_address,
DBG("dest %s", dest_address);
- if (dest_address == NULL)
+ if (!dest_address)
return -EINVAL;
memset(&hints, 0, sizeof(hints));
@@ -2170,7 +2525,7 @@ int __connman_inet_get_route(const char *dest_address,
return -EINVAL;
rth = g_try_malloc0(sizeof(struct __connman_inet_rtnl_handle));
- if (rth == NULL) {
+ if (!rth) {
freeaddrinfo(rp);
return -ENOMEM;
}
@@ -2197,7 +2552,7 @@ int __connman_inet_get_route(const char *dest_address,
goto fail;
data = g_try_malloc(sizeof(struct get_route_cb_data));
- if (data == NULL) {
+ if (!data) {
err = -ENOMEM;
goto done;
}
@@ -2242,7 +2597,7 @@ int connman_inet_check_ipaddress(const char *host)
}
/* Check routine modified from ics-dhcp 4.2.3-P2 */
-connman_bool_t connman_inet_check_hostname(const char *ptr, size_t len)
+bool connman_inet_check_hostname(const char *ptr, size_t len)
{
const char *p;
@@ -2250,7 +2605,7 @@ connman_bool_t connman_inet_check_hostname(const char *ptr, size_t len)
* Not empty or complete length not over 255 characters.
*/
if ((len == 0) || (len > 256))
- return FALSE;
+ return false;
/*
* Consists of [[:alnum:]-]+ labels separated by [.]
@@ -2263,7 +2618,7 @@ connman_bool_t connman_inet_check_hostname(const char *ptr, size_t len)
* Not allowed at begin or end of a label.
*/
if (((p - ptr) == 0) || (len == 0) || (p[1] == '.'))
- return FALSE;
+ return false;
} else if (*p == '.') {
/*
@@ -2273,7 +2628,7 @@ connman_bool_t connman_inet_check_hostname(const char *ptr, size_t len)
size_t d = p - ptr;
if ((d <= 0) || (d >= 64))
- return FALSE;
+ return false;
ptr = p + 1; /* Jump to the next label */
@@ -2281,11 +2636,11 @@ connman_bool_t connman_inet_check_hostname(const char *ptr, size_t len)
/*
* Also numbers at the begin are fine
*/
- return FALSE;
+ return false;
}
}
- return TRUE;
+ return true;
}
char **__connman_inet_get_running_interfaces(void)
@@ -2310,7 +2665,7 @@ char **__connman_inet_get_running_interfaces(void)
* calls.
*/
ifr = g_try_malloc0(ifc.ifc_len * 2);
- if (ifr == NULL)
+ if (!ifr)
goto error;
ifc.ifc_req = ifr;
@@ -2321,7 +2676,7 @@ char **__connman_inet_get_running_interfaces(void)
numif = ifc.ifc_len / sizeof(struct ifreq);
result = g_try_malloc0((numif + 1) * sizeof(char *));
- if (result == NULL)
+ if (!result)
goto error;
close(sk);
@@ -2366,16 +2721,16 @@ error:
return NULL;
}
-connman_bool_t connman_inet_is_ipv6_supported()
+bool connman_inet_is_ipv6_supported()
{
int sk;
sk = socket(PF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
if (sk < 0)
- return FALSE;
+ return false;
close(sk);
- return TRUE;
+ return true;
}
int __connman_inet_get_interface_address(int index, int family, void *address)
@@ -2384,7 +2739,7 @@ int __connman_inet_get_interface_address(int index, int family, void *address)
int err = -ENOENT;
char name[IF_NAMESIZE];
- if (if_indextoname(index, name) == NULL)
+ if (!if_indextoname(index, name))
return -EINVAL;
DBG("index %d interface %s", index, name);
@@ -2395,8 +2750,8 @@ int __connman_inet_get_interface_address(int index, int family, void *address)
return err;
}
- for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
- if (ifa->ifa_addr == NULL)
+ for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
+ if (!ifa->ifa_addr)
continue;
if (strncmp(ifa->ifa_name, name, IF_NAMESIZE) == 0 &&
@@ -2431,3 +2786,237 @@ out:
freeifaddrs(ifaddr);
return err;
}
+
+static int iprule_modify(int cmd, int family, uint32_t table_id,
+ uint32_t fwmark)
+{
+ struct __connman_inet_rtnl_handle rth;
+ int ret;
+
+ memset(&rth, 0, sizeof(rth));
+
+ rth.req.n.nlmsg_type = cmd;
+ rth.req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
+ rth.req.n.nlmsg_flags = NLM_F_REQUEST;
+ rth.req.u.r.rt.rtm_family = family;
+ rth.req.u.r.rt.rtm_protocol = RTPROT_BOOT;
+ rth.req.u.r.rt.rtm_scope = RT_SCOPE_UNIVERSE;
+ rth.req.u.r.rt.rtm_table = table_id;
+ rth.req.u.r.rt.rtm_type = RTN_UNSPEC;
+ rth.req.u.r.rt.rtm_flags = 0;
+
+ if (cmd == RTM_NEWRULE) {
+ rth.req.n.nlmsg_flags |= NLM_F_CREATE|NLM_F_EXCL;
+ rth.req.u.r.rt.rtm_type = RTN_UNICAST;
+ }
+
+ __connman_inet_rtnl_addattr32(&rth.req.n, sizeof(rth.req),
+ FRA_FWMARK, fwmark);
+
+ if (table_id < 256) {
+ rth.req.u.r.rt.rtm_table = table_id;
+ } else {
+ rth.req.u.r.rt.rtm_table = RT_TABLE_UNSPEC;
+ __connman_inet_rtnl_addattr32(&rth.req.n, sizeof(rth.req),
+ FRA_TABLE, table_id);
+ }
+
+ if (rth.req.u.r.rt.rtm_family == AF_UNSPEC)
+ rth.req.u.r.rt.rtm_family = AF_INET;
+
+ ret = __connman_inet_rtnl_open(&rth);
+ if (ret < 0)
+ goto done;
+
+ ret = __connman_inet_rtnl_send(&rth, &rth.req.n);
+
+done:
+ __connman_inet_rtnl_close(&rth);
+
+ return ret;
+}
+
+int __connman_inet_add_fwmark_rule(uint32_t table_id, int family, uint32_t fwmark)
+{
+ /* ip rule add fwmark 9876 table 1234 */
+
+ return iprule_modify(RTM_NEWRULE, family, table_id, fwmark);
+}
+
+int __connman_inet_del_fwmark_rule(uint32_t table_id, int family, uint32_t fwmark)
+{
+ return iprule_modify(RTM_DELRULE, family, table_id, fwmark);
+}
+
+static int iproute_default_modify(int cmd, uint32_t table_id, int ifindex,
+ const char *gateway)
+{
+ struct __connman_inet_rtnl_handle rth;
+ unsigned char buf[sizeof(struct in6_addr)];
+ int ret, len;
+ int family = connman_inet_check_ipaddress(gateway);
+
+ switch (family) {
+ case AF_INET:
+ len = 4;
+ break;
+ case AF_INET6:
+ len = 16;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ ret = inet_pton(family, gateway, buf);
+ if (ret <= 0)
+ return -EINVAL;
+
+ memset(&rth, 0, sizeof(rth));
+
+ rth.req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
+ rth.req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL;
+ rth.req.n.nlmsg_type = cmd;
+ rth.req.u.r.rt.rtm_family = family;
+ rth.req.u.r.rt.rtm_table = RT_TABLE_MAIN;
+ rth.req.u.r.rt.rtm_scope = RT_SCOPE_NOWHERE;
+ rth.req.u.r.rt.rtm_protocol = RTPROT_BOOT;
+ rth.req.u.r.rt.rtm_scope = RT_SCOPE_UNIVERSE;
+ rth.req.u.r.rt.rtm_type = RTN_UNICAST;
+
+ __connman_inet_rtnl_addattr_l(&rth.req.n, sizeof(rth.req), RTA_GATEWAY,
+ buf, len);
+ if (table_id < 256) {
+ rth.req.u.r.rt.rtm_table = table_id;
+ } else {
+ rth.req.u.r.rt.rtm_table = RT_TABLE_UNSPEC;
+ __connman_inet_rtnl_addattr32(&rth.req.n, sizeof(rth.req),
+ RTA_TABLE, table_id);
+ }
+
+ __connman_inet_rtnl_addattr32(&rth.req.n, sizeof(rth.req),
+ RTA_OIF, ifindex);
+
+ ret = __connman_inet_rtnl_open(&rth);
+ if (ret < 0)
+ goto done;
+
+ ret = __connman_inet_rtnl_send(&rth, &rth.req.n);
+
+done:
+ __connman_inet_rtnl_close(&rth);
+
+ return ret;
+}
+
+int __connman_inet_add_default_to_table(uint32_t table_id, int ifindex,
+ const char *gateway)
+{
+ /* ip route add default via 1.2.3.4 dev wlan0 table 1234 */
+
+ return iproute_default_modify(RTM_NEWROUTE, table_id, ifindex, gateway);
+}
+
+int __connman_inet_del_default_from_table(uint32_t table_id, int ifindex,
+ const char *gateway)
+{
+ /* ip route del default via 1.2.3.4 dev wlan0 table 1234 */
+
+ return iproute_default_modify(RTM_DELROUTE, table_id, ifindex, gateway);
+}
+
+int __connman_inet_get_interface_ll_address(int index, int family,
+ void *address)
+{
+ struct ifaddrs *ifaddr, *ifa;
+ int err = -ENOENT;
+ char name[IF_NAMESIZE];
+
+ if (!if_indextoname(index, name))
+ return -EINVAL;
+
+ DBG("index %d interface %s", index, name);
+
+ if (getifaddrs(&ifaddr) < 0) {
+ err = -errno;
+ DBG("Cannot get addresses err %d/%s", err, strerror(-err));
+ return err;
+ }
+
+ for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
+ if (!ifa->ifa_addr)
+ continue;
+
+ if (strncmp(ifa->ifa_name, name, IF_NAMESIZE) == 0 &&
+ ifa->ifa_addr->sa_family == family) {
+ if (family == AF_INET) {
+ struct sockaddr_in *in4 = (struct sockaddr_in *)
+ ifa->ifa_addr;
+ if (in4->sin_addr.s_addr == INADDR_ANY)
+ continue;
+ if ((in4->sin_addr.s_addr & IN_CLASSB_NET) !=
+ ((in_addr_t) 0xa9fe0000))
+ continue;
+ memcpy(address, &in4->sin_addr,
+ sizeof(struct in_addr));
+ } else if (family == AF_INET6) {
+ struct sockaddr_in6 *in6 =
+ (struct sockaddr_in6 *)ifa->ifa_addr;
+ if (memcmp(&in6->sin6_addr, &in6addr_any,
+ sizeof(struct in6_addr)) == 0)
+ continue;
+ if (!IN6_IS_ADDR_LINKLOCAL(&in6->sin6_addr))
+ continue;
+
+ memcpy(address, &in6->sin6_addr,
+ sizeof(struct in6_addr));
+ } else {
+ err = -EINVAL;
+ goto out;
+ }
+
+ err = 0;
+ break;
+ }
+ }
+
+out:
+ freeifaddrs(ifaddr);
+ return err;
+}
+
+int __connman_inet_get_address_netmask(int ifindex,
+ struct sockaddr_in *address,
+ struct sockaddr_in *netmask)
+{
+ int sk, ret = -EINVAL;
+ struct ifreq ifr;
+
+ DBG("index %d", ifindex);
+
+ sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
+ if (sk < 0)
+ return -EINVAL;
+
+ memset(&ifr, 0, sizeof(ifr));
+ ifr.ifr_ifindex = ifindex;
+
+ if (ioctl(sk, SIOCGIFNAME, &ifr) < 0)
+ goto out;
+
+ if (ioctl(sk, SIOCGIFNETMASK, &ifr) < 0)
+ goto out;
+
+ memcpy(netmask, (struct sockaddr_in *)&ifr.ifr_netmask,
+ sizeof(struct sockaddr_in));
+
+ if (ioctl(sk, SIOCGIFADDR, &ifr) < 0)
+ goto out;
+
+ memcpy(address, (struct sockaddr_in *)&ifr.ifr_addr,
+ sizeof(struct sockaddr_in));
+ ret = 0;
+
+out:
+ close(sk);
+ return ret;
+}
diff --git a/src/inotify.c b/src/inotify.c
index f451f1c0..72ba6f68 100644
--- a/src/inotify.c
+++ b/src/inotify.c
@@ -3,7 +3,7 @@
* Connection Manager
*
* Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
- * Copyright (C) 2012 BMW Car IT GmbH. All rights reserved.
+ * Copyright (C) 2012-2013 BMW Car IT GmbH. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -95,7 +95,7 @@ static gboolean inotify_data(GIOChannel *channel, GIOCondition cond,
next_event += len;
bytes_read -= len;
- for (list = inotify->list; list != NULL; list = list->next) {
+ for (list = inotify->list; list; list = list->next) {
inotify_event_cb callback = list->data;
(*callback)(event, ident);
@@ -125,7 +125,7 @@ static int create_watch(const char *path, struct connman_inotify *inotify)
}
inotify->channel = g_io_channel_unix_new(fd);
- if (inotify->channel == NULL) {
+ if (!inotify->channel) {
connman_error("Creation of inotify channel failed");
inotify_rm_watch(fd, inotify->wd);
inotify->wd = 0;
@@ -149,7 +149,7 @@ static void remove_watch(struct connman_inotify *inotify)
{
int fd;
- if (inotify->channel == NULL)
+ if (!inotify->channel)
return;
if (inotify->watch > 0)
@@ -168,15 +168,15 @@ int connman_inotify_register(const char *path, inotify_event_cb callback)
struct connman_inotify *inotify;
int err;
- if (callback == NULL)
+ if (!callback)
return -EINVAL;
inotify = g_hash_table_lookup(inotify_hash, path);
- if (inotify != NULL)
+ if (inotify)
goto update;
inotify = g_try_new0(struct connman_inotify, 1);
- if (inotify == NULL)
+ if (!inotify)
return -ENOMEM;
inotify->wd = -1;
@@ -210,11 +210,11 @@ void connman_inotify_unregister(const char *path, inotify_event_cb callback)
struct connman_inotify *inotify;
inotify = g_hash_table_lookup(inotify_hash, path);
- if (inotify == NULL)
+ if (!inotify)
return;
inotify->list = g_slist_remove(inotify->list, callback);
- if (inotify->list != NULL)
+ if (inotify->list)
return;
g_hash_table_remove(inotify_hash, path);
diff --git a/src/ipaddress.c b/src/ipaddress.c
index f66bb674..57f9435d 100644
--- a/src/ipaddress.c
+++ b/src/ipaddress.c
@@ -2,7 +2,7 @@
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2013 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -38,7 +38,7 @@ struct connman_ipaddress *connman_ipaddress_alloc(int family)
struct connman_ipaddress *ipaddress;
ipaddress = g_try_new0(struct connman_ipaddress, 1);
- if (ipaddress == NULL)
+ if (!ipaddress)
return NULL;
ipaddress->family = family;
@@ -53,7 +53,7 @@ struct connman_ipaddress *connman_ipaddress_alloc(int family)
void connman_ipaddress_free(struct connman_ipaddress *ipaddress)
{
- if (ipaddress == NULL)
+ if (!ipaddress)
return;
g_free(ipaddress->broadcast);
@@ -69,7 +69,7 @@ unsigned char __connman_ipaddress_netmask_prefix_len(const char *netmask)
in_addr_t mask;
in_addr_t host;
- if (netmask == NULL)
+ if (!netmask)
return 32;
mask = inet_network(netmask);
@@ -86,19 +86,19 @@ unsigned char __connman_ipaddress_netmask_prefix_len(const char *netmask)
return bits;
}
-static gboolean check_ipv6_address(const char *address)
+static bool check_ipv6_address(const char *address)
{
unsigned char buf[sizeof(struct in6_addr)];
int err;
- if (address == NULL)
- return FALSE;
+ if (!address)
+ return false;
err = inet_pton(AF_INET6, address, buf);
if (err > 0)
- return TRUE;
+ return true;
- return FALSE;
+ return false;
}
int connman_ipaddress_set_ipv6(struct connman_ipaddress *ipaddress,
@@ -106,10 +106,10 @@ int connman_ipaddress_set_ipv6(struct connman_ipaddress *ipaddress,
unsigned char prefix_length,
const char *gateway)
{
- if (ipaddress == NULL)
+ if (!ipaddress)
return -EINVAL;
- if (check_ipv6_address(address) == FALSE)
+ if (!check_ipv6_address(address))
return -EINVAL;
DBG("prefix_len %d address %s gateway %s",
@@ -131,7 +131,7 @@ int connman_ipaddress_set_ipv6(struct connman_ipaddress *ipaddress,
int connman_ipaddress_set_ipv4(struct connman_ipaddress *ipaddress,
const char *address, const char *netmask, const char *gateway)
{
- if (ipaddress == NULL)
+ if (!ipaddress)
return -EINVAL;
ipaddress->family = AF_INET;
@@ -150,7 +150,7 @@ int connman_ipaddress_set_ipv4(struct connman_ipaddress *ipaddress,
void connman_ipaddress_set_peer(struct connman_ipaddress *ipaddress,
const char *peer)
{
- if (ipaddress == NULL)
+ if (!ipaddress)
return;
g_free(ipaddress->peer);
@@ -159,7 +159,7 @@ void connman_ipaddress_set_peer(struct connman_ipaddress *ipaddress,
void connman_ipaddress_clear(struct connman_ipaddress *ipaddress)
{
- if (ipaddress == NULL)
+ if (!ipaddress)
return;
ipaddress->prefixlen = 0;
@@ -185,7 +185,7 @@ void connman_ipaddress_clear(struct connman_ipaddress *ipaddress)
void connman_ipaddress_copy_address(struct connman_ipaddress *ipaddress,
struct connman_ipaddress *source)
{
- if (ipaddress == NULL || source == NULL)
+ if (!ipaddress || !source)
return;
ipaddress->family = source->family;
diff --git a/src/ipconfig.c b/src/ipconfig.c
index 694cc614..b23df160 100644
--- a/src/ipconfig.c
+++ b/src/ipconfig.c
@@ -2,7 +2,7 @@
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2013 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -50,18 +50,18 @@ struct connman_ipconfig {
const struct connman_ipconfig_ops *ops;
void *ops_data;
- connman_bool_t enabled;
+ bool enabled;
enum connman_ipconfig_method method;
struct connman_ipaddress *address;
struct connman_ipaddress *system;
int ipv6_privacy_config;
char *last_dhcp_address;
+ char **last_dhcpv6_prefixes;
};
struct connman_ipdevice {
int index;
- char *ifname;
unsigned short type;
unsigned int flags;
char *address;
@@ -84,17 +84,17 @@ struct connman_ipdevice {
struct connman_ipconfig *config_ipv4;
struct connman_ipconfig *config_ipv6;
- gboolean ipv6_enabled;
+ bool ipv6_enabled;
int ipv6_privacy;
};
static GHashTable *ipdevice_hash = NULL;
static GList *ipconfig_list = NULL;
-static connman_bool_t is_ipv6_supported = FALSE;
+static bool is_ipv6_supported = false;
void __connman_ipconfig_clear_address(struct connman_ipconfig *ipconfig)
{
- if (ipconfig == NULL)
+ if (!ipconfig)
return;
connman_ipaddress_clear(ipconfig->address);
@@ -175,27 +175,27 @@ static const char *scope2str(unsigned char scope)
return "";
}
-static gboolean get_ipv6_state(gchar *ifname)
+static bool get_ipv6_state(gchar *ifname)
{
int disabled;
gchar *path;
FILE *f;
- gboolean enabled = FALSE;
+ bool enabled = false;
- if (ifname == NULL)
+ if (!ifname)
path = g_strdup("/proc/sys/net/ipv6/conf/all/disable_ipv6");
else
path = g_strdup_printf(
"/proc/sys/net/ipv6/conf/%s/disable_ipv6", ifname);
- if (path == NULL)
+ if (!path)
return enabled;
f = fopen(path, "r");
g_free(path);
- if (f != NULL) {
+ if (f) {
if (fscanf(f, "%d", &disabled) > 0)
enabled = !disabled;
fclose(f);
@@ -204,28 +204,28 @@ static gboolean get_ipv6_state(gchar *ifname)
return enabled;
}
-static void set_ipv6_state(gchar *ifname, gboolean enable)
+static void set_ipv6_state(gchar *ifname, bool enable)
{
gchar *path;
FILE *f;
- if (ifname == NULL)
+ if (!ifname)
path = g_strdup("/proc/sys/net/ipv6/conf/all/disable_ipv6");
else
path = g_strdup_printf(
"/proc/sys/net/ipv6/conf/%s/disable_ipv6", ifname);
- if (path == NULL)
+ if (!path)
return;
f = fopen(path, "r+");
g_free(path);
- if (f == NULL)
+ if (!f)
return;
- if (enable == FALSE)
+ if (!enable)
fprintf(f, "1");
else
fprintf(f, "0");
@@ -239,20 +239,20 @@ static int get_ipv6_privacy(gchar *ifname)
FILE *f;
int value;
- if (ifname == NULL)
+ if (!ifname)
return 0;
path = g_strdup_printf("/proc/sys/net/ipv6/conf/%s/use_tempaddr",
ifname);
- if (path == NULL)
+ if (!path)
return 0;
f = fopen(path, "r");
g_free(path);
- if (f == NULL)
+ if (!f)
return 0;
if (fscanf(f, "%d", &value) <= 0)
@@ -271,13 +271,13 @@ static void set_ipv6_privacy(gchar *ifname, int value)
gchar *path;
FILE *f;
- if (ifname == NULL)
+ if (!ifname)
return;
path = g_strdup_printf("/proc/sys/net/ipv6/conf/%s/use_tempaddr",
ifname);
- if (path == NULL)
+ if (!path)
return;
if (value < 0)
@@ -287,21 +287,21 @@ static void set_ipv6_privacy(gchar *ifname, int value)
g_free(path);
- if (f == NULL)
+ if (!f)
return;
fprintf(f, "%d", value);
fclose(f);
}
-static int get_rp_filter()
+static int get_rp_filter(void)
{
FILE *f;
int value = -EINVAL, tmp;
f = fopen("/proc/sys/net/ipv4/conf/all/rp_filter", "r");
- if (f != NULL) {
+ if (f) {
if (fscanf(f, "%d", &tmp) == 1)
value = tmp;
fclose(f);
@@ -316,7 +316,7 @@ static void set_rp_filter(int value)
f = fopen("/proc/sys/net/ipv4/conf/all/rp_filter", "r+");
- if (f == NULL)
+ if (!f)
return;
fprintf(f, "%d", value);
@@ -348,27 +348,48 @@ void __connman_ipconfig_unset_rp_filter(int old_value)
connman_info("rp_filter restored to %d", old_value);
}
-gboolean __connman_ipconfig_ipv6_privacy_enabled(struct connman_ipconfig *ipconfig)
+bool __connman_ipconfig_ipv6_privacy_enabled(struct connman_ipconfig *ipconfig)
{
- if (ipconfig == NULL)
- return FALSE;
+ if (!ipconfig)
+ return false;
return ipconfig->ipv6_privacy_config == 0 ? FALSE : TRUE;
}
+bool __connman_ipconfig_ipv6_is_enabled(struct connman_ipconfig *ipconfig)
+{
+ struct connman_ipdevice *ipdevice;
+ char *ifname;
+ bool ret;
+
+ if (!ipconfig)
+ return false;
+
+ ipdevice = g_hash_table_lookup(ipdevice_hash,
+ GINT_TO_POINTER(ipconfig->index));
+ if (!ipdevice)
+ return false;
+
+ ifname = connman_inet_ifname(ipconfig->index);
+ ret = get_ipv6_state(ifname);
+ g_free(ifname);
+
+ return ret;
+}
+
static void free_ipdevice(gpointer data)
{
struct connman_ipdevice *ipdevice = data;
+ char *ifname = connman_inet_ifname(ipdevice->index);
- connman_info("%s {remove} index %d", ipdevice->ifname,
- ipdevice->index);
+ connman_info("%s {remove} index %d", ifname, ipdevice->index);
- if (ipdevice->config_ipv4 != NULL) {
+ if (ipdevice->config_ipv4) {
__connman_ipconfig_unref(ipdevice->config_ipv4);
ipdevice->config_ipv4 = NULL;
}
- if (ipdevice->config_ipv6 != NULL) {
+ if (ipdevice->config_ipv6) {
__connman_ipconfig_unref(ipdevice->config_ipv6);
ipdevice->config_ipv6 = NULL;
}
@@ -380,10 +401,10 @@ static void free_ipdevice(gpointer data)
g_free(ipdevice->address);
- set_ipv6_state(ipdevice->ifname, ipdevice->ipv6_enabled);
- set_ipv6_privacy(ipdevice->ifname, ipdevice->ipv6_privacy);
+ set_ipv6_state(ifname, ipdevice->ipv6_enabled);
+ set_ipv6_privacy(ifname, ipdevice->ipv6_privacy);
- g_free(ipdevice->ifname);
+ g_free(ifname);
g_free(ipdevice);
}
@@ -409,19 +430,19 @@ static void __connman_ipconfig_lower_down(struct connman_ipdevice *ipdevice)
}
static void update_stats(struct connman_ipdevice *ipdevice,
- struct rtnl_link_stats *stats)
+ const char *ifname, struct rtnl_link_stats *stats)
{
struct connman_service *service;
if (stats->rx_packets == 0 && stats->tx_packets == 0)
return;
- connman_info("%s {RX} %u packets %u bytes", ipdevice->ifname,
+ connman_info("%s {RX} %u packets %u bytes", ifname,
stats->rx_packets, stats->rx_bytes);
- connman_info("%s {TX} %u packets %u bytes", ipdevice->ifname,
+ connman_info("%s {TX} %u packets %u bytes", ifname,
stats->tx_packets, stats->tx_bytes);
- if (ipdevice->config_ipv4 == NULL && ipdevice->config_ipv6 == NULL)
+ if (!ipdevice->config_ipv4 && !ipdevice->config_ipv6)
return;
if (ipdevice->config_ipv4)
@@ -431,7 +452,7 @@ static void update_stats(struct connman_ipdevice *ipdevice,
else
return;
- if (service == NULL)
+ if (!service)
return;
ipdevice->rx_packets = stats->rx_packets;
@@ -456,78 +477,69 @@ void __connman_ipconfig_newlink(int index, unsigned short type,
struct rtnl_link_stats *stats)
{
struct connman_ipdevice *ipdevice;
- GList *list;
+ GList *list, *ipconfig_copy;
GString *str;
- gboolean up = FALSE, down = FALSE;
- gboolean lower_up = FALSE, lower_down = FALSE;
+ bool up = false, down = false;
+ bool lower_up = false, lower_down = false;
+ char *ifname;
DBG("index %d", index);
if (type == ARPHRD_LOOPBACK)
return;
- ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
- if (ipdevice != NULL) {
- char *ifname = connman_inet_ifname(index);
- if (g_strcmp0(ipdevice->ifname, ifname) != 0) {
- DBG("interface name changed %s -> %s",
- ipdevice->ifname, ifname);
-
- g_free(ipdevice->ifname);
- ipdevice->ifname = ifname;
- } else
- g_free(ifname);
+ ifname = connman_inet_ifname(index);
+ ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
+ if (ipdevice)
goto update;
- }
ipdevice = g_try_new0(struct connman_ipdevice, 1);
- if (ipdevice == NULL)
- return;
+ if (!ipdevice)
+ goto out;
ipdevice->index = index;
- ipdevice->ifname = connman_inet_ifname(index);
ipdevice->type = type;
- ipdevice->ipv6_enabled = get_ipv6_state(ipdevice->ifname);
- ipdevice->ipv6_privacy = get_ipv6_privacy(ipdevice->ifname);
+ ipdevice->ipv6_enabled = get_ipv6_state(ifname);
+ ipdevice->ipv6_privacy = get_ipv6_privacy(ifname);
ipdevice->address = g_strdup(address);
g_hash_table_insert(ipdevice_hash, GINT_TO_POINTER(index), ipdevice);
- connman_info("%s {create} index %d type %d <%s>", ipdevice->ifname,
+ connman_info("%s {create} index %d type %d <%s>", ifname,
index, type, type2str(type));
update:
ipdevice->mtu = mtu;
- update_stats(ipdevice, stats);
+ update_stats(ipdevice, ifname, stats);
if (flags == ipdevice->flags)
- return;
+ goto out;
if ((ipdevice->flags & IFF_UP) != (flags & IFF_UP)) {
if (flags & IFF_UP)
- up = TRUE;
+ up = true;
else
- down = TRUE;
+ down = true;
}
if ((ipdevice->flags & (IFF_RUNNING | IFF_LOWER_UP)) !=
(flags & (IFF_RUNNING | IFF_LOWER_UP))) {
if ((flags & (IFF_RUNNING | IFF_LOWER_UP)) ==
(IFF_RUNNING | IFF_LOWER_UP))
- lower_up = TRUE;
+ lower_up = true;
else if ((flags & (IFF_RUNNING | IFF_LOWER_UP)) == 0)
- lower_down = TRUE;
+ lower_down = true;
}
ipdevice->flags = flags;
str = g_string_new(NULL);
- if (str == NULL)
- return;
+ if (!str)
+ goto out;
if (flags & IFF_UP)
g_string_append(str, "UP");
@@ -540,50 +552,59 @@ update:
if (flags & IFF_LOWER_UP)
g_string_append(str, ",LOWER_UP");
- connman_info("%s {update} flags %u <%s>", ipdevice->ifname,
- flags, str->str);
+ connman_info("%s {update} flags %u <%s>", ifname, flags, str->str);
g_string_free(str, TRUE);
- for (list = g_list_first(ipconfig_list); list;
+ ipconfig_copy = g_list_copy(ipconfig_list);
+
+ for (list = g_list_first(ipconfig_copy); list;
list = g_list_next(list)) {
struct connman_ipconfig *ipconfig = list->data;
if (index != ipconfig->index)
continue;
- if (ipconfig->ops == NULL)
+ if (!ipconfig->ops)
continue;
- if (up == TRUE && ipconfig->ops->up)
- ipconfig->ops->up(ipconfig);
- if (lower_up == TRUE && ipconfig->ops->lower_up)
- ipconfig->ops->lower_up(ipconfig);
+ if (up && ipconfig->ops->up)
+ ipconfig->ops->up(ipconfig, ifname);
+ if (lower_up && ipconfig->ops->lower_up)
+ ipconfig->ops->lower_up(ipconfig, ifname);
- if (lower_down == TRUE && ipconfig->ops->lower_down)
- ipconfig->ops->lower_down(ipconfig);
- if (down == TRUE && ipconfig->ops->down)
- ipconfig->ops->down(ipconfig);
+ if (lower_down && ipconfig->ops->lower_down)
+ ipconfig->ops->lower_down(ipconfig, ifname);
+ if (down && ipconfig->ops->down)
+ ipconfig->ops->down(ipconfig, ifname);
}
+ g_list_free(ipconfig_copy);
+
if (lower_up)
__connman_ipconfig_lower_up(ipdevice);
if (lower_down)
__connman_ipconfig_lower_down(ipdevice);
+
+out:
+ g_free(ifname);
}
void __connman_ipconfig_dellink(int index, struct rtnl_link_stats *stats)
{
struct connman_ipdevice *ipdevice;
GList *list;
+ char *ifname;
DBG("index %d", index);
ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
- if (ipdevice == NULL)
+ if (!ipdevice)
return;
- update_stats(ipdevice, stats);
+ ifname = connman_inet_ifname(index);
+
+ update_stats(ipdevice, ifname, stats);
for (list = g_list_first(ipconfig_list); list;
list = g_list_next(list)) {
@@ -594,15 +615,17 @@ void __connman_ipconfig_dellink(int index, struct rtnl_link_stats *stats)
ipconfig->index = -1;
- if (ipconfig->ops == NULL)
+ if (!ipconfig->ops)
continue;
if (ipconfig->ops->lower_down)
- ipconfig->ops->lower_down(ipconfig);
+ ipconfig->ops->lower_down(ipconfig, ifname);
if (ipconfig->ops->down)
- ipconfig->ops->down(ipconfig);
+ ipconfig->ops->down(ipconfig, ifname);
}
+ g_free(ifname);
+
__connman_ipconfig_lower_down(ipdevice);
g_hash_table_remove(ipdevice_hash, GINT_TO_POINTER(index));
@@ -626,15 +649,16 @@ void __connman_ipconfig_newaddr(int index, int family, const char *label,
struct connman_ipaddress *ipaddress;
enum connman_ipconfig_type type;
GList *list;
+ char *ifname;
DBG("index %d", index);
ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
- if (ipdevice == NULL)
+ if (!ipdevice)
return;
ipaddress = connman_ipaddress_alloc(family);
- if (ipaddress == NULL)
+ if (!ipaddress)
return;
ipaddress->prefixlen = prefixlen;
@@ -656,21 +680,22 @@ void __connman_ipconfig_newaddr(int index, int family, const char *label,
ipdevice->address_list = g_slist_prepend(ipdevice->address_list,
ipaddress);
+ ifname = connman_inet_ifname(index);
connman_info("%s {add} address %s/%u label %s family %d",
- ipdevice->ifname, address, prefixlen, label, family);
+ ifname, address, prefixlen, label, family);
if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
__connman_ippool_newaddr(index, address, prefixlen);
- if (ipdevice->config_ipv4 != NULL && family == AF_INET)
+ if (ipdevice->config_ipv4 && family == AF_INET)
connman_ipaddress_copy_address(ipdevice->config_ipv4->system,
ipaddress);
- else if (ipdevice->config_ipv6 != NULL && family == AF_INET6)
+ else if (ipdevice->config_ipv6 && family == AF_INET6)
connman_ipaddress_copy_address(ipdevice->config_ipv6->system,
ipaddress);
else
- return;
+ goto out;
if ((ipdevice->flags & (IFF_RUNNING | IFF_LOWER_UP)) != (IFF_RUNNING | IFF_LOWER_UP))
return;
@@ -685,12 +710,15 @@ void __connman_ipconfig_newaddr(int index, int family, const char *label,
if (type != ipconfig->type)
continue;
- if (ipconfig->ops == NULL)
+ if (!ipconfig->ops)
continue;
if (ipconfig->ops->ip_bound)
- ipconfig->ops->ip_bound(ipconfig);
+ ipconfig->ops->ip_bound(ipconfig, ifname);
}
+
+out:
+ g_free(ifname);
}
void __connman_ipconfig_deladdr(int index, int family, const char *label,
@@ -700,15 +728,16 @@ void __connman_ipconfig_deladdr(int index, int family, const char *label,
struct connman_ipaddress *ipaddress;
enum connman_ipconfig_type type;
GList *list;
+ char *ifname;
DBG("index %d", index);
ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
- if (ipdevice == NULL)
+ if (!ipdevice)
return;
ipaddress = find_ipaddress(ipdevice, prefixlen, address);
- if (ipaddress == NULL)
+ if (!ipaddress)
return;
if (family == AF_INET)
@@ -727,14 +756,15 @@ void __connman_ipconfig_deladdr(int index, int family, const char *label,
connman_ipaddress_clear(ipaddress);
g_free(ipaddress);
- connman_info("%s {del} address %s/%u label %s", ipdevice->ifname,
+ ifname = connman_inet_ifname(index);
+ connman_info("%s {del} address %s/%u label %s", ifname,
address, prefixlen, label);
if ((ipdevice->flags & (IFF_RUNNING | IFF_LOWER_UP)) != (IFF_RUNNING | IFF_LOWER_UP))
- return;
+ goto out;
if (g_slist_length(ipdevice->address_list) > 0)
- return;
+ goto out;
for (list = g_list_first(ipconfig_list); list;
list = g_list_next(list)) {
@@ -746,25 +776,31 @@ void __connman_ipconfig_deladdr(int index, int family, const char *label,
if (type != ipconfig->type)
continue;
- if (ipconfig->ops == NULL)
+ if (!ipconfig->ops)
continue;
if (ipconfig->ops->ip_release)
- ipconfig->ops->ip_release(ipconfig);
+ ipconfig->ops->ip_release(ipconfig, ifname);
}
+
+out:
+ g_free(ifname);
}
void __connman_ipconfig_newroute(int index, int family, unsigned char scope,
const char *dst, const char *gateway)
{
struct connman_ipdevice *ipdevice;
+ char *ifname;
DBG("index %d", index);
ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
- if (ipdevice == NULL)
+ if (!ipdevice)
return;
+ ifname = connman_inet_ifname(index);
+
if (scope == 0 && (g_strcmp0(dst, "0.0.0.0") == 0 ||
g_strcmp0(dst, "::") == 0)) {
GList *config_list;
@@ -775,8 +811,8 @@ void __connman_ipconfig_newroute(int index, int family, unsigned char scope,
g_free(ipdevice->ipv6_gateway);
ipdevice->ipv6_gateway = g_strdup(gateway);
- if (ipdevice->config_ipv6 != NULL &&
- ipdevice->config_ipv6->system != NULL) {
+ if (ipdevice->config_ipv6 &&
+ ipdevice->config_ipv6->system) {
g_free(ipdevice->config_ipv6->system->gateway);
ipdevice->config_ipv6->system->gateway =
g_strdup(gateway);
@@ -786,14 +822,14 @@ void __connman_ipconfig_newroute(int index, int family, unsigned char scope,
g_free(ipdevice->ipv4_gateway);
ipdevice->ipv4_gateway = g_strdup(gateway);
- if (ipdevice->config_ipv4 != NULL &&
- ipdevice->config_ipv4->system != NULL) {
+ if (ipdevice->config_ipv4 &&
+ ipdevice->config_ipv4->system) {
g_free(ipdevice->config_ipv4->system->gateway);
ipdevice->config_ipv4->system->gateway =
g_strdup(gateway);
}
} else
- return;
+ goto out;
for (config_list = g_list_first(ipconfig_list); config_list;
config_list = g_list_next(config_list)) {
@@ -805,30 +841,35 @@ void __connman_ipconfig_newroute(int index, int family, unsigned char scope,
if (type != ipconfig->type)
continue;
- if (ipconfig->ops == NULL)
+ if (!ipconfig->ops)
continue;
if (ipconfig->ops->route_set)
- ipconfig->ops->route_set(ipconfig);
+ ipconfig->ops->route_set(ipconfig, ifname);
}
}
connman_info("%s {add} route %s gw %s scope %u <%s>",
- ipdevice->ifname, dst, gateway,
- scope, scope2str(scope));
+ ifname, dst, gateway, scope, scope2str(scope));
+
+out:
+ g_free(ifname);
}
void __connman_ipconfig_delroute(int index, int family, unsigned char scope,
const char *dst, const char *gateway)
{
struct connman_ipdevice *ipdevice;
+ char *ifname;
DBG("index %d", index);
ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
- if (ipdevice == NULL)
+ if (!ipdevice)
return;
+ ifname = connman_inet_ifname(index);
+
if (scope == 0 && (g_strcmp0(dst, "0.0.0.0") == 0 ||
g_strcmp0(dst, "::") == 0)) {
GList *config_list;
@@ -839,8 +880,8 @@ void __connman_ipconfig_delroute(int index, int family, unsigned char scope,
g_free(ipdevice->ipv6_gateway);
ipdevice->ipv6_gateway = NULL;
- if (ipdevice->config_ipv6 != NULL &&
- ipdevice->config_ipv6->system != NULL) {
+ if (ipdevice->config_ipv6 &&
+ ipdevice->config_ipv6->system) {
g_free(ipdevice->config_ipv6->system->gateway);
ipdevice->config_ipv6->system->gateway = NULL;
}
@@ -849,13 +890,13 @@ void __connman_ipconfig_delroute(int index, int family, unsigned char scope,
g_free(ipdevice->ipv4_gateway);
ipdevice->ipv4_gateway = NULL;
- if (ipdevice->config_ipv4 != NULL &&
- ipdevice->config_ipv4->system != NULL) {
+ if (ipdevice->config_ipv4 &&
+ ipdevice->config_ipv4->system) {
g_free(ipdevice->config_ipv4->system->gateway);
ipdevice->config_ipv4->system->gateway = NULL;
}
} else
- return;
+ goto out;
for (config_list = g_list_first(ipconfig_list); config_list;
config_list = g_list_next(config_list)) {
@@ -867,17 +908,19 @@ void __connman_ipconfig_delroute(int index, int family, unsigned char scope,
if (type != ipconfig->type)
continue;
- if (ipconfig->ops == NULL)
+ if (!ipconfig->ops)
continue;
if (ipconfig->ops->route_unset)
- ipconfig->ops->route_unset(ipconfig);
+ ipconfig->ops->route_unset(ipconfig, ifname);
}
}
connman_info("%s {del} route %s gw %s scope %u <%s>",
- ipdevice->ifname, dst, gateway,
- scope, scope2str(scope));
+ ifname, dst, gateway, scope, scope2str(scope));
+
+out:
+ g_free(ifname);
}
void __connman_ipconfig_foreach(void (*function) (int index, void *user_data),
@@ -886,7 +929,7 @@ void __connman_ipconfig_foreach(void (*function) (int index, void *user_data),
GList *list, *keys;
keys = g_hash_table_get_keys(ipdevice_hash);
- if (keys == NULL)
+ if (!keys)
return;
for (list = g_list_first(keys); list; list = g_list_next(list)) {
@@ -909,7 +952,7 @@ unsigned short __connman_ipconfig_get_type_from_index(int index)
struct connman_ipdevice *ipdevice;
ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
- if (ipdevice == NULL)
+ if (!ipdevice)
return ARPHRD_VOID;
return ipdevice->type;
@@ -920,7 +963,7 @@ unsigned int __connman_ipconfig_get_flags_from_index(int index)
struct connman_ipdevice *ipdevice;
ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
- if (ipdevice == NULL)
+ if (!ipdevice)
return 0;
return ipdevice->flags;
@@ -932,24 +975,24 @@ const char *__connman_ipconfig_get_gateway_from_index(int index,
struct connman_ipdevice *ipdevice;
ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
- if (ipdevice == NULL)
+ if (!ipdevice)
return NULL;
if (type != CONNMAN_IPCONFIG_TYPE_IPV6) {
- if (ipdevice->ipv4_gateway != NULL)
+ if (ipdevice->ipv4_gateway)
return ipdevice->ipv4_gateway;
- if (ipdevice->config_ipv4 != NULL &&
- ipdevice->config_ipv4->address != NULL)
+ if (ipdevice->config_ipv4 &&
+ ipdevice->config_ipv4->address)
return ipdevice->config_ipv4->address->gateway;
}
if (type != CONNMAN_IPCONFIG_TYPE_IPV4) {
- if (ipdevice->ipv6_gateway != NULL)
+ if (ipdevice->ipv6_gateway)
return ipdevice->ipv6_gateway;
- if (ipdevice->config_ipv6 != NULL &&
- ipdevice->config_ipv6->address != NULL)
+ if (ipdevice->config_ipv6 &&
+ ipdevice->config_ipv6->address)
return ipdevice->config_ipv6->address->gateway;
}
@@ -963,15 +1006,16 @@ void __connman_ipconfig_set_index(struct connman_ipconfig *ipconfig, int index)
const char *__connman_ipconfig_get_local(struct connman_ipconfig *ipconfig)
{
- if (ipconfig->address == NULL)
+ if (!ipconfig->address)
return NULL;
return ipconfig->address->local;
}
-void __connman_ipconfig_set_local(struct connman_ipconfig *ipconfig, const char *address)
+void __connman_ipconfig_set_local(struct connman_ipconfig *ipconfig,
+ const char *address)
{
- if (ipconfig->address == NULL)
+ if (!ipconfig->address)
return;
g_free(ipconfig->address->local);
@@ -980,15 +1024,16 @@ void __connman_ipconfig_set_local(struct connman_ipconfig *ipconfig, const char
const char *__connman_ipconfig_get_peer(struct connman_ipconfig *ipconfig)
{
- if (ipconfig->address == NULL)
+ if (!ipconfig->address)
return NULL;
return ipconfig->address->peer;
}
-void __connman_ipconfig_set_peer(struct connman_ipconfig *ipconfig, const char *address)
+void __connman_ipconfig_set_peer(struct connman_ipconfig *ipconfig,
+ const char *address)
{
- if (ipconfig->address == NULL)
+ if (!ipconfig->address)
return;
g_free(ipconfig->address->peer);
@@ -997,15 +1042,16 @@ void __connman_ipconfig_set_peer(struct connman_ipconfig *ipconfig, const char *
const char *__connman_ipconfig_get_broadcast(struct connman_ipconfig *ipconfig)
{
- if (ipconfig->address == NULL)
+ if (!ipconfig->address)
return NULL;
return ipconfig->address->broadcast;
}
-void __connman_ipconfig_set_broadcast(struct connman_ipconfig *ipconfig, const char *broadcast)
+void __connman_ipconfig_set_broadcast(struct connman_ipconfig *ipconfig,
+ const char *broadcast)
{
- if (ipconfig->address == NULL)
+ if (!ipconfig->address)
return;
g_free(ipconfig->address->broadcast);
@@ -1014,17 +1060,18 @@ void __connman_ipconfig_set_broadcast(struct connman_ipconfig *ipconfig, const c
const char *__connman_ipconfig_get_gateway(struct connman_ipconfig *ipconfig)
{
- if (ipconfig->address == NULL)
+ if (!ipconfig->address)
return NULL;
return ipconfig->address->gateway;
}
-void __connman_ipconfig_set_gateway(struct connman_ipconfig *ipconfig, const char *gateway)
+void __connman_ipconfig_set_gateway(struct connman_ipconfig *ipconfig,
+ const char *gateway)
{
DBG("");
- if (ipconfig->address == NULL)
+ if (!ipconfig->address)
return;
g_free(ipconfig->address->gateway);
ipconfig->address->gateway = g_strdup(gateway);
@@ -1036,11 +1083,11 @@ int __connman_ipconfig_gateway_add(struct connman_ipconfig *ipconfig)
DBG("");
- if (ipconfig->address == NULL)
+ if (!ipconfig->address)
return -EINVAL;
service = __connman_service_lookup_from_index(ipconfig->index);
- if (service == NULL)
+ if (!service)
return -EINVAL;
__connman_connection_gateway_remove(service, ipconfig->type);
@@ -1065,21 +1112,22 @@ void __connman_ipconfig_gateway_remove(struct connman_ipconfig *ipconfig)
DBG("");
service = __connman_service_lookup_from_index(ipconfig->index);
- if (service != NULL)
+ if (service)
__connman_connection_gateway_remove(service, ipconfig->type);
}
unsigned char __connman_ipconfig_get_prefixlen(struct connman_ipconfig *ipconfig)
{
- if (ipconfig->address == NULL)
+ if (!ipconfig->address)
return 0;
return ipconfig->address->prefixlen;
}
-void __connman_ipconfig_set_prefixlen(struct connman_ipconfig *ipconfig, unsigned char prefixlen)
+void __connman_ipconfig_set_prefixlen(struct connman_ipconfig *ipconfig,
+ unsigned char prefixlen)
{
- if (ipconfig->address == NULL)
+ if (!ipconfig->address)
return;
ipconfig->address->prefixlen = prefixlen;
@@ -1093,26 +1141,26 @@ static struct connman_ipconfig *create_ipv6config(int index)
DBG("index %d", index);
ipv6config = g_try_new0(struct connman_ipconfig, 1);
- if (ipv6config == NULL)
+ if (!ipv6config)
return NULL;
ipv6config->refcount = 1;
ipv6config->index = index;
- ipv6config->enabled = FALSE;
+ ipv6config->enabled = false;
ipv6config->type = CONNMAN_IPCONFIG_TYPE_IPV6;
- if (is_ipv6_supported == FALSE)
+ if (!is_ipv6_supported)
ipv6config->method = CONNMAN_IPCONFIG_METHOD_OFF;
else
ipv6config->method = CONNMAN_IPCONFIG_METHOD_AUTO;
ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
- if (ipdevice != NULL)
+ if (ipdevice)
ipv6config->ipv6_privacy_config = ipdevice->ipv6_privacy;
ipv6config->address = connman_ipaddress_alloc(AF_INET6);
- if (ipv6config->address == NULL) {
+ if (!ipv6config->address) {
g_free(ipv6config);
return NULL;
}
@@ -1143,17 +1191,17 @@ struct connman_ipconfig *__connman_ipconfig_create(int index,
DBG("index %d", index);
ipconfig = g_try_new0(struct connman_ipconfig, 1);
- if (ipconfig == NULL)
+ if (!ipconfig)
return NULL;
ipconfig->refcount = 1;
ipconfig->index = index;
- ipconfig->enabled = FALSE;
+ ipconfig->enabled = false;
ipconfig->type = CONNMAN_IPCONFIG_TYPE_IPV4;
ipconfig->address = connman_ipaddress_alloc(AF_INET);
- if (ipconfig->address == NULL) {
+ if (!ipconfig->address) {
g_free(ipconfig);
return NULL;
}
@@ -1193,7 +1241,7 @@ __connman_ipconfig_ref_debug(struct connman_ipconfig *ipconfig,
void __connman_ipconfig_unref_debug(struct connman_ipconfig *ipconfig,
const char *file, int line, const char *caller)
{
- if (ipconfig == NULL)
+ if (!ipconfig)
return;
DBG("%p ref %d by %s:%d:%s()", ipconfig, ipconfig->refcount - 1,
@@ -1207,7 +1255,7 @@ void __connman_ipconfig_unref_debug(struct connman_ipconfig *ipconfig,
__connman_ipconfig_set_ops(ipconfig, NULL);
- if (ipconfig->origin != NULL && ipconfig->origin != ipconfig) {
+ if (ipconfig->origin && ipconfig->origin != ipconfig) {
__connman_ipconfig_unref(ipconfig->origin);
ipconfig->origin = NULL;
}
@@ -1215,6 +1263,7 @@ void __connman_ipconfig_unref_debug(struct connman_ipconfig *ipconfig,
connman_ipaddress_free(ipconfig->system);
connman_ipaddress_free(ipconfig->address);
g_free(ipconfig->last_dhcp_address);
+ g_strfreev(ipconfig->last_dhcpv6_prefixes);
g_free(ipconfig);
}
@@ -1226,7 +1275,7 @@ void __connman_ipconfig_unref_debug(struct connman_ipconfig *ipconfig,
*/
void *__connman_ipconfig_get_data(struct connman_ipconfig *ipconfig)
{
- if (ipconfig == NULL)
+ if (!ipconfig)
return NULL;
return ipconfig->ops_data;
@@ -1252,40 +1301,16 @@ void __connman_ipconfig_set_data(struct connman_ipconfig *ipconfig, void *data)
*/
int __connman_ipconfig_get_index(struct connman_ipconfig *ipconfig)
{
- if (ipconfig == NULL)
+ if (!ipconfig)
return -1;
- if (ipconfig->origin != NULL)
+ if (ipconfig->origin)
return ipconfig->origin->index;
return ipconfig->index;
}
/**
- * connman_ipconfig_get_ifname:
- * @ipconfig: ipconfig structure
- *
- * Get interface name
- */
-const char *__connman_ipconfig_get_ifname(struct connman_ipconfig *ipconfig)
-{
- struct connman_ipdevice *ipdevice;
-
- if (ipconfig == NULL)
- return NULL;
-
- if (ipconfig->index < 0)
- return NULL;
-
- ipdevice = g_hash_table_lookup(ipdevice_hash,
- GINT_TO_POINTER(ipconfig->index));
- if (ipdevice == NULL)
- return NULL;
-
- return ipdevice->ifname;
-}
-
-/**
* connman_ipconfig_set_ops:
* @ipconfig: ipconfig structure
* @ops: operation callbacks
@@ -1313,9 +1338,10 @@ int __connman_ipconfig_set_method(struct connman_ipconfig *ipconfig,
return 0;
}
-enum connman_ipconfig_method __connman_ipconfig_get_method(struct connman_ipconfig *ipconfig)
+enum connman_ipconfig_method __connman_ipconfig_get_method(
+ struct connman_ipconfig *ipconfig)
{
- if (ipconfig == NULL)
+ if (!ipconfig)
return CONNMAN_IPCONFIG_METHOD_UNKNOWN;
return ipconfig->method;
@@ -1350,7 +1376,7 @@ int __connman_ipconfig_address_remove(struct connman_ipconfig *ipconfig)
DBG("");
- if (ipconfig == NULL)
+ if (!ipconfig)
return 0;
DBG("method %d", ipconfig->method);
@@ -1378,7 +1404,7 @@ int __connman_ipconfig_address_unset(struct connman_ipconfig *ipconfig)
DBG("");
- if (ipconfig == NULL)
+ if (!ipconfig)
return 0;
DBG("method %d", ipconfig->method);
@@ -1415,12 +1441,12 @@ int __connman_ipconfig_set_proxy_autoconfig(struct connman_ipconfig *ipconfig,
DBG("ipconfig %p", ipconfig);
- if (ipconfig == NULL || ipconfig->index < 0)
+ if (!ipconfig || ipconfig->index < 0)
return -ENODEV;
ipdevice = g_hash_table_lookup(ipdevice_hash,
GINT_TO_POINTER(ipconfig->index));
- if (ipdevice == NULL)
+ if (!ipdevice)
return -ENXIO;
g_free(ipdevice->pac);
@@ -1435,12 +1461,12 @@ const char *__connman_ipconfig_get_proxy_autoconfig(struct connman_ipconfig *ipc
DBG("ipconfig %p", ipconfig);
- if (ipconfig == NULL || ipconfig->index < 0)
+ if (!ipconfig || ipconfig->index < 0)
return NULL;
ipdevice = g_hash_table_lookup(ipdevice_hash,
GINT_TO_POINTER(ipconfig->index));
- if (ipdevice == NULL)
+ if (!ipdevice)
return NULL;
return ipdevice->pac;
@@ -1449,7 +1475,7 @@ const char *__connman_ipconfig_get_proxy_autoconfig(struct connman_ipconfig *ipc
void __connman_ipconfig_set_dhcp_address(struct connman_ipconfig *ipconfig,
const char *address)
{
- if (ipconfig == NULL)
+ if (!ipconfig)
return;
g_free(ipconfig->last_dhcp_address);
@@ -1458,47 +1484,74 @@ void __connman_ipconfig_set_dhcp_address(struct connman_ipconfig *ipconfig,
char *__connman_ipconfig_get_dhcp_address(struct connman_ipconfig *ipconfig)
{
- if (ipconfig == NULL)
+ if (!ipconfig)
return NULL;
return ipconfig->last_dhcp_address;
}
+void __connman_ipconfig_set_dhcpv6_prefixes(struct connman_ipconfig *ipconfig,
+ char **prefixes)
+{
+ if (!ipconfig)
+ return;
+
+ g_strfreev(ipconfig->last_dhcpv6_prefixes);
+ ipconfig->last_dhcpv6_prefixes = prefixes;
+}
+
+char **__connman_ipconfig_get_dhcpv6_prefixes(struct connman_ipconfig *ipconfig)
+{
+ if (!ipconfig)
+ return NULL;
+
+ return ipconfig->last_dhcpv6_prefixes;
+}
+
static void disable_ipv6(struct connman_ipconfig *ipconfig)
{
struct connman_ipdevice *ipdevice;
+ char *ifname;
DBG("");
ipdevice = g_hash_table_lookup(ipdevice_hash,
GINT_TO_POINTER(ipconfig->index));
- if (ipdevice == NULL)
+ if (!ipdevice)
return;
- set_ipv6_state(ipdevice->ifname, FALSE);
+ ifname = connman_inet_ifname(ipconfig->index);
+
+ set_ipv6_state(ifname, false);
+
+ g_free(ifname);
}
static void enable_ipv6(struct connman_ipconfig *ipconfig)
{
struct connman_ipdevice *ipdevice;
+ char *ifname;
DBG("");
ipdevice = g_hash_table_lookup(ipdevice_hash,
GINT_TO_POINTER(ipconfig->index));
- if (ipdevice == NULL)
+ if (!ipdevice)
return;
+ ifname = connman_inet_ifname(ipconfig->index);
+
if (ipconfig->method == CONNMAN_IPCONFIG_METHOD_AUTO)
- set_ipv6_privacy(ipdevice->ifname,
- ipconfig->ipv6_privacy_config);
+ set_ipv6_privacy(ifname, ipconfig->ipv6_privacy_config);
+
+ set_ipv6_state(ifname, true);
- set_ipv6_state(ipdevice->ifname, TRUE);
+ g_free(ifname);
}
void __connman_ipconfig_enable_ipv6(struct connman_ipconfig *ipconfig)
{
- if (ipconfig == NULL || ipconfig->type != CONNMAN_IPCONFIG_TYPE_IPV6)
+ if (!ipconfig || ipconfig->type != CONNMAN_IPCONFIG_TYPE_IPV6)
return;
enable_ipv6(ipconfig);
@@ -1506,21 +1559,21 @@ void __connman_ipconfig_enable_ipv6(struct connman_ipconfig *ipconfig)
void __connman_ipconfig_disable_ipv6(struct connman_ipconfig *ipconfig)
{
- if (ipconfig == NULL || ipconfig->type != CONNMAN_IPCONFIG_TYPE_IPV6)
+ if (!ipconfig || ipconfig->type != CONNMAN_IPCONFIG_TYPE_IPV6)
return;
disable_ipv6(ipconfig);
}
-connman_bool_t __connman_ipconfig_is_usable(struct connman_ipconfig *ipconfig)
+bool __connman_ipconfig_is_usable(struct connman_ipconfig *ipconfig)
{
- if (ipconfig == NULL)
- return FALSE;
+ if (!ipconfig)
+ return false;
switch (ipconfig->method) {
case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
case CONNMAN_IPCONFIG_METHOD_OFF:
- return FALSE;
+ return false;
case CONNMAN_IPCONFIG_METHOD_AUTO:
case CONNMAN_IPCONFIG_METHOD_FIXED:
case CONNMAN_IPCONFIG_METHOD_DHCP:
@@ -1528,24 +1581,25 @@ connman_bool_t __connman_ipconfig_is_usable(struct connman_ipconfig *ipconfig)
break;
}
- return TRUE;
+ return true;
}
int __connman_ipconfig_enable(struct connman_ipconfig *ipconfig)
{
struct connman_ipdevice *ipdevice;
- gboolean up = FALSE, down = FALSE;
- gboolean lower_up = FALSE, lower_down = FALSE;
+ bool up = false, down = false;
+ bool lower_up = false, lower_down = false;
enum connman_ipconfig_type type;
+ char *ifname;
DBG("ipconfig %p", ipconfig);
- if (ipconfig == NULL || ipconfig->index < 0)
+ if (!ipconfig || ipconfig->index < 0)
return -ENODEV;
ipdevice = g_hash_table_lookup(ipdevice_hash,
GINT_TO_POINTER(ipconfig->index));
- if (ipdevice == NULL)
+ if (!ipdevice)
return -ENXIO;
if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV4) {
@@ -1559,10 +1613,10 @@ int __connman_ipconfig_enable(struct connman_ipconfig *ipconfig)
} else
return -EINVAL;
- ipconfig->enabled = TRUE;
+ ipconfig->enabled = true;
if (type == CONNMAN_IPCONFIG_TYPE_IPV4 &&
- ipdevice->config_ipv4 != NULL) {
+ ipdevice->config_ipv4) {
ipconfig_list = g_list_remove(ipconfig_list,
ipdevice->config_ipv4);
@@ -1572,7 +1626,7 @@ int __connman_ipconfig_enable(struct connman_ipconfig *ipconfig)
}
if (type == CONNMAN_IPCONFIG_TYPE_IPV6 &&
- ipdevice->config_ipv6 != NULL) {
+ ipdevice->config_ipv6) {
ipconfig_list = g_list_remove(ipconfig_list,
ipdevice->config_ipv6);
@@ -1591,25 +1645,29 @@ int __connman_ipconfig_enable(struct connman_ipconfig *ipconfig)
ipconfig_list = g_list_append(ipconfig_list, ipconfig);
if (ipdevice->flags & IFF_UP)
- up = TRUE;
+ up = true;
else
- down = TRUE;
+ down = true;
if ((ipdevice->flags & (IFF_RUNNING | IFF_LOWER_UP)) ==
(IFF_RUNNING | IFF_LOWER_UP))
- lower_up = TRUE;
+ lower_up = true;
else if ((ipdevice->flags & (IFF_RUNNING | IFF_LOWER_UP)) == 0)
- lower_down = TRUE;
+ lower_down = true;
- if (up == TRUE && ipconfig->ops->up)
- ipconfig->ops->up(ipconfig);
- if (lower_up == TRUE && ipconfig->ops->lower_up)
- ipconfig->ops->lower_up(ipconfig);
+ ifname = connman_inet_ifname(ipconfig->index);
- if (lower_down == TRUE && ipconfig->ops->lower_down)
- ipconfig->ops->lower_down(ipconfig);
- if (down == TRUE && ipconfig->ops->down)
- ipconfig->ops->down(ipconfig);
+ if (up && ipconfig->ops->up)
+ ipconfig->ops->up(ipconfig, ifname);
+ if (lower_up && ipconfig->ops->lower_up)
+ ipconfig->ops->lower_up(ipconfig, ifname);
+
+ if (lower_down && ipconfig->ops->lower_down)
+ ipconfig->ops->lower_down(ipconfig, ifname);
+ if (down && ipconfig->ops->down)
+ ipconfig->ops->down(ipconfig, ifname);
+
+ g_free(ifname);
return 0;
}
@@ -1620,18 +1678,18 @@ int __connman_ipconfig_disable(struct connman_ipconfig *ipconfig)
DBG("ipconfig %p", ipconfig);
- if (ipconfig == NULL || ipconfig->index < 0)
+ if (!ipconfig || ipconfig->index < 0)
return -ENODEV;
ipdevice = g_hash_table_lookup(ipdevice_hash,
GINT_TO_POINTER(ipconfig->index));
- if (ipdevice == NULL)
+ if (!ipdevice)
return -ENXIO;
- if (ipdevice->config_ipv4 == NULL && ipdevice->config_ipv6 == NULL)
+ if (!ipdevice->config_ipv4 && !ipdevice->config_ipv6)
return -EINVAL;
- ipconfig->enabled = FALSE;
+ ipconfig->enabled = false;
if (ipdevice->config_ipv4 == ipconfig) {
ipconfig_list = g_list_remove(ipconfig_list, ipconfig);
@@ -1700,10 +1758,8 @@ static const char *privacy2string(int privacy)
return "disabled";
else if (privacy == 1)
return "enabled";
- else if (privacy > 1)
+ else
return "prefered";
-
- return "disabled";
}
static int string2privacy(const char *privacy)
@@ -1712,6 +1768,8 @@ static int string2privacy(const char *privacy)
return 0;
else if (g_strcmp0(privacy, "enabled") == 0)
return 1;
+ else if (g_strcmp0(privacy, "preferred") == 0)
+ return 2;
else if (g_strcmp0(privacy, "prefered") == 0)
return 2;
else
@@ -1723,7 +1781,7 @@ int __connman_ipconfig_ipv6_set_privacy(struct connman_ipconfig *ipconfig,
{
int privacy;
- if (ipconfig == NULL)
+ if (!ipconfig)
return -EINVAL;
DBG("ipconfig %p privacy %s", ipconfig, value);
@@ -1749,7 +1807,7 @@ void __connman_ipconfig_append_ipv4(struct connman_ipconfig *ipconfig,
return;
str = __connman_ipconfig_method2string(ipconfig->method);
- if (str == NULL)
+ if (!str)
return;
connman_dbus_dict_append_basic(iter, "Method", DBUS_TYPE_STRING, &str);
@@ -1770,10 +1828,10 @@ void __connman_ipconfig_append_ipv4(struct connman_ipconfig *ipconfig,
break;
}
- if (append_addr == NULL)
+ if (!append_addr)
return;
- if (append_addr->local != NULL) {
+ if (append_addr->local) {
in_addr_t addr;
struct in_addr netmask;
char *mask;
@@ -1788,7 +1846,7 @@ void __connman_ipconfig_append_ipv4(struct connman_ipconfig *ipconfig,
DBUS_TYPE_STRING, &mask);
}
- if (append_addr->gateway != NULL)
+ if (append_addr->gateway)
connman_dbus_dict_append_basic(iter, "Gateway",
DBUS_TYPE_STRING, &append_addr->gateway);
}
@@ -1806,10 +1864,10 @@ void __connman_ipconfig_append_ipv6(struct connman_ipconfig *ipconfig,
return;
str = __connman_ipconfig_method2string(ipconfig->method);
- if (str == NULL)
+ if (!str)
return;
- if (ipconfig_ipv4 != NULL &&
+ if (ipconfig_ipv4 &&
ipconfig->method == CONNMAN_IPCONFIG_METHOD_AUTO) {
if (__connman_6to4_check(ipconfig_ipv4) == 1)
str = "6to4";
@@ -1833,10 +1891,10 @@ void __connman_ipconfig_append_ipv6(struct connman_ipconfig *ipconfig,
break;
}
- if (append_addr == NULL)
+ if (!append_addr)
return;
- if (append_addr->local != NULL) {
+ if (append_addr->local) {
connman_dbus_dict_append_basic(iter, "Address",
DBUS_TYPE_STRING, &append_addr->local);
connman_dbus_dict_append_basic(iter, "PrefixLength",
@@ -1844,7 +1902,7 @@ void __connman_ipconfig_append_ipv6(struct connman_ipconfig *ipconfig,
&append_addr->prefixlen);
}
- if (append_addr->gateway != NULL)
+ if (append_addr->gateway)
connman_dbus_dict_append_basic(iter, "Gateway",
DBUS_TYPE_STRING, &append_addr->gateway);
@@ -1861,7 +1919,7 @@ void __connman_ipconfig_append_ipv6config(struct connman_ipconfig *ipconfig,
DBG("");
str = __connman_ipconfig_method2string(ipconfig->method);
- if (str == NULL)
+ if (!str)
return;
connman_dbus_dict_append_basic(iter, "Method", DBUS_TYPE_STRING, &str);
@@ -1877,10 +1935,10 @@ void __connman_ipconfig_append_ipv6config(struct connman_ipconfig *ipconfig,
break;
}
- if (ipconfig->address == NULL)
+ if (!ipconfig->address)
return;
- if (ipconfig->address->local != NULL) {
+ if (ipconfig->address->local) {
connman_dbus_dict_append_basic(iter, "Address",
DBUS_TYPE_STRING, &ipconfig->address->local);
connman_dbus_dict_append_basic(iter, "PrefixLength",
@@ -1888,7 +1946,7 @@ void __connman_ipconfig_append_ipv6config(struct connman_ipconfig *ipconfig,
&ipconfig->address->prefixlen);
}
- if (ipconfig->address->gateway != NULL)
+ if (ipconfig->address->gateway)
connman_dbus_dict_append_basic(iter, "Gateway",
DBUS_TYPE_STRING, &ipconfig->address->gateway);
@@ -1905,7 +1963,7 @@ void __connman_ipconfig_append_ipv4config(struct connman_ipconfig *ipconfig,
DBG("");
str = __connman_ipconfig_method2string(ipconfig->method);
- if (str == NULL)
+ if (!str)
return;
connman_dbus_dict_append_basic(iter, "Method", DBUS_TYPE_STRING, &str);
@@ -1921,10 +1979,10 @@ void __connman_ipconfig_append_ipv4config(struct connman_ipconfig *ipconfig,
break;
}
- if (ipconfig->address == NULL)
+ if (!ipconfig->address)
return;
- if (ipconfig->address->local != NULL) {
+ if (ipconfig->address->local) {
in_addr_t addr;
struct in_addr netmask;
char *mask;
@@ -1939,7 +1997,7 @@ void __connman_ipconfig_append_ipv4config(struct connman_ipconfig *ipconfig,
DBUS_TYPE_STRING, &mask);
}
- if (ipconfig->address->gateway != NULL)
+ if (ipconfig->address->gateway)
connman_dbus_dict_append_basic(iter, "Gateway",
DBUS_TYPE_STRING, &ipconfig->address->gateway);
}
@@ -1981,7 +2039,7 @@ int __connman_ipconfig_set_config(struct connman_ipconfig *ipconfig,
type = dbus_message_iter_get_arg_type(&value);
- if (g_str_equal(key, "Method") == TRUE) {
+ if (g_str_equal(key, "Method")) {
const char *str;
if (type != DBUS_TYPE_STRING)
@@ -1989,12 +2047,12 @@ int __connman_ipconfig_set_config(struct connman_ipconfig *ipconfig,
dbus_message_iter_get_basic(&value, &str);
method = __connman_ipconfig_string2method(str);
- } else if (g_str_equal(key, "Address") == TRUE) {
+ } else if (g_str_equal(key, "Address")) {
if (type != DBUS_TYPE_STRING)
return -EINVAL;
dbus_message_iter_get_basic(&value, &address);
- } else if (g_str_equal(key, "PrefixLength") == TRUE) {
+ } else if (g_str_equal(key, "PrefixLength")) {
if (type != DBUS_TYPE_BYTE)
return -EINVAL;
@@ -2002,17 +2060,17 @@ int __connman_ipconfig_set_config(struct connman_ipconfig *ipconfig,
if (prefix_length < 0 || prefix_length > 128)
return -EINVAL;
- } else if (g_str_equal(key, "Netmask") == TRUE) {
+ } else if (g_str_equal(key, "Netmask")) {
if (type != DBUS_TYPE_STRING)
return -EINVAL;
dbus_message_iter_get_basic(&value, &netmask);
- } else if (g_str_equal(key, "Gateway") == TRUE) {
+ } else if (g_str_equal(key, "Gateway")) {
if (type != DBUS_TYPE_STRING)
return -EINVAL;
dbus_message_iter_get_basic(&value, &gateway);
- } else if (g_str_equal(key, "Privacy") == TRUE) {
+ } else if (g_str_equal(key, "Privacy")) {
if (type != DBUS_TYPE_STRING)
return -EINVAL;
@@ -2044,7 +2102,7 @@ int __connman_ipconfig_set_config(struct connman_ipconfig *ipconfig,
return -EOPNOTSUPP;
ipconfig->method = method;
- if (privacy_string != NULL)
+ if (privacy_string)
ipconfig->ipv6_privacy_config = privacy;
enable_ipv6(ipconfig);
break;
@@ -2062,12 +2120,12 @@ int __connman_ipconfig_set_config(struct connman_ipconfig *ipconfig,
break;
}
- if ((address != NULL && connman_inet_check_ipaddress(address)
+ if ((address && connman_inet_check_ipaddress(address)
!= type) ||
- (netmask != NULL &&
+ (netmask &&
connman_inet_check_ipaddress(netmask)
!= type) ||
- (gateway != NULL &&
+ (gateway &&
connman_inet_check_ipaddress(gateway)
!= type))
return -EINVAL;
@@ -2105,14 +2163,17 @@ void __connman_ipconfig_append_ethernet(struct connman_ipconfig *ipconfig,
ipdevice = g_hash_table_lookup(ipdevice_hash,
GINT_TO_POINTER(ipconfig->index));
- if (ipdevice == NULL)
+ if (!ipdevice)
return;
- if (ipdevice->ifname != NULL)
+ if (ipconfig->index >= 0) {
+ char *ifname = connman_inet_ifname(ipconfig->index);
connman_dbus_dict_append_basic(iter, "Interface",
- DBUS_TYPE_STRING, &ipdevice->ifname);
+ DBUS_TYPE_STRING, &ifname);
+ g_free(ifname);
+ }
- if (ipdevice->address != NULL)
+ if (ipdevice->address)
connman_dbus_dict_append_basic(iter, "Address",
DBUS_TYPE_STRING, &ipdevice->address);
@@ -2132,7 +2193,7 @@ int __connman_ipconfig_load(struct connman_ipconfig *ipconfig,
key = g_strdup_printf("%smethod", prefix);
method = g_key_file_get_string(keyfile, identifier, key, NULL);
- if (method == NULL) {
+ if (!method) {
switch (ipconfig->type) {
case CONNMAN_IPCONFIG_TYPE_IPV4:
ipconfig->method = CONNMAN_IPCONFIG_METHOD_DHCP;
@@ -2151,16 +2212,30 @@ int __connman_ipconfig_load(struct connman_ipconfig *ipconfig,
ipconfig->method = CONNMAN_IPCONFIG_METHOD_OFF;
if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV6) {
+ gsize length;
+ char *pprefix;
+
if (ipconfig->method == CONNMAN_IPCONFIG_METHOD_AUTO ||
ipconfig->method == CONNMAN_IPCONFIG_METHOD_MANUAL) {
char *privacy;
- char *pprefix = g_strdup_printf("%sprivacy", prefix);
+
+ pprefix = g_strdup_printf("%sprivacy", prefix);
privacy = g_key_file_get_string(keyfile, identifier,
pprefix, NULL);
ipconfig->ipv6_privacy_config = string2privacy(privacy);
g_free(pprefix);
g_free(privacy);
}
+
+ pprefix = g_strdup_printf("%sDHCP.LastPrefixes", prefix);
+ ipconfig->last_dhcpv6_prefixes =
+ g_key_file_get_string_list(keyfile, identifier, pprefix,
+ &length, NULL);
+ if (ipconfig->last_dhcpv6_prefixes && length == 0) {
+ g_free(ipconfig->last_dhcpv6_prefixes);
+ ipconfig->last_dhcpv6_prefixes = NULL;
+ }
+ g_free(pprefix);
}
g_free(method);
@@ -2172,28 +2247,32 @@ int __connman_ipconfig_load(struct connman_ipconfig *ipconfig,
g_free(key);
key = g_strdup_printf("%slocal_address", prefix);
+ g_free(ipconfig->address->local);
ipconfig->address->local = g_key_file_get_string(
keyfile, identifier, key, NULL);
g_free(key);
key = g_strdup_printf("%speer_address", prefix);
+ g_free(ipconfig->address->peer);
ipconfig->address->peer = g_key_file_get_string(
keyfile, identifier, key, NULL);
g_free(key);
key = g_strdup_printf("%sbroadcast_address", prefix);
+ g_free(ipconfig->address->broadcast);
ipconfig->address->broadcast = g_key_file_get_string(
keyfile, identifier, key, NULL);
g_free(key);
key = g_strdup_printf("%sgateway", prefix);
+ g_free(ipconfig->address->gateway);
ipconfig->address->gateway = g_key_file_get_string(
keyfile, identifier, key, NULL);
g_free(key);
key = g_strdup_printf("%sDHCP.LastAddress", prefix);
str = g_key_file_get_string(keyfile, identifier, key, NULL);
- if (str != NULL) {
+ if (str) {
g_free(ipconfig->last_dhcp_address);
ipconfig->last_dhcp_address = str;
}
@@ -2208,13 +2287,15 @@ int __connman_ipconfig_save(struct connman_ipconfig *ipconfig,
const char *method;
char *key;
- DBG("ipconfig %p identifier %s", ipconfig, identifier);
-
method = __connman_ipconfig_method2string(ipconfig->method);
- key = g_strdup_printf("%smethod", prefix);
- g_key_file_set_string(keyfile, identifier, key, method);
- g_free(key);
+ DBG("ipconfig %p identifier %s method %s", ipconfig, identifier,
+ method);
+ if (method) {
+ key = g_strdup_printf("%smethod", prefix);
+ g_key_file_set_string(keyfile, identifier, key, method);
+ g_free(key);
+ }
if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV6) {
const char *privacy;
@@ -2224,13 +2305,26 @@ int __connman_ipconfig_save(struct connman_ipconfig *ipconfig,
g_free(key);
key = g_strdup_printf("%sDHCP.LastAddress", prefix);
- if (ipconfig->last_dhcp_address != NULL &&
+ if (ipconfig->last_dhcp_address &&
strlen(ipconfig->last_dhcp_address) > 0)
g_key_file_set_string(keyfile, identifier, key,
ipconfig->last_dhcp_address);
else
g_key_file_remove_key(keyfile, identifier, key, NULL);
g_free(key);
+
+ key = g_strdup_printf("%sDHCP.LastPrefixes", prefix);
+ if (ipconfig->last_dhcpv6_prefixes &&
+ ipconfig->last_dhcpv6_prefixes[0]) {
+ guint len =
+ g_strv_length(ipconfig->last_dhcpv6_prefixes);
+
+ g_key_file_set_string_list(keyfile, identifier, key,
+ (const gchar **)ipconfig->last_dhcpv6_prefixes,
+ len);
+ } else
+ g_key_file_remove_key(keyfile, identifier, key, NULL);
+ g_free(key);
}
switch (ipconfig->method) {
@@ -2239,7 +2333,7 @@ int __connman_ipconfig_save(struct connman_ipconfig *ipconfig,
break;
case CONNMAN_IPCONFIG_METHOD_DHCP:
key = g_strdup_printf("%sDHCP.LastAddress", prefix);
- if (ipconfig->last_dhcp_address != NULL &&
+ if (ipconfig->last_dhcp_address &&
strlen(ipconfig->last_dhcp_address) > 0)
g_key_file_set_string(keyfile, identifier, key,
ipconfig->last_dhcp_address);
@@ -2260,25 +2354,25 @@ int __connman_ipconfig_save(struct connman_ipconfig *ipconfig,
g_free(key);
key = g_strdup_printf("%slocal_address", prefix);
- if (ipconfig->address->local != NULL)
+ if (ipconfig->address->local)
g_key_file_set_string(keyfile, identifier,
key, ipconfig->address->local);
g_free(key);
key = g_strdup_printf("%speer_address", prefix);
- if (ipconfig->address->peer != NULL)
+ if (ipconfig->address->peer)
g_key_file_set_string(keyfile, identifier,
key, ipconfig->address->peer);
g_free(key);
key = g_strdup_printf("%sbroadcast_address", prefix);
- if (ipconfig->address->broadcast != NULL)
+ if (ipconfig->address->broadcast)
g_key_file_set_string(keyfile, identifier,
key, ipconfig->address->broadcast);
g_free(key);
key = g_strdup_printf("%sgateway", prefix);
- if (ipconfig->address->gateway != NULL)
+ if (ipconfig->address->gateway)
g_key_file_set_string(keyfile, identifier,
key, ipconfig->address->gateway);
g_free(key);
diff --git a/src/ippool.c b/src/ippool.c
index ba613fb1..558e9662 100644
--- a/src/ippool.c
+++ b/src/ippool.c
@@ -2,8 +2,8 @@
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
- * Copyright (C) 2012 BMW Car IT GmbH. All rights reserved.
+ * Copyright (C) 2007-2013 Intel Corporation. All rights reserved.
+ * Copyright (C) 2012-2013 BMW Car IT GmbH. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -24,7 +24,6 @@
#include <config.h>
#endif
-#include <getopt.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -82,7 +81,7 @@ __connman_ippool_ref_debug(struct connman_ippool *pool,
void __connman_ippool_unref_debug(struct connman_ippool *pool,
const char *file, int line, const char *caller)
{
- if (pool == NULL)
+ if (!pool)
return;
DBG("%p ref %d by %s:%d:%s()", pool, pool->refcount - 1,
@@ -170,7 +169,7 @@ static uint32_t get_free_block(unsigned int size)
struct address_info *info;
uint32_t block;
GSList *list;
- connman_bool_t collision;
+ bool collision;
/*
* Instead starting always from the 16 bit block, we start
@@ -188,17 +187,17 @@ static uint32_t get_free_block(unsigned int size)
block = next_block(last_block);
do {
- collision = FALSE;
- for (list = allocated_blocks; list != NULL; list = list->next) {
+ collision = false;
+ for (list = allocated_blocks; list; list = list->next) {
info = list->data;
if (info->start <= block && block <= info->end) {
- collision = TRUE;
+ collision = true;
break;
}
}
- if (collision == FALSE)
+ if (!collision)
return block;
block = next_block(block);
@@ -211,7 +210,7 @@ static struct address_info *lookup_info(int index, uint32_t start)
{
GSList *list;
- for (list = allocated_blocks; list != NULL; list = list->next) {
+ for (list = allocated_blocks; list; list = list->next) {
struct address_info *info = list->data;
if (info->index == index && info->start == start)
@@ -221,7 +220,7 @@ static struct address_info *lookup_info(int index, uint32_t start)
return NULL;
}
-static connman_bool_t is_private_address(uint32_t address)
+static bool is_private_address(uint32_t address)
{
unsigned int a, b;
@@ -230,9 +229,9 @@ static connman_bool_t is_private_address(uint32_t address)
if (a == 10 || (a == 192 && b == 168) ||
(a == 172 && (b >= 16 && b <= 31)))
- return TRUE;
+ return true;
- return FALSE;
+ return false;
}
void __connman_ippool_newaddr(int index, const char *address,
@@ -247,7 +246,7 @@ void __connman_ippool_newaddr(int index, const char *address,
return;
start = ntohl(inp.s_addr);
- if (is_private_address(start) == FALSE)
+ if (!is_private_address(start))
return;
if (prefixlen >= 32)
@@ -259,11 +258,11 @@ void __connman_ippool_newaddr(int index, const char *address,
end = start | ~mask;
info = lookup_info(index, start);
- if (info != NULL)
+ if (info)
goto update;
info = g_try_new0(struct address_info, 1);
- if (info == NULL)
+ if (!info)
return;
info->index = index;
@@ -275,7 +274,7 @@ void __connman_ippool_newaddr(int index, const char *address,
update:
info->use_count = info->use_count + 1;
- if (info->use_count > 1 || info->pool != NULL) {
+ if (info->use_count > 1 || info->pool) {
/*
* We need only to check for the first IP in a block for
* collisions.
@@ -283,16 +282,16 @@ update:
return;
}
- for (list = allocated_blocks; list != NULL; list = list->next) {
+ for (list = allocated_blocks; list; list = list->next) {
it = list->data;
if (it == info)
continue;
- if (!(it->start <= info->start || info->start <= it->end))
+ if (!(info->start >= it->start && info->start <= it->end))
continue;
- if (it->pool != NULL && it->pool->collision_cb != NULL)
+ if (it->pool && it->pool->collision_cb)
it->pool->collision_cb(it->pool, it->pool->user_data);
return;
@@ -310,27 +309,28 @@ void __connman_ippool_deladdr(int index, const char *address,
return;
start = ntohl(inp.s_addr);
- if (is_private_address(start) == FALSE)
+ if (!is_private_address(start))
return;
mask = ~(0xffffffff >> prefixlen);
start = start & mask;
info = lookup_info(index, start);
- if (info == NULL) {
+ if (!info) {
/* In theory this should never happen */
connman_error("Inconsistent IP pool management (start not found)");
return;
}
info->use_count = info->use_count - 1;
- if (info->pool != NULL)
+ if (info->pool)
return;
if (info->use_count > 0)
return;
allocated_blocks = g_slist_remove(allocated_blocks, info);
+ g_free(info);
}
struct connman_ippool *__connman_ippool_create(int index,
@@ -361,11 +361,11 @@ struct connman_ippool *__connman_ippool_create(int index,
}
pool = g_try_new0(struct connman_ippool, 1);
- if (pool == NULL)
+ if (!pool)
return NULL;
info = g_try_new0(struct address_info, 1);
- if (info == NULL) {
+ if (!info) {
g_free(pool);
return NULL;
}
@@ -427,7 +427,7 @@ static void pool_free(gpointer data)
{
struct connman_ippool *pool = data;
- if (pool->info != NULL) {
+ if (pool->info) {
allocated_blocks = g_slist_remove(allocated_blocks, pool->info);
g_free(pool->info);
}
@@ -463,7 +463,7 @@ void __connman_ippool_cleanup(void)
g_hash_table_destroy(pool_hash);
pool_hash = NULL;
- g_slist_free(allocated_blocks);
+ g_slist_free_full(allocated_blocks, g_free);
last_block = 0;
allocated_blocks = NULL;
}
diff --git a/src/iptables.c b/src/iptables.c
index 9584e126..8d583eae 100644
--- a/src/iptables.c
+++ b/src/iptables.c
@@ -2,7 +2,7 @@
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2013 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -35,6 +35,7 @@
#include <linux/netfilter_ipv4/ip_tables.h>
#include "connman.h"
+#include "src/shared/util.h"
/*
* Some comments on how the iptables API works (some of them from the
@@ -175,10 +176,10 @@ struct connman_iptables {
};
static GHashTable *table_hash = NULL;
-static gboolean debug_enabled = FALSE;
+static bool debug_enabled = false;
typedef int (*iterate_entries_cb_t)(struct ipt_entry *entry, int builtin,
- unsigned int hook,size_t size,
+ unsigned int hook, size_t size,
unsigned int offset, void *user_data);
static unsigned int next_hook_entry_index(unsigned int *valid_hooks)
@@ -233,9 +234,8 @@ static int iterate_entries(struct ipt_entry *entries,
if (h == NF_INET_NUMHOOKS)
hook = h;
- if (h < NF_INET_NUMHOOKS && underflow[h] <= offset) {
+ if (h < NF_INET_NUMHOOKS && underflow[h] <= offset)
h = next_hook_entry_index(&valid_hooks);
- }
err = cb(entry, builtin, hook, size, offset, user_data);
if (err < 0)
@@ -274,18 +274,18 @@ static int target_to_verdict(const char *target_name)
return 0;
}
-static gboolean is_builtin_target(const char *target_name)
+static bool is_builtin_target(const char *target_name)
{
if (!g_strcmp0(target_name, LABEL_ACCEPT) ||
!g_strcmp0(target_name, LABEL_DROP) ||
!g_strcmp0(target_name, LABEL_QUEUE) ||
!g_strcmp0(target_name, LABEL_RETURN))
- return TRUE;
+ return true;
- return FALSE;
+ return false;
}
-static gboolean is_jump(struct connman_iptables_entry *e)
+static bool is_jump(struct connman_iptables_entry *e)
{
struct xt_entry_target *target;
@@ -312,7 +312,7 @@ static gboolean is_jump(struct connman_iptables_entry *e)
return false;
}
-static gboolean is_fallthrough(struct connman_iptables_entry *e)
+static bool is_fallthrough(struct connman_iptables_entry *e)
{
struct xt_entry_target *target;
@@ -327,7 +327,7 @@ static gboolean is_fallthrough(struct connman_iptables_entry *e)
return false;
}
-static gboolean is_chain(struct connman_iptables *table,
+static bool is_chain(struct connman_iptables *table,
struct connman_iptables_entry *e)
{
struct ipt_entry *entry;
@@ -335,13 +335,13 @@ static gboolean is_chain(struct connman_iptables *table,
entry = e->entry;
if (e->builtin >= 0)
- return TRUE;
+ return true;
target = ipt_get_target(entry);
if (!g_strcmp0(target->u.user.name, IPT_ERROR_TARGET))
- return TRUE;
+ return true;
- return FALSE;
+ return false;
}
static GList *find_chain_head(struct connman_iptables *table,
@@ -379,7 +379,7 @@ static GList *find_chain_tail(struct connman_iptables *table,
GList *chain_head, *list;
chain_head = find_chain_head(table, chain_name);
- if (chain_head == NULL)
+ if (!chain_head)
return NULL;
/* Then we look for the next chain */
@@ -420,7 +420,7 @@ static void update_offsets(struct connman_iptables *table)
static void update_targets_reference(struct connman_iptables *table,
struct connman_iptables_entry *entry_before,
struct connman_iptables_entry *modified_entry,
- gboolean is_removing)
+ bool is_removing)
{
struct connman_iptables_entry *tmp;
struct xt_standard_target *t;
@@ -437,7 +437,7 @@ static void update_targets_reference(struct connman_iptables *table,
t = (struct xt_standard_target *)ipt_get_target(tmp->entry);
- if (is_removing == TRUE) {
+ if (is_removing) {
if (t->verdict >= entry_before->offset)
t->verdict -= offset;
} else {
@@ -447,7 +447,8 @@ static void update_targets_reference(struct connman_iptables *table,
}
if (is_fallthrough(modified_entry)) {
- t = (struct xt_standard_target *) ipt_get_target(modified_entry->entry);
+ t = (struct xt_standard_target *)
+ ipt_get_target(modified_entry->entry);
t->verdict = entry_before->offset +
modified_entry->entry->target_offset +
@@ -463,11 +464,11 @@ static int iptables_add_entry(struct connman_iptables *table,
{
struct connman_iptables_entry *e, *entry_before;
- if (table == NULL)
+ if (!table)
return -1;
e = g_try_malloc0(sizeof(struct connman_iptables_entry));
- if (e == NULL)
+ if (!e)
return -1;
e->entry = entry;
@@ -477,7 +478,7 @@ static int iptables_add_entry(struct connman_iptables *table,
table->num_entries++;
table->size += entry->next_offset;
- if (before == NULL) {
+ if (!before) {
e->offset = table->size - entry->next_offset;
return 0;
@@ -489,7 +490,7 @@ static int iptables_add_entry(struct connman_iptables *table,
* We've just appended/insterted a new entry. All references
* should be bumped accordingly.
*/
- update_targets_reference(table, entry_before, e, FALSE);
+ update_targets_reference(table, entry_before, e, false);
update_offsets(table);
@@ -546,11 +547,11 @@ static int iptables_flush_chain(struct connman_iptables *table,
DBG("table %s chain %s", table->name, name);
chain_head = find_chain_head(table, name);
- if (chain_head == NULL)
+ if (!chain_head)
return -EINVAL;
chain_tail = find_chain_tail(table, name);
- if (chain_tail == NULL)
+ if (!chain_tail)
return -EINVAL;
entry = chain_head->data;
@@ -605,13 +606,13 @@ static int iptables_add_chain(struct connman_iptables *table,
*/
/* head entry */
- entry_head_size = sizeof(struct ipt_entry) +
- sizeof(struct error_target);
+ entry_head_size = ALIGN(sizeof(struct ipt_entry)) +
+ ALIGN(sizeof(struct error_target));
entry_head = g_try_malloc0(entry_head_size);
- if (entry_head == NULL)
+ if (!entry_head)
goto err_head;
- entry_head->target_offset = sizeof(struct ipt_entry);
+ entry_head->target_offset = ALIGN(sizeof(struct ipt_entry));
entry_head->next_offset = entry_head_size;
error = (struct error_target *) entry_head->elems;
@@ -623,13 +624,13 @@ static int iptables_add_chain(struct connman_iptables *table,
goto err_head;
/* tail entry */
- entry_return_size = sizeof(struct ipt_entry) +
- sizeof(struct ipt_standard_target);
+ entry_return_size = ALIGN(sizeof(struct ipt_entry))+
+ ALIGN(sizeof(struct ipt_standard_target));
entry_return = g_try_malloc0(entry_return_size);
- if (entry_return == NULL)
+ if (!entry_return)
goto err;
- entry_return->target_offset = sizeof(struct ipt_entry);
+ entry_return->target_offset = ALIGN(sizeof(struct ipt_entry));
entry_return->next_offset = entry_return_size;
standard = (struct ipt_standard_target *) entry_return->elems;
@@ -659,7 +660,7 @@ static int iptables_delete_chain(struct connman_iptables *table,
DBG("table %s chain %s", table->name, name);
chain_head = find_chain_head(table, name);
- if (chain_head == NULL)
+ if (!chain_head)
return -EINVAL;
entry = chain_head->data;
@@ -669,7 +670,7 @@ static int iptables_delete_chain(struct connman_iptables *table,
return -EINVAL;
chain_tail = find_chain_tail(table, name);
- if (chain_tail == NULL)
+ if (!chain_tail)
return -EINVAL;
/* Chain must be flushed */
@@ -695,27 +696,28 @@ static struct ipt_entry *new_rule(struct ipt_ip *ip,
size_t match_size, target_size;
match_size = 0;
- for (tmp_xt_rm = xt_rm; tmp_xt_rm != NULL; tmp_xt_rm = tmp_xt_rm->next)
+ for (tmp_xt_rm = xt_rm; tmp_xt_rm; tmp_xt_rm = tmp_xt_rm->next)
match_size += tmp_xt_rm->match->m->u.match_size;
if (xt_t)
- target_size = ALIGN(xt_t->t->u.target_size);
+ target_size = xt_t->t->u.target_size;
else
target_size = ALIGN(sizeof(struct xt_standard_target));
- new_entry = g_try_malloc0(sizeof(struct ipt_entry) + target_size +
- match_size);
- if (new_entry == NULL)
+ new_entry = g_try_malloc0(ALIGN(sizeof(struct ipt_entry)) +
+ target_size + match_size);
+ if (!new_entry)
return NULL;
memcpy(&new_entry->ip, ip, sizeof(struct ipt_ip));
- new_entry->target_offset = sizeof(struct ipt_entry) + match_size;
- new_entry->next_offset = sizeof(struct ipt_entry) + target_size +
- match_size;
+ new_entry->target_offset = ALIGN(sizeof(struct ipt_entry)) +
+ match_size;
+ new_entry->next_offset = ALIGN(sizeof(struct ipt_entry)) +
+ target_size + match_size;
match_size = 0;
- for (tmp_xt_rm = xt_rm; tmp_xt_rm != NULL;
+ for (tmp_xt_rm = xt_rm; tmp_xt_rm;
tmp_xt_rm = tmp_xt_rm->next) {
memcpy(new_entry->elems + match_size, tmp_xt_rm->match->m,
tmp_xt_rm->match->m->u.match_size);
@@ -739,7 +741,7 @@ static void update_hooks(struct connman_iptables *table, GList *chain_head,
struct connman_iptables_entry *head, *e;
int builtin;
- if (chain_head == NULL)
+ if (!chain_head)
return;
head = chain_head->data;
@@ -767,22 +769,22 @@ static struct ipt_entry *prepare_rule_inclusion(struct connman_iptables *table,
const char *target_name,
struct xtables_target *xt_t,
int *builtin, struct xtables_rule_match *xt_rm,
- connman_bool_t insert)
+ bool insert)
{
GList *chain_tail, *chain_head;
struct ipt_entry *new_entry;
struct connman_iptables_entry *head;
chain_head = find_chain_head(table, chain_name);
- if (chain_head == NULL)
+ if (!chain_head)
return NULL;
chain_tail = find_chain_tail(table, chain_name);
- if (chain_tail == NULL)
+ if (!chain_tail)
return NULL;
new_entry = new_rule(ip, target_name, xt_t, xt_rm);
- if (new_entry == NULL)
+ if (!new_entry)
return NULL;
update_hooks(table, chain_head, new_entry);
@@ -795,7 +797,7 @@ static struct ipt_entry *prepare_rule_inclusion(struct connman_iptables *table,
head = chain_head->data;
if (head->builtin < 0)
*builtin = -1;
- else if (insert == TRUE || chain_head == chain_tail->prev) {
+ else if (insert || chain_head == chain_tail->prev) {
*builtin = head->builtin;
head->builtin = -1;
}
@@ -816,12 +818,12 @@ static int iptables_append_rule(struct connman_iptables *table,
DBG("table %s chain %s", table->name, chain_name);
chain_tail = find_chain_tail(table, chain_name);
- if (chain_tail == NULL)
+ if (!chain_tail)
return -EINVAL;
new_entry = prepare_rule_inclusion(table, ip, chain_name,
- target_name, xt_t, &builtin, xt_rm, FALSE);
- if (new_entry == NULL)
+ target_name, xt_t, &builtin, xt_rm, false);
+ if (!new_entry)
return -EINVAL;
ret = iptables_add_entry(table, new_entry, chain_tail->prev, builtin);
@@ -844,12 +846,12 @@ static int iptables_insert_rule(struct connman_iptables *table,
DBG("table %s chain %s", table->name, chain_name);
chain_head = find_chain_head(table, chain_name);
- if (chain_head == NULL)
+ if (!chain_head)
return -EINVAL;
new_entry = prepare_rule_inclusion(table, ip, chain_name,
- target_name, xt_t, &builtin, xt_rm, TRUE);
- if (new_entry == NULL)
+ target_name, xt_t, &builtin, xt_rm, true);
+ if (!new_entry)
return -EINVAL;
if (builtin == -1)
@@ -862,33 +864,33 @@ static int iptables_insert_rule(struct connman_iptables *table,
return ret;
}
-static gboolean is_same_ipt_entry(struct ipt_entry *i_e1,
+static bool is_same_ipt_entry(struct ipt_entry *i_e1,
struct ipt_entry *i_e2)
{
if (memcmp(&i_e1->ip, &i_e2->ip, sizeof(struct ipt_ip)) != 0)
- return FALSE;
+ return false;
if (i_e1->target_offset != i_e2->target_offset)
- return FALSE;
+ return false;
if (i_e1->next_offset != i_e2->next_offset)
- return FALSE;
+ return false;
- return TRUE;
+ return true;
}
-static gboolean is_same_target(struct xt_entry_target *xt_e_t1,
+static bool is_same_target(struct xt_entry_target *xt_e_t1,
struct xt_entry_target *xt_e_t2)
{
unsigned int i;
- if (xt_e_t1 == NULL || xt_e_t2 == NULL)
- return FALSE;
+ if (!xt_e_t1 || !xt_e_t2)
+ return false;
if (g_strcmp0(xt_e_t1->u.user.name, "") == 0 &&
g_strcmp0(xt_e_t2->u.user.name, "") == 0) {
/* fallthrough */
- return TRUE;
+ return true;
} else if (g_strcmp0(xt_e_t1->u.user.name, IPT_STANDARD_TARGET) == 0) {
struct xt_standard_target *xt_s_t1;
struct xt_standard_target *xt_s_t2;
@@ -897,48 +899,48 @@ static gboolean is_same_target(struct xt_entry_target *xt_e_t1,
xt_s_t2 = (struct xt_standard_target *) xt_e_t2;
if (xt_s_t1->verdict != xt_s_t2->verdict)
- return FALSE;
+ return false;
} else {
if (xt_e_t1->u.target_size != xt_e_t2->u.target_size)
- return FALSE;
+ return false;
if (g_strcmp0(xt_e_t1->u.user.name, xt_e_t2->u.user.name) != 0)
- return FALSE;
+ return false;
for (i = 0; i < xt_e_t1->u.target_size -
sizeof(struct xt_standard_target); i++) {
if ((xt_e_t1->data[i] ^ xt_e_t2->data[i]) != 0)
- return FALSE;
+ return false;
}
}
- return TRUE;
+ return true;
}
-static gboolean is_same_match(struct xt_entry_match *xt_e_m1,
+static bool is_same_match(struct xt_entry_match *xt_e_m1,
struct xt_entry_match *xt_e_m2)
{
unsigned int i;
- if (xt_e_m1 == NULL || xt_e_m2 == NULL)
- return FALSE;
+ if (!xt_e_m1 || !xt_e_m2)
+ return false;
if (xt_e_m1->u.match_size != xt_e_m2->u.match_size)
- return FALSE;
+ return false;
if (xt_e_m1->u.user.revision != xt_e_m2->u.user.revision)
- return FALSE;
+ return false;
if (g_strcmp0(xt_e_m1->u.user.name, xt_e_m2->u.user.name) != 0)
- return FALSE;
+ return false;
for (i = 0; i < xt_e_m1->u.match_size - sizeof(struct xt_entry_match);
i++) {
if ((xt_e_m1->data[i] ^ xt_e_m2->data[i]) != 0)
- return FALSE;
+ return false;
}
- return TRUE;
+ return true;
}
static GList *find_existing_rule(struct connman_iptables *table,
@@ -956,23 +958,23 @@ static GList *find_existing_rule(struct connman_iptables *table,
int builtin;
chain_head = find_chain_head(table, chain_name);
- if (chain_head == NULL)
+ if (!chain_head)
return NULL;
chain_tail = find_chain_tail(table, chain_name);
- if (chain_tail == NULL)
+ if (!chain_tail)
return NULL;
if (!xt_t && !matches)
return NULL;
entry_test = new_rule(ip, target_name, xt_t, xt_rm);
- if (entry_test == NULL)
+ if (!entry_test)
return NULL;
- if (xt_t != NULL)
+ if (xt_t)
xt_e_t = ipt_get_target(entry_test);
- if (matches != NULL)
+ if (matches)
xt_e_m = (struct xt_entry_match *)entry_test->elems;
entry = chain_head->data;
@@ -990,10 +992,10 @@ static GList *find_existing_rule(struct connman_iptables *table,
tmp = list->data;
tmp_e = tmp->entry;
- if (is_same_ipt_entry(entry_test, tmp_e) == FALSE)
+ if (!is_same_ipt_entry(entry_test, tmp_e))
continue;
- if (xt_t != NULL) {
+ if (xt_t) {
struct xt_entry_target *tmp_xt_e_t;
tmp_xt_e_t = ipt_get_target(tmp_e);
@@ -1002,7 +1004,7 @@ static GList *find_existing_rule(struct connman_iptables *table,
continue;
}
- if (matches != NULL) {
+ if (matches) {
struct xt_entry_match *tmp_xt_e_m;
tmp_xt_e_m = (struct xt_entry_match *)tmp_e->elems;
@@ -1039,16 +1041,16 @@ static int iptables_delete_rule(struct connman_iptables *table,
removed = 0;
chain_head = find_chain_head(table, chain_name);
- if (chain_head == NULL)
+ if (!chain_head)
return -EINVAL;
chain_tail = find_chain_tail(table, chain_name);
- if (chain_tail == NULL)
+ if (!chain_tail)
return -EINVAL;
list = find_existing_rule(table, ip, chain_name, target_name,
xt_t, matches, xt_rm);
- if (list == NULL)
+ if (!list)
return -EINVAL;
entry = chain_head->data;
@@ -1071,14 +1073,14 @@ static int iptables_delete_rule(struct connman_iptables *table,
}
entry = list->data;
- if (entry == NULL)
+ if (!entry)
return -EINVAL;
/* We have deleted a rule,
* all references should be bumped accordingly */
- if (list->next != NULL)
+ if (list->next)
update_targets_reference(table, list->next->data,
- list->data, TRUE);
+ list->data, true);
removed += remove_table_entry(table, entry);
@@ -1111,7 +1113,7 @@ static int iptables_change_policy(struct connman_iptables *table,
}
chain_head = find_chain_head(table, chain_name);
- if (chain_head == NULL)
+ if (!chain_head)
return -EINVAL;
entry = chain_head->data;
@@ -1119,7 +1121,7 @@ static int iptables_change_policy(struct connman_iptables *table,
return -EINVAL;
chain_tail = find_chain_tail(table, chain_name);
- if (chain_tail == NULL)
+ if (!chain_tail)
return -EINVAL;
entry = chain_tail->prev->data;
@@ -1139,14 +1141,14 @@ static struct ipt_replace *iptables_blob(struct connman_iptables *table)
unsigned char *entry_index;
r = g_try_malloc0(sizeof(struct ipt_replace) + table->size);
- if (r == NULL)
+ if (!r)
return NULL;
memset(r, 0, sizeof(*r) + table->size);
r->counters = g_try_malloc0(sizeof(struct xt_counters)
* table->old_entries);
- if (r->counters == NULL) {
+ if (!r->counters) {
g_free(r);
return NULL;
}
@@ -1184,14 +1186,14 @@ static void dump_ip(struct ipt_entry *entry)
if (strlen(ip->outiface))
DBG("\tout %s", ip->outiface);
- if (inet_ntop(AF_INET, &ip->src, ip_string, INET6_ADDRSTRLEN) != NULL &&
- inet_ntop(AF_INET, &ip->smsk,
- ip_mask, INET6_ADDRSTRLEN) != NULL)
+ if (inet_ntop(AF_INET, &ip->src, ip_string, INET6_ADDRSTRLEN) &&
+ inet_ntop(AF_INET, &ip->smsk, ip_mask,
+ INET6_ADDRSTRLEN))
DBG("\tsrc %s/%s", ip_string, ip_mask);
- if (inet_ntop(AF_INET, &ip->dst, ip_string, INET6_ADDRSTRLEN) != NULL &&
- inet_ntop(AF_INET, &ip->dmsk,
- ip_mask, INET6_ADDRSTRLEN) != NULL)
+ if (inet_ntop(AF_INET, &ip->dst, ip_string, INET6_ADDRSTRLEN) &&
+ inet_ntop(AF_INET, &ip->dmsk, ip_mask,
+ INET6_ADDRSTRLEN))
DBG("\tdst %s/%s", ip_string, ip_mask);
}
@@ -1237,16 +1239,16 @@ static void dump_target(struct ipt_entry *entry)
xt_t = xtables_find_target(IPT_STANDARD_TARGET,
XTF_LOAD_MUST_SUCCEED);
- if(xt_t->print != NULL)
+ if (xt_t->print)
xt_t->print(NULL, target, 1);
} else {
xt_t = xtables_find_target(target->u.user.name, XTF_TRY_LOAD);
- if (xt_t == NULL) {
+ if (!xt_t) {
DBG("\ttarget %s", target->u.user.name);
return;
}
- if(xt_t->print != NULL) {
+ if (xt_t->print) {
DBG("\ttarget ");
xt_t->print(NULL, target, 1);
}
@@ -1270,10 +1272,10 @@ static void dump_match(struct ipt_entry *entry)
return;
xt_m = xtables_find_match(match->u.user.name, XTF_TRY_LOAD, NULL);
- if (xt_m == NULL)
+ if (!xt_m)
goto out;
- if(xt_m->print != NULL) {
+ if (xt_m->print) {
DBG("\tmatch ");
xt_m->print(NULL, match, 1);
@@ -1378,18 +1380,29 @@ static void dump_ipt_replace(struct ipt_replace *repl)
static int iptables_get_entries(struct connman_iptables *table)
{
socklen_t entry_size;
+ int err;
entry_size = sizeof(struct ipt_get_entries) + table->info->size;
- return getsockopt(table->ipt_sock, IPPROTO_IP, IPT_SO_GET_ENTRIES,
+ err = getsockopt(table->ipt_sock, IPPROTO_IP, IPT_SO_GET_ENTRIES,
table->blob_entries, &entry_size);
+ if (err < 0)
+ return -errno;
+
+ return 0;
}
static int iptables_replace(struct connman_iptables *table,
struct ipt_replace *r)
{
- return setsockopt(table->ipt_sock, IPPROTO_IP, IPT_SO_SET_REPLACE, r,
- sizeof(*r) + r->size);
+ int err;
+
+ err = setsockopt(table->ipt_sock, IPPROTO_IP, IPT_SO_SET_REPLACE, r,
+ sizeof(*r) + r->size);
+ if (err < 0)
+ return -errno;
+
+ return 0;
}
static int add_entry(struct ipt_entry *entry, int builtin, unsigned int hook,
@@ -1399,7 +1412,7 @@ static int add_entry(struct ipt_entry *entry, int builtin, unsigned int hook,
struct ipt_entry *new_entry;
new_entry = g_try_malloc0(entry->next_offset);
- if (new_entry == NULL)
+ if (!new_entry)
return -ENOMEM;
memcpy(new_entry, entry, entry->next_offset);
@@ -1412,7 +1425,7 @@ static void table_cleanup(struct connman_iptables *table)
GList *list;
struct connman_iptables_entry *entry;
- if (table == NULL)
+ if (!table)
return;
if (table->ipt_sock >= 0)
@@ -1444,7 +1457,7 @@ static struct connman_iptables *iptables_init(const char *table_name)
DBG("ip_tables module loading gives error but trying anyway");
module = g_strconcat("iptable_", table_name, NULL);
- if (module == NULL)
+ if (!module)
return NULL;
if (xtables_insmod(module, NULL, TRUE) != 0)
@@ -1453,11 +1466,11 @@ static struct connman_iptables *iptables_init(const char *table_name)
g_free(module);
table = g_try_new0(struct connman_iptables, 1);
- if (table == NULL)
+ if (!table)
return NULL;
table->info = g_try_new0(struct ipt_getinfo, 1);
- if (table->info == NULL)
+ if (!table->info)
goto err;
table->ipt_sock = socket(AF_INET, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_RAW);
@@ -1475,7 +1488,7 @@ static struct connman_iptables *iptables_init(const char *table_name)
table->blob_entries = g_try_malloc0(sizeof(struct ipt_get_entries) +
table->info->size);
- if (table->blob_entries == NULL)
+ if (!table->blob_entries)
goto err;
g_stpcpy(table->blob_entries->name, table_name);
@@ -1498,7 +1511,7 @@ static struct connman_iptables *iptables_init(const char *table_name)
table->info->underflow, table->blob_entries->size,
add_entry, table);
- if (debug_enabled == TRUE)
+ if (debug_enabled)
dump_table(table);
return table;
@@ -1539,19 +1552,19 @@ static struct xtables_target *prepare_target(struct connman_iptables *table,
const char *target_name)
{
struct xtables_target *xt_t = NULL;
- gboolean is_builtin, is_user_defined;
+ bool is_builtin, is_user_defined;
GList *chain_head = NULL;
size_t target_size;
- is_builtin = FALSE;
- is_user_defined = FALSE;
+ is_builtin = false;
+ is_user_defined = false;
if (is_builtin_target(target_name))
- is_builtin = TRUE;
+ is_builtin = true;
else {
chain_head = find_chain_head(table, target_name);
- if (chain_head != NULL && chain_head->next != NULL)
- is_user_defined = TRUE;
+ if (chain_head && chain_head->next)
+ is_user_defined = true;
}
if (is_builtin || is_user_defined)
@@ -1560,13 +1573,13 @@ static struct xtables_target *prepare_target(struct connman_iptables *table,
else
xt_t = xtables_find_target(target_name, XTF_TRY_LOAD);
- if (xt_t == NULL)
+ if (!xt_t)
return NULL;
target_size = ALIGN(sizeof(struct ipt_entry_target)) + xt_t->size;
xt_t->t = g_try_malloc0(target_size);
- if (xt_t->t == NULL)
+ if (!xt_t->t)
return NULL;
xt_t->t->u.target_size = target_size;
@@ -1577,27 +1590,22 @@ static struct xtables_target *prepare_target(struct connman_iptables *table,
target = (struct xt_standard_target *)(xt_t->t);
g_stpcpy(target->target.u.user.name, IPT_STANDARD_TARGET);
- if (is_builtin == TRUE)
+ if (is_builtin)
target->verdict = target_to_verdict(target_name);
- else if (is_user_defined == TRUE) {
+ else if (is_user_defined) {
struct connman_iptables_entry *target_rule;
- if (chain_head == NULL) {
- g_free(xt_t->t);
- return NULL;
- }
-
target_rule = chain_head->next->data;
target->verdict = target_rule->offset;
}
} else {
g_stpcpy(xt_t->t->u.user.name, target_name);
xt_t->t->u.user.revision = xt_t->revision;
- if (xt_t->init != NULL)
+ if (xt_t->init)
xt_t->init(xt_t->t);
}
- if (xt_t->x6_options != NULL)
+ if (xt_t->x6_options)
iptables_globals.opts =
xtables_options_xfrm(
iptables_globals.orig_opts,
@@ -1612,7 +1620,7 @@ static struct xtables_target *prepare_target(struct connman_iptables *table,
xt_t->extra_opts,
&xt_t->option_offset);
- if (iptables_globals.opts == NULL) {
+ if (!iptables_globals.opts) {
g_free(xt_t->t);
xt_t = NULL;
}
@@ -1627,24 +1635,24 @@ static struct xtables_match *prepare_matches(struct connman_iptables *table,
struct xtables_match *xt_m;
size_t match_size;
- if (match_name == NULL)
+ if (!match_name)
return NULL;
xt_m = xtables_find_match(match_name, XTF_LOAD_MUST_SUCCEED, xt_rm);
match_size = ALIGN(sizeof(struct ipt_entry_match)) + xt_m->size;
xt_m->m = g_try_malloc0(match_size);
- if (xt_m->m == NULL)
+ if (!xt_m->m)
return NULL;
xt_m->m->u.match_size = match_size;
g_stpcpy(xt_m->m->u.user.name, xt_m->name);
xt_m->m->u.user.revision = xt_m->revision;
- if (xt_m->init != NULL)
+ if (xt_m->init)
xt_m->init(xt_m->m);
- if (xt_m->x6_options != NULL)
+ if (xt_m->x6_options)
iptables_globals.opts =
xtables_options_xfrm(
iptables_globals.orig_opts,
@@ -1659,7 +1667,7 @@ static struct xtables_match *prepare_matches(struct connman_iptables *table,
xt_m->extra_opts,
&xt_m->option_offset);
- if (iptables_globals.opts == NULL) {
+ if (!iptables_globals.opts) {
g_free(xt_m->m);
if (xt_m == xt_m->next)
@@ -1671,7 +1679,8 @@ static struct xtables_match *prepare_matches(struct connman_iptables *table,
return xt_m;
}
-static int parse_ip_and_mask(const char *str, struct in_addr *ip, struct in_addr *mask)
+static int parse_ip_and_mask(const char *str, struct in_addr *ip,
+ struct in_addr *mask)
{
char **tokens;
uint32_t prefixlength;
@@ -1679,7 +1688,7 @@ static int parse_ip_and_mask(const char *str, struct in_addr *ip, struct in_addr
int err;
tokens = g_strsplit(str, "/", 2);
- if (tokens == NULL)
+ if (!tokens)
return -1;
if (!inet_pton(AF_INET, tokens[0], ip)) {
@@ -1687,7 +1696,7 @@ static int parse_ip_and_mask(const char *str, struct in_addr *ip, struct in_addr
goto out;
}
- if (tokens[1] != NULL) {
+ if (tokens[1]) {
prefixlength = strtol(tokens[1], NULL, 10);
if (prefixlength > 31) {
err = -1;
@@ -1712,15 +1721,15 @@ static struct connman_iptables *get_table(const char *table_name)
{
struct connman_iptables *table;
- if (table_name == NULL)
+ if (!table_name)
table_name = "filter";
table = g_hash_table_lookup(table_hash, table_name);
- if (table != NULL)
+ if (table)
return table;
table = iptables_init(table_name);
- if (table == NULL)
+ if (!table)
return NULL;
table->name = g_strdup(table_name);
@@ -1752,7 +1761,7 @@ static int prepare_getopt_args(const char *str, struct parse_context *ctx)
/* Don't forget the last NULL entry */
ctx->argv = g_try_malloc0((ctx->argc + 1) * sizeof(char *));
- if (ctx->argv == NULL) {
+ if (!ctx->argv) {
g_strfreev(tokens);
return -ENOMEM;
}
@@ -1770,19 +1779,19 @@ static int prepare_getopt_args(const char *str, struct parse_context *ctx)
return 0;
}
-static int parse_xt_modules(int c, connman_bool_t invert,
+static int parse_xt_modules(int c, bool invert,
struct parse_context *ctx)
{
struct xtables_match *m;
struct xtables_rule_match *rm;
- for (rm = ctx->xt_rm; rm != NULL; rm = rm->next) {
+ for (rm = ctx->xt_rm; rm; rm = rm->next) {
if (rm->completed != 0)
continue;
m = rm->match;
- if (m->x6_parse == NULL && m->parse == NULL)
+ if (!m->x6_parse && !m->parse)
continue;
if (c < (int) m->option_offset ||
@@ -1793,10 +1802,10 @@ static int parse_xt_modules(int c, connman_bool_t invert,
xtables_option_mpcall(c, ctx->argv, invert, m, NULL);
}
- if (ctx->xt_t == NULL)
+ if (!ctx->xt_t)
return 0;
- if (ctx->xt_t->x6_parse == NULL && ctx->xt_t->parse == NULL)
+ if (!ctx->xt_t->x6_parse && !ctx->xt_t->parse)
return 0;
if (c < (int) ctx->xt_t->option_offset ||
@@ -1813,10 +1822,10 @@ static int final_check_xt_modules(struct parse_context *ctx)
{
struct xtables_rule_match *rm;
- for (rm = ctx->xt_rm; rm != NULL; rm = rm->next)
+ for (rm = ctx->xt_rm; rm; rm = rm->next)
xtables_option_mfcall(rm->match);
- if (ctx->xt_t != NULL)
+ if (ctx->xt_t)
xtables_option_tfcall(ctx->xt_t);
return 0;
@@ -1902,11 +1911,11 @@ static int parse_rule_spec(struct connman_iptables *table,
* of libxtables is found.
*/
struct xtables_match *xt_m;
- connman_bool_t invert = FALSE;
+ bool invert = false;
int len, c, err;
ctx->ip = g_try_new0(struct ipt_ip, 1);
- if (ctx->ip == NULL)
+ if (!ctx->ip)
return -ENOMEM;
/*
@@ -1972,7 +1981,7 @@ static int parse_rule_spec(struct connman_iptables *table,
case 'm':
/* Matches */
xt_m = prepare_matches(table, &ctx->xt_rm, optarg);
- if (xt_m == NULL) {
+ if (!xt_m) {
err = -EINVAL;
goto out;
}
@@ -1982,7 +1991,7 @@ static int parse_rule_spec(struct connman_iptables *table,
case 'j':
/* Target */
ctx->xt_t = prepare_target(table, optarg);
- if (ctx->xt_t == NULL) {
+ if (!ctx->xt_t) {
err = -EINVAL;
goto out;
}
@@ -1990,7 +1999,7 @@ static int parse_rule_spec(struct connman_iptables *table,
break;
case 1:
if (optarg[0] == '!' && optarg[1] == '\0') {
- invert = TRUE;
+ invert = true;
/* Remove the '!' from the optarg */
optarg[0] = '\0';
@@ -2011,7 +2020,7 @@ static int parse_rule_spec(struct connman_iptables *table,
break;
}
- invert = FALSE;
+ invert = false;
}
err = final_check_xt_modules(ctx);
@@ -2033,10 +2042,10 @@ static void reset_xtables(void)
* Clear all flags because the flags are only valid
* for one rule.
*/
- for (xt_m = xtables_matches; xt_m != NULL; xt_m = xt_m->next)
+ for (xt_m = xtables_matches; xt_m; xt_m = xt_m->next)
xt_m->mflags = 0;
- for (xt_t = xtables_targets; xt_t != NULL; xt_t = xt_t->next) {
+ for (xt_t = xtables_targets; xt_t; xt_t = xt_t->next) {
xt_t->tflags = 0;
xt_t->used = 0;
}
@@ -2060,12 +2069,12 @@ static void cleanup_parse_context(struct parse_context *ctx)
g_strfreev(ctx->argv);
g_free(ctx->ip);
- if (ctx->xt_t != NULL) {
+ if (ctx->xt_t) {
g_free(ctx->xt_t->t);
ctx->xt_t->t = NULL;
}
- for (list = ctx->xt_m; list != NULL; list = list->next) {
+ for (list = ctx->xt_m; list; list = list->next) {
struct xtables_match *xt_m = list->data;
g_free(xt_m->m);
@@ -2077,8 +2086,8 @@ static void cleanup_parse_context(struct parse_context *ctx)
}
g_list_free(ctx->xt_m);
- for (tmp = NULL, rm = ctx->xt_rm; rm != NULL; rm = rm->next) {
- if (tmp != NULL)
+ for (tmp = NULL, rm = ctx->xt_rm; rm; rm = rm->next) {
+ if (tmp)
g_free(tmp);
tmp = rm;
}
@@ -2094,7 +2103,7 @@ int __connman_iptables_dump(const char *table_name)
DBG("-t %s -L", table_name);
table = get_table(table_name);
- if (table == NULL)
+ if (!table)
return -EINVAL;
dump_table(table);
@@ -2110,7 +2119,7 @@ int __connman_iptables_new_chain(const char *table_name,
DBG("-t %s -N %s", table_name, chain);
table = get_table(table_name);
- if (table == NULL)
+ if (!table)
return -EINVAL;
return iptables_add_chain(table, chain);
@@ -2124,7 +2133,7 @@ int __connman_iptables_delete_chain(const char *table_name,
DBG("-t %s -X %s", table_name, chain);
table = get_table(table_name);
- if (table == NULL)
+ if (!table)
return -EINVAL;
return iptables_delete_chain(table, chain);
@@ -2138,7 +2147,7 @@ int __connman_iptables_flush_chain(const char *table_name,
DBG("-t %s -F %s", table_name, chain);
table = get_table(table_name);
- if (table == NULL)
+ if (!table)
return -EINVAL;
return iptables_flush_chain(table, chain);
@@ -2153,7 +2162,7 @@ int __connman_iptables_change_policy(const char *table_name,
DBG("-t %s -F %s", table_name, chain);
table = get_table(table_name);
- if (table == NULL)
+ if (!table)
return -EINVAL;
return iptables_change_policy(table, chain, policy);
@@ -2169,7 +2178,7 @@ int __connman_iptables_append(const char *table_name,
int err;
ctx = g_try_new0(struct parse_context, 1);
- if (ctx == NULL)
+ if (!ctx)
return -ENOMEM;
DBG("-t %s -A %s %s", table_name, chain, rule_spec);
@@ -2179,7 +2188,7 @@ int __connman_iptables_append(const char *table_name,
goto out;
table = get_table(table_name);
- if (table == NULL) {
+ if (!table) {
err = -EINVAL;
goto out;
}
@@ -2188,7 +2197,7 @@ int __connman_iptables_append(const char *table_name,
if (err < 0)
goto out;
- if (ctx->xt_t == NULL)
+ if (!ctx->xt_t)
target_name = NULL;
else
target_name = ctx->xt_t->name;
@@ -2212,7 +2221,7 @@ int __connman_iptables_insert(const char *table_name,
int err;
ctx = g_try_new0(struct parse_context, 1);
- if (ctx == NULL)
+ if (!ctx)
return -ENOMEM;
DBG("-t %s -I %s %s", table_name, chain, rule_spec);
@@ -2222,7 +2231,7 @@ int __connman_iptables_insert(const char *table_name,
goto out;
table = get_table(table_name);
- if (table == NULL) {
+ if (!table) {
err = -EINVAL;
goto out;
}
@@ -2231,7 +2240,7 @@ int __connman_iptables_insert(const char *table_name,
if (err < 0)
goto out;
- if (ctx->xt_t == NULL)
+ if (!ctx->xt_t)
target_name = NULL;
else
target_name = ctx->xt_t->name;
@@ -2255,7 +2264,7 @@ int __connman_iptables_delete(const char *table_name,
int err;
ctx = g_try_new0(struct parse_context, 1);
- if (ctx == NULL)
+ if (!ctx)
return -ENOMEM;
DBG("-t %s -D %s %s", table_name, chain, rule_spec);
@@ -2265,7 +2274,7 @@ int __connman_iptables_delete(const char *table_name,
goto out;
table = get_table(table_name);
- if (table == NULL) {
+ if (!table) {
err = -EINVAL;
goto out;
}
@@ -2274,7 +2283,7 @@ int __connman_iptables_delete(const char *table_name,
if (err < 0)
goto out;
- if (ctx->xt_t == NULL)
+ if (!ctx->xt_t)
target_name = NULL;
else
target_name = ctx->xt_t->name;
@@ -2298,12 +2307,12 @@ int __connman_iptables_commit(const char *table_name)
DBG("%s", table_name);
table = g_hash_table_lookup(table_hash, table_name);
- if (table == NULL)
+ if (!table)
return -EINVAL;
repl = iptables_blob(table);
- if (debug_enabled == TRUE)
+ if (debug_enabled)
dump_ipt_replace(repl);
err = iptables_replace(table, repl);
@@ -2312,7 +2321,7 @@ int __connman_iptables_commit(const char *table_name)
g_free(repl);
if (err < 0)
- return err;
+ return err;
g_hash_table_remove(table_hash, table_name);
@@ -2340,7 +2349,7 @@ static int iterate_chains_cb(struct ipt_entry *entry, int builtin,
target = ipt_get_target(entry);
if (!g_strcmp0(target->u.user.name, IPT_ERROR_TARGET))
- (*cb)((const char*)target->data, cbd->user_data);
+ (*cb)((const char *)target->data, cbd->user_data);
else if (builtin >= 0)
(*cb)(hooknames[builtin], cbd->user_data);
@@ -2355,7 +2364,7 @@ int __connman_iptables_iterate_chains(const char *table_name,
struct connman_iptables *table;
table = get_table(table_name);
- if (table == NULL)
+ if (!table)
return -EINVAL;
iterate_entries(table->blob_entries->entrytable,
@@ -2375,7 +2384,7 @@ int __connman_iptables_init(void)
DBG("");
if (getenv("CONNMAN_IPTABLES_DEBUG"))
- debug_enabled = TRUE;
+ debug_enabled = true;
table_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
NULL, remove_table);
diff --git a/src/ipv6pd.c b/src/ipv6pd.c
new file mode 100644
index 00000000..5ecda389
--- /dev/null
+++ b/src/ipv6pd.c
@@ -0,0 +1,383 @@
+/*
+ *
+ * Connection Manager
+ *
+ * Copyright (C) 2013 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdio.h>
+
+#include "connman.h"
+
+#include <gdhcp/gdhcp.h>
+
+#define DEFAULT_ROUTER_LIFETIME 180 /* secs */
+#define DEFAULT_RA_INTERVAL 120 /* secs */
+
+static int bridge_index = -1;
+static guint timer_uplink;
+static guint timer_ra;
+static char *default_interface;
+static GSList *prefixes;
+static GHashTable *timer_hash;
+static void *rs_context;
+
+static int setup_prefix_delegation(struct connman_service *service);
+static void dhcpv6_callback(struct connman_network *network,
+ enum __connman_dhcpv6_status status, gpointer data);
+
+static int enable_ipv6_forward(bool enable)
+{
+ FILE *f;
+
+ f = fopen("/proc/sys/net/ipv6/ip_forward", "r+");
+ if (!f)
+ return -errno;
+
+ if (enable)
+ fprintf(f, "1");
+ else
+ fprintf(f, "0");
+
+ fclose(f);
+
+ return 0;
+}
+
+static gboolean send_ra(gpointer data)
+{
+ __connman_inet_ipv6_send_ra(bridge_index, NULL, prefixes,
+ DEFAULT_ROUTER_LIFETIME);
+
+ return TRUE;
+}
+
+static void start_ra(int ifindex, GSList *prefix)
+{
+ if (prefixes)
+ g_slist_free_full(prefixes, g_free);
+
+ prefixes = g_dhcpv6_copy_prefixes(prefix);
+
+ enable_ipv6_forward(true);
+
+ if (timer_ra > 0)
+ g_source_remove(timer_ra);
+
+ send_ra(NULL);
+
+ timer_ra = g_timeout_add_seconds(DEFAULT_RA_INTERVAL, send_ra, NULL);
+}
+
+static void stop_ra(int ifindex)
+{
+ __connman_inet_ipv6_send_ra(ifindex, NULL, prefixes, 0);
+
+ if (timer_ra > 0) {
+ g_source_remove(timer_ra);
+ timer_ra = 0;
+ }
+
+ enable_ipv6_forward(false);
+
+ if (prefixes) {
+ g_slist_free_full(prefixes, g_free);
+ prefixes = NULL;
+ }
+}
+
+static void rs_received(struct nd_router_solicit *reply,
+ unsigned int length, void *user_data)
+{
+ GDHCPIAPrefix *prefix;
+ GSList *list;
+
+ if (!prefixes)
+ return;
+
+ DBG("");
+
+ for (list = prefixes; list; list = list->next) {
+ prefix = list->data;
+
+ prefix->valid -= time(NULL) - prefix->expire;
+ prefix->preferred -= time(NULL) - prefix->expire;
+ }
+
+ __connman_inet_ipv6_send_ra(bridge_index, NULL, prefixes,
+ DEFAULT_ROUTER_LIFETIME);
+}
+
+static gboolean do_setup(gpointer data)
+{
+ int ret;
+
+ timer_uplink = 0;
+
+ if (!default_interface)
+ DBG("No uplink connection, retrying prefix delegation");
+
+ ret = setup_prefix_delegation(__connman_service_get_default());
+ if (ret < 0 && ret != -EINPROGRESS)
+ return TRUE; /* delegation error, try again */
+
+ return FALSE;
+}
+
+static void dhcpv6_renew_callback(struct connman_network *network,
+ enum __connman_dhcpv6_status status,
+ gpointer data)
+{
+ DBG("network %p status %d data %p", network, status, data);
+
+ if (status == CONNMAN_DHCPV6_STATUS_SUCCEED)
+ dhcpv6_callback(network, status, data);
+ else
+ setup_prefix_delegation(__connman_service_get_default());
+}
+
+static void cleanup(void)
+{
+ if (timer_uplink != 0) {
+ g_source_remove(timer_uplink);
+ timer_uplink = 0;
+ }
+
+ g_hash_table_destroy(timer_hash);
+ timer_hash = NULL;
+
+ if (prefixes) {
+ g_slist_free_full(prefixes, g_free);
+ prefixes = NULL;
+ }
+}
+
+static void dhcpv6_callback(struct connman_network *network,
+ enum __connman_dhcpv6_status status, gpointer data)
+{
+ GSList *prefix_list = data;
+
+ DBG("network %p status %d data %p", network, status, data);
+
+ if (status == CONNMAN_DHCPV6_STATUS_FAIL) {
+ DBG("Prefix delegation request failed");
+ cleanup();
+ return;
+ }
+
+ if (!prefix_list) {
+ DBG("No prefixes, retrying");
+ if (timer_uplink == 0)
+ timer_uplink = g_timeout_add_seconds(10, do_setup,
+ NULL);
+ return;
+ }
+
+ /*
+ * After we have got a list of prefixes, we can start to send router
+ * advertisements (RA) to tethering interface.
+ */
+ start_ra(bridge_index, prefix_list);
+
+ if (__connman_dhcpv6_start_pd_renew(network,
+ dhcpv6_renew_callback) == -ETIMEDOUT)
+ dhcpv6_renew_callback(network, CONNMAN_DHCPV6_STATUS_FAIL,
+ NULL);
+}
+
+static int setup_prefix_delegation(struct connman_service *service)
+{
+ struct connman_ipconfig *ipconfig;
+ char *interface;
+ int err = 0, ifindex;
+
+ if (!service) {
+ /*
+ * We do not have uplink connection. We just wait until
+ * default interface is updated.
+ */
+ return -EINPROGRESS;
+ }
+
+ interface = connman_service_get_interface(service);
+
+ DBG("interface %s bridge_index %d", interface, bridge_index);
+
+ if (default_interface) {
+ stop_ra(bridge_index);
+
+ ifindex = connman_inet_ifindex(default_interface);
+ __connman_dhcpv6_stop_pd(ifindex);
+ }
+
+ g_free(default_interface);
+
+ ipconfig = __connman_service_get_ip6config(service);
+ if (!__connman_ipconfig_ipv6_is_enabled(ipconfig)) {
+ g_free(interface);
+ default_interface = NULL;
+ return -EPFNOSUPPORT;
+ }
+
+ default_interface = interface;
+
+ if (default_interface) {
+ ifindex = connman_inet_ifindex(default_interface);
+
+ /*
+ * Try to get a IPv6 prefix so we can start to advertise it.
+ */
+ err = __connman_dhcpv6_start_pd(ifindex, prefixes,
+ dhcpv6_callback);
+ if (err < 0)
+ DBG("prefix delegation %d/%s", err, strerror(-err));
+ }
+
+ return err;
+}
+
+static void cleanup_timer(gpointer user_data)
+{
+ guint timer = GPOINTER_TO_UINT(user_data);
+
+ g_source_remove(timer);
+}
+
+static void update_default_interface(struct connman_service *service)
+{
+ setup_prefix_delegation(service);
+}
+
+static void update_ipconfig(struct connman_service *service,
+ struct connman_ipconfig *ipconfig)
+{
+ if (!service || service != __connman_service_get_default())
+ return;
+
+ if (ipconfig != __connman_service_get_ip6config(service))
+ return;
+
+ if (!__connman_ipconfig_ipv6_is_enabled(ipconfig)) {
+ if (default_interface) {
+ int ifindex;
+
+ ifindex = connman_inet_ifindex(default_interface);
+ __connman_dhcpv6_stop_pd(ifindex);
+
+ g_free(default_interface);
+ default_interface = NULL;
+ }
+
+ DBG("No IPv6 support for interface index %d",
+ __connman_ipconfig_get_index(ipconfig));
+ return;
+ }
+
+ /*
+ * Did we had PD activated already? If not, then start it.
+ */
+ if (!default_interface) {
+ DBG("IPv6 ipconfig %p changed for interface index %d", ipconfig,
+ __connman_ipconfig_get_index(ipconfig));
+
+ setup_prefix_delegation(service);
+ }
+}
+
+static struct connman_notifier pd_notifier = {
+ .name = "IPv6 prefix delegation",
+ .default_changed = update_default_interface,
+ .ipconfig_changed = update_ipconfig,
+};
+
+int __connman_ipv6pd_setup(const char *bridge)
+{
+ struct connman_service *service;
+ int err;
+
+ if (!connman_inet_is_ipv6_supported())
+ return -EPFNOSUPPORT;
+
+ if (bridge_index >= 0) {
+ DBG("Prefix delegation already running");
+ return -EALREADY;
+ }
+
+ err = connman_notifier_register(&pd_notifier);
+ if (err < 0)
+ return err;
+
+ bridge_index = connman_inet_ifindex(bridge);
+
+ timer_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal,
+ NULL, cleanup_timer);
+
+ err = __connman_inet_ipv6_start_recv_rs(bridge_index, rs_received,
+ NULL, &rs_context);
+ if (err < 0)
+ DBG("Cannot receive router solicitation %d/%s",
+ err, strerror(-err));
+
+ service = __connman_service_get_default();
+ if (service) {
+ /*
+ * We have an uplink connection already, try to use it.
+ */
+ return setup_prefix_delegation(service);
+ }
+
+ /*
+ * The prefix delegation is started after have got the uplink
+ * connection up i.e., when the default service is setup in which
+ * case the update_default_interface() will be called.
+ */
+ return -EINPROGRESS;
+}
+
+void __connman_ipv6pd_cleanup(void)
+{
+ int ifindex;
+
+ if (!connman_inet_is_ipv6_supported())
+ return;
+
+ connman_notifier_unregister(&pd_notifier);
+
+ __connman_inet_ipv6_stop_recv_rs(rs_context);
+ rs_context = NULL;
+
+ cleanup();
+
+ stop_ra(bridge_index);
+
+ if (default_interface) {
+ ifindex = connman_inet_ifindex(default_interface);
+ __connman_dhcpv6_stop_pd(ifindex);
+ g_free(default_interface);
+ default_interface = NULL;
+ }
+
+ bridge_index = -1;
+}
diff --git a/src/log.c b/src/log.c
index 4e305a98..a693bd00 100644
--- a/src/log.c
+++ b/src/log.c
@@ -2,7 +2,7 @@
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2013 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -119,7 +119,7 @@ static void print_backtrace(unsigned int offset)
int pathlen;
pid_t pid;
- if (program_exec == NULL)
+ if (!program_exec)
return;
pathlen = strlen(program_path);
@@ -179,7 +179,7 @@ static void print_backtrace(unsigned int offset)
if (written < 0)
break;
- len = read(infd[0], buf, sizeof(buf));
+ len = read(infd[0], buf, sizeof(buf) - 1);
if (len < 0)
break;
@@ -243,23 +243,23 @@ extern struct connman_debug_desc __stop___debug[];
static gchar **enabled = NULL;
-static connman_bool_t is_enabled(struct connman_debug_desc *desc)
+static bool is_enabled(struct connman_debug_desc *desc)
{
int i;
- if (enabled == NULL)
- return FALSE;
+ if (!enabled)
+ return false;
- for (i = 0; enabled[i] != NULL; i++) {
- if (desc->name != NULL && g_pattern_match_simple(enabled[i],
- desc->name) == TRUE)
- return TRUE;
- if (desc->file != NULL && g_pattern_match_simple(enabled[i],
- desc->file) == TRUE)
- return TRUE;
+ for (i = 0; enabled[i]; i++) {
+ if (desc->name && g_pattern_match_simple(enabled[i],
+ desc->name))
+ return true;
+ if (desc->file && g_pattern_match_simple(enabled[i],
+ desc->file))
+ return true;
}
- return FALSE;
+ return false;
}
void __connman_log_enable(struct connman_debug_desc *start,
@@ -268,7 +268,7 @@ void __connman_log_enable(struct connman_debug_desc *start,
struct connman_debug_desc *desc;
const char *name = NULL, *file = NULL;
- if (start == NULL || stop == NULL)
+ if (!start || !stop)
return;
for (desc = start; desc < stop; desc++) {
@@ -278,21 +278,21 @@ void __connman_log_enable(struct connman_debug_desc *start,
continue;
}
- if (file != NULL || name != NULL) {
+ if (file || name) {
if (g_strcmp0(desc->file, file) == 0) {
- if (desc->name == NULL)
+ if (!desc->name)
desc->name = name;
} else
file = NULL;
}
- if (is_enabled(desc) == TRUE)
+ if (is_enabled(desc))
desc->flags |= CONNMAN_DEBUG_FLAG_PRINT;
}
}
int __connman_log_init(const char *program, const char *debug,
- connman_bool_t detach, connman_bool_t backtrace,
+ gboolean detach, gboolean backtrace,
const char *program_name, const char *program_version)
{
static char path[PATH_MAX];
@@ -301,15 +301,15 @@ int __connman_log_init(const char *program, const char *debug,
program_exec = program;
program_path = getcwd(path, sizeof(path));
- if (debug != NULL)
+ if (debug)
enabled = g_strsplit_set(debug, ":, ", 0);
__connman_log_enable(__start___debug, __stop___debug);
- if (detach == FALSE)
+ if (!detach)
option |= LOG_PERROR;
- if (backtrace == TRUE)
+ if (backtrace)
signal_setup(signal_handler);
openlog(basename(program), option, LOG_DAEMON);
@@ -319,13 +319,13 @@ int __connman_log_init(const char *program, const char *debug,
return 0;
}
-void __connman_log_cleanup(connman_bool_t backtrace)
+void __connman_log_cleanup(gboolean backtrace)
{
syslog(LOG_INFO, "Exit");
closelog();
- if (backtrace == TRUE)
+ if (backtrace)
signal_setup(SIG_DFL);
g_strfreev(enabled);
diff --git a/src/main.c b/src/main.c
index c257ca0b..4f635de5 100644
--- a/src/main.c
+++ b/src/main.c
@@ -2,7 +2,7 @@
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2013 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -39,8 +39,8 @@
#include "connman.h"
-#define DEFAULT_INPUT_REQUEST_TIMEOUT 120 * 1000
-#define DEFAULT_BROWSER_LAUNCH_TIMEOUT 300 * 1000
+#define DEFAULT_INPUT_REQUEST_TIMEOUT (120 * 1000)
+#define DEFAULT_BROWSER_LAUNCH_TIMEOUT (300 * 1000)
#define MAINFILE "main.conf"
#define CONFIGMAINFILE CONFIGDIR "/" MAINFILE
@@ -56,11 +56,12 @@ static char *default_blacklist[] = {
"vmnet",
"vboxnet",
"virbr",
+ "ifb",
NULL
};
static struct {
- connman_bool_t bg_scan;
+ bool bg_scan;
char **pref_timeservers;
unsigned int *auto_connect;
unsigned int *preferred_techs;
@@ -68,12 +69,12 @@ static struct {
unsigned int timeout_inputreq;
unsigned int timeout_browserlaunch;
char **blacklisted_interfaces;
- connman_bool_t allow_hostname_updates;
- connman_bool_t single_tech;
+ bool allow_hostname_updates;
+ bool single_tech;
char **tethering_technologies;
- connman_bool_t persistent_tethering_mode;
+ bool persistent_tethering_mode;
} connman_settings = {
- .bg_scan = TRUE,
+ .bg_scan = true,
.pref_timeservers = NULL,
.auto_connect = NULL,
.preferred_techs = NULL,
@@ -81,10 +82,10 @@ static struct {
.timeout_inputreq = DEFAULT_INPUT_REQUEST_TIMEOUT,
.timeout_browserlaunch = DEFAULT_BROWSER_LAUNCH_TIMEOUT,
.blacklisted_interfaces = NULL,
- .allow_hostname_updates = TRUE,
- .single_tech = FALSE,
+ .allow_hostname_updates = true,
+ .single_tech = false,
.tethering_technologies = NULL,
- .persistent_tethering_mode = FALSE,
+ .persistent_tethering_mode = false,
};
#define CONF_BG_SCAN "BackgroundScanning"
@@ -146,13 +147,12 @@ static uint *parse_service_types(char **str_list, gsize len)
enum connman_service_type type;
type_list = g_try_new0(unsigned int, len + 1);
- if (type_list == NULL)
+ if (!type_list)
return NULL;
i = 0;
j = 0;
- while (str_list[i] != NULL)
- {
+ while (str_list[i]) {
type = __connman_service_string2type(str_list[i]);
if (type != CONNMAN_SERVICE_TYPE_UNKNOWN) {
@@ -162,6 +162,8 @@ static uint *parse_service_types(char **str_list, gsize len)
i += 1;
}
+ type_list[j] = CONNMAN_SERVICE_TYPE_UNKNOWN;
+
return type_list;
}
@@ -171,12 +173,12 @@ static char **parse_fallback_nameservers(char **nameservers, gsize len)
int i, j;
servers = g_try_new0(char *, len + 1);
- if (servers == NULL)
+ if (!servers)
return NULL;
i = 0;
j = 0;
- while (nameservers[i] != NULL) {
+ while (nameservers[i]) {
if (connman_inet_check_ipaddress(nameservers[i]) > 0) {
servers[j] = g_strdup(nameservers[i]);
j += 1;
@@ -192,12 +194,12 @@ static void check_config(GKeyFile *config)
char **keys;
int j;
- if (config == NULL)
+ if (!config)
return;
keys = g_key_file_get_groups(config, NULL);
- for (j = 0; keys != NULL && keys[j] != NULL; j++) {
+ for (j = 0; keys && keys[j]; j++) {
if (g_strcmp0(keys[j], "General") != 0)
connman_warn("Unknown group %s in %s",
keys[j], MAINFILE);
@@ -207,18 +209,18 @@ static void check_config(GKeyFile *config)
keys = g_key_file_get_keys(config, "General", NULL, NULL);
- for (j = 0; keys != NULL && keys[j] != NULL; j++) {
- connman_bool_t found;
+ for (j = 0; keys && keys[j]; j++) {
+ bool found;
int i;
- found = FALSE;
- for (i = 0; supported_options[i] != NULL; i++) {
+ found = false;
+ for (i = 0; supported_options[i]; i++) {
if (g_strcmp0(keys[j], supported_options[i]) == 0) {
- found = TRUE;
+ found = true;
break;
}
}
- if (found == FALSE && supported_options[i] == NULL)
+ if (!found && !supported_options[i])
connman_warn("Unknown option %s in %s",
keys[j], MAINFILE);
}
@@ -229,7 +231,7 @@ static void check_config(GKeyFile *config)
static void parse_config(GKeyFile *config)
{
GError *error = NULL;
- gboolean boolean;
+ bool boolean;
char **timeservers;
char **interfaces;
char **str_list;
@@ -237,7 +239,7 @@ static void parse_config(GKeyFile *config)
gsize len;
int timeout;
- if (config == NULL) {
+ if (!config) {
connman_settings.auto_connect =
parse_service_types(default_auto_connect, 3);
connman_settings.blacklisted_interfaces =
@@ -249,22 +251,22 @@ static void parse_config(GKeyFile *config)
boolean = g_key_file_get_boolean(config, "General",
CONF_BG_SCAN, &error);
- if (error == NULL)
+ if (!error)
connman_settings.bg_scan = boolean;
g_clear_error(&error);
- timeservers = g_key_file_get_string_list(config, "General",
+ timeservers = __connman_config_get_string_list(config, "General",
CONF_PREF_TIMESERVERS, NULL, &error);
- if (error == NULL)
+ if (!error)
connman_settings.pref_timeservers = timeservers;
g_clear_error(&error);
- str_list = g_key_file_get_string_list(config, "General",
+ str_list = __connman_config_get_string_list(config, "General",
CONF_AUTO_CONNECT, &len, &error);
- if (error == NULL)
+ if (!error)
connman_settings.auto_connect =
parse_service_types(str_list, len);
else
@@ -275,10 +277,10 @@ static void parse_config(GKeyFile *config)
g_clear_error(&error);
- str_list = g_key_file_get_string_list(config, "General",
+ str_list = __connman_config_get_string_list(config, "General",
CONF_PREFERRED_TECHS, &len, &error);
- if (error == NULL)
+ if (!error)
connman_settings.preferred_techs =
parse_service_types(str_list, len);
@@ -286,10 +288,10 @@ static void parse_config(GKeyFile *config)
g_clear_error(&error);
- str_list = g_key_file_get_string_list(config, "General",
+ str_list = __connman_config_get_string_list(config, "General",
CONF_FALLBACK_NAMESERVERS, &len, &error);
- if (error == NULL)
+ if (!error)
connman_settings.fallback_nameservers =
parse_fallback_nameservers(str_list, len);
@@ -299,22 +301,22 @@ static void parse_config(GKeyFile *config)
timeout = g_key_file_get_integer(config, "General",
CONF_TIMEOUT_INPUTREQ, &error);
- if (error == NULL && timeout >= 0)
+ if (!error && timeout >= 0)
connman_settings.timeout_inputreq = timeout * 1000;
g_clear_error(&error);
timeout = g_key_file_get_integer(config, "General",
CONF_TIMEOUT_BROWSERLAUNCH, &error);
- if (error == NULL && timeout >= 0)
+ if (!error && timeout >= 0)
connman_settings.timeout_browserlaunch = timeout * 1000;
g_clear_error(&error);
- interfaces = g_key_file_get_string_list(config, "General",
+ interfaces = __connman_config_get_string_list(config, "General",
CONF_BLACKLISTED_INTERFACES, &len, &error);
- if (error == NULL)
+ if (!error)
connman_settings.blacklisted_interfaces = interfaces;
else
connman_settings.blacklisted_interfaces =
@@ -322,33 +324,33 @@ static void parse_config(GKeyFile *config)
g_clear_error(&error);
- boolean = g_key_file_get_boolean(config, "General",
+ boolean = __connman_config_get_bool(config, "General",
CONF_ALLOW_HOSTNAME_UPDATES,
&error);
- if (error == NULL)
+ if (!error)
connman_settings.allow_hostname_updates = boolean;
g_clear_error(&error);
- boolean = g_key_file_get_boolean(config, "General",
+ boolean = __connman_config_get_bool(config, "General",
CONF_SINGLE_TECH, &error);
- if (error == NULL)
+ if (!error)
connman_settings.single_tech = boolean;
g_clear_error(&error);
- tethering = g_key_file_get_string_list(config, "General",
+ tethering = __connman_config_get_string_list(config, "General",
CONF_TETHERING_TECHNOLOGIES, &len, &error);
- if (error == NULL)
+ if (!error)
connman_settings.tethering_technologies = tethering;
g_clear_error(&error);
- boolean = g_key_file_get_boolean(config, "General",
+ boolean = __connman_config_get_bool(config, "General",
CONF_PERSISTENT_TETHERING_MODE,
&error);
- if (error == NULL)
+ if (!error)
connman_settings.persistent_tethering_mode = boolean;
g_clear_error(&error);
@@ -361,7 +363,7 @@ static int config_init(const char *file)
config = load_config(file);
check_config(config);
parse_config(config);
- if (config != NULL)
+ if (config)
g_key_file_free(config);
return 0;
@@ -458,7 +460,7 @@ static gboolean option_dnsproxy = TRUE;
static gboolean option_backtrace = TRUE;
static gboolean option_version = FALSE;
-static gboolean parse_debug(const char *key, const char *value,
+static bool parse_debug(const char *key, const char *value,
gpointer user_data, GError **error)
{
if (value)
@@ -466,7 +468,7 @@ static gboolean parse_debug(const char *key, const char *value,
else
option_debug = g_strdup("*");
- return TRUE;
+ return true;
}
static GOptionEntry options[] = {
@@ -503,7 +505,7 @@ static GOptionEntry options[] = {
const char *connman_option_get_string(const char *key)
{
if (g_strcmp0(key, "wifi") == 0) {
- if (option_wifi == NULL)
+ if (!option_wifi)
return "nl80211,wext";
else
return option_wifi;
@@ -512,35 +514,35 @@ const char *connman_option_get_string(const char *key)
return NULL;
}
-connman_bool_t connman_setting_get_bool(const char *key)
+bool connman_setting_get_bool(const char *key)
{
- if (g_str_equal(key, CONF_BG_SCAN) == TRUE)
+ if (g_str_equal(key, CONF_BG_SCAN))
return connman_settings.bg_scan;
- if (g_str_equal(key, CONF_ALLOW_HOSTNAME_UPDATES) == TRUE)
+ if (g_str_equal(key, CONF_ALLOW_HOSTNAME_UPDATES))
return connman_settings.allow_hostname_updates;
- if (g_str_equal(key, CONF_SINGLE_TECH) == TRUE)
+ if (g_str_equal(key, CONF_SINGLE_TECH))
return connman_settings.single_tech;
- if (g_str_equal(key, CONF_PERSISTENT_TETHERING_MODE) == TRUE)
+ if (g_str_equal(key, CONF_PERSISTENT_TETHERING_MODE))
return connman_settings.persistent_tethering_mode;
- return FALSE;
+ return false;
}
char **connman_setting_get_string_list(const char *key)
{
- if (g_str_equal(key, CONF_PREF_TIMESERVERS) == TRUE)
+ if (g_str_equal(key, CONF_PREF_TIMESERVERS))
return connman_settings.pref_timeservers;
- if (g_str_equal(key, CONF_FALLBACK_NAMESERVERS) == TRUE)
+ if (g_str_equal(key, CONF_FALLBACK_NAMESERVERS))
return connman_settings.fallback_nameservers;
- if (g_str_equal(key, CONF_BLACKLISTED_INTERFACES) == TRUE)
+ if (g_str_equal(key, CONF_BLACKLISTED_INTERFACES))
return connman_settings.blacklisted_interfaces;
- if (g_str_equal(key, CONF_TETHERING_TECHNOLOGIES) == TRUE)
+ if (g_str_equal(key, CONF_TETHERING_TECHNOLOGIES))
return connman_settings.tethering_technologies;
return NULL;
@@ -548,20 +550,22 @@ char **connman_setting_get_string_list(const char *key)
unsigned int *connman_setting_get_uint_list(const char *key)
{
- if (g_str_equal(key, CONF_AUTO_CONNECT) == TRUE)
+ if (g_str_equal(key, CONF_AUTO_CONNECT))
return connman_settings.auto_connect;
- if (g_str_equal(key, CONF_PREFERRED_TECHS) == TRUE)
+ if (g_str_equal(key, CONF_PREFERRED_TECHS))
return connman_settings.preferred_techs;
return NULL;
}
-unsigned int connman_timeout_input_request(void) {
+unsigned int connman_timeout_input_request(void)
+{
return connman_settings.timeout_inputreq;
}
-unsigned int connman_timeout_browser_launch(void) {
+unsigned int connman_timeout_browser_launch(void)
+{
return connman_settings.timeout_browserlaunch;
}
@@ -573,16 +577,11 @@ int main(int argc, char *argv[])
DBusError err;
guint signal;
-#ifdef NEED_THREADS
- if (g_thread_supported() == FALSE)
- g_thread_init(NULL);
-#endif
-
context = g_option_context_new(NULL);
g_option_context_add_main_entries(context, options, NULL);
- if (g_option_context_parse(context, &argc, &argv, &error) == FALSE) {
- if (error != NULL) {
+ if (!g_option_context_parse(context, &argc, &argv, &error)) {
+ if (error) {
g_printerr("%s\n", error->message);
g_error_free(error);
} else
@@ -592,24 +591,18 @@ int main(int argc, char *argv[])
g_option_context_free(context);
- if (option_version == TRUE) {
+ if (option_version) {
printf("%s\n", VERSION);
exit(0);
}
- if (option_detach == TRUE) {
+ if (option_detach) {
if (daemon(0, 0)) {
perror("Can't start daemon");
exit(1);
}
}
- if (mkdir(STATEDIR, S_IRUSR | S_IWUSR | S_IXUSR |
- S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) < 0) {
- if (errno != EEXIST)
- perror("Failed to create state directory");
- }
-
if (mkdir(STORAGEDIR, S_IRUSR | S_IWUSR | S_IXUSR |
S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) < 0) {
if (errno != EEXIST)
@@ -620,20 +613,13 @@ int main(int argc, char *argv[])
main_loop = g_main_loop_new(NULL, FALSE);
-#ifdef NEED_THREADS
- if (dbus_threads_init_default() == FALSE) {
- fprintf(stderr, "Can't init usage of threads\n");
- exit(1);
- }
-#endif
-
signal = setup_signalfd();
dbus_error_init(&err);
conn = g_dbus_setup_bus(DBUS_BUS_SYSTEM, CONNMAN_SERVICE, &err);
- if (conn == NULL) {
- if (dbus_error_is_set(&err) == TRUE) {
+ if (!conn) {
+ if (dbus_error_is_set(&err)) {
fprintf(stderr, "%s\n", err.message);
dbus_error_free(&err);
} else
@@ -648,7 +634,7 @@ int main(int argc, char *argv[])
__connman_dbus_init(conn);
- if (option_config == NULL)
+ if (!option_config)
config_init(CONFIGMAINFILE);
else
config_init(option_config);
@@ -658,8 +644,10 @@ int main(int argc, char *argv[])
__connman_notifier_init();
__connman_agent_init();
__connman_service_init();
+ __connman_peer_init();
__connman_provider_init();
__connman_network_init();
+ __connman_config_init();
__connman_device_init(option_device, option_nodevice);
__connman_ippool_init();
@@ -669,7 +657,6 @@ int main(int argc, char *argv[])
__connman_tethering_init();
__connman_counter_init();
__connman_manager_init();
- __connman_config_init();
__connman_stats_init();
__connman_clock_init();
@@ -706,7 +693,6 @@ int main(int argc, char *argv[])
__connman_wispr_cleanup();
__connman_wpad_cleanup();
__connman_dhcpv6_cleanup();
- __connman_dhcp_cleanup();
__connman_session_cleanup();
__connman_plugin_cleanup();
__connman_provider_cleanup();
@@ -730,7 +716,9 @@ int main(int argc, char *argv[])
__connman_ippool_cleanup();
__connman_device_cleanup();
__connman_network_cleanup();
+ __connman_dhcp_cleanup();
__connman_service_cleanup();
+ __connman_peer_cleanup();
__connman_agent_cleanup();
__connman_ipconfig_cleanup();
__connman_notifier_cleanup();
@@ -745,7 +733,7 @@ int main(int argc, char *argv[])
g_main_loop_unref(main_loop);
- if (connman_settings.pref_timeservers != NULL)
+ if (connman_settings.pref_timeservers)
g_strfreev(connman_settings.pref_timeservers);
g_free(connman_settings.auto_connect);
diff --git a/src/main.conf b/src/main.conf
index b8b3239b..93c7a501 100644
--- a/src/main.conf
+++ b/src/main.conf
@@ -27,8 +27,8 @@
# domain names, IPv4 and IPv6 addresses.
# FallbackTimeservers =
-# List of fallback nameservers separated by "," appended
-# to the list of nameservers given by the service. The
+# List of fallback nameservers separated by "," used if no
+# nameservers are otherwise provided by the service. The
# nameserver entries must be in numeric format, host
# names are ignored.
# FallbackNameservers =
@@ -57,8 +57,8 @@
# Found interfaces will be compared to the list and will
# not be handled by connman, if their first characters
# match any of the list entries. Default value is
-# vmnet,vboxnet,virbr.
-# NetworkInterfaceBlacklist = vmnet,vboxnet,virbr
+# vmnet,vboxnet,virbr,ifb.
+# NetworkInterfaceBlacklist = vmnet,vboxnet,virbr,ifb
# Allow connman to change the system hostname. This can
# happen for example if we receive DHCP hostname option.
diff --git a/src/manager.c b/src/manager.c
index e56f2e13..b31ab4c7 100644
--- a/src/manager.c
+++ b/src/manager.c
@@ -2,7 +2,7 @@
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2013 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -31,21 +31,21 @@
#include "connman.h"
-static connman_bool_t connman_state_idle;
-static DBusMessage *session_mode_pending = NULL;
+static bool connman_state_idle;
+static dbus_bool_t sessionmode;
static DBusMessage *get_properties(DBusConnection *conn,
DBusMessage *msg, void *data)
{
DBusMessage *reply;
DBusMessageIter array, dict;
- connman_bool_t offlinemode, sessionmode;
+ dbus_bool_t offlinemode;
const char *str;
DBG("conn %p", conn);
reply = dbus_message_new_method_return(msg);
- if (reply == NULL)
+ if (!reply)
return NULL;
dbus_message_iter_init_append(reply, &array);
@@ -60,7 +60,6 @@ static DBusMessage *get_properties(DBusConnection *conn,
connman_dbus_dict_append_basic(&dict, "OfflineMode",
DBUS_TYPE_BOOLEAN, &offlinemode);
- sessionmode = __connman_session_mode();
connman_dbus_dict_append_basic(&dict, "SessionMode",
DBUS_TYPE_BOOLEAN,
&sessionmode);
@@ -79,7 +78,7 @@ static DBusMessage *set_property(DBusConnection *conn,
DBG("conn %p", conn);
- if (dbus_message_iter_init(msg, &iter) == FALSE)
+ if (!dbus_message_iter_init(msg, &iter))
return __connman_error_invalid_arguments(msg);
if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
@@ -95,8 +94,8 @@ static DBusMessage *set_property(DBusConnection *conn,
type = dbus_message_iter_get_arg_type(&value);
- if (g_str_equal(name, "OfflineMode") == TRUE) {
- connman_bool_t offlinemode;
+ if (g_str_equal(name, "OfflineMode")) {
+ dbus_bool_t offlinemode;
if (type != DBUS_TYPE_BOOLEAN)
return __connman_error_invalid_arguments(msg);
@@ -104,24 +103,13 @@ static DBusMessage *set_property(DBusConnection *conn,
dbus_message_iter_get_basic(&value, &offlinemode);
__connman_technology_set_offlinemode(offlinemode);
- } else if (g_str_equal(name, "SessionMode") == TRUE) {
- connman_bool_t sessionmode;
+ } else if (g_str_equal(name, "SessionMode")) {
if (type != DBUS_TYPE_BOOLEAN)
return __connman_error_invalid_arguments(msg);
dbus_message_iter_get_basic(&value, &sessionmode);
- if (session_mode_pending != NULL)
- return __connman_error_in_progress(msg);
-
- __connman_session_set_mode(sessionmode);
-
- if (sessionmode == TRUE && connman_state_idle == FALSE) {
- session_mode_pending = dbus_message_ref(msg);
- return NULL;
- }
-
} else
return __connman_error_invalid_property(msg);
@@ -141,7 +129,7 @@ static DBusMessage *get_technologies(DBusConnection *conn,
DBG("");
reply = dbus_message_new_method_return(msg);
- if (reply == NULL)
+ if (!reply)
return NULL;
__connman_dbus_append_objpath_dict_array(reply,
@@ -170,28 +158,15 @@ static DBusMessage *remove_provider(DBusConnection *conn,
static DBusConnection *connection = NULL;
-static void session_mode_notify(void)
-{
- DBusMessage *reply;
-
- reply = g_dbus_create_reply(session_mode_pending, DBUS_TYPE_INVALID);
- g_dbus_send_message(connection, reply);
-
- dbus_message_unref(session_mode_pending);
- session_mode_pending = NULL;
-}
-
-static void idle_state(connman_bool_t idle)
+static void idle_state(bool idle)
{
DBG("idle %d", idle);
connman_state_idle = idle;
- if (connman_state_idle == FALSE || session_mode_pending == NULL)
+ if (!connman_state_idle)
return;
-
- session_mode_notify();
}
static struct connman_notifier technology_notifier = {
@@ -211,7 +186,7 @@ static DBusMessage *get_services(DBusConnection *conn,
DBusMessage *reply;
reply = dbus_message_new_method_return(msg);
- if (reply == NULL)
+ if (!reply)
return NULL;
__connman_dbus_append_objpath_dict_array(reply,
@@ -220,6 +195,25 @@ static DBusMessage *get_services(DBusConnection *conn,
return reply;
}
+static void append_peer_structs(DBusMessageIter *iter, void *user_data)
+{
+ __connman_peer_list_struct(iter);
+}
+
+static DBusMessage *get_peers(DBusConnection *conn,
+ DBusMessage *msg, void *data)
+{
+ DBusMessage *reply;
+
+ reply = dbus_message_new_method_return(msg);
+ if (!reply)
+ return NULL;
+
+ __connman_dbus_append_objpath_dict_array(reply,
+ append_peer_structs, NULL);
+ return reply;
+}
+
static DBusMessage *connect_provider(DBusConnection *conn,
DBusMessage *msg, void *data)
{
@@ -227,13 +221,6 @@ static DBusMessage *connect_provider(DBusConnection *conn,
DBG("conn %p", conn);
- if (__connman_session_mode() == TRUE) {
- connman_info("Session mode enabled: "
- "direct provider connect disabled");
-
- return __connman_error_failed(msg, EINVAL);
- }
-
err = __connman_provider_create_and_connect(msg);
if (err < 0)
return __connman_error_failed(msg, -err);
@@ -409,6 +396,9 @@ static const GDBusMethodTable manager_methods[] = {
{ GDBUS_METHOD("GetServices",
NULL, GDBUS_ARGS({ "services", "a(oa{sv})" }),
get_services) },
+ { GDBUS_METHOD("GetPeers",
+ NULL, GDBUS_ARGS({ "peers", "a(oa{sv})" }),
+ get_peers) },
{ GDBUS_DEPRECATED_ASYNC_METHOD("ConnectProvider",
GDBUS_ARGS({ "provider", "a{sv}" }),
GDBUS_ARGS({ "path", "o" }),
@@ -456,6 +446,9 @@ static const GDBusSignalTable manager_signals[] = {
{ GDBUS_SIGNAL("ServicesChanged",
GDBUS_ARGS({ "changed", "a(oa{sv})" },
{ "removed", "ao" })) },
+ { GDBUS_SIGNAL("PeersChanged",
+ GDBUS_ARGS({ "changed", "a(oa{sv})" },
+ { "removed", "ao" })) },
{ },
};
@@ -464,7 +457,7 @@ int __connman_manager_init(void)
DBG("");
connection = connman_dbus_get_connection();
- if (connection == NULL)
+ if (!connection)
return -1;
if (connman_notifier_register(&technology_notifier) < 0)
@@ -475,7 +468,7 @@ int __connman_manager_init(void)
manager_methods,
manager_signals, NULL, NULL, NULL);
- connman_state_idle = TRUE;
+ connman_state_idle = true;
return 0;
}
@@ -484,12 +477,9 @@ void __connman_manager_cleanup(void)
{
DBG("");
- if (connection == NULL)
+ if (!connection)
return;
- if (session_mode_pending != NULL)
- dbus_message_unref(session_mode_pending);
-
connman_notifier_unregister(&technology_notifier);
g_dbus_unregister_interface(connection, CONNMAN_MANAGER_PATH,
diff --git a/src/nat.c b/src/nat.c
index 5447eb71..4d235504 100644
--- a/src/nat.c
+++ b/src/nat.c
@@ -35,19 +35,20 @@ static GHashTable *nat_hash;
struct connman_nat {
char *address;
unsigned char prefixlen;
+ struct firewall_context *fw;
char *interface;
};
-static int enable_ip_forward(connman_bool_t enable)
+static int enable_ip_forward(bool enable)
{
FILE *f;
f = fopen("/proc/sys/net/ipv4/ip_forward", "r+");
- if (f == NULL)
+ if (!f)
return -errno;
- if (enable == TRUE)
+ if (enable)
fprintf(f, "1");
else
fprintf(f, "0");
@@ -65,7 +66,7 @@ static int enable_nat(struct connman_nat *nat)
g_free(nat->interface);
nat->interface = g_strdup(default_interface);
- if (nat->interface == NULL)
+ if (!nat->interface)
return 0;
/* Enable masquerading */
@@ -73,33 +74,23 @@ static int enable_nat(struct connman_nat *nat)
nat->address,
nat->prefixlen,
nat->interface);
- err = __connman_iptables_append("nat", "POSTROUTING", cmd);
+
+ err = __connman_firewall_add_rule(nat->fw, "nat",
+ "POSTROUTING", cmd);
g_free(cmd);
if (err < 0)
return err;
- return __connman_iptables_commit("nat");
+ return __connman_firewall_enable(nat->fw);
}
static void disable_nat(struct connman_nat *nat)
{
- char *cmd;
- int err;
-
- if (nat->interface == NULL)
+ if (!nat->interface)
return;
/* Disable masquerading */
- cmd = g_strdup_printf("-s %s/%d -o %s -j MASQUERADE",
- nat->address,
- nat->prefixlen,
- nat->interface);
- err = __connman_iptables_delete("nat", "POSTROUTING", cmd);
- g_free(cmd);
- if (err < 0)
- return;
-
- __connman_iptables_commit("nat");
+ __connman_firewall_disable(nat->fw);
}
int __connman_nat_enable(const char *name, const char *address,
@@ -109,18 +100,18 @@ int __connman_nat_enable(const char *name, const char *address,
int err;
if (g_hash_table_size(nat_hash) == 0) {
- err = enable_ip_forward(TRUE);
+ err = enable_ip_forward(true);
if (err < 0)
return err;
}
nat = g_try_new0(struct connman_nat, 1);
- if (nat == NULL) {
- if (g_hash_table_size(nat_hash) == 0)
- enable_ip_forward(FALSE);
+ if (!nat)
+ goto err;
- return -ENOMEM;
- }
+ nat->fw = __connman_firewall_create();
+ if (!nat->fw)
+ goto err;
nat->address = g_strdup(address);
nat->prefixlen = prefixlen;
@@ -128,6 +119,18 @@ int __connman_nat_enable(const char *name, const char *address,
g_hash_table_replace(nat_hash, g_strdup(name), nat);
return enable_nat(nat);
+
+err:
+ if (nat) {
+ if (nat->fw)
+ __connman_firewall_destroy(nat->fw);
+ g_free(nat);
+ }
+
+ if (g_hash_table_size(nat_hash) == 0)
+ enable_ip_forward(false);
+
+ return -ENOMEM;
}
void __connman_nat_disable(const char *name)
@@ -135,7 +138,7 @@ void __connman_nat_disable(const char *name)
struct connman_nat *nat;
nat = g_hash_table_lookup(nat_hash, name);
- if (nat == NULL)
+ if (!nat)
return;
disable_nat(nat);
@@ -143,7 +146,7 @@ void __connman_nat_disable(const char *name)
g_hash_table_remove(nat_hash, name);
if (g_hash_table_size(nat_hash) == 0)
- enable_ip_forward(FALSE);
+ enable_ip_forward(false);
}
static void update_default_interface(struct connman_service *service)
@@ -162,7 +165,7 @@ static void update_default_interface(struct connman_service *service)
g_hash_table_iter_init(&iter, nat_hash);
- while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
+ while (g_hash_table_iter_next(&iter, &key, &value)) {
const char *name = key;
struct connman_nat *nat = value;
@@ -184,6 +187,7 @@ static void cleanup_nat(gpointer data)
{
struct connman_nat *nat = data;
+ __connman_firewall_destroy(nat->fw);
g_free(nat->address);
g_free(nat->interface);
g_free(nat);
diff --git a/src/net.connman.service.in b/src/net.connman.service.in
new file mode 100644
index 00000000..0bb1e8b9
--- /dev/null
+++ b/src/net.connman.service.in
@@ -0,0 +1,5 @@
+[D-BUS Service]
+Name=net.connman
+Exec=@prefix@/sbin/connman -n
+User=root
+SystemdService=connman.service
diff --git a/src/network.c b/src/network.c
index 6a926cbc..160bd061 100644
--- a/src/network.c
+++ b/src/network.c
@@ -2,7 +2,7 @@
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2014 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -47,9 +47,9 @@ static GSList *driver_list = NULL;
struct connman_network {
int refcount;
enum connman_network_type type;
- connman_bool_t available;
- connman_bool_t connected;
- connman_bool_t roaming;
+ bool available;
+ bool connected;
+ bool roaming;
uint8_t strength;
uint16_t frequency;
char *identifier;
@@ -64,8 +64,8 @@ struct connman_network {
struct connman_network_driver *driver;
void *driver_data;
- connman_bool_t connecting;
- connman_bool_t associating;
+ bool connecting;
+ bool associating;
struct connman_device *device;
@@ -76,7 +76,6 @@ struct connman_network {
unsigned short channel;
char *security;
char *passphrase;
- char *agent_passphrase;
char *eap;
char *identity;
char *agent_identity;
@@ -85,8 +84,8 @@ struct connman_network {
char *private_key_path;
char *private_key_passphrase;
char *phase2_auth;
- connman_bool_t wps;
- connman_bool_t use_wps;
+ bool wps;
+ bool use_wps;
char *pin_wps;
} wifi;
@@ -100,6 +99,8 @@ static const char *type2string(enum connman_network_type type)
break;
case CONNMAN_NETWORK_TYPE_ETHERNET:
return "ethernet";
+ case CONNMAN_NETWORK_TYPE_GADGET:
+ return "gadget";
case CONNMAN_NETWORK_TYPE_WIFI:
return "wifi";
case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
@@ -112,14 +113,14 @@ static const char *type2string(enum connman_network_type type)
return NULL;
}
-static gboolean match_driver(struct connman_network *network,
+static bool match_driver(struct connman_network *network,
struct connman_network_driver *driver)
{
if (network->type == driver->type ||
driver->type == CONNMAN_NETWORK_TYPE_UNKNOWN)
- return TRUE;
+ return true;
- return FALSE;
+ return false;
}
static void set_configuration(struct connman_network *network,
@@ -129,12 +130,12 @@ static void set_configuration(struct connman_network *network,
DBG("network %p", network);
- if (network->device == NULL)
+ if (!network->device)
return;
__connman_device_set_network(network->device, network);
- connman_device_set_disconnected(network->device, FALSE);
+ connman_device_set_disconnected(network->device, false);
service = connman_service_lookup_from_network(network);
__connman_service_ipconfig_indicate_state(service,
@@ -149,14 +150,20 @@ static void dhcp_success(struct connman_network *network)
int err;
service = connman_service_lookup_from_network(network);
- if (service == NULL)
+ if (!service)
goto err;
- connman_network_set_associating(network, FALSE);
+ connman_network_set_associating(network, false);
- network->connecting = FALSE;
+ network->connecting = false;
ipconfig_ipv4 = __connman_service_get_ip4config(service);
+
+ DBG("lease acquired for ipconfig %p", ipconfig_ipv4);
+
+ if (!ipconfig_ipv4)
+ return;
+
err = __connman_ipconfig_address_add(ipconfig_ipv4);
if (err < 0)
goto err;
@@ -175,22 +182,30 @@ err:
static void dhcp_failure(struct connman_network *network)
{
struct connman_service *service;
+ struct connman_ipconfig *ipconfig_ipv4;
service = connman_service_lookup_from_network(network);
- if (service == NULL)
+ if (!service)
return;
- __connman_service_ipconfig_indicate_state(service,
- CONNMAN_SERVICE_STATE_IDLE,
- CONNMAN_IPCONFIG_TYPE_IPV4);
+ connman_network_set_associating(network, false);
+ network->connecting = false;
+
+ ipconfig_ipv4 = __connman_service_get_ip4config(service);
+
+ DBG("lease lost for ipconfig %p", ipconfig_ipv4);
+
+ if (!ipconfig_ipv4)
+ return;
+
+ __connman_ipconfig_address_remove(ipconfig_ipv4);
+ __connman_ipconfig_gateway_remove(ipconfig_ipv4);
}
static void dhcp_callback(struct connman_network *network,
- connman_bool_t success)
+ bool success, gpointer data)
{
- DBG("success %d", success);
-
- if (success == TRUE)
+ if (success)
dhcp_success(network);
else
dhcp_failure(network);
@@ -210,9 +225,9 @@ static int set_connected_fixed(struct connman_network *network)
set_configuration(network, CONNMAN_IPCONFIG_TYPE_IPV4);
- network->connecting = FALSE;
+ network->connecting = false;
- connman_network_set_associating(network, FALSE);
+ connman_network_set_associating(network, false);
err = __connman_ipconfig_address_add(ipconfig_ipv4);
if (err < 0)
@@ -243,7 +258,7 @@ static void set_connected_manual(struct connman_network *network)
ipconfig = __connman_service_get_ip4config(service);
- if (__connman_ipconfig_get_local(ipconfig) == NULL)
+ if (!__connman_ipconfig_get_local(ipconfig))
__connman_service_read_ip4config(service);
set_configuration(network, CONNMAN_IPCONFIG_TYPE_IPV4);
@@ -256,9 +271,9 @@ static void set_connected_manual(struct connman_network *network)
if (err < 0)
goto err;
- network->connecting = FALSE;
+ network->connecting = false;
- connman_network_set_associating(network, FALSE);
+ connman_network_set_associating(network, false);
return;
@@ -294,10 +309,10 @@ static int manual_ipv6_set(struct connman_network *network,
DBG("network %p ipv6 %p", network, ipconfig_ipv6);
service = connman_service_lookup_from_network(network);
- if (service == NULL)
+ if (!service)
return -EINVAL;
- if (__connman_ipconfig_get_local(ipconfig_ipv6) == NULL)
+ if (!__connman_ipconfig_get_local(ipconfig_ipv6))
__connman_service_read_ip6config(service);
__connman_ipconfig_enable_ipv6(ipconfig_ipv6);
@@ -318,9 +333,9 @@ static int manual_ipv6_set(struct connman_network *network,
__connman_device_set_network(network->device, network);
- connman_device_set_disconnected(network->device, FALSE);
+ connman_device_set_disconnected(network->device, false);
- network->connecting = FALSE;
+ network->connecting = false;
return 0;
}
@@ -331,9 +346,10 @@ static void stop_dhcpv6(struct connman_network *network)
}
static void dhcpv6_release_callback(struct connman_network *network,
- connman_bool_t success)
+ enum __connman_dhcpv6_status status,
+ gpointer data)
{
- DBG("success %d", success);
+ DBG("status %d", status);
stop_dhcpv6(network);
}
@@ -345,26 +361,27 @@ static void release_dhcpv6(struct connman_network *network)
}
static void dhcpv6_info_callback(struct connman_network *network,
- connman_bool_t success)
+ enum __connman_dhcpv6_status status,
+ gpointer data)
{
- DBG("success %d", success);
+ DBG("status %d", status);
stop_dhcpv6(network);
}
-static gboolean dhcpv6_set_addresses(struct connman_network *network)
+static int dhcpv6_set_addresses(struct connman_network *network)
{
struct connman_service *service;
struct connman_ipconfig *ipconfig_ipv6;
int err = -EINVAL;
service = connman_service_lookup_from_network(network);
- if (service == NULL)
+ if (!service)
goto err;
- connman_network_set_associating(network, FALSE);
+ connman_network_set_associating(network, false);
- network->connecting = FALSE;
+ network->connecting = false;
ipconfig_ipv6 = __connman_service_get_ip6config(service);
err = __connman_ipconfig_address_add(ipconfig_ipv6);
@@ -385,7 +402,7 @@ err:
static void autoconf_ipv6_set(struct connman_network *network);
static void dhcpv6_callback(struct connman_network *network,
- connman_bool_t success);
+ enum __connman_dhcpv6_status status, gpointer data);
/*
* Have a separate callback for renew so that we do not do autoconf
@@ -393,25 +410,30 @@ static void dhcpv6_callback(struct connman_network *network,
* DHCPv6 solicitation.
*/
static void dhcpv6_renew_callback(struct connman_network *network,
- connman_bool_t success)
+ enum __connman_dhcpv6_status status,
+ gpointer data)
{
- if (success == TRUE)
- dhcpv6_callback(network, success);
- else {
+ switch (status) {
+ case CONNMAN_DHCPV6_STATUS_SUCCEED:
+ dhcpv6_callback(network, status, data);
+ break;
+ case CONNMAN_DHCPV6_STATUS_FAIL:
+ case CONNMAN_DHCPV6_STATUS_RESTART:
stop_dhcpv6(network);
/* restart and do solicit again. */
autoconf_ipv6_set(network);
+ break;
}
}
static void dhcpv6_callback(struct connman_network *network,
- connman_bool_t success)
+ enum __connman_dhcpv6_status status, gpointer data)
{
- DBG("success %d", success);
+ DBG("status %d", status);
/* Start the renew process if necessary */
- if (success == TRUE) {
+ if (status == CONNMAN_DHCPV6_STATUS_SUCCEED) {
if (dhcpv6_set_addresses(network) < 0) {
stop_dhcpv6(network);
@@ -420,7 +442,13 @@ static void dhcpv6_callback(struct connman_network *network,
if (__connman_dhcpv6_start_renew(network,
dhcpv6_renew_callback) == -ETIMEDOUT)
- dhcpv6_renew_callback(network, FALSE);
+ dhcpv6_renew_callback(network,
+ CONNMAN_DHCPV6_STATUS_FAIL,
+ data);
+
+ } else if (status == CONNMAN_DHCPV6_STATUS_RESTART) {
+ stop_dhcpv6(network);
+ autoconf_ipv6_set(network);
} else
stop_dhcpv6(network);
}
@@ -433,7 +461,7 @@ static void check_dhcpv6(struct nd_router_advert *reply,
DBG("reply %p", reply);
- if (reply == NULL) {
+ if (!reply) {
/*
* Router solicitation message seem to get lost easily so
* try to send it again.
@@ -456,7 +484,7 @@ static void check_dhcpv6(struct nd_router_advert *reply,
* If we were disconnected while waiting router advertisement,
* we just quit and do not start DHCPv6
*/
- if (network->connected == FALSE) {
+ if (!network->connected) {
connman_network_unref(network);
return;
}
@@ -481,7 +509,7 @@ static void receive_refresh_rs_reply(struct nd_router_advert *reply,
DBG("reply %p", reply);
- if (reply == NULL) {
+ if (!reply) {
/*
* Router solicitation message seem to get lost easily so
* try to send it again.
@@ -505,7 +533,8 @@ static void receive_refresh_rs_reply(struct nd_router_advert *reply,
return;
}
-int __connman_refresh_rs_ipv6(struct connman_network *network, int index)
+int __connman_network_refresh_rs_ipv6(struct connman_network *network,
+ int index)
{
int ret = 0;
@@ -546,16 +575,16 @@ static void autoconf_ipv6_set(struct connman_network *network)
__connman_device_set_network(network->device, network);
- connman_device_set_disconnected(network->device, FALSE);
+ connman_device_set_disconnected(network->device, false);
- network->connecting = FALSE;
+ network->connecting = false;
service = connman_service_lookup_from_network(network);
- if (service == NULL)
+ if (!service)
return;
ipconfig = __connman_service_get_ip6config(service);
- if (ipconfig == NULL)
+ if (!ipconfig)
return;
index = __connman_ipconfig_get_index(ipconfig);
@@ -574,10 +603,10 @@ static void set_connected(struct connman_network *network)
struct connman_service *service;
int ret;
- if (network->connected == TRUE)
+ if (network->connected)
return;
- network->connected = TRUE;
+ network->connected = true;
service = connman_service_lookup_from_network(network);
@@ -634,9 +663,9 @@ static void set_connected(struct connman_network *network)
}
}
- network->connecting = FALSE;
+ network->connecting = false;
- connman_network_set_associating(network, FALSE);
+ connman_network_set_associating(network, false);
}
static void set_disconnected(struct connman_network *network)
@@ -646,11 +675,6 @@ static void set_disconnected(struct connman_network *network)
enum connman_service_state state;
struct connman_service *service;
- if (network->connected == FALSE)
- return;
-
- network->connected = FALSE;
-
service = connman_service_lookup_from_network(network);
ipconfig_ipv4 = __connman_service_get_ip4config(service);
@@ -672,28 +696,30 @@ static void set_disconnected(struct connman_network *network)
__connman_device_set_network(network->device, NULL);
- switch (ipv6_method) {
- case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
- case CONNMAN_IPCONFIG_METHOD_OFF:
- case CONNMAN_IPCONFIG_METHOD_FIXED:
- case CONNMAN_IPCONFIG_METHOD_MANUAL:
- break;
- case CONNMAN_IPCONFIG_METHOD_DHCP:
- case CONNMAN_IPCONFIG_METHOD_AUTO:
- release_dhcpv6(network);
- break;
- }
+ if (network->connected) {
+ switch (ipv6_method) {
+ case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
+ case CONNMAN_IPCONFIG_METHOD_OFF:
+ case CONNMAN_IPCONFIG_METHOD_FIXED:
+ case CONNMAN_IPCONFIG_METHOD_MANUAL:
+ break;
+ case CONNMAN_IPCONFIG_METHOD_DHCP:
+ case CONNMAN_IPCONFIG_METHOD_AUTO:
+ release_dhcpv6(network);
+ break;
+ }
- switch (ipv4_method) {
- case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
- case CONNMAN_IPCONFIG_METHOD_OFF:
- case CONNMAN_IPCONFIG_METHOD_AUTO:
- case CONNMAN_IPCONFIG_METHOD_FIXED:
- case CONNMAN_IPCONFIG_METHOD_MANUAL:
- break;
- case CONNMAN_IPCONFIG_METHOD_DHCP:
- __connman_dhcp_stop(network);
- break;
+ switch (ipv4_method) {
+ case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
+ case CONNMAN_IPCONFIG_METHOD_OFF:
+ case CONNMAN_IPCONFIG_METHOD_AUTO:
+ case CONNMAN_IPCONFIG_METHOD_FIXED:
+ case CONNMAN_IPCONFIG_METHOD_MANUAL:
+ break;
+ case CONNMAN_IPCONFIG_METHOD_DHCP:
+ __connman_dhcp_stop(network);
+ break;
+ }
}
/*
@@ -717,21 +743,23 @@ static void set_disconnected(struct connman_network *network)
CONNMAN_SERVICE_STATE_DISCONNECT,
CONNMAN_IPCONFIG_TYPE_IPV6);
- __connman_connection_gateway_remove(service,
- CONNMAN_IPCONFIG_TYPE_ALL);
+ if (network->connected) {
+ __connman_connection_gateway_remove(service,
+ CONNMAN_IPCONFIG_TYPE_ALL);
- __connman_ipconfig_address_unset(ipconfig_ipv4);
- __connman_ipconfig_address_unset(ipconfig_ipv6);
+ __connman_ipconfig_address_unset(ipconfig_ipv4);
+ __connman_ipconfig_address_unset(ipconfig_ipv6);
- /*
- * Special handling for IPv6 autoconfigured address.
- * The simplest way to remove autoconfigured routes is to
- * disable IPv6 temporarily so that kernel will do the cleanup
- * automagically.
- */
- if (ipv6_method == CONNMAN_IPCONFIG_METHOD_AUTO) {
- __connman_ipconfig_disable_ipv6(ipconfig_ipv6);
- __connman_ipconfig_enable_ipv6(ipconfig_ipv6);
+ /*
+ * Special handling for IPv6 autoconfigured address.
+ * The simplest way to remove autoconfigured routes is to
+ * disable IPv6 temporarily so that kernel will do the cleanup
+ * automagically.
+ */
+ if (ipv6_method == CONNMAN_IPCONFIG_METHOD_AUTO) {
+ __connman_ipconfig_disable_ipv6(ipconfig_ipv6);
+ __connman_ipconfig_enable_ipv6(ipconfig_ipv6);
+ }
}
__connman_service_ipconfig_indicate_state(service,
@@ -742,9 +770,10 @@ static void set_disconnected(struct connman_network *network)
CONNMAN_SERVICE_STATE_IDLE,
CONNMAN_IPCONFIG_TYPE_IPV6);
- network->connecting = FALSE;
+ network->connecting = false;
+ network->connected = false;
- connman_network_set_associating(network, FALSE);
+ connman_network_set_associating(network, false);
}
@@ -756,13 +785,13 @@ static int network_probe(struct connman_network *network)
DBG("network %p name %s", network, network->name);
- if (network->driver != NULL)
+ if (network->driver)
return -EALREADY;
for (list = driver_list; list; list = list->next) {
driver = list->data;
- if (match_driver(network, driver) == FALSE) {
+ if (!match_driver(network, driver)) {
driver = NULL;
continue;
}
@@ -775,10 +804,10 @@ static int network_probe(struct connman_network *network)
driver = NULL;
}
- if (driver == NULL)
+ if (!driver)
return -ENODEV;
- if (network->group == NULL)
+ if (!network->group)
return -EINVAL;
switch (network->type) {
@@ -786,12 +815,13 @@ static int network_probe(struct connman_network *network)
case CONNMAN_NETWORK_TYPE_VENDOR:
return 0;
case CONNMAN_NETWORK_TYPE_ETHERNET:
+ case CONNMAN_NETWORK_TYPE_GADGET:
case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
case CONNMAN_NETWORK_TYPE_CELLULAR:
case CONNMAN_NETWORK_TYPE_WIFI:
network->driver = driver;
- if (__connman_service_create_from_network(network) == NULL) {
+ if (!__connman_service_create_from_network(network)) {
network->driver = NULL;
return -EINVAL;
}
@@ -804,10 +834,10 @@ static void network_remove(struct connman_network *network)
{
DBG("network %p name %s", network, network->name);
- if (network->driver == NULL)
+ if (!network->driver)
return;
- if (network->connected == TRUE)
+ if (network->connected)
set_disconnected(network);
switch (network->type) {
@@ -815,11 +845,12 @@ static void network_remove(struct connman_network *network)
case CONNMAN_NETWORK_TYPE_VENDOR:
break;
case CONNMAN_NETWORK_TYPE_ETHERNET:
+ case CONNMAN_NETWORK_TYPE_GADGET:
case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
case CONNMAN_NETWORK_TYPE_CELLULAR:
case CONNMAN_NETWORK_TYPE_WIFI:
- if (network->group != NULL) {
+ if (network->group) {
__connman_service_remove_from_network(network);
g_free(network->group);
@@ -838,17 +869,17 @@ static void network_change(struct connman_network *network)
{
DBG("network %p name %s", network, network->name);
- if (network->connected == FALSE)
+ if (!network->connected)
return;
- connman_device_set_disconnected(network->device, TRUE);
+ connman_device_set_disconnected(network->device, true);
if (network->driver && network->driver->disconnect) {
network->driver->disconnect(network);
return;
}
- network->connected = FALSE;
+ network->connected = false;
}
static void probe_driver(struct connman_network_driver *driver)
@@ -857,10 +888,10 @@ static void probe_driver(struct connman_network_driver *driver)
DBG("driver %p name %s", driver, driver->name);
- for (list = network_list; list != NULL; list = list->next) {
+ for (list = network_list; list; list = list->next) {
struct connman_network *network = list->data;
- if (network->driver != NULL)
+ if (network->driver)
continue;
if (driver->type != network->type)
@@ -879,7 +910,7 @@ static void remove_driver(struct connman_network_driver *driver)
DBG("driver %p name %s", driver, driver->name);
- for (list = network_list; list != NULL; list = list->next) {
+ for (list = network_list; list; list = list->next) {
struct connman_network *network = list->data;
if (network->driver == driver)
@@ -938,7 +969,6 @@ static void network_destruct(struct connman_network *network)
g_free(network->wifi.mode);
g_free(network->wifi.security);
g_free(network->wifi.passphrase);
- g_free(network->wifi.agent_passphrase);
g_free(network->wifi.eap);
g_free(network->wifi.identity);
g_free(network->wifi.agent_identity);
@@ -977,7 +1007,7 @@ struct connman_network *connman_network_create(const char *identifier,
DBG("identifier %s type %d", identifier, type);
network = g_try_new0(struct connman_network, 1);
- if (network == NULL)
+ if (!network)
return NULL;
DBG("network %p", network);
@@ -986,7 +1016,7 @@ struct connman_network *connman_network_create(const char *identifier,
ident = g_strdup(identifier);
- if (ident == NULL) {
+ if (!ident) {
g_free(network);
return NULL;
}
@@ -1048,7 +1078,8 @@ const char *__connman_network_get_type(struct connman_network *network)
*
* Get type of network
*/
-enum connman_network_type connman_network_get_type(struct connman_network *network)
+enum connman_network_type connman_network_get_type(
+ struct connman_network *network)
{
return network->type;
}
@@ -1077,11 +1108,11 @@ void connman_network_set_index(struct connman_network *network, int index)
struct connman_ipconfig *ipconfig;
service = connman_service_lookup_from_network(network);
- if (service == NULL)
+ if (!service)
goto done;
ipconfig = __connman_service_get_ip4config(service);
- if (ipconfig == NULL)
+ if (!ipconfig)
goto done;
/* If index changed, the index of ipconfig must be reset. */
@@ -1119,6 +1150,7 @@ void connman_network_set_group(struct connman_network *network,
case CONNMAN_NETWORK_TYPE_VENDOR:
return;
case CONNMAN_NETWORK_TYPE_ETHERNET:
+ case CONNMAN_NETWORK_TYPE_GADGET:
case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
case CONNMAN_NETWORK_TYPE_CELLULAR:
@@ -1127,12 +1159,12 @@ void connman_network_set_group(struct connman_network *network,
}
if (g_strcmp0(network->group, group) == 0) {
- if (group != NULL)
+ if (group)
__connman_service_update_from_network(network);
return;
}
- if (network->group != NULL) {
+ if (network->group) {
__connman_service_remove_from_network(network);
g_free(network->group);
@@ -1140,7 +1172,7 @@ void connman_network_set_group(struct connman_network *network,
network->group = g_strdup(group);
- if (network->group != NULL)
+ if (network->group)
network_probe(network);
}
@@ -1157,34 +1189,33 @@ const char *connman_network_get_group(struct connman_network *network)
const char *__connman_network_get_ident(struct connman_network *network)
{
- if (network->device == NULL)
+ if (!network->device)
return NULL;
return connman_device_get_ident(network->device);
}
-connman_bool_t __connman_network_get_weakness(struct connman_network *network)
+bool __connman_network_get_weakness(struct connman_network *network)
{
switch (network->type) {
case CONNMAN_NETWORK_TYPE_UNKNOWN:
case CONNMAN_NETWORK_TYPE_VENDOR:
case CONNMAN_NETWORK_TYPE_ETHERNET:
+ case CONNMAN_NETWORK_TYPE_GADGET:
case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
case CONNMAN_NETWORK_TYPE_CELLULAR:
break;
case CONNMAN_NETWORK_TYPE_WIFI:
- if (g_strcmp0(network->wifi.mode, "adhoc") == 0)
- return TRUE;
if (network->strength > 0 && network->strength < 20)
- return TRUE;
+ return true;
break;
}
- return FALSE;
+ return false;
}
-connman_bool_t connman_network_get_connecting(struct connman_network *network)
+bool connman_network_get_connecting(struct connman_network *network)
{
return network->connecting;
}
@@ -1197,7 +1228,7 @@ connman_bool_t connman_network_get_connecting(struct connman_network *network)
* Change availability state of network (in range)
*/
int connman_network_set_available(struct connman_network *network,
- connman_bool_t available)
+ bool available)
{
DBG("network %p available %d", network, available);
@@ -1215,7 +1246,7 @@ int connman_network_set_available(struct connman_network *network,
*
* Get network available setting
*/
-connman_bool_t connman_network_get_available(struct connman_network *network)
+bool connman_network_get_available(struct connman_network *network)
{
return network->available;
}
@@ -1228,7 +1259,7 @@ connman_bool_t connman_network_get_available(struct connman_network *network)
* Change associating state of network
*/
int connman_network_set_associating(struct connman_network *network,
- connman_bool_t associating)
+ bool associating)
{
DBG("network %p associating %d", network, associating);
@@ -1237,7 +1268,7 @@ int connman_network_set_associating(struct connman_network *network,
network->associating = associating;
- if (associating == TRUE) {
+ if (associating) {
struct connman_service *service;
service = connman_service_lookup_from_network(network);
@@ -1299,11 +1330,11 @@ void connman_network_set_ipv4_method(struct connman_network *network,
struct connman_ipconfig *ipconfig;
service = connman_service_lookup_from_network(network);
- if (service == NULL)
+ if (!service)
return;
ipconfig = __connman_service_get_ip4config(service);
- if (ipconfig == NULL)
+ if (!ipconfig)
return;
__connman_ipconfig_set_method(ipconfig, method);
@@ -1316,11 +1347,11 @@ void connman_network_set_ipv6_method(struct connman_network *network,
struct connman_ipconfig *ipconfig;
service = connman_service_lookup_from_network(network);
- if (service == NULL)
+ if (!service)
return;
ipconfig = __connman_service_get_ip6config(service);
- if (ipconfig == NULL)
+ if (!ipconfig)
return;
__connman_ipconfig_set_method(ipconfig, method);
@@ -1331,8 +1362,8 @@ void connman_network_set_error(struct connman_network *network,
{
DBG("network %p error %d", network, error);
- network->connecting = FALSE;
- network->associating = FALSE;
+ network->connecting = false;
+ network->associating = false;
switch (error) {
case CONNMAN_NETWORK_ERROR_UNKNOWN:
@@ -1360,10 +1391,10 @@ void connman_network_clear_error(struct connman_network *network)
DBG("network %p", network);
- if (network == NULL)
+ if (!network)
return;
- if (network->connecting == TRUE || network->associating == TRUE)
+ if (network->connecting || network->associating)
return;
service = connman_service_lookup_from_network(network);
@@ -1378,14 +1409,14 @@ void connman_network_clear_error(struct connman_network *network)
* Change connected state of network
*/
int connman_network_set_connected(struct connman_network *network,
- connman_bool_t connected)
+ bool connected)
{
DBG("network %p connected %d/%d connecting %d associating %d",
network, network->connected, connected, network->connecting,
network->associating);
- if ((network->connecting == TRUE || network->associating == TRUE) &&
- connected == FALSE) {
+ if ((network->connecting || network->associating) &&
+ !connected) {
connman_network_set_error(network,
CONNMAN_NETWORK_ERROR_CONNECT_FAIL);
if (__connman_network_disconnect(network) == 0)
@@ -1395,7 +1426,7 @@ int connman_network_set_connected(struct connman_network *network,
if (network->connected == connected)
return -EALREADY;
- if (connected == FALSE)
+ if (!connected)
set_disconnected(network);
else
set_connected(network);
@@ -1409,7 +1440,7 @@ int connman_network_set_connected(struct connman_network *network,
*
* Get network connection status
*/
-connman_bool_t connman_network_get_connected(struct connman_network *network)
+bool connman_network_get_connected(struct connman_network *network)
{
return network->connected;
}
@@ -1420,14 +1451,14 @@ connman_bool_t connman_network_get_connected(struct connman_network *network)
*
* Get network associating status
*/
-connman_bool_t connman_network_get_associating(struct connman_network *network)
+bool connman_network_get_associating(struct connman_network *network)
{
return network->associating;
}
void connman_network_clear_hidden(void *user_data)
{
- if (user_data == NULL)
+ if (!user_data)
return;
DBG("user_data %p", user_data);
@@ -1442,7 +1473,7 @@ void connman_network_clear_hidden(void *user_data)
}
int connman_network_connect_hidden(struct connman_network *network,
- char *identity, char* passphrase, void *user_data)
+ char *identity, char *passphrase, void *user_data)
{
int err = 0;
struct connman_service *service;
@@ -1451,15 +1482,13 @@ int connman_network_connect_hidden(struct connman_network *network,
DBG("network %p service %p user_data %p", network, service, user_data);
- if (service == NULL) {
- err = -EINVAL;
- goto out;
- }
+ if (!service)
+ return -EINVAL;
- if (identity != NULL)
+ if (identity)
__connman_service_set_agent_identity(service, identity);
- if (passphrase != NULL)
+ if (passphrase)
err = __connman_service_add_passphrase(service, passphrase);
if (err == -ENOKEY) {
@@ -1468,9 +1497,9 @@ int connman_network_connect_hidden(struct connman_network *network,
goto out;
} else {
__connman_service_set_hidden(service);
- __connman_service_set_userconnect(service, TRUE);
__connman_service_set_hidden_data(service, user_data);
- return __connman_service_connect(service);
+ return __connman_service_connect(service,
+ CONNMAN_SERVICE_CONNECT_REASON_USER);
}
out:
@@ -1490,32 +1519,31 @@ int __connman_network_connect(struct connman_network *network)
DBG("network %p", network);
- if (network->connected == TRUE)
+ if (network->connected)
return -EISCONN;
- if (network->connecting == TRUE || network->associating == TRUE)
+ if (network->connecting || network->associating)
return -EALREADY;
- if (network->driver == NULL)
+ if (!network->driver)
return -EUNATCH;
- if (network->driver->connect == NULL)
+ if (!network->driver->connect)
return -ENOSYS;
- if (network->device == NULL)
+ if (!network->device)
return -ENODEV;
- network->connecting = TRUE;
+ network->connecting = true;
__connman_device_disconnect(network->device);
err = network->driver->connect(network);
if (err < 0) {
if (err == -EINPROGRESS)
- connman_network_set_associating(network, TRUE);
- else {
- network->connecting = FALSE;
- }
+ connman_network_set_associating(network, true);
+ else
+ network->connecting = false;
return err;
}
@@ -1533,24 +1561,23 @@ int __connman_network_connect(struct connman_network *network)
*/
int __connman_network_disconnect(struct connman_network *network)
{
- int err;
+ int err = 0;
DBG("network %p", network);
- if (network->connected == FALSE && network->connecting == FALSE &&
- network->associating == FALSE)
+ if (!network->connected && !network->connecting &&
+ !network->associating)
return -ENOTCONN;
- if (network->driver == NULL)
+ if (!network->driver)
return -EUNATCH;
- if (network->driver->disconnect == NULL)
- return -ENOSYS;
+ network->connecting = false;
- network->connecting = FALSE;
+ if (network->driver->disconnect)
+ err = network->driver->disconnect(network);
- err = network->driver->disconnect(network);
- if (err == 0)
+ if (err != -EINPROGRESS)
set_disconnected(network);
return err;
@@ -1563,7 +1590,7 @@ static int manual_ipv4_set(struct connman_network *network,
int err;
service = connman_service_lookup_from_network(network);
- if (service == NULL)
+ if (!service)
return -EINVAL;
err = __connman_ipconfig_address_add(ipconfig);
@@ -1584,7 +1611,7 @@ int __connman_network_clear_ipconfig(struct connman_network *network,
enum connman_ipconfig_type type;
service = connman_service_lookup_from_network(network);
- if (service == NULL)
+ if (!service)
return -EINVAL;
method = __connman_ipconfig_get_method(ipconfig);
@@ -1625,7 +1652,7 @@ int __connman_network_set_ipconfig(struct connman_network *network,
enum connman_ipconfig_method method;
int ret;
- if (network == NULL)
+ if (!network)
return -EINVAL;
if (ipconfig_ipv6) {
@@ -1680,11 +1707,11 @@ int connman_network_set_ipaddress(struct connman_network *network,
DBG("network %p", network);
service = connman_service_lookup_from_network(network);
- if (service == NULL)
+ if (!service)
return -EINVAL;
ipconfig = __connman_service_get_ipconfig(service, ipaddress->family);
- if (ipconfig == NULL)
+ if (!ipconfig)
return -EINVAL;
__connman_ipconfig_set_local(ipconfig, ipaddress->local);
@@ -1706,19 +1733,19 @@ int connman_network_set_nameservers(struct connman_network *network,
DBG("network %p nameservers %s", network, nameservers);
service = connman_service_lookup_from_network(network);
- if (service == NULL)
+ if (!service)
return -EINVAL;
__connman_service_nameserver_clear(service);
- if (nameservers == NULL)
+ if (!nameservers)
return 0;
nameservers_array = g_strsplit(nameservers, " ", 0);
- for (i = 0; nameservers_array[i] != NULL; i++) {
+ for (i = 0; nameservers_array[i]; i++) {
__connman_service_nameserver_append(service,
- nameservers_array[i], FALSE);
+ nameservers_array[i], false);
}
g_strfreev(nameservers_array);
@@ -1734,7 +1761,7 @@ int connman_network_set_domain(struct connman_network *network,
DBG("network %p domain %s", network, domain);
service = connman_service_lookup_from_network(network);
- if (service == NULL)
+ if (!service)
return -EINVAL;
__connman_service_set_domainname(service, domain);
@@ -1829,49 +1856,46 @@ int connman_network_set_string(struct connman_network *network,
if (g_strcmp0(key, "Name") == 0)
return connman_network_set_name(network, value);
- if (g_str_equal(key, "Path") == TRUE) {
+ if (g_str_equal(key, "Path")) {
g_free(network->path);
network->path = g_strdup(value);
- } else if (g_str_equal(key, "Node") == TRUE) {
+ } else if (g_str_equal(key, "Node")) {
g_free(network->node);
network->node = g_strdup(value);
- } else if (g_str_equal(key, "WiFi.Mode") == TRUE) {
+ } else if (g_str_equal(key, "WiFi.Mode")) {
g_free(network->wifi.mode);
network->wifi.mode = g_strdup(value);
- } else if (g_str_equal(key, "WiFi.Security") == TRUE) {
+ } else if (g_str_equal(key, "WiFi.Security")) {
g_free(network->wifi.security);
network->wifi.security = g_strdup(value);
- } else if (g_str_equal(key, "WiFi.Passphrase") == TRUE) {
+ } else if (g_str_equal(key, "WiFi.Passphrase")) {
g_free(network->wifi.passphrase);
network->wifi.passphrase = g_strdup(value);
- } else if (g_str_equal(key, "WiFi.AgentPassphrase") == TRUE) {
- g_free(network->wifi.agent_passphrase);
- network->wifi.agent_passphrase = g_strdup(value);
- } else if (g_str_equal(key, "WiFi.EAP") == TRUE) {
+ } else if (g_str_equal(key, "WiFi.EAP")) {
g_free(network->wifi.eap);
network->wifi.eap = g_strdup(value);
- } else if (g_str_equal(key, "WiFi.Identity") == TRUE) {
+ } else if (g_str_equal(key, "WiFi.Identity")) {
g_free(network->wifi.identity);
network->wifi.identity = g_strdup(value);
- } else if (g_str_equal(key, "WiFi.AgentIdentity") == TRUE) {
+ } else if (g_str_equal(key, "WiFi.AgentIdentity")) {
g_free(network->wifi.agent_identity);
network->wifi.agent_identity = g_strdup(value);
- } else if (g_str_equal(key, "WiFi.CACertFile") == TRUE) {
+ } else if (g_str_equal(key, "WiFi.CACertFile")) {
g_free(network->wifi.ca_cert_path);
network->wifi.ca_cert_path = g_strdup(value);
- } else if (g_str_equal(key, "WiFi.ClientCertFile") == TRUE) {
+ } else if (g_str_equal(key, "WiFi.ClientCertFile")) {
g_free(network->wifi.client_cert_path);
network->wifi.client_cert_path = g_strdup(value);
- } else if (g_str_equal(key, "WiFi.PrivateKeyFile") == TRUE) {
+ } else if (g_str_equal(key, "WiFi.PrivateKeyFile")) {
g_free(network->wifi.private_key_path);
network->wifi.private_key_path = g_strdup(value);
- } else if (g_str_equal(key, "WiFi.PrivateKeyPassphrase") == TRUE) {
+ } else if (g_str_equal(key, "WiFi.PrivateKeyPassphrase")) {
g_free(network->wifi.private_key_passphrase);
network->wifi.private_key_passphrase = g_strdup(value);
- } else if (g_str_equal(key, "WiFi.Phase2") == TRUE) {
+ } else if (g_str_equal(key, "WiFi.Phase2")) {
g_free(network->wifi.phase2_auth);
network->wifi.phase2_auth = g_strdup(value);
- } else if (g_str_equal(key, "WiFi.PinWPS") == TRUE) {
+ } else if (g_str_equal(key, "WiFi.PinWPS")) {
g_free(network->wifi.pin_wps);
network->wifi.pin_wps = g_strdup(value);
} else {
@@ -1893,37 +1917,35 @@ const char *connman_network_get_string(struct connman_network *network,
{
DBG("network %p key %s", network, key);
- if (g_str_equal(key, "Path") == TRUE)
+ if (g_str_equal(key, "Path"))
return network->path;
- else if (g_str_equal(key, "Name") == TRUE)
+ else if (g_str_equal(key, "Name"))
return network->name;
- else if (g_str_equal(key, "Node") == TRUE)
+ else if (g_str_equal(key, "Node"))
return network->node;
- else if (g_str_equal(key, "WiFi.Mode") == TRUE)
+ else if (g_str_equal(key, "WiFi.Mode"))
return network->wifi.mode;
- else if (g_str_equal(key, "WiFi.Security") == TRUE)
+ else if (g_str_equal(key, "WiFi.Security"))
return network->wifi.security;
- else if (g_str_equal(key, "WiFi.Passphrase") == TRUE)
+ else if (g_str_equal(key, "WiFi.Passphrase"))
return network->wifi.passphrase;
- else if (g_str_equal(key, "WiFi.AgentPassphrase") == TRUE)
- return network->wifi.agent_passphrase;
- else if (g_str_equal(key, "WiFi.EAP") == TRUE)
+ else if (g_str_equal(key, "WiFi.EAP"))
return network->wifi.eap;
- else if (g_str_equal(key, "WiFi.Identity") == TRUE)
+ else if (g_str_equal(key, "WiFi.Identity"))
return network->wifi.identity;
- else if (g_str_equal(key, "WiFi.AgentIdentity") == TRUE)
+ else if (g_str_equal(key, "WiFi.AgentIdentity"))
return network->wifi.agent_identity;
- else if (g_str_equal(key, "WiFi.CACertFile") == TRUE)
+ else if (g_str_equal(key, "WiFi.CACertFile"))
return network->wifi.ca_cert_path;
- else if (g_str_equal(key, "WiFi.ClientCertFile") == TRUE)
+ else if (g_str_equal(key, "WiFi.ClientCertFile"))
return network->wifi.client_cert_path;
- else if (g_str_equal(key, "WiFi.PrivateKeyFile") == TRUE)
+ else if (g_str_equal(key, "WiFi.PrivateKeyFile"))
return network->wifi.private_key_path;
- else if (g_str_equal(key, "WiFi.PrivateKeyPassphrase") == TRUE)
+ else if (g_str_equal(key, "WiFi.PrivateKeyPassphrase"))
return network->wifi.private_key_passphrase;
- else if (g_str_equal(key, "WiFi.Phase2") == TRUE)
+ else if (g_str_equal(key, "WiFi.Phase2"))
return network->wifi.phase2_auth;
- else if (g_str_equal(key, "WiFi.PinWPS") == TRUE)
+ else if (g_str_equal(key, "WiFi.PinWPS"))
return network->wifi.pin_wps;
return NULL;
@@ -1938,7 +1960,7 @@ const char *connman_network_get_string(struct connman_network *network,
* Set boolean value for specific key
*/
int connman_network_set_bool(struct connman_network *network,
- const char *key, connman_bool_t value)
+ const char *key, bool value)
{
DBG("network %p key %s value %d", network, key, value);
@@ -1959,19 +1981,19 @@ int connman_network_set_bool(struct connman_network *network,
*
* Get boolean value for specific key
*/
-connman_bool_t connman_network_get_bool(struct connman_network *network,
+bool connman_network_get_bool(struct connman_network *network,
const char *key)
{
DBG("network %p key %s", network, key);
- if (g_str_equal(key, "Roaming") == TRUE)
+ if (g_str_equal(key, "Roaming"))
return network->roaming;
- else if (g_str_equal(key, "WiFi.WPS") == TRUE)
+ else if (g_str_equal(key, "WiFi.WPS"))
return network->wifi.wps;
- else if (g_str_equal(key, "WiFi.UseWPS") == TRUE)
+ else if (g_str_equal(key, "WiFi.UseWPS"))
return network->wifi.use_wps;
- return FALSE;
+ return false;
}
/**
@@ -1988,10 +2010,10 @@ int connman_network_set_blob(struct connman_network *network,
{
DBG("network %p key %s size %d", network, key, size);
- if (g_str_equal(key, "WiFi.SSID") == TRUE) {
+ if (g_str_equal(key, "WiFi.SSID")) {
g_free(network->wifi.ssid);
network->wifi.ssid = g_try_malloc(size);
- if (network->wifi.ssid != NULL) {
+ if (network->wifi.ssid) {
memcpy(network->wifi.ssid, data, size);
network->wifi.ssid_len = size;
} else
@@ -2016,8 +2038,8 @@ const void *connman_network_get_blob(struct connman_network *network,
{
DBG("network %p key %s", network, key);
- if (g_str_equal(key, "WiFi.SSID") == TRUE) {
- if (size != NULL)
+ if (g_str_equal(key, "WiFi.SSID")) {
+ if (size)
*size = network->wifi.ssid_len;
return network->wifi.ssid;
}
@@ -2031,12 +2053,12 @@ void __connman_network_set_device(struct connman_network *network,
if (network->device == device)
return;
- if (network->device != NULL)
+ if (network->device)
network_remove(network);
network->device = device;
- if (network->device != NULL)
+ if (network->device)
network_probe(network);
}
@@ -2081,6 +2103,7 @@ void connman_network_update(struct connman_network *network)
case CONNMAN_NETWORK_TYPE_VENDOR:
return;
case CONNMAN_NETWORK_TYPE_ETHERNET:
+ case CONNMAN_NETWORK_TYPE_GADGET:
case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
case CONNMAN_NETWORK_TYPE_CELLULAR:
@@ -2088,7 +2111,7 @@ void connman_network_update(struct connman_network *network)
break;
}
- if (network->group != NULL)
+ if (network->group)
__connman_service_update_from_network(network);
}
diff --git a/src/notifier.c b/src/notifier.c
index 623b970b..5ba53242 100644
--- a/src/notifier.c
+++ b/src/notifier.c
@@ -2,7 +2,7 @@
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2013 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -73,46 +73,44 @@ void connman_notifier_unregister(struct connman_notifier *notifier)
notifier_list = g_slist_remove(notifier_list, notifier);
}
-#define MAX_TECHNOLOGIES 10
+static int connected[MAX_CONNMAN_SERVICE_TYPES];
+static int online[MAX_CONNMAN_SERVICE_TYPES];
-static int connected[MAX_TECHNOLOGIES];
-static int online[MAX_TECHNOLOGIES];
-
-static connman_bool_t notifier_is_online(void)
+static bool notifier_is_online(void)
{
unsigned int i;
__sync_synchronize();
- for (i = 0; i < MAX_TECHNOLOGIES; i++) {
+ for (i = 0; i < MAX_CONNMAN_SERVICE_TYPES; i++) {
if (online[i] > 0)
- return TRUE;
+ return true;
}
- return FALSE;
+ return false;
}
-connman_bool_t __connman_notifier_is_connected(void)
+bool __connman_notifier_is_connected(void)
{
unsigned int i;
__sync_synchronize();
- for (i = 0; i < MAX_TECHNOLOGIES; i++) {
+ for (i = 0; i < MAX_CONNMAN_SERVICE_TYPES; i++) {
if (connected[i] > 0)
- return TRUE;
+ return true;
}
- return FALSE;
+ return false;
}
static const char *evaluate_notifier_state(void)
{
- if (notifier_is_online() == TRUE)
+ if (notifier_is_online())
return "online";
- if (__connman_notifier_is_connected() == TRUE)
+ if (__connman_notifier_is_connected())
return "ready";
- if ( __connman_technology_get_offlinemode() == TRUE)
+ if (__connman_technology_get_offlinemode())
return "offline";
return "idle";
@@ -148,17 +146,18 @@ void __connman_notifier_connect(enum connman_service_type type)
case CONNMAN_SERVICE_TYPE_SYSTEM:
case CONNMAN_SERVICE_TYPE_GPS:
case CONNMAN_SERVICE_TYPE_VPN:
- case CONNMAN_SERVICE_TYPE_GADGET:
return;
case CONNMAN_SERVICE_TYPE_ETHERNET:
+ case CONNMAN_SERVICE_TYPE_GADGET:
case CONNMAN_SERVICE_TYPE_WIFI:
case CONNMAN_SERVICE_TYPE_BLUETOOTH:
case CONNMAN_SERVICE_TYPE_CELLULAR:
+ case CONNMAN_SERVICE_TYPE_P2P:
break;
}
if (__sync_fetch_and_add(&connected[type], 1) == 0) {
- __connman_technology_set_connected(type, TRUE);
+ __connman_technology_set_connected(type, true);
state_changed();
}
}
@@ -194,19 +193,20 @@ void __connman_notifier_disconnect(enum connman_service_type type)
case CONNMAN_SERVICE_TYPE_SYSTEM:
case CONNMAN_SERVICE_TYPE_GPS:
case CONNMAN_SERVICE_TYPE_VPN:
- case CONNMAN_SERVICE_TYPE_GADGET:
return;
case CONNMAN_SERVICE_TYPE_ETHERNET:
+ case CONNMAN_SERVICE_TYPE_GADGET:
case CONNMAN_SERVICE_TYPE_WIFI:
case CONNMAN_SERVICE_TYPE_BLUETOOTH:
case CONNMAN_SERVICE_TYPE_CELLULAR:
+ case CONNMAN_SERVICE_TYPE_P2P:
break;
}
if (__sync_fetch_and_sub(&connected[type], 1) != 1)
return;
- __connman_technology_set_connected(type, FALSE);
+ __connman_technology_set_connected(type, false);
state_changed();
}
@@ -239,7 +239,7 @@ void __connman_notifier_service_remove(struct connman_service *service)
{
GSList *list;
- if (g_hash_table_lookup(service_hash, service) != NULL) {
+ if (g_hash_table_lookup(service_hash, service)) {
/*
* This is a tempory check for consistency. It can be
* removed when there are no reports for the following
@@ -279,7 +279,7 @@ static void offlinemode_changed(dbus_bool_t enabled)
DBUS_TYPE_BOOLEAN, &enabled);
}
-void __connman_notifier_offlinemode(connman_bool_t enabled)
+void __connman_notifier_offlinemode(bool enabled)
{
GSList *list;
@@ -296,7 +296,7 @@ void __connman_notifier_offlinemode(connman_bool_t enabled)
}
}
-static void notify_idle_state(connman_bool_t idle)
+static void notify_idle_state(bool idle)
{
GSList *list;
@@ -315,7 +315,7 @@ void __connman_notifier_service_state_changed(struct connman_service *service,
{
GSList *list;
unsigned int old_size;
- connman_bool_t found;
+ bool found;
for (list = notifier_list; list; list = list->next) {
struct connman_notifier *notifier = list->data;
@@ -325,31 +325,31 @@ void __connman_notifier_service_state_changed(struct connman_service *service,
}
old_size = g_hash_table_size(service_hash);
- found = g_hash_table_lookup(service_hash, service) != NULL;
+ found = g_hash_table_lookup(service_hash, service);
switch (state) {
case CONNMAN_SERVICE_STATE_UNKNOWN:
case CONNMAN_SERVICE_STATE_FAILURE:
case CONNMAN_SERVICE_STATE_DISCONNECT:
case CONNMAN_SERVICE_STATE_IDLE:
- if (found == FALSE)
+ if (!found)
break;
g_hash_table_remove(service_hash, service);
if (old_size == 1)
- notify_idle_state(TRUE);
+ notify_idle_state(true);
break;
case CONNMAN_SERVICE_STATE_ASSOCIATION:
case CONNMAN_SERVICE_STATE_CONFIGURATION:
case CONNMAN_SERVICE_STATE_READY:
case CONNMAN_SERVICE_STATE_ONLINE:
- if (found == TRUE)
+ if (found)
break;
g_hash_table_insert(service_hash, service, service);
if (old_size == 0)
- notify_idle_state(FALSE);
+ notify_idle_state(false);
break;
}
diff --git a/src/ntp.c b/src/ntp.c
index b588c99c..b4fe63aa 100644
--- a/src/ntp.c
+++ b/src/ntp.c
@@ -2,7 +2,7 @@
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2014 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -93,6 +93,9 @@ struct ntp_msg {
#define NTP_FLAG_MD_CONTROL 6
#define NTP_FLAG_MD_PRIVATE 7
+#define NTP_FLAG_VN_VER3 3
+#define NTP_FLAG_VN_VER4 4
+
#define NTP_FLAGS_ENCODE(li, vn, md) ((uint8_t)( \
(((li) & NTP_FLAG_LI_MASK) << NTP_FLAG_LI_SHIFT) | \
(((vn) & NTP_FLAG_VN_MASK) << NTP_FLAG_VN_SHIFT) | \
@@ -114,15 +117,16 @@ static struct timespec mtx_time;
static int transmit_fd = 0;
static char *timeserver = NULL;
+static struct sockaddr_in timeserver_addr;
static gint poll_id = 0;
static gint timeout_id = 0;
static guint retries = 0;
-static void send_packet(int fd, const char *server);
+static void send_packet(int fd, const char *server, uint32_t timeout);
static void next_server(void)
{
- if (timeserver != NULL) {
+ if (timeserver) {
g_free(timeserver);
timeserver = NULL;
}
@@ -132,17 +136,19 @@ static void next_server(void)
static gboolean send_timeout(gpointer user_data)
{
- DBG("send timeout (retries %d)", retries);
+ uint32_t timeout = GPOINTER_TO_UINT(user_data);
+
+ DBG("send timeout %u (retries %d)", timeout, retries);
if (retries++ == NTP_SEND_RETRIES)
next_server();
else
- send_packet(transmit_fd, timeserver);
+ send_packet(transmit_fd, timeserver, timeout << 1);
return FALSE;
}
-static void send_packet(int fd, const char *server)
+static void send_packet(int fd, const char *server, uint32_t timeout)
{
struct ntp_msg msg;
struct sockaddr_in addr;
@@ -156,7 +162,8 @@ static void send_packet(int fd, const char *server)
* msg.precision = (int)log2(ts.tv_sec + (ts.tv_nsec * 1.0e-9));
*/
memset(&msg, 0, sizeof(msg));
- msg.flags = NTP_FLAGS_ENCODE(NTP_FLAG_LI_NOTINSYNC, 4, NTP_FLAG_MD_CLIENT);
+ msg.flags = NTP_FLAGS_ENCODE(NTP_FLAG_LI_NOTINSYNC, NTP_FLAG_VN_VER4,
+ NTP_FLAG_MD_CLIENT);
msg.poll = 4; // min
msg.poll = 10; // max
msg.precision = NTP_PRECISION_S;
@@ -190,28 +197,31 @@ static void send_packet(int fd, const char *server)
}
/*
- * Add a retry timeout of two seconds to retry the existing
+ * Add an exponential retry timeout to retry the existing
* request. After a set number of retries, we'll fallback to
* trying another server.
*/
- timeout_id = g_timeout_add_seconds(NTP_SEND_TIMEOUT, send_timeout, NULL);
+ timeout_id = g_timeout_add_seconds(timeout, send_timeout,
+ GUINT_TO_POINTER(timeout));
}
static gboolean next_poll(gpointer user_data)
{
- if (timeserver == NULL || transmit_fd == 0)
+ if (!timeserver || transmit_fd == 0)
return FALSE;
- send_packet(transmit_fd, timeserver);
+ send_packet(transmit_fd, timeserver, NTP_SEND_TIMEOUT);
return FALSE;
}
static void reset_timeout(void)
{
- if (timeout_id > 0)
+ if (timeout_id > 0) {
g_source_remove(timeout_id);
+ timeout_id = 0;
+ }
retries = 0;
}
@@ -229,7 +239,7 @@ static void decode_msg(void *base, size_t len, struct timeval *tv,
return;
}
- if (tv == NULL) {
+ if (!tv) {
connman_error("Invalid packet timestamp from time server");
return;
}
@@ -246,6 +256,17 @@ static void decode_msg(void *base, size_t len, struct timeval *tv,
msg->rootdisp.seconds, msg->rootdisp.fraction);
DBG("reference : 0x%04x", msg->refid);
+ if (!msg->stratum) {
+ /* RFC 4330 ch 8 Kiss-of-Death packet */
+ uint32_t code = ntohl(msg->refid);
+
+ connman_info("Skipping server %s KoD code %c%c%c%c",
+ timeserver, code >> 24, code >> 16 & 0xff,
+ code >> 8 & 0xff, code & 0xff);
+ next_server();
+ return;
+ }
+
transmit_delay = LOGTOD(msg->poll);
if (NTP_FLAGS_LI_DECODE(msg->flags) == NTP_FLAG_LI_NOTINSYNC) {
@@ -253,9 +274,15 @@ static void decode_msg(void *base, size_t len, struct timeval *tv,
return;
}
- if (NTP_FLAGS_VN_DECODE(msg->flags) != 4) {
- DBG("unsupported version %d", NTP_FLAGS_VN_DECODE(msg->flags));
- return;
+
+ if (NTP_FLAGS_VN_DECODE(msg->flags) != NTP_FLAG_VN_VER4) {
+ if (NTP_FLAGS_VN_DECODE(msg->flags) == NTP_FLAG_VN_VER3) {
+ DBG("requested version %d, accepting version %d",
+ NTP_FLAG_VN_VER4, NTP_FLAGS_VN_DECODE(msg->flags));
+ } else {
+ DBG("unsupported version %d", NTP_FLAGS_VN_DECODE(msg->flags));
+ return;
+ }
}
if (NTP_FLAGS_MD_DECODE(msg->flags) != NTP_FLAG_MD_SERVER) {
@@ -335,6 +362,7 @@ static gboolean received_data(GIOChannel *channel, GIOCondition condition,
gpointer user_data)
{
unsigned char buf[128];
+ struct sockaddr_in sender_addr;
struct msghdr msg;
struct iovec iov;
struct cmsghdr *cmsg;
@@ -360,11 +388,17 @@ static gboolean received_data(GIOChannel *channel, GIOCondition condition,
msg.msg_iovlen = 1;
msg.msg_control = aux;
msg.msg_controllen = sizeof(aux);
+ msg.msg_name = &sender_addr;
+ msg.msg_namelen = sizeof(sender_addr);
len = recvmsg(fd, &msg, MSG_DONTWAIT);
if (len < 0)
return TRUE;
+ if (timeserver_addr.sin_addr.s_addr != sender_addr.sin_addr.s_addr)
+ /* only accept messages from the timeserver */
+ return TRUE;
+
tv = NULL;
clock_gettime(CLOCK_MONOTONIC, &mrx_time);
@@ -390,7 +424,7 @@ static void start_ntp(char *server)
struct sockaddr_in addr;
int tos = IPTOS_LOWDELAY, timestamp = 1;
- if (server == NULL)
+ if (!server)
return;
DBG("server %s", server);
@@ -427,7 +461,7 @@ static void start_ntp(char *server)
}
channel = g_io_channel_unix_new(transmit_fd);
- if (channel == NULL) {
+ if (!channel) {
close(transmit_fd);
return;
}
@@ -444,20 +478,21 @@ static void start_ntp(char *server)
g_io_channel_unref(channel);
send:
- send_packet(transmit_fd, server);
+ send_packet(transmit_fd, server, NTP_SEND_TIMEOUT);
}
int __connman_ntp_start(char *server)
{
DBG("%s", server);
- if (server == NULL)
+ if (!server)
return -EINVAL;
- if (timeserver != NULL)
+ if (timeserver)
g_free(timeserver);
timeserver = g_strdup(server);
+ timeserver_addr.sin_addr.s_addr = inet_addr(server);
start_ntp(timeserver);
@@ -468,10 +503,12 @@ void __connman_ntp_stop()
{
DBG("");
- if (poll_id > 0)
+ if (poll_id > 0) {
g_source_remove(poll_id);
+ poll_id = 0;
+ }
- reset_timeout();
+ reset_timeout();
if (channel_watch > 0) {
g_source_remove(channel_watch);
@@ -479,7 +516,7 @@ void __connman_ntp_stop()
transmit_fd = 0;
}
- if (timeserver != NULL) {
+ if (timeserver) {
g_free(timeserver);
timeserver = NULL;
}
diff --git a/src/peer.c b/src/peer.c
new file mode 100644
index 00000000..ce3b582e
--- /dev/null
+++ b/src/peer.c
@@ -0,0 +1,317 @@
+/*
+ *
+ * Connection Manager
+ *
+ * Copyright (C) 2014 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <errno.h>
+#include <gdbus.h>
+
+#include "connman.h"
+
+static DBusConnection *connection = NULL;
+
+static GHashTable *peers_table = NULL;
+
+struct connman_peer {
+ char *identifier;
+ char *name;
+ char *path;
+};
+
+static void peer_free(gpointer data)
+{
+ struct connman_peer *peer = data;
+ connman_peer_destroy(peer);
+}
+
+static void append_properties(DBusMessageIter *iter, struct connman_peer *peer)
+{
+ const char *state = "disconnected";
+ DBusMessageIter dict;
+
+ connman_dbus_dict_open(iter, &dict);
+
+ connman_dbus_dict_append_basic(&dict, "State",
+ DBUS_TYPE_STRING, &state);
+ connman_dbus_dict_append_basic(&dict, "Name",
+ DBUS_TYPE_STRING, &peer->name);
+ connman_dbus_dict_append_dict(&dict, "IPv4", NULL, NULL);
+
+ connman_dbus_dict_close(iter, &dict);
+}
+
+static DBusMessage *get_peer_properties(DBusConnection *conn,
+ DBusMessage *msg, void *data)
+{
+ struct connman_peer *peer = data;
+ DBusMessageIter dict;
+ DBusMessage *reply;
+
+ reply = dbus_message_new_method_return(msg);
+ if (!reply)
+ return NULL;
+
+ dbus_message_iter_init_append(reply, &dict);
+ append_properties(&dict, peer);
+
+ return reply;
+}
+
+static void append_peer_struct(gpointer key, gpointer value,
+ gpointer user_data)
+{
+ DBusMessageIter *array = user_data;
+ struct connman_peer *peer = value;
+ DBusMessageIter entry;
+
+ dbus_message_iter_open_container(array, DBUS_TYPE_STRUCT,
+ NULL, &entry);
+ dbus_message_iter_append_basic(&entry, DBUS_TYPE_OBJECT_PATH,
+ &peer->path);
+ append_properties(&entry, peer);
+ dbus_message_iter_close_container(array, &entry);
+}
+
+struct _peers_notify {
+ int id;
+ GHashTable *add;
+ GHashTable *remove;
+} *peers_notify;
+
+static void append_existing_and_new_peers(gpointer key,
+ gpointer value, gpointer user_data)
+{
+ struct connman_peer *peer = value;
+ DBusMessageIter *iter = user_data;
+ DBusMessageIter entry;
+
+ if (g_hash_table_lookup(peers_notify->add, peer->path)) {
+ DBG("new %s", peer->path);
+
+ append_peer_struct(key, value, user_data);
+ g_hash_table_remove(peers_notify->add, peer->path);
+ } else {
+ DBG("existing %s", peer->path);
+
+ dbus_message_iter_open_container(iter, DBUS_TYPE_STRUCT,
+ NULL, &entry);
+ dbus_message_iter_append_basic(&entry, DBUS_TYPE_OBJECT_PATH,
+ &peer->path);
+ dbus_message_iter_close_container(iter, &entry);
+ }
+}
+
+static void peer_append_all(DBusMessageIter *iter, void *user_data)
+{
+ g_hash_table_foreach(peers_table, append_existing_and_new_peers, iter);
+}
+
+static void append_removed(gpointer key, gpointer value, gpointer user_data)
+{
+ DBusMessageIter *iter = user_data;
+ char *objpath = key;
+
+ DBG("removed %s", objpath);
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH, &objpath);
+}
+
+static void peer_append_removed(DBusMessageIter *iter, void *user_data)
+{
+ g_hash_table_foreach(peers_notify->remove, append_removed, iter);
+}
+
+static gboolean peer_send_changed(gpointer data)
+{
+ DBusMessage *signal;
+
+ DBG("");
+
+ peers_notify->id = 0;
+
+ signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH,
+ CONNMAN_MANAGER_INTERFACE, "PeersChanged");
+ if (!signal)
+ return FALSE;
+
+ __connman_dbus_append_objpath_dict_array(signal,
+ peer_append_all, NULL);
+ __connman_dbus_append_objpath_array(signal,
+ peer_append_removed, NULL);
+
+ dbus_connection_send(connection, signal, NULL);
+ dbus_message_unref(signal);
+
+ g_hash_table_remove_all(peers_notify->remove);
+ g_hash_table_remove_all(peers_notify->add);
+
+ return FALSE;
+}
+
+static void peer_schedule_changed(void)
+{
+ if (peers_notify->id != 0)
+ return;
+
+ peers_notify->id = g_timeout_add(100, peer_send_changed, NULL);
+}
+
+static void peer_added(struct connman_peer *peer)
+{
+ DBG("peer %p", peer);
+
+ g_hash_table_remove(peers_notify->remove, peer->path);
+ g_hash_table_replace(peers_notify->add, peer->path, peer);
+
+ peer_schedule_changed();
+}
+
+static void peer_removed(struct connman_peer *peer)
+{
+ DBG("peer %p", peer);
+
+ g_hash_table_remove(peers_notify->add, peer->path);
+ g_hash_table_replace(peers_notify->remove, g_strdup(peer->path), NULL);
+
+ peer_schedule_changed();
+}
+
+struct connman_peer *connman_peer_create(const char *identifier)
+{
+ struct connman_peer *peer;
+
+ peer = g_malloc0(sizeof(struct connman_peer));
+ peer->identifier = g_strdup_printf("peer_%s", identifier);
+
+ return peer;
+}
+
+void connman_peer_destroy(struct connman_peer *peer)
+{
+ if (!peer)
+ return;
+
+ if (peer->path) {
+ peer_removed(peer);
+ g_dbus_unregister_interface(connection, peer->path,
+ CONNMAN_PEER_INTERFACE);
+ g_free(peer->path);
+ }
+
+ g_free(peer->identifier);
+ g_free(peer->name);
+
+ g_free(peer);
+}
+
+void connman_peer_set_name(struct connman_peer *peer, const char *name)
+{
+ g_free(peer->name);
+ peer->name = g_strdup(name);
+}
+
+static const GDBusMethodTable peer_methods[] = {
+ { GDBUS_METHOD("GetProperties",
+ NULL, GDBUS_ARGS({ "properties", "a{sv}" }),
+ get_peer_properties) },
+ { GDBUS_ASYNC_METHOD("Connect", NULL, NULL, NULL) },
+ { GDBUS_METHOD("Disconnect", NULL, NULL, NULL) },
+ { },
+};
+
+static const GDBusSignalTable peer_signals[] = {
+ { GDBUS_SIGNAL("PropertyChanged",
+ GDBUS_ARGS({ "name", "s" }, { "value", "v" })) },
+ { },
+};
+
+int connman_peer_register(struct connman_peer *peer)
+{
+ DBG("peer %p", peer);
+
+ if (peer->path)
+ return -EALREADY;
+
+ peer->path = g_strdup_printf("%s/peer/%s", CONNMAN_PATH,
+ peer->identifier);
+ DBG("path %s", peer->path);
+
+ g_hash_table_insert(peers_table, peer->identifier, peer);
+
+ g_dbus_register_interface(connection, peer->path,
+ CONNMAN_PEER_INTERFACE,
+ peer_methods, peer_signals,
+ NULL, peer, NULL);
+ peer_added(peer);
+
+ return 0;
+}
+
+void connman_peer_unregister(struct connman_peer *peer)
+{
+ DBG("peer %p", peer);
+
+ if (peer->path)
+ g_hash_table_remove(peers_table, peer->identifier);
+ else
+ connman_peer_destroy(peer);
+}
+
+struct connman_peer *connman_peer_get(const char *identifier)
+{
+ char *ident = g_strdup_printf("peer_%s", identifier);
+ struct connman_peer *peer;
+
+ peer = g_hash_table_lookup(peers_table, ident);
+ g_free(ident);
+
+ return peer;
+}
+
+void __connman_peer_list_struct(DBusMessageIter *array)
+{
+ g_hash_table_foreach(peers_table, append_peer_struct, array);
+}
+
+int __connman_peer_init(void)
+{
+ DBG("");
+
+ connection = connman_dbus_get_connection();
+
+ peers_table = g_hash_table_new_full(g_str_hash, g_str_equal,
+ NULL, peer_free);
+
+ peers_notify = g_new0(struct _peers_notify, 1);
+ peers_notify->add = g_hash_table_new(g_str_hash, g_str_equal);
+ peers_notify->remove = g_hash_table_new_full(g_str_hash, g_str_equal,
+ g_free, NULL);
+ return 0;
+}
+
+void __connman_peer_cleanup(void)
+{
+ DBG("");
+
+ g_hash_table_destroy(peers_table);
+ dbus_connection_unref(connection);
+}
diff --git a/src/plugin.c b/src/plugin.c
index adf8525b..7d730582 100644
--- a/src/plugin.c
+++ b/src/plugin.c
@@ -33,22 +33,11 @@
#include "connman.h"
-/*
- * Plugins that are using libraries with threads and their own mainloop
- * will crash on exit. This is a bug inside these libraries, but there is
- * nothing much that can be done about it.
- */
-#ifdef NEED_THREADS
-#define PLUGINFLAG (RTLD_NOW | RTLD_NODELETE)
-#else
-#define PLUGINFLAG (RTLD_NOW)
-#endif
-
static GSList *plugins = NULL;
struct connman_plugin {
void *handle;
- gboolean active;
+ bool active;
struct connman_plugin_desc *desc;
};
@@ -60,35 +49,35 @@ static gint compare_priority(gconstpointer a, gconstpointer b)
return plugin2->desc->priority - plugin1->desc->priority;
}
-static gboolean add_plugin(void *handle, struct connman_plugin_desc *desc)
+static bool add_plugin(void *handle, struct connman_plugin_desc *desc)
{
struct connman_plugin *plugin;
- if (desc->init == NULL)
- return FALSE;
+ if (!desc->init)
+ return false;
- if (g_str_equal(desc->version, CONNMAN_VERSION) == FALSE) {
+ if (!g_str_equal(desc->version, CONNMAN_VERSION)) {
connman_error("Invalid version %s for %s", desc->version,
desc->description);
- return FALSE;
+ return false;
}
plugin = g_try_new0(struct connman_plugin, 1);
- if (plugin == NULL)
- return FALSE;
+ if (!plugin)
+ return false;
plugin->handle = handle;
- plugin->active = FALSE;
+ plugin->active = false;
plugin->desc = desc;
__connman_log_enable(desc->debug_start, desc->debug_stop);
plugins = g_slist_insert_sorted(plugins, plugin, compare_priority);
- return TRUE;
+ return true;
}
-static gboolean check_plugin(struct connman_plugin_desc *desc,
+static bool check_plugin(struct connman_plugin_desc *desc,
char **patterns, char **excludes)
{
if (excludes) {
@@ -97,7 +86,7 @@ static gboolean check_plugin(struct connman_plugin_desc *desc,
break;
if (*excludes) {
connman_info("Excluding %s", desc->description);
- return FALSE;
+ return false;
}
}
@@ -107,11 +96,11 @@ static gboolean check_plugin(struct connman_plugin_desc *desc,
break;
if (!*patterns) {
connman_info("Ignoring %s", desc->description);
- return FALSE;
+ return false;
}
}
- return TRUE;
+ return true;
}
#include <builtin.h>
@@ -135,27 +124,26 @@ int __connman_plugin_init(const char *pattern, const char *exclude)
excludes = g_strsplit_set(exclude, ":, ", -1);
for (i = 0; __connman_builtin[i]; i++) {
- if (check_plugin(__connman_builtin[i],
- patterns, excludes) == FALSE)
+ if (!check_plugin(__connman_builtin[i], patterns, excludes))
continue;
add_plugin(NULL, __connman_builtin[i]);
}
dir = g_dir_open(PLUGINDIR, 0, NULL);
- if (dir != NULL) {
- while ((file = g_dir_read_name(dir)) != NULL) {
+ if (dir) {
+ while ((file = g_dir_read_name(dir))) {
void *handle;
struct connman_plugin_desc *desc;
- if (g_str_has_prefix(file, "lib") == TRUE ||
- g_str_has_suffix(file, ".so") == FALSE)
+ if (g_str_has_prefix(file, "lib") ||
+ !g_str_has_suffix(file, ".so"))
continue;
filename = g_build_filename(PLUGINDIR, file, NULL);
- handle = dlopen(filename, PLUGINFLAG);
- if (handle == NULL) {
+ handle = dlopen(filename, RTLD_NOW);
+ if (!handle) {
connman_error("Can't load %s: %s",
filename, dlerror());
g_free(filename);
@@ -165,19 +153,19 @@ int __connman_plugin_init(const char *pattern, const char *exclude)
g_free(filename);
desc = dlsym(handle, "connman_plugin_desc");
- if (desc == NULL) {
+ if (!desc) {
connman_error("Can't load symbol: %s",
dlerror());
dlclose(handle);
continue;
}
- if (check_plugin(desc, patterns, excludes) == FALSE) {
+ if (!check_plugin(desc, patterns, excludes)) {
dlclose(handle);
continue;
}
- if (add_plugin(handle, desc) == FALSE)
+ if (!add_plugin(handle, desc))
dlclose(handle);
}
@@ -190,7 +178,7 @@ int __connman_plugin_init(const char *pattern, const char *exclude)
if (plugin->desc->init() < 0)
continue;
- plugin->active = TRUE;
+ plugin->active = true;
}
g_strfreev(patterns);
@@ -208,10 +196,10 @@ void __connman_plugin_cleanup(void)
for (list = plugins; list; list = list->next) {
struct connman_plugin *plugin = list->data;
- if (plugin->active == TRUE && plugin->desc->exit)
+ if (plugin->active && plugin->desc->exit)
plugin->desc->exit();
- if (plugin->handle != NULL)
+ if (plugin->handle)
dlclose(plugin->handle);
g_free(plugin);
diff --git a/src/provider.c b/src/provider.c
index 1c360172..693552ee 100644
--- a/src/provider.c
+++ b/src/provider.c
@@ -2,7 +2,7 @@
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2013 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -40,6 +40,7 @@ static GSList *driver_list = NULL;
struct connman_provider {
int refcount;
+ bool immutable;
struct connman_service *vpn_service;
int index;
char *identifier;
@@ -53,22 +54,22 @@ void __connman_provider_append_properties(struct connman_provider *provider,
{
const char *host, *domain, *type;
- if (provider->driver == NULL || provider->driver->get_property == NULL)
+ if (!provider->driver || !provider->driver->get_property)
return;
host = provider->driver->get_property(provider, "Host");
domain = provider->driver->get_property(provider, "Domain");
type = provider->driver->get_property(provider, "Type");
- if (host != NULL)
+ if (host)
connman_dbus_dict_append_basic(iter, "Host",
DBUS_TYPE_STRING, &host);
- if (domain != NULL)
+ if (domain)
connman_dbus_dict_append_basic(iter, "Domain",
DBUS_TYPE_STRING, &domain);
- if (type != NULL)
+ if (type)
connman_dbus_dict_append_basic(iter, "Type", DBUS_TYPE_STRING,
&type);
}
@@ -87,7 +88,7 @@ connman_provider_ref_debug(struct connman_provider *provider,
static void provider_remove(struct connman_provider *provider)
{
- if (provider->driver != NULL) {
+ if (provider->driver) {
provider->driver->remove(provider);
provider->driver = NULL;
}
@@ -131,12 +132,12 @@ int connman_provider_disconnect(struct connman_provider *provider)
DBG("provider %p", provider);
- if (provider->driver != NULL && provider->driver->disconnect != NULL)
+ if (provider->driver && provider->driver->disconnect)
err = provider->driver->disconnect(provider);
else
return -EOPNOTSUPP;
- if (provider->vpn_service != NULL)
+ if (provider->vpn_service)
provider_indicate_state(provider,
CONNMAN_SERVICE_STATE_DISCONNECT);
@@ -169,9 +170,9 @@ int __connman_provider_connect(struct connman_provider *provider)
DBG("provider %p", provider);
- if (provider->driver != NULL && provider->driver->connect != NULL) {
+ if (provider->driver && provider->driver->connect)
err = provider->driver->connect(provider);
- } else
+ else
return -EOPNOTSUPP;
if (err < 0) {
@@ -196,11 +197,11 @@ int __connman_provider_remove_by_path(const char *path)
DBG("path %s", path);
g_hash_table_iter_init(&iter, provider_hash);
- while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
+ while (g_hash_table_iter_next(&iter, &key, &value)) {
const char *srv_path;
provider = value;
- if (provider->vpn_service == NULL)
+ if (!provider->vpn_service)
continue;
srv_path = __connman_service_get_path(provider->vpn_service);
@@ -223,18 +224,18 @@ int __connman_provider_remove_by_path(const char *path)
}
static int set_connected(struct connman_provider *provider,
- connman_bool_t connected)
+ bool connected)
{
struct connman_service *service = provider->vpn_service;
struct connman_ipconfig *ipconfig;
- if (service == NULL)
+ if (!service)
return -ENODEV;
ipconfig = __connman_service_get_ipconfig(service, provider->family);
- if (connected == TRUE) {
- if (ipconfig == NULL) {
+ if (connected) {
+ if (!ipconfig) {
provider_indicate_state(provider,
CONNMAN_SERVICE_STATE_FAILURE);
return -EIO;
@@ -246,12 +247,12 @@ static int set_connected(struct connman_provider *provider,
provider_indicate_state(provider,
CONNMAN_SERVICE_STATE_READY);
- if (provider->driver != NULL && provider->driver->set_routes)
+ if (provider->driver && provider->driver->set_routes)
provider->driver->set_routes(provider,
CONNMAN_PROVIDER_ROUTE_ALL);
} else {
- if (ipconfig != NULL) {
+ if (ipconfig) {
provider_indicate_state(provider,
CONNMAN_SERVICE_STATE_DISCONNECT);
__connman_ipconfig_gateway_remove(ipconfig);
@@ -267,19 +268,19 @@ static int set_connected(struct connman_provider *provider,
int connman_provider_set_state(struct connman_provider *provider,
enum connman_provider_state state)
{
- if (provider == NULL || provider->vpn_service == NULL)
+ if (!provider || !provider->vpn_service)
return -EINVAL;
switch (state) {
case CONNMAN_PROVIDER_STATE_UNKNOWN:
return -EINVAL;
case CONNMAN_PROVIDER_STATE_IDLE:
- return set_connected(provider, FALSE);
+ return set_connected(provider, false);
case CONNMAN_PROVIDER_STATE_CONNECT:
return provider_indicate_state(provider,
CONNMAN_SERVICE_STATE_ASSOCIATION);
case CONNMAN_PROVIDER_STATE_READY:
- return set_connected(provider, TRUE);
+ return set_connected(provider, true);
case CONNMAN_PROVIDER_STATE_DISCONNECT:
return provider_indicate_state(provider,
CONNMAN_SERVICE_STATE_DISCONNECT);
@@ -317,17 +318,17 @@ int connman_provider_indicate_error(struct connman_provider *provider,
int connman_provider_create_service(struct connman_provider *provider)
{
- if (provider->vpn_service != NULL) {
- connman_bool_t connected;
+ if (provider->vpn_service) {
+ bool connected;
connected = __connman_service_is_connected_state(
provider->vpn_service, CONNMAN_IPCONFIG_TYPE_IPV4);
- if (connected == TRUE)
+ if (connected)
return -EALREADY;
connected = __connman_service_is_connected_state(
provider->vpn_service, CONNMAN_IPCONFIG_TYPE_IPV6);
- if (connected == TRUE)
+ if (connected)
return -EALREADY;
return 0;
@@ -336,7 +337,7 @@ int connman_provider_create_service(struct connman_provider *provider)
provider->vpn_service =
__connman_service_create_from_provider(provider);
- if (provider->vpn_service == NULL) {
+ if (!provider->vpn_service) {
connman_warn("service creation failed for provider %s",
provider->identifier);
@@ -347,17 +348,24 @@ int connman_provider_create_service(struct connman_provider *provider)
return 0;
}
+bool __connman_provider_is_immutable(struct connman_provider *provider)
+
+{
+ if (provider)
+ return provider->immutable;
+
+ return false;
+}
+
int connman_provider_set_immutable(struct connman_provider *provider,
- connman_bool_t immutable)
+ bool immutable)
{
- if (provider == NULL)
+ if (!provider)
return -EINVAL;
- if (provider->vpn_service == NULL)
- return -ESRCH;
+ provider->immutable = immutable;
- return __connman_service_set_immutable(provider->vpn_service,
- immutable);
+ return 0;
}
static struct connman_provider *provider_lookup(const char *identifier)
@@ -374,15 +382,15 @@ static void connection_ready(DBusMessage *msg, int error_code, void *user_data)
if (error_code != 0) {
reply = __connman_error_failed(msg, -error_code);
- if (g_dbus_send_message(connection, reply) == FALSE)
+ if (!g_dbus_send_message(connection, reply))
DBG("reply %p send failed", reply);
} else {
const char *path;
struct connman_provider *provider;
provider = provider_lookup(identifier);
- if (provider == NULL) {
- reply = __connman_error_failed(msg, -EINVAL);
+ if (!provider) {
+ reply = __connman_error_failed(msg, EINVAL);
g_dbus_send_message(connection, reply);
return;
}
@@ -399,11 +407,11 @@ int __connman_provider_create_and_connect(DBusMessage *msg)
{
struct connman_provider_driver *driver;
- if (driver_list == NULL)
+ if (!driver_list)
return -EINVAL;
driver = driver_list->data;
- if (driver == NULL || driver->create == NULL)
+ if (!driver || !driver->create)
return -EINVAL;
DBG("msg %p", msg);
@@ -411,9 +419,9 @@ int __connman_provider_create_and_connect(DBusMessage *msg)
return driver->create(msg, connection_ready);
}
-const char * __connman_provider_get_ident(struct connman_provider *provider)
+const char *__connman_provider_get_ident(struct connman_provider *provider)
{
- if (provider == NULL)
+ if (!provider)
return NULL;
return provider->identifier;
@@ -422,7 +430,7 @@ const char * __connman_provider_get_ident(struct connman_provider *provider)
int connman_provider_set_string(struct connman_provider *provider,
const char *key, const char *value)
{
- if (provider->driver != NULL && provider->driver->set_property)
+ if (provider->driver && provider->driver->set_property)
return provider->driver->set_property(provider, key, value);
return 0;
@@ -431,22 +439,22 @@ int connman_provider_set_string(struct connman_provider *provider,
const char *connman_provider_get_string(struct connman_provider *provider,
const char *key)
{
- if (provider->driver != NULL && provider->driver->get_property)
+ if (provider->driver && provider->driver->get_property)
return provider->driver->get_property(provider, key);
return NULL;
}
-connman_bool_t
+bool
__connman_provider_check_routes(struct connman_provider *provider)
{
- if (provider == NULL)
- return FALSE;
+ if (!provider)
+ return false;
- if (provider->driver != NULL && provider->driver->check_routes)
+ if (provider->driver && provider->driver->check_routes)
return provider->driver->check_routes(provider);
- return FALSE;
+ return false;
}
void *connman_provider_get_data(struct connman_provider *provider)
@@ -466,16 +474,16 @@ void connman_provider_set_index(struct connman_provider *provider, int index)
DBG("");
- if (service == NULL)
+ if (!service)
return;
ipconfig = __connman_service_get_ip4config(service);
- if (ipconfig == NULL) {
+ if (!ipconfig) {
connman_service_create_ip4config(service, index);
ipconfig = __connman_service_get_ip4config(service);
- if (ipconfig == NULL) {
+ if (!ipconfig) {
DBG("Couldnt create ipconfig");
goto done;
}
@@ -486,11 +494,11 @@ void connman_provider_set_index(struct connman_provider *provider, int index)
ipconfig = __connman_service_get_ip6config(service);
- if (ipconfig == NULL) {
+ if (!ipconfig) {
connman_service_create_ip6config(service, index);
ipconfig = __connman_service_get_ip6config(service);
- if (ipconfig == NULL) {
+ if (!ipconfig) {
DBG("Couldnt create ipconfig for IPv6");
goto done;
}
@@ -515,7 +523,7 @@ int connman_provider_set_ipaddress(struct connman_provider *provider,
ipconfig = __connman_service_get_ipconfig(provider->vpn_service,
ipaddress->family);
- if (ipconfig == NULL)
+ if (!ipconfig)
return -EINVAL;
provider->family = ipaddress->family;
@@ -552,7 +560,7 @@ int connman_provider_set_domain(struct connman_provider *provider,
}
int connman_provider_set_nameservers(struct connman_provider *provider,
- char * const * nameservers)
+ char * const *nameservers)
{
int i;
@@ -560,12 +568,12 @@ int connman_provider_set_nameservers(struct connman_provider *provider,
__connman_service_nameserver_clear(provider->vpn_service);
- if (nameservers == NULL)
+ if (!nameservers)
return 0;
- for (i = 0; nameservers[i] != NULL; i++)
+ for (i = 0; nameservers[i]; i++)
__connman_service_nameserver_append(provider->vpn_service,
- nameservers[i], FALSE);
+ nameservers[i], false);
return 0;
}
@@ -576,7 +584,7 @@ static void unregister_provider(gpointer data)
DBG("provider %p service %p", provider, provider->vpn_service);
- if (provider->vpn_service != NULL) {
+ if (provider->vpn_service) {
connman_service_unref(provider->vpn_service);
provider->vpn_service = NULL;
}
@@ -619,11 +627,11 @@ static void provider_disconnect_all(gpointer key, gpointer value,
connman_provider_disconnect(provider);
}
-static void provider_offline_mode(connman_bool_t enabled)
+static void provider_offline_mode(bool enabled)
{
DBG("enabled %d", enabled);
- if (enabled == TRUE)
+ if (enabled)
g_hash_table_foreach(provider_hash, provider_disconnect_all,
NULL);
@@ -642,7 +650,7 @@ static struct connman_provider *provider_new(void)
struct connman_provider *provider;
provider = g_try_new0(struct connman_provider, 1);
- if (provider == NULL)
+ if (!provider)
return NULL;
provider->refcount = 1;
@@ -658,11 +666,11 @@ struct connman_provider *connman_provider_get(const char *identifier)
struct connman_provider *provider;
provider = g_hash_table_lookup(provider_hash, identifier);
- if (provider != NULL)
+ if (provider)
return provider;
provider = provider_new();
- if (provider == NULL)
+ if (!provider)
return NULL;
DBG("provider %p", provider);
@@ -686,7 +694,7 @@ static struct connman_provider *provider_get(int index)
g_hash_table_iter_init(&iter, provider_hash);
- while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
+ while (g_hash_table_iter_next(&iter, &key, &value)) {
struct connman_provider *provider = value;
if (provider->index == index)
@@ -702,7 +710,7 @@ static void provider_service_changed(struct connman_service *service,
struct connman_provider *provider;
int vpn_index, service_index;
- if (service == NULL)
+ if (!service)
return;
switch (state) {
@@ -730,7 +738,7 @@ static void provider_service_changed(struct connman_service *service,
return;
provider = provider_get(vpn_index);
- if (provider == NULL)
+ if (!provider)
return;
DBG("disconnect %p index %d", provider, vpn_index);
diff --git a/src/proxy.c b/src/proxy.c
index b6775b67..0d1a25ab 100644
--- a/src/proxy.c
+++ b/src/proxy.c
@@ -69,7 +69,7 @@ static gboolean lookup_callback(gpointer user_data)
struct proxy_lookup *lookup = user_data;
GSList *list;
- if (lookup == NULL)
+ if (!lookup)
return FALSE;
lookup->watch = 0;
@@ -77,14 +77,14 @@ static gboolean lookup_callback(gpointer user_data)
for (list = driver_list; list; list = list->next) {
struct connman_proxy_driver *proxy = list->data;
- if (proxy->request_lookup == NULL)
+ if (!proxy->request_lookup)
continue;
lookup->proxy = proxy;
break;
}
- if (lookup->proxy == NULL ||
+ if (!lookup->proxy ||
lookup->proxy->request_lookup(lookup->service,
lookup->url) < 0) {
@@ -106,11 +106,11 @@ unsigned int connman_proxy_lookup(const char *interface, const char *url,
DBG("interface %s url %s", interface, url);
- if (interface == NULL)
+ if (!interface)
return 0;
lookup = g_try_new0(struct proxy_lookup, 1);
- if (lookup == NULL)
+ if (!lookup)
return 0;
lookup->token = next_lookup_token++;
@@ -149,14 +149,14 @@ void connman_proxy_lookup_cancel(unsigned int token)
lookup = NULL;
}
- if (lookup != NULL) {
+ if (lookup) {
if (lookup->watch > 0) {
g_source_remove(lookup->watch);
lookup->watch = 0;
}
- if (lookup->proxy != NULL &&
- lookup->proxy->cancel_lookup != NULL)
+ if (lookup->proxy &&
+ lookup->proxy->cancel_lookup)
lookup->proxy->cancel_lookup(lookup->service,
lookup->url);
@@ -165,7 +165,7 @@ void connman_proxy_lookup_cancel(unsigned int token)
}
void connman_proxy_driver_lookup_notify(struct connman_service *service,
- const char *url, const char *result)
+ const char *url, const char *result)
{
GSList *list, *matches = NULL;
@@ -185,7 +185,7 @@ void connman_proxy_driver_lookup_notify(struct connman_service *service,
}
}
- if (matches != NULL)
+ if (matches)
remove_lookups(matches);
}
diff --git a/src/resolver.c b/src/resolver.c
index b965778b..01e7c0e0 100644
--- a/src/resolver.c
+++ b/src/resolver.c
@@ -2,7 +2,7 @@
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2013 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -54,7 +54,7 @@ struct entry_data {
};
static GSList *entry_list = NULL;
-static connman_bool_t dnsproxy_enabled = FALSE;
+static bool dnsproxy_enabled = false;
struct resolvfile_entry {
int index;
@@ -168,7 +168,7 @@ int __connman_resolvfile_append(int index, const char *domain,
return -ENOENT;
entry = g_try_new0(struct resolvfile_entry, 1);
- if (entry == NULL)
+ if (!entry)
return -ENOMEM;
entry->index = index;
@@ -193,7 +193,7 @@ int __connman_resolvfile_remove(int index, const char *domain,
if (index >= 0 && entry->index != index)
continue;
- if (domain != NULL && g_strcmp0(entry->domain, domain) != 0)
+ if (domain && g_strcmp0(entry->domain, domain) != 0)
continue;
if (g_strcmp0(entry->server, server) != 0)
@@ -207,6 +207,57 @@ int __connman_resolvfile_remove(int index, const char *domain,
return resolvfile_export();
}
+static void append_fallback_nameservers(void)
+{
+ GSList *list;
+
+ for (list = entry_list; list; list = list->next) {
+ struct entry_data *entry = list->data;
+
+ if (entry->index >= 0 && entry->server)
+ return;
+ }
+
+ for (list = entry_list; list; list = list->next) {
+ struct entry_data *entry = list->data;
+
+ if (entry->index != -1 || !entry->server)
+ continue;
+
+ DBG("index %d server %s", entry->index, entry->server);
+
+ if (dnsproxy_enabled) {
+ __connman_dnsproxy_append(entry->index, entry->domain,
+ entry->server);
+ } else {
+ __connman_resolvfile_append(entry->index,
+ entry->domain, entry->server);
+ }
+ }
+}
+
+static void remove_fallback_nameservers(void)
+{
+ GSList *list;
+
+ for (list = entry_list; list; list = list->next) {
+ struct entry_data *entry = list->data;
+
+ if (entry->index >= 0 || !entry->server)
+ continue;
+
+ DBG("index %d server %s", entry->index, entry->server);
+
+ if (dnsproxy_enabled) {
+ __connman_dnsproxy_remove(entry->index, entry->domain,
+ entry->server);
+ } else {
+ __connman_resolvfile_remove(entry->index,
+ entry->domain, entry->server);
+ }
+ }
+}
+
static void remove_entries(GSList *entries)
{
GSList *list;
@@ -216,7 +267,7 @@ static void remove_entries(GSList *entries)
entry_list = g_slist_remove(entry_list, entry);
- if (dnsproxy_enabled == TRUE) {
+ if (dnsproxy_enabled) {
__connman_dnsproxy_remove(entry->index, entry->domain,
entry->server);
} else {
@@ -247,9 +298,9 @@ static gboolean resolver_expire_cb(gpointer user_data)
if (entry->index >= 0) {
struct connman_service *service;
service = __connman_service_lookup_from_index(entry->index);
- if (service != NULL)
+ if (service)
__connman_service_nameserver_remove(service,
- entry->server, TRUE);
+ entry->server, true);
}
remove_entries(list);
@@ -277,12 +328,12 @@ static gboolean resolver_refresh_cb(gpointer user_data)
if (entry->index >= 0) {
service = __connman_service_lookup_from_index(entry->index);
- if (service != NULL) {
+ if (service) {
/*
* Send Router Solicitation to refresh RDNSS entries
* before their lifetime expires
*/
- __connman_refresh_rs_ipv6(
+ __connman_network_refresh_rs_ipv6(
__connman_service_get_network(service),
entry->index);
}
@@ -300,11 +351,11 @@ static int append_resolver(int index, const char *domain,
DBG("index %d domain %s server %s lifetime %d flags %d",
index, domain, server, lifetime, flags);
- if (server == NULL && domain == NULL)
+ if (!server && !domain)
return -EINVAL;
entry = g_try_new0(struct entry_data, 1);
- if (entry == NULL)
+ if (!entry)
return -ENOMEM;
entry->index = index;
@@ -313,7 +364,7 @@ static int append_resolver(int index, const char *domain,
entry->flags = flags;
entry->lifetime = lifetime;
- if (server != NULL)
+ if (server)
entry->family = connman_inet_check_ipaddress(server);
if (lifetime) {
@@ -330,17 +381,21 @@ static int append_resolver(int index, const char *domain,
* We update the service only for those nameservers
* that are automagically added via netlink (lifetime > 0)
*/
- if (server != NULL && entry->index >= 0) {
+ if (server && entry->index >= 0) {
struct connman_service *service;
service = __connman_service_lookup_from_index(entry->index);
- if (service != NULL)
+ if (service)
__connman_service_nameserver_append(service,
- server, TRUE);
+ server, true);
}
}
+
+ if (entry->index >= 0 && entry->server)
+ remove_fallback_nameservers();
+
entry_list = g_slist_append(entry_list, entry);
- if (dnsproxy_enabled == TRUE)
+ if (dnsproxy_enabled)
__connman_dnsproxy_append(entry->index, domain, server);
else
__connman_resolvfile_append(entry->index, domain, server);
@@ -363,7 +418,7 @@ int connman_resolver_append(int index, const char *domain,
DBG("index %d domain %s server %s", index, domain, server);
- if (server == NULL && domain == NULL)
+ if (!server && !domain)
return -EINVAL;
for (list = entry_list; list; list = list->next) {
@@ -374,8 +429,13 @@ int connman_resolver_append(int index, const char *domain,
if (entry->index == index &&
g_strcmp0(entry->domain, domain) == 0 &&
- g_strcmp0(entry->server, server) == 0)
+ g_strcmp0(entry->server, server) == 0) {
+ if (dnsproxy_enabled)
+ __connman_dnsproxy_append(entry->index, domain,
+ server);
+
return -EEXIST;
+ }
}
return append_resolver(index, domain, server, 0, 0);
@@ -399,7 +459,7 @@ int connman_resolver_append_lifetime(int index, const char *domain,
DBG("index %d domain %s server %s lifetime %d",
index, domain, server, lifetime);
- if (server == NULL && domain == NULL)
+ if (!server && !domain)
return -EINVAL;
for (list = entry_list; list; list = list->next) {
@@ -462,7 +522,7 @@ int connman_resolver_remove(int index, const char *domain, const char *server)
break;
}
- if (matches == NULL)
+ if (!matches)
return -ENOENT;
remove_entries(matches);
@@ -494,7 +554,7 @@ int connman_resolver_remove_all(int index)
matches = g_slist_prepend(matches, entry);
}
- if (matches == NULL)
+ if (!matches)
return -ENOENT;
remove_entries(matches);
@@ -509,7 +569,9 @@ int connman_resolver_remove_all(int index)
*/
void connman_resolver_flush(void)
{
- if (dnsproxy_enabled == TRUE)
+ append_fallback_nameservers();
+
+ if (dnsproxy_enabled)
__connman_dnsproxy_flush();
return;
@@ -519,7 +581,7 @@ int __connman_resolver_redo_servers(int index)
{
GSList *list;
- if (dnsproxy_enabled == FALSE)
+ if (!dnsproxy_enabled)
return 0;
DBG("index %d", index);
@@ -578,14 +640,14 @@ static void free_resolvfile(gpointer data)
g_free(entry);
}
-int __connman_resolver_init(connman_bool_t dnsproxy)
+int __connman_resolver_init(gboolean dnsproxy)
{
int i;
char **ns;
DBG("dnsproxy %d", dnsproxy);
- if (dnsproxy == FALSE)
+ if (!dnsproxy)
return 0;
if (__connman_dnsproxy_init() < 0) {
@@ -593,10 +655,10 @@ int __connman_resolver_init(connman_bool_t dnsproxy)
return 0;
}
- dnsproxy_enabled = TRUE;
+ dnsproxy_enabled = true;
ns = connman_setting_get_string_list("FallbackNameservers");
- for (i = 0; ns != NULL && ns[i] != NULL; i += 1) {
+ for (i = 0; ns && ns[i]; i += 1) {
DBG("server %s", ns[i]);
append_resolver(-1, NULL, ns[i], 0, RESOLVER_FLAG_PUBLIC);
}
@@ -608,7 +670,7 @@ void __connman_resolver_cleanup(void)
{
DBG("");
- if (dnsproxy_enabled == TRUE)
+ if (dnsproxy_enabled)
__connman_dnsproxy_cleanup();
else {
GList *list;
diff --git a/src/rfkill.c b/src/rfkill.c
index e21b2a15..960cfea7 100644
--- a/src/rfkill.c
+++ b/src/rfkill.c
@@ -2,7 +2,7 @@
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2013 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -88,6 +88,7 @@ static enum rfkill_type convert_service_type(enum connman_service_type type)
case CONNMAN_SERVICE_TYPE_ETHERNET:
case CONNMAN_SERVICE_TYPE_VPN:
case CONNMAN_SERVICE_TYPE_GADGET:
+ case CONNMAN_SERVICE_TYPE_P2P:
case CONNMAN_SERVICE_TYPE_UNKNOWN:
return NUM_RFKILL_TYPES;
}
@@ -141,8 +142,7 @@ static GIOStatus rfkill_process(GIOChannel *chan)
return status;
}
-static gboolean rfkill_event(GIOChannel *chan,
- GIOCondition cond, gpointer data)
+static gboolean rfkill_event(GIOChannel *chan, GIOCondition cond, gpointer data)
{
if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
return FALSE;
@@ -155,7 +155,7 @@ static gboolean rfkill_event(GIOChannel *chan,
static GIOChannel *channel = NULL;
-int __connman_rfkill_block(enum connman_service_type type, connman_bool_t block)
+int __connman_rfkill_block(enum connman_service_type type, bool block)
{
uint8_t rfkill_type;
struct rfkill_event event;
@@ -225,7 +225,7 @@ void __connman_rfkill_cleanup(void)
{
DBG("");
- if (channel == NULL)
+ if (!channel)
return;
g_io_channel_shutdown(channel, TRUE, NULL);
diff --git a/src/rtnl.c b/src/rtnl.c
index af8ab707..a46aa284 100644
--- a/src/rtnl.c
+++ b/src/rtnl.c
@@ -2,7 +2,7 @@
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2013 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -65,7 +65,6 @@ static guint update_timeout = 0;
struct interface_data {
int index;
- char *name;
char *ident;
enum connman_service_type service_type;
enum connman_device_type device_type;
@@ -78,53 +77,54 @@ static void free_interface(gpointer data)
struct interface_data *interface = data;
__connman_technology_remove_interface(interface->service_type,
- interface->index, interface->name, interface->ident);
+ interface->index, interface->ident);
g_free(interface->ident);
- g_free(interface->name);
g_free(interface);
}
-static connman_bool_t ether_blacklisted(const char *name)
+static bool ether_blacklisted(const char *name)
{
- if (name == NULL)
- return TRUE;
+ if (!name)
+ return true;
- if (__connman_device_isfiltered(name) == TRUE)
- return TRUE;
+ if (__connman_device_isfiltered(name))
+ return true;
- return FALSE;
+ return false;
}
-static connman_bool_t wext_interface(char *ifname)
+static bool wext_interface(char *ifname)
{
struct iwreq wrq;
int fd, err;
fd = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
if (fd < 0)
- return FALSE;
+ return false;
memset(&wrq, 0, sizeof(wrq));
- strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
+ strncpy(wrq.ifr_name, ifname, sizeof(wrq.ifr_name) - 1);
err = ioctl(fd, SIOCGIWNAME, &wrq);
close(fd);
if (err < 0)
- return FALSE;
+ return false;
- return TRUE;
+ return true;
}
static void read_uevent(struct interface_data *interface)
{
- char *filename, line[128];
- connman_bool_t found_devtype;
+ char *filename, *name, line[128];
+ bool found_devtype;
FILE *f;
- if (ether_blacklisted(interface->name) == TRUE) {
+ name = connman_inet_ifname(interface->index);
+
+ if (ether_blacklisted(name)) {
interface->service_type = CONNMAN_SERVICE_TYPE_UNKNOWN;
interface->device_type = CONNMAN_DEVICE_TYPE_UNKNOWN;
} else {
@@ -132,29 +132,31 @@ static void read_uevent(struct interface_data *interface)
interface->device_type = CONNMAN_DEVICE_TYPE_ETHERNET;
}
- filename = g_strdup_printf("/sys/class/net/%s/uevent",
- interface->name);
+ filename = g_strdup_printf("/sys/class/net/%s/uevent", name);
f = fopen(filename, "re");
g_free(filename);
- if (f == NULL)
- return;
+ if (!f) {
+ interface->service_type = CONNMAN_SERVICE_TYPE_UNKNOWN;
+ interface->device_type = CONNMAN_DEVICE_TYPE_UNKNOWN;
+ goto out;
+ }
- found_devtype = FALSE;
+ found_devtype = false;
while (fgets(line, sizeof(line), f)) {
char *pos;
pos = strchr(line, '\n');
- if (pos == NULL)
+ if (!pos)
continue;
pos[0] = '\0';
if (strncmp(line, "DEVTYPE=", 8) != 0)
continue;
- found_devtype = TRUE;
+ found_devtype = true;
if (strcmp(line + 8, "wlan") == 0) {
interface->service_type = CONNMAN_SERVICE_TYPE_WIFI;
@@ -178,16 +180,18 @@ static void read_uevent(struct interface_data *interface)
fclose(f);
if (found_devtype)
- return;
+ goto out;
/* We haven't got a DEVTYPE, let's check if it's a wireless device */
- if (wext_interface(interface->name)) {
+ if (wext_interface(name)) {
interface->service_type = CONNMAN_SERVICE_TYPE_WIFI;
interface->device_type = CONNMAN_DEVICE_TYPE_WIFI;
- connman_error("%s runs an unsupported 802.11 driver",
- interface->name);
+ connman_error("%s runs an unsupported 802.11 driver", name);
}
+
+out:
+ g_free(name);
}
enum connman_device_type __connman_rtnl_get_device_type(int index)
@@ -196,7 +200,7 @@ enum connman_device_type __connman_rtnl_get_device_type(int index)
interface = g_hash_table_lookup(interface_list,
GINT_TO_POINTER(index));
- if (interface == NULL)
+ if (!interface)
return CONNMAN_DEVICE_TYPE_UNKNOWN;
return interface->device_type;
@@ -218,7 +222,7 @@ unsigned int connman_rtnl_add_newlink_watch(int index,
struct watch_data *watch;
watch = g_try_new0(struct watch_data, 1);
- if (watch == NULL)
+ if (!watch)
return 0;
watch->id = ++watch_id;
@@ -283,7 +287,7 @@ static void trigger_rtnl(int index, void *user_data)
__connman_ipconfig_get_gateway_from_index(index,
CONNMAN_IPCONFIG_TYPE_ALL);
- if (gateway != NULL)
+ if (gateway)
rtnl->newgateway(index, gateway);
}
}
@@ -353,7 +357,7 @@ static const char *operstate2str(unsigned char operstate)
return "";
}
-static connman_bool_t extract_link(struct ifinfomsg *msg, int bytes,
+static bool extract_link(struct ifinfomsg *msg, int bytes,
struct ether_addr *address, const char **ifname,
unsigned int *mtu, unsigned char *operstate,
struct rtnl_link_stats *stats)
@@ -364,41 +368,40 @@ static connman_bool_t extract_link(struct ifinfomsg *msg, int bytes,
attr = RTA_NEXT(attr, bytes)) {
switch (attr->rta_type) {
case IFLA_ADDRESS:
- if (address != NULL)
+ if (address)
memcpy(address, RTA_DATA(attr), ETH_ALEN);
break;
case IFLA_IFNAME:
- if (ifname != NULL)
+ if (ifname)
*ifname = RTA_DATA(attr);
break;
case IFLA_MTU:
- if (mtu != NULL)
+ if (mtu)
*mtu = *((unsigned int *) RTA_DATA(attr));
break;
case IFLA_STATS:
- if (stats != NULL)
+ if (stats)
memcpy(stats, RTA_DATA(attr),
sizeof(struct rtnl_link_stats));
break;
case IFLA_OPERSTATE:
- if (operstate != NULL)
+ if (operstate)
*operstate = *((unsigned char *) RTA_DATA(attr));
break;
case IFLA_LINKMODE:
break;
case IFLA_WIRELESS:
- return FALSE;
+ return false;
}
}
- return TRUE;
+ return true;
}
static void process_newlink(unsigned short type, int index, unsigned flags,
unsigned change, struct ifinfomsg *msg, int bytes)
{
struct ether_addr address = {{ 0, 0, 0, 0, 0, 0 }};
- struct ether_addr compare = {{ 0, 0, 0, 0, 0, 0 }};
struct rtnl_link_stats stats;
unsigned char operstate = 0xff;
struct interface_data *interface;
@@ -408,8 +411,7 @@ static void process_newlink(unsigned short type, int index, unsigned flags,
GSList *list;
memset(&stats, 0, sizeof(stats));
- if (extract_link(msg, bytes, &address, &ifname, &mtu, &operstate,
- &stats) == FALSE)
+ if (!extract_link(msg, bytes, &address, &ifname, &mtu, &operstate, &stats))
return;
snprintf(ident, 13, "%02x%02x%02x%02x%02x%02x",
@@ -428,6 +430,12 @@ static void process_newlink(unsigned short type, int index, unsigned flags,
address.ether_addr_octet[4],
address.ether_addr_octet[5]);
+ if (flags & IFF_SLAVE) {
+ connman_info("%s {newlink} ignoring slave, index %d address %s",
+ ifname, index, str);
+ return;
+ }
+
switch (type) {
case ARPHRD_ETHER:
case ARPHRD_LOOPBACK:
@@ -439,9 +447,8 @@ static void process_newlink(unsigned short type, int index, unsigned flags,
break;
}
- if (memcmp(&address, &compare, ETH_ALEN) != 0)
- connman_info("%s {newlink} index %d address %s mtu %u",
- ifname, index, str, mtu);
+ connman_info("%s {newlink} index %d address %s mtu %u",
+ ifname, index, str, mtu);
if (operstate != 0xff)
connman_info("%s {newlink} index %d operstate %u <%s>",
@@ -449,10 +456,9 @@ static void process_newlink(unsigned short type, int index, unsigned flags,
operstate2str(operstate));
interface = g_hash_table_lookup(interface_list, GINT_TO_POINTER(index));
- if (interface == NULL) {
+ if (!interface) {
interface = g_new0(struct interface_data, 1);
interface->index = index;
- interface->name = g_strdup(ifname);
interface->ident = g_strdup(ident);
g_hash_table_insert(interface_list,
@@ -476,9 +482,9 @@ static void process_newlink(unsigned short type, int index, unsigned flags,
* __connman_technology_add_interface() expects the
* technology to be there already.
*/
- if (interface != NULL)
+ if (interface)
__connman_technology_add_interface(interface->service_type,
- interface->index, interface->name, interface->ident);
+ interface->index, interface->ident);
for (list = watch_list; list; list = list->next) {
struct watch_data *watch = list->data;
@@ -500,8 +506,7 @@ static void process_dellink(unsigned short type, int index, unsigned flags,
GSList *list;
memset(&stats, 0, sizeof(stats));
- if (extract_link(msg, bytes, NULL, &ifname, NULL, &operstate,
- &stats) == FALSE)
+ if (!extract_link(msg, bytes, NULL, &ifname, NULL, &operstate, &stats))
return;
if (operstate != 0xff)
@@ -519,6 +524,8 @@ static void process_dellink(unsigned short type, int index, unsigned flags,
switch (type) {
case ARPHRD_ETHER:
case ARPHRD_LOOPBACK:
+ case ARPHDR_PHONET_PIPE:
+ case ARPHRD_PPP:
case ARPHRD_NONE:
__connman_ipconfig_dellink(index, &stats);
break;
@@ -539,19 +546,19 @@ static void extract_ipv4_addr(struct ifaddrmsg *msg, int bytes,
attr = RTA_NEXT(attr, bytes)) {
switch (attr->rta_type) {
case IFA_ADDRESS:
- if (address != NULL)
+ if (address)
*address = *((struct in_addr *) RTA_DATA(attr));
break;
case IFA_LOCAL:
- if (local != NULL)
+ if (local)
*local = *((struct in_addr *) RTA_DATA(attr));
break;
case IFA_BROADCAST:
- if (broadcast != NULL)
+ if (broadcast)
*broadcast = *((struct in_addr *) RTA_DATA(attr));
break;
case IFA_LABEL:
- if (label != NULL)
+ if (label)
*label = RTA_DATA(attr);
break;
}
@@ -568,11 +575,11 @@ static void extract_ipv6_addr(struct ifaddrmsg *msg, int bytes,
attr = RTA_NEXT(attr, bytes)) {
switch (attr->rta_type) {
case IFA_ADDRESS:
- if (addr != NULL)
+ if (addr)
*addr = *((struct in6_addr *) RTA_DATA(attr));
break;
case IFA_LOCAL:
- if (local != NULL)
+ if (local)
*local = *((struct in6_addr *) RTA_DATA(attr));
break;
}
@@ -582,18 +589,17 @@ static void extract_ipv6_addr(struct ifaddrmsg *msg, int bytes,
static void process_newaddr(unsigned char family, unsigned char prefixlen,
int index, struct ifaddrmsg *msg, int bytes)
{
+ struct in_addr ipv4_addr = { INADDR_ANY };
+ struct in6_addr ipv6_address, ipv6_local;
const char *label = NULL;
void *src;
char ip_string[INET6_ADDRSTRLEN];
if (family == AF_INET) {
- struct in_addr ipv4_addr = { INADDR_ANY };
extract_ipv4_addr(msg, bytes, &label, &ipv4_addr, NULL, NULL);
src = &ipv4_addr;
} else if (family == AF_INET6) {
- struct in6_addr ipv6_address, ipv6_local;
-
extract_ipv6_addr(msg, bytes, &ipv6_address, &ipv6_local);
if (IN6_IS_ADDR_LINKLOCAL(&ipv6_address))
return;
@@ -603,7 +609,7 @@ static void process_newaddr(unsigned char family, unsigned char prefixlen,
return;
}
- if (inet_ntop(family, src, ip_string, INET6_ADDRSTRLEN) == NULL)
+ if (!inet_ntop(family, src, ip_string, INET6_ADDRSTRLEN))
return;
__connman_ipconfig_newaddr(index, family, label,
@@ -623,18 +629,16 @@ static void process_newaddr(unsigned char family, unsigned char prefixlen,
static void process_deladdr(unsigned char family, unsigned char prefixlen,
int index, struct ifaddrmsg *msg, int bytes)
{
+ struct in_addr ipv4_addr = { INADDR_ANY };
+ struct in6_addr ipv6_address, ipv6_local;
const char *label = NULL;
void *src;
char ip_string[INET6_ADDRSTRLEN];
if (family == AF_INET) {
- struct in_addr ipv4_addr = { INADDR_ANY };
-
extract_ipv4_addr(msg, bytes, &label, &ipv4_addr, NULL, NULL);
src = &ipv4_addr;
} else if (family == AF_INET6) {
- struct in6_addr ipv6_address, ipv6_local;
-
extract_ipv6_addr(msg, bytes, &ipv6_address, &ipv6_local);
if (IN6_IS_ADDR_LINKLOCAL(&ipv6_address))
return;
@@ -644,7 +648,7 @@ static void process_deladdr(unsigned char family, unsigned char prefixlen,
return;
}
- if (inet_ntop(family, src, ip_string, INET6_ADDRSTRLEN) == NULL)
+ if (!inet_ntop(family, src, ip_string, INET6_ADDRSTRLEN))
return;
__connman_ipconfig_deladdr(index, family, label,
@@ -661,15 +665,15 @@ static void extract_ipv4_route(struct rtmsg *msg, int bytes, int *index,
attr = RTA_NEXT(attr, bytes)) {
switch (attr->rta_type) {
case RTA_DST:
- if (dst != NULL)
+ if (dst)
*dst = *((struct in_addr *) RTA_DATA(attr));
break;
case RTA_GATEWAY:
- if (gateway != NULL)
+ if (gateway)
*gateway = *((struct in_addr *) RTA_DATA(attr));
break;
case RTA_OIF:
- if (index != NULL)
+ if (index)
*index = *((int *) RTA_DATA(attr));
break;
}
@@ -686,16 +690,16 @@ static void extract_ipv6_route(struct rtmsg *msg, int bytes, int *index,
attr = RTA_NEXT(attr, bytes)) {
switch (attr->rta_type) {
case RTA_DST:
- if (dst != NULL)
+ if (dst)
*dst = *((struct in6_addr *) RTA_DATA(attr));
break;
case RTA_GATEWAY:
- if (gateway != NULL)
+ if (gateway)
*gateway =
*((struct in6_addr *) RTA_DATA(attr));
break;
case RTA_OIF:
- if (index != NULL)
+ if (index)
*index = *((int *) RTA_DATA(attr));
break;
}
@@ -947,6 +951,9 @@ static void rtnl_newlink(struct nlmsghdr *hdr)
rtnl_link(hdr);
+ if (hdr->nlmsg_type == IFLA_WIRELESS)
+ connman_warn_once("Obsolete WEXT WiFi driver detected");
+
process_newlink(msg->ifi_type, msg->ifi_index, msg->ifi_flags,
msg->ifi_change, msg, IFA_PAYLOAD(hdr));
}
@@ -1074,20 +1081,20 @@ static void rtnl_route(struct nlmsghdr *hdr)
}
}
-static connman_bool_t is_route_rtmsg(struct rtmsg *msg)
+static bool is_route_rtmsg(struct rtmsg *msg)
{
if (msg->rtm_table != RT_TABLE_MAIN)
- return FALSE;
+ return false;
if (msg->rtm_protocol != RTPROT_BOOT &&
msg->rtm_protocol != RTPROT_KERNEL)
- return FALSE;
+ return false;
if (msg->rtm_type != RTN_UNICAST)
- return FALSE;
+ return false;
- return TRUE;
+ return true;
}
static void rtnl_newroute(struct nlmsghdr *hdr)
@@ -1238,7 +1245,7 @@ static void rtnl_newnduseropt(struct nlmsghdr *hdr)
g_free(domains);
domains = rtnl_nd_opt_dnssl(opt, &lifetime);
- for (i = 0; domains != NULL && domains[i] != NULL; i++)
+ for (i = 0; domains && domains[i]; i++)
connman_resolver_append_lifetime(index,
domains[i], NULL, lifetime);
}
@@ -1344,13 +1351,13 @@ static int process_response(guint32 seq)
DBG("seq %d", seq);
req = find_request(seq);
- if (req != NULL) {
+ if (req) {
request_list = g_slist_remove(request_list, req);
g_free(req);
}
req = g_slist_nth_data(request_list, 0);
- if (req == NULL)
+ if (!req)
return 0;
return send_request(req);
@@ -1413,8 +1420,7 @@ static void rtnl_message(void *buf, size_t len)
}
}
-static gboolean netlink_event(GIOChannel *chan,
- GIOCondition cond, gpointer data)
+static gboolean netlink_event(GIOChannel *chan, GIOCondition cond, gpointer data)
{
unsigned char buf[4096];
struct sockaddr_nl nladdr;
@@ -1459,7 +1465,7 @@ static int send_getlink(void)
DBG("");
req = g_try_malloc0(RTNL_REQUEST_SIZE);
- if (req == NULL)
+ if (!req)
return -ENOMEM;
req->hdr.nlmsg_len = RTNL_REQUEST_SIZE;
@@ -1479,7 +1485,7 @@ static int send_getaddr(void)
DBG("");
req = g_try_malloc0(RTNL_REQUEST_SIZE);
- if (req == NULL)
+ if (!req)
return -ENOMEM;
req->hdr.nlmsg_len = RTNL_REQUEST_SIZE;
@@ -1499,7 +1505,7 @@ static int send_getroute(void)
DBG("");
req = g_try_malloc0(RTNL_REQUEST_SIZE);
- if (req == NULL)
+ if (!req)
return -ENOMEM;
req->hdr.nlmsg_len = RTNL_REQUEST_SIZE;
@@ -1570,7 +1576,7 @@ unsigned int __connman_rtnl_update_interval_remove(unsigned int interval)
update_list = g_slist_remove(update_list, GINT_TO_POINTER(interval));
- if (update_list != NULL)
+ if (update_list)
min = GPOINTER_TO_UINT(g_slist_nth_data(update_list, 0));
if (min > update_interval)
diff --git a/src/service.c b/src/service.c
index 9c4f3fbc..cbca669e 100644
--- a/src/service.c
+++ b/src/service.c
@@ -2,7 +2,7 @@
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2014 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -45,26 +45,26 @@ static GList *service_list = NULL;
static GHashTable *service_hash = NULL;
static GSList *counter_list = NULL;
static unsigned int autoconnect_timeout = 0;
+static unsigned int vpn_autoconnect_timeout = 0;
static struct connman_service *current_default = NULL;
-static connman_bool_t services_dirty = FALSE;
+static bool services_dirty = false;
struct connman_stats {
- connman_bool_t valid;
- connman_bool_t enabled;
+ bool valid;
+ bool enabled;
struct connman_stats_data data_last;
struct connman_stats_data data;
GTimer *timer;
};
struct connman_stats_counter {
- connman_bool_t append_all;
+ bool append_all;
struct connman_stats stats;
struct connman_stats stats_roaming;
};
struct connman_service {
int refcount;
- int session_usage_count;
char *identifier;
char *path;
enum connman_service_type type;
@@ -73,19 +73,18 @@ struct connman_service {
enum connman_service_state state_ipv4;
enum connman_service_state state_ipv6;
enum connman_service_error error;
+ enum connman_service_connect_reason connect_reason;
uint8_t strength;
- connman_bool_t favorite;
- connman_bool_t immutable;
- connman_bool_t hidden;
- connman_bool_t ignore;
- connman_bool_t autoconnect;
- connman_bool_t userconnect;
+ bool favorite;
+ bool immutable;
+ bool hidden;
+ bool ignore;
+ bool autoconnect;
GTimeVal modified;
unsigned int order;
char *name;
char *passphrase;
- char *agent_passphrase;
- connman_bool_t roaming;
+ bool roaming;
struct connman_ipconfig *ipconfig_ipv4;
struct connman_ipconfig *ipconfig_ipv6;
struct connman_network *network;
@@ -94,6 +93,7 @@ struct connman_service {
char **nameservers_config;
char **nameservers_auto;
char **domains;
+ char *hostname;
char *domainname;
char **timeservers;
char **timeservers_config;
@@ -117,16 +117,16 @@ struct connman_service {
char **proxies;
char **excludes;
char *pac;
- connman_bool_t wps;
+ bool wps;
int online_check_count;
- connman_bool_t do_split_routing;
- connman_bool_t new_service;
- connman_bool_t hidden_service;
+ bool do_split_routing;
+ bool new_service;
+ bool hidden_service;
char *config_file;
char *config_entry;
};
-static connman_bool_t allow_property_changed(struct connman_service *service);
+static bool allow_property_changed(struct connman_service *service);
static struct connman_ipconfig *create_ip4config(struct connman_service *service,
int index, enum connman_ipconfig_method method);
@@ -144,7 +144,7 @@ static void compare_path(gpointer value, gpointer user_data)
struct connman_service *service = value;
struct find_data *data = user_data;
- if (data->service != NULL)
+ if (data->service)
return;
if (g_strcmp0(service->path, data->path) == 0)
@@ -162,6 +162,23 @@ static struct connman_service *find_service(const char *path)
return data.service;
}
+static const char *reason2string(enum connman_service_connect_reason reason)
+{
+
+ switch (reason) {
+ case CONNMAN_SERVICE_CONNECT_REASON_NONE:
+ return "none";
+ case CONNMAN_SERVICE_CONNECT_REASON_USER:
+ return "user";
+ case CONNMAN_SERVICE_CONNECT_REASON_AUTO:
+ return "auto";
+ case CONNMAN_SERVICE_CONNECT_REASON_SESSION:
+ return "session";
+ }
+
+ return "unknown";
+}
+
const char *__connman_service_type2string(enum connman_service_type type)
{
switch (type) {
@@ -183,6 +200,8 @@ const char *__connman_service_type2string(enum connman_service_type type)
return "vpn";
case CONNMAN_SERVICE_TYPE_GADGET:
return "gadget";
+ case CONNMAN_SERVICE_TYPE_P2P:
+ return "p2p";
}
return NULL;
@@ -190,7 +209,7 @@ const char *__connman_service_type2string(enum connman_service_type type)
enum connman_service_type __connman_service_string2type(const char *str)
{
- if (str == NULL)
+ if (!str)
return CONNMAN_SERVICE_TYPE_UNKNOWN;
if (strcmp(str, "ethernet") == 0)
@@ -209,6 +228,8 @@ enum connman_service_type __connman_service_string2type(const char *str)
return CONNMAN_SERVICE_TYPE_GPS;
if (strcmp(str, "system") == 0)
return CONNMAN_SERVICE_TYPE_SYSTEM;
+ if (strcmp(str, "p2p") == 0)
+ return CONNMAN_SERVICE_TYPE_P2P;
return CONNMAN_SERVICE_TYPE_UNKNOWN;
}
@@ -321,67 +342,120 @@ static enum connman_service_proxy_method string2proxymethod(const char *method)
return CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN;
}
+int __connman_service_load_modifiable(struct connman_service *service)
+{
+ GKeyFile *keyfile;
+ GError *error = NULL;
+ gchar *str;
+ bool autoconnect;
+
+ DBG("service %p", service);
+
+ keyfile = connman_storage_load_service(service->identifier);
+ if (!keyfile)
+ return -EIO;
+
+ switch (service->type) {
+ case CONNMAN_SERVICE_TYPE_UNKNOWN:
+ case CONNMAN_SERVICE_TYPE_SYSTEM:
+ case CONNMAN_SERVICE_TYPE_GPS:
+ case CONNMAN_SERVICE_TYPE_P2P:
+ break;
+ case CONNMAN_SERVICE_TYPE_VPN:
+ service->do_split_routing = g_key_file_get_boolean(keyfile,
+ service->identifier, "SplitRouting", NULL);
+ /* fall through */
+ case CONNMAN_SERVICE_TYPE_WIFI:
+ case CONNMAN_SERVICE_TYPE_GADGET:
+ case CONNMAN_SERVICE_TYPE_BLUETOOTH:
+ case CONNMAN_SERVICE_TYPE_CELLULAR:
+ case CONNMAN_SERVICE_TYPE_ETHERNET:
+ autoconnect = g_key_file_get_boolean(keyfile,
+ service->identifier, "AutoConnect", &error);
+ if (!error)
+ service->autoconnect = autoconnect;
+ g_clear_error(&error);
+ break;
+ }
+
+ str = g_key_file_get_string(keyfile,
+ service->identifier, "Modified", NULL);
+ if (str) {
+ g_time_val_from_iso8601(str, &service->modified);
+ g_free(str);
+ }
+
+ g_key_file_free(keyfile);
+
+ return 0;
+}
+
static int service_load(struct connman_service *service)
{
GKeyFile *keyfile;
GError *error = NULL;
gsize length;
gchar *str;
- connman_bool_t autoconnect;
+ bool autoconnect;
unsigned int ssid_len;
int err = 0;
DBG("service %p", service);
keyfile = connman_storage_load_service(service->identifier);
- if (keyfile == NULL) {
- service->new_service = TRUE;
+ if (!keyfile) {
+ service->new_service = true;
return -EIO;
} else
- service->new_service = FALSE;
+ service->new_service = false;
switch (service->type) {
case CONNMAN_SERVICE_TYPE_UNKNOWN:
case CONNMAN_SERVICE_TYPE_SYSTEM:
case CONNMAN_SERVICE_TYPE_GPS:
- case CONNMAN_SERVICE_TYPE_GADGET:
+ case CONNMAN_SERVICE_TYPE_P2P:
break;
case CONNMAN_SERVICE_TYPE_VPN:
service->do_split_routing = g_key_file_get_boolean(keyfile,
service->identifier, "SplitRouting", NULL);
+ autoconnect = g_key_file_get_boolean(keyfile,
+ service->identifier, "AutoConnect", &error);
+ if (!error)
+ service->autoconnect = autoconnect;
+ g_clear_error(&error);
break;
case CONNMAN_SERVICE_TYPE_WIFI:
- if (service->name == NULL) {
+ if (!service->name) {
gchar *name;
name = g_key_file_get_string(keyfile,
service->identifier, "Name", NULL);
- if (name != NULL) {
+ if (name) {
g_free(service->name);
service->name = name;
}
- if (service->network != NULL)
+ if (service->network)
connman_network_set_name(service->network,
name);
}
if (service->network &&
- connman_network_get_blob(service->network,
- "WiFi.SSID", &ssid_len) == NULL) {
+ !connman_network_get_blob(service->network,
+ "WiFi.SSID", &ssid_len)) {
gchar *hex_ssid;
hex_ssid = g_key_file_get_string(keyfile,
service->identifier,
"SSID", NULL);
- if (hex_ssid != NULL) {
+ if (hex_ssid) {
gchar *ssid;
unsigned int i, j = 0, hex;
size_t hex_ssid_len = strlen(hex_ssid);
ssid = g_try_malloc0(hex_ssid_len / 2);
- if (ssid == NULL) {
+ if (!ssid) {
g_free(hex_ssid);
err = -ENOMEM;
goto done;
@@ -400,6 +474,7 @@ static int service_load(struct connman_service *service)
}
/* fall through */
+ case CONNMAN_SERVICE_TYPE_GADGET:
case CONNMAN_SERVICE_TYPE_BLUETOOTH:
case CONNMAN_SERVICE_TYPE_CELLULAR:
service->favorite = g_key_file_get_boolean(keyfile,
@@ -407,8 +482,8 @@ static int service_load(struct connman_service *service)
str = g_key_file_get_string(keyfile,
service->identifier, "Failure", NULL);
- if (str != NULL) {
- if (service->favorite == FALSE)
+ if (str) {
+ if (!service->favorite)
service->state_ipv4 = service->state_ipv6 =
CONNMAN_SERVICE_STATE_FAILURE;
service->error = string2error(str);
@@ -419,7 +494,7 @@ static int service_load(struct connman_service *service)
case CONNMAN_SERVICE_TYPE_ETHERNET:
autoconnect = g_key_file_get_boolean(keyfile,
service->identifier, "AutoConnect", &error);
- if (error == NULL)
+ if (!error)
service->autoconnect = autoconnect;
g_clear_error(&error);
break;
@@ -427,71 +502,71 @@ static int service_load(struct connman_service *service)
str = g_key_file_get_string(keyfile,
service->identifier, "Modified", NULL);
- if (str != NULL) {
+ if (str) {
g_time_val_from_iso8601(str, &service->modified);
g_free(str);
}
str = g_key_file_get_string(keyfile,
service->identifier, "Passphrase", NULL);
- if (str != NULL) {
+ if (str) {
g_free(service->passphrase);
service->passphrase = str;
}
- if (service->ipconfig_ipv4 != NULL)
+ if (service->ipconfig_ipv4)
__connman_ipconfig_load(service->ipconfig_ipv4, keyfile,
service->identifier, "IPv4.");
- if (service->ipconfig_ipv6 != NULL)
+ if (service->ipconfig_ipv6)
__connman_ipconfig_load(service->ipconfig_ipv6, keyfile,
service->identifier, "IPv6.");
service->nameservers_config = g_key_file_get_string_list(keyfile,
service->identifier, "Nameservers", &length, NULL);
- if (service->nameservers_config != NULL && length == 0) {
+ if (service->nameservers_config && length == 0) {
g_strfreev(service->nameservers_config);
service->nameservers_config = NULL;
}
service->timeservers_config = g_key_file_get_string_list(keyfile,
service->identifier, "Timeservers", &length, NULL);
- if (service->timeservers_config != NULL && length == 0) {
+ if (service->timeservers_config && length == 0) {
g_strfreev(service->timeservers_config);
service->timeservers_config = NULL;
}
service->domains = g_key_file_get_string_list(keyfile,
service->identifier, "Domains", &length, NULL);
- if (service->domains != NULL && length == 0) {
+ if (service->domains && length == 0) {
g_strfreev(service->domains);
service->domains = NULL;
}
str = g_key_file_get_string(keyfile,
service->identifier, "Proxy.Method", NULL);
- if (str != NULL)
+ if (str)
service->proxy_config = string2proxymethod(str);
g_free(str);
service->proxies = g_key_file_get_string_list(keyfile,
service->identifier, "Proxy.Servers", &length, NULL);
- if (service->proxies != NULL && length == 0) {
+ if (service->proxies && length == 0) {
g_strfreev(service->proxies);
service->proxies = NULL;
}
service->excludes = g_key_file_get_string_list(keyfile,
service->identifier, "Proxy.Excludes", &length, NULL);
- if (service->excludes != NULL && length == 0) {
+ if (service->excludes && length == 0) {
g_strfreev(service->excludes);
service->excludes = NULL;
}
str = g_key_file_get_string(keyfile,
service->identifier, "Proxy.URL", NULL);
- if (str != NULL) {
+ if (str) {
g_free(service->pac);
service->pac = str;
}
@@ -515,14 +590,14 @@ static int service_save(struct connman_service *service)
DBG("service %p new %d", service, service->new_service);
- if (service->new_service == TRUE)
+ if (service->new_service)
return -ESRCH;
keyfile = __connman_storage_open_service(service->identifier);
- if (keyfile == NULL)
+ if (!keyfile)
return -EIO;
- if (service->name != NULL)
+ if (service->name)
g_key_file_set_string(keyfile, service->identifier,
"Name", service->name);
@@ -530,11 +605,14 @@ static int service_save(struct connman_service *service)
case CONNMAN_SERVICE_TYPE_UNKNOWN:
case CONNMAN_SERVICE_TYPE_SYSTEM:
case CONNMAN_SERVICE_TYPE_GPS:
- case CONNMAN_SERVICE_TYPE_GADGET:
+ case CONNMAN_SERVICE_TYPE_P2P:
break;
case CONNMAN_SERVICE_TYPE_VPN:
g_key_file_set_boolean(keyfile, service->identifier,
"SplitRouting", service->do_split_routing);
+ if (service->favorite)
+ g_key_file_set_boolean(keyfile, service->identifier,
+ "AutoConnect", service->autoconnect);
break;
case CONNMAN_SERVICE_TYPE_WIFI:
if (service->network) {
@@ -544,13 +622,13 @@ static int service_save(struct connman_service *service)
ssid = connman_network_get_blob(service->network,
"WiFi.SSID", &ssid_len);
- if (ssid != NULL && ssid_len > 0 && ssid[0] != '\0') {
+ if (ssid && ssid_len > 0 && ssid[0] != '\0') {
char *identifier = service->identifier;
GString *ssid_str;
unsigned int i;
ssid_str = g_string_sized_new(ssid_len * 2);
- if (ssid_str == NULL) {
+ if (!ssid_str) {
err = -ENOMEM;
goto done;
}
@@ -571,6 +649,7 @@ static int service_save(struct connman_service *service)
}
/* fall through */
+ case CONNMAN_SERVICE_TYPE_GADGET:
case CONNMAN_SERVICE_TYPE_BLUETOOTH:
case CONNMAN_SERVICE_TYPE_CELLULAR:
g_key_file_set_boolean(keyfile, service->identifier,
@@ -579,7 +658,7 @@ static int service_save(struct connman_service *service)
if (service->state_ipv4 == CONNMAN_SERVICE_STATE_FAILURE ||
service->state_ipv6 == CONNMAN_SERVICE_STATE_FAILURE) {
const char *failure = error2string(service->error);
- if (failure != NULL)
+ if (failure)
g_key_file_set_string(keyfile,
service->identifier,
"Failure", failure);
@@ -590,35 +669,35 @@ static int service_save(struct connman_service *service)
/* fall through */
case CONNMAN_SERVICE_TYPE_ETHERNET:
- if (service->favorite == TRUE)
+ if (service->favorite)
g_key_file_set_boolean(keyfile, service->identifier,
"AutoConnect", service->autoconnect);
break;
}
str = g_time_val_to_iso8601(&service->modified);
- if (str != NULL) {
+ if (str) {
g_key_file_set_string(keyfile, service->identifier,
"Modified", str);
g_free(str);
}
- if (service->passphrase != NULL && strlen(service->passphrase) > 0)
+ if (service->passphrase && strlen(service->passphrase) > 0)
g_key_file_set_string(keyfile, service->identifier,
"Passphrase", service->passphrase);
else
g_key_file_remove_key(keyfile, service->identifier,
"Passphrase", NULL);
- if (service->ipconfig_ipv4 != NULL)
+ if (service->ipconfig_ipv4)
__connman_ipconfig_save(service->ipconfig_ipv4, keyfile,
service->identifier, "IPv4.");
- if (service->ipconfig_ipv6 != NULL)
+ if (service->ipconfig_ipv6)
__connman_ipconfig_save(service->ipconfig_ipv6, keyfile,
service->identifier, "IPv6.");
- if (service->nameservers_config != NULL) {
+ if (service->nameservers_config) {
guint len = g_strv_length(service->nameservers_config);
g_key_file_set_string_list(keyfile, service->identifier,
@@ -628,7 +707,7 @@ static int service_save(struct connman_service *service)
g_key_file_remove_key(keyfile, service->identifier,
"Nameservers", NULL);
- if (service->timeservers_config != NULL) {
+ if (service->timeservers_config) {
guint len = g_strv_length(service->timeservers_config);
g_key_file_set_string_list(keyfile, service->identifier,
@@ -638,7 +717,7 @@ static int service_save(struct connman_service *service)
g_key_file_remove_key(keyfile, service->identifier,
"Timeservers", NULL);
- if (service->domains != NULL) {
+ if (service->domains) {
guint len = g_strv_length(service->domains);
g_key_file_set_string_list(keyfile, service->identifier,
@@ -649,11 +728,11 @@ static int service_save(struct connman_service *service)
"Domains", NULL);
cst_str = proxymethod2string(service->proxy_config);
- if (cst_str != NULL)
+ if (cst_str)
g_key_file_set_string(keyfile, service->identifier,
"Proxy.Method", cst_str);
- if (service->proxies != NULL) {
+ if (service->proxies) {
guint len = g_strv_length(service->proxies);
g_key_file_set_string_list(keyfile, service->identifier,
@@ -663,7 +742,7 @@ static int service_save(struct connman_service *service)
g_key_file_remove_key(keyfile, service->identifier,
"Proxy.Servers", NULL);
- if (service->excludes != NULL) {
+ if (service->excludes) {
guint len = g_strv_length(service->excludes);
g_key_file_set_string_list(keyfile, service->identifier,
@@ -673,22 +752,22 @@ static int service_save(struct connman_service *service)
g_key_file_remove_key(keyfile, service->identifier,
"Proxy.Excludes", NULL);
- if (service->pac != NULL && strlen(service->pac) > 0)
+ if (service->pac && strlen(service->pac) > 0)
g_key_file_set_string(keyfile, service->identifier,
"Proxy.URL", service->pac);
else
g_key_file_remove_key(keyfile, service->identifier,
"Proxy.URL", NULL);
- if (service->hidden_service == TRUE)
+ if (service->hidden_service)
g_key_file_set_boolean(keyfile, service->identifier, "Hidden",
TRUE);
- if (service->config_file != NULL && strlen(service->config_file) > 0)
+ if (service->config_file && strlen(service->config_file) > 0)
g_key_file_set_string(keyfile, service->identifier,
"Config.file", service->config_file);
- if (service->config_entry != NULL &&
+ if (service->config_entry &&
strlen(service->config_entry) > 0)
g_key_file_set_string(keyfile, service->identifier,
"Config.ident", service->config_entry);
@@ -703,6 +782,9 @@ done:
void __connman_service_save(struct connman_service *service)
{
+ if (!service)
+ return;
+
service_save(service);
}
@@ -793,14 +875,14 @@ done:
return result;
}
-static connman_bool_t is_connecting_state(struct connman_service *service,
+static bool is_connecting_state(struct connman_service *service,
enum connman_service_state state)
{
switch (state) {
case CONNMAN_SERVICE_STATE_UNKNOWN:
case CONNMAN_SERVICE_STATE_IDLE:
case CONNMAN_SERVICE_STATE_FAILURE:
- if (service->network != NULL)
+ if (service->network)
return connman_network_get_connecting(service->network);
case CONNMAN_SERVICE_STATE_DISCONNECT:
case CONNMAN_SERVICE_STATE_READY:
@@ -808,13 +890,13 @@ static connman_bool_t is_connecting_state(struct connman_service *service,
break;
case CONNMAN_SERVICE_STATE_ASSOCIATION:
case CONNMAN_SERVICE_STATE_CONFIGURATION:
- return TRUE;
+ return true;
}
- return FALSE;
+ return false;
}
-static connman_bool_t is_connected_state(const struct connman_service *service,
+static bool is_connected_state(const struct connman_service *service,
enum connman_service_state state)
{
switch (state) {
@@ -827,13 +909,13 @@ static connman_bool_t is_connected_state(const struct connman_service *service,
break;
case CONNMAN_SERVICE_STATE_READY:
case CONNMAN_SERVICE_STATE_ONLINE:
- return TRUE;
+ return true;
}
- return FALSE;
+ return false;
}
-static connman_bool_t is_idle_state(const struct connman_service *service,
+static bool is_idle_state(const struct connman_service *service,
enum connman_service_state state)
{
switch (state) {
@@ -846,31 +928,24 @@ static connman_bool_t is_idle_state(const struct connman_service *service,
case CONNMAN_SERVICE_STATE_FAILURE:
break;
case CONNMAN_SERVICE_STATE_IDLE:
- return TRUE;
+ return true;
}
- return FALSE;
+ return false;
}
-static connman_bool_t is_connecting(struct connman_service *service)
+static bool is_connecting(struct connman_service *service)
{
return is_connecting_state(service, service->state);
}
-static connman_bool_t is_connected(struct connman_service *service)
+static bool is_connected(struct connman_service *service)
{
return is_connected_state(service, service->state);
}
static int nameserver_get_index(struct connman_service *service)
{
- int index;
-
- index = __connman_service_get_index(service);
-
- if (index < 0)
- return -1;
-
switch (combine_state(service->state_ipv4, service->state_ipv6)) {
case CONNMAN_SERVICE_STATE_UNKNOWN:
case CONNMAN_SERVICE_STATE_IDLE:
@@ -884,7 +959,7 @@ static int nameserver_get_index(struct connman_service *service)
break;
}
- return index;
+ return __connman_service_get_index(service);
}
static void remove_nameservers(struct connman_service *service,
@@ -892,7 +967,7 @@ static void remove_nameservers(struct connman_service *service,
{
int i;
- if (ns == NULL)
+ if (!ns)
return;
if (index < 0)
@@ -901,7 +976,7 @@ static void remove_nameservers(struct connman_service *service,
if (index < 0)
return;
- for (i = 0; ns[i] != NULL; i++)
+ for (i = 0; ns[i]; i++)
connman_resolver_remove(index, NULL, ns[i]);
}
@@ -910,7 +985,7 @@ static void remove_searchdomains(struct connman_service *service,
{
int i;
- if (sd == NULL)
+ if (!sd)
return;
if (index < 0)
@@ -919,13 +994,29 @@ static void remove_searchdomains(struct connman_service *service,
if (index < 0)
return;
- for (i = 0; sd[i] != NULL; i++)
+ for (i = 0; sd[i]; i++)
connman_resolver_remove(index, sd[i], NULL);
}
+static bool nameserver_available(struct connman_service *service, char *ns)
+{
+ int family;
+
+ family = connman_inet_check_ipaddress(ns);
+
+ if (family == AF_INET)
+ return is_connected_state(service, service->state_ipv4);
+
+ if (family == AF_INET6)
+ return is_connected_state(service, service->state_ipv6);
+
+ return false;
+}
+
static void update_nameservers(struct connman_service *service)
{
int index;
+ char *ns;
index = __connman_service_get_index(service);
if (index < 0)
@@ -946,7 +1037,7 @@ static void update_nameservers(struct connman_service *service)
break;
}
- if (service->nameservers_config != NULL) {
+ if (service->nameservers_config) {
int i;
remove_nameservers(service, index, service->nameservers);
@@ -954,21 +1045,29 @@ static void update_nameservers(struct connman_service *service)
i = g_strv_length(service->nameservers_config);
while (i != 0) {
i--;
- connman_resolver_append(index, NULL,
- service->nameservers_config[i]);
+
+ ns = service->nameservers_config[i];
+
+ if (nameserver_available(service, ns))
+ connman_resolver_append(index, NULL, ns);
}
- } else if (service->nameservers != NULL) {
+ } else if (service->nameservers) {
int i;
+ remove_nameservers(service, index, service->nameservers);
+
i = g_strv_length(service->nameservers);
while (i != 0) {
i--;
- connman_resolver_append(index, NULL,
- service->nameservers[i]);
+
+ ns = service->nameservers[i];
+
+ if (nameserver_available(service, ns))
+ connman_resolver_append(index, NULL, ns);
}
}
- if (service->domains != NULL) {
+ if (service->domains) {
char *searchdomains[2] = {NULL, NULL};
int i;
@@ -981,7 +1080,7 @@ static void update_nameservers(struct connman_service *service)
connman_resolver_append(index, service->domains[i],
NULL);
}
- } else if (service->domainname != NULL)
+ } else if (service->domainname)
connman_resolver_append(index, service->domainname, NULL);
connman_resolver_flush();
@@ -993,26 +1092,26 @@ static void update_nameservers(struct connman_service *service)
* for details) and not through service.c
*/
int __connman_service_nameserver_append(struct connman_service *service,
- const char *nameserver, gboolean is_auto)
+ const char *nameserver, bool is_auto)
{
char **nameservers;
int len, i;
DBG("service %p nameserver %s auto %d", service, nameserver, is_auto);
- if (nameserver == NULL)
+ if (!nameserver)
return -EINVAL;
- if (is_auto == TRUE)
+ if (is_auto)
nameservers = service->nameservers_auto;
else
nameservers = service->nameservers;
- for (i = 0; nameservers != NULL && nameservers[i] != NULL; i++)
+ for (i = 0; nameservers && nameservers[i]; i++)
if (g_strcmp0(nameservers[i], nameserver) == 0)
return -EEXIST;
- if (nameservers != NULL) {
+ if (nameservers) {
len = g_strv_length(nameservers);
nameservers = g_try_renew(char *, nameservers, len + 2);
} else {
@@ -1020,16 +1119,16 @@ int __connman_service_nameserver_append(struct connman_service *service,
nameservers = g_try_new0(char *, len + 2);
}
- if (nameservers == NULL)
+ if (!nameservers)
return -ENOMEM;
nameservers[len] = g_strdup(nameserver);
- if (nameservers[len] == NULL)
+ if (!nameservers[len])
return -ENOMEM;
nameservers[len + 1] = NULL;
- if (is_auto == TRUE) {
+ if (is_auto) {
service->nameservers_auto = nameservers;
} else {
service->nameservers = nameservers;
@@ -1040,39 +1139,39 @@ int __connman_service_nameserver_append(struct connman_service *service,
}
int __connman_service_nameserver_remove(struct connman_service *service,
- const char *nameserver, gboolean is_auto)
+ const char *nameserver, bool is_auto)
{
char **servers, **nameservers;
- gboolean found = FALSE;
+ bool found = false;
int len, i, j;
DBG("service %p nameserver %s auto %d", service, nameserver, is_auto);
- if (nameserver == NULL)
+ if (!nameserver)
return -EINVAL;
- if (is_auto == TRUE)
+ if (is_auto)
nameservers = service->nameservers_auto;
else
nameservers = service->nameservers;
- if (nameservers == NULL)
+ if (!nameservers)
return 0;
- for (i = 0; nameservers != NULL && nameservers[i] != NULL; i++)
+ for (i = 0; nameservers && nameservers[i]; i++)
if (g_strcmp0(nameservers[i], nameserver) == 0) {
- found = TRUE;
+ found = true;
break;
}
- if (found == FALSE)
+ if (!found)
return 0;
len = g_strv_length(nameservers);
if (len == 1) {
g_strfreev(nameservers);
- if (is_auto == TRUE)
+ if (is_auto)
service->nameservers_auto = NULL;
else
service->nameservers = NULL;
@@ -1081,13 +1180,13 @@ int __connman_service_nameserver_remove(struct connman_service *service,
}
servers = g_try_new0(char *, len);
- if (servers == NULL)
+ if (!servers)
return -ENOMEM;
for (i = 0, j = 0; i < len; i++) {
if (g_strcmp0(nameservers[i], nameserver) != 0) {
servers[j] = g_strdup(nameservers[i]);
- if (servers[j] == NULL)
+ if (!servers[j])
return -ENOMEM;
j++;
}
@@ -1097,7 +1196,7 @@ int __connman_service_nameserver_remove(struct connman_service *service,
g_strfreev(nameservers);
nameservers = servers;
- if (is_auto == TRUE) {
+ if (is_auto) {
service->nameservers_auto = nameservers;
} else {
service->nameservers = nameservers;
@@ -1120,7 +1219,7 @@ static void add_nameserver_route(int family, int index, char *nameserver,
{
switch (family) {
case AF_INET:
- if (connman_inet_compare_subnet(index, nameserver) == TRUE)
+ if (connman_inet_compare_subnet(index, nameserver))
break;
if (connman_inet_add_host_route(index, nameserver, gw) < 0)
@@ -1142,7 +1241,7 @@ static void nameserver_add_routes(int index, char **nameservers,
{
int i, family;
- for (i = 0; nameservers[i] != NULL; i++) {
+ for (i = 0; nameservers[i]; i++) {
family = connman_inet_check_ipaddress(nameservers[i]);
if (family < 0)
continue;
@@ -1156,7 +1255,7 @@ static void nameserver_del_routes(int index, char **nameservers,
{
int i, family;
- for (i = 0; nameservers[i] != NULL; i++) {
+ for (i = 0; nameservers[i]; i++) {
family = connman_inet_check_ipaddress(nameservers[i]);
if (family < 0)
continue;
@@ -1179,23 +1278,20 @@ static void nameserver_del_routes(int index, char **nameservers,
void __connman_service_nameserver_add_routes(struct connman_service *service,
const char *gw)
{
- int index = -1;
+ int index;
- if (service == NULL)
+ if (!service)
return;
- if (service->network != NULL)
- index = connman_network_get_index(service->network);
- else if (service->provider != NULL)
- index = connman_provider_get_index(service->provider);
+ index = __connman_service_get_index(service);
- if (service->nameservers_config != NULL) {
+ if (service->nameservers_config) {
/*
* Configured nameserver takes preference over the
* discoverd nameserver gathered from DHCP, VPN, etc.
*/
nameserver_add_routes(index, service->nameservers_config, gw);
- } else if (service->nameservers != NULL) {
+ } else if (service->nameservers) {
/*
* We add nameservers host routes for nameservers that
* are not on our subnet. For those who are, the subnet
@@ -1210,32 +1306,29 @@ void __connman_service_nameserver_add_routes(struct connman_service *service,
void __connman_service_nameserver_del_routes(struct connman_service *service,
enum connman_ipconfig_type type)
{
- int index = -1;
+ int index;
- if (service == NULL)
+ if (!service)
return;
- if (service->network != NULL)
- index = connman_network_get_index(service->network);
- else if (service->provider != NULL)
- index = connman_provider_get_index(service->provider);
+ index = __connman_service_get_index(service);
- if (service->nameservers_config != NULL)
+ if (service->nameservers_config)
nameserver_del_routes(index, service->nameservers_config,
type);
- else if (service->nameservers != NULL)
+ else if (service->nameservers)
nameserver_del_routes(index, service->nameservers, type);
}
static struct connman_stats *stats_get(struct connman_service *service)
{
- if (service->roaming == TRUE)
+ if (service->roaming)
return &service->stats_roaming;
else
return &service->stats;
}
-static connman_bool_t stats_enabled(struct connman_service *service)
+static bool stats_enabled(struct connman_service *service)
{
struct connman_stats *stats = stats_get(service);
@@ -1248,10 +1341,10 @@ static void stats_start(struct connman_service *service)
DBG("service %p", service);
- if (stats->timer == NULL)
+ if (!stats->timer)
return;
- stats->enabled = TRUE;
+ stats->enabled = true;
stats->data_last.time = stats->data.time;
g_timer_start(stats->timer);
@@ -1264,10 +1357,10 @@ static void stats_stop(struct connman_service *service)
DBG("service %p", service);
- if (stats->timer == NULL)
+ if (!stats->timer)
return;
- if (stats->enabled == FALSE)
+ if (!stats->enabled)
return;
g_timer_stop(stats->timer);
@@ -1275,7 +1368,7 @@ static void stats_stop(struct connman_service *service)
seconds = g_timer_elapsed(stats->timer, NULL);
stats->data.time = stats->data_last.time + seconds;
- stats->enabled = FALSE;
+ stats->enabled = false;
}
static void reset_stats(struct connman_service *service)
@@ -1283,7 +1376,7 @@ static void reset_stats(struct connman_service *service)
DBG("service %p", service);
/* home */
- service->stats.valid = FALSE;
+ service->stats.valid = false;
service->stats.data.rx_packets = 0;
service->stats.data.tx_packets = 0;
@@ -1299,7 +1392,7 @@ static void reset_stats(struct connman_service *service)
g_timer_reset(service->stats.timer);
/* roaming */
- service->stats_roaming.valid = FALSE;
+ service->stats_roaming.valid = false;
service->stats_roaming.data.rx_packets = 0;
service->stats_roaming.data.tx_packets = 0;
@@ -1319,17 +1412,29 @@ struct connman_service *__connman_service_get_default(void)
{
struct connman_service *service;
- if (service_list == NULL)
+ if (!service_list)
return NULL;
service = service_list->data;
- if (is_connected(service) == FALSE)
+ if (!is_connected(service))
return NULL;
return service;
}
+bool __connman_service_index_is_default(int index)
+{
+ struct connman_service *service;
+
+ if (index < 0)
+ return false;
+
+ service = __connman_service_get_default();
+
+ return __connman_service_get_index(service) == index;
+}
+
static void default_changed(void)
{
struct connman_service *service = __connman_service_get_default();
@@ -1337,10 +1442,23 @@ static void default_changed(void)
if (service == current_default)
return;
+ DBG("current default %p %s", current_default,
+ current_default ? current_default->identifier : "");
+ DBG("new default %p %s", service, service ? service->identifier : "");
+
__connman_service_timeserver_changed(current_default, NULL);
current_default = service;
+ if (service) {
+ if (service->hostname &&
+ connman_setting_get_bool("AllowHostnameUpdates"))
+ __connman_utsname_set_hostname(service->hostname);
+
+ if (service->domainname)
+ __connman_utsname_set_domainname(service->domainname);
+ }
+
__connman_notifier_default_changed(service);
}
@@ -1351,10 +1469,10 @@ static void state_changed(struct connman_service *service)
__connman_notifier_service_state_changed(service, service->state);
str = state2string(service->state);
- if (str == NULL)
+ if (!str)
return;
- if (allow_property_changed(service) == FALSE)
+ if (!allow_property_changed(service))
return;
connman_dbus_property_changed_basic(service->path,
@@ -1367,7 +1485,7 @@ static void strength_changed(struct connman_service *service)
if (service->strength == 0)
return;
- if (allow_property_changed(service) == FALSE)
+ if (!allow_property_changed(service))
return;
connman_dbus_property_changed_basic(service->path,
@@ -1377,54 +1495,66 @@ static void strength_changed(struct connman_service *service)
static void favorite_changed(struct connman_service *service)
{
- if (service->path == NULL)
+ dbus_bool_t favorite;
+
+ if (!service->path)
return;
- if (allow_property_changed(service) == FALSE)
+ if (!allow_property_changed(service))
return;
+ favorite = service->favorite;
connman_dbus_property_changed_basic(service->path,
CONNMAN_SERVICE_INTERFACE, "Favorite",
- DBUS_TYPE_BOOLEAN, &service->favorite);
+ DBUS_TYPE_BOOLEAN, &favorite);
}
static void immutable_changed(struct connman_service *service)
{
- if (service->path == NULL)
+ dbus_bool_t immutable;
+
+ if (!service->path)
return;
- if (allow_property_changed(service) == FALSE)
+ if (!allow_property_changed(service))
return;
+ immutable = service->immutable;
connman_dbus_property_changed_basic(service->path,
CONNMAN_SERVICE_INTERFACE, "Immutable",
- DBUS_TYPE_BOOLEAN, &service->immutable);
+ DBUS_TYPE_BOOLEAN, &immutable);
}
static void roaming_changed(struct connman_service *service)
{
- if (service->path == NULL)
+ dbus_bool_t roaming;
+
+ if (!service->path)
return;
- if (allow_property_changed(service) == FALSE)
+ if (!allow_property_changed(service))
return;
+ roaming = service->roaming;
connman_dbus_property_changed_basic(service->path,
CONNMAN_SERVICE_INTERFACE, "Roaming",
- DBUS_TYPE_BOOLEAN, &service->roaming);
+ DBUS_TYPE_BOOLEAN, &roaming);
}
static void autoconnect_changed(struct connman_service *service)
{
- if (service->path == NULL)
+ dbus_bool_t autoconnect;
+
+ if (!service->path)
return;
- if (allow_property_changed(service) == FALSE)
+ if (!allow_property_changed(service))
return;
+ autoconnect = service->autoconnect;
connman_dbus_property_changed_basic(service->path,
CONNMAN_SERVICE_INTERFACE, "AutoConnect",
- DBUS_TYPE_BOOLEAN, &service->autoconnect);
+ DBUS_TYPE_BOOLEAN, &autoconnect);
}
static void append_security(DBusMessageIter *iter, void *user_data)
@@ -1433,7 +1563,7 @@ static void append_security(DBusMessageIter *iter, void *user_data)
const char *str;
str = security2string(service->security);
- if (str != NULL)
+ if (str)
dbus_message_iter_append_basic(iter,
DBUS_TYPE_STRING, &str);
@@ -1442,14 +1572,14 @@ static void append_security(DBusMessageIter *iter, void *user_data)
* are configured as open or no security, so filter
* appropriately.
*/
- if (service->wps == TRUE) {
+ if (service->wps) {
switch (service->security) {
case CONNMAN_SERVICE_SECURITY_PSK:
case CONNMAN_SERVICE_SECURITY_WPA:
case CONNMAN_SERVICE_SECURITY_RSN:
str = "wps";
dbus_message_iter_append_basic(iter,
- DBUS_TYPE_STRING, &str);
+ DBUS_TYPE_STRING, &str);
break;
case CONNMAN_SERVICE_SECURITY_UNKNOWN:
case CONNMAN_SERVICE_SECURITY_NONE:
@@ -1464,10 +1594,10 @@ static void append_ethernet(DBusMessageIter *iter, void *user_data)
{
struct connman_service *service = user_data;
- if (service->ipconfig_ipv4 != NULL)
+ if (service->ipconfig_ipv4)
__connman_ipconfig_append_ethernet(service->ipconfig_ipv4,
iter);
- else if (service->ipconfig_ipv6 != NULL)
+ else if (service->ipconfig_ipv6)
__connman_ipconfig_append_ethernet(service->ipconfig_ipv6,
iter);
}
@@ -1476,13 +1606,10 @@ static void append_ipv4(DBusMessageIter *iter, void *user_data)
{
struct connman_service *service = user_data;
- DBG("ipv4 %p state %s", service->ipconfig_ipv4,
- state2string(service->state_ipv4));
-
- if (is_connected_state(service, service->state_ipv4) == FALSE)
+ if (!is_connected_state(service, service->state_ipv4))
return;
- if (service->ipconfig_ipv4 != NULL)
+ if (service->ipconfig_ipv4)
__connman_ipconfig_append_ipv4(service->ipconfig_ipv4, iter);
}
@@ -1490,13 +1617,10 @@ static void append_ipv6(DBusMessageIter *iter, void *user_data)
{
struct connman_service *service = user_data;
- DBG("ipv6 %p state %s", service->ipconfig_ipv6,
- state2string(service->state_ipv6));
-
- if (is_connected_state(service, service->state_ipv6) == FALSE)
+ if (!is_connected_state(service, service->state_ipv6))
return;
- if (service->ipconfig_ipv6 != NULL)
+ if (service->ipconfig_ipv6)
__connman_ipconfig_append_ipv6(service->ipconfig_ipv6, iter,
service->ipconfig_ipv4);
}
@@ -1505,7 +1629,7 @@ static void append_ipv4config(DBusMessageIter *iter, void *user_data)
{
struct connman_service *service = user_data;
- if (service->ipconfig_ipv4 != NULL)
+ if (service->ipconfig_ipv4)
__connman_ipconfig_append_ipv4config(service->ipconfig_ipv4,
iter);
}
@@ -1514,20 +1638,25 @@ static void append_ipv6config(DBusMessageIter *iter, void *user_data)
{
struct connman_service *service = user_data;
- if (service->ipconfig_ipv6 != NULL)
+ if (service->ipconfig_ipv6)
__connman_ipconfig_append_ipv6config(service->ipconfig_ipv6,
iter);
}
-static void append_nameservers(DBusMessageIter *iter, char **servers)
+static void append_nameservers(DBusMessageIter *iter,
+ struct connman_service *service, char **servers)
{
int i;
+ bool available = true;
- DBG("%p", servers);
+ for (i = 0; servers[i]; i++) {
+ if (service)
+ available = nameserver_available(service, servers[i]);
- for (i = 0; servers[i] != NULL; i++) {
- DBG("servers[%d] %s", i, servers[i]);
- dbus_message_iter_append_basic(iter,
+ DBG("servers[%d] %s available %d", i, servers[i], available);
+
+ if (available)
+ dbus_message_iter_append_basic(iter,
DBUS_TYPE_STRING, &servers[i]);
}
}
@@ -1536,18 +1665,30 @@ static void append_dns(DBusMessageIter *iter, void *user_data)
{
struct connman_service *service = user_data;
- if (is_connected(service) == FALSE)
+ if (!is_connected(service))
return;
- if (service->nameservers_config != NULL) {
- append_nameservers(iter, service->nameservers_config);
+ if (service->nameservers_config) {
+ append_nameservers(iter, service, service->nameservers_config);
return;
} else {
- if (service->nameservers != NULL)
- append_nameservers(iter, service->nameservers);
+ if (service->nameservers)
+ append_nameservers(iter, service,
+ service->nameservers);
+
+ if (service->nameservers_auto)
+ append_nameservers(iter, service,
+ service->nameservers_auto);
+
+ if (!service->nameservers && !service->nameservers_auto) {
+ char **ns;
- if (service->nameservers_auto != NULL)
- append_nameservers(iter, service->nameservers_auto);
+ DBG("append fallback nameservers");
+
+ ns = connman_setting_get_string_list("FallbackNameservers");
+ if (ns)
+ append_nameservers(iter, service, ns);
+ }
}
}
@@ -1555,20 +1696,20 @@ static void append_dnsconfig(DBusMessageIter *iter, void *user_data)
{
struct connman_service *service = user_data;
- if (service->nameservers_config == NULL)
+ if (!service->nameservers_config)
return;
- append_nameservers(iter, service->nameservers_config);
+ append_nameservers(iter, NULL, service->nameservers_config);
}
static void append_ts(DBusMessageIter *iter, void *user_data)
{
GSList *list = user_data;
- while (list != NULL) {
+ while (list) {
char *timeserver = list->data;
- if (timeserver != NULL)
+ if (timeserver)
dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING,
&timeserver);
@@ -1581,7 +1722,7 @@ static void append_tsconfig(DBusMessageIter *iter, void *user_data)
struct connman_service *service = user_data;
int i;
- if (service->timeservers_config == NULL)
+ if (!service->timeservers_config)
return;
for (i = 0; service->timeservers_config[i]; i++) {
@@ -1596,7 +1737,7 @@ static void append_domainconfig(DBusMessageIter *iter, void *user_data)
struct connman_service *service = user_data;
int i;
- if (service->domains == NULL)
+ if (!service->domains)
return;
for (i = 0; service->domains[i]; i++)
@@ -1608,13 +1749,13 @@ static void append_domain(DBusMessageIter *iter, void *user_data)
{
struct connman_service *service = user_data;
- if (is_connected(service) == FALSE &&
- is_connecting(service) == FALSE)
+ if (!is_connected(service) &&
+ !is_connecting(service))
return;
- if (service->domains != NULL)
+ if (service->domains)
append_domainconfig(iter, user_data);
- else if (service->domainname != NULL)
+ else if (service->domainname)
dbus_message_iter_append_basic(iter,
DBUS_TYPE_STRING, &service->domainname);
}
@@ -1624,7 +1765,7 @@ static void append_proxies(DBusMessageIter *iter, void *user_data)
struct connman_service *service = user_data;
int i;
- if (service->proxies == NULL)
+ if (!service->proxies)
return;
for (i = 0; service->proxies[i]; i++)
@@ -1637,7 +1778,7 @@ static void append_excludes(DBusMessageIter *iter, void *user_data)
struct connman_service *service = user_data;
int i;
- if (service->excludes == NULL)
+ if (!service->excludes)
return;
for (i = 0; service->excludes[i]; i++)
@@ -1653,9 +1794,7 @@ static void append_proxy(DBusMessageIter *iter, void *user_data)
const char *method = proxymethod2string(
CONNMAN_SERVICE_PROXY_METHOD_DIRECT);
- DBG("");
-
- if (is_connected(service) == FALSE)
+ if (!is_connected(service))
return;
proxy = connman_service_get_proxy_method(service);
@@ -1676,17 +1815,17 @@ static void append_proxy(DBusMessageIter *iter, void *user_data)
break;
case CONNMAN_SERVICE_PROXY_METHOD_AUTO:
/* Maybe DHCP, or WPAD, has provided an url for a pac file */
- if (service->ipconfig_ipv4 != NULL)
+ if (service->ipconfig_ipv4)
pac = __connman_ipconfig_get_proxy_autoconfig(
service->ipconfig_ipv4);
- else if (service->ipconfig_ipv6 != NULL)
+ else if (service->ipconfig_ipv6)
pac = __connman_ipconfig_get_proxy_autoconfig(
service->ipconfig_ipv6);
- if (service->pac == NULL && pac == NULL)
+ if (!service->pac && !pac)
goto done;
- if (service->pac != NULL)
+ if (service->pac)
pac = service->pac;
connman_dbus_dict_append_basic(iter, "URL",
@@ -1715,18 +1854,18 @@ static void append_proxyconfig(DBusMessageIter *iter, void *user_data)
case CONNMAN_SERVICE_PROXY_METHOD_DIRECT:
break;
case CONNMAN_SERVICE_PROXY_METHOD_MANUAL:
- if (service->proxies != NULL)
+ if (service->proxies)
connman_dbus_dict_append_array(iter, "Servers",
DBUS_TYPE_STRING,
append_proxies, service);
- if (service->excludes != NULL)
+ if (service->excludes)
connman_dbus_dict_append_array(iter, "Excludes",
DBUS_TYPE_STRING,
append_excludes, service);
break;
case CONNMAN_SERVICE_PROXY_METHOD_AUTO:
- if (service->pac != NULL)
+ if (service->pac)
connman_dbus_dict_append_basic(iter, "URL",
DBUS_TYPE_STRING, &service->pac);
break;
@@ -1742,12 +1881,10 @@ static void append_provider(DBusMessageIter *iter, void *user_data)
{
struct connman_service *service = user_data;
- DBG("%p %p", service, service->provider);
-
- if (is_connected(service) == FALSE)
+ if (!is_connected(service))
return;
- if (service->provider != NULL)
+ if (service->provider)
__connman_provider_append_properties(service->provider, iter);
}
@@ -1757,7 +1894,7 @@ static void settings_changed(struct connman_service *service,
{
enum connman_ipconfig_type type;
- if (allow_property_changed(service) == FALSE)
+ if (!allow_property_changed(service))
return;
type = __connman_ipconfig_get_config_type(ipconfig);
@@ -1776,7 +1913,7 @@ static void settings_changed(struct connman_service *service,
static void ipv4_configuration_changed(struct connman_service *service)
{
- if (allow_property_changed(service) == FALSE)
+ if (!allow_property_changed(service))
return;
connman_dbus_property_changed_dict(service->path,
@@ -1788,7 +1925,7 @@ static void ipv4_configuration_changed(struct connman_service *service)
static void ipv6_configuration_changed(struct connman_service *service)
{
- if (allow_property_changed(service) == FALSE)
+ if (!allow_property_changed(service))
return;
connman_dbus_property_changed_dict(service->path,
@@ -1800,7 +1937,7 @@ static void ipv6_configuration_changed(struct connman_service *service)
static void dns_changed(struct connman_service *service)
{
- if (allow_property_changed(service) == FALSE)
+ if (!allow_property_changed(service))
return;
connman_dbus_property_changed_array(service->path,
@@ -1810,7 +1947,7 @@ static void dns_changed(struct connman_service *service)
static void dns_configuration_changed(struct connman_service *service)
{
- if (allow_property_changed(service) == FALSE)
+ if (!allow_property_changed(service))
return;
connman_dbus_property_changed_array(service->path,
@@ -1823,7 +1960,7 @@ static void dns_configuration_changed(struct connman_service *service)
static void domain_changed(struct connman_service *service)
{
- if (allow_property_changed(service) == FALSE)
+ if (!allow_property_changed(service))
return;
connman_dbus_property_changed_array(service->path,
@@ -1833,7 +1970,7 @@ static void domain_changed(struct connman_service *service)
static void domain_configuration_changed(struct connman_service *service)
{
- if (allow_property_changed(service) == FALSE)
+ if (!allow_property_changed(service))
return;
connman_dbus_property_changed_array(service->path,
@@ -1844,7 +1981,7 @@ static void domain_configuration_changed(struct connman_service *service)
static void proxy_changed(struct connman_service *service)
{
- if (allow_property_changed(service) == FALSE)
+ if (!allow_property_changed(service))
return;
connman_dbus_property_changed_dict(service->path,
@@ -1854,7 +1991,7 @@ static void proxy_changed(struct connman_service *service)
static void proxy_configuration_changed(struct connman_service *service)
{
- if (allow_property_changed(service) == FALSE)
+ if (!allow_property_changed(service))
return;
connman_dbus_property_changed_dict(service->path,
@@ -1866,7 +2003,7 @@ static void proxy_configuration_changed(struct connman_service *service)
static void timeservers_configuration_changed(struct connman_service *service)
{
- if (allow_property_changed(service) == FALSE)
+ if (!allow_property_changed(service))
return;
connman_dbus_property_changed_array(service->path,
@@ -1878,7 +2015,7 @@ static void timeservers_configuration_changed(struct connman_service *service)
static void link_changed(struct connman_service *service)
{
- if (allow_property_changed(service) == FALSE)
+ if (!allow_property_changed(service))
return;
connman_dbus_property_changed_dict(service->path,
@@ -1889,7 +2026,7 @@ static void link_changed(struct connman_service *service)
static void stats_append_counters(DBusMessageIter *dict,
struct connman_stats_data *stats,
struct connman_stats_data *counters,
- connman_bool_t append_all)
+ bool append_all)
{
if (counters->rx_packets != stats->rx_packets || append_all) {
counters->rx_packets = stats->rx_packets;
@@ -1949,7 +2086,7 @@ static void stats_append_counters(DBusMessageIter *dict,
static void stats_append(struct connman_service *service,
const char *counter,
struct connman_stats_counter *counters,
- connman_bool_t append_all)
+ bool append_all)
{
DBusMessageIter array, dict;
DBusMessage *msg;
@@ -1957,7 +2094,7 @@ static void stats_append(struct connman_service *service,
DBG("service %p counter %s", service, counter);
msg = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_CALL);
- if (msg == NULL)
+ if (!msg)
return;
dbus_message_append_args(msg, DBUS_TYPE_OBJECT_PATH,
@@ -1997,7 +2134,7 @@ static void stats_update(struct connman_service *service,
DBG("service %p", service);
- if (stats->valid == TRUE) {
+ if (stats->valid) {
data->rx_packets +=
rx_packets - data_last->rx_packets;
data->tx_packets +=
@@ -2015,7 +2152,7 @@ static void stats_update(struct connman_service *service,
data->tx_dropped +=
tx_dropped - data_last->tx_dropped;
} else {
- stats->valid = TRUE;
+ stats->valid = true;
}
data_last->rx_packets = rx_packets;
@@ -2044,10 +2181,10 @@ void __connman_service_notify(struct connman_service *service,
struct connman_stats_data *data;
int err;
- if (service == NULL)
+ if (!service)
return;
- if (is_connected(service) == FALSE)
+ if (!is_connected(service))
return;
stats_update(service,
@@ -2068,7 +2205,7 @@ void __connman_service_notify(struct connman_service *service,
counters = value;
stats_append(service, counter, counters, counters->append_all);
- counters->append_all = FALSE;
+ counters->append_all = false;
}
}
@@ -2082,14 +2219,14 @@ int __connman_service_counter_register(const char *counter)
counter_list = g_slist_prepend(counter_list, (gpointer)counter);
- for (list = service_list; list != NULL; list = list->next) {
+ for (list = service_list; list; list = list->next) {
service = list->data;
counters = g_try_new0(struct connman_stats_counter, 1);
- if (counters == NULL)
+ if (!counters)
return -ENOMEM;
- counters->append_all = TRUE;
+ counters->append_all = true;
g_hash_table_replace(service->counter_table, (gpointer)counter,
counters);
@@ -2105,7 +2242,7 @@ void __connman_service_counter_unregister(const char *counter)
DBG("counter %s", counter);
- for (list = service_list; list != NULL; list = list->next) {
+ for (list = service_list; list; list = list->next) {
service = list->data;
g_hash_table_remove(service->counter_table, counter);
@@ -2118,42 +2255,24 @@ int __connman_service_iterate_services(service_iterate_cb cb, void *user_data)
{
GList *list;
- for (list = service_list; list != NULL; list = list->next) {
+ for (list = service_list; list; list = list->next) {
struct connman_service *service = list->data;
- cb(service, service->name, service->state, user_data);
+ cb(service, user_data);
}
return 0;
}
-void __connman_service_session_inc(struct connman_service *service)
-{
- DBG("service %p ref count %d", service,
- service->session_usage_count + 1);
-
- __sync_fetch_and_add(&service->session_usage_count, 1);
-}
-
-connman_bool_t __connman_service_session_dec(struct connman_service *service)
-{
- DBG("service %p ref count %d", service,
- service->session_usage_count - 1);
-
- if (__sync_fetch_and_sub(&service->session_usage_count, 1) != 1)
- return FALSE;
-
- return TRUE;
-}
-
static void append_properties(DBusMessageIter *dict, dbus_bool_t limited,
struct connman_service *service)
{
+ dbus_bool_t val;
const char *str;
GSList *list;
str = __connman_service_type2string(service->type);
- if (str != NULL)
+ if (str)
connman_dbus_dict_append_basic(dict, "Type",
DBUS_TYPE_STRING, &str);
@@ -2161,12 +2280,12 @@ static void append_properties(DBusMessageIter *dict, dbus_bool_t limited,
DBUS_TYPE_STRING, append_security, service);
str = state2string(service->state);
- if (str != NULL)
+ if (str)
connman_dbus_dict_append_basic(dict, "State",
DBUS_TYPE_STRING, &str);
str = error2string(service->error);
- if (str != NULL)
+ if (str)
connman_dbus_dict_append_basic(dict, "Error",
DBUS_TYPE_STRING, &str);
@@ -2174,20 +2293,23 @@ static void append_properties(DBusMessageIter *dict, dbus_bool_t limited,
connman_dbus_dict_append_basic(dict, "Strength",
DBUS_TYPE_BYTE, &service->strength);
+ val = service->favorite;
connman_dbus_dict_append_basic(dict, "Favorite",
- DBUS_TYPE_BOOLEAN, &service->favorite);
+ DBUS_TYPE_BOOLEAN, &val);
+ val = service->immutable;
connman_dbus_dict_append_basic(dict, "Immutable",
- DBUS_TYPE_BOOLEAN, &service->immutable);
+ DBUS_TYPE_BOOLEAN, &val);
- if (service->favorite == TRUE)
- connman_dbus_dict_append_basic(dict, "AutoConnect",
- DBUS_TYPE_BOOLEAN, &service->autoconnect);
+ if (service->favorite)
+ val = service->autoconnect;
else
- connman_dbus_dict_append_basic(dict, "AutoConnect",
- DBUS_TYPE_BOOLEAN, &service->favorite);
+ val = service->favorite;
+
+ connman_dbus_dict_append_basic(dict, "AutoConnect",
+ DBUS_TYPE_BOOLEAN, &val);
- if (service->name != NULL)
+ if (service->name)
connman_dbus_dict_append_basic(dict, "Name",
DBUS_TYPE_STRING, &service->name);
@@ -2196,11 +2318,12 @@ static void append_properties(DBusMessageIter *dict, dbus_bool_t limited,
case CONNMAN_SERVICE_TYPE_SYSTEM:
case CONNMAN_SERVICE_TYPE_GPS:
case CONNMAN_SERVICE_TYPE_VPN:
- case CONNMAN_SERVICE_TYPE_GADGET:
+ case CONNMAN_SERVICE_TYPE_P2P:
break;
case CONNMAN_SERVICE_TYPE_CELLULAR:
+ val = service->roaming;
connman_dbus_dict_append_basic(dict, "Roaming",
- DBUS_TYPE_BOOLEAN, &service->roaming);
+ DBUS_TYPE_BOOLEAN, &val);
connman_dbus_dict_append_dict(dict, "Ethernet",
append_ethernet, service);
@@ -2208,6 +2331,7 @@ static void append_properties(DBusMessageIter *dict, dbus_bool_t limited,
case CONNMAN_SERVICE_TYPE_WIFI:
case CONNMAN_SERVICE_TYPE_ETHERNET:
case CONNMAN_SERVICE_TYPE_BLUETOOTH:
+ case CONNMAN_SERVICE_TYPE_GADGET:
connman_dbus_dict_append_dict(dict, "Ethernet",
append_ethernet, service);
break;
@@ -2270,7 +2394,7 @@ static void append_struct_service(DBusMessageIter *iter,
&service->path);
connman_dbus_dict_open(&entry, &dict);
- if (function != NULL)
+ if (function)
function(&dict, service);
connman_dbus_dict_close(&entry, &dict);
@@ -2289,7 +2413,7 @@ static void append_struct(gpointer value, gpointer user_data)
struct connman_service *service = value;
DBusMessageIter *iter = user_data;
- if (service->path == NULL)
+ if (!service->path)
return;
append_struct_service(iter, append_dict_properties, service);
@@ -2300,25 +2424,39 @@ void __connman_service_list_struct(DBusMessageIter *iter)
g_list_foreach(service_list, append_struct, iter);
}
-connman_bool_t __connman_service_is_hidden(struct connman_service *service)
+bool __connman_service_is_hidden(struct connman_service *service)
{
return service->hidden;
}
-connman_bool_t
+bool
__connman_service_is_split_routing(struct connman_service *service)
{
return service->do_split_routing;
}
+bool __connman_service_index_is_split_routing(int index)
+{
+ struct connman_service *service;
+
+ if (index < 0)
+ return false;
+
+ service = __connman_service_lookup_from_index(index);
+ if (!service)
+ return false;
+
+ return __connman_service_is_split_routing(service);
+}
+
int __connman_service_get_index(struct connman_service *service)
{
- if (service == NULL)
+ if (!service)
return -1;
- if (service->network != NULL)
+ if (service->network)
return connman_network_get_index(service->network);
- else if (service->provider != NULL)
+ else if (service->provider)
return connman_provider_get_index(service->provider);
return -1;
@@ -2326,16 +2464,34 @@ int __connman_service_get_index(struct connman_service *service)
void __connman_service_set_hidden(struct connman_service *service)
{
- if (service == NULL || service->hidden == TRUE)
+ if (!service || service->hidden)
return;
- service->hidden_service = TRUE;
+ service->hidden_service = true;
+}
+
+void __connman_service_set_hostname(struct connman_service *service,
+ const char *hostname)
+{
+ if (!service || service->hidden)
+ return;
+
+ g_free(service->hostname);
+ service->hostname = g_strdup(hostname);
+}
+
+const char *__connman_service_get_hostname(struct connman_service *service)
+{
+ if (!service)
+ return NULL;
+
+ return service->hostname;
}
void __connman_service_set_domainname(struct connman_service *service,
const char *domainname)
{
- if (service == NULL || service->hidden == TRUE)
+ if (!service || service->hidden)
return;
g_free(service->domainname);
@@ -2346,10 +2502,10 @@ void __connman_service_set_domainname(struct connman_service *service,
const char *connman_service_get_domainname(struct connman_service *service)
{
- if (service == NULL)
+ if (!service)
return NULL;
- if (service->domains != NULL)
+ if (service->domains)
return service->domains[0];
else
return service->domainname;
@@ -2357,23 +2513,23 @@ const char *connman_service_get_domainname(struct connman_service *service)
char **connman_service_get_nameservers(struct connman_service *service)
{
- if (service == NULL)
+ if (!service)
return NULL;
- if (service->nameservers_config != NULL)
+ if (service->nameservers_config)
return g_strdupv(service->nameservers_config);
- else if (service->nameservers != NULL ||
- service->nameservers_auto != NULL) {
+ else if (service->nameservers ||
+ service->nameservers_auto) {
int len = 0, len_auto = 0, i;
char **nameservers;
- if (service->nameservers != NULL)
+ if (service->nameservers)
len = g_strv_length(service->nameservers);
- if (service->nameservers_auto != NULL)
+ if (service->nameservers_auto)
len_auto = g_strv_length(service->nameservers_auto);
nameservers = g_try_new0(char *, len + len_auto + 1);
- if (nameservers == NULL)
+ if (!nameservers)
return NULL;
for (i = 0; i < len; i++)
@@ -2386,12 +2542,12 @@ char **connman_service_get_nameservers(struct connman_service *service)
return nameservers;
}
- return NULL;
+ return g_strdupv(connman_setting_get_string_list("FallbackNameservers"));
}
char **connman_service_get_timeservers_config(struct connman_service *service)
{
- if (service == NULL)
+ if (!service)
return NULL;
return service->timeservers_config;
@@ -2399,19 +2555,16 @@ char **connman_service_get_timeservers_config(struct connman_service *service)
char **connman_service_get_timeservers(struct connman_service *service)
{
- if (service == NULL)
+ if (!service)
return NULL;
- if (service->timeservers != NULL)
- return service->timeservers;
-
- return NULL;
+ return service->timeservers;
}
void connman_service_set_proxy_method(struct connman_service *service,
enum connman_service_proxy_method method)
{
- if (service == NULL || service->hidden == TRUE)
+ if (!service || service->hidden)
return;
service->proxy = method;
@@ -2425,12 +2578,12 @@ void connman_service_set_proxy_method(struct connman_service *service,
enum connman_service_proxy_method connman_service_get_proxy_method(
struct connman_service *service)
{
- if (service == NULL)
+ if (!service)
return CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN;
if (service->proxy_config != CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN) {
if (service->proxy_config == CONNMAN_SERVICE_PROXY_METHOD_AUTO &&
- service->pac == NULL)
+ !service->pac)
return service->proxy;
return service->proxy_config;
@@ -2451,7 +2604,7 @@ char **connman_service_get_proxy_excludes(struct connman_service *service)
const char *connman_service_get_proxy_url(struct connman_service *service)
{
- if (service == NULL)
+ if (!service)
return NULL;
return service->pac;
@@ -2460,7 +2613,7 @@ const char *connman_service_get_proxy_url(struct connman_service *service)
void __connman_service_set_proxy_autoconfig(struct connman_service *service,
const char *url)
{
- if (service == NULL || service->hidden == TRUE)
+ if (!service || service->hidden)
return;
service->proxy = CONNMAN_SERVICE_PROXY_METHOD_AUTO;
@@ -2483,7 +2636,7 @@ void __connman_service_set_proxy_autoconfig(struct connman_service *service,
const char *connman_service_get_proxy_autoconfig(struct connman_service *service)
{
- if (service == NULL)
+ if (!service)
return NULL;
if (service->ipconfig_ipv4)
@@ -2500,13 +2653,13 @@ void __connman_service_set_timeservers(struct connman_service *service,
{
int i;
- if (service == NULL)
+ if (!service)
return;
g_strfreev(service->timeservers);
service->timeservers = NULL;
- for (i = 0; timeservers != NULL && timeservers[i] != NULL; i++)
+ for (i = 0; timeservers && timeservers[i]; i++)
__connman_service_timeserver_append(service, timeservers[i]);
}
@@ -2517,13 +2670,13 @@ int __connman_service_timeserver_append(struct connman_service *service,
DBG("service %p timeserver %s", service, timeserver);
- if (timeserver == NULL)
+ if (!timeserver)
return -EINVAL;
- if (service->timeservers != NULL) {
+ if (service->timeservers) {
int i;
- for (i = 0; service->timeservers[i] != NULL; i++)
+ for (i = 0; service->timeservers[i]; i++)
if (g_strcmp0(service->timeservers[i], timeserver) == 0)
return -EEXIST;
@@ -2535,7 +2688,7 @@ int __connman_service_timeserver_append(struct connman_service *service,
service->timeservers = g_try_new0(char *, len + 2);
}
- if (service->timeservers == NULL)
+ if (!service->timeservers)
return -ENOMEM;
service->timeservers[len] = g_strdup(timeserver);
@@ -2552,14 +2705,14 @@ int __connman_service_timeserver_remove(struct connman_service *service,
DBG("service %p timeserver %s", service, timeserver);
- if (timeserver == NULL)
+ if (!timeserver)
return -EINVAL;
- if (service->timeservers == NULL)
+ if (!service->timeservers)
return 0;
- for (i = 0; service->timeservers != NULL &&
- service->timeservers[i] != NULL; i++)
+ for (i = 0; service->timeservers &&
+ service->timeservers[i]; i++)
if (g_strcmp0(service->timeservers[i], timeserver) == 0) {
found = 1;
break;
@@ -2578,13 +2731,13 @@ int __connman_service_timeserver_remove(struct connman_service *service,
}
servers = g_try_new0(char *, len);
- if (servers == NULL)
+ if (!servers)
return -ENOMEM;
for (i = 0, j = 0; i < len; i++) {
if (g_strcmp0(service->timeservers[i], timeserver) != 0) {
servers[j] = g_strdup(service->timeservers[i]);
- if (servers[j] == NULL)
+ if (!servers[j])
return -ENOMEM;
j++;
}
@@ -2600,10 +2753,10 @@ int __connman_service_timeserver_remove(struct connman_service *service,
void __connman_service_timeserver_changed(struct connman_service *service,
GSList *ts_list)
{
- if (service == NULL)
+ if (!service)
return;
- if (allow_property_changed(service) == FALSE)
+ if (!allow_property_changed(service))
return;
connman_dbus_property_changed_array(service->path,
@@ -2614,7 +2767,7 @@ void __connman_service_timeserver_changed(struct connman_service *service,
void __connman_service_set_pac(struct connman_service *service,
const char *pac)
{
- if (service->hidden == TRUE)
+ if (service->hidden)
return;
g_free(service->pac);
service->pac = g_strdup(pac);
@@ -2625,13 +2778,13 @@ void __connman_service_set_pac(struct connman_service *service,
void __connman_service_set_identity(struct connman_service *service,
const char *identity)
{
- if (service->immutable || service->hidden == TRUE)
+ if (service->immutable || service->hidden)
return;
g_free(service->identity);
service->identity = g_strdup(identity);
- if (service->network != NULL)
+ if (service->network)
connman_network_set_string(service->network,
"WiFi.Identity",
service->identity);
@@ -2640,12 +2793,12 @@ void __connman_service_set_identity(struct connman_service *service,
void __connman_service_set_agent_identity(struct connman_service *service,
const char *agent_identity)
{
- if (service->hidden == TRUE)
+ if (service->hidden)
return;
g_free(service->agent_identity);
service->agent_identity = g_strdup(agent_identity);
- if (service->network != NULL)
+ if (service->network)
connman_network_set_string(service->network,
"WiFi.AgentIdentity",
service->agent_identity);
@@ -2658,12 +2811,12 @@ static int check_passphrase(struct connman_service *service,
guint i;
gsize length;
- if (passphrase == NULL) {
+ if (!passphrase) {
/*
* This will prevent __connman_service_set_passphrase() to
* wipe the passphrase out in case of -ENOKEY error for a
* favorite service. */
- if (service->favorite == TRUE)
+ if (service->favorite)
return 1;
else
return 0;
@@ -2713,7 +2866,7 @@ int __connman_service_set_passphrase(struct connman_service *service,
{
int err = 0;
- if (service->immutable == TRUE || service->hidden == TRUE)
+ if (service->immutable || service->hidden)
return -EINVAL;
err = check_passphrase(service, service->security, passphrase);
@@ -2722,7 +2875,7 @@ int __connman_service_set_passphrase(struct connman_service *service,
g_free(service->passphrase);
service->passphrase = g_strdup(passphrase);
- if (service->network != NULL)
+ if (service->network)
connman_network_set_string(service->network,
"WiFi.Passphrase",
service->passphrase);
@@ -2734,26 +2887,12 @@ int __connman_service_set_passphrase(struct connman_service *service,
const char *__connman_service_get_passphrase(struct connman_service *service)
{
- if (service == NULL)
+ if (!service)
return NULL;
return service->passphrase;
}
-void __connman_service_set_agent_passphrase(struct connman_service *service,
- const char *agent_passphrase)
-{
- if (service->hidden == TRUE)
- return;
- g_free(service->agent_passphrase);
- service->agent_passphrase = g_strdup(agent_passphrase);
-
- if (service->network != NULL)
- connman_network_set_string(service->network,
- "WiFi.AgentPassphrase",
- service->agent_passphrase);
-}
-
static DBusMessage *get_properties(DBusConnection *conn,
DBusMessage *msg, void *user_data)
{
@@ -2764,7 +2903,7 @@ static DBusMessage *get_properties(DBusConnection *conn,
DBG("service %p", service);
reply = dbus_message_new_method_return(msg);
- if (reply == NULL)
+ if (!reply)
return NULL;
dbus_message_iter_init_append(reply, &array);
@@ -2809,7 +2948,7 @@ static int update_proxy_configuration(struct connman_service *service,
type = dbus_message_iter_get_arg_type(&variant);
- if (g_str_equal(key, "Method") == TRUE) {
+ if (g_str_equal(key, "Method")) {
const char *val;
if (type != DBUS_TYPE_STRING)
@@ -2817,19 +2956,19 @@ static int update_proxy_configuration(struct connman_service *service,
dbus_message_iter_get_basic(&variant, &val);
method = string2proxymethod(val);
- } else if (g_str_equal(key, "URL") == TRUE) {
+ } else if (g_str_equal(key, "URL")) {
if (type != DBUS_TYPE_STRING)
goto error;
dbus_message_iter_get_basic(&variant, &url);
- } else if (g_str_equal(key, "Servers") == TRUE) {
+ } else if (g_str_equal(key, "Servers")) {
DBusMessageIter str_array;
if (type != DBUS_TYPE_ARRAY)
goto error;
servers_str = g_string_new(NULL);
- if (servers_str == NULL)
+ if (!servers_str)
goto error;
dbus_message_iter_recurse(&variant, &str_array);
@@ -2848,14 +2987,14 @@ static int update_proxy_configuration(struct connman_service *service,
dbus_message_iter_next(&str_array);
}
- } else if (g_str_equal(key, "Excludes") == TRUE) {
+ } else if (g_str_equal(key, "Excludes")) {
DBusMessageIter str_array;
if (type != DBUS_TYPE_ARRAY)
goto error;
excludes_str = g_string_new(NULL);
- if (excludes_str == NULL)
+ if (!excludes_str)
goto error;
dbus_message_iter_recurse(&variant, &str_array);
@@ -2883,10 +3022,10 @@ static int update_proxy_configuration(struct connman_service *service,
case CONNMAN_SERVICE_PROXY_METHOD_DIRECT:
break;
case CONNMAN_SERVICE_PROXY_METHOD_MANUAL:
- if (servers_str == NULL && service->proxies == NULL)
+ if (!servers_str && !service->proxies)
goto error;
- if (servers_str != NULL) {
+ if (servers_str) {
g_strfreev(service->proxies);
if (servers_str->len > 0)
@@ -2896,7 +3035,7 @@ static int update_proxy_configuration(struct connman_service *service,
service->proxies = NULL;
}
- if (excludes_str != NULL) {
+ if (excludes_str) {
g_strfreev(service->excludes);
if (excludes_str->len > 0)
@@ -2906,14 +3045,14 @@ static int update_proxy_configuration(struct connman_service *service,
service->excludes = NULL;
}
- if (service->proxies == NULL)
+ if (!service->proxies)
method = CONNMAN_SERVICE_PROXY_METHOD_DIRECT;
break;
case CONNMAN_SERVICE_PROXY_METHOD_AUTO:
g_free(service->pac);
- if (url != NULL && strlen(url) > 0)
+ if (url && strlen(url) > 0)
service->pac = g_strdup(url);
else
service->pac = NULL;
@@ -2929,10 +3068,10 @@ static int update_proxy_configuration(struct connman_service *service,
goto error;
}
- if (servers_str != NULL)
+ if (servers_str)
g_string_free(servers_str, TRUE);
- if (excludes_str != NULL)
+ if (excludes_str)
g_string_free(excludes_str, TRUE);
service->proxy_config = method;
@@ -2940,10 +3079,10 @@ static int update_proxy_configuration(struct connman_service *service,
return 0;
error:
- if (servers_str != NULL)
+ if (servers_str)
g_string_free(servers_str, TRUE);
- if (excludes_str != NULL)
+ if (excludes_str)
g_string_free(excludes_str, TRUE);
return -EINVAL;
@@ -2969,7 +3108,7 @@ int __connman_service_reset_ipconfig(struct connman_service *service,
} else
return -EINVAL;
- if (ipconfig == NULL)
+ if (!ipconfig)
return -ENXIO;
old_method = __connman_ipconfig_get_method(ipconfig);
@@ -2981,7 +3120,7 @@ int __connman_service_reset_ipconfig(struct connman_service *service,
else
new_ipconfig = create_ip6config(service, index);
- if (array != NULL) {
+ if (array) {
err = __connman_ipconfig_set_config(new_ipconfig, array);
if (err < 0) {
__connman_ipconfig_unref(new_ipconfig);
@@ -2996,25 +3135,24 @@ int __connman_service_reset_ipconfig(struct connman_service *service,
__connman_network_clear_ipconfig(service->network, ipconfig);
__connman_ipconfig_unref(ipconfig);
- if (type == CONNMAN_IPCONFIG_TYPE_IPV4) {
+ if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
service->ipconfig_ipv4 = new_ipconfig;
- } else if (type == CONNMAN_IPCONFIG_TYPE_IPV6) {
+ else if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
service->ipconfig_ipv6 = new_ipconfig;
- }
__connman_ipconfig_enable(new_ipconfig);
- if (new_state != NULL && new_method != old_method) {
+ if (new_state && new_method != old_method) {
if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
*new_state = service->state_ipv4;
else
*new_state = service->state_ipv6;
- __connman_service_auto_connect();
+ __connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO);
}
DBG("err %d ipconfig %p type %d method %d state %s", err,
new_ipconfig, type, new_method,
- new_state == NULL ? "-" : state2string(*new_state));
+ !new_state ? "-" : state2string(*new_state));
return err;
}
@@ -3029,7 +3167,7 @@ static DBusMessage *set_property(DBusConnection *conn,
DBG("service %p", service);
- if (dbus_message_iter_init(msg, &iter) == FALSE)
+ if (!dbus_message_iter_init(msg, &iter))
return __connman_error_invalid_arguments(msg);
if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
@@ -3045,13 +3183,13 @@ static DBusMessage *set_property(DBusConnection *conn,
type = dbus_message_iter_get_arg_type(&value);
- if (g_str_equal(name, "AutoConnect") == TRUE) {
- connman_bool_t autoconnect;
+ if (g_str_equal(name, "AutoConnect")) {
+ dbus_bool_t autoconnect;
if (type != DBUS_TYPE_BOOLEAN)
return __connman_error_invalid_arguments(msg);
- if (service->favorite == FALSE)
+ if (!service->favorite)
return __connman_error_invalid_service(msg);
dbus_message_iter_get_basic(&value, &autoconnect);
@@ -3063,30 +3201,28 @@ static DBusMessage *set_property(DBusConnection *conn,
autoconnect_changed(service);
- if (autoconnect == TRUE)
- __connman_service_auto_connect();
+ if (autoconnect)
+ __connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO);
service_save(service);
- } else if (g_str_equal(name, "Nameservers.Configuration") == TRUE) {
+ } else if (g_str_equal(name, "Nameservers.Configuration")) {
DBusMessageIter entry;
GString *str;
int index;
const char *gw;
- if (service->immutable == TRUE)
+ if (__connman_provider_is_immutable(service->provider) ||
+ service->immutable)
return __connman_error_not_supported(msg);
if (type != DBUS_TYPE_ARRAY)
return __connman_error_invalid_arguments(msg);
str = g_string_new(NULL);
- if (str == NULL)
+ if (!str)
return __connman_error_invalid_arguments(msg);
- if (service->type == CONNMAN_SERVICE_TYPE_VPN)
- index = connman_provider_get_index(service->provider);
- else
- index = connman_network_get_index(service->network);
+ index = __connman_service_get_index(service);
gw = __connman_ipconfig_get_gateway_from_index(index,
CONNMAN_IPCONFIG_TYPE_ALL);
@@ -3137,12 +3273,12 @@ static DBusMessage *set_property(DBusConnection *conn,
CONNMAN_IPCONFIG_TYPE_IPV6);
service_save(service);
- } else if (g_str_equal(name, "Timeservers.Configuration") == TRUE) {
+ } else if (g_str_equal(name, "Timeservers.Configuration")) {
DBusMessageIter entry;
GSList *list = NULL;
int count = 0;
- if (service->immutable == TRUE)
+ if (service->immutable)
return __connman_error_not_supported(msg);
if (type != DBUS_TYPE_ARRAY)
@@ -3168,10 +3304,10 @@ static DBusMessage *set_property(DBusConnection *conn,
g_strfreev(service->timeservers_config);
service->timeservers_config = NULL;
- if (list != NULL) {
+ if (list) {
service->timeservers_config = g_new0(char *, count+1);
- while (list != NULL) {
+ while (list) {
count--;
service->timeservers_config[count] = list->data;
list = g_slist_delete_link(list, list);
@@ -3184,18 +3320,18 @@ static DBusMessage *set_property(DBusConnection *conn,
if (service == __connman_service_get_default())
__connman_timeserver_sync(service);
- } else if (g_str_equal(name, "Domains.Configuration") == TRUE) {
+ } else if (g_str_equal(name, "Domains.Configuration")) {
DBusMessageIter entry;
GString *str;
- if (service->immutable == TRUE)
+ if (service->immutable)
return __connman_error_not_supported(msg);
if (type != DBUS_TYPE_ARRAY)
return __connman_error_invalid_arguments(msg);
str = g_string_new(NULL);
- if (str == NULL)
+ if (!str)
return __connman_error_invalid_arguments(msg);
dbus_message_iter_recurse(&value, &entry);
@@ -3225,10 +3361,10 @@ static DBusMessage *set_property(DBusConnection *conn,
domain_changed(service);
service_save(service);
- } else if (g_str_equal(name, "Proxy.Configuration") == TRUE) {
+ } else if (g_str_equal(name, "Proxy.Configuration")) {
int err;
- if (service->immutable == TRUE)
+ if (service->immutable)
return __connman_error_not_supported(msg);
if (type != DBUS_TYPE_ARRAY)
@@ -3244,7 +3380,7 @@ static DBusMessage *set_property(DBusConnection *conn,
__connman_notifier_proxy_changed(service);
service_save(service);
- } else if (g_str_equal(name, "IPv4.Configuration") == TRUE ||
+ } else if (g_str_equal(name, "IPv4.Configuration") ||
g_str_equal(name, "IPv6.Configuration")) {
enum connman_service_state state =
@@ -3253,16 +3389,17 @@ static DBusMessage *set_property(DBusConnection *conn,
CONNMAN_IPCONFIG_TYPE_UNKNOWN;
int err = 0;
- if (service->immutable == TRUE)
+ if (service->type == CONNMAN_SERVICE_TYPE_VPN ||
+ service->immutable)
return __connman_error_not_supported(msg);
DBG("%s", name);
- if (service->ipconfig_ipv4 == NULL &&
- service->ipconfig_ipv6 == NULL)
+ if (!service->ipconfig_ipv4 &&
+ !service->ipconfig_ipv6)
return __connman_error_invalid_property(msg);
- if (g_str_equal(name, "IPv4.Configuration") == TRUE)
+ if (g_str_equal(name, "IPv4.Configuration"))
type = CONNMAN_IPCONFIG_TYPE_IPV4;
else
type = CONNMAN_IPCONFIG_TYPE_IPV6;
@@ -3306,15 +3443,15 @@ static void set_error(struct connman_service *service,
service->error = error;
- if (service->path == NULL)
+ if (!service->path)
return;
str = error2string(service->error);
- if (str == NULL)
+ if (!str)
str = "";
- if (allow_property_changed(service) == FALSE)
+ if (!allow_property_changed(service))
return;
connman_dbus_property_changed_basic(service->path,
@@ -3322,14 +3459,6 @@ static void set_error(struct connman_service *service,
DBUS_TYPE_STRING, &str);
}
-static void set_idle(struct connman_service *service)
-{
- service->state = service->state_ipv4 = service->state_ipv6 =
- CONNMAN_SERVICE_STATE_IDLE;
- set_error(service, CONNMAN_SERVICE_ERROR_UNKNOWN);
- state_changed(service);
-}
-
static DBusMessage *clear_property(DBusConnection *conn,
DBusMessage *msg, void *user_data)
{
@@ -3341,8 +3470,8 @@ static DBusMessage *clear_property(DBusConnection *conn,
dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &name,
DBUS_TYPE_INVALID);
- if (g_str_equal(name, "Error") == TRUE) {
- set_idle(service);
+ if (g_str_equal(name, "Error")) {
+ set_error(service, CONNMAN_SERVICE_ERROR_UNKNOWN);
g_get_current_time(&service->modified);
service_save(service);
@@ -3352,34 +3481,102 @@ static DBusMessage *clear_property(DBusConnection *conn,
return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
}
-static connman_bool_t is_ipconfig_usable(struct connman_service *service)
+static bool is_ipconfig_usable(struct connman_service *service)
{
- if (__connman_ipconfig_is_usable(service->ipconfig_ipv4) == FALSE &&
- __connman_ipconfig_is_usable(service->ipconfig_ipv6)
- == FALSE)
- return FALSE;
+ if (!__connman_ipconfig_is_usable(service->ipconfig_ipv4) &&
+ !__connman_ipconfig_is_usable(service->ipconfig_ipv6))
+ return false;
- return TRUE;
+ return true;
}
-static connman_bool_t is_ignore(struct connman_service *service)
+static bool is_ignore(struct connman_service *service)
{
- if (service->autoconnect == FALSE)
- return TRUE;
+ if (!service->autoconnect)
+ return true;
- if (service->roaming == TRUE)
- return TRUE;
+ if (service->roaming)
+ return true;
- if (service->ignore == TRUE)
- return TRUE;
+ if (service->ignore)
+ return true;
if (service->state == CONNMAN_SERVICE_STATE_FAILURE)
- return TRUE;
+ return true;
- if (is_ipconfig_usable(service) == FALSE)
- return TRUE;
+ if (!is_ipconfig_usable(service))
+ return true;
- return FALSE;
+ return false;
+}
+
+static void disconnect_on_last_session(enum connman_service_type type)
+{
+ GList *list;
+
+ for (list = service_list; list; list = list->next) {
+ struct connman_service *service = list->data;
+
+ if (service->type != type)
+ continue;
+
+ if (service->connect_reason != CONNMAN_SERVICE_CONNECT_REASON_SESSION)
+ continue;
+
+ __connman_service_disconnect(service);
+ return;
+ }
+}
+
+static int active_sessions[MAX_CONNMAN_SERVICE_TYPES] = {};
+static int active_count = 0;
+
+void __connman_service_set_active_session(bool enable, GSList *list)
+{
+ if (!list)
+ return;
+
+ if (enable)
+ active_count++;
+ else
+ active_count--;
+
+ while (list != NULL) {
+ enum connman_service_type type = GPOINTER_TO_INT(list->data);
+
+ switch (type) {
+ case CONNMAN_SERVICE_TYPE_ETHERNET:
+ case CONNMAN_SERVICE_TYPE_WIFI:
+ case CONNMAN_SERVICE_TYPE_BLUETOOTH:
+ case CONNMAN_SERVICE_TYPE_CELLULAR:
+ case CONNMAN_SERVICE_TYPE_GADGET:
+ if (enable)
+ active_sessions[type]++;
+ else
+ active_sessions[type]--;
+ break;
+
+ case CONNMAN_SERVICE_TYPE_UNKNOWN:
+ case CONNMAN_SERVICE_TYPE_SYSTEM:
+ case CONNMAN_SERVICE_TYPE_GPS:
+ case CONNMAN_SERVICE_TYPE_VPN:
+ case CONNMAN_SERVICE_TYPE_P2P:
+ break;
+ }
+
+ if (active_sessions[type] == 0)
+ disconnect_on_last_session(type);
+
+ list = g_slist_next(list);
+ }
+
+ DBG("eth %d wifi %d bt %d cellular %d gadget %d sessions %d",
+ active_sessions[CONNMAN_SERVICE_TYPE_ETHERNET],
+ active_sessions[CONNMAN_SERVICE_TYPE_WIFI],
+ active_sessions[CONNMAN_SERVICE_TYPE_BLUETOOTH],
+ active_sessions[CONNMAN_SERVICE_TYPE_CELLULAR],
+ active_sessions[CONNMAN_SERVICE_TYPE_GADGET],
+ active_count);
}
struct preferred_tech_data {
@@ -3401,25 +3598,26 @@ static void preferred_tech_add_by_type(gpointer data, gpointer user_data)
}
}
-static GList* preferred_tech_list_get(void)
+static GList *preferred_tech_list_get(void)
{
unsigned int *tech_array;
struct preferred_tech_data tech_data = { 0, };
int i;
tech_array = connman_setting_get_uint_list("PreferredTechnologies");
- if (tech_array == NULL)
+ if (!tech_array)
return NULL;
- if (connman_setting_get_bool("SingleConnectedTechnology") == TRUE) {
+ if (connman_setting_get_bool("SingleConnectedTechnology")) {
GList *list;
- for (list = service_list; list != NULL; list = list->next) {
+ for (list = service_list; list; list = list->next) {
struct connman_service *service = list->data;
- if (is_connected(service) == FALSE)
+ if (!is_connected(service))
break;
- if (service->userconnect == TRUE) {
+ if (service->connect_reason ==
+ CONNMAN_SERVICE_CONNECT_REASON_USER) {
DBG("service %p name %s is user connected",
service, service->name);
return NULL;
@@ -3436,87 +3634,162 @@ static GList* preferred_tech_list_get(void)
return tech_data.preferred_list;
}
-static connman_bool_t auto_connect_service(GList *services,
- connman_bool_t preferred)
+static bool auto_connect_service(GList *services,
+ enum connman_service_connect_reason reason,
+ bool preferred)
{
struct connman_service *service = NULL;
+ bool ignore[MAX_CONNMAN_SERVICE_TYPES] = { };
+ bool autoconnecting = false;
GList *list;
- for (list = services; list != NULL; list = list->next) {
+ DBG("preferred %d sessions %d reason %s", preferred, active_count,
+ reason2string(reason));
+
+ ignore[CONNMAN_SERVICE_TYPE_VPN] = true;
+
+ for (list = services; list; list = list->next) {
service = list->data;
- if (service->pending != NULL)
- return TRUE;
+ if (ignore[service->type]) {
+ DBG("service %p type %s ignore", service,
+ __connman_service_type2string(service->type));
+ continue;
+ }
+
+ if (service->pending ||
+ is_connecting(service) ||
+ is_connected(service)) {
+ if (!active_count)
+ return true;
- if (is_connecting(service) == TRUE)
- return TRUE;
+ ignore[service->type] = true;
+ autoconnecting = true;
- if (service->favorite == FALSE) {
- if (preferred == TRUE)
- goto next_service;
- return FALSE;
+ DBG("service %p type %s busy", service,
+ __connman_service_type2string(service->type));
+
+ continue;
}
- if (is_connected(service) == TRUE)
- return TRUE;
+ if (!service->favorite) {
+ if (preferred)
+ continue;
- if (is_ignore(service) == FALSE && service->state ==
- CONNMAN_SERVICE_STATE_IDLE)
- break;
+ return autoconnecting;
+ }
- next_service:
- service = NULL;
- }
+ if (is_ignore(service) || service->state !=
+ CONNMAN_SERVICE_STATE_IDLE)
+ continue;
- if (service != NULL) {
+ if (autoconnecting && !active_sessions[service->type]) {
+ DBG("service %p type %s has no users", service,
+ __connman_service_type2string(service->type));
+ continue;
+ }
DBG("service %p %s %s", service, service->name,
- (preferred == TRUE)? "preferred": "auto");
+ (preferred) ? "preferred" : reason2string(reason));
+
+ __connman_service_connect(service, reason);
- service->userconnect = FALSE;
- __connman_service_connect(service);
- return TRUE;
+ if (!active_count)
+ return true;
+
+ ignore[service->type] = true;
}
- return FALSE;
+
+ return autoconnecting;
}
static gboolean run_auto_connect(gpointer data)
{
- GList *list = NULL, *preferred_tech;
+ enum connman_service_connect_reason reason = GPOINTER_TO_UINT(data);
+ bool autoconnecting = false;
+ GList *preferred_tech;
autoconnect_timeout = 0;
DBG("");
preferred_tech = preferred_tech_list_get();
- if (preferred_tech != NULL)
- list = preferred_tech;
-
- if (list == NULL || auto_connect_service(list, TRUE) == FALSE)
- list = service_list;
-
- if (list != NULL)
- auto_connect_service(list, FALSE);
-
- if (preferred_tech != NULL)
+ if (preferred_tech) {
+ autoconnecting = auto_connect_service(preferred_tech, reason,
+ true);
g_list_free(preferred_tech);
+ }
+
+ if (!autoconnecting || active_count)
+ auto_connect_service(service_list, reason, false);
return FALSE;
}
-void __connman_service_auto_connect(void)
+void __connman_service_auto_connect(enum connman_service_connect_reason reason)
{
DBG("");
- if (__connman_session_mode() == TRUE) {
- DBG("Session mode enabled: auto connect disabled");
+ if (autoconnect_timeout != 0)
return;
+
+ if (!__connman_session_policy_autoconnect(reason))
+ return;
+
+ autoconnect_timeout = g_timeout_add_seconds(0, run_auto_connect,
+ GUINT_TO_POINTER(reason));
+}
+
+static gboolean run_vpn_auto_connect(gpointer data) {
+ GList *list;
+ bool need_split = false;
+
+ vpn_autoconnect_timeout = 0;
+
+ for (list = service_list; list; list = list->next) {
+ struct connman_service *service = list->data;
+ int res;
+
+ if (service->type != CONNMAN_SERVICE_TYPE_VPN)
+ continue;
+
+ if (is_connected(service) || is_connecting(service)) {
+ if (!service->do_split_routing)
+ need_split = true;
+ continue;
+ }
+
+ if (is_ignore(service) || !service->favorite)
+ continue;
+
+ if (need_split && !service->do_split_routing) {
+ DBG("service %p no split routing", service);
+ continue;
+ }
+
+ DBG("service %p %s %s", service, service->name,
+ service->do_split_routing ?
+ "split routing" : "");
+
+ res = __connman_service_connect(service,
+ CONNMAN_SERVICE_CONNECT_REASON_AUTO);
+ if (res < 0 && res != -EINPROGRESS)
+ continue;
+
+ if (!service->do_split_routing)
+ need_split = true;
}
- if (autoconnect_timeout != 0)
+ return FALSE;
+}
+
+static void vpn_auto_connect(void)
+{
+ if (vpn_autoconnect_timeout)
return;
- autoconnect_timeout = g_timeout_add_seconds(0, run_auto_connect, NULL);
+ vpn_autoconnect_timeout =
+ g_timeout_add_seconds(0, run_vpn_auto_connect, NULL);
}
static void remove_timeout(struct connman_service *service)
@@ -3530,18 +3803,18 @@ static void remove_timeout(struct connman_service *service)
void __connman_service_reply_dbus_pending(DBusMessage *pending, int error,
const char *path)
{
- if (pending != NULL) {
+ if (pending) {
if (error > 0) {
DBusMessage *reply;
reply = __connman_error_failed(pending, error);
- if (reply != NULL)
+ if (reply)
g_dbus_send_message(connection, reply);
} else {
const char *sender;
sender = dbus_message_get_interface(pending);
- if (path == NULL)
+ if (!path)
path = dbus_message_get_path(pending);
DBG("sender %s path %s", sender, path);
@@ -3563,35 +3836,35 @@ static void reply_pending(struct connman_service *service, int error)
{
remove_timeout(service);
- if (service->pending != NULL) {
+ if (service->pending) {
__connman_service_reply_dbus_pending(service->pending, error,
NULL);
service->pending = NULL;
}
- if (service->provider_pending != NULL) {
+ if (service->provider_pending) {
__connman_service_reply_dbus_pending(service->provider_pending,
error, service->path);
service->provider_pending = NULL;
}
}
-connman_bool_t
+bool
__connman_service_is_provider_pending(struct connman_service *service)
{
- if (service == NULL)
- return FALSE;
+ if (!service)
+ return false;
- if (service->provider_pending != NULL)
- return TRUE;
+ if (service->provider_pending)
+ return true;
- return FALSE;
+ return false;
}
void __connman_service_set_provider_pending(struct connman_service *service,
DBusMessage *msg)
{
- if (service->provider_pending != NULL) {
+ if (service->provider_pending) {
DBG("service %p provider pending msg %p already exists",
service, service->provider_pending);
return;
@@ -3603,7 +3876,7 @@ void __connman_service_set_provider_pending(struct connman_service *service,
static void check_pending_msg(struct connman_service *service)
{
- if (service->pending == NULL)
+ if (!service->pending)
return;
DBG("service %p pending msg %p already exists", service,
@@ -3618,7 +3891,7 @@ void __connman_service_set_hidden_data(struct connman_service *service,
DBG("service %p pending %p", service, pending);
- if (pending == NULL)
+ if (!pending)
return;
check_pending_msg(service);
@@ -3639,15 +3912,15 @@ void __connman_service_return_error(struct connman_service *service,
static gboolean connect_timeout(gpointer user_data)
{
struct connman_service *service = user_data;
- connman_bool_t autoconnect = FALSE;
+ bool autoconnect = false;
DBG("service %p", service);
service->timeout = 0;
- if (service->network != NULL)
+ if (service->network)
__connman_network_disconnect(service->network);
- else if (service->provider != NULL)
+ else if (service->provider)
connman_provider_disconnect(service->provider);
__connman_ipconfig_disable(service->ipconfig_ipv4);
@@ -3655,17 +3928,17 @@ static gboolean connect_timeout(gpointer user_data)
__connman_stats_service_unregister(service);
- if (service->pending != NULL) {
+ if (service->pending) {
DBusMessage *reply;
reply = __connman_error_operation_timeout(service->pending);
- if (reply != NULL)
+ if (reply)
g_dbus_send_message(connection, reply);
dbus_message_unref(service->pending);
service->pending = NULL;
} else
- autoconnect = TRUE;
+ autoconnect = true;
__connman_service_ipconfig_indicate_state(service,
CONNMAN_SERVICE_STATE_FAILURE,
@@ -3674,77 +3947,50 @@ static gboolean connect_timeout(gpointer user_data)
CONNMAN_SERVICE_STATE_FAILURE,
CONNMAN_IPCONFIG_TYPE_IPV6);
- if (autoconnect == TRUE && service->userconnect == FALSE)
- __connman_service_auto_connect();
+ if (autoconnect &&
+ service->connect_reason !=
+ CONNMAN_SERVICE_CONNECT_REASON_USER)
+ __connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO);
return FALSE;
}
-static void set_reconnect_state(struct connman_service *service,
- connman_bool_t reconnect)
-{
- struct connman_device *device;
-
- if (service->network == NULL)
- return;
-
- device = connman_network_get_device(service->network);
- if (device == NULL)
- return;
-
- __connman_device_set_reconnect(device, reconnect);
-}
-
-static connman_bool_t get_reconnect_state(struct connman_service *service)
-{
- struct connman_device *device;
-
- if (service->network == NULL)
- return FALSE;
-
- device = connman_network_get_device(service->network);
- if (device == NULL)
- return FALSE;
-
- return __connman_device_get_reconnect(device);
-}
-
-static connman_bool_t is_interface_available(struct connman_service *service,
+static bool is_interface_available(struct connman_service *service,
struct connman_service *other_service)
{
unsigned int index = 0, other_index = 0;
- if (service->ipconfig_ipv4 != NULL)
+ if (service->ipconfig_ipv4)
index = __connman_ipconfig_get_index(service->ipconfig_ipv4);
- else if (service->ipconfig_ipv6 != NULL)
+ else if (service->ipconfig_ipv6)
index = __connman_ipconfig_get_index(service->ipconfig_ipv6);
- if (other_service->ipconfig_ipv4 != NULL)
+ if (other_service->ipconfig_ipv4)
other_index = __connman_ipconfig_get_index(
other_service->ipconfig_ipv4);
- else if (other_service->ipconfig_ipv6 != NULL)
+ else if (other_service->ipconfig_ipv6)
other_index = __connman_ipconfig_get_index(
other_service->ipconfig_ipv6);
if (index > 0 && other_index != index)
- return TRUE;
+ return true;
- return FALSE;
+ return false;
}
static DBusMessage *connect_service(DBusConnection *conn,
DBusMessage *msg, void *user_data)
{
struct connman_service *service = user_data;
+ int err = 0;
GList *list;
- int err;
DBG("service %p", service);
- if (service->pending != NULL)
+ if (service->pending)
return __connman_error_in_progress(msg);
- for (list = service_list; list != NULL; list = list->next) {
+ for (list = service_list; list; list = list->next) {
struct connman_service *temp = list->data;
/*
@@ -3752,47 +3998,35 @@ static DBusMessage *connect_service(DBusConnection *conn,
* interfaces for a given technology type (like having
* more than one wifi card).
*/
- if (service->type == temp->type &&
- is_connecting(temp) == TRUE &&
- is_interface_available(service,
- temp) == FALSE) {
- if (temp->pending != NULL)
- __connman_service_return_error(temp,
- ECONNABORTED,
- NULL);
+ if (!is_connecting(temp) && !is_connected(temp))
+ break;
- err = __connman_service_disconnect(temp);
- if (err < 0 && err != -EINPROGRESS)
- return __connman_error_in_progress(msg);
- else {
- set_idle(temp);
- break;
- }
+ if (service->type != temp->type)
+ continue;
+
+ if(!is_interface_available(service, temp)) {
+ if (__connman_service_disconnect(temp) == -EINPROGRESS)
+ err = -EINPROGRESS;
}
}
+ if (err == -EINPROGRESS)
+ return __connman_error_in_progress(msg);
- service->ignore = FALSE;
-
- service->userconnect = TRUE;
+ service->ignore = false;
service->pending = dbus_message_ref(msg);
- set_reconnect_state(service, FALSE);
-
- err = __connman_service_connect(service);
- if (err < 0) {
- if (service->pending == NULL)
- return NULL;
+ err = __connman_service_connect(service,
+ CONNMAN_SERVICE_CONNECT_REASON_USER);
- if (err != -EINPROGRESS) {
- dbus_message_unref(service->pending);
- service->pending = NULL;
+ if (err == -EINPROGRESS)
+ return NULL;
- return __connman_error_failed(msg, -err);
- }
+ dbus_message_unref(service->pending);
+ service->pending = NULL;
- return NULL;
- }
+ if (err < 0)
+ return __connman_error_failed(msg, -err);
return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
}
@@ -3805,11 +4039,7 @@ static DBusMessage *disconnect_service(DBusConnection *conn,
DBG("service %p", service);
- reply_pending(service, ECONNABORTED);
-
- service->ignore = TRUE;
-
- set_reconnect_state(service, FALSE);
+ service->ignore = true;
err = __connman_service_disconnect(service);
if (err < 0) {
@@ -3820,28 +4050,25 @@ static DBusMessage *disconnect_service(DBusConnection *conn,
return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
}
-gboolean __connman_service_remove(struct connman_service *service)
+bool __connman_service_remove(struct connman_service *service)
{
- if (service->type == CONNMAN_SERVICE_TYPE_ETHERNET)
- return FALSE;
+ if (service->type == CONNMAN_SERVICE_TYPE_ETHERNET ||
+ service->type == CONNMAN_SERVICE_TYPE_GADGET)
+ return false;
- if (service->immutable == TRUE || service->hidden == TRUE)
- return FALSE;
+ if (service->immutable || service->hidden ||
+ __connman_provider_is_immutable(service->provider))
+ return false;
- if (service->favorite == FALSE && service->state !=
+ if (!service->favorite && service->state !=
CONNMAN_SERVICE_STATE_FAILURE)
- return FALSE;
-
- set_reconnect_state(service, FALSE);
+ return false;
__connman_service_disconnect(service);
g_free(service->passphrase);
service->passphrase = NULL;
- g_free(service->agent_passphrase);
- service->agent_passphrase = NULL;
-
g_free(service->identity);
service->identity = NULL;
@@ -3851,13 +4078,13 @@ gboolean __connman_service_remove(struct connman_service *service)
g_free(service->eap);
service->eap = NULL;
- set_idle(service);
+ service->error = CONNMAN_SERVICE_ERROR_UNKNOWN;
- __connman_service_set_favorite(service, FALSE);
+ __connman_service_set_favorite(service, false);
service_save(service);
- return TRUE;
+ return true;
}
static DBusMessage *remove_service(DBusConnection *conn,
@@ -3867,13 +4094,13 @@ static DBusMessage *remove_service(DBusConnection *conn,
DBG("service %p", service);
- if (__connman_service_remove(service) == FALSE)
+ if (!__connman_service_remove(service))
return __connman_error_not_supported(msg);
return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
}
-static gboolean check_suitable_state(enum connman_service_state a,
+static bool check_suitable_state(enum connman_service_state a,
enum connman_service_state b)
{
/*
@@ -3884,14 +4111,14 @@ static gboolean check_suitable_state(enum connman_service_state a,
b == CONNMAN_SERVICE_STATE_READY) ||
(b == CONNMAN_SERVICE_STATE_ONLINE &&
a == CONNMAN_SERVICE_STATE_READY))
- return TRUE;
+ return true;
return a == b;
}
static void downgrade_state(struct connman_service *service)
{
- if (service == NULL)
+ if (!service)
return;
DBG("service %p state4 %d state6 %d", service, service->state_ipv4,
@@ -3913,13 +4140,14 @@ static void apply_relevant_default_downgrade(struct connman_service *service)
struct connman_service *def_service;
def_service = __connman_service_get_default();
- if (def_service == NULL)
+ if (!def_service)
return;
if (def_service == service &&
def_service->state == CONNMAN_SERVICE_STATE_ONLINE) {
def_service->state = CONNMAN_SERVICE_STATE_READY;
__connman_notifier_leave_online(def_service->type);
+ state_changed(def_service);
}
}
@@ -3946,7 +4174,7 @@ static void switch_default_service(struct connman_service *default_service,
static DBusMessage *move_service(DBusConnection *conn,
DBusMessage *msg, void *user_data,
- gboolean before)
+ bool before)
{
struct connman_service *service = user_data;
struct connman_service *target;
@@ -3959,11 +4187,11 @@ static DBusMessage *move_service(DBusConnection *conn,
dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
DBUS_TYPE_INVALID);
- if (service->favorite == FALSE)
+ if (!service->favorite)
return __connman_error_not_supported(msg);
target = find_service(path);
- if (target == NULL || target->favorite == FALSE || target == service)
+ if (!target || !target->favorite || target == service)
return __connman_error_invalid_service(msg);
if (target->type == CONNMAN_SERVICE_TYPE_VPN) {
@@ -3971,19 +4199,18 @@ static DBusMessage *move_service(DBusConnection *conn,
* We only allow VPN route splitting if there are
* routes defined for a given VPN.
*/
- if (__connman_provider_check_routes(target->provider)
- == FALSE) {
+ if (!__connman_provider_check_routes(target->provider)) {
connman_info("Cannot move service. "
"No routes defined for provider %s",
__connman_provider_get_ident(target->provider));
return __connman_error_invalid_service(msg);
}
- target->do_split_routing = TRUE;
+ target->do_split_routing = true;
} else
- target->do_split_routing = FALSE;
+ target->do_split_routing = false;
- service->do_split_routing = FALSE;
+ service->do_split_routing = false;
target4 = __connman_ipconfig_get_method(target->ipconfig_ipv4);
target6 = __connman_ipconfig_get_method(target->ipconfig_ipv6);
@@ -4004,32 +4231,32 @@ static DBusMessage *move_service(DBusConnection *conn,
*/
if (target4 == CONNMAN_IPCONFIG_METHOD_OFF) {
if (service6 != CONNMAN_IPCONFIG_METHOD_OFF) {
- if (check_suitable_state(target->state_ipv6,
- service->state_ipv6) == FALSE)
+ if (!check_suitable_state(target->state_ipv6,
+ service->state_ipv6))
return __connman_error_invalid_service(msg);
}
}
if (target6 == CONNMAN_IPCONFIG_METHOD_OFF) {
if (service4 != CONNMAN_IPCONFIG_METHOD_OFF) {
- if (check_suitable_state(target->state_ipv4,
- service->state_ipv4) == FALSE)
+ if (!check_suitable_state(target->state_ipv4,
+ service->state_ipv4))
return __connman_error_invalid_service(msg);
}
}
if (service4 == CONNMAN_IPCONFIG_METHOD_OFF) {
if (target6 != CONNMAN_IPCONFIG_METHOD_OFF) {
- if (check_suitable_state(target->state_ipv6,
- service->state_ipv6) == FALSE)
+ if (!check_suitable_state(target->state_ipv6,
+ service->state_ipv6))
return __connman_error_invalid_service(msg);
}
}
if (service6 == CONNMAN_IPCONFIG_METHOD_OFF) {
if (target4 != CONNMAN_IPCONFIG_METHOD_OFF) {
- if (check_suitable_state(target->state_ipv4,
- service->state_ipv4) == FALSE)
+ if (!check_suitable_state(target->state_ipv4,
+ service->state_ipv4))
return __connman_error_invalid_service(msg);
}
}
@@ -4044,7 +4271,7 @@ static DBusMessage *move_service(DBusConnection *conn,
* the service which goes up, needs to recompute its state which
* is triggered via downgrading it - if relevant - to state ready.
*/
- if (before == TRUE)
+ if (before)
switch_default_service(target, service);
else
switch_default_service(service, target);
@@ -4057,13 +4284,13 @@ static DBusMessage *move_service(DBusConnection *conn,
static DBusMessage *move_before(DBusConnection *conn,
DBusMessage *msg, void *user_data)
{
- return move_service(conn, msg, user_data, TRUE);
+ return move_service(conn, msg, user_data, true);
}
static DBusMessage *move_after(DBusConnection *conn,
DBusMessage *msg, void *user_data)
{
- return move_service(conn, msg, user_data, FALSE);
+ return move_service(conn, msg, user_data, false);
}
static DBusMessage *reset_counters(DBusConnection *conn,
@@ -4087,12 +4314,12 @@ static void service_append_added_foreach(gpointer data, gpointer user_data)
struct connman_service *service = data;
DBusMessageIter *iter = user_data;
- if (service == NULL || service->path == NULL) {
+ if (!service || !service->path) {
DBG("service %p or path is NULL", service);
return;
}
- if (g_hash_table_lookup(services_notify->add, service->path) != NULL) {
+ if (g_hash_table_lookup(services_notify->add, service->path)) {
DBG("new %s", service->path);
append_struct(service, iter);
@@ -4118,10 +4345,14 @@ static void append_removed(gpointer key, gpointer value, gpointer user_data)
dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH, &objpath);
}
+static void service_append_removed(DBusMessageIter *iter, void *user_data)
+{
+ g_hash_table_foreach(services_notify->remove, append_removed, iter);
+}
+
static gboolean service_send_changed(gpointer data)
{
DBusMessage *signal;
- DBusMessageIter iter, array;
DBG("");
@@ -4129,19 +4360,13 @@ static gboolean service_send_changed(gpointer data)
signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH,
CONNMAN_MANAGER_INTERFACE, "ServicesChanged");
- if (signal == NULL)
+ if (!signal)
return FALSE;
__connman_dbus_append_objpath_dict_array(signal,
- service_append_ordered, NULL);
-
- dbus_message_iter_init_append(signal, &iter);
- dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
- DBUS_TYPE_OBJECT_PATH_AS_STRING, &array);
-
- g_hash_table_foreach(services_notify->remove, append_removed, &array);
-
- dbus_message_iter_close_container(&iter, &array);
+ service_append_ordered, NULL);
+ __connman_dbus_append_objpath_array(signal,
+ service_append_removed, NULL);
dbus_connection_send(connection, signal, NULL);
dbus_message_unref(signal);
@@ -4174,7 +4399,7 @@ static void service_schedule_removed(struct connman_service *service)
{
DBG("service %p %s", service, service->path);
- if (service == NULL || service->path == NULL) {
+ if (!service || !service->path) {
DBG("service %p or path is NULL", service);
return;
}
@@ -4186,15 +4411,15 @@ static void service_schedule_removed(struct connman_service *service)
service_schedule_changed();
}
-static connman_bool_t allow_property_changed(struct connman_service *service)
+static bool allow_property_changed(struct connman_service *service)
{
if (g_hash_table_lookup_extended(services_notify->add, service->path,
- NULL, NULL) == TRUE) {
+ NULL, NULL)) {
DBG("no property updates for service %p", service);
- return FALSE;
+ return false;
}
- return TRUE;
+ return true;
}
static const GDBusMethodTable service_methods[] = {
@@ -4245,7 +4470,7 @@ static void service_free(gpointer user_data)
service->path = NULL;
- if (path != NULL) {
+ if (path) {
__connman_connection_update_gateway();
g_dbus_unregister_interface(connection, path,
@@ -4255,23 +4480,23 @@ static void service_free(gpointer user_data)
g_hash_table_destroy(service->counter_table);
- if (service->network != NULL) {
+ if (service->network) {
__connman_network_disconnect(service->network);
connman_network_unref(service->network);
service->network = NULL;
}
- if (service->provider != NULL)
+ if (service->provider)
connman_provider_unref(service->provider);
- if (service->ipconfig_ipv4 != NULL) {
+ if (service->ipconfig_ipv4) {
__connman_ipconfig_set_ops(service->ipconfig_ipv4, NULL);
__connman_ipconfig_set_data(service->ipconfig_ipv4, NULL);
__connman_ipconfig_unref(service->ipconfig_ipv4);
service->ipconfig_ipv4 = NULL;
}
- if (service->ipconfig_ipv6 != NULL) {
+ if (service->ipconfig_ipv6) {
__connman_ipconfig_set_ops(service->ipconfig_ipv6, NULL);
__connman_ipconfig_set_data(service->ipconfig_ipv6, NULL);
__connman_ipconfig_unref(service->ipconfig_ipv6);
@@ -4287,11 +4512,11 @@ static void service_free(gpointer user_data)
g_strfreev(service->proxies);
g_strfreev(service->excludes);
+ g_free(service->hostname);
g_free(service->domainname);
g_free(service->pac);
g_free(service->name);
g_free(service->passphrase);
- g_free(service->agent_passphrase);
g_free(service->identifier);
g_free(service->eap);
g_free(service->identity);
@@ -4304,24 +4529,27 @@ static void service_free(gpointer user_data)
g_free(service->config_file);
g_free(service->config_entry);
- if (service->stats.timer != NULL)
+ if (service->stats.timer)
g_timer_destroy(service->stats.timer);
- if (service->stats_roaming.timer != NULL)
+ if (service->stats_roaming.timer)
g_timer_destroy(service->stats_roaming.timer);
+ if (current_default == service)
+ current_default = NULL;
+
g_free(service);
}
static void stats_init(struct connman_service *service)
{
/* home */
- service->stats.valid = FALSE;
- service->stats.enabled = FALSE;
+ service->stats.valid = false;
+ service->stats.enabled = false;
service->stats.timer = g_timer_new();
/* roaming */
- service->stats_roaming.valid = FALSE;
- service->stats_roaming.enabled = FALSE;
+ service->stats_roaming.valid = false;
+ service->stats_roaming.enabled = false;
service->stats_roaming.timer = g_timer_new();
}
@@ -4330,7 +4558,6 @@ static void service_initialize(struct connman_service *service)
DBG("service %p", service);
service->refcount = 1;
- service->session_usage_count = 0;
service->error = CONNMAN_SERVICE_ERROR_UNKNOWN;
@@ -4341,13 +4568,13 @@ static void service_initialize(struct connman_service *service)
service->state_ipv4 = CONNMAN_SERVICE_STATE_UNKNOWN;
service->state_ipv6 = CONNMAN_SERVICE_STATE_UNKNOWN;
- service->favorite = FALSE;
- service->immutable = FALSE;
- service->hidden = FALSE;
+ service->favorite = false;
+ service->immutable = false;
+ service->hidden = false;
- service->ignore = FALSE;
+ service->ignore = false;
- service->userconnect = FALSE;
+ service->connect_reason = CONNMAN_SERVICE_CONNECT_REASON_NONE;
service->order = 0;
@@ -4355,7 +4582,7 @@ static void service_initialize(struct connman_service *service)
service->provider = NULL;
- service->wps = FALSE;
+ service->wps = false;
}
/**
@@ -4374,7 +4601,7 @@ struct connman_service *connman_service_create(void)
struct connman_service *service;
service = g_try_new0(struct connman_service, 1);
- if (service == NULL)
+ if (!service)
return NULL;
DBG("service %p", service);
@@ -4386,13 +4613,13 @@ struct connman_service *connman_service_create(void)
counter = list->data;
counters = g_try_new0(struct connman_stats_counter, 1);
- if (counters == NULL) {
+ if (!counters) {
g_hash_table_destroy(service->counter_table);
g_free(service);
return NULL;
}
- counters->append_all = TRUE;
+ counters->append_all = true;
g_hash_table_replace(service->counter_table, (gpointer)counter,
counters);
@@ -4439,7 +4666,6 @@ void connman_service_unref_debug(struct connman_service *service,
service_list = g_list_remove(service_list, service);
- reply_pending(service, ECONNABORTED);
__connman_service_disconnect(service);
g_hash_table_remove(service_hash, service->identifier);
@@ -4450,15 +4676,24 @@ static gint service_compare(gconstpointer a, gconstpointer b)
struct connman_service *service_a = (void *) a;
struct connman_service *service_b = (void *) b;
enum connman_service_state state_a, state_b;
+ bool a_connected, b_connected;
+ gint strength;
state_a = service_a->state;
state_b = service_b->state;
+ a_connected = is_connected(service_a);
+ b_connected = is_connected(service_b);
- if (state_a != state_b) {
- gboolean a_connected = is_connected(service_a);
- gboolean b_connected = is_connected(service_b);
+ if (a_connected && b_connected) {
+ if (service_a->order > service_b->order)
+ return -1;
+
+ if (service_a->order < service_b->order)
+ return 1;
+ }
- if (a_connected == TRUE && b_connected == TRUE) {
+ if (state_a != state_b) {
+ if (a_connected && b_connected) {
/* We prefer online over ready state */
if (state_a == CONNMAN_SERVICE_STATE_ONLINE)
return -1;
@@ -4467,47 +4702,69 @@ static gint service_compare(gconstpointer a, gconstpointer b)
return 1;
}
- if (a_connected == TRUE)
+ if (a_connected)
return -1;
- if (b_connected == TRUE)
+ if (b_connected)
return 1;
- if (is_connecting(service_a) == TRUE)
+ if (is_connecting(service_a))
return -1;
- if (is_connecting(service_b) == TRUE)
+ if (is_connecting(service_b))
return 1;
}
- if (service_a->order > service_b->order)
+ if (service_a->favorite && !service_b->favorite)
return -1;
- if (service_a->order < service_b->order)
+ if (!service_a->favorite && service_b->favorite)
return 1;
- if (service_a->favorite == TRUE && service_b->favorite == FALSE)
- return -1;
+ if (service_a->type != service_b->type) {
- if (service_a->favorite == FALSE && service_b->favorite == TRUE)
- return 1;
+ if (service_a->type == CONNMAN_SERVICE_TYPE_ETHERNET)
+ return -1;
+ if (service_b->type == CONNMAN_SERVICE_TYPE_ETHERNET)
+ return 1;
- if (service_a->type != service_b->type) {
- switch (service_a->type) {
- case CONNMAN_SERVICE_TYPE_UNKNOWN:
- case CONNMAN_SERVICE_TYPE_SYSTEM:
- case CONNMAN_SERVICE_TYPE_ETHERNET:
- case CONNMAN_SERVICE_TYPE_GPS:
- case CONNMAN_SERVICE_TYPE_VPN:
- case CONNMAN_SERVICE_TYPE_GADGET:
- break;
- case CONNMAN_SERVICE_TYPE_WIFI:
+ if (service_a->type == CONNMAN_SERVICE_TYPE_WIFI)
+ return -1;
+ if (service_b->type == CONNMAN_SERVICE_TYPE_WIFI)
return 1;
- case CONNMAN_SERVICE_TYPE_BLUETOOTH:
- case CONNMAN_SERVICE_TYPE_CELLULAR:
+
+ if (service_a->type == CONNMAN_SERVICE_TYPE_CELLULAR)
return -1;
- }
+ if (service_b->type == CONNMAN_SERVICE_TYPE_CELLULAR)
+ return 1;
+
+ if (service_a->type == CONNMAN_SERVICE_TYPE_BLUETOOTH)
+ return -1;
+ if (service_b->type == CONNMAN_SERVICE_TYPE_BLUETOOTH)
+ return 1;
+
+ if (service_a->type == CONNMAN_SERVICE_TYPE_VPN)
+ return -1;
+ if (service_b->type == CONNMAN_SERVICE_TYPE_VPN)
+ return 1;
+
+ if (service_a->type == CONNMAN_SERVICE_TYPE_GADGET)
+ return -1;
+ if (service_b->type == CONNMAN_SERVICE_TYPE_GADGET)
+ return 1;
}
- return (gint) service_b->strength - (gint) service_a->strength;
+ strength = (gint) service_b->strength - (gint) service_a->strength;
+ if (strength)
+ return strength;
+
+ return g_strcmp0(service_a->name, service_b->name);
+}
+
+static void service_list_sort(void)
+{
+ if (service_list && service_list->next) {
+ service_list = g_list_sort(service_list, service_compare);
+ service_schedule_changed();
+ }
}
/**
@@ -4518,7 +4775,7 @@ static gint service_compare(gconstpointer a, gconstpointer b)
*/
enum connman_service_type connman_service_get_type(struct connman_service *service)
{
- if (service == NULL)
+ if (!service)
return CONNMAN_SERVICE_TYPE_UNKNOWN;
return service->type;
@@ -4534,26 +4791,10 @@ char *connman_service_get_interface(struct connman_service *service)
{
int index;
- if (service == NULL)
+ if (!service)
return NULL;
- if (service->type == CONNMAN_SERVICE_TYPE_VPN) {
- if (service->ipconfig_ipv4)
- index = __connman_ipconfig_get_index(
- service->ipconfig_ipv4);
- else if (service->ipconfig_ipv6)
- index = __connman_ipconfig_get_index(
- service->ipconfig_ipv6);
- else
- return NULL;
-
- return connman_inet_ifname(index);
- }
-
- if (service->network == NULL)
- return NULL;
-
- index = connman_network_get_index(service->network);
+ index = __connman_service_get_index(service);
return connman_inet_ifname(index);
}
@@ -4567,7 +4808,7 @@ char *connman_service_get_interface(struct connman_service *service)
struct connman_network *
__connman_service_get_network(struct connman_service *service)
{
- if (service == NULL)
+ if (!service)
return NULL;
return service->network;
@@ -4576,7 +4817,7 @@ __connman_service_get_network(struct connman_service *service)
struct connman_ipconfig *
__connman_service_get_ip4config(struct connman_service *service)
{
- if (service == NULL)
+ if (!service)
return NULL;
return service->ipconfig_ipv4;
@@ -4585,7 +4826,7 @@ __connman_service_get_ip4config(struct connman_service *service)
struct connman_ipconfig *
__connman_service_get_ip6config(struct connman_service *service)
{
- if (service == NULL)
+ if (!service)
return NULL;
return service->ipconfig_ipv6;
@@ -4603,11 +4844,11 @@ __connman_service_get_ipconfig(struct connman_service *service, int family)
}
-connman_bool_t __connman_service_is_connected_state(struct connman_service *service,
+bool __connman_service_is_connected_state(struct connman_service *service,
enum connman_ipconfig_type type)
{
- if (service == NULL)
- return FALSE;
+ if (!service)
+ return false;
switch (type) {
case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
@@ -4618,11 +4859,12 @@ connman_bool_t __connman_service_is_connected_state(struct connman_service *serv
return is_connected_state(service, service->state_ipv6);
}
- return FALSE;
+ return false;
}
-enum connman_service_security __connman_service_get_security(struct connman_service *service)
+enum connman_service_security __connman_service_get_security(
+ struct connman_service *service)
{
- if (service == NULL)
+ if (!service)
return CONNMAN_SERVICE_SECURITY_UNKNOWN;
return service->security;
@@ -4630,24 +4872,24 @@ enum connman_service_security __connman_service_get_security(struct connman_serv
const char *__connman_service_get_phase2(struct connman_service *service)
{
- if (service == NULL)
+ if (!service)
return NULL;
return service->phase2;
}
-connman_bool_t __connman_service_wps_enabled(struct connman_service *service)
+bool __connman_service_wps_enabled(struct connman_service *service)
{
- if (service == NULL)
- return FALSE;
+ if (!service)
+ return false;
return service->wps;
}
-void __connman_service_mark_dirty()
- {
- services_dirty = TRUE;
- }
+void __connman_service_mark_dirty(void)
+{
+ services_dirty = true;
+}
/**
* __connman_service_set_favorite_delayed:
@@ -4658,10 +4900,10 @@ void __connman_service_mark_dirty()
* Change the favorite setting of service
*/
int __connman_service_set_favorite_delayed(struct connman_service *service,
- connman_bool_t favorite,
- gboolean delay_ordering)
+ bool favorite,
+ bool delay_ordering)
{
- if (service->hidden == TRUE)
+ if (service->hidden)
return -EOPNOTSUPP;
if (service->favorite == favorite)
@@ -4669,18 +4911,14 @@ int __connman_service_set_favorite_delayed(struct connman_service *service,
service->favorite = favorite;
- if (delay_ordering == FALSE)
- service->order = __connman_service_get_order(service);
+ if (!delay_ordering)
+ __connman_service_get_order(service);
favorite_changed(service);
- if (delay_ordering == FALSE) {
+ if (!delay_ordering) {
- if (service_list->next != NULL) {
- service_list = g_list_sort(service_list,
- service_compare);
- service_schedule_changed();
- }
+ service_list_sort();
__connman_connection_update_gateway();
}
@@ -4696,21 +4934,26 @@ int __connman_service_set_favorite_delayed(struct connman_service *service,
* Change the favorite setting of service
*/
int __connman_service_set_favorite(struct connman_service *service,
- connman_bool_t favorite)
+ bool favorite)
{
return __connman_service_set_favorite_delayed(service, favorite,
- FALSE);
+ false);
}
-connman_bool_t connman_service_get_favorite(struct connman_service *service)
+bool connman_service_get_favorite(struct connman_service *service)
{
- return service->favorite;
+ return service->favorite;
+}
+
+bool connman_service_get_autoconnect(struct connman_service *service)
+{
+ return service->autoconnect;
}
int __connman_service_set_immutable(struct connman_service *service,
- connman_bool_t immutable)
+ bool immutable)
{
- if (service->hidden == TRUE)
+ if (service->hidden)
return -EOPNOTSUPP;
if (service->immutable == immutable)
@@ -4724,9 +4967,9 @@ int __connman_service_set_immutable(struct connman_service *service,
}
int __connman_service_set_ignore(struct connman_service *service,
- connman_bool_t ignore)
+ bool ignore)
{
- if (service == NULL)
+ if (!service)
return -EINVAL;
service->ignore = ignore;
@@ -4737,42 +4980,35 @@ int __connman_service_set_ignore(struct connman_service *service,
void __connman_service_set_string(struct connman_service *service,
const char *key, const char *value)
{
- if (service->hidden == TRUE)
+ if (service->hidden)
return;
- if (g_str_equal(key, "EAP") == TRUE) {
+ if (g_str_equal(key, "EAP")) {
g_free(service->eap);
service->eap = g_strdup(value);
- } else if (g_str_equal(key, "Identity") == TRUE) {
+ } else if (g_str_equal(key, "Identity")) {
g_free(service->identity);
service->identity = g_strdup(value);
- } else if (g_str_equal(key, "CACertFile") == TRUE) {
+ } else if (g_str_equal(key, "CACertFile")) {
g_free(service->ca_cert_file);
service->ca_cert_file = g_strdup(value);
- } else if (g_str_equal(key, "ClientCertFile") == TRUE) {
+ } else if (g_str_equal(key, "ClientCertFile")) {
g_free(service->client_cert_file);
service->client_cert_file = g_strdup(value);
- } else if (g_str_equal(key, "PrivateKeyFile") == TRUE) {
+ } else if (g_str_equal(key, "PrivateKeyFile")) {
g_free(service->private_key_file);
service->private_key_file = g_strdup(value);
- } else if (g_str_equal(key, "PrivateKeyPassphrase") == TRUE) {
+ } else if (g_str_equal(key, "PrivateKeyPassphrase")) {
g_free(service->private_key_passphrase);
service->private_key_passphrase = g_strdup(value);
- } else if (g_str_equal(key, "Phase2") == TRUE) {
+ } else if (g_str_equal(key, "Phase2")) {
g_free(service->phase2);
service->phase2 = g_strdup(value);
- } else if (g_str_equal(key, "Passphrase") == TRUE) {
+ } else if (g_str_equal(key, "Passphrase")) {
g_free(service->passphrase);
service->passphrase = g_strdup(value);
}
}
-void __connman_service_set_userconnect(struct connman_service *service,
- connman_bool_t userconnect)
-{
- if (service != NULL)
- service->userconnect = userconnect;
-}
-
void __connman_service_set_search_domains(struct connman_service *service,
char **domains)
{
@@ -4782,7 +5018,7 @@ void __connman_service_set_search_domains(struct connman_service *service,
if (index < 0)
return;
- if (service->domains != NULL) {
+ if (service->domains) {
remove_searchdomains(service, index, service->domains);
g_strfreev(service->domains);
@@ -4792,24 +5028,37 @@ void __connman_service_set_search_domains(struct connman_service *service,
}
}
+/*
+ * This variant is used when domain search list is updated via
+ * dhcp and in that case the service is not yet fully connected so
+ * we cannot do same things as what the set() variant is doing.
+ */
+void __connman_service_update_search_domains(struct connman_service *service,
+ char **domains)
+{
+ g_strfreev(service->domains);
+ service->domains = g_strdupv(domains);
+}
+
static void service_complete(struct connman_service *service)
{
reply_pending(service, EIO);
- if (service->userconnect == FALSE)
- __connman_service_auto_connect();
+ if (service->connect_reason != CONNMAN_SERVICE_CONNECT_REASON_USER)
+ __connman_service_auto_connect(service->connect_reason);
g_get_current_time(&service->modified);
service_save(service);
}
-static void report_error_cb(void *user_context, gboolean retry,
+static void report_error_cb(void *user_context, bool retry,
void *user_data)
{
struct connman_service *service = user_context;
- if (retry == TRUE)
- __connman_service_connect(service);
+ if (retry)
+ __connman_service_connect(service,
+ CONNMAN_SERVICE_CONNECT_REASON_USER);
else {
/* It is not relevant to stay on Failure state
* when failing is due to wrong user input */
@@ -4828,12 +5077,10 @@ int __connman_service_add_passphrase(struct connman_service *service,
switch (service->security) {
case CONNMAN_SERVICE_SECURITY_WEP:
case CONNMAN_SERVICE_SECURITY_PSK:
- err = __connman_service_set_passphrase(service, passphrase);
- break;
case CONNMAN_SERVICE_SECURITY_8021X:
- __connman_service_set_agent_passphrase(service,
- passphrase);
+ err = __connman_service_set_passphrase(service, passphrase);
break;
+
case CONNMAN_SERVICE_SECURITY_UNKNOWN:
case CONNMAN_SERVICE_SECURITY_NONE:
case CONNMAN_SERVICE_SECURITY_WPA:
@@ -4852,7 +5099,7 @@ static int check_wpspin(struct connman_service *service, const char *wpspin)
int length;
guint i;
- if (wpspin == NULL)
+ if (!wpspin)
return 0;
length = strlen(wpspin);
@@ -4879,53 +5126,56 @@ static int check_wpspin(struct connman_service *service, const char *wpspin)
return 0;
}
-static void request_input_cb (struct connman_service *service,
- connman_bool_t values_received,
+static void request_input_cb(struct connman_service *service,
+ bool values_received,
const char *name, int name_len,
const char *identity, const char *passphrase,
- gboolean wps, const char *wpspin,
+ bool wps, const char *wpspin,
const char *error, void *user_data)
{
struct connman_device *device;
+ const char *security;
int err = 0;
- DBG ("RequestInput return, %p", service);
+ DBG("RequestInput return, %p", service);
- if (error != NULL) {
+ if (error) {
DBG("error: %s", error);
if (g_strcmp0(error,
"net.connman.Agent.Error.Canceled") == 0) {
err = -EINVAL;
- if (service->hidden == TRUE)
+ if (service->hidden)
__connman_service_return_error(service,
ECANCELED, user_data);
goto done;
} else {
- if (service->hidden == TRUE)
+ if (service->hidden)
__connman_service_return_error(service,
ETIMEDOUT, user_data);
}
}
- if (service->hidden == TRUE && name_len > 0 && name_len <= 32) {
+ if (service->hidden && name_len > 0 && name_len <= 32) {
device = connman_network_get_device(service->network);
+ security = connman_network_get_string(service->network,
+ "WiFi.Security");
err = __connman_device_request_hidden_scan(device,
name, name_len,
identity, passphrase,
- user_data);
+ security, user_data);
if (err < 0)
__connman_service_return_error(service, -err,
user_data);
}
- if (values_received == FALSE || service->hidden == TRUE) {
+ if (!values_received || service->hidden) {
err = -EINVAL;
goto done;
}
- if (wps == TRUE && service->network != NULL) {
+ if (wps && service->network) {
err = check_wpspin(service, wpspin);
if (err < 0)
goto done;
@@ -4933,10 +5183,10 @@ static void request_input_cb (struct connman_service *service,
connman_network_set_bool(service->network, "WiFi.UseWPS", wps);
}
- if (identity != NULL)
+ if (identity)
__connman_service_set_agent_identity(service, identity);
- if (passphrase != NULL)
+ if (passphrase)
err = __connman_service_add_passphrase(service, passphrase);
done:
@@ -4944,11 +5194,9 @@ static void request_input_cb (struct connman_service *service,
/* We forget any previous error. */
set_error(service, CONNMAN_SERVICE_ERROR_UNKNOWN);
- __connman_service_connect(service);
+ __connman_service_connect(service,
+ CONNMAN_SERVICE_CONNECT_REASON_USER);
- /* Never cache agent provided credentials */
- __connman_service_set_agent_identity(service, NULL);
- __connman_service_set_agent_passphrase(service, NULL);
} else if (err == -ENOKEY) {
__connman_service_indicate_error(service,
CONNMAN_SERVICE_ERROR_INVALID_KEY);
@@ -4957,7 +5205,7 @@ static void request_input_cb (struct connman_service *service,
* when failing is due to wrong user input */
service->state = CONNMAN_SERVICE_STATE_IDLE;
- if (service->hidden == FALSE) {
+ if (!service->hidden) {
/*
* If there was a real error when requesting
* hidden scan, then that error is returned already
@@ -4978,10 +5226,10 @@ static void downgrade_connected_services(void)
struct connman_service *up_service;
GList *list;
- for (list = service_list; list != NULL; list = list->next) {
+ for (list = service_list; list; list = list->next) {
up_service = list->data;
- if (is_connected(up_service) == FALSE)
+ if (!is_connected(up_service))
continue;
if (up_service->state == CONNMAN_SERVICE_STATE_ONLINE)
@@ -4998,12 +5246,12 @@ static int service_update_preferred_order(struct connman_service *default_servic
unsigned int *tech_array;
int i;
- if (default_service == NULL || default_service == new_service ||
- default_service->state != new_state )
+ if (!default_service || default_service == new_service ||
+ default_service->state != new_state)
return 0;
tech_array = connman_setting_get_uint_list("PreferredTechnologies");
- if (tech_array != NULL) {
+ if (tech_array) {
for (i = 0; tech_array[i] != 0; i += 1) {
if (default_service->type == tech_array[i])
@@ -5029,10 +5277,10 @@ static void single_connected_tech(struct connman_service *allowed)
DBG("keeping %p %s", allowed, allowed->path);
- for (iter = service_list; iter != NULL; iter = iter->next) {
+ for (iter = service_list; iter; iter = iter->next) {
service = iter->data;
- if (is_connected(service) == FALSE)
+ if (!is_connected(service))
break;
if (service == allowed)
@@ -5041,7 +5289,7 @@ static void single_connected_tech(struct connman_service *allowed)
services = g_slist_prepend(services, service);
}
- for (list = services; list != NULL; list = list->next) {
+ for (list = services; list; list = list->next) {
service = list->data;
DBG("disconnecting %p %s", service, service->path);
@@ -5051,13 +5299,21 @@ static void single_connected_tech(struct connman_service *allowed)
g_slist_free(services);
}
+static const char *get_dbus_sender(struct connman_service *service)
+{
+ if (!service->pending)
+ return NULL;
+
+ return dbus_message_get_sender(service->pending);
+}
+
static int service_indicate_state(struct connman_service *service)
{
enum connman_service_state old_state, new_state;
struct connman_service *def_service;
int result;
- if (service == NULL)
+ if (!service)
return -EINVAL;
old_state = service->state;
@@ -5090,63 +5346,55 @@ static int service_indicate_state(struct connman_service *service)
if (new_state == CONNMAN_SERVICE_STATE_IDLE &&
old_state != CONNMAN_SERVICE_STATE_DISCONNECT) {
- reply_pending(service, ECONNABORTED);
__connman_service_disconnect(service);
}
if (new_state == CONNMAN_SERVICE_STATE_CONFIGURATION) {
- if (service->new_service == FALSE &&
+ if (!service->new_service &&
__connman_stats_service_register(service) == 0) {
/*
* For new services the statistics are updated after
* we have successfully connected.
*/
- __connman_stats_get(service, FALSE,
+ __connman_stats_get(service, false,
&service->stats.data);
- __connman_stats_get(service, TRUE,
+ __connman_stats_get(service, true,
&service->stats_roaming.data);
}
}
- if (new_state == CONNMAN_SERVICE_STATE_IDLE) {
- connman_bool_t reconnect;
-
- reconnect = get_reconnect_state(service);
- if (reconnect == TRUE)
- __connman_service_auto_connect();
- }
-
if (new_state == CONNMAN_SERVICE_STATE_READY) {
enum connman_ipconfig_method method;
- if (service->new_service == TRUE &&
+ if (service->new_service &&
__connman_stats_service_register(service) == 0) {
/*
* This is normally done after configuring state
* but for new service do this after we have connected
* successfully.
*/
- __connman_stats_get(service, FALSE,
+ __connman_stats_get(service, false,
&service->stats.data);
- __connman_stats_get(service, TRUE,
+ __connman_stats_get(service, true,
&service->stats_roaming.data);
}
- service->new_service = FALSE;
+ service->new_service = false;
- service_update_preferred_order(def_service, service, new_state);
+ default_changed();
+
+ def_service = __connman_service_get_default();
- set_reconnect_state(service, TRUE);
+ service_update_preferred_order(def_service, service, new_state);
- __connman_service_set_favorite(service, TRUE);
+ __connman_service_set_favorite(service, true);
reply_pending(service, 0);
g_get_current_time(&service->modified);
service_save(service);
- update_nameservers(service);
dns_changed(service);
domain_changed(service);
proxy_changed(service);
@@ -5156,7 +5404,7 @@ static int service_indicate_state(struct connman_service *service)
if (service->type == CONNMAN_SERVICE_TYPE_WIFI &&
connman_network_get_bool(service->network,
- "WiFi.UseWPS") == TRUE) {
+ "WiFi.UseWPS")) {
const char *pass;
pass = connman_network_get_string(service->network,
@@ -5165,26 +5413,25 @@ static int service_indicate_state(struct connman_service *service)
__connman_service_set_passphrase(service, pass);
connman_network_set_bool(service->network,
- "WiFi.UseWPS", FALSE);
+ "WiFi.UseWPS", false);
}
- default_changed();
-
method = __connman_ipconfig_get_method(service->ipconfig_ipv6);
if (method == CONNMAN_IPCONFIG_METHOD_OFF)
__connman_ipconfig_disable_ipv6(
service->ipconfig_ipv6);
- if (connman_setting_get_bool("SingleConnectedTechnology")
- == TRUE)
+ if (connman_setting_get_bool("SingleConnectedTechnology"))
single_connected_tech(service);
+ else if (service->type != CONNMAN_SERVICE_TYPE_VPN)
+ vpn_auto_connect();
} else if (new_state == CONNMAN_SERVICE_STATE_DISCONNECT) {
def_service = __connman_service_get_default();
- if (__connman_notifier_is_connected() == FALSE &&
- def_service != NULL &&
- def_service->provider != NULL)
+ if (!__connman_notifier_is_connected() &&
+ def_service &&
+ def_service->provider)
connman_provider_disconnect(def_service->provider);
default_changed();
@@ -5193,38 +5440,44 @@ static int service_indicate_state(struct connman_service *service)
__connman_wpad_stop(service);
- update_nameservers(service);
dns_changed(service);
domain_changed(service);
proxy_changed(service);
- __connman_notifier_disconnect(service->type);
-
/*
* Previous services which are connected and which states
* are set to online should reset relevantly ipconfig_state
* to ready so wispr/portal will be rerun on those
*/
downgrade_connected_services();
+
+ __connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO);
}
if (new_state == CONNMAN_SERVICE_STATE_FAILURE) {
- if (service->userconnect == TRUE &&
+
+ if (service->connect_reason == CONNMAN_SERVICE_CONNECT_REASON_USER &&
connman_agent_report_error(service, service->path,
error2string(service->error),
- report_error_cb, NULL) == -EINPROGRESS)
+ report_error_cb,
+ get_dbus_sender(service),
+ NULL) == -EINPROGRESS)
return 0;
service_complete(service);
} else
set_error(service, CONNMAN_SERVICE_ERROR_UNKNOWN);
- if (service_list->next != NULL) {
- service_list = g_list_sort(service_list, service_compare);
- service_schedule_changed();
- }
+ service_list_sort();
__connman_connection_update_gateway();
+ if ((old_state == CONNMAN_SERVICE_STATE_ONLINE &&
+ new_state != CONNMAN_SERVICE_STATE_READY) ||
+ (old_state == CONNMAN_SERVICE_STATE_READY &&
+ new_state != CONNMAN_SERVICE_STATE_ONLINE)) {
+ __connman_notifier_disconnect(service->type);
+ }
+
if (new_state == CONNMAN_SERVICE_STATE_ONLINE) {
__connman_notifier_enter_online(service->type);
default_changed();
@@ -5238,14 +5491,21 @@ int __connman_service_indicate_error(struct connman_service *service,
{
DBG("service %p error %d", service, error);
- if (service == NULL)
+ if (!service)
return -EINVAL;
set_error(service, error);
- if (service->error == CONNMAN_SERVICE_ERROR_INVALID_KEY)
+ /*
+ * Supplicant does not always return invalid key error for
+ * WPA-EAP so clear the credentials always.
+ */
+ if (service->error == CONNMAN_SERVICE_ERROR_INVALID_KEY ||
+ service->security == CONNMAN_SERVICE_SECURITY_8021X)
__connman_service_set_passphrase(service, NULL);
+ __connman_service_set_agent_identity(service, NULL);
+
__connman_service_ipconfig_indicate_state(service,
CONNMAN_SERVICE_STATE_FAILURE,
CONNMAN_IPCONFIG_TYPE_IPV4);
@@ -5259,7 +5519,7 @@ int __connman_service_clear_error(struct connman_service *service)
{
DBG("service %p", service);
- if (service == NULL)
+ if (!service)
return -EINVAL;
if (service->state != CONNMAN_SERVICE_STATE_FAILURE)
@@ -5269,9 +5529,6 @@ int __connman_service_clear_error(struct connman_service *service)
CONNMAN_SERVICE_STATE_UNKNOWN;
set_error(service, CONNMAN_SERVICE_ERROR_UNKNOWN);
- if (service->favorite == TRUE)
- set_reconnect_state(service, TRUE);
-
__connman_service_ipconfig_indicate_state(service,
CONNMAN_SERVICE_STATE_IDLE,
CONNMAN_IPCONFIG_TYPE_IPV6);
@@ -5291,7 +5548,16 @@ int __connman_service_clear_error(struct connman_service *service)
int __connman_service_indicate_default(struct connman_service *service)
{
- DBG("service %p", service);
+ DBG("service %p state %s", service, state2string(service->state));
+
+ if (!is_connected(service)) {
+ /*
+ * If service is not yet fully connected, then we must not
+ * change the default yet. The default gw will be changed
+ * after the service state is in ready.
+ */
+ return -EINPROGRESS;
+ }
default_changed();
@@ -5302,7 +5568,7 @@ enum connman_service_state __connman_service_ipconfig_get_state(
struct connman_service *service,
enum connman_ipconfig_type type)
{
- if (service == NULL)
+ if (!service)
return CONNMAN_SERVICE_STATE_UNKNOWN;
if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
@@ -5327,7 +5593,7 @@ static void check_proxy_setup(struct connman_service *service)
if (service->proxy_config != CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN &&
(service->proxy_config != CONNMAN_SERVICE_PROXY_METHOD_AUTO ||
- service->pac != NULL))
+ service->pac))
goto done;
if (__connman_wpad_start(service) < 0) {
@@ -5352,7 +5618,7 @@ static int connected_networks_count;
static int original_rp_filter;
static void service_rp_filter(struct connman_service *service,
- gboolean connected)
+ bool connected)
{
enum connman_ipconfig_method method;
@@ -5369,7 +5635,7 @@ static void service_rp_filter(struct connman_service *service,
break;
}
- if (connected == TRUE) {
+ if (connected) {
if (connected_networks_count == 1) {
int filter_value;
filter_value = __connman_ipconfig_set_rp_filter();
@@ -5398,8 +5664,13 @@ static void service_rp_filter(struct connman_service *service,
static gboolean redo_wispr(gpointer user_data)
{
struct connman_service *service = user_data;
+ int refcount = service->refcount - 1;
- DBG("");
+ connman_service_unref(service);
+ if (refcount == 0) {
+ DBG("Service %p already removed", service);
+ return FALSE;
+ }
__connman_wispr_start(service, CONNMAN_IPCONFIG_TYPE_IPV6);
@@ -5427,7 +5698,7 @@ int __connman_service_online_check_failed(struct connman_service *service,
* necessary IPv6 router advertisement messages that might have
* DNS data etc.
*/
- g_timeout_add_seconds(1, redo_wispr, service);
+ g_timeout_add_seconds(1, redo_wispr, connman_service_ref(service));
return EAGAIN;
}
@@ -5438,9 +5709,9 @@ int __connman_service_ipconfig_indicate_state(struct connman_service *service,
{
struct connman_ipconfig *ipconfig = NULL;
enum connman_service_state old_state;
- int ret;
+ enum connman_ipconfig_method method;
- if (service == NULL)
+ if (!service)
return -EINVAL;
if (type == CONNMAN_IPCONFIG_TYPE_IPV4) {
@@ -5451,7 +5722,7 @@ int __connman_service_ipconfig_indicate_state(struct connman_service *service,
ipconfig = service->ipconfig_ipv6;
}
- if (ipconfig == NULL)
+ if (!ipconfig)
return -EINVAL;
/* Any change? */
@@ -5475,11 +5746,9 @@ int __connman_service_ipconfig_indicate_state(struct connman_service *service,
__connman_ipconfig_enable(ipconfig);
break;
case CONNMAN_SERVICE_STATE_READY:
- update_nameservers(service);
-
if (type == CONNMAN_IPCONFIG_TYPE_IPV4) {
check_proxy_setup(service);
- service_rp_filter(service, TRUE);
+ service_rp_filter(service, true);
} else {
service->online_check_count = 1;
__connman_wispr_start(service, type);
@@ -5492,48 +5761,42 @@ int __connman_service_ipconfig_indicate_state(struct connman_service *service,
return -EINVAL;
if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
- service_rp_filter(service, FALSE);
+ service_rp_filter(service, false);
break;
case CONNMAN_SERVICE_STATE_FAILURE:
break;
}
- /* We keep that state */
- if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
- service->state_ipv4 = new_state;
- else if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
- service->state_ipv6 = new_state;
-
- ret = service_indicate_state(service);
-
- /*
- * If the ipconfig method is OFF, then we set the state to IDLE
- * so that it will not affect the combined state in the future.
+ /* Keep that state, but if the ipconfig method is OFF, then we set
+ the state to IDLE so that it will not affect the combined state
+ in the future.
*/
if (type == CONNMAN_IPCONFIG_TYPE_IPV4) {
- enum connman_ipconfig_method method;
method = __connman_ipconfig_get_method(service->ipconfig_ipv4);
+
if (method == CONNMAN_IPCONFIG_METHOD_OFF ||
- method == CONNMAN_IPCONFIG_METHOD_UNKNOWN) {
- service->state_ipv4 = CONNMAN_SERVICE_STATE_IDLE;
- ret = service_indicate_state(service);
- }
+ method == CONNMAN_IPCONFIG_METHOD_UNKNOWN)
+ new_state = CONNMAN_SERVICE_STATE_IDLE;
+
+ service->state_ipv4 = new_state;
} else if (type == CONNMAN_IPCONFIG_TYPE_IPV6) {
- enum connman_ipconfig_method method;
method = __connman_ipconfig_get_method(service->ipconfig_ipv6);
+
if (method == CONNMAN_IPCONFIG_METHOD_OFF ||
- method == CONNMAN_IPCONFIG_METHOD_UNKNOWN) {
- service->state_ipv6 = CONNMAN_SERVICE_STATE_IDLE;
- ret = service_indicate_state(service);
- }
+ method == CONNMAN_IPCONFIG_METHOD_UNKNOWN)
+ new_state = CONNMAN_SERVICE_STATE_IDLE;
+
+ service->state_ipv6 = new_state;
}
- return ret;
+ update_nameservers(service);
+
+ return service_indicate_state(service);
}
-static connman_bool_t prepare_network(struct connman_service *service)
+static bool prepare_network(struct connman_service *service)
{
enum connman_network_type type;
unsigned int ssid_len;
@@ -5543,56 +5806,57 @@ static connman_bool_t prepare_network(struct connman_service *service)
switch (type) {
case CONNMAN_NETWORK_TYPE_UNKNOWN:
case CONNMAN_NETWORK_TYPE_VENDOR:
- return FALSE;
+ return false;
case CONNMAN_NETWORK_TYPE_WIFI:
- if (connman_network_get_blob(service->network, "WiFi.SSID",
- &ssid_len) == NULL)
- return FALSE;
+ if (!connman_network_get_blob(service->network, "WiFi.SSID",
+ &ssid_len))
+ return false;
- if (service->passphrase != NULL)
+ if (service->passphrase)
connman_network_set_string(service->network,
"WiFi.Passphrase", service->passphrase);
break;
case CONNMAN_NETWORK_TYPE_ETHERNET:
+ case CONNMAN_NETWORK_TYPE_GADGET:
case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
case CONNMAN_NETWORK_TYPE_CELLULAR:
break;
}
- return TRUE;
+ return true;
}
static void prepare_8021x(struct connman_service *service)
{
- if (service->eap != NULL)
+ if (service->eap)
connman_network_set_string(service->network, "WiFi.EAP",
service->eap);
- if (service->identity != NULL)
+ if (service->identity)
connman_network_set_string(service->network, "WiFi.Identity",
service->identity);
- if (service->ca_cert_file != NULL)
+ if (service->ca_cert_file)
connman_network_set_string(service->network, "WiFi.CACertFile",
service->ca_cert_file);
- if (service->client_cert_file != NULL)
+ if (service->client_cert_file)
connman_network_set_string(service->network,
"WiFi.ClientCertFile",
service->client_cert_file);
- if (service->private_key_file != NULL)
+ if (service->private_key_file)
connman_network_set_string(service->network,
"WiFi.PrivateKeyFile",
service->private_key_file);
- if (service->private_key_passphrase != NULL)
+ if (service->private_key_passphrase)
connman_network_set_string(service->network,
"WiFi.PrivateKeyPassphrase",
service->private_key_passphrase);
- if (service->phase2 != NULL)
+ if (service->phase2)
connman_network_set_string(service->network, "WiFi.Phase2",
service->phase2);
}
@@ -5601,16 +5865,17 @@ static int service_connect(struct connman_service *service)
{
int err;
- if (service->hidden == TRUE)
+ if (service->hidden)
return -EPERM;
switch (service->type) {
case CONNMAN_SERVICE_TYPE_UNKNOWN:
case CONNMAN_SERVICE_TYPE_SYSTEM:
case CONNMAN_SERVICE_TYPE_GPS:
- case CONNMAN_SERVICE_TYPE_GADGET:
+ case CONNMAN_SERVICE_TYPE_P2P:
return -EINVAL;
case CONNMAN_SERVICE_TYPE_ETHERNET:
+ case CONNMAN_SERVICE_TYPE_GADGET:
case CONNMAN_SERVICE_TYPE_BLUETOOTH:
case CONNMAN_SERVICE_TYPE_CELLULAR:
case CONNMAN_SERVICE_TYPE_VPN:
@@ -5624,28 +5889,26 @@ static int service_connect(struct connman_service *service)
case CONNMAN_SERVICE_SECURITY_PSK:
case CONNMAN_SERVICE_SECURITY_WPA:
case CONNMAN_SERVICE_SECURITY_RSN:
- if (service->passphrase == NULL) {
- if (service->network == NULL)
+ if (!service->passphrase) {
+ if (!service->network)
return -EOPNOTSUPP;
- if (service->wps == FALSE ||
- connman_network_get_bool(
- service->network,
- "WiFi.UseWPS") == FALSE)
+ if (!service->wps ||
+ !connman_network_get_bool(service->network, "WiFi.UseWPS"))
return -ENOKEY;
} else if (service->error ==
CONNMAN_SERVICE_ERROR_INVALID_KEY)
return -ENOKEY;
break;
case CONNMAN_SERVICE_SECURITY_8021X:
- if (service->eap == NULL)
+ if (!service->eap)
return -EINVAL;
/*
* never request credentials if using EAP-TLS
* (EAP-TLS networks need to be fully provisioned)
*/
- if (g_str_equal(service->eap, "tls") == TRUE)
+ if (g_str_equal(service->eap, "tls"))
break;
/*
@@ -5653,10 +5916,9 @@ static int service_connect(struct connman_service *service)
* missing. Agent provided credentials can be used as
* fallback if needed.
*/
- if ((service->identity == NULL &&
- service->agent_identity == NULL) ||
- (service->passphrase == NULL &&
- service->agent_passphrase == NULL))
+ if ((!service->identity &&
+ !service->agent_identity) ||
+ !service->passphrase)
return -ENOKEY;
break;
@@ -5664,8 +5926,8 @@ static int service_connect(struct connman_service *service)
break;
}
- if (service->network != NULL) {
- if (prepare_network(service) == FALSE)
+ if (service->network) {
+ if (!prepare_network(service))
return -EINVAL;
switch (service->security) {
@@ -5682,9 +5944,9 @@ static int service_connect(struct connman_service *service)
}
if (__connman_stats_service_register(service) == 0) {
- __connman_stats_get(service, FALSE,
+ __connman_stats_get(service, false,
&service->stats.data);
- __connman_stats_get(service, TRUE,
+ __connman_stats_get(service, true,
&service->stats_roaming.data);
}
@@ -5695,7 +5957,7 @@ static int service_connect(struct connman_service *service)
err = __connman_network_connect(service->network);
} else if (service->type == CONNMAN_SERVICE_TYPE_VPN &&
- service->provider != NULL)
+ service->provider)
err = __connman_provider_connect(service->provider);
else
return -EOPNOTSUPP;
@@ -5711,32 +5973,36 @@ static int service_connect(struct connman_service *service)
return err;
}
-
-int __connman_service_connect(struct connman_service *service)
+int __connman_service_connect(struct connman_service *service,
+ enum connman_service_connect_reason reason)
{
int err;
- DBG("service %p state %s", service, state2string(service->state));
+ DBG("service %p state %s connect reason %s -> %s",
+ service, state2string(service->state),
+ reason2string(service->connect_reason),
+ reason2string(reason));
- if (is_connected(service) == TRUE)
+ if (is_connected(service))
return -EISCONN;
- if (is_connecting(service) == TRUE)
+ if (is_connecting(service))
return -EALREADY;
switch (service->type) {
case CONNMAN_SERVICE_TYPE_UNKNOWN:
case CONNMAN_SERVICE_TYPE_SYSTEM:
case CONNMAN_SERVICE_TYPE_GPS:
- case CONNMAN_SERVICE_TYPE_GADGET:
+ case CONNMAN_SERVICE_TYPE_P2P:
return -EINVAL;
default:
- if (is_ipconfig_usable(service) == FALSE)
+ if (!is_ipconfig_usable(service))
return -ENOLINK;
err = service_connect(service);
}
+ service->connect_reason = reason;
if (err >= 0) {
set_error(service, CONNMAN_SERVICE_ERROR_UNKNOWN);
return 0;
@@ -5750,13 +6016,13 @@ int __connman_service_connect(struct connman_service *service)
return -EINPROGRESS;
}
- if (service->network != NULL)
+ if (service->network)
__connman_network_disconnect(service->network);
else if (service->type == CONNMAN_SERVICE_TYPE_VPN &&
- service->provider != NULL)
+ service->provider)
connman_provider_disconnect(service->provider);
- if (service->userconnect == TRUE) {
+ if (service->connect_reason == CONNMAN_SERVICE_CONNECT_REASON_USER) {
if (err == -ENOKEY || err == -EPERM) {
DBusMessage *pending = NULL;
@@ -5766,14 +6032,16 @@ int __connman_service_connect(struct connman_service *service)
* after the real hidden network is connected or
* connection failed.
*/
- if (service->hidden == TRUE) {
+ if (service->hidden) {
pending = service->pending;
service->pending = NULL;
}
err = __connman_agent_request_passphrase_input(service,
- request_input_cb, pending);
- if (service->hidden == TRUE && err != -EINPROGRESS)
+ request_input_cb,
+ get_dbus_sender(service),
+ pending);
+ if (service->hidden && err != -EINPROGRESS)
service->pending = pending;
return err;
@@ -5790,14 +6058,17 @@ int __connman_service_disconnect(struct connman_service *service)
DBG("service %p", service);
- service->userconnect = FALSE;
+ service->connect_reason = CONNMAN_SERVICE_CONNECT_REASON_NONE;
+ service->proxy = CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN;
connman_agent_cancel(service);
- if (service->network != NULL) {
+ reply_pending(service, ECONNABORTED);
+
+ if (service->network) {
err = __connman_network_disconnect(service->network);
} else if (service->type == CONNMAN_SERVICE_TYPE_VPN &&
- service->provider != NULL)
+ service->provider)
err = connman_provider_disconnect(service->provider);
else
return -EOPNOTSUPP;
@@ -5836,21 +6107,19 @@ int __connman_service_disconnect_all(void)
DBG("");
- for (iter = service_list; iter != NULL; iter = iter->next) {
+ for (iter = service_list; iter; iter = iter->next) {
service = iter->data;
- if (is_connected(service) == FALSE)
+ if (!is_connected(service))
break;
services = g_slist_prepend(services, service);
}
- for (list = services; list != NULL; list = list->next) {
+ for (list = services; list; list = list->next) {
struct connman_service *service = list->data;
- service->ignore = TRUE;
-
- set_reconnect_state(service, FALSE);
+ service->ignore = true;
__connman_service_disconnect(service);
}
@@ -5902,14 +6171,10 @@ int __connman_service_provision_changed(const char *ident)
* Because the provision_changed() might have set some services
* as favorite, we must sort the sequence now.
*/
- if (services_dirty == TRUE) {
- services_dirty = FALSE;
+ if (services_dirty) {
+ services_dirty = false;
- if (service_list->next != NULL) {
- service_list = g_list_sort(service_list,
- service_compare);
- service_schedule_changed();
- }
+ service_list_sort();
__connman_connection_update_gateway();
}
@@ -5920,7 +6185,7 @@ int __connman_service_provision_changed(const char *ident)
void __connman_service_set_config(struct connman_service *service,
const char *file_id, const char *entry)
{
- if (service == NULL)
+ if (!service)
return;
g_free(service->config_file);
@@ -5941,13 +6206,13 @@ static struct connman_service *service_get(const char *identifier)
struct connman_service *service;
service = g_hash_table_lookup(service_hash, identifier);
- if (service != NULL) {
+ if (service) {
connman_service_ref(service);
return service;
}
service = connman_service_create();
- if (service == NULL)
+ if (!service)
return NULL;
DBG("service %p", service);
@@ -5966,7 +6231,7 @@ static int service_register(struct connman_service *service)
{
DBG("service %p", service);
- if (service->path != NULL)
+ if (service->path)
return -EALREADY;
service->path = g_strdup_printf("%s/service/%s", CONNMAN_PATH,
@@ -5974,74 +6239,75 @@ static int service_register(struct connman_service *service)
DBG("path %s", service->path);
- __connman_config_provision_service(service);
-
- service_load(service);
+ if (__connman_config_provision_service(service) < 0)
+ service_load(service);
g_dbus_register_interface(connection, service->path,
CONNMAN_SERVICE_INTERFACE,
service_methods, service_signals,
NULL, service, NULL);
- if (service_list->next != NULL) {
- service_list = g_list_sort(service_list, service_compare);
- service_schedule_changed();
- }
+ service_list_sort();
__connman_connection_update_gateway();
return 0;
}
-static void service_up(struct connman_ipconfig *ipconfig)
+static void service_up(struct connman_ipconfig *ipconfig,
+ const char *ifname)
{
struct connman_service *service = __connman_ipconfig_get_data(ipconfig);
- DBG("%s up", __connman_ipconfig_get_ifname(ipconfig));
+ DBG("%s up", ifname);
link_changed(service);
- service->stats.valid = FALSE;
- service->stats_roaming.valid = FALSE;
+ service->stats.valid = false;
+ service->stats_roaming.valid = false;
}
-static void service_down(struct connman_ipconfig *ipconfig)
+static void service_down(struct connman_ipconfig *ipconfig,
+ const char *ifname)
{
- DBG("%s down", __connman_ipconfig_get_ifname(ipconfig));
+ DBG("%s down", ifname);
}
-static void service_lower_up(struct connman_ipconfig *ipconfig)
+static void service_lower_up(struct connman_ipconfig *ipconfig,
+ const char *ifname)
{
struct connman_service *service = __connman_ipconfig_get_data(ipconfig);
- DBG("%s lower up", __connman_ipconfig_get_ifname(ipconfig));
+ DBG("%s lower up", ifname);
stats_start(service);
}
-static void service_lower_down(struct connman_ipconfig *ipconfig)
+static void service_lower_down(struct connman_ipconfig *ipconfig,
+ const char *ifname)
{
struct connman_service *service = __connman_ipconfig_get_data(ipconfig);
- DBG("%s lower down", __connman_ipconfig_get_ifname(ipconfig));
+ DBG("%s lower down", ifname);
- if (is_idle_state(service, service->state_ipv4) == FALSE)
+ if (!is_idle_state(service, service->state_ipv4))
__connman_ipconfig_disable(service->ipconfig_ipv4);
- if (is_idle_state(service, service->state_ipv6) == FALSE)
+ if (!is_idle_state(service, service->state_ipv6))
__connman_ipconfig_disable(service->ipconfig_ipv6);
stats_stop(service);
service_save(service);
}
-static void service_ip_bound(struct connman_ipconfig *ipconfig)
+static void service_ip_bound(struct connman_ipconfig *ipconfig,
+ const char *ifname)
{
struct connman_service *service = __connman_ipconfig_get_data(ipconfig);
enum connman_ipconfig_method method = CONNMAN_IPCONFIG_METHOD_UNKNOWN;
enum connman_ipconfig_type type = CONNMAN_IPCONFIG_TYPE_UNKNOWN;
- DBG("%s ip bound", __connman_ipconfig_get_ifname(ipconfig));
+ DBG("%s ip bound", ifname);
type = __connman_ipconfig_get_config_type(ipconfig);
method = __connman_ipconfig_get_method(ipconfig);
@@ -6058,13 +6324,14 @@ static void service_ip_bound(struct connman_ipconfig *ipconfig)
settings_changed(service, ipconfig);
}
-static void service_ip_release(struct connman_ipconfig *ipconfig)
+static void service_ip_release(struct connman_ipconfig *ipconfig,
+ const char *ifname)
{
struct connman_service *service = __connman_ipconfig_get_data(ipconfig);
enum connman_ipconfig_method method = CONNMAN_IPCONFIG_METHOD_UNKNOWN;
enum connman_ipconfig_type type = CONNMAN_IPCONFIG_TYPE_UNKNOWN;
- DBG("%s ip release", __connman_ipconfig_get_ifname(ipconfig));
+ DBG("%s ip release", ifname);
type = __connman_ipconfig_get_config_type(ipconfig);
method = __connman_ipconfig_get_method(ipconfig);
@@ -6087,11 +6354,12 @@ static void service_ip_release(struct connman_ipconfig *ipconfig)
settings_changed(service, ipconfig);
}
-static void service_route_changed(struct connman_ipconfig *ipconfig)
+static void service_route_changed(struct connman_ipconfig *ipconfig,
+ const char *ifname)
{
struct connman_service *service = __connman_ipconfig_get_data(ipconfig);
- DBG("%s route changed", __connman_ipconfig_get_ifname(ipconfig));
+ DBG("%s route changed", ifname);
settings_changed(service, ipconfig);
}
@@ -6114,7 +6382,7 @@ static struct connman_ipconfig *create_ip4config(struct connman_service *service
ipconfig_ipv4 = __connman_ipconfig_create(index,
CONNMAN_IPCONFIG_TYPE_IPV4);
- if (ipconfig_ipv4 == NULL)
+ if (!ipconfig_ipv4)
return NULL;
__connman_ipconfig_set_method(ipconfig_ipv4, method);
@@ -6133,7 +6401,7 @@ static struct connman_ipconfig *create_ip6config(struct connman_service *service
ipconfig_ipv6 = __connman_ipconfig_create(index,
CONNMAN_IPCONFIG_TYPE_IPV6);
- if (ipconfig_ipv6 == NULL)
+ if (!ipconfig_ipv6)
return NULL;
__connman_ipconfig_set_data(ipconfig_ipv6, service);
@@ -6147,11 +6415,11 @@ void __connman_service_read_ip4config(struct connman_service *service)
{
GKeyFile *keyfile;
- if (service->ipconfig_ipv4 == NULL)
+ if (!service->ipconfig_ipv4)
return;
keyfile = connman_storage_load_service(service->identifier);
- if (keyfile == NULL)
+ if (!keyfile)
return;
__connman_ipconfig_load(service->ipconfig_ipv4, keyfile,
@@ -6165,7 +6433,7 @@ void connman_service_create_ip4config(struct connman_service *service,
{
DBG("ipv4 %p", service->ipconfig_ipv4);
- if (service->ipconfig_ipv4 != NULL)
+ if (service->ipconfig_ipv4)
return;
service->ipconfig_ipv4 = create_ip4config(service, index,
@@ -6177,11 +6445,11 @@ void __connman_service_read_ip6config(struct connman_service *service)
{
GKeyFile *keyfile;
- if (service->ipconfig_ipv6 == NULL)
+ if (!service->ipconfig_ipv6)
return;
keyfile = connman_storage_load_service(service->identifier);
- if (keyfile == NULL)
+ if (!keyfile)
return;
__connman_ipconfig_load(service->ipconfig_ipv6, keyfile,
@@ -6195,7 +6463,7 @@ void connman_service_create_ip6config(struct connman_service *service,
{
DBG("ipv6 %p", service->ipconfig_ipv6);
- if (service->ipconfig_ipv6 != NULL)
+ if (service->ipconfig_ipv6)
return;
service->ipconfig_ipv6 = create_ip6config(service, index);
@@ -6215,17 +6483,15 @@ struct connman_service *connman_service_lookup_from_network(struct connman_netwo
const char *ident, *group;
char *name;
- DBG("network %p", network);
-
- if (network == NULL)
+ if (!network)
return NULL;
ident = __connman_network_get_ident(network);
- if (ident == NULL)
+ if (!ident)
return NULL;
group = connman_network_get_group(network);
- if (group == NULL)
+ if (!group)
return NULL;
name = g_strdup_printf("%s_%s_%s",
@@ -6241,7 +6507,7 @@ struct connman_service *__connman_service_lookup_from_index(int index)
struct connman_service *service;
GList *list;
- for (list = service_list; list != NULL; list = list->next) {
+ for (list = service_list; list; list = list->next) {
service = list->data;
if (__connman_ipconfig_get_index(service->ipconfig_ipv4)
@@ -6271,34 +6537,46 @@ const char *__connman_service_get_path(struct connman_service *service)
return service->path;
}
+const char *__connman_service_get_name(struct connman_service *service)
+{
+ return service->name;
+}
+
+enum connman_service_state __connman_service_get_state(struct connman_service *service)
+{
+ return service->state;
+}
+
unsigned int __connman_service_get_order(struct connman_service *service)
{
- if (service == NULL)
+ unsigned int order = 0;
+
+ if (!service)
return 0;
- if (service->favorite == FALSE) {
- service->order = 0;
- goto done;
- }
+ service->order = 0;
+
+ if (!service->favorite)
+ return 0;
if (service == service_list->data)
- service->order = 1;
- else if (service->type == CONNMAN_SERVICE_TYPE_VPN &&
- service->do_split_routing == FALSE)
+ order = 1;
+
+ if (service->type == CONNMAN_SERVICE_TYPE_VPN &&
+ !service->do_split_routing) {
service->order = 10;
- else
- service->order = 0;
+ order = 10;
+ }
DBG("service %p name %s order %d split %d", service, service->name,
- service->order, service->do_split_routing);
+ order, service->do_split_routing);
-done:
- return service->order;
+ return order;
}
void __connman_service_update_ordering(void)
{
- if (service_list != NULL && service_list->next != NULL)
+ if (service_list && service_list->next)
service_list = g_list_sort(service_list, service_compare);
}
@@ -6319,6 +6597,8 @@ static enum connman_service_type convert_network_type(struct connman_network *ne
return CONNMAN_SERVICE_TYPE_BLUETOOTH;
case CONNMAN_NETWORK_TYPE_CELLULAR:
return CONNMAN_SERVICE_TYPE_CELLULAR;
+ case CONNMAN_NETWORK_TYPE_GADGET:
+ return CONNMAN_SERVICE_TYPE_GADGET;
}
return CONNMAN_SERVICE_TYPE_UNKNOWN;
@@ -6326,19 +6606,19 @@ static enum connman_service_type convert_network_type(struct connman_network *ne
static enum connman_service_security convert_wifi_security(const char *security)
{
- if (security == NULL)
+ if (!security)
return CONNMAN_SERVICE_SECURITY_UNKNOWN;
- else if (g_str_equal(security, "none") == TRUE)
+ else if (g_str_equal(security, "none"))
return CONNMAN_SERVICE_SECURITY_NONE;
- else if (g_str_equal(security, "wep") == TRUE)
+ else if (g_str_equal(security, "wep"))
return CONNMAN_SERVICE_SECURITY_WEP;
- else if (g_str_equal(security, "psk") == TRUE)
+ else if (g_str_equal(security, "psk"))
return CONNMAN_SERVICE_SECURITY_PSK;
- else if (g_str_equal(security, "ieee8021x") == TRUE)
+ else if (g_str_equal(security, "ieee8021x"))
return CONNMAN_SERVICE_SECURITY_8021X;
- else if (g_str_equal(security, "wpa") == TRUE)
+ else if (g_str_equal(security, "wpa"))
return CONNMAN_SERVICE_SECURITY_WPA;
- else if (g_str_equal(security, "rsn") == TRUE)
+ else if (g_str_equal(security, "rsn"))
return CONNMAN_SERVICE_SECURITY_RSN;
else
return CONNMAN_SERVICE_SECURITY_UNKNOWN;
@@ -6352,21 +6632,21 @@ static void update_from_network(struct connman_service *service,
DBG("service %p network %p", service, network);
- if (is_connected(service) == TRUE)
+ if (is_connected(service))
return;
- if (is_connecting(service) == TRUE)
+ if (is_connecting(service))
return;
str = connman_network_get_string(network, "Name");
- if (str != NULL) {
+ if (str) {
g_free(service->name);
service->name = g_strdup(str);
- service->hidden = FALSE;
+ service->hidden = false;
} else {
g_free(service->name);
service->name = NULL;
- service->hidden = TRUE;
+ service->hidden = true;
}
service->strength = connman_network_get_strength(network);
@@ -6386,20 +6666,17 @@ static void update_from_network(struct connman_service *service,
if (service->type == CONNMAN_SERVICE_TYPE_WIFI)
service->wps = connman_network_get_bool(network, "WiFi.WPS");
- if (service->strength > strength && service->network != NULL) {
+ if (service->strength > strength && service->network) {
connman_network_unref(service->network);
service->network = connman_network_ref(network);
strength_changed(service);
}
- if (service->network == NULL)
+ if (!service->network)
service->network = connman_network_ref(network);
- if (service_list->next != NULL) {
- service_list = g_list_sort(service_list, service_compare);
- service_schedule_changed();
- }
+ service_list_sort();
}
/**
@@ -6419,15 +6696,15 @@ struct connman_service * __connman_service_create_from_network(struct connman_ne
DBG("network %p", network);
- if (network == NULL)
+ if (!network)
return NULL;
ident = __connman_network_get_ident(network);
- if (ident == NULL)
+ if (!ident)
return NULL;
group = connman_network_get_group(network);
- if (group == NULL)
+ if (!group)
return NULL;
name = g_strdup_printf("%s_%s_%s",
@@ -6435,13 +6712,13 @@ struct connman_service * __connman_service_create_from_network(struct connman_ne
service = service_get(name);
g_free(name);
- if (service == NULL)
+ if (!service)
return NULL;
- if (__connman_network_get_weakness(network) == TRUE)
+ if (__connman_network_get_weakness(network))
return service;
- if (service->path != NULL) {
+ if (service->path) {
update_from_network(service, network);
__connman_connection_update_gateway();
return service;
@@ -6450,11 +6727,11 @@ struct connman_service * __connman_service_create_from_network(struct connman_ne
service->type = convert_network_type(network);
auto_connect_types = connman_setting_get_uint_list("DefaultAutoConnectTechnologies");
- service->autoconnect = FALSE;
- for (i = 0; auto_connect_types != NULL &&
+ service->autoconnect = false;
+ for (i = 0; auto_connect_types &&
auto_connect_types[i] != 0; i++) {
if (service->type == auto_connect_types[i]) {
- service->autoconnect = TRUE;
+ service->autoconnect = true;
break;
}
}
@@ -6468,9 +6745,10 @@ struct connman_service * __connman_service_create_from_network(struct connman_ne
case CONNMAN_SERVICE_TYPE_GADGET:
case CONNMAN_SERVICE_TYPE_WIFI:
case CONNMAN_SERVICE_TYPE_CELLULAR:
+ case CONNMAN_SERVICE_TYPE_P2P:
break;
case CONNMAN_SERVICE_TYPE_ETHERNET:
- service->favorite = TRUE;
+ service->favorite = true;
break;
}
@@ -6481,19 +6759,19 @@ struct connman_service * __connman_service_create_from_network(struct connman_ne
index = connman_network_get_index(network);
- if (service->ipconfig_ipv4 == NULL)
+ if (!service->ipconfig_ipv4)
service->ipconfig_ipv4 = create_ip4config(service, index,
CONNMAN_IPCONFIG_METHOD_DHCP);
- if (service->ipconfig_ipv6 == NULL)
+ if (!service->ipconfig_ipv6)
service->ipconfig_ipv6 = create_ip6config(service, index);
service_register(service);
- if (service->favorite == TRUE) {
+ if (service->favorite) {
device = connman_network_get_device(service->network);
- if (device && connman_device_get_scanning(device) == FALSE)
- __connman_service_auto_connect();
+ if (device && !connman_device_get_scanning(device))
+ __connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO);
}
__connman_notifier_service_add(service, service->name);
@@ -6504,20 +6782,18 @@ struct connman_service * __connman_service_create_from_network(struct connman_ne
void __connman_service_update_from_network(struct connman_network *network)
{
- connman_bool_t need_sort = FALSE;
+ bool need_sort = false;
struct connman_service *service;
uint8_t strength;
- connman_bool_t roaming;
+ bool roaming;
const char *name;
- connman_bool_t stats_enable;
-
- DBG("network %p", network);
+ bool stats_enable;
service = connman_service_lookup_from_network(network);
- if (service == NULL)
+ if (!service)
return;
- if (service->network == NULL)
+ if (!service->network)
return;
name = connman_network_get_string(service->network, "Name");
@@ -6525,7 +6801,7 @@ void __connman_service_update_from_network(struct connman_network *network)
g_free(service->name);
service->name = g_strdup(name);
- if (allow_property_changed(service) == TRUE)
+ if (allow_property_changed(service))
connman_dbus_property_changed_basic(service->path,
CONNMAN_SERVICE_INTERFACE, "Name",
DBUS_TYPE_STRING, &service->name);
@@ -6539,7 +6815,7 @@ void __connman_service_update_from_network(struct connman_network *network)
goto roaming;
service->strength = strength;
- need_sort = TRUE;
+ need_sort = true;
strength_changed(service);
@@ -6549,24 +6825,20 @@ roaming:
goto sorting;
stats_enable = stats_enabled(service);
- if (stats_enable == TRUE)
+ if (stats_enable)
stats_stop(service);
service->roaming = roaming;
- need_sort = TRUE;
+ need_sort = true;
- if (stats_enable == TRUE)
+ if (stats_enable)
stats_start(service);
roaming_changed(service);
sorting:
- if (need_sort == TRUE) {
- if (service_list->next != NULL) {
- service_list = g_list_sort(service_list,
- service_compare);
- service_schedule_changed();
- }
+ if (need_sort) {
+ service_list_sort();
}
}
@@ -6574,13 +6846,14 @@ void __connman_service_remove_from_network(struct connman_network *network)
{
struct connman_service *service;
- DBG("network %p", network);
-
service = connman_service_lookup_from_network(network);
- if (service == NULL)
+
+ DBG("network %p service %p", network, service);
+
+ if (!service)
return;
- service->ignore = TRUE;
+ service->ignore = true;
__connman_connection_gateway_remove(service,
CONNMAN_IPCONFIG_TYPE_ALL);
@@ -6605,42 +6878,42 @@ __connman_service_create_from_provider(struct connman_provider *provider)
DBG("provider %p", provider);
ident = __connman_provider_get_ident(provider);
- if (ident == NULL)
+ if (!ident)
return NULL;
name = g_strdup_printf("vpn_%s", ident);
service = service_get(name);
g_free(name);
- if (service == NULL)
+ if (!service)
return NULL;
service->type = CONNMAN_SERVICE_TYPE_VPN;
service->provider = connman_provider_ref(provider);
- service->autoconnect = FALSE;
- service->userconnect = TRUE;
+ service->autoconnect = false;
+ service->favorite = true;
service->state_ipv4 = service->state_ipv6 = CONNMAN_SERVICE_STATE_IDLE;
service->state = combine_state(service->state_ipv4, service->state_ipv6);
str = connman_provider_get_string(provider, "Name");
- if (str != NULL) {
+ if (str) {
g_free(service->name);
service->name = g_strdup(str);
- service->hidden = FALSE;
+ service->hidden = false;
} else {
g_free(service->name);
service->name = NULL;
- service->hidden = TRUE;
+ service->hidden = true;
}
service->strength = 0;
- if (service->ipconfig_ipv4 == NULL)
+ if (!service->ipconfig_ipv4)
service->ipconfig_ipv4 = create_ip4config(service, index,
CONNMAN_IPCONFIG_METHOD_MANUAL);
- if (service->ipconfig_ipv6 == NULL)
+ if (!service->ipconfig_ipv6)
service->ipconfig_ipv6 = create_ip6config(service, index);
service_register(service);
@@ -6651,7 +6924,7 @@ __connman_service_create_from_provider(struct connman_provider *provider)
return service;
}
-static void remove_unprovisioned_services()
+static void remove_unprovisioned_services(void)
{
gchar **services;
GKeyFile *keyfile, *configkeyfile;
@@ -6659,29 +6932,29 @@ static void remove_unprovisioned_services()
int i = 0;
services = connman_storage_get_services();
- if (services == NULL)
+ if (!services)
return;
- for (;services[i] != NULL; i++) {
+ for (; services[i]; i++) {
file = section = NULL;
keyfile = configkeyfile = NULL;
keyfile = connman_storage_load_service(services[i]);
- if (keyfile == NULL)
+ if (!keyfile)
continue;
file = g_key_file_get_string(keyfile, services[i],
"Config.file", NULL);
- if (file == NULL)
+ if (!file)
goto next;
section = g_key_file_get_string(keyfile, services[i],
"Config.ident", NULL);
- if (section == NULL)
+ if (!section)
goto next;
configkeyfile = __connman_storage_load_config(file);
- if (configkeyfile == NULL) {
+ if (!configkeyfile) {
/*
* Config file is missing, remove the provisioned
* service.
@@ -6690,7 +6963,7 @@ static void remove_unprovisioned_services()
goto next;
}
- if (g_key_file_has_group(configkeyfile, section) == FALSE)
+ if (!g_key_file_has_group(configkeyfile, section))
/*
* Config section is missing, remove the provisioned
* service.
@@ -6698,10 +6971,10 @@ static void remove_unprovisioned_services()
__connman_storage_remove_service(services[i]);
next:
- if (keyfile != NULL)
+ if (keyfile)
g_key_file_free(keyfile);
- if (configkeyfile != NULL)
+ if (configkeyfile)
g_key_file_free(configkeyfile);
g_free(section);
@@ -6777,11 +7050,18 @@ void __connman_service_cleanup(void)
{
DBG("");
+ if (vpn_autoconnect_timeout) {
+ g_source_remove(vpn_autoconnect_timeout);
+ vpn_autoconnect_timeout = 0;
+ }
+
if (autoconnect_timeout != 0) {
g_source_remove(autoconnect_timeout);
autoconnect_timeout = 0;
}
+ connman_agent_driver_unregister(&agent_driver);
+
g_list_free(service_list);
service_list = NULL;
@@ -6799,7 +7079,5 @@ void __connman_service_cleanup(void)
}
g_free(services_notify);
- connman_agent_driver_unregister(&agent_driver);
-
dbus_connection_unref(connection);
}
diff --git a/src/session.c b/src/session.c
index 6d3827b7..00ef3696 100644
--- a/src/session.c
+++ b/src/session.c
@@ -2,8 +2,8 @@
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
- * Copyright (C) 2011 BWM CarIT GmbH. All rights reserved.
+ * Copyright (C) 2007-2014 Intel Corporation. All rights reserved.
+ * Copyright (C) 2011-2014 BWM CarIT GmbH. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -34,24 +34,10 @@
static DBusConnection *connection;
static GHashTable *session_hash;
-static connman_bool_t sessionmode;
+static GHashTable *service_hash;
static struct connman_session *ecall_session;
-static GSList *policy_list;
-
-enum connman_session_trigger {
- CONNMAN_SESSION_TRIGGER_UNKNOWN = 0,
- CONNMAN_SESSION_TRIGGER_SETTING = 1,
- CONNMAN_SESSION_TRIGGER_CONNECT = 2,
- CONNMAN_SESSION_TRIGGER_DISCONNECT = 3,
- CONNMAN_SESSION_TRIGGER_SERVICE = 4,
- CONNMAN_SESSION_TRIGGER_ECALL = 5,
-};
-
-enum connman_session_reason {
- CONNMAN_SESSION_REASON_UNKNOWN = 0,
- CONNMAN_SESSION_REASON_CONNECT = 1,
- CONNMAN_SESSION_REASON_FREE_RIDE = 2,
-};
+static uint32_t session_mark = 256;
+static struct firewall_context *global_firewall = NULL;
enum connman_session_state {
CONNMAN_SESSION_STATE_DISCONNECTED = 0,
@@ -59,23 +45,9 @@ enum connman_session_state {
CONNMAN_SESSION_STATE_ONLINE = 2,
};
-struct service_entry {
- struct connman_session *session;
- /* track why this service was selected */
- enum connman_session_reason reason;
- enum connman_service_state state;
- const char *name;
- struct connman_service *service;
- char *ifname;
- const char *bearer;
- GSList *pending_timeouts;
-};
-
struct session_info {
struct connman_session_config config;
enum connman_session_state state;
- struct service_entry *entry;
- enum connman_session_reason reason;
};
struct connman_session {
@@ -84,52 +56,41 @@ struct connman_session {
char *notify_path;
guint notify_watch;
- struct connman_session_policy *policy;
-
- connman_bool_t append_all;
+ bool active;
+ bool append_all;
struct session_info *info;
struct session_info *info_last;
+ struct connman_service *service;
+ struct connman_service *service_last;
struct connman_session_config *policy_config;
GSList *user_allowed_bearers;
- connman_bool_t ecall;
+ bool ecall;
- GList *service_list;
- GHashTable *service_hash;
+ enum connman_session_id_type id_type;
+ struct firewall_context *fw;
+ uint32_t mark;
+ int index;
+ char *gateway;
+ bool policy_routing;
};
-static const char *trigger2string(enum connman_session_trigger trigger)
-{
- switch (trigger) {
- case CONNMAN_SESSION_TRIGGER_UNKNOWN:
- break;
- case CONNMAN_SESSION_TRIGGER_SETTING:
- return "setting";
- case CONNMAN_SESSION_TRIGGER_CONNECT:
- return "connect";
- case CONNMAN_SESSION_TRIGGER_DISCONNECT:
- return "disconnect";
- case CONNMAN_SESSION_TRIGGER_SERVICE:
- return "service";
- case CONNMAN_SESSION_TRIGGER_ECALL:
- return "ecall";
- }
+struct connman_service_info {
+ struct connman_service *service;
+ GSList *sessions;
+};
- return NULL;
-}
+static struct connman_session_policy *policy;
+static void session_activate(struct connman_session *session);
+static void session_deactivate(struct connman_session *session);
+static void update_session_state(struct connman_session *session);
-static const char *reason2string(enum connman_session_reason reason)
+static void cleanup_service(gpointer data)
{
- switch (reason) {
- case CONNMAN_SESSION_REASON_UNKNOWN:
- return "unknown";
- case CONNMAN_SESSION_REASON_CONNECT:
- return "connect";
- case CONNMAN_SESSION_REASON_FREE_RIDE:
- return "free-ride";
- }
+ struct connman_service_info *info = data;
- return NULL;
+ g_slist_free(info->sessions);
+ g_free(info);
}
static const char *state2string(enum connman_session_state state)
@@ -196,14 +157,14 @@ static int bearer2service(const char *bearer, enum connman_service_type *type)
*type = CONNMAN_SERVICE_TYPE_ETHERNET;
else if (g_strcmp0(bearer, "wifi") == 0)
*type = CONNMAN_SERVICE_TYPE_WIFI;
+ else if (g_strcmp0(bearer, "gadget") == 0)
+ *type = CONNMAN_SERVICE_TYPE_GADGET;
else if (g_strcmp0(bearer, "bluetooth") == 0)
*type = CONNMAN_SERVICE_TYPE_BLUETOOTH;
else if (g_strcmp0(bearer, "cellular") == 0)
*type = CONNMAN_SERVICE_TYPE_CELLULAR;
else if (g_strcmp0(bearer, "vpn") == 0)
*type = CONNMAN_SERVICE_TYPE_VPN;
- else if (g_strcmp0(bearer, "*") == 0)
- *type = CONNMAN_SERVICE_TYPE_UNKNOWN;
else
return -EINVAL;
@@ -215,6 +176,8 @@ static char *service2bearer(enum connman_service_type type)
switch (type) {
case CONNMAN_SERVICE_TYPE_ETHERNET:
return "ethernet";
+ case CONNMAN_SERVICE_TYPE_GADGET:
+ return "gadget";
case CONNMAN_SERVICE_TYPE_WIFI:
return "wifi";
case CONNMAN_SERVICE_TYPE_BLUETOOTH:
@@ -223,30 +186,220 @@ static char *service2bearer(enum connman_service_type type)
return "cellular";
case CONNMAN_SERVICE_TYPE_VPN:
return "vpn";
- case CONNMAN_SERVICE_TYPE_UNKNOWN:
- return "*";
case CONNMAN_SERVICE_TYPE_SYSTEM:
case CONNMAN_SERVICE_TYPE_GPS:
- case CONNMAN_SERVICE_TYPE_GADGET:
+ case CONNMAN_SERVICE_TYPE_P2P:
+ case CONNMAN_SERVICE_TYPE_UNKNOWN:
return "";
}
return "";
}
+static int init_firewall(void)
+{
+ struct firewall_context *fw;
+ int err;
+
+ if (global_firewall)
+ return 0;
+
+ fw = __connman_firewall_create();
+
+ err = __connman_firewall_add_rule(fw, "mangle", "INPUT",
+ "-j CONNMARK --restore-mark");
+ if (err < 0)
+ goto err;
+
+ err = __connman_firewall_add_rule(fw, "mangle", "POSTROUTING",
+ "-j CONNMARK --save-mark");
+ if (err < 0)
+ goto err;
+
+ err = __connman_firewall_enable(fw);
+ if (err < 0)
+ goto err;
+
+ global_firewall = fw;
+
+ return 0;
+
+err:
+ __connman_firewall_destroy(fw);
+
+ return err;
+}
+
+static void cleanup_firewall(void)
+{
+ if (!global_firewall)
+ return;
+
+ __connman_firewall_disable(global_firewall);
+ __connman_firewall_destroy(global_firewall);
+}
+
+static int init_firewall_session(struct connman_session *session)
+{
+ struct firewall_context *fw;
+ int err;
+
+ if (session->policy_config->id_type == CONNMAN_SESSION_ID_TYPE_UNKNOWN)
+ return 0;
+
+ DBG("");
+
+ err = init_firewall();
+ if (err < 0)
+ return err;
+
+ fw = __connman_firewall_create();
+ if (!fw)
+ return -ENOMEM;
+
+ switch (session->policy_config->id_type) {
+ case CONNMAN_SESSION_ID_TYPE_UID:
+ err = __connman_firewall_add_rule(fw, "mangle", "OUTPUT",
+ "-m owner --uid-owner %s -j MARK --set-mark %d",
+ session->policy_config->id,
+ session->mark);
+ break;
+ case CONNMAN_SESSION_ID_TYPE_GID:
+ err = __connman_firewall_add_rule(fw, "mangle", "OUTPUT",
+ "-m owner --gid-owner %s -j MARK --set-mark %d",
+ session->policy_config->id,
+ session->mark);
+ break;
+ case CONNMAN_SESSION_ID_TYPE_LSM:
+ default:
+ err = -EINVAL;
+ }
+
+ if (err < 0)
+ goto err;
+
+ session->id_type = session->policy_config->id_type;
+
+ err = __connman_firewall_enable(fw);
+ if (err)
+ goto err;
+
+ session->fw = fw;
+
+ return 0;
+
+err:
+ __connman_firewall_destroy(fw);
+
+ return err;
+}
+
+static void cleanup_firewall_session(struct connman_session *session)
+{
+ if (!session->fw)
+ return;
+
+ __connman_firewall_disable(session->fw);
+ __connman_firewall_destroy(session->fw);
+
+ session->fw = NULL;
+}
+
+static int init_routing_table(struct connman_session *session)
+{
+ int err;
+
+ if (session->policy_config->id_type == CONNMAN_SESSION_ID_TYPE_UNKNOWN)
+ return 0;
+
+ DBG("");
+
+ err = __connman_inet_add_fwmark_rule(session->mark,
+ AF_INET, session->mark);
+ if (err < 0)
+ return err;
+
+ err = __connman_inet_add_fwmark_rule(session->mark,
+ AF_INET6, session->mark);
+ if (err < 0)
+ __connman_inet_del_fwmark_rule(session->mark,
+ AF_INET, session->mark);
+ session->policy_routing = true;
+
+ return err;
+}
+
+static void del_default_route(struct connman_session *session)
+{
+ if (!session->gateway)
+ return;
+
+ DBG("index %d routing table %d default gateway %s",
+ session->index, session->mark, session->gateway);
+
+ __connman_inet_del_default_from_table(session->mark,
+ session->index, session->gateway);
+ g_free(session->gateway);
+ session->gateway = NULL;
+ session->index = -1;
+}
+
+static void add_default_route(struct connman_session *session)
+{
+ struct connman_ipconfig *ipconfig;
+ int err;
+
+ if (!session->service)
+ return;
+
+ ipconfig = __connman_service_get_ip4config(session->service);
+ session->index = __connman_ipconfig_get_index(ipconfig);
+ session->gateway = g_strdup(__connman_ipconfig_get_gateway(ipconfig));
+
+ DBG("index %d routing table %d default gateway %s",
+ session->index, session->mark, session->gateway);
+
+ err = __connman_inet_add_default_to_table(session->mark,
+ session->index, session->gateway);
+ if (err < 0)
+ DBG("session %p %s", session, strerror(-err));
+}
+
+static void cleanup_routing_table(struct connman_session *session)
+{
+ DBG("");
+
+ if (session->policy_routing) {
+ __connman_inet_del_fwmark_rule(session->mark,
+ AF_INET6, session->mark);
+
+ __connman_inet_del_fwmark_rule(session->mark,
+ AF_INET, session->mark);
+ session->policy_routing = false;
+ }
+
+ del_default_route(session);
+}
+
+static void update_routing_table(struct connman_session *session)
+{
+ del_default_route(session);
+ add_default_route(session);
+}
+
static void destroy_policy_config(struct connman_session *session)
{
- if (session->policy == NULL) {
+ if (!policy) {
g_free(session->policy_config);
return;
}
- (*session->policy->destroy)(session);
+ policy->destroy(session);
}
static void free_session(struct connman_session *session)
{
- if (session == NULL)
+ if (!session)
return;
if (session->notify_watch > 0)
@@ -259,158 +412,123 @@ static void free_session(struct connman_session *session)
g_free(session->notify_path);
g_free(session->info);
g_free(session->info_last);
+ g_free(session->gateway);
g_free(session);
}
+static void set_active_session(struct connman_session *session, bool enable)
+{
+
+ if (policy && policy->session_changed)
+ policy->session_changed(session, enable,
+ session->info->config.allowed_bearers);
+
+ __connman_service_set_active_session(enable,
+ session->info->config.allowed_bearers);
+}
+
static void cleanup_session(gpointer user_data)
{
struct connman_session *session = user_data;
- struct session_info *info = session->info;
DBG("remove %s", session->session_path);
- g_slist_free(session->user_allowed_bearers);
- if (session->service_hash != NULL)
- g_hash_table_destroy(session->service_hash);
- g_list_free(session->service_list);
-
- if (info->entry != NULL &&
- info->entry->reason == CONNMAN_SESSION_REASON_CONNECT) {
- __connman_service_disconnect(info->entry->service);
- }
-
- free_session(session);
-}
+ cleanup_routing_table(session);
+ cleanup_firewall_session(session);
-static int assign_policy_plugin(struct connman_session *session)
-{
- if (session->policy != NULL)
- return -EALREADY;
+ if (session->active)
+ set_active_session(session, false);
- if (policy_list == NULL)
- return 0;
+ session_deactivate(session);
+ update_session_state(session);
- session->policy = policy_list->data;
+ g_slist_free(session->user_allowed_bearers);
- return 0;
+ free_session(session);
}
-struct user_config {
+struct creation_data {
DBusMessage *pending;
+ struct connman_session *session;
+ /* user config */
enum connman_session_type type;
GSList *allowed_bearers;
};
-static void cleanup_user_config(struct user_config *user_config)
+static void cleanup_creation_data(struct creation_data *creation_data)
{
- if (user_config == NULL)
+ if (!creation_data)
return;
- if (user_config->pending != NULL)
- dbus_message_unref(user_config->pending);
+ if (creation_data->pending)
+ dbus_message_unref(creation_data->pending);
- g_slist_free(user_config->allowed_bearers);
- g_free(user_config);
+ g_slist_free(creation_data->allowed_bearers);
+ g_free(creation_data);
}
static int create_policy_config(struct connman_session *session,
connman_session_config_func_t cb,
- struct user_config *user_config)
+ struct creation_data *creation_data)
{
struct connman_session_config *config;
- if (session->policy == NULL) {
+ if (!policy) {
config = connman_session_create_default_config();
- if (config == NULL) {
+ if (!config) {
free_session(session);
- cleanup_user_config(user_config);
+ cleanup_creation_data(creation_data);
return -ENOMEM;
}
- return cb(session, config, user_config, 0);
+ return cb(session, config, creation_data, 0);
}
- return (*session->policy->create)(session, cb, user_config);
+ return policy->create(session, cb, creation_data);
}
-static void probe_policy(struct connman_session_policy *policy)
+int connman_session_policy_register(struct connman_session_policy *plugin)
{
+ if (policy)
+ return -EINVAL;
- GHashTableIter iter;
- gpointer key, value;
- struct connman_session *session;
-
- DBG("policy %p name %s", policy, policy->name);
+ if (!plugin->create || !plugin->destroy)
+ return -EINVAL;
- g_hash_table_iter_init(&iter, session_hash);
+ DBG("name %s", plugin->name);
- while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
- session = value;
+ policy = plugin;
- if (session->policy != NULL)
- continue;
-
- assign_policy_plugin(session);
- }
+ return 0;
}
-static void remove_policy(struct connman_session_policy *policy)
+void connman_session_policy_unregister(struct connman_session_policy *plugin)
{
- GHashTableIter iter;
- gpointer key, value;
- struct connman_session *session;
-
- if (session_hash == NULL)
+ if (plugin != policy)
return;
- DBG("policy %p name %s", policy, policy->name);
-
- g_hash_table_iter_init(&iter, session_hash);
-
- while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
- session = value;
-
- if (session->policy != policy)
- continue;
-
- session->policy = NULL;
- assign_policy_plugin(session);
- }
-}
-
-static gint compare_priority(gconstpointer a, gconstpointer b)
-{
- const struct connman_session_policy *policy1 = a;
- const struct connman_session_policy *policy2 = b;
-
- return policy2->priority - policy1->priority;
-}
-
-
-int connman_session_policy_register(struct connman_session_policy *policy)
-{
DBG("name %s", policy->name);
- if (policy->create == NULL || policy->destroy == NULL)
- return -EINVAL;
-
- policy_list = g_slist_insert_sorted(policy_list, policy,
- compare_priority);
-
- probe_policy(policy);
-
- return 0;
+ policy = NULL;
}
-void connman_session_policy_unregister(struct connman_session_policy *policy)
-{
- DBG("name %s", policy->name);
+static int default_bearers[] = {
+ CONNMAN_SERVICE_TYPE_ETHERNET,
+ CONNMAN_SERVICE_TYPE_WIFI,
+ CONNMAN_SERVICE_TYPE_BLUETOOTH,
+ CONNMAN_SERVICE_TYPE_CELLULAR,
+ CONNMAN_SERVICE_TYPE_GADGET,
+};
- policy_list = g_slist_remove(policy_list, policy);
+static void add_default_bearer_types(GSList **list)
+{
+ unsigned int i;
- remove_policy(policy);
+ for (i = 0; i < G_N_ELEMENTS(default_bearers); i++)
+ *list = g_slist_append(*list,
+ GINT_TO_POINTER(default_bearers[i]));
}
void connman_session_set_default_config(struct connman_session_config *config)
@@ -425,8 +543,7 @@ void connman_session_set_default_config(struct connman_session_config *config)
config->ecall = FALSE;
g_slist_free(config->allowed_bearers);
- config->allowed_bearers = g_slist_prepend(NULL,
- GINT_TO_POINTER(CONNMAN_SERVICE_TYPE_UNKNOWN));
+ add_default_bearer_types(&config->allowed_bearers);
}
struct connman_session_config *connman_session_create_default_config(void)
@@ -463,6 +580,11 @@ int connman_session_parse_bearers(const char *token, GSList **list)
if (g_strcmp0(token, "") == 0)
return 0;
+ if (g_strcmp0(token, "*") == 0) {
+ add_default_bearer_types(list);
+ return 0;
+ }
+
err = bearer2service(token, &bearer);
if (err < 0)
return err;
@@ -506,58 +628,40 @@ static int parse_bearers(DBusMessageIter *iter, GSList **list)
return 0;
}
-static int filter_bearer(GSList *policy_bearers,
+static void filter_bearer(GSList *policy_bearers,
enum connman_service_type bearer,
GSList **list)
{
enum connman_service_type policy;
GSList *it;
- if (policy_bearers == NULL)
- return 0;
+ if (!policy_bearers)
+ return;
- for (it = policy_bearers; it != NULL; it = it->next) {
+ for (it = policy_bearers; it; it = it->next) {
policy = GPOINTER_TO_INT(it->data);
- if (bearer == CONNMAN_SERVICE_TYPE_UNKNOWN) {
- bearer = policy;
- goto clone;
- }
-
- if (policy != CONNMAN_SERVICE_TYPE_UNKNOWN && policy != bearer)
+ if (policy != bearer)
continue;
- goto clone;
+ *list = g_slist_append(*list, GINT_TO_POINTER(bearer));
+ return;
}
-
- *list = NULL;
-
- return 0;
-
-clone:
- *list = g_slist_append(*list, GINT_TO_POINTER(bearer));
-
- return 0;
}
-static int apply_policy_on_bearers(GSList *policy_bearers, GSList *bearers,
+static void apply_policy_on_bearers(GSList *policy_bearers, GSList *bearers,
GSList **list)
{
enum connman_service_type bearer;
GSList *it;
- int err;
*list = NULL;
- for (it = bearers; it != NULL; it = it->next) {
+ for (it = bearers; it; it = it->next) {
bearer = GPOINTER_TO_INT(it->data);
- err = filter_bearer(policy_bearers, bearer, list);
- if (err < 0)
- return err;
+ filter_bearer(policy_bearers, bearer, list);
}
-
- return 0;
}
const char *connman_session_get_owner(struct connman_session *session)
@@ -571,12 +675,12 @@ static void append_allowed_bearers(DBusMessageIter *iter, void *user_data)
GSList *list;
for (list = info->config.allowed_bearers;
- list != NULL; list = list->next) {
+ list; list = list->next) {
enum connman_service_type bearer = GPOINTER_TO_INT(list->data);
const char *name = __connman_service_type2string(bearer);
- if (name == NULL)
- name = "*";
+ if (!name)
+ name = "";
dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING,
&name);
@@ -588,16 +692,15 @@ static void append_ipconfig_ipv4(DBusMessageIter *iter, void *user_data)
struct connman_service *service = user_data;
struct connman_ipconfig *ipconfig_ipv4;
- if (service == NULL)
+ if (!service)
return;
- if (__connman_service_is_connected_state(service,
- CONNMAN_IPCONFIG_TYPE_IPV4) == FALSE) {
+ if (!__connman_service_is_connected_state(service,
+ CONNMAN_IPCONFIG_TYPE_IPV4))
return;
- }
ipconfig_ipv4 = __connman_service_get_ip4config(service);
- if (ipconfig_ipv4 == NULL)
+ if (!ipconfig_ipv4)
return;
__connman_ipconfig_append_ipv4(ipconfig_ipv4, iter);
@@ -608,17 +711,16 @@ static void append_ipconfig_ipv6(DBusMessageIter *iter, void *user_data)
struct connman_service *service = user_data;
struct connman_ipconfig *ipconfig_ipv4, *ipconfig_ipv6;
- if (service == NULL)
+ if (!service)
return;
- if (__connman_service_is_connected_state(service,
- CONNMAN_IPCONFIG_TYPE_IPV6) == FALSE) {
+ if (!__connman_service_is_connected_state(service,
+ CONNMAN_IPCONFIG_TYPE_IPV6))
return;
- }
ipconfig_ipv4 = __connman_service_get_ip4config(service);
ipconfig_ipv6 = __connman_service_get_ip6config(service);
- if (ipconfig_ipv6 == NULL)
+ if (!ipconfig_ipv6)
return;
__connman_ipconfig_append_ipv6(ipconfig_ipv6, iter, ipconfig_ipv4);
@@ -630,10 +732,12 @@ static void append_notify(DBusMessageIter *dict,
struct session_info *info = session->info;
struct session_info *info_last = session->info_last;
struct connman_service *service;
- const char *name, *ifname, *bearer;
+ enum connman_service_type type;
+ const char *name, *bearer;
+ char *ifname;
+ int idx;
- if (session->append_all == TRUE ||
- info->state != info_last->state) {
+ if (session->append_all || info->state != info_last->state) {
const char *state = state2string(info->state);
connman_dbus_dict_append_basic(dict, "State",
@@ -642,18 +746,23 @@ static void append_notify(DBusMessageIter *dict,
info_last->state = info->state;
}
- if (session->append_all == TRUE ||
- info->entry != info_last->entry) {
- if (info->entry == NULL) {
- name = "";
- ifname = "";
+ if (session->append_all || session->service != session->service_last) {
+ if (session->service) {
+ service = session->service;
+ name = __connman_service_get_name(service);
+ idx = __connman_service_get_index(service);
+
+ ifname = connman_inet_ifname(idx);
+ if (!ifname)
+ ifname = g_strdup("");
+
+ type = connman_service_get_type(service);
+ bearer = service2bearer(type);
+ } else {
service = NULL;
+ name = "";
+ ifname = g_strdup("");
bearer = "";
- } else {
- name = info->entry->name;
- ifname = info->entry->ifname;
- service = info->entry->service;
- bearer = info->entry->bearer;
}
connman_dbus_dict_append_basic(dict, "Name",
@@ -676,10 +785,12 @@ static void append_notify(DBusMessageIter *dict,
DBUS_TYPE_STRING,
&bearer);
- info_last->entry = info->entry;
+ g_free(ifname);
+
+ session->service_last = session->service;
}
- if (session->append_all == TRUE ||
+ if (session->append_all ||
info->config.type != info_last->config.type) {
const char *type = type2string(info->config.type);
@@ -689,7 +800,7 @@ static void append_notify(DBusMessageIter *dict,
info_last->config.type = info->config.type;
}
- if (session->append_all == TRUE ||
+ if (session->append_all ||
info->config.allowed_bearers != info_last->config.allowed_bearers) {
connman_dbus_dict_append_array(dict, "AllowedBearers",
DBUS_TYPE_STRING,
@@ -698,53 +809,29 @@ static void append_notify(DBusMessageIter *dict,
info_last->config.allowed_bearers = info->config.allowed_bearers;
}
- session->append_all = FALSE;
+ session->append_all = false;
}
-static connman_bool_t is_type_matching_state(enum connman_session_state *state,
- enum connman_session_type type)
-{
- switch (type) {
- case CONNMAN_SESSION_TYPE_UNKNOWN:
- return FALSE;
- case CONNMAN_SESSION_TYPE_ANY:
- return TRUE;
- case CONNMAN_SESSION_TYPE_LOCAL:
- if (*state >= CONNMAN_SESSION_STATE_CONNECTED) {
- *state = CONNMAN_SESSION_STATE_CONNECTED;
- return TRUE;
- }
-
- break;
- case CONNMAN_SESSION_TYPE_INTERNET:
- if (*state == CONNMAN_SESSION_STATE_ONLINE)
- return TRUE;
- break;
- }
-
- return FALSE;
-}
-
-static connman_bool_t compute_notifiable_changes(struct connman_session *session)
+static bool compute_notifiable_changes(struct connman_session *session)
{
struct session_info *info_last = session->info_last;
struct session_info *info = session->info;
- if (session->append_all == TRUE)
- return TRUE;
+ if (session->append_all)
+ return true;
if (info->state != info_last->state)
- return TRUE;
+ return true;
- if (info->entry != info_last->entry &&
+ if (session->service != session->service_last &&
info->state >= CONNMAN_SESSION_STATE_CONNECTED)
- return TRUE;
+ return true;
if (info->config.allowed_bearers != info_last->config.allowed_bearers ||
info->config.type != info_last->config.type)
- return TRUE;
+ return true;
- return FALSE;
+ return false;
}
static gboolean session_notify(gpointer user_data)
@@ -753,7 +840,7 @@ static gboolean session_notify(gpointer user_data)
DBusMessage *msg;
DBusMessageIter array, dict;
- if (compute_notifiable_changes(session) == FALSE)
+ if (!compute_notifiable_changes(session))
return FALSE;
DBG("session %p owner %s notify_path %s", session,
@@ -762,7 +849,7 @@ static gboolean session_notify(gpointer user_data)
msg = dbus_message_new_method_call(session->owner, session->notify_path,
CONNMAN_NOTIFICATION_INTERFACE,
"Update");
- if (msg == NULL)
+ if (!msg)
return FALSE;
dbus_message_iter_init_append(msg, &array);
@@ -779,651 +866,16 @@ static gboolean session_notify(gpointer user_data)
static void ipconfig_ipv4_changed(struct connman_session *session)
{
- struct session_info *info = session->info;
-
connman_dbus_setting_changed_dict(session->owner, session->notify_path,
"IPv4", append_ipconfig_ipv4,
- info->entry->service);
+ session->service);
}
static void ipconfig_ipv6_changed(struct connman_session *session)
{
- struct session_info *info = session->info;
-
connman_dbus_setting_changed_dict(session->owner, session->notify_path,
"IPv6", append_ipconfig_ipv6,
- info->entry->service);
-}
-
-static connman_bool_t service_type_match(struct connman_session *session,
- struct connman_service *service)
-{
- struct session_info *info = session->info;
- GSList *list;
-
- for (list = info->config.allowed_bearers;
- list != NULL; list = list->next) {
- enum connman_service_type bearer = GPOINTER_TO_INT(list->data);
- enum connman_service_type service_type;
-
- if (bearer == CONNMAN_SERVICE_TYPE_UNKNOWN)
- return TRUE;
-
- service_type = connman_service_get_type(service);
- if (bearer == service_type)
- return TRUE;
- }
-
- return FALSE;
-}
-
-static connman_bool_t service_match(struct connman_session *session,
- struct connman_service *service)
-{
- if (service_type_match(session, service) == FALSE)
- return FALSE;
-
- return TRUE;
-}
-
-static int service_type_weight(enum connman_service_type type)
-{
- /*
- * The session doesn't care which service
- * to use. Nevertheless we have to sort them
- * according their type. The ordering is
- *
- * 1. Ethernet
- * 2. Bluetooth
- * 3. WiFi
- * 4. Cellular
- */
-
- switch (type) {
- case CONNMAN_SERVICE_TYPE_ETHERNET:
- return 4;
- case CONNMAN_SERVICE_TYPE_BLUETOOTH:
- return 3;
- case CONNMAN_SERVICE_TYPE_WIFI:
- return 2;
- case CONNMAN_SERVICE_TYPE_CELLULAR:
- return 1;
- case CONNMAN_SERVICE_TYPE_UNKNOWN:
- case CONNMAN_SERVICE_TYPE_SYSTEM:
- case CONNMAN_SERVICE_TYPE_GPS:
- case CONNMAN_SERVICE_TYPE_VPN:
- case CONNMAN_SERVICE_TYPE_GADGET:
- break;
- }
-
- return 0;
-}
-
-static gint sort_allowed_bearers(struct connman_service *service_a,
- struct connman_service *service_b,
- struct connman_session *session)
-{
- struct session_info *info = session->info;
- GSList *list;
- enum connman_service_type type_a, type_b;
- int weight_a, weight_b;
-
- type_a = connman_service_get_type(service_a);
- type_b = connman_service_get_type(service_b);
-
- for (list = info->config.allowed_bearers;
- list != NULL; list = list->next) {
- enum connman_service_type bearer = GPOINTER_TO_INT(list->data);
-
- if (bearer == CONNMAN_SERVICE_TYPE_UNKNOWN) {
- if (type_a != type_b) {
- weight_a = service_type_weight(type_a);
- weight_b = service_type_weight(type_b);
-
- if (weight_a > weight_b)
- return -1;
-
- if (weight_a < weight_b)
- return 1;
-
- return 0;
- }
- }
-
- if (type_a == bearer && type_b == bearer)
- return 0;
-
- if (type_a == bearer && type_b != bearer)
- return -1;
-
- if (type_a != bearer && type_b == bearer)
- return 1;
- }
-
- return 0;
-}
-
-static gint sort_services(gconstpointer a, gconstpointer b, gpointer user_data)
-{
- struct service_entry *entry_a = (void *)a;
- struct service_entry *entry_b = (void *)b;
- struct connman_session *session = user_data;
-
- return sort_allowed_bearers(entry_a->service, entry_b->service,
- session);
-}
-
-static enum connman_session_state service_to_session_state(enum connman_service_state state)
-{
- switch (state) {
- case CONNMAN_SERVICE_STATE_UNKNOWN:
- case CONNMAN_SERVICE_STATE_IDLE:
- case CONNMAN_SERVICE_STATE_ASSOCIATION:
- case CONNMAN_SERVICE_STATE_CONFIGURATION:
- case CONNMAN_SERVICE_STATE_DISCONNECT:
- case CONNMAN_SERVICE_STATE_FAILURE:
- break;
- case CONNMAN_SERVICE_STATE_READY:
- return CONNMAN_SESSION_STATE_CONNECTED;
- case CONNMAN_SERVICE_STATE_ONLINE:
- return CONNMAN_SESSION_STATE_ONLINE;
- }
-
- return CONNMAN_SESSION_STATE_DISCONNECTED;
-}
-
-static connman_bool_t is_connected(enum connman_service_state state)
-{
- switch (state) {
- case CONNMAN_SERVICE_STATE_UNKNOWN:
- case CONNMAN_SERVICE_STATE_IDLE:
- case CONNMAN_SERVICE_STATE_ASSOCIATION:
- case CONNMAN_SERVICE_STATE_CONFIGURATION:
- case CONNMAN_SERVICE_STATE_DISCONNECT:
- case CONNMAN_SERVICE_STATE_FAILURE:
- break;
- case CONNMAN_SERVICE_STATE_READY:
- case CONNMAN_SERVICE_STATE_ONLINE:
- return TRUE;
- }
-
- return FALSE;
-}
-
-static connman_bool_t is_connecting(enum connman_service_state state)
-{
- switch (state) {
- case CONNMAN_SERVICE_STATE_UNKNOWN:
- case CONNMAN_SERVICE_STATE_IDLE:
- break;
- case CONNMAN_SERVICE_STATE_ASSOCIATION:
- case CONNMAN_SERVICE_STATE_CONFIGURATION:
- return TRUE;
- case CONNMAN_SERVICE_STATE_DISCONNECT:
- case CONNMAN_SERVICE_STATE_FAILURE:
- case CONNMAN_SERVICE_STATE_READY:
- case CONNMAN_SERVICE_STATE_ONLINE:
- break;
- }
-
- return FALSE;
-}
-
-static connman_bool_t explicit_connect(enum connman_session_reason reason)
-{
- switch (reason) {
- case CONNMAN_SESSION_REASON_UNKNOWN:
- case CONNMAN_SESSION_REASON_FREE_RIDE:
- break;
- case CONNMAN_SESSION_REASON_CONNECT:
- return TRUE;
- }
-
- return FALSE;
-}
-
-static connman_bool_t explicit_disconnect(struct session_info *info)
-{
- if (info->entry == NULL)
- return FALSE;
-
- DBG("reason %s service %p state %d",
- reason2string(info->entry->reason),
- info->entry->service, info->entry->state);
-
- if (info->entry->reason == CONNMAN_SESSION_REASON_UNKNOWN)
- return FALSE;
-
- if (explicit_connect(info->entry->reason) == FALSE)
- return FALSE;
-
- if (__connman_service_session_dec(info->entry->service) == FALSE)
- return FALSE;
-
- return TRUE;
-}
-
-struct pending_data {
- unsigned int timeout;
- struct service_entry *entry;
- gboolean (*cb)(gpointer);
-};
-
-static void pending_timeout_free(gpointer data, gpointer user_data)
-{
- struct pending_data *pending = data;
-
- DBG("pending %p timeout %d", pending, pending->timeout);
- g_source_remove(pending->timeout);
- g_free(pending);
-}
-
-static void pending_timeout_remove_all(struct service_entry *entry)
-{
- DBG("");
-
- g_slist_foreach(entry->pending_timeouts, pending_timeout_free, NULL);
- g_slist_free(entry->pending_timeouts);
- entry->pending_timeouts = NULL;
-}
-
-static gboolean pending_timeout_cb(gpointer data)
-{
- struct pending_data *pending = data;
- struct service_entry *entry = pending->entry;
- gboolean ret;
-
- DBG("pending %p timeout %d", pending, pending->timeout);
-
- ret = pending->cb(pending->entry);
- if (ret == FALSE) {
- entry->pending_timeouts =
- g_slist_remove(entry->pending_timeouts,
- pending);
- g_free(pending);
- }
- return ret;
-}
-
-static connman_bool_t pending_timeout_add(unsigned int seconds,
- gboolean (*cb)(gpointer),
- struct service_entry *entry)
-{
- struct pending_data *pending = g_try_new0(struct pending_data, 1);
-
- if (pending == NULL || cb == NULL || entry == NULL) {
- g_free(pending);
- return FALSE;
- }
-
- pending->cb = cb;
- pending->entry = entry;
- pending->timeout = g_timeout_add_seconds(seconds, pending_timeout_cb,
- pending);
- entry->pending_timeouts = g_slist_prepend(entry->pending_timeouts,
- pending);
-
- DBG("pending %p entry %p timeout id %d", pending, entry,
- pending->timeout);
-
- return TRUE;
-}
-
-static gboolean call_disconnect(gpointer user_data)
-{
- struct service_entry *entry = user_data;
- struct connman_service *service = entry->service;
-
- /*
- * TODO: We should mark this entry as pending work. In case
- * disconnect fails we just unassign this session from the
- * service and can't do anything later on it
- */
- DBG("disconnect service %p", service);
- __connman_service_disconnect(service);
-
- return FALSE;
-}
-
-static gboolean call_connect(gpointer user_data)
-{
- struct service_entry *entry = user_data;
- struct connman_service *service = entry->service;
-
- DBG("connect service %p", service);
- __connman_service_connect(service);
-
- return FALSE;
-}
-
-static void deselect_service(struct session_info *info)
-{
- struct service_entry *entry;
- connman_bool_t disconnect, connected;
-
- DBG("");
-
- if (info->entry == NULL)
- return;
-
- disconnect = explicit_disconnect(info);
-
- connected = is_connecting(info->entry->state) == TRUE ||
- is_connected(info->entry->state) == TRUE;
-
- info->state = CONNMAN_SESSION_STATE_DISCONNECTED;
- info->entry->reason = CONNMAN_SESSION_REASON_UNKNOWN;
-
- entry = info->entry;
- info->entry = NULL;
-
- DBG("disconnect %d connected %d", disconnect, connected);
-
- if (disconnect == TRUE && connected == TRUE)
- pending_timeout_add(0, call_disconnect, entry);
-}
-
-static void deselect_and_disconnect(struct connman_session *session)
-{
- struct session_info *info = session->info;
-
- deselect_service(info);
-
- info->reason = CONNMAN_SESSION_REASON_FREE_RIDE;
-}
-
-static void select_connected_service(struct session_info *info,
- struct service_entry *entry)
-{
- enum connman_session_state state;
-
- state = service_to_session_state(entry->state);
- if (is_type_matching_state(&state, info->config.type) == FALSE)
- return;
-
- info->state = state;
-
- info->entry = entry;
- info->entry->reason = info->reason;
-
- if (explicit_connect(info->reason) == FALSE)
- return;
-
- __connman_service_session_inc(info->entry->service);
-}
-
-static void select_offline_service(struct session_info *info,
- struct service_entry *entry)
-{
- if (explicit_connect(info->reason) == FALSE)
- return;
-
- info->state = service_to_session_state(entry->state);
-
- info->entry = entry;
- info->entry->reason = info->reason;
-
- __connman_service_session_inc(info->entry->service);
- pending_timeout_add(0, call_connect, entry);
-}
-
-static void select_service(struct session_info *info,
- struct service_entry *entry)
-{
- DBG("service %p", entry->service);
-
- if (is_connected(entry->state) == TRUE)
- select_connected_service(info, entry);
- else
- select_offline_service(info, entry);
-}
-
-static void select_and_connect(struct connman_session *session,
- enum connman_session_reason reason)
-{
- struct session_info *info = session->info;
- struct service_entry *entry = NULL;
- GList *list;
-
- DBG("session %p reason %s", session, reason2string(reason));
-
- info->reason = reason;
-
- for (list = session->service_list; list != NULL; list = list->next) {
- entry = list->data;
-
- switch (entry->state) {
- case CONNMAN_SERVICE_STATE_ASSOCIATION:
- case CONNMAN_SERVICE_STATE_CONFIGURATION:
- case CONNMAN_SERVICE_STATE_READY:
- case CONNMAN_SERVICE_STATE_ONLINE:
- case CONNMAN_SERVICE_STATE_IDLE:
- case CONNMAN_SERVICE_STATE_DISCONNECT:
- select_service(info, entry);
- return;
- case CONNMAN_SERVICE_STATE_UNKNOWN:
- case CONNMAN_SERVICE_STATE_FAILURE:
- break;
- }
- }
-}
-
-static struct service_entry *create_service_entry(struct connman_session * session,
- struct connman_service *service,
- const char *name,
- enum connman_service_state state)
-{
- struct service_entry *entry;
- enum connman_service_type type;
- int idx;
-
- entry = g_try_new0(struct service_entry, 1);
- if (entry == NULL)
- return entry;
-
- entry->reason = CONNMAN_SESSION_REASON_UNKNOWN;
- entry->state = state;
- if (name != NULL)
- entry->name = name;
- else
- entry->name = "";
- entry->service = service;
-
- idx = __connman_service_get_index(entry->service);
- entry->ifname = connman_inet_ifname(idx);
- if (entry->ifname == NULL)
- entry->ifname = g_strdup("");
-
- type = connman_service_get_type(entry->service);
- entry->bearer = service2bearer(type);
-
- entry->session = session;
-
- return entry;
-}
-
-static void iterate_service_cb(struct connman_service *service,
- const char *name,
- enum connman_service_state state,
- void *user_data)
-{
- struct connman_session *session = user_data;
- struct service_entry *entry;
-
- if (service_match(session, service) == FALSE)
- return;
-
- entry = create_service_entry(session, service, name, state);
- if (entry == NULL)
- return;
-
- g_hash_table_replace(session->service_hash, service, entry);
-}
-
-static void destroy_service_entry(gpointer data)
-{
- struct service_entry *entry = data;
- struct session_info *info = entry->session->info;
- struct connman_session *session;
-
- if (info != NULL && info->entry == entry) {
- session = entry->session;
- deselect_and_disconnect(session);
- }
-
- pending_timeout_remove_all(entry);
- g_free(entry->ifname);
-
- g_free(entry);
-}
-
-static void populate_service_list(struct connman_session *session)
-{
- GHashTableIter iter;
- gpointer key, value;
-
- session->service_hash =
- g_hash_table_new_full(g_direct_hash, g_direct_equal,
- NULL, destroy_service_entry);
- __connman_service_iterate_services(iterate_service_cb, session);
-
- g_hash_table_iter_init(&iter, session->service_hash);
-
- while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
- struct service_entry *entry = value;
-
- DBG("service %p type %s name %s", entry->service,
- service2bearer(connman_service_get_type(entry->service)),
- entry->name);
- session->service_list = g_list_prepend(session->service_list,
- entry);
- }
-
- session->service_list = g_list_sort_with_data(session->service_list,
- sort_services, session);
-}
-
-static void session_changed(struct connman_session *session,
- enum connman_session_trigger trigger)
-{
- struct session_info *info = session->info;
- struct session_info *info_last = session->info_last;
- struct connman_service *service;
- struct service_entry *entry = NULL, *entry_last = NULL;
- GHashTable *service_hash_last;
-
- /*
- * TODO: This only a placeholder for the 'real' algorithm to
- * play a bit around. So we are going to improve it step by step.
- */
-
- DBG("session %p trigger %s reason %s", session, trigger2string(trigger),
- reason2string(info->reason));
-
- if (info->entry != NULL) {
- enum connman_session_state state;
-
- state = service_to_session_state(info->entry->state);
-
- if (is_type_matching_state(&state, info->config.type) == TRUE)
- info->state = state;
- }
-
- switch (trigger) {
- case CONNMAN_SESSION_TRIGGER_UNKNOWN:
- DBG("ignore session changed event");
- return;
- case CONNMAN_SESSION_TRIGGER_SETTING:
- if (info->config.allowed_bearers != info_last->config.allowed_bearers) {
-
- service_hash_last = session->service_hash;
- g_list_free(session->service_list);
- session->service_list = NULL;
-
- if (info->entry != NULL)
- service = info->entry->service;
- else
- service = NULL;
-
- populate_service_list(session);
-
- if (info->entry != NULL) {
- entry_last = g_hash_table_lookup(
- service_hash_last,
- info->entry->service);
- entry = g_hash_table_lookup(
- session->service_hash,
- service);
- }
-
- if (entry == NULL && entry_last != NULL) {
- /*
- * The currently selected service is
- * not part of this session anymore.
- */
- deselect_and_disconnect(session);
- }
-
- g_hash_table_destroy(service_hash_last);
- }
-
- if (info->config.type != info_last->config.type) {
- if (info->state >= CONNMAN_SESSION_STATE_CONNECTED &&
- is_type_matching_state(&info->state,
- info->config.type) == FALSE)
- deselect_and_disconnect(session);
- }
-
- if (info->state == CONNMAN_SESSION_STATE_DISCONNECTED) {
- select_and_connect(session,
- CONNMAN_SESSION_REASON_FREE_RIDE);
- }
-
- break;
- case CONNMAN_SESSION_TRIGGER_ECALL:
- /*
- * For the time beeing we fallback to normal connect
- * strategy.
- */
- case CONNMAN_SESSION_TRIGGER_CONNECT:
- if (info->state >= CONNMAN_SESSION_STATE_CONNECTED) {
- if (info->entry->reason == CONNMAN_SESSION_REASON_CONNECT)
- break;
- info->entry->reason = CONNMAN_SESSION_REASON_CONNECT;
- __connman_service_session_inc(info->entry->service);
- break;
- }
-
- if (info->entry != NULL &&
- is_connecting(info->entry->state) == TRUE) {
- break;
- }
-
- select_and_connect(session,
- CONNMAN_SESSION_REASON_CONNECT);
-
- break;
- case CONNMAN_SESSION_TRIGGER_DISCONNECT:
- deselect_and_disconnect(session);
-
- break;
- case CONNMAN_SESSION_TRIGGER_SERVICE:
- if (info->entry != NULL &&
- (is_connecting(info->entry->state) == TRUE ||
- is_connected(info->entry->state) == TRUE)) {
- break;
- }
-
- deselect_and_disconnect(session);
-
- if (info->reason == CONNMAN_SESSION_REASON_FREE_RIDE) {
- select_and_connect(session, info->reason);
- }
-
- break;
- }
-
- session_notify(session);
+ session->service);
}
int connman_session_config_update(struct connman_session *session)
@@ -1439,16 +891,33 @@ int connman_session_config_update(struct connman_session *session)
* might have changed. We can still optimize this later.
*/
- err = apply_policy_on_bearers(
+ if (session->id_type != session->policy_config->id_type) {
+ cleanup_firewall_session(session);
+ err = init_firewall_session(session);
+ if (err < 0) {
+ connman_session_destroy(session);
+ return err;
+ }
+
+ session->id_type = session->policy_config->id_type;
+ }
+
+ apply_policy_on_bearers(
session->policy_config->allowed_bearers,
session->user_allowed_bearers,
&allowed_bearers);
- if (err < 0)
- return err;
+
+ if (session->active)
+ set_active_session(session, false);
+
+ session->active = false;
+ session_deactivate(session);
g_slist_free(info->config.allowed_bearers);
info->config.allowed_bearers = allowed_bearers;
+ session_activate(session);
+
info->config.type = apply_policy_on_type(
session->policy_config->type,
info->config.type);
@@ -1456,12 +925,12 @@ int connman_session_config_update(struct connman_session *session)
info->config.roaming_policy = session->policy_config->roaming_policy;
info->config.ecall = session->policy_config->ecall;
- if (info->config.ecall == TRUE)
+ if (info->config.ecall)
ecall_session = session;
info->config.priority = session->policy_config->priority;
- session_changed(session, CONNMAN_SESSION_TRIGGER_SETTING);
+ session_notify(session);
return 0;
}
@@ -1473,14 +942,21 @@ static DBusMessage *connect_session(DBusConnection *conn,
DBG("session %p", session);
- if (ecall_session != NULL) {
- if (ecall_session->ecall == TRUE && ecall_session != session)
+ if (ecall_session) {
+ if (ecall_session->ecall && ecall_session != session)
return __connman_error_failed(msg, EBUSY);
- session->ecall = TRUE;
- session_changed(session, CONNMAN_SESSION_TRIGGER_ECALL);
- } else
- session_changed(session, CONNMAN_SESSION_TRIGGER_CONNECT);
+ session->ecall = true;
+ }
+
+ if (!session->active) {
+ session->active = true;
+ set_active_session(session, true);
+ }
+
+ session_activate(session);
+
+ __connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_SESSION);
return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
}
@@ -1492,14 +968,20 @@ static DBusMessage *disconnect_session(DBusConnection *conn,
DBG("session %p", session);
- if (ecall_session != NULL) {
- if (ecall_session->ecall == TRUE && ecall_session != session)
+ if (ecall_session) {
+ if (ecall_session->ecall && ecall_session != session)
return __connman_error_failed(msg, EBUSY);
- session->ecall = FALSE;
+ session->ecall = false;
}
- session_changed(session, CONNMAN_SESSION_TRIGGER_DISCONNECT);
+ if (session->active) {
+ session->active = false;
+ set_active_session(session, false);
+ }
+
+ session_deactivate(session);
+ update_session_state(session);
return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
}
@@ -1516,7 +998,7 @@ static DBusMessage *change_session(DBusConnection *conn,
int err;
DBG("session %p", session);
- if (dbus_message_iter_init(msg, &iter) == FALSE)
+ if (!dbus_message_iter_init(msg, &iter))
return __connman_error_invalid_arguments(msg);
if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
@@ -1532,27 +1014,32 @@ static DBusMessage *change_session(DBusConnection *conn,
switch (dbus_message_iter_get_arg_type(&value)) {
case DBUS_TYPE_ARRAY:
- if (g_str_equal(name, "AllowedBearers") == TRUE) {
+ if (g_str_equal(name, "AllowedBearers")) {
err = parse_bearers(&value, &allowed_bearers);
if (err < 0)
- return __connman_error_failed(msg, err);
+ return __connman_error_failed(msg, -err);
+
+ if (session->active)
+ set_active_session(session, false);
+
+ session->active = false;
+ session_deactivate(session);
g_slist_free(info->config.allowed_bearers);
session->user_allowed_bearers = allowed_bearers;
- err = apply_policy_on_bearers(
+ apply_policy_on_bearers(
session->policy_config->allowed_bearers,
session->user_allowed_bearers,
&info->config.allowed_bearers);
- if (err < 0)
- return __connman_error_failed(msg, err);
+ session_activate(session);
} else {
goto err;
}
break;
case DBUS_TYPE_STRING:
- if (g_str_equal(name, "ConnectionType") == TRUE) {
+ if (g_str_equal(name, "ConnectionType")) {
dbus_message_iter_get_basic(&value, &val);
info->config.type = apply_policy_on_type(
session->policy_config->type,
@@ -1565,7 +1052,7 @@ static DBusMessage *change_session(DBusConnection *conn,
goto err;
}
- session_changed(session, CONNMAN_SESSION_TRIGGER_SETTING);
+ session_notify(session);
return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
@@ -1590,7 +1077,7 @@ static void release_session(gpointer key, gpointer value, gpointer user_data)
session->notify_path,
CONNMAN_NOTIFICATION_INTERFACE,
"Release");
- if (message == NULL)
+ if (!message)
return;
dbus_message_set_no_reply(message, TRUE);
@@ -1608,8 +1095,6 @@ static int session_disconnect(struct connman_session *session)
g_dbus_unregister_interface(connection, session->session_path,
CONNMAN_SESSION_INTERFACE);
- deselect_and_disconnect(session);
-
g_hash_table_remove(session_hash, session->session_path);
return 0;
@@ -1631,7 +1116,7 @@ static DBusMessage *destroy_session(DBusConnection *conn,
DBG("session %p", session);
- if (ecall_session != NULL && ecall_session != session)
+ if (ecall_session && ecall_session != session)
return __connman_error_failed(msg, EBUSY);
session_disconnect(session);
@@ -1650,86 +1135,93 @@ static const GDBusMethodTable session_methods[] = {
{ },
};
-static int session_create_cb(struct connman_session *session,
+static int session_policy_config_cb(struct connman_session *session,
struct connman_session_config *config,
void *user_data, int err)
{
- DBusMessage *reply;
- struct user_config *user_config = user_data;
+ struct creation_data *creation_data = user_data;
struct session_info *info, *info_last;
+ DBusMessage *reply;
DBG("session %p config %p", session, config);
- if (err != 0)
- goto out;
+ if (err < 0)
+ goto err;
session->policy_config = config;
+ session->mark = session_mark++;
+ session->index = -1;
+
+ err = init_firewall_session(session);
+ if (err < 0)
+ goto err;
+
+ err = init_routing_table(session);
+ if (err < 0)
+ goto err;
+
info = session->info;
info_last = session->info_last;
- if (session->policy_config->ecall == TRUE)
+ if (session->policy_config->ecall)
ecall_session = session;
info->state = CONNMAN_SESSION_STATE_DISCONNECTED;
info->config.type = apply_policy_on_type(
session->policy_config->type,
- user_config->type);
+ creation_data->type);
info->config.priority = session->policy_config->priority;
info->config.roaming_policy = session->policy_config->roaming_policy;
- info->entry = NULL;
- session->user_allowed_bearers = user_config->allowed_bearers;
- user_config->allowed_bearers = NULL;
+ session->user_allowed_bearers = creation_data->allowed_bearers;
+ creation_data->allowed_bearers = NULL;
- err = apply_policy_on_bearers(
+ apply_policy_on_bearers(
session->policy_config->allowed_bearers,
session->user_allowed_bearers,
&info->config.allowed_bearers);
- if (err < 0)
- goto out;
g_hash_table_replace(session_hash, session->session_path, session);
DBG("add %s", session->session_path);
- if (g_dbus_register_interface(connection, session->session_path,
+ if (!g_dbus_register_interface(connection, session->session_path,
CONNMAN_SESSION_INTERFACE,
- session_methods, NULL,
- NULL, session, NULL) == FALSE) {
+ session_methods, NULL, NULL,
+ session, NULL)) {
connman_error("Failed to register %s", session->session_path);
g_hash_table_remove(session_hash, session->session_path);
err = -EINVAL;
- goto out;
+ goto err;
}
- reply = g_dbus_create_reply(user_config->pending,
+ reply = g_dbus_create_reply(creation_data->pending,
DBUS_TYPE_OBJECT_PATH, &session->session_path,
DBUS_TYPE_INVALID);
g_dbus_send_message(connection, reply);
- user_config->pending = NULL;
-
- populate_service_list(session);
+ creation_data->pending = NULL;
info_last->state = info->state;
info_last->config.priority = info->config.priority;
info_last->config.roaming_policy = info->config.roaming_policy;
- info_last->entry = info->entry;
info_last->config.allowed_bearers = info->config.allowed_bearers;
- session->append_all = TRUE;
+ session->append_all = true;
- session_changed(session, CONNMAN_SESSION_TRIGGER_SETTING);
+ cleanup_creation_data(creation_data);
-out:
- if (err < 0) {
- reply = __connman_error_failed(user_config->pending, -err);
- g_dbus_send_message(connection, reply);
+ session_activate(session);
- free_session(session);
- }
+ return 0;
+
+err:
+ reply = __connman_error_failed(creation_data->pending, -err);
+ g_dbus_send_message(connection, reply);
+ creation_data->pending = NULL;
- cleanup_user_config(user_config);
+ cleanup_session(session);
+ cleanup_creation_data(creation_data);
return err;
}
@@ -1740,16 +1232,17 @@ int __connman_session_create(DBusMessage *msg)
char *session_path = NULL;
DBusMessageIter iter, array;
struct connman_session *session = NULL;
- struct user_config *user_config = NULL;
- connman_bool_t user_allowed_bearers = FALSE;
- connman_bool_t user_connection_type = FALSE;
- int err;
+ struct creation_data *creation_data = NULL;
+ bool user_allowed_bearers = false;
+ bool user_connection_type = false;
+ int err, i;
+ char *str;
owner = dbus_message_get_sender(msg);
DBG("owner %s", owner);
- if (ecall_session != NULL && ecall_session->ecall == TRUE) {
+ if (ecall_session && ecall_session->ecall) {
/*
* If there is an emergency call already going on,
* ignore session creation attempt
@@ -1758,13 +1251,13 @@ int __connman_session_create(DBusMessage *msg)
goto err;
}
- user_config = g_try_new0(struct user_config, 1);
- if (user_config == NULL) {
+ creation_data = g_try_new0(struct creation_data, 1);
+ if (!creation_data) {
err = -ENOMEM;
goto err;
}
- user_config->pending = dbus_message_ref(msg);
+ creation_data->pending = dbus_message_ref(msg);
dbus_message_iter_init(msg, &iter);
dbus_message_iter_recurse(&iter, &array);
@@ -1781,25 +1274,25 @@ int __connman_session_create(DBusMessage *msg)
switch (dbus_message_iter_get_arg_type(&value)) {
case DBUS_TYPE_ARRAY:
- if (g_str_equal(key, "AllowedBearers") == TRUE) {
+ if (g_str_equal(key, "AllowedBearers")) {
err = parse_bearers(&value,
- &user_config->allowed_bearers);
+ &creation_data->allowed_bearers);
if (err < 0)
goto err;
- user_allowed_bearers = TRUE;
+ user_allowed_bearers = true;
} else {
err = -EINVAL;
goto err;
}
break;
case DBUS_TYPE_STRING:
- if (g_str_equal(key, "ConnectionType") == TRUE) {
+ if (g_str_equal(key, "ConnectionType")) {
dbus_message_iter_get_basic(&value, &val);
- user_config->type =
+ creation_data->type =
connman_session_parse_connection_type(val);
- user_connection_type = TRUE;
+ user_connection_type = true;
} else {
err = -EINVAL;
goto err;
@@ -1814,36 +1307,40 @@ int __connman_session_create(DBusMessage *msg)
*
* For AllowedBearers this is '*', ...
*/
- if (user_allowed_bearers == FALSE) {
- user_config->allowed_bearers =
- g_slist_append(NULL,
- GINT_TO_POINTER(CONNMAN_SERVICE_TYPE_UNKNOWN));
- if (user_config->allowed_bearers == NULL) {
+ if (!user_allowed_bearers) {
+ add_default_bearer_types(&creation_data->allowed_bearers);
+ if (!creation_data->allowed_bearers) {
err = -ENOMEM;
goto err;
}
}
/* ... and for ConnectionType it is 'any'. */
- if (user_connection_type == FALSE)
- user_config->type = CONNMAN_SESSION_TYPE_ANY;
+ if (!user_connection_type)
+ creation_data->type = CONNMAN_SESSION_TYPE_ANY;
dbus_message_iter_next(&iter);
dbus_message_iter_get_basic(&iter, &notify_path);
- if (notify_path == NULL) {
+ if (!notify_path) {
err = -EINVAL;
goto err;
}
- session_path = g_strdup_printf("/sessions%s", notify_path);
- if (session_path == NULL) {
+ str = g_strdup(owner);
+ for (i = 0; str[i] != '\0'; i++)
+ if (str[i] == ':' || str[i] == '.')
+ str[i] = '_';
+ session_path = g_strdup_printf("/sessions/%s%s", str, notify_path);
+ g_free(str);
+
+ if (!session_path) {
err = -ENOMEM;
goto err;
}
session = g_hash_table_lookup(session_hash, session_path);
- if (session != NULL) {
+ if (session) {
g_free(session_path);
session = NULL;
err = -EEXIST;
@@ -1851,22 +1348,23 @@ int __connman_session_create(DBusMessage *msg)
}
session = g_try_new0(struct connman_session, 1);
- if (session == NULL) {
+ if (!session) {
g_free(session_path);
err = -ENOMEM;
goto err;
}
+ creation_data->session = session;
session->session_path = session_path;
session->info = g_try_new0(struct session_info, 1);
- if (session->info == NULL) {
+ if (!session->info) {
err = -ENOMEM;
goto err;
}
session->info_last = g_try_new0(struct session_info, 1);
- if (session->info_last == NULL) {
+ if (!session->info_last) {
err = -ENOMEM;
goto err;
}
@@ -1877,11 +1375,8 @@ int __connman_session_create(DBusMessage *msg)
g_dbus_add_disconnect_watch(connection, session->owner,
owner_disconnect, session, NULL);
- err = assign_policy_plugin(session);
- if (err < 0)
- goto err;
-
- err = create_policy_config(session, session_create_cb, user_config);
+ err = create_policy_config(session, session_policy_config_cb,
+ creation_data);
if (err < 0 && err != -EINPROGRESS)
return err;
@@ -1892,10 +1387,18 @@ err:
free_session(session);
- cleanup_user_config(user_config);
+ cleanup_creation_data(creation_data);
return err;
}
+bool __connman_session_policy_autoconnect(enum connman_service_connect_reason reason)
+{
+ if (!policy || !policy->autoconnect)
+ return true;
+
+ return policy->autoconnect(reason);
+}
+
void connman_session_destroy(struct connman_session *session)
{
DBG("session %p", session);
@@ -1914,11 +1417,11 @@ int __connman_session_destroy(DBusMessage *msg)
dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &session_path,
DBUS_TYPE_INVALID);
- if (session_path == NULL)
+ if (!session_path)
return -EINVAL;
session = g_hash_table_lookup(session_hash, session_path);
- if (session == NULL)
+ if (!session)
return -EINVAL;
if (g_strcmp0(owner, session->owner) != 0)
@@ -1929,111 +1432,241 @@ int __connman_session_destroy(DBusMessage *msg)
return 0;
}
-connman_bool_t __connman_session_mode()
+int connman_session_connect(struct connman_service *service)
{
- return sessionmode;
+ DBG("service %p name %s", service, __connman_service_get_name(service));
+
+ return __connman_service_connect(service,
+ CONNMAN_SERVICE_CONNECT_REASON_SESSION);
}
-void __connman_session_set_mode(connman_bool_t enable)
+int connman_session_disconnect(struct connman_service *service)
{
- DBG("enable %d", enable);
+ DBG("service %p", service);
- if (sessionmode != enable) {
- sessionmode = enable;
+ return __connman_service_disconnect(service);
+}
- connman_dbus_property_changed_basic(CONNMAN_MANAGER_PATH,
- CONNMAN_MANAGER_INTERFACE, "SessionMode",
- DBUS_TYPE_BOOLEAN, &sessionmode);
+static enum connman_session_state service_to_session_state(
+ enum connman_service_state state)
+{
+ switch (state) {
+ case CONNMAN_SERVICE_STATE_UNKNOWN:
+ case CONNMAN_SERVICE_STATE_IDLE:
+ case CONNMAN_SERVICE_STATE_ASSOCIATION:
+ case CONNMAN_SERVICE_STATE_CONFIGURATION:
+ case CONNMAN_SERVICE_STATE_DISCONNECT:
+ case CONNMAN_SERVICE_STATE_FAILURE:
+ break;
+ case CONNMAN_SERVICE_STATE_READY:
+ return CONNMAN_SESSION_STATE_CONNECTED;
+ case CONNMAN_SERVICE_STATE_ONLINE:
+ return CONNMAN_SESSION_STATE_ONLINE;
}
- if (sessionmode == TRUE)
- __connman_service_disconnect_all();
+ return CONNMAN_SESSION_STATE_DISCONNECTED;
}
-static void service_add(struct connman_service *service,
- const char *name)
+static void update_session_state(struct connman_session *session)
{
- GHashTableIter iter;
- gpointer key, value;
- struct connman_session *session;
- struct service_entry *entry;
+ enum connman_service_state service_state;
+ enum connman_session_state state = CONNMAN_SESSION_STATE_DISCONNECTED;
- DBG("service %p", service);
+ if (session->service) {
+ service_state = __connman_service_get_state(session->service);
+ state = service_to_session_state(service_state);
+ session->info->state = state;
+ }
+ session->info->state = state;
- g_hash_table_iter_init(&iter, session_hash);
+ DBG("session %p state %s", session, state2string(state));
- while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
- session = value;
-
- if (service_match(session, service) == FALSE)
- continue;
+ update_routing_table(session);
+ session_notify(session);
+}
- entry = create_service_entry(session, service, name,
- CONNMAN_SERVICE_STATE_IDLE);
- if (entry == NULL)
- continue;
+static bool session_match_service(struct connman_session *session,
+ struct connman_service *service)
+{
+ enum connman_service_type bearer_type;
+ enum connman_service_type service_type;
+ GSList *list;
- session->service_list = g_list_insert_sorted_with_data(
- session->service_list, entry, sort_services, session);
+ if (policy && policy->allowed)
+ return policy->allowed(session, service);
- g_hash_table_replace(session->service_hash, service, entry);
+ for (list = session->info->config.allowed_bearers; list; list = list->next) {
+ bearer_type = GPOINTER_TO_INT(list->data);
+ service_type = connman_service_get_type(service);
- session_changed(session, CONNMAN_SESSION_TRIGGER_SERVICE);
+ if (bearer_type == service_type)
+ return true;
}
+
+ return false;
}
-static void service_remove(struct connman_service *service)
+static bool is_session_connected(struct connman_session *session,
+ enum connman_service_state state)
+
{
+ switch (state) {
+ case CONNMAN_SERVICE_STATE_UNKNOWN:
+ case CONNMAN_SERVICE_STATE_IDLE:
+ case CONNMAN_SERVICE_STATE_ASSOCIATION:
+ case CONNMAN_SERVICE_STATE_CONFIGURATION:
+ case CONNMAN_SERVICE_STATE_DISCONNECT:
+ case CONNMAN_SERVICE_STATE_FAILURE:
+ break;
+ case CONNMAN_SERVICE_STATE_READY:
+ if (session->info->config.type == CONNMAN_SESSION_TYPE_INTERNET)
+ return false;
+ case CONNMAN_SERVICE_STATE_ONLINE:
+ return true;
+ }
+ return false;
+}
+
+static void session_activate(struct connman_session *session)
+{
GHashTableIter iter;
gpointer key, value;
- struct connman_session *session;
- struct session_info *info;
- DBG("service %p", service);
+ if (!service_hash)
+ return;
+
+ g_hash_table_iter_init(&iter, service_hash);
+ while (g_hash_table_iter_next(&iter, &key, &value)) {
+ struct connman_service_info *info = value;
+ enum connman_service_state state;
+
+ state = __connman_service_get_state(info->service);
+
+ if (is_session_connected(session, state) &&
+ session_match_service(session, info->service)) {
+ DBG("session %p add service %p", session, info->service);
+
+ info->sessions = g_slist_prepend(info->sessions,
+ session);
+ session->service = info->service;
+ update_session_state(session);
+
+ return;
+ }
+ }
+
+ session_notify(session);
+}
+
+static void session_deactivate(struct connman_session *session)
+{
+ struct connman_service_info *info;
+
+ if (!service_hash)
+ return;
+
+ if (!session->service)
+ return;
+
+ info = g_hash_table_lookup(service_hash, session->service);
+ if (!info)
+ return;
+
+ info->sessions = g_slist_remove(info->sessions, session);
+ session->service = NULL;
+
+ session->info->state = CONNMAN_SESSION_STATE_DISCONNECTED;
+}
+
+static void handle_service_state_online(struct connman_service *service,
+ enum connman_service_state state,
+ struct connman_service_info *info)
+{
+ GHashTableIter iter;
+ gpointer key, value;
g_hash_table_iter_init(&iter, session_hash);
+ while (g_hash_table_iter_next(&iter, &key, &value)) {
+ struct connman_session *session = value;
+ bool connected;
- while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
- struct service_entry *entry;
- session = value;
- info = session->info;
+ connected = is_session_connected(session, state);
- entry = g_hash_table_lookup(session->service_hash, service);
- if (entry == NULL)
- continue;
+ if (session->service == service) {
+ if (!connected) {
+ DBG("session %p remove service %p", session, service);
+ info->sessions = g_slist_remove(info->sessions,
+ session);
+ session->service = NULL;
+ update_session_state(session);
+ }
+ } else if (connected && session_match_service(session, service)) {
+ DBG("session %p add service %p", session, service);
- session->service_list = g_list_remove(session->service_list,
- entry);
+ info->sessions = g_slist_prepend(info->sessions,
+ session);
+ session->service = service;
+ update_session_state(session);
+ }
+ }
+}
+
+static void handle_service_state_offline(struct connman_service *service,
+ struct connman_service_info *info)
+{
+ GSList *list;
- g_hash_table_remove(session->service_hash, service);
+ for (list = info->sessions; list; list = list->next) {
+ struct connman_session *session = list->data;
- if (info->entry != NULL && info->entry->service == service)
- info->entry = NULL;
- session_changed(session, CONNMAN_SESSION_TRIGGER_SERVICE);
+ if (session->service != service) {
+ connman_warn("session %p should have session %p assigned",
+ session, service);
+ continue;
+ }
+
+ DBG("session %p remove service %p", session, service);
+
+ session->service = NULL;
+ update_session_state(session);
}
}
+
static void service_state_changed(struct connman_service *service,
- enum connman_service_state state)
+ enum connman_service_state state)
{
- GHashTableIter iter;
- gpointer key, value;
+ struct connman_service_info *info;
DBG("service %p state %d", service, state);
- g_hash_table_iter_init(&iter, session_hash);
+ info = g_hash_table_lookup(service_hash, service);
- while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
- struct connman_session *session = value;
- struct service_entry *entry;
+ switch (state) {
+ case CONNMAN_SERVICE_STATE_UNKNOWN:
+ case CONNMAN_SERVICE_STATE_IDLE:
+ case CONNMAN_SERVICE_STATE_ASSOCIATION:
+ case CONNMAN_SERVICE_STATE_CONFIGURATION:
+ case CONNMAN_SERVICE_STATE_FAILURE:
+ case CONNMAN_SERVICE_STATE_DISCONNECT:
+ if (!info)
+ return;
+
+ handle_service_state_offline(service, info);
- entry = g_hash_table_lookup(session->service_hash, service);
- if (entry != NULL)
- entry->state = state;
+ g_hash_table_remove(service_hash, service);
- session_changed(session,
- CONNMAN_SESSION_TRIGGER_SERVICE);
+ return;
+ case CONNMAN_SERVICE_STATE_READY:
+ case CONNMAN_SERVICE_STATE_ONLINE:
+ if (!info) {
+ info = g_new0(struct connman_service_info, 1);
+ g_hash_table_replace(service_hash, service, info);
+ }
+
+ info->service = service;
+ handle_service_state_online(service, state, info);
}
}
@@ -2052,14 +1685,16 @@ static void ipconfig_changed(struct connman_service *service,
g_hash_table_iter_init(&iter, session_hash);
- while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
+ while (g_hash_table_iter_next(&iter, &key, &value)) {
session = value;
info = session->info;
if (info->state == CONNMAN_SESSION_STATE_DISCONNECTED)
continue;
- if (info->entry != NULL && info->entry->service == service) {
+ if (session->service && session->service == service) {
+ update_routing_table(session);
+
if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
ipconfig_ipv4_changed(session);
else if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
@@ -2070,8 +1705,6 @@ static void ipconfig_changed(struct connman_service *service,
static struct connman_notifier session_notifier = {
.name = "session",
- .service_add = service_add,
- .service_remove = service_remove,
.service_state_changed = service_state_changed,
.ipconfig_changed = ipconfig_changed,
};
@@ -2083,7 +1716,7 @@ int __connman_session_init(void)
DBG("");
connection = connman_dbus_get_connection();
- if (connection == NULL)
+ if (!connection)
return -1;
err = connman_notifier_register(&session_notifier);
@@ -2095,7 +1728,14 @@ int __connman_session_init(void)
session_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
NULL, cleanup_session);
- sessionmode = FALSE;
+ service_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal,
+ NULL, cleanup_service);
+ if (__connman_firewall_is_up()) {
+ err = init_firewall();
+ if (err < 0)
+ return err;
+ }
+
return 0;
}
@@ -2103,14 +1743,18 @@ void __connman_session_cleanup(void)
{
DBG("");
- if (connection == NULL)
+ if (!connection)
return;
+ cleanup_firewall();
+
connman_notifier_unregister(&session_notifier);
g_hash_table_foreach(session_hash, release_session, NULL);
g_hash_table_destroy(session_hash);
session_hash = NULL;
+ g_hash_table_destroy(service_hash);
+ service_hash = NULL;
dbus_connection_unref(connection);
}
diff --git a/src/shared/debugfs.c b/src/shared/debugfs.c
deleted file mode 100644
index f522c518..00000000
--- a/src/shared/debugfs.c
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- *
- * Connection Manager
- *
- * Copyright (C) 2012 Intel Corporation. All rights reserved.
- *
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdio.h>
-#include <stdbool.h>
-#include <string.h>
-#include <limits.h>
-
-#include "src/shared/debugfs.h"
-
-#define STRINGIFY(x) STRINGIFY_ARG(x)
-#define STRINGIFY_ARG(x) #x
-
-const char *debugfs_get_path(void)
-{
- static char path[PATH_MAX + 1];
- static bool found = false;
- char type[100];
- FILE *fp;
-
- if (found)
- return path;
-
- fp = fopen("/proc/mounts", "r");
- if (!fp)
- return NULL;
-
- while (fscanf(fp, "%*s %" STRINGIFY(PATH_MAX) "s %99s %*s %*d %*d\n",
- path, type) == 2) {
- if (!strcmp(type, "debugfs")) {
- found = true;
- break;
- }
- }
-
- fclose(fp);
-
- if (!found)
- return NULL;
-
- return path;
-}
diff --git a/src/shared/debugfs.h b/src/shared/debugfs.h
deleted file mode 100644
index 7f41ca7f..00000000
--- a/src/shared/debugfs.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- *
- * Connection Manager
- *
- * Copyright (C) 2012 Intel Corporation. All rights reserved.
- *
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-const char *debugfs_get_path(void);
diff --git a/src/shared/netlink.c b/src/shared/netlink.c
new file mode 100644
index 00000000..d72294cc
--- /dev/null
+++ b/src/shared/netlink.c
@@ -0,0 +1,666 @@
+/*
+ *
+ * Connection Manager
+ *
+ * Copyright (C) 2011-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2013 BWM CarIT GmbH.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation.
+ *
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+/*
+ * This file is a copy from ELL which has been ported to use GLib's
+ * data structures.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <linux/netlink.h>
+
+#include <gdbus.h>
+
+#include "src/shared/util.h"
+#include "src/shared/netlink.h"
+
+#ifndef SOL_NETLINK
+#define SOL_NETLINK 270
+#endif
+
+struct command {
+ unsigned int id;
+ uint32_t seq;
+ uint32_t len;
+ netlink_command_func_t handler;
+ netlink_destroy_func_t destroy;
+ void *user_data;
+};
+
+struct notify {
+ uint32_t group;
+ netlink_notify_func_t handler;
+ netlink_destroy_func_t destroy;
+ void *user_data;
+};
+
+struct netlink_info {
+ uint32_t pid;
+ GIOChannel *channel;
+ uint32_t next_seq;
+ GQueue *command_queue;
+ GHashTable *command_pending;
+ GHashTable *command_lookup;
+ unsigned int next_command_id;
+ GHashTable *notify_groups;
+ GHashTable *notify_lookup;
+ unsigned int next_notify_id;
+ netlink_debug_func_t debug_handler;
+ netlink_destroy_func_t debug_destroy;
+ void *debug_data;
+};
+
+
+static void destroy_command(struct command *command)
+{
+ if (command->destroy)
+ command->destroy(command->user_data);
+
+ g_free(command);
+}
+
+static void destroy_notify(struct notify *notify)
+{
+ if (notify->destroy)
+ notify->destroy(notify->user_data);
+
+ g_free(notify);
+}
+
+static gboolean can_write_data(GIOChannel *chan,
+ GIOCondition cond, gpointer user_data)
+{
+ struct netlink_info *netlink = user_data;
+ struct command *command;
+ struct sockaddr_nl addr;
+ const void *data;
+ ssize_t written;
+ int sk;
+
+ command = g_queue_pop_head(netlink->command_queue);
+ if (!command)
+ return FALSE;
+
+ sk = g_io_channel_unix_get_fd(chan);
+
+ memset(&addr, 0, sizeof(addr));
+ addr.nl_family = AF_NETLINK;
+ addr.nl_pid = 0;
+
+ data = ((void *) command) + NLMSG_ALIGN(sizeof(struct command));
+
+ written = sendto(sk, data, command->len, 0,
+ (struct sockaddr *) &addr, sizeof(addr));
+ if (written < 0 || (uint32_t) written != command->len) {
+ g_hash_table_remove(netlink->command_lookup,
+ GUINT_TO_POINTER(command->id));
+ destroy_command(command);
+ return FALSE;
+ }
+
+ util_hexdump('<', data, command->len,
+ netlink->debug_handler, netlink->debug_data);
+
+ g_hash_table_replace(netlink->command_pending,
+ GUINT_TO_POINTER(command->seq), command);
+
+ return g_queue_get_length(netlink->command_queue) > 0;
+}
+
+static void do_notify(gpointer key, gpointer value, gpointer user_data)
+{
+ struct nlmsghdr *nlmsg = user_data;
+ struct notify *notify = value;
+
+ if (notify->handler) {
+ notify->handler(nlmsg->nlmsg_type, NLMSG_DATA(nlmsg),
+ nlmsg->nlmsg_len - NLMSG_HDRLEN, notify->user_data);
+ }
+}
+
+static void process_broadcast(struct netlink_info *netlink, uint32_t group,
+ struct nlmsghdr *nlmsg)
+{
+ GHashTable *notify_list;
+
+ notify_list = g_hash_table_lookup(netlink->notify_groups,
+ GUINT_TO_POINTER(group));
+ if (!notify_list)
+ return;
+
+ g_hash_table_foreach(notify_list, do_notify, nlmsg);
+}
+
+static void process_message(struct netlink_info *netlink,
+ struct nlmsghdr *nlmsg)
+{
+ const void *data = nlmsg;
+ struct command *command;
+
+ command = g_hash_table_lookup(netlink->command_pending,
+ GUINT_TO_POINTER(nlmsg->nlmsg_seq));
+ if (!command)
+ return;
+
+ g_hash_table_remove(netlink->command_pending,
+ GUINT_TO_POINTER(nlmsg->nlmsg_seq));
+
+ if (!command->handler)
+ goto done;
+
+ if (nlmsg->nlmsg_type < NLMSG_MIN_TYPE) {
+ const struct nlmsgerr *err;
+
+ switch (nlmsg->nlmsg_type) {
+ case NLMSG_ERROR:
+ err = data + NLMSG_HDRLEN;
+
+ command->handler(-err->error, 0, NULL, 0,
+ command->user_data);
+ break;
+ }
+ } else {
+ command->handler(0, nlmsg->nlmsg_type, data + NLMSG_HDRLEN,
+ nlmsg->nlmsg_len - NLMSG_HDRLEN,
+ command->user_data);
+ }
+
+done:
+ g_hash_table_remove(netlink->command_lookup,
+ GUINT_TO_POINTER(command->id));
+
+ destroy_command(command);
+}
+
+static void process_multi(struct netlink_info *netlink, struct nlmsghdr *nlmsg)
+{
+ const void *data = nlmsg;
+ struct command *command;
+
+ command = g_hash_table_lookup(netlink->command_pending,
+ GUINT_TO_POINTER(nlmsg->nlmsg_seq));
+ if (!command)
+ return;
+
+ if (!command->handler)
+ goto done;
+
+ if (nlmsg->nlmsg_type < NLMSG_MIN_TYPE) {
+ const struct nlmsgerr *err;
+
+ switch (nlmsg->nlmsg_type) {
+ case NLMSG_DONE:
+ case NLMSG_ERROR:
+ err = data + NLMSG_HDRLEN;
+
+ command->handler(-err->error, 0, NULL, 0,
+ command->user_data);
+ break;
+ }
+ } else {
+ command->handler(0, nlmsg->nlmsg_type, data + NLMSG_HDRLEN,
+ nlmsg->nlmsg_len - NLMSG_HDRLEN,
+ command->user_data);
+ return;
+ }
+
+done:
+ g_hash_table_remove(netlink->command_pending,
+ GUINT_TO_POINTER(nlmsg->nlmsg_seq));
+
+ g_hash_table_remove(netlink->command_lookup,
+ GUINT_TO_POINTER(command->id));
+
+ destroy_command(command);
+}
+
+static gboolean can_read_data(GIOChannel *chan,
+ GIOCondition cond, gpointer data)
+{
+ struct netlink_info *netlink = data;
+ struct cmsghdr *cmsg;
+ struct msghdr msg;
+ struct iovec iov;
+ struct nlmsghdr *nlmsg;
+ unsigned char buffer[4096];
+ unsigned char control[32];
+ uint32_t group = 0;
+ ssize_t len;
+ int sk;
+
+ sk = g_io_channel_unix_get_fd(chan);
+
+ iov.iov_base = buffer;
+ iov.iov_len = sizeof(buffer);
+
+ memset(&msg, 0, sizeof(msg));
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = control;
+ msg.msg_controllen = sizeof(control);
+
+ len = recvmsg(sk, &msg, 0);
+ if (len < 0)
+ return FALSE;
+
+ util_hexdump('>', buffer, len, netlink->debug_handler,
+ netlink->debug_data);
+
+ for (cmsg = CMSG_FIRSTHDR(&msg); cmsg;
+ cmsg = CMSG_NXTHDR(&msg, cmsg)) {
+ struct nl_pktinfo *pktinfo;
+
+ if (cmsg->cmsg_level != SOL_NETLINK)
+ continue;
+
+ if (cmsg->cmsg_type != NETLINK_PKTINFO)
+ continue;
+
+ pktinfo = (void *) CMSG_DATA(cmsg);
+
+ group = pktinfo->group;
+ }
+
+ for (nlmsg = iov.iov_base; NLMSG_OK(nlmsg, (uint32_t) len);
+ nlmsg = NLMSG_NEXT(nlmsg, len)) {
+ if (group > 0 && nlmsg->nlmsg_seq == 0) {
+ process_broadcast(netlink, group, nlmsg);
+ continue;
+ }
+
+ if (nlmsg->nlmsg_pid != netlink->pid)
+ continue;
+
+ if (nlmsg->nlmsg_flags & NLM_F_MULTI)
+ process_multi(netlink, nlmsg);
+ else
+ process_message(netlink, nlmsg);
+ }
+
+ return TRUE;
+}
+
+static gboolean netlink_event(GIOChannel *chan,
+ GIOCondition cond, gpointer data)
+{
+ if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
+ return FALSE;
+
+ return TRUE;
+}
+
+static int create_netlink_socket(int protocol, uint32_t *pid)
+{
+ struct sockaddr_nl addr;
+ socklen_t addrlen = sizeof(addr);
+ int sk, pktinfo = 1;
+
+ sk = socket(PF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
+ protocol);
+ if (sk < 0)
+ return -1;
+
+ memset(&addr, 0, sizeof(addr));
+ addr.nl_family = AF_NETLINK;
+
+ if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+ close(sk);
+ return -1;
+ }
+
+ if (getsockname(sk, (struct sockaddr *) &addr, &addrlen) < 0) {
+ close(sk);
+ return -1;
+ }
+
+ if (setsockopt(sk, SOL_NETLINK, NETLINK_PKTINFO,
+ &pktinfo, sizeof(pktinfo)) < 0) {
+ close(sk);
+ return -1;
+ }
+
+ if (pid)
+ *pid = addr.nl_pid;
+
+ return sk;
+}
+
+struct netlink_info *netlink_new(int protocol)
+{
+ struct netlink_info *netlink;
+ int sk;
+
+ netlink = g_try_new0(struct netlink_info, 1);
+ if (!netlink)
+ return NULL;
+
+ netlink->next_seq = 1;
+ netlink->next_command_id = 1;
+ netlink->next_notify_id = 1;
+
+ sk = create_netlink_socket(protocol, &netlink->pid);
+ if (sk < 0) {
+ g_free(netlink);
+ return NULL;
+ }
+
+ netlink->channel = g_io_channel_unix_new(sk);
+ g_io_channel_set_close_on_unref(netlink->channel, TRUE);
+
+ g_io_channel_set_encoding(netlink->channel, NULL, NULL);
+ g_io_channel_set_buffered(netlink->channel, FALSE);
+
+ g_io_add_watch(netlink->channel, G_IO_IN, can_read_data, netlink);
+ g_io_add_watch(netlink->channel, G_IO_NVAL | G_IO_HUP | G_IO_ERR,
+ netlink_event, netlink);
+
+ netlink->command_queue = g_queue_new();
+ netlink->command_pending = g_hash_table_new(g_direct_hash,
+ g_direct_equal);
+ netlink->command_lookup = g_hash_table_new(g_direct_hash,
+ g_direct_equal);
+
+ netlink->notify_groups = g_hash_table_new(g_direct_hash,
+ g_direct_equal);
+ netlink->notify_lookup = g_hash_table_new(g_direct_hash,
+ g_direct_equal);
+
+ return netlink;
+}
+
+static gboolean cleanup_notify(gpointer key, gpointer value, gpointer user_data)
+{
+ struct notify *notify = value;
+
+ destroy_notify(notify);
+
+ return TRUE;
+
+}
+
+static gboolean cleanup_notify_group(gpointer key, gpointer value,
+ gpointer user_data)
+{
+ GHashTable *notify_list = value;
+
+ g_hash_table_foreach_remove(notify_list, cleanup_notify, user_data);
+ g_hash_table_destroy(notify_list);
+
+ return TRUE;
+}
+
+static gboolean cleanup_command(gpointer key, gpointer value,
+ gpointer user_data)
+{
+ struct command *command = value;
+
+ destroy_command(command);
+
+ return TRUE;
+}
+
+void netlink_destroy(struct netlink_info *netlink)
+{
+ g_hash_table_destroy(netlink->notify_lookup);
+
+ g_hash_table_foreach_remove(netlink->notify_groups,
+ cleanup_notify_group, NULL);
+ g_hash_table_destroy(netlink->notify_groups);
+
+ g_queue_free(netlink->command_queue);
+
+ g_hash_table_destroy(netlink->command_pending);
+
+ g_hash_table_foreach_remove(netlink->command_lookup,
+ cleanup_command, NULL);
+ g_hash_table_destroy(netlink->command_lookup);
+
+ g_io_channel_shutdown(netlink->channel, TRUE, NULL);
+ g_io_channel_unref(netlink->channel);
+
+ g_free(netlink);
+}
+
+unsigned int netlink_send(struct netlink_info *netlink,
+ uint16_t type, uint16_t flags, const void *data,
+ uint32_t len, netlink_command_func_t function,
+ void *user_data, netlink_destroy_func_t destroy)
+{
+ struct command *command;
+ struct nlmsghdr *nlmsg;
+ size_t size;
+
+ if (!netlink)
+ return 0;
+
+ if (!netlink->command_queue ||
+ !netlink->command_pending ||
+ !netlink->command_lookup)
+ return 0;
+
+ size = NLMSG_ALIGN(sizeof(struct command)) +
+ NLMSG_HDRLEN + NLMSG_ALIGN(len);
+
+ command = g_try_malloc0(size);
+ if (!command)
+ return 0;
+
+ command->handler = function;
+ command->destroy = destroy;
+ command->user_data = user_data;
+
+ command->id = netlink->next_command_id;
+
+ g_hash_table_replace(netlink->command_lookup,
+ GUINT_TO_POINTER(command->id), command);
+
+ command->seq = netlink->next_seq++;
+ command->len = NLMSG_HDRLEN + NLMSG_ALIGN(len);
+
+ nlmsg = ((void *) command) + NLMSG_ALIGN(sizeof(struct command));
+
+ nlmsg->nlmsg_len = command->len;
+ nlmsg->nlmsg_type = type;
+ nlmsg->nlmsg_flags = NLM_F_REQUEST | flags;
+ nlmsg->nlmsg_seq = command->seq;
+ nlmsg->nlmsg_pid = netlink->pid;
+
+ if (data && len > 0)
+ memcpy(((void *) nlmsg) + NLMSG_HDRLEN, data, len);
+
+ g_queue_push_tail(netlink->command_queue, command);
+
+ netlink->next_command_id++;
+
+ /* Arm IOChannel to call can_write_data in case it is not armed yet. */
+ if (g_queue_get_length(netlink->command_queue) == 1)
+ g_io_add_watch(netlink->channel, G_IO_OUT, can_write_data,
+ netlink);
+
+ return command->id;
+}
+
+bool netlink_cancel(struct netlink_info *netlink, unsigned int id)
+{
+ struct command *command;
+
+ if (!netlink || id == 0)
+ return false;
+
+ if (!netlink->command_queue ||
+ !netlink->command_pending ||
+ !netlink->command_lookup)
+ return false;
+
+ command = g_hash_table_lookup(netlink->command_lookup,
+ GUINT_TO_POINTER(id));
+ if (!command)
+ return false;
+
+ g_hash_table_remove(netlink->command_lookup, GUINT_TO_POINTER(id));
+
+ if (!g_queue_remove(netlink->command_queue, command)) {
+ g_hash_table_remove(netlink->command_pending,
+ GUINT_TO_POINTER(command->seq));
+ }
+
+ destroy_command(command);
+
+ return true;
+}
+
+static bool add_membership(struct netlink_info *netlink, uint32_t group)
+{
+ int sk, value = group;
+
+ sk = g_io_channel_unix_get_fd(netlink->channel);
+
+ if (setsockopt(sk, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP,
+ &value, sizeof(value)) < 0)
+ return false;
+
+ return true;
+}
+
+static bool drop_membership(struct netlink_info *netlink, uint32_t group)
+{
+ int sk, value = group;
+
+ sk = g_io_channel_unix_get_fd(netlink->channel);
+
+ if (setsockopt(sk, SOL_NETLINK, NETLINK_DROP_MEMBERSHIP,
+ &value, sizeof(value)) < 0)
+ return false;
+
+ return true;
+}
+
+unsigned int netlink_register(struct netlink_info *netlink,
+ uint32_t group, netlink_notify_func_t function,
+ void *user_data, netlink_destroy_func_t destroy)
+{
+ GHashTable *notify_list;
+ struct notify *notify;
+ unsigned int id;
+
+ if (!netlink)
+ return 0;
+
+ if (!netlink->notify_groups || !netlink->notify_lookup)
+ return 0;
+
+ notify_list = g_hash_table_lookup(netlink->notify_groups,
+ GUINT_TO_POINTER(group));
+ if (!notify_list) {
+ notify_list = g_hash_table_new(g_direct_hash, g_direct_equal);
+ if (!notify_list)
+ return 0;
+
+ g_hash_table_replace(netlink->notify_groups,
+ GUINT_TO_POINTER(group), notify_list);
+ }
+
+ notify = g_new(struct notify, 1);
+
+ notify->group = group;
+ notify->handler = function;
+ notify->destroy = destroy;
+ notify->user_data = user_data;
+
+ id = netlink->next_notify_id;
+
+ g_hash_table_replace(netlink->notify_lookup,
+ GUINT_TO_POINTER(id), notify_list);
+ g_hash_table_replace(notify_list, GUINT_TO_POINTER(id), notify);
+
+ if (g_hash_table_size(notify_list) == 1) {
+ if (add_membership(netlink, notify->group) == false)
+ goto remove_notify;
+ }
+
+ netlink->next_notify_id++;
+
+ return id;
+
+remove_notify:
+ g_hash_table_remove(notify_list, GUINT_TO_POINTER(id));
+ g_hash_table_remove(netlink->notify_lookup, GUINT_TO_POINTER(id));
+ g_free(notify);
+
+ return 0;
+}
+
+bool netlink_unregister(struct netlink_info *netlink, unsigned int id)
+{
+ GHashTable *notify_list;
+ struct notify *notify;
+
+ if (!netlink || id == 0)
+ return false;
+
+ if (!netlink->notify_groups || !netlink->notify_lookup)
+ return false;
+
+ notify_list = g_hash_table_lookup(netlink->notify_lookup,
+ GUINT_TO_POINTER(id));
+
+ if (!notify_list)
+ return false;
+
+ g_hash_table_remove(netlink->notify_lookup, GUINT_TO_POINTER(id));
+
+ notify = g_hash_table_lookup(notify_list, GUINT_TO_POINTER(id));
+ if (!notify)
+ return false;
+
+ g_hash_table_remove(notify_list, GUINT_TO_POINTER(id));
+
+ if (g_hash_table_size(notify_list) == 0)
+ drop_membership(netlink, notify->group);
+
+ destroy_notify(notify);
+
+ return true;
+}
+
+bool netlink_set_debug(struct netlink_info *netlink,
+ netlink_debug_func_t function,
+ void *user_data, netlink_destroy_func_t destroy)
+{
+ if (!netlink)
+ return false;
+
+ if (netlink->debug_destroy)
+ netlink->debug_destroy(netlink->debug_data);
+
+ netlink->debug_handler = function;
+ netlink->debug_destroy = destroy;
+ netlink->debug_data = user_data;
+
+ return true;
+}
diff --git a/src/shared/netlink.h b/src/shared/netlink.h
new file mode 100644
index 00000000..62bb3e01
--- /dev/null
+++ b/src/shared/netlink.h
@@ -0,0 +1,53 @@
+/*
+ *
+ * Connection Manager
+ *
+ * Copyright (C) 2011-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2013 BMW Car IT GbmH.
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation.
+ *
+ * This library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+
+typedef void (*netlink_debug_func_t) (const char *str, void *user_data);
+typedef void (*netlink_command_func_t) (unsigned int error,
+ uint16_t type, const void *data,
+ uint32_t len, void *user_data);
+typedef void (*netlink_notify_func_t) (uint16_t type, const void *data,
+ uint32_t len, void *user_data);
+typedef void (*netlink_destroy_func_t) (void *user_data);
+
+struct netlink_info;
+
+struct netlink_info *netlink_new(int protocol);
+void netlink_destroy(struct netlink_info *netlink);
+
+unsigned int netlink_send(struct netlink_info *netlink,
+ uint16_t type, uint16_t flags, const void *data,
+ uint32_t len, netlink_command_func_t function,
+ void *user_data, netlink_destroy_func_t destroy);
+bool netlink_cancel(struct netlink_info *netlink, unsigned int id);
+
+unsigned int netlink_register(struct netlink_info *netlink,
+ uint32_t group, netlink_notify_func_t function,
+ void *user_data, netlink_destroy_func_t destroy);
+bool netlink_unregister(struct netlink_info *netlink, unsigned int id);
+
+bool netlink_set_debug(struct netlink_info *netlink,
+ netlink_debug_func_t function,
+ void *user_data, netlink_destroy_func_t destroy);
diff --git a/src/shared/util.h b/src/shared/util.h
index cb81fc57..293fb3a4 100644
--- a/src/shared/util.h
+++ b/src/shared/util.h
@@ -21,6 +21,8 @@
*
*/
+#include <glib.h>
+
typedef void (*util_debug_func_t)(const char *str, void *user_data);
void util_debug(util_debug_func_t function, void *user_data,
@@ -29,3 +31,20 @@ void util_debug(util_debug_func_t function, void *user_data,
void util_hexdump(const char dir, const unsigned char *buf, size_t len,
util_debug_func_t function, void *user_data);
+
+struct cb_data {
+ void *cb;
+ void *user_data;
+ void *data;
+};
+
+static inline struct cb_data *cb_data_new(void *cb, void *user_data)
+{
+ struct cb_data *ret;
+
+ ret = g_new0(struct cb_data, 1);
+ ret->cb = cb;
+ ret->user_data = user_data;
+
+ return ret;
+}
diff --git a/src/stats.c b/src/stats.c
index 828c1ef8..df5ab4eb 100644
--- a/src/stats.c
+++ b/src/stats.c
@@ -125,7 +125,7 @@ struct stats_iter {
struct stats_record *it;
};
-GHashTable *stats_hash = NULL;
+static GHashTable *stats_hash = NULL;
static struct stats_file_header *get_hdr(struct stats_file *file)
{
@@ -219,7 +219,7 @@ static void stats_free(gpointer user_data)
{
struct stats_file *file = user_data;
- if (file == NULL)
+ if (!file)
return;
msync(file->addr, file->len, MS_SYNC);
@@ -230,12 +230,12 @@ static void stats_free(gpointer user_data)
TFR(close(file->fd));
file->fd = -1;
- if (file->history_name != NULL) {
+ if (file->history_name) {
g_free(file->history_name);
file->history_name = NULL;
}
- if (file->name != NULL) {
+ if (file->name) {
g_free(file->name);
file->name = NULL;
}
@@ -295,7 +295,7 @@ static int stats_file_remap(struct stats_file *file, size_t size)
return -errno;
}
- if (file->addr == NULL) {
+ if (!file->addr) {
/*
* Though the buffer is not shared between processes, we still
* have to take MAP_SHARED because MAP_PRIVATE does not
@@ -472,18 +472,18 @@ static struct stats_record *process_file(struct stats_iter *iter,
home = NULL;
roaming = NULL;
- if (cur == NULL)
+ if (!cur)
cur = get_next_record(iter);
next = get_next_record(iter);
- while (next != NULL) {
+ while (next) {
GDate date_cur;
GDate date_next;
- int append;
+ bool append;
- append = FALSE;
+ append = false;
- if (cur->roaming == TRUE)
+ if (cur->roaming)
roaming = cur;
else
home = cur;
@@ -503,24 +503,24 @@ static struct stats_record *process_file(struct stats_iter *iter,
day_next = g_date_get_day(&date_next);
if (day_cur == day_next && month_cur != month_next) {
- append = TRUE;
+ append = true;
} else if (day_cur < account_period_offset &&
day_next >= account_period_offset) {
- append = TRUE;
+ append = true;
}
} else {
/* day period size */
if (g_date_days_between(&date_cur, &date_next) > 0)
- append = TRUE;
+ append = true;
}
- if (append == TRUE) {
- if (home != NULL) {
+ if (append) {
+ if (home) {
append_record(temp_file, home);
home = NULL;
}
- if (roaming != NULL) {
+ if (roaming) {
append_record(temp_file, roaming);
roaming = NULL;
}
@@ -562,7 +562,7 @@ static int summarize(struct stats_file *data_file,
/* Now process history file */
cur = NULL;
- if (history_file != NULL) {
+ if (history_file) {
history_iter.file = history_file;
history_iter.begin = get_iterator_begin(history_iter.file);
history_iter.end = get_iterator_end(history_iter.file);
@@ -582,9 +582,9 @@ static int summarize(struct stats_file *data_file,
* Ensure date_file records are newer than the history_file
* record
*/
- if (cur != NULL) {
+ if (cur) {
next = get_next_record(&data_iter);
- while (next != NULL && cur->ts > next->ts)
+ while (next && cur->ts > next->ts)
next = get_next_record(&data_iter);
}
@@ -593,7 +593,7 @@ static int summarize(struct stats_file *data_file,
&date_change_step_size,
data_file->account_period_offset);
- if (cur != NULL)
+ if (cur)
append_record(temp_file, cur);
return 0;
@@ -677,9 +677,9 @@ int __connman_stats_service_register(struct connman_service *service)
DBG("service %p", service);
file = g_hash_table_lookup(stats_hash, service);
- if (file == NULL) {
+ if (!file) {
file = g_try_new0(struct stats_file, 1);
- if (file == NULL)
+ if (!file)
return -ENOMEM;
g_hash_table_insert(stats_hash, service, file);
@@ -692,7 +692,7 @@ int __connman_stats_service_register(struct connman_service *service)
/* If the dir doesn't exist, create it */
if (!g_file_test(dir, G_FILE_TEST_IS_DIR)) {
- if(mkdir(dir, MODE) < 0) {
+ if (mkdir(dir, MODE) < 0) {
if (errno != EEXIST) {
g_free(dir);
@@ -737,7 +737,7 @@ void __connman_stats_service_unregister(struct connman_service *service)
}
int __connman_stats_update(struct connman_service *service,
- connman_bool_t roaming,
+ bool roaming,
struct connman_stats_data *data)
{
struct stats_file *file;
@@ -745,7 +745,7 @@ int __connman_stats_update(struct connman_service *service,
int err;
file = g_hash_table_lookup(stats_hash, service);
- if (file == NULL)
+ if (!file)
return -EEXIST;
if (file->len < file->max_len &&
@@ -772,7 +772,7 @@ int __connman_stats_update(struct connman_service *service,
next->roaming = roaming;
memcpy(&next->data, data, sizeof(struct connman_stats_data));
- if (roaming != TRUE)
+ if (!roaming)
set_home(file, next);
else
set_roaming(file, next);
@@ -783,22 +783,22 @@ int __connman_stats_update(struct connman_service *service,
}
int __connman_stats_get(struct connman_service *service,
- connman_bool_t roaming,
+ bool roaming,
struct connman_stats_data *data)
{
struct stats_file *file;
struct stats_record *rec;
file = g_hash_table_lookup(stats_hash, service);
- if (file == NULL)
+ if (!file)
return -EEXIST;
- if (roaming != TRUE)
+ if (!roaming)
rec = file->home;
else
rec = file->roaming;
- if (rec != NULL) {
+ if (rec) {
memcpy(data, &rec->data,
sizeof(struct connman_stats_data));
}
diff --git a/src/storage.c b/src/storage.c
index 1ceafb99..7d031303 100644
--- a/src/storage.c
+++ b/src/storage.c
@@ -2,7 +2,7 @@
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2013 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -92,7 +92,7 @@ GKeyFile *__connman_storage_load_global(void)
GKeyFile *keyfile = NULL;
pathname = g_strdup_printf("%s/%s", STORAGEDIR, SETTINGS);
- if(pathname == NULL)
+ if (!pathname)
return NULL;
keyfile = storage_load(pathname);
@@ -108,7 +108,7 @@ int __connman_storage_save_global(GKeyFile *keyfile)
int ret;
pathname = g_strdup_printf("%s/%s", STORAGEDIR, SETTINGS);
- if(pathname == NULL)
+ if (!pathname)
return -ENOMEM;
ret = storage_save(keyfile, pathname);
@@ -123,7 +123,7 @@ void __connman_storage_delete_global(void)
gchar *pathname;
pathname = g_strdup_printf("%s/%s", STORAGEDIR, SETTINGS);
- if(pathname == NULL)
+ if (!pathname)
return;
storage_delete(pathname);
@@ -137,7 +137,7 @@ GKeyFile *__connman_storage_load_config(const char *ident)
GKeyFile *keyfile = NULL;
pathname = g_strdup_printf("%s/%s.config", STORAGEDIR, ident);
- if(pathname == NULL)
+ if (!pathname)
return NULL;
keyfile = storage_load(pathname);
@@ -153,7 +153,7 @@ GKeyFile *__connman_storage_load_provider_config(const char *ident)
GKeyFile *keyfile = NULL;
pathname = g_strdup_printf("%s/%s.config", VPN_STORAGEDIR, ident);
- if (pathname == NULL)
+ if (!pathname)
return NULL;
keyfile = storage_load(pathname);
@@ -169,7 +169,7 @@ GKeyFile *__connman_storage_open_service(const char *service_id)
GKeyFile *keyfile = NULL;
pathname = g_strdup_printf("%s/%s/%s", STORAGEDIR, service_id, SETTINGS);
- if(pathname == NULL)
+ if (!pathname)
return NULL;
keyfile = storage_load(pathname);
@@ -196,7 +196,7 @@ gchar **connman_storage_get_services(void)
int ret;
dir = opendir(STORAGEDIR);
- if (dir == NULL)
+ if (!dir)
return NULL;
result = g_string_new(NULL);
@@ -248,7 +248,7 @@ GKeyFile *connman_storage_load_service(const char *service_id)
GKeyFile *keyfile = NULL;
pathname = g_strdup_printf("%s/%s/%s", STORAGEDIR, service_id, SETTINGS);
- if(pathname == NULL)
+ if (!pathname)
return NULL;
keyfile = storage_load(pathname);
@@ -263,12 +263,12 @@ int __connman_storage_save_service(GKeyFile *keyfile, const char *service_id)
gchar *pathname, *dirname;
dirname = g_strdup_printf("%s/%s", STORAGEDIR, service_id);
- if(dirname == NULL)
+ if (!dirname)
return -ENOMEM;
/* If the dir doesn't exist, create it */
if (!g_file_test(dirname, G_FILE_TEST_IS_DIR)) {
- if(mkdir(dirname, MODE) < 0) {
+ if (mkdir(dirname, MODE) < 0) {
if (errno != EEXIST) {
g_free(dirname);
return -errno;
@@ -287,67 +287,67 @@ int __connman_storage_save_service(GKeyFile *keyfile, const char *service_id)
return ret;
}
-static gboolean remove_file(const char *service_id, const char *file)
+static bool remove_file(const char *service_id, const char *file)
{
gchar *pathname;
- gboolean ret = FALSE;
+ bool ret = false;
pathname = g_strdup_printf("%s/%s/%s", STORAGEDIR, service_id, file);
- if(pathname == NULL)
- return FALSE;
+ if (!pathname)
+ return false;
- if (g_file_test(pathname, G_FILE_TEST_EXISTS) == FALSE) {
- ret = TRUE;
- } else if (g_file_test(pathname, G_FILE_TEST_IS_REGULAR) == TRUE) {
+ if (!g_file_test(pathname, G_FILE_TEST_EXISTS)) {
+ ret = true;
+ } else if (g_file_test(pathname, G_FILE_TEST_IS_REGULAR)) {
unlink(pathname);
- ret = TRUE;
+ ret = true;
}
g_free(pathname);
return ret;
}
-static gboolean remove_dir(const char *service_id)
+static bool remove_dir(const char *service_id)
{
gchar *pathname;
- gboolean ret = FALSE;
+ bool ret = false;
pathname = g_strdup_printf("%s/%s", STORAGEDIR, service_id);
- if(pathname == NULL)
- return FALSE;
+ if (!pathname)
+ return false;
- if (g_file_test(pathname, G_FILE_TEST_EXISTS) == FALSE) {
- ret = TRUE;
- } else if (g_file_test(pathname, G_FILE_TEST_IS_DIR) == TRUE) {
+ if (!g_file_test(pathname, G_FILE_TEST_EXISTS)) {
+ ret = true;
+ } else if (g_file_test(pathname, G_FILE_TEST_IS_DIR)) {
rmdir(pathname);
- ret = TRUE;
+ ret = true;
}
g_free(pathname);
return ret;
}
-gboolean __connman_storage_remove_service(const char *service_id)
+bool __connman_storage_remove_service(const char *service_id)
{
- gboolean removed;
+ bool removed;
/* Remove service configuration file */
removed = remove_file(service_id, SETTINGS);
- if (removed == FALSE)
- return FALSE;
+ if (!removed)
+ return false;
/* Remove the statistics file also */
removed = remove_file(service_id, "data");
- if (removed == FALSE)
- return FALSE;
+ if (!removed)
+ return false;
removed = remove_dir(service_id);
- if (removed == FALSE)
- return FALSE;
+ if (!removed)
+ return false;
DBG("Removed service dir %s/%s", STORAGEDIR, service_id);
- return TRUE;
+ return true;
}
GKeyFile *__connman_storage_load_provider(const char *identifier)
@@ -357,7 +357,7 @@ GKeyFile *__connman_storage_load_provider(const char *identifier)
pathname = g_strdup_printf("%s/%s_%s/%s", STORAGEDIR, "provider",
identifier, SETTINGS);
- if (pathname == NULL)
+ if (!pathname)
return NULL;
keyfile = storage_load(pathname);
@@ -372,10 +372,10 @@ void __connman_storage_save_provider(GKeyFile *keyfile, const char *identifier)
dirname = g_strdup_printf("%s/%s_%s", STORAGEDIR,
"provider", identifier);
- if (dirname == NULL)
+ if (!dirname)
return;
- if (g_file_test(dirname, G_FILE_TEST_IS_DIR) == FALSE &&
+ if (!g_file_test(dirname, G_FILE_TEST_IS_DIR) &&
mkdir(dirname, MODE) < 0) {
g_free(dirname);
return;
@@ -388,39 +388,39 @@ void __connman_storage_save_provider(GKeyFile *keyfile, const char *identifier)
g_free(pathname);
}
-static gboolean remove_all(const char *id)
+static bool remove_all(const char *id)
{
- gboolean removed;
+ bool removed;
remove_file(id, SETTINGS);
remove_file(id, "data");
removed = remove_dir(id);
- if (removed == FALSE)
- return FALSE;
+ if (!removed)
+ return false;
- return TRUE;
+ return true;
}
-gboolean __connman_storage_remove_provider(const char *identifier)
+bool __connman_storage_remove_provider(const char *identifier)
{
- gboolean removed;
+ bool removed;
gchar *id;
id = g_strdup_printf("%s_%s", "provider", identifier);
- if (id == NULL)
- return FALSE;
+ if (!id)
+ return false;
- if (remove_all(id) == TRUE)
+ if (remove_all(id))
DBG("Removed provider dir %s/%s", STORAGEDIR, id);
g_free(id);
id = g_strdup_printf("%s_%s", "vpn", identifier);
- if (id == NULL)
- return FALSE;
+ if (!id)
+ return false;
- if ((removed = remove_all(id)) == TRUE)
+ if ((removed = remove_all(id)))
DBG("Removed vpn dir %s/%s", STORAGEDIR, id);
g_free(id);
@@ -441,7 +441,7 @@ gchar **__connman_storage_get_providers(void)
GSList *iter;
dir = opendir(STORAGEDIR);
- if (dir == NULL)
+ if (!dir)
return NULL;
while ((d = readdir(dir))) {
@@ -465,8 +465,8 @@ gchar **__connman_storage_get_providers(void)
closedir(dir);
providers = g_try_new0(char *, num + 1);
- for (iter = list; iter != NULL; iter = g_slist_next(iter)) {
- if (providers != NULL)
+ for (iter = list; iter; iter = g_slist_next(iter)) {
+ if (providers)
providers[i] = iter->data;
else
g_free(iter->data);
diff --git a/src/task.c b/src/task.c
index 60e336ac..8b9e1d93 100644
--- a/src/task.c
+++ b/src/task.c
@@ -102,7 +102,7 @@ struct connman_task *connman_task_create(const char *program)
DBG("");
task = g_try_new0(struct connman_task, 1);
- if (task == NULL)
+ if (!task)
return NULL;
counter = __sync_fetch_and_add(&task_counter, 1);
@@ -167,7 +167,7 @@ int connman_task_add_argument(struct connman_task *task,
DBG("task %p arg %s", task, name);
- if (name == NULL)
+ if (!name)
return -EINVAL;
str = g_strdup(name);
@@ -175,7 +175,7 @@ int connman_task_add_argument(struct connman_task *task,
va_start(ap, format);
- if (format != NULL) {
+ if (format) {
str = g_strdup_vprintf(format, ap);
g_ptr_array_add(task->argv, str);
}
@@ -202,7 +202,7 @@ int connman_task_add_variable(struct connman_task *task,
DBG("task %p key %s", task, key);
- if (key == NULL)
+ if (!key)
return -EINVAL;
va_start(ap, format);
@@ -234,7 +234,7 @@ int connman_task_set_notify(struct connman_task *task, const char *member,
DBG("task %p", task);
notify = g_try_new0(struct notify_data, 1);
- if (notify == NULL)
+ if (!notify)
return -ENOMEM;
notify->func = function;
@@ -293,7 +293,7 @@ int connman_task_run(struct connman_task *task,
int *stdin_fd, int *stdout_fd, int *stderr_fd)
{
GSpawnFlags flags = G_SPAWN_DO_NOT_REAP_CHILD;
- gboolean result;
+ bool result;
char **argv, **envp;
DBG("task %p", task);
@@ -301,20 +301,20 @@ int connman_task_run(struct connman_task *task,
if (task->pid > 0)
return -EALREADY;
- if (stdout_fd == NULL)
+ if (!stdout_fd)
flags |= G_SPAWN_STDOUT_TO_DEV_NULL;
- if (stderr_fd == NULL)
+ if (!stderr_fd)
flags |= G_SPAWN_STDERR_TO_DEV_NULL;
task->exit_func = function;
task->exit_data = user_data;
- if (g_ptr_array_index(task->argv, task->argv->len - 1) != NULL)
+ if (g_ptr_array_index(task->argv, task->argv->len - 1))
g_ptr_array_add(task->argv, NULL);
- if (task->envp->len == 0 || g_ptr_array_index(task->envp,
- task->envp->len - 1) != NULL) {
+ if (task->envp->len == 0 ||
+ g_ptr_array_index(task->envp, task->envp->len - 1)) {
if (g_hash_table_size(task->notify) > 0) {
const char *busname;
char *str;
@@ -340,7 +340,7 @@ int connman_task_run(struct connman_task *task,
result = g_spawn_async_with_pipes(NULL, argv, envp, flags,
task_setup, task, &task->pid,
stdin_fd, stdout_fd, stderr_fd, NULL);
- if (result == FALSE) {
+ if (!result) {
connman_error("Failed to spawn %s", argv[0]);
return -EIO;
}
@@ -419,39 +419,38 @@ static DBusHandlerResult task_filter(DBusConnection *conn,
if (dbus_message_get_type(message) != DBUS_MESSAGE_TYPE_METHOD_CALL)
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
- if (dbus_message_has_interface(message,
- CONNMAN_TASK_INTERFACE) == FALSE)
+ if (!dbus_message_has_interface(message, CONNMAN_TASK_INTERFACE))
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
path = dbus_message_get_path(message);
- if (path == NULL)
+ if (!path)
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
task = g_hash_table_lookup(task_hash, path);
- if (task == NULL)
+ if (!task)
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
member = dbus_message_get_member(message);
- if (member == NULL)
+ if (!member)
goto send_reply;
notify = g_hash_table_lookup(task->notify, member);
- if (notify == NULL)
+ if (!notify)
goto send_reply;
if (notify->func)
reply = notify->func(task, message, notify->data);
send_reply:
- if (dbus_message_get_no_reply(message) == FALSE &&
- reply == NULL) {
+ if (!dbus_message_get_no_reply(message) &&
+ !reply) {
reply = dbus_message_new_method_return(message);
- if (reply == NULL)
+ if (!reply)
return DBUS_HANDLER_RESULT_NEED_MEMORY;
}
- if (reply != NULL) {
+ if (reply) {
dbus_connection_send(conn, reply, NULL);
dbus_message_unref(reply);
diff --git a/src/technology.c b/src/technology.c
index 632f7164..d80d9e6d 100644
--- a/src/technology.c
+++ b/src/technology.c
@@ -2,7 +2,7 @@
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2013 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -41,13 +41,13 @@ static GSList *technology_list = NULL;
static GSList *techless_device_list = NULL;
static GHashTable *rfkill_list;
-static connman_bool_t global_offlinemode;
+static bool global_offlinemode;
struct connman_rfkill {
unsigned int index;
enum connman_service_type type;
- connman_bool_t softblock;
- connman_bool_t hardblock;
+ bool softblock;
+ bool hardblock;
};
struct connman_technology {
@@ -55,19 +55,19 @@ struct connman_technology {
enum connman_service_type type;
char *path;
GSList *device_list;
- connman_bool_t enabled;
+ bool enabled;
char *regdom;
- connman_bool_t connected;
+ bool connected;
- connman_bool_t tethering;
- connman_bool_t tethering_persistent; /* Tells the save status, needed
+ bool tethering;
+ bool tethering_persistent; /* Tells the save status, needed
* as offline mode might set
* tethering OFF.
*/
char *tethering_ident;
char *tethering_passphrase;
- connman_bool_t enable_persistent; /* Save the tech state */
+ bool enable_persistent; /* Save the tech state */
GSList *driver_list;
@@ -76,10 +76,10 @@ struct connman_technology {
GSList *scan_pending;
- connman_bool_t rfkill_driven;
- connman_bool_t softblocked;
- connman_bool_t hardblocked;
- connman_bool_t dbus_registered;
+ bool rfkill_driven;
+ bool softblocked;
+ bool hardblocked;
+ bool dbus_registered;
};
static GSList *driver_list = NULL;
@@ -103,7 +103,7 @@ static void rfkill_check(gpointer key, gpointer value, gpointer user_data)
rfkill->softblock, rfkill->hardblock);
}
-connman_bool_t
+bool
connman_technology_is_tethering_allowed(enum connman_service_type type)
{
static char *allowed_default[] = { "wifi", "bluetooth", "gadget",
@@ -112,100 +112,19 @@ connman_technology_is_tethering_allowed(enum connman_service_type type)
char **allowed;
int i;
- if (type_str == NULL)
- return FALSE;
+ if (!type_str)
+ return false;
allowed = connman_setting_get_string_list("TetheringTechnologies");
- if (allowed == NULL)
+ if (!allowed)
allowed = allowed_default;
- for (i = 0; allowed[i] != NULL; i++) {
+ for (i = 0; allowed[i]; i++) {
if (g_strcmp0(allowed[i], type_str) == 0)
- return TRUE;
+ return true;
}
- return FALSE;
-}
-
-/**
- * connman_technology_driver_register:
- * @driver: Technology driver definition
- *
- * Register a new technology driver
- *
- * Returns: %0 on success
- */
-int connman_technology_driver_register(struct connman_technology_driver *driver)
-{
- GSList *list;
- struct connman_device *device;
- enum connman_service_type type;
-
- DBG("Registering %s driver", driver->name);
-
- driver_list = g_slist_insert_sorted(driver_list, driver,
- compare_priority);
-
- /*
- * Check for technology less devices if this driver
- * can service any of them.
- */
- for (list = techless_device_list; list != NULL; list = list->next) {
- device = list->data;
-
- type = __connman_device_get_service_type(device);
- if (type != driver->type)
- continue;
-
- techless_device_list = g_slist_remove(techless_device_list,
- device);
-
- __connman_technology_add_device(device);
- }
-
- /* Check for orphaned rfkill switches. */
- g_hash_table_foreach(rfkill_list, rfkill_check,
- GINT_TO_POINTER(driver->type));
-
- return 0;
-}
-
-/**
- * connman_technology_driver_unregister:
- * @driver: Technology driver definition
- *
- * Remove a previously registered technology driver
- */
-void connman_technology_driver_unregister(struct connman_technology_driver *driver)
-{
- GSList *list, *tech_drivers;
- struct connman_technology *technology;
- struct connman_technology_driver *current;
-
- DBG("Unregistering driver %p name %s", driver, driver->name);
-
- for (list = technology_list; list; list = list->next) {
- technology = list->data;
-
- for (tech_drivers = technology->driver_list;
- tech_drivers != NULL;
- tech_drivers = g_slist_next(tech_drivers)) {
-
- current = tech_drivers->data;
- if (driver != current)
- continue;
-
- if (driver->remove != NULL)
- driver->remove(technology);
-
- technology->driver_list =
- g_slist_remove(technology->driver_list, driver);
-
- break;
- }
- }
-
- driver_list = g_slist_remove(driver_list, driver);
+ return false;
}
static const char *get_name(enum connman_service_type type)
@@ -215,8 +134,9 @@ static const char *get_name(enum connman_service_type type)
case CONNMAN_SERVICE_TYPE_SYSTEM:
case CONNMAN_SERVICE_TYPE_GPS:
case CONNMAN_SERVICE_TYPE_VPN:
- case CONNMAN_SERVICE_TYPE_GADGET:
break;
+ case CONNMAN_SERVICE_TYPE_GADGET:
+ return "Gadget";
case CONNMAN_SERVICE_TYPE_ETHERNET:
return "Wired";
case CONNMAN_SERVICE_TYPE_WIFI:
@@ -225,6 +145,8 @@ static const char *get_name(enum connman_service_type type)
return "Bluetooth";
case CONNMAN_SERVICE_TYPE_CELLULAR:
return "Cellular";
+ case CONNMAN_SERVICE_TYPE_P2P:
+ return "P2P";
}
return NULL;
@@ -234,15 +156,19 @@ static void technology_save(struct connman_technology *technology)
{
GKeyFile *keyfile;
gchar *identifier;
+ const char *name = get_name(technology->type);
- DBG("technology %p", technology);
+ DBG("technology %p type %d name %s", technology, technology->type,
+ name);
+ if (!name)
+ return;
keyfile = __connman_storage_load_global();
- if (keyfile == NULL)
+ if (!keyfile)
keyfile = g_key_file_new();
- identifier = g_strdup_printf("%s", get_name(technology->type));
- if (identifier == NULL)
+ identifier = g_strdup_printf("%s", name);
+ if (!identifier)
goto done;
g_key_file_set_boolean(keyfile, identifier, "Enable",
@@ -251,12 +177,12 @@ static void technology_save(struct connman_technology *technology)
g_key_file_set_boolean(keyfile, identifier, "Tethering",
technology->tethering_persistent);
- if (technology->tethering_ident != NULL)
+ if (technology->tethering_ident)
g_key_file_set_string(keyfile, identifier,
"Tethering.Identifier",
technology->tethering_ident);
- if (technology->tethering_passphrase != NULL)
+ if (technology->tethering_passphrase)
g_key_file_set_string(keyfile, identifier,
"Tethering.Passphrase",
technology->tethering_passphrase);
@@ -273,7 +199,7 @@ done:
static void tethering_changed(struct connman_technology *technology)
{
- connman_bool_t tethering = technology->tethering;
+ dbus_bool_t tethering = technology->tethering;
connman_dbus_property_changed_basic(technology->path,
CONNMAN_TECHNOLOGY_INTERFACE, "Tethering",
@@ -283,10 +209,8 @@ static void tethering_changed(struct connman_technology *technology)
}
void connman_technology_tethering_notify(struct connman_technology *technology,
- connman_bool_t enabled)
+ bool enabled)
{
- GSList *list;
-
DBG("technology %p enabled %u", technology, enabled);
if (technology->tethering == enabled)
@@ -296,21 +220,14 @@ void connman_technology_tethering_notify(struct connman_technology *technology,
tethering_changed(technology);
- if (enabled == TRUE)
+ if (enabled)
__connman_tethering_set_enabled();
- else {
- for (list = technology_list; list; list = list->next) {
- struct connman_technology *other_tech = list->data;
- if (other_tech->tethering == TRUE)
- break;
- }
- if (list == NULL)
- __connman_tethering_set_disabled();
- }
+ else
+ __connman_tethering_set_disabled();
}
static int set_tethering(struct connman_technology *technology,
- connman_bool_t enabled)
+ bool enabled)
{
int result = -EOPNOTSUPP;
int err;
@@ -321,22 +238,22 @@ static int set_tethering(struct connman_technology *technology,
passphrase = technology->tethering_passphrase;
__sync_synchronize();
- if (technology->enabled == FALSE)
+ if (!technology->enabled)
return -EACCES;
bridge = __connman_tethering_get_bridge();
- if (bridge == NULL)
+ if (!bridge)
return -EOPNOTSUPP;
if (technology->type == CONNMAN_SERVICE_TYPE_WIFI &&
- (ident == NULL || passphrase == NULL))
+ (!ident || !passphrase))
return -EINVAL;
- for (tech_drivers = technology->driver_list; tech_drivers != NULL;
+ for (tech_drivers = technology->driver_list; tech_drivers;
tech_drivers = g_slist_next(tech_drivers)) {
struct connman_technology_driver *driver = tech_drivers->data;
- if (driver == NULL || driver->set_tethering == NULL)
+ if (!driver || !driver->set_tethering)
continue;
err = driver->set_tethering(technology, ident, passphrase,
@@ -359,7 +276,7 @@ void connman_technology_regdom_notify(struct connman_technology *technology,
{
DBG("");
- if (alpha2 == NULL)
+ if (!alpha2)
connman_error("Failed to set regulatory domain");
else
DBG("Regulatory domain set to %s", alpha2);
@@ -393,13 +310,13 @@ int connman_technology_set_regdom(const char *alpha2)
if (set_regdom_by_device(technology, alpha2) != 0) {
for (tech_drivers = technology->driver_list;
- tech_drivers != NULL;
+ tech_drivers;
tech_drivers = g_slist_next(tech_drivers)) {
struct connman_technology_driver *driver =
tech_drivers->data;
- if (driver->set_regdom != NULL)
+ if (driver->set_regdom)
driver->set_regdom(technology, alpha2);
}
}
@@ -424,27 +341,27 @@ static struct connman_technology *technology_find(enum connman_service_type type
return NULL;
}
-connman_bool_t connman_technology_get_wifi_tethering(const char **ssid,
+bool connman_technology_get_wifi_tethering(const char **ssid,
const char **psk)
{
struct connman_technology *technology;
- if (ssid == NULL || psk == NULL)
- return FALSE;
+ if (!ssid || !psk)
+ return false;
*ssid = *psk = NULL;
technology = technology_find(CONNMAN_SERVICE_TYPE_WIFI);
- if (technology == NULL)
- return FALSE;
+ if (!technology)
+ return false;
- if (technology->tethering == FALSE)
- return FALSE;
+ if (!technology->tethering)
+ return false;
*ssid = technology->tethering_ident;
*psk = technology->tethering_passphrase;
- return TRUE;
+ return true;
}
static void free_rfkill(gpointer data)
@@ -459,48 +376,48 @@ static void technology_load(struct connman_technology *technology)
GKeyFile *keyfile;
gchar *identifier;
GError *error = NULL;
- connman_bool_t enable, need_saving = FALSE;
+ bool enable, need_saving = false;
DBG("technology %p", technology);
keyfile = __connman_storage_load_global();
/* Fallback on disabling technology if file not found. */
- if (keyfile == NULL) {
+ if (!keyfile) {
if (technology->type == CONNMAN_SERVICE_TYPE_ETHERNET)
/* We enable ethernet by default */
- technology->enable_persistent = TRUE;
+ technology->enable_persistent = true;
else
- technology->enable_persistent = FALSE;
+ technology->enable_persistent = false;
return;
}
identifier = g_strdup_printf("%s", get_name(technology->type));
- if (identifier == NULL)
+ if (!identifier)
goto done;
enable = g_key_file_get_boolean(keyfile, identifier, "Enable", &error);
- if (error == NULL)
+ if (!error)
technology->enable_persistent = enable;
else {
if (technology->type == CONNMAN_SERVICE_TYPE_ETHERNET)
- technology->enable_persistent = TRUE;
+ technology->enable_persistent = true;
else
- technology->enable_persistent = FALSE;
+ technology->enable_persistent = false;
- need_saving = TRUE;
+ need_saving = true;
g_clear_error(&error);
}
enable = g_key_file_get_boolean(keyfile, identifier,
"Tethering", &error);
- if (error == NULL)
+ if (!error)
technology->tethering_persistent = enable;
else {
- need_saving = TRUE;
+ need_saving = true;
g_clear_error(&error);
}
- if (need_saving == TRUE)
+ if (need_saving)
technology_save(technology);
technology->tethering_ident = g_key_file_get_string(keyfile,
@@ -516,17 +433,17 @@ done:
return;
}
-connman_bool_t __connman_technology_get_offlinemode(void)
+bool __connman_technology_get_offlinemode(void)
{
return global_offlinemode;
}
-static void connman_technology_save_offlinemode()
+static void connman_technology_save_offlinemode(void)
{
GKeyFile *keyfile;
keyfile = __connman_storage_load_global();
- if (keyfile == NULL)
+ if (!keyfile)
keyfile = g_key_file_new();
g_key_file_set_boolean(keyfile, "global",
@@ -539,21 +456,21 @@ static void connman_technology_save_offlinemode()
return;
}
-static connman_bool_t connman_technology_load_offlinemode()
+static bool connman_technology_load_offlinemode(void)
{
GKeyFile *keyfile;
GError *error = NULL;
- connman_bool_t offlinemode;
+ bool offlinemode;
/* If there is a error, we enable offlinemode */
keyfile = __connman_storage_load_global();
- if (keyfile == NULL)
- return FALSE;
+ if (!keyfile)
+ return false;
offlinemode = g_key_file_get_boolean(keyfile, "global",
"OfflineMode", &error);
- if (error != NULL) {
- offlinemode = FALSE;
+ if (error) {
+ offlinemode = false;
g_clear_error(&error);
}
@@ -566,39 +483,43 @@ static void append_properties(DBusMessageIter *iter,
struct connman_technology *technology)
{
DBusMessageIter dict;
+ dbus_bool_t val;
const char *str;
connman_dbus_dict_open(iter, &dict);
str = get_name(technology->type);
- if (str != NULL)
+ if (str)
connman_dbus_dict_append_basic(&dict, "Name",
DBUS_TYPE_STRING, &str);
str = __connman_service_type2string(technology->type);
- if (str != NULL)
+ if (str)
connman_dbus_dict_append_basic(&dict, "Type",
DBUS_TYPE_STRING, &str);
__sync_synchronize();
+ val = technology->enabled;
connman_dbus_dict_append_basic(&dict, "Powered",
DBUS_TYPE_BOOLEAN,
- &technology->enabled);
+ &val);
+ val = technology->connected;
connman_dbus_dict_append_basic(&dict, "Connected",
DBUS_TYPE_BOOLEAN,
- &technology->connected);
+ &val);
+ val = technology->tethering;
connman_dbus_dict_append_basic(&dict, "Tethering",
DBUS_TYPE_BOOLEAN,
- &technology->tethering);
+ &val);
- if (technology->tethering_ident != NULL)
+ if (technology->tethering_ident)
connman_dbus_dict_append_basic(&dict, "TetheringIdentifier",
DBUS_TYPE_STRING,
&technology->tethering_ident);
- if (technology->tethering_passphrase != NULL)
+ if (technology->tethering_passphrase)
connman_dbus_dict_append_basic(&dict, "TetheringPassphrase",
DBUS_TYPE_STRING,
&technology->tethering_passphrase);
@@ -613,7 +534,7 @@ static void technology_added_signal(struct connman_technology *technology)
signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH,
CONNMAN_MANAGER_INTERFACE, "TechnologyAdded");
- if (signal == NULL)
+ if (!signal)
return;
dbus_message_iter_init_append(signal, &iter);
@@ -641,7 +562,7 @@ static DBusMessage *get_properties(DBusConnection *conn,
DBusMessageIter iter;
reply = dbus_message_new_method_return(message);
- if (reply == NULL)
+ if (!reply)
return NULL;
dbus_message_iter_init_append(reply, &iter);
@@ -658,9 +579,9 @@ void __connman_technology_list_struct(DBusMessageIter *array)
for (list = technology_list; list; list = list->next) {
struct connman_technology *technology = list->data;
- if (technology->path == NULL ||
- (technology->rfkill_driven == TRUE &&
- technology->hardblocked == TRUE))
+ if (!technology->path ||
+ (technology->rfkill_driven &&
+ technology->hardblocked))
continue;
dbus_message_iter_open_container(array, DBUS_TYPE_STRUCT,
@@ -678,9 +599,9 @@ static gboolean technology_pending_reply(gpointer user_data)
DBusMessage *reply;
/* Power request timedout, send ETIMEDOUT. */
- if (technology->pending_reply != NULL) {
+ if (technology->pending_reply) {
reply = __connman_error_failed(technology->pending_reply, ETIMEDOUT);
- if (reply != NULL)
+ if (reply)
g_dbus_send_message(connection, reply);
dbus_message_unref(technology->pending_reply);
@@ -692,15 +613,18 @@ static gboolean technology_pending_reply(gpointer user_data)
}
static int technology_affect_devices(struct connman_technology *technology,
- connman_bool_t enable_device)
+ bool enable_device)
{
GSList *list;
- int err = 0;
+ int err = -ENXIO;
+
+ if (technology->type == CONNMAN_SERVICE_TYPE_P2P)
+ return 0;
for (list = technology->device_list; list; list = list->next) {
struct connman_device *device = list->data;
- if (enable_device == TRUE)
+ if (enable_device)
err = __connman_device_enable(device);
else
err = __connman_device_disable(device);
@@ -709,6 +633,68 @@ static int technology_affect_devices(struct connman_technology *technology,
return err;
}
+static void powered_changed(struct connman_technology *technology)
+{
+ dbus_bool_t enabled;
+
+ if (!technology->dbus_registered)
+ return;
+
+ if (technology->pending_reply) {
+ g_dbus_send_reply(connection,
+ technology->pending_reply, DBUS_TYPE_INVALID);
+ dbus_message_unref(technology->pending_reply);
+ technology->pending_reply = NULL;
+
+ g_source_remove(technology->pending_timeout);
+ technology->pending_timeout = 0;
+ }
+
+ __sync_synchronize();
+ enabled = technology->enabled;
+ connman_dbus_property_changed_basic(technology->path,
+ CONNMAN_TECHNOLOGY_INTERFACE, "Powered",
+ DBUS_TYPE_BOOLEAN, &enabled);
+}
+
+static void enable_tethering(struct connman_technology *technology)
+{
+ int ret;
+
+ if (!connman_setting_get_bool("PersistentTetheringMode"))
+ return;
+
+ ret = set_tethering(technology, true);
+ if (ret < 0 && ret != -EALREADY)
+ DBG("Cannot enable tethering yet for %s (%d/%s)",
+ get_name(technology->type),
+ -ret, strerror(-ret));
+}
+
+static int technology_enabled(struct connman_technology *technology)
+{
+ __sync_synchronize();
+ if (technology->enabled)
+ return -EALREADY;
+
+ technology->enabled = true;
+
+ if (technology->type == CONNMAN_SERVICE_TYPE_WIFI) {
+ struct connman_technology *p2p;
+
+ p2p = technology_find(CONNMAN_SERVICE_TYPE_P2P);
+ if (p2p && !p2p->enabled && p2p->enable_persistent)
+ technology_enabled(p2p);
+ }
+
+ if (technology->tethering_persistent)
+ enable_tethering(technology);
+
+ powered_changed(technology);
+
+ return 0;
+}
+
static int technology_enable(struct connman_technology *technology)
{
int err = 0;
@@ -717,27 +703,50 @@ static int technology_enable(struct connman_technology *technology)
DBG("technology %p enable", technology);
__sync_synchronize();
- if (technology->enabled == TRUE)
+
+ if (technology->type == CONNMAN_SERVICE_TYPE_P2P) {
+ struct connman_technology *wifi;
+
+ wifi = technology_find(CONNMAN_SERVICE_TYPE_WIFI);
+ if (wifi && wifi->enabled)
+ return technology_enabled(technology);
+ return 0;
+ }
+
+ if (technology->enabled)
return -EALREADY;
- if (technology->pending_reply != NULL)
+ if (technology->pending_reply)
return -EBUSY;
- if (connman_setting_get_bool("PersistentTetheringMode") == TRUE &&
- technology->tethering == TRUE)
- set_tethering(technology, TRUE);
+ if (connman_setting_get_bool("PersistentTetheringMode") &&
+ technology->tethering)
+ set_tethering(technology, true);
- if (technology->rfkill_driven == TRUE)
- err = __connman_rfkill_block(technology->type, FALSE);
+ if (technology->rfkill_driven)
+ err = __connman_rfkill_block(technology->type, false);
- err_dev = technology_affect_devices(technology, TRUE);
+ err_dev = technology_affect_devices(technology, true);
- if (technology->rfkill_driven == FALSE)
+ if (!technology->rfkill_driven)
err = err_dev;
return err;
}
+static int technology_disabled(struct connman_technology *technology)
+{
+ __sync_synchronize();
+ if (!technology->enabled)
+ return -EALREADY;
+
+ technology->enabled = false;
+
+ powered_changed(technology);
+
+ return 0;
+}
+
static int technology_disable(struct connman_technology *technology)
{
int err;
@@ -745,35 +754,49 @@ static int technology_disable(struct connman_technology *technology)
DBG("technology %p disable", technology);
__sync_synchronize();
- if (technology->enabled == FALSE)
+
+ if (technology->type == CONNMAN_SERVICE_TYPE_P2P) {
+ technology->enable_persistent = false;
+ return technology_disabled(technology);
+ } else if (technology->type == CONNMAN_SERVICE_TYPE_WIFI) {
+ struct connman_technology *p2p;
+
+ p2p = technology_find(CONNMAN_SERVICE_TYPE_P2P);
+ if (p2p && p2p->enabled) {
+ p2p->enable_persistent = true;
+ technology_disabled(p2p);
+ }
+ }
+
+ if (!technology->enabled)
return -EALREADY;
- if (technology->pending_reply != NULL)
+ if (technology->pending_reply)
return -EBUSY;
- if (technology->tethering == TRUE)
- set_tethering(technology, FALSE);
+ if (technology->tethering)
+ set_tethering(technology, false);
- err = technology_affect_devices(technology, FALSE);
+ err = technology_affect_devices(technology, false);
- if (technology->rfkill_driven == TRUE)
- err = __connman_rfkill_block(technology->type, TRUE);
+ if (technology->rfkill_driven)
+ err = __connman_rfkill_block(technology->type, true);
return err;
}
static DBusMessage *set_powered(struct connman_technology *technology,
- DBusMessage *msg, connman_bool_t powered)
+ DBusMessage *msg, bool powered)
{
DBusMessage *reply = NULL;
int err = 0;
- if (technology->rfkill_driven && technology->hardblocked == TRUE) {
+ if (technology->rfkill_driven && technology->hardblocked) {
err = -EACCES;
goto make_reply;
}
- if (powered == TRUE)
+ if (powered)
err = technology_enable(technology);
else
err = technology_disable(technology);
@@ -789,7 +812,7 @@ make_reply:
technology->pending_timeout = g_timeout_add_seconds(10,
technology_pending_reply, technology);
} else if (err == -EALREADY) {
- if (powered == TRUE)
+ if (powered)
reply = __connman_error_already_enabled(msg);
else
reply = __connman_error_already_disabled(msg);
@@ -811,7 +834,7 @@ static DBusMessage *set_property(DBusConnection *conn,
DBG("conn %p", conn);
- if (dbus_message_iter_init(msg, &iter) == FALSE)
+ if (!dbus_message_iter_init(msg, &iter))
return __connman_error_invalid_arguments(msg);
if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
@@ -829,15 +852,14 @@ static DBusMessage *set_property(DBusConnection *conn,
DBG("property %s", name);
- if (g_str_equal(name, "Tethering") == TRUE) {
+ if (g_str_equal(name, "Tethering")) {
+ dbus_bool_t tethering;
int err;
- connman_bool_t tethering;
if (type != DBUS_TYPE_BOOLEAN)
return __connman_error_invalid_arguments(msg);
- if (connman_technology_is_tethering_allowed(technology->type)
- == FALSE) {
+ if (!connman_technology_is_tethering_allowed(technology->type)) {
DBG("%s tethering not allowed by config file",
__connman_service_type2string(technology->type));
return __connman_error_not_supported(msg);
@@ -846,7 +868,7 @@ static DBusMessage *set_property(DBusConnection *conn,
dbus_message_iter_get_basic(&value, &tethering);
if (technology->tethering == tethering) {
- if (tethering == FALSE)
+ if (!tethering)
return __connman_error_already_disabled(msg);
else
return __connman_error_already_enabled(msg);
@@ -860,7 +882,7 @@ static DBusMessage *set_property(DBusConnection *conn,
technology_save(technology);
- } else if (g_str_equal(name, "TetheringIdentifier") == TRUE) {
+ } else if (g_str_equal(name, "TetheringIdentifier")) {
const char *str;
dbus_message_iter_get_basic(&value, &str);
@@ -882,7 +904,7 @@ static DBusMessage *set_property(DBusConnection *conn,
DBUS_TYPE_STRING,
&technology->tethering_ident);
}
- } else if (g_str_equal(name, "TetheringPassphrase") == TRUE) {
+ } else if (g_str_equal(name, "TetheringPassphrase")) {
const char *str;
dbus_message_iter_get_basic(&value, &str);
@@ -904,8 +926,8 @@ static DBusMessage *set_property(DBusConnection *conn,
DBUS_TYPE_STRING,
&technology->tethering_passphrase);
}
- } else if (g_str_equal(name, "Powered") == TRUE) {
- connman_bool_t enable;
+ } else if (g_str_equal(name, "Powered")) {
+ dbus_bool_t enable;
if (type != DBUS_TYPE_BOOLEAN)
return __connman_error_invalid_arguments(msg);
@@ -925,7 +947,7 @@ static void reply_scan_pending(struct connman_technology *technology, int err)
DBG("technology %p err %d", technology, err);
- while (technology->scan_pending != NULL) {
+ while (technology->scan_pending) {
DBusMessage *msg = technology->scan_pending->data;
DBG("reply to %s", dbus_message_get_sender(msg));
@@ -948,22 +970,21 @@ void __connman_technology_scan_started(struct connman_device *device)
DBG("device %p", device);
}
-void __connman_technology_scan_stopped(struct connman_device *device)
+void __connman_technology_scan_stopped(struct connman_device *device,
+ enum connman_service_type type)
{
int count = 0;
struct connman_technology *technology;
- enum connman_service_type type;
GSList *list;
- type = __connman_device_get_service_type(device);
technology = technology_find(type);
DBG("technology %p device %p", technology, device);
- if (technology == NULL)
+ if (!technology)
return;
- for (list = technology->device_list; list != NULL; list = list->next) {
+ for (list = technology->device_list; list; list = list->next) {
struct connman_device *other_device = list->data;
if (device == other_device)
@@ -972,7 +993,7 @@ void __connman_technology_scan_stopped(struct connman_device *device)
if (__connman_device_get_service_type(other_device) != type)
continue;
- if (connman_device_get_scanning(other_device) == TRUE)
+ if (connman_device_get_scanning(other_device))
count += 1;
}
@@ -983,7 +1004,7 @@ void __connman_technology_scan_stopped(struct connman_device *device)
void __connman_technology_notify_regdom_by_device(struct connman_device *device,
int result, const char *alpha2)
{
- connman_bool_t regdom_set = FALSE;
+ bool regdom_set = false;
struct connman_technology *technology;
enum connman_service_type type;
GSList *tech_drivers;
@@ -991,25 +1012,25 @@ void __connman_technology_notify_regdom_by_device(struct connman_device *device,
type = __connman_device_get_service_type(device);
technology = technology_find(type);
- if (technology == NULL)
+ if (!technology)
return;
if (result < 0) {
for (tech_drivers = technology->driver_list;
- tech_drivers != NULL;
+ tech_drivers;
tech_drivers = g_slist_next(tech_drivers)) {
struct connman_technology_driver *driver =
tech_drivers->data;
- if (driver->set_regdom != NULL) {
+ if (driver->set_regdom) {
driver->set_regdom(technology, alpha2);
- regdom_set = TRUE;
+ regdom_set = true;
}
}
- if (regdom_set == FALSE)
+ if (!regdom_set)
alpha2 = NULL;
}
@@ -1021,7 +1042,7 @@ static DBusMessage *scan(DBusConnection *conn, DBusMessage *msg, void *data)
struct connman_technology *technology = data;
int err;
- DBG ("technology %p request from %s", technology,
+ DBG("technology %p request from %s", technology,
dbus_message_get_sender(msg));
dbus_message_ref(msg);
@@ -1052,25 +1073,72 @@ static const GDBusSignalTable technology_signals[] = {
{ },
};
-static gboolean technology_dbus_register(struct connman_technology *technology)
+static bool technology_dbus_register(struct connman_technology *technology)
{
- if (technology->dbus_registered == TRUE ||
- (technology->rfkill_driven == TRUE &&
- technology->hardblocked == TRUE))
- return TRUE;
-
- if (g_dbus_register_interface(connection, technology->path,
- CONNMAN_TECHNOLOGY_INTERFACE,
- technology_methods, technology_signals,
- NULL, technology, NULL) == FALSE) {
+ if (technology->dbus_registered ||
+ (technology->rfkill_driven &&
+ technology->hardblocked))
+ return true;
+
+ if (!g_dbus_register_interface(connection, technology->path,
+ CONNMAN_TECHNOLOGY_INTERFACE,
+ technology_methods, technology_signals,
+ NULL, technology, NULL)) {
connman_error("Failed to register %s", technology->path);
- return FALSE;
+ return false;
}
technology_added_signal(technology);
- technology->dbus_registered = TRUE;
+ technology->dbus_registered = true;
+
+ return true;
+}
+
+static void technology_dbus_unregister(struct connman_technology *technology)
+{
+ if (!technology->dbus_registered)
+ return;
+
+ technology_removed_signal(technology);
+ g_dbus_unregister_interface(connection, technology->path,
+ CONNMAN_TECHNOLOGY_INTERFACE);
- return TRUE;
+ technology->dbus_registered = false;
+}
+
+static void technology_put(struct connman_technology *technology)
+{
+ DBG("technology %p", technology);
+
+ if (__sync_sub_and_fetch(&technology->refcount, 1) > 0)
+ return;
+
+ reply_scan_pending(technology, -EINTR);
+
+ while (technology->driver_list) {
+ struct connman_technology_driver *driver;
+
+ driver = technology->driver_list->data;
+
+ if (driver->remove)
+ driver->remove(technology);
+
+ technology->driver_list =
+ g_slist_delete_link(technology->driver_list,
+ technology->driver_list);
+ }
+
+ technology_list = g_slist_remove(technology_list, technology);
+
+ technology_dbus_unregister(technology);
+
+ g_slist_free(technology->device_list);
+
+ g_free(technology->path);
+ g_free(technology->regdom);
+ g_free(technology->tethering_ident);
+ g_free(technology->tethering_passphrase);
+ g_free(technology);
}
static struct connman_technology *technology_get(enum connman_service_type type)
@@ -1084,12 +1152,13 @@ static struct connman_technology *technology_get(enum connman_service_type type)
DBG("type %d", type);
str = __connman_service_type2string(type);
- if (str == NULL)
+ if (!str)
return NULL;
technology = technology_find(type);
- if (technology != NULL) {
- __sync_fetch_and_add(&technology->refcount, 1);
+ if (technology) {
+ if (type != CONNMAN_SERVICE_TYPE_P2P)
+ __sync_fetch_and_add(&technology->refcount, 1);
return technology;
}
@@ -1103,121 +1172,139 @@ static struct connman_technology *technology_get(enum connman_service_type type)
}
}
- if (tech_drivers == NULL) {
+ if (!tech_drivers) {
DBG("No matching drivers found for %s.",
__connman_service_type2string(type));
return NULL;
}
technology = g_try_new0(struct connman_technology, 1);
- if (technology == NULL)
+ if (!technology)
return NULL;
technology->refcount = 1;
-
- technology->rfkill_driven = FALSE;
- technology->softblocked = FALSE;
- technology->hardblocked = FALSE;
-
technology->type = type;
technology->path = g_strdup_printf("%s/technology/%s",
CONNMAN_PATH, str);
+ if (type == CONNMAN_SERVICE_TYPE_P2P) {
+ struct connman_technology *wifi;
- technology->device_list = NULL;
-
- technology->pending_reply = NULL;
-
- technology_load(technology);
-
- if (technology_dbus_register(technology) == FALSE) {
- g_free(technology);
- return NULL;
+ wifi = technology_find(CONNMAN_SERVICE_TYPE_WIFI);
+ if (wifi)
+ technology->enabled = wifi->enabled;
}
+ technology_load(technology);
technology_list = g_slist_prepend(technology_list, technology);
-
technology->driver_list = tech_drivers;
- for (list = tech_drivers; list != NULL; list = g_slist_next(list)) {
+ for (list = tech_drivers; list; list = list->next) {
driver = list->data;
- if (driver->probe != NULL && driver->probe(technology) < 0)
+ if (driver->probe && driver->probe(technology) < 0)
DBG("Driver probe failed for technology %p",
technology);
}
+ if (!technology_dbus_register(technology)) {
+ technology_put(technology);
+ return NULL;
+ }
+
DBG("technology %p", technology);
return technology;
}
-static void technology_dbus_unregister(struct connman_technology *technology)
+int connman_technology_driver_register(struct connman_technology_driver *driver)
{
- if (technology->dbus_registered == FALSE)
- return;
+ GSList *list;
+ struct connman_device *device;
+ enum connman_service_type type;
- technology_removed_signal(technology);
- g_dbus_unregister_interface(connection, technology->path,
- CONNMAN_TECHNOLOGY_INTERFACE);
+ for (list = driver_list; list; list = list->next) {
+ if (list->data == driver)
+ goto exist;
+ }
- technology->dbus_registered = FALSE;
-}
+ DBG("Registering %s driver", driver->name);
-static void technology_put(struct connman_technology *technology)
-{
- DBG("technology %p", technology);
+ driver_list = g_slist_insert_sorted(driver_list, driver,
+ compare_priority);
- if (__sync_sub_and_fetch(&technology->refcount, 1) > 0)
- return;
+ /*
+ * Check for technology less devices if this driver
+ * can service any of them.
+ */
+ for (list = techless_device_list; list; list = list->next) {
+ device = list->data;
- reply_scan_pending(technology, -EINTR);
+ type = __connman_device_get_service_type(device);
+ if (type != driver->type)
+ continue;
- while (technology->driver_list != NULL) {
- struct connman_technology_driver *driver;
+ techless_device_list = g_slist_remove(techless_device_list,
+ device);
- driver = technology->driver_list->data;
+ __connman_technology_add_device(device);
+ }
- if (driver->remove != NULL)
- driver->remove(technology);
+ /* Check for orphaned rfkill switches. */
+ g_hash_table_foreach(rfkill_list, rfkill_check,
+ GINT_TO_POINTER(driver->type));
- technology->driver_list =
- g_slist_delete_link(technology->driver_list,
- technology->driver_list);
+exist:
+ if (driver->type == CONNMAN_SERVICE_TYPE_P2P) {
+ if (!technology_get(CONNMAN_SERVICE_TYPE_P2P))
+ return -ENOMEM;
}
- technology_list = g_slist_remove(technology_list, technology);
+ return 0;
+}
- technology_dbus_unregister(technology);
+void connman_technology_driver_unregister(struct connman_technology_driver *driver)
+{
+ GSList *list, *tech_drivers;
+ struct connman_technology *technology;
+ struct connman_technology_driver *current;
- g_slist_free(technology->device_list);
+ DBG("Unregistering driver %p name %s", driver, driver->name);
- g_free(technology->path);
- g_free(technology->regdom);
- g_free(technology->tethering_ident);
- g_free(technology->tethering_passphrase);
- g_free(technology);
-}
+ for (list = technology_list; list; list = list->next) {
+ technology = list->data;
-static void enable_tethering(struct connman_technology *technology)
-{
- int ret;
+ for (tech_drivers = technology->driver_list; tech_drivers;
+ tech_drivers = g_slist_next(tech_drivers)) {
+ current = tech_drivers->data;
+ if (driver != current)
+ continue;
- if (connman_setting_get_bool("PersistentTetheringMode") == FALSE)
- return;
+ if (driver->remove)
+ driver->remove(technology);
- ret = set_tethering(technology, TRUE);
- if (ret < 0 && ret != -EALREADY)
- DBG("Cannot enable tethering yet for %s (%d/%s)",
- get_name(technology->type),
- -ret, strerror(-ret));
+ technology->driver_list =
+ g_slist_remove(technology->driver_list,
+ driver);
+ break;
+ }
+ }
+
+ driver_list = g_slist_remove(driver_list, driver);
+
+ if (driver->type == CONNMAN_SERVICE_TYPE_P2P) {
+ technology = technology_find(CONNMAN_SERVICE_TYPE_P2P);
+ if (technology)
+ technology_put(technology);
+ }
}
void __connman_technology_add_interface(enum connman_service_type type,
- int index, const char *name, const char *ident)
+ int index, const char *ident)
{
struct connman_technology *technology;
GSList *tech_drivers;
struct connman_technology_driver *driver;
+ char *name;
switch (type) {
case CONNMAN_SERVICE_TYPE_UNKNOWN:
@@ -1230,22 +1317,24 @@ void __connman_technology_add_interface(enum connman_service_type type,
case CONNMAN_SERVICE_TYPE_GPS:
case CONNMAN_SERVICE_TYPE_VPN:
case CONNMAN_SERVICE_TYPE_GADGET:
+ case CONNMAN_SERVICE_TYPE_P2P:
break;
}
+ name = connman_inet_ifname(index);
connman_info("Adding interface %s [ %s ]", name,
__connman_service_type2string(type));
technology = technology_find(type);
- if (technology == NULL)
- return;
+ if (!technology)
+ goto out;
- for (tech_drivers = technology->driver_list; tech_drivers != NULL;
+ for (tech_drivers = technology->driver_list; tech_drivers;
tech_drivers = g_slist_next(tech_drivers)) {
driver = tech_drivers->data;
- if(driver->add_interface != NULL)
+ if (driver->add_interface)
driver->add_interface(technology, index, name, ident);
}
@@ -1253,16 +1342,20 @@ void __connman_technology_add_interface(enum connman_service_type type,
* At this point we can try to enable tethering automatically as
* now the interfaces are set properly.
*/
- if (technology->tethering_persistent == TRUE)
+ if (technology->tethering_persistent)
enable_tethering(technology);
+
+out:
+ g_free(name);
}
void __connman_technology_remove_interface(enum connman_service_type type,
- int index, const char *name, const char *ident)
+ int index, const char *ident)
{
struct connman_technology *technology;
GSList *tech_drivers;
struct connman_technology_driver *driver;
+ char *name;
switch (type) {
case CONNMAN_SERVICE_TYPE_UNKNOWN:
@@ -1275,22 +1368,25 @@ void __connman_technology_remove_interface(enum connman_service_type type,
case CONNMAN_SERVICE_TYPE_GPS:
case CONNMAN_SERVICE_TYPE_VPN:
case CONNMAN_SERVICE_TYPE_GADGET:
+ case CONNMAN_SERVICE_TYPE_P2P:
break;
}
+ name = connman_inet_ifname(index);
connman_info("Remove interface %s [ %s ]", name,
__connman_service_type2string(type));
+ g_free(name);
technology = technology_find(type);
- if (technology == NULL)
+ if (!technology)
return;
- for (tech_drivers = technology->driver_list; tech_drivers != NULL;
+ for (tech_drivers = technology->driver_list; tech_drivers;
tech_drivers = g_slist_next(tech_drivers)) {
driver = tech_drivers->data;
- if(driver->remove_interface != NULL)
+ if (driver->remove_interface)
driver->remove_interface(technology, index);
}
}
@@ -1305,7 +1401,7 @@ int __connman_technology_add_device(struct connman_device *device)
DBG("device %p type %s", device, get_name(type));
technology = technology_get(type);
- if (technology == NULL) {
+ if (!technology) {
/*
* Since no driver can be found for this device at the moment we
* add it to the techless device list.
@@ -1317,8 +1413,8 @@ int __connman_technology_add_device(struct connman_device *device)
}
__sync_synchronize();
- if (technology->rfkill_driven == TRUE) {
- if (technology->enabled == TRUE)
+ if (technology->rfkill_driven) {
+ if (technology->enabled)
__connman_device_enable(device);
else
__connman_device_disable(device);
@@ -1326,8 +1422,8 @@ int __connman_technology_add_device(struct connman_device *device)
goto done;
}
- if (technology->enable_persistent == TRUE &&
- global_offlinemode == FALSE) {
+ if (technology->enable_persistent &&
+ !global_offlinemode) {
int err = __connman_device_enable(device);
/*
* connman_technology_add_device() calls __connman_device_enable()
@@ -1339,7 +1435,7 @@ int __connman_technology_add_device(struct connman_device *device)
__connman_technology_enabled(type);
}
/* if technology persistent state is offline */
- if (technology->enable_persistent == FALSE)
+ if (!technology->enable_persistent)
__connman_device_disable(device);
done:
@@ -1359,7 +1455,7 @@ int __connman_technology_remove_device(struct connman_device *device)
type = __connman_device_get_service_type(device);
technology = technology_find(type);
- if (technology == NULL) {
+ if (!technology) {
techless_device_list = g_slist_remove(techless_device_list,
device);
return -ENXIO;
@@ -1368,65 +1464,28 @@ int __connman_technology_remove_device(struct connman_device *device)
technology->device_list = g_slist_remove(technology->device_list,
device);
- if (technology->tethering == TRUE)
- set_tethering(technology, FALSE);
+ if (technology->tethering)
+ set_tethering(technology, false);
technology_put(technology);
return 0;
}
-static void powered_changed(struct connman_technology *technology)
-{
- if (technology->dbus_registered == FALSE)
- return;
-
- if (technology->pending_reply != NULL) {
- g_dbus_send_reply(connection,
- technology->pending_reply, DBUS_TYPE_INVALID);
- dbus_message_unref(technology->pending_reply);
- technology->pending_reply = NULL;
-
- g_source_remove(technology->pending_timeout);
- technology->pending_timeout = 0;
- }
-
- __sync_synchronize();
- connman_dbus_property_changed_basic(technology->path,
- CONNMAN_TECHNOLOGY_INTERFACE, "Powered",
- DBUS_TYPE_BOOLEAN, &technology->enabled);
-}
-
-static int technology_enabled(struct connman_technology *technology)
-{
- __sync_synchronize();
- if (technology->enabled == TRUE)
- return -EALREADY;
-
- technology->enabled = TRUE;
-
- if (technology->tethering_persistent == TRUE)
- enable_tethering(technology);
-
- powered_changed(technology);
-
- return 0;
-}
-
int __connman_technology_enabled(enum connman_service_type type)
{
struct connman_technology *technology;
technology = technology_find(type);
- if (technology == NULL)
+ if (!technology)
return -ENXIO;
DBG("technology %p type %s rfkill %d enabled %d", technology,
get_name(type), technology->rfkill_driven,
technology->enabled);
- if (technology->rfkill_driven == TRUE) {
- if (technology->tethering_persistent == TRUE)
+ if (technology->rfkill_driven) {
+ if (technology->tethering_persistent)
enable_tethering(technology);
return 0;
}
@@ -1434,42 +1493,29 @@ int __connman_technology_enabled(enum connman_service_type type)
return technology_enabled(technology);
}
-static int technology_disabled(struct connman_technology *technology)
-{
- __sync_synchronize();
- if (technology->enabled == FALSE)
- return -EALREADY;
-
- technology->enabled = FALSE;
-
- powered_changed(technology);
-
- return 0;
-}
-
int __connman_technology_disabled(enum connman_service_type type)
{
struct connman_technology *technology;
GSList *list;
technology = technology_find(type);
- if (technology == NULL)
+ if (!technology)
return -ENXIO;
- if (technology->rfkill_driven == TRUE)
+ if (technology->rfkill_driven)
return 0;
- for (list = technology->device_list; list != NULL; list = list->next) {
+ for (list = technology->device_list; list; list = list->next) {
struct connman_device *device = list->data;
- if (connman_device_get_powered(device) == TRUE)
+ if (connman_device_get_powered(device))
return 0;
}
return technology_disabled(technology);
}
-int __connman_technology_set_offlinemode(connman_bool_t offlinemode)
+int __connman_technology_set_offlinemode(bool offlinemode)
{
GSList *list;
int err = -EINVAL, enabled_tech_count = 0;
@@ -1497,6 +1543,9 @@ int __connman_technology_set_offlinemode(connman_bool_t offlinemode)
if (offlinemode)
err = technology_disable(technology);
else {
+ if (technology->hardblocked)
+ continue;
+
if (technology->enable_persistent) {
err = technology_enable(technology);
enabled_tech_count++;
@@ -1515,30 +1564,32 @@ int __connman_technology_set_offlinemode(connman_bool_t offlinemode)
}
void __connman_technology_set_connected(enum connman_service_type type,
- connman_bool_t connected)
+ bool connected)
{
struct connman_technology *technology;
+ dbus_bool_t val;
technology = technology_find(type);
- if (technology == NULL)
+ if (!technology)
return;
DBG("technology %p connected %d", technology, connected);
technology->connected = connected;
+ val = connected;
connman_dbus_property_changed_basic(technology->path,
CONNMAN_TECHNOLOGY_INTERFACE, "Connected",
- DBUS_TYPE_BOOLEAN, &connected);
+ DBUS_TYPE_BOOLEAN, &val);
}
-static connman_bool_t technology_apply_rfkill_change(struct connman_technology *technology,
- connman_bool_t softblock,
- connman_bool_t hardblock,
- connman_bool_t new_rfkill)
+static bool technology_apply_rfkill_change(struct connman_technology *technology,
+ bool softblock,
+ bool hardblock,
+ bool new_rfkill)
{
- gboolean hardblock_changed = FALSE;
- gboolean apply = TRUE;
+ bool hardblock_changed = false;
+ bool apply = true;
GList *start, *list;
DBG("technology %p --> %d/%d vs %d/%d",
@@ -1548,53 +1599,58 @@ static connman_bool_t technology_apply_rfkill_change(struct connman_technology *
if (technology->hardblocked == hardblock)
goto softblock_change;
- if (!(new_rfkill == TRUE && hardblock == FALSE)) {
+ if (!(new_rfkill && !hardblock)) {
start = g_hash_table_get_values(rfkill_list);
- for (list = start; list != NULL; list = list->next) {
+ for (list = start; list; list = list->next) {
struct connman_rfkill *rfkill = list->data;
if (rfkill->type != technology->type)
continue;
if (rfkill->hardblock != hardblock)
- apply = FALSE;
+ apply = false;
}
g_list_free(start);
}
- if (apply == FALSE)
+ if (!apply)
goto softblock_change;
technology->hardblocked = hardblock;
- hardblock_changed = TRUE;
+ hardblock_changed = true;
softblock_change:
- if (apply == FALSE && technology->softblocked != softblock)
- apply = TRUE;
+ if (!apply && technology->softblocked != softblock)
+ apply = true;
- if (apply == FALSE)
+ if (!apply)
return technology->hardblocked;
technology->softblocked = softblock;
- if (technology->hardblocked == TRUE ||
- technology->softblocked == TRUE) {
+ if (technology->hardblocked ||
+ technology->softblocked) {
if (technology_disabled(technology) != -EALREADY)
- technology_affect_devices(technology, FALSE);
- } else if (technology->hardblocked == FALSE &&
- technology->softblocked == FALSE) {
+ technology_affect_devices(technology, false);
+ } else if (!technology->hardblocked &&
+ !technology->softblocked) {
if (technology_enabled(technology) != -EALREADY)
- technology_affect_devices(technology, TRUE);
+ technology_affect_devices(technology, true);
}
- if (hardblock_changed == TRUE) {
- if (technology->hardblocked == TRUE) {
+ if (hardblock_changed) {
+ if (technology->hardblocked) {
DBG("%s is switched off.", get_name(technology->type));
technology_dbus_unregister(technology);
- } else
+ } else {
+ DBG("%s is switched on.", get_name(technology->type));
technology_dbus_register(technology);
+
+ if (global_offlinemode)
+ __connman_rfkill_block(technology->type, true);
+ }
}
return technology->hardblocked;
@@ -1602,8 +1658,8 @@ softblock_change:
int __connman_technology_add_rfkill(unsigned int index,
enum connman_service_type type,
- connman_bool_t softblock,
- connman_bool_t hardblock)
+ bool softblock,
+ bool hardblock)
{
struct connman_technology *technology;
struct connman_rfkill *rfkill;
@@ -1612,11 +1668,11 @@ int __connman_technology_add_rfkill(unsigned int index,
softblock, hardblock);
rfkill = g_hash_table_lookup(rfkill_list, GINT_TO_POINTER(index));
- if (rfkill != NULL)
+ if (rfkill)
goto done;
rfkill = g_try_new0(struct connman_rfkill, 1);
- if (rfkill == NULL)
+ if (!rfkill)
return -ENOMEM;
rfkill->index = index;
@@ -1629,36 +1685,37 @@ int __connman_technology_add_rfkill(unsigned int index,
done:
technology = technology_get(type);
/* If there is no driver for this type, ignore it. */
- if (technology == NULL)
+ if (!technology)
return -ENXIO;
- technology->rfkill_driven = TRUE;
+ technology->rfkill_driven = true;
/* If hardblocked, there is no need to handle softblocked state */
if (technology_apply_rfkill_change(technology,
- softblock, hardblock, TRUE) == TRUE)
+ softblock, hardblock, true))
+ return 0;
+
+ if (global_offlinemode)
return 0;
/*
* Depending on softblocked state we unblock/block according to
* offlinemode and persistente state.
*/
- if (technology->softblocked == TRUE &&
- global_offlinemode == FALSE &&
- technology->enable_persistent == TRUE)
- return __connman_rfkill_block(type, FALSE);
- else if (technology->softblocked == FALSE &&
- (global_offlinemode == TRUE ||
- technology->enable_persistent == FALSE))
- return __connman_rfkill_block(type, TRUE);
+ if (technology->softblocked &&
+ technology->enable_persistent)
+ return __connman_rfkill_block(type, false);
+ else if (!technology->softblocked &&
+ !technology->enable_persistent)
+ return __connman_rfkill_block(type, true);
return 0;
}
int __connman_technology_update_rfkill(unsigned int index,
enum connman_service_type type,
- connman_bool_t softblock,
- connman_bool_t hardblock)
+ bool softblock,
+ bool hardblock)
{
struct connman_technology *technology;
struct connman_rfkill *rfkill;
@@ -1666,7 +1723,7 @@ int __connman_technology_update_rfkill(unsigned int index,
DBG("index %u soft %u hard %u", index, softblock, hardblock);
rfkill = g_hash_table_lookup(rfkill_list, GINT_TO_POINTER(index));
- if (rfkill == NULL)
+ if (!rfkill)
return -ENXIO;
if (rfkill->softblock == softblock &&
@@ -1678,27 +1735,17 @@ int __connman_technology_update_rfkill(unsigned int index,
technology = technology_find(type);
/* If there is no driver for this type, ignore it. */
- if (technology == NULL)
+ if (!technology)
return -ENXIO;
- /* If hardblocked, there is no need to handle softblocked state */
- if (technology_apply_rfkill_change(technology,
- softblock, hardblock, FALSE) == TRUE)
- return 0;
+ technology_apply_rfkill_change(technology, softblock, hardblock,
+ false);
- if (global_offlinemode == TRUE)
- return 0;
-
- /*
- * Depending on softblocked state we unblock/block according to
- * persistent state.
- */
- if (technology->softblocked == TRUE &&
- technology->enable_persistent == TRUE)
- return __connman_rfkill_block(type, FALSE);
- else if (technology->softblocked == FALSE &&
- technology->enable_persistent == FALSE)
- return __connman_rfkill_block(type, TRUE);
+ if (technology->hardblocked)
+ DBG("%s hardblocked", get_name(technology->type));
+ else
+ DBG("%s is%s softblocked", get_name(technology->type),
+ technology->softblocked ? "" : " not");
return 0;
}
@@ -1712,17 +1759,17 @@ int __connman_technology_remove_rfkill(unsigned int index,
DBG("index %u", index);
rfkill = g_hash_table_lookup(rfkill_list, GINT_TO_POINTER(index));
- if (rfkill == NULL)
+ if (!rfkill)
return -ENXIO;
g_hash_table_remove(rfkill_list, GINT_TO_POINTER(index));
technology = technology_find(type);
- if (technology == NULL)
+ if (!technology)
return -ENXIO;
technology_apply_rfkill_change(technology,
- technology->softblocked, !technology->hardblocked, FALSE);
+ technology->softblocked, !technology->hardblocked, false);
technology_put(technology);
diff --git a/src/tethering.c b/src/tethering.c
index 7042040c..c7e17f5d 100644
--- a/src/tethering.c
+++ b/src/tethering.c
@@ -2,7 +2,7 @@
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2013 Intel Corporation. All rights reserved.
* Copyright (C) 2011 ProFUSION embedded systems
*
* This program is free software; you can redistribute it and/or modify
@@ -133,7 +133,7 @@ static void dhcp_server_error(GDHCPServerError error)
}
static GDHCPServer *dhcp_server_start(const char *bridge,
- const char *router, const char* subnet,
+ const char *router, const char *subnet,
const char *start_ip, const char *end_ip,
unsigned int lease_time, const char *dns)
{
@@ -148,7 +148,7 @@ static GDHCPServer *dhcp_server_start(const char *bridge,
return NULL;
dhcp_server = g_dhcp_server_new(G_DHCP_IPV4, index, &error);
- if (dhcp_server == NULL) {
+ if (!dhcp_server) {
dhcp_server_error(error);
return NULL;
}
@@ -168,7 +168,7 @@ static GDHCPServer *dhcp_server_start(const char *bridge,
static void dhcp_server_stop(GDHCPServer *server)
{
- if (server == NULL)
+ if (!server)
return;
g_dhcp_server_unref(server);
@@ -176,6 +176,7 @@ static void dhcp_server_stop(GDHCPServer *server)
static void tethering_restart(struct connman_ippool *pool, void *user_data)
{
+ DBG("pool %p", pool);
__connman_tethering_set_disabled();
__connman_tethering_set_enabled();
}
@@ -207,7 +208,7 @@ void __connman_tethering_set_enabled(void)
index = connman_inet_ifindex(BRIDGE_NAME);
dhcp_ippool = __connman_ippool_create(index, 2, 252,
tethering_restart, NULL);
- if (dhcp_ippool == NULL) {
+ if (!dhcp_ippool) {
connman_error("Fail to create IP pool");
__connman_bridge_remove(BRIDGE_NAME);
__sync_fetch_and_sub(&tethering_enabled, 1);
@@ -220,7 +221,9 @@ void __connman_tethering_set_enabled(void)
start_ip = __connman_ippool_get_start_ip(dhcp_ippool);
end_ip = __connman_ippool_get_end_ip(dhcp_ippool);
- err = __connman_bridge_enable(BRIDGE_NAME, gateway, broadcast);
+ err = __connman_bridge_enable(BRIDGE_NAME, gateway,
+ __connman_ipaddress_netmask_prefix_len(subnet_mask),
+ broadcast);
if (err < 0 && err != -EALREADY) {
__connman_ippool_unref(dhcp_ippool);
__connman_bridge_remove(BRIDGE_NAME);
@@ -229,12 +232,12 @@ void __connman_tethering_set_enabled(void)
}
ns = connman_setting_get_string_list("FallbackNameservers");
- if (ns != NULL) {
- if (ns[0] != NULL) {
+ if (ns) {
+ if (ns[0]) {
g_free(private_network_primary_dns);
private_network_primary_dns = g_strdup(ns[0]);
}
- if (ns[1] != NULL) {
+ if (ns[1]) {
g_free(private_network_secondary_dns);
private_network_secondary_dns = g_strdup(ns[1]);
}
@@ -256,7 +259,7 @@ void __connman_tethering_set_enabled(void)
gateway, subnet_mask,
start_ip, end_ip,
24 * 3600, dns);
- if (tethering_dhcp_server == NULL) {
+ if (!tethering_dhcp_server) {
__connman_bridge_disable(BRIDGE_NAME);
__connman_ippool_unref(dhcp_ippool);
__connman_bridge_remove(BRIDGE_NAME);
@@ -264,9 +267,22 @@ void __connman_tethering_set_enabled(void)
return;
}
- prefixlen =
- __connman_ipaddress_netmask_prefix_len(subnet_mask);
- __connman_nat_enable(BRIDGE_NAME, start_ip, prefixlen);
+ prefixlen = __connman_ipaddress_netmask_prefix_len(subnet_mask);
+ err = __connman_nat_enable(BRIDGE_NAME, start_ip, prefixlen);
+ if (err < 0) {
+ connman_error("Cannot enable NAT %d/%s", err, strerror(-err));
+ dhcp_server_stop(tethering_dhcp_server);
+ __connman_bridge_disable(BRIDGE_NAME);
+ __connman_ippool_unref(dhcp_ippool);
+ __connman_bridge_remove(BRIDGE_NAME);
+ __sync_fetch_and_sub(&tethering_enabled, 1);
+ return;
+ }
+
+ err = __connman_ipv6pd_setup(BRIDGE_NAME);
+ if (err < 0 && err != -EINPROGRESS)
+ DBG("Cannot setup IPv6 prefix delegation %d/%s", err,
+ strerror(-err));
DBG("tethering started");
}
@@ -277,12 +293,14 @@ void __connman_tethering_set_disabled(void)
DBG("enabled %d", tethering_enabled - 1);
- index = connman_inet_ifindex(BRIDGE_NAME);
- __connman_dnsproxy_remove_listener(index);
-
if (__sync_fetch_and_sub(&tethering_enabled, 1) != 1)
return;
+ __connman_ipv6pd_cleanup();
+
+ index = connman_inet_ifindex(BRIDGE_NAME);
+ __connman_dnsproxy_remove_listener(index);
+
__connman_nat_disable(BRIDGE_NAME);
dhcp_server_stop(tethering_dhcp_server);
@@ -351,11 +369,11 @@ static void setup_tun_interface(unsigned int flags, unsigned change,
DBUS_TYPE_STRING, &server_ip);
connman_dbus_dict_append_basic(&dict, "PeerIPv4",
DBUS_TYPE_STRING, &peer_ip);
- if (pn->primary_dns != NULL)
+ if (pn->primary_dns)
connman_dbus_dict_append_basic(&dict, "PrimaryDNS",
DBUS_TYPE_STRING, &pn->primary_dns);
- if (pn->secondary_dns != NULL)
+ if (pn->secondary_dns)
connman_dbus_dict_append_basic(&dict, "SecondaryDNS",
DBUS_TYPE_STRING, &pn->secondary_dns);
@@ -451,7 +469,7 @@ int __connman_private_network_request(DBusMessage *msg, const char *owner)
err = connman_inet_set_mtu(index, DEFAULT_MTU);
pn = g_try_new0(struct connman_private_network, 1);
- if (pn == NULL) {
+ if (!pn) {
err = -ENOMEM;
goto error;
}
@@ -462,14 +480,14 @@ int __connman_private_network_request(DBusMessage *msg, const char *owner)
owner_disconnect, pn, NULL);
pn->msg = msg;
pn->reply = dbus_message_new_method_return(pn->msg);
- if (pn->reply == NULL)
+ if (!pn->reply)
goto error;
pn->fd = fd;
pn->interface = iface;
pn->index = index;
pn->pool = __connman_ippool_create(pn->index, 1, 1, ippool_disconnect, pn);
- if (pn->pool == NULL) {
+ if (!pn->pool) {
errno = -ENOMEM;
goto error;
}
@@ -497,7 +515,7 @@ int __connman_private_network_release(const char *path)
struct connman_private_network *pn;
pn = g_hash_table_lookup(pn_hash, path);
- if (pn == NULL)
+ if (!pn)
return -EACCES;
g_hash_table_remove(pn_hash, path);
@@ -511,7 +529,7 @@ int __connman_tethering_init(void)
tethering_enabled = 0;
connection = connman_dbus_get_connection();
- if (connection == NULL)
+ if (!connection)
return -EFAULT;
pn_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
@@ -522,10 +540,10 @@ int __connman_tethering_init(void)
void __connman_tethering_cleanup(void)
{
- DBG("");
+ DBG("enabled %d", tethering_enabled);
__sync_synchronize();
- if (tethering_enabled == 0) {
+ if (tethering_enabled > 0) {
if (tethering_dhcp_server)
dhcp_server_stop(tethering_dhcp_server);
__connman_bridge_disable(BRIDGE_NAME);
@@ -533,7 +551,7 @@ void __connman_tethering_cleanup(void)
__connman_nat_disable(BRIDGE_NAME);
}
- if (connection == NULL)
+ if (!connection)
return;
g_hash_table_destroy(pn_hash);
diff --git a/src/timeserver.c b/src/timeserver.c
index f3c1220d..d41fa404 100644
--- a/src/timeserver.c
+++ b/src/timeserver.c
@@ -2,7 +2,7 @@
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2013 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -51,10 +51,10 @@ static void save_timeservers(char **servers)
int cnt;
keyfile = __connman_storage_load_global();
- if (keyfile == NULL)
+ if (!keyfile)
keyfile = g_key_file_new();
- for (cnt = 0; servers != NULL && servers[cnt] != NULL; cnt++);
+ for (cnt = 0; servers && servers[cnt]; cnt++);
g_key_file_set_string_list(keyfile, "global", "Timeservers",
(const gchar **)servers, cnt);
@@ -66,13 +66,13 @@ static void save_timeservers(char **servers)
return;
}
-static char **load_timeservers()
+static char **load_timeservers(void)
{
GKeyFile *keyfile;
char **servers = NULL;
keyfile = __connman_storage_load_global();
- if (keyfile == NULL)
+ if (!keyfile)
return NULL;
servers = g_key_file_get_string_list(keyfile, "global",
@@ -83,14 +83,15 @@ static char **load_timeservers()
return servers;
}
-static void resolv_result(GResolvResultStatus status, char **results, gpointer user_data)
+static void resolv_result(GResolvResultStatus status, char **results,
+ gpointer user_data)
{
int i;
DBG("status %d", status);
if (status == G_RESOLV_RESULT_STATUS_SUCCESS) {
- if (results != NULL) {
+ if (results) {
for (i = 0; results[i]; i++) {
DBG("result[%d]: %s", i, results[i]);
if (i == 0)
@@ -121,7 +122,7 @@ static void resolv_result(GResolvResultStatus status, char **results, gpointer u
*/
void __connman_timeserver_sync_next()
{
- if (ts_current != NULL) {
+ if (ts_current) {
g_free(ts_current);
ts_current = NULL;
}
@@ -129,7 +130,7 @@ void __connman_timeserver_sync_next()
__connman_ntp_stop();
/* Get the 1st server in the list */
- if (ts_list == NULL)
+ if (!ts_list)
return;
ts_current = ts_list->data;
@@ -158,10 +159,10 @@ GSList *__connman_timeserver_add_list(GSList *server_list,
{
GSList *list = server_list;
- if (timeserver == NULL)
+ if (!timeserver)
return server_list;
- while (list != NULL) {
+ while (list) {
char *existing_server = list->data;
if (strcmp(timeserver, existing_server) == 0)
return server_list;
@@ -192,7 +193,7 @@ GSList *__connman_timeserver_get_all(struct connman_service *service)
service_ts_config = connman_service_get_timeservers_config(service);
/* First add Service Timeservers.Configuration to the list */
- for (i = 0; service_ts_config != NULL && service_ts_config[i] != NULL;
+ for (i = 0; service_ts_config && service_ts_config[i];
i++)
list = __connman_timeserver_add_list(list,
service_ts_config[i]);
@@ -200,24 +201,24 @@ GSList *__connman_timeserver_get_all(struct connman_service *service)
service_ts = connman_service_get_timeservers(service);
/* First add Service Timeservers via DHCP to the list */
- for (i = 0; service_ts != NULL && service_ts[i] != NULL; i++)
+ for (i = 0; service_ts && service_ts[i]; i++)
list = __connman_timeserver_add_list(list, service_ts[i]);
network = __connman_service_get_network(service);
- if (network != NULL) {
+ if (network) {
index = connman_network_get_index(network);
service_gw = __connman_ipconfig_get_gateway_from_index(index,
CONNMAN_IPCONFIG_TYPE_ALL);
/* Then add Service Gateway to the list */
- if (service_gw != NULL)
+ if (service_gw)
list = __connman_timeserver_add_list(list, service_gw);
}
/* Then add Global Timeservers to the list */
timeservers = load_timeservers();
- for (i = 0; timeservers != NULL && timeservers[i] != NULL; i++)
+ for (i = 0; timeservers && timeservers[i]; i++)
list = __connman_timeserver_add_list(list, timeservers[i]);
g_strfreev(timeservers);
@@ -225,19 +226,19 @@ GSList *__connman_timeserver_get_all(struct connman_service *service)
fallback_ts = connman_setting_get_string_list("FallbackTimeservers");
/* Lastly add the fallback servers */
- for (i = 0; fallback_ts != NULL && fallback_ts[i] != NULL; i++)
+ for (i = 0; fallback_ts && fallback_ts[i]; i++)
list = __connman_timeserver_add_list(list, fallback_ts[i]);
return g_slist_reverse(list);
}
-static gboolean ts_recheck(void *user_data)
+static gboolean ts_recheck(gpointer user_data)
{
GSList *ts;
ts = __connman_timeserver_get_all(__connman_service_get_default());
- if (ts == NULL) {
+ if (!ts) {
DBG("timeservers disabled");
return TRUE;
@@ -268,7 +269,7 @@ static void ts_recheck_disable(void)
g_source_remove(ts_recheck_id);
ts_recheck_id = 0;
- if (ts_current != NULL) {
+ if (ts_current) {
g_free(ts_current);
ts_current = NULL;
}
@@ -291,15 +292,15 @@ int __connman_timeserver_sync(struct connman_service *default_service)
{
struct connman_service *service;
- if (default_service != NULL)
+ if (default_service)
service = default_service;
else
service = __connman_service_get_default();
- if (service == NULL)
+ if (!service)
return -EINVAL;
- if (resolv == NULL)
+ if (!resolv)
return 0;
/*
* Before we start creating the new timeserver list we must stop
@@ -319,14 +320,14 @@ int __connman_timeserver_sync(struct connman_service *default_service)
__connman_service_timeserver_changed(service, ts_list);
- if (ts_list == NULL) {
+ if (!ts_list) {
DBG("No timeservers set.");
return 0;
}
ts_recheck_enable();
- __connman_timeserver_sync_next();
+ __connman_timeserver_sync_next();
return 0;
}
@@ -343,21 +344,21 @@ static int timeserver_start(struct connman_service *service)
return -EINVAL;
nameservers = connman_service_get_nameservers(service);
- if (nameservers == NULL)
+ if (!nameservers)
return -EINVAL;
/* Stop an already ongoing resolution, if there is one */
- if (resolv != NULL && resolv_id > 0)
+ if (resolv && resolv_id > 0)
g_resolv_cancel_lookup(resolv, resolv_id);
/* get rid of the old resolver */
- if (resolv != NULL) {
+ if (resolv) {
g_resolv_unref(resolv);
resolv = NULL;
}
resolv = g_resolv_new(i);
- if (resolv == NULL) {
+ if (!resolv) {
g_strfreev(nameservers);
return -ENOMEM;
}
@@ -365,7 +366,7 @@ static int timeserver_start(struct connman_service *service)
if (getenv("CONNMAN_RESOLV_DEBUG"))
g_resolv_set_debug(resolv, resolv_debug, "RESOLV");
- for (i = 0; nameservers[i] != NULL; i++)
+ for (i = 0; nameservers[i]; i++)
g_resolv_add_nameserver(resolv, nameservers[i], 53, 0);
g_strfreev(nameservers);
@@ -373,11 +374,11 @@ static int timeserver_start(struct connman_service *service)
return __connman_timeserver_sync(service);
}
-static void timeserver_stop()
+static void timeserver_stop(void)
{
DBG(" ");
- if (resolv != NULL) {
+ if (resolv) {
g_resolv_unref(resolv);
resolv = NULL;
}
@@ -410,7 +411,7 @@ char **__connman_timeserver_system_get()
static void default_changed(struct connman_service *default_service)
{
- if (default_service != NULL)
+ if (default_service)
timeserver_start(default_service);
else
timeserver_stop();
diff --git a/src/timezone.c b/src/timezone.c
index 2b556c28..e346b11a 100644
--- a/src/timezone.c
+++ b/src/timezone.c
@@ -60,7 +60,7 @@ static char *read_key_file(const char *pathname, const char *key)
}
map = mmap(0, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
- if (map == NULL || map == MAP_FAILED) {
+ if (!map || map == MAP_FAILED) {
close(fd);
return NULL;
}
@@ -81,25 +81,25 @@ static char *read_key_file(const char *pathname, const char *key)
}
ptr = memchr(ptr + 1, key[0], ptrlen - 1);
- if (ptr == NULL)
+ if (!ptr)
break;
ptrlen = st.st_size - (ptr - map);
}
- if (ptr != NULL) {
+ if (ptr) {
char *end, *val;
ptrlen = st.st_size - (ptr - map);
end = memchr(ptr, '\n', ptrlen);
- if (end != NULL)
+ if (end)
ptrlen = end - ptr;
val = memchr(ptr, '"', ptrlen);
- if (val != NULL) {
+ if (val) {
end = memchr(val + 1, '"', end - val - 1);
- if (end != NULL)
+ if (end)
str = g_strndup(val + 1, end - val - 1);
else
str = NULL;
@@ -137,10 +137,10 @@ static int compare_file(void *src_map, struct stat *src_st,
}
dst_map = mmap(0, dst_st.st_size, PROT_READ, MAP_SHARED, fd, 0);
- if (dst_map == NULL || dst_map == MAP_FAILED) {
+ if (!dst_map || dst_map == MAP_FAILED) {
close(fd);
return -1;
- }
+ }
result = memcmp(src_map, dst_map, src_st->st_size);
@@ -160,14 +160,14 @@ static char *find_origin(void *src_map, struct stat *src_st,
struct stat buf;
int ret;
- if (subpath == NULL)
- strncpy(pathname, basepath, sizeof(pathname));
+ if (!subpath)
+ strncpy(pathname, basepath, sizeof(pathname) - 1);
else
snprintf(pathname, sizeof(pathname),
"%s/%s", basepath, subpath);
dir = opendir(pathname);
- if (dir == NULL)
+ if (!dir)
return NULL;
while ((d = readdir(dir))) {
@@ -179,7 +179,7 @@ static char *find_origin(void *src_map, struct stat *src_st,
switch (d->d_type) {
case DT_REG:
- if (subpath == NULL)
+ if (!subpath)
snprintf(pathname, PATH_MAX,
"%s/%s", basepath, d->d_name);
else
@@ -206,14 +206,14 @@ static char *find_origin(void *src_map, struct stat *src_st,
continue;
/* fall through */
case DT_DIR:
- if (subpath == NULL)
+ if (!subpath)
strncpy(pathname, d->d_name, sizeof(pathname));
else
snprintf(pathname, sizeof(pathname),
"%s/%s", subpath, d->d_name);
str = find_origin(src_map, src_st, basepath, pathname);
- if (str != NULL) {
+ if (str) {
closedir(dir);
return str;
}
@@ -248,14 +248,14 @@ char *__connman_timezone_lookup(void)
if (S_ISREG(st.st_mode)) {
map = mmap(0, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
- if (map == NULL || map == MAP_FAILED) {
+ if (!map || map == MAP_FAILED) {
g_free(zone);
zone = NULL;
goto done;
}
- if (zone != NULL) {
+ if (zone) {
char pathname[PATH_MAX];
snprintf(pathname, PATH_MAX, "%s/%s",
@@ -267,7 +267,7 @@ char *__connman_timezone_lookup(void)
}
}
- if (zone == NULL)
+ if (!zone)
zone = find_origin(map, &st, USR_SHARE_ZONEINFO, NULL);
munmap(map, st.st_size);
@@ -331,7 +331,7 @@ int __connman_timezone_change(const char *zone)
}
map = mmap(0, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
- if (map == NULL || map == MAP_FAILED) {
+ if (!map || map == MAP_FAILED) {
close(fd);
return -EIO;
}
@@ -415,7 +415,7 @@ int __connman_timezone_init(void)
return -EIO;
channel = g_io_channel_unix_new(fd);
- if (channel == NULL) {
+ if (!channel) {
close(fd);
return -EIO;
}
diff --git a/src/utsname.c b/src/utsname.c
index 1451c748..1dd5e0f2 100644
--- a/src/utsname.c
+++ b/src/utsname.c
@@ -85,11 +85,11 @@ const char *connman_utsname_get_hostname(void)
DBG("driver %p name %s", driver, driver->name);
- if (driver->get_hostname == NULL)
+ if (!driver->get_hostname)
continue;
hostname = driver->get_hostname();
- if (hostname != NULL)
+ if (hostname)
return hostname;
}
@@ -107,7 +107,7 @@ int __connman_utsname_set_hostname(const char *hostname)
DBG("driver %p name %s", driver, driver->name);
- if (driver->set_hostname == NULL)
+ if (!driver->set_hostname)
continue;
if (driver->set_hostname(hostname) == 0)
@@ -128,7 +128,7 @@ int __connman_utsname_set_domainname(const char *domainname)
DBG("driver %p name %s", driver, driver->name);
- if (driver->set_domainname == NULL)
+ if (!driver->set_domainname)
continue;
if (driver->set_domainname(domainname) == 0)
diff --git a/src/wispr.c b/src/wispr.c
index 94800948..dcce93cc 100644
--- a/src/wispr.c
+++ b/src/wispr.c
@@ -2,7 +2,7 @@
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2013 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -34,7 +34,7 @@
#define STATUS_URL_IPV6 "http://ipv6.connman.net/online/status.html"
struct connman_wispr_message {
- gboolean has_error;
+ bool has_error;
const char *current_element;
int message_type;
int response_code;
@@ -92,7 +92,7 @@ struct connman_wispr_portal {
struct connman_wispr_portal_context *ipv6_context;
};
-static gboolean wispr_portal_web_result(GWebResult *result, gpointer user_data);
+static bool wispr_portal_web_result(GWebResult *result, gpointer user_data);
static GHashTable *wispr_portal_list = NULL;
@@ -100,7 +100,7 @@ static void connman_wispr_message_init(struct connman_wispr_message *msg)
{
DBG("");
- msg->has_error = FALSE;
+ msg->has_error = false;
msg->current_element = NULL;
msg->message_type = -1;
@@ -127,13 +127,13 @@ static void connman_wispr_message_init(struct connman_wispr_message *msg)
static void free_wispr_routes(struct connman_wispr_portal_context *wp_context)
{
- while (wp_context->route_list != NULL) {
+ while (wp_context->route_list) {
struct wispr_route *route = wp_context->route_list->data;
DBG("free route to %s if %d type %d", route->address,
route->if_index, wp_context->type);
- switch(wp_context->type) {
+ switch (wp_context->type) {
case CONNMAN_IPCONFIG_TYPE_IPV4:
connman_inet_del_host_route(route->if_index,
route->address);
@@ -155,14 +155,15 @@ static void free_wispr_routes(struct connman_wispr_portal_context *wp_context)
}
}
-static void free_connman_wispr_portal_context(struct connman_wispr_portal_context *wp_context)
+static void free_connman_wispr_portal_context(
+ struct connman_wispr_portal_context *wp_context)
{
DBG("context %p", wp_context);
- if (wp_context == NULL)
+ if (!wp_context)
return;
- if (wp_context->wispr_portal != NULL) {
+ if (wp_context->wispr_portal) {
if (wp_context->wispr_portal->ipv4_context == wp_context)
wp_context->wispr_portal->ipv4_context = NULL;
@@ -179,12 +180,12 @@ static void free_connman_wispr_portal_context(struct connman_wispr_portal_contex
if (wp_context->timeout > 0)
g_source_remove(wp_context->timeout);
- if (wp_context->web != NULL)
+ if (wp_context->web)
g_web_unref(wp_context->web);
g_free(wp_context->redirect_url);
- if (wp_context->wispr_parser != NULL)
+ if (wp_context->wispr_parser)
g_web_parser_unref(wp_context->wispr_parser);
connman_wispr_message_init(&wp_context->wispr_msg);
@@ -209,7 +210,7 @@ static void free_connman_wispr_portal(gpointer data)
DBG("");
- if (wispr_portal == NULL)
+ if (!wispr_portal)
return;
free_connman_wispr_portal_context(wispr_portal->ipv4_context);
@@ -326,12 +327,11 @@ static void xml_wispr_text_handler(GMarkupParseContext *context,
struct connman_wispr_message *msg = user_data;
int i;
- if (msg->current_element == NULL)
+ if (!msg->current_element)
return;
for (i = 0; wispr_element_map[i].str; i++) {
- if (g_str_equal(wispr_element_map[i].str,
- msg->current_element) == FALSE)
+ if (!g_str_equal(wispr_element_map[i].str, msg->current_element))
continue;
switch (wispr_element_map[i].element) {
@@ -380,7 +380,7 @@ static void xml_wispr_error_handler(GMarkupParseContext *context,
{
struct connman_wispr_message *msg = user_data;
- msg->has_error = TRUE;
+ msg->has_error = true;
}
static const GMarkupParser xml_wispr_parser_handlers = {
@@ -395,7 +395,7 @@ static void xml_wispr_parser_callback(const char *str, gpointer user_data)
{
struct connman_wispr_portal_context *wp_context = user_data;
GMarkupParseContext *parser_context = NULL;
- gboolean result;
+ bool result;
DBG("");
@@ -405,7 +405,7 @@ static void xml_wispr_parser_callback(const char *str, gpointer user_data)
result = g_markup_parse_context_parse(parser_context,
str, strlen(str), NULL);
- if (result == TRUE)
+ if (result)
g_markup_parse_context_end_parse(parser_context, NULL);
g_markup_parse_context_free(parser_context);
@@ -434,19 +434,19 @@ static void portal_manage_status(GWebResult *result,
/* We currently don't do anything with this info */
if (g_web_result_get_header(result, "X-ConnMan-Client-IP",
- &str) == TRUE)
+ &str))
connman_info("Client-IP: %s", str);
if (g_web_result_get_header(result, "X-ConnMan-Client-Country",
- &str) == TRUE)
+ &str))
connman_info("Client-Country: %s", str);
if (g_web_result_get_header(result, "X-ConnMan-Client-Region",
- &str) == TRUE)
+ &str))
connman_info("Client-Region: %s", str);
if (g_web_result_get_header(result, "X-ConnMan-Client-Timezone",
- &str) == TRUE)
+ &str))
connman_info("Client-Timezone: %s", str);
free_connman_wispr_portal_context(wp_context);
@@ -455,7 +455,7 @@ static void portal_manage_status(GWebResult *result,
CONNMAN_SERVICE_STATE_ONLINE, type);
}
-static gboolean wispr_route_request(const char *address, int ai_family,
+static bool wispr_route_request(const char *address, int ai_family,
int if_index, gpointer user_data)
{
int result = -1;
@@ -468,16 +468,16 @@ static gboolean wispr_route_request(const char *address, int ai_family,
DBG("address %s if %d gw %s", address, if_index, gateway);
- if (gateway == NULL)
- return FALSE;
+ if (!gateway)
+ return false;
route = g_try_new0(struct wispr_route, 1);
if (route == 0) {
DBG("could not create struct");
- return FALSE;
+ return false;
}
- switch(wp_context->type) {
+ switch (wp_context->type) {
case CONNMAN_IPCONFIG_TYPE_IPV4:
result = connman_inet_add_host_route(if_index, address,
gateway);
@@ -492,17 +492,18 @@ static gboolean wispr_route_request(const char *address, int ai_family,
if (result < 0) {
g_free(route);
- return FALSE;
+ return false;
}
route->address = g_strdup(address);
route->if_index = if_index;
wp_context->route_list = g_slist_prepend(wp_context->route_list, route);
- return TRUE;
+ return true;
}
-static void wispr_portal_request_portal(struct connman_wispr_portal_context *wp_context)
+static void wispr_portal_request_portal(
+ struct connman_wispr_portal_context *wp_context)
{
DBG("");
@@ -516,7 +517,7 @@ static void wispr_portal_request_portal(struct connman_wispr_portal_context *wp_
wispr_portal_error(wp_context);
}
-static gboolean wispr_input(const guint8 **data, gsize *length,
+static bool wispr_input(const guint8 **data, gsize *length,
gpointer user_data)
{
struct connman_wispr_portal_context *wp_context = user_data;
@@ -544,21 +545,21 @@ static gboolean wispr_input(const guint8 **data, gsize *length,
*data = (guint8 *) wp_context->wispr_formdata;
*length = count;
- return FALSE;
+ return false;
}
static void wispr_portal_browser_reply_cb(struct connman_service *service,
- connman_bool_t authentication_done,
+ bool authentication_done,
const char *error, void *user_data)
{
struct connman_wispr_portal_context *wp_context = user_data;
DBG("");
- if (service == NULL || wp_context == NULL)
+ if (!service || !wp_context)
return;
- if (authentication_done == FALSE) {
+ if (!authentication_done) {
wispr_portal_error(wp_context);
free_wispr_routes(wp_context);
return;
@@ -569,17 +570,17 @@ static void wispr_portal_browser_reply_cb(struct connman_service *service,
}
static void wispr_portal_request_wispr_login(struct connman_service *service,
- connman_bool_t success,
+ bool success,
const char *ssid, int ssid_len,
const char *username, const char *password,
- gboolean wps, const char *wpspin,
+ bool wps, const char *wpspin,
const char *error, void *user_data)
{
struct connman_wispr_portal_context *wp_context = user_data;
DBG("");
- if (error != NULL) {
+ if (error) {
if (g_strcmp0(error,
"net.connman.Agent.Error.LaunchBrowser") == 0) {
if (__connman_agent_request_browser(service,
@@ -608,7 +609,7 @@ static void wispr_portal_request_wispr_login(struct connman_service *service,
connman_wispr_message_init(&wp_context->wispr_msg);
}
-static gboolean wispr_manage_message(GWebResult *result,
+static bool wispr_manage_message(GWebResult *result,
struct connman_wispr_portal_context *wp_context)
{
DBG("Message type: %s (%d)",
@@ -618,21 +619,21 @@ static gboolean wispr_manage_message(GWebResult *result,
response_code_to_string(wp_context->wispr_msg.response_code),
wp_context->wispr_msg.response_code);
- if (wp_context->wispr_msg.access_procedure != NULL)
+ if (wp_context->wispr_msg.access_procedure)
DBG("Access procedure: %s",
wp_context->wispr_msg.access_procedure);
- if (wp_context->wispr_msg.access_location != NULL)
+ if (wp_context->wispr_msg.access_location)
DBG("Access location: %s",
wp_context->wispr_msg.access_location);
- if (wp_context->wispr_msg.location_name != NULL)
+ if (wp_context->wispr_msg.location_name)
DBG("Location name: %s",
wp_context->wispr_msg.location_name);
- if (wp_context->wispr_msg.login_url != NULL)
+ if (wp_context->wispr_msg.login_url)
DBG("Login URL: %s", wp_context->wispr_msg.login_url);
- if (wp_context->wispr_msg.abort_login_url != NULL)
+ if (wp_context->wispr_msg.abort_login_url)
DBG("Abort login URL: %s",
wp_context->wispr_msg.abort_login_url);
- if (wp_context->wispr_msg.logoff_url != NULL)
+ if (wp_context->wispr_msg.logoff_url)
DBG("Logoff URL: %s", wp_context->wispr_msg.logoff_url);
switch (wp_context->wispr_msg.message_type) {
@@ -645,6 +646,8 @@ static gboolean wispr_manage_message(GWebResult *result,
wispr_portal_request_wispr_login,
wp_context) != -EINPROGRESS)
wispr_portal_error(wp_context);
+ else
+ return true;
break;
case 120: /* Falling down */
@@ -663,7 +666,7 @@ static gboolean wispr_manage_message(GWebResult *result,
wispr_portal_request_portal(wp_context);
- return TRUE;
+ return true;
} else
wispr_portal_error(wp_context);
@@ -672,10 +675,10 @@ static gboolean wispr_manage_message(GWebResult *result,
break;
}
- return FALSE;
+ return false;
}
-static gboolean wispr_portal_web_result(GWebResult *result, gpointer user_data)
+static bool wispr_portal_web_result(GWebResult *result, gpointer user_data)
{
struct connman_wispr_portal_context *wp_context = user_data;
const char *redirect = NULL;
@@ -692,13 +695,13 @@ static gboolean wispr_portal_web_result(GWebResult *result, gpointer user_data)
if (length > 0) {
g_web_parser_feed_data(wp_context->wispr_parser,
chunk, length);
- return TRUE;
+ return true;
}
g_web_parser_end_data(wp_context->wispr_parser);
if (wp_context->wispr_msg.message_type >= 0) {
- if (wispr_manage_message(result, wp_context) == TRUE)
+ if (wispr_manage_message(result, wp_context))
goto done;
}
}
@@ -713,20 +716,19 @@ static gboolean wispr_portal_web_result(GWebResult *result, gpointer user_data)
break;
if (g_web_result_get_header(result, "X-ConnMan-Status",
- &str) == TRUE) {
+ &str)) {
portal_manage_status(result, wp_context);
- return FALSE;
- }
- else
+ return false;
+ } else
__connman_agent_request_browser(wp_context->service,
wispr_portal_browser_reply_cb,
wp_context->redirect_url, wp_context);
break;
case 302:
- if (g_web_supports_tls() == FALSE ||
- g_web_result_get_header(result, "Location",
- &redirect) == FALSE) {
+ if (!g_web_supports_tls() ||
+ !g_web_result_get_header(result, "Location",
+ &redirect)) {
__connman_agent_request_browser(wp_context->service,
wispr_portal_browser_reply_cb,
@@ -749,7 +751,7 @@ static gboolean wispr_portal_web_result(GWebResult *result, gpointer user_data)
wp_context->type) == 0) {
wispr_portal_error(wp_context);
free_connman_wispr_portal_context(wp_context);
- return FALSE;
+ return false;
}
break;
@@ -761,7 +763,7 @@ static gboolean wispr_portal_web_result(GWebResult *result, gpointer user_data)
wp_context->request_id = 0;
done:
wp_context->wispr_msg.message_type = -1;
- return FALSE;
+ return false;
}
static void proxy_callback(const char *proxy, void *user_data)
@@ -770,13 +772,18 @@ static void proxy_callback(const char *proxy, void *user_data)
DBG("proxy %s", proxy);
- if (wp_context == NULL)
+ if (!wp_context)
return;
wp_context->token = 0;
- if (proxy != NULL && g_strcmp0(proxy, "DIRECT") != 0)
+ if (proxy && g_strcmp0(proxy, "DIRECT") != 0) {
+ if (g_str_has_prefix(proxy, "PROXY")) {
+ proxy += 5;
+ for (; *proxy == ' ' && *proxy != '\0'; proxy++);
+ }
g_web_set_proxy(wp_context->web, proxy);
+ }
g_web_set_accept(wp_context->web, NULL);
g_web_set_user_agent(wp_context->web, "ConnMan/%s wispr", VERSION);
@@ -823,17 +830,18 @@ static int wispr_portal_detect(struct connman_wispr_portal_context *wp_context)
case CONNMAN_SERVICE_TYPE_WIFI:
case CONNMAN_SERVICE_TYPE_BLUETOOTH:
case CONNMAN_SERVICE_TYPE_CELLULAR:
+ case CONNMAN_SERVICE_TYPE_GADGET:
break;
case CONNMAN_SERVICE_TYPE_UNKNOWN:
case CONNMAN_SERVICE_TYPE_SYSTEM:
case CONNMAN_SERVICE_TYPE_GPS:
case CONNMAN_SERVICE_TYPE_VPN:
- case CONNMAN_SERVICE_TYPE_GADGET:
+ case CONNMAN_SERVICE_TYPE_P2P:
return -EOPNOTSUPP;
}
interface = connman_service_get_interface(wp_context->service);
- if (interface == NULL)
+ if (!interface)
return -EINVAL;
DBG("interface %s", interface);
@@ -846,14 +854,14 @@ static int wispr_portal_detect(struct connman_wispr_portal_context *wp_context)
}
nameservers = connman_service_get_nameservers(wp_context->service);
- if (nameservers == NULL) {
+ if (!nameservers) {
DBG("Could not get nameservers");
err = -EINVAL;
goto done;
}
wp_context->web = g_web_new(if_index);
- if (wp_context->web == NULL) {
+ if (!wp_context->web) {
DBG("Could not set up GWeb");
err = -ENOMEM;
goto done;
@@ -870,7 +878,7 @@ static int wispr_portal_detect(struct connman_wispr_portal_context *wp_context)
wp_context->status_url = STATUS_URL_IPV6;
}
- for (i = 0; nameservers[i] != NULL; i++)
+ for (i = 0; nameservers[i]; i++)
g_web_add_nameserver(wp_context->web, nameservers[i]);
proxy_method = connman_service_get_proxy_method(wp_context->service);
@@ -906,7 +914,7 @@ int __connman_wispr_start(struct connman_service *service,
DBG("service %p", service);
- if (wispr_portal_list == NULL)
+ if (!wispr_portal_list)
return -EINVAL;
index = __connman_service_get_index(service);
@@ -915,9 +923,9 @@ int __connman_wispr_start(struct connman_service *service,
wispr_portal = g_hash_table_lookup(wispr_portal_list,
GINT_TO_POINTER(index));
- if (wispr_portal == NULL) {
+ if (!wispr_portal) {
wispr_portal = g_try_new0(struct connman_wispr_portal, 1);
- if (wispr_portal == NULL)
+ if (!wispr_portal)
return -ENOMEM;
g_hash_table_replace(wispr_portal_list,
@@ -932,11 +940,11 @@ int __connman_wispr_start(struct connman_service *service,
return -EINVAL;
/* If there is already an existing context, we wipe it */
- if (wp_context != NULL)
+ if (wp_context)
free_connman_wispr_portal_context(wp_context);
wp_context = create_wispr_portal_context();
- if (wp_context == NULL)
+ if (!wp_context)
return -ENOMEM;
wp_context->service = service;
@@ -957,7 +965,7 @@ void __connman_wispr_stop(struct connman_service *service)
DBG("service %p", service);
- if (wispr_portal_list == NULL)
+ if (!wispr_portal_list)
return;
index = __connman_service_get_index(service);
diff --git a/src/wpad.c b/src/wpad.c
index 4e5834e5..d40959be 100644
--- a/src/wpad.c
+++ b/src/wpad.c
@@ -53,7 +53,7 @@ static void free_wpad(gpointer data)
g_strfreev(wpad->addrlist);
g_free(wpad->hostname);
- g_free(wpad);
+ g_free(wpad);
}
static void download_pac(struct connman_wpad *wpad, const char *target)
@@ -72,7 +72,7 @@ static void wpad_result(GResolvResultStatus status,
if (status == G_RESOLV_RESULT_STATUS_SUCCESS) {
char *url;
- if (results == NULL || g_strv_length(results) == 0)
+ if (!results || g_strv_length(results) == 0)
goto failed;
url = g_strdup_printf("http://%s/wpad.dat", wpad->hostname);
@@ -80,7 +80,7 @@ static void wpad_result(GResolvResultStatus status,
__connman_service_set_proxy_autoconfig(wpad->service, url);
wpad->addrlist = g_strdupv(results);
- if (wpad->addrlist != NULL)
+ if (wpad->addrlist)
download_pac(wpad, "wpad.dat");
g_free(url);
@@ -97,10 +97,10 @@ static void wpad_result(GResolvResultStatus status,
goto failed;
ptr = strchr(hostname + 5, '.');
- if (ptr == NULL || strlen(ptr) < 2)
+ if (!ptr || strlen(ptr) < 2)
goto failed;
- if (strchr(ptr + 1, '.') == NULL)
+ if (!strchr(ptr + 1, '.'))
goto failed;
wpad->hostname = g_strdup_printf("wpad.%s", ptr + 1);
@@ -131,7 +131,7 @@ int __connman_wpad_start(struct connman_service *service)
DBG("service %p", service);
- if (wpad_list == NULL)
+ if (!wpad_list)
return -EINVAL;
index = __connman_service_get_index(service);
@@ -139,22 +139,22 @@ int __connman_wpad_start(struct connman_service *service)
return -EINVAL;
domainname = connman_service_get_domainname(service);
- if (domainname == NULL)
+ if (!domainname)
return -EINVAL;
nameservers = connman_service_get_nameservers(service);
- if (nameservers == NULL)
+ if (!nameservers)
return -EINVAL;
wpad = g_try_new0(struct connman_wpad, 1);
- if (wpad == NULL) {
+ if (!wpad) {
g_strfreev(nameservers);
return -ENOMEM;
}
wpad->service = service;
wpad->resolv = g_resolv_new(index);
- if (wpad->resolv == NULL) {
+ if (!wpad->resolv) {
g_strfreev(nameservers);
g_free(wpad);
return -ENOMEM;
@@ -163,7 +163,7 @@ int __connman_wpad_start(struct connman_service *service)
if (getenv("CONNMAN_RESOLV_DEBUG"))
g_resolv_set_debug(wpad->resolv, resolv_debug, "RESOLV");
- for (i = 0; nameservers[i] != NULL; i++)
+ for (i = 0; nameservers[i]; i++)
g_resolv_add_nameserver(wpad->resolv, nameservers[i], 53, 0);
g_strfreev(nameservers);
@@ -187,14 +187,14 @@ void __connman_wpad_stop(struct connman_service *service)
DBG("service %p", service);
- if (wpad_list == NULL)
+ if (!wpad_list)
return;
index = __connman_service_get_index(service);
if (index < 0)
return;
- if (g_hash_table_remove(wpad_list, GINT_TO_POINTER(index)) == TRUE)
+ if (g_hash_table_remove(wpad_list, GINT_TO_POINTER(index)))
connman_service_unref(service);
}