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 5/6] Added logic to perform perpetual online checks
      ([email protected])
   2. [PATCH 6/6] Added timeout to socket connections
      ([email protected])


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

Message: 1
Date: Tue, 27 Aug 2019 15:30:45 +0300
From: [email protected]
To: [email protected]
Cc: Aleksandar Mitev <[email protected]>
Subject: [PATCH 5/6] Added logic to perform perpetual online checks
Message-ID: <[email protected]>

From: Aleksandar Mitev <[email protected]>

The feature activates when online state is reached and performs
regular checks whether online state is still maintained by the
services (default every 5 minutes). In the case then the
online check fails the serice state is downgrated to Ready
to give the chance for a switchover with another service.
---
 src/service.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 77 insertions(+), 4 deletions(-)

diff --git a/src/service.c b/src/service.c
index 7051165b..c7cb0ce0 100644
--- a/src/service.c
+++ b/src/service.c
@@ -3441,17 +3441,23 @@ int __connman_service_reset_ipconfig(struct 
connman_service *service,
 #define ONLINE_CHECK_INITIAL_INTERVAL 1
 #define ONLINE_CHECK_MAX_INTERVAL 12
 
-void __connman_service_wispr_start(struct connman_service *service,
+static void reset_online_recheck_interval(struct connman_service *service,
                                        enum connman_ipconfig_type type)
 {
-       DBG("service %p type %s", service, 
__connman_ipconfig_type2string(type));
-
        if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
                service->online_check_interval_ipv4 =
                                        ONLINE_CHECK_INITIAL_INTERVAL;
        else
                service->online_check_interval_ipv6 =
                                        ONLINE_CHECK_INITIAL_INTERVAL;
+}
+
+void __connman_service_wispr_start(struct connman_service *service,
+                                       enum connman_ipconfig_type type)
+{
+       DBG("service %p type %s", service, 
__connman_ipconfig_type2string(type));
+
+       reset_online_recheck_interval(service, type);
 
        __connman_wispr_start(service, type);
 }
@@ -6040,18 +6046,64 @@ static gboolean redo_wispr_ipv6(gpointer user_data)
        return FALSE;
 }
 
+/* When the online state is once reached perform fruther
+ * checks less frequently
+ */
+#define ONLINE_CHECK_REGULAR_INTERVAL 300
+
+static int __connman_service_online_perform_regular(struct connman_service 
*service,
+                                       enum connman_ipconfig_type type)
+{
+       GSourceFunc redo_func;
+       guint retry_interval = ONLINE_CHECK_REGULAR_INTERVAL;
+
+       /* no use of double starting the check */
+       if (service->online_timeout != 0)
+               return 0;
+
+       if (type == CONNMAN_IPCONFIG_TYPE_IPV4) {
+               redo_func = redo_wispr_ipv4;
+       } else {
+               redo_func = redo_wispr_ipv6;
+       }
+       reset_online_recheck_interval(service, type);
+
+       DBG("service %p (%s) will be rechecked for internet connectivity in 
%ds",
+               service, service ? service->identifier : NULL, retry_interval);
+
+       service->online_timeout =
+               g_timeout_add_seconds(retry_interval, redo_func, 
connman_service_ref(service));
+
+       return 0;
+}
+
+static gboolean downgrade_state_handler(gpointer user_data)
+{
+       struct connman_service *service = user_data;
+
+       connman_warn("Downgrading service %s for online check did not pass",
+               service ? service->identifier : NULL);
+
+       downgrade_state(service);
+
+       return FALSE;
+}
+
 int __connman_service_online_check_failed(struct connman_service *service,
                                        enum connman_ipconfig_type type)
 {
        GSourceFunc redo_func;
        int *interval;
+       enum connman_service_state curr_state;
 
        if (type == CONNMAN_IPCONFIG_TYPE_IPV4) {
                interval = &service->online_check_interval_ipv4;
                redo_func = redo_wispr_ipv4;
+               curr_state = service->state_ipv4;
        } else {
                interval = &service->online_check_interval_ipv6;
                redo_func = redo_wispr_ipv6;
+               curr_state = service->state_ipv6;
        }
 
        DBG("service %p type %s interval %d", service,
@@ -6065,6 +6117,12 @@ int __connman_service_online_check_failed(struct 
connman_service *service,
         */
        if (*interval < ONLINE_CHECK_MAX_INTERVAL)
                (*interval)++;
+       else {
+               if(curr_state == CONNMAN_SERVICE_STATE_ONLINE) {
+                       g_idle_add(downgrade_state_handler, service);
+                       return 0;
+               }
+       }
 
        return EAGAIN;
 }
@@ -6132,8 +6190,17 @@ int __connman_service_ipconfig_indicate_state(struct 
connman_service *service,
        }
 
        /* Any change? */
-       if (old_state == new_state)
+       if (old_state == new_state) {
+               /* continuous online check requires restart of the check at 
regular intervals */
+               if ((new_state == CONNMAN_SERVICE_STATE_ONLINE) &&
+                       service->perpetual_online_check ) {
+                       connman_info("Online check continues for %s.\n", 
service->name);
+                       __connman_service_online_perform_regular(service, type);
+                       service_indicate_state(service);
+               }
+
                return -EALREADY;
+       }
 
        DBG("service %p (%s) old state %d (%s) new state %d (%s) type %d (%s)",
                service, service ? service->identifier : NULL,
@@ -6162,6 +6229,12 @@ int __connman_service_ipconfig_indicate_state(struct 
connman_service *service,
                set_mdns(service, service->mdns_config);
                break;
        case CONNMAN_SERVICE_STATE_ONLINE:
+               /* will reach here once, as next time should be from
+                * ONLINE to ONLINE, there is a special check above
+                */
+               connman_info("Online state reached for %s.\n", service->name);
+               if (service->perpetual_online_check)
+                       __connman_service_online_perform_regular(service, type);
                break;
        case CONNMAN_SERVICE_STATE_DISCONNECT:
                if (service->state == CONNMAN_SERVICE_STATE_IDLE)
-- 
2.17.1



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

Message: 2
Date: Tue, 27 Aug 2019 15:30:46 +0300
From: [email protected]
To: [email protected]
Cc: Aleksandar Mitev <[email protected]>
Subject: [PATCH 6/6] Added timeout to socket connections
Message-ID: <[email protected]>

From: Aleksandar Mitev <[email protected]>

By default, sockets timeout after the system defined time which is
too much all the timers in connman.
This patch helps make online checks in a deterministic fashion.
---
 gweb/gweb.c | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/gweb/gweb.c b/gweb/gweb.c
index 393afe0a..5743042f 100644
--- a/gweb/gweb.c
+++ b/gweb/gweb.c
@@ -77,6 +77,7 @@ struct web_session {
        GIOChannel *transport_channel;
        guint transport_watch;
        guint send_watch;
+       guint timeout_timer;
 
        guint resolv_action;
        guint address_action;
@@ -164,6 +165,8 @@ static void free_session(struct web_session *session)
 
        web = session->web;
 
+       debug(web, "freeing session %p", session);
+
        if (session->address_action > 0)
                g_source_remove(session->address_action);
 
@@ -176,6 +179,9 @@ static void free_session(struct web_session *session)
        if (session->send_watch > 0)
                g_source_remove(session->send_watch);
 
+       if (session->timeout_timer > 0)
+               g_source_remove(session->timeout_timer);
+
        if (session->transport_channel)
                g_io_channel_unref(session->transport_channel);
 
@@ -1032,10 +1038,28 @@ static inline int bind_socket(int sk, int index, int 
family)
        return err;
 }
 
+static gboolean socket_timeout_handler(gpointer user_data)
+{
+       struct web_session *session = user_data;
+       int fd;
+
+       if (session->transport_channel) {
+               debug(session->web, "No response, closing the socket");
+               fd = g_io_channel_unix_get_fd(session->transport_channel);
+               g_io_channel_shutdown(session->transport_channel, TRUE, NULL);
+               close(fd);
+       }
+
+       session->timeout_timer = 0;
+       return FALSE;
+}
+
 static int connect_session_transport(struct web_session *session)
 {
        GIOFlags flags;
        int sk;
+       /* TODO: not sure if this is optimal enough */
+       const int socket_timeout = 20;
 
        sk = socket(session->addr->ai_family, SOCK_STREAM | SOCK_CLOEXEC,
                        IPPROTO_TCP);
@@ -1090,6 +1114,14 @@ static int connect_session_transport(struct web_session 
*session)
                                G_IO_OUT | G_IO_HUP | G_IO_NVAL | G_IO_ERR,
                                                send_data, session);
 
+       debug(session->web, "Setting timeout to the socket to %ds", 
socket_timeout);
+       /* TODO: if this is not effective, resort to using mutexes
+        * Assign lower priority to this callback than that of the watch 
functions
+        * as we don't want the timeout to possibly interrupt last moment 
read/writes
+        */
+       session->timeout_timer = 
g_timeout_add_seconds_full(G_PRIORITY_DEFAULT_IDLE,
+                               socket_timeout, socket_timeout_handler, 
session, NULL);
+
        return 0;
 }
 
-- 
2.17.1



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

Subject: Digest Footer

_______________________________________________
connman mailing list
[email protected]
https://lists.01.org/mailman/listinfo/connman


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

End of connman Digest, Vol 46, Issue 26
***************************************

Reply via email to