14b22b933Srs /* -*- Mode: C; tab-width: 4 -*- 24b22b933Srs * 3*3b436d06SToomas Soome * Copyright (c) 2002-2018 Apple Inc. All rights reserved. 44b22b933Srs * 54b22b933Srs * Licensed under the Apache License, Version 2.0 (the "License"); 64b22b933Srs * you may not use this file except in compliance with the License. 74b22b933Srs * You may obtain a copy of the License at 85ffb0c9bSToomas Soome * 94b22b933Srs * http://www.apache.org/licenses/LICENSE-2.0 105ffb0c9bSToomas Soome * 114b22b933Srs * Unless required by applicable law or agreed to in writing, software 124b22b933Srs * distributed under the License is distributed on an "AS IS" BASIS, 134b22b933Srs * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 144b22b933Srs * See the License for the specific language governing permissions and 154b22b933Srs * limitations under the License. 164b22b933Srs 174b22b933Srs NOTE: 184b22b933Srs If you're building an application that uses DNS Service Discovery 194b22b933Srs this is probably NOT the header file you're looking for. 204b22b933Srs In most cases you will want to use /usr/include/dns_sd.h instead. 214b22b933Srs 224b22b933Srs This header file defines the lowest level raw interface to mDNSCore, 234b22b933Srs which is appropriate *only* on tiny embedded systems where everything 244b22b933Srs runs in a single address space and memory is extremely constrained. 254b22b933Srs All the APIs here are malloc-free, which means that the caller is 264b22b933Srs responsible for passing in a pointer to the relevant storage that 274b22b933Srs will be used in the execution of that call, and (when called with 284b22b933Srs correct parameters) all the calls are guaranteed to succeed. There 294b22b933Srs is never a case where a call can suffer intermittent failures because 304b22b933Srs the implementation calls malloc() and sometimes malloc() returns NULL 314b22b933Srs because memory is so limited that no more is available. 324b22b933Srs This is primarily for devices that need to have precisely known fixed 334b22b933Srs memory requirements, with absolutely no uncertainty or run-time variation, 344b22b933Srs but that certainty comes at a cost of more difficult programming. 355ffb0c9bSToomas Soome 364b22b933Srs For applications running on general-purpose desktop operating systems 374b22b933Srs (Mac OS, Linux, Solaris, Windows, etc.) the API you should use is 384b22b933Srs /usr/include/dns_sd.h, which defines the API by which multiple 394b22b933Srs independent client processes communicate their DNS Service Discovery 404b22b933Srs requests to a single "mdnsd" daemon running in the background. 415ffb0c9bSToomas Soome 424b22b933Srs Even on platforms that don't run multiple independent processes in 434b22b933Srs multiple independent address spaces, you can still use the preferred 444b22b933Srs dns_sd.h APIs by linking in "dnssd_clientshim.c", which implements 454b22b933Srs the standard "dns_sd.h" API calls, allocates any required storage 464b22b933Srs using malloc(), and then calls through to the low-level malloc-free 474b22b933Srs mDNSCore routines defined here. This has the benefit that even though 484b22b933Srs you're running on a small embedded system with a single address space, 494b22b933Srs you can still use the exact same client C code as you'd use on a 504b22b933Srs general-purpose desktop system. 514b22b933Srs 525ffb0c9bSToomas Soome */ 534b22b933Srs 545ffb0c9bSToomas Soome #ifndef __mDNSEmbeddedAPI_h 555ffb0c9bSToomas Soome #define __mDNSEmbeddedAPI_h 564b22b933Srs 575ffb0c9bSToomas Soome #if defined(EFI32) || defined(EFI64) || defined(EFIX64) 585ffb0c9bSToomas Soome // EFI doesn't have stdarg.h unless it's building with GCC. 595ffb0c9bSToomas Soome #include "Tiano.h" 605ffb0c9bSToomas Soome #if !defined(__GNUC__) 615ffb0c9bSToomas Soome #define va_list VA_LIST 625ffb0c9bSToomas Soome #define va_start(a, b) VA_START(a, b) 635ffb0c9bSToomas Soome #define va_end(a) VA_END(a) 645ffb0c9bSToomas Soome #define va_arg(a, b) VA_ARG(a, b) 655ffb0c9bSToomas Soome #endif 665ffb0c9bSToomas Soome #else 675ffb0c9bSToomas Soome #include <stdarg.h> // stdarg.h is required for for va_list support for the mDNS_vsnprintf declaration 685ffb0c9bSToomas Soome #endif 694b22b933Srs 705ffb0c9bSToomas Soome #include "mDNSDebug.h" 715ffb0c9bSToomas Soome #if APPLE_OSX_mDNSResponder 725ffb0c9bSToomas Soome #include <uuid/uuid.h> 73cda73f64SToomas Soome #include <TargetConditionals.h> 745ffb0c9bSToomas Soome #endif 754b22b933Srs 765ffb0c9bSToomas Soome #ifdef __cplusplus 775ffb0c9bSToomas Soome extern "C" { 785ffb0c9bSToomas Soome #endif 794b22b933Srs 805ffb0c9bSToomas Soome // *************************************************************************** 815ffb0c9bSToomas Soome // Feature removal compile options & limited resource targets 824b22b933Srs 835ffb0c9bSToomas Soome // The following compile options are responsible for removing certain features from mDNSCore to reduce the 845ffb0c9bSToomas Soome // memory footprint for use in embedded systems with limited resources. 854b22b933Srs 865ffb0c9bSToomas Soome // UNICAST_DISABLED - disables unicast DNS functionality, including Wide Area Bonjour 875ffb0c9bSToomas Soome // ANONYMOUS_DISABLED - disables anonymous functionality 885ffb0c9bSToomas Soome // DNSSEC_DISABLED - disables DNSSEC functionality 895ffb0c9bSToomas Soome // SPC_DISABLED - disables Bonjour Sleep Proxy client 905ffb0c9bSToomas Soome // IDLESLEEPCONTROL_DISABLED - disables sleep control for Bonjour Sleep Proxy clients 914b22b933Srs 925ffb0c9bSToomas Soome // In order to disable the above features pass the option to your compiler, e.g. -D UNICAST_DISABLED 934b22b933Srs 94cda73f64SToomas Soome // Additionally, the LIMITED_RESOURCES_TARGET compile option will reduce the maximum DNS message sizes. 954b22b933Srs 965ffb0c9bSToomas Soome #ifdef LIMITED_RESOURCES_TARGET 975ffb0c9bSToomas Soome // Don't support jumbo frames 98cda73f64SToomas Soome // 40 (IPv6 header) + 8 (UDP header) + 12 (DNS message header) + 1440 (DNS message body) = 1500 total 99c65ebfc7SToomas Soome #define AbsoluteMaxDNSMessageData 1440 1005ffb0c9bSToomas Soome // StandardAuthRDSize is 264 (256+8), which is large enough to hold a maximum-sized SRV record (6 + 256 bytes) 101c65ebfc7SToomas Soome #define MaximumRDSize 264 1024b22b933Srs #endif 1034b22b933Srs 104*3b436d06SToomas Soome #if !defined(MDNSRESPONDER_BTMM_SUPPORT) 105*3b436d06SToomas Soome #define MDNSRESPONDER_BTMM_SUPPORT 0 106*3b436d06SToomas Soome #endif 107*3b436d06SToomas Soome 1084b22b933Srs // *************************************************************************** 1094b22b933Srs // Function scope indicators 1104b22b933Srs 1114b22b933Srs // If you see "mDNSlocal" before a function name in a C file, it means the function is not callable outside this file 1124b22b933Srs #ifndef mDNSlocal 1134b22b933Srs #define mDNSlocal static 1144b22b933Srs #endif 1154b22b933Srs // If you see "mDNSexport" before a symbol in a C file, it means the symbol is exported for use by clients 1164b22b933Srs // For every "mDNSexport" in a C file, there needs to be a corresponding "extern" declaration in some header file 1174b22b933Srs // (When a C file #includes a header file, the "extern" declarations tell the compiler: 1184b22b933Srs // "This symbol exists -- but not necessarily in this C file.") 1194b22b933Srs #ifndef mDNSexport 1204b22b933Srs #define mDNSexport 1214b22b933Srs #endif 1224b22b933Srs 1234b22b933Srs // Explanation: These local/export markers are a little habit of mine for signaling the programmers' intentions. 1244b22b933Srs // When "mDNSlocal" is just a synonym for "static", and "mDNSexport" is a complete no-op, you could be 1254b22b933Srs // forgiven for asking what purpose they serve. The idea is that if you see "mDNSexport" in front of a 1264b22b933Srs // function definition it means the programmer intended it to be exported and callable from other files 1274b22b933Srs // in the project. If you see "mDNSlocal" in front of a function definition it means the programmer 1284b22b933Srs // intended it to be private to that file. If you see neither in front of a function definition it 1294b22b933Srs // means the programmer forgot (so you should work out which it is supposed to be, and fix it). 1304b22b933Srs // Using "mDNSlocal" instead of "static" makes it easier to do a textual searches for one or the other. 1314b22b933Srs // For example you can do a search for "static" to find if any functions declare any local variables as "static" 1324b22b933Srs // (generally a bad idea unless it's also "const", because static storage usually risks being non-thread-safe) 1334b22b933Srs // without the results being cluttered with hundreds of matches for functions declared static. 1344b22b933Srs // - Stuart Cheshire 1354b22b933Srs 1364b22b933Srs // *************************************************************************** 1374b22b933Srs // Structure packing macro 1384b22b933Srs 1394b22b933Srs // If we're not using GNUC, it's not fatal. 1404b22b933Srs // Most compilers naturally pack the on-the-wire structures correctly anyway, so a plain "struct" is usually fine. 1414b22b933Srs // In the event that structures are not packed correctly, mDNS_Init() will detect this and report an error, so the 1424b22b933Srs // developer will know what's wrong, and can investigate what needs to be done on that compiler to provide proper packing. 1434b22b933Srs #ifndef packedstruct 1444b22b933Srs #if ((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 9))) 1454b22b933Srs #define packedstruct struct __attribute__((__packed__)) 1464b22b933Srs #define packedunion union __attribute__((__packed__)) 1474b22b933Srs #else 1484b22b933Srs #define packedstruct struct 1494b22b933Srs #define packedunion union 1504b22b933Srs #endif 1514b22b933Srs #endif 1524b22b933Srs 1534b22b933Srs // *************************************************************************** 1544b22b933Srs #if 0 1554b22b933Srs #pragma mark - DNS Resource Record class and type constants 1564b22b933Srs #endif 1574b22b933Srs 1585ffb0c9bSToomas Soome typedef enum // From RFC 1035 1595ffb0c9bSToomas Soome { 1605ffb0c9bSToomas Soome kDNSClass_IN = 1, // Internet 1615ffb0c9bSToomas Soome kDNSClass_CS = 2, // CSNET 1625ffb0c9bSToomas Soome kDNSClass_CH = 3, // CHAOS 1635ffb0c9bSToomas Soome kDNSClass_HS = 4, // Hesiod 1645ffb0c9bSToomas Soome kDNSClass_NONE = 254, // Used in DNS UPDATE [RFC 2136] 1655ffb0c9bSToomas Soome 1665ffb0c9bSToomas Soome kDNSClass_Mask = 0x7FFF, // Multicast DNS uses the bottom 15 bits to identify the record class... 1675ffb0c9bSToomas Soome kDNSClass_UniqueRRSet = 0x8000, // ... and the top bit indicates that all other cached records are now invalid 1685ffb0c9bSToomas Soome 1695ffb0c9bSToomas Soome kDNSQClass_ANY = 255, // Not a DNS class, but a DNS query class, meaning "all classes" 1705ffb0c9bSToomas Soome kDNSQClass_UnicastResponse = 0x8000 // Top bit set in a question means "unicast response acceptable" 1715ffb0c9bSToomas Soome } DNS_ClassValues; 1725ffb0c9bSToomas Soome 1735ffb0c9bSToomas Soome typedef enum // From RFC 1035 1745ffb0c9bSToomas Soome { 1755ffb0c9bSToomas Soome kDNSType_A = 1, // 1 Address 1765ffb0c9bSToomas Soome kDNSType_NS, // 2 Name Server 1775ffb0c9bSToomas Soome kDNSType_MD, // 3 Mail Destination 1785ffb0c9bSToomas Soome kDNSType_MF, // 4 Mail Forwarder 1795ffb0c9bSToomas Soome kDNSType_CNAME, // 5 Canonical Name 1805ffb0c9bSToomas Soome kDNSType_SOA, // 6 Start of Authority 1815ffb0c9bSToomas Soome kDNSType_MB, // 7 Mailbox 1825ffb0c9bSToomas Soome kDNSType_MG, // 8 Mail Group 1835ffb0c9bSToomas Soome kDNSType_MR, // 9 Mail Rename 1845ffb0c9bSToomas Soome kDNSType_NULL, // 10 NULL RR 1855ffb0c9bSToomas Soome kDNSType_WKS, // 11 Well-known-service 1865ffb0c9bSToomas Soome kDNSType_PTR, // 12 Domain name pointer 1875ffb0c9bSToomas Soome kDNSType_HINFO, // 13 Host information 1885ffb0c9bSToomas Soome kDNSType_MINFO, // 14 Mailbox information 1895ffb0c9bSToomas Soome kDNSType_MX, // 15 Mail Exchanger 1905ffb0c9bSToomas Soome kDNSType_TXT, // 16 Arbitrary text string 1915ffb0c9bSToomas Soome kDNSType_RP, // 17 Responsible person 1925ffb0c9bSToomas Soome kDNSType_AFSDB, // 18 AFS cell database 1935ffb0c9bSToomas Soome kDNSType_X25, // 19 X_25 calling address 1945ffb0c9bSToomas Soome kDNSType_ISDN, // 20 ISDN calling address 1955ffb0c9bSToomas Soome kDNSType_RT, // 21 Router 1965ffb0c9bSToomas Soome kDNSType_NSAP, // 22 NSAP address 1975ffb0c9bSToomas Soome kDNSType_NSAP_PTR, // 23 Reverse NSAP lookup (deprecated) 1985ffb0c9bSToomas Soome kDNSType_SIG, // 24 Security signature 1995ffb0c9bSToomas Soome kDNSType_KEY, // 25 Security key 2005ffb0c9bSToomas Soome kDNSType_PX, // 26 X.400 mail mapping 2015ffb0c9bSToomas Soome kDNSType_GPOS, // 27 Geographical position (withdrawn) 2025ffb0c9bSToomas Soome kDNSType_AAAA, // 28 IPv6 Address 2035ffb0c9bSToomas Soome kDNSType_LOC, // 29 Location Information 2045ffb0c9bSToomas Soome kDNSType_NXT, // 30 Next domain (security) 2055ffb0c9bSToomas Soome kDNSType_EID, // 31 Endpoint identifier 2065ffb0c9bSToomas Soome kDNSType_NIMLOC, // 32 Nimrod Locator 2075ffb0c9bSToomas Soome kDNSType_SRV, // 33 Service record 2085ffb0c9bSToomas Soome kDNSType_ATMA, // 34 ATM Address 2095ffb0c9bSToomas Soome kDNSType_NAPTR, // 35 Naming Authority PoinTeR 2105ffb0c9bSToomas Soome kDNSType_KX, // 36 Key Exchange 2115ffb0c9bSToomas Soome kDNSType_CERT, // 37 Certification record 2125ffb0c9bSToomas Soome kDNSType_A6, // 38 IPv6 Address (deprecated) 2135ffb0c9bSToomas Soome kDNSType_DNAME, // 39 Non-terminal DNAME (for IPv6) 2145ffb0c9bSToomas Soome kDNSType_SINK, // 40 Kitchen sink (experimental) 2155ffb0c9bSToomas Soome kDNSType_OPT, // 41 EDNS0 option (meta-RR) 2165ffb0c9bSToomas Soome kDNSType_APL, // 42 Address Prefix List 2175ffb0c9bSToomas Soome kDNSType_DS, // 43 Delegation Signer 2185ffb0c9bSToomas Soome kDNSType_SSHFP, // 44 SSH Key Fingerprint 2195ffb0c9bSToomas Soome kDNSType_IPSECKEY, // 45 IPSECKEY 2205ffb0c9bSToomas Soome kDNSType_RRSIG, // 46 RRSIG 2215ffb0c9bSToomas Soome kDNSType_NSEC, // 47 Denial of Existence 2225ffb0c9bSToomas Soome kDNSType_DNSKEY, // 48 DNSKEY 2235ffb0c9bSToomas Soome kDNSType_DHCID, // 49 DHCP Client Identifier 2245ffb0c9bSToomas Soome kDNSType_NSEC3, // 50 Hashed Authenticated Denial of Existence 2255ffb0c9bSToomas Soome kDNSType_NSEC3PARAM, // 51 Hashed Authenticated Denial of Existence 2265ffb0c9bSToomas Soome 2275ffb0c9bSToomas Soome kDNSType_HIP = 55, // 55 Host Identity Protocol 2285ffb0c9bSToomas Soome 2295ffb0c9bSToomas Soome kDNSType_SPF = 99, // 99 Sender Policy Framework for E-Mail 2305ffb0c9bSToomas Soome kDNSType_UINFO, // 100 IANA-Reserved 2315ffb0c9bSToomas Soome kDNSType_UID, // 101 IANA-Reserved 2325ffb0c9bSToomas Soome kDNSType_GID, // 102 IANA-Reserved 2335ffb0c9bSToomas Soome kDNSType_UNSPEC, // 103 IANA-Reserved 2345ffb0c9bSToomas Soome 2355ffb0c9bSToomas Soome kDNSType_TKEY = 249, // 249 Transaction key 2365ffb0c9bSToomas Soome kDNSType_TSIG, // 250 Transaction signature 2375ffb0c9bSToomas Soome kDNSType_IXFR, // 251 Incremental zone transfer 2385ffb0c9bSToomas Soome kDNSType_AXFR, // 252 Transfer zone of authority 2395ffb0c9bSToomas Soome kDNSType_MAILB, // 253 Transfer mailbox records 2405ffb0c9bSToomas Soome kDNSType_MAILA, // 254 Transfer mail agent records 2415ffb0c9bSToomas Soome kDNSQType_ANY // Not a DNS type, but a DNS query type, meaning "all types" 2425ffb0c9bSToomas Soome } DNS_TypeValues; 2434b22b933Srs 2444b22b933Srs // *************************************************************************** 2454b22b933Srs #if 0 2465ffb0c9bSToomas Soome #pragma mark - 2474b22b933Srs #pragma mark - Simple types 2484b22b933Srs #endif 2494b22b933Srs 2504b22b933Srs // mDNS defines its own names for these common types to simplify portability across 2514b22b933Srs // multiple platforms that may each have their own (different) names for these types. 2525ffb0c9bSToomas Soome typedef unsigned char mDNSBool; 2535ffb0c9bSToomas Soome typedef signed char mDNSs8; 2545ffb0c9bSToomas Soome typedef unsigned char mDNSu8; 2554b22b933Srs typedef signed short mDNSs16; 2564b22b933Srs typedef unsigned short mDNSu16; 2574b22b933Srs 2585ffb0c9bSToomas Soome // Source: http://www.unix.org/version2/whatsnew/lp64_wp.html 2595ffb0c9bSToomas Soome // http://software.intel.com/sites/products/documentation/hpc/mkl/lin/MKL_UG_structure/Support_for_ILP64_Programming.htm 2605ffb0c9bSToomas Soome // It can be safely assumed that int is 32bits on the platform 2614b22b933Srs #if defined(_ILP64) || defined(__ILP64__) 2624b22b933Srs typedef signed int32 mDNSs32; 2634b22b933Srs typedef unsigned int32 mDNSu32; 2644b22b933Srs #else 2655ffb0c9bSToomas Soome typedef signed int mDNSs32; 2665ffb0c9bSToomas Soome typedef unsigned int mDNSu32; 2674b22b933Srs #endif 2684b22b933Srs 2694b22b933Srs // To enforce useful type checking, we make mDNSInterfaceID be a pointer to a dummy struct 2704b22b933Srs // This way, mDNSInterfaceIDs can be assigned, and compared with each other, but not with other types 2714b22b933Srs // Declaring the type to be the typical generic "void *" would lack this type checking 2724b22b933Srs typedef struct mDNSInterfaceID_dummystruct { void *dummy; } *mDNSInterfaceID; 2734b22b933Srs 2744b22b933Srs // These types are for opaque two- and four-byte identifiers. 2754b22b933Srs // The "NotAnInteger" fields of the unions allow the value to be conveniently passed around in a 2764b22b933Srs // register for the sake of efficiency, and compared for equality or inequality, but don't forget -- 2774b22b933Srs // just because it is in a register doesn't mean it is an integer. Operations like greater than, 2784b22b933Srs // less than, add, multiply, increment, decrement, etc., are undefined for opaque identifiers, 2794b22b933Srs // and if you make the mistake of trying to do those using the NotAnInteger field, then you'll 2804b22b933Srs // find you get code that doesn't work consistently on big-endian and little-endian machines. 2815ffb0c9bSToomas Soome #if defined(_WIN32) 2825ffb0c9bSToomas Soome #pragma pack(push,2) 283*3b436d06SToomas Soome #elif !defined(__GNUC__) 284*3b436d06SToomas Soome #pragma pack(1) 2855ffb0c9bSToomas Soome #endif 2865ffb0c9bSToomas Soome typedef union { mDNSu8 b[ 2]; mDNSu16 NotAnInteger; } mDNSOpaque16; 2875ffb0c9bSToomas Soome typedef union { mDNSu8 b[ 4]; mDNSu32 NotAnInteger; } mDNSOpaque32; 2884b22b933Srs typedef packedunion { mDNSu8 b[ 6]; mDNSu16 w[3]; mDNSu32 l[1]; } mDNSOpaque48; 2895ffb0c9bSToomas Soome typedef union { mDNSu8 b[ 8]; mDNSu16 w[4]; mDNSu32 l[2]; } mDNSOpaque64; 2905ffb0c9bSToomas Soome typedef union { mDNSu8 b[16]; mDNSu16 w[8]; mDNSu32 l[4]; } mDNSOpaque128; 2915ffb0c9bSToomas Soome #if defined(_WIN32) 2925ffb0c9bSToomas Soome #pragma pack(pop) 293*3b436d06SToomas Soome #elif !defined(__GNUC__) 294*3b436d06SToomas Soome #pragma pack() 2955ffb0c9bSToomas Soome #endif 2965ffb0c9bSToomas Soome 2975ffb0c9bSToomas Soome typedef mDNSOpaque16 mDNSIPPort; // An IP port is a two-byte opaque identifier (not an integer) 2985ffb0c9bSToomas Soome typedef mDNSOpaque32 mDNSv4Addr; // An IP address is a four-byte opaque identifier (not an integer) 2995ffb0c9bSToomas Soome typedef mDNSOpaque128 mDNSv6Addr; // An IPv6 address is a 16-byte opaque identifier (not an integer) 3005ffb0c9bSToomas Soome typedef mDNSOpaque48 mDNSEthAddr; // An Ethernet address is a six-byte opaque identifier (not an integer) 3014b22b933Srs 3025ffb0c9bSToomas Soome // Bit operations for opaque 64 bit quantity. Uses the 32 bit quantity(l[2]) to set and clear bits 3035ffb0c9bSToomas Soome #define mDNSNBBY 8 3045ffb0c9bSToomas Soome #define bit_set_opaque64(op64, index) (op64.l[((index))/(sizeof(mDNSu32) * mDNSNBBY)] |= (1 << ((index) % (sizeof(mDNSu32) * mDNSNBBY)))) 3055ffb0c9bSToomas Soome #define bit_clr_opaque64(op64, index) (op64.l[((index))/(sizeof(mDNSu32) * mDNSNBBY)] &= ~(1 << ((index) % (sizeof(mDNSu32) * mDNSNBBY)))) 3065ffb0c9bSToomas Soome #define bit_get_opaque64(op64, index) (op64.l[((index))/(sizeof(mDNSu32) * mDNSNBBY)] & (1 << ((index) % (sizeof(mDNSu32) * mDNSNBBY)))) 3074b22b933Srs 308c65ebfc7SToomas Soome // Bit operations for opaque 128 bit quantity. Uses the 32 bit quantity(l[4]) to set and clear bits 309c65ebfc7SToomas Soome #define bit_set_opaque128(op128, index) (op128.l[((index))/(sizeof(mDNSu32) * mDNSNBBY)] |= (1 << ((index) % (sizeof(mDNSu32) * mDNSNBBY)))) 310c65ebfc7SToomas Soome #define bit_clr_opaque128(op128, index) (op128.l[((index))/(sizeof(mDNSu32) * mDNSNBBY)] &= ~(1 << ((index) % (sizeof(mDNSu32) * mDNSNBBY)))) 311c65ebfc7SToomas Soome #define bit_get_opaque128(op128, index) (op128.l[((index))/(sizeof(mDNSu32) * mDNSNBBY)] & (1 << ((index) % (sizeof(mDNSu32) * mDNSNBBY)))) 312c65ebfc7SToomas Soome 313c65ebfc7SToomas Soome typedef enum 3145ffb0c9bSToomas Soome { 3155ffb0c9bSToomas Soome mDNSAddrType_None = 0, 3165ffb0c9bSToomas Soome mDNSAddrType_IPv4 = 4, 3175ffb0c9bSToomas Soome mDNSAddrType_IPv6 = 6, 3185ffb0c9bSToomas Soome mDNSAddrType_Unknown = ~0 // Special marker value used in known answer list recording 319c65ebfc7SToomas Soome } mDNSAddr_Type; 3205ffb0c9bSToomas Soome 321c65ebfc7SToomas Soome typedef enum 3225ffb0c9bSToomas Soome { 3235ffb0c9bSToomas Soome mDNSTransport_None = 0, 3245ffb0c9bSToomas Soome mDNSTransport_UDP = 1, 3255ffb0c9bSToomas Soome mDNSTransport_TCP = 2 326c65ebfc7SToomas Soome } mDNSTransport_Type; 3274b22b933Srs 3284b22b933Srs typedef struct 3295ffb0c9bSToomas Soome { 3305ffb0c9bSToomas Soome mDNSs32 type; 3315ffb0c9bSToomas Soome union { mDNSv6Addr v6; mDNSv4Addr v4; } ip; 3325ffb0c9bSToomas Soome } mDNSAddr; 3334b22b933Srs 3344b22b933Srs enum { mDNSfalse = 0, mDNStrue = 1 }; 3354b22b933Srs 3364b22b933Srs #define mDNSNULL 0L 3374b22b933Srs 3384b22b933Srs enum 3395ffb0c9bSToomas Soome { 3405ffb0c9bSToomas Soome mStatus_Waiting = 1, 3415ffb0c9bSToomas Soome mStatus_NoError = 0, 3425ffb0c9bSToomas Soome 3435ffb0c9bSToomas Soome // mDNS return values are in the range FFFE FF00 (-65792) to FFFE FFFF (-65537) 3445ffb0c9bSToomas Soome // The top end of the range (FFFE FFFF) is used for error codes; 3455ffb0c9bSToomas Soome // the bottom end of the range (FFFE FF00) is used for non-error values; 3465ffb0c9bSToomas Soome 3475ffb0c9bSToomas Soome // Error codes: 3485ffb0c9bSToomas Soome mStatus_UnknownErr = -65537, // First value: 0xFFFE FFFF 3495ffb0c9bSToomas Soome mStatus_NoSuchNameErr = -65538, 3505ffb0c9bSToomas Soome mStatus_NoMemoryErr = -65539, 3515ffb0c9bSToomas Soome mStatus_BadParamErr = -65540, 3525ffb0c9bSToomas Soome mStatus_BadReferenceErr = -65541, 3535ffb0c9bSToomas Soome mStatus_BadStateErr = -65542, 3545ffb0c9bSToomas Soome mStatus_BadFlagsErr = -65543, 3555ffb0c9bSToomas Soome mStatus_UnsupportedErr = -65544, 3565ffb0c9bSToomas Soome mStatus_NotInitializedErr = -65545, 3575ffb0c9bSToomas Soome mStatus_NoCache = -65546, 3585ffb0c9bSToomas Soome mStatus_AlreadyRegistered = -65547, 3595ffb0c9bSToomas Soome mStatus_NameConflict = -65548, 3605ffb0c9bSToomas Soome mStatus_Invalid = -65549, 3615ffb0c9bSToomas Soome mStatus_Firewall = -65550, 3625ffb0c9bSToomas Soome mStatus_Incompatible = -65551, 3635ffb0c9bSToomas Soome mStatus_BadInterfaceErr = -65552, 3645ffb0c9bSToomas Soome mStatus_Refused = -65553, 3655ffb0c9bSToomas Soome mStatus_NoSuchRecord = -65554, 3665ffb0c9bSToomas Soome mStatus_NoAuth = -65555, 3675ffb0c9bSToomas Soome mStatus_NoSuchKey = -65556, 3685ffb0c9bSToomas Soome mStatus_NATTraversal = -65557, 3695ffb0c9bSToomas Soome mStatus_DoubleNAT = -65558, 3705ffb0c9bSToomas Soome mStatus_BadTime = -65559, 3715ffb0c9bSToomas Soome mStatus_BadSig = -65560, // while we define this per RFC 2845, BIND 9 returns Refused for bad/missing signatures 3725ffb0c9bSToomas Soome mStatus_BadKey = -65561, 3735ffb0c9bSToomas Soome mStatus_TransientErr = -65562, // transient failures, e.g. sending packets shortly after a network transition or wake from sleep 3745ffb0c9bSToomas Soome mStatus_ServiceNotRunning = -65563, // Background daemon not running 3755ffb0c9bSToomas Soome mStatus_NATPortMappingUnsupported = -65564, // NAT doesn't support PCP, NAT-PMP or UPnP 3765ffb0c9bSToomas Soome mStatus_NATPortMappingDisabled = -65565, // NAT supports PCP, NAT-PMP or UPnP, but it's disabled by the administrator 3775ffb0c9bSToomas Soome mStatus_NoRouter = -65566, 3785ffb0c9bSToomas Soome mStatus_PollingMode = -65567, 3795ffb0c9bSToomas Soome mStatus_Timeout = -65568, 380c65ebfc7SToomas Soome mStatus_HostUnreachErr = -65569, 381c65ebfc7SToomas Soome // -65570 to -65786 currently unused; available for allocation 3825ffb0c9bSToomas Soome 3835ffb0c9bSToomas Soome // tcp connection status 3845ffb0c9bSToomas Soome mStatus_ConnPending = -65787, 3855ffb0c9bSToomas Soome mStatus_ConnFailed = -65788, 3865ffb0c9bSToomas Soome mStatus_ConnEstablished = -65789, 3875ffb0c9bSToomas Soome 3885ffb0c9bSToomas Soome // Non-error values: 3895ffb0c9bSToomas Soome mStatus_GrowCache = -65790, 3905ffb0c9bSToomas Soome mStatus_ConfigChanged = -65791, 3915ffb0c9bSToomas Soome mStatus_MemFree = -65792 // Last value: 0xFFFE FF00 3925ffb0c9bSToomas Soome // mStatus_MemFree is the last legal mDNS error code, at the end of the range allocated for mDNS 3935ffb0c9bSToomas Soome }; 3944b22b933Srs 3954b22b933Srs typedef mDNSs32 mStatus; 3965ffb0c9bSToomas Soome #define MaxIp 5 // Needs to be consistent with MaxInputIf in dns_services.h 3975ffb0c9bSToomas Soome 3985ffb0c9bSToomas Soome typedef enum { q_stop = 0, q_start } q_state; 3995ffb0c9bSToomas Soome typedef enum { reg_stop = 0, reg_start } reg_state; 4004b22b933Srs 4014b22b933Srs // RFC 1034/1035 specify that a domain label consists of a length byte plus up to 63 characters 4024b22b933Srs #define MAX_DOMAIN_LABEL 63 4035ffb0c9bSToomas Soome typedef struct { mDNSu8 c[ 64]; } domainlabel; // One label: length byte and up to 63 characters 4044b22b933Srs 4055ffb0c9bSToomas Soome // RFC 1034/1035/2181 specify that a domain name (length bytes and data bytes) may be up to 255 bytes long, 4065ffb0c9bSToomas Soome // plus the terminating zero at the end makes 256 bytes total in the on-the-wire format. 4075ffb0c9bSToomas Soome #define MAX_DOMAIN_NAME 256 4085ffb0c9bSToomas Soome typedef struct { mDNSu8 c[256]; } domainname; // Up to 256 bytes of length-prefixed domainlabels 4094b22b933Srs 4105ffb0c9bSToomas Soome typedef struct { mDNSu8 c[256]; } UTF8str255; // Null-terminated C string 4114b22b933Srs 4125ffb0c9bSToomas Soome // The longest legal textual form of a DNS name is 1009 bytes, including the C-string terminating NULL at the end. 4134b22b933Srs // Explanation: 4144b22b933Srs // When a native domainname object is converted to printable textual form using ConvertDomainNameToCString(), 4154b22b933Srs // non-printing characters are represented in the conventional DNS way, as '\ddd', where ddd is a three-digit decimal number. 4165ffb0c9bSToomas Soome // The longest legal domain name is 256 bytes, in the form of four labels as shown below: 4175ffb0c9bSToomas Soome // Length byte, 63 data bytes, length byte, 63 data bytes, length byte, 63 data bytes, length byte, 62 data bytes, zero byte. 4184b22b933Srs // Each label is encoded textually as characters followed by a trailing dot. 4194b22b933Srs // If every character has to be represented as a four-byte escape sequence, then this makes the maximum textual form four labels 4204b22b933Srs // plus the C-string terminating NULL as shown below: 4215ffb0c9bSToomas Soome // 63*4+1 + 63*4+1 + 63*4+1 + 62*4+1 + 1 = 1009. 4224b22b933Srs // Note that MAX_ESCAPED_DOMAIN_LABEL is not normally used: If you're only decoding a single label, escaping is usually not required. 4234b22b933Srs // It is for domain names, where dots are used as label separators, that proper escaping is vital. 4244b22b933Srs #define MAX_ESCAPED_DOMAIN_LABEL 254 4255ffb0c9bSToomas Soome #define MAX_ESCAPED_DOMAIN_NAME 1009 4265ffb0c9bSToomas Soome 4275ffb0c9bSToomas Soome // MAX_REVERSE_MAPPING_NAME 4285ffb0c9bSToomas Soome // For IPv4: "123.123.123.123.in-addr.arpa." 30 bytes including terminating NUL 4295ffb0c9bSToomas Soome // 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 4305ffb0c9bSToomas Soome 4315ffb0c9bSToomas Soome #define MAX_REVERSE_MAPPING_NAME_V4 30 4325ffb0c9bSToomas Soome #define MAX_REVERSE_MAPPING_NAME_V6 74 4335ffb0c9bSToomas Soome #define MAX_REVERSE_MAPPING_NAME 74 4344b22b933Srs 4354b22b933Srs // Most records have a TTL of 75 minutes, so that their 80% cache-renewal query occurs once per hour. 4364b22b933Srs // For records containing a hostname (in the name on the left, or in the rdata on the right), 4374b22b933Srs // like A, AAAA, reverse-mapping PTR, and SRV, we use a two-minute TTL by default, because we don't want 4384b22b933Srs // them to hang around for too long in the cache if the host in question crashes or otherwise goes away. 4395ffb0c9bSToomas Soome 4404b22b933Srs #define kStandardTTL (3600UL * 100 / 80) 4414b22b933Srs #define kHostNameTTL 120UL 4425ffb0c9bSToomas Soome 4435ffb0c9bSToomas Soome // Some applications want to register their SRV records with a lower ttl so that in case the server 4445ffb0c9bSToomas Soome // using a dynamic port number restarts, the clients will not have stale information for more than 4455ffb0c9bSToomas Soome // 10 seconds 4465ffb0c9bSToomas Soome 4475ffb0c9bSToomas Soome #define kHostNameSmallTTL 10UL 4485ffb0c9bSToomas Soome 4495ffb0c9bSToomas Soome 4505ffb0c9bSToomas Soome // Multicast DNS uses announcements (gratuitous responses) to update peer caches. 4515ffb0c9bSToomas Soome // This means it is feasible to use relatively larger TTL values than we might otherwise 4525ffb0c9bSToomas Soome // use, because we have a cache coherency protocol to keep the peer caches up to date. 4535ffb0c9bSToomas Soome // With Unicast DNS, once an authoritative server gives a record with a certain TTL value to a client 4545ffb0c9bSToomas Soome // or caching server, that client or caching server is entitled to hold onto the record until its TTL 4555ffb0c9bSToomas Soome // expires, and has no obligation to contact the authoritative server again until that time arrives. 4565ffb0c9bSToomas Soome // This means that whereas Multicast DNS can use announcements to pre-emptively update stale data 4575ffb0c9bSToomas Soome // before it would otherwise have expired, standard Unicast DNS (not using LLQs) has no equivalent 4585ffb0c9bSToomas Soome // mechanism, and TTL expiry is the *only* mechanism by which stale data gets deleted. Because of this, 4595ffb0c9bSToomas Soome // we currently limit the TTL to ten seconds in such cases where no dynamic cache updating is possible. 4605ffb0c9bSToomas Soome #define kStaticCacheTTL 10 4614b22b933Srs 4624b22b933Srs #define DefaultTTLforRRType(X) (((X) == kDNSType_A || (X) == kDNSType_AAAA || (X) == kDNSType_SRV) ? kHostNameTTL : kStandardTTL) 4635ffb0c9bSToomas Soome #define mDNS_KeepaliveRecord(rr) ((rr)->rrtype == kDNSType_NULL && SameDomainLabel(SecondLabel((rr)->name)->c, (mDNSu8 *)"\x0A_keepalive")) 4645ffb0c9bSToomas Soome 4655ffb0c9bSToomas Soome // Number of times keepalives are sent if no ACK is received before waking up the system 4665ffb0c9bSToomas Soome // this is analogous to net.inet.tcp.keepcnt 4675ffb0c9bSToomas Soome #define kKeepaliveRetryCount 10 4685ffb0c9bSToomas Soome // The frequency at which keepalives are retried if no ACK is received 4695ffb0c9bSToomas Soome #define kKeepaliveRetryInterval 30 4705ffb0c9bSToomas Soome 4715ffb0c9bSToomas Soome typedef struct AuthRecord_struct AuthRecord; 4725ffb0c9bSToomas Soome typedef struct ServiceRecordSet_struct ServiceRecordSet; 4735ffb0c9bSToomas Soome typedef struct CacheRecord_struct CacheRecord; 4745ffb0c9bSToomas Soome typedef struct CacheGroup_struct CacheGroup; 4755ffb0c9bSToomas Soome typedef struct AuthGroup_struct AuthGroup; 4765ffb0c9bSToomas Soome typedef struct DNSQuestion_struct DNSQuestion; 4775ffb0c9bSToomas Soome typedef struct ZoneData_struct ZoneData; 4785ffb0c9bSToomas Soome typedef struct mDNS_struct mDNS; 4795ffb0c9bSToomas Soome typedef struct mDNS_PlatformSupport_struct mDNS_PlatformSupport; 4805ffb0c9bSToomas Soome typedef struct NATTraversalInfo_struct NATTraversalInfo; 4815ffb0c9bSToomas Soome typedef struct ResourceRecord_struct ResourceRecord; 4825ffb0c9bSToomas Soome 4835ffb0c9bSToomas Soome // Structure to abstract away the differences between TCP/SSL sockets, and one for UDP sockets 4845ffb0c9bSToomas Soome // The actual definition of these structures appear in the appropriate platform support code 4855ffb0c9bSToomas Soome typedef struct TCPSocket_struct TCPSocket; 4865ffb0c9bSToomas Soome typedef struct UDPSocket_struct UDPSocket; 4874b22b933Srs 4884b22b933Srs // *************************************************************************** 4894b22b933Srs #if 0 4905ffb0c9bSToomas Soome #pragma mark - 4914b22b933Srs #pragma mark - DNS Message structures 4924b22b933Srs #endif 4934b22b933Srs 4944b22b933Srs #define mDNS_numZones numQuestions 4954b22b933Srs #define mDNS_numPrereqs numAnswers 4964b22b933Srs #define mDNS_numUpdates numAuthorities 4974b22b933Srs 498c65ebfc7SToomas Soome typedef struct 4995ffb0c9bSToomas Soome { 5005ffb0c9bSToomas Soome mDNSOpaque16 id; 5015ffb0c9bSToomas Soome mDNSOpaque16 flags; 5025ffb0c9bSToomas Soome mDNSu16 numQuestions; 5035ffb0c9bSToomas Soome mDNSu16 numAnswers; 5045ffb0c9bSToomas Soome mDNSu16 numAuthorities; 5055ffb0c9bSToomas Soome mDNSu16 numAdditionals; 5065ffb0c9bSToomas Soome } DNSMessageHeader; 5074b22b933Srs 5084b22b933Srs // We can send and receive packets up to 9000 bytes (Ethernet Jumbo Frame size, if that ever becomes widely used) 5094b22b933Srs // However, in the normal case we try to limit packets to 1500 bytes so that we don't get IP fragmentation on standard Ethernet 5104b22b933Srs // 40 (IPv6 header) + 8 (UDP header) + 12 (DNS message header) + 1440 (DNS message body) = 1500 total 5115ffb0c9bSToomas Soome #ifndef AbsoluteMaxDNSMessageData 5124b22b933Srs #define AbsoluteMaxDNSMessageData 8940 5135ffb0c9bSToomas Soome #endif 5144b22b933Srs #define NormalMaxDNSMessageData 1440 515c65ebfc7SToomas Soome typedef struct 5165ffb0c9bSToomas Soome { 5175ffb0c9bSToomas Soome DNSMessageHeader h; // Note: Size 12 bytes 5185ffb0c9bSToomas Soome mDNSu8 data[AbsoluteMaxDNSMessageData]; // 40 (IPv6) + 8 (UDP) + 12 (DNS header) + 8940 (data) = 9000 5195ffb0c9bSToomas Soome } DNSMessage; 5205ffb0c9bSToomas Soome 5215ffb0c9bSToomas Soome typedef struct tcpInfo_t 5225ffb0c9bSToomas Soome { 5235ffb0c9bSToomas Soome mDNS *m; 5245ffb0c9bSToomas Soome TCPSocket *sock; 5255ffb0c9bSToomas Soome DNSMessage request; 5265ffb0c9bSToomas Soome int requestLen; 5275ffb0c9bSToomas Soome DNSQuestion *question; // For queries 5285ffb0c9bSToomas Soome AuthRecord *rr; // For record updates 5295ffb0c9bSToomas Soome mDNSAddr Addr; 5305ffb0c9bSToomas Soome mDNSIPPort Port; 5315ffb0c9bSToomas Soome mDNSIPPort SrcPort; 5325ffb0c9bSToomas Soome DNSMessage *reply; 5335ffb0c9bSToomas Soome mDNSu16 replylen; 5345ffb0c9bSToomas Soome unsigned long nread; 5355ffb0c9bSToomas Soome int numReplies; 5365ffb0c9bSToomas Soome } tcpInfo_t; 5375ffb0c9bSToomas Soome 5385ffb0c9bSToomas Soome // *************************************************************************** 5395ffb0c9bSToomas Soome #if 0 5405ffb0c9bSToomas Soome #pragma mark - 5415ffb0c9bSToomas Soome #pragma mark - Other Packet Format Structures 5425ffb0c9bSToomas Soome #endif 5435ffb0c9bSToomas Soome 5445ffb0c9bSToomas Soome typedef packedstruct 5455ffb0c9bSToomas Soome { 5465ffb0c9bSToomas Soome mDNSEthAddr dst; 5475ffb0c9bSToomas Soome mDNSEthAddr src; 5485ffb0c9bSToomas Soome mDNSOpaque16 ethertype; 5495ffb0c9bSToomas Soome } EthernetHeader; // 14 bytes 5505ffb0c9bSToomas Soome 5515ffb0c9bSToomas Soome typedef packedstruct 5525ffb0c9bSToomas Soome { 5535ffb0c9bSToomas Soome mDNSOpaque16 hrd; 5545ffb0c9bSToomas Soome mDNSOpaque16 pro; 5555ffb0c9bSToomas Soome mDNSu8 hln; 5565ffb0c9bSToomas Soome mDNSu8 pln; 5575ffb0c9bSToomas Soome mDNSOpaque16 op; 5585ffb0c9bSToomas Soome mDNSEthAddr sha; 5595ffb0c9bSToomas Soome mDNSv4Addr spa; 5605ffb0c9bSToomas Soome mDNSEthAddr tha; 5615ffb0c9bSToomas Soome mDNSv4Addr tpa; 5625ffb0c9bSToomas Soome } ARP_EthIP; // 28 bytes 5635ffb0c9bSToomas Soome 5645ffb0c9bSToomas Soome typedef packedstruct 5655ffb0c9bSToomas Soome { 5665ffb0c9bSToomas Soome mDNSu8 vlen; 5675ffb0c9bSToomas Soome mDNSu8 tos; 568cda73f64SToomas Soome mDNSOpaque16 totlen; 5695ffb0c9bSToomas Soome mDNSOpaque16 id; 5705ffb0c9bSToomas Soome mDNSOpaque16 flagsfrags; 5715ffb0c9bSToomas Soome mDNSu8 ttl; 5725ffb0c9bSToomas Soome mDNSu8 protocol; // Payload type: 0x06 = TCP, 0x11 = UDP 5735ffb0c9bSToomas Soome mDNSu16 checksum; 5745ffb0c9bSToomas Soome mDNSv4Addr src; 5755ffb0c9bSToomas Soome mDNSv4Addr dst; 5765ffb0c9bSToomas Soome } IPv4Header; // 20 bytes 5775ffb0c9bSToomas Soome 5785ffb0c9bSToomas Soome typedef packedstruct 5795ffb0c9bSToomas Soome { 5805ffb0c9bSToomas Soome mDNSu32 vcf; // Version, Traffic Class, Flow Label 5815ffb0c9bSToomas Soome mDNSu16 len; // Payload Length 5825ffb0c9bSToomas Soome mDNSu8 pro; // Type of next header: 0x06 = TCP, 0x11 = UDP, 0x3A = ICMPv6 5835ffb0c9bSToomas Soome mDNSu8 ttl; // Hop Limit 5845ffb0c9bSToomas Soome mDNSv6Addr src; 5855ffb0c9bSToomas Soome mDNSv6Addr dst; 5865ffb0c9bSToomas Soome } IPv6Header; // 40 bytes 5875ffb0c9bSToomas Soome 5885ffb0c9bSToomas Soome typedef packedstruct 5895ffb0c9bSToomas Soome { 5905ffb0c9bSToomas Soome mDNSv6Addr src; 5915ffb0c9bSToomas Soome mDNSv6Addr dst; 5925ffb0c9bSToomas Soome mDNSOpaque32 len; 5935ffb0c9bSToomas Soome mDNSOpaque32 pro; 5945ffb0c9bSToomas Soome } IPv6PseudoHeader; // 40 bytes 5955ffb0c9bSToomas Soome 5965ffb0c9bSToomas Soome typedef union 5975ffb0c9bSToomas Soome { 5985ffb0c9bSToomas Soome mDNSu8 bytes[20]; 5995ffb0c9bSToomas Soome ARP_EthIP arp; 6005ffb0c9bSToomas Soome IPv4Header v4; 6015ffb0c9bSToomas Soome IPv6Header v6; 6025ffb0c9bSToomas Soome } NetworkLayerPacket; 6035ffb0c9bSToomas Soome 6045ffb0c9bSToomas Soome typedef packedstruct 6055ffb0c9bSToomas Soome { 6065ffb0c9bSToomas Soome mDNSIPPort src; 6075ffb0c9bSToomas Soome mDNSIPPort dst; 6085ffb0c9bSToomas Soome mDNSu32 seq; 6095ffb0c9bSToomas Soome mDNSu32 ack; 6105ffb0c9bSToomas Soome mDNSu8 offset; 6115ffb0c9bSToomas Soome mDNSu8 flags; 6125ffb0c9bSToomas Soome mDNSu16 window; 6135ffb0c9bSToomas Soome mDNSu16 checksum; 6145ffb0c9bSToomas Soome mDNSu16 urgent; 6155ffb0c9bSToomas Soome } TCPHeader; // 20 bytes; IP protocol type 0x06 6165ffb0c9bSToomas Soome 6175ffb0c9bSToomas Soome typedef struct 6185ffb0c9bSToomas Soome { 6195ffb0c9bSToomas Soome mDNSInterfaceID IntfId; 6205ffb0c9bSToomas Soome mDNSu32 seq; 6215ffb0c9bSToomas Soome mDNSu32 ack; 6225ffb0c9bSToomas Soome mDNSu16 window; 6235ffb0c9bSToomas Soome } mDNSTCPInfo; 6245ffb0c9bSToomas Soome 6255ffb0c9bSToomas Soome typedef packedstruct 6265ffb0c9bSToomas Soome { 6275ffb0c9bSToomas Soome mDNSIPPort src; 6285ffb0c9bSToomas Soome mDNSIPPort dst; 6295ffb0c9bSToomas Soome mDNSu16 len; // Length including UDP header (i.e. minimum value is 8 bytes) 6305ffb0c9bSToomas Soome mDNSu16 checksum; 6315ffb0c9bSToomas Soome } UDPHeader; // 8 bytes; IP protocol type 0x11 6325ffb0c9bSToomas Soome 633c65ebfc7SToomas Soome typedef struct 6345ffb0c9bSToomas Soome { 6355ffb0c9bSToomas Soome mDNSu8 type; // 0x87 == Neighbor Solicitation, 0x88 == Neighbor Advertisement 6365ffb0c9bSToomas Soome mDNSu8 code; 6375ffb0c9bSToomas Soome mDNSu16 checksum; 6385ffb0c9bSToomas Soome mDNSu32 flags_res; // R/S/O flags and reserved bits 6395ffb0c9bSToomas Soome mDNSv6Addr target; 6405ffb0c9bSToomas Soome // Typically 8 bytes of options are also present 6415ffb0c9bSToomas Soome } IPv6NDP; // 24 bytes or more; IP protocol type 0x3A 6425ffb0c9bSToomas Soome 6435ffb0c9bSToomas Soome typedef struct 6445ffb0c9bSToomas Soome { 6455ffb0c9bSToomas Soome mDNSAddr ipaddr; 6465ffb0c9bSToomas Soome char ethaddr[18]; 6475ffb0c9bSToomas Soome } IPAddressMACMapping; 6485ffb0c9bSToomas Soome 6495ffb0c9bSToomas Soome #define NDP_Sol 0x87 6505ffb0c9bSToomas Soome #define NDP_Adv 0x88 6515ffb0c9bSToomas Soome 6525ffb0c9bSToomas Soome #define NDP_Router 0x80 6535ffb0c9bSToomas Soome #define NDP_Solicited 0x40 6545ffb0c9bSToomas Soome #define NDP_Override 0x20 6555ffb0c9bSToomas Soome 6565ffb0c9bSToomas Soome #define NDP_SrcLL 1 6575ffb0c9bSToomas Soome #define NDP_TgtLL 2 6585ffb0c9bSToomas Soome 6595ffb0c9bSToomas Soome typedef union 6605ffb0c9bSToomas Soome { 6615ffb0c9bSToomas Soome mDNSu8 bytes[20]; 6625ffb0c9bSToomas Soome TCPHeader tcp; 6635ffb0c9bSToomas Soome UDPHeader udp; 6645ffb0c9bSToomas Soome IPv6NDP ndp; 6655ffb0c9bSToomas Soome } TransportLayerPacket; 6665ffb0c9bSToomas Soome 6675ffb0c9bSToomas Soome typedef packedstruct 6685ffb0c9bSToomas Soome { 6695ffb0c9bSToomas Soome mDNSOpaque64 InitiatorCookie; 6705ffb0c9bSToomas Soome mDNSOpaque64 ResponderCookie; 6715ffb0c9bSToomas Soome mDNSu8 NextPayload; 6725ffb0c9bSToomas Soome mDNSu8 Version; 6735ffb0c9bSToomas Soome mDNSu8 ExchangeType; 6745ffb0c9bSToomas Soome mDNSu8 Flags; 6755ffb0c9bSToomas Soome mDNSOpaque32 MessageID; 6765ffb0c9bSToomas Soome mDNSu32 Length; 6775ffb0c9bSToomas Soome } IKEHeader; // 28 bytes 6784b22b933Srs 6794b22b933Srs // *************************************************************************** 6804b22b933Srs #if 0 6815ffb0c9bSToomas Soome #pragma mark - 6824b22b933Srs #pragma mark - Resource Record structures 6834b22b933Srs #endif 6844b22b933Srs 6854b22b933Srs // Authoritative Resource Records: 6864b22b933Srs // There are four basic types: Shared, Advisory, Unique, Known Unique 6874b22b933Srs 6884b22b933Srs // * Shared Resource Records do not have to be unique 6894b22b933Srs // -- Shared Resource Records are used for DNS-SD service PTRs 6904b22b933Srs // -- It is okay for several hosts to have RRs with the same name but different RDATA 6914b22b933Srs // -- We use a random delay on responses to reduce collisions when all the hosts respond to the same query 6924b22b933Srs // -- These RRs typically have moderately high TTLs (e.g. one hour) 6934b22b933Srs // -- These records are announced on startup and topology changes for the benefit of passive listeners 6944b22b933Srs // -- These records send a goodbye packet when deregistering 6954b22b933Srs // 6964b22b933Srs // * Advisory Resource Records are like Shared Resource Records, except they don't send a goodbye packet 6974b22b933Srs // 6984b22b933Srs // * Unique Resource Records should be unique among hosts within any given mDNS scope 6994b22b933Srs // -- The majority of Resource Records are of this type 7004b22b933Srs // -- If two entities on the network have RRs with the same name but different RDATA, this is a conflict 7014b22b933Srs // -- Responses may be sent immediately, because only one host should be responding to any particular query 7024b22b933Srs // -- These RRs typically have low TTLs (e.g. a few minutes) 7034b22b933Srs // -- On startup and after topology changes, a host issues queries to verify uniqueness 7044b22b933Srs 7054b22b933Srs // * Known Unique Resource Records are treated like Unique Resource Records, except that mDNS does 7064b22b933Srs // not have to verify their uniqueness because this is already known by other means (e.g. the RR name 7074b22b933Srs // is derived from the host's IP or Ethernet address, which is already known to be a unique identifier). 7084b22b933Srs 7094b22b933Srs // Summary of properties of different record types: 7104b22b933Srs // Probe? Does this record type send probes before announcing? 7114b22b933Srs // Conflict? Does this record type react if we observe an apparent conflict? 7124b22b933Srs // Goodbye? Does this record type send a goodbye packet on departure? 7134b22b933Srs // 7144b22b933Srs // Probe? Conflict? Goodbye? Notes 7154b22b933Srs // Unregistered Should not appear in any list (sanity check value) 7164b22b933Srs // Shared No No Yes e.g. Service PTR record 7174b22b933Srs // Deregistering No No Yes Shared record about to announce its departure and leave the list 7184b22b933Srs // Advisory No No No 7194b22b933Srs // Unique Yes Yes No Record intended to be unique -- will probe to verify 7204b22b933Srs // Verified Yes Yes No Record has completed probing, and is verified unique 7214b22b933Srs // KnownUnique No Yes No Record is assumed by other means to be unique 7224b22b933Srs 7234b22b933Srs // Valid lifecycle of a record: 7244b22b933Srs // Unregistered -> Shared -> Deregistering -(goodbye)-> Unregistered 7254b22b933Srs // Unregistered -> Advisory -> Unregistered 7264b22b933Srs // Unregistered -> Unique -(probe)-> Verified -> Unregistered 7274b22b933Srs // Unregistered -> KnownUnique -> Unregistered 7284b22b933Srs 7294b22b933Srs // Each Authoritative kDNSRecordType has only one bit set. This makes it easy to quickly see if a record 7304b22b933Srs // is one of a particular set of types simply by performing the appropriate bitwise masking operation. 7314b22b933Srs 7325ffb0c9bSToomas Soome // Cache Resource Records (received from the network): 7335ffb0c9bSToomas Soome // There are four basic types: Answer, Unique Answer, Additional, Unique Additional 7345ffb0c9bSToomas Soome // Bit 7 (the top bit) of kDNSRecordType is always set for Cache Resource Records; always clear for Authoritative Resource Records 7355ffb0c9bSToomas Soome // Bit 6 (value 0x40) is set for answer records; clear for authority/additional records 7365ffb0c9bSToomas Soome // Bit 5 (value 0x20) is set for records received with the kDNSClass_UniqueRRSet 7375ffb0c9bSToomas Soome 738c65ebfc7SToomas Soome typedef enum 7395ffb0c9bSToomas Soome { 7405ffb0c9bSToomas Soome kDNSRecordTypeUnregistered = 0x00, // Not currently in any list 7415ffb0c9bSToomas Soome kDNSRecordTypeDeregistering = 0x01, // Shared record about to announce its departure and leave the list 7425ffb0c9bSToomas Soome 7435ffb0c9bSToomas Soome kDNSRecordTypeUnique = 0x02, // Will become a kDNSRecordTypeVerified when probing is complete 7445ffb0c9bSToomas Soome 7455ffb0c9bSToomas Soome kDNSRecordTypeAdvisory = 0x04, // Like Shared, but no goodbye packet 7465ffb0c9bSToomas Soome kDNSRecordTypeShared = 0x08, // Shared means record name does not have to be unique -- use random delay on responses 7475ffb0c9bSToomas Soome 7485ffb0c9bSToomas Soome kDNSRecordTypeVerified = 0x10, // Unique means mDNS should check that name is unique (and then send immediate responses) 7495ffb0c9bSToomas Soome kDNSRecordTypeKnownUnique = 0x20, // Known Unique means mDNS can assume name is unique without checking 7505ffb0c9bSToomas Soome // For Dynamic Update records, Known Unique means the record must already exist on the server. 7515ffb0c9bSToomas Soome kDNSRecordTypeUniqueMask = (kDNSRecordTypeUnique | kDNSRecordTypeVerified | kDNSRecordTypeKnownUnique), 7525ffb0c9bSToomas Soome kDNSRecordTypeActiveSharedMask = (kDNSRecordTypeAdvisory | kDNSRecordTypeShared), 7535ffb0c9bSToomas Soome kDNSRecordTypeActiveUniqueMask = (kDNSRecordTypeVerified | kDNSRecordTypeKnownUnique), 7545ffb0c9bSToomas Soome kDNSRecordTypeActiveMask = (kDNSRecordTypeActiveSharedMask | kDNSRecordTypeActiveUniqueMask), 7555ffb0c9bSToomas Soome 7565ffb0c9bSToomas Soome kDNSRecordTypePacketAdd = 0x80, // Received in the Additional Section of a DNS Response 7575ffb0c9bSToomas Soome kDNSRecordTypePacketAddUnique = 0x90, // Received in the Additional Section of a DNS Response with kDNSClass_UniqueRRSet set 7585ffb0c9bSToomas Soome kDNSRecordTypePacketAuth = 0xA0, // Received in the Authorities Section of a DNS Response 7595ffb0c9bSToomas Soome kDNSRecordTypePacketAuthUnique = 0xB0, // Received in the Authorities Section of a DNS Response with kDNSClass_UniqueRRSet set 7605ffb0c9bSToomas Soome kDNSRecordTypePacketAns = 0xC0, // Received in the Answer Section of a DNS Response 7615ffb0c9bSToomas Soome kDNSRecordTypePacketAnsUnique = 0xD0, // Received in the Answer Section of a DNS Response with kDNSClass_UniqueRRSet set 7625ffb0c9bSToomas Soome 7635ffb0c9bSToomas Soome kDNSRecordTypePacketNegative = 0xF0, // Pseudo-RR generated to cache non-existence results like NXDomain 7645ffb0c9bSToomas Soome 7655ffb0c9bSToomas Soome kDNSRecordTypePacketUniqueMask = 0x10 // True for PacketAddUnique, PacketAnsUnique, PacketAuthUnique, kDNSRecordTypePacketNegative 766c65ebfc7SToomas Soome } kDNSRecordTypes; 7675ffb0c9bSToomas Soome 7685ffb0c9bSToomas Soome typedef packedstruct { mDNSu16 priority; mDNSu16 weight; mDNSIPPort port; domainname target; } rdataSRV; 7695ffb0c9bSToomas Soome typedef packedstruct { mDNSu16 preference; domainname exchange; } rdataMX; 7705ffb0c9bSToomas Soome typedef packedstruct { domainname mbox; domainname txt; } rdataRP; 7715ffb0c9bSToomas Soome typedef packedstruct { mDNSu16 preference; domainname map822; domainname mapx400; } rdataPX; 7725ffb0c9bSToomas Soome 7735ffb0c9bSToomas Soome typedef packedstruct 7745ffb0c9bSToomas Soome { 7755ffb0c9bSToomas Soome domainname mname; 7765ffb0c9bSToomas Soome domainname rname; 7775ffb0c9bSToomas Soome mDNSs32 serial; // Modular counter; increases when zone changes 7785ffb0c9bSToomas Soome mDNSu32 refresh; // Time in seconds that a slave waits after successful replication of the database before it attempts replication again 7795ffb0c9bSToomas Soome mDNSu32 retry; // Time in seconds that a slave waits after an unsuccessful replication attempt before it attempts replication again 7805ffb0c9bSToomas Soome mDNSu32 expire; // Time in seconds that a slave holds on to old data while replication attempts remain unsuccessful 7815ffb0c9bSToomas Soome mDNSu32 min; // Nominally the minimum record TTL for this zone, in seconds; also used for negative caching. 7825ffb0c9bSToomas Soome } rdataSOA; 7835ffb0c9bSToomas Soome 7845ffb0c9bSToomas Soome // http://www.iana.org/assignments/dns-sec-alg-numbers/dns-sec-alg-numbers.xhtml 7855ffb0c9bSToomas Soome // Algorithm used for RRSIG, DS and DNS KEY 7865ffb0c9bSToomas Soome #define CRYPTO_RSA_SHA1 0x05 7875ffb0c9bSToomas Soome #define CRYPTO_DSA_NSEC3_SHA1 0x06 7885ffb0c9bSToomas Soome #define CRYPTO_RSA_NSEC3_SHA1 0x07 7895ffb0c9bSToomas Soome #define CRYPTO_RSA_SHA256 0x08 7905ffb0c9bSToomas Soome #define CRYPTO_RSA_SHA512 0x0A 7915ffb0c9bSToomas Soome 7925ffb0c9bSToomas Soome #define CRYPTO_ALG_MAX 0x0B 7935ffb0c9bSToomas Soome 7945ffb0c9bSToomas Soome // alg - same as in RRSIG, DNS KEY or DS. 7955ffb0c9bSToomas Soome // RFC 4034 defines SHA1 7965ffb0c9bSToomas Soome // RFC 4509 defines SHA256 7975ffb0c9bSToomas Soome // Note: NSEC3 also uses 1 for SHA1 and hence we will reuse for now till a new 7985ffb0c9bSToomas Soome // value is assigned. 7995ffb0c9bSToomas Soome // 8005ffb0c9bSToomas Soome #define SHA1_DIGEST_TYPE 1 8015ffb0c9bSToomas Soome #define SHA256_DIGEST_TYPE 2 8025ffb0c9bSToomas Soome #define DIGEST_TYPE_MAX 3 8035ffb0c9bSToomas Soome 8045ffb0c9bSToomas Soome // We need support for base64 and base32 encoding for displaying KEY, NSEC3 8055ffb0c9bSToomas Soome // To make this platform agnostic, we define two types which the platform 8065ffb0c9bSToomas Soome // needs to support 8075ffb0c9bSToomas Soome #define ENC_BASE32 1 8085ffb0c9bSToomas Soome #define ENC_BASE64 2 8095ffb0c9bSToomas Soome #define ENC_ALG_MAX 3 8105ffb0c9bSToomas Soome 8115ffb0c9bSToomas Soome #define DS_FIXED_SIZE 4 8125ffb0c9bSToomas Soome typedef packedstruct 8135ffb0c9bSToomas Soome { 8145ffb0c9bSToomas Soome mDNSu16 keyTag; 8155ffb0c9bSToomas Soome mDNSu8 alg; 8165ffb0c9bSToomas Soome mDNSu8 digestType; 8175ffb0c9bSToomas Soome mDNSu8 *digest; 8185ffb0c9bSToomas Soome } rdataDS; 8195ffb0c9bSToomas Soome 8205ffb0c9bSToomas Soome typedef struct TrustAnchor 8215ffb0c9bSToomas Soome { 8225ffb0c9bSToomas Soome struct TrustAnchor *next; 8235ffb0c9bSToomas Soome int digestLen; 8245ffb0c9bSToomas Soome mDNSu32 validFrom; 825c65ebfc7SToomas Soome mDNSu32 validUntil; 8265ffb0c9bSToomas Soome domainname zone; 8275ffb0c9bSToomas Soome rdataDS rds; 8285ffb0c9bSToomas Soome } TrustAnchor; 8295ffb0c9bSToomas Soome 8305ffb0c9bSToomas Soome //size of rdataRRSIG excluding signerName and signature (which are variable fields) 8315ffb0c9bSToomas Soome #define RRSIG_FIXED_SIZE 18 832c65ebfc7SToomas Soome typedef struct 8335ffb0c9bSToomas Soome { 8345ffb0c9bSToomas Soome mDNSu16 typeCovered; 8355ffb0c9bSToomas Soome mDNSu8 alg; 8365ffb0c9bSToomas Soome mDNSu8 labels; 8375ffb0c9bSToomas Soome mDNSu32 origTTL; 8385ffb0c9bSToomas Soome mDNSu32 sigExpireTime; 8395ffb0c9bSToomas Soome mDNSu32 sigInceptTime; 8405ffb0c9bSToomas Soome mDNSu16 keyTag; 841c65ebfc7SToomas Soome mDNSu8 signerName[1]; // signerName is a dynamically-sized array 8425ffb0c9bSToomas Soome // mDNSu8 *signature 8435ffb0c9bSToomas Soome } rdataRRSig; 8445ffb0c9bSToomas Soome 8455ffb0c9bSToomas Soome // RFC 4034: For DNS Key RR 8465ffb0c9bSToomas Soome // flags - the valid value for DNSSEC is 256 (Zone signing key - ZSK) and 257 (Secure Entry Point) which also 8475ffb0c9bSToomas Soome // includes the ZSK bit 8485ffb0c9bSToomas Soome // 8495ffb0c9bSToomas Soome #define DNSKEY_ZONE_SIGN_KEY 0x100 8505ffb0c9bSToomas Soome #define DNSKEY_SECURE_ENTRY_POINT 0x101 8515ffb0c9bSToomas Soome 8525ffb0c9bSToomas Soome // proto - the only valid value for protocol is 3 (See RFC 4034) 8535ffb0c9bSToomas Soome #define DNSKEY_VALID_PROTO_VALUE 0x003 8545ffb0c9bSToomas Soome 8555ffb0c9bSToomas Soome // alg - The only mandatory algorithm that we support is RSA/SHA-1 8565ffb0c9bSToomas Soome // DNSSEC_RSA_SHA1_ALG 8575ffb0c9bSToomas Soome 8585ffb0c9bSToomas Soome #define DNSKEY_FIXED_SIZE 4 8595ffb0c9bSToomas Soome typedef packedstruct 8605ffb0c9bSToomas Soome { 8615ffb0c9bSToomas Soome mDNSu16 flags; 8625ffb0c9bSToomas Soome mDNSu8 proto; 8635ffb0c9bSToomas Soome mDNSu8 alg; 8645ffb0c9bSToomas Soome mDNSu8 *data; 8655ffb0c9bSToomas Soome } rdataDNSKey; 8665ffb0c9bSToomas Soome 8675ffb0c9bSToomas Soome #define NSEC3_FIXED_SIZE 5 8685ffb0c9bSToomas Soome #define NSEC3_FLAGS_OPTOUT 1 8695ffb0c9bSToomas Soome #define NSEC3_MAX_ITERATIONS 2500 8705ffb0c9bSToomas Soome typedef packedstruct 8715ffb0c9bSToomas Soome { 8725ffb0c9bSToomas Soome mDNSu8 alg; 8735ffb0c9bSToomas Soome mDNSu8 flags; 8745ffb0c9bSToomas Soome mDNSu16 iterations; 8755ffb0c9bSToomas Soome mDNSu8 saltLength; 8765ffb0c9bSToomas Soome mDNSu8 *salt; 8775ffb0c9bSToomas Soome // hashLength, nxt, bitmap 8785ffb0c9bSToomas Soome } rdataNSEC3; 8795ffb0c9bSToomas Soome 8805ffb0c9bSToomas Soome // In the multicast usage of NSEC3, we know the actual size of RData 8815ffb0c9bSToomas Soome // 4 bytes : HashAlg, Flags,Iterations 8825ffb0c9bSToomas Soome // 5 bytes : Salt Length 1 byte, Salt 4 bytes 8835ffb0c9bSToomas Soome // 21 bytes : HashLength 1 byte, Hash 20 bytes 8845ffb0c9bSToomas Soome // 34 bytes : Window number, Bitmap length, Type bit map to include the first 256 types 8855ffb0c9bSToomas Soome #define MCAST_NSEC3_RDLENGTH (4 + 5 + 21 + 34) 8865ffb0c9bSToomas Soome #define SHA1_HASH_LENGTH 20 8875ffb0c9bSToomas Soome 8885ffb0c9bSToomas Soome // Base32 encoding takes 5 bytes of the input and encodes as 8 bytes of output. 8895ffb0c9bSToomas Soome // For example, SHA-1 hash of 20 bytes will be encoded as 20/5 * 8 = 32 base32 8905ffb0c9bSToomas Soome // bytes. For a max domain name size of 255 bytes of base32 encoding : (255/8)*5 8915ffb0c9bSToomas Soome // is the max hash length possible. 892c65ebfc7SToomas Soome #define NSEC3_MAX_HASH_LEN 155 8935ffb0c9bSToomas Soome // In NSEC3, the names are hashed and stored in the first label and hence cannot exceed label 8945ffb0c9bSToomas Soome // size. 895c65ebfc7SToomas Soome #define NSEC3_MAX_B32_LEN MAX_DOMAIN_LABEL 8965ffb0c9bSToomas Soome 8975ffb0c9bSToomas Soome // We define it here instead of dnssec.h so that these values can be used 8985ffb0c9bSToomas Soome // in files without bringing in all of dnssec.h unnecessarily. 8995ffb0c9bSToomas Soome typedef enum 9005ffb0c9bSToomas Soome { 9015ffb0c9bSToomas Soome DNSSEC_Secure = 1, // Securely validated and has a chain up to the trust anchor 9025ffb0c9bSToomas Soome DNSSEC_Insecure, // Cannot build a chain up to the trust anchor 9035ffb0c9bSToomas Soome DNSSEC_Indeterminate, // Not used currently 9045ffb0c9bSToomas Soome DNSSEC_Bogus, // failed to validate signatures 9055ffb0c9bSToomas Soome DNSSEC_NoResponse // No DNSSEC records to start with 9065ffb0c9bSToomas Soome } DNSSECStatus; 9075ffb0c9bSToomas Soome 9085ffb0c9bSToomas Soome #define DNSSECRecordType(rrtype) (((rrtype) == kDNSType_RRSIG) || ((rrtype) == kDNSType_NSEC) || ((rrtype) == kDNSType_DNSKEY) || ((rrtype) == kDNSType_DS) || \ 9095ffb0c9bSToomas Soome ((rrtype) == kDNSType_NSEC3)) 9105ffb0c9bSToomas Soome 9115ffb0c9bSToomas Soome typedef enum 9125ffb0c9bSToomas Soome { 913c65ebfc7SToomas Soome platform_OSX = 1, // OSX Platform 914c65ebfc7SToomas Soome platform_iOS, // iOS Platform 915c65ebfc7SToomas Soome platform_Atv, // Atv Platform 9165ffb0c9bSToomas Soome platform_NonApple // Non-Apple (Windows, POSIX) Platform 9175ffb0c9bSToomas Soome } Platform_t; 9185ffb0c9bSToomas Soome 9195ffb0c9bSToomas Soome // EDNS Option Code registrations are recorded in the "DNS EDNS0 Options" section of 9205ffb0c9bSToomas Soome // <http://www.iana.org/assignments/dns-parameters> 9215ffb0c9bSToomas Soome 9225ffb0c9bSToomas Soome #define kDNSOpt_LLQ 1 9235ffb0c9bSToomas Soome #define kDNSOpt_Lease 2 9245ffb0c9bSToomas Soome #define kDNSOpt_NSID 3 9255ffb0c9bSToomas Soome #define kDNSOpt_Owner 4 926c65ebfc7SToomas Soome #define kDNSOpt_Trace 65001 // 65001-65534 Reserved for Local/Experimental Use 9275ffb0c9bSToomas Soome 9285ffb0c9bSToomas Soome typedef struct 9295ffb0c9bSToomas Soome { 9305ffb0c9bSToomas Soome mDNSu16 vers; 9315ffb0c9bSToomas Soome mDNSu16 llqOp; 9325ffb0c9bSToomas Soome mDNSu16 err; // Or UDP reply port, in setup request 9335ffb0c9bSToomas Soome // Note: In the in-memory form, there's typically a two-byte space here, so that the following 64-bit id is word-aligned 9345ffb0c9bSToomas Soome mDNSOpaque64 id; 9355ffb0c9bSToomas Soome mDNSu32 llqlease; 9365ffb0c9bSToomas Soome } LLQOptData; 9375ffb0c9bSToomas Soome 9385ffb0c9bSToomas Soome typedef struct 9395ffb0c9bSToomas Soome { 9405ffb0c9bSToomas Soome mDNSu8 vers; // Version number of this Owner OPT record 9415ffb0c9bSToomas Soome mDNSs8 seq; // Sleep/wake epoch 9425ffb0c9bSToomas Soome mDNSEthAddr HMAC; // Host's primary identifier (e.g. MAC of on-board Ethernet) 9435ffb0c9bSToomas Soome mDNSEthAddr IMAC; // Interface's MAC address (if different to primary MAC) 9445ffb0c9bSToomas Soome mDNSOpaque48 password; // Optional password 9455ffb0c9bSToomas Soome } OwnerOptData; 9465ffb0c9bSToomas Soome 9475ffb0c9bSToomas Soome typedef struct 9485ffb0c9bSToomas Soome { 9495ffb0c9bSToomas Soome mDNSu8 platf; // Running platform (see enum Platform_t) 9505ffb0c9bSToomas Soome mDNSu32 mDNSv; // mDNSResponder Version (DNS_SD_H defined in dns_sd.h) 9515ffb0c9bSToomas Soome } TracerOptData; 9525ffb0c9bSToomas Soome 9535ffb0c9bSToomas Soome // Note: rdataOPT format may be repeated an arbitrary number of times in a single resource record 954c65ebfc7SToomas Soome typedef struct 9555ffb0c9bSToomas Soome { 9565ffb0c9bSToomas Soome mDNSu16 opt; 9575ffb0c9bSToomas Soome mDNSu16 optlen; 9585ffb0c9bSToomas Soome union { LLQOptData llq; mDNSu32 updatelease; OwnerOptData owner; TracerOptData tracer; } u; 9595ffb0c9bSToomas Soome } rdataOPT; 9605ffb0c9bSToomas Soome 9615ffb0c9bSToomas Soome // Space needed to put OPT records into a packet: 9625ffb0c9bSToomas Soome // Header 11 bytes (name 1, type 2, class 2, TTL 4, length 2) 9635ffb0c9bSToomas Soome // LLQ rdata 18 bytes (opt 2, len 2, vers 2, op 2, err 2, id 8, lease 4) 9645ffb0c9bSToomas Soome // Lease rdata 8 bytes (opt 2, len 2, lease 4) 9655ffb0c9bSToomas Soome // Owner rdata 12-24 bytes (opt 2, len 2, owner 8-20) 9665ffb0c9bSToomas Soome // Trace rdata 9 bytes (opt 2, len 2, platf 1, mDNSv 4) 9675ffb0c9bSToomas Soome 9685ffb0c9bSToomas Soome 9695ffb0c9bSToomas Soome #define DNSOpt_Header_Space 11 9705ffb0c9bSToomas Soome #define DNSOpt_LLQData_Space (4 + 2 + 2 + 2 + 8 + 4) 9715ffb0c9bSToomas Soome #define DNSOpt_LeaseData_Space (4 + 4) 9725ffb0c9bSToomas Soome #define DNSOpt_OwnerData_ID_Space (4 + 2 + 6) 9735ffb0c9bSToomas Soome #define DNSOpt_OwnerData_ID_Wake_Space (4 + 2 + 6 + 6) 9745ffb0c9bSToomas Soome #define DNSOpt_OwnerData_ID_Wake_PW4_Space (4 + 2 + 6 + 6 + 4) 9755ffb0c9bSToomas Soome #define DNSOpt_OwnerData_ID_Wake_PW6_Space (4 + 2 + 6 + 6 + 6) 9765ffb0c9bSToomas Soome #define DNSOpt_TraceData_Space (4 + 1 + 4) 9775ffb0c9bSToomas Soome 9785ffb0c9bSToomas Soome #define ValidOwnerLength(X) ( (X) == DNSOpt_OwnerData_ID_Space - 4 || \ 9795ffb0c9bSToomas Soome (X) == DNSOpt_OwnerData_ID_Wake_Space - 4 || \ 9805ffb0c9bSToomas Soome (X) == DNSOpt_OwnerData_ID_Wake_PW4_Space - 4 || \ 9815ffb0c9bSToomas Soome (X) == DNSOpt_OwnerData_ID_Wake_PW6_Space - 4 ) 9825ffb0c9bSToomas Soome 9835ffb0c9bSToomas Soome #define DNSOpt_Owner_Space(A,B) (mDNSSameEthAddress((A),(B)) ? DNSOpt_OwnerData_ID_Space : DNSOpt_OwnerData_ID_Wake_Space) 9845ffb0c9bSToomas Soome 9855ffb0c9bSToomas Soome #define DNSOpt_Data_Space(O) ( \ 9865ffb0c9bSToomas Soome (O)->opt == kDNSOpt_LLQ ? DNSOpt_LLQData_Space : \ 9875ffb0c9bSToomas Soome (O)->opt == kDNSOpt_Lease ? DNSOpt_LeaseData_Space : \ 9885ffb0c9bSToomas Soome (O)->opt == kDNSOpt_Trace ? DNSOpt_TraceData_Space : \ 9895ffb0c9bSToomas Soome (O)->opt == kDNSOpt_Owner ? DNSOpt_Owner_Space(&(O)->u.owner.HMAC, &(O)->u.owner.IMAC) : 0x10000) 9905ffb0c9bSToomas Soome 9915ffb0c9bSToomas Soome // NSEC record is defined in RFC 4034. 9925ffb0c9bSToomas Soome // 16 bit RRTYPE space is split into 256 windows and each window has 256 bits (32 bytes). 9935ffb0c9bSToomas Soome // If we create a structure for NSEC, it's size would be: 9945ffb0c9bSToomas Soome // 9955ffb0c9bSToomas Soome // 256 bytes domainname 'nextname' 9965ffb0c9bSToomas Soome // + 256 * 34 = 8704 bytes of bitmap data 9975ffb0c9bSToomas Soome // = 8960 bytes total 9985ffb0c9bSToomas Soome // 9995ffb0c9bSToomas Soome // This would be a waste, as types about 256 are not very common. But it would be odd, if we receive 10005ffb0c9bSToomas Soome // a type above 256 (.US zone had TYPE65534 when this code was written) and not able to handle it. 10015ffb0c9bSToomas Soome // Hence, we handle any size by not fixing a strucure in place. The following is just a placeholder 10025ffb0c9bSToomas Soome // and never used anywhere. 10035ffb0c9bSToomas Soome // 10045ffb0c9bSToomas Soome #define NSEC_MCAST_WINDOW_SIZE 32 10055ffb0c9bSToomas Soome typedef struct 10065ffb0c9bSToomas Soome { 10075ffb0c9bSToomas Soome domainname *next; //placeholders are uncommented because C89 in Windows requires that a struct has at least a member. 10085ffb0c9bSToomas Soome char bitmap[32]; 10095ffb0c9bSToomas Soome } rdataNSEC; 10105ffb0c9bSToomas Soome 10115ffb0c9bSToomas Soome // StandardAuthRDSize is 264 (256+8), which is large enough to hold a maximum-sized SRV record (6 + 256 bytes) 10125ffb0c9bSToomas Soome // MaximumRDSize is 8K the absolute maximum we support (at least for now) 10135ffb0c9bSToomas Soome #define StandardAuthRDSize 264 10145ffb0c9bSToomas Soome #ifndef MaximumRDSize 10155ffb0c9bSToomas Soome #define MaximumRDSize 8192 10165ffb0c9bSToomas Soome #endif 10175ffb0c9bSToomas Soome 10185ffb0c9bSToomas Soome // InlineCacheRDSize is 68 10195ffb0c9bSToomas Soome // Records received from the network with rdata this size or less have their rdata stored right in the CacheRecord object 10205ffb0c9bSToomas Soome // Records received from the network with rdata larger than this have additional storage allocated for the rdata 10215ffb0c9bSToomas Soome // A quick unscientific sample from a busy network at Apple with lots of machines revealed this: 10225ffb0c9bSToomas Soome // 1461 records in cache 10235ffb0c9bSToomas Soome // 292 were one-byte TXT records 10245ffb0c9bSToomas Soome // 136 were four-byte A records 10255ffb0c9bSToomas Soome // 184 were sixteen-byte AAAA records 10265ffb0c9bSToomas Soome // 780 were various PTR, TXT and SRV records from 12-64 bytes 10275ffb0c9bSToomas Soome // Only 69 records had rdata bigger than 64 bytes 10285ffb0c9bSToomas Soome // Note that since CacheRecord object and a CacheGroup object are allocated out of the same pool, it's sensible to 10295ffb0c9bSToomas Soome // have them both be the same size. Making one smaller without making the other smaller won't actually save any memory. 10305ffb0c9bSToomas Soome #define InlineCacheRDSize 68 10315ffb0c9bSToomas Soome 10325ffb0c9bSToomas Soome // The RDataBody union defines the common rdata types that fit into our 264-byte limit 10335ffb0c9bSToomas Soome typedef union 10345ffb0c9bSToomas Soome { 10355ffb0c9bSToomas Soome mDNSu8 data[StandardAuthRDSize]; 10365ffb0c9bSToomas Soome mDNSv4Addr ipv4; // For 'A' record 10375ffb0c9bSToomas Soome domainname name; // For PTR, NS, CNAME, DNAME 10385ffb0c9bSToomas Soome UTF8str255 txt; 10395ffb0c9bSToomas Soome rdataMX mx; 10405ffb0c9bSToomas Soome mDNSv6Addr ipv6; // For 'AAAA' record 10415ffb0c9bSToomas Soome rdataSRV srv; 10425ffb0c9bSToomas Soome rdataOPT opt[2]; // For EDNS0 OPT record; RDataBody may contain multiple variable-length rdataOPT objects packed together 10435ffb0c9bSToomas Soome } RDataBody; 10445ffb0c9bSToomas Soome 10455ffb0c9bSToomas Soome // The RDataBody2 union is the same as above, except it includes fields for the larger types like soa, rp, px 10465ffb0c9bSToomas Soome typedef union 10475ffb0c9bSToomas Soome { 10485ffb0c9bSToomas Soome mDNSu8 data[StandardAuthRDSize]; 10495ffb0c9bSToomas Soome mDNSv4Addr ipv4; // For 'A' record 10505ffb0c9bSToomas Soome domainname name; // For PTR, NS, CNAME, DNAME 10515ffb0c9bSToomas Soome rdataSOA soa; // This is large; not included in the normal RDataBody definition 10525ffb0c9bSToomas Soome UTF8str255 txt; 10535ffb0c9bSToomas Soome rdataMX mx; 10545ffb0c9bSToomas Soome rdataRP rp; // This is large; not included in the normal RDataBody definition 10555ffb0c9bSToomas Soome rdataPX px; // This is large; not included in the normal RDataBody definition 10565ffb0c9bSToomas Soome mDNSv6Addr ipv6; // For 'AAAA' record 10575ffb0c9bSToomas Soome rdataSRV srv; 10585ffb0c9bSToomas Soome rdataOPT opt[2]; // For EDNS0 OPT record; RDataBody may contain multiple variable-length rdataOPT objects packed together 10595ffb0c9bSToomas Soome rdataDS ds; 10605ffb0c9bSToomas Soome rdataDNSKey key; 10615ffb0c9bSToomas Soome rdataRRSig rrsig; 10625ffb0c9bSToomas Soome } RDataBody2; 10635ffb0c9bSToomas Soome 10645ffb0c9bSToomas Soome typedef struct 10655ffb0c9bSToomas Soome { 10665ffb0c9bSToomas Soome mDNSu16 MaxRDLength; // Amount of storage allocated for rdata (usually sizeof(RDataBody)) 10675ffb0c9bSToomas Soome mDNSu16 padding; // So that RDataBody is aligned on 32-bit boundary 10685ffb0c9bSToomas Soome RDataBody u; 10695ffb0c9bSToomas Soome } RData; 10705ffb0c9bSToomas Soome 10715ffb0c9bSToomas Soome // sizeofRDataHeader should be 4 bytes 10725ffb0c9bSToomas Soome #define sizeofRDataHeader (sizeof(RData) - sizeof(RDataBody)) 10735ffb0c9bSToomas Soome 10745ffb0c9bSToomas Soome // RData_small is a smaller version of the RData object, used for inline data storage embedded in a CacheRecord_struct 10755ffb0c9bSToomas Soome typedef struct 10765ffb0c9bSToomas Soome { 10775ffb0c9bSToomas Soome mDNSu16 MaxRDLength; // Storage allocated for data (may be greater than InlineCacheRDSize if additional storage follows this object) 10785ffb0c9bSToomas Soome mDNSu16 padding; // So that data is aligned on 32-bit boundary 10795ffb0c9bSToomas Soome mDNSu8 data[InlineCacheRDSize]; 10805ffb0c9bSToomas Soome } RData_small; 10815ffb0c9bSToomas Soome 10825ffb0c9bSToomas Soome // Note: Within an mDNSRecordCallback mDNS all API calls are legal except mDNS_Init(), mDNS_Exit(), mDNS_Execute() 10835ffb0c9bSToomas Soome typedef void mDNSRecordCallback (mDNS *const m, AuthRecord *const rr, mStatus result); 10845ffb0c9bSToomas Soome 10855ffb0c9bSToomas Soome // Note: 10865ffb0c9bSToomas Soome // Restrictions: An mDNSRecordUpdateCallback may not make any mDNS API calls. 10875ffb0c9bSToomas Soome // The intent of this callback is to allow the client to free memory, if necessary. 10885ffb0c9bSToomas Soome // The internal data structures of the mDNS code may not be in a state where mDNS API calls may be made safely. 10895ffb0c9bSToomas Soome typedef void mDNSRecordUpdateCallback (mDNS *const m, AuthRecord *const rr, RData *OldRData, mDNSu16 OldRDLen); 10905ffb0c9bSToomas Soome 10915ffb0c9bSToomas Soome // *************************************************************************** 10925ffb0c9bSToomas Soome #if 0 10935ffb0c9bSToomas Soome #pragma mark - 10945ffb0c9bSToomas Soome #pragma mark - NAT Traversal structures and constants 10955ffb0c9bSToomas Soome #endif 10965ffb0c9bSToomas Soome 10975ffb0c9bSToomas Soome #define NATMAP_MAX_RETRY_INTERVAL ((mDNSPlatformOneSecond * 60) * 15) // Max retry interval is 15 minutes 10985ffb0c9bSToomas Soome #define NATMAP_MIN_RETRY_INTERVAL (mDNSPlatformOneSecond * 2) // Min retry interval is 2 seconds 10995ffb0c9bSToomas Soome #define NATMAP_INIT_RETRY (mDNSPlatformOneSecond / 4) // start at 250ms w/ exponential decay 11005ffb0c9bSToomas Soome #define NATMAP_DEFAULT_LEASE (60 * 60 * 2) // 2 hour lease life in seconds 11015ffb0c9bSToomas Soome #define NATMAP_VERS 0 11025ffb0c9bSToomas Soome 11035ffb0c9bSToomas Soome typedef enum 11045ffb0c9bSToomas Soome { 11055ffb0c9bSToomas Soome NATOp_AddrRequest = 0, 11065ffb0c9bSToomas Soome NATOp_MapUDP = 1, 11075ffb0c9bSToomas Soome NATOp_MapTCP = 2, 11085ffb0c9bSToomas Soome 11095ffb0c9bSToomas Soome NATOp_AddrResponse = 0x80 | 0, 11105ffb0c9bSToomas Soome NATOp_MapUDPResponse = 0x80 | 1, 11115ffb0c9bSToomas Soome NATOp_MapTCPResponse = 0x80 | 2, 11125ffb0c9bSToomas Soome } NATOp_t; 11135ffb0c9bSToomas Soome 11145ffb0c9bSToomas Soome enum 11155ffb0c9bSToomas Soome { 11165ffb0c9bSToomas Soome NATErr_None = 0, 11175ffb0c9bSToomas Soome NATErr_Vers = 1, 11185ffb0c9bSToomas Soome NATErr_Refused = 2, 11195ffb0c9bSToomas Soome NATErr_NetFail = 3, 11205ffb0c9bSToomas Soome NATErr_Res = 4, 11215ffb0c9bSToomas Soome NATErr_Opcode = 5 11225ffb0c9bSToomas Soome }; 11235ffb0c9bSToomas Soome 11245ffb0c9bSToomas Soome typedef mDNSu16 NATErr_t; 11255ffb0c9bSToomas Soome 11265ffb0c9bSToomas Soome typedef packedstruct 11275ffb0c9bSToomas Soome { 11285ffb0c9bSToomas Soome mDNSu8 vers; 11295ffb0c9bSToomas Soome mDNSu8 opcode; 11305ffb0c9bSToomas Soome } NATAddrRequest; 11315ffb0c9bSToomas Soome 11325ffb0c9bSToomas Soome typedef packedstruct 11335ffb0c9bSToomas Soome { 11345ffb0c9bSToomas Soome mDNSu8 vers; 11355ffb0c9bSToomas Soome mDNSu8 opcode; 11365ffb0c9bSToomas Soome mDNSu16 err; 11375ffb0c9bSToomas Soome mDNSu32 upseconds; // Time since last NAT engine reboot, in seconds 11385ffb0c9bSToomas Soome mDNSv4Addr ExtAddr; 11395ffb0c9bSToomas Soome } NATAddrReply; 11405ffb0c9bSToomas Soome 11415ffb0c9bSToomas Soome typedef packedstruct 11425ffb0c9bSToomas Soome { 11435ffb0c9bSToomas Soome mDNSu8 vers; 11445ffb0c9bSToomas Soome mDNSu8 opcode; 11455ffb0c9bSToomas Soome mDNSOpaque16 unused; 11465ffb0c9bSToomas Soome mDNSIPPort intport; 11475ffb0c9bSToomas Soome mDNSIPPort extport; 11485ffb0c9bSToomas Soome mDNSu32 NATReq_lease; 11495ffb0c9bSToomas Soome } NATPortMapRequest; 11504b22b933Srs 11515ffb0c9bSToomas Soome typedef packedstruct 11525ffb0c9bSToomas Soome { 11535ffb0c9bSToomas Soome mDNSu8 vers; 11545ffb0c9bSToomas Soome mDNSu8 opcode; 11555ffb0c9bSToomas Soome mDNSu16 err; 11565ffb0c9bSToomas Soome mDNSu32 upseconds; // Time since last NAT engine reboot, in seconds 11575ffb0c9bSToomas Soome mDNSIPPort intport; 11585ffb0c9bSToomas Soome mDNSIPPort extport; 11595ffb0c9bSToomas Soome mDNSu32 NATRep_lease; 11605ffb0c9bSToomas Soome } NATPortMapReply; 11614b22b933Srs 11625ffb0c9bSToomas Soome // PCP Support for IPv4 mappings 11634b22b933Srs 11645ffb0c9bSToomas Soome #define PCP_VERS 0x02 11655ffb0c9bSToomas Soome #define PCP_WAITSECS_AFTER_EPOCH_INVALID 5 11664b22b933Srs 11675ffb0c9bSToomas Soome typedef enum 11685ffb0c9bSToomas Soome { 11695ffb0c9bSToomas Soome PCPOp_Announce = 0, 11705ffb0c9bSToomas Soome PCPOp_Map = 1 11715ffb0c9bSToomas Soome } PCPOp_t; 11724b22b933Srs 11735ffb0c9bSToomas Soome typedef enum 11745ffb0c9bSToomas Soome { 11755ffb0c9bSToomas Soome PCPProto_All = 0, 11765ffb0c9bSToomas Soome PCPProto_TCP = 6, 11775ffb0c9bSToomas Soome PCPProto_UDP = 17 11785ffb0c9bSToomas Soome } PCPProto_t; 11794b22b933Srs 11805ffb0c9bSToomas Soome typedef enum 11815ffb0c9bSToomas Soome { 11825ffb0c9bSToomas Soome PCPResult_Success = 0, 11835ffb0c9bSToomas Soome PCPResult_UnsuppVersion = 1, 11845ffb0c9bSToomas Soome PCPResult_NotAuthorized = 2, 11855ffb0c9bSToomas Soome PCPResult_MalformedReq = 3, 11865ffb0c9bSToomas Soome PCPResult_UnsuppOpcode = 4, 11875ffb0c9bSToomas Soome PCPResult_UnsuppOption = 5, 11885ffb0c9bSToomas Soome PCPResult_MalformedOption = 6, 11895ffb0c9bSToomas Soome PCPResult_NetworkFailure = 7, 11905ffb0c9bSToomas Soome PCPResult_NoResources = 8, 11915ffb0c9bSToomas Soome PCPResult_UnsuppProtocol = 9, 11925ffb0c9bSToomas Soome PCPResult_UserExQuota = 10, 11935ffb0c9bSToomas Soome PCPResult_CantProvideExt = 11, 11945ffb0c9bSToomas Soome PCPResult_AddrMismatch = 12, 11955ffb0c9bSToomas Soome PCPResult_ExcesRemotePeer = 13 11965ffb0c9bSToomas Soome } PCPResult_t; 11974b22b933Srs 1198c65ebfc7SToomas Soome typedef struct 11995ffb0c9bSToomas Soome { 12005ffb0c9bSToomas Soome mDNSu8 version; 12015ffb0c9bSToomas Soome mDNSu8 opCode; 12025ffb0c9bSToomas Soome mDNSOpaque16 reserved; 12035ffb0c9bSToomas Soome mDNSu32 lifetime; 12045ffb0c9bSToomas Soome mDNSv6Addr clientAddr; 12055ffb0c9bSToomas Soome mDNSu32 nonce[3]; 12065ffb0c9bSToomas Soome mDNSu8 protocol; 12075ffb0c9bSToomas Soome mDNSu8 reservedMapOp[3]; 12085ffb0c9bSToomas Soome mDNSIPPort intPort; 12095ffb0c9bSToomas Soome mDNSIPPort extPort; 12105ffb0c9bSToomas Soome mDNSv6Addr extAddress; 12115ffb0c9bSToomas Soome } PCPMapRequest; 12124b22b933Srs 1213c65ebfc7SToomas Soome typedef struct 12145ffb0c9bSToomas Soome { 12155ffb0c9bSToomas Soome mDNSu8 version; 12165ffb0c9bSToomas Soome mDNSu8 opCode; 12175ffb0c9bSToomas Soome mDNSu8 reserved; 12185ffb0c9bSToomas Soome mDNSu8 result; 12195ffb0c9bSToomas Soome mDNSu32 lifetime; 12205ffb0c9bSToomas Soome mDNSu32 epoch; 12215ffb0c9bSToomas Soome mDNSu32 clientAddrParts[3]; 12225ffb0c9bSToomas Soome mDNSu32 nonce[3]; 12235ffb0c9bSToomas Soome mDNSu8 protocol; 12245ffb0c9bSToomas Soome mDNSu8 reservedMapOp[3]; 12255ffb0c9bSToomas Soome mDNSIPPort intPort; 12265ffb0c9bSToomas Soome mDNSIPPort extPort; 12275ffb0c9bSToomas Soome mDNSv6Addr extAddress; 12285ffb0c9bSToomas Soome } PCPMapReply; 12295ffb0c9bSToomas Soome 12305ffb0c9bSToomas Soome // LNT Support 12314b22b933Srs 12325ffb0c9bSToomas Soome typedef enum 12335ffb0c9bSToomas Soome { 12345ffb0c9bSToomas Soome LNTDiscoveryOp = 1, 12355ffb0c9bSToomas Soome LNTExternalAddrOp = 2, 12365ffb0c9bSToomas Soome LNTPortMapOp = 3, 12375ffb0c9bSToomas Soome LNTPortMapDeleteOp = 4 12385ffb0c9bSToomas Soome } LNTOp_t; 12395ffb0c9bSToomas Soome 12405ffb0c9bSToomas Soome #define LNT_MAXBUFSIZE 8192 12415ffb0c9bSToomas Soome typedef struct tcpLNTInfo_struct tcpLNTInfo; 12425ffb0c9bSToomas Soome struct tcpLNTInfo_struct 12435ffb0c9bSToomas Soome { 12445ffb0c9bSToomas Soome tcpLNTInfo *next; 12455ffb0c9bSToomas Soome mDNS *m; 12465ffb0c9bSToomas Soome NATTraversalInfo *parentNATInfo; // pointer back to the parent NATTraversalInfo 12475ffb0c9bSToomas Soome TCPSocket *sock; 12485ffb0c9bSToomas Soome LNTOp_t op; // operation performed using this connection 12495ffb0c9bSToomas Soome mDNSAddr Address; // router address 12505ffb0c9bSToomas Soome mDNSIPPort Port; // router port 12515ffb0c9bSToomas Soome mDNSu8 *Request; // xml request to router 12525ffb0c9bSToomas Soome int requestLen; 12535ffb0c9bSToomas Soome mDNSu8 *Reply; // xml reply from router 12545ffb0c9bSToomas Soome int replyLen; 12555ffb0c9bSToomas Soome unsigned long nread; // number of bytes read so far 12565ffb0c9bSToomas Soome int retries; // number of times we've tried to do this port mapping 12575ffb0c9bSToomas Soome }; 12585ffb0c9bSToomas Soome 12595ffb0c9bSToomas Soome typedef void (*NATTraversalClientCallback)(mDNS *m, NATTraversalInfo *n); 12605ffb0c9bSToomas Soome 12615ffb0c9bSToomas Soome // if m->timenow < ExpiryTime then we have an active mapping, and we'll renew halfway to expiry 12625ffb0c9bSToomas Soome // if m->timenow >= ExpiryTime then our mapping has expired, and we're trying to create one 12634b22b933Srs 12645ffb0c9bSToomas Soome typedef enum 12655ffb0c9bSToomas Soome { 12665ffb0c9bSToomas Soome NATTProtocolNone = 0, 12675ffb0c9bSToomas Soome NATTProtocolNATPMP = 1, 12685ffb0c9bSToomas Soome NATTProtocolUPNPIGD = 2, 12695ffb0c9bSToomas Soome NATTProtocolPCP = 3, 12705ffb0c9bSToomas Soome } NATTProtocol; 12715ffb0c9bSToomas Soome 12725ffb0c9bSToomas Soome struct NATTraversalInfo_struct 12735ffb0c9bSToomas Soome { 12745ffb0c9bSToomas Soome // Internal state fields. These are used internally by mDNSCore; the client layer needn't be concerned with them. 12755ffb0c9bSToomas Soome NATTraversalInfo *next; 12765ffb0c9bSToomas Soome 12775ffb0c9bSToomas Soome mDNSs32 ExpiryTime; // Time this mapping expires, or zero if no mapping 12785ffb0c9bSToomas Soome mDNSs32 retryInterval; // Current interval, between last packet we sent and the next one 12795ffb0c9bSToomas Soome mDNSs32 retryPortMap; // If Protocol is nonzero, time to send our next mapping packet 12805ffb0c9bSToomas Soome mStatus NewResult; // New error code; will be copied to Result just prior to invoking callback 12815ffb0c9bSToomas Soome NATTProtocol lastSuccessfulProtocol; // To send correct deletion request & update non-PCP external address operations 12825ffb0c9bSToomas Soome mDNSBool sentNATPMP; // Whether we just sent a NAT-PMP packet, so we won't send another if 12835ffb0c9bSToomas Soome // we receive another NAT-PMP "Unsupported Version" packet 12844b22b933Srs 12855ffb0c9bSToomas Soome #ifdef _LEGACY_NAT_TRAVERSAL_ 12865ffb0c9bSToomas Soome tcpLNTInfo tcpInfo; // Legacy NAT traversal (UPnP) TCP connection 12875ffb0c9bSToomas Soome #endif 12884b22b933Srs 12895ffb0c9bSToomas Soome // Result fields: When the callback is invoked these fields contain the answers the client is looking for 12905ffb0c9bSToomas Soome // When the callback is invoked ExternalPort is *usually* set to be the same the same as RequestedPort, except: 12915ffb0c9bSToomas Soome // (a) When we're behind a NAT gateway with port mapping disabled, ExternalPort is reported as zero to 12925ffb0c9bSToomas Soome // indicate that we don't currently have a working mapping (but RequestedPort retains the external port 12935ffb0c9bSToomas Soome // we'd like to get, the next time we meet an accomodating NAT gateway willing to give us one). 12945ffb0c9bSToomas Soome // (b) When we have a routable non-RFC1918 address, we don't *need* a port mapping, so ExternalPort 12955ffb0c9bSToomas Soome // is reported as the same as our InternalPort, since that is effectively our externally-visible port too. 12965ffb0c9bSToomas Soome // Again, RequestedPort retains the external port we'd like to get the next time we find ourself behind a NAT gateway. 12975ffb0c9bSToomas Soome // To improve stability of port mappings, RequestedPort is updated any time we get a successful 12985ffb0c9bSToomas Soome // mapping response from the PCP, NAT-PMP or UPnP gateway. For example, if we ask for port 80, and 12995ffb0c9bSToomas Soome // get assigned port 81, then thereafter we'll contine asking for port 81. 13005ffb0c9bSToomas Soome mDNSInterfaceID InterfaceID; 13015ffb0c9bSToomas Soome mDNSv4Addr ExternalAddress; // Initially set to onesIPv4Addr, until first callback 13025ffb0c9bSToomas Soome mDNSv4Addr NewAddress; // May be updated with actual value assigned by gateway 13035ffb0c9bSToomas Soome mDNSIPPort ExternalPort; 13045ffb0c9bSToomas Soome mDNSu32 Lifetime; 13055ffb0c9bSToomas Soome mStatus Result; 13065ffb0c9bSToomas Soome 13075ffb0c9bSToomas Soome // Client API fields: The client must set up these fields *before* making any NAT traversal API calls 13085ffb0c9bSToomas Soome mDNSu8 Protocol; // NATOp_MapUDP or NATOp_MapTCP, or zero if just requesting the external IP address 13095ffb0c9bSToomas Soome mDNSIPPort IntPort; // Client's internal port number (doesn't change) 13105ffb0c9bSToomas Soome mDNSIPPort RequestedPort; // Requested external port; may be updated with actual value assigned by gateway 13115ffb0c9bSToomas Soome mDNSu32 NATLease; // Requested lifetime in seconds (doesn't change) 13125ffb0c9bSToomas Soome NATTraversalClientCallback clientCallback; 13135ffb0c9bSToomas Soome void *clientContext; 13145ffb0c9bSToomas Soome }; 13154b22b933Srs 13165ffb0c9bSToomas Soome // *************************************************************************** 13175ffb0c9bSToomas Soome #if 0 13185ffb0c9bSToomas Soome #pragma mark - 13195ffb0c9bSToomas Soome #pragma mark - DNSServer & McastResolver structures and constants 13205ffb0c9bSToomas Soome #endif 13214b22b933Srs 13225ffb0c9bSToomas Soome enum 13235ffb0c9bSToomas Soome { 1324cda73f64SToomas Soome DNSServer_FlagDelete = 0x1, 1325cda73f64SToomas Soome DNSServer_FlagNew = 0x2, 1326cda73f64SToomas Soome #if APPLE_OSX_mDNSResponder 1327cda73f64SToomas Soome DNSServer_FlagUnreachable = 0x4, 1328cda73f64SToomas Soome #endif 13295ffb0c9bSToomas Soome }; 13304b22b933Srs 13315ffb0c9bSToomas Soome enum 13325ffb0c9bSToomas Soome { 13335ffb0c9bSToomas Soome McastResolver_FlagDelete = 1, 13345ffb0c9bSToomas Soome McastResolver_FlagNew = 2 13355ffb0c9bSToomas Soome }; 13365ffb0c9bSToomas Soome 13375ffb0c9bSToomas Soome typedef struct McastResolver 13385ffb0c9bSToomas Soome { 13395ffb0c9bSToomas Soome struct McastResolver *next; 13405ffb0c9bSToomas Soome mDNSInterfaceID interface; 13415ffb0c9bSToomas Soome mDNSu32 flags; // Set when we're planning to delete this from the list 13425ffb0c9bSToomas Soome domainname domain; 13435ffb0c9bSToomas Soome mDNSu32 timeout; // timeout value for questions 13445ffb0c9bSToomas Soome } McastResolver; 13455ffb0c9bSToomas Soome 1346*3b436d06SToomas Soome enum { 1347*3b436d06SToomas Soome Mortality_Mortal = 0, // This cache record can expire and get purged 1348*3b436d06SToomas Soome Mortality_Immortal = 1, // Allow this record to remain in the cache indefinitely 1349*3b436d06SToomas Soome Mortality_Ghost = 2 // An immortal record that has expired and can linger in the cache 1350*3b436d06SToomas Soome }; 1351*3b436d06SToomas Soome typedef mDNSu8 MortalityState; 1352*3b436d06SToomas Soome 13535ffb0c9bSToomas Soome // scoped values for DNSServer matching 13545ffb0c9bSToomas Soome enum 13555ffb0c9bSToomas Soome { 13565ffb0c9bSToomas Soome kScopeNone = 0, // DNS server used by unscoped questions 13575ffb0c9bSToomas Soome kScopeInterfaceID = 1, // Scoped DNS server used only by scoped questions 1358c65ebfc7SToomas Soome kScopeServiceID = 2, // Service specific DNS server used only by questions 13595ffb0c9bSToomas Soome // have a matching serviceID 1360c65ebfc7SToomas Soome kScopesMaxCount = 3 // Max count for scopes enum 13615ffb0c9bSToomas Soome }; 13625ffb0c9bSToomas Soome 13635ffb0c9bSToomas Soome // Note: DNSSECAware is set if we are able to get a valid response to 13645ffb0c9bSToomas Soome // a DNSSEC question. In some cases it is possible that the proxy 13655ffb0c9bSToomas Soome // strips the EDNS0 option and we just get a plain response with no 13665ffb0c9bSToomas Soome // signatures. But we still mark DNSSECAware in that case. As DNSSECAware 13675ffb0c9bSToomas Soome // is only used to determine whether DNSSEC_VALIDATION_SECURE_OPTIONAL 13685ffb0c9bSToomas Soome // should be turned off or not, it is sufficient that we are getting 13695ffb0c9bSToomas Soome // responses back. 13705ffb0c9bSToomas Soome typedef struct DNSServer 13715ffb0c9bSToomas Soome { 13725ffb0c9bSToomas Soome struct DNSServer *next; 13735ffb0c9bSToomas Soome mDNSInterfaceID interface; // DNS requests should be sent on this interface 13745ffb0c9bSToomas Soome mDNSs32 serviceID; 13755ffb0c9bSToomas Soome mDNSAddr addr; 13765ffb0c9bSToomas Soome mDNSIPPort port; 13775ffb0c9bSToomas Soome mDNSu32 flags; // Set when we're planning to delete this from the list 13785ffb0c9bSToomas Soome domainname domain; // name->server matching for "split dns" 13795ffb0c9bSToomas Soome mDNSs32 penaltyTime; // amount of time this server is penalized 13805ffb0c9bSToomas Soome mDNSu32 scoped; // See the scoped enum above 13815ffb0c9bSToomas Soome mDNSu32 timeout; // timeout value for questions 13825ffb0c9bSToomas Soome mDNSu16 resGroupID; // ID of the resolver group that contains this DNSServer 1383c65ebfc7SToomas Soome mDNSu8 retransDO; // Total Retransmissions for queries sent with DO option 1384c65ebfc7SToomas Soome mDNSBool cellIntf; // Resolver from Cellular Interface? 13855ffb0c9bSToomas Soome mDNSBool req_A; // If set, send v4 query (DNSConfig allows A queries) 13865ffb0c9bSToomas Soome mDNSBool req_AAAA; // If set, send v6 query (DNSConfig allows AAAA queries) 13875ffb0c9bSToomas Soome mDNSBool req_DO; // If set, okay to send DNSSEC queries (EDNS DO bit is supported) 1388c65ebfc7SToomas Soome mDNSBool DNSSECAware; // Set if we are able to receive a response to a request sent with DO option. 1389c65ebfc7SToomas Soome mDNSBool isExpensive; // True if the interface to this server is expensive. 1390*3b436d06SToomas Soome mDNSBool isCLAT46; // True if the interface to this server is CLAT46. 13915ffb0c9bSToomas Soome } DNSServer; 13924b22b933Srs 13934b22b933Srs typedef struct 13945ffb0c9bSToomas Soome { 13955ffb0c9bSToomas Soome mDNSu8 *AnonData; 13965ffb0c9bSToomas Soome int AnonDataLen; 13975ffb0c9bSToomas Soome mDNSu32 salt; 13985ffb0c9bSToomas Soome ResourceRecord *nsec3RR; 13995ffb0c9bSToomas Soome mDNSInterfaceID SendNow; // The interface ID that this record should be sent on 14005ffb0c9bSToomas Soome } AnonymousInfo; 14015ffb0c9bSToomas Soome 14025ffb0c9bSToomas Soome struct ResourceRecord_struct 14035ffb0c9bSToomas Soome { 1404c65ebfc7SToomas Soome mDNSu8 RecordType; // See kDNSRecordTypes enum. 1405*3b436d06SToomas Soome MortalityState mortality; // Mortality of this resource record (See MortalityState enum) 1406c65ebfc7SToomas Soome mDNSu16 rrtype; // See DNS_TypeValues enum. 1407c65ebfc7SToomas Soome mDNSu16 rrclass; // See DNS_ClassValues enum. 14085ffb0c9bSToomas Soome mDNSu32 rroriginalttl; // In seconds 14095ffb0c9bSToomas Soome mDNSu16 rdlength; // Size of the raw rdata, in bytes, in the on-the-wire format 14105ffb0c9bSToomas Soome // (In-memory storage may be larger, for structures containing 'holes', like SOA) 14115ffb0c9bSToomas Soome mDNSu16 rdestimate; // Upper bound on on-the-wire size of rdata after name compression 14125ffb0c9bSToomas Soome mDNSu32 namehash; // Name-based (i.e. case-insensitive) hash of name 14135ffb0c9bSToomas Soome mDNSu32 rdatahash; // For rdata containing domain name (e.g. PTR, SRV, CNAME etc.), case-insensitive name hash 14145ffb0c9bSToomas Soome // else, for all other rdata, 32-bit hash of the raw rdata 14155ffb0c9bSToomas Soome // Note: This requirement is important. Various routines like AddAdditionalsToResponseList(), 14165ffb0c9bSToomas Soome // ReconfirmAntecedents(), etc., use rdatahash as a pre-flight check to see 14175ffb0c9bSToomas Soome // whether it's worth doing a full SameDomainName() call. If the rdatahash 14185ffb0c9bSToomas Soome // is not a correct case-insensitive name hash, they'll get false negatives. 14195ffb0c9bSToomas Soome // Grouping pointers together at the end of the structure improves the memory layout efficiency 14205ffb0c9bSToomas Soome mDNSInterfaceID InterfaceID; // Set if this RR is specific to one interface 14215ffb0c9bSToomas Soome // For records received off the wire, InterfaceID is *always* set to the receiving interface 14225ffb0c9bSToomas Soome // For our authoritative records, InterfaceID is usually zero, except for those few records 14235ffb0c9bSToomas Soome // that are interface-specific (e.g. address records, especially linklocal addresses) 14245ffb0c9bSToomas Soome const domainname *name; 14255ffb0c9bSToomas Soome RData *rdata; // Pointer to storage for this rdata 1426cda73f64SToomas Soome DNSServer *rDNSServer; // Unicast DNS server authoritative for this entry; null for multicast 14275ffb0c9bSToomas Soome AnonymousInfo *AnonInfo; // Anonymous Information 14285ffb0c9bSToomas Soome }; 14295ffb0c9bSToomas Soome 14305ffb0c9bSToomas Soome 14315ffb0c9bSToomas Soome // Unless otherwise noted, states may apply to either independent record registrations or service registrations 14324b22b933Srs typedef enum 14335ffb0c9bSToomas Soome { 14345ffb0c9bSToomas Soome regState_Zero = 0, 14355ffb0c9bSToomas Soome regState_Pending = 1, // update sent, reply not received 14365ffb0c9bSToomas Soome regState_Registered = 2, // update sent, reply received 14375ffb0c9bSToomas Soome regState_DeregPending = 3, // dereg sent, reply not received 14385ffb0c9bSToomas Soome regState_Unregistered = 4, // not in any list 14395ffb0c9bSToomas Soome regState_Refresh = 5, // outstanding refresh (or target change) message 14405ffb0c9bSToomas Soome regState_NATMap = 6, // establishing NAT port mapping 14415ffb0c9bSToomas Soome regState_UpdatePending = 7, // update in flight as result of mDNS_Update call 14425ffb0c9bSToomas Soome regState_NoTarget = 8, // SRV Record registration pending registration of hostname 14435ffb0c9bSToomas Soome regState_NATError = 9 // unable to complete NAT traversal 14445ffb0c9bSToomas Soome } regState_t; 14454b22b933Srs 14465ffb0c9bSToomas Soome enum 14475ffb0c9bSToomas Soome { 14485ffb0c9bSToomas Soome Target_Manual = 0, 14495ffb0c9bSToomas Soome Target_AutoHost = 1, 14505ffb0c9bSToomas Soome Target_AutoHostAndNATMAP = 2 14515ffb0c9bSToomas Soome }; 14525ffb0c9bSToomas Soome 14535ffb0c9bSToomas Soome typedef enum 14545ffb0c9bSToomas Soome { 14555ffb0c9bSToomas Soome mergeState_Zero = 0, 14565ffb0c9bSToomas Soome mergeState_DontMerge = 1 // Set on fatal error conditions to disable merging 14575ffb0c9bSToomas Soome } mergeState_t; 14585ffb0c9bSToomas Soome 14595ffb0c9bSToomas Soome #define AUTH_GROUP_NAME_SIZE 128 14605ffb0c9bSToomas Soome struct AuthGroup_struct // Header object for a list of AuthRecords with the same name 14615ffb0c9bSToomas Soome { 14625ffb0c9bSToomas Soome AuthGroup *next; // Next AuthGroup object in this hash table bucket 14635ffb0c9bSToomas Soome mDNSu32 namehash; // Name-based (i.e. case insensitive) hash of name 14645ffb0c9bSToomas Soome AuthRecord *members; // List of CacheRecords with this same name 14655ffb0c9bSToomas Soome AuthRecord **rrauth_tail; // Tail end of that list 14665ffb0c9bSToomas Soome domainname *name; // Common name for all AuthRecords in this list 14675ffb0c9bSToomas Soome AuthRecord *NewLocalOnlyRecords; 14685ffb0c9bSToomas Soome mDNSu8 namestorage[AUTH_GROUP_NAME_SIZE]; 14695ffb0c9bSToomas Soome }; 14705ffb0c9bSToomas Soome 14715ffb0c9bSToomas Soome #ifndef AUTH_HASH_SLOTS 14725ffb0c9bSToomas Soome #define AUTH_HASH_SLOTS 499 14735ffb0c9bSToomas Soome #endif 14745ffb0c9bSToomas Soome #define FORALL_AUTHRECORDS(SLOT,AG,AR) \ 14755ffb0c9bSToomas Soome for ((SLOT) = 0; (SLOT) < AUTH_HASH_SLOTS; (SLOT)++) \ 14765ffb0c9bSToomas Soome for ((AG)=m->rrauth.rrauth_hash[(SLOT)]; (AG); (AG)=(AG)->next) \ 14775ffb0c9bSToomas Soome for ((AR) = (AG)->members; (AR); (AR)=(AR)->next) 14785ffb0c9bSToomas Soome 14795ffb0c9bSToomas Soome typedef union AuthEntity_union AuthEntity; 14805ffb0c9bSToomas Soome union AuthEntity_union { AuthEntity *next; AuthGroup ag; }; 14815ffb0c9bSToomas Soome typedef struct { 14825ffb0c9bSToomas Soome mDNSu32 rrauth_size; // Total number of available auth entries 14835ffb0c9bSToomas Soome mDNSu32 rrauth_totalused; // Number of auth entries currently occupied 14845ffb0c9bSToomas Soome mDNSu32 rrauth_report; 14855ffb0c9bSToomas Soome mDNSu8 rrauth_lock; // For debugging: Set at times when these lists may not be modified 14865ffb0c9bSToomas Soome AuthEntity *rrauth_free; 14875ffb0c9bSToomas Soome AuthGroup *rrauth_hash[AUTH_HASH_SLOTS]; 14885ffb0c9bSToomas Soome }AuthHash; 14895ffb0c9bSToomas Soome 14905ffb0c9bSToomas Soome // AuthRecordAny includes mDNSInterface_Any and interface specific auth records. 14915ffb0c9bSToomas Soome typedef enum 14925ffb0c9bSToomas Soome { 14935ffb0c9bSToomas Soome AuthRecordAny, // registered for *Any, NOT including P2P interfaces 14945ffb0c9bSToomas Soome AuthRecordAnyIncludeP2P, // registered for *Any, including P2P interfaces 14955ffb0c9bSToomas Soome AuthRecordAnyIncludeAWDL, // registered for *Any, including AWDL interface 14965ffb0c9bSToomas Soome AuthRecordAnyIncludeAWDLandP2P, // registered for *Any, including AWDL and P2P interfaces 14975ffb0c9bSToomas Soome AuthRecordLocalOnly, 14985ffb0c9bSToomas Soome AuthRecordP2P // discovered over D2D/P2P framework 14995ffb0c9bSToomas Soome } AuthRecType; 15005ffb0c9bSToomas Soome 15015ffb0c9bSToomas Soome typedef enum 15025ffb0c9bSToomas Soome { 15035ffb0c9bSToomas Soome AuthFlagsWakeOnly = 0x1 // WakeOnly service 15045ffb0c9bSToomas Soome } AuthRecordFlags; 15054b22b933Srs 15064b22b933Srs struct AuthRecord_struct 15075ffb0c9bSToomas Soome { 15085ffb0c9bSToomas Soome // For examples of how to set up this structure for use in mDNS_Register(), 15095ffb0c9bSToomas Soome // see mDNS_AdvertiseInterface() or mDNS_RegisterService(). 15105ffb0c9bSToomas Soome // Basically, resrec and persistent metadata need to be set up before calling mDNS_Register(). 15115ffb0c9bSToomas Soome // mDNS_SetupResourceRecord() is avaliable as a helper routine to set up most fields to sensible default values for you 15125ffb0c9bSToomas Soome 15135ffb0c9bSToomas Soome AuthRecord *next; // Next in list; first element of structure for efficiency reasons 15145ffb0c9bSToomas Soome // Field Group 1: Common ResourceRecord fields 1515cda73f64SToomas Soome ResourceRecord resrec; // 36 bytes when compiling for 32-bit; 48 when compiling for 64-bit (now 44/64) 15165ffb0c9bSToomas Soome 15175ffb0c9bSToomas Soome // Field Group 2: Persistent metadata for Authoritative Records 15185ffb0c9bSToomas Soome AuthRecord *Additional1; // Recommended additional record to include in response (e.g. SRV for PTR record) 15195ffb0c9bSToomas Soome AuthRecord *Additional2; // Another additional (e.g. TXT for PTR record) 15205ffb0c9bSToomas Soome AuthRecord *DependentOn; // This record depends on another for its uniqueness checking 15215ffb0c9bSToomas Soome AuthRecord *RRSet; // This unique record is part of an RRSet 15225ffb0c9bSToomas Soome mDNSRecordCallback *RecordCallback; // Callback function to call for state changes, and to free memory asynchronously on deregistration 15235ffb0c9bSToomas Soome void *RecordContext; // Context parameter for the callback function 15245ffb0c9bSToomas Soome mDNSu8 AutoTarget; // Set if the target of this record (PTR, CNAME, SRV, etc.) is our host name 15255ffb0c9bSToomas Soome mDNSu8 AllowRemoteQuery; // Set if we allow hosts not on the local link to query this record 15265ffb0c9bSToomas Soome mDNSu8 ForceMCast; // Set by client to advertise solely via multicast, even for apparently unicast names 15275ffb0c9bSToomas Soome mDNSu8 AuthFlags; 15285ffb0c9bSToomas Soome 15295ffb0c9bSToomas Soome OwnerOptData WakeUp; // WakeUp.HMAC.l[0] nonzero indicates that this is a Sleep Proxy record 15305ffb0c9bSToomas Soome mDNSAddr AddressProxy; // For reverse-mapping Sleep Proxy PTR records, address in question 15315ffb0c9bSToomas Soome mDNSs32 TimeRcvd; // In platform time units 15325ffb0c9bSToomas Soome mDNSs32 TimeExpire; // In platform time units 15335ffb0c9bSToomas Soome AuthRecType ARType; // LocalOnly, P2P or Normal ? 15345ffb0c9bSToomas Soome mDNSs32 KATimeExpire; // In platform time units: time to send keepalive packet for the proxy record 15355ffb0c9bSToomas Soome 15365ffb0c9bSToomas Soome // Field Group 3: Transient state for Authoritative Records 15375ffb0c9bSToomas Soome mDNSu8 Acknowledged; // Set if we've given the success callback to the client 15385ffb0c9bSToomas Soome mDNSu8 ProbeRestartCount; // Number of times we have restarted probing 15395ffb0c9bSToomas Soome mDNSu8 ProbeCount; // Number of probes remaining before this record is valid (kDNSRecordTypeUnique) 15405ffb0c9bSToomas Soome mDNSu8 AnnounceCount; // Number of announcements remaining (kDNSRecordTypeShared) 15415ffb0c9bSToomas Soome mDNSu8 RequireGoodbye; // Set if this RR has been announced on the wire and will require a goodbye packet 15425ffb0c9bSToomas Soome mDNSu8 AnsweredLocalQ; // Set if this AuthRecord has been delivered to any local question (LocalOnly or mDNSInterface_Any) 15435ffb0c9bSToomas Soome mDNSu8 IncludeInProbe; // Set if this RR is being put into a probe right now 15445ffb0c9bSToomas Soome mDNSu8 ImmedUnicast; // Set if we may send our response directly via unicast to the requester 15455ffb0c9bSToomas Soome mDNSInterfaceID SendNSECNow; // Set if we need to generate associated NSEC data for this rrname 15465ffb0c9bSToomas Soome mDNSInterfaceID ImmedAnswer; // Someone on this interface issued a query we need to answer (all-ones for all interfaces) 15474b22b933Srs #if MDNS_LOG_ANSWER_SUPPRESSION_TIMES 15485ffb0c9bSToomas Soome mDNSs32 ImmedAnswerMarkTime; 15494b22b933Srs #endif 15505ffb0c9bSToomas Soome mDNSInterfaceID ImmedAdditional; // Hint that we might want to also send this record, just to be helpful 15515ffb0c9bSToomas Soome mDNSInterfaceID SendRNow; // The interface this query is being sent on right now 15525ffb0c9bSToomas Soome mDNSv4Addr v4Requester; // Recent v4 query for this record, or all-ones if more than one recent query 15535ffb0c9bSToomas Soome mDNSv6Addr v6Requester; // Recent v6 query for this record, or all-ones if more than one recent query 15545ffb0c9bSToomas Soome AuthRecord *NextResponse; // Link to the next element in the chain of responses to generate 15555ffb0c9bSToomas Soome const mDNSu8 *NR_AnswerTo; // Set if this record was selected by virtue of being a direct answer to a question 15565ffb0c9bSToomas Soome AuthRecord *NR_AdditionalTo; // Set if this record was selected by virtue of being additional to another 15575ffb0c9bSToomas Soome mDNSs32 ThisAPInterval; // In platform time units: Current interval for announce/probe 15585ffb0c9bSToomas Soome mDNSs32 LastAPTime; // In platform time units: Last time we sent announcement/probe 15595ffb0c9bSToomas Soome mDNSs32 LastMCTime; // Last time we multicast this record (used to guard against packet-storm attacks) 15605ffb0c9bSToomas Soome mDNSInterfaceID LastMCInterface; // Interface this record was multicast on at the time LastMCTime was recorded 15615ffb0c9bSToomas Soome RData *NewRData; // Set if we are updating this record with new rdata 15625ffb0c9bSToomas Soome mDNSu16 newrdlength; // ... and the length of the new RData 15635ffb0c9bSToomas Soome mDNSRecordUpdateCallback *UpdateCallback; 15645ffb0c9bSToomas Soome mDNSu32 UpdateCredits; // Token-bucket rate limiting of excessive updates 15655ffb0c9bSToomas Soome mDNSs32 NextUpdateCredit; // Time next token is added to bucket 15665ffb0c9bSToomas Soome mDNSs32 UpdateBlocked; // Set if update delaying is in effect 15675ffb0c9bSToomas Soome 15685ffb0c9bSToomas Soome // Field Group 4: Transient uDNS state for Authoritative Records 15695ffb0c9bSToomas Soome regState_t state; // Maybe combine this with resrec.RecordType state? Right now it's ambiguous and confusing. 15705ffb0c9bSToomas Soome // e.g. rr->resrec.RecordType can be kDNSRecordTypeUnregistered, 15715ffb0c9bSToomas Soome // and rr->state can be regState_Unregistered 15725ffb0c9bSToomas Soome // What if we find one of those statements is true and the other false? What does that mean? 15735ffb0c9bSToomas Soome mDNSBool uselease; // dynamic update contains (should contain) lease option 15745ffb0c9bSToomas Soome mDNSs32 expire; // In platform time units: expiration of lease (-1 for static) 15755ffb0c9bSToomas Soome mDNSBool Private; // If zone is private, DNS updates may have to be encrypted to prevent eavesdropping 15765ffb0c9bSToomas Soome mDNSOpaque16 updateid; // Identifier to match update request and response -- also used when transferring records to Sleep Proxy 15775ffb0c9bSToomas Soome mDNSOpaque64 updateIntID; // Interface IDs (one bit per interface index)to which updates have been sent 15785ffb0c9bSToomas Soome const domainname *zone; // the zone that is updated 15795ffb0c9bSToomas Soome ZoneData *nta; 15805ffb0c9bSToomas Soome struct tcpInfo_t *tcp; 15815ffb0c9bSToomas Soome NATTraversalInfo NATinfo; 15825ffb0c9bSToomas Soome mDNSBool SRVChanged; // temporarily deregistered service because its SRV target or port changed 15835ffb0c9bSToomas Soome mergeState_t mState; // Unicast Record Registrations merge state 15845ffb0c9bSToomas Soome mDNSu8 refreshCount; // Number of refreshes to the server 15855ffb0c9bSToomas Soome mStatus updateError; // Record update resulted in Error ? 15865ffb0c9bSToomas Soome 15875ffb0c9bSToomas Soome // uDNS_UpdateRecord support fields 15885ffb0c9bSToomas Soome // Do we really need all these in *addition* to NewRData and newrdlength above? 15895ffb0c9bSToomas Soome void *UpdateContext; // Context parameter for the update callback function 15905ffb0c9bSToomas Soome mDNSu16 OrigRDLen; // previously registered, being deleted 15915ffb0c9bSToomas Soome mDNSu16 InFlightRDLen; // currently being registered 15925ffb0c9bSToomas Soome mDNSu16 QueuedRDLen; // pending operation (re-transmitting if necessary) THEN register the queued update 15935ffb0c9bSToomas Soome RData *OrigRData; 15945ffb0c9bSToomas Soome RData *InFlightRData; 15955ffb0c9bSToomas Soome RData *QueuedRData; 15965ffb0c9bSToomas Soome 15975ffb0c9bSToomas Soome // Field Group 5: Large data objects go at the end 15985ffb0c9bSToomas Soome domainname namestorage; 15995ffb0c9bSToomas Soome RData rdatastorage; // Normally the storage is right here, except for oversized records 16005ffb0c9bSToomas Soome // rdatastorage MUST be the last thing in the structure -- when using oversized AuthRecords, extra bytes 16015ffb0c9bSToomas Soome // are appended after the end of the AuthRecord, logically augmenting the size of the rdatastorage 16025ffb0c9bSToomas Soome // DO NOT ADD ANY MORE FIELDS HERE 16035ffb0c9bSToomas Soome }; 16045ffb0c9bSToomas Soome 16055ffb0c9bSToomas Soome // IsLocalDomain alone is not sufficient to determine that a record is mDNS or uDNS. By default domain names within 16065ffb0c9bSToomas Soome // the "local" pseudo-TLD (and within the IPv4 and IPv6 link-local reverse mapping domains) are automatically treated 16075ffb0c9bSToomas Soome // as mDNS records, but it is also possible to force any record (even those not within one of the inherently local 16085ffb0c9bSToomas Soome // domains) to be handled as an mDNS record by setting the ForceMCast flag, or by setting a non-zero InterfaceID. 16095ffb0c9bSToomas Soome // For example, the reverse-mapping PTR record created in AdvertiseInterface sets the ForceMCast flag, since it points to 16105ffb0c9bSToomas Soome // a dot-local hostname, and therefore it would make no sense to register this record with a wide-area Unicast DNS server. 16115ffb0c9bSToomas Soome // The same applies to Sleep Proxy records, which we will answer for when queried via mDNS, but we never want to try 16125ffb0c9bSToomas Soome // to register them with a wide-area Unicast DNS server -- and we probably don't have the required credentials anyway. 16135ffb0c9bSToomas Soome // Currently we have no concept of a wide-area uDNS record scoped to a particular interface, so if the InterfaceID is 16145ffb0c9bSToomas Soome // nonzero we treat this the same as ForceMCast. 16155ffb0c9bSToomas Soome // Note: Question_uDNS(Q) is used in *only* one place -- on entry to mDNS_StartQuery_internal, to decide whether to set TargetQID. 16165ffb0c9bSToomas Soome // Everywhere else in the code, the determination of whether a question is unicast is made by checking to see if TargetQID is nonzero. 16175ffb0c9bSToomas Soome #define AuthRecord_uDNS(R) ((R)->resrec.InterfaceID == mDNSInterface_Any && !(R)->ForceMCast && !IsLocalDomain((R)->resrec.name)) 16185ffb0c9bSToomas Soome #define Question_uDNS(Q) ((Q)->InterfaceID == mDNSInterface_Unicast || (Q)->ProxyQuestion || \ 1619c65ebfc7SToomas Soome ((Q)->InterfaceID != mDNSInterface_LocalOnly && (Q)->InterfaceID != mDNSInterface_P2P && (Q)->InterfaceID != mDNSInterface_BLE && !(Q)->ForceMCast && !IsLocalDomain(&(Q)->qname))) 16205ffb0c9bSToomas Soome 1621c65ebfc7SToomas Soome // AuthRecordLocalOnly records are registered using mDNSInterface_LocalOnly and 1622c65ebfc7SToomas Soome // AuthRecordP2P records are created by D2DServiceFound events. Both record types are kept on the same list. 16235ffb0c9bSToomas Soome #define RRLocalOnly(rr) ((rr)->ARType == AuthRecordLocalOnly || (rr)->ARType == AuthRecordP2P) 16245ffb0c9bSToomas Soome 1625c65ebfc7SToomas Soome // All other auth records, not including those defined as RRLocalOnly(). 16265ffb0c9bSToomas Soome #define RRAny(rr) ((rr)->ARType == AuthRecordAny || (rr)->ARType == AuthRecordAnyIncludeP2P || (rr)->ARType == AuthRecordAnyIncludeAWDL || (rr)->ARType == AuthRecordAnyIncludeAWDLandP2P) 16275ffb0c9bSToomas Soome 16285ffb0c9bSToomas Soome // Question (A or AAAA) that is suppressed currently because IPv4 or IPv6 address 16295ffb0c9bSToomas Soome // is not available locally for A or AAAA question respectively. Also, if the 16305ffb0c9bSToomas Soome // query is disallowed for the "pid" that we are sending on behalf of, suppress it. 16315ffb0c9bSToomas Soome #define QuerySuppressed(Q) (((Q)->SuppressUnusable && (Q)->SuppressQuery) || ((Q)->DisallowPID)) 16325ffb0c9bSToomas Soome 16335ffb0c9bSToomas Soome #define PrivateQuery(Q) ((Q)->AuthInfo && (Q)->AuthInfo->AutoTunnel) 16345ffb0c9bSToomas Soome 16355ffb0c9bSToomas Soome // Normally we always lookup the cache and /etc/hosts before sending the query on the wire. For single label 16365ffb0c9bSToomas Soome // queries (A and AAAA) that are unqualified (indicated by AppendSearchDomains), we want to append search 16375ffb0c9bSToomas Soome // domains before we try them as such 16385ffb0c9bSToomas Soome #define ApplySearchDomainsFirst(q) ((q)->AppendSearchDomains && (CountLabels(&((q)->qname))) == 1) 16394b22b933Srs 16404b22b933Srs // Wrapper struct for Auth Records for higher-level code that cannot use the AuthRecord's ->next pointer field 16414b22b933Srs typedef struct ARListElem 16425ffb0c9bSToomas Soome { 16435ffb0c9bSToomas Soome struct ARListElem *next; 16445ffb0c9bSToomas Soome AuthRecord ar; // Note: Must be last element of structure, to accomodate oversized AuthRecords 16455ffb0c9bSToomas Soome } ARListElem; 16464b22b933Srs 16474b22b933Srs struct CacheRecord_struct 16485ffb0c9bSToomas Soome { 16495ffb0c9bSToomas Soome CacheRecord *next; // Next in list; first element of structure for efficiency reasons 1650cda73f64SToomas Soome ResourceRecord resrec; // 36 bytes when compiling for 32-bit; 48 when compiling for 64-bit (now 44/64) 16515ffb0c9bSToomas Soome 16525ffb0c9bSToomas Soome // Transient state for Cache Records 16535ffb0c9bSToomas Soome CacheRecord *NextInKAList; // Link to the next element in the chain of known answers to send 16545ffb0c9bSToomas Soome mDNSs32 TimeRcvd; // In platform time units 16555ffb0c9bSToomas Soome mDNSs32 DelayDelivery; // Set if we want to defer delivery of this answer to local clients 16565ffb0c9bSToomas Soome mDNSs32 NextRequiredQuery; // In platform time units 1657*3b436d06SToomas Soome // Extra four bytes here (on 64bit) 16585ffb0c9bSToomas Soome DNSQuestion *CRActiveQuestion; // Points to an active question referencing this answer. Can never point to a NewQuestion. 16595ffb0c9bSToomas Soome mDNSs32 LastUnansweredTime; // In platform time units; last time we incremented UnansweredQueries 16605ffb0c9bSToomas Soome mDNSu8 UnansweredQueries; // Number of times we've issued a query for this record without getting an answer 16615ffb0c9bSToomas Soome mDNSu8 CRDNSSECQuestion; // Set to 1 if this was created in response to a DNSSEC question 16625ffb0c9bSToomas Soome mDNSOpaque16 responseFlags; // Second 16 bit in the DNS response 16635ffb0c9bSToomas Soome CacheRecord *NextInCFList; // Set if this is in the list of records we just received with the cache flush bit set 16645ffb0c9bSToomas Soome CacheRecord *nsec; // NSEC records needed for non-existence proofs 16655ffb0c9bSToomas Soome CacheRecord *soa; // SOA record to return for proxy questions 16665ffb0c9bSToomas Soome 16675ffb0c9bSToomas Soome mDNSAddr sourceAddress; // node from which we received this record 1668cda73f64SToomas Soome // Size to here is 76 bytes when compiling 32-bit; 104 bytes when compiling 64-bit (now 160 bytes for 64-bit) 16695ffb0c9bSToomas Soome RData_small smallrdatastorage; // Storage for small records is right here (4 bytes header + 68 bytes data = 72 bytes) 16705ffb0c9bSToomas Soome }; 16715ffb0c9bSToomas Soome 16725ffb0c9bSToomas Soome // Should match the CacheGroup_struct members, except namestorage[]. Only used to calculate 1673cda73f64SToomas Soome // the size of the namestorage array in CacheGroup_struct so that sizeof(CacheGroup) == sizeof(CacheRecord) 16745ffb0c9bSToomas Soome struct CacheGroup_base 16755ffb0c9bSToomas Soome { 16765ffb0c9bSToomas Soome CacheGroup *next; 16775ffb0c9bSToomas Soome mDNSu32 namehash; 16785ffb0c9bSToomas Soome CacheRecord *members; 16795ffb0c9bSToomas Soome CacheRecord **rrcache_tail; 16805ffb0c9bSToomas Soome domainname *name; 16815ffb0c9bSToomas Soome }; 16825ffb0c9bSToomas Soome 16835ffb0c9bSToomas Soome struct CacheGroup_struct // Header object for a list of CacheRecords with the same name 16845ffb0c9bSToomas Soome { 16855ffb0c9bSToomas Soome CacheGroup *next; // Next CacheGroup object in this hash table bucket 16865ffb0c9bSToomas Soome mDNSu32 namehash; // Name-based (i.e. case insensitive) hash of name 16875ffb0c9bSToomas Soome CacheRecord *members; // List of CacheRecords with this same name 16885ffb0c9bSToomas Soome CacheRecord **rrcache_tail; // Tail end of that list 16895ffb0c9bSToomas Soome domainname *name; // Common name for all CacheRecords in this list 16905ffb0c9bSToomas Soome mDNSu8 namestorage[sizeof(CacheRecord) - sizeof(struct CacheGroup_base)]; // match sizeof(CacheRecord) 16915ffb0c9bSToomas Soome }; 16924b22b933Srs 16934b22b933Srs // Storage sufficient to hold either a CacheGroup header or a CacheRecord 16945ffb0c9bSToomas Soome // -- for best efficiency (to avoid wasted unused storage) they should be the same size 16954b22b933Srs typedef union CacheEntity_union CacheEntity; 16964b22b933Srs union CacheEntity_union { CacheEntity *next; CacheGroup cg; CacheRecord cr; }; 16974b22b933Srs 16984b22b933Srs typedef struct 16995ffb0c9bSToomas Soome { 17005ffb0c9bSToomas Soome CacheRecord r; 17015ffb0c9bSToomas Soome mDNSu8 _extradata[MaximumRDSize-InlineCacheRDSize]; // Glue on the necessary number of extra bytes 17025ffb0c9bSToomas Soome domainname namestorage; // Needs to go *after* the extra rdata bytes 17035ffb0c9bSToomas Soome } LargeCacheRecord; 17045ffb0c9bSToomas Soome 17055ffb0c9bSToomas Soome typedef struct HostnameInfo 17065ffb0c9bSToomas Soome { 17075ffb0c9bSToomas Soome struct HostnameInfo *next; 17085ffb0c9bSToomas Soome NATTraversalInfo natinfo; 17094b22b933Srs domainname fqdn; 17105ffb0c9bSToomas Soome AuthRecord arv4; // registered IPv4 address record 17115ffb0c9bSToomas Soome AuthRecord arv6; // registered IPv6 address record 17125ffb0c9bSToomas Soome mDNSRecordCallback *StatusCallback; // callback to deliver success or error code to client layer 17135ffb0c9bSToomas Soome const void *StatusContext; // Client Context 17145ffb0c9bSToomas Soome } HostnameInfo; 17154b22b933Srs 17164b22b933Srs typedef struct ExtraResourceRecord_struct ExtraResourceRecord; 17174b22b933Srs struct ExtraResourceRecord_struct 17185ffb0c9bSToomas Soome { 17195ffb0c9bSToomas Soome ExtraResourceRecord *next; 17204b22b933Srs mDNSu32 ClientID; // Opaque ID field to be used by client to map an AddRecord call to a set of Extra records 17215ffb0c9bSToomas Soome AuthRecord r; 17225ffb0c9bSToomas Soome // Note: Add any additional fields *before* the AuthRecord in this structure, not at the end. 17235ffb0c9bSToomas Soome // In some cases clients can allocate larger chunks of memory and set r->rdata->MaxRDLength to indicate 17245ffb0c9bSToomas Soome // that this extra memory is available, which would result in any fields after the AuthRecord getting smashed 17255ffb0c9bSToomas Soome }; 17265ffb0c9bSToomas Soome 17275ffb0c9bSToomas Soome // Note: Within an mDNSServiceCallback mDNS all API calls are legal except mDNS_Init(), mDNS_Exit(), mDNS_Execute() 17285ffb0c9bSToomas Soome typedef void mDNSServiceCallback (mDNS *const m, ServiceRecordSet *const sr, mStatus result); 17295ffb0c9bSToomas Soome 17305ffb0c9bSToomas Soome // A ServiceRecordSet has no special meaning to the core code of the Multicast DNS protocol engine; 17315ffb0c9bSToomas Soome // it is just a convenience structure to group together the records that make up a standard service 17325ffb0c9bSToomas Soome // registration so that they can be allocted and deallocted together as a single memory object. 17335ffb0c9bSToomas Soome // It contains its own ServiceCallback+ServiceContext to report aggregate results up to the next layer of software above. 17345ffb0c9bSToomas Soome // It also contains: 17355ffb0c9bSToomas Soome // * the basic PTR/SRV/TXT triplet used to represent any DNS-SD service 17365ffb0c9bSToomas Soome // * the "_services" PTR record for service enumeration 17375ffb0c9bSToomas Soome // * the optional list of SubType PTR records 17385ffb0c9bSToomas Soome // * the optional list of additional records attached to the service set (e.g. iChat pictures) 17394b22b933Srs 17404b22b933Srs struct ServiceRecordSet_struct 17415ffb0c9bSToomas Soome { 17425ffb0c9bSToomas Soome // These internal state fields are used internally by mDNSCore; the client layer needn't be concerned with them. 17435ffb0c9bSToomas Soome // No fields need to be set up by the client prior to calling mDNS_RegisterService(); 17445ffb0c9bSToomas Soome // all required data is passed as parameters to that function. 17455ffb0c9bSToomas Soome mDNSServiceCallback *ServiceCallback; 17465ffb0c9bSToomas Soome void *ServiceContext; 17475ffb0c9bSToomas Soome mDNSBool Conflict; // Set if this record set was forcibly deregistered because of a conflict 17485ffb0c9bSToomas Soome 17495ffb0c9bSToomas Soome ExtraResourceRecord *Extras; // Optional list of extra AuthRecords attached to this service registration 17505ffb0c9bSToomas Soome mDNSu32 NumSubTypes; 17515ffb0c9bSToomas Soome AuthRecord *SubTypes; 17525ffb0c9bSToomas Soome const mDNSu8 *AnonData; 1753c65ebfc7SToomas Soome mDNSu32 flags; // saved for subsequent calls to mDNS_RegisterService() if records 17545ffb0c9bSToomas Soome // need to be re-registered. 17555ffb0c9bSToomas Soome AuthRecord RR_ADV; // e.g. _services._dns-sd._udp.local. PTR _printer._tcp.local. 17565ffb0c9bSToomas Soome AuthRecord RR_PTR; // e.g. _printer._tcp.local. PTR Name._printer._tcp.local. 17575ffb0c9bSToomas Soome AuthRecord RR_SRV; // e.g. Name._printer._tcp.local. SRV 0 0 port target 17585ffb0c9bSToomas Soome AuthRecord RR_TXT; // e.g. Name._printer._tcp.local. TXT PrintQueueName 17595ffb0c9bSToomas Soome // Don't add any fields after AuthRecord RR_TXT. 17605ffb0c9bSToomas Soome // This is where the implicit extra space goes if we allocate a ServiceRecordSet containing an oversized RR_TXT record 17615ffb0c9bSToomas Soome }; 17624b22b933Srs 17634b22b933Srs // *************************************************************************** 17644b22b933Srs #if 0 17655ffb0c9bSToomas Soome #pragma mark - 17664b22b933Srs #pragma mark - Question structures 17674b22b933Srs #endif 17684b22b933Srs 17694b22b933Srs // We record the last eight instances of each duplicate query 17705ffb0c9bSToomas Soome // This gives us v4/v6 on each of Ethernet, AirPort and Firewire, and two free slots "for future expansion" 17714b22b933Srs // If the host has more active interfaces that this it is not fatal -- duplicate question suppression will degrade gracefully. 17724b22b933Srs // Since we will still remember the last eight, the busiest interfaces will still get the effective duplicate question suppression. 17734b22b933Srs #define DupSuppressInfoSize 8 17744b22b933Srs 17754b22b933Srs typedef struct 17765ffb0c9bSToomas Soome { 17775ffb0c9bSToomas Soome mDNSs32 Time; 17785ffb0c9bSToomas Soome mDNSInterfaceID InterfaceID; 17795ffb0c9bSToomas Soome mDNSs32 Type; // v4 or v6? 17805ffb0c9bSToomas Soome } DupSuppressInfo; 17814b22b933Srs 17824b22b933Srs typedef enum 17835ffb0c9bSToomas Soome { 17845ffb0c9bSToomas Soome LLQ_InitialRequest = 1, 17855ffb0c9bSToomas Soome LLQ_SecondaryRequest = 2, 17865ffb0c9bSToomas Soome LLQ_Established = 3, 17875ffb0c9bSToomas Soome LLQ_Poll = 4 17885ffb0c9bSToomas Soome } LLQ_State; 17894b22b933Srs 17904b22b933Srs // LLQ constants 17914b22b933Srs #define kLLQ_Vers 1 17924b22b933Srs #define kLLQ_DefLease 7200 // 2 hours 17934b22b933Srs #define kLLQ_MAX_TRIES 3 // retry an operation 3 times max 17944b22b933Srs #define kLLQ_INIT_RESEND 2 // resend an un-ack'd packet after 2 seconds, then double for each additional 17954b22b933Srs // LLQ Operation Codes 17964b22b933Srs #define kLLQOp_Setup 1 17974b22b933Srs #define kLLQOp_Refresh 2 17984b22b933Srs #define kLLQOp_Event 3 17994b22b933Srs 18004b22b933Srs // LLQ Errror Codes 18014b22b933Srs enum 18025ffb0c9bSToomas Soome { 18035ffb0c9bSToomas Soome LLQErr_NoError = 0, 18045ffb0c9bSToomas Soome LLQErr_ServFull = 1, 18055ffb0c9bSToomas Soome LLQErr_Static = 2, 18065ffb0c9bSToomas Soome LLQErr_FormErr = 3, 18075ffb0c9bSToomas Soome LLQErr_NoSuchLLQ = 4, 18085ffb0c9bSToomas Soome LLQErr_BadVers = 5, 18095ffb0c9bSToomas Soome LLQErr_UnknownErr = 6 18105ffb0c9bSToomas Soome }; 18115ffb0c9bSToomas Soome 18125ffb0c9bSToomas Soome enum { NoAnswer_Normal = 0, NoAnswer_Suspended = 1, NoAnswer_Fail = 2 }; 18135ffb0c9bSToomas Soome 1814c65ebfc7SToomas Soome // DNS Push Notification 1815c65ebfc7SToomas Soome typedef enum 1816c65ebfc7SToomas Soome { 1817c65ebfc7SToomas Soome DNSPUSH_NOERROR = 0, 1818c65ebfc7SToomas Soome DNSPUSH_FORMERR = 1, 1819c65ebfc7SToomas Soome DNSPUSH_SERVFAIL = 2, 1820c65ebfc7SToomas Soome DNSPUSH_NOTIMP = 4, 1821c65ebfc7SToomas Soome DNSPUSH_REFUSED = 5 1822c65ebfc7SToomas Soome } DNSPUSH_ErrorCode; 1823c65ebfc7SToomas Soome 1824c65ebfc7SToomas Soome typedef enum { 1825c65ebfc7SToomas Soome DNSPUSH_INIT = 1, 1826c65ebfc7SToomas Soome DNSPUSH_NOSERVER = 2, 1827c65ebfc7SToomas Soome DNSPUSH_SERVERFOUND = 3, 1828c65ebfc7SToomas Soome DNSPUSH_ESTABLISHED = 4 1829c65ebfc7SToomas Soome } DNSPush_State; 1830*3b436d06SToomas Soome 1831*3b436d06SToomas Soome enum { 1832*3b436d06SToomas Soome AllowExpired_None = 0, // Don't allow expired answers or mark answers immortal (behave normally) 1833*3b436d06SToomas Soome AllowExpired_MakeAnswersImmortal = 1, // Any answers to this question get marked as immortal 1834*3b436d06SToomas Soome AllowExpired_AllowExpiredAnswers = 2 // Allow already expired answers from the cache 1835*3b436d06SToomas Soome }; 1836*3b436d06SToomas Soome typedef mDNSu8 AllowExpiredState; 1837c65ebfc7SToomas Soome 18385ffb0c9bSToomas Soome #define HMAC_LEN 64 18395ffb0c9bSToomas Soome #define HMAC_IPAD 0x36 18405ffb0c9bSToomas Soome #define HMAC_OPAD 0x5c 18415ffb0c9bSToomas Soome #define MD5_LEN 16 18425ffb0c9bSToomas Soome 18435ffb0c9bSToomas Soome #define AutoTunnelUnregistered(X) ( \ 18445ffb0c9bSToomas Soome (X)->AutoTunnelHostRecord.resrec.RecordType == kDNSRecordTypeUnregistered && \ 18455ffb0c9bSToomas Soome (X)->AutoTunnelTarget.resrec.RecordType == kDNSRecordTypeUnregistered && \ 18465ffb0c9bSToomas Soome (X)->AutoTunnelDeviceInfo.resrec.RecordType == kDNSRecordTypeUnregistered && \ 18475ffb0c9bSToomas Soome (X)->AutoTunnelService.resrec.RecordType == kDNSRecordTypeUnregistered && \ 18485ffb0c9bSToomas Soome (X)->AutoTunnel6Record.resrec.RecordType == kDNSRecordTypeUnregistered ) 18495ffb0c9bSToomas Soome 18505ffb0c9bSToomas Soome // Internal data structure to maintain authentication information 18515ffb0c9bSToomas Soome typedef struct DomainAuthInfo 18525ffb0c9bSToomas Soome { 18535ffb0c9bSToomas Soome struct DomainAuthInfo *next; 18545ffb0c9bSToomas Soome mDNSs32 deltime; // If we're planning to delete this DomainAuthInfo, the time we want it deleted 18555ffb0c9bSToomas Soome mDNSBool AutoTunnel; // Whether this is AutoTunnel 18565ffb0c9bSToomas Soome AuthRecord AutoTunnelHostRecord; // User-visible hostname; used as SRV target for AutoTunnel services 18575ffb0c9bSToomas Soome AuthRecord AutoTunnelTarget; // Opaque hostname of tunnel endpoint; used as SRV target for AutoTunnelService record 18585ffb0c9bSToomas Soome AuthRecord AutoTunnelDeviceInfo; // Device info of tunnel endpoint 18595ffb0c9bSToomas Soome AuthRecord AutoTunnelService; // Service record (possibly NAT-Mapped) of IKE daemon implementing tunnel endpoint 18605ffb0c9bSToomas Soome AuthRecord AutoTunnel6Record; // AutoTunnel AAAA Record obtained from awacsd 18615ffb0c9bSToomas Soome mDNSBool AutoTunnelServiceStarted; // Whether a service has been registered in this domain 18625ffb0c9bSToomas Soome mDNSv6Addr AutoTunnelInnerAddress; 18635ffb0c9bSToomas Soome domainname domain; 18645ffb0c9bSToomas Soome domainname keyname; 18655ffb0c9bSToomas Soome domainname hostname; 18665ffb0c9bSToomas Soome mDNSIPPort port; 18675ffb0c9bSToomas Soome char b64keydata[32]; 18685ffb0c9bSToomas Soome mDNSu8 keydata_ipad[HMAC_LEN]; // padded key for inner hash rounds 18695ffb0c9bSToomas Soome mDNSu8 keydata_opad[HMAC_LEN]; // padded key for outer hash rounds 18705ffb0c9bSToomas Soome } DomainAuthInfo; 18715ffb0c9bSToomas Soome 18725ffb0c9bSToomas Soome // Note: Within an mDNSQuestionCallback mDNS all API calls are legal except mDNS_Init(), mDNS_Exit(), mDNS_Execute() 18735ffb0c9bSToomas Soome // Note: Any value other than QC_rmv i.e., any non-zero value will result in kDNSServiceFlagsAdd to the application 18745ffb0c9bSToomas Soome // layer. These values are used within mDNSResponder and not sent across to the application. QC_addnocache is for 18755ffb0c9bSToomas Soome // delivering a response without adding to the cache. QC_forceresponse is superset of QC_addnocache where in 18765ffb0c9bSToomas Soome // addition to not entering in the cache, it also forces the negative response through. 18775ffb0c9bSToomas Soome typedef enum { QC_rmv = 0, QC_add, QC_addnocache, QC_forceresponse, QC_dnssec , QC_nodnssec, QC_suppressed } QC_result; 18785ffb0c9bSToomas Soome typedef void mDNSQuestionCallback (mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord); 18795ffb0c9bSToomas Soome typedef void AsyncDispatchFunc(mDNS *const m, void *context); 18805ffb0c9bSToomas Soome typedef void DNSSECAuthInfoFreeCallback(mDNS *const m, void *context); 18815ffb0c9bSToomas Soome extern void mDNSPlatformDispatchAsync(mDNS *const m, void *context, AsyncDispatchFunc func); 18825ffb0c9bSToomas Soome 18835ffb0c9bSToomas Soome #define NextQSendTime(Q) ((Q)->LastQTime + (Q)->ThisQInterval) 18845ffb0c9bSToomas Soome #define ActiveQuestion(Q) ((Q)->ThisQInterval > 0 && !(Q)->DuplicateOf) 18855ffb0c9bSToomas Soome #define TimeToSendThisQuestion(Q,time) (ActiveQuestion(Q) && (time) - NextQSendTime(Q) >= 0) 18865ffb0c9bSToomas Soome 18875ffb0c9bSToomas Soome // q->ValidationStatus is either DNSSECValNotRequired or DNSSECValRequired and then moves onto DNSSECValInProgress. 18885ffb0c9bSToomas Soome // When Validation is done, we mark all "DNSSECValInProgress" questions "DNSSECValDone". If we are answering 18895ffb0c9bSToomas Soome // questions from /etc/hosts, then we go straight to DNSSECValDone from the initial state. 18905ffb0c9bSToomas Soome typedef enum { DNSSECValNotRequired = 0, DNSSECValRequired, DNSSECValInProgress, DNSSECValDone } DNSSECValState; 18915ffb0c9bSToomas Soome 18925ffb0c9bSToomas Soome // ValidationRequired can be set to the following values: 18935ffb0c9bSToomas Soome // 1894c65ebfc7SToomas Soome // SECURE validation is set to determine whether something is secure or bogus 18955ffb0c9bSToomas Soome // INSECURE validation is set internally by dnssec code to indicate that it is currently proving something 18965ffb0c9bSToomas Soome // is insecure 18975ffb0c9bSToomas Soome #define DNSSEC_VALIDATION_NONE 0x00 18985ffb0c9bSToomas Soome #define DNSSEC_VALIDATION_SECURE 0x01 18995ffb0c9bSToomas Soome #define DNSSEC_VALIDATION_SECURE_OPTIONAL 0x02 19005ffb0c9bSToomas Soome #define DNSSEC_VALIDATION_INSECURE 0x03 19015ffb0c9bSToomas Soome 19025ffb0c9bSToomas Soome // For both ValidationRequired and ValidatingResponse question, we validate DNSSEC responses. 19035ffb0c9bSToomas Soome // For ProxyQuestion with DNSSECOK, we just receive the DNSSEC records to pass them along without 19045ffb0c9bSToomas Soome // validation and if the CD bit is not set, we also validate. 19055ffb0c9bSToomas Soome #define DNSSECQuestion(q) ((q)->ValidationRequired || (q)->ValidatingResponse || ((q)->ProxyQuestion && (q)->ProxyDNSSECOK)) 19065ffb0c9bSToomas Soome 19075ffb0c9bSToomas Soome // ValidatingQuestion is used when we need to know whether we are validating the DNSSEC responses for a question 19085ffb0c9bSToomas Soome #define ValidatingQuestion(q) ((q)->ValidationRequired || (q)->ValidatingResponse) 19095ffb0c9bSToomas Soome 19105ffb0c9bSToomas Soome #define DNSSECOptionalQuestion(q) ((q)->ValidationRequired == DNSSEC_VALIDATION_SECURE_OPTIONAL) 19115ffb0c9bSToomas Soome 19125ffb0c9bSToomas Soome // Given the resource record and the question, should we follow the CNAME ? 19135ffb0c9bSToomas Soome #define FollowCNAME(q, rr, AddRecord) (AddRecord && (q)->qtype != kDNSType_CNAME && \ 19145ffb0c9bSToomas Soome (rr)->RecordType != kDNSRecordTypePacketNegative && \ 19155ffb0c9bSToomas Soome (rr)->rrtype == kDNSType_CNAME) 19165ffb0c9bSToomas Soome 1917c65ebfc7SToomas Soome // RFC 4122 defines it to be 16 bytes 19185ffb0c9bSToomas Soome #define UUID_SIZE 16 19195ffb0c9bSToomas Soome 1920*3b436d06SToomas Soome #define AWD_METRICS (USE_AWD && TARGET_OS_IOS) 1921c65ebfc7SToomas Soome 1922c65ebfc7SToomas Soome #if AWD_METRICS 1923*3b436d06SToomas Soome 1924*3b436d06SToomas Soome enum 1925cda73f64SToomas Soome { 1926*3b436d06SToomas Soome ExpiredAnswer_None = 0, // No expired answers used 1927*3b436d06SToomas Soome ExpiredAnswer_Allowed = 1, // An expired answer is allowed by this request 1928*3b436d06SToomas Soome ExpiredAnswer_AnsweredWithExpired = 2, // Question was answered with an expired answer 1929*3b436d06SToomas Soome ExpiredAnswer_ExpiredAnswerChanged = 3, // Expired answer changed on refresh 1930*3b436d06SToomas Soome 1931*3b436d06SToomas Soome ExpiredAnswer_EnumCount 1932*3b436d06SToomas Soome }; 1933*3b436d06SToomas Soome typedef mDNSu8 ExpiredAnswerMetric; 1934cda73f64SToomas Soome 1935*3b436d06SToomas Soome typedef struct 1936*3b436d06SToomas Soome { 1937*3b436d06SToomas Soome domainname * originalQName; // Name of original A/AAAA record if this question is for a CNAME record. 1938*3b436d06SToomas Soome mDNSu32 querySendCount; // Number of queries that have been sent to DNS servers so far. 1939*3b436d06SToomas Soome mDNSs32 firstQueryTime; // The time when the first query was sent to a DNS server. 1940*3b436d06SToomas Soome mDNSBool answered; // Has this question been answered? 1941*3b436d06SToomas Soome ExpiredAnswerMetric expiredAnswerState; // Expired answer state (see ExpiredAnswerMetric above) 1942*3b436d06SToomas Soome 1943cda73f64SToomas Soome } uDNSMetrics; 1944cda73f64SToomas Soome #endif 1945cda73f64SToomas Soome 1946c65ebfc7SToomas Soome // DNS64 code is only for iOS, which is currently the only Apple OS that supports DNS proxy network extensions. 1947c65ebfc7SToomas Soome #define USE_DNS64 (HAVE_DNS64 && TARGET_OS_IOS) 1948c65ebfc7SToomas Soome 1949c65ebfc7SToomas Soome #if USE_DNS64 1950c65ebfc7SToomas Soome #include "DNS64State.h" 1951c65ebfc7SToomas Soome #endif 1952c65ebfc7SToomas Soome 1953c65ebfc7SToomas Soome #if TARGET_OS_EMBEDDED 1954c65ebfc7SToomas Soome extern mDNSu32 curr_num_regservices; // tracks the current number of services registered 1955c65ebfc7SToomas Soome extern mDNSu32 max_num_regservices; // tracks the max number of simultaneous services registered by the device 1956c65ebfc7SToomas Soome #endif 1957c65ebfc7SToomas Soome 19584b22b933Srs struct DNSQuestion_struct 19595ffb0c9bSToomas Soome { 19605ffb0c9bSToomas Soome // Internal state fields. These are used internally by mDNSCore; the client layer needn't be concerned with them. 19615ffb0c9bSToomas Soome DNSQuestion *next; 19625ffb0c9bSToomas Soome mDNSu32 qnamehash; 19635ffb0c9bSToomas Soome mDNSs32 DelayAnswering; // Set if we want to defer answering this question until the cache settles 19645ffb0c9bSToomas Soome mDNSs32 LastQTime; // Last scheduled transmission of this Q on *all* applicable interfaces 19655ffb0c9bSToomas Soome mDNSs32 ThisQInterval; // LastQTime + ThisQInterval is the next scheduled transmission of this Q 19665ffb0c9bSToomas Soome // ThisQInterval > 0 for an active question; 19675ffb0c9bSToomas Soome // ThisQInterval = 0 for a suspended question that's still in the list 19685ffb0c9bSToomas Soome // ThisQInterval = -1 for a cancelled question (should not still be in list) 19695ffb0c9bSToomas Soome mDNSs32 ExpectUnicastResp; // Set when we send a query with the kDNSQClass_UnicastResponse bit set 19705ffb0c9bSToomas Soome mDNSs32 LastAnswerPktNum; // The sequence number of the last response packet containing an answer to this Q 19715ffb0c9bSToomas Soome mDNSu32 RecentAnswerPkts; // Number of answers since the last time we sent this query 19725ffb0c9bSToomas Soome mDNSu32 CurrentAnswers; // Number of records currently in the cache that answer this question 19735ffb0c9bSToomas Soome mDNSu32 BrowseThreshold; // If we have received at least this number of answers, 19745ffb0c9bSToomas Soome // set the next question interval to MaxQuestionInterval 19755ffb0c9bSToomas Soome mDNSu32 LargeAnswers; // Number of answers with rdata > 1024 bytes 19765ffb0c9bSToomas Soome mDNSu32 UniqueAnswers; // Number of answers received with kDNSClass_UniqueRRSet bit set 19775ffb0c9bSToomas Soome mDNSInterfaceID FlappingInterface1; // Set when an interface goes away, to flag if remove events are delivered for this Q 19785ffb0c9bSToomas Soome mDNSInterfaceID FlappingInterface2; // Set when an interface goes away, to flag if remove events are delivered for this Q 19795ffb0c9bSToomas Soome DomainAuthInfo *AuthInfo; // Non-NULL if query is currently being done using Private DNS 19805ffb0c9bSToomas Soome DNSQuestion *DuplicateOf; 19815ffb0c9bSToomas Soome DNSQuestion *NextInDQList; 19825ffb0c9bSToomas Soome AnonymousInfo *AnonInfo; // Anonymous Information 19835ffb0c9bSToomas Soome DupSuppressInfo DupSuppress[DupSuppressInfoSize]; 19845ffb0c9bSToomas Soome mDNSInterfaceID SendQNow; // The interface this query is being sent on right now 19855ffb0c9bSToomas Soome mDNSBool SendOnAll; // Set if we're sending this question on all active interfaces 1986c65ebfc7SToomas Soome mDNSBool CachedAnswerNeedsUpdate; // See SendQueries(). Set if we're sending this question 19875ffb0c9bSToomas Soome // because a cached answer needs to be refreshed. 19885ffb0c9bSToomas Soome mDNSu32 RequestUnicast; // Non-zero if we want to send query with kDNSQClass_UnicastResponse bit set 19895ffb0c9bSToomas Soome mDNSs32 LastQTxTime; // Last time this Q was sent on one (but not necessarily all) interfaces 19905ffb0c9bSToomas Soome mDNSu32 CNAMEReferrals; // Count of how many CNAME redirections we've done 19915ffb0c9bSToomas Soome mDNSBool SuppressQuery; // This query should be suppressed and not sent on the wire 19925ffb0c9bSToomas Soome mDNSu8 LOAddressAnswers; // Number of answers from the local only auth records that are 19935ffb0c9bSToomas Soome // answering A, AAAA, CNAME, or PTR (/etc/hosts) 19945ffb0c9bSToomas Soome mDNSu8 WakeOnResolveCount; // Number of wakes that should be sent on resolve 19955ffb0c9bSToomas Soome mDNSs32 StopTime; // Time this question should be stopped by giving them a negative answer 19965ffb0c9bSToomas Soome 19975ffb0c9bSToomas Soome // DNSSEC fields 19985ffb0c9bSToomas Soome DNSSECValState ValidationState; // Current state of the Validation process 19995ffb0c9bSToomas Soome DNSSECStatus ValidationStatus; // Validation status for "ValidationRequired" questions (dnssec) 20005ffb0c9bSToomas Soome mDNSu8 ValidatingResponse; // Question trying to validate a response (dnssec) on behalf of 20015ffb0c9bSToomas Soome // ValidationRequired question 20025ffb0c9bSToomas Soome void *DNSSECAuthInfo; 20035ffb0c9bSToomas Soome DNSSECAuthInfoFreeCallback *DAIFreeCallback; 20045ffb0c9bSToomas Soome 20055ffb0c9bSToomas Soome // Wide Area fields. These are used internally by the uDNS core (Unicast) 20065ffb0c9bSToomas Soome UDPSocket *LocalSocket; 20075ffb0c9bSToomas Soome 20085ffb0c9bSToomas Soome // |-> DNS Configuration related fields used in uDNS (Subset of Wide Area/Unicast fields) 20095ffb0c9bSToomas Soome DNSServer *qDNSServer; // Caching server for this query (in the absence of an SRV saying otherwise) 2010c65ebfc7SToomas Soome mDNSOpaque128 validDNSServers; // Valid DNSServers for this question 20115ffb0c9bSToomas Soome mDNSu16 noServerResponse; // At least one server did not respond. 20125ffb0c9bSToomas Soome mDNSu16 triedAllServersOnce; // Tried all DNS servers once 20135ffb0c9bSToomas Soome mDNSu8 unansweredQueries; // The number of unanswered queries to this server 2014*3b436d06SToomas Soome AllowExpiredState allowExpired; // Allow expired answers state (see enum AllowExpired_None, etc. above) 20155ffb0c9bSToomas Soome 20165ffb0c9bSToomas Soome ZoneData *nta; // Used for getting zone data for private or LLQ query 20175ffb0c9bSToomas Soome mDNSAddr servAddr; // Address and port learned from _dns-llq, _dns-llq-tls or _dns-query-tls SRV query 20185ffb0c9bSToomas Soome mDNSIPPort servPort; 20195ffb0c9bSToomas Soome struct tcpInfo_t *tcp; 20205ffb0c9bSToomas Soome mDNSIPPort tcpSrcPort; // Local Port TCP packet received on;need this as tcp struct is disposed 20215ffb0c9bSToomas Soome // by tcpCallback before calling into mDNSCoreReceive 20225ffb0c9bSToomas Soome mDNSu8 NoAnswer; // Set if we want to suppress answers until tunnel setup has completed 20235ffb0c9bSToomas Soome mDNSu8 Restart; // This question should be restarted soon 20245ffb0c9bSToomas Soome 20255ffb0c9bSToomas Soome // LLQ-specific fields. These fields are only meaningful when LongLived flag is set 20265ffb0c9bSToomas Soome LLQ_State state; 20275ffb0c9bSToomas Soome mDNSu32 ReqLease; // seconds (relative) 20285ffb0c9bSToomas Soome mDNSs32 expire; // ticks (absolute) 20295ffb0c9bSToomas Soome mDNSs16 ntries; // for UDP: the number of packets sent for this LLQ state 20305ffb0c9bSToomas Soome // for TCP: there is some ambiguity in the use of this variable, but in general, it is 20315ffb0c9bSToomas Soome // the number of TCP/TLS connection attempts for this LLQ state, or 20325ffb0c9bSToomas Soome // the number of packets sent for this TCP/TLS connection 2033c65ebfc7SToomas Soome 2034c65ebfc7SToomas Soome // DNS Push Notification fields. These fields are only meaningful when LongLived flag is set 2035c65ebfc7SToomas Soome DNSPush_State dnsPushState; // The state of the DNS push notification negotiation 2036c65ebfc7SToomas Soome mDNSAddr dnsPushServerAddr; // Address of the system acting as the DNS Push Server 2037c65ebfc7SToomas Soome mDNSIPPort dnsPushServerPort; // Port on which the DNS Push Server is being advertised. 2038c65ebfc7SToomas Soome 20395ffb0c9bSToomas Soome mDNSOpaque64 id; 20405ffb0c9bSToomas Soome 20415ffb0c9bSToomas Soome // DNS Proxy fields 20425ffb0c9bSToomas Soome mDNSOpaque16 responseFlags; // Temporary place holder for the error we get back from the DNS server 20435ffb0c9bSToomas Soome // till we populate in the cache 20445ffb0c9bSToomas Soome mDNSBool DisallowPID; // Is the query allowed for the "PID" that we are sending on behalf of ? 20455ffb0c9bSToomas Soome mDNSs32 ServiceID; // Service identifier to match against the DNS server 2046c65ebfc7SToomas Soome 20475ffb0c9bSToomas Soome // Client API fields: The client must set up these fields *before* calling mDNS_StartQuery() 20485ffb0c9bSToomas Soome mDNSInterfaceID InterfaceID; // Non-zero if you want to issue queries only on a single specific IP interface 20495ffb0c9bSToomas Soome mDNSu32 flags; // flags from original DNSService*() API request. 20505ffb0c9bSToomas Soome mDNSAddr Target; // Non-zero if you want to direct queries to a specific unicast target address 20515ffb0c9bSToomas Soome mDNSIPPort TargetPort; // Must be set if Target is set 20525ffb0c9bSToomas Soome mDNSOpaque16 TargetQID; // Must be set if Target is set 20535ffb0c9bSToomas Soome domainname qname; 2054*3b436d06SToomas Soome domainname firstExpiredQname; // first expired qname in request chain 20555ffb0c9bSToomas Soome mDNSu16 qtype; 20565ffb0c9bSToomas Soome mDNSu16 qclass; 20575ffb0c9bSToomas Soome mDNSBool LongLived; // Set by client for calls to mDNS_StartQuery to indicate LLQs to unicast layer. 20585ffb0c9bSToomas Soome mDNSBool ExpectUnique; // Set by client if it's expecting unique RR(s) for this question, not shared RRs 20595ffb0c9bSToomas Soome mDNSBool ForceMCast; // Set by client to force mDNS query, even for apparently uDNS names 20605ffb0c9bSToomas Soome mDNSBool ReturnIntermed; // Set by client to request callbacks for intermediate CNAME/NXDOMAIN results 20615ffb0c9bSToomas Soome mDNSBool SuppressUnusable; // Set by client to suppress unusable queries to be sent on the wire 20625ffb0c9bSToomas Soome mDNSu8 RetryWithSearchDomains; // Retry with search domains if there is no entry in the cache or AuthRecords 20635ffb0c9bSToomas Soome mDNSu8 TimeoutQuestion; // Timeout this question if there is no reply in configured time 20645ffb0c9bSToomas Soome mDNSu8 WakeOnResolve; // Send wakeup on resolve 20655ffb0c9bSToomas Soome mDNSu8 UseBackgroundTrafficClass; // Set by client to use background traffic class for request 20665ffb0c9bSToomas Soome mDNSs8 SearchListIndex; // Index into SearchList; Used by the client layer but not touched by core 20675ffb0c9bSToomas Soome mDNSs8 AppendSearchDomains; // Search domains can be appended for this query 20685ffb0c9bSToomas Soome mDNSs8 AppendLocalSearchDomains; // Search domains ending in .local can be appended for this query 20695ffb0c9bSToomas Soome mDNSu8 ValidationRequired; // Requires DNSSEC validation. 20705ffb0c9bSToomas Soome mDNSu8 ProxyQuestion; // Proxy Question 20715ffb0c9bSToomas Soome mDNSu8 ProxyDNSSECOK; // Proxy Question with EDNS0 DNSSEC OK bit set 20725ffb0c9bSToomas Soome mDNSs32 pid; // Process ID of the client that is requesting the question 20735ffb0c9bSToomas Soome mDNSu8 uuid[UUID_SIZE]; // Unique ID of the client that is requesting the question (valid only if pid is zero) 2074cda73f64SToomas Soome mDNSu32 euid; // Effective User Id of the client that is requesting the question 20755ffb0c9bSToomas Soome domainname *qnameOrig; // Copy of the original question name if it is not fully qualified 20765ffb0c9bSToomas Soome mDNSQuestionCallback *QuestionCallback; 20775ffb0c9bSToomas Soome void *QuestionContext; 2078*3b436d06SToomas Soome #if AWD_METRICS 2079cda73f64SToomas Soome uDNSMetrics metrics; // Data used for collecting unicast DNS query metrics. 2080cda73f64SToomas Soome #endif 2081c65ebfc7SToomas Soome #if USE_DNS64 2082c65ebfc7SToomas Soome DNS64 dns64; // DNS64 state for performing IPv6 address synthesis on networks with NAT64. 2083c65ebfc7SToomas Soome #endif 20845ffb0c9bSToomas Soome }; 20854b22b933Srs 2086c65ebfc7SToomas Soome typedef enum { ZoneServiceUpdate, ZoneServiceQuery, ZoneServiceLLQ, ZoneServiceDNSPush } ZoneService; 20875ffb0c9bSToomas Soome 20885ffb0c9bSToomas Soome typedef void ZoneDataCallback (mDNS *const m, mStatus err, const ZoneData *result); 20895ffb0c9bSToomas Soome 20905ffb0c9bSToomas Soome struct ZoneData_struct 20915ffb0c9bSToomas Soome { 20925ffb0c9bSToomas Soome domainname ChildName; // Name for which we're trying to find the responsible server 20935ffb0c9bSToomas Soome ZoneService ZoneService; // Which service we're seeking for this zone (update, query, or LLQ) 20945ffb0c9bSToomas Soome domainname *CurrentSOA; // Points to somewhere within ChildName 20955ffb0c9bSToomas Soome domainname ZoneName; // Discovered result: Left-hand-side of SOA record 20965ffb0c9bSToomas Soome mDNSu16 ZoneClass; // Discovered result: DNS Class from SOA record 20975ffb0c9bSToomas Soome domainname Host; // Discovered result: Target host from SRV record 20985ffb0c9bSToomas Soome mDNSIPPort Port; // Discovered result: Update port, query port, or LLQ port from SRV record 20995ffb0c9bSToomas Soome mDNSAddr Addr; // Discovered result: Address of Target host from SRV record 21005ffb0c9bSToomas Soome mDNSBool ZonePrivate; // Discovered result: Does zone require encrypted queries? 21015ffb0c9bSToomas Soome ZoneDataCallback *ZoneDataCallback; // Caller-specified function to be called upon completion 21025ffb0c9bSToomas Soome void *ZoneDataContext; 21035ffb0c9bSToomas Soome DNSQuestion question; // Storage for any active question 21045ffb0c9bSToomas Soome }; 21055ffb0c9bSToomas Soome 21065ffb0c9bSToomas Soome extern ZoneData *StartGetZoneData(mDNS *const m, const domainname *const name, const ZoneService target, ZoneDataCallback callback, void *callbackInfo); 21075ffb0c9bSToomas Soome extern void CancelGetZoneData(mDNS *const m, ZoneData *nta); 21085ffb0c9bSToomas Soome extern mDNSBool IsGetZoneDataQuestion(DNSQuestion *q); 21095ffb0c9bSToomas Soome 21105ffb0c9bSToomas Soome typedef struct DNameListElem 21115ffb0c9bSToomas Soome { 21125ffb0c9bSToomas Soome struct DNameListElem *next; 21135ffb0c9bSToomas Soome mDNSu32 uid; 21145ffb0c9bSToomas Soome domainname name; 21155ffb0c9bSToomas Soome } DNameListElem; 21165ffb0c9bSToomas Soome 21175ffb0c9bSToomas Soome #if APPLE_OSX_mDNSResponder 21185ffb0c9bSToomas Soome // Different states that we go through locating the peer 21195ffb0c9bSToomas Soome #define TC_STATE_AAAA_PEER 0x000000001 /* Peer's BTMM IPv6 address */ 21205ffb0c9bSToomas Soome #define TC_STATE_AAAA_PEER_RELAY 0x000000002 /* Peer's IPv6 Relay address */ 21215ffb0c9bSToomas Soome #define TC_STATE_SRV_PEER 0x000000003 /* Peer's SRV Record corresponding to IPv4 address */ 21225ffb0c9bSToomas Soome #define TC_STATE_ADDR_PEER 0x000000004 /* Peer's IPv4 address */ 21235ffb0c9bSToomas Soome 21245ffb0c9bSToomas Soome typedef struct ClientTunnel 21255ffb0c9bSToomas Soome { 21265ffb0c9bSToomas Soome struct ClientTunnel *next; 21275ffb0c9bSToomas Soome domainname dstname; 21285ffb0c9bSToomas Soome mDNSBool MarkedForDeletion; 21295ffb0c9bSToomas Soome mDNSv6Addr loc_inner; 21305ffb0c9bSToomas Soome mDNSv4Addr loc_outer; 21315ffb0c9bSToomas Soome mDNSv6Addr loc_outer6; 21325ffb0c9bSToomas Soome mDNSv6Addr rmt_inner; 21335ffb0c9bSToomas Soome mDNSv4Addr rmt_outer; 21345ffb0c9bSToomas Soome mDNSv6Addr rmt_outer6; 21355ffb0c9bSToomas Soome mDNSIPPort rmt_outer_port; 21365ffb0c9bSToomas Soome mDNSu16 tc_state; 21375ffb0c9bSToomas Soome DNSQuestion q; 21385ffb0c9bSToomas Soome } ClientTunnel; 21395ffb0c9bSToomas Soome #endif 21404b22b933Srs 21414b22b933Srs // *************************************************************************** 21424b22b933Srs #if 0 21435ffb0c9bSToomas Soome #pragma mark - 21445ffb0c9bSToomas Soome #pragma mark - NetworkInterfaceInfo_struct 21454b22b933Srs #endif 21464b22b933Srs 21475ffb0c9bSToomas Soome typedef struct NetworkInterfaceInfo_struct NetworkInterfaceInfo; 21484b22b933Srs 21495ffb0c9bSToomas Soome // A NetworkInterfaceInfo_struct serves two purposes: 21505ffb0c9bSToomas Soome // 1. It holds the address, PTR and HINFO records to advertise a given IP address on a given physical interface 21515ffb0c9bSToomas Soome // 2. It tells mDNSCore which physical interfaces are available; each physical interface has its own unique InterfaceID. 21525ffb0c9bSToomas Soome // Since there may be multiple IP addresses on a single physical interface, 21535ffb0c9bSToomas Soome // there may be multiple NetworkInterfaceInfo_structs with the same InterfaceID. 21545ffb0c9bSToomas Soome // In this case, to avoid sending the same packet n times, when there's more than one 21555ffb0c9bSToomas Soome // struct with the same InterfaceID, mDNSCore picks one member of the set to be the 21565ffb0c9bSToomas Soome // active representative of the set; all others have the 'InterfaceActive' flag unset. 21574b22b933Srs 21585ffb0c9bSToomas Soome struct NetworkInterfaceInfo_struct 21595ffb0c9bSToomas Soome { 21605ffb0c9bSToomas Soome // Internal state fields. These are used internally by mDNSCore; the client layer needn't be concerned with them. 21615ffb0c9bSToomas Soome NetworkInterfaceInfo *next; 21625ffb0c9bSToomas Soome 21635ffb0c9bSToomas Soome mDNSu8 InterfaceActive; // Set if interface is sending & receiving packets (see comment above) 21645ffb0c9bSToomas Soome mDNSu8 IPv4Available; // If InterfaceActive, set if v4 available on this InterfaceID 21655ffb0c9bSToomas Soome mDNSu8 IPv6Available; // If InterfaceActive, set if v6 available on this InterfaceID 21665ffb0c9bSToomas Soome 21675ffb0c9bSToomas Soome DNSQuestion NetWakeBrowse; 21685ffb0c9bSToomas Soome DNSQuestion NetWakeResolve[3]; // For fault-tolerance, we try up to three Sleep Proxies 21695ffb0c9bSToomas Soome mDNSAddr SPSAddr[3]; 21705ffb0c9bSToomas Soome mDNSIPPort SPSPort[3]; 21715ffb0c9bSToomas Soome mDNSs32 NextSPSAttempt; // -1 if we're not currently attempting to register with any Sleep Proxy 21725ffb0c9bSToomas Soome mDNSs32 NextSPSAttemptTime; 21735ffb0c9bSToomas Soome 21745ffb0c9bSToomas Soome // Standard AuthRecords that every Responder host should have (one per active IP address) 21755ffb0c9bSToomas Soome AuthRecord RR_A; // 'A' or 'AAAA' (address) record for our ".local" name 21765ffb0c9bSToomas Soome AuthRecord RR_PTR; // PTR (reverse lookup) record 21775ffb0c9bSToomas Soome AuthRecord RR_HINFO; 21785ffb0c9bSToomas Soome 21795ffb0c9bSToomas Soome // Client API fields: The client must set up these fields *before* calling mDNS_RegisterInterface() 21805ffb0c9bSToomas Soome mDNSInterfaceID InterfaceID; // Identifies physical interface; MUST NOT be 0, -1, or -2 21815ffb0c9bSToomas Soome mDNSAddr ip; // The IPv4 or IPv6 address to advertise 21825ffb0c9bSToomas Soome mDNSAddr mask; 21835ffb0c9bSToomas Soome mDNSEthAddr MAC; 21845ffb0c9bSToomas Soome char ifname[64]; // Windows uses a GUID string for the interface name, which doesn't fit in 16 bytes 21855ffb0c9bSToomas Soome mDNSu8 Advertise; // False if you are only searching on this interface 21865ffb0c9bSToomas Soome mDNSu8 McastTxRx; // Send/Receive multicast on this { InterfaceID, address family } ? 21875ffb0c9bSToomas Soome mDNSu8 NetWake; // Set if Wake-On-Magic-Packet is enabled on this interface 21885ffb0c9bSToomas Soome mDNSu8 Loopback; // Set if this is the loopback interface 21895ffb0c9bSToomas Soome mDNSu8 IgnoreIPv4LL; // Set if IPv4 Link-Local addresses have to be ignored. 21905ffb0c9bSToomas Soome mDNSu8 SendGoodbyes; // Send goodbyes on this interface while sleeping 21915ffb0c9bSToomas Soome mDNSBool DirectLink; // a direct link, indicating we can skip the probe for 21925ffb0c9bSToomas Soome // address records 2193cda73f64SToomas Soome mDNSBool SupportsUnicastMDNSResponse; // Indicates that the interface supports unicast responses 2194*3b436d06SToomas Soome // to Bonjour queries. Generally true for an interface. 21955ffb0c9bSToomas Soome }; 21965ffb0c9bSToomas Soome 21975ffb0c9bSToomas Soome #define SLE_DELETE 0x00000001 21985ffb0c9bSToomas Soome #define SLE_WAB_BROWSE_QUERY_STARTED 0x00000002 21995ffb0c9bSToomas Soome #define SLE_WAB_LBROWSE_QUERY_STARTED 0x00000004 22005ffb0c9bSToomas Soome #define SLE_WAB_REG_QUERY_STARTED 0x00000008 22015ffb0c9bSToomas Soome 22025ffb0c9bSToomas Soome typedef struct SearchListElem 22035ffb0c9bSToomas Soome { 22045ffb0c9bSToomas Soome struct SearchListElem *next; 22055ffb0c9bSToomas Soome domainname domain; 22065ffb0c9bSToomas Soome int flag; 22075ffb0c9bSToomas Soome mDNSInterfaceID InterfaceID; 22085ffb0c9bSToomas Soome DNSQuestion BrowseQ; 22095ffb0c9bSToomas Soome DNSQuestion DefBrowseQ; 22105ffb0c9bSToomas Soome DNSQuestion AutomaticBrowseQ; 22115ffb0c9bSToomas Soome DNSQuestion RegisterQ; 22125ffb0c9bSToomas Soome DNSQuestion DefRegisterQ; 22135ffb0c9bSToomas Soome int numCfAnswers; 22145ffb0c9bSToomas Soome ARListElem *AuthRecs; 22155ffb0c9bSToomas Soome } SearchListElem; 22165ffb0c9bSToomas Soome 22175ffb0c9bSToomas Soome // For domain enumeration and automatic browsing 22185ffb0c9bSToomas Soome // This is the user's DNS search list. 22195ffb0c9bSToomas Soome // In each of these domains we search for our special pointer records (lb._dns-sd._udp.<domain>, etc.) 22205ffb0c9bSToomas Soome // to discover recommended domains for domain enumeration (browse, default browse, registration, 22215ffb0c9bSToomas Soome // default registration) and possibly one or more recommended automatic browsing domains. 22225ffb0c9bSToomas Soome extern SearchListElem *SearchList; // This really ought to be part of mDNS_struct -- SC 22234b22b933Srs 22244b22b933Srs // *************************************************************************** 22254b22b933Srs #if 0 22265ffb0c9bSToomas Soome #pragma mark - 22274b22b933Srs #pragma mark - Main mDNS object, used to hold all the mDNS state 22284b22b933Srs #endif 22294b22b933Srs 22305ffb0c9bSToomas Soome typedef void mDNSCallback (mDNS *const m, mStatus result); 22314b22b933Srs 22325ffb0c9bSToomas Soome #ifndef CACHE_HASH_SLOTS 22334b22b933Srs #define CACHE_HASH_SLOTS 499 22345ffb0c9bSToomas Soome #endif 22354b22b933Srs 22364b22b933Srs enum 22375ffb0c9bSToomas Soome { 22385ffb0c9bSToomas Soome SleepState_Awake = 0, 22395ffb0c9bSToomas Soome SleepState_Transferring = 1, 22405ffb0c9bSToomas Soome SleepState_Sleeping = 2 22415ffb0c9bSToomas Soome }; 22425ffb0c9bSToomas Soome 22435ffb0c9bSToomas Soome typedef enum 22445ffb0c9bSToomas Soome { 22455ffb0c9bSToomas Soome kStatsActionIncrement, 22465ffb0c9bSToomas Soome kStatsActionDecrement, 22475ffb0c9bSToomas Soome kStatsActionClear, 22485ffb0c9bSToomas Soome kStatsActionSet 22495ffb0c9bSToomas Soome } DNSSECStatsAction; 22505ffb0c9bSToomas Soome 22515ffb0c9bSToomas Soome typedef enum 22525ffb0c9bSToomas Soome { 22535ffb0c9bSToomas Soome kStatsTypeMemoryUsage, 22545ffb0c9bSToomas Soome kStatsTypeLatency, 22555ffb0c9bSToomas Soome kStatsTypeExtraPackets, 22565ffb0c9bSToomas Soome kStatsTypeStatus, 22575ffb0c9bSToomas Soome kStatsTypeProbe, 22585ffb0c9bSToomas Soome kStatsTypeMsgSize 22595ffb0c9bSToomas Soome } DNSSECStatsType; 22605ffb0c9bSToomas Soome 22615ffb0c9bSToomas Soome typedef struct 22625ffb0c9bSToomas Soome { 22635ffb0c9bSToomas Soome mDNSu32 TotalMemUsed; 22645ffb0c9bSToomas Soome mDNSu32 Latency0; // 0 to 4 ms 22655ffb0c9bSToomas Soome mDNSu32 Latency5; // 5 to 9 ms 22665ffb0c9bSToomas Soome mDNSu32 Latency10; // 10 to 19 ms 22675ffb0c9bSToomas Soome mDNSu32 Latency20; // 20 to 49 ms 22685ffb0c9bSToomas Soome mDNSu32 Latency50; // 50 to 99 ms 22695ffb0c9bSToomas Soome mDNSu32 Latency100; // >= 100 ms 22705ffb0c9bSToomas Soome mDNSu32 ExtraPackets0; // 0 to 2 packets 22715ffb0c9bSToomas Soome mDNSu32 ExtraPackets3; // 3 to 6 packets 22725ffb0c9bSToomas Soome mDNSu32 ExtraPackets7; // 7 to 9 packets 22735ffb0c9bSToomas Soome mDNSu32 ExtraPackets10; // >= 10 packets 22745ffb0c9bSToomas Soome mDNSu32 SecureStatus; 22755ffb0c9bSToomas Soome mDNSu32 InsecureStatus; 22765ffb0c9bSToomas Soome mDNSu32 IndeterminateStatus; 22775ffb0c9bSToomas Soome mDNSu32 BogusStatus; 22785ffb0c9bSToomas Soome mDNSu32 NoResponseStatus; 22795ffb0c9bSToomas Soome mDNSu32 NumProbesSent; // Number of probes sent 22805ffb0c9bSToomas Soome mDNSu32 MsgSize0; // DNSSEC message size <= 1024 22815ffb0c9bSToomas Soome mDNSu32 MsgSize1; // DNSSEC message size <= 2048 22825ffb0c9bSToomas Soome mDNSu32 MsgSize2; // DNSSEC message size > 2048 22835ffb0c9bSToomas Soome } DNSSECStatistics; 22844b22b933Srs 22854b22b933Srs typedef struct 22865ffb0c9bSToomas Soome { 22875ffb0c9bSToomas Soome mDNSu32 NameConflicts; // Normal Name conflicts 22885ffb0c9bSToomas Soome mDNSu32 KnownUniqueNameConflicts; // Name Conflicts for KnownUnique Records 22895ffb0c9bSToomas Soome mDNSu32 DupQuerySuppressions; // Duplicate query suppressions 22905ffb0c9bSToomas Soome mDNSu32 KnownAnswerSuppressions; // Known Answer suppressions 22915ffb0c9bSToomas Soome mDNSu32 KnownAnswerMultiplePkts; // Known Answer in queries spannign multiple packets 22925ffb0c9bSToomas Soome mDNSu32 PoofCacheDeletions; // Number of times the cache was deleted due to POOF 22935ffb0c9bSToomas Soome mDNSu32 UnicastBitInQueries; // Queries with QU bit set 22945ffb0c9bSToomas Soome mDNSu32 NormalQueries; // Queries with QU bit not set 22955ffb0c9bSToomas Soome mDNSu32 MatchingAnswersForQueries; // Queries for which we had a response 22965ffb0c9bSToomas Soome mDNSu32 UnicastResponses; // Unicast responses to queries 22975ffb0c9bSToomas Soome mDNSu32 MulticastResponses; // Multicast responses to queries 22985ffb0c9bSToomas Soome mDNSu32 UnicastDemotedToMulticast; // Number of times unicast demoted to multicast 22995ffb0c9bSToomas Soome mDNSu32 Sleeps; // Total sleeps 23005ffb0c9bSToomas Soome mDNSu32 Wakes; // Total wakes 23015ffb0c9bSToomas Soome mDNSu32 InterfaceUp; // Total Interface UP events 23025ffb0c9bSToomas Soome mDNSu32 InterfaceUpFlap; // Total Interface UP events with flaps 23035ffb0c9bSToomas Soome mDNSu32 InterfaceDown; // Total Interface Down events 23045ffb0c9bSToomas Soome mDNSu32 InterfaceDownFlap; // Total Interface Down events with flaps 23055ffb0c9bSToomas Soome mDNSu32 CacheRefreshQueries; // Number of queries that we sent for refreshing cache 23065ffb0c9bSToomas Soome mDNSu32 CacheRefreshed; // Number of times the cache was refreshed due to a response 23075ffb0c9bSToomas Soome mDNSu32 WakeOnResolves; // Number of times we did a wake on resolve 23085ffb0c9bSToomas Soome } mDNSStatistics; 2309cda73f64SToomas Soome 23105ffb0c9bSToomas Soome extern void LogMDNSStatistics(mDNS *const m); 23114b22b933Srs 2312c65ebfc7SToomas Soome typedef struct mDNS_DNSPushNotificationServer DNSPushNotificationServer; 2313c65ebfc7SToomas Soome typedef struct mDNS_DNSPushNotificationZone DNSPushNotificationZone; 2314c65ebfc7SToomas Soome 2315c65ebfc7SToomas Soome struct mDNS_DNSPushNotificationServer 2316c65ebfc7SToomas Soome { 2317c65ebfc7SToomas Soome mDNSAddr serverAddr; // Server Address 2318c65ebfc7SToomas Soome tcpInfo_t *connection; // TCP Connection pointer 2319c65ebfc7SToomas Soome mDNSu32 numberOfQuestions; // Number of questions for this server 2320c65ebfc7SToomas Soome DNSPushNotificationServer *next; 2321c65ebfc7SToomas Soome } ; 2322c65ebfc7SToomas Soome 2323c65ebfc7SToomas Soome struct mDNS_DNSPushNotificationZone 2324c65ebfc7SToomas Soome { 2325c65ebfc7SToomas Soome domainname zoneName; 2326c65ebfc7SToomas Soome DNSPushNotificationServer *servers; // DNS Push Notification Servers for this zone 2327c65ebfc7SToomas Soome mDNSu32 numberOfQuestions; // Number of questions for this zone 2328c65ebfc7SToomas Soome DNSPushNotificationZone *next; 2329c65ebfc7SToomas Soome } ; 2330c65ebfc7SToomas Soome 2331c65ebfc7SToomas Soome 2332c65ebfc7SToomas Soome // Time constant (~= 260 hours ~= 10 days and 21 hours) used to set 2333c65ebfc7SToomas Soome // various time values to a point well into the future. 2334c65ebfc7SToomas Soome #define FutureTime 0x38000000 2335c65ebfc7SToomas Soome 23364b22b933Srs struct mDNS_struct 23375ffb0c9bSToomas Soome { 23385ffb0c9bSToomas Soome // Internal state fields. These hold the main internal state of mDNSCore; 23395ffb0c9bSToomas Soome // the client layer needn't be concerned with them. 23405ffb0c9bSToomas Soome // No fields need to be set up by the client prior to calling mDNS_Init(); 23415ffb0c9bSToomas Soome // all required data is passed as parameters to that function. 23425ffb0c9bSToomas Soome 23435ffb0c9bSToomas Soome mDNS_PlatformSupport *p; // Pointer to platform-specific data of indeterminite size 2344cda73f64SToomas Soome mDNSs32 NetworkChanged; 23455ffb0c9bSToomas Soome mDNSBool CanReceiveUnicastOn5353; 23465ffb0c9bSToomas Soome mDNSBool AdvertiseLocalAddresses; 23475ffb0c9bSToomas Soome mDNSBool DivertMulticastAdvertisements; // from interfaces that do not advertise local addresses to local-only 23485ffb0c9bSToomas Soome mStatus mDNSPlatformStatus; 23495ffb0c9bSToomas Soome mDNSIPPort UnicastPort4; 23505ffb0c9bSToomas Soome mDNSIPPort UnicastPort6; 23515ffb0c9bSToomas Soome mDNSEthAddr PrimaryMAC; // Used as unique host ID 23525ffb0c9bSToomas Soome mDNSCallback *MainCallback; 23535ffb0c9bSToomas Soome void *MainContext; 23545ffb0c9bSToomas Soome 23555ffb0c9bSToomas Soome // For debugging: To catch and report locking failures 23565ffb0c9bSToomas Soome mDNSu32 mDNS_busy; // Incremented between mDNS_Lock/mDNS_Unlock section 23575ffb0c9bSToomas Soome mDNSu32 mDNS_reentrancy; // Incremented when calling a client callback 23585ffb0c9bSToomas Soome mDNSu8 lock_rrcache; // For debugging: Set at times when these lists may not be modified 23595ffb0c9bSToomas Soome mDNSu8 lock_Questions; 23605ffb0c9bSToomas Soome mDNSu8 lock_Records; 23615ffb0c9bSToomas Soome #ifndef MaxMsg 23625ffb0c9bSToomas Soome #define MaxMsg 512 23635ffb0c9bSToomas Soome #endif 23645ffb0c9bSToomas Soome char MsgBuffer[MaxMsg]; // Temp storage used while building error log messages 23655ffb0c9bSToomas Soome 23665ffb0c9bSToomas Soome // Task Scheduling variables 23675ffb0c9bSToomas Soome mDNSs32 timenow_adjust; // Correction applied if we ever discover time went backwards 23685ffb0c9bSToomas Soome mDNSs32 timenow; // The time that this particular activation of the mDNS code started 23695ffb0c9bSToomas Soome mDNSs32 timenow_last; // The time the last time we ran 23705ffb0c9bSToomas Soome mDNSs32 NextScheduledEvent; // Derived from values below 23715ffb0c9bSToomas Soome mDNSs32 ShutdownTime; // Set when we're shutting down; allows us to skip some unnecessary steps 23725ffb0c9bSToomas Soome mDNSs32 SuppressSending; // Don't send local-link mDNS packets during this time 23735ffb0c9bSToomas Soome mDNSs32 NextCacheCheck; // Next time to refresh cache record before it expires 23745ffb0c9bSToomas Soome mDNSs32 NextScheduledQuery; // Next time to send query in its exponential backoff sequence 23755ffb0c9bSToomas Soome mDNSs32 NextScheduledProbe; // Next time to probe for new authoritative record 23765ffb0c9bSToomas Soome mDNSs32 NextScheduledResponse; // Next time to send authoritative record(s) in responses 23775ffb0c9bSToomas Soome mDNSs32 NextScheduledNATOp; // Next time to send NAT-traversal packets 23785ffb0c9bSToomas Soome mDNSs32 NextScheduledSPS; // Next time to purge expiring Sleep Proxy records 23795ffb0c9bSToomas Soome mDNSs32 NextScheduledKA; // Next time to send Keepalive packets (SPS) 2380c65ebfc7SToomas Soome #if BONJOUR_ON_DEMAND 2381c65ebfc7SToomas Soome mDNSs32 NextBonjourDisableTime; // Next time to leave multicast group if Bonjour on Demand is enabled 2382c65ebfc7SToomas Soome mDNSu8 BonjourEnabled; // Non zero if Bonjour is currently enabled by the Bonjour on Demand logic 2383c65ebfc7SToomas Soome #endif // BONJOUR_ON_DEMAND 2384c65ebfc7SToomas Soome mDNSs32 DelayConflictProcessing; // To prevent spurious confilcts due to stale packets on the wire/air. 23855ffb0c9bSToomas Soome mDNSs32 RandomQueryDelay; // For de-synchronization of query packets on the wire 23865ffb0c9bSToomas Soome mDNSu32 RandomReconfirmDelay; // For de-synchronization of reconfirmation queries on the wire 23875ffb0c9bSToomas Soome mDNSs32 PktNum; // Unique sequence number assigned to each received packet 23885ffb0c9bSToomas Soome mDNSs32 MPktNum; // Unique sequence number assigned to each received Multicast packet 23895ffb0c9bSToomas Soome mDNSu8 LocalRemoveEvents; // Set if we may need to deliver remove events for local-only questions and/or local-only records 23905ffb0c9bSToomas Soome mDNSu8 SleepState; // Set if we're sleeping 23915ffb0c9bSToomas Soome mDNSu8 SleepSeqNum; // "Epoch number" of our current period of wakefulness 23925ffb0c9bSToomas Soome mDNSu8 SystemWakeOnLANEnabled; // Set if we want to register with a Sleep Proxy before going to sleep 23935ffb0c9bSToomas Soome mDNSu8 SentSleepProxyRegistration; // Set if we registered (or tried to register) with a Sleep Proxy 23945ffb0c9bSToomas Soome mDNSu8 SystemSleepOnlyIfWakeOnLAN; // Set if we may only sleep if we managed to register with a Sleep Proxy 23955ffb0c9bSToomas Soome mDNSs32 AnnounceOwner; // After waking from sleep, include OWNER option in packets until this time 23965ffb0c9bSToomas Soome mDNSs32 DelaySleep; // To inhibit re-sleeping too quickly right after wake 23975ffb0c9bSToomas Soome mDNSs32 SleepLimit; // Time window to allow deregistrations, etc., 23985ffb0c9bSToomas Soome // during which underying platform layer should inhibit system sleep 23995ffb0c9bSToomas Soome mDNSs32 TimeSlept; // Time we went to sleep. 24005ffb0c9bSToomas Soome 24015ffb0c9bSToomas Soome mDNSs32 UnicastPacketsSent; // Number of unicast packets sent. 24025ffb0c9bSToomas Soome mDNSs32 MulticastPacketsSent; // Number of multicast packets sent. 24035ffb0c9bSToomas Soome mDNSs32 RemoteSubnet; // Multicast packets received from outside our subnet. 24045ffb0c9bSToomas Soome 24055ffb0c9bSToomas Soome mDNSs32 NextScheduledSPRetry; // Time next sleep proxy registration action is required. 24065ffb0c9bSToomas Soome // Only valid if SleepLimit is nonzero and DelaySleep is zero. 24075ffb0c9bSToomas Soome 24085ffb0c9bSToomas Soome mDNSs32 NextScheduledStopTime; // Next time to stop a question 24095ffb0c9bSToomas Soome 2410c65ebfc7SToomas Soome mDNSs32 NextBLEServiceTime; // Next time to call the BLE discovery management layer. Non zero when active. 24115ffb0c9bSToomas Soome 24125ffb0c9bSToomas Soome // These fields only required for mDNS Searcher... 24135ffb0c9bSToomas Soome DNSQuestion *Questions; // List of all registered questions, active and inactive 24145ffb0c9bSToomas Soome DNSQuestion *NewQuestions; // Fresh questions not yet answered from cache 24155ffb0c9bSToomas Soome DNSQuestion *CurrentQuestion; // Next question about to be examined in AnswerLocalQuestions() 24165ffb0c9bSToomas Soome DNSQuestion *LocalOnlyQuestions; // Questions with InterfaceID set to mDNSInterface_LocalOnly or mDNSInterface_P2P 24175ffb0c9bSToomas Soome DNSQuestion *NewLocalOnlyQuestions; // Fresh local-only or P2P questions not yet answered 24185ffb0c9bSToomas Soome DNSQuestion *RestartQuestion; // Questions that are being restarted (stop followed by start) 24195ffb0c9bSToomas Soome DNSQuestion *ValidationQuestion; // Questions that are being validated (dnssec) 24205ffb0c9bSToomas Soome mDNSu32 rrcache_size; // Total number of available cache entries 24215ffb0c9bSToomas Soome mDNSu32 rrcache_totalused; // Number of cache entries currently occupied 24225ffb0c9bSToomas Soome mDNSu32 rrcache_totalused_unicast; // Number of cache entries currently occupied by unicast 24235ffb0c9bSToomas Soome mDNSu32 rrcache_active; // Number of cache entries currently occupied by records that answer active questions 24245ffb0c9bSToomas Soome mDNSu32 rrcache_report; 24255ffb0c9bSToomas Soome CacheEntity *rrcache_free; 24265ffb0c9bSToomas Soome CacheGroup *rrcache_hash[CACHE_HASH_SLOTS]; 24275ffb0c9bSToomas Soome mDNSs32 rrcache_nextcheck[CACHE_HASH_SLOTS]; 24285ffb0c9bSToomas Soome 24295ffb0c9bSToomas Soome AuthHash rrauth; 24305ffb0c9bSToomas Soome 24315ffb0c9bSToomas Soome // Fields below only required for mDNS Responder... 24325ffb0c9bSToomas Soome domainlabel nicelabel; // Rich text label encoded using canonically precomposed UTF-8 24335ffb0c9bSToomas Soome domainlabel hostlabel; // Conforms to RFC 1034 "letter-digit-hyphen" ARPANET host name rules 24345ffb0c9bSToomas Soome domainname MulticastHostname; // Fully Qualified "dot-local" Host Name, e.g. "Foo.local." 24355ffb0c9bSToomas Soome UTF8str255 HIHardware; 24365ffb0c9bSToomas Soome UTF8str255 HISoftware; 24375ffb0c9bSToomas Soome AuthRecord DeviceInfo; 24385ffb0c9bSToomas Soome AuthRecord *ResourceRecords; 24395ffb0c9bSToomas Soome AuthRecord *DuplicateRecords; // Records currently 'on hold' because they are duplicates of existing records 24405ffb0c9bSToomas Soome AuthRecord *NewLocalRecords; // Fresh AuthRecords (public) not yet delivered to our local-only questions 24415ffb0c9bSToomas Soome AuthRecord *CurrentRecord; // Next AuthRecord about to be examined 24425ffb0c9bSToomas Soome mDNSBool NewLocalOnlyRecords; // Fresh AuthRecords (local only) not yet delivered to our local questions 24435ffb0c9bSToomas Soome NetworkInterfaceInfo *HostInterfaces; 24445ffb0c9bSToomas Soome mDNSs32 ProbeFailTime; 24455ffb0c9bSToomas Soome mDNSu32 NumFailedProbes; 24465ffb0c9bSToomas Soome mDNSs32 SuppressProbes; 2447c65ebfc7SToomas Soome Platform_t mDNS_plat; // Why is this here in the “only required for mDNS Responder” section? -- SC 24485ffb0c9bSToomas Soome 24495ffb0c9bSToomas Soome // Unicast-specific data 24505ffb0c9bSToomas Soome mDNSs32 NextuDNSEvent; // uDNS next event 24515ffb0c9bSToomas Soome mDNSs32 NextSRVUpdate; // Time to perform delayed update 24525ffb0c9bSToomas Soome 24535ffb0c9bSToomas Soome DNSServer *DNSServers; // list of DNS servers 24545ffb0c9bSToomas Soome McastResolver *McastResolvers; // list of Mcast Resolvers 24555ffb0c9bSToomas Soome 24565ffb0c9bSToomas Soome mDNSAddr Router; 24575ffb0c9bSToomas Soome mDNSAddr AdvertisedV4; // IPv4 address pointed to by hostname 24585ffb0c9bSToomas Soome mDNSAddr AdvertisedV6; // IPv6 address pointed to by hostname 24595ffb0c9bSToomas Soome 24605ffb0c9bSToomas Soome DomainAuthInfo *AuthInfoList; // list of domains requiring authentication for updates 24615ffb0c9bSToomas Soome 24625ffb0c9bSToomas Soome DNSQuestion ReverseMap; // Reverse-map query to find static hostname for service target 24635ffb0c9bSToomas Soome DNSQuestion AutomaticBrowseDomainQ; 24645ffb0c9bSToomas Soome domainname StaticHostname; // Current answer to reverse-map query 24655ffb0c9bSToomas Soome domainname FQDN; 24665ffb0c9bSToomas Soome HostnameInfo *Hostnames; // List of registered hostnames + hostname metadata 24675ffb0c9bSToomas Soome NATTraversalInfo AutoTunnelNAT; // Shared between all AutoTunnel DomainAuthInfo structs 24685ffb0c9bSToomas Soome mDNSv6Addr AutoTunnelRelayAddr; 24695ffb0c9bSToomas Soome 24705ffb0c9bSToomas Soome mDNSu32 WABBrowseQueriesCount; // Number of WAB Browse domain enumeration queries (b, db) callers 24715ffb0c9bSToomas Soome mDNSu32 WABLBrowseQueriesCount; // Number of legacy WAB Browse domain enumeration queries (lb) callers 24725ffb0c9bSToomas Soome mDNSu32 WABRegQueriesCount; // Number of WAB Registration domain enumeration queries (r, dr) callers 24735ffb0c9bSToomas Soome mDNSu8 SearchDomainsHash[MD5_LEN]; 24745ffb0c9bSToomas Soome 24755ffb0c9bSToomas Soome // NAT-Traversal fields 24765ffb0c9bSToomas Soome NATTraversalInfo LLQNAT; // Single shared NAT Traversal to receive inbound LLQ notifications 24775ffb0c9bSToomas Soome NATTraversalInfo *NATTraversals; 24785ffb0c9bSToomas Soome NATTraversalInfo *CurrentNATTraversal; 24795ffb0c9bSToomas Soome mDNSs32 retryIntervalGetAddr; // delta between time sent and retry for NAT-PMP & UPnP/IGD external address request 24805ffb0c9bSToomas Soome mDNSs32 retryGetAddr; // absolute time when we retry for NAT-PMP & UPnP/IGD external address request 24815ffb0c9bSToomas Soome mDNSv4Addr ExtAddress; // the external address discovered via NAT-PMP or UPnP/IGD 24825ffb0c9bSToomas Soome mDNSu32 PCPNonce[3]; // the nonce if using PCP 24835ffb0c9bSToomas Soome 24845ffb0c9bSToomas Soome UDPSocket *NATMcastRecvskt; // For receiving PCP & NAT-PMP announcement multicasts from router on port 5350 24855ffb0c9bSToomas Soome mDNSu32 LastNATupseconds; // NAT engine uptime in seconds, from most recent NAT packet 24865ffb0c9bSToomas Soome mDNSs32 LastNATReplyLocalTime; // Local time in ticks when most recent NAT packet was received 24875ffb0c9bSToomas Soome mDNSu16 LastNATMapResultCode; // Most recent error code for mappings 24885ffb0c9bSToomas Soome 24895ffb0c9bSToomas Soome tcpLNTInfo tcpAddrInfo; // legacy NAT traversal TCP connection info for external address 24905ffb0c9bSToomas Soome tcpLNTInfo tcpDeviceInfo; // legacy NAT traversal TCP connection info for device info 24915ffb0c9bSToomas Soome tcpLNTInfo *tcpInfoUnmapList; // list of pending unmap requests 24925ffb0c9bSToomas Soome mDNSInterfaceID UPnPInterfaceID; 24935ffb0c9bSToomas Soome UDPSocket *SSDPSocket; // For SSDP request/response 24945ffb0c9bSToomas Soome mDNSBool SSDPWANPPPConnection; // whether we should send the SSDP query for WANIPConnection or WANPPPConnection 24955ffb0c9bSToomas Soome mDNSIPPort UPnPRouterPort; // port we send discovery messages to 24965ffb0c9bSToomas Soome mDNSIPPort UPnPSOAPPort; // port we send SOAP messages to 2497c65ebfc7SToomas Soome char *UPnPRouterURL; // router's URL string 24985ffb0c9bSToomas Soome mDNSBool UPnPWANPPPConnection; // whether we're using WANIPConnection or WANPPPConnection 2499c65ebfc7SToomas Soome char *UPnPSOAPURL; // router's SOAP control URL string 2500c65ebfc7SToomas Soome char *UPnPRouterAddressString; // holds both the router's address and port 2501c65ebfc7SToomas Soome char *UPnPSOAPAddressString; // holds both address and port for SOAP messages 2502c65ebfc7SToomas Soome 2503c65ebfc7SToomas Soome // DNS Push Notification fields 2504c65ebfc7SToomas Soome DNSPushNotificationServer *DNSPushServers; // DNS Push Notification Servers 2505c65ebfc7SToomas Soome DNSPushNotificationZone *DNSPushZones; 25065ffb0c9bSToomas Soome 25075ffb0c9bSToomas Soome // Sleep Proxy client fields 25085ffb0c9bSToomas Soome AuthRecord *SPSRRSet; // To help the client keep track of the records registered with the sleep proxy 25095ffb0c9bSToomas Soome 25105ffb0c9bSToomas Soome // Sleep Proxy Server fields 25115ffb0c9bSToomas Soome mDNSu8 SPSType; // 0 = off, 10-99 encodes desirability metric 25125ffb0c9bSToomas Soome mDNSu8 SPSPortability; // 10-99 25135ffb0c9bSToomas Soome mDNSu8 SPSMarginalPower; // 10-99 25145ffb0c9bSToomas Soome mDNSu8 SPSTotalPower; // 10-99 25155ffb0c9bSToomas Soome mDNSu8 SPSFeatureFlags; // Features supported. Currently 1 = TCP KeepAlive supported. 25165ffb0c9bSToomas Soome mDNSu8 SPSState; // 0 = off, 1 = running, 2 = shutting down, 3 = suspended during sleep 25175ffb0c9bSToomas Soome mDNSInterfaceID SPSProxyListChanged; 25185ffb0c9bSToomas Soome UDPSocket *SPSSocket; 25195ffb0c9bSToomas Soome #ifndef SPC_DISABLED 25205ffb0c9bSToomas Soome ServiceRecordSet SPSRecords; 25215ffb0c9bSToomas Soome #endif 25225ffb0c9bSToomas Soome mDNSQuestionCallback *SPSBrowseCallback; // So the platform layer can do something useful with SPS browse results 25235ffb0c9bSToomas Soome int ProxyRecords; // Total number of records we're holding as proxy 25245ffb0c9bSToomas Soome #define MAX_PROXY_RECORDS 10000 /* DOS protection: 400 machines at 25 records each */ 25255ffb0c9bSToomas Soome 25265ffb0c9bSToomas Soome #if APPLE_OSX_mDNSResponder 25275ffb0c9bSToomas Soome ClientTunnel *TunnelClients; 25285ffb0c9bSToomas Soome void *WCF; 25295ffb0c9bSToomas Soome #endif 25305ffb0c9bSToomas Soome // DNS Proxy fields 25315ffb0c9bSToomas Soome mDNSu32 dp_ipintf[MaxIp]; // input interface index list from the DNS Proxy Client 25325ffb0c9bSToomas Soome mDNSu32 dp_opintf; // output interface index from the DNS Proxy Client 25335ffb0c9bSToomas Soome 25345ffb0c9bSToomas Soome TrustAnchor *TrustAnchors; 25355ffb0c9bSToomas Soome int notifyToken; 2536cda73f64SToomas Soome 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 25375ffb0c9bSToomas Soome mDNSu32 AutoTargetServices; // # of services that have AutoTarget set 2538c65ebfc7SToomas Soome 2539c65ebfc7SToomas Soome #if BONJOUR_ON_DEMAND 2540c65ebfc7SToomas Soome // Counters used in Bonjour on Demand logic. 2541c65ebfc7SToomas Soome 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.) 2542c65ebfc7SToomas Soome mDNSu32 NumAllInterfaceQuestions; // Right now we count *all* multicast questions here. Later we may want to change to count interface-specific questions separately. 2543c65ebfc7SToomas Soome #endif // BONJOUR_ON_DEMAND 2544c65ebfc7SToomas Soome 25455ffb0c9bSToomas Soome DNSSECStatistics DNSSECStats; 25465ffb0c9bSToomas Soome mDNSStatistics mDNSStats; 25475ffb0c9bSToomas Soome 25485ffb0c9bSToomas Soome // Fixed storage, to avoid creating large objects on the stack 25495ffb0c9bSToomas Soome // The imsg is declared as a union with a pointer type to enforce CPU-appropriate alignment 25505ffb0c9bSToomas Soome union { DNSMessage m; void *p; } imsg; // Incoming message received from wire 25515ffb0c9bSToomas Soome DNSMessage omsg; // Outgoing message we're building 25525ffb0c9bSToomas Soome LargeCacheRecord rec; // Resource Record extracted from received message 25535ffb0c9bSToomas Soome }; 25545ffb0c9bSToomas Soome 25555ffb0c9bSToomas Soome #define FORALL_CACHERECORDS(SLOT,CG,CR) \ 2556cda73f64SToomas Soome for ((SLOT) = 0; (SLOT) < CACHE_HASH_SLOTS; (SLOT)++) \ 2557cda73f64SToomas Soome for ((CG)=m->rrcache_hash[(SLOT)]; (CG); (CG)=(CG)->next) \ 25585ffb0c9bSToomas Soome for ((CR) = (CG)->members; (CR); (CR)=(CR)->next) 25594b22b933Srs 25604b22b933Srs // *************************************************************************** 25614b22b933Srs #if 0 25625ffb0c9bSToomas Soome #pragma mark - 25634b22b933Srs #pragma mark - Useful Static Constants 25644b22b933Srs #endif 25654b22b933Srs 25665ffb0c9bSToomas Soome extern const mDNSInterfaceID mDNSInterface_Any; // Zero 25675ffb0c9bSToomas Soome extern const mDNSInterfaceID mDNSInterface_LocalOnly; // Special value 25685ffb0c9bSToomas Soome extern const mDNSInterfaceID mDNSInterface_Unicast; // Special value 25695ffb0c9bSToomas Soome extern const mDNSInterfaceID mDNSInterfaceMark; // Special value 25705ffb0c9bSToomas Soome extern const mDNSInterfaceID mDNSInterface_P2P; // Special value 25715ffb0c9bSToomas Soome extern const mDNSInterfaceID uDNSInterfaceMark; // Special value 2572c65ebfc7SToomas Soome extern const mDNSInterfaceID mDNSInterface_BLE; // Special value 2573c65ebfc7SToomas Soome 2574c65ebfc7SToomas Soome #define LocalOnlyOrP2PInterface(INTERFACE) ((INTERFACE == mDNSInterface_LocalOnly) || (INTERFACE == mDNSInterface_P2P) || (INTERFACE == mDNSInterface_BLE)) 25755ffb0c9bSToomas Soome 25765ffb0c9bSToomas Soome extern const mDNSIPPort DiscardPort; 25775ffb0c9bSToomas Soome extern const mDNSIPPort SSHPort; 25785ffb0c9bSToomas Soome extern const mDNSIPPort UnicastDNSPort; 25795ffb0c9bSToomas Soome extern const mDNSIPPort SSDPPort; 25805ffb0c9bSToomas Soome extern const mDNSIPPort IPSECPort; 25815ffb0c9bSToomas Soome extern const mDNSIPPort NSIPCPort; 25825ffb0c9bSToomas Soome extern const mDNSIPPort NATPMPAnnouncementPort; 25835ffb0c9bSToomas Soome extern const mDNSIPPort NATPMPPort; 25845ffb0c9bSToomas Soome extern const mDNSIPPort DNSEXTPort; 25855ffb0c9bSToomas Soome extern const mDNSIPPort MulticastDNSPort; 25865ffb0c9bSToomas Soome extern const mDNSIPPort LoopbackIPCPort; 25875ffb0c9bSToomas Soome extern const mDNSIPPort PrivateDNSPort; 25885ffb0c9bSToomas Soome 25895ffb0c9bSToomas Soome extern const OwnerOptData zeroOwner; 25905ffb0c9bSToomas Soome 25915ffb0c9bSToomas Soome extern const mDNSIPPort zeroIPPort; 25925ffb0c9bSToomas Soome extern const mDNSv4Addr zerov4Addr; 25935ffb0c9bSToomas Soome extern const mDNSv6Addr zerov6Addr; 25945ffb0c9bSToomas Soome extern const mDNSEthAddr zeroEthAddr; 25955ffb0c9bSToomas Soome extern const mDNSv4Addr onesIPv4Addr; 25965ffb0c9bSToomas Soome extern const mDNSv6Addr onesIPv6Addr; 25975ffb0c9bSToomas Soome extern const mDNSEthAddr onesEthAddr; 25985ffb0c9bSToomas Soome extern const mDNSAddr zeroAddr; 25995ffb0c9bSToomas Soome 26005ffb0c9bSToomas Soome extern const mDNSv4Addr AllDNSAdminGroup; 26015ffb0c9bSToomas Soome extern const mDNSv4Addr AllHosts_v4; 26025ffb0c9bSToomas Soome extern const mDNSv6Addr AllHosts_v6; 26035ffb0c9bSToomas Soome extern const mDNSv6Addr NDP_prefix; 26045ffb0c9bSToomas Soome extern const mDNSEthAddr AllHosts_v6_Eth; 26055ffb0c9bSToomas Soome extern const mDNSAddr AllDNSLinkGroup_v4; 26065ffb0c9bSToomas Soome extern const mDNSAddr AllDNSLinkGroup_v6; 26074b22b933Srs 26084b22b933Srs extern const mDNSOpaque16 zeroID; 26095ffb0c9bSToomas Soome extern const mDNSOpaque16 onesID; 26104b22b933Srs extern const mDNSOpaque16 QueryFlags; 26114b22b933Srs extern const mDNSOpaque16 uQueryFlags; 26125ffb0c9bSToomas Soome extern const mDNSOpaque16 DNSSecQFlags; 26134b22b933Srs extern const mDNSOpaque16 ResponseFlags; 26144b22b933Srs extern const mDNSOpaque16 UpdateReqFlags; 26154b22b933Srs extern const mDNSOpaque16 UpdateRespFlags; 2616c65ebfc7SToomas Soome extern const mDNSOpaque16 SubscribeFlags; 2617c65ebfc7SToomas Soome extern const mDNSOpaque16 UnSubscribeFlags; 26184b22b933Srs 26195ffb0c9bSToomas Soome extern const mDNSOpaque64 zeroOpaque64; 2620c65ebfc7SToomas Soome extern const mDNSOpaque128 zeroOpaque128; 26215ffb0c9bSToomas Soome 26225ffb0c9bSToomas Soome extern mDNSBool StrictUnicastOrdering; 26235ffb0c9bSToomas Soome extern mDNSu8 NumUnicastDNSServers; 2624cda73f64SToomas Soome #if APPLE_OSX_mDNSResponder 2625cda73f64SToomas Soome extern mDNSu8 NumUnreachableDNSServers; 2626cda73f64SToomas Soome #endif 26275ffb0c9bSToomas Soome 26285ffb0c9bSToomas Soome #define localdomain (*(const domainname *)"\x5" "local") 26295ffb0c9bSToomas Soome #define DeviceInfoName (*(const domainname *)"\xC" "_device-info" "\x4" "_tcp") 26305ffb0c9bSToomas Soome #define LocalDeviceInfoName (*(const domainname *)"\xC" "_device-info" "\x4" "_tcp" "\x5" "local") 26315ffb0c9bSToomas Soome #define SleepProxyServiceType (*(const domainname *)"\xC" "_sleep-proxy" "\x4" "_udp") 26325ffb0c9bSToomas Soome 26334b22b933Srs // *************************************************************************** 26344b22b933Srs #if 0 26355ffb0c9bSToomas Soome #pragma mark - 26364b22b933Srs #pragma mark - Inline functions 26374b22b933Srs #endif 26384b22b933Srs 26394b22b933Srs #if (defined(_MSC_VER)) 26405ffb0c9bSToomas Soome #define mDNSinline static __inline 26414b22b933Srs #elif ((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 9))) 26425ffb0c9bSToomas Soome #define mDNSinline static inline 2643*3b436d06SToomas Soome #else 2644*3b436d06SToomas Soome #define mDNSinline static inline 26454b22b933Srs #endif 26464b22b933Srs 26474b22b933Srs // If we're not doing inline functions, then this header needs to have the extern declarations 26484b22b933Srs #if !defined(mDNSinline) 26494b22b933Srs extern mDNSs32 NonZeroTime(mDNSs32 t); 26504b22b933Srs extern mDNSu16 mDNSVal16(mDNSOpaque16 x); 26514b22b933Srs extern mDNSOpaque16 mDNSOpaque16fromIntVal(mDNSu16 v); 26524b22b933Srs #endif 26534b22b933Srs 26544b22b933Srs // If we're compiling the particular C file that instantiates our inlines, then we 26554b22b933Srs // define "mDNSinline" (to empty string) so that we generate code in the following section 26564b22b933Srs #if (!defined(mDNSinline) && mDNS_InstantiateInlines) 26574b22b933Srs #define mDNSinline 26584b22b933Srs #endif 26594b22b933Srs 26604b22b933Srs #ifdef mDNSinline 26614b22b933Srs 26625ffb0c9bSToomas Soome mDNSinline mDNSs32 NonZeroTime(mDNSs32 t) { if (t) return(t);else return(1);} 26634b22b933Srs 26644b22b933Srs mDNSinline mDNSu16 mDNSVal16(mDNSOpaque16 x) { return((mDNSu16)((mDNSu16)x.b[0] << 8 | (mDNSu16)x.b[1])); } 26654b22b933Srs 26664b22b933Srs mDNSinline mDNSOpaque16 mDNSOpaque16fromIntVal(mDNSu16 v) 26675ffb0c9bSToomas Soome { 26685ffb0c9bSToomas Soome mDNSOpaque16 x; 26695ffb0c9bSToomas Soome x.b[0] = (mDNSu8)(v >> 8); 26705ffb0c9bSToomas Soome x.b[1] = (mDNSu8)(v & 0xFF); 26715ffb0c9bSToomas Soome return(x); 26725ffb0c9bSToomas Soome } 26734b22b933Srs 26744b22b933Srs #endif 26754b22b933Srs 26764b22b933Srs // *************************************************************************** 26774b22b933Srs #if 0 26785ffb0c9bSToomas Soome #pragma mark - 26794b22b933Srs #pragma mark - Main Client Functions 26804b22b933Srs #endif 26814b22b933Srs 26824b22b933Srs // Every client should call mDNS_Init, passing in storage for the mDNS object and the mDNS_PlatformSupport object. 26834b22b933Srs // 26844b22b933Srs // Clients that are only advertising services should use mDNS_Init_NoCache and mDNS_Init_ZeroCacheSize. 2685c65ebfc7SToomas Soome // Clients that plan to perform queries (mDNS_StartQuery, mDNS_StartBrowse, etc.) 26864b22b933Srs // need to provide storage for the resource record cache, or the query calls will return 'mStatus_NoCache'. 26874b22b933Srs // The rrcachestorage parameter is the address of memory for the resource record cache, and 26884b22b933Srs // the rrcachesize parameter is the number of entries in the CacheRecord array passed in. 26894b22b933Srs // (i.e. the size of the cache memory needs to be sizeof(CacheRecord) * rrcachesize). 26904b22b933Srs // OS X 10.3 Panther uses an initial cache size of 64 entries, and then mDNSCore sends an 26914b22b933Srs // mStatus_GrowCache message if it needs more. 26924b22b933Srs // 26934b22b933Srs // Most clients should use mDNS_Init_AdvertiseLocalAddresses. This causes mDNSCore to automatically 26944b22b933Srs // create the correct address records for all the hosts interfaces. If you plan to advertise 26954b22b933Srs // services being offered by the local machine, this is almost always what you want. 26964b22b933Srs // There are two cases where you might use mDNS_Init_DontAdvertiseLocalAddresses: 26974b22b933Srs // 1. A client-only device, that browses for services but doesn't advertise any of its own. 26984b22b933Srs // 2. A proxy-registration service, that advertises services being offered by other machines, and takes 26994b22b933Srs // the appropriate steps to manually create the correct address records for those other machines. 27004b22b933Srs // In principle, a proxy-like registration service could manually create address records for its own machine too, 27014b22b933Srs // but this would be pointless extra effort when using mDNS_Init_AdvertiseLocalAddresses does that for you. 27024b22b933Srs // 27035ffb0c9bSToomas Soome // Note that a client-only device that wishes to prohibit multicast advertisements (e.g. from 27045ffb0c9bSToomas Soome // higher-layer API calls) must also set DivertMulticastAdvertisements in the mDNS structure and 27055ffb0c9bSToomas Soome // advertise local address(es) on a loopback interface. 27065ffb0c9bSToomas Soome // 27074b22b933Srs // When mDNS has finished setting up the client's callback is called 27084b22b933Srs // A client can also spin and poll the mDNSPlatformStatus field to see when it changes from mStatus_Waiting to mStatus_NoError 27094b22b933Srs // 27105ffb0c9bSToomas Soome // Call mDNS_StartExit to tidy up before exiting 27115ffb0c9bSToomas Soome // Because exiting may be an asynchronous process (e.g. if unicast records need to be deregistered) 27125ffb0c9bSToomas Soome // client layer may choose to wait until mDNS_ExitNow() returns true before calling mDNS_FinalExit(). 27134b22b933Srs // 27144b22b933Srs // Call mDNS_Register with a completed AuthRecord object to register a resource record 27154b22b933Srs // If the resource record type is kDNSRecordTypeUnique (or kDNSknownunique) then if a conflicting resource record is discovered, 27164b22b933Srs // the resource record's mDNSRecordCallback will be called with error code mStatus_NameConflict. The callback should deregister 27174b22b933Srs // the record, and may then try registering the record again after picking a new name (e.g. by automatically appending a number). 27184b22b933Srs // Following deregistration, the RecordCallback will be called with result mStatus_MemFree to signal that it is safe to deallocate 27194b22b933Srs // the record's storage (memory must be freed asynchronously to allow for goodbye packets and dynamic update deregistration). 27204b22b933Srs // 27214b22b933Srs // Call mDNS_StartQuery to initiate a query. mDNS will proceed to issue Multicast DNS query packets, and any time a response 27224b22b933Srs // is received containing a record which matches the question, the DNSQuestion's mDNSAnswerCallback function will be called 27234b22b933Srs // Call mDNS_StopQuery when no more answers are required 27244b22b933Srs // 27254b22b933Srs // Care should be taken on multi-threaded or interrupt-driven environments. 27264b22b933Srs // The main mDNS routines call mDNSPlatformLock() on entry and mDNSPlatformUnlock() on exit; 27274b22b933Srs // each platform layer needs to implement these appropriately for its respective platform. 27284b22b933Srs // For example, if the support code on a particular platform implements timer callbacks at interrupt time, then 27294b22b933Srs // mDNSPlatformLock/Unlock need to disable interrupts or do similar concurrency control to ensure that the mDNS 27304b22b933Srs // code is not entered by an interrupt-time timer callback while in the middle of processing a client call. 27314b22b933Srs 27324b22b933Srs extern mStatus mDNS_Init (mDNS *const m, mDNS_PlatformSupport *const p, 27335ffb0c9bSToomas Soome CacheEntity *rrcachestorage, mDNSu32 rrcachesize, 27345ffb0c9bSToomas Soome mDNSBool AdvertiseLocalAddresses, 27355ffb0c9bSToomas Soome mDNSCallback *Callback, void *Context); 27364b22b933Srs // See notes above on use of NoCache/ZeroCacheSize 27374b22b933Srs #define mDNS_Init_NoCache mDNSNULL 27384b22b933Srs #define mDNS_Init_ZeroCacheSize 0 27394b22b933Srs // See notes above on use of Advertise/DontAdvertiseLocalAddresses 27404b22b933Srs #define mDNS_Init_AdvertiseLocalAddresses mDNStrue 27414b22b933Srs #define mDNS_Init_DontAdvertiseLocalAddresses mDNSfalse 27424b22b933Srs #define mDNS_Init_NoInitCallback mDNSNULL 27434b22b933Srs #define mDNS_Init_NoInitCallbackContext mDNSNULL 27444b22b933Srs 27455ffb0c9bSToomas Soome extern void mDNS_ConfigChanged(mDNS *const m); 27464b22b933Srs extern void mDNS_GrowCache (mDNS *const m, CacheEntity *storage, mDNSu32 numrecords); 27475ffb0c9bSToomas Soome extern void mDNS_StartExit (mDNS *const m); 27485ffb0c9bSToomas Soome extern void mDNS_FinalExit (mDNS *const m); 27495ffb0c9bSToomas Soome #define mDNS_Close(m) do { mDNS_StartExit(m); mDNS_FinalExit(m); } while(0) 27505ffb0c9bSToomas Soome #define mDNS_ExitNow(m, now) ((now) - (m)->ShutdownTime >= 0 || (!(m)->ResourceRecords)) 27515ffb0c9bSToomas Soome 27524b22b933Srs extern mDNSs32 mDNS_Execute (mDNS *const m); 27534b22b933Srs 27544b22b933Srs extern mStatus mDNS_Register (mDNS *const m, AuthRecord *const rr); 27554b22b933Srs extern mStatus mDNS_Update (mDNS *const m, AuthRecord *const rr, mDNSu32 newttl, 27565ffb0c9bSToomas Soome const mDNSu16 newrdlength, RData *const newrdata, mDNSRecordUpdateCallback *Callback); 27574b22b933Srs extern mStatus mDNS_Deregister(mDNS *const m, AuthRecord *const rr); 27584b22b933Srs 27594b22b933Srs extern mStatus mDNS_StartQuery(mDNS *const m, DNSQuestion *const question); 27604b22b933Srs extern mStatus mDNS_StopQuery (mDNS *const m, DNSQuestion *const question); 27615ffb0c9bSToomas Soome extern mStatus mDNS_StopQueryWithRemoves(mDNS *const m, DNSQuestion *const question); 27624b22b933Srs extern mStatus mDNS_Reconfirm (mDNS *const m, CacheRecord *const cacherr); 27635ffb0c9bSToomas Soome extern mStatus mDNS_Reconfirm_internal(mDNS *const m, CacheRecord *const rr, mDNSu32 interval); 27644b22b933Srs extern mStatus mDNS_ReconfirmByValue(mDNS *const m, ResourceRecord *const rr); 27655ffb0c9bSToomas Soome extern void mDNS_PurgeCacheResourceRecord(mDNS *const m, CacheRecord *rr); 27664b22b933Srs extern mDNSs32 mDNS_TimeNow(const mDNS *const m); 27674b22b933Srs 27685ffb0c9bSToomas Soome extern mStatus mDNS_StartNATOperation(mDNS *const m, NATTraversalInfo *traversal); 27695ffb0c9bSToomas Soome extern mStatus mDNS_StopNATOperation(mDNS *const m, NATTraversalInfo *traversal); 27705ffb0c9bSToomas Soome extern mStatus mDNS_StopNATOperation_internal(mDNS *m, NATTraversalInfo *traversal); 27715ffb0c9bSToomas Soome 27725ffb0c9bSToomas Soome extern DomainAuthInfo *GetAuthInfoForName(mDNS *m, const domainname *const name); 27735ffb0c9bSToomas Soome 27745ffb0c9bSToomas Soome extern void mDNS_UpdateAllowSleep(mDNS *const m); 27755ffb0c9bSToomas Soome 27764b22b933Srs // *************************************************************************** 27774b22b933Srs #if 0 27785ffb0c9bSToomas Soome #pragma mark - 27794b22b933Srs #pragma mark - Platform support functions that are accessible to the client layer too 27804b22b933Srs #endif 27814b22b933Srs 27825ffb0c9bSToomas Soome extern mDNSs32 mDNSPlatformOneSecond; 27834b22b933Srs 27844b22b933Srs // *************************************************************************** 27854b22b933Srs #if 0 27865ffb0c9bSToomas Soome #pragma mark - 27874b22b933Srs #pragma mark - General utility and helper functions 27884b22b933Srs #endif 27894b22b933Srs 27905ffb0c9bSToomas Soome // mDNS_Dereg_normal is used for most calls to mDNS_Deregister_internal 27915ffb0c9bSToomas Soome // mDNS_Dereg_rapid is used to send one goodbye instead of three, when we want the memory available for reuse sooner 27925ffb0c9bSToomas Soome // mDNS_Dereg_conflict is used to indicate that this record is being forcibly deregistered because of a conflict 27935ffb0c9bSToomas Soome // mDNS_Dereg_repeat is used when cleaning up, for records that may have already been forcibly deregistered 27945ffb0c9bSToomas Soome typedef enum { mDNS_Dereg_normal, mDNS_Dereg_rapid, mDNS_Dereg_conflict, mDNS_Dereg_repeat } mDNS_Dereg_type; 27955ffb0c9bSToomas Soome 27964b22b933Srs // mDNS_RegisterService is a single call to register the set of resource records associated with a given named service. 27974b22b933Srs // 27984b22b933Srs // 27994b22b933Srs // mDNS_AddRecordToService adds an additional record to a Service Record Set. This record may be deregistered 28004b22b933Srs // via mDNS_RemoveRecordFromService, or by deregistering the service. mDNS_RemoveRecordFromService is passed a 28014b22b933Srs // callback to free the memory associated with the extra RR when it is safe to do so. The ExtraResourceRecord 28024b22b933Srs // object can be found in the record's context pointer. 28035ffb0c9bSToomas Soome 28044b22b933Srs // mDNS_GetBrowseDomains is a special case of the mDNS_StartQuery call, where the resulting answers 28054b22b933Srs // are a list of PTR records indicating (in the rdata) domains that are recommended for browsing. 28064b22b933Srs // After getting the list of domains to browse, call mDNS_StopQuery to end the search. 28074b22b933Srs // mDNS_GetDefaultBrowseDomain returns the name of the domain that should be highlighted by default. 28084b22b933Srs // 28094b22b933Srs // mDNS_GetRegistrationDomains and mDNS_GetDefaultRegistrationDomain are the equivalent calls to get the list 28104b22b933Srs // of one or more domains that should be offered to the user as choices for where they may register their service, 28114b22b933Srs // and the default domain in which to register in the case where the user has made no selection. 28124b22b933Srs 28134b22b933Srs extern void mDNS_SetupResourceRecord(AuthRecord *rr, RData *RDataStorage, mDNSInterfaceID InterfaceID, 28145ffb0c9bSToomas Soome mDNSu16 rrtype, mDNSu32 ttl, mDNSu8 RecordType, AuthRecType artype, mDNSRecordCallback Callback, void *Context); 28155ffb0c9bSToomas Soome 2816c65ebfc7SToomas Soome extern mDNSu32 deriveD2DFlagsFromAuthRecType(AuthRecType authRecType); 28174b22b933Srs extern mStatus mDNS_RegisterService (mDNS *const m, ServiceRecordSet *sr, 28185ffb0c9bSToomas Soome const domainlabel *const name, const domainname *const type, const domainname *const domain, 2819*3b436d06SToomas Soome const domainname *const host, mDNSIPPort port, RData *txtrdata, const mDNSu8 txtinfo[], mDNSu16 txtlen, 28205ffb0c9bSToomas Soome AuthRecord *SubTypes, mDNSu32 NumSubTypes, 28215ffb0c9bSToomas Soome mDNSInterfaceID InterfaceID, mDNSServiceCallback Callback, void *Context, mDNSu32 flags); 28225ffb0c9bSToomas Soome extern mStatus mDNS_AddRecordToService(mDNS *const m, ServiceRecordSet *sr, ExtraResourceRecord *extra, RData *rdata, mDNSu32 ttl, mDNSu32 flags); 28234b22b933Srs extern mStatus mDNS_RemoveRecordFromService(mDNS *const m, ServiceRecordSet *sr, ExtraResourceRecord *extra, mDNSRecordCallback MemFreeCallback, void *Context); 28244b22b933Srs extern mStatus mDNS_RenameAndReregisterService(mDNS *const m, ServiceRecordSet *const sr, const domainlabel *newname); 28255ffb0c9bSToomas Soome extern mStatus mDNS_DeregisterService_drt(mDNS *const m, ServiceRecordSet *sr, mDNS_Dereg_type drt); 28265ffb0c9bSToomas Soome #define mDNS_DeregisterService(M,S) mDNS_DeregisterService_drt((M), (S), mDNS_Dereg_normal) 28274b22b933Srs 28284b22b933Srs extern mStatus mDNS_RegisterNoSuchService(mDNS *const m, AuthRecord *const rr, 28295ffb0c9bSToomas Soome const domainlabel *const name, const domainname *const type, const domainname *const domain, 28305ffb0c9bSToomas Soome const domainname *const host, 28315ffb0c9bSToomas Soome const mDNSInterfaceID InterfaceID, mDNSRecordCallback Callback, void *Context, mDNSu32 flags); 28324b22b933Srs #define mDNS_DeregisterNoSuchService mDNS_Deregister 28334b22b933Srs 28345ffb0c9bSToomas Soome extern void mDNS_SetupQuestion(DNSQuestion *const q, const mDNSInterfaceID InterfaceID, const domainname *const name, 28355ffb0c9bSToomas Soome const mDNSu16 qtype, mDNSQuestionCallback *const callback, void *const context); 28365ffb0c9bSToomas Soome 28374b22b933Srs extern mStatus mDNS_StartBrowse(mDNS *const m, DNSQuestion *const question, 28385ffb0c9bSToomas Soome const domainname *const srv, const domainname *const domain, const mDNSu8 *anondata, 28395ffb0c9bSToomas Soome const mDNSInterfaceID InterfaceID, mDNSu32 flags, 28405ffb0c9bSToomas Soome mDNSBool ForceMCast, mDNSBool useBackgroundTrafficClass, 28415ffb0c9bSToomas Soome mDNSQuestionCallback *Callback, void *Context); 28424b22b933Srs #define mDNS_StopBrowse mDNS_StopQuery 28434b22b933Srs 28444b22b933Srs 28454b22b933Srs typedef enum 28465ffb0c9bSToomas Soome { 28475ffb0c9bSToomas Soome mDNS_DomainTypeBrowse = 0, 28485ffb0c9bSToomas Soome mDNS_DomainTypeBrowseDefault = 1, 28495ffb0c9bSToomas Soome mDNS_DomainTypeBrowseAutomatic = 2, 28505ffb0c9bSToomas Soome mDNS_DomainTypeRegistration = 3, 28515ffb0c9bSToomas Soome mDNS_DomainTypeRegistrationDefault = 4, 28525ffb0c9bSToomas Soome 28535ffb0c9bSToomas Soome mDNS_DomainTypeMax = 4 28545ffb0c9bSToomas Soome } mDNS_DomainType; 28554b22b933Srs 28564b22b933Srs extern const char *const mDNS_DomainTypeNames[]; 28574b22b933Srs 28584b22b933Srs extern mStatus mDNS_GetDomains(mDNS *const m, DNSQuestion *const question, mDNS_DomainType DomainType, const domainname *dom, 28595ffb0c9bSToomas Soome const mDNSInterfaceID InterfaceID, mDNSQuestionCallback *Callback, void *Context); 28604b22b933Srs #define mDNS_StopGetDomains mDNS_StopQuery 28614b22b933Srs extern mStatus mDNS_AdvertiseDomains(mDNS *const m, AuthRecord *rr, mDNS_DomainType DomainType, const mDNSInterfaceID InterfaceID, char *domname); 28624b22b933Srs #define mDNS_StopAdvertiseDomains mDNS_Deregister 28634b22b933Srs 28645ffb0c9bSToomas Soome extern mDNSOpaque16 mDNS_NewMessageID(mDNS *const m); 2865cda73f64SToomas Soome extern mDNSBool mDNS_AddressIsLocalSubnet(mDNS *const m, const mDNSInterfaceID InterfaceID, const mDNSAddr *addr); 28665ffb0c9bSToomas Soome 28675ffb0c9bSToomas Soome extern DNSServer *GetServerForQuestion(mDNS *m, DNSQuestion *question); 28685ffb0c9bSToomas Soome extern mDNSu32 SetValidDNSServers(mDNS *m, DNSQuestion *question); 28695ffb0c9bSToomas Soome 28704b22b933Srs // *************************************************************************** 28714b22b933Srs #if 0 28725ffb0c9bSToomas Soome #pragma mark - 28734b22b933Srs #pragma mark - DNS name utility functions 28744b22b933Srs #endif 28754b22b933Srs 28764b22b933Srs // In order to expose the full capabilities of the DNS protocol (which allows any arbitrary eight-bit values 28774b22b933Srs // in domain name labels, including unlikely characters like ascii nulls and even dots) all the mDNS APIs 28784b22b933Srs // work with DNS's native length-prefixed strings. For convenience in C, the following utility functions 28794b22b933Srs // are provided for converting between C's null-terminated strings and DNS's length-prefixed strings. 28804b22b933Srs 28814b22b933Srs // Assignment 28824b22b933Srs // A simple C structure assignment of a domainname can cause a protection fault by accessing unmapped memory, 28834b22b933Srs // because that object is defined to be 256 bytes long, but not all domainname objects are truly the full size. 28844b22b933Srs // This macro uses mDNSPlatformMemCopy() to make sure it only touches the actual bytes that are valid. 28855ffb0c9bSToomas Soome #define AssignDomainName(DST, SRC) do { mDNSu16 len__ = DomainNameLength((SRC)); \ 2886c65ebfc7SToomas Soome if (len__ <= MAX_DOMAIN_NAME) mDNSPlatformMemCopy((DST)->c, (SRC)->c, len__); else (DST)->c[0] = 0; } while(0) 28874b22b933Srs 28884b22b933Srs // Comparison functions 28895ffb0c9bSToomas Soome #define SameDomainLabelCS(A,B) ((A)[0] == (B)[0] && mDNSPlatformMemSame((A)+1, (B)+1, (A)[0])) 28904b22b933Srs extern mDNSBool SameDomainLabel(const mDNSu8 *a, const mDNSu8 *b); 28914b22b933Srs extern mDNSBool SameDomainName(const domainname *const d1, const domainname *const d2); 28925ffb0c9bSToomas Soome extern mDNSBool SameDomainNameCS(const domainname *const d1, const domainname *const d2); 28935ffb0c9bSToomas Soome typedef mDNSBool DomainNameComparisonFn (const domainname *const d1, const domainname *const d2); 28944b22b933Srs extern mDNSBool IsLocalDomain(const domainname *d); // returns true for domains that by default should be looked up using link-local multicast 28954b22b933Srs 28965ffb0c9bSToomas Soome #define StripFirstLabel(X) ((const domainname *)& (X)->c[(X)->c[0] ? 1 + (X)->c[0] : 0]) 28975ffb0c9bSToomas Soome 28985ffb0c9bSToomas Soome #define FirstLabel(X) ((const domainlabel *)(X)) 28995ffb0c9bSToomas Soome #define SecondLabel(X) ((const domainlabel *)StripFirstLabel(X)) 29005ffb0c9bSToomas Soome #define ThirdLabel(X) ((const domainlabel *)StripFirstLabel(StripFirstLabel(X))) 29015ffb0c9bSToomas Soome 29025ffb0c9bSToomas Soome extern const mDNSu8 *LastLabel(const domainname *d); 29035ffb0c9bSToomas Soome 29044b22b933Srs // Get total length of domain name, in native DNS format, including terminal root label 29054b22b933Srs // (e.g. length of "com." is 5 (length byte, three data bytes, final zero) 29065ffb0c9bSToomas Soome extern mDNSu16 DomainNameLengthLimit(const domainname *const name, const mDNSu8 *limit); 29075ffb0c9bSToomas Soome #define DomainNameLength(name) DomainNameLengthLimit((name), (name)->c + MAX_DOMAIN_NAME) 29084b22b933Srs 29094b22b933Srs // Append functions to append one or more labels to an existing native format domain name: 29104b22b933Srs // AppendLiteralLabelString adds a single label from a literal C string, with no escape character interpretation. 29114b22b933Srs // AppendDNSNameString adds zero or more labels from a C string using conventional DNS dots-and-escaping interpretation 29124b22b933Srs // AppendDomainLabel adds a single label from a native format domainlabel 29134b22b933Srs // AppendDomainName adds zero or more labels from a native format domainname 29144b22b933Srs extern mDNSu8 *AppendLiteralLabelString(domainname *const name, const char *cstr); 29154b22b933Srs extern mDNSu8 *AppendDNSNameString (domainname *const name, const char *cstr); 29164b22b933Srs extern mDNSu8 *AppendDomainLabel (domainname *const name, const domainlabel *const label); 29174b22b933Srs extern mDNSu8 *AppendDomainName (domainname *const name, const domainname *const append); 29184b22b933Srs 29194b22b933Srs // Convert from null-terminated string to native DNS format: 29204b22b933Srs // The DomainLabel form makes a single label from a literal C string, with no escape character interpretation. 29214b22b933Srs // The DomainName form makes native format domain name from a C string using conventional DNS interpretation: 29224b22b933Srs // dots separate labels, and within each label, '\.' represents a literal dot, '\\' represents a literal 29234b22b933Srs // backslash and backslash with three decimal digits (e.g. \000) represents an arbitrary byte value. 29244b22b933Srs extern mDNSBool MakeDomainLabelFromLiteralString(domainlabel *const label, const char *cstr); 29254b22b933Srs extern mDNSu8 *MakeDomainNameFromDNSNameString (domainname *const name, const char *cstr); 29264b22b933Srs 29274b22b933Srs // Convert native format domainlabel or domainname back to C string format 29284b22b933Srs // IMPORTANT: 29294b22b933Srs // When using ConvertDomainLabelToCString, the target buffer must be MAX_ESCAPED_DOMAIN_LABEL (254) bytes long 29304b22b933Srs // to guarantee there will be no buffer overrun. It is only safe to use a buffer shorter than this in rare cases 29314b22b933Srs // where the label is known to be constrained somehow (for example, if the label is known to be either "_tcp" or "_udp"). 29325ffb0c9bSToomas Soome // Similarly, when using ConvertDomainNameToCString, the target buffer must be MAX_ESCAPED_DOMAIN_NAME (1009) bytes long. 29334b22b933Srs // See definitions of MAX_ESCAPED_DOMAIN_LABEL and MAX_ESCAPED_DOMAIN_NAME for more detailed explanation. 29344b22b933Srs extern char *ConvertDomainLabelToCString_withescape(const domainlabel *const name, char *cstr, char esc); 29354b22b933Srs #define ConvertDomainLabelToCString_unescaped(D,C) ConvertDomainLabelToCString_withescape((D), (C), 0) 29364b22b933Srs #define ConvertDomainLabelToCString(D,C) ConvertDomainLabelToCString_withescape((D), (C), '\\') 29374b22b933Srs extern char *ConvertDomainNameToCString_withescape(const domainname *const name, char *cstr, char esc); 29384b22b933Srs #define ConvertDomainNameToCString_unescaped(D,C) ConvertDomainNameToCString_withescape((D), (C), 0) 29394b22b933Srs #define ConvertDomainNameToCString(D,C) ConvertDomainNameToCString_withescape((D), (C), '\\') 29404b22b933Srs 29414b22b933Srs extern void ConvertUTF8PstringToRFC1034HostLabel(const mDNSu8 UTF8Name[], domainlabel *const hostlabel); 29424b22b933Srs 2943c65ebfc7SToomas Soome #define ValidTransportProtocol(X) ( (X)[0] == 4 && (X)[1] == '_' && \ 2944c65ebfc7SToomas Soome ((((X)[2] | 0x20) == 'u' && ((X)[3] | 0x20) == 'd') || (((X)[2] | 0x20) == 't' && ((X)[3] | 0x20) == 'c')) && \ 2945c65ebfc7SToomas Soome ((X)[4] | 0x20) == 'p') 2946c65ebfc7SToomas Soome 29474b22b933Srs extern mDNSu8 *ConstructServiceName(domainname *const fqdn, const domainlabel *name, const domainname *type, const domainname *const domain); 29484b22b933Srs extern mDNSBool DeconstructServiceName(const domainname *const fqdn, domainlabel *const name, domainname *const type, domainname *const domain); 29494b22b933Srs 29504b22b933Srs // Note: Some old functions have been replaced by more sensibly-named versions. 29514b22b933Srs // You can uncomment the hash-defines below if you don't want to have to change your source code right away. 29524b22b933Srs // When updating your code, note that (unlike the old versions) *all* the new routines take the target object 29534b22b933Srs // as their first parameter. 29544b22b933Srs //#define ConvertCStringToDomainName(SRC,DST) MakeDomainNameFromDNSNameString((DST),(SRC)) 29554b22b933Srs //#define ConvertCStringToDomainLabel(SRC,DST) MakeDomainLabelFromLiteralString((DST),(SRC)) 29564b22b933Srs //#define AppendStringLabelToName(DST,SRC) AppendLiteralLabelString((DST),(SRC)) 29574b22b933Srs //#define AppendStringNameToName(DST,SRC) AppendDNSNameString((DST),(SRC)) 29584b22b933Srs //#define AppendDomainLabelToName(DST,SRC) AppendDomainLabel((DST),(SRC)) 29594b22b933Srs //#define AppendDomainNameToName(DST,SRC) AppendDomainName((DST),(SRC)) 29604b22b933Srs 29614b22b933Srs // *************************************************************************** 29624b22b933Srs #if 0 29635ffb0c9bSToomas Soome #pragma mark - 29644b22b933Srs #pragma mark - Other utility functions and macros 29654b22b933Srs #endif 29664b22b933Srs 29674b22b933Srs // mDNS_vsnprintf/snprintf return the number of characters written, excluding the final terminating null. 29684b22b933Srs // The output is always null-terminated: for example, if the output turns out to be exactly buflen long, 29694b22b933Srs // then the output will be truncated by one character to allow space for the terminating null. 29704b22b933Srs // Unlike standard C vsnprintf/snprintf, they return the number of characters *actually* written, 29714b22b933Srs // not the number of characters that *would* have been printed were buflen unlimited. 2972c65ebfc7SToomas Soome extern mDNSu32 mDNS_vsnprintf(char *sbuffer, mDNSu32 buflen, const char *fmt, va_list arg) IS_A_PRINTF_STYLE_FUNCTION(3,0); 29734b22b933Srs extern mDNSu32 mDNS_snprintf(char *sbuffer, mDNSu32 buflen, const char *fmt, ...) IS_A_PRINTF_STYLE_FUNCTION(3,4); 29744b22b933Srs extern mDNSu32 NumCacheRecordsForInterfaceID(const mDNS *const m, mDNSInterfaceID id); 29754b22b933Srs extern char *DNSTypeName(mDNSu16 rrtype); 29765ffb0c9bSToomas Soome extern char *GetRRDisplayString_rdb(const ResourceRecord *const rr, const RDataBody *const rd1, char *const buffer); 29774b22b933Srs #define RRDisplayString(m, rr) GetRRDisplayString_rdb(rr, &(rr)->rdata->u, (m)->MsgBuffer) 29784b22b933Srs #define ARDisplayString(m, rr) GetRRDisplayString_rdb(&(rr)->resrec, &(rr)->resrec.rdata->u, (m)->MsgBuffer) 29794b22b933Srs #define CRDisplayString(m, rr) GetRRDisplayString_rdb(&(rr)->resrec, &(rr)->resrec.rdata->u, (m)->MsgBuffer) 2980*3b436d06SToomas Soome #define MortalityDisplayString(M) (M == Mortality_Mortal ? "mortal" : (M == Mortality_Immortal ? "immortal" : "ghost")) 29814b22b933Srs extern mDNSBool mDNSSameAddress(const mDNSAddr *ip1, const mDNSAddr *ip2); 29824b22b933Srs extern void IncrementLabelSuffix(domainlabel *name, mDNSBool RichText); 29835ffb0c9bSToomas Soome extern mDNSBool mDNSv4AddrIsRFC1918(const mDNSv4Addr * const addr); // returns true for RFC1918 private addresses 29845ffb0c9bSToomas Soome #define mDNSAddrIsRFC1918(X) ((X)->type == mDNSAddrType_IPv4 && mDNSv4AddrIsRFC1918(&(X)->ip.v4)) 29855ffb0c9bSToomas Soome 29865ffb0c9bSToomas Soome // For PCP 29875ffb0c9bSToomas Soome extern void mDNSAddrMapIPv4toIPv6(mDNSv4Addr* in, mDNSv6Addr* out); 29885ffb0c9bSToomas Soome extern mDNSBool mDNSAddrIPv4FromMappedIPv6(mDNSv6Addr *in, mDNSv4Addr *out); 29895ffb0c9bSToomas Soome 29905ffb0c9bSToomas Soome #define mDNSSameIPPort(A,B) ((A).NotAnInteger == (B).NotAnInteger) 29915ffb0c9bSToomas Soome #define mDNSSameOpaque16(A,B) ((A).NotAnInteger == (B).NotAnInteger) 29925ffb0c9bSToomas Soome #define mDNSSameOpaque32(A,B) ((A).NotAnInteger == (B).NotAnInteger) 29935ffb0c9bSToomas Soome #define mDNSSameOpaque64(A,B) ((A)->l[0] == (B)->l[0] && (A)->l[1] == (B)->l[1]) 29944b22b933Srs 29954b22b933Srs #define mDNSSameIPv4Address(A,B) ((A).NotAnInteger == (B).NotAnInteger) 29964b22b933Srs #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]) 29975ffb0c9bSToomas Soome #define mDNSSameIPv6NetworkPart(A,B) ((A).l[0] == (B).l[0] && (A).l[1] == (B).l[1]) 29984b22b933Srs #define mDNSSameEthAddress(A,B) ((A)->w[0] == (B)->w[0] && (A)->w[1] == (B)->w[1] && (A)->w[2] == (B)->w[2]) 29994b22b933Srs 30005ffb0c9bSToomas Soome #define mDNSIPPortIsZero(A) ((A).NotAnInteger == 0) 30015ffb0c9bSToomas Soome #define mDNSOpaque16IsZero(A) ((A).NotAnInteger == 0) 30025ffb0c9bSToomas Soome #define mDNSOpaque64IsZero(A) (((A)->l[0] | (A)->l[1] ) == 0) 3003c65ebfc7SToomas Soome #define mDNSOpaque128IsZero(A) (((A)->l[0] | (A)->l[1] | (A)->l[2] | (A)->l[3]) == 0) 30045ffb0c9bSToomas Soome #define mDNSIPv4AddressIsZero(A) ((A).NotAnInteger == 0) 30055ffb0c9bSToomas Soome #define mDNSIPv6AddressIsZero(A) (((A).l[0] | (A).l[1] | (A).l[2] | (A).l[3]) == 0) 30065ffb0c9bSToomas Soome #define mDNSEthAddressIsZero(A) (((A).w[0] | (A).w[1] | (A).w[2] ) == 0) 30074b22b933Srs 30085ffb0c9bSToomas Soome #define mDNSIPv4AddressIsOnes(A) ((A).NotAnInteger == 0xFFFFFFFF) 30095ffb0c9bSToomas Soome #define mDNSIPv6AddressIsOnes(A) (((A).l[0] & (A).l[1] & (A).l[2] & (A).l[3]) == 0xFFFFFFFF) 30104b22b933Srs 30115ffb0c9bSToomas Soome #define mDNSAddressIsAllDNSLinkGroup(X) ( \ 30125ffb0c9bSToomas Soome ((X)->type == mDNSAddrType_IPv4 && mDNSSameIPv4Address((X)->ip.v4, AllDNSLinkGroup_v4.ip.v4)) || \ 30135ffb0c9bSToomas Soome ((X)->type == mDNSAddrType_IPv6 && mDNSSameIPv6Address((X)->ip.v6, AllDNSLinkGroup_v6.ip.v6)) ) 30144b22b933Srs 30154b22b933Srs #define mDNSAddressIsZero(X) ( \ 30165ffb0c9bSToomas Soome ((X)->type == mDNSAddrType_IPv4 && mDNSIPv4AddressIsZero((X)->ip.v4)) || \ 30175ffb0c9bSToomas Soome ((X)->type == mDNSAddrType_IPv6 && mDNSIPv6AddressIsZero((X)->ip.v6)) ) 30184b22b933Srs 30194b22b933Srs #define mDNSAddressIsValidNonZero(X) ( \ 30205ffb0c9bSToomas Soome ((X)->type == mDNSAddrType_IPv4 && !mDNSIPv4AddressIsZero((X)->ip.v4)) || \ 30215ffb0c9bSToomas Soome ((X)->type == mDNSAddrType_IPv6 && !mDNSIPv6AddressIsZero((X)->ip.v6)) ) 30224b22b933Srs 30234b22b933Srs #define mDNSAddressIsOnes(X) ( \ 30245ffb0c9bSToomas Soome ((X)->type == mDNSAddrType_IPv4 && mDNSIPv4AddressIsOnes((X)->ip.v4)) || \ 30255ffb0c9bSToomas Soome ((X)->type == mDNSAddrType_IPv6 && mDNSIPv6AddressIsOnes((X)->ip.v6)) ) 30264b22b933Srs 30274b22b933Srs #define mDNSAddressIsValid(X) ( \ 30285ffb0c9bSToomas Soome ((X)->type == mDNSAddrType_IPv4) ? !(mDNSIPv4AddressIsZero((X)->ip.v4) || mDNSIPv4AddressIsOnes((X)->ip.v4)) : \ 30295ffb0c9bSToomas Soome ((X)->type == mDNSAddrType_IPv6) ? !(mDNSIPv6AddressIsZero((X)->ip.v6) || mDNSIPv6AddressIsOnes((X)->ip.v6)) : mDNSfalse) 30305ffb0c9bSToomas Soome 30315ffb0c9bSToomas Soome #define mDNSv4AddressIsLinkLocal(X) ((X)->b[0] == 169 && (X)->b[1] == 254) 30325ffb0c9bSToomas Soome #define mDNSv6AddressIsLinkLocal(X) ((X)->b[0] == 0xFE && ((X)->b[1] & 0xC0) == 0x80) 30335ffb0c9bSToomas Soome 30345ffb0c9bSToomas Soome #define mDNSAddressIsLinkLocal(X) ( \ 30355ffb0c9bSToomas Soome ((X)->type == mDNSAddrType_IPv4) ? mDNSv4AddressIsLinkLocal(&(X)->ip.v4) : \ 30365ffb0c9bSToomas Soome ((X)->type == mDNSAddrType_IPv6) ? mDNSv6AddressIsLinkLocal(&(X)->ip.v6) : mDNSfalse) 30374b22b933Srs 30384b22b933Srs 30394b22b933Srs // *************************************************************************** 30404b22b933Srs #if 0 30415ffb0c9bSToomas Soome #pragma mark - 30424b22b933Srs #pragma mark - Authentication Support 30434b22b933Srs #endif 30444b22b933Srs 30454b22b933Srs // Unicast DNS and Dynamic Update specific Client Calls 30464b22b933Srs // 30475ffb0c9bSToomas Soome // mDNS_SetSecretForDomain tells the core to authenticate (via TSIG with an HMAC_MD5 hash of the shared secret) 30484b22b933Srs // when dynamically updating a given zone (and its subdomains). The key used in authentication must be in 30494b22b933Srs // domain name format. The shared secret must be a null-terminated base64 encoded string. A minimum size of 30504b22b933Srs // 16 bytes (128 bits) is recommended for an MD5 hash as per RFC 2485. 30514b22b933Srs // Calling this routine multiple times for a zone replaces previously entered values. Call with a NULL key 30525ffb0c9bSToomas Soome // to disable authentication for the zone. A non-NULL autoTunnelPrefix means this is an AutoTunnel domain, 30535ffb0c9bSToomas Soome // and the value is prepended to the IPSec identifier (used for key lookup) 30544b22b933Srs 30555ffb0c9bSToomas Soome extern mStatus mDNS_SetSecretForDomain(mDNS *m, DomainAuthInfo *info, 30565ffb0c9bSToomas Soome const domainname *domain, const domainname *keyname, const char *b64keydata, const domainname *hostname, mDNSIPPort *port, mDNSBool autoTunnel); 30575ffb0c9bSToomas Soome 30585ffb0c9bSToomas Soome extern void RecreateNATMappings(mDNS *const m, const mDNSu32 waitTicks); 30594b22b933Srs 30604b22b933Srs // Hostname/Unicast Interface Configuration 30614b22b933Srs 30624b22b933Srs // All hostnames advertised point to one IPv4 address and/or one IPv6 address, set via SetPrimaryInterfaceInfo. Invoking this routine 30634b22b933Srs // updates all existing hostnames to point to the new address. 30645ffb0c9bSToomas Soome 30654b22b933Srs // A hostname is added via AddDynDNSHostName, which points to the primary interface's v4 and/or v6 addresss 30664b22b933Srs 30674b22b933Srs // The status callback is invoked to convey success or failure codes - the callback should not modify the AuthRecord or free memory. 30684b22b933Srs // Added hostnames may be removed (deregistered) via mDNS_RemoveDynDNSHostName. 30694b22b933Srs 30704b22b933Srs // Host domains added prior to specification of the primary interface address and computer name will be deferred until 30714b22b933Srs // these values are initialized. 30724b22b933Srs 30735ffb0c9bSToomas Soome // DNS servers used to resolve unicast queries are specified by mDNS_AddDNSServer. 30744b22b933Srs // For "split" DNS configurations, in which queries for different domains are sent to different servers (e.g. VPN and external), 30754b22b933Srs // a domain may be associated with a DNS server. For standard configurations, specify the root label (".") or NULL. 30765ffb0c9bSToomas Soome 30774b22b933Srs extern void mDNS_AddDynDNSHostName(mDNS *m, const domainname *fqdn, mDNSRecordCallback *StatusCallback, const void *StatusContext); 30784b22b933Srs extern void mDNS_RemoveDynDNSHostName(mDNS *m, const domainname *fqdn); 30794b22b933Srs extern void mDNS_SetPrimaryInterfaceInfo(mDNS *m, const mDNSAddr *v4addr, const mDNSAddr *v6addr, const mDNSAddr *router); 30805ffb0c9bSToomas Soome extern DNSServer *mDNS_AddDNSServer(mDNS *const m, const domainname *d, const mDNSInterfaceID interface, mDNSs32 serviceID, const mDNSAddr *addr, 3081*3b436d06SToomas Soome const mDNSIPPort port, mDNSu32 scoped, mDNSu32 timeout, mDNSBool cellIntf, mDNSBool isExpensive, mDNSBool isCLAT46, 3082*3b436d06SToomas Soome mDNSu16 resGroupID, mDNSBool reqA, mDNSBool reqAAAA, mDNSBool reqDO); 30835ffb0c9bSToomas Soome extern void PenalizeDNSServer(mDNS *const m, DNSQuestion *q, mDNSOpaque16 responseFlags); 30845ffb0c9bSToomas Soome extern void mDNS_AddSearchDomain(const domainname *const domain, mDNSInterfaceID InterfaceID); 30854b22b933Srs 30865ffb0c9bSToomas Soome extern McastResolver *mDNS_AddMcastResolver(mDNS *const m, const domainname *d, const mDNSInterfaceID interface, mDNSu32 timeout); 30875ffb0c9bSToomas Soome 30885ffb0c9bSToomas Soome // We use ((void *)0) here instead of mDNSNULL to avoid compile warnings on gcc 4.2 30895ffb0c9bSToomas Soome #define mDNS_AddSearchDomain_CString(X, I) \ 30905ffb0c9bSToomas Soome do { domainname d__; if (((X) != (void*)0) && MakeDomainNameFromDNSNameString(&d__, (X)) && d__.c[0]) mDNS_AddSearchDomain(&d__, I);} while(0) 30914b22b933Srs 30925ffb0c9bSToomas Soome // Routines called by the core, exported by DNSDigest.c 30934b22b933Srs 30945ffb0c9bSToomas Soome // Convert an arbitrary base64 encoded key key into an HMAC key (stored in AuthInfo struct) 30955ffb0c9bSToomas Soome extern mDNSs32 DNSDigest_ConstructHMACKeyfromBase64(DomainAuthInfo *info, const char *b64key); 30964b22b933Srs 30975ffb0c9bSToomas Soome // sign a DNS message. The message must be complete, with all values in network byte order. end points to the end 30984b22b933Srs // of the message, and is modified by this routine. numAdditionals is a pointer to the number of additional 30994b22b933Srs // records in HOST byte order, which is incremented upon successful completion of this routine. The function returns 31004b22b933Srs // the new end pointer on success, and NULL on failure. 31015ffb0c9bSToomas Soome extern void DNSDigest_SignMessage(DNSMessage *msg, mDNSu8 **end, DomainAuthInfo *info, mDNSu16 tcode); 31025ffb0c9bSToomas Soome 31035ffb0c9bSToomas Soome #define SwapDNSHeaderBytes(M) do { \ 31045ffb0c9bSToomas Soome (M)->h.numQuestions = (mDNSu16)((mDNSu8 *)&(M)->h.numQuestions )[0] << 8 | ((mDNSu8 *)&(M)->h.numQuestions )[1]; \ 31055ffb0c9bSToomas Soome (M)->h.numAnswers = (mDNSu16)((mDNSu8 *)&(M)->h.numAnswers )[0] << 8 | ((mDNSu8 *)&(M)->h.numAnswers )[1]; \ 31065ffb0c9bSToomas Soome (M)->h.numAuthorities = (mDNSu16)((mDNSu8 *)&(M)->h.numAuthorities)[0] << 8 | ((mDNSu8 *)&(M)->h.numAuthorities)[1]; \ 31075ffb0c9bSToomas Soome (M)->h.numAdditionals = (mDNSu16)((mDNSu8 *)&(M)->h.numAdditionals)[0] << 8 | ((mDNSu8 *)&(M)->h.numAdditionals)[1]; \ 31085ffb0c9bSToomas Soome } while (0) 31095ffb0c9bSToomas Soome 31105ffb0c9bSToomas Soome #define DNSDigest_SignMessageHostByteOrder(M,E,INFO) \ 31115ffb0c9bSToomas Soome do { SwapDNSHeaderBytes(M); DNSDigest_SignMessage((M), (E), (INFO), 0); SwapDNSHeaderBytes(M); } while (0) 31125ffb0c9bSToomas Soome 31135ffb0c9bSToomas Soome // verify a DNS message. The message must be complete, with all values in network byte order. end points to the 31145ffb0c9bSToomas Soome // end of the record. tsig is a pointer to the resource record that contains the TSIG OPT record. info is 31155ffb0c9bSToomas Soome // the matching key to use for verifying the message. This function expects that the additionals member 31165ffb0c9bSToomas Soome // of the DNS message header has already had one subtracted from it. 31175ffb0c9bSToomas Soome extern mDNSBool DNSDigest_VerifyMessage(DNSMessage *msg, mDNSu8 *end, LargeCacheRecord *tsig, DomainAuthInfo *info, mDNSu16 *rcode, mDNSu16 *tcode); 31184b22b933Srs 31194b22b933Srs // *************************************************************************** 31204b22b933Srs #if 0 31215ffb0c9bSToomas Soome #pragma mark - 31224b22b933Srs #pragma mark - PlatformSupport interface 31234b22b933Srs #endif 31244b22b933Srs 31254b22b933Srs // This section defines the interface to the Platform Support layer. 31264b22b933Srs // Normal client code should not use any of types defined here, or directly call any of the functions defined here. 31274b22b933Srs // The definitions are placed here because sometimes clients do use these calls indirectly, via other supported client operations. 31284b22b933Srs // For example, AssignDomainName is a macro defined using mDNSPlatformMemCopy() 31294b22b933Srs 31304b22b933Srs // Every platform support module must provide the following functions. 31314b22b933Srs // mDNSPlatformInit() typically opens a communication endpoint, and starts listening for mDNS packets. 31324b22b933Srs // When Setup is complete, the platform support layer calls mDNSCoreInitComplete(). 31334b22b933Srs // mDNSPlatformSendUDP() sends one UDP packet 31344b22b933Srs // When a packet is received, the PlatformSupport code calls mDNSCoreReceive() 31354b22b933Srs // mDNSPlatformClose() tidies up on exit 31364b22b933Srs // 31374b22b933Srs // Note: mDNSPlatformMemAllocate/mDNSPlatformMemFree are only required for handling oversized resource records and unicast DNS. 31384b22b933Srs // If your target platform has a well-defined specialized application, and you know that all the records it uses 31394b22b933Srs // are InlineCacheRDSize or less, then you can just make a simple mDNSPlatformMemAllocate() stub that always returns 31405ffb0c9bSToomas Soome // NULL. InlineCacheRDSize is a compile-time constant, which is set by default to 68. If you need to handle records 31414b22b933Srs // a little larger than this and you don't want to have to implement run-time allocation and freeing, then you 31424b22b933Srs // can raise the value of this constant to a suitable value (at the expense of increased memory usage). 31434b22b933Srs // 31444b22b933Srs // USE CAUTION WHEN CALLING mDNSPlatformRawTime: The m->timenow_adjust correction factor needs to be added 31454b22b933Srs // Generally speaking: 31464b22b933Srs // Code that's protected by the main mDNS lock should just use the m->timenow value 31474b22b933Srs // Code outside the main mDNS lock should use mDNS_TimeNow(m) to get properly adjusted time 31484b22b933Srs // In certain cases there may be reasons why it's necessary to get the time without taking the lock first 31494b22b933Srs // (e.g. inside the routines that are doing the locking and unlocking, where a call to get the lock would result in a 31504b22b933Srs // recursive loop); in these cases use mDNS_TimeNow_NoLock(m) to get mDNSPlatformRawTime with the proper correction factor added. 31514b22b933Srs // 31524b22b933Srs // mDNSPlatformUTC returns the time, in seconds, since Jan 1st 1970 UTC and is required for generating TSIG records 31534b22b933Srs 31544b22b933Srs extern mStatus mDNSPlatformInit (mDNS *const m); 31554b22b933Srs extern void mDNSPlatformClose (mDNS *const m); 31564b22b933Srs extern mStatus mDNSPlatformSendUDP(const mDNS *const m, const void *const msg, const mDNSu8 *const end, 3157c65ebfc7SToomas Soome mDNSInterfaceID InterfaceID, UDPSocket *src, const mDNSAddr *dst, 31585ffb0c9bSToomas Soome mDNSIPPort dstport, mDNSBool useBackgroundTrafficClass); 31594b22b933Srs 31604b22b933Srs extern void mDNSPlatformLock (const mDNS *const m); 31614b22b933Srs extern void mDNSPlatformUnlock (const mDNS *const m); 31624b22b933Srs 31635ffb0c9bSToomas Soome extern void mDNSPlatformStrCopy ( void *dst, const void *src); 3164c65ebfc7SToomas Soome extern mDNSu32 mDNSPlatformStrLCopy ( void *dst, const void *src, mDNSu32 len); 31655ffb0c9bSToomas Soome extern mDNSu32 mDNSPlatformStrLen ( const void *src); 31665ffb0c9bSToomas Soome extern void mDNSPlatformMemCopy ( void *dst, const void *src, mDNSu32 len); 31675ffb0c9bSToomas Soome extern mDNSBool mDNSPlatformMemSame (const void *dst, const void *src, mDNSu32 len); 31685ffb0c9bSToomas Soome extern int mDNSPlatformMemCmp (const void *dst, const void *src, mDNSu32 len); 31695ffb0c9bSToomas Soome extern void mDNSPlatformMemZero ( void *dst, mDNSu32 len); 31705ffb0c9bSToomas Soome extern void mDNSPlatformQsort (void *base, int nel, int width, int (*compar)(const void *, const void *)); 31715ffb0c9bSToomas Soome #if APPLE_OSX_mDNSResponder && MACOSX_MDNS_MALLOC_DEBUGGING 31725ffb0c9bSToomas Soome #define mDNSPlatformMemAllocate(X) mallocL(# X, X) 31735ffb0c9bSToomas Soome #else 31744b22b933Srs extern void * mDNSPlatformMemAllocate (mDNSu32 len); 31755ffb0c9bSToomas Soome #endif 31764b22b933Srs extern void mDNSPlatformMemFree (void *mem); 31775ffb0c9bSToomas Soome 31785ffb0c9bSToomas Soome // If the platform doesn't have a strong PRNG, we define a naive multiply-and-add based on a seed 31795ffb0c9bSToomas Soome // from the platform layer. Long-term, we should embed an arc4 implementation, but the strength 31805ffb0c9bSToomas Soome // will still depend on the randomness of the seed. 31815ffb0c9bSToomas Soome #if !defined(_PLATFORM_HAS_STRONG_PRNG_) && (_BUILDING_XCODE_PROJECT_ || defined(_WIN32)) 31825ffb0c9bSToomas Soome #define _PLATFORM_HAS_STRONG_PRNG_ 1 31835ffb0c9bSToomas Soome #endif 31845ffb0c9bSToomas Soome #if _PLATFORM_HAS_STRONG_PRNG_ 31855ffb0c9bSToomas Soome extern mDNSu32 mDNSPlatformRandomNumber(void); 31865ffb0c9bSToomas Soome #else 31874b22b933Srs extern mDNSu32 mDNSPlatformRandomSeed (void); 31885ffb0c9bSToomas Soome #endif // _PLATFORM_HAS_STRONG_PRNG_ 31895ffb0c9bSToomas Soome 31904b22b933Srs extern mStatus mDNSPlatformTimeInit (void); 31914b22b933Srs extern mDNSs32 mDNSPlatformRawTime (void); 31924b22b933Srs extern mDNSs32 mDNSPlatformUTC (void); 31935ffb0c9bSToomas Soome #define mDNS_TimeNow_NoLock(m) (mDNSPlatformRawTime() + (m)->timenow_adjust) 31945ffb0c9bSToomas Soome 31955ffb0c9bSToomas Soome #if MDNS_DEBUGMSGS 31965ffb0c9bSToomas Soome extern void mDNSPlatformWriteDebugMsg(const char *msg); 31975ffb0c9bSToomas Soome #endif 31985ffb0c9bSToomas Soome extern void mDNSPlatformWriteLogMsg(const char *ident, const char *msg, mDNSLogLevel_t loglevel); 31995ffb0c9bSToomas Soome 32004b22b933Srs // Platform support modules should provide the following functions to map between opaque interface IDs 32014b22b933Srs // and interface indexes in order to support the DNS-SD API. If your target platform does not support 32024b22b933Srs // multiple interfaces and/or does not support the DNS-SD API, these functions can be empty. 32035ffb0c9bSToomas Soome extern mDNSInterfaceID mDNSPlatformInterfaceIDfromInterfaceIndex(mDNS *const m, mDNSu32 ifindex); 32045ffb0c9bSToomas Soome extern mDNSu32 mDNSPlatformInterfaceIndexfromInterfaceID(mDNS *const m, mDNSInterfaceID id, mDNSBool suppressNetworkChange); 32054b22b933Srs 32064b22b933Srs // Every platform support module must provide the following functions if it is to support unicast DNS 32074b22b933Srs // and Dynamic Update. 32084b22b933Srs // All TCP socket operations implemented by the platform layer MUST NOT BLOCK. 32094b22b933Srs // mDNSPlatformTCPConnect initiates a TCP connection with a peer, adding the socket descriptor to the 32104b22b933Srs // main event loop. The return value indicates whether the connection succeeded, failed, or is pending 32114b22b933Srs // (i.e. the call would block.) On return, the descriptor parameter is set to point to the connected socket. 32124b22b933Srs // The TCPConnectionCallback is subsequently invoked when the connection 32134b22b933Srs // completes (in which case the ConnectionEstablished parameter is true), or data is available for 32144b22b933Srs // reading on the socket (indicated by the ConnectionEstablished parameter being false.) If the connection 32154b22b933Srs // asynchronously fails, the TCPConnectionCallback should be invoked as usual, with the error being 32164b22b933Srs // returned in subsequent calls to PlatformReadTCP or PlatformWriteTCP. (This allows for platforms 32174b22b933Srs // with limited asynchronous error detection capabilities.) PlatformReadTCP and PlatformWriteTCP must 32185ffb0c9bSToomas Soome // return the number of bytes read/written, 0 if the call would block, and -1 if an error. PlatformReadTCP 32195ffb0c9bSToomas Soome // should set the closed argument if the socket has been closed. 32204b22b933Srs // PlatformTCPCloseConnection must close the connection to the peer and remove the descriptor from the 32214b22b933Srs // event loop. CloseConnectin may be called at any time, including in a ConnectionCallback. 32224b22b933Srs 32235ffb0c9bSToomas Soome typedef enum 32245ffb0c9bSToomas Soome { 32255ffb0c9bSToomas Soome kTCPSocketFlags_Zero = 0, 32265ffb0c9bSToomas Soome kTCPSocketFlags_UseTLS = (1 << 0) 32275ffb0c9bSToomas Soome } TCPSocketFlags; 32285ffb0c9bSToomas Soome 32295ffb0c9bSToomas Soome typedef void (*TCPConnectionCallback)(TCPSocket *sock, void *context, mDNSBool ConnectionEstablished, mStatus err); 3230c65ebfc7SToomas Soome extern TCPSocket *mDNSPlatformTCPSocket(TCPSocketFlags flags, mDNSIPPort *port, mDNSBool useBackgroundTrafficClass); // creates a TCP socket 32315ffb0c9bSToomas Soome extern TCPSocket *mDNSPlatformTCPAccept(TCPSocketFlags flags, int sd); 32325ffb0c9bSToomas Soome extern int mDNSPlatformTCPGetFD(TCPSocket *sock); 32335ffb0c9bSToomas Soome extern mStatus mDNSPlatformTCPConnect(TCPSocket *sock, const mDNSAddr *dst, mDNSOpaque16 dstport, domainname *hostname, 32345ffb0c9bSToomas Soome mDNSInterfaceID InterfaceID, TCPConnectionCallback callback, void *context); 32355ffb0c9bSToomas Soome extern void mDNSPlatformTCPCloseConnection(TCPSocket *sock); 32365ffb0c9bSToomas Soome extern long mDNSPlatformReadTCP(TCPSocket *sock, void *buf, unsigned long buflen, mDNSBool *closed); 32375ffb0c9bSToomas Soome extern long mDNSPlatformWriteTCP(TCPSocket *sock, const char *msg, unsigned long len); 3238c65ebfc7SToomas Soome extern UDPSocket *mDNSPlatformUDPSocket(const mDNSIPPort requestedport); 32395ffb0c9bSToomas Soome extern mDNSu16 mDNSPlatformGetUDPPort(UDPSocket *sock); 32405ffb0c9bSToomas Soome extern void mDNSPlatformUDPClose(UDPSocket *sock); 3241c65ebfc7SToomas Soome extern mDNSBool mDNSPlatformUDPSocketEncounteredEOF(const UDPSocket *sock); 3242c65ebfc7SToomas Soome extern void mDNSPlatformReceiveBPF_fd(int fd); 3243c65ebfc7SToomas Soome extern void mDNSPlatformUpdateProxyList(const mDNSInterfaceID InterfaceID); 32445ffb0c9bSToomas Soome extern void mDNSPlatformSendRawPacket(const void *const msg, const mDNSu8 *const end, mDNSInterfaceID InterfaceID); 3245c65ebfc7SToomas Soome extern void mDNSPlatformSetLocalAddressCacheEntry(const mDNSAddr *const tpa, const mDNSEthAddr *const tha, mDNSInterfaceID InterfaceID); 32465ffb0c9bSToomas Soome extern void mDNSPlatformSourceAddrForDest(mDNSAddr *const src, const mDNSAddr *const dst); 32475ffb0c9bSToomas Soome extern void mDNSPlatformSendKeepalive(mDNSAddr *sadd, mDNSAddr *dadd, mDNSIPPort *lport, mDNSIPPort *rport, mDNSu32 seq, mDNSu32 ack, mDNSu16 win); 3248c65ebfc7SToomas Soome extern mStatus mDNSPlatformRetrieveTCPInfo(mDNSAddr *laddr, mDNSIPPort *lport, mDNSAddr *raddr, mDNSIPPort *rport, mDNSTCPInfo *mti); 3249c65ebfc7SToomas Soome extern mStatus mDNSPlatformGetRemoteMacAddr(mDNSAddr *raddr); 32505ffb0c9bSToomas Soome extern mStatus mDNSPlatformStoreSPSMACAddr(mDNSAddr *spsaddr, char *ifname); 3251c65ebfc7SToomas Soome extern mStatus mDNSPlatformClearSPSData(void); 3252c65ebfc7SToomas Soome extern mStatus mDNSPlatformStoreOwnerOptRecord(char *ifname, DNSMessage *msg, int length); 32535ffb0c9bSToomas Soome 32545ffb0c9bSToomas Soome // mDNSPlatformTLSSetupCerts/mDNSPlatformTLSTearDownCerts used by dnsextd 32555ffb0c9bSToomas Soome extern mStatus mDNSPlatformTLSSetupCerts(void); 32565ffb0c9bSToomas Soome extern void mDNSPlatformTLSTearDownCerts(void); 32574b22b933Srs 32584b22b933Srs // Platforms that support unicast browsing and dynamic update registration for clients who do not specify a domain 32594b22b933Srs // in browse/registration calls must implement these routines to get the "default" browse/registration list. 32604b22b933Srs 3261c65ebfc7SToomas Soome extern mDNSBool mDNSPlatformSetDNSConfig(mDNSBool setservers, mDNSBool setsearch, domainname *const fqdn, DNameListElem **RegDomains, 32625ffb0c9bSToomas Soome DNameListElem **BrowseDomains, mDNSBool ackConfig); 3263c65ebfc7SToomas Soome extern mStatus mDNSPlatformGetPrimaryInterface(mDNSAddr *v4, mDNSAddr *v6, mDNSAddr *router); 32645ffb0c9bSToomas Soome extern void mDNSPlatformDynDNSHostNameStatusChanged(const domainname *const dname, const mStatus status); 32654b22b933Srs 3266c65ebfc7SToomas Soome extern void mDNSPlatformSetAllowSleep(mDNSBool allowSleep, const char *reason); 3267c65ebfc7SToomas Soome extern void mDNSPlatformPreventSleep(mDNSu32 timeout, const char *reason); 3268c65ebfc7SToomas Soome extern void mDNSPlatformSendWakeupPacket(mDNSInterfaceID InterfaceID, char *EthAddr, char *IPAddr, int iteration); 32694b22b933Srs 32705ffb0c9bSToomas Soome extern mDNSBool mDNSPlatformInterfaceIsD2D(mDNSInterfaceID InterfaceID); 32715ffb0c9bSToomas Soome extern mDNSBool mDNSPlatformInterfaceIsAWDL(const NetworkInterfaceInfo *intf); 32725ffb0c9bSToomas Soome extern mDNSBool mDNSPlatformValidRecordForQuestion(const ResourceRecord *const rr, const DNSQuestion *const q); 3273c65ebfc7SToomas Soome extern mDNSBool mDNSPlatformValidRecordForInterface(const AuthRecord *rr, mDNSInterfaceID InterfaceID); 32745ffb0c9bSToomas Soome extern mDNSBool mDNSPlatformValidQuestionForInterface(DNSQuestion *q, const NetworkInterfaceInfo *intf); 32755ffb0c9bSToomas Soome 32765ffb0c9bSToomas Soome extern void mDNSPlatformFormatTime(unsigned long t, mDNSu8 *buf, int bufsize); 32774b22b933Srs 32784b22b933Srs #ifdef _LEGACY_NAT_TRAVERSAL_ 32794b22b933Srs // Support for legacy NAT traversal protocols, implemented by the platform layer and callable by the core. 32805ffb0c9bSToomas Soome extern void LNT_SendDiscoveryMsg(mDNS *m); 32815ffb0c9bSToomas Soome extern void LNT_ConfigureRouterInfo(mDNS *m, const mDNSInterfaceID InterfaceID, const mDNSu8 *const data, const mDNSu16 len); 32825ffb0c9bSToomas Soome extern mStatus LNT_GetExternalAddress(mDNS *m); 32835ffb0c9bSToomas Soome extern mStatus LNT_MapPort(mDNS *m, NATTraversalInfo *const n); 32845ffb0c9bSToomas Soome extern mStatus LNT_UnmapPort(mDNS *m, NATTraversalInfo *const n); 32855ffb0c9bSToomas Soome extern void LNT_ClearState(mDNS *const m); 32864b22b933Srs #endif // _LEGACY_NAT_TRAVERSAL_ 32874b22b933Srs 32884b22b933Srs // The core mDNS code provides these functions, for the platform support code to call at appropriate times 32894b22b933Srs // 32904b22b933Srs // mDNS_SetFQDN() is called once on startup (typically from mDNSPlatformInit()) 32914b22b933Srs // and then again on each subsequent change of the host name. 32924b22b933Srs // 32934b22b933Srs // mDNS_RegisterInterface() is used by the platform support layer to inform mDNSCore of what 32944b22b933Srs // physical and/or logical interfaces are available for sending and receiving packets. 32954b22b933Srs // Typically it is called on startup for each available interface, but register/deregister may be 32964b22b933Srs // called again later, on multiple occasions, to inform the core of interface configuration changes. 32974b22b933Srs // If set->Advertise is set non-zero, then mDNS_RegisterInterface() also registers the standard 32984b22b933Srs // resource records that should be associated with every publicised IP address/interface: 32994b22b933Srs // -- Name-to-address records (A/AAAA) 33004b22b933Srs // -- Address-to-name records (PTR) 33014b22b933Srs // -- Host information (HINFO) 33024b22b933Srs // IMPORTANT: The specified mDNSInterfaceID MUST NOT be 0, -1, or -2; these values have special meaning 33034b22b933Srs // mDNS_RegisterInterface does not result in the registration of global hostnames via dynamic update - 33044b22b933Srs // see mDNS_SetPrimaryInterfaceInfo, mDNS_AddDynDNSHostName, etc. for this purpose. 33054b22b933Srs // Note that the set may be deallocated immediately after it is deregistered via mDNS_DeegisterInterface. 33064b22b933Srs // 33074b22b933Srs // mDNS_RegisterDNS() is used by the platform support layer to provide the core with the addresses of 33084b22b933Srs // available domain name servers for unicast queries/updates. RegisterDNS() should be called once for 33094b22b933Srs // each name server, typically at startup, or when a new name server becomes available. DeregiterDNS() 33104b22b933Srs // must be called whenever a registered name server becomes unavailable. DeregisterDNSList deregisters 33114b22b933Srs // all registered servers. mDNS_DNSRegistered() returns true if one or more servers are registered in the core. 33124b22b933Srs // 33134b22b933Srs // mDNSCoreInitComplete() is called when the platform support layer is finished. 33144b22b933Srs // Typically this is at the end of mDNSPlatformInit(), but may be later 33154b22b933Srs // (on platforms like OT that allow asynchronous initialization of the networking stack). 33164b22b933Srs // 33174b22b933Srs // mDNSCoreReceive() is called when a UDP packet is received 33184b22b933Srs // 33194b22b933Srs // mDNSCoreMachineSleep() is called when the machine sleeps or wakes 33204b22b933Srs // (This refers to heavyweight laptop-style sleep/wake that disables network access, 33214b22b933Srs // not lightweight second-by-second CPU power management modes.) 33224b22b933Srs 33234b22b933Srs extern void mDNS_SetFQDN(mDNS *const m); 33245ffb0c9bSToomas Soome extern void mDNS_ActivateNetWake_internal (mDNS *const m, NetworkInterfaceInfo *set); 33255ffb0c9bSToomas Soome extern void mDNS_DeactivateNetWake_internal(mDNS *const m, NetworkInterfaceInfo *set); 3326c65ebfc7SToomas Soome 3327c65ebfc7SToomas Soome // Attributes that controls the Bonjour operation initiation and response speed for an interface. 3328c65ebfc7SToomas Soome typedef enum 3329c65ebfc7SToomas Soome { 3330c65ebfc7SToomas Soome FastActivation, // For p2p* and DirectLink type interfaces 3331c65ebfc7SToomas Soome NormalActivation, // For standard interface timing 3332c65ebfc7SToomas Soome SlowActivation // For flapping interfaces 3333c65ebfc7SToomas Soome } InterfaceActivationSpeed; 3334c65ebfc7SToomas Soome 3335c65ebfc7SToomas Soome extern mStatus mDNS_RegisterInterface (mDNS *const m, NetworkInterfaceInfo *set, InterfaceActivationSpeed probeDelay); 3336c65ebfc7SToomas Soome extern void mDNS_DeregisterInterface(mDNS *const m, NetworkInterfaceInfo *set, InterfaceActivationSpeed probeDelay); 33374b22b933Srs extern void mDNSCoreInitComplete(mDNS *const m, mStatus result); 3338c65ebfc7SToomas Soome extern void mDNSCoreReceive(mDNS *const m, DNSMessage *const msg, const mDNSu8 *const end, 33395ffb0c9bSToomas Soome const mDNSAddr *const srcaddr, const mDNSIPPort srcport, 33405ffb0c9bSToomas Soome const mDNSAddr *dstaddr, const mDNSIPPort dstport, const mDNSInterfaceID InterfaceID); 33415ffb0c9bSToomas Soome extern void mDNSCoreRestartQueries(mDNS *const m); 33425ffb0c9bSToomas Soome extern void mDNSCoreRestartQuestion(mDNS *const m, DNSQuestion *q); 33435ffb0c9bSToomas Soome extern void mDNSCoreRestartRegistration(mDNS *const m, AuthRecord *rr, int announceCount); 33445ffb0c9bSToomas Soome typedef void (*FlushCache)(mDNS *const m); 33455ffb0c9bSToomas Soome typedef void (*CallbackBeforeStartQuery)(mDNS *const m, void *context); 33465ffb0c9bSToomas Soome extern void mDNSCoreRestartAddressQueries(mDNS *const m, mDNSBool SearchDomainsChanged, FlushCache flushCacheRecords, 33475ffb0c9bSToomas Soome CallbackBeforeStartQuery beforeQueryStart, void *context); 33485ffb0c9bSToomas Soome extern mDNSBool mDNSCoreHaveAdvertisedMulticastServices(mDNS *const m); 33494b22b933Srs extern void mDNSCoreMachineSleep(mDNS *const m, mDNSBool wake); 33505ffb0c9bSToomas Soome extern mDNSBool mDNSCoreReadyForSleep(mDNS *m, mDNSs32 now); 33515ffb0c9bSToomas Soome extern mDNSs32 mDNSCoreIntervalToNextWake(mDNS *const m, mDNSs32 now); 33525ffb0c9bSToomas Soome 33535ffb0c9bSToomas Soome extern void mDNSCoreReceiveRawPacket (mDNS *const m, const mDNSu8 *const p, const mDNSu8 *const end, const mDNSInterfaceID InterfaceID); 33544b22b933Srs 33554b22b933Srs extern mDNSBool mDNSAddrIsDNSMulticast(const mDNSAddr *ip); 33564b22b933Srs 33575ffb0c9bSToomas Soome extern CacheRecord *CreateNewCacheEntry(mDNS *const m, const mDNSu32 slot, CacheGroup *cg, mDNSs32 delay, mDNSBool Add, const mDNSAddr *sourceAddress); 3358c65ebfc7SToomas Soome extern CacheGroup *CacheGroupForName(const mDNS *const m, const mDNSu32 namehash, const domainname *const name); 33595ffb0c9bSToomas Soome extern void ReleaseCacheRecord(mDNS *const m, CacheRecord *r); 33605ffb0c9bSToomas Soome extern void ScheduleNextCacheCheckTime(mDNS *const m, const mDNSu32 slot, const mDNSs32 event); 33615ffb0c9bSToomas Soome extern void SetNextCacheCheckTimeForRecord(mDNS *const m, CacheRecord *const rr); 33625ffb0c9bSToomas Soome extern void GrantCacheExtensions(mDNS *const m, DNSQuestion *q, mDNSu32 lease); 33635ffb0c9bSToomas Soome extern void MakeNegativeCacheRecord(mDNS *const m, CacheRecord *const cr, 33645ffb0c9bSToomas Soome const domainname *const name, const mDNSu32 namehash, const mDNSu16 rrtype, const mDNSu16 rrclass, mDNSu32 ttl_seconds, 33655ffb0c9bSToomas Soome mDNSInterfaceID InterfaceID, DNSServer *dnsserver); 33665ffb0c9bSToomas Soome extern void CompleteDeregistration(mDNS *const m, AuthRecord *rr); 33675ffb0c9bSToomas Soome extern void AnswerCurrentQuestionWithResourceRecord(mDNS *const m, CacheRecord *const rr, const QC_result AddRecord); 33685ffb0c9bSToomas Soome extern void AnswerQuestionByFollowingCNAME(mDNS *const m, DNSQuestion *q, ResourceRecord *rr); 33695ffb0c9bSToomas Soome extern char *InterfaceNameForID(mDNS *const m, const mDNSInterfaceID InterfaceID); 33705ffb0c9bSToomas Soome extern void DNSServerChangeForQuestion(mDNS *const m, DNSQuestion *q, DNSServer *newServer); 33715ffb0c9bSToomas Soome extern void ActivateUnicastRegistration(mDNS *const m, AuthRecord *const rr); 33725ffb0c9bSToomas Soome extern void CheckSuppressUnusableQuestions(mDNS *const m); 33735ffb0c9bSToomas Soome extern void RetrySearchDomainQuestions(mDNS *const m); 33745ffb0c9bSToomas Soome extern mDNSBool DomainEnumQuery(const domainname *qname); 33755ffb0c9bSToomas Soome extern mStatus UpdateKeepaliveRData(mDNS *const m, AuthRecord *rr, NetworkInterfaceInfo *const intf, mDNSBool updateMac, char *ethAddr); 33765ffb0c9bSToomas Soome extern void UpdateKeepaliveRMACAsync(mDNS *const m, void *context); 3377c65ebfc7SToomas Soome extern void UpdateRMAC(mDNS *const m, void *context); 33785ffb0c9bSToomas Soome 33795ffb0c9bSToomas Soome // Used only in logging to restrict the number of /etc/hosts entries printed 33805ffb0c9bSToomas Soome extern void FreeEtcHosts(mDNS *const m, AuthRecord *const rr, mStatus result); 33815ffb0c9bSToomas Soome // exported for using the hash for /etc/hosts AuthRecords 3382c65ebfc7SToomas Soome extern AuthGroup *AuthGroupForName(AuthHash *r, const mDNSu32 namehash, const domainname *const name); 3383c65ebfc7SToomas Soome extern AuthGroup *AuthGroupForRecord(AuthHash *r, const ResourceRecord *const rr); 33845ffb0c9bSToomas Soome extern AuthGroup *InsertAuthRecord(mDNS *const m, AuthHash *r, AuthRecord *rr); 33855ffb0c9bSToomas Soome extern AuthGroup *RemoveAuthRecord(mDNS *const m, AuthHash *r, AuthRecord *rr); 33865ffb0c9bSToomas Soome extern mDNSBool mDNS_CheckForCacheRecord(mDNS *const m, DNSQuestion *q, mDNSu16 qtype); 33875ffb0c9bSToomas Soome 33885ffb0c9bSToomas Soome // For now this AutoTunnel stuff is specific to Mac OS X. 33895ffb0c9bSToomas Soome // In the future, if there's demand, we may see if we can abstract it out cleanly into the platform layer 33905ffb0c9bSToomas Soome #if APPLE_OSX_mDNSResponder 33915ffb0c9bSToomas Soome extern void AutoTunnelCallback(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord); 3392c65ebfc7SToomas Soome extern void AddNewClientTunnel(DNSQuestion *const q); 3393c65ebfc7SToomas Soome extern void StartServerTunnel(DomainAuthInfo *const info); 33945ffb0c9bSToomas Soome extern void UpdateAutoTunnelDomainStatuses(const mDNS *const m); 33955ffb0c9bSToomas Soome extern void RemoveAutoTunnel6Record(mDNS *const m); 3396c65ebfc7SToomas Soome extern mDNSBool RecordReadyForSleep(AuthRecord *rr); 33975ffb0c9bSToomas Soome // For now this LocalSleepProxy stuff is specific to Mac OS X. 33985ffb0c9bSToomas Soome // In the future, if there's demand, we may see if we can abstract it out cleanly into the platform layer 3399*3b436d06SToomas Soome extern mStatus ActivateLocalProxy(NetworkInterfaceInfo *const intf, mDNSBool offloadKeepAlivesOnly, mDNSBool *keepaliveOnly); 3400c65ebfc7SToomas Soome extern void mDNSPlatformUpdateDNSStatus(DNSQuestion *q); 3401c65ebfc7SToomas Soome extern void mDNSPlatformTriggerDNSRetry(DNSQuestion *v4q, DNSQuestion *v6q); 34025ffb0c9bSToomas Soome extern void mDNSPlatformLogToFile(int log_level, const char *buffer); 34035ffb0c9bSToomas Soome extern mDNSBool SupportsInNICProxy(NetworkInterfaceInfo *const intf); 3404cda73f64SToomas Soome extern mStatus SymptomReporterDNSServerReachable(mDNS *const m, const mDNSAddr *addr); 3405cda73f64SToomas Soome extern mStatus SymptomReporterDNSServerUnreachable(DNSServer *s); 34065ffb0c9bSToomas Soome #endif 34075ffb0c9bSToomas Soome 3408c65ebfc7SToomas Soome typedef void ProxyCallback (void *socket, DNSMessage *const msg, const mDNSu8 *const end, const mDNSAddr *const srcaddr, 34095ffb0c9bSToomas Soome const mDNSIPPort srcport, const mDNSAddr *dstaddr, const mDNSIPPort dstport, const mDNSInterfaceID InterfaceID, void *context); 3410c65ebfc7SToomas Soome extern void mDNSPlatformInitDNSProxySkts(ProxyCallback *UDPCallback, ProxyCallback *TCPCallback); 34115ffb0c9bSToomas Soome extern void mDNSPlatformCloseDNSProxySkts(mDNS *const m); 34125ffb0c9bSToomas Soome extern void mDNSPlatformDisposeProxyContext(void *context); 34135ffb0c9bSToomas Soome extern mDNSu8 *DNSProxySetAttributes(DNSQuestion *q, DNSMessageHeader *h, DNSMessage *msg, mDNSu8 *start, mDNSu8 *limit); 34145ffb0c9bSToomas Soome 34155ffb0c9bSToomas Soome #if APPLE_OSX_mDNSResponder 3416c65ebfc7SToomas Soome extern void mDNSPlatformGetDNSRoutePolicy(DNSQuestion *q, mDNSBool *isBlocked); 34175ffb0c9bSToomas Soome #endif 3418c65ebfc7SToomas Soome extern void mDNSPlatformSetSocktOpt(void *sock, mDNSTransport_Type transType, mDNSAddr_Type addrType, const DNSQuestion *q); 34195ffb0c9bSToomas Soome extern mDNSs32 mDNSPlatformGetPID(void); 3420cda73f64SToomas Soome extern mDNSBool mDNSValidKeepAliveRecord(AuthRecord *rr); 3421c65ebfc7SToomas Soome extern mDNSBool CacheRecordRmvEventsForQuestion(mDNS *const m, DNSQuestion *q); 34225ffb0c9bSToomas Soome 34235ffb0c9bSToomas Soome // *************************************************************************** 34245ffb0c9bSToomas Soome #if 0 34255ffb0c9bSToomas Soome #pragma mark - 34265ffb0c9bSToomas Soome #pragma mark - Sleep Proxy 34275ffb0c9bSToomas Soome #endif 34285ffb0c9bSToomas Soome 34295ffb0c9bSToomas Soome // Sleep Proxy Server Property Encoding 34305ffb0c9bSToomas Soome // 34315ffb0c9bSToomas Soome // Sleep Proxy Servers are advertised using a structured service name, consisting of four 34325ffb0c9bSToomas Soome // metrics followed by a human-readable name. The metrics assist clients in deciding which 34335ffb0c9bSToomas Soome // Sleep Proxy Server(s) to use when multiple are available on the network. Each metric 34345ffb0c9bSToomas Soome // is a two-digit decimal number in the range 10-99. Lower metrics are generally better. 34355ffb0c9bSToomas Soome // 34365ffb0c9bSToomas Soome // AA-BB-CC-DD.FF Name 34375ffb0c9bSToomas Soome // 34385ffb0c9bSToomas Soome // Metrics: 34395ffb0c9bSToomas Soome // 34405ffb0c9bSToomas Soome // AA = Intent 34415ffb0c9bSToomas Soome // BB = Portability 34425ffb0c9bSToomas Soome // CC = Marginal Power 34435ffb0c9bSToomas Soome // DD = Total Power 34445ffb0c9bSToomas Soome // FF = Features Supported (Currently TCP Keepalive only) 34455ffb0c9bSToomas Soome // 34465ffb0c9bSToomas Soome // 34475ffb0c9bSToomas Soome // ** Intent Metric ** 34485ffb0c9bSToomas Soome // 34495ffb0c9bSToomas Soome // 20 = Dedicated Sleep Proxy Server -- a device, permanently powered on, 34505ffb0c9bSToomas Soome // installed for the express purpose of providing Sleep Proxy Service. 34515ffb0c9bSToomas Soome // 34525ffb0c9bSToomas Soome // 30 = Primary Network Infrastructure Hardware -- a router, DHCP server, NAT gateway, 34535ffb0c9bSToomas Soome // or similar permanently installed device which is permanently powered on. 34545ffb0c9bSToomas Soome // This is hardware designed for the express purpose of being network 34555ffb0c9bSToomas Soome // infrastructure, and for most home users is typically a single point 34565ffb0c9bSToomas Soome // of failure for the local network -- e.g. most home users only have 34575ffb0c9bSToomas Soome // a single NAT gateway / DHCP server. Even though in principle the 34585ffb0c9bSToomas Soome // hardware might technically be capable of running different software, 34595ffb0c9bSToomas Soome // a typical user is unlikely to do that. e.g. AirPort base station. 34605ffb0c9bSToomas Soome // 34615ffb0c9bSToomas Soome // 40 = Primary Network Infrastructure Software -- a general-purpose computer 34625ffb0c9bSToomas Soome // (e.g. Mac, Windows, Linux, etc.) which is currently running DHCP server 34635ffb0c9bSToomas Soome // or NAT gateway software, but the user could choose to turn that off 34645ffb0c9bSToomas Soome // fairly easily. e.g. iMac running Internet Sharing 34655ffb0c9bSToomas Soome // 34665ffb0c9bSToomas Soome // 50 = Secondary Network Infrastructure Hardware -- like primary infrastructure 34675ffb0c9bSToomas Soome // hardware, except not a single point of failure for the entire local network. 34685ffb0c9bSToomas Soome // For example, an AirPort base station in bridge mode. This may have clients 34695ffb0c9bSToomas Soome // associated with it, and if it goes away those clients will be inconvenienced, 34705ffb0c9bSToomas Soome // but unlike the NAT gateway / DHCP server, the entire local network is not 34715ffb0c9bSToomas Soome // dependent on it. 34725ffb0c9bSToomas Soome // 34735ffb0c9bSToomas Soome // 60 = Secondary Network Infrastructure Software -- like 50, but in a general- 34745ffb0c9bSToomas Soome // purpose CPU. 34755ffb0c9bSToomas Soome // 34765ffb0c9bSToomas Soome // 70 = Incidentally Available Hardware -- a device which has no power switch 34775ffb0c9bSToomas Soome // and is generally left powered on all the time. Even though it is not a 34785ffb0c9bSToomas Soome // part of what we conventionally consider network infrastructure (router, 34795ffb0c9bSToomas Soome // DHCP, NAT, DNS, etc.), and the rest of the network can operate fine 34805ffb0c9bSToomas Soome // without it, since it's available and unlikely to be turned off, it is a 34815ffb0c9bSToomas Soome // reasonable candidate for providing Sleep Proxy Service e.g. Apple TV, 34825ffb0c9bSToomas Soome // or an AirPort base station in client mode, associated with an existing 34835ffb0c9bSToomas Soome // wireless network (e.g. AirPort Express connected to a music system, or 34845ffb0c9bSToomas Soome // being used to share a USB printer). 34855ffb0c9bSToomas Soome // 34865ffb0c9bSToomas Soome // 80 = Incidentally Available Software -- a general-purpose computer which 34875ffb0c9bSToomas Soome // happens at this time to be set to "never sleep", and as such could be 34885ffb0c9bSToomas Soome // useful as a Sleep Proxy Server, but has not been intentionally provided 34895ffb0c9bSToomas Soome // for this purpose. Of all the Intent Metric categories this is the 34905ffb0c9bSToomas Soome // one most likely to be shut down or put to sleep without warning. 34915ffb0c9bSToomas Soome // However, if nothing else is availalable, it may be better than nothing. 34925ffb0c9bSToomas Soome // e.g. Office computer in the workplace which has been set to "never sleep" 34935ffb0c9bSToomas Soome // 34945ffb0c9bSToomas Soome // 34955ffb0c9bSToomas Soome // ** Portability Metric ** 34965ffb0c9bSToomas Soome // 34975ffb0c9bSToomas Soome // Inversely related to mass of device, on the basis that, all other things 34985ffb0c9bSToomas Soome // being equal, heavier devices are less likely to be moved than lighter devices. 34995ffb0c9bSToomas Soome // E.g. A MacBook running Internet Sharing is probably more likely to be 35005ffb0c9bSToomas Soome // put to sleep and taken away than a Mac Pro running Internet Sharing. 35015ffb0c9bSToomas Soome // The Portability Metric is a logarithmic decibel scale, computed by taking the 35025ffb0c9bSToomas Soome // (approximate) mass of the device in milligrammes, taking the base 10 logarithm 35035ffb0c9bSToomas Soome // of that, multiplying by 10, and subtracting the result from 100: 35045ffb0c9bSToomas Soome // 35055ffb0c9bSToomas Soome // Portability Metric = 100 - (log10(mg) * 10) 35065ffb0c9bSToomas Soome // 35075ffb0c9bSToomas Soome // The Portability Metric is not necessarily computed literally from the actual 35085ffb0c9bSToomas Soome // mass of the device; the intent is just that lower numbers indicate more 35095ffb0c9bSToomas Soome // permanent devices, and higher numbers indicate devices more likely to be 35105ffb0c9bSToomas Soome // removed from the network, e.g., in order of increasing portability: 35115ffb0c9bSToomas Soome // 35125ffb0c9bSToomas Soome // Mac Pro < iMac < Laptop < iPhone 35135ffb0c9bSToomas Soome // 35145ffb0c9bSToomas Soome // Example values: 35155ffb0c9bSToomas Soome // 35165ffb0c9bSToomas Soome // 10 = 1 metric tonne 35175ffb0c9bSToomas Soome // 40 = 1kg 35185ffb0c9bSToomas Soome // 70 = 1g 35195ffb0c9bSToomas Soome // 90 = 10mg 35205ffb0c9bSToomas Soome // 35215ffb0c9bSToomas Soome // 35225ffb0c9bSToomas Soome // ** Marginal Power and Total Power Metrics ** 35235ffb0c9bSToomas Soome // 35245ffb0c9bSToomas Soome // The Marginal Power Metric is the power difference between sleeping and staying awake 35255ffb0c9bSToomas Soome // to be a Sleep Proxy Server. 35265ffb0c9bSToomas Soome // 35275ffb0c9bSToomas Soome // The Total Power Metric is the total power consumption when being Sleep Proxy Server. 35285ffb0c9bSToomas Soome // 35295ffb0c9bSToomas Soome // The Power Metrics use a logarithmic decibel scale, computed as ten times the 35305ffb0c9bSToomas Soome // base 10 logarithm of the (approximate) power in microwatts: 35315ffb0c9bSToomas Soome // 35325ffb0c9bSToomas Soome // Power Metric = log10(uW) * 10 35335ffb0c9bSToomas Soome // 35345ffb0c9bSToomas Soome // Higher values indicate higher power consumption. Example values: 35355ffb0c9bSToomas Soome // 35365ffb0c9bSToomas Soome // 10 = 10 uW 35375ffb0c9bSToomas Soome // 20 = 100 uW 35385ffb0c9bSToomas Soome // 30 = 1 mW 35395ffb0c9bSToomas Soome // 60 = 1 W 35405ffb0c9bSToomas Soome // 90 = 1 kW 35415ffb0c9bSToomas Soome 35425ffb0c9bSToomas Soome typedef enum 35435ffb0c9bSToomas Soome { 35445ffb0c9bSToomas Soome mDNSSleepProxyMetric_Dedicated = 20, 35455ffb0c9bSToomas Soome mDNSSleepProxyMetric_PrimaryHardware = 30, 35465ffb0c9bSToomas Soome mDNSSleepProxyMetric_PrimarySoftware = 40, 35475ffb0c9bSToomas Soome mDNSSleepProxyMetric_SecondaryHardware = 50, 35485ffb0c9bSToomas Soome mDNSSleepProxyMetric_SecondarySoftware = 60, 35495ffb0c9bSToomas Soome mDNSSleepProxyMetric_IncidentalHardware = 70, 35505ffb0c9bSToomas Soome mDNSSleepProxyMetric_IncidentalSoftware = 80 35515ffb0c9bSToomas Soome } mDNSSleepProxyMetric; 35525ffb0c9bSToomas Soome 35535ffb0c9bSToomas Soome typedef enum 35545ffb0c9bSToomas Soome { 35555ffb0c9bSToomas Soome mDNS_NoWake = 0, // System does not support Wake on LAN 35565ffb0c9bSToomas Soome mDNS_WakeOnAC = 1, // System supports Wake on LAN when connected to AC power only 35575ffb0c9bSToomas Soome mDNS_WakeOnBattery = 2 // System supports Wake on LAN on battery 35585ffb0c9bSToomas Soome } mDNSWakeForNetworkAccess; 35595ffb0c9bSToomas Soome 35605ffb0c9bSToomas Soome extern void mDNSCoreBeSleepProxyServer_internal(mDNS *const m, mDNSu8 sps, mDNSu8 port, mDNSu8 marginalpower, mDNSu8 totpower, mDNSu8 features); 35615ffb0c9bSToomas Soome #define mDNSCoreBeSleepProxyServer(M,S,P,MP,TP,F) \ 35625ffb0c9bSToomas Soome do { mDNS_Lock(m); mDNSCoreBeSleepProxyServer_internal((M),(S),(P),(MP),(TP),(F)); mDNS_Unlock(m); } while(0) 35635ffb0c9bSToomas Soome 35645ffb0c9bSToomas Soome extern void FindSPSInCache(mDNS *const m, const DNSQuestion *const q, const CacheRecord *sps[3]); 35655ffb0c9bSToomas Soome #define PrototypeSPSName(X) ((X)[0] >= 11 && (X)[3] == '-' && (X)[ 4] == '9' && (X)[ 5] == '9' && \ 35665ffb0c9bSToomas Soome (X)[6] == '-' && (X)[ 7] == '9' && (X)[ 8] == '9' && \ 35675ffb0c9bSToomas Soome (X)[9] == '-' && (X)[10] == '9' && (X)[11] == '9' ) 35685ffb0c9bSToomas Soome #define ValidSPSName(X) ((X)[0] >= 5 && mDNSIsDigit((X)[1]) && mDNSIsDigit((X)[2]) && mDNSIsDigit((X)[4]) && mDNSIsDigit((X)[5])) 35695ffb0c9bSToomas Soome #define SPSMetric(X) (!ValidSPSName(X) || PrototypeSPSName(X) ? 1000000 : \ 35705ffb0c9bSToomas Soome ((X)[1]-'0') * 100000 + ((X)[2]-'0') * 10000 + ((X)[4]-'0') * 1000 + ((X)[5]-'0') * 100 + ((X)[7]-'0') * 10 + ((X)[8]-'0')) 35715ffb0c9bSToomas Soome #define LocalSPSMetric(X) ( (X)->SPSType * 10000 + (X)->SPSPortability * 100 + (X)->SPSMarginalPower) 35725ffb0c9bSToomas Soome #define SPSFeatures(X) ((X)[0] >= 13 && (X)[12] =='.' ? ((X)[13]-'0') : 0 ) 35735ffb0c9bSToomas Soome 35745ffb0c9bSToomas Soome #define MD5_DIGEST_LENGTH 16 /* digest length in bytes */ 35755ffb0c9bSToomas Soome #define MD5_BLOCK_BYTES 64 /* block size in bytes */ 35765ffb0c9bSToomas Soome #define MD5_BLOCK_LONG (MD5_BLOCK_BYTES / sizeof(mDNSu32)) 35775ffb0c9bSToomas Soome 35785ffb0c9bSToomas Soome typedef struct MD5state_st 35795ffb0c9bSToomas Soome { 35805ffb0c9bSToomas Soome mDNSu32 A,B,C,D; 35815ffb0c9bSToomas Soome mDNSu32 Nl,Nh; 35825ffb0c9bSToomas Soome mDNSu32 data[MD5_BLOCK_LONG]; 35835ffb0c9bSToomas Soome int num; 35845ffb0c9bSToomas Soome } MD5_CTX; 35855ffb0c9bSToomas Soome 35865ffb0c9bSToomas Soome extern int MD5_Init(MD5_CTX *c); 35875ffb0c9bSToomas Soome extern int MD5_Update(MD5_CTX *c, const void *data, unsigned long len); 35885ffb0c9bSToomas Soome extern int MD5_Final(unsigned char *md, MD5_CTX *c); 35895ffb0c9bSToomas Soome 35904b22b933Srs // *************************************************************************** 35914b22b933Srs #if 0 35925ffb0c9bSToomas Soome #pragma mark - 35934b22b933Srs #pragma mark - Compile-Time assertion checks 35944b22b933Srs #endif 35954b22b933Srs 35964b22b933Srs // Some C compiler cleverness. We can make the compiler check certain things for 35974b22b933Srs // us, and report compile-time errors if anything is wrong. The usual way to do 35984b22b933Srs // this would be to use a run-time "if" statement, but then you don't find out 35994b22b933Srs // what's wrong until you run the software. This way, if the assertion condition 36004b22b933Srs // is false, the array size is negative, and the complier complains immediately. 36014b22b933Srs 36025ffb0c9bSToomas Soome struct CompileTimeAssertionChecks_mDNS 36035ffb0c9bSToomas Soome { 36045ffb0c9bSToomas Soome // Check that the compiler generated our on-the-wire packet format structure definitions 36055ffb0c9bSToomas Soome // properly packed, without adding padding bytes to align fields on 32-bit or 64-bit boundaries. 36065ffb0c9bSToomas Soome char assert0[(sizeof(rdataSRV) == 262 ) ? 1 : -1]; 36075ffb0c9bSToomas Soome char assert1[(sizeof(DNSMessageHeader) == 12 ) ? 1 : -1]; 36085ffb0c9bSToomas Soome char assert2[(sizeof(DNSMessage) == 12+AbsoluteMaxDNSMessageData) ? 1 : -1]; 36095ffb0c9bSToomas Soome char assert3[(sizeof(mDNSs8) == 1 ) ? 1 : -1]; 36105ffb0c9bSToomas Soome char assert4[(sizeof(mDNSu8) == 1 ) ? 1 : -1]; 36115ffb0c9bSToomas Soome char assert5[(sizeof(mDNSs16) == 2 ) ? 1 : -1]; 36125ffb0c9bSToomas Soome char assert6[(sizeof(mDNSu16) == 2 ) ? 1 : -1]; 36135ffb0c9bSToomas Soome char assert7[(sizeof(mDNSs32) == 4 ) ? 1 : -1]; 36145ffb0c9bSToomas Soome char assert8[(sizeof(mDNSu32) == 4 ) ? 1 : -1]; 36155ffb0c9bSToomas Soome char assert9[(sizeof(mDNSOpaque16) == 2 ) ? 1 : -1]; 36165ffb0c9bSToomas Soome char assertA[(sizeof(mDNSOpaque32) == 4 ) ? 1 : -1]; 36175ffb0c9bSToomas Soome char assertB[(sizeof(mDNSOpaque128) == 16 ) ? 1 : -1]; 36185ffb0c9bSToomas Soome char assertC[(sizeof(CacheRecord ) == sizeof(CacheGroup) ) ? 1 : -1]; 36195ffb0c9bSToomas Soome char assertD[(sizeof(int) >= 4 ) ? 1 : -1]; 36205ffb0c9bSToomas Soome char assertE[(StandardAuthRDSize >= 256 ) ? 1 : -1]; 36215ffb0c9bSToomas Soome char assertF[(sizeof(EthernetHeader) == 14 ) ? 1 : -1]; 36225ffb0c9bSToomas Soome char assertG[(sizeof(ARP_EthIP ) == 28 ) ? 1 : -1]; 36235ffb0c9bSToomas Soome char assertH[(sizeof(IPv4Header ) == 20 ) ? 1 : -1]; 36245ffb0c9bSToomas Soome char assertI[(sizeof(IPv6Header ) == 40 ) ? 1 : -1]; 36255ffb0c9bSToomas Soome char assertJ[(sizeof(IPv6NDP ) == 24 ) ? 1 : -1]; 36265ffb0c9bSToomas Soome char assertK[(sizeof(UDPHeader ) == 8 ) ? 1 : -1]; 36275ffb0c9bSToomas Soome char assertL[(sizeof(IKEHeader ) == 28 ) ? 1 : -1]; 36285ffb0c9bSToomas Soome char assertM[(sizeof(TCPHeader ) == 20 ) ? 1 : -1]; 3629c65ebfc7SToomas Soome char assertN[(sizeof(rdataOPT) == 24 ) ? 1 : -1]; 3630c65ebfc7SToomas Soome char assertO[(sizeof(rdataRRSig) == 20 ) ? 1 : -1]; 3631c65ebfc7SToomas Soome char assertP[(sizeof(PCPMapRequest) == 60 ) ? 1 : -1]; 3632c65ebfc7SToomas Soome char assertQ[(sizeof(PCPMapReply) == 60 ) ? 1 : -1]; 3633c65ebfc7SToomas Soome 36345ffb0c9bSToomas Soome 36355ffb0c9bSToomas Soome // Check our structures are reasonable sizes. Including overly-large buffers, or embedding 36365ffb0c9bSToomas Soome // other overly-large structures instead of having a pointer to them, can inadvertently 36375ffb0c9bSToomas Soome // cause structure sizes (and therefore memory usage) to balloon unreasonably. 36385ffb0c9bSToomas Soome char sizecheck_RDataBody [(sizeof(RDataBody) == 264) ? 1 : -1]; 36395ffb0c9bSToomas Soome char sizecheck_ResourceRecord [(sizeof(ResourceRecord) <= 72) ? 1 : -1]; 36405ffb0c9bSToomas Soome char sizecheck_AuthRecord [(sizeof(AuthRecord) <= 1208) ? 1 : -1]; 36415ffb0c9bSToomas Soome char sizecheck_CacheRecord [(sizeof(CacheRecord) <= 232) ? 1 : -1]; 36425ffb0c9bSToomas Soome char sizecheck_CacheGroup [(sizeof(CacheGroup) <= 232) ? 1 : -1]; 3643*3b436d06SToomas Soome char sizecheck_DNSQuestion [(sizeof(DNSQuestion) <= 1168) ? 1 : -1]; 36445ffb0c9bSToomas Soome 3645*3b436d06SToomas Soome char sizecheck_ZoneData [(sizeof(ZoneData) <= 2000) ? 1 : -1]; 36465ffb0c9bSToomas Soome char sizecheck_NATTraversalInfo [(sizeof(NATTraversalInfo) <= 200) ? 1 : -1]; 36475ffb0c9bSToomas Soome char sizecheck_HostnameInfo [(sizeof(HostnameInfo) <= 3050) ? 1 : -1]; 3648c65ebfc7SToomas Soome char sizecheck_DNSServer [(sizeof(DNSServer) <= 330) ? 1 : -1]; 3649*3b436d06SToomas Soome char sizecheck_NetworkInterfaceInfo[(sizeof(NetworkInterfaceInfo) <= 8400) ? 1 : -1]; 36505ffb0c9bSToomas Soome char sizecheck_ServiceRecordSet [(sizeof(ServiceRecordSet) <= 5540) ? 1 : -1]; 36515ffb0c9bSToomas Soome char sizecheck_DomainAuthInfo [(sizeof(DomainAuthInfo) <= 7888) ? 1 : -1]; 36525ffb0c9bSToomas Soome #if APPLE_OSX_mDNSResponder 3653*3b436d06SToomas Soome char sizecheck_ClientTunnel [(sizeof(ClientTunnel) <= 1512) ? 1 : -1]; 36545ffb0c9bSToomas Soome #endif 36555ffb0c9bSToomas Soome }; 36565ffb0c9bSToomas Soome 36575ffb0c9bSToomas Soome // Routine to initialize device-info TXT record contents 36585ffb0c9bSToomas Soome mDNSu32 initializeDeviceInfoTXT(mDNS *m, mDNSu8 *ptr); 36595ffb0c9bSToomas Soome 36605ffb0c9bSToomas Soome #if APPLE_OSX_mDNSResponder 36615ffb0c9bSToomas Soome extern void D2D_start_advertising_interface(NetworkInterfaceInfo *interface); 36625ffb0c9bSToomas Soome extern void D2D_stop_advertising_interface(NetworkInterfaceInfo *interface); 3663c65ebfc7SToomas Soome extern void D2D_start_advertising_record(AuthRecord *ar); 3664c65ebfc7SToomas Soome extern void D2D_stop_advertising_record(AuthRecord *ar); 3665c65ebfc7SToomas Soome #else 3666c65ebfc7SToomas Soome #define D2D_start_advertising_interface(X) 3667c65ebfc7SToomas Soome #define D2D_stop_advertising_interface(X) 3668c65ebfc7SToomas Soome #define D2D_start_advertising_record(X) 3669c65ebfc7SToomas Soome #define D2D_stop_advertising_record(X) 36705ffb0c9bSToomas Soome #endif 36714b22b933Srs 36724b22b933Srs // *************************************************************************** 36734b22b933Srs 36744b22b933Srs #ifdef __cplusplus 36755ffb0c9bSToomas Soome } 36764b22b933Srs #endif 36774b22b933Srs 36784b22b933Srs #endif 3679