resolved: fix comments in resolve.conf for search domain overflows (#3422)
Write comments about "too many search domains" and "Total length of all search domains is too long" just once. Also put it on a separate line, as resolv.conf(5) only specifies comments in a line by themselves. This is ugly to do if write_resolv_conf_search() gets called once for every search domain. So change it to receive the complete OrderedSet instead and do the iteration by itself. Add test cases to networkd-test.py. https://launchpad.net/bugs/1588229
This commit is contained in:
parent
21fce63ecf
commit
d2bc125132
|
@ -164,30 +164,32 @@ static void write_resolv_conf_server(DnsServer *s, FILE *f, unsigned *count) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void write_resolv_conf_search(
|
static void write_resolv_conf_search(
|
||||||
const char *domain,
|
OrderedSet *domains,
|
||||||
FILE *f,
|
FILE *f) {
|
||||||
unsigned *count,
|
unsigned length = 0, count = 0;
|
||||||
unsigned *length) {
|
Iterator i;
|
||||||
|
char *domain;
|
||||||
|
|
||||||
assert(domain);
|
assert(domains);
|
||||||
assert(f);
|
assert(f);
|
||||||
assert(length);
|
|
||||||
|
|
||||||
if (*count >= MAXDNSRCH ||
|
fputs("search", f);
|
||||||
*length + strlen(domain) > 256) {
|
|
||||||
if (*count == MAXDNSRCH)
|
|
||||||
fputs(" # Too many search domains configured, remaining ones ignored.", f);
|
|
||||||
if (*length <= 256)
|
|
||||||
fputs(" # Total length of all search domains is too long, remaining ones ignored.", f);
|
|
||||||
|
|
||||||
return;
|
ORDERED_SET_FOREACH(domain, domains, i) {
|
||||||
|
if (++count > MAXDNSRCH) {
|
||||||
|
fputs("\n# Too many search domains configured, remaining ones ignored.", f);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
length += strlen(domain) + 1;
|
||||||
|
if (length > 256) {
|
||||||
|
fputs("\n# Total length of all search domains is too long, remaining ones ignored.", f);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fputc(' ', f);
|
||||||
|
fputs(domain, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
(*length) += strlen(domain);
|
fputs("\n", f);
|
||||||
(*count)++;
|
|
||||||
|
|
||||||
fputc(' ', f);
|
|
||||||
fputs(domain, f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int write_resolv_conf_contents(FILE *f, OrderedSet *dns, OrderedSet *domains) {
|
static int write_resolv_conf_contents(FILE *f, OrderedSet *dns, OrderedSet *domains) {
|
||||||
|
@ -209,15 +211,8 @@ static int write_resolv_conf_contents(FILE *f, OrderedSet *dns, OrderedSet *doma
|
||||||
write_resolv_conf_server(s, f, &count);
|
write_resolv_conf_server(s, f, &count);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ordered_set_isempty(domains)) {
|
if (!ordered_set_isempty(domains))
|
||||||
unsigned length = 0, count = 0;
|
write_resolv_conf_search(domains, f);
|
||||||
char *domain;
|
|
||||||
|
|
||||||
fputs("search", f);
|
|
||||||
ORDERED_SET_FOREACH(domain, domains, i)
|
|
||||||
write_resolv_conf_search(domain, f, &count, &length);
|
|
||||||
fputs("\n", f);
|
|
||||||
}
|
|
||||||
|
|
||||||
return fflush_and_check(f);
|
return fflush_and_check(f);
|
||||||
}
|
}
|
||||||
|
|
|
@ -370,6 +370,77 @@ exec $(systemctl cat systemd-networkd.service | sed -n '/^ExecStart=/ { s/^.*=//
|
||||||
def test_coldplug_dhcp_ip6(self):
|
def test_coldplug_dhcp_ip6(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def test_search_domains(self):
|
||||||
|
|
||||||
|
# we don't use this interface for this test
|
||||||
|
self.if_router = None
|
||||||
|
|
||||||
|
with open('/run/systemd/network/test.netdev', 'w') as f:
|
||||||
|
f.write('''[NetDev]
|
||||||
|
Name=dummy0
|
||||||
|
Kind=dummy
|
||||||
|
MACAddress=12:34:56:78:9a:bc''')
|
||||||
|
with open('/run/systemd/network/test.network', 'w') as f:
|
||||||
|
f.write('''[Match]
|
||||||
|
Name=dummy0
|
||||||
|
[Network]
|
||||||
|
Address=192.168.42.100
|
||||||
|
DNS=192.168.42.1
|
||||||
|
Domains= one two three four five six seven eight nine ten''')
|
||||||
|
self.addCleanup(os.remove, '/run/systemd/network/test.netdev')
|
||||||
|
self.addCleanup(os.remove, '/run/systemd/network/test.network')
|
||||||
|
|
||||||
|
subprocess.check_call(['systemctl', 'start', 'systemd-networkd'])
|
||||||
|
|
||||||
|
if os.path.islink('/etc/resolv.conf'):
|
||||||
|
for timeout in range(50):
|
||||||
|
with open('/etc/resolv.conf') as f:
|
||||||
|
contents = f.read()
|
||||||
|
if 'search one\n' in contents:
|
||||||
|
break
|
||||||
|
time.sleep(0.1)
|
||||||
|
self.assertIn('search one two three four five six\n'
|
||||||
|
'# Too many search domains configured, remaining ones ignored.\n',
|
||||||
|
contents)
|
||||||
|
|
||||||
|
def test_search_domains_too_long(self):
|
||||||
|
|
||||||
|
# we don't use this interface for this test
|
||||||
|
self.if_router = None
|
||||||
|
|
||||||
|
name_prefix = 'a' * 60
|
||||||
|
|
||||||
|
with open('/run/systemd/network/test.netdev', 'w') as f:
|
||||||
|
f.write('''[NetDev]
|
||||||
|
Name=dummy0
|
||||||
|
Kind=dummy
|
||||||
|
MACAddress=12:34:56:78:9a:bc''')
|
||||||
|
with open('/run/systemd/network/test.network', 'w') as f:
|
||||||
|
f.write('''[Match]
|
||||||
|
Name=dummy0
|
||||||
|
[Network]
|
||||||
|
Address=192.168.42.100
|
||||||
|
DNS=192.168.42.1
|
||||||
|
Domains=''')
|
||||||
|
for i in range(5):
|
||||||
|
f.write('%s%i ' % (name_prefix, i))
|
||||||
|
|
||||||
|
self.addCleanup(os.remove, '/run/systemd/network/test.netdev')
|
||||||
|
self.addCleanup(os.remove, '/run/systemd/network/test.network')
|
||||||
|
|
||||||
|
subprocess.check_call(['systemctl', 'start', 'systemd-networkd'])
|
||||||
|
|
||||||
|
if os.path.islink('/etc/resolv.conf'):
|
||||||
|
for timeout in range(50):
|
||||||
|
with open('/etc/resolv.conf') as f:
|
||||||
|
contents = f.read()
|
||||||
|
if 'search one\n' in contents:
|
||||||
|
break
|
||||||
|
time.sleep(0.1)
|
||||||
|
self.assertIn('search %(p)s0 %(p)s1 %(p)s2 %(p)s3\n'
|
||||||
|
'# Total length of all search domains is too long, remaining ones ignored.' % {'p': name_prefix},
|
||||||
|
contents)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main(testRunner=unittest.TextTestRunner(stream=sys.stdout,
|
unittest.main(testRunner=unittest.TextTestRunner(stream=sys.stdout,
|
||||||
|
|
Loading…
Reference in a new issue