Good morning !

The intended invariant is that /tmp/resolv.conf is handled whenever a resolver 
listens on 127.0.0.1#53.

Within just the scope of dnsmasq, finding the instance that is to be regarded 
the main instance, seems a fairly simple test:
(dnsmasq listens on loopback by default irrespective of the setting of 
nonwildcard)
Proposed code:

        dnsmasq_ismain() # true=0, false=1.
        {
                local cfg="$1"
                local port notinterfaces

                config_get port "$cfg" port “53"
                [ $port = "53" ] || return 1

                config_get notinterfaces "$cfg" notinterface ""
                [ -n $notinterfaces -a list_contains $notinterfaces "loopback" 
] || return 1

                # dnsmasq instance is designated to listen on 127.0.0.1#53.
                return 0
        }

The dnsmasq init script will then handle /tmp/resolv.conf dnsmasq_ismain() is 
true.

When running unbound as resolver with dnsmasq as the dhcp companion (dhcp_link 
is dnsmasq), dnsmasq is configured to listen on another port, e.g. 1053, and 
subsequently the above test will return false and the dnsmasq init start/stop 
routines will not handle /tmp/resolv.conf, which is correct. In this setup, it 
is unbound that listens on 127.0.0.1#53 and it should therefor be regarded the 
designated main resolver.

The current guard (resolvsym) is now determined with:

        if [ ! -x /usr/sbin/dnsmasq -o ! -x /etc/init.d/dnsmasq ] ; then
                resolvsym=1
        else
                /etc/init.d/dnsmasq enabled || resolvsym=1
        fi

This assumes that dnsmasq when enabled, in whatever way, will handle 
/tmp/resolv.conf.
A correct solution would be to handle /tmp/resolv.conf in the unbound init 
script whenever unbound will listen on 127.0.0.1#53. Then /tmp/resolv.conf is 
handled whenever either dnsmasq or unbound listens on 127.0.0.1#53.
Agree ?

The unbound init routines **should** handle /tmp/resolv in this case, but 
currently do not (when dnsmasq is the dhcp_link).
Proposed code:

        unbound_ismain() # true=0, false=1.
        {
                if [ "$UNBOUND_D_DHCP_LINK" = "none" ] \
                && /etc/init.d/dnsmasq enabled && [ -x /usr/sbin/dnsmasq -a -x 
/etc/init.d/dnsmasq ] ; then
                        return 1
                fi

                # unbound is designated to listen on 127.0.0.1#53.
                return 0
        }

Do you agree ?
If so, then I will post two patches, one for dnsmasq and one for unbound.

Ciao,
Paul




> Op 5 jun. 2017, om 05:37 heeft Eric Luehrsen <ericluehr...@hotmail.com> het 
> volgende geschreven:
> 
> Hi Paul -
> 
> The solution I put into Unbound scripts was due to this trickiness. 
> dnsmasq and its little extra functions have become entrenched and 
> necessary in base OpenWrt/LEDE. This includes the oddities in 
> architecture for UCI and LuCI.
> 
> Normally, it is much easier to bind to the wild card address. So one 
> might assume that the primary binds to #53, and any other instance must 
> use a different port. It is also possible to bind per interface. An 
> instance may bind to 127.0.0.1#53, another 192.168.1.1#53, and yet 
> another to 192.168.2.1#53. Depending on subnet management and access 
> limiting controls, this could get complicated.
> 
> Requirements first. In an ecosystem with a choice of DNS servers 
> (multiple instances each and stub vs recursive), what shall be the 
> direct or inferred protocol to denote the primary DNS instance? The 
> scripts all but write themselves with such requirement set and agreed to.
> 
> - Eric
> 
>> (in short: when dnsmasq.noresolv=1 and dnsmasq.resolvfile is unset, then 
>> /tmp/resolv.conf is not handled).
>> 
>> After some analysis the conclusion is that the dnsmasq init script should 
>> handle /tmp/resolv.conf, if and only if, when its main instance is run. The 
>> main instance is designated the one that will listen on 127.0.0.1#53 
>> (naturally there can be only one such instance).
>> 
>> When using unbound with UCI unbound.dhcp_link set to “dnsmasq”, the unbound 
>> init script does **not** handle /tmp/resolv.conf and leaves it to dnsmasq to 
>> do so. In the dhcp_link=dnsmasq setup it is unbound that listens on 
>> 127.0.0.1#53 and so no instance of dnsmasq can possibly be the main 
>> instance. Which makes sense.
>> 
>> An attempt to solve this problem just within the scope of the dnsmasq init 
>> script has proven to be more convoluted than I first thought.
>> 
>> A simple, sane and much more elegant solution would be:
>> a) dnsmasq indeed only handles /tmp/resolv.conf when it runs the main 
>> instance and
>> b) unbound does so when it the main instance, i.e. will listen on 
>> 127.0.0.1#53.
>> 
>> Do you agree ?
>> 
>> If so, could you share your thoughts on how best to do the unbound change ?
>> A few different approaches to the determination of $resolvsym seem possible, 
>> but I’m sure that picking best/easiest/whatever approach is best chosen by 
>> you.
>> 
>> Regards,
>> Paul
>> 
>> 
>>> Op 4 jun. 2017, om 16:26 heeft Paul Oranje <p...@xs4all.nl> het volgende 
>>> geschreven:
>>> 
>>> Good afternoon,
>>> 
>>> Conclusions:
>>> 1) Always initialise $resolvfile (i.e. independently of the state of 
>>> noresolv).
>>> 2) The value of $resolvfile cannot not be used the determine the dnsmasq 
>>> main instance since several instances likely will an equal value.
>>> 3) The main dnsmasq instance is the instance that listens on 127.0.0.1:53 
>>> (of which there can only be one or none).
>>> 4) When no local DNS resolver runs /tmp/resolv.conf should soft-link 
>>> $resolvfile (and that could possible be something else than 
>>> /tmp/resolv.conf.auto).
>>> 
>>> ad 3)
>>> The designated main instance can be determined at runtime by:
>>> - at start of an instance X, when this instance is configured to listen on 
>>> 127.0.0.1#53 and no process listens on that socket, then
>>> - at stop of an instance X, when this instance is configured to listen on 
>>> 127.0.0.1#53 and a process listens on that socket, then
>>> 
>>> For a listening-on test something like “nslookup localhost 127.0.0.1#53 
>>> >/dev/null” would seemingly work (though not on OWRT CC), but that will 
>>> incur a timeout delay (10 sec ?) when no daemon is listening.
>>> Understandably, suggestions for an alternative test that will not incur 
>>> such a timeout are welcome.
>>> 
>>> The above determination of the main instance assume that only one of 
>>> multiple instances is configured to listen on 127.0.0.1#53, otherwise the 
>>> tests may result erroneously in undefined behaviour.
>>> 
>>> ad 4)
>>> A use-case for setting resolvfile to a non-default might be the use of 
>>> different upstream resolvers for different subnets, though that could 
>>> easily be achieved with the server options of UCI dhcp.dnsmasq[x].
>>> 
>>> 
>>> Regards,
>>> Paul
>>> 
>>> 
>>> 
>>>> Op 4 jun. 2017, om 00:09 heeft Hans Dedecker <dedec...@gmail.com> het 
>>>> volgende geschreven:
>>>> 
>>>> On Sat, Jun 3, 2017 at 3:33 PM, Paul Oranje <p...@xs4all.nl> wrote:
>>>>> Thanks, please see a few quick reactions of mine inline ...
>>>>> Paul
>>>>> 
>>>>>> Op 3 jun. 2017, om 14:18 heeft Hans Dedecker <dedec...@gmail.com> het 
>>>>>> volgende geschreven:
>>>>>> 
>>>>>> On Thu, Jun 1, 2017 at 12:00 PM, Paul Oranje <p...@xs4all.nl> wrote:
>>>>>>> Hello Hans,
>>>>>>> 
>>>>>>> A new version of this small patch is worked on -overlooked your 
>>>>>>> previous comment and have lately been busy with other stuff-, but after 
>>>>>>> studying the code a little more I’ve a few questions. The intended 
>>>>>>> patch changes code that was added with commit 
>>>>>>> a35f9bbc43c3da06eed042f80dc09e8c1da681b4 (dnsmasq: Multiple dnsmasq 
>>>>>>> instances support) that was authored by you.
>>>>>>> 
>>>>>>> 
>>>>>>> The routines dnsmasq_start() and dnsmasq_stop() contain a guard on 
>>>>>>> writing and resetting /tmp/resolv.conf:
>>>>>>>      [ "$resolvfile" = "/tmp/resolv.conf.auto” ] &&
>>>>>>> 
>>>>>>> As explained in FS#785, the guard test fails when $noresolv is true and 
>>>>>>> $resolvfile has not been explicitly configured to its default 
>>>>>>> "/tmp/resolv.conf.auto", causing /tmp/resolv.conf to remain a soft link 
>>>>>>> to /tmp/resolv.conf.auto (the WAN its DNS).
>>>>>>> 
>>>>>>> The routine dnsmasq_stop() the guard is commented with
>>>>>>>      #relink /tmp/resolve.conf only for main instance
>>>>>>> 
>>>>>>> This suggests that only for the main (first ?) instance 
>>>>>>> /tmp/resolv.conf would be handled, which makes sense, but the test to 
>>>>>>> accomplish that seems wrong.
>>>>>>> 
>>>>>>> Q1:
>>>>>>> What is the supposed relation between dnsmasq instance and the value of 
>>>>>>> the value/setting of resolvfile ?
>>>>>> The DNS servers learned on the wan interface(s) by netifd are written
>>>>>> in /tmp/resolv.conf.auto. By default a dnsmasq instance uses
>>>>>> /tmp/resolv.conf.auto as resolver file unless configured otherwise.
>>>>> Indeed and whether dnsmasq uses the (whatever) resolvfile is governed by 
>>>>> the noresolv parameter; these two parameters are orthogonal.
>>>>> The init script though skips setting resolvfile when noresolv is true.
>>>> Agree the value of noresolv should have no influence on reading he
>>>> resolvfile parameter; this behavior has been introduced in commit
>>>> 2ac21bd793946a214295b760cd652b4150d3dc07
>>> So I blamed the wrong commit.
>>> 
>>>>>> Using /tmp/rsolv.conf.auto as resolver file triggers logic to rewrite
>>>>>> /tmp/resolv.conf
>>>>> Why would the question whether local DNS resolution is handled by the DNS 
>>>>> available on WAN interface be determined by this specific **value** of 
>>>>> $resolvfile (and irrespective of the actual existence of that file) ?
>>>>> 
>>>>> Also the above question (Q1) is about the relation with the dnsmasq 
>>>>> **instance**.
>>>>> Could you please share your thoughts on the relation behind first 
>>>>> instance and the value of $resolvfile ?
>>>> If resolvfile is set to /tmp/resolv.conf.auto assumption is made this
>>>> is the main dnsmasq instance due to a lack of a better criterium. DHCP
>>>> configs in use before the introduction of multiple dnsmasq instances
>>>> used /tmp/resolv.conf.auto as netifd by default populates the file
>>>> /tmp/resolv.conf.auto. That's the only link I see between the main
>>>> dnsmasq instance and the value of resolvfile
>>>>> 
>>>>>>> A fix I considered is to omit this guard altogether (so different from 
>>>>>>> the patch previously submitted), so that the local DNS service will 
>>>>>>> allways be used for local (router) DNS resolution when dnsmasq is 
>>>>>>> started; at stop of dnsmasq the local resolution would return to use 
>>>>>>> $resolvfile. Obviously doing so in dnsmasq_start() and dnsmasq_stop() 
>>>>>>> routines that start or stop an instance would be the wrong place to do 
>>>>>>> so, since that code will be called for each instance. These routines ar 
>>>>>>> spawned from the start_service() and stop_service() routines that do 
>>>>>>> iterate on the instances.
>>>>>>> 
>>>>>>> Q2:
>>>>>>> Would placement of the /tmp/resolv.conf handling not be better placed 
>>>>>>> in the start_ and stop_service() routines or, be guarded by a better 
>>>>>>> test in the dnsmasq_start() and _stop() routines ? In other words: what 
>>>>>>> would be a correct test ?
>>>>>> we could move rewriting of /tmp/resolv.conf to the start routine; but
>>>>>> this will not be trivial as for every dnsmasq instance DNS_SERVERS and
>>>>>> DOMAIN state will need to be kept
>>>>> The objective is to rewrite /tmp/resolv.conf to use local resolution 
>>>>> whenever a local resolver runs (i.e. dnsmasq, unbound, ... listening on 
>>>>> localhost:53). As multiple instances may be started, triggering on the 
>>>>> first/main one seems to make sense (for lack of a better criterium).
>>>>> So the question is: what do you think is a (practical) guard for that 
>>>>> (and in what routines would those be placed best) ?
>>>> The dnsmasq instance which listens on 127.0.0.1 (and thus does not
>>>> exclude the loopback interface in the notinterface parameter) for dns
>>>> requests can be used as trigger to rewrite /tmp/resolv.conf.auto which
>>>> means the logic needs to be kept in dnsmasq_start
>>>>>>> In the stop routine the file /tmp/resolv.conf is (re)set to a soft link 
>>>>>>> to $resolvfile, which currently because of the test always is 
>>>>>>> "/tmp/resolv.conf.auto”, irrespective whether that file exists or not.
>>>>>>> 
>>>>>>> Q3:
>>>>>>> What would be the desired state of /tmp/resolv.conf after dnsmasq has 
>>>>>>> been stopped ?
>>>>>> In case dnsmasq is stopped /tmp/resolv.conf needs to use only the wan
>>>>>> DNS servers; which are written by netifd in /tmp/resolv.conf.auto; and
>>>>>> not anymore 127.0.0.1.
>>>>> Okay, so that should never be any self user defined resolvfile ?
>>>> AFAIK this has never been the case before
>>>> 
>>>> Hans
>>>>>> Hans
>>>>>>> 
>>>>>>> Bye,
>>>>>>> Paul
>>>>>>> 
>>>>>>> 
>>>>>>> 
>>>>>>>> Op 20 mei 2017, om 20:58 heeft Hans Dedecker <dedec...@gmail.com> het 
>>>>>>>> volgende geschreven:
>>>>>>>> 
>>>>>>>> On Sat, May 20, 2017 at 12:41 AM, Paul Oranje <p...@xs4all.nl> wrote:
>>>>>>>>> When UCI dhcp.dnsmasq.noresolv is true, dnsmasq ignores the (wan) 
>>>>>>>>> resolv.conf
>>>>>>>>> for upstream name resolution and the dnsmasq init script ialso skips 
>>>>>>>>> writing
>>>>>>>>> /tmp/resolv.conf (/etc/resolv.conf soft links that file).
>>>>>>>>> 
>>>>>>>>> Not using the local running DNS service when noresolv is true does 
>>>>>>>>> not make
>>>>>>>>> sence; the semantics of that config value do not imply this. With 
>>>>>>>>> this patch
>>>>>>>>> the init script also writes /tmp/resolv.conf when noresolv is true.
>>>>>>>>> 
>>>>>>>>> fixes FS#785
>>>>>>>>> 
>>>>>>>>> Signed-off-by: Paul Oranje <p...@xs4all.nl>
>>>>>>>>> ---
>>>>>>>>> This patch replaces an earlier patch with subject
>>>>>>>>> dnsmasq: also write /tmp/resolv.conf when UCI dhcp.dnsmasq.noresolv 
>>>>>>>>> is '1'
>>>>>>>>> which is obsoleted because that subject was required to be shorter.
>>>>>>>>> ---
>>>>>>>>> package/network/services/dnsmasq/files/dnsmasq.init | 4 ++--
>>>>>>>>> 1 file changed, 2 insertions(+), 2 deletions(-)
>>>>>>>>> 
>>>>>>>>> diff --git a/package/network/services/dnsmasq/files/dnsmasq.init 
>>>>>>>>> b/package/network/services/dnsmasq/files/dnsmasq.init
>>>>>>>>> index 30fec7a4ee..197aae9de1 100644
>>>>>>>>> --- a/package/network/services/dnsmasq/files/dnsmasq.init
>>>>>>>>> +++ b/package/network/services/dnsmasq/files/dnsmasq.init
>>>>>>>>> @@ -947,7 +947,7 @@ dnsmasq_start()
>>>>>>>>>     echo >> $CONFIGFILE_TMP
>>>>>>>>>     mv -f $CONFIGFILE_TMP $CONFIGFILE
>>>>>>>>> 
>>>>>>>>> -       [ "$resolvfile" = "/tmp/resolv.conf.auto" ] && {
>>>>>>>>> +       [ "$noresolv" = "1" -o "$resolvfile" = 
>>>>>>>>> "/tmp/resolv.conf.auto" ] && {
>>>>>>>>>             rm -f /tmp/resolv.conf
>>>>>>>>>             [ $ADD_LOCAL_DOMAIN -eq 1 ] && [ -n "$DOMAIN" ] && {
>>>>>>>>>                     echo "search $DOMAIN" >> /tmp/resolv.conf
>>>>>>>>> @@ -982,7 +982,7 @@ dnsmasq_stop()
>>>>>>>>>     config_get resolvfile "$cfg" "resolvfile"
>>>>>>>>> 
>>>>>>>>>     #relink /tmp/resolve.conf only for main instance
>>>>>>>>> -       [ "$resolvfile" = "/tmp/resolv.conf.auto" ] && {
>>>>>>>>> +       [ "$noresolv" = "1" -o "$resolvfile" = 
>>>>>>>>> "/tmp/resolv.conf.auto" ] && {
>>>>>>>> As mentioned in the previous code review noresolv value must be read
>>>>>>>> from config (similar to resolvfile) otherwise this will not work
>>>>>>>>>             [ -f /tmp/resolv.conf ] && {
>>>>>>>>>                     rm -f /tmp/resolv.conf
>>>>>>>>>                     ln -s "$resolvfile" /tmp/resolv.conf
>>>>>>>> As mentioned in the previous code review resolvfile can now be empty
>>>>>>>> which will make ln -s produce an error
>>>>>>>> 
>>>>>>>> Hans
>>>>>>>>> --
>>>>>>>>> 
>>>>>>>>> 
>>>>>>>>> _______________________________________________
>>>>>>>>> Lede-dev mailing list
>>>>>>>>> Lede-dev@lists.infradead.org
>>>>>>>>> http://lists.infradead.org/mailman/listinfo/lede-dev
>>>>>>>> _______________________________________________
>>>>>>>> Lede-dev mailing list
>>>>>>>> Lede-dev@lists.infradead.org
>>>>>>>> http://lists.infradead.org/mailman/listinfo/lede-dev
>>>>>> _______________________________________________
>>>>>> Lede-dev mailing list
>>>>>> Lede-dev@lists.infradead.org
>>>>>> http://lists.infradead.org/mailman/listinfo/lede-dev
>>>> _______________________________________________
>>>> Lede-dev mailing list
>>>> Lede-dev@lists.infradead.org
>>>> http://lists.infradead.org/mailman/listinfo/lede-dev
>>> 
>>> _______________________________________________
>>> Lede-dev mailing list
>>> Lede-dev@lists.infradead.org
>>> http://lists.infradead.org/mailman/listinfo/lede-dev
> 
> _______________________________________________
> Lede-dev mailing list
> Lede-dev@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/lede-dev


_______________________________________________
Lede-dev mailing list
Lede-dev@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/lede-dev

Reply via email to