react-native-zeroconf 0.13.8 → 0.14.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.
Files changed (294) hide show
  1. package/NOTICE +49 -0
  2. package/README.md +473 -65
  3. package/android/build.gradle +28 -22
  4. package/android/src/main/AndroidManifest.xml +1 -2
  5. package/android/src/main/java/com/balthazargronon/RCTZeroconf/rx2dnssd/DnssdImpl.java +19 -3
  6. package/android/src/main/java/com/github/druk/dnssd/BaseListener.java +33 -0
  7. package/android/src/main/java/com/github/druk/dnssd/BrowseListener.java +67 -0
  8. package/android/src/main/java/com/github/druk/dnssd/DNSRecord.java +47 -0
  9. package/android/src/main/java/com/github/druk/dnssd/DNSSD.java +650 -0
  10. package/android/src/main/java/com/github/druk/dnssd/DNSSDBindable.java +67 -0
  11. package/android/src/main/java/com/github/druk/dnssd/DNSSDEmbedded.java +135 -0
  12. package/android/src/main/java/com/github/druk/dnssd/DNSSDException.java +66 -0
  13. package/android/src/main/java/com/github/druk/dnssd/DNSSDRecordRegistrar.java +55 -0
  14. package/android/src/main/java/com/github/druk/dnssd/DNSSDRegistration.java +54 -0
  15. package/android/src/main/java/com/github/druk/dnssd/DNSSDService.java +35 -0
  16. package/android/src/main/java/com/github/druk/dnssd/DomainListener.java +57 -0
  17. package/android/src/main/java/com/github/druk/dnssd/InternalBrowseListener.java +76 -0
  18. package/android/src/main/java/com/github/druk/dnssd/InternalDNSSD.java +870 -0
  19. package/android/src/main/java/com/github/druk/dnssd/InternalDNSSDRecordRegistrar.java +30 -0
  20. package/android/src/main/java/com/github/druk/dnssd/InternalDNSSDRegistration.java +34 -0
  21. package/android/src/main/java/com/github/druk/dnssd/InternalDNSSDService.java +29 -0
  22. package/android/src/main/java/com/github/druk/dnssd/InternalDomainListener.java +62 -0
  23. package/android/src/main/java/com/github/druk/dnssd/InternalQueryListener.java +61 -0
  24. package/android/src/main/java/com/github/druk/dnssd/InternalRegisterListener.java +51 -0
  25. package/android/src/main/java/com/github/druk/dnssd/InternalResolveListener.java +58 -0
  26. package/android/src/main/java/com/github/druk/dnssd/NSClass.java +16 -0
  27. package/android/src/main/java/com/github/druk/dnssd/NSType.java +58 -0
  28. package/android/src/main/java/com/github/druk/dnssd/QueryListener.java +54 -0
  29. package/android/src/main/java/com/github/druk/dnssd/RegisterListener.java +46 -0
  30. package/android/src/main/java/com/github/druk/dnssd/RegisterRecordListener.java +35 -0
  31. package/android/src/main/java/com/github/druk/dnssd/ResolveListener.java +55 -0
  32. package/android/src/main/java/com/github/druk/dnssd/TXTRecord.java +293 -0
  33. package/android/src/main/java/com/github/druk/rx2dnssd/BonjourService.java +400 -0
  34. package/android/src/main/java/com/github/druk/rx2dnssd/Rx2BrowseListener.java +55 -0
  35. package/android/src/main/java/com/github/druk/rx2dnssd/Rx2Dnssd.java +127 -0
  36. package/android/src/main/java/com/github/druk/rx2dnssd/Rx2DnssdBindable.java +35 -0
  37. package/android/src/main/java/com/github/druk/rx2dnssd/Rx2DnssdCommon.java +280 -0
  38. package/android/src/main/java/com/github/druk/rx2dnssd/Rx2DnssdEmbedded.java +31 -0
  39. package/android/src/main/java/com/github/druk/rx2dnssd/Rx2QueryListener.java +70 -0
  40. package/android/src/main/java/com/github/druk/rx2dnssd/Rx2RegisterListener.java +47 -0
  41. package/android/src/main/java/com/github/druk/rx2dnssd/Rx2ResolveListener.java +51 -0
  42. package/android/src/main/jni/Android.mk +95 -0
  43. package/android/src/main/jni/Application.mk +3 -0
  44. package/android/src/main/jni/DNSSD.java.h +290 -0
  45. package/android/src/main/jni/JNISupport.c +1140 -0
  46. package/android/src/main/jni/mdnsresponder/Android.bp +215 -0
  47. package/android/src/main/jni/mdnsresponder/Clients/ClientCommon.c +75 -0
  48. package/android/src/main/jni/mdnsresponder/Clients/ClientCommon.h +41 -0
  49. package/android/src/main/jni/mdnsresponder/Clients/Makefile +54 -0
  50. package/android/src/main/jni/mdnsresponder/Clients/ReadMe.txt +25 -0
  51. package/android/src/main/jni/mdnsresponder/Clients/dns-sd.c +1351 -0
  52. package/android/src/main/jni/mdnsresponder/LICENSE +13 -0
  53. package/android/src/main/jni/mdnsresponder/MODULE_LICENSE_APACHE2 +0 -0
  54. package/android/src/main/jni/mdnsresponder/Makefile +41 -0
  55. package/android/src/main/jni/mdnsresponder/NOTICE +13 -0
  56. package/android/src/main/jni/mdnsresponder/PrivateDNS.txt +275 -0
  57. package/android/src/main/jni/mdnsresponder/README.txt +166 -0
  58. package/android/src/main/jni/mdnsresponder/README.version +3 -0
  59. package/android/src/main/jni/mdnsresponder/android/caseMapping/Iphlpapi.h +1 -0
  60. package/android/src/main/jni/mdnsresponder/android/caseMapping/README +3 -0
  61. package/android/src/main/jni/mdnsresponder/android/caseMapping/Resource.h +1 -0
  62. package/android/src/main/jni/mdnsresponder/android/caseMapping/Ws2tcpip.h +1 -0
  63. package/android/src/main/jni/mdnsresponder/android/caseMapping/ipExport.h +1 -0
  64. package/android/src/main/jni/mdnsresponder/android/windows_firewall_dummy.c +10 -0
  65. package/android/src/main/jni/mdnsresponder/mDNSCore/DNSCommon.c +3157 -0
  66. package/android/src/main/jni/mdnsresponder/mDNSCore/DNSCommon.h +292 -0
  67. package/android/src/main/jni/mdnsresponder/mDNSCore/DNSDigest.c +1579 -0
  68. package/android/src/main/jni/mdnsresponder/mDNSCore/Implementer Notes.txt +66 -0
  69. package/android/src/main/jni/mdnsresponder/mDNSCore/mDNS.c +11469 -0
  70. package/android/src/main/jni/mdnsresponder/mDNSCore/mDNSDebug.h +164 -0
  71. package/android/src/main/jni/mdnsresponder/mDNSCore/mDNSEmbeddedAPI.h +2974 -0
  72. package/android/src/main/jni/mdnsresponder/mDNSCore/uDNS.c +4969 -0
  73. package/android/src/main/jni/mdnsresponder/mDNSCore/uDNS.h +132 -0
  74. package/android/src/main/jni/mdnsresponder/mDNSPosix/Client.c +223 -0
  75. package/android/src/main/jni/mdnsresponder/mDNSPosix/ExampleClientApp.c +91 -0
  76. package/android/src/main/jni/mdnsresponder/mDNSPosix/ExampleClientApp.h +18 -0
  77. package/android/src/main/jni/mdnsresponder/mDNSPosix/Identify.c +378 -0
  78. package/android/src/main/jni/mdnsresponder/mDNSPosix/Makefile +520 -0
  79. package/android/src/main/jni/mdnsresponder/mDNSPosix/NetMonitor.c +1010 -0
  80. package/android/src/main/jni/mdnsresponder/mDNSPosix/PosixDaemon.c +329 -0
  81. package/android/src/main/jni/mdnsresponder/mDNSPosix/ProxyResponder.c +300 -0
  82. package/android/src/main/jni/mdnsresponder/mDNSPosix/ReadMe.txt +314 -0
  83. package/android/src/main/jni/mdnsresponder/mDNSPosix/Responder.c +792 -0
  84. package/android/src/main/jni/mdnsresponder/mDNSPosix/Services.txt +36 -0
  85. package/android/src/main/jni/mdnsresponder/mDNSPosix/libnss_mdns.8 +148 -0
  86. package/android/src/main/jni/mdnsresponder/mDNSPosix/mDNSPosix.c +1685 -0
  87. package/android/src/main/jni/mdnsresponder/mDNSPosix/mDNSPosix.h +88 -0
  88. package/android/src/main/jni/mdnsresponder/mDNSPosix/mDNSUNP.c +726 -0
  89. package/android/src/main/jni/mdnsresponder/mDNSPosix/mDNSUNP.h +130 -0
  90. package/android/src/main/jni/mdnsresponder/mDNSPosix/mdnsd.sh +73 -0
  91. package/android/src/main/jni/mdnsresponder/mDNSPosix/nss_ReadMe.txt +125 -0
  92. package/android/src/main/jni/mdnsresponder/mDNSPosix/nss_mdns.c +2723 -0
  93. package/android/src/main/jni/mdnsresponder/mDNSPosix/nss_mdns.conf +13 -0
  94. package/android/src/main/jni/mdnsresponder/mDNSPosix/nss_mdns.conf.5 +135 -0
  95. package/android/src/main/jni/mdnsresponder/mDNSPosix/parselog.py +247 -0
  96. package/android/src/main/jni/mdnsresponder/mDNSResponder.sln +400 -0
  97. package/android/src/main/jni/mdnsresponder/mDNSShared/CommonServices.h +1537 -0
  98. package/android/src/main/jni/mdnsresponder/mDNSShared/DebugServices.c +3075 -0
  99. package/android/src/main/jni/mdnsresponder/mDNSShared/DebugServices.h +1607 -0
  100. package/android/src/main/jni/mdnsresponder/mDNSShared/GenLinkedList.c +319 -0
  101. package/android/src/main/jni/mdnsresponder/mDNSShared/GenLinkedList.h +90 -0
  102. package/android/src/main/jni/mdnsresponder/mDNSShared/PlatformCommon.c +220 -0
  103. package/android/src/main/jni/mdnsresponder/mDNSShared/PlatformCommon.h +18 -0
  104. package/android/src/main/jni/mdnsresponder/mDNSShared/dns-sd.1 +194 -0
  105. package/android/src/main/jni/mdnsresponder/mDNSShared/dns_sd.h +2452 -0
  106. package/android/src/main/jni/mdnsresponder/mDNSShared/dnsextd.8 +69 -0
  107. package/android/src/main/jni/mdnsresponder/mDNSShared/dnsextd.c +3146 -0
  108. package/android/src/main/jni/mdnsresponder/mDNSShared/dnsextd.conf +60 -0
  109. package/android/src/main/jni/mdnsresponder/mDNSShared/dnsextd.h +163 -0
  110. package/android/src/main/jni/mdnsresponder/mDNSShared/dnsextd_lexer.l +84 -0
  111. package/android/src/main/jni/mdnsresponder/mDNSShared/dnsextd_parser.y +585 -0
  112. package/android/src/main/jni/mdnsresponder/mDNSShared/dnssd_clientlib.c +368 -0
  113. package/android/src/main/jni/mdnsresponder/mDNSShared/dnssd_clientshim.c +802 -0
  114. package/android/src/main/jni/mdnsresponder/mDNSShared/dnssd_clientstub.c +1988 -0
  115. package/android/src/main/jni/mdnsresponder/mDNSShared/dnssd_ipc.c +161 -0
  116. package/android/src/main/jni/mdnsresponder/mDNSShared/dnssd_ipc.h +219 -0
  117. package/android/src/main/jni/mdnsresponder/mDNSShared/mDNS.1 +198 -0
  118. package/android/src/main/jni/mdnsresponder/mDNSShared/mDNSDebug.c +93 -0
  119. package/android/src/main/jni/mdnsresponder/mDNSShared/mDNSResponder.8 +116 -0
  120. package/android/src/main/jni/mdnsresponder/mDNSShared/uds_daemon.c +4758 -0
  121. package/android/src/main/jni/mdnsresponder/mDNSShared/uds_daemon.h +80 -0
  122. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/BrowsingPage.cpp +441 -0
  123. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/BrowsingPage.h +156 -0
  124. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ConfigDialog.cpp +59 -0
  125. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ConfigDialog.h +48 -0
  126. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ConfigPropertySheet.cpp +301 -0
  127. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ConfigPropertySheet.h +105 -0
  128. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ControlPanel.cpp +380 -0
  129. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ControlPanel.def +20 -0
  130. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ControlPanel.h +84 -0
  131. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ControlPanel.rc +141 -0
  132. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ControlPanel.vcproj +727 -0
  133. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ControlPanelDll.rc +123 -0
  134. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ControlPanelExe.cpp +373 -0
  135. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ControlPanelExe.h +48 -0
  136. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ControlPanelExe.rc +123 -0
  137. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ControlPanelExe.vcproj +764 -0
  138. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ControlPanelLocRes.rc +270 -0
  139. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ControlPanelLocRes.vcproj +487 -0
  140. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ControlPanelRes.rc +134 -0
  141. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ControlPanelRes.vcproj +518 -0
  142. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/FourthPage.cpp +197 -0
  143. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/FourthPage.h +87 -0
  144. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/RegistrationPage.cpp +387 -0
  145. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/RegistrationPage.h +75 -0
  146. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/SecondPage.cpp +544 -0
  147. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/SecondPage.h +107 -0
  148. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ServicesPage.cpp +273 -0
  149. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ServicesPage.h +123 -0
  150. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/SharedSecret.cpp +115 -0
  151. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/SharedSecret.h +54 -0
  152. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/res/ControlPanel.dll.manifest +10 -0
  153. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/res/ControlPanel.exe.manifest +17 -0
  154. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/res/ControlPanel.manifest +17 -0
  155. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/res/ControlPanel.rc2 +13 -0
  156. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/res/ControlPanel64.manifest +17 -0
  157. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/res/EnergySaver.ico +0 -0
  158. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/res/controlpanel.ico +0 -0
  159. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/res/failure.ico +0 -0
  160. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/res/success.ico +0 -0
  161. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/resource.h +56 -0
  162. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/stdafx.cpp +20 -0
  163. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/stdafx.h +64 -0
  164. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL/dll.aps +0 -0
  165. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL/dll.rc +102 -0
  166. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL/dllmain.c +112 -0
  167. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL/dnssd.def +48 -0
  168. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL/dnssd.vcproj +472 -0
  169. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL/resource.h +27 -0
  170. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL.NET/AssemblyInfo.cpp +84 -0
  171. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL.NET/PString.h +70 -0
  172. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL.NET/Stdafx.cpp +22 -0
  173. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL.NET/Stdafx.h +33 -0
  174. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL.NET/dnssd_NET.cpp +1234 -0
  175. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL.NET/dnssd_NET.h +1392 -0
  176. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL.NET/dnssd_NET.ico +0 -0
  177. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL.NET/dnssd_NET.rc +113 -0
  178. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL.NET/dnssd_NET.vcproj +446 -0
  179. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL.NET/resource.h +3 -0
  180. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLStub/DLLStub.cpp +693 -0
  181. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLStub/DLLStub.h +52 -0
  182. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLStub/DLLStub.vcproj +324 -0
  183. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DLLX.cpp +208 -0
  184. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DLLX.def +35 -0
  185. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DLLX.idl +491 -0
  186. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DLLX.rc +126 -0
  187. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DLLX.rgs +11 -0
  188. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DLLX.vcproj +625 -0
  189. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DNSSD.cpp +892 -0
  190. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DNSSDEventManager.cpp +31 -0
  191. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DNSSDEventManager.h +133 -0
  192. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DNSSDEventManager.rgs +27 -0
  193. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DNSSDRecord.cpp +101 -0
  194. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DNSSDRecord.h +185 -0
  195. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DNSSDRecord.rgs +27 -0
  196. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DNSSDService.cpp +2095 -0
  197. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DNSSDService.h +429 -0
  198. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DNSSDService.rgs +27 -0
  199. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/StringServices.cpp +344 -0
  200. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/StringServices.h +102 -0
  201. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/TXTRecord.cpp +381 -0
  202. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/TXTRecord.h +203 -0
  203. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/TXTRecord.rgs +27 -0
  204. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/_IDNSSDEvents_CP.h +358 -0
  205. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/dlldatax.c +51 -0
  206. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/dlldatax.h +49 -0
  207. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/resource.h +30 -0
  208. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/stdafx.h +88 -0
  209. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/ApplicationVS2002.sln +21 -0
  210. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/ApplicationVS2002.vcproj +253 -0
  211. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/ApplicationVS2003.sln +21 -0
  212. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/ApplicationVS2003.vcproj +267 -0
  213. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/Resources/Application.ico +0 -0
  214. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/Resources/Application.rc +323 -0
  215. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/Resources/Application.rc2 +20 -0
  216. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/Resources/Resource.h +53 -0
  217. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/Sources/AboutDialog.cpp +71 -0
  218. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/Sources/AboutDialog.h +62 -0
  219. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/Sources/Application.cpp +111 -0
  220. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/Sources/Application.h +68 -0
  221. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/Sources/ChooserDialog.cpp +1426 -0
  222. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/Sources/ChooserDialog.h +131 -0
  223. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/Sources/LoginDialog.cpp +109 -0
  224. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/Sources/LoginDialog.h +53 -0
  225. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/Sources/StdAfx.cpp +18 -0
  226. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/Sources/StdAfx.h +48 -0
  227. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/WindowsCE/Application.vcc +37 -0
  228. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/WindowsCE/Application.vcp +868 -0
  229. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/WindowsCE/Application.vcw +29 -0
  230. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/WindowsCE/Resources/Application.ico +0 -0
  231. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/WindowsCE/Resources/Application.rc +194 -0
  232. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/WindowsCE/Resources/Application.rc2 +13 -0
  233. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/WindowsCE/Resources/newres.h +28 -0
  234. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/WindowsCE/Resources/resource.h +22 -0
  235. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/WindowsCE/Sources/Application.cpp +92 -0
  236. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/WindowsCE/Sources/Application.h +57 -0
  237. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/WindowsCE/Sources/BrowserDialog.cpp +394 -0
  238. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/WindowsCE/Sources/BrowserDialog.h +84 -0
  239. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/WindowsCE/Sources/StdAfx.cpp +18 -0
  240. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/WindowsCE/Sources/StdAfx.h +46 -0
  241. package/android/src/main/jni/mdnsresponder/mDNSWindows/Java/Java.vcproj +111 -0
  242. package/android/src/main/jni/mdnsresponder/mDNSWindows/Java/jdns_sd.rc +62 -0
  243. package/android/src/main/jni/mdnsresponder/mDNSWindows/Java/makefile +143 -0
  244. package/android/src/main/jni/mdnsresponder/mDNSWindows/Java/makefile64 +143 -0
  245. package/android/src/main/jni/mdnsresponder/mDNSWindows/NSPTool/NSPTool.aps +0 -0
  246. package/android/src/main/jni/mdnsresponder/mDNSWindows/NSPTool/NSPTool.c +581 -0
  247. package/android/src/main/jni/mdnsresponder/mDNSWindows/NSPTool/NSPTool.rc +103 -0
  248. package/android/src/main/jni/mdnsresponder/mDNSWindows/NSPTool/NSPTool.vcproj +409 -0
  249. package/android/src/main/jni/mdnsresponder/mDNSWindows/NSPTool/Prefix.h +28 -0
  250. package/android/src/main/jni/mdnsresponder/mDNSWindows/NSPTool/resource.h +27 -0
  251. package/android/src/main/jni/mdnsresponder/mDNSWindows/PosixCompat.c +128 -0
  252. package/android/src/main/jni/mdnsresponder/mDNSWindows/PosixCompat.h +70 -0
  253. package/android/src/main/jni/mdnsresponder/mDNSWindows/README.txt +85 -0
  254. package/android/src/main/jni/mdnsresponder/mDNSWindows/RegNames.h +57 -0
  255. package/android/src/main/jni/mdnsresponder/mDNSWindows/Secret.c +338 -0
  256. package/android/src/main/jni/mdnsresponder/mDNSWindows/Secret.h +42 -0
  257. package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/EventLog.mc +11 -0
  258. package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/EventLogMessages.bin +0 -0
  259. package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/Firewall.cpp +484 -0
  260. package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/Firewall.h +79 -0
  261. package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/Prefix.h +30 -0
  262. package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/Service.aps +0 -0
  263. package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/Service.c +2669 -0
  264. package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/Service.h +30 -0
  265. package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/Service.mcp +0 -0
  266. package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/Service.rc +114 -0
  267. package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/Service.vcproj +562 -0
  268. package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/main.c +32 -0
  269. package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/res/mDNSResponder.manifest +12 -0
  270. package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/res/mDNSResponder64.manifest +12 -0
  271. package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/resource.h +17 -0
  272. package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/resrc1.h +15 -0
  273. package/android/src/main/jni/mdnsresponder/mDNSWindows/VPCDetect.cpp +165 -0
  274. package/android/src/main/jni/mdnsresponder/mDNSWindows/VPCDetect.h +36 -0
  275. package/android/src/main/jni/mdnsresponder/mDNSWindows/WinServices.cpp +93 -0
  276. package/android/src/main/jni/mdnsresponder/mDNSWindows/WinServices.h +34 -0
  277. package/android/src/main/jni/mdnsresponder/mDNSWindows/WinVersRes.h +35 -0
  278. package/android/src/main/jni/mdnsresponder/mDNSWindows/isocode.h +135 -0
  279. package/android/src/main/jni/mdnsresponder/mDNSWindows/loclibrary.c +268 -0
  280. package/android/src/main/jni/mdnsresponder/mDNSWindows/loclibrary.h +54 -0
  281. package/android/src/main/jni/mdnsresponder/mDNSWindows/mDNSWin32.c +5200 -0
  282. package/android/src/main/jni/mdnsresponder/mDNSWindows/mDNSWin32.h +208 -0
  283. package/android/src/main/jni/mdnsresponder/mDNSWindows/mdnsNSP/ReadMe.txt +15 -0
  284. package/android/src/main/jni/mdnsresponder/mDNSWindows/mdnsNSP/mdnsNSP.aps +0 -0
  285. package/android/src/main/jni/mdnsresponder/mDNSWindows/mdnsNSP/mdnsNSP.c +2430 -0
  286. package/android/src/main/jni/mdnsresponder/mDNSWindows/mdnsNSP/mdnsNSP.def +24 -0
  287. package/android/src/main/jni/mdnsresponder/mDNSWindows/mdnsNSP/mdnsNSP.rc +104 -0
  288. package/android/src/main/jni/mdnsresponder/mDNSWindows/mdnsNSP/mdnsNSP.vcproj +457 -0
  289. package/android/src/main/jni/mdnsresponder/mDNSWindows/mdnsNSP/resource.h +27 -0
  290. package/android/src/main/jni/mdnsresponder/mdnsd.rc +7 -0
  291. package/android/src/main/jni/nameser.h +588 -0
  292. package/dist/index.js +148 -1
  293. package/package.json +23 -17
  294. package/src/index.js +166 -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