From patchwork Sun Nov 22 15:56:58 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Mathieu Othacehe X-Patchwork-Id: 25287 Return-Path: X-Original-To: patchwork@mira.cbaines.net Delivered-To: patchwork@mira.cbaines.net Received: by mira.cbaines.net (Postfix, from userid 113) id 945DE27BBF8; Sun, 22 Nov 2020 15:58:21 +0000 (GMT) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mira.cbaines.net X-Spam-Level: X-Spam-Status: No, score=-2.9 required=5.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_MSPIKE_H4,RCVD_IN_MSPIKE_WL,SPF_HELO_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mira.cbaines.net (Postfix) with ESMTPS id B798727BBF7 for ; Sun, 22 Nov 2020 15:58:20 +0000 (GMT) Received: from localhost ([::1]:49484 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kgrkp-0001vT-W2 for patchwork@mira.cbaines.net; Sun, 22 Nov 2020 10:58:20 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:58626) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kgrka-0001kJ-NB for guix-patches@gnu.org; Sun, 22 Nov 2020 10:58:04 -0500 Received: from debbugs.gnu.org ([209.51.188.43]:36576) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kgrkZ-0002IK-MC for guix-patches@gnu.org; Sun, 22 Nov 2020 10:58:03 -0500 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1kgrkZ-00064V-Lo for guix-patches@gnu.org; Sun, 22 Nov 2020 10:58:03 -0500 X-Loop: help-debbugs@gnu.org Subject: [bug#44802] [PATCH 1/2] Add Avahi support. Resent-From: Mathieu Othacehe Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Sun, 22 Nov 2020 15:58:03 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: report 44802 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 44802@debbugs.gnu.org Cc: Mathieu Othacehe X-Debbugs-Original-To: guix-patches@gnu.org Received: via spool by submit@debbugs.gnu.org id=B.160606065323271 (code B ref -1); Sun, 22 Nov 2020 15:58:03 +0000 Received: (at submit) by debbugs.gnu.org; 22 Nov 2020 15:57:33 +0000 Received: from localhost ([127.0.0.1]:48118 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1kgrjy-000631-Iq for submit@debbugs.gnu.org; Sun, 22 Nov 2020 10:57:33 -0500 Received: from lists.gnu.org ([209.51.188.17]:48480) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1kgrjs-00062T-M5 for submit@debbugs.gnu.org; Sun, 22 Nov 2020 10:57:24 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:58580) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kgrjs-0001h3-DA for guix-patches@gnu.org; Sun, 22 Nov 2020 10:57:20 -0500 Received: from fencepost.gnu.org ([2001:470:142:3::e]:46123) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kgrjs-000232-6P for guix-patches@gnu.org; Sun, 22 Nov 2020 10:57:20 -0500 Received: from [2a01:e0a:19b:d9a0:f0c7:1dab:64ad:1a4a] (port=49596 helo=localhost.localdomain) by fencepost.gnu.org with esmtpsa (TLS1.2:DHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.82) (envelope-from ) id 1kgrjp-0006Iv-8a; Sun, 22 Nov 2020 10:57:17 -0500 From: Mathieu Othacehe Date: Sun, 22 Nov 2020 16:56:58 +0100 Message-Id: <20201122155659.67235-2-othacehe@gnu.org> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20201122155659.67235-1-othacehe@gnu.org> References: <20201122155659.67235-1-othacehe@gnu.org> MIME-Version: 1.0 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: guix-patches@gnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org Sender: "Guix-patches" X-getmail-retrieved-from-mailbox: Patches * guix/avahi.scm: New file. * Makefile.am (MODULES): Add it. * configure.ac: Add Guile-Avahi dependency. * doc/guix.texi (Requirements): Document it. * gnu/packages/package-management.scm (guix)[native-inputs]: Add "guile-avahi", [propagated-inputs]: ditto. * guix/self.scm (specification->package): Add guile-avahi. (compiled-guix): Ditto. --- Makefile.am | 1 + configure.ac | 6 ++ doc/guix.texi | 1 + gnu/packages/package-management.scm | 2 + guix/avahi.scm | 162 ++++++++++++++++++++++++++++ guix/self.scm | 9 +- 6 files changed, 179 insertions(+), 2 deletions(-) create mode 100644 guix/avahi.scm diff --git a/Makefile.am b/Makefile.am index ea43650a14..7c716804c8 100644 --- a/Makefile.am +++ b/Makefile.am @@ -73,6 +73,7 @@ include gnu/local.mk include po/doc/local.mk MODULES = \ + guix/avahi.scm \ guix/base16.scm \ guix/base32.scm \ guix/base64.scm \ diff --git a/configure.ac b/configure.ac index 6e718afdd1..307e8b361f 100644 --- a/configure.ac +++ b/configure.ac @@ -161,6 +161,12 @@ if test "x$have_guile_lzlib" != "xyes"; then AC_MSG_ERROR([Guile-lzlib is missing; please install it.]) fi +dnl Check for Guile-Avahi. +GUILE_MODULE_AVAILABLE([have_guile_avahi], [(avahi)]) +if test "x$have_guile_avahi" != "xyes"; then + AC_MSG_ERROR([Guile-Avahi is missing; please install it.]) +fi + dnl Guile-newt is used by the graphical installer. GUILE_MODULE_AVAILABLE([have_guile_newt], [(newt)]) diff --git a/doc/guix.texi b/doc/guix.texi index b7f1bc1f00..e2361c25e3 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -827,6 +827,7 @@ Guile,, gnutls-guile, GnuTLS-Guile}); or later; @item @uref{https://notabug.org/guile-zlib/guile-zlib, Guile-zlib}; @item @uref{https://notabug.org/guile-lzlib/guile-lzlib, Guile-lzlib}; +@item @uref{https://www.nongnu.org/guile-avahi/, Guile-Avahi}; @item @c FIXME: Specify a version number once a release has been made. @uref{https://gitlab.com/guile-git/guile-git, Guile-Git}, version 0.3.0 diff --git a/gnu/packages/package-management.scm b/gnu/packages/package-management.scm index 7ceb7737d8..bc393a8417 100644 --- a/gnu/packages/package-management.scm +++ b/gnu/packages/package-management.scm @@ -343,6 +343,7 @@ $(prefix)/etc/init.d\n"))) ;; cross-compilation. ("guile" ,guile-3.0-latest) ;for faster builds ("gnutls" ,gnutls) + ("guile-avahi" ,guile-avahi) ("guile-gcrypt" ,guile-gcrypt) ("guile-json" ,guile-json-4) ("guile-sqlite3" ,guile-sqlite3) @@ -393,6 +394,7 @@ $(prefix)/etc/init.d\n"))) ("glibc-utf8-locales" ,glibc-utf8-locales))) (propagated-inputs `(("gnutls" ,(if (%current-target-system) gnutls-3.6.14 gnutls)) + ("guile-avahi" ,guile-avahi) ("guile-gcrypt" ,guile-gcrypt) ("guile-json" ,guile-json-4) ("guile-sqlite3" ,guile-sqlite3) diff --git a/guix/avahi.scm b/guix/avahi.scm new file mode 100644 index 0000000000..fa4a258066 --- /dev/null +++ b/guix/avahi.scm @@ -0,0 +1,162 @@ +;;; GNU Guix --- Functional package management for GNU +;;; Copyright © 2020 Mathieu Othacehe +;;; +;;; This file is part of GNU Guix. +;;; +;;; GNU Guix is free software; you can redistribute it and/or modify it +;;; under the terms of the GNU General Public License as published by +;;; the Free Software Foundation; either version 3 of the License, or (at +;;; your option) any later version. +;;; +;;; GNU Guix is distributed in the hope that it will be useful, but +;;; WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;; GNU General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with GNU Guix. If not, see . + +(define-module (guix avahi) + #:use-module (guix records) + #:use-module (guix ui) + #:use-module (guix build syscalls) + #:use-module (avahi) + #:use-module (avahi client) + #:use-module (avahi client lookup) + #:use-module (avahi client publish) + #:use-module (ice-9 threads) + #:export (avahi-service + avahi-service? + avahi-service-name + avahi-service-interface + avahi-service-local-address + avahi-service-address + avahi-service-port + avahi-service-txt + + avahi-publish-service-thread + avahi-browse-service-thread)) + +(define-record-type* + avahi-service make-avahi-service + avahi-service? + (name avahi-service-name) + (interface avahi-service-interface) + (local-address avahi-service-local-address) + (address avahi-service-address) + (port avahi-service-port) + (txt avahi-service-txt)) + +(define* (avahi-publish-service-thread name + #:key + type port + (stop-loop? (const #f)) + (timeout 100) + (txt '())) + "Publish the service TYPE using Avahi, for the given PORT, on all interfaces +and for all protocols. Also, advertise the given TXT record list. + +This procedure starts a new thread running the Avahi event loop. It exits +when STOP-LOOP? procedure returns true." + (define client-callback + (lambda (client state) + (when (eq? state client-state/s-running) + (let ((group (make-entry-group client (const #t)))) + (apply + add-entry-group-service! group interface/unspecified + protocol/unspecified '() + name type #f #f port txt) + (commit-entry-group group))))) + + (call-with-new-thread + (lambda () + (let* ((poll (make-simple-poll)) + (client (make-client (simple-poll poll) + (list + client-flag/ignore-user-config) + client-callback))) + (while (not (stop-loop?)) + (iterate-simple-poll poll timeout)))))) + +(define (interface->ip-address interface) + "Return the local IP address of the given INTERFACE." + (let ((address + (network-interface-address + (socket AF_INET SOCK_STREAM 0) interface))) + (inet-ntop (sockaddr:fam address) (sockaddr:addr address)))) + +(define* (avahi-browse-service-thread proc + #:key + type + (family AF_INET) + (stop-loop? (const #f)) + (timeout 100)) + "Browse services of the given TYPE and FAMILY using Avahi. Each time a new +service is found, PROC is called and passed as argument the corresponding +AVAHI-SERVICE record. If a service is available on multiple network +interfaces, it will only be reported on the first interface found. + +This procedure starts a new thread running the Avahi event loop. It exits +when STOP-LOOP? procedure returns true." + (define %known-hosts + ;; Set of Avahi discovered hosts. + (make-hash-table)) + + (define (service-resolver-callback resolver interface protocol event + service-name service-type domain + host-name address-type address port + txt flags) + ;; Handle service resolution events. + (cond ((eq? event resolver-event/found) + (info (G_ "resolved service `~a' at `~a:~a'~%") + service-name (inet-ntop family address) port) + ;; Add the service if the host is unknown. This means that if a + ;; service is available on multiple network interfaces for a single + ;; host, only the first interface found will be considered. + (unless (hash-ref %known-hosts service-name) + (let* ((address (inet-ntop family address)) + (local-address (interface->ip-address interface)) + (service* (avahi-service + (name service-name) + (interface interface) + (local-address local-address) + (address address) + (port port) + (txt txt)))) + (hash-set! %known-hosts service-name service*) + (proc service*)))) + ((eq? event resolver-event/failure) + (report-error (G_ "failed to resolve service `~a'~%") + service-name))) + (free-service-resolver! resolver)) + + (define (service-browser-callback browser interface protocol event + service-name service-type + domain flags) + (cond + ((eq? event browser-event/new) + (make-service-resolver (service-browser-client browser) + interface protocol + service-name service-type domain + protocol/unspecified '() + service-resolver-callback)) + ((eq? event browser-event/remove) + (when (hash-ref %known-hosts service-name) + (hash-remove! %known-hosts service-name))))) + + (define client-callback + (lambda (client state) + (if (eq? state client-state/s-running) + (make-service-browser client + interface/unspecified + protocol/inet + type #f '() + service-browser-callback)))) + + (let* ((poll (make-simple-poll)) + (client (make-client (simple-poll poll) + '() ;; no flags + client-callback))) + (and (client? client) + (while (not (stop-loop?)) + (iterate-simple-poll poll timeout))))) diff --git a/guix/self.scm b/guix/self.scm index bbfd2f1b95..344dc7c3de 100644 --- a/guix/self.scm +++ b/guix/self.scm @@ -50,6 +50,7 @@ (module-ref (resolve-interface module) variable)))) (match-lambda ("guile" (ref '(gnu packages guile) 'guile-3.0/libgc-7)) + ("guile-avahi" (ref '(gnu packages guile) 'guile-avahi)) ("guile-json" (ref '(gnu packages guile) 'guile-json-4)) ("guile-ssh" (ref '(gnu packages ssh) 'guile-ssh)) ("guile-git" (ref '(gnu packages guile) 'guile-git)) @@ -778,6 +779,9 @@ Info manual." (xz (specification->package "xz")) (guix (specification->package "guix"))) "Return a file-like object that contains a compiled Guix." + (define guile-avahi + (specification->package "guile-avahi")) + (define guile-json (specification->package "guile-json")) @@ -806,8 +810,9 @@ Info manual." (match (append-map (lambda (package) (cons (list "x" package) (package-transitive-propagated-inputs package))) - (list guile-gcrypt gnutls guile-git guile-json - guile-ssh guile-sqlite3 guile-zlib guile-lzlib)) + (list guile-gcrypt gnutls guile-git guile-avahi + guile-json guile-ssh guile-sqlite3 guile-zlib + guile-lzlib)) (((labels packages _ ...) ...) packages))) From patchwork Sun Nov 22 15:56:59 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mathieu Othacehe X-Patchwork-Id: 25285 Return-Path: X-Original-To: patchwork@mira.cbaines.net Delivered-To: patchwork@mira.cbaines.net Received: by mira.cbaines.net (Postfix, from userid 113) id 4C12627BBF7; Sun, 22 Nov 2020 15:58:16 +0000 (GMT) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mira.cbaines.net X-Spam-Level: X-Spam-Status: No, score=-2.9 required=5.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_MSPIKE_H4,RCVD_IN_MSPIKE_WL,SPF_HELO_PASS autolearn=unavailable autolearn_force=no version=3.4.2 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mira.cbaines.net (Postfix) with ESMTPS id 3CA3627BBF9 for ; Sun, 22 Nov 2020 15:58:15 +0000 (GMT) Received: from localhost ([::1]:49074 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kgrkk-0001kh-G0 for patchwork@mira.cbaines.net; Sun, 22 Nov 2020 10:58:14 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:58620) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kgrkZ-0001k3-8U for guix-patches@gnu.org; Sun, 22 Nov 2020 10:58:03 -0500 Received: from debbugs.gnu.org ([209.51.188.43]:36574) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kgrkZ-0002HI-1R for guix-patches@gnu.org; Sun, 22 Nov 2020 10:58:03 -0500 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1kgrkZ-00064G-1C for guix-patches@gnu.org; Sun, 22 Nov 2020 10:58:03 -0500 X-Loop: help-debbugs@gnu.org Subject: [bug#44801] [PATCH 2/2] publish: Add avahi support. Resent-From: Mathieu Othacehe Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Sun, 22 Nov 2020 15:58:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: report 44801 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 44801@debbugs.gnu.org Cc: Mathieu Othacehe X-Debbugs-Original-To: guix-patches@gnu.org Received: via spool by submit@debbugs.gnu.org id=B.160606064623254 (code B ref -1); Sun, 22 Nov 2020 15:58:02 +0000 Received: (at submit) by debbugs.gnu.org; 22 Nov 2020 15:57:26 +0000 Received: from localhost ([127.0.0.1]:48116 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1kgrjy-00062y-8F for submit@debbugs.gnu.org; Sun, 22 Nov 2020 10:57:26 -0500 Received: from lists.gnu.org ([209.51.188.17]:48484) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1kgrjv-00062d-49 for submit@debbugs.gnu.org; Sun, 22 Nov 2020 10:57:23 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:58586) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kgrju-0001hF-Rc for guix-patches@gnu.org; Sun, 22 Nov 2020 10:57:22 -0500 Received: from fencepost.gnu.org ([2001:470:142:3::e]:46126) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kgrju-000241-Kt for guix-patches@gnu.org; Sun, 22 Nov 2020 10:57:22 -0500 Received: from [2a01:e0a:19b:d9a0:f0c7:1dab:64ad:1a4a] (port=49596 helo=localhost.localdomain) by fencepost.gnu.org with esmtpsa (TLS1.2:DHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.82) (envelope-from ) id 1kgrjr-0006Iv-AG; Sun, 22 Nov 2020 10:57:19 -0500 From: Mathieu Othacehe Date: Sun, 22 Nov 2020 16:56:59 +0100 Message-Id: <20201122155659.67235-3-othacehe@gnu.org> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20201122155659.67235-1-othacehe@gnu.org> References: <20201122155659.67235-1-othacehe@gnu.org> MIME-Version: 1.0 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: guix-patches@gnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org Sender: "Guix-patches" X-getmail-retrieved-from-mailbox: Patches * guix/scripts/publish.scm (%options): Add "--enable-avahi" option. (show-help): Document it. (service-name): New procedure, (service-type): new variable. (run-publish-server): Add "avahi?" and "port" parameters. Use them to publish the server using Avahi. (guix-publish): Pass the "avahi?" option to "run-publish-server". --- doc/guix.texi | 4 ++++ guix/scripts/publish.scm | 23 +++++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/doc/guix.texi b/doc/guix.texi index e2361c25e3..cfbf495cbc 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -12151,6 +12151,10 @@ The signing key pair must be generated before @command{guix publish} is launched, using @command{guix archive --generate-key} (@pxref{Invoking guix archive}). +When the @option{--enable-avahi} option is passed, the publish server is +advertised on the local network as an Avahi service, using Guile-Avahi +bindings. + The general syntax is: @example diff --git a/guix/scripts/publish.scm b/guix/scripts/publish.scm index a12abf5b4d..34fcb682b5 100644 --- a/guix/scripts/publish.scm +++ b/guix/scripts/publish.scm @@ -41,6 +41,7 @@ #:use-module (web server) #:use-module (web uri) #:autoload (sxml simple) (sxml->xml) + #:use-module (guix avahi) #:use-module (guix base32) #:use-module (guix base64) #:use-module (guix config) @@ -82,6 +83,8 @@ Publish ~a over HTTP.\n") %store-directory) (display (G_ " -u, --user=USER change privileges to USER as soon as possible")) (display (G_ " + -a, --enable-avahi enable Avahi based discovery")) + (display (G_ " -C, --compression[=METHOD:LEVEL] compress archives with METHOD at LEVEL")) (display (G_ " @@ -156,6 +159,9 @@ usage." (option '(#\V "version") #f #f (lambda _ (show-version-and-exit "guix publish"))) + (option '(#\a "enable-avahi") #f #f + (lambda (opt name arg result) + (alist-cons 'enable-avahi? #t result))) (option '(#\u "user") #t #f (lambda (opt name arg result) (alist-cons 'user arg result))) @@ -1043,11 +1049,25 @@ methods, return the applicable compression." (x (not-found request))) (not-found request)))) +(define (service-name) + "Return the Avahi service name of the server." + (string-append "guix-publish-" (gethostname))) + +(define service-type + ;; Return the Avahi service type of the server. + "_guix_publish._tcp") + (define* (run-publish-server socket store #:key + avahi? port (compressions (list %no-compression)) (nar-path "nar") narinfo-ttl cache pool) + (when avahi? + (avahi-publish-service-thread (service-name) + #:type service-type + #:port port)) + (run-server (make-request-handler store #:cache cache #:pool pool @@ -1092,6 +1112,7 @@ methods, return the applicable compression." (lambda (arg result) (leave (G_ "~A: extraneous argument~%") arg)) %default-options)) + (avahi? (assoc-ref opts 'enable-avahi?)) (user (assoc-ref opts 'user)) (port (assoc-ref opts 'port)) (ttl (assoc-ref opts 'narinfo-ttl)) @@ -1152,6 +1173,8 @@ consider using the '--user' option!~%"))) (with-store store (run-publish-server socket store + #:avahi? avahi? + #:port port #:cache cache #:pool (and cache (make-pool workers #:thread-name