sd-dhcp6-client: Add Request message sending
As described in RFC 3315, Section 17.1.2, a client has to wait until the first timeout has elapsed before it is allowed to request IPv6 addresses from the DHCPv6 server. This is indicated by a non-NULL lease and a non-zero resend count. Should the Advertisement contain a preference value of 255 or be received after the first timeout, IPv6 address requesting is started immediately. In response to these events, create a Request message and set up proper resend timers to send the message to the server.
This commit is contained in:
@@ -54,6 +54,9 @@ enum {
|
||||
#define DHCP6_SOL_MAX_DELAY 1 * USEC_PER_SEC
|
||||
#define DHCP6_SOL_TIMEOUT 1 * USEC_PER_SEC
|
||||
#define DHCP6_SOL_MAX_RT 120 * USEC_PER_SEC
|
||||
#define DHCP6_REQ_TIMEOUT 1 * USEC_PER_SEC
|
||||
#define DHCP6_REQ_MAX_RT 120 * USEC_PER_SEC
|
||||
#define DHCP6_REQ_MAX_RC 10
|
||||
|
||||
enum {
|
||||
DHCP6_DUID_LLT = 1,
|
||||
@@ -66,6 +69,7 @@ enum DHCP6State {
|
||||
DHCP6_STATE_STOPPED = 0,
|
||||
DHCP6_STATE_RS = 1,
|
||||
DHCP6_STATE_SOLICITATION = 2,
|
||||
DHCP6_STATE_REQUEST = 3,
|
||||
};
|
||||
|
||||
enum {
|
||||
|
||||
@@ -213,12 +213,22 @@ static int client_send_message(sd_dhcp6_client *client) {
|
||||
case DHCP6_STATE_SOLICITATION:
|
||||
message->type = DHCP6_SOLICIT;
|
||||
|
||||
r = dhcp6_option_append(&opt, &optlen, DHCP6_OPTION_CLIENTID,
|
||||
sizeof(client->duid), &client->duid);
|
||||
r = dhcp6_option_append_ia(&opt, &optlen, &client->ia_na);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = dhcp6_option_append_ia(&opt, &optlen, &client->ia_na);
|
||||
break;
|
||||
|
||||
case DHCP6_STATE_REQUEST:
|
||||
message->type = DHCP6_REQUEST;
|
||||
|
||||
r = dhcp6_option_append(&opt, &optlen, DHCP6_OPTION_SERVERID,
|
||||
client->lease->serverid_len,
|
||||
client->lease->serverid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = dhcp6_option_append_ia(&opt, &optlen, &client->lease->ia);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -229,6 +239,11 @@ static int client_send_message(sd_dhcp6_client *client) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
r = dhcp6_option_append(&opt, &optlen, DHCP6_OPTION_CLIENTID,
|
||||
sizeof(client->duid), &client->duid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = dhcp6_network_send_udp_socket(client->fd, &all_servers, message,
|
||||
len - optlen);
|
||||
if (r < 0)
|
||||
@@ -275,6 +290,12 @@ static int client_timeout_resend(sd_event_source *s, uint64_t usec,
|
||||
|
||||
switch (client->state) {
|
||||
case DHCP6_STATE_SOLICITATION:
|
||||
|
||||
if (client->retransmit_count && client->lease) {
|
||||
client_start(client, DHCP6_STATE_REQUEST);
|
||||
return 0;
|
||||
}
|
||||
|
||||
init_retransmit_time = DHCP6_SOL_TIMEOUT;
|
||||
max_retransmit_time = DHCP6_SOL_MAX_RT;
|
||||
max_retransmit_count = 0;
|
||||
@@ -282,6 +303,14 @@ static int client_timeout_resend(sd_event_source *s, uint64_t usec,
|
||||
|
||||
break;
|
||||
|
||||
case DHCP6_STATE_REQUEST:
|
||||
init_retransmit_time = DHCP6_REQ_TIMEOUT;
|
||||
max_retransmit_time = DHCP6_REQ_MAX_RT;
|
||||
max_retransmit_count = DHCP6_REQ_MAX_RC;
|
||||
max_retransmit_duration = 0;
|
||||
|
||||
break;
|
||||
|
||||
case DHCP6_STATE_STOPPED:
|
||||
case DHCP6_STATE_RS:
|
||||
return 0;
|
||||
@@ -537,6 +566,9 @@ static int client_receive_advertise(sd_dhcp6_client *client,
|
||||
r = 0;
|
||||
}
|
||||
|
||||
if (pref_advertise == 255 || client->retransmit_count > 1)
|
||||
r = DHCP6_STATE_REQUEST;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -596,8 +628,12 @@ static int client_receive_message(sd_event_source *s, int fd, uint32_t revents,
|
||||
case DHCP6_STATE_SOLICITATION:
|
||||
r = client_receive_advertise(client, message, len);
|
||||
|
||||
if (r == DHCP6_STATE_REQUEST)
|
||||
client_start(client, r);
|
||||
|
||||
break;
|
||||
|
||||
case DHCP6_STATE_REQUEST:
|
||||
case DHCP6_STATE_STOPPED:
|
||||
case DHCP6_STATE_RS:
|
||||
return 0;
|
||||
@@ -654,6 +690,11 @@ static int client_start(sd_dhcp6_client *client, enum DHCP6State state)
|
||||
|
||||
client->state = DHCP6_STATE_SOLICITATION;
|
||||
|
||||
break;
|
||||
|
||||
case DHCP6_STATE_REQUEST:
|
||||
client->state = state;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user