diff options
author | Jukka Rissanen <jukka.rissanen@linux.intel.com> | 2012-01-05 13:38:14 +0200 |
---|---|---|
committer | Daniel Wagner <daniel.wagner@bmw-carit.de> | 2012-01-05 13:17:26 +0100 |
commit | 53f38ce0bc6505c8b8a7342b0243df442b7db5a4 (patch) | |
tree | ed3550a683f4f77ab7936374f4464ce19d1fbc5d /src/dhcpv6.c | |
parent | 5f5b3609c4f9884954623d7e6bf2ae1ae7096637 (diff) | |
download | connman-53f38ce0bc6505c8b8a7342b0243df442b7db5a4.tar.gz connman-53f38ce0bc6505c8b8a7342b0243df442b7db5a4.tar.bz2 connman-53f38ce0bc6505c8b8a7342b0243df442b7db5a4.zip |
dhcpv6: Release message implemented.
Diffstat (limited to 'src/dhcpv6.c')
-rw-r--r-- | src/dhcpv6.c | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/src/dhcpv6.c b/src/dhcpv6.c index fd6e0ebe..f2c7da60 100644 --- a/src/dhcpv6.c +++ b/src/dhcpv6.c @@ -66,6 +66,7 @@ struct connman_dhcpv6 { gboolean use_ta; /* set to TRUE if IPv6 privacy is enabled */ GSList *prefixes; /* network prefixes from radvd */ int request_count; /* how many times REQUEST have been sent */ + gboolean stateless; /* TRUE if stateless DHCPv6 is used */ }; static GHashTable *network_table; @@ -236,6 +237,10 @@ static void clear_callbacks(GDHCPClient *dhcp_client) NULL, NULL); g_dhcp_client_register_event(dhcp_client, + G_DHCP_CLIENT_EVENT_RELEASE, + NULL, NULL); + + g_dhcp_client_register_event(dhcp_client, G_DHCP_CLIENT_EVENT_INFORMATION_REQ, NULL, NULL); } @@ -854,6 +859,64 @@ int __connman_dhcpv6_start_renew(struct connman_network *network, return 0; } +static void release_cb(GDHCPClient *dhcp_client, gpointer user_data) +{ + struct connman_dhcpv6 *dhcp = user_data; + + DBG("dhcpv6 release msg %p", dhcp); + + if (dhcp->callback != NULL) { + uint16_t status = g_dhcpv6_client_get_status(dhcp_client); + dhcp->callback(dhcp->network, status == 0 ? TRUE : FALSE); + } +} + +int __connman_dhcpv6_start_release(struct connman_network *network, + dhcp_cb callback) +{ + struct connman_dhcpv6 *dhcp; + GDHCPClient *dhcp_client; + + if (network_table == NULL) + return 0; /* we are already released */ + + dhcp = g_hash_table_lookup(network_table, network); + if (dhcp == NULL) + return -ENOENT; + + DBG("dhcp %p stateless %d", dhcp, dhcp->stateless); + + if (dhcp->stateless == TRUE) + return -EINVAL; + + if (dhcp->timeout > 0) { + g_source_remove(dhcp->timeout); + dhcp->timeout = 0; + } + + dhcp_client = dhcp->dhcp_client; + + g_dhcp_client_clear_requests(dhcp_client); + g_dhcp_client_clear_values(dhcp_client); + + g_dhcp_client_set_request(dhcp_client, G_DHCPV6_CLIENTID); + g_dhcp_client_set_request(dhcp_client, G_DHCPV6_SERVERID); + + 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, + NULL, NULL, TRUE); + + clear_callbacks(dhcp_client); + + g_dhcp_client_register_event(dhcp_client, G_DHCP_CLIENT_EVENT_RELEASE, + release_cb, dhcp); + + dhcp->dhcp_client = dhcp_client; + + return g_dhcp_client_start(dhcp_client, NULL); +} + static int dhcpv6_release(struct connman_dhcpv6 *dhcp) { DBG("dhcp %p", dhcp); @@ -932,6 +995,7 @@ int __connman_dhcpv6_start_info(struct connman_network *network, dhcp->network = network; dhcp->callback = callback; + dhcp->stateless = TRUE; connman_network_ref(network); |