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
***************************************