mirror of
https://github.com/genodelabs/genode.git
synced 2025-06-03 08:00:58 +00:00
nic_router: propagate dns domain name via dhcp
With this commit, the NIC router DHCP client reads out the first DNS domain name (DHCP option 15) if any from a DHCP reply that generates an IPv4 config for a domain and stores the name together with the IPv4 config for that domain. DNS domain names are reported via the new report tag '<dns-domain>' if the 'config' attribute in the config tag '<report>' is set. Furthermore, the NIC router DHCP server becomes able to obtain a DNS domain name from another domain that has a DHCP client dynamically (given the config attribute 'dns_config_from' is set and no static DNS config is given) or statically from its configuration (new config tag '<dns-domain>') and propagate this name with DHCP replies (DHCP option 15). The 'nic_router_dhcp_*' tests are adapted to test the new feautures. The commit also gets rid of some mirrored files in 'test/nic_router_dhcp/manager'. Fixes #4246
This commit is contained in:
parent
fa64aae7f8
commit
812fdec27c
@ -127,6 +127,7 @@ class Net::Dhcp_packet
|
|||||||
SUBNET_MASK = 1,
|
SUBNET_MASK = 1,
|
||||||
ROUTER = 3,
|
ROUTER = 3,
|
||||||
DNS_SERVER = 6,
|
DNS_SERVER = 6,
|
||||||
|
DOMAIN_NAME = 15,
|
||||||
BROADCAST_ADDR = 28,
|
BROADCAST_ADDR = 28,
|
||||||
REQ_IP_ADDR = 50,
|
REQ_IP_ADDR = 50,
|
||||||
IP_LEASE_TIME = 51,
|
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 <typename FUNC>
|
||||||
|
void with_string(FUNC && func) const
|
||||||
|
{
|
||||||
|
func(_name, Option::len());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
enum class Message_type : Genode::uint8_t {
|
enum class Message_type : Genode::uint8_t {
|
||||||
DISCOVER = 1,
|
DISCOVER = 1,
|
||||||
OFFER = 2,
|
OFFER = 2,
|
||||||
@ -442,6 +465,16 @@ class Net::Dhcp_packet
|
|||||||
|
|
||||||
_base += header_size + data.size();
|
_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<Domain_name>((void *)_base, data_size);
|
||||||
|
_base += header_size + data_size;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -63,6 +63,7 @@ append config {
|
|||||||
<dns-server ip="1.2.3.4"/>
|
<dns-server ip="1.2.3.4"/>
|
||||||
<dns-server ip="2.3.4.5"/>
|
<dns-server ip="2.3.4.5"/>
|
||||||
<dns-server ip="3.4.5.6"/>
|
<dns-server ip="3.4.5.6"/>
|
||||||
|
<dns-domain name="genode.org"/>
|
||||||
|
|
||||||
</dhcp-server>
|
</dhcp-server>
|
||||||
|
|
||||||
@ -96,7 +97,7 @@ append config {
|
|||||||
<sleep milliseconds="2000"/>
|
<sleep milliseconds="2000"/>
|
||||||
<inline>
|
<inline>
|
||||||
|
|
||||||
<config>
|
<config verbose="yes">
|
||||||
|
|
||||||
<policy label="nic_router_2 -> " domain="downlink"/>
|
<policy label="nic_router_2 -> " domain="downlink"/>
|
||||||
|
|
||||||
@ -106,6 +107,7 @@ append config {
|
|||||||
ip_last="10.2.4.2">
|
ip_last="10.2.4.2">
|
||||||
|
|
||||||
<dns-server ip="6.7.8.9"/>
|
<dns-server ip="6.7.8.9"/>
|
||||||
|
<dns-domain name="this_is_a_way_to_long_dns_domain_name_that_should_be_rejected_by_the_router_and_cause_the_corresponding_dhcp_option_to_disappear_but_you_never_know_and_so_we_better_test_it"/>
|
||||||
|
|
||||||
</dhcp-server>
|
</dhcp-server>
|
||||||
|
|
||||||
@ -126,6 +128,8 @@ append config {
|
|||||||
<dhcp-server ip_first="10.2.4.200"
|
<dhcp-server ip_first="10.2.4.200"
|
||||||
ip_last="10.2.4.200">
|
ip_last="10.2.4.200">
|
||||||
|
|
||||||
|
<dns-domain name="genodians.org"/>
|
||||||
|
|
||||||
</dhcp-server>
|
</dhcp-server>
|
||||||
|
|
||||||
</domain>
|
</domain>
|
||||||
@ -145,6 +149,8 @@ append config {
|
|||||||
<dhcp-server ip_first="10.2.3.2"
|
<dhcp-server ip_first="10.2.3.2"
|
||||||
ip_last="10.2.3.2">
|
ip_last="10.2.3.2">
|
||||||
|
|
||||||
|
<dns-domain name="genodians.org"/>
|
||||||
|
|
||||||
</dhcp-server>
|
</dhcp-server>
|
||||||
|
|
||||||
</domain>
|
</domain>
|
||||||
@ -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 #1: 1.2.3.4.*\n"
|
||||||
append done_string ".* DNS server #2: 2.3.4.5.*\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 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 ".*DHCP request completed:.*\n"
|
||||||
append done_string ".* IP lease time: 3600 seconds.*\n"
|
append done_string ".* IP lease time: 3600 seconds.*\n"
|
||||||
append done_string ".* Interface: 10.0.3.2/24.*\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 ".* IP lease time: 3600 seconds.*\n"
|
||||||
append done_string ".* Interface: 10.0.3.2/24.*\n"
|
append done_string ".* Interface: 10.0.3.2/24.*\n"
|
||||||
append done_string ".* Router: 10.0.3.1.*\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 ".*DHCP request completed:.*\n"
|
||||||
append done_string ".* IP lease time: 3600 seconds.*\n"
|
append done_string ".* IP lease time: 3600 seconds.*\n"
|
||||||
append done_string ".* Interface: 10.0.3.2/24.*\n"
|
append done_string ".* Interface: 10.0.3.2/24.*\n"
|
||||||
append done_string ".* Router: 10.0.3.1.*\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 ".*DHCP request completed:.*\n"
|
||||||
append done_string ".* IP lease time: 3600 seconds.*\n"
|
append done_string ".* IP lease time: 3600 seconds.*\n"
|
||||||
append done_string ".* Interface: 10.0.3.2/24.*\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 #1: 1.2.3.4.*\n"
|
||||||
append done_string ".* DNS server #2: 2.3.4.5.*\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 server #3: 3.4.5.6.*\n"
|
||||||
|
append done_string ".* DNS domain name: genode.org.*\n"
|
||||||
|
|
||||||
run_genode_until $done_string 30
|
run_genode_until $done_string 30
|
||||||
|
@ -441,6 +441,7 @@ this:
|
|||||||
! ip_last="10.0.1.100"
|
! ip_last="10.0.1.100"
|
||||||
! ip_lease_time_sec="3600">
|
! ip_lease_time_sec="3600">
|
||||||
!
|
!
|
||||||
|
! <dns-domain name="genodians.org" />
|
||||||
! <dns-server ip="8.8.8.8" />
|
! <dns-server ip="8.8.8.8" />
|
||||||
! <dns-server ip="1.1.1.1" />
|
! <dns-server ip="1.1.1.1" />
|
||||||
! ...
|
! ...
|
||||||
@ -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 <domain> tag and
|
be in the subnet defined by the 'interface' attribute of the <domain> tag and
|
||||||
must not cover the IPv4 address given by this attribute.
|
must not cover the IPv4 address given by this attribute.
|
||||||
|
|
||||||
|
The <dns-domain> 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 <dns-server> sub-tags from the first example statically provide a list of
|
The <dns-server> 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
|
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
|
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 <dns-server> tags in the configuration.
|
order as the <dns-server> tags in the configuration.
|
||||||
|
|
||||||
The 'dns_config_from' attribute from the second example takes effect only when
|
The 'dns_config_from' attribute from the second example takes effect only when
|
||||||
the <dhcp-server> tag does not contain any <dns-server> sub-tags. The attribute
|
the <dhcp-server> tag does not contain any <dns-domain> or <dns-server>
|
||||||
states the domain from whose IP config to take the list of propagated DNS
|
sub-tags. The attribute states the domain from whose IP config to take the DNS
|
||||||
server addresses. Note that the order of DNS server adresses is not altered
|
domain name and the list of DNS server addresses that shall be propagated. Note
|
||||||
thereby. This is useful in scenarios where these addresses must be obtained
|
that the order of DNS server adresses is not altered thereby. This is useful in
|
||||||
dynamically through the DHCP client of another domain. An implication of the
|
scenarios where these addresses must be obtained dynamically through the DHCP
|
||||||
'dns_config_from' attribute is that the link state of all interfaces at the
|
client of another domain. An implication of the 'dns_config_from' attribute is
|
||||||
domain with the DHCP server becomes bound to the validity of the IP config of
|
that the link state of all interfaces at the domain with the DHCP server
|
||||||
the domain that is stated in the attribute.
|
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
|
The lifetime of an IP address assignment that was yet only offered to the
|
||||||
client can be configured for all domains in the <config> tag of the router:
|
client can be configured for all domains in the <config> tag of the router:
|
||||||
@ -548,6 +554,7 @@ A complete state report of the NIC router is structured the following way
|
|||||||
! <domain name="domain_1" rx_bytes="17597" tx_bytes="7788"
|
! <domain name="domain_1" rx_bytes="17597" tx_bytes="7788"
|
||||||
! ipv4="100.200.0.10/24" gw="100.200.0.1">
|
! ipv4="100.200.0.10/24" gw="100.200.0.1">
|
||||||
!
|
!
|
||||||
|
! <dns-domain name="genodians.org"/>
|
||||||
! <dns ip="100.200.0.8"/>
|
! <dns ip="100.200.0.8"/>
|
||||||
! <dns ip="1.1.1.1"/>
|
! <dns ip="1.1.1.1"/>
|
||||||
! <dns ip="8.8.8.8"/>
|
! <dns ip="8.8.8.8"/>
|
||||||
@ -687,14 +694,15 @@ simply the 'limit' value minus the 'used' value.
|
|||||||
'config'
|
'config'
|
||||||
|
|
||||||
A boolean value that controls whether the attributes 'ipv4' and 'gw' of the
|
A boolean value that controls whether the attributes 'ipv4' and 'gw' of the
|
||||||
<domain> tag and the subtag <dns> in the <domain> tag are generated. The
|
<domain> tag and the subtags <dns> and <dns-domain> in the <domain> tag are
|
||||||
attribute 'ipv4' contains the current IPv4 address of the router in this domain
|
generated. The attribute 'ipv4' contains the current IPv4 address of the router
|
||||||
suffixed by the length of the subnet prefix in bits. The 'gw' attribute
|
in this domain suffixed by the length of the subnet prefix in bits. The 'gw'
|
||||||
contains the IPv4 address of the gateway in this domain. Each <dns> subtag of a
|
attribute contains the IPv4 address of the gateway in this domain. Each <dns>
|
||||||
<domain> tag shows the IPv4 address of a DNS server known to this domain. The
|
subtag of a <domain> tag shows the IPv4 address of a DNS server known to this
|
||||||
<dns> subtags have the same order that the addresses had in the DHCP option 6
|
domain. The <dns> subtags have the same order that the addresses had in the
|
||||||
entry of the DHCP reply that the router received and that led to the current
|
DHCP option 6 entry of the DHCP reply that the router received and that led to
|
||||||
IPv4 configuration of the domain.
|
the current IPv4 configuration of the domain. The <dns-domain> subtag of the
|
||||||
|
<domain> tag states the DNS domain name of this domain if any.
|
||||||
|
|
||||||
'config_triggers'
|
'config_triggers'
|
||||||
|
|
||||||
|
@ -12,6 +12,12 @@
|
|||||||
</xs:restriction>
|
</xs:restriction>
|
||||||
</xs:simpleType><!-- Domain_name -->
|
</xs:simpleType><!-- Domain_name -->
|
||||||
|
|
||||||
|
<xs:simpleType name="Dns_domain_name">
|
||||||
|
<xs:restriction base="xs:string">
|
||||||
|
<xs:minLength value="1"/>
|
||||||
|
</xs:restriction>
|
||||||
|
</xs:simpleType><!-- Dns_domain_name -->
|
||||||
|
|
||||||
<xs:simpleType name="Icmp_type_3_code_attribute">
|
<xs:simpleType name="Icmp_type_3_code_attribute">
|
||||||
<xs:restriction base="xs:string">
|
<xs:restriction base="xs:string">
|
||||||
<xs:enumeration value="no" />
|
<xs:enumeration value="no" />
|
||||||
@ -140,6 +146,12 @@
|
|||||||
</xs:complexType>
|
</xs:complexType>
|
||||||
</xs:element><!-- dns-server -->
|
</xs:element><!-- dns-server -->
|
||||||
|
|
||||||
|
<xs:element name="dns-domain">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:attribute name="name" type="Dns_domain_name" />
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element><!-- dns-domain -->
|
||||||
|
|
||||||
</xs:choice>
|
</xs:choice>
|
||||||
<xs:attribute name="ip_first" type="Ipv4_address" />
|
<xs:attribute name="ip_first" type="Ipv4_address" />
|
||||||
<xs:attribute name="ip_last" type="Ipv4_address" />
|
<xs:attribute name="ip_last" type="Ipv4_address" />
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include <interface.h>
|
#include <interface.h>
|
||||||
#include <domain.h>
|
#include <domain.h>
|
||||||
#include <configuration.h>
|
#include <configuration.h>
|
||||||
|
#include <xml_node.h>
|
||||||
|
|
||||||
using namespace Net;
|
using namespace Net;
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
@ -42,6 +43,18 @@ Dhcp_server_base::Dhcp_server_base(Xml_node const &node,
|
|||||||
_invalid(domain, "invalid DNS server entry");
|
_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) {
|
_dns_servers.for_each([&] (Dns_server const &dns_server) {
|
||||||
Genode::print(output, "DNS server ", dns_server.ip(), ", ");
|
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(), ", "); }
|
try { Genode::print(output, "DNS config from ", _dns_config_from(), ", "); }
|
||||||
catch (Pointer<Domain>::Invalid) { }
|
catch (Pointer<Domain>::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<Domain> Dhcp_server::_init_dns_config_from(Genode::Xml_node const node,
|
Pointer<Domain> Dhcp_server::_init_dns_config_from(Genode::Xml_node const node,
|
||||||
Domain_tree &domains)
|
Domain_tree &domains)
|
||||||
{
|
{
|
||||||
if (!_dns_servers.empty()) {
|
if (!_dns_servers.empty() ||
|
||||||
|
_dns_domain_name.valid()) {
|
||||||
|
|
||||||
return Pointer<Domain>();
|
return Pointer<Domain>();
|
||||||
}
|
}
|
||||||
Domain_name dns_config_from =
|
Domain_name dns_config_from =
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
#include <bit_allocator_dynamic.h>
|
#include <bit_allocator_dynamic.h>
|
||||||
#include <list.h>
|
#include <list.h>
|
||||||
#include <pointer.h>
|
#include <pointer.h>
|
||||||
#include <dns_server.h>
|
#include <dns.h>
|
||||||
#include <ipv4_config.h>
|
#include <ipv4_config.h>
|
||||||
|
|
||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
@ -47,8 +47,9 @@ class Net::Dhcp_server_base
|
|||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
Genode::Allocator &_alloc;
|
Genode::Allocator &_alloc;
|
||||||
Net::List<Dns_server> _dns_servers { };
|
Dns_server_list _dns_servers { };
|
||||||
|
Dns_domain_name _dns_domain_name { _alloc };
|
||||||
|
|
||||||
void _invalid(Domain const &domain,
|
void _invalid(Domain const &domain,
|
||||||
char const *reason);
|
char const *reason);
|
||||||
@ -123,8 +124,15 @@ class Net::Dhcp_server : private Genode::Noncopyable,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
Dns_domain_name const &dns_domain_name() const
|
||||||
dns_servers_equal_to_those_of(Dhcp_server const &dhcp_server) 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;
|
||||||
|
|
||||||
|
|
||||||
/*********
|
/*********
|
||||||
|
128
repos/os/src/server/nic_router/dns.cc
Normal file
128
repos/os/src/server/nic_router/dns.cc
Normal file
@ -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 <dns.h>
|
||||||
|
#include <domain.h>
|
||||||
|
#include <configuration.h>
|
||||||
|
|
||||||
|
/* Genode includes */
|
||||||
|
#include <util/xml_node.h>
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
104
repos/os/src/server/nic_router/dns.h
Normal file
104
repos/os/src/server/nic_router/dns.h
Normal file
@ -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 <list.h>
|
||||||
|
#include <pointer.h>
|
||||||
|
|
||||||
|
/* Genode includes */
|
||||||
|
#include <util/reconstructible.h>
|
||||||
|
#include <net/ipv4.h>
|
||||||
|
#include <net/dhcp.h>
|
||||||
|
|
||||||
|
namespace Genode {
|
||||||
|
|
||||||
|
class Xml_attribute;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Net {
|
||||||
|
|
||||||
|
class Dns_server;
|
||||||
|
class Dns_domain_name;
|
||||||
|
|
||||||
|
using Dns_server_list = Net::List<Dns_server>;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Net::Dns_server : private Genode::Noncopyable,
|
||||||
|
public Net::List<Dns_server>::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<STRING_CAPACITY>;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Genode::Allocator &_alloc;
|
||||||
|
Pointer<String> _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 <typename FUNC>
|
||||||
|
void with_string(FUNC && func) const
|
||||||
|
{
|
||||||
|
if (_string.valid()) {
|
||||||
|
func(_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool equal_to(Dns_domain_name const &other) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _DNS_H_ */
|
@ -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 <dns_server.h>
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
@ -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 <list.h>
|
|
||||||
|
|
||||||
/* Genode includes */
|
|
||||||
#include <net/ipv4.h>
|
|
||||||
|
|
||||||
namespace Net { class Dns_server; }
|
|
||||||
|
|
||||||
class Net::Dns_server : private Genode::Noncopyable,
|
|
||||||
public Net::List<Dns_server>::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_ */
|
|
@ -113,7 +113,7 @@ void Domain::discard_ip_config()
|
|||||||
void Domain::ip_config_from_dhcp_ack(Dhcp_packet &dhcp_ack)
|
void Domain::ip_config_from_dhcp_ack(Dhcp_packet &dhcp_ack)
|
||||||
{
|
{
|
||||||
_reconstruct_ip_config([&] (Reconstructible<Ipv4_config> &ip_config) {
|
_reconstruct_ip_config([&] (Reconstructible<Ipv4_config> &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()));
|
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;
|
empty = false;
|
||||||
}
|
}
|
||||||
if (_config.report().stats()) {
|
if (_config.report().stats()) {
|
||||||
|
@ -678,6 +678,11 @@ void Interface::_send_dhcp_reply(Dhcp_server const &dhcp_srv,
|
|||||||
data.append_address(addr);
|
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<Dhcp_packet::Broadcast_addr>(local_intf.broadcast_address());
|
dhcp_opts.append_option<Dhcp_packet::Broadcast_addr>(local_intf.broadcast_address());
|
||||||
dhcp_opts.append_option<Dhcp_packet::Options_end>();
|
dhcp_opts.append_option<Dhcp_packet::Options_end>();
|
||||||
|
|
||||||
@ -1908,12 +1913,7 @@ void Interface::_update_dhcp_allocations(Domain &old_domain,
|
|||||||
try {
|
try {
|
||||||
Dhcp_server &old_dhcp_srv = old_domain.dhcp_server();
|
Dhcp_server &old_dhcp_srv = old_domain.dhcp_server();
|
||||||
Dhcp_server &new_dhcp_srv = new_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)) {
|
if (!old_dhcp_srv.config_equal_to_that_of(new_dhcp_srv)) {
|
||||||
throw Pointer<Dhcp_server>::Invalid();
|
|
||||||
}
|
|
||||||
if (old_dhcp_srv.ip_lease_time().value !=
|
|
||||||
new_dhcp_srv.ip_lease_time().value)
|
|
||||||
{
|
|
||||||
throw Pointer<Dhcp_server>::Invalid();
|
throw Pointer<Dhcp_server>::Invalid();
|
||||||
}
|
}
|
||||||
_dhcp_allocations.for_each([&] (Dhcp_allocation &allocation) {
|
_dhcp_allocations.for_each([&] (Dhcp_allocation &allocation) {
|
||||||
|
@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
/* local includes */
|
/* local includes */
|
||||||
#include <ipv4_config.h>
|
#include <ipv4_config.h>
|
||||||
|
#include <domain.h>
|
||||||
|
#include <configuration.h>
|
||||||
|
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
using namespace Net;
|
using namespace Net;
|
||||||
@ -45,22 +47,23 @@ Ipv4_config::Ipv4_config(Ipv4_config const &ip_config,
|
|||||||
_interface { ip_config._interface },
|
_interface { ip_config._interface },
|
||||||
_gateway { ip_config._gateway }
|
_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(
|
_dns_servers.insert_as_tail(
|
||||||
*new (alloc) Dns_server(dns_server.ip()));
|
*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,
|
Ipv4_config::Ipv4_config(Dhcp_packet &dhcp_ack,
|
||||||
Allocator &alloc)
|
Allocator &alloc,
|
||||||
|
Domain const &domain)
|
||||||
:
|
:
|
||||||
_alloc { alloc },
|
_alloc { alloc },
|
||||||
_interface { dhcp_ack.yiaddr(),
|
_interface { dhcp_ack.yiaddr(),
|
||||||
dhcp_ipv4_option<Dhcp_packet::Subnet_mask>(dhcp_ack) },
|
dhcp_ipv4_option<Dhcp_packet::Subnet_mask>(dhcp_ack) },
|
||||||
_gateway { dhcp_ipv4_option<Dhcp_packet::Router_ipv4>(dhcp_ack) }
|
_gateway { dhcp_ipv4_option<Dhcp_packet::Router_ipv4>(dhcp_ack) }
|
||||||
{
|
{
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Dhcp_packet::Dns_server const &dns_server {
|
Dhcp_packet::Dns_server const &dns_server {
|
||||||
dhcp_ack.option<Dhcp_packet::Dns_server>() };
|
dhcp_ack.option<Dhcp_packet::Dns_server>() };
|
||||||
@ -70,6 +73,17 @@ Ipv4_config::Ipv4_config(Dhcp_packet &dhcp_ack,
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
catch (Dhcp_packet::Option_not_found) { }
|
catch (Dhcp_packet::Option_not_found) { }
|
||||||
|
try {
|
||||||
|
_dns_domain_name.set_to(dhcp_ack.option<Dhcp_packet::Domain_name>());
|
||||||
|
|
||||||
|
if (domain.config().verbose() &&
|
||||||
|
!_dns_domain_name.valid()) {
|
||||||
|
|
||||||
|
log("[", domain, "] rejecting oversized DNS "
|
||||||
|
"domain name from DHCP reply");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Dhcp_packet::Option_not_found) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -17,12 +17,16 @@
|
|||||||
/* local includes */
|
/* local includes */
|
||||||
#include <ipv4_address_prefix.h>
|
#include <ipv4_address_prefix.h>
|
||||||
#include <dhcp.h>
|
#include <dhcp.h>
|
||||||
#include <dns_server.h>
|
#include <dns.h>
|
||||||
|
|
||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
#include <util/xml_node.h>
|
#include <util/xml_node.h>
|
||||||
|
|
||||||
namespace Net { class Ipv4_config; }
|
namespace Net {
|
||||||
|
|
||||||
|
class Domain;
|
||||||
|
class Ipv4_config;
|
||||||
|
}
|
||||||
|
|
||||||
class Net::Ipv4_config
|
class Net::Ipv4_config
|
||||||
{
|
{
|
||||||
@ -36,7 +40,8 @@ class Net::Ipv4_config
|
|||||||
bool const _point_to_point { _gateway_valid &&
|
bool const _point_to_point { _gateway_valid &&
|
||||||
_interface_valid &&
|
_interface_valid &&
|
||||||
_interface.prefix == 32 };
|
_interface.prefix == 32 };
|
||||||
Net::List<Dns_server> _dns_servers { };
|
Dns_server_list _dns_servers { };
|
||||||
|
Dns_domain_name _dns_domain_name { _alloc };
|
||||||
bool const _valid { _point_to_point ||
|
bool const _valid { _point_to_point ||
|
||||||
(_interface_valid &&
|
(_interface_valid &&
|
||||||
(!_gateway_valid ||
|
(!_gateway_valid ||
|
||||||
@ -45,7 +50,8 @@ class Net::Ipv4_config
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
Ipv4_config(Net::Dhcp_packet &dhcp_ack,
|
Ipv4_config(Net::Dhcp_packet &dhcp_ack,
|
||||||
Genode::Allocator &alloc);
|
Genode::Allocator &alloc,
|
||||||
|
Domain const &domain);
|
||||||
|
|
||||||
Ipv4_config(Genode::Xml_node const &domain_node,
|
Ipv4_config(Genode::Xml_node const &domain_node,
|
||||||
Genode::Allocator &alloc);
|
Genode::Allocator &alloc);
|
||||||
@ -59,16 +65,17 @@ class Net::Ipv4_config
|
|||||||
|
|
||||||
bool operator != (Ipv4_config const &other) const
|
bool operator != (Ipv4_config const &other) const
|
||||||
{
|
{
|
||||||
return _interface != other._interface ||
|
return _interface != other._interface ||
|
||||||
_gateway != other._gateway ||
|
_gateway != other._gateway ||
|
||||||
!_dns_servers.equal_to(other._dns_servers);
|
!_dns_servers.equal_to(other._dns_servers) ||
|
||||||
|
!_dns_domain_name.equal_to(other._dns_domain_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename FUNC>
|
template <typename FUNC>
|
||||||
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) {
|
_dns_servers.for_each([&] (Dns_server const &dns_server) {
|
||||||
functor(dns_server);
|
func(dns_server);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,10 +91,11 @@ class Net::Ipv4_config
|
|||||||
** Accessors **
|
** Accessors **
|
||||||
***************/
|
***************/
|
||||||
|
|
||||||
bool valid() const { return _valid; }
|
bool valid() const { return _valid; }
|
||||||
Ipv4_address_prefix const &interface() const { return _interface; }
|
Ipv4_address_prefix const &interface() const { return _interface; }
|
||||||
Ipv4_address const &gateway() const { return _gateway; }
|
Ipv4_address const &gateway() const { return _gateway; }
|
||||||
bool gateway_valid() const { return _gateway_valid; }
|
bool gateway_valid() const { return _gateway_valid; }
|
||||||
|
Dns_domain_name const &dns_domain_name() const { return _dns_domain_name; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _IPV4_CONFIG_H_ */
|
#endif /* _IPV4_CONFIG_H_ */
|
||||||
|
@ -73,6 +73,8 @@ class Net::Const_pointer
|
|||||||
|
|
||||||
return *_obj;
|
return *_obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool valid() const { return _obj != nullptr; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _POINTER_H_ */
|
#endif /* _POINTER_H_ */
|
||||||
|
@ -22,7 +22,7 @@ SRC_CC += \
|
|||||||
link.cc \
|
link.cc \
|
||||||
transport_rule.cc \
|
transport_rule.cc \
|
||||||
permit_rule.cc \
|
permit_rule.cc \
|
||||||
dns_server.cc \
|
dns.cc \
|
||||||
dhcp_client.cc \
|
dhcp_client.cc \
|
||||||
dhcp_server.cc \
|
dhcp_server.cc \
|
||||||
report.cc \
|
report.cc \
|
||||||
@ -30,7 +30,6 @@ SRC_CC += \
|
|||||||
uplink_session_root.cc \
|
uplink_session_root.cc \
|
||||||
communication_buffer.cc \
|
communication_buffer.cc \
|
||||||
|
|
||||||
|
|
||||||
INC_DIR += $(PRG_DIR)
|
INC_DIR += $(PRG_DIR)
|
||||||
|
|
||||||
CONFIG_XSD = config.xsd
|
CONFIG_XSD = config.xsd
|
||||||
|
@ -24,6 +24,16 @@ namespace Genode {
|
|||||||
Microseconds read_sec_attr(Xml_node const node,
|
Microseconds read_sec_attr(Xml_node const node,
|
||||||
char const *name,
|
char const *name,
|
||||||
uint64_t const default_sec);
|
uint64_t const default_sec);
|
||||||
|
|
||||||
|
template <typename FUNC>
|
||||||
|
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_ */
|
#endif /* _XML_NODE_H_ */
|
||||||
|
@ -185,6 +185,15 @@ void Dhcp_client::_handle_dhcp_reply(Dhcp_packet &dhcp)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
catch (Dhcp_packet::Option_not_found) { }
|
catch (Dhcp_packet::Option_not_found) { }
|
||||||
|
try {
|
||||||
|
Dhcp_packet::Domain_name const &domain_name {
|
||||||
|
dhcp.option<Dhcp_packet::Domain_name>() };
|
||||||
|
|
||||||
|
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_config ip_config(
|
||||||
Ipv4_address_prefix(
|
Ipv4_address_prefix(
|
||||||
|
@ -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 <dns_server.h>
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
@ -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 <list.h>
|
|
||||||
|
|
||||||
/* Genode includes */
|
|
||||||
#include <net/ipv4.h>
|
|
||||||
|
|
||||||
namespace Local { class Dns_server; }
|
|
||||||
|
|
||||||
class Local::Dns_server : private Genode::Noncopyable,
|
|
||||||
public Local::List<Dns_server>::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_ */
|
|
@ -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 <util/list.h>
|
|
||||||
#include <base/allocator.h>
|
|
||||||
|
|
||||||
namespace Local { template <typename> class List; }
|
|
||||||
|
|
||||||
|
|
||||||
template <typename LT>
|
|
||||||
struct Local::List : Genode::List<LT>
|
|
||||||
{
|
|
||||||
using Base = Genode::List<LT>;
|
|
||||||
|
|
||||||
template <typename FUNC>
|
|
||||||
void for_each(FUNC && functor)
|
|
||||||
{
|
|
||||||
for (LT *elem = Base::first(); elem; )
|
|
||||||
{
|
|
||||||
LT *const next = elem->Base::Element::next();
|
|
||||||
functor(*elem);
|
|
||||||
elem = next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename FUNC>
|
|
||||||
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<LT> 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<LT>::Element::next() };
|
|
||||||
|
|
||||||
LT const *const next_elem_2 {
|
|
||||||
curr_elem_2->List<LT>::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_ */
|
|
@ -20,7 +20,10 @@
|
|||||||
|
|
||||||
/* local includes */
|
/* local includes */
|
||||||
#include <ipv4_address_prefix.h>
|
#include <ipv4_address_prefix.h>
|
||||||
#include <dns_server.h>
|
|
||||||
|
/* NIC router includes */
|
||||||
|
#include <dns.h>
|
||||||
|
#include <xml_node.h>
|
||||||
|
|
||||||
using namespace Net;
|
using namespace Net;
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
@ -39,7 +42,8 @@ class Local::Main
|
|||||||
Signal_handler<Main> _router_state_handler { _env.ep(), *this, &Main::_handle_router_state };
|
Signal_handler<Main> _router_state_handler { _env.ep(), *this, &Main::_handle_router_state };
|
||||||
Expanding_reporter _router_config_reporter { _env, "config", "router_config" };
|
Expanding_reporter _router_config_reporter { _env, "config", "router_config" };
|
||||||
bool _router_config_outdated { true };
|
bool _router_config_outdated { true };
|
||||||
Local::List<Dns_server> _dns_servers { };
|
Dns_server_list _dns_servers { };
|
||||||
|
Dns_domain_name _dns_domain_name { _heap };
|
||||||
|
|
||||||
void _handle_router_state();
|
void _handle_router_state();
|
||||||
|
|
||||||
@ -99,7 +103,7 @@ void Local::Main::_handle_router_state()
|
|||||||
* Read out all DNS servers from the new uplink state
|
* Read out all DNS servers from the new uplink state
|
||||||
* and memorize them in a function-local list.
|
* and memorize them in a function-local list.
|
||||||
*/
|
*/
|
||||||
Local::List<Dns_server> dns_servers { };
|
Dns_server_list dns_servers { };
|
||||||
domain_node.for_each_sub_node(
|
domain_node.for_each_sub_node(
|
||||||
"dns",
|
"dns",
|
||||||
[&] (Xml_node const &dns_node)
|
[&] (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,
|
* If the new list of DNS servers differs from the stored list,
|
||||||
* update the member list, and remember to write out a new router
|
* update the stored list, and remember to write out a new router
|
||||||
* configuration.
|
* configuration.
|
||||||
*/
|
*/
|
||||||
if (!_dns_servers.equal_to(dns_servers)) {
|
if (!_dns_servers.equal_to(dns_servers)) {
|
||||||
@ -124,6 +128,19 @@ void Local::Main::_handle_router_state()
|
|||||||
_router_config_outdated = true;
|
_router_config_outdated = true;
|
||||||
}
|
}
|
||||||
dns_servers.destroy_each(_heap);
|
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()));
|
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);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -2,6 +2,9 @@ TARGET = test-nic_router_dhcp-manager
|
|||||||
|
|
||||||
LIBS += base
|
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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user