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.
uint8_t *serverid;
size_t serverid_len;
uint8_t preference;
uint8_t *serverid;
size_t serverid_len;
uint8_t preference;
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_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);
int dhcp6_lease_get_iaid(sd_dhcp6_lease *lease, be32_t *iaid);
int dhcp6_lease_new(sd_dhcp6_lease **ret);
size_t optlen, const void *optval) {
int r;
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;
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;
*buf += optlen;
*buflen -= optlen;
case DHCP6_STATE_SOLICITATION:
message->type = DHCP6_SOLICIT;
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;
r = dhcp6_option_append_ia(&opt, &optlen, &client->ia_na);
if (r < 0)
return r;
+
+ case DHCP6_OPTION_RAPID_COMMIT:
+ r = dhcp6_lease_set_rapid_commit(lease);
+ if (r < 0)
+ return r;
+
+ break;
{
int r;
_cleanup_dhcp6_lease_free_ sd_dhcp6_lease *lease = NULL;
{
int r;
_cleanup_dhcp6_lease_free_ sd_dhcp6_lease *lease = NULL;
if (reply->type != DHCP6_REPLY)
if (reply->type != DHCP6_REPLY)
r = dhcp6_lease_new(&lease);
if (r < 0)
r = dhcp6_lease_new(&lease);
if (r < 0)
+ 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);
dhcp6_lease_clear_timers(&client->lease->ia);
client->lease = sd_dhcp6_lease_unref(client->lease);
uint8_t pref_advertise = 0, pref_lease = 0;
if (advertise->type != DHCP6_ADVERTISE)
uint8_t pref_advertise = 0, pref_lease = 0;
if (advertise->type != DHCP6_ADVERTISE)
r = dhcp6_lease_new(&lease);
if (r < 0)
r = dhcp6_lease_new(&lease);
if (r < 0)
case DHCP6_STATE_SOLICITATION:
r = client_receive_advertise(client, message, len);
case DHCP6_STATE_SOLICITATION:
r = client_receive_advertise(client, message, len);
- if (r == DHCP6_STATE_REQUEST)
+ if (r == DHCP6_STATE_REQUEST) {
+ /* fall through for Soliciation Rapid Commit option check */
case DHCP6_STATE_REQUEST:
case DHCP6_STATE_RENEW:
case DHCP6_STATE_REBIND:
case DHCP6_STATE_REQUEST:
case DHCP6_STATE_RENEW:
case DHCP6_STATE_REBIND:
+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);
int dhcp6_lease_get_iaid(sd_dhcp6_lease *lease, be32_t *iaid) {
assert_return(lease, -EINVAL);
assert_return(iaid, -EINVAL);