Send connman mailing list submissions to
[email protected]
To subscribe or unsubscribe via the World Wide Web, visit
https://lists.01.org/mailman/listinfo/connman
or, via email, send a message with subject or body 'help' to
[email protected]
You can reach the person managing the list at
[email protected]
When replying, please edit your Subject line so it is more specific
than "Re: Contents of connman digest..."
Today's Topics:
1. [PATCH 07/27] Add Address Conflict Detection support (RFC
5227) (Christian Spielberger)
2. [PATCH 14/27] acd: add acdhost_start and acdhost_stop
(Christian Spielberger)
3. [PATCH 11/27] acd: add send_probe_packet (Christian Spielberger)
4. [PATCH 12/27] acd: add send_announce_packet
(Christian Spielberger)
5. [PATCH 13/27] acd: add callback function pointers
(Christian Spielberger)
----------------------------------------------------------------------
Message: 1
Date: Wed, 11 Apr 2018 16:00:27 +0200
From: Christian Spielberger <[email protected]>
To: Daniel Wagner <[email protected]>
Cc: [email protected], Christian Spielberger
<[email protected]>
Subject: [PATCH 07/27] Add Address Conflict Detection support (RFC
5227)
Message-ID:
<[email protected]>
Add first acd.h, acd.c, a configuration ACD on/off switch and a first
version of start_acd in network.c which does nothing for the moment.
---
Makefile.am | 6 ++++--
include/acd.h | 38 ++++++++++++++++++++++++++++++++++++++
src/acd.c | 19 +++++++++++++++++++
src/main.c | 13 +++++++++++++
src/network.c | 38 ++++++++++++++++++++++++++++++++++++++
5 files changed, 112 insertions(+), 2 deletions(-)
create mode 100644 include/acd.h
create mode 100644 src/acd.c
diff --git a/Makefile.am b/Makefile.am
index aa58691..1e54d88 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -11,7 +11,8 @@ include_HEADERS = include/log.h include/plugin.h \
include/device.h include/network.h include/inet.h \
include/storage.h include/provision.h \
include/session.h include/ipaddress.h include/agent.h \
- include/inotify.h include/peer.h include/machine.h
+ include/inotify.h include/peer.h include/machine.h \
+ include/acd.h
nodist_include_HEADERS = include/version.h
@@ -125,7 +126,8 @@ src_connmand_SOURCES = $(gdhcp_sources) $(gweb_sources)
$(backtrace_sources) \
src/stats.c src/6to4.c \
src/ippool.c src/bridge.c src/nat.c src/ipaddress.c \
src/inotify.c src/ipv6pd.c src/peer.c \
- src/peer_service.c src/machine.c src/util.c
+ src/peer_service.c src/machine.c src/util.c \
+ src/acd.c
if INTERNAL_DNS_BACKEND
src_connmand_SOURCES += src/dnsproxy.c
diff --git a/include/acd.h b/include/acd.h
new file mode 100644
index 0000000..c347d77
--- /dev/null
+++ b/include/acd.h
@@ -0,0 +1,38 @@
+/*
+ *
+ * Connection Manager
+ *
+ * Address Conflict Detection (RFC 5227)
+ *
+ * based on DHCP client library with GLib integration,
+ * Copyright (C) 2009-2014 Intel Corporation. All rights reserved.
+ *
+ * Copyright (C) 2018 Commend International. 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.
+ *
+ */
+
+#ifndef __CONNMAN_ACD_H
+#define __CONNMAN_ACD_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct _acd_host;
+
+typedef struct _acd_host acd_host;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CONNMAN_ACD_H */
diff --git a/src/acd.c b/src/acd.c
new file mode 100644
index 0000000..1653d2f
--- /dev/null
+++ b/src/acd.c
@@ -0,0 +1,19 @@
+/*
+ *
+ * Connection Manager
+ *
+ * Address Conflict Detection (ACD) RFC 5227
+ *
+ * Copyright (C) 2018 Commend International 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
+ * 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.
+ *
+ */
+
diff --git a/src/main.c b/src/main.c
index dda54bb..4a07d60 100644
--- a/src/main.c
+++ b/src/main.c
@@ -82,6 +82,7 @@ static struct {
char *vendor_class_id;
bool enable_online_check;
bool auto_connect_roaming_services;
+ bool acd;
} connman_settings = {
.bg_scan = true,
.pref_timeservers = NULL,
@@ -101,6 +102,7 @@ static struct {
.vendor_class_id = NULL,
.enable_online_check = true,
.auto_connect_roaming_services = false,
+ .acd = false,
};
#define CONF_BG_SCAN "BackgroundScanning"
@@ -121,6 +123,7 @@ static struct {
#define CONF_VENDOR_CLASS_ID "VendorClassID"
#define CONF_ENABLE_ONLINE_CHECK "EnableOnlineCheck"
#define CONF_AUTO_CONNECT_ROAMING_SERVICES "AutoConnectRoamingServices"
+#define CONF_ACD "AddressConflictDetection"
static const char *supported_options[] = {
CONF_BG_SCAN,
@@ -141,6 +144,7 @@ static const char *supported_options[] = {
CONF_VENDOR_CLASS_ID,
CONF_ENABLE_ONLINE_CHECK,
CONF_AUTO_CONNECT_ROAMING_SERVICES,
+ CONF_ACD,
NULL
};
@@ -432,6 +436,12 @@ static void parse_config(GKeyFile *config)
connman_settings.auto_connect_roaming_services = boolean;
g_clear_error(&error);
+
+ boolean = __connman_config_get_bool(config, "General", CONF_ACD,
&error);
+ if (!error)
+ connman_settings.acd = boolean;
+
+ g_clear_error(&error);
}
static int config_init(const char *file)
@@ -645,6 +655,9 @@ bool connman_setting_get_bool(const char *key)
if (g_str_equal(key, CONF_AUTO_CONNECT_ROAMING_SERVICES))
return connman_settings.auto_connect_roaming_services;
+ if (g_str_equal(key, CONF_ACD))
+ return connman_settings.acd;
+
return false;
}
diff --git a/src/network.c b/src/network.c
index 4757d0d..6df1d01 100644
--- a/src/network.c
+++ b/src/network.c
@@ -26,6 +26,7 @@
#include <errno.h>
#include <string.h>
+#include <connman/acd.h>
#include "connman.h"
/*
@@ -67,6 +68,7 @@ struct connman_network {
int index;
int router_solicit_count;
int router_solicit_refresh_count;
+ acd_host *acdhost;
struct connman_network_driver *driver;
void *driver_data;
@@ -154,6 +156,24 @@ static void set_configuration(struct connman_network
*network,
type);
}
+static int start_acd(struct connman_network *network)
+{
+ struct connman_service *service;
+ struct connman_ipconfig *ipconfig_ipv4;
+
+ service = connman_service_lookup_from_network(network);
+ if (!service)
+ return -EINVAL;
+
+ ipconfig_ipv4 = __connman_service_get_ip4config(service);
+ if (!ipconfig_ipv4) {
+ connman_error("Service has no IPv4 configuration");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static void dhcp_success(struct connman_network *network)
{
struct connman_service *service;
@@ -171,6 +191,14 @@ static void dhcp_success(struct connman_network *network)
if (!ipconfig_ipv4)
return;
+ if (connman_setting_get_bool("AddressConflictDetection")) {
+ err = start_acd(network);
+ if (!err)
+ return;
+
+ /* On error proceed without ACD. */
+ }
+
err = __connman_ipconfig_address_add(ipconfig_ipv4);
if (err < 0)
goto err;
@@ -237,6 +265,14 @@ static int set_connected_manual(struct connman_network
*network)
if (!__connman_ipconfig_get_local(ipconfig))
__connman_service_read_ip4config(service);
+ if (connman_setting_get_bool("AddressConflictDetection")) {
+ err = start_acd(network);
+ if (!err)
+ return 0;
+
+ /* On error proceed without ACD. */
+ }
+
err = __connman_ipconfig_address_add(ipconfig);
if (err < 0)
goto err;
@@ -920,6 +956,7 @@ static void network_destruct(struct connman_network
*network)
g_free(network->node);
g_free(network->name);
g_free(network->identifier);
+ g_free(network->acdhost);
network->device = NULL;
@@ -955,6 +992,7 @@ struct connman_network *connman_network_create(const char
*identifier,
network->type = type;
network->identifier = ident;
+ network->acdhost = NULL;
network_list = g_slist_prepend(network_list, network);
--
2.7.4
------------------------------
Message: 2
Date: Wed, 11 Apr 2018 16:00:34 +0200
From: Christian Spielberger <[email protected]>
To: Daniel Wagner <[email protected]>
Cc: [email protected], Christian Spielberger
<[email protected]>
Subject: [PATCH 14/27] acd: add acdhost_start and acdhost_stop
Message-ID:
<1523455247-5877-15-git-send-email-christian.spielber...@gmail.com>
Adds functions for starting and stopping ACD.
---
include/acd.h | 2 ++
src/acd.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/network.c | 3 +++
3 files changed, 59 insertions(+)
diff --git a/include/acd.h b/include/acd.h
index dbef0b3..24b4707 100644
--- a/include/acd.h
+++ b/include/acd.h
@@ -35,6 +35,8 @@ struct _acd_host;
typedef struct _acd_host acd_host;
acd_host *acdhost_new(int ifindex);
+int acdhost_start(acd_host *acd, uint32_t ip);
+void acdhost_stop(acd_host *acd);
typedef void (*ACDHostEventFunc) (acd_host *acd, gpointer user_data);
diff --git a/src/acd.c b/src/acd.c
index f1e0c6f..fcc955c 100644
--- a/src/acd.c
+++ b/src/acd.c
@@ -280,3 +280,57 @@ static gboolean send_announce_packet(gpointer acd_data)
NULL);
return TRUE;
}
+
+int acdhost_start(acd_host *acd, uint32_t ip)
+{
+ guint timeout;
+ int err;
+
+ remove_timeout(acd);
+
+ err = start_listening(acd);
+ if (err)
+ return err;
+
+ acd->retry_times = 0;
+ acd->requested_ip = ip;
+
+ /* First wait a random delay to avoid storm of ARP requests on boot */
+ timeout = random_delay_ms(PROBE_WAIT);
+ acd->state = ACD_PROBE;
+
+ acd->timeout = g_timeout_add_full(G_PRIORITY_HIGH,
+ timeout,
+ acd_probe_timeout,
+ acd,
+ NULL);
+ return 0;
+}
+
+void acdhost_stop(acd_host *acd)
+{
+
+ stop_listening(acd);
+
+ remove_timeout(acd);
+
+ if (acd->listener_watch > 0) {
+ g_source_remove(acd->listener_watch);
+ acd->listener_watch = 0;
+ }
+
+ acd->state = ACD_PROBE;
+ acd->retry_times = 0;
+ acd->requested_ip = 0;
+}
+
+static gboolean acd_defend_timeout(gpointer acd_data)
+{
+}
+
+static gboolean acd_announce_timeout(gpointer acd_data)
+{
+}
+
+static int acd_recv_arp_packet(acd_host *acd) {
+}
diff --git a/src/network.c b/src/network.c
index 6df1d01..acf4179 100644
--- a/src/network.c
+++ b/src/network.c
@@ -1537,6 +1537,9 @@ int __connman_network_disconnect(struct connman_network
*network)
DBG("network %p", network);
+ if (network->acdhost)
+ acdhost_stop(network->acdhost);
+
if (!network->connected && !network->connecting &&
!network->associating)
return -ENOTCONN;
--
2.7.4
------------------------------
Message: 3
Date: Wed, 11 Apr 2018 16:00:31 +0200
From: Christian Spielberger <[email protected]>
To: Daniel Wagner <[email protected]>
Cc: [email protected], Christian Spielberger
<[email protected]>
Subject: [PATCH 11/27] acd: add send_probe_packet
Message-ID:
<1523455247-5877-12-git-send-email-christian.spielber...@gmail.com>
Adds a function for sending ARP probe packets and a timeout callback function
for invoking send_probe_packet repeatedly.
---
src/acd.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 52 insertions(+)
diff --git a/src/acd.c b/src/acd.c
index 7dcad2e..173ce47 100644
--- a/src/acd.c
+++ b/src/acd.c
@@ -22,9 +22,11 @@
#include <connman/inet.h>
#include <glib.h>
#include "src/shared/arp.h"
+#include "src/shared/random.h"
#include <errno.h>
#include <unistd.h>
#include <stdarg.h>
+#include <stdio.h>
typedef enum _acd_state {
ACD_PROBE,
@@ -53,6 +55,8 @@ static void stop_listening(acd_host *acd);
static gboolean acd_listener_event(GIOChannel *channel, GIOCondition condition,
gpointer acd_data);
static int acd_recv_arp_packet(acd_host *acd);
+static void send_probe_packet(gpointer acd_data);
+static gboolean acd_probe_timeout(gpointer acd_data);
static void debug(acd_host *acd, const char *format, ...)
{
@@ -175,3 +179,51 @@ static gboolean acd_listener_event(GIOChannel *channel,
GIOCondition condition,
return TRUE;
}
+static void send_probe_packet(gpointer acd_data)
+{
+ guint timeout;
+ acd_host *acd = acd_data;
+
+ debug(acd, "sending ARP probe request");
+ if (acd->retry_times == 1) {
+ acd->state = ACD_PROBE;
+ start_listening(acd);
+ }
+ send_arp_packet(acd->mac_address, 0,
+ acd->requested_ip, acd->ifindex);
+
+ if (acd->retry_times < PROBE_NUM) {
+ /* Add a random timeout in range of PROBE_MIN to PROBE_MAX. */
+ timeout = random_delay_ms(PROBE_MAX-PROBE_MIN);
+ timeout += PROBE_MIN * 1000;
+ } else
+ timeout = ANNOUNCE_WAIT * 1000;
+
+ acd->timeout = g_timeout_add_full(G_PRIORITY_HIGH,
+ timeout,
+ acd_probe_timeout,
+ acd,
+ NULL);
+}
+
+static gboolean acd_probe_timeout(gpointer acd_data)
+{
+ acd_host *acd = acd_data;
+
+ acd->timeout = 0;
+
+ debug(acd, "acd probe timeout (retries %d)", acd->retry_times);
+ if (acd->retry_times == PROBE_NUM) {
+ acd->state = ACD_ANNOUNCE;
+ acd->retry_times = 1;
+
+ send_announce_packet(acd);
+ return FALSE;
+ }
+
+ acd->retry_times++;
+ send_probe_packet(acd);
+
+ return FALSE;
+}
+
--
2.7.4
------------------------------
Message: 4
Date: Wed, 11 Apr 2018 16:00:32 +0200
From: Christian Spielberger <[email protected]>
To: Daniel Wagner <[email protected]>
Cc: [email protected], Christian Spielberger
<[email protected]>
Subject: [PATCH 12/27] acd: add send_announce_packet
Message-ID:
<1523455247-5877-13-git-send-email-christian.spielber...@gmail.com>
Adding function for sending announce packets and only function headers of
the timeout callbacks acd_announce_timeout for repeated announce packets and
acd_defend_timeout for switching from DEFEND state back to MONITOR state.
---
src/acd.c | 39 +++++++++++++++++++++++++++++++++++++++
1 file changed, 39 insertions(+)
diff --git a/src/acd.c b/src/acd.c
index 173ce47..8d3e121 100644
--- a/src/acd.c
+++ b/src/acd.c
@@ -57,6 +57,9 @@ static gboolean acd_listener_event(GIOChannel *channel,
GIOCondition condition,
static int acd_recv_arp_packet(acd_host *acd);
static void send_probe_packet(gpointer acd_data);
static gboolean acd_probe_timeout(gpointer acd_data);
+static gboolean send_announce_packet(gpointer acd_data);
+static gboolean acd_announce_timeout(gpointer acd_data);
+static gboolean acd_defend_timeout(gpointer acd_data);
static void debug(acd_host *acd, const char *format, ...)
{
@@ -114,6 +117,14 @@ error:
return NULL;
}
+static void remove_timeout(acd_host *acd)
+{
+ if (acd->timeout > 0)
+ g_source_remove(acd->timeout);
+
+ acd->timeout = 0;
+}
+
static int start_listening(acd_host *acd)
{
GIOChannel *listener_channel;
@@ -185,6 +196,7 @@ static void send_probe_packet(gpointer acd_data)
acd_host *acd = acd_data;
debug(acd, "sending ARP probe request");
+ remove_timeout(acd);
if (acd->retry_times == 1) {
acd->state = ACD_PROBE;
start_listening(acd);
@@ -227,3 +239,30 @@ static gboolean acd_probe_timeout(gpointer acd_data)
return FALSE;
}
+static gboolean send_announce_packet(gpointer acd_data)
+{
+ acd_host *acd = acd_data;
+
+ debug(acd, "sending ACD announce request");
+
+ send_arp_packet(acd->mac_address,
+ acd->requested_ip,
+ acd->requested_ip,
+ acd->ifindex);
+
+ remove_timeout(acd);
+
+ if (acd->state == ACD_DEFEND)
+ acd->timeout = g_timeout_add_seconds_full(G_PRIORITY_HIGH,
+ DEFEND_INTERVAL,
+ acd_defend_timeout,
+ acd,
+ NULL);
+ else
+ acd->timeout = g_timeout_add_seconds_full(G_PRIORITY_HIGH,
+ ANNOUNCE_INTERVAL,
+ acd_announce_timeout,
+ acd,
+ NULL);
+ return TRUE;
+}
--
2.7.4
------------------------------
Message: 5
Date: Wed, 11 Apr 2018 16:00:33 +0200
From: Christian Spielberger <[email protected]>
To: Daniel Wagner <[email protected]>
Cc: [email protected], Christian Spielberger
<[email protected]>
Subject: [PATCH 13/27] acd: add callback function pointers
Message-ID:
<1523455247-5877-14-git-send-email-christian.spielber...@gmail.com>
Adds the callback functions for higher level address conflict handling.
ipv4_available_cb will be called if there was no address conflict detected.
ipv4_lost_cb will be called if another host is using our IPv4 address and
defending was not successfull.
ipv4_conflict_cb will be called if ACD detected a conflict during probing and
there had been less than MAX_CONFLICTS conflicts.
ipv4_max_conflicts_cb will be called if ACD detected a conflict during probing
and there had been at least MAX_CONFLICTS conflicts.
---
include/acd.h | 3 +++
src/acd.c | 14 ++++++++++++++
2 files changed, 17 insertions(+)
diff --git a/include/acd.h b/include/acd.h
index 08f9ec9..dbef0b3 100644
--- a/include/acd.h
+++ b/include/acd.h
@@ -24,6 +24,7 @@
#define __CONNMAN_ACD_H
#include <stdint.h>
+#include <glib.h>
#ifdef __cplusplus
extern "C" {
@@ -35,6 +36,8 @@ typedef struct _acd_host acd_host;
acd_host *acdhost_new(int ifindex);
+typedef void (*ACDHostEventFunc) (acd_host *acd, gpointer user_data);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/acd.c b/src/acd.c
index 8d3e121..f1e0c6f 100644
--- a/src/acd.c
+++ b/src/acd.c
@@ -48,6 +48,15 @@ struct _acd_host {
unsigned int conflicts;
guint timeout;
guint listener_watch;
+
+ ACDHostEventFunc ipv4_available_cb;
+ gpointer ipv4_available_data;
+ ACDHostEventFunc ipv4_lost_cb;
+ gpointer ipv4_lost_data;
+ ACDHostEventFunc ipv4_conflict_cb;
+ gpointer ipv4_conflict_data;
+ ACDHostEventFunc ipv4_max_conflicts_cb;
+ gpointer ipv4_max_conflicts_data;
};
static int start_listening(acd_host *acd);
@@ -109,6 +118,11 @@ acd_host *acdhost_new(int ifindex)
acd->listener_watch = 0;
acd->retry_times = 0;
+ acd->ipv4_available_cb = NULL;
+ acd->ipv4_lost_cb = NULL;
+ acd->ipv4_conflict_cb = NULL;
+ acd->ipv4_max_conflicts_cb = NULL;
+
return acd;
error:
--
2.7.4
------------------------------
Subject: Digest Footer
_______________________________________________
connman mailing list
[email protected]
https://lists.01.org/mailman/listinfo/connman
------------------------------
End of connman Digest, Vol 30, Issue 6
**************************************