1
0
mirror of https://github.com/systemd/systemd synced 2026-04-03 13:44:55 +02:00

Compare commits

..

No commits in common. "222cd15654fda4ec9d58f866ab57861ab19f5920" and "7e6abd25f42d6e3cbcb6005c5b88beea6ce19fcf" have entirely different histories.

3 changed files with 34 additions and 69 deletions

View File

@ -14,8 +14,6 @@
struct sd_dhcp6_lease { struct sd_dhcp6_lease {
unsigned n_ref; unsigned n_ref;
uint8_t *clientid;
size_t clientid_len;
uint8_t *serverid; uint8_t *serverid;
size_t serverid_len; size_t serverid_len;
uint8_t preference; uint8_t preference;
@ -43,10 +41,9 @@ struct sd_dhcp6_lease {
int dhcp6_lease_ia_rebind_expire(const DHCP6IA *ia, uint32_t *expire); int dhcp6_lease_ia_rebind_expire(const DHCP6IA *ia, uint32_t *expire);
DHCP6IA *dhcp6_lease_free_ia(DHCP6IA *ia); DHCP6IA *dhcp6_lease_free_ia(DHCP6IA *ia);
int dhcp6_lease_set_clientid(sd_dhcp6_lease *lease, const uint8_t *id, size_t len); int dhcp6_lease_set_serverid(sd_dhcp6_lease *lease, const uint8_t *id,
int dhcp6_lease_get_clientid(sd_dhcp6_lease *lease, uint8_t **ret_id, size_t *ret_len); size_t len);
int dhcp6_lease_set_serverid(sd_dhcp6_lease *lease, const uint8_t *id, size_t len); int dhcp6_lease_get_serverid(sd_dhcp6_lease *lease, uint8_t **id, size_t *len);
int dhcp6_lease_get_serverid(sd_dhcp6_lease *lease, uint8_t **ret_id, size_t *ret_len);
int dhcp6_lease_set_preference(sd_dhcp6_lease *lease, uint8_t preference); 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_preference(sd_dhcp6_lease *lease, uint8_t *preference);
int dhcp6_lease_set_rapid_commit(sd_dhcp6_lease *lease); int dhcp6_lease_set_rapid_commit(sd_dhcp6_lease *lease);

View File

@ -884,12 +884,14 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
if (r < 0) if (r < 0)
return r; return r;
/* RFC 8415 Section 21.9. elapsed_usec = time_now - client->transaction_start;
* A client MUST include an Elapsed Time option in messages to indicate how long the client has if (elapsed_usec < 0xffff * USEC_PER_MSEC * 10)
* been trying to complete a DHCP message exchange. */ elapsed_time = htobe16(elapsed_usec / USEC_PER_MSEC / 10);
elapsed_usec = MIN(usec_sub_unsigned(time_now, client->transaction_start) / USEC_PER_MSEC / 10, (usec_t) UINT16_MAX); else
elapsed_time = htobe16(elapsed_usec); elapsed_time = 0xffff;
r = dhcp6_option_append(&opt, &optlen, SD_DHCP6_OPTION_ELAPSED_TIME, sizeof(elapsed_time), &elapsed_time);
r = dhcp6_option_append(&opt, &optlen, SD_DHCP6_OPTION_ELAPSED_TIME,
sizeof(elapsed_time), &elapsed_time);
if (r < 0) if (r < 0)
return r; return r;
@ -989,7 +991,7 @@ static int client_timeout_resend(sd_event_source *s, uint64_t usec, void *userda
case DHCP6_STATE_SOLICITATION: case DHCP6_STATE_SOLICITATION:
if (client->retransmit_count > 0 && client->lease) { if (client->retransmit_count && client->lease) {
client_start(client, DHCP6_STATE_REQUEST); client_start(client, DHCP6_STATE_REQUEST);
return 0; return 0;
} }
@ -1132,6 +1134,7 @@ static int client_parse_message(
uint32_t lt_t1 = UINT32_MAX, lt_t2 = UINT32_MAX; uint32_t lt_t1 = UINT32_MAX, lt_t2 = UINT32_MAX;
usec_t irt = IRT_DEFAULT; usec_t irt = IRT_DEFAULT;
bool clientid = false;
int r; int r;
assert(client); assert(client);
@ -1151,19 +1154,23 @@ static int client_parse_message(
switch (optcode) { switch (optcode) {
case SD_DHCP6_OPTION_CLIENTID: case SD_DHCP6_OPTION_CLIENTID:
if (dhcp6_lease_get_clientid(lease, NULL, NULL) >= 0) if (clientid)
return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL), "%s contains multiple client IDs", return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL), "%s contains multiple clientids",
dhcp6_message_type_to_string(message->type)); dhcp6_message_type_to_string(message->type));
r = dhcp6_lease_set_clientid(lease, optval, optlen); if (optlen != client->duid_len ||
if (r < 0) memcmp(&client->duid, optval, optlen) != 0)
return r; return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL), "%s DUID does not match",
dhcp6_message_type_to_string(message->type));
clientid = true;
break; break;
case SD_DHCP6_OPTION_SERVERID: case SD_DHCP6_OPTION_SERVERID:
if (dhcp6_lease_get_serverid(lease, NULL, NULL) >= 0) r = dhcp6_lease_get_serverid(lease, NULL, NULL);
return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL), "%s contains multiple server IDs", if (r >= 0)
return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL), "%s contains multiple serverids",
dhcp6_message_type_to_string(message->type)); dhcp6_message_type_to_string(message->type));
r = dhcp6_lease_set_serverid(lease, optval, optlen); r = dhcp6_lease_set_serverid(lease, optval, optlen);
@ -1302,15 +1309,8 @@ static int client_parse_message(
} }
} }
uint8_t *clientid; if (!clientid)
size_t clientid_len; return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL), "%s has incomplete options",
if (dhcp6_lease_get_clientid(lease, &clientid, &clientid_len) < 0)
return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL), "%s message does not contain client ID. Ignoring.",
dhcp6_message_type_to_string(message->type));
if (clientid_len != client->duid_len ||
memcmp(clientid, &client->duid, clientid_len) != 0)
return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL), "The client ID in %s message does not match. Ignoring.",
dhcp6_message_type_to_string(message->type)); dhcp6_message_type_to_string(message->type));
if (client->state != DHCP6_STATE_INFORMATION_REQUEST) { if (client->state != DHCP6_STATE_INFORMATION_REQUEST) {

View File

@ -71,43 +71,12 @@ DHCP6IA *dhcp6_lease_free_ia(DHCP6IA *ia) {
return NULL; return NULL;
} }
int dhcp6_lease_set_clientid(sd_dhcp6_lease *lease, const uint8_t *id, size_t len) { int dhcp6_lease_set_serverid(sd_dhcp6_lease *lease, const uint8_t *id,
uint8_t *clientid; size_t len) {
assert_return(lease, -EINVAL);
assert_return(id, -EINVAL);
assert_return(len > 0, -EINVAL);
clientid = memdup(id, len);
if (!clientid)
return -ENOMEM;
free_and_replace(lease->clientid, clientid);
lease->clientid_len = len;
return 0;
}
int dhcp6_lease_get_clientid(sd_dhcp6_lease *lease, uint8_t **ret_id, size_t *ret_len) {
assert_return(lease, -EINVAL);
if (!lease->clientid)
return -ENODATA;
if (ret_id)
*ret_id = lease->clientid;
if (ret_len)
*ret_len = lease->clientid_len;
return 0;
}
int dhcp6_lease_set_serverid(sd_dhcp6_lease *lease, const uint8_t *id, size_t len) {
uint8_t *serverid; uint8_t *serverid;
assert_return(lease, -EINVAL); assert_return(lease, -EINVAL);
assert_return(id, -EINVAL); assert_return(id, -EINVAL);
assert_return(len > 0, -EINVAL);
serverid = memdup(id, len); serverid = memdup(id, len);
if (!serverid) if (!serverid)
@ -119,16 +88,16 @@ int dhcp6_lease_set_serverid(sd_dhcp6_lease *lease, const uint8_t *id, size_t le
return 0; return 0;
} }
int dhcp6_lease_get_serverid(sd_dhcp6_lease *lease, uint8_t **ret_id, size_t *ret_len) { int dhcp6_lease_get_serverid(sd_dhcp6_lease *lease, uint8_t **id, size_t *len) {
assert_return(lease, -EINVAL); assert_return(lease, -EINVAL);
if (!lease->serverid) if (!lease->serverid)
return -ENODATA; return -ENOMSG;
if (ret_id) if (id)
*ret_id = lease->serverid; *id = lease->serverid;
if (ret_len) if (len)
*ret_len = lease->serverid_len; *len = lease->serverid_len;
return 0; return 0;
} }
@ -398,7 +367,6 @@ static sd_dhcp6_lease *dhcp6_lease_free(sd_dhcp6_lease *lease) {
if (!lease) if (!lease)
return NULL; return NULL;
free(lease->clientid);
free(lease->serverid); free(lease->serverid);
dhcp6_lease_free_ia(&lease->ia); dhcp6_lease_free_ia(&lease->ia);
dhcp6_lease_free_ia(&lease->pd); dhcp6_lease_free_ia(&lease->pd);