From 3cdcb528ff8206511034239ba8ac2b335778642a Mon Sep 17 00:00:00 2001 From: Martin Stein Date: Tue, 28 Nov 2017 15:03:28 +0100 Subject: [PATCH] nic_router: advanced timeout configuration Replace former rtt_sec attribute of the tag by more specific (and still optional) attributes for timeouts used in the NIC router (these are also the default values): Details about the new attributes can be found in the README of the router. Issue #2590 --- repos/libports/run/nic_dump.run | 2 +- repos/libports/run/nic_router.run | 8 ++- repos/os/src/server/nic_router/README | 62 ++++++++++++------- .../os/src/server/nic_router/configuration.cc | 7 ++- .../os/src/server/nic_router/configuration.h | 27 ++++++-- repos/os/src/server/nic_router/dhcp_client.cc | 4 +- repos/os/src/server/nic_router/interface.cc | 4 +- repos/os/src/server/nic_router/link.cc | 11 ++-- repos/os/src/server/nic_router/link.h | 8 ++- repos/ports/run/virtualbox_nic_router.run | 4 +- 10 files changed, 91 insertions(+), 46 deletions(-) diff --git a/repos/libports/run/nic_dump.run b/repos/libports/run/nic_dump.run index d0dadbb91..6c05c2c65 100644 --- a/repos/libports/run/nic_dump.run +++ b/repos/libports/run/nic_dump.run @@ -66,7 +66,7 @@ append config { - + diff --git a/repos/libports/run/nic_router.run b/repos/libports/run/nic_router.run index 360afc229..22d9d0ede 100644 --- a/repos/libports/run/nic_router.run +++ b/repos/libports/run/nic_router.run @@ -83,7 +83,13 @@ append config { - + diff --git a/repos/os/src/server/nic_router/README b/repos/os/src/server/nic_router/README index 4eccfc558..64a67b568 100644 --- a/repos/os/src/server/nic_router/README +++ b/repos/os/src/server/nic_router/README @@ -211,31 +211,36 @@ the case if the transfer includes NAT no matter of what kind or for which side. It is desirable to discard a link state as soon as it is not needed anymore. -The more precise the algorithm for that, the more efficient can NIC sessions -use their resources (ports, RAM), and the less is the risk for DoS attacks. -In order to meet this requirement, the router needs to know the round-trip -time of the exchange behind a link state. This value is given through the -attribute 'rtt_sec' in the router's configuration: +The more precise this is done, the more efficient can NIC sessions use their +resources (ports, RAM), and the less is the risk for DoS attacks. Therefore, +the NIC router keeps track of the idle time of a link. Idle time means the +time passed since the last packet was routed using that link regardless of +the direction or content of that packet. The amount of idle time at which +the NIC router shall discard a link state can be configured in the +tag of the router for each link type separately: -! ... +! -This would set the round-trip time to three seconds. The value is used for all -link states so you should choose it with care. If it is too low, replies that -normally need no routing rule may get lost. If it is too high, link states are -held longer than necessary. +This would set the maximum UDP idle time to 30 and the maximum TCP idle time +to 50 seconds. You should choose these values with care. If they are too low, +replies that normally need no routing rule may get lost. If it is too high, +link states are held longer than necessary. -In general, each link state is discarded after a duration of the round-trip -time without a matching packet. For UDP link states, this is the only rule and -better known as hole punching. It allows peers to keep alive a UDP -pseudo-connection through the router by frequently sending empty packets. The -need for such a pseudo-connection arises from the router's demand to support -NAT for UDP transfers and the consequence of keeping the corresponding mapping -information. +For UDP link states, this timeout is the only condition that leads to a +discard. This is better known as hole punching. It allows peers to keep alive +a UDP pseudo-connection through the router by frequently sending empty packets. +The need for such a pseudo-connection arises from the router's demand to +support NAT for UDP transfers and the consequence of keeping the corresponding +mapping information. The lifetime management of TCP link states, in contrast, is more complex. In -addition to the common timeout, they may be discarded even if they still -receive packets. This is the case when the router observed the four-way -termination handshake of TCP and the round-trip time has passed. +addition to the common timeout, they may be discarded also after the router +observed the four-way termination handshake of TCP plus a duration of two +times the maximum segment lifetime. The maximum segment lifetime can be be set +in the tag too: + +! Configuring NAT @@ -297,9 +302,13 @@ assignment in seconds. The IPv4 address range must be in the subnet defined by the interface attribute of the domain tag and must not cover the IPv4 address in this attribute. The dns_server attribute gives the IPv4 address of the DNS server that might also be in another subnet. -The lifetime of an offered assignment is the configured round-trip time of -the router while ip_lease_time_sec is applied only when the offer is -acknowledged by the client in time. +The lifetime of an assignment that was yet only offered to the client +can be configured for all domains in the tag of the router: + +! + +The timeout ip_lease_time_sec is applied only when the offer is acknowledged +by the client in time. Configuring DHCP client functionality @@ -319,6 +328,13 @@ and all other router functionality is disabled for the domain. A domain cannot act as DHCP client and DHCP server at once. So, a 'domain' tag must either have an 'interface' attribute or must not contain a 'dhcp-server' tag. +The timeouts when waiting for the reply of DHCP discover messages and for DHCP +request messages can be configured for all domains in the tag of the +router: + +! + Examples ######## diff --git a/repos/os/src/server/nic_router/configuration.cc b/repos/os/src/server/nic_router/configuration.cc index 7f171b77d..c587cc5d5 100644 --- a/repos/os/src/server/nic_router/configuration.cc +++ b/repos/os/src/server/nic_router/configuration.cc @@ -49,7 +49,12 @@ Configuration::Configuration(Xml_node const node, Allocator &alloc) : _alloc(alloc), _verbose(node.attribute_value("verbose", false)), - _rtt(read_sec_attr(node, "rtt_sec", DEFAULT_RTT_SEC)), + _dhcp_discover_timeout(read_sec_attr(node, "dhcp_discover_timeout_sec", DEFAULT_DHCP_DISCOVER_TIMEOUT_SEC)), + _dhcp_request_timeout (read_sec_attr(node, "dhcp_request_timeout_sec", DEFAULT_DHCP_REQUEST_TIMEOUT_SEC )), + _dhcp_offer_timeout (read_sec_attr(node, "dhcp_offer_timeout_sec", DEFAULT_DHCP_OFFER_TIMEOUT_SEC )), + _udp_idle_timeout (read_sec_attr(node, "udp_idle_timeout_sec", DEFAULT_UDP_IDLE_TIMEOUT_SEC )), + _tcp_idle_timeout (read_sec_attr(node, "tcp_idle_timeout_sec", DEFAULT_TCP_IDLE_TIMEOUT_SEC )), + _tcp_max_segm_lifetime(read_sec_attr(node, "tcp_max_segm_lifetime_sec", DEFAULT_TCP_MAX_SEGM_LIFETIME_SEC)), _node(node) { /* read domains */ diff --git a/repos/os/src/server/nic_router/configuration.h b/repos/os/src/server/nic_router/configuration.h index 82f6e4137..ae7050e28 100644 --- a/repos/os/src/server/nic_router/configuration.h +++ b/repos/os/src/server/nic_router/configuration.h @@ -31,13 +31,23 @@ class Net::Configuration Genode::Allocator &_alloc; bool const _verbose; - Genode::Microseconds const _rtt; + Genode::Microseconds const _dhcp_discover_timeout; + Genode::Microseconds const _dhcp_request_timeout; + Genode::Microseconds const _dhcp_offer_timeout; + Genode::Microseconds const _udp_idle_timeout; + Genode::Microseconds const _tcp_idle_timeout; + Genode::Microseconds const _tcp_max_segm_lifetime; Domain_tree _domains; Genode::Xml_node const _node; public: - enum { DEFAULT_RTT_SEC = 6 }; + enum { DEFAULT_DHCP_DISCOVER_TIMEOUT_SEC = 10 }; + enum { DEFAULT_DHCP_REQUEST_TIMEOUT_SEC = 10 }; + enum { DEFAULT_DHCP_OFFER_TIMEOUT_SEC = 10 }; + enum { DEFAULT_UDP_IDLE_TIMEOUT_SEC = 30 }; + enum { DEFAULT_TCP_IDLE_TIMEOUT_SEC = 600 }; + enum { DEFAULT_TCP_MAX_SEGM_LIFETIME_SEC = 30 }; Configuration(Genode::Xml_node const node, Genode::Allocator &alloc); @@ -46,10 +56,15 @@ class Net::Configuration ** Accessors ** ***************/ - bool verbose() const { return _verbose; } - Genode::Microseconds rtt() const { return _rtt; } - Domain_tree &domains() { return _domains; } - Genode::Xml_node node() const { return _node; } + bool verbose() const { return _verbose; } + Genode::Microseconds dhcp_discover_timeout() const { return _dhcp_discover_timeout; } + Genode::Microseconds dhcp_request_timeout() const { return _dhcp_request_timeout; } + Genode::Microseconds dhcp_offer_timeout() const { return _dhcp_offer_timeout; } + Genode::Microseconds udp_idle_timeout() const { return _udp_idle_timeout; } + Genode::Microseconds tcp_idle_timeout() const { return _tcp_idle_timeout; } + Genode::Microseconds tcp_max_segm_lifetime() const { return _tcp_max_segm_lifetime; } + Domain_tree &domains() { return _domains; } + Genode::Xml_node node() const { return _node; } }; #endif /* _CONFIGURATION_H_ */ diff --git a/repos/os/src/server/nic_router/dhcp_client.cc b/repos/os/src/server/nic_router/dhcp_client.cc index 2d422834d..b87c8f8da 100644 --- a/repos/os/src/server/nic_router/dhcp_client.cc +++ b/repos/os/src/server/nic_router/dhcp_client.cc @@ -41,7 +41,7 @@ Dhcp_client::Dhcp_client(Genode::Allocator &alloc, void Dhcp_client::discover() { - _set_state(State::SELECT, _config().rtt()); + _set_state(State::SELECT, _config().dhcp_discover_timeout()); _send(Message_type::DISCOVER, Ipv4_address(), Ipv4_address()); } @@ -132,7 +132,7 @@ void Dhcp_client::_handle_dhcp_reply(Dhcp_packet &dhcp) if (msg_type != Message_type::OFFER) { throw Packet_ignored("DHCP client expects an offer"); } - _set_state(State::REQUEST, _config().rtt()); + _set_state(State::REQUEST, _config().dhcp_request_timeout()); _send(Message_type::REQUEST, dhcp.yiaddr(), dhcp.option().value()); break; diff --git a/repos/os/src/server/nic_router/interface.cc b/repos/os/src/server/nic_router/interface.cc index 3890e5fe5..cc68785e4 100644 --- a/repos/os/src/server/nic_router/interface.cc +++ b/repos/os/src/server/nic_router/interface.cc @@ -430,7 +430,7 @@ void Interface::_handle_dhcp_request(Ethernet_frame ð, throw Bad_dhcp_request(); } else { - allocation.lifetime(_config().rtt()); + allocation.lifetime(_config().dhcp_offer_timeout()); _send_dhcp_reply(dhcp_srv, eth.src(), allocation.ip(), Dhcp_packet::Message_type::OFFER, @@ -501,7 +501,7 @@ void Interface::_handle_dhcp_request(Ethernet_frame ð, Dhcp_allocation &allocation = *new (_alloc) Dhcp_allocation(*this, dhcp_srv.alloc_ip(), dhcp.client_mac(), _timer, - _config().rtt()); + _config().dhcp_offer_timeout()); _dhcp_allocations.insert(&allocation); if (_config().verbose()) { diff --git a/repos/os/src/server/nic_router/link.cc b/repos/os/src/server/nic_router/link.cc index 5c0b85c2f..fc7938701 100644 --- a/repos/os/src/server/nic_router/link.cc +++ b/repos/os/src/server/nic_router/link.cc @@ -117,14 +117,15 @@ Link::Link(Interface &cln_interface, Link_side_id const &srv_id, Timer::Connection &timer, Configuration &config, - L3_protocol const protocol) + L3_protocol const protocol, + Microseconds const close_timeout) : _config(config), _client(cln_interface, cln_id, *this), _server_port_alloc(srv_port_alloc), _server(srv_interface, srv_id, *this), _close_timeout(timer, *this, &Link::_handle_close_timeout), - _close_timeout_us(_config.rtt()), + _close_timeout_us(close_timeout), _protocol(protocol) { _close_timeout.schedule(_close_timeout_us); @@ -172,14 +173,14 @@ Tcp_link::Tcp_link(Interface &cln_interface, L3_protocol const protocol) : Link(cln_interface, cln_id, srv_port_alloc, srv_interface, srv_id, timer, - config, protocol) + config, protocol, config.tcp_idle_timeout()) { } void Tcp_link::_fin_acked() { if (_server_fin_acked && _client_fin_acked) { - _close_timeout.schedule(_close_timeout_us); + _close_timeout.schedule(Microseconds(config().tcp_max_segm_lifetime().value << 1)); _closed = true; } } @@ -233,5 +234,5 @@ Udp_link::Udp_link(Interface &cln_interface, L3_protocol const protocol) : Link(cln_interface, cln_id, srv_port_alloc, srv_interface, srv_id, timer, - config, protocol) + config, protocol, config.udp_idle_timeout()) { } diff --git a/repos/os/src/server/nic_router/link.h b/repos/os/src/server/nic_router/link.h index 8cd4cbc90..f1e3a1f77 100644 --- a/repos/os/src/server/nic_router/link.h +++ b/repos/os/src/server/nic_router/link.h @@ -147,7 +147,8 @@ class Net::Link : public Link_list::Element Link_side_id const &srv_id, Timer::Connection &timer, Configuration &config, - L3_protocol const protocol); + L3_protocol const protocol, + Genode::Microseconds const close_timeout); void dissolve(); @@ -163,8 +164,9 @@ class Net::Link : public Link_list::Element ** Accessors ** ***************/ - Link_side &client() { return _client; } - Link_side &server() { return _server; } + Link_side &client() { return _client; } + Link_side &server() { return _server; } + Configuration &config() { return _config; } }; diff --git a/repos/ports/run/virtualbox_nic_router.run b/repos/ports/run/virtualbox_nic_router.run index 8d539b489..709d6c0e7 100644 --- a/repos/ports/run/virtualbox_nic_router.run +++ b/repos/ports/run/virtualbox_nic_router.run @@ -98,7 +98,7 @@ append_if [expr $use_net] config { - + @@ -126,7 +126,7 @@ append_if [expr $use_net] config { - +