summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
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 340b69e..0e3a7a1 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 9ccba72..ab538f3 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 5c3bd28..37cf524 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 e46cdda..034fa13 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 2ce61d9..0fde2c3 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 e5c9c7e..330ae81 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 c7b1f62..e98ccb5 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 75f136f..24db5f8 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 2e9e4d5..7b6195e 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 76d91d4..06e5daf 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 5cc6106..4fa0b36 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 5bf44af..6c03920 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 5feeee1..a97d790 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 f32bfae..83d7dfb 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 bff57d4..2ede854 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 9030a35..7232b98 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 0000000..768b7b4
--- /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 955b4b8..4f24ae2 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 c235d86..90c3d3c 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 5196576..6111629 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 f451f1c..72ba6f6 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 f66bb67..57f9435 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 694cc61..b23df16 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 ba613fb..558e966 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 9584e12..8d583ea 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 0000000..5ecda38
--- /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 4e305a9..a693bd0 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 c257ca0..4f635de 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 b8b3239..93c7a50 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 e56f2e1..b31ab4c 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 5447eb7..4d23550 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 0000000..0bb1e8b
--- /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 6a926cb..160bd06 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 623b970..5ba5324 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 b588c99..b4fe63a 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 0000000..ce3b582
--- /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 adf8525..7d73058 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 1c36017..693552e 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);