diff --git a/repos/os/src/server/nic_router/interface.cc b/repos/os/src/server/nic_router/interface.cc index b6415b84f..8ec87f7a9 100644 --- a/repos/os/src/server/nic_router/interface.cc +++ b/repos/os/src/server/nic_router/interface.cc @@ -16,6 +16,7 @@ #include #include #include +#include /* local includes */ #include @@ -30,6 +31,9 @@ using Genode::log; using Genode::error; using Genode::warning; using Genode::construct_at; +using Genode::Quota_guard; +using Genode::Ram_quota; +using Genode::Constructible; using Genode::Signal_context_capability; using Genode::Signal_transmitter; @@ -345,16 +349,37 @@ Interface::_new_link(L3_protocol const protocol, { switch (protocol) { case L3_protocol::TCP: - new (_alloc) Tcp_link(*this, local, remote_port_alloc, remote_domain, - remote, _timer, _config(), protocol); + try { + new (_alloc) + Tcp_link { *this, local, remote_port_alloc, remote_domain, + remote, _timer, _config(), protocol }; + } + catch (Quota_guard::Limit_exceeded) { + throw Drop_packet_inform( + "RAM quota exhausted during allocation of TCP link"); + } break; case L3_protocol::UDP: - new (_alloc) Udp_link(*this, local, remote_port_alloc, remote_domain, - remote, _timer, _config(), protocol); + try { + new (_alloc) + Udp_link { *this, local, remote_port_alloc, remote_domain, + remote, _timer, _config(), protocol }; + } + catch (Quota_guard::Limit_exceeded) { + throw Drop_packet_inform( + "RAM quota exhausted during allocation of UDP link"); + } break; case L3_protocol::ICMP: - new (_alloc) Icmp_link(*this, local, remote_port_alloc, remote_domain, - remote, _timer, _config(), protocol); + try { + new (_alloc) + Icmp_link { *this, local, remote_port_alloc, remote_domain, + remote, _timer, _config(), protocol }; + } + catch (Quota_guard::Limit_exceeded) { + throw Drop_packet_inform( + "RAM quota exhausted during allocation of ICMP link"); + } break; default: throw Bad_transport_protocol(); } } @@ -403,7 +428,11 @@ void Interface::_adapt_eth(Ethernet_frame ð, interface._broadcast_arp_request(remote_ip_cfg.interface.address, hop_ip); }); - new (_alloc) Arp_waiter(*this, remote_domain, hop_ip, pkt); + try { new (_alloc) Arp_waiter { *this, remote_domain, hop_ip, pkt }; } + catch (Quota_guard::Limit_exceeded) { + throw Drop_packet_inform( + "RAM quota exhausted during allocation of ARP waiter"); + } throw Packet_postponed(); } } @@ -526,22 +555,26 @@ void Interface::_new_dhcp_allocation(Ethernet_frame ð, Dhcp_server &dhcp_srv, Domain &local_domain) { - Dhcp_allocation &allocation = *new (_alloc) - Dhcp_allocation(*this, dhcp_srv.alloc_ip(), - dhcp.client_mac(), _timer, - _config().dhcp_offer_timeout()); + try { + 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 DHCP allocation: ", allocation, - " at ", local_domain); + _dhcp_allocations.insert(allocation); + if (_config().verbose()) { + log("Offer DHCP allocation: ", allocation, + " at ", local_domain); + } + _send_dhcp_reply(dhcp_srv, eth.src(), dhcp.client_mac(), + allocation.ip(), + Dhcp_packet::Message_type::OFFER, + dhcp.xid(), + local_domain.ip_config().interface); + } + catch (Quota_guard::Limit_exceeded) { + throw Drop_packet_inform( + "RAM quota exhausted during allocation of DHCP allocation"); } - _send_dhcp_reply(dhcp_srv, eth.src(), dhcp.client_mac(), - allocation.ip(), - Dhcp_packet::Message_type::OFFER, - dhcp.xid(), - local_domain.ip_config().interface); - return; } @@ -1600,9 +1633,7 @@ void Interface::handle_config_2() _attach_to_domain_raw(new_domain); /* remember that the interface stays attached to the same domain */ - _update_domain = *new (_alloc) - Update_domain { old_domain, new_domain }; - + _update_domain.construct(old_domain, new_domain); return; } catch (Domain_tree::No_match) { @@ -1628,11 +1659,10 @@ void Interface::handle_config_3() * interface already got detached from its old domain and there is * nothing to update. */ - Update_domain &update_domain = _update_domain(); + Update_domain &update_domain = *_update_domain; Domain &old_domain = update_domain.old_domain; Domain &new_domain = update_domain.new_domain; - destroy(_alloc, &update_domain); - _update_domain = Pointer(); + _update_domain.destruct(); /* if the IP configs differ, detach completely from the IP config */ if (old_domain.ip_config() != new_domain.ip_config()) { @@ -1650,7 +1680,7 @@ void Interface::handle_config_3() _update_dhcp_allocations(old_domain, new_domain); _update_own_arp_waiters(new_domain); } - catch (Pointer::Invalid) { + catch (Constructible::Deref_unconstructed_object) { /* if the interface moved to another domain, finish the operation */ try { attach_to_domain_finish(); } diff --git a/repos/os/src/server/nic_router/interface.h b/repos/os/src/server/nic_router/interface.h index ae19c943d..1984edb39 100644 --- a/repos/os/src/server/nic_router/interface.h +++ b/repos/os/src/server/nic_router/interface.h @@ -76,35 +76,42 @@ class Net::Interface : private Interface_list::Element { Domain &old_domain; Domain &new_domain; + + Update_domain(Domain &old_domain, + Domain &new_domain) + : + old_domain(old_domain), + new_domain(new_domain) + { } }; - Packet_stream_sink &_sink; - Packet_stream_source &_source; - bool &_session_link_state; - Signal_context_capability _session_link_state_sigh { }; - Signal_handler _sink_ack; - Signal_handler _sink_submit; - Signal_handler _source_ack; - Signal_handler _source_submit; - Mac_address const _router_mac; - Mac_address const _mac; - Reference _config; - Interface_policy &_policy; - Timer::Connection &_timer; - Genode::Allocator &_alloc; - Pointer _domain { }; - Arp_waiter_list _own_arp_waiters { }; - Link_list _tcp_links { }; - Link_list _udp_links { }; - Link_list _icmp_links { }; - Link_list _dissolved_tcp_links { }; - Link_list _dissolved_udp_links { }; - Link_list _dissolved_icmp_links { }; - Dhcp_allocation_tree _dhcp_allocations { }; - Dhcp_allocation_list _released_dhcp_allocations { }; - Dhcp_client _dhcp_client { _alloc, _timer, *this }; - Interface_list &_interfaces; - Pointer _update_domain { }; + Packet_stream_sink &_sink; + Packet_stream_source &_source; + bool &_session_link_state; + Signal_context_capability _session_link_state_sigh { }; + Signal_handler _sink_ack; + Signal_handler _sink_submit; + Signal_handler _source_ack; + Signal_handler _source_submit; + Mac_address const _router_mac; + Mac_address const _mac; + Reference _config; + Interface_policy &_policy; + Timer::Connection &_timer; + Genode::Allocator &_alloc; + Pointer _domain { }; + Arp_waiter_list _own_arp_waiters { }; + Link_list _tcp_links { }; + Link_list _udp_links { }; + Link_list _icmp_links { }; + Link_list _dissolved_tcp_links { }; + Link_list _dissolved_udp_links { }; + Link_list _dissolved_icmp_links { }; + Dhcp_allocation_tree _dhcp_allocations { }; + Dhcp_allocation_list _released_dhcp_allocations { }; + Dhcp_client _dhcp_client { _alloc, _timer, *this }; + Interface_list &_interfaces; + Genode::Constructible _update_domain { }; void _new_link(L3_protocol const protocol, Link_side_id const &local_id,