1 /* 2 * Copyright (c) 2002-2024 Apple Inc. All rights reserved. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * https://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 16 NOTE: 17 If you're building an application that uses DNS Service Discovery 18 this is probably NOT the header file you're looking for. 19 In most cases you will want to use /usr/include/dns_sd.h instead. 20 21 This header file defines the lowest level raw interface to mDNSCore, 22 which is appropriate *only* on tiny embedded systems where everything 23 runs in a single address space and memory is extremely constrained. 24 All the APIs here are malloc-free, which means that the caller is 25 responsible for passing in a pointer to the relevant storage that 26 will be used in the execution of that call, and (when called with 27 correct parameters) all the calls are guaranteed to succeed. There 28 is never a case where a call can suffer intermittent failures because 29 the implementation calls malloc() and sometimes malloc() returns NULL 30 because memory is so limited that no more is available. 31 This is primarily for devices that need to have precisely known fixed 32 memory requirements, with absolutely no uncertainty or run-time variation, 33 but that certainty comes at a cost of more difficult programming. 34 35 For applications running on general-purpose desktop operating systems 36 (Mac OS, Linux, Solaris, Windows, etc.) the API you should use is 37 /usr/include/dns_sd.h, which defines the API by which multiple 38 independent client processes communicate their DNS Service Discovery 39 requests to a single "mdnsd" daemon running in the background. 40 41 Even on platforms that don't run multiple independent processes in 42 multiple independent address spaces, you can still use the preferred 43 dns_sd.h APIs by linking in "dnssd_clientshim.c", which implements 44 the standard "dns_sd.h" API calls, allocates any required storage 45 using malloc(), and then calls through to the low-level malloc-free 46 mDNSCore routines defined here. This has the benefit that even though 47 you're running on a small embedded system with a single address space, 48 you can still use the exact same client C code as you'd use on a 49 general-purpose desktop system. 50 51 */ 52 53 #ifndef __mDNSEmbeddedAPI_h 54 #define __mDNSEmbeddedAPI_h 55 56 #ifdef __MINGW32__ 57 // MinGW defines "#define interface struct" for ObjC compatibility. 58 #undef interface 59 #endif 60 61 #if defined(EFI32) || defined(EFI64) || defined(EFIX64) 62 // EFI doesn't have stdarg.h unless it's building with GCC. 63 #include "Tiano.h" 64 #if !defined(__GNUC__) 65 #define va_list VA_LIST 66 #define va_start(a, b) VA_START(a, b) 67 #define va_end(a) VA_END(a) 68 #define va_arg(a, b) VA_ARG(a, b) 69 #endif 70 #else 71 #include <stdarg.h> // stdarg.h is required for for va_list support for the mDNS_vsnprintf declaration 72 #endif 73 74 #include <inttypes.h> // for uintptr_t and PRIXPTR 75 76 77 #include "mDNSFeatures.h" 78 #include "mDNSDebug.h" 79 #include "general.h" 80 81 // *************************************************************************** 82 // Feature removal compile options & limited resource targets 83 84 // The following compile options are responsible for removing certain features from mDNSCore to reduce the 85 // memory footprint for use in embedded systems with limited resources. 86 87 // UNICAST_DISABLED - disables unicast DNS functionality, including Wide Area Bonjour 88 // SPC_DISABLED - disables Bonjour Sleep Proxy client 89 // IDLESLEEPCONTROL_DISABLED - disables sleep control for Bonjour Sleep Proxy clients 90 91 // In order to disable the above features pass the option to your compiler, e.g. -D UNICAST_DISABLED 92 93 #if MDNSRESPONDER_SUPPORTS(APPLE, WEB_CONTENT_FILTER) 94 #include <WebFilterDNS/WebFilterDNS.h> 95 #endif 96 97 #if MDNSRESPONDER_SUPPORTS(APPLE, DNSSECv2) 98 #include "dnssec_obj_dns_question_member.h" 99 #include "dnssec_obj_resource_record_member.h" 100 #include "dnssec_obj_denial_of_existence.h" 101 #include "dnssec_obj_trust_anchor_manager.h" 102 #endif 103 104 #if MDNSRESPONDER_SUPPORTS(APPLE, DNS_PUSH) 105 #include "dns_push_obj_dns_question_member.h" 106 #include "dns_push_obj_resource_record_member.h" 107 #endif 108 109 // Additionally, the LIMITED_RESOURCES_TARGET compile option will reduce the maximum DNS message sizes. 110 111 #ifdef LIMITED_RESOURCES_TARGET 112 // Don't support jumbo frames 113 // 40 (IPv6 header) + 8 (UDP header) + 12 (DNS message header) + 1440 (DNS message body) = 1500 total 114 #define AbsoluteMaxDNSMessageData 1440 115 // StandardAuthRDSize is 264 (256+8), which is large enough to hold a maximum-sized SRV record (6 + 256 bytes) 116 #define MaximumRDSize 264 117 #endif 118 119 #if MDNSRESPONDER_SUPPORTS(APPLE, QUERIER) 120 #include <mdns/cache_metadata.h> 121 #include <mdns/private.h> 122 #endif 123 124 #if MDNSRESPONDER_SUPPORTS(APPLE, AUDIT_TOKEN) 125 #include <mdns/audit_token.h> 126 #endif 127 128 #if MDNSRESPONDER_SUPPORTS(APPLE, LOG_PRIVACY_LEVEL) 129 #include "dnssd_private.h" // For dnssd_log_privacy_level_t. 130 #endif 131 132 #if MDNSRESPONDER_SUPPORTS(APPLE, RUNTIME_MDNS_METRICS) 133 #include <mdns/multicast_delay_histogram.h> 134 #endif 135 136 #if __has_feature(objc_fixed_enum) || __has_extension(cxx_fixed_enum) || __has_extension(cxx_strong_enums) 137 #define MDNSRESPONDER_CLOSED_ENUM(NAME, UNDERLYING_TYPE, ...) \ 138 typedef enum : UNDERLYING_TYPE {__VA_ARGS__} MDNSRESPONDER_ENUM_ATTR_CLOSED NAME 139 #else 140 #define MDNSRESPONDER_CLOSED_ENUM(NAME, UNDERLYING_TYPE, ...) \ 141 typedef UNDERLYING_TYPE NAME; enum NAME ## _Enum {__VA_ARGS__} MDNSRESPONDER_ENUM_ATTR_CLOSED 142 #endif 143 144 #ifdef __cplusplus 145 extern "C" { 146 #endif 147 148 // *************************************************************************** 149 // Function scope indicators 150 151 // If you see "mDNSlocal" before a function name in a C file, it means the function is not callable outside this file 152 #ifndef mDNSlocal 153 #define mDNSlocal static 154 #endif 155 // If you see "mDNSexport" before a symbol in a C file, it means the symbol is exported for use by clients 156 // For every "mDNSexport" in a C file, there needs to be a corresponding "extern" declaration in some header file 157 // (When a C file #includes a header file, the "extern" declarations tell the compiler: 158 // "This symbol exists -- but not necessarily in this C file.") 159 #ifndef mDNSexport 160 #define mDNSexport 161 #endif 162 163 // Explanation: These local/export markers are a little habit of mine for signaling the programmers' intentions. 164 // When "mDNSlocal" is just a synonym for "static", and "mDNSexport" is a complete no-op, you could be 165 // forgiven for asking what purpose they serve. The idea is that if you see "mDNSexport" in front of a 166 // function definition it means the programmer intended it to be exported and callable from other files 167 // in the project. If you see "mDNSlocal" in front of a function definition it means the programmer 168 // intended it to be private to that file. If you see neither in front of a function definition it 169 // means the programmer forgot (so you should work out which it is supposed to be, and fix it). 170 // Using "mDNSlocal" instead of "static" makes it easier to do a textual searches for one or the other. 171 // For example you can do a search for "static" to find if any functions declare any local variables as "static" 172 // (generally a bad idea unless it's also "const", because static storage usually risks being non-thread-safe) 173 // without the results being cluttered with hundreds of matches for functions declared static. 174 // - Stuart Cheshire 175 176 // *************************************************************************** 177 // Structure packing macro 178 179 // If we're not using GNUC, it's not fatal. 180 // Most compilers naturally pack the on-the-wire structures correctly anyway, so a plain "struct" is usually fine. 181 // In the event that structures are not packed correctly, mDNS_Init() will detect this and report an error, so the 182 // developer will know what's wrong, and can investigate what needs to be done on that compiler to provide proper packing. 183 #ifndef packedstruct 184 #if ((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 9))) 185 #define packedstruct struct __attribute__((__packed__)) 186 #define packedunion union __attribute__((__packed__)) 187 #else 188 #define packedstruct struct 189 #define packedunion union 190 #endif 191 #endif 192 193 #ifndef fallthrough 194 #if MDNS_COMPILER_IS_CLANG() 195 #if __has_attribute(fallthrough) 196 #define fallthrough() __attribute__((fallthrough)) 197 #else 198 #define fallthrough() 199 #endif 200 #elif __GNUC__ 201 #define fallthrough() __attribute__((fallthrough)) 202 #else 203 #define fallthrough() 204 #endif // __GNUC__ 205 #endif // fallthrough 206 207 // *************************************************************************** 208 #if 0 209 #pragma mark - DNS Resource Record class and type constants 210 #endif 211 212 typedef enum // From RFC 1035 213 { 214 kDNSClass_IN = 1, // Internet 215 kDNSClass_CS = 2, // CSNET 216 kDNSClass_CH = 3, // CHAOS 217 kDNSClass_HS = 4, // Hesiod 218 kDNSClass_NONE = 254, // Used in DNS UPDATE [RFC 2136] 219 220 kDNSClass_Mask = 0x7FFF, // Multicast DNS uses the bottom 15 bits to identify the record class... 221 kDNSClass_UniqueRRSet = 0x8000, // ... and the top bit indicates that all other cached records are now invalid 222 223 kDNSQClass_ANY = 255, // Not a DNS class, but a DNS query class, meaning "all classes" 224 kDNSQClass_UnicastResponse = 0x8000 // Top bit set in a question means "unicast response acceptable" 225 } DNS_ClassValues; 226 227 typedef enum // From RFC 1035 228 { 229 kDNSType_A = 1, // 1 Address 230 kDNSType_NS, // 2 Name Server 231 kDNSType_MD, // 3 Mail Destination 232 kDNSType_MF, // 4 Mail Forwarder 233 kDNSType_CNAME, // 5 Canonical Name 234 kDNSType_SOA, // 6 Start of Authority 235 kDNSType_MB, // 7 Mailbox 236 kDNSType_MG, // 8 Mail Group 237 kDNSType_MR, // 9 Mail Rename 238 kDNSType_NULL, // 10 NULL RR 239 kDNSType_WKS, // 11 Well-known-service 240 kDNSType_PTR, // 12 Domain name pointer 241 kDNSType_HINFO, // 13 Host information 242 kDNSType_MINFO, // 14 Mailbox information 243 kDNSType_MX, // 15 Mail Exchanger 244 kDNSType_TXT, // 16 Arbitrary text string 245 kDNSType_RP, // 17 Responsible person 246 kDNSType_AFSDB, // 18 AFS cell database 247 kDNSType_X25, // 19 X_25 calling address 248 kDNSType_ISDN, // 20 ISDN calling address 249 kDNSType_RT, // 21 Router 250 kDNSType_NSAP, // 22 NSAP address 251 kDNSType_NSAP_PTR, // 23 Reverse NSAP lookup (deprecated) 252 kDNSType_SIG, // 24 Security signature 253 kDNSType_KEY, // 25 Security key 254 kDNSType_PX, // 26 X.400 mail mapping 255 kDNSType_GPOS, // 27 Geographical position (withdrawn) 256 kDNSType_AAAA, // 28 IPv6 Address 257 kDNSType_LOC, // 29 Location Information 258 kDNSType_NXT, // 30 Next domain (security) 259 kDNSType_EID, // 31 Endpoint identifier 260 kDNSType_NIMLOC, // 32 Nimrod Locator 261 kDNSType_SRV, // 33 Service record 262 kDNSType_ATMA, // 34 ATM Address 263 kDNSType_NAPTR, // 35 Naming Authority PoinTeR 264 kDNSType_KX, // 36 Key Exchange 265 kDNSType_CERT, // 37 Certification record 266 kDNSType_A6, // 38 IPv6 Address (deprecated) 267 kDNSType_DNAME, // 39 Non-terminal DNAME (for IPv6) 268 kDNSType_SINK, // 40 Kitchen sink (experimental) 269 kDNSType_OPT, // 41 EDNS0 option (meta-RR) 270 kDNSType_APL, // 42 Address Prefix List 271 kDNSType_DS, // 43 Delegation Signer 272 kDNSType_SSHFP, // 44 SSH Key Fingerprint 273 kDNSType_IPSECKEY, // 45 IPSECKEY 274 kDNSType_RRSIG, // 46 RRSIG 275 kDNSType_NSEC, // 47 Denial of Existence 276 kDNSType_DNSKEY, // 48 DNSKEY 277 kDNSType_DHCID, // 49 DHCP Client Identifier 278 kDNSType_NSEC3, // 50 Hashed Authenticated Denial of Existence 279 kDNSType_NSEC3PARAM, // 51 Hashed Authenticated Denial of Existence 280 281 kDNSType_HIP = 55, // 55 Host Identity Protocol 282 283 kDNSType_SVCB = 64, // 64 Service Binding 284 kDNSType_HTTPS, // 65 HTTPS Service Binding 285 286 kDNSType_SPF = 99, // 99 Sender Policy Framework for E-Mail 287 kDNSType_UINFO, // 100 IANA-Reserved 288 kDNSType_UID, // 101 IANA-Reserved 289 kDNSType_GID, // 102 IANA-Reserved 290 kDNSType_UNSPEC, // 103 IANA-Reserved 291 292 kDNSType_TKEY = 249, // 249 Transaction key 293 kDNSType_TSIG, // 250 Transaction signature 294 kDNSType_IXFR, // 251 Incremental zone transfer 295 kDNSType_AXFR, // 252 Transfer zone of authority 296 kDNSType_MAILB, // 253 Transfer mailbox records 297 kDNSType_MAILA, // 254 Transfer mail agent records 298 kDNSQType_ANY, // Not a DNS type, but a DNS query type, meaning "all types" 299 kDNSType_TSR = 65323 // Time since received, private for now, will update when allocated by IANA 300 } DNS_TypeValues; 301 302 // *************************************************************************** 303 #if 0 304 #pragma mark - 305 #pragma mark - Simple types 306 #endif 307 308 // mDNS defines its own names for these common types to simplify portability across 309 // multiple platforms that may each have their own (different) names for these types. 310 typedef unsigned char mDNSBool; 311 typedef signed char mDNSs8; 312 typedef unsigned char mDNSu8; 313 typedef signed short mDNSs16; 314 typedef unsigned short mDNSu16; 315 316 // Source: http://www.unix.org/version2/whatsnew/lp64_wp.html 317 // http://software.intel.com/sites/products/documentation/hpc/mkl/lin/MKL_UG_structure/Support_for_ILP64_Programming.htm 318 // It can be safely assumed that int is 32bits on the platform 319 #if defined(_ILP64) || defined(__ILP64__) 320 typedef signed int32 mDNSs32; 321 typedef unsigned int32 mDNSu32; 322 #else 323 typedef signed int mDNSs32; 324 typedef unsigned int mDNSu32; 325 #endif 326 327 // To enforce useful type checking, we make mDNSInterfaceID be a pointer to a dummy struct 328 // This way, mDNSInterfaceIDs can be assigned, and compared with each other, but not with other types 329 // Declaring the type to be the typical generic "void *" would lack this type checking 330 typedef const struct mDNSInterfaceID_dummystruct { void *dummy; } *mDNSInterfaceID; 331 332 // Use when printing interface IDs; the interface ID is actually a pointer, but we're only using 333 // the pointer as a unique identifier, and in special cases it's actually a small number. So there's 334 // little point in printing all 64 bits--the upper 32 bits in particular will not add information. 335 #define IIDPrintable(x) ((uint32_t)(uintptr_t)(x)) 336 337 // These types are for opaque two- and four-byte identifiers. 338 // The "NotAnInteger" fields of the unions allow the value to be conveniently passed around in a 339 // register for the sake of efficiency, and compared for equality or inequality, but don't forget -- 340 // just because it is in a register doesn't mean it is an integer. Operations like greater than, 341 // less than, add, multiply, increment, decrement, etc., are undefined for opaque identifiers, 342 // and if you make the mistake of trying to do those using the NotAnInteger field, then you'll 343 // find you get code that doesn't work consistently on big-endian and little-endian machines. 344 #if defined(_WIN32) 345 #pragma pack(push,2) 346 #endif 347 typedef union { mDNSu8 b[ 2]; mDNSu16 NotAnInteger; } mDNSOpaque16; 348 typedef union { mDNSu8 b[ 4]; mDNSu32 NotAnInteger; } mDNSOpaque32; 349 typedef packedunion { mDNSu8 b[ 6]; mDNSu16 w[3]; mDNSu32 l[1]; } mDNSOpaque48; 350 typedef union { mDNSu8 b[ 8]; mDNSu16 w[4]; mDNSu32 l[2]; } mDNSOpaque64; 351 typedef union { mDNSu8 b[16]; mDNSu16 w[8]; mDNSu32 l[4]; } mDNSOpaque128; 352 #if defined(_WIN32) 353 #pragma pack(pop) 354 #endif 355 356 typedef mDNSOpaque16 mDNSIPPort; // An IP port is a two-byte opaque identifier (not an integer) 357 typedef mDNSOpaque32 mDNSv4Addr; // An IP address is a four-byte opaque identifier (not an integer) 358 typedef mDNSOpaque128 mDNSv6Addr; // An IPv6 address is a 16-byte opaque identifier (not an integer) 359 typedef mDNSOpaque48 mDNSEthAddr; // An Ethernet address is a six-byte opaque identifier (not an integer) 360 361 // Bit operations for opaque 64 bit quantity. Uses the 32 bit quantity(l[2]) to set and clear bits 362 #define mDNSNBBY 8 363 #define bit_set_opaque64(op64, index) (op64.l[((index))/(sizeof(mDNSu32) * mDNSNBBY)] |= (1 << ((index) % (sizeof(mDNSu32) * mDNSNBBY)))) 364 #define bit_clr_opaque64(op64, index) (op64.l[((index))/(sizeof(mDNSu32) * mDNSNBBY)] &= ~(1 << ((index) % (sizeof(mDNSu32) * mDNSNBBY)))) 365 #define bit_get_opaque64(op64, index) (op64.l[((index))/(sizeof(mDNSu32) * mDNSNBBY)] & (1 << ((index) % (sizeof(mDNSu32) * mDNSNBBY)))) 366 367 // Bit operations for opaque 128 bit quantity. Uses the 32 bit quantity(l[4]) to set and clear bits 368 #define bit_set_opaque128(op128, index) (op128.l[((index))/(sizeof(mDNSu32) * mDNSNBBY)] |= (1 << ((index) % (sizeof(mDNSu32) * mDNSNBBY)))) 369 #define bit_clr_opaque128(op128, index) (op128.l[((index))/(sizeof(mDNSu32) * mDNSNBBY)] &= ~(1 << ((index) % (sizeof(mDNSu32) * mDNSNBBY)))) 370 #define bit_get_opaque128(op128, index) (op128.l[((index))/(sizeof(mDNSu32) * mDNSNBBY)] & (1 << ((index) % (sizeof(mDNSu32) * mDNSNBBY)))) 371 372 typedef enum 373 { 374 mDNSAddrType_None = 0, 375 mDNSAddrType_IPv4 = 4, 376 mDNSAddrType_IPv6 = 6, 377 mDNSAddrType_Unknown = ~0 // Special marker value used in known answer list recording 378 } mDNSAddr_Type; 379 380 typedef enum 381 { 382 mDNSTransport_None = 0, 383 mDNSTransport_UDP = 1, 384 mDNSTransport_TCP = 2 385 } mDNSTransport_Type; 386 387 typedef struct 388 { 389 mDNSs32 type; 390 union { mDNSv6Addr v6; mDNSv4Addr v4; } ip; 391 } mDNSAddr; 392 393 enum { mDNSfalse = 0, mDNStrue = 1 }; 394 395 #define mDNSNULL 0L 396 397 enum 398 { 399 mStatus_Waiting = 1, 400 mStatus_NoError = 0, 401 402 // mDNS return values are in the range FFFE FF00 (-65792) to FFFE FFFF (-65537) 403 // The top end of the range (FFFE FFFF) is used for error codes; 404 // the bottom end of the range (FFFE FF00) is used for non-error values; 405 406 // Error codes: 407 mStatus_UnknownErr = -65537, // First value: 0xFFFE FFFF 408 mStatus_NoSuchNameErr = -65538, 409 mStatus_NoMemoryErr = -65539, 410 mStatus_BadParamErr = -65540, 411 mStatus_BadReferenceErr = -65541, 412 mStatus_BadStateErr = -65542, 413 mStatus_BadFlagsErr = -65543, 414 mStatus_UnsupportedErr = -65544, 415 mStatus_NotInitializedErr = -65545, 416 mStatus_NoCache = -65546, 417 mStatus_AlreadyRegistered = -65547, 418 mStatus_NameConflict = -65548, 419 mStatus_Invalid = -65549, 420 mStatus_Firewall = -65550, 421 mStatus_Incompatible = -65551, 422 mStatus_BadInterfaceErr = -65552, 423 mStatus_Refused = -65553, 424 mStatus_NoSuchRecord = -65554, 425 mStatus_NoAuth = -65555, 426 mStatus_NoSuchKey = -65556, 427 mStatus_NATTraversal = -65557, 428 mStatus_DoubleNAT = -65558, 429 mStatus_BadTime = -65559, 430 mStatus_BadSig = -65560, // while we define this per RFC 2845, BIND 9 returns Refused for bad/missing signatures 431 mStatus_BadKey = -65561, 432 mStatus_TransientErr = -65562, // transient failures, e.g. sending packets shortly after a network transition or wake from sleep 433 mStatus_ServiceNotRunning = -65563, // Background daemon not running 434 mStatus_NATPortMappingUnsupported = -65564, // NAT doesn't support PCP, NAT-PMP or UPnP 435 mStatus_NATPortMappingDisabled = -65565, // NAT supports PCP, NAT-PMP or UPnP, but it's disabled by the administrator 436 mStatus_NoRouter = -65566, 437 mStatus_PollingMode = -65567, 438 mStatus_Timeout = -65568, 439 mStatus_DefunctConnection = -65569, 440 mStatus_PolicyDenied = -65570, 441 mStatus_NotPermitted = -65571, // From kDNSSDAdvertisingProxyStatus_NotPermitted 442 mStatus_StaleData = -65572, 443 // -65573 to -65785 currently unused; available for allocation 444 445 // udp connection status 446 mStatus_HostUnreachErr = -65786, 447 448 // tcp connection status 449 mStatus_ConnPending = -65787, 450 mStatus_ConnFailed = -65788, 451 mStatus_ConnEstablished = -65789, 452 453 // Non-error values: 454 mStatus_GrowCache = -65790, 455 mStatus_ConfigChanged = -65791, 456 mStatus_MemFree = -65792 // Last value: 0xFFFE FF00 457 458 // mStatus_MemFree is the last legal mDNS error code, at the end of the range allocated for mDNS 459 }; 460 461 typedef mDNSs32 mStatus; 462 463 #define MaxIp 5 // Needs to be consistent with MaxInputIf in dns_services.h 464 465 typedef enum { q_stop = 0, q_start } q_state; 466 typedef enum { reg_stop = 0, reg_start } reg_state; 467 468 // RFC 1034/1035 specify that a domain label consists of a length byte plus up to 63 characters 469 #define MAX_DOMAIN_LABEL 63 470 typedef struct { mDNSu8 c[ 64]; } domainlabel; // One label: length byte and up to 63 characters 471 472 // RFC 1034/1035/2181 specify that a domain name (length bytes and data bytes) may be up to 255 bytes long, 473 // plus the terminating zero at the end makes 256 bytes total in the on-the-wire format. 474 #define MAX_DOMAIN_NAME 256 475 typedef struct { mDNSu8 c[256]; } domainname; // Up to 256 bytes of length-prefixed domainlabels 476 477 typedef struct { mDNSu8 c[256]; } UTF8str255; // Null-terminated C string 478 479 // The longest legal textual form of a DNS name is 1009 bytes, including the C-string terminating NULL at the end. 480 // Explanation: 481 // When a native domainname object is converted to printable textual form using ConvertDomainNameToCString(), 482 // non-printing characters are represented in the conventional DNS way, as '\ddd', where ddd is a three-digit decimal number. 483 // The longest legal domain name is 256 bytes, in the form of four labels as shown below: 484 // Length byte, 63 data bytes, length byte, 63 data bytes, length byte, 63 data bytes, length byte, 62 data bytes, zero byte. 485 // Each label is encoded textually as characters followed by a trailing dot. 486 // If every character has to be represented as a four-byte escape sequence, then this makes the maximum textual form four labels 487 // plus the C-string terminating NULL as shown below: 488 // 63*4+1 + 63*4+1 + 63*4+1 + 62*4+1 + 1 = 1009. 489 // Note that MAX_ESCAPED_DOMAIN_LABEL is not normally used: If you're only decoding a single label, escaping is usually not required. 490 // It is for domain names, where dots are used as label separators, that proper escaping is vital. 491 #define MAX_ESCAPED_DOMAIN_LABEL 254 492 #define MAX_ESCAPED_DOMAIN_NAME 1009 493 494 // MAX_REVERSE_MAPPING_NAME 495 // For IPv4: "123.123.123.123.in-addr.arpa." 30 bytes including terminating NUL 496 // For IPv6: "x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.ip6.arpa." 74 bytes including terminating NUL 497 498 #define MAX_REVERSE_MAPPING_NAME_V4 30 499 #define MAX_REVERSE_MAPPING_NAME_V6 74 500 #define MAX_REVERSE_MAPPING_NAME 74 501 502 // Most records have a TTL of 75 minutes, so that their 80% cache-renewal query occurs once per hour. 503 // For records containing a hostname (in the name on the left, or in the rdata on the right), 504 // like A, AAAA, reverse-mapping PTR, and SRV, we previously used a two-minute TTL by default, because we did't want 505 // them to hang around for too long in the cache if the host in question crashes or otherwise goes away... but to reduce 506 // the multicast traffic required to refresh these records, the same 75 minute TTL is now used for all record types. 507 508 #define kStandardTTL (3600UL * 100 / 80) 509 #define kHostNameTTL kStandardTTL // Was 120UL 510 511 // Multicast DNS uses announcements (gratuitous responses) to update peer caches. 512 // This means it is feasible to use relatively larger TTL values than we might otherwise 513 // use, because we have a cache coherency protocol to keep the peer caches up to date. 514 // With Unicast DNS, once an authoritative server gives a record with a certain TTL value to a client 515 // or caching server, that client or caching server is entitled to hold onto the record until its TTL 516 // expires, and has no obligation to contact the authoritative server again until that time arrives. 517 // This means that whereas Multicast DNS can use announcements to pre-emptively update stale data 518 // before it would otherwise have expired, standard Unicast DNS (not using LLQs) has no equivalent 519 // mechanism, and TTL expiry is the *only* mechanism by which stale data gets deleted. Because of this, 520 // we currently limit the TTL to ten seconds in such cases where no dynamic cache updating is possible. 521 #define kStaticCacheTTL 10 522 523 #define DefaultTTLforRRType(X) (((X) == kDNSType_A || (X) == kDNSType_AAAA || (X) == kDNSType_SRV) ? kHostNameTTL : kStandardTTL) 524 #define mDNS_KeepaliveRecord(rr) ((rr)->rrtype == kDNSType_NULL && SameDomainLabel(SecondLabel((rr)->name)->c, (mDNSu8 *)"\x0A_keepalive")) 525 526 // Number of times keepalives are sent if no ACK is received before waking up the system 527 // this is analogous to net.inet.tcp.keepcnt 528 #define kKeepaliveRetryCount 10 529 // The frequency at which keepalives are retried if no ACK is received 530 #define kKeepaliveRetryInterval 30 531 532 typedef struct AuthRecord_struct AuthRecord; 533 typedef struct ServiceRecordSet_struct ServiceRecordSet; 534 typedef struct CacheRecord_struct CacheRecord; 535 typedef struct CacheGroup_struct CacheGroup; 536 typedef struct AuthGroup_struct AuthGroup; 537 typedef struct DNSQuestion_struct DNSQuestion; 538 typedef struct ZoneData_struct ZoneData; 539 typedef struct mDNS_struct mDNS; 540 typedef struct mDNS_PlatformSupport_struct mDNS_PlatformSupport; 541 typedef struct NATTraversalInfo_struct NATTraversalInfo; 542 typedef struct ResourceRecord_struct ResourceRecord; 543 544 // Structure to abstract away the differences between TCP/SSL sockets, and one for UDP sockets 545 // The actual definition of these structures appear in the appropriate platform support code 546 typedef struct TCPListener_struct TCPListener; 547 typedef struct TCPSocket_struct TCPSocket; 548 typedef struct UDPSocket_struct UDPSocket; 549 typedef struct TLSContext_struct TLSContext; 550 typedef struct TLSServerContext_struct TLSServerContext; 551 552 // *************************************************************************** 553 #if 0 554 #pragma mark - 555 #pragma mark - DNS Message structures 556 #endif 557 558 #define mDNS_numZones numQuestions 559 #define mDNS_numPrereqs numAnswers 560 #define mDNS_numUpdates numAuthorities 561 562 typedef struct 563 { 564 mDNSOpaque16 id; 565 mDNSOpaque16 flags; 566 mDNSu16 numQuestions; 567 mDNSu16 numAnswers; 568 mDNSu16 numAuthorities; 569 mDNSu16 numAdditionals; 570 } DNSMessageHeader; 571 572 // We can send and receive packets up to 9000 bytes (Ethernet Jumbo Frame size, if that ever becomes widely used) 573 // However, in the normal case we try to limit packets to 1500 bytes so that we don't get IP fragmentation on standard Ethernet 574 // 40 (IPv6 header) + 8 (UDP header) + 12 (DNS message header) + 1440 (DNS message body) = 1500 total 575 #ifndef AbsoluteMaxDNSMessageData 576 #define AbsoluteMaxDNSMessageData 8940 577 #endif 578 #define NormalMaxDNSMessageData 1440 579 typedef struct 580 { 581 DNSMessageHeader h; // Note: Size 12 bytes 582 mDNSu8 data[AbsoluteMaxDNSMessageData]; // 40 (IPv6) + 8 (UDP) + 12 (DNS header) + 8940 (data) = 9000 583 } DNSMessage; 584 585 typedef struct tcpInfo_t 586 { 587 mDNS *m; 588 TCPSocket *sock; 589 DNSMessage request; 590 int requestLen; 591 DNSQuestion *question; // For queries 592 AuthRecord *rr; // For record updates 593 mDNSAddr Addr; 594 mDNSIPPort Port; 595 mDNSIPPort SrcPort; 596 DNSMessage *reply; 597 mDNSu16 replylen; 598 unsigned long nread; 599 int numReplies; 600 } tcpInfo_t; 601 602 // *************************************************************************** 603 #if 0 604 #pragma mark - 605 #pragma mark - Other Packet Format Structures 606 #endif 607 608 typedef packedstruct 609 { 610 mDNSEthAddr dst; 611 mDNSEthAddr src; 612 mDNSOpaque16 ethertype; 613 } EthernetHeader; // 14 bytes 614 615 // For clang, suppress -Wunaligned-access, which is triggered by the fact that the type of spa is mDNSv4Addr, which 616 // isn't a packed union, but it's a member of ARP_EthIP, which is packed. Having an unpacked union as a member of a 617 // packed struct is suspicious, but doesn't automatically produce undefined behavior, i.e., the compiler will 618 // produce the correct code to deal with the fact that spa may not be on a 4-byte boundary. If the address of any 619 // of the members of ARP_EthIP is used, then the -Waddress-of-packed-member warning will be triggered, which is a 620 // more useful warning. See <https://github.com/llvm/llvm-project/issues/55520#issuecomment-1128533595>. 621 typedef packedstruct 622 { 623 mDNSOpaque16 hrd; 624 mDNSOpaque16 pro; 625 mDNSu8 hln; 626 mDNSu8 pln; 627 mDNSOpaque16 op; 628 mDNSEthAddr sha; 629 MDNS_CLANG_IGNORE_UNALIGNED_ACCESS_WARNING_BEGIN() 630 mDNSv4Addr spa; 631 MDNS_CLANG_IGNORE_UNALIGNED_ACCESS_WARNING_END() 632 mDNSEthAddr tha; 633 mDNSv4Addr tpa; 634 } ARP_EthIP; // 28 bytes 635 636 typedef packedstruct 637 { 638 mDNSu8 vlen; 639 mDNSu8 tos; 640 mDNSOpaque16 totlen; 641 mDNSOpaque16 id; 642 mDNSOpaque16 flagsfrags; 643 mDNSu8 ttl; 644 mDNSu8 protocol; // Payload type: 0x06 = TCP, 0x11 = UDP 645 mDNSu16 checksum; 646 mDNSv4Addr src; 647 mDNSv4Addr dst; 648 } IPv4Header; // 20 bytes 649 650 typedef packedstruct 651 { 652 mDNSu32 vcf; // Version, Traffic Class, Flow Label 653 mDNSu16 len; // Payload Length 654 mDNSu8 pro; // Type of next header: 0x06 = TCP, 0x11 = UDP, 0x3A = ICMPv6 655 mDNSu8 ttl; // Hop Limit 656 mDNSv6Addr src; 657 mDNSv6Addr dst; 658 } IPv6Header; // 40 bytes 659 660 typedef packedstruct 661 { 662 mDNSv6Addr src; 663 mDNSv6Addr dst; 664 mDNSOpaque32 len; 665 mDNSOpaque32 pro; 666 } IPv6PseudoHeader; // 40 bytes 667 668 typedef union 669 { 670 mDNSu8 bytes[20]; 671 ARP_EthIP arp; 672 IPv4Header v4; 673 IPv6Header v6; 674 } NetworkLayerPacket; 675 676 typedef packedstruct 677 { 678 mDNSIPPort src; 679 mDNSIPPort dst; 680 mDNSu32 seq; 681 mDNSu32 ack; 682 mDNSu8 offset; 683 mDNSu8 flags; 684 mDNSu16 window; 685 mDNSu16 checksum; 686 mDNSu16 urgent; 687 } TCPHeader; // 20 bytes; IP protocol type 0x06 688 689 typedef struct 690 { 691 mDNSInterfaceID IntfId; 692 mDNSu32 seq; 693 mDNSu32 ack; 694 mDNSu16 window; 695 } mDNSTCPInfo; 696 697 typedef packedstruct 698 { 699 mDNSIPPort src; 700 mDNSIPPort dst; 701 mDNSu16 len; // Length including UDP header (i.e. minimum value is 8 bytes) 702 mDNSu16 checksum; 703 } UDPHeader; // 8 bytes; IP protocol type 0x11 704 705 typedef struct 706 { 707 mDNSu8 type; // 0x87 == Neighbor Solicitation, 0x88 == Neighbor Advertisement 708 mDNSu8 code; 709 mDNSu16 checksum; 710 mDNSu32 flags_res; // R/S/O flags and reserved bits 711 mDNSv6Addr target; 712 // Typically 8 bytes of options are also present 713 } IPv6NDP; // 24 bytes or more; IP protocol type 0x3A 714 715 typedef struct 716 { 717 mDNSAddr ipaddr; 718 char ethaddr[18]; 719 } IPAddressMACMapping; 720 721 #define NDP_Sol 0x87 722 #define NDP_Adv 0x88 723 724 #define NDP_Router 0x80 725 #define NDP_Solicited 0x40 726 #define NDP_Override 0x20 727 728 #define NDP_SrcLL 1 729 #define NDP_TgtLL 2 730 731 typedef union 732 { 733 mDNSu8 bytes[20]; 734 TCPHeader tcp; 735 UDPHeader udp; 736 IPv6NDP ndp; 737 } TransportLayerPacket; 738 739 typedef packedstruct 740 { 741 mDNSOpaque64 InitiatorCookie; 742 mDNSOpaque64 ResponderCookie; 743 mDNSu8 NextPayload; 744 mDNSu8 Version; 745 mDNSu8 ExchangeType; 746 mDNSu8 Flags; 747 mDNSOpaque32 MessageID; 748 mDNSu32 Length; 749 } IKEHeader; // 28 bytes 750 751 // *************************************************************************** 752 #if 0 753 #pragma mark - 754 #pragma mark - Resource Record structures 755 #endif 756 757 // Authoritative Resource Records: 758 // There are four basic types: Shared, Advisory, Unique, Known Unique 759 760 // * Shared Resource Records do not have to be unique 761 // -- Shared Resource Records are used for DNS-SD service PTRs 762 // -- It is okay for several hosts to have RRs with the same name but different RDATA 763 // -- We use a random delay on responses to reduce collisions when all the hosts respond to the same query 764 // -- These RRs typically have moderately high TTLs (e.g. one hour) 765 // -- These records are announced on startup and topology changes for the benefit of passive listeners 766 // -- These records send a goodbye packet when deregistering 767 // 768 // * Advisory Resource Records are like Shared Resource Records, except they don't send a goodbye packet 769 // 770 // * Unique Resource Records should be unique among hosts within any given mDNS scope 771 // -- The majority of Resource Records are of this type 772 // -- If two entities on the network have RRs with the same name but different RDATA, this is a conflict 773 // -- Responses may be sent immediately, because only one host should be responding to any particular query 774 // -- These RRs typically have low TTLs (e.g. a few minutes) 775 // -- On startup and after topology changes, a host issues queries to verify uniqueness 776 777 // * Known Unique Resource Records are treated like Unique Resource Records, except that mDNS does 778 // not have to verify their uniqueness because this is already known by other means (e.g. the RR name 779 // is derived from the host's IP or Ethernet address, which is already known to be a unique identifier). 780 781 // Summary of properties of different record types: 782 // Probe? Does this record type send probes before announcing? 783 // Conflict? Does this record type react if we observe an apparent conflict? 784 // Goodbye? Does this record type send a goodbye packet on departure? 785 // 786 // Probe? Conflict? Goodbye? Notes 787 // Unregistered Should not appear in any list (sanity check value) 788 // Shared No No Yes e.g. Service PTR record 789 // Deregistering No No Yes Shared record about to announce its departure and leave the list 790 // Advisory No No No 791 // Unique Yes Yes No Record intended to be unique -- will probe to verify 792 // Verified Yes Yes No Record has completed probing, and is verified unique 793 // KnownUnique No Yes No Record is assumed by other means to be unique 794 795 // Valid lifecycle of a record: 796 // Unregistered -> Shared -> Deregistering -(goodbye)-> Unregistered 797 // Unregistered -> Advisory -> Unregistered 798 // Unregistered -> Unique -(probe)-> Verified -> Unregistered 799 // Unregistered -> KnownUnique -> Unregistered 800 801 // Each Authoritative kDNSRecordType has only one bit set. This makes it easy to quickly see if a record 802 // is one of a particular set of types simply by performing the appropriate bitwise masking operation. 803 804 // Cache Resource Records (received from the network): 805 // There are four basic types: Answer, Unique Answer, Additional, Unique Additional 806 // Bit 7 (the top bit) of kDNSRecordType is always set for Cache Resource Records; always clear for Authoritative Resource Records 807 // Bit 6 (value 0x40) is set for answer records; clear for authority/additional records 808 // Bit 5 (value 0x20) is set for records received with the kDNSClass_UniqueRRSet 809 810 typedef enum 811 { 812 kDNSRecordTypeUnregistered = 0x00, // Not currently in any list 813 kDNSRecordTypeDeregistering = 0x01, // Shared record about to announce its departure and leave the list 814 815 kDNSRecordTypeUnique = 0x02, // Will become a kDNSRecordTypeVerified when probing is complete 816 817 kDNSRecordTypeAdvisory = 0x04, // Like Shared, but no goodbye packet 818 kDNSRecordTypeShared = 0x08, // Shared means record name does not have to be unique -- use random delay on responses 819 820 kDNSRecordTypeVerified = 0x10, // Unique means mDNS should check that name is unique (and then send immediate responses) 821 kDNSRecordTypeKnownUnique = 0x20, // Known Unique means mDNS can assume name is unique without checking 822 // For Dynamic Update records, Known Unique means the record must already exist on the server. 823 kDNSRecordTypeUniqueMask = (kDNSRecordTypeUnique | kDNSRecordTypeVerified | kDNSRecordTypeKnownUnique), 824 kDNSRecordTypeActiveSharedMask = (kDNSRecordTypeAdvisory | kDNSRecordTypeShared), 825 kDNSRecordTypeActiveUniqueMask = (kDNSRecordTypeVerified | kDNSRecordTypeKnownUnique), 826 kDNSRecordTypeActiveMask = (kDNSRecordTypeActiveSharedMask | kDNSRecordTypeActiveUniqueMask), 827 828 kDNSRecordTypePacketAdd = 0x80, // Received in the Additional Section of a DNS Response 829 kDNSRecordTypePacketAddUnique = 0x90, // Received in the Additional Section of a DNS Response with kDNSClass_UniqueRRSet set 830 kDNSRecordTypePacketAuth = 0xA0, // Received in the Authorities Section of a DNS Response 831 kDNSRecordTypePacketAuthUnique = 0xB0, // Received in the Authorities Section of a DNS Response with kDNSClass_UniqueRRSet set 832 kDNSRecordTypePacketAns = 0xC0, // Received in the Answer Section of a DNS Response 833 kDNSRecordTypePacketAnsUnique = 0xD0, // Received in the Answer Section of a DNS Response with kDNSClass_UniqueRRSet set 834 835 kDNSRecordTypePacketNegative = 0xF0, // Pseudo-RR generated to cache non-existence results like NXDomain 836 837 kDNSRecordTypePacketUniqueMask = 0x10 // True for PacketAddUnique, PacketAnsUnique, PacketAuthUnique, kDNSRecordTypePacketNegative 838 } kDNSRecordTypes; 839 840 typedef packedstruct { mDNSu16 priority; mDNSu16 weight; mDNSIPPort port; domainname target; } rdataSRV; 841 typedef packedstruct { mDNSu16 preference; domainname exchange; } rdataMX; 842 typedef struct { domainname mbox; domainname txt; } rdataRP; 843 typedef packedstruct { mDNSu16 preference; domainname map822; domainname mapx400; } rdataPX; 844 845 typedef packedstruct 846 { 847 domainname mname; 848 domainname rname; 849 mDNSs32 serial; // Modular counter; increases when zone changes 850 mDNSu32 refresh; // Time in seconds that a slave waits after successful replication of the database before it attempts replication again 851 mDNSu32 retry; // Time in seconds that a slave waits after an unsuccessful replication attempt before it attempts replication again 852 mDNSu32 expire; // Time in seconds that a slave holds on to old data while replication attempts remain unsuccessful 853 mDNSu32 min; // Nominally the minimum record TTL for this zone, in seconds; also used for negative caching. 854 } rdataSOA; 855 856 typedef enum 857 { 858 platform_OSX = 1, // OSX Platform 859 platform_iOS, // iOS Platform 860 platform_Atv, // Atv Platform 861 platform_NonApple // Non-Apple (Windows, POSIX) Platform 862 } Platform_t; 863 864 // EDNS Option Code registrations are recorded in the "DNS EDNS0 Options" section of 865 // <http://www.iana.org/assignments/dns-parameters> 866 867 #define kDNSOpt_LLQ 1 868 #define kDNSOpt_Lease 2 869 #define kDNSOpt_NSID 3 870 #define kDNSOpt_Owner 4 871 #define kDNSOpt_Trace 65001 // 65001-65534 Reserved for Local/Experimental Use 872 #define kDNSOpt_TSR 65002 873 874 typedef struct 875 { 876 mDNSu16 vers; 877 mDNSu16 llqOp; 878 mDNSu16 err; // Or UDP reply port, in setup request 879 // Note: In the in-memory form, there's typically a two-byte space here, so that the following 64-bit id is word-aligned 880 mDNSOpaque64 id; 881 mDNSu32 llqlease; 882 } LLQOptData; 883 884 typedef struct 885 { 886 mDNSu8 vers; // Version number of this Owner OPT record 887 mDNSs8 seq; // Sleep/wake epoch 888 mDNSEthAddr HMAC; // Host's primary identifier (e.g. MAC of on-board Ethernet) 889 mDNSEthAddr IMAC; // Interface's MAC address (if different to primary MAC) 890 mDNSOpaque48 password; // Optional password 891 } OwnerOptData; 892 893 typedef struct 894 { 895 mDNSu8 platf; // Running platform (see enum Platform_t) 896 mDNSu32 mDNSv; // mDNSResponder Version (DNS_SD_H defined in dns_sd.h) 897 } TracerOptData; 898 899 typedef struct 900 { 901 mDNSs32 timeStamp; // TSR record timestamp 902 mDNSu32 hostkeyHash; // 32-bit Hostkey Hash value 903 mDNSu16 recIndex; // Index into the DNS packet of the first answer (1-based) 904 } TSROptData; 905 906 // Note: rdataOPT format may be repeated an arbitrary number of times in a single resource record 907 typedef struct 908 { 909 mDNSu16 opt; 910 mDNSu16 optlen; 911 union { LLQOptData llq; mDNSu32 updatelease; OwnerOptData owner; TracerOptData tracer; TSROptData tsr; } u; 912 } rdataOPT; 913 914 // Space needed to put OPT records into a packet: 915 // Header 11 bytes (name 1, type 2, class 2, TTL 4, length 2) 916 // LLQ rdata 18 bytes (opt 2, len 2, vers 2, op 2, err 2, id 8, lease 4) 917 // Lease rdata 8 bytes (opt 2, len 2, lease 4) 918 // Owner rdata 12-24 bytes (opt 2, len 2, owner 8-20) 919 // Trace rdata 9 bytes (opt 2, len 2, platf 1, mDNSv 4) 920 // TSR rdata 14 bytes (opt 2, len 2, time 4, hash 4, index 2) 921 922 #define DNSOpt_Header_Space 11 923 #define DNSOpt_LLQData_Space (4 + 2 + 2 + 2 + 8 + 4) 924 #define DNSOpt_LeaseData_Space (4 + 4) 925 #define DNSOpt_OwnerData_ID_Space (4 + 2 + 6) 926 #define DNSOpt_OwnerData_ID_Wake_Space (4 + 2 + 6 + 6) 927 #define DNSOpt_OwnerData_ID_Wake_PW4_Space (4 + 2 + 6 + 6 + 4) 928 #define DNSOpt_OwnerData_ID_Wake_PW6_Space (4 + 2 + 6 + 6 + 6) 929 #define DNSOpt_TraceData_Space (4 + 1 + 4) 930 #define DNSOpt_TSRData_Space (4 + 4 + 4 + 2) 931 932 #define ValidOwnerLength(X) ( (X) == DNSOpt_OwnerData_ID_Space - 4 || \ 933 (X) == DNSOpt_OwnerData_ID_Wake_Space - 4 || \ 934 (X) == DNSOpt_OwnerData_ID_Wake_PW4_Space - 4 || \ 935 (X) == DNSOpt_OwnerData_ID_Wake_PW6_Space - 4 ) 936 937 #define DNSOpt_Owner_Space(A,B) (mDNSSameEthAddress((A),(B)) ? DNSOpt_OwnerData_ID_Space : DNSOpt_OwnerData_ID_Wake_Space) 938 939 #define DNSOpt_Data_Space(O) ( \ 940 (O)->opt == kDNSOpt_LLQ ? DNSOpt_LLQData_Space : \ 941 (O)->opt == kDNSOpt_Lease ? DNSOpt_LeaseData_Space : \ 942 (O)->opt == kDNSOpt_Trace ? DNSOpt_TraceData_Space : \ 943 (O)->opt == kDNSOpt_TSR ? DNSOpt_TSRData_Space : \ 944 (O)->opt == kDNSOpt_Owner ? DNSOpt_Owner_Space(&(O)->u.owner.HMAC, &(O)->u.owner.IMAC) : 0x10000) 945 946 // NSEC record is defined in RFC 4034. 947 // 16 bit RRTYPE space is split into 256 windows and each window has 256 bits (32 bytes). 948 // If we create a structure for NSEC, it's size would be: 949 // 950 // 256 bytes domainname 'nextname' 951 // + 256 * 34 = 8704 bytes of bitmap data 952 // = 8960 bytes total 953 // 954 // This would be a waste, as types about 256 are not very common. But it would be odd, if we receive 955 // a type above 256 (.US zone had TYPE65534 when this code was written) and not able to handle it. 956 // Hence, we handle any size by not fixing a strucure in place. The following is just a placeholder 957 // and never used anywhere. 958 // 959 #define NSEC_MCAST_WINDOW_SIZE 32 960 typedef struct 961 { 962 domainname *next; //placeholders are uncommented because C89 in Windows requires that a struct has at least a member. 963 char bitmap[32]; 964 } rdataNSEC; 965 966 // StandardAuthRDSize is 264 (256+8), which is large enough to hold a maximum-sized SRV record (6 + 256 bytes) 967 // MaximumRDSize is 8K the absolute maximum we support (at least for now) 968 #define StandardAuthRDSize 264 969 #ifndef MaximumRDSize 970 #define MaximumRDSize 8192 971 #endif 972 973 // InlineCacheRDSize is 68 974 // Records received from the network with rdata this size or less have their rdata stored right in the CacheRecord object 975 // Records received from the network with rdata larger than this have additional storage allocated for the rdata 976 // A quick unscientific sample from a busy network at Apple with lots of machines revealed this: 977 // 1461 records in cache 978 // 292 were one-byte TXT records 979 // 136 were four-byte A records 980 // 184 were sixteen-byte AAAA records 981 // 780 were various PTR, TXT and SRV records from 12-64 bytes 982 // Only 69 records had rdata bigger than 64 bytes 983 // Note that since CacheRecord object and a CacheGroup object are allocated out of the same pool, it's sensible to 984 // have them both be the same size. Making one smaller without making the other smaller won't actually save any memory. 985 #define InlineCacheRDSize 68 986 987 // The RDataBody union defines the common rdata types that fit into our 264-byte limit 988 typedef union 989 { 990 mDNSu8 data[StandardAuthRDSize]; 991 mDNSv4Addr ipv4; // For 'A' record 992 domainname name; // For PTR, NS, CNAME, DNAME 993 UTF8str255 txt; 994 rdataMX mx; 995 mDNSv6Addr ipv6; // For 'AAAA' record 996 rdataSRV srv; 997 mDNSs32 tsr_value; // For TSR record 998 rdataOPT opt[2]; // For EDNS0 OPT record; RDataBody may contain multiple variable-length rdataOPT objects packed together 999 } RDataBody; 1000 1001 // The RDataBody2 union is the same as above, except it includes fields for the larger types like soa, rp, px 1002 typedef union 1003 { 1004 mDNSu8 data[StandardAuthRDSize]; 1005 mDNSv4Addr ipv4; // For 'A' record 1006 domainname name; // For PTR, NS, CNAME, DNAME 1007 rdataSOA soa; // This is large; not included in the normal RDataBody definition 1008 UTF8str255 txt; 1009 rdataMX mx; 1010 rdataRP rp; // This is large; not included in the normal RDataBody definition 1011 rdataPX px; // This is large; not included in the normal RDataBody definition 1012 mDNSv6Addr ipv6; // For 'AAAA' record 1013 rdataSRV srv; 1014 mDNSs32 tsr_value; // For TSR record 1015 rdataOPT opt[2]; // For EDNS0 OPT record; RDataBody may contain multiple variable-length rdataOPT objects packed together 1016 } RDataBody2; 1017 1018 typedef struct 1019 { 1020 mDNSu16 MaxRDLength; // Amount of storage allocated for rdata (usually sizeof(RDataBody)) 1021 mDNSu16 padding; // So that RDataBody is aligned on 32-bit boundary 1022 RDataBody u; 1023 } RData; 1024 1025 // sizeofRDataHeader should be 4 bytes 1026 #define sizeofRDataHeader (sizeof(RData) - sizeof(RDataBody)) 1027 1028 // RData_small is a smaller version of the RData object, used for inline data storage embedded in a CacheRecord_struct 1029 typedef struct 1030 { 1031 mDNSu16 MaxRDLength; // Storage allocated for data (may be greater than InlineCacheRDSize if additional storage follows this object) 1032 mDNSu16 padding; // So that data is aligned on 32-bit boundary 1033 mDNSu8 data[InlineCacheRDSize]; 1034 } RData_small; 1035 1036 // Note: Within an mDNSRecordCallback mDNS all API calls are legal except mDNS_Init(), mDNS_Exit(), mDNS_Execute() 1037 typedef void mDNSRecordCallback (mDNS *const m, AuthRecord *const rr, mStatus result); 1038 1039 // Note: 1040 // Restrictions: An mDNSRecordUpdateCallback may not make any mDNS API calls. 1041 // The intent of this callback is to allow the client to free memory, if necessary. 1042 // The internal data structures of the mDNS code may not be in a state where mDNS API calls may be made safely. 1043 typedef void mDNSRecordUpdateCallback (mDNS *const m, AuthRecord *const rr, RData *OldRData, mDNSu16 OldRDLen); 1044 1045 // *************************************************************************** 1046 #if 0 1047 #pragma mark - 1048 #pragma mark - NAT Traversal structures and constants 1049 #endif 1050 1051 #define NATMAP_MAX_RETRY_INTERVAL ((mDNSPlatformOneSecond * 60) * 15) // Max retry interval is 15 minutes 1052 #define NATMAP_MIN_RETRY_INTERVAL (mDNSPlatformOneSecond * 2) // Min retry interval is 2 seconds 1053 #define NATMAP_INIT_RETRY (mDNSPlatformOneSecond / 4) // start at 250ms w/ exponential decay 1054 #define NATMAP_DEFAULT_LEASE (60 * 60 * 2) // 2 hour lease life in seconds 1055 #define NATMAP_VERS 0 1056 1057 typedef enum 1058 { 1059 NATOp_AddrRequest = 0, 1060 NATOp_MapUDP = 1, 1061 NATOp_MapTCP = 2, 1062 1063 NATOp_AddrResponse = 0x80 | 0, 1064 NATOp_MapUDPResponse = 0x80 | 1, 1065 NATOp_MapTCPResponse = 0x80 | 2, 1066 } NATOp_t; 1067 1068 enum 1069 { 1070 NATErr_None = 0, 1071 NATErr_Vers = 1, 1072 NATErr_Refused = 2, 1073 NATErr_NetFail = 3, 1074 NATErr_Res = 4, 1075 NATErr_Opcode = 5 1076 }; 1077 1078 typedef mDNSu16 NATErr_t; 1079 1080 typedef struct // packedstruct unnecessary 1081 { 1082 mDNSu8 vers; 1083 mDNSu8 opcode; 1084 } NATAddrRequest; 1085 1086 typedef packedstruct 1087 { 1088 mDNSu8 vers; 1089 mDNSu8 opcode; 1090 mDNSu16 err; 1091 mDNSu32 upseconds; // Time since last NAT engine reboot, in seconds 1092 mDNSv4Addr ExtAddr; 1093 } NATAddrReply; 1094 1095 typedef packedstruct 1096 { 1097 mDNSu8 vers; 1098 mDNSu8 opcode; 1099 mDNSOpaque16 unused; 1100 mDNSIPPort intport; 1101 mDNSIPPort extport; 1102 mDNSu32 NATReq_lease; 1103 } NATPortMapRequest; 1104 1105 typedef packedstruct 1106 { 1107 mDNSu8 vers; 1108 mDNSu8 opcode; 1109 mDNSu16 err; 1110 mDNSu32 upseconds; // Time since last NAT engine reboot, in seconds 1111 mDNSIPPort intport; 1112 mDNSIPPort extport; 1113 mDNSu32 NATRep_lease; 1114 } NATPortMapReply; 1115 1116 // PCP Support for IPv4 mappings 1117 1118 #define PCP_VERS 0x02 1119 #define PCP_WAITSECS_AFTER_EPOCH_INVALID 5 1120 1121 typedef enum 1122 { 1123 PCPOp_Announce = 0, 1124 PCPOp_Map = 1 1125 } PCPOp_t; 1126 1127 typedef enum 1128 { 1129 PCPProto_All = 0, 1130 PCPProto_TCP = 6, 1131 PCPProto_UDP = 17 1132 } PCPProto_t; 1133 1134 typedef enum 1135 { 1136 PCPResult_Success = 0, 1137 PCPResult_UnsuppVersion = 1, 1138 PCPResult_NotAuthorized = 2, 1139 PCPResult_MalformedReq = 3, 1140 PCPResult_UnsuppOpcode = 4, 1141 PCPResult_UnsuppOption = 5, 1142 PCPResult_MalformedOption = 6, 1143 PCPResult_NetworkFailure = 7, 1144 PCPResult_NoResources = 8, 1145 PCPResult_UnsuppProtocol = 9, 1146 PCPResult_UserExQuota = 10, 1147 PCPResult_CantProvideExt = 11, 1148 PCPResult_AddrMismatch = 12, 1149 PCPResult_ExcesRemotePeer = 13 1150 } PCPResult_t; 1151 1152 typedef struct 1153 { 1154 mDNSu8 version; 1155 mDNSu8 opCode; 1156 mDNSOpaque16 reserved; 1157 mDNSu32 lifetime; 1158 mDNSv6Addr clientAddr; 1159 mDNSu32 nonce[3]; 1160 mDNSu8 protocol; 1161 mDNSu8 reservedMapOp[3]; 1162 mDNSIPPort intPort; 1163 mDNSIPPort extPort; 1164 mDNSv6Addr extAddress; 1165 } PCPMapRequest; 1166 1167 typedef struct 1168 { 1169 mDNSu8 version; 1170 mDNSu8 opCode; 1171 mDNSu8 reserved; 1172 mDNSu8 result; 1173 mDNSu32 lifetime; 1174 mDNSu32 epoch; 1175 mDNSu32 clientAddrParts[3]; 1176 mDNSu32 nonce[3]; 1177 mDNSu8 protocol; 1178 mDNSu8 reservedMapOp[3]; 1179 mDNSIPPort intPort; 1180 mDNSIPPort extPort; 1181 mDNSv6Addr extAddress; 1182 } PCPMapReply; 1183 1184 // LNT Support 1185 1186 typedef enum 1187 { 1188 LNTDiscoveryOp = 1, 1189 LNTExternalAddrOp = 2, 1190 LNTPortMapOp = 3, 1191 LNTPortMapDeleteOp = 4 1192 } LNTOp_t; 1193 1194 #define LNT_MAXBUFSIZE 8192 1195 typedef struct tcpLNTInfo_struct tcpLNTInfo; 1196 struct tcpLNTInfo_struct 1197 { 1198 tcpLNTInfo *next; 1199 mDNS *m; 1200 NATTraversalInfo *parentNATInfo; // pointer back to the parent NATTraversalInfo 1201 TCPSocket *sock; 1202 LNTOp_t op; // operation performed using this connection 1203 mDNSAddr Address; // router address 1204 mDNSIPPort Port; // router port 1205 mDNSu8 *Request; // xml request to router 1206 int requestLen; 1207 mDNSu8 *Reply; // xml reply from router 1208 int replyLen; 1209 unsigned long nread; // number of bytes read so far 1210 int retries; // number of times we've tried to do this port mapping 1211 }; 1212 1213 typedef void (*NATTraversalClientCallback)(mDNS *m, NATTraversalInfo *n); 1214 1215 // if m->timenow < ExpiryTime then we have an active mapping, and we'll renew halfway to expiry 1216 // if m->timenow >= ExpiryTime then our mapping has expired, and we're trying to create one 1217 1218 typedef enum 1219 { 1220 NATTProtocolNone = 0, 1221 NATTProtocolNATPMP = 1, 1222 NATTProtocolUPNPIGD = 2, 1223 NATTProtocolPCP = 3, 1224 } NATTProtocol; 1225 1226 struct NATTraversalInfo_struct 1227 { 1228 // Internal state fields. These are used internally by mDNSCore; the client layer needn't be concerned with them. 1229 NATTraversalInfo *next; 1230 1231 mDNSs32 ExpiryTime; // Time this mapping expires, or zero if no mapping 1232 mDNSs32 retryInterval; // Current interval, between last packet we sent and the next one 1233 mDNSs32 retryPortMap; // If Protocol is nonzero, time to send our next mapping packet 1234 mStatus NewResult; // New error code; will be copied to Result just prior to invoking callback 1235 NATTProtocol lastSuccessfulProtocol; // To send correct deletion request & update non-PCP external address operations 1236 mDNSBool sentNATPMP; // Whether we just sent a NAT-PMP packet, so we won't send another if 1237 // we receive another NAT-PMP "Unsupported Version" packet 1238 1239 #ifdef _LEGACY_NAT_TRAVERSAL_ 1240 tcpLNTInfo tcpInfo; // Legacy NAT traversal (UPnP) TCP connection 1241 #endif 1242 1243 // Result fields: When the callback is invoked these fields contain the answers the client is looking for 1244 // When the callback is invoked ExternalPort is *usually* set to be the same the same as RequestedPort, except: 1245 // (a) When we're behind a NAT gateway with port mapping disabled, ExternalPort is reported as zero to 1246 // indicate that we don't currently have a working mapping (but RequestedPort retains the external port 1247 // we'd like to get, the next time we meet an accomodating NAT gateway willing to give us one). 1248 // (b) When we have a routable non-RFC1918 address, we don't *need* a port mapping, so ExternalPort 1249 // is reported as the same as our InternalPort, since that is effectively our externally-visible port too. 1250 // Again, RequestedPort retains the external port we'd like to get the next time we find ourself behind a NAT gateway. 1251 // To improve stability of port mappings, RequestedPort is updated any time we get a successful 1252 // mapping response from the PCP, NAT-PMP or UPnP gateway. For example, if we ask for port 80, and 1253 // get assigned port 81, then thereafter we'll contine asking for port 81. 1254 mDNSInterfaceID InterfaceID; 1255 mDNSv4Addr ExternalAddress; // Initially set to onesIPv4Addr, until first callback 1256 mDNSv4Addr NewAddress; // May be updated with actual value assigned by gateway 1257 mDNSIPPort ExternalPort; 1258 mDNSu32 Lifetime; 1259 mStatus Result; 1260 1261 // Client API fields: The client must set up these fields *before* making any NAT traversal API calls 1262 mDNSu8 Protocol; // NATOp_MapUDP or NATOp_MapTCP, or zero if just requesting the external IP address 1263 mDNSIPPort IntPort; // Client's internal port number (doesn't change) 1264 mDNSIPPort RequestedPort; // Requested external port; may be updated with actual value assigned by gateway 1265 mDNSu32 NATLease; // Requested lifetime in seconds (doesn't change) 1266 NATTraversalClientCallback clientCallback; 1267 void *clientContext; 1268 }; 1269 1270 // *************************************************************************** 1271 #if 0 1272 #pragma mark - 1273 #pragma mark - DNSServer & McastResolver structures and constants 1274 #endif 1275 1276 enum 1277 { 1278 McastResolver_FlagDelete = 1, 1279 McastResolver_FlagNew = 2 1280 }; 1281 1282 typedef struct McastResolver 1283 { 1284 struct McastResolver *next; 1285 mDNSInterfaceID interface; 1286 mDNSu32 flags; // Set when we're planning to delete this from the list 1287 domainname domain; 1288 mDNSu32 timeout; // timeout value for questions 1289 } McastResolver; 1290 1291 enum { 1292 Mortality_Mortal = 0, // This cache record can expire and get purged 1293 Mortality_Immortal = 1, // Allow this record to remain in the cache indefinitely 1294 Mortality_Ghost = 2 // An immortal record that has expired and can linger in the cache 1295 }; 1296 typedef mDNSu8 MortalityState; 1297 1298 // ScopeType values for DNSServer matching 1299 typedef enum 1300 { 1301 kScopeNone = 0, // DNS server used by unscoped questions 1302 kScopeInterfaceID = 1, // Scoped DNS server used only by scoped questions 1303 kScopeServiceID = 2 // Service specific DNS server used only by questions 1304 // have a matching serviceID 1305 } ScopeType; 1306 1307 #if !MDNSRESPONDER_SUPPORTS(APPLE, QUERIER) 1308 typedef mDNSu32 DNSServerFlags; 1309 #define DNSServerFlag_Delete (1U << 0) 1310 #if MDNSRESPONDER_SUPPORTS(APPLE, SYMPTOMS) 1311 #define DNSServerFlag_Unreachable (1U << 1) 1312 #endif 1313 1314 typedef struct DNSServer 1315 { 1316 struct DNSServer *next; 1317 mDNSInterfaceID interface; // DNS requests should be sent on this interface 1318 mDNSs32 serviceID; // ServiceID from DNS configuration. 1319 mDNSAddr addr; // DNS server's IP address. 1320 DNSServerFlags flags; // Set when we're planning to delete this from the list. 1321 mDNSs32 penaltyTime; // amount of time this server is penalized 1322 ScopeType scopeType; // See the ScopeType enum above 1323 mDNSu32 timeout; // timeout value for questions 1324 mDNSu32 resGroupID; // ID of the resolver group that contains this DNSServer 1325 mDNSIPPort port; // DNS server's port number. 1326 mDNSBool usableA; // True if A query results are usable over the interface, i.e., interface has IPv4. 1327 mDNSBool usableAAAA; // True if AAAA query results are usable over the interface, i.e., interface has IPv6. 1328 mDNSBool isCell; // True if the interface to this server is cellular. 1329 mDNSBool isExpensive; // True if the interface to this server is expensive. 1330 mDNSBool isConstrained; // True if the interface to this server is constrained. 1331 mDNSBool isCLAT46; // True if the interface to this server supports CLAT46. 1332 domainname domain; // name->server matching for "split dns" 1333 } DNSServer; 1334 #endif 1335 1336 struct ResourceRecord_struct 1337 { 1338 mDNSu8 RecordType; // See kDNSRecordTypes enum. 1339 mDNSu8 rcode; // If the record was received via DNS, specifies the RCODE of the response message. 1340 MortalityState mortality; // Mortality of this resource record (See MortalityState enum) 1341 mDNSu16 rrtype; // See DNS_TypeValues enum. 1342 mDNSu16 rrclass; // See DNS_ClassValues enum. 1343 mDNSu32 rroriginalttl; // In seconds 1344 mDNSu16 rdlength; // Size of the raw rdata, in bytes, in the on-the-wire format 1345 // (In-memory storage may be larger, for structures containing 'holes', like SOA) 1346 mDNSu16 rdestimate; // Upper bound on on-the-wire size of rdata after name compression 1347 mDNSu32 namehash; // Name-based (i.e. case-insensitive) hash of name 1348 mDNSu32 rdatahash; // For rdata containing domain name (e.g. PTR, SRV, CNAME etc.), case-insensitive name hash 1349 // else, for all other rdata, 32-bit hash of the raw rdata 1350 // Note: This requirement is important. Various routines like AddAdditionalsToResponseList(), 1351 // ReconfirmAntecedents(), etc., use rdatahash as a pre-flight check to see 1352 // whether it's worth doing a full SameDomainName() call. If the rdatahash 1353 // is not a correct case-insensitive name hash, they'll get false negatives. 1354 // Grouping pointers together at the end of the structure improves the memory layout efficiency 1355 mDNSInterfaceID InterfaceID; // Set if this RR is specific to one interface 1356 // For records received off the wire, InterfaceID is *always* set to the receiving interface 1357 // For our authoritative records, InterfaceID is usually zero, except for those few records 1358 // that are interface-specific (e.g. address records, especially linklocal addresses) 1359 const domainname *name; 1360 RData *rdata; // Pointer to storage for this rdata 1361 #if MDNSRESPONDER_SUPPORTS(APPLE, QUERIER) 1362 mdns_cache_metadata_t metadata; 1363 #else 1364 DNSServer *rDNSServer; // Unicast DNS server authoritative for this entry; null for multicast 1365 #endif 1366 1367 #if MDNSRESPONDER_SUPPORTS(APPLE, DNSSECv2) 1368 dnssec_obj_resource_record_member_t dnssec; // DNSSEC-related information for the current RR. 1369 #endif 1370 }; 1371 1372 1373 // Unless otherwise noted, states may apply to either independent record registrations or service registrations 1374 typedef enum 1375 { 1376 regState_Zero = 0, 1377 regState_Pending = 1, // update sent, reply not received 1378 regState_Registered = 2, // update sent, reply received 1379 regState_DeregPending = 3, // dereg sent, reply not received 1380 regState_Unregistered = 4, // not in any list 1381 regState_Refresh = 5, // outstanding refresh (or target change) message 1382 regState_NATMap = 6, // establishing NAT port mapping 1383 regState_UpdatePending = 7, // update in flight as result of mDNS_Update call 1384 regState_NoTarget = 8, // SRV Record registration pending registration of hostname 1385 regState_NATError = 9 // unable to complete NAT traversal 1386 } regState_t; 1387 1388 enum 1389 { 1390 Target_Manual = 0, 1391 Target_AutoHost = 1, 1392 Target_AutoHostAndNATMAP = 2 1393 }; 1394 1395 typedef enum 1396 { 1397 mergeState_Zero = 0, 1398 mergeState_DontMerge = 1 // Set on fatal error conditions to disable merging 1399 } mergeState_t; 1400 1401 #define AUTH_GROUP_NAME_SIZE 128 1402 struct AuthGroup_struct // Header object for a list of AuthRecords with the same name 1403 { 1404 AuthGroup *next; // Next AuthGroup object in this hash table bucket 1405 mDNSu32 namehash; // Name-based (i.e. case insensitive) hash of name 1406 AuthRecord *members; // List of CacheRecords with this same name 1407 AuthRecord **rrauth_tail; // Tail end of that list 1408 domainname *name; // Common name for all AuthRecords in this list 1409 AuthRecord *NewLocalOnlyRecords; 1410 mDNSu8 namestorage[AUTH_GROUP_NAME_SIZE]; 1411 }; 1412 1413 #ifndef AUTH_HASH_SLOTS 1414 #define AUTH_HASH_SLOTS 499 1415 #endif 1416 #define FORALL_AUTHRECORDS(SLOT,AG,AR) \ 1417 for ((SLOT) = 0; (SLOT) < AUTH_HASH_SLOTS; (SLOT)++) \ 1418 for ((AG)=m->rrauth.rrauth_hash[(SLOT)]; (AG); (AG)=(AG)->next) \ 1419 for ((AR) = (AG)->members; (AR); (AR)=(AR)->next) 1420 1421 typedef union AuthEntity_union AuthEntity; 1422 union AuthEntity_union { AuthEntity *next; AuthGroup ag; }; 1423 typedef struct { 1424 mDNSu32 rrauth_size; // Total number of available auth entries 1425 mDNSu32 rrauth_totalused; // Number of auth entries currently occupied 1426 mDNSu32 rrauth_report; 1427 mDNSu8 rrauth_lock; // For debugging: Set at times when these lists may not be modified 1428 AuthEntity *rrauth_free; 1429 AuthGroup *rrauth_hash[AUTH_HASH_SLOTS]; 1430 }AuthHash; 1431 1432 // AuthRecordAny includes mDNSInterface_Any and interface specific auth records. 1433 typedef enum 1434 { 1435 AuthRecordAny, // registered for *Any, NOT including P2P interfaces 1436 AuthRecordAnyIncludeP2P, // registered for *Any, including P2P interfaces 1437 AuthRecordAnyIncludeAWDL, // registered for *Any, including AWDL interface 1438 AuthRecordAnyIncludeAWDLandP2P, // registered for *Any, including AWDL and P2P interfaces 1439 AuthRecordLocalOnly, 1440 AuthRecordP2P, // discovered over D2D/P2P framework 1441 } AuthRecType; 1442 1443 #define AuthRecordIncludesAWDL(AR) \ 1444 (((AR)->ARType == AuthRecordAnyIncludeAWDL) || ((AR)->ARType == AuthRecordAnyIncludeAWDLandP2P)) 1445 1446 typedef enum 1447 { 1448 AuthFlagsWakeOnly = 0x1 // WakeOnly service 1449 } AuthRecordFlags; 1450 1451 struct AuthRecord_struct 1452 { 1453 // For examples of how to set up this structure for use in mDNS_Register(), 1454 // see mDNS_AdvertiseInterface() or mDNS_RegisterService(). 1455 // Basically, resrec and persistent metadata need to be set up before calling mDNS_Register(). 1456 // mDNS_SetupResourceRecord() is avaliable as a helper routine to set up most fields to sensible default values for you 1457 1458 AuthRecord *next; // Next in list; first element of structure for efficiency reasons 1459 // Field Group 1: Common ResourceRecord fields 1460 ResourceRecord resrec; // 36 bytes when compiling for 32-bit; 48 when compiling for 64-bit (now 44/64) 1461 1462 // Field Group 2: Persistent metadata for Authoritative Records 1463 AuthRecord *Additional1; // Recommended additional record to include in response (e.g. SRV for PTR record) 1464 AuthRecord *Additional2; // Another additional (e.g. TXT for PTR record) 1465 AuthRecord *DependentOn; // This record depends on another for its uniqueness checking 1466 uintptr_t RRSet; // This unique record is part of an RRSet 1467 mDNSRecordCallback *RecordCallback; // Callback function to call for state changes, and to free memory asynchronously on deregistration 1468 void *RecordContext; // Context parameter for the callback function 1469 mDNSu8 AutoTarget; // Set if the target of this record (PTR, CNAME, SRV, etc.) is our host name 1470 mDNSu8 AllowRemoteQuery; // Set if we allow hosts not on the local link to query this record 1471 mDNSu8 ForceMCast; // Set by client to advertise solely via multicast, even for apparently unicast names 1472 mDNSu8 AuthFlags; 1473 1474 OwnerOptData WakeUp; // WakeUp.HMAC.l[0] nonzero indicates that this is a Sleep Proxy record 1475 mDNSAddr AddressProxy; // For reverse-mapping Sleep Proxy PTR records, address in question 1476 mDNSs32 TimeRcvd; // In platform time units 1477 mDNSs32 TimeExpire; // In platform time units 1478 AuthRecType ARType; // LocalOnly, P2P or Normal ? 1479 mDNSs32 KATimeExpire; // In platform time units: time to send keepalive packet for the proxy record 1480 1481 // Field Group 3: Transient state for Authoritative Records 1482 mDNSs32 ProbingConflictCount; // Number of conflicting records observed during probing. 1483 mDNSs32 LastConflictPktNum; // Number of the last received packet that caused a probing conflict. 1484 mDNSu8 Acknowledged; // Set if we've given the success callback to the client 1485 mDNSu8 ProbeRestartCount; // Number of times we have restarted probing 1486 mDNSu8 ProbeCount; // Number of probes remaining before this record is valid (kDNSRecordTypeUnique) 1487 mDNSu8 AnnounceCount; // Number of announcements remaining (kDNSRecordTypeShared) 1488 mDNSu8 RequireGoodbye; // Set if this RR has been announced on the wire and will require a goodbye packet 1489 mDNSu8 AnsweredLocalQ; // Set if this AuthRecord has been delivered to any local question (LocalOnly or mDNSInterface_Any) 1490 mDNSu8 IncludeInProbe; // Set if this RR is being put into a probe right now 1491 mDNSu8 ImmedUnicast; // Set if we may send our response directly via unicast to the requester 1492 mDNSInterfaceID SendNSECNow; // Set if we need to generate associated NSEC data for this rrname 1493 mDNSInterfaceID ImmedAnswer; // Someone on this interface issued a query we need to answer (all-ones for all interfaces) 1494 #if defined(MDNS_LOG_ANSWER_SUPPRESSION_TIMES) && MDNS_LOG_ANSWER_SUPPRESSION_TIMES 1495 mDNSs32 ImmedAnswerMarkTime; 1496 #endif 1497 mDNSInterfaceID ImmedAdditional; // Hint that we might want to also send this record, just to be helpful 1498 mDNSInterfaceID SendRNow; // The interface this query is being sent on right now 1499 mDNSv4Addr v4Requester; // Recent v4 query for this record, or all-ones if more than one recent query 1500 mDNSv6Addr v6Requester; // Recent v6 query for this record, or all-ones if more than one recent query 1501 AuthRecord *NextResponse; // Link to the next element in the chain of responses to generate 1502 const mDNSu8 *NR_AnswerTo; // Set if this record was selected by virtue of being a direct answer to a question 1503 AuthRecord *NR_AdditionalTo; // Set if this record was selected by virtue of being additional to another 1504 mDNSs32 ThisAPInterval; // In platform time units: Current interval for announce/probe 1505 mDNSs32 LastAPTime; // In platform time units: Last time we sent announcement/probe 1506 mDNSs32 LastMCTime; // Last time we multicast this record (used to guard against packet-storm attacks) 1507 mDNSInterfaceID LastMCInterface; // Interface this record was multicast on at the time LastMCTime was recorded 1508 RData *NewRData; // Set if we are updating this record with new rdata 1509 mDNSu16 newrdlength; // ... and the length of the new RData 1510 mDNSRecordUpdateCallback *UpdateCallback; 1511 mDNSu32 UpdateCredits; // Token-bucket rate limiting of excessive updates 1512 mDNSs32 NextUpdateCredit; // Time next token is added to bucket 1513 mDNSs32 UpdateBlocked; // Set if update delaying is in effect 1514 mDNSs32 TentativeSetTime; // In platform time units 1515 1516 // Field Group 4: Transient uDNS state for Authoritative Records 1517 regState_t state; // Maybe combine this with resrec.RecordType state? Right now it's ambiguous and confusing. 1518 // e.g. rr->resrec.RecordType can be kDNSRecordTypeUnregistered, 1519 // and rr->state can be regState_Unregistered 1520 // What if we find one of those statements is true and the other false? What does that mean? 1521 mDNSBool uselease; // dynamic update contains (should contain) lease option 1522 mDNSs32 expire; // In platform time units: expiration of lease (-1 for static) 1523 mDNSBool Private; // If zone is private, DNS updates may have to be encrypted to prevent eavesdropping 1524 mDNSOpaque16 updateid; // Identifier to match update request and response -- also used when transferring records to Sleep Proxy 1525 mDNSOpaque64 updateIntID; // Interface IDs (one bit per interface index)to which updates have been sent 1526 const domainname *zone; // the zone that is updated 1527 ZoneData *nta; 1528 struct tcpInfo_t *tcp; 1529 NATTraversalInfo NATinfo; 1530 mDNSBool SRVChanged; // temporarily deregistered service because its SRV target or port changed 1531 mergeState_t mState; // Unicast Record Registrations merge state 1532 mDNSu8 refreshCount; // Number of refreshes to the server 1533 mStatus updateError; // Record update resulted in Error ? 1534 1535 // uDNS_UpdateRecord support fields 1536 // Do we really need all these in *addition* to NewRData and newrdlength above? 1537 void *UpdateContext; // Context parameter for the update callback function 1538 mDNSu16 OrigRDLen; // previously registered, being deleted 1539 mDNSu16 InFlightRDLen; // currently being registered 1540 mDNSu16 QueuedRDLen; // pending operation (re-transmitting if necessary) THEN register the queued update 1541 RData *OrigRData; 1542 RData *InFlightRData; 1543 RData *QueuedRData; 1544 1545 mDNSs32 TimeRegistered; // The time when the record is registered in platform time units. 1546 1547 // Field Group 5: Large data objects go at the end 1548 domainname namestorage; 1549 RData rdatastorage; // Normally the storage is right here, except for oversized records 1550 // rdatastorage MUST be the last thing in the structure -- when using oversized AuthRecords, extra bytes 1551 // are appended after the end of the AuthRecord, logically augmenting the size of the rdatastorage 1552 // DO NOT ADD ANY MORE FIELDS HERE 1553 }; 1554 1555 // IsLocalDomain alone is not sufficient to determine that a record is mDNS or uDNS. By default domain names within 1556 // the "local" pseudo-TLD (and within the IPv4 and IPv6 link-local reverse mapping domains) are automatically treated 1557 // as mDNS records, but it is also possible to force any record (even those not within one of the inherently local 1558 // domains) to be handled as an mDNS record by setting the ForceMCast flag, or by setting a non-zero InterfaceID. 1559 // For example, the reverse-mapping PTR record created in AdvertiseInterface sets the ForceMCast flag, since it points to 1560 // a dot-local hostname, and therefore it would make no sense to register this record with a wide-area Unicast DNS server. 1561 // The same applies to Sleep Proxy records, which we will answer for when queried via mDNS, but we never want to try 1562 // to register them with a wide-area Unicast DNS server -- and we probably don't have the required credentials anyway. 1563 // Currently we have no concept of a wide-area uDNS record scoped to a particular interface, so if the InterfaceID is 1564 // nonzero we treat this the same as ForceMCast. 1565 // Note: Question_uDNS(Q) is used in *only* one place -- on entry to mDNS_StartQuery_internal, to decide whether to set TargetQID. 1566 // Everywhere else in the code, the determination of whether a question is unicast is made by checking to see if TargetQID is nonzero. 1567 #define AuthRecord_uDNS(R) ((R)->resrec.InterfaceID == mDNSInterface_Any && !(R)->ForceMCast && !IsLocalDomain((R)->resrec.name)) 1568 #define Question_uDNS(Q) ((Q)->IsUnicastDotLocal || (Q)->ProxyQuestion || \ 1569 ((Q)->InterfaceID != mDNSInterface_LocalOnly && (Q)->InterfaceID != mDNSInterface_P2P && (Q)->InterfaceID != mDNSInterface_BLE && !(Q)->ForceMCast && !IsLocalDomain(&(Q)->qname))) 1570 1571 // AuthRecordLocalOnly records are registered using mDNSInterface_LocalOnly and 1572 // AuthRecordP2P records are created by D2DServiceFound events. Both record types are kept on the same list. 1573 #define RRLocalOnly(rr) ((rr)->ARType == AuthRecordLocalOnly || (rr)->ARType == AuthRecordP2P) 1574 1575 // All other auth records, not including those defined as RRLocalOnly(). 1576 #define RRAny(rr) ((rr)->ARType == AuthRecordAny || (rr)->ARType == AuthRecordAnyIncludeP2P || (rr)->ARType == AuthRecordAnyIncludeAWDL || (rr)->ARType == AuthRecordAnyIncludeAWDLandP2P) 1577 1578 // Normally we always lookup the cache and /etc/hosts before sending the query on the wire. For single label 1579 // queries (A and AAAA) that are unqualified (indicated by AppendSearchDomains), we want to append search 1580 // domains before we try them as such 1581 #define ApplySearchDomainsFirst(q) ((q)->AppendSearchDomains && (CountLabels(&((q)->qname))) == 1) 1582 1583 // Wrapper struct for Auth Records for higher-level code that cannot use the AuthRecord's ->next pointer field 1584 typedef struct ARListElem 1585 { 1586 struct ARListElem *next; 1587 AuthRecord ar; // Note: Must be last element of structure, to accomodate oversized AuthRecords 1588 } ARListElem; 1589 1590 #if MDNSRESPONDER_SUPPORTS(APPLE, LOG_PRIVACY_LEVEL) 1591 // This enum is used by state dump to determine whether the cache record should be redacted when printing the state. 1592 MDNS_CLOSED_ENUM(mDNSCRLogPrivacyLevel, mDNSu8, 1593 // The state change flow: 1594 // mDNSCRLogPrivacyLevel_Default -> mDNSCRLogPrivacyLevel_Private -> mDNSCRLogPrivacyLevel_Public 1595 // | ^ 1596 // ----------------------------------------------------------| 1597 mDNSCRLogPrivacyLevel_Default = 0, // No state has been set, unredacted. 1598 mDNSCRLogPrivacyLevel_Private = 1, // Private state, redacted. 1599 mDNSCRLogPrivacyLevel_Public = 2 // Public state, unredacted. 1600 ); 1601 1602 #define PRIVATE_DOMAIN_NAME ((const domainname *)"\x7" "private" "\x6" "domain" "\x4" "name" "\x7" "invalid") 1603 #define PRIVATE_RECORD_DESCRIPTION "<private record description>" 1604 1605 #endif // MDNSRESPONDER_SUPPORTS(APPLE, LOG_PRIVACY_LEVEL) 1606 1607 struct CacheRecord_struct 1608 { 1609 CacheRecord *next; // Next in list; first element of structure for efficiency reasons 1610 ResourceRecord resrec; // 36 bytes when compiling for 32-bit; 48 when compiling for 64-bit (now 44/64) 1611 1612 // Transient state for Cache Records 1613 CacheRecord *NextInKAList; // Link to the next element in the chain of known answers to send 1614 mDNSs32 TimeRcvd; // In platform time units 1615 mDNSs32 DelayDelivery; // Set if we want to defer delivery of this answer to local clients 1616 mDNSs32 NextRequiredQuery; // In platform time units 1617 #if MDNSRESPONDER_SUPPORTS(APPLE, CACHE_ANALYTICS) 1618 mDNSs32 LastCachedAnswerTime; // Last time this record was used as an answer from the cache (before a query) 1619 // In platform time units 1620 #else 1621 // Extra four bytes here (on 64bit) 1622 #endif 1623 DNSQuestion *CRActiveQuestion; // Points to an active question referencing this answer. Can never point to a NewQuestion. 1624 mDNSs32 LastUnansweredTime; // In platform time units; last time we incremented UnansweredQueries 1625 mDNSu8 UnansweredQueries; // Number of times we've issued a query for this record without getting an answer 1626 1627 #if MDNSRESPONDER_SUPPORTS(COMMON, DNS_PUSH) || MDNSRESPONDER_SUPPORTS(APPLE, DNS_PUSH) 1628 mDNSBool DNSPushSubscribed; // Indicate whether the cached record has an active DNS push subscription. If 1629 // true, the record never expires. 1630 #endif 1631 1632 mDNSOpaque16 responseFlags; // Second 16 bit in the DNS response 1633 CacheRecord *NextInCFList; // Set if this is in the list of records we just received with the cache flush bit set 1634 CacheRecord *soa; // SOA record to return for proxy questions 1635 1636 #if MDNSRESPONDER_SUPPORTS(APPLE, DNSSECv2) 1637 mDNSBool ineligibleForRecycling; // If this cached record can be recycled when there is not enough cache space. 1638 #endif 1639 #if MDNSRESPONDER_SUPPORTS(APPLE, LOG_PRIVACY_LEVEL) 1640 mDNSCRLogPrivacyLevel PrivacyLevel; // The privacy level of the cache record. 1641 #endif 1642 #if MDNSRESPONDER_SUPPORTS(APPLE, UNICAST_ASSIST) 1643 mDNSBool unicastAssistSent; // Unicast Assist sent state of this record. 1644 #endif 1645 1646 mDNSAddr sourceAddress; // node from which we received this record 1647 // Size to here is 76 bytes when compiling 32-bit; 104 bytes when compiling 64-bit (now 160 bytes for 64-bit) 1648 RData_small smallrdatastorage; // Storage for small records is right here (4 bytes header + 68 bytes data = 72 bytes) 1649 }; 1650 1651 // Should match the CacheGroup_struct members, except namestorage[]. Only used to calculate 1652 // the size of the namestorage array in CacheGroup_struct so that sizeof(CacheGroup) == sizeof(CacheRecord) 1653 struct CacheGroup_base 1654 { 1655 CacheGroup *next; 1656 mDNSu32 namehash; 1657 CacheRecord *members; 1658 CacheRecord **rrcache_tail; 1659 domainname *name; 1660 }; 1661 1662 struct CacheGroup_struct // Header object for a list of CacheRecords with the same name 1663 { 1664 CacheGroup *next; // Next CacheGroup object in this hash table bucket 1665 mDNSu32 namehash; // Name-based (i.e. case insensitive) hash of name 1666 CacheRecord *members; // List of CacheRecords with this same name 1667 CacheRecord **rrcache_tail; // Tail end of that list 1668 domainname *name; // Common name for all CacheRecords in this list 1669 mDNSu8 namestorage[sizeof(CacheRecord) - sizeof(struct CacheGroup_base)]; // match sizeof(CacheRecord) 1670 }; 1671 1672 // Storage sufficient to hold either a CacheGroup header or a CacheRecord 1673 // -- for best efficiency (to avoid wasted unused storage) they should be the same size 1674 typedef union CacheEntity_union CacheEntity; 1675 union CacheEntity_union { CacheEntity *next; CacheGroup cg; CacheRecord cr; }; 1676 1677 typedef struct 1678 { 1679 CacheRecord r; 1680 mDNSu8 _extradata[MaximumRDSize-InlineCacheRDSize]; // Glue on the necessary number of extra bytes 1681 domainname namestorage; // Needs to go *after* the extra rdata bytes 1682 } LargeCacheRecord; 1683 1684 typedef struct HostnameInfo 1685 { 1686 struct HostnameInfo *next; 1687 NATTraversalInfo natinfo; 1688 domainname fqdn; 1689 AuthRecord arv4; // registered IPv4 address record 1690 AuthRecord arv6; // registered IPv6 address record 1691 mDNSRecordCallback *StatusCallback; // callback to deliver success or error code to client layer 1692 const void *StatusContext; // Client Context 1693 } HostnameInfo; 1694 1695 typedef struct ExtraResourceRecord_struct ExtraResourceRecord; 1696 struct ExtraResourceRecord_struct 1697 { 1698 ExtraResourceRecord *next; 1699 mDNSu32 ClientID; // Opaque ID field to be used by client to map an AddRecord call to a set of Extra records 1700 AuthRecord r; 1701 // Note: Add any additional fields *before* the AuthRecord in this structure, not at the end. 1702 // In some cases clients can allocate larger chunks of memory and set r->rdata->MaxRDLength to indicate 1703 // that this extra memory is available, which would result in any fields after the AuthRecord getting smashed 1704 }; 1705 1706 // Note: Within an mDNSServiceCallback mDNS all API calls are legal except mDNS_Init(), mDNS_Exit(), mDNS_Execute() 1707 typedef void mDNSServiceCallback (mDNS *const m, ServiceRecordSet *const sr, mStatus result); 1708 1709 // A ServiceRecordSet has no special meaning to the core code of the Multicast DNS protocol engine; 1710 // it is just a convenience structure to group together the records that make up a standard service 1711 // registration so that they can be allocted and deallocted together as a single memory object. 1712 // It contains its own ServiceCallback+ServiceContext to report aggregate results up to the next layer of software above. 1713 // It also contains: 1714 // * the basic PTR/SRV/TXT triplet used to represent any DNS-SD service 1715 // * the "_services" PTR record for service enumeration 1716 // * the optional list of SubType PTR records 1717 // * the optional list of additional records attached to the service set (e.g. iChat pictures) 1718 1719 struct ServiceRecordSet_struct 1720 { 1721 // These internal state fields are used internally by mDNSCore; the client layer needn't be concerned with them. 1722 // No fields need to be set up by the client prior to calling mDNS_RegisterService(); 1723 // all required data is passed as parameters to that function. 1724 mDNSServiceCallback *ServiceCallback; 1725 void *ServiceContext; 1726 mDNSBool Conflict; // Set if this record set was forcibly deregistered because of a conflict 1727 1728 ExtraResourceRecord *Extras; // Optional list of extra AuthRecords attached to this service registration. e.g. TSR record 1729 mDNSu32 NumSubTypes; 1730 AuthRecord *SubTypes; 1731 mDNSu32 flags; // saved for subsequent calls to mDNS_RegisterService() if records 1732 // need to be re-registered. 1733 AuthRecord RR_ADV; // e.g. _services._dns-sd._udp.local. PTR _printer._tcp.local. 1734 AuthRecord RR_PTR; // e.g. _printer._tcp.local. PTR Name._printer._tcp.local. 1735 AuthRecord RR_SRV; // e.g. Name._printer._tcp.local. SRV 0 0 port target 1736 AuthRecord RR_TXT; // e.g. Name._printer._tcp.local. TXT PrintQueueName 1737 // Don't add any fields after AuthRecord RR_TXT. 1738 // This is where the implicit extra space goes if we allocate a ServiceRecordSet containing an oversized RR_TXT record 1739 }; 1740 1741 // *************************************************************************** 1742 #if 0 1743 #pragma mark - 1744 #pragma mark - Question structures 1745 #endif 1746 1747 // We record the last eight instances of each duplicate query 1748 // This gives us v4/v6 on each of Ethernet, AirPort and Firewire, and two free slots "for future expansion" 1749 // If the host has more active interfaces that this it is not fatal -- duplicate question suppression will degrade gracefully. 1750 // Since we will still remember the last eight, the busiest interfaces will still get the effective duplicate question suppression. 1751 #define DupSuppressInfoSize 8 1752 1753 typedef struct 1754 { 1755 mDNSInterfaceID InterfaceID; 1756 mDNSs32 Time; 1757 mDNSs32 Type; // v4 or v6? 1758 } DupSuppressInfo; 1759 1760 typedef struct 1761 { 1762 DupSuppressInfo slots[DupSuppressInfoSize]; // Data structures for keeping track of duplicate query suppressions. 1763 } DupSuppressState; 1764 1765 MDNS_CLOSED_ENUM(LLQ_State, mDNSu8, 1766 LLQ_Invalid = 0, 1767 // This is the initial state. 1768 LLQ_Init = 1, 1769 1770 // All of these states indicate that we are doing DNS Push, and haven't given up yet. 1771 LLQ_DNSPush_ServerDiscovery = 10, 1772 LLQ_DNSPush_Connecting = 11, 1773 LLQ_DNSPush_Established = 12, 1774 1775 // All of these states indicate that we are doing LLQ and haven't given up yet. 1776 LLQ_InitialRequest = 20, 1777 LLQ_SecondaryRequest = 21, 1778 LLQ_Established = 22, 1779 1780 // If we get here, it means DNS Push isn't available, so we're polling. 1781 LLQ_Poll = 30 1782 ); 1783 1784 #if MDNSRESPONDER_SUPPORTS(COMMON, DNS_PUSH) 1785 #define DNS_PUSH_IN_PROGRESS(STATE) ((STATE) == LLQ_DNSPush_ServerDiscovery || (STATE) == LLQ_DNSPush_Connecting \ 1786 || (STATE) == LLQ_DNSPush_Established) 1787 #endif 1788 1789 // LLQ constants 1790 #define kLLQ_Vers 1 1791 #define kLLQ_DefLease 7200 // 2 hours 1792 #define kLLQ_MAX_TRIES 3 // retry an operation 3 times max 1793 #define kLLQ_INIT_RESEND 2 // resend an un-ack'd packet after 2 seconds, then double for each additional 1794 // LLQ Operation Codes 1795 #define kLLQOp_Setup 1 1796 #define kLLQOp_Refresh 2 1797 #define kLLQOp_Event 3 1798 1799 // LLQ Errror Codes 1800 enum 1801 { 1802 LLQErr_NoError = 0, 1803 LLQErr_ServFull = 1, 1804 LLQErr_Static = 2, 1805 LLQErr_FormErr = 3, 1806 LLQErr_NoSuchLLQ = 4, 1807 LLQErr_BadVers = 5, 1808 LLQErr_UnknownErr = 6 1809 }; 1810 1811 typedef enum { 1812 DNSPushServerDisconnected, 1813 DNSPushServerConnectFailed, 1814 DNSPushServerConnectionInProgress, 1815 DNSPushServerConnected, 1816 DNSPushServerSessionEstablished, 1817 DNSPushServerNoDNSPush 1818 } DNSPushServer_ConnectState; 1819 1820 #define HMAC_LEN 64 1821 #define HMAC_IPAD 0x36 1822 #define HMAC_OPAD 0x5c 1823 #define MD5_LEN 16 1824 1825 // Internal data structure to maintain authentication information 1826 1827 #if MDNSRESPONDER_SUPPORTS(APPLE, SECURE_HMAC_ALGORITHM_2022) 1828 1829 typedef enum { 1830 kDNSDigest_HMACAlg_None = 0, 1831 kDNSDigest_HMACAlg_MD5, 1832 kDNSDigest_HMACAlg_SHA1, 1833 kDNSDigest_HMACAlg_SHA224, 1834 kDNSDigest_HMACAlg_SHA256, 1835 kDNSDigest_HMACAlg_SHA384, 1836 kDNSDigest_HMACAlg_SHA512, 1837 } DNSDigest_HMACAlgorithm; 1838 1839 #define kDNSDigest_HMACMD5_OutputLengthInBytes 16 1840 #define kDNSDigest_HMACSHA1_OutputLengthInBytes 20 1841 #define kDNSDigest_HMACSHA224_OutputLengthInBytes 28 1842 #define kDNSDigest_HMACSHA256_OutputLengthInBytes 32 1843 #define kDNSDigest_HMACSHA384_OutputLengthInBytes 48 1844 #define kDNSDigest_HMACSHA512_OutputLengthInBytes 64 1845 1846 #define kDNSDigest_HMACMD5_KeyLengthInBytes kDNSDigest_HMACMD5_OutputLengthInBytes 1847 #define kDNSDigest_HMACSHA1_KeyLengthInBytes kDNSDigest_HMACSHA1_OutputLengthInBytes 1848 #define kDNSDigest_HMACSHA224_KeyLengthInBytes kDNSDigest_HMACSHA224_OutputLengthInBytes 1849 #define kDNSDigest_HMACSHA256_KeyLengthInBytes kDNSDigest_HMACSHA256_OutputLengthInBytes 1850 #define kDNSDigest_HMACSHA384_KeyLengthInBytes kDNSDigest_HMACSHA384_OutputLengthInBytes 1851 #define kDNSDigest_HMACSHA512_KeyLengthInBytes kDNSDigest_HMACSHA512_OutputLengthInBytes 1852 1853 #define DNSDigest_Base64EncodedSize(SIZE) ((((SIZE) + 2) / 3) * 4) 1854 #define DNSDigest_Base64EncodedMaxSize(SIZE) (DNSDigest_Base64EncodedSize(SIZE)) 1855 1856 #define kDNSDigest_HMACKeyLengthInBytesMAX kDNSDigest_HMACSHA512_KeyLengthInBytes 1857 #define kDNSDigest_HMACBase64EncodedKeyLengthInBytesMAX (DNSDigest_Base64EncodedMaxSize(kDNSDigest_HMACKeyLengthInBytesMAX)) 1858 #define kDNSDigest_HMACOutputLengthInBytesMAX kDNSDigest_HMACSHA512_OutputLengthInBytes 1859 1860 #endif // MDNSRESPONDER_SUPPORTS(APPLE, SECURE_HMAC_ALGORITHM_2022) 1861 1862 typedef struct DomainAuthInfo 1863 { 1864 struct DomainAuthInfo *next; 1865 mDNSs32 deltime; // If we're planning to delete this DomainAuthInfo, the time we want it deleted 1866 domainname domain; 1867 domainname keyname; 1868 domainname hostname; 1869 mDNSIPPort port; 1870 #if MDNSRESPONDER_SUPPORTS(APPLE, SECURE_HMAC_ALGORITHM_2022) 1871 DNSDigest_HMACAlgorithm algorithm; // The algorithm of the key. 1872 mDNSu32 key_len; // The actual length of the key data in bytes. 1873 mDNSu8 key[kDNSDigest_HMACKeyLengthInBytesMAX]; // The "large enough" key data buffer. 1874 #else 1875 char b64keydata[32]; 1876 mDNSu8 keydata_ipad[HMAC_LEN]; // padded key for inner hash rounds 1877 mDNSu8 keydata_opad[HMAC_LEN]; // padded key for outer hash rounds 1878 #endif 1879 } DomainAuthInfo; 1880 1881 // Note: Within an mDNSQuestionCallback mDNS all API calls are legal except mDNS_Init(), mDNS_Exit(), mDNS_Execute() 1882 // Note: Any value other than QC_rmv i.e., any non-zero value will result in kDNSServiceFlagsAdd to the application 1883 // layer. These values are used within mDNSResponder and not sent across to the application. QC_addnocache is for 1884 // delivering a response without adding to the cache. QC_forceresponse is superset of QC_addnocache where in 1885 // addition to not entering in the cache, it also forces the negative response through. 1886 typedef enum { QC_rmv = 0, QC_add, QC_addnocache, QC_forceresponse, QC_suppressed } QC_result; 1887 typedef void mDNSQuestionCallback (mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord); 1888 typedef void (*mDNSQuestionResetHandler)(DNSQuestion *question); 1889 typedef void AsyncDispatchFunc(mDNS *const m, void *context); 1890 extern void mDNSPlatformDispatchAsync(mDNS *const m, void *context, AsyncDispatchFunc func); 1891 1892 #define NextQSendTime(Q) ((Q)->LastQTime + (Q)->ThisQInterval) 1893 #define ActiveQuestion(Q) ((Q)->ThisQInterval > 0 && !(Q)->DuplicateOf) 1894 #define TimeToSendThisQuestion(Q,time) (ActiveQuestion(Q) && (time) - NextQSendTime(Q) >= 0) 1895 #define TicksTTL(RR) ((mDNSs32)(RR)->resrec.rroriginalttl * mDNSPlatformOneSecond) 1896 extern mDNSs32 RRExpireTime(const CacheRecord *cr); 1897 #define MaxUnansweredQueries 4 1898 #define MaxTentativeSeconds 5 1899 1900 // RFC 4122 defines it to be 16 bytes 1901 #define UUID_SIZE 16 1902 1903 #if MDNSRESPONDER_SUPPORTS(APPLE, DNS_ANALYTICS) || MDNSRESPONDER_SUPPORTS(APPLE, RUNTIME_MDNS_METRICS) 1904 typedef struct 1905 { 1906 mDNSu32 querySendCount; // Number of queries that have been sent to DNS servers so far. 1907 mDNSs32 firstQueryTime; // The time when the first query was sent to a DNS server. 1908 mDNSBool answered; // Has this question been answered? 1909 } DNSMetrics; 1910 #endif 1911 1912 #if MDNSRESPONDER_SUPPORTS(APPLE, DNS64) 1913 #include "DNS64State.h" 1914 #endif 1915 1916 typedef struct mDNS_DNSPushServer DNSPushServer; 1917 typedef struct mDNS_DNSPushZone DNSPushZone; 1918 1919 MDNS_CLOSED_ENUM(mDNSExpiredRecordPolicy, mDNSu8, 1920 mDNSExpiredRecordPolicy_DoNotUse = 0, // Don't use expired cache records at all. This is the default policy. 1921 mDNSExpiredRecordPolicy_UseCached = 1, // Use expired cache records and immortalize unexpired answers. [1,2] 1922 mDNSExpiredRecordPolicy_Immortalize = 2 // Don't use expired records, but immortalize unexpired answers. [1,2] 1923 ); 1924 // Notes: 1925 // 1. Policy only applies to non-mDNS DNSQuestions. 1926 // 2. A DNSQuestion that uses the mDNSExpiredRecordPolicy_UseCached policy will be downgraded to the 1927 // mDNSExpiredRecordPolicy_Immortalize policy after it has been determined that there are no expired cache records 1928 // that can be used as answers for the DNSQuestion. The mDNSQuestionEvent_NoMoreExpiredRecords event will be 1929 // delivered via the DNSQuestion's event handler after the determination, right before the policy downgrade. 1930 1931 MDNS_CLOSED_ENUM(mDNSQuestionEvent, mDNSu8, 1932 mDNSQuestionEvent_NoMoreExpiredRecords = 1 // No more expired cache records will be provided. [1] 1933 ); 1934 // Notes: 1935 // 1. This event is only relevant for non-mDNS DNSQuestions that use the mDNSExpiredRecordPolicy_UseCached policy. It 1936 // signals that no more expired cache records will be provided to a DNSQuestion's owner. 1937 1938 typedef void (*mDNSQuestionEventHandler)(DNSQuestion *question, mDNSQuestionEvent event); 1939 1940 #if MDNSRESPONDER_SUPPORTS(APPLE, PADDING_CHECKS) 1941 // The member variables of struct DNSQuestion_struct are in descending order of alignment requirement to eliminate 1942 // padding between member variables. That is, member variables with an 8-byte alignment requirement come first, followed 1943 // by member variables with a 4-byte alignment requirement, and so forth. 1944 MDNS_CLANG_TREAT_WARNING_AS_ERROR_BEGIN(-Wpadded) 1945 #endif 1946 struct DNSQuestion_struct 1947 { 1948 #if MDNSRESPONDER_SUPPORTS(APPLE, QUERIER) 1949 mdns_dns_service_id_t CustomID; // ID for client-specific custom DNS service. 1950 #endif 1951 DNSQuestion *next; 1952 mDNSInterfaceID FlappingInterface1; // Set when an interface goes away, to flag if remove events are delivered for this Q 1953 mDNSInterfaceID FlappingInterface2; // Set when an interface goes away, to flag if remove events are delivered for this Q 1954 DomainAuthInfo *AuthInfo; // Non-NULL if query is currently being done using Private DNS 1955 DNSQuestion *DuplicateOf; 1956 DNSQuestion *NextInDQList; 1957 DupSuppressState *DupSuppress; 1958 mDNSInterfaceID SendQNow; // The interface this query is being sent on right now 1959 UDPSocket *LocalSocket; 1960 #if MDNSRESPONDER_SUPPORTS(APPLE, QUERIER) 1961 mdns_dns_service_t dnsservice; // The current DNS service. 1962 mdns_dns_service_id_t lastDNSServiceID; // The ID of the previous DNS service before a CNAME restart. 1963 mdns_client_t client; // The current querier or subscriber. 1964 #else 1965 DNSServer *qDNSServer; // Caching server for this query (in the absence of an SRV saying otherwise) 1966 #endif 1967 ZoneData *nta; // Used for getting zone data for private or LLQ query 1968 struct tcpInfo_t *tcp; 1969 #if MDNSRESPONDER_SUPPORTS(COMMON, DNS_PUSH) 1970 // DNS Push fields. These fields are only meaningful when LongLived flag is set. 1971 DNSPushZone *dnsPushZone; // The DNS push zone where the current question is if the 1972 // kDNSServiceFlagsLongLivedQuery flag is set. 1973 DNSPushServer *dnsPushServer; // The DNS push server that is responsible for answering the current 1974 // question if the kDNSServiceFlagsLongLivedQuery flag is set. 1975 #endif 1976 #if MDNSRESPONDER_SUPPORTS(APPLE, AUDIT_TOKEN) 1977 mdns_audit_token_t PeerToken; // The immediate client's audit token. 1978 mdns_audit_token_t DelegatorToken; // The delegator's audit token if the immediate client is a delegate. 1979 #endif 1980 mDNSInterfaceID InterfaceID; // Non-zero if you want to issue queries only on a single specific IP interface 1981 #if MDNSRESPONDER_SUPPORTS(APPLE, DNSSECv2) 1982 dnssec_obj_dns_question_member_t dnssec;// DNSSEC-related information for the current question. 1983 #endif 1984 mDNSQuestionCallback *QuestionCallback; 1985 mDNSQuestionResetHandler ResetHandler; 1986 mDNSQuestionEventHandler EventHandler; 1987 void *QuestionContext; 1988 #if MDNSRESPONDER_SUPPORTS(APPLE, DNS_PUSH) 1989 dns_push_obj_dns_question_member_t dns_push; 1990 #endif 1991 #if MDNSRESPONDER_SUPPORTS(APPLE, DISCOVERY_PROXY_CLIENT) 1992 CFMutableSetRef DPSubscribers; // Current set of local domain Discovery Proxy subscribers. 1993 #endif 1994 mDNSu32 qnamehash; 1995 mDNSs32 DelayAnswering; // Set if we want to defer answering this question until the cache settles 1996 mDNSs32 LastQTime; // Last scheduled transmission of this Q on *all* applicable interfaces 1997 mDNSs32 ThisQInterval; // LastQTime + ThisQInterval is the next scheduled transmission of this Q 1998 // ThisQInterval > 0 for an active question; 1999 // ThisQInterval = 0 for a suspended question that's still in the list 2000 // ThisQInterval = -1 for a cancelled question (should not still be in list) 2001 mDNSs32 ExpectUnicastResp; // Set when we send a query with the kDNSQClass_UnicastResponse bit set 2002 mDNSs32 LastAnswerPktNum; // The sequence number of the last response packet containing an answer to this Q 2003 mDNSu32 RecentAnswerPkts; // Number of answers since the last time we sent this query 2004 mDNSu32 CurrentAnswers; // Number of records currently in the cache that answer this question 2005 mDNSu32 LargeAnswers; // Number of answers with rdata > 1024 bytes 2006 mDNSu32 UniqueAnswers; // Number of answers received with kDNSClass_UniqueRRSet bit set 2007 mDNSs32 StopTime; // Time this question should be stopped by giving them a negative answer 2008 mDNSs32 pid; // Process ID of the client that is requesting the question 2009 mDNSu32 euid; // Effective User Id of the client that is requesting the question 2010 mDNSu32 request_id; // The ID of request that generates the current question 2011 mDNSs32 LastQTxTime; // Last time this Q was sent on one (but not necessarily all) interfaces 2012 #if MDNSRESPONDER_SUPPORTS(APPLE, DNS_ANALYTICS) || MDNSRESPONDER_SUPPORTS(APPLE, RUNTIME_MDNS_METRICS) 2013 DNSMetrics metrics; // Data used for collecting unicast/multicast DNS query metrics. 2014 #endif 2015 mDNSu32 ReqLease; // LLQ: seconds (relative) 2016 mDNSs32 expire; // LLQ: ticks (absolute) 2017 mDNSs32 ServiceID; // Service identifier to match against the DNS server 2018 mDNSAddr servAddr; // Address and port learned from _dns-llq, _dns-llq-tls or _dns-query-tls SRV query 2019 #if MDNSRESPONDER_SUPPORTS(APPLE, UNICAST_DISCOVERY) 2020 mDNSAddr UnicastMDNSResolver; // If a non-zero IP address, mDNS queries will be sent to this address via 2021 // unicast instead of to an mDNS multicast address. 2022 #endif 2023 mDNSu32 flags; // flags from original DNSService*() API request. 2024 mDNSOpaque64 id; 2025 #if !MDNSRESPONDER_SUPPORTS(APPLE, QUERIER) 2026 mDNSOpaque128 validDNSServers; // Valid DNSServers for this question 2027 #endif 2028 mDNSIPPort servPort; 2029 mDNSIPPort tcpSrcPort; // Local Port TCP packet received on;need this as tcp struct is disposed 2030 // by tcpCallback before calling into mDNSCoreReceive 2031 mDNSOpaque16 TargetQID; // DNS or mDNS message ID. 2032 mDNSu16 qtype; 2033 mDNSu16 qclass; 2034 mDNSOpaque16 responseFlags; // Temporary place holder for the error we get back from the DNS server 2035 // till we populate in the cache 2036 mDNSs16 ntries; // for UDP: the number of packets sent for this LLQ state 2037 // for TCP: there is some ambiguity in the use of this variable, but in general, it is 2038 // the number of TCP/TLS connection attempts for this LLQ state, or 2039 // the number of packets sent for this TCP/TLS connection 2040 #if !MDNSRESPONDER_SUPPORTS(APPLE, QUERIER) 2041 mDNSu16 noServerResponse; // At least one server did not respond. 2042 #endif 2043 LLQ_State state; 2044 mDNSu8 BrowseThreshold; // If we have received at least this number of answers, 2045 // set the next question interval to MaxQuestionInterval 2046 mDNSu8 RequestUnicast; // Non-zero if we want to send query with kDNSQClass_UnicastResponse bit set 2047 mDNSu8 CNAMEReferrals; // Count of how many CNAME redirections we've done 2048 mDNSBool Suppressed; // This query should be suppressed, i.e., not sent on the wire. 2049 mDNSu8 LOAddressAnswers; // Number of answers from the local only auth records that are 2050 // answering A, AAAA, CNAME, or PTR (/etc/hosts) 2051 mDNSu8 WakeOnResolveCount; // Number of wakes that should be sent on resolve 2052 mDNSBool InitialCacheMiss; // True after the question cannot be answered from the cache 2053 mDNSBool SendOnAll; // Set if we're sending this question on all active interfaces 2054 mDNSBool CachedAnswerNeedsUpdate; // See SendQueries(). Set if we're sending this question 2055 // because a cached answer needs to be refreshed. 2056 #if MDNSRESPONDER_SUPPORTS(APPLE, QUERIER) 2057 mDNSu8 ResolverUUID[UUID_SIZE]; // Resolver UUID to match against the DNS server 2058 #endif 2059 domainname qname; 2060 mDNSBool LongLived; // Set by client for calls to mDNS_StartQuery to indicate LLQs to unicast layer. 2061 mDNSBool ExpectUnique; // Set by client if it's expecting unique RR(s) for this question, not shared RRs 2062 mDNSBool ForceMCast; // Set by client to force mDNS query, even for apparently uDNS names 2063 mDNSBool ReturnIntermed; // Set by client to request callbacks for intermediate CNAME/NXDOMAIN results 2064 mDNSBool SuppressUnusable; // Set by client to suppress unusable queries to be sent on the wire 2065 mDNSBool TimeoutQuestion; // Timeout this question if there is no reply in configured time 2066 mDNSBool IsUnicastDotLocal; // True if this is a dot-local query that should be answered via unicast DNS. 2067 mDNSBool WakeOnResolve; // Send wakeup on resolve 2068 mDNSBool UseBackgroundTraffic; // Set by client to use background traffic class for request 2069 mDNSBool AppendSearchDomains; // Search domains can be appended for this query 2070 mDNSBool ForcePathEval; // Perform a path evaluation even if kDNSServiceFlagsPathEvaluationDone is set. 2071 mDNSBool IsFailover; // True if the client requested to skip resolvers that allow failover. 2072 mDNSBool PersistWhenRecordsUnusable; // Set by client to force CNAME follows while suppressed due to unusable records. 2073 mDNSBool ForceCNAMEFollows; // Follow CNAMEs even if the DNSQuestion is suppressed. 2074 mDNSExpiredRecordPolicy ExpRecordPolicy;// The DNSQuestion's policy for expired records. 2075 #if MDNSRESPONDER_SUPPORTS(APPLE, QUERIER) 2076 mDNSBool RequireEncryption; // Set by client to require encrypted queries 2077 mDNSBool NeedUpdatedQuerier; // True if new querier is needed for DNSQuestion's updated qname/qtype/qclass. 2078 mDNSBool UsedAsFailFastProbe; // True if used as a probe for fail-fast service with connection problems. 2079 mDNSBool ProhibitEncryptedDNS; // True if use of encrypted DNS protocols is prohibited. 2080 mDNSBool OverrideDNSService; // True if resolver UUID overrides normal DNS service selection. 2081 #endif 2082 mDNSu8 ProxyQuestion; // Proxy Question 2083 #if MDNSRESPONDER_SUPPORTS(APPLE, AUDIT_TOKEN) 2084 mDNSBool inAppBrowserRequest; // Is request associated with an in-app-browser 2085 #endif 2086 mDNSBool BlockedByPolicy; // True if the question is blocked by policy rule evaluation. 2087 #if MDNSRESPONDER_SUPPORTS(APPLE, DNSSECv2) 2088 mDNSBool enableDNSSEC; // The boolean value controlling whether to enable DNSSEC for this question. 2089 #endif 2090 mDNSu8 uuid[UUID_SIZE]; // Unique ID of the client that is requesting the question (valid only if pid is zero) 2091 #if MDNSRESPONDER_SUPPORTS(APPLE, DNS64) 2092 DNS64 dns64; // DNS64 state for performing IPv6 address synthesis on networks with NAT64. 2093 #endif 2094 #if !MDNSRESPONDER_SUPPORTS(APPLE, QUERIER) 2095 mDNSBool triedAllServersOnce; // True if all DNS servers have been tried once. 2096 mDNSu8 unansweredQueries; // The number of unanswered queries to this server 2097 mDNSBool Restart; // This question should be restarted soon. 2098 #endif 2099 #if MDNSRESPONDER_SUPPORTS(APPLE, UNICAST_ASSIST) 2100 mDNSBool initialAssistPerformed; // Initial quetion unicast assist logic was performed 2101 #endif 2102 #if MDNSRESPONDER_SUPPORTS(APPLE, LOG_PRIVACY_LEVEL) 2103 dnssd_log_privacy_level_t logPrivacyLevel; // The log privacy level that the client wishes to have when the question 2104 // is started. 2105 #endif 2106 #if MDNSRESPONDER_SUPPORTS(APPLE, PADDING_CHECKS) 2107 #if TARGET_OS_OSX || TARGET_OS_TV 2108 MDNS_STRUCT_PAD(2); 2109 #else 2110 MDNS_STRUCT_PAD_64_32(6, 2); 2111 #endif 2112 #endif 2113 }; 2114 #if MDNSRESPONDER_SUPPORTS(APPLE, PADDING_CHECKS) 2115 MDNS_CLANG_TREAT_WARNING_AS_ERROR_END() 2116 MDNS_GENERAL_STRUCT_PAD_CHECK(DNSQuestion); 2117 #endif 2118 2119 typedef enum { ZoneServiceUpdate, ZoneServiceQuery, ZoneServiceLLQ, ZoneServiceDNSPush } ZoneService; 2120 2121 typedef void ZoneDataCallback (mDNS *const m, mStatus err, const ZoneData *result); 2122 2123 struct ZoneData_struct 2124 { 2125 domainname ChildName; // Name for which we're trying to find the responsible server 2126 ZoneService ZoneService; // Which service we're seeking for this zone (update, query, or LLQ) 2127 domainname *CurrentSOA; // Points to somewhere within ChildName 2128 domainname ZoneName; // Discovered result: Left-hand-side of SOA record 2129 mDNSu16 ZoneClass; // Discovered result: DNS Class from SOA record 2130 domainname Host; // Discovered result: Target host from SRV record 2131 mDNSIPPort Port; // Discovered result: Update port, query port, or LLQ port from SRV record 2132 mDNSAddr Addr; // Discovered result: Address of Target host from SRV record 2133 mDNSBool ZonePrivate; // Discovered result: Does zone require encrypted queries? 2134 ZoneDataCallback *ZoneDataCallback; // Caller-specified function to be called upon completion 2135 void *ZoneDataContext; 2136 DNSQuestion question; // Storage for any active question 2137 }; 2138 2139 extern ZoneData *StartGetZoneData(mDNS *const m, const domainname *const name, const ZoneService target, ZoneDataCallback callback, void *callbackInfo); 2140 extern void CancelGetZoneData(mDNS *const m, ZoneData *nta); 2141 extern mDNSBool IsGetZoneDataQuestion(DNSQuestion *q); 2142 2143 typedef struct DNameListElem 2144 { 2145 struct DNameListElem *next; 2146 mDNSu32 uid; 2147 domainname name; 2148 } DNameListElem; 2149 2150 2151 // *************************************************************************** 2152 #if 0 2153 #pragma mark - 2154 #pragma mark - NetworkInterfaceInfo_struct 2155 #endif 2156 2157 typedef struct NetworkInterfaceInfo_struct NetworkInterfaceInfo; 2158 2159 // A NetworkInterfaceInfo_struct serves two purposes: 2160 // 1. It holds the address, PTR and HINFO records to advertise a given IP address on a given physical interface 2161 // 2. It tells mDNSCore which physical interfaces are available; each physical interface has its own unique InterfaceID. 2162 // Since there may be multiple IP addresses on a single physical interface, 2163 // there may be multiple NetworkInterfaceInfo_structs with the same InterfaceID. 2164 // In this case, to avoid sending the same packet n times, when there's more than one 2165 // struct with the same InterfaceID, mDNSCore picks one member of the set to be the 2166 // active representative of the set; all others have the 'InterfaceActive' flag unset. 2167 2168 struct NetworkInterfaceInfo_struct 2169 { 2170 // Internal state fields. These are used internally by mDNSCore; the client layer needn't be concerned with them. 2171 NetworkInterfaceInfo *next; 2172 2173 #if MDNSRESPONDER_SUPPORTS(APPLE, RUNTIME_MDNS_METRICS) 2174 // Object that is used to track the mDNS response delay distribution per interface. 2175 // It is only initialized when the interface is mDNS-capable. 2176 mdns_multicast_delay_histogram_t delayHistogram; 2177 #endif 2178 2179 mDNSu8 InterfaceActive; // Set if interface is sending & receiving packets (see comment above) 2180 mDNSu8 IPv4Available; // If InterfaceActive, set if v4 available on this InterfaceID 2181 mDNSu8 IPv6Available; // If InterfaceActive, set if v6 available on this InterfaceID 2182 2183 #if MDNSRESPONDER_SUPPORTS(COMMON, SPS_CLIENT) 2184 DNSQuestion NetWakeBrowse; 2185 DNSQuestion NetWakeResolve[3]; // For fault-tolerance, we try up to three Sleep Proxies 2186 mDNSAddr SPSAddr[3]; 2187 mDNSIPPort SPSPort[3]; 2188 mDNSs32 NextSPSAttempt; // -1 if we're not currently attempting to register with any Sleep Proxy 2189 mDNSs32 NextSPSAttemptTime; 2190 #endif 2191 2192 // Standard AuthRecords that every Responder host should have (one per active IP address) 2193 AuthRecord RR_A; // 'A' or 'AAAA' (address) record for our ".local" name 2194 AuthRecord RR_PTR; // PTR (reverse lookup) record 2195 #if MDNSRESPONDER_SUPPORTS(APPLE, RANDOM_AWDL_HOSTNAME) 2196 AuthRecord RR_AddrRand; // For non-AWDL interfaces, this is the A or AAAA record of the randomized hostname. 2197 #endif 2198 2199 // Client API fields: The client must set up these fields *before* calling mDNS_RegisterInterface() 2200 mDNSInterfaceID InterfaceID; // Identifies physical interface; MUST NOT be 0, -1, or -2 2201 mDNSAddr ip; // The IPv4 or IPv6 address to advertise 2202 mDNSAddr mask; 2203 mDNSEthAddr MAC; 2204 char ifname[64]; // Windows uses a GUID string for the interface name, which doesn't fit in 16 bytes 2205 mDNSu8 Advertise; // False if you are only searching on this interface 2206 mDNSu8 McastTxRx; // Send/Receive multicast on this { InterfaceID, address family } ? 2207 mDNSu8 NetWake; // Set if Wake-On-Magic-Packet is enabled on this interface 2208 mDNSu8 Loopback; // Set if this is the loopback interface 2209 mDNSu8 IgnoreIPv4LL; // Set if IPv4 Link-Local addresses have to be ignored. 2210 mDNSu8 SendGoodbyes; // Send goodbyes on this interface while sleeping 2211 mDNSBool DirectLink; // a direct link, indicating we can skip the probe for 2212 // address records 2213 mDNSBool SupportsUnicastMDNSResponse; // Indicates that the interface supports unicast responses 2214 // to Bonjour queries. Generally true for an interface. 2215 mDNSBool MustNotPreventSleep; // Set if this interface must not ever prevent sleep. 2216 }; 2217 2218 #define SLE_DELETE 0x00000001 2219 #define SLE_WAB_BROWSE_QUERY_STARTED 0x00000002 2220 #define SLE_WAB_LBROWSE_QUERY_STARTED 0x00000004 2221 #define SLE_WAB_REG_QUERY_STARTED 0x00000008 2222 2223 typedef struct SearchListElem 2224 { 2225 struct SearchListElem *next; 2226 domainname domain; 2227 int flag; 2228 mDNSInterfaceID InterfaceID; 2229 DNSQuestion BrowseQ; 2230 DNSQuestion DefBrowseQ; 2231 DNSQuestion AutomaticBrowseQ; 2232 DNSQuestion RegisterQ; 2233 DNSQuestion DefRegisterQ; 2234 int numCfAnswers; 2235 ARListElem *AuthRecs; 2236 } SearchListElem; 2237 2238 typedef enum 2239 { 2240 mDNS_DomainTypeBrowse = 0, 2241 mDNS_DomainTypeBrowseDefault = 1, 2242 mDNS_DomainTypeBrowseAutomatic = 2, 2243 mDNS_DomainTypeRegistration = 3, 2244 mDNS_DomainTypeRegistrationDefault = 4, 2245 2246 mDNS_DomainTypeMax = 4, 2247 mDNS_DomainTypeMaxCount = 5 2248 } mDNS_DomainType; 2249 2250 typedef struct EnumeratedDomainList 2251 { 2252 domainname name; 2253 struct EnumeratedDomainList *next; 2254 } EnumeratedDomainList; 2255 2256 typedef enum { 2257 DomainEnumerationState_Stopped, // Domain enumeration is inactive. 2258 DomainEnumerationState_Started, // Domain enumeration is active. 2259 DomainEnumerationState_StopInProgress, // Domain enumeration is active but will become inactive later. 2260 } DomainEnumerationState; 2261 2262 typedef struct DomainEnumerationWithType DomainEnumerationWithType; 2263 struct DomainEnumerationWithType 2264 { 2265 EnumeratedDomainList *domainList; // Domain discovered through the domain enumeration. 2266 DNSQuestion question; // The DNS question that is used to do the domain enumeration. 2267 DomainEnumerationState state; // The state of the domain enumeration operation. 2268 mDNSu32 activeClientCount; // The number of active clients that need the domain enumeration. 2269 mDNSs32 nextStopTime; // If the operation state is DomainEnumerationState_StopInProgress, it indicates when the operation will be stopped. 2270 }; 2271 2272 typedef struct DomainEnumerationOp DomainEnumerationOp; 2273 struct DomainEnumerationOp 2274 { 2275 domainname name; // The name of the domain that does domain enumeration. 2276 DomainEnumerationWithType *enumerations[mDNS_DomainTypeMaxCount]; // The specific domain enumeration for different types. 2277 DomainEnumerationOp *next; // The next domain in the list to do enumeration. 2278 }; 2279 2280 // For domain enumeration and automatic browsing 2281 // This is the user's DNS search list. 2282 // In each of these domains we search for our special pointer records (lb._dns-sd._udp.<domain>, etc.) 2283 // to discover recommended domains for domain enumeration (browse, default browse, registration, 2284 // default registration) and possibly one or more recommended automatic browsing domains. 2285 extern SearchListElem *SearchList; // This really ought to be part of mDNS_struct -- SC 2286 2287 // *************************************************************************** 2288 #if 0 2289 #pragma mark - 2290 #pragma mark - Main mDNS object, used to hold all the mDNS state 2291 #endif 2292 2293 typedef void mDNSCallback (mDNS *const m, mStatus result); 2294 2295 #ifndef CACHE_HASH_SLOTS 2296 #define CACHE_HASH_SLOTS 499 2297 #endif 2298 2299 enum 2300 { 2301 SleepState_Awake = 0, 2302 SleepState_Transferring = 1, 2303 SleepState_Sleeping = 2 2304 }; 2305 2306 typedef struct 2307 { 2308 mDNSu32 NameConflicts; // Normal Name conflicts 2309 mDNSu32 KnownUniqueNameConflicts; // Name Conflicts for KnownUnique Records 2310 mDNSu32 DupQuerySuppressions; // Duplicate query suppressions 2311 mDNSu32 KnownAnswerSuppressions; // Known Answer suppressions 2312 mDNSu32 KnownAnswerMultiplePkts; // Known Answer in queries spannign multiple packets 2313 mDNSu32 PoofCacheDeletions; // Number of times the cache was deleted due to POOF 2314 mDNSu32 UnicastBitInQueries; // Queries with QU bit set 2315 mDNSu32 NormalQueries; // Queries with QU bit not set 2316 mDNSu32 MatchingAnswersForQueries; // Queries for which we had a response 2317 mDNSu32 UnicastResponses; // Unicast responses to queries 2318 mDNSu32 MulticastResponses; // Multicast responses to queries 2319 mDNSu32 UnicastDemotedToMulticast; // Number of times unicast demoted to multicast 2320 mDNSu32 Sleeps; // Total sleeps 2321 mDNSu32 Wakes; // Total wakes 2322 mDNSu32 InterfaceUp; // Total Interface UP events 2323 mDNSu32 InterfaceUpFlap; // Total Interface UP events with flaps 2324 mDNSu32 InterfaceDown; // Total Interface Down events 2325 mDNSu32 InterfaceDownFlap; // Total Interface Down events with flaps 2326 mDNSu32 CacheRefreshQueries; // Number of queries that we sent for refreshing cache 2327 mDNSu32 CacheRefreshed; // Number of times the cache was refreshed due to a response 2328 mDNSu32 WakeOnResolves; // Number of times we did a wake on resolve 2329 } mDNSStatistics; 2330 2331 extern void LogMDNSStatisticsToFD(int fd, mDNS *const m); 2332 2333 // Time constant (~= 260 hours ~= 10 days and 21 hours) used to set 2334 // various time values to a point well into the future. 2335 #define FutureTime 0x38000000 2336 2337 // Seven days in seconds, used to limit the time since received in TSR record. 2338 #define MaxTimeSinceReceived (7*86400) 2339 2340 #if MDNSRESPONDER_SUPPORTS(APPLE, RUNTIME_MDNS_METRICS) 2341 // Print mDNS response delay distribution for every 30 minutes. 2342 #define RuntimeMDNSMetricsReportInterval (mDNSPlatformOneSecond * 1800) 2343 #endif 2344 2345 struct mDNS_struct 2346 { 2347 // Internal state fields. These hold the main internal state of mDNSCore; 2348 // the client layer needn't be concerned with them. 2349 // No fields need to be set up by the client prior to calling mDNS_Init(); 2350 // all required data is passed as parameters to that function. 2351 2352 mDNS_PlatformSupport *p; // Pointer to platform-specific data of indeterminite size 2353 mDNSs32 NetworkChanged; 2354 mDNSBool CanReceiveUnicastOn5353; 2355 mDNSBool AdvertiseLocalAddresses; 2356 mDNSBool DivertMulticastAdvertisements; // from interfaces that do not advertise local addresses to local-only 2357 mStatus mDNSPlatformStatus; 2358 mDNSIPPort UnicastPort4; 2359 mDNSIPPort UnicastPort6; 2360 mDNSEthAddr PrimaryMAC; // Used as unique host ID 2361 mDNSCallback *MainCallback; 2362 void *MainContext; 2363 2364 // For debugging: To catch and report locking failures 2365 mDNSu32 mDNS_busy; // Incremented between mDNS_Lock/mDNS_Unlock section 2366 mDNSu32 mDNS_reentrancy; // Incremented when calling a client callback 2367 const char *mDNS_Lock_functionname; // Where was the last lock taken 2368 int mDNS_Lock_lineno; // and line number: 2369 mDNSu8 lock_rrcache; // For debugging: Set at times when these lists may not be modified 2370 mDNSu8 lock_Questions; 2371 mDNSu8 lock_Records; 2372 2373 // Task Scheduling variables 2374 mDNSs32 timenow_adjust; // Correction applied if we ever discover time went backwards 2375 mDNSs32 timenow; // The time that this particular activation of the mDNS code started 2376 mDNSs32 timenow_last; // The time the last time we ran 2377 mDNSs32 NextScheduledEvent; // Derived from values below 2378 mDNSs32 ShutdownTime; // Set when we're shutting down; allows us to skip some unnecessary steps 2379 mDNSs32 SuppressQueries; // Don't send local-link mDNS queries during this time 2380 mDNSs32 SuppressResponses; // Don't send local-link mDNS responses during this time 2381 mDNSs32 NextCacheCheck; // Next time to refresh cache record before it expires 2382 mDNSs32 NextScheduledQuery; // Next time to send query in its exponential backoff sequence 2383 mDNSs32 NextScheduledProbe; // Next time to probe for new authoritative record 2384 mDNSs32 NextScheduledResponse; // Next time to send authoritative record(s) in responses 2385 mDNSs32 NextScheduledNATOp; // Next time to send NAT-traversal packets 2386 mDNSs32 NextScheduledSPS; // Next time to purge expiring Sleep Proxy records 2387 mDNSs32 NextScheduledKA; // Next time to send Keepalive packets (SPS) 2388 #if MDNSRESPONDER_SUPPORTS(APPLE, BONJOUR_ON_DEMAND) 2389 mDNSs32 NextBonjourDisableTime; // Next time to leave multicast group if Bonjour on Demand is enabled 2390 mDNSu8 BonjourEnabled; // Non zero if Bonjour is currently enabled by the Bonjour on Demand logic 2391 #endif 2392 mDNSs32 RandomQueryDelay; // For de-synchronization of query packets on the wire 2393 mDNSu32 RandomReconfirmDelay; // For de-synchronization of reconfirmation queries on the wire 2394 mDNSs32 PktNum; // Unique sequence number assigned to each received packet 2395 mDNSs32 MPktNum; // Unique sequence number assigned to each received Multicast packet 2396 mDNSu8 LocalRemoveEvents; // Set if we may need to deliver remove events for local-only questions and/or local-only records 2397 mDNSu8 SleepState; // Set if we're sleeping 2398 mDNSu8 SleepSeqNum; // "Epoch number" of our current period of wakefulness 2399 mDNSu8 SystemWakeOnLANEnabled; // Set if we want to register with a Sleep Proxy before going to sleep 2400 #if MDNSRESPONDER_SUPPORTS(COMMON, SPS_CLIENT) 2401 mDNSu8 SentSleepProxyRegistration; // Set if we registered (or tried to register) with a Sleep Proxy 2402 #endif 2403 mDNSu8 SystemSleepOnlyIfWakeOnLAN; // Set if we may only sleep if we managed to register with a Sleep Proxy 2404 #if MDNSRESPONDER_SUPPORTS(COMMON, SPS_CLIENT) 2405 mDNSs32 AnnounceOwner; // After waking from sleep, include OWNER option in packets until this time 2406 #endif 2407 mDNSs32 DelaySleep; // To inhibit re-sleeping too quickly right after wake 2408 mDNSs32 SleepLimit; // Time window to allow deregistrations, etc., 2409 // during which underying platform layer should inhibit system sleep 2410 mDNSs32 TimeSlept; // Time we went to sleep. 2411 2412 #if MDNSRESPONDER_SUPPORTS(APPLE, DNSSECv2) 2413 mDNSs32 NextUpdateDNSSECValidatedCache; // Next time to update the cache with DNSSEC-validated records. 2414 #endif 2415 2416 #if MDNSRESPONDER_SUPPORTS(APPLE, RUNTIME_MDNS_METRICS) 2417 mDNSs32 NextMDNSResponseDelayReport; // Next time to generate a mDNS response delay report. 2418 #endif 2419 2420 mDNSs32 UnicastPacketsSent; // Number of unicast packets sent. 2421 mDNSs32 MulticastPacketsSent; // Number of multicast packets sent. 2422 mDNSs32 RemoteSubnet; // Multicast packets received from outside our subnet. 2423 2424 mDNSs32 NextScheduledSPRetry; // Time next sleep proxy registration action is required. 2425 // Only valid if SleepLimit is nonzero and DelaySleep is zero. 2426 2427 mDNSs32 NextScheduledStopTime; // Next time to stop a question 2428 2429 mDNSs32 NextBLEServiceTime; // Next time to call the BLE discovery management layer. Non zero when active. 2430 2431 // These fields only required for mDNS Searcher... 2432 DNSQuestion *Questions; // List of all registered questions, active and inactive 2433 DNSQuestion *NewQuestions; // Fresh questions not yet answered from cache 2434 DNSQuestion *CurrentQuestion; // Next question about to be examined in AnswerLocalQuestions() 2435 DNSQuestion *LocalOnlyQuestions; // Questions with InterfaceID set to mDNSInterface_LocalOnly or mDNSInterface_P2P 2436 DNSQuestion *NewLocalOnlyQuestions; // Fresh local-only or P2P questions not yet answered 2437 DNSQuestion *RestartQuestion; // Questions that are being restarted (stop followed by start) 2438 mDNSu32 rrcache_size; // Total number of available cache entries 2439 mDNSu32 rrcache_totalused; // Number of cache entries currently occupied 2440 mDNSu32 rrcache_totalused_unicast; // Number of cache entries currently occupied by unicast 2441 mDNSu32 rrcache_active; // Number of cache entries currently occupied by records that answer active questions 2442 mDNSu32 rrcache_report; 2443 CacheEntity *rrcache_free; 2444 CacheGroup *rrcache_hash[CACHE_HASH_SLOTS]; 2445 mDNSs32 rrcache_nextcheck[CACHE_HASH_SLOTS]; 2446 2447 AuthHash rrauth; 2448 2449 // Fields below only required for mDNS Responder... 2450 domainlabel nicelabel; // Rich text label encoded using canonically precomposed UTF-8 2451 domainlabel hostlabel; // Conforms to RFC 1034 "letter-digit-hyphen" ARPANET host name rules 2452 domainname MulticastHostname; // Fully Qualified "dot-local" Host Name, e.g. "Foo.local." 2453 #if MDNSRESPONDER_SUPPORTS(APPLE, RANDOM_AWDL_HOSTNAME) 2454 domainname RandomizedHostname; // Randomized hostname to use for services involving AWDL interfaces. This is to 2455 // avoid using a hostname derived from the device's name, which may contain the 2456 // owner's real name, (e.g., "Steve's iPhone" -> "Steves-iPhone.local"), which is a 2457 // privacy concern. 2458 mDNSu32 AutoTargetAWDLIncludedCount;// Number of registered AWDL-included auto-target records. 2459 mDNSu32 AutoTargetAWDLOnlyCount; // Number of registered AWDL-only auto-target records. 2460 #endif 2461 UTF8str255 HIHardware; 2462 UTF8str255 HISoftware; 2463 AuthRecord DeviceInfo; 2464 AuthRecord *ResourceRecords; 2465 AuthRecord *DuplicateRecords; // Records currently 'on hold' because they are duplicates of existing records 2466 AuthRecord *NewLocalRecords; // Fresh AuthRecords (public) not yet delivered to our local-only questions 2467 AuthRecord *CurrentRecord; // Next AuthRecord about to be examined 2468 mDNSBool NewLocalOnlyRecords; // Fresh AuthRecords (local only) not yet delivered to our local questions 2469 NetworkInterfaceInfo *HostInterfaces; 2470 mDNSs32 ProbeFailTime; 2471 mDNSu32 NumFailedProbes; 2472 mDNSs32 SuppressProbes; 2473 mDNSu8 mDNS_plat; // Why is this here in the only required for mDNS Responder section? -- SC 2474 2475 // Unicast-specific data 2476 mDNSs32 NextuDNSEvent; // uDNS next event 2477 mDNSs32 NextSRVUpdate; // Time to perform delayed update 2478 2479 #if !MDNSRESPONDER_SUPPORTS(APPLE, QUERIER) 2480 DNSServer *DNSServers; // list of DNS servers 2481 #endif 2482 McastResolver *McastResolvers; // list of Mcast Resolvers 2483 2484 mDNSAddr Router; 2485 mDNSAddr AdvertisedV4; // IPv4 address pointed to by hostname 2486 mDNSAddr AdvertisedV6; // IPv6 address pointed to by hostname 2487 2488 DomainAuthInfo *AuthInfoList; // list of domains requiring authentication for updates 2489 2490 DNSQuestion ReverseMap; // Reverse-map query to find static hostname for service target 2491 2492 DNSQuestion AutomaticBrowseDomainQ_Internal; // The internal DNS question started to manage all automatic browse domain events from different sources. 2493 2494 DomainEnumerationOp *domainsToDoEnumeration; // The list of domain(s) that possibly need(s) to do the domain enumeration. 2495 2496 domainname StaticHostname; // Current answer to reverse-map query 2497 domainname FQDN; 2498 HostnameInfo *Hostnames; // List of registered hostnames + hostname metadata 2499 2500 mDNSu32 WABBrowseQueriesCount; // Number of WAB Browse domain enumeration queries (b, db) callers 2501 mDNSu32 WABLBrowseQueriesCount; // Number of legacy WAB Browse domain enumeration queries (lb) callers 2502 mDNSu32 WABRegQueriesCount; // Number of WAB Registration domain enumeration queries (r, dr) callers 2503 mDNSu8 SearchDomainsHash[MD5_LEN]; 2504 2505 // NAT-Traversal fields 2506 #if MDNSRESPONDER_SUPPORTS(COMMON, DNS_LLQ) 2507 NATTraversalInfo LLQNAT; // Single shared NAT Traversal to receive inbound LLQ notifications 2508 #endif 2509 NATTraversalInfo *NATTraversals; 2510 NATTraversalInfo *CurrentNATTraversal; 2511 mDNSs32 retryIntervalGetAddr; // delta between time sent and retry for NAT-PMP & UPnP/IGD external address request 2512 mDNSs32 retryGetAddr; // absolute time when we retry for NAT-PMP & UPnP/IGD external address request 2513 mDNSv4Addr ExtAddress; // the external address discovered via NAT-PMP or UPnP/IGD 2514 mDNSu32 PCPNonce[3]; // the nonce if using PCP 2515 2516 UDPSocket *NATMcastRecvskt; // For receiving PCP & NAT-PMP announcement multicasts from router on port 5350 2517 mDNSu32 LastNATupseconds; // NAT engine uptime in seconds, from most recent NAT packet 2518 mDNSs32 LastNATReplyLocalTime; // Local time in ticks when most recent NAT packet was received 2519 mDNSu16 LastNATMapResultCode; // Most recent error code for mappings 2520 2521 tcpLNTInfo tcpAddrInfo; // legacy NAT traversal TCP connection info for external address 2522 tcpLNTInfo tcpDeviceInfo; // legacy NAT traversal TCP connection info for device info 2523 tcpLNTInfo *tcpInfoUnmapList; // list of pending unmap requests 2524 mDNSInterfaceID UPnPInterfaceID; 2525 UDPSocket *SSDPSocket; // For SSDP request/response 2526 mDNSBool SSDPWANPPPConnection; // whether we should send the SSDP query for WANIPConnection or WANPPPConnection 2527 mDNSIPPort UPnPRouterPort; // port we send discovery messages to 2528 mDNSIPPort UPnPSOAPPort; // port we send SOAP messages to 2529 char *UPnPRouterURL; // router's URL string 2530 mDNSBool UPnPWANPPPConnection; // whether we're using WANIPConnection or WANPPPConnection 2531 char *UPnPSOAPURL; // router's SOAP control URL string 2532 char *UPnPRouterAddressString; // holds both the router's address and port 2533 char *UPnPSOAPAddressString; // holds both address and port for SOAP messages 2534 2535 // DNS Push fields 2536 DNSPushServer *DNSPushServers; 2537 DNSPushZone *DNSPushZones; 2538 2539 // Sleep Proxy client fields 2540 AuthRecord *SPSRRSet; // To help the client keep track of the records registered with the sleep proxy 2541 2542 // Sleep Proxy Server fields 2543 mDNSu8 SPSType; // 0 = off, 10-99 encodes desirability metric 2544 mDNSu8 SPSPortability; // 10-99 2545 mDNSu8 SPSMarginalPower; // 10-99 2546 mDNSu8 SPSTotalPower; // 10-99 2547 mDNSu8 SPSFeatureFlags; // Features supported. Currently 1 = TCP KeepAlive supported. 2548 mDNSu8 SPSState; // 0 = off, 1 = running, 2 = shutting down, 3 = suspended during sleep 2549 mDNSInterfaceID SPSProxyListChanged; 2550 UDPSocket *SPSSocket; 2551 #ifndef SPC_DISABLED 2552 ServiceRecordSet SPSRecords; 2553 #endif 2554 #if MDNSRESPONDER_SUPPORTS(COMMON, SPS_CLIENT) 2555 mDNSQuestionCallback *SPSBrowseCallback; // So the platform layer can do something useful with SPS browse results 2556 #endif 2557 int ProxyRecords; // Total number of records we're holding as proxy 2558 #define MAX_PROXY_RECORDS 10000 /* DOS protection: 400 machines at 25 records each */ 2559 2560 #if MDNSRESPONDER_SUPPORTS(APPLE, WEB_CONTENT_FILTER) 2561 WCFConnection *WCF; 2562 #endif 2563 int notifyToken; 2564 int uds_listener_skt; // Listening socket for incoming UDS clients. This should not be here -- it's private to uds_daemon.c and nothing to do with mDNSCore -- SC 2565 mDNSu32 AutoTargetServices; // # of services that have AutoTarget set 2566 2567 #if MDNSRESPONDER_SUPPORTS(APPLE, BONJOUR_ON_DEMAND) 2568 // Counters used in Bonjour on Demand logic. 2569 mDNSu32 NumAllInterfaceRecords; // Right now we count *all* multicast records here. Later we may want to change to count interface-specific records separately. (This count includes records on the DuplicateRecords list too.) 2570 mDNSu32 NumAllInterfaceQuestions; // Right now we count *all* multicast questions here. Later we may want to change to count interface-specific questions separately. 2571 #endif 2572 2573 mDNSStatistics mDNSStats; 2574 2575 #if MDNSRESPONDER_SUPPORTS(APPLE, DNSSECv2) 2576 dnssec_obj_trust_anchor_manager_t DNSSECTrustAnchorManager; // The trust anchor manager manages all the useful anchors for DNSSEC. 2577 #endif 2578 2579 // Fixed storage, to avoid creating large objects on the stack 2580 // The imsg is declared as a union with a pointer type to enforce CPU-appropriate alignment 2581 union { DNSMessage m; void *p; } imsg; // Incoming message received from wire 2582 DNSMessage omsg; // Outgoing message we're building 2583 LargeCacheRecord rec; // Resource Record extracted from received message 2584 2585 #ifndef MaxMsg 2586 #define MaxMsg 512 2587 #endif 2588 mDNSu8 RDataBuffer[MaxMsg]; // Temp storage used to construct rrtype + rdata bytes for logging. 2589 char MsgBuffer[MaxMsg]; // Temp storage used while building error log messages (keep at end of struct) 2590 }; 2591 2592 #define FORALL_CACHEGROUPS(SLOT,CG) \ 2593 for ((SLOT) = 0; (SLOT) < CACHE_HASH_SLOTS; (SLOT)++) \ 2594 for ((CG)=m->rrcache_hash[(SLOT)]; (CG); (CG)=(CG)->next) 2595 2596 #define FORALL_CACHERECORDS(SLOT,CG,CR) \ 2597 FORALL_CACHEGROUPS(SLOT,CG) \ 2598 for ((CR) = (CG)->members; (CR); (CR)=(CR)->next) 2599 2600 // *************************************************************************** 2601 #if 0 2602 #pragma mark - 2603 #pragma mark - Useful Static Constants 2604 #endif 2605 2606 extern const mDNSInterfaceID mDNSInterface_Any; // Zero 2607 extern const mDNSInterfaceID mDNSInterface_LocalOnly; // Special value 2608 extern const mDNSInterfaceID mDNSInterfaceMark; // Special value 2609 extern const mDNSInterfaceID mDNSInterface_P2P; // Special value 2610 extern const mDNSInterfaceID uDNSInterfaceMark; // Special value 2611 extern const mDNSInterfaceID mDNSInterface_BLE; // Special value 2612 2613 #define LocalOnlyOrP2PInterface(INTERFACE) (((INTERFACE) == mDNSInterface_LocalOnly) || ((INTERFACE) == mDNSInterface_P2P) || ((INTERFACE) == mDNSInterface_BLE)) 2614 2615 extern const mDNSIPPort DiscardPort; 2616 extern const mDNSIPPort SSHPort; 2617 extern const mDNSIPPort UnicastDNSPort; 2618 extern const mDNSIPPort SSDPPort; 2619 extern const mDNSIPPort IPSECPort; 2620 extern const mDNSIPPort NSIPCPort; 2621 extern const mDNSIPPort NATPMPAnnouncementPort; 2622 extern const mDNSIPPort NATPMPPort; 2623 extern const mDNSIPPort DNSEXTPort; 2624 extern const mDNSIPPort MulticastDNSPort; 2625 extern const mDNSIPPort LoopbackIPCPort; 2626 extern const mDNSIPPort PrivateDNSPort; 2627 2628 extern const OwnerOptData zeroOwner; 2629 2630 extern const mDNSIPPort zeroIPPort; 2631 extern const mDNSv4Addr zerov4Addr; 2632 extern const mDNSv6Addr zerov6Addr; 2633 extern const mDNSEthAddr zeroEthAddr; 2634 extern const mDNSv4Addr onesIPv4Addr; 2635 extern const mDNSv6Addr onesIPv6Addr; 2636 extern const mDNSEthAddr onesEthAddr; 2637 extern const mDNSAddr zeroAddr; 2638 2639 extern const mDNSv4Addr AllDNSAdminGroup; 2640 extern const mDNSv4Addr AllHosts_v4; 2641 extern const mDNSv6Addr AllHosts_v6; 2642 extern const mDNSv6Addr NDP_prefix; 2643 extern const mDNSEthAddr AllHosts_v6_Eth; 2644 extern const mDNSAddr AllDNSLinkGroup_v4; 2645 extern const mDNSAddr AllDNSLinkGroup_v6; 2646 2647 extern const mDNSOpaque16 zeroID; 2648 extern const mDNSOpaque16 onesID; 2649 extern const mDNSOpaque16 QueryFlags; 2650 extern const mDNSOpaque16 uQueryFlags; 2651 extern const mDNSOpaque16 ResponseFlags; 2652 extern const mDNSOpaque16 UpdateReqFlags; 2653 extern const mDNSOpaque16 UpdateRespFlags; 2654 extern const mDNSOpaque16 SubscribeFlags; 2655 extern const mDNSOpaque16 UnSubscribeFlags; 2656 extern const mDNSOpaque16 uDNSSecQueryFlags; 2657 2658 extern const mDNSOpaque64 zeroOpaque64; 2659 extern const mDNSOpaque128 zeroOpaque128; 2660 2661 extern mDNSBool StrictUnicastOrdering; 2662 2663 #define localdomain (*(const domainname *)"\x5" "local") 2664 #define DeviceInfoName (*(const domainname *)"\xC" "_device-info" "\x4" "_tcp") 2665 #define LocalDeviceInfoName (*(const domainname *)"\xC" "_device-info" "\x4" "_tcp" "\x5" "local") 2666 #define SleepProxyServiceType (*(const domainname *)"\xC" "_sleep-proxy" "\x4" "_udp") 2667 2668 #if MDNSRESPONDER_SUPPORTS(COMMON, LOCAL_DNS_RESOLVER_DISCOVERY) 2669 // Change `Do53_UNICAST_DISCOVERY_DOMAIN` to a non-root domain to do Do53 service discovery under this domain. 2670 #define Do53_UNICAST_DISCOVERY_DOMAIN ((const domainname *) "") 2671 #endif // MDNSRESPONDER_SUPPORTS(COMMON, LOCAL_DNS_RESOLVER_DISCOVERY) 2672 2673 // *************************************************************************** 2674 #if 0 2675 #pragma mark - 2676 #pragma mark - Inline functions 2677 #endif 2678 2679 #if (defined(_MSC_VER)) 2680 #define mDNSinline static __inline 2681 #elif ((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 9))) || defined(__lint__) 2682 #define mDNSinline static inline 2683 #endif 2684 2685 // If we're not doing inline functions, then this header needs to have the extern declarations 2686 #if !defined(mDNSinline) 2687 #if !MDNSRESPONDER_SUPPORTS(APPLE, QUERIER) 2688 extern int CountOfUnicastDNSServers(mDNS *const m); 2689 #endif 2690 extern mDNSs32 NonZeroTime(mDNSs32 t); 2691 extern mDNSu16 mDNSVal16(mDNSOpaque16 x); 2692 extern mDNSOpaque16 mDNSOpaque16fromIntVal(mDNSu16 v); 2693 #endif 2694 2695 // If we're compiling the particular C file that instantiates our inlines, then we 2696 // define "mDNSinline" (to empty string) so that we generate code in the following section 2697 #if (!defined(mDNSinline) && mDNS_InstantiateInlines) 2698 #define mDNSinline 2699 #endif 2700 2701 #ifdef mDNSinline 2702 2703 #if !MDNSRESPONDER_SUPPORTS(APPLE, QUERIER) 2704 mDNSinline int CountOfUnicastDNSServers(mDNS *const m) 2705 { 2706 int count = 0; 2707 DNSServer *ptr = m->DNSServers; 2708 while(ptr) { if(!(ptr->flags & DNSServerFlag_Delete)) count++; ptr = ptr->next; } 2709 return (count); 2710 } 2711 #endif 2712 2713 mDNSinline mDNSs32 NonZeroTime(mDNSs32 t) { if (t) return(t);else return(1);} 2714 2715 mDNSinline mDNSu16 mDNSVal16(mDNSOpaque16 x) { return((mDNSu16)((mDNSu16)x.b[0] << 8 | (mDNSu16)x.b[1])); } 2716 2717 mDNSinline mDNSOpaque16 mDNSOpaque16fromIntVal(mDNSu16 v) 2718 { 2719 mDNSOpaque16 x; 2720 x.b[0] = (mDNSu8)(v >> 8); 2721 x.b[1] = (mDNSu8)(v & 0xFF); 2722 return(x); 2723 } 2724 2725 mDNSinline mDNSu32 mDNSVal32(mDNSOpaque32 x) 2726 { 2727 return((mDNSu32)((((mDNSu32)x.b[0]) << 24) | (((mDNSu32)x.b[1]) << 16) | (((mDNSu32)x.b[2]) << 8) | (mDNSu32)x.b[3])); 2728 } 2729 2730 #endif 2731 2732 // *************************************************************************** 2733 #if 0 2734 #pragma mark - 2735 #pragma mark - Main Client Functions 2736 #endif 2737 2738 // Every client should call mDNS_Init, passing in storage for the mDNS object and the mDNS_PlatformSupport object. 2739 // 2740 // Clients that are only advertising services should use mDNS_Init_NoCache and mDNS_Init_ZeroCacheSize. 2741 // Clients that plan to perform queries (mDNS_StartQuery, mDNS_StartBrowse, etc.) 2742 // need to provide storage for the resource record cache, or the query calls will return 'mStatus_NoCache'. 2743 // The rrcachestorage parameter is the address of memory for the resource record cache, and 2744 // the rrcachesize parameter is the number of entries in the CacheRecord array passed in. 2745 // (i.e. the size of the cache memory needs to be sizeof(CacheRecord) * rrcachesize). 2746 // OS X 10.3 Panther uses an initial cache size of 64 entries, and then mDNSCore sends an 2747 // mStatus_GrowCache message if it needs more. 2748 // 2749 // Most clients should use mDNS_Init_AdvertiseLocalAddresses. This causes mDNSCore to automatically 2750 // create the correct address records for all the hosts interfaces. If you plan to advertise 2751 // services being offered by the local machine, this is almost always what you want. 2752 // There are two cases where you might use mDNS_Init_DontAdvertiseLocalAddresses: 2753 // 1. A client-only device, that browses for services but doesn't advertise any of its own. 2754 // 2. A proxy-registration service, that advertises services being offered by other machines, and takes 2755 // the appropriate steps to manually create the correct address records for those other machines. 2756 // In principle, a proxy-like registration service could manually create address records for its own machine too, 2757 // but this would be pointless extra effort when using mDNS_Init_AdvertiseLocalAddresses does that for you. 2758 // 2759 // Note that a client-only device that wishes to prohibit multicast advertisements (e.g. from 2760 // higher-layer API calls) must also set DivertMulticastAdvertisements in the mDNS structure and 2761 // advertise local address(es) on a loopback interface. 2762 // 2763 // When mDNS has finished setting up the client's callback is called 2764 // A client can also spin and poll the mDNSPlatformStatus field to see when it changes from mStatus_Waiting to mStatus_NoError 2765 // 2766 // Call mDNS_StartExit to tidy up before exiting 2767 // Because exiting may be an asynchronous process (e.g. if unicast records need to be deregistered) 2768 // client layer may choose to wait until mDNS_ExitNow() returns true before calling mDNS_FinalExit(). 2769 // 2770 // Call mDNS_Register with a completed AuthRecord object to register a resource record 2771 // If the resource record type is kDNSRecordTypeUnique (or kDNSknownunique) then if a conflicting resource record is discovered, 2772 // the resource record's mDNSRecordCallback will be called with error code mStatus_NameConflict. The callback should deregister 2773 // the record, and may then try registering the record again after picking a new name (e.g. by automatically appending a number). 2774 // Following deregistration, the RecordCallback will be called with result mStatus_MemFree to signal that it is safe to deallocate 2775 // the record's storage (memory must be freed asynchronously to allow for goodbye packets and dynamic update deregistration). 2776 // 2777 // Call mDNS_StartQuery to initiate a query. mDNS will proceed to issue Multicast DNS query packets, and any time a response 2778 // is received containing a record which matches the question, the DNSQuestion's mDNSAnswerCallback function will be called 2779 // Call mDNS_StopQuery when no more answers are required 2780 // 2781 // Care should be taken on multi-threaded or interrupt-driven environments. 2782 // The main mDNS routines call mDNSPlatformLock() on entry and mDNSPlatformUnlock() on exit; 2783 // each platform layer needs to implement these appropriately for its respective platform. 2784 // For example, if the support code on a particular platform implements timer callbacks at interrupt time, then 2785 // mDNSPlatformLock/Unlock need to disable interrupts or do similar concurrency control to ensure that the mDNS 2786 // code is not entered by an interrupt-time timer callback while in the middle of processing a client call. 2787 2788 extern mStatus mDNS_Init (mDNS *const m, mDNS_PlatformSupport *const p, 2789 CacheEntity *rrcachestorage, mDNSu32 rrcachesize, 2790 mDNSBool AdvertiseLocalAddresses, 2791 mDNSCallback *Callback, void *Context); 2792 // See notes above on use of NoCache/ZeroCacheSize 2793 #define mDNS_Init_NoCache mDNSNULL 2794 #define mDNS_Init_ZeroCacheSize 0 2795 // See notes above on use of Advertise/DontAdvertiseLocalAddresses 2796 #define mDNS_Init_AdvertiseLocalAddresses mDNStrue 2797 #define mDNS_Init_DontAdvertiseLocalAddresses mDNSfalse 2798 #define mDNS_Init_NoInitCallback mDNSNULL 2799 #define mDNS_Init_NoInitCallbackContext mDNSNULL 2800 2801 extern void mDNS_ConfigChanged(mDNS *const m); 2802 extern void mDNS_GrowCache (mDNS *const m, CacheEntity *storage, mDNSu32 numrecords); 2803 extern void mDNS_StartExit (mDNS *const m); 2804 extern void mDNS_FinalExit (mDNS *const m); 2805 #define mDNS_Close(m) do { mDNS_StartExit(m); mDNS_FinalExit(m); } while(0) 2806 #define mDNS_ExitNow(m, now) ((now) - (m)->ShutdownTime >= 0 || (!(m)->ResourceRecords)) 2807 2808 extern mDNSs32 mDNS_Execute (mDNS *const m); 2809 2810 extern mStatus mDNS_Register (mDNS *const m, AuthRecord *const rr); 2811 extern mStatus mDNS_Update (mDNS *const m, AuthRecord *const rr, mDNSu32 newttl, 2812 const mDNSu16 newrdlength, RData *const newrdata, mDNSRecordUpdateCallback *Callback); 2813 extern mStatus mDNS_Deregister(mDNS *const m, AuthRecord *const rr); 2814 2815 extern mStatus mDNS_StartQuery(mDNS *const m, DNSQuestion *const question); 2816 extern mStatus mDNS_StopQuery (mDNS *const m, DNSQuestion *const question); 2817 extern mStatus mDNS_StopQueryWithRemoves(mDNS *const m, DNSQuestion *const question); 2818 extern mStatus mDNS_Reconfirm (mDNS *const m, CacheRecord *const cacherr); 2819 extern mStatus mDNS_Reconfirm_internal(mDNS *const m, CacheRecord *const rr, mDNSu32 interval); 2820 extern mStatus mDNS_ReconfirmByValue(mDNS *const m, ResourceRecord *const rr); 2821 extern void mDNS_PurgeCacheResourceRecord(mDNS *const m, CacheRecord *rr); 2822 extern mDNSs32 mDNS_TimeNow(const mDNS *const m); 2823 2824 extern mStatus mDNS_StartNATOperation(mDNS *const m, NATTraversalInfo *traversal); 2825 extern mStatus mDNS_StopNATOperation(mDNS *const m, NATTraversalInfo *traversal); 2826 extern mStatus mDNS_StopNATOperation_internal(mDNS *m, NATTraversalInfo *traversal); 2827 2828 extern DomainAuthInfo *GetAuthInfoForName(mDNS *m, const domainname *const name); 2829 2830 extern void mDNS_UpdateAllowSleep(mDNS *const m); 2831 2832 // *************************************************************************** 2833 #if 0 2834 #pragma mark - 2835 #pragma mark - Platform support functions that are accessible to the client layer too 2836 #endif 2837 2838 extern mDNSs32 mDNSPlatformOneSecond; 2839 2840 // *************************************************************************** 2841 #if 0 2842 #pragma mark - 2843 #pragma mark - General utility and helper functions 2844 #endif 2845 2846 // mDNS_Dereg_normal is used for most calls to mDNS_Deregister_internal 2847 // mDNS_Dereg_rapid is used to send one goodbye instead of three, when we want the memory available for reuse sooner 2848 // mDNS_Dereg_conflict is used to indicate that this record is being forcibly deregistered because of a conflict 2849 // mDNS_Dereg_repeat is used when cleaning up, for records that may have already been forcibly deregistered 2850 // mDNS_Dereg_stale is used when the registered record has been superseded by another host 2851 typedef enum { mDNS_Dereg_normal, mDNS_Dereg_rapid, mDNS_Dereg_conflict, mDNS_Dereg_repeat, mDNS_Dereg_stale } mDNS_Dereg_type; 2852 2853 // mDNS_RegisterService is a single call to register the set of resource records associated with a given named service. 2854 // 2855 // 2856 // mDNS_AddRecordToService adds an additional record to a Service Record Set. This record may be deregistered 2857 // via mDNS_RemoveRecordFromService, or by deregistering the service. mDNS_RemoveRecordFromService is passed a 2858 // callback to free the memory associated with the extra RR when it is safe to do so. The ExtraResourceRecord 2859 // object can be found in the record's context pointer. 2860 2861 // mDNS_GetBrowseDomains is a special case of the mDNS_StartQuery call, where the resulting answers 2862 // are a list of PTR records indicating (in the rdata) domains that are recommended for browsing. 2863 // After getting the list of domains to browse, call mDNS_StopQuery to end the search. 2864 // mDNS_GetDefaultBrowseDomain returns the name of the domain that should be highlighted by default. 2865 // 2866 // mDNS_GetRegistrationDomains and mDNS_GetDefaultRegistrationDomain are the equivalent calls to get the list 2867 // of one or more domains that should be offered to the user as choices for where they may register their service, 2868 // and the default domain in which to register in the case where the user has made no selection. 2869 2870 extern void mDNS_SetupResourceRecord(AuthRecord *rr, RData *RDataStorage, mDNSInterfaceID InterfaceID, 2871 mDNSu16 rrtype, mDNSu32 ttl, mDNSu8 RecordType, AuthRecType artype, mDNSRecordCallback Callback, void *Context); 2872 2873 extern mStatus mDNS_RegisterService (mDNS *const m, ServiceRecordSet *sr, 2874 const domainlabel *const name, const domainname *const type, const domainname *const domain, 2875 const domainname *const host, mDNSIPPort port, RData *txtrdata, const mDNSu8 txtinfo[], mDNSu16 txtlen, 2876 AuthRecord *SubTypes, mDNSu32 NumSubTypes, 2877 mDNSInterfaceID InterfaceID, mDNSServiceCallback Callback, void *Context, mDNSu32 flags); 2878 extern mStatus mDNS_AddRecordToService(mDNS *const m, ServiceRecordSet *sr, ExtraResourceRecord *extra, RData *rdata, mDNSu32 ttl, mDNSu32 flags); 2879 extern mStatus mDNS_RemoveRecordFromService(mDNS *const m, ServiceRecordSet *sr, ExtraResourceRecord *extra, mDNSRecordCallback MemFreeCallback, void *Context); 2880 extern mStatus mDNS_RenameAndReregisterService(mDNS *const m, ServiceRecordSet *const sr, const domainlabel *newname); 2881 extern mStatus mDNS_DeregisterService_drt(mDNS *const m, ServiceRecordSet *sr, mDNS_Dereg_type drt); 2882 #define mDNS_DeregisterService(M,S) mDNS_DeregisterService_drt((M), (S), mDNS_Dereg_normal) 2883 2884 extern mStatus mDNS_RegisterNoSuchService(mDNS *const m, AuthRecord *const rr, 2885 const domainlabel *const name, const domainname *const type, const domainname *const domain, 2886 const domainname *const host, 2887 const mDNSInterfaceID InterfaceID, mDNSRecordCallback Callback, void *Context, mDNSu32 flags); 2888 #define mDNS_DeregisterNoSuchService mDNS_Deregister 2889 2890 extern void mDNS_SetupQuestion(DNSQuestion *const q, const mDNSInterfaceID InterfaceID, const domainname *const name, 2891 const mDNSu16 qtype, mDNSQuestionCallback *const callback, void *const context); 2892 2893 extern mStatus mDNS_StartBrowse(mDNS *const m, DNSQuestion *const question, 2894 const domainname *const srv, const domainname *const domain, 2895 const mDNSInterfaceID InterfaceID, mDNSu32 flags, 2896 mDNSBool ForceMCast, mDNSBool useBackgroundTrafficClass, 2897 mDNSQuestionCallback *Callback, void *Context); 2898 #define mDNS_StopBrowse mDNS_StopQuery 2899 2900 2901 extern const char *const mDNS_DomainTypeNames[]; 2902 2903 extern mStatus mDNS_GetDomains(mDNS *const m, DNSQuestion *const question, mDNS_DomainType DomainType, const domainname *dom, 2904 const mDNSInterfaceID InterfaceID, mDNSQuestionCallback *Callback, void *Context); 2905 #define mDNS_StopGetDomains mDNS_StopQuery 2906 #define mDNS_StopGetDomains_Internal mDNS_StopQuery_internal 2907 extern mStatus mDNS_AdvertiseDomains(mDNS *const m, AuthRecord *rr, mDNS_DomainType DomainType, const mDNSInterfaceID InterfaceID, char *domname); 2908 #define mDNS_StopAdvertiseDomains mDNS_Deregister 2909 2910 // Function that is used to do domain enumeration. 2911 extern mStatus mDNS_StartDomainEnumeration(mDNS *m, const domainname *domain, mDNS_DomainType type); 2912 extern mStatus mDNS_StopDomainEnumeration(mDNS *m, const domainname *domain, mDNS_DomainType type); 2913 extern mStatus mDNS_AddDomainDiscoveredForDomainEnumeration(mDNS *m, const domainname *domain, mDNS_DomainType type, 2914 const domainname *domainDiscovered); 2915 extern mStatus mDNS_RemoveDomainDiscoveredForDomainEnumeration(mDNS *m, const domainname *domain, mDNS_DomainType type, 2916 const domainname *domainDiscovered); 2917 extern void FoundNonLocalOnlyAutomaticBrowseDomain(mDNS *m, DNSQuestion *q, const ResourceRecord *answer, QC_result add_record); 2918 extern void DeregisterLocalOnlyDomainEnumPTR_Internal(mDNS *m, const domainname *d, int type, mDNSBool lockHeld); 2919 2920 extern mDNSOpaque16 mDNS_NewMessageID(mDNS *const m); 2921 extern mDNSBool mDNS_AddressIsLocalSubnet(mDNS *const m, const mDNSInterfaceID InterfaceID, const mDNSAddr *addr); 2922 2923 #if !MDNSRESPONDER_SUPPORTS(APPLE, QUERIER) 2924 extern DNSServer *GetServerForQuestion(mDNS *m, DNSQuestion *question); 2925 #endif 2926 extern mDNSu32 SetValidDNSServers(mDNS *m, DNSQuestion *question); 2927 #if MDNSRESPONDER_SUPPORTS(APPLE, QUERIER) 2928 extern mDNSBool ShouldSuppressUnicastQuery(const DNSQuestion *q, mdns_dns_service_t dnsservice); 2929 extern mDNSBool LocalRecordRmvEventsForQuestion(mDNS *m, DNSQuestion *q); 2930 #endif 2931 2932 // *************************************************************************** 2933 #if 0 2934 #pragma mark - 2935 #pragma mark - DNS name utility functions 2936 #endif 2937 2938 // In order to expose the full capabilities of the DNS protocol (which allows any arbitrary eight-bit values 2939 // in domain name labels, including unlikely characters like ascii nulls and even dots) all the mDNS APIs 2940 // work with DNS's native length-prefixed strings. For convenience in C, the following utility functions 2941 // are provided for converting between C's null-terminated strings and DNS's length-prefixed strings. 2942 2943 // Assignment 2944 // A simple C structure assignment of a domainname can cause a protection fault by accessing unmapped memory, 2945 // because that object is defined to be 256 bytes long, but not all domainname objects are truly the full size. 2946 // This macro uses mDNSPlatformMemCopy() to make sure it only touches the actual bytes that are valid. 2947 #define AssignDomainName(DST, SRC) do { mDNSu16 len__ = DomainNameLength((SRC)); \ 2948 if (len__ <= MAX_DOMAIN_NAME) mDNSPlatformMemCopy((DST)->c, (SRC)->c, len__); else (DST)->c[0] = 0; } while(0) 2949 #define AssignConstStringDomainName(DST, SRC) do { \ 2950 mDNSu16 len__ = DomainNameLengthLimit((domainname *)(SRC), (mDNSu8 *)(SRC) + sizeof (SRC)); \ 2951 if (len__ <= MAX_DOMAIN_NAME) \ 2952 mDNSPlatformMemCopy((DST)->c, (SRC), len__); else (DST)->c[0] = 0; } while(0) 2953 2954 // Comparison functions 2955 #define SameDomainLabelCS(A,B) ((A)[0] == (B)[0] && mDNSPlatformMemSame((A)+1, (B)+1, (A)[0])) 2956 extern mDNSBool SameDomainLabel(const mDNSu8 *a, const mDNSu8 *b); 2957 extern mDNSBool SameDomainName(const domainname *const d1, const domainname *const d2); 2958 extern mDNSBool SameDomainNameBytes(const mDNSu8 *d1, const mDNSu8 *d2); 2959 extern mDNSBool SameDomainNameCS(const domainname *const d1, const domainname *const d2); 2960 typedef mDNSBool DomainNameComparisonFn (const domainname *const d1, const domainname *const d2); 2961 extern mDNSBool IsLocalDomain(const domainname *d); // returns true for domains that by default should be looked up using link-local multicast 2962 extern mDNSBool SameResourceRecordNameClassInterface(const AuthRecord *r1, const AuthRecord *r2); 2963 2964 #define StripFirstLabel(X) ((const domainname *)& (X)->c[(X)->c[0] ? 1 + (X)->c[0] : 0]) 2965 2966 #define FirstLabel(X) ((const domainlabel *)(X)) 2967 #define SecondLabel(X) ((const domainlabel *)StripFirstLabel(X)) 2968 #define ThirdLabel(X) ((const domainlabel *)StripFirstLabel(StripFirstLabel(X))) 2969 2970 extern mDNSBool IsRootDomain(const domainname *d); 2971 extern const mDNSu8 *LastLabel(const domainname *d); 2972 2973 // Get total length of domain name, in native DNS format, including terminal root label 2974 // (e.g. length of "com." is 5 (length byte, three data bytes, final zero) 2975 extern mDNSu16 DomainNameLengthLimit(const domainname *const name, const mDNSu8 *limit); 2976 #define DomainNameLength(name) DomainNameLengthLimit((name), (name)->c + MAX_DOMAIN_NAME) 2977 extern mDNSu16 DomainNameBytesLength(const mDNSu8 *name, const mDNSu8 *limit); 2978 2979 extern mDNSu8 DomainLabelLength(const domainlabel *const label); 2980 2981 // Append functions to append one or more labels to an existing native format domain name: 2982 // AppendLiteralLabelString adds a single label from a literal C string, with no escape character interpretation. 2983 // AppendDNSNameString adds zero or more labels from a C string using conventional DNS dots-and-escaping interpretation 2984 // AppendDomainLabel adds a single label from a native format domainlabel 2985 // AppendDomainName adds zero or more labels from a native format domainname 2986 extern mDNSu8 *AppendLiteralLabelString(domainname *const name, const char *cstr); 2987 extern mDNSu8 *AppendDNSNameString (domainname *const name, const char *cstr); 2988 extern mDNSu8 *AppendDomainLabel (domainname *const name, const domainlabel *const label); 2989 extern mDNSu8 *AppendDomainName (domainname *const name, const domainname *const append); 2990 2991 // Convert from null-terminated string to native DNS format: 2992 // The DomainLabel form makes a single label from a literal C string, with no escape character interpretation. 2993 // The DomainName form makes native format domain name from a C string using conventional DNS interpretation: 2994 // dots separate labels, and within each label, '\.' represents a literal dot, '\\' represents a literal 2995 // backslash and backslash with three decimal digits (e.g. \000) represents an arbitrary byte value. 2996 extern mDNSBool MakeDomainLabelFromLiteralString(domainlabel *const label, const char *cstr); 2997 extern mDNSu8 *MakeDomainNameFromDNSNameString (domainname *const name, const char *cstr); 2998 2999 // Convert native format domainlabel or domainname back to C string format 3000 // IMPORTANT: 3001 // When using ConvertDomainLabelToCString, the target buffer must be MAX_ESCAPED_DOMAIN_LABEL (254) bytes long 3002 // to guarantee there will be no buffer overrun. It is only safe to use a buffer shorter than this in rare cases 3003 // where the label is known to be constrained somehow (for example, if the label is known to be either "_tcp" or "_udp"). 3004 // Similarly, when using ConvertDomainNameToCString, the target buffer must be MAX_ESCAPED_DOMAIN_NAME (1009) bytes long. 3005 // See definitions of MAX_ESCAPED_DOMAIN_LABEL and MAX_ESCAPED_DOMAIN_NAME for more detailed explanation. 3006 extern char *ConvertDomainLabelToCString_withescape(const domainlabel *const name, char *cstr, char esc); 3007 #define ConvertDomainLabelToCString_unescaped(D,C) ConvertDomainLabelToCString_withescape((D), (C), 0) 3008 #define ConvertDomainLabelToCString(D,C) ConvertDomainLabelToCString_withescape((D), (C), '\\') 3009 extern char *ConvertDomainNameToCString_withescape(const domainname *const name, char *cstr, char esc); 3010 #define ConvertDomainNameToCString_unescaped(D,C) ConvertDomainNameToCString_withescape((D), (C), 0) 3011 #define ConvertDomainNameToCString(D,C) ConvertDomainNameToCString_withescape((D), (C), '\\') 3012 3013 extern void ConvertUTF8PstringToRFC1034HostLabel(const mDNSu8 UTF8Name[], domainlabel *const hostlabel); 3014 3015 #define ValidTransportProtocol(X) ( (X)[0] == 4 && (X)[1] == '_' && \ 3016 ((((X)[2] | 0x20) == 'u' && ((X)[3] | 0x20) == 'd') || (((X)[2] | 0x20) == 't' && ((X)[3] | 0x20) == 'c')) && \ 3017 ((X)[4] | 0x20) == 'p') 3018 3019 extern mDNSu8 *ConstructServiceName(domainname *const fqdn, const domainlabel *name, const domainname *type, const domainname *const domain); 3020 extern mDNSBool DeconstructServiceName(const domainname *const fqdn, domainlabel *const name, domainname *const type, domainname *const domain); 3021 3022 // Note: Some old functions have been replaced by more sensibly-named versions. 3023 // You can uncomment the hash-defines below if you don't want to have to change your source code right away. 3024 // When updating your code, note that (unlike the old versions) *all* the new routines take the target object 3025 // as their first parameter. 3026 //#define ConvertCStringToDomainName(SRC,DST) MakeDomainNameFromDNSNameString((DST),(SRC)) 3027 //#define ConvertCStringToDomainLabel(SRC,DST) MakeDomainLabelFromLiteralString((DST),(SRC)) 3028 //#define AppendStringLabelToName(DST,SRC) AppendLiteralLabelString((DST),(SRC)) 3029 //#define AppendStringNameToName(DST,SRC) AppendDNSNameString((DST),(SRC)) 3030 //#define AppendDomainLabelToName(DST,SRC) AppendDomainLabel((DST),(SRC)) 3031 //#define AppendDomainNameToName(DST,SRC) AppendDomainName((DST),(SRC)) 3032 3033 // *************************************************************************** 3034 #if 0 3035 #pragma mark - 3036 #pragma mark - Other utility functions and macros 3037 #endif 3038 3039 // mDNS_vsnprintf/snprintf return the number of characters written, excluding the final terminating null. 3040 // The output is always null-terminated: for example, if the output turns out to be exactly buflen long, 3041 // then the output will be truncated by one character to allow space for the terminating null. 3042 // Unlike standard C vsnprintf/snprintf, they return the number of characters *actually* written, 3043 // not the number of characters that *would* have been printed were buflen unlimited. 3044 extern mDNSu32 mDNS_vsnprintf(char *sbuffer, mDNSu32 buflen, const char *fmt, va_list arg) IS_A_PRINTF_STYLE_FUNCTION(3,0); 3045 extern mDNSu32 mDNS_snprintf(char *sbuffer, mDNSu32 buflen, const char *fmt, ...) IS_A_PRINTF_STYLE_FUNCTION(3,4); 3046 extern void mDNS_snprintf_add(char **dst, const char *lim, const char *fmt, ...) IS_A_PRINTF_STYLE_FUNCTION(3,4); 3047 extern mDNSu32 NumCacheRecordsForInterfaceID(const mDNS *const m, mDNSInterfaceID id); 3048 extern char *DNSTypeName(mDNSu16 rrtype); 3049 extern const char *mStatusDescription(mStatus error); 3050 extern char *GetRRDisplayString_rdb(const ResourceRecord *const rr, const RDataBody *const rd1, char *const buffer); 3051 #define RRDisplayString(m, rr) GetRRDisplayString_rdb(rr, &(rr)->rdata->u, (m)->MsgBuffer) 3052 #define ARDisplayString(m, rr) GetRRDisplayString_rdb(&(rr)->resrec, &(rr)->resrec.rdata->u, (m)->MsgBuffer) 3053 #define CRDisplayString(m, rr) GetRRDisplayString_rdb(&(rr)->resrec, &(rr)->resrec.rdata->u, (m)->MsgBuffer) 3054 #if MDNSRESPONDER_SUPPORTS(APPLE, OS_LOG) 3055 extern const mDNSu8 *GetPrintableRDataBytes(mDNSu8 *outBuffer, mDNSu32 bufferLen, mDNSu16 recordType, 3056 const mDNSu8 *rdata, mDNSu32 rdataLen); 3057 #endif 3058 #define MortalityDisplayString(M) (M == Mortality_Mortal ? "mortal" : (M == Mortality_Immortal ? "immortal" : "ghost")) 3059 extern mDNSBool mDNSSameAddress(const mDNSAddr *ip1, const mDNSAddr *ip2); 3060 extern void IncrementLabelSuffix(domainlabel *name, mDNSBool RichText); 3061 extern mDNSBool mDNSv4AddrIsRFC1918(const mDNSv4Addr * const addr); // returns true for RFC1918 private addresses 3062 #define mDNSAddrIsRFC1918(X) ((X)->type == mDNSAddrType_IPv4 && mDNSv4AddrIsRFC1918(&(X)->ip.v4)) 3063 extern const char *DNSScopeToString(mDNSu32 scope); 3064 3065 // For PCP 3066 extern void mDNSAddrMapIPv4toIPv6(mDNSv4Addr* in, mDNSv6Addr* out); 3067 extern mDNSBool mDNSAddrIPv4FromMappedIPv6(mDNSv6Addr *in, mDNSv4Addr *out); 3068 3069 #define mDNSSameIPPort(A,B) ((A).NotAnInteger == (B).NotAnInteger) 3070 #define mDNSSameOpaque16(A,B) ((A).NotAnInteger == (B).NotAnInteger) 3071 #define mDNSSameOpaque32(A,B) ((A).NotAnInteger == (B).NotAnInteger) 3072 #define mDNSSameOpaque64(A,B) ((A)->l[0] == (B)->l[0] && (A)->l[1] == (B)->l[1]) 3073 3074 #define mDNSSameIPv4Address(A,B) ((A).NotAnInteger == (B).NotAnInteger) 3075 #define mDNSSameIPv6Address(A,B) ((A).l[0] == (B).l[0] && (A).l[1] == (B).l[1] && (A).l[2] == (B).l[2] && (A).l[3] == (B).l[3]) 3076 #define mDNSSameIPv6NetworkPart(A,B) ((A).l[0] == (B).l[0] && (A).l[1] == (B).l[1]) 3077 #define mDNSSameEthAddress(A,B) ((A)->w[0] == (B)->w[0] && (A)->w[1] == (B)->w[1] && (A)->w[2] == (B)->w[2]) 3078 3079 #define mDNSIPPortIsZero(A) ((A).NotAnInteger == 0) 3080 #define mDNSOpaque16IsZero(A) ((A).NotAnInteger == 0) 3081 #define mDNSOpaque64IsZero(A) (((A)->l[0] | (A)->l[1] ) == 0) 3082 #define mDNSOpaque128IsZero(A) (((A)->l[0] | (A)->l[1] | (A)->l[2] | (A)->l[3]) == 0) 3083 #define mDNSIPv4AddressIsZero(A) ((A).NotAnInteger == 0) 3084 #define mDNSIPv6AddressIsZero(A) (((A).l[0] | (A).l[1] | (A).l[2] | (A).l[3]) == 0) 3085 #define mDNSEthAddressIsZero(A) (((A).w[0] | (A).w[1] | (A).w[2] ) == 0) 3086 3087 #define mDNSIPv4AddressIsOnes(A) ((A).NotAnInteger == 0xFFFFFFFF) 3088 #define mDNSIPv6AddressIsOnes(A) (((A).l[0] & (A).l[1] & (A).l[2] & (A).l[3]) == 0xFFFFFFFF) 3089 3090 #define mDNSAddressIsAllDNSLinkGroup(X) ( \ 3091 ((X)->type == mDNSAddrType_IPv4 && mDNSSameIPv4Address((X)->ip.v4, AllDNSLinkGroup_v4.ip.v4)) || \ 3092 ((X)->type == mDNSAddrType_IPv6 && mDNSSameIPv6Address((X)->ip.v6, AllDNSLinkGroup_v6.ip.v6)) ) 3093 3094 #define mDNSAddressIsZero(X) ( \ 3095 ((X)->type == mDNSAddrType_IPv4 && mDNSIPv4AddressIsZero((X)->ip.v4)) || \ 3096 ((X)->type == mDNSAddrType_IPv6 && mDNSIPv6AddressIsZero((X)->ip.v6)) ) 3097 3098 #define mDNSAddressIsValidNonZero(X) ( \ 3099 ((X)->type == mDNSAddrType_IPv4 && !mDNSIPv4AddressIsZero((X)->ip.v4)) || \ 3100 ((X)->type == mDNSAddrType_IPv6 && !mDNSIPv6AddressIsZero((X)->ip.v6)) ) 3101 3102 #define mDNSAddressIsOnes(X) ( \ 3103 ((X)->type == mDNSAddrType_IPv4 && mDNSIPv4AddressIsOnes((X)->ip.v4)) || \ 3104 ((X)->type == mDNSAddrType_IPv6 && mDNSIPv6AddressIsOnes((X)->ip.v6)) ) 3105 3106 #define mDNSAddressIsValid(X) ( \ 3107 ((X)->type == mDNSAddrType_IPv4) ? !(mDNSIPv4AddressIsZero((X)->ip.v4) || mDNSIPv4AddressIsOnes((X)->ip.v4)) : \ 3108 ((X)->type == mDNSAddrType_IPv6) ? !(mDNSIPv6AddressIsZero((X)->ip.v6) || mDNSIPv6AddressIsOnes((X)->ip.v6)) : mDNSfalse) 3109 3110 #define mDNSv4AddressIsLinkLocal(X) ((X)->b[0] == 169 && (X)->b[1] == 254) 3111 #define mDNSv6AddressIsLinkLocal(X) ((X)->b[0] == 0xFE && ((X)->b[1] & 0xC0) == 0x80) 3112 3113 #define mDNSAddressIsLinkLocal(X) ( \ 3114 ((X)->type == mDNSAddrType_IPv4) ? mDNSv4AddressIsLinkLocal(&(X)->ip.v4) : \ 3115 ((X)->type == mDNSAddrType_IPv6) ? mDNSv6AddressIsLinkLocal(&(X)->ip.v6) : mDNSfalse) 3116 3117 3118 // *************************************************************************** 3119 #if 0 3120 #pragma mark - 3121 #pragma mark - Authentication Support 3122 #endif 3123 3124 // Unicast DNS and Dynamic Update specific Client Calls 3125 // 3126 // mDNS_SetSecretForDomain tells the core to authenticate (via TSIG with an HMAC_MD5 hash of the shared secret) 3127 // when dynamically updating a given zone (and its subdomains). The key used in authentication must be in 3128 // domain name format. The shared secret must be a null-terminated base64 encoded string. A minimum size of 3129 // 16 bytes (128 bits) is recommended for an MD5 hash as per RFC 2485. 3130 // Calling this routine multiple times for a zone replaces previously entered values. Call with a NULL key 3131 // to disable authentication for the zone. A non-NULL autoTunnelPrefix means this is an AutoTunnel domain, 3132 // and the value is prepended to the IPSec identifier (used for key lookup) 3133 3134 extern mStatus mDNS_SetSecretForDomain(mDNS *m, DomainAuthInfo *info, 3135 const domainname *domain, const domainname *keyname, const char *b64keydata, const domainname *hostname, mDNSIPPort *port); 3136 3137 extern void RecreateNATMappings(mDNS *const m, const mDNSu32 waitTicks); 3138 3139 // Hostname/Unicast Interface Configuration 3140 3141 // All hostnames advertised point to one IPv4 address and/or one IPv6 address, set via SetPrimaryInterfaceInfo. Invoking this routine 3142 // updates all existing hostnames to point to the new address. 3143 3144 // A hostname is added via AddDynDNSHostName, which points to the primary interface's v4 and/or v6 addresss 3145 3146 // The status callback is invoked to convey success or failure codes - the callback should not modify the AuthRecord or free memory. 3147 // Added hostnames may be removed (deregistered) via mDNS_RemoveDynDNSHostName. 3148 3149 // Host domains added prior to specification of the primary interface address and computer name will be deferred until 3150 // these values are initialized. 3151 3152 // DNS servers used to resolve unicast queries are specified by mDNS_AddDNSServer. 3153 // For "split" DNS configurations, in which queries for different domains are sent to different servers (e.g. VPN and external), 3154 // a domain may be associated with a DNS server. For standard configurations, specify the root label (".") or NULL. 3155 3156 extern void mDNS_AddDynDNSHostName(mDNS *m, const domainname *fqdn, mDNSRecordCallback *StatusCallback, const void *StatusContext); 3157 extern void mDNS_RemoveDynDNSHostName(mDNS *m, const domainname *fqdn); 3158 extern void mDNS_SetPrimaryInterfaceInfo(mDNS *m, const mDNSAddr *v4addr, const mDNSAddr *v6addr, const mDNSAddr *router); 3159 #if !MDNSRESPONDER_SUPPORTS(APPLE, QUERIER) 3160 extern DNSServer *mDNS_AddDNSServer(mDNS *const m, const domainname *d, const mDNSInterfaceID interface, mDNSs32 serviceID, const mDNSAddr *addr, 3161 const mDNSIPPort port, ScopeType scopeType, mDNSu32 timeout, mDNSBool cellIntf, mDNSBool isExpensive, mDNSBool isConstrained, mDNSBool isCLAT46, 3162 mDNSu32 resGroupID, mDNSBool reqA, mDNSBool reqAAAA, mDNSBool reqDO); 3163 extern void PenalizeDNSServer(mDNS *const m, DNSQuestion *q, mDNSOpaque16 responseFlags); 3164 #endif 3165 extern void mDNS_AddSearchDomain(const domainname *const domain, mDNSInterfaceID InterfaceID); 3166 3167 extern McastResolver *mDNS_AddMcastResolver(mDNS *const m, const domainname *d, const mDNSInterfaceID interface, mDNSu32 timeout); 3168 3169 // We use ((void *)0) here instead of mDNSNULL to avoid compile warnings on gcc 4.2 3170 #define mDNS_AddSearchDomain_CString(X, I) \ 3171 do { domainname d__; if (((X) != (void*)0) && MakeDomainNameFromDNSNameString(&d__, (X)) && d__.c[0]) mDNS_AddSearchDomain(&d__, I);} while(0) 3172 3173 // Routines called by the core, exported by DNSDigest.c 3174 3175 // Convert an arbitrary base64 encoded key key into an HMAC key (stored in AuthInfo struct) 3176 extern mDNSs32 DNSDigest_ConstructHMACKeyfromBase64(DomainAuthInfo *info, const char *b64key); 3177 3178 // sign a DNS message. The message must be complete, with all values in network byte order. end points to the end 3179 // of the message, and is modified by this routine. numAdditionals is a pointer to the number of additional 3180 // records in HOST byte order, which is incremented upon successful completion of this routine. The function returns 3181 // the new end pointer on success, and NULL on failure. 3182 extern void DNSDigest_SignMessage(DNSMessage *msg, mDNSu8 **end, DomainAuthInfo *info, mDNSu16 tcode); 3183 3184 static inline void SwapDNSHeaderBytesWithHeader(DNSMessageHeader *const hdr) 3185 { 3186 const mDNSu8 *const questions = ((const mDNSu8 *)&hdr->numQuestions); 3187 const mDNSu8 *const answers = ((const mDNSu8 *)&hdr->numAnswers); 3188 const mDNSu8 *const authorities = ((const mDNSu8 *)&hdr->numAuthorities); 3189 const mDNSu8 *const additionals = ((const mDNSu8 *)&hdr->numAdditionals); 3190 3191 hdr->numQuestions = (mDNSu16) ((mDNSu16)questions[0] << 8 | questions[1]); 3192 hdr->numAnswers = (mDNSu16) ((mDNSu16)answers[0] << 8 | answers[1]); 3193 hdr->numAuthorities = (mDNSu16) ((mDNSu16)authorities[0] << 8 | authorities[1]); 3194 hdr->numAdditionals = (mDNSu16) ((mDNSu16)additionals[0] << 8 | additionals[1]); 3195 } 3196 3197 static inline void SwapDNSHeaderBytes(DNSMessage *const msg) 3198 { 3199 SwapDNSHeaderBytesWithHeader(&msg->h); 3200 } 3201 3202 // verify a DNS message. The message must be complete, with all values in network byte order. end points to the 3203 // end of the record. tsig is a pointer to the resource record that contains the TSIG OPT record. info is 3204 // the matching key to use for verifying the message. This function expects that the additionals member 3205 // of the DNS message header has already had one subtracted from it. 3206 extern mDNSBool DNSDigest_VerifyMessage(const DNSMessage *msg, const mDNSu8 *end, const LargeCacheRecord *tsig, 3207 const DomainAuthInfo *info, mDNSu16 *rcode, mDNSu16 *tcode); 3208 3209 #if defined(DEBUG) && DEBUG 3210 extern void DNSDigest_VerifyMessage_Verify(DNSMessage *msg, const mDNSu8 *end, const DomainAuthInfo *authInfo); 3211 #endif 3212 3213 // *************************************************************************** 3214 #if 0 3215 #pragma mark - 3216 #pragma mark - PlatformSupport interface 3217 #endif 3218 3219 // This section defines the interface to the Platform Support layer. 3220 // Normal client code should not use any of types defined here, or directly call any of the functions defined here. 3221 // The definitions are placed here because sometimes clients do use these calls indirectly, via other supported client operations. 3222 // For example, AssignDomainName is a macro defined using mDNSPlatformMemCopy() 3223 3224 // Every platform support module must provide the following functions. 3225 // mDNSPlatformInit() typically opens a communication endpoint, and starts listening for mDNS packets. 3226 // When Setup is complete, the platform support layer calls mDNSCoreInitComplete(). 3227 // mDNSPlatformSendUDP() sends one UDP packet 3228 // When a packet is received, the PlatformSupport code calls mDNSCoreReceive() 3229 // mDNSPlatformClose() tidies up on exit 3230 // 3231 // Note: mDNSPlatformMemAllocate/mDNSPlatformMemFree are only required for handling oversized resource records and unicast DNS. 3232 // If your target platform has a well-defined specialized application, and you know that all the records it uses 3233 // are InlineCacheRDSize or less, then you can just make a simple mDNSPlatformMemAllocate() stub that always returns 3234 // NULL. InlineCacheRDSize is a compile-time constant, which is set by default to 68. If you need to handle records 3235 // a little larger than this and you don't want to have to implement run-time allocation and freeing, then you 3236 // can raise the value of this constant to a suitable value (at the expense of increased memory usage). 3237 // 3238 // USE CAUTION WHEN CALLING mDNSPlatformRawTime: The m->timenow_adjust correction factor needs to be added 3239 // Generally speaking: 3240 // Code that's protected by the main mDNS lock should just use the m->timenow value 3241 // Code outside the main mDNS lock should use mDNS_TimeNow(m) to get properly adjusted time 3242 // In certain cases there may be reasons why it's necessary to get the time without taking the lock first 3243 // (e.g. inside the routines that are doing the locking and unlocking, where a call to get the lock would result in a 3244 // recursive loop); in these cases use mDNS_TimeNow_NoLock(m) to get mDNSPlatformRawTime with the proper correction factor added. 3245 // 3246 // mDNSPlatformUTC returns the time, in seconds, since Jan 1st 1970 UTC and is required for generating TSIG records 3247 3248 #ifdef MDNS_MALLOC_DEBUGGING 3249 typedef void mDNSListValidationFunction(void *); 3250 typedef struct listValidator mDNSListValidator; 3251 struct listValidator { 3252 struct listValidator *next; 3253 const char *validationFunctionName; 3254 mDNSListValidationFunction *validator; 3255 void *context; 3256 }; 3257 #endif // MDNS_MALLOC_DEBUGGING 3258 3259 extern mStatus mDNSPlatformInit (mDNS *const m); 3260 extern void mDNSPlatformClose (mDNS *const m); 3261 extern mStatus mDNSPlatformSendUDP(const mDNS *const m, const void *const msg, const mDNSu8 *const end, 3262 mDNSInterfaceID InterfaceID, UDPSocket *src, const mDNSAddr *dst, 3263 mDNSIPPort dstport, mDNSBool useBackgroundTrafficClass); 3264 3265 extern void mDNSPlatformLock (const mDNS *const m); 3266 extern void mDNSPlatformUnlock (const mDNS *const m); 3267 3268 extern void mDNSPlatformStrLCopy ( void *dst, const void *src, mDNSu32 len); 3269 extern mDNSu32 mDNSPlatformStrLen ( const void *src); 3270 extern void mDNSPlatformMemCopy ( void *dst, const void *src, mDNSu32 len); 3271 extern mDNSBool mDNSPlatformMemSame (const void *dst, const void *src, mDNSu32 len); 3272 extern int mDNSPlatformMemCmp (const void *dst, const void *src, mDNSu32 len); 3273 extern void mDNSPlatformMemZero ( void *dst, mDNSu32 len); 3274 extern void mDNSPlatformQsort (void *base, int nel, int width, int (*compar)(const void *, const void *)); 3275 #if MDNS_MALLOC_DEBUGGING 3276 #define mDNSPlatformMemAllocate(X) mallocL(# X, X) 3277 #define mDNSPlatformMemAllocateClear(X) callocL(# X, X) 3278 #define mDNSPlatformMemFree(X) freeL(# X, X) 3279 extern void mDNSPlatformValidateLists (void); 3280 extern void mDNSPlatformAddListValidator(mDNSListValidator *validator, 3281 mDNSListValidationFunction *vf, const char *vfName, void *context); 3282 #else 3283 extern void * mDNSPlatformMemAllocate(mDNSu32 len); 3284 extern void * mDNSPlatformMemAllocateClear(mDNSu32 len); 3285 extern void mDNSPlatformMemFree(void *mem); 3286 #endif // MDNS_MALLOC_DEBUGGING 3287 3288 #define mDNSPlatformMemForget(PTR) \ 3289 do \ 3290 { \ 3291 if (*(PTR)) \ 3292 { \ 3293 mDNSPlatformMemFree(*(PTR)); \ 3294 *(PTR) = NULL; \ 3295 } \ 3296 } while(0) 3297 3298 // If the platform doesn't have a strong PRNG, we define a naive multiply-and-add based on a seed 3299 // from the platform layer. Long-term, we should embed an arc4 implementation, but the strength 3300 // will still depend on the randomness of the seed. 3301 #if !defined(_PLATFORM_HAS_STRONG_PRNG_) && (_BUILDING_XCODE_PROJECT_ || defined(_WIN32)) 3302 #define _PLATFORM_HAS_STRONG_PRNG_ 1 3303 #endif 3304 #if _PLATFORM_HAS_STRONG_PRNG_ 3305 extern mDNSu32 mDNSPlatformRandomNumber(void); 3306 #else 3307 extern mDNSu32 mDNSPlatformRandomSeed (void); 3308 #endif // _PLATFORM_HAS_STRONG_PRNG_ 3309 3310 extern mStatus mDNSPlatformTimeInit (void); 3311 extern mDNSs32 mDNSPlatformRawTime (void); 3312 extern mDNSs32 mDNSPlatformUTC (void); 3313 extern mDNSs32 mDNSPlatformContinuousTimeSeconds (void); 3314 3315 // strlen("1900-01-01 00:00:00.000000-0000" + "\0") == 32; 3316 // bufferLen must be greater than MIN_TIMESTAMP_STRING_LENGTH to avoid the string truncation. 3317 #define MIN_TIMESTAMP_STRING_LENGTH 32 3318 extern void getLocalTimestampFromPlatformTime(mDNSs32 platformTimeNow, mDNSs32 platformTime, 3319 char *outBuffer, mDNSu32 bufferLen); 3320 extern void getLocalTimestampNow(char *outBuffer, mDNSu32 bufferLen); 3321 3322 /*! 3323 * @brief 3324 * Convert the Platform time in ticks to millisecond. 3325 * 3326 * @param ticks 3327 * The time interval calculated by subtracting one absolute platform time from another. 3328 * 3329 * @result 3330 * The time interval in millisecond. 3331 * 3332 * @discussion 3333 * if the number of milliseconds represented by `ticks` is greater than `UINT_MAX`, 3334 * `UINT_MAX` will be returned. 3335 * 3336 * Calling this function with absolute platform time is undefined. 3337 */ 3338 extern mDNSu32 getMillisecondsFromTicks(mDNSs32 ticks); 3339 3340 #define mDNS_TimeNow_NoLock(m) (mDNSPlatformRawTime() + (m)->timenow_adjust) 3341 3342 #if MDNS_DEBUGMSGS 3343 extern void mDNSPlatformWriteDebugMsg(const char *msg); 3344 #endif 3345 extern void mDNSPlatformWriteLogMsg(const char *ident, const char *msg, mDNSLogLevel_t loglevel); 3346 3347 // Platform support modules should provide the following functions to map between opaque interface IDs 3348 // and interface indexes in order to support the DNS-SD API. If your target platform does not support 3349 // multiple interfaces and/or does not support the DNS-SD API, these functions can be empty. 3350 extern mDNSInterfaceID mDNSPlatformInterfaceIDfromInterfaceIndex(mDNS *const m, mDNSu32 ifindex); 3351 extern mDNSu32 mDNSPlatformInterfaceIndexfromInterfaceID(mDNS *const m, mDNSInterfaceID id, mDNSBool suppressNetworkChange); 3352 3353 // Every platform support module must provide the following functions if it is to support unicast DNS 3354 // and Dynamic Update. 3355 // All TCP socket operations implemented by the platform layer MUST NOT BLOCK. 3356 // mDNSPlatformTCPConnect initiates a TCP connection with a peer, adding the socket descriptor to the 3357 // main event loop. The return value indicates whether the connection succeeded, failed, or is pending 3358 // (i.e. the call would block.) On return, the descriptor parameter is set to point to the connected socket. 3359 // The TCPConnectionCallback is subsequently invoked when the connection 3360 // completes (in which case the ConnectionEstablished parameter is true), or data is available for 3361 // reading on the socket (indicated by the ConnectionEstablished parameter being false.) If the connection 3362 // asynchronously fails, the TCPConnectionCallback should be invoked as usual, with the error being 3363 // returned in subsequent calls to PlatformReadTCP or PlatformWriteTCP. (This allows for platforms 3364 // with limited asynchronous error detection capabilities.) PlatformReadTCP and PlatformWriteTCP must 3365 // return the number of bytes read/written, 0 if the call would block, and -1 if an error. PlatformReadTCP 3366 // should set the closed argument if the socket has been closed. 3367 // PlatformTCPCloseConnection must close the connection to the peer and remove the descriptor from the 3368 // event loop. CloseConnectin may be called at any time, including in a ConnectionCallback. 3369 3370 typedef enum 3371 { 3372 kTCPSocketFlags_Zero = 0, 3373 kTCPSocketFlags_UseTLS = (1 << 0), 3374 kTCPSocketFlags_TLSValidationNotRequired = (1 << 1) 3375 } TCPSocketFlags; 3376 3377 typedef void (*TCPConnectionCallback)(TCPSocket *sock, void *context, mDNSBool ConnectionEstablished, mStatus err); 3378 typedef void (*TCPAcceptedCallback)(TCPSocket *sock, mDNSAddr *addr, mDNSIPPort *port, 3379 const char *remoteName, void *context); 3380 extern TCPSocket *mDNSPlatformTCPSocket(TCPSocketFlags flags, mDNSAddr_Type addrtype, mDNSIPPort *port, domainname *hostname, mDNSBool useBackgroundTrafficClass); // creates a TCP socket 3381 extern TCPListener *mDNSPlatformTCPListen(mDNSAddr_Type addrtype, mDNSIPPort *port, mDNSAddr *addr, 3382 TCPSocketFlags socketFlags, mDNSBool reuseAddr, int queueLength, 3383 TCPAcceptedCallback callback, void *context); // Listen on a port 3384 extern mStatus mDNSPlatformTCPSocketSetCallback(TCPSocket *sock, TCPConnectionCallback callback, void *context); 3385 extern TCPSocket *mDNSPlatformTCPAccept(TCPSocketFlags flags, int sd); 3386 extern int mDNSPlatformTCPGetFD(TCPSocket *sock); 3387 extern mDNSBool mDNSPlatformTCPWritable(TCPSocket *sock); 3388 extern mStatus mDNSPlatformTCPConnect(TCPSocket *sock, const mDNSAddr *dst, mDNSOpaque16 dstport, 3389 mDNSInterfaceID InterfaceID, TCPConnectionCallback callback, void *context); 3390 extern void mDNSPlatformTCPCloseConnection(TCPSocket *sock); 3391 extern long mDNSPlatformReadTCP(TCPSocket *sock, void *buf, unsigned long buflen, mDNSBool *closed); 3392 extern long mDNSPlatformWriteTCP(TCPSocket *sock, const char *msg, unsigned long len); 3393 extern UDPSocket *mDNSPlatformUDPSocket(const mDNSIPPort requestedport); 3394 extern mDNSu16 mDNSPlatformGetUDPPort(UDPSocket *sock); 3395 extern void mDNSPlatformUDPClose(UDPSocket *sock); 3396 extern mDNSBool mDNSPlatformUDPSocketEncounteredEOF(const UDPSocket *sock); 3397 extern void mDNSPlatformReceiveBPF_fd(int fd); 3398 extern void mDNSPlatformUpdateProxyList(const mDNSInterfaceID InterfaceID); 3399 extern void mDNSPlatformSendRawPacket(const void *const msg, const mDNSu8 *const end, mDNSInterfaceID InterfaceID); 3400 extern void mDNSPlatformSetLocalAddressCacheEntry(const mDNSAddr *const tpa, const mDNSEthAddr *const tha, mDNSInterfaceID InterfaceID); 3401 extern void mDNSPlatformSourceAddrForDest(mDNSAddr *const src, const mDNSAddr *const dst); 3402 extern void mDNSPlatformSendKeepalive(mDNSAddr *sadd, mDNSAddr *dadd, mDNSIPPort *lport, mDNSIPPort *rport, mDNSu32 seq, mDNSu32 ack, mDNSu16 win); 3403 extern mStatus mDNSPlatformRetrieveTCPInfo(mDNSAddr *laddr, mDNSIPPort *lport, mDNSAddr *raddr, mDNSIPPort *rport, mDNSTCPInfo *mti); 3404 extern mStatus mDNSPlatformGetRemoteMacAddr(mDNSAddr *raddr); 3405 extern mStatus mDNSPlatformStoreSPSMACAddr(mDNSAddr *spsaddr, char *ifname); 3406 extern mStatus mDNSPlatformClearSPSData(void); 3407 extern mStatus mDNSPlatformStoreOwnerOptRecord(char *ifname, DNSMessage *msg, int length); 3408 3409 // mDNSPlatformTLSSetupCerts/mDNSPlatformTLSTearDownCerts used by dnsextd 3410 extern mStatus mDNSPlatformTLSSetupCerts(void); 3411 extern void mDNSPlatformTLSTearDownCerts(void); 3412 3413 // Platforms that support unicast browsing and dynamic update registration for clients who do not specify a domain 3414 // in browse/registration calls must implement these routines to get the "default" browse/registration list. 3415 3416 extern mDNSBool mDNSPlatformSetDNSConfig(mDNSBool setservers, mDNSBool setsearch, domainname *const fqdn, DNameListElem **RegDomains, 3417 DNameListElem **BrowseDomains, mDNSBool ackConfig); 3418 extern mStatus mDNSPlatformGetPrimaryInterface(mDNSAddr *v4, mDNSAddr *v6, mDNSAddr *router); 3419 extern void mDNSPlatformDynDNSHostNameStatusChanged(const domainname *const dname, const mStatus status); 3420 3421 extern void mDNSPlatformSetAllowSleep(mDNSBool allowSleep, const char *reason); 3422 extern void mDNSPlatformPreventSleep(mDNSu32 timeout, const char *reason); 3423 extern void mDNSPlatformSendWakeupPacket(mDNSInterfaceID InterfaceID, char *EthAddr, char *IPAddr, int iteration); 3424 3425 extern mDNSBool mDNSPlatformInterfaceIsD2D(mDNSInterfaceID InterfaceID); 3426 #if MDNSRESPONDER_SUPPORTS(APPLE, AWDL) 3427 extern mDNSBool mDNSPlatformInterfaceIsAWDL(mDNSInterfaceID interfaceID); 3428 #endif 3429 extern mDNSBool mDNSPlatformValidRecordForQuestion(const ResourceRecord *const rr, const DNSQuestion *const q); 3430 extern mDNSBool mDNSPlatformValidRecordForInterface(const AuthRecord *rr, mDNSInterfaceID InterfaceID); 3431 extern mDNSBool mDNSPlatformValidQuestionForInterface(const DNSQuestion *q, const NetworkInterfaceInfo *intf); 3432 3433 extern void mDNSPlatformFormatTime(unsigned long t, mDNSu8 *buf, int bufsize); 3434 3435 // Platform event API 3436 3437 #ifdef _LEGACY_NAT_TRAVERSAL_ 3438 // Support for legacy NAT traversal protocols, implemented by the platform layer and callable by the core. 3439 extern void LNT_SendDiscoveryMsg(mDNS *m); 3440 extern void LNT_ConfigureRouterInfo(mDNS *m, const mDNSInterfaceID InterfaceID, const mDNSu8 *const data, const mDNSu16 len); 3441 extern mStatus LNT_GetExternalAddress(mDNS *m); 3442 extern mStatus LNT_MapPort(mDNS *m, NATTraversalInfo *const n); 3443 extern mStatus LNT_UnmapPort(mDNS *m, NATTraversalInfo *const n); 3444 extern void LNT_ClearState(mDNS *const m); 3445 #endif // _LEGACY_NAT_TRAVERSAL_ 3446 3447 // The core mDNS code provides these functions, for the platform support code to call at appropriate times 3448 // 3449 // mDNS_SetFQDN() is called once on startup (typically from mDNSPlatformInit()) 3450 // and then again on each subsequent change of the host name. 3451 // 3452 // mDNS_RegisterInterface() is used by the platform support layer to inform mDNSCore of what 3453 // physical and/or logical interfaces are available for sending and receiving packets. 3454 // Typically it is called on startup for each available interface, but register/deregister may be 3455 // called again later, on multiple occasions, to inform the core of interface configuration changes. 3456 // If set->Advertise is set non-zero, then mDNS_RegisterInterface() also registers the standard 3457 // resource records that should be associated with every publicised IP address/interface: 3458 // -- Name-to-address records (A/AAAA) 3459 // -- Address-to-name records (PTR) 3460 // -- Host information (HINFO) 3461 // IMPORTANT: The specified mDNSInterfaceID MUST NOT be 0, -1, or -2; these values have special meaning 3462 // mDNS_RegisterInterface does not result in the registration of global hostnames via dynamic update - 3463 // see mDNS_SetPrimaryInterfaceInfo, mDNS_AddDynDNSHostName, etc. for this purpose. 3464 // Note that the set may be deallocated immediately after it is deregistered via mDNS_DeegisterInterface. 3465 // 3466 // mDNS_RegisterDNS() is used by the platform support layer to provide the core with the addresses of 3467 // available domain name servers for unicast queries/updates. RegisterDNS() should be called once for 3468 // each name server, typically at startup, or when a new name server becomes available. DeregiterDNS() 3469 // must be called whenever a registered name server becomes unavailable. DeregisterDNSList deregisters 3470 // all registered servers. mDNS_DNSRegistered() returns true if one or more servers are registered in the core. 3471 // 3472 // mDNSCoreInitComplete() is called when the platform support layer is finished. 3473 // Typically this is at the end of mDNSPlatformInit(), but may be later 3474 // (on platforms like OT that allow asynchronous initialization of the networking stack). 3475 // 3476 // mDNSCoreReceive() is called when a UDP packet is received 3477 // 3478 // mDNSCoreMachineSleep() is called when the machine sleeps or wakes 3479 // (This refers to heavyweight laptop-style sleep/wake that disables network access, 3480 // not lightweight second-by-second CPU power management modes.) 3481 3482 extern void mDNS_SetFQDN(mDNS *const m); 3483 extern void mDNS_ActivateNetWake_internal (mDNS *const m, NetworkInterfaceInfo *set); 3484 extern void mDNS_DeactivateNetWake_internal(mDNS *const m, NetworkInterfaceInfo *set); 3485 3486 // Attributes that controls the Bonjour operation initiation and response speed for an interface. 3487 typedef enum 3488 { 3489 FastActivation, // For p2p* and DirectLink type interfaces 3490 NormalActivation, // For standard interface timing 3491 #if MDNSRESPONDER_SUPPORTS(APPLE, SLOW_ACTIVATION) 3492 SlowActivation // For flapping interfaces 3493 #endif 3494 } InterfaceActivationSpeed; 3495 3496 extern mStatus mDNS_RegisterInterface (mDNS *const m, NetworkInterfaceInfo *set, InterfaceActivationSpeed probeDelay); 3497 extern void mDNS_DeregisterInterface(mDNS *const m, NetworkInterfaceInfo *set, InterfaceActivationSpeed probeDelay); 3498 extern void mDNSCoreInitComplete(mDNS *const m, mStatus result); 3499 extern void mDNSCoreReceive(mDNS *const m, DNSMessage *const msg, const mDNSu8 *const end, 3500 const mDNSAddr *const srcaddr, const mDNSIPPort srcport, 3501 const mDNSAddr *dstaddr, const mDNSIPPort dstport, const mDNSInterfaceID InterfaceID); 3502 #if MDNSRESPONDER_SUPPORTS(APPLE, QUERIER) 3503 extern void mDNSCoreReceiveForQuerier(mDNS *m, DNSMessage *msg, const mDNSu8 *end, mdns_client_t client, 3504 mdns_dns_service_t service, mDNSInterfaceID InterfaceID); 3505 #endif 3506 extern CacheRecord *mDNSCheckCacheFlushRecords(mDNS *m, CacheRecord *CacheFlushRecords, mDNSBool id_is_zero, int numAnswers, 3507 DNSQuestion *unicastQuestion, CacheRecord *NSECCachePtr, CacheRecord *NSECRecords, 3508 mDNSu8 rcode); 3509 extern void mDNSCoreRestartQueries(mDNS *const m); 3510 extern void mDNSCoreRestartQuestion(mDNS *const m, DNSQuestion *q); 3511 extern void mDNSCoreRestartRegistration(mDNS *const m, AuthRecord *rr, int announceCount); 3512 typedef void (*FlushCache)(mDNS *const m); 3513 typedef void (*CallbackBeforeStartQuery)(mDNS *const m, void *context); 3514 extern void mDNSCoreRestartAddressQueries(mDNS *const m, mDNSBool SearchDomainsChanged, FlushCache flushCacheRecords, 3515 CallbackBeforeStartQuery beforeQueryStart, void *context); 3516 extern mDNSBool mDNSCoreHaveAdvertisedMulticastServices(mDNS *const m); 3517 extern void mDNSCoreMachineSleep(mDNS *const m, mDNSBool wake); 3518 extern mDNSBool mDNSCoreReadyForSleep(mDNS *m, mDNSs32 now); 3519 3520 typedef enum 3521 { 3522 mDNSNextWakeReason_Null = 0, 3523 mDNSNextWakeReason_NATPortMappingRenewal = 1, 3524 mDNSNextWakeReason_RecordRegistrationRenewal = 2, 3525 mDNSNextWakeReason_UpkeepWake = 3, 3526 mDNSNextWakeReason_DHCPLeaseRenewal = 4, 3527 mDNSNextWakeReason_SleepProxyRegistrationRetry = 5 3528 } mDNSNextWakeReason; 3529 3530 extern mDNSs32 mDNSCoreIntervalToNextWake(mDNS *const m, mDNSs32 now, mDNSNextWakeReason *outReason); 3531 3532 extern void mDNSCoreReceiveRawPacket (mDNS *const m, const mDNSu8 *const p, const mDNSu8 *const end, const mDNSInterfaceID InterfaceID); 3533 3534 extern mDNSBool mDNSAddrIsDNSMulticast(const mDNSAddr *ip); 3535 3536 typedef mDNSu32 CreateNewCacheEntryFlags; 3537 #define kCreateNewCacheEntryFlagsNone 0 3538 #if MDNSRESPONDER_SUPPORTS(COMMON, DNS_PUSH) || MDNSRESPONDER_SUPPORTS(APPLE, DNS_PUSH) 3539 #define kCreateNewCacheEntryFlagsDNSPushSubscribed (1U << 0) 3540 #endif 3541 #if MDNSRESPONDER_SUPPORTS(APPLE, DNSSECv2) 3542 // Set this flag if the record being created comes from a DNSSEC-aware response. 3543 #define kCreateNewCacheEntryFlagsDNSSECRRToValidate (1U << 1) 3544 #define kCreateNewCacheEntryFlagsDNSSECRRValidatedSecure (1U << 2) 3545 #define kCreateNewCacheEntryFlagsDNSSECRRValidatedInsecure (1U << 3) 3546 #define kCreateNewCacheEntryFlagsDNSSECInsecureValidationUsable (1U << 4) 3547 #endif 3548 extern CacheRecord *CreateNewCacheEntryEx(mDNS *m, mDNSu32 slot, CacheGroup *cg, mDNSs32 delay, mDNSBool add, 3549 const mDNSAddr *sourceAddress, CreateNewCacheEntryFlags flags); 3550 extern CacheRecord *CreateNewCacheEntry(mDNS *const m, const mDNSu32 slot, CacheGroup *cg, mDNSs32 delay, mDNSBool Add, const mDNSAddr *sourceAddress); 3551 extern CacheGroup *CacheGroupForName(const mDNS *const m, const mDNSu32 namehash, const domainname *const name); 3552 extern void ReleaseCacheRecord(mDNS *const m, CacheRecord *r); 3553 extern void ScheduleNextCacheCheckTime(mDNS *const m, const mDNSu32 slot, const mDNSs32 event); 3554 extern void SetNextCacheCheckTimeForRecord(mDNS *const m, CacheRecord *const rr); 3555 extern void RefreshCacheRecord(mDNS *const m, CacheRecord *rr, mDNSu32 ttl); 3556 extern void GrantCacheExtensions(mDNS *const m, DNSQuestion *q, mDNSu32 lease); 3557 extern void MakeNegativeCacheRecordForQuestion(mDNS *m, CacheRecord *cr, const DNSQuestion *q, mDNSu32 ttl, 3558 mDNSInterfaceID InterfaceID, mDNSOpaque16 responseFlags); 3559 extern void CompleteDeregistration(mDNS *const m, AuthRecord *rr); 3560 extern void AnswerCurrentQuestionWithResourceRecord(mDNS *const m, CacheRecord *const rr, const QC_result AddRecord); 3561 extern void AnswerQuestionByFollowingCNAME(mDNS *const m, DNSQuestion *q, ResourceRecord *rr); 3562 extern NetworkInterfaceInfo *FirstInterfaceForID(mDNS *const m, const mDNSInterfaceID InterfaceID); 3563 extern NetworkInterfaceInfo *FirstIPv4LLInterfaceForID(mDNS *const m, const mDNSInterfaceID InterfaceID); 3564 extern char *InterfaceNameForID(mDNS *const m, const mDNSInterfaceID InterfaceID); 3565 extern const char *InterfaceNameForIDOrEmptyString(mDNSInterfaceID InterfaceID); 3566 extern void CacheRecordSetResponseFlags(CacheRecord *const cr, const mDNSOpaque16 responseFlags); 3567 extern void mDNSCoreResetRecord(mDNS *const m); 3568 extern mDNSBool getValidContinousTSRTime(mDNSs32 *timestampContinuous, mDNSu32 tsrTimestamp); 3569 extern AuthRecord *mDNSGetTSRForAuthRecord(mDNS *m, const AuthRecord *rr); 3570 extern CacheRecord *mDNSGetTSRForCacheGroup(const CacheGroup *const cg); 3571 typedef enum { eTSRCheckLose = -1, eTSRCheckNoKeyMatch = 0, eTSRCheckKeyMatch, eTSRCheckWin } eTSRCheckResult; 3572 extern eTSRCheckResult CheckTSRForResourceRecord(const TSROptData *curTSROpt, const ResourceRecord *ourTSRRec); 3573 #if !MDNSRESPONDER_SUPPORTS(APPLE, QUERIER) 3574 extern void DNSServerChangeForQuestion(mDNS *const m, DNSQuestion *q, DNSServer *newServer); 3575 #endif 3576 extern void ActivateUnicastRegistration(mDNS *const m, AuthRecord *const rr); 3577 #if MDNSRESPONDER_SUPPORTS(APPLE, D2D) 3578 extern void mDNSCoreReceiveD2DResponse(mDNS *const m, const DNSMessage *const response, const mDNSu8 *end, 3579 const mDNSAddr *srcaddr, const mDNSIPPort srcport, const mDNSAddr *dstaddr, mDNSIPPort dstport, 3580 const mDNSInterfaceID InterfaceID); 3581 #endif 3582 extern void CheckSuppressUnusableQuestions(mDNS *const m); 3583 extern void RetrySearchDomainQuestions(mDNS *const m); 3584 extern mDNSBool DomainEnumQuery(const domainname *qname); 3585 extern mStatus UpdateKeepaliveRData(mDNS *const m, AuthRecord *rr, NetworkInterfaceInfo *const intf, mDNSBool updateMac, char *ethAddr); 3586 extern void UpdateKeepaliveRMACAsync(mDNS *const m, void *context); 3587 extern void UpdateRMAC(mDNS *const m, void *context); 3588 3589 // Used only in logging to restrict the number of /etc/hosts entries printed 3590 extern void FreeEtcHosts(mDNS *const m, AuthRecord *const rr, mStatus result); 3591 // exported for using the hash for /etc/hosts AuthRecords 3592 extern AuthGroup *AuthGroupForName(AuthHash *r, const mDNSu32 namehash, const domainname *const name); 3593 extern AuthGroup *AuthGroupForRecord(AuthHash *r, const ResourceRecord *const rr); 3594 extern AuthGroup *InsertAuthRecord(mDNS *const m, AuthHash *r, AuthRecord *rr); 3595 extern AuthGroup *RemoveAuthRecord(mDNS *const m, AuthHash *r, AuthRecord *rr); 3596 3597 3598 typedef void ProxyCallback (void *socket, DNSMessage *const msg, const mDNSu8 *const end, const mDNSAddr *const srcaddr, 3599 const mDNSIPPort srcport, const mDNSAddr *dstaddr, const mDNSIPPort dstport, const mDNSInterfaceID InterfaceID, void *context); 3600 extern void mDNSPlatformInitDNSProxySkts(ProxyCallback *UDPCallback, ProxyCallback *TCPCallback); 3601 extern void mDNSPlatformCloseDNSProxySkts(mDNS *const m); 3602 extern void mDNSPlatformDisposeProxyContext(void *context); 3603 extern mDNSu8 *DNSProxySetAttributes(DNSQuestion *q, DNSMessageHeader *h, DNSMessage *msg, mDNSu8 *start, mDNSu8 *limit); 3604 3605 extern void mDNSPlatformSetSocktOpt(void *sock, mDNSTransport_Type transType, mDNSAddr_Type addrType, const DNSQuestion *q); 3606 extern mDNSs32 mDNSPlatformGetPID(void); 3607 extern mDNSBool mDNSValidKeepAliveRecord(AuthRecord *rr); 3608 extern mDNSBool CacheRecordRmvEventsForQuestion(mDNS *const m, DNSQuestion *q); 3609 #if MDNSRESPONDER_SUPPORTS(APPLE, RANDOM_AWDL_HOSTNAME) 3610 extern void GetRandomUUIDLabel(domainlabel *label); 3611 extern void GetRandomUUIDLocalHostname(domainname *hostname); 3612 #endif 3613 #if MDNSRESPONDER_SUPPORTS(APPLE, DNS_ANALYTICS) || MDNSRESPONDER_SUPPORTS(APPLE, RUNTIME_MDNS_METRICS) 3614 extern void DNSMetricsClear(DNSMetrics *metrics); 3615 #endif 3616 3617 // *************************************************************************** 3618 #if 0 3619 #pragma mark - 3620 #pragma mark - Sleep Proxy 3621 #endif 3622 3623 // Sleep Proxy Server Property Encoding 3624 // 3625 // Sleep Proxy Servers are advertised using a structured service name, consisting of four 3626 // metrics followed by a human-readable name. The metrics assist clients in deciding which 3627 // Sleep Proxy Server(s) to use when multiple are available on the network. Each metric 3628 // is a two-digit decimal number in the range 10-99. Lower metrics are generally better. 3629 // 3630 // AA-BB-CC-DD.FF Name 3631 // 3632 // Metrics: 3633 // 3634 // AA = Intent 3635 // BB = Portability 3636 // CC = Marginal Power 3637 // DD = Total Power 3638 // FF = Features Supported (Currently TCP Keepalive only) 3639 // 3640 // 3641 // ** Intent Metric ** 3642 // 3643 // 20 = Dedicated Sleep Proxy Server -- a device, permanently powered on, 3644 // installed for the express purpose of providing Sleep Proxy Service. 3645 // 3646 // 30 = Primary Network Infrastructure Hardware -- a router, DHCP server, NAT gateway, 3647 // or similar permanently installed device which is permanently powered on. 3648 // This is hardware designed for the express purpose of being network 3649 // infrastructure, and for most home users is typically a single point 3650 // of failure for the local network -- e.g. most home users only have 3651 // a single NAT gateway / DHCP server. Even though in principle the 3652 // hardware might technically be capable of running different software, 3653 // a typical user is unlikely to do that. e.g. AirPort base station. 3654 // 3655 // 40 = Primary Network Infrastructure Software -- a general-purpose computer 3656 // (e.g. Mac, Windows, Linux, etc.) which is currently running DHCP server 3657 // or NAT gateway software, but the user could choose to turn that off 3658 // fairly easily. e.g. iMac running Internet Sharing 3659 // 3660 // 50 = Secondary Network Infrastructure Hardware -- like primary infrastructure 3661 // hardware, except not a single point of failure for the entire local network. 3662 // For example, an AirPort base station in bridge mode. This may have clients 3663 // associated with it, and if it goes away those clients will be inconvenienced, 3664 // but unlike the NAT gateway / DHCP server, the entire local network is not 3665 // dependent on it. 3666 // 3667 // 60 = Secondary Network Infrastructure Software -- like 50, but in a general- 3668 // purpose CPU. 3669 // 3670 // 70 = Incidentally Available Hardware -- a device which has no power switch 3671 // and is generally left powered on all the time. Even though it is not a 3672 // part of what we conventionally consider network infrastructure (router, 3673 // DHCP, NAT, DNS, etc.), and the rest of the network can operate fine 3674 // without it, since it's available and unlikely to be turned off, it is a 3675 // reasonable candidate for providing Sleep Proxy Service e.g. Apple TV, 3676 // or an AirPort base station in client mode, associated with an existing 3677 // wireless network (e.g. AirPort Express connected to a music system, or 3678 // being used to share a USB printer). 3679 // 3680 // 80 = Incidentally Available Software -- a general-purpose computer which 3681 // happens at this time to be set to "never sleep", and as such could be 3682 // useful as a Sleep Proxy Server, but has not been intentionally provided 3683 // for this purpose. Of all the Intent Metric categories this is the 3684 // one most likely to be shut down or put to sleep without warning. 3685 // However, if nothing else is availalable, it may be better than nothing. 3686 // e.g. Office computer in the workplace which has been set to "never sleep" 3687 // 3688 // 3689 // ** Portability Metric ** 3690 // 3691 // Inversely related to mass of device, on the basis that, all other things 3692 // being equal, heavier devices are less likely to be moved than lighter devices. 3693 // E.g. A MacBook running Internet Sharing is probably more likely to be 3694 // put to sleep and taken away than a Mac Pro running Internet Sharing. 3695 // The Portability Metric is a logarithmic decibel scale, computed by taking the 3696 // (approximate) mass of the device in milligrammes, taking the base 10 logarithm 3697 // of that, multiplying by 10, and subtracting the result from 100: 3698 // 3699 // Portability Metric = 100 - (log10(mg) * 10) 3700 // 3701 // The Portability Metric is not necessarily computed literally from the actual 3702 // mass of the device; the intent is just that lower numbers indicate more 3703 // permanent devices, and higher numbers indicate devices more likely to be 3704 // removed from the network, e.g., in order of increasing portability: 3705 // 3706 // Mac Pro < iMac < Laptop < iPhone 3707 // 3708 // Example values: 3709 // 3710 // 10 = 1 metric tonne 3711 // 40 = 1kg 3712 // 70 = 1g 3713 // 90 = 10mg 3714 // 3715 // 3716 // ** Marginal Power and Total Power Metrics ** 3717 // 3718 // The Marginal Power Metric is the power difference between sleeping and staying awake 3719 // to be a Sleep Proxy Server. 3720 // 3721 // The Total Power Metric is the total power consumption when being Sleep Proxy Server. 3722 // 3723 // The Power Metrics use a logarithmic decibel scale, computed as ten times the 3724 // base 10 logarithm of the (approximate) power in microwatts: 3725 // 3726 // Power Metric = log10(uW) * 10 3727 // 3728 // Higher values indicate higher power consumption. Example values: 3729 // 3730 // 10 = 10 uW 3731 // 20 = 100 uW 3732 // 30 = 1 mW 3733 // 60 = 1 W 3734 // 90 = 1 kW 3735 3736 typedef enum 3737 { 3738 mDNSSleepProxyMetric_Dedicated = 20, 3739 mDNSSleepProxyMetric_PrimaryHardware = 30, 3740 mDNSSleepProxyMetric_PrimarySoftware = 40, 3741 mDNSSleepProxyMetric_SecondaryHardware = 50, 3742 mDNSSleepProxyMetric_SecondarySoftware = 60, 3743 mDNSSleepProxyMetric_IncidentalHardware = 70, 3744 mDNSSleepProxyMetric_IncidentalSoftware = 80 3745 } mDNSSleepProxyMetric; 3746 3747 typedef enum 3748 { 3749 mDNS_NoWake = 0, // System does not support Wake on LAN 3750 mDNS_WakeOnAC = 1, // System supports Wake on LAN when connected to AC power only 3751 mDNS_WakeOnBattery = 2 // System supports Wake on LAN on battery 3752 } mDNSWakeForNetworkAccess; 3753 3754 extern void mDNSCoreBeSleepProxyServer_internal(mDNS *const m, mDNSu8 sps, mDNSu8 port, mDNSu8 marginalpower, mDNSu8 totpower, mDNSu8 features); 3755 #define mDNSCoreBeSleepProxyServer(M,S,P,MP,TP,F) \ 3756 do { mDNS_Lock(m); mDNSCoreBeSleepProxyServer_internal((M),(S),(P),(MP),(TP),(F)); mDNS_Unlock(m); } while(0) 3757 3758 #if MDNSRESPONDER_SUPPORTS(COMMON, SPS_CLIENT) 3759 extern void FindSPSInCache(mDNS *const m, const DNSQuestion *const q, const CacheRecord *sps[3]); 3760 #endif 3761 #define PrototypeSPSName(X) ((X)[0] >= 11 && (X)[3] == '-' && (X)[ 4] == '9' && (X)[ 5] == '9' && \ 3762 (X)[6] == '-' && (X)[ 7] == '9' && (X)[ 8] == '9' && \ 3763 (X)[9] == '-' && (X)[10] == '9' && (X)[11] == '9' ) 3764 #define ValidSPSName(X) ((X)[0] >= 5 && mDNSIsDigit((X)[1]) && mDNSIsDigit((X)[2]) && mDNSIsDigit((X)[4]) && mDNSIsDigit((X)[5])) 3765 #define SPSMetric(X) (!ValidSPSName(X) || PrototypeSPSName(X) ? 1000000 : \ 3766 ((X)[1]-'0') * 100000 + ((X)[2]-'0') * 10000 + ((X)[4]-'0') * 1000 + ((X)[5]-'0') * 100 + ((X)[7]-'0') * 10 + ((X)[8]-'0')) 3767 #define LocalSPSMetric(X) ( (X)->SPSType * 10000 + (X)->SPSPortability * 100 + (X)->SPSMarginalPower) 3768 #define SPSFeatures(X) ((X)[0] >= 13 && (X)[12] =='.' ? ((X)[13]-'0') : 0 ) 3769 3770 #define MD5_DIGEST_LENGTH 16 /* digest length in bytes */ 3771 #define MD5_BLOCK_BYTES 64 /* block size in bytes */ 3772 #define MD5_BLOCK_LONG (MD5_BLOCK_BYTES / sizeof(mDNSu32)) 3773 3774 typedef struct MD5state_st 3775 { 3776 mDNSu32 A,B,C,D; 3777 mDNSu32 Nl,Nh; 3778 mDNSu32 data[MD5_BLOCK_LONG]; 3779 mDNSu32 num; 3780 } MD5_CTX; 3781 3782 extern int MD5_Init(MD5_CTX *c); 3783 extern int MD5_Update(MD5_CTX *c, const void *data, unsigned long len); 3784 extern int MD5_Final(unsigned char *md, MD5_CTX *c); 3785 3786 // *************************************************************************** 3787 #if 0 3788 #pragma mark - 3789 #pragma mark - Compile-Time assertion checks 3790 #endif 3791 3792 // Some C compiler cleverness. We can make the compiler check certain things for 3793 // us, and report compile-time errors if anything is wrong. The usual way to do 3794 // this would be to use a run-time "if" statement, but then you don't find out 3795 // what's wrong until you run the software. This way, if the assertion condition 3796 // is false, the array size is negative, and the complier complains immediately. 3797 3798 struct CompileTimeAssertionChecks_mDNS 3799 { 3800 #ifndef __lint__ 3801 // Check that the compiler generated our on-the-wire packet format structure definitions 3802 // properly packed, without adding padding bytes to align fields on 32-bit or 64-bit boundaries. 3803 char assert0[(sizeof(rdataSRV) == 262 ) ? 1 : -1]; 3804 char assert1[(sizeof(DNSMessageHeader) == 12 ) ? 1 : -1]; 3805 char assert2[(sizeof(DNSMessage) == 12+AbsoluteMaxDNSMessageData) ? 1 : -1]; 3806 char assert3[(sizeof(mDNSs8) == 1 ) ? 1 : -1]; 3807 char assert4[(sizeof(mDNSu8) == 1 ) ? 1 : -1]; 3808 char assert5[(sizeof(mDNSs16) == 2 ) ? 1 : -1]; 3809 char assert6[(sizeof(mDNSu16) == 2 ) ? 1 : -1]; 3810 char assert7[(sizeof(mDNSs32) == 4 ) ? 1 : -1]; 3811 char assert8[(sizeof(mDNSu32) == 4 ) ? 1 : -1]; 3812 char assert9[(sizeof(mDNSOpaque16) == 2 ) ? 1 : -1]; 3813 char assertA[(sizeof(mDNSOpaque32) == 4 ) ? 1 : -1]; 3814 char assertB[(sizeof(mDNSOpaque128) == 16 ) ? 1 : -1]; 3815 char assertC[(sizeof(CacheRecord ) == sizeof(CacheGroup) ) ? 1 : -1]; 3816 char assertD[(sizeof(int) >= 4 ) ? 1 : -1]; 3817 char assertE[(StandardAuthRDSize >= 256 ) ? 1 : -1]; 3818 char assertF[(sizeof(EthernetHeader) == 14 ) ? 1 : -1]; 3819 char assertG[(sizeof(ARP_EthIP ) == 28 ) ? 1 : -1]; 3820 char assertH[(sizeof(IPv4Header ) == 20 ) ? 1 : -1]; 3821 char assertI[(sizeof(IPv6Header ) == 40 ) ? 1 : -1]; 3822 char assertJ[(sizeof(IPv6NDP ) == 24 ) ? 1 : -1]; 3823 char assertK[(sizeof(UDPHeader ) == 8 ) ? 1 : -1]; 3824 char assertL[(sizeof(IKEHeader ) == 28 ) ? 1 : -1]; 3825 char assertM[(sizeof(TCPHeader ) == 20 ) ? 1 : -1]; 3826 char assertN[(sizeof(rdataOPT) == 24 ) ? 1 : -1]; 3827 char assertP[(sizeof(PCPMapRequest) == 60 ) ? 1 : -1]; 3828 char assertQ[(sizeof(PCPMapReply) == 60 ) ? 1 : -1]; 3829 3830 3831 // Check our structures are reasonable sizes. Including overly-large buffers, or embedding 3832 // other overly-large structures instead of having a pointer to them, can inadvertently 3833 // cause structure sizes (and therefore memory usage) to balloon unreasonably. 3834 char sizecheck_RDataBody [(sizeof(RDataBody) == 264) ? 1 : -1]; 3835 char sizecheck_ResourceRecord [(sizeof(ResourceRecord) <= 64) ? 1 : -1]; 3836 char sizecheck_AuthRecord [(sizeof(AuthRecord) <= 1176) ? 1 : -1]; 3837 char sizecheck_CacheRecord [(sizeof(CacheRecord) <= 224) ? 1 : -1]; 3838 char sizecheck_CacheGroup [(sizeof(CacheGroup) <= 224) ? 1 : -1]; 3839 char sizecheck_DNSQuestion [(sizeof(DNSQuestion) <= 712) ? 1 : -1]; 3840 char sizecheck_ZoneData [(sizeof(ZoneData) <= 1544) ? 1 : -1]; 3841 char sizecheck_NATTraversalInfo [(sizeof(NATTraversalInfo) <= 200) ? 1 : -1]; 3842 char sizecheck_HostnameInfo [(sizeof(HostnameInfo) <= 3050) ? 1 : -1]; 3843 #if !MDNSRESPONDER_SUPPORTS(APPLE, QUERIER) 3844 char sizecheck_DNSServer [(sizeof(DNSServer) <= 328) ? 1 : -1]; 3845 #endif 3846 char sizecheck_NetworkInterfaceInfo[(sizeof(NetworkInterfaceInfo) <= 6576) ? 1 : -1]; 3847 char sizecheck_ServiceRecordSet [(sizeof(ServiceRecordSet) <= 4792) ? 1 : -1]; 3848 char sizecheck_DomainAuthInfo [(sizeof(DomainAuthInfo) <= 944) ? 1 : -1]; 3849 #if MDNSRESPONDER_SUPPORTS(APPLE, OS_LOG) 3850 // structure size is assumed by LogRedact routine. 3851 char sizecheck_mDNSAddr [(sizeof(mDNSAddr) == 20) ? 1 : -1]; 3852 char sizecheck_mDNSv4Addr [(sizeof(mDNSv4Addr) == 4) ? 1 : -1]; 3853 char sizecheck_mDNSv6Addr [(sizeof(mDNSv6Addr) == 16) ? 1 : -1]; 3854 #endif 3855 #endif 3856 }; 3857 mdns_compile_time_max_size_check(DupSuppressState, 128); 3858 3859 // Routine to initialize device-info TXT record contents 3860 mDNSu32 initializeDeviceInfoTXT(mDNS *m, mDNSu8 *ptr); 3861 3862 // *************************************************************************** 3863 3864 #ifdef __cplusplus 3865 } 3866 #endif 3867 3868 #endif 3869