diff --git a/repos/os/include/net/dhcp.h b/repos/os/include/net/dhcp.h index c23aaca91e..6429ebb2f8 100644 --- a/repos/os/include/net/dhcp.h +++ b/repos/os/include/net/dhcp.h @@ -127,6 +127,7 @@ class Net::Dhcp_packet SUBNET_MASK = 1, ROUTER = 3, DNS_SERVER = 6, + DOMAIN_NAME = 15, BROADCAST_ADDR = 28, REQ_IP_ADDR = 50, IP_LEASE_TIME = 51, @@ -227,6 +228,28 @@ class Net::Dhcp_packet } }; + /** + * Domain name option + */ + class Domain_name : public Option + { + private: + + char _name[0]; + + public: + + static constexpr Code CODE = Code::DOMAIN_NAME; + + Domain_name (Genode::size_t len) : Option(CODE, len) { } + + template + void with_string(FUNC && func) const + { + func(_name, Option::len()); + } + }; + enum class Message_type : Genode::uint8_t { DISCOVER = 1, OFFER = 2, @@ -442,6 +465,16 @@ class Net::Dhcp_packet _base += header_size + data.size(); } + + void append_domain_name(char const *data_src, + Genode::size_t data_size) + { + Genode::size_t const header_size { sizeof(Domain_name) }; + _size_guard.consume_head(header_size + data_size); + Genode::memcpy((char *)(_base + header_size), data_src, data_size); + Genode::construct_at((void *)_base, data_size); + _base += header_size + data_size; + } }; diff --git a/repos/os/run/nic_router_dhcp.inc b/repos/os/run/nic_router_dhcp.inc index 2d07917ff3..5b0db45e59 100644 --- a/repos/os/run/nic_router_dhcp.inc +++ b/repos/os/run/nic_router_dhcp.inc @@ -63,6 +63,7 @@ append config { + @@ -96,7 +97,7 @@ append config { - + @@ -106,6 +107,7 @@ append config { ip_last="10.2.4.2"> + @@ -126,6 +128,8 @@ append config { + + @@ -145,6 +149,8 @@ append config { + + @@ -281,6 +287,7 @@ append done_string ".* Router: 10.0.3.1.*\n" append done_string ".* DNS server #1: 1.2.3.4.*\n" append done_string ".* DNS server #2: 2.3.4.5.*\n" append done_string ".* DNS server #3: 3.4.5.6.*\n" +append done_string ".* DNS domain name: genode.org.*\n" append done_string ".*DHCP request completed:.*\n" append done_string ".* IP lease time: 3600 seconds.*\n" append done_string ".* Interface: 10.0.3.2/24.*\n" @@ -296,10 +303,12 @@ append done_string ".*DHCP request completed:.*\n" append done_string ".* IP lease time: 3600 seconds.*\n" append done_string ".* Interface: 10.0.3.2/24.*\n" append done_string ".* Router: 10.0.3.1.*\n" +append done_string ".* DNS domain name: genodians.org.*\n" append done_string ".*DHCP request completed:.*\n" append done_string ".* IP lease time: 3600 seconds.*\n" append done_string ".* Interface: 10.0.3.2/24.*\n" append done_string ".* Router: 10.0.3.1.*\n" +append done_string ".* DNS domain name: genodians.org.*\n" append done_string ".*DHCP request completed:.*\n" append done_string ".* IP lease time: 3600 seconds.*\n" append done_string ".* Interface: 10.0.3.2/24.*\n" @@ -307,5 +316,6 @@ append done_string ".* Router: 10.0.3.1.*\n" append done_string ".* DNS server #1: 1.2.3.4.*\n" append done_string ".* DNS server #2: 2.3.4.5.*\n" append done_string ".* DNS server #3: 3.4.5.6.*\n" +append done_string ".* DNS domain name: genode.org.*\n" run_genode_until $done_string 30 diff --git a/repos/os/src/server/nic_router/README b/repos/os/src/server/nic_router/README index 1b92e493d0..c76baa0394 100644 --- a/repos/os/src/server/nic_router/README +++ b/repos/os/src/server/nic_router/README @@ -441,6 +441,7 @@ this: ! ip_last="10.0.1.100" ! ip_lease_time_sec="3600"> ! +! ! ! ! ... @@ -468,6 +469,10 @@ lifetime of an IPv4 address assignment in seconds. The IPv4 address range must be in the subnet defined by the 'interface' attribute of the tag and must not cover the IPv4 address given by this attribute. +The sub-tag from the first example statically provides a DNS +domain name that shall be propagated by the DHCP server through a DHCP option +15 entry to its clients. + The sub-tags from the first example statically provide a list of DNS server addresses that shall be propagated by the DHCP server through a DHCP option 6 entry to its clients. These addresses might be of any IP subnet. The @@ -475,14 +480,15 @@ addresses in the DHCP option 6 entry in the DHCP replies will have the same order as the tags in the configuration. The 'dns_config_from' attribute from the second example takes effect only when -the tag does not contain any sub-tags. The attribute -states the domain from whose IP config to take the list of propagated DNS -server addresses. Note that the order of DNS server adresses is not altered -thereby. This is useful in scenarios where these addresses must be obtained -dynamically through the DHCP client of another domain. An implication of the -'dns_config_from' attribute is that the link state of all interfaces at the -domain with the DHCP server becomes bound to the validity of the IP config of -the domain that is stated in the attribute. +the tag does not contain any or +sub-tags. The attribute states the domain from whose IP config to take the DNS +domain name and the list of DNS server addresses that shall be propagated. Note +that the order of DNS server adresses is not altered thereby. This is useful in +scenarios where these addresses must be obtained dynamically through the DHCP +client of another domain. An implication of the 'dns_config_from' attribute is +that the link state of all interfaces at the domain with the DHCP server +becomes bound to the validity of the IP config of the domain that is stated in +the attribute. The lifetime of an IP address assignment that was yet only offered to the client can be configured for all domains in the tag of the router: @@ -548,6 +554,7 @@ A complete state report of the NIC router is structured the following way ! ! +! ! ! ! @@ -687,14 +694,15 @@ simply the 'limit' value minus the 'used' value. 'config' A boolean value that controls whether the attributes 'ipv4' and 'gw' of the - tag and the subtag in the tag are generated. The -attribute 'ipv4' contains the current IPv4 address of the router in this domain -suffixed by the length of the subnet prefix in bits. The 'gw' attribute -contains the IPv4 address of the gateway in this domain. Each subtag of a - tag shows the IPv4 address of a DNS server known to this domain. The - subtags have the same order that the addresses had in the DHCP option 6 -entry of the DHCP reply that the router received and that led to the current -IPv4 configuration of the domain. + tag and the subtags and in the tag are +generated. The attribute 'ipv4' contains the current IPv4 address of the router +in this domain suffixed by the length of the subnet prefix in bits. The 'gw' +attribute contains the IPv4 address of the gateway in this domain. Each +subtag of a tag shows the IPv4 address of a DNS server known to this +domain. The subtags have the same order that the addresses had in the +DHCP option 6 entry of the DHCP reply that the router received and that led to +the current IPv4 configuration of the domain. The subtag of the + tag states the DNS domain name of this domain if any. 'config_triggers' diff --git a/repos/os/src/server/nic_router/config.xsd b/repos/os/src/server/nic_router/config.xsd index 05a037460f..35fc2975bb 100644 --- a/repos/os/src/server/nic_router/config.xsd +++ b/repos/os/src/server/nic_router/config.xsd @@ -12,6 +12,12 @@ + + + + + + @@ -140,6 +146,12 @@ + + + + + + diff --git a/repos/os/src/server/nic_router/dhcp_server.cc b/repos/os/src/server/nic_router/dhcp_server.cc index 0207e8b870..1637a7655f 100644 --- a/repos/os/src/server/nic_router/dhcp_server.cc +++ b/repos/os/src/server/nic_router/dhcp_server.cc @@ -16,6 +16,7 @@ #include #include #include +#include using namespace Net; using namespace Genode; @@ -42,6 +43,18 @@ Dhcp_server_base::Dhcp_server_base(Xml_node const &node, _invalid(domain, "invalid DNS server entry"); } }); + node.with_sub_node("dns-domain", [&] (Xml_node const &sub_node) { + xml_node_with_attribute(sub_node, "name", [&] (Xml_attribute const &attr) { + _dns_domain_name.set_to(attr); + + if (domain.config().verbose() && + !_dns_domain_name.valid()) { + + log("[", domain, "] rejecting oversized DNS " + "domain name from DHCP server configuration"); + } + }); + }); } @@ -108,6 +121,9 @@ void Dhcp_server::print(Output &output) const _dns_servers.for_each([&] (Dns_server const &dns_server) { Genode::print(output, "DNS server ", dns_server.ip(), ", "); }); + _dns_domain_name.with_string([&] (Dns_domain_name::String const &str) { + Genode::print(output, "DNS domain name ", str, ", "); + }); try { Genode::print(output, "DNS config from ", _dns_config_from(), ", "); } catch (Pointer::Invalid) { } @@ -118,9 +134,11 @@ void Dhcp_server::print(Output &output) const } -bool Dhcp_server::dns_servers_equal_to_those_of(Dhcp_server const &dhcp_server) const +bool Dhcp_server::config_equal_to_that_of(Dhcp_server const &other) const { - return _dns_servers.equal_to(dhcp_server._dns_servers); + return _ip_lease_time.value == other._ip_lease_time.value && + _dns_servers.equal_to(other._dns_servers) && + _dns_domain_name.equal_to(other._dns_domain_name); } @@ -177,7 +195,9 @@ void Dhcp_server::free_ip(Domain const &domain, Pointer Dhcp_server::_init_dns_config_from(Genode::Xml_node const node, Domain_tree &domains) { - if (!_dns_servers.empty()) { + if (!_dns_servers.empty() || + _dns_domain_name.valid()) { + return Pointer(); } Domain_name dns_config_from = diff --git a/repos/os/src/server/nic_router/dhcp_server.h b/repos/os/src/server/nic_router/dhcp_server.h index dd0ad55484..e903e8f02e 100644 --- a/repos/os/src/server/nic_router/dhcp_server.h +++ b/repos/os/src/server/nic_router/dhcp_server.h @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include /* Genode includes */ @@ -47,8 +47,9 @@ class Net::Dhcp_server_base { protected: - Genode::Allocator &_alloc; - Net::List _dns_servers { }; + Genode::Allocator &_alloc; + Dns_server_list _dns_servers { }; + Dns_domain_name _dns_domain_name { _alloc }; void _invalid(Domain const &domain, char const *reason); @@ -123,8 +124,15 @@ class Net::Dhcp_server : private Genode::Noncopyable, } } - bool - dns_servers_equal_to_those_of(Dhcp_server const &dhcp_server) const; + Dns_domain_name const &dns_domain_name() const + { + if (_dns_config_from.valid()) { + return _resolve_dns_config_from().dns_domain_name(); + } + return _dns_domain_name; + } + + bool config_equal_to_that_of(Dhcp_server const &dhcp_server) const; /********* diff --git a/repos/os/src/server/nic_router/dns.cc b/repos/os/src/server/nic_router/dns.cc new file mode 100644 index 0000000000..fae3892868 --- /dev/null +++ b/repos/os/src/server/nic_router/dns.cc @@ -0,0 +1,128 @@ +/* + * \brief Utilities for handling DNS configurations + * \author Martin Stein + * \date 2020-11-17 + */ + +/* + * Copyright (C) 2020 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +/* local includes */ +#include +#include +#include + +/* Genode includes */ +#include + +using namespace Net; +using namespace Genode; + + +/**************** + ** Dns_server ** + ****************/ + +Dns_server::Dns_server(Ipv4_address const &ip) +: + _ip { ip } +{ + if (!_ip.valid()) { + throw Invalid { }; + } +} + + +bool Dns_server::equal_to(Dns_server const &server) const +{ + return _ip == server._ip; +} + + +/********************* + ** Dns_domain_name ** + *********************/ + +void Dns_domain_name::set_to(Dns_domain_name const &name) +{ + if (name.valid()) { + name.with_string([&] (String const &string) { + if (_string.valid()) { + _string() = string; + } else { + _string = *new (_alloc) String { string }; + } + }); + } else { + set_invalid(); + } +} + + +void Dns_domain_name::set_to(Xml_attribute const &name_attr) +{ + name_attr.with_raw_value([&] (char const *base, size_t size) { + if (size < STRING_CAPACITY) { + if (_string.valid()) { + _string() = Cstring { base, size }; + } else { + _string = *new (_alloc) String { Cstring { base, size } }; + } + } else { + set_invalid(); + } + }); +} + + +void Dns_domain_name::set_to(Dhcp_packet::Domain_name const &name_option) +{ + name_option.with_string([&] (char const *base, size_t size) { + if (size < STRING_CAPACITY) { + if (_string.valid()) { + _string() = Cstring { base, size }; + } else { + _string = *new (_alloc) String { Cstring { base, size } }; + } + } else { + set_invalid(); + } + }); +} + + +void Dns_domain_name::set_invalid() +{ + if (_string.valid()) { + _alloc.free(&_string(), sizeof(String)); + _string = { }; + } +} + + +bool Dns_domain_name::equal_to(Dns_domain_name const &other) const +{ + if (_string.valid()) { + if (other._string.valid()) { + return _string() == other._string(); + } + return false; + } + return !other._string.valid(); +} + + +Dns_domain_name::Dns_domain_name(Genode::Allocator &alloc) +: + _alloc { alloc } +{ } + + +Dns_domain_name::~Dns_domain_name() +{ + set_invalid(); +} diff --git a/repos/os/src/server/nic_router/dns.h b/repos/os/src/server/nic_router/dns.h new file mode 100644 index 0000000000..6d747e56a9 --- /dev/null +++ b/repos/os/src/server/nic_router/dns.h @@ -0,0 +1,104 @@ +/* + * \brief Utilities for handling DNS configurations + * \author Martin Stein + * \date 2020-11-17 + */ + +/* + * Copyright (C) 2020 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +#ifndef _DNS_H_ +#define _DNS_H_ + +/* local includes */ +#include +#include + +/* Genode includes */ +#include +#include +#include + +namespace Genode { + + class Xml_attribute; +} + +namespace Net { + + class Dns_server; + class Dns_domain_name; + + using Dns_server_list = Net::List; +} + +class Net::Dns_server : private Genode::Noncopyable, + public Net::List::Element +{ + private: + + Net::Ipv4_address const _ip; + + public: + + struct Invalid : Genode::Exception { }; + + Dns_server(Net::Ipv4_address const &ip); + + bool equal_to(Dns_server const &server) const; + + + /*************** + ** Accessors ** + ***************/ + + Net::Ipv4_address const &ip() const { return _ip; } +}; + +class Net::Dns_domain_name : private Genode::Noncopyable +{ + private: + + enum { STRING_CAPACITY = 160 }; + + public: + + using String = Genode::String; + + private: + + Genode::Allocator &_alloc; + Pointer _string { }; + + public: + + Dns_domain_name(Genode::Allocator &alloc); + + ~Dns_domain_name(); + + void set_to(Dns_domain_name const &name); + + void set_to(Genode::Xml_attribute const &name_attr); + + void set_to(Dhcp_packet::Domain_name const &name_option); + + void set_invalid(); + + bool valid() const { return _string.valid(); } + + template + void with_string(FUNC && func) const + { + if (_string.valid()) { + func(_string()); + } + } + + bool equal_to(Dns_domain_name const &other) const; +}; + +#endif /* _DNS_H_ */ diff --git a/repos/os/src/server/nic_router/dns_server.cc b/repos/os/src/server/nic_router/dns_server.cc deleted file mode 100644 index 0876c1b82b..0000000000 --- a/repos/os/src/server/nic_router/dns_server.cc +++ /dev/null @@ -1,34 +0,0 @@ -/* - * \brief DNS server entry of a DHCP server or IPv4 config - * \author Martin Stein - * \date 2020-11-17 - */ - -/* - * Copyright (C) 2020 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU Affero General Public License version 3. - */ - -/* local includes */ -#include - -using namespace Net; -using namespace Genode; - - -Net::Dns_server::Dns_server(Ipv4_address const &ip) -: - _ip { ip } -{ - if (!_ip.valid()) { - throw Invalid { }; - } -} - - -bool Net::Dns_server::equal_to(Dns_server const &server) const -{ - return _ip == server._ip; -} diff --git a/repos/os/src/server/nic_router/dns_server.h b/repos/os/src/server/nic_router/dns_server.h deleted file mode 100644 index ed7984cbd9..0000000000 --- a/repos/os/src/server/nic_router/dns_server.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * \brief DNS server entry of a DHCP server or IPv4 config - * \author Martin Stein - * \date 2020-11-17 - */ - -/* - * Copyright (C) 2020 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU Affero General Public License version 3. - */ - -#ifndef _DNS_SERVER_H_ -#define _DNS_SERVER_H_ - -/* local includes */ -#include - -/* Genode includes */ -#include - -namespace Net { class Dns_server; } - -class Net::Dns_server : private Genode::Noncopyable, - public Net::List::Element -{ - private: - - Net::Ipv4_address const _ip; - - public: - - struct Invalid : Genode::Exception { }; - - Dns_server(Net::Ipv4_address const &ip); - - bool equal_to(Dns_server const &server) const; - - - /*************** - ** Accessors ** - ***************/ - - Net::Ipv4_address const &ip() const { return _ip; } -}; - - - -#endif /* _DHCP_SERVER_H_ */ diff --git a/repos/os/src/server/nic_router/domain.cc b/repos/os/src/server/nic_router/domain.cc index c037993b7d..11af946ab7 100644 --- a/repos/os/src/server/nic_router/domain.cc +++ b/repos/os/src/server/nic_router/domain.cc @@ -113,7 +113,7 @@ void Domain::discard_ip_config() void Domain::ip_config_from_dhcp_ack(Dhcp_packet &dhcp_ack) { _reconstruct_ip_config([&] (Reconstructible &ip_config) { - ip_config.construct(dhcp_ack, _alloc); }); + ip_config.construct(dhcp_ack, _alloc, *this); }); } @@ -397,6 +397,13 @@ void Domain::report(Xml_generator &xml) xml.attribute("ip", String<16>(dns_server.ip())); }); }); + ip_config().dns_domain_name().with_string( + [&] (Dns_domain_name::String const &str) + { + xml.node("dns-domain", [&] () { + xml.attribute("name", str); + }); + }); empty = false; } if (_config.report().stats()) { diff --git a/repos/os/src/server/nic_router/interface.cc b/repos/os/src/server/nic_router/interface.cc index 501dcba0a9..8bd01f3fd7 100644 --- a/repos/os/src/server/nic_router/interface.cc +++ b/repos/os/src/server/nic_router/interface.cc @@ -678,6 +678,11 @@ void Interface::_send_dhcp_reply(Dhcp_server const &dhcp_srv, data.append_address(addr); }); }); + dhcp_srv.dns_domain_name().with_string( + [&] (Dns_domain_name::String const &str) + { + dhcp_opts.append_domain_name(str.string(), str.length()); + }); dhcp_opts.append_option(local_intf.broadcast_address()); dhcp_opts.append_option(); @@ -1908,12 +1913,7 @@ void Interface::_update_dhcp_allocations(Domain &old_domain, try { Dhcp_server &old_dhcp_srv = old_domain.dhcp_server(); Dhcp_server &new_dhcp_srv = new_domain.dhcp_server(); - if (!old_dhcp_srv.dns_servers_equal_to_those_of(new_dhcp_srv)) { - throw Pointer::Invalid(); - } - if (old_dhcp_srv.ip_lease_time().value != - new_dhcp_srv.ip_lease_time().value) - { + if (!old_dhcp_srv.config_equal_to_that_of(new_dhcp_srv)) { throw Pointer::Invalid(); } _dhcp_allocations.for_each([&] (Dhcp_allocation &allocation) { diff --git a/repos/os/src/server/nic_router/ipv4_config.cc b/repos/os/src/server/nic_router/ipv4_config.cc index 89794bf831..22ef3ebf8e 100644 --- a/repos/os/src/server/nic_router/ipv4_config.cc +++ b/repos/os/src/server/nic_router/ipv4_config.cc @@ -16,6 +16,8 @@ /* local includes */ #include +#include +#include using namespace Genode; using namespace Net; @@ -45,22 +47,23 @@ Ipv4_config::Ipv4_config(Ipv4_config const &ip_config, _interface { ip_config._interface }, _gateway { ip_config._gateway } { - ip_config._dns_servers.for_each([&] (Dns_server const &dns_server) { + ip_config.for_each_dns_server([&] (Dns_server const &dns_server) { _dns_servers.insert_as_tail( *new (alloc) Dns_server(dns_server.ip())); }); + _dns_domain_name.set_to(ip_config.dns_domain_name()); } -Ipv4_config::Ipv4_config(Dhcp_packet &dhcp_ack, - Allocator &alloc) +Ipv4_config::Ipv4_config(Dhcp_packet &dhcp_ack, + Allocator &alloc, + Domain const &domain) : _alloc { alloc }, _interface { dhcp_ack.yiaddr(), dhcp_ipv4_option(dhcp_ack) }, _gateway { dhcp_ipv4_option(dhcp_ack) } { - try { Dhcp_packet::Dns_server const &dns_server { dhcp_ack.option() }; @@ -70,6 +73,17 @@ Ipv4_config::Ipv4_config(Dhcp_packet &dhcp_ack, }); } catch (Dhcp_packet::Option_not_found) { } + try { + _dns_domain_name.set_to(dhcp_ack.option()); + + if (domain.config().verbose() && + !_dns_domain_name.valid()) { + + log("[", domain, "] rejecting oversized DNS " + "domain name from DHCP reply"); + } + } + catch (Dhcp_packet::Option_not_found) { } } diff --git a/repos/os/src/server/nic_router/ipv4_config.h b/repos/os/src/server/nic_router/ipv4_config.h index 4b5725bf9b..af9602a744 100644 --- a/repos/os/src/server/nic_router/ipv4_config.h +++ b/repos/os/src/server/nic_router/ipv4_config.h @@ -17,12 +17,16 @@ /* local includes */ #include #include -#include +#include /* Genode includes */ #include -namespace Net { class Ipv4_config; } +namespace Net { + + class Domain; + class Ipv4_config; +} class Net::Ipv4_config { @@ -36,7 +40,8 @@ class Net::Ipv4_config bool const _point_to_point { _gateway_valid && _interface_valid && _interface.prefix == 32 }; - Net::List _dns_servers { }; + Dns_server_list _dns_servers { }; + Dns_domain_name _dns_domain_name { _alloc }; bool const _valid { _point_to_point || (_interface_valid && (!_gateway_valid || @@ -45,7 +50,8 @@ class Net::Ipv4_config public: Ipv4_config(Net::Dhcp_packet &dhcp_ack, - Genode::Allocator &alloc); + Genode::Allocator &alloc, + Domain const &domain); Ipv4_config(Genode::Xml_node const &domain_node, Genode::Allocator &alloc); @@ -59,16 +65,17 @@ class Net::Ipv4_config bool operator != (Ipv4_config const &other) const { - return _interface != other._interface || - _gateway != other._gateway || - !_dns_servers.equal_to(other._dns_servers); + return _interface != other._interface || + _gateway != other._gateway || + !_dns_servers.equal_to(other._dns_servers) || + !_dns_domain_name.equal_to(other._dns_domain_name); } template - void for_each_dns_server(FUNC && functor) const + void for_each_dns_server(FUNC && func) const { _dns_servers.for_each([&] (Dns_server const &dns_server) { - functor(dns_server); + func(dns_server); }); } @@ -84,10 +91,11 @@ class Net::Ipv4_config ** Accessors ** ***************/ - bool valid() const { return _valid; } - Ipv4_address_prefix const &interface() const { return _interface; } - Ipv4_address const &gateway() const { return _gateway; } - bool gateway_valid() const { return _gateway_valid; } + bool valid() const { return _valid; } + Ipv4_address_prefix const &interface() const { return _interface; } + Ipv4_address const &gateway() const { return _gateway; } + bool gateway_valid() const { return _gateway_valid; } + Dns_domain_name const &dns_domain_name() const { return _dns_domain_name; } }; #endif /* _IPV4_CONFIG_H_ */ diff --git a/repos/os/src/server/nic_router/pointer.h b/repos/os/src/server/nic_router/pointer.h index 400db572ec..abfd744760 100644 --- a/repos/os/src/server/nic_router/pointer.h +++ b/repos/os/src/server/nic_router/pointer.h @@ -73,6 +73,8 @@ class Net::Const_pointer return *_obj; } + + bool valid() const { return _obj != nullptr; } }; #endif /* _POINTER_H_ */ diff --git a/repos/os/src/server/nic_router/target.mk b/repos/os/src/server/nic_router/target.mk index 063db306fe..df293c3800 100644 --- a/repos/os/src/server/nic_router/target.mk +++ b/repos/os/src/server/nic_router/target.mk @@ -22,7 +22,7 @@ SRC_CC += \ link.cc \ transport_rule.cc \ permit_rule.cc \ - dns_server.cc \ + dns.cc \ dhcp_client.cc \ dhcp_server.cc \ report.cc \ @@ -30,7 +30,6 @@ SRC_CC += \ uplink_session_root.cc \ communication_buffer.cc \ - INC_DIR += $(PRG_DIR) CONFIG_XSD = config.xsd diff --git a/repos/os/src/server/nic_router/xml_node.h b/repos/os/src/server/nic_router/xml_node.h index 33cf34647c..63fea7e3b1 100644 --- a/repos/os/src/server/nic_router/xml_node.h +++ b/repos/os/src/server/nic_router/xml_node.h @@ -24,6 +24,16 @@ namespace Genode { Microseconds read_sec_attr(Xml_node const node, char const *name, uint64_t const default_sec); + + template + void xml_node_with_attribute(Xml_node const node, + char const *name, + FUNC && func) + { + if (node.has_attribute(name)) { + func(node.attribute(name)); + } + } } #endif /* _XML_NODE_H_ */ diff --git a/repos/os/src/test/nic_router_dhcp/client/dhcp_client.cc b/repos/os/src/test/nic_router_dhcp/client/dhcp_client.cc index 629a210af4..53dfe84b99 100644 --- a/repos/os/src/test/nic_router_dhcp/client/dhcp_client.cc +++ b/repos/os/src/test/nic_router_dhcp/client/dhcp_client.cc @@ -185,6 +185,15 @@ void Dhcp_client::_handle_dhcp_reply(Dhcp_packet &dhcp) }); } catch (Dhcp_packet::Option_not_found) { } + try { + Dhcp_packet::Domain_name const &domain_name { + dhcp.option() }; + + domain_name.with_string([&] (char const *base, size_t size) { + log(" DNS domain name: ", Cstring { base, size }); + }); + } + catch (Dhcp_packet::Option_not_found) { } Ipv4_config ip_config( Ipv4_address_prefix( diff --git a/repos/os/src/test/nic_router_dhcp/manager/dns_server.cc b/repos/os/src/test/nic_router_dhcp/manager/dns_server.cc deleted file mode 100644 index 17337ead6f..0000000000 --- a/repos/os/src/test/nic_router_dhcp/manager/dns_server.cc +++ /dev/null @@ -1,34 +0,0 @@ -/* - * \brief DNS server entry of a DHCP server or IPv4 config - * \author Martin Stein - * \date 2020-11-17 - */ - -/* - * Copyright (C) 2020 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU Affero General Public License version 3. - */ - -/* local includes */ -#include - -using namespace Net; -using namespace Genode; - - -Local::Dns_server::Dns_server(Ipv4_address const &ip) -: - _ip { ip } -{ - if (!_ip.valid()) { - throw Invalid { }; - } -} - - -bool Local::Dns_server::equal_to(Dns_server const &server) const -{ - return _ip == server._ip; -} diff --git a/repos/os/src/test/nic_router_dhcp/manager/dns_server.h b/repos/os/src/test/nic_router_dhcp/manager/dns_server.h deleted file mode 100644 index 56d5b80fd4..0000000000 --- a/repos/os/src/test/nic_router_dhcp/manager/dns_server.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * \brief DNS server entry of a DHCP server or IPv4 config - * \author Martin Stein - * \date 2020-11-17 - */ - -/* - * Copyright (C) 2020 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU Affero General Public License version 3. - */ - -#ifndef _DNS_SERVER_H_ -#define _DNS_SERVER_H_ - -/* local includes */ -#include - -/* Genode includes */ -#include - -namespace Local { class Dns_server; } - -class Local::Dns_server : private Genode::Noncopyable, - public Local::List::Element -{ - private: - - Net::Ipv4_address const _ip; - - public: - - struct Invalid : Genode::Exception { }; - - Dns_server(Net::Ipv4_address const &ip); - - bool equal_to(Dns_server const &server) const; - - - /*************** - ** Accessors ** - ***************/ - - Net::Ipv4_address const &ip() const { return _ip; } -}; - - - -#endif /* _DHCP_SERVER_H_ */ diff --git a/repos/os/src/test/nic_router_dhcp/manager/list.h b/repos/os/src/test/nic_router_dhcp/manager/list.h deleted file mode 100644 index e8d935b056..0000000000 --- a/repos/os/src/test/nic_router_dhcp/manager/list.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * \brief Genode list with additional functions needed by NIC router - * \author Martin Stein - * \date 2016-08-19 - */ - -/* - * Copyright (C) 2016-2017 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU Affero General Public License version 3. - */ - -#ifndef _LIST_H_ -#define _LIST_H_ - -/* Genode includes */ -#include -#include - -namespace Local { template class List; } - - -template -struct Local::List : Genode::List -{ - using Base = Genode::List; - - template - void for_each(FUNC && functor) - { - for (LT *elem = Base::first(); elem; ) - { - LT *const next = elem->Base::Element::next(); - functor(*elem); - elem = next; - } - } - - template - void for_each(FUNC && functor) const - { - for (LT const *elem = Base::first(); elem; ) - { - LT const *const next = elem->Base::Element::next(); - functor(*elem); - elem = next; - } - } - - void destroy_each(Genode::Deallocator &dealloc) - { - while (LT *elem = Base::first()) { - Base::remove(elem); - destroy(dealloc, elem); - } - } - - bool empty() const - { - return Base::first() == nullptr; - } - - void insert_as_tail(LT const &le) - { - LT *elem { Base::first() }; - if (elem) { - while (elem->Base::Element::next()) { - elem = elem->Base::Element::next(); - } - } - Base::insert(&le, elem); - } - - bool equal_to(List const &list) const - { - LT const *curr_elem_1 { Base::first() }; - LT const *curr_elem_2 { list.Base::first() }; - while (true) { - - if (curr_elem_1 == nullptr) { - return curr_elem_2 == nullptr; - } - if (curr_elem_2 == nullptr) { - return false; - } - LT const *const next_elem_1 { - curr_elem_1->List::Element::next() }; - - LT const *const next_elem_2 { - curr_elem_2->List::Element::next() }; - - if (!curr_elem_1->equal_to(*curr_elem_2)) { - return false; - } - curr_elem_1 = next_elem_1; - curr_elem_2 = next_elem_2; - } - } -}; - -#endif /* _LIST_H_ */ diff --git a/repos/os/src/test/nic_router_dhcp/manager/main.cc b/repos/os/src/test/nic_router_dhcp/manager/main.cc index 113122d696..5ddbb3434f 100644 --- a/repos/os/src/test/nic_router_dhcp/manager/main.cc +++ b/repos/os/src/test/nic_router_dhcp/manager/main.cc @@ -20,7 +20,10 @@ /* local includes */ #include -#include + +/* NIC router includes */ +#include +#include using namespace Net; using namespace Genode; @@ -39,7 +42,8 @@ class Local::Main Signal_handler
_router_state_handler { _env.ep(), *this, &Main::_handle_router_state }; Expanding_reporter _router_config_reporter { _env, "config", "router_config" }; bool _router_config_outdated { true }; - Local::List _dns_servers { }; + Dns_server_list _dns_servers { }; + Dns_domain_name _dns_domain_name { _heap }; void _handle_router_state(); @@ -99,7 +103,7 @@ void Local::Main::_handle_router_state() * Read out all DNS servers from the new uplink state * and memorize them in a function-local list. */ - Local::List dns_servers { }; + Dns_server_list dns_servers { }; domain_node.for_each_sub_node( "dns", [&] (Xml_node const &dns_node) @@ -110,8 +114,8 @@ void Local::Main::_handle_router_state() }); /* - * If the new list of DNS servers differs our member list, - * update the member list, and remember to write out a new router + * If the new list of DNS servers differs from the stored list, + * update the stored list, and remember to write out a new router * configuration. */ if (!_dns_servers.equal_to(dns_servers)) { @@ -124,6 +128,19 @@ void Local::Main::_handle_router_state() _router_config_outdated = true; } dns_servers.destroy_each(_heap); + + /* read out new DNS domain name */ + Dns_domain_name dns_domain_name { _heap }; + domain_node.with_sub_node("dns-domain", [&] (Xml_node const &sub_node) { + xml_node_with_attribute(sub_node, "name", [&] (Xml_attribute const &attr) { + dns_domain_name.set_to(attr); + }); + }); + /* update stored DNS domain name if necessary */ + if (!_dns_domain_name.equal_to(dns_domain_name)) { + _dns_domain_name.set_to(dns_domain_name); + _router_config_outdated = true; + } } }); @@ -164,6 +181,13 @@ void Local::Main::_handle_router_state() xml.attribute("ip", String<16>(dns_server.ip())); }); }); + _dns_domain_name.with_string( + [&] (Dns_domain_name::String const &str) + { + xml.node("dns-domain", [&] () { + xml.attribute("name", str); + }); + }); }); }); }); diff --git a/repos/os/src/test/nic_router_dhcp/manager/target.mk b/repos/os/src/test/nic_router_dhcp/manager/target.mk index 76fd289216..095352407f 100644 --- a/repos/os/src/test/nic_router_dhcp/manager/target.mk +++ b/repos/os/src/test/nic_router_dhcp/manager/target.mk @@ -2,6 +2,9 @@ TARGET = test-nic_router_dhcp-manager LIBS += base -SRC_CC += main.cc ipv4_address_prefix.cc dns_server.cc +SRC_CC += main.cc ipv4_address_prefix.cc dns.cc xml_node.cc -INC_DIR += $(PRG_DIR) +INC_DIR += $(PRG_DIR) $(REP_DIR)/src/server/nic_router + +vpath dns.cc $(REP_DIR)/src/server/nic_router +vpath xml_node.cc $(REP_DIR)/src/server/nic_router