https://ntp.isc.org/bugs/show_bug.cgi?id=578 attachment #241 I did improve the existing Zeroconf support, which only did support Apple's Bonjour, a bit. After applying the patch the following Zeroconf implementations are supported: * Avahi (LGPL) * Howl (A fork of Apple's Bonjour code) * Apple's Bonjour --- ../ntp-dev-org/configure.ac 2006-03-07 09:42:15.000000000 +0100 +++ configure.ac 2006-03-06 14:13:16.000000000 +0100 @@ -329,14 +329,63 @@ AC_HEADER_STDC AC_CHECK_HEADERS(bstring.h) -AC_CHECK_HEADER(dns_sd.h, - [AC_CHECK_LIB(dns_sd, - DNSServiceRegister, - [AC_DEFINE(HAVE_DNSREGISTRATION, 1, - [Use Rendezvous/DNS-SD registration])])]) -case "$ac_cv_lib_dns_sd_DNSServiceRegister" in - yes) LIBS="-ldns_sd $LIBS" ;; + +dnl The below section allows to compile the ntp distribution +dnl with Zeroconf support. At the time there are three Zeroconf +dnl implementations available: Avahi (LGPL), Howl and Bonjour. +dnl The --with-zeroconf knob is used to enable Zeroconf support. + +AC_ARG_WITH(zeroconf, + AC_HELP_STRING([--with-zeroconf], [- Compile with Zeroconf support?]), + [zero=$withval], [zero=no]) + +case "$zero" in + yes) + # mDNS support using Apple's Bonjour + AC_CHECK_HEADER(dns_sd.h, + [AC_CHECK_LIB(dns_sd, + DNSServiceRegister, + [AC_DEFINE(HAVE_DNSREGISTRATION, 1, + [Use DNS-SD registration])])]) + case "$ac_cv_lib_dns_sd_DNSServiceRegister" in + yes) + LIBS="-ldns_sd $LIBS" + AC_DEFINE(HAVE_BONJOUR, 1, [Use Bonjour/DNS-SD registration]) + ;; + esac + # mDNS support using Porchdog's Howl + AC_CHECK_HEADER(howl.h, + [AC_CHECK_LIB(howl, + sw_discovery_publish, + [AC_DEFINE(HAVE_DNSREGISTRATION, 1, + [Use DNS-SD registration])])]) + case "$ac_cv_lib_howl_sw_discovery_publish" in + yes) + LIBS="-lhowl $LIBS" + AC_DEFINE(HAVE_HOWL, 1, [Use Howl/DNS-SD registration]) + ;; + esac + # mDNS support using Avahi + AC_CHECK_HEADER(avahi-client/client.h, + [AC_CHECK_LIB(avahi-client, + avahi_client_new, + [AC_DEFINE(HAVE_DNSREGISTRATION, 1, + [Use DNS-SD registration])])]) + case "$ac_cv_lib_avahi_client_avahi_client_new" in + yes) + PKG_CHECK_MODULES(AVAHI, [ avahi-client >= 0.6 ]) + PKG_CHECK_MODULES(AVAHI_TPOLL, [ avahi-client >= 0.6 ], + [AC_DEFINE(HAVE_AVAHI_THREADED_POLL, 1, [Uses Avahis threaded poll implementation])]) + AC_SUBST(AVAHI_CFLAGS) + AC_SUBST(AVAHI_LIBS) + LIBS="$AVAHI_LIBS $LIBS" + CFLAGS="$AVAHI_CFLAGS $CFLAGS" + AC_DEFINE(HAVE_AVAHI, 1, [Use Avahi/DNS-SD registration]) + ;; + esac + ;; esac + AC_CHECK_HEADERS(errno.h fcntl.h ieeefp.h math.h) # HMS: Lame, but fast. --- ../ntp-dev-org/ntpd/Makefile.am 2006-03-07 09:42:34.000000000 +0100 +++ ntpd/Makefile.am 2006-03-06 14:44:27.000000000 +0100 @@ -31,7 +31,8 @@ # SIM: cmd_args.c ntp_config.c ntp_io.c ntpd.c + ntpsim.c (include/ntpsim.h) # ntp_resolver.c is presently unused... -ntpd_SOURCES = cmd_args.c ntp_config.c ntp_io.c ntpd.c +ntpd_SOURCES = cmd_args.c ntp_config.c ntp_io.c ntpd.c \ + ntpd_zeroconf.h ntpd_zeroconf.c ntpd_avahi.c ntpd_bonjour.c ntpd_howl.c ntpdsim_SOURCES = $(ntpd_SOURCES) ntpsim.c libntpd_a_SOURCES = jupiter.h ntp_control.c \ ntp_crypto.c ntp_filegen.c \ --- ../ntp-dev-org/ntpd/ntpd_avahi.c 2006-03-07 09:54:58.000000000 +0100 +++ ntpd/ntpd_avahi.c 2006-03-07 09:56:47.000000000 +0100 @@ -0,0 +1,420 @@ +/* -*- Mode: C; tab-width: 2; indent-tabs-mode: t; c-basic-offset: 2 -*- */ +/* + * Author: Daniel S. Haischt + * Purpose: Avahi based Zeroconf support + * Docs: http://avahi.org/download/doxygen/ + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifdef HAVE_AVAHI + +#include "ntpd_avahi.h" + +/* + * This function tries to register the NTP DNS + * SRV service type. + */ +static void register_stuff(struct context *ctx) { + char r[128]; + int ret; + + assert(ctx->client); + + if (!ctx->group) { + + if (!(ctx->group = avahi_entry_group_new(ctx->client, + publish_reply, + ctx))) { + msyslog(LOG_ERR, + "Failed to create entry group: %s\n", + avahi_strerror(avahi_client_errno(ctx->client))); + goto fail; + } + + } + + msyslog(LOG_INFO, "Adding service '%s'\n", ctx->name); + + if (avahi_entry_group_is_empty(ctx->group)) { + /* Register our service */ + + if (avahi_entry_group_add_service(ctx->group, + AVAHI_IF_UNSPEC, + AVAHI_PROTO_UNSPEC, + 0, + ctx->name, + NTP_DNS_SERVICE_TYPE, + NULL, + NULL, + ctx->port, + NULL) < 0) { + msyslog(LOG_ERR, + "Failed to add service: %s\n", + avahi_strerror(avahi_client_errno(ctx->client))); + goto fail; + } + + if (avahi_entry_group_commit(ctx->group) < 0) { + msyslog(LOG_ERR, + "Failed to commit entry group: %s\n", + avahi_strerror(avahi_client_errno(ctx->client))); + goto fail; + } + } + + return; + + fail: + avahi_client_free (ctx->client); +#ifndef HAVE_AVAHI_THREADED_POLL + avahi_simple_poll_quit(ctx->simple_poll); +#else + avahi_threaded_poll_quit(ctx->threaded_poll); +#endif +} + +/* Called when publishing of service data completes */ +static void publish_reply(AvahiEntryGroup *g, + AvahiEntryGroupState state, + AVAHI_GCC_UNUSED void *userdata) +{ + struct context *ctx = userdata; + + assert(g == ctx->group); + + switch (state) { + + case AVAHI_ENTRY_GROUP_ESTABLISHED : + /* The entry group has been established successfully */ + break; + + case AVAHI_ENTRY_GROUP_COLLISION: { + char *n; + + /* Pick a new name for our service */ + + n = avahi_alternative_service_name(ctx->name); + assert(n); + + avahi_free(ctx->name); + ctx->name = n; + + register_stuff(ctx); + break; + } + + case AVAHI_ENTRY_GROUP_FAILURE: { + msyslog(LOG_ERR, + "Failed to register service: %s\n", + avahi_strerror(avahi_client_errno(ctx->client))); + avahi_client_free (avahi_entry_group_get_client(g)); +#ifndef HAVE_AVAHI_THREADED_POLL + avahi_simple_poll_quit(ctx->simple_poll); +#else + avahi_threaded_poll_quit(ctx->threaded_poll); +#endif + break; + } + + case AVAHI_ENTRY_GROUP_UNCOMMITED: + case AVAHI_ENTRY_GROUP_REGISTERING: + ; + } +} + +static void client_callback(AvahiClient *client, + AvahiClientState state, + void *userdata) +{ + struct context *ctx = userdata; + + ctx->client = client; + + switch (state) { + + case AVAHI_CLIENT_S_RUNNING: + + /* The server has startup successfully and registered its host + * name on the network, so it's time to create our services */ + if (!ctx->group) + register_stuff(ctx); + break; + + case AVAHI_CLIENT_S_COLLISION: + + if (ctx->group) + avahi_entry_group_reset(ctx->group); + break; + + case AVAHI_CLIENT_FAILURE: { + + if (avahi_client_errno(client) == AVAHI_ERR_DISCONNECTED) { + int error; + + avahi_client_free(ctx->client); + ctx->client = NULL; + ctx->group = NULL; + + /* Reconnect to the server */ + +#ifndef HAVE_AVAHI_THREADED_POLL + if (!(ctx->client = avahi_client_new(avahi_simple_poll_get(ctx->simple_poll), +#else + if (!(ctx->client = avahi_client_new(avahi_threaded_poll_get(ctx->threaded_poll), +#endif + AVAHI_CLIENT_NO_FAIL, + client_callback, + ctx, + &error))) { + + msyslog(LOG_ERR, "Failed to contact server: %s\n", avahi_strerror(error)); + + avahi_client_free (ctx->client); +#ifndef HAVE_AVAHI_THREADED_POLL + avahi_simple_poll_quit(ctx->simple_poll); +#else + avahi_threaded_poll_quit(ctx->threaded_poll); +#endif + } + + } else { + msyslog(LOG_ERR, "Client failure: %s\n", avahi_strerror(avahi_client_errno(client))); + + avahi_client_free (ctx->client); +#ifndef HAVE_AVAHI_THREADED_POLL + avahi_simple_poll_quit(ctx->simple_poll); +#else + avahi_threaded_poll_quit(ctx->threaded_poll); +#endif + } + + break; + } + + case AVAHI_CLIENT_S_REGISTERING: + case AVAHI_CLIENT_CONNECTING: + ; + } +} + +/* + * Tries to setup the Zeroconf thread and any + * neccessary config setting. + */ +void* av_zeroconf_setup(unsigned long port, const char *name) { + struct context *ctx = NULL; + + /* default service name, if there's none in + * the config file. + */ + char service[256] = "NTP Server on "; + int error, ret; + + /* initialize the struct that holds our + * config settings. + */ + ctx = malloc(sizeof(struct context)); + assert(ctx); + ctx->client = NULL; + ctx->group = NULL; +#ifndef HAVE_AVAHI_THREADED_POLL + ctx->simple_poll = NULL; +#else + ctx->threaded_poll = NULL; +#endif + ctx->thread_running = 0; + ctx->port = port; + pthread_mutex_init(&ctx->mutex, NULL); + + /* Prepare service name */ + if (!name) { + msyslog(LOG_INFO, "Assigning default service name.\n"); + gethostname(service+14, sizeof(service)-15); + service[sizeof(service)-1] = 0; + + ctx->name = strdup(service); + } + else { + ctx->name = strdup(name); + } + + assert(ctx->name); + +/* first of all we need to initialize our threading env */ +#ifdef HAVE_AVAHI_THREADED_POLL + if (!(ctx->threaded_poll = avahi_threaded_poll_new())) { + return; + } +#else + avahi_simple_poll_set_func(ctx->simple_poll, poll_func, &ctx->mutex); + + if (!(ctx->simple_poll = avahi_simple_poll_new())) { + msyslog(LOG_ERR, "Failed to create event loop object.\n"); + goto fail; + } +#endif + +/* now we need to acquire a client */ +#ifdef HAVE_AVAHI_THREADED_POLL + if (!(ctx->client = avahi_client_new(avahi_threaded_poll_get(ctx->threaded_poll), + AVAHI_CLIENT_NO_FAIL, + client_callback, + ctx, + &error))) { + msyslog(LOG_ERR, + "Failed to create client object: %s\n", + avahi_strerror(avahi_client_errno(ctx->client))); + goto fail; + } +#else + if (!(ctx->client = avahi_client_new(avahi_simple_poll_get(ctx->simple_poll), + AVAHI_CLIENT_NO_FAIL, + client_callback, + ctx, + &error))) { + msyslog(LOG_ERR, + "Failed to create client object: %s\n", + avahi_strerror(avahi_client_errno(ctx->client))); + goto fail; + } +#endif + + return ctx; + +fail: + + if (ctx) + av_zeroconf_unregister(ctx); + + return NULL; +} + +/* + * This function finally runs the loop impl. + */ +int av_zeroconf_run(void *u) { + struct context *ctx = u; + int ret; + +#ifdef HAVE_AVAHI_THREADED_POLL + /* Finally, start the event loop thread */ + if (avahi_threaded_poll_start(ctx->threaded_poll) < 0) { + msyslog(LOG_ERR, + "Failed to create thread: %s\n", + avahi_strerror(avahi_client_errno(ctx->client))); + goto fail; + } else { + msyslog(LOG_INFO, "Successfully started avahi loop.\n"); + } +#else + /* Create the mDNS event handler */ + if ((ret = pthread_create(&ctx->thread_id, NULL, thread, ctx)) < 0) { + msyslog(LOG_ERR, "Failed to create thread: %s\n", strerror(ret)); + goto fail; + } else { + msyslog(LOG_INFO, "Successfully started avahi loop.\n"); + } +#endif + + ctx->thread_running = 1; + + return 0; + +fail: + + if (ctx) + av_zeroconf_unregister(ctx); + + return -1; +} + +/* + * Used to lock access to the loop. + * Currently unused. + */ +void av_zeroconf_lock(void *u) { + struct context *ctx = u; + + avahi_threaded_poll_lock(ctx->threaded_poll); +} + +/* + * Used to unlock access to the loop. + * Currently unused. + */ +void av_zeroconf_unlock(void *u) { + struct context *ctx = u; + + avahi_threaded_poll_unlock(ctx->threaded_poll); +} + +/* + * Tries to shutdown this loop impl. + * Call this function from outside this thread. + */ +void av_zeroconf_shutdown(void *u) { + struct context *ctx = u; + + /* Call this when the app shuts down */ +#ifdef HAVE_AVAHI_THREADED_POLL + avahi_threaded_poll_stop(ctx->threaded_poll); + avahi_free(ctx->name); + avahi_client_free(ctx->client); + avahi_threaded_poll_free(ctx->threaded_poll); +#else + av_zeroconf_unregister(ctx); +#endif +} + +/* + * Tries to shutdown this loop impl. + * Call this function from inside this thread. + */ +int av_zeroconf_unregister(void *u) { + struct context *ctx = u; + + if (ctx->thread_running) { +#ifndef HAVE_AVAHI_THREADED_POLL + pthread_mutex_lock(&ctx->mutex); + avahi_simple_poll_quit(ctx->simple_poll); + pthread_mutex_unlock(&ctx->mutex); + + pthread_join(ctx->thread_id, NULL); +#else + /* First, block the event loop */ + avahi_threaded_poll_lock(ctx->threaded_poll); + + /* Than, do your stuff */ + avahi_threaded_poll_quit(ctx->threaded_poll); + + /* Finally, unblock the event loop */ + avahi_threaded_poll_unlock(ctx->threaded_poll); +#endif + ctx->thread_running = 0; + } + + avahi_free(ctx->name); + + if (ctx->client) + avahi_client_free(ctx->client); + +#ifndef HAVE_AVAHI_THREADED_POLL + if (ctx->simple_poll) + avahi_simple_poll_free(ctx->simple_poll); + + pthread_mutex_destroy(&ctx->mutex); +#else + if (ctx->threaded_poll) + avahi_threaded_poll_free(ctx->threaded_poll); +#endif + + free(ctx); + + return 0; +} + +#endif /* USE_AVAHI */ --- ../ntp-dev-org/ntpd/ntpd_avahi.h 2006-03-07 09:54:57.000000000 +0100 +++ ntpd/ntpd_avahi.h 2006-03-07 09:57:03.000000000 +0100 @@ -0,0 +1,60 @@ +/* -*- Mode: C; tab-width: 2; indent-tabs-mode: t; c-basic-offset: 2 -*- */ +/* + * Author: Daniel S. Haischt + * Purpose: Avahi based Zeroconf support + * Docs: http://avahi.org/download/doxygen/ + * + */ + +#ifndef _NTPD_AVAHI_H +#define _NTPD_AVAHI_H + +#include +#include +#include + +#include +#include + +#include + +#ifndef HAVE_AVAHI_THREADED_POLL +#include +#else +#include +#endif + +#include +#include + +#include "ntp_syslog.h" /* mysyslog() */ + +#define NTP_DNS_SERVICE_TYPE "_ntp._udp" + +struct context { + int thread_running; + pthread_t thread_id; + pthread_mutex_t mutex; + char *name; +#ifndef HAVE_AVAHI_THREADED_POLL + AvahiSimplePoll *simple_poll; +#else + AvahiThreadedPoll *threaded_poll; +#endif + AvahiClient *client; + AvahiEntryGroup *group; + unsigned long port; +}; + +/* prototype definitions */ +void* av_zeroconf_setup(unsigned long, const char *); +int av_zeroconf_run(void*); +int av_zeroconf_unregister(void*); +void av_zeroconf_shutdown(void*); +void av_zeroconf_lock(void *); +void av_zeroconf_unlock(void *); +static void publish_reply(AvahiEntryGroup *g, + AvahiEntryGroupState state, + void *userdata); + +#endif /* _NTPD_AVAHI_H */ --- ../ntp-dev-org/ntpd/ntpd_bonjour.h 2006-03-07 09:55:02.000000000 +0100 +++ ntpd/ntpd_bonjour.h 2006-03-07 09:58:13.000000000 +0100 @@ -0,0 +1,39 @@ +/* -*- Mode: C; tab-width: 2; indent-tabs-mode: t; c-basic-offset: 2 -*- */ +/* + * Author: Daniel S. Haischt + * Purpose: Bonjour based Zeroconf support + * Docs: http://developer.apple.com/documentation/Networking/Reference/DNSServiceDiscovery_CRef/dns_sd/ + * + */ + +#ifndef _NTPD_BONJOUR_H +#define _NTPD_BONJOUR_H + +#include +#include +#include + +#include /* DNSServiceRegister(), DNSServiceDiscoveryDeallocate() */ + +#include "ntp_syslog.h" /* mysyslog() */ + +#define NTP_DNS_SERVICE_TYPE "_ntp._udp" + +/* prototype definitions */ +void* bo_zeroconf_setup(unsigned long, const char *); +int bo_zeroconf_unregister(void); +int bo_zeroconf_run(void); +#ifdef SYS_WINNT +static void DNSSD_API +#else +static void +#endif +publish_reply(DNSServiceRef, + const DNSServiceFlags, + DNSServiceErrorType, + const char *, + const char *, + const char *, + void *); + +#endif /* _NTPD_BONJOUR_H */ --- ../ntp-dev-org/ntpd/ntpd_bonjour.c 2006-03-07 09:55:01.000000000 +0100 +++ ntpd/ntpd_bonjour.c 2006-03-07 09:57:54.000000000 +0100 @@ -0,0 +1,103 @@ +/* -*- Mode: C; tab-width: 2; indent-tabs-mode: t; c-basic-offset: 2 -*- */ +/* + * Author: Daniel S. Haischt + * Purpose: Bonjour based Zeroconf support + * Docs: http://developer.apple.com/documentation/Networking/Reference/DNSServiceDiscovery_CRef/dns_sd/ + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifdef HAVE_BONJOUR + +#include "ntpd_bonjour.h" + +DNSServiceRef publish_session = NULL; + +static void DNSSD_API +publish_reply (DNSServiceRef sdRef, + const DNSServiceFlags flags, + DNSServiceErrorType errorCode, + const char *name, + const char *regtype, + const char *domain, + void *context) +{ +} + +void* bo_zeroconf_setup(unsigned long port, const char *name) { + DNSServiceErrorType err; + char service[256] = "NTP Server on "; + + /* Prepare service name */ + if (!name) { + out_log(LEVEL_INFO, "Assigning default service name.\n"); + gethostname(service+14, sizeof(service)-15); + service[sizeof(service)-1] = 0; + + name = strdup(service); + } + + assert(name); + assert(port); + + err = DNSServiceRegister (&publish_session, + 0, /* flags */ + 0, /* interface; 0 for all */ + name, /* name */ + FTP_DNS_SERVICE_TYPE, /* type */ + NULL, /* domain */ + NULL, /* hostname */ + htons (port), /* port in network byte order */ + 0, /* text record length */ + NULL, /* text record */ + publish_reply, /* callback */ + NULL); /* context */ + + if (err == kDNSServiceErr_NoError) { + out_log(LEVEL_INFO, "Adding service '%s'\n", name); + } else { + out_log(LEVEL_CRITICAL, "Adding service '%s' failed\n", name); + bo_zeroconf_unregister(); + } +} + +int bo_zeroconf_run(void) { + fd_set set; + int fd; + struct timeval timeout; + + /* Initialize the file descriptor set. */ + FD_ZERO (&set); + FD_SET (fd, &set); + + /* Initialize the timeout data structure. */ + /* TODO: Should the value for sec be configurable? */ + timeout.tv_sec = 10; + timeout.tv_usec = 0; + + if (publish_session != NULL) { + fd = DNSServiceRefSockFD(publish_session); + + if (select(FD_SETSIZE, + &set, NULL, NULL, + &timeout) > 0) { + DNSServiceProcessResult(publish_session); + } + } + + return 0; +} + +int bo_zeroconf_unregister(void) { + if (publish_session != NULL) { + DNSServiceRefDeallocate(publish_session); + publish_session = NULL; + } + + return 0; +} + +#endif /* HAVE_BONJOUR */ --- ../ntp-dev-org/ntpd/ntpd_howl.c 2006-03-07 09:55:05.000000000 +0100 +++ ntpd/ntpd_howl.c 2006-03-07 09:58:52.000000000 +0100 @@ -0,0 +1,86 @@ +/* -*- Mode: C; tab-width: 2; indent-tabs-mode: t; c-basic-offset: 2 -*- */ +/* + * Author: Daniel S. Haischt + * Purpose: Howl based Zeroconf support + * Doc: http://www.porchdogsoft.com/products/howl/docs/ + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifdef HAVE_HOWL + +#include "ntpd_howl.h" + +sw_discovery discovery = NULL; + +static sw_result HOWL_API publish_reply(sw_discovery discovery, + sw_discovery_oid oid, + sw_discovery_publish_status status, + sw_opaque extra) { + static sw_string + status_text[] = + { + "Started", + "Stopped", + "Name Collision", + "Invalid" + }; + + msyslog(LOG_INFO, "publish reply: %s\n", status_text[status]); + return SW_OKAY; +} + +void* ho_zeroconf_setup(unsigned long port, const char *name) { + sw_result result; + sw_discovery_publish_id id; + char service[256] = "NTP Server on "; + + if (sw_discovery_init (&discovery) != SW_OKAY) { + msyslog(LOG_ERR, + "NTPD could not be started. \nTry running mDNSResponder."); + return; + } + + /* Prepare service name */ + if (!name) { + msyslog(LOG_INFO, "Assigning default service name.\n"); + gethostname(service+14, sizeof(service)-15); + service[sizeof(service)-1] = 0; + + name = strdup(service); + } + + assert(name); + + if (!(result = sw_discovery_publish (discovery, + 0, + name, + NTP_DNS_SERVICE_TYPE, + NULL, + NULL, + port, + NULL, + 0, + publish_reply, + NULL, + &id)) != SW_OKAY) { + msyslog(LOG_INFO, "Adding service '%s'\n", name); + } else { + msyslog(LOG_ERR, "Adding service '%s' failed\n", name); + ho_zeroconf_unregister(); + } +} + +void* ho_zeroconf_run(void) { + sw_discovery_run(discovery); +} + +void* ho_zeroconf_unregister(void) { + sw_discovery_stop_run(discovery); + sw_discovery_fina(discovery); +} + +#endif /* USE_HOWL */ --- ../ntp-dev-org/ntpd/ntpd_howl.h 2006-03-07 09:55:05.000000000 +0100 +++ ntpd/ntpd_howl.h 2006-03-07 09:59:06.000000000 +0100 @@ -0,0 +1,31 @@ +/* -*- Mode: C; tab-width: 2; indent-tabs-mode: t; c-basic-offset: 2 -*- */ +/* + * Author: Daniel S. Haischt + * Purpose: Howl based Zeroconf support + * Doc: http://www.porchdogsoft.com/products/howl/docs/ + * + */ + +#ifndef _NTPD_HOWL_H +#define _NTPD_HOWL_H + +#include +#include +#include + +#include + +#include "ntp_syslog.h" /* mysyslog() */ + +#define NTP_DNS_SERVICE_TYPE "_ntp._udp" + +/* prototype definitions */ +void* ho_zeroconf_setup(unsigned long, const char *); +void* ho_zeroconf_unregister(void); +void* ho_zeroconf_run(void); +static sw_result HOWL_API publish_reply(sw_discovery, + sw_discovery_oid, + sw_discovery_publish_status, + sw_opaque); + +#endif /* _NTPD_HOWL_H */ --- ../ntp-dev-org/ntpd/ntpd_zeroconf.h 2006-03-07 09:55:09.000000000 +0100 +++ ntpd/ntpd_zeroconf.h 2006-03-07 09:59:51.000000000 +0100 @@ -0,0 +1,41 @@ +/* -*- Mode: C; tab-width: 2; indent-tabs-mode: t; c-basic-offset: 2 -*- */ +/* + * Author: Daniel S. Haischt + * Purpose: Zeroconf facade, that abstracts access to a + * particular Zeroconf implementation + * Doc: http://www.dns-sd.org/ + * + */ + +#ifndef _NTPD_ZEROCONF_H +#define _NTPD_ZEROCONF_H + +#include /* htons() */ + +#include "ntp_fp.h" +#include "ntp.h" /* NTP_PORT */ +#include "ntp_stdlib.h" /* mysyslog() */ + +# ifdef HAVE_BONJOUR +# include "ntpd_bonjour.h" +# elif defined (HAVE_HOWL) +# include "ntpd_howl.h" +# elif defined (HAVE_AVAHI) +# include "ntpd_avahi.h" +# endif + +/* + * Prototype Definitions + */ + +/* + * registers the ntpd service with a particular Zerconf implemenation. + */ +void zeroconf_register(void); + +/* + * de-registers the ntpd service with a particular Zerconf implemenation. + */ +void zeroconf_deregister(void); + +#endif /* _NTPD_ZEROCONF_H */ --- ../ntp-dev-org/ntpd/ntpd_zeroconf.c 2006-03-07 09:55:08.000000000 +0100 +++ ntpd/ntpd_zeroconf.c 2006-03-07 10:00:04.000000000 +0100 @@ -0,0 +1,56 @@ +/* -*- Mode: C; tab-width: 2; indent-tabs-mode: t; c-basic-offset: 2 -*- */ +/* + * Author: Daniel S. Haischt + * Purpose: Zeroconf facade, that abstracts access to a + * particular Zeroconf implementation + * Doc: http://www.dns-sd.org/ + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "ntpd_zeroconf.h" + +/* + * Global Definitions + */ +#ifdef HAVE_AVAHI +struct context *ctx = NULL; +#endif + +/* + * Functions (actually they are just facades) + */ +void zeroconf_register(void) +{ +#ifdef HAVE_BONJOUR + msyslog(LOG_INFO, "Attemping to register mDNS using Apple's Bonjour\n"); + bo_zeroconf_setup(htons(NTP_PORT), NULL); + bo_zeroconf_run(); +#elif defined (HAVE_HOWL) + msyslog(LOG_INFO, "Attemping to register mDNS using Porchdog's Howl\n"); + ho_zeroconf_setup(NTP_PORT, NULL); + bo_zeroconf_run(); +#elif defined (HAVE_AVAHI) + msyslog(LOG_INFO, "Attemping to register mDNS using Avahi\n"); + ctx = av_zeroconf_setup(htons(NTP_PORT), NULL); + av_zeroconf_run(ctx); +#endif +} + +void zeroconf_deregister(void) +{ +#ifdef HAVE_BONJOUR + msyslog(LOG_INFO, "Attemping to de-register mDNS using Apple's Bonjour\n"); + bo_zeroconf_unregister(); +#elif defined (HAVE_HOWL) + msyslog(LOG_INFO, "Attemping to de-register mDNS using Porchdog's Howl\n"); + ho_zeroconf_unregister(); +#elif defined (HAVE_AVAHI) + msyslog(LOG_INFO, "Attemping to de-register mDNS using Avahi\n"); + if (ctx) + av_zeroconf_shutdown(ctx); +#endif +} --- ../ntp-dev-org/ntpd/ntpd.c 2006-03-07 09:42:37.000000000 +0100 +++ ntpd/ntpd.c 2006-03-06 15:02:02.000000000 +0100 @@ -130,9 +130,12 @@ # define SIGDIE4 SIGTERM #endif /* SYS_WINNT */ +/* + * setup zero configuration networking + * if the system supports it. + */ #ifdef HAVE_DNSREGISTRATION -#include -DNSServiceRef mdns; +# include "ntpd_zeroconf.h" #endif /* @@ -477,10 +480,7 @@ ntp_srandom((int)(now.l_i * now.l_uf)); #ifdef HAVE_DNSREGISTRATION - msyslog(LOG_INFO, "Attemping to register mDNS\n"); - if ( DNSServiceRegister (&mdns, 0, 0, NULL, "_ntp._udp", NULL, NULL, htons(NTP_PORT), 0, NULL, NULL, NULL) != kDNSServiceErr_NoError ) { - msyslog(LOG_ERR, "Unable to register mDNS\n"); - } + zeroconf_register(); #endif #if !defined(VMS) @@ -991,8 +991,7 @@ msyslog(LOG_NOTICE, "ntpd exiting on signal %d", sig); #ifdef HAVE_DNSREGISTRATION - if (mdns != NULL) - DNSServiceRefDeallocate(mdns); + zeroconf_deregister(); #endif switch (sig)