react-native-zeroconf 0.13.8 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NOTICE +49 -0
- package/README.md +489 -65
- package/android/build.gradle +23 -24
- package/android/src/main/AndroidManifest.xml +5 -2
- package/android/src/main/java/com/balthazargronon/RCTZeroconf/ZeroConfImplFactory.java +10 -3
- package/android/src/main/java/com/balthazargronon/RCTZeroconf/ZeroconfModule.java +3 -2
- package/android/src/main/java/com/balthazargronon/RCTZeroconf/nsd/NsdServiceImpl.java +83 -22
- package/android/src/main/java/com/balthazargronon/RCTZeroconf/rx2dnssd/DnssdImpl.java +61 -16
- package/android/src/main/java/com/github/druk/dnssd/BaseListener.java +33 -0
- package/android/src/main/java/com/github/druk/dnssd/BrowseListener.java +67 -0
- package/android/src/main/java/com/github/druk/dnssd/DNSRecord.java +47 -0
- package/android/src/main/java/com/github/druk/dnssd/DNSSD.java +650 -0
- package/android/src/main/java/com/github/druk/dnssd/DNSSDBindable.java +67 -0
- package/android/src/main/java/com/github/druk/dnssd/DNSSDEmbedded.java +135 -0
- package/android/src/main/java/com/github/druk/dnssd/DNSSDException.java +66 -0
- package/android/src/main/java/com/github/druk/dnssd/DNSSDRecordRegistrar.java +55 -0
- package/android/src/main/java/com/github/druk/dnssd/DNSSDRegistration.java +54 -0
- package/android/src/main/java/com/github/druk/dnssd/DNSSDService.java +35 -0
- package/android/src/main/java/com/github/druk/dnssd/DomainListener.java +57 -0
- package/android/src/main/java/com/github/druk/dnssd/InternalBrowseListener.java +76 -0
- package/android/src/main/java/com/github/druk/dnssd/InternalDNSSD.java +870 -0
- package/android/src/main/java/com/github/druk/dnssd/InternalDNSSDRecordRegistrar.java +30 -0
- package/android/src/main/java/com/github/druk/dnssd/InternalDNSSDRegistration.java +34 -0
- package/android/src/main/java/com/github/druk/dnssd/InternalDNSSDService.java +29 -0
- package/android/src/main/java/com/github/druk/dnssd/InternalDomainListener.java +62 -0
- package/android/src/main/java/com/github/druk/dnssd/InternalQueryListener.java +61 -0
- package/android/src/main/java/com/github/druk/dnssd/InternalRegisterListener.java +51 -0
- package/android/src/main/java/com/github/druk/dnssd/InternalResolveListener.java +58 -0
- package/android/src/main/java/com/github/druk/dnssd/NSClass.java +16 -0
- package/android/src/main/java/com/github/druk/dnssd/NSType.java +58 -0
- package/android/src/main/java/com/github/druk/dnssd/QueryListener.java +54 -0
- package/android/src/main/java/com/github/druk/dnssd/RegisterListener.java +46 -0
- package/android/src/main/java/com/github/druk/dnssd/RegisterRecordListener.java +35 -0
- package/android/src/main/java/com/github/druk/dnssd/ResolveListener.java +55 -0
- package/android/src/main/java/com/github/druk/dnssd/TXTRecord.java +293 -0
- package/android/src/main/java/com/github/druk/rx2dnssd/BonjourService.java +400 -0
- package/android/src/main/java/com/github/druk/rx2dnssd/Rx2BrowseListener.java +55 -0
- package/android/src/main/java/com/github/druk/rx2dnssd/Rx2Dnssd.java +127 -0
- package/android/src/main/java/com/github/druk/rx2dnssd/Rx2DnssdBindable.java +35 -0
- package/android/src/main/java/com/github/druk/rx2dnssd/Rx2DnssdCommon.java +280 -0
- package/android/src/main/java/com/github/druk/rx2dnssd/Rx2DnssdEmbedded.java +31 -0
- package/android/src/main/java/com/github/druk/rx2dnssd/Rx2QueryListener.java +70 -0
- package/android/src/main/java/com/github/druk/rx2dnssd/Rx2RegisterListener.java +47 -0
- package/android/src/main/java/com/github/druk/rx2dnssd/Rx2ResolveListener.java +51 -0
- package/android/src/main/jni/Android.mk +95 -0
- package/android/src/main/jni/Application.mk +3 -0
- package/android/src/main/jni/DNSSD.java.h +290 -0
- package/android/src/main/jni/JNISupport.c +1140 -0
- package/android/src/main/jni/mdnsresponder/Android.bp +215 -0
- package/android/src/main/jni/mdnsresponder/Clients/ClientCommon.c +75 -0
- package/android/src/main/jni/mdnsresponder/Clients/ClientCommon.h +41 -0
- package/android/src/main/jni/mdnsresponder/Clients/Makefile +54 -0
- package/android/src/main/jni/mdnsresponder/Clients/ReadMe.txt +25 -0
- package/android/src/main/jni/mdnsresponder/Clients/dns-sd.c +1351 -0
- package/android/src/main/jni/mdnsresponder/LICENSE +13 -0
- package/android/src/main/jni/mdnsresponder/MODULE_LICENSE_APACHE2 +0 -0
- package/android/src/main/jni/mdnsresponder/Makefile +41 -0
- package/android/src/main/jni/mdnsresponder/NOTICE +13 -0
- package/android/src/main/jni/mdnsresponder/PrivateDNS.txt +275 -0
- package/android/src/main/jni/mdnsresponder/README.txt +166 -0
- package/android/src/main/jni/mdnsresponder/README.version +3 -0
- package/android/src/main/jni/mdnsresponder/android/caseMapping/Iphlpapi.h +1 -0
- package/android/src/main/jni/mdnsresponder/android/caseMapping/README +3 -0
- package/android/src/main/jni/mdnsresponder/android/caseMapping/Resource.h +1 -0
- package/android/src/main/jni/mdnsresponder/android/caseMapping/Ws2tcpip.h +1 -0
- package/android/src/main/jni/mdnsresponder/android/caseMapping/ipExport.h +1 -0
- package/android/src/main/jni/mdnsresponder/android/windows_firewall_dummy.c +10 -0
- package/android/src/main/jni/mdnsresponder/mDNSCore/DNSCommon.c +3157 -0
- package/android/src/main/jni/mdnsresponder/mDNSCore/DNSCommon.h +292 -0
- package/android/src/main/jni/mdnsresponder/mDNSCore/DNSDigest.c +1579 -0
- package/android/src/main/jni/mdnsresponder/mDNSCore/Implementer Notes.txt +66 -0
- package/android/src/main/jni/mdnsresponder/mDNSCore/mDNS.c +11469 -0
- package/android/src/main/jni/mdnsresponder/mDNSCore/mDNSDebug.h +164 -0
- package/android/src/main/jni/mdnsresponder/mDNSCore/mDNSEmbeddedAPI.h +2974 -0
- package/android/src/main/jni/mdnsresponder/mDNSCore/uDNS.c +4969 -0
- package/android/src/main/jni/mdnsresponder/mDNSCore/uDNS.h +132 -0
- package/android/src/main/jni/mdnsresponder/mDNSPosix/Client.c +223 -0
- package/android/src/main/jni/mdnsresponder/mDNSPosix/ExampleClientApp.c +91 -0
- package/android/src/main/jni/mdnsresponder/mDNSPosix/ExampleClientApp.h +18 -0
- package/android/src/main/jni/mdnsresponder/mDNSPosix/Identify.c +378 -0
- package/android/src/main/jni/mdnsresponder/mDNSPosix/Makefile +520 -0
- package/android/src/main/jni/mdnsresponder/mDNSPosix/NetMonitor.c +1010 -0
- package/android/src/main/jni/mdnsresponder/mDNSPosix/PosixDaemon.c +329 -0
- package/android/src/main/jni/mdnsresponder/mDNSPosix/ProxyResponder.c +300 -0
- package/android/src/main/jni/mdnsresponder/mDNSPosix/ReadMe.txt +314 -0
- package/android/src/main/jni/mdnsresponder/mDNSPosix/Responder.c +792 -0
- package/android/src/main/jni/mdnsresponder/mDNSPosix/Services.txt +36 -0
- package/android/src/main/jni/mdnsresponder/mDNSPosix/libnss_mdns.8 +148 -0
- package/android/src/main/jni/mdnsresponder/mDNSPosix/mDNSPosix.c +1685 -0
- package/android/src/main/jni/mdnsresponder/mDNSPosix/mDNSPosix.h +88 -0
- package/android/src/main/jni/mdnsresponder/mDNSPosix/mDNSUNP.c +726 -0
- package/android/src/main/jni/mdnsresponder/mDNSPosix/mDNSUNP.h +130 -0
- package/android/src/main/jni/mdnsresponder/mDNSPosix/mdnsd.sh +73 -0
- package/android/src/main/jni/mdnsresponder/mDNSPosix/nss_ReadMe.txt +125 -0
- package/android/src/main/jni/mdnsresponder/mDNSPosix/nss_mdns.c +2723 -0
- package/android/src/main/jni/mdnsresponder/mDNSPosix/nss_mdns.conf +13 -0
- package/android/src/main/jni/mdnsresponder/mDNSPosix/nss_mdns.conf.5 +135 -0
- package/android/src/main/jni/mdnsresponder/mDNSPosix/parselog.py +247 -0
- package/android/src/main/jni/mdnsresponder/mDNSResponder.sln +400 -0
- package/android/src/main/jni/mdnsresponder/mDNSShared/CommonServices.h +1537 -0
- package/android/src/main/jni/mdnsresponder/mDNSShared/DebugServices.c +3075 -0
- package/android/src/main/jni/mdnsresponder/mDNSShared/DebugServices.h +1607 -0
- package/android/src/main/jni/mdnsresponder/mDNSShared/GenLinkedList.c +319 -0
- package/android/src/main/jni/mdnsresponder/mDNSShared/GenLinkedList.h +90 -0
- package/android/src/main/jni/mdnsresponder/mDNSShared/PlatformCommon.c +220 -0
- package/android/src/main/jni/mdnsresponder/mDNSShared/PlatformCommon.h +18 -0
- package/android/src/main/jni/mdnsresponder/mDNSShared/dns-sd.1 +194 -0
- package/android/src/main/jni/mdnsresponder/mDNSShared/dns_sd.h +2452 -0
- package/android/src/main/jni/mdnsresponder/mDNSShared/dnsextd.8 +69 -0
- package/android/src/main/jni/mdnsresponder/mDNSShared/dnsextd.c +3146 -0
- package/android/src/main/jni/mdnsresponder/mDNSShared/dnsextd.conf +60 -0
- package/android/src/main/jni/mdnsresponder/mDNSShared/dnsextd.h +163 -0
- package/android/src/main/jni/mdnsresponder/mDNSShared/dnsextd_lexer.l +84 -0
- package/android/src/main/jni/mdnsresponder/mDNSShared/dnsextd_parser.y +585 -0
- package/android/src/main/jni/mdnsresponder/mDNSShared/dnssd_clientlib.c +368 -0
- package/android/src/main/jni/mdnsresponder/mDNSShared/dnssd_clientshim.c +802 -0
- package/android/src/main/jni/mdnsresponder/mDNSShared/dnssd_clientstub.c +1988 -0
- package/android/src/main/jni/mdnsresponder/mDNSShared/dnssd_ipc.c +161 -0
- package/android/src/main/jni/mdnsresponder/mDNSShared/dnssd_ipc.h +219 -0
- package/android/src/main/jni/mdnsresponder/mDNSShared/mDNS.1 +198 -0
- package/android/src/main/jni/mdnsresponder/mDNSShared/mDNSDebug.c +93 -0
- package/android/src/main/jni/mdnsresponder/mDNSShared/mDNSResponder.8 +116 -0
- package/android/src/main/jni/mdnsresponder/mDNSShared/uds_daemon.c +4758 -0
- package/android/src/main/jni/mdnsresponder/mDNSShared/uds_daemon.h +80 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/BrowsingPage.cpp +441 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/BrowsingPage.h +156 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ConfigDialog.cpp +59 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ConfigDialog.h +48 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ConfigPropertySheet.cpp +301 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ConfigPropertySheet.h +105 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ControlPanel.cpp +380 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ControlPanel.def +20 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ControlPanel.h +84 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ControlPanel.rc +141 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ControlPanel.vcproj +727 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ControlPanelDll.rc +123 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ControlPanelExe.cpp +373 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ControlPanelExe.h +48 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ControlPanelExe.rc +123 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ControlPanelExe.vcproj +764 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ControlPanelLocRes.rc +270 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ControlPanelLocRes.vcproj +487 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ControlPanelRes.rc +134 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ControlPanelRes.vcproj +518 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/FourthPage.cpp +197 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/FourthPage.h +87 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/RegistrationPage.cpp +387 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/RegistrationPage.h +75 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/SecondPage.cpp +544 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/SecondPage.h +107 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ServicesPage.cpp +273 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ServicesPage.h +123 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/SharedSecret.cpp +115 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/SharedSecret.h +54 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/res/ControlPanel.dll.manifest +10 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/res/ControlPanel.exe.manifest +17 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/res/ControlPanel.manifest +17 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/res/ControlPanel.rc2 +13 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/res/ControlPanel64.manifest +17 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/res/EnergySaver.ico +0 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/res/controlpanel.ico +0 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/res/failure.ico +0 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/res/success.ico +0 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/resource.h +56 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/stdafx.cpp +20 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/stdafx.h +64 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL/dll.aps +0 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL/dll.rc +102 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL/dllmain.c +112 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL/dnssd.def +48 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL/dnssd.vcproj +472 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL/resource.h +27 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL.NET/AssemblyInfo.cpp +84 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL.NET/PString.h +70 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL.NET/Stdafx.cpp +22 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL.NET/Stdafx.h +33 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL.NET/dnssd_NET.cpp +1234 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL.NET/dnssd_NET.h +1392 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL.NET/dnssd_NET.ico +0 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL.NET/dnssd_NET.rc +113 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL.NET/dnssd_NET.vcproj +446 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL.NET/resource.h +3 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLStub/DLLStub.cpp +693 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLStub/DLLStub.h +52 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLStub/DLLStub.vcproj +324 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DLLX.cpp +208 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DLLX.def +35 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DLLX.idl +491 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DLLX.rc +126 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DLLX.rgs +11 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DLLX.vcproj +625 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DNSSD.cpp +892 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DNSSDEventManager.cpp +31 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DNSSDEventManager.h +133 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DNSSDEventManager.rgs +27 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DNSSDRecord.cpp +101 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DNSSDRecord.h +185 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DNSSDRecord.rgs +27 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DNSSDService.cpp +2095 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DNSSDService.h +429 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DNSSDService.rgs +27 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/StringServices.cpp +344 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/StringServices.h +102 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/TXTRecord.cpp +381 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/TXTRecord.h +203 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/TXTRecord.rgs +27 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/_IDNSSDEvents_CP.h +358 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/dlldatax.c +51 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/dlldatax.h +49 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/resource.h +30 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/stdafx.h +88 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/ApplicationVS2002.sln +21 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/ApplicationVS2002.vcproj +253 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/ApplicationVS2003.sln +21 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/ApplicationVS2003.vcproj +267 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/Resources/Application.ico +0 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/Resources/Application.rc +323 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/Resources/Application.rc2 +20 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/Resources/Resource.h +53 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/Sources/AboutDialog.cpp +71 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/Sources/AboutDialog.h +62 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/Sources/Application.cpp +111 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/Sources/Application.h +68 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/Sources/ChooserDialog.cpp +1426 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/Sources/ChooserDialog.h +131 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/Sources/LoginDialog.cpp +109 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/Sources/LoginDialog.h +53 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/Sources/StdAfx.cpp +18 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/Sources/StdAfx.h +48 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/WindowsCE/Application.vcc +37 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/WindowsCE/Application.vcp +868 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/WindowsCE/Application.vcw +29 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/WindowsCE/Resources/Application.ico +0 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/WindowsCE/Resources/Application.rc +194 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/WindowsCE/Resources/Application.rc2 +13 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/WindowsCE/Resources/newres.h +28 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/WindowsCE/Resources/resource.h +22 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/WindowsCE/Sources/Application.cpp +92 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/WindowsCE/Sources/Application.h +57 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/WindowsCE/Sources/BrowserDialog.cpp +394 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/WindowsCE/Sources/BrowserDialog.h +84 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/WindowsCE/Sources/StdAfx.cpp +18 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/WindowsCE/Sources/StdAfx.h +46 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/Java/Java.vcproj +111 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/Java/jdns_sd.rc +62 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/Java/makefile +143 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/Java/makefile64 +143 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/NSPTool/NSPTool.aps +0 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/NSPTool/NSPTool.c +581 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/NSPTool/NSPTool.rc +103 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/NSPTool/NSPTool.vcproj +409 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/NSPTool/Prefix.h +28 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/NSPTool/resource.h +27 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/PosixCompat.c +128 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/PosixCompat.h +70 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/README.txt +85 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/RegNames.h +57 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/Secret.c +338 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/Secret.h +42 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/EventLog.mc +11 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/EventLogMessages.bin +0 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/Firewall.cpp +484 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/Firewall.h +79 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/Prefix.h +30 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/Service.aps +0 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/Service.c +2669 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/Service.h +30 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/Service.mcp +0 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/Service.rc +114 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/Service.vcproj +562 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/main.c +32 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/res/mDNSResponder.manifest +12 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/res/mDNSResponder64.manifest +12 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/resource.h +17 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/resrc1.h +15 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/VPCDetect.cpp +165 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/VPCDetect.h +36 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/WinServices.cpp +93 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/WinServices.h +34 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/WinVersRes.h +35 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/isocode.h +135 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/loclibrary.c +268 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/loclibrary.h +54 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/mDNSWin32.c +5200 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/mDNSWin32.h +208 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/mdnsNSP/ReadMe.txt +15 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/mdnsNSP/mdnsNSP.aps +0 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/mdnsNSP/mdnsNSP.c +2430 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/mdnsNSP/mdnsNSP.def +24 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/mdnsNSP/mdnsNSP.rc +104 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/mdnsNSP/mdnsNSP.vcproj +457 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/mdnsNSP/resource.h +27 -0
- package/android/src/main/jni/mdnsresponder/mdnsd.rc +7 -0
- package/android/src/main/jni/nameser.h +588 -0
- package/dist/index.js +160 -1
- package/index.d.ts +91 -0
- package/ios/RNZeroconf/RNNetServiceSerializer.m +7 -3
- package/ios/RNZeroconf/RNZeroconf.m +8 -0
- package/package.json +25 -17
- package/src/index.js +183 -0
|
@@ -0,0 +1,1988 @@
|
|
|
1
|
+
/* -*- Mode: C; tab-width: 4 -*-
|
|
2
|
+
*
|
|
3
|
+
* Copyright (c) 2003-2004, Apple Computer, Inc. All rights reserved.
|
|
4
|
+
*
|
|
5
|
+
* Redistribution and use in source and binary forms, with or without
|
|
6
|
+
* modification, are permitted provided that the following conditions are met:
|
|
7
|
+
*
|
|
8
|
+
* 1. Redistributions of source code must retain the above copyright notice,
|
|
9
|
+
* this list of conditions and the following disclaimer.
|
|
10
|
+
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
11
|
+
* this list of conditions and the following disclaimer in the documentation
|
|
12
|
+
* and/or other materials provided with the distribution.
|
|
13
|
+
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of its
|
|
14
|
+
* contributors may be used to endorse or promote products derived from this
|
|
15
|
+
* software without specific prior written permission.
|
|
16
|
+
*
|
|
17
|
+
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
|
|
18
|
+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
19
|
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
20
|
+
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
|
|
21
|
+
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
22
|
+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
23
|
+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
24
|
+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
25
|
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
26
|
+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
#include <errno.h>
|
|
30
|
+
#include <stdlib.h>
|
|
31
|
+
|
|
32
|
+
#include "dnssd_ipc.h"
|
|
33
|
+
|
|
34
|
+
static int gDaemonErr = kDNSServiceErr_NoError;
|
|
35
|
+
|
|
36
|
+
#if defined(_WIN32)
|
|
37
|
+
|
|
38
|
+
#define _SSIZE_T
|
|
39
|
+
#include <CommonServices.h>
|
|
40
|
+
#include <DebugServices.h>
|
|
41
|
+
#include <winsock2.h>
|
|
42
|
+
#include <ws2tcpip.h>
|
|
43
|
+
#include <windows.h>
|
|
44
|
+
#include <stdarg.h>
|
|
45
|
+
|
|
46
|
+
#define sockaddr_mdns sockaddr_in
|
|
47
|
+
#define AF_MDNS AF_INET
|
|
48
|
+
|
|
49
|
+
// Disable warning: "'type cast' : from data pointer 'void *' to function pointer"
|
|
50
|
+
#pragma warning(disable:4055)
|
|
51
|
+
|
|
52
|
+
// Disable warning: "nonstandard extension, function/data pointer conversion in expression"
|
|
53
|
+
#pragma warning(disable:4152)
|
|
54
|
+
|
|
55
|
+
extern BOOL IsSystemServiceDisabled();
|
|
56
|
+
|
|
57
|
+
#define sleep(X) Sleep((X) * 1000)
|
|
58
|
+
|
|
59
|
+
static int g_initWinsock = 0;
|
|
60
|
+
#define LOG_WARNING kDebugLevelWarning
|
|
61
|
+
#define LOG_INFO kDebugLevelInfo
|
|
62
|
+
static void syslog( int priority, const char * message, ...)
|
|
63
|
+
{
|
|
64
|
+
va_list args;
|
|
65
|
+
int len;
|
|
66
|
+
char * buffer;
|
|
67
|
+
DWORD err = WSAGetLastError();
|
|
68
|
+
(void) priority;
|
|
69
|
+
va_start( args, message );
|
|
70
|
+
len = _vscprintf( message, args ) + 1;
|
|
71
|
+
buffer = malloc( len * sizeof(char) );
|
|
72
|
+
if ( buffer ) { vsprintf( buffer, message, args ); OutputDebugString( buffer ); free( buffer ); }
|
|
73
|
+
WSASetLastError( err );
|
|
74
|
+
}
|
|
75
|
+
#else
|
|
76
|
+
|
|
77
|
+
#ifndef __ANDROID__
|
|
78
|
+
#include <sys/fcntl.h> // For O_RDWR etc.
|
|
79
|
+
#else
|
|
80
|
+
#include <fcntl.h>
|
|
81
|
+
#define LOG_TAG "libmdns"
|
|
82
|
+
#endif // !__ANDROID__
|
|
83
|
+
#include <sys/time.h>
|
|
84
|
+
#include <sys/socket.h>
|
|
85
|
+
#include <syslog.h>
|
|
86
|
+
|
|
87
|
+
#define sockaddr_mdns sockaddr_un
|
|
88
|
+
#define AF_MDNS AF_LOCAL
|
|
89
|
+
|
|
90
|
+
#endif
|
|
91
|
+
|
|
92
|
+
// <rdar://problem/4096913> Specifies how many times we'll try and connect to the server.
|
|
93
|
+
|
|
94
|
+
#define DNSSD_CLIENT_MAXTRIES 4
|
|
95
|
+
|
|
96
|
+
// Uncomment the line below to use the old error return mechanism of creating a temporary named socket (e.g. in /var/tmp)
|
|
97
|
+
//#define USE_NAMED_ERROR_RETURN_SOCKET 1
|
|
98
|
+
|
|
99
|
+
#define DNSSD_CLIENT_TIMEOUT 10 // In seconds
|
|
100
|
+
|
|
101
|
+
#ifndef CTL_PATH_PREFIX
|
|
102
|
+
#define CTL_PATH_PREFIX "/var/tmp/dnssd_result_socket."
|
|
103
|
+
#endif
|
|
104
|
+
|
|
105
|
+
typedef struct
|
|
106
|
+
{
|
|
107
|
+
ipc_msg_hdr ipc_hdr;
|
|
108
|
+
DNSServiceFlags cb_flags;
|
|
109
|
+
uint32_t cb_interface;
|
|
110
|
+
DNSServiceErrorType cb_err;
|
|
111
|
+
} CallbackHeader;
|
|
112
|
+
|
|
113
|
+
typedef struct _DNSServiceRef_t DNSServiceOp;
|
|
114
|
+
typedef struct _DNSRecordRef_t DNSRecord;
|
|
115
|
+
|
|
116
|
+
// client stub callback to process message from server and deliver results to client application
|
|
117
|
+
typedef void (*ProcessReplyFn)(DNSServiceOp *const sdr, const CallbackHeader *const cbh, const char *msg, const char *const end);
|
|
118
|
+
|
|
119
|
+
#define ValidatorBits 0x12345678
|
|
120
|
+
#define DNSServiceRefValid(X) (dnssd_SocketValid((X)->sockfd) && (((X)->sockfd ^ (X)->validator) == ValidatorBits))
|
|
121
|
+
|
|
122
|
+
// When using kDNSServiceFlagsShareConnection, there is one primary _DNSServiceOp_t, and zero or more subordinates
|
|
123
|
+
// For the primary, the 'next' field points to the first subordinate, and its 'next' field points to the next, and so on.
|
|
124
|
+
// For the primary, the 'primary' field is NULL; for subordinates the 'primary' field points back to the associated primary
|
|
125
|
+
//
|
|
126
|
+
// _DNS_SD_LIBDISPATCH is defined where libdispatch/GCD is available. This does not mean that the application will use the
|
|
127
|
+
// DNSServiceSetDispatchQueue API. Hence any new code guarded with _DNS_SD_LIBDISPATCH should still be backwards compatible.
|
|
128
|
+
struct _DNSServiceRef_t
|
|
129
|
+
{
|
|
130
|
+
DNSServiceOp *next; // For shared connection
|
|
131
|
+
DNSServiceOp *primary; // For shared connection
|
|
132
|
+
dnssd_sock_t sockfd; // Connected socket between client and daemon
|
|
133
|
+
dnssd_sock_t validator; // Used to detect memory corruption, double disposals, etc.
|
|
134
|
+
client_context_t uid; // For shared connection requests, each subordinate DNSServiceRef has its own ID,
|
|
135
|
+
// unique within the scope of the same shared parent DNSServiceRef
|
|
136
|
+
uint32_t op; // request_op_t or reply_op_t
|
|
137
|
+
uint32_t max_index; // Largest assigned record index - 0 if no additional records registered
|
|
138
|
+
uint32_t logcounter; // Counter used to control number of syslog messages we write
|
|
139
|
+
int *moreptr; // Set while DNSServiceProcessResult working on this particular DNSServiceRef
|
|
140
|
+
ProcessReplyFn ProcessReply; // Function pointer to the code to handle received messages
|
|
141
|
+
void *AppCallback; // Client callback function and context
|
|
142
|
+
void *AppContext;
|
|
143
|
+
DNSRecord *rec;
|
|
144
|
+
#if _DNS_SD_LIBDISPATCH
|
|
145
|
+
dispatch_source_t disp_source;
|
|
146
|
+
dispatch_queue_t disp_queue;
|
|
147
|
+
#endif
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
struct _DNSRecordRef_t
|
|
151
|
+
{
|
|
152
|
+
DNSRecord *recnext;
|
|
153
|
+
void *AppContext;
|
|
154
|
+
DNSServiceRegisterRecordReply AppCallback;
|
|
155
|
+
DNSRecordRef recref;
|
|
156
|
+
uint32_t record_index; // index is unique to the ServiceDiscoveryRef
|
|
157
|
+
DNSServiceOp *sdr;
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
// Write len bytes. Return 0 on success, -1 on error
|
|
161
|
+
static int write_all(dnssd_sock_t sd, char *buf, size_t len)
|
|
162
|
+
{
|
|
163
|
+
// Don't use "MSG_WAITALL"; it returns "Invalid argument" on some Linux versions; use an explicit while() loop instead.
|
|
164
|
+
//if (send(sd, buf, len, MSG_WAITALL) != len) return -1;
|
|
165
|
+
while (len)
|
|
166
|
+
{
|
|
167
|
+
ssize_t num_written = send(sd, buf, (long)len, 0);
|
|
168
|
+
if (num_written < 0 || (size_t)num_written > len)
|
|
169
|
+
{
|
|
170
|
+
// Should never happen. If it does, it indicates some OS bug,
|
|
171
|
+
// or that the mDNSResponder daemon crashed (which should never happen).
|
|
172
|
+
#if !defined(__ppc__) && defined(SO_ISDEFUNCT)
|
|
173
|
+
int defunct;
|
|
174
|
+
socklen_t dlen = sizeof (defunct);
|
|
175
|
+
if (getsockopt(sd, SOL_SOCKET, SO_ISDEFUNCT, &defunct, &dlen) < 0)
|
|
176
|
+
syslog(LOG_WARNING, "dnssd_clientstub write_all: SO_ISDEFUNCT failed %d %s", dnssd_errno, dnssd_strerror(dnssd_errno));
|
|
177
|
+
if (!defunct)
|
|
178
|
+
syslog(LOG_WARNING, "dnssd_clientstub write_all(%d) failed %ld/%ld %d %s", sd,
|
|
179
|
+
(long)num_written, (long)len,
|
|
180
|
+
(num_written < 0) ? dnssd_errno : 0,
|
|
181
|
+
(num_written < 0) ? dnssd_strerror(dnssd_errno) : "");
|
|
182
|
+
else
|
|
183
|
+
syslog(LOG_INFO, "dnssd_clientstub write_all(%d) DEFUNCT", sd);
|
|
184
|
+
#else
|
|
185
|
+
syslog(LOG_WARNING, "dnssd_clientstub write_all(%d) failed %ld/%ld %d %s", sd,
|
|
186
|
+
(long)num_written, (long)len,
|
|
187
|
+
(num_written < 0) ? dnssd_errno : 0,
|
|
188
|
+
(num_written < 0) ? dnssd_strerror(dnssd_errno) : "");
|
|
189
|
+
#endif
|
|
190
|
+
return -1;
|
|
191
|
+
}
|
|
192
|
+
buf += num_written;
|
|
193
|
+
len -= num_written;
|
|
194
|
+
}
|
|
195
|
+
return 0;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
enum { read_all_success = 0, read_all_fail = -1, read_all_wouldblock = -2 };
|
|
199
|
+
|
|
200
|
+
// Read len bytes. Return 0 on success, read_all_fail on error, or read_all_wouldblock for
|
|
201
|
+
static int read_all(dnssd_sock_t sd, char *buf, int len)
|
|
202
|
+
{
|
|
203
|
+
// Don't use "MSG_WAITALL"; it returns "Invalid argument" on some Linux versions; use an explicit while() loop instead.
|
|
204
|
+
//if (recv(sd, buf, len, MSG_WAITALL) != len) return -1;
|
|
205
|
+
|
|
206
|
+
while (len)
|
|
207
|
+
{
|
|
208
|
+
ssize_t num_read = recv(sd, buf, len, 0);
|
|
209
|
+
// It is valid to get an interrupted system call error e.g., somebody attaching
|
|
210
|
+
// in a debugger, retry without failing
|
|
211
|
+
if ((num_read < 0) && (errno == EINTR)) { syslog(LOG_INFO, "dnssd_clientstub read_all: EINTR continue"); continue; }
|
|
212
|
+
if ((num_read == 0) || (num_read < 0) || (num_read > len))
|
|
213
|
+
{
|
|
214
|
+
int printWarn = 0;
|
|
215
|
+
int defunct = 0;
|
|
216
|
+
// Should never happen. If it does, it indicates some OS bug,
|
|
217
|
+
// or that the mDNSResponder daemon crashed (which should never happen).
|
|
218
|
+
#if defined(WIN32)
|
|
219
|
+
// <rdar://problem/7481776> Suppress logs for "A non-blocking socket operation
|
|
220
|
+
// could not be completed immediately"
|
|
221
|
+
if (WSAGetLastError() != WSAEWOULDBLOCK)
|
|
222
|
+
printWarn = 1;
|
|
223
|
+
#endif
|
|
224
|
+
#if !defined(__ppc__) && defined(SO_ISDEFUNCT)
|
|
225
|
+
{
|
|
226
|
+
socklen_t dlen = sizeof (defunct);
|
|
227
|
+
if (getsockopt(sd, SOL_SOCKET, SO_ISDEFUNCT, &defunct, &dlen) < 0)
|
|
228
|
+
syslog(LOG_WARNING, "dnssd_clientstub read_all: SO_ISDEFUNCT failed %d %s", dnssd_errno, dnssd_strerror(dnssd_errno));
|
|
229
|
+
}
|
|
230
|
+
if (!defunct)
|
|
231
|
+
printWarn = 1;
|
|
232
|
+
#endif
|
|
233
|
+
if (printWarn)
|
|
234
|
+
syslog(LOG_WARNING, "dnssd_clientstub read_all(%d) failed %ld/%ld %d %s", sd,
|
|
235
|
+
(long)num_read, (long)len,
|
|
236
|
+
(num_read < 0) ? dnssd_errno : 0,
|
|
237
|
+
(num_read < 0) ? dnssd_strerror(dnssd_errno) : "");
|
|
238
|
+
else if (defunct)
|
|
239
|
+
syslog(LOG_INFO, "dnssd_clientstub read_all(%d) DEFUNCT", sd);
|
|
240
|
+
return (num_read < 0 && dnssd_errno == dnssd_EWOULDBLOCK) ? read_all_wouldblock : read_all_fail;
|
|
241
|
+
}
|
|
242
|
+
buf += num_read;
|
|
243
|
+
len -= num_read;
|
|
244
|
+
}
|
|
245
|
+
return read_all_success;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// Returns 1 if more bytes remain to be read on socket descriptor sd, 0 otherwise
|
|
249
|
+
static int more_bytes(dnssd_sock_t sd)
|
|
250
|
+
{
|
|
251
|
+
struct timeval tv = { 0, 0 };
|
|
252
|
+
fd_set readfds;
|
|
253
|
+
fd_set *fs;
|
|
254
|
+
int ret;
|
|
255
|
+
|
|
256
|
+
if (sd < FD_SETSIZE)
|
|
257
|
+
{
|
|
258
|
+
fs = &readfds;
|
|
259
|
+
FD_ZERO(fs);
|
|
260
|
+
}
|
|
261
|
+
else
|
|
262
|
+
{
|
|
263
|
+
// Compute the number of integers needed for storing "sd". Internally fd_set is stored
|
|
264
|
+
// as an array of ints with one bit for each fd and hence we need to compute
|
|
265
|
+
// the number of ints needed rather than the number of bytes. If "sd" is 32, we need
|
|
266
|
+
// two ints and not just one.
|
|
267
|
+
int nfdbits = sizeof (int) * 8;
|
|
268
|
+
int nints = (sd/nfdbits) + 1;
|
|
269
|
+
fs = (fd_set *)calloc(nints, sizeof(int));
|
|
270
|
+
if (fs == NULL) { syslog(LOG_WARNING, "dnssd_clientstub more_bytes: malloc failed"); return 0; }
|
|
271
|
+
}
|
|
272
|
+
FD_SET(sd, fs);
|
|
273
|
+
ret = select((int)sd+1, fs, (fd_set*)NULL, (fd_set*)NULL, &tv);
|
|
274
|
+
if (fs != &readfds) free(fs);
|
|
275
|
+
return (ret > 0);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// Wait for daemon to write to socket
|
|
279
|
+
static int wait_for_daemon(dnssd_sock_t sock, int timeout)
|
|
280
|
+
{
|
|
281
|
+
#ifndef WIN32
|
|
282
|
+
// At this point the next operation (accept() or read()) on this socket may block for a few milliseconds waiting
|
|
283
|
+
// for the daemon to respond, but that's okay -- the daemon is a trusted service and we know if won't take more
|
|
284
|
+
// than a few milliseconds to respond. So we'll forego checking for readability of the socket.
|
|
285
|
+
(void) sock;
|
|
286
|
+
(void) timeout;
|
|
287
|
+
#else
|
|
288
|
+
// Windows on the other hand suffers from 3rd party software (primarily 3rd party firewall software) that
|
|
289
|
+
// interferes with proper functioning of the TCP protocol stack. Because of this and because we depend on TCP
|
|
290
|
+
// to communicate with the system service, we want to make sure that the next operation on this socket (accept() or
|
|
291
|
+
// read()) doesn't block indefinitely.
|
|
292
|
+
if (!gDaemonErr)
|
|
293
|
+
{
|
|
294
|
+
struct timeval tv;
|
|
295
|
+
fd_set set;
|
|
296
|
+
|
|
297
|
+
FD_ZERO(&set);
|
|
298
|
+
FD_SET(sock, &set);
|
|
299
|
+
tv.tv_sec = timeout;
|
|
300
|
+
tv.tv_usec = 0;
|
|
301
|
+
if (!select((int)(sock + 1), &set, NULL, NULL, &tv))
|
|
302
|
+
{
|
|
303
|
+
syslog(LOG_WARNING, "dnssd_clientstub wait_for_daemon timed out");
|
|
304
|
+
gDaemonErr = kDNSServiceErr_Timeout;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
#endif
|
|
308
|
+
return gDaemonErr;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/* create_hdr
|
|
312
|
+
*
|
|
313
|
+
* allocate and initialize an ipc message header. Value of len should initially be the
|
|
314
|
+
* length of the data, and is set to the value of the data plus the header. data_start
|
|
315
|
+
* is set to point to the beginning of the data section. SeparateReturnSocket should be
|
|
316
|
+
* non-zero for calls that can't receive an immediate error return value on their primary
|
|
317
|
+
* socket, and therefore require a separate return path for the error code result.
|
|
318
|
+
* if zero, the path to a control socket is appended at the beginning of the message buffer.
|
|
319
|
+
* data_start is set past this string.
|
|
320
|
+
*/
|
|
321
|
+
static ipc_msg_hdr *create_hdr(uint32_t op, size_t *len, char **data_start, int SeparateReturnSocket, DNSServiceOp *ref)
|
|
322
|
+
{
|
|
323
|
+
char *msg = NULL;
|
|
324
|
+
ipc_msg_hdr *hdr;
|
|
325
|
+
int datalen;
|
|
326
|
+
#if !defined(USE_TCP_LOOPBACK)
|
|
327
|
+
char ctrl_path[64] = ""; // "/var/tmp/dnssd_result_socket.xxxxxxxxxx-xxx-xxxxxx"
|
|
328
|
+
#endif
|
|
329
|
+
|
|
330
|
+
if (SeparateReturnSocket)
|
|
331
|
+
{
|
|
332
|
+
#if defined(USE_TCP_LOOPBACK)
|
|
333
|
+
*len += 2; // Allocate space for two-byte port number
|
|
334
|
+
#elif defined(USE_NAMED_ERROR_RETURN_SOCKET)
|
|
335
|
+
struct timeval tv;
|
|
336
|
+
if (gettimeofday(&tv, NULL) < 0)
|
|
337
|
+
{ syslog(LOG_WARNING, "dnssd_clientstub create_hdr: gettimeofday failed %d %s", dnssd_errno, dnssd_strerror(dnssd_errno)); return NULL; }
|
|
338
|
+
sprintf(ctrl_path, "%s%d-%.3lx-%.6lu", CTL_PATH_PREFIX, (int)getpid(),
|
|
339
|
+
(unsigned long)(tv.tv_sec & 0xFFF), (unsigned long)(tv.tv_usec));
|
|
340
|
+
*len += strlen(ctrl_path) + 1;
|
|
341
|
+
#else
|
|
342
|
+
*len += 1; // Allocate space for single zero byte (empty C string)
|
|
343
|
+
#endif
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
datalen = (int) *len;
|
|
347
|
+
*len += sizeof(ipc_msg_hdr);
|
|
348
|
+
|
|
349
|
+
// Write message to buffer
|
|
350
|
+
msg = malloc(*len);
|
|
351
|
+
if (!msg) { syslog(LOG_WARNING, "dnssd_clientstub create_hdr: malloc failed"); return NULL; }
|
|
352
|
+
|
|
353
|
+
memset(msg, 0, *len);
|
|
354
|
+
hdr = (ipc_msg_hdr *)msg;
|
|
355
|
+
hdr->version = VERSION;
|
|
356
|
+
hdr->datalen = datalen;
|
|
357
|
+
hdr->ipc_flags = 0;
|
|
358
|
+
hdr->op = op;
|
|
359
|
+
hdr->client_context = ref->uid;
|
|
360
|
+
hdr->reg_index = 0;
|
|
361
|
+
*data_start = msg + sizeof(ipc_msg_hdr);
|
|
362
|
+
#if defined(USE_TCP_LOOPBACK)
|
|
363
|
+
// Put dummy data in for the port, since we don't know what it is yet.
|
|
364
|
+
// The data will get filled in before we send the message. This happens in deliver_request().
|
|
365
|
+
if (SeparateReturnSocket) put_uint16(0, data_start);
|
|
366
|
+
#else
|
|
367
|
+
if (SeparateReturnSocket) put_string(ctrl_path, data_start);
|
|
368
|
+
#endif
|
|
369
|
+
return hdr;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
static void FreeDNSRecords(DNSServiceOp *sdRef)
|
|
373
|
+
{
|
|
374
|
+
DNSRecord *rec = sdRef->rec;
|
|
375
|
+
while (rec)
|
|
376
|
+
{
|
|
377
|
+
DNSRecord *next = rec->recnext;
|
|
378
|
+
free(rec);
|
|
379
|
+
rec = next;
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
static void FreeDNSServiceOp(DNSServiceOp *x)
|
|
384
|
+
{
|
|
385
|
+
// We don't use our DNSServiceRefValid macro here because if we're cleaning up after a socket() call failed
|
|
386
|
+
// then sockfd could legitimately contain a failing value (e.g. dnssd_InvalidSocket)
|
|
387
|
+
if ((x->sockfd ^ x->validator) != ValidatorBits)
|
|
388
|
+
syslog(LOG_WARNING, "dnssd_clientstub attempt to dispose invalid DNSServiceRef %p %08X %08X", x, x->sockfd, x->validator);
|
|
389
|
+
else
|
|
390
|
+
{
|
|
391
|
+
x->next = NULL;
|
|
392
|
+
x->primary = NULL;
|
|
393
|
+
x->sockfd = dnssd_InvalidSocket;
|
|
394
|
+
x->validator = 0xDDDDDDDD;
|
|
395
|
+
x->op = request_op_none;
|
|
396
|
+
x->max_index = 0;
|
|
397
|
+
x->logcounter = 0;
|
|
398
|
+
x->moreptr = NULL;
|
|
399
|
+
x->ProcessReply = NULL;
|
|
400
|
+
x->AppCallback = NULL;
|
|
401
|
+
x->AppContext = NULL;
|
|
402
|
+
#if _DNS_SD_LIBDISPATCH
|
|
403
|
+
if (x->disp_source) dispatch_release(x->disp_source);
|
|
404
|
+
x->disp_source = NULL;
|
|
405
|
+
x->disp_queue = NULL;
|
|
406
|
+
#endif
|
|
407
|
+
// DNSRecords may have been added to subordinate sdRef e.g., DNSServiceRegister/DNSServiceAddRecord
|
|
408
|
+
// or on the main sdRef e.g., DNSServiceCreateConnection/DNSServiveRegisterRecord. DNSRecords may have
|
|
409
|
+
// been freed if the application called DNSRemoveRecord
|
|
410
|
+
FreeDNSRecords(x);
|
|
411
|
+
free(x);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
// Return a connected service ref (deallocate with DNSServiceRefDeallocate)
|
|
416
|
+
static DNSServiceErrorType ConnectToServer(DNSServiceRef *ref, DNSServiceFlags flags, uint32_t op, ProcessReplyFn ProcessReply, void *AppCallback, void *AppContext)
|
|
417
|
+
{
|
|
418
|
+
#if APPLE_OSX_mDNSResponder
|
|
419
|
+
int NumTries = DNSSD_CLIENT_MAXTRIES;
|
|
420
|
+
#else
|
|
421
|
+
int NumTries = 0;
|
|
422
|
+
#endif
|
|
423
|
+
|
|
424
|
+
dnssd_sockaddr_t saddr;
|
|
425
|
+
DNSServiceOp *sdr;
|
|
426
|
+
|
|
427
|
+
if (!ref) { syslog(LOG_WARNING, "dnssd_clientstub DNSService operation with NULL DNSServiceRef"); return kDNSServiceErr_BadParam; }
|
|
428
|
+
|
|
429
|
+
if (flags & kDNSServiceFlagsShareConnection)
|
|
430
|
+
{
|
|
431
|
+
if (!*ref)
|
|
432
|
+
{
|
|
433
|
+
syslog(LOG_WARNING, "dnssd_clientstub kDNSServiceFlagsShareConnection used with NULL DNSServiceRef");
|
|
434
|
+
return kDNSServiceErr_BadParam;
|
|
435
|
+
}
|
|
436
|
+
if (!DNSServiceRefValid(*ref) || (*ref)->op != connection_request || (*ref)->primary)
|
|
437
|
+
{
|
|
438
|
+
syslog(LOG_WARNING, "dnssd_clientstub kDNSServiceFlagsShareConnection used with invalid DNSServiceRef %p %08X %08X",
|
|
439
|
+
(*ref), (*ref)->sockfd, (*ref)->validator);
|
|
440
|
+
*ref = NULL;
|
|
441
|
+
return kDNSServiceErr_BadReference;
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
#if defined(_WIN32)
|
|
446
|
+
if (!g_initWinsock)
|
|
447
|
+
{
|
|
448
|
+
WSADATA wsaData;
|
|
449
|
+
g_initWinsock = 1;
|
|
450
|
+
if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) { *ref = NULL; return kDNSServiceErr_ServiceNotRunning; }
|
|
451
|
+
}
|
|
452
|
+
// <rdar://problem/4096913> If the system service is disabled, we only want to try to connect once
|
|
453
|
+
if (IsSystemServiceDisabled()) NumTries = DNSSD_CLIENT_MAXTRIES;
|
|
454
|
+
#endif
|
|
455
|
+
|
|
456
|
+
sdr = malloc(sizeof(DNSServiceOp));
|
|
457
|
+
if (!sdr) { syslog(LOG_WARNING, "dnssd_clientstub ConnectToServer: malloc failed"); *ref = NULL; return kDNSServiceErr_NoMemory; }
|
|
458
|
+
sdr->next = NULL;
|
|
459
|
+
sdr->primary = NULL;
|
|
460
|
+
sdr->sockfd = dnssd_InvalidSocket;
|
|
461
|
+
sdr->validator = sdr->sockfd ^ ValidatorBits;
|
|
462
|
+
sdr->op = op;
|
|
463
|
+
sdr->max_index = 0;
|
|
464
|
+
sdr->logcounter = 0;
|
|
465
|
+
sdr->moreptr = NULL;
|
|
466
|
+
sdr->uid.u32[0] = 0;
|
|
467
|
+
sdr->uid.u32[1] = 0;
|
|
468
|
+
sdr->ProcessReply = ProcessReply;
|
|
469
|
+
sdr->AppCallback = AppCallback;
|
|
470
|
+
sdr->AppContext = AppContext;
|
|
471
|
+
sdr->rec = NULL;
|
|
472
|
+
#if _DNS_SD_LIBDISPATCH
|
|
473
|
+
sdr->disp_source = NULL;
|
|
474
|
+
sdr->disp_queue = NULL;
|
|
475
|
+
#endif
|
|
476
|
+
|
|
477
|
+
if (flags & kDNSServiceFlagsShareConnection)
|
|
478
|
+
{
|
|
479
|
+
DNSServiceOp **p = &(*ref)->next; // Append ourselves to end of primary's list
|
|
480
|
+
while (*p) p = &(*p)->next;
|
|
481
|
+
*p = sdr;
|
|
482
|
+
// Preincrement counter before we use it -- it helps with debugging if we know the all-zeroes ID should never appear
|
|
483
|
+
if (++(*ref)->uid.u32[0] == 0) ++(*ref)->uid.u32[1]; // In parent DNSServiceOp increment UID counter
|
|
484
|
+
sdr->primary = *ref; // Set our primary pointer
|
|
485
|
+
sdr->sockfd = (*ref)->sockfd; // Inherit primary's socket
|
|
486
|
+
sdr->validator = (*ref)->validator;
|
|
487
|
+
sdr->uid = (*ref)->uid;
|
|
488
|
+
//printf("ConnectToServer sharing socket %d\n", sdr->sockfd);
|
|
489
|
+
}
|
|
490
|
+
else
|
|
491
|
+
{
|
|
492
|
+
#ifdef SO_NOSIGPIPE
|
|
493
|
+
const unsigned long optval = 1;
|
|
494
|
+
#endif
|
|
495
|
+
*ref = NULL;
|
|
496
|
+
sdr->sockfd = socket(AF_DNSSD, SOCK_STREAM, 0);
|
|
497
|
+
sdr->validator = sdr->sockfd ^ ValidatorBits;
|
|
498
|
+
if (!dnssd_SocketValid(sdr->sockfd))
|
|
499
|
+
{
|
|
500
|
+
syslog(LOG_WARNING, "dnssd_clientstub ConnectToServer: socket failed %d %s", dnssd_errno, dnssd_strerror(dnssd_errno));
|
|
501
|
+
FreeDNSServiceOp(sdr);
|
|
502
|
+
return kDNSServiceErr_NoMemory;
|
|
503
|
+
}
|
|
504
|
+
#ifdef SO_NOSIGPIPE
|
|
505
|
+
// Some environments (e.g. OS X) support turning off SIGPIPE for a socket
|
|
506
|
+
if (setsockopt(sdr->sockfd, SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval)) < 0)
|
|
507
|
+
syslog(LOG_WARNING, "dnssd_clientstub ConnectToServer: SO_NOSIGPIPE failed %d %s", dnssd_errno, dnssd_strerror(dnssd_errno));
|
|
508
|
+
#endif
|
|
509
|
+
#if defined(USE_TCP_LOOPBACK)
|
|
510
|
+
saddr.sin_family = AF_INET;
|
|
511
|
+
saddr.sin_addr.s_addr = inet_addr(MDNS_TCP_SERVERADDR);
|
|
512
|
+
saddr.sin_port = htons(MDNS_TCP_SERVERPORT);
|
|
513
|
+
#else
|
|
514
|
+
saddr.sun_family = AF_LOCAL;
|
|
515
|
+
strcpy(saddr.sun_path, MDNS_UDS_SERVERPATH);
|
|
516
|
+
#if !defined(__ppc__) && defined(SO_DEFUNCTOK)
|
|
517
|
+
{
|
|
518
|
+
int defunct = 1;
|
|
519
|
+
if (setsockopt(sdr->sockfd, SOL_SOCKET, SO_DEFUNCTOK, &defunct, sizeof(defunct)) < 0)
|
|
520
|
+
syslog(LOG_WARNING, "dnssd_clientstub ConnectToServer: SO_DEFUNCTOK failed %d %s", dnssd_errno, dnssd_strerror(dnssd_errno));
|
|
521
|
+
}
|
|
522
|
+
#endif
|
|
523
|
+
#endif
|
|
524
|
+
|
|
525
|
+
while (1)
|
|
526
|
+
{
|
|
527
|
+
int err = connect(sdr->sockfd, (struct sockaddr *) &saddr, sizeof(saddr));
|
|
528
|
+
if (!err) break; // If we succeeded, return sdr
|
|
529
|
+
// If we failed, then it may be because the daemon is still launching.
|
|
530
|
+
// This can happen for processes that launch early in the boot process, while the
|
|
531
|
+
// daemon is still coming up. Rather than fail here, we'll wait a bit and try again.
|
|
532
|
+
// If, after four seconds, we still can't connect to the daemon,
|
|
533
|
+
// then we give up and return a failure code.
|
|
534
|
+
if (++NumTries < DNSSD_CLIENT_MAXTRIES) sleep(1); // Sleep a bit, then try again
|
|
535
|
+
else { dnssd_close(sdr->sockfd); FreeDNSServiceOp(sdr); return kDNSServiceErr_ServiceNotRunning; }
|
|
536
|
+
}
|
|
537
|
+
//printf("ConnectToServer opened socket %d\n", sdr->sockfd);
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
*ref = sdr;
|
|
541
|
+
return kDNSServiceErr_NoError;
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
#define deliver_request_bailout(MSG) \
|
|
545
|
+
do { syslog(LOG_WARNING, "dnssd_clientstub deliver_request: %s failed %d (%s)", (MSG), dnssd_errno, dnssd_strerror(dnssd_errno)); goto cleanup; } while(0)
|
|
546
|
+
|
|
547
|
+
static DNSServiceErrorType deliver_request(ipc_msg_hdr *hdr, DNSServiceOp *sdr)
|
|
548
|
+
{
|
|
549
|
+
uint32_t datalen = hdr->datalen; // We take a copy here because we're going to convert hdr->datalen to network byte order
|
|
550
|
+
#if defined(USE_TCP_LOOPBACK) || defined(USE_NAMED_ERROR_RETURN_SOCKET)
|
|
551
|
+
char *const data = (char *)hdr + sizeof(ipc_msg_hdr);
|
|
552
|
+
#endif
|
|
553
|
+
dnssd_sock_t listenfd = dnssd_InvalidSocket, errsd = dnssd_InvalidSocket;
|
|
554
|
+
DNSServiceErrorType err = kDNSServiceErr_Unknown; // Default for the "goto cleanup" cases
|
|
555
|
+
int MakeSeparateReturnSocket = 0;
|
|
556
|
+
|
|
557
|
+
// Note: need to check hdr->op, not sdr->op.
|
|
558
|
+
// hdr->op contains the code for the specific operation we're currently doing, whereas sdr->op
|
|
559
|
+
// contains the original parent DNSServiceOp (e.g. for an add_record_request, hdr->op will be
|
|
560
|
+
// add_record_request but the parent sdr->op will be connection_request or reg_service_request)
|
|
561
|
+
if (sdr->primary ||
|
|
562
|
+
hdr->op == reg_record_request || hdr->op == add_record_request || hdr->op == update_record_request || hdr->op == remove_record_request)
|
|
563
|
+
MakeSeparateReturnSocket = 1;
|
|
564
|
+
|
|
565
|
+
if (!DNSServiceRefValid(sdr))
|
|
566
|
+
{
|
|
567
|
+
syslog(LOG_WARNING, "dnssd_clientstub deliver_request: invalid DNSServiceRef %p %08X %08X", sdr, sdr->sockfd, sdr->validator);
|
|
568
|
+
return kDNSServiceErr_BadReference;
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
if (!hdr) { syslog(LOG_WARNING, "dnssd_clientstub deliver_request: !hdr"); return kDNSServiceErr_Unknown; }
|
|
572
|
+
|
|
573
|
+
if (MakeSeparateReturnSocket)
|
|
574
|
+
{
|
|
575
|
+
#if defined(USE_TCP_LOOPBACK)
|
|
576
|
+
{
|
|
577
|
+
union { uint16_t s; u_char b[2]; } port;
|
|
578
|
+
dnssd_sockaddr_t caddr;
|
|
579
|
+
dnssd_socklen_t len = (dnssd_socklen_t) sizeof(caddr);
|
|
580
|
+
listenfd = socket(AF_DNSSD, SOCK_STREAM, 0);
|
|
581
|
+
if (!dnssd_SocketValid(listenfd)) deliver_request_bailout("TCP socket");
|
|
582
|
+
|
|
583
|
+
caddr.sin_family = AF_INET;
|
|
584
|
+
caddr.sin_port = 0;
|
|
585
|
+
caddr.sin_addr.s_addr = inet_addr(MDNS_TCP_SERVERADDR);
|
|
586
|
+
if (bind(listenfd, (struct sockaddr*) &caddr, sizeof(caddr)) < 0) deliver_request_bailout("TCP bind");
|
|
587
|
+
if (getsockname(listenfd, (struct sockaddr*) &caddr, &len) < 0) deliver_request_bailout("TCP getsockname");
|
|
588
|
+
if (listen(listenfd, 1) < 0) deliver_request_bailout("TCP listen");
|
|
589
|
+
port.s = caddr.sin_port;
|
|
590
|
+
data[0] = port.b[0]; // don't switch the byte order, as the
|
|
591
|
+
data[1] = port.b[1]; // daemon expects it in network byte order
|
|
592
|
+
}
|
|
593
|
+
#elif defined(USE_NAMED_ERROR_RETURN_SOCKET)
|
|
594
|
+
{
|
|
595
|
+
mode_t mask;
|
|
596
|
+
int bindresult;
|
|
597
|
+
dnssd_sockaddr_t caddr;
|
|
598
|
+
listenfd = socket(AF_DNSSD, SOCK_STREAM, 0);
|
|
599
|
+
if (!dnssd_SocketValid(listenfd)) deliver_request_bailout("USE_NAMED_ERROR_RETURN_SOCKET socket");
|
|
600
|
+
|
|
601
|
+
caddr.sun_family = AF_LOCAL;
|
|
602
|
+
// According to Stevens (section 3.2), there is no portable way to
|
|
603
|
+
// determine whether sa_len is defined on a particular platform.
|
|
604
|
+
#ifndef NOT_HAVE_SA_LEN
|
|
605
|
+
caddr.sun_len = sizeof(struct sockaddr_un);
|
|
606
|
+
#endif
|
|
607
|
+
strcpy(caddr.sun_path, data);
|
|
608
|
+
mask = umask(0);
|
|
609
|
+
bindresult = bind(listenfd, (struct sockaddr *)&caddr, sizeof(caddr));
|
|
610
|
+
umask(mask);
|
|
611
|
+
if (bindresult < 0) deliver_request_bailout("USE_NAMED_ERROR_RETURN_SOCKET bind");
|
|
612
|
+
if (listen(listenfd, 1) < 0) deliver_request_bailout("USE_NAMED_ERROR_RETURN_SOCKET listen");
|
|
613
|
+
}
|
|
614
|
+
#else
|
|
615
|
+
{
|
|
616
|
+
dnssd_sock_t sp[2];
|
|
617
|
+
if (socketpair(AF_DNSSD, SOCK_STREAM, 0, sp) < 0) deliver_request_bailout("socketpair");
|
|
618
|
+
else
|
|
619
|
+
{
|
|
620
|
+
errsd = sp[0]; // We'll read our four-byte error code from sp[0]
|
|
621
|
+
listenfd = sp[1]; // We'll send sp[1] to the daemon
|
|
622
|
+
#if !defined(__ppc__) && defined(SO_DEFUNCTOK)
|
|
623
|
+
{
|
|
624
|
+
int defunct = 1;
|
|
625
|
+
if (setsockopt(errsd, SOL_SOCKET, SO_DEFUNCTOK, &defunct, sizeof(defunct)) < 0)
|
|
626
|
+
syslog(LOG_WARNING, "dnssd_clientstub ConnectToServer: SO_DEFUNCTOK failed %d %s", dnssd_errno, dnssd_strerror(dnssd_errno));
|
|
627
|
+
}
|
|
628
|
+
#endif
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
#endif
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
#if !defined(USE_TCP_LOOPBACK) && !defined(USE_NAMED_ERROR_RETURN_SOCKET)
|
|
635
|
+
// If we're going to make a separate error return socket, and pass it to the daemon
|
|
636
|
+
// using sendmsg, then we'll hold back one data byte to go with it.
|
|
637
|
+
// On some versions of Unix (including Leopard) sending a control message without
|
|
638
|
+
// any associated data does not work reliably -- e.g. one particular issue we ran
|
|
639
|
+
// into is that if the receiving program is in a kqueue loop waiting to be notified
|
|
640
|
+
// of the received message, it doesn't get woken up when the control message arrives.
|
|
641
|
+
if (MakeSeparateReturnSocket || sdr->op == send_bpf) datalen--; // Okay to use sdr->op when checking for op == send_bpf
|
|
642
|
+
#endif
|
|
643
|
+
|
|
644
|
+
// At this point, our listening socket is set up and waiting, if necessary, for the daemon to connect back to
|
|
645
|
+
ConvertHeaderBytes(hdr);
|
|
646
|
+
//syslog(LOG_WARNING, "dnssd_clientstub deliver_request writing %lu bytes", (unsigned long)(datalen + sizeof(ipc_msg_hdr)));
|
|
647
|
+
//if (MakeSeparateReturnSocket) syslog(LOG_WARNING, "dnssd_clientstub deliver_request name is %s", data);
|
|
648
|
+
#if TEST_SENDING_ONE_BYTE_AT_A_TIME
|
|
649
|
+
unsigned int i;
|
|
650
|
+
for (i=0; i<datalen + sizeof(ipc_msg_hdr); i++)
|
|
651
|
+
{
|
|
652
|
+
syslog(LOG_WARNING, "dnssd_clientstub deliver_request writing %d", i);
|
|
653
|
+
if (write_all(sdr->sockfd, ((char *)hdr)+i, 1) < 0)
|
|
654
|
+
{ syslog(LOG_WARNING, "write_all (byte %u) failed", i); goto cleanup; }
|
|
655
|
+
usleep(10000);
|
|
656
|
+
}
|
|
657
|
+
#else
|
|
658
|
+
if (write_all(sdr->sockfd, (char *)hdr, datalen + sizeof(ipc_msg_hdr)) < 0)
|
|
659
|
+
{
|
|
660
|
+
// write_all already prints an error message if there is an error writing to
|
|
661
|
+
// the socket except for DEFUNCT. Logging here is unnecessary and also wrong
|
|
662
|
+
// in the case of DEFUNCT sockets
|
|
663
|
+
syslog(LOG_INFO, "dnssd_clientstub deliver_request ERROR: write_all(%d, %lu bytes) failed",
|
|
664
|
+
sdr->sockfd, (unsigned long)(datalen + sizeof(ipc_msg_hdr)));
|
|
665
|
+
goto cleanup;
|
|
666
|
+
}
|
|
667
|
+
#endif
|
|
668
|
+
|
|
669
|
+
if (!MakeSeparateReturnSocket) errsd = sdr->sockfd;
|
|
670
|
+
if (MakeSeparateReturnSocket || sdr->op == send_bpf) // Okay to use sdr->op when checking for op == send_bpf
|
|
671
|
+
{
|
|
672
|
+
#if defined(USE_TCP_LOOPBACK) || defined(USE_NAMED_ERROR_RETURN_SOCKET)
|
|
673
|
+
// At this point we may block in accept for a few milliseconds waiting for the daemon to connect back to us,
|
|
674
|
+
// but that's okay -- the daemon is a trusted service and we know if won't take more than a few milliseconds to respond.
|
|
675
|
+
dnssd_sockaddr_t daddr;
|
|
676
|
+
dnssd_socklen_t len = sizeof(daddr);
|
|
677
|
+
if ((err = wait_for_daemon(listenfd, DNSSD_CLIENT_TIMEOUT)) != kDNSServiceErr_NoError) goto cleanup;
|
|
678
|
+
errsd = accept(listenfd, (struct sockaddr *)&daddr, &len);
|
|
679
|
+
if (!dnssd_SocketValid(errsd)) deliver_request_bailout("accept");
|
|
680
|
+
#else
|
|
681
|
+
|
|
682
|
+
#if APPLE_OSX_mDNSResponder
|
|
683
|
+
// On Leopard, the stock definitions of the CMSG_* macros in /usr/include/sys/socket.h,
|
|
684
|
+
// while arguably correct in theory, nonetheless in practice produce code that doesn't work on 64-bit machines
|
|
685
|
+
// For details see <rdar://problem/5565787> Bonjour API broken for 64-bit apps (SCM_RIGHTS sendmsg fails)
|
|
686
|
+
#undef CMSG_DATA
|
|
687
|
+
#define CMSG_DATA(cmsg) ((unsigned char *)(cmsg) + (sizeof(struct cmsghdr)))
|
|
688
|
+
#undef CMSG_SPACE
|
|
689
|
+
#define CMSG_SPACE(l) ((sizeof(struct cmsghdr)) + (l))
|
|
690
|
+
#undef CMSG_LEN
|
|
691
|
+
#define CMSG_LEN(l) ((sizeof(struct cmsghdr)) + (l))
|
|
692
|
+
#endif
|
|
693
|
+
|
|
694
|
+
struct iovec vec = { ((char *)hdr) + sizeof(ipc_msg_hdr) + datalen, 1 }; // Send the last byte along with the SCM_RIGHTS
|
|
695
|
+
struct msghdr msg;
|
|
696
|
+
struct cmsghdr *cmsg;
|
|
697
|
+
char cbuf[CMSG_SPACE(sizeof(dnssd_sock_t))];
|
|
698
|
+
|
|
699
|
+
if (sdr->op == send_bpf) // Okay to use sdr->op when checking for op == send_bpf
|
|
700
|
+
{
|
|
701
|
+
int i;
|
|
702
|
+
char p[12]; // Room for "/dev/bpf999" with terminating null
|
|
703
|
+
for (i=0; i<100; i++)
|
|
704
|
+
{
|
|
705
|
+
snprintf(p, sizeof(p), "/dev/bpf%d", i);
|
|
706
|
+
listenfd = open(p, O_RDWR, 0);
|
|
707
|
+
//if (dnssd_SocketValid(listenfd)) syslog(LOG_WARNING, "Sending fd %d for %s", listenfd, p);
|
|
708
|
+
if (!dnssd_SocketValid(listenfd) && dnssd_errno != EBUSY)
|
|
709
|
+
syslog(LOG_WARNING, "Error opening %s %d (%s)", p, dnssd_errno, dnssd_strerror(dnssd_errno));
|
|
710
|
+
if (dnssd_SocketValid(listenfd) || dnssd_errno != EBUSY) break;
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
msg.msg_name = 0;
|
|
715
|
+
msg.msg_namelen = 0;
|
|
716
|
+
msg.msg_iov = &vec;
|
|
717
|
+
msg.msg_iovlen = 1;
|
|
718
|
+
msg.msg_control = cbuf;
|
|
719
|
+
msg.msg_controllen = CMSG_LEN(sizeof(dnssd_sock_t));
|
|
720
|
+
msg.msg_flags = 0;
|
|
721
|
+
cmsg = CMSG_FIRSTHDR(&msg);
|
|
722
|
+
cmsg->cmsg_len = CMSG_LEN(sizeof(dnssd_sock_t));
|
|
723
|
+
cmsg->cmsg_level = SOL_SOCKET;
|
|
724
|
+
cmsg->cmsg_type = SCM_RIGHTS;
|
|
725
|
+
*((dnssd_sock_t *)CMSG_DATA(cmsg)) = listenfd;
|
|
726
|
+
|
|
727
|
+
#if TEST_KQUEUE_CONTROL_MESSAGE_BUG
|
|
728
|
+
sleep(1);
|
|
729
|
+
#endif
|
|
730
|
+
|
|
731
|
+
#if DEBUG_64BIT_SCM_RIGHTS
|
|
732
|
+
syslog(LOG_WARNING, "dnssd_clientstub sendmsg read sd=%d write sd=%d %ld %ld %ld/%ld/%ld/%ld",
|
|
733
|
+
errsd, listenfd, sizeof(dnssd_sock_t), sizeof(void*),
|
|
734
|
+
sizeof(struct cmsghdr) + sizeof(dnssd_sock_t),
|
|
735
|
+
CMSG_LEN(sizeof(dnssd_sock_t)), (long)CMSG_SPACE(sizeof(dnssd_sock_t)),
|
|
736
|
+
(long)((char*)CMSG_DATA(cmsg) + 4 - cbuf));
|
|
737
|
+
#endif // DEBUG_64BIT_SCM_RIGHTS
|
|
738
|
+
|
|
739
|
+
if (sendmsg(sdr->sockfd, &msg, 0) < 0)
|
|
740
|
+
{
|
|
741
|
+
syslog(LOG_WARNING, "dnssd_clientstub deliver_request ERROR: sendmsg failed read sd=%d write sd=%d errno %d (%s)",
|
|
742
|
+
errsd, listenfd, dnssd_errno, dnssd_strerror(dnssd_errno));
|
|
743
|
+
err = kDNSServiceErr_Incompatible;
|
|
744
|
+
goto cleanup;
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
#if DEBUG_64BIT_SCM_RIGHTS
|
|
748
|
+
syslog(LOG_WARNING, "dnssd_clientstub sendmsg read sd=%d write sd=%d okay", errsd, listenfd);
|
|
749
|
+
#endif // DEBUG_64BIT_SCM_RIGHTS
|
|
750
|
+
|
|
751
|
+
#endif
|
|
752
|
+
// Close our end of the socketpair *before* blocking in read_all to get the four-byte error code.
|
|
753
|
+
// Otherwise, if the daemon closes our socket (or crashes), we block in read_all() forever
|
|
754
|
+
// because the socket is not closed (we still have an open reference to it ourselves).
|
|
755
|
+
dnssd_close(listenfd);
|
|
756
|
+
listenfd = dnssd_InvalidSocket; // Make sure we don't close it a second time in the cleanup handling below
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
// At this point we may block in read_all for a few milliseconds waiting for the daemon to send us the error code,
|
|
760
|
+
// but that's okay -- the daemon is a trusted service and we know if won't take more than a few milliseconds to respond.
|
|
761
|
+
if (sdr->op == send_bpf) // Okay to use sdr->op when checking for op == send_bpf
|
|
762
|
+
err = kDNSServiceErr_NoError;
|
|
763
|
+
else if ((err = wait_for_daemon(errsd, DNSSD_CLIENT_TIMEOUT)) == kDNSServiceErr_NoError)
|
|
764
|
+
{
|
|
765
|
+
if (read_all(errsd, (char*)&err, (int)sizeof(err)) < 0)
|
|
766
|
+
err = kDNSServiceErr_ServiceNotRunning; // On failure read_all will have written a message to syslog for us
|
|
767
|
+
else
|
|
768
|
+
err = ntohl(err);
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
//syslog(LOG_WARNING, "dnssd_clientstub deliver_request: retrieved error code %d", err);
|
|
772
|
+
|
|
773
|
+
cleanup:
|
|
774
|
+
if (MakeSeparateReturnSocket)
|
|
775
|
+
{
|
|
776
|
+
if (dnssd_SocketValid(listenfd)) dnssd_close(listenfd);
|
|
777
|
+
if (dnssd_SocketValid(errsd)) dnssd_close(errsd);
|
|
778
|
+
#if defined(USE_NAMED_ERROR_RETURN_SOCKET)
|
|
779
|
+
// syslog(LOG_WARNING, "dnssd_clientstub deliver_request: removing UDS: %s", data);
|
|
780
|
+
if (unlink(data) != 0)
|
|
781
|
+
syslog(LOG_WARNING, "dnssd_clientstub WARNING: unlink(\"%s\") failed errno %d (%s)", data, dnssd_errno, dnssd_strerror(dnssd_errno));
|
|
782
|
+
// else syslog(LOG_WARNING, "dnssd_clientstub deliver_request: removed UDS: %s", data);
|
|
783
|
+
#endif
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
free(hdr);
|
|
787
|
+
return err;
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
int DNSSD_API DNSServiceRefSockFD(DNSServiceRef sdRef)
|
|
791
|
+
{
|
|
792
|
+
if (!sdRef) { syslog(LOG_WARNING, "dnssd_clientstub DNSServiceRefSockFD called with NULL DNSServiceRef"); return dnssd_InvalidSocket; }
|
|
793
|
+
|
|
794
|
+
if (!DNSServiceRefValid(sdRef))
|
|
795
|
+
{
|
|
796
|
+
syslog(LOG_WARNING, "dnssd_clientstub DNSServiceRefSockFD called with invalid DNSServiceRef %p %08X %08X",
|
|
797
|
+
sdRef, sdRef->sockfd, sdRef->validator);
|
|
798
|
+
return dnssd_InvalidSocket;
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
if (sdRef->primary)
|
|
802
|
+
{
|
|
803
|
+
syslog(LOG_WARNING, "dnssd_clientstub DNSServiceRefSockFD undefined for kDNSServiceFlagsShareConnection subordinate DNSServiceRef %p", sdRef);
|
|
804
|
+
return dnssd_InvalidSocket;
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
return (int) sdRef->sockfd;
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
#if _DNS_SD_LIBDISPATCH
|
|
811
|
+
static void CallbackWithError(DNSServiceRef sdRef, DNSServiceErrorType error)
|
|
812
|
+
{
|
|
813
|
+
DNSServiceOp *sdr = sdRef;
|
|
814
|
+
DNSServiceOp *sdrNext;
|
|
815
|
+
DNSRecord *rec;
|
|
816
|
+
DNSRecord *recnext;
|
|
817
|
+
int morebytes;
|
|
818
|
+
|
|
819
|
+
while (sdr)
|
|
820
|
+
{
|
|
821
|
+
// We can't touch the sdr after the callback as it can be deallocated in the callback
|
|
822
|
+
sdrNext = sdr->next;
|
|
823
|
+
morebytes = 1;
|
|
824
|
+
sdr->moreptr = &morebytes;
|
|
825
|
+
switch (sdr->op)
|
|
826
|
+
{
|
|
827
|
+
case resolve_request:
|
|
828
|
+
if (sdr->AppCallback)((DNSServiceResolveReply) sdr->AppCallback)(sdr, 0, 0, error, NULL, 0, 0, 0, NULL, sdr->AppContext);
|
|
829
|
+
break;
|
|
830
|
+
case query_request:
|
|
831
|
+
if (sdr->AppCallback)((DNSServiceQueryRecordReply)sdr->AppCallback)(sdr, 0, 0, error, NULL, 0, 0, 0, NULL, 0, sdr->AppContext);
|
|
832
|
+
break;
|
|
833
|
+
case addrinfo_request:
|
|
834
|
+
if (sdr->AppCallback)((DNSServiceGetAddrInfoReply)sdr->AppCallback)(sdr, 0, 0, error, NULL, NULL, 0, sdr->AppContext);
|
|
835
|
+
break;
|
|
836
|
+
case browse_request:
|
|
837
|
+
if (sdr->AppCallback)((DNSServiceBrowseReply) sdr->AppCallback)(sdr, 0, 0, error, NULL, 0, NULL, sdr->AppContext);
|
|
838
|
+
break;
|
|
839
|
+
case reg_service_request:
|
|
840
|
+
if (sdr->AppCallback)((DNSServiceRegisterReply) sdr->AppCallback)(sdr, 0, error, NULL, 0, NULL, sdr->AppContext);
|
|
841
|
+
break;
|
|
842
|
+
case enumeration_request:
|
|
843
|
+
if (sdr->AppCallback)((DNSServiceDomainEnumReply) sdr->AppCallback)(sdr, 0, 0, error, NULL, sdr->AppContext);
|
|
844
|
+
break;
|
|
845
|
+
case sethost_request:
|
|
846
|
+
if (sdr->AppCallback)((DNSServiceSetHostReply) sdr->AppCallback)(sdr, 0, error, NULL, sdr->AppContext);
|
|
847
|
+
break;
|
|
848
|
+
case connection_request:
|
|
849
|
+
// This means Register Record, walk the list of DNSRecords to do the callback
|
|
850
|
+
rec = sdr->rec;
|
|
851
|
+
while (rec)
|
|
852
|
+
{
|
|
853
|
+
recnext = rec->recnext;
|
|
854
|
+
if (rec->AppCallback) ((DNSServiceRegisterRecordReply)rec->AppCallback)(sdr, 0, 0, error, rec->AppContext);
|
|
855
|
+
// The Callback can call DNSServiceRefDeallocate which in turn frees sdr and all the records.
|
|
856
|
+
// Detect that and return early
|
|
857
|
+
if (!morebytes){syslog(LOG_WARNING, "dnssdclientstub:Record: CallbackwithError morebytes zero"); return;}
|
|
858
|
+
rec = recnext;
|
|
859
|
+
}
|
|
860
|
+
break;
|
|
861
|
+
case port_mapping_request:
|
|
862
|
+
if (sdr->AppCallback)((DNSServiceNATPortMappingReply)sdr->AppCallback)(sdr, 0, 0, error, 0, 0, 0, 0, 0, sdr->AppContext);
|
|
863
|
+
break;
|
|
864
|
+
default:
|
|
865
|
+
syslog(LOG_WARNING, "dnssd_clientstub CallbackWithError called with bad op %d", sdr->op);
|
|
866
|
+
}
|
|
867
|
+
// If DNSServiceRefDeallocate was called in the callback, morebytes will be zero. It means
|
|
868
|
+
// all other sdrefs have been freed. This happens for shared connections where the
|
|
869
|
+
// DNSServiceRefDeallocate on the first sdRef frees all other sdrefs.
|
|
870
|
+
if (!morebytes){syslog(LOG_WARNING, "dnssdclientstub:sdRef: CallbackwithError morebytes zero"); return;}
|
|
871
|
+
sdr = sdrNext;
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
#endif // _DNS_SD_LIBDISPATCH
|
|
875
|
+
|
|
876
|
+
// Handle reply from server, calling application client callback. If there is no reply
|
|
877
|
+
// from the daemon on the socket contained in sdRef, the call will block.
|
|
878
|
+
DNSServiceErrorType DNSSD_API DNSServiceProcessResult(DNSServiceRef sdRef)
|
|
879
|
+
{
|
|
880
|
+
int morebytes = 0;
|
|
881
|
+
|
|
882
|
+
if (!sdRef) { syslog(LOG_WARNING, "dnssd_clientstub DNSServiceProcessResult called with NULL DNSServiceRef"); return kDNSServiceErr_BadParam; }
|
|
883
|
+
|
|
884
|
+
if (!DNSServiceRefValid(sdRef))
|
|
885
|
+
{
|
|
886
|
+
syslog(LOG_WARNING, "dnssd_clientstub DNSServiceProcessResult called with invalid DNSServiceRef %p %08X %08X", sdRef, sdRef->sockfd, sdRef->validator);
|
|
887
|
+
return kDNSServiceErr_BadReference;
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
if (sdRef->primary)
|
|
891
|
+
{
|
|
892
|
+
syslog(LOG_WARNING, "dnssd_clientstub DNSServiceProcessResult undefined for kDNSServiceFlagsShareConnection subordinate DNSServiceRef %p", sdRef);
|
|
893
|
+
return kDNSServiceErr_BadReference;
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
if (!sdRef->ProcessReply)
|
|
897
|
+
{
|
|
898
|
+
static int num_logs = 0;
|
|
899
|
+
if (num_logs < 10) syslog(LOG_WARNING, "dnssd_clientstub DNSServiceProcessResult called with DNSServiceRef with no ProcessReply function");
|
|
900
|
+
if (num_logs < 1000) num_logs++; else sleep(1);
|
|
901
|
+
return kDNSServiceErr_BadReference;
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
do
|
|
905
|
+
{
|
|
906
|
+
CallbackHeader cbh;
|
|
907
|
+
char *data;
|
|
908
|
+
|
|
909
|
+
// return NoError on EWOULDBLOCK. This will handle the case
|
|
910
|
+
// where a non-blocking socket is told there is data, but it was a false positive.
|
|
911
|
+
// On error, read_all will write a message to syslog for us, so don't need to duplicate that here
|
|
912
|
+
// Note: If we want to properly support using non-blocking sockets in the future
|
|
913
|
+
int result = read_all(sdRef->sockfd, (void *)&cbh.ipc_hdr, sizeof(cbh.ipc_hdr));
|
|
914
|
+
if (result == read_all_fail)
|
|
915
|
+
{
|
|
916
|
+
// Set the ProcessReply to NULL before callback as the sdRef can get deallocated
|
|
917
|
+
// in the callback.
|
|
918
|
+
sdRef->ProcessReply = NULL;
|
|
919
|
+
#if _DNS_SD_LIBDISPATCH
|
|
920
|
+
// Call the callbacks with an error if using the dispatch API, as DNSServiceProcessResult
|
|
921
|
+
// is not called by the application and hence need to communicate the error. Cancel the
|
|
922
|
+
// source so that we don't get any more events
|
|
923
|
+
if (sdRef->disp_source)
|
|
924
|
+
{
|
|
925
|
+
dispatch_source_cancel(sdRef->disp_source);
|
|
926
|
+
dispatch_release(sdRef->disp_source);
|
|
927
|
+
sdRef->disp_source = NULL;
|
|
928
|
+
CallbackWithError(sdRef, kDNSServiceErr_ServiceNotRunning);
|
|
929
|
+
}
|
|
930
|
+
#endif
|
|
931
|
+
// Don't touch sdRef anymore as it might have been deallocated
|
|
932
|
+
return kDNSServiceErr_ServiceNotRunning;
|
|
933
|
+
}
|
|
934
|
+
else if (result == read_all_wouldblock)
|
|
935
|
+
{
|
|
936
|
+
if (morebytes && sdRef->logcounter < 100)
|
|
937
|
+
{
|
|
938
|
+
sdRef->logcounter++;
|
|
939
|
+
syslog(LOG_WARNING, "dnssd_clientstub DNSServiceProcessResult error: select indicated data was waiting but read_all returned EWOULDBLOCK");
|
|
940
|
+
}
|
|
941
|
+
return kDNSServiceErr_NoError;
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
ConvertHeaderBytes(&cbh.ipc_hdr);
|
|
945
|
+
if (cbh.ipc_hdr.version != VERSION)
|
|
946
|
+
{
|
|
947
|
+
syslog(LOG_WARNING, "dnssd_clientstub DNSServiceProcessResult daemon version %d does not match client version %d", cbh.ipc_hdr.version, VERSION);
|
|
948
|
+
sdRef->ProcessReply = NULL;
|
|
949
|
+
return kDNSServiceErr_Incompatible;
|
|
950
|
+
}
|
|
951
|
+
|
|
952
|
+
data = malloc(cbh.ipc_hdr.datalen);
|
|
953
|
+
if (!data) return kDNSServiceErr_NoMemory;
|
|
954
|
+
if (read_all(sdRef->sockfd, data, cbh.ipc_hdr.datalen) < 0) // On error, read_all will write a message to syslog for us
|
|
955
|
+
{
|
|
956
|
+
// Set the ProcessReply to NULL before callback as the sdRef can get deallocated
|
|
957
|
+
// in the callback.
|
|
958
|
+
sdRef->ProcessReply = NULL;
|
|
959
|
+
#if _DNS_SD_LIBDISPATCH
|
|
960
|
+
// Call the callbacks with an error if using the dispatch API, as DNSServiceProcessResult
|
|
961
|
+
// is not called by the application and hence need to communicate the error. Cancel the
|
|
962
|
+
// source so that we don't get any more events
|
|
963
|
+
if (sdRef->disp_source)
|
|
964
|
+
{
|
|
965
|
+
dispatch_source_cancel(sdRef->disp_source);
|
|
966
|
+
dispatch_release(sdRef->disp_source);
|
|
967
|
+
sdRef->disp_source = NULL;
|
|
968
|
+
CallbackWithError(sdRef, kDNSServiceErr_ServiceNotRunning);
|
|
969
|
+
}
|
|
970
|
+
#endif
|
|
971
|
+
// Don't touch sdRef anymore as it might have been deallocated
|
|
972
|
+
free(data);
|
|
973
|
+
return kDNSServiceErr_ServiceNotRunning;
|
|
974
|
+
}
|
|
975
|
+
else
|
|
976
|
+
{
|
|
977
|
+
const char *ptr = data;
|
|
978
|
+
cbh.cb_flags = get_flags (&ptr, data + cbh.ipc_hdr.datalen);
|
|
979
|
+
cbh.cb_interface = get_uint32 (&ptr, data + cbh.ipc_hdr.datalen);
|
|
980
|
+
cbh.cb_err = get_error_code(&ptr, data + cbh.ipc_hdr.datalen);
|
|
981
|
+
|
|
982
|
+
// CAUTION: We have to handle the case where the client calls DNSServiceRefDeallocate from within the callback function.
|
|
983
|
+
// To do this we set moreptr to point to morebytes. If the client does call DNSServiceRefDeallocate(),
|
|
984
|
+
// then that routine will clear morebytes for us, and cause us to exit our loop.
|
|
985
|
+
morebytes = more_bytes(sdRef->sockfd);
|
|
986
|
+
if (morebytes)
|
|
987
|
+
{
|
|
988
|
+
cbh.cb_flags |= kDNSServiceFlagsMoreComing;
|
|
989
|
+
sdRef->moreptr = &morebytes;
|
|
990
|
+
}
|
|
991
|
+
if (ptr) sdRef->ProcessReply(sdRef, &cbh, ptr, data + cbh.ipc_hdr.datalen);
|
|
992
|
+
// Careful code here:
|
|
993
|
+
// If morebytes is non-zero, that means we set sdRef->moreptr above, and the operation was not
|
|
994
|
+
// cancelled out from under us, so now we need to clear sdRef->moreptr so we don't leave a stray
|
|
995
|
+
// dangling pointer pointing to a long-gone stack variable.
|
|
996
|
+
// If morebytes is zero, then one of two thing happened:
|
|
997
|
+
// (a) morebytes was 0 above, so we didn't set sdRef->moreptr, so we don't need to clear it
|
|
998
|
+
// (b) morebytes was 1 above, and we set sdRef->moreptr, but the operation was cancelled (with DNSServiceRefDeallocate()),
|
|
999
|
+
// so we MUST NOT try to dereference our stale sdRef pointer.
|
|
1000
|
+
if (morebytes) sdRef->moreptr = NULL;
|
|
1001
|
+
}
|
|
1002
|
+
free(data);
|
|
1003
|
+
} while (morebytes);
|
|
1004
|
+
|
|
1005
|
+
return kDNSServiceErr_NoError;
|
|
1006
|
+
}
|
|
1007
|
+
|
|
1008
|
+
void DNSSD_API DNSServiceRefDeallocate(DNSServiceRef sdRef)
|
|
1009
|
+
{
|
|
1010
|
+
if (!sdRef) { syslog(LOG_WARNING, "dnssd_clientstub DNSServiceRefDeallocate called with NULL DNSServiceRef"); return; }
|
|
1011
|
+
|
|
1012
|
+
if (!DNSServiceRefValid(sdRef)) // Also verifies dnssd_SocketValid(sdRef->sockfd) for us too
|
|
1013
|
+
{
|
|
1014
|
+
syslog(LOG_WARNING, "dnssd_clientstub DNSServiceRefDeallocate called with invalid DNSServiceRef %p %08X %08X", sdRef, sdRef->sockfd, sdRef->validator);
|
|
1015
|
+
return;
|
|
1016
|
+
}
|
|
1017
|
+
|
|
1018
|
+
// If we're in the middle of a DNSServiceProcessResult() invocation for this DNSServiceRef, clear its morebytes flag to break it out of its while loop
|
|
1019
|
+
if (sdRef->moreptr) *(sdRef->moreptr) = 0;
|
|
1020
|
+
|
|
1021
|
+
if (sdRef->primary) // If this is a subordinate DNSServiceOp, just send a 'stop' command
|
|
1022
|
+
{
|
|
1023
|
+
DNSServiceOp **p = &sdRef->primary->next;
|
|
1024
|
+
while (*p && *p != sdRef) p = &(*p)->next;
|
|
1025
|
+
if (*p)
|
|
1026
|
+
{
|
|
1027
|
+
char *ptr;
|
|
1028
|
+
size_t len = 0;
|
|
1029
|
+
ipc_msg_hdr *hdr = create_hdr(cancel_request, &len, &ptr, 0, sdRef);
|
|
1030
|
+
if (hdr)
|
|
1031
|
+
{
|
|
1032
|
+
ConvertHeaderBytes(hdr);
|
|
1033
|
+
write_all(sdRef->sockfd, (char *)hdr, len);
|
|
1034
|
+
free(hdr);
|
|
1035
|
+
}
|
|
1036
|
+
*p = sdRef->next;
|
|
1037
|
+
FreeDNSServiceOp(sdRef);
|
|
1038
|
+
}
|
|
1039
|
+
}
|
|
1040
|
+
else // else, make sure to terminate all subordinates as well
|
|
1041
|
+
{
|
|
1042
|
+
#if _DNS_SD_LIBDISPATCH
|
|
1043
|
+
// The cancel handler will close the fd if a dispatch source has been set
|
|
1044
|
+
if (sdRef->disp_source)
|
|
1045
|
+
{
|
|
1046
|
+
// By setting the ProcessReply to NULL, we make sure that we never call
|
|
1047
|
+
// the application callbacks ever, after returning from this function. We
|
|
1048
|
+
// assume that DNSServiceRefDeallocate is called from the serial queue
|
|
1049
|
+
// that was passed to DNSServiceSetDispatchQueue. Hence, dispatch_source_cancel
|
|
1050
|
+
// should cancel all the blocks on the queue and hence there should be no more
|
|
1051
|
+
// callbacks when we return from this function. Setting ProcessReply to NULL
|
|
1052
|
+
// provides extra protection.
|
|
1053
|
+
sdRef->ProcessReply = NULL;
|
|
1054
|
+
dispatch_source_cancel(sdRef->disp_source);
|
|
1055
|
+
dispatch_release(sdRef->disp_source);
|
|
1056
|
+
sdRef->disp_source = NULL;
|
|
1057
|
+
}
|
|
1058
|
+
// if disp_queue is set, it means it used the DNSServiceSetDispatchQueue API. In that case,
|
|
1059
|
+
// when the source was cancelled, the fd was closed in the handler. Currently the source
|
|
1060
|
+
// is cancelled only when the mDNSResponder daemon dies
|
|
1061
|
+
else if (!sdRef->disp_queue) dnssd_close(sdRef->sockfd);
|
|
1062
|
+
#else
|
|
1063
|
+
dnssd_close(sdRef->sockfd);
|
|
1064
|
+
#endif
|
|
1065
|
+
// Free DNSRecords added in DNSRegisterRecord if they have not
|
|
1066
|
+
// been freed in DNSRemoveRecord
|
|
1067
|
+
while (sdRef)
|
|
1068
|
+
{
|
|
1069
|
+
DNSServiceOp *p = sdRef;
|
|
1070
|
+
sdRef = sdRef->next;
|
|
1071
|
+
FreeDNSServiceOp(p);
|
|
1072
|
+
}
|
|
1073
|
+
}
|
|
1074
|
+
}
|
|
1075
|
+
|
|
1076
|
+
DNSServiceErrorType DNSSD_API DNSServiceGetProperty(const char *property, void *result, uint32_t *size)
|
|
1077
|
+
{
|
|
1078
|
+
char *ptr;
|
|
1079
|
+
size_t len = strlen(property) + 1;
|
|
1080
|
+
ipc_msg_hdr *hdr;
|
|
1081
|
+
DNSServiceOp *tmp;
|
|
1082
|
+
uint32_t actualsize;
|
|
1083
|
+
|
|
1084
|
+
DNSServiceErrorType err = ConnectToServer(&tmp, 0, getproperty_request, NULL, NULL, NULL);
|
|
1085
|
+
if (err) return err;
|
|
1086
|
+
|
|
1087
|
+
hdr = create_hdr(getproperty_request, &len, &ptr, 0, tmp);
|
|
1088
|
+
if (!hdr) { DNSServiceRefDeallocate(tmp); return kDNSServiceErr_NoMemory; }
|
|
1089
|
+
|
|
1090
|
+
put_string(property, &ptr);
|
|
1091
|
+
err = deliver_request(hdr, tmp); // Will free hdr for us
|
|
1092
|
+
if (read_all(tmp->sockfd, (char*)&actualsize, (int)sizeof(actualsize)) < 0)
|
|
1093
|
+
{ DNSServiceRefDeallocate(tmp); return kDNSServiceErr_ServiceNotRunning; }
|
|
1094
|
+
|
|
1095
|
+
actualsize = ntohl(actualsize);
|
|
1096
|
+
if (read_all(tmp->sockfd, (char*)result, actualsize < *size ? actualsize : *size) < 0)
|
|
1097
|
+
{ DNSServiceRefDeallocate(tmp); return kDNSServiceErr_ServiceNotRunning; }
|
|
1098
|
+
DNSServiceRefDeallocate(tmp);
|
|
1099
|
+
|
|
1100
|
+
// Swap version result back to local process byte order
|
|
1101
|
+
if (!strcmp(property, kDNSServiceProperty_DaemonVersion) && *size >= 4)
|
|
1102
|
+
*(uint32_t*)result = ntohl(*(uint32_t*)result);
|
|
1103
|
+
|
|
1104
|
+
*size = actualsize;
|
|
1105
|
+
return kDNSServiceErr_NoError;
|
|
1106
|
+
}
|
|
1107
|
+
|
|
1108
|
+
static void handle_resolve_response(DNSServiceOp *const sdr, const CallbackHeader *const cbh, const char *data, const char *end)
|
|
1109
|
+
{
|
|
1110
|
+
char fullname[kDNSServiceMaxDomainName];
|
|
1111
|
+
char target[kDNSServiceMaxDomainName];
|
|
1112
|
+
uint16_t txtlen;
|
|
1113
|
+
union { uint16_t s; u_char b[2]; } port;
|
|
1114
|
+
unsigned char *txtrecord;
|
|
1115
|
+
|
|
1116
|
+
get_string(&data, end, fullname, kDNSServiceMaxDomainName);
|
|
1117
|
+
get_string(&data, end, target, kDNSServiceMaxDomainName);
|
|
1118
|
+
if (!data || data + 2 > end) goto fail;
|
|
1119
|
+
|
|
1120
|
+
port.b[0] = *data++;
|
|
1121
|
+
port.b[1] = *data++;
|
|
1122
|
+
txtlen = get_uint16(&data, end);
|
|
1123
|
+
txtrecord = (unsigned char *)get_rdata(&data, end, txtlen);
|
|
1124
|
+
|
|
1125
|
+
if (!data) goto fail;
|
|
1126
|
+
((DNSServiceResolveReply)sdr->AppCallback)(sdr, cbh->cb_flags, cbh->cb_interface, cbh->cb_err, fullname, target, port.s, txtlen, txtrecord, sdr->AppContext);
|
|
1127
|
+
return;
|
|
1128
|
+
// MUST NOT touch sdr after invoking AppCallback -- client is allowed to dispose it from within callback function
|
|
1129
|
+
fail:
|
|
1130
|
+
syslog(LOG_WARNING, "dnssd_clientstub handle_resolve_response: error reading result from daemon");
|
|
1131
|
+
}
|
|
1132
|
+
|
|
1133
|
+
DNSServiceErrorType DNSSD_API DNSServiceResolve
|
|
1134
|
+
(
|
|
1135
|
+
DNSServiceRef *sdRef,
|
|
1136
|
+
DNSServiceFlags flags,
|
|
1137
|
+
uint32_t interfaceIndex,
|
|
1138
|
+
const char *name,
|
|
1139
|
+
const char *regtype,
|
|
1140
|
+
const char *domain,
|
|
1141
|
+
DNSServiceResolveReply callBack,
|
|
1142
|
+
void *context
|
|
1143
|
+
)
|
|
1144
|
+
{
|
|
1145
|
+
char *ptr;
|
|
1146
|
+
size_t len;
|
|
1147
|
+
ipc_msg_hdr *hdr;
|
|
1148
|
+
DNSServiceErrorType err;
|
|
1149
|
+
|
|
1150
|
+
if (!name || !regtype || !domain || !callBack) return kDNSServiceErr_BadParam;
|
|
1151
|
+
|
|
1152
|
+
// Need a real InterfaceID for WakeOnResolve
|
|
1153
|
+
if ((flags & kDNSServiceFlagsWakeOnResolve) != 0 &&
|
|
1154
|
+
((interfaceIndex == kDNSServiceInterfaceIndexAny) ||
|
|
1155
|
+
(interfaceIndex == kDNSServiceInterfaceIndexLocalOnly) ||
|
|
1156
|
+
(interfaceIndex == kDNSServiceInterfaceIndexUnicast) ||
|
|
1157
|
+
(interfaceIndex == kDNSServiceInterfaceIndexP2P)))
|
|
1158
|
+
{
|
|
1159
|
+
return kDNSServiceErr_BadParam;
|
|
1160
|
+
}
|
|
1161
|
+
|
|
1162
|
+
err = ConnectToServer(sdRef, flags, resolve_request, handle_resolve_response, callBack, context);
|
|
1163
|
+
if (err) return err; // On error ConnectToServer leaves *sdRef set to NULL
|
|
1164
|
+
|
|
1165
|
+
// Calculate total message length
|
|
1166
|
+
len = sizeof(flags);
|
|
1167
|
+
len += sizeof(interfaceIndex);
|
|
1168
|
+
len += strlen(name) + 1;
|
|
1169
|
+
len += strlen(regtype) + 1;
|
|
1170
|
+
len += strlen(domain) + 1;
|
|
1171
|
+
|
|
1172
|
+
hdr = create_hdr(resolve_request, &len, &ptr, (*sdRef)->primary ? 1 : 0, *sdRef);
|
|
1173
|
+
if (!hdr) { DNSServiceRefDeallocate(*sdRef); *sdRef = NULL; return kDNSServiceErr_NoMemory; }
|
|
1174
|
+
|
|
1175
|
+
put_flags(flags, &ptr);
|
|
1176
|
+
put_uint32(interfaceIndex, &ptr);
|
|
1177
|
+
put_string(name, &ptr);
|
|
1178
|
+
put_string(regtype, &ptr);
|
|
1179
|
+
put_string(domain, &ptr);
|
|
1180
|
+
|
|
1181
|
+
err = deliver_request(hdr, *sdRef); // Will free hdr for us
|
|
1182
|
+
if (err) { DNSServiceRefDeallocate(*sdRef); *sdRef = NULL; }
|
|
1183
|
+
return err;
|
|
1184
|
+
}
|
|
1185
|
+
|
|
1186
|
+
static void handle_query_response(DNSServiceOp *const sdr, const CallbackHeader *const cbh, const char *data, const char *const end)
|
|
1187
|
+
{
|
|
1188
|
+
uint32_t ttl;
|
|
1189
|
+
char name[kDNSServiceMaxDomainName];
|
|
1190
|
+
uint16_t rrtype, rrclass, rdlen;
|
|
1191
|
+
const char *rdata;
|
|
1192
|
+
|
|
1193
|
+
get_string(&data, end, name, kDNSServiceMaxDomainName);
|
|
1194
|
+
rrtype = get_uint16(&data, end);
|
|
1195
|
+
rrclass = get_uint16(&data, end);
|
|
1196
|
+
rdlen = get_uint16(&data, end);
|
|
1197
|
+
rdata = get_rdata(&data, end, rdlen);
|
|
1198
|
+
ttl = get_uint32(&data, end);
|
|
1199
|
+
|
|
1200
|
+
if (!data) syslog(LOG_WARNING, "dnssd_clientstub handle_query_response: error reading result from daemon");
|
|
1201
|
+
else ((DNSServiceQueryRecordReply)sdr->AppCallback)(sdr, cbh->cb_flags, cbh->cb_interface, cbh->cb_err, name, rrtype, rrclass, rdlen, rdata, ttl, sdr->AppContext);
|
|
1202
|
+
// MUST NOT touch sdr after invoking AppCallback -- client is allowed to dispose it from within callback function
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1205
|
+
DNSServiceErrorType DNSSD_API DNSServiceQueryRecord
|
|
1206
|
+
(
|
|
1207
|
+
DNSServiceRef *sdRef,
|
|
1208
|
+
DNSServiceFlags flags,
|
|
1209
|
+
uint32_t interfaceIndex,
|
|
1210
|
+
const char *name,
|
|
1211
|
+
uint16_t rrtype,
|
|
1212
|
+
uint16_t rrclass,
|
|
1213
|
+
DNSServiceQueryRecordReply callBack,
|
|
1214
|
+
void *context
|
|
1215
|
+
)
|
|
1216
|
+
{
|
|
1217
|
+
char *ptr;
|
|
1218
|
+
size_t len;
|
|
1219
|
+
ipc_msg_hdr *hdr;
|
|
1220
|
+
DNSServiceErrorType err = ConnectToServer(sdRef, flags, query_request, handle_query_response, callBack, context);
|
|
1221
|
+
if (err) return err; // On error ConnectToServer leaves *sdRef set to NULL
|
|
1222
|
+
|
|
1223
|
+
if (!name) name = "\0";
|
|
1224
|
+
|
|
1225
|
+
// Calculate total message length
|
|
1226
|
+
len = sizeof(flags);
|
|
1227
|
+
len += sizeof(uint32_t); // interfaceIndex
|
|
1228
|
+
len += strlen(name) + 1;
|
|
1229
|
+
len += 2 * sizeof(uint16_t); // rrtype, rrclass
|
|
1230
|
+
|
|
1231
|
+
hdr = create_hdr(query_request, &len, &ptr, (*sdRef)->primary ? 1 : 0, *sdRef);
|
|
1232
|
+
if (!hdr) { DNSServiceRefDeallocate(*sdRef); *sdRef = NULL; return kDNSServiceErr_NoMemory; }
|
|
1233
|
+
|
|
1234
|
+
put_flags(flags, &ptr);
|
|
1235
|
+
put_uint32(interfaceIndex, &ptr);
|
|
1236
|
+
put_string(name, &ptr);
|
|
1237
|
+
put_uint16(rrtype, &ptr);
|
|
1238
|
+
put_uint16(rrclass, &ptr);
|
|
1239
|
+
|
|
1240
|
+
err = deliver_request(hdr, *sdRef); // Will free hdr for us
|
|
1241
|
+
if (err) { DNSServiceRefDeallocate(*sdRef); *sdRef = NULL; }
|
|
1242
|
+
return err;
|
|
1243
|
+
}
|
|
1244
|
+
|
|
1245
|
+
static void handle_addrinfo_response(DNSServiceOp *const sdr, const CallbackHeader *const cbh, const char *data, const char *const end)
|
|
1246
|
+
{
|
|
1247
|
+
char hostname[kDNSServiceMaxDomainName];
|
|
1248
|
+
uint16_t rrtype, rrclass, rdlen;
|
|
1249
|
+
const char *rdata;
|
|
1250
|
+
uint32_t ttl;
|
|
1251
|
+
|
|
1252
|
+
get_string(&data, end, hostname, kDNSServiceMaxDomainName);
|
|
1253
|
+
rrtype = get_uint16(&data, end);
|
|
1254
|
+
rrclass = get_uint16(&data, end);
|
|
1255
|
+
rdlen = get_uint16(&data, end);
|
|
1256
|
+
rdata = get_rdata (&data, end, rdlen);
|
|
1257
|
+
ttl = get_uint32(&data, end);
|
|
1258
|
+
|
|
1259
|
+
// We only generate client callbacks for A and AAAA results (including NXDOMAIN results for
|
|
1260
|
+
// those types, if the client has requested those with the kDNSServiceFlagsReturnIntermediates).
|
|
1261
|
+
// Other result types, specifically CNAME referrals, are not communicated to the client, because
|
|
1262
|
+
// the DNSServiceGetAddrInfoReply interface doesn't have any meaningful way to communiate CNAME referrals.
|
|
1263
|
+
if (!data) syslog(LOG_WARNING, "dnssd_clientstub handle_addrinfo_response: error reading result from daemon");
|
|
1264
|
+
else if (rrtype == kDNSServiceType_A || rrtype == kDNSServiceType_AAAA)
|
|
1265
|
+
{
|
|
1266
|
+
struct sockaddr_in sa4;
|
|
1267
|
+
struct sockaddr_in6 sa6;
|
|
1268
|
+
const struct sockaddr *const sa = (rrtype == kDNSServiceType_A) ? (struct sockaddr*)&sa4 : (struct sockaddr*)&sa6;
|
|
1269
|
+
if (rrtype == kDNSServiceType_A)
|
|
1270
|
+
{
|
|
1271
|
+
memset(&sa4, 0, sizeof(sa4));
|
|
1272
|
+
#ifndef NOT_HAVE_SA_LEN
|
|
1273
|
+
sa4.sin_len = sizeof(struct sockaddr_in);
|
|
1274
|
+
#endif
|
|
1275
|
+
sa4.sin_family = AF_INET;
|
|
1276
|
+
// sin_port = 0;
|
|
1277
|
+
if (!cbh->cb_err) memcpy(&sa4.sin_addr, rdata, rdlen);
|
|
1278
|
+
}
|
|
1279
|
+
else
|
|
1280
|
+
{
|
|
1281
|
+
memset(&sa6, 0, sizeof(sa6));
|
|
1282
|
+
#ifndef NOT_HAVE_SA_LEN
|
|
1283
|
+
sa6.sin6_len = sizeof(struct sockaddr_in6);
|
|
1284
|
+
#endif
|
|
1285
|
+
sa6.sin6_family = AF_INET6;
|
|
1286
|
+
// sin6_port = 0;
|
|
1287
|
+
// sin6_flowinfo = 0;
|
|
1288
|
+
// sin6_scope_id = 0;
|
|
1289
|
+
if (!cbh->cb_err)
|
|
1290
|
+
{
|
|
1291
|
+
memcpy(&sa6.sin6_addr, rdata, rdlen);
|
|
1292
|
+
if (IN6_IS_ADDR_LINKLOCAL(&sa6.sin6_addr)) sa6.sin6_scope_id = cbh->cb_interface;
|
|
1293
|
+
}
|
|
1294
|
+
}
|
|
1295
|
+
((DNSServiceGetAddrInfoReply)sdr->AppCallback)(sdr, cbh->cb_flags, cbh->cb_interface, cbh->cb_err, hostname, sa, ttl, sdr->AppContext);
|
|
1296
|
+
// MUST NOT touch sdr after invoking AppCallback -- client is allowed to dispose it from within callback function
|
|
1297
|
+
}
|
|
1298
|
+
}
|
|
1299
|
+
|
|
1300
|
+
DNSServiceErrorType DNSSD_API DNSServiceGetAddrInfo
|
|
1301
|
+
(
|
|
1302
|
+
DNSServiceRef *sdRef,
|
|
1303
|
+
DNSServiceFlags flags,
|
|
1304
|
+
uint32_t interfaceIndex,
|
|
1305
|
+
uint32_t protocol,
|
|
1306
|
+
const char *hostname,
|
|
1307
|
+
DNSServiceGetAddrInfoReply callBack,
|
|
1308
|
+
void *context /* may be NULL */
|
|
1309
|
+
)
|
|
1310
|
+
{
|
|
1311
|
+
char *ptr;
|
|
1312
|
+
size_t len;
|
|
1313
|
+
ipc_msg_hdr *hdr;
|
|
1314
|
+
DNSServiceErrorType err;
|
|
1315
|
+
|
|
1316
|
+
if (!hostname) return kDNSServiceErr_BadParam;
|
|
1317
|
+
|
|
1318
|
+
err = ConnectToServer(sdRef, flags, addrinfo_request, handle_addrinfo_response, callBack, context);
|
|
1319
|
+
if (err) return err; // On error ConnectToServer leaves *sdRef set to NULL
|
|
1320
|
+
|
|
1321
|
+
// Calculate total message length
|
|
1322
|
+
len = sizeof(flags);
|
|
1323
|
+
len += sizeof(uint32_t); // interfaceIndex
|
|
1324
|
+
len += sizeof(uint32_t); // protocol
|
|
1325
|
+
len += strlen(hostname) + 1;
|
|
1326
|
+
|
|
1327
|
+
hdr = create_hdr(addrinfo_request, &len, &ptr, (*sdRef)->primary ? 1 : 0, *sdRef);
|
|
1328
|
+
if (!hdr) { DNSServiceRefDeallocate(*sdRef); *sdRef = NULL; return kDNSServiceErr_NoMemory; }
|
|
1329
|
+
|
|
1330
|
+
put_flags(flags, &ptr);
|
|
1331
|
+
put_uint32(interfaceIndex, &ptr);
|
|
1332
|
+
put_uint32(protocol, &ptr);
|
|
1333
|
+
put_string(hostname, &ptr);
|
|
1334
|
+
|
|
1335
|
+
err = deliver_request(hdr, *sdRef); // Will free hdr for us
|
|
1336
|
+
if (err) { DNSServiceRefDeallocate(*sdRef); *sdRef = NULL; }
|
|
1337
|
+
return err;
|
|
1338
|
+
}
|
|
1339
|
+
|
|
1340
|
+
static void handle_browse_response(DNSServiceOp *const sdr, const CallbackHeader *const cbh, const char *data, const char *const end)
|
|
1341
|
+
{
|
|
1342
|
+
char replyName[256], replyType[kDNSServiceMaxDomainName], replyDomain[kDNSServiceMaxDomainName];
|
|
1343
|
+
get_string(&data, end, replyName, 256);
|
|
1344
|
+
get_string(&data, end, replyType, kDNSServiceMaxDomainName);
|
|
1345
|
+
get_string(&data, end, replyDomain, kDNSServiceMaxDomainName);
|
|
1346
|
+
if (!data) syslog(LOG_WARNING, "dnssd_clientstub handle_browse_response: error reading result from daemon");
|
|
1347
|
+
else ((DNSServiceBrowseReply)sdr->AppCallback)(sdr, cbh->cb_flags, cbh->cb_interface, cbh->cb_err, replyName, replyType, replyDomain, sdr->AppContext);
|
|
1348
|
+
// MUST NOT touch sdr after invoking AppCallback -- client is allowed to dispose it from within callback function
|
|
1349
|
+
}
|
|
1350
|
+
|
|
1351
|
+
DNSServiceErrorType DNSSD_API DNSServiceBrowse
|
|
1352
|
+
(
|
|
1353
|
+
DNSServiceRef *sdRef,
|
|
1354
|
+
DNSServiceFlags flags,
|
|
1355
|
+
uint32_t interfaceIndex,
|
|
1356
|
+
const char *regtype,
|
|
1357
|
+
const char *domain,
|
|
1358
|
+
DNSServiceBrowseReply callBack,
|
|
1359
|
+
void *context
|
|
1360
|
+
)
|
|
1361
|
+
{
|
|
1362
|
+
char *ptr;
|
|
1363
|
+
size_t len;
|
|
1364
|
+
ipc_msg_hdr *hdr;
|
|
1365
|
+
DNSServiceErrorType err = ConnectToServer(sdRef, flags, browse_request, handle_browse_response, callBack, context);
|
|
1366
|
+
if (err) return err; // On error ConnectToServer leaves *sdRef set to NULL
|
|
1367
|
+
|
|
1368
|
+
if (!domain) domain = "";
|
|
1369
|
+
len = sizeof(flags);
|
|
1370
|
+
len += sizeof(interfaceIndex);
|
|
1371
|
+
len += strlen(regtype) + 1;
|
|
1372
|
+
len += strlen(domain) + 1;
|
|
1373
|
+
|
|
1374
|
+
hdr = create_hdr(browse_request, &len, &ptr, (*sdRef)->primary ? 1 : 0, *sdRef);
|
|
1375
|
+
if (!hdr) { DNSServiceRefDeallocate(*sdRef); *sdRef = NULL; return kDNSServiceErr_NoMemory; }
|
|
1376
|
+
|
|
1377
|
+
put_flags(flags, &ptr);
|
|
1378
|
+
put_uint32(interfaceIndex, &ptr);
|
|
1379
|
+
put_string(regtype, &ptr);
|
|
1380
|
+
put_string(domain, &ptr);
|
|
1381
|
+
|
|
1382
|
+
err = deliver_request(hdr, *sdRef); // Will free hdr for us
|
|
1383
|
+
if (err) { DNSServiceRefDeallocate(*sdRef); *sdRef = NULL; }
|
|
1384
|
+
return err;
|
|
1385
|
+
}
|
|
1386
|
+
|
|
1387
|
+
static void handle_hostname_changed_response(
|
|
1388
|
+
DNSServiceOp *const sdr,
|
|
1389
|
+
const CallbackHeader *const cbh,
|
|
1390
|
+
const char *data,
|
|
1391
|
+
const char *const end)
|
|
1392
|
+
{
|
|
1393
|
+
char replyHostname[256];
|
|
1394
|
+
get_string(&data, end, replyHostname, sizeof(replyHostname));
|
|
1395
|
+
if (!data) syslog(LOG_WARNING,
|
|
1396
|
+
"dnssd_clientstub handle_hostname_changed_response: error reading result from daemon");
|
|
1397
|
+
else ((DNSHostnameChangedReply)sdr->AppCallback)(
|
|
1398
|
+
sdr, cbh->cb_flags, cbh->cb_err, replyHostname, sdr->AppContext);
|
|
1399
|
+
}
|
|
1400
|
+
|
|
1401
|
+
DNSServiceErrorType DNSSD_API DNSSetHostname
|
|
1402
|
+
(
|
|
1403
|
+
DNSServiceRef *sdRef,
|
|
1404
|
+
DNSServiceFlags flags,
|
|
1405
|
+
const char *hostname,
|
|
1406
|
+
DNSHostnameChangedReply callBack,
|
|
1407
|
+
void *context
|
|
1408
|
+
)
|
|
1409
|
+
{
|
|
1410
|
+
char *ptr;
|
|
1411
|
+
size_t len;
|
|
1412
|
+
ipc_msg_hdr *hdr;
|
|
1413
|
+
DNSServiceErrorType err = ConnectToServer(sdRef, flags, sethost_request,
|
|
1414
|
+
handle_hostname_changed_response, callBack, context);
|
|
1415
|
+
if (err) return err;
|
|
1416
|
+
len = sizeof(flags);
|
|
1417
|
+
len += strlen(hostname) + 1;
|
|
1418
|
+
hdr = create_hdr(sethost_request, &len, &ptr,
|
|
1419
|
+
(*sdRef)->primary ? 1 : 0, *sdRef);
|
|
1420
|
+
if (!hdr)
|
|
1421
|
+
{
|
|
1422
|
+
DNSServiceRefDeallocate(*sdRef);
|
|
1423
|
+
*sdRef = NULL;
|
|
1424
|
+
return kDNSServiceErr_NoMemory;
|
|
1425
|
+
}
|
|
1426
|
+
put_flags(flags, &ptr);
|
|
1427
|
+
put_string(hostname, &ptr);
|
|
1428
|
+
err = deliver_request(hdr, *sdRef);
|
|
1429
|
+
if (err) { DNSServiceRefDeallocate(*sdRef); *sdRef = NULL; }
|
|
1430
|
+
return err;
|
|
1431
|
+
}
|
|
1432
|
+
|
|
1433
|
+
DNSServiceErrorType DNSSD_API DNSServiceSetDefaultDomainForUser(DNSServiceFlags flags, const char *domain);
|
|
1434
|
+
DNSServiceErrorType DNSSD_API DNSServiceSetDefaultDomainForUser(DNSServiceFlags flags, const char *domain)
|
|
1435
|
+
{
|
|
1436
|
+
DNSServiceOp *tmp;
|
|
1437
|
+
char *ptr;
|
|
1438
|
+
size_t len = sizeof(flags) + strlen(domain) + 1;
|
|
1439
|
+
ipc_msg_hdr *hdr;
|
|
1440
|
+
DNSServiceErrorType err = ConnectToServer(&tmp, 0, setdomain_request, NULL, NULL, NULL);
|
|
1441
|
+
if (err) return err;
|
|
1442
|
+
|
|
1443
|
+
hdr = create_hdr(setdomain_request, &len, &ptr, 0, tmp);
|
|
1444
|
+
if (!hdr) { DNSServiceRefDeallocate(tmp); return kDNSServiceErr_NoMemory; }
|
|
1445
|
+
|
|
1446
|
+
put_flags(flags, &ptr);
|
|
1447
|
+
put_string(domain, &ptr);
|
|
1448
|
+
err = deliver_request(hdr, tmp); // Will free hdr for us
|
|
1449
|
+
DNSServiceRefDeallocate(tmp);
|
|
1450
|
+
return err;
|
|
1451
|
+
}
|
|
1452
|
+
|
|
1453
|
+
static void handle_regservice_response(DNSServiceOp *const sdr, const CallbackHeader *const cbh, const char *data, const char *const end)
|
|
1454
|
+
{
|
|
1455
|
+
char name[256], regtype[kDNSServiceMaxDomainName], domain[kDNSServiceMaxDomainName];
|
|
1456
|
+
get_string(&data, end, name, 256);
|
|
1457
|
+
get_string(&data, end, regtype, kDNSServiceMaxDomainName);
|
|
1458
|
+
get_string(&data, end, domain, kDNSServiceMaxDomainName);
|
|
1459
|
+
if (!data) syslog(LOG_WARNING, "dnssd_clientstub handle_regservice_response: error reading result from daemon");
|
|
1460
|
+
else ((DNSServiceRegisterReply)sdr->AppCallback)(sdr, cbh->cb_flags, cbh->cb_err, name, regtype, domain, sdr->AppContext);
|
|
1461
|
+
// MUST NOT touch sdr after invoking AppCallback -- client is allowed to dispose it from within callback function
|
|
1462
|
+
}
|
|
1463
|
+
|
|
1464
|
+
DNSServiceErrorType DNSSD_API DNSServiceRegister
|
|
1465
|
+
(
|
|
1466
|
+
DNSServiceRef *sdRef,
|
|
1467
|
+
DNSServiceFlags flags,
|
|
1468
|
+
uint32_t interfaceIndex,
|
|
1469
|
+
const char *name,
|
|
1470
|
+
const char *regtype,
|
|
1471
|
+
const char *domain,
|
|
1472
|
+
const char *host,
|
|
1473
|
+
uint16_t PortInNetworkByteOrder,
|
|
1474
|
+
uint16_t txtLen,
|
|
1475
|
+
const void *txtRecord,
|
|
1476
|
+
DNSServiceRegisterReply callBack,
|
|
1477
|
+
void *context
|
|
1478
|
+
)
|
|
1479
|
+
{
|
|
1480
|
+
char *ptr;
|
|
1481
|
+
size_t len;
|
|
1482
|
+
ipc_msg_hdr *hdr;
|
|
1483
|
+
DNSServiceErrorType err;
|
|
1484
|
+
union { uint16_t s; u_char b[2]; } port = { PortInNetworkByteOrder };
|
|
1485
|
+
|
|
1486
|
+
if (!name) name = "";
|
|
1487
|
+
if (!regtype) return kDNSServiceErr_BadParam;
|
|
1488
|
+
if (!domain) domain = "";
|
|
1489
|
+
if (!host) host = "";
|
|
1490
|
+
if (!txtRecord) txtRecord = (void*)"";
|
|
1491
|
+
|
|
1492
|
+
// No callback must have auto-rename
|
|
1493
|
+
if (!callBack && (flags & kDNSServiceFlagsNoAutoRename)) return kDNSServiceErr_BadParam;
|
|
1494
|
+
|
|
1495
|
+
err = ConnectToServer(sdRef, flags, reg_service_request, callBack ? handle_regservice_response : NULL, callBack, context);
|
|
1496
|
+
if (err) return err; // On error ConnectToServer leaves *sdRef set to NULL
|
|
1497
|
+
|
|
1498
|
+
len = sizeof(DNSServiceFlags);
|
|
1499
|
+
len += sizeof(uint32_t); // interfaceIndex
|
|
1500
|
+
len += strlen(name) + strlen(regtype) + strlen(domain) + strlen(host) + 4;
|
|
1501
|
+
len += 2 * sizeof(uint16_t); // port, txtLen
|
|
1502
|
+
len += txtLen;
|
|
1503
|
+
|
|
1504
|
+
hdr = create_hdr(reg_service_request, &len, &ptr, (*sdRef)->primary ? 1 : 0, *sdRef);
|
|
1505
|
+
if (!hdr) { DNSServiceRefDeallocate(*sdRef); *sdRef = NULL; return kDNSServiceErr_NoMemory; }
|
|
1506
|
+
if (!callBack) hdr->ipc_flags |= IPC_FLAGS_NOREPLY;
|
|
1507
|
+
|
|
1508
|
+
put_flags(flags, &ptr);
|
|
1509
|
+
put_uint32(interfaceIndex, &ptr);
|
|
1510
|
+
put_string(name, &ptr);
|
|
1511
|
+
put_string(regtype, &ptr);
|
|
1512
|
+
put_string(domain, &ptr);
|
|
1513
|
+
put_string(host, &ptr);
|
|
1514
|
+
*ptr++ = port.b[0];
|
|
1515
|
+
*ptr++ = port.b[1];
|
|
1516
|
+
put_uint16(txtLen, &ptr);
|
|
1517
|
+
put_rdata(txtLen, txtRecord, &ptr);
|
|
1518
|
+
|
|
1519
|
+
err = deliver_request(hdr, *sdRef); // Will free hdr for us
|
|
1520
|
+
if (err) { DNSServiceRefDeallocate(*sdRef); *sdRef = NULL; }
|
|
1521
|
+
return err;
|
|
1522
|
+
}
|
|
1523
|
+
|
|
1524
|
+
static void handle_enumeration_response(DNSServiceOp *const sdr, const CallbackHeader *const cbh, const char *data, const char *const end)
|
|
1525
|
+
{
|
|
1526
|
+
char domain[kDNSServiceMaxDomainName];
|
|
1527
|
+
get_string(&data, end, domain, kDNSServiceMaxDomainName);
|
|
1528
|
+
if (!data) syslog(LOG_WARNING, "dnssd_clientstub handle_enumeration_response: error reading result from daemon");
|
|
1529
|
+
else ((DNSServiceDomainEnumReply)sdr->AppCallback)(sdr, cbh->cb_flags, cbh->cb_interface, cbh->cb_err, domain, sdr->AppContext);
|
|
1530
|
+
// MUST NOT touch sdr after invoking AppCallback -- client is allowed to dispose it from within callback function
|
|
1531
|
+
}
|
|
1532
|
+
|
|
1533
|
+
DNSServiceErrorType DNSSD_API DNSServiceEnumerateDomains
|
|
1534
|
+
(
|
|
1535
|
+
DNSServiceRef *sdRef,
|
|
1536
|
+
DNSServiceFlags flags,
|
|
1537
|
+
uint32_t interfaceIndex,
|
|
1538
|
+
DNSServiceDomainEnumReply callBack,
|
|
1539
|
+
void *context
|
|
1540
|
+
)
|
|
1541
|
+
{
|
|
1542
|
+
char *ptr;
|
|
1543
|
+
size_t len;
|
|
1544
|
+
ipc_msg_hdr *hdr;
|
|
1545
|
+
DNSServiceErrorType err;
|
|
1546
|
+
|
|
1547
|
+
int f1 = (flags & kDNSServiceFlagsBrowseDomains) != 0;
|
|
1548
|
+
int f2 = (flags & kDNSServiceFlagsRegistrationDomains) != 0;
|
|
1549
|
+
if (f1 + f2 != 1) return kDNSServiceErr_BadParam;
|
|
1550
|
+
|
|
1551
|
+
err = ConnectToServer(sdRef, flags, enumeration_request, handle_enumeration_response, callBack, context);
|
|
1552
|
+
if (err) return err; // On error ConnectToServer leaves *sdRef set to NULL
|
|
1553
|
+
|
|
1554
|
+
len = sizeof(DNSServiceFlags);
|
|
1555
|
+
len += sizeof(uint32_t);
|
|
1556
|
+
|
|
1557
|
+
hdr = create_hdr(enumeration_request, &len, &ptr, (*sdRef)->primary ? 1 : 0, *sdRef);
|
|
1558
|
+
if (!hdr) { DNSServiceRefDeallocate(*sdRef); *sdRef = NULL; return kDNSServiceErr_NoMemory; }
|
|
1559
|
+
|
|
1560
|
+
put_flags(flags, &ptr);
|
|
1561
|
+
put_uint32(interfaceIndex, &ptr);
|
|
1562
|
+
|
|
1563
|
+
err = deliver_request(hdr, *sdRef); // Will free hdr for us
|
|
1564
|
+
if (err) { DNSServiceRefDeallocate(*sdRef); *sdRef = NULL; }
|
|
1565
|
+
return err;
|
|
1566
|
+
}
|
|
1567
|
+
|
|
1568
|
+
static void ConnectionResponse(DNSServiceOp *const sdr, const CallbackHeader *const cbh, const char *const data, const char *const end)
|
|
1569
|
+
{
|
|
1570
|
+
DNSRecordRef rref = cbh->ipc_hdr.client_context.context;
|
|
1571
|
+
(void)data; // Unused
|
|
1572
|
+
|
|
1573
|
+
//printf("ConnectionResponse got %d\n", cbh->ipc_hdr.op);
|
|
1574
|
+
if (cbh->ipc_hdr.op != reg_record_reply_op)
|
|
1575
|
+
{
|
|
1576
|
+
// When using kDNSServiceFlagsShareConnection, need to search the list of associated DNSServiceOps
|
|
1577
|
+
// to find the one this response is intended for, and then call through to its ProcessReply handler.
|
|
1578
|
+
// We start with our first subordinate DNSServiceRef -- don't want to accidentally match the parent DNSServiceRef.
|
|
1579
|
+
DNSServiceOp *op = sdr->next;
|
|
1580
|
+
while (op && (op->uid.u32[0] != cbh->ipc_hdr.client_context.u32[0] || op->uid.u32[1] != cbh->ipc_hdr.client_context.u32[1]))
|
|
1581
|
+
op = op->next;
|
|
1582
|
+
// Note: We may sometimes not find a matching DNSServiceOp, in the case where the client has
|
|
1583
|
+
// cancelled the subordinate DNSServiceOp, but there are still messages in the pipeline from the daemon
|
|
1584
|
+
if (op && op->ProcessReply) op->ProcessReply(op, cbh, data, end);
|
|
1585
|
+
// WARNING: Don't touch op or sdr after this -- client may have called DNSServiceRefDeallocate
|
|
1586
|
+
return;
|
|
1587
|
+
}
|
|
1588
|
+
|
|
1589
|
+
if (sdr->op == connection_request)
|
|
1590
|
+
rref->AppCallback(rref->sdr, rref, cbh->cb_flags, cbh->cb_err, rref->AppContext);
|
|
1591
|
+
else
|
|
1592
|
+
{
|
|
1593
|
+
syslog(LOG_WARNING, "dnssd_clientstub ConnectionResponse: sdr->op != connection_request");
|
|
1594
|
+
rref->AppCallback(rref->sdr, rref, 0, kDNSServiceErr_Unknown, rref->AppContext);
|
|
1595
|
+
}
|
|
1596
|
+
// MUST NOT touch sdr after invoking AppCallback -- client is allowed to dispose it from within callback function
|
|
1597
|
+
}
|
|
1598
|
+
|
|
1599
|
+
DNSServiceErrorType DNSSD_API DNSServiceCreateConnection(DNSServiceRef *sdRef)
|
|
1600
|
+
{
|
|
1601
|
+
char *ptr;
|
|
1602
|
+
size_t len = 0;
|
|
1603
|
+
ipc_msg_hdr *hdr;
|
|
1604
|
+
DNSServiceErrorType err = ConnectToServer(sdRef, 0, connection_request, ConnectionResponse, NULL, NULL);
|
|
1605
|
+
if (err) return err; // On error ConnectToServer leaves *sdRef set to NULL
|
|
1606
|
+
|
|
1607
|
+
hdr = create_hdr(connection_request, &len, &ptr, 0, *sdRef);
|
|
1608
|
+
if (!hdr) { DNSServiceRefDeallocate(*sdRef); *sdRef = NULL; return kDNSServiceErr_NoMemory; }
|
|
1609
|
+
|
|
1610
|
+
err = deliver_request(hdr, *sdRef); // Will free hdr for us
|
|
1611
|
+
if (err) { DNSServiceRefDeallocate(*sdRef); *sdRef = NULL; }
|
|
1612
|
+
return err;
|
|
1613
|
+
}
|
|
1614
|
+
|
|
1615
|
+
DNSServiceErrorType DNSSD_API DNSServiceRegisterRecord
|
|
1616
|
+
(
|
|
1617
|
+
DNSServiceRef sdRef,
|
|
1618
|
+
DNSRecordRef *RecordRef,
|
|
1619
|
+
DNSServiceFlags flags,
|
|
1620
|
+
uint32_t interfaceIndex,
|
|
1621
|
+
const char *fullname,
|
|
1622
|
+
uint16_t rrtype,
|
|
1623
|
+
uint16_t rrclass,
|
|
1624
|
+
uint16_t rdlen,
|
|
1625
|
+
const void *rdata,
|
|
1626
|
+
uint32_t ttl,
|
|
1627
|
+
DNSServiceRegisterRecordReply callBack,
|
|
1628
|
+
void *context
|
|
1629
|
+
)
|
|
1630
|
+
{
|
|
1631
|
+
char *ptr;
|
|
1632
|
+
size_t len;
|
|
1633
|
+
ipc_msg_hdr *hdr = NULL;
|
|
1634
|
+
DNSRecordRef rref = NULL;
|
|
1635
|
+
DNSRecord **p;
|
|
1636
|
+
int f1 = (flags & kDNSServiceFlagsShared) != 0;
|
|
1637
|
+
int f2 = (flags & kDNSServiceFlagsUnique) != 0;
|
|
1638
|
+
if (f1 + f2 != 1) return kDNSServiceErr_BadParam;
|
|
1639
|
+
|
|
1640
|
+
if (!sdRef) { syslog(LOG_WARNING, "dnssd_clientstub DNSServiceRegisterRecord called with NULL DNSServiceRef"); return kDNSServiceErr_BadParam; }
|
|
1641
|
+
|
|
1642
|
+
if (!DNSServiceRefValid(sdRef))
|
|
1643
|
+
{
|
|
1644
|
+
syslog(LOG_WARNING, "dnssd_clientstub DNSServiceRegisterRecord called with invalid DNSServiceRef %p %08X %08X", sdRef, sdRef->sockfd, sdRef->validator);
|
|
1645
|
+
return kDNSServiceErr_BadReference;
|
|
1646
|
+
}
|
|
1647
|
+
|
|
1648
|
+
if (sdRef->op != connection_request)
|
|
1649
|
+
{
|
|
1650
|
+
syslog(LOG_WARNING, "dnssd_clientstub DNSServiceRegisterRecord called with non-DNSServiceCreateConnection DNSServiceRef %p %d", sdRef, sdRef->op);
|
|
1651
|
+
return kDNSServiceErr_BadReference;
|
|
1652
|
+
}
|
|
1653
|
+
|
|
1654
|
+
*RecordRef = NULL;
|
|
1655
|
+
|
|
1656
|
+
len = sizeof(DNSServiceFlags);
|
|
1657
|
+
len += 2 * sizeof(uint32_t); // interfaceIndex, ttl
|
|
1658
|
+
len += 3 * sizeof(uint16_t); // rrtype, rrclass, rdlen
|
|
1659
|
+
len += strlen(fullname) + 1;
|
|
1660
|
+
len += rdlen;
|
|
1661
|
+
|
|
1662
|
+
hdr = create_hdr(reg_record_request, &len, &ptr, 1, sdRef);
|
|
1663
|
+
if (!hdr) return kDNSServiceErr_NoMemory;
|
|
1664
|
+
|
|
1665
|
+
put_flags(flags, &ptr);
|
|
1666
|
+
put_uint32(interfaceIndex, &ptr);
|
|
1667
|
+
put_string(fullname, &ptr);
|
|
1668
|
+
put_uint16(rrtype, &ptr);
|
|
1669
|
+
put_uint16(rrclass, &ptr);
|
|
1670
|
+
put_uint16(rdlen, &ptr);
|
|
1671
|
+
put_rdata(rdlen, rdata, &ptr);
|
|
1672
|
+
put_uint32(ttl, &ptr);
|
|
1673
|
+
|
|
1674
|
+
rref = malloc(sizeof(DNSRecord));
|
|
1675
|
+
if (!rref) { free(hdr); return kDNSServiceErr_NoMemory; }
|
|
1676
|
+
rref->AppContext = context;
|
|
1677
|
+
rref->AppCallback = callBack;
|
|
1678
|
+
rref->record_index = sdRef->max_index++;
|
|
1679
|
+
rref->sdr = sdRef;
|
|
1680
|
+
rref->recnext = NULL;
|
|
1681
|
+
*RecordRef = rref;
|
|
1682
|
+
hdr->client_context.context = rref;
|
|
1683
|
+
hdr->reg_index = rref->record_index;
|
|
1684
|
+
|
|
1685
|
+
p = &(sdRef)->rec;
|
|
1686
|
+
while (*p) p = &(*p)->recnext;
|
|
1687
|
+
*p = rref;
|
|
1688
|
+
|
|
1689
|
+
return deliver_request(hdr, sdRef); // Will free hdr for us
|
|
1690
|
+
}
|
|
1691
|
+
|
|
1692
|
+
// sdRef returned by DNSServiceRegister()
|
|
1693
|
+
DNSServiceErrorType DNSSD_API DNSServiceAddRecord
|
|
1694
|
+
(
|
|
1695
|
+
DNSServiceRef sdRef,
|
|
1696
|
+
DNSRecordRef *RecordRef,
|
|
1697
|
+
DNSServiceFlags flags,
|
|
1698
|
+
uint16_t rrtype,
|
|
1699
|
+
uint16_t rdlen,
|
|
1700
|
+
const void *rdata,
|
|
1701
|
+
uint32_t ttl
|
|
1702
|
+
)
|
|
1703
|
+
{
|
|
1704
|
+
ipc_msg_hdr *hdr;
|
|
1705
|
+
size_t len = 0;
|
|
1706
|
+
char *ptr;
|
|
1707
|
+
DNSRecordRef rref;
|
|
1708
|
+
DNSRecord **p;
|
|
1709
|
+
|
|
1710
|
+
if (!sdRef) { syslog(LOG_WARNING, "dnssd_clientstub DNSServiceAddRecord called with NULL DNSServiceRef"); return kDNSServiceErr_BadParam; }
|
|
1711
|
+
if (!RecordRef) { syslog(LOG_WARNING, "dnssd_clientstub DNSServiceAddRecord called with NULL DNSRecordRef pointer"); return kDNSServiceErr_BadParam; }
|
|
1712
|
+
if (sdRef->op != reg_service_request)
|
|
1713
|
+
{
|
|
1714
|
+
syslog(LOG_WARNING, "dnssd_clientstub DNSServiceAddRecord called with non-DNSServiceRegister DNSServiceRef %p %d", sdRef, sdRef->op);
|
|
1715
|
+
return kDNSServiceErr_BadReference;
|
|
1716
|
+
}
|
|
1717
|
+
|
|
1718
|
+
if (!DNSServiceRefValid(sdRef))
|
|
1719
|
+
{
|
|
1720
|
+
syslog(LOG_WARNING, "dnssd_clientstub DNSServiceAddRecord called with invalid DNSServiceRef %p %08X %08X", sdRef, sdRef->sockfd, sdRef->validator);
|
|
1721
|
+
return kDNSServiceErr_BadReference;
|
|
1722
|
+
}
|
|
1723
|
+
|
|
1724
|
+
*RecordRef = NULL;
|
|
1725
|
+
|
|
1726
|
+
len += 2 * sizeof(uint16_t); // rrtype, rdlen
|
|
1727
|
+
len += rdlen;
|
|
1728
|
+
len += sizeof(uint32_t);
|
|
1729
|
+
len += sizeof(DNSServiceFlags);
|
|
1730
|
+
|
|
1731
|
+
hdr = create_hdr(add_record_request, &len, &ptr, 1, sdRef);
|
|
1732
|
+
if (!hdr) return kDNSServiceErr_NoMemory;
|
|
1733
|
+
put_flags(flags, &ptr);
|
|
1734
|
+
put_uint16(rrtype, &ptr);
|
|
1735
|
+
put_uint16(rdlen, &ptr);
|
|
1736
|
+
put_rdata(rdlen, rdata, &ptr);
|
|
1737
|
+
put_uint32(ttl, &ptr);
|
|
1738
|
+
|
|
1739
|
+
rref = malloc(sizeof(DNSRecord));
|
|
1740
|
+
if (!rref) { free(hdr); return kDNSServiceErr_NoMemory; }
|
|
1741
|
+
rref->AppContext = NULL;
|
|
1742
|
+
rref->AppCallback = NULL;
|
|
1743
|
+
rref->record_index = sdRef->max_index++;
|
|
1744
|
+
rref->sdr = sdRef;
|
|
1745
|
+
rref->recnext = NULL;
|
|
1746
|
+
*RecordRef = rref;
|
|
1747
|
+
hdr->reg_index = rref->record_index;
|
|
1748
|
+
|
|
1749
|
+
p = &(sdRef)->rec;
|
|
1750
|
+
while (*p) p = &(*p)->recnext;
|
|
1751
|
+
*p = rref;
|
|
1752
|
+
|
|
1753
|
+
return deliver_request(hdr, sdRef); // Will free hdr for us
|
|
1754
|
+
}
|
|
1755
|
+
|
|
1756
|
+
// DNSRecordRef returned by DNSServiceRegisterRecord or DNSServiceAddRecord
|
|
1757
|
+
DNSServiceErrorType DNSSD_API DNSServiceUpdateRecord
|
|
1758
|
+
(
|
|
1759
|
+
DNSServiceRef sdRef,
|
|
1760
|
+
DNSRecordRef RecordRef,
|
|
1761
|
+
DNSServiceFlags flags,
|
|
1762
|
+
uint16_t rdlen,
|
|
1763
|
+
const void *rdata,
|
|
1764
|
+
uint32_t ttl
|
|
1765
|
+
)
|
|
1766
|
+
{
|
|
1767
|
+
ipc_msg_hdr *hdr;
|
|
1768
|
+
size_t len = 0;
|
|
1769
|
+
char *ptr;
|
|
1770
|
+
|
|
1771
|
+
if (!sdRef) { syslog(LOG_WARNING, "dnssd_clientstub DNSServiceUpdateRecord called with NULL DNSServiceRef"); return kDNSServiceErr_BadParam; }
|
|
1772
|
+
|
|
1773
|
+
if (!DNSServiceRefValid(sdRef))
|
|
1774
|
+
{
|
|
1775
|
+
syslog(LOG_WARNING, "dnssd_clientstub DNSServiceUpdateRecord called with invalid DNSServiceRef %p %08X %08X", sdRef, sdRef->sockfd, sdRef->validator);
|
|
1776
|
+
return kDNSServiceErr_BadReference;
|
|
1777
|
+
}
|
|
1778
|
+
|
|
1779
|
+
// Note: RecordRef is allowed to be NULL
|
|
1780
|
+
|
|
1781
|
+
len += sizeof(uint16_t);
|
|
1782
|
+
len += rdlen;
|
|
1783
|
+
len += sizeof(uint32_t);
|
|
1784
|
+
len += sizeof(DNSServiceFlags);
|
|
1785
|
+
|
|
1786
|
+
hdr = create_hdr(update_record_request, &len, &ptr, 1, sdRef);
|
|
1787
|
+
if (!hdr) return kDNSServiceErr_NoMemory;
|
|
1788
|
+
hdr->reg_index = RecordRef ? RecordRef->record_index : TXT_RECORD_INDEX;
|
|
1789
|
+
put_flags(flags, &ptr);
|
|
1790
|
+
put_uint16(rdlen, &ptr);
|
|
1791
|
+
put_rdata(rdlen, rdata, &ptr);
|
|
1792
|
+
put_uint32(ttl, &ptr);
|
|
1793
|
+
return deliver_request(hdr, sdRef); // Will free hdr for us
|
|
1794
|
+
}
|
|
1795
|
+
|
|
1796
|
+
DNSServiceErrorType DNSSD_API DNSServiceRemoveRecord
|
|
1797
|
+
(
|
|
1798
|
+
DNSServiceRef sdRef,
|
|
1799
|
+
DNSRecordRef RecordRef,
|
|
1800
|
+
DNSServiceFlags flags
|
|
1801
|
+
)
|
|
1802
|
+
{
|
|
1803
|
+
ipc_msg_hdr *hdr;
|
|
1804
|
+
size_t len = 0;
|
|
1805
|
+
char *ptr;
|
|
1806
|
+
DNSServiceErrorType err;
|
|
1807
|
+
|
|
1808
|
+
if (!sdRef) { syslog(LOG_WARNING, "dnssd_clientstub DNSServiceRemoveRecord called with NULL DNSServiceRef"); return kDNSServiceErr_BadParam; }
|
|
1809
|
+
if (!RecordRef) { syslog(LOG_WARNING, "dnssd_clientstub DNSServiceRemoveRecord called with NULL DNSRecordRef"); return kDNSServiceErr_BadParam; }
|
|
1810
|
+
if (!sdRef->max_index) { syslog(LOG_WARNING, "dnssd_clientstub DNSServiceRemoveRecord called with bad DNSServiceRef"); return kDNSServiceErr_BadReference; }
|
|
1811
|
+
|
|
1812
|
+
if (!DNSServiceRefValid(sdRef))
|
|
1813
|
+
{
|
|
1814
|
+
syslog(LOG_WARNING, "dnssd_clientstub DNSServiceRemoveRecord called with invalid DNSServiceRef %p %08X %08X", sdRef, sdRef->sockfd, sdRef->validator);
|
|
1815
|
+
return kDNSServiceErr_BadReference;
|
|
1816
|
+
}
|
|
1817
|
+
|
|
1818
|
+
len += sizeof(flags);
|
|
1819
|
+
hdr = create_hdr(remove_record_request, &len, &ptr, 1, sdRef);
|
|
1820
|
+
if (!hdr) return kDNSServiceErr_NoMemory;
|
|
1821
|
+
hdr->reg_index = RecordRef->record_index;
|
|
1822
|
+
put_flags(flags, &ptr);
|
|
1823
|
+
err = deliver_request(hdr, sdRef); // Will free hdr for us
|
|
1824
|
+
if (!err)
|
|
1825
|
+
{
|
|
1826
|
+
// This RecordRef could have been allocated in DNSServiceRegisterRecord or DNSServiceAddRecord.
|
|
1827
|
+
// If so, delink from the list before freeing
|
|
1828
|
+
DNSRecord **p = &sdRef->rec;
|
|
1829
|
+
while (*p && *p != RecordRef) p = &(*p)->recnext;
|
|
1830
|
+
if (*p) *p = RecordRef->recnext;
|
|
1831
|
+
free(RecordRef);
|
|
1832
|
+
}
|
|
1833
|
+
return err;
|
|
1834
|
+
}
|
|
1835
|
+
|
|
1836
|
+
DNSServiceErrorType DNSSD_API DNSServiceReconfirmRecord
|
|
1837
|
+
(
|
|
1838
|
+
DNSServiceFlags flags,
|
|
1839
|
+
uint32_t interfaceIndex,
|
|
1840
|
+
const char *fullname,
|
|
1841
|
+
uint16_t rrtype,
|
|
1842
|
+
uint16_t rrclass,
|
|
1843
|
+
uint16_t rdlen,
|
|
1844
|
+
const void *rdata
|
|
1845
|
+
)
|
|
1846
|
+
{
|
|
1847
|
+
char *ptr;
|
|
1848
|
+
size_t len;
|
|
1849
|
+
ipc_msg_hdr *hdr;
|
|
1850
|
+
DNSServiceOp *tmp;
|
|
1851
|
+
|
|
1852
|
+
DNSServiceErrorType err = ConnectToServer(&tmp, flags, reconfirm_record_request, NULL, NULL, NULL);
|
|
1853
|
+
if (err) return err;
|
|
1854
|
+
|
|
1855
|
+
len = sizeof(DNSServiceFlags);
|
|
1856
|
+
len += sizeof(uint32_t);
|
|
1857
|
+
len += strlen(fullname) + 1;
|
|
1858
|
+
len += 3 * sizeof(uint16_t);
|
|
1859
|
+
len += rdlen;
|
|
1860
|
+
hdr = create_hdr(reconfirm_record_request, &len, &ptr, 0, tmp);
|
|
1861
|
+
if (!hdr) { DNSServiceRefDeallocate(tmp); return kDNSServiceErr_NoMemory; }
|
|
1862
|
+
|
|
1863
|
+
put_flags(flags, &ptr);
|
|
1864
|
+
put_uint32(interfaceIndex, &ptr);
|
|
1865
|
+
put_string(fullname, &ptr);
|
|
1866
|
+
put_uint16(rrtype, &ptr);
|
|
1867
|
+
put_uint16(rrclass, &ptr);
|
|
1868
|
+
put_uint16(rdlen, &ptr);
|
|
1869
|
+
put_rdata(rdlen, rdata, &ptr);
|
|
1870
|
+
|
|
1871
|
+
err = deliver_request(hdr, tmp); // Will free hdr for us
|
|
1872
|
+
DNSServiceRefDeallocate(tmp);
|
|
1873
|
+
return err;
|
|
1874
|
+
}
|
|
1875
|
+
|
|
1876
|
+
static void handle_port_mapping_response(DNSServiceOp *const sdr, const CallbackHeader *const cbh, const char *data, const char *const end)
|
|
1877
|
+
{
|
|
1878
|
+
union { uint32_t l; u_char b[4]; } addr;
|
|
1879
|
+
uint8_t protocol;
|
|
1880
|
+
union { uint16_t s; u_char b[2]; } internalPort;
|
|
1881
|
+
union { uint16_t s; u_char b[2]; } externalPort;
|
|
1882
|
+
uint32_t ttl;
|
|
1883
|
+
|
|
1884
|
+
if (!data || data + 13 > end) goto fail;
|
|
1885
|
+
|
|
1886
|
+
addr .b[0] = *data++;
|
|
1887
|
+
addr .b[1] = *data++;
|
|
1888
|
+
addr .b[2] = *data++;
|
|
1889
|
+
addr .b[3] = *data++;
|
|
1890
|
+
protocol = *data++;
|
|
1891
|
+
internalPort.b[0] = *data++;
|
|
1892
|
+
internalPort.b[1] = *data++;
|
|
1893
|
+
externalPort.b[0] = *data++;
|
|
1894
|
+
externalPort.b[1] = *data++;
|
|
1895
|
+
ttl = get_uint32(&data, end);
|
|
1896
|
+
if (!data) goto fail;
|
|
1897
|
+
|
|
1898
|
+
((DNSServiceNATPortMappingReply)sdr->AppCallback)(sdr, cbh->cb_flags, cbh->cb_interface, cbh->cb_err, addr.l, protocol, internalPort.s, externalPort.s, ttl, sdr->AppContext);
|
|
1899
|
+
return;
|
|
1900
|
+
// MUST NOT touch sdr after invoking AppCallback -- client is allowed to dispose it from within callback function
|
|
1901
|
+
|
|
1902
|
+
fail:
|
|
1903
|
+
syslog(LOG_WARNING, "dnssd_clientstub handle_port_mapping_response: error reading result from daemon");
|
|
1904
|
+
}
|
|
1905
|
+
|
|
1906
|
+
DNSServiceErrorType DNSSD_API DNSServiceNATPortMappingCreate
|
|
1907
|
+
(
|
|
1908
|
+
DNSServiceRef *sdRef,
|
|
1909
|
+
DNSServiceFlags flags,
|
|
1910
|
+
uint32_t interfaceIndex,
|
|
1911
|
+
uint32_t protocol, /* TCP and/or UDP */
|
|
1912
|
+
uint16_t internalPortInNetworkByteOrder,
|
|
1913
|
+
uint16_t externalPortInNetworkByteOrder,
|
|
1914
|
+
uint32_t ttl, /* time to live in seconds */
|
|
1915
|
+
DNSServiceNATPortMappingReply callBack,
|
|
1916
|
+
void *context /* may be NULL */
|
|
1917
|
+
)
|
|
1918
|
+
{
|
|
1919
|
+
char *ptr;
|
|
1920
|
+
size_t len;
|
|
1921
|
+
ipc_msg_hdr *hdr;
|
|
1922
|
+
union { uint16_t s; u_char b[2]; } internalPort = { internalPortInNetworkByteOrder };
|
|
1923
|
+
union { uint16_t s; u_char b[2]; } externalPort = { externalPortInNetworkByteOrder };
|
|
1924
|
+
|
|
1925
|
+
DNSServiceErrorType err = ConnectToServer(sdRef, flags, port_mapping_request, handle_port_mapping_response, callBack, context);
|
|
1926
|
+
if (err) return err; // On error ConnectToServer leaves *sdRef set to NULL
|
|
1927
|
+
|
|
1928
|
+
len = sizeof(flags);
|
|
1929
|
+
len += sizeof(interfaceIndex);
|
|
1930
|
+
len += sizeof(protocol);
|
|
1931
|
+
len += sizeof(internalPort);
|
|
1932
|
+
len += sizeof(externalPort);
|
|
1933
|
+
len += sizeof(ttl);
|
|
1934
|
+
|
|
1935
|
+
hdr = create_hdr(port_mapping_request, &len, &ptr, (*sdRef)->primary ? 1 : 0, *sdRef);
|
|
1936
|
+
if (!hdr) { DNSServiceRefDeallocate(*sdRef); *sdRef = NULL; return kDNSServiceErr_NoMemory; }
|
|
1937
|
+
|
|
1938
|
+
put_flags(flags, &ptr);
|
|
1939
|
+
put_uint32(interfaceIndex, &ptr);
|
|
1940
|
+
put_uint32(protocol, &ptr);
|
|
1941
|
+
*ptr++ = internalPort.b[0];
|
|
1942
|
+
*ptr++ = internalPort.b[1];
|
|
1943
|
+
*ptr++ = externalPort.b[0];
|
|
1944
|
+
*ptr++ = externalPort.b[1];
|
|
1945
|
+
put_uint32(ttl, &ptr);
|
|
1946
|
+
|
|
1947
|
+
err = deliver_request(hdr, *sdRef); // Will free hdr for us
|
|
1948
|
+
if (err) { DNSServiceRefDeallocate(*sdRef); *sdRef = NULL; }
|
|
1949
|
+
return err;
|
|
1950
|
+
}
|
|
1951
|
+
|
|
1952
|
+
#if _DNS_SD_LIBDISPATCH
|
|
1953
|
+
DNSServiceErrorType DNSSD_API DNSServiceSetDispatchQueue
|
|
1954
|
+
(
|
|
1955
|
+
DNSServiceRef service,
|
|
1956
|
+
dispatch_queue_t queue
|
|
1957
|
+
)
|
|
1958
|
+
{
|
|
1959
|
+
int dnssd_fd = DNSServiceRefSockFD(service);
|
|
1960
|
+
if (dnssd_fd == dnssd_InvalidSocket) return kDNSServiceErr_BadParam;
|
|
1961
|
+
if (!queue)
|
|
1962
|
+
{
|
|
1963
|
+
syslog(LOG_WARNING, "dnssd_clientstub: DNSServiceSetDispatchQueue dispatch queue NULL");
|
|
1964
|
+
return kDNSServiceErr_BadParam;
|
|
1965
|
+
}
|
|
1966
|
+
if (service->disp_queue)
|
|
1967
|
+
{
|
|
1968
|
+
syslog(LOG_WARNING, "dnssd_clientstub DNSServiceSetDispatchQueue dispatch queue set already");
|
|
1969
|
+
return kDNSServiceErr_BadParam;
|
|
1970
|
+
}
|
|
1971
|
+
if (service->disp_source)
|
|
1972
|
+
{
|
|
1973
|
+
syslog(LOG_WARNING, "DNSServiceSetDispatchQueue dispatch source set already");
|
|
1974
|
+
return kDNSServiceErr_BadParam;
|
|
1975
|
+
}
|
|
1976
|
+
service->disp_source = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, dnssd_fd, 0, queue);
|
|
1977
|
+
if (!service->disp_source)
|
|
1978
|
+
{
|
|
1979
|
+
syslog(LOG_WARNING, "DNSServiceSetDispatchQueue dispatch_source_create failed");
|
|
1980
|
+
return kDNSServiceErr_NoMemory;
|
|
1981
|
+
}
|
|
1982
|
+
service->disp_queue = queue;
|
|
1983
|
+
dispatch_source_set_event_handler(service->disp_source, ^{DNSServiceProcessResult(service);});
|
|
1984
|
+
dispatch_source_set_cancel_handler(service->disp_source, ^{dnssd_close(dnssd_fd);});
|
|
1985
|
+
dispatch_resume(service->disp_source);
|
|
1986
|
+
return kDNSServiceErr_NoError;
|
|
1987
|
+
}
|
|
1988
|
+
#endif // _DNS_SD_LIBDISPATCH
|