1
0
mirror of https://github.com/systemd/systemd synced 2026-03-19 19:44:48 +01:00

Compare commits

..

No commits in common. "6222acc2b59309ac6187450d9e65eceb1b7cc1c5" and "4dbad977ff153f1457fd3ec5bc06b5b7e6414cc0" have entirely different histories.

View File

@ -1587,17 +1587,9 @@ static int client_handle_forcerenew(sd_dhcp_client *client, DHCPMessage *force,
if (r != DHCP_FORCERENEW) if (r != DHCP_FORCERENEW)
return -ENOMSG; return -ENOMSG;
#if 0
log_dhcp_client(client, "FORCERENEW"); log_dhcp_client(client, "FORCERENEW");
return 0; return 0;
#else
/* FIXME: Ignore FORCERENEW requests until we implement RFC3118 (Authentication for DHCP
* Messages) and/or RFC6704 (Forcerenew Nonce Authentication), as unauthenticated FORCERENEW
* requests causes a security issue (TALOS-2020-1142, CVE-2020-13529). */
log_dhcp_client(client, "Received FORCERENEW, ignoring.");
return -ENOMSG;
#endif
} }
static bool lease_equal(const sd_dhcp_lease *a, const sd_dhcp_lease *b) { static bool lease_equal(const sd_dhcp_lease *a, const sd_dhcp_lease *b) {
@ -1785,7 +1777,7 @@ static int client_set_lease_timeouts(sd_dhcp_client *client) {
static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, int len) { static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, int len) {
DHCP_CLIENT_DONT_DESTROY(client); DHCP_CLIENT_DONT_DESTROY(client);
char time_string[FORMAT_TIMESPAN_MAX]; char time_string[FORMAT_TIMESPAN_MAX];
int r, notify_event; int r = 0, notify_event = 0;
assert(client); assert(client);
assert(client->event); assert(client->event);
@ -1795,10 +1787,7 @@ static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, i
case DHCP_STATE_SELECTING: case DHCP_STATE_SELECTING:
r = client_handle_offer(client, message, len); r = client_handle_offer(client, message, len);
if (r == -ENOMSG) if (r >= 0) {
return 0; /* invalid message, let's ignore it */
if (r < 0)
goto error;
client->state = DHCP_STATE_REQUESTING; client->state = DHCP_STATE_REQUESTING;
client->attempt = 0; client->attempt = 0;
@ -1808,6 +1797,12 @@ static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, i
0, 0, 0, 0,
client_timeout_resend, client, client_timeout_resend, client,
client->event_priority, "dhcp4-resend-timer", true); client->event_priority, "dhcp4-resend-timer", true);
if (r < 0)
goto error;
} else if (r == -ENOMSG)
/* invalid message, let's ignore it */
return 0;
break; break;
case DHCP_STATE_REBOOTING: case DHCP_STATE_REBOOTING:
@ -1816,40 +1811,19 @@ static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, i
case DHCP_STATE_REBINDING: case DHCP_STATE_REBINDING:
r = client_handle_ack(client, message, len); r = client_handle_ack(client, message, len);
if (r == -ENOMSG) if (r >= 0) {
return 0; /* invalid message, let's ignore it */
if (r == -EADDRNOTAVAIL) {
/* got a NAK, let's restart the client */
client_notify(client, SD_DHCP_CLIENT_EVENT_EXPIRED);
r = client_initialize(client);
if (r < 0)
goto error;
r = client_start_delayed(client);
if (r < 0)
goto error;
log_dhcp_client(client, "REBOOT in %s", format_timespan(time_string, FORMAT_TIMESPAN_MAX,
client->start_delay, USEC_PER_SEC));
client->start_delay = CLAMP(client->start_delay * 2,
RESTART_AFTER_NAK_MIN_USEC, RESTART_AFTER_NAK_MAX_USEC);
return 0;
}
if (r < 0)
goto error;
if (IN_SET(client->state, DHCP_STATE_REQUESTING, DHCP_STATE_REBOOTING))
notify_event = SD_DHCP_CLIENT_EVENT_IP_ACQUIRE;
else
notify_event = r;
client->start_delay = 0; client->start_delay = 0;
(void) event_source_disable(client->timeout_resend); (void) event_source_disable(client->timeout_resend);
client->receive_message = sd_event_source_unref(client->receive_message); client->receive_message =
sd_event_source_unref(client->receive_message);
client->fd = safe_close(client->fd); client->fd = safe_close(client->fd);
if (IN_SET(client->state, DHCP_STATE_REQUESTING,
DHCP_STATE_REBOOTING))
notify_event = SD_DHCP_CLIENT_EVENT_IP_ACQUIRE;
else if (r != SD_DHCP_CLIENT_EVENT_IP_ACQUIRE)
notify_event = r;
client->state = DHCP_STATE_BOUND; client->state = DHCP_STATE_BOUND;
client->attempt = 0; client->attempt = 0;
@ -1871,35 +1845,57 @@ static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, i
client_initialize_io_events(client, client_receive_message_udp); client_initialize_io_events(client, client_receive_message_udp);
if (IN_SET(client->state, DHCP_STATE_RENEWING, DHCP_STATE_REBINDING) && if (notify_event) {
notify_event == SD_DHCP_CLIENT_EVENT_IP_ACQUIRE)
/* FIXME: hmm, maybe this is a bug... */
log_dhcp_client(client, "client_handle_ack() returned SD_DHCP_CLIENT_EVENT_IP_ACQUIRE while DHCP client is %s the address, skipping callback.",
client->state == DHCP_STATE_RENEWING ? "renewing" : "rebinding");
else
client_notify(client, notify_event); client_notify(client, notify_event);
if (client->state == DHCP_STATE_STOPPED)
return 0;
}
} else if (r == -EADDRNOTAVAIL) {
/* got a NAK, let's restart the client */
client_notify(client, SD_DHCP_CLIENT_EVENT_EXPIRED);
r = client_initialize(client);
if (r < 0)
goto error;
r = client_start_delayed(client);
if (r < 0)
goto error;
log_dhcp_client(client, "REBOOT in %s", format_timespan(time_string, FORMAT_TIMESPAN_MAX,
client->start_delay, USEC_PER_SEC));
client->start_delay = CLAMP(client->start_delay * 2,
RESTART_AFTER_NAK_MIN_USEC, RESTART_AFTER_NAK_MAX_USEC);
return 0;
} else if (r == -ENOMSG)
/* invalid message, let's ignore it */
return 0;
break; break;
case DHCP_STATE_BOUND: case DHCP_STATE_BOUND:
r = client_handle_forcerenew(client, message, len); r = client_handle_forcerenew(client, message, len);
if (r == -ENOMSG) if (r >= 0) {
return 0; /* invalid message, let's ignore it */ r = client_timeout_t1(NULL, 0, client);
if (r < 0) if (r < 0)
goto error; goto error;
} else if (r == -ENOMSG)
/* invalid message, let's ignore it */
return 0;
r = client_timeout_t1(NULL, 0, client);
break; break;
case DHCP_STATE_INIT: case DHCP_STATE_INIT:
case DHCP_STATE_INIT_REBOOT: case DHCP_STATE_INIT_REBOOT:
r = 0;
break; break;
case DHCP_STATE_STOPPED: case DHCP_STATE_STOPPED:
r = -EINVAL; r = -EINVAL;
goto error; goto error;
default:
assert_not_reached("invalid state");
} }
error: error: