[PATCH 6to4 v1 4/6] service: Create 6to4 tunnel if enabled.

2011-02-14 Thread Jukka Rissanen
---
 src/connman.h |1 +
 src/ipv4.c|5 +
 src/service.c |   56 
 3 files changed, 62 insertions(+), 0 deletions(-)

diff --git a/src/connman.h b/src/connman.h
index 08bd7a9..24816a0 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -466,6 +466,7 @@ struct connman_ipconfig *__connman_service_get_ip4config(
struct connman_service *service);
 struct connman_ipconfig *__connman_service_get_ip6config(
struct connman_service *service);
+connman_bool_t __connman_service_6to4_enabled(struct connman_service *service);
 const char *__connman_service_get_ident(struct connman_service *service);
 const char *__connman_service_get_path(struct connman_service *service);
 unsigned int __connman_service_get_order(struct connman_service *service);
diff --git a/src/ipv4.c b/src/ipv4.c
index f6e436c..8cbeaf3 100644
--- a/src/ipv4.c
+++ b/src/ipv4.c
@@ -99,6 +99,9 @@ static int ipv4_probe(struct connman_element *element)
__connman_ipconfig_set_element_ipv6_gateway(
ipconfig, connection);
 
+   if (__connman_service_6to4_enabled(service) == TRUE)
+   __connman_6to4_probe(address);
+
if (connman_element_register(connection, element)  0)
connman_element_unref(connection);
 
@@ -148,6 +151,8 @@ static void ipv4_remove(struct connman_element *element)
AF_INET, address, peer, prefixlen, broadcast)  0))
DBG(address removal failed);
 
+   __connman_6to4_remove();
+
connman_element_unref(element);
 }
 
diff --git a/src/service.c b/src/service.c
index 7751dc0..ff9a1af 100644
--- a/src/service.c
+++ b/src/service.c
@@ -108,6 +108,7 @@ struct connman_service {
char **excludes;
char *pac;
connman_bool_t wps;
+   connman_bool_t enabled_6to4;
 };
 
 static void append_path(gpointer value, gpointer user_data)
@@ -1622,6 +1623,9 @@ static void append_properties(DBusMessageIter *dict, 
dbus_bool_t limited,
connman_dbus_dict_append_dict(dict, IPv6.Configuration,
append_ipv6config, service);
 
+   connman_dbus_dict_append_basic(dict, 6to4,
+   DBUS_TYPE_BOOLEAN, service-enabled_6to4);
+
connman_dbus_dict_append_array(dict, Nameservers,
DBUS_TYPE_STRING, append_dns, service);
 
@@ -1817,6 +1821,21 @@ void __connman_service_set_passphrase(struct 
connman_service *service,
__connman_storage_save_service(service);
 }
 
+connman_bool_t __connman_service_6to4_enabled(struct connman_service *service)
+{
+   enum connman_ipconfig_method method;
+
+   if (service == NULL)
+   return FALSE;
+
+   method = __connman_ipconfig_get_method(service-ipconfig_ipv6);
+   if (method == CONNMAN_IPCONFIG_METHOD_UNKNOWN ||
+   method == CONNMAN_IPCONFIG_METHOD_OFF)
+   return FALSE;
+
+   return service-enabled_6to4;
+}
+
 static DBusMessage *get_properties(DBusConnection *conn,
DBusMessage *msg, void *user_data)
 {
@@ -2313,6 +2332,31 @@ static DBusMessage *set_property(DBusConnection *conn,
ipv4, ipv6);
 
__connman_storage_save_service(service);
+   } else if (g_str_equal(name, 6to4) == TRUE) {
+   connman_bool_t six2four;
+
+   if (type != DBUS_TYPE_BOOLEAN)
+   return __connman_error_invalid_arguments(msg);
+
+   dbus_message_iter_get_basic(value, six2four);
+
+   if (service-enabled_6to4 == six2four)
+   return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
+
+   service-enabled_6to4 = six2four;
+   if (service-enabled_6to4 == TRUE) {
+   if (__connman_service_6to4_enabled(service) == TRUE) {
+   struct connman_ipaddress *address;
+   address =
+   __connman_ipconfig_get_system_address(
+   service-ipconfig_ipv4);
+   if (address)
+   __connman_6to4_probe(address-local);
+   }
+   } else
+   __connman_6to4_remove();
+
+   __connman_storage_save_service(service);
} else
return __connman_error_invalid_property(msg);
 
@@ -4821,6 +4865,8 @@ static int service_load(struct connman_service *service)
case CONNMAN_SERVICE_TYPE_UNKNOWN:
case CONNMAN_SERVICE_TYPE_SYSTEM:
case CONNMAN_SERVICE_TYPE_ETHERNET:
+   service-enabled_6to4 = g_key_file_get_boolean(keyfile,
+ 

[PATCH 6to4 v1 2/6] ipconfig: Add function to return the system address pointer.

2011-02-14 Thread Jukka Rissanen
---
 src/connman.h  |2 ++
 src/ipconfig.c |9 +
 2 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/src/connman.h b/src/connman.h
index 6202db3..5014291 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -253,6 +253,8 @@ void __connman_ipconfig_set_element_ipv6_gateway(
 int __connman_ipconfig_set_gateway(struct connman_ipconfig *ipconfig,
struct connman_element *parent);
 int __connman_ipconfig_set_address(struct connman_ipconfig *ipconfig);
+struct connman_ipaddress *__connman_ipconfig_get_system_address(
+   struct connman_ipconfig *ipconfig);
 int __connman_ipconfig_clear_address(struct connman_ipconfig *ipconfig);
 unsigned char __connman_ipconfig_netmask_prefix_len(const char *netmask);
 
diff --git a/src/ipconfig.c b/src/ipconfig.c
index 1fb8281..7396645 100644
--- a/src/ipconfig.c
+++ b/src/ipconfig.c
@@ -1129,6 +1129,15 @@ enum connman_ipconfig_method 
__connman_ipconfig_get_method(struct connman_ipconf
return ipconfig-method;
 }
 
+struct connman_ipaddress *__connman_ipconfig_get_system_address(
+   struct connman_ipconfig *ipconfig)
+{
+   if (ipconfig == NULL)
+   return NULL;
+
+   return ipconfig-system;
+}
+
 /**
  * connman_ipconfig_bind:
  * @ipconfig: ipconfig structure
-- 
1.7.0.4

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH 6to4 v1 0/6] Create 6to4 tunnel automatically if enabled

2011-02-14 Thread Jukka Rissanen
Hi,

the following patches create 6to4 tunnel automatically if enabled for
a given service, IPv6 is enabled and device has public IP address.

Regards,
Jukka


Jukka Rissanen (6):
  doc: Add comment about 6to4 tunnelling.
  ipconfig: Add function to return the system address pointer.
  6to4: Add 6to4 tunnel support.
  service: Create 6to4 tunnel if enabled.
  test: Add support for 6to4 tunnel status printing.
  test: Add support for enabling/disabling 6to4 tunnel.

 Makefile.am |2 +-
 doc/service-api.txt |9 +
 src/6to4.c  |  569 +++
 src/connman.h   |6 +
 src/ipconfig.c  |9 +
 src/ipv4.c  |5 +
 src/service.c   |   56 +
 test/list-services  |2 +-
 test/test-connman   |   28 +++
 9 files changed, 684 insertions(+), 2 deletions(-)
 create mode 100644 src/6to4.c

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH 6to4 v1 1/6] doc: Add comment about 6to4 tunnelling.

2011-02-14 Thread Jukka Rissanen
---
 doc/service-api.txt |9 +
 1 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/doc/service-api.txt b/doc/service-api.txt
index b3e758e..35e03a6 100644
--- a/doc/service-api.txt
+++ b/doc/service-api.txt
@@ -386,6 +386,15 @@ Properties string State [readonly]
until the new configuration has been successfully
installed.
 
+   boolean 6to4 [readwrite]
+
+   If set to true, the service will create 6to4
+   tunnel if the service IPv4 address is not private.
+   Default value is false meaning that 6to4 tunnel is
+   not created. Only one tunnel is created even if
+   there are more than one active service that have
+   public IPv4 address.
+
dict Proxy [readonly]
 
string Method [readonly]
-- 
1.7.0.4

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH v2] ipconfig: Enable IPv6 privacy extension for autoconf addresses.

2011-02-15 Thread Jukka Rissanen
This is described in RFC 3041 and RFC 4941
---
 src/ipconfig.c |   64 
 1 files changed, 64 insertions(+), 0 deletions(-)

diff --git a/src/ipconfig.c b/src/ipconfig.c
index 1fb8281..f6af4c4 100644
--- a/src/ipconfig.c
+++ b/src/ipconfig.c
@@ -79,6 +79,7 @@ struct connman_ipdevice {
struct connman_ipconfig *config_ipv6;
 
gboolean ipv6_enabled;
+   int ipv6_privacy;
 };
 
 static GHashTable *ipdevice_hash = NULL;
@@ -352,6 +353,65 @@ static void set_ipv6_state(gchar *ifname, gboolean enable)
fclose(f);
 }
 
+static int get_ipv6_privacy(gchar *ifname)
+{
+   gchar *path;
+   FILE *f;
+   int value = 0;
+
+   if (ifname == NULL)
+   return value;
+
+   path = g_strdup_printf(/proc/sys/net/ipv6/conf/%s/use_tempaddr,
+   ifname);
+
+   if (path == NULL)
+   return value;
+
+   f = fopen(path, r);
+
+   g_free(path);
+
+   if (f != NULL) {
+   if (fscanf(f, %d, value) = 0)
+   value = 0;
+   fclose(f);
+   }
+
+   return value;
+}
+
+/* Enable the IPv6 privacy extension for stateless address autoconfiguration.
+ * This is described in RFC 3041 and RFC 4941
+ */
+static void set_ipv6_privacy(gchar *ifname, int value)
+{
+   gchar *path;
+   FILE *f;
+
+   if (ifname == NULL)
+   return;
+
+   path = g_strdup_printf(/proc/sys/net/ipv6/conf/%s/use_tempaddr,
+   ifname);
+
+   if (path == NULL)
+   return;
+
+   if (value  0)
+   value = 0;
+
+   f = fopen(path, r+);
+
+   g_free(path);
+
+   if (f == NULL)
+   return;
+
+   fprintf(f, %d, value);
+   fclose(f);
+}
+
 static void free_ipdevice(gpointer data)
 {
struct connman_ipdevice *ipdevice = data;
@@ -377,6 +437,7 @@ static void free_ipdevice(gpointer data)
g_free(ipdevice-address);
 
set_ipv6_state(ipdevice-ifname, ipdevice-ipv6_enabled);
+   set_ipv6_privacy(ipdevice-ifname, ipdevice-ipv6_privacy);
 
g_free(ipdevice-ifname);
g_free(ipdevice);
@@ -474,6 +535,7 @@ void __connman_ipconfig_newlink(int index, unsigned short 
type,
ipdevice-type = type;
 
ipdevice-ipv6_enabled = get_ipv6_state(ipdevice-ifname);
+   ipdevice-ipv6_privacy = get_ipv6_privacy(ipdevice-ifname);
 
ipdevice-address = g_strdup(address);
 
@@ -1610,6 +1672,8 @@ static void enable_ipv6(struct connman_ipconfig *ipconfig)
if (ipdevice == NULL)
return;
 
+   set_ipv6_privacy(ipdevice-ifname, 2);
+
set_ipv6_state(ipdevice-ifname, TRUE);
 }
 
-- 
1.7.0.4

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH] ipconfig: Never return or set system wide IPv6 status value.

2011-02-15 Thread Jukka Rissanen
---
 src/ipconfig.c |   18 +-
 1 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/src/ipconfig.c b/src/ipconfig.c
index 1fb8281..f8ca414 100644
--- a/src/ipconfig.c
+++ b/src/ipconfig.c
@@ -299,13 +299,13 @@ static gboolean get_ipv6_state(gchar *ifname)
int disabled;
gchar *path;
FILE *f;
-   gboolean enabled = FALSE;
+   gboolean enabled = TRUE;
 
if (ifname == NULL)
-   path = g_strdup(/proc/sys/net/ipv6/conf/all/disable_ipv6);
-   else
-   path = g_strdup_printf(
-   /proc/sys/net/ipv6/conf/%s/disable_ipv6, ifname);
+   return enabled;
+
+   path = g_strdup_printf(/proc/sys/net/ipv6/conf/%s/disable_ipv6,
+   ifname);
 
if (path == NULL)
return enabled;
@@ -329,10 +329,10 @@ static void set_ipv6_state(gchar *ifname, gboolean enable)
FILE *f;
 
if (ifname == NULL)
-   path = g_strdup(/proc/sys/net/ipv6/conf/all/disable_ipv6);
-   else
-   path = g_strdup_printf(
-   /proc/sys/net/ipv6/conf/%s/disable_ipv6, ifname);
+   return;
+
+   path = g_strdup_printf(/proc/sys/net/ipv6/conf/%s/disable_ipv6,
+   ifname);
 
if (path == NULL)
return;
-- 
1.7.0.4

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH v3] ipconfig: Enable IPv6 privacy extension for autoconf addresses.

2011-02-15 Thread Jukka Rissanen
This is described in RFC 3041 and RFC 4941
---
 src/ipconfig.c |   66 
 1 files changed, 66 insertions(+), 0 deletions(-)

diff --git a/src/ipconfig.c b/src/ipconfig.c
index 1fb8281..0f676d3 100644
--- a/src/ipconfig.c
+++ b/src/ipconfig.c
@@ -79,6 +79,7 @@ struct connman_ipdevice {
struct connman_ipconfig *config_ipv6;
 
gboolean ipv6_enabled;
+   int ipv6_privacy;
 };
 
 static GHashTable *ipdevice_hash = NULL;
@@ -352,6 +353,67 @@ static void set_ipv6_state(gchar *ifname, gboolean enable)
fclose(f);
 }
 
+static int get_ipv6_privacy(gchar *ifname)
+{
+   gchar *path;
+   FILE *f;
+   int value;
+
+   if (ifname == NULL)
+   return 0;
+
+   path = g_strdup_printf(/proc/sys/net/ipv6/conf/%s/use_tempaddr,
+   ifname);
+
+   if (path == NULL)
+   return 0;
+
+   f = fopen(path, r);
+
+   g_free(path);
+
+   if (f == NULL)
+   return 0;
+
+   if (fscanf(f, %d, value) = 0)
+   value = 0;
+
+   fclose(f);
+
+   return value;
+}
+
+/* Enable the IPv6 privacy extension for stateless address autoconfiguration.
+ * This is described in RFC 3041 and RFC 4941
+ */
+static void set_ipv6_privacy(gchar *ifname, int value)
+{
+   gchar *path;
+   FILE *f;
+
+   if (ifname == NULL)
+   return;
+
+   path = g_strdup_printf(/proc/sys/net/ipv6/conf/%s/use_tempaddr,
+   ifname);
+
+   if (path == NULL)
+   return;
+
+   if (value  0)
+   value = 0;
+
+   f = fopen(path, r+);
+
+   g_free(path);
+
+   if (f == NULL)
+   return;
+
+   fprintf(f, %d, value);
+   fclose(f);
+}
+
 static void free_ipdevice(gpointer data)
 {
struct connman_ipdevice *ipdevice = data;
@@ -377,6 +439,7 @@ static void free_ipdevice(gpointer data)
g_free(ipdevice-address);
 
set_ipv6_state(ipdevice-ifname, ipdevice-ipv6_enabled);
+   set_ipv6_privacy(ipdevice-ifname, ipdevice-ipv6_privacy);
 
g_free(ipdevice-ifname);
g_free(ipdevice);
@@ -474,6 +537,7 @@ void __connman_ipconfig_newlink(int index, unsigned short 
type,
ipdevice-type = type;
 
ipdevice-ipv6_enabled = get_ipv6_state(ipdevice-ifname);
+   ipdevice-ipv6_privacy = get_ipv6_privacy(ipdevice-ifname);
 
ipdevice-address = g_strdup(address);
 
@@ -1610,6 +1674,8 @@ static void enable_ipv6(struct connman_ipconfig *ipconfig)
if (ipdevice == NULL)
return;
 
+   set_ipv6_privacy(ipdevice-ifname, 2);
+
set_ipv6_state(ipdevice-ifname, TRUE);
 }
 
-- 
1.7.0.4

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


Re: [PATCH v3] ipconfig: Enable IPv6 privacy extension for autoconf addresses.

2011-02-15 Thread Jukka Rissanen
Hi David,

 ... but while ConnMan is driving the device we *always* use this horrid
 'privacy' mode when IPv6 is enabled?

What kind of problems there is with the privacy mode?


Regards,
Jukka
___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH] ipconfig: Enable IPv6 properly when loading and if method is AUTO or MANUAL.

2011-02-16 Thread Jukka Rissanen
---
Hi,

This fixes the issue when ipconfig IPv6 method is AUTO and
config is loaded during connman startup, now depending on timing
it is possible that IPv4 address is not loaded at all.
This can happen easily for WLAN connections, ethernet connections
will probably work ok without the patch.

The IPv6 disabling must also not done during the loading so that
if multiple configs are loaded, those ones that have IPv6 method
OFF will not block IPv6 networking from those that have method set
to AUTO.

Regards,
Jukka


 src/ipconfig.c |   17 ++---
 1 files changed, 2 insertions(+), 15 deletions(-)

diff --git a/src/ipconfig.c b/src/ipconfig.c
index 14edb3d..28f77a6 100644
--- a/src/ipconfig.c
+++ b/src/ipconfig.c
@@ -1856,23 +1856,10 @@ int __connman_ipconfig_load(struct connman_ipconfig 
*ipconfig,
ipconfig-method = CONNMAN_IPCONFIG_METHOD_OFF;
 
if (ipconfig-type == CONNMAN_IPCONFIG_TYPE_IPV6) {
-   if (ipconfig-method == CONNMAN_IPCONFIG_METHOD_OFF)
-   disable_ipv6(ipconfig);
-   else if (ipconfig-method == CONNMAN_IPCONFIG_METHOD_AUTO ||
+   if (ipconfig-method == CONNMAN_IPCONFIG_METHOD_AUTO ||
ipconfig-method == CONNMAN_IPCONFIG_METHOD_MANUAL) {
-   enable_ipv6(ipconfig);
__connman_ipconfig_enable(ipconfig);
-
-   if (ipconfig-ops_data) {
-   struct connman_service *service =
-   ipconfig-ops_data;
-   struct connman_network *network;
-   network = __connman_service_get_network(
-   service);
-   if (network)
-   __connman_network_set_ipconfig(network,
-   NULL, ipconfig);
-   }
+   enable_ipv6(ipconfig);
}
}
 
-- 
1.7.0.4

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH v2] ipconfig: Toggle interface IPv6 status if IPv6 ipconfig is enabled or disabled.

2011-02-17 Thread Jukka Rissanen
This is done so that if service is disconnected, the kernel
created autoconf routes need to be cleared also.
That can be done easiest by disabling IPv6 for that interface.
The disabling of IPv6 is only done for autoconfigured interfaces.
When service is connected, the IPv6 is enabled for the used
interface.
---

Hi,

this is the second version of the patch. No code changes, just fixed
the changelog to describe the problem properly.

Regards,
Jukka


 src/ipconfig.c |   61 ++-
 1 files changed, 33 insertions(+), 28 deletions(-)

diff --git a/src/ipconfig.c b/src/ipconfig.c
index 14edb3d..62d3766 100644
--- a/src/ipconfig.c
+++ b/src/ipconfig.c
@@ -1351,6 +1351,34 @@ const char 
*__connman_ipconfig_get_proxy_autoconfig(struct connman_ipconfig *ipc
return ipdevice-pac;
 }
 
+static void disable_ipv6(struct connman_ipconfig *ipconfig)
+{
+   struct connman_ipdevice *ipdevice;
+
+   DBG();
+
+   ipdevice = g_hash_table_lookup(ipdevice_hash,
+   GINT_TO_POINTER(ipconfig-index));
+   if (ipdevice == NULL)
+   return;
+
+   set_ipv6_state(ipdevice-ifname, FALSE);
+}
+
+static void enable_ipv6(struct connman_ipconfig *ipconfig)
+{
+   struct connman_ipdevice *ipdevice;
+
+   DBG();
+
+   ipdevice = g_hash_table_lookup(ipdevice_hash,
+   GINT_TO_POINTER(ipconfig-index));
+   if (ipdevice == NULL)
+   return;
+
+   set_ipv6_state(ipdevice-ifname, TRUE);
+}
+
 int __connman_ipconfig_enable(struct connman_ipconfig *ipconfig)
 {
struct connman_ipdevice *ipdevice;
@@ -1376,6 +1404,7 @@ int __connman_ipconfig_enable(struct connman_ipconfig 
*ipconfig)
if (ipdevice-config_ipv6 == ipconfig)
return -EALREADY;
type = CONNMAN_IPCONFIG_TYPE_IPV6;
+   enable_ipv6(ipconfig);
} else
return -EINVAL;
 
@@ -1459,6 +1488,10 @@ int __connman_ipconfig_disable(struct connman_ipconfig 
*ipconfig)
if (ipdevice-config_ipv6 == ipconfig) {
ipconfig_list = g_list_remove(ipconfig_list, ipconfig);
 
+   if (ipdevice-config_ipv6-method ==
+   CONNMAN_IPCONFIG_METHOD_AUTO)
+   disable_ipv6(ipdevice-config_ipv6);
+
connman_ipaddress_clear(ipdevice-config_ipv6-system);
connman_ipconfig_unref(ipdevice-config_ipv6);
ipdevice-config_ipv6 = NULL;
@@ -1662,34 +1695,6 @@ void __connman_ipconfig_append_ipv4config(struct 
connman_ipconfig *ipconfig,
DBUS_TYPE_STRING, ipconfig-address-gateway);
 }
 
-static void disable_ipv6(struct connman_ipconfig *ipconfig)
-{
-   struct connman_ipdevice *ipdevice;
-
-   DBG();
-
-   ipdevice = g_hash_table_lookup(ipdevice_hash,
-   GINT_TO_POINTER(ipconfig-index));
-   if (ipdevice == NULL)
-   return;
-
-   set_ipv6_state(ipdevice-ifname, FALSE);
-}
-
-static void enable_ipv6(struct connman_ipconfig *ipconfig)
-{
-   struct connman_ipdevice *ipdevice;
-
-   DBG();
-
-   ipdevice = g_hash_table_lookup(ipdevice_hash,
-   GINT_TO_POINTER(ipconfig-index));
-   if (ipdevice == NULL)
-   return;
-
-   set_ipv6_state(ipdevice-ifname, TRUE);
-}
-
 int __connman_ipconfig_set_config(struct connman_ipconfig *ipconfig,
DBusMessageIter *array)
 {
-- 
1.7.0.4

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH privacy v2 0/3] Enable/disable IPv6 privacy extension

2011-02-17 Thread Jukka Rissanen
Hi,

this is the v2 of the IPv6 privacy patch. This version makes the
privacy setting configurable.

The privacy setting can be changed in service API via IPv6.Configuration
property. I used the same values for privacy setting as described in the
kernel documentation Documentation/networking/ip-sysctl.txt file so that
the mapping between those two is simple.
By default the privacy setting is 1, meaning it is enabled but public
addresses are prefered over temporary ones.
The privacy value is only written to kernel if IPv6 method is AUTO.

Note that the kernel might not activate the privacy mode immediately,
it seems to require that interface goes down before activation.
Same thing happens if privacy mode is disabled, the temporary addresses
do not disappear until the interface is taken down. At least this
was happening in my test system with kernel 2.6.32.

Regards,
Jukka


Jukka Rissanen (3):
  doc: Add description about IPv6 privacy setting.
  ipconfig: Enable IPv6 privacy extension for autoconf addresses.
  test: Enable or disable IPv6 privacy extension.

 doc/service-api.txt  |   18 
 src/ipconfig.c   |  113 --
 test/set-ipv6-method |   18 +---
 3 files changed, 138 insertions(+), 11 deletions(-)

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH privacy v2 2/3] ipconfig: Enable IPv6 privacy extension for autoconf addresses.

2011-02-17 Thread Jukka Rissanen
---
 src/ipconfig.c |  113 ++--
 1 files changed, 109 insertions(+), 4 deletions(-)

diff --git a/src/ipconfig.c b/src/ipconfig.c
index 1fb8281..481133b 100644
--- a/src/ipconfig.c
+++ b/src/ipconfig.c
@@ -51,6 +51,8 @@ struct connman_ipconfig {
enum connman_ipconfig_method method;
struct connman_ipaddress *address;
struct connman_ipaddress *system;
+
+   int ipv6_privacy;
 };
 
 struct connman_ipdevice {
@@ -79,6 +81,7 @@ struct connman_ipdevice {
struct connman_ipconfig *config_ipv6;
 
gboolean ipv6_enabled;
+   int ipv6_privacy;
 };
 
 static GHashTable *ipdevice_hash = NULL;
@@ -352,6 +355,67 @@ static void set_ipv6_state(gchar *ifname, gboolean enable)
fclose(f);
 }
 
+static int get_ipv6_privacy(gchar *ifname)
+{
+   gchar *path;
+   FILE *f;
+   int value;
+
+   if (ifname == NULL)
+   return 0;
+
+   path = g_strdup_printf(/proc/sys/net/ipv6/conf/%s/use_tempaddr,
+   ifname);
+
+   if (path == NULL)
+   return 0;
+
+   f = fopen(path, r);
+
+   g_free(path);
+
+   if (f == NULL)
+   return 0;
+
+   if (fscanf(f, %d, value) = 0)
+   value = 0;
+
+   fclose(f);
+
+   return value;
+}
+
+/* Enable the IPv6 privacy extension for stateless address autoconfiguration.
+ * The privacy extension is described in RFC 3041 and RFC 4941
+ */
+static void set_ipv6_privacy(gchar *ifname, int value)
+{
+   gchar *path;
+   FILE *f;
+
+   if (ifname == NULL)
+   return;
+
+   path = g_strdup_printf(/proc/sys/net/ipv6/conf/%s/use_tempaddr,
+   ifname);
+
+   if (path == NULL)
+   return;
+
+   if (value  0)
+   value = 0;
+
+   f = fopen(path, r+);
+
+   g_free(path);
+
+   if (f == NULL)
+   return;
+
+   fprintf(f, %d, value);
+   fclose(f);
+}
+
 static void free_ipdevice(gpointer data)
 {
struct connman_ipdevice *ipdevice = data;
@@ -377,6 +441,7 @@ static void free_ipdevice(gpointer data)
g_free(ipdevice-address);
 
set_ipv6_state(ipdevice-ifname, ipdevice-ipv6_enabled);
+   set_ipv6_privacy(ipdevice-ifname, ipdevice-ipv6_privacy);
 
g_free(ipdevice-ifname);
g_free(ipdevice);
@@ -474,6 +539,7 @@ void __connman_ipconfig_newlink(int index, unsigned short 
type,
ipdevice-type = type;
 
ipdevice-ipv6_enabled = get_ipv6_state(ipdevice-ifname);
+   ipdevice-ipv6_privacy = get_ipv6_privacy(ipdevice-ifname);
 
ipdevice-address = g_strdup(address);
 
@@ -926,6 +992,7 @@ static struct connman_ipconfig *create_ipv6config(int index)
ipv6config-index = index;
ipv6config-type = CONNMAN_IPCONFIG_TYPE_IPV6;
ipv6config-method = CONNMAN_IPCONFIG_METHOD_AUTO;
+   ipv6config-ipv6_privacy = 1;
 
ipv6config-address = connman_ipaddress_alloc(AF_INET6);
if (ipv6config-address == NULL) {
@@ -1496,6 +1563,9 @@ void __connman_ipconfig_append_ipv6(struct 
connman_ipconfig *ipconfig,
if (ipconfig-system-gateway != NULL)
connman_dbus_dict_append_basic(iter, Gateway,
DBUS_TYPE_STRING, ipconfig-system-gateway);
+
+   connman_dbus_dict_append_basic(iter, Privacy,
+   DBUS_TYPE_INT32, ipconfig-ipv6_privacy);
 }
 
 void __connman_ipconfig_append_ipv6config(struct connman_ipconfig *ipconfig,
@@ -1536,6 +1606,9 @@ void __connman_ipconfig_append_ipv6config(struct 
connman_ipconfig *ipconfig,
if (ipconfig-address-gateway != NULL)
connman_dbus_dict_append_basic(iter, Gateway,
DBUS_TYPE_STRING, ipconfig-address-gateway);
+
+   connman_dbus_dict_append_basic(iter, Privacy,
+   DBUS_TYPE_INT32, ipconfig-ipv6_privacy);
 }
 
 void __connman_ipconfig_append_ipv4config(struct connman_ipconfig *ipconfig,
@@ -1610,6 +1683,9 @@ static void enable_ipv6(struct connman_ipconfig *ipconfig)
if (ipdevice == NULL)
return;
 
+   if (ipconfig-method == CONNMAN_IPCONFIG_METHOD_AUTO)
+   set_ipv6_privacy(ipdevice-ifname, ipconfig-ipv6_privacy);
+
set_ipv6_state(ipdevice-ifname, TRUE);
 }
 
@@ -1618,8 +1694,8 @@ int __connman_ipconfig_set_config(struct connman_ipconfig 
*ipconfig,
 {
enum connman_ipconfig_method method = CONNMAN_IPCONFIG_METHOD_UNKNOWN;
const char *address = NULL, *netmask = NULL, *gateway = NULL,
-   *prefix_length_string = NULL;
-   int prefix_length = 0;
+   *prefix_length_string = NULL, *privacy_string = NULL;
+   int prefix_length = 0, privacy = 1;
DBusMessageIter dict;
 
DBG(ipconfig %p, ipconfig);
@@ -1678,12 +1754,24 @@ int 

[PATCH privacy v2 3/3] test: Enable or disable IPv6 privacy extension.

2011-02-17 Thread Jukka Rissanen
---
 test/set-ipv6-method |   18 +++---
 1 files changed, 11 insertions(+), 7 deletions(-)

diff --git a/test/set-ipv6-method b/test/set-ipv6-method
index 274e89b..c0b251e 100755
--- a/test/set-ipv6-method
+++ b/test/set-ipv6-method
@@ -4,7 +4,7 @@ import sys
 import dbus
 
 def print_usage():
-   print Usage: %s service off|manual|auto [address [prefixlen] 
[gateway]] % (sys.argv[0])
+   print Usage: %s service off|manual|auto [address [prefixlen] 
[gateway]] [privacy] % (sys.argv[0])
 
 if (len(sys.argv)  3):
print_usage()
@@ -20,12 +20,16 @@ properties = service.GetProperties()
 print Setting method %s for %s % (sys.argv[2], sys.argv[1])
 
 ipv6_configuration = { Method: sys.argv[2] }
-if (len(sys.argv)  3):
-   ipv6_configuration[Address] = sys.argv[3]
-if (len(sys.argv)  4):
-   ipv6_configuration[PrefixLength] = sys.argv[4]
-if (len(sys.argv)  5):
-   ipv6_configuration[Gateway] = sys.argv[5]
+if sys.argv[2] == auto:
+   if (len(sys.argv)  3):
+   ipv6_configuration[Privacy] = sys.argv[3]
+else:
+   if (len(sys.argv)  3):
+   ipv6_configuration[Address] = sys.argv[3]
+   if (len(sys.argv)  4):
+   ipv6_configuration[PrefixLength] = sys.argv[4]
+   if (len(sys.argv)  5):
+   ipv6_configuration[Gateway] = sys.argv[5]
 
 service.SetProperty(IPv6.Configuration, ipv6_configuration)
 print New IPv6.Configuration: , ipv6_configuration
-- 
1.7.0.4

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH privacy v2 1/3] doc: Add description about IPv6 privacy setting.

2011-02-17 Thread Jukka Rissanen
---
 doc/service-api.txt |   18 ++
 1 files changed, 18 insertions(+), 0 deletions(-)

diff --git a/doc/service-api.txt b/doc/service-api.txt
index b3e758e..55c5b6e 100644
--- a/doc/service-api.txt
+++ b/doc/service-api.txt
@@ -375,6 +375,24 @@ Properties string State [readonly]
 
The current configured IPv6 gateway.
 
+   int32 Privacy [readonly]
+
+   Enable or disable IPv6 privacy extension
+   that is described in RFC 4941. The value
+   has only meaning if Method is set to auto.
+
+   Value = 0 means that privacy extension is
+   disabled and normal autoconf addresses are
+   used.
+   Value 1 means that privacy extension is
+   enabled and system prefers to use public
+   addresses over temporary addresses.
+   Value = 2 means that privacy extension is
+   enabled and system prefers temporary addresses
+   over public addresses.
+
+   Default value is 1.
+
dict IPv6.Configuration [readwrite]
 
Same values as IPv6 property. The IPv6 represents
-- 
1.7.0.4

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


Re: Memory Leaks When Using Statistics (was Re: [PATCH 1/1]: Fix Memory-map and Double-free Errors in Statistics Handling (was Re: Connman-0.67 Crashes and/or Hangs on Start-up))

2011-02-17 Thread Jukka Rissanen
Hi Grant,

On 17 February 2011 20:10, Grant Erickson maratho...@gmail.com wrote:
 To isolate the leaks, I systematically eliminated processes from the system
 until I was left with:

    - syslogd
    - klogd
    - wpa_supplicant
    - dbus-daemon
    - connmand


I have run connmand under valgrind and it reports memory leaks in
gsupplicant code. I sent earlier some memoryleak patches in various
parts of connman but unfortunately I have lately had no time to find
out where the latest supplicant leaks are.

Regards,
Jukka
___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH 6to4 v2 0/7] Create 6to4 tunnel automatically if enabled

2011-02-18 Thread Jukka Rissanen
Hi,

the v2 patch checks if the tunnel has internet connectivity.
Only change to v1 is the patch #7 which adds the connectivity check.
The check is done by trying to connect to ipv6.google.com:80 via the
tunnel. The google host was choosen as it only provides connectivity
via IPv6. This could be changed to connman.net when it provides the
same kind of service.
The IPv6 address of the host is resolved by async DNS so that mainloop
is not blocked.
The timeouts I used were 10 sec for DNS query and 2 sec for connection
test but these can be tweaked of course.

Any comments or suggestions?

Regards,
Jukka


Jukka Rissanen (7):
  doc: Add comment about 6to4 tunnelling.
  ipconfig: Add function to return the system address pointer.
  6to4: Add 6to4 tunnel support.
  service: Create 6to4 tunnel if enabled.
  test: Add support for 6to4 tunnel status printing.
  test: Add support for enabling/disabling 6to4 tunnel.
  6to4: Check the connectivity via tunnel after creating it.

 Makefile.am |   10 +-
 configure.ac|4 +
 doc/service-api.txt |9 +
 src/6to4.c  |  789 +++
 src/connman.h   |6 +
 src/ipconfig.c  |9 +
 src/ipv4.c  |5 +
 src/service.c   |   56 
 test/list-services  |2 +-
 test/test-connman   |   28 ++
 10 files changed, 912 insertions(+), 6 deletions(-)
 create mode 100644 src/6to4.c

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH 6to4 v2 1/7] doc: Add comment about 6to4 tunnelling.

2011-02-18 Thread Jukka Rissanen
---
 doc/service-api.txt |9 +
 1 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/doc/service-api.txt b/doc/service-api.txt
index 9695059..c662aaf 100644
--- a/doc/service-api.txt
+++ b/doc/service-api.txt
@@ -377,6 +377,15 @@ Properties string State [readonly]
until the new configuration has been successfully
installed.
 
+   boolean 6to4 [readwrite]
+
+   If set to true, the service will create 6to4
+   tunnel if the service IPv4 address is not private.
+   Default value is false meaning that 6to4 tunnel is
+   not created. Only one tunnel is created even if
+   there are more than one active service that have
+   public IPv4 address.
+
dict Proxy [readonly]
 
string Method [readonly]
-- 
1.7.0.4

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH 6to4 v2 3/7] 6to4: Add 6to4 tunnel support.

2011-02-18 Thread Jukka Rissanen
---
 Makefile.am   |2 +-
 src/6to4.c|  569 +
 src/connman.h |3 +
 3 files changed, 573 insertions(+), 1 deletions(-)
 create mode 100644 src/6to4.c

diff --git a/Makefile.am b/Makefile.am
index 144fcc5..8f13f56 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -77,7 +77,7 @@ src_connmand_SOURCES = $(gdbus_sources) $(gdhcp_sources) \
src/wifi.c src/storage.c src/dbus.c src/config.c \
src/technology.c src/counter.c src/location.c \
src/session.c src/tethering.c src/wpad.c src/wispr.c \
-   src/stats.c src/iptables.c src/dnsproxy.c
+   src/stats.c src/iptables.c src/dnsproxy.c src/6to4.c
 
 src_connmand_LDADD = $(builtin_libadd) @GLIB_LIBS@ @DBUS_LIBS@ \
@CAPNG_LIBS@ @XTABLES_LIBS@ -lresolv -ldl
diff --git a/src/6to4.c b/src/6to4.c
new file mode 100644
index 000..b07eeed
--- /dev/null
+++ b/src/6to4.c
@@ -0,0 +1,569 @@
+/*
+ *
+ *  Connection Manager
+ *
+ *  Copyright (C) 2011  Nokia 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 string.h
+#include sys/socket.h
+#include netinet/in.h
+#include arpa/inet.h
+#include net/if.h
+#include linux/ip.h
+#include linux/if_tunnel.h
+#include linux/netlink.h
+#include linux/rtnetlink.h
+#include sys/ioctl.h
+#include unistd.h
+
+#include connman.h
+#include connman/log.h
+
+static int tunnel_created;
+
+#define NLMSG_TAIL(nmsg) \
+   ((struct rtattr *) (((void *)(nmsg)) + NLMSG_ALIGN((nmsg)-nlmsg_len)))
+
+#ifndef IP_DF
+#define IP_DF  0x4000  /* Flag: Don't Fragment   */
+#endif
+
+struct rtnl_handle {
+   int fd;
+   struct sockaddr_nl  local;
+   struct sockaddr_nl  peer;
+   __u32   seq;
+   __u32   dump;
+};
+
+/* Note that addattr32(), addattr_l(), rtnl_close(), rtnl_open() and
+ * rtnl_talk() are from libnetlink.c that is found in iproute2 package
+ * and copyright by Alexey Kuznetsov et al.
+ */
+static int addattr32(struct nlmsghdr *n, int maxlen, int type, __u32 data)
+{
+   int len = RTA_LENGTH(4);
+   struct rtattr *rta;
+   if (NLMSG_ALIGN(n-nlmsg_len) + len  (unsigned int)maxlen) {
+   DBG(Error! max allowed bound %d exceeded, maxlen);
+   return -1;
+   }
+   rta = NLMSG_TAIL(n);
+   rta-rta_type = type;
+   rta-rta_len = len;
+   memcpy(RTA_DATA(rta), data, 4);
+   n-nlmsg_len = NLMSG_ALIGN(n-nlmsg_len) + len;
+
+   return 0;
+}
+
+static int addattr_l(struct nlmsghdr *n, int maxlen, int type,
+   const void *data, int alen)
+{
+   int len = RTA_LENGTH(alen);
+   struct rtattr *rta;
+
+   if (NLMSG_ALIGN(n-nlmsg_len) + RTA_ALIGN(len) 
+   (unsigned int)maxlen) {
+   DBG(addattr_l message exceeded bound of %d, maxlen);
+   return -1;
+   }
+   rta = NLMSG_TAIL(n);
+   rta-rta_type = type;
+   rta-rta_len = len;
+   memcpy(RTA_DATA(rta), data, alen);
+   n-nlmsg_len = NLMSG_ALIGN(n-nlmsg_len) + RTA_ALIGN(len);
+
+   return 0;
+}
+
+static void rtnl_close(struct rtnl_handle *rth)
+{
+   if (rth-fd = 0) {
+   close(rth-fd);
+   rth-fd = -1;
+   }
+}
+
+static int rtnl_open(struct rtnl_handle *rth)
+{
+   socklen_t addr_len;
+   int sndbuf = 32768;
+   int rcvbuf = 32768;
+
+   memset(rth, 0, sizeof(*rth));
+
+   rth-fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+   if (rth-fd  0) {
+   DBG(Cannot open netlink socket: %s, strerror(errno));
+   return -1;
+   }
+
+   if (setsockopt(rth-fd, SOL_SOCKET, SO_SNDBUF, sndbuf,
+   sizeof(sndbuf))  0) {
+   DBG(SO_SNDBUF: %s, strerror(errno));
+   return -1;
+   }
+
+   if (setsockopt(rth-fd, SOL_SOCKET, SO_RCVBUF, rcvbuf,
+   sizeof(rcvbuf))  0) {
+   DBG(SO_RCVBUF: %s, strerror(errno));
+   return -1;
+   }
+
+   memset(rth-local, 0, sizeof(rth-local));
+   rth-local.nl_family = AF_NETLINK;

[PATCH 6to4 v2 4/7] service: Create 6to4 tunnel if enabled.

2011-02-18 Thread Jukka Rissanen
---
 src/connman.h |1 +
 src/ipv4.c|5 +
 src/service.c |   56 
 3 files changed, 62 insertions(+), 0 deletions(-)

diff --git a/src/connman.h b/src/connman.h
index a8ef170..0d90b6b 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -481,6 +481,7 @@ struct connman_ipconfig *__connman_service_get_ip4config(
struct connman_service *service);
 struct connman_ipconfig *__connman_service_get_ip6config(
struct connman_service *service);
+connman_bool_t __connman_service_6to4_enabled(struct connman_service *service);
 const char *__connman_service_get_ident(struct connman_service *service);
 const char *__connman_service_get_path(struct connman_service *service);
 unsigned int __connman_service_get_order(struct connman_service *service);
diff --git a/src/ipv4.c b/src/ipv4.c
index e77b8ee..1ab0338 100644
--- a/src/ipv4.c
+++ b/src/ipv4.c
@@ -103,6 +103,9 @@ static int ipv4_probe(struct connman_element *element)
if (err  0)
return err;
 
+   if (__connman_service_6to4_enabled(service) == TRUE)
+   __connman_6to4_probe(address);
+
return 0;
 }
 
@@ -152,6 +155,8 @@ static void ipv4_remove(struct connman_element *element)
AF_INET, address, peer, prefixlen, broadcast)  0))
DBG(address removal failed);
 
+   __connman_6to4_remove();
+
connman_element_unref(element);
 }
 
diff --git a/src/service.c b/src/service.c
index 9a0d499..7293354 100644
--- a/src/service.c
+++ b/src/service.c
@@ -103,6 +103,7 @@ struct connman_service {
char **excludes;
char *pac;
connman_bool_t wps;
+   connman_bool_t enabled_6to4;
 };
 
 static void append_path(gpointer value, gpointer user_data)
@@ -1649,6 +1650,9 @@ static void append_properties(DBusMessageIter *dict, 
dbus_bool_t limited,
connman_dbus_dict_append_dict(dict, IPv6.Configuration,
append_ipv6config, service);
 
+   connman_dbus_dict_append_basic(dict, 6to4,
+   DBUS_TYPE_BOOLEAN, service-enabled_6to4);
+
connman_dbus_dict_append_array(dict, Nameservers,
DBUS_TYPE_STRING, append_dns, service);
 
@@ -1851,6 +1855,21 @@ void __connman_service_set_passphrase(struct 
connman_service *service,
__connman_storage_save_service(service);
 }
 
+connman_bool_t __connman_service_6to4_enabled(struct connman_service *service)
+{
+   enum connman_ipconfig_method method;
+
+   if (service == NULL)
+   return FALSE;
+
+   method = __connman_ipconfig_get_method(service-ipconfig_ipv6);
+   if (method == CONNMAN_IPCONFIG_METHOD_UNKNOWN ||
+   method == CONNMAN_IPCONFIG_METHOD_OFF)
+   return FALSE;
+
+   return service-enabled_6to4;
+}
+
 static DBusMessage *get_properties(DBusConnection *conn,
DBusMessage *msg, void *user_data)
 {
@@ -2281,6 +2300,31 @@ static DBusMessage *set_property(DBusConnection *conn,
ipv4, ipv6);
 
__connman_storage_save_service(service);
+   } else if (g_str_equal(name, 6to4) == TRUE) {
+   connman_bool_t six2four;
+
+   if (type != DBUS_TYPE_BOOLEAN)
+   return __connman_error_invalid_arguments(msg);
+
+   dbus_message_iter_get_basic(value, six2four);
+
+   if (service-enabled_6to4 == six2four)
+   return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
+
+   service-enabled_6to4 = six2four;
+   if (service-enabled_6to4 == TRUE) {
+   if (__connman_service_6to4_enabled(service) == TRUE) {
+   struct connman_ipaddress *address;
+   address =
+   __connman_ipconfig_get_system_address(
+   service-ipconfig_ipv4);
+   if (address)
+   __connman_6to4_probe(address-local);
+   }
+   } else
+   __connman_6to4_remove();
+
+   __connman_storage_save_service(service);
} else
return __connman_error_invalid_property(msg);
 
@@ -4756,6 +4800,8 @@ static int service_load(struct connman_service *service)
case CONNMAN_SERVICE_TYPE_UNKNOWN:
case CONNMAN_SERVICE_TYPE_SYSTEM:
case CONNMAN_SERVICE_TYPE_ETHERNET:
+   service-enabled_6to4 = g_key_file_get_boolean(keyfile,
+   service-identifier, 6to4, NULL);
case CONNMAN_SERVICE_TYPE_GPS:
case CONNMAN_SERVICE_TYPE_VPN:
case CONNMAN_SERVICE_TYPE_GADGET:
@@ -4830,6 

[PATCH 6to4 v2 5/7] test: Add support for 6to4 tunnel status printing.

2011-02-18 Thread Jukka Rissanen
---
 test/list-services |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/test/list-services b/test/list-services
index 3ae6a4d..20295b1 100755
--- a/test/list-services
+++ b/test/list-services
@@ -50,7 +50,7 @@ for path in properties[Services]:
val = extract_list(properties[key])
elif key in [Favorite, Immutable, AutoConnect,
LoginRequired, SetupRequired,
-   PassphraseRequired]:
+   PassphraseRequired, 6to4]:
if properties[key] == dbus.Boolean(1):
val = true
else:
-- 
1.7.0.4

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH v2] ipconfig: Enable IPv6 properly when loading config and disable IPv6 properly when connecting service.

2011-02-18 Thread Jukka Rissanen
---
Hi,

this sets the IPv6 status correctly by
- enabling IPv6 when service config is loaded and method is AUTO or MANUAL
- and disabling IPv6 when service is connected and method is OFF

Regards,
Jukka


 include/ipconfig.h |1 +
 src/ipconfig.c |   25 ++---
 src/service.c  |7 +++
 3 files changed, 18 insertions(+), 15 deletions(-)

diff --git a/include/ipconfig.h b/include/ipconfig.h
index 9bc97d5..7d62330 100644
--- a/include/ipconfig.h
+++ b/include/ipconfig.h
@@ -95,6 +95,7 @@ int connman_ipconfig_set_method(struct connman_ipconfig 
*ipconfig,
enum connman_ipconfig_method method);
 void connman_ipconfig_bind(struct connman_ipconfig *ipconfig,
struct connman_ipaddress *ipaddress);
+void __connman_ipconfig_disable_ipv6(struct connman_ipconfig *ipconfig);
 
 #ifdef __cplusplus
 }
diff --git a/src/ipconfig.c b/src/ipconfig.c
index 62d3766..6511370 100644
--- a/src/ipconfig.c
+++ b/src/ipconfig.c
@@ -1379,6 +1379,14 @@ static void enable_ipv6(struct connman_ipconfig 
*ipconfig)
set_ipv6_state(ipdevice-ifname, TRUE);
 }
 
+void __connman_ipconfig_disable_ipv6(struct connman_ipconfig *ipconfig)
+{
+   if (ipconfig == NULL || ipconfig-type != CONNMAN_IPCONFIG_TYPE_IPV6)
+   return;
+
+   disable_ipv6(ipconfig);
+}
+
 int __connman_ipconfig_enable(struct connman_ipconfig *ipconfig)
 {
struct connman_ipdevice *ipdevice;
@@ -1861,23 +1869,10 @@ int __connman_ipconfig_load(struct connman_ipconfig 
*ipconfig,
ipconfig-method = CONNMAN_IPCONFIG_METHOD_OFF;
 
if (ipconfig-type == CONNMAN_IPCONFIG_TYPE_IPV6) {
-   if (ipconfig-method == CONNMAN_IPCONFIG_METHOD_OFF)
-   disable_ipv6(ipconfig);
-   else if (ipconfig-method == CONNMAN_IPCONFIG_METHOD_AUTO ||
+   if (ipconfig-method == CONNMAN_IPCONFIG_METHOD_AUTO ||
ipconfig-method == CONNMAN_IPCONFIG_METHOD_MANUAL) {
-   enable_ipv6(ipconfig);
__connman_ipconfig_enable(ipconfig);
-
-   if (ipconfig-ops_data) {
-   struct connman_service *service =
-   ipconfig-ops_data;
-   struct connman_network *network;
-   network = __connman_service_get_network(
-   service);
-   if (network)
-   __connman_network_set_ipconfig(network,
-   NULL, ipconfig);
-   }
+   enable_ipv6(ipconfig);
}
}
 
diff --git a/src/service.c b/src/service.c
index 9a0d499..1696e5a 100644
--- a/src/service.c
+++ b/src/service.c
@@ -3319,6 +3319,7 @@ int __connman_service_indicate_state(struct 
connman_service *service,
 
if (state == CONNMAN_SERVICE_STATE_READY) {
enum connman_service_proxy_method proxy_config;
+   enum connman_ipconfig_method method;
 
set_reconnect_state(service, TRUE);
 
@@ -3371,6 +3372,12 @@ int __connman_service_indicate_state(struct 
connman_service *service,
}
 
default_changed();
+
+   method = __connman_ipconfig_get_method(service-ipconfig_ipv6);
+   if (method == CONNMAN_IPCONFIG_METHOD_OFF)
+   __connman_ipconfig_disable_ipv6(
+   service-ipconfig_ipv6);
+
} else if (state == CONNMAN_SERVICE_STATE_DISCONNECT) {
__connman_location_finish(service);
 
-- 
1.7.0.4

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH ipv6routes v1 1/2] rtnl: Catch IPv6 route netlink messages.

2011-02-18 Thread Jukka Rissanen
---
 src/rtnl.c |  122 +++
 1 files changed, 97 insertions(+), 25 deletions(-)

diff --git a/src/rtnl.c b/src/rtnl.c
index 5b09ca4..42b1632 100644
--- a/src/rtnl.c
+++ b/src/rtnl.c
@@ -633,7 +633,7 @@ static void process_deladdr(unsigned char family, unsigned 
char prefixlen,
prefixlen, ip_string);
 }
 
-static void extract_route(struct rtmsg *msg, int bytes, int *index,
+static void extract_ipv4_route(struct rtmsg *msg, int bytes, int *index,
struct in_addr *dst,
struct in_addr *gateway)
 {
@@ -658,30 +658,79 @@ static void extract_route(struct rtmsg *msg, int bytes, 
int *index,
}
 }
 
+static void extract_ipv6_route(struct rtmsg *msg, int bytes, int *index,
+   struct in6_addr *dst,
+   struct in6_addr *gateway)
+{
+   struct rtattr *attr;
+
+   for (attr = RTM_RTA(msg); RTA_OK(attr, bytes);
+   attr = RTA_NEXT(attr, bytes)) {
+   switch (attr-rta_type) {
+   case RTA_DST:
+   if (dst != NULL)
+   *dst = *((struct in6_addr *) RTA_DATA(attr));
+   break;
+   case RTA_GATEWAY:
+   if (gateway != NULL)
+   *gateway =
+   *((struct in6_addr *) RTA_DATA(attr));
+   break;
+   case RTA_OIF:
+   if (index != NULL)
+   *index = *((int *) RTA_DATA(attr));
+   break;
+   }
+   }
+}
+
 static void process_newroute(unsigned char family, unsigned char scope,
struct rtmsg *msg, int bytes)
 {
GSList *list;
-   struct in_addr dst = { INADDR_ANY }, gateway = { INADDR_ANY };
-   char dststr[16], gatewaystr[16];
+   char dststr[INET6_ADDRSTRLEN], gatewaystr[INET6_ADDRSTRLEN];
int index = -1;
 
-   if (family != AF_INET)
-   return;
+   if (family == AF_INET) {
+   struct in_addr dst = { INADDR_ANY }, gateway = { INADDR_ANY };
 
-   extract_route(msg, bytes, index, dst, gateway);
+   extract_ipv4_route(msg, bytes, index, dst, gateway);
 
-   inet_ntop(family, dst, dststr, sizeof(dststr));
-   inet_ntop(family, gateway, gatewaystr, sizeof(gatewaystr));
+   inet_ntop(family, dst, dststr, sizeof(dststr));
+   inet_ntop(family, gateway, gatewaystr, sizeof(gatewaystr));
 
-   __connman_ipconfig_newroute(index, family, scope, dststr, gatewaystr);
+   __connman_ipconfig_newroute(index, family, scope, dststr,
+   gatewaystr);
 
-   /* skip host specific routes */
-   if (scope != RT_SCOPE_UNIVERSE 
+   /* skip host specific routes */
+   if (scope != RT_SCOPE_UNIVERSE 
!(scope == RT_SCOPE_LINK  dst.s_addr == INADDR_ANY))
-   return;
+   return;
 
-   if (dst.s_addr != INADDR_ANY)
+   if (dst.s_addr != INADDR_ANY)
+   return;
+
+   } else if (family == AF_INET6) {
+   struct in6_addr dst = IN6ADDR_ANY_INIT,
+   gateway = IN6ADDR_ANY_INIT;
+
+   extract_ipv6_route(msg, bytes, index, dst, gateway);
+
+   inet_ntop(family, dst, dststr, sizeof(dststr));
+   inet_ntop(family, gateway, gatewaystr, sizeof(gatewaystr));
+
+   __connman_ipconfig_newroute(index, family, scope, dststr,
+   gatewaystr);
+
+   /* skip host specific routes */
+   if (scope != RT_SCOPE_UNIVERSE 
+   !(scope == RT_SCOPE_LINK 
+   IN6_IS_ADDR_UNSPECIFIED(dst)))
+   return;
+
+   if (!IN6_IS_ADDR_UNSPECIFIED(dst))
+   return;
+   } else
return;
 
for (list = rtnl_list; list; list = list-next) {
@@ -696,26 +745,49 @@ static void process_delroute(unsigned char family, 
unsigned char scope,
struct rtmsg *msg, int bytes)
 {
GSList *list;
-   struct in_addr dst = { INADDR_ANY }, gateway = { INADDR_ANY };
-   char dststr[16], gatewaystr[16];
+   char dststr[INET6_ADDRSTRLEN], gatewaystr[INET6_ADDRSTRLEN];
int index = -1;
 
-   if (family != AF_INET)
-   return;
+   if (family == AF_INET) {
+   struct in_addr dst = { INADDR_ANY }, gateway = { INADDR_ANY };
 
-   extract_route(msg, bytes, 

[PATCH ipv6routes v1 0/2] Catch IPv6 default gw messages

2011-02-18 Thread Jukka Rissanen
Hi,

here is some preliminary work for IPv6 route handling. The patch
catches IPv6 route additions and deletions and updates ipconfig
accordingly.

Regards,
Jukka


Jukka Rissanen (2):
  rtnl: Catch IPv6 route netlink messages.
  ipconfig: Catch IPv6 default route creation and deletion.

 src/ipconfig.c |   16 +---
 src/rtnl.c |  122 ---
 2 files changed, 107 insertions(+), 31 deletions(-)

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH ipv6routes v1 2/2] ipconfig: Catch IPv6 default route creation and deletion.

2011-02-18 Thread Jukka Rissanen
---
 src/ipconfig.c |   16 ++--
 1 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/src/ipconfig.c b/src/ipconfig.c
index 62d3766..59dd987 100644
--- a/src/ipconfig.c
+++ b/src/ipconfig.c
@@ -720,7 +720,8 @@ void __connman_ipconfig_newroute(int index, int family, 
unsigned char scope,
if (ipdevice == NULL)
return;
 
-   if (scope == 0  g_strcmp0(dst, 0.0.0.0) == 0) {
+   if (scope == 0  (g_strcmp0(dst, 0.0.0.0) == 0 ||
+   g_strcmp0(dst, ::) == 0)) {
GSList *list;
GList *config_list;
 
@@ -734,7 +735,7 @@ void __connman_ipconfig_newroute(int index, int family, 
unsigned char scope,
ipdevice-config_ipv6-system-gateway =
g_strdup(gateway);
}
-   } else {
+   } else if (family == AF_INET) {
g_free(ipdevice-ipv4_gateway);
ipdevice-ipv4_gateway = g_strdup(gateway);
 
@@ -744,7 +745,8 @@ void __connman_ipconfig_newroute(int index, int family, 
unsigned char scope,
ipdevice-config_ipv4-system-gateway =
g_strdup(gateway);
}
-   }
+   } else
+   return;
 
for (list = ipdevice-address_list; list; list = list-next) {
struct connman_ipaddress *ipaddress = list-data;
@@ -784,7 +786,8 @@ void __connman_ipconfig_delroute(int index, int family, 
unsigned char scope,
if (ipdevice == NULL)
return;
 
-   if (scope == 0  g_strcmp0(dst, 0.0.0.0) == 0) {
+   if (scope == 0  (g_strcmp0(dst, 0.0.0.0) == 0 ||
+   g_strcmp0(dst, ::) == 0)) {
GSList *list;
GList *config_list;
 
@@ -797,7 +800,7 @@ void __connman_ipconfig_delroute(int index, int family, 
unsigned char scope,
g_free(ipdevice-config_ipv6-system-gateway);
ipdevice-config_ipv6-system-gateway = NULL;
}
-   } else {
+   } else if (family == AF_INET) {
g_free(ipdevice-ipv4_gateway);
ipdevice-ipv4_gateway = NULL;
 
@@ -806,7 +809,8 @@ void __connman_ipconfig_delroute(int index, int family, 
unsigned char scope,
g_free(ipdevice-config_ipv4-system-gateway);
ipdevice-config_ipv4-system-gateway = NULL;
}
-   }
+   } else
+   return;
 
for (list = ipdevice-address_list; list; list = list-next) {
struct connman_ipaddress *ipaddress = list-data;
-- 
1.7.0.4

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH 6to4 v3 0/7] Create 6to4 tunnel automatically if enabled

2011-02-21 Thread Jukka Rissanen
Hi,

The v3 patch moves 6to4 property to IPv4 dict.

The v2 patch checks if the tunnel has internet connectivity.
The check is done by trying to connect to ipv6.google.com:80 via the
tunnel. The google host was choosen as it only provides connectivity
via IPv6. This could be changed to connman.net when it provides the
same kind of service.
The IPv6 address of the host is resolved by async DNS so that mainloop
is not blocked.
The timeouts I used were 10 sec for DNS query and 2 sec for connection
test but these can be tweaked of course.

Regards,
Jukka


Jukka Rissanen (7):
  doc: Add description about 6to4 tunnelling.
  ipconfig: Add function to return the system address pointer.
  6to4: Add 6to4 tunnel support.
  service: Create 6to4 tunnel if enabled.
  test: Add support for 6to4 tunnel status printing.
  test: Add support for enabling/disabling 6to4 tunnel.
  6to4: Check the connectivity via tunnel after creating it.

 Makefile.am |   10 +-
 configure.ac|4 +
 doc/service-api.txt |   11 +
 src/6to4.c  |  789 +++
 src/connman.h   |9 +-
 src/ipconfig.c  |   25 ++-
 src/ipv4.c  |5 +
 src/service.c   |   61 -
 test/list-services  |8 +-
 test/test-connman   |   37 +++
 10 files changed, 947 insertions(+), 12 deletions(-)
 create mode 100644 src/6to4.c

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH 6to4 v3 3/7] 6to4: Add 6to4 tunnel support.

2011-02-21 Thread Jukka Rissanen
---
 Makefile.am   |2 +-
 src/6to4.c|  569 +
 src/connman.h |3 +
 3 files changed, 573 insertions(+), 1 deletions(-)
 create mode 100644 src/6to4.c

diff --git a/Makefile.am b/Makefile.am
index 144fcc5..8f13f56 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -77,7 +77,7 @@ src_connmand_SOURCES = $(gdbus_sources) $(gdhcp_sources) \
src/wifi.c src/storage.c src/dbus.c src/config.c \
src/technology.c src/counter.c src/location.c \
src/session.c src/tethering.c src/wpad.c src/wispr.c \
-   src/stats.c src/iptables.c src/dnsproxy.c
+   src/stats.c src/iptables.c src/dnsproxy.c src/6to4.c
 
 src_connmand_LDADD = $(builtin_libadd) @GLIB_LIBS@ @DBUS_LIBS@ \
@CAPNG_LIBS@ @XTABLES_LIBS@ -lresolv -ldl
diff --git a/src/6to4.c b/src/6to4.c
new file mode 100644
index 000..b07eeed
--- /dev/null
+++ b/src/6to4.c
@@ -0,0 +1,569 @@
+/*
+ *
+ *  Connection Manager
+ *
+ *  Copyright (C) 2011  Nokia 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 string.h
+#include sys/socket.h
+#include netinet/in.h
+#include arpa/inet.h
+#include net/if.h
+#include linux/ip.h
+#include linux/if_tunnel.h
+#include linux/netlink.h
+#include linux/rtnetlink.h
+#include sys/ioctl.h
+#include unistd.h
+
+#include connman.h
+#include connman/log.h
+
+static int tunnel_created;
+
+#define NLMSG_TAIL(nmsg) \
+   ((struct rtattr *) (((void *)(nmsg)) + NLMSG_ALIGN((nmsg)-nlmsg_len)))
+
+#ifndef IP_DF
+#define IP_DF  0x4000  /* Flag: Don't Fragment   */
+#endif
+
+struct rtnl_handle {
+   int fd;
+   struct sockaddr_nl  local;
+   struct sockaddr_nl  peer;
+   __u32   seq;
+   __u32   dump;
+};
+
+/* Note that addattr32(), addattr_l(), rtnl_close(), rtnl_open() and
+ * rtnl_talk() are from libnetlink.c that is found in iproute2 package
+ * and copyright by Alexey Kuznetsov et al.
+ */
+static int addattr32(struct nlmsghdr *n, int maxlen, int type, __u32 data)
+{
+   int len = RTA_LENGTH(4);
+   struct rtattr *rta;
+   if (NLMSG_ALIGN(n-nlmsg_len) + len  (unsigned int)maxlen) {
+   DBG(Error! max allowed bound %d exceeded, maxlen);
+   return -1;
+   }
+   rta = NLMSG_TAIL(n);
+   rta-rta_type = type;
+   rta-rta_len = len;
+   memcpy(RTA_DATA(rta), data, 4);
+   n-nlmsg_len = NLMSG_ALIGN(n-nlmsg_len) + len;
+
+   return 0;
+}
+
+static int addattr_l(struct nlmsghdr *n, int maxlen, int type,
+   const void *data, int alen)
+{
+   int len = RTA_LENGTH(alen);
+   struct rtattr *rta;
+
+   if (NLMSG_ALIGN(n-nlmsg_len) + RTA_ALIGN(len) 
+   (unsigned int)maxlen) {
+   DBG(addattr_l message exceeded bound of %d, maxlen);
+   return -1;
+   }
+   rta = NLMSG_TAIL(n);
+   rta-rta_type = type;
+   rta-rta_len = len;
+   memcpy(RTA_DATA(rta), data, alen);
+   n-nlmsg_len = NLMSG_ALIGN(n-nlmsg_len) + RTA_ALIGN(len);
+
+   return 0;
+}
+
+static void rtnl_close(struct rtnl_handle *rth)
+{
+   if (rth-fd = 0) {
+   close(rth-fd);
+   rth-fd = -1;
+   }
+}
+
+static int rtnl_open(struct rtnl_handle *rth)
+{
+   socklen_t addr_len;
+   int sndbuf = 32768;
+   int rcvbuf = 32768;
+
+   memset(rth, 0, sizeof(*rth));
+
+   rth-fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+   if (rth-fd  0) {
+   DBG(Cannot open netlink socket: %s, strerror(errno));
+   return -1;
+   }
+
+   if (setsockopt(rth-fd, SOL_SOCKET, SO_SNDBUF, sndbuf,
+   sizeof(sndbuf))  0) {
+   DBG(SO_SNDBUF: %s, strerror(errno));
+   return -1;
+   }
+
+   if (setsockopt(rth-fd, SOL_SOCKET, SO_RCVBUF, rcvbuf,
+   sizeof(rcvbuf))  0) {
+   DBG(SO_RCVBUF: %s, strerror(errno));
+   return -1;
+   }
+
+   memset(rth-local, 0, sizeof(rth-local));
+   rth-local.nl_family = AF_NETLINK;

[PATCH 6to4 v3 5/7] test: Add support for 6to4 tunnel status printing.

2011-02-21 Thread Jukka Rissanen
---
 test/list-services |8 +++-
 1 files changed, 7 insertions(+), 1 deletions(-)

diff --git a/test/list-services b/test/list-services
index 3ae6a4d..bfb0f73 100755
--- a/test/list-services
+++ b/test/list-services
@@ -12,7 +12,13 @@ def extract_values(values):
if key in [Servers, Excludes]:
val += extract_list(values[key])
else:
-   val += str(values[key])
+   if key in [6to4]:
+   if values[key] == dbus.Boolean(1):
+   val += true
+   else:
+   val += false
+   else:
+   val += str(values[key])
val +=  }
return val
 
-- 
1.7.0.4

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH 6to4 v3 6/7] test: Add support for enabling/disabling 6to4 tunnel.

2011-02-21 Thread Jukka Rissanen
---
 test/test-connman |   37 +
 1 files changed, 37 insertions(+), 0 deletions(-)

diff --git a/test/test-connman b/test/test-connman
index 9a855fb..c297cf7 100755
--- a/test/test-connman
+++ b/test/test-connman
@@ -18,6 +18,7 @@ if len(sys.argv)  2:
print   connect service
print   disconnect service
print   remove service
+   print   6to4 service [on|off]
print 
print   scan [type]
print   enable type
@@ -170,6 +171,42 @@ elif sys.argv[1] in [remove]:
except dbus.DBusException, error:
print %s: %s % (error._dbus_error_name, error.message)
 
+elif sys.argv[1] == 6to4:
+   if (len(sys.argv)  3):
+   print Need at least service parameter
+   sys.exit(1)
+
+   path = /profile/default/ + sys.argv[2]
+
+   service = dbus.Interface(bus.get_object(net.connman, path),
+   net.connman.Service)
+   properties = service.GetProperties()
+
+   if (len(sys.argv)  3):
+   flag = sys.argv[3].strip().lower()
+   six2four = dbus.Boolean(flag not in ['false', 'off', 'f', 'n', 
'0'])
+
+   ipv4_config = properties[IPv4.Configuration]
+   ipv4_configuration = { Method : str(ipv4_config[Method]) }
+   ipv4_configuration[6to4] = str(six2four)
+   if Address in ipv4_config.keys():
+   ipv4_configuration[Address] = 
str(ipv4_config[Address])
+   if Netmask in ipv4_config.keys():
+   ipv4_configuration[Netmask] = 
str(ipv4_config[Netmask])
+   if Gateway in ipv4_config.keys():
+   ipv4_configuration[Gateway] = 
str(ipv4_config[Gateway])
+   service.SetProperty(IPv4.Configuration, ipv4_configuration)
+
+   print 6to4 tunnelling set to %s for %s % (six2four, 
sys.argv[2])
+   else:
+   ipv4_configuration = properties[IPv4.Configuration]
+   if 6to4 in ipv4_configuration.keys():
+   six2four = ipv4_configuration[6to4]
+   else:
+   six2four = dbus.Boolean(0)
+
+   print 6to4 tunnelling set to %s for %s % (six2four, 
sys.argv[2])
+
 elif sys.argv[1] == scan:
if len(sys.argv)  2:
manager.RequestScan(sys.argv[2])
-- 
1.7.0.4

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH privacy v3 2/3] ipconfig: Support IPv6 privacy extension for autoconf addresses.

2011-02-21 Thread Jukka Rissanen
---
 src/ipconfig.c |  141 +--
 1 files changed, 135 insertions(+), 6 deletions(-)

diff --git a/src/ipconfig.c b/src/ipconfig.c
index 6511370..5d4e755 100644
--- a/src/ipconfig.c
+++ b/src/ipconfig.c
@@ -51,6 +51,8 @@ struct connman_ipconfig {
enum connman_ipconfig_method method;
struct connman_ipaddress *address;
struct connman_ipaddress *system;
+
+   int ipv6_privacy_config;
 };
 
 struct connman_ipdevice {
@@ -79,6 +81,7 @@ struct connman_ipdevice {
struct connman_ipconfig *config_ipv6;
 
gboolean ipv6_enabled;
+   int ipv6_privacy;
 };
 
 static GHashTable *ipdevice_hash = NULL;
@@ -352,6 +355,67 @@ static void set_ipv6_state(gchar *ifname, gboolean enable)
fclose(f);
 }
 
+static int get_ipv6_privacy(gchar *ifname)
+{
+   gchar *path;
+   FILE *f;
+   int value;
+
+   if (ifname == NULL)
+   return 0;
+
+   path = g_strdup_printf(/proc/sys/net/ipv6/conf/%s/use_tempaddr,
+   ifname);
+
+   if (path == NULL)
+   return 0;
+
+   f = fopen(path, r);
+
+   g_free(path);
+
+   if (f == NULL)
+   return 0;
+
+   if (fscanf(f, %d, value) = 0)
+   value = 0;
+
+   fclose(f);
+
+   return value;
+}
+
+/* Enable the IPv6 privacy extension for stateless address autoconfiguration.
+ * The privacy extension is described in RFC 3041 and RFC 4941
+ */
+static void set_ipv6_privacy(gchar *ifname, int value)
+{
+   gchar *path;
+   FILE *f;
+
+   if (ifname == NULL)
+   return;
+
+   path = g_strdup_printf(/proc/sys/net/ipv6/conf/%s/use_tempaddr,
+   ifname);
+
+   if (path == NULL)
+   return;
+
+   if (value  0)
+   value = 0;
+
+   f = fopen(path, r+);
+
+   g_free(path);
+
+   if (f == NULL)
+   return;
+
+   fprintf(f, %d, value);
+   fclose(f);
+}
+
 static void free_ipdevice(gpointer data)
 {
struct connman_ipdevice *ipdevice = data;
@@ -377,6 +441,7 @@ static void free_ipdevice(gpointer data)
g_free(ipdevice-address);
 
set_ipv6_state(ipdevice-ifname, ipdevice-ipv6_enabled);
+   set_ipv6_privacy(ipdevice-ifname, ipdevice-ipv6_privacy);
 
g_free(ipdevice-ifname);
g_free(ipdevice);
@@ -474,6 +539,7 @@ void __connman_ipconfig_newlink(int index, unsigned short 
type,
ipdevice-type = type;
 
ipdevice-ipv6_enabled = get_ipv6_state(ipdevice-ifname);
+   ipdevice-ipv6_privacy = get_ipv6_privacy(ipdevice-ifname);
 
ipdevice-address = g_strdup(address);
 
@@ -1030,6 +1096,7 @@ static struct connman_ipconfig *create_ipv6config(int 
index)
ipv6config-index = index;
ipv6config-type = CONNMAN_IPCONFIG_TYPE_IPV6;
ipv6config-method = CONNMAN_IPCONFIG_METHOD_AUTO;
+   ipv6config-ipv6_privacy_config = 0;
 
ipv6config-address = connman_ipaddress_alloc(AF_INET6);
if (ipv6config-address == NULL) {
@@ -1376,6 +1443,10 @@ static void enable_ipv6(struct connman_ipconfig 
*ipconfig)
if (ipdevice == NULL)
return;
 
+   if (ipconfig-method == CONNMAN_IPCONFIG_METHOD_AUTO)
+   set_ipv6_privacy(ipdevice-ifname,
+   ipconfig-ipv6_privacy_config);
+
set_ipv6_state(ipdevice-ifname, TRUE);
 }
 
@@ -1545,6 +1616,30 @@ enum connman_ipconfig_method 
__connman_ipconfig_string2method(const char *method
return CONNMAN_IPCONFIG_METHOD_UNKNOWN;
 }
 
+static const char *privacy2string(int privacy)
+{
+   if (privacy = 0)
+   return disabled;
+   else if (privacy == 1)
+   return enabled;
+   else if (privacy  1)
+   return prefered;
+
+   return disabled;
+}
+
+static int string2privacy(const char *privacy)
+{
+   if (g_strcmp0(privacy, disabled) == 0)
+   return 0;
+   else if (g_strcmp0(privacy, enabled) == 0)
+   return 1;
+   else if (g_strcmp0(privacy, prefered) == 0)
+   return 2;
+   else
+   return 0;
+}
+
 void __connman_ipconfig_append_ipv4(struct connman_ipconfig *ipconfig,
DBusMessageIter *iter)
 {
@@ -1587,7 +1682,7 @@ void __connman_ipconfig_append_ipv4(struct 
connman_ipconfig *ipconfig,
 void __connman_ipconfig_append_ipv6(struct connman_ipconfig *ipconfig,
DBusMessageIter *iter)
 {
-   const char *str;
+   const char *str, *privacy;
 
DBG();
 
@@ -1614,12 +1709,16 @@ void __connman_ipconfig_append_ipv6(struct 
connman_ipconfig *ipconfig,
if (ipconfig-system-gateway != NULL)
connman_dbus_dict_append_basic(iter, Gateway,

[PATCH privacy v3 3/3] test: Enable or disable IPv6 privacy extension.

2011-02-21 Thread Jukka Rissanen
---
 test/set-ipv6-method |   18 +++---
 1 files changed, 11 insertions(+), 7 deletions(-)

diff --git a/test/set-ipv6-method b/test/set-ipv6-method
index 274e89b..c0b251e 100755
--- a/test/set-ipv6-method
+++ b/test/set-ipv6-method
@@ -4,7 +4,7 @@ import sys
 import dbus
 
 def print_usage():
-   print Usage: %s service off|manual|auto [address [prefixlen] 
[gateway]] % (sys.argv[0])
+   print Usage: %s service off|manual|auto [address [prefixlen] 
[gateway]] [privacy] % (sys.argv[0])
 
 if (len(sys.argv)  3):
print_usage()
@@ -20,12 +20,16 @@ properties = service.GetProperties()
 print Setting method %s for %s % (sys.argv[2], sys.argv[1])
 
 ipv6_configuration = { Method: sys.argv[2] }
-if (len(sys.argv)  3):
-   ipv6_configuration[Address] = sys.argv[3]
-if (len(sys.argv)  4):
-   ipv6_configuration[PrefixLength] = sys.argv[4]
-if (len(sys.argv)  5):
-   ipv6_configuration[Gateway] = sys.argv[5]
+if sys.argv[2] == auto:
+   if (len(sys.argv)  3):
+   ipv6_configuration[Privacy] = sys.argv[3]
+else:
+   if (len(sys.argv)  3):
+   ipv6_configuration[Address] = sys.argv[3]
+   if (len(sys.argv)  4):
+   ipv6_configuration[PrefixLength] = sys.argv[4]
+   if (len(sys.argv)  5):
+   ipv6_configuration[Gateway] = sys.argv[5]
 
 service.SetProperty(IPv6.Configuration, ipv6_configuration)
 print New IPv6.Configuration: , ipv6_configuration
-- 
1.7.0.4

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH 6to4 v4 01/10] doc: Add description about 6to4 tunnelling.

2011-03-16 Thread Jukka Rissanen
---
 doc/service-api.txt |   10 ++
 1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/doc/service-api.txt b/doc/service-api.txt
index 65554a2..e13808e 100644
--- a/doc/service-api.txt
+++ b/doc/service-api.txt
@@ -332,6 +332,16 @@ Properties string State [readonly]
 
The current configured IPv4 gateway.
 
+   boolean 6to4 [readonly]
+
+   If true, the service created 6to4
+   tunnel if the service IPv4 address is not
+   private and autoconfiguration does not work.
+   Only one tunnel is created even if there are
+   more than one active service that have public
+   IPv4 address. Tunnel is only created if it
+   provides internet connectivity.
+
dict IPv4.Configuration [readwrite]
 
Same values as IPv4 property. The IPv4 represents
-- 
1.7.0.4

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH 6to4 v4 00/10] 6to4 tunneling support

2011-03-16 Thread Jukka Rissanen
Hi,

this is v4 of the 6to4 tunneling support and many things
have been changed in this version like:
- 6to4 tunnel setting in service is read only i.e., it cannot
  be manipulated via dbus any longer
- generic tunnel creation added to inet.c
- IPv6 router solicitation / advertisement handling in inet.c
- IPv6 support is added to gweb
- gweb is used when checking connectivity through tunnel
- tunnel is only created if we have a public IP address,
  the IPv6 is enabled and method is auto, we have not received
  autoconfigured ip address and internet connectivity via
  tunnel works ok

The patch set is only tested via simulation (by commenting out
various checks in the code) as I could not find such a crappy
network anywhere, so there might be some problems left in the code.

There is one issue when using gweb to check the connectivity via
tunnel. As the network interface to be used is not set in gweb,
we are just hoping that the routing in the device forces the check
go through tunnel.

Regards,
Jukka


Jukka Rissanen (10):
  doc: Add description about 6to4 tunnelling.
  inet: MTU and tunnel setup functions added.
  inet: Add routines to send IPv6 router solicitation message.
  gweb: Add support for connecting to IPv6 host.
  6to4: Add 6to4 tunnel support.
  6to4: Check the connectivity via tunnel after creating it.
  service: Create/remove 6to4 tunnel.
  6to4: Check if the 6to4 tunnel is active or not.
  service: Return 6to4 tunnel status to dbus caller.
  test: Add support for 6to4 tunnel status printing.

 Makefile.am |2 +-
 doc/service-api.txt |   10 +
 gweb/gweb.c |   29 ++-
 include/inet.h  |   11 +
 src/6to4.c  |  563 +++
 src/connman.h   |4 +
 src/dhcp.c  |4 +
 src/inet.c  |  386 +++-
 src/service.c   |   12 +-
 test/list-services  |8 +-
 10 files changed, 1015 insertions(+), 14 deletions(-)
 create mode 100644 src/6to4.c

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH 6to4 v4 03/10] inet: Add routines to send IPv6 router solicitation message.

2011-03-16 Thread Jukka Rissanen
---
 include/inet.h |8 ++
 src/inet.c |  315 
 2 files changed, 323 insertions(+), 0 deletions(-)

diff --git a/include/inet.h b/include/inet.h
index 9a9411d..3ed19c4 100644
--- a/include/inet.h
+++ b/include/inet.h
@@ -25,6 +25,8 @@
 #include arpa/inet.h
 #include linux/netlink.h
 #include linux/rtnetlink.h
+#include netinet/ip6.h
+#include netinet/icmp6.h
 
 #include connman/device.h
 #include connman/ipconfig.h
@@ -76,6 +78,12 @@ int connman_inet_remove_from_bridge(int index, const char 
*bridge);
 int connman_inet_set_mtu(int index, int mtu);
 int connman_inet_setup_tunnel(char *tunnel, int mtu);
 
+typedef void (*connman_inet_rs_cb_t) (struct nd_router_advert *reply,
+   void *user_data);
+
+int connman_inet_ipv6_send_rs(int index, int timeout,
+   connman_inet_rs_cb_t callback, void *user_data);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/inet.c b/src/inet.c
index 858d34c..40d8a8d 100644
--- a/src/inet.c
+++ b/src/inet.c
@@ -4,6 +4,10 @@
  *
  *  Copyright (C) 2007-2010  Intel Corporation. All rights reserved.
  *
+ *  Portions (IPv6 router solicitation handling from MIPL project) are
+ *  Copyright 2003-2005 Go-Core Project and 2003-2006 Helsinki University of
+ *  Technology
+ *
  *  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.
@@ -37,6 +41,7 @@
 #include net/ethernet.h
 #include net/if.h
 #include net/if_arp.h
+#include netinet/icmp6.h
 
 #include connman.h
 
@@ -1261,3 +1266,313 @@ done:
close(sk);
return err;
 }
+
+struct rs_cb_data {
+   GIOChannel *channel;
+   connman_inet_rs_cb_t callback;
+   struct sockaddr_in6 addr;
+   guint rs_timeout;
+   void *user_data;
+};
+
+#define CMSG_BUF_LEN 512
+#define IN6ADDR_ALL_NODES_MC_INIT \
+   { { { 0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,0x1 } } } /* ff02::1 */
+#define IN6ADDR_ALL_ROUTERS_MC_INIT \
+   { { { 0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,0x2 } } } /* ff02::2 */
+
+static const struct in6_addr in6addr_all_nodes_mc = IN6ADDR_ALL_NODES_MC_INIT;
+static const struct in6_addr in6addr_all_routers_mc =
+   IN6ADDR_ALL_ROUTERS_MC_INIT;
+
+/* from netinet/in.h */
+struct in6_pktinfo {
+   struct in6_addr ipi6_addr;  /* src/dst IPv6 address */
+   unsigned int ipi6_ifindex;  /* send/recv interface index */
+};
+
+static void rs_cleanup(struct rs_cb_data *data)
+{
+   g_io_channel_shutdown(data-channel, TRUE, NULL);
+   g_io_channel_unref(data-channel);
+   data-channel = 0;
+
+   if (data-rs_timeout  0)
+   g_source_remove(data-rs_timeout);
+
+   g_free(data);
+}
+
+static gboolean rs_timeout_cb(gpointer user_data)
+{
+   struct rs_cb_data *data = user_data;
+
+   DBG(user data %p, user_data);
+
+   if (data == NULL)
+   return FALSE;
+
+   if (data-callback != NULL)
+   data-callback(NULL, data-user_data);
+
+   data-rs_timeout = 0;
+   rs_cleanup(data);
+   return FALSE;
+}
+
+static int icmpv6_recv(int fd, gpointer user_data)
+{
+   struct msghdr mhdr;
+   struct iovec iov;
+   unsigned char chdr[CMSG_BUF_LEN];
+   unsigned char buf[1540];
+   struct rs_cb_data *data = user_data;
+   struct nd_router_advert *hdr;
+   struct sockaddr_in6 saddr;
+   ssize_t len;
+
+   DBG();
+
+   iov.iov_len = sizeof(buf);
+   iov.iov_base = buf;
+
+   mhdr.msg_name = (void *)saddr;
+   mhdr.msg_namelen = sizeof(struct sockaddr_in6);
+   mhdr.msg_iov = iov;
+   mhdr.msg_iovlen = 1;
+   mhdr.msg_control = (void *)chdr;
+   mhdr.msg_controllen = CMSG_BUF_LEN;
+
+   len = recvmsg(fd, mhdr, 0);
+   if (len  0) {
+   data-callback(NULL, data-user_data);
+   return -errno;
+   }
+
+   hdr = (struct nd_router_advert *)buf;
+   if (hdr-nd_ra_code != 0)
+   return 0;
+
+   data-callback(hdr, data-user_data);
+   rs_cleanup(data);
+
+   return len;
+}
+
+static gboolean icmpv6_event(GIOChannel *chan, GIOCondition cond,
+   gpointer data)
+{
+   int fd, ret;
+
+   DBG();
+
+   if (cond  (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
+   return FALSE;
+
+   fd = g_io_channel_unix_get_fd(chan);
+   ret = icmpv6_recv(fd, data);
+   if (ret == 0)
+   return TRUE;
+
+   return FALSE;
+}
+
+/* Adapted from RFC 1071 C Implementation Example */
+static uint16_t csum(const void *phdr, const void *data, socklen_t datalen)
+{
+   register unsigned long sum = 0;
+   socklen_t count;
+   uint16_t *addr;
+   int i;
+
+   /* caller must make sure datalen is even */
+
+   addr = (uint16_t *)phdr;
+  

[PATCH 6to4 v4 02/10] inet: MTU and tunnel setup functions added.

2011-03-16 Thread Jukka Rissanen
---
 include/inet.h |3 ++
 src/inet.c |   71 ++-
 2 files changed, 72 insertions(+), 2 deletions(-)

diff --git a/include/inet.h b/include/inet.h
index 9ba7781..9a9411d 100644
--- a/include/inet.h
+++ b/include/inet.h
@@ -73,6 +73,9 @@ int connman_inet_clear_ipv6_gateway_address(int index, const 
char *gateway);
 int connman_inet_add_to_bridge(int index, const char *bridge);
 int connman_inet_remove_from_bridge(int index, const char *bridge);
 
+int connman_inet_set_mtu(int index, int mtu);
+int connman_inet_setup_tunnel(char *tunnel, int mtu);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/inet.c b/src/inet.c
index 2f287f6..858d34c 100644
--- a/src/inet.c
+++ b/src/inet.c
@@ -35,8 +35,8 @@
 #include arpa/inet.h
 #include net/route.h
 #include net/ethernet.h
-#include linux/if_arp.h
-#include linux/wireless.h
+#include net/if.h
+#include net/if_arp.h
 
 #include connman.h
 
@@ -1194,3 +1194,70 @@ int connman_inet_add_to_bridge(int index, const char 
*bridge)
 
return 0;
 }
+
+int connman_inet_set_mtu(int index, int mtu)
+{
+   struct ifreq ifr;
+   int sk, err;
+
+   sk = socket(AF_INET, SOCK_DGRAM, 0);
+   if (sk  0)
+   return sk;
+
+   memset(ifr, 0, sizeof(ifr));
+   ifr.ifr_ifindex = index;
+
+   err = ioctl(sk, SIOCGIFNAME, ifr);
+   if (err == 0) {
+   ifr.ifr_mtu = mtu;
+   err = ioctl(sk, SIOCSIFMTU, ifr);
+   }
+
+   close(sk);
+   return err;
+}
+
+int connman_inet_setup_tunnel(char *tunnel, int mtu)
+{
+   struct ifreq ifr;
+   int sk, err, index;
+   __u32 mask;
+   __u32 flags;
+
+   if (tunnel == NULL)
+   return -EINVAL;
+
+   sk = socket(AF_INET, SOCK_DGRAM, 0);
+   if (sk  0)
+   return sk;
+
+   index = if_nametoindex(tunnel);
+
+   err = connman_inet_set_mtu(index, mtu);
+   if (err  0)
+   return err;
+   else if (err)
+   goto done;
+
+   memset(ifr, 0, sizeof(ifr));
+   strncpy(ifr.ifr_name, tunnel, IFNAMSIZ);
+   err = ioctl(sk, SIOCGIFFLAGS, ifr);
+   if (err)
+   goto done;
+
+   mask = IFF_UP;
+   flags = IFF_UP;
+
+   if ((ifr.ifr_flags ^ flags)  mask) {
+   ifr.ifr_flags = ~mask;
+   ifr.ifr_flags |= mask  flags;
+   err = ioctl(sk, SIOCSIFFLAGS, ifr);
+   if (err)
+   connman_error(SIOCSIFFLAGS failed: %s,
+   strerror(errno));
+   }
+
+done:
+   close(sk);
+   return err;
+}
-- 
1.7.0.4

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH 6to4 v4 05/10] 6to4: Add 6to4 tunnel support.

2011-03-16 Thread Jukka Rissanen
---
 Makefile.am   |2 +-
 src/6to4.c|  498 +
 src/connman.h |3 +
 3 files changed, 502 insertions(+), 1 deletions(-)
 create mode 100644 src/6to4.c

diff --git a/Makefile.am b/Makefile.am
index 3ad1ee9..95aefc7 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -77,7 +77,7 @@ src_connmand_SOURCES = $(gdbus_sources) $(gdhcp_sources) \
src/wifi.c src/storage.c src/dbus.c src/config.c \
src/technology.c src/counter.c src/location.c \
src/session.c src/tethering.c src/wpad.c src/wispr.c \
-   src/stats.c src/iptables.c src/dnsproxy.c
+   src/stats.c src/iptables.c src/dnsproxy.c src/6to4.c
 
 src_connmand_LDADD = $(builtin_libadd) @GLIB_LIBS@ @DBUS_LIBS@ \
@CAPNG_LIBS@ @XTABLES_LIBS@ -lresolv -ldl
diff --git a/src/6to4.c b/src/6to4.c
new file mode 100644
index 000..68472e6
--- /dev/null
+++ b/src/6to4.c
@@ -0,0 +1,498 @@
+/*
+ *
+ *  Connection Manager
+ *
+ *  Copyright (C) 2011  Nokia Corporation. All rights reserved.
+ *
+ *  Portions copyright by Alexey Kuznetsov et al. from iproute2 package.
+ *
+ *  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 string.h
+#include sys/socket.h
+#include netinet/in.h
+#include arpa/inet.h
+#include net/if.h
+#include linux/ip.h
+#include linux/if_tunnel.h
+#include linux/netlink.h
+#include linux/rtnetlink.h
+#include sys/ioctl.h
+#include unistd.h
+
+#include connman.h
+#include connman/log.h
+#include connman/ipconfig.h
+
+static int tunnel_created;
+static int tunnel_pending;
+static char *tunnel_ip_address;
+
+#define NLMSG_TAIL(nmsg) \
+   ((struct rtattr *) (((void *)(nmsg)) + NLMSG_ALIGN((nmsg)-nlmsg_len)))
+
+#ifndef IP_DF
+#define IP_DF  0x4000  /* Flag: Don't Fragment   */
+#endif
+
+struct rtnl_handle {
+   int fd;
+   struct sockaddr_nl  local;
+   struct sockaddr_nl  peer;
+   __u32   seq;
+   __u32   dump;
+};
+
+static int addattr32(struct nlmsghdr *n, int maxlen, int type, __u32 data)
+{
+   int len = RTA_LENGTH(4);
+   struct rtattr *rta;
+   if (NLMSG_ALIGN(n-nlmsg_len) + len  (unsigned int)maxlen) {
+   DBG(Error! max allowed bound %d exceeded, maxlen);
+   return -1;
+   }
+   rta = NLMSG_TAIL(n);
+   rta-rta_type = type;
+   rta-rta_len = len;
+   memcpy(RTA_DATA(rta), data, 4);
+   n-nlmsg_len = NLMSG_ALIGN(n-nlmsg_len) + len;
+
+   return 0;
+}
+
+static int addattr_l(struct nlmsghdr *n, int maxlen, int type,
+   const void *data, int alen)
+{
+   int len = RTA_LENGTH(alen);
+   struct rtattr *rta;
+
+   if (NLMSG_ALIGN(n-nlmsg_len) + RTA_ALIGN(len) 
+   (unsigned int)maxlen) {
+   DBG(addattr_l message exceeded bound of %d, maxlen);
+   return -1;
+   }
+   rta = NLMSG_TAIL(n);
+   rta-rta_type = type;
+   rta-rta_len = len;
+   memcpy(RTA_DATA(rta), data, alen);
+   n-nlmsg_len = NLMSG_ALIGN(n-nlmsg_len) + RTA_ALIGN(len);
+
+   return 0;
+}
+
+static void rtnl_close(struct rtnl_handle *rth)
+{
+   if (rth-fd = 0) {
+   close(rth-fd);
+   rth-fd = -1;
+   }
+}
+
+static int rtnl_open(struct rtnl_handle *rth)
+{
+   socklen_t addr_len;
+   int sndbuf = 1024;
+
+   memset(rth, 0, sizeof(*rth));
+
+   rth-fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+   if (rth-fd  0) {
+   connman_error(Can not open netlink socket: %s,
+   strerror(errno));
+   return -1;
+   }
+
+   if (setsockopt(rth-fd, SOL_SOCKET, SO_SNDBUF, sndbuf,
+   sizeof(sndbuf))  0) {
+   connman_error(SO_SNDBUF: %s, strerror(errno));
+   return -1;
+   }
+
+   memset(rth-local, 0, sizeof(rth-local));
+   rth-local.nl_family = AF_NETLINK;
+   rth-local.nl_groups = 0;
+
+   if (bind(rth-fd, (struct sockaddr *)rth-local,
+   sizeof(rth-local))  0) {
+   connman_error(Can not bind 

[PATCH 6to4 v4 06/10] 6to4: Check the connectivity via tunnel after creating it.

2011-03-16 Thread Jukka Rissanen
---
 src/6to4.c |   47 ++-
 1 files changed, 46 insertions(+), 1 deletions(-)

diff --git a/src/6to4.c b/src/6to4.c
index 68472e6..52a0c53 100644
--- a/src/6to4.c
+++ b/src/6to4.c
@@ -41,10 +41,15 @@
 #include connman.h
 #include connman/log.h
 #include connman/ipconfig.h
+#include gweb/gweb.h
 
 static int tunnel_created;
 static int tunnel_pending;
 static char *tunnel_ip_address;
+static GWeb *web;
+static guint web_request_id;
+
+#define STATUS_URL http://ipv6.google.com/;
 
 #define NLMSG_TAIL(nmsg) \
((struct rtattr *) (((void *)(nmsg)) + NLMSG_ALIGN((nmsg)-nlmsg_len)))
@@ -359,6 +364,35 @@ done:
return ret;
 }
 
+static gboolean unref_web(gpointer user_data)
+{
+   g_web_unref(web);
+   return FALSE;
+}
+
+static gboolean web_result(GWebResult *result, gpointer user_data)
+{
+   guint16 status;
+
+   if (web_request_id == 0)
+   return FALSE;
+
+   status = g_web_result_get_status(result);
+
+   DBG(status %u, status);
+
+   if (status = 400  status  500)
+   tunnel_destroy();
+   else
+   tunnel_pending = 0;
+
+   web_request_id = 0;
+
+   g_timeout_add_seconds(1, unref_web, NULL);
+
+   return FALSE;
+}
+
 static int init_6to4(struct in_addr *ip4addr)
 {
unsigned int a, b, c, d;
@@ -392,7 +426,18 @@ static int init_6to4(struct in_addr *ip4addr)
if (ret)
goto error;
 
-   tunnel_pending = 0;
+   /* We try to verify that connectivity through tunnel works ok.
+*/
+   web = g_web_new(0);
+   if (web == NULL)
+   goto error;
+
+   g_web_set_accept(web, NULL);
+   g_web_set_user_agent(web, ConnMan/%s, VERSION);
+   g_web_set_close_connection(web, TRUE);
+
+   web_request_id = g_web_request_get(web, STATUS_URL, web_result, NULL);
+
return 0;
 
 error:
-- 
1.7.0.4

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH 6to4 v4 09/10] service: Return 6to4 tunnel status to dbus caller.

2011-03-16 Thread Jukka Rissanen
---
 src/service.c |   10 +-
 1 files changed, 9 insertions(+), 1 deletions(-)

diff --git a/src/service.c b/src/service.c
index 29d6af5..77e16a5 100644
--- a/src/service.c
+++ b/src/service.c
@@ -987,8 +987,16 @@ static void append_ipv4(DBusMessageIter *iter, void 
*user_data)
if (is_connected_state(service, service-state_ipv4) == FALSE)
return;
 
-   if (service-ipconfig_ipv4 != NULL)
+   if (service-ipconfig_ipv4 != NULL) {
+   int status;
+
__connman_ipconfig_append_ipv4(service-ipconfig_ipv4, iter);
+
+   status = __connman_6to4_check(service-ipconfig_ipv4);
+   if (status = 0)
+   connman_dbus_dict_append_basic(iter, 6to4,
+   DBUS_TYPE_BOOLEAN, status);
+   }
 }
 
 static void append_ipv6(DBusMessageIter *iter, void *user_data)
-- 
1.7.0.4

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH 6to4 v4 08/10] 6to4: Check if the 6to4 tunnel is active or not.

2011-03-16 Thread Jukka Rissanen
---
 src/6to4.c|   20 
 src/connman.h |1 +
 2 files changed, 21 insertions(+), 0 deletions(-)

diff --git a/src/6to4.c b/src/6to4.c
index 52a0c53..8593e71 100644
--- a/src/6to4.c
+++ b/src/6to4.c
@@ -541,3 +541,23 @@ void __connman_6to4_remove(struct connman_ipconfig 
*ip4config)
if (tunnel_created)
tunnel_destroy();
 }
+
+int __connman_6to4_check(struct connman_ipconfig *ip4config)
+{
+   const char *address;
+
+   if (ip4config == NULL || tunnel_created == 0 ||
+   tunnel_pending == 1)
+   return -1;
+
+   DBG(tunnel ip address %s, tunnel_ip_address);
+
+   address = __connman_ipconfig_get_local(ip4config);
+   if (address == NULL)
+   return -1;
+
+   if (g_strcmp0(address, tunnel_ip_address) == 0)
+   return 1;
+
+   return 0;
+}
diff --git a/src/connman.h b/src/connman.h
index b3a45f0..a4ebbbe 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -639,3 +639,4 @@ void __connman_dnsproxy_flush(void);
 
 int __connman_6to4_probe(struct connman_service *service);
 void __connman_6to4_remove(struct connman_ipconfig *ipconfig);
+int __connman_6to4_check(struct connman_ipconfig *ipconfig);
-- 
1.7.0.4

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH 6to4 v4 07/10] service: Create/remove 6to4 tunnel.

2011-03-16 Thread Jukka Rissanen
---
 src/dhcp.c|4 
 src/service.c |2 ++
 2 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/src/dhcp.c b/src/dhcp.c
index 6fda67d..dd7c498 100644
--- a/src/dhcp.c
+++ b/src/dhcp.c
@@ -73,6 +73,8 @@ static void dhcp_invalid(struct connman_dhcp *dhcp)
if (ipconfig == NULL)
return;
 
+   __connman_6to4_remove(ipconfig);
+
__connman_service_set_domainname(service, NULL);
__connman_service_set_pac(service, NULL);
__connman_service_timeserver_remove(service, dhcp-timeserver);
@@ -211,6 +213,8 @@ static void lease_available_cb(GDHCPClient *dhcp_client, 
gpointer user_data)
 
dhcp_valid(dhcp);
 
+   __connman_6to4_probe(service);
+
g_free(address);
g_free(netmask);
g_free(gateway);
diff --git a/src/service.c b/src/service.c
index ece29fd..29d6af5 100644
--- a/src/service.c
+++ b/src/service.c
@@ -3875,6 +3875,8 @@ int __connman_service_disconnect(struct connman_service 
*service)
if (err  0  err != -EINPROGRESS)
return err;
 
+   __connman_6to4_remove(service-ipconfig_ipv4);
+
if (service-ipconfig_ipv4)
__connman_ipconfig_set_proxy_autoconfig(service-ipconfig_ipv4,
NULL);
-- 
1.7.0.4

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH 6to4 v4 10/10] test: Add support for 6to4 tunnel status printing.

2011-03-16 Thread Jukka Rissanen
---
 test/list-services |8 +++-
 1 files changed, 7 insertions(+), 1 deletions(-)

diff --git a/test/list-services b/test/list-services
index 3ae6a4d..bfb0f73 100755
--- a/test/list-services
+++ b/test/list-services
@@ -12,7 +12,13 @@ def extract_values(values):
if key in [Servers, Excludes]:
val += extract_list(values[key])
else:
-   val += str(values[key])
+   if key in [6to4]:
+   if values[key] == dbus.Boolean(1):
+   val += true
+   else:
+   val += false
+   else:
+   val += str(values[key])
val +=  }
return val
 
-- 
1.7.0.4

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH 6to4 v5 2/9] inet: MTU and tunnel setup functions added.

2011-03-17 Thread Jukka Rissanen
---
 include/inet.h |3 ++
 src/inet.c |   71 ++-
 2 files changed, 72 insertions(+), 2 deletions(-)

diff --git a/include/inet.h b/include/inet.h
index 9ba7781..9a9411d 100644
--- a/include/inet.h
+++ b/include/inet.h
@@ -73,6 +73,9 @@ int connman_inet_clear_ipv6_gateway_address(int index, const 
char *gateway);
 int connman_inet_add_to_bridge(int index, const char *bridge);
 int connman_inet_remove_from_bridge(int index, const char *bridge);
 
+int connman_inet_set_mtu(int index, int mtu);
+int connman_inet_setup_tunnel(char *tunnel, int mtu);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/inet.c b/src/inet.c
index 2f287f6..858d34c 100644
--- a/src/inet.c
+++ b/src/inet.c
@@ -35,8 +35,8 @@
 #include arpa/inet.h
 #include net/route.h
 #include net/ethernet.h
-#include linux/if_arp.h
-#include linux/wireless.h
+#include net/if.h
+#include net/if_arp.h
 
 #include connman.h
 
@@ -1194,3 +1194,70 @@ int connman_inet_add_to_bridge(int index, const char 
*bridge)
 
return 0;
 }
+
+int connman_inet_set_mtu(int index, int mtu)
+{
+   struct ifreq ifr;
+   int sk, err;
+
+   sk = socket(AF_INET, SOCK_DGRAM, 0);
+   if (sk  0)
+   return sk;
+
+   memset(ifr, 0, sizeof(ifr));
+   ifr.ifr_ifindex = index;
+
+   err = ioctl(sk, SIOCGIFNAME, ifr);
+   if (err == 0) {
+   ifr.ifr_mtu = mtu;
+   err = ioctl(sk, SIOCSIFMTU, ifr);
+   }
+
+   close(sk);
+   return err;
+}
+
+int connman_inet_setup_tunnel(char *tunnel, int mtu)
+{
+   struct ifreq ifr;
+   int sk, err, index;
+   __u32 mask;
+   __u32 flags;
+
+   if (tunnel == NULL)
+   return -EINVAL;
+
+   sk = socket(AF_INET, SOCK_DGRAM, 0);
+   if (sk  0)
+   return sk;
+
+   index = if_nametoindex(tunnel);
+
+   err = connman_inet_set_mtu(index, mtu);
+   if (err  0)
+   return err;
+   else if (err)
+   goto done;
+
+   memset(ifr, 0, sizeof(ifr));
+   strncpy(ifr.ifr_name, tunnel, IFNAMSIZ);
+   err = ioctl(sk, SIOCGIFFLAGS, ifr);
+   if (err)
+   goto done;
+
+   mask = IFF_UP;
+   flags = IFF_UP;
+
+   if ((ifr.ifr_flags ^ flags)  mask) {
+   ifr.ifr_flags = ~mask;
+   ifr.ifr_flags |= mask  flags;
+   err = ioctl(sk, SIOCSIFFLAGS, ifr);
+   if (err)
+   connman_error(SIOCSIFFLAGS failed: %s,
+   strerror(errno));
+   }
+
+done:
+   close(sk);
+   return err;
+}
-- 
1.7.0.4

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH 6to4 v5 3/9] inet: Add routines to send IPv6 router solicitation message.

2011-03-17 Thread Jukka Rissanen
---
 include/inet.h |8 ++
 src/inet.c |  315 
 2 files changed, 323 insertions(+), 0 deletions(-)

diff --git a/include/inet.h b/include/inet.h
index 9a9411d..3ed19c4 100644
--- a/include/inet.h
+++ b/include/inet.h
@@ -25,6 +25,8 @@
 #include arpa/inet.h
 #include linux/netlink.h
 #include linux/rtnetlink.h
+#include netinet/ip6.h
+#include netinet/icmp6.h
 
 #include connman/device.h
 #include connman/ipconfig.h
@@ -76,6 +78,12 @@ int connman_inet_remove_from_bridge(int index, const char 
*bridge);
 int connman_inet_set_mtu(int index, int mtu);
 int connman_inet_setup_tunnel(char *tunnel, int mtu);
 
+typedef void (*connman_inet_rs_cb_t) (struct nd_router_advert *reply,
+   void *user_data);
+
+int connman_inet_ipv6_send_rs(int index, int timeout,
+   connman_inet_rs_cb_t callback, void *user_data);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/inet.c b/src/inet.c
index 858d34c..40d8a8d 100644
--- a/src/inet.c
+++ b/src/inet.c
@@ -4,6 +4,10 @@
  *
  *  Copyright (C) 2007-2010  Intel Corporation. All rights reserved.
  *
+ *  Portions (IPv6 router solicitation handling from MIPL project) are
+ *  Copyright 2003-2005 Go-Core Project and 2003-2006 Helsinki University of
+ *  Technology
+ *
  *  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.
@@ -37,6 +41,7 @@
 #include net/ethernet.h
 #include net/if.h
 #include net/if_arp.h
+#include netinet/icmp6.h
 
 #include connman.h
 
@@ -1261,3 +1266,313 @@ done:
close(sk);
return err;
 }
+
+struct rs_cb_data {
+   GIOChannel *channel;
+   connman_inet_rs_cb_t callback;
+   struct sockaddr_in6 addr;
+   guint rs_timeout;
+   void *user_data;
+};
+
+#define CMSG_BUF_LEN 512
+#define IN6ADDR_ALL_NODES_MC_INIT \
+   { { { 0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,0x1 } } } /* ff02::1 */
+#define IN6ADDR_ALL_ROUTERS_MC_INIT \
+   { { { 0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,0x2 } } } /* ff02::2 */
+
+static const struct in6_addr in6addr_all_nodes_mc = IN6ADDR_ALL_NODES_MC_INIT;
+static const struct in6_addr in6addr_all_routers_mc =
+   IN6ADDR_ALL_ROUTERS_MC_INIT;
+
+/* from netinet/in.h */
+struct in6_pktinfo {
+   struct in6_addr ipi6_addr;  /* src/dst IPv6 address */
+   unsigned int ipi6_ifindex;  /* send/recv interface index */
+};
+
+static void rs_cleanup(struct rs_cb_data *data)
+{
+   g_io_channel_shutdown(data-channel, TRUE, NULL);
+   g_io_channel_unref(data-channel);
+   data-channel = 0;
+
+   if (data-rs_timeout  0)
+   g_source_remove(data-rs_timeout);
+
+   g_free(data);
+}
+
+static gboolean rs_timeout_cb(gpointer user_data)
+{
+   struct rs_cb_data *data = user_data;
+
+   DBG(user data %p, user_data);
+
+   if (data == NULL)
+   return FALSE;
+
+   if (data-callback != NULL)
+   data-callback(NULL, data-user_data);
+
+   data-rs_timeout = 0;
+   rs_cleanup(data);
+   return FALSE;
+}
+
+static int icmpv6_recv(int fd, gpointer user_data)
+{
+   struct msghdr mhdr;
+   struct iovec iov;
+   unsigned char chdr[CMSG_BUF_LEN];
+   unsigned char buf[1540];
+   struct rs_cb_data *data = user_data;
+   struct nd_router_advert *hdr;
+   struct sockaddr_in6 saddr;
+   ssize_t len;
+
+   DBG();
+
+   iov.iov_len = sizeof(buf);
+   iov.iov_base = buf;
+
+   mhdr.msg_name = (void *)saddr;
+   mhdr.msg_namelen = sizeof(struct sockaddr_in6);
+   mhdr.msg_iov = iov;
+   mhdr.msg_iovlen = 1;
+   mhdr.msg_control = (void *)chdr;
+   mhdr.msg_controllen = CMSG_BUF_LEN;
+
+   len = recvmsg(fd, mhdr, 0);
+   if (len  0) {
+   data-callback(NULL, data-user_data);
+   return -errno;
+   }
+
+   hdr = (struct nd_router_advert *)buf;
+   if (hdr-nd_ra_code != 0)
+   return 0;
+
+   data-callback(hdr, data-user_data);
+   rs_cleanup(data);
+
+   return len;
+}
+
+static gboolean icmpv6_event(GIOChannel *chan, GIOCondition cond,
+   gpointer data)
+{
+   int fd, ret;
+
+   DBG();
+
+   if (cond  (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
+   return FALSE;
+
+   fd = g_io_channel_unix_get_fd(chan);
+   ret = icmpv6_recv(fd, data);
+   if (ret == 0)
+   return TRUE;
+
+   return FALSE;
+}
+
+/* Adapted from RFC 1071 C Implementation Example */
+static uint16_t csum(const void *phdr, const void *data, socklen_t datalen)
+{
+   register unsigned long sum = 0;
+   socklen_t count;
+   uint16_t *addr;
+   int i;
+
+   /* caller must make sure datalen is even */
+
+   addr = (uint16_t *)phdr;
+  

[PATCH 6to4 v5 1/9] doc: Add description about 6to4 tunnelling.

2011-03-17 Thread Jukka Rissanen
---
 doc/service-api.txt |6 +-
 1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/doc/service-api.txt b/doc/service-api.txt
index 65554a2..7e87e6e 100644
--- a/doc/service-api.txt
+++ b/doc/service-api.txt
@@ -347,12 +347,16 @@ Propertiesstring State [readonly]
 
string Method [readonly]
 
-   Possible values are auto, manual
+   Possible values are auto, manual, 6to4
and off.
 
The value fixed indicates an IP address
that can not be modified. For example
cellular networks return fixed information.
+   The value 6to4 is returned if 6to4 tunnel
+   is created by connman. The tunnel can only be
+   created if method was set to auto by the
+   user. User cannot set the method to 6to4.
 
string Address [readonly]
 
-- 
1.7.0.4

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH 6to4 v5 5/9] 6to4: Add 6to4 tunnel support.

2011-03-17 Thread Jukka Rissanen
---
 Makefile.am   |2 +-
 src/6to4.c|  498 +
 src/connman.h |3 +
 3 files changed, 502 insertions(+), 1 deletions(-)
 create mode 100644 src/6to4.c

diff --git a/Makefile.am b/Makefile.am
index 3ad1ee9..95aefc7 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -77,7 +77,7 @@ src_connmand_SOURCES = $(gdbus_sources) $(gdhcp_sources) \
src/wifi.c src/storage.c src/dbus.c src/config.c \
src/technology.c src/counter.c src/location.c \
src/session.c src/tethering.c src/wpad.c src/wispr.c \
-   src/stats.c src/iptables.c src/dnsproxy.c
+   src/stats.c src/iptables.c src/dnsproxy.c src/6to4.c
 
 src_connmand_LDADD = $(builtin_libadd) @GLIB_LIBS@ @DBUS_LIBS@ \
@CAPNG_LIBS@ @XTABLES_LIBS@ -lresolv -ldl
diff --git a/src/6to4.c b/src/6to4.c
new file mode 100644
index 000..68472e6
--- /dev/null
+++ b/src/6to4.c
@@ -0,0 +1,498 @@
+/*
+ *
+ *  Connection Manager
+ *
+ *  Copyright (C) 2011  Nokia Corporation. All rights reserved.
+ *
+ *  Portions copyright by Alexey Kuznetsov et al. from iproute2 package.
+ *
+ *  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 string.h
+#include sys/socket.h
+#include netinet/in.h
+#include arpa/inet.h
+#include net/if.h
+#include linux/ip.h
+#include linux/if_tunnel.h
+#include linux/netlink.h
+#include linux/rtnetlink.h
+#include sys/ioctl.h
+#include unistd.h
+
+#include connman.h
+#include connman/log.h
+#include connman/ipconfig.h
+
+static int tunnel_created;
+static int tunnel_pending;
+static char *tunnel_ip_address;
+
+#define NLMSG_TAIL(nmsg) \
+   ((struct rtattr *) (((void *)(nmsg)) + NLMSG_ALIGN((nmsg)-nlmsg_len)))
+
+#ifndef IP_DF
+#define IP_DF  0x4000  /* Flag: Don't Fragment   */
+#endif
+
+struct rtnl_handle {
+   int fd;
+   struct sockaddr_nl  local;
+   struct sockaddr_nl  peer;
+   __u32   seq;
+   __u32   dump;
+};
+
+static int addattr32(struct nlmsghdr *n, int maxlen, int type, __u32 data)
+{
+   int len = RTA_LENGTH(4);
+   struct rtattr *rta;
+   if (NLMSG_ALIGN(n-nlmsg_len) + len  (unsigned int)maxlen) {
+   DBG(Error! max allowed bound %d exceeded, maxlen);
+   return -1;
+   }
+   rta = NLMSG_TAIL(n);
+   rta-rta_type = type;
+   rta-rta_len = len;
+   memcpy(RTA_DATA(rta), data, 4);
+   n-nlmsg_len = NLMSG_ALIGN(n-nlmsg_len) + len;
+
+   return 0;
+}
+
+static int addattr_l(struct nlmsghdr *n, int maxlen, int type,
+   const void *data, int alen)
+{
+   int len = RTA_LENGTH(alen);
+   struct rtattr *rta;
+
+   if (NLMSG_ALIGN(n-nlmsg_len) + RTA_ALIGN(len) 
+   (unsigned int)maxlen) {
+   DBG(addattr_l message exceeded bound of %d, maxlen);
+   return -1;
+   }
+   rta = NLMSG_TAIL(n);
+   rta-rta_type = type;
+   rta-rta_len = len;
+   memcpy(RTA_DATA(rta), data, alen);
+   n-nlmsg_len = NLMSG_ALIGN(n-nlmsg_len) + RTA_ALIGN(len);
+
+   return 0;
+}
+
+static void rtnl_close(struct rtnl_handle *rth)
+{
+   if (rth-fd = 0) {
+   close(rth-fd);
+   rth-fd = -1;
+   }
+}
+
+static int rtnl_open(struct rtnl_handle *rth)
+{
+   socklen_t addr_len;
+   int sndbuf = 1024;
+
+   memset(rth, 0, sizeof(*rth));
+
+   rth-fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+   if (rth-fd  0) {
+   connman_error(Can not open netlink socket: %s,
+   strerror(errno));
+   return -1;
+   }
+
+   if (setsockopt(rth-fd, SOL_SOCKET, SO_SNDBUF, sndbuf,
+   sizeof(sndbuf))  0) {
+   connman_error(SO_SNDBUF: %s, strerror(errno));
+   return -1;
+   }
+
+   memset(rth-local, 0, sizeof(rth-local));
+   rth-local.nl_family = AF_NETLINK;
+   rth-local.nl_groups = 0;
+
+   if (bind(rth-fd, (struct sockaddr *)rth-local,
+   sizeof(rth-local))  0) {
+   connman_error(Can not bind 

[PATCH 6to4 v5 6/9] 6to4: Check the connectivity via tunnel after creating it.

2011-03-17 Thread Jukka Rissanen
---
 src/6to4.c |   47 ++-
 1 files changed, 46 insertions(+), 1 deletions(-)

diff --git a/src/6to4.c b/src/6to4.c
index 68472e6..52a0c53 100644
--- a/src/6to4.c
+++ b/src/6to4.c
@@ -41,10 +41,15 @@
 #include connman.h
 #include connman/log.h
 #include connman/ipconfig.h
+#include gweb/gweb.h
 
 static int tunnel_created;
 static int tunnel_pending;
 static char *tunnel_ip_address;
+static GWeb *web;
+static guint web_request_id;
+
+#define STATUS_URL http://ipv6.google.com/;
 
 #define NLMSG_TAIL(nmsg) \
((struct rtattr *) (((void *)(nmsg)) + NLMSG_ALIGN((nmsg)-nlmsg_len)))
@@ -359,6 +364,35 @@ done:
return ret;
 }
 
+static gboolean unref_web(gpointer user_data)
+{
+   g_web_unref(web);
+   return FALSE;
+}
+
+static gboolean web_result(GWebResult *result, gpointer user_data)
+{
+   guint16 status;
+
+   if (web_request_id == 0)
+   return FALSE;
+
+   status = g_web_result_get_status(result);
+
+   DBG(status %u, status);
+
+   if (status = 400  status  500)
+   tunnel_destroy();
+   else
+   tunnel_pending = 0;
+
+   web_request_id = 0;
+
+   g_timeout_add_seconds(1, unref_web, NULL);
+
+   return FALSE;
+}
+
 static int init_6to4(struct in_addr *ip4addr)
 {
unsigned int a, b, c, d;
@@ -392,7 +426,18 @@ static int init_6to4(struct in_addr *ip4addr)
if (ret)
goto error;
 
-   tunnel_pending = 0;
+   /* We try to verify that connectivity through tunnel works ok.
+*/
+   web = g_web_new(0);
+   if (web == NULL)
+   goto error;
+
+   g_web_set_accept(web, NULL);
+   g_web_set_user_agent(web, ConnMan/%s, VERSION);
+   g_web_set_close_connection(web, TRUE);
+
+   web_request_id = g_web_request_get(web, STATUS_URL, web_result, NULL);
+
return 0;
 
 error:
-- 
1.7.0.4

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH 6to4 v5 4/9] gweb: Add support for connecting to IPv6 host.

2011-03-17 Thread Jukka Rissanen
---
 gweb/gweb.c |   29 -
 1 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/gweb/gweb.c b/gweb/gweb.c
index f3c8a7e..1bb1c70 100644
--- a/gweb/gweb.c
+++ b/gweb/gweb.c
@@ -31,6 +31,7 @@
 #include string.h
 #include sys/socket.h
 #include arpa/inet.h
+#include netdb.h
 
 #include giognutls.h
 #include gresolv.h
@@ -63,6 +64,7 @@ struct web_session {
char *host;
uint16_t port;
unsigned long flags;
+   struct addrinfo *addr;
 
char *content_type;
 
@@ -168,6 +170,9 @@ static void free_session(struct web_session *session)
 
g_free(session-host);
g_free(session-address);
+   if (session-addr != NULL)
+   freeaddrinfo(session-addr);
+
g_free(session);
 }
 
@@ -881,10 +886,9 @@ static gboolean received_data(GIOChannel *channel, 
GIOCondition cond,
 static int connect_session_transport(struct web_session *session)
 {
GIOFlags flags;
-   struct sockaddr_in sin;
int sk;
 
-   sk = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+   sk = socket(session-addr-ai_family, SOCK_STREAM, IPPROTO_TCP);
if (sk  0)
return -EIO;
 
@@ -910,12 +914,8 @@ static int connect_session_transport(struct web_session 
*session)
 
g_io_channel_set_close_on_unref(session-transport_channel, TRUE);
 
-   memset(sin, 0, sizeof(sin));
-   sin.sin_family = AF_INET;
-   sin.sin_port = htons(session-port);
-   sin.sin_addr.s_addr = inet_addr(session-address);
-
-   if (connect(sk, (struct sockaddr *) sin, sizeof(sin))  0) {
+   if (connect(sk, session-addr-ai_addr,
+   session-addr-ai_addrlen)  0) {
if (errno != EINPROGRESS) {
close(sk);
return -EIO;
@@ -1048,6 +1048,8 @@ static void resolv_result(GResolvResultStatus status,
char **results, gpointer user_data)
 {
struct web_session *session = user_data;
+   struct addrinfo hints;
+   int ret;
 
if (results == NULL || results[0] == NULL) {
call_result_func(session, 404);
@@ -1056,7 +1058,16 @@ static void resolv_result(GResolvResultStatus status,
 
debug(session-web, address %s, results[0]);
 
-   if (inet_aton(results[0], NULL) == 0) {
+   memset(hints, 0, sizeof(struct addrinfo));
+   hints.ai_flags = AI_NUMERICHOST;
+
+   if (session-addr != NULL) {
+   freeaddrinfo(session-addr);
+   session-addr = NULL;
+   }
+
+   ret = getaddrinfo(results[0], NULL, hints, session-addr);
+   if (ret != 0 || session-addr == NULL) {
call_result_func(session, 400);
return;
}
-- 
1.7.0.4

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH 6to4 v5 7/9] service: Create/remove 6to4 tunnel.

2011-03-17 Thread Jukka Rissanen
---
 src/dhcp.c|4 
 src/service.c |2 ++
 2 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/src/dhcp.c b/src/dhcp.c
index 6fda67d..dd7c498 100644
--- a/src/dhcp.c
+++ b/src/dhcp.c
@@ -73,6 +73,8 @@ static void dhcp_invalid(struct connman_dhcp *dhcp)
if (ipconfig == NULL)
return;
 
+   __connman_6to4_remove(ipconfig);
+
__connman_service_set_domainname(service, NULL);
__connman_service_set_pac(service, NULL);
__connman_service_timeserver_remove(service, dhcp-timeserver);
@@ -211,6 +213,8 @@ static void lease_available_cb(GDHCPClient *dhcp_client, 
gpointer user_data)
 
dhcp_valid(dhcp);
 
+   __connman_6to4_probe(service);
+
g_free(address);
g_free(netmask);
g_free(gateway);
diff --git a/src/service.c b/src/service.c
index ece29fd..29d6af5 100644
--- a/src/service.c
+++ b/src/service.c
@@ -3875,6 +3875,8 @@ int __connman_service_disconnect(struct connman_service 
*service)
if (err  0  err != -EINPROGRESS)
return err;
 
+   __connman_6to4_remove(service-ipconfig_ipv4);
+
if (service-ipconfig_ipv4)
__connman_ipconfig_set_proxy_autoconfig(service-ipconfig_ipv4,
NULL);
-- 
1.7.0.4

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH 6to4 v5 8/9] 6to4: Check if the 6to4 tunnel is active or not.

2011-03-17 Thread Jukka Rissanen
---
 src/6to4.c|   20 
 src/connman.h |1 +
 2 files changed, 21 insertions(+), 0 deletions(-)

diff --git a/src/6to4.c b/src/6to4.c
index 52a0c53..8593e71 100644
--- a/src/6to4.c
+++ b/src/6to4.c
@@ -541,3 +541,23 @@ void __connman_6to4_remove(struct connman_ipconfig 
*ip4config)
if (tunnel_created)
tunnel_destroy();
 }
+
+int __connman_6to4_check(struct connman_ipconfig *ip4config)
+{
+   const char *address;
+
+   if (ip4config == NULL || tunnel_created == 0 ||
+   tunnel_pending == 1)
+   return -1;
+
+   DBG(tunnel ip address %s, tunnel_ip_address);
+
+   address = __connman_ipconfig_get_local(ip4config);
+   if (address == NULL)
+   return -1;
+
+   if (g_strcmp0(address, tunnel_ip_address) == 0)
+   return 1;
+
+   return 0;
+}
diff --git a/src/connman.h b/src/connman.h
index b3a45f0..a4ebbbe 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -639,3 +639,4 @@ void __connman_dnsproxy_flush(void);
 
 int __connman_6to4_probe(struct connman_service *service);
 void __connman_6to4_remove(struct connman_ipconfig *ipconfig);
+int __connman_6to4_check(struct connman_ipconfig *ipconfig);
-- 
1.7.0.4

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH 6to4 v5 9/9] service: Return 6to4 tunnel status to dbus caller.

2011-03-17 Thread Jukka Rissanen
---
 src/connman.h  |3 ++-
 src/ipconfig.c |9 -
 src/service.c  |3 ++-
 3 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/src/connman.h b/src/connman.h
index a4ebbbe..47f3c89 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -247,7 +247,8 @@ void __connman_ipconfig_append_ipv4(struct connman_ipconfig 
*ipconfig,
 void __connman_ipconfig_append_ipv4config(struct connman_ipconfig *ipconfig,
DBusMessageIter *iter);
 void __connman_ipconfig_append_ipv6(struct connman_ipconfig *ipconfig,
-   DBusMessageIter *iter);
+   DBusMessageIter *iter,
+   struct connman_ipconfig *ip4config);
 void __connman_ipconfig_append_ipv6config(struct connman_ipconfig *ipconfig,
DBusMessageIter *iter);
 int __connman_ipconfig_set_config(struct connman_ipconfig *ipconfig,
diff --git a/src/ipconfig.c b/src/ipconfig.c
index 9f0d5d9..15cc9ce 100644
--- a/src/ipconfig.c
+++ b/src/ipconfig.c
@@ -1693,7 +1693,8 @@ void __connman_ipconfig_append_ipv4(struct 
connman_ipconfig *ipconfig,
 }
 
 void __connman_ipconfig_append_ipv6(struct connman_ipconfig *ipconfig,
-   DBusMessageIter *iter)
+   DBusMessageIter *iter,
+   struct connman_ipconfig *ipconfig_ipv4)
 {
const char *str, *privacy;
 
@@ -1706,6 +1707,12 @@ void __connman_ipconfig_append_ipv6(struct 
connman_ipconfig *ipconfig,
if (str == NULL)
return;
 
+   if (ipconfig_ipv4 != NULL 
+   ipconfig-method == CONNMAN_IPCONFIG_METHOD_AUTO) {
+   if (__connman_6to4_check(ipconfig_ipv4) == 1)
+   str = 6to4;
+   }
+
connman_dbus_dict_append_basic(iter, Method, DBUS_TYPE_STRING, str);
 
if (ipconfig-system == NULL)
diff --git a/src/service.c b/src/service.c
index 29d6af5..36f7d64 100644
--- a/src/service.c
+++ b/src/service.c
@@ -1002,7 +1002,8 @@ static void append_ipv6(DBusMessageIter *iter, void 
*user_data)
return;
 
if (service-ipconfig_ipv6 != NULL)
-   __connman_ipconfig_append_ipv6(service-ipconfig_ipv6, iter);
+   __connman_ipconfig_append_ipv6(service-ipconfig_ipv6, iter,
+   service-ipconfig_ipv4);
 }
 
 static void append_ipv4config(DBusMessageIter *iter, void *user_data)
-- 
1.7.0.4

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


Re: [PATCH 6to4 v5 3/9] inet: Add routines to send IPv6 router solicitation message.

2011-03-17 Thread Jukka Rissanen
Hi Marcel,

On 17 March 2011 09:29, Marcel Holtmann mar...@holtmann.org wrote:
 Hi Jukka,

 diff --git a/src/inet.c b/src/inet.c
 index 858d34c..40d8a8d 100644
 --- a/src/inet.c
 +++ b/src/inet.c
 @@ -4,6 +4,10 @@
   *
   *  Copyright (C) 2007-2010  Intel Corporation. All rights reserved.
   *
 + *  Portions (IPv6 router solicitation handling from MIPL project) are
 + *  Copyright 2003-2005 Go-Core Project and 2003-2006 Helsinki University of
 + *  Technology
 + *
   *  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.

 what is the license of the code from Go-Core Project and Helsinki
 University? We need to ensure that it is compatible with GPLv2 license
 we use in ConnMan. Please provide pointers to the original code.

+ *  Portions (IPv6 router solicitation handling from MIPL project) are
+ *  Copyright 2003-2005 Go-Core Project and 2003-2006 Helsinki University of
+ *  Technology and have GPLv2 license. Original code can be found at
+ *  git://linux-ipv6.org/gitroot/mipv6-daemon.git or
+ *  
http://www.linux-ipv6.org/gitweb/gitweb.cgi?p=gitroot/mipv6-daemon.git;a=blob;f=src/ndisc.c
+ *

Would something like this be ok? The linux-ipv6.org git repo seems to
be corrupt as I cannot clone it but web interface still works.


Regards,
Jukka
___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


Re: [PATCH 6to4 v5 3/9] inet: Add routines to send IPv6 router solicitation message.

2011-03-18 Thread Jukka Rissanen
Hi Marcel,

On 17 March 2011 18:50, Marcel Holtmann mar...@holtmann.org wrote:
 Hi Jukka,

 you don't have to go this much over board with this. I just needed to
 double check by myself that we are GPLv2 compatible before going any
 further with this patch.

Ok, I just wanted to be exact :)

 Please have the origin note and a link to the file in the commit message
 of your patch for reference.

 And for the headers just add the appropriate copyright:

        * Copyright 2003-2005 Go-Core Project
        * Copyright 2003-2006 Helsinki University of Technology

 That is clearly enough for us.

Good, that is now done for inet.c and iproute2 stuff in 6to4.c

Samuel, should I send a new patchset version or should I wait if you
have any comments about the other patches in the set?


Regards,
Jukka
___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[6to4 v6 0/9] 6to4 tunneling support

2011-03-25 Thread Jukka Rissanen
Hi,

v6:
- copyright notice fixed in 6to4.c and inet.c (patches #3 and
  #5 fixed)
- IPv6 router solicitation function in inet.c is now available
  to connman core only (affects patches #3 and #5)

v5:
- the 6to4 tunnel status is returned via IPv6.Method (patch #9
  reworked)
- removed test script modifications (removed patch #10)
- doc updated (patch #1 updated)

v4:
- 6to4 tunnel setting in service is read only i.e., it cannot
  be manipulated via dbus any longer
- generic tunnel creation added to inet.c
- IPv6 router solicitation / advertisement handling in inet.c
- IPv6 support is added to gweb
- gweb is used when checking connectivity through tunnel
- tunnel is only created if we have a public IP address,
  the IPv6 is enabled and method is auto, we have not received
  autoconfigured ip address and internet connectivity via
  tunnel works ok

The patch set is only tested via simulation (by commenting out
various checks in the code) as I could not find such a crappy
network anywhere, so there might be some problems left in the code.

There is one issue when using gweb to check the connectivity via
tunnel. As the network interface to be used is not set in gweb,
we are just hoping that the routing in the device forces the check
go through tunnel.

Regards,
Jukka


Jukka Rissanen (9):
  doc: Add description about 6to4 tunnelling.
  inet: MTU and tunnel setup functions added.
  inet: Add routines to send IPv6 router solicitation message.
  gweb: Add support for connecting to IPv6 host.
  6to4: Add 6to4 tunnel support.
  6to4: Check the connectivity via tunnel after creating it.
  service: Create/remove 6to4 tunnel.
  6to4: Check if the 6to4 tunnel is active or not.
  service: Return 6to4 tunnel status to dbus caller.

 Makefile.am |2 +-
 doc/service-api.txt |6 +-
 gweb/gweb.c |   29 ++-
 include/inet.h  |3 +
 src/6to4.c  |  562 +++
 src/connman.h   |   16 ++-
 src/dhcp.c  |4 +
 src/inet.c  |  384 ++-
 src/ipconfig.c  |9 +-
 src/service.c   |5 +-
 10 files changed, 1004 insertions(+), 16 deletions(-)
 create mode 100644 src/6to4.c

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[6to4 v6 1/9] doc: Add description about 6to4 tunnelling.

2011-03-25 Thread Jukka Rissanen
---
 doc/service-api.txt |6 +-
 1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/doc/service-api.txt b/doc/service-api.txt
index 65554a2..7e87e6e 100644
--- a/doc/service-api.txt
+++ b/doc/service-api.txt
@@ -347,12 +347,16 @@ Propertiesstring State [readonly]
 
string Method [readonly]
 
-   Possible values are auto, manual
+   Possible values are auto, manual, 6to4
and off.
 
The value fixed indicates an IP address
that can not be modified. For example
cellular networks return fixed information.
+   The value 6to4 is returned if 6to4 tunnel
+   is created by connman. The tunnel can only be
+   created if method was set to auto by the
+   user. User cannot set the method to 6to4.
 
string Address [readonly]
 
-- 
1.7.0.4

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[6to4 v6 3/9] inet: Add routines to send IPv6 router solicitation message.

2011-03-25 Thread Jukka Rissanen
IPv6 router solicitation handling is from MIPL project.
Original code can be found at
git://linux-ipv6.org/gitroot/mipv6-daemon.git
and
http://www.linux-ipv6.org/gitweb/gitweb.cgi?p=gitroot/mipv6-daemon.git;a=blob;f=src/ndisc.c
---
 src/connman.h |9 ++
 src/inet.c|  313 +
 2 files changed, 322 insertions(+), 0 deletions(-)

diff --git a/src/connman.h b/src/connman.h
index 42bf2e6..6150064 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -110,6 +110,15 @@ int __connman_inet_modify_address(int cmd, int flags, int 
index, int family,
unsigned char prefixlen,
const char *broadcast);
 
+#include netinet/ip6.h
+#include netinet/icmp6.h
+
+typedef void (*__connman_inet_rs_cb_t) (struct nd_router_advert *reply,
+   void *user_data);
+
+int __connman_inet_ipv6_send_rs(int index, int timeout,
+   __connman_inet_rs_cb_t callback, void *user_data);
+
 #include connman/wifi.h
 
 #include connman/rfkill.h
diff --git a/src/inet.c b/src/inet.c
index 8609d9e..5e5d9cc 100644
--- a/src/inet.c
+++ b/src/inet.c
@@ -3,6 +3,8 @@
  *  Connection Manager
  *
  *  Copyright (C) 2007-2010  Intel Corporation. All rights reserved.
+ *  Copyright (C) 2003-2005  Go-Core Project
+ *  Copyright (C) 2003-2006  Helsinki University of Technology
  *
  *  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
@@ -37,6 +39,7 @@
 #include net/ethernet.h
 #include net/if.h
 #include net/if_arp.h
+#include netinet/icmp6.h
 
 #include connman.h
 
@@ -1261,3 +1264,313 @@ done:
close(sk);
return err;
 }
+
+struct rs_cb_data {
+   GIOChannel *channel;
+   __connman_inet_rs_cb_t callback;
+   struct sockaddr_in6 addr;
+   guint rs_timeout;
+   void *user_data;
+};
+
+#define CMSG_BUF_LEN 512
+#define IN6ADDR_ALL_NODES_MC_INIT \
+   { { { 0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,0x1 } } } /* ff02::1 */
+#define IN6ADDR_ALL_ROUTERS_MC_INIT \
+   { { { 0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,0x2 } } } /* ff02::2 */
+
+static const struct in6_addr in6addr_all_nodes_mc = IN6ADDR_ALL_NODES_MC_INIT;
+static const struct in6_addr in6addr_all_routers_mc =
+   IN6ADDR_ALL_ROUTERS_MC_INIT;
+
+/* from netinet/in.h */
+struct in6_pktinfo {
+   struct in6_addr ipi6_addr;  /* src/dst IPv6 address */
+   unsigned int ipi6_ifindex;  /* send/recv interface index */
+};
+
+static void rs_cleanup(struct rs_cb_data *data)
+{
+   g_io_channel_shutdown(data-channel, TRUE, NULL);
+   g_io_channel_unref(data-channel);
+   data-channel = 0;
+
+   if (data-rs_timeout  0)
+   g_source_remove(data-rs_timeout);
+
+   g_free(data);
+}
+
+static gboolean rs_timeout_cb(gpointer user_data)
+{
+   struct rs_cb_data *data = user_data;
+
+   DBG(user data %p, user_data);
+
+   if (data == NULL)
+   return FALSE;
+
+   if (data-callback != NULL)
+   data-callback(NULL, data-user_data);
+
+   data-rs_timeout = 0;
+   rs_cleanup(data);
+   return FALSE;
+}
+
+static int icmpv6_recv(int fd, gpointer user_data)
+{
+   struct msghdr mhdr;
+   struct iovec iov;
+   unsigned char chdr[CMSG_BUF_LEN];
+   unsigned char buf[1540];
+   struct rs_cb_data *data = user_data;
+   struct nd_router_advert *hdr;
+   struct sockaddr_in6 saddr;
+   ssize_t len;
+
+   DBG();
+
+   iov.iov_len = sizeof(buf);
+   iov.iov_base = buf;
+
+   mhdr.msg_name = (void *)saddr;
+   mhdr.msg_namelen = sizeof(struct sockaddr_in6);
+   mhdr.msg_iov = iov;
+   mhdr.msg_iovlen = 1;
+   mhdr.msg_control = (void *)chdr;
+   mhdr.msg_controllen = CMSG_BUF_LEN;
+
+   len = recvmsg(fd, mhdr, 0);
+   if (len  0) {
+   data-callback(NULL, data-user_data);
+   return -errno;
+   }
+
+   hdr = (struct nd_router_advert *)buf;
+   if (hdr-nd_ra_code != 0)
+   return 0;
+
+   data-callback(hdr, data-user_data);
+   rs_cleanup(data);
+
+   return len;
+}
+
+static gboolean icmpv6_event(GIOChannel *chan, GIOCondition cond,
+   gpointer data)
+{
+   int fd, ret;
+
+   DBG();
+
+   if (cond  (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
+   return FALSE;
+
+   fd = g_io_channel_unix_get_fd(chan);
+   ret = icmpv6_recv(fd, data);
+   if (ret == 0)
+   return TRUE;
+
+   return FALSE;
+}
+
+/* Adapted from RFC 1071 C Implementation Example */
+static uint16_t csum(const void *phdr, const void *data, socklen_t datalen)
+{
+   register unsigned long sum = 0;
+   socklen_t count;
+   uint16_t *addr;
+   int i;
+
+   /* caller must make sure datalen is even */

[6to4 v6 2/9] inet: MTU and tunnel setup functions added.

2011-03-25 Thread Jukka Rissanen
---
 include/inet.h |3 ++
 src/inet.c |   71 ++-
 2 files changed, 72 insertions(+), 2 deletions(-)

diff --git a/include/inet.h b/include/inet.h
index 9ba7781..9a9411d 100644
--- a/include/inet.h
+++ b/include/inet.h
@@ -73,6 +73,9 @@ int connman_inet_clear_ipv6_gateway_address(int index, const 
char *gateway);
 int connman_inet_add_to_bridge(int index, const char *bridge);
 int connman_inet_remove_from_bridge(int index, const char *bridge);
 
+int connman_inet_set_mtu(int index, int mtu);
+int connman_inet_setup_tunnel(char *tunnel, int mtu);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/inet.c b/src/inet.c
index fa768fb..8609d9e 100644
--- a/src/inet.c
+++ b/src/inet.c
@@ -35,8 +35,8 @@
 #include arpa/inet.h
 #include net/route.h
 #include net/ethernet.h
-#include linux/if_arp.h
-#include linux/wireless.h
+#include net/if.h
+#include net/if_arp.h
 
 #include connman.h
 
@@ -1194,3 +1194,70 @@ int connman_inet_add_to_bridge(int index, const char 
*bridge)
 
return 0;
 }
+
+int connman_inet_set_mtu(int index, int mtu)
+{
+   struct ifreq ifr;
+   int sk, err;
+
+   sk = socket(AF_INET, SOCK_DGRAM, 0);
+   if (sk  0)
+   return sk;
+
+   memset(ifr, 0, sizeof(ifr));
+   ifr.ifr_ifindex = index;
+
+   err = ioctl(sk, SIOCGIFNAME, ifr);
+   if (err == 0) {
+   ifr.ifr_mtu = mtu;
+   err = ioctl(sk, SIOCSIFMTU, ifr);
+   }
+
+   close(sk);
+   return err;
+}
+
+int connman_inet_setup_tunnel(char *tunnel, int mtu)
+{
+   struct ifreq ifr;
+   int sk, err, index;
+   __u32 mask;
+   __u32 flags;
+
+   if (tunnel == NULL)
+   return -EINVAL;
+
+   sk = socket(AF_INET, SOCK_DGRAM, 0);
+   if (sk  0)
+   return sk;
+
+   index = if_nametoindex(tunnel);
+
+   err = connman_inet_set_mtu(index, mtu);
+   if (err  0)
+   return err;
+   else if (err)
+   goto done;
+
+   memset(ifr, 0, sizeof(ifr));
+   strncpy(ifr.ifr_name, tunnel, IFNAMSIZ);
+   err = ioctl(sk, SIOCGIFFLAGS, ifr);
+   if (err)
+   goto done;
+
+   mask = IFF_UP;
+   flags = IFF_UP;
+
+   if ((ifr.ifr_flags ^ flags)  mask) {
+   ifr.ifr_flags = ~mask;
+   ifr.ifr_flags |= mask  flags;
+   err = ioctl(sk, SIOCSIFFLAGS, ifr);
+   if (err)
+   connman_error(SIOCSIFFLAGS failed: %s,
+   strerror(errno));
+   }
+
+done:
+   close(sk);
+   return err;
+}
-- 
1.7.0.4

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[6to4 v6 4/9] gweb: Add support for connecting to IPv6 host.

2011-03-25 Thread Jukka Rissanen
---
 gweb/gweb.c |   29 -
 1 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/gweb/gweb.c b/gweb/gweb.c
index f3c8a7e..1bb1c70 100644
--- a/gweb/gweb.c
+++ b/gweb/gweb.c
@@ -31,6 +31,7 @@
 #include string.h
 #include sys/socket.h
 #include arpa/inet.h
+#include netdb.h
 
 #include giognutls.h
 #include gresolv.h
@@ -63,6 +64,7 @@ struct web_session {
char *host;
uint16_t port;
unsigned long flags;
+   struct addrinfo *addr;
 
char *content_type;
 
@@ -168,6 +170,9 @@ static void free_session(struct web_session *session)
 
g_free(session-host);
g_free(session-address);
+   if (session-addr != NULL)
+   freeaddrinfo(session-addr);
+
g_free(session);
 }
 
@@ -881,10 +886,9 @@ static gboolean received_data(GIOChannel *channel, 
GIOCondition cond,
 static int connect_session_transport(struct web_session *session)
 {
GIOFlags flags;
-   struct sockaddr_in sin;
int sk;
 
-   sk = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+   sk = socket(session-addr-ai_family, SOCK_STREAM, IPPROTO_TCP);
if (sk  0)
return -EIO;
 
@@ -910,12 +914,8 @@ static int connect_session_transport(struct web_session 
*session)
 
g_io_channel_set_close_on_unref(session-transport_channel, TRUE);
 
-   memset(sin, 0, sizeof(sin));
-   sin.sin_family = AF_INET;
-   sin.sin_port = htons(session-port);
-   sin.sin_addr.s_addr = inet_addr(session-address);
-
-   if (connect(sk, (struct sockaddr *) sin, sizeof(sin))  0) {
+   if (connect(sk, session-addr-ai_addr,
+   session-addr-ai_addrlen)  0) {
if (errno != EINPROGRESS) {
close(sk);
return -EIO;
@@ -1048,6 +1048,8 @@ static void resolv_result(GResolvResultStatus status,
char **results, gpointer user_data)
 {
struct web_session *session = user_data;
+   struct addrinfo hints;
+   int ret;
 
if (results == NULL || results[0] == NULL) {
call_result_func(session, 404);
@@ -1056,7 +1058,16 @@ static void resolv_result(GResolvResultStatus status,
 
debug(session-web, address %s, results[0]);
 
-   if (inet_aton(results[0], NULL) == 0) {
+   memset(hints, 0, sizeof(struct addrinfo));
+   hints.ai_flags = AI_NUMERICHOST;
+
+   if (session-addr != NULL) {
+   freeaddrinfo(session-addr);
+   session-addr = NULL;
+   }
+
+   ret = getaddrinfo(results[0], NULL, hints, session-addr);
+   if (ret != 0 || session-addr == NULL) {
call_result_func(session, 400);
return;
}
-- 
1.7.0.4

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[6to4 v6 5/9] 6to4: Add 6to4 tunnel support.

2011-03-25 Thread Jukka Rissanen
Netlink support routines taken from iproute2 package.
Iproute2 source code can be found at
git://git.kernel.org/pub/scm/linux/kernel/git/shemminger/iproute2.git
---
 Makefile.am   |2 +-
 src/6to4.c|  497 +
 src/connman.h |3 +
 3 files changed, 501 insertions(+), 1 deletions(-)
 create mode 100644 src/6to4.c

diff --git a/Makefile.am b/Makefile.am
index 3ad1ee9..95aefc7 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -77,7 +77,7 @@ src_connmand_SOURCES = $(gdbus_sources) $(gdhcp_sources) \
src/wifi.c src/storage.c src/dbus.c src/config.c \
src/technology.c src/counter.c src/location.c \
src/session.c src/tethering.c src/wpad.c src/wispr.c \
-   src/stats.c src/iptables.c src/dnsproxy.c
+   src/stats.c src/iptables.c src/dnsproxy.c src/6to4.c
 
 src_connmand_LDADD = $(builtin_libadd) @GLIB_LIBS@ @DBUS_LIBS@ \
@CAPNG_LIBS@ @XTABLES_LIBS@ -lresolv -ldl
diff --git a/src/6to4.c b/src/6to4.c
new file mode 100644
index 000..767c866
--- /dev/null
+++ b/src/6to4.c
@@ -0,0 +1,497 @@
+/*
+ *
+ *  Connection Manager
+ *
+ *  Copyright (C) 2011  Nokia Corporation. All rights reserved.
+ *  Copyright (C) Alexey Kuznetsov et al. from iproute2 package.
+ *
+ *  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 string.h
+#include sys/socket.h
+#include netinet/in.h
+#include arpa/inet.h
+#include net/if.h
+#include linux/ip.h
+#include linux/if_tunnel.h
+#include linux/netlink.h
+#include linux/rtnetlink.h
+#include sys/ioctl.h
+#include unistd.h
+
+#include connman.h
+#include connman/log.h
+#include connman/ipconfig.h
+
+static int tunnel_created;
+static int tunnel_pending;
+static char *tunnel_ip_address;
+
+#define NLMSG_TAIL(nmsg) \
+   ((struct rtattr *) (((void *)(nmsg)) + NLMSG_ALIGN((nmsg)-nlmsg_len)))
+
+#ifndef IP_DF
+#define IP_DF  0x4000  /* Flag: Don't Fragment   */
+#endif
+
+struct rtnl_handle {
+   int fd;
+   struct sockaddr_nl  local;
+   struct sockaddr_nl  peer;
+   __u32   seq;
+   __u32   dump;
+};
+
+static int addattr32(struct nlmsghdr *n, int maxlen, int type, __u32 data)
+{
+   int len = RTA_LENGTH(4);
+   struct rtattr *rta;
+   if (NLMSG_ALIGN(n-nlmsg_len) + len  (unsigned int)maxlen) {
+   DBG(Error! max allowed bound %d exceeded, maxlen);
+   return -1;
+   }
+   rta = NLMSG_TAIL(n);
+   rta-rta_type = type;
+   rta-rta_len = len;
+   memcpy(RTA_DATA(rta), data, 4);
+   n-nlmsg_len = NLMSG_ALIGN(n-nlmsg_len) + len;
+
+   return 0;
+}
+
+static int addattr_l(struct nlmsghdr *n, int maxlen, int type,
+   const void *data, int alen)
+{
+   int len = RTA_LENGTH(alen);
+   struct rtattr *rta;
+
+   if (NLMSG_ALIGN(n-nlmsg_len) + RTA_ALIGN(len) 
+   (unsigned int)maxlen) {
+   DBG(addattr_l message exceeded bound of %d, maxlen);
+   return -1;
+   }
+   rta = NLMSG_TAIL(n);
+   rta-rta_type = type;
+   rta-rta_len = len;
+   memcpy(RTA_DATA(rta), data, alen);
+   n-nlmsg_len = NLMSG_ALIGN(n-nlmsg_len) + RTA_ALIGN(len);
+
+   return 0;
+}
+
+static void rtnl_close(struct rtnl_handle *rth)
+{
+   if (rth-fd = 0) {
+   close(rth-fd);
+   rth-fd = -1;
+   }
+}
+
+static int rtnl_open(struct rtnl_handle *rth)
+{
+   socklen_t addr_len;
+   int sndbuf = 1024;
+
+   memset(rth, 0, sizeof(*rth));
+
+   rth-fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+   if (rth-fd  0) {
+   connman_error(Can not open netlink socket: %s,
+   strerror(errno));
+   return -1;
+   }
+
+   if (setsockopt(rth-fd, SOL_SOCKET, SO_SNDBUF, sndbuf,
+   sizeof(sndbuf))  0) {
+   connman_error(SO_SNDBUF: %s, strerror(errno));
+   return -1;
+   }
+
+   memset(rth-local, 0, sizeof(rth-local));
+   rth-local.nl_family = AF_NETLINK;
+   rth-local.nl_groups = 0;
+

[6to4 v6 6/9] 6to4: Check the connectivity via tunnel after creating it.

2011-03-25 Thread Jukka Rissanen
---
 src/6to4.c |   47 ++-
 1 files changed, 46 insertions(+), 1 deletions(-)

diff --git a/src/6to4.c b/src/6to4.c
index 767c866..e6815a0 100644
--- a/src/6to4.c
+++ b/src/6to4.c
@@ -40,10 +40,15 @@
 #include connman.h
 #include connman/log.h
 #include connman/ipconfig.h
+#include gweb/gweb.h
 
 static int tunnel_created;
 static int tunnel_pending;
 static char *tunnel_ip_address;
+static GWeb *web;
+static guint web_request_id;
+
+#define STATUS_URL http://ipv6.google.com/;
 
 #define NLMSG_TAIL(nmsg) \
((struct rtattr *) (((void *)(nmsg)) + NLMSG_ALIGN((nmsg)-nlmsg_len)))
@@ -358,6 +363,35 @@ done:
return ret;
 }
 
+static gboolean unref_web(gpointer user_data)
+{
+   g_web_unref(web);
+   return FALSE;
+}
+
+static gboolean web_result(GWebResult *result, gpointer user_data)
+{
+   guint16 status;
+
+   if (web_request_id == 0)
+   return FALSE;
+
+   status = g_web_result_get_status(result);
+
+   DBG(status %u, status);
+
+   if (status = 400  status  500)
+   tunnel_destroy();
+   else
+   tunnel_pending = 0;
+
+   web_request_id = 0;
+
+   g_timeout_add_seconds(1, unref_web, NULL);
+
+   return FALSE;
+}
+
 static int init_6to4(struct in_addr *ip4addr)
 {
unsigned int a, b, c, d;
@@ -391,7 +425,18 @@ static int init_6to4(struct in_addr *ip4addr)
if (ret)
goto error;
 
-   tunnel_pending = 0;
+   /* We try to verify that connectivity through tunnel works ok.
+*/
+   web = g_web_new(0);
+   if (web == NULL)
+   goto error;
+
+   g_web_set_accept(web, NULL);
+   g_web_set_user_agent(web, ConnMan/%s, VERSION);
+   g_web_set_close_connection(web, TRUE);
+
+   web_request_id = g_web_request_get(web, STATUS_URL, web_result, NULL);
+
return 0;
 
 error:
-- 
1.7.0.4

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[6to4 v6 7/9] service: Create/remove 6to4 tunnel.

2011-03-25 Thread Jukka Rissanen
---
 src/dhcp.c|4 
 src/service.c |2 ++
 2 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/src/dhcp.c b/src/dhcp.c
index 3106c3d..03a2b90 100644
--- a/src/dhcp.c
+++ b/src/dhcp.c
@@ -73,6 +73,8 @@ static void dhcp_invalid(struct connman_dhcp *dhcp)
if (ipconfig == NULL)
return;
 
+   __connman_6to4_remove(ipconfig);
+
__connman_service_set_domainname(service, NULL);
__connman_service_set_pac(service, NULL);
__connman_service_timeserver_remove(service, dhcp-timeserver);
@@ -289,6 +291,8 @@ static void lease_available_cb(GDHCPClient *dhcp_client, 
gpointer user_data)
if (ip_change == TRUE)
dhcp_valid(dhcp);
 
+   __connman_6to4_probe(service);
+
g_free(address);
g_free(netmask);
g_free(gateway);
diff --git a/src/service.c b/src/service.c
index f4b15f0..b147551 100644
--- a/src/service.c
+++ b/src/service.c
@@ -3887,6 +3887,8 @@ int __connman_service_disconnect(struct connman_service 
*service)
if (err  0  err != -EINPROGRESS)
return err;
 
+   __connman_6to4_remove(service-ipconfig_ipv4);
+
if (service-ipconfig_ipv4)
__connman_ipconfig_set_proxy_autoconfig(service-ipconfig_ipv4,
NULL);
-- 
1.7.0.4

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[6to4 v6 8/9] 6to4: Check if the 6to4 tunnel is active or not.

2011-03-25 Thread Jukka Rissanen
---
 src/6to4.c|   20 
 src/connman.h |1 +
 2 files changed, 21 insertions(+), 0 deletions(-)

diff --git a/src/6to4.c b/src/6to4.c
index e6815a0..3877bfb 100644
--- a/src/6to4.c
+++ b/src/6to4.c
@@ -540,3 +540,23 @@ void __connman_6to4_remove(struct connman_ipconfig 
*ip4config)
if (tunnel_created)
tunnel_destroy();
 }
+
+int __connman_6to4_check(struct connman_ipconfig *ip4config)
+{
+   const char *address;
+
+   if (ip4config == NULL || tunnel_created == 0 ||
+   tunnel_pending == 1)
+   return -1;
+
+   DBG(tunnel ip address %s, tunnel_ip_address);
+
+   address = __connman_ipconfig_get_local(ip4config);
+   if (address == NULL)
+   return -1;
+
+   if (g_strcmp0(address, tunnel_ip_address) == 0)
+   return 1;
+
+   return 0;
+}
diff --git a/src/connman.h b/src/connman.h
index 1ca73ed..d466b21 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -648,3 +648,4 @@ void __connman_dnsproxy_flush(void);
 
 int __connman_6to4_probe(struct connman_service *service);
 void __connman_6to4_remove(struct connman_ipconfig *ipconfig);
+int __connman_6to4_check(struct connman_ipconfig *ipconfig);
-- 
1.7.0.4

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[6to4 v6 9/9] service: Return 6to4 tunnel status to dbus caller.

2011-03-25 Thread Jukka Rissanen
---
 src/connman.h  |3 ++-
 src/ipconfig.c |9 -
 src/service.c  |3 ++-
 3 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/src/connman.h b/src/connman.h
index d466b21..01dca1b 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -256,7 +256,8 @@ void __connman_ipconfig_append_ipv4(struct connman_ipconfig 
*ipconfig,
 void __connman_ipconfig_append_ipv4config(struct connman_ipconfig *ipconfig,
DBusMessageIter *iter);
 void __connman_ipconfig_append_ipv6(struct connman_ipconfig *ipconfig,
-   DBusMessageIter *iter);
+   DBusMessageIter *iter,
+   struct connman_ipconfig *ip4config);
 void __connman_ipconfig_append_ipv6config(struct connman_ipconfig *ipconfig,
DBusMessageIter *iter);
 int __connman_ipconfig_set_config(struct connman_ipconfig *ipconfig,
diff --git a/src/ipconfig.c b/src/ipconfig.c
index 0599a73..22dd03b 100644
--- a/src/ipconfig.c
+++ b/src/ipconfig.c
@@ -1701,7 +1701,8 @@ void __connman_ipconfig_append_ipv4(struct 
connman_ipconfig *ipconfig,
 }
 
 void __connman_ipconfig_append_ipv6(struct connman_ipconfig *ipconfig,
-   DBusMessageIter *iter)
+   DBusMessageIter *iter,
+   struct connman_ipconfig *ipconfig_ipv4)
 {
const char *str, *privacy;
 
@@ -1714,6 +1715,12 @@ void __connman_ipconfig_append_ipv6(struct 
connman_ipconfig *ipconfig,
if (str == NULL)
return;
 
+   if (ipconfig_ipv4 != NULL 
+   ipconfig-method == CONNMAN_IPCONFIG_METHOD_AUTO) {
+   if (__connman_6to4_check(ipconfig_ipv4) == 1)
+   str = 6to4;
+   }
+
connman_dbus_dict_append_basic(iter, Method, DBUS_TYPE_STRING, str);
 
if (ipconfig-system == NULL)
diff --git a/src/service.c b/src/service.c
index b147551..ae1f6fd 100644
--- a/src/service.c
+++ b/src/service.c
@@ -1002,7 +1002,8 @@ static void append_ipv6(DBusMessageIter *iter, void 
*user_data)
return;
 
if (service-ipconfig_ipv6 != NULL)
-   __connman_ipconfig_append_ipv6(service-ipconfig_ipv6, iter);
+   __connman_ipconfig_append_ipv6(service-ipconfig_ipv6, iter,
+   service-ipconfig_ipv4);
 }
 
 static void append_ipv4config(DBusMessageIter *iter, void *user_data)
-- 
1.7.0.4

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH ipv6 gw 00/13] ipv6 gw: Fix route and gateway handling for IPv6

2011-06-20 Thread Jukka Rissanen
Hi,

here are some patches to fix route and gateway handling for static
and autoconfigured IPv6 addresses.

Description of patches:

01 - Error print enhancement
02,03 - Very minor indentation fixes
04 - Functions for setting and clearing IPv6 gateway address,
 needed by patch #07
05 - Set routes to IPv6 nameservers properly
06 - Association state was not set for IPv6
07 - Fix gateway handling for IPv6
08 - Setup gateways for manual IPv6 configs
09 - Added function to remove IP address from interface without
 removing the address from internal structures.
 This is needed by patch #10
10 - Remove address from interface
11 - Enable IPv6 support function. This is needed by patch #12
12 - Remove IPv6 autoconfigured addresses and routes by disabling IPv6
 temporarily. This is done so that kernel can do the hard work for
 us as it will remove all autoconfigured address automagically
 when IPv6 is disabled.
13 - Mark the IPv6 gateway handling as done


Jukka


Jukka Rissanen (13):
  inet: Changed error prints to print the error string.
  inet: Fixed indentation.
  service: Fixed indentation.
  inet: Added support functions for setting and clearing IPv6 gateway
address.
  service: Set and clear IPv6 nameserver addresses properly.
  network: Add IPv6 associating state.
  connection: Separate IPv4 and IPv6 gateway and routing handling.
  network: Set manual IPv6 state and gateway.
  ipconfig: Added function to remove address from interface.
  network: Clear interface addresses after removing gateway address.
  ipconfig: Added function to enable IPv6.
  network: Clear IPv6 autoconfigured routes when disconnected.
  TODO: IPv6 gateway handling done.

 TODO   |   10 -
 include/inet.h |2 +
 include/ipconfig.h |2 +
 src/connection.c   |  495 
 src/connman.h  |   12 +-
 src/inet.c |  106 +++-
 src/ipconfig.c |   56 +--
 src/network.c  |   43 -
 src/service.c  |   56 +-
 9 files changed, 624 insertions(+), 158 deletions(-)

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH ipv6 gw 01/13] inet: Changed error prints to print the error string.

2011-06-20 Thread Jukka Rissanen
---
 src/inet.c |   12 
 1 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/src/inet.c b/src/inet.c
index e3adb7e..c55af06 100644
--- a/src/inet.c
+++ b/src/inet.c
@@ -783,7 +783,8 @@ int connman_inet_del_ipv6_network_route(int index, const 
char *host,
close(sk);
 out:
if (err  0)
-   connman_error(Del IPv6 host route error);
+   connman_error(Del IPv6 host route error (%s),
+   strerror(errno));
 
return err;
 }
@@ -833,7 +834,8 @@ int connman_inet_add_ipv6_network_route(int index, const 
char *host,
close(sk);
 out:
if (err  0)
-   connman_error(Set IPv6 host route error);
+   connman_error(Set IPv6 host route error (%s),
+   strerror(errno));
 
return err;
 }
@@ -875,7 +877,8 @@ int connman_inet_set_ipv6_gateway_address(int index, const 
char *gateway)
close(sk);
 out:
if (err  0)
-   connman_error(Set default IPv6 gateway error);
+   connman_error(Set default IPv6 gateway error (%s),
+   strerror(errno));
 
return err;
 }
@@ -911,7 +914,8 @@ int connman_inet_clear_ipv6_gateway_address(int index, 
const char *gateway)
close(sk);
 out:
if (err  0)
-   connman_error(Clear default IPv6 gateway error);
+   connman_error(Clear default IPv6 gateway error (%s),
+   strerror(errno));
 
return err;
 }
-- 
1.7.1

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH ipv6 gw 02/13] inet: Fixed indentation.

2011-06-20 Thread Jukka Rissanen
---
 src/inet.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/src/inet.c b/src/inet.c
index c55af06..05ead31 100644
--- a/src/inet.c
+++ b/src/inet.c
@@ -796,7 +796,7 @@ int connman_inet_del_ipv6_host_route(int index, const char 
*host)
 
 int connman_inet_add_ipv6_network_route(int index, const char *host,
const char *gateway,
-   unsigned char prefix_len)
+   unsigned char prefix_len)
 {
struct in6_rtmsg rt;
int sk, err;
-- 
1.7.1

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH ipv6 gw 06/13] network: Add IPv6 associating state.

2011-06-20 Thread Jukka Rissanen
---
 src/network.c |3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/src/network.c b/src/network.c
index 88b8ad8..1693109 100644
--- a/src/network.c
+++ b/src/network.c
@@ -657,6 +657,9 @@ int connman_network_set_associating(struct connman_network 
*network,
__connman_service_indicate_state(service,
CONNMAN_SERVICE_STATE_ASSOCIATION,
CONNMAN_IPCONFIG_TYPE_IPV4);
+   __connman_service_indicate_state(service,
+   CONNMAN_SERVICE_STATE_ASSOCIATION,
+   CONNMAN_IPCONFIG_TYPE_IPV6);
}
 
return 0;
-- 
1.7.1

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH ipv6 gw 05/13] service: Set and clear IPv6 nameserver addresses properly.

2011-06-20 Thread Jukka Rissanen
---
 src/service.c |   56 +---
 1 files changed, 49 insertions(+), 7 deletions(-)

diff --git a/src/service.c b/src/service.c
index eca4ef2..216fa47 100644
--- a/src/service.c
+++ b/src/service.c
@@ -26,6 +26,7 @@
 #include errno.h
 #include stdio.h
 #include string.h
+#include netdb.h
 #include gdbus.h
 
 #include connman.h
@@ -611,22 +612,63 @@ void __connman_service_nameserver_clear(struct 
connman_service *service)
 static void nameserver_add_routes(int index, char **nameservers,
const char *gw)
 {
-   int i;
+   int i, ret, family;
+   struct addrinfo hints;
+   struct addrinfo *addr;
 
for (i = 0; nameservers[i] != NULL; i++) {
-   if (connman_inet_compare_subnet(index, nameservers[i]))
+   memset(hints, 0, sizeof(struct addrinfo));
+   hints.ai_flags = AI_NUMERICHOST;
+   addr = NULL;
+
+   ret = getaddrinfo(nameservers[i], NULL, hints, addr);
+   if (ret == EAI_NONAME)
+   family = AF_INET; /* use the IPv4 as a default */
+   else if (ret != 0)
continue;
+   else
+   family = addr-ai_family;
+
+   if (family == AF_INET) {
+   if (connman_inet_compare_subnet(index,
+   nameservers[i]) != TRUE)
+   connman_inet_add_host_route(index,
+   nameservers[i], gw);
+   } else if (family == AF_INET6)
+   connman_inet_add_ipv6_host_route(index,
+   nameservers[i], gw);
 
-   connman_inet_add_host_route(index, nameservers[i], gw);
+   freeaddrinfo(addr);
}
 }
 
 static void nameserver_del_routes(int index, char **nameservers)
 {
-   int i;
+   int i, ret, family;
+   struct addrinfo hints;
+   struct addrinfo *addr;
+
+   for (i = 0; nameservers[i] != NULL; i++) {
+   memset(hints, 0, sizeof(struct addrinfo));
+   hints.ai_flags = AI_NUMERICHOST;
+   addr = NULL;
+
+   ret = getaddrinfo(nameservers[i], NULL, hints, addr);
+   if (ret == EAI_NONAME)
+   family = AF_INET; /* use the IPv4 as a default */
+   else if (ret != 0)
+   continue;
+   else
+   family = addr-ai_family;
 
-   for (i = 0; nameservers[i] != NULL; i++)
-   connman_inet_del_host_route(index, nameservers[i]);
+   if (family == AF_INET)
+   connman_inet_del_host_route(index, nameservers[i]);
+   else if (family == AF_INET6)
+   connman_inet_del_ipv6_host_route(index,
+   nameservers[i]);
+
+   freeaddrinfo(addr);
+   }
 }
 
 void __connman_service_nameserver_add_routes(struct connman_service *service,
-- 
1.7.1

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH ipv6 gw 09/13] ipconfig: Added function to remove address from interface.

2011-06-20 Thread Jukka Rissanen
---
 src/connman.h  |1 +
 src/ipconfig.c |   30 --
 2 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/src/connman.h b/src/connman.h
index 7e22b78..9e28837 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -249,6 +249,7 @@ enum connman_ipconfig_method __connman_ipconfig_get_method(
 
 int __connman_ipconfig_address_add(struct connman_ipconfig *ipconfig);
 int __connman_ipconfig_address_remove(struct connman_ipconfig *ipconfig);
+int __connman_ipconfig_address_unset(struct connman_ipconfig *ipconfig);
 int __connman_ipconfig_gateway_add(struct connman_ipconfig *ipconfig);
 void __connman_ipconfig_gateway_remove(struct connman_ipconfig *ipconfig);
 unsigned char __connman_ipconfig_netmask_prefix_len(const char *netmask);
diff --git a/src/ipconfig.c b/src/ipconfig.c
index c8466d9..4d74ca8 100644
--- a/src/ipconfig.c
+++ b/src/ipconfig.c
@@ -1401,6 +1401,34 @@ int __connman_ipconfig_address_remove(struct 
connman_ipconfig *ipconfig)
case CONNMAN_IPCONFIG_METHOD_FIXED:
case CONNMAN_IPCONFIG_METHOD_DHCP:
case CONNMAN_IPCONFIG_METHOD_MANUAL:
+   err = __connman_ipconfig_address_unset(ipconfig);
+   connman_ipaddress_clear(ipconfig-address);
+
+   return err;
+   }
+
+   return 0;
+}
+
+int __connman_ipconfig_address_unset(struct connman_ipconfig *ipconfig)
+{
+   int err;
+
+   DBG();
+
+   if (ipconfig == NULL)
+   return 0;
+
+   DBG(method %d, ipconfig-method);
+
+   switch (ipconfig-method) {
+   case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
+   case CONNMAN_IPCONFIG_METHOD_OFF:
+   case CONNMAN_IPCONFIG_METHOD_AUTO:
+   break;
+   case CONNMAN_IPCONFIG_METHOD_FIXED:
+   case CONNMAN_IPCONFIG_METHOD_DHCP:
+   case CONNMAN_IPCONFIG_METHOD_MANUAL:
if (ipconfig-type == CONNMAN_IPCONFIG_TYPE_IPV4)
err = connman_inet_clear_address(ipconfig-index,
ipconfig-address);
@@ -1412,8 +1440,6 @@ int __connman_ipconfig_address_remove(struct 
connman_ipconfig *ipconfig)
else
err = -EINVAL;
 
-   connman_ipaddress_clear(ipconfig-address);
-
return err;
}
 
-- 
1.7.1

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH ipv6 gw 10/13] network: Clear interface addresses after removing gateway address.

2011-06-20 Thread Jukka Rissanen
---
 src/network.c |3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/src/network.c b/src/network.c
index 4abcb09..0ae77ca 100644
--- a/src/network.c
+++ b/src/network.c
@@ -1101,6 +1101,9 @@ static gboolean set_connected(gpointer user_data)
__connman_connection_gateway_remove(service,
CONNMAN_IPCONFIG_TYPE_ALL);
 
+   __connman_ipconfig_address_unset(ipconfig_ipv4);
+   __connman_ipconfig_address_unset(ipconfig_ipv6);
+
__connman_service_indicate_state(service,
CONNMAN_SERVICE_STATE_IDLE,
CONNMAN_IPCONFIG_TYPE_IPV4);
-- 
1.7.1

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH ipv6 gw 11/13] ipconfig: Added function to enable IPv6.

2011-06-20 Thread Jukka Rissanen
---
 include/ipconfig.h |1 +
 src/ipconfig.c |8 
 2 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/include/ipconfig.h b/include/ipconfig.h
index 8980a78..34463eb 100644
--- a/include/ipconfig.h
+++ b/include/ipconfig.h
@@ -99,6 +99,7 @@ void connman_ipconfig_set_ops(struct connman_ipconfig 
*ipconfig,
 int connman_ipconfig_set_method(struct connman_ipconfig *ipconfig,
enum connman_ipconfig_method method);
 void __connman_ipconfig_disable_ipv6(struct connman_ipconfig *ipconfig);
+void __connman_ipconfig_enable_ipv6(struct connman_ipconfig *ipconfig);
 
 #ifdef __cplusplus
 }
diff --git a/src/ipconfig.c b/src/ipconfig.c
index 4d74ca8..454d5d5 100644
--- a/src/ipconfig.c
+++ b/src/ipconfig.c
@@ -1516,6 +1516,14 @@ static void enable_ipv6(struct connman_ipconfig 
*ipconfig)
set_ipv6_state(ipdevice-ifname, TRUE);
 }
 
+void __connman_ipconfig_enable_ipv6(struct connman_ipconfig *ipconfig)
+{
+   if (ipconfig == NULL || ipconfig-type != CONNMAN_IPCONFIG_TYPE_IPV6)
+   return;
+
+   enable_ipv6(ipconfig);
+}
+
 void __connman_ipconfig_disable_ipv6(struct connman_ipconfig *ipconfig)
 {
if (ipconfig == NULL || ipconfig-type != CONNMAN_IPCONFIG_TYPE_IPV6)
-- 
1.7.1

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH ipv6 gw 12/13] network: Clear IPv6 autoconfigured routes when disconnected.

2011-06-20 Thread Jukka Rissanen
---
 src/network.c |   11 +++
 1 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/src/network.c b/src/network.c
index 0ae77ca..ac7bd07 100644
--- a/src/network.c
+++ b/src/network.c
@@ -1104,6 +1104,17 @@ static gboolean set_connected(gpointer user_data)
__connman_ipconfig_address_unset(ipconfig_ipv4);
__connman_ipconfig_address_unset(ipconfig_ipv6);
 
+   /*
+* Special handling for IPv6 autoconfigured address.
+* The simplest way to remove autoconfigured routes is to
+* disable IPv6 temporarily so that kernel will do the cleanup
+* automagically.
+*/
+   if (ipv6_method == CONNMAN_IPCONFIG_METHOD_AUTO) {
+   __connman_ipconfig_disable_ipv6(ipconfig_ipv6);
+   __connman_ipconfig_enable_ipv6(ipconfig_ipv6);
+   }
+
__connman_service_indicate_state(service,
CONNMAN_SERVICE_STATE_IDLE,
CONNMAN_IPCONFIG_TYPE_IPV4);
-- 
1.7.1

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH ipv6 gw 13/13] TODO: IPv6 gateway handling done.

2011-06-20 Thread Jukka Rissanen
---
 TODO |   10 --
 1 files changed, 0 insertions(+), 10 deletions(-)

diff --git a/TODO b/TODO
index 7420ba0..8937041 100644
--- a/TODO
+++ b/TODO
@@ -64,16 +64,6 @@ Core
not all driver (especially WiFi ones) implement runtime PM hooks.
 
 
-- IPv6 gateway handling
-
-   Priority: Medium
-   Complexity: C4
-
-   We should be able to switch between IPv6 only services and thus
-   change the default IPv6 gateway on the fly. For that we need to
-   improve the connection.c code to properly handle IPv6 gateways.
-
-
 - IP ranges allocation and check
 
Priority: High
-- 
1.7.1

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


Re: [PATCH ipv6 gw 10/13] network: Clear interface addresses after removing gateway address.

2011-06-22 Thread Jukka Rissanen

Hi Samuel,

On 06/21/2011 07:11 PM, Samuel Ortiz wrote:

Hi Jukka,

On Mon, Jun 20, 2011 at 02:05:26PM +0300, Jukka Rissanen wrote:

---
  src/network.c |3 +++
  1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/src/network.c b/src/network.c
index 4abcb09..0ae77ca 100644
--- a/src/network.c
+++ b/src/network.c
@@ -1101,6 +1101,9 @@ static gboolean set_connected(gpointer user_data)
__connman_connection_gateway_remove(service,
CONNMAN_IPCONFIG_TYPE_ALL);

+   __connman_ipconfig_address_unset(ipconfig_ipv4);
+   __connman_ipconfig_address_unset(ipconfig_ipv6);
+

So we're already calling ipconfig_address_remove() from service.c and also
from dhcp.c. Why do we need this ?


Yes, the __connman_service_disconnect() will call the 
__connman_ipconfig_address_remove() but when changing the service, the 
__connman_service_disconnect() is not called at all. This means that the 
code path is different if you just disconnect a service and if you 
change from one service to another although the end result is the same 
i.e., the service is disconnected.


The new __connman_ipconfig_address_unset() differs in small detail from 
__connman_ipconfig_address_remove(). The _unset() does not call 
connman_ipaddress_clear() so that we do not remove addresses from 
internal structures. Clearing the ipaddress from ipconfig caused 
problems if done at this stage of the call flow (sorry, I do not 
remember the details).




Btw, the changelog would be the right place to explain why we do need those
calls.


Very true, I try to do better next time :)


Cheers,
Samuel.


Jukka
___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


Re: [PATCH ipv6 gw 07/13] connection: Separate IPv4 and IPv6 gateway and routing handling.

2011-06-22 Thread Jukka Rissanen

Hi Samuel,

On 06/21/2011 07:10 PM, Samuel Ortiz wrote:

Hi Jukka,

On Mon, Jun 20, 2011 at 02:05:23PM +0300, Jukka Rissanen wrote:

---
  include/ipconfig.h |1 +
  src/connection.c   |  495 
  src/connman.h  |9 +-
  src/ipconfig.c |   18 +-
  src/network.c  |3 +-
  5 files changed, 397 insertions(+), 129 deletions(-)

Pretty good patch, I have one comment though:


Thanks, I tried to test the patch as well as possible but my test setup 
is quite limited atm so I could not test the VPN connectivity for example.





-static struct gateway_data *find_gateway(int index, const char *gateway)
+static struct gateway_data *find_gateway(int index, const char *gateway,
+   struct gateway_config **config)

Couldn't this one simply return a struct gateway_config * ?


Yes, you are right. I can fix that.



Cheers,
Samuel.



Jukka


___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH ipv6 gw v2 05/13] service: Set and clear IPv6 nameserver addresses properly.

2011-06-22 Thread Jukka Rissanen
---
 src/service.c |   56 +---
 1 files changed, 49 insertions(+), 7 deletions(-)

diff --git a/src/service.c b/src/service.c
index 3f6df36..7f55bbf 100644
--- a/src/service.c
+++ b/src/service.c
@@ -26,6 +26,7 @@
 #include errno.h
 #include stdio.h
 #include string.h
+#include netdb.h
 #include gdbus.h
 
 #include connman.h
@@ -611,22 +612,63 @@ void __connman_service_nameserver_clear(struct 
connman_service *service)
 static void nameserver_add_routes(int index, char **nameservers,
const char *gw)
 {
-   int i;
+   int i, ret, family;
+   struct addrinfo hints;
+   struct addrinfo *addr;
 
for (i = 0; nameservers[i] != NULL; i++) {
-   if (connman_inet_compare_subnet(index, nameservers[i]))
+   memset(hints, 0, sizeof(struct addrinfo));
+   hints.ai_flags = AI_NUMERICHOST;
+   addr = NULL;
+
+   ret = getaddrinfo(nameservers[i], NULL, hints, addr);
+   if (ret == EAI_NONAME)
+   family = AF_INET; /* use the IPv4 as a default */
+   else if (ret != 0)
continue;
+   else
+   family = addr-ai_family;
+
+   if (family == AF_INET) {
+   if (connman_inet_compare_subnet(index,
+   nameservers[i]) != TRUE)
+   connman_inet_add_host_route(index,
+   nameservers[i], gw);
+   } else if (family == AF_INET6)
+   connman_inet_add_ipv6_host_route(index,
+   nameservers[i], gw);
 
-   connman_inet_add_host_route(index, nameservers[i], gw);
+   freeaddrinfo(addr);
}
 }
 
 static void nameserver_del_routes(int index, char **nameservers)
 {
-   int i;
+   int i, ret, family;
+   struct addrinfo hints;
+   struct addrinfo *addr;
+
+   for (i = 0; nameservers[i] != NULL; i++) {
+   memset(hints, 0, sizeof(struct addrinfo));
+   hints.ai_flags = AI_NUMERICHOST;
+   addr = NULL;
+
+   ret = getaddrinfo(nameservers[i], NULL, hints, addr);
+   if (ret == EAI_NONAME)
+   family = AF_INET; /* use the IPv4 as a default */
+   else if (ret != 0)
+   continue;
+   else
+   family = addr-ai_family;
 
-   for (i = 0; nameservers[i] != NULL; i++)
-   connman_inet_del_host_route(index, nameservers[i]);
+   if (family == AF_INET)
+   connman_inet_del_host_route(index, nameservers[i]);
+   else if (family == AF_INET6)
+   connman_inet_del_ipv6_host_route(index,
+   nameservers[i]);
+
+   freeaddrinfo(addr);
+   }
 }
 
 void __connman_service_nameserver_add_routes(struct connman_service *service,
-- 
1.7.1

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH ipv6 gw v2 04/13] inet: Added support functions for setting and clearing IPv6 gateway address.

2011-06-22 Thread Jukka Rissanen
---
 include/inet.h |2 +
 src/inet.c |   92 
 2 files changed, 94 insertions(+), 0 deletions(-)

diff --git a/include/inet.h b/include/inet.h
index 19f4455..1aa23ea 100644
--- a/include/inet.h
+++ b/include/inet.h
@@ -69,6 +69,8 @@ int connman_inet_del_ipv6_network_route(int index, const char 
*host,
 int connman_inet_del_ipv6_host_route(int index, const char *host);
 int connman_inet_set_ipv6_gateway_address(int index, const char *gateway);
 int connman_inet_clear_ipv6_gateway_address(int index, const char *gateway);
+int connman_inet_set_ipv6_gateway_interface(int index);
+int connman_inet_clear_ipv6_gateway_interface(int index);
 
 int connman_inet_add_to_bridge(int index, const char *bridge);
 int connman_inet_remove_from_bridge(int index, const char *bridge);
diff --git a/src/inet.c b/src/inet.c
index 05ead31..d898650 100644
--- a/src/inet.c
+++ b/src/inet.c
@@ -1014,6 +1014,52 @@ int connman_inet_set_gateway_interface(int index)
return err;
 }
 
+int connman_inet_set_ipv6_gateway_interface(int index)
+{
+   struct ifreq ifr;
+   struct rtentry rt;
+   struct sockaddr_in6 addr;
+   const struct in6_addr any = IN6ADDR_ANY_INIT;
+   int sk, err;
+
+   DBG();
+
+   sk = socket(PF_INET6, SOCK_DGRAM, 0);
+   if (sk  0)
+   return -1;
+
+   memset(ifr, 0, sizeof(ifr));
+   ifr.ifr_ifindex = index;
+
+   if (ioctl(sk, SIOCGIFNAME, ifr)  0) {
+   close(sk);
+   return -1;
+   }
+
+   DBG(ifname %s, ifr.ifr_name);
+
+   memset(rt, 0, sizeof(rt));
+   rt.rt_flags = RTF_UP;
+
+   memset(addr, 0, sizeof(addr));
+   addr.sin6_family = AF_INET6;
+   addr.sin6_addr = any;
+
+   memcpy(rt.rt_genmask, addr, sizeof(rt.rt_genmask));
+   memcpy(rt.rt_dst, addr, sizeof(rt.rt_dst));
+   memcpy(rt.rt_gateway, addr, sizeof(rt.rt_gateway));
+
+   rt.rt_dev = ifr.ifr_name;
+
+   err = ioctl(sk, SIOCADDRT, rt);
+   if (err  0)
+   connman_error(Setting default interface route failed (%s),
+   strerror(errno));
+   close(sk);
+
+   return err;
+}
+
 int connman_inet_clear_gateway_address(int index, const char *gateway)
 {
struct ifreq ifr;
@@ -1110,6 +1156,52 @@ int connman_inet_clear_gateway_interface(int index)
return err;
 }
 
+int connman_inet_clear_ipv6_gateway_interface(int index)
+{
+   struct ifreq ifr;
+   struct rtentry rt;
+   struct sockaddr_in6 addr;
+   const struct in6_addr any = IN6ADDR_ANY_INIT;
+   int sk, err;
+
+   DBG();
+
+   sk = socket(PF_INET6, SOCK_DGRAM, 0);
+   if (sk  0)
+   return -1;
+
+   memset(ifr, 0, sizeof(ifr));
+   ifr.ifr_ifindex = index;
+
+   if (ioctl(sk, SIOCGIFNAME, ifr)  0) {
+   close(sk);
+   return -1;
+   }
+
+   DBG(ifname %s, ifr.ifr_name);
+
+   memset(rt, 0, sizeof(rt));
+   rt.rt_flags = RTF_UP;
+
+   memset(addr, 0, sizeof(addr));
+   addr.sin6_family = AF_INET6;
+   addr.sin6_addr = any;
+
+   memcpy(rt.rt_genmask, addr, sizeof(rt.rt_genmask));
+   memcpy(rt.rt_dst, addr, sizeof(rt.rt_dst));
+   memcpy(rt.rt_gateway, addr, sizeof(rt.rt_gateway));
+
+   rt.rt_dev = ifr.ifr_name;
+
+   err = ioctl(sk, SIOCDELRT, rt);
+   if (err  0)
+   connman_error(Removing default interface route failed (%s),
+   strerror(errno));
+   close(sk);
+
+   return err;
+}
+
 connman_bool_t connman_inet_compare_subnet(int index, const char *host)
 {
struct ifreq ifr;
-- 
1.7.1

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH ipv6 gw v2 06/13] network: Add IPv6 associating state.

2011-06-22 Thread Jukka Rissanen
---
 src/network.c |3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/src/network.c b/src/network.c
index 88b8ad8..1693109 100644
--- a/src/network.c
+++ b/src/network.c
@@ -657,6 +657,9 @@ int connman_network_set_associating(struct connman_network 
*network,
__connman_service_indicate_state(service,
CONNMAN_SERVICE_STATE_ASSOCIATION,
CONNMAN_IPCONFIG_TYPE_IPV4);
+   __connman_service_indicate_state(service,
+   CONNMAN_SERVICE_STATE_ASSOCIATION,
+   CONNMAN_IPCONFIG_TYPE_IPV6);
}
 
return 0;
-- 
1.7.1

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH ipv6 gw v2 08/13] network: Set manual IPv6 state and gateway.

2011-06-22 Thread Jukka Rissanen
---
 src/network.c |   23 +++
 1 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/src/network.c b/src/network.c
index acc374f..4abcb09 100644
--- a/src/network.c
+++ b/src/network.c
@@ -960,6 +960,8 @@ static int manual_ipv6_set(struct connman_network *network,
struct connman_service *service;
int err;
 
+   DBG(network %p ipv6 %p, network, ipconfig_ipv6);
+
service = __connman_service_lookup_from_network(network);
if (service == NULL)
return -EINVAL;
@@ -971,10 +973,23 @@ static int manual_ipv6_set(struct connman_network 
*network,
return err;
}
 
-   /*
-* READY state will be indicated by IPV4 setting
-* gateway will be set by IPV4 setting
-*/
+   err = __connman_ipconfig_gateway_add(ipconfig_ipv6);
+   if (err  0)
+   return err;
+
+   __connman_connection_gateway_activate(service,
+   CONNMAN_IPCONFIG_TYPE_IPV6);
+
+   __connman_device_increase_connections(network-device);
+
+   __connman_device_set_network(network-device, network);
+
+   connman_device_set_disconnected(network-device, FALSE);
+
+   network-connecting = FALSE;
+
+   __connman_service_set_ipconfig_ready(service,
+   CONNMAN_IPCONFIG_TYPE_IPV6);
 
return 0;
 }
-- 
1.7.1

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH ipv6 gw v2 07/13] connection: Separate IPv4 and IPv6 gateway and routing handling.

2011-06-22 Thread Jukka Rissanen
---
 include/ipconfig.h |1 +
 src/connection.c   |  495 +++-
 src/connman.h  |9 +-
 src/ipconfig.c |   18 +-
 src/network.c  |3 +-
 5 files changed, 393 insertions(+), 133 deletions(-)

diff --git a/include/ipconfig.h b/include/ipconfig.h
index a0673af..8980a78 100644
--- a/include/ipconfig.h
+++ b/include/ipconfig.h
@@ -58,6 +58,7 @@ void connman_ipaddress_copy(struct connman_ipaddress 
*ipaddress,
 
 enum connman_ipconfig_type {
CONNMAN_IPCONFIG_TYPE_UNKNOWN = 0,
+   CONNMAN_IPCONFIG_TYPE_ALL = 0,
CONNMAN_IPCONFIG_TYPE_IPV4= 1,
CONNMAN_IPCONFIG_TYPE_IPV6= 2,
 };
diff --git a/src/connection.c b/src/connection.c
index 10ef04a..a402588 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -31,22 +31,27 @@
 
 #include connman.h
 
-struct gateway_data {
-   int index;
-   struct connman_service *service;
-   char *ipv4_gateway;
-   char *ipv6_gateway;
-   unsigned int order;
+struct gateway_config {
gboolean active;
+   char *gateway;
+
/* VPN extra data */
gboolean vpn;
char *vpn_ip;
int vpn_phy_index;
 };
 
+struct gateway_data {
+   int index;
+   struct connman_service *service;
+   unsigned int order;
+   struct gateway_config *ipv4_gateway;
+   struct gateway_config *ipv6_gateway;
+};
+
 static GHashTable *gateway_hash = NULL;
 
-static struct gateway_data *find_gateway(int index, const char *gateway)
+static struct gateway_config *find_gateway(int index, const char *gateway)
 {
GHashTableIter iter;
gpointer value, key;
@@ -59,46 +64,113 @@ static struct gateway_data *find_gateway(int index, const 
char *gateway)
while (g_hash_table_iter_next(iter, key, value) == TRUE) {
struct gateway_data *data = value;
 
-   if (data-ipv4_gateway == NULL)
-   continue;
+   if (data-ipv4_gateway != NULL  data-index == index 
+   g_str_equal(data-ipv4_gateway-gateway,
+   gateway) == TRUE)
+   return data-ipv4_gateway;
 
-   if (data-index == index 
-   g_str_equal(data-ipv4_gateway, gateway)
-   == TRUE)
-   return data;
+   if (data-ipv6_gateway != NULL  data-index == index 
+   g_str_equal(data-ipv6_gateway-gateway,
+   gateway) == TRUE)
+   return data-ipv6_gateway;
}
 
return NULL;
 }
 
-static int del_routes(struct gateway_data *data)
+static int del_routes(struct gateway_data *data,
+   enum connman_ipconfig_type type)
 {
-   if (data-vpn) {
-   if (data-vpn_phy_index = 0)
-   connman_inet_del_host_route(data-vpn_phy_index,
-   data-ipv4_gateway);
-   return connman_inet_clear_gateway_address(data-index,
-   data-vpn_ip);
-   } else if (g_strcmp0(data-ipv4_gateway, 0.0.0.0) == 0) {
-   return connman_inet_clear_gateway_interface(data-index);
-   } else {
-   connman_inet_del_ipv6_host_route(data-index,
-   data-ipv6_gateway);
-   connman_inet_clear_ipv6_gateway_address(data-index,
-   data-ipv6_gateway);
-   connman_inet_del_host_route(data-index, data-ipv4_gateway);
-   return connman_inet_clear_gateway_address(data-index,
-   data-ipv4_gateway);
+   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;
+
+   if (do_ipv4 == TRUE  data-ipv4_gateway != NULL) {
+   if (data-ipv4_gateway-vpn == TRUE) {
+   if (data-ipv4_gateway-vpn_phy_index = 0)
+   connman_inet_del_host_route(
+   data-ipv4_gateway-vpn_phy_index,
+   data-ipv4_gateway-gateway);
+
+   status4 = connman_inet_clear_gateway_address(
+   data-index,
+   data-ipv4_gateway-vpn_ip);
+
+   } else if (g_strcmp0(data-ipv4_gateway-gateway,
+   0.0.0.0) == 0) {
+   status4 = connman_inet_clear_gateway_interface(
+  

[PATCH ipv6 gw v2 10/13] network: Clear interface addresses after removing gateway address.

2011-06-22 Thread Jukka Rissanen
The reason for this patch is that service disconnect code path
is different from service change code path. In disconnect,
the __connman_ipconfig_address_remove() is called which clears the
addresses from interface. When changing from one service to another,
the function __connman_service_disconnect() is not called and thus
the interface address is not removed.
We cannot call __connman_ipconfig_address_remove() yet at this point
because it would clear addresses from internal data structures so we
use __connman_ipconfig_address_unset() instead.
---
 src/network.c |3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/src/network.c b/src/network.c
index 4abcb09..0ae77ca 100644
--- a/src/network.c
+++ b/src/network.c
@@ -1101,6 +1101,9 @@ static gboolean set_connected(gpointer user_data)
__connman_connection_gateway_remove(service,
CONNMAN_IPCONFIG_TYPE_ALL);
 
+   __connman_ipconfig_address_unset(ipconfig_ipv4);
+   __connman_ipconfig_address_unset(ipconfig_ipv6);
+
__connman_service_indicate_state(service,
CONNMAN_SERVICE_STATE_IDLE,
CONNMAN_IPCONFIG_TYPE_IPV4);
-- 
1.7.1

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH ipv6 gw v2 11/13] ipconfig: Added function to enable IPv6.

2011-06-22 Thread Jukka Rissanen
---
 include/ipconfig.h |1 +
 src/ipconfig.c |8 
 2 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/include/ipconfig.h b/include/ipconfig.h
index 8980a78..34463eb 100644
--- a/include/ipconfig.h
+++ b/include/ipconfig.h
@@ -99,6 +99,7 @@ void connman_ipconfig_set_ops(struct connman_ipconfig 
*ipconfig,
 int connman_ipconfig_set_method(struct connman_ipconfig *ipconfig,
enum connman_ipconfig_method method);
 void __connman_ipconfig_disable_ipv6(struct connman_ipconfig *ipconfig);
+void __connman_ipconfig_enable_ipv6(struct connman_ipconfig *ipconfig);
 
 #ifdef __cplusplus
 }
diff --git a/src/ipconfig.c b/src/ipconfig.c
index 4d74ca8..454d5d5 100644
--- a/src/ipconfig.c
+++ b/src/ipconfig.c
@@ -1516,6 +1516,14 @@ static void enable_ipv6(struct connman_ipconfig 
*ipconfig)
set_ipv6_state(ipdevice-ifname, TRUE);
 }
 
+void __connman_ipconfig_enable_ipv6(struct connman_ipconfig *ipconfig)
+{
+   if (ipconfig == NULL || ipconfig-type != CONNMAN_IPCONFIG_TYPE_IPV6)
+   return;
+
+   enable_ipv6(ipconfig);
+}
+
 void __connman_ipconfig_disable_ipv6(struct connman_ipconfig *ipconfig)
 {
if (ipconfig == NULL || ipconfig-type != CONNMAN_IPCONFIG_TYPE_IPV6)
-- 
1.7.1

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH ipv6 gw v2 09/13] ipconfig: Add function to remove address from interface.

2011-06-22 Thread Jukka Rissanen
The new function removes the address from interface but does not
touch internal data structures.
---
 src/connman.h  |1 +
 src/ipconfig.c |   30 --
 2 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/src/connman.h b/src/connman.h
index da8323d..948a285 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -249,6 +249,7 @@ enum connman_ipconfig_method __connman_ipconfig_get_method(
 
 int __connman_ipconfig_address_add(struct connman_ipconfig *ipconfig);
 int __connman_ipconfig_address_remove(struct connman_ipconfig *ipconfig);
+int __connman_ipconfig_address_unset(struct connman_ipconfig *ipconfig);
 int __connman_ipconfig_gateway_add(struct connman_ipconfig *ipconfig);
 void __connman_ipconfig_gateway_remove(struct connman_ipconfig *ipconfig);
 unsigned char __connman_ipconfig_netmask_prefix_len(const char *netmask);
diff --git a/src/ipconfig.c b/src/ipconfig.c
index c8466d9..4d74ca8 100644
--- a/src/ipconfig.c
+++ b/src/ipconfig.c
@@ -1401,6 +1401,34 @@ int __connman_ipconfig_address_remove(struct 
connman_ipconfig *ipconfig)
case CONNMAN_IPCONFIG_METHOD_FIXED:
case CONNMAN_IPCONFIG_METHOD_DHCP:
case CONNMAN_IPCONFIG_METHOD_MANUAL:
+   err = __connman_ipconfig_address_unset(ipconfig);
+   connman_ipaddress_clear(ipconfig-address);
+
+   return err;
+   }
+
+   return 0;
+}
+
+int __connman_ipconfig_address_unset(struct connman_ipconfig *ipconfig)
+{
+   int err;
+
+   DBG();
+
+   if (ipconfig == NULL)
+   return 0;
+
+   DBG(method %d, ipconfig-method);
+
+   switch (ipconfig-method) {
+   case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
+   case CONNMAN_IPCONFIG_METHOD_OFF:
+   case CONNMAN_IPCONFIG_METHOD_AUTO:
+   break;
+   case CONNMAN_IPCONFIG_METHOD_FIXED:
+   case CONNMAN_IPCONFIG_METHOD_DHCP:
+   case CONNMAN_IPCONFIG_METHOD_MANUAL:
if (ipconfig-type == CONNMAN_IPCONFIG_TYPE_IPV4)
err = connman_inet_clear_address(ipconfig-index,
ipconfig-address);
@@ -1412,8 +1440,6 @@ int __connman_ipconfig_address_remove(struct 
connman_ipconfig *ipconfig)
else
err = -EINVAL;
 
-   connman_ipaddress_clear(ipconfig-address);
-
return err;
}
 
-- 
1.7.1

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH ipv6 gw v2 12/13] network: Clear IPv6 autoconfigured routes when disconnected.

2011-06-22 Thread Jukka Rissanen
---
 src/network.c |   11 +++
 1 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/src/network.c b/src/network.c
index 0ae77ca..ac7bd07 100644
--- a/src/network.c
+++ b/src/network.c
@@ -1104,6 +1104,17 @@ static gboolean set_connected(gpointer user_data)
__connman_ipconfig_address_unset(ipconfig_ipv4);
__connman_ipconfig_address_unset(ipconfig_ipv6);
 
+   /*
+* Special handling for IPv6 autoconfigured address.
+* The simplest way to remove autoconfigured routes is to
+* disable IPv6 temporarily so that kernel will do the cleanup
+* automagically.
+*/
+   if (ipv6_method == CONNMAN_IPCONFIG_METHOD_AUTO) {
+   __connman_ipconfig_disable_ipv6(ipconfig_ipv6);
+   __connman_ipconfig_enable_ipv6(ipconfig_ipv6);
+   }
+
__connman_service_indicate_state(service,
CONNMAN_SERVICE_STATE_IDLE,
CONNMAN_IPCONFIG_TYPE_IPV4);
-- 
1.7.1

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH ipv6 gw v2 13/13] TODO: IPv6 gateway handling done.

2011-06-22 Thread Jukka Rissanen
---
 TODO |   10 --
 1 files changed, 0 insertions(+), 10 deletions(-)

diff --git a/TODO b/TODO
index e376522..36f8240 100644
--- a/TODO
+++ b/TODO
@@ -57,16 +57,6 @@ Core
not all driver (especially WiFi ones) implement runtime PM hooks.
 
 
-- IPv6 gateway handling
-
-   Priority: Medium
-   Complexity: C4
-
-   We should be able to switch between IPv6 only services and thus
-   change the default IPv6 gateway on the fly. For that we need to
-   improve the connection.c code to properly handle IPv6 gateways.
-
-
 - IP ranges allocation and check
 
Priority: High
-- 
1.7.1

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH dns cache 0/3] Implement DNS caching

2011-07-04 Thread Jukka Rissanen
Hi,

this patchset implements a simple DNS A and  record caching
based on their TTL. The caching is implemented inside dnsproxy.

Following limits are implemented in the cache:
- max number of cached entries is currently 256 (in order to not use
  too much memory, each cache entry is about 100 bytes long)
- max cache ttl is set to 30min so the cache entry can stay in the cache
  only maximum 30 minutes (in order not to flood the cache with long
  ttl entries)

Regards,
Jukka


  TODO: DNS caching
  dnsproxy: Implement A and  DNS record caching.
  dnsproxy: Fix indentation.

 TODO   |9 --
 src/dnsproxy.c |  418 ++--
 2 files changed, 407 insertions(+), 20 deletions(-)

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH dns cache 1/3] TODO: DNS caching

2011-07-04 Thread Jukka Rissanen
---
 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 3/3] dnsproxy: Fix indentation.

2011-07-04 Thread Jukka Rissanen
---
 src/dnsproxy.c |6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/dnsproxy.c b/src/dnsproxy.c
index a9bab01..1bf5328 100644
--- a/src/dnsproxy.c
+++ b/src/dnsproxy.c
@@ -306,7 +306,7 @@ static gboolean request_timeout(gpointer user_data)
hdr = (void *) (req-request + 2);
hdr-id = req-srcid;
send_response(req-client_sk, req-request,
-   req-request_len, NULL, 0, IPPROTO_TCP);
+   req-request_len, NULL, 0, IPPROTO_TCP);
 
} else if (req-protocol == IPPROTO_UDP) {
int sk;
@@ -929,7 +929,7 @@ hangup:
hdr = (void *) (req-request + 2);
hdr-id = req-srcid;
send_response(req-client_sk, req-request,
-   req-request_len, NULL, 0, IPPROTO_TCP);
+   req-request_len, NULL, 0, IPPROTO_TCP);
 
request_list = g_slist_remove(request_list, req);
}
@@ -1655,7 +1655,7 @@ static gboolean udp_listener_event(GIOChannel *channel, 
GIOCondition condition,
err = parse_request(buf, len, query, sizeof(query));
if (err  0 || (g_slist_length(server_list) == 0)) {
send_response(sk, buf, len, (void *)client_addr,
- client_addr_len, IPPROTO_UDP);
+   client_addr_len, IPPROTO_UDP);
return TRUE;
}
 
-- 
1.7.1

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH dns cache 2/3] dnsproxy: Implement A and AAAA DNS record caching.

2011-07-04 Thread Jukka Rissanen
---
 src/dnsproxy.c |  412 ++-
 1 files changed, 404 insertions(+), 8 deletions(-)

diff --git a/src/dnsproxy.c b/src/dnsproxy.c
index d03b734..a9bab01 100644
--- a/src/dnsproxy.c
+++ b/src/dnsproxy.c
@@ -90,6 +90,7 @@ struct server_data {
gboolean enabled;
gboolean connected;
struct partial_reply *incoming_reply;
+   GHashTable *cache;
 };
 
 struct request_data {
@@ -123,6 +124,33 @@ struct listener_data {
guint tcp_listener_watch;
 };
 
+struct cache_entry {
+   GHashTable *cache;
+   unsigned char *key;
+   int type;
+   int timeout;
+   int answers;
+   unsigned int data_len;
+   unsigned char *data; /* contains dns header + body */
+};
+
+/*
+ * 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 93 bytes memory.
+ * The value is the max amount of cached dns responses (count).
+ */
+#define MAX_CACHE_SIZE 256
+static int cache_size;
+
+/*
+ * 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)
+
 static GSList *server_list = NULL;
 static GSList *request_list = NULL;
 static GSList *request_pending_list = NULL;
@@ -187,6 +215,34 @@ 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, int 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)
+   return;
+}
 
 static void send_response(int sk, unsigned char *buf, int len,
const struct sockaddr *to, socklen_t tolen,
@@ -325,12 +381,301 @@ static int append_query(unsigned char *buf, unsigned int 
size,
return ptr - buf;
 }
 
+static struct cache_entry *cache_check(struct server_data *server,
+   gpointer request)
+{
+   uint16_t type;
+   unsigned int offset = 0;
+   unsigned char *dns_body = (unsigned char *)request + 12;
+   unsigned char *question = dns_body[offset];
+   struct cache_entry *entry;
+
+   offset = strlen((char *)question) + 1;
+   type = ntohs(*(uint16_t *)(dns_body[offset]));
+
+   /* ATM we only cache either A (1) or  (28) requests */
+   if (type != 1  type != 28)
+   return NULL;
+
+   entry = g_hash_table_lookup(server-cache, question);
+   if (entry == NULL || entry-type != type)
+   return NULL;
+
+   return entry;
+}
+
+static gboolean cache_entry_timeout(gpointer user_data)
+{
+   struct cache_entry *entry = user_data;
+
+   DBG(cache %d key \%s\, cache_size - 1, entry-key);
+
+   g_hash_table_remove(entry-cache, entry-key);
+   return FALSE;
+}
+
+static int get_name(int counter, unsigned char *pkt, unsigned char *start,
+   unsigned char *max, unsigned char *name, int max_name,
+   int *name_len, unsigned char **end)
+{
+   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  0xc0) {
+   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,
+   name, max_name, name_len, end);
+   } else {
+   unsigned label_len = *p;
+
+   if (pkt+label_len  max)
+   return -ENOBUFS;
+
+   if (*name_len  max_name)
+   return -ENOBUFS;
+
+   /* We compress the result and use pointers */
+   name[0] = 0xC0;
+   name[1] = 0x0C;
+   *name_len = 2;
+
+   p += label_len + 1;
+
+  

Re: [PATCH dns cache v2 3/3] dnsproxy: Implement A and AAAA DNS record caching.

2011-07-07 Thread Jukka Rissanen

Hi Marcel,

On 07/07/2011 08:52 AM, Marcel Holtmann wrote:

Hi Jukka,


diff --git a/src/dnsproxy.c b/src/dnsproxy.c
index 9701343..246a6a2 100644
--- a/src/dnsproxy.c
+++ b/src/dnsproxy.c
@@ -123,6 +123,52 @@ struct listener_data {
guint tcp_listener_watch;
  };

+struct cache_data {
+   int type;
+   int timeout;
+   int answers;


is a signed integer really a good idea here. Might uint16_t or uint32_t
not be better here?


Ok, I will change to unsigned although it should not make much difference.



+   unsigned int data_len;
+   unsigned char *data; /* contains dns header + body */


Nitpick here, but upper case DNS please (and in all other comments as
well).


Sure, I changed all occurances of dns to upper case, plus fixed all the 
other nitpicks.




+};
+
+struct cache_entry {
+   unsigned char *key;
+
+   /* The same cache entry can have both IPv4 and IPv6 addresses */
+   struct cache_data *A;
+   struct cache_data *;


In general I prefer not to have upper case variable names. So maybe just
calling these ipv4 and ipv6 might be a bit more clear than just a
generic name a and some cryptic .


Ok.



+
+   *qtype = type;


If you are sure that qtype is always provided (since the function is
internal), then it is fine. Otherwise check for qtype != NULL.


qtype is always provided so I did not change this.



+   /*
+* Note that the name var below and the question and response variables
+* in cache_update() should have the same length so we use a define
+* here.
+*/
+#define MAX_NAME_LEN 255
+   char name[MAX_NAME_LEN + 1];


Don't we have some sort of constant in resolv.h for that provided by
Glibc?


Yes, there was some constants in arpa/nameser.h, I start to use them.



+   if (new_entry == TRUE) {
+   data-timeout = g_timeout_add_seconds(ttl,
+   cache_entry_timeout,
+   entry);


We could do it like this, but generally I do not like this way of
dealing with the timeout.

I rather prefer to have some garbage collection style handling of
expired values. Reason here is that we unnecessarily wake up ConnMan to
clean a value in a cache that has no relevance to us at that point of
time.

Next time a DNS request comes in for that specific record we can clean
it. Or if the cache size is too big, we purge the oldest ones.

That said, we do not have to fix this right now. I will apply a patch
with this timeout in it, but your next step then needs to be to get this
fixed.


I changed the timeout handling anyway, it was not a big issue. The new 
version clears the cache only if it is full or if cache entry has 
expired when checking if entry is in cache.




I might need another read-through the patch in details since it changes
a lot of code. If you can break it down into smaller pieces that would
help. Not sure if that is possible.


The patch is not easy to break to smaller pieces so if possible please 
try to review it as is.
I am quite confident that caching works ok, I have been using valgrind 
when testing it and there should be no invalid access or memory leaks in 
this patch.




But all in all it looks pretty good.

Regards

Marcel



Thanks,
Jukka

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH dns cache v3 0/2] Implement DNS caching

2011-07-07 Thread Jukka Rissanen
Hi,

this is the 3rd version of the patch and fixes following issues

- Timeout handling is not using glib timeouts but just purges
  the cache if it is full and removes old entries. Also when
  adding entry to cache, old and expired entry is removed and
  new value is cached.
- Using various name server constants (NS_) from resolv.h


Regards,
Jukka


Jukka Rissanen (2):
  dnsproxy: Implement A and  DNS record caching.
  TODO: DNS caching

 TODO   |9 -
 src/dnsproxy.c |  708 +++-
 2 files changed, 699 insertions(+), 18 deletions(-)

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH dns cache v3 1/2] dnsproxy: Implement A and AAAA DNS record caching.

2011-07-07 Thread Jukka Rissanen
---
 src/dnsproxy.c |  708 +++-
 1 files changed, 699 insertions(+), 9 deletions(-)

diff --git a/src/dnsproxy.c b/src/dnsproxy.c
index 9701343..37e6b1e 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 {
+   unsigned 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,34 @@ 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)
+   return;
+}
 
 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;
+   struct cache_entry *entry;
+   struct domain_question *q;
+   time_t current_time;
+   uint16_t type;
+   int offset;
+
+   offset = strlen((char *)question) + 1;
+   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;
+   }
+
+   *qtype = type;
+   return entry;
+}
+
+static int get_name(int counter,
+   unsigned char 

[PATCH dns cache v3 2/2] TODO: DNS caching

2011-07-07 Thread Jukka Rissanen
---
 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 pre-l2tp/pptp 01/11] provider: NULL pointer check.

2011-07-20 Thread Jukka Rissanen
---
 src/provider.c |5 -
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/src/provider.c b/src/provider.c
index 9ae62cd..f3b10a0 100644
--- a/src/provider.c
+++ b/src/provider.c
@@ -879,7 +879,10 @@ int connman_provider_append_route(struct connman_provider 
*provider,
 
 const char *connman_provider_get_driver_name(struct connman_provider *provider)
 {
-   return provider-driver-name;
+   if (provider-driver != NULL)
+   return provider-driver-name;
+
+   return NULL;
 }
 
 static gint compare_priority(gconstpointer a, gconstpointer b)
-- 
1.7.1

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH pre-l2tp/pptp 06/11] service: Fix function name as it is static.

2011-07-20 Thread Jukka Rissanen
---
 src/service.c |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/service.c b/src/service.c
index c11ae44..dbd0c83 100644
--- a/src/service.c
+++ b/src/service.c
@@ -3428,7 +3428,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;
@@ -3733,7 +3733,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 05/11] service: Set the user connect status correctly for VPN.

2011-07-20 Thread Jukka Rissanen
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 b2670aa..c11ae44 100644
--- a/src/service.c
+++ b/src/service.c
@@ -4987,6 +4987,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 08/11] service: Change the ipconfig state only when needed.

2011-07-20 Thread Jukka Rissanen
We should not try to change the state if the corresponding ipconfig
is set to be OFF. What this means that we change the state and
combine ipv4 and ipv6 states only if both are active. This patch is
needed by provider and the VPN authentication failure case.
---
 src/service.c |   20 +++-
 1 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/src/service.c b/src/service.c
index 133e5cf..27ad068 100644
--- a/src/service.c
+++ b/src/service.c
@@ -3727,11 +3727,21 @@ int __connman_service_ipconfig_indicate_state(struct 
connman_service *service,
break;
}
 
-   /* We keep that state */
-   if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
-   service-state_ipv4 = new_state;
-   else if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
-   service-state_ipv6 = new_state;
+   /* We keep that state but only if the method is not OFF */
+   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 = new_state;
+
+   } 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 = new_state;
+   }
 
return service_indicate_state(service);
 }
-- 
1.7.1

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH pre-l2tp/pptp 10/11] provider: Return existing service path if already connected.

2011-07-20 Thread Jukka Rissanen
---
 src/provider.c |9 +
 1 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/provider.c b/src/provider.c
index f0ede5e..90f145d 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 11/11] connection: Service was not ref counted properly.

2011-07-20 Thread Jukka Rissanen
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 l2tp/pptp 00/21] L2TP/PPTP support

2011-07-20 Thread Jukka Rissanen
Hi,

here are the L2TP/PPTP patches.

Patches 01, 03, 04, 05, 06 and 07 were sent by Mohamed Abbas
of Intel in February 2011 but they were never integrated to connman.
I modified the original patches and they now contain fixes to
suggestions that Daniel Wagner did back in February. There are also
some fixes needed so that the code would work with current head.

The rest of the patches add authentication failure support and
fix various bugs. Both the l2tp and pptp have been tested with
real network and they seem to work ok.

01 - ppp tunneling support added
02 - Added various null checks in order to avoid crashes
 in following patches
03 - Catch dbus request and send back data to ppp plugin
04 - pptp support
05 - ppp plugin
06 - l2tp support
07 - l2tp/pptp test script support
08 - l2tp in Makefile/configure file
09 - pptp in Makefile/configure file
10 - compile libppp-plugin properly
11 - Set the ip address of the l2tp VPN link. The established VPN
 connection will be closed after two minutes without this
 patch.
12 - ppp plugin will catch authentication error and report it
 to connman
13 - xl2tpd does not return any useful information in its exit code
 so check the auth error in dbus notify function
14 - pptp auth error check is needed in dbus notify function
15 - Same as patch #11 but for the pptp driver
16 - Remove password from options list so that its value is not used
 when starting the pppd (because it would then be shown in ps list)
 Password will be passed via libppp-plugin instead of cmd line.
17 - Added information what l2tp/pptp packages are needed
18 - Memory leak fix in vpn.c
19 - Memory leak fix in provider.c
20 - Make sure the task gets killed by sending SIGTERM. If that does
 not work try SIGINT and finally kill the process by SIGKILL.
 This is needed because xl2tpd seems to hang really easily even
 if it catches SIGTERM. Without this patch xl2tpd seems to
 hang when L2TP VPN is disconnected and subsequent L2TP sessions
 will not work. When xl2tpd is killed, the pppd daemon will also
 kill itself so there are no processes left around.
21 - Mark l2tp and pptp support as done.


Regards,
Jukka


Jukka Rissanen (15):
  vpn: Add null checks.
  l2tp: Add l2tp makefile and configure file.
  pptp: Add pptp makefile and configure file.
  scripts: Compile libppp-plugin.so properly.
  l2tp: Set the provider IP address when connected.
  scripts: Report authentication error to connman.
  l2tp: Check authentication error properly.
  pptp: Return authentication errors properly.
  pptp: Set the provider IP address when connected.
  pptp: Do not put password in command line options.
  readme: Add l2tp and pptp information.
  vpn: Fix memory leak.
  provider: Fix memory leak.
  task: Make sure the process is eventually killed.
  todo: Mark l2tp and pptp as done.

Mohamed Abbas (6):
  vpn: Add support to allow ppp tunnelling.
  task: Allow vpn plugins to send reply.
  pptp: Add pptp vpn support
  pptp: Add ppp plugin library.
  l2tp: Add l2tp vpn support.
  test: Add test script support for pptp/l2tp.

 Makefile.plugins|   51 +
 README  |   15 ++
 TODO|   14 --
 configure.ac|   34 
 include/task.h  |2 +-
 plugins/l2tp.c  |  501 +++
 plugins/pptp.c  |  311 +
 plugins/vpn.c   |  146 +++
 plugins/vpn.h   |4 +
 scripts/libppp-plugin.c |  318 ++
 src/provider.c  |1 +
 src/task.c  |   74 ++--
 test/connect-vpn|   18 ++
 13 files changed, 1424 insertions(+), 65 deletions(-)
 create mode 100644 plugins/l2tp.c
 create mode 100644 plugins/pptp.c
 create mode 100644 scripts/libppp-plugin.c

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH l2tp/pptp 02/21] vpn: Add null checks.

2011-07-20 Thread Jukka Rissanen
---
 plugins/vpn.c |   18 --
 1 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/plugins/vpn.c b/plugins/vpn.c
index 506a71c..a1759c9 100644
--- a/plugins/vpn.c
+++ b/plugins/vpn.c
@@ -77,6 +77,9 @@ static int stop_vpn(struct connman_provider *provider)
return -1;
 
name = connman_provider_get_driver_name(provider);
+   if (name == NULL)
+   return -EINVAL;
+
vpn_driver_data = g_hash_table_lookup(driver_hash, name);
 
if (vpn_driver_data != NULL  vpn_driver_data-vpn_driver != NULL 
@@ -136,10 +139,12 @@ void vpn_died(struct connman_task *task, int exit_code, 
void *user_data)
 vpn_exit:
if (state != VPN_STATE_READY  state != VPN_STATE_DISCONNECT) {
const char *name;
-   struct vpn_driver_data *vpn_data;
+   struct vpn_driver_data *vpn_data = NULL;
 
name = connman_provider_get_driver_name(provider);
-   vpn_data = g_hash_table_lookup(driver_hash, name);
+   if (name != NULL)
+   vpn_data = g_hash_table_lookup(driver_hash, name);
+
if (vpn_data != NULL 
vpn_data-vpn_driver-error_code != NULL)
ret = vpn_data-vpn_driver-error_code(exit_code);
@@ -203,6 +208,9 @@ static void vpn_notify(struct connman_task *task,
data = connman_provider_get_data(provider);
 
name = connman_provider_get_driver_name(provider);
+   if (name == NULL)
+   return;
+
vpn_driver_data = g_hash_table_lookup(driver_hash, name);
if (vpn_driver_data == NULL)
return;
@@ -325,6 +333,9 @@ static int vpn_connect(struct connman_provider *provider)
connman_provider_set_data(provider, data);
 
name = connman_provider_get_driver_name(provider);
+   if (name == NULL)
+   return -EINVAL;
+
vpn_driver_data = g_hash_table_lookup(driver_hash, name);
 
if (vpn_driver_data != NULL  vpn_driver_data-vpn_driver != NULL 
@@ -394,6 +405,9 @@ static int vpn_disconnect(struct connman_provider *provider)
return 0;
 
name = connman_provider_get_driver_name(provider);
+   if (name == NULL)
+   return 0;
+
vpn_driver_data = g_hash_table_lookup(driver_hash, name);
if (vpn_driver_data-vpn_driver-disconnect)
vpn_driver_data-vpn_driver-disconnect();
-- 
1.7.1

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


[PATCH l2tp/pptp 03/21] task: Allow vpn plugins to send reply.

2011-07-20 Thread Jukka Rissanen
From: Mohamed Abbas mab...@linux.intel.com

Change task notify to allow client to send dbus reply. This
will allow vpn plugin to send requested user/password info.
---
 include/task.h |2 +-
 plugins/vpn.c  |8 +---
 src/task.c |   30 +-
 3 files changed, 23 insertions(+), 17 deletions(-)

diff --git a/include/task.h b/include/task.h
index bde2a29..d93df2d 100644
--- a/include/task.h
+++ b/include/task.h
@@ -39,7 +39,7 @@ struct connman_task;
 typedef void (* connman_task_exit_t) (struct connman_task *task,
int exit_code, void *user_data);
 
-typedef void (* connman_task_notify_t) (struct connman_task *task,
+typedef DBusMessage * (* connman_task_notify_t) (struct connman_task *task,
DBusMessage *message, void *user_data);
 
 struct connman_task *connman_task_create(const char *program);
diff --git a/plugins/vpn.c b/plugins/vpn.c
index a1759c9..ee85dd7 100644
--- a/plugins/vpn.c
+++ b/plugins/vpn.c
@@ -196,7 +196,7 @@ static void vpn_newlink(unsigned flags, unsigned change, 
void *user_data)
data-flags = flags;
 }
 
-static void vpn_notify(struct connman_task *task,
+static DBusMessage *vpn_notify(struct connman_task *task,
DBusMessage *msg, void *user_data)
 {
struct connman_provider *provider = user_data;
@@ -209,11 +209,11 @@ static void vpn_notify(struct connman_task *task,
 
name = connman_provider_get_driver_name(provider);
if (name == NULL)
-   return;
+   return NULL;
 
vpn_driver_data = g_hash_table_lookup(driver_hash, name);
if (vpn_driver_data == NULL)
-   return;
+   return NULL;
 
state = vpn_driver_data-vpn_driver-notify(msg, provider);
switch (state) {
@@ -238,6 +238,8 @@ static void vpn_notify(struct connman_task *task,
CONNMAN_PROVIDER_ERROR_AUTH_FAILED);
break;
}
+
+   return NULL;
 }
 
 static int vpn_create_tun(struct connman_provider *provider)
diff --git a/src/task.c b/src/task.c
index b5b9ef7..51b4898 100644
--- a/src/task.c
+++ b/src/task.c
@@ -366,6 +366,7 @@ static DBusHandlerResult task_filter(DBusConnection 
*connection,
struct connman_task *task;
struct notify_data *notify;
const char *path, *member;
+   DBusMessage *reply = NULL;
 
if (dbus_message_get_type(message) != DBUS_MESSAGE_TYPE_METHOD_CALL)
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
@@ -382,29 +383,32 @@ static DBusHandlerResult task_filter(DBusConnection 
*connection,
if (task == NULL)
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 
-   if (dbus_message_get_no_reply(message) == FALSE) {
-   DBusMessage *reply;
+   member = dbus_message_get_member(message);
+   if (member == NULL)
+   goto send_reply;
+
+   notify = g_hash_table_lookup(task-notify, member);
+   if (notify == NULL)
+   goto send_reply;
+
+   if (notify-func)
+   reply = notify-func(task, message, notify-data);
+
+send_reply:
+   if (dbus_message_get_no_reply(message) == FALSE 
+   reply == NULL) {
 
reply = dbus_message_new_method_return(message);
if (reply == NULL)
return DBUS_HANDLER_RESULT_NEED_MEMORY;
+   }
 
+   if (reply != NULL) {
dbus_connection_send(connection, reply, NULL);
 
dbus_message_unref(reply);
}
 
-   member = dbus_message_get_member(message);
-   if (member == NULL)
-   return DBUS_HANDLER_RESULT_HANDLED;
-
-   notify = g_hash_table_lookup(task-notify, member);
-   if (notify == NULL)
-   return DBUS_HANDLER_RESULT_HANDLED;
-
-   if (notify-func)
-   notify-func(task, message, notify-data);
-
return DBUS_HANDLER_RESULT_HANDLED;
 }
 
-- 
1.7.1

___
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman


<    1   2   3   4   5   6   7   8   9   10   >