mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-01 08:48:20 +00:00
nic_router: advanced timeout configuration
Replace former rtt_sec attribute of the <config> tag by more specific (and still optional) attributes for timeouts used in the NIC router (these are also the default values): <config dhcp_discover_timeout_sec="10" dhcp_request_timeout_sec="10" dhcp_offer_timeout_sec="10" udp_idle_timeout_sec="30" tcp_idle_timeout_sec="600" tcp_max_segm_lifetime_sec="30"> Details about the new attributes can be found in the README of the router. Issue #2590
This commit is contained in:
parent
564e6a6885
commit
3cdcb528ff
@ -66,7 +66,7 @@ append config {
|
||||
<start name="nic_router" caps="200" priority="-1">
|
||||
<resource name="RAM" quantum="10M"/>
|
||||
<provides><service name="Nic"/></provides>
|
||||
<config rtt_sec="6" verbose="no">
|
||||
<config verbose="no">
|
||||
|
||||
<policy label_prefix="udp_client_1" domain="udp_client_1" />
|
||||
<policy label_prefix="http_client_3" domain="http_client_3" />
|
||||
|
@ -83,7 +83,13 @@ append config {
|
||||
<start name="nic_router" caps="200" priority="-1">
|
||||
<resource name="RAM" quantum="10M"/>
|
||||
<provides><service name="Nic"/></provides>
|
||||
<config rtt_sec="12" verbose="no">
|
||||
<config verbose="no"
|
||||
dhcp_discover_timeout_sec="3"
|
||||
dhcp_request_timeout_sec="3"
|
||||
dhcp_offer_timeout_sec="3"
|
||||
udp_idle_timeout_sec="30"
|
||||
tcp_idle_timeout_sec="30"
|
||||
tcp_max_segm_lifetime_sec="15">
|
||||
|
||||
<policy label_prefix="udp_client_1" domain="udp_client_1" />
|
||||
<policy label_prefix="http_client_3" domain="http_client_3" />
|
||||
|
@ -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 <config>
|
||||
tag of the router for each link type separately:
|
||||
|
||||
! <config rtt_sec="3"> ... </config>
|
||||
! <config udp_idle_timeout_sec="30"
|
||||
! tcp_idle_timeout_sec="50">
|
||||
|
||||
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 <config> tag too:
|
||||
|
||||
! <config tcp_max_segm_lifetime_sec="20">
|
||||
|
||||
|
||||
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 <config> tag of the router:
|
||||
|
||||
! <config dhcp_offer_timeout_sec="6">
|
||||
|
||||
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 <config> tag of the
|
||||
router:
|
||||
|
||||
! <config dhcp_discover_timeout_sec="10"
|
||||
! dhcp_request_timeout_sec="6">
|
||||
|
||||
|
||||
Examples
|
||||
########
|
||||
|
@ -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 */
|
||||
|
@ -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_ */
|
||||
|
@ -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<Dhcp_packet::Server_ipv4>().value());
|
||||
break;
|
||||
|
@ -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()) {
|
||||
|
@ -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())
|
||||
{ }
|
||||
|
@ -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; }
|
||||
};
|
||||
|
||||
|
||||
|
@ -98,7 +98,7 @@ append_if [expr $use_net] config {
|
||||
<binary name="nic_router"/>
|
||||
<resource name="RAM" quantum="10M"/>
|
||||
<provides><service name="Nic"/></provides>
|
||||
<config rtt_sec="6" verbose="yes">
|
||||
<config verbose="yes">
|
||||
|
||||
<policy label_prefix="router2" domain="router2"/>
|
||||
|
||||
@ -126,7 +126,7 @@ append_if [expr $use_net] config {
|
||||
<binary name="nic_router"/>
|
||||
<resource name="RAM" quantum="10M"/>
|
||||
<provides><service name="Nic"/></provides>
|
||||
<config rtt_sec="6" verbose="yes">
|
||||
<config verbose="yes">
|
||||
|
||||
<policy label_prefix="vbox1" domain="vbox"/>
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user