]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
3733. [func] Improve interface scanning support. Interface
authorMark Andrews <marka@isc.org>
Fri, 7 Feb 2014 06:16:37 +0000 (17:16 +1100)
committerMark Andrews <marka@isc.org>
Fri, 7 Feb 2014 06:16:37 +0000 (17:16 +1100)
                        information will be automatically updated if the
                        OS supports routing sockets.  Use
                        "automatic-interface-scan no;" to disable.

                        Add "rndc scan" to trigger a scan. [RT #23027]

20 files changed:
CHANGES
bin/named/bind9.xsl
bin/named/bind9.xsl.h
bin/named/config.c
bin/named/control.c
bin/named/include/named/control.h
bin/named/include/named/server.h
bin/named/interfacemgr.c
bin/named/server.c
bin/named/statschannel.c
bin/rndc/rndc.c
bin/rndc/rndc.docbook
config.h.in
configure
configure.in
doc/arm/Bv9ARM-book.xml
lib/isc/include/isc/socket.h
lib/isc/unix/socket.c
lib/isc/win32/socket.c
lib/isccfg/namedconf.c

diff --git a/CHANGES b/CHANGES
index f71fb1e14d73b88f78b0b7db2771573b2ea318f9..5d28df43e4b9755d5386196ba0f7cae98acec410 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,10 @@
+3733.  [func]          Improve interface scanning support.  Interface
+                       information will be automatically updated if the
+                       OS supports routing sockets.  Use
+                       "automatic-interface-scan no;" to disable.
+
+                       Add "rndc scan" to trigger a scan. [RT #23027]
+
 3732.  [contrib]       Fixed a type mismatch causing the ODBC DLZ
                        driver to dump core on 64-bit systems. [RT #35324]
 
index a84486c5688ed54e6f9aacd32fa383fe11b7adbe..b76d1acf6198fa9c9f03638a6c5c4f26ec20e4d3 100644 (file)
@@ -20,7 +20,7 @@
 <!-- %Id: bind9.xsl,v 1.21 2009/01/27 23:47:54 tbox Exp % -->
 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml" version="1.0">
   <xsl:output method="html" indent="yes" version="4.0"/>
-  <xsl:template match="statistics[@version=&quot;3.4&quot;]">
+  <xsl:template match="statistics[@version=&quot;3.5&quot;]">
     <html>
       <head>
         <xsl:if test="system-property('xsl:vendor')!='Transformiix'">
index 7351382bae1b385d3a6cd7930fe984b38a4f631a..602c78e975f10d1054f840d16c04cc3af5bab2d2 100644 (file)
@@ -25,7 +25,7 @@ static char xslmsg[] =
        "<!-- \045Id: bind9.xsl,v 1.21 2009/01/27 23:47:54 tbox Exp \045 -->\n"
        "<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" xmlns=\"http://www.w3.org/1999/xhtml\" version=\"1.0\">\n"
        " <xsl:output method=\"html\" indent=\"yes\" version=\"4.0\"/>\n"
-       " <xsl:template match=\"statistics[@version=&quot;3.4&quot;]\">\n"
+       " <xsl:template match=\"statistics[@version=&quot;3.5&quot;]\">\n"
        " <html>\n"
        " <head>\n"
        " <xsl:if test=\"system-property('xsl:vendor')!='Transformiix'\">\n"
index 8d4498c7707a2cfc2e33b840cef042f5175297f4..20395c525336b143d96762b2145359927034fcc6 100644 (file)
@@ -52,6 +52,7 @@
 /*% default configuration */
 static char defaultconf[] = "\
 options {\n\
+       automatic-interface-scan yes;\n\
 #      blackhole {none;};\n"
 #ifndef WIN32
 "      coresize default;\n\
index 2ab480b3168d6255f7022dbcd33cf53e7f091be5..d1cf4de4f4becdac83dd0c70e09e10568745953c 100644 (file)
@@ -186,6 +186,9 @@ ns_control_docommand(isccc_sexpr_t *message, isc_buffer_t *text) {
                   command_compare(command, NS_COMMAND_THAW)) {
                result = ns_server_freeze(ns_g_server, ISC_FALSE, command,
                                          text);
+       } else if (command_compare(command, NS_COMMAND_SCAN)) {
+               result = ISC_R_SUCCESS;
+               ns_server_scan_interfaces(ns_g_server);
        } else if (command_compare(command, NS_COMMAND_SYNC)) {
                result = ns_server_sync(ns_g_server, command, text);
        } else if (command_compare(command, NS_COMMAND_RECURSING)) {
index 550099c1d998e3b37ffd70e73cc62a0de6f7e324..b6199d9916c550d703cec058b65190e127fc2ee7 100644 (file)
@@ -59,6 +59,7 @@
 #define NS_COMMAND_NULL                "null"
 #define NS_COMMAND_NOTIFY      "notify"
 #define NS_COMMAND_VALIDATION  "validation"
+#define NS_COMMAND_SCAN        "scan"
 #define NS_COMMAND_SIGN        "sign"
 #define NS_COMMAND_LOADKEYS    "loadkeys"
 #define NS_COMMAND_ADDZONE     "addzone"
index 73c648b139a621c87c71940707830860c00de6ae..3e03dc110f9fafb54c944ca8aacc7bf510fc96dc 100644 (file)
@@ -37,6 +37,7 @@
 #define NS_EVENTCLASS          ISC_EVENTCLASS(0x4E43)
 #define NS_EVENT_RELOAD                (NS_EVENTCLASS + 0)
 #define NS_EVENT_CLIENTCONTROL (NS_EVENTCLASS + 1)
+#define NS_EVENT_IFSCAN                (NS_EVENTCLASS + 2)
 
 /*%
  * Name server state.  Better here than in lots of separate global variables.
@@ -114,6 +115,7 @@ struct ns_server {
        dns_name_t              *session_keyname;
        unsigned int            session_keyalg;
        isc_uint16_t            session_keybits;
+       isc_boolean_t           interface_auto;
 };
 
 #define NS_SERVER_MAGIC                        ISC_MAGIC('S','V','E','R')
@@ -200,6 +202,12 @@ ns_server_reloadwanted(ns_server_t *server);
  * is ignored.
  */
 
+void
+ns_server_scan_interfaces(ns_server_t *server);
+/*%<
+ * Trigger a interface scan.
+ */
+
 void
 ns_server_flushonshutdown(ns_server_t *server, isc_boolean_t flush);
 /*%<
index ff629a9b308938923c8ef0b3671766d03cd53cda..5e9d65d34100e7e30e89662868fc19e3f52c51ed 100644 (file)
 #include <named/client.h>
 #include <named/log.h>
 #include <named/interfacemgr.h>
+#include <named/server.h>
+
+#ifdef HAVE_NET_ROUTE_H
+#include <net/route.h>
+#if defined(RTM_VERSION) && defined(RTM_NEWADDR) && defined(RTM_DELADDR)
+#define USE_ROUTE_SOCKET 1
+#endif
+#endif
 
 #define IFMGR_MAGIC                    ISC_MAGIC('I', 'F', 'M', 'G')
 #define NS_INTERFACEMGR_VALID(t)       ISC_MAGIC_VALID(t, IFMGR_MAGIC)
@@ -55,6 +63,11 @@ struct ns_interfacemgr {
        dns_aclenv_t            aclenv;         /*%< Localhost/localnets ACLs */
        ISC_LIST(ns_interface_t) interfaces;    /*%< List of interfaces. */
        ISC_LIST(isc_sockaddr_t) listenon;
+#ifdef USE_ROUTE_SOCKET
+       isc_task_t *            task;
+       isc_socket_t *          route;
+       unsigned char           buf[2048];
+#endif
 };
 
 static void
@@ -63,6 +76,69 @@ purge_old_interfaces(ns_interfacemgr_t *mgr);
 static void
 clearlistenon(ns_interfacemgr_t *mgr);
 
+#ifdef USE_ROUTE_SOCKET
+static void
+route_event(isc_task_t *task, isc_event_t *event) {
+       isc_socketevent_t *sevent = NULL;
+       ns_interfacemgr_t *mgr = NULL;
+       isc_region_t r;
+       isc_result_t result;
+       struct rt_msghdr *rtm;
+
+       UNUSED(task);
+
+       REQUIRE(event->ev_type == ISC_SOCKEVENT_RECVDONE);
+       mgr = event->ev_arg;
+       sevent = (isc_socketevent_t *)event;
+
+       if (sevent->result != ISC_R_SUCCESS) {
+               if (sevent->result != ISC_R_CANCELED)
+                       isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR,
+                                     "automatic interface scanning "
+                                     "terminated: %s",
+                                     isc_result_totext(sevent->result));
+               ns_interfacemgr_detach(&mgr);
+               isc_event_free(&event);
+               return;
+       }
+
+       rtm = (struct rt_msghdr *)mgr->buf;
+       if (rtm->rtm_version != RTM_VERSION) {
+               isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR,
+                             "automatic interface rescanning disabled: "
+                             "rtm->rtm_version mismatch (%u != %u) "
+                             "recompile required", rtm->rtm_version,
+                             RTM_VERSION);
+               isc_task_detach(&mgr->task);
+               isc_socket_detach(&mgr->route);
+               ns_interfacemgr_detach(&mgr);
+               isc_event_free(&event);
+               return;
+       }
+
+       switch (rtm->rtm_type) {
+       case RTM_NEWADDR:
+       case RTM_DELADDR:
+               if (ns_g_server->interface_auto)
+                       ns_server_scan_interfaces(ns_g_server);
+               break;
+       default:
+               break;
+       }
+
+       /*
+        * Look for next route event.
+        */
+       r.base = mgr->buf;
+       r.length = sizeof(mgr->buf);
+       result = isc_socket_recv(mgr->route, &r, 1, mgr->task,
+                                route_event, mgr);
+       if (result != ISC_R_SUCCESS)
+               ns_interfacemgr_detach(&mgr);
+       isc_event_free(&event);
+}
+#endif
+
 isc_result_t
 ns_interfacemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
                       isc_socketmgr_t *socketmgr,
@@ -112,11 +188,51 @@ ns_interfacemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
        mgr->aclenv.geoip = ns_g_geoip;
 #endif
 
+#ifdef USE_ROUTE_SOCKET
+       mgr->route = NULL;
+       result = isc_socket_create(mgr->socketmgr, PF_ROUTE,
+                                  isc_sockettype_raw, &mgr->route);
+       switch (result) {
+       case ISC_R_NOPERM:
+       case ISC_R_SUCCESS:
+       case ISC_R_NOTIMPLEMENTED:
+           break;
+       default:
+               goto cleanup_aclenv;
+       }
+
+       mgr->task = NULL;
+       if (mgr->route != NULL) {
+               result = isc_task_create(taskmgr, 0, &mgr->task);
+               if (result != ISC_R_SUCCESS)
+                       goto cleanup_route;
+       }
+       mgr->references = (mgr->route != NULL) ? 2 : 1;
+#else
        mgr->references = 1;
+#endif
        mgr->magic = IFMGR_MAGIC;
        *mgrp = mgr;
+
+#ifdef USE_ROUTE_SOCKET
+       if (mgr->route != NULL) {
+               isc_region_t r = { mgr->buf, sizeof(mgr->buf) };
+
+               result = isc_socket_recv(mgr->route, &r, 1, mgr->task,
+                                        route_event, mgr);
+               if (result != ISC_R_SUCCESS)
+                       ns_interfacemgr_detach(&mgr);
+       }
+#endif
        return (ISC_R_SUCCESS);
 
+#ifdef USE_ROUTE_SOCKET
+ cleanup_route:
+       if (mgr->route != NULL)
+               isc_socket_detach(&mgr->route);
+ cleanup_aclenv:
+#endif
+       dns_aclenv_destroy(&mgr->aclenv);
  cleanup_listenon:
        ns_listenlist_detach(&mgr->listenon4);
        ns_listenlist_detach(&mgr->listenon6);
@@ -128,6 +244,13 @@ ns_interfacemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
 static void
 ns_interfacemgr_destroy(ns_interfacemgr_t *mgr) {
        REQUIRE(NS_INTERFACEMGR_VALID(mgr));
+
+#ifdef USE_ROUTE_SOCKET
+       if (mgr->route != NULL)
+               isc_socket_detach(&mgr->route);
+       if (mgr->task != NULL)
+               isc_task_detach(&mgr->task);
+#endif
        dns_aclenv_destroy(&mgr->aclenv);
        ns_listenlist_detach(&mgr->listenon4);
        ns_listenlist_detach(&mgr->listenon6);
@@ -179,6 +302,10 @@ ns_interfacemgr_shutdown(ns_interfacemgr_t *mgr) {
         * consider all interfaces "old".
         */
        mgr->generation++;
+#ifdef USE_ROUTE_SOCKET
+       if (mgr->route != NULL)
+               isc_socket_cancel(mgr->route, mgr->task, ISC_SOCKCANCEL_RECV);
+#endif
        purge_old_interfaces(mgr);
 }
 
index f86aa6733b8c854d9923c8e6190eed471008990a..7eac7d03599fdd2e2ffa4e8495397f46a81ec8cd 100644 (file)
@@ -4741,16 +4741,25 @@ adjust_interfaces(ns_server_t *server, isc_mem_t *mctx) {
 }
 
 /*
- * This event callback is invoked to do periodic network
- * interface scanning.
+ * This event callback is invoked to do periodic network interface
+ * scanning.  It is also called by ns_server_scan_interfaces(),
+ * invoked by "rndc scan"
  */
+
 static void
 interface_timer_tick(isc_task_t *task, isc_event_t *event) {
        isc_result_t result;
        ns_server_t *server = (ns_server_t *) event->ev_arg;
        INSIST(task == server->task);
        UNUSED(task);
+
+       if (event->ev_type == NS_EVENT_IFSCAN)
+               isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+                             NS_LOGMODULE_SERVER, ISC_LOG_DEBUG(1),
+                             "automatic interface rescan");
+
        isc_event_free(&event);
+
        /*
         * XXX should scan interfaces unlocked and get exclusive access
         * only to replace ACLs.
@@ -5676,6 +5685,14 @@ load_configuration(const char *filename, ns_server_t *server,
        }
        server->interface_interval = interface_interval;
 
+       /*
+        * Enable automatic interface scans.
+        */
+       obj = NULL;
+       result = ns_config_get(maps, "automatic-interface-scan", &obj);
+       INSIST(result == ISC_R_SUCCESS);
+       server->interface_auto = cfg_obj_asboolean(obj);
+
        /*
         * Configure the dialup heartbeat timer.
         */
@@ -6902,6 +6919,17 @@ ns_server_reloadwanted(ns_server_t *server) {
        UNLOCK(&server->reload_event_lock);
 }
 
+void
+ns_server_scan_interfaces(ns_server_t *server) {
+       isc_event_t *event;
+
+       event = isc_event_allocate(ns_g_mctx, server, NS_EVENT_IFSCAN,
+                                  interface_timer_tick, server,
+                                  sizeof(isc_event_t));
+       if (event != NULL)
+               isc_task_send(server->task, &event);
+}
+
 static char *
 next_token(char **stringp, const char *delim) {
        char *res;
index 957149492a9e01b301a3b8cf7b48b91b7a20ed20..d2d483bc0133f205c5379d235dd5254b8c78d9c7 100644 (file)
@@ -372,6 +372,7 @@ init_desc(void) {
        SET_SOCKSTATDESC(tcp4open, "TCP/IPv4 sockets opened", "TCP4Open");
        SET_SOCKSTATDESC(tcp6open, "TCP/IPv6 sockets opened", "TCP6Open");
        SET_SOCKSTATDESC(unixopen, "Unix domain sockets opened", "UnixOpen");
+       SET_SOCKSTATDESC(rawopen, "Raw sockets opened", "RawOpen");
        SET_SOCKSTATDESC(udp4openfail, "UDP/IPv4 socket open failures",
                         "UDP4OpenFail");
        SET_SOCKSTATDESC(udp6openfail, "UDP/IPv6 socket open failures",
@@ -382,6 +383,8 @@ init_desc(void) {
                         "TCP6OpenFail");
        SET_SOCKSTATDESC(unixopenfail, "Unix domain socket open failures",
                         "UnixOpenFail");
+       SET_SOCKSTATDESC(rawopenfail, "Raw socket open failures",
+                        "RawOpenFail");
        SET_SOCKSTATDESC(udp4close, "UDP/IPv4 sockets closed", "UDP4Close");
        SET_SOCKSTATDESC(udp6close, "UDP/IPv6 sockets closed", "UDP6Close");
        SET_SOCKSTATDESC(tcp4close, "TCP/IPv4 sockets closed", "TCP4Close");
@@ -389,6 +392,7 @@ init_desc(void) {
        SET_SOCKSTATDESC(unixclose, "Unix domain sockets closed", "UnixClose");
        SET_SOCKSTATDESC(fdwatchclose, "FDwatch sockets closed",
                         "FDWatchClose");
+       SET_SOCKSTATDESC(rawclose, "Raw sockets closed", "RawClose");
        SET_SOCKSTATDESC(udp4bindfail, "UDP/IPv4 socket bind failures",
                         "UDP4BindFail");
        SET_SOCKSTATDESC(udp6bindfail, "UDP/IPv6 socket bind failures",
@@ -455,12 +459,14 @@ init_desc(void) {
                         "UnixRecvErr");
        SET_SOCKSTATDESC(fdwatchrecvfail, "FDwatch recv errors",
                         "FDwatchRecvErr");
+       SET_SOCKSTATDESC(rawrecvfail, "Raw recv errors", "RawRecvErr");
        SET_SOCKSTATDESC(udp4active, "UDP/IPv4 sockets active", "UDP4Active");
        SET_SOCKSTATDESC(udp6active, "UDP/IPv6 sockets active", "UDP6Active");
        SET_SOCKSTATDESC(tcp4active, "TCP/IPv4 sockets active", "TCP4Active");
        SET_SOCKSTATDESC(tcp6active, "TCP/IPv6 sockets active", "TCP6Active");
        SET_SOCKSTATDESC(unixactive, "Unix domain sockets active",
                         "UnixActive");
+       SET_SOCKSTATDESC(rawactive, "Raw sockets active", "RawActive");
        INSIST(i == isc_sockstatscounter_max);
 
        /* Initialize DNSSEC statistics */
@@ -985,7 +991,7 @@ generatexml(ns_server_t *server, isc_uint32_t flags,
                        ISC_XMLCHAR "type=\"text/xsl\" href=\"/bind9.xsl\""));
        TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "statistics"));
        TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "version",
-                                        ISC_XMLCHAR "3.4"));
+                                        ISC_XMLCHAR "3.5"));
 
        /* Set common fields for statistics dump */
        dumparg.type = isc_statsformat_xml;
index 155ac091ba260de71ecd3ba1ca08cf02fb7f7be3..f7cb8d547e8194d9ee29d3a5e9a72d599abb2b32 100644 (file)
@@ -163,6 +163,7 @@ command is one of the following:\n\
                Add zone to given view. Requires new-zone-file option.\n\
   delzone [-clean] zone [class [view]]\n\
                Removes zone from given view. Requires new-zone-file option.\n\
+  scan         Scan available network interfaces for changes.\n\
   signing -list zone [class [view]]\n\
                List the private records showing the state of DNSSEC\n\
                signing in the given zone.\n\
index 6678bc783541844711ad9ee31b28eb85f57bd185..ae9dfe953cdf3d3fdb9774cba56191de43308373 100644 (file)
         </listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><userinput>scan</userinput></term>
+        <listitem>
+          <para>
+             Scan the list of available network interfaces
+             for changes, without performing a full
+             <command>reconfig</command> or waiting for the
+             <command>interface-interval</command> timer.
+          </para>
+        </listitem>
+      </varlistentry>
+
       <varlistentry>
         <term><userinput>sync <optional>-clean</optional> <optional><replaceable>zone</replaceable> <optional><replaceable>class</replaceable> <optional><replaceable>view</replaceable></optional></optional></optional></userinput></term>
         <listitem>
index adbea81437d79ad44067e3a7cafe081994a31497..06db5d4af1cd84985688804dc25c914b3a9428e1 100644 (file)
@@ -1,6 +1,6 @@
 /* config.h.in.  Generated from configure.in by autoheader.  */
 /*
- * Copyright (C) 2004, 2005, 2007, 2008, 2012  Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2008, 2012, 2014  Internet Systems Consortium, Inc. ("ISC")
  * Copyright (C) 1999-2003  Internet Software Consortium.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
@@ -305,6 +305,9 @@ int sigwait(const unsigned int *set, int *sig);
 /* Define to 1 if you have the <net/if6.h> header file. */
 #undef HAVE_NET_IF6_H
 
+/* Define to 1 if you have the <net/route.h> header file. */
+#undef HAVE_NET_ROUTE_H
+
 /* Define if your OpenSSL version supports ECDSA. */
 #undef HAVE_OPENSSL_ECDSA
 
@@ -383,6 +386,9 @@ int sigwait(const unsigned int *set, int *sig);
 /* Define to 1 if you have the <sys/select.h> header file. */
 #undef HAVE_SYS_SELECT_H
 
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#undef HAVE_SYS_SOCKET_H
+
 /* Define to 1 if you have the <sys/sockio.h> header file. */
 #undef HAVE_SYS_SOCKIO_H
 
index d33faf61278a33a8b5745cc5aa9cdd182433a369..5dd7fa6aeb596f547ec16ceb8ef5cce8b6ff8d5f 100755 (executable)
--- a/configure
+++ b/configure
@@ -12544,13 +12544,16 @@ $as_echo "#define STDC_HEADERS 1" >>confdefs.h
 fi
 
 
-for ac_header in fcntl.h regex.h sys/time.h unistd.h sys/mman.h sys/sockio.h sys/select.h sys/param.h sys/sysctl.h net/if6.h
+for ac_header in fcntl.h regex.h sys/time.h unistd.h sys/mman.h sys/sockio.h sys/select.h sys/param.h sys/sysctl.h net/if6.h sys/socket.h net/route.h
 do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
 ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
 #ifdef HAVE_SYS_PARAM_H
 # include <sys/param.h>
 #endif
+#ifdef HAVE_SYS_SOCKET_H
+# include <sys/socket.h>
+#endif
 
 "
 if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
index 3f878cbd17e1d54e5b6bfa06cbf24c5aa8813bff..18653e4e8e89dadc8df3a87f7a9de70425f80340 100644 (file)
@@ -366,11 +366,14 @@ fi
 
 AC_HEADER_STDC
 
-AC_CHECK_HEADERS(fcntl.h regex.h sys/time.h unistd.h sys/mman.h sys/sockio.h sys/select.h sys/param.h sys/sysctl.h net/if6.h,,,
+AC_CHECK_HEADERS(fcntl.h regex.h sys/time.h unistd.h sys/mman.h sys/sockio.h sys/select.h sys/param.h sys/sysctl.h net/if6.h sys/socket.h net/route.h,,,
 [$ac_includes_default
 #ifdef HAVE_SYS_PARAM_H
 # include <sys/param.h>
 #endif
+#ifdef HAVE_SYS_SOCKET_H
+# include <sys/socket.h>
+#endif
 ])
 
 AC_C_CONST
index e9abd94b33dc9e4778f5e5ff527a774c7c3bebb2..21e0ce8a8e95141be6bb84885310fb6f001bbbfc 100644 (file)
@@ -5734,6 +5734,23 @@ options {
 
          <variablelist>
 
+           <varlistentry>
+             <term><command>automatic-interface-scan</command></term>
+             <listitem>
+               <para>
+                 If <userinput>yes</userinput> and supported by the OS,
+                 automatically rescan network interfaces when the interface
+                 addresses are added or removed.  The default is
+                 <userinput>yes</userinput>.
+               </para>
+               <para>
+                 Currently the OS needs to support routing sockets for
+                 <command>automatic-interface-scan</command> to be
+                 supported.
+               </para>
+             </listitem>
+           </varlistentry>
+
            <varlistentry>
              <term><command>allow-new-zones</command></term>
              <listitem>
index 1fef83f35e8da4ae7e12a2ea1877e3cdbc898f3e..37730e807ac51eeadeb713284a21aba057f6c7b5 100644 (file)
@@ -206,7 +206,13 @@ enum {
        isc_sockstatscounter_tcp6active = 55,
        isc_sockstatscounter_unixactive = 56,
 
-       isc_sockstatscounter_max = 57
+       isc_sockstatscounter_rawopen = 57,
+       isc_sockstatscounter_rawopenfail = 58,
+       isc_sockstatscounter_rawclose = 59,
+       isc_sockstatscounter_rawrecvfail = 60,
+       isc_sockstatscounter_rawactive = 61,
+
+       isc_sockstatscounter_max = 62
 };
 
 /***
@@ -280,7 +286,8 @@ typedef enum {
        isc_sockettype_udp = 1,
        isc_sockettype_tcp = 2,
        isc_sockettype_unix = 3,
-       isc_sockettype_fdwatch = 4
+       isc_sockettype_fdwatch = 4,
+       isc_sockettype_raw = 5
 } isc_sockettype_t;
 
 /*@{*/
index 56d16c7611086f9db7818371bcd0123a4accc56c..267f474622b814a52d0dd211afa0d96e8c6fdf4b 100644 (file)
@@ -737,6 +737,19 @@ static const isc_statscounter_t fdwatchstatsindex[] = {
        isc_sockstatscounter_fdwatchrecvfail,
        -1
 };
+static const isc_statscounter_t rawstatsindex[] = {
+       isc_sockstatscounter_rawopen,
+       isc_sockstatscounter_rawopenfail,
+       isc_sockstatscounter_rawclose,
+       -1,
+       -1,
+       -1,
+       -1,
+       -1,
+       -1,
+       isc_sockstatscounter_rawrecvfail,
+       isc_sockstatscounter_rawactive
+};
 
 #if defined(USE_KQUEUE) || defined(USE_EPOLL) || defined(USE_DEVPOLL) || \
     defined(USE_WATCHER_THREAD)
@@ -1884,6 +1897,7 @@ doio_recv(isc__socket_t *sock, isc_socketevent_t *dev) {
                        return (DOIO_EOF);
                break;
        case isc_sockettype_udp:
+       case isc_sockettype_raw:
                break;
        case isc_sockettype_fdwatch:
        default:
@@ -2462,6 +2476,11 @@ opensocket(isc__socketmgr_t *manager, isc__socket_t *sock,
                case isc_sockettype_unix:
                        sock->fd = socket(sock->pf, SOCK_STREAM, 0);
                        break;
+               case isc_sockettype_raw:
+                       sock->fd = socket(sock->pf, SOCK_RAW, 0);
+                       if (sock->pf == PF_ROUTE)
+                               sock->bound = 1;
+                       break;
                case isc_sockettype_fdwatch:
                        /*
                         * We should not be called for isc_sockettype_fdwatch
@@ -2796,6 +2815,9 @@ socket_create(isc_socketmgr_t *manager0, int pf, isc_sockettype_t type,
        case isc_sockettype_unix:
                sock->statsindex = unixstatsindex;
                break;
+       case isc_sockettype_raw:
+               sock->statsindex = rawstatsindex;
+               break;
        default:
                INSIST(0);
        }
index 11903eddf2ac7c3f97293a0d17499e15c7641a40..585c457655ceb81063fac5a8fb549468e2328057 100644 (file)
@@ -1672,6 +1672,11 @@ socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type,
        if (dup_socket != NULL)
                return (ISC_R_NOTIMPLEMENTED);
 
+#ifndef SOCK_RAW
+       if (type == isc_sockettype_raw)
+               return (ISC_R_NOTIMPLEMENTED);
+#endif
+
        result = allocate_socket(manager, type, &sock);
        if (result != ISC_R_SUCCESS)
                return (result);
@@ -1704,6 +1709,13 @@ socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type,
                case isc_sockettype_tcp:
                        sock->fd = socket(pf, SOCK_STREAM, IPPROTO_TCP);
                        break;
+#ifdef SOCK_RAW
+               case isc_sockettype_raw:
+                       sock->fd = socket(pf, SOCK_RAW, 0);
+                       if (pf == PF_ROUTE)
+                               sock->bound = 1;
+                       break;
+#endif
                }
 #if 0
        } else {
index 3a95962bb0d30fa3d694cc32719f4cc7ae1a536c..e18b9fd33cd38ef8a1340c3a66810bc6b6bd709e 100644 (file)
@@ -952,6 +952,7 @@ bindkeys_clauses[] = {
  */
 static cfg_clausedef_t
 options_clauses[] = {
+       { "automatic-interface-scan", &cfg_type_boolean, 0 },
        { "avoid-v4-udp-ports", &cfg_type_bracketed_portlist, 0 },
        { "avoid-v6-udp-ports", &cfg_type_bracketed_portlist, 0 },
        { "bindkeys-file", &cfg_type_qstring, 0 },