summaryrefslogtreecommitdiff
path: root/src/dhcpv6.c
diff options
context:
space:
mode:
authorJukka Rissanen <jukka.rissanen@linux.intel.com>2012-01-05 13:38:11 +0200
committerDaniel Wagner <daniel.wagner@bmw-carit.de>2012-01-05 13:17:26 +0100
commit8aa986762c7774844e6199b8fa2514d639df2500 (patch)
tree2a5be3b4ac85ced613e8e65cc3a4a0468aacaebb /src/dhcpv6.c
parent3fd016f68a3d021d89fa7a1be1fa712e27e4913b (diff)
downloadconnman-8aa986762c7774844e6199b8fa2514d639df2500.tar.gz
connman-8aa986762c7774844e6199b8fa2514d639df2500.tar.bz2
connman-8aa986762c7774844e6199b8fa2514d639df2500.zip
dhcpv6: Renew message implemented.
Diffstat (limited to 'src/dhcpv6.c')
-rw-r--r--src/dhcpv6.c125
1 files changed, 124 insertions, 1 deletions
diff --git a/src/dhcpv6.c b/src/dhcpv6.c
index 34395fe0..b5b91727 100644
--- a/src/dhcpv6.c
+++ b/src/dhcpv6.c
@@ -46,6 +46,8 @@
#define REQ_TIMEOUT (1 * 1000)
#define REQ_MAX_RT (30 * 1000)
#define REQ_MAX_RC 10
+#define REN_TIMEOUT (10 * 1000)
+#define REN_MAX_RT (600 * 1000)
struct connman_dhcpv6 {
@@ -224,6 +226,10 @@ static void clear_callbacks(GDHCPClient *dhcp_client)
NULL, NULL);
g_dhcp_client_register_event(dhcp_client,
+ G_DHCP_CLIENT_EVENT_RENEW,
+ NULL, NULL);
+
+ g_dhcp_client_register_event(dhcp_client,
G_DHCP_CLIENT_EVENT_INFORMATION_REQ,
NULL, NULL);
}
@@ -552,7 +558,7 @@ static int dhcpv6_request(struct connman_dhcpv6 *dhcp,
g_dhcpv6_client_set_oro(dhcp_client, 2, G_DHCPV6_DNS_SERVERS,
G_DHCPV6_SNTP_SERVERS);
- g_dhcpv6_client_get_timeouts(dhcp_client, &T1, &T2);
+ g_dhcpv6_client_get_timeouts(dhcp_client, &T1, &T2, NULL);
g_dhcpv6_client_set_ia(dhcp_client,
connman_network_get_index(dhcp->network),
dhcp->use_ta == TRUE ? G_DHCPV6_IA_TA : G_DHCPV6_IA_NA,
@@ -591,6 +597,123 @@ static gboolean timeout_request(gpointer user_data)
return FALSE;
}
+static void renew_cb(GDHCPClient *dhcp_client, gpointer user_data)
+{
+ DBG("");
+
+ g_dhcpv6_client_reset_renew(dhcp_client);
+
+ re_cb(dhcp_client, user_data);
+}
+
+static int dhcpv6_renew(struct connman_dhcpv6 *dhcp)
+{
+ GDHCPClient *dhcp_client;
+ uint32_t T1, T2;
+
+ DBG("dhcp %p", dhcp);
+
+ dhcp_client = dhcp->dhcp_client;
+
+ g_dhcp_client_clear_requests(dhcp_client);
+
+ g_dhcp_client_set_request(dhcp_client, G_DHCPV6_CLIENTID);
+ g_dhcp_client_set_request(dhcp_client, G_DHCPV6_SERVERID);
+ g_dhcp_client_set_request(dhcp_client, G_DHCPV6_DNS_SERVERS);
+ g_dhcp_client_set_request(dhcp_client, G_DHCPV6_SNTP_SERVERS);
+
+ g_dhcpv6_client_set_oro(dhcp_client, 2, G_DHCPV6_DNS_SERVERS,
+ G_DHCPV6_SNTP_SERVERS);
+
+ g_dhcpv6_client_get_timeouts(dhcp_client, &T1, &T2, NULL);
+ g_dhcpv6_client_set_ia(dhcp_client,
+ connman_network_get_index(dhcp->network),
+ dhcp->use_ta == TRUE ? G_DHCPV6_IA_TA : G_DHCPV6_IA_NA,
+ &T1, &T2, TRUE);
+
+ clear_callbacks(dhcp_client);
+
+ g_dhcp_client_register_event(dhcp_client, G_DHCP_CLIENT_EVENT_RENEW,
+ renew_cb, dhcp);
+
+ dhcp->dhcp_client = dhcp_client;
+
+ return g_dhcp_client_start(dhcp_client, NULL);
+}
+
+static gboolean timeout_renew(gpointer user_data)
+{
+ struct connman_dhcpv6 *dhcp = user_data;
+
+ dhcp->RT = calc_delay(dhcp->RT, REN_MAX_RT);
+
+ DBG("renew RT timeout %d msec", dhcp->RT);
+
+ dhcp->timeout = g_timeout_add(dhcp->RT, timeout_renew, dhcp);
+
+ g_dhcp_client_start(dhcp->dhcp_client, NULL);
+
+ return FALSE;
+}
+
+static gboolean start_renew(gpointer user_data)
+{
+ struct connman_dhcpv6 *dhcp = user_data;
+
+ dhcp->RT = REN_TIMEOUT * (1 + get_random());
+
+ DBG("renew initial RT timeout %d msec", dhcp->RT);
+
+ dhcp->timeout = g_timeout_add(dhcp->RT, timeout_renew, dhcp);
+
+ dhcpv6_renew(dhcp);
+
+ return FALSE;
+}
+
+int __connman_dhcpv6_start_renew(struct connman_network *network,
+ dhcp_cb callback)
+{
+ struct connman_dhcpv6 *dhcp;
+ uint32_t T1, T2;
+ time_t last_renew, current;
+
+ DBG("");
+
+ dhcp = g_hash_table_lookup(network_table, network);
+ if (dhcp == NULL)
+ return -ENOENT;
+
+ if (dhcp->timeout > 0) {
+ g_source_remove(dhcp->timeout);
+ dhcp->timeout = 0;
+ }
+
+ g_dhcpv6_client_get_timeouts(dhcp->dhcp_client, &T1, &T2,
+ &last_renew);
+ DBG("T1 %u T2 %u", T1, T2);
+
+ if (T1 == 0xffffffff)
+ /* RFC 3315, 22.4 */
+ return 0;
+
+ if (T1 == 0)
+ /* RFC 3315, 22.4
+ * Client can choose the timeout.
+ */
+ T1 = 1800;
+
+ current = time(0);
+
+ dhcp->callback = callback;
+
+ DBG("renew after %d secs", T1);
+
+ dhcp->timeout = g_timeout_add_seconds(T1, start_renew, dhcp);
+
+ return 0;
+}
+
static int dhcpv6_release(struct connman_dhcpv6 *dhcp)
{
DBG("dhcp %p", dhcp);