diff --git a/.config.ci b/.config.ci index 1a2c01a..60bd5a8 100644 --- a/.config.ci +++ b/.config.ci @@ -4,4 +4,5 @@ CONFIG_PACKAGE_wpad-basic-openssl=n CONFIG_PACKAGE_wpad-basic-wolfssl=n CONFIG_PACKAGE_wpad-openssl=y CONFIG_PACKAGE_matter-netman=y +CONFIG_PACKAGE_mdnsresponder=y CONFIG_PACKAGE_openthread-br=y diff --git a/third_party/mdnsresponder/Makefile b/third_party/mdnsresponder/Makefile new file mode 100644 index 0000000..8ac6a2a --- /dev/null +++ b/third_party/mdnsresponder/Makefile @@ -0,0 +1,171 @@ +# Copyright (c) 2024 Apple Inc. +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +include $(TOPDIR)/rules.mk + +PKG_NAME:=mDNSResponder +PKG_VERSION:=2200.140.11 +PKG_RELEASE:=1 + +PKG_SOURCE:=mDNSResponder-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://github.com/apple-oss-distributions/mDNSResponder/archive/refs/tags +PKG_HASH:=f52963497e8baf650e6640fb5769ffbad7c6e45eea833dec2a0ca86a3ca55928 + +# Use local source dir for development +# USE_SOURCE_DIR:=$(HOME)/workspace/mDNSResponder + +PKG_LICENSE:=Apache-2.0 +PKG_LICENSE_FILES:=LICENSE + +PKG_BUILD_PARALLEL:=1 +PKG_CONFIG_DEPENDS:=CONFIG_MDNSD_DEBUG_LOGGING + +include $(INCLUDE_DIR)/package.mk + +define Package/mdnsresponder/Default + SECTION:=net + CATEGORY:=Network + SUBMENU:=IP Addresses and Names + URL:=https://github.com/apple-oss-distributions/mDNSResponder +endef + +define Package/mdnsresponder/Default/description +The mDNS Responder suite consists of a set of daemons, tools, and +libraries that implement Multicast DNS and DNS-SD service discovery. +endef + + +define Package/mdnsresponder + $(call Package/mdnsresponder/Default) + TITLE:=mDNS Responder suite (meta package) + DEPENDS:=+mdnsd +libdnssd +mdns-utils +endef + +define Package/mdnsresponder/description +$(call Package/mdnsresponder/Default/description) + +This meta-package selects all packages in the mDNS Responder suite. +endef + + +define Package/mdnsd + $(call Package/mdnsresponder/Default) + TITLE:=mDNS Responder daemon + MENU:=1 +endef + +define Package/mdnsd/config +if PACKAGE_mdnsd + config MDNSD_DEBUG_LOGGING + bool "Enable debug logging" + default n +endif +endef + +define Package/mdnsd/description +$(call Package/mdnsresponder/Default/description) + +The mDNS Responder daemon serves both as resolver for information +published using multicast DNS (mDNS), and as a publisher of mDNS +information. +endef + + +define Package/libdnssd + $(call Package/mdnsresponder/Default) + SECTION:=libs + CATEGORY:=Libraries + SUBMENU:= + TITLE:=mDNS Responder DNS-SD client library + CONFLICTS:=libavahi-compat-libdnssd + DEPENDS:=+mdnsd +endef + +define Package/libdnssd/description +The DNS-SD client library allows applications to make use of the +functionality provided by mDNSResponder. This includes publishing, +browsing, and resolving of DNS-SD services. +endef + + +define Package/mdns-utils + $(call Package/mdnsresponder/Default) + TITLE:=mDNS Responder utilities + DEPENDS:=+libdnssd +endef + +define Package/mdns-utils/description +This package contains the dns-sd utility. +endef + + +# The GitHub archive tarball has the wrong prefix due to the tag including the package name +TAR_CMD=$(HOST_TAR) -C $(1) --strip-components 1 $(TAR_OPTIONS) + +# Build with os=linux-uclibc ("not glibc") because musl does not support nss. +# Build without debug options or stripping, both are handled via the OpenWrt build system. +# Use gcc as the linker front-end so libssp gets linked automatically if needed. +MAKE_PATH:=mDNSPosix +OUT_DIR:=$(PKG_BUILD_DIR)/$(MAKE_PATH)/build/prod +CLIENTS_OUT_DIR:=$(PKG_BUILD_DIR)/Clients/build +MAKE_FLAGS+=os=linux-uclibc tls=no CFLAGS_DEBUGGING= LD="$(TARGET_CC)" STRIP=: +TARGET_CFLAGS+=\ + -DmDNSResponderVersion=$(PKG_VERSION)-$(PKG_RELEASE) \ + -DMDNS_VERSIONSTR_NODTS \ + -DUNICAST_DISABLED \ + -DMDNS_DEBUGMSGS=$(if CONFIG_MDNSD_DEBUG_LOGGING,1,0) + +# No configure step as such, but make clean on config changes +define Build/Configure + [ -f $(STAMP_CONFIGURED) ] || $(MAKE) -C $(PKG_BUILD_DIR)/$(MAKE_PATH) clean +endef + +define Build/Compile + $(call Build/Compile/Default,Daemon libdns_sd Clients) +endef + +define Build/InstallDev + $(INSTALL_DIR) $(1)/usr/include $(1)/usr/lib + $(CP) $(PKG_BUILD_DIR)/mDNSShared/dns_sd.h $(1)/usr/include/ + $(CP) $(OUT_DIR)/libdns_sd.so $(1)/usr/lib/ +endef + +# make install is not suitable for a cross-compilation environment, +# pick up files directly from the build directory instead. +Build/Install:=$(empty) + + +Package/mdnsresponder/install:=$(empty) + +define Package/mdnsd/install + $(INSTALL_DIR) $(1)/usr/sbin $(1)/etc/init.d + $(INSTALL_BIN) $(OUT_DIR)/mdnsd $(1)/usr/sbin + $(INSTALL_BIN) ./files/mdnsd.init $(1)/etc/init.d/mdnsd +endef + +define Package/libdnssd/install + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(OUT_DIR)/libdns_sd.so $(1)/usr/lib/ +endef + +define Package/mdns-utils/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(CLIENTS_OUT_DIR)/dns-sd $(1)/usr/bin +endef + +$(eval $(call BuildPackage,mdnsresponder)) +$(eval $(call BuildPackage,mdnsd)) +$(eval $(call BuildPackage,libdnssd)) +$(eval $(call BuildPackage,mdns-utils)) diff --git a/third_party/mdnsresponder/files/mdnsd.init b/third_party/mdnsresponder/files/mdnsd.init new file mode 100644 index 0000000..22d1cfe --- /dev/null +++ b/third_party/mdnsresponder/files/mdnsd.init @@ -0,0 +1,28 @@ +#!/bin/sh /etc/rc.common + +# Copyright (c) 2024 Apple Inc. +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +START=50 + +USE_PROCD=1 +PROG=/usr/sbin/mdnsd + +start_service() { + procd_open_instance + procd_set_param command "$PROG" + procd_set_param respawn + procd_close_instance +} diff --git a/third_party/mdnsresponder/patches/0001-mDNSResponderVersion-and-MDNS_VERSIONSTR_NODTS-handl.patch b/third_party/mdnsresponder/patches/0001-mDNSResponderVersion-and-MDNS_VERSIONSTR_NODTS-handl.patch new file mode 100644 index 0000000..7a3efce --- /dev/null +++ b/third_party/mdnsresponder/patches/0001-mDNSResponderVersion-and-MDNS_VERSIONSTR_NODTS-handl.patch @@ -0,0 +1,58 @@ +From a3a7a5aed8bab31a9b9bc7f564d062e143a83d71 Mon Sep 17 00:00:00 2001 +From: Karsten Sperling +Date: Tue, 24 Sep 2024 19:47:40 +1200 +Subject: [PATCH] mDNSResponderVersion and MDNS_VERSIONSTR_NODTS handling + +--- + mDNSPosix/PosixDaemon.c | 18 +++++++++++++----- + mDNSShared/dnssd_clientlib.c | 6 +++++- + 2 files changed, 18 insertions(+), 6 deletions(-) + +diff --git a/mDNSPosix/PosixDaemon.c b/mDNSPosix/PosixDaemon.c +index 9a0f692..beda41e 100644 +--- a/mDNSPosix/PosixDaemon.c ++++ b/mDNSPosix/PosixDaemon.c +@@ -270,10 +270,18 @@ asm (".desc ___crashreporter_info__, 0x10"); + #endif + + // For convenience when using the "strings" command, this is the last thing in the file +-#if mDNSResponderVersion > 1 +-mDNSexport const char mDNSResponderVersionString_SCCS[] = "@(#) mDNSResponder-" STRINGIFY(mDNSResponderVersion) " (" __DATE__ " " __TIME__ ")"; +-#elif MDNS_VERSIONSTR_NODTS +-mDNSexport const char mDNSResponderVersionString_SCCS[] = "@(#) mDNSResponder (Engineering Build)"; ++#ifndef STRINGIFY ++#define STRINGIFY_ARGUMENT_WITHOUT_EXPANSION(s) # s ++#define STRINGIFY(s) STRINGIFY_ARGUMENT_WITHOUT_EXPANSION(s) ++#endif ++ ++mDNSexport const char mDNSResponderVersionString_SCCS[] = "@(#) mDNSResponder" ++#ifdef mDNSResponderVersion ++ "-" STRINGIFY(mDNSResponderVersion) + #else +-mDNSexport const char mDNSResponderVersionString_SCCS[] = "@(#) mDNSResponder (Engineering Build) (" __DATE__ " " __TIME__ ")"; ++ " (Engineering Build)" ++#endif ++#if !MDNS_VERSIONSTR_NODTS ++ " (" __DATE__ " " __TIME__ ")" + #endif ++; +diff --git a/mDNSShared/dnssd_clientlib.c b/mDNSShared/dnssd_clientlib.c +index a1d98d9..75bece2 100644 +--- a/mDNSShared/dnssd_clientlib.c ++++ b/mDNSShared/dnssd_clientlib.c +@@ -372,7 +372,11 @@ DNSServiceErrorType DNSSD_API TXTRecordGetItemAtIndex + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wdate-time" + #endif +-const char VersionString_SCCS_libdnssd[] DNSSD_USED = "@(#) libdns_sd " STRINGIFY(mDNSResponderVersion) " (" __DATE__ " " __TIME__ ")"; ++const char VersionString_SCCS_libdnssd[] DNSSD_USED = "@(#) libdns_sd " STRINGIFY(mDNSResponderVersion) ++#if !MDNS_VERSIONSTR_NODTS ++ " (" __DATE__ " " __TIME__ ")" ++#endif ++; + #if defined(__GNUC__) + #pragma GCC diagnostic pop + #endif +-- +2.39.2 + diff --git a/third_party/mdnsresponder/patches/0002-Avoid-strcmp-with-null.patch b/third_party/mdnsresponder/patches/0002-Avoid-strcmp-with-null.patch new file mode 100644 index 0000000..2171cd0 --- /dev/null +++ b/third_party/mdnsresponder/patches/0002-Avoid-strcmp-with-null.patch @@ -0,0 +1,25 @@ +From edf0afdd8378fd2ce6a2aca050dfdb8a79eab372 Mon Sep 17 00:00:00 2001 +From: Karsten Sperling +Date: Tue, 24 Sep 2024 19:48:17 +1200 +Subject: [PATCH] Avoid strcmp with null + +--- + mDNSShared/mDNSDebug.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/mDNSShared/mDNSDebug.c b/mDNSShared/mDNSDebug.c +index 7a4ca19..d449dde 100644 +--- a/mDNSShared/mDNSDebug.c ++++ b/mDNSShared/mDNSDebug.c +@@ -71,7 +71,7 @@ mDNSlocal void LogMsgWithLevelv(os_log_t category, os_log_type_t level, const ch + mDNSlocal void LogMsgWithLevelv(const char *category, mDNSLogLevel_t level, const char *format, va_list args) + { + // Do not print the logs if the log category is MDNS_LOG_CATEGORY_DISABLED. +- if (strcmp(category, MDNS_LOG_CATEGORY_DISABLED) == 0) ++ if (category && strcmp(category, MDNS_LOG_CATEGORY_DISABLED) == 0) + { + return; + } +-- +2.39.2 + diff --git a/third_party/mdnsresponder/patches/0003-Ignore-irrelevant-config-files-with-UNICAST_DISABLED.patch b/third_party/mdnsresponder/patches/0003-Ignore-irrelevant-config-files-with-UNICAST_DISABLED.patch new file mode 100644 index 0000000..3a6bbba --- /dev/null +++ b/third_party/mdnsresponder/patches/0003-Ignore-irrelevant-config-files-with-UNICAST_DISABLED.patch @@ -0,0 +1,76 @@ +From b1aff590a9adbc6133819e56aef197fd768134a2 Mon Sep 17 00:00:00 2001 +From: Karsten Sperling +Date: Wed, 25 Sep 2024 12:40:17 +1200 +Subject: [PATCH] Ignore irrelevant config files with UNICAST_DISABLED + +--- + mDNSCore/uDNS.c | 2 +- + mDNSPosix/PosixDaemon.c | 4 ++++ + mDNSPosix/mDNSPosix.c | 2 ++ + 3 files changed, 7 insertions(+), 1 deletion(-) + +diff --git a/mDNSCore/uDNS.c b/mDNSCore/uDNS.c +index c9e9bcd..fe8d372 100644 +--- a/mDNSCore/uDNS.c ++++ b/mDNSCore/uDNS.c +@@ -7277,7 +7277,7 @@ mDNSexport mStatus mDNS_SetSecretForDomain(mDNS *m, DomainAuthInfo *info, const + return mStatus_UnsupportedErr; + } + +-mDNSexport domainname *uDNS_GetNextSearchDomain(mDNSInterfaceID InterfaceID, mDNSs8 *searchIndex, mDNSBool ignoreDotLocal) ++mDNSexport domainname *uDNS_GetNextSearchDomain(mDNSInterfaceID InterfaceID, int *searchIndex, mDNSBool ignoreDotLocal) + { + (void) InterfaceID; + (void) searchIndex; +diff --git a/mDNSPosix/PosixDaemon.c b/mDNSPosix/PosixDaemon.c +index beda41e..c9867ef 100644 +--- a/mDNSPosix/PosixDaemon.c ++++ b/mDNSPosix/PosixDaemon.c +@@ -50,9 +50,11 @@ extern int daemon(int, int); + #include "uds_daemon.h" + #include "PlatformCommon.h" + ++#ifndef UNICAST_DISABLED + #define CONFIG_FILE "/etc/mdnsd.conf" + static domainname DynDNSZone; // Default wide-area zone for service registration + static domainname DynDNSHostname; ++#endif + + #define RR_CACHE_SIZE 500 + static CacheEntity gRRCache[RR_CACHE_SIZE]; +@@ -87,6 +89,7 @@ mDNSlocal void mDNS_StatusCallback(mDNS *const m, mStatus result) + + static void Reconfigure(mDNS *m) + { ++#ifndef UNICAST_DISABLED + mDNSAddr DynDNSIP; + const mDNSAddr dummy = { mDNSAddrType_IPv4, { { { 1, 1, 1, 1 } } } };; + mDNS_SetPrimaryInterfaceInfo(m, NULL, NULL, NULL); +@@ -96,6 +99,7 @@ static void Reconfigure(mDNS *m) + mDNSPlatformSourceAddrForDest(&DynDNSIP, &dummy); + if (DynDNSHostname.c[0]) mDNS_AddDynDNSHostName(m, &DynDNSHostname, NULL, NULL); + if (DynDNSIP.type) mDNS_SetPrimaryInterfaceInfo(m, &DynDNSIP, NULL, NULL); ++#endif + mDNS_ConfigChanged(m); + } + +diff --git a/mDNSPosix/mDNSPosix.c b/mDNSPosix/mDNSPosix.c +index 3b761d0..51cbd9b 100644 +--- a/mDNSPosix/mDNSPosix.c ++++ b/mDNSPosix/mDNSPosix.c +@@ -1852,10 +1852,12 @@ mDNSexport mStatus mDNSPlatformInit(mDNS *const m) + // Tell mDNS core about the network interfaces on this machine. + if (err == mStatus_NoError) err = SetupInterfaceList(m); + ++#ifndef UNICAST_DISABLED + // Tell mDNS core about DNS Servers + mDNS_Lock(m); + if (err == mStatus_NoError) ParseDNSServers(m, uDNS_SERVERS_FILE); + mDNS_Unlock(m); ++#endif + + if (err == mStatus_NoError) + { +-- +2.39.2 + diff --git a/third_party/mdnsresponder/patches/0004-Run-in-foreground-under-procd.patch b/third_party/mdnsresponder/patches/0004-Run-in-foreground-under-procd.patch new file mode 100644 index 0000000..b9841a9 --- /dev/null +++ b/third_party/mdnsresponder/patches/0004-Run-in-foreground-under-procd.patch @@ -0,0 +1,25 @@ +From 9506c22107cb110abeeb94bb6ddeda15c8fc38db Mon Sep 17 00:00:00 2001 +From: Karsten Sperling +Date: Wed, 25 Sep 2024 18:13:45 +1200 +Subject: [PATCH] Run in foreground under procd + +--- + mDNSPosix/PosixDaemon.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/mDNSPosix/PosixDaemon.c b/mDNSPosix/PosixDaemon.c +index c9867ef..4861895 100644 +--- a/mDNSPosix/PosixDaemon.c ++++ b/mDNSPosix/PosixDaemon.c +@@ -113,7 +113,7 @@ mDNSlocal void ParseCmdLineArgs(int argc, char **argv) + } + if (!mDNS_DebugMode) + { +- int result = daemon(0, 0); ++ int result = 0; //daemon(0, 0); + if (result != 0) { LogMsg("Could not run as daemon - exiting"); exit(result); } + #if __APPLE__ + LogMsg("The POSIX mdnsd should only be used on OS X for testing - exiting"); +-- +2.39.2 + diff --git a/third_party/mdnsresponder/patches/0005-Fix-Makefile-dependency-to-enable-parallel-builds.patch b/third_party/mdnsresponder/patches/0005-Fix-Makefile-dependency-to-enable-parallel-builds.patch new file mode 100644 index 0000000..9a2ac57 --- /dev/null +++ b/third_party/mdnsresponder/patches/0005-Fix-Makefile-dependency-to-enable-parallel-builds.patch @@ -0,0 +1,25 @@ +From 0ca713d18def127918fdb80c8d77806c592d5106 Mon Sep 17 00:00:00 2001 +From: Karsten Sperling +Date: Thu, 26 Sep 2024 12:11:01 +1200 +Subject: [PATCH] Fix Makefile dependency to enable parallel builds + +--- + mDNSPosix/Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/mDNSPosix/Makefile b/mDNSPosix/Makefile +index 0417065..3d58d7f 100755 +--- a/mDNSPosix/Makefile ++++ b/mDNSPosix/Makefile +@@ -282,7 +282,7 @@ $(BUILDDIR)/libdns_sd.$(LDSUFFIX): $(CLIENTLIBOBJS) + Clients: setup libdns_sd ../Clients/build/dns-sd + @echo "Clients done" + +-../Clients/build/dns-sd: ../Clients/dns-sd.c ++../Clients/build/dns-sd: ../Clients/dns-sd.c libdns_sd + $(MAKE) -C ../Clients DEBUG=$(DEBUG) SUPMAKE_CFLAGS="$(MDNSCFLAGS)" + + # nss_mdns target builds the Name Service Switch module +-- +2.39.2 + diff --git a/third_party/mdnsresponder/patches/0006-Improve-rtnetlink-parsing-logging-and-ignore-duplica.patch b/third_party/mdnsresponder/patches/0006-Improve-rtnetlink-parsing-logging-and-ignore-duplica.patch new file mode 100644 index 0000000..a9f9a2b --- /dev/null +++ b/third_party/mdnsresponder/patches/0006-Improve-rtnetlink-parsing-logging-and-ignore-duplica.patch @@ -0,0 +1,259 @@ +From 65b1836cbd9c2976a7473e3fb5816eda48bcfa75 Mon Sep 17 00:00:00 2001 +From: Karsten Sperling +Date: Tue, 15 Oct 2024 13:03:31 +1300 +Subject: [PATCH] Improve rtnetlink parsing/logging and ignore duplicate + RTM_NEWADDR events + +--- + mDNSPosix/mDNSPosix.c | 188 +++++++++++++++++++++++++++++------------- + 1 file changed, 131 insertions(+), 57 deletions(-) + +diff --git a/mDNSPosix/mDNSPosix.c b/mDNSPosix/mDNSPosix.c +index 51cbd9b..ef18773 100644 +--- a/mDNSPosix/mDNSPosix.c ++++ b/mDNSPosix/mDNSPosix.c +@@ -1606,87 +1606,159 @@ mDNSlocal mStatus OpenIfNotifySocket(int *pFD) + } + + #if MDNS_DEBUGMSGS +-mDNSlocal void PrintNetLinkMsg(const struct nlmsghdr *pNLMsg) ++#define CASE_ENUM_NAME(name) case name: return #name; ++mDNSlocal char const * NLMsgTypeName(uint16_t type) + { +- const char *kNLMsgTypes[] = { "", "NLMSG_NOOP", "NLMSG_ERROR", "NLMSG_DONE", "NLMSG_OVERRUN" }; +- const char *kNLRtMsgTypes[] = { "RTM_NEWLINK", "RTM_DELLINK", "RTM_GETLINK", "RTM_NEWADDR", "RTM_DELADDR", "RTM_GETADDR" }; +- +- printf("nlmsghdr len=%d, type=%s, flags=0x%x\n", pNLMsg->nlmsg_len, +- pNLMsg->nlmsg_type < RTM_BASE ? kNLMsgTypes[pNLMsg->nlmsg_type] : kNLRtMsgTypes[pNLMsg->nlmsg_type - RTM_BASE], +- pNLMsg->nlmsg_flags); +- +- if (RTM_NEWLINK <= pNLMsg->nlmsg_type && pNLMsg->nlmsg_type <= RTM_GETLINK) ++ switch (type) + { +- struct ifinfomsg *pIfInfo = (struct ifinfomsg*) NLMSG_DATA(pNLMsg); +- printf("ifinfomsg family=%d, type=%d, index=%d, flags=0x%x, change=0x%x\n", pIfInfo->ifi_family, +- pIfInfo->ifi_type, pIfInfo->ifi_index, pIfInfo->ifi_flags, pIfInfo->ifi_change); +- ++ CASE_ENUM_NAME(NLMSG_NOOP); ++ CASE_ENUM_NAME(NLMSG_ERROR); ++ CASE_ENUM_NAME(NLMSG_DONE); ++ CASE_ENUM_NAME(NLMSG_OVERRUN); ++ CASE_ENUM_NAME(RTM_NEWLINK); ++ CASE_ENUM_NAME(RTM_DELLINK); ++ CASE_ENUM_NAME(RTM_NEWADDR); ++ CASE_ENUM_NAME(RTM_DELADDR); + } +- else if (RTM_NEWADDR <= pNLMsg->nlmsg_type && pNLMsg->nlmsg_type <= RTM_GETADDR) ++ return "???"; ++} ++mDNSlocal char const * IFATypeName(unsigned short type) ++{ ++ switch (type) + { +- struct ifaddrmsg *pIfAddr = (struct ifaddrmsg*) NLMSG_DATA(pNLMsg); +- printf("ifaddrmsg family=%d, index=%d, flags=0x%x\n", pIfAddr->ifa_family, +- pIfAddr->ifa_index, pIfAddr->ifa_flags); ++ CASE_ENUM_NAME(IFA_ADDRESS); ++ CASE_ENUM_NAME(IFA_LOCAL); ++ CASE_ENUM_NAME(IFA_LABEL); ++ CASE_ENUM_NAME(IFA_BROADCAST); ++ CASE_ENUM_NAME(IFA_ANYCAST); ++ CASE_ENUM_NAME(IFA_CACHEINFO); ++ CASE_ENUM_NAME(IFA_MULTICAST); ++ CASE_ENUM_NAME(IFA_FLAGS); + } +- printf("\n"); ++ return "???"; + } ++#undef CASE_ENUM_NAME + #endif + +-mDNSlocal mDNSu32 ProcessRoutingNotification(int sd) ++mDNSlocal void MarkInterfaceMask(mDNSu32 *mask, int ifindex) ++{ ++ // Valid interface indices are > 0, but might be >= 32 ++ *mask |= (0 < ifindex && ifindex < 32) ? (mDNSu32)1 << ifindex : 1; ++} ++ ++mDNSlocal mDNSu32 ProcessRoutingNotification(int sd, mDNS *m) + // Read through the messages on sd and if any indicate that any interface records should + // be torn down and rebuilt, return affected indices as a bitmask. Otherwise return 0. + { + ssize_t readCount; + char buff[4096]; +- struct nlmsghdr *pNLMsg = (struct nlmsghdr*) buff; ++ struct nlmsghdr *pNLMsg; ++ int len; + mDNSu32 result = 0; + +- // The structure here is more complex than it really ought to be because, +- // unfortunately, there's no good way to size a buffer in advance large +- // enough to hold all pending data and so avoid message fragmentation. +- // (Note that FIONREAD is not supported on AF_NETLINK.) ++ readCount = recv(sd, buff, sizeof(buff), MSG_TRUNC); ++ if (readCount < 0) ++ { ++ LogMsg("netlink recv failed: %s", strerror(errno)); ++ return 0; ++ } ++ if (readCount > (ssize_t)sizeof(buff)) ++ { ++ LogMsg("netlink recv truncated: %ld", (long int)readCount); ++ return UINT32_MAX; // assume we have missed a relevant event ++ } + +- readCount = read(sd, buff, sizeof buff); +- while (1) ++ pNLMsg = (struct nlmsghdr *)buff; ++ len = (int)readCount; ++ while (NLMSG_OK(pNLMsg, len)) + { +- // Make sure we've got an entire nlmsghdr in the buffer, and payload, too. +- // If not, discard already-processed messages in buffer and read more data. +- if (((char*) &pNLMsg[1] > (buff + readCount)) || // i.e. *pNLMsg extends off end of buffer +- ((char*) pNLMsg + pNLMsg->nlmsg_len > (buff + readCount))) ++ debugf("nlmsghdr ofs=%d len=%d, type=%s(%d), flags=0x%x", ++ (char const *)pNLMsg - buff, pNLMsg->nlmsg_len, ++ NLMsgTypeName(pNLMsg->nlmsg_type), pNLMsg->nlmsg_type, pNLMsg->nlmsg_flags); ++ ++ if (pNLMsg->nlmsg_type == RTM_NEWLINK || pNLMsg->nlmsg_type == RTM_DELLINK) + { +- if (buff < (char*) pNLMsg) // we have space to shuffle ++ struct ifinfomsg *pIfInfo = NLMSG_DATA(pNLMsg); ++ ++#if MDNS_DEBUGMSGS ++ struct rtattr *pRta = IFLA_RTA(pIfInfo); ++ int rlen = pNLMsg->nlmsg_len; ++ debugf("ifinfomsg family=%d, type=%d, index=%d, flags=0x%x, change=0x%x", ++ pIfInfo->ifi_family, pIfInfo->ifi_type, pIfInfo->ifi_index, ++ pIfInfo->ifi_flags, pIfInfo->ifi_change); ++ while (RTA_OK(pRta, rlen)) + { +- // discard processed data +- readCount -= ((char*) pNLMsg - buff); +- memmove(buff, pNLMsg, readCount); +- pNLMsg = (struct nlmsghdr*) buff; +- +- // read more data +- readCount += read(sd, buff + readCount, sizeof buff - readCount); +- continue; // spin around and revalidate with new readCount ++ debugf("rtattr type=???" "(%d) [%d bytes]", pRta->rta_type, RTA_PAYLOAD(pRta)); ++ pRta = RTA_NEXT(pRta, rlen); + } +- else +- break; // Otherwise message does not fit in buffer +- } ++#endif + ++ MarkInterfaceMask(&result, pIfInfo->ifi_index); ++ } ++ else if (pNLMsg->nlmsg_type == RTM_NEWADDR || pNLMsg->nlmsg_type == RTM_DELADDR) ++ { ++ struct ifaddrmsg *pIfAddr = NLMSG_DATA(pNLMsg); ++ struct rtattr *pRta = IFA_RTA(pIfAddr); ++ int rlen = pNLMsg->nlmsg_len; ++ mDNSAddr addr = { mDNSAddrType_None }; ++ mDNSBool ignore = mDNSfalse; ++ ++ debugf("ifaddrmsg family=%d, prefixlen=%d, flags=0x%x, scope=%d, index=%d", ++ pIfAddr->ifa_family, pIfAddr->ifa_prefixlen, pIfAddr->ifa_flags, pIfAddr->ifa_scope, pIfAddr->ifa_index); ++ while (RTA_OK(pRta, rlen)) ++ { ++ if (pRta->rta_type == IFA_ADDRESS) ++ { ++ if (pIfAddr->ifa_family == AF_INET) ++ { ++ addr.type = mDNSAddrType_IPv4; ++ addr.ip.v4 = *(mDNSv4Addr *)RTA_DATA(pRta); ++ } ++#if HAVE_IPV6 ++ else if (pIfAddr->ifa_family == AF_INET6) ++ { ++ addr.type = mDNSAddrType_IPv6; ++ addr.ip.v6 = *(mDNSv6Addr *)RTA_DATA(pRta); ++ } ++#endif + #if MDNS_DEBUGMSGS +- PrintNetLinkMsg(pNLMsg); ++ debugf("rtattr type=IFA_ADDRESS(%d) %#a", pRta->rta_type, &addr); + #endif ++ } ++ else if (pRta->rta_type == IFA_FLAGS) ++ { ++ debugf("rtattr type=IFA_FLAGS(%d) 0x%" PRIx32, pRta->rta_type, *(uint32_t *)RTA_DATA(pRta)); ++ } ++ else ++ { ++ debugf("rtattr type=%s(%d) [%d bytes]", IFATypeName(pRta->rta_type), pRta->rta_type, RTA_PAYLOAD(pRta)); ++ } ++ pRta = RTA_NEXT(pRta, rlen); ++ } + +- // Process the NetLink message +- if (pNLMsg->nlmsg_type == RTM_GETLINK || pNLMsg->nlmsg_type == RTM_NEWLINK) +- result |= 1 << ((struct ifinfomsg*) NLMSG_DATA(pNLMsg))->ifi_index; +- else if (pNLMsg->nlmsg_type == RTM_DELADDR || pNLMsg->nlmsg_type == RTM_NEWADDR) +- result |= 1 << ((struct ifaddrmsg*) NLMSG_DATA(pNLMsg))->ifa_index; ++ // The kernel appears to periodically send RTM_NEWADDR events for IPv6 addresses that ++ // we already know about; in practice this has been observed as frequently as multiple ++ // times per minute and may be releated to receiving a RA. We don't want to completely ++ // rebuild and re-advertise all our host records in this case. ++ if (pNLMsg->nlmsg_type == RTM_NEWADDR && addr.type != mDNSAddrType_None) ++ { ++ PosixNetworkInterface *intf = (PosixNetworkInterface *)m->HostInterfaces; ++ while (intf != NULL) ++ { ++ if ((mDNSu32)intf->index == pIfAddr->ifa_index && mDNSSameAddress(&intf->coreIntf.ip, &addr)) ++ { ++ debugf("RTM_NEWADDR matches existing %s address, ignoring", intf->intfName); ++ ignore = mDNStrue; ++ break; ++ } ++ intf = (PosixNetworkInterface *)intf->coreIntf.next; ++ } ++ } + +- // Advance pNLMsg to the next message in the buffer +- if ((pNLMsg->nlmsg_flags & NLM_F_MULTI) != 0 && pNLMsg->nlmsg_type != NLMSG_DONE) +- { +- ssize_t len = readCount - ((char*)pNLMsg - buff); +- pNLMsg = NLMSG_NEXT(pNLMsg, len); ++ if (!ignore) MarkInterfaceMask(&result, pIfAddr->ifa_index); + } +- else +- break; // all done! ++ ++ pNLMsg = NLMSG_NEXT(pNLMsg, len); + } + + return result; +@@ -1721,7 +1793,7 @@ mDNSlocal void PrintRoutingSocketMsg(const struct ifa_msghdr *pRSMsg) + } + #endif + +-mDNSlocal mDNSu32 ProcessRoutingNotification(int sd) ++mDNSlocal mDNSu32 ProcessRoutingNotification(int sd, mDNS *m) + // Read through the messages on sd and if any indicate that any interface records should + // be torn down and rebuilt, return affected indices as a bitmask. Otherwise return 0. + { +@@ -1730,6 +1802,8 @@ mDNSlocal mDNSu32 ProcessRoutingNotification(int sd) + struct ifa_msghdr *pRSMsg = (struct ifa_msghdr*) buff; + mDNSu32 result = 0; + ++ (void)m; // Unused ++ + readCount = read(sd, buff, sizeof buff); + if (readCount < (ssize_t) sizeof(struct ifa_msghdr)) + return mStatus_UnsupportedErr; // cannot decipher message +@@ -1768,7 +1842,7 @@ mDNSlocal void InterfaceChangeCallback(int fd, void *context) + + do + { +- changedInterfaces |= ProcessRoutingNotification(pChgRec->NotifySD); ++ changedInterfaces |= ProcessRoutingNotification(pChgRec->NotifySD, pChgRec->mDNS); + } + while (0 < select(pChgRec->NotifySD + 1, &readFDs, (fd_set*) NULL, (fd_set*) NULL, &zeroTimeout)); + +-- +2.39.2 + diff --git a/third_party/openthread-br/Makefile b/third_party/openthread-br/Makefile index 1fdea48..e607af1 100644 --- a/third_party/openthread-br/Makefile +++ b/third_party/openthread-br/Makefile @@ -29,7 +29,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=openthread-br -PKG_RELEASE:=1 +PKG_RELEASE:=2 PKG_SOURCE_URL:=https://github.com/openthread/ot-br-posix.git PKG_SOURCE_PROTO:=git PKG_SOURCE_MIRROR:=0 # don't try OpenWrt mirror @@ -44,38 +44,75 @@ PKG_LICENSE_FILES:=LICENSE include $(INCLUDE_DIR)/package.mk include $(INCLUDE_DIR)/cmake.mk +define Package/openthread-br/Default + SECTION:=net + CATEGORY:=Network + TITLE:=OpenThread Border Router + URL:=https://github.com/openthread/ot-br-posix + DEPENDS:=+libstdcpp +libjson-c +libubus +libblobmsg-json +kmod-usb-acm +kmod-tun +endef + +define Package/openthread-br/Default/description +The OpenThread Border Router daemon connects a Thread Network to the +Wi-Fi / Ethernet infrastructure network. Requires a Radio Co-Processor +(RCP) with appropriate firmware connected via UART / USB. +endef + + +define Package/openthread-br + $(call Package/openthread-br/Default) + VARIANT:=default + DEPENDS+= +libdnssd +endef + +define Package/openthread-br/description +$(call Package/openthread-br/Default/description) + +This default variant of the package uses mDNSResponder for mDNS / DNS-SD. +endef + + +define Package/openthread-br-avahi + $(call Package/openthread-br/Default) + VARIANT:=avahi + PROVIDES:=openthread-br + CONFLICTS:=openthread-br + DEPENDS+= +libavahi-client +endef + +define Package/openthread-br-avahi/description +$(call Package/openthread-br/Default/description) + +This variant of the package uses Avahi for mDNS / DNS-SD. +endef + + # Disable firewall integration due to https://github.com/openthread/ot-br-posix/issues/1675 CMAKE_OPTIONS+= \ - -DBUILD_TESTING=OFF \ + -DCMAKE_BUILD_TYPE=$(if $(CONFIG_DEBUG),Debug,Release) \ -DCMAKE_INSTALL_PREFIX=/usr \ + -DBUILD_TESTING=OFF \ + -DOTBR_OPENWRT=ON \ -DOTBR_BORDER_AGENT=ON \ -DOTBR_BORDER_ROUTING=ON \ -DOTBR_INFRA_IF_NAME=br-lan \ - -DOTBR_MDNS="avahi" \ - -DOTBR_OPENWRT=ON \ -DOTBR_SRP_ADVERTISING_PROXY=ON \ + -DOTBR_NAT64=OFF \ -DOT_FIREWALL=OFF \ -DOT_POSIX_SETTINGS_PATH=\"/etc/openthread\" \ - -DOT_READLINE=OFF \ - -DOTBR_NAT64=OFF \ - -DNAT64_SERVICE=\"openthread\" + -DOT_READLINE=OFF # OpenWrt uses /var/run instead of /run -TARGET_CFLAGS += -DOPENTHREAD_POSIX_CONFIG_DAEMON_SOCKET_BASENAME=\\\"/var/run/openthread-%s\\\" - -define Package/openthread-br - SECTION:=net - CATEGORY:=Network - TITLE:=OpenThread Border Router - URL:=https://github.com/openthread/ot-br-posix - DEPENDS:=+libstdcpp +libjson-c +libubus +libblobmsg-json +libavahi-client +avahi-daemon +kmod-usb-acm +kmod-tun -endef +TARGET_CFLAGS += \ + -DOPENTHREAD_POSIX_CONFIG_DAEMON_SOCKET_BASENAME=\\\"/var/run/openthread-%s\\\" \ + -DOPENTHREAD_CONFIG_LOG_PREPEND_UPTIME=0 \ + -DOPENTHREAD_CONFIG_LOG_PREPEND_LEVEL=0 -define Package/openthread-br/description - OpenThread Border Router - Connects a Thread Network to the Wi-Fi / Ethernet infrastructure network. - Requires a Radio Co-Processor (RCP) with appropriate firmware connected via UART / USB. -endef +ifeq ($(BUILD_VARIANT),avahi) +CMAKE_OPTIONS+= -DOTBR_MDNS="avahi" +else +CMAKE_OPTIONS+= -DOTBR_MDNS="mDNSResponder" +endif define Package/openthread-br/install $(INSTALL_DIR) $(1)/usr/sbin @@ -98,4 +135,12 @@ define Package/openthread-br/install $(CP) $(PKG_BUILD_DIR)/src/openwrt/handle_error.js $(1)/www/luci-static/resources endef +define Package/openthread-br/conffiles +/etc/openthread/ +endef + +Package/openthread-br-avahi/install=$(Package/openthread-br/install) +Package/openthread-br-avahi/conffiles=$(Package/openthread-br/conffiles) + $(eval $(call BuildPackage,openthread-br)) +$(eval $(call BuildPackage,openthread-br-avahi)) diff --git a/third_party/openthread-br/patches/010-init-script.patch b/third_party/openthread-br/patches/010-init-script.patch index 33bb4ab..4cf24f4 100644 --- a/third_party/openthread-br/patches/010-init-script.patch +++ b/third_party/openthread-br/patches/010-init-script.patch @@ -68,7 +68,7 @@ index 46505ff434..e942234fb9 100755 + 'thread_if_name:string' \ + 'infra_if_name:string' \ + 'uart_device:string' \ -+ 'uart_baudrate:uinteger:115200' \ ++ 'uart_baudrate:uinteger:460800' \ + 'uart_flow_control:bool:1' +} + @@ -117,5 +117,5 @@ index 855d708852..d80d91b5ff 100644 +config otbr-agent 'wpan0' + option infra_if_name '@OTBR_INFRA_IF_NAME@' + option uart_device '/dev/ttyACM0' -+ option uart_baudrate '115200' ++ option uart_baudrate '460800' + option uart_flow_control '1'