Bug #1243

dntpd(8) blocks during startup

Added by hasso over 5 years ago. Updated over 5 years ago.

Status:ClosedStart date:
Priority:LowDue date:
Assignee:nthery% Done:

0%

Category:-
Target version:-

Description

If dntpd(8) is started with network configured, but not really usable yet,
dntpd(8) blocks trying to resolve servers names and connect to them before the
main loop.

It's common in wireless networks where you can make association with AP and
get a IP address, but you have to authenticate yourself via web to really
reach a network. So, your network is configured at boot, but it will block
there at dntpd(8) startup and you have to press a Ctrl+C to continue (or wait
for a long time).

History

#1 Updated by dillon over 5 years ago

If someone wants to take on this task it would actually be fairly easy
to do, maybe 2 hours of work. And probably quite fun, too. The source
is in /usr/src/usr.sbin/dntpd.

The dntpd state machine includes a DNS-resolution stage. Currently dntpd
blocks because the add_server() tries to resolve the server name prior
to demonization. The add_server() calls must still be made prior to
demonization because we want fatal parsing errors to be reported prior
to going into the background.

However, instead of having add_server() create the initial socket and
do the initial DNS resolution it could instead start the server in the
dns-reresolve state, which is state -1, and not even try to resolve
the server names from inside add_server() itself.

-Matt

#2 Updated by nthery over 5 years ago

If it's fun I'll give it a try then.

I tested the following patch by starting dntpd on a machine
disconnected from the network and set to an incorrect system time.
dntpd goes into background without hanging and, when connected back,
the time is eventually corrected.

Is it as simple as that? Have I missed some corner case?

(I'll include an explanatory comment in the final change)

diff --git a/usr.sbin/dntpd/main.c b/usr.sbin/dntpd/main.c
index 9d15bab..90634bd 100644
--- a/usr.sbin/dntpd/main.c
+++ b/usr.sbin/dntpd/main.c
@@ -344,7 +344,6 @@ static void
add_server(const char *target)
{
server_info_t info;
- const char *ipstr;

if (nservers == maxservers) {
maxservers += 16;
@@ -355,14 +354,9 @@ add_server(const char *target)
servers[nservers] = info;
bzero(info, sizeof(struct server_info));
info->sam = (struct sockaddr *)&info->sam_st;
- info->fd = udp_socket(target, 123, info->sam);
+ info->fd = -1;
info->target = strdup(target);
- if (info->fd >= 0) {
- ipstr = myaddr2ascii(info->sam);
- info->ipstr = strdup(ipstr);
- } else {
- client_setserverstate(info, -1, "DNS or IP lookup failure");
- }
+ info->server_state = -1;
++nservers;
}

#3 Updated by dillon over 5 years ago

:If it's fun I'll give it a try then.
:
:I tested the following patch by starting dntpd on a machine
:disconnected from the network and set to an incorrect system time.
:dntpd goes into background without hanging and, when connected back,
:the time is eventually corrected.
:
:Is it as simple as that? Have I missed some corner case?

Just the logging case. I'm pretty sure with a high enough logging
level it will log messages that imply a failed connection
reconnected when, in fact, it is the initial connection that is
being handled.

Other then that, well, yah... it's pretty easy :-). Take a quick
shot at the logging case and then we'll commit it.

-Matt
Matthew Dillon
<>

#4 Updated by nthery over 5 years ago

Ok. I'll check into this and commit it later this week.

Cheers,
Nicolas

#5 Updated by nthery over 5 years ago

Fix committed to crater/master.

Also available in: Atom PDF