libc: use socket fs for DNS information

The libc will now use the file given by the 'nameserver_file' attribute
to get the DNS nameserver address instead of reading '/etc/resolv.conf'.
It defaults to '/socket/nameserver' which is the common location when
using the lxip VFS plugin. As a constraint the libc will read the first
line and expects the nameserver address without any keywords in front of
it.

Fixes #2861.
This commit is contained in:
Josef Söntgen 2018-05-25 22:22:12 +02:00 committed by Norman Feske
parent a7a160eebc
commit 74dcc7a3d5
13 changed files with 96 additions and 40 deletions

View File

@ -43,10 +43,6 @@
<provides> <service name="File_system"/> </provides>
<config>
<vfs>
<dir name="etc">
<inline name="resolv.conf">nameserver 1.1.1.1</inline>
<inline name="hosts"/>
</dir>
<dir name="socket">
<lxip dhcp="yes"/>
</dir>

View File

@ -1 +1 @@
c9c17345f57cb2f827c271806df456d829e32ce3
5a5de5baab6e3ce23f24012a7604abf070fa990c

View File

@ -85,9 +85,6 @@ append config {
<config>
<report progress="yes"/>
<vfs>
<dir name="etc">
<inline name="resolv.conf">nameserver 1.1.1.1</inline>
</dir>
<dir name="dev">
<log/> <null/> <inline name="rtc">2000-01-01 00:00</inline>
<inline name="random">01234567890123456789</inline>

View File

@ -52,9 +52,6 @@ append config {
<resource name="RAM" quantum="32M"/>
<config>
<vfs>
<dir name="etc">
<inline name="resolv.conf">nameserver 10.0.2.3</inline>
</dir>
<dir name="dev"> <log/> </dir>
<dir name="socket"> <lxip dhcp="yes"/> </dir>
</vfs>

View File

@ -0,0 +1,69 @@
+++ src/lib/libc/lib/libc/resolv/res_init.c
@@ -152,6 +152,10 @@
return (__res_vinit(statp, 0));
}
+
+extern char const *libc_resolv_path;
+
+
/*% This function has to be reachable by res_data.c but not publically. */
int
__res_vinit(res_state statp, int preinit) {
@@ -304,8 +308,47 @@
line[sizeof(name) - 1] == '\t'))
nserv = 0;
- if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) {
+ if ((fp = fopen(libc_resolv_path, "r")) != NULL) {
/* read the config file */
+#if 1
+ if (fgets(buf, sizeof(buf), fp) != NULL) {
+ /* read nameservers to query */
+ struct addrinfo hints, *ai;
+ char sbuf[NI_MAXSERV];
+ const size_t minsiz = sizeof(statp->_u._ext.ext->nsaddrs[0]);
+
+ cp = buf;
+ cp[strcspn(cp, "\n")] = '\0';
+
+ if ((*cp != '\0') && (*cp != '\n')) {
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = PF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM; /*dummy*/
+ hints.ai_flags = AI_NUMERICHOST;
+ sprintf(sbuf, "%u", NAMESERVER_PORT);
+
+ if (getaddrinfo(cp, sbuf, &hints, &ai) == 0 &&
+ ai->ai_addrlen <= minsiz) {
+ if (statp->_u._ext.ext != NULL) {
+ memcpy(&statp->_u._ext.ext->nsaddrs[nserv],
+ ai->ai_addr, ai->ai_addrlen);
+ }
+
+ if (ai->ai_addrlen <=
+ sizeof(statp->nsaddr_list[nserv])) {
+ memcpy(&statp->nsaddr_list[nserv],
+ ai->ai_addr, ai->ai_addrlen);
+ } else {
+ statp->nsaddr_list[nserv].sin_family = 0;
+ }
+
+ freeaddrinfo(ai);
+ nserv++;
+ }
+ }
+ }
+#else
while (fgets(buf, sizeof(buf), fp) != NULL) {
/* skip comments */
if (*buf == ';' || *buf == '#')
@@ -502,6 +545,7 @@
continue;
}
}
+#endif /* 1 */
if (nserv > 0)
statp->nscount = nserv;
#ifdef RESOLVSORT

View File

@ -91,15 +91,11 @@ static void vfs_stat_to_libc_stat_struct(Vfs::Directory_service::Stat const &src
static Genode::Xml_node *_config_node;
char const *libc_resolv_path;
namespace Libc {
void libc_config_init(Genode::Xml_node node)
{
static Genode::Xml_node config = node;
_config_node = &config;
}
Genode::Xml_node config() __attribute__((weak));
Genode::Xml_node config()
{
@ -143,6 +139,22 @@ namespace Libc {
return socket.string();
}
char const *config_nameserver_file() __attribute__((weak));
char const *config_nameserver_file()
{
static Config_attr ns_file("nameserver_file",
"/socket/nameserver");
return ns_file.string();
}
void libc_config_init(Genode::Xml_node node)
{
static Genode::Xml_node config = node;
_config_node = &config;
libc_resolv_path = config_nameserver_file();
}
void notify_read_ready(Vfs::Vfs_handle *handle)
{
struct Check : Libc::Suspend_functor

View File

@ -1,6 +1,6 @@
/*
* \brief Libc plugin providing lwIP's DNS server address in the
* '/etc/resolv.conf' file
* '/socket/nameserver' file
* \author Christian Prochaska
* \date 2013-05-02
*/
@ -122,13 +122,13 @@ namespace {
/**
* File name this plugin feels responsible for
*/
static char const *_file_name() { return "/etc/resolv.conf"; }
static char const *_file_name() { return "/socket/nameserver"; }
const char *_file_content()
{
static char result[32];
ip_addr_t nameserver_ip = dns_getserver(0);
snprintf(result, sizeof(result), "nameserver %s\n",
snprintf(result, sizeof(result), "%s\n",
ipaddr_ntoa(&nameserver_ip));
return result;
}
@ -150,7 +150,7 @@ namespace {
bool supports_stat(const char *path)
{
return (Genode::strcmp(path, "/etc") == 0) ||
return (Genode::strcmp(path, "/socket") == 0) ||
(Genode::strcmp(path, _file_name()) == 0);
}
@ -177,7 +177,7 @@ namespace {
{
if (buf) {
Genode::memset(buf, 0, sizeof(struct stat));
if (Genode::strcmp(path, "/etc") == 0)
if (Genode::strcmp(path, "/socket") == 0)
buf->st_mode = S_IFDIR;
else if (Genode::strcmp(path, _file_name()) == 0) {
buf->st_mode = S_IFREG;

View File

@ -45,14 +45,12 @@
<config>
<vfs>
<ram/>
<dir name="etc">
<inline name="resolv.conf">nameserver 9.9.9.9</inline> </dir>
<dir name="dev">
<log/> <null/> <rtc/>
<jitterentropy name="random"/>
</dir>
<dir name="socket">
<lxip ip_addr="10.0.1.2" netmask="255.255.255.0" gateway="10.0.1.1"/>
<lxip ip_addr="10.0.1.2" netmask="255.255.255.0" gateway="10.0.1.1" nameserver="9.9.9.9"/>
</dir>
<inline name="stubby.yaml">
listen_addresses:

View File

@ -106,9 +106,6 @@ append config {
<jitterentropy name="random"/>
<inline name="rtc">2018-01-01 00:01</inline>
</dir>
<dir name="etc">
<inline name="resolv.conf">nameserver 10.0.2.3</inline>
</dir>
<tar name="qt5_dejavusans.tar"/>
</vfs>
<libc stdout="/dev/log" stderr="/dev/log" rtc="/dev/rtc" socket="/dev/socket"/>

View File

@ -40,7 +40,7 @@ build $build_components
#
# The '<build-dir>/bin/etc/' directory is expected to contain the
# files 'services', 'protocols', 'hosts', and 'resolv.conf'.
# files 'services', 'protocols', and 'hosts'.
# Download these files from the FreeBSD source tree is possible.
#
exec mkdir -p bin/etc
@ -48,7 +48,6 @@ set freebsd_url "http://svn.freebsd.org/base/release/8.2.0/etc"
foreach etc_file { services protocols hosts } {
if {![file exists bin/etc/$etc_file]} {
catch { exec wget -c -P bin/etc $freebsd_url/$etc_file } } }
exec touch bin/etc/resolv.conf
exec tar rfv bin/netcat.tar -h -C bin/ etc

View File

@ -99,14 +99,12 @@ append config {
<config>
<vfs>
<ram/>
<dir name="etc">
<inline name="resolv.conf">nameserver 10.0.2.3</inline> </dir>
<dir name="dev">
<log/> <null/> <rtc/>
<jitterentropy name="random"/>
</dir>
<dir name="socket">
<lxip ip_addr="10.0.53.2" netmask="255.255.255.0" gateway="10.0.53.1"/>
<lxip ip_addr="10.0.53.2" netmask="255.255.255.0" gateway="10.0.53.1" nameserver="10.0.2.3"/>
</dir>
<inline name="stubby.yaml">
listen_addresses:
@ -125,9 +123,6 @@ listen_addresses:
<provides> <service name="File_system"/> </provides>
<config>
<vfs>
<dir name="etc">
<inline name="resolv.conf">nameserver 10.0.53.2</inline>
</dir>
<dir name="socket"> <lxip dhcp="yes"/> </dir>
</vfs>
<default-policy writeable="yes" root="/"/>

View File

@ -176,9 +176,6 @@ append config {
<resource name="RAM" quantum="32M"/>
<config>
<vfs>
<dir name="etc">
<inline name="resolv.conf">nameserver 10.0.1.2</inline>
</dir>
<dir name="dev"> <log/> </dir>
<dir name="socket"> <lxip dhcp="yes"/> </dir>
</vfs>

View File

@ -22,7 +22,6 @@ copy-contrib-files:
done
generate-files: copy-contrib-files
$(VERBOSE)echo 'nameserver 8.8.8.8' > $(TARGET_DIR)/resolv.conf
$(BUILD_BIN_DIR)/$(TARGET): generate-files