diff options
Diffstat (limited to 'gdhcp/client.c')
-rw-r--r-- | gdhcp/client.c | 48 |
1 files changed, 46 insertions, 2 deletions
diff --git a/gdhcp/client.c b/gdhcp/client.c index a1f03097..cd428cff 100644 --- a/gdhcp/client.c +++ b/gdhcp/client.c @@ -73,6 +73,7 @@ typedef enum _dhcp_client_state { SOLICITATION, REQUEST, RENEW, + REBIND, } ClientState; struct _GDHCPClient { @@ -123,6 +124,8 @@ struct _GDHCPClient { gpointer request_data; GDHCPClientEventFunc renew_cb; gpointer renew_data; + GDHCPClientEventFunc rebind_cb; + gpointer rebind_data; char *last_address; unsigned char *duid; int duid_len; @@ -134,6 +137,7 @@ struct _GDHCPClient { struct in6_addr ia_na; struct in6_addr ia_ta; time_t last_renew; + time_t last_rebind; }; static inline void debug(GDHCPClient *client, const char *format, ...) @@ -622,7 +626,8 @@ void g_dhcpv6_client_create_iaid(GDHCPClient *dhcp_client, int index, } int g_dhcpv6_client_get_timeouts(GDHCPClient *dhcp_client, - uint32_t *T1, uint32_t *T2, time_t *last_renew) + uint32_t *T1, uint32_t *T2, + time_t *last_renew, time_t *last_rebind) { if (dhcp_client == NULL || dhcp_client->type == G_DHCP_IPV4) return -EINVAL; @@ -636,6 +641,9 @@ int g_dhcpv6_client_get_timeouts(GDHCPClient *dhcp_client, if (last_renew != NULL) *last_renew = dhcp_client->last_renew; + if (last_rebind != NULL) + *last_rebind = dhcp_client->last_rebind; + return 0; } @@ -799,6 +807,11 @@ static int send_dhcpv6_renew(GDHCPClient *dhcp_client) return send_dhcpv6_msg(dhcp_client, DHCPV6_RENEW, "renew"); } +static int send_dhcpv6_rebind(GDHCPClient *dhcp_client) +{ + return send_dhcpv6_msg(dhcp_client, DHCPV6_REBIND, "rebind"); +} + static int send_information_req(GDHCPClient *dhcp_client) { return send_dhcpv6_msg(dhcp_client, DHCPV6_INFORMATION_REQ, @@ -870,7 +883,7 @@ GDHCPClient *g_dhcp_client_new(GDHCPType type, dhcp_client->require_list = NULL; dhcp_client->duid = NULL; dhcp_client->duid_len = 0; - dhcp_client->last_renew = time(0); + dhcp_client->last_renew = dhcp_client->last_rebind = time(0); *error = G_DHCP_CLIENT_ERROR_NONE; @@ -1980,6 +1993,7 @@ static gboolean listener_event(GIOChannel *channel, GIOCondition condition, case INFORMATION_REQ: case REQUEST: case RENEW: + case REBIND: if (dhcp_client->type != G_DHCP_IPV6) return TRUE; @@ -2026,6 +2040,11 @@ static gboolean listener_event(GIOChannel *channel, GIOCondition condition, dhcp_client->renew_data); return TRUE; } + if (dhcp_client->rebind_cb != NULL) { + dhcp_client->rebind_cb(dhcp_client, + dhcp_client->rebind_data); + return TRUE; + } break; default: break; @@ -2159,6 +2178,16 @@ int g_dhcp_client_start(GDHCPClient *dhcp_client, const char *last_address) return re; } send_dhcpv6_renew(dhcp_client); + + } else if (dhcp_client->rebind_cb) { + dhcp_client->state = REBIND; + re = switch_listening_mode(dhcp_client, L3); + if (re != 0) { + switch_listening_mode(dhcp_client, L_NONE); + dhcp_client->state = 0; + return re; + } + send_dhcpv6_rebind(dhcp_client); } return 0; @@ -2303,6 +2332,12 @@ void g_dhcp_client_register_event(GDHCPClient *dhcp_client, dhcp_client->renew_cb = func; dhcp_client->renew_data = data; return; + case G_DHCP_CLIENT_EVENT_REBIND: + if (dhcp_client->type == G_DHCP_IPV4) + return; + dhcp_client->rebind_cb = func; + dhcp_client->rebind_data = data; + return; } } @@ -2342,6 +2377,7 @@ char *g_dhcp_client_get_netmask(GDHCPClient *dhcp_client) case SOLICITATION: case REQUEST: case RENEW: + case REBIND: break; } return NULL; @@ -2446,6 +2482,14 @@ void g_dhcpv6_client_reset_renew(GDHCPClient *dhcp_client) dhcp_client->last_renew = time(0); } +void g_dhcpv6_client_reset_rebind(GDHCPClient *dhcp_client) +{ + if (dhcp_client == NULL || dhcp_client->type == G_DHCP_IPV4) + return; + + dhcp_client->last_rebind = time(0); +} + uint16_t g_dhcpv6_client_get_status(GDHCPClient *dhcp_client) { if (dhcp_client == NULL || dhcp_client->type == G_DHCP_IPV4) |