Support SetDomainServers DBus method for dnsmasq so we can specify IPv6 linklocal...
authorRoy Marples <roy@marples.name>
Sun, 2 Dec 2012 00:06:28 +0000 (00:06 +0000)
committerRoy Marples <roy@marples.name>
Sun, 2 Dec 2012 00:06:28 +0000 (00:06 +0000)
dnsmasq.in

index eb75159e8c772573c90c68aec24abe5d7c41ff7c..44f73d1495613d3d117d0612c8a22dd09e931dac 100644 (file)
@@ -46,6 +46,7 @@ newresolv="$newconf"
 # so we need to validate a few things first.
 # Check for DBus support in the binary
 dbus=false
+dbus_ex=false
 : ${dbus_pid:=/var/run/dbus/dbus.pid}
 [ -s "$dbus_pid" ] || dbus_pid=/var/run/dbus.pid
 [ -s "$dbus_pid" ] || dbus_pid=/var/run/dbus/pid
@@ -58,6 +59,10 @@ if [ -s "$dbus_pid" -a -s "$dnsmasq_pid" ]; then
                        kill -0 $(cat "$dnsmasq_pid") 2>/dev/null
                then
                        dbus=true
+                       if dbus-send --print-reply --system --dest=uk.org.thekelleys.dnsmasq /uk/org/thekelleys/dnsmasq org.freedesktop.DBus.Introspectable.Introspect | grep -q '<method name="SetDomainServers">'
+                       then
+                               dbus_ex=true
+                       fi
                fi
        fi
 fi
@@ -67,66 +72,77 @@ for n in $NAMESERVERS; do
 done
 
 dbusdest=
+dbusdest_ex=
 conf=
 for d in $DOMAINS; do
        dn="${d%%:*}"
        ns="${d#*:}"
        while [ -n "$ns" ]; do
                n="${ns%%,*}"
-               case "$n" in
-               *.*.*.*)
-                       SIFS=${IFS-y} OIFS=$IFS
-                       IFS=.
-                       set -- $n
-                       num="0x$(printf %02x $1 $2 $3 $4)"
-                       if [ "$SIFS" = y ]; then
-                               unset IFS
-                       else
-                               IFS=$OIFS
-                       fi
-                       dbusdest="$dbusdest uint32:$(printf %u $num)"
-                       dbusdest="$dbusdest string:$dn"
-                       ;;
-               *:*)
-                       SIFS=${IFS-y} OIFS=$IFS bytes= front= back=
-                       empty=false i=0
-                       IFS=:
-                       set -- $n
-                       while [ -n "$1" -o -n "$2" ]; do
-                               addr="$1"
-                               shift
-                               if [ -z "$addr" ]; then
-                                       empty=true
-                                       continue
+               if $dbus && ! $dbus_ex; then
+                       case "$n" in
+                       *.*.*.*)
+                               SIFS=${IFS-y} OIFS=$IFS
+                               IFS=.
+                               set -- $n
+                               num="0x$(printf %02x $1 $2 $3 $4)"
+                               if [ "$SIFS" = y ]; then
+                                       unset IFS
+                               else
+                                       IFS=$OIFS
                                fi
+                               dbusdest="$dbusdest uint32:$(printf %u $num)"
+                               dbusdest="$dbusdest string:$dn"
+                               ;;
+                       *:*%*)
+                               # This version of dnsmasq won't accept
+                               # scoped IPv6 addresses
+                               dbus=false
+                               ;;
+                       *:*)
+                               SIFS=${IFS-y} OIFS=$IFS bytes= front= back=
+                               empty=false i=0
+                               IFS=:
+                               set -- $n
+                               while [ -n "$1" -o -n "$2" ]; do
+                                       addr="$1"
+                                       shift
+                                       if [ -z "$addr" ]; then
+                                               empty=true
+                                               continue
+                                       fi
+                                       i=$(($i + 1))
+                                       while [ ${#addr} -lt 4 ]; do
+                                               addr="0${addr}"
+                                       done
+                                       byte1="$(printf %d 0x${addr%??})"
+                                       byte2="$(printf %d 0x${addr#??})"
+                                       if $empty; then
+                                               back="$back byte:$byte1 byte:$byte2"
+                                       else
+                                               front="$front byte:$byte1 byte:$byte2"
+                                       fi
+                               done
+                               while [ $i != 8 ]; do
                                i=$(($i + 1))
-                               while [ ${#addr} -lt 4 ]; do
-                                       addr="0${addr}"
+                                       front="$front byte:0 byte:0"
                                done
-                               byte1="$(printf %d 0x${addr%??})"
-                               byte2="$(printf %d 0x${addr#??})"
-                               if $empty; then
-                                       back="$back byte:$byte1 byte:$byte2"
+                               front="${front}$back"
+                               if [ "$SIFS" = y ]; then
+                                       unset IFS
                                else
-                                       front="$front byte:$byte1 byte:$byte2"
+                                       IFS=$OIFS
                                fi
-                       done
-                       while [ $i != 8 ]; do
-                               i=$(($i + 1))
-                               front="$front byte:0 byte:0"
-                       done
-                       front="${front}$back"
-                       if [ "$SIFS" = y ]; then
-                               unset IFS
-                       else
-                               IFS=$OIFS
-                       fi
-                       dbusdest="${dbusdest}$front string:$dn"
-                       ;;
-               *)
-                       dbus=false
-                       ;;
-               esac
+                               dbusdest="${dbusdest}$front string:$dn"
+                               ;;
+                       *)
+                               if ! $dbus_ex; then
+                                       dbus=false
+                               fi
+                               ;;
+                       esac
+               fi
+               dbusdest_ex="$dbusdest_ex${dbusdest_ex:+,}/$dn/$n"
                conf="${conf}server=/$dn/$n$NL"
                [ "$ns" = "${ns#*,}" ] && break
                ns="${ns#*,}"
@@ -174,7 +190,16 @@ fi
 if $dbus; then
        $changed || kill -HUP $(cat "$dnsmasq_pid")
        # Send even if empty so old servers are cleared
+       if $dbus_ex; then
+               method=SetDomainServers
+               if [ -n "$dbusdest_ex" ]; then
+                       dbusdest_ex="array:string:$dbusdest_ex"
+               fi
+               dbusdest="$dbusdest_ex"
+       else
+               method=SetServers
+       fi
        dbus-send --system --dest=uk.org.thekelleys.dnsmasq \
-               /uk/org/thekelleys/dnsmasq uk.org.thekelleys.SetServers \
+               /uk/org/thekelleys/dnsmasq uk.org.thekelleys.$method \
                $dbusdest
 fi