[PATCH l2tp/pptp 04/21] pptp: Add pptp vpn support
From: Mohamed Abbas mab...@linux.intel.com Initial revision. --- plugins/pptp.c | 278 1 files changed, 278 insertions(+), 0 deletions(-) create mode 100644 plugins/pptp.c diff --git a/plugins/pptp.c b/plugins/pptp.c new file mode 100644 index 000..ea0b599 --- /dev/null +++ b/plugins/pptp.c @@ -0,0 +1,278 @@ +/* + * + * Connection Manager + * + * Copyright (C) 2010 BMW Car IT 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include config.h +#endif + +#include string.h +#include errno.h +#include unistd.h +#include stdio.h +#include net/if.h + +#include glib.h + +#define CONNMAN_API_SUBJECT_TO_CHANGE +#include connman/plugin.h +#include connman/provider.h +#include connman/log.h +#include connman/task.h +#include connman/dbus.h +#include connman/inet.h + +#include vpn.h + +#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0])) + +enum { + OPT_STRING = 1, + OPT_BOOL = 2, +}; + +struct { + const char *cm_opt; + const char *pptp_opt; + const char *vpnc_default; + int type; +} pptp_options[] = { + { PPTP.User, user, NULL, OPT_STRING }, + { PPTP.Password, password, NULL, OPT_STRING }, + { PPTP.EchoFailure, lcp-echo-failure, 0, OPT_STRING }, + { PPTP.EchoInterval, lcp-echo-interval, 0, OPT_STRING }, + { PPTP.Debug, debug, NULL, OPT_STRING }, + { PPTP.RefuseEAP, refuse-eap, NULL, OPT_BOOL }, + { PPTP.RefusePAP, refuse-pap, NULL, OPT_BOOL }, + { PPTP.RefuseCHAP, refuse-chap, NULL, OPT_BOOL }, + { PPTP.RefuseMSCHAP, refuse-mschap, NULL, OPT_BOOL }, + { PPTP.RefuseMSCHAP2, refuse-mschapv2, NULL, OPT_BOOL }, + { PPTP.NoBSDComp, nobsdcomp, NULL, OPT_BOOL }, + { PPTP.NoDeflate, nodeflatey, NULL, OPT_BOOL }, + { PPTP.RequirMPPE, require-mppe, NULL, OPT_BOOL }, + { PPTP.RequirMPPE40, require-mppe-40, NULL, OPT_BOOL }, + { PPTP.RequirMPPE128, require-mppe-128, NULL, OPT_BOOL }, + { PPTP.RequirMPPEStateful, mppe-stateful, NULL, OPT_BOOL }, + { PPTP.NoVJ, no-vj-comp, NULL, OPT_BOOL }, +}; + +static DBusConnection *connection; + +static DBusMessage *pptp_get_sec(struct connman_task *task, + DBusMessage *msg, void *user_data) +{ + const char *user, *passwd; + struct connman_provider *provider = user_data; + + if (dbus_message_get_no_reply(msg) == FALSE) { + DBusMessage *reply; + + user = connman_provider_get_string(provider, PPTP.User); + passwd = connman_provider_get_string(provider, PPTP.Password); + if (user == NULL || strlen(user) == 0 || + passwd == NULL || strlen(passwd) == 0) + return NULL; + + reply = dbus_message_new_method_return(msg); + if (reply == NULL) + return NULL; + + dbus_message_append_args(reply, DBUS_TYPE_STRING, user, + DBUS_TYPE_STRING, passwd, + DBUS_TYPE_INVALID); + + return reply; + } + + return NULL; +} + +static int pptp_notify(DBusMessage *msg, struct connman_provider *provider) +{ + DBusMessageIter iter, dict; + const char *reason, *key, *value; + char *ifname = NULL; + + dbus_message_iter_init(msg, iter); + + dbus_message_iter_get_basic(iter, reason); + dbus_message_iter_next(iter); + + if (!provider) { + connman_error(No provider found); + return VPN_STATE_FAILURE; + } + + if (strcmp(reason, connect)) + return VPN_STATE_DISCONNECT; + + dbus_message_iter_recurse(iter, dict); + + while (dbus_message_iter_get_arg_type(dict) == DBUS_TYPE_DICT_ENTRY) { + DBusMessageIter entry; + + dbus_message_iter_recurse(dict, entry); + dbus_message_iter_get_basic(entry, key); + dbus_message_iter_next(entry); + dbus_message_iter_get_basic(entry, value); + + DBG(%s = %s, key, value); + + if (!strcmp(key, INTERNAL_IP4_ADDRESS)) + connman_provider_set_string(provider, Address, value); + +
[PATCH l2tp/pptp 05/21] pptp: Add ppp plugin library.
From: Mohamed Abbas mab...@linux.intel.com pppd will use this library to talk with connman vpn plugin. Original patch comes from Mohamed Abbas. Jukka Rissanen changed the pptp function prefix to ppp as the plugin is used by both pptp and l2tp plugins. --- scripts/libppp-plugin.c | 308 +++ 1 files changed, 308 insertions(+), 0 deletions(-) create mode 100644 scripts/libppp-plugin.c diff --git a/scripts/libppp-plugin.c b/scripts/libppp-plugin.c new file mode 100644 index 000..74f6207 --- /dev/null +++ b/scripts/libppp-plugin.c @@ -0,0 +1,308 @@ +/* + * + * Connection Manager + * + * Copyright (C) 2007-2010 Intel Corporation. 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include config.h +#endif + +#include stdio.h +#include stdlib.h +#include string.h +#include sys/types.h +#include sys/stat.h +#include fcntl.h +#include pppd/pppd.h +#include pppd/fsm.h +#include pppd/ipcp.h +#include netinet/in.h +#include arpa/inet.h + +#include dbus/dbus.h + +#define INET_ADDRES_LEN (INET_ADDRSTRLEN + 5) +#define INET_DNS_LEN (2*INET_ADDRSTRLEN + 9) + +static char *busname; +static char *interface; +static char *path; + +static DBusConnection *connection; + +char pppd_version[] = VERSION; + +int plugin_init(void); + +static void append(DBusMessageIter *dict, const char *key, const char *value) +{ + DBusMessageIter entry; + + /* We clean the environment before invoking openconnect, but +* might as well still filter out the few things that get +* added that we're not interested in +*/ + if (!strcmp(key, PWD) || !strcmp(key, _) || + !strcmp(key, SHLVL) || !strcmp(key, connman_busname) || + !strcmp(key, connman_network)) + return; + + dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY, + NULL, entry); + + dbus_message_iter_append_basic(entry, DBUS_TYPE_STRING, key); + + dbus_message_iter_append_basic(entry, DBUS_TYPE_STRING, value); + + dbus_message_iter_close_container(dict, entry); +} + + +static int ppp_have_secret() +{ + return 1; +} + +static int ppp_get_secret(char *username, char *password) +{ + DBusMessage *msg, *reply; + const char *user, *pass; + DBusError err; + + if (username == NULL password == NULL) + return -1; + + if (password == NULL) + return 1; + + if (connection == NULL) + return -1; + + dbus_error_init(err); + + msg = dbus_message_new_method_call(busname, path, + interface, getsec); + if (msg == NULL) + return -1; + + dbus_message_append_args(msg, DBUS_TYPE_INVALID, DBUS_TYPE_INVALID); + + reply = dbus_connection_send_with_reply_and_block(connection, + msg, -1, err); + + if (reply == NULL) { + if (dbus_error_is_set(err) == TRUE) + dbus_error_free(err); + + dbus_message_unref(msg); + return -1; + } + + dbus_message_unref(msg); + + dbus_error_init(err); + + if (dbus_message_get_args(reply, err, DBUS_TYPE_STRING, user, + DBUS_TYPE_STRING, pass, + DBUS_TYPE_INVALID) == FALSE) { + if (dbus_error_is_set(err) == TRUE) + dbus_error_free(err); + + dbus_message_unref(reply); + return -1; + } + + if (username != NULL) + strcpy(username, user); + + strcpy(password, pass); + + dbus_message_unref(reply); + + return 1; +} + +static void ppp_up(void *data, int arg) +{ + char buf[INET_ADDRES_LEN]; + char dns[INET_DNS_LEN]; + const char *reason = connect; + bool add_blank = FALSE; + DBusMessageIter iter, dict; + DBusMessage *msg; + + if (connection == NULL) + return; + + if (ipcp_gotoptions[0].ouraddr == 0) + return; + + msg = dbus_message_new_method_call(busname, path
[PATCH l2tp/pptp 06/21] l2tp: Add l2tp vpn support.
From: Mohamed Abbas mab...@linux.intel.com Initial revision. --- plugins/l2tp.c | 470 1 files changed, 470 insertions(+), 0 deletions(-) create mode 100644 plugins/l2tp.c diff --git a/plugins/l2tp.c b/plugins/l2tp.c new file mode 100644 index 000..0209b2f --- /dev/null +++ b/plugins/l2tp.c @@ -0,0 +1,470 @@ +/* + * + * Connection Manager + * + * Copyright (C) 2010 BMW Car IT 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include config.h +#endif + +#include string.h +#include errno.h +#include unistd.h +#include sys/types.h +#include sys/stat.h +#include fcntl.h + +#include stdio.h +#include net/if.h + +#include glib.h + +#define CONNMAN_API_SUBJECT_TO_CHANGE +#include connman/plugin.h +#include connman/provider.h +#include connman/log.h +#include connman/task.h +#include connman/dbus.h +#include connman/inet.h + +#include vpn.h + +#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0])) + +enum { + OPT_STRING = 1, + OPT_BOOL = 2, +}; + +enum { + OPT_ALL = 1, + OPT_L2G = 2, + OPT_L2 = 3, + OPT_PPPD = 4, +}; + +struct { + const char *cm_opt; + const char *pppd_opt; + int sub; + const char *vpnc_default; + int type; +} pppd_options[] = { + { L2TP.User, name, OPT_ALL, NULL, OPT_STRING }, + { L2TP.BPS, bps, OPT_L2, NULL, OPT_STRING }, + { L2TP.LengthBit, length bit, OPT_L2, NULL, OPT_STRING }, + { L2TP.Challenge, challenge, OPT_L2, NULL, OPT_STRING }, + { L2TP.DefaultRoute, defaultroute, OPT_L2, NULL, OPT_STRING }, + { L2TP.FlowBit, flow bit, OPT_L2, NULL, OPT_STRING }, + { L2TP.TunnelRWS, tunnel rws, OPT_L2, NULL, OPT_STRING }, + { L2TP.Exclusive, exclusive, OPT_L2, NULL, OPT_STRING }, + { L2TP.Autodial, autodial, OPT_L2, yes, OPT_STRING }, + { L2TP.Redial, redial, OPT_L2, yes, OPT_STRING }, + { L2TP.RedialTimeout, redial timeout, OPT_L2, 10, OPT_STRING }, + { L2TP.MaxRedials, max redials, OPT_L2, NULL, OPT_STRING }, + { L2TP.RequirePAP, require pap, OPT_L2, no, OPT_STRING }, + { L2TP.RequireCHAP, require chap, OPT_L2, yes, OPT_STRING }, + { L2TP.ReqAuth, require authentication, OPT_L2, no, OPT_STRING }, + { L2TP.AccessControl, access control, OPT_L2G, yes, OPT_STRING }, + { L2TP.AuthFile, auth file, OPT_L2G, NULL, OPT_STRING }, + { L2TP.ForceUserSpace, force userspace, OPT_L2G, NULL, OPT_STRING }, + { L2TP.ListenAddr, listen-addr, OPT_L2G, NULL, OPT_STRING }, + { L2TP.Rand Source, rand source, OPT_L2G, NULL, OPT_STRING }, + { L2TP.IPsecSaref, ipsec saref, OPT_L2G, NULL, OPT_STRING }, + { L2TP.Port, port, OPT_L2G, NULL, OPT_STRING }, + { L2TP.EchoFailure, lcp-echo-failure, OPT_PPPD, 0, OPT_STRING }, + { L2TP.EchoInterval, lcp-echo-interval, OPT_PPPD, 0, OPT_STRING }, + { L2TP.Debug, debug, OPT_PPPD, NULL, OPT_STRING }, + { L2TP.RefuseEAP, refuse-eap, OPT_PPPD, NULL, OPT_BOOL }, + { L2TP.RefusePAP, refuse-pap, OPT_PPPD, NULL, OPT_BOOL }, + { L2TP.RefuseCHAP, refuse-chap, OPT_PPPD, NULL, OPT_BOOL }, + { L2TP.RefuseMSCHAP, refuse-mschap, OPT_PPPD, NULL, OPT_BOOL }, + { L2TP.RefuseMSCHAP2, refuse-mschapv2, OPT_PPPD, NULL, OPT_BOOL }, + { L2TP.NoBSDComp, nobsdcomp, OPT_PPPD, NULL, OPT_BOOL }, + { L2TP.NoPcomp, nopcomp, OPT_PPPD, NULL, OPT_BOOL }, + { L2TP.UseAccomp, accomp, OPT_PPPD, NULL, OPT_BOOL }, + { L2TP.NoDeflate, nodeflatey, OPT_PPPD, NULL, OPT_BOOL }, + { L2TP.ReqMPPE, require-mppe, OPT_PPPD, NULL, OPT_BOOL }, + { L2TP.ReqMPPE40, require-mppe-40, OPT_PPPD, NULL, OPT_BOOL }, + { L2TP.ReqMPPE128, require-mppe-128, OPT_PPPD, NULL, OPT_BOOL }, + { L2TP.ReqMPPEStateful, mppe-stateful, OPT_PPPD, NULL, OPT_BOOL }, + { L2TP.NoVJ, no-vj-comp, OPT_PPPD, NULL, OPT_BOOL }, +}; + +static DBusConnection *connection; + +static DBusMessage *l2tp_get_sec(struct connman_task *task, + DBusMessage *msg, void *user_data) +{ + const char *user, *passwd; + struct connman_provider *provider = user_data; + + if (dbus_message_get_no_reply(msg) == FALSE) { + DBusMessage *reply; + + user = connman_provider_get_string(provider,
[PATCH l2tp/pptp 07/21] test: Add test script support for pptp/l2tp.
From: Mohamed Abbas mab...@linux.intel.com Modify connect-vpn script to handle pptp/l2tp connection. --- test/connect-vpn | 18 ++ 1 files changed, 18 insertions(+), 0 deletions(-) diff --git a/test/connect-vpn b/test/connect-vpn index a43c4cd..00fa717 100755 --- a/test/connect-vpn +++ b/test/connect-vpn @@ -9,6 +9,10 @@ if (len(sys.argv) 4): print name host domain cookie [servercert] print type: openvpn print name host domain cafile certfile keyfile + print type: pptp + print name host domain user password + print type: l2tp + print name host domain user password sys.exit(1) bus = dbus.SystemBus() @@ -32,6 +36,20 @@ if sys.argv[1] == openconnect: Host: sys.argv[3], VPN.Domain: sys.argv[4], OpenConnect.Cookie: sys.argv[5]})) +elif sys.argv[1] == pptp: + path = manager.ConnectProvider(({ Type: pptp, + Name: sys.argv[2], + Host: sys.argv[3], + VPN.Domain: sys.argv[4], + PPTP.User: sys.argv[5], + PPTP.Password: sys.argv[6]})) +elif sys.argv[1] == l2tp: + path = manager.ConnectProvider(({ Type: l2tp, + Name: sys.argv[2], + Host: sys.argv[3], + VPN.Domain: sys.argv[4], + L2TP.User: sys.argv[5], + L2TP.Password: sys.argv[6]})) elif sys.argv[1] == openvpn: path = manager.ConnectProvider(({ Type: openvpn, Name: sys.argv[2], -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH l2tp/pptp 08/21] l2tp: Add l2tp makefile and configure file.
--- Makefile.plugins | 18 ++ configure.ac | 14 ++ 2 files changed, 32 insertions(+), 0 deletions(-) diff --git a/Makefile.plugins b/Makefile.plugins index 23524df..4e33524 100644 --- a/Makefile.plugins +++ b/Makefile.plugins @@ -137,6 +137,24 @@ plugins_vpnc_la_LDFLAGS = $(plugin_ldflags) endif endif +if L2TP +if L2TP_BUILTIN +builtin_modules += l2tp +builtin_sources += plugins/l2tp.c +builtin_vpn_sources = plugins/vpn.c plugins/vpn.h +builtin_cflags += -DL2TP=\@L2TP@\ +else +plugin_LTLIBRARIES += plugins/l2tp.la +plugin_objects += $(plugins_l2tp_la_OBJECTS) +plugins_l2tp_la_SOURCES = plugins/vpn.h plugins/vpn.c \ + plugins/l2tp.c +plugins_l2tp_la_CFLAGS = $(plugin_cflags) -DL2TP=\@L2TP@\ \ + -DSTATEDIR=\$(statedir)\ \ + -DSCRIPTDIR=\$(build_scriptdir)\ +plugins_l2tp_la_LDFLAGS = $(plugin_ldflags) +endif +endif + builtin_sources += $(builtin_vpn_sources) if PORTAL diff --git a/configure.ac b/configure.ac index 0986045..075255c 100644 --- a/configure.ac +++ b/configure.ac @@ -112,6 +112,20 @@ fi AM_CONDITIONAL(OPENCONNECT, test ${enable_openconnect} != no) AM_CONDITIONAL(OPENCONNECT_BUILTIN, test ${enable_openconnect} = builtin) +AC_ARG_ENABLE(l2tp, + AC_HELP_STRING([--enable-l2tp], [enable l2tp support]), + [enable_l2tp=${enableval}], [enable_l2tp=no]) +if (test ${enable_l2tp} != no); then + if (test -z ${path_l2tp}); then + AC_PATH_PROG(L2TP, [xl2tpd], [], $PATH:/sbin:/usr/sbin) + else + L2TP=${path_l2tp} + AC_SUBST(L2TP) + fi +fi +AM_CONDITIONAL(L2TP, test ${enable_l2tp} != no) +AM_CONDITIONAL(L2TP_BUILTIN, test ${enable_l2tp} = builtin) + AC_ARG_ENABLE(portal, AC_HELP_STRING([--enable-portal], [enable portal detection support]), [enable_portal=${enableval}], [enable_portal=no]) -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH l2tp/pptp 09/21] pptp: Add pptp makefile and configure file.
--- Makefile.plugins | 19 +++ configure.ac | 20 2 files changed, 39 insertions(+), 0 deletions(-) diff --git a/Makefile.plugins b/Makefile.plugins index 4e33524..5b1225d 100644 --- a/Makefile.plugins +++ b/Makefile.plugins @@ -155,6 +155,25 @@ plugins_l2tp_la_LDFLAGS = $(plugin_ldflags) endif endif +if PPTP +if PPTP_BUILTIN +builtin_modules += pptp +builtin_sources += plugins/pptp.c +builtin_vpn_sources = plugins/vpn.c plugins/vpn.h +builtin_cflags += -DPPPD=\@PPPD@\ -DPPTP=\@PPTP@\ +else +plugin_LTLIBRARIES += plugins/pptp.la +plugin_objects += $(plugins_pptp_la_OBJECTS) +plugins_pptp_la_SOURCES = plugins/vpn.h plugins/vpn.c \ + plugins/pptp.c +plugins_pptp_la_CFLAGS = $(plugin_cflags) -DPPPD=\@PPPD@\ \ + -DPPTP=\@PPTP@\ \ + -DSTATEDIR=\$(statedir)\ \ + -DSCRIPTDIR=\$(build_scriptdir)\ +plugins_pptp_la_LDFLAGS = $(plugin_ldflags) +endif +endif + builtin_sources += $(builtin_vpn_sources) if PORTAL diff --git a/configure.ac b/configure.ac index 075255c..9c834ab 100644 --- a/configure.ac +++ b/configure.ac @@ -126,6 +126,26 @@ fi AM_CONDITIONAL(L2TP, test ${enable_l2tp} != no) AM_CONDITIONAL(L2TP_BUILTIN, test ${enable_l2tp} = builtin) +AC_ARG_ENABLE(pptp, + AC_HELP_STRING([--enable-pptp], [enable pptp support]), + [enable_pptp=${enableval}], [enable_pptp=no]) +if (test ${enable_pptp} != no); then + if (test -z ${path_pppd}); then + AC_PATH_PROG(PPPD, [pppd], [], $PATH:/sbin:/usr/sbin) + else + PPPD=${path_pppd} + AC_SUBST(PPPD) + fi + if (test -z ${path_pptp}); then + AC_PATH_PROG(PPTP, [pptp], [], $PATH:/sbin:/usr/sbin) + else + PPTP=${path_pptp} + AC_SUBST(PPTP) + fi +fi +AM_CONDITIONAL(PPTP, test ${enable_pptp} != no) +AM_CONDITIONAL(PPTP_BUILTIN, test ${enable_pptp} = builtin) + AC_ARG_ENABLE(portal, AC_HELP_STRING([--enable-portal], [enable portal detection support]), [enable_portal=${enableval}], [enable_portal=no]) -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH l2tp/pptp 10/21] scripts: Compile libppp-plugin.so properly.
--- Makefile.plugins | 14 ++ 1 files changed, 14 insertions(+), 0 deletions(-) diff --git a/Makefile.plugins b/Makefile.plugins index 5b1225d..3fdfac0 100644 --- a/Makefile.plugins +++ b/Makefile.plugins @@ -3,6 +3,8 @@ plugin_cflags = -fvisibility=hidden -I$(srcdir)/gdbus \ @DBUS_CFLAGS@ @GLIB_CFLAGS@ plugin_ldflags = -no-undefined -module -avoid-version +script_cflags = -fvisibility=hidden -I$(srcdir)/gdbus \ + @DBUS_CFLAGS@ if LOOPBACK if LOOPBACK_BUILTIN @@ -174,6 +176,18 @@ plugins_pptp_la_LDFLAGS = $(plugin_ldflags) endif endif +if PPTP +script_LTLIBRARIES += scripts/libppp-plugin.la +scripts_libppp_plugin_la_LDFLAGS = $(script_cflags) @DBUS_CFLAGS@ +scripts_libppp_plugin_la_LIBADD = @DBUS_LIBS@ +else +if L2TP +script_LTLIBRARIES += scripts/libppp-plugin.la +scripts_libppp_plugin_la_LDFLAGS = $(script_cflags) @DBUS_CFLAGS@ +scripts_libppp_plugin_la_LIBADD = @DBUS_LIBS@ +endif +endif + builtin_sources += $(builtin_vpn_sources) if PORTAL -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH l2tp/pptp 11/21] l2tp: Set the provider IP address when connected.
Without this patch the service connect timeout handler will stop the provider service after two minutes. --- plugins/l2tp.c | 37 ++--- 1 files changed, 34 insertions(+), 3 deletions(-) diff --git a/plugins/l2tp.c b/plugins/l2tp.c index 0209b2f..84f4843 100644 --- a/plugins/l2tp.c +++ b/plugins/l2tp.c @@ -143,7 +143,9 @@ static int l2tp_notify(DBusMessage *msg, struct connman_provider *provider) { DBusMessageIter iter, dict; const char *reason, *key, *value; + char *addressv4 = NULL, *netmask = NULL, *gateway = NULL; char *ifname = NULL; + struct connman_ipaddress *ipaddress = NULL; dbus_message_iter_init(msg, iter); @@ -170,11 +172,15 @@ static int l2tp_notify(DBusMessage *msg, struct connman_provider *provider) DBG(%s = %s, key, value); - if (!strcmp(key, INTERNAL_IP4_ADDRESS)) + if (!strcmp(key, INTERNAL_IP4_ADDRESS)) { connman_provider_set_string(provider, Address, value); + addressv4 = g_strdup(value); + } - if (!strcmp(key, INTERNAL_IP4_NETMASK)) + if (!strcmp(key, INTERNAL_IP4_NETMASK)) { connman_provider_set_string(provider, Netmask, value); + netmask = g_strdup(value); + } if (!strcmp(key, INTERNAL_IP4_DNS)) connman_provider_set_string(provider, DNS, value); @@ -187,14 +193,39 @@ static int l2tp_notify(DBusMessage *msg, struct connman_provider *provider) if (vpn_set_ifname(provider, ifname) 0) { g_free(ifname); + g_free(addressv4); + g_free(netmask); return VPN_STATE_FAILURE; } + if (addressv4 != NULL) + ipaddress = connman_ipaddress_alloc(AF_INET); + g_free(ifname); + if (ipaddress == NULL) { + connman_error(No IP address for provider); + g_free(addressv4); + g_free(netmask); + return VPN_STATE_FAILURE; + } + value = connman_provider_get_string(provider, Host); - if (value != NULL) + if (value != NULL) { connman_provider_set_string(provider, Gateway, value); + gateway = g_strdup(value); + } + + if (addressv4 != NULL) + connman_ipaddress_set_ipv4(ipaddress, addressv4, netmask, + gateway); + + connman_provider_set_ipaddress(provider, ipaddress); + + g_free(addressv4); + g_free(netmask); + g_free(gateway); + connman_ipaddress_free(ipaddress); return VPN_STATE_CONNECT; } -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH l2tp/pptp 13/21] l2tp: Check authentication error properly.
--- plugins/l2tp.c |6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/l2tp.c b/plugins/l2tp.c index 84f4843..6bfc725 100644 --- a/plugins/l2tp.c +++ b/plugins/l2tp.c @@ -157,6 +157,9 @@ static int l2tp_notify(DBusMessage *msg, struct connman_provider *provider) return VPN_STATE_FAILURE; } + if (strcmp(reason, auth failed) == 0) + return VPN_STATE_AUTH_FAILURE; + if (strcmp(reason, connect)) return VPN_STATE_DISCONNECT; @@ -465,12 +468,9 @@ static int l2tp_connect(struct connman_provider *provider, static int l2tp_error_code(int exit_code) { - switch (exit_code) { case 1: return CONNMAN_PROVIDER_ERROR_CONNECT_FAILED; - case 2: - return CONNMAN_PROVIDER_ERROR_LOGIN_FAILED; default: return CONNMAN_PROVIDER_ERROR_UNKNOWN; } -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH l2tp/pptp 12/21] scripts: Report authentication error to connman.
The ppp plugin now checks ppp authentication error and report it to correct connman plugin. --- scripts/libppp-plugin.c | 12 +++- 1 files changed, 11 insertions(+), 1 deletions(-) diff --git a/scripts/libppp-plugin.c b/scripts/libppp-plugin.c index 74f6207..b0276c2 100644 --- a/scripts/libppp-plugin.c +++ b/scripts/libppp-plugin.c @@ -45,6 +45,7 @@ static char *interface; static char *path; static DBusConnection *connection; +static int prev_phase; char pppd_version[] = VERSION; @@ -239,11 +240,18 @@ static void ppp_phase_change(void *data, int arg) { const char *reason = disconnect; DBusMessage *msg; + int send_msg = 0; if (connection == NULL) return; - if (arg == PHASE_DEAD || arg == PHASE_DISCONNECT) { + if (prev_phase == PHASE_AUTHENTICATE + arg == PHASE_TERMINATE) { + reason = auth failed; + send_msg = 1; + } + + if (send_msg 0 || arg == PHASE_DEAD || arg == PHASE_DISCONNECT) { msg = dbus_message_new_method_call(busname, path, interface, notify); if (msg == NULL) @@ -260,6 +268,8 @@ static void ppp_phase_change(void *data, int arg) dbus_message_unref(msg); } + + prev_phase = arg; } int plugin_init(void) -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH l2tp/pptp 14/21] pptp: Return authentication errors properly.
--- plugins/pptp.c |3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/plugins/pptp.c b/plugins/pptp.c index ea0b599..7c62276 100644 --- a/plugins/pptp.c +++ b/plugins/pptp.c @@ -120,6 +120,9 @@ static int pptp_notify(DBusMessage *msg, struct connman_provider *provider) return VPN_STATE_FAILURE; } + if (strcmp(reason, auth failed) == 0) + return VPN_STATE_AUTH_FAILURE; + if (strcmp(reason, connect)) return VPN_STATE_DISCONNECT; -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH l2tp/pptp 01/21] vpn: Add support to allow ppp tunnelling.
From: Mohamed Abbas mab...@linux.intel.com pptp and l2tp does not use tun/tab approach so change the vpn.c to allow vpn daemon to create the interface. Now vpn plugin tell vpn to create the device or leave to vpn client. On connection vpn will get the interface name set the index for the provider. This patch is prepared by Jukka Rissanen and it contains Mohamed Abbas original patch + fixes suggested by Daniel Wagner. --- plugins/vpn.c | 116 + plugins/vpn.h |4 ++ 2 files changed, 88 insertions(+), 32 deletions(-) diff --git a/plugins/vpn.c b/plugins/vpn.c index efeb959..506a71c 100644 --- a/plugins/vpn.c +++ b/plugins/vpn.c @@ -65,27 +65,40 @@ struct vpn_driver_data { GHashTable *driver_hash = NULL; -static int kill_tun(char *tun_name) +static int stop_vpn(struct connman_provider *provider) { + struct vpn_data *data = connman_provider_get_data(provider); + struct vpn_driver_data *vpn_driver_data; + const char *name; struct ifreq ifr; int fd, err; + if (data == NULL) + return -1; + + name = connman_provider_get_driver_name(provider); + vpn_driver_data = g_hash_table_lookup(driver_hash, name); + + if (vpn_driver_data != NULL vpn_driver_data-vpn_driver != NULL + vpn_driver_data-vpn_driver-flags == VPN_FLAG_NO_TUN) + return 0; + memset(ifr, 0, sizeof(ifr)); ifr.ifr_flags = IFF_TUN | IFF_NO_PI; - sprintf(ifr.ifr_name, %s, tun_name); + sprintf(ifr.ifr_name, %s, data-if_name); fd = open(/dev/net/tun, O_RDWR); if (fd 0) { err = -errno; connman_error(Failed to open /dev/net/tun to device %s: %s, - tun_name, strerror(errno)); + data-if_name, strerror(errno)); return err; } if (ioctl(fd, TUNSETIFF, (void *)ifr)) { err = -errno; connman_error(Failed to TUNSETIFF for device %s to it: %s, - tun_name, strerror(errno)); + data-if_name, strerror(errno)); close(fd); return err; } @@ -93,12 +106,12 @@ static int kill_tun(char *tun_name) if (ioctl(fd, TUNSETPERSIST, 0)) { err = -errno; connman_error(Failed to set tun device %s nonpersistent: %s, - tun_name, strerror(errno)); + data-if_name, strerror(errno)); close(fd); return err; } close(fd); - DBG(Killed tun device %s, tun_name); + DBG(Killed tun device %s, data-if_name); return 0; } @@ -116,7 +129,7 @@ void vpn_died(struct connman_task *task, int exit_code, void *user_data) state = data-state; - kill_tun(data-if_name); + stop_vpn(provider); connman_provider_set_data(provider, NULL); connman_rtnl_remove_watch(data-watch); @@ -145,6 +158,24 @@ vpn_exit: connman_task_destroy(task); } +int vpn_set_ifname(struct connman_provider *provider, const char *ifname) +{ + struct vpn_data *data = connman_provider_get_data(provider); + int index; + + if (ifname == NULL || data == NULL) + return -EIO; + + index = connman_inet_ifindex(ifname); + if (index 0) + return -EIO; + + data-if_name = (char *)g_strdup(ifname); + connman_provider_set_index(provider, index); + + return 0; +} + static void vpn_newlink(unsigned flags, unsigned change, void *user_data) { struct connman_provider *provider = user_data; @@ -201,32 +232,15 @@ static void vpn_notify(struct connman_task *task, } } -static int vpn_connect(struct connman_provider *provider) +static int vpn_create_tun(struct connman_provider *provider) { struct vpn_data *data = connman_provider_get_data(provider); - struct vpn_driver_data *vpn_driver_data; struct ifreq ifr; - const char *name; int i, fd, index; int ret = 0; - if (data != NULL) - return -EISCONN; - - data = g_try_new0(struct vpn_data, 1); if (data == NULL) - return -ENOMEM; - - data-provider = connman_provider_ref(provider); - data-watch = 0; - data-flags = 0; - data-task = NULL; - data-state = VPN_STATE_IDLE; - - connman_provider_set_data(provider, data); - - name = connman_provider_get_driver_name(provider); - vpn_driver_data = g_hash_table_lookup(driver_hash, name); + return -EISCONN; fd = open(/dev/net/tun, O_RDWR); if (fd 0) { @@ -276,24 +290,63 @@ static int vpn_connect(struct connman_provider *provider) index = connman_inet_ifindex(data-if_name); if (index 0) { connman_error(Failed
[PATCH l2tp/pptp 15/21] pptp: Set the provider IP address when connected.
Without this patch the service connect timeout handler will stop the provider service after two minutes. --- plugins/pptp.c | 37 ++--- 1 files changed, 34 insertions(+), 3 deletions(-) diff --git a/plugins/pptp.c b/plugins/pptp.c index 7c62276..fed322b 100644 --- a/plugins/pptp.c +++ b/plugins/pptp.c @@ -108,7 +108,9 @@ static int pptp_notify(DBusMessage *msg, struct connman_provider *provider) { DBusMessageIter iter, dict; const char *reason, *key, *value; + char *addressv4 = NULL, *netmask = NULL, *gateway = NULL; char *ifname = NULL; + struct connman_ipaddress *ipaddress = NULL; dbus_message_iter_init(msg, iter); @@ -138,11 +140,15 @@ static int pptp_notify(DBusMessage *msg, struct connman_provider *provider) DBG(%s = %s, key, value); - if (!strcmp(key, INTERNAL_IP4_ADDRESS)) + if (!strcmp(key, INTERNAL_IP4_ADDRESS)) { connman_provider_set_string(provider, Address, value); + addressv4 = g_strdup(value); + } - if (!strcmp(key, INTERNAL_IP4_NETMASK)) + if (!strcmp(key, INTERNAL_IP4_NETMASK)) { connman_provider_set_string(provider, Netmask, value); + netmask = g_strdup(value); + } if (!strcmp(key, INTERNAL_IP4_DNS)) connman_provider_set_string(provider, DNS, value); @@ -155,14 +161,39 @@ static int pptp_notify(DBusMessage *msg, struct connman_provider *provider) if (vpn_set_ifname(provider, ifname) 0) { g_free(ifname); + g_free(addressv4); + g_free(netmask); return VPN_STATE_FAILURE; } + if (addressv4 != NULL) + ipaddress = connman_ipaddress_alloc(AF_INET); + g_free(ifname); + if (ipaddress == NULL) { + connman_error(No IP address for provider); + g_free(addressv4); + g_free(netmask); + return VPN_STATE_FAILURE; + } + value = connman_provider_get_string(provider, Host); - if (value != NULL) + if (value != NULL) { connman_provider_set_string(provider, Gateway, value); + gateway = g_strdup(value); + } + + if (addressv4 != NULL) + connman_ipaddress_set_ipv4(ipaddress, addressv4, netmask, + gateway); + + connman_provider_set_ipaddress(provider, ipaddress); + + g_free(addressv4); + g_free(netmask); + g_free(gateway); + connman_ipaddress_free(ipaddress); return VPN_STATE_CONNECT; } -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH l2tp/pptp 17/21] readme: Add l2tp and pptp information.
--- README | 15 +++ 1 files changed, 15 insertions(+), 0 deletions(-) diff --git a/README b/README index 0cec62b..532e327 100644 --- a/README +++ b/README @@ -41,6 +41,21 @@ To compile and install run: make make install +VPN +=== + +In order to compile pptp and l2tp VPN plugins, you need ppp development +package. + +To run l2tp you will need + - xl2tpd, http://www.xelerance.com/services/software/xl2tpd + +To run pptp you will need + - pptp client, http://pptpclient.sourceforge.net + +Both l2tp and pptp also need pppd. + + Configuration and options = -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH l2tp/pptp 16/21] pptp: Do not put password in command line options.
--- plugins/pptp.c |1 - 1 files changed, 0 insertions(+), 1 deletions(-) diff --git a/plugins/pptp.c b/plugins/pptp.c index fed322b..465f2dc 100644 --- a/plugins/pptp.c +++ b/plugins/pptp.c @@ -55,7 +55,6 @@ struct { int type; } pptp_options[] = { { PPTP.User, user, NULL, OPT_STRING }, - { PPTP.Password, password, NULL, OPT_STRING }, { PPTP.EchoFailure, lcp-echo-failure, 0, OPT_STRING }, { PPTP.EchoInterval, lcp-echo-interval, 0, OPT_STRING }, { PPTP.Debug, debug, NULL, OPT_STRING }, -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH l2tp/pptp 18/21] vpn: Fix memory leak.
--- plugins/vpn.c |6 ++ 1 files changed, 6 insertions(+), 0 deletions(-) diff --git a/plugins/vpn.c b/plugins/vpn.c index ee85dd7..8a51bda 100644 --- a/plugins/vpn.c +++ b/plugins/vpn.c @@ -158,6 +158,8 @@ vpn_exit: connman_provider_set_index(provider, -1); connman_provider_unref(data-provider); + + g_free(data-if_name); g_free(data); connman_task_destroy(task); @@ -175,6 +177,9 @@ int vpn_set_ifname(struct connman_provider *provider, const char *ifname) if (index 0) return -EIO; + if (data-if_name != NULL) + g_free(data-if_name); + data-if_name = (char *)g_strdup(ifname); connman_provider_set_index(provider, index); @@ -385,6 +390,7 @@ exist_err: connman_provider_set_index(provider, -1); connman_provider_set_data(provider, NULL); connman_provider_unref(data-provider); + g_free(data-if_name); g_free(data); return ret; -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH l2tp/pptp 19/21] provider: Fix memory leak.
Provider name is already allocated in connman_provider_get() so we must deallocate it before setting it again. --- src/provider.c |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/src/provider.c b/src/provider.c index 90f145d..5a1dffb 100644 --- a/src/provider.c +++ b/src/provider.c @@ -533,6 +533,7 @@ int __connman_provider_create_and_connect(DBusMessage *msg) provider-host = g_strdup(host); provider-domain = g_strdup(domain); + g_free(provider-name); provider-name = g_strdup(name); provider-type = g_strdup(type); -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH l2tp/pptp 20/21] task: Make sure the process is eventually killed.
If a task refuses to kill itself, then wait two secs before trying again and if that does not help then forcefully kill it. --- src/task.c | 44 +++- 1 files changed, 43 insertions(+), 1 deletions(-) diff --git a/src/task.c b/src/task.c index 51b4898..e9f1ccb 100644 --- a/src/task.c +++ b/src/task.c @@ -344,6 +344,44 @@ int connman_task_run(struct connman_task *task, return 0; } +static gboolean force_kill_timeout(gpointer user_data) +{ + pid_t pid = GPOINTER_TO_INT(user_data); + if (pid 0) { + if (kill(pid, SIGKILL) == 0) + connman_warn(killing pid %d by force, pid); + } + + return FALSE; +} + +static gboolean kill_timeout(gpointer user_data) +{ + pid_t pid = GPOINTER_TO_INT(user_data); + if (pid 0) { + if (kill(pid, SIGINT) == 0) + g_timeout_add_seconds(1, force_kill_timeout, + GINT_TO_POINTER(pid)); + } + + return FALSE; +} + +static gboolean check_kill(gpointer user_data) +{ + pid_t pid = GPOINTER_TO_INT(user_data); + if (pid 0) { + if (kill(pid, 0) == 0) { + connman_info(pid %d was not killed, + retrying after 2 sec, pid); + g_timeout_add_seconds(2, kill_timeout, + GINT_TO_POINTER(pid)); + } + } + + return FALSE; +} + /** * connman_task_stop: * @task: task structure @@ -354,9 +392,13 @@ int connman_task_stop(struct connman_task *task) { DBG(task %p, task); - if (task-pid 0) + if (task-pid 0) { kill(task-pid, SIGTERM); + g_timeout_add_seconds(0, check_kill, + GINT_TO_POINTER(task-pid)); + } + return 0; } -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH l2tp/pptp 21/21] todo: Mark l2tp and pptp as done.
--- TODO | 14 -- 1 files changed, 0 insertions(+), 14 deletions(-) diff --git a/TODO b/TODO index 36f8240..7bf512d 100644 --- a/TODO +++ b/TODO @@ -153,20 +153,6 @@ Cellular VPN === -- l2tp support - - Priority: Low - Complexity: C2 - Owner: Mohamed Abbas mohamed.ab...@intel.com - - -- pptp support - - Priority: Low - Complexity: C2 - Owner: Mohamed Abbas mohamed.ab...@intel.com - - - IPsec Priority: Low -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
Re: [PATCH dns cache v3 1/2] dnsproxy: Implement A and AAAA DNS record caching.
Hi Marcel, On 07/20/2011 03:45 PM, Marcel Holtmann wrote: Hi Jukka, +static void send_cached_response(int sk, unsigned char *buf, int len, + const struct sockaddr *to, socklen_t tolen, + int protocol, int id, uint16_t answers) +{ + struct domain_hdr *hdr; + int err, offset = protocol_offset(protocol); + + if (offset 0) + return; + + if (len 12) + return; + + hdr = (void *) (buf + offset); + + hdr-id = id; + hdr-qr = 1; + hdr-rcode = 0; + hdr-ancount = htons(answers); + hdr-nscount = 0; + hdr-arcount = 0; I am still worried about unaligned access here. This might break on PowerPC for example. Hmm, actually the same construct is already used in send_response() function that can be found below the send_cached_response() func. So there are already problems in committed code if the above code does not work properly. + DBG(id 0x%04x answers %d, hdr-id, answers); + + err = sendto(sk, buf, len, 0, to, tolen); + if (err 0) + return; At least print an error here ;) Should I send a separate patch that fixes also the same issue in send_response()? +} static void send_response(int sk, unsigned char *buf, int len, const struct sockaddr *to, socklen_t tolen, @@ -325,12 +399,570 @@ static int append_query(unsigned char *buf, unsigned int size, return ptr - buf; } +static struct cache_entry *cache_check(gpointer request, int *qtype) +{ + unsigned char *question = (unsigned char *)request + 12; Space after that cast itself please: *) request. Is this case really needed? You are right, the cast is not needed. + struct cache_entry *entry; + struct domain_question *q; + time_t current_time; + uint16_t type; + int offset; + + offset = strlen((char *)question) + 1; Cast coding style please! However why do we bother with an unsigned char and then cast it to a char. Why not just cast it to a char in the first place. Ok, will do that. + q = (void *) (question + offset); + type = ntohs(q-type); + + /* we only cache either A (1) or (28) requests */ + if (type != 1 type != 28) + return NULL; + + entry = g_hash_table_lookup(cache, question); + if (entry == NULL) + return NULL; + + if (type == 1 entry-ipv4 == NULL) + return NULL; + + if (type == 28 entry-ipv6 == NULL) + return NULL; + + current_time = time(0); + + if (type == 1 (entry-ipv4-inserted + entry-ipv4-timeout + current_time)) { + DBG(cache timeout \%s\ type A, question); + + /* +* We do not remove cache entry if there is still valid IPv6 +* entry found in the cache. +*/ + if (entry-ipv6 == NULL || + (entry-ipv6-inserted + + entry-ipv6-timeout current_time)) + g_hash_table_remove(cache, question); + + return NULL; + } + + if (type == 28 (entry-ipv6-inserted + entry-ipv6-timeout + current_time)) { + DBG(cache timeout \%s\ type , question); + if (entry-ipv4 == NULL || + (entry-ipv4-inserted + + entry-ipv4-timeout current_time)) + g_hash_table_remove(cache, question); + + return NULL; + } I do not like this construct at all. First of all, we check the type four times. Why not factor this out into a switch statement and then call separate functions. Or create some helper lookup functions. Please spent some time to make this simpler and more readable. We are going to get lost if we ever have to read this code again. I reworked the fuction and split it into smaller pieces, hopefully it is more readable now. Does this look better? +static gboolean cache_check_if_valid(struct cache_data *data, + time_t current_time) +{ + if (data == NULL) + return FALSE; + + if (data-inserted + data-timeout current_time) + return FALSE; + + return TRUE; +} + +static uint16_t cache_check_validity(char *question, uint16_t type, + struct cache_data *ipv4, + struct cache_data *ipv6) +{ + time_t current_time; + gboolean valid; + + current_time = time(0); + + if (ipv4 != NULL type == 1) { + valid = cache_check_if_valid(ipv4, current_time); + if (valid == FALSE) { + DBG(cache timeout \%s\ type A,
Re: [PATCH dns cache v3 1/2] dnsproxy: Implement A and AAAA DNS record caching.
Hi Marcel, On 07/21/2011 02:11 PM, Marcel Holtmann wrote: Hi Jukka, + hdr = (void *) (buf + offset); + + hdr-id = id; + hdr-qr = 1; + hdr-rcode = 0; + hdr-ancount = htons(answers); + hdr-nscount = 0; + hdr-arcount = 0; I am still worried about unaligned access here. This might break on PowerPC for example. Hmm, actually the same construct is already used in send_response() function that can be found below the send_cached_response() func. So there are already problems in committed code if the above code does not work properly. that could be well true. I do not run around with a PowerPC machine all the time ;) I do not have access to powerpc either :( +static gboolean cache_check_if_valid(struct cache_data *data, + time_t current_time) +{ + if (data == NULL) + return FALSE; + + if (data-inserted + data-timeout current_time) + return FALSE; + + return TRUE; +} + +static uint16_t cache_check_validity(char *question, uint16_t type, + struct cache_data *ipv4, + struct cache_data *ipv6) +{ + time_t current_time; + gboolean valid; + + current_time = time(0); + + if (ipv4 != NULL type == 1) { You already have the ipv4 NULL check in cache_check_if_valid(). I put the NULL check there so that the debug print is not printed and confuse things. + valid = cache_check_if_valid(ipv4, current_time); + if (valid == FALSE) { What is the point of this variable? if (cache_check_if_valid(ipv4, current_time) == FALSE) I was using the form without a variable but remembered that the coding style in connman (at least most places) was to use always a helper variable. I am confused now :) + DBG(cache timeout \%s\ type A, question); + + /* +* We do not remove cache entry if there is still +* valid IPv6 entry found in the cache. +*/ + valid = cache_check_if_valid(ipv6, current_time); + if (valid == FALSE) + g_hash_table_remove(cache, question); + } else + type = 0; + + } else if (ipv6 != NULL type == 28) { + valid = cache_check_if_valid(ipv6, current_time); + if (valid == FALSE) { + DBG(cache timeout \%s\ type , question); + + valid = cache_check_if_valid(ipv4, current_time); + if (valid == FALSE) + g_hash_table_remove(cache, question); + } else + type = 0; + } So what about this: switch (type) { case 1: /* IPv4 */ if (cache_check_is_valid(...) == FALSE) { } break; case 28:/* IPv6 */ if (cache_check... break; } Sure. To me the if()'s looked better :) +static int get_name(int counter, + unsigned char *pkt, unsigned char *start, unsigned char *max, + unsigned char *output, int output_max, int *output_len, + unsigned char **end, char *name, int *name_len) +{ + unsigned char *p; + + /* Limit recursion to 10 (this means up to 10 labels in domain name) */ + if (counter 10) + return -EINVAL; + + p = start; + while (*p) { + if (*p NS_CMPRSFLGS) { + uint16_t offset = (*p 0x3F) * 256 + *(p + 1); + + if (offset= max - pkt) + return -ENOBUFS; + + if (*end == NULL) + *end = p + 2; + + return get_name(counter + 1, pkt, pkt + offset, max, + output, output_max, output_len, end, + name, name_len); + } else { + unsigned label_len = *p; + + if (pkt + label_len max) + return -ENOBUFS; + + if (*output_len output_max) + return -ENOBUFS; + + /* +* We need the original name in order to check +* if this answer is the correct one. +*/ + name[(*name_len)++] = label_len; + memcpy(name + *name_len, p + 1, label_len + 1); + *name_len += label_len; + + /* We compress the result */ + output[0] = NS_CMPRSFLGS; + output[1] = 0x0C; + *output_len = 2;
[PATCH] dnsproxy: Add error print when DNS response send failed.
--- src/dnsproxy.c |5 - 1 files changed, 4 insertions(+), 1 deletions(-) diff --git a/src/dnsproxy.c b/src/dnsproxy.c index 9701343..33206c0 100644 --- a/src/dnsproxy.c +++ b/src/dnsproxy.c @@ -215,8 +215,11 @@ static void send_response(int sk, unsigned char *buf, int len, hdr-arcount = 0; err = sendto(sk, buf, len, 0, to, tolen); - if (err 0) + if (err 0) { + connman_error(Cannot send DNS response: %s, + strerror(errno)); return; + } } static gboolean request_timeout(gpointer user_data) -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH dns cache v4 0/2] Implement DNS caching
Hi, this 4th version fixes following issues: - unnecessary castings removed - added lots of comments to various functions - refactored various functions Issue with possible unaligned memory access is still there as I have no hardware to check whether there are any real problems with the code. Regards, Jukka Jukka Rissanen (2): dnsproxy: Implement A and DNS record caching. TODO: DNS caching TODO |9 - src/dnsproxy.c | 787 +++- 2 files changed, 778 insertions(+), 18 deletions(-) ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH dns cache v4 2/2] TODO: DNS caching
--- TODO |9 - 1 files changed, 0 insertions(+), 9 deletions(-) diff --git a/TODO b/TODO index 36f8240..22078c8 100644 --- a/TODO +++ b/TODO @@ -36,15 +36,6 @@ Core credentials, ConnMan should be able to initiate a WiSPR authentication. -- DNS caching - - Priority: Low - Complexity: C4 - - A simple initial implementation would see ConnMan's dnsproxy - caching the DNS record based on their TTL. - - - Power management Priority: Medium -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH dns cache v4 1/2] dnsproxy: Implement A and AAAA DNS record caching.
--- src/dnsproxy.c | 787 +++- 1 files changed, 778 insertions(+), 9 deletions(-) diff --git a/src/dnsproxy.c b/src/dnsproxy.c index 33206c0..1241a61 100644 --- a/src/dnsproxy.c +++ b/src/dnsproxy.c @@ -32,6 +32,7 @@ #include sys/types.h #include sys/socket.h #include netdb.h +#include resolv.h #include glib.h @@ -123,6 +124,51 @@ struct listener_data { guint tcp_listener_watch; }; +struct cache_data { + time_t inserted; + int timeout; + uint16_t type; + uint16_t answers; + unsigned int data_len; + unsigned char *data; /* contains DNS header + body */ +}; + +struct cache_entry { + char *key; + struct cache_data *ipv4; + struct cache_data *ipv6; +}; + +struct domain_question { + uint16_t type; + uint16_t class; +} __attribute__ ((packed)); + +struct domain_rr { + uint16_t type; + uint16_t class; + uint32_t ttl; + uint16_t rdlen; +} __attribute__ ((packed)); + +/* + * We limit how long the cached DNS entry stays in the cache. + * By default the TTL (time-to-live) of the DNS response is used + * when setting the cache entry life time. The value is in seconds. + */ +#define MAX_CACHE_TTL (60 * 30) + +/* + * We limit the cache size to some sane value so that cached data does + * not occupy too much memory. Each cached entry occupies on average + * about 100 bytes memory (depending on DNS name length). + * Example: caching www.connman.net uses 97 bytes memory. + * The value is the max amount of cached DNS responses (count). + */ +#define MAX_CACHE_SIZE 256 + +static int cache_size; +static GHashTable *cache; static GSList *server_list = NULL; static GSList *request_list = NULL; static GSList *request_pending_list = NULL; @@ -187,6 +233,37 @@ static struct server_data *find_server(const char *interface, return NULL; } +static void send_cached_response(int sk, unsigned char *buf, int len, + const struct sockaddr *to, socklen_t tolen, + int protocol, int id, uint16_t answers) +{ + struct domain_hdr *hdr; + int err, offset = protocol_offset(protocol); + + if (offset 0) + return; + + if (len 12) + return; + + hdr = (void *) (buf + offset); + + hdr-id = id; + hdr-qr = 1; + hdr-rcode = 0; + hdr-ancount = htons(answers); + hdr-nscount = 0; + hdr-arcount = 0; + + DBG(id 0x%04x answers %d, hdr-id, answers); + + err = sendto(sk, buf, len, 0, to, tolen); + if (err 0) { + connman_error(Cannot send cached DNS response: %s, + strerror(errno)); + return; + } +} static void send_response(int sk, unsigned char *buf, int len, const struct sockaddr *to, socklen_t tolen, @@ -328,12 +405,646 @@ static int append_query(unsigned char *buf, unsigned int size, return ptr - buf; } +static gboolean cache_check_is_valid(struct cache_data *data, + time_t current_time) +{ + if (data == NULL) + return FALSE; + + if (data-inserted + data-timeout current_time) + return FALSE; + + return TRUE; +} + +static uint16_t cache_check_validity(char *question, uint16_t type, + struct cache_data *ipv4, + struct cache_data *ipv6) +{ + time_t current_time = time(0); + + switch (type) { + case 1: /* IPv4 */ + if (cache_check_is_valid(ipv4, current_time) == FALSE) { + DBG(cache %s \%s\ type A, + ipv4 ? timeout : entry missing, question); + + /* +* We do not remove cache entry if there is still +* valid IPv6 entry found in the cache. +*/ + if (cache_check_is_valid(ipv6, current_time) == FALSE) + g_hash_table_remove(cache, question); + + type = 0; + } + break; + + case 28:/* IPv6 */ + if (cache_check_is_valid(ipv6, current_time) == FALSE) { + DBG(cache %s \%s\ type , + ipv6 ? timeout : entry missing, question); + + if (cache_check_is_valid(ipv4, current_time) == FALSE) + g_hash_table_remove(cache, question); + + type = 0; + } + break; + } + + return type; +} + +static struct cache_entry *cache_check(gpointer request, int *qtype) +{ + char *question = request + 12; + struct cache_entry *entry; + struct domain_question *q; + uint16_t type; + int offset; + +
Re: [PATCH l2tp/pptp 01/21] vpn: Add support to allow ppp tunnelling.
Hi Daniel, On 07/22/2011 12:43 PM, Daniel Wagner wrote: Hi Jukka, + data-if_name = (char *)g_strdup(ifname); I know this should not part of your patch, but I think we do not free data-if_name. Or do I miss something? cheers, daniel The free is done in patch #18. So I did not change the original Mohamed's patch too much. Those original patches only contains the changes that you commented in February + fixes needed to make it compile against head. The rest of the patches mostly fixes bugs in the original patches. Jukka ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
Re: [PATCH l2tp/pptp 04/21] pptp: Add pptp vpn support
Hi Daniel, On 07/22/2011 12:57 PM, Daniel Wagner wrote: Hi Jukka, On Wed, Jul 20, 2011 at 10:30:38AM +0300, Jukka Rissanen wrote: From: Mohamed Abbasmab...@linux.intel.com Initial revision. --- plugins/pptp.c | 278 1 files changed, 278 insertions(+), 0 deletions(-) create mode 100644 plugins/pptp.c + if (!strcmp(key, INTERNAL_IP4_ADDRESS)) + connman_provider_set_string(provider, Address, value); + + if (!strcmp(key, INTERNAL_IP4_NETMASK)) + connman_provider_set_string(provider, Netmask, value); + + if (!strcmp(key, INTERNAL_IP4_DNS)) + connman_provider_set_string(provider, DNS, value); + + if (!strcmp(key, INTERNAL_IFNAME)) + ifname = (char *)g_strdup(value); + + dbus_message_iter_next(dict); + } I had a look what we are doing in openvpn.c here. We have there following sequence: connman_ipaddress_set_ipv4(ipaddress, address, NULL, gateway); connman_ipaddress_set_peer(ipaddress, peer); connman_provider_set_ipaddress(provider, ipaddress); connman_provider_set_nameservers(provider, nameservers); Also there is some nameserver handling code there. Don't we have to do this here too? Address setting is done in patch #15 for pptp and patch #11 for l2tp. cheers, daniel Jukka ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
Re: [PATCH l2tp/pptp 11/21] l2tp: Set the provider IP address when connected.
Hi Daniel, On 07/22/2011 01:19 PM, Daniel Wagner wrote: Hi Jukka, @@ -187,14 +193,39 @@ static int l2tp_notify(DBusMessage *msg, struct connman_provider *provider) ... + + g_free(addressv4); + g_free(netmask); + g_free(gateway); + connman_ipaddress_free(ipaddress); Here is the code I was missing. Wouldn't it make sense to merge this patch? Or do you want to keep it clear how has written which part? cheers, daniel I was thinking that I could fix the nitpicks (code style etc minor issues) in the original patches but bug fixes would go to separate patches. Jukka ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH dhcp 1/4] service: Remember last DHCP IP address.
--- src/connman.h |3 +++ src/service.c | 36 2 files changed, 39 insertions(+), 0 deletions(-) diff --git a/src/connman.h b/src/connman.h index 408b809..e687502 100644 --- a/src/connman.h +++ b/src/connman.h @@ -552,6 +552,9 @@ void __connman_service_notify(struct connman_service *service, int __connman_service_counter_register(const char *counter); void __connman_service_counter_unregister(const char *counter); +void __connman_service_set_dhcp_address(struct connman_service *service, + const char *address); +char *__connman_service_get_dhcp_address(struct connman_service *service); struct connman_session; struct service_entry; diff --git a/src/service.c b/src/service.c index b8f6aac..72e08a7 100644 --- a/src/service.c +++ b/src/service.c @@ -108,6 +108,7 @@ struct connman_service { char **excludes; char *pac; connman_bool_t wps; + char *last_dynamic_ip_address; }; static void append_path(gpointer value, gpointer user_data) @@ -3005,6 +3006,7 @@ static void service_free(gpointer user_data) g_free(service-private_key_file); g_free(service-private_key_passphrase); g_free(service-phase2); + g_free(service-last_dynamic_ip_address); if (service-stats.timer != NULL) g_timer_destroy(service-stats.timer); @@ -5003,6 +5005,24 @@ __connman_service_create_from_provider(struct connman_provider *provider) return service; } +void __connman_service_set_dhcp_address(struct connman_service *service, + const char *address) +{ + if (service == NULL) + return; + + g_free(service-last_dynamic_ip_address); + service-last_dynamic_ip_address = g_strdup(address); +} + +char *__connman_service_get_dhcp_address(struct connman_service *service) +{ + if (service == NULL) + return NULL; + + return g_strdup(service-last_dynamic_ip_address); +} + static int service_load(struct connman_service *service) { const char *ident = service-profile; @@ -5186,6 +5206,13 @@ static int service_load(struct connman_service *service) service-pac = str; } + str = g_key_file_get_string(keyfile, + service-identifier, DHCP.LastAddress, NULL); + if (str != NULL) { + g_free(service-last_dynamic_ip_address); + service-last_dynamic_ip_address = str; + } + done: g_key_file_free(keyfile); @@ -5366,6 +5393,15 @@ update: g_key_file_remove_key(keyfile, service-identifier, Proxy.URL, NULL); + if (service-last_dynamic_ip_address != NULL + strlen(service-last_dynamic_ip_address) 0) + g_key_file_set_string(keyfile, service-identifier, + DHCP.LastAddress, + service-last_dynamic_ip_address); + else + g_key_file_remove_key(keyfile, service-identifier, + DHCP.LastAddress, NULL); + data = g_key_file_to_data(keyfile, length, NULL); if (g_file_set_contents(pathname, data, length, NULL) == FALSE) -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH dhcp 0/4] Reuse last IP address.
Hi, the following patchset fixes the problem in bug #21068 https://bugs.meego.com/show_bug.cgi?id=21068 We suggest the DHCP server to give us the IP address we had last time. This is done by sending the DHCP REQUESTED IP option to server. Regards, Jukka Jukka Rissanen (4): service: Remember last DHCP IP address. gdhcp: Enable DHCP REQUESTED IP address option when starting client. tools: Add missing parameter. dhcp: Try to reuse the IP address we had last time. gdhcp/client.c| 22 ++ gdhcp/gdhcp.h |2 +- src/connman.h |3 +++ src/dhcp.c| 21 - src/service.c | 36 tools/dhcp-test.c |2 +- 6 files changed, 79 insertions(+), 7 deletions(-) ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH dhcp 3/4] tools: Add missing parameter.
--- tools/dhcp-test.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/tools/dhcp-test.c b/tools/dhcp-test.c index 1fbf1f9..18527c8 100644 --- a/tools/dhcp-test.c +++ b/tools/dhcp-test.c @@ -170,7 +170,7 @@ int main(int argc, char *argv[]) timer = g_timer_new(); - g_dhcp_client_start(dhcp_client); + g_dhcp_client_start(dhcp_client, NULL); memset(sa, 0, sizeof(sa)); sa.sa_handler = sig_term; -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH dhcp 2/4] gdhcp: Enable DHCP REQUESTED IP address option when starting client.
--- gdhcp/client.c | 22 ++ gdhcp/gdhcp.h |2 +- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/gdhcp/client.c b/gdhcp/client.c index 0cf39cd..9ac7752 100644 --- a/gdhcp/client.c +++ b/gdhcp/client.c @@ -109,6 +109,7 @@ struct _GDHCPClient { gpointer address_conflict_data; GDHCPDebugFunc debug_func; gpointer debug_data; + char *last_address; }; static inline void debug(GDHCPClient *client, const char *format, ...) @@ -879,7 +880,7 @@ static void restart_dhcp(GDHCPClient *dhcp_client, int retry_times) dhcp_client-requested_ip = 0; switch_listening_mode(dhcp_client, L2); - g_dhcp_client_start(dhcp_client); + g_dhcp_client_start(dhcp_client, dhcp_client-last_address); } static gboolean start_rebound_timeout(gpointer user_data) @@ -1240,7 +1241,7 @@ static gboolean discover_timeout(gpointer user_data) dhcp_client-retry_times++; - g_dhcp_client_start(dhcp_client); + g_dhcp_client_start(dhcp_client, dhcp_client-last_address); return FALSE; } @@ -1306,9 +1307,10 @@ static gboolean ipv4ll_probe_timeout(gpointer dhcp_data) return FALSE; } -int g_dhcp_client_start(GDHCPClient *dhcp_client) +int g_dhcp_client_start(GDHCPClient *dhcp_client, const char *last_address) { int re; + uint32_t addr; if (dhcp_client-retry_times == DISCOVER_RETRIES) { ipv4ll_start(dhcp_client); @@ -1327,7 +1329,18 @@ int g_dhcp_client_start(GDHCPClient *dhcp_client) dhcp_client-xid = rand(); } - send_discover(dhcp_client, 0); + if (last_address == NULL) + addr = 0; + else { + addr = inet_addr(last_address); + if (addr == 0x) + addr = 0; + else { + g_free(dhcp_client-last_address); + dhcp_client-last_address = g_strdup(last_address); + } + } + send_discover(dhcp_client, addr); dhcp_client-timeout = g_timeout_add_seconds_full(G_PRIORITY_HIGH, DISCOVER_TIMEOUT, @@ -1505,6 +1518,7 @@ void g_dhcp_client_unref(GDHCPClient *dhcp_client) g_free(dhcp_client-interface); g_free(dhcp_client-assigned_ip); + g_free(dhcp_client-last_address); g_list_free(dhcp_client-request_list); g_list_free(dhcp_client-require_list); diff --git a/gdhcp/gdhcp.h b/gdhcp/gdhcp.h index 4f583ff..d89446e 100644 --- a/gdhcp/gdhcp.h +++ b/gdhcp/gdhcp.h @@ -73,7 +73,7 @@ typedef void (*GDHCPDebugFunc)(const char *str, gpointer user_data); GDHCPClient *g_dhcp_client_new(GDHCPType type, int index, GDHCPClientError *error); -int g_dhcp_client_start(GDHCPClient *client); +int g_dhcp_client_start(GDHCPClient *client, const char *last_address); void g_dhcp_client_stop(GDHCPClient *client); GDHCPClient *g_dhcp_client_ref(GDHCPClient *client); -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH dhcp 4/4] dhcp: Try to reuse the IP address we had last time.
This fix sends the DHCP_REQUESTED_IP option to server. Fixes BMC #21068 --- src/dhcp.c | 21 - 1 files changed, 20 insertions(+), 1 deletions(-) diff --git a/src/dhcp.c b/src/dhcp.c index 20fc599..0f93b95 100644 --- a/src/dhcp.c +++ b/src/dhcp.c @@ -42,6 +42,7 @@ struct connman_dhcp { char **nameservers; char *timeserver; char *pac; + char *last_address; GDHCPClient *dhcp_client; }; @@ -53,10 +54,12 @@ static void dhcp_free(struct connman_dhcp *dhcp) g_strfreev(dhcp-nameservers); g_free(dhcp-timeserver); g_free(dhcp-pac); + g_free(dhcp-last_address); dhcp-nameservers = NULL; dhcp-timeserver = NULL; dhcp-pac = NULL; + dhcp-last_address = NULL; } /** @@ -103,6 +106,10 @@ static void dhcp_invalidate(struct connman_dhcp *dhcp, connman_bool_t callback) } } + __connman_service_set_dhcp_address(service, dhcp-last_address); + + DBG(last address %s, dhcp-last_address); + __connman_ipconfig_address_remove(ipconfig); __connman_ipconfig_set_local(ipconfig, NULL); @@ -204,6 +211,12 @@ static void lease_available_cb(GDHCPClient *dhcp_client, gpointer user_data) address = g_dhcp_client_get_address(dhcp_client); + g_free(dhcp-last_address); + dhcp-last_address = g_strdup(address); + __connman_service_set_dhcp_address(service, dhcp-last_address); + + DBG(last address %s, address); + option = g_dhcp_client_get_option(dhcp_client, G_DHCP_SUBNET); if (option != NULL) netmask = g_strdup(option-data); @@ -409,7 +422,7 @@ static int dhcp_request(struct connman_dhcp *dhcp) dhcp-dhcp_client = dhcp_client; - return g_dhcp_client_start(dhcp_client); + return g_dhcp_client_start(dhcp_client, dhcp-last_address); } static int dhcp_release(struct connman_dhcp *dhcp) @@ -442,6 +455,7 @@ static void remove_network(gpointer user_data) int __connman_dhcp_start(struct connman_network *network, dhcp_cb callback) { struct connman_dhcp *dhcp; + struct connman_service *service; DBG(); @@ -452,6 +466,11 @@ int __connman_dhcp_start(struct connman_network *network, dhcp_cb callback) dhcp-network = network; dhcp-callback = callback; + service = __connman_service_lookup_from_network(network); + dhcp-last_address = __connman_service_get_dhcp_address(service); + + DBG(last address %s, dhcp-last_address); + g_hash_table_replace(network_table, network, dhcp); return dhcp_request(dhcp); -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH dhcp v2 1/2] ipconfig: Remember last DHCP IP address.
--- src/connman.h |3 +++ src/ipconfig.c | 40 +++- 2 files changed, 42 insertions(+), 1 deletions(-) diff --git a/src/connman.h b/src/connman.h index 408b809..d6acae4 100644 --- a/src/connman.h +++ b/src/connman.h @@ -257,6 +257,9 @@ unsigned char __connman_ipconfig_netmask_prefix_len(const char *netmask); int __connman_ipconfig_set_proxy_autoconfig(struct connman_ipconfig *ipconfig, const char *url); const char *__connman_ipconfig_get_proxy_autoconfig(struct connman_ipconfig *ipconfig); +void __connman_ipconfig_set_dhcp_address(struct connman_ipconfig *ipconfig, + const char *address); +char *__connman_ipconfig_get_dhcp_address(struct connman_ipconfig *ipconfig); int __connman_ipconfig_load(struct connman_ipconfig *ipconfig, GKeyFile *keyfile, const char *identifier, const char *prefix); diff --git a/src/ipconfig.c b/src/ipconfig.c index 9f73b65..7fb56a4 100644 --- a/src/ipconfig.c +++ b/src/ipconfig.c @@ -54,6 +54,7 @@ struct connman_ipconfig { struct connman_ipaddress *system; int ipv6_privacy_config; + char *last_dynamic_ip_address; }; struct connman_ipdevice { @@ -1286,6 +1287,7 @@ void connman_ipconfig_unref(struct connman_ipconfig *ipconfig) connman_ipaddress_free(ipconfig-system); connman_ipaddress_free(ipconfig-address); + g_free(ipconfig-last_dynamic_ip_address); g_free(ipconfig); } } @@ -1518,6 +1520,24 @@ const char *__connman_ipconfig_get_proxy_autoconfig(struct connman_ipconfig *ipc return ipdevice-pac; } +void __connman_ipconfig_set_dhcp_address(struct connman_ipconfig *ipconfig, + const char *address) +{ + if (ipconfig == NULL) + return; + + g_free(ipconfig-last_dynamic_ip_address); + ipconfig-last_dynamic_ip_address = g_strdup(address); +} + +char *__connman_ipconfig_get_dhcp_address(struct connman_ipconfig *ipconfig) +{ + if (ipconfig == NULL) + return NULL; + + return g_strdup(ipconfig-last_dynamic_ip_address); +} + static void disable_ipv6(struct connman_ipconfig *ipconfig) { struct connman_ipdevice *ipdevice; @@ -2080,6 +2100,7 @@ int __connman_ipconfig_load(struct connman_ipconfig *ipconfig, { char *method; char *key; + char *str; DBG(ipconfig %p identifier %s, ipconfig, identifier); @@ -2140,6 +2161,14 @@ int __connman_ipconfig_load(struct connman_ipconfig *ipconfig, keyfile, identifier, key, NULL); g_free(key); + key = g_strdup_printf(%sDHCP.LastAddress, prefix); + str = g_key_file_get_string(keyfile, identifier, key, NULL); + if (str != NULL) { + g_free(ipconfig-last_dynamic_ip_address); + ipconfig-last_dynamic_ip_address = str; + } + g_free(key); + return 0; } @@ -2169,9 +2198,18 @@ int __connman_ipconfig_save(struct connman_ipconfig *ipconfig, case CONNMAN_IPCONFIG_METHOD_FIXED: case CONNMAN_IPCONFIG_METHOD_MANUAL: break; + case CONNMAN_IPCONFIG_METHOD_DHCP: + key = g_strdup_printf(%sDHCP.LastAddress, prefix); + if (ipconfig-last_dynamic_ip_address != NULL + strlen(ipconfig-last_dynamic_ip_address) 0) + g_key_file_set_string(keyfile, identifier, key, + ipconfig-last_dynamic_ip_address); + else + g_key_file_remove_key(keyfile, identifier, key, NULL); + g_free(key); + /* fall through */ case CONNMAN_IPCONFIG_METHOD_UNKNOWN: case CONNMAN_IPCONFIG_METHOD_OFF: - case CONNMAN_IPCONFIG_METHOD_DHCP: case CONNMAN_IPCONFIG_METHOD_AUTO: return 0; } -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
Re: [PATCH dhcp v2 0/2] Reuse last IP address.
I just noticed that this patch is not yet ready. I missed the non-authoritative server case where the server ignores the request with REQUESTED IP option. I will send a new version soonish. Jukka On 07/27/2011 01:58 PM, Jukka Rissanen wrote: Hi, changes in this v2 patch: - The IP address is saved in ipconfig instead of service - I also merged three patches to one so that they do not break the build. The following patchset fixes the problem in bug #21068 https://bugs.meego.com/show_bug.cgi?id=21068 We suggest the DHCP server to give us the IP address we had last time. This is done by sending the DHCP REQUESTED IP option to server. Regards, Jukka Jukka Rissanen (2): ipconfig: Remember last DHCP IP address. dhcp: Try to reuse the IP address we had last time. gdhcp/client.c| 22 ++ gdhcp/gdhcp.h |2 +- src/connman.h |3 +++ src/dhcp.c| 23 ++- src/ipconfig.c| 40 +++- tools/dhcp-test.c |2 +- 6 files changed, 84 insertions(+), 8 deletions(-) ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH dhcp v3 1/2] ipconfig: Remember last DHCP IP address.
--- src/connman.h |3 +++ src/ipconfig.c | 40 +++- 2 files changed, 42 insertions(+), 1 deletions(-) diff --git a/src/connman.h b/src/connman.h index 681b29f..3fc5a8a 100644 --- a/src/connman.h +++ b/src/connman.h @@ -257,6 +257,9 @@ unsigned char __connman_ipconfig_netmask_prefix_len(const char *netmask); int __connman_ipconfig_set_proxy_autoconfig(struct connman_ipconfig *ipconfig, const char *url); const char *__connman_ipconfig_get_proxy_autoconfig(struct connman_ipconfig *ipconfig); +void __connman_ipconfig_set_dhcp_address(struct connman_ipconfig *ipconfig, + const char *address); +char *__connman_ipconfig_get_dhcp_address(struct connman_ipconfig *ipconfig); int __connman_ipconfig_load(struct connman_ipconfig *ipconfig, GKeyFile *keyfile, const char *identifier, const char *prefix); diff --git a/src/ipconfig.c b/src/ipconfig.c index 9f73b65..7fb56a4 100644 --- a/src/ipconfig.c +++ b/src/ipconfig.c @@ -54,6 +54,7 @@ struct connman_ipconfig { struct connman_ipaddress *system; int ipv6_privacy_config; + char *last_dynamic_ip_address; }; struct connman_ipdevice { @@ -1286,6 +1287,7 @@ void connman_ipconfig_unref(struct connman_ipconfig *ipconfig) connman_ipaddress_free(ipconfig-system); connman_ipaddress_free(ipconfig-address); + g_free(ipconfig-last_dynamic_ip_address); g_free(ipconfig); } } @@ -1518,6 +1520,24 @@ const char *__connman_ipconfig_get_proxy_autoconfig(struct connman_ipconfig *ipc return ipdevice-pac; } +void __connman_ipconfig_set_dhcp_address(struct connman_ipconfig *ipconfig, + const char *address) +{ + if (ipconfig == NULL) + return; + + g_free(ipconfig-last_dynamic_ip_address); + ipconfig-last_dynamic_ip_address = g_strdup(address); +} + +char *__connman_ipconfig_get_dhcp_address(struct connman_ipconfig *ipconfig) +{ + if (ipconfig == NULL) + return NULL; + + return g_strdup(ipconfig-last_dynamic_ip_address); +} + static void disable_ipv6(struct connman_ipconfig *ipconfig) { struct connman_ipdevice *ipdevice; @@ -2080,6 +2100,7 @@ int __connman_ipconfig_load(struct connman_ipconfig *ipconfig, { char *method; char *key; + char *str; DBG(ipconfig %p identifier %s, ipconfig, identifier); @@ -2140,6 +2161,14 @@ int __connman_ipconfig_load(struct connman_ipconfig *ipconfig, keyfile, identifier, key, NULL); g_free(key); + key = g_strdup_printf(%sDHCP.LastAddress, prefix); + str = g_key_file_get_string(keyfile, identifier, key, NULL); + if (str != NULL) { + g_free(ipconfig-last_dynamic_ip_address); + ipconfig-last_dynamic_ip_address = str; + } + g_free(key); + return 0; } @@ -2169,9 +2198,18 @@ int __connman_ipconfig_save(struct connman_ipconfig *ipconfig, case CONNMAN_IPCONFIG_METHOD_FIXED: case CONNMAN_IPCONFIG_METHOD_MANUAL: break; + case CONNMAN_IPCONFIG_METHOD_DHCP: + key = g_strdup_printf(%sDHCP.LastAddress, prefix); + if (ipconfig-last_dynamic_ip_address != NULL + strlen(ipconfig-last_dynamic_ip_address) 0) + g_key_file_set_string(keyfile, identifier, key, + ipconfig-last_dynamic_ip_address); + else + g_key_file_remove_key(keyfile, identifier, key, NULL); + g_free(key); + /* fall through */ case CONNMAN_IPCONFIG_METHOD_UNKNOWN: case CONNMAN_IPCONFIG_METHOD_OFF: - case CONNMAN_IPCONFIG_METHOD_DHCP: case CONNMAN_IPCONFIG_METHOD_AUTO: return 0; } -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH dhcp v3 0/2] Reuse last IP address.
Hi, changes in v3: - Do not send REQUESTED IP option in resend because the non-authoritative server case will drop those packets changes in v2: - The IP address is saved in ipconfig instead of service - I also merged three patches to one so that they do not break the build. The following patchset fixes the problem in bug #21068 https://bugs.meego.com/show_bug.cgi?id=21068 We suggest the DHCP server to give us the IP address we had last time. This is done by sending the DHCP REQUESTED IP option to server. Regards, Jukka Jukka Rissanen (2): ipconfig: Remember last DHCP IP address. dhcp: Try to reuse the IP address we had last time. gdhcp/client.c| 27 +++ gdhcp/gdhcp.h |2 +- src/connman.h |3 +++ src/dhcp.c| 23 ++- src/ipconfig.c| 40 +++- tools/dhcp-test.c |2 +- 6 files changed, 89 insertions(+), 8 deletions(-) ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH dhcp v3 2/2] dhcp: Try to reuse the IP address we had last time.
This fix will cause the DHCP_REQUESTED_IP option to be sent to the server. Fixes BMC #21068 --- gdhcp/client.c| 27 +++ gdhcp/gdhcp.h |2 +- src/dhcp.c| 23 ++- tools/dhcp-test.c |2 +- 4 files changed, 47 insertions(+), 7 deletions(-) diff --git a/gdhcp/client.c b/gdhcp/client.c index 0cf39cd..f491f5c 100644 --- a/gdhcp/client.c +++ b/gdhcp/client.c @@ -109,6 +109,7 @@ struct _GDHCPClient { gpointer address_conflict_data; GDHCPDebugFunc debug_func; gpointer debug_data; + char *last_address; }; static inline void debug(GDHCPClient *client, const char *format, ...) @@ -879,7 +880,7 @@ static void restart_dhcp(GDHCPClient *dhcp_client, int retry_times) dhcp_client-requested_ip = 0; switch_listening_mode(dhcp_client, L2); - g_dhcp_client_start(dhcp_client); + g_dhcp_client_start(dhcp_client, dhcp_client-last_address); } static gboolean start_rebound_timeout(gpointer user_data) @@ -1240,7 +1241,12 @@ static gboolean discover_timeout(gpointer user_data) dhcp_client-retry_times++; - g_dhcp_client_start(dhcp_client); + /* +* We do not send the REQUESTED IP option if we are retrying because +* if the server is non-authoritative it will ignore the request if the +* option is present. +*/ + g_dhcp_client_start(dhcp_client, NULL); return FALSE; } @@ -1306,9 +1312,10 @@ static gboolean ipv4ll_probe_timeout(gpointer dhcp_data) return FALSE; } -int g_dhcp_client_start(GDHCPClient *dhcp_client) +int g_dhcp_client_start(GDHCPClient *dhcp_client, const char *last_address) { int re; + uint32_t addr; if (dhcp_client-retry_times == DISCOVER_RETRIES) { ipv4ll_start(dhcp_client); @@ -1327,7 +1334,18 @@ int g_dhcp_client_start(GDHCPClient *dhcp_client) dhcp_client-xid = rand(); } - send_discover(dhcp_client, 0); + if (last_address == NULL) + addr = 0; + else { + addr = inet_addr(last_address); + if (addr == 0x) + addr = 0; + else { + g_free(dhcp_client-last_address); + dhcp_client-last_address = g_strdup(last_address); + } + } + send_discover(dhcp_client, addr); dhcp_client-timeout = g_timeout_add_seconds_full(G_PRIORITY_HIGH, DISCOVER_TIMEOUT, @@ -1505,6 +1523,7 @@ void g_dhcp_client_unref(GDHCPClient *dhcp_client) g_free(dhcp_client-interface); g_free(dhcp_client-assigned_ip); + g_free(dhcp_client-last_address); g_list_free(dhcp_client-request_list); g_list_free(dhcp_client-require_list); diff --git a/gdhcp/gdhcp.h b/gdhcp/gdhcp.h index 4f583ff..d89446e 100644 --- a/gdhcp/gdhcp.h +++ b/gdhcp/gdhcp.h @@ -73,7 +73,7 @@ typedef void (*GDHCPDebugFunc)(const char *str, gpointer user_data); GDHCPClient *g_dhcp_client_new(GDHCPType type, int index, GDHCPClientError *error); -int g_dhcp_client_start(GDHCPClient *client); +int g_dhcp_client_start(GDHCPClient *client, const char *last_address); void g_dhcp_client_stop(GDHCPClient *client); GDHCPClient *g_dhcp_client_ref(GDHCPClient *client); diff --git a/src/dhcp.c b/src/dhcp.c index 39f4eeb..0e31e86 100644 --- a/src/dhcp.c +++ b/src/dhcp.c @@ -42,6 +42,7 @@ struct connman_dhcp { char **nameservers; char *timeserver; char *pac; + char *last_address; GDHCPClient *dhcp_client; }; @@ -53,10 +54,12 @@ static void dhcp_free(struct connman_dhcp *dhcp) g_strfreev(dhcp-nameservers); g_free(dhcp-timeserver); g_free(dhcp-pac); + g_free(dhcp-last_address); dhcp-nameservers = NULL; dhcp-timeserver = NULL; dhcp-pac = NULL; + dhcp-last_address = NULL; } /** @@ -103,6 +106,10 @@ static void dhcp_invalidate(struct connman_dhcp *dhcp, connman_bool_t callback) } } + __connman_ipconfig_set_dhcp_address(ipconfig, dhcp-last_address); + + DBG(last address %s, dhcp-last_address); + __connman_ipconfig_address_remove(ipconfig); __connman_ipconfig_set_local(ipconfig, NULL); @@ -205,6 +212,12 @@ static void lease_available_cb(GDHCPClient *dhcp_client, gpointer user_data) address = g_dhcp_client_get_address(dhcp_client); + g_free(dhcp-last_address); + dhcp-last_address = g_strdup(address); + __connman_ipconfig_set_dhcp_address(ipconfig, dhcp-last_address); + + DBG(last address %s, address); + option = g_dhcp_client_get_option(dhcp_client, G_DHCP_SUBNET); if (option != NULL) netmask = g_strdup(option-data); @@ -412,7 +425,7 @@ static int dhcp_request(struct
[PATCH dhcp v4 1/2] ipconfig: Remember last DHCP IP address.
--- src/connman.h |3 +++ src/ipconfig.c | 40 +++- 2 files changed, 42 insertions(+), 1 deletions(-) diff --git a/src/connman.h b/src/connman.h index 681b29f..3fc5a8a 100644 --- a/src/connman.h +++ b/src/connman.h @@ -257,6 +257,9 @@ unsigned char __connman_ipconfig_netmask_prefix_len(const char *netmask); int __connman_ipconfig_set_proxy_autoconfig(struct connman_ipconfig *ipconfig, const char *url); const char *__connman_ipconfig_get_proxy_autoconfig(struct connman_ipconfig *ipconfig); +void __connman_ipconfig_set_dhcp_address(struct connman_ipconfig *ipconfig, + const char *address); +char *__connman_ipconfig_get_dhcp_address(struct connman_ipconfig *ipconfig); int __connman_ipconfig_load(struct connman_ipconfig *ipconfig, GKeyFile *keyfile, const char *identifier, const char *prefix); diff --git a/src/ipconfig.c b/src/ipconfig.c index 9f73b65..aa8274c 100644 --- a/src/ipconfig.c +++ b/src/ipconfig.c @@ -54,6 +54,7 @@ struct connman_ipconfig { struct connman_ipaddress *system; int ipv6_privacy_config; + char *last_dhcp_address; }; struct connman_ipdevice { @@ -1286,6 +1287,7 @@ void connman_ipconfig_unref(struct connman_ipconfig *ipconfig) connman_ipaddress_free(ipconfig-system); connman_ipaddress_free(ipconfig-address); + g_free(ipconfig-last_dhcp_address); g_free(ipconfig); } } @@ -1518,6 +1520,24 @@ const char *__connman_ipconfig_get_proxy_autoconfig(struct connman_ipconfig *ipc return ipdevice-pac; } +void __connman_ipconfig_set_dhcp_address(struct connman_ipconfig *ipconfig, + const char *address) +{ + if (ipconfig == NULL) + return; + + g_free(ipconfig-last_dhcp_address); + ipconfig-last_dhcp_address = g_strdup(address); +} + +char *__connman_ipconfig_get_dhcp_address(struct connman_ipconfig *ipconfig) +{ + if (ipconfig == NULL) + return NULL; + + return ipconfig-last_dhcp_address; +} + static void disable_ipv6(struct connman_ipconfig *ipconfig) { struct connman_ipdevice *ipdevice; @@ -2080,6 +2100,7 @@ int __connman_ipconfig_load(struct connman_ipconfig *ipconfig, { char *method; char *key; + char *str; DBG(ipconfig %p identifier %s, ipconfig, identifier); @@ -2140,6 +2161,14 @@ int __connman_ipconfig_load(struct connman_ipconfig *ipconfig, keyfile, identifier, key, NULL); g_free(key); + key = g_strdup_printf(%sDHCP.LastAddress, prefix); + str = g_key_file_get_string(keyfile, identifier, key, NULL); + if (str != NULL) { + g_free(ipconfig-last_dhcp_address); + ipconfig-last_dhcp_address = str; + } + g_free(key); + return 0; } @@ -2169,9 +2198,18 @@ int __connman_ipconfig_save(struct connman_ipconfig *ipconfig, case CONNMAN_IPCONFIG_METHOD_FIXED: case CONNMAN_IPCONFIG_METHOD_MANUAL: break; + case CONNMAN_IPCONFIG_METHOD_DHCP: + key = g_strdup_printf(%sDHCP.LastAddress, prefix); + if (ipconfig-last_dhcp_address != NULL + strlen(ipconfig-last_dhcp_address) 0) + g_key_file_set_string(keyfile, identifier, key, + ipconfig-last_dhcp_address); + else + g_key_file_remove_key(keyfile, identifier, key, NULL); + g_free(key); + /* fall through */ case CONNMAN_IPCONFIG_METHOD_UNKNOWN: case CONNMAN_IPCONFIG_METHOD_OFF: - case CONNMAN_IPCONFIG_METHOD_DHCP: case CONNMAN_IPCONFIG_METHOD_AUTO: return 0; } -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH dhcp v4 0/2] Reuse last IP address.
Hi, changes in v4: - style issues in gdhcp/client.c - get rid of last_address var in dhcp.c - variable name changed in ipconfig.c changes in v3: - Do not send REQUESTED IP option in resend because the non-authoritative server case will drop those packets changes in v2: - The IP address is saved in ipconfig instead of service - I also merged three patches to one so that they do not break the build. The following patchset fixes the problem in bug #21068 https://bugs.meego.com/show_bug.cgi?id=21068 We suggest the DHCP server to give us the IP address we had last time. This is done by sending the DHCP REQUESTED IP option to server. Regards, Jukka Jukka Rissanen (2): ipconfig: Remember last DHCP IP address. dhcp: Try to reuse the IP address we had last time. gdhcp/client.c| 27 +++ gdhcp/gdhcp.h |2 +- src/connman.h |3 +++ src/dhcp.c| 15 ++- src/ipconfig.c| 40 +++- tools/dhcp-test.c |2 +- 6 files changed, 81 insertions(+), 8 deletions(-) ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH dhcp v4 2/2] dhcp: Try to reuse the IP address we had last time.
This fix will cause the DHCP_REQUESTED_IP option to be sent to the server. Fixes BMC #21068 --- gdhcp/client.c| 27 +++ gdhcp/gdhcp.h |2 +- src/dhcp.c| 15 ++- tools/dhcp-test.c |2 +- 4 files changed, 39 insertions(+), 7 deletions(-) diff --git a/gdhcp/client.c b/gdhcp/client.c index 0cf39cd..8ea75d6 100644 --- a/gdhcp/client.c +++ b/gdhcp/client.c @@ -109,6 +109,7 @@ struct _GDHCPClient { gpointer address_conflict_data; GDHCPDebugFunc debug_func; gpointer debug_data; + char *last_address; }; static inline void debug(GDHCPClient *client, const char *format, ...) @@ -879,7 +880,7 @@ static void restart_dhcp(GDHCPClient *dhcp_client, int retry_times) dhcp_client-requested_ip = 0; switch_listening_mode(dhcp_client, L2); - g_dhcp_client_start(dhcp_client); + g_dhcp_client_start(dhcp_client, dhcp_client-last_address); } static gboolean start_rebound_timeout(gpointer user_data) @@ -1240,7 +1241,12 @@ static gboolean discover_timeout(gpointer user_data) dhcp_client-retry_times++; - g_dhcp_client_start(dhcp_client); + /* +* We do not send the REQUESTED IP option if we are retrying because +* if the server is non-authoritative it will ignore the request if the +* option is present. +*/ + g_dhcp_client_start(dhcp_client, NULL); return FALSE; } @@ -1306,9 +1312,10 @@ static gboolean ipv4ll_probe_timeout(gpointer dhcp_data) return FALSE; } -int g_dhcp_client_start(GDHCPClient *dhcp_client) +int g_dhcp_client_start(GDHCPClient *dhcp_client, const char *last_address) { int re; + uint32_t addr; if (dhcp_client-retry_times == DISCOVER_RETRIES) { ipv4ll_start(dhcp_client); @@ -1327,7 +1334,18 @@ int g_dhcp_client_start(GDHCPClient *dhcp_client) dhcp_client-xid = rand(); } - send_discover(dhcp_client, 0); + if (last_address == NULL) { + addr = 0; + } else { + addr = inet_addr(last_address); + if (addr == 0x) { + addr = 0; + } else { + g_free(dhcp_client-last_address); + dhcp_client-last_address = g_strdup(last_address); + } + } + send_discover(dhcp_client, addr); dhcp_client-timeout = g_timeout_add_seconds_full(G_PRIORITY_HIGH, DISCOVER_TIMEOUT, @@ -1505,6 +1523,7 @@ void g_dhcp_client_unref(GDHCPClient *dhcp_client) g_free(dhcp_client-interface); g_free(dhcp_client-assigned_ip); + g_free(dhcp_client-last_address); g_list_free(dhcp_client-request_list); g_list_free(dhcp_client-require_list); diff --git a/gdhcp/gdhcp.h b/gdhcp/gdhcp.h index 4f583ff..d89446e 100644 --- a/gdhcp/gdhcp.h +++ b/gdhcp/gdhcp.h @@ -73,7 +73,7 @@ typedef void (*GDHCPDebugFunc)(const char *str, gpointer user_data); GDHCPClient *g_dhcp_client_new(GDHCPType type, int index, GDHCPClientError *error); -int g_dhcp_client_start(GDHCPClient *client); +int g_dhcp_client_start(GDHCPClient *client, const char *last_address); void g_dhcp_client_stop(GDHCPClient *client); GDHCPClient *g_dhcp_client_ref(GDHCPClient *client); diff --git a/src/dhcp.c b/src/dhcp.c index 39f4eeb..10e1403 100644 --- a/src/dhcp.c +++ b/src/dhcp.c @@ -103,6 +103,10 @@ static void dhcp_invalidate(struct connman_dhcp *dhcp, connman_bool_t callback) } } + __connman_ipconfig_set_dhcp_address(ipconfig, + __connman_ipconfig_get_local(ipconfig)); + DBG(last address %s, __connman_ipconfig_get_dhcp_address(ipconfig)); + __connman_ipconfig_address_remove(ipconfig); __connman_ipconfig_set_local(ipconfig, NULL); @@ -205,6 +209,9 @@ static void lease_available_cb(GDHCPClient *dhcp_client, gpointer user_data) address = g_dhcp_client_get_address(dhcp_client); + __connman_ipconfig_set_dhcp_address(ipconfig, address); + DBG(last address %s, address); + option = g_dhcp_client_get_option(dhcp_client, G_DHCP_SUBNET); if (option != NULL) netmask = g_strdup(option-data); @@ -365,6 +372,8 @@ static void dhcp_debug(const char *str, void *data) static int dhcp_request(struct connman_dhcp *dhcp) { + struct connman_service *service; + struct connman_ipconfig *ipconfig; GDHCPClient *dhcp_client; GDHCPClientError error; const char *hostname; @@ -412,7 +421,11 @@ static int dhcp_request(struct connman_dhcp *dhcp) dhcp-dhcp_client = dhcp_client; - return g_dhcp_client_start(dhcp_client); + service = __connman_service_lookup_from_network(dhcp-network); + ipconfig =
Re: [PATCH dhcp v4 1/2] ipconfig: Remember last DHCP IP address.
Hi Marcel, On 07/28/2011 02:13 PM, Marcel Holtmann wrote: Hi Jukka, src/connman.h |3 +++ src/ipconfig.c | 40 +++- 2 files changed, 42 insertions(+), 1 deletions(-) @@ -2169,9 +2198,18 @@ int __connman_ipconfig_save(struct connman_ipconfig *ipconfig, case CONNMAN_IPCONFIG_METHOD_FIXED: case CONNMAN_IPCONFIG_METHOD_MANUAL: break; + case CONNMAN_IPCONFIG_METHOD_DHCP: + key = g_strdup_printf(%sDHCP.LastAddress, prefix); + if (ipconfig-last_dhcp_address != NULL + strlen(ipconfig-last_dhcp_address) 0) + g_key_file_set_string(keyfile, identifier, key, + ipconfig-last_dhcp_address); + else + g_key_file_remove_key(keyfile, identifier, key, NULL); + g_free(key); + /* fall through */ I am against storing the last IP address from DHCP on disk. What is this good for? I have been running this patch on my meego netbook and it has been very useful. Now I get the same IP address back almost always which makes it easy to ssh to the device and I do not have to constantly check my IP address in netbook (of course this is perhaps a useful use case for me only). The DHCP REQUESTED IP address option is just a hint to the server anyway. When you leave the current network to switch to a different one or when you shutdown your laptop, why bother with trying to keep the same address. I rather not actually. Hmm, I would rather do actually :) There is some more discussion here https://bugs.meego.com/show_bug.cgi?id=21068 When connected to the same network and roaming between access points, then yes, you should keep the same address, but that is only valid as long as ConnMan is actually running. Regards Marcel Jukka ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH pre-l2tp/pptp v2 00/14] Preliminary patches for L2TP/PPTP patchset
Hi, v2 changes: - swapped the null check in patch #01 - added two more patches after noticing crashes when testing patch #08 The crashes happened when I was connected via ethernet and the IPv6 method was set to OFF. Then I removed ethernet cable and immediately set the IPv6 method to AUTO. This cable un-plugging caused the service-network to be become NULL and method setting to AUTO was trying to access NULL pointer. So it seems that there is a race somewhere, unfortunately the patches #13 and #14 do not fix the race, they just prevent the crash in these cases. - when reviewing the #08, I noticed service state errors when combining IPv4 and IPv6 states. This is now fixed in patch #08 and #09 so here are patches that are needed by L2TP/PPTP patches that I will be updating and sending soonish. The patches are not related to L2TP/PPTP but are generic fixes. They mainly fix bugs and also implement authentication failure notification to the user (via agent API). The auth failure notification works with every VPN driver after these fixes. 01 - provider driver name null check 02 - Set the authentication failure error code so that we can catch VPN authentication errors. 03 - Return ipconfig state to caller. Needed by patch #04 04 - Do not change the service disconnect state unless we were really disconnecting the service. This means that if the service is in idle / failure state, we do not mark the ipconfig state as disconnected. This is useful in VPN case so that we do not lose the failure state when combining the states. 05 - Set the user connect flag for VPN services. This is needed so that if there is an authentication error, the agent API will be called and the user will know about the auth failure. 06 - Fix the function name as it is now static 07 - Fix the debug print location, currently it is not very useful 08 - Fix service state combining. The patch fixes the case when IPv4 is ONLINE/READY and IPv6 is DISCONNECTED. In this case we should be ONLINE/READY instead of DISCONNECT. 09 - If the ipconfig method is OFF, then we set the corresponding service state to IDLE. This is done so that only the active ipconfig affects the service state combining. 10 - Add reference counting debugging for provider 11 - If the user tries to connect to existing VPN service, then return the already existing service. It does not make sense to disconnect the older service and then reconnect. 12 - Service was not properly ref counted in connection.c This problem was clearly seen when using VPN service and valgrind. 13 - NULL check. The problem can be triggered by setting IPv6 method of eth0 to OFF, then un-plugging ethernet cable and at the same time setting IPv6 method to AUTO 14 - NULL check. Same issue as in #13 BTW, there is an easy way to test the service state machine: 1. setup radvd in the network so that connman will receive router advertisements 2. run following commands $ set-ipv6-method service auto $ set-ipv4-method service dhcp $ get-state should return online $ set-ipv6-method service off $ get-state should return online $ set-ipv4-method service off $ get-state should return offline $ set-ipv6-method service auto $ get-state should return online $ set-ipv4-method service dhcp $ get-state should return online I noticed that when IPv4 method is set from OFF to DHCP, the device (in this case it was netbook with meego 1.2+) will not fetch ip address automagically when connected via ethernet. One needs to reconnect ethernet cable to start the dhcp. I had no time to investigate this. Regards, Jukka Jukka Rissanen (14): provider: NULL pointer check. vpn: Set authentication failure error code properly in provider. service: Add function to get the ipconfig state. network: Change the service disconnect state when necessary. service: Set the user connect status correctly for VPN. service: Fix function name as it is static. service: Change the debug print location to be more useful. service: Fix state combining. service: Set the service state to IDLE if method is off or unknown. provider: Add ref counting debug. provider: Return existing service path if already connected. connection: Service was not ref counted properly. network: Add NULL check. service: Add NULL check. plugins/vpn.c|5 ++ plugins/vpn.h|1 + src/connection.c |6 ++- src/connman.h|3 + src/network.c| 21 +- src/provider.c | 16 +--- src/service.c| 120 ++ 7 files changed, 109 insertions(+), 63 deletions(-) ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH pre-l2tp/pptp v2 01/14] provider: NULL pointer check.
--- src/provider.c |3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/src/provider.c b/src/provider.c index 9ae62cd..633ca40 100644 --- a/src/provider.c +++ b/src/provider.c @@ -879,6 +879,9 @@ int connman_provider_append_route(struct connman_provider *provider, const char *connman_provider_get_driver_name(struct connman_provider *provider) { + if (provider-driver == NULL) + return NULL; + return provider-driver-name; } -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH pre-l2tp/pptp v2 02/14] vpn: Set authentication failure error code properly in provider.
This patch is needed so that we can catch the authentication error from vpn driver and inform the failure to user. --- plugins/vpn.c |5 + plugins/vpn.h |1 + 2 files changed, 6 insertions(+), 0 deletions(-) diff --git a/plugins/vpn.c b/plugins/vpn.c index e028b63..efeb959 100644 --- a/plugins/vpn.c +++ b/plugins/vpn.c @@ -193,6 +193,11 @@ static void vpn_notify(struct connman_task *task, connman_provider_set_state(provider, CONNMAN_PROVIDER_STATE_DISCONNECT); break; + + case VPN_STATE_AUTH_FAILURE: + connman_provider_indicate_error(provider, + CONNMAN_PROVIDER_ERROR_AUTH_FAILED); + break; } } diff --git a/plugins/vpn.h b/plugins/vpn.h index a45c718..6392aca 100644 --- a/plugins/vpn.h +++ b/plugins/vpn.h @@ -26,6 +26,7 @@ enum vpn_state { VPN_STATE_READY = 3, VPN_STATE_DISCONNECT= 4, VPN_STATE_FAILURE = 5, + VPN_STATE_AUTH_FAILURE = 6, }; struct vpn_driver { -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH pre-l2tp/pptp v2 04/14] network: Change the service disconnect state when necessary.
If we are in idle or failure states, then we should not change to disconnect state when the service is disconnected. This is because we were not connected in the first place. --- src/network.c | 18 -- 1 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/network.c b/src/network.c index 41f9188..ae82dc5 100644 --- a/src/network.c +++ b/src/network.c @@ -1057,6 +1057,7 @@ static gboolean set_connected(gpointer user_data) } else { struct connman_service *service; + enum connman_service_state state; __connman_device_set_network(network-device, NULL); network-hidden = FALSE; @@ -1075,11 +1076,24 @@ static gboolean set_connected(gpointer user_data) break; } - __connman_service_ipconfig_indicate_state(service, + /* +* We only set the disconnect state if we were not in idle +* or in failure. It does not make sense to go to disconnect +* state if we were not connected. +*/ + state = __connman_service_ipconfig_get_state(service, + CONNMAN_IPCONFIG_TYPE_IPV4); + if (state != CONNMAN_SERVICE_STATE_IDLE + state != CONNMAN_SERVICE_STATE_FAILURE) + __connman_service_ipconfig_indicate_state(service, CONNMAN_SERVICE_STATE_DISCONNECT, CONNMAN_IPCONFIG_TYPE_IPV4); - __connman_service_ipconfig_indicate_state(service, + state = __connman_service_ipconfig_get_state(service, + CONNMAN_IPCONFIG_TYPE_IPV6); + if (state != CONNMAN_SERVICE_STATE_IDLE + state != CONNMAN_SERVICE_STATE_FAILURE) + __connman_service_ipconfig_indicate_state(service, CONNMAN_SERVICE_STATE_DISCONNECT, CONNMAN_IPCONFIG_TYPE_IPV6); -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH pre-l2tp/pptp v2 03/14] service: Add function to get the ipconfig state.
--- src/connman.h |3 +++ src/service.c | 13 + 2 files changed, 16 insertions(+), 0 deletions(-) diff --git a/src/connman.h b/src/connman.h index 681b29f..ff3ea97 100644 --- a/src/connman.h +++ b/src/connman.h @@ -499,6 +499,9 @@ void __connman_service_set_string(struct connman_service *service, int __connman_service_ipconfig_indicate_state(struct connman_service *service, enum connman_service_state new_state, enum connman_ipconfig_type type); +enum connman_service_state __connman_service_ipconfig_get_state( + struct connman_service *service, + enum connman_ipconfig_type type); int __connman_service_indicate_error(struct connman_service *service, enum connman_service_error error); diff --git a/src/service.c b/src/service.c index e1ebec3..091233a 100644 --- a/src/service.c +++ b/src/service.c @@ -3633,6 +3633,19 @@ int __connman_service_indicate_default(struct connman_service *service) return 0; } +enum connman_service_state __connman_service_ipconfig_get_state( + struct connman_service *service, + enum connman_ipconfig_type type) +{ + if (type == CONNMAN_IPCONFIG_TYPE_IPV4) + return service-state_ipv4; + + if (type == CONNMAN_IPCONFIG_TYPE_IPV6) + return service-state_ipv6; + + return CONNMAN_SERVICE_STATE_UNKNOWN; +} + static void check_proxy_setup(struct connman_service *service) { /* -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH pre-l2tp/pptp v2 05/14] service: Set the user connect status correctly for VPN.
If the userconnect is not set, then informatation about authentication errors cannot be reported by agent API. --- src/service.c |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/src/service.c b/src/service.c index 091233a..257fe3c 100644 --- a/src/service.c +++ b/src/service.c @@ -5017,6 +5017,7 @@ __connman_service_create_from_provider(struct connman_provider *provider) service-type = CONNMAN_SERVICE_TYPE_VPN; service-provider = connman_provider_ref(provider); service-autoconnect = FALSE; + service-userconnect = TRUE; service-state_ipv4 = service-state_ipv6 = CONNMAN_SERVICE_STATE_IDLE; -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH pre-l2tp/pptp v2 06/14] service: Fix function name as it is static.
--- src/service.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/service.c b/src/service.c index 257fe3c..d8fe898 100644 --- a/src/service.c +++ b/src/service.c @@ -3426,7 +3426,7 @@ static void report_error_cb(struct connman_service *service, } } -static int __connman_service_indicate_state(struct connman_service *service) +static int service_indicate_state(struct connman_service *service) { enum connman_service_state old_state, new_state; GSequenceIter *iter; @@ -3731,7 +3731,7 @@ int __connman_service_ipconfig_indicate_state(struct connman_service *service, else if (type == CONNMAN_IPCONFIG_TYPE_IPV6) service-state_ipv6 = new_state; - return __connman_service_indicate_state(service); + return service_indicate_state(service); } int __connman_service_request_login(struct connman_service *service) -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH pre-l2tp/pptp v2 07/14] service: Change the debug print location to be more useful.
--- src/service.c |6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/service.c b/src/service.c index d8fe898..fcbfc87 100644 --- a/src/service.c +++ b/src/service.c @@ -3437,9 +3437,6 @@ static int service_indicate_state(struct connman_service *service) old_state = service-state; new_state = combine_state(service-state_ipv4, service-state_ipv6); - if (old_state == new_state) - return -EALREADY; - DBG(service %p old %s - new %s/%s = %s, service, state2string(old_state), @@ -3447,6 +3444,9 @@ static int service_indicate_state(struct connman_service *service) state2string(service-state_ipv6), state2string(new_state)); + if (old_state == new_state) + return -EALREADY; + service-state = new_state; state_changed(service); -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH pre-l2tp/pptp v2 08/14] service: Fix state combining.
If we have IPv6 state as DISCONNECT and IPv4 state as ONLINE or READY then we are not disconnected. --- src/service.c | 64 ++-- 1 files changed, 16 insertions(+), 48 deletions(-) diff --git a/src/service.c b/src/service.c index fcbfc87..9319323 100644 --- a/src/service.c +++ b/src/service.c @@ -327,75 +327,43 @@ static enum connman_service_state combine_state( goto done; } - if (state_a == CONNMAN_SERVICE_STATE_ASSOCIATION) { - if (state_b == CONNMAN_SERVICE_STATE_CONFIGURATION || - state_b == CONNMAN_SERVICE_STATE_ONLINE || - state_b == CONNMAN_SERVICE_STATE_READY) - result = state_b; - else - result = state_a; + if (state_a == CONNMAN_SERVICE_STATE_ONLINE) { + result = state_a; goto done; } - if (state_b == CONNMAN_SERVICE_STATE_ASSOCIATION) { - if (state_a == CONNMAN_SERVICE_STATE_CONFIGURATION || - state_a == CONNMAN_SERVICE_STATE_ONLINE || - state_a == CONNMAN_SERVICE_STATE_READY) - result = state_a; - else - result = state_b; + if (state_b == CONNMAN_SERVICE_STATE_ONLINE) { + result = state_b; goto done; } - if (state_a == CONNMAN_SERVICE_STATE_CONFIGURATION) { - if (state_b == CONNMAN_SERVICE_STATE_ONLINE || - state_b == CONNMAN_SERVICE_STATE_READY) - result = state_b; - else - result = state_a; + if (state_a == CONNMAN_SERVICE_STATE_READY) { + result = state_a; goto done; } - if (state_b == CONNMAN_SERVICE_STATE_CONFIGURATION) { - if (state_a == CONNMAN_SERVICE_STATE_ONLINE || - state_a == CONNMAN_SERVICE_STATE_READY) - result = state_a; - else - result = state_b; + if (state_b == CONNMAN_SERVICE_STATE_READY) { + result = state_b; goto done; } - if (state_a == CONNMAN_SERVICE_STATE_READY) { - if (state_b == CONNMAN_SERVICE_STATE_ONLINE || - state_b == CONNMAN_SERVICE_STATE_DISCONNECT) - result = state_b; - else - result = state_a; + if (state_a == CONNMAN_SERVICE_STATE_CONFIGURATION) { + result = state_a; goto done; } - if (state_b == CONNMAN_SERVICE_STATE_READY) { - if (state_a == CONNMAN_SERVICE_STATE_ONLINE || - state_a == CONNMAN_SERVICE_STATE_DISCONNECT) - result = state_a; - else - result = state_b; + if (state_b == CONNMAN_SERVICE_STATE_CONFIGURATION) { + result = state_b; goto done; } - if (state_a == CONNMAN_SERVICE_STATE_ONLINE) { - if (state_b == CONNMAN_SERVICE_STATE_DISCONNECT) - result = state_b; - else - result = state_a; + if (state_a == CONNMAN_SERVICE_STATE_ASSOCIATION) { + result = state_a; goto done; } - if (state_b == CONNMAN_SERVICE_STATE_ONLINE) { - if (state_a == CONNMAN_SERVICE_STATE_DISCONNECT) - result = state_a; - else - result = state_b; + if (state_b == CONNMAN_SERVICE_STATE_ASSOCIATION) { + result = state_b; goto done; } -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH pre-l2tp/pptp v2 10/14] provider: Add ref counting debug.
--- src/provider.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/provider.c b/src/provider.c index 633ca40..bbd462e 100644 --- a/src/provider.c +++ b/src/provider.c @@ -143,7 +143,7 @@ static void provider_unregister(struct connman_provider *provider) struct connman_provider *connman_provider_ref(struct connman_provider *provider) { - DBG(provider %p, provider); + DBG(provider %p refcount %d, provider, provider-refcount + 1); g_atomic_int_inc(provider-refcount); @@ -165,7 +165,7 @@ static void provider_destruct(struct connman_provider *provider) void connman_provider_unref(struct connman_provider *provider) { - DBG(provider %p, provider); + DBG(provider %p refcount %d, provider, provider-refcount - 1); if (g_atomic_int_dec_and_test(provider-refcount) == FALSE) return; -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH pre-l2tp/pptp v2 09/14] service: Set the service state to IDLE if method is off or unknown.
--- src/service.c | 28 +++- 1 files changed, 27 insertions(+), 1 deletions(-) diff --git a/src/service.c b/src/service.c index 9319323..34dbc79 100644 --- a/src/service.c +++ b/src/service.c @@ -3642,6 +3642,7 @@ int __connman_service_ipconfig_indicate_state(struct connman_service *service, { struct connman_ipconfig *ipconfig = NULL; enum connman_service_state old_state; + int ret; if (service == NULL) return -EINVAL; @@ -3699,7 +3700,32 @@ int __connman_service_ipconfig_indicate_state(struct connman_service *service, else if (type == CONNMAN_IPCONFIG_TYPE_IPV6) service-state_ipv6 = new_state; - return service_indicate_state(service); + ret = service_indicate_state(service); + + /* +* If the ipconfig method is OFF, then we set the state to IDLE +* so that it will not affect the combined state in the future. +*/ + if (type == CONNMAN_IPCONFIG_TYPE_IPV4) { + enum connman_ipconfig_method method; + method = __connman_ipconfig_get_method(service-ipconfig_ipv4); + if (method == CONNMAN_IPCONFIG_METHOD_OFF || + method == CONNMAN_IPCONFIG_METHOD_UNKNOWN) { + service-state_ipv4 = CONNMAN_SERVICE_STATE_IDLE; + ret = service_indicate_state(service); + } + + } else if (type == CONNMAN_IPCONFIG_TYPE_IPV6) { + enum connman_ipconfig_method method; + method = __connman_ipconfig_get_method(service-ipconfig_ipv6); + if (method == CONNMAN_IPCONFIG_METHOD_OFF || + method == CONNMAN_IPCONFIG_METHOD_UNKNOWN) { + service-state_ipv6 = CONNMAN_SERVICE_STATE_IDLE; + ret = service_indicate_state(service); + } + } + + return ret; } int __connman_service_request_login(struct connman_service *service) -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH pre-l2tp/pptp v2 12/14] connection: Service was not ref counted properly.
The reference counting problems were clearly seen with VPN service. --- src/connection.c |6 -- 1 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/connection.c b/src/connection.c index 4f3b3f8..38269d6 100644 --- a/src/connection.c +++ b/src/connection.c @@ -227,6 +227,7 @@ static struct gateway_data *add_gateway(struct connman_service *service, } } + connman_service_ref(service); g_hash_table_replace(gateway_hash, service, data); return data; @@ -614,9 +615,10 @@ void __connman_connection_gateway_remove(struct connman_service *service, do_ipv4 == TRUE) || (data-ipv6_gateway != NULL data-ipv4_gateway == NULL do_ipv6 == TRUE) - ) + ) { + connman_service_unref(service); g_hash_table_remove(gateway_hash, service); - else + } else DBG(Not yet removing gw ipv4 %p/%d ipv6 %p/%d, data-ipv4_gateway, do_ipv4, data-ipv6_gateway, do_ipv6); -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH pre-l2tp/pptp v2 11/14] provider: Return existing service path if already connected.
--- src/provider.c |9 + 1 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/provider.c b/src/provider.c index bbd462e..8f1862e 100644 --- a/src/provider.c +++ b/src/provider.c @@ -571,11 +571,12 @@ int __connman_provider_create_and_connect(DBusMessage *msg) err = -EOPNOTSUPP; goto unref; } - } - err = __connman_service_connect(provider-vpn_service); - if (err 0 err != -EINPROGRESS) - goto failed; + err = __connman_service_connect(provider-vpn_service); + if (err 0 err != -EINPROGRESS) + goto failed; + } else + DBG(provider already connected); service_path = __connman_service_get_path(provider-vpn_service); g_dbus_send_reply(connection, msg, -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH pre-l2tp/pptp v2 13/14] network: Add NULL check.
--- src/network.c |3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/src/network.c b/src/network.c index ae82dc5..4a1e33c 100644 --- a/src/network.c +++ b/src/network.c @@ -1333,6 +1333,9 @@ int __connman_network_set_ipconfig(struct connman_network *network, enum connman_ipconfig_method method; int ret; + if (network == NULL) + return -EINVAL; + if (ipconfig_ipv6) { method = __connman_ipconfig_get_method(ipconfig_ipv6); -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH pre-l2tp/pptp v2 14/14] service: Add NULL check.
--- src/service.c |6 ++ 1 files changed, 6 insertions(+), 0 deletions(-) diff --git a/src/service.c b/src/service.c index 34dbc79..dd75eba 100644 --- a/src/service.c +++ b/src/service.c @@ -4609,6 +4609,9 @@ struct connman_service *__connman_service_lookup_from_network(struct connman_net DBG(network %p, network); + if (network == NULL) + return NULL; + ident = __connman_network_get_ident(network); if (ident == NULL) return NULL; @@ -4802,6 +4805,9 @@ struct connman_service * __connman_service_create_from_network(struct connman_ne DBG(network %p, network); + if (network == NULL) + return NULL; + ident = __connman_network_get_ident(network); if (ident == NULL) return NULL; -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH] dnsproxy: Fix possible alignment issue when handling DNS packet.
--- Hi, this patch fixes possible memory alignment issue when dealing with DNS packet. I will send the fixed DNS cache patch after this has been commited. Regards, Jukka src/dnsproxy.c | 85 +++ 1 files changed, 48 insertions(+), 37 deletions(-) diff --git a/src/dnsproxy.c b/src/dnsproxy.c index d9e291c..af3d8b4 100644 --- a/src/dnsproxy.c +++ b/src/dnsproxy.c @@ -192,7 +192,7 @@ static void send_response(int sk, unsigned char *buf, int len, const struct sockaddr *to, socklen_t tolen, int protocol) { - struct domain_hdr *hdr; + unsigned char *hdr; int err, offset = protocol_offset(protocol); DBG(); @@ -205,14 +205,15 @@ static void send_response(int sk, unsigned char *buf, int len, hdr = (void *) (buf + offset); - DBG(id 0x%04x qr %d opcode %d, hdr-id, hdr-qr, hdr-opcode); + DBG(id 0x%04x qr %d opcode %d, hdr[0] 8 | hdr[1], + (hdr[2] 0x80) 8, (hdr[2] 0x78) 3); - hdr-qr = 1; - hdr-rcode = 2; + hdr[2] |= 0x80; /* qr */ + hdr[3] = (hdr[3] 0xf0) | 0x02; /* rcode */ - hdr-ancount = 0; - hdr-nscount = 0; - hdr-arcount = 0; + hdr[6] = hdr[7] = 0; /* ancount */ + hdr[8] = hdr[9] = 0; /* nscount */ + hdr[10] = hdr[11] = 0; /* arcount */ err = sendto(sk, buf, len, 0, to, tolen); if (err 0) { @@ -247,11 +248,12 @@ static gboolean request_timeout(gpointer user_data) if (err 0) return FALSE; } else if (req-request req-numserv == 0) { - struct domain_hdr *hdr; + unsigned char *hdr; if (req-protocol == IPPROTO_TCP) { hdr = (void *) (req-request + 2); - hdr-id = req-srcid; + hdr[0] = req-srcid 8; + hdr[1] = req-srcid; send_response(req-client_sk, req-request, req-request_len, NULL, 0, IPPROTO_TCP); @@ -259,7 +261,8 @@ static gboolean request_timeout(gpointer user_data) int sk; hdr = (void *) (req-request); - hdr-id = req-srcid; + hdr[0] = req-srcid 8; + hdr[1] = req-srcid; sk = g_io_channel_unix_get_fd( ifdata-udp_listener_channel); send_response(sk, req-request, req-request_len, @@ -349,7 +352,7 @@ static int ns_resolv(struct server_data *server, struct request_data *req, for (list = server-domains; list; list = list-next) { char *domain; unsigned char alt[1024]; - struct domain_hdr *hdr = (void *) alt; + unsigned char *hdr = (void *) alt; int altlen, domlen, offset; domain = list-data; @@ -365,11 +368,11 @@ static int ns_resolv(struct server_data *server, struct request_data *req, if (domlen 5) return -EINVAL; - alt[offset] = req-altid 0xff; - alt[offset + 1] = req-altid 8; + alt[offset] = req-altid 8; + alt[offset + 1] = req-altid; memcpy(alt + offset + 2, request + offset + 2, 10); - hdr-qdcount = htons(1); + hdr[5] = 1; /* qdcount */ altlen = append_query(alt + offset + 12, sizeof(alt) - 12, name, domain); @@ -401,16 +404,17 @@ static int ns_resolv(struct server_data *server, struct request_data *req, static int forward_dns_reply(unsigned char *reply, int reply_len, int protocol) { - struct domain_hdr *hdr; + unsigned char *hdr; struct request_data *req; int dns_id, sk, err, offset = protocol_offset(protocol); struct listener_data *ifdata; + int rcode; if (offset 0) return offset; hdr = (void *)(reply + offset); - dns_id = reply[offset] | reply[offset + 1] 8; + dns_id = reply[offset] 8 | reply[offset + 1]; DBG(Received %d bytes (id 0x%04x), reply_len, dns_id); @@ -418,16 +422,18 @@ static int forward_dns_reply(unsigned char *reply, int reply_len, int protocol) if (req == NULL) return -EINVAL; - DBG(id 0x%04x rcode %d, hdr-id, hdr-rcode); + rcode = hdr[3] 0x0f; + + DBG(id 0x%04x rcode %d, hdr[0] 8 | hdr[1], rcode); ifdata = req-ifdata; - reply[offset] = req-srcid 0xff; - reply[offset + 1] = req-srcid 8; + reply[offset] = req-srcid 8; + reply[offset + 1] = req-srcid; req-numresp++; - if (hdr-rcode == 0 || req-resp == NULL) { + if (rcode == 0 || req-resp == NULL) {
[PATCH v2] dnsproxy: Fix possible alignment issue when handling DNS packet.
--- Hi, this patch fixes possible memory alignment issue when dealing with DNS packet. This version uses alignment macros from Bluez. Jukka include/types.h | 17 +++ src/dnsproxy.c | 134 +-- 2 files changed, 98 insertions(+), 53 deletions(-) diff --git a/include/types.h b/include/types.h index 70aff9e..82f534a 100644 --- a/include/types.h +++ b/include/types.h @@ -38,6 +38,23 @@ typedef int connman_bool_t; typedef unsigned char connman_uint8_t; typedef unsigned short connman_uint16_t; +/* unaligned access (code taken from Bluez lib/bluetooth.h) */ +#define cm_get_unaligned(ptr) \ +({ \ + struct __attribute__((packed)) {\ + typeof(*(ptr)) __v; \ + } *__p = (void *) (ptr);\ + __p-__v; \ +}) + +#define cm_put_unaligned(val, ptr) \ +do { \ + struct __attribute__((packed)) {\ + typeof(*(ptr)) __v; \ + } *__p = (void *) (ptr);\ + __p-__v = (val); \ +} while(0) + #ifdef __cplusplus } #endif diff --git a/src/dnsproxy.c b/src/dnsproxy.c index d9e291c..5fd6093 100644 --- a/src/dnsproxy.c +++ b/src/dnsproxy.c @@ -37,23 +37,6 @@ #include connman.h -#if __BYTE_ORDER == __LITTLE_ENDIAN -struct domain_hdr { - uint16_t id; - uint8_t rd:1; - uint8_t tc:1; - uint8_t aa:1; - uint8_t opcode:4; - uint8_t qr:1; - uint8_t rcode:4; - uint8_t z:3; - uint8_t ra:1; - uint16_t qdcount; - uint16_t ancount; - uint16_t nscount; - uint16_t arcount; -} __attribute__ ((packed)); -#elif __BYTE_ORDER == __BIG_ENDIAN struct domain_hdr { uint16_t id; uint8_t qr:1; @@ -69,9 +52,6 @@ struct domain_hdr { uint16_t nscount; uint16_t arcount; } __attribute__ ((packed)); -#else -#error Unknown byte order -#endif struct partial_reply { uint16_t len; @@ -187,12 +167,56 @@ static struct server_data *find_server(const char *interface, return NULL; } +static struct domain_hdr *get_hdr(unsigned char *buf, struct domain_hdr *hdr) +{ + if (hdr == NULL) + return NULL; + + hdr-id = ntohs(cm_get_unaligned((uint16_t *)buf)); + hdr-qr = (buf[2] 0x80) 7; + hdr-opcode = (buf[2] 0x78) 3; + hdr-aa = (buf[2] 0x04) 2; + hdr-tc = (buf[2] 0x02) 1; + hdr-rd = buf[2] 0x01; + hdr-ra = (buf[3] 0x80) 7; + hdr-z = 0; + hdr-rcode = buf[3] 0x0f; + + hdr-qdcount = ntohs(cm_get_unaligned((uint16_t *)buf[4])); + hdr-ancount = ntohs(cm_get_unaligned((uint16_t *)buf[6])); + hdr-nscount = ntohs(cm_get_unaligned((uint16_t *)buf[8])); + hdr-arcount = ntohs(cm_get_unaligned((uint16_t *)buf[10])); + + return hdr; +} + +static void put_hdr(struct domain_hdr *hdr, unsigned char *buf) +{ + if (hdr == NULL) + return; + + cm_put_unaligned(htons(hdr-id), (uint16_t *)buf); + + buf[2] |= hdr-qr 7; + buf[2] |= hdr-opcode 3; + buf[2] |= hdr-aa 2; + buf[2] |= hdr-tc 1; + buf[2] |= hdr-rd 0; + buf[3] |= hdr-ra 7; + buf[3] = ~0x70; + buf[3] |= hdr-rcode; + + cm_put_unaligned(htons(hdr-qdcount), (uint16_t *)buf[4]); + cm_put_unaligned(htons(hdr-ancount), (uint16_t *)buf[6]); + cm_put_unaligned(htons(hdr-nscount), (uint16_t *)buf[8]); + cm_put_unaligned(htons(hdr-arcount), (uint16_t *)buf[10]); +} static void send_response(int sk, unsigned char *buf, int len, const struct sockaddr *to, socklen_t tolen, int protocol) { - struct domain_hdr *hdr; + struct domain_hdr *hdr, header; int err, offset = protocol_offset(protocol); DBG(); @@ -203,7 +227,7 @@ static void send_response(int sk, unsigned char *buf, int len, if (len 12) return; - hdr = (void *) (buf + offset); + hdr = get_hdr(buf + offset, header); DBG(id 0x%04x qr %d opcode %d, hdr-id, hdr-qr, hdr-opcode); @@ -214,6 +238,8 @@ static void send_response(int sk, unsigned char *buf, int len, hdr-nscount = 0; hdr-arcount = 0; + put_hdr(hdr, buf + offset); + err = sendto(sk, buf, len, 0, to, tolen); if (err 0) { connman_error(Failed to send DNS response: %s, @@ -247,19 +273,18 @@ static gboolean request_timeout(gpointer user_data) if (err 0) return FALSE; } else if (req-request req-numserv == 0) { - struct domain_hdr *hdr; if (req-protocol == IPPROTO_TCP) { - hdr = (void *) (req-request + 2); -
[PATCH v3] dnsproxy: Fix possible alignment issue when handling DNS packet.
--- Hi, this 3rd version fixes the alignment macro namespace issue. Jukka include/types.h | 16 src/dnsproxy.c | 114 +++ 2 files changed, 97 insertions(+), 33 deletions(-) diff --git a/include/types.h b/include/types.h index 70aff9e..f722e65 100644 --- a/include/types.h +++ b/include/types.h @@ -38,6 +38,22 @@ typedef int connman_bool_t; typedef unsigned char connman_uint8_t; typedef unsigned short connman_uint16_t; +#define connman_get_unaligned(ptr) \ +({ \ + struct __attribute__((packed)) {\ + typeof(*(ptr)) __v; \ + } *__p = (void *) (ptr);\ + __p-__v; \ +}) + +#define connman_put_unaligned(val, ptr)\ +do { \ + struct __attribute__((packed)) {\ + typeof(*(ptr)) __v; \ + } *__p = (void *) (ptr);\ + __p-__v = (val); \ +} while(0) + #ifdef __cplusplus } #endif diff --git a/src/dnsproxy.c b/src/dnsproxy.c index d9e291c..dd67aff 100644 --- a/src/dnsproxy.c +++ b/src/dnsproxy.c @@ -187,12 +187,56 @@ static struct server_data *find_server(const char *interface, return NULL; } +static struct domain_hdr *get_hdr(unsigned char *buf, struct domain_hdr *hdr) +{ + if (hdr == NULL) + return NULL; + + hdr-id = ntohs(connman_get_unaligned((uint16_t *)buf)); + hdr-qr = (buf[2] 0x80) 7; + hdr-opcode = (buf[2] 0x78) 3; + hdr-aa = (buf[2] 0x04) 2; + hdr-tc = (buf[2] 0x02) 1; + hdr-rd = buf[2] 0x01; + hdr-ra = (buf[3] 0x80) 7; + hdr-z = 0; + hdr-rcode = buf[3] 0x0f; + + hdr-qdcount = ntohs(connman_get_unaligned((uint16_t *)buf[4])); + hdr-ancount = ntohs(connman_get_unaligned((uint16_t *)buf[6])); + hdr-nscount = ntohs(connman_get_unaligned((uint16_t *)buf[8])); + hdr-arcount = ntohs(connman_get_unaligned((uint16_t *)buf[10])); + + return hdr; +} + +static void put_hdr(struct domain_hdr *hdr, unsigned char *buf) +{ + if (hdr == NULL) + return; + + connman_put_unaligned(htons(hdr-id), (uint16_t *)buf); + + buf[2] |= hdr-qr 7; + buf[2] |= hdr-opcode 3; + buf[2] |= hdr-aa 2; + buf[2] |= hdr-tc 1; + buf[2] |= hdr-rd 0; + buf[3] |= hdr-ra 7; + buf[3] = ~0x70; + buf[3] |= hdr-rcode; + + connman_put_unaligned(htons(hdr-qdcount), (uint16_t *)buf[4]); + connman_put_unaligned(htons(hdr-ancount), (uint16_t *)buf[6]); + connman_put_unaligned(htons(hdr-nscount), (uint16_t *)buf[8]); + connman_put_unaligned(htons(hdr-arcount), (uint16_t *)buf[10]); +} static void send_response(int sk, unsigned char *buf, int len, const struct sockaddr *to, socklen_t tolen, int protocol) { - struct domain_hdr *hdr; + struct domain_hdr *hdr, header; int err, offset = protocol_offset(protocol); DBG(); @@ -203,7 +247,7 @@ static void send_response(int sk, unsigned char *buf, int len, if (len 12) return; - hdr = (void *) (buf + offset); + hdr = get_hdr(buf + offset, header); DBG(id 0x%04x qr %d opcode %d, hdr-id, hdr-qr, hdr-opcode); @@ -214,6 +258,8 @@ static void send_response(int sk, unsigned char *buf, int len, hdr-nscount = 0; hdr-arcount = 0; + put_hdr(hdr, buf + offset); + err = sendto(sk, buf, len, 0, to, tolen); if (err 0) { connman_error(Failed to send DNS response: %s, @@ -247,19 +293,18 @@ static gboolean request_timeout(gpointer user_data) if (err 0) return FALSE; } else if (req-request req-numserv == 0) { - struct domain_hdr *hdr; if (req-protocol == IPPROTO_TCP) { - hdr = (void *) (req-request + 2); - hdr-id = req-srcid; + connman_put_unaligned(htons(req-srcid), + (uint16_t *)(req-request + 2)); send_response(req-client_sk, req-request, req-request_len, NULL, 0, IPPROTO_TCP); } else if (req-protocol == IPPROTO_UDP) { int sk; - hdr = (void *) (req-request); - hdr-id = req-srcid; + connman_put_unaligned(htons(req-srcid), + (uint16_t *)req-request); sk = g_io_channel_unix_get_fd( ifdata-udp_listener_channel); send_response(sk, req-request,
[PATCH 1/2] connection: Fix indentation.
--- src/connection.c |8 1 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/connection.c b/src/connection.c index 9ceefd3..3cd89eb 100644 --- a/src/connection.c +++ b/src/connection.c @@ -269,8 +269,8 @@ static void set_default_gateway(struct gateway_data *data, connman_inet_set_gateway_address(data-index, data-ipv4_gateway-vpn_ip); connman_inet_add_host_route(data-ipv4_gateway-vpn_phy_index, - data-ipv4_gateway-vpn_ip, - data-ipv4_gateway-vpn_phy_ip); + data-ipv4_gateway-vpn_ip, + data-ipv4_gateway-vpn_phy_ip); data-ipv4_gateway-active = TRUE; __connman_service_indicate_default(data-service); @@ -283,8 +283,8 @@ static void set_default_gateway(struct gateway_data *data, connman_inet_set_ipv6_gateway_address(data-index, data-ipv6_gateway-vpn_ip); connman_inet_add_host_route(data-ipv6_gateway-vpn_phy_index, - data-ipv6_gateway-vpn_ip, - data-ipv6_gateway-vpn_phy_ip); + data-ipv6_gateway-vpn_ip, + data-ipv6_gateway-vpn_phy_ip); data-ipv6_gateway-active = TRUE; __connman_service_indicate_default(data-service); -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH 2/2] connection: Fix IPv6 host route setting when using VPN.
--- src/connection.c |3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/src/connection.c b/src/connection.c index 3cd89eb..5ea3c9b 100644 --- a/src/connection.c +++ b/src/connection.c @@ -282,7 +282,8 @@ static void set_default_gateway(struct gateway_data *data, data-ipv6_gateway-vpn == TRUE) { connman_inet_set_ipv6_gateway_address(data-index, data-ipv6_gateway-vpn_ip); - connman_inet_add_host_route(data-ipv6_gateway-vpn_phy_index, + connman_inet_add_ipv6_host_route( + data-ipv6_gateway-vpn_phy_index, data-ipv6_gateway-vpn_ip, data-ipv6_gateway-vpn_phy_ip); data-ipv6_gateway-active = TRUE; -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH service move 1/6] service: Ignore ipconfig that is not active when moving service.
--- src/service.c | 49 + 1 files changed, 45 insertions(+), 4 deletions(-) diff --git a/src/service.c b/src/service.c index 7cd21b5..4cb90fb 100644 --- a/src/service.c +++ b/src/service.c @@ -2920,6 +2920,8 @@ static DBusMessage *move_service(DBusConnection *conn, struct connman_service *target; const char *path; GSequenceIter *src, *dst; + enum connman_ipconfig_method target4, target6; + enum connman_ipconfig_method service4, service6; DBG(service %p, service); @@ -2933,11 +2935,50 @@ static DBusMessage *move_service(DBusConnection *conn, if (target == NULL || target-favorite == FALSE || target == service) return __connman_error_invalid_service(msg); - DBG(target %s, target-identifier); + target4 = __connman_ipconfig_get_method(target-ipconfig_ipv4); + target6 = __connman_ipconfig_get_method(target-ipconfig_ipv6); + service4 = __connman_ipconfig_get_method(service-ipconfig_ipv4); + service6 = __connman_ipconfig_get_method(service-ipconfig_ipv6); - if (target-state_ipv4 != service-state_ipv4 - target-state_ipv6 != service-state_ipv6) - return __connman_error_invalid_service(msg); + DBG(target %s method %d/%d state %d/%d, target-identifier, + target4, target6, + target-state_ipv4, target-state_ipv6); + + DBG(service %s method %d/%d state %d/%d, service-identifier, + service4, service6, + service-state_ipv4, service-state_ipv6); + + /* +* If method is OFF, then we do not need to check the corresponding +* ipconfig state. +*/ + if (target4 == CONNMAN_IPCONFIG_METHOD_OFF) { + if (service6 != CONNMAN_IPCONFIG_METHOD_OFF) { + if (target-state_ipv6 != service-state_ipv6) + return __connman_error_invalid_service(msg); + } + } + + if (target6 == CONNMAN_IPCONFIG_METHOD_OFF) { + if (service4 != CONNMAN_IPCONFIG_METHOD_OFF) { + if (target-state_ipv4 != service-state_ipv4) + return __connman_error_invalid_service(msg); + } + } + + if (service4 == CONNMAN_IPCONFIG_METHOD_OFF) { + if (target6 != CONNMAN_IPCONFIG_METHOD_OFF) { + if (target-state_ipv6 != service-state_ipv6) + return __connman_error_invalid_service(msg); + } + } + + if (service6 == CONNMAN_IPCONFIG_METHOD_OFF) { + if (target4 != CONNMAN_IPCONFIG_METHOD_OFF) { + if (target-state_ipv4 != service-state_ipv4) + return __connman_error_invalid_service(msg); + } + } g_get_current_time(service-modified); __connman_storage_save_service(service); -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH service move 2/6] service: Allow ready service to be moved before online one.
--- src/service.c | 28 1 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/service.c b/src/service.c index 4cb90fb..5f7242d 100644 --- a/src/service.c +++ b/src/service.c @@ -2912,6 +2912,22 @@ static DBusMessage *remove_service(DBusConnection *conn, return g_dbus_create_reply(msg, DBUS_TYPE_INVALID); } +static gboolean check_suitable_state(enum connman_service_state a, + enum connman_service_state b) +{ + /* +* Special check so that ready service can be moved before +* online one. +*/ + if ((a == CONNMAN_SERVICE_STATE_ONLINE + b == CONNMAN_SERVICE_STATE_READY) || + (b == CONNMAN_SERVICE_STATE_ONLINE + a == CONNMAN_SERVICE_STATE_READY)) + return TRUE; + + return a == b; +} + static DBusMessage *move_service(DBusConnection *conn, DBusMessage *msg, void *user_data, gboolean before) @@ -2954,28 +2970,32 @@ static DBusMessage *move_service(DBusConnection *conn, */ if (target4 == CONNMAN_IPCONFIG_METHOD_OFF) { if (service6 != CONNMAN_IPCONFIG_METHOD_OFF) { - if (target-state_ipv6 != service-state_ipv6) + if (check_suitable_state(target-state_ipv6, + service-state_ipv6) == FALSE) return __connman_error_invalid_service(msg); } } if (target6 == CONNMAN_IPCONFIG_METHOD_OFF) { if (service4 != CONNMAN_IPCONFIG_METHOD_OFF) { - if (target-state_ipv4 != service-state_ipv4) + if (check_suitable_state(target-state_ipv4, + service-state_ipv4) == FALSE) return __connman_error_invalid_service(msg); } } if (service4 == CONNMAN_IPCONFIG_METHOD_OFF) { if (target6 != CONNMAN_IPCONFIG_METHOD_OFF) { - if (target-state_ipv6 != service-state_ipv6) + if (check_suitable_state(target-state_ipv6, + service-state_ipv6) == FALSE) return __connman_error_invalid_service(msg); } } if (service6 == CONNMAN_IPCONFIG_METHOD_OFF) { if (target4 != CONNMAN_IPCONFIG_METHOD_OFF) { - if (target-state_ipv4 != service-state_ipv4) + if (check_suitable_state(target-state_ipv4, + service-state_ipv4) == FALSE) return __connman_error_invalid_service(msg); } } -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH service move 3/6] service: Allow state downgrade from online to ready.
--- src/connman.h |1 + src/service.c | 19 +++ 2 files changed, 20 insertions(+), 0 deletions(-) diff --git a/src/connman.h b/src/connman.h index 6e68c99..3d9f459 100644 --- a/src/connman.h +++ b/src/connman.h @@ -559,6 +559,7 @@ void __connman_service_notify(struct connman_service *service, int __connman_service_counter_register(const char *counter); void __connman_service_counter_unregister(const char *counter); +void __connman_service_downgrade_state(struct connman_service *service); struct connman_session; struct service_entry; diff --git a/src/service.c b/src/service.c index 5f7242d..e92412e 100644 --- a/src/service.c +++ b/src/service.c @@ -5145,6 +5145,25 @@ __connman_service_create_from_provider(struct connman_provider *provider) return service; } +void __connman_service_downgrade_state(struct connman_service *service) +{ + if (service == NULL) + return; + + DBG(service %p state4 %d state6 %d, service, service-state_ipv4, + service-state_ipv6); + + if (service-state_ipv4 == CONNMAN_SERVICE_STATE_ONLINE) + __connman_service_ipconfig_indicate_state(service, + CONNMAN_SERVICE_STATE_READY, + CONNMAN_IPCONFIG_TYPE_IPV4); + + if (service-state_ipv6 == CONNMAN_SERVICE_STATE_ONLINE) + __connman_service_ipconfig_indicate_state(service, + CONNMAN_SERVICE_STATE_READY, + CONNMAN_IPCONFIG_TYPE_IPV6); +} + static int service_load(struct connman_service *service) { const char *ident = service-profile; -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH service move 4/6] service: Prefer online state over ready when comparing services.
--- src/service.c | 16 ++-- 1 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/service.c b/src/service.c index e92412e..1382705 100644 --- a/src/service.c +++ b/src/service.c @@ -3297,9 +3297,21 @@ static gint service_compare(gconstpointer a, gconstpointer b, state_b = service_b-state; if (state_a != state_b) { - if (is_connected(service_a) == TRUE) + gboolean a_connected = is_connected(service_a), + b_connected = is_connected(service_b); + + if (a_connected == TRUE b_connected == TRUE) { + /* We prefer online over ready state */ + if (state_a == CONNMAN_SERVICE_STATE_ONLINE) + return -1; + + if (state_b == CONNMAN_SERVICE_STATE_ONLINE) + return 1; + } + + if (a_connected == TRUE) return -1; - if (is_connected(service_b) == TRUE) + if (b_connected == TRUE) return 1; if (is_connecting(service_a) == TRUE) -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH service move 6/6] connection: Default gateway is changed when reorganizing services.
Fixes BMC#22540 --- src/connection.c | 93 - 1 files changed, 91 insertions(+), 2 deletions(-) diff --git a/src/connection.c b/src/connection.c index 84e3ab4..ef39ff2 100644 --- a/src/connection.c +++ b/src/connection.c @@ -326,6 +326,70 @@ done: __connman_service_indicate_default(data-service); } +static void unset_default_gateway(struct gateway_data *data, + enum connman_ipconfig_type type) +{ + int index; + int status4 = 0, status6 = 0; + int do_ipv4 = FALSE, do_ipv6 = FALSE; + + if (type == CONNMAN_IPCONFIG_TYPE_IPV4) + do_ipv4 = TRUE; + else if (type == CONNMAN_IPCONFIG_TYPE_IPV6) + do_ipv6 = TRUE; + else + do_ipv4 = do_ipv6 = TRUE; + + DBG(type %d gateway ipv4 %p ipv6 %p, type, data-ipv4_gateway, + data-ipv6_gateway); + + if (do_ipv4 == TRUE data-ipv4_gateway != NULL + data-ipv4_gateway-vpn == TRUE) { + connman_inet_del_host_route(data-index, + data-ipv4_gateway-vpn_ip); + connman_inet_clear_gateway_address(data-index, + data-ipv4_gateway-vpn_ip); + data-ipv4_gateway-active = FALSE; + + return; + } + + if (do_ipv6 == TRUE data-ipv6_gateway != NULL + data-ipv6_gateway-vpn == TRUE) { + connman_inet_del_ipv6_host_route(data-index, + data-ipv6_gateway-vpn_ip); + connman_inet_clear_ipv6_gateway_address(data-index, + data-ipv6_gateway-vpn_ip); + data-ipv6_gateway-active = FALSE; + + return; + } + + index = __connman_service_get_index(data-service); + + if (do_ipv4 == TRUE data-ipv4_gateway != NULL + g_strcmp0(data-ipv4_gateway-gateway, + 0.0.0.0) == 0) { + connman_inet_clear_gateway_interface(index); + return; + } + + if (do_ipv6 == TRUE data-ipv6_gateway != NULL + g_strcmp0(data-ipv6_gateway-gateway, + ::) == 0) { + connman_inet_clear_ipv6_gateway_interface(index); + return; + } + + if (do_ipv6 == TRUE data-ipv6_gateway != NULL) + status6 = connman_inet_clear_ipv6_gateway_address(index, + data-ipv6_gateway-gateway); + + if (do_ipv4 == TRUE data-ipv4_gateway != NULL) + status4 = connman_inet_clear_gateway_address(index, + data-ipv4_gateway-gateway); +} + static struct gateway_data *find_default_gateway(void) { struct gateway_data *found = NULL; @@ -684,14 +748,39 @@ gboolean __connman_connection_update_gateway(void) if (gateway_hash == NULL) return updated; + active_gateway = find_active_gateway(); + update_order(); - active_gateway = find_active_gateway(); default_gateway = find_default_gateway(); - if (active_gateway active_gateway != default_gateway) + if (active_gateway active_gateway != default_gateway) { updated = TRUE; + if (active_gateway) { + if (active_gateway-ipv4_gateway) + unset_default_gateway(active_gateway, + CONNMAN_IPCONFIG_TYPE_IPV4); + + if (active_gateway-ipv6_gateway) + unset_default_gateway(active_gateway, + CONNMAN_IPCONFIG_TYPE_IPV6); + + __connman_service_downgrade_state( + active_gateway-service); + } + + if (default_gateway) { + if (default_gateway-ipv4_gateway) + set_default_gateway(default_gateway, + CONNMAN_IPCONFIG_TYPE_IPV4); + + if (default_gateway-ipv6_gateway) + set_default_gateway(default_gateway, + CONNMAN_IPCONFIG_TYPE_IPV6); + } + } + return updated; } -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH 0/2] device and wifi cleanup
Hi, attached patches do minor cleanup for device.c and wifi.c Regards, Jukka Jukka Rissanen (2): device: Device scan function made private. wifi: Remove not used code. plugins/wifi.c | 14 -- src/connman.h |1 - src/device.c |4 ++-- 3 files changed, 2 insertions(+), 17 deletions(-) ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH 1/2] device: Device scan function made private.
The __connman_device_scan() is now static as it is only called from device.c --- src/connman.h |1 - src/device.c |4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/connman.h b/src/connman.h index 17add6d..9ed9d24 100644 --- a/src/connman.h +++ b/src/connman.h @@ -361,7 +361,6 @@ void __connman_device_set_network(struct connman_device *device, struct connman_network *network); void __connman_device_cleanup_networks(struct connman_device *device); -int __connman_device_scan(struct connman_device *device); int __connman_device_enable(struct connman_device *device); int __connman_device_enable_persistent(struct connman_device *device); int __connman_device_disable(struct connman_device *device); diff --git a/src/device.c b/src/device.c index 3fb4b1e..12fa49a 100644 --- a/src/device.c +++ b/src/device.c @@ -725,7 +725,7 @@ connman_bool_t __connman_device_get_blocked(struct connman_device *device) return device-blocked; } -int __connman_device_scan(struct connman_device *device) +static int device_scan(struct connman_device *device) { if (!device-driver || !device-driver-scan) return -EOPNOTSUPP; @@ -1310,7 +1310,7 @@ int __connman_device_request_scan(enum connman_service_type type) continue; } - err = __connman_device_scan(device); + err = device_scan(device); if (err 0 err != -EINPROGRESS) { DBG(err %d, err); /* XXX maybe only a continue? */ -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH 2/2] wifi: Remove not used code.
--- plugins/wifi.c | 14 -- 1 files changed, 0 insertions(+), 14 deletions(-) diff --git a/plugins/wifi.c b/plugins/wifi.c index 469ec67..f3ea836 100644 --- a/plugins/wifi.c +++ b/plugins/wifi.c @@ -764,26 +764,12 @@ static void interface_removed(GSupplicantInterface *interface) static void scan_started(GSupplicantInterface *interface) { - struct wifi_data *wifi; - DBG(); - - wifi = g_supplicant_interface_get_data(interface); - - if (wifi == NULL) - return; } static void scan_finished(GSupplicantInterface *interface) { - struct wifi_data *wifi; - DBG(); - - wifi = g_supplicant_interface_get_data(interface); - - if (wifi == NULL) - return; } static unsigned char calculate_strength(GSupplicantNetwork *supplicant_network) -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH service move v2 1/6] service: Ignore ipconfig that is not active when moving service.
--- src/service.c | 49 + 1 files changed, 45 insertions(+), 4 deletions(-) diff --git a/src/service.c b/src/service.c index fc90934..b8f1c70 100644 --- a/src/service.c +++ b/src/service.c @@ -2920,6 +2920,8 @@ static DBusMessage *move_service(DBusConnection *conn, struct connman_service *target; const char *path; GSequenceIter *src, *dst; + enum connman_ipconfig_method target4, target6; + enum connman_ipconfig_method service4, service6; DBG(service %p, service); @@ -2933,11 +2935,50 @@ static DBusMessage *move_service(DBusConnection *conn, if (target == NULL || target-favorite == FALSE || target == service) return __connman_error_invalid_service(msg); - DBG(target %s, target-identifier); + target4 = __connman_ipconfig_get_method(target-ipconfig_ipv4); + target6 = __connman_ipconfig_get_method(target-ipconfig_ipv6); + service4 = __connman_ipconfig_get_method(service-ipconfig_ipv4); + service6 = __connman_ipconfig_get_method(service-ipconfig_ipv6); - if (target-state_ipv4 != service-state_ipv4 - target-state_ipv6 != service-state_ipv6) - return __connman_error_invalid_service(msg); + DBG(target %s method %d/%d state %d/%d, target-identifier, + target4, target6, + target-state_ipv4, target-state_ipv6); + + DBG(service %s method %d/%d state %d/%d, service-identifier, + service4, service6, + service-state_ipv4, service-state_ipv6); + + /* +* If method is OFF, then we do not need to check the corresponding +* ipconfig state. +*/ + if (target4 == CONNMAN_IPCONFIG_METHOD_OFF) { + if (service6 != CONNMAN_IPCONFIG_METHOD_OFF) { + if (target-state_ipv6 != service-state_ipv6) + return __connman_error_invalid_service(msg); + } + } + + if (target6 == CONNMAN_IPCONFIG_METHOD_OFF) { + if (service4 != CONNMAN_IPCONFIG_METHOD_OFF) { + if (target-state_ipv4 != service-state_ipv4) + return __connman_error_invalid_service(msg); + } + } + + if (service4 == CONNMAN_IPCONFIG_METHOD_OFF) { + if (target6 != CONNMAN_IPCONFIG_METHOD_OFF) { + if (target-state_ipv6 != service-state_ipv6) + return __connman_error_invalid_service(msg); + } + } + + if (service6 == CONNMAN_IPCONFIG_METHOD_OFF) { + if (target4 != CONNMAN_IPCONFIG_METHOD_OFF) { + if (target-state_ipv4 != service-state_ipv4) + return __connman_error_invalid_service(msg); + } + } g_get_current_time(service-modified); __connman_storage_save_service(service); -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH service move v2 0/6] Fix moving services
Hi, This v2 fixes style issue in service.c (patch #4) and unnecessary pointer check in connection.c (patch #6). This patchset fixes the https://bugs.meego.com/show_bug.cgi?id=22540 and allows connected services to be moved around. When moving connected services, the default route is also properly set. Regards, Jukka Jukka Rissanen (6): service: Ignore ipconfig that is not active when moving service. service: Allow ready service to be moved before online one. service: Allow state downgrade from online to ready. service: Prefer online state over ready when comparing services. test: Script for testing service.MoveBefore interface. connection: Default gateway is changed when reorganizing services. src/connection.c | 90 +++- src/connman.h|1 + src/service.c| 104 +++--- test/service-move-before | 27 4 files changed, 214 insertions(+), 8 deletions(-) create mode 100755 test/service-move-before ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH service move v2 3/6] service: Allow state downgrade from online to ready.
--- src/connman.h |1 + src/service.c | 19 +++ 2 files changed, 20 insertions(+), 0 deletions(-) diff --git a/src/connman.h b/src/connman.h index 17add6d..d74e653 100644 --- a/src/connman.h +++ b/src/connman.h @@ -560,6 +560,7 @@ void __connman_service_notify(struct connman_service *service, int __connman_service_counter_register(const char *counter); void __connman_service_counter_unregister(const char *counter); +void __connman_service_downgrade_state(struct connman_service *service); struct connman_session; struct service_entry; diff --git a/src/service.c b/src/service.c index 2819d51..0380dbe 100644 --- a/src/service.c +++ b/src/service.c @@ -5158,6 +5158,25 @@ __connman_service_create_from_provider(struct connman_provider *provider) return service; } +void __connman_service_downgrade_state(struct connman_service *service) +{ + if (service == NULL) + return; + + DBG(service %p state4 %d state6 %d, service, service-state_ipv4, + service-state_ipv6); + + if (service-state_ipv4 == CONNMAN_SERVICE_STATE_ONLINE) + __connman_service_ipconfig_indicate_state(service, + CONNMAN_SERVICE_STATE_READY, + CONNMAN_IPCONFIG_TYPE_IPV4); + + if (service-state_ipv6 == CONNMAN_SERVICE_STATE_ONLINE) + __connman_service_ipconfig_indicate_state(service, + CONNMAN_SERVICE_STATE_READY, + CONNMAN_IPCONFIG_TYPE_IPV6); +} + static int service_load(struct connman_service *service) { const char *ident = service-profile; -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH service move v2 5/6] test: Script for testing service.MoveBefore interface.
--- test/service-move-before | 27 +++ 1 files changed, 27 insertions(+), 0 deletions(-) create mode 100755 test/service-move-before diff --git a/test/service-move-before b/test/service-move-before new file mode 100755 index 000..f1fddd1 --- /dev/null +++ b/test/service-move-before @@ -0,0 +1,27 @@ +#!/usr/bin/python + +import sys +import dbus + +def print_usage(): + print Usage: %s service target service % (sys.argv[0]) + + +if (len(sys.argv) 2): + print_usage() + sys.exit(1) + +bus = dbus.SystemBus() +path = /profile/default/ + sys.argv[1] +service = dbus.Interface(bus.get_object('net.connman', path), + 'net.connman.Service') + +path2 = /profile/default/ + sys.argv[2] +service2 = dbus.Interface(bus.get_object('net.connman', path2), + 'net.connman.Service') + +print Moving %s before %s % (sys.argv[1], sys.argv[2]) + +service.MoveBefore(service2) + +print -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH service move v2 2/6] service: Allow ready service to be moved before online one.
--- src/service.c | 28 1 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/service.c b/src/service.c index b8f1c70..2819d51 100644 --- a/src/service.c +++ b/src/service.c @@ -2912,6 +2912,22 @@ static DBusMessage *remove_service(DBusConnection *conn, return g_dbus_create_reply(msg, DBUS_TYPE_INVALID); } +static gboolean check_suitable_state(enum connman_service_state a, + enum connman_service_state b) +{ + /* +* Special check so that ready service can be moved before +* online one. +*/ + if ((a == CONNMAN_SERVICE_STATE_ONLINE + b == CONNMAN_SERVICE_STATE_READY) || + (b == CONNMAN_SERVICE_STATE_ONLINE + a == CONNMAN_SERVICE_STATE_READY)) + return TRUE; + + return a == b; +} + static DBusMessage *move_service(DBusConnection *conn, DBusMessage *msg, void *user_data, gboolean before) @@ -2954,28 +2970,32 @@ static DBusMessage *move_service(DBusConnection *conn, */ if (target4 == CONNMAN_IPCONFIG_METHOD_OFF) { if (service6 != CONNMAN_IPCONFIG_METHOD_OFF) { - if (target-state_ipv6 != service-state_ipv6) + if (check_suitable_state(target-state_ipv6, + service-state_ipv6) == FALSE) return __connman_error_invalid_service(msg); } } if (target6 == CONNMAN_IPCONFIG_METHOD_OFF) { if (service4 != CONNMAN_IPCONFIG_METHOD_OFF) { - if (target-state_ipv4 != service-state_ipv4) + if (check_suitable_state(target-state_ipv4, + service-state_ipv4) == FALSE) return __connman_error_invalid_service(msg); } } if (service4 == CONNMAN_IPCONFIG_METHOD_OFF) { if (target6 != CONNMAN_IPCONFIG_METHOD_OFF) { - if (target-state_ipv6 != service-state_ipv6) + if (check_suitable_state(target-state_ipv6, + service-state_ipv6) == FALSE) return __connman_error_invalid_service(msg); } } if (service6 == CONNMAN_IPCONFIG_METHOD_OFF) { if (target4 != CONNMAN_IPCONFIG_METHOD_OFF) { - if (target-state_ipv4 != service-state_ipv4) + if (check_suitable_state(target-state_ipv4, + service-state_ipv4) == FALSE) return __connman_error_invalid_service(msg); } } -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH service move v2 6/6] connection: Default gateway is changed when reorganizing services.
Fixes BMC#22540 --- src/connection.c | 90 - 1 files changed, 88 insertions(+), 2 deletions(-) diff --git a/src/connection.c b/src/connection.c index 84e3ab4..3a6a116 100644 --- a/src/connection.c +++ b/src/connection.c @@ -326,6 +326,70 @@ done: __connman_service_indicate_default(data-service); } +static void unset_default_gateway(struct gateway_data *data, + enum connman_ipconfig_type type) +{ + int index; + int status4 = 0, status6 = 0; + int do_ipv4 = FALSE, do_ipv6 = FALSE; + + if (type == CONNMAN_IPCONFIG_TYPE_IPV4) + do_ipv4 = TRUE; + else if (type == CONNMAN_IPCONFIG_TYPE_IPV6) + do_ipv6 = TRUE; + else + do_ipv4 = do_ipv6 = TRUE; + + DBG(type %d gateway ipv4 %p ipv6 %p, type, data-ipv4_gateway, + data-ipv6_gateway); + + if (do_ipv4 == TRUE data-ipv4_gateway != NULL + data-ipv4_gateway-vpn == TRUE) { + connman_inet_del_host_route(data-index, + data-ipv4_gateway-vpn_ip); + connman_inet_clear_gateway_address(data-index, + data-ipv4_gateway-vpn_ip); + data-ipv4_gateway-active = FALSE; + + return; + } + + if (do_ipv6 == TRUE data-ipv6_gateway != NULL + data-ipv6_gateway-vpn == TRUE) { + connman_inet_del_ipv6_host_route(data-index, + data-ipv6_gateway-vpn_ip); + connman_inet_clear_ipv6_gateway_address(data-index, + data-ipv6_gateway-vpn_ip); + data-ipv6_gateway-active = FALSE; + + return; + } + + index = __connman_service_get_index(data-service); + + if (do_ipv4 == TRUE data-ipv4_gateway != NULL + g_strcmp0(data-ipv4_gateway-gateway, + 0.0.0.0) == 0) { + connman_inet_clear_gateway_interface(index); + return; + } + + if (do_ipv6 == TRUE data-ipv6_gateway != NULL + g_strcmp0(data-ipv6_gateway-gateway, + ::) == 0) { + connman_inet_clear_ipv6_gateway_interface(index); + return; + } + + if (do_ipv6 == TRUE data-ipv6_gateway != NULL) + status6 = connman_inet_clear_ipv6_gateway_address(index, + data-ipv6_gateway-gateway); + + if (do_ipv4 == TRUE data-ipv4_gateway != NULL) + status4 = connman_inet_clear_gateway_address(index, + data-ipv4_gateway-gateway); +} + static struct gateway_data *find_default_gateway(void) { struct gateway_data *found = NULL; @@ -684,14 +748,36 @@ gboolean __connman_connection_update_gateway(void) if (gateway_hash == NULL) return updated; + active_gateway = find_active_gateway(); + update_order(); - active_gateway = find_active_gateway(); default_gateway = find_default_gateway(); - if (active_gateway active_gateway != default_gateway) + if (active_gateway active_gateway != default_gateway) { updated = TRUE; + if (active_gateway-ipv4_gateway) + unset_default_gateway(active_gateway, + CONNMAN_IPCONFIG_TYPE_IPV4); + + if (active_gateway-ipv6_gateway) + unset_default_gateway(active_gateway, + CONNMAN_IPCONFIG_TYPE_IPV6); + + __connman_service_downgrade_state(active_gateway-service); + + if (default_gateway) { + if (default_gateway-ipv4_gateway) + set_default_gateway(default_gateway, + CONNMAN_IPCONFIG_TYPE_IPV4); + + if (default_gateway-ipv6_gateway) + set_default_gateway(default_gateway, + CONNMAN_IPCONFIG_TYPE_IPV6); + } + } + return updated; } -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH fast connect 0/9] Fast connect resend
Hi, here is the fast connect patches sent again. The patches consists of Mohamed's original patches + some fixes to make the fast connect work properly. The patches also require supplicant changes (patch sent to supplicant mailing list 23 Aug). Jukka Jukka Rissanen (4): gsupplicant: Fix the ssid array. wifi: Removed extra scan request call. device: Make debug print more useful. wifi: Fallback to normal scan if fast scan is not supported. Mohamed Abbas (5): Add frequency support to service. Add support to multi scan type. Add support to append char ** entries to dbus dict. Get the number of scan ssids from supplicant. Add ssids and frequencies to wpa_supplicant scan for fast scan. gsupplicant/dbus.c| 29 ++ gsupplicant/dbus.h| 20 gsupplicant/gsupplicant.h | 19 gsupplicant/supplicant.c | 162 +-- include/device.h |1 + plugins/wifi.c| 240 - src/device.c |6 +- src/service.c |5 + 8 files changed, 469 insertions(+), 13 deletions(-) ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH fast connect 1/9] service: Add frequency support to service.
From: Mohamed Abbas mohamed.ab...@intel.com Get the frequncy of gsupplicant network on connman network creation, and always save the frequency of the wifi service. --- gsupplicant/gsupplicant.h |1 + gsupplicant/supplicant.c | 10 ++ plugins/wifi.c|3 +++ src/service.c |5 + 4 files changed, 19 insertions(+), 0 deletions(-) diff --git a/gsupplicant/gsupplicant.h b/gsupplicant/gsupplicant.h index 5c453aa..a634141 100644 --- a/gsupplicant/gsupplicant.h +++ b/gsupplicant/gsupplicant.h @@ -196,6 +196,7 @@ const void *g_supplicant_network_get_ssid(GSupplicantNetwork *network, const char *g_supplicant_network_get_mode(GSupplicantNetwork *network); const char *g_supplicant_network_get_security(GSupplicantNetwork *network); dbus_int16_t g_supplicant_network_get_signal(GSupplicantNetwork *network); +dbus_int16_t g_supplicant_network_get_frequency(GSupplicantNetwork *network); dbus_bool_t g_supplicant_network_get_wps(GSupplicantNetwork *network); struct _GSupplicantCallbacks { diff --git a/gsupplicant/supplicant.c b/gsupplicant/supplicant.c index e5743f0..ba9f207 100644 --- a/gsupplicant/supplicant.c +++ b/gsupplicant/supplicant.c @@ -178,6 +178,7 @@ struct _GSupplicantNetwork { unsigned char ssid[32]; unsigned int ssid_len; dbus_int16_t signal; + dbus_uint16_t frequency; GSupplicantMode mode; GSupplicantSecurity security; dbus_bool_t wps; @@ -782,6 +783,14 @@ dbus_int16_t g_supplicant_network_get_signal(GSupplicantNetwork *network) return network-signal; } +dbus_int16_t g_supplicant_network_get_frequency(GSupplicantNetwork *network) +{ + if (network == NULL) + return 0; + + return network-frequency; +} + dbus_bool_t g_supplicant_network_get_wps(GSupplicantNetwork *network) { if (network == NULL) @@ -1006,6 +1015,7 @@ static void add_bss_to_network(struct g_supplicant_bss *bss) network-ssid_len = bss-ssid_len; memcpy(network-ssid, bss-ssid, bss-ssid_len); network-signal = bss-signal; + network-frequency = bss-frequency; network-wps = FALSE; if ((bss-keymgmt G_SUPPLICANT_KEYMGMT_WPS) != 0) diff --git a/plugins/wifi.c b/plugins/wifi.c index 469ec67..9ec6581 100644 --- a/plugins/wifi.c +++ b/plugins/wifi.c @@ -850,6 +850,9 @@ static void network_added(GSupplicantNetwork *supplicant_network) calculate_strength(supplicant_network)); connman_network_set_bool(network, WiFi.WPS, wps); + connman_network_set_frequency(network, + g_supplicant_network_get_frequency(supplicant_network)); + connman_network_set_available(network, TRUE); if (ssid != NULL) diff --git a/src/service.c b/src/service.c index fc90934..f1f768a 100644 --- a/src/service.c +++ b/src/service.c @@ -5293,6 +5293,7 @@ static int service_save(struct connman_service *service) gchar *pathname, *data = NULL; gsize length; gchar *str; + gint freq; const char *cst_str = NULL; int err = 0; @@ -5359,6 +5360,10 @@ update: g_string_free(str, TRUE); } + + freq = connman_network_get_frequency(service-network); + g_key_file_set_integer(keyfile, service-identifier, + Frequency, freq); } /* fall through */ -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH fast connect 4/9] gsupplicant: Get the number of scan ssids from supplicant.
From: Mohamed Abbas mohamed.ab...@intel.com --- gsupplicant/gsupplicant.h |2 ++ gsupplicant/supplicant.c | 18 +- 2 files changed, 19 insertions(+), 1 deletions(-) diff --git a/gsupplicant/gsupplicant.h b/gsupplicant/gsupplicant.h index a634141..5f7adc0 100644 --- a/gsupplicant/gsupplicant.h +++ b/gsupplicant/gsupplicant.h @@ -181,6 +181,8 @@ const void *g_supplicant_interface_get_wps_ssid(GSupplicantInterface *interface, unsigned int *ssid_len); GSupplicantWpsState g_supplicant_interface_get_wps_state(GSupplicantInterface *interface); unsigned int g_supplicant_interface_get_mode(GSupplicantInterface *interface); +unsigned int g_supplicant_interface_get_max_scan_ssids( + GSupplicantInterface *interface); /* Network API */ struct _GSupplicantNetwork; diff --git a/gsupplicant/supplicant.c b/gsupplicant/supplicant.c index ba9f207..828d6f3 100644 --- a/gsupplicant/supplicant.c +++ b/gsupplicant/supplicant.c @@ -153,6 +153,7 @@ struct _GSupplicantInterface { unsigned int pairwise_capa; unsigned int scan_capa; unsigned int mode_capa; + unsigned int max_scan_ssids; dbus_bool_t ready; GSupplicantState state; dbus_bool_t scanning; @@ -611,7 +612,13 @@ static void interface_capability(const char *key, DBusMessageIter *iter, else if (g_strcmp0(key, Modes) == 0) supplicant_dbus_array_foreach(iter, interface_capability_mode, interface); - else + else if (g_strcmp0(key, MaxScanSSID) == 0) { + dbus_int32_t max_scan_ssid; + + dbus_message_iter_get_basic(iter, max_scan_ssid); + interface-max_scan_ssids = max_scan_ssid; + + } else SUPPLICANT_DBG(key %s type %c, key, dbus_message_iter_get_arg_type(iter)); } @@ -714,6 +721,15 @@ unsigned int g_supplicant_interface_get_mode(GSupplicantInterface *interface) return interface-mode_capa; } +unsigned int g_supplicant_interface_get_max_scan_ssids( + GSupplicantInterface *interface) +{ + if (interface == NULL) + return 0; + + return interface-max_scan_ssids; +} + GSupplicantInterface *g_supplicant_network_get_interface( GSupplicantNetwork *network) { -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH fast connect 6/9] gsupplicant: Fix the ssid array.
--- gsupplicant/gsupplicant.h |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/gsupplicant/gsupplicant.h b/gsupplicant/gsupplicant.h index 059837f..93e1c8e 100644 --- a/gsupplicant/gsupplicant.h +++ b/gsupplicant/gsupplicant.h @@ -135,7 +135,7 @@ typedef struct _GSupplicantSSID GSupplicantSSID; struct _GSupplicantScanParams { struct scan_ssid { - unsigned char *ssid[32]; + unsigned char ssid[32]; uint8_t ssid_len; } ssids[G_SUPPLICANT_MAX_FAST_SCAN]; -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH fast connect 5/9] wifi: Add SSIDs and frequencies to wpa_supplicant scan for fast scan.
From: Mohamed Abbas mohamed.ab...@intel.com --- gsupplicant/gsupplicant.h | 16 gsupplicant/supplicant.c | 134 ++-- plugins/wifi.c| 217 - 3 files changed, 357 insertions(+), 10 deletions(-) diff --git a/gsupplicant/gsupplicant.h b/gsupplicant/gsupplicant.h index 5f7adc0..059837f 100644 --- a/gsupplicant/gsupplicant.h +++ b/gsupplicant/gsupplicant.h @@ -73,6 +73,8 @@ extern C { #define G_SUPPLICANT_PAIRWISE_TKIP (1 1) #define G_SUPPLICANT_PAIRWISE_CCMP (1 2) +#define G_SUPPLICANT_MAX_FAST_SCAN 4 + typedef enum { G_SUPPLICANT_MODE_UNKNOWN, G_SUPPLICANT_MODE_INFRA, @@ -131,6 +133,19 @@ struct _GSupplicantSSID { typedef struct _GSupplicantSSID GSupplicantSSID; +struct _GSupplicantScanParams { + struct scan_ssid { + unsigned char *ssid[32]; + uint8_t ssid_len; + } ssids[G_SUPPLICANT_MAX_FAST_SCAN]; + + uint8_t num_ssids; + + uint16_t freqs[G_SUPPLICANT_MAX_FAST_SCAN]; +}; + +typedef struct _GSupplicantScanParams GSupplicantScanParams; + /* global API */ typedef void (*GSupplicantCountryCallback) (void *user_data); @@ -155,6 +170,7 @@ int g_supplicant_interface_remove(GSupplicantInterface *interface, GSupplicantInterfaceCallback callback, void *user_data); int g_supplicant_interface_scan(GSupplicantInterface *interface, + GSupplicantScanParams *scan_data, GSupplicantInterfaceCallback callback, void *user_data); diff --git a/gsupplicant/supplicant.c b/gsupplicant/supplicant.c index 828d6f3..d2e6aff 100644 --- a/gsupplicant/supplicant.c +++ b/gsupplicant/supplicant.c @@ -2113,6 +2113,13 @@ struct interface_connect_data { void *user_data; }; +struct interface_scan_data { + GSupplicantInterface *interface; + GSupplicantInterfaceCallback callback; + GSupplicantScanParams *scan_params; + void *user_data; +}; + static void interface_create_property(const char *key, DBusMessageIter *iter, void *user_data) { @@ -2368,9 +2375,11 @@ int g_supplicant_interface_remove(GSupplicantInterface *interface, static void interface_scan_result(const char *error, DBusMessageIter *iter, void *user_data) { - struct interface_data *data = user_data; + struct interface_scan_data *data = user_data; if (error != NULL) { + SUPPLICANT_DBG(error %s, error); + if (data-callback != NULL) data-callback(-EIO, data-interface, data-user_data); } else { @@ -2378,27 +2387,134 @@ static void interface_scan_result(const char *error, data-interface-scan_data = data-user_data; } + if (data != NULL data-scan_params != NULL) + g_free(data-scan_params); + dbus_free(data); } +static void add_scan_frequency(DBusMessageIter *iter, unsigned int freq) +{ + DBusMessageIter data; + unsigned int width; + + dbus_message_iter_open_container(iter, DBUS_TYPE_STRUCT, NULL, data); + + dbus_message_iter_append_basic(data, DBUS_TYPE_UINT32, freq); + dbus_message_iter_append_basic(data, DBUS_TYPE_UINT32, width); + + dbus_message_iter_close_container(iter, data); +} + +static void add_scan_frequencies(DBusMessageIter *iter, + void *user_data) +{ + GSupplicantScanParams *scan_data = user_data; + unsigned int freq; + int i; + + for (i = 0; i G_SUPPLICANT_MAX_FAST_SCAN; i++) { + freq = scan_data-freqs[i]; + if (!freq) + break; + + add_scan_frequency(iter, freq); + } +} + +static void append_ssid(DBusMessageIter *iter, + const void *ssid, unsigned int len) +{ + DBusMessageIter array; + + dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, + DBUS_TYPE_BYTE_AS_STRING, array); + + dbus_message_iter_append_fixed_array(array, DBUS_TYPE_BYTE, + ssid, len); + dbus_message_iter_close_container(iter, array); +} + +static void append_ssids(DBusMessageIter *iter, void *user_data) +{ + GSupplicantScanParams *scan_data = user_data; + int i; + + for (i = 0; i scan_data-num_ssids; i++) + append_ssid(iter, scan_data-ssids[i].ssid, + scan_data-ssids[i].ssid_len); +} + +static void supplicant_add_scan_frequency(DBusMessageIter *dict, + const char *key, supplicant_dbus_array_function function, + void
[PATCH fast connect 8/9] device: Make debug print more useful.
--- src/device.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/src/device.c b/src/device.c index 6b8e873..6e84bc4 100644 --- a/src/device.c +++ b/src/device.c @@ -106,7 +106,7 @@ static void reset_scan_trigger(struct connman_device *device) } else interval = device-scan_interval; - DBG(interval %d, interval); + DBG(interface %s interval %d, device-interface, interval); device-scan_timeout = g_timeout_add_seconds(interval, device_scan_trigger, device); -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH fast connect 7/9] wifi: Removed extra scan request call.
The wifi_scan_fast() is already called in connman_device_set_powered() so no need to call it again immediately. --- plugins/wifi.c |2 -- 1 files changed, 0 insertions(+), 2 deletions(-) diff --git a/plugins/wifi.c b/plugins/wifi.c index b9e30db..c0607f5 100644 --- a/plugins/wifi.c +++ b/plugins/wifi.c @@ -801,8 +801,6 @@ static void interface_added(GSupplicantInterface *interface) if (wifi-tethering == TRUE) return; - - wifi_scan_fast(wifi-device); } static connman_bool_t is_idle(struct wifi_data *wifi) -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH fast connect 9/9] wifi: Fallback to normal scan if fast scan is not supported.
--- plugins/wifi.c |9 ++--- 1 files changed, 6 insertions(+), 3 deletions(-) diff --git a/plugins/wifi.c b/plugins/wifi.c index c0607f5..410095d 100644 --- a/plugins/wifi.c +++ b/plugins/wifi.c @@ -506,13 +506,16 @@ static int wifi_scan_fast(struct connman_device *device) if (wifi-tethering == TRUE) return 0; + driver_max = g_supplicant_interface_get_max_scan_ssids( + wifi-interface); + DBG(max ssids %d, driver_max); + if (driver_max == 0) + return wifi_scan(device); + scan_params = g_try_malloc0(sizeof(GSupplicantScanParams)); if (scan_params == NULL) return -ENOMEM; - driver_max = g_supplicant_interface_get_max_scan_ssids( - wifi-interface); - DBG(max ssids %d, driver_max); get_latest_connections(wifi_, driver_max, scan_params); ret = g_supplicant_interface_scan(wifi-interface, scan_params, -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH misc 03/14] service: Add function to get the ipconfig state.
--- src/connman.h |3 +++ src/service.c | 13 + 2 files changed, 16 insertions(+), 0 deletions(-) diff --git a/src/connman.h b/src/connman.h index 17add6d..6b2216a 100644 --- a/src/connman.h +++ b/src/connman.h @@ -502,6 +502,9 @@ void __connman_service_set_string(struct connman_service *service, int __connman_service_ipconfig_indicate_state(struct connman_service *service, enum connman_service_state new_state, enum connman_ipconfig_type type); +enum connman_service_state __connman_service_ipconfig_get_state( + struct connman_service *service, + enum connman_ipconfig_type type); int __connman_service_indicate_error(struct connman_service *service, enum connman_service_error error); diff --git a/src/service.c b/src/service.c index fc90934..60c5ccc 100644 --- a/src/service.c +++ b/src/service.c @@ -3702,6 +3702,19 @@ int __connman_service_indicate_default(struct connman_service *service) return 0; } +enum connman_service_state __connman_service_ipconfig_get_state( + struct connman_service *service, + enum connman_ipconfig_type type) +{ + if (type == CONNMAN_IPCONFIG_TYPE_IPV4) + return service-state_ipv4; + + if (type == CONNMAN_IPCONFIG_TYPE_IPV6) + return service-state_ipv6; + + return CONNMAN_SERVICE_STATE_UNKNOWN; +} + static void check_proxy_setup(struct connman_service *service) { /* -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH misc 01/14] provider: NULL pointer check.
--- src/provider.c |3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/src/provider.c b/src/provider.c index 9ae62cd..633ca40 100644 --- a/src/provider.c +++ b/src/provider.c @@ -879,6 +879,9 @@ int connman_provider_append_route(struct connman_provider *provider, const char *connman_provider_get_driver_name(struct connman_provider *provider) { + if (provider-driver == NULL) + return NULL; + return provider-driver-name; } -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH misc 08/14] service: Fix state combining.
If we have IPv6 state as DISCONNECT and IPv4 state as ONLINE or READY then we are not disconnected. --- src/service.c | 64 ++-- 1 files changed, 16 insertions(+), 48 deletions(-) diff --git a/src/service.c b/src/service.c index 089a715..2aebff2 100644 --- a/src/service.c +++ b/src/service.c @@ -329,75 +329,43 @@ static enum connman_service_state combine_state( goto done; } - if (state_a == CONNMAN_SERVICE_STATE_ASSOCIATION) { - if (state_b == CONNMAN_SERVICE_STATE_CONFIGURATION || - state_b == CONNMAN_SERVICE_STATE_ONLINE || - state_b == CONNMAN_SERVICE_STATE_READY) - result = state_b; - else - result = state_a; + if (state_a == CONNMAN_SERVICE_STATE_ONLINE) { + result = state_a; goto done; } - if (state_b == CONNMAN_SERVICE_STATE_ASSOCIATION) { - if (state_a == CONNMAN_SERVICE_STATE_CONFIGURATION || - state_a == CONNMAN_SERVICE_STATE_ONLINE || - state_a == CONNMAN_SERVICE_STATE_READY) - result = state_a; - else - result = state_b; + if (state_b == CONNMAN_SERVICE_STATE_ONLINE) { + result = state_b; goto done; } - if (state_a == CONNMAN_SERVICE_STATE_CONFIGURATION) { - if (state_b == CONNMAN_SERVICE_STATE_ONLINE || - state_b == CONNMAN_SERVICE_STATE_READY) - result = state_b; - else - result = state_a; + if (state_a == CONNMAN_SERVICE_STATE_READY) { + result = state_a; goto done; } - if (state_b == CONNMAN_SERVICE_STATE_CONFIGURATION) { - if (state_a == CONNMAN_SERVICE_STATE_ONLINE || - state_a == CONNMAN_SERVICE_STATE_READY) - result = state_a; - else - result = state_b; + if (state_b == CONNMAN_SERVICE_STATE_READY) { + result = state_b; goto done; } - if (state_a == CONNMAN_SERVICE_STATE_READY) { - if (state_b == CONNMAN_SERVICE_STATE_ONLINE || - state_b == CONNMAN_SERVICE_STATE_DISCONNECT) - result = state_b; - else - result = state_a; + if (state_a == CONNMAN_SERVICE_STATE_CONFIGURATION) { + result = state_a; goto done; } - if (state_b == CONNMAN_SERVICE_STATE_READY) { - if (state_a == CONNMAN_SERVICE_STATE_ONLINE || - state_a == CONNMAN_SERVICE_STATE_DISCONNECT) - result = state_a; - else - result = state_b; + if (state_b == CONNMAN_SERVICE_STATE_CONFIGURATION) { + result = state_b; goto done; } - if (state_a == CONNMAN_SERVICE_STATE_ONLINE) { - if (state_b == CONNMAN_SERVICE_STATE_DISCONNECT) - result = state_b; - else - result = state_a; + if (state_a == CONNMAN_SERVICE_STATE_ASSOCIATION) { + result = state_a; goto done; } - if (state_b == CONNMAN_SERVICE_STATE_ONLINE) { - if (state_a == CONNMAN_SERVICE_STATE_DISCONNECT) - result = state_a; - else - result = state_b; + if (state_b == CONNMAN_SERVICE_STATE_ASSOCIATION) { + result = state_b; goto done; } -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH misc 07/14] service: Change the debug print location to be more useful.
--- src/service.c |6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/service.c b/src/service.c index 7ec4a30..089a715 100644 --- a/src/service.c +++ b/src/service.c @@ -3501,9 +3501,6 @@ static int service_indicate_state(struct connman_service *service) old_state = service-state; new_state = combine_state(service-state_ipv4, service-state_ipv6); - if (old_state == new_state) - return -EALREADY; - DBG(service %p old %s - new %s/%s = %s, service, state2string(old_state), @@ -3511,6 +3508,9 @@ static int service_indicate_state(struct connman_service *service) state2string(service-state_ipv6), state2string(new_state)); + if (old_state == new_state) + return -EALREADY; + service-state = new_state; state_changed(service); -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH misc 09/14] service: Set the service state to IDLE if method is off or unknown.
--- src/service.c | 28 +++- 1 files changed, 27 insertions(+), 1 deletions(-) diff --git a/src/service.c b/src/service.c index 2aebff2..a081b79 100644 --- a/src/service.c +++ b/src/service.c @@ -3711,6 +3711,7 @@ int __connman_service_ipconfig_indicate_state(struct connman_service *service, { struct connman_ipconfig *ipconfig = NULL; enum connman_service_state old_state; + int ret; if (service == NULL) return -EINVAL; @@ -3768,7 +3769,32 @@ int __connman_service_ipconfig_indicate_state(struct connman_service *service, else if (type == CONNMAN_IPCONFIG_TYPE_IPV6) service-state_ipv6 = new_state; - return service_indicate_state(service); + ret = service_indicate_state(service); + + /* +* If the ipconfig method is OFF, then we set the state to IDLE +* so that it will not affect the combined state in the future. +*/ + if (type == CONNMAN_IPCONFIG_TYPE_IPV4) { + enum connman_ipconfig_method method; + method = __connman_ipconfig_get_method(service-ipconfig_ipv4); + if (method == CONNMAN_IPCONFIG_METHOD_OFF || + method == CONNMAN_IPCONFIG_METHOD_UNKNOWN) { + service-state_ipv4 = CONNMAN_SERVICE_STATE_IDLE; + ret = service_indicate_state(service); + } + + } else if (type == CONNMAN_IPCONFIG_TYPE_IPV6) { + enum connman_ipconfig_method method; + method = __connman_ipconfig_get_method(service-ipconfig_ipv6); + if (method == CONNMAN_IPCONFIG_METHOD_OFF || + method == CONNMAN_IPCONFIG_METHOD_UNKNOWN) { + service-state_ipv6 = CONNMAN_SERVICE_STATE_IDLE; + ret = service_indicate_state(service); + } + } + + return ret; } int __connman_service_request_login(struct connman_service *service) -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH misc 10/14] provider: Add ref counting debug.
--- src/provider.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/provider.c b/src/provider.c index 633ca40..bbd462e 100644 --- a/src/provider.c +++ b/src/provider.c @@ -143,7 +143,7 @@ static void provider_unregister(struct connman_provider *provider) struct connman_provider *connman_provider_ref(struct connman_provider *provider) { - DBG(provider %p, provider); + DBG(provider %p refcount %d, provider, provider-refcount + 1); g_atomic_int_inc(provider-refcount); @@ -165,7 +165,7 @@ static void provider_destruct(struct connman_provider *provider) void connman_provider_unref(struct connman_provider *provider) { - DBG(provider %p, provider); + DBG(provider %p refcount %d, provider, provider-refcount - 1); if (g_atomic_int_dec_and_test(provider-refcount) == FALSE) return; -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH misc 13/14] network: Add NULL check.
--- src/network.c |3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/src/network.c b/src/network.c index 31e7eaa..b8175a5 100644 --- a/src/network.c +++ b/src/network.c @@ -1330,6 +1330,9 @@ int __connman_network_set_ipconfig(struct connman_network *network, enum connman_ipconfig_method method; int ret; + if (network == NULL) + return -EINVAL; + if (ipconfig_ipv6) { method = __connman_ipconfig_get_method(ipconfig_ipv6); -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH misc 11/14] provider: Return existing service path if already connected.
--- src/provider.c |9 + 1 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/provider.c b/src/provider.c index bbd462e..8f1862e 100644 --- a/src/provider.c +++ b/src/provider.c @@ -571,11 +571,12 @@ int __connman_provider_create_and_connect(DBusMessage *msg) err = -EOPNOTSUPP; goto unref; } - } - err = __connman_service_connect(provider-vpn_service); - if (err 0 err != -EINPROGRESS) - goto failed; + err = __connman_service_connect(provider-vpn_service); + if (err 0 err != -EINPROGRESS) + goto failed; + } else + DBG(provider already connected); service_path = __connman_service_get_path(provider-vpn_service); g_dbus_send_reply(connection, msg, -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH misc 12/14] connection: Service was not ref counted properly.
The reference counting problems were clearly seen with VPN service. --- src/connection.c |6 -- 1 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/connection.c b/src/connection.c index 84e3ab4..6323401 100644 --- a/src/connection.c +++ b/src/connection.c @@ -229,6 +229,7 @@ static struct gateway_data *add_gateway(struct connman_service *service, } } + connman_service_ref(service); g_hash_table_replace(gateway_hash, service, data); return data; @@ -657,9 +658,10 @@ void __connman_connection_gateway_remove(struct connman_service *service, do_ipv4 == TRUE) || (data-ipv6_gateway != NULL data-ipv4_gateway == NULL do_ipv6 == TRUE) - ) + ) { + connman_service_unref(service); g_hash_table_remove(gateway_hash, service); - else + } else DBG(Not yet removing gw ipv4 %p/%d ipv6 %p/%d, data-ipv4_gateway, do_ipv4, data-ipv6_gateway, do_ipv6); -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH fast connect v2 0/5] Fast connect resend
Hi, v2 contains the fixes to comments by Samuel. Jukka Mohamed Abbas (5): service: Add frequency support to service. wifi: Add support to multi scan type. gsupplicant: Add support to append char ** entries to dbus dict. gsupplicant: Get the number of scan ssids from supplicant. wifi: Add SSIDs and frequencies to wpa_supplicant scan for fast scan. gsupplicant/dbus.c| 34 +++ gsupplicant/dbus.h| 20 gsupplicant/gsupplicant.h | 19 gsupplicant/supplicant.c | 163 +++- include/device.h |1 + plugins/wifi.c| 226 - src/device.c |4 +- src/service.c |5 + 8 files changed, 461 insertions(+), 11 deletions(-) ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH fast connect v2 2/5] wifi: Add support to multi scan type.
From: Mohamed Abbas mohamed.ab...@intel.com Allow multi scan type for fast connect. Scanning request removed from interface_added() because it is already called in connman_device_set_powered() so no need to call it again immediately (fix by Jukka Rissanen jukka.rissa...@linux.intel.com) --- include/device.h |1 + plugins/wifi.c | 21 +++-- src/device.c |4 +++- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/include/device.h b/include/device.h index d4f54ec..3749a20 100644 --- a/include/device.h +++ b/include/device.h @@ -108,6 +108,7 @@ struct connman_device_driver { int (*enable) (struct connman_device *device); int (*disable) (struct connman_device *device); int (*scan) (struct connman_device *device); + int (*scan_fast) (struct connman_device *device); }; int connman_device_driver_register(struct connman_device_driver *driver); diff --git a/plugins/wifi.c b/plugins/wifi.c index e1aecab..03d94ee 100644 --- a/plugins/wifi.c +++ b/plugins/wifi.c @@ -298,6 +298,24 @@ static int wifi_scan(struct connman_device *device) return ret; } +static int wifi_scan_fast(struct connman_device *device) +{ + struct wifi_data *wifi = connman_device_get_data(device); + int ret; + + DBG(device %p %p, device, wifi-interface); + + if (wifi-tethering == TRUE) + return 0; + + ret = g_supplicant_interface_scan(wifi-interface, scan_callback, + device); + if (ret == 0) + connman_device_set_scanning(device, TRUE); + + return ret; +} + static struct connman_device_driver wifi_ng_driver = { .name = wifi, .type = CONNMAN_DEVICE_TYPE_WIFI, @@ -307,6 +325,7 @@ static struct connman_device_driver wifi_ng_driver = { .enable = wifi_enable, .disable= wifi_disable, .scan = wifi_scan, + .scan_fast = wifi_scan_fast, }; static void system_ready(void) @@ -573,8 +592,6 @@ static void interface_added(GSupplicantInterface *interface) if (wifi-tethering == TRUE) return; - - wifi_scan(wifi-device); } static connman_bool_t is_idle(struct wifi_data *wifi) diff --git a/src/device.c b/src/device.c index 12fa49a..ac28326 100644 --- a/src/device.c +++ b/src/device.c @@ -692,7 +692,9 @@ int connman_device_set_powered(struct connman_device *device, reset_scan_trigger(device); - if (device-driver device-driver-scan) + if (device-driver device-driver-scan_fast) + device-driver-scan_fast(device); + else if (device-driver device-driver-scan) device-driver-scan(device); return 0; -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH fast connect v2 1/5] service: Add frequency support to service.
From: Mohamed Abbas mohamed.ab...@intel.com Get the frequncy of gsupplicant network on connman network creation, and always save the frequency of the wifi service. --- gsupplicant/gsupplicant.h |1 + gsupplicant/supplicant.c | 10 ++ plugins/wifi.c|3 +++ src/service.c |5 + 4 files changed, 19 insertions(+), 0 deletions(-) diff --git a/gsupplicant/gsupplicant.h b/gsupplicant/gsupplicant.h index 5c453aa..8e3690b 100644 --- a/gsupplicant/gsupplicant.h +++ b/gsupplicant/gsupplicant.h @@ -196,6 +196,7 @@ const void *g_supplicant_network_get_ssid(GSupplicantNetwork *network, const char *g_supplicant_network_get_mode(GSupplicantNetwork *network); const char *g_supplicant_network_get_security(GSupplicantNetwork *network); dbus_int16_t g_supplicant_network_get_signal(GSupplicantNetwork *network); +dbus_uint16_t g_supplicant_network_get_frequency(GSupplicantNetwork *network); dbus_bool_t g_supplicant_network_get_wps(GSupplicantNetwork *network); struct _GSupplicantCallbacks { diff --git a/gsupplicant/supplicant.c b/gsupplicant/supplicant.c index e5743f0..7afdc68 100644 --- a/gsupplicant/supplicant.c +++ b/gsupplicant/supplicant.c @@ -178,6 +178,7 @@ struct _GSupplicantNetwork { unsigned char ssid[32]; unsigned int ssid_len; dbus_int16_t signal; + dbus_uint16_t frequency; GSupplicantMode mode; GSupplicantSecurity security; dbus_bool_t wps; @@ -782,6 +783,14 @@ dbus_int16_t g_supplicant_network_get_signal(GSupplicantNetwork *network) return network-signal; } +dbus_uint16_t g_supplicant_network_get_frequency(GSupplicantNetwork *network) +{ + if (network == NULL) + return 0; + + return network-frequency; +} + dbus_bool_t g_supplicant_network_get_wps(GSupplicantNetwork *network) { if (network == NULL) @@ -1006,6 +1015,7 @@ static void add_bss_to_network(struct g_supplicant_bss *bss) network-ssid_len = bss-ssid_len; memcpy(network-ssid, bss-ssid, bss-ssid_len); network-signal = bss-signal; + network-frequency = bss-frequency; network-wps = FALSE; if ((bss-keymgmt G_SUPPLICANT_KEYMGMT_WPS) != 0) diff --git a/plugins/wifi.c b/plugins/wifi.c index f3ea836..e1aecab 100644 --- a/plugins/wifi.c +++ b/plugins/wifi.c @@ -836,6 +836,9 @@ static void network_added(GSupplicantNetwork *supplicant_network) calculate_strength(supplicant_network)); connman_network_set_bool(network, WiFi.WPS, wps); + connman_network_set_frequency(network, + g_supplicant_network_get_frequency(supplicant_network)); + connman_network_set_available(network, TRUE); if (ssid != NULL) diff --git a/src/service.c b/src/service.c index 4ab3750..cc4856a 100644 --- a/src/service.c +++ b/src/service.c @@ -5385,6 +5385,7 @@ static int service_save(struct connman_service *service) gchar *pathname, *data = NULL; gsize length; gchar *str; + guint freq; const char *cst_str = NULL; int err = 0; @@ -5451,6 +5452,10 @@ update: g_string_free(str, TRUE); } + + freq = connman_network_get_frequency(service-network); + g_key_file_set_integer(keyfile, service-identifier, + Frequency, freq); } /* fall through */ -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH fast connect v2 4/5] gsupplicant: Get the number of scan ssids from supplicant.
From: Mohamed Abbas mohamed.ab...@intel.com --- gsupplicant/gsupplicant.h |2 ++ gsupplicant/supplicant.c | 18 +- 2 files changed, 19 insertions(+), 1 deletions(-) diff --git a/gsupplicant/gsupplicant.h b/gsupplicant/gsupplicant.h index 8e3690b..1419157 100644 --- a/gsupplicant/gsupplicant.h +++ b/gsupplicant/gsupplicant.h @@ -181,6 +181,8 @@ const void *g_supplicant_interface_get_wps_ssid(GSupplicantInterface *interface, unsigned int *ssid_len); GSupplicantWpsState g_supplicant_interface_get_wps_state(GSupplicantInterface *interface); unsigned int g_supplicant_interface_get_mode(GSupplicantInterface *interface); +unsigned int g_supplicant_interface_get_max_scan_ssids( + GSupplicantInterface *interface); /* Network API */ struct _GSupplicantNetwork; diff --git a/gsupplicant/supplicant.c b/gsupplicant/supplicant.c index 7afdc68..edc9279 100644 --- a/gsupplicant/supplicant.c +++ b/gsupplicant/supplicant.c @@ -153,6 +153,7 @@ struct _GSupplicantInterface { unsigned int pairwise_capa; unsigned int scan_capa; unsigned int mode_capa; + unsigned int max_scan_ssids; dbus_bool_t ready; GSupplicantState state; dbus_bool_t scanning; @@ -611,7 +612,13 @@ static void interface_capability(const char *key, DBusMessageIter *iter, else if (g_strcmp0(key, Modes) == 0) supplicant_dbus_array_foreach(iter, interface_capability_mode, interface); - else + else if (g_strcmp0(key, MaxScanSSID) == 0) { + dbus_int32_t max_scan_ssid; + + dbus_message_iter_get_basic(iter, max_scan_ssid); + interface-max_scan_ssids = max_scan_ssid; + + } else SUPPLICANT_DBG(key %s type %c, key, dbus_message_iter_get_arg_type(iter)); } @@ -714,6 +721,15 @@ unsigned int g_supplicant_interface_get_mode(GSupplicantInterface *interface) return interface-mode_capa; } +unsigned int g_supplicant_interface_get_max_scan_ssids( + GSupplicantInterface *interface) +{ + if (interface == NULL) + return 0; + + return interface-max_scan_ssids; +} + GSupplicantInterface *g_supplicant_network_get_interface( GSupplicantNetwork *network) { -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH fast connect v2 5/5] wifi: Add SSIDs and frequencies to wpa_supplicant scan for fast scan.
From: Mohamed Abbas mohamed.ab...@intel.com Quite many fixes by Jukka Rissanen jukka.rissa...@linux.intel.com --- gsupplicant/gsupplicant.h | 16 gsupplicant/supplicant.c | 135 - plugins/wifi.c| 206 - 3 files changed, 348 insertions(+), 9 deletions(-) diff --git a/gsupplicant/gsupplicant.h b/gsupplicant/gsupplicant.h index 1419157..c409a4c 100644 --- a/gsupplicant/gsupplicant.h +++ b/gsupplicant/gsupplicant.h @@ -73,6 +73,8 @@ extern C { #define G_SUPPLICANT_PAIRWISE_TKIP (1 1) #define G_SUPPLICANT_PAIRWISE_CCMP (1 2) +#define G_SUPPLICANT_MAX_FAST_SCAN 4 + typedef enum { G_SUPPLICANT_MODE_UNKNOWN, G_SUPPLICANT_MODE_INFRA, @@ -131,6 +133,19 @@ struct _GSupplicantSSID { typedef struct _GSupplicantSSID GSupplicantSSID; +struct _GSupplicantScanParams { + struct scan_ssid { + unsigned char ssid[32]; + uint8_t ssid_len; + } ssids[G_SUPPLICANT_MAX_FAST_SCAN]; + + uint8_t num_ssids; + + uint16_t freqs[G_SUPPLICANT_MAX_FAST_SCAN]; +}; + +typedef struct _GSupplicantScanParams GSupplicantScanParams; + /* global API */ typedef void (*GSupplicantCountryCallback) (void *user_data); @@ -155,6 +170,7 @@ int g_supplicant_interface_remove(GSupplicantInterface *interface, GSupplicantInterfaceCallback callback, void *user_data); int g_supplicant_interface_scan(GSupplicantInterface *interface, + GSupplicantScanParams *scan_data, GSupplicantInterfaceCallback callback, void *user_data); diff --git a/gsupplicant/supplicant.c b/gsupplicant/supplicant.c index edc9279..3212606 100644 --- a/gsupplicant/supplicant.c +++ b/gsupplicant/supplicant.c @@ -2113,6 +2113,13 @@ struct interface_connect_data { void *user_data; }; +struct interface_scan_data { + GSupplicantInterface *interface; + GSupplicantInterfaceCallback callback; + GSupplicantScanParams *scan_params; + void *user_data; +}; + static void interface_create_property(const char *key, DBusMessageIter *iter, void *user_data) { @@ -2368,9 +2375,11 @@ int g_supplicant_interface_remove(GSupplicantInterface *interface, static void interface_scan_result(const char *error, DBusMessageIter *iter, void *user_data) { - struct interface_data *data = user_data; + struct interface_scan_data *data = user_data; if (error != NULL) { + SUPPLICANT_DBG(error %s, error); + if (data-callback != NULL) data-callback(-EIO, data-interface, data-user_data); } else { @@ -2378,27 +2387,137 @@ static void interface_scan_result(const char *error, data-interface-scan_data = data-user_data; } + if (data != NULL data-scan_params != NULL) + g_free(data-scan_params); + dbus_free(data); } +static void add_scan_frequency(DBusMessageIter *iter, unsigned int freq) +{ + DBusMessageIter data; + unsigned int width; + + dbus_message_iter_open_container(iter, DBUS_TYPE_STRUCT, NULL, data); + + dbus_message_iter_append_basic(data, DBUS_TYPE_UINT32, freq); + dbus_message_iter_append_basic(data, DBUS_TYPE_UINT32, width); + + dbus_message_iter_close_container(iter, data); +} + +static void add_scan_frequencies(DBusMessageIter *iter, + void *user_data) +{ + GSupplicantScanParams *scan_data = user_data; + unsigned int freq; + int i; + + for (i = 0; i G_SUPPLICANT_MAX_FAST_SCAN; i++) { + freq = scan_data-freqs[i]; + if (!freq) + break; + + add_scan_frequency(iter, freq); + } +} + +static void append_ssid(DBusMessageIter *iter, + const void *ssid, unsigned int len) +{ + DBusMessageIter array; + + dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, + DBUS_TYPE_BYTE_AS_STRING, array); + + dbus_message_iter_append_fixed_array(array, DBUS_TYPE_BYTE, + ssid, len); + dbus_message_iter_close_container(iter, array); +} + +static void append_ssids(DBusMessageIter *iter, void *user_data) +{ + GSupplicantScanParams *scan_data = user_data; + int i; + + for (i = 0; i scan_data-num_ssids; i++) + append_ssid(iter, scan_data-ssids[i].ssid, + scan_data-ssids[i].ssid_len); +} + +static void supplicant_add_scan_frequency(DBusMessageIter *dict, + supplicant_dbus_array_function function
[PATCH] service: Do not allow service to be moved before a VPN service.
This is needed as the default routes are not set properly if we allow a service to be moved before a VPN service. --- Hi, it would be nice to allow a service to be moved before VPN service but unfortunately it would require bigger changes in connection.c so atm just disallow this. Jukka src/service.c |3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/src/service.c b/src/service.c index fab0cd7..8152b73 100644 --- a/src/service.c +++ b/src/service.c @@ -2916,7 +2916,8 @@ static DBusMessage *move_service(DBusConnection *conn, return __connman_error_not_supported(msg); target = find_service(path); - if (target == NULL || target-favorite == FALSE || target == service) + if (target == NULL || target-favorite == FALSE || target == service || + target-type == CONNMAN_SERVICE_TYPE_VPN) return __connman_error_invalid_service(msg); target4 = __connman_ipconfig_get_method(target-ipconfig_ipv4); -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH] network: Read only the ipconfig data if we have no address.
We must not read ipconfig data from file if there is already a valid address that was set by service set_property(). Fixes BMC#22767 --- Hi, the following patches fix the bug https://bugs.meego.com/show_bug.cgi?id=22767 where user is unable to set manual ipaddress. The bug is about IPv6 but the same applies also to IPv4 if the ipconfig method is set to OFF. Jukka src/network.c |8 +--- 1 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/network.c b/src/network.c index b8175a5..ffbf220 100644 --- a/src/network.c +++ b/src/network.c @@ -890,10 +890,11 @@ static void set_connected_manual(struct connman_network *network) service = __connman_service_lookup_from_network(network); - __connman_service_read_ip4config(service); - ipconfig = __connman_service_get_ip4config(service); + if (__connman_ipconfig_get_local(ipconfig) == NULL) + __connman_service_read_ip4config(service); + set_configuration(network); err = __connman_ipconfig_address_add(ipconfig); @@ -945,7 +946,8 @@ static int manual_ipv6_set(struct connman_network *network, if (service == NULL) return -EINVAL; - __connman_service_read_ip6config(service); + if (__connman_ipconfig_get_local(ipconfig_ipv6) == NULL) + __connman_service_read_ip6config(service); err = __connman_ipconfig_address_add(ipconfig_ipv6); if (err 0) { -- 1.7.1 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman