From f59ee209d2177a2978791a226dde74d332d4bdf5 Mon Sep 17 00:00:00 2001 From: Martin Stein Date: Mon, 26 Sep 2022 16:03:37 +0200 Subject: [PATCH] nic_router: use exact packet sizes in dhcp client The DHCP client used to always send packets with a size of 1024 regardless of the size of the actual content, which was always significantly lower. 1024 bytes was simply a guess to provide enough space for all types of DHCP client packets. As we know the exact size of each packet the DHCP client sends even before packet creation, this commit makes use of the knowledge resulting in much smaller packets sent by the DHCP client. Fixes #4619 --- repos/os/src/server/nic_router/dhcp_client.cc | 22 +++++++++++-------- repos/os/src/server/nic_router/dhcp_client.h | 3 ++- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/repos/os/src/server/nic_router/dhcp_client.cc b/repos/os/src/server/nic_router/dhcp_client.cc index 936d3a94cf..99e499a7c6 100644 --- a/repos/os/src/server/nic_router/dhcp_client.cc +++ b/repos/os/src/server/nic_router/dhcp_client.cc @@ -17,8 +17,6 @@ #include #include -enum { PKT_SIZE = 1024 }; - using namespace Genode; using namespace Net; using Message_type = Dhcp_packet::Message_type; @@ -64,17 +62,20 @@ Dhcp_client::Dhcp_client(Cached_timer &timer, void Dhcp_client::discover() { + enum { DISCOVER_PKT_SIZE = 309 }; _set_state(State::SELECT, _config().dhcp_discover_timeout()); _send(Message_type::DISCOVER, Ipv4_address(), Ipv4_address(), - Ipv4_address()); + Ipv4_address(), DISCOVER_PKT_SIZE); } void Dhcp_client::_rerequest(State next_state) { + enum { REREQUEST_PKT_SIZE = 309 }; _set_state(next_state, _rerequest_timeout(2)); Ipv4_address const client_ip = _domain().ip_config().interface().address; - _send(Message_type::REQUEST, client_ip, Ipv4_address(), client_ip); + _send(Message_type::REQUEST, client_ip, Ipv4_address(), client_ip, + REREQUEST_PKT_SIZE); } @@ -129,10 +130,11 @@ void Dhcp_client::handle_dhcp_reply(Dhcp_packet &dhcp) if (msg_type != Message_type::OFFER) { throw Drop_packet("DHCP client expects an offer"); } + enum { REQUEST_PKT_SIZE = 321 }; _set_state(State::REQUEST, _config().dhcp_request_timeout()); _send(Message_type::REQUEST, Ipv4_address(), dhcp.option().value(), - dhcp.yiaddr()); + dhcp.yiaddr(), REQUEST_PKT_SIZE); break; case State::REQUEST: @@ -159,10 +161,11 @@ void Dhcp_client::handle_dhcp_reply(Dhcp_packet &dhcp) void Dhcp_client::_send(Message_type msg_type, Ipv4_address client_ip, Ipv4_address server_ip, - Ipv4_address requested_ip) + Ipv4_address requested_ip, + size_t pkt_size) { Mac_address client_mac = _interface.router_mac(); - _interface.send(PKT_SIZE, [&] (void *pkt_base, Size_guard &size_guard) { + _interface.send(pkt_size, [&] (void *pkt_base, Size_guard &size_guard) { /* create ETH header of the request */ Ethernet_frame ð = Ethernet_frame::construct_at(pkt_base, size_guard); @@ -198,19 +201,20 @@ void Dhcp_client::_send(Message_type msg_type, dhcp.default_magic_cookie(); /* append DHCP option fields to the request */ + enum { MAX_PKT_SIZE = 1024 }; Dhcp_options dhcp_opts(dhcp, size_guard); dhcp_opts.append_option(msg_type); switch (msg_type) { case Message_type::DISCOVER: append_param_req_list(dhcp_opts); dhcp_opts.append_option(client_mac); - dhcp_opts.append_option(PKT_SIZE - dhcp_off); + dhcp_opts.append_option(MAX_PKT_SIZE - dhcp_off); break; case Message_type::REQUEST: append_param_req_list(dhcp_opts); dhcp_opts.append_option(client_mac); - dhcp_opts.append_option(PKT_SIZE - dhcp_off); + dhcp_opts.append_option(MAX_PKT_SIZE - dhcp_off); if (_state == State::REQUEST) { dhcp_opts.append_option(requested_ip); dhcp_opts.append_option(server_ip); diff --git a/repos/os/src/server/nic_router/dhcp_client.h b/repos/os/src/server/nic_router/dhcp_client.h index 887e9a6b99..066cdc726a 100644 --- a/repos/os/src/server/nic_router/dhcp_client.h +++ b/repos/os/src/server/nic_router/dhcp_client.h @@ -54,7 +54,8 @@ class Net::Dhcp_client void _send(Dhcp_packet::Message_type msg_type, Ipv4_address client_ip, Ipv4_address server_ip, - Ipv4_address requested_ip); + Ipv4_address requested_ip, + Genode::size_t pkt_size); Configuration &_config();