summaryrefslogtreecommitdiff
path: root/src/6to4.c
diff options
context:
space:
mode:
authorJukka Rissanen <jukka.rissanen@linux.intel.com>2012-04-05 12:04:08 +0300
committerPatrik Flykt <patrik.flykt@linux.intel.com>2012-04-05 15:23:02 +0300
commit18a57a8cd68ee51fc0d478eb059bb37aef2b7b7c (patch)
tree10c0a9b04853238a8477fe0884bdc7fd3e125933 /src/6to4.c
parent0920acb99a94265bf33e6eca01ae78f7987c2ecd (diff)
downloadconnman-18a57a8cd68ee51fc0d478eb059bb37aef2b7b7c.tar.gz
connman-18a57a8cd68ee51fc0d478eb059bb37aef2b7b7c.tar.bz2
connman-18a57a8cd68ee51fc0d478eb059bb37aef2b7b7c.zip
6to4: Connectivity check was done too early
The 6to4 code checks that we can connect to ipv6.connman.net host via tunnel. The check can be done only after we have the tunnel up and running. The patch makes sure that we do the checks only after we have got newlink message from rtnl.
Diffstat (limited to 'src/6to4.c')
-rw-r--r--src/6to4.c84
1 files changed, 71 insertions, 13 deletions
diff --git a/src/6to4.c b/src/6to4.c
index 802a1dfc..c75af94f 100644
--- a/src/6to4.c
+++ b/src/6to4.c
@@ -49,6 +49,9 @@ static int tunnel_pending;
static char *tunnel_ip_address;
static GWeb *web;
static guint web_request_id;
+static unsigned int newlink_watch;
+static unsigned int newlink_flags;
+static int newlink_timeout_id;
#define STATUS_URL "http://ipv6.connman.net/online/status.html"
@@ -256,6 +259,71 @@ static void web_debug(const char *str, void *data)
connman_info("%s: %s\n", (const char *) data, str);
}
+static gboolean newlink_timeout(gpointer user_data)
+{
+ /*
+ * Stop if the timeout has been cancelled already by tun_newlink()
+ */
+ if (newlink_timeout_id == 0)
+ return FALSE;
+
+ DBG("");
+
+ if (newlink_watch != 0) {
+ connman_rtnl_remove_watch(newlink_watch);
+ newlink_watch = 0;
+ }
+
+ newlink_flags = 0;
+
+ if (web_request_id == 0)
+ tunnel_destroy();
+
+ newlink_timeout_id = 0;
+
+ return FALSE;
+}
+
+static void tun_newlink(unsigned flags, unsigned change, void *user_data)
+{
+ int index = GPOINTER_TO_INT(user_data);
+
+ if ((newlink_flags & IFF_UP) == (flags & IFF_UP)) {
+ newlink_flags = flags;
+ return;
+ }
+
+ if (flags & IFF_UP) {
+ /*
+ * We try to verify that connectivity through tunnel works ok.
+ */
+ if (newlink_timeout_id > 0) {
+ g_source_remove(newlink_timeout_id);
+ newlink_timeout_id = 0;
+ }
+
+ web = g_web_new(index);
+ if (web == NULL) {
+ tunnel_destroy();
+ return;
+ }
+
+ g_web_set_accept(web, NULL);
+ g_web_set_user_agent(web, "ConnMan/%s", VERSION);
+ g_web_set_close_connection(web, TRUE);
+
+ if (getenv("CONNMAN_WEB_DEBUG"))
+ g_web_set_debug(web, web_debug, "6to4");
+
+ web_request_id = g_web_request_get(web, STATUS_URL,
+ web_result, NULL);
+
+ newlink_timeout(NULL);
+ }
+
+ newlink_flags = flags;
+}
+
static int init_6to4(struct in_addr *ip4addr)
{
unsigned int a, b, c, d;
@@ -293,20 +361,10 @@ static int init_6to4(struct in_addr *ip4addr)
if (if_index < 0)
goto error;
- /* We try to verify that connectivity through tunnel works ok.
- */
- web = g_web_new(if_index);
- 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);
-
- if (getenv("CONNMAN_WEB_DEBUG"))
- g_web_set_debug(web, web_debug, "6to4");
+ newlink_watch = connman_rtnl_add_newlink_watch(if_index,
+ tun_newlink, GINT_TO_POINTER(if_index));
- web_request_id = g_web_request_get(web, STATUS_URL, web_result, NULL);
+ newlink_timeout_id = g_timeout_add_seconds(1, newlink_timeout, NULL);
return 0;