Send connman mailing list submissions to
[email protected]
To subscribe or unsubscribe 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] vpnc: Implement disconnect function to cancel queued VPN agent msg
(Jussi Laakkonen)
2. High CPU useage during DNS resolution over TCP
(Blanquicet Melendez Jose (M))
3. [PATCH 0/7] Rewrite OpenConnect plugin and enhance support for VPN auth
errors
(Jussi Laakkonen)
4. [PATCH 3/7] doc: Add VpnAgent.AuthFailure to VPN agent API documentation
(Jussi Laakkonen)
5. [PATCH 2/7] vpn-agent: Implement function to add auth failures to VPN
agent msg
(Jussi Laakkonen)
6. [PATCH 4/7] vpn-provider: Implement setting string to bool conversion
function
(Jussi Laakkonen)
7. [PATCH 1/7] vpn-provider: Implement simple connection and auth error
counters
(Jussi Laakkonen)
----------------------------------------------------------------------
Date: Wed, 2 Oct 2019 12:13:39 +0300
From: Jussi Laakkonen <[email protected]>
Subject: [PATCH] vpnc: Implement disconnect function to cancel queued
VPN agent msg
To: [email protected]
Message-ID: <[email protected]>
Queued VPN agent messages must be canceled if the plugin timeouts
without starting the process. This fixes the issue of having multiple
VPN agent queries stacked on another in such scenario, where VPNC is
awaiting for user input.
---
vpn/plugins/vpnc.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/vpn/plugins/vpnc.c b/vpn/plugins/vpnc.c
index cb24a2b4..808c36cd 100644
--- a/vpn/plugins/vpnc.c
+++ b/vpn/plugins/vpnc.c
@@ -815,6 +815,14 @@ static int vc_connect(struct vpn_provider *provider,
return run_connect(data);
}
+static void vc_disconnect(struct vpn_provider *provider)
+{
+ if (!provider)
+ return;
+
+ connman_agent_cancel(provider);
+}
+
static int vc_error_code(struct vpn_provider *provider, int exit_code)
{
switch (exit_code) {
@@ -850,6 +858,7 @@ static int vc_device_flags(struct vpn_provider *provider)
static struct vpn_driver vpn_driver = {
.notify = vc_notify,
.connect = vc_connect,
+ .disconnect = vc_disconnect,
.error_code = vc_error_code,
.save = vc_save,
.device_flags = vc_device_flags,
--
2.20.1
------------------------------
Date: Wed, 2 Oct 2019 13:17:06 +0000
From: "Blanquicet Melendez Jose (M)" <[email protected]>
Subject: High CPU useage during DNS resolution over TCP
To: "[email protected]" <[email protected]>
Message-ID: <[email protected]>
Content-Type: text/plain; charset="us-ascii"
Hi everyone,
We are currently using ConnMan with tethering active on WIFI technology and an
online service that allows devices connected to WIFI AP to access Internet.
In such situation, ConnMan works as DNS-Proxy given that devices connected to
WIFI AP use it as DNS resolver. It means that ConnMan receives DNS requests and
it has to process and forward them to DNS servers of online service.
Now, we noticed that when DNS requests uses TCP instead of UDP (There are
specific cases when TCP needs to be use, see RFC7766 [1]), ConnMan takes too
much CPU resources. For example, if a tool like top is used to monitor CPU
load, it is possible to see how ConnMan quickly starts taking more and more
resources, arriving even to ~60% of CPU load on an embedded system where a DNS
request over UDP does not reach neither 5%.
Digging into the DNS-Proxy implementation on ConnMan, we noticed a difference
between TCP and UDP implementation. Unlike UDP, the TCP socket towards DNS
server is configured to be called each time data can be written (GLib watch
condition G_IO_OUT). The problem is that using such configuration, the callback
is triggered each time data can be written without blocking, which means many
many times in a second. According to our analysis, that is what could be taking
that much CPU resources from the moment socket is open (DNS request from
devices connected to tethering Technology or from target itself), until socket
is closed (DNS server responses or 30 seconds of idle-timeout):
src/dnsproxy.c:2510
if (data->protocol == IPPROTO_TCP) {
g_io_channel_set_flags(data->channel, G_IO_FLAG_NONBLOCK, NULL);
data->watch = g_io_add_watch(data->channel,
G_IO_OUT | G_IO_IN | G_IO_HUP | G_IO_NVAL | G_IO_ERR,
tcp_server_event, data);
data->timeout = g_timeout_add_seconds(30, tcp_idle_timeout,
data);
} else
data->watch = g_io_add_watch(data->channel,
G_IO_IN | G_IO_NVAL | G_IO_ERR | G_IO_HUP,
udp_server_event, data);
Has someone else seen this? What do you think about our analysis?
BTW, for testing, DNS requests over TCP can be generated using "vc" option of
nslookup tool.
[1] https://tools.ietf.org/html/rfc7766
Thanks,
Jose
VISITA IL NOSTRO SITO WEB! - VISIT OUR WEB SITE! www.magnetimarelli.com
Confidential Notice: This message - including its attachments - may contain
proprietary, confidential and/or legally protected information and is intended
solely for the use of the designated addressee(s) above. If you are not the
intended recipient be aware that any downloading, copying, disclosure,
distribution or use of the contents of the above information is strictly
prohibited. If you have received this communication by mistake, please forward
the message back to the sender at the email address above, delete the message
from all mailboxes and any other electronic storage medium and destroy all
copies. Disclaimer Notice: Internet communications cannot be guaranteed to be
safe or error-free. Therefore we do not assure that this message is complete or
accurate and we do not accept liability for any errors or omissions in the
contents of this message.
------------------------------
Date: Wed, 2 Oct 2019 17:16:42 +0300
From: Jussi Laakkonen <[email protected]>
Subject: [PATCH 0/7] Rewrite OpenConnect plugin and enhance support
for VPN auth errors
To: [email protected]
Message-ID: <[email protected]>
This set of patches contains almost complete rewrite of OpenConnect VPN plugin,
introduces a method for informing VPN agent about authentication errors and
adds support for easier use of boolean type setting strings.
First of all, as the biggest change, OpenConnect VPN plugin is rewritten to
support the different authentication methods, which is configurable in provider
settings. If the configuration is omitted, cookie based authentication is set
as default. Support for automatic cookie (first use credentials to get cookie
and then connect with the cookie), credentials and separate public key with
private key and PKCS#12 credential authentication is introduced. Credentials
and PKCS#12 password is queried from VPN agent. Also support for the three
openconnect protocols is added also as provider settings for the OpenConnect
plugin. New options for OpenConnect are added as well to support allowing self
signed certificates and to toggle connection parameters, which may be required
with different server setups.
Second, the authentication and connection errors are tracked by vpn-provider.c
when vpn_provider_indicate_error() is called with appropriate error code. These
errors can be utilized in VPN plugins to indicate VPN agent that saved
authentication credentials should be cleared. After succesful connection or
after saving provider settings the error counters are cleared. Main reason for
implementing these into provider is that saving the values in plugin private
data would be cleared after the connection is terminated, and provider is more
permanent during the runtime of vpnd.
And last, a new function to better support setting strings expected to be
boolean in value ("true" or "false") is implemented. This function can be used
to check if the setting string is explicitly the desired boolean value as the
default value in case of missing or invalid value is to be given.
Jussi Laakkonen (7):
vpn-provider: Implement simple connection and auth error counters
vpn-agent: Implement function to add auth failures to VPN agent msg
doc: Add VpnAgent.AuthFailure to VPN agent API documentation
vpn-provider: Implement setting string to bool conversion function
openconnect: Rewrite plugin to support more auth methods and protocols
doc: Add new OpenConnect PKCS#12 parameters to VPN agent API
doc: Add new OpenConnect configuration options to VPN config format
doc/vpn-agent-api.txt | 16 +
doc/vpn-config-format.txt | 77 ++-
vpn/plugins/openconnect.c | 1086 ++++++++++++++++++++++++++++++++-----
vpn/vpn-agent.c | 53 ++
vpn/vpn-agent.h | 3 +
vpn/vpn-provider.c | 54 +-
vpn/vpn-provider.h | 8 +
7 files changed, 1141 insertions(+), 156 deletions(-)
--
2.20.1
------------------------------
Date: Wed, 2 Oct 2019 17:16:45 +0300
From: Jussi Laakkonen <[email protected]>
Subject: [PATCH 3/7] doc: Add VpnAgent.AuthFailure to VPN agent API
documentation
To: [email protected]
Message-ID: <[email protected]>
Document new informational string field VpnAgent.Authfailure.
---
doc/vpn-agent-api.txt | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/doc/vpn-agent-api.txt b/doc/vpn-agent-api.txt
index 72bee9db..26c732d1 100644
--- a/doc/vpn-agent-api.txt
+++ b/doc/vpn-agent-api.txt
@@ -96,6 +96,13 @@ Fields string Username
Return the final VPN server to use after possible
web authentication logins, selections and redirections.
+ string VpnAgent.AuthFailure
+
+ Informational field that can be used to indicate VPN
+ agent that previous authentication has failed and new
+ credentials should be requested from user. Additional
+ information about the failure can be added as "Value".
+
Arguments string Type
Contains the type of a field. For example "password",
--
2.20.1
------------------------------
Date: Wed, 2 Oct 2019 17:16:44 +0300
From: Jussi Laakkonen <[email protected]>
Subject: [PATCH 2/7] vpn-agent: Implement function to add auth
failures to VPN agent msg
To: [email protected]
Message-ID: <[email protected]>
A new field for VPN Agent API, "VpnAgent.AuthFailure" is introduced with
this change and a function to set the error with optional additional
information about failure is added. This field is to be used for
indicating VPN agent that authentication credentials should be cleared
if they are saved in order to request them again from the user.
If the given addtional information is not set, VPN provider settings is
queried using the key "VpnAgent.AuthFailure". The value should be run
time only and never to be stored within provider settings file.
---
vpn/vpn-agent.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++
vpn/vpn-agent.h | 3 +++
2 files changed, 56 insertions(+)
diff --git a/vpn/vpn-agent.c b/vpn/vpn-agent.c
index be9774a2..a06f8c2d 100644
--- a/vpn/vpn-agent.c
+++ b/vpn/vpn-agent.c
@@ -146,6 +146,59 @@ void vpn_agent_append_user_info(DBusMessageIter *iter,
&data);
}
+struct auth_failure_data {
+ struct vpn_provider *provider;
+ const char* type_str;
+ const char *key;
+ const char* str;
+};
+
+static void request_input_append_failure(DBusMessageIter *iter,
+ void *user_data)
+{
+ struct auth_failure_data *data;
+ const char *str;
+
+ data = user_data;
+
+ connman_dbus_dict_append_basic(iter, "Type",
+ DBUS_TYPE_STRING, &data->type_str);
+ str = "informational";
+ connman_dbus_dict_append_basic(iter, "Requirement",
+ DBUS_TYPE_STRING, &str);
+
+ str = data->str;
+
+ /* Try to get information from provider about error */
+ if (!str)
+ str = vpn_provider_get_string(data->provider, data->key);
+
+ if (str)
+ connman_dbus_dict_append_basic(iter, "Value",
+ DBUS_TYPE_STRING, &str);
+}
+
+void vpn_agent_append_auth_failure(DBusMessageIter *iter,
+ struct vpn_provider *provider,
+ const char* information)
+{
+ struct auth_failure_data data;
+ unsigned int value;
+
+ /* Skip if there are no auth errors */
+ value = vpn_provider_get_authentication_errors(provider);
+ if (!value)
+ return;
+
+ data.provider = provider;
+ data.type_str = "string";
+ data.key = "VpnAgent.AuthFailure";
+ data.str = information;
+
+ connman_dbus_dict_append_dict(iter, data.key,
+ request_input_append_failure, &data);
+}
+
int vpn_agent_check_and_process_reply_error(DBusMessage *reply,
struct vpn_provider *provider,
struct connman_task *task,
diff --git a/vpn/vpn-agent.h b/vpn/vpn-agent.h
index be7f9dd9..1dcaa4ec 100644
--- a/vpn/vpn-agent.h
+++ b/vpn/vpn-agent.h
@@ -38,6 +38,9 @@ bool vpn_agent_check_reply_has_dict(DBusMessage *reply);
void vpn_agent_append_user_info(DBusMessageIter *iter,
struct vpn_provider *provider,
const char *username_str);
+void vpn_agent_append_auth_failure(DBusMessageIter *iter,
+ struct vpn_provider *provider,
+ const char *information);
int vpn_agent_check_and_process_reply_error(DBusMessage *reply,
struct vpn_provider *provider,
struct connman_task *task,
--
2.20.1
------------------------------
Date: Wed, 2 Oct 2019 17:16:46 +0300
From: Jussi Laakkonen <[email protected]>
Subject: [PATCH 4/7] vpn-provider: Implement setting string to bool
conversion function
To: [email protected]
Message-ID: <[email protected]>
Add vpn_provider_get_boolean() to do conversion for saved setting
strings expected to be "true" or "false" in value. Given default value
is returned in case of invalid or missing string.
---
vpn/vpn-provider.c | 20 ++++++++++++++++++++
vpn/vpn-provider.h | 2 ++
2 files changed, 22 insertions(+)
diff --git a/vpn/vpn-provider.c b/vpn/vpn-provider.c
index 7eb3472d..a4443528 100644
--- a/vpn/vpn-provider.c
+++ b/vpn/vpn-provider.c
@@ -2367,6 +2367,26 @@ const char *vpn_provider_get_string(struct vpn_provider
*provider,
return setting->value;
}
+bool vpn_provider_get_boolean(struct vpn_provider *provider, const char *key,
+ bool default_value)
+{
+ struct vpn_setting *setting;
+
+ connman_info("provider %p key %s", provider, key);
+
+ setting = g_hash_table_lookup(provider->setting_strings, key);
+ if (!setting || !setting->value)
+ return default_value;
+
+ if (!g_strcmp0(setting->value, "true"))
+ return true;
+
+ if (!g_strcmp0(setting->value, "false"))
+ return false;
+
+ return default_value;
+}
+
bool vpn_provider_get_string_immutable(struct vpn_provider *provider,
const char *key)
{
diff --git a/vpn/vpn-provider.h b/vpn/vpn-provider.h
index 9e184812..fcd00ef4 100644
--- a/vpn/vpn-provider.h
+++ b/vpn/vpn-provider.h
@@ -87,6 +87,8 @@ const char *vpn_provider_get_string(struct vpn_provider
*provider,
const char *key);
bool vpn_provider_get_string_immutable(struct vpn_provider *provider,
const char *key);
+bool vpn_provider_get_boolean(struct vpn_provider *provider, const char *key,
+ bool default_value);
int vpn_provider_set_state(struct vpn_provider *provider,
enum vpn_provider_state state);
--
2.20.1
------------------------------
Date: Wed, 2 Oct 2019 17:16:43 +0300
From: Jussi Laakkonen <[email protected]>
Subject: [PATCH 1/7] vpn-provider: Implement simple connection and
auth error counters
To: [email protected]
Message-ID: <[email protected]>
Add simple error counters to vpn-provider.c to count authentication and
connection errors separately. These can be used by the VPN plugins using
VPN agent to determine if the previous authentication has failed, and in
such case to re-request the credentials. Values are incremented when
vpn_provider_indicate_error() is called, both login errors
(VPN_PROVIDER_ERROR_LOGIN_FAILED) and authentication errors
(VPN_PROVIDER_ERROR_AUTH_FAILED) increase the authentication error
counter.
Counters are reset when connection succeeds (vpn-provider.c:connect_cb()
is called without error) or when the provider is saved (for the cases
where user updates the credential info in provider settings).
Removed changing of the provider state to idle in case of login error.
It is only necessary to record the errors and set state using VPN
driver.
---
vpn/vpn-provider.c | 34 ++++++++++++++++++++++++++++++----
vpn/vpn-provider.h | 6 ++++++
2 files changed, 36 insertions(+), 4 deletions(-)
diff --git a/vpn/vpn-provider.c b/vpn/vpn-provider.c
index ff4bab9a..7eb3472d 100644
--- a/vpn/vpn-provider.c
+++ b/vpn/vpn-provider.c
@@ -88,6 +88,8 @@ struct vpn_provider {
struct connman_ipaddress *prev_ipv4_addr;
struct connman_ipaddress *prev_ipv6_addr;
void *plugin_data;
+ unsigned int auth_error_counter;
+ unsigned int conn_error_counter;
};
static void append_properties(DBusMessageIter *iter,
@@ -859,6 +861,14 @@ static gchar **create_network_list(GSList *networks, gsize
*count)
return result;
}
+void reset_error_counters(struct vpn_provider *provider)
+{
+ if (!provider)
+ return;
+
+ provider->auth_error_counter = provider->conn_error_counter = 0;
+}
+
static int vpn_provider_save(struct vpn_provider *provider)
{
GKeyFile *keyfile;
@@ -866,6 +876,8 @@ static int vpn_provider_save(struct vpn_provider *provider)
DBG("provider %p immutable %s", provider,
provider->immutable ? "yes" : "no");
+ reset_error_counters(provider);
+
if (provider->immutable) {
/*
* Do not save providers that are provisioned via .config
@@ -1134,8 +1146,10 @@ static void connect_cb(struct vpn_provider *provider,
void *user_data,
vpn_provider_set_state(provider,
VPN_PROVIDER_STATE_FAILURE);
}
- } else
+ } else {
+ reset_error_counters(provider);
g_dbus_send_reply(connection, pending, DBUS_TYPE_INVALID);
+ }
dbus_message_unref(pending);
}
@@ -1656,12 +1670,14 @@ int vpn_provider_indicate_error(struct vpn_provider
*provider,
switch (error) {
case VPN_PROVIDER_ERROR_UNKNOWN:
+ break;
case VPN_PROVIDER_ERROR_CONNECT_FAILED:
+ ++provider->conn_error_counter;
break;
- case VPN_PROVIDER_ERROR_LOGIN_FAILED:
- case VPN_PROVIDER_ERROR_AUTH_FAILED:
- vpn_provider_set_state(provider, VPN_PROVIDER_STATE_IDLE);
+ case VPN_PROVIDER_ERROR_LOGIN_FAILED:
+ case VPN_PROVIDER_ERROR_AUTH_FAILED:
+ ++provider->auth_error_counter;
break;
}
@@ -2683,6 +2699,16 @@ const char *vpn_provider_get_path(struct vpn_provider
*provider)
return provider->path;
}
+const unsigned int vpn_provider_get_authentication_errors(struct vpn_provider
*provider)
+{
+ return provider->auth_error_counter;
+}
+
+const unsigned int vpn_provider_get_connection_errors(struct vpn_provider
*provider)
+{
+ return provider->conn_error_counter;
+}
+
void vpn_provider_change_address(struct vpn_provider *provider)
{
switch (provider->family) {
diff --git a/vpn/vpn-provider.h b/vpn/vpn-provider.h
index 9aaff583..9e184812 100644
--- a/vpn/vpn-provider.h
+++ b/vpn/vpn-provider.h
@@ -118,6 +118,12 @@ const char *vpn_provider_get_save_group(struct
vpn_provider *provider);
const char *vpn_provider_get_name(struct vpn_provider *provider);
const char *vpn_provider_get_host(struct vpn_provider *provider);
const char *vpn_provider_get_path(struct vpn_provider *provider);
+
+const unsigned int vpn_provider_get_authentication_errors(
+ struct vpn_provider *provider);
+const unsigned int vpn_provider_get_connection_errors(
+ struct vpn_provider *provider);
+
void vpn_provider_change_address(struct vpn_provider *provider);
void vpn_provider_clear_address(struct vpn_provider *provider, int family);
--
2.20.1
------------------------------
Subject: Digest Footer
_______________________________________________
connman mailing list -- [email protected]
To unsubscribe send an email to [email protected]
------------------------------
End of connman Digest, Vol 48, Issue 2
**************************************