Re: rebound quantum entanglement
+ return sysctl_int(oldp, oldlenp, newp, newlen, &dnsjacking); +int dnsjacking = 0; + sin.sin_port = htons(dnsjacking); How about using u_int16_t or in_port_t; and maybe error out if high bits are set rather than ignoring them but still displaying them.
Re: rebound quantum entanglement
Ted Unangst wrote: > Ted Unangst wrote: > > So the plan is for rebound to be the 'system' resolver, with libc talking to > > rbeound and rebound talking to the cloud. The main wrinkle is how does > > rebound > > find the cloud? rebound.conf, but dhclient doesn't know anything about > > rebound.conf, preferring to edit resolv.conf. But if rebound reads > > resolv.conf, what does libc read? This has been a bit of a tangle until now, > > especially in scenarios like upgrades where rebound may not even be running. > > Move the hijacking into the kernel. rebound sets a sysctl, and then the kernel > gives it all the dns connections. libc knows nothing. if rebound dies, dns > dies. still listening on :53 because it has to listen somewhere. configurable jack port, rebound uses 54. Index: sys/kern/kern_sysctl.c === RCS file: /cvs/src/sys/kern/kern_sysctl.c,v retrieving revision 1.311 diff -u -p -r1.311 kern_sysctl.c --- sys/kern/kern_sysctl.c 21 Sep 2016 14:06:50 - 1.311 +++ sys/kern/kern_sysctl.c 21 Sep 2016 16:06:16 - @@ -598,6 +598,10 @@ kern_sysctl(int *name, u_int namelen, vo return sysctl_int(oldp, oldlenp, newp, newlen, &global_ptrace); } #endif + case KERN_DNSJACKING: { + extern int dnsjacking; + return sysctl_int(oldp, oldlenp, newp, newlen, &dnsjacking); + } default: return (EOPNOTSUPP); } Index: sys/kern/uipc_syscalls.c === RCS file: /cvs/src/sys/kern/uipc_syscalls.c,v retrieving revision 1.133 diff -u -p -r1.133 uipc_syscalls.c --- sys/kern/uipc_syscalls.c9 Aug 2016 02:25:35 - 1.133 +++ sys/kern/uipc_syscalls.c15 Sep 2016 22:32:55 - @@ -67,6 +67,8 @@ externstruct fileops socketops; intcopyaddrout(struct proc *, struct mbuf *, struct sockaddr *, socklen_t, socklen_t *); +int dnsjacking = 0; + int sys_socket(struct proc *p, void *v, register_t *retval) { @@ -395,6 +397,16 @@ sys_connect(struct proc *p, void *v, reg FRELE(fp, p); m_freem(nam); return (error); + } + if (dnsjacking) { + struct sockaddr_in sin; + memset(&sin, 0, sizeof(sin)); + sin.sin_len = sizeof(sin); + sin.sin_family = AF_INET; + sin.sin_port = htons(dnsjacking); + sin.sin_addr.s_addr = INADDR_LOOPBACK; + memcpy(mtod(nam, void *), &sin, sizeof(sin)); + nam->m_len = sizeof(sin); } } Index: sys/sys/sysctl.h === RCS file: /cvs/src/sys/sys/sysctl.h,v retrieving revision 1.166 diff -u -p -r1.166 sysctl.h --- sys/sys/sysctl.h21 Sep 2016 14:06:50 - 1.166 +++ sys/sys/sysctl.h21 Sep 2016 16:06:16 - @@ -113,7 +113,7 @@ struct ctlname { #defineKERN_HOSTNAME 10 /* string: hostname */ #defineKERN_HOSTID 11 /* int: host identifier */ #defineKERN_CLOCKRATE 12 /* struct: struct clockinfo */ -/* was KERN_VNODE 13 */ +#defineKERN_DNSJACKING 13 /* hijack dns sockets */ /* was KERN_PROC 14 */ /* was KERN_FILE 15 */ #defineKERN_PROF 16 /* node: kernel profiling info */ @@ -200,7 +200,7 @@ struct ctlname { { "hostname", CTLTYPE_STRING }, \ { "hostid", CTLTYPE_INT }, \ { "clockrate", CTLTYPE_STRUCT }, \ - { "gap", 0 }, \ + { "dnsjacking", CTLTYPE_INT }, \ { "gap", 0 }, \ { "gap", 0 }, \ { "profiling", CTLTYPE_NODE }, \ Index: usr.sbin/rebound/rebound.8 === RCS file: /cvs/src/usr.sbin/rebound/rebound.8,v retrieving revision 1.4 diff -u -p -r1.4 rebound.8 --- usr.sbin/rebound/rebound.8 4 Dec 2015 04:50:43 - 1.4 +++ usr.sbin/rebound/rebound.8 29 Sep 2016 01:20:02 - @@ -33,9 +33,7 @@ The options are as follows: .Bl -tag -width Ds .It Fl c Ar config Specify an alternative configuration file, instead of the default -.Pa /etc/rebound.conf . -At present, the config file consists of a single line containing the next -hop DNS server. +.Pa /etc/resolv.conf . .Nm will reload the configuration file when sent a SIGHUP signal. .It Fl d @@ -46,8 +44,8 @@ does not into the background. .El .Sh FILES -.Bl -tag -width "/etc/rebound.confXX" -compact -.It Pa /etc/rebound.conf +.Bl -tag -width "/etc/resolv.confXX" -compact +.It Pa /etc/resolv.conf Default .Nm configuration file. Index: usr.sbin/rebound/rebound.c ===
Re: rebound quantum entanglement
On 2016-09-15, "Ted Unangst" wrote: > Particular edge case: if resolv.conf has no nameservers, then the localhost > default is not prepended. So libc won't try talking to rebound if it's > specifically configured not to (chroot). Huh? If resolv.conf has no nameservers, libc already falls back to the localhost. -- Christian "naddy" Weisgerber na...@mips.inka.de
Re: rebound quantum entanglement
Theo de Raadt [dera...@openbsd.org] wrote: > > That rebound acts like a nameserver is what prompted the idea to > > hijack the resolver. But it's really a tool that takes over certain > > duties from the libc resolver, so the libc resolver should be properly > > configurable to hand over duties, or not. 'search' is the logical > > place for this. > > So maybe the first generation Ted proposes has some problems. And > what have YOU DONE recently?? > Sorry guys. I didn't mean to shit all over Ted's first revision. I was just flabbergasted at the casual tone of this conversation, in contrast to what was being discussed. > Look, I think some people don't understand the goal. > > search won't work in roaming + non-roaming situations. There are > solutions being discussed to make that easier, they dovetail into > this slightly. > Roaming means dhclient right? SOCK_DNS sounds like a great clue. Chris
Re: rebound quantum entanglement
Ted Unangst wrote: > So the plan is for rebound to be the 'system' resolver, with libc talking to > rbeound and rebound talking to the cloud. The main wrinkle is how does rebound > find the cloud? rebound.conf, but dhclient doesn't know anything about > rebound.conf, preferring to edit resolv.conf. But if rebound reads > resolv.conf, what does libc read? This has been a bit of a tangle until now, > especially in scenarios like upgrades where rebound may not even be running. Move the hijacking into the kernel. rebound sets a sysctl, and then the kernel gives it all the dns connections. libc knows nothing. if rebound dies, dns dies. still listening on :53 because it has to listen somewhere. Index: sys/kern/kern_sysctl.c === RCS file: /cvs/src/sys/kern/kern_sysctl.c,v retrieving revision 1.309 diff -u -p -r1.309 kern_sysctl.c --- sys/kern/kern_sysctl.c 7 Sep 2016 17:30:12 - 1.309 +++ sys/kern/kern_sysctl.c 15 Sep 2016 22:03:19 - @@ -615,6 +615,10 @@ kern_sysctl(int *name, u_int namelen, vo return sysctl_int(oldp, oldlenp, newp, newlen, &global_ptrace); } #endif + case KERN_DNSJACKING: { + extern int dnsjacking; + return sysctl_int(oldp, oldlenp, newp, newlen, &dnsjacking); + } default: return (EOPNOTSUPP); } Index: sys/kern/uipc_syscalls.c === RCS file: /cvs/src/sys/kern/uipc_syscalls.c,v retrieving revision 1.133 diff -u -p -r1.133 uipc_syscalls.c --- sys/kern/uipc_syscalls.c9 Aug 2016 02:25:35 - 1.133 +++ sys/kern/uipc_syscalls.c15 Sep 2016 22:03:45 - @@ -67,6 +67,8 @@ externstruct fileops socketops; intcopyaddrout(struct proc *, struct mbuf *, struct sockaddr *, socklen_t, socklen_t *); +int dnsjacking = 0; + int sys_socket(struct proc *p, void *v, register_t *retval) { @@ -395,6 +397,16 @@ sys_connect(struct proc *p, void *v, reg FRELE(fp, p); m_freem(nam); return (error); + } + if (dnsjacking) { + struct sockaddr_in sin; + memset(&sin, 0, sizeof(sin)); + sin.sin_len = sizeof(sin); + sin.sin_family = AF_INET; + sin.sin_port = htons(53); + sin.sin_addr.s_addr = INADDR_LOOPBACK; + memcpy(mtod(nam, void *), &sin, sizeof(sin)); + nam->m_len = sizeof(sin); } } Index: sys/sys/sysctl.h === RCS file: /cvs/src/sys/sys/sysctl.h,v retrieving revision 1.165 diff -u -p -r1.165 sysctl.h --- sys/sys/sysctl.h7 Sep 2016 17:30:12 - 1.165 +++ sys/sys/sysctl.h15 Sep 2016 22:01:48 - @@ -113,7 +113,7 @@ struct ctlname { #defineKERN_HOSTNAME 10 /* string: hostname */ #defineKERN_HOSTID 11 /* int: host identifier */ #defineKERN_CLOCKRATE 12 /* struct: struct clockinfo */ -/* was KERN_VNODE 13 */ +#defineKERN_DNSJACKING 13 /* hijack dns sockets */ /* was KERN_PROC 14 */ /* was KERN_FILE 15 */ #defineKERN_PROF 16 /* node: kernel profiling info */ @@ -200,7 +200,7 @@ struct ctlname { { "hostname", CTLTYPE_STRING }, \ { "hostid", CTLTYPE_INT }, \ { "clockrate", CTLTYPE_STRUCT }, \ - { "gap", 0 }, \ + { "dnsjacking", CTLTYPE_INT }, \ { "gap", 0 }, \ { "gap", 0 }, \ { "profiling", CTLTYPE_NODE }, \ Index: usr.sbin/rebound/rebound.8 === RCS file: /cvs/src/usr.sbin/rebound/rebound.8,v retrieving revision 1.4 diff -u -p -r1.4 rebound.8 --- usr.sbin/rebound/rebound.8 4 Dec 2015 04:50:43 - 1.4 +++ usr.sbin/rebound/rebound.8 15 Sep 2016 00:57:21 - @@ -33,9 +33,7 @@ The options are as follows: .Bl -tag -width Ds .It Fl c Ar config Specify an alternative configuration file, instead of the default -.Pa /etc/rebound.conf . -At present, the config file consists of a single line containing the next -hop DNS server. +.Pa /etc/resolv.conf . .Nm will reload the configuration file when sent a SIGHUP signal. .It Fl d @@ -46,8 +44,8 @@ does not into the background. .El .Sh FILES -.Bl -tag -width "/etc/rebound.confXX" -compact -.It Pa /etc/rebound.conf +.Bl -tag -width "/etc/resolv.confXX" -compact +.It Pa /etc/resolv.conf Default .Nm configuration file. Index: usr.sbin/rebound/rebound.c === RCS file: /cvs/src/usr.sbin/rebound/rebound.c,v retrieving revision 1.70 diff -u -p -r1.70 rebo
Re: rebound quantum entanglement
> That rebound acts like a nameserver is what prompted the idea to > hijack the resolver. But it's really a tool that takes over certain > duties from the libc resolver, so the libc resolver should be properly > configurable to hand over duties, or not. 'search' is the logical > place for this. So maybe the first generation Ted proposes has some problems. And what have YOU DONE recently?? Look, I think some people don't understand the goal. The goal is a privsep layer for the libc resolver, with external communication operating on the other side of a priv boundary. Preventing direct communication to programs, to test their soft underbellies. That is a valuable goal. Maybe YOU trust unbound to do this. Maybe you haven't gotten a grasp of how featuritis is eating it release after release, and the risk of error creeps in constantly. I am also hearing an argument for selective configuration. That's the kind of "remember to compile with the stack protector if you believe in security!" hogwash I heard around 20 years ago. Only make it secure if you need it secure! Get off my computer kidz. We know this program-libc-external-world issue with DNS needs to be solved one day. Requiring deep port 53 invasion into a host or network is patently stupid, yet accepted. As I said, unbound does not solve the problem because the software does 900 other things you don't want. I'm hearing a tone that only people who know how to configure complex situations should be secure. That stands against my principles. For this DNS problem, I think we have a number of new ideas which can fit together to do something great, and we should endeavour to integrate this stuff. That kind of thing does not happen on one round. Such harsh condemnation of the first attempt is seriously contemptable. Take a chill pill, or participate in improving it, or wait your turn. Now to the logic. search won't work in roaming + non-roaming situations. There are solutions being discussed to make that easier, they dovetail into this slightly. For Ted's current proposal I think making this libc:resolver interface communiate via an IP address is the problem. People wish to control policy via their own IP reach policies towards their own nameservers, and 127.0.0.1 is an IP that falls into that catagory of control. For instance, hijacking 127.0.0.1 immediately makes it impossible for rebound to speak to a localhost unbound, I think it is clear this design isn't quite right. If such a twisted configuration can still work, it would indicate we are on the right road. We kind of want a secret direct interface between the resolver library routines and the resolution daemon (or remote one). BTW, it has been done before -- the original Sun ypserv used to do this, and I suppose other systems have done it also. Luckily we already have a mechanism which allows us to know that a DNS lookup is being performed by libc -- the socket has been opened with SOCK_DNS. In some way, those can be directed to a rebound (if it is running) -- which can then do the standard dance of honouring /etc/resolv.conf, just like libc would have. Which would allow all other configurations to work, probably. Yes there are also not-our-resolvers which lack the SOCK_DNS flag. We want to do the right thing there. They would continue to lookup via resolv.conf, and miss out on rebound protection. Eventually when people realize programs-speaking-to-rebound prevent a host from selectively filtering port 53 to only one program (rebound), then maybe they'll want to fix those other programs/libraries. It is a long road. I don't know these ideas creates new problems. We'll just have try them out. But throwing them under the bus with +1's is basically the 'get off my lawn" argument. But at least I'll try to engage in constructive arguments with Ted, because if we can pull this cleanly it will be great.
Re: rebound quantum entanglement
On Thu, 15 Sep 2016, Chris Cappuccio wrote: > That rebound acts like a nameserver is what prompted the idea to > hijack the resolver. But it's really a tool that takes over certain > duties from the libc resolver, so the libc resolver should be properly > configurable to hand over duties, or not. 'search' is the logical > place for this. +1 to this Hidden magic configuration always causes grief.
Re: rebound quantum entanglement
Bryan Steele [bry...@gmail.com] wrote: > On Thu, Sep 15, 2016 at 10:14:51AM -0400, Ted Unangst wrote: > > Florian Obser wrote: > > > Not everything listening on localhost port 53 is a recursive resolver. > > > nsd(8) per defaults listens on 0.0.0.0 and will respond with REFUSED for > > > almost every query. asr stops in that case and does not try the next > > > resolver in the list. > > > > Ah! There's the catch. The good news is I think we can still bind to > > localhost:53 if nsd is on *:53 (right?). This matters if rebound isn't > > listening. > > Perhaps I'm confused, but what happens when rebound is stopped by the > user or it crashes? I think that would mean requests would fallback to > nsd on *:53 which as Florian mentioned, would not try the next > nameserver in resolv.conf. > This entire discussion is bat-shit crazy to me! Adding secret nameservers to resolv.conf is plain wrong. Hijacking the libc resolver is an approach for systemd, not OpenBSD. I already configure special nameservers on certain machines, that bind to 127.0.0.1, for my own reasons. In a general sense, when I configure the system to do something, and it does something different, I now have to recompile libc. What !??!?! This point that has been reached in this discussion just reinforces the idea that this approach is wrong. The sensible thing to do is add a 'search' parameter to resolv.conf. If programs parse resolv.conf themselves, and they break, we should fix them. It seems like the default should be 'search rebound file bind' and 'search rebound bind file' if no 'lookup' keyword is specified. Most users won't ever have 'search rebound' visible in their resolv.conf. That rebound acts like a nameserver is what prompted the idea to hijack the resolver. But it's really a tool that takes over certain duties from the libc resolver, so the libc resolver should be properly configurable to hand over duties, or not. 'search' is the logical place for this. Chris
Re: rebound quantum entanglement
On 2016/09/15 06:23, Jiri B wrote: > On Thu, Sep 15, 2016 at 10:04:00AM +0100, Stuart Henderson wrote: > > > What about this: > > > > > > Add "rebound" as possible value to the lookup keyword in resolv.conf. > > > If this is set the libc resolver sends dns requests to the unix socket > > > /var/run/rebound.sock where rebound listens. rebound can use the > > > nameservers from /etc/resolv.conf without the risk of creating "loops". > > > > > > Remi > > > > > > > Non-standard things in resolv.conf hurt; some programs parse this directly. > > Why not having rebound as proxy and use PF anchor for that? > Or having a sysctl knob to "hijack" it somehow? There are certainly plenty of use cases where having it as a hijacking proxy would be a problem (for example, when you want to do a direct DNS lookup from an auth server). On 2016/09/15 13:42, Remi Locherer wrote: > On Thu, Sep 15, 2016 at 10:04:00AM +0100, Stuart Henderson wrote: > > > > Non-standard things in resolv.conf hurt; some programs parse this directly. > > I did not think of this. Was there a big fallout in 2009 when the family > option was added? How do programs that parse /etc/resolv.conf directly deal > with "lookup yp"? (I know, lookup yp hase been removed recently). Not sure about "family". There were definitely problems with the extension to allow using a particular port.
Re: rebound quantum entanglement
On Thu, Sep 15, 2016 at 10:14:51AM -0400, Ted Unangst wrote: > Florian Obser wrote: > > Not everything listening on localhost port 53 is a recursive resolver. > > nsd(8) per defaults listens on 0.0.0.0 and will respond with REFUSED for > > almost every query. asr stops in that case and does not try the next > > resolver in the list. > > Ah! There's the catch. The good news is I think we can still bind to > localhost:53 if nsd is on *:53 (right?). This matters if rebound isn't > listening. Perhaps I'm confused, but what happens when rebound is stopped by the user or it crashes? I think that would mean requests would fallback to nsd on *:53 which as Florian mentioned, would not try the next nameserver in resolv.conf. -Bryan.
Re: rebound quantum entanglement
* Ted Unangst [2016-09-15 16:15]: > The good news is I think we can still bind to > localhost:53 if nsd is on *:53 (right?). right. -- Henning Brauer, h...@bsws.de, henn...@openbsd.org BS Web Services GmbH, http://bsws.de, Full-Service ISP Secure Hosting, Mail and DNS. Virtual & Dedicated Servers, Root to Fully Managed Henning Brauer Consulting, http://henningbrauer.com/
Re: rebound quantum entanglement
Florian Obser wrote: > Not everything listening on localhost port 53 is a recursive resolver. > nsd(8) per defaults listens on 0.0.0.0 and will respond with REFUSED for > almost every query. asr stops in that case and does not try the next > resolver in the list. Ah! There's the catch. The good news is I think we can still bind to localhost:53 if nsd is on *:53 (right?). This matters if rebound isn't listening.
Re: rebound quantum entanglement
On Wed, Sep 14, 2016 at 09:19:07PM -0400, Ted Unangst wrote: > So the plan is for rebound to be the 'system' resolver, with libc talking to > rbeound and rebound talking to the cloud. The main wrinkle is how does rebound > find the cloud? rebound.conf, but dhclient doesn't know anything about > rebound.conf, preferring to edit resolv.conf. But if rebound reads > resolv.conf, what does libc read? This has been a bit of a tangle until now, > especially in scenarios like upgrades where rebound may not even be running. > > And so I present the following diff to enable a smooth transition. It's > 'quantum' because it works whether or not rebound is running. No need to open > the box. > > 1. rebound reads resolv.conf. This remains the config file for upstream DNS. > > 2. libc now prepends its nameserver list with localhost, thus always searching > for rebound. If it's not running, we just continue down the list. Not everything listening on localhost port 53 is a recursive resolver. nsd(8) per defaults listens on 0.0.0.0 and will respond with REFUSED for almost every query. asr stops in that case and does not try the next resolver in the list. -- I'm not entirely sure you are real.
Re: rebound quantum entanglement
On Thu, Sep 15, 2016 at 10:04:00AM +0100, Stuart Henderson wrote: > On 2016/09/15 10:39, Remi Locherer wrote: > > On Wed, Sep 14, 2016 at 08:10:29PM -0600, Theo de Raadt wrote: > > > > > wont this also mean if it is not running i have to wait for the > > > > > localhost > > > > > attempt to fail before the resolver moves on? (ASR_STATE_NEXT_NS, > > > > > etc) so i > > > > > slow everything down for a timeout? > > > > > > > > Not if he connects to the TCP port 53 instead of the UDP; it looks like > > > > rebound binds to both. > > > > > > OK. But I suspect this is multiple system-call roundtrip for everyone > > > not running rebound. > > > > What about this: > > > > Add "rebound" as possible value to the lookup keyword in resolv.conf. > > If this is set the libc resolver sends dns requests to the unix socket > > /var/run/rebound.sock where rebound listens. rebound can use the > > nameservers from /etc/resolv.conf without the risk of creating "loops". > > > > Remi > > > > Non-standard things in resolv.conf hurt; some programs parse this directly. I did not think of this. Was there a big fallout in 2009 when the family option was added? How do programs that parse /etc/resolv.conf directly deal with "lookup yp"? (I know, lookup yp hase been removed recently).
Re: rebound quantum entanglement
On 2016/09/15 10:39, Remi Locherer wrote: > On Wed, Sep 14, 2016 at 08:10:29PM -0600, Theo de Raadt wrote: > > > > wont this also mean if it is not running i have to wait for the > > > > localhost > > > > attempt to fail before the resolver moves on? (ASR_STATE_NEXT_NS, etc) > > > > so i > > > > slow everything down for a timeout? > > > > > > Not if he connects to the TCP port 53 instead of the UDP; it looks like > > > rebound binds to both. > > > > OK. But I suspect this is multiple system-call roundtrip for everyone > > not running rebound. > > What about this: > > Add "rebound" as possible value to the lookup keyword in resolv.conf. > If this is set the libc resolver sends dns requests to the unix socket > /var/run/rebound.sock where rebound listens. rebound can use the > nameservers from /etc/resolv.conf without the risk of creating "loops". > > Remi > Non-standard things in resolv.conf hurt; some programs parse this directly.
Re: rebound quantum entanglement
On Wed, Sep 14, 2016 at 08:10:29PM -0600, Theo de Raadt wrote: > > > wont this also mean if it is not running i have to wait for the localhost > > > attempt to fail before the resolver moves on? (ASR_STATE_NEXT_NS, etc) so > > > i > > > slow everything down for a timeout? > > > > Not if he connects to the TCP port 53 instead of the UDP; it looks like > > rebound binds to both. > > OK. But I suspect this is multiple system-call roundtrip for everyone > not running rebound. What about this: Add "rebound" as possible value to the lookup keyword in resolv.conf. If this is set the libc resolver sends dns requests to the unix socket /var/run/rebound.sock where rebound listens. rebound can use the nameservers from /etc/resolv.conf without the risk of creating "loops". Remi
Re: rebound quantum entanglement
On Wed, Sep 14, 2016 at 09:19:07PM -0400, Ted Unangst wrote: > And so I present the following diff to enable a smooth transition. It's > 'quantum' because it works whether or not rebound is running. No need to open > the box. I'm sure there's a cat(ch)... -- Erling Westenvik
Re: rebound quantum entanglement
BTW I'm not picking on you.. my DNS setup blew up this week for local resolution and I've been dealing with the fallout - so the topic is relatively near and dear to my heart. On Wed, Sep 14, 2016 at 10:07 PM, Bob Beck wrote: > > Yep. and now you need to solve the problem that when prepending > 127.0.0.1, and hitting rebound, which in turn is going to only grab the > first dns server from my resolv.conf instead of all of them, that it now > doubles my failure time when the first dns server doesn't respond (once for > libc asking rebound, which asks only the first server it found, which > fails) then falls back to libc asking resolv.conf which again... asks the > first server, and fails again. > > So the problem here is that it's going to be great when things are working > but become a failure multiplier when something breaks. > > Of course - perhaps you could query them all in parallel to mitigate this? > Rebound might need to become a real boy if we're going to do something > like this. If rebound were a "real boy" it would be it easier to say "just > use rebound or if it's not there just use resolv.conf normally > > then nothing changes at *all* when it's not there. > > > On Wed, Sep 14, 2016 at 8:39 PM, Ted Unangst wrote: > >> Ted Unangst wrote: >> > Bob Beck wrote: >> > > how is rebound going to handle a change in resolv.conf? thats still a >> > > problem here >> > >> > oh, that's easy. it watches the file for changes. i never quite got >> around to >> > that, but it's another five lines. >> >> ok, so it's a net +15 lines, including blanks. >> >> Index: rebound.8 >> === >> RCS file: /cvs/src/usr.sbin/rebound/rebound.8,v >> retrieving revision 1.4 >> diff -u -p -r1.4 rebound.8 >> --- rebound.8 4 Dec 2015 04:50:43 - 1.4 >> +++ rebound.8 15 Sep 2016 00:57:21 - >> @@ -33,9 +33,7 @@ The options are as follows: >> .Bl -tag -width Ds >> .It Fl c Ar config >> Specify an alternative configuration file, instead of the default >> -.Pa /etc/rebound.conf . >> -At present, the config file consists of a single line containing the next >> -hop DNS server. >> +.Pa /etc/resolv.conf . >> .Nm >> will reload the configuration file when sent a SIGHUP signal. >> .It Fl d >> @@ -46,8 +44,8 @@ does not >> into the background. >> .El >> .Sh FILES >> -.Bl -tag -width "/etc/rebound.confXX" -compact >> -.It Pa /etc/rebound.conf >> +.Bl -tag -width "/etc/resolv.confXX" -compact >> +.It Pa /etc/resolv.conf >> Default >> .Nm >> configuration file. >> Index: rebound.c >> === >> RCS file: /cvs/src/usr.sbin/rebound/rebound.c,v >> retrieving revision 1.70 >> diff -u -p -r1.70 rebound.c >> --- rebound.c 1 Sep 2016 10:57:24 - 1.70 >> +++ rebound.c 15 Sep 2016 02:30:46 - >> @@ -33,10 +33,12 @@ >> #include >> #include >> #include >> +#include >> #include >> #include >> #include >> #include >> +#include >> >> #define MINIMUM(a,b) (((a)<(b))?(a):(b)) >> >> @@ -455,34 +457,51 @@ fail: >> } >> >> static int >> -readconfig(FILE *conf, union sockun *remoteaddr) >> +readconfig(int conffd, union sockun *remoteaddr) >> { >> + const char ns[] = "nameserver"; >> char buf[1024]; >> + char *p; >> struct sockaddr_in *sin = &remoteaddr->i; >> struct sockaddr_in6 *sin6 = &remoteaddr->i6; >> + FILE *conf; >> + int rv = -1; >> >> - if (fgets(buf, sizeof(buf), conf) == NULL) >> - return -1; >> - buf[strcspn(buf, "\n")] = '\0'; >> + conf = fdopen(conffd, "r"); >> >> - memset(remoteaddr, 0, sizeof(*remoteaddr)); >> - if (inet_pton(AF_INET, buf, &sin->sin_addr) == 1) { >> - sin->sin_len = sizeof(*sin); >> - sin->sin_family = AF_INET; >> - sin->sin_port = htons(53); >> - return AF_INET; >> - } else if (inet_pton(AF_INET6, buf, &sin6->sin6_addr) == 1) { >> - sin6->sin6_len = sizeof(*sin6); >> - sin6->sin6_family = AF_INET6; >> - sin6->sin6_port = htons(53); >> - return AF_INET6; >> - } else { >> - return -1; >> + while (fgets(buf, sizeof(buf), conf) != NULL) { >> + buf[strcspn(buf, "\n")] = '\0'; >> + >> + if (strncmp(buf, ns, strlen(ns)) != 0) >> + continue; >> + p = buf + strlen(ns) + 1; >> + while (isspace((unsigned char)*p)) >> + p++; >> + >> + /* this will not end well */ >> + if (strcmp(p, "127.0.0.1") == 0) >> + continue; >> + >> + memset(remoteaddr, 0, sizeof(*remoteaddr)); >> + if (inet_pton(AF_INET, p, &sin->sin_addr) == 1) { >> + sin->sin_len = sizeof(*sin); >> + sin->sin_family = AF_INET; >> +
Re: rebound quantum entanglement
Yep. and now you need to solve the problem that when prepending 127.0.0.1, and hitting rebound, which in turn is going to only grab the first dns server from my resolv.conf instead of all of them, that it now doubles my failure time when the first dns server doesn't respond (once for libc asking rebound, which asks only the first server it found, which fails) then falls back to libc asking resolv.conf which again... asks the first server, and fails again. So the problem here is that it's going to be great when things are working but become a failure multiplier when something breaks. Of course - perhaps you could query them all in parallel to mitigate this? Rebound might need to become a real boy if we're going to do something like this. If rebound were a "real boy" it would be it easier to say "just use rebound or if it's not there just use resolv.conf normally then nothing changes at *all* when it's not there. On Wed, Sep 14, 2016 at 8:39 PM, Ted Unangst wrote: > Ted Unangst wrote: > > Bob Beck wrote: > > > how is rebound going to handle a change in resolv.conf? thats still a > > > problem here > > > > oh, that's easy. it watches the file for changes. i never quite got > around to > > that, but it's another five lines. > > ok, so it's a net +15 lines, including blanks. > > Index: rebound.8 > === > RCS file: /cvs/src/usr.sbin/rebound/rebound.8,v > retrieving revision 1.4 > diff -u -p -r1.4 rebound.8 > --- rebound.8 4 Dec 2015 04:50:43 - 1.4 > +++ rebound.8 15 Sep 2016 00:57:21 - > @@ -33,9 +33,7 @@ The options are as follows: > .Bl -tag -width Ds > .It Fl c Ar config > Specify an alternative configuration file, instead of the default > -.Pa /etc/rebound.conf . > -At present, the config file consists of a single line containing the next > -hop DNS server. > +.Pa /etc/resolv.conf . > .Nm > will reload the configuration file when sent a SIGHUP signal. > .It Fl d > @@ -46,8 +44,8 @@ does not > into the background. > .El > .Sh FILES > -.Bl -tag -width "/etc/rebound.confXX" -compact > -.It Pa /etc/rebound.conf > +.Bl -tag -width "/etc/resolv.confXX" -compact > +.It Pa /etc/resolv.conf > Default > .Nm > configuration file. > Index: rebound.c > === > RCS file: /cvs/src/usr.sbin/rebound/rebound.c,v > retrieving revision 1.70 > diff -u -p -r1.70 rebound.c > --- rebound.c 1 Sep 2016 10:57:24 - 1.70 > +++ rebound.c 15 Sep 2016 02:30:46 - > @@ -33,10 +33,12 @@ > #include > #include > #include > +#include > #include > #include > #include > #include > +#include > > #define MINIMUM(a,b) (((a)<(b))?(a):(b)) > > @@ -455,34 +457,51 @@ fail: > } > > static int > -readconfig(FILE *conf, union sockun *remoteaddr) > +readconfig(int conffd, union sockun *remoteaddr) > { > + const char ns[] = "nameserver"; > char buf[1024]; > + char *p; > struct sockaddr_in *sin = &remoteaddr->i; > struct sockaddr_in6 *sin6 = &remoteaddr->i6; > + FILE *conf; > + int rv = -1; > > - if (fgets(buf, sizeof(buf), conf) == NULL) > - return -1; > - buf[strcspn(buf, "\n")] = '\0'; > + conf = fdopen(conffd, "r"); > > - memset(remoteaddr, 0, sizeof(*remoteaddr)); > - if (inet_pton(AF_INET, buf, &sin->sin_addr) == 1) { > - sin->sin_len = sizeof(*sin); > - sin->sin_family = AF_INET; > - sin->sin_port = htons(53); > - return AF_INET; > - } else if (inet_pton(AF_INET6, buf, &sin6->sin6_addr) == 1) { > - sin6->sin6_len = sizeof(*sin6); > - sin6->sin6_family = AF_INET6; > - sin6->sin6_port = htons(53); > - return AF_INET6; > - } else { > - return -1; > + while (fgets(buf, sizeof(buf), conf) != NULL) { > + buf[strcspn(buf, "\n")] = '\0'; > + > + if (strncmp(buf, ns, strlen(ns)) != 0) > + continue; > + p = buf + strlen(ns) + 1; > + while (isspace((unsigned char)*p)) > + p++; > + > + /* this will not end well */ > + if (strcmp(p, "127.0.0.1") == 0) > + continue; > + > + memset(remoteaddr, 0, sizeof(*remoteaddr)); > + if (inet_pton(AF_INET, p, &sin->sin_addr) == 1) { > + sin->sin_len = sizeof(*sin); > + sin->sin_family = AF_INET; > + sin->sin_port = htons(53); > + rv = AF_INET; > + } else if (inet_pton(AF_INET6, p, &sin6->sin6_addr) == 1) { > + sin6->sin6_len = sizeof(*sin6); > + sin6->sin6_family = AF_INET6; > + sin6->sin6_port = htons(53); > + rv = AF_INET6; > +
Re: rebound quantum entanglement
Ted Unangst wrote: > Bob Beck wrote: > > how is rebound going to handle a change in resolv.conf? thats still a > > problem here > > oh, that's easy. it watches the file for changes. i never quite got around to > that, but it's another five lines. ok, so it's a net +15 lines, including blanks. Index: rebound.8 === RCS file: /cvs/src/usr.sbin/rebound/rebound.8,v retrieving revision 1.4 diff -u -p -r1.4 rebound.8 --- rebound.8 4 Dec 2015 04:50:43 - 1.4 +++ rebound.8 15 Sep 2016 00:57:21 - @@ -33,9 +33,7 @@ The options are as follows: .Bl -tag -width Ds .It Fl c Ar config Specify an alternative configuration file, instead of the default -.Pa /etc/rebound.conf . -At present, the config file consists of a single line containing the next -hop DNS server. +.Pa /etc/resolv.conf . .Nm will reload the configuration file when sent a SIGHUP signal. .It Fl d @@ -46,8 +44,8 @@ does not into the background. .El .Sh FILES -.Bl -tag -width "/etc/rebound.confXX" -compact -.It Pa /etc/rebound.conf +.Bl -tag -width "/etc/resolv.confXX" -compact +.It Pa /etc/resolv.conf Default .Nm configuration file. Index: rebound.c === RCS file: /cvs/src/usr.sbin/rebound/rebound.c,v retrieving revision 1.70 diff -u -p -r1.70 rebound.c --- rebound.c 1 Sep 2016 10:57:24 - 1.70 +++ rebound.c 15 Sep 2016 02:30:46 - @@ -33,10 +33,12 @@ #include #include #include +#include #include #include #include #include +#include #define MINIMUM(a,b) (((a)<(b))?(a):(b)) @@ -455,34 +457,51 @@ fail: } static int -readconfig(FILE *conf, union sockun *remoteaddr) +readconfig(int conffd, union sockun *remoteaddr) { + const char ns[] = "nameserver"; char buf[1024]; + char *p; struct sockaddr_in *sin = &remoteaddr->i; struct sockaddr_in6 *sin6 = &remoteaddr->i6; + FILE *conf; + int rv = -1; - if (fgets(buf, sizeof(buf), conf) == NULL) - return -1; - buf[strcspn(buf, "\n")] = '\0'; + conf = fdopen(conffd, "r"); - memset(remoteaddr, 0, sizeof(*remoteaddr)); - if (inet_pton(AF_INET, buf, &sin->sin_addr) == 1) { - sin->sin_len = sizeof(*sin); - sin->sin_family = AF_INET; - sin->sin_port = htons(53); - return AF_INET; - } else if (inet_pton(AF_INET6, buf, &sin6->sin6_addr) == 1) { - sin6->sin6_len = sizeof(*sin6); - sin6->sin6_family = AF_INET6; - sin6->sin6_port = htons(53); - return AF_INET6; - } else { - return -1; + while (fgets(buf, sizeof(buf), conf) != NULL) { + buf[strcspn(buf, "\n")] = '\0'; + + if (strncmp(buf, ns, strlen(ns)) != 0) + continue; + p = buf + strlen(ns) + 1; + while (isspace((unsigned char)*p)) + p++; + + /* this will not end well */ + if (strcmp(p, "127.0.0.1") == 0) + continue; + + memset(remoteaddr, 0, sizeof(*remoteaddr)); + if (inet_pton(AF_INET, p, &sin->sin_addr) == 1) { + sin->sin_len = sizeof(*sin); + sin->sin_family = AF_INET; + sin->sin_port = htons(53); + rv = AF_INET; + } else if (inet_pton(AF_INET6, p, &sin6->sin6_addr) == 1) { + sin6->sin6_len = sizeof(*sin6); + sin6->sin6_family = AF_INET6; + sin6->sin6_port = htons(53); + rv = AF_INET6; + } + break; } + fclose(conf); + return rv; } static int -launch(FILE *conf, int ud, int ld, int kq) +launch(int conffd, int ud, int ld) { union sockun remoteaddr; struct kevent ch[2], kev[4]; @@ -490,16 +509,13 @@ launch(FILE *conf, int ud, int ld, int k struct request *req; struct dnscache *ent; struct passwd *pwd; - int i, r, af; + int i, r, af, kq; pid_t parent, child; parent = getpid(); if (!debug) { - if ((child = fork())) { - fclose(conf); + if ((child = fork())) return child; - } - close(kq); } kq = kqueue(); @@ -526,8 +542,7 @@ launch(FILE *conf, int ud, int ld, int k if (pledge("stdio inet", NULL) == -1) logerr("pledge failed"); - af = readconfig(conf, &remoteaddr); - fclose(conf); + af = readconfig(conffd, &remoteaddr); if (af == -1) logerr("parse error in config file"); @@ -647,6 +662,23 @@ launch(FILE *conf, int ud, int ld, int k exit(1); } +static int +openconfi
Re: rebound quantum entanglement
Bob Beck wrote: > wont this also mean if it is not running i have to wait for the localhost > attempt to fail before the resolver moves on? (ASR_STATE_NEXT_NS, etc) so i > slow everything down for a timeout? you get back unreachable and move on. it's fast. you can try it. :)
Re: rebound quantum entanglement
> > wont this also mean if it is not running i have to wait for the localhost > > attempt to fail before the resolver moves on? (ASR_STATE_NEXT_NS, etc) so i > > slow everything down for a timeout? > > Not if he connects to the TCP port 53 instead of the UDP; it looks like > rebound binds to both. OK. But I suspect this is multiple system-call roundtrip for everyone not running rebound.
Re: rebound quantum entanglement
On Wed, 14 Sep 2016 20:00:32 -0600, Bob Beck wrote: > wont this also mean if it is not running i have to wait for the localhost > attempt to fail before the resolver moves on? (ASR_STATE_NEXT_NS, etc) so i > slow everything down for a timeout? Not if he connects to the TCP port 53 instead of the UDP; it looks like rebound binds to both. - todd
Re: rebound quantum entanglement
> wont this also mean if it is not running i have to wait for the localhost > attempt to fail before the resolver moves on? (ASR_STATE_NEXT_NS, etc) so i > slow everything down for a timeout? i think that is right. ktrace would show what is going on. if it stalls, this is not enough.
Re: rebound quantum entanglement
wont this also mean if it is not running i have to wait for the localhost attempt to fail before the resolver moves on? (ASR_STATE_NEXT_NS, etc) so i slow everything down for a timeout? dont get me wrong, it is an interesting direction, but I think maybe get the rest of the five line changes into rebound to make it useful and then look at libc which might need slightly more cleverness than just adding localhost unconditionally. On Wednesday, 14 September 2016, Ted Unangst wrote: > Bob Beck wrote: > > how is rebound going to handle a change in resolv.conf? thats still a > > problem here > > oh, that's easy. it watches the file for changes. i never quite got around > to > that, but it's another five lines. >
Re: rebound quantum entanglement
Bob Beck wrote: > how is rebound going to handle a change in resolv.conf? thats still a > problem here oh, that's easy. it watches the file for changes. i never quite got around to that, but it's another five lines.
Re: rebound quantum entanglement
how is rebound going to handle a change in resolv.conf? thats still a problem here On Wednesday, 14 September 2016, Ted Unangst wrote: > So the plan is for rebound to be the 'system' resolver, with libc talking > to > rbeound and rebound talking to the cloud. The main wrinkle is how does > rebound > find the cloud? rebound.conf, but dhclient doesn't know anything about > rebound.conf, preferring to edit resolv.conf. But if rebound reads > resolv.conf, what does libc read? This has been a bit of a tangle until > now, > especially in scenarios like upgrades where rebound may not even be > running. > > And so I present the following diff to enable a smooth transition. It's > 'quantum' because it works whether or not rebound is running. No need to > open > the box. > > 1. rebound reads resolv.conf. This remains the config file for upstream > DNS. > > 2. libc now prepends its nameserver list with localhost, thus always > searching > for rebound. If it's not running, we just continue down the list. > > This covers the basic use case, where enabling rebound now requires no > additional work. No need to edit dhclient.conf, etc. It also works on > ramdisks. It also works with a mix of old and new binaries. Once you flip > resolv.conf back to upstream, old binaries will bypass rebound, but that's > ok. > The new rebound checks to make sure it's not stuck in a time loop, which is > never good. > > I also note this improves the situation for people who have been using > unbound > as a local cache, too. Just enable unbound and libc will use it > automatically. > > Particular edge case: if resolv.conf has no nameservers, then the localhost > default is not prepended. So libc won't try talking to rebound if it's > specifically configured not to (chroot). > > > Index: lib/libc/asr/asr.c > === > RCS file: /cvs/src/lib/libc/asr/asr.c,v > retrieving revision 1.54 > diff -u -p -r1.54 asr.c > --- lib/libc/asr/asr.c 18 Jun 2016 15:25:28 - 1.54 > +++ lib/libc/asr/asr.c 15 Sep 2016 00:42:30 - > @@ -549,6 +549,15 @@ pass0(char **tok, int n, struct asr_ctx > return; > if (n != 2) > return; > + /* prepend localhost to list */ > + if (ac->ac_nscount == 0) { > + if (asr_parse_nameserver((struct sockaddr *)&ss, > "127.0.0.1")) > + return; > + if ((ac->ac_ns[ac->ac_nscount] = calloc(1, > ss.ss_len)) == NULL) > + return; > + memmove(ac->ac_ns[ac->ac_nscount], &ss, > ss.ss_len); > + ac->ac_nscount += 1; > + } > if (asr_parse_nameserver((struct sockaddr *)&ss, tok[1])) > return; > if ((ac->ac_ns[ac->ac_nscount] = calloc(1, ss.ss_len)) == > NULL) > Index: usr.sbin/rebound/rebound.8 > === > RCS file: /cvs/src/usr.sbin/rebound/rebound.8,v > retrieving revision 1.4 > diff -u -p -r1.4 rebound.8 > --- usr.sbin/rebound/rebound.8 4 Dec 2015 04:50:43 - 1.4 > +++ usr.sbin/rebound/rebound.8 15 Sep 2016 00:57:21 - > @@ -33,9 +33,7 @@ The options are as follows: > .Bl -tag -width Ds > .It Fl c Ar config > Specify an alternative configuration file, instead of the default > -.Pa /etc/rebound.conf . > -At present, the config file consists of a single line containing the next > -hop DNS server. > +.Pa /etc/resolv.conf . > .Nm > will reload the configuration file when sent a SIGHUP signal. > .It Fl d > @@ -46,8 +44,8 @@ does not > into the background. > .El > .Sh FILES > -.Bl -tag -width "/etc/rebound.confXX" -compact > -.It Pa /etc/rebound.conf > +.Bl -tag -width "/etc/resolv.confXX" -compact > +.It Pa /etc/resolv.conf > Default > .Nm > configuration file. > Index: usr.sbin/rebound/rebound.c > === > RCS file: /cvs/src/usr.sbin/rebound/rebound.c,v > retrieving revision 1.70 > diff -u -p -r1.70 rebound.c > --- usr.sbin/rebound/rebound.c 1 Sep 2016 10:57:24 - 1.70 > +++ usr.sbin/rebound/rebound.c 15 Sep 2016 00:53:26 - > @@ -37,6 +37,7 @@ > #include > #include > #include > +#include > > #define MINIMUM(a,b) (((a)<(b))?(a):(b)) > > @@ -457,28 +458,41 @@ fail: > static int > readconfig(FILE *conf, union sockun *remoteaddr) > { > + const char ns[] = "nameserver"; > char buf[1024]; > + char *p; > struct sockaddr_in *sin = &remoteaddr->i; > struct sockaddr_in6 *sin6 = &remoteaddr->i6; > > - if (fgets(buf, sizeof(buf), conf) == NULL) > - return -1; > - buf[strcspn(buf, "\n")] = '\0'; > + while (fgets(buf, sizeof(buf), conf) != NULL) { > + buf[strcspn(buf, "\n")] = '\0'; > > - memset(remoteaddr, 0, sizeof(*remoteadd
rebound quantum entanglement
So the plan is for rebound to be the 'system' resolver, with libc talking to rbeound and rebound talking to the cloud. The main wrinkle is how does rebound find the cloud? rebound.conf, but dhclient doesn't know anything about rebound.conf, preferring to edit resolv.conf. But if rebound reads resolv.conf, what does libc read? This has been a bit of a tangle until now, especially in scenarios like upgrades where rebound may not even be running. And so I present the following diff to enable a smooth transition. It's 'quantum' because it works whether or not rebound is running. No need to open the box. 1. rebound reads resolv.conf. This remains the config file for upstream DNS. 2. libc now prepends its nameserver list with localhost, thus always searching for rebound. If it's not running, we just continue down the list. This covers the basic use case, where enabling rebound now requires no additional work. No need to edit dhclient.conf, etc. It also works on ramdisks. It also works with a mix of old and new binaries. Once you flip resolv.conf back to upstream, old binaries will bypass rebound, but that's ok. The new rebound checks to make sure it's not stuck in a time loop, which is never good. I also note this improves the situation for people who have been using unbound as a local cache, too. Just enable unbound and libc will use it automatically. Particular edge case: if resolv.conf has no nameservers, then the localhost default is not prepended. So libc won't try talking to rebound if it's specifically configured not to (chroot). Index: lib/libc/asr/asr.c === RCS file: /cvs/src/lib/libc/asr/asr.c,v retrieving revision 1.54 diff -u -p -r1.54 asr.c --- lib/libc/asr/asr.c 18 Jun 2016 15:25:28 - 1.54 +++ lib/libc/asr/asr.c 15 Sep 2016 00:42:30 - @@ -549,6 +549,15 @@ pass0(char **tok, int n, struct asr_ctx return; if (n != 2) return; + /* prepend localhost to list */ + if (ac->ac_nscount == 0) { + if (asr_parse_nameserver((struct sockaddr *)&ss, "127.0.0.1")) + return; + if ((ac->ac_ns[ac->ac_nscount] = calloc(1, ss.ss_len)) == NULL) + return; + memmove(ac->ac_ns[ac->ac_nscount], &ss, ss.ss_len); + ac->ac_nscount += 1; + } if (asr_parse_nameserver((struct sockaddr *)&ss, tok[1])) return; if ((ac->ac_ns[ac->ac_nscount] = calloc(1, ss.ss_len)) == NULL) Index: usr.sbin/rebound/rebound.8 === RCS file: /cvs/src/usr.sbin/rebound/rebound.8,v retrieving revision 1.4 diff -u -p -r1.4 rebound.8 --- usr.sbin/rebound/rebound.8 4 Dec 2015 04:50:43 - 1.4 +++ usr.sbin/rebound/rebound.8 15 Sep 2016 00:57:21 - @@ -33,9 +33,7 @@ The options are as follows: .Bl -tag -width Ds .It Fl c Ar config Specify an alternative configuration file, instead of the default -.Pa /etc/rebound.conf . -At present, the config file consists of a single line containing the next -hop DNS server. +.Pa /etc/resolv.conf . .Nm will reload the configuration file when sent a SIGHUP signal. .It Fl d @@ -46,8 +44,8 @@ does not into the background. .El .Sh FILES -.Bl -tag -width "/etc/rebound.confXX" -compact -.It Pa /etc/rebound.conf +.Bl -tag -width "/etc/resolv.confXX" -compact +.It Pa /etc/resolv.conf Default .Nm configuration file. Index: usr.sbin/rebound/rebound.c === RCS file: /cvs/src/usr.sbin/rebound/rebound.c,v retrieving revision 1.70 diff -u -p -r1.70 rebound.c --- usr.sbin/rebound/rebound.c 1 Sep 2016 10:57:24 - 1.70 +++ usr.sbin/rebound/rebound.c 15 Sep 2016 00:53:26 - @@ -37,6 +37,7 @@ #include #include #include +#include #define MINIMUM(a,b) (((a)<(b))?(a):(b)) @@ -457,28 +458,41 @@ fail: static int readconfig(FILE *conf, union sockun *remoteaddr) { + const char ns[] = "nameserver"; char buf[1024]; + char *p; struct sockaddr_in *sin = &remoteaddr->i; struct sockaddr_in6 *sin6 = &remoteaddr->i6; - if (fgets(buf, sizeof(buf), conf) == NULL) - return -1; - buf[strcspn(buf, "\n")] = '\0'; + while (fgets(buf, sizeof(buf), conf) != NULL) { + buf[strcspn(buf, "\n")] = '\0'; - memset(remoteaddr, 0, sizeof(*remoteaddr)); - if (inet_pton(AF_INET, buf, &sin->sin_addr) == 1) { - sin->sin_len = sizeof(*sin); - sin->sin_family = AF_INET; - sin->sin_port = htons(53); - return AF_INET; - } else if (inet_pton(AF_INET6, buf, &sin6->sin6_addr) == 1) { - sin6->sin6_len = sizeof(*sin6); - sin6->sin6_fami