mirror of
https://github.com/systemd/systemd.git
synced 2024-12-20 23:53:38 +08:00
sd-dhcp6-client: Implement Rapid Commit
Add a Rapid Commit option to Solicit messages and expect a Reply to be received instead of an Advertise. When receiving a DHCPv6 message from the server in state Solicit, continue testing whether the message is a Reply. Ease up the message type checking, it's not fatal if the message is of a wrong type. Add helper functions to set/get the rapid commit of a lease. See RFC 3315, sections 17., 17.1.2., 17.1.4. and 18.1.8.
This commit is contained in:
parent
3dc34fcc97
commit
ed6ee21953
@ -35,6 +35,7 @@ struct sd_dhcp6_lease {
|
||||
uint8_t *serverid;
|
||||
size_t serverid_len;
|
||||
uint8_t preference;
|
||||
bool rapid_commit;
|
||||
|
||||
DHCP6IA ia;
|
||||
|
||||
@ -50,6 +51,9 @@ int dhcp6_lease_set_serverid(sd_dhcp6_lease *lease, const uint8_t *id,
|
||||
int dhcp6_lease_get_serverid(sd_dhcp6_lease *lease, uint8_t **id, size_t *len);
|
||||
int dhcp6_lease_set_preference(sd_dhcp6_lease *lease, uint8_t preference);
|
||||
int dhcp6_lease_get_preference(sd_dhcp6_lease *lease, uint8_t *preference);
|
||||
int dhcp6_lease_set_rapid_commit(sd_dhcp6_lease *lease);
|
||||
int dhcp6_lease_get_rapid_commit(sd_dhcp6_lease *lease, bool *rapid_commit);
|
||||
|
||||
int dhcp6_lease_get_iaid(sd_dhcp6_lease *lease, be32_t *iaid);
|
||||
|
||||
int dhcp6_lease_new(sd_dhcp6_lease **ret);
|
||||
|
@ -58,13 +58,14 @@ int dhcp6_option_append(uint8_t **buf, size_t *buflen, uint16_t code,
|
||||
size_t optlen, const void *optval) {
|
||||
int r;
|
||||
|
||||
assert_return(optval, -EINVAL);
|
||||
assert_return(optval || optlen == 0, -EINVAL);
|
||||
|
||||
r = option_append_hdr(buf, buflen, code, optlen);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
memcpy(*buf, optval, optlen);
|
||||
if (optval)
|
||||
memcpy(*buf, optval, optlen);
|
||||
|
||||
*buf += optlen;
|
||||
*buflen -= optlen;
|
||||
|
@ -252,6 +252,9 @@ 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_RAPID_COMMIT, 0, NULL);
|
||||
|
||||
r = dhcp6_option_append_ia(&opt, &optlen, &client->ia_na);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@ -658,6 +661,13 @@ static int client_parse_message(sd_dhcp6_client *client,
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case DHCP6_OPTION_RAPID_COMMIT:
|
||||
r = dhcp6_lease_set_rapid_commit(lease);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -680,9 +690,10 @@ static int client_receive_reply(sd_dhcp6_client *client, DHCP6Message *reply,
|
||||
{
|
||||
int r;
|
||||
_cleanup_dhcp6_lease_free_ sd_dhcp6_lease *lease = NULL;
|
||||
bool rapid_commit;
|
||||
|
||||
if (reply->type != DHCP6_REPLY)
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
|
||||
r = dhcp6_lease_new(&lease);
|
||||
if (r < 0)
|
||||
@ -692,6 +703,15 @@ static int client_receive_reply(sd_dhcp6_client *client, DHCP6Message *reply,
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (client->state == DHCP6_STATE_SOLICITATION) {
|
||||
r = dhcp6_lease_get_rapid_commit(lease, &rapid_commit);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!rapid_commit)
|
||||
return 0;
|
||||
}
|
||||
|
||||
dhcp6_lease_clear_timers(&client->lease->ia);
|
||||
|
||||
client->lease = sd_dhcp6_lease_unref(client->lease);
|
||||
@ -708,7 +728,7 @@ static int client_receive_advertise(sd_dhcp6_client *client,
|
||||
uint8_t pref_advertise = 0, pref_lease = 0;
|
||||
|
||||
if (advertise->type != DHCP6_ADVERTISE)
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
|
||||
r = dhcp6_lease_new(&lease);
|
||||
if (r < 0)
|
||||
@ -793,11 +813,13 @@ 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)
|
||||
if (r == DHCP6_STATE_REQUEST) {
|
||||
client_start(client, r);
|
||||
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
/* fall through for Soliciation Rapid Commit option check */
|
||||
case DHCP6_STATE_REQUEST:
|
||||
case DHCP6_STATE_RENEW:
|
||||
case DHCP6_STATE_REBIND:
|
||||
|
@ -118,6 +118,23 @@ int dhcp6_lease_get_preference(sd_dhcp6_lease *lease, uint8_t *preference) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dhcp6_lease_set_rapid_commit(sd_dhcp6_lease *lease) {
|
||||
assert_return(lease, -EINVAL);
|
||||
|
||||
lease->rapid_commit = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dhcp6_lease_get_rapid_commit(sd_dhcp6_lease *lease, bool *rapid_commit) {
|
||||
assert_return(lease, -EINVAL);
|
||||
assert_return(rapid_commit, -EINVAL);
|
||||
|
||||
*rapid_commit = lease->rapid_commit;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dhcp6_lease_get_iaid(sd_dhcp6_lease *lease, be32_t *iaid) {
|
||||
assert_return(lease, -EINVAL);
|
||||
assert_return(iaid, -EINVAL);
|
||||
|
Loading…
Reference in New Issue
Block a user