nic_router: no DHCP fail on unexpected DISCOVER

If a client decides to spontaneously send a DHCP DISCOVER again, even though
he has received a still valid IP config from the router, we don't want to
discard the DISCOVER like it was done before but discard the IP config
assignment and offer a new one.

Issue #2534
This commit is contained in:
Martin Stein 2017-12-05 15:45:54 +01:00 committed by Christian Helmuth
parent 70c5c31ec9
commit 9c0bd03363
2 changed files with 34 additions and 17 deletions

View File

@ -409,6 +409,28 @@ void Interface::_release_dhcp_allocation(Dhcp_allocation &allocation)
}
void Interface::_new_dhcp_allocation(Ethernet_frame &eth,
Dhcp_packet &dhcp,
Dhcp_server &dhcp_srv)
{
Dhcp_allocation &allocation = *new (_alloc)
Dhcp_allocation(*this, dhcp_srv.alloc_ip(),
dhcp.client_mac(), _timer,
_config().dhcp_offer_timeout());
_dhcp_allocations.insert(&allocation);
if (_config().verbose()) {
log("Offer IP allocation: ", allocation,
" at ", *this);
}
_send_dhcp_reply(dhcp_srv, eth.src(),
allocation.ip(),
Dhcp_packet::Message_type::OFFER,
dhcp.xid());
return;
}
void Interface::_handle_dhcp_request(Ethernet_frame &eth,
Genode::size_t eth_size,
Dhcp_packet &dhcp)
@ -430,7 +452,11 @@ void Interface::_handle_dhcp_request(Ethernet_frame &eth,
case Dhcp_packet::Message_type::DISCOVER:
if (allocation.bound()) {
throw Drop_packet_warn("DHCP DISCOVER from client expected to be in DHCP BOUND state");
_release_dhcp_allocation(allocation);
_destroy_dhcp_allocation(allocation);
_new_dhcp_allocation(eth, dhcp, dhcp_srv);
return;
} else {
allocation.lifetime(_config().dhcp_offer_timeout());
@ -500,23 +526,10 @@ void Interface::_handle_dhcp_request(Ethernet_frame &eth,
switch (msg_type) {
case Dhcp_packet::Message_type::DISCOVER:
{
Dhcp_allocation &allocation = *new (_alloc)
Dhcp_allocation(*this, dhcp_srv.alloc_ip(),
dhcp.client_mac(), _timer,
_config().dhcp_offer_timeout());
_dhcp_allocations.insert(&allocation);
if (_config().verbose()) {
log("Offer IP allocation: ", allocation,
" at ", *this);
}
_send_dhcp_reply(dhcp_srv, eth.src(),
allocation.ip(),
Dhcp_packet::Message_type::OFFER,
dhcp.xid());
return;
}
_new_dhcp_allocation(eth, dhcp, dhcp_srv);
return;
case Dhcp_packet::Message_type::REQUEST: throw Drop_packet_warn("DHCP REQUEST from client without offered/acked IP");
case Dhcp_packet::Message_type::DECLINE: throw Drop_packet_warn("DHCP DECLINE from client without offered/acked IP");
case Dhcp_packet::Message_type::RELEASE: throw Drop_packet_warn("DHCP RELEASE from client without offered/acked IP");

View File

@ -86,6 +86,10 @@ class Net::Interface
void _release_dhcp_allocation(Dhcp_allocation &allocation);
void _new_dhcp_allocation(Ethernet_frame &eth,
Dhcp_packet &dhcp,
Dhcp_server &dhcp_srv);
void _send_dhcp_reply(Dhcp_server const &dhcp_srv,
Mac_address const &client_mac,
Ipv4_address const &client_ip,