diff -up bind-9.8.0rc1/bin/named/include/named/globals.h.libnm bind-9.8.0rc1/bin/named/include/named/globals.h --- bind-9.8.0rc1/bin/named/include/named/globals.h.libnm 2011-02-22 16:08:19.538575568 +0100 +++ bind-9.8.0rc1/bin/named/include/named/globals.h 2011-02-22 16:08:37.779101415 +0100 @@ -151,6 +151,7 @@ EXTERN isc_boolean_t ns_g_memstatistics EXTERN isc_boolean_t ns_g_clienttest INIT(ISC_FALSE); EXTERN isc_boolean_t ns_g_nosoa INIT(ISC_FALSE); EXTERN isc_boolean_t ns_g_noaa INIT(ISC_FALSE); +EXTERN isc_boolean_t ns_g_libnm INIT(ISC_FALSE); #undef EXTERN #undef INIT diff -up bind-9.8.0rc1/bin/named/include/named/server.h.libnm bind-9.8.0rc1/bin/named/include/named/server.h --- bind-9.8.0rc1/bin/named/include/named/server.h.libnm 2011-02-22 16:09:03.039788866 +0100 +++ bind-9.8.0rc1/bin/named/include/named/server.h 2011-02-22 16:10:40.552722679 +0100 @@ -34,9 +34,12 @@ #include +#include + #define NS_EVENTCLASS ISC_EVENTCLASS(0x4E43) #define NS_EVENT_RELOAD (NS_EVENTCLASS + 0) #define NS_EVENT_CLIENTCONTROL (NS_EVENTCLASS + 1) +#define NS_EVENT_NSEVENT (NS_EVENTCLASS + 2) /*% * Name server state. Better here than in lots of separate global variables. @@ -114,6 +117,8 @@ struct ns_server { dns_name_t *session_keyname; unsigned int session_keyalg; isc_uint16_t session_keybits; + + nmserver_control_t *nmcontrol; }; #define NS_SERVER_MAGIC ISC_MAGIC('S','V','E','R') diff -up bind-9.8.0rc1/bin/named/main.c.libnm bind-9.8.0rc1/bin/named/main.c --- bind-9.8.0rc1/bin/named/main.c.libnm 2011-02-22 16:06:25.835268500 +0100 +++ bind-9.8.0rc1/bin/named/main.c 2011-02-22 16:06:25.845268792 +0100 @@ -416,7 +416,7 @@ parse_command_line(int argc, char *argv[ isc_commandline_errprint = ISC_FALSE; while ((ch = isc_commandline_parse(argc, argv, - "46c:C:d:E:fFgi:lm:n:N:p:P:" + "46c:C:d:DE:fFgi:lm:n:N:p:P:" "sS:t:T:u:vVx:")) != -1) { switch (ch) { case '4': @@ -448,6 +448,9 @@ parse_command_line(int argc, char *argv[ ns_main_earlyfatal("cannot specify -c and -C"); lwresd_g_useresolvconf = ISC_TRUE; break; + case 'D': + ns_g_libnm = ISC_TRUE; + break; case 'd': ns_g_debuglevel = parse_int(isc_commandline_argument, "debug level"); diff -up bind-9.8.0rc1/bin/named/Makefile.in.libnm bind-9.8.0rc1/bin/named/Makefile.in --- bind-9.8.0rc1/bin/named/Makefile.in.libnm 2011-02-22 16:06:25.835268500 +0100 +++ bind-9.8.0rc1/bin/named/Makefile.in 2011-02-22 16:06:25.945271687 +0100 @@ -45,7 +45,7 @@ CINCLUDES = -I${srcdir}/include -I${srcd ${ISCCFG_INCLUDES} ${ISCCC_INCLUDES} ${ISC_INCLUDES} \ ${DLZDRIVER_INCLUDES} ${DBDRIVER_INCLUDES} @DST_OPENSSL_INC@ -CDEFINES = @USE_DLZ@ @USE_PKCS11@ @USE_OPENSSL@ +CDEFINES = @USE_DLZ@ @USE_PKCS11@ @USE_OPENSSL@ @LIBNMSERVER_CPPFLAGS@ CWARNINGS = @@ -69,11 +69,11 @@ DEPLIBS = ${LWRESDEPLIBS} ${DNSDEPLIBS} LIBS = ${LWRESLIBS} ${DNSLIBS} ${BIND9LIBS} \ ${ISCCFGLIBS} ${ISCCCLIBS} ${ISCLIBS} \ - ${DLZDRIVER_LIBS} ${DBDRIVER_LIBS} @LIBS@ + ${DLZDRIVER_LIBS} ${DBDRIVER_LIBS} @LIBNMSERVER_LIBS@ @LIBS@ NOSYMLIBS = ${LWRESLIBS} ${DNSLIBS} ${BIND9LIBS} \ ${ISCCFGLIBS} ${ISCCCLIBS} ${ISCNOSYMLIBS} \ - ${DLZDRIVER_LIBS} ${DBDRIVER_LIBS} @LIBS@ + ${DLZDRIVER_LIBS} ${DBDRIVER_LIBS} @LIBNMSERVER_LIBS@ @LIBS@ SUBDIRS = unix diff -up bind-9.8.0rc1/bin/named/server.c.libnm bind-9.8.0rc1/bin/named/server.c --- bind-9.8.0rc1/bin/named/server.c.libnm 2011-02-22 16:06:25.845268792 +0100 +++ bind-9.8.0rc1/bin/named/server.c 2011-02-22 16:06:26.065275159 +0100 @@ -111,6 +111,8 @@ #include #endif +#include + #ifndef PATH_MAX #define PATH_MAX 1024 #endif @@ -216,6 +218,12 @@ struct cfg_context { cfg_aclconfctx_t actx; }; +typedef struct nmserver_nsevent { + ISC_EVENT_COMMON(struct nmserver_nsevent); + ns_server_t *server; + isc_sockaddrlist_t *fwds; +} nmserver_nsevent_t; + /* * These zones should not leak onto the Internet. */ @@ -2366,9 +2372,15 @@ configure_view(dns_view_t *view, cfg_par forwarders = NULL; (void)ns_config_get(maps, "forward", &forwardtype); (void)ns_config_get(maps, "forwarders", &forwarders); - if (forwarders != NULL) + if (forwarders != NULL) { + if (ns_g_libnm) + fatal("Cannot use \"forwarders\" directive and " + "\"-D\" parameter simultaneously", + ISC_R_FAILURE); + CHECK(configure_forward(config, view, dns_rootname, forwarders, forwardtype)); + } /* * Dual Stack Servers. @@ -5161,6 +5173,126 @@ load_new_zones(ns_server_t *server, isc_ } static void +nmserver_errcallback(nmserver_result_t result) { + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, + ISC_LOG_ERROR, "got error from libnmserver: %d", result); +} + +static void +update_forwarders(isc_task_t *task, isc_event_t *event) { + isc_result_t result; + dns_view_t *view; + isc_sockaddr_t *sa; + nmserver_nsevent_t *nsevent = (nmserver_nsevent_t *)event; + ns_server_t *server = nsevent->server; + isc_sockaddrlist_t *salist = nsevent->fwds; + + INSIST(task = server->task); + + result = isc_task_beginexclusive(server->task); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + + /* Update forwarders in all views */ + for (view = ISC_LIST_HEAD(server->viewlist); + view != NULL; + view = ISC_LIST_NEXT(view, link)) { + (void) dns_fwdtable_delete(view->fwdtable, dns_rootname); + + CHECKFATAL(dns_fwdtable_add(view->fwdtable, dns_rootname, + salist, dns_fwdpolicy_only), + "adding forwarders from libnmserver"); + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, + ISC_LOG_ERROR, "forwarder added"); + } + + isc_task_endexclusive(server->task); + + while (!ISC_LIST_EMPTY(*salist)) { + sa = ISC_LIST_HEAD(*salist); + ISC_LIST_UNLINK(*salist, sa, link); + isc_mem_put(server->mctx, sa, sizeof(*sa)); + } + isc_mem_put(server->mctx, salist, sizeof(*salist)); + isc_mem_put(server->mctx, nsevent, sizeof(*nsevent)); +} + +static void +nmserver_nscallback(in_addr_t *servers, void *data) { + in_addr_t *ptr; + isc_sockaddr_t *sa; + isc_sockaddrlist_t *salist; + char str[ISC_SOCKADDR_FORMATSIZE]; + nmserver_nsevent_t *nsevent; + isc_result_t result = ISC_R_SUCCESS; + ns_server_t *server = (ns_server_t *)data; + + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, + ISC_LOG_ERROR, "got servers"); + + salist = isc_mem_get(server->mctx, sizeof(*salist)); + if (salist == NULL) { + result = ISC_R_NOMEMORY; + goto cleanup; + } + ISC_LIST_INIT(*salist); + + for (ptr = servers; *ptr != 0; ptr++) { + sa = isc_mem_get(server->mctx, sizeof(*sa)); + if (sa == NULL) { + result = ISC_R_NOMEMORY; + goto cleanup; + } +#if 0 + in_addr_t asd; + asd = htonl(10L << 24 | 34L << 16 | 255L << 8 | 7); + isc_sockaddr_fromin(sa, (struct in_addr *) &asd, 53); +#endif + isc_sockaddr_fromin(sa, (struct in_addr *)ptr, 53); + isc_sockaddr_format(sa, str, ISC_SOCKADDR_FORMATSIZE); + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, + ISC_LOG_ERROR, "got forwarder %s", str); + + ISC_LINK_INIT(sa, link); + ISC_LIST_APPEND(*salist, sa, link); + } + + nsevent = (nmserver_nsevent_t *) + isc_event_allocate(ns_g_mctx, server, + NS_EVENT_NSEVENT, + update_forwarders, + NULL, + sizeof(*nsevent)); + if (nsevent == NULL) { + result = ISC_R_NOMEMORY; + goto cleanup; + } + + nsevent->server = server; + nsevent->fwds = salist; + isc_task_send(server->task, ISC_EVENT_PTR(&nsevent)); + result = ISC_R_SUCCESS; + +cleanup: + + if (result == ISC_R_SUCCESS) + return; + + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_SERVER, ISC_LOG_ERROR, + "Failed to obtain forwarders from libnmserver " + "library: %s", isc_result_totext(result)); + + if (salist != NULL) { + while (!ISC_LIST_EMPTY(*salist)) { + sa = ISC_LIST_HEAD(*salist); + ISC_LIST_UNLINK(*salist, sa, link); + isc_mem_put(server->mctx, sa, sizeof(*sa)); + } + isc_mem_put(server->mctx, salist, sizeof(*salist)); + } +} + +static void run_server(isc_task_t *task, isc_event_t *event) { isc_result_t result; ns_server_t *server = (ns_server_t *)event->ev_arg; @@ -5212,6 +5344,25 @@ run_server(isc_task_t *task, isc_event_t CHECKFATAL(load_zones(server, ISC_FALSE), "loading zones"); + ns_g_server->nmcontrol = NULL; + if (ns_g_libnm) { + nmserver_control_t *control = NULL; + nmserver_result_t result; + + result = nmserver_control_create(&control, server); + if (result != NMSERVER_R_OK) + fatal("loading libnmserver library", ISC_R_FAILURE); + + nmserver_nscallback_register(control, &nmserver_nscallback); + nmserver_errcallback_register(control, &nmserver_errcallback); + + result = nmserver_threaded_run(control); + if (result != NMSERVER_R_OK) + fatal("starting libnmserver library", ISC_R_FAILURE); + + ns_g_server->nmcontrol = control; + } + ns_os_started(); isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_NOTICE, "running"); @@ -5251,6 +5402,9 @@ shutdown_server(isc_task_t *task, isc_ev cfg_obj_destroy(ns_g_parser, &ns_g_config); cfg_parser_destroy(&ns_g_parser); + if (ns_g_server->nmcontrol) + nmserver_control_destroy(&ns_g_server->nmcontrol); + for (view = ISC_LIST_HEAD(server->viewlist); view != NULL; view = view_next) { diff -up bind-9.8.0rc1/configure.in.libnm bind-9.8.0rc1/configure.in --- bind-9.8.0rc1/configure.in.libnm 2011-02-03 06:50:05.000000000 +0100 +++ bind-9.8.0rc1/configure.in 2011-02-22 16:06:26.025274000 +0100 @@ -3251,6 +3258,30 @@ for e in $DNS_CRYPTO_LIBS ; do done DNS_CRYPTO_LIBS="$NEWFLAGS" +LIBNMSERVER_CPPFLAGS= +LIBNMSERVER_LIBS= +AC_MSG_CHECKING(for libnmserver support) +AC_ARG_WITH(libnmserver, + [ --with-libnmserver, libnmserver support requires pkg-config], + use_libnmserver="$withval", use_libnmserver="no") +case "$use_libnmserver" in + no) + AC_MSG_RESULT(no) + ;; + yes) + AC_MSG_RESULT(yes) + AC_PATH_PROG(PKGCONFIG, pkg-config) + LIBNMSERVER_CPPFLAGS=`$PKGCONFIG libnmserver --cflags` + LIBNMSERVER_LIBS=`$PKGCONFIG libnmserver --libs` + ;; + *) + AC_MSG_ERROR(Specify yes or no) + ;; +esac + +AC_SUBST(LIBNMSERVER_CPPFLAGS) +AC_SUBST(LIBNMSERVER_LIBS) + AC_SUBST(BUILD_CC) AC_SUBST(BUILD_CFLAGS) AC_SUBST(BUILD_CPPFLAGS)