Send connman mailing list submissions to
        connman@lists.01.org

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
        connman-requ...@lists.01.org

You can reach the person managing the list at
        connman-ow...@lists.01.org

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 <christian.spielber...@gmail.com>
To: Daniel Wagner <w...@monom.org>
Cc: connman@lists.01.org, Christian Spielberger
        <christian.spielber...@gmail.com>
Subject: [PATCH 07/27] Add Address Conflict Detection support (RFC
        5227)
Message-ID:
        <1523455247-5877-8-git-send-email-christian.spielber...@gmail.com>

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 <christian.spielber...@gmail.com>
To: Daniel Wagner <w...@monom.org>
Cc: connman@lists.01.org, Christian Spielberger
        <christian.spielber...@gmail.com>
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 <christian.spielber...@gmail.com>
To: Daniel Wagner <w...@monom.org>
Cc: connman@lists.01.org, Christian Spielberger
        <christian.spielber...@gmail.com>
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 <christian.spielber...@gmail.com>
To: Daniel Wagner <w...@monom.org>
Cc: connman@lists.01.org, Christian Spielberger
        <christian.spielber...@gmail.com>
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 <christian.spielber...@gmail.com>
To: Daniel Wagner <w...@monom.org>
Cc: connman@lists.01.org, Christian Spielberger
        <christian.spielber...@gmail.com>
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
connman@lists.01.org
https://lists.01.org/mailman/listinfo/connman


------------------------------

End of connman Digest, Vol 30, Issue 6
**************************************

Reply via email to