xref: /illumos-gate/usr/src/contrib/mDNSResponder/mDNSCore/mDNSEmbeddedAPI.h (revision c65ebfc7045424bd04a6c7719a27b0ad3399ad54)
14b22b933Srs /* -*- Mode: C; tab-width: 4 -*-
24b22b933Srs  *
3cda73f64SToomas Soome  * Copyright (c) 2002-2015 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
99*c65ebfc7SToomas 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)
101*c65ebfc7SToomas Soome #define MaximumRDSize               264
1024b22b933Srs #endif
1034b22b933Srs 
1044b22b933Srs // ***************************************************************************
1054b22b933Srs // Function scope indicators
1064b22b933Srs 
1074b22b933Srs // If you see "mDNSlocal" before a function name in a C file, it means the function is not callable outside this file
1084b22b933Srs #ifndef mDNSlocal
1094b22b933Srs #define mDNSlocal static
1104b22b933Srs #endif
1114b22b933Srs // If you see "mDNSexport" before a symbol in a C file, it means the symbol is exported for use by clients
1124b22b933Srs // For every "mDNSexport" in a C file, there needs to be a corresponding "extern" declaration in some header file
1134b22b933Srs // (When a C file #includes a header file, the "extern" declarations tell the compiler:
1144b22b933Srs // "This symbol exists -- but not necessarily in this C file.")
1154b22b933Srs #ifndef mDNSexport
1164b22b933Srs #define mDNSexport
1174b22b933Srs #endif
1184b22b933Srs 
1194b22b933Srs // Explanation: These local/export markers are a little habit of mine for signaling the programmers' intentions.
1204b22b933Srs // When "mDNSlocal" is just a synonym for "static", and "mDNSexport" is a complete no-op, you could be
1214b22b933Srs // forgiven for asking what purpose they serve. The idea is that if you see "mDNSexport" in front of a
1224b22b933Srs // function definition it means the programmer intended it to be exported and callable from other files
1234b22b933Srs // in the project. If you see "mDNSlocal" in front of a function definition it means the programmer
1244b22b933Srs // intended it to be private to that file. If you see neither in front of a function definition it
1254b22b933Srs // means the programmer forgot (so you should work out which it is supposed to be, and fix it).
1264b22b933Srs // Using "mDNSlocal" instead of "static" makes it easier to do a textual searches for one or the other.
1274b22b933Srs // For example you can do a search for "static" to find if any functions declare any local variables as "static"
1284b22b933Srs // (generally a bad idea unless it's also "const", because static storage usually risks being non-thread-safe)
1294b22b933Srs // without the results being cluttered with hundreds of matches for functions declared static.
1304b22b933Srs // - Stuart Cheshire
1314b22b933Srs 
1324b22b933Srs // ***************************************************************************
1334b22b933Srs // Structure packing macro
1344b22b933Srs 
1354b22b933Srs // If we're not using GNUC, it's not fatal.
1364b22b933Srs // Most compilers naturally pack the on-the-wire structures correctly anyway, so a plain "struct" is usually fine.
1374b22b933Srs // In the event that structures are not packed correctly, mDNS_Init() will detect this and report an error, so the
1384b22b933Srs // developer will know what's wrong, and can investigate what needs to be done on that compiler to provide proper packing.
1394b22b933Srs #ifndef packedstruct
1404b22b933Srs  #if ((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 9)))
1414b22b933Srs   #define packedstruct struct __attribute__((__packed__))
1424b22b933Srs   #define packedunion  union  __attribute__((__packed__))
1434b22b933Srs  #else
1444b22b933Srs   #define packedstruct struct
1454b22b933Srs   #define packedunion  union
1464b22b933Srs  #endif
1474b22b933Srs #endif
1484b22b933Srs 
1494b22b933Srs // ***************************************************************************
1504b22b933Srs #if 0
1514b22b933Srs #pragma mark - DNS Resource Record class and type constants
1524b22b933Srs #endif
1534b22b933Srs 
1545ffb0c9bSToomas Soome typedef enum                            // From RFC 1035
1555ffb0c9bSToomas Soome {
1565ffb0c9bSToomas Soome     kDNSClass_IN               = 1,     // Internet
1575ffb0c9bSToomas Soome     kDNSClass_CS               = 2,     // CSNET
1585ffb0c9bSToomas Soome     kDNSClass_CH               = 3,     // CHAOS
1595ffb0c9bSToomas Soome     kDNSClass_HS               = 4,     // Hesiod
1605ffb0c9bSToomas Soome     kDNSClass_NONE             = 254,   // Used in DNS UPDATE [RFC 2136]
1615ffb0c9bSToomas Soome 
1625ffb0c9bSToomas Soome     kDNSClass_Mask             = 0x7FFF, // Multicast DNS uses the bottom 15 bits to identify the record class...
1635ffb0c9bSToomas Soome     kDNSClass_UniqueRRSet      = 0x8000, // ... and the top bit indicates that all other cached records are now invalid
1645ffb0c9bSToomas Soome 
1655ffb0c9bSToomas Soome     kDNSQClass_ANY             = 255,   // Not a DNS class, but a DNS query class, meaning "all classes"
1665ffb0c9bSToomas Soome     kDNSQClass_UnicastResponse = 0x8000 // Top bit set in a question means "unicast response acceptable"
1675ffb0c9bSToomas Soome } DNS_ClassValues;
1685ffb0c9bSToomas Soome 
1695ffb0c9bSToomas Soome typedef enum                // From RFC 1035
1705ffb0c9bSToomas Soome {
1715ffb0c9bSToomas Soome     kDNSType_A = 1,         //  1 Address
1725ffb0c9bSToomas Soome     kDNSType_NS,            //  2 Name Server
1735ffb0c9bSToomas Soome     kDNSType_MD,            //  3 Mail Destination
1745ffb0c9bSToomas Soome     kDNSType_MF,            //  4 Mail Forwarder
1755ffb0c9bSToomas Soome     kDNSType_CNAME,         //  5 Canonical Name
1765ffb0c9bSToomas Soome     kDNSType_SOA,           //  6 Start of Authority
1775ffb0c9bSToomas Soome     kDNSType_MB,            //  7 Mailbox
1785ffb0c9bSToomas Soome     kDNSType_MG,            //  8 Mail Group
1795ffb0c9bSToomas Soome     kDNSType_MR,            //  9 Mail Rename
1805ffb0c9bSToomas Soome     kDNSType_NULL,          // 10 NULL RR
1815ffb0c9bSToomas Soome     kDNSType_WKS,           // 11 Well-known-service
1825ffb0c9bSToomas Soome     kDNSType_PTR,           // 12 Domain name pointer
1835ffb0c9bSToomas Soome     kDNSType_HINFO,         // 13 Host information
1845ffb0c9bSToomas Soome     kDNSType_MINFO,         // 14 Mailbox information
1855ffb0c9bSToomas Soome     kDNSType_MX,            // 15 Mail Exchanger
1865ffb0c9bSToomas Soome     kDNSType_TXT,           // 16 Arbitrary text string
1875ffb0c9bSToomas Soome     kDNSType_RP,            // 17 Responsible person
1885ffb0c9bSToomas Soome     kDNSType_AFSDB,         // 18 AFS cell database
1895ffb0c9bSToomas Soome     kDNSType_X25,           // 19 X_25 calling address
1905ffb0c9bSToomas Soome     kDNSType_ISDN,          // 20 ISDN calling address
1915ffb0c9bSToomas Soome     kDNSType_RT,            // 21 Router
1925ffb0c9bSToomas Soome     kDNSType_NSAP,          // 22 NSAP address
1935ffb0c9bSToomas Soome     kDNSType_NSAP_PTR,      // 23 Reverse NSAP lookup (deprecated)
1945ffb0c9bSToomas Soome     kDNSType_SIG,           // 24 Security signature
1955ffb0c9bSToomas Soome     kDNSType_KEY,           // 25 Security key
1965ffb0c9bSToomas Soome     kDNSType_PX,            // 26 X.400 mail mapping
1975ffb0c9bSToomas Soome     kDNSType_GPOS,          // 27 Geographical position (withdrawn)
1985ffb0c9bSToomas Soome     kDNSType_AAAA,          // 28 IPv6 Address
1995ffb0c9bSToomas Soome     kDNSType_LOC,           // 29 Location Information
2005ffb0c9bSToomas Soome     kDNSType_NXT,           // 30 Next domain (security)
2015ffb0c9bSToomas Soome     kDNSType_EID,           // 31 Endpoint identifier
2025ffb0c9bSToomas Soome     kDNSType_NIMLOC,        // 32 Nimrod Locator
2035ffb0c9bSToomas Soome     kDNSType_SRV,           // 33 Service record
2045ffb0c9bSToomas Soome     kDNSType_ATMA,          // 34 ATM Address
2055ffb0c9bSToomas Soome     kDNSType_NAPTR,         // 35 Naming Authority PoinTeR
2065ffb0c9bSToomas Soome     kDNSType_KX,            // 36 Key Exchange
2075ffb0c9bSToomas Soome     kDNSType_CERT,          // 37 Certification record
2085ffb0c9bSToomas Soome     kDNSType_A6,            // 38 IPv6 Address (deprecated)
2095ffb0c9bSToomas Soome     kDNSType_DNAME,         // 39 Non-terminal DNAME (for IPv6)
2105ffb0c9bSToomas Soome     kDNSType_SINK,          // 40 Kitchen sink (experimental)
2115ffb0c9bSToomas Soome     kDNSType_OPT,           // 41 EDNS0 option (meta-RR)
2125ffb0c9bSToomas Soome     kDNSType_APL,           // 42 Address Prefix List
2135ffb0c9bSToomas Soome     kDNSType_DS,            // 43 Delegation Signer
2145ffb0c9bSToomas Soome     kDNSType_SSHFP,         // 44 SSH Key Fingerprint
2155ffb0c9bSToomas Soome     kDNSType_IPSECKEY,      // 45 IPSECKEY
2165ffb0c9bSToomas Soome     kDNSType_RRSIG,         // 46 RRSIG
2175ffb0c9bSToomas Soome     kDNSType_NSEC,          // 47 Denial of Existence
2185ffb0c9bSToomas Soome     kDNSType_DNSKEY,        // 48 DNSKEY
2195ffb0c9bSToomas Soome     kDNSType_DHCID,         // 49 DHCP Client Identifier
2205ffb0c9bSToomas Soome     kDNSType_NSEC3,         // 50 Hashed Authenticated Denial of Existence
2215ffb0c9bSToomas Soome     kDNSType_NSEC3PARAM,    // 51 Hashed Authenticated Denial of Existence
2225ffb0c9bSToomas Soome 
2235ffb0c9bSToomas Soome     kDNSType_HIP = 55,      // 55 Host Identity Protocol
2245ffb0c9bSToomas Soome 
2255ffb0c9bSToomas Soome     kDNSType_SPF = 99,      // 99 Sender Policy Framework for E-Mail
2265ffb0c9bSToomas Soome     kDNSType_UINFO,         // 100 IANA-Reserved
2275ffb0c9bSToomas Soome     kDNSType_UID,           // 101 IANA-Reserved
2285ffb0c9bSToomas Soome     kDNSType_GID,           // 102 IANA-Reserved
2295ffb0c9bSToomas Soome     kDNSType_UNSPEC,        // 103 IANA-Reserved
2305ffb0c9bSToomas Soome 
2315ffb0c9bSToomas Soome     kDNSType_TKEY = 249,    // 249 Transaction key
2325ffb0c9bSToomas Soome     kDNSType_TSIG,          // 250 Transaction signature
2335ffb0c9bSToomas Soome     kDNSType_IXFR,          // 251 Incremental zone transfer
2345ffb0c9bSToomas Soome     kDNSType_AXFR,          // 252 Transfer zone of authority
2355ffb0c9bSToomas Soome     kDNSType_MAILB,         // 253 Transfer mailbox records
2365ffb0c9bSToomas Soome     kDNSType_MAILA,         // 254 Transfer mail agent records
2375ffb0c9bSToomas Soome     kDNSQType_ANY           // Not a DNS type, but a DNS query type, meaning "all types"
2385ffb0c9bSToomas Soome } DNS_TypeValues;
2394b22b933Srs 
2404b22b933Srs // ***************************************************************************
2414b22b933Srs #if 0
2425ffb0c9bSToomas Soome #pragma mark -
2434b22b933Srs #pragma mark - Simple types
2444b22b933Srs #endif
2454b22b933Srs 
2464b22b933Srs // mDNS defines its own names for these common types to simplify portability across
2474b22b933Srs // multiple platforms that may each have their own (different) names for these types.
2485ffb0c9bSToomas Soome typedef unsigned char mDNSBool;
2495ffb0c9bSToomas Soome typedef   signed char mDNSs8;
2505ffb0c9bSToomas Soome typedef unsigned char mDNSu8;
2514b22b933Srs typedef   signed short mDNSs16;
2524b22b933Srs typedef unsigned short mDNSu16;
2534b22b933Srs 
2545ffb0c9bSToomas Soome // Source: http://www.unix.org/version2/whatsnew/lp64_wp.html
2555ffb0c9bSToomas Soome // http://software.intel.com/sites/products/documentation/hpc/mkl/lin/MKL_UG_structure/Support_for_ILP64_Programming.htm
2565ffb0c9bSToomas Soome // It can be safely assumed that int is 32bits on the platform
2574b22b933Srs #if defined(_ILP64) || defined(__ILP64__)
2584b22b933Srs typedef   signed int32 mDNSs32;
2594b22b933Srs typedef unsigned int32 mDNSu32;
2604b22b933Srs #else
2615ffb0c9bSToomas Soome typedef   signed int mDNSs32;
2625ffb0c9bSToomas Soome typedef unsigned int mDNSu32;
2634b22b933Srs #endif
2644b22b933Srs 
2654b22b933Srs // To enforce useful type checking, we make mDNSInterfaceID be a pointer to a dummy struct
2664b22b933Srs // This way, mDNSInterfaceIDs can be assigned, and compared with each other, but not with other types
2674b22b933Srs // Declaring the type to be the typical generic "void *" would lack this type checking
2684b22b933Srs typedef struct mDNSInterfaceID_dummystruct { void *dummy; } *mDNSInterfaceID;
2694b22b933Srs 
2704b22b933Srs // These types are for opaque two- and four-byte identifiers.
2714b22b933Srs // The "NotAnInteger" fields of the unions allow the value to be conveniently passed around in a
2724b22b933Srs // register for the sake of efficiency, and compared for equality or inequality, but don't forget --
2734b22b933Srs // just because it is in a register doesn't mean it is an integer. Operations like greater than,
2744b22b933Srs // less than, add, multiply, increment, decrement, etc., are undefined for opaque identifiers,
2754b22b933Srs // and if you make the mistake of trying to do those using the NotAnInteger field, then you'll
2764b22b933Srs // find you get code that doesn't work consistently on big-endian and little-endian machines.
2775ffb0c9bSToomas Soome #if defined(_WIN32)
2785ffb0c9bSToomas Soome  #pragma pack(push,2)
2795ffb0c9bSToomas Soome #endif
2805ffb0c9bSToomas Soome typedef       union { mDNSu8 b[ 2]; mDNSu16 NotAnInteger; } mDNSOpaque16;
2815ffb0c9bSToomas Soome typedef       union { mDNSu8 b[ 4]; mDNSu32 NotAnInteger; } mDNSOpaque32;
2824b22b933Srs typedef packedunion { mDNSu8 b[ 6]; mDNSu16 w[3]; mDNSu32 l[1]; } mDNSOpaque48;
2835ffb0c9bSToomas Soome typedef       union { mDNSu8 b[ 8]; mDNSu16 w[4]; mDNSu32 l[2]; } mDNSOpaque64;
2845ffb0c9bSToomas Soome typedef       union { mDNSu8 b[16]; mDNSu16 w[8]; mDNSu32 l[4]; } mDNSOpaque128;
2855ffb0c9bSToomas Soome #if defined(_WIN32)
2865ffb0c9bSToomas Soome  #pragma pack(pop)
2875ffb0c9bSToomas Soome #endif
2885ffb0c9bSToomas Soome 
2895ffb0c9bSToomas Soome typedef mDNSOpaque16 mDNSIPPort;        // An IP port is a two-byte opaque identifier (not an integer)
2905ffb0c9bSToomas Soome typedef mDNSOpaque32 mDNSv4Addr;        // An IP address is a four-byte opaque identifier (not an integer)
2915ffb0c9bSToomas Soome typedef mDNSOpaque128 mDNSv6Addr;       // An IPv6 address is a 16-byte opaque identifier (not an integer)
2925ffb0c9bSToomas Soome typedef mDNSOpaque48 mDNSEthAddr;       // An Ethernet address is a six-byte opaque identifier (not an integer)
2934b22b933Srs 
2945ffb0c9bSToomas Soome // Bit operations for opaque 64 bit quantity. Uses the 32 bit quantity(l[2]) to set and clear bits
2955ffb0c9bSToomas Soome #define mDNSNBBY 8
2965ffb0c9bSToomas Soome #define bit_set_opaque64(op64, index) (op64.l[((index))/(sizeof(mDNSu32) * mDNSNBBY)] |= (1 << ((index) % (sizeof(mDNSu32) * mDNSNBBY))))
2975ffb0c9bSToomas Soome #define bit_clr_opaque64(op64, index) (op64.l[((index))/(sizeof(mDNSu32) * mDNSNBBY)] &= ~(1 << ((index) % (sizeof(mDNSu32) * mDNSNBBY))))
2985ffb0c9bSToomas Soome #define bit_get_opaque64(op64, index) (op64.l[((index))/(sizeof(mDNSu32) * mDNSNBBY)] & (1 << ((index) % (sizeof(mDNSu32) * mDNSNBBY))))
2994b22b933Srs 
300*c65ebfc7SToomas Soome // Bit operations for opaque 128 bit quantity. Uses the 32 bit quantity(l[4]) to set and clear bits
301*c65ebfc7SToomas Soome #define bit_set_opaque128(op128, index) (op128.l[((index))/(sizeof(mDNSu32) * mDNSNBBY)] |= (1 << ((index) % (sizeof(mDNSu32) * mDNSNBBY))))
302*c65ebfc7SToomas Soome #define bit_clr_opaque128(op128, index) (op128.l[((index))/(sizeof(mDNSu32) * mDNSNBBY)] &= ~(1 << ((index) % (sizeof(mDNSu32) * mDNSNBBY))))
303*c65ebfc7SToomas Soome #define bit_get_opaque128(op128, index) (op128.l[((index))/(sizeof(mDNSu32) * mDNSNBBY)] & (1 << ((index) % (sizeof(mDNSu32) * mDNSNBBY))))
304*c65ebfc7SToomas Soome 
305*c65ebfc7SToomas Soome typedef enum
3065ffb0c9bSToomas Soome {
3075ffb0c9bSToomas Soome     mDNSAddrType_None    = 0,
3085ffb0c9bSToomas Soome     mDNSAddrType_IPv4    = 4,
3095ffb0c9bSToomas Soome     mDNSAddrType_IPv6    = 6,
3105ffb0c9bSToomas Soome     mDNSAddrType_Unknown = ~0   // Special marker value used in known answer list recording
311*c65ebfc7SToomas Soome } mDNSAddr_Type;
3125ffb0c9bSToomas Soome 
313*c65ebfc7SToomas Soome typedef enum
3145ffb0c9bSToomas Soome {
3155ffb0c9bSToomas Soome     mDNSTransport_None = 0,
3165ffb0c9bSToomas Soome     mDNSTransport_UDP  = 1,
3175ffb0c9bSToomas Soome     mDNSTransport_TCP  = 2
318*c65ebfc7SToomas Soome } mDNSTransport_Type;
3194b22b933Srs 
3204b22b933Srs typedef struct
3215ffb0c9bSToomas Soome {
3225ffb0c9bSToomas Soome     mDNSs32 type;
3235ffb0c9bSToomas Soome     union { mDNSv6Addr v6; mDNSv4Addr v4; } ip;
3245ffb0c9bSToomas Soome } mDNSAddr;
3254b22b933Srs 
3264b22b933Srs enum { mDNSfalse = 0, mDNStrue = 1 };
3274b22b933Srs 
3284b22b933Srs #define mDNSNULL 0L
3294b22b933Srs 
3304b22b933Srs enum
3315ffb0c9bSToomas Soome {
3325ffb0c9bSToomas Soome     mStatus_Waiting           = 1,
3335ffb0c9bSToomas Soome     mStatus_NoError           = 0,
3345ffb0c9bSToomas Soome 
3355ffb0c9bSToomas Soome     // mDNS return values are in the range FFFE FF00 (-65792) to FFFE FFFF (-65537)
3365ffb0c9bSToomas Soome     // The top end of the range (FFFE FFFF) is used for error codes;
3375ffb0c9bSToomas Soome     // the bottom end of the range (FFFE FF00) is used for non-error values;
3385ffb0c9bSToomas Soome 
3395ffb0c9bSToomas Soome     // Error codes:
3405ffb0c9bSToomas Soome     mStatus_UnknownErr                = -65537,     // First value: 0xFFFE FFFF
3415ffb0c9bSToomas Soome     mStatus_NoSuchNameErr             = -65538,
3425ffb0c9bSToomas Soome     mStatus_NoMemoryErr               = -65539,
3435ffb0c9bSToomas Soome     mStatus_BadParamErr               = -65540,
3445ffb0c9bSToomas Soome     mStatus_BadReferenceErr           = -65541,
3455ffb0c9bSToomas Soome     mStatus_BadStateErr               = -65542,
3465ffb0c9bSToomas Soome     mStatus_BadFlagsErr               = -65543,
3475ffb0c9bSToomas Soome     mStatus_UnsupportedErr            = -65544,
3485ffb0c9bSToomas Soome     mStatus_NotInitializedErr         = -65545,
3495ffb0c9bSToomas Soome     mStatus_NoCache                   = -65546,
3505ffb0c9bSToomas Soome     mStatus_AlreadyRegistered         = -65547,
3515ffb0c9bSToomas Soome     mStatus_NameConflict              = -65548,
3525ffb0c9bSToomas Soome     mStatus_Invalid                   = -65549,
3535ffb0c9bSToomas Soome     mStatus_Firewall                  = -65550,
3545ffb0c9bSToomas Soome     mStatus_Incompatible              = -65551,
3555ffb0c9bSToomas Soome     mStatus_BadInterfaceErr           = -65552,
3565ffb0c9bSToomas Soome     mStatus_Refused                   = -65553,
3575ffb0c9bSToomas Soome     mStatus_NoSuchRecord              = -65554,
3585ffb0c9bSToomas Soome     mStatus_NoAuth                    = -65555,
3595ffb0c9bSToomas Soome     mStatus_NoSuchKey                 = -65556,
3605ffb0c9bSToomas Soome     mStatus_NATTraversal              = -65557,
3615ffb0c9bSToomas Soome     mStatus_DoubleNAT                 = -65558,
3625ffb0c9bSToomas Soome     mStatus_BadTime                   = -65559,
3635ffb0c9bSToomas Soome     mStatus_BadSig                    = -65560,     // while we define this per RFC 2845, BIND 9 returns Refused for bad/missing signatures
3645ffb0c9bSToomas Soome     mStatus_BadKey                    = -65561,
3655ffb0c9bSToomas Soome     mStatus_TransientErr              = -65562,     // transient failures, e.g. sending packets shortly after a network transition or wake from sleep
3665ffb0c9bSToomas Soome     mStatus_ServiceNotRunning         = -65563,     // Background daemon not running
3675ffb0c9bSToomas Soome     mStatus_NATPortMappingUnsupported = -65564,     // NAT doesn't support PCP, NAT-PMP or UPnP
3685ffb0c9bSToomas Soome     mStatus_NATPortMappingDisabled    = -65565,     // NAT supports PCP, NAT-PMP or UPnP, but it's disabled by the administrator
3695ffb0c9bSToomas Soome     mStatus_NoRouter                  = -65566,
3705ffb0c9bSToomas Soome     mStatus_PollingMode               = -65567,
3715ffb0c9bSToomas Soome     mStatus_Timeout                   = -65568,
372*c65ebfc7SToomas Soome     mStatus_HostUnreachErr            = -65569,
373*c65ebfc7SToomas Soome     // -65570 to -65786 currently unused; available for allocation
3745ffb0c9bSToomas Soome 
3755ffb0c9bSToomas Soome     // tcp connection status
3765ffb0c9bSToomas Soome     mStatus_ConnPending       = -65787,
3775ffb0c9bSToomas Soome     mStatus_ConnFailed        = -65788,
3785ffb0c9bSToomas Soome     mStatus_ConnEstablished   = -65789,
3795ffb0c9bSToomas Soome 
3805ffb0c9bSToomas Soome     // Non-error values:
3815ffb0c9bSToomas Soome     mStatus_GrowCache         = -65790,
3825ffb0c9bSToomas Soome     mStatus_ConfigChanged     = -65791,
3835ffb0c9bSToomas Soome     mStatus_MemFree           = -65792      // Last value: 0xFFFE FF00
3845ffb0c9bSToomas Soome                                 // mStatus_MemFree is the last legal mDNS error code, at the end of the range allocated for mDNS
3855ffb0c9bSToomas Soome };
3864b22b933Srs 
3874b22b933Srs typedef mDNSs32 mStatus;
3885ffb0c9bSToomas Soome #define MaxIp 5 // Needs to be consistent with MaxInputIf in dns_services.h
3895ffb0c9bSToomas Soome 
3905ffb0c9bSToomas Soome typedef enum { q_stop = 0, q_start } q_state;
3915ffb0c9bSToomas Soome typedef enum { reg_stop = 0, reg_start } reg_state;
3924b22b933Srs 
3934b22b933Srs // RFC 1034/1035 specify that a domain label consists of a length byte plus up to 63 characters
3944b22b933Srs #define MAX_DOMAIN_LABEL 63
3955ffb0c9bSToomas Soome typedef struct { mDNSu8 c[ 64]; } domainlabel;      // One label: length byte and up to 63 characters
3964b22b933Srs 
3975ffb0c9bSToomas Soome // RFC 1034/1035/2181 specify that a domain name (length bytes and data bytes) may be up to 255 bytes long,
3985ffb0c9bSToomas Soome // plus the terminating zero at the end makes 256 bytes total in the on-the-wire format.
3995ffb0c9bSToomas Soome #define MAX_DOMAIN_NAME 256
4005ffb0c9bSToomas Soome typedef struct { mDNSu8 c[256]; } domainname;       // Up to 256 bytes of length-prefixed domainlabels
4014b22b933Srs 
4025ffb0c9bSToomas Soome typedef struct { mDNSu8 c[256]; } UTF8str255;       // Null-terminated C string
4034b22b933Srs 
4045ffb0c9bSToomas Soome // The longest legal textual form of a DNS name is 1009 bytes, including the C-string terminating NULL at the end.
4054b22b933Srs // Explanation:
4064b22b933Srs // When a native domainname object is converted to printable textual form using ConvertDomainNameToCString(),
4074b22b933Srs // non-printing characters are represented in the conventional DNS way, as '\ddd', where ddd is a three-digit decimal number.
4085ffb0c9bSToomas Soome // The longest legal domain name is 256 bytes, in the form of four labels as shown below:
4095ffb0c9bSToomas Soome // Length byte, 63 data bytes, length byte, 63 data bytes, length byte, 63 data bytes, length byte, 62 data bytes, zero byte.
4104b22b933Srs // Each label is encoded textually as characters followed by a trailing dot.
4114b22b933Srs // If every character has to be represented as a four-byte escape sequence, then this makes the maximum textual form four labels
4124b22b933Srs // plus the C-string terminating NULL as shown below:
4135ffb0c9bSToomas Soome // 63*4+1 + 63*4+1 + 63*4+1 + 62*4+1 + 1 = 1009.
4144b22b933Srs // Note that MAX_ESCAPED_DOMAIN_LABEL is not normally used: If you're only decoding a single label, escaping is usually not required.
4154b22b933Srs // It is for domain names, where dots are used as label separators, that proper escaping is vital.
4164b22b933Srs #define MAX_ESCAPED_DOMAIN_LABEL 254
4175ffb0c9bSToomas Soome #define MAX_ESCAPED_DOMAIN_NAME 1009
4185ffb0c9bSToomas Soome 
4195ffb0c9bSToomas Soome // MAX_REVERSE_MAPPING_NAME
4205ffb0c9bSToomas Soome // For IPv4: "123.123.123.123.in-addr.arpa."  30 bytes including terminating NUL
4215ffb0c9bSToomas 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
4225ffb0c9bSToomas Soome 
4235ffb0c9bSToomas Soome #define MAX_REVERSE_MAPPING_NAME_V4 30
4245ffb0c9bSToomas Soome #define MAX_REVERSE_MAPPING_NAME_V6 74
4255ffb0c9bSToomas Soome #define MAX_REVERSE_MAPPING_NAME    74
4264b22b933Srs 
4274b22b933Srs // Most records have a TTL of 75 minutes, so that their 80% cache-renewal query occurs once per hour.
4284b22b933Srs // For records containing a hostname (in the name on the left, or in the rdata on the right),
4294b22b933Srs // like A, AAAA, reverse-mapping PTR, and SRV, we use a two-minute TTL by default, because we don't want
4304b22b933Srs // them to hang around for too long in the cache if the host in question crashes or otherwise goes away.
4315ffb0c9bSToomas Soome 
4324b22b933Srs #define kStandardTTL (3600UL * 100 / 80)
4334b22b933Srs #define kHostNameTTL 120UL
4345ffb0c9bSToomas Soome 
4355ffb0c9bSToomas Soome // Some applications want to register their SRV records with a lower ttl so that in case the server
4365ffb0c9bSToomas Soome // using a dynamic port number restarts, the clients will not have stale information for more than
4375ffb0c9bSToomas Soome // 10 seconds
4385ffb0c9bSToomas Soome 
4395ffb0c9bSToomas Soome #define kHostNameSmallTTL 10UL
4405ffb0c9bSToomas Soome 
4415ffb0c9bSToomas Soome 
4425ffb0c9bSToomas Soome // Multicast DNS uses announcements (gratuitous responses) to update peer caches.
4435ffb0c9bSToomas Soome // This means it is feasible to use relatively larger TTL values than we might otherwise
4445ffb0c9bSToomas Soome // use, because we have a cache coherency protocol to keep the peer caches up to date.
4455ffb0c9bSToomas Soome // With Unicast DNS, once an authoritative server gives a record with a certain TTL value to a client
4465ffb0c9bSToomas Soome // or caching server, that client or caching server is entitled to hold onto the record until its TTL
4475ffb0c9bSToomas Soome // expires, and has no obligation to contact the authoritative server again until that time arrives.
4485ffb0c9bSToomas Soome // This means that whereas Multicast DNS can use announcements to pre-emptively update stale data
4495ffb0c9bSToomas Soome // before it would otherwise have expired, standard Unicast DNS (not using LLQs) has no equivalent
4505ffb0c9bSToomas Soome // mechanism, and TTL expiry is the *only* mechanism by which stale data gets deleted. Because of this,
4515ffb0c9bSToomas Soome // we currently limit the TTL to ten seconds in such cases where no dynamic cache updating is possible.
4525ffb0c9bSToomas Soome #define kStaticCacheTTL 10
4534b22b933Srs 
4544b22b933Srs #define DefaultTTLforRRType(X) (((X) == kDNSType_A || (X) == kDNSType_AAAA || (X) == kDNSType_SRV) ? kHostNameTTL : kStandardTTL)
4555ffb0c9bSToomas Soome #define mDNS_KeepaliveRecord(rr) ((rr)->rrtype == kDNSType_NULL && SameDomainLabel(SecondLabel((rr)->name)->c, (mDNSu8 *)"\x0A_keepalive"))
4565ffb0c9bSToomas Soome 
4575ffb0c9bSToomas Soome // Number of times keepalives are sent if no ACK is received before waking up the system
4585ffb0c9bSToomas Soome // this is analogous to net.inet.tcp.keepcnt
4595ffb0c9bSToomas Soome #define kKeepaliveRetryCount    10
4605ffb0c9bSToomas Soome // The frequency at which keepalives are retried if no ACK is received
4615ffb0c9bSToomas Soome #define kKeepaliveRetryInterval 30
4625ffb0c9bSToomas Soome 
4635ffb0c9bSToomas Soome typedef struct AuthRecord_struct AuthRecord;
4645ffb0c9bSToomas Soome typedef struct ServiceRecordSet_struct ServiceRecordSet;
4655ffb0c9bSToomas Soome typedef struct CacheRecord_struct CacheRecord;
4665ffb0c9bSToomas Soome typedef struct CacheGroup_struct CacheGroup;
4675ffb0c9bSToomas Soome typedef struct AuthGroup_struct AuthGroup;
4685ffb0c9bSToomas Soome typedef struct DNSQuestion_struct DNSQuestion;
4695ffb0c9bSToomas Soome typedef struct ZoneData_struct ZoneData;
4705ffb0c9bSToomas Soome typedef struct mDNS_struct mDNS;
4715ffb0c9bSToomas Soome typedef struct mDNS_PlatformSupport_struct mDNS_PlatformSupport;
4725ffb0c9bSToomas Soome typedef struct NATTraversalInfo_struct NATTraversalInfo;
4735ffb0c9bSToomas Soome typedef struct ResourceRecord_struct ResourceRecord;
4745ffb0c9bSToomas Soome 
4755ffb0c9bSToomas Soome // Structure to abstract away the differences between TCP/SSL sockets, and one for UDP sockets
4765ffb0c9bSToomas Soome // The actual definition of these structures appear in the appropriate platform support code
4775ffb0c9bSToomas Soome typedef struct TCPSocket_struct TCPSocket;
4785ffb0c9bSToomas Soome typedef struct UDPSocket_struct UDPSocket;
4794b22b933Srs 
4804b22b933Srs // ***************************************************************************
4814b22b933Srs #if 0
4825ffb0c9bSToomas Soome #pragma mark -
4834b22b933Srs #pragma mark - DNS Message structures
4844b22b933Srs #endif
4854b22b933Srs 
4864b22b933Srs #define mDNS_numZones   numQuestions
4874b22b933Srs #define mDNS_numPrereqs numAnswers
4884b22b933Srs #define mDNS_numUpdates numAuthorities
4894b22b933Srs 
490*c65ebfc7SToomas Soome typedef struct
4915ffb0c9bSToomas Soome {
4925ffb0c9bSToomas Soome     mDNSOpaque16 id;
4935ffb0c9bSToomas Soome     mDNSOpaque16 flags;
4945ffb0c9bSToomas Soome     mDNSu16 numQuestions;
4955ffb0c9bSToomas Soome     mDNSu16 numAnswers;
4965ffb0c9bSToomas Soome     mDNSu16 numAuthorities;
4975ffb0c9bSToomas Soome     mDNSu16 numAdditionals;
4985ffb0c9bSToomas Soome } DNSMessageHeader;
4994b22b933Srs 
5004b22b933Srs // We can send and receive packets up to 9000 bytes (Ethernet Jumbo Frame size, if that ever becomes widely used)
5014b22b933Srs // However, in the normal case we try to limit packets to 1500 bytes so that we don't get IP fragmentation on standard Ethernet
5024b22b933Srs // 40 (IPv6 header) + 8 (UDP header) + 12 (DNS message header) + 1440 (DNS message body) = 1500 total
5035ffb0c9bSToomas Soome #ifndef AbsoluteMaxDNSMessageData
5044b22b933Srs #define AbsoluteMaxDNSMessageData 8940
5055ffb0c9bSToomas Soome #endif
5064b22b933Srs #define NormalMaxDNSMessageData 1440
507*c65ebfc7SToomas Soome typedef struct
5085ffb0c9bSToomas Soome {
5095ffb0c9bSToomas Soome     DNSMessageHeader h;                     // Note: Size 12 bytes
5105ffb0c9bSToomas Soome     mDNSu8 data[AbsoluteMaxDNSMessageData]; // 40 (IPv6) + 8 (UDP) + 12 (DNS header) + 8940 (data) = 9000
5115ffb0c9bSToomas Soome } DNSMessage;
5125ffb0c9bSToomas Soome 
5135ffb0c9bSToomas Soome typedef struct tcpInfo_t
5145ffb0c9bSToomas Soome {
5155ffb0c9bSToomas Soome     mDNS             *m;
5165ffb0c9bSToomas Soome     TCPSocket        *sock;
5175ffb0c9bSToomas Soome     DNSMessage request;
5185ffb0c9bSToomas Soome     int requestLen;
5195ffb0c9bSToomas Soome     DNSQuestion      *question;   // For queries
5205ffb0c9bSToomas Soome     AuthRecord       *rr;         // For record updates
5215ffb0c9bSToomas Soome     mDNSAddr Addr;
5225ffb0c9bSToomas Soome     mDNSIPPort Port;
5235ffb0c9bSToomas Soome     mDNSIPPort SrcPort;
5245ffb0c9bSToomas Soome     DNSMessage       *reply;
5255ffb0c9bSToomas Soome     mDNSu16 replylen;
5265ffb0c9bSToomas Soome     unsigned long nread;
5275ffb0c9bSToomas Soome     int numReplies;
5285ffb0c9bSToomas Soome } tcpInfo_t;
5295ffb0c9bSToomas Soome 
5305ffb0c9bSToomas Soome // ***************************************************************************
5315ffb0c9bSToomas Soome #if 0
5325ffb0c9bSToomas Soome #pragma mark -
5335ffb0c9bSToomas Soome #pragma mark - Other Packet Format Structures
5345ffb0c9bSToomas Soome #endif
5355ffb0c9bSToomas Soome 
5365ffb0c9bSToomas Soome typedef packedstruct
5375ffb0c9bSToomas Soome {
5385ffb0c9bSToomas Soome     mDNSEthAddr dst;
5395ffb0c9bSToomas Soome     mDNSEthAddr src;
5405ffb0c9bSToomas Soome     mDNSOpaque16 ethertype;
5415ffb0c9bSToomas Soome } EthernetHeader;           // 14 bytes
5425ffb0c9bSToomas Soome 
5435ffb0c9bSToomas Soome typedef packedstruct
5445ffb0c9bSToomas Soome {
5455ffb0c9bSToomas Soome     mDNSOpaque16 hrd;
5465ffb0c9bSToomas Soome     mDNSOpaque16 pro;
5475ffb0c9bSToomas Soome     mDNSu8 hln;
5485ffb0c9bSToomas Soome     mDNSu8 pln;
5495ffb0c9bSToomas Soome     mDNSOpaque16 op;
5505ffb0c9bSToomas Soome     mDNSEthAddr sha;
5515ffb0c9bSToomas Soome     mDNSv4Addr spa;
5525ffb0c9bSToomas Soome     mDNSEthAddr tha;
5535ffb0c9bSToomas Soome     mDNSv4Addr tpa;
5545ffb0c9bSToomas Soome } ARP_EthIP;                // 28 bytes
5555ffb0c9bSToomas Soome 
5565ffb0c9bSToomas Soome typedef packedstruct
5575ffb0c9bSToomas Soome {
5585ffb0c9bSToomas Soome     mDNSu8 vlen;
5595ffb0c9bSToomas Soome     mDNSu8 tos;
560cda73f64SToomas Soome     mDNSOpaque16 totlen;
5615ffb0c9bSToomas Soome     mDNSOpaque16 id;
5625ffb0c9bSToomas Soome     mDNSOpaque16 flagsfrags;
5635ffb0c9bSToomas Soome     mDNSu8 ttl;
5645ffb0c9bSToomas Soome     mDNSu8 protocol;        // Payload type: 0x06 = TCP, 0x11 = UDP
5655ffb0c9bSToomas Soome     mDNSu16 checksum;
5665ffb0c9bSToomas Soome     mDNSv4Addr src;
5675ffb0c9bSToomas Soome     mDNSv4Addr dst;
5685ffb0c9bSToomas Soome } IPv4Header;               // 20 bytes
5695ffb0c9bSToomas Soome 
5705ffb0c9bSToomas Soome typedef packedstruct
5715ffb0c9bSToomas Soome {
5725ffb0c9bSToomas Soome     mDNSu32 vcf;            // Version, Traffic Class, Flow Label
5735ffb0c9bSToomas Soome     mDNSu16 len;            // Payload Length
5745ffb0c9bSToomas Soome     mDNSu8 pro;             // Type of next header: 0x06 = TCP, 0x11 = UDP, 0x3A = ICMPv6
5755ffb0c9bSToomas Soome     mDNSu8 ttl;             // Hop Limit
5765ffb0c9bSToomas Soome     mDNSv6Addr src;
5775ffb0c9bSToomas Soome     mDNSv6Addr dst;
5785ffb0c9bSToomas Soome } IPv6Header;               // 40 bytes
5795ffb0c9bSToomas Soome 
5805ffb0c9bSToomas Soome typedef packedstruct
5815ffb0c9bSToomas Soome {
5825ffb0c9bSToomas Soome     mDNSv6Addr src;
5835ffb0c9bSToomas Soome     mDNSv6Addr dst;
5845ffb0c9bSToomas Soome     mDNSOpaque32 len;
5855ffb0c9bSToomas Soome     mDNSOpaque32 pro;
5865ffb0c9bSToomas Soome } IPv6PseudoHeader;         // 40 bytes
5875ffb0c9bSToomas Soome 
5885ffb0c9bSToomas Soome typedef union
5895ffb0c9bSToomas Soome {
5905ffb0c9bSToomas Soome     mDNSu8 bytes[20];
5915ffb0c9bSToomas Soome     ARP_EthIP arp;
5925ffb0c9bSToomas Soome     IPv4Header v4;
5935ffb0c9bSToomas Soome     IPv6Header v6;
5945ffb0c9bSToomas Soome } NetworkLayerPacket;
5955ffb0c9bSToomas Soome 
5965ffb0c9bSToomas Soome typedef packedstruct
5975ffb0c9bSToomas Soome {
5985ffb0c9bSToomas Soome     mDNSIPPort src;
5995ffb0c9bSToomas Soome     mDNSIPPort dst;
6005ffb0c9bSToomas Soome     mDNSu32 seq;
6015ffb0c9bSToomas Soome     mDNSu32 ack;
6025ffb0c9bSToomas Soome     mDNSu8 offset;
6035ffb0c9bSToomas Soome     mDNSu8 flags;
6045ffb0c9bSToomas Soome     mDNSu16 window;
6055ffb0c9bSToomas Soome     mDNSu16 checksum;
6065ffb0c9bSToomas Soome     mDNSu16 urgent;
6075ffb0c9bSToomas Soome } TCPHeader;                // 20 bytes; IP protocol type 0x06
6085ffb0c9bSToomas Soome 
6095ffb0c9bSToomas Soome typedef struct
6105ffb0c9bSToomas Soome {
6115ffb0c9bSToomas Soome     mDNSInterfaceID IntfId;
6125ffb0c9bSToomas Soome     mDNSu32 seq;
6135ffb0c9bSToomas Soome     mDNSu32 ack;
6145ffb0c9bSToomas Soome     mDNSu16 window;
6155ffb0c9bSToomas Soome } mDNSTCPInfo;
6165ffb0c9bSToomas Soome 
6175ffb0c9bSToomas Soome typedef packedstruct
6185ffb0c9bSToomas Soome {
6195ffb0c9bSToomas Soome     mDNSIPPort src;
6205ffb0c9bSToomas Soome     mDNSIPPort dst;
6215ffb0c9bSToomas Soome     mDNSu16 len;            // Length including UDP header (i.e. minimum value is 8 bytes)
6225ffb0c9bSToomas Soome     mDNSu16 checksum;
6235ffb0c9bSToomas Soome } UDPHeader;                // 8 bytes; IP protocol type 0x11
6245ffb0c9bSToomas Soome 
625*c65ebfc7SToomas Soome typedef struct
6265ffb0c9bSToomas Soome {
6275ffb0c9bSToomas Soome     mDNSu8 type;            // 0x87 == Neighbor Solicitation, 0x88 == Neighbor Advertisement
6285ffb0c9bSToomas Soome     mDNSu8 code;
6295ffb0c9bSToomas Soome     mDNSu16 checksum;
6305ffb0c9bSToomas Soome     mDNSu32 flags_res;      // R/S/O flags and reserved bits
6315ffb0c9bSToomas Soome     mDNSv6Addr target;
6325ffb0c9bSToomas Soome     // Typically 8 bytes of options are also present
6335ffb0c9bSToomas Soome } IPv6NDP;                  // 24 bytes or more; IP protocol type 0x3A
6345ffb0c9bSToomas Soome 
6355ffb0c9bSToomas Soome typedef struct
6365ffb0c9bSToomas Soome {
6375ffb0c9bSToomas Soome     mDNSAddr    ipaddr;
6385ffb0c9bSToomas Soome     char        ethaddr[18];
6395ffb0c9bSToomas Soome } IPAddressMACMapping;
6405ffb0c9bSToomas Soome 
6415ffb0c9bSToomas Soome #define NDP_Sol 0x87
6425ffb0c9bSToomas Soome #define NDP_Adv 0x88
6435ffb0c9bSToomas Soome 
6445ffb0c9bSToomas Soome #define NDP_Router    0x80
6455ffb0c9bSToomas Soome #define NDP_Solicited 0x40
6465ffb0c9bSToomas Soome #define NDP_Override  0x20
6475ffb0c9bSToomas Soome 
6485ffb0c9bSToomas Soome #define NDP_SrcLL 1
6495ffb0c9bSToomas Soome #define NDP_TgtLL 2
6505ffb0c9bSToomas Soome 
6515ffb0c9bSToomas Soome typedef union
6525ffb0c9bSToomas Soome {
6535ffb0c9bSToomas Soome     mDNSu8 bytes[20];
6545ffb0c9bSToomas Soome     TCPHeader tcp;
6555ffb0c9bSToomas Soome     UDPHeader udp;
6565ffb0c9bSToomas Soome     IPv6NDP ndp;
6575ffb0c9bSToomas Soome } TransportLayerPacket;
6585ffb0c9bSToomas Soome 
6595ffb0c9bSToomas Soome typedef packedstruct
6605ffb0c9bSToomas Soome {
6615ffb0c9bSToomas Soome     mDNSOpaque64 InitiatorCookie;
6625ffb0c9bSToomas Soome     mDNSOpaque64 ResponderCookie;
6635ffb0c9bSToomas Soome     mDNSu8 NextPayload;
6645ffb0c9bSToomas Soome     mDNSu8 Version;
6655ffb0c9bSToomas Soome     mDNSu8 ExchangeType;
6665ffb0c9bSToomas Soome     mDNSu8 Flags;
6675ffb0c9bSToomas Soome     mDNSOpaque32 MessageID;
6685ffb0c9bSToomas Soome     mDNSu32 Length;
6695ffb0c9bSToomas Soome } IKEHeader;                // 28 bytes
6704b22b933Srs 
6714b22b933Srs // ***************************************************************************
6724b22b933Srs #if 0
6735ffb0c9bSToomas Soome #pragma mark -
6744b22b933Srs #pragma mark - Resource Record structures
6754b22b933Srs #endif
6764b22b933Srs 
6774b22b933Srs // Authoritative Resource Records:
6784b22b933Srs // There are four basic types: Shared, Advisory, Unique, Known Unique
6794b22b933Srs 
6804b22b933Srs // * Shared Resource Records do not have to be unique
6814b22b933Srs // -- Shared Resource Records are used for DNS-SD service PTRs
6824b22b933Srs // -- It is okay for several hosts to have RRs with the same name but different RDATA
6834b22b933Srs // -- We use a random delay on responses to reduce collisions when all the hosts respond to the same query
6844b22b933Srs // -- These RRs typically have moderately high TTLs (e.g. one hour)
6854b22b933Srs // -- These records are announced on startup and topology changes for the benefit of passive listeners
6864b22b933Srs // -- These records send a goodbye packet when deregistering
6874b22b933Srs //
6884b22b933Srs // * Advisory Resource Records are like Shared Resource Records, except they don't send a goodbye packet
6894b22b933Srs //
6904b22b933Srs // * Unique Resource Records should be unique among hosts within any given mDNS scope
6914b22b933Srs // -- The majority of Resource Records are of this type
6924b22b933Srs // -- If two entities on the network have RRs with the same name but different RDATA, this is a conflict
6934b22b933Srs // -- Responses may be sent immediately, because only one host should be responding to any particular query
6944b22b933Srs // -- These RRs typically have low TTLs (e.g. a few minutes)
6954b22b933Srs // -- On startup and after topology changes, a host issues queries to verify uniqueness
6964b22b933Srs 
6974b22b933Srs // * Known Unique Resource Records are treated like Unique Resource Records, except that mDNS does
6984b22b933Srs // not have to verify their uniqueness because this is already known by other means (e.g. the RR name
6994b22b933Srs // is derived from the host's IP or Ethernet address, which is already known to be a unique identifier).
7004b22b933Srs 
7014b22b933Srs // Summary of properties of different record types:
7024b22b933Srs // Probe?    Does this record type send probes before announcing?
7034b22b933Srs // Conflict? Does this record type react if we observe an apparent conflict?
7044b22b933Srs // Goodbye?  Does this record type send a goodbye packet on departure?
7054b22b933Srs //
7064b22b933Srs //               Probe? Conflict? Goodbye? Notes
7074b22b933Srs // Unregistered                            Should not appear in any list (sanity check value)
7084b22b933Srs // Shared         No      No       Yes     e.g. Service PTR record
7094b22b933Srs // Deregistering  No      No       Yes     Shared record about to announce its departure and leave the list
7104b22b933Srs // Advisory       No      No       No
7114b22b933Srs // Unique         Yes     Yes      No      Record intended to be unique -- will probe to verify
7124b22b933Srs // Verified       Yes     Yes      No      Record has completed probing, and is verified unique
7134b22b933Srs // KnownUnique    No      Yes      No      Record is assumed by other means to be unique
7144b22b933Srs 
7154b22b933Srs // Valid lifecycle of a record:
7164b22b933Srs // Unregistered ->                   Shared      -> Deregistering -(goodbye)-> Unregistered
7174b22b933Srs // Unregistered ->                   Advisory                               -> Unregistered
7184b22b933Srs // Unregistered -> Unique -(probe)-> Verified                               -> Unregistered
7194b22b933Srs // Unregistered ->                   KnownUnique                            -> Unregistered
7204b22b933Srs 
7214b22b933Srs // Each Authoritative kDNSRecordType has only one bit set. This makes it easy to quickly see if a record
7224b22b933Srs // is one of a particular set of types simply by performing the appropriate bitwise masking operation.
7234b22b933Srs 
7245ffb0c9bSToomas Soome // Cache Resource Records (received from the network):
7255ffb0c9bSToomas Soome // There are four basic types: Answer, Unique Answer, Additional, Unique Additional
7265ffb0c9bSToomas Soome // Bit 7 (the top bit) of kDNSRecordType is always set for Cache Resource Records; always clear for Authoritative Resource Records
7275ffb0c9bSToomas Soome // Bit 6 (value 0x40) is set for answer records; clear for authority/additional records
7285ffb0c9bSToomas Soome // Bit 5 (value 0x20) is set for records received with the kDNSClass_UniqueRRSet
7295ffb0c9bSToomas Soome 
730*c65ebfc7SToomas Soome typedef enum
7315ffb0c9bSToomas Soome {
7325ffb0c9bSToomas Soome     kDNSRecordTypeUnregistered     = 0x00,  // Not currently in any list
7335ffb0c9bSToomas Soome     kDNSRecordTypeDeregistering    = 0x01,  // Shared record about to announce its departure and leave the list
7345ffb0c9bSToomas Soome 
7355ffb0c9bSToomas Soome     kDNSRecordTypeUnique           = 0x02,  // Will become a kDNSRecordTypeVerified when probing is complete
7365ffb0c9bSToomas Soome 
7375ffb0c9bSToomas Soome     kDNSRecordTypeAdvisory         = 0x04,  // Like Shared, but no goodbye packet
7385ffb0c9bSToomas Soome     kDNSRecordTypeShared           = 0x08,  // Shared means record name does not have to be unique -- use random delay on responses
7395ffb0c9bSToomas Soome 
7405ffb0c9bSToomas Soome     kDNSRecordTypeVerified         = 0x10,  // Unique means mDNS should check that name is unique (and then send immediate responses)
7415ffb0c9bSToomas Soome     kDNSRecordTypeKnownUnique      = 0x20,  // Known Unique means mDNS can assume name is unique without checking
7425ffb0c9bSToomas Soome                                             // For Dynamic Update records, Known Unique means the record must already exist on the server.
7435ffb0c9bSToomas Soome     kDNSRecordTypeUniqueMask       = (kDNSRecordTypeUnique | kDNSRecordTypeVerified | kDNSRecordTypeKnownUnique),
7445ffb0c9bSToomas Soome     kDNSRecordTypeActiveSharedMask = (kDNSRecordTypeAdvisory         | kDNSRecordTypeShared),
7455ffb0c9bSToomas Soome     kDNSRecordTypeActiveUniqueMask = (kDNSRecordTypeVerified         | kDNSRecordTypeKnownUnique),
7465ffb0c9bSToomas Soome     kDNSRecordTypeActiveMask       = (kDNSRecordTypeActiveSharedMask | kDNSRecordTypeActiveUniqueMask),
7475ffb0c9bSToomas Soome 
7485ffb0c9bSToomas Soome     kDNSRecordTypePacketAdd        = 0x80,  // Received in the Additional  Section of a DNS Response
7495ffb0c9bSToomas Soome     kDNSRecordTypePacketAddUnique  = 0x90,  // Received in the Additional  Section of a DNS Response with kDNSClass_UniqueRRSet set
7505ffb0c9bSToomas Soome     kDNSRecordTypePacketAuth       = 0xA0,  // Received in the Authorities Section of a DNS Response
7515ffb0c9bSToomas Soome     kDNSRecordTypePacketAuthUnique = 0xB0,  // Received in the Authorities Section of a DNS Response with kDNSClass_UniqueRRSet set
7525ffb0c9bSToomas Soome     kDNSRecordTypePacketAns        = 0xC0,  // Received in the Answer      Section of a DNS Response
7535ffb0c9bSToomas Soome     kDNSRecordTypePacketAnsUnique  = 0xD0,  // Received in the Answer      Section of a DNS Response with kDNSClass_UniqueRRSet set
7545ffb0c9bSToomas Soome 
7555ffb0c9bSToomas Soome     kDNSRecordTypePacketNegative   = 0xF0,  // Pseudo-RR generated to cache non-existence results like NXDomain
7565ffb0c9bSToomas Soome 
7575ffb0c9bSToomas Soome     kDNSRecordTypePacketUniqueMask = 0x10   // True for PacketAddUnique, PacketAnsUnique, PacketAuthUnique, kDNSRecordTypePacketNegative
758*c65ebfc7SToomas Soome } kDNSRecordTypes;
7595ffb0c9bSToomas Soome 
7605ffb0c9bSToomas Soome typedef packedstruct { mDNSu16 priority; mDNSu16 weight; mDNSIPPort port; domainname target;   } rdataSRV;
7615ffb0c9bSToomas Soome typedef packedstruct { mDNSu16 preference;                                domainname exchange; } rdataMX;
7625ffb0c9bSToomas Soome typedef packedstruct { domainname mbox; domainname txt;                                        } rdataRP;
7635ffb0c9bSToomas Soome typedef packedstruct { mDNSu16 preference; domainname map822; domainname mapx400;              } rdataPX;
7645ffb0c9bSToomas Soome 
7655ffb0c9bSToomas Soome typedef packedstruct
7665ffb0c9bSToomas Soome {
7675ffb0c9bSToomas Soome     domainname mname;
7685ffb0c9bSToomas Soome     domainname rname;
7695ffb0c9bSToomas Soome     mDNSs32 serial;     // Modular counter; increases when zone changes
7705ffb0c9bSToomas Soome     mDNSu32 refresh;    // Time in seconds that a slave waits after successful replication of the database before it attempts replication again
7715ffb0c9bSToomas Soome     mDNSu32 retry;      // Time in seconds that a slave waits after an unsuccessful replication attempt before it attempts replication again
7725ffb0c9bSToomas Soome     mDNSu32 expire;     // Time in seconds that a slave holds on to old data while replication attempts remain unsuccessful
7735ffb0c9bSToomas Soome     mDNSu32 min;        // Nominally the minimum record TTL for this zone, in seconds; also used for negative caching.
7745ffb0c9bSToomas Soome } rdataSOA;
7755ffb0c9bSToomas Soome 
7765ffb0c9bSToomas Soome // http://www.iana.org/assignments/dns-sec-alg-numbers/dns-sec-alg-numbers.xhtml
7775ffb0c9bSToomas Soome // Algorithm used for RRSIG, DS and DNS KEY
7785ffb0c9bSToomas Soome #define CRYPTO_RSA_SHA1             0x05
7795ffb0c9bSToomas Soome #define CRYPTO_DSA_NSEC3_SHA1       0x06
7805ffb0c9bSToomas Soome #define CRYPTO_RSA_NSEC3_SHA1       0x07
7815ffb0c9bSToomas Soome #define CRYPTO_RSA_SHA256           0x08
7825ffb0c9bSToomas Soome #define CRYPTO_RSA_SHA512           0x0A
7835ffb0c9bSToomas Soome 
7845ffb0c9bSToomas Soome #define CRYPTO_ALG_MAX              0x0B
7855ffb0c9bSToomas Soome 
7865ffb0c9bSToomas Soome // alg - same as in RRSIG, DNS KEY or DS.
7875ffb0c9bSToomas Soome // RFC 4034 defines SHA1
7885ffb0c9bSToomas Soome // RFC 4509 defines SHA256
7895ffb0c9bSToomas Soome // Note: NSEC3 also uses 1 for SHA1 and hence we will reuse for now till a new
7905ffb0c9bSToomas Soome // value is assigned.
7915ffb0c9bSToomas Soome //
7925ffb0c9bSToomas Soome #define SHA1_DIGEST_TYPE        1
7935ffb0c9bSToomas Soome #define SHA256_DIGEST_TYPE      2
7945ffb0c9bSToomas Soome #define DIGEST_TYPE_MAX         3
7955ffb0c9bSToomas Soome 
7965ffb0c9bSToomas Soome // We need support for base64 and base32 encoding for displaying KEY, NSEC3
7975ffb0c9bSToomas Soome // To make this platform agnostic, we define two types which the platform
7985ffb0c9bSToomas Soome // needs to support
7995ffb0c9bSToomas Soome #define ENC_BASE32              1
8005ffb0c9bSToomas Soome #define ENC_BASE64              2
8015ffb0c9bSToomas Soome #define ENC_ALG_MAX             3
8025ffb0c9bSToomas Soome 
8035ffb0c9bSToomas Soome #define DS_FIXED_SIZE           4
8045ffb0c9bSToomas Soome typedef packedstruct
8055ffb0c9bSToomas Soome {
8065ffb0c9bSToomas Soome     mDNSu16 keyTag;
8075ffb0c9bSToomas Soome     mDNSu8 alg;
8085ffb0c9bSToomas Soome     mDNSu8 digestType;
8095ffb0c9bSToomas Soome     mDNSu8  *digest;
8105ffb0c9bSToomas Soome } rdataDS;
8115ffb0c9bSToomas Soome 
8125ffb0c9bSToomas Soome typedef struct TrustAnchor
8135ffb0c9bSToomas Soome {
8145ffb0c9bSToomas Soome     struct TrustAnchor *next;
8155ffb0c9bSToomas Soome     int digestLen;
8165ffb0c9bSToomas Soome     mDNSu32 validFrom;
817*c65ebfc7SToomas Soome     mDNSu32 validUntil;
8185ffb0c9bSToomas Soome     domainname zone;
8195ffb0c9bSToomas Soome     rdataDS rds;
8205ffb0c9bSToomas Soome } TrustAnchor;
8215ffb0c9bSToomas Soome 
8225ffb0c9bSToomas Soome //size of rdataRRSIG excluding signerName and signature (which are variable fields)
8235ffb0c9bSToomas Soome #define RRSIG_FIXED_SIZE      18
824*c65ebfc7SToomas Soome typedef struct
8255ffb0c9bSToomas Soome {
8265ffb0c9bSToomas Soome     mDNSu16 typeCovered;
8275ffb0c9bSToomas Soome     mDNSu8 alg;
8285ffb0c9bSToomas Soome     mDNSu8 labels;
8295ffb0c9bSToomas Soome     mDNSu32 origTTL;
8305ffb0c9bSToomas Soome     mDNSu32 sigExpireTime;
8315ffb0c9bSToomas Soome     mDNSu32 sigInceptTime;
8325ffb0c9bSToomas Soome     mDNSu16 keyTag;
833*c65ebfc7SToomas Soome     mDNSu8  signerName[1]; // signerName is a dynamically-sized array
8345ffb0c9bSToomas Soome     // mDNSu8 *signature
8355ffb0c9bSToomas Soome } rdataRRSig;
8365ffb0c9bSToomas Soome 
8375ffb0c9bSToomas Soome // RFC 4034: For DNS Key RR
8385ffb0c9bSToomas Soome // flags - the valid value for DNSSEC is 256 (Zone signing key - ZSK) and 257 (Secure Entry Point) which also
8395ffb0c9bSToomas Soome // includes the ZSK bit
8405ffb0c9bSToomas Soome //
8415ffb0c9bSToomas Soome #define DNSKEY_ZONE_SIGN_KEY        0x100
8425ffb0c9bSToomas Soome #define DNSKEY_SECURE_ENTRY_POINT   0x101
8435ffb0c9bSToomas Soome 
8445ffb0c9bSToomas Soome // proto - the only valid value for protocol is 3 (See RFC 4034)
8455ffb0c9bSToomas Soome #define DNSKEY_VALID_PROTO_VALUE    0x003
8465ffb0c9bSToomas Soome 
8475ffb0c9bSToomas Soome // alg - The only mandatory algorithm that we support is RSA/SHA-1
8485ffb0c9bSToomas Soome // DNSSEC_RSA_SHA1_ALG
8495ffb0c9bSToomas Soome 
8505ffb0c9bSToomas Soome #define DNSKEY_FIXED_SIZE          4
8515ffb0c9bSToomas Soome typedef packedstruct
8525ffb0c9bSToomas Soome {
8535ffb0c9bSToomas Soome     mDNSu16 flags;
8545ffb0c9bSToomas Soome     mDNSu8 proto;
8555ffb0c9bSToomas Soome     mDNSu8 alg;
8565ffb0c9bSToomas Soome     mDNSu8  *data;
8575ffb0c9bSToomas Soome } rdataDNSKey;
8585ffb0c9bSToomas Soome 
8595ffb0c9bSToomas Soome #define NSEC3_FIXED_SIZE          5
8605ffb0c9bSToomas Soome #define NSEC3_FLAGS_OPTOUT        1
8615ffb0c9bSToomas Soome #define NSEC3_MAX_ITERATIONS      2500
8625ffb0c9bSToomas Soome typedef packedstruct
8635ffb0c9bSToomas Soome {
8645ffb0c9bSToomas Soome     mDNSu8 alg;
8655ffb0c9bSToomas Soome     mDNSu8 flags;
8665ffb0c9bSToomas Soome     mDNSu16 iterations;
8675ffb0c9bSToomas Soome     mDNSu8 saltLength;
8685ffb0c9bSToomas Soome     mDNSu8 *salt;
8695ffb0c9bSToomas Soome     // hashLength, nxt, bitmap
8705ffb0c9bSToomas Soome } rdataNSEC3;
8715ffb0c9bSToomas Soome 
8725ffb0c9bSToomas Soome // In the multicast usage of NSEC3, we know the actual size of RData
8735ffb0c9bSToomas Soome // 4 bytes : HashAlg, Flags,Iterations
8745ffb0c9bSToomas Soome // 5 bytes : Salt Length 1 byte, Salt 4 bytes
8755ffb0c9bSToomas Soome // 21 bytes : HashLength 1 byte, Hash 20 bytes
8765ffb0c9bSToomas Soome // 34 bytes : Window number, Bitmap length, Type bit map to include the first 256 types
8775ffb0c9bSToomas Soome #define MCAST_NSEC3_RDLENGTH (4 + 5 + 21 + 34)
8785ffb0c9bSToomas Soome #define SHA1_HASH_LENGTH 20
8795ffb0c9bSToomas Soome 
8805ffb0c9bSToomas Soome // Base32 encoding takes 5 bytes of the input and encodes as 8 bytes of output.
8815ffb0c9bSToomas Soome // For example, SHA-1 hash of 20 bytes will be encoded as 20/5 * 8 = 32 base32
8825ffb0c9bSToomas Soome // bytes. For a max domain name size of 255 bytes of base32 encoding : (255/8)*5
8835ffb0c9bSToomas Soome // is the max hash length possible.
884*c65ebfc7SToomas Soome #define NSEC3_MAX_HASH_LEN  155
8855ffb0c9bSToomas Soome // In NSEC3, the names are hashed and stored in the first label and hence cannot exceed label
8865ffb0c9bSToomas Soome // size.
887*c65ebfc7SToomas Soome #define NSEC3_MAX_B32_LEN   MAX_DOMAIN_LABEL
8885ffb0c9bSToomas Soome 
8895ffb0c9bSToomas Soome // We define it here instead of dnssec.h so that these values can be used
8905ffb0c9bSToomas Soome // in files without bringing in all of dnssec.h unnecessarily.
8915ffb0c9bSToomas Soome typedef enum
8925ffb0c9bSToomas Soome {
8935ffb0c9bSToomas Soome     DNSSEC_Secure = 1,      // Securely validated and has a chain up to the trust anchor
8945ffb0c9bSToomas Soome     DNSSEC_Insecure,        // Cannot build a chain up to the trust anchor
8955ffb0c9bSToomas Soome     DNSSEC_Indeterminate,   // Not used currently
8965ffb0c9bSToomas Soome     DNSSEC_Bogus,           // failed to validate signatures
8975ffb0c9bSToomas Soome     DNSSEC_NoResponse       // No DNSSEC records to start with
8985ffb0c9bSToomas Soome } DNSSECStatus;
8995ffb0c9bSToomas Soome 
9005ffb0c9bSToomas Soome #define DNSSECRecordType(rrtype) (((rrtype) == kDNSType_RRSIG) || ((rrtype) == kDNSType_NSEC) || ((rrtype) == kDNSType_DNSKEY) || ((rrtype) == kDNSType_DS) || \
9015ffb0c9bSToomas Soome                                   ((rrtype) == kDNSType_NSEC3))
9025ffb0c9bSToomas Soome 
9035ffb0c9bSToomas Soome typedef enum
9045ffb0c9bSToomas Soome {
905*c65ebfc7SToomas Soome     platform_OSX = 1,   // OSX Platform
906*c65ebfc7SToomas Soome     platform_iOS,       // iOS Platform
907*c65ebfc7SToomas Soome     platform_Atv,       // Atv Platform
9085ffb0c9bSToomas Soome     platform_NonApple   // Non-Apple (Windows, POSIX) Platform
9095ffb0c9bSToomas Soome } Platform_t;
9105ffb0c9bSToomas Soome 
9115ffb0c9bSToomas Soome // EDNS Option Code registrations are recorded in the "DNS EDNS0 Options" section of
9125ffb0c9bSToomas Soome // <http://www.iana.org/assignments/dns-parameters>
9135ffb0c9bSToomas Soome 
9145ffb0c9bSToomas Soome #define kDNSOpt_LLQ   1
9155ffb0c9bSToomas Soome #define kDNSOpt_Lease 2
9165ffb0c9bSToomas Soome #define kDNSOpt_NSID  3
9175ffb0c9bSToomas Soome #define kDNSOpt_Owner 4
918*c65ebfc7SToomas Soome #define kDNSOpt_Trace 65001  // 65001-65534 Reserved for Local/Experimental Use
9195ffb0c9bSToomas Soome 
9205ffb0c9bSToomas Soome typedef struct
9215ffb0c9bSToomas Soome {
9225ffb0c9bSToomas Soome     mDNSu16 vers;
9235ffb0c9bSToomas Soome     mDNSu16 llqOp;
9245ffb0c9bSToomas Soome     mDNSu16 err;        // Or UDP reply port, in setup request
9255ffb0c9bSToomas 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
9265ffb0c9bSToomas Soome     mDNSOpaque64 id;
9275ffb0c9bSToomas Soome     mDNSu32 llqlease;
9285ffb0c9bSToomas Soome } LLQOptData;
9295ffb0c9bSToomas Soome 
9305ffb0c9bSToomas Soome typedef struct
9315ffb0c9bSToomas Soome {
9325ffb0c9bSToomas Soome     mDNSu8 vers;            // Version number of this Owner OPT record
9335ffb0c9bSToomas Soome     mDNSs8 seq;             // Sleep/wake epoch
9345ffb0c9bSToomas Soome     mDNSEthAddr HMAC;       // Host's primary identifier (e.g. MAC of on-board Ethernet)
9355ffb0c9bSToomas Soome     mDNSEthAddr IMAC;       // Interface's MAC address (if different to primary MAC)
9365ffb0c9bSToomas Soome     mDNSOpaque48 password;  // Optional password
9375ffb0c9bSToomas Soome } OwnerOptData;
9385ffb0c9bSToomas Soome 
9395ffb0c9bSToomas Soome typedef struct
9405ffb0c9bSToomas Soome {
9415ffb0c9bSToomas Soome     mDNSu8    platf;      // Running platform (see enum Platform_t)
9425ffb0c9bSToomas Soome     mDNSu32   mDNSv;      // mDNSResponder Version (DNS_SD_H defined in dns_sd.h)
9435ffb0c9bSToomas Soome } TracerOptData;
9445ffb0c9bSToomas Soome 
9455ffb0c9bSToomas Soome // Note: rdataOPT format may be repeated an arbitrary number of times in a single resource record
946*c65ebfc7SToomas Soome typedef struct
9475ffb0c9bSToomas Soome {
9485ffb0c9bSToomas Soome     mDNSu16 opt;
9495ffb0c9bSToomas Soome     mDNSu16 optlen;
9505ffb0c9bSToomas Soome     union { LLQOptData llq; mDNSu32 updatelease; OwnerOptData owner; TracerOptData tracer; } u;
9515ffb0c9bSToomas Soome } rdataOPT;
9525ffb0c9bSToomas Soome 
9535ffb0c9bSToomas Soome // Space needed to put OPT records into a packet:
9545ffb0c9bSToomas Soome // Header         11  bytes (name 1, type 2, class 2, TTL 4, length 2)
9555ffb0c9bSToomas Soome // LLQ   rdata    18  bytes (opt 2, len 2, vers 2, op 2, err 2, id 8, lease 4)
9565ffb0c9bSToomas Soome // Lease rdata     8  bytes (opt 2, len 2, lease 4)
9575ffb0c9bSToomas Soome // Owner rdata 12-24  bytes (opt 2, len 2, owner 8-20)
9585ffb0c9bSToomas Soome // Trace rdata     9  bytes (opt 2, len 2, platf 1, mDNSv 4)
9595ffb0c9bSToomas Soome 
9605ffb0c9bSToomas Soome 
9615ffb0c9bSToomas Soome #define DNSOpt_Header_Space                 11
9625ffb0c9bSToomas Soome #define DNSOpt_LLQData_Space               (4 + 2 + 2 + 2 + 8 + 4)
9635ffb0c9bSToomas Soome #define DNSOpt_LeaseData_Space             (4 + 4)
9645ffb0c9bSToomas Soome #define DNSOpt_OwnerData_ID_Space          (4 + 2 + 6)
9655ffb0c9bSToomas Soome #define DNSOpt_OwnerData_ID_Wake_Space     (4 + 2 + 6 + 6)
9665ffb0c9bSToomas Soome #define DNSOpt_OwnerData_ID_Wake_PW4_Space (4 + 2 + 6 + 6 + 4)
9675ffb0c9bSToomas Soome #define DNSOpt_OwnerData_ID_Wake_PW6_Space (4 + 2 + 6 + 6 + 6)
9685ffb0c9bSToomas Soome #define DNSOpt_TraceData_Space             (4 + 1 + 4)
9695ffb0c9bSToomas Soome 
9705ffb0c9bSToomas Soome #define ValidOwnerLength(X) (   (X) == DNSOpt_OwnerData_ID_Space          - 4 || \
9715ffb0c9bSToomas Soome                                 (X) == DNSOpt_OwnerData_ID_Wake_Space     - 4 || \
9725ffb0c9bSToomas Soome                                 (X) == DNSOpt_OwnerData_ID_Wake_PW4_Space - 4 || \
9735ffb0c9bSToomas Soome                                 (X) == DNSOpt_OwnerData_ID_Wake_PW6_Space - 4    )
9745ffb0c9bSToomas Soome 
9755ffb0c9bSToomas Soome #define DNSOpt_Owner_Space(A,B) (mDNSSameEthAddress((A),(B)) ? DNSOpt_OwnerData_ID_Space : DNSOpt_OwnerData_ID_Wake_Space)
9765ffb0c9bSToomas Soome 
9775ffb0c9bSToomas Soome #define DNSOpt_Data_Space(O) (                                  \
9785ffb0c9bSToomas Soome         (O)->opt == kDNSOpt_LLQ   ? DNSOpt_LLQData_Space   :        \
9795ffb0c9bSToomas Soome         (O)->opt == kDNSOpt_Lease ? DNSOpt_LeaseData_Space :        \
9805ffb0c9bSToomas Soome         (O)->opt == kDNSOpt_Trace ? DNSOpt_TraceData_Space :        \
9815ffb0c9bSToomas Soome         (O)->opt == kDNSOpt_Owner ? DNSOpt_Owner_Space(&(O)->u.owner.HMAC, &(O)->u.owner.IMAC) : 0x10000)
9825ffb0c9bSToomas Soome 
9835ffb0c9bSToomas Soome // NSEC record is defined in RFC 4034.
9845ffb0c9bSToomas Soome // 16 bit RRTYPE space is split into 256 windows and each window has 256 bits (32 bytes).
9855ffb0c9bSToomas Soome // If we create a structure for NSEC, it's size would be:
9865ffb0c9bSToomas Soome //
9875ffb0c9bSToomas Soome //   256 bytes domainname 'nextname'
9885ffb0c9bSToomas Soome // + 256 * 34 = 8704 bytes of bitmap data
9895ffb0c9bSToomas Soome // = 8960 bytes total
9905ffb0c9bSToomas Soome //
9915ffb0c9bSToomas Soome // This would be a waste, as types about 256 are not very common. But it would be odd, if we receive
9925ffb0c9bSToomas Soome // a type above 256 (.US zone had TYPE65534 when this code was written) and not able to handle it.
9935ffb0c9bSToomas Soome // Hence, we handle any size by not fixing a strucure in place. The following is just a placeholder
9945ffb0c9bSToomas Soome // and never used anywhere.
9955ffb0c9bSToomas Soome //
9965ffb0c9bSToomas Soome #define NSEC_MCAST_WINDOW_SIZE 32
9975ffb0c9bSToomas Soome typedef struct
9985ffb0c9bSToomas Soome {
9995ffb0c9bSToomas Soome     domainname *next; //placeholders are uncommented because C89 in Windows requires that a struct has at least a member.
10005ffb0c9bSToomas Soome     char bitmap[32];
10015ffb0c9bSToomas Soome } rdataNSEC;
10025ffb0c9bSToomas Soome 
10035ffb0c9bSToomas Soome // StandardAuthRDSize is 264 (256+8), which is large enough to hold a maximum-sized SRV record (6 + 256 bytes)
10045ffb0c9bSToomas Soome // MaximumRDSize is 8K the absolute maximum we support (at least for now)
10055ffb0c9bSToomas Soome #define StandardAuthRDSize 264
10065ffb0c9bSToomas Soome #ifndef MaximumRDSize
10075ffb0c9bSToomas Soome #define MaximumRDSize 8192
10085ffb0c9bSToomas Soome #endif
10095ffb0c9bSToomas Soome 
10105ffb0c9bSToomas Soome // InlineCacheRDSize is 68
10115ffb0c9bSToomas Soome // Records received from the network with rdata this size or less have their rdata stored right in the CacheRecord object
10125ffb0c9bSToomas Soome // Records received from the network with rdata larger than this have additional storage allocated for the rdata
10135ffb0c9bSToomas Soome // A quick unscientific sample from a busy network at Apple with lots of machines revealed this:
10145ffb0c9bSToomas Soome // 1461 records in cache
10155ffb0c9bSToomas Soome // 292 were one-byte TXT records
10165ffb0c9bSToomas Soome // 136 were four-byte A records
10175ffb0c9bSToomas Soome // 184 were sixteen-byte AAAA records
10185ffb0c9bSToomas Soome // 780 were various PTR, TXT and SRV records from 12-64 bytes
10195ffb0c9bSToomas Soome // Only 69 records had rdata bigger than 64 bytes
10205ffb0c9bSToomas Soome // Note that since CacheRecord object and a CacheGroup object are allocated out of the same pool, it's sensible to
10215ffb0c9bSToomas Soome // have them both be the same size. Making one smaller without making the other smaller won't actually save any memory.
10225ffb0c9bSToomas Soome #define InlineCacheRDSize 68
10235ffb0c9bSToomas Soome 
10245ffb0c9bSToomas Soome // The RDataBody union defines the common rdata types that fit into our 264-byte limit
10255ffb0c9bSToomas Soome typedef union
10265ffb0c9bSToomas Soome {
10275ffb0c9bSToomas Soome     mDNSu8 data[StandardAuthRDSize];
10285ffb0c9bSToomas Soome     mDNSv4Addr ipv4;        // For 'A' record
10295ffb0c9bSToomas Soome     domainname name;        // For PTR, NS, CNAME, DNAME
10305ffb0c9bSToomas Soome     UTF8str255 txt;
10315ffb0c9bSToomas Soome     rdataMX mx;
10325ffb0c9bSToomas Soome     mDNSv6Addr ipv6;        // For 'AAAA' record
10335ffb0c9bSToomas Soome     rdataSRV srv;
10345ffb0c9bSToomas Soome     rdataOPT opt[2];        // For EDNS0 OPT record; RDataBody may contain multiple variable-length rdataOPT objects packed together
10355ffb0c9bSToomas Soome } RDataBody;
10365ffb0c9bSToomas Soome 
10375ffb0c9bSToomas Soome // The RDataBody2 union is the same as above, except it includes fields for the larger types like soa, rp, px
10385ffb0c9bSToomas Soome typedef union
10395ffb0c9bSToomas Soome {
10405ffb0c9bSToomas Soome     mDNSu8 data[StandardAuthRDSize];
10415ffb0c9bSToomas Soome     mDNSv4Addr ipv4;        // For 'A' record
10425ffb0c9bSToomas Soome     domainname name;        // For PTR, NS, CNAME, DNAME
10435ffb0c9bSToomas Soome     rdataSOA soa;           // This is large; not included in the normal RDataBody definition
10445ffb0c9bSToomas Soome     UTF8str255 txt;
10455ffb0c9bSToomas Soome     rdataMX mx;
10465ffb0c9bSToomas Soome     rdataRP rp;             // This is large; not included in the normal RDataBody definition
10475ffb0c9bSToomas Soome     rdataPX px;             // This is large; not included in the normal RDataBody definition
10485ffb0c9bSToomas Soome     mDNSv6Addr ipv6;        // For 'AAAA' record
10495ffb0c9bSToomas Soome     rdataSRV srv;
10505ffb0c9bSToomas Soome     rdataOPT opt[2];        // For EDNS0 OPT record; RDataBody may contain multiple variable-length rdataOPT objects packed together
10515ffb0c9bSToomas Soome     rdataDS ds;
10525ffb0c9bSToomas Soome     rdataDNSKey key;
10535ffb0c9bSToomas Soome     rdataRRSig rrsig;
10545ffb0c9bSToomas Soome } RDataBody2;
10555ffb0c9bSToomas Soome 
10565ffb0c9bSToomas Soome typedef struct
10575ffb0c9bSToomas Soome {
10585ffb0c9bSToomas Soome     mDNSu16 MaxRDLength;    // Amount of storage allocated for rdata (usually sizeof(RDataBody))
10595ffb0c9bSToomas Soome     mDNSu16 padding;        // So that RDataBody is aligned on 32-bit boundary
10605ffb0c9bSToomas Soome     RDataBody u;
10615ffb0c9bSToomas Soome } RData;
10625ffb0c9bSToomas Soome 
10635ffb0c9bSToomas Soome // sizeofRDataHeader should be 4 bytes
10645ffb0c9bSToomas Soome #define sizeofRDataHeader (sizeof(RData) - sizeof(RDataBody))
10655ffb0c9bSToomas Soome 
10665ffb0c9bSToomas Soome // RData_small is a smaller version of the RData object, used for inline data storage embedded in a CacheRecord_struct
10675ffb0c9bSToomas Soome typedef struct
10685ffb0c9bSToomas Soome {
10695ffb0c9bSToomas Soome     mDNSu16 MaxRDLength;    // Storage allocated for data (may be greater than InlineCacheRDSize if additional storage follows this object)
10705ffb0c9bSToomas Soome     mDNSu16 padding;        // So that data is aligned on 32-bit boundary
10715ffb0c9bSToomas Soome     mDNSu8 data[InlineCacheRDSize];
10725ffb0c9bSToomas Soome } RData_small;
10735ffb0c9bSToomas Soome 
10745ffb0c9bSToomas Soome // Note: Within an mDNSRecordCallback mDNS all API calls are legal except mDNS_Init(), mDNS_Exit(), mDNS_Execute()
10755ffb0c9bSToomas Soome typedef void mDNSRecordCallback (mDNS *const m, AuthRecord *const rr, mStatus result);
10765ffb0c9bSToomas Soome 
10775ffb0c9bSToomas Soome // Note:
10785ffb0c9bSToomas Soome // Restrictions: An mDNSRecordUpdateCallback may not make any mDNS API calls.
10795ffb0c9bSToomas Soome // The intent of this callback is to allow the client to free memory, if necessary.
10805ffb0c9bSToomas Soome // The internal data structures of the mDNS code may not be in a state where mDNS API calls may be made safely.
10815ffb0c9bSToomas Soome typedef void mDNSRecordUpdateCallback (mDNS *const m, AuthRecord *const rr, RData *OldRData, mDNSu16 OldRDLen);
10825ffb0c9bSToomas Soome 
10835ffb0c9bSToomas Soome // ***************************************************************************
10845ffb0c9bSToomas Soome #if 0
10855ffb0c9bSToomas Soome #pragma mark -
10865ffb0c9bSToomas Soome #pragma mark - NAT Traversal structures and constants
10875ffb0c9bSToomas Soome #endif
10885ffb0c9bSToomas Soome 
10895ffb0c9bSToomas Soome #define NATMAP_MAX_RETRY_INTERVAL    ((mDNSPlatformOneSecond * 60) * 15)    // Max retry interval is 15 minutes
10905ffb0c9bSToomas Soome #define NATMAP_MIN_RETRY_INTERVAL     (mDNSPlatformOneSecond * 2)           // Min retry interval is 2 seconds
10915ffb0c9bSToomas Soome #define NATMAP_INIT_RETRY             (mDNSPlatformOneSecond / 4)           // start at 250ms w/ exponential decay
10925ffb0c9bSToomas Soome #define NATMAP_DEFAULT_LEASE          (60 * 60 * 2)                         // 2 hour lease life in seconds
10935ffb0c9bSToomas Soome #define NATMAP_VERS 0
10945ffb0c9bSToomas Soome 
10955ffb0c9bSToomas Soome typedef enum
10965ffb0c9bSToomas Soome {
10975ffb0c9bSToomas Soome     NATOp_AddrRequest    = 0,
10985ffb0c9bSToomas Soome     NATOp_MapUDP         = 1,
10995ffb0c9bSToomas Soome     NATOp_MapTCP         = 2,
11005ffb0c9bSToomas Soome 
11015ffb0c9bSToomas Soome     NATOp_AddrResponse   = 0x80 | 0,
11025ffb0c9bSToomas Soome     NATOp_MapUDPResponse = 0x80 | 1,
11035ffb0c9bSToomas Soome     NATOp_MapTCPResponse = 0x80 | 2,
11045ffb0c9bSToomas Soome } NATOp_t;
11055ffb0c9bSToomas Soome 
11065ffb0c9bSToomas Soome enum
11075ffb0c9bSToomas Soome {
11085ffb0c9bSToomas Soome     NATErr_None    = 0,
11095ffb0c9bSToomas Soome     NATErr_Vers    = 1,
11105ffb0c9bSToomas Soome     NATErr_Refused = 2,
11115ffb0c9bSToomas Soome     NATErr_NetFail = 3,
11125ffb0c9bSToomas Soome     NATErr_Res     = 4,
11135ffb0c9bSToomas Soome     NATErr_Opcode  = 5
11145ffb0c9bSToomas Soome };
11155ffb0c9bSToomas Soome 
11165ffb0c9bSToomas Soome typedef mDNSu16 NATErr_t;
11175ffb0c9bSToomas Soome 
11185ffb0c9bSToomas Soome typedef packedstruct
11195ffb0c9bSToomas Soome {
11205ffb0c9bSToomas Soome     mDNSu8 vers;
11215ffb0c9bSToomas Soome     mDNSu8 opcode;
11225ffb0c9bSToomas Soome } NATAddrRequest;
11235ffb0c9bSToomas Soome 
11245ffb0c9bSToomas Soome typedef packedstruct
11255ffb0c9bSToomas Soome {
11265ffb0c9bSToomas Soome     mDNSu8 vers;
11275ffb0c9bSToomas Soome     mDNSu8 opcode;
11285ffb0c9bSToomas Soome     mDNSu16 err;
11295ffb0c9bSToomas Soome     mDNSu32 upseconds;          // Time since last NAT engine reboot, in seconds
11305ffb0c9bSToomas Soome     mDNSv4Addr ExtAddr;
11315ffb0c9bSToomas Soome } NATAddrReply;
11325ffb0c9bSToomas Soome 
11335ffb0c9bSToomas Soome typedef packedstruct
11345ffb0c9bSToomas Soome {
11355ffb0c9bSToomas Soome     mDNSu8 vers;
11365ffb0c9bSToomas Soome     mDNSu8 opcode;
11375ffb0c9bSToomas Soome     mDNSOpaque16 unused;
11385ffb0c9bSToomas Soome     mDNSIPPort intport;
11395ffb0c9bSToomas Soome     mDNSIPPort extport;
11405ffb0c9bSToomas Soome     mDNSu32 NATReq_lease;
11415ffb0c9bSToomas Soome } NATPortMapRequest;
11424b22b933Srs 
11435ffb0c9bSToomas Soome typedef packedstruct
11445ffb0c9bSToomas Soome {
11455ffb0c9bSToomas Soome     mDNSu8 vers;
11465ffb0c9bSToomas Soome     mDNSu8 opcode;
11475ffb0c9bSToomas Soome     mDNSu16 err;
11485ffb0c9bSToomas Soome     mDNSu32 upseconds;          // Time since last NAT engine reboot, in seconds
11495ffb0c9bSToomas Soome     mDNSIPPort intport;
11505ffb0c9bSToomas Soome     mDNSIPPort extport;
11515ffb0c9bSToomas Soome     mDNSu32 NATRep_lease;
11525ffb0c9bSToomas Soome } NATPortMapReply;
11534b22b933Srs 
11545ffb0c9bSToomas Soome // PCP Support for IPv4 mappings
11554b22b933Srs 
11565ffb0c9bSToomas Soome #define PCP_VERS 0x02
11575ffb0c9bSToomas Soome #define PCP_WAITSECS_AFTER_EPOCH_INVALID 5
11584b22b933Srs 
11595ffb0c9bSToomas Soome typedef enum
11605ffb0c9bSToomas Soome {
11615ffb0c9bSToomas Soome     PCPOp_Announce = 0,
11625ffb0c9bSToomas Soome     PCPOp_Map      = 1
11635ffb0c9bSToomas Soome } PCPOp_t;
11644b22b933Srs 
11655ffb0c9bSToomas Soome typedef enum
11665ffb0c9bSToomas Soome {
11675ffb0c9bSToomas Soome     PCPProto_All = 0,
11685ffb0c9bSToomas Soome     PCPProto_TCP = 6,
11695ffb0c9bSToomas Soome     PCPProto_UDP = 17
11705ffb0c9bSToomas Soome } PCPProto_t;
11714b22b933Srs 
11725ffb0c9bSToomas Soome typedef enum
11735ffb0c9bSToomas Soome {
11745ffb0c9bSToomas Soome     PCPResult_Success         = 0,
11755ffb0c9bSToomas Soome     PCPResult_UnsuppVersion   = 1,
11765ffb0c9bSToomas Soome     PCPResult_NotAuthorized   = 2,
11775ffb0c9bSToomas Soome     PCPResult_MalformedReq    = 3,
11785ffb0c9bSToomas Soome     PCPResult_UnsuppOpcode    = 4,
11795ffb0c9bSToomas Soome     PCPResult_UnsuppOption    = 5,
11805ffb0c9bSToomas Soome     PCPResult_MalformedOption = 6,
11815ffb0c9bSToomas Soome     PCPResult_NetworkFailure  = 7,
11825ffb0c9bSToomas Soome     PCPResult_NoResources     = 8,
11835ffb0c9bSToomas Soome     PCPResult_UnsuppProtocol  = 9,
11845ffb0c9bSToomas Soome     PCPResult_UserExQuota     = 10,
11855ffb0c9bSToomas Soome     PCPResult_CantProvideExt  = 11,
11865ffb0c9bSToomas Soome     PCPResult_AddrMismatch    = 12,
11875ffb0c9bSToomas Soome     PCPResult_ExcesRemotePeer = 13
11885ffb0c9bSToomas Soome } PCPResult_t;
11894b22b933Srs 
1190*c65ebfc7SToomas Soome typedef struct
11915ffb0c9bSToomas Soome {
11925ffb0c9bSToomas Soome     mDNSu8       version;
11935ffb0c9bSToomas Soome     mDNSu8       opCode;
11945ffb0c9bSToomas Soome     mDNSOpaque16 reserved;
11955ffb0c9bSToomas Soome     mDNSu32      lifetime;
11965ffb0c9bSToomas Soome     mDNSv6Addr   clientAddr;
11975ffb0c9bSToomas Soome     mDNSu32      nonce[3];
11985ffb0c9bSToomas Soome     mDNSu8       protocol;
11995ffb0c9bSToomas Soome     mDNSu8       reservedMapOp[3];
12005ffb0c9bSToomas Soome     mDNSIPPort   intPort;
12015ffb0c9bSToomas Soome     mDNSIPPort   extPort;
12025ffb0c9bSToomas Soome     mDNSv6Addr   extAddress;
12035ffb0c9bSToomas Soome } PCPMapRequest;
12044b22b933Srs 
1205*c65ebfc7SToomas Soome typedef struct
12065ffb0c9bSToomas Soome {
12075ffb0c9bSToomas Soome     mDNSu8     version;
12085ffb0c9bSToomas Soome     mDNSu8     opCode;
12095ffb0c9bSToomas Soome     mDNSu8     reserved;
12105ffb0c9bSToomas Soome     mDNSu8     result;
12115ffb0c9bSToomas Soome     mDNSu32    lifetime;
12125ffb0c9bSToomas Soome     mDNSu32    epoch;
12135ffb0c9bSToomas Soome     mDNSu32    clientAddrParts[3];
12145ffb0c9bSToomas Soome     mDNSu32    nonce[3];
12155ffb0c9bSToomas Soome     mDNSu8     protocol;
12165ffb0c9bSToomas Soome     mDNSu8     reservedMapOp[3];
12175ffb0c9bSToomas Soome     mDNSIPPort intPort;
12185ffb0c9bSToomas Soome     mDNSIPPort extPort;
12195ffb0c9bSToomas Soome     mDNSv6Addr extAddress;
12205ffb0c9bSToomas Soome } PCPMapReply;
12215ffb0c9bSToomas Soome 
12225ffb0c9bSToomas Soome // LNT Support
12234b22b933Srs 
12245ffb0c9bSToomas Soome typedef enum
12255ffb0c9bSToomas Soome {
12265ffb0c9bSToomas Soome     LNTDiscoveryOp      = 1,
12275ffb0c9bSToomas Soome     LNTExternalAddrOp   = 2,
12285ffb0c9bSToomas Soome     LNTPortMapOp        = 3,
12295ffb0c9bSToomas Soome     LNTPortMapDeleteOp  = 4
12305ffb0c9bSToomas Soome } LNTOp_t;
12315ffb0c9bSToomas Soome 
12325ffb0c9bSToomas Soome #define LNT_MAXBUFSIZE 8192
12335ffb0c9bSToomas Soome typedef struct tcpLNTInfo_struct tcpLNTInfo;
12345ffb0c9bSToomas Soome struct tcpLNTInfo_struct
12355ffb0c9bSToomas Soome {
12365ffb0c9bSToomas Soome     tcpLNTInfo       *next;
12375ffb0c9bSToomas Soome     mDNS             *m;
12385ffb0c9bSToomas Soome     NATTraversalInfo *parentNATInfo;    // pointer back to the parent NATTraversalInfo
12395ffb0c9bSToomas Soome     TCPSocket        *sock;
12405ffb0c9bSToomas Soome     LNTOp_t op;                         // operation performed using this connection
12415ffb0c9bSToomas Soome     mDNSAddr Address;                   // router address
12425ffb0c9bSToomas Soome     mDNSIPPort Port;                    // router port
12435ffb0c9bSToomas Soome     mDNSu8           *Request;          // xml request to router
12445ffb0c9bSToomas Soome     int requestLen;
12455ffb0c9bSToomas Soome     mDNSu8           *Reply;            // xml reply from router
12465ffb0c9bSToomas Soome     int replyLen;
12475ffb0c9bSToomas Soome     unsigned long nread;                // number of bytes read so far
12485ffb0c9bSToomas Soome     int retries;                        // number of times we've tried to do this port mapping
12495ffb0c9bSToomas Soome };
12505ffb0c9bSToomas Soome 
12515ffb0c9bSToomas Soome typedef void (*NATTraversalClientCallback)(mDNS *m, NATTraversalInfo *n);
12525ffb0c9bSToomas Soome 
12535ffb0c9bSToomas Soome // if m->timenow <  ExpiryTime then we have an active mapping, and we'll renew halfway to expiry
12545ffb0c9bSToomas Soome // if m->timenow >= ExpiryTime then our mapping has expired, and we're trying to create one
12554b22b933Srs 
12565ffb0c9bSToomas Soome typedef enum
12575ffb0c9bSToomas Soome {
12585ffb0c9bSToomas Soome     NATTProtocolNone    = 0,
12595ffb0c9bSToomas Soome     NATTProtocolNATPMP  = 1,
12605ffb0c9bSToomas Soome     NATTProtocolUPNPIGD = 2,
12615ffb0c9bSToomas Soome     NATTProtocolPCP     = 3,
12625ffb0c9bSToomas Soome } NATTProtocol;
12635ffb0c9bSToomas Soome 
12645ffb0c9bSToomas Soome struct NATTraversalInfo_struct
12655ffb0c9bSToomas Soome {
12665ffb0c9bSToomas Soome     // Internal state fields. These are used internally by mDNSCore; the client layer needn't be concerned with them.
12675ffb0c9bSToomas Soome     NATTraversalInfo           *next;
12685ffb0c9bSToomas Soome 
12695ffb0c9bSToomas Soome     mDNSs32 ExpiryTime;                             // Time this mapping expires, or zero if no mapping
12705ffb0c9bSToomas Soome     mDNSs32 retryInterval;                          // Current interval, between last packet we sent and the next one
12715ffb0c9bSToomas Soome     mDNSs32 retryPortMap;                           // If Protocol is nonzero, time to send our next mapping packet
12725ffb0c9bSToomas Soome     mStatus NewResult;                              // New error code; will be copied to Result just prior to invoking callback
12735ffb0c9bSToomas Soome     NATTProtocol lastSuccessfulProtocol;            // To send correct deletion request & update non-PCP external address operations
12745ffb0c9bSToomas Soome     mDNSBool sentNATPMP;                            // Whether we just sent a NAT-PMP packet, so we won't send another if
12755ffb0c9bSToomas Soome                                                     //    we receive another NAT-PMP "Unsupported Version" packet
12764b22b933Srs 
12775ffb0c9bSToomas Soome #ifdef _LEGACY_NAT_TRAVERSAL_
12785ffb0c9bSToomas Soome     tcpLNTInfo tcpInfo;                             // Legacy NAT traversal (UPnP) TCP connection
12795ffb0c9bSToomas Soome #endif
12804b22b933Srs 
12815ffb0c9bSToomas Soome     // Result fields: When the callback is invoked these fields contain the answers the client is looking for
12825ffb0c9bSToomas Soome     // When the callback is invoked ExternalPort is *usually* set to be the same the same as RequestedPort, except:
12835ffb0c9bSToomas Soome     // (a) When we're behind a NAT gateway with port mapping disabled, ExternalPort is reported as zero to
12845ffb0c9bSToomas Soome     //     indicate that we don't currently have a working mapping (but RequestedPort retains the external port
12855ffb0c9bSToomas Soome     //     we'd like to get, the next time we meet an accomodating NAT gateway willing to give us one).
12865ffb0c9bSToomas Soome     // (b) When we have a routable non-RFC1918 address, we don't *need* a port mapping, so ExternalPort
12875ffb0c9bSToomas Soome     //     is reported as the same as our InternalPort, since that is effectively our externally-visible port too.
12885ffb0c9bSToomas Soome     //     Again, RequestedPort retains the external port we'd like to get the next time we find ourself behind a NAT gateway.
12895ffb0c9bSToomas Soome     // To improve stability of port mappings, RequestedPort is updated any time we get a successful
12905ffb0c9bSToomas Soome     // mapping response from the PCP, NAT-PMP or UPnP gateway. For example, if we ask for port 80, and
12915ffb0c9bSToomas Soome     // get assigned port 81, then thereafter we'll contine asking for port 81.
12925ffb0c9bSToomas Soome     mDNSInterfaceID InterfaceID;
12935ffb0c9bSToomas Soome     mDNSv4Addr ExternalAddress;                     // Initially set to onesIPv4Addr, until first callback
12945ffb0c9bSToomas Soome     mDNSv4Addr NewAddress;                          // May be updated with actual value assigned by gateway
12955ffb0c9bSToomas Soome     mDNSIPPort ExternalPort;
12965ffb0c9bSToomas Soome     mDNSu32 Lifetime;
12975ffb0c9bSToomas Soome     mStatus Result;
12985ffb0c9bSToomas Soome 
12995ffb0c9bSToomas Soome     // Client API fields: The client must set up these fields *before* making any NAT traversal API calls
13005ffb0c9bSToomas Soome     mDNSu8 Protocol;                                // NATOp_MapUDP or NATOp_MapTCP, or zero if just requesting the external IP address
13015ffb0c9bSToomas Soome     mDNSIPPort IntPort;                             // Client's internal port number (doesn't change)
13025ffb0c9bSToomas Soome     mDNSIPPort RequestedPort;                       // Requested external port; may be updated with actual value assigned by gateway
13035ffb0c9bSToomas Soome     mDNSu32 NATLease;                               // Requested lifetime in seconds (doesn't change)
13045ffb0c9bSToomas Soome     NATTraversalClientCallback clientCallback;
13055ffb0c9bSToomas Soome     void                       *clientContext;
13065ffb0c9bSToomas Soome };
13074b22b933Srs 
13085ffb0c9bSToomas Soome // ***************************************************************************
13095ffb0c9bSToomas Soome #if 0
13105ffb0c9bSToomas Soome #pragma mark -
13115ffb0c9bSToomas Soome #pragma mark - DNSServer & McastResolver structures and constants
13125ffb0c9bSToomas Soome #endif
13134b22b933Srs 
13145ffb0c9bSToomas Soome enum
13155ffb0c9bSToomas Soome {
1316cda73f64SToomas Soome     DNSServer_FlagDelete      = 0x1,
1317cda73f64SToomas Soome     DNSServer_FlagNew         = 0x2,
1318cda73f64SToomas Soome #if APPLE_OSX_mDNSResponder
1319cda73f64SToomas Soome     DNSServer_FlagUnreachable = 0x4,
1320cda73f64SToomas Soome #endif
13215ffb0c9bSToomas Soome };
13224b22b933Srs 
13235ffb0c9bSToomas Soome enum
13245ffb0c9bSToomas Soome {
13255ffb0c9bSToomas Soome     McastResolver_FlagDelete = 1,
13265ffb0c9bSToomas Soome     McastResolver_FlagNew    = 2
13275ffb0c9bSToomas Soome };
13285ffb0c9bSToomas Soome 
13295ffb0c9bSToomas Soome typedef struct McastResolver
13305ffb0c9bSToomas Soome {
13315ffb0c9bSToomas Soome     struct McastResolver *next;
13325ffb0c9bSToomas Soome     mDNSInterfaceID interface;
13335ffb0c9bSToomas Soome     mDNSu32 flags;              // Set when we're planning to delete this from the list
13345ffb0c9bSToomas Soome     domainname domain;
13355ffb0c9bSToomas Soome     mDNSu32 timeout;            // timeout value for questions
13365ffb0c9bSToomas Soome } McastResolver;
13375ffb0c9bSToomas Soome 
13385ffb0c9bSToomas Soome // scoped values for DNSServer matching
13395ffb0c9bSToomas Soome enum
13405ffb0c9bSToomas Soome {
13415ffb0c9bSToomas Soome     kScopeNone         = 0,        // DNS server used by unscoped questions
13425ffb0c9bSToomas Soome     kScopeInterfaceID  = 1,        // Scoped DNS server used only by scoped questions
1343*c65ebfc7SToomas Soome     kScopeServiceID    = 2,         // Service specific DNS server used only by questions
13445ffb0c9bSToomas Soome                                    // have a matching serviceID
1345*c65ebfc7SToomas Soome     kScopesMaxCount    = 3         // Max count for scopes enum
13465ffb0c9bSToomas Soome };
13475ffb0c9bSToomas Soome 
13485ffb0c9bSToomas Soome // Note: DNSSECAware is set if we are able to get a valid response to
13495ffb0c9bSToomas Soome // a DNSSEC question. In some cases it is possible that the proxy
13505ffb0c9bSToomas Soome // strips the EDNS0 option and we just get a plain response with no
13515ffb0c9bSToomas Soome // signatures. But we still mark DNSSECAware in that case. As DNSSECAware
13525ffb0c9bSToomas Soome // is only used to determine whether DNSSEC_VALIDATION_SECURE_OPTIONAL
13535ffb0c9bSToomas Soome // should be turned off or not, it is sufficient that we are getting
13545ffb0c9bSToomas Soome // responses back.
13555ffb0c9bSToomas Soome typedef struct DNSServer
13565ffb0c9bSToomas Soome {
13575ffb0c9bSToomas Soome     struct DNSServer *next;
13585ffb0c9bSToomas Soome     mDNSInterfaceID interface;  // DNS requests should be sent on this interface
13595ffb0c9bSToomas Soome     mDNSs32 serviceID;
13605ffb0c9bSToomas Soome     mDNSAddr addr;
13615ffb0c9bSToomas Soome     mDNSIPPort port;
13625ffb0c9bSToomas Soome     mDNSu32 flags;              // Set when we're planning to delete this from the list
13635ffb0c9bSToomas Soome     domainname domain;          // name->server matching for "split dns"
13645ffb0c9bSToomas Soome     mDNSs32 penaltyTime;        // amount of time this server is penalized
13655ffb0c9bSToomas Soome     mDNSu32 scoped;             // See the scoped enum above
13665ffb0c9bSToomas Soome     mDNSu32 timeout;            // timeout value for questions
13675ffb0c9bSToomas Soome     mDNSu16 resGroupID;         // ID of the resolver group that contains this DNSServer
1368*c65ebfc7SToomas Soome     mDNSu8 retransDO;           // Total Retransmissions for queries sent with DO option
1369*c65ebfc7SToomas Soome     mDNSBool cellIntf;          // Resolver from Cellular Interface?
13705ffb0c9bSToomas Soome     mDNSBool req_A;             // If set, send v4 query (DNSConfig allows A queries)
13715ffb0c9bSToomas Soome     mDNSBool req_AAAA;          // If set, send v6 query (DNSConfig allows AAAA queries)
13725ffb0c9bSToomas Soome     mDNSBool req_DO;            // If set, okay to send DNSSEC queries (EDNS DO bit is supported)
1373*c65ebfc7SToomas Soome     mDNSBool DNSSECAware;       // Set if we are able to receive a response to a request sent with DO option.
1374*c65ebfc7SToomas Soome     mDNSBool isExpensive;       // True if the interface to this server is expensive.
13755ffb0c9bSToomas Soome } DNSServer;
13764b22b933Srs 
13774b22b933Srs typedef struct
13785ffb0c9bSToomas Soome {
13795ffb0c9bSToomas Soome     mDNSu8 *AnonData;
13805ffb0c9bSToomas Soome     int AnonDataLen;
13815ffb0c9bSToomas Soome     mDNSu32 salt;
13825ffb0c9bSToomas Soome     ResourceRecord *nsec3RR;
13835ffb0c9bSToomas Soome     mDNSInterfaceID SendNow;     // The interface ID that this record should be sent on
13845ffb0c9bSToomas Soome } AnonymousInfo;
13855ffb0c9bSToomas Soome 
13865ffb0c9bSToomas Soome struct ResourceRecord_struct
13875ffb0c9bSToomas Soome {
1388*c65ebfc7SToomas Soome     mDNSu8 RecordType;                  // See kDNSRecordTypes enum.
1389*c65ebfc7SToomas Soome     mDNSu16 rrtype;                     // See DNS_TypeValues enum.
1390*c65ebfc7SToomas Soome     mDNSu16 rrclass;                    // See DNS_ClassValues enum.
13915ffb0c9bSToomas Soome     mDNSu32 rroriginalttl;              // In seconds
13925ffb0c9bSToomas Soome     mDNSu16 rdlength;                   // Size of the raw rdata, in bytes, in the on-the-wire format
13935ffb0c9bSToomas Soome                                         // (In-memory storage may be larger, for structures containing 'holes', like SOA)
13945ffb0c9bSToomas Soome     mDNSu16 rdestimate;                 // Upper bound on on-the-wire size of rdata after name compression
13955ffb0c9bSToomas Soome     mDNSu32 namehash;                   // Name-based (i.e. case-insensitive) hash of name
13965ffb0c9bSToomas Soome     mDNSu32 rdatahash;                  // For rdata containing domain name (e.g. PTR, SRV, CNAME etc.), case-insensitive name hash
13975ffb0c9bSToomas Soome                                         // else, for all other rdata, 32-bit hash of the raw rdata
13985ffb0c9bSToomas Soome                                         // Note: This requirement is important. Various routines like AddAdditionalsToResponseList(),
13995ffb0c9bSToomas Soome                                         // ReconfirmAntecedents(), etc., use rdatahash as a pre-flight check to see
14005ffb0c9bSToomas Soome                                         // whether it's worth doing a full SameDomainName() call. If the rdatahash
14015ffb0c9bSToomas Soome                                         // is not a correct case-insensitive name hash, they'll get false negatives.
14025ffb0c9bSToomas Soome 
14035ffb0c9bSToomas Soome     // Grouping pointers together at the end of the structure improves the memory layout efficiency
14045ffb0c9bSToomas Soome     mDNSInterfaceID InterfaceID;        // Set if this RR is specific to one interface
14055ffb0c9bSToomas Soome                                         // For records received off the wire, InterfaceID is *always* set to the receiving interface
14065ffb0c9bSToomas Soome                                         // For our authoritative records, InterfaceID is usually zero, except for those few records
14075ffb0c9bSToomas Soome                                         // that are interface-specific (e.g. address records, especially linklocal addresses)
14085ffb0c9bSToomas Soome     const domainname *name;
14095ffb0c9bSToomas Soome     RData           *rdata;             // Pointer to storage for this rdata
1410cda73f64SToomas Soome     DNSServer       *rDNSServer;        // Unicast DNS server authoritative for this entry; null for multicast
14115ffb0c9bSToomas Soome     AnonymousInfo   *AnonInfo;          // Anonymous Information
14125ffb0c9bSToomas Soome };
14135ffb0c9bSToomas Soome 
14145ffb0c9bSToomas Soome 
14155ffb0c9bSToomas Soome // Unless otherwise noted, states may apply to either independent record registrations or service registrations
14164b22b933Srs typedef enum
14175ffb0c9bSToomas Soome {
14185ffb0c9bSToomas Soome     regState_Zero              = 0,
14195ffb0c9bSToomas Soome     regState_Pending           = 1,     // update sent, reply not received
14205ffb0c9bSToomas Soome     regState_Registered        = 2,     // update sent, reply received
14215ffb0c9bSToomas Soome     regState_DeregPending      = 3,     // dereg sent, reply not received
14225ffb0c9bSToomas Soome     regState_Unregistered      = 4,     // not in any list
14235ffb0c9bSToomas Soome     regState_Refresh           = 5,     // outstanding refresh (or target change) message
14245ffb0c9bSToomas Soome     regState_NATMap            = 6,     // establishing NAT port mapping
14255ffb0c9bSToomas Soome     regState_UpdatePending     = 7,     // update in flight as result of mDNS_Update call
14265ffb0c9bSToomas Soome     regState_NoTarget          = 8,     // SRV Record registration pending registration of hostname
14275ffb0c9bSToomas Soome     regState_NATError          = 9     // unable to complete NAT traversal
14285ffb0c9bSToomas Soome } regState_t;
14294b22b933Srs 
14305ffb0c9bSToomas Soome enum
14315ffb0c9bSToomas Soome {
14325ffb0c9bSToomas Soome     Target_Manual = 0,
14335ffb0c9bSToomas Soome     Target_AutoHost = 1,
14345ffb0c9bSToomas Soome     Target_AutoHostAndNATMAP = 2
14355ffb0c9bSToomas Soome };
14365ffb0c9bSToomas Soome 
14375ffb0c9bSToomas Soome typedef enum
14385ffb0c9bSToomas Soome {
14395ffb0c9bSToomas Soome     mergeState_Zero = 0,
14405ffb0c9bSToomas Soome     mergeState_DontMerge = 1  // Set on fatal error conditions to disable merging
14415ffb0c9bSToomas Soome } mergeState_t;
14425ffb0c9bSToomas Soome 
14435ffb0c9bSToomas Soome #define AUTH_GROUP_NAME_SIZE    128
14445ffb0c9bSToomas Soome struct AuthGroup_struct             // Header object for a list of AuthRecords with the same name
14455ffb0c9bSToomas Soome {
14465ffb0c9bSToomas Soome     AuthGroup      *next;               // Next AuthGroup object in this hash table bucket
14475ffb0c9bSToomas Soome     mDNSu32 namehash;                   // Name-based (i.e. case insensitive) hash of name
14485ffb0c9bSToomas Soome     AuthRecord     *members;            // List of CacheRecords with this same name
14495ffb0c9bSToomas Soome     AuthRecord    **rrauth_tail;        // Tail end of that list
14505ffb0c9bSToomas Soome     domainname     *name;               // Common name for all AuthRecords in this list
14515ffb0c9bSToomas Soome     AuthRecord     *NewLocalOnlyRecords;
14525ffb0c9bSToomas Soome     mDNSu8 namestorage[AUTH_GROUP_NAME_SIZE];
14535ffb0c9bSToomas Soome };
14545ffb0c9bSToomas Soome 
14555ffb0c9bSToomas Soome #ifndef AUTH_HASH_SLOTS
14565ffb0c9bSToomas Soome #define AUTH_HASH_SLOTS 499
14575ffb0c9bSToomas Soome #endif
14585ffb0c9bSToomas Soome #define FORALL_AUTHRECORDS(SLOT,AG,AR)                              \
14595ffb0c9bSToomas Soome     for ((SLOT) = 0; (SLOT) < AUTH_HASH_SLOTS; (SLOT)++)                                                                     \
14605ffb0c9bSToomas Soome         for ((AG)=m->rrauth.rrauth_hash[(SLOT)]; (AG); (AG)=(AG)->next)                                                                         \
14615ffb0c9bSToomas Soome             for ((AR) = (AG)->members; (AR); (AR)=(AR)->next)
14625ffb0c9bSToomas Soome 
14635ffb0c9bSToomas Soome typedef union AuthEntity_union AuthEntity;
14645ffb0c9bSToomas Soome union AuthEntity_union { AuthEntity *next; AuthGroup ag; };
14655ffb0c9bSToomas Soome typedef struct {
14665ffb0c9bSToomas Soome     mDNSu32 rrauth_size;                // Total number of available auth entries
14675ffb0c9bSToomas Soome     mDNSu32 rrauth_totalused;           // Number of auth entries currently occupied
14685ffb0c9bSToomas Soome     mDNSu32 rrauth_report;
14695ffb0c9bSToomas Soome     mDNSu8 rrauth_lock;                 // For debugging: Set at times when these lists may not be modified
14705ffb0c9bSToomas Soome     AuthEntity *rrauth_free;
14715ffb0c9bSToomas Soome     AuthGroup *rrauth_hash[AUTH_HASH_SLOTS];
14725ffb0c9bSToomas Soome }AuthHash;
14735ffb0c9bSToomas Soome 
14745ffb0c9bSToomas Soome // AuthRecordAny includes mDNSInterface_Any and interface specific auth records.
14755ffb0c9bSToomas Soome typedef enum
14765ffb0c9bSToomas Soome {
14775ffb0c9bSToomas Soome     AuthRecordAny,              // registered for *Any, NOT including P2P interfaces
14785ffb0c9bSToomas Soome     AuthRecordAnyIncludeP2P,    // registered for *Any, including P2P interfaces
14795ffb0c9bSToomas Soome     AuthRecordAnyIncludeAWDL,   // registered for *Any, including AWDL interface
14805ffb0c9bSToomas Soome     AuthRecordAnyIncludeAWDLandP2P, // registered for *Any, including AWDL and P2P interfaces
14815ffb0c9bSToomas Soome     AuthRecordLocalOnly,
14825ffb0c9bSToomas Soome     AuthRecordP2P               // discovered over D2D/P2P framework
14835ffb0c9bSToomas Soome } AuthRecType;
14845ffb0c9bSToomas Soome 
14855ffb0c9bSToomas Soome typedef enum
14865ffb0c9bSToomas Soome {
14875ffb0c9bSToomas Soome     AuthFlagsWakeOnly = 0x1     // WakeOnly service
14885ffb0c9bSToomas Soome } AuthRecordFlags;
14894b22b933Srs 
14904b22b933Srs struct AuthRecord_struct
14915ffb0c9bSToomas Soome {
14925ffb0c9bSToomas Soome     // For examples of how to set up this structure for use in mDNS_Register(),
14935ffb0c9bSToomas Soome     // see mDNS_AdvertiseInterface() or mDNS_RegisterService().
14945ffb0c9bSToomas Soome     // Basically, resrec and persistent metadata need to be set up before calling mDNS_Register().
14955ffb0c9bSToomas Soome     // mDNS_SetupResourceRecord() is avaliable as a helper routine to set up most fields to sensible default values for you
14965ffb0c9bSToomas Soome 
14975ffb0c9bSToomas Soome     AuthRecord     *next;               // Next in list; first element of structure for efficiency reasons
14985ffb0c9bSToomas Soome     // Field Group 1: Common ResourceRecord fields
1499cda73f64SToomas Soome     ResourceRecord resrec;              // 36 bytes when compiling for 32-bit; 48 when compiling for 64-bit (now 44/64)
15005ffb0c9bSToomas Soome 
15015ffb0c9bSToomas Soome     // Field Group 2: Persistent metadata for Authoritative Records
15025ffb0c9bSToomas Soome     AuthRecord     *Additional1;        // Recommended additional record to include in response (e.g. SRV for PTR record)
15035ffb0c9bSToomas Soome     AuthRecord     *Additional2;        // Another additional (e.g. TXT for PTR record)
15045ffb0c9bSToomas Soome     AuthRecord     *DependentOn;        // This record depends on another for its uniqueness checking
15055ffb0c9bSToomas Soome     AuthRecord     *RRSet;              // This unique record is part of an RRSet
15065ffb0c9bSToomas Soome     mDNSRecordCallback *RecordCallback; // Callback function to call for state changes, and to free memory asynchronously on deregistration
15075ffb0c9bSToomas Soome     void           *RecordContext;      // Context parameter for the callback function
15085ffb0c9bSToomas Soome     mDNSu8 AutoTarget;                  // Set if the target of this record (PTR, CNAME, SRV, etc.) is our host name
15095ffb0c9bSToomas Soome     mDNSu8 AllowRemoteQuery;            // Set if we allow hosts not on the local link to query this record
15105ffb0c9bSToomas Soome     mDNSu8 ForceMCast;                  // Set by client to advertise solely via multicast, even for apparently unicast names
15115ffb0c9bSToomas Soome     mDNSu8 AuthFlags;
15125ffb0c9bSToomas Soome 
15135ffb0c9bSToomas Soome     OwnerOptData WakeUp;                // WakeUp.HMAC.l[0] nonzero indicates that this is a Sleep Proxy record
15145ffb0c9bSToomas Soome     mDNSAddr AddressProxy;              // For reverse-mapping Sleep Proxy PTR records, address in question
15155ffb0c9bSToomas Soome     mDNSs32 TimeRcvd;                   // In platform time units
15165ffb0c9bSToomas Soome     mDNSs32 TimeExpire;                 // In platform time units
15175ffb0c9bSToomas Soome     AuthRecType ARType;                 // LocalOnly, P2P or Normal ?
15185ffb0c9bSToomas Soome     mDNSs32 KATimeExpire;               // In platform time units: time to send keepalive packet for the proxy record
15195ffb0c9bSToomas Soome 
15205ffb0c9bSToomas Soome     // Field Group 3: Transient state for Authoritative Records
15215ffb0c9bSToomas Soome     mDNSu8 Acknowledged;                // Set if we've given the success callback to the client
15225ffb0c9bSToomas Soome     mDNSu8 ProbeRestartCount;           // Number of times we have restarted probing
15235ffb0c9bSToomas Soome     mDNSu8 ProbeCount;                  // Number of probes remaining before this record is valid (kDNSRecordTypeUnique)
15245ffb0c9bSToomas Soome     mDNSu8 AnnounceCount;               // Number of announcements remaining (kDNSRecordTypeShared)
15255ffb0c9bSToomas Soome     mDNSu8 RequireGoodbye;              // Set if this RR has been announced on the wire and will require a goodbye packet
15265ffb0c9bSToomas Soome     mDNSu8 AnsweredLocalQ;              // Set if this AuthRecord has been delivered to any local question (LocalOnly or mDNSInterface_Any)
15275ffb0c9bSToomas Soome     mDNSu8 IncludeInProbe;              // Set if this RR is being put into a probe right now
15285ffb0c9bSToomas Soome     mDNSu8 ImmedUnicast;                // Set if we may send our response directly via unicast to the requester
15295ffb0c9bSToomas Soome     mDNSInterfaceID SendNSECNow;        // Set if we need to generate associated NSEC data for this rrname
15305ffb0c9bSToomas Soome     mDNSInterfaceID ImmedAnswer;        // Someone on this interface issued a query we need to answer (all-ones for all interfaces)
15314b22b933Srs #if MDNS_LOG_ANSWER_SUPPRESSION_TIMES
15325ffb0c9bSToomas Soome     mDNSs32 ImmedAnswerMarkTime;
15334b22b933Srs #endif
15345ffb0c9bSToomas Soome     mDNSInterfaceID ImmedAdditional;    // Hint that we might want to also send this record, just to be helpful
15355ffb0c9bSToomas Soome     mDNSInterfaceID SendRNow;           // The interface this query is being sent on right now
15365ffb0c9bSToomas Soome     mDNSv4Addr v4Requester;             // Recent v4 query for this record, or all-ones if more than one recent query
15375ffb0c9bSToomas Soome     mDNSv6Addr v6Requester;             // Recent v6 query for this record, or all-ones if more than one recent query
15385ffb0c9bSToomas Soome     AuthRecord     *NextResponse;       // Link to the next element in the chain of responses to generate
15395ffb0c9bSToomas Soome     const mDNSu8   *NR_AnswerTo;        // Set if this record was selected by virtue of being a direct answer to a question
15405ffb0c9bSToomas Soome     AuthRecord     *NR_AdditionalTo;    // Set if this record was selected by virtue of being additional to another
15415ffb0c9bSToomas Soome     mDNSs32 ThisAPInterval;             // In platform time units: Current interval for announce/probe
15425ffb0c9bSToomas Soome     mDNSs32 LastAPTime;                 // In platform time units: Last time we sent announcement/probe
15435ffb0c9bSToomas Soome     mDNSs32 LastMCTime;                 // Last time we multicast this record (used to guard against packet-storm attacks)
15445ffb0c9bSToomas Soome     mDNSInterfaceID LastMCInterface;    // Interface this record was multicast on at the time LastMCTime was recorded
15455ffb0c9bSToomas Soome     RData          *NewRData;           // Set if we are updating this record with new rdata
15465ffb0c9bSToomas Soome     mDNSu16 newrdlength;                // ... and the length of the new RData
15475ffb0c9bSToomas Soome     mDNSRecordUpdateCallback *UpdateCallback;
15485ffb0c9bSToomas Soome     mDNSu32 UpdateCredits;              // Token-bucket rate limiting of excessive updates
15495ffb0c9bSToomas Soome     mDNSs32 NextUpdateCredit;           // Time next token is added to bucket
15505ffb0c9bSToomas Soome     mDNSs32 UpdateBlocked;              // Set if update delaying is in effect
15515ffb0c9bSToomas Soome 
15525ffb0c9bSToomas Soome     // Field Group 4: Transient uDNS state for Authoritative Records
15535ffb0c9bSToomas Soome     regState_t state;           // Maybe combine this with resrec.RecordType state? Right now it's ambiguous and confusing.
15545ffb0c9bSToomas Soome                                 // e.g. rr->resrec.RecordType can be kDNSRecordTypeUnregistered,
15555ffb0c9bSToomas Soome                                 // and rr->state can be regState_Unregistered
15565ffb0c9bSToomas Soome                                 // What if we find one of those statements is true and the other false? What does that mean?
15575ffb0c9bSToomas Soome     mDNSBool uselease;          // dynamic update contains (should contain) lease option
15585ffb0c9bSToomas Soome     mDNSs32 expire;             // In platform time units: expiration of lease (-1 for static)
15595ffb0c9bSToomas Soome     mDNSBool Private;           // If zone is private, DNS updates may have to be encrypted to prevent eavesdropping
15605ffb0c9bSToomas Soome     mDNSOpaque16 updateid;      // Identifier to match update request and response -- also used when transferring records to Sleep Proxy
15615ffb0c9bSToomas Soome     mDNSOpaque64 updateIntID;   // Interface IDs (one bit per interface index)to which updates have been sent
15625ffb0c9bSToomas Soome     const domainname *zone;     // the zone that is updated
15635ffb0c9bSToomas Soome     ZoneData  *nta;
15645ffb0c9bSToomas Soome     struct tcpInfo_t *tcp;
15655ffb0c9bSToomas Soome     NATTraversalInfo NATinfo;
15665ffb0c9bSToomas Soome     mDNSBool SRVChanged;       // temporarily deregistered service because its SRV target or port changed
15675ffb0c9bSToomas Soome     mergeState_t mState;       // Unicast Record Registrations merge state
15685ffb0c9bSToomas Soome     mDNSu8 refreshCount;        // Number of refreshes to the server
15695ffb0c9bSToomas Soome     mStatus updateError;        // Record update resulted in Error ?
15705ffb0c9bSToomas Soome 
15715ffb0c9bSToomas Soome     // uDNS_UpdateRecord support fields
15725ffb0c9bSToomas Soome     // Do we really need all these in *addition* to NewRData and newrdlength above?
15735ffb0c9bSToomas Soome     void *UpdateContext;    // Context parameter for the update callback function
15745ffb0c9bSToomas Soome     mDNSu16 OrigRDLen;      // previously registered, being deleted
15755ffb0c9bSToomas Soome     mDNSu16 InFlightRDLen;  // currently being registered
15765ffb0c9bSToomas Soome     mDNSu16 QueuedRDLen;    // pending operation (re-transmitting if necessary) THEN register the queued update
15775ffb0c9bSToomas Soome     RData *OrigRData;
15785ffb0c9bSToomas Soome     RData *InFlightRData;
15795ffb0c9bSToomas Soome     RData *QueuedRData;
15805ffb0c9bSToomas Soome 
15815ffb0c9bSToomas Soome     // Field Group 5: Large data objects go at the end
15825ffb0c9bSToomas Soome     domainname namestorage;
15835ffb0c9bSToomas Soome     RData rdatastorage;                 // Normally the storage is right here, except for oversized records
15845ffb0c9bSToomas Soome     // rdatastorage MUST be the last thing in the structure -- when using oversized AuthRecords, extra bytes
15855ffb0c9bSToomas Soome     // are appended after the end of the AuthRecord, logically augmenting the size of the rdatastorage
15865ffb0c9bSToomas Soome     // DO NOT ADD ANY MORE FIELDS HERE
15875ffb0c9bSToomas Soome };
15885ffb0c9bSToomas Soome 
15895ffb0c9bSToomas Soome // IsLocalDomain alone is not sufficient to determine that a record is mDNS or uDNS. By default domain names within
15905ffb0c9bSToomas Soome // the "local" pseudo-TLD (and within the IPv4 and IPv6 link-local reverse mapping domains) are automatically treated
15915ffb0c9bSToomas Soome // as mDNS records, but it is also possible to force any record (even those not within one of the inherently local
15925ffb0c9bSToomas Soome // domains) to be handled as an mDNS record by setting the ForceMCast flag, or by setting a non-zero InterfaceID.
15935ffb0c9bSToomas Soome // For example, the reverse-mapping PTR record created in AdvertiseInterface sets the ForceMCast flag, since it points to
15945ffb0c9bSToomas Soome // a dot-local hostname, and therefore it would make no sense to register this record with a wide-area Unicast DNS server.
15955ffb0c9bSToomas Soome // The same applies to Sleep Proxy records, which we will answer for when queried via mDNS, but we never want to try
15965ffb0c9bSToomas Soome // to register them with a wide-area Unicast DNS server -- and we probably don't have the required credentials anyway.
15975ffb0c9bSToomas Soome // Currently we have no concept of a wide-area uDNS record scoped to a particular interface, so if the InterfaceID is
15985ffb0c9bSToomas Soome // nonzero we treat this the same as ForceMCast.
15995ffb0c9bSToomas Soome // Note: Question_uDNS(Q) is used in *only* one place -- on entry to mDNS_StartQuery_internal, to decide whether to set TargetQID.
16005ffb0c9bSToomas Soome // Everywhere else in the code, the determination of whether a question is unicast is made by checking to see if TargetQID is nonzero.
16015ffb0c9bSToomas Soome #define AuthRecord_uDNS(R) ((R)->resrec.InterfaceID == mDNSInterface_Any && !(R)->ForceMCast && !IsLocalDomain((R)->resrec.name))
16025ffb0c9bSToomas Soome #define Question_uDNS(Q)   ((Q)->InterfaceID == mDNSInterface_Unicast || (Q)->ProxyQuestion || \
1603*c65ebfc7SToomas Soome                             ((Q)->InterfaceID != mDNSInterface_LocalOnly && (Q)->InterfaceID != mDNSInterface_P2P && (Q)->InterfaceID != mDNSInterface_BLE && !(Q)->ForceMCast && !IsLocalDomain(&(Q)->qname)))
16045ffb0c9bSToomas Soome 
1605*c65ebfc7SToomas Soome // AuthRecordLocalOnly records are registered using mDNSInterface_LocalOnly and
1606*c65ebfc7SToomas Soome // AuthRecordP2P records are created by D2DServiceFound events.  Both record types are kept on the same list.
16075ffb0c9bSToomas Soome #define RRLocalOnly(rr) ((rr)->ARType == AuthRecordLocalOnly || (rr)->ARType == AuthRecordP2P)
16085ffb0c9bSToomas Soome 
1609*c65ebfc7SToomas Soome // All other auth records, not including those defined as RRLocalOnly().
16105ffb0c9bSToomas Soome #define RRAny(rr) ((rr)->ARType == AuthRecordAny || (rr)->ARType == AuthRecordAnyIncludeP2P || (rr)->ARType == AuthRecordAnyIncludeAWDL || (rr)->ARType == AuthRecordAnyIncludeAWDLandP2P)
16115ffb0c9bSToomas Soome 
16125ffb0c9bSToomas Soome // Question (A or AAAA) that is suppressed currently because IPv4 or IPv6 address
16135ffb0c9bSToomas Soome // is not available locally for A or AAAA question respectively. Also, if the
16145ffb0c9bSToomas Soome // query is disallowed for the "pid" that we are sending on behalf of, suppress it.
16155ffb0c9bSToomas Soome #define QuerySuppressed(Q) (((Q)->SuppressUnusable && (Q)->SuppressQuery) || ((Q)->DisallowPID))
16165ffb0c9bSToomas Soome 
16175ffb0c9bSToomas Soome #define PrivateQuery(Q) ((Q)->AuthInfo && (Q)->AuthInfo->AutoTunnel)
16185ffb0c9bSToomas Soome 
16195ffb0c9bSToomas Soome // Normally we always lookup the cache and /etc/hosts before sending the query on the wire. For single label
16205ffb0c9bSToomas Soome // queries (A and AAAA) that are unqualified (indicated by AppendSearchDomains), we want to append search
16215ffb0c9bSToomas Soome // domains before we try them as such
16225ffb0c9bSToomas Soome #define ApplySearchDomainsFirst(q) ((q)->AppendSearchDomains && (CountLabels(&((q)->qname))) == 1)
16234b22b933Srs 
16244b22b933Srs // Wrapper struct for Auth Records for higher-level code that cannot use the AuthRecord's ->next pointer field
16254b22b933Srs typedef struct ARListElem
16265ffb0c9bSToomas Soome {
16275ffb0c9bSToomas Soome     struct ARListElem *next;
16285ffb0c9bSToomas Soome     AuthRecord ar;          // Note: Must be last element of structure, to accomodate oversized AuthRecords
16295ffb0c9bSToomas Soome } ARListElem;
16304b22b933Srs 
16314b22b933Srs struct CacheRecord_struct
16325ffb0c9bSToomas Soome {
16335ffb0c9bSToomas Soome     CacheRecord    *next;               // Next in list; first element of structure for efficiency reasons
1634cda73f64SToomas Soome     ResourceRecord resrec;              // 36 bytes when compiling for 32-bit; 48 when compiling for 64-bit (now 44/64)
16355ffb0c9bSToomas Soome 
16365ffb0c9bSToomas Soome     // Transient state for Cache Records
16375ffb0c9bSToomas Soome     CacheRecord    *NextInKAList;       // Link to the next element in the chain of known answers to send
16385ffb0c9bSToomas Soome     mDNSs32 TimeRcvd;                   // In platform time units
16395ffb0c9bSToomas Soome     mDNSs32 DelayDelivery;              // Set if we want to defer delivery of this answer to local clients
16405ffb0c9bSToomas Soome     mDNSs32 NextRequiredQuery;          // In platform time units
16415ffb0c9bSToomas Soome     mDNSs32 LastUsed;                   // In platform time units
16425ffb0c9bSToomas Soome     DNSQuestion    *CRActiveQuestion;   // Points to an active question referencing this answer. Can never point to a NewQuestion.
16435ffb0c9bSToomas Soome     mDNSs32 LastUnansweredTime;         // In platform time units; last time we incremented UnansweredQueries
16445ffb0c9bSToomas Soome     mDNSu8  UnansweredQueries;          // Number of times we've issued a query for this record without getting an answer
16455ffb0c9bSToomas Soome     mDNSu8  CRDNSSECQuestion;           // Set to 1 if this was created in response to a DNSSEC question
16465ffb0c9bSToomas Soome     mDNSOpaque16 responseFlags;         // Second 16 bit in the DNS response
16475ffb0c9bSToomas Soome     CacheRecord    *NextInCFList;       // Set if this is in the list of records we just received with the cache flush bit set
16485ffb0c9bSToomas Soome     CacheRecord    *nsec;               // NSEC records needed for non-existence proofs
16495ffb0c9bSToomas Soome     CacheRecord    *soa;                // SOA record to return for proxy questions
16505ffb0c9bSToomas Soome 
16515ffb0c9bSToomas Soome     mDNSAddr sourceAddress;             // node from which we received this record
1652cda73f64SToomas Soome     // Size to here is 76 bytes when compiling 32-bit; 104 bytes when compiling 64-bit (now 160 bytes for 64-bit)
16535ffb0c9bSToomas Soome     RData_small smallrdatastorage;      // Storage for small records is right here (4 bytes header + 68 bytes data = 72 bytes)
16545ffb0c9bSToomas Soome };
16555ffb0c9bSToomas Soome 
16565ffb0c9bSToomas Soome // Should match the CacheGroup_struct members, except namestorage[].  Only used to calculate
1657cda73f64SToomas Soome // the size of the namestorage array in CacheGroup_struct so that sizeof(CacheGroup) == sizeof(CacheRecord)
16585ffb0c9bSToomas Soome struct CacheGroup_base
16595ffb0c9bSToomas Soome {
16605ffb0c9bSToomas Soome     CacheGroup     *next;
16615ffb0c9bSToomas Soome     mDNSu32         namehash;
16625ffb0c9bSToomas Soome     CacheRecord    *members;
16635ffb0c9bSToomas Soome     CacheRecord   **rrcache_tail;
16645ffb0c9bSToomas Soome     domainname     *name;
16655ffb0c9bSToomas Soome };
16665ffb0c9bSToomas Soome 
16675ffb0c9bSToomas Soome struct CacheGroup_struct                // Header object for a list of CacheRecords with the same name
16685ffb0c9bSToomas Soome {
16695ffb0c9bSToomas Soome     CacheGroup     *next;               // Next CacheGroup object in this hash table bucket
16705ffb0c9bSToomas Soome     mDNSu32         namehash;           // Name-based (i.e. case insensitive) hash of name
16715ffb0c9bSToomas Soome     CacheRecord    *members;            // List of CacheRecords with this same name
16725ffb0c9bSToomas Soome     CacheRecord   **rrcache_tail;       // Tail end of that list
16735ffb0c9bSToomas Soome     domainname     *name;               // Common name for all CacheRecords in this list
16745ffb0c9bSToomas Soome     mDNSu8 namestorage[sizeof(CacheRecord) - sizeof(struct CacheGroup_base)];  // match sizeof(CacheRecord)
16755ffb0c9bSToomas Soome };
16764b22b933Srs 
16774b22b933Srs // Storage sufficient to hold either a CacheGroup header or a CacheRecord
16785ffb0c9bSToomas Soome // -- for best efficiency (to avoid wasted unused storage) they should be the same size
16794b22b933Srs typedef union CacheEntity_union CacheEntity;
16804b22b933Srs union CacheEntity_union { CacheEntity *next; CacheGroup cg; CacheRecord cr; };
16814b22b933Srs 
16824b22b933Srs typedef struct
16835ffb0c9bSToomas Soome {
16845ffb0c9bSToomas Soome     CacheRecord r;
16855ffb0c9bSToomas Soome     mDNSu8 _extradata[MaximumRDSize-InlineCacheRDSize];     // Glue on the necessary number of extra bytes
16865ffb0c9bSToomas Soome     domainname namestorage;                                 // Needs to go *after* the extra rdata bytes
16875ffb0c9bSToomas Soome } LargeCacheRecord;
16885ffb0c9bSToomas Soome 
16895ffb0c9bSToomas Soome typedef struct HostnameInfo
16905ffb0c9bSToomas Soome {
16915ffb0c9bSToomas Soome     struct HostnameInfo *next;
16925ffb0c9bSToomas Soome     NATTraversalInfo natinfo;
16934b22b933Srs     domainname fqdn;
16945ffb0c9bSToomas Soome     AuthRecord arv4;                          // registered IPv4 address record
16955ffb0c9bSToomas Soome     AuthRecord arv6;                          // registered IPv6 address record
16965ffb0c9bSToomas Soome     mDNSRecordCallback *StatusCallback;       // callback to deliver success or error code to client layer
16975ffb0c9bSToomas Soome     const void *StatusContext;                // Client Context
16985ffb0c9bSToomas Soome } HostnameInfo;
16994b22b933Srs 
17004b22b933Srs typedef struct ExtraResourceRecord_struct ExtraResourceRecord;
17014b22b933Srs struct ExtraResourceRecord_struct
17025ffb0c9bSToomas Soome {
17035ffb0c9bSToomas Soome     ExtraResourceRecord *next;
17044b22b933Srs     mDNSu32 ClientID;  // Opaque ID field to be used by client to map an AddRecord call to a set of Extra records
17055ffb0c9bSToomas Soome     AuthRecord r;
17065ffb0c9bSToomas Soome     // Note: Add any additional fields *before* the AuthRecord in this structure, not at the end.
17075ffb0c9bSToomas Soome     // In some cases clients can allocate larger chunks of memory and set r->rdata->MaxRDLength to indicate
17085ffb0c9bSToomas Soome     // that this extra memory is available, which would result in any fields after the AuthRecord getting smashed
17095ffb0c9bSToomas Soome };
17105ffb0c9bSToomas Soome 
17115ffb0c9bSToomas Soome // Note: Within an mDNSServiceCallback mDNS all API calls are legal except mDNS_Init(), mDNS_Exit(), mDNS_Execute()
17125ffb0c9bSToomas Soome typedef void mDNSServiceCallback (mDNS *const m, ServiceRecordSet *const sr, mStatus result);
17135ffb0c9bSToomas Soome 
17145ffb0c9bSToomas Soome // A ServiceRecordSet has no special meaning to the core code of the Multicast DNS protocol engine;
17155ffb0c9bSToomas Soome // it is just a convenience structure to group together the records that make up a standard service
17165ffb0c9bSToomas Soome // registration so that they can be allocted and deallocted together as a single memory object.
17175ffb0c9bSToomas Soome // It contains its own ServiceCallback+ServiceContext to report aggregate results up to the next layer of software above.
17185ffb0c9bSToomas Soome // It also contains:
17195ffb0c9bSToomas Soome //  * the basic PTR/SRV/TXT triplet used to represent any DNS-SD service
17205ffb0c9bSToomas Soome //  * the "_services" PTR record for service enumeration
17215ffb0c9bSToomas Soome //  * the optional list of SubType PTR records
17225ffb0c9bSToomas Soome //  * the optional list of additional records attached to the service set (e.g. iChat pictures)
17234b22b933Srs 
17244b22b933Srs struct ServiceRecordSet_struct
17255ffb0c9bSToomas Soome {
17265ffb0c9bSToomas Soome     // These internal state fields are used internally by mDNSCore; the client layer needn't be concerned with them.
17275ffb0c9bSToomas Soome     // No fields need to be set up by the client prior to calling mDNS_RegisterService();
17285ffb0c9bSToomas Soome     // all required data is passed as parameters to that function.
17295ffb0c9bSToomas Soome     mDNSServiceCallback *ServiceCallback;
17305ffb0c9bSToomas Soome     void                *ServiceContext;
17315ffb0c9bSToomas Soome     mDNSBool Conflict;              // Set if this record set was forcibly deregistered because of a conflict
17325ffb0c9bSToomas Soome 
17335ffb0c9bSToomas Soome     ExtraResourceRecord *Extras;    // Optional list of extra AuthRecords attached to this service registration
17345ffb0c9bSToomas Soome     mDNSu32 NumSubTypes;
17355ffb0c9bSToomas Soome     AuthRecord          *SubTypes;
17365ffb0c9bSToomas Soome     const mDNSu8        *AnonData;
1737*c65ebfc7SToomas Soome     mDNSu32             flags;      // saved for subsequent calls to mDNS_RegisterService() if records
17385ffb0c9bSToomas Soome                                     // need to be re-registered.
17395ffb0c9bSToomas Soome     AuthRecord RR_ADV;              // e.g. _services._dns-sd._udp.local. PTR _printer._tcp.local.
17405ffb0c9bSToomas Soome     AuthRecord RR_PTR;              // e.g. _printer._tcp.local.        PTR Name._printer._tcp.local.
17415ffb0c9bSToomas Soome     AuthRecord RR_SRV;              // e.g. Name._printer._tcp.local.   SRV 0 0 port target
17425ffb0c9bSToomas Soome     AuthRecord RR_TXT;              // e.g. Name._printer._tcp.local.   TXT PrintQueueName
17435ffb0c9bSToomas Soome     // Don't add any fields after AuthRecord RR_TXT.
17445ffb0c9bSToomas Soome     // This is where the implicit extra space goes if we allocate a ServiceRecordSet containing an oversized RR_TXT record
17455ffb0c9bSToomas Soome };
17464b22b933Srs 
17474b22b933Srs // ***************************************************************************
17484b22b933Srs #if 0
17495ffb0c9bSToomas Soome #pragma mark -
17504b22b933Srs #pragma mark - Question structures
17514b22b933Srs #endif
17524b22b933Srs 
17534b22b933Srs // We record the last eight instances of each duplicate query
17545ffb0c9bSToomas Soome // This gives us v4/v6 on each of Ethernet, AirPort and Firewire, and two free slots "for future expansion"
17554b22b933Srs // If the host has more active interfaces that this it is not fatal -- duplicate question suppression will degrade gracefully.
17564b22b933Srs // Since we will still remember the last eight, the busiest interfaces will still get the effective duplicate question suppression.
17574b22b933Srs #define DupSuppressInfoSize 8
17584b22b933Srs 
17594b22b933Srs typedef struct
17605ffb0c9bSToomas Soome {
17615ffb0c9bSToomas Soome     mDNSs32 Time;
17625ffb0c9bSToomas Soome     mDNSInterfaceID InterfaceID;
17635ffb0c9bSToomas Soome     mDNSs32 Type;                           // v4 or v6?
17645ffb0c9bSToomas Soome } DupSuppressInfo;
17654b22b933Srs 
17664b22b933Srs typedef enum
17675ffb0c9bSToomas Soome {
17685ffb0c9bSToomas Soome     LLQ_InitialRequest    = 1,
17695ffb0c9bSToomas Soome     LLQ_SecondaryRequest  = 2,
17705ffb0c9bSToomas Soome     LLQ_Established       = 3,
17715ffb0c9bSToomas Soome     LLQ_Poll              = 4
17725ffb0c9bSToomas Soome } LLQ_State;
17734b22b933Srs 
17744b22b933Srs // LLQ constants
17754b22b933Srs #define kLLQ_Vers      1
17764b22b933Srs #define kLLQ_DefLease  7200 // 2 hours
17774b22b933Srs #define kLLQ_MAX_TRIES 3    // retry an operation 3 times max
17784b22b933Srs #define kLLQ_INIT_RESEND 2 // resend an un-ack'd packet after 2 seconds, then double for each additional
17794b22b933Srs // LLQ Operation Codes
17804b22b933Srs #define kLLQOp_Setup     1
17814b22b933Srs #define kLLQOp_Refresh   2
17824b22b933Srs #define kLLQOp_Event     3
17834b22b933Srs 
17844b22b933Srs // LLQ Errror Codes
17854b22b933Srs enum
17865ffb0c9bSToomas Soome {
17875ffb0c9bSToomas Soome     LLQErr_NoError    = 0,
17885ffb0c9bSToomas Soome     LLQErr_ServFull   = 1,
17895ffb0c9bSToomas Soome     LLQErr_Static     = 2,
17905ffb0c9bSToomas Soome     LLQErr_FormErr    = 3,
17915ffb0c9bSToomas Soome     LLQErr_NoSuchLLQ  = 4,
17925ffb0c9bSToomas Soome     LLQErr_BadVers    = 5,
17935ffb0c9bSToomas Soome     LLQErr_UnknownErr = 6
17945ffb0c9bSToomas Soome };
17955ffb0c9bSToomas Soome 
17965ffb0c9bSToomas Soome enum { NoAnswer_Normal = 0, NoAnswer_Suspended = 1, NoAnswer_Fail = 2 };
17975ffb0c9bSToomas Soome 
1798*c65ebfc7SToomas Soome // DNS Push Notification
1799*c65ebfc7SToomas Soome typedef enum
1800*c65ebfc7SToomas Soome {
1801*c65ebfc7SToomas Soome     DNSPUSH_NOERROR  = 0,
1802*c65ebfc7SToomas Soome     DNSPUSH_FORMERR  = 1,
1803*c65ebfc7SToomas Soome     DNSPUSH_SERVFAIL = 2,
1804*c65ebfc7SToomas Soome     DNSPUSH_NOTIMP   = 4,
1805*c65ebfc7SToomas Soome     DNSPUSH_REFUSED  = 5
1806*c65ebfc7SToomas Soome } DNSPUSH_ErrorCode;
1807*c65ebfc7SToomas Soome 
1808*c65ebfc7SToomas Soome typedef enum {
1809*c65ebfc7SToomas Soome     DNSPUSH_INIT         = 1,
1810*c65ebfc7SToomas Soome     DNSPUSH_NOSERVER     = 2,
1811*c65ebfc7SToomas Soome     DNSPUSH_SERVERFOUND  = 3,
1812*c65ebfc7SToomas Soome     DNSPUSH_ESTABLISHED  = 4
1813*c65ebfc7SToomas Soome } DNSPush_State;
1814*c65ebfc7SToomas Soome 
1815*c65ebfc7SToomas Soome 
1816*c65ebfc7SToomas Soome 
18175ffb0c9bSToomas Soome #define HMAC_LEN    64
18185ffb0c9bSToomas Soome #define HMAC_IPAD   0x36
18195ffb0c9bSToomas Soome #define HMAC_OPAD   0x5c
18205ffb0c9bSToomas Soome #define MD5_LEN     16
18215ffb0c9bSToomas Soome 
18225ffb0c9bSToomas Soome #define AutoTunnelUnregistered(X) (                                               \
18235ffb0c9bSToomas Soome         (X)->AutoTunnelHostRecord.resrec.RecordType == kDNSRecordTypeUnregistered && \
18245ffb0c9bSToomas Soome         (X)->AutoTunnelTarget.resrec.RecordType == kDNSRecordTypeUnregistered && \
18255ffb0c9bSToomas Soome         (X)->AutoTunnelDeviceInfo.resrec.RecordType == kDNSRecordTypeUnregistered && \
18265ffb0c9bSToomas Soome         (X)->AutoTunnelService.resrec.RecordType == kDNSRecordTypeUnregistered && \
18275ffb0c9bSToomas Soome         (X)->AutoTunnel6Record.resrec.RecordType == kDNSRecordTypeUnregistered )
18285ffb0c9bSToomas Soome 
18295ffb0c9bSToomas Soome // Internal data structure to maintain authentication information
18305ffb0c9bSToomas Soome typedef struct DomainAuthInfo
18315ffb0c9bSToomas Soome {
18325ffb0c9bSToomas Soome     struct DomainAuthInfo *next;
18335ffb0c9bSToomas Soome     mDNSs32 deltime;                        // If we're planning to delete this DomainAuthInfo, the time we want it deleted
18345ffb0c9bSToomas Soome     mDNSBool   AutoTunnel;                  // Whether this is AutoTunnel
18355ffb0c9bSToomas Soome     AuthRecord AutoTunnelHostRecord;        // User-visible hostname; used as SRV target for AutoTunnel services
18365ffb0c9bSToomas Soome     AuthRecord AutoTunnelTarget;            // Opaque hostname of tunnel endpoint; used as SRV target for AutoTunnelService record
18375ffb0c9bSToomas Soome     AuthRecord AutoTunnelDeviceInfo;        // Device info of tunnel endpoint
18385ffb0c9bSToomas Soome     AuthRecord AutoTunnelService;           // Service record (possibly NAT-Mapped) of IKE daemon implementing tunnel endpoint
18395ffb0c9bSToomas Soome     AuthRecord AutoTunnel6Record;           // AutoTunnel AAAA Record obtained from awacsd
18405ffb0c9bSToomas Soome     mDNSBool AutoTunnelServiceStarted;         // Whether a service has been registered in this domain
18415ffb0c9bSToomas Soome     mDNSv6Addr AutoTunnelInnerAddress;
18425ffb0c9bSToomas Soome     domainname domain;
18435ffb0c9bSToomas Soome     domainname keyname;
18445ffb0c9bSToomas Soome     domainname hostname;
18455ffb0c9bSToomas Soome     mDNSIPPort port;
18465ffb0c9bSToomas Soome     char b64keydata[32];
18475ffb0c9bSToomas Soome     mDNSu8 keydata_ipad[HMAC_LEN];              // padded key for inner hash rounds
18485ffb0c9bSToomas Soome     mDNSu8 keydata_opad[HMAC_LEN];              // padded key for outer hash rounds
18495ffb0c9bSToomas Soome } DomainAuthInfo;
18505ffb0c9bSToomas Soome 
18515ffb0c9bSToomas Soome // Note: Within an mDNSQuestionCallback mDNS all API calls are legal except mDNS_Init(), mDNS_Exit(), mDNS_Execute()
18525ffb0c9bSToomas Soome // Note: Any value other than QC_rmv i.e., any non-zero value will result in kDNSServiceFlagsAdd to the application
18535ffb0c9bSToomas Soome // layer. These values are used within mDNSResponder and not sent across to the application. QC_addnocache is for
18545ffb0c9bSToomas Soome // delivering a response without adding to the cache. QC_forceresponse is superset of QC_addnocache where in
18555ffb0c9bSToomas Soome // addition to not entering in the cache, it also forces the negative response through.
18565ffb0c9bSToomas Soome typedef enum { QC_rmv = 0, QC_add, QC_addnocache, QC_forceresponse, QC_dnssec , QC_nodnssec, QC_suppressed } QC_result;
18575ffb0c9bSToomas Soome typedef void mDNSQuestionCallback (mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord);
18585ffb0c9bSToomas Soome typedef void AsyncDispatchFunc(mDNS *const m, void *context);
18595ffb0c9bSToomas Soome typedef void DNSSECAuthInfoFreeCallback(mDNS *const m, void *context);
18605ffb0c9bSToomas Soome extern void mDNSPlatformDispatchAsync(mDNS *const m, void *context, AsyncDispatchFunc func);
18615ffb0c9bSToomas Soome 
18625ffb0c9bSToomas Soome #define NextQSendTime(Q)  ((Q)->LastQTime + (Q)->ThisQInterval)
18635ffb0c9bSToomas Soome #define ActiveQuestion(Q) ((Q)->ThisQInterval > 0 && !(Q)->DuplicateOf)
18645ffb0c9bSToomas Soome #define TimeToSendThisQuestion(Q,time) (ActiveQuestion(Q) && (time) - NextQSendTime(Q) >= 0)
18655ffb0c9bSToomas Soome 
18665ffb0c9bSToomas Soome // q->ValidationStatus is either DNSSECValNotRequired or DNSSECValRequired and then moves onto DNSSECValInProgress.
18675ffb0c9bSToomas Soome // When Validation is done, we mark all "DNSSECValInProgress" questions "DNSSECValDone". If we are answering
18685ffb0c9bSToomas Soome // questions from /etc/hosts, then we go straight to DNSSECValDone from the initial state.
18695ffb0c9bSToomas Soome typedef enum { DNSSECValNotRequired = 0, DNSSECValRequired, DNSSECValInProgress, DNSSECValDone } DNSSECValState;
18705ffb0c9bSToomas Soome 
18715ffb0c9bSToomas Soome // ValidationRequired can be set to the following values:
18725ffb0c9bSToomas Soome //
1873*c65ebfc7SToomas Soome // SECURE validation is set to determine whether something is secure or bogus
18745ffb0c9bSToomas Soome // INSECURE validation is set internally by dnssec code to indicate that it is currently proving something
18755ffb0c9bSToomas Soome // is insecure
18765ffb0c9bSToomas Soome #define DNSSEC_VALIDATION_NONE              0x00
18775ffb0c9bSToomas Soome #define DNSSEC_VALIDATION_SECURE            0x01
18785ffb0c9bSToomas Soome #define DNSSEC_VALIDATION_SECURE_OPTIONAL   0x02
18795ffb0c9bSToomas Soome #define DNSSEC_VALIDATION_INSECURE          0x03
18805ffb0c9bSToomas Soome 
18815ffb0c9bSToomas Soome // For both ValidationRequired and ValidatingResponse question, we validate DNSSEC responses.
18825ffb0c9bSToomas Soome // For ProxyQuestion with DNSSECOK, we just receive the DNSSEC records to pass them along without
18835ffb0c9bSToomas Soome // validation and if the CD bit is not set, we also validate.
18845ffb0c9bSToomas Soome #define DNSSECQuestion(q) ((q)->ValidationRequired || (q)->ValidatingResponse || ((q)->ProxyQuestion && (q)->ProxyDNSSECOK))
18855ffb0c9bSToomas Soome 
18865ffb0c9bSToomas Soome // ValidatingQuestion is used when we need to know whether we are validating the DNSSEC responses for a question
18875ffb0c9bSToomas Soome #define ValidatingQuestion(q) ((q)->ValidationRequired || (q)->ValidatingResponse)
18885ffb0c9bSToomas Soome 
18895ffb0c9bSToomas Soome #define DNSSECOptionalQuestion(q) ((q)->ValidationRequired == DNSSEC_VALIDATION_SECURE_OPTIONAL)
18905ffb0c9bSToomas Soome 
18915ffb0c9bSToomas Soome // Given the resource record and the question, should we follow the CNAME ?
18925ffb0c9bSToomas Soome #define FollowCNAME(q, rr, AddRecord)   (AddRecord && (q)->qtype != kDNSType_CNAME && \
18935ffb0c9bSToomas Soome                                          (rr)->RecordType != kDNSRecordTypePacketNegative && \
18945ffb0c9bSToomas Soome                                          (rr)->rrtype == kDNSType_CNAME)
18955ffb0c9bSToomas Soome 
1896*c65ebfc7SToomas Soome // RFC 4122 defines it to be 16 bytes
18975ffb0c9bSToomas Soome #define UUID_SIZE       16
18985ffb0c9bSToomas Soome 
1899*c65ebfc7SToomas Soome #define AWD_METRICS (USE_AWD && TARGET_OS_EMBEDDED)
1900*c65ebfc7SToomas Soome 
1901*c65ebfc7SToomas Soome #if AWD_METRICS
1902cda73f64SToomas Soome typedef struct
1903cda73f64SToomas Soome {
1904cda73f64SToomas Soome     domainname *    originalQName;          // Name of original A/AAAA record if this question is for a CNAME record.
1905cda73f64SToomas Soome     mDNSu32         querySendCount;         // Number of queries that have been sent to DNS servers so far.
1906cda73f64SToomas Soome     mDNSs32         firstQueryTime;         // The time when the first query was sent to a DNS server.
1907cda73f64SToomas Soome     mDNSBool        answered;               // Has this question been answered?
1908cda73f64SToomas Soome 
1909cda73f64SToomas Soome }   uDNSMetrics;
1910cda73f64SToomas Soome #endif
1911cda73f64SToomas Soome 
1912*c65ebfc7SToomas Soome // DNS64 code is only for iOS, which is currently the only Apple OS that supports DNS proxy network extensions.
1913*c65ebfc7SToomas Soome #define USE_DNS64 (HAVE_DNS64 && TARGET_OS_IOS)
1914*c65ebfc7SToomas Soome 
1915*c65ebfc7SToomas Soome #if USE_DNS64
1916*c65ebfc7SToomas Soome #include "DNS64State.h"
1917*c65ebfc7SToomas Soome #endif
1918*c65ebfc7SToomas Soome 
1919*c65ebfc7SToomas Soome #if TARGET_OS_EMBEDDED
1920*c65ebfc7SToomas Soome extern mDNSu32 curr_num_regservices; // tracks the current number of services registered
1921*c65ebfc7SToomas Soome extern mDNSu32 max_num_regservices;  // tracks the max number of simultaneous services registered by the device
1922*c65ebfc7SToomas Soome #endif
1923*c65ebfc7SToomas Soome 
19244b22b933Srs struct DNSQuestion_struct
19255ffb0c9bSToomas Soome {
19265ffb0c9bSToomas Soome     // Internal state fields. These are used internally by mDNSCore; the client layer needn't be concerned with them.
19275ffb0c9bSToomas Soome     DNSQuestion          *next;
19285ffb0c9bSToomas Soome     mDNSu32 qnamehash;
19295ffb0c9bSToomas Soome     mDNSs32 DelayAnswering;                 // Set if we want to defer answering this question until the cache settles
19305ffb0c9bSToomas Soome     mDNSs32 LastQTime;                      // Last scheduled transmission of this Q on *all* applicable interfaces
19315ffb0c9bSToomas Soome     mDNSs32 ThisQInterval;                  // LastQTime + ThisQInterval is the next scheduled transmission of this Q
19325ffb0c9bSToomas Soome                                             // ThisQInterval > 0 for an active question;
19335ffb0c9bSToomas Soome                                             // ThisQInterval = 0 for a suspended question that's still in the list
19345ffb0c9bSToomas Soome                                             // ThisQInterval = -1 for a cancelled question (should not still be in list)
19355ffb0c9bSToomas Soome     mDNSs32 ExpectUnicastResp;              // Set when we send a query with the kDNSQClass_UnicastResponse bit set
19365ffb0c9bSToomas Soome     mDNSs32 LastAnswerPktNum;               // The sequence number of the last response packet containing an answer to this Q
19375ffb0c9bSToomas Soome     mDNSu32 RecentAnswerPkts;               // Number of answers since the last time we sent this query
19385ffb0c9bSToomas Soome     mDNSu32 CurrentAnswers;                 // Number of records currently in the cache that answer this question
19395ffb0c9bSToomas Soome     mDNSu32 BrowseThreshold;                // If we have received at least this number of answers,
19405ffb0c9bSToomas Soome                                             // set the next question interval to MaxQuestionInterval
19415ffb0c9bSToomas Soome     mDNSu32 LargeAnswers;                   // Number of answers with rdata > 1024 bytes
19425ffb0c9bSToomas Soome     mDNSu32 UniqueAnswers;                  // Number of answers received with kDNSClass_UniqueRRSet bit set
19435ffb0c9bSToomas Soome     mDNSInterfaceID FlappingInterface1;     // Set when an interface goes away, to flag if remove events are delivered for this Q
19445ffb0c9bSToomas Soome     mDNSInterfaceID FlappingInterface2;     // Set when an interface goes away, to flag if remove events are delivered for this Q
19455ffb0c9bSToomas Soome     DomainAuthInfo       *AuthInfo;         // Non-NULL if query is currently being done using Private DNS
19465ffb0c9bSToomas Soome     DNSQuestion          *DuplicateOf;
19475ffb0c9bSToomas Soome     DNSQuestion          *NextInDQList;
19485ffb0c9bSToomas Soome     AnonymousInfo        *AnonInfo;         // Anonymous Information
19495ffb0c9bSToomas Soome     DupSuppressInfo DupSuppress[DupSuppressInfoSize];
19505ffb0c9bSToomas Soome     mDNSInterfaceID SendQNow;               // The interface this query is being sent on right now
19515ffb0c9bSToomas Soome     mDNSBool SendOnAll;                     // Set if we're sending this question on all active interfaces
1952*c65ebfc7SToomas Soome     mDNSBool CachedAnswerNeedsUpdate;       // See SendQueries().  Set if we're sending this question
19535ffb0c9bSToomas Soome                                             // because a cached answer needs to be refreshed.
19545ffb0c9bSToomas Soome     mDNSu32 RequestUnicast;                 // Non-zero if we want to send query with kDNSQClass_UnicastResponse bit set
19555ffb0c9bSToomas Soome     mDNSs32 LastQTxTime;                    // Last time this Q was sent on one (but not necessarily all) interfaces
19565ffb0c9bSToomas Soome     mDNSu32 CNAMEReferrals;                 // Count of how many CNAME redirections we've done
19575ffb0c9bSToomas Soome     mDNSBool SuppressQuery;                 // This query should be suppressed and not sent on the wire
19585ffb0c9bSToomas Soome     mDNSu8 LOAddressAnswers;                // Number of answers from the local only auth records that are
19595ffb0c9bSToomas Soome                                             // answering A, AAAA, CNAME, or PTR (/etc/hosts)
19605ffb0c9bSToomas Soome     mDNSu8 WakeOnResolveCount;              // Number of wakes that should be sent on resolve
19615ffb0c9bSToomas Soome     mDNSs32 StopTime;                       // Time this question should be stopped by giving them a negative answer
19625ffb0c9bSToomas Soome 
19635ffb0c9bSToomas Soome     // DNSSEC fields
19645ffb0c9bSToomas Soome     DNSSECValState ValidationState;            // Current state of the Validation process
19655ffb0c9bSToomas Soome     DNSSECStatus ValidationStatus;             // Validation status for "ValidationRequired" questions (dnssec)
19665ffb0c9bSToomas Soome     mDNSu8 ValidatingResponse;                 // Question trying to validate a response (dnssec) on behalf of
19675ffb0c9bSToomas Soome                                                // ValidationRequired question
19685ffb0c9bSToomas Soome     void *DNSSECAuthInfo;
19695ffb0c9bSToomas Soome     DNSSECAuthInfoFreeCallback *DAIFreeCallback;
19705ffb0c9bSToomas Soome 
19715ffb0c9bSToomas Soome     // Wide Area fields. These are used internally by the uDNS core (Unicast)
19725ffb0c9bSToomas Soome     UDPSocket            *LocalSocket;
19735ffb0c9bSToomas Soome 
19745ffb0c9bSToomas Soome     // |-> DNS Configuration related fields used in uDNS (Subset of Wide Area/Unicast fields)
19755ffb0c9bSToomas Soome     DNSServer            *qDNSServer;       // Caching server for this query (in the absence of an SRV saying otherwise)
1976*c65ebfc7SToomas Soome     mDNSOpaque128 validDNSServers;          // Valid DNSServers for this question
19775ffb0c9bSToomas Soome     mDNSu16 noServerResponse;               // At least one server did not respond.
19785ffb0c9bSToomas Soome     mDNSu16 triedAllServersOnce;            // Tried all DNS servers once
19795ffb0c9bSToomas Soome     mDNSu8 unansweredQueries;               // The number of unanswered queries to this server
19805ffb0c9bSToomas Soome 
19815ffb0c9bSToomas Soome     ZoneData             *nta;              // Used for getting zone data for private or LLQ query
19825ffb0c9bSToomas Soome     mDNSAddr servAddr;                      // Address and port learned from _dns-llq, _dns-llq-tls or _dns-query-tls SRV query
19835ffb0c9bSToomas Soome     mDNSIPPort servPort;
19845ffb0c9bSToomas Soome     struct tcpInfo_t *tcp;
19855ffb0c9bSToomas Soome     mDNSIPPort tcpSrcPort;                  // Local Port TCP packet received on;need this as tcp struct is disposed
19865ffb0c9bSToomas Soome                                             // by tcpCallback before calling into mDNSCoreReceive
19875ffb0c9bSToomas Soome     mDNSu8 NoAnswer;                        // Set if we want to suppress answers until tunnel setup has completed
19885ffb0c9bSToomas Soome     mDNSu8 Restart;                         // This question should be restarted soon
19895ffb0c9bSToomas Soome 
19905ffb0c9bSToomas Soome     // LLQ-specific fields. These fields are only meaningful when LongLived flag is set
19915ffb0c9bSToomas Soome     LLQ_State state;
19925ffb0c9bSToomas Soome     mDNSu32 ReqLease;                       // seconds (relative)
19935ffb0c9bSToomas Soome     mDNSs32 expire;                         // ticks (absolute)
19945ffb0c9bSToomas Soome     mDNSs16 ntries;                         // for UDP: the number of packets sent for this LLQ state
19955ffb0c9bSToomas Soome                                             // for TCP: there is some ambiguity in the use of this variable, but in general, it is
19965ffb0c9bSToomas Soome                                             //          the number of TCP/TLS connection attempts for this LLQ state, or
19975ffb0c9bSToomas Soome                                             //          the number of packets sent for this TCP/TLS connection
1998*c65ebfc7SToomas Soome 
1999*c65ebfc7SToomas Soome     // DNS Push Notification fields. These fields are only meaningful when LongLived flag is set
2000*c65ebfc7SToomas Soome     DNSPush_State dnsPushState;             // The state of the DNS push notification negotiation
2001*c65ebfc7SToomas Soome     mDNSAddr      dnsPushServerAddr;        // Address of the system acting as the DNS Push Server
2002*c65ebfc7SToomas Soome     mDNSIPPort    dnsPushServerPort;        // Port on which the DNS Push Server is being advertised.
2003*c65ebfc7SToomas Soome 
20045ffb0c9bSToomas Soome     mDNSOpaque64 id;
20055ffb0c9bSToomas Soome 
20065ffb0c9bSToomas Soome     // DNS Proxy fields
20075ffb0c9bSToomas Soome     mDNSOpaque16 responseFlags;             // Temporary place holder for the error we get back from the DNS server
20085ffb0c9bSToomas Soome                                             // till we populate in the cache
20095ffb0c9bSToomas Soome     mDNSBool     DisallowPID;               // Is the query allowed for the "PID" that we are sending on behalf of ?
20105ffb0c9bSToomas Soome     mDNSs32      ServiceID;                 // Service identifier to match against the DNS server
2011*c65ebfc7SToomas Soome 
20125ffb0c9bSToomas Soome     // Client API fields: The client must set up these fields *before* calling mDNS_StartQuery()
20135ffb0c9bSToomas Soome     mDNSInterfaceID InterfaceID;            // Non-zero if you want to issue queries only on a single specific IP interface
20145ffb0c9bSToomas Soome     mDNSu32  flags;                         // flags from original DNSService*() API request.
20155ffb0c9bSToomas Soome     mDNSAddr Target;                        // Non-zero if you want to direct queries to a specific unicast target address
20165ffb0c9bSToomas Soome     mDNSIPPort TargetPort;                  // Must be set if Target is set
20175ffb0c9bSToomas Soome     mDNSOpaque16 TargetQID;                 // Must be set if Target is set
20185ffb0c9bSToomas Soome     domainname qname;
20195ffb0c9bSToomas Soome     mDNSu16 qtype;
20205ffb0c9bSToomas Soome     mDNSu16 qclass;
20215ffb0c9bSToomas Soome     mDNSBool LongLived;                     // Set by client for calls to mDNS_StartQuery to indicate LLQs to unicast layer.
20225ffb0c9bSToomas Soome     mDNSBool ExpectUnique;                  // Set by client if it's expecting unique RR(s) for this question, not shared RRs
20235ffb0c9bSToomas Soome     mDNSBool ForceMCast;                    // Set by client to force mDNS query, even for apparently uDNS names
20245ffb0c9bSToomas Soome     mDNSBool ReturnIntermed;                // Set by client to request callbacks for intermediate CNAME/NXDOMAIN results
20255ffb0c9bSToomas Soome     mDNSBool SuppressUnusable;              // Set by client to suppress unusable queries to be sent on the wire
20265ffb0c9bSToomas Soome     mDNSu8 RetryWithSearchDomains;          // Retry with search domains if there is no entry in the cache or AuthRecords
20275ffb0c9bSToomas Soome     mDNSu8 TimeoutQuestion;                 // Timeout this question if there is no reply in configured time
20285ffb0c9bSToomas Soome     mDNSu8 WakeOnResolve;                   // Send wakeup on resolve
20295ffb0c9bSToomas Soome     mDNSu8 UseBackgroundTrafficClass;       // Set by client to use background traffic class for request
20305ffb0c9bSToomas Soome     mDNSs8 SearchListIndex;                 // Index into SearchList; Used by the client layer but not touched by core
20315ffb0c9bSToomas Soome     mDNSs8 AppendSearchDomains;             // Search domains can be appended for this query
20325ffb0c9bSToomas Soome     mDNSs8 AppendLocalSearchDomains;        // Search domains ending in .local can be appended for this query
20335ffb0c9bSToomas Soome     mDNSu8 ValidationRequired;              // Requires DNSSEC validation.
20345ffb0c9bSToomas Soome     mDNSu8 ProxyQuestion;                   // Proxy Question
20355ffb0c9bSToomas Soome     mDNSu8 ProxyDNSSECOK;                   // Proxy Question with EDNS0 DNSSEC OK bit set
20365ffb0c9bSToomas Soome     mDNSs32 pid;                            // Process ID of the client that is requesting the question
20375ffb0c9bSToomas Soome     mDNSu8  uuid[UUID_SIZE];                // Unique ID of the client that is requesting the question (valid only if pid is zero)
2038cda73f64SToomas Soome     mDNSu32 euid;                           // Effective User Id of the client that is requesting the question
20395ffb0c9bSToomas Soome     domainname           *qnameOrig;        // Copy of the original question name if it is not fully qualified
20405ffb0c9bSToomas Soome     mDNSQuestionCallback *QuestionCallback;
20415ffb0c9bSToomas Soome     void                 *QuestionContext;
2042cda73f64SToomas Soome #if TARGET_OS_EMBEDDED
2043cda73f64SToomas Soome     uDNSMetrics metrics;                    // Data used for collecting unicast DNS query metrics.
2044cda73f64SToomas Soome #endif
2045*c65ebfc7SToomas Soome #if USE_DNS64
2046*c65ebfc7SToomas Soome     DNS64 dns64;                            // DNS64 state for performing IPv6 address synthesis on networks with NAT64.
2047*c65ebfc7SToomas Soome #endif
20485ffb0c9bSToomas Soome };
20494b22b933Srs 
2050*c65ebfc7SToomas Soome typedef enum { ZoneServiceUpdate, ZoneServiceQuery, ZoneServiceLLQ, ZoneServiceDNSPush } ZoneService;
20515ffb0c9bSToomas Soome 
20525ffb0c9bSToomas Soome typedef void ZoneDataCallback (mDNS *const m, mStatus err, const ZoneData *result);
20535ffb0c9bSToomas Soome 
20545ffb0c9bSToomas Soome struct ZoneData_struct
20555ffb0c9bSToomas Soome {
20565ffb0c9bSToomas Soome     domainname ChildName;               // Name for which we're trying to find the responsible server
20575ffb0c9bSToomas Soome     ZoneService ZoneService;            // Which service we're seeking for this zone (update, query, or LLQ)
20585ffb0c9bSToomas Soome     domainname       *CurrentSOA;       // Points to somewhere within ChildName
20595ffb0c9bSToomas Soome     domainname ZoneName;                // Discovered result: Left-hand-side of SOA record
20605ffb0c9bSToomas Soome     mDNSu16 ZoneClass;                  // Discovered result: DNS Class from SOA record
20615ffb0c9bSToomas Soome     domainname Host;                    // Discovered result: Target host from SRV record
20625ffb0c9bSToomas Soome     mDNSIPPort Port;                    // Discovered result: Update port, query port, or LLQ port from SRV record
20635ffb0c9bSToomas Soome     mDNSAddr Addr;                      // Discovered result: Address of Target host from SRV record
20645ffb0c9bSToomas Soome     mDNSBool ZonePrivate;               // Discovered result: Does zone require encrypted queries?
20655ffb0c9bSToomas Soome     ZoneDataCallback *ZoneDataCallback; // Caller-specified function to be called upon completion
20665ffb0c9bSToomas Soome     void             *ZoneDataContext;
20675ffb0c9bSToomas Soome     DNSQuestion question;               // Storage for any active question
20685ffb0c9bSToomas Soome };
20695ffb0c9bSToomas Soome 
20705ffb0c9bSToomas Soome extern ZoneData *StartGetZoneData(mDNS *const m, const domainname *const name, const ZoneService target, ZoneDataCallback callback, void *callbackInfo);
20715ffb0c9bSToomas Soome extern void CancelGetZoneData(mDNS *const m, ZoneData *nta);
20725ffb0c9bSToomas Soome extern mDNSBool IsGetZoneDataQuestion(DNSQuestion *q);
20735ffb0c9bSToomas Soome 
20745ffb0c9bSToomas Soome typedef struct DNameListElem
20755ffb0c9bSToomas Soome {
20765ffb0c9bSToomas Soome     struct DNameListElem *next;
20775ffb0c9bSToomas Soome     mDNSu32 uid;
20785ffb0c9bSToomas Soome     domainname name;
20795ffb0c9bSToomas Soome } DNameListElem;
20805ffb0c9bSToomas Soome 
20815ffb0c9bSToomas Soome #if APPLE_OSX_mDNSResponder
20825ffb0c9bSToomas Soome // Different states that we go through locating the peer
20835ffb0c9bSToomas Soome #define TC_STATE_AAAA_PEER          0x000000001     /* Peer's BTMM IPv6 address */
20845ffb0c9bSToomas Soome #define TC_STATE_AAAA_PEER_RELAY    0x000000002     /* Peer's IPv6 Relay address */
20855ffb0c9bSToomas Soome #define TC_STATE_SRV_PEER           0x000000003     /* Peer's SRV Record corresponding to IPv4 address */
20865ffb0c9bSToomas Soome #define TC_STATE_ADDR_PEER          0x000000004     /* Peer's IPv4 address */
20875ffb0c9bSToomas Soome 
20885ffb0c9bSToomas Soome typedef struct ClientTunnel
20895ffb0c9bSToomas Soome {
20905ffb0c9bSToomas Soome     struct ClientTunnel *next;
20915ffb0c9bSToomas Soome     domainname dstname;
20925ffb0c9bSToomas Soome     mDNSBool MarkedForDeletion;
20935ffb0c9bSToomas Soome     mDNSv6Addr loc_inner;
20945ffb0c9bSToomas Soome     mDNSv4Addr loc_outer;
20955ffb0c9bSToomas Soome     mDNSv6Addr loc_outer6;
20965ffb0c9bSToomas Soome     mDNSv6Addr rmt_inner;
20975ffb0c9bSToomas Soome     mDNSv4Addr rmt_outer;
20985ffb0c9bSToomas Soome     mDNSv6Addr rmt_outer6;
20995ffb0c9bSToomas Soome     mDNSIPPort rmt_outer_port;
21005ffb0c9bSToomas Soome     mDNSu16 tc_state;
21015ffb0c9bSToomas Soome     DNSQuestion q;
21025ffb0c9bSToomas Soome } ClientTunnel;
21035ffb0c9bSToomas Soome #endif
21044b22b933Srs 
21054b22b933Srs // ***************************************************************************
21064b22b933Srs #if 0
21075ffb0c9bSToomas Soome #pragma mark -
21085ffb0c9bSToomas Soome #pragma mark - NetworkInterfaceInfo_struct
21094b22b933Srs #endif
21104b22b933Srs 
21115ffb0c9bSToomas Soome typedef struct NetworkInterfaceInfo_struct NetworkInterfaceInfo;
21124b22b933Srs 
21135ffb0c9bSToomas Soome // A NetworkInterfaceInfo_struct serves two purposes:
21145ffb0c9bSToomas Soome // 1. It holds the address, PTR and HINFO records to advertise a given IP address on a given physical interface
21155ffb0c9bSToomas Soome // 2. It tells mDNSCore which physical interfaces are available; each physical interface has its own unique InterfaceID.
21165ffb0c9bSToomas Soome //    Since there may be multiple IP addresses on a single physical interface,
21175ffb0c9bSToomas Soome //    there may be multiple NetworkInterfaceInfo_structs with the same InterfaceID.
21185ffb0c9bSToomas Soome //    In this case, to avoid sending the same packet n times, when there's more than one
21195ffb0c9bSToomas Soome //    struct with the same InterfaceID, mDNSCore picks one member of the set to be the
21205ffb0c9bSToomas Soome //    active representative of the set; all others have the 'InterfaceActive' flag unset.
21214b22b933Srs 
21225ffb0c9bSToomas Soome struct NetworkInterfaceInfo_struct
21235ffb0c9bSToomas Soome {
21245ffb0c9bSToomas Soome     // Internal state fields. These are used internally by mDNSCore; the client layer needn't be concerned with them.
21255ffb0c9bSToomas Soome     NetworkInterfaceInfo *next;
21265ffb0c9bSToomas Soome 
21275ffb0c9bSToomas Soome     mDNSu8 InterfaceActive;             // Set if interface is sending & receiving packets (see comment above)
21285ffb0c9bSToomas Soome     mDNSu8 IPv4Available;               // If InterfaceActive, set if v4 available on this InterfaceID
21295ffb0c9bSToomas Soome     mDNSu8 IPv6Available;               // If InterfaceActive, set if v6 available on this InterfaceID
21305ffb0c9bSToomas Soome 
21315ffb0c9bSToomas Soome     DNSQuestion NetWakeBrowse;
21325ffb0c9bSToomas Soome     DNSQuestion NetWakeResolve[3];      // For fault-tolerance, we try up to three Sleep Proxies
21335ffb0c9bSToomas Soome     mDNSAddr SPSAddr[3];
21345ffb0c9bSToomas Soome     mDNSIPPort SPSPort[3];
21355ffb0c9bSToomas Soome     mDNSs32 NextSPSAttempt;             // -1 if we're not currently attempting to register with any Sleep Proxy
21365ffb0c9bSToomas Soome     mDNSs32 NextSPSAttemptTime;
21375ffb0c9bSToomas Soome 
21385ffb0c9bSToomas Soome     // Standard AuthRecords that every Responder host should have (one per active IP address)
21395ffb0c9bSToomas Soome     AuthRecord RR_A;                    // 'A' or 'AAAA' (address) record for our ".local" name
21405ffb0c9bSToomas Soome     AuthRecord RR_PTR;                  // PTR (reverse lookup) record
21415ffb0c9bSToomas Soome     AuthRecord RR_HINFO;
21425ffb0c9bSToomas Soome 
21435ffb0c9bSToomas Soome     // Client API fields: The client must set up these fields *before* calling mDNS_RegisterInterface()
21445ffb0c9bSToomas Soome     mDNSInterfaceID InterfaceID;        // Identifies physical interface; MUST NOT be 0, -1, or -2
21455ffb0c9bSToomas Soome     mDNSAddr ip;                        // The IPv4 or IPv6 address to advertise
21465ffb0c9bSToomas Soome     mDNSAddr mask;
21475ffb0c9bSToomas Soome     mDNSEthAddr MAC;
21485ffb0c9bSToomas Soome     char ifname[64];                    // Windows uses a GUID string for the interface name, which doesn't fit in 16 bytes
21495ffb0c9bSToomas Soome     mDNSu8 Advertise;                   // False if you are only searching on this interface
21505ffb0c9bSToomas Soome     mDNSu8 McastTxRx;                   // Send/Receive multicast on this { InterfaceID, address family } ?
21515ffb0c9bSToomas Soome     mDNSu8 NetWake;                     // Set if Wake-On-Magic-Packet is enabled on this interface
21525ffb0c9bSToomas Soome     mDNSu8 Loopback;                    // Set if this is the loopback interface
21535ffb0c9bSToomas Soome     mDNSu8 IgnoreIPv4LL;                // Set if IPv4 Link-Local addresses have to be ignored.
21545ffb0c9bSToomas Soome     mDNSu8 SendGoodbyes;                // Send goodbyes on this interface while sleeping
21555ffb0c9bSToomas Soome     mDNSBool DirectLink;                // a direct link, indicating we can skip the probe for
21565ffb0c9bSToomas Soome                                         // address records
2157cda73f64SToomas Soome     mDNSBool SupportsUnicastMDNSResponse;  // Indicates that the interface supports unicast responses
2158*c65ebfc7SToomas Soome                                         // to Bonjour queries.  Generally true for an interface
21595ffb0c9bSToomas Soome };
21605ffb0c9bSToomas Soome 
21615ffb0c9bSToomas Soome #define SLE_DELETE                      0x00000001
21625ffb0c9bSToomas Soome #define SLE_WAB_BROWSE_QUERY_STARTED    0x00000002
21635ffb0c9bSToomas Soome #define SLE_WAB_LBROWSE_QUERY_STARTED   0x00000004
21645ffb0c9bSToomas Soome #define SLE_WAB_REG_QUERY_STARTED       0x00000008
21655ffb0c9bSToomas Soome 
21665ffb0c9bSToomas Soome typedef struct SearchListElem
21675ffb0c9bSToomas Soome {
21685ffb0c9bSToomas Soome     struct SearchListElem *next;
21695ffb0c9bSToomas Soome     domainname domain;
21705ffb0c9bSToomas Soome     int flag;
21715ffb0c9bSToomas Soome     mDNSInterfaceID InterfaceID;
21725ffb0c9bSToomas Soome     DNSQuestion BrowseQ;
21735ffb0c9bSToomas Soome     DNSQuestion DefBrowseQ;
21745ffb0c9bSToomas Soome     DNSQuestion AutomaticBrowseQ;
21755ffb0c9bSToomas Soome     DNSQuestion RegisterQ;
21765ffb0c9bSToomas Soome     DNSQuestion DefRegisterQ;
21775ffb0c9bSToomas Soome     int numCfAnswers;
21785ffb0c9bSToomas Soome     ARListElem *AuthRecs;
21795ffb0c9bSToomas Soome } SearchListElem;
21805ffb0c9bSToomas Soome 
21815ffb0c9bSToomas Soome // For domain enumeration and automatic browsing
21825ffb0c9bSToomas Soome // This is the user's DNS search list.
21835ffb0c9bSToomas Soome // In each of these domains we search for our special pointer records (lb._dns-sd._udp.<domain>, etc.)
21845ffb0c9bSToomas Soome // to discover recommended domains for domain enumeration (browse, default browse, registration,
21855ffb0c9bSToomas Soome // default registration) and possibly one or more recommended automatic browsing domains.
21865ffb0c9bSToomas Soome extern SearchListElem *SearchList;      // This really ought to be part of mDNS_struct -- SC
21874b22b933Srs 
21884b22b933Srs // ***************************************************************************
21894b22b933Srs #if 0
21905ffb0c9bSToomas Soome #pragma mark -
21914b22b933Srs #pragma mark - Main mDNS object, used to hold all the mDNS state
21924b22b933Srs #endif
21934b22b933Srs 
21945ffb0c9bSToomas Soome typedef void mDNSCallback (mDNS *const m, mStatus result);
21954b22b933Srs 
21965ffb0c9bSToomas Soome #ifndef CACHE_HASH_SLOTS
21974b22b933Srs #define CACHE_HASH_SLOTS 499
21985ffb0c9bSToomas Soome #endif
21994b22b933Srs 
22004b22b933Srs enum
22015ffb0c9bSToomas Soome {
22025ffb0c9bSToomas Soome     SleepState_Awake = 0,
22035ffb0c9bSToomas Soome     SleepState_Transferring = 1,
22045ffb0c9bSToomas Soome     SleepState_Sleeping = 2
22055ffb0c9bSToomas Soome };
22065ffb0c9bSToomas Soome 
22075ffb0c9bSToomas Soome typedef enum
22085ffb0c9bSToomas Soome {
22095ffb0c9bSToomas Soome     kStatsActionIncrement,
22105ffb0c9bSToomas Soome     kStatsActionDecrement,
22115ffb0c9bSToomas Soome     kStatsActionClear,
22125ffb0c9bSToomas Soome     kStatsActionSet
22135ffb0c9bSToomas Soome } DNSSECStatsAction;
22145ffb0c9bSToomas Soome 
22155ffb0c9bSToomas Soome typedef enum
22165ffb0c9bSToomas Soome {
22175ffb0c9bSToomas Soome     kStatsTypeMemoryUsage,
22185ffb0c9bSToomas Soome     kStatsTypeLatency,
22195ffb0c9bSToomas Soome     kStatsTypeExtraPackets,
22205ffb0c9bSToomas Soome     kStatsTypeStatus,
22215ffb0c9bSToomas Soome     kStatsTypeProbe,
22225ffb0c9bSToomas Soome     kStatsTypeMsgSize
22235ffb0c9bSToomas Soome } DNSSECStatsType;
22245ffb0c9bSToomas Soome 
22255ffb0c9bSToomas Soome typedef struct
22265ffb0c9bSToomas Soome {
22275ffb0c9bSToomas Soome     mDNSu32 TotalMemUsed;
22285ffb0c9bSToomas Soome     mDNSu32 Latency0;           // 0 to 4 ms
22295ffb0c9bSToomas Soome     mDNSu32 Latency5;           // 5 to  9 ms
22305ffb0c9bSToomas Soome     mDNSu32 Latency10;          // 10 to 19 ms
22315ffb0c9bSToomas Soome     mDNSu32 Latency20;          // 20 to 49 ms
22325ffb0c9bSToomas Soome     mDNSu32 Latency50;          // 50 to 99 ms
22335ffb0c9bSToomas Soome     mDNSu32 Latency100;         // >= 100 ms
22345ffb0c9bSToomas Soome     mDNSu32 ExtraPackets0;      // 0 to 2 packets
22355ffb0c9bSToomas Soome     mDNSu32 ExtraPackets3;      // 3 to 6 packets
22365ffb0c9bSToomas Soome     mDNSu32 ExtraPackets7;      // 7 to 9 packets
22375ffb0c9bSToomas Soome     mDNSu32 ExtraPackets10;     // >= 10 packets
22385ffb0c9bSToomas Soome     mDNSu32 SecureStatus;
22395ffb0c9bSToomas Soome     mDNSu32 InsecureStatus;
22405ffb0c9bSToomas Soome     mDNSu32 IndeterminateStatus;
22415ffb0c9bSToomas Soome     mDNSu32 BogusStatus;
22425ffb0c9bSToomas Soome     mDNSu32 NoResponseStatus;
22435ffb0c9bSToomas Soome     mDNSu32 NumProbesSent;      // Number of probes sent
22445ffb0c9bSToomas Soome     mDNSu32 MsgSize0;           // DNSSEC message size <= 1024
22455ffb0c9bSToomas Soome     mDNSu32 MsgSize1;           // DNSSEC message size <= 2048
22465ffb0c9bSToomas Soome     mDNSu32 MsgSize2;           // DNSSEC message size > 2048
22475ffb0c9bSToomas Soome } DNSSECStatistics;
22484b22b933Srs 
22494b22b933Srs typedef struct
22505ffb0c9bSToomas Soome {
22515ffb0c9bSToomas Soome     mDNSu32 NameConflicts;                  // Normal Name conflicts
22525ffb0c9bSToomas Soome     mDNSu32 KnownUniqueNameConflicts;       // Name Conflicts for KnownUnique Records
22535ffb0c9bSToomas Soome     mDNSu32 DupQuerySuppressions;           // Duplicate query suppressions
22545ffb0c9bSToomas Soome     mDNSu32 KnownAnswerSuppressions;        // Known Answer suppressions
22555ffb0c9bSToomas Soome     mDNSu32 KnownAnswerMultiplePkts;        // Known Answer in queries spannign multiple packets
22565ffb0c9bSToomas Soome     mDNSu32 PoofCacheDeletions;             // Number of times the cache was deleted due to POOF
22575ffb0c9bSToomas Soome     mDNSu32 UnicastBitInQueries;            // Queries with QU bit set
22585ffb0c9bSToomas Soome     mDNSu32 NormalQueries;                  // Queries with QU bit not set
22595ffb0c9bSToomas Soome     mDNSu32 MatchingAnswersForQueries;      // Queries for which we had a response
22605ffb0c9bSToomas Soome     mDNSu32 UnicastResponses;               // Unicast responses to queries
22615ffb0c9bSToomas Soome     mDNSu32 MulticastResponses;             // Multicast responses to queries
22625ffb0c9bSToomas Soome     mDNSu32 UnicastDemotedToMulticast;      // Number of times unicast demoted to multicast
22635ffb0c9bSToomas Soome     mDNSu32 Sleeps;                         // Total sleeps
22645ffb0c9bSToomas Soome     mDNSu32 Wakes;                          // Total wakes
22655ffb0c9bSToomas Soome     mDNSu32 InterfaceUp;                    // Total Interface UP events
22665ffb0c9bSToomas Soome     mDNSu32 InterfaceUpFlap;                // Total Interface UP events with flaps
22675ffb0c9bSToomas Soome     mDNSu32 InterfaceDown;                  // Total Interface Down events
22685ffb0c9bSToomas Soome     mDNSu32 InterfaceDownFlap;              // Total Interface Down events with flaps
22695ffb0c9bSToomas Soome     mDNSu32 CacheRefreshQueries;            // Number of queries that we sent for refreshing cache
22705ffb0c9bSToomas Soome     mDNSu32 CacheRefreshed;                 // Number of times the cache was refreshed due to a response
22715ffb0c9bSToomas Soome     mDNSu32 WakeOnResolves;                 // Number of times we did a wake on resolve
22725ffb0c9bSToomas Soome } mDNSStatistics;
2273cda73f64SToomas Soome 
22745ffb0c9bSToomas Soome extern void LogMDNSStatistics(mDNS *const m);
22754b22b933Srs 
2276*c65ebfc7SToomas Soome typedef struct mDNS_DNSPushNotificationServer DNSPushNotificationServer;
2277*c65ebfc7SToomas Soome typedef struct mDNS_DNSPushNotificationZone   DNSPushNotificationZone;
2278*c65ebfc7SToomas Soome 
2279*c65ebfc7SToomas Soome struct mDNS_DNSPushNotificationServer
2280*c65ebfc7SToomas Soome {
2281*c65ebfc7SToomas Soome     mDNSAddr   serverAddr;        // Server Address
2282*c65ebfc7SToomas Soome     tcpInfo_t *connection;        // TCP Connection pointer
2283*c65ebfc7SToomas Soome     mDNSu32    numberOfQuestions; // Number of questions for this server
2284*c65ebfc7SToomas Soome     DNSPushNotificationServer *next;
2285*c65ebfc7SToomas Soome } ;
2286*c65ebfc7SToomas Soome 
2287*c65ebfc7SToomas Soome struct mDNS_DNSPushNotificationZone
2288*c65ebfc7SToomas Soome {
2289*c65ebfc7SToomas Soome     domainname zoneName;
2290*c65ebfc7SToomas Soome     DNSPushNotificationServer *servers; // DNS Push Notification Servers for this zone
2291*c65ebfc7SToomas Soome     mDNSu32 numberOfQuestions;          // Number of questions for this zone
2292*c65ebfc7SToomas Soome     DNSPushNotificationZone *next;
2293*c65ebfc7SToomas Soome } ;
2294*c65ebfc7SToomas Soome 
2295*c65ebfc7SToomas Soome 
2296*c65ebfc7SToomas Soome // Time constant (~= 260 hours ~= 10 days and 21 hours) used to set
2297*c65ebfc7SToomas Soome // various time values to a point well into the future.
2298*c65ebfc7SToomas Soome #define FutureTime   0x38000000
2299*c65ebfc7SToomas Soome 
23004b22b933Srs struct mDNS_struct
23015ffb0c9bSToomas Soome {
23025ffb0c9bSToomas Soome     // Internal state fields. These hold the main internal state of mDNSCore;
23035ffb0c9bSToomas Soome     // the client layer needn't be concerned with them.
23045ffb0c9bSToomas Soome     // No fields need to be set up by the client prior to calling mDNS_Init();
23055ffb0c9bSToomas Soome     // all required data is passed as parameters to that function.
23065ffb0c9bSToomas Soome 
23075ffb0c9bSToomas Soome     mDNS_PlatformSupport *p;            // Pointer to platform-specific data of indeterminite size
2308cda73f64SToomas Soome     mDNSs32 NetworkChanged;
23095ffb0c9bSToomas Soome     mDNSBool CanReceiveUnicastOn5353;
23105ffb0c9bSToomas Soome     mDNSBool AdvertiseLocalAddresses;
23115ffb0c9bSToomas Soome     mDNSBool DivertMulticastAdvertisements; // from interfaces that do not advertise local addresses to local-only
23125ffb0c9bSToomas Soome     mStatus mDNSPlatformStatus;
23135ffb0c9bSToomas Soome     mDNSIPPort UnicastPort4;
23145ffb0c9bSToomas Soome     mDNSIPPort UnicastPort6;
23155ffb0c9bSToomas Soome     mDNSEthAddr PrimaryMAC;             // Used as unique host ID
23165ffb0c9bSToomas Soome     mDNSCallback *MainCallback;
23175ffb0c9bSToomas Soome     void         *MainContext;
23185ffb0c9bSToomas Soome 
23195ffb0c9bSToomas Soome     // For debugging: To catch and report locking failures
23205ffb0c9bSToomas Soome     mDNSu32 mDNS_busy;                  // Incremented between mDNS_Lock/mDNS_Unlock section
23215ffb0c9bSToomas Soome     mDNSu32 mDNS_reentrancy;            // Incremented when calling a client callback
23225ffb0c9bSToomas Soome     mDNSu8 lock_rrcache;                // For debugging: Set at times when these lists may not be modified
23235ffb0c9bSToomas Soome     mDNSu8 lock_Questions;
23245ffb0c9bSToomas Soome     mDNSu8 lock_Records;
23255ffb0c9bSToomas Soome #ifndef MaxMsg
23265ffb0c9bSToomas Soome     #define MaxMsg 512
23275ffb0c9bSToomas Soome #endif
23285ffb0c9bSToomas Soome     char MsgBuffer[MaxMsg];             // Temp storage used while building error log messages
23295ffb0c9bSToomas Soome 
23305ffb0c9bSToomas Soome     // Task Scheduling variables
23315ffb0c9bSToomas Soome     mDNSs32 timenow_adjust;             // Correction applied if we ever discover time went backwards
23325ffb0c9bSToomas Soome     mDNSs32 timenow;                    // The time that this particular activation of the mDNS code started
23335ffb0c9bSToomas Soome     mDNSs32 timenow_last;               // The time the last time we ran
23345ffb0c9bSToomas Soome     mDNSs32 NextScheduledEvent;         // Derived from values below
23355ffb0c9bSToomas Soome     mDNSs32 ShutdownTime;               // Set when we're shutting down; allows us to skip some unnecessary steps
23365ffb0c9bSToomas Soome     mDNSs32 SuppressSending;            // Don't send local-link mDNS packets during this time
23375ffb0c9bSToomas Soome     mDNSs32 NextCacheCheck;             // Next time to refresh cache record before it expires
23385ffb0c9bSToomas Soome     mDNSs32 NextScheduledQuery;         // Next time to send query in its exponential backoff sequence
23395ffb0c9bSToomas Soome     mDNSs32 NextScheduledProbe;         // Next time to probe for new authoritative record
23405ffb0c9bSToomas Soome     mDNSs32 NextScheduledResponse;      // Next time to send authoritative record(s) in responses
23415ffb0c9bSToomas Soome     mDNSs32 NextScheduledNATOp;         // Next time to send NAT-traversal packets
23425ffb0c9bSToomas Soome     mDNSs32 NextScheduledSPS;           // Next time to purge expiring Sleep Proxy records
23435ffb0c9bSToomas Soome     mDNSs32 NextScheduledKA;            // Next time to send Keepalive packets (SPS)
2344*c65ebfc7SToomas Soome #if BONJOUR_ON_DEMAND
2345*c65ebfc7SToomas Soome     mDNSs32 NextBonjourDisableTime;     // Next time to leave multicast group if Bonjour on Demand is enabled
2346*c65ebfc7SToomas Soome     mDNSu8 BonjourEnabled;              // Non zero if Bonjour is currently enabled by the Bonjour on Demand logic
2347*c65ebfc7SToomas Soome #endif // BONJOUR_ON_DEMAND
2348*c65ebfc7SToomas Soome     mDNSs32 DelayConflictProcessing;    // To prevent spurious confilcts due to stale packets on the wire/air.
23495ffb0c9bSToomas Soome     mDNSs32 RandomQueryDelay;           // For de-synchronization of query packets on the wire
23505ffb0c9bSToomas Soome     mDNSu32 RandomReconfirmDelay;       // For de-synchronization of reconfirmation queries on the wire
23515ffb0c9bSToomas Soome     mDNSs32 PktNum;                     // Unique sequence number assigned to each received packet
23525ffb0c9bSToomas Soome     mDNSs32 MPktNum;                    // Unique sequence number assigned to each received Multicast packet
23535ffb0c9bSToomas Soome     mDNSu8 LocalRemoveEvents;           // Set if we may need to deliver remove events for local-only questions and/or local-only records
23545ffb0c9bSToomas Soome     mDNSu8 SleepState;                  // Set if we're sleeping
23555ffb0c9bSToomas Soome     mDNSu8 SleepSeqNum;                 // "Epoch number" of our current period of wakefulness
23565ffb0c9bSToomas Soome     mDNSu8 SystemWakeOnLANEnabled;      // Set if we want to register with a Sleep Proxy before going to sleep
23575ffb0c9bSToomas Soome     mDNSu8 SentSleepProxyRegistration;  // Set if we registered (or tried to register) with a Sleep Proxy
23585ffb0c9bSToomas Soome     mDNSu8 SystemSleepOnlyIfWakeOnLAN;  // Set if we may only sleep if we managed to register with a Sleep Proxy
23595ffb0c9bSToomas Soome     mDNSs32 AnnounceOwner;              // After waking from sleep, include OWNER option in packets until this time
23605ffb0c9bSToomas Soome     mDNSs32 DelaySleep;                 // To inhibit re-sleeping too quickly right after wake
23615ffb0c9bSToomas Soome     mDNSs32 SleepLimit;                 // Time window to allow deregistrations, etc.,
23625ffb0c9bSToomas Soome                                         // during which underying platform layer should inhibit system sleep
23635ffb0c9bSToomas Soome     mDNSs32 TimeSlept;                  // Time we went to sleep.
23645ffb0c9bSToomas Soome 
23655ffb0c9bSToomas Soome     mDNSs32 UnicastPacketsSent;         // Number of unicast packets sent.
23665ffb0c9bSToomas Soome     mDNSs32 MulticastPacketsSent;       // Number of multicast packets sent.
23675ffb0c9bSToomas Soome     mDNSs32 RemoteSubnet;               // Multicast packets received from outside our subnet.
23685ffb0c9bSToomas Soome 
23695ffb0c9bSToomas Soome     mDNSs32 NextScheduledSPRetry;       // Time next sleep proxy registration action is required.
23705ffb0c9bSToomas Soome                                         // Only valid if SleepLimit is nonzero and DelaySleep is zero.
23715ffb0c9bSToomas Soome 
23725ffb0c9bSToomas Soome     mDNSs32 NextScheduledStopTime;      // Next time to stop a question
23735ffb0c9bSToomas Soome 
2374*c65ebfc7SToomas Soome     mDNSs32 NextBLEServiceTime;         // Next time to call the BLE discovery management layer.  Non zero when active.
23755ffb0c9bSToomas Soome 
23765ffb0c9bSToomas Soome     // These fields only required for mDNS Searcher...
23775ffb0c9bSToomas Soome     DNSQuestion *Questions;             // List of all registered questions, active and inactive
23785ffb0c9bSToomas Soome     DNSQuestion *NewQuestions;          // Fresh questions not yet answered from cache
23795ffb0c9bSToomas Soome     DNSQuestion *CurrentQuestion;       // Next question about to be examined in AnswerLocalQuestions()
23805ffb0c9bSToomas Soome     DNSQuestion *LocalOnlyQuestions;    // Questions with InterfaceID set to mDNSInterface_LocalOnly or mDNSInterface_P2P
23815ffb0c9bSToomas Soome     DNSQuestion *NewLocalOnlyQuestions; // Fresh local-only or P2P questions not yet answered
23825ffb0c9bSToomas Soome     DNSQuestion *RestartQuestion;       // Questions that are being restarted (stop followed by start)
23835ffb0c9bSToomas Soome     DNSQuestion *ValidationQuestion;    // Questions that are being validated (dnssec)
23845ffb0c9bSToomas Soome     mDNSu32 rrcache_size;               // Total number of available cache entries
23855ffb0c9bSToomas Soome     mDNSu32 rrcache_totalused;          // Number of cache entries currently occupied
23865ffb0c9bSToomas Soome     mDNSu32 rrcache_totalused_unicast;  // Number of cache entries currently occupied by unicast
23875ffb0c9bSToomas Soome     mDNSu32 rrcache_active;             // Number of cache entries currently occupied by records that answer active questions
23885ffb0c9bSToomas Soome     mDNSu32 rrcache_report;
23895ffb0c9bSToomas Soome     CacheEntity *rrcache_free;
23905ffb0c9bSToomas Soome     CacheGroup *rrcache_hash[CACHE_HASH_SLOTS];
23915ffb0c9bSToomas Soome     mDNSs32 rrcache_nextcheck[CACHE_HASH_SLOTS];
23925ffb0c9bSToomas Soome 
23935ffb0c9bSToomas Soome     AuthHash rrauth;
23945ffb0c9bSToomas Soome 
23955ffb0c9bSToomas Soome     // Fields below only required for mDNS Responder...
23965ffb0c9bSToomas Soome     domainlabel nicelabel;              // Rich text label encoded using canonically precomposed UTF-8
23975ffb0c9bSToomas Soome     domainlabel hostlabel;              // Conforms to RFC 1034 "letter-digit-hyphen" ARPANET host name rules
23985ffb0c9bSToomas Soome     domainname MulticastHostname;       // Fully Qualified "dot-local" Host Name, e.g. "Foo.local."
23995ffb0c9bSToomas Soome     UTF8str255 HIHardware;
24005ffb0c9bSToomas Soome     UTF8str255 HISoftware;
24015ffb0c9bSToomas Soome     AuthRecord DeviceInfo;
24025ffb0c9bSToomas Soome     AuthRecord *ResourceRecords;
24035ffb0c9bSToomas Soome     AuthRecord *DuplicateRecords;       // Records currently 'on hold' because they are duplicates of existing records
24045ffb0c9bSToomas Soome     AuthRecord *NewLocalRecords;        // Fresh AuthRecords (public) not yet delivered to our local-only questions
24055ffb0c9bSToomas Soome     AuthRecord *CurrentRecord;          // Next AuthRecord about to be examined
24065ffb0c9bSToomas Soome     mDNSBool NewLocalOnlyRecords;       // Fresh AuthRecords (local only) not yet delivered to our local questions
24075ffb0c9bSToomas Soome     NetworkInterfaceInfo *HostInterfaces;
24085ffb0c9bSToomas Soome     mDNSs32 ProbeFailTime;
24095ffb0c9bSToomas Soome     mDNSu32 NumFailedProbes;
24105ffb0c9bSToomas Soome     mDNSs32 SuppressProbes;
2411*c65ebfc7SToomas Soome     Platform_t mDNS_plat;               // Why is this here in the “only required for mDNS Responder” section? -- SC
24125ffb0c9bSToomas Soome 
24135ffb0c9bSToomas Soome     // Unicast-specific data
24145ffb0c9bSToomas Soome     mDNSs32 NextuDNSEvent;                  // uDNS next event
24155ffb0c9bSToomas Soome     mDNSs32 NextSRVUpdate;                  // Time to perform delayed update
24165ffb0c9bSToomas Soome 
24175ffb0c9bSToomas Soome     DNSServer        *DNSServers;           // list of DNS servers
24185ffb0c9bSToomas Soome     McastResolver    *McastResolvers;       // list of Mcast Resolvers
24195ffb0c9bSToomas Soome 
24205ffb0c9bSToomas Soome     mDNSAddr Router;
24215ffb0c9bSToomas Soome     mDNSAddr AdvertisedV4;                  // IPv4 address pointed to by hostname
24225ffb0c9bSToomas Soome     mDNSAddr AdvertisedV6;                  // IPv6 address pointed to by hostname
24235ffb0c9bSToomas Soome 
24245ffb0c9bSToomas Soome     DomainAuthInfo   *AuthInfoList;         // list of domains requiring authentication for updates
24255ffb0c9bSToomas Soome 
24265ffb0c9bSToomas Soome     DNSQuestion ReverseMap;                 // Reverse-map query to find static hostname for service target
24275ffb0c9bSToomas Soome     DNSQuestion AutomaticBrowseDomainQ;
24285ffb0c9bSToomas Soome     domainname StaticHostname;              // Current answer to reverse-map query
24295ffb0c9bSToomas Soome     domainname FQDN;
24305ffb0c9bSToomas Soome     HostnameInfo     *Hostnames;            // List of registered hostnames + hostname metadata
24315ffb0c9bSToomas Soome     NATTraversalInfo AutoTunnelNAT;         // Shared between all AutoTunnel DomainAuthInfo structs
24325ffb0c9bSToomas Soome     mDNSv6Addr AutoTunnelRelayAddr;
24335ffb0c9bSToomas Soome 
24345ffb0c9bSToomas Soome     mDNSu32 WABBrowseQueriesCount;          // Number of WAB Browse domain enumeration queries (b, db) callers
24355ffb0c9bSToomas Soome     mDNSu32 WABLBrowseQueriesCount;         // Number of legacy WAB Browse domain enumeration queries (lb) callers
24365ffb0c9bSToomas Soome     mDNSu32 WABRegQueriesCount;             // Number of WAB Registration domain enumeration queries (r, dr) callers
24375ffb0c9bSToomas Soome     mDNSu8 SearchDomainsHash[MD5_LEN];
24385ffb0c9bSToomas Soome 
24395ffb0c9bSToomas Soome     // NAT-Traversal fields
24405ffb0c9bSToomas Soome     NATTraversalInfo LLQNAT;                    // Single shared NAT Traversal to receive inbound LLQ notifications
24415ffb0c9bSToomas Soome     NATTraversalInfo *NATTraversals;
24425ffb0c9bSToomas Soome     NATTraversalInfo *CurrentNATTraversal;
24435ffb0c9bSToomas Soome     mDNSs32 retryIntervalGetAddr;               // delta between time sent and retry for NAT-PMP & UPnP/IGD external address request
24445ffb0c9bSToomas Soome     mDNSs32 retryGetAddr;                       // absolute time when we retry for NAT-PMP & UPnP/IGD external address request
24455ffb0c9bSToomas Soome     mDNSv4Addr ExtAddress;                      // the external address discovered via NAT-PMP or UPnP/IGD
24465ffb0c9bSToomas Soome     mDNSu32 PCPNonce[3];                        // the nonce if using PCP
24475ffb0c9bSToomas Soome 
24485ffb0c9bSToomas Soome     UDPSocket        *NATMcastRecvskt;          // For receiving PCP & NAT-PMP announcement multicasts from router on port 5350
24495ffb0c9bSToomas Soome     mDNSu32 LastNATupseconds;                   // NAT engine uptime in seconds, from most recent NAT packet
24505ffb0c9bSToomas Soome     mDNSs32 LastNATReplyLocalTime;              // Local time in ticks when most recent NAT packet was received
24515ffb0c9bSToomas Soome     mDNSu16 LastNATMapResultCode;               // Most recent error code for mappings
24525ffb0c9bSToomas Soome 
24535ffb0c9bSToomas Soome     tcpLNTInfo tcpAddrInfo;                     // legacy NAT traversal TCP connection info for external address
24545ffb0c9bSToomas Soome     tcpLNTInfo tcpDeviceInfo;                   // legacy NAT traversal TCP connection info for device info
24555ffb0c9bSToomas Soome     tcpLNTInfo       *tcpInfoUnmapList;         // list of pending unmap requests
24565ffb0c9bSToomas Soome     mDNSInterfaceID UPnPInterfaceID;
24575ffb0c9bSToomas Soome     UDPSocket        *SSDPSocket;               // For SSDP request/response
24585ffb0c9bSToomas Soome     mDNSBool SSDPWANPPPConnection;              // whether we should send the SSDP query for WANIPConnection or WANPPPConnection
24595ffb0c9bSToomas Soome     mDNSIPPort UPnPRouterPort;                  // port we send discovery messages to
24605ffb0c9bSToomas Soome     mDNSIPPort UPnPSOAPPort;                    // port we send SOAP messages to
2461*c65ebfc7SToomas Soome     char             *UPnPRouterURL;            // router's URL string
24625ffb0c9bSToomas Soome     mDNSBool UPnPWANPPPConnection;              // whether we're using WANIPConnection or WANPPPConnection
2463*c65ebfc7SToomas Soome     char             *UPnPSOAPURL;              // router's SOAP control URL string
2464*c65ebfc7SToomas Soome     char             *UPnPRouterAddressString;  // holds both the router's address and port
2465*c65ebfc7SToomas Soome     char             *UPnPSOAPAddressString;    // holds both address and port for SOAP messages
2466*c65ebfc7SToomas Soome 
2467*c65ebfc7SToomas Soome     // DNS Push Notification fields
2468*c65ebfc7SToomas Soome     DNSPushNotificationServer *DNSPushServers;  // DNS Push Notification Servers
2469*c65ebfc7SToomas Soome     DNSPushNotificationZone   *DNSPushZones;
24705ffb0c9bSToomas Soome 
24715ffb0c9bSToomas Soome     // Sleep Proxy client fields
24725ffb0c9bSToomas Soome     AuthRecord *SPSRRSet;                       // To help the client keep track of the records registered with the sleep proxy
24735ffb0c9bSToomas Soome 
24745ffb0c9bSToomas Soome     // Sleep Proxy Server fields
24755ffb0c9bSToomas Soome     mDNSu8 SPSType;                             // 0 = off, 10-99 encodes desirability metric
24765ffb0c9bSToomas Soome     mDNSu8 SPSPortability;                      // 10-99
24775ffb0c9bSToomas Soome     mDNSu8 SPSMarginalPower;                    // 10-99
24785ffb0c9bSToomas Soome     mDNSu8 SPSTotalPower;                       // 10-99
24795ffb0c9bSToomas Soome     mDNSu8 SPSFeatureFlags;                     // Features supported. Currently 1 = TCP KeepAlive supported.
24805ffb0c9bSToomas Soome     mDNSu8 SPSState;                            // 0 = off, 1 = running, 2 = shutting down, 3 = suspended during sleep
24815ffb0c9bSToomas Soome     mDNSInterfaceID SPSProxyListChanged;
24825ffb0c9bSToomas Soome     UDPSocket        *SPSSocket;
24835ffb0c9bSToomas Soome #ifndef SPC_DISABLED
24845ffb0c9bSToomas Soome     ServiceRecordSet SPSRecords;
24855ffb0c9bSToomas Soome #endif
24865ffb0c9bSToomas Soome     mDNSQuestionCallback *SPSBrowseCallback;    // So the platform layer can do something useful with SPS browse results
24875ffb0c9bSToomas Soome     int ProxyRecords;                           // Total number of records we're holding as proxy
24885ffb0c9bSToomas Soome     #define           MAX_PROXY_RECORDS 10000   /* DOS protection: 400 machines at 25 records each */
24895ffb0c9bSToomas Soome 
24905ffb0c9bSToomas Soome #if APPLE_OSX_mDNSResponder
24915ffb0c9bSToomas Soome     ClientTunnel     *TunnelClients;
24925ffb0c9bSToomas Soome     void            *WCF;
24935ffb0c9bSToomas Soome #endif
24945ffb0c9bSToomas Soome     // DNS Proxy fields
24955ffb0c9bSToomas Soome     mDNSu32 dp_ipintf[MaxIp];                   // input interface index list from the DNS Proxy Client
24965ffb0c9bSToomas Soome     mDNSu32 dp_opintf;                          // output interface index from the DNS Proxy Client
24975ffb0c9bSToomas Soome 
24985ffb0c9bSToomas Soome     TrustAnchor     *TrustAnchors;
24995ffb0c9bSToomas Soome     int             notifyToken;
2500cda73f64SToomas 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
25015ffb0c9bSToomas Soome     mDNSu32         AutoTargetServices;         // # of services that have AutoTarget set
2502*c65ebfc7SToomas Soome 
2503*c65ebfc7SToomas Soome #if BONJOUR_ON_DEMAND
2504*c65ebfc7SToomas Soome     // Counters used in Bonjour on Demand logic.
2505*c65ebfc7SToomas 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.)
2506*c65ebfc7SToomas Soome     mDNSu32         NumAllInterfaceQuestions;   // Right now we count *all* multicast questions here. Later we may want to change to count interface-specific questions separately.
2507*c65ebfc7SToomas Soome #endif // BONJOUR_ON_DEMAND
2508*c65ebfc7SToomas Soome 
25095ffb0c9bSToomas Soome     DNSSECStatistics DNSSECStats;
25105ffb0c9bSToomas Soome     mDNSStatistics   mDNSStats;
25115ffb0c9bSToomas Soome 
25125ffb0c9bSToomas Soome     // Fixed storage, to avoid creating large objects on the stack
25135ffb0c9bSToomas Soome     // The imsg is declared as a union with a pointer type to enforce CPU-appropriate alignment
25145ffb0c9bSToomas Soome     union { DNSMessage m; void *p; } imsg;  // Incoming message received from wire
25155ffb0c9bSToomas Soome     DNSMessage omsg;                        // Outgoing message we're building
25165ffb0c9bSToomas Soome     LargeCacheRecord rec;                   // Resource Record extracted from received message
25175ffb0c9bSToomas Soome };
25185ffb0c9bSToomas Soome 
25195ffb0c9bSToomas Soome #define FORALL_CACHERECORDS(SLOT,CG,CR)                           \
2520cda73f64SToomas Soome     for ((SLOT) = 0; (SLOT) < CACHE_HASH_SLOTS; (SLOT)++)         \
2521cda73f64SToomas Soome         for ((CG)=m->rrcache_hash[(SLOT)]; (CG); (CG)=(CG)->next) \
25225ffb0c9bSToomas Soome             for ((CR) = (CG)->members; (CR); (CR)=(CR)->next)
25234b22b933Srs 
25244b22b933Srs // ***************************************************************************
25254b22b933Srs #if 0
25265ffb0c9bSToomas Soome #pragma mark -
25274b22b933Srs #pragma mark - Useful Static Constants
25284b22b933Srs #endif
25294b22b933Srs 
25305ffb0c9bSToomas Soome extern const mDNSInterfaceID mDNSInterface_Any;             // Zero
25315ffb0c9bSToomas Soome extern const mDNSInterfaceID mDNSInterface_LocalOnly;       // Special value
25325ffb0c9bSToomas Soome extern const mDNSInterfaceID mDNSInterface_Unicast;         // Special value
25335ffb0c9bSToomas Soome extern const mDNSInterfaceID mDNSInterfaceMark;             // Special value
25345ffb0c9bSToomas Soome extern const mDNSInterfaceID mDNSInterface_P2P;             // Special value
25355ffb0c9bSToomas Soome extern const mDNSInterfaceID uDNSInterfaceMark;             // Special value
2536*c65ebfc7SToomas Soome extern const mDNSInterfaceID mDNSInterface_BLE;             // Special value
2537*c65ebfc7SToomas Soome 
2538*c65ebfc7SToomas Soome #define LocalOnlyOrP2PInterface(INTERFACE)  ((INTERFACE == mDNSInterface_LocalOnly) || (INTERFACE == mDNSInterface_P2P) || (INTERFACE == mDNSInterface_BLE))
25395ffb0c9bSToomas Soome 
25405ffb0c9bSToomas Soome extern const mDNSIPPort DiscardPort;
25415ffb0c9bSToomas Soome extern const mDNSIPPort SSHPort;
25425ffb0c9bSToomas Soome extern const mDNSIPPort UnicastDNSPort;
25435ffb0c9bSToomas Soome extern const mDNSIPPort SSDPPort;
25445ffb0c9bSToomas Soome extern const mDNSIPPort IPSECPort;
25455ffb0c9bSToomas Soome extern const mDNSIPPort NSIPCPort;
25465ffb0c9bSToomas Soome extern const mDNSIPPort NATPMPAnnouncementPort;
25475ffb0c9bSToomas Soome extern const mDNSIPPort NATPMPPort;
25485ffb0c9bSToomas Soome extern const mDNSIPPort DNSEXTPort;
25495ffb0c9bSToomas Soome extern const mDNSIPPort MulticastDNSPort;
25505ffb0c9bSToomas Soome extern const mDNSIPPort LoopbackIPCPort;
25515ffb0c9bSToomas Soome extern const mDNSIPPort PrivateDNSPort;
25525ffb0c9bSToomas Soome 
25535ffb0c9bSToomas Soome extern const OwnerOptData zeroOwner;
25545ffb0c9bSToomas Soome 
25555ffb0c9bSToomas Soome extern const mDNSIPPort zeroIPPort;
25565ffb0c9bSToomas Soome extern const mDNSv4Addr zerov4Addr;
25575ffb0c9bSToomas Soome extern const mDNSv6Addr zerov6Addr;
25585ffb0c9bSToomas Soome extern const mDNSEthAddr zeroEthAddr;
25595ffb0c9bSToomas Soome extern const mDNSv4Addr onesIPv4Addr;
25605ffb0c9bSToomas Soome extern const mDNSv6Addr onesIPv6Addr;
25615ffb0c9bSToomas Soome extern const mDNSEthAddr onesEthAddr;
25625ffb0c9bSToomas Soome extern const mDNSAddr zeroAddr;
25635ffb0c9bSToomas Soome 
25645ffb0c9bSToomas Soome extern const mDNSv4Addr AllDNSAdminGroup;
25655ffb0c9bSToomas Soome extern const mDNSv4Addr AllHosts_v4;
25665ffb0c9bSToomas Soome extern const mDNSv6Addr AllHosts_v6;
25675ffb0c9bSToomas Soome extern const mDNSv6Addr NDP_prefix;
25685ffb0c9bSToomas Soome extern const mDNSEthAddr AllHosts_v6_Eth;
25695ffb0c9bSToomas Soome extern const mDNSAddr AllDNSLinkGroup_v4;
25705ffb0c9bSToomas Soome extern const mDNSAddr AllDNSLinkGroup_v6;
25714b22b933Srs 
25724b22b933Srs extern const mDNSOpaque16 zeroID;
25735ffb0c9bSToomas Soome extern const mDNSOpaque16 onesID;
25744b22b933Srs extern const mDNSOpaque16 QueryFlags;
25754b22b933Srs extern const mDNSOpaque16 uQueryFlags;
25765ffb0c9bSToomas Soome extern const mDNSOpaque16 DNSSecQFlags;
25774b22b933Srs extern const mDNSOpaque16 ResponseFlags;
25784b22b933Srs extern const mDNSOpaque16 UpdateReqFlags;
25794b22b933Srs extern const mDNSOpaque16 UpdateRespFlags;
2580*c65ebfc7SToomas Soome extern const mDNSOpaque16 SubscribeFlags;
2581*c65ebfc7SToomas Soome extern const mDNSOpaque16 UnSubscribeFlags;
25824b22b933Srs 
25835ffb0c9bSToomas Soome extern const mDNSOpaque64 zeroOpaque64;
2584*c65ebfc7SToomas Soome extern const mDNSOpaque128 zeroOpaque128;
25855ffb0c9bSToomas Soome 
25865ffb0c9bSToomas Soome extern mDNSBool StrictUnicastOrdering;
25875ffb0c9bSToomas Soome extern mDNSu8 NumUnicastDNSServers;
2588cda73f64SToomas Soome #if APPLE_OSX_mDNSResponder
2589cda73f64SToomas Soome extern mDNSu8 NumUnreachableDNSServers;
2590cda73f64SToomas Soome #endif
25915ffb0c9bSToomas Soome 
25925ffb0c9bSToomas Soome #define localdomain           (*(const domainname *)"\x5" "local")
25935ffb0c9bSToomas Soome #define DeviceInfoName        (*(const domainname *)"\xC" "_device-info" "\x4" "_tcp")
25945ffb0c9bSToomas Soome #define LocalDeviceInfoName   (*(const domainname *)"\xC" "_device-info" "\x4" "_tcp" "\x5" "local")
25955ffb0c9bSToomas Soome #define SleepProxyServiceType (*(const domainname *)"\xC" "_sleep-proxy" "\x4" "_udp")
25965ffb0c9bSToomas Soome 
25974b22b933Srs // ***************************************************************************
25984b22b933Srs #if 0
25995ffb0c9bSToomas Soome #pragma mark -
26004b22b933Srs #pragma mark - Inline functions
26014b22b933Srs #endif
26024b22b933Srs 
26034b22b933Srs #if (defined(_MSC_VER))
26045ffb0c9bSToomas Soome     #define mDNSinline static __inline
26054b22b933Srs #elif ((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 9)))
26065ffb0c9bSToomas Soome     #define mDNSinline static inline
26074b22b933Srs #endif
26084b22b933Srs 
26094b22b933Srs // If we're not doing inline functions, then this header needs to have the extern declarations
26104b22b933Srs #if !defined(mDNSinline)
26114b22b933Srs extern mDNSs32      NonZeroTime(mDNSs32 t);
26124b22b933Srs extern mDNSu16      mDNSVal16(mDNSOpaque16 x);
26134b22b933Srs extern mDNSOpaque16 mDNSOpaque16fromIntVal(mDNSu16 v);
26144b22b933Srs #endif
26154b22b933Srs 
26164b22b933Srs // If we're compiling the particular C file that instantiates our inlines, then we
26174b22b933Srs // define "mDNSinline" (to empty string) so that we generate code in the following section
26184b22b933Srs #if (!defined(mDNSinline) && mDNS_InstantiateInlines)
26194b22b933Srs #define mDNSinline
26204b22b933Srs #endif
26214b22b933Srs 
26224b22b933Srs #ifdef mDNSinline
26234b22b933Srs 
26245ffb0c9bSToomas Soome mDNSinline mDNSs32 NonZeroTime(mDNSs32 t) { if (t) return(t);else return(1);}
26254b22b933Srs 
26264b22b933Srs mDNSinline mDNSu16 mDNSVal16(mDNSOpaque16 x) { return((mDNSu16)((mDNSu16)x.b[0] <<  8 | (mDNSu16)x.b[1])); }
26274b22b933Srs 
26284b22b933Srs mDNSinline mDNSOpaque16 mDNSOpaque16fromIntVal(mDNSu16 v)
26295ffb0c9bSToomas Soome {
26305ffb0c9bSToomas Soome     mDNSOpaque16 x;
26315ffb0c9bSToomas Soome     x.b[0] = (mDNSu8)(v >> 8);
26325ffb0c9bSToomas Soome     x.b[1] = (mDNSu8)(v & 0xFF);
26335ffb0c9bSToomas Soome     return(x);
26345ffb0c9bSToomas Soome }
26354b22b933Srs 
26364b22b933Srs #endif
26374b22b933Srs 
26384b22b933Srs // ***************************************************************************
26394b22b933Srs #if 0
26405ffb0c9bSToomas Soome #pragma mark -
26414b22b933Srs #pragma mark - Main Client Functions
26424b22b933Srs #endif
26434b22b933Srs 
26444b22b933Srs // Every client should call mDNS_Init, passing in storage for the mDNS object and the mDNS_PlatformSupport object.
26454b22b933Srs //
26464b22b933Srs // Clients that are only advertising services should use mDNS_Init_NoCache and mDNS_Init_ZeroCacheSize.
2647*c65ebfc7SToomas Soome // Clients that plan to perform queries (mDNS_StartQuery, mDNS_StartBrowse, etc.)
26484b22b933Srs // need to provide storage for the resource record cache, or the query calls will return 'mStatus_NoCache'.
26494b22b933Srs // The rrcachestorage parameter is the address of memory for the resource record cache, and
26504b22b933Srs // the rrcachesize parameter is the number of entries in the CacheRecord array passed in.
26514b22b933Srs // (i.e. the size of the cache memory needs to be sizeof(CacheRecord) * rrcachesize).
26524b22b933Srs // OS X 10.3 Panther uses an initial cache size of 64 entries, and then mDNSCore sends an
26534b22b933Srs // mStatus_GrowCache message if it needs more.
26544b22b933Srs //
26554b22b933Srs // Most clients should use mDNS_Init_AdvertiseLocalAddresses. This causes mDNSCore to automatically
26564b22b933Srs // create the correct address records for all the hosts interfaces. If you plan to advertise
26574b22b933Srs // services being offered by the local machine, this is almost always what you want.
26584b22b933Srs // There are two cases where you might use mDNS_Init_DontAdvertiseLocalAddresses:
26594b22b933Srs // 1. A client-only device, that browses for services but doesn't advertise any of its own.
26604b22b933Srs // 2. A proxy-registration service, that advertises services being offered by other machines, and takes
26614b22b933Srs //    the appropriate steps to manually create the correct address records for those other machines.
26624b22b933Srs // In principle, a proxy-like registration service could manually create address records for its own machine too,
26634b22b933Srs // but this would be pointless extra effort when using mDNS_Init_AdvertiseLocalAddresses does that for you.
26644b22b933Srs //
26655ffb0c9bSToomas Soome // Note that a client-only device that wishes to prohibit multicast advertisements (e.g. from
26665ffb0c9bSToomas Soome // higher-layer API calls) must also set DivertMulticastAdvertisements in the mDNS structure and
26675ffb0c9bSToomas Soome // advertise local address(es) on a loopback interface.
26685ffb0c9bSToomas Soome //
26694b22b933Srs // When mDNS has finished setting up the client's callback is called
26704b22b933Srs // A client can also spin and poll the mDNSPlatformStatus field to see when it changes from mStatus_Waiting to mStatus_NoError
26714b22b933Srs //
26725ffb0c9bSToomas Soome // Call mDNS_StartExit to tidy up before exiting
26735ffb0c9bSToomas Soome // Because exiting may be an asynchronous process (e.g. if unicast records need to be deregistered)
26745ffb0c9bSToomas Soome // client layer may choose to wait until mDNS_ExitNow() returns true before calling mDNS_FinalExit().
26754b22b933Srs //
26764b22b933Srs // Call mDNS_Register with a completed AuthRecord object to register a resource record
26774b22b933Srs // If the resource record type is kDNSRecordTypeUnique (or kDNSknownunique) then if a conflicting resource record is discovered,
26784b22b933Srs // the resource record's mDNSRecordCallback will be called with error code mStatus_NameConflict. The callback should deregister
26794b22b933Srs // the record, and may then try registering the record again after picking a new name (e.g. by automatically appending a number).
26804b22b933Srs // Following deregistration, the RecordCallback will be called with result mStatus_MemFree to signal that it is safe to deallocate
26814b22b933Srs // the record's storage (memory must be freed asynchronously to allow for goodbye packets and dynamic update deregistration).
26824b22b933Srs //
26834b22b933Srs // Call mDNS_StartQuery to initiate a query. mDNS will proceed to issue Multicast DNS query packets, and any time a response
26844b22b933Srs // is received containing a record which matches the question, the DNSQuestion's mDNSAnswerCallback function will be called
26854b22b933Srs // Call mDNS_StopQuery when no more answers are required
26864b22b933Srs //
26874b22b933Srs // Care should be taken on multi-threaded or interrupt-driven environments.
26884b22b933Srs // The main mDNS routines call mDNSPlatformLock() on entry and mDNSPlatformUnlock() on exit;
26894b22b933Srs // each platform layer needs to implement these appropriately for its respective platform.
26904b22b933Srs // For example, if the support code on a particular platform implements timer callbacks at interrupt time, then
26914b22b933Srs // mDNSPlatformLock/Unlock need to disable interrupts or do similar concurrency control to ensure that the mDNS
26924b22b933Srs // code is not entered by an interrupt-time timer callback while in the middle of processing a client call.
26934b22b933Srs 
26944b22b933Srs extern mStatus mDNS_Init      (mDNS *const m, mDNS_PlatformSupport *const p,
26955ffb0c9bSToomas Soome                                CacheEntity *rrcachestorage, mDNSu32 rrcachesize,
26965ffb0c9bSToomas Soome                                mDNSBool AdvertiseLocalAddresses,
26975ffb0c9bSToomas Soome                                mDNSCallback *Callback, void *Context);
26984b22b933Srs // See notes above on use of NoCache/ZeroCacheSize
26994b22b933Srs #define mDNS_Init_NoCache                     mDNSNULL
27004b22b933Srs #define mDNS_Init_ZeroCacheSize               0
27014b22b933Srs // See notes above on use of Advertise/DontAdvertiseLocalAddresses
27024b22b933Srs #define mDNS_Init_AdvertiseLocalAddresses     mDNStrue
27034b22b933Srs #define mDNS_Init_DontAdvertiseLocalAddresses mDNSfalse
27044b22b933Srs #define mDNS_Init_NoInitCallback              mDNSNULL
27054b22b933Srs #define mDNS_Init_NoInitCallbackContext       mDNSNULL
27064b22b933Srs 
27075ffb0c9bSToomas Soome extern void    mDNS_ConfigChanged(mDNS *const m);
27084b22b933Srs extern void    mDNS_GrowCache (mDNS *const m, CacheEntity *storage, mDNSu32 numrecords);
27095ffb0c9bSToomas Soome extern void    mDNS_StartExit (mDNS *const m);
27105ffb0c9bSToomas Soome extern void    mDNS_FinalExit (mDNS *const m);
27115ffb0c9bSToomas Soome #define mDNS_Close(m) do { mDNS_StartExit(m); mDNS_FinalExit(m); } while(0)
27125ffb0c9bSToomas Soome #define mDNS_ExitNow(m, now) ((now) - (m)->ShutdownTime >= 0 || (!(m)->ResourceRecords))
27135ffb0c9bSToomas Soome 
27144b22b933Srs extern mDNSs32 mDNS_Execute   (mDNS *const m);
27154b22b933Srs 
27164b22b933Srs extern mStatus mDNS_Register  (mDNS *const m, AuthRecord *const rr);
27174b22b933Srs extern mStatus mDNS_Update    (mDNS *const m, AuthRecord *const rr, mDNSu32 newttl,
27185ffb0c9bSToomas Soome                                const mDNSu16 newrdlength, RData *const newrdata, mDNSRecordUpdateCallback *Callback);
27194b22b933Srs extern mStatus mDNS_Deregister(mDNS *const m, AuthRecord *const rr);
27204b22b933Srs 
27214b22b933Srs extern mStatus mDNS_StartQuery(mDNS *const m, DNSQuestion *const question);
27224b22b933Srs extern mStatus mDNS_StopQuery (mDNS *const m, DNSQuestion *const question);
27235ffb0c9bSToomas Soome extern mStatus mDNS_StopQueryWithRemoves(mDNS *const m, DNSQuestion *const question);
27244b22b933Srs extern mStatus mDNS_Reconfirm (mDNS *const m, CacheRecord *const cacherr);
27255ffb0c9bSToomas Soome extern mStatus mDNS_Reconfirm_internal(mDNS *const m, CacheRecord *const rr, mDNSu32 interval);
27264b22b933Srs extern mStatus mDNS_ReconfirmByValue(mDNS *const m, ResourceRecord *const rr);
27275ffb0c9bSToomas Soome extern void    mDNS_PurgeCacheResourceRecord(mDNS *const m, CacheRecord *rr);
27284b22b933Srs extern mDNSs32 mDNS_TimeNow(const mDNS *const m);
27294b22b933Srs 
27305ffb0c9bSToomas Soome extern mStatus mDNS_StartNATOperation(mDNS *const m, NATTraversalInfo *traversal);
27315ffb0c9bSToomas Soome extern mStatus mDNS_StopNATOperation(mDNS *const m, NATTraversalInfo *traversal);
27325ffb0c9bSToomas Soome extern mStatus mDNS_StopNATOperation_internal(mDNS *m, NATTraversalInfo *traversal);
27335ffb0c9bSToomas Soome 
27345ffb0c9bSToomas Soome extern DomainAuthInfo *GetAuthInfoForName(mDNS *m, const domainname *const name);
27355ffb0c9bSToomas Soome 
27365ffb0c9bSToomas Soome extern void    mDNS_UpdateAllowSleep(mDNS *const m);
27375ffb0c9bSToomas Soome 
27384b22b933Srs // ***************************************************************************
27394b22b933Srs #if 0
27405ffb0c9bSToomas Soome #pragma mark -
27414b22b933Srs #pragma mark - Platform support functions that are accessible to the client layer too
27424b22b933Srs #endif
27434b22b933Srs 
27445ffb0c9bSToomas Soome extern mDNSs32 mDNSPlatformOneSecond;
27454b22b933Srs 
27464b22b933Srs // ***************************************************************************
27474b22b933Srs #if 0
27485ffb0c9bSToomas Soome #pragma mark -
27494b22b933Srs #pragma mark - General utility and helper functions
27504b22b933Srs #endif
27514b22b933Srs 
27525ffb0c9bSToomas Soome // mDNS_Dereg_normal is used for most calls to mDNS_Deregister_internal
27535ffb0c9bSToomas Soome // mDNS_Dereg_rapid is used to send one goodbye instead of three, when we want the memory available for reuse sooner
27545ffb0c9bSToomas Soome // mDNS_Dereg_conflict is used to indicate that this record is being forcibly deregistered because of a conflict
27555ffb0c9bSToomas Soome // mDNS_Dereg_repeat is used when cleaning up, for records that may have already been forcibly deregistered
27565ffb0c9bSToomas Soome typedef enum { mDNS_Dereg_normal, mDNS_Dereg_rapid, mDNS_Dereg_conflict, mDNS_Dereg_repeat } mDNS_Dereg_type;
27575ffb0c9bSToomas Soome 
27584b22b933Srs // mDNS_RegisterService is a single call to register the set of resource records associated with a given named service.
27594b22b933Srs //
27604b22b933Srs //
27614b22b933Srs // mDNS_AddRecordToService adds an additional record to a Service Record Set.  This record may be deregistered
27624b22b933Srs // via mDNS_RemoveRecordFromService, or by deregistering the service.  mDNS_RemoveRecordFromService is passed a
27634b22b933Srs // callback to free the memory associated with the extra RR when it is safe to do so.  The ExtraResourceRecord
27644b22b933Srs // object can be found in the record's context pointer.
27655ffb0c9bSToomas Soome 
27664b22b933Srs // mDNS_GetBrowseDomains is a special case of the mDNS_StartQuery call, where the resulting answers
27674b22b933Srs // are a list of PTR records indicating (in the rdata) domains that are recommended for browsing.
27684b22b933Srs // After getting the list of domains to browse, call mDNS_StopQuery to end the search.
27694b22b933Srs // mDNS_GetDefaultBrowseDomain returns the name of the domain that should be highlighted by default.
27704b22b933Srs //
27714b22b933Srs // mDNS_GetRegistrationDomains and mDNS_GetDefaultRegistrationDomain are the equivalent calls to get the list
27724b22b933Srs // of one or more domains that should be offered to the user as choices for where they may register their service,
27734b22b933Srs // and the default domain in which to register in the case where the user has made no selection.
27744b22b933Srs 
27754b22b933Srs extern void    mDNS_SetupResourceRecord(AuthRecord *rr, RData *RDataStorage, mDNSInterfaceID InterfaceID,
27765ffb0c9bSToomas Soome                                         mDNSu16 rrtype, mDNSu32 ttl, mDNSu8 RecordType, AuthRecType artype, mDNSRecordCallback Callback, void *Context);
27775ffb0c9bSToomas Soome 
2778*c65ebfc7SToomas Soome extern mDNSu32 deriveD2DFlagsFromAuthRecType(AuthRecType authRecType);
27794b22b933Srs extern mStatus mDNS_RegisterService  (mDNS *const m, ServiceRecordSet *sr,
27805ffb0c9bSToomas Soome                                       const domainlabel *const name, const domainname *const type, const domainname *const domain,
27815ffb0c9bSToomas Soome                                       const domainname *const host, mDNSIPPort port, const mDNSu8 txtinfo[], mDNSu16 txtlen,
27825ffb0c9bSToomas Soome                                       AuthRecord *SubTypes, mDNSu32 NumSubTypes,
27835ffb0c9bSToomas Soome                                       mDNSInterfaceID InterfaceID, mDNSServiceCallback Callback, void *Context, mDNSu32 flags);
27845ffb0c9bSToomas Soome extern mStatus mDNS_AddRecordToService(mDNS *const m, ServiceRecordSet *sr, ExtraResourceRecord *extra, RData *rdata, mDNSu32 ttl,  mDNSu32 flags);
27854b22b933Srs extern mStatus mDNS_RemoveRecordFromService(mDNS *const m, ServiceRecordSet *sr, ExtraResourceRecord *extra, mDNSRecordCallback MemFreeCallback, void *Context);
27864b22b933Srs extern mStatus mDNS_RenameAndReregisterService(mDNS *const m, ServiceRecordSet *const sr, const domainlabel *newname);
27875ffb0c9bSToomas Soome extern mStatus mDNS_DeregisterService_drt(mDNS *const m, ServiceRecordSet *sr, mDNS_Dereg_type drt);
27885ffb0c9bSToomas Soome #define mDNS_DeregisterService(M,S) mDNS_DeregisterService_drt((M), (S), mDNS_Dereg_normal)
27894b22b933Srs 
27904b22b933Srs extern mStatus mDNS_RegisterNoSuchService(mDNS *const m, AuthRecord *const rr,
27915ffb0c9bSToomas Soome                                           const domainlabel *const name, const domainname *const type, const domainname *const domain,
27925ffb0c9bSToomas Soome                                           const domainname *const host,
27935ffb0c9bSToomas Soome                                           const mDNSInterfaceID InterfaceID, mDNSRecordCallback Callback, void *Context, mDNSu32 flags);
27944b22b933Srs #define        mDNS_DeregisterNoSuchService mDNS_Deregister
27954b22b933Srs 
27965ffb0c9bSToomas Soome extern void mDNS_SetupQuestion(DNSQuestion *const q, const mDNSInterfaceID InterfaceID, const domainname *const name,
27975ffb0c9bSToomas Soome                                const mDNSu16 qtype, mDNSQuestionCallback *const callback, void *const context);
27985ffb0c9bSToomas Soome 
27994b22b933Srs extern mStatus mDNS_StartBrowse(mDNS *const m, DNSQuestion *const question,
28005ffb0c9bSToomas Soome                                 const domainname *const srv, const domainname *const domain, const mDNSu8 *anondata,
28015ffb0c9bSToomas Soome                                 const mDNSInterfaceID InterfaceID, mDNSu32 flags,
28025ffb0c9bSToomas Soome                                 mDNSBool ForceMCast, mDNSBool useBackgroundTrafficClass,
28035ffb0c9bSToomas Soome                                 mDNSQuestionCallback *Callback, void *Context);
28044b22b933Srs #define        mDNS_StopBrowse mDNS_StopQuery
28054b22b933Srs 
28064b22b933Srs 
28074b22b933Srs typedef enum
28085ffb0c9bSToomas Soome {
28095ffb0c9bSToomas Soome     mDNS_DomainTypeBrowse              = 0,
28105ffb0c9bSToomas Soome     mDNS_DomainTypeBrowseDefault       = 1,
28115ffb0c9bSToomas Soome     mDNS_DomainTypeBrowseAutomatic     = 2,
28125ffb0c9bSToomas Soome     mDNS_DomainTypeRegistration        = 3,
28135ffb0c9bSToomas Soome     mDNS_DomainTypeRegistrationDefault = 4,
28145ffb0c9bSToomas Soome 
28155ffb0c9bSToomas Soome     mDNS_DomainTypeMax = 4
28165ffb0c9bSToomas Soome } mDNS_DomainType;
28174b22b933Srs 
28184b22b933Srs extern const char *const mDNS_DomainTypeNames[];
28194b22b933Srs 
28204b22b933Srs extern mStatus mDNS_GetDomains(mDNS *const m, DNSQuestion *const question, mDNS_DomainType DomainType, const domainname *dom,
28215ffb0c9bSToomas Soome                                const mDNSInterfaceID InterfaceID, mDNSQuestionCallback *Callback, void *Context);
28224b22b933Srs #define        mDNS_StopGetDomains mDNS_StopQuery
28234b22b933Srs extern mStatus mDNS_AdvertiseDomains(mDNS *const m, AuthRecord *rr, mDNS_DomainType DomainType, const mDNSInterfaceID InterfaceID, char *domname);
28244b22b933Srs #define        mDNS_StopAdvertiseDomains mDNS_Deregister
28254b22b933Srs 
28265ffb0c9bSToomas Soome extern mDNSOpaque16 mDNS_NewMessageID(mDNS *const m);
2827cda73f64SToomas Soome extern mDNSBool mDNS_AddressIsLocalSubnet(mDNS *const m, const mDNSInterfaceID InterfaceID, const mDNSAddr *addr);
28285ffb0c9bSToomas Soome 
28295ffb0c9bSToomas Soome extern DNSServer *GetServerForQuestion(mDNS *m, DNSQuestion *question);
28305ffb0c9bSToomas Soome extern mDNSu32 SetValidDNSServers(mDNS *m, DNSQuestion *question);
28315ffb0c9bSToomas Soome 
28324b22b933Srs // ***************************************************************************
28334b22b933Srs #if 0
28345ffb0c9bSToomas Soome #pragma mark -
28354b22b933Srs #pragma mark - DNS name utility functions
28364b22b933Srs #endif
28374b22b933Srs 
28384b22b933Srs // In order to expose the full capabilities of the DNS protocol (which allows any arbitrary eight-bit values
28394b22b933Srs // in domain name labels, including unlikely characters like ascii nulls and even dots) all the mDNS APIs
28404b22b933Srs // work with DNS's native length-prefixed strings. For convenience in C, the following utility functions
28414b22b933Srs // are provided for converting between C's null-terminated strings and DNS's length-prefixed strings.
28424b22b933Srs 
28434b22b933Srs // Assignment
28444b22b933Srs // A simple C structure assignment of a domainname can cause a protection fault by accessing unmapped memory,
28454b22b933Srs // because that object is defined to be 256 bytes long, but not all domainname objects are truly the full size.
28464b22b933Srs // This macro uses mDNSPlatformMemCopy() to make sure it only touches the actual bytes that are valid.
28475ffb0c9bSToomas Soome #define AssignDomainName(DST, SRC) do { mDNSu16 len__ = DomainNameLength((SRC)); \
2848*c65ebfc7SToomas Soome     if (len__ <= MAX_DOMAIN_NAME) mDNSPlatformMemCopy((DST)->c, (SRC)->c, len__); else (DST)->c[0] = 0; } while(0)
28494b22b933Srs 
28504b22b933Srs // Comparison functions
28515ffb0c9bSToomas Soome #define SameDomainLabelCS(A,B) ((A)[0] == (B)[0] && mDNSPlatformMemSame((A)+1, (B)+1, (A)[0]))
28524b22b933Srs extern mDNSBool SameDomainLabel(const mDNSu8 *a, const mDNSu8 *b);
28534b22b933Srs extern mDNSBool SameDomainName(const domainname *const d1, const domainname *const d2);
28545ffb0c9bSToomas Soome extern mDNSBool SameDomainNameCS(const domainname *const d1, const domainname *const d2);
28555ffb0c9bSToomas Soome typedef mDNSBool DomainNameComparisonFn (const domainname *const d1, const domainname *const d2);
28564b22b933Srs extern mDNSBool IsLocalDomain(const domainname *d);     // returns true for domains that by default should be looked up using link-local multicast
28574b22b933Srs 
28585ffb0c9bSToomas Soome #define StripFirstLabel(X) ((const domainname *)& (X)->c[(X)->c[0] ? 1 + (X)->c[0] : 0])
28595ffb0c9bSToomas Soome 
28605ffb0c9bSToomas Soome #define FirstLabel(X)  ((const domainlabel *)(X))
28615ffb0c9bSToomas Soome #define SecondLabel(X) ((const domainlabel *)StripFirstLabel(X))
28625ffb0c9bSToomas Soome #define ThirdLabel(X)  ((const domainlabel *)StripFirstLabel(StripFirstLabel(X)))
28635ffb0c9bSToomas Soome 
28645ffb0c9bSToomas Soome extern const mDNSu8 *LastLabel(const domainname *d);
28655ffb0c9bSToomas Soome 
28664b22b933Srs // Get total length of domain name, in native DNS format, including terminal root label
28674b22b933Srs //   (e.g. length of "com." is 5 (length byte, three data bytes, final zero)
28685ffb0c9bSToomas Soome extern mDNSu16  DomainNameLengthLimit(const domainname *const name, const mDNSu8 *limit);
28695ffb0c9bSToomas Soome #define DomainNameLength(name) DomainNameLengthLimit((name), (name)->c + MAX_DOMAIN_NAME)
28704b22b933Srs 
28714b22b933Srs // Append functions to append one or more labels to an existing native format domain name:
28724b22b933Srs //   AppendLiteralLabelString adds a single label from a literal C string, with no escape character interpretation.
28734b22b933Srs //   AppendDNSNameString      adds zero or more labels from a C string using conventional DNS dots-and-escaping interpretation
28744b22b933Srs //   AppendDomainLabel        adds a single label from a native format domainlabel
28754b22b933Srs //   AppendDomainName         adds zero or more labels from a native format domainname
28764b22b933Srs extern mDNSu8  *AppendLiteralLabelString(domainname *const name, const char *cstr);
28774b22b933Srs extern mDNSu8  *AppendDNSNameString     (domainname *const name, const char *cstr);
28784b22b933Srs extern mDNSu8  *AppendDomainLabel       (domainname *const name, const domainlabel *const label);
28794b22b933Srs extern mDNSu8  *AppendDomainName        (domainname *const name, const domainname *const append);
28804b22b933Srs 
28814b22b933Srs // Convert from null-terminated string to native DNS format:
28824b22b933Srs //   The DomainLabel form makes a single label from a literal C string, with no escape character interpretation.
28834b22b933Srs //   The DomainName form makes native format domain name from a C string using conventional DNS interpretation:
28844b22b933Srs //     dots separate labels, and within each label, '\.' represents a literal dot, '\\' represents a literal
28854b22b933Srs //     backslash and backslash with three decimal digits (e.g. \000) represents an arbitrary byte value.
28864b22b933Srs extern mDNSBool MakeDomainLabelFromLiteralString(domainlabel *const label, const char *cstr);
28874b22b933Srs extern mDNSu8  *MakeDomainNameFromDNSNameString (domainname  *const name,  const char *cstr);
28884b22b933Srs 
28894b22b933Srs // Convert native format domainlabel or domainname back to C string format
28904b22b933Srs // IMPORTANT:
28914b22b933Srs // When using ConvertDomainLabelToCString, the target buffer must be MAX_ESCAPED_DOMAIN_LABEL (254) bytes long
28924b22b933Srs // to guarantee there will be no buffer overrun. It is only safe to use a buffer shorter than this in rare cases
28934b22b933Srs // where the label is known to be constrained somehow (for example, if the label is known to be either "_tcp" or "_udp").
28945ffb0c9bSToomas Soome // Similarly, when using ConvertDomainNameToCString, the target buffer must be MAX_ESCAPED_DOMAIN_NAME (1009) bytes long.
28954b22b933Srs // See definitions of MAX_ESCAPED_DOMAIN_LABEL and MAX_ESCAPED_DOMAIN_NAME for more detailed explanation.
28964b22b933Srs extern char    *ConvertDomainLabelToCString_withescape(const domainlabel *const name, char *cstr, char esc);
28974b22b933Srs #define         ConvertDomainLabelToCString_unescaped(D,C) ConvertDomainLabelToCString_withescape((D), (C), 0)
28984b22b933Srs #define         ConvertDomainLabelToCString(D,C)           ConvertDomainLabelToCString_withescape((D), (C), '\\')
28994b22b933Srs extern char    *ConvertDomainNameToCString_withescape(const domainname *const name, char *cstr, char esc);
29004b22b933Srs #define         ConvertDomainNameToCString_unescaped(D,C) ConvertDomainNameToCString_withescape((D), (C), 0)
29014b22b933Srs #define         ConvertDomainNameToCString(D,C)           ConvertDomainNameToCString_withescape((D), (C), '\\')
29024b22b933Srs 
29034b22b933Srs extern void     ConvertUTF8PstringToRFC1034HostLabel(const mDNSu8 UTF8Name[], domainlabel *const hostlabel);
29044b22b933Srs 
2905*c65ebfc7SToomas Soome #define ValidTransportProtocol(X) ( (X)[0] == 4 && (X)[1] == '_' && \
2906*c65ebfc7SToomas Soome                                     ((((X)[2] | 0x20) == 'u' && ((X)[3] | 0x20) == 'd') || (((X)[2] | 0x20) == 't' && ((X)[3] | 0x20) == 'c')) && \
2907*c65ebfc7SToomas Soome                                     ((X)[4] | 0x20) == 'p')
2908*c65ebfc7SToomas Soome 
29094b22b933Srs extern mDNSu8  *ConstructServiceName(domainname *const fqdn, const domainlabel *name, const domainname *type, const domainname *const domain);
29104b22b933Srs extern mDNSBool DeconstructServiceName(const domainname *const fqdn, domainlabel *const name, domainname *const type, domainname *const domain);
29114b22b933Srs 
29124b22b933Srs // Note: Some old functions have been replaced by more sensibly-named versions.
29134b22b933Srs // You can uncomment the hash-defines below if you don't want to have to change your source code right away.
29144b22b933Srs // When updating your code, note that (unlike the old versions) *all* the new routines take the target object
29154b22b933Srs // as their first parameter.
29164b22b933Srs //#define ConvertCStringToDomainName(SRC,DST)  MakeDomainNameFromDNSNameString((DST),(SRC))
29174b22b933Srs //#define ConvertCStringToDomainLabel(SRC,DST) MakeDomainLabelFromLiteralString((DST),(SRC))
29184b22b933Srs //#define AppendStringLabelToName(DST,SRC)     AppendLiteralLabelString((DST),(SRC))
29194b22b933Srs //#define AppendStringNameToName(DST,SRC)      AppendDNSNameString((DST),(SRC))
29204b22b933Srs //#define AppendDomainLabelToName(DST,SRC)     AppendDomainLabel((DST),(SRC))
29214b22b933Srs //#define AppendDomainNameToName(DST,SRC)      AppendDomainName((DST),(SRC))
29224b22b933Srs 
29234b22b933Srs // ***************************************************************************
29244b22b933Srs #if 0
29255ffb0c9bSToomas Soome #pragma mark -
29264b22b933Srs #pragma mark - Other utility functions and macros
29274b22b933Srs #endif
29284b22b933Srs 
29294b22b933Srs // mDNS_vsnprintf/snprintf return the number of characters written, excluding the final terminating null.
29304b22b933Srs // The output is always null-terminated: for example, if the output turns out to be exactly buflen long,
29314b22b933Srs // then the output will be truncated by one character to allow space for the terminating null.
29324b22b933Srs // Unlike standard C vsnprintf/snprintf, they return the number of characters *actually* written,
29334b22b933Srs // not the number of characters that *would* have been printed were buflen unlimited.
2934*c65ebfc7SToomas Soome extern mDNSu32 mDNS_vsnprintf(char *sbuffer, mDNSu32 buflen, const char *fmt, va_list arg) IS_A_PRINTF_STYLE_FUNCTION(3,0);
29354b22b933Srs extern mDNSu32 mDNS_snprintf(char *sbuffer, mDNSu32 buflen, const char *fmt, ...) IS_A_PRINTF_STYLE_FUNCTION(3,4);
29364b22b933Srs extern mDNSu32 NumCacheRecordsForInterfaceID(const mDNS *const m, mDNSInterfaceID id);
29374b22b933Srs extern char *DNSTypeName(mDNSu16 rrtype);
29385ffb0c9bSToomas Soome extern char *GetRRDisplayString_rdb(const ResourceRecord *const rr, const RDataBody *const rd1, char *const buffer);
29394b22b933Srs #define RRDisplayString(m, rr) GetRRDisplayString_rdb(rr, &(rr)->rdata->u, (m)->MsgBuffer)
29404b22b933Srs #define ARDisplayString(m, rr) GetRRDisplayString_rdb(&(rr)->resrec, &(rr)->resrec.rdata->u, (m)->MsgBuffer)
29414b22b933Srs #define CRDisplayString(m, rr) GetRRDisplayString_rdb(&(rr)->resrec, &(rr)->resrec.rdata->u, (m)->MsgBuffer)
29424b22b933Srs extern mDNSBool mDNSSameAddress(const mDNSAddr *ip1, const mDNSAddr *ip2);
29434b22b933Srs extern void IncrementLabelSuffix(domainlabel *name, mDNSBool RichText);
29445ffb0c9bSToomas Soome extern mDNSBool mDNSv4AddrIsRFC1918(const mDNSv4Addr * const addr);  // returns true for RFC1918 private addresses
29455ffb0c9bSToomas Soome #define mDNSAddrIsRFC1918(X) ((X)->type == mDNSAddrType_IPv4 && mDNSv4AddrIsRFC1918(&(X)->ip.v4))
29465ffb0c9bSToomas Soome 
29475ffb0c9bSToomas Soome // For PCP
29485ffb0c9bSToomas Soome extern void mDNSAddrMapIPv4toIPv6(mDNSv4Addr* in, mDNSv6Addr* out);
29495ffb0c9bSToomas Soome extern mDNSBool mDNSAddrIPv4FromMappedIPv6(mDNSv6Addr *in, mDNSv4Addr *out);
29505ffb0c9bSToomas Soome 
29515ffb0c9bSToomas Soome #define mDNSSameIPPort(A,B)      ((A).NotAnInteger == (B).NotAnInteger)
29525ffb0c9bSToomas Soome #define mDNSSameOpaque16(A,B)    ((A).NotAnInteger == (B).NotAnInteger)
29535ffb0c9bSToomas Soome #define mDNSSameOpaque32(A,B)    ((A).NotAnInteger == (B).NotAnInteger)
29545ffb0c9bSToomas Soome #define mDNSSameOpaque64(A,B)    ((A)->l[0] == (B)->l[0] && (A)->l[1] == (B)->l[1])
29554b22b933Srs 
29564b22b933Srs #define mDNSSameIPv4Address(A,B) ((A).NotAnInteger == (B).NotAnInteger)
29574b22b933Srs #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])
29585ffb0c9bSToomas Soome #define mDNSSameIPv6NetworkPart(A,B) ((A).l[0] == (B).l[0] && (A).l[1] == (B).l[1])
29594b22b933Srs #define mDNSSameEthAddress(A,B)  ((A)->w[0] == (B)->w[0] && (A)->w[1] == (B)->w[1] && (A)->w[2] == (B)->w[2])
29604b22b933Srs 
29615ffb0c9bSToomas Soome #define mDNSIPPortIsZero(A)      ((A).NotAnInteger                            == 0)
29625ffb0c9bSToomas Soome #define mDNSOpaque16IsZero(A)    ((A).NotAnInteger                            == 0)
29635ffb0c9bSToomas Soome #define mDNSOpaque64IsZero(A)    (((A)->l[0] | (A)->l[1]                    ) == 0)
2964*c65ebfc7SToomas Soome #define mDNSOpaque128IsZero(A)   (((A)->l[0] | (A)->l[1] | (A)->l[2] | (A)->l[3]) == 0)
29655ffb0c9bSToomas Soome #define mDNSIPv4AddressIsZero(A) ((A).NotAnInteger                            == 0)
29665ffb0c9bSToomas Soome #define mDNSIPv6AddressIsZero(A) (((A).l[0] | (A).l[1] | (A).l[2] | (A).l[3]) == 0)
29675ffb0c9bSToomas Soome #define mDNSEthAddressIsZero(A)  (((A).w[0] | (A).w[1] | (A).w[2]           ) == 0)
29684b22b933Srs 
29695ffb0c9bSToomas Soome #define mDNSIPv4AddressIsOnes(A) ((A).NotAnInteger == 0xFFFFFFFF)
29705ffb0c9bSToomas Soome #define mDNSIPv6AddressIsOnes(A) (((A).l[0] & (A).l[1] & (A).l[2] & (A).l[3]) == 0xFFFFFFFF)
29714b22b933Srs 
29725ffb0c9bSToomas Soome #define mDNSAddressIsAllDNSLinkGroup(X) (                                                            \
29735ffb0c9bSToomas Soome         ((X)->type == mDNSAddrType_IPv4 && mDNSSameIPv4Address((X)->ip.v4, AllDNSLinkGroup_v4.ip.v4)) || \
29745ffb0c9bSToomas Soome         ((X)->type == mDNSAddrType_IPv6 && mDNSSameIPv6Address((X)->ip.v6, AllDNSLinkGroup_v6.ip.v6))    )
29754b22b933Srs 
29764b22b933Srs #define mDNSAddressIsZero(X) (                                                \
29775ffb0c9bSToomas Soome         ((X)->type == mDNSAddrType_IPv4 && mDNSIPv4AddressIsZero((X)->ip.v4))  || \
29785ffb0c9bSToomas Soome         ((X)->type == mDNSAddrType_IPv6 && mDNSIPv6AddressIsZero((X)->ip.v6))     )
29794b22b933Srs 
29804b22b933Srs #define mDNSAddressIsValidNonZero(X) (                                        \
29815ffb0c9bSToomas Soome         ((X)->type == mDNSAddrType_IPv4 && !mDNSIPv4AddressIsZero((X)->ip.v4)) || \
29825ffb0c9bSToomas Soome         ((X)->type == mDNSAddrType_IPv6 && !mDNSIPv6AddressIsZero((X)->ip.v6))    )
29834b22b933Srs 
29844b22b933Srs #define mDNSAddressIsOnes(X) (                                                \
29855ffb0c9bSToomas Soome         ((X)->type == mDNSAddrType_IPv4 && mDNSIPv4AddressIsOnes((X)->ip.v4))  || \
29865ffb0c9bSToomas Soome         ((X)->type == mDNSAddrType_IPv6 && mDNSIPv6AddressIsOnes((X)->ip.v6))     )
29874b22b933Srs 
29884b22b933Srs #define mDNSAddressIsValid(X) (                                                                                             \
29895ffb0c9bSToomas Soome         ((X)->type == mDNSAddrType_IPv4) ? !(mDNSIPv4AddressIsZero((X)->ip.v4) || mDNSIPv4AddressIsOnes((X)->ip.v4)) :          \
29905ffb0c9bSToomas Soome         ((X)->type == mDNSAddrType_IPv6) ? !(mDNSIPv6AddressIsZero((X)->ip.v6) || mDNSIPv6AddressIsOnes((X)->ip.v6)) : mDNSfalse)
29915ffb0c9bSToomas Soome 
29925ffb0c9bSToomas Soome #define mDNSv4AddressIsLinkLocal(X) ((X)->b[0] ==  169 &&  (X)->b[1]         ==  254)
29935ffb0c9bSToomas Soome #define mDNSv6AddressIsLinkLocal(X) ((X)->b[0] == 0xFE && ((X)->b[1] & 0xC0) == 0x80)
29945ffb0c9bSToomas Soome 
29955ffb0c9bSToomas Soome #define mDNSAddressIsLinkLocal(X)  (                                                    \
29965ffb0c9bSToomas Soome         ((X)->type == mDNSAddrType_IPv4) ? mDNSv4AddressIsLinkLocal(&(X)->ip.v4) :          \
29975ffb0c9bSToomas Soome         ((X)->type == mDNSAddrType_IPv6) ? mDNSv6AddressIsLinkLocal(&(X)->ip.v6) : mDNSfalse)
29984b22b933Srs 
29994b22b933Srs 
30004b22b933Srs // ***************************************************************************
30014b22b933Srs #if 0
30025ffb0c9bSToomas Soome #pragma mark -
30034b22b933Srs #pragma mark - Authentication Support
30044b22b933Srs #endif
30054b22b933Srs 
30064b22b933Srs // Unicast DNS and Dynamic Update specific Client Calls
30074b22b933Srs //
30085ffb0c9bSToomas Soome // mDNS_SetSecretForDomain tells the core to authenticate (via TSIG with an HMAC_MD5 hash of the shared secret)
30094b22b933Srs // when dynamically updating a given zone (and its subdomains).  The key used in authentication must be in
30104b22b933Srs // domain name format.  The shared secret must be a null-terminated base64 encoded string.  A minimum size of
30114b22b933Srs // 16 bytes (128 bits) is recommended for an MD5 hash as per RFC 2485.
30124b22b933Srs // Calling this routine multiple times for a zone replaces previously entered values.  Call with a NULL key
30135ffb0c9bSToomas Soome // to disable authentication for the zone.  A non-NULL autoTunnelPrefix means this is an AutoTunnel domain,
30145ffb0c9bSToomas Soome // and the value is prepended to the IPSec identifier (used for key lookup)
30154b22b933Srs 
30165ffb0c9bSToomas Soome extern mStatus mDNS_SetSecretForDomain(mDNS *m, DomainAuthInfo *info,
30175ffb0c9bSToomas Soome                                        const domainname *domain, const domainname *keyname, const char *b64keydata, const domainname *hostname, mDNSIPPort *port, mDNSBool autoTunnel);
30185ffb0c9bSToomas Soome 
30195ffb0c9bSToomas Soome extern void RecreateNATMappings(mDNS *const m, const mDNSu32 waitTicks);
30204b22b933Srs 
30214b22b933Srs // Hostname/Unicast Interface Configuration
30224b22b933Srs 
30234b22b933Srs // All hostnames advertised point to one IPv4 address and/or one IPv6 address, set via SetPrimaryInterfaceInfo.  Invoking this routine
30244b22b933Srs // updates all existing hostnames to point to the new address.
30255ffb0c9bSToomas Soome 
30264b22b933Srs // A hostname is added via AddDynDNSHostName, which points to the primary interface's v4 and/or v6 addresss
30274b22b933Srs 
30284b22b933Srs // The status callback is invoked to convey success or failure codes - the callback should not modify the AuthRecord or free memory.
30294b22b933Srs // Added hostnames may be removed (deregistered) via mDNS_RemoveDynDNSHostName.
30304b22b933Srs 
30314b22b933Srs // Host domains added prior to specification of the primary interface address and computer name will be deferred until
30324b22b933Srs // these values are initialized.
30334b22b933Srs 
30345ffb0c9bSToomas Soome // DNS servers used to resolve unicast queries are specified by mDNS_AddDNSServer.
30354b22b933Srs // For "split" DNS configurations, in which queries for different domains are sent to different servers (e.g. VPN and external),
30364b22b933Srs // a domain may be associated with a DNS server.  For standard configurations, specify the root label (".") or NULL.
30375ffb0c9bSToomas Soome 
30384b22b933Srs extern void mDNS_AddDynDNSHostName(mDNS *m, const domainname *fqdn, mDNSRecordCallback *StatusCallback, const void *StatusContext);
30394b22b933Srs extern void mDNS_RemoveDynDNSHostName(mDNS *m, const domainname *fqdn);
30404b22b933Srs extern void mDNS_SetPrimaryInterfaceInfo(mDNS *m, const mDNSAddr *v4addr,  const mDNSAddr *v6addr, const mDNSAddr *router);
30415ffb0c9bSToomas Soome extern DNSServer *mDNS_AddDNSServer(mDNS *const m, const domainname *d, const mDNSInterfaceID interface, mDNSs32 serviceID, const mDNSAddr *addr,
3042*c65ebfc7SToomas Soome                                     const mDNSIPPort port, mDNSu32 scoped, mDNSu32 timeout, mDNSBool cellIntf, mDNSBool isExpensive, mDNSu16 resGroupID,
3043*c65ebfc7SToomas Soome                                     mDNSBool reqA, mDNSBool reqAAAA, mDNSBool reqDO);
30445ffb0c9bSToomas Soome extern void PenalizeDNSServer(mDNS *const m, DNSQuestion *q, mDNSOpaque16 responseFlags);
30455ffb0c9bSToomas Soome extern void mDNS_AddSearchDomain(const domainname *const domain, mDNSInterfaceID InterfaceID);
30464b22b933Srs 
30475ffb0c9bSToomas Soome extern McastResolver *mDNS_AddMcastResolver(mDNS *const m, const domainname *d, const mDNSInterfaceID interface, mDNSu32 timeout);
30485ffb0c9bSToomas Soome 
30495ffb0c9bSToomas Soome // We use ((void *)0) here instead of mDNSNULL to avoid compile warnings on gcc 4.2
30505ffb0c9bSToomas Soome #define mDNS_AddSearchDomain_CString(X, I) \
30515ffb0c9bSToomas Soome     do { domainname d__; if (((X) != (void*)0) && MakeDomainNameFromDNSNameString(&d__, (X)) && d__.c[0]) mDNS_AddSearchDomain(&d__, I);} while(0)
30524b22b933Srs 
30535ffb0c9bSToomas Soome // Routines called by the core, exported by DNSDigest.c
30544b22b933Srs 
30555ffb0c9bSToomas Soome // Convert an arbitrary base64 encoded key key into an HMAC key (stored in AuthInfo struct)
30565ffb0c9bSToomas Soome extern mDNSs32 DNSDigest_ConstructHMACKeyfromBase64(DomainAuthInfo *info, const char *b64key);
30574b22b933Srs 
30585ffb0c9bSToomas Soome // sign a DNS message.  The message must be complete, with all values in network byte order.  end points to the end
30594b22b933Srs // of the message, and is modified by this routine.  numAdditionals is a pointer to the number of additional
30604b22b933Srs // records in HOST byte order, which is incremented upon successful completion of this routine.  The function returns
30614b22b933Srs // the new end pointer on success, and NULL on failure.
30625ffb0c9bSToomas Soome extern void DNSDigest_SignMessage(DNSMessage *msg, mDNSu8 **end, DomainAuthInfo *info, mDNSu16 tcode);
30635ffb0c9bSToomas Soome 
30645ffb0c9bSToomas Soome #define SwapDNSHeaderBytes(M) do { \
30655ffb0c9bSToomas Soome     (M)->h.numQuestions   = (mDNSu16)((mDNSu8 *)&(M)->h.numQuestions  )[0] << 8 | ((mDNSu8 *)&(M)->h.numQuestions  )[1]; \
30665ffb0c9bSToomas Soome     (M)->h.numAnswers     = (mDNSu16)((mDNSu8 *)&(M)->h.numAnswers    )[0] << 8 | ((mDNSu8 *)&(M)->h.numAnswers    )[1]; \
30675ffb0c9bSToomas Soome     (M)->h.numAuthorities = (mDNSu16)((mDNSu8 *)&(M)->h.numAuthorities)[0] << 8 | ((mDNSu8 *)&(M)->h.numAuthorities)[1]; \
30685ffb0c9bSToomas Soome     (M)->h.numAdditionals = (mDNSu16)((mDNSu8 *)&(M)->h.numAdditionals)[0] << 8 | ((mDNSu8 *)&(M)->h.numAdditionals)[1]; \
30695ffb0c9bSToomas Soome } while (0)
30705ffb0c9bSToomas Soome 
30715ffb0c9bSToomas Soome #define DNSDigest_SignMessageHostByteOrder(M,E,INFO) \
30725ffb0c9bSToomas Soome     do { SwapDNSHeaderBytes(M); DNSDigest_SignMessage((M), (E), (INFO), 0); SwapDNSHeaderBytes(M); } while (0)
30735ffb0c9bSToomas Soome 
30745ffb0c9bSToomas Soome // verify a DNS message.  The message must be complete, with all values in network byte order.  end points to the
30755ffb0c9bSToomas Soome // end of the record.  tsig is a pointer to the resource record that contains the TSIG OPT record.  info is
30765ffb0c9bSToomas Soome // the matching key to use for verifying the message.  This function expects that the additionals member
30775ffb0c9bSToomas Soome // of the DNS message header has already had one subtracted from it.
30785ffb0c9bSToomas Soome extern mDNSBool DNSDigest_VerifyMessage(DNSMessage *msg, mDNSu8 *end, LargeCacheRecord *tsig, DomainAuthInfo *info, mDNSu16 *rcode, mDNSu16 *tcode);
30794b22b933Srs 
30804b22b933Srs // ***************************************************************************
30814b22b933Srs #if 0
30825ffb0c9bSToomas Soome #pragma mark -
30834b22b933Srs #pragma mark - PlatformSupport interface
30844b22b933Srs #endif
30854b22b933Srs 
30864b22b933Srs // This section defines the interface to the Platform Support layer.
30874b22b933Srs // Normal client code should not use any of types defined here, or directly call any of the functions defined here.
30884b22b933Srs // The definitions are placed here because sometimes clients do use these calls indirectly, via other supported client operations.
30894b22b933Srs // For example, AssignDomainName is a macro defined using mDNSPlatformMemCopy()
30904b22b933Srs 
30914b22b933Srs // Every platform support module must provide the following functions.
30924b22b933Srs // mDNSPlatformInit() typically opens a communication endpoint, and starts listening for mDNS packets.
30934b22b933Srs // When Setup is complete, the platform support layer calls mDNSCoreInitComplete().
30944b22b933Srs // mDNSPlatformSendUDP() sends one UDP packet
30954b22b933Srs // When a packet is received, the PlatformSupport code calls mDNSCoreReceive()
30964b22b933Srs // mDNSPlatformClose() tidies up on exit
30974b22b933Srs //
30984b22b933Srs // Note: mDNSPlatformMemAllocate/mDNSPlatformMemFree are only required for handling oversized resource records and unicast DNS.
30994b22b933Srs // If your target platform has a well-defined specialized application, and you know that all the records it uses
31004b22b933Srs // are InlineCacheRDSize or less, then you can just make a simple mDNSPlatformMemAllocate() stub that always returns
31015ffb0c9bSToomas Soome // NULL. InlineCacheRDSize is a compile-time constant, which is set by default to 68. If you need to handle records
31024b22b933Srs // a little larger than this and you don't want to have to implement run-time allocation and freeing, then you
31034b22b933Srs // can raise the value of this constant to a suitable value (at the expense of increased memory usage).
31044b22b933Srs //
31054b22b933Srs // USE CAUTION WHEN CALLING mDNSPlatformRawTime: The m->timenow_adjust correction factor needs to be added
31064b22b933Srs // Generally speaking:
31074b22b933Srs // Code that's protected by the main mDNS lock should just use the m->timenow value
31084b22b933Srs // Code outside the main mDNS lock should use mDNS_TimeNow(m) to get properly adjusted time
31094b22b933Srs // In certain cases there may be reasons why it's necessary to get the time without taking the lock first
31104b22b933Srs // (e.g. inside the routines that are doing the locking and unlocking, where a call to get the lock would result in a
31114b22b933Srs // recursive loop); in these cases use mDNS_TimeNow_NoLock(m) to get mDNSPlatformRawTime with the proper correction factor added.
31124b22b933Srs //
31134b22b933Srs // mDNSPlatformUTC returns the time, in seconds, since Jan 1st 1970 UTC and is required for generating TSIG records
31144b22b933Srs 
31154b22b933Srs extern mStatus  mDNSPlatformInit        (mDNS *const m);
31164b22b933Srs extern void     mDNSPlatformClose       (mDNS *const m);
31174b22b933Srs extern mStatus  mDNSPlatformSendUDP(const mDNS *const m, const void *const msg, const mDNSu8 *const end,
3118*c65ebfc7SToomas Soome                                     mDNSInterfaceID InterfaceID, UDPSocket *src, const mDNSAddr *dst,
31195ffb0c9bSToomas Soome                                     mDNSIPPort dstport, mDNSBool useBackgroundTrafficClass);
31204b22b933Srs 
31214b22b933Srs extern void     mDNSPlatformLock        (const mDNS *const m);
31224b22b933Srs extern void     mDNSPlatformUnlock      (const mDNS *const m);
31234b22b933Srs 
31245ffb0c9bSToomas Soome extern void     mDNSPlatformStrCopy     (      void *dst, const void *src);
3125*c65ebfc7SToomas Soome extern mDNSu32  mDNSPlatformStrLCopy    (      void *dst, const void *src, mDNSu32 len);
31265ffb0c9bSToomas Soome extern mDNSu32  mDNSPlatformStrLen      (                 const void *src);
31275ffb0c9bSToomas Soome extern void     mDNSPlatformMemCopy     (      void *dst, const void *src, mDNSu32 len);
31285ffb0c9bSToomas Soome extern mDNSBool mDNSPlatformMemSame     (const void *dst, const void *src, mDNSu32 len);
31295ffb0c9bSToomas Soome extern int      mDNSPlatformMemCmp      (const void *dst, const void *src, mDNSu32 len);
31305ffb0c9bSToomas Soome extern void     mDNSPlatformMemZero     (      void *dst,                  mDNSu32 len);
31315ffb0c9bSToomas Soome extern void mDNSPlatformQsort       (void *base, int nel, int width, int (*compar)(const void *, const void *));
31325ffb0c9bSToomas Soome #if APPLE_OSX_mDNSResponder && MACOSX_MDNS_MALLOC_DEBUGGING
31335ffb0c9bSToomas Soome #define         mDNSPlatformMemAllocate(X) mallocL(# X, X)
31345ffb0c9bSToomas Soome #else
31354b22b933Srs extern void *   mDNSPlatformMemAllocate (mDNSu32 len);
31365ffb0c9bSToomas Soome #endif
31374b22b933Srs extern void     mDNSPlatformMemFree     (void *mem);
31385ffb0c9bSToomas Soome 
31395ffb0c9bSToomas Soome // If the platform doesn't have a strong PRNG, we define a naive multiply-and-add based on a seed
31405ffb0c9bSToomas Soome // from the platform layer.  Long-term, we should embed an arc4 implementation, but the strength
31415ffb0c9bSToomas Soome // will still depend on the randomness of the seed.
31425ffb0c9bSToomas Soome #if !defined(_PLATFORM_HAS_STRONG_PRNG_) && (_BUILDING_XCODE_PROJECT_ || defined(_WIN32))
31435ffb0c9bSToomas Soome #define _PLATFORM_HAS_STRONG_PRNG_ 1
31445ffb0c9bSToomas Soome #endif
31455ffb0c9bSToomas Soome #if _PLATFORM_HAS_STRONG_PRNG_
31465ffb0c9bSToomas Soome extern mDNSu32  mDNSPlatformRandomNumber(void);
31475ffb0c9bSToomas Soome #else
31484b22b933Srs extern mDNSu32  mDNSPlatformRandomSeed  (void);
31495ffb0c9bSToomas Soome #endif // _PLATFORM_HAS_STRONG_PRNG_
31505ffb0c9bSToomas Soome 
31514b22b933Srs extern mStatus  mDNSPlatformTimeInit    (void);
31524b22b933Srs extern mDNSs32  mDNSPlatformRawTime     (void);
31534b22b933Srs extern mDNSs32  mDNSPlatformUTC         (void);
31545ffb0c9bSToomas Soome #define mDNS_TimeNow_NoLock(m) (mDNSPlatformRawTime() + (m)->timenow_adjust)
31555ffb0c9bSToomas Soome 
31565ffb0c9bSToomas Soome #if MDNS_DEBUGMSGS
31575ffb0c9bSToomas Soome extern void mDNSPlatformWriteDebugMsg(const char *msg);
31585ffb0c9bSToomas Soome #endif
31595ffb0c9bSToomas Soome extern void mDNSPlatformWriteLogMsg(const char *ident, const char *msg, mDNSLogLevel_t loglevel);
31605ffb0c9bSToomas Soome 
31614b22b933Srs // Platform support modules should provide the following functions to map between opaque interface IDs
31624b22b933Srs // and interface indexes in order to support the DNS-SD API. If your target platform does not support
31634b22b933Srs // multiple interfaces and/or does not support the DNS-SD API, these functions can be empty.
31645ffb0c9bSToomas Soome extern mDNSInterfaceID mDNSPlatformInterfaceIDfromInterfaceIndex(mDNS *const m, mDNSu32 ifindex);
31655ffb0c9bSToomas Soome extern mDNSu32 mDNSPlatformInterfaceIndexfromInterfaceID(mDNS *const m, mDNSInterfaceID id, mDNSBool suppressNetworkChange);
31664b22b933Srs 
31674b22b933Srs // Every platform support module must provide the following functions if it is to support unicast DNS
31684b22b933Srs // and Dynamic Update.
31694b22b933Srs // All TCP socket operations implemented by the platform layer MUST NOT BLOCK.
31704b22b933Srs // mDNSPlatformTCPConnect initiates a TCP connection with a peer, adding the socket descriptor to the
31714b22b933Srs // main event loop.  The return value indicates whether the connection succeeded, failed, or is pending
31724b22b933Srs // (i.e. the call would block.)  On return, the descriptor parameter is set to point to the connected socket.
31734b22b933Srs // The TCPConnectionCallback is subsequently invoked when the connection
31744b22b933Srs // completes (in which case the ConnectionEstablished parameter is true), or data is available for
31754b22b933Srs // reading on the socket (indicated by the ConnectionEstablished parameter being false.)  If the connection
31764b22b933Srs // asynchronously fails, the TCPConnectionCallback should be invoked as usual, with the error being
31774b22b933Srs // returned in subsequent calls to PlatformReadTCP or PlatformWriteTCP.  (This allows for platforms
31784b22b933Srs // with limited asynchronous error detection capabilities.)  PlatformReadTCP and PlatformWriteTCP must
31795ffb0c9bSToomas Soome // return the number of bytes read/written, 0 if the call would block, and -1 if an error.  PlatformReadTCP
31805ffb0c9bSToomas Soome // should set the closed argument if the socket has been closed.
31814b22b933Srs // PlatformTCPCloseConnection must close the connection to the peer and remove the descriptor from the
31824b22b933Srs // event loop.  CloseConnectin may be called at any time, including in a ConnectionCallback.
31834b22b933Srs 
31845ffb0c9bSToomas Soome typedef enum
31855ffb0c9bSToomas Soome {
31865ffb0c9bSToomas Soome     kTCPSocketFlags_Zero   = 0,
31875ffb0c9bSToomas Soome     kTCPSocketFlags_UseTLS = (1 << 0)
31885ffb0c9bSToomas Soome } TCPSocketFlags;
31895ffb0c9bSToomas Soome 
31905ffb0c9bSToomas Soome typedef void (*TCPConnectionCallback)(TCPSocket *sock, void *context, mDNSBool ConnectionEstablished, mStatus err);
3191*c65ebfc7SToomas Soome extern TCPSocket *mDNSPlatformTCPSocket(TCPSocketFlags flags, mDNSIPPort *port, mDNSBool useBackgroundTrafficClass); // creates a TCP socket
31925ffb0c9bSToomas Soome extern TCPSocket *mDNSPlatformTCPAccept(TCPSocketFlags flags, int sd);
31935ffb0c9bSToomas Soome extern int        mDNSPlatformTCPGetFD(TCPSocket *sock);
31945ffb0c9bSToomas Soome extern mStatus    mDNSPlatformTCPConnect(TCPSocket *sock, const mDNSAddr *dst, mDNSOpaque16 dstport, domainname *hostname,
31955ffb0c9bSToomas Soome                                          mDNSInterfaceID InterfaceID, TCPConnectionCallback callback, void *context);
31965ffb0c9bSToomas Soome extern void       mDNSPlatformTCPCloseConnection(TCPSocket *sock);
31975ffb0c9bSToomas Soome extern long       mDNSPlatformReadTCP(TCPSocket *sock, void *buf, unsigned long buflen, mDNSBool *closed);
31985ffb0c9bSToomas Soome extern long       mDNSPlatformWriteTCP(TCPSocket *sock, const char *msg, unsigned long len);
3199*c65ebfc7SToomas Soome extern UDPSocket *mDNSPlatformUDPSocket(const mDNSIPPort requestedport);
32005ffb0c9bSToomas Soome extern mDNSu16    mDNSPlatformGetUDPPort(UDPSocket *sock);
32015ffb0c9bSToomas Soome extern void       mDNSPlatformUDPClose(UDPSocket *sock);
3202*c65ebfc7SToomas Soome extern mDNSBool   mDNSPlatformUDPSocketEncounteredEOF(const UDPSocket *sock);
3203*c65ebfc7SToomas Soome extern void       mDNSPlatformReceiveBPF_fd(int fd);
3204*c65ebfc7SToomas Soome extern void       mDNSPlatformUpdateProxyList(const mDNSInterfaceID InterfaceID);
32055ffb0c9bSToomas Soome extern void       mDNSPlatformSendRawPacket(const void *const msg, const mDNSu8 *const end, mDNSInterfaceID InterfaceID);
3206*c65ebfc7SToomas Soome extern void       mDNSPlatformSetLocalAddressCacheEntry(const mDNSAddr *const tpa, const mDNSEthAddr *const tha, mDNSInterfaceID InterfaceID);
32075ffb0c9bSToomas Soome extern void       mDNSPlatformSourceAddrForDest(mDNSAddr *const src, const mDNSAddr *const dst);
32085ffb0c9bSToomas Soome extern void       mDNSPlatformSendKeepalive(mDNSAddr *sadd, mDNSAddr *dadd, mDNSIPPort *lport, mDNSIPPort *rport, mDNSu32 seq, mDNSu32 ack, mDNSu16 win);
3209*c65ebfc7SToomas Soome extern mStatus    mDNSPlatformRetrieveTCPInfo(mDNSAddr *laddr, mDNSIPPort *lport, mDNSAddr *raddr,  mDNSIPPort *rport, mDNSTCPInfo *mti);
3210*c65ebfc7SToomas Soome extern mStatus    mDNSPlatformGetRemoteMacAddr(mDNSAddr *raddr);
32115ffb0c9bSToomas Soome extern mStatus    mDNSPlatformStoreSPSMACAddr(mDNSAddr *spsaddr, char *ifname);
3212*c65ebfc7SToomas Soome extern mStatus    mDNSPlatformClearSPSData(void);
3213*c65ebfc7SToomas Soome extern mStatus    mDNSPlatformStoreOwnerOptRecord(char *ifname, DNSMessage *msg, int length);
32145ffb0c9bSToomas Soome 
32155ffb0c9bSToomas Soome // mDNSPlatformTLSSetupCerts/mDNSPlatformTLSTearDownCerts used by dnsextd
32165ffb0c9bSToomas Soome extern mStatus    mDNSPlatformTLSSetupCerts(void);
32175ffb0c9bSToomas Soome extern void       mDNSPlatformTLSTearDownCerts(void);
32184b22b933Srs 
32194b22b933Srs // Platforms that support unicast browsing and dynamic update registration for clients who do not specify a domain
32204b22b933Srs // in browse/registration calls must implement these routines to get the "default" browse/registration list.
32214b22b933Srs 
3222*c65ebfc7SToomas Soome extern mDNSBool   mDNSPlatformSetDNSConfig(mDNSBool setservers, mDNSBool setsearch, domainname *const fqdn, DNameListElem **RegDomains,
32235ffb0c9bSToomas Soome                         DNameListElem **BrowseDomains, mDNSBool ackConfig);
3224*c65ebfc7SToomas Soome extern mStatus    mDNSPlatformGetPrimaryInterface(mDNSAddr *v4, mDNSAddr *v6, mDNSAddr *router);
32255ffb0c9bSToomas Soome extern void       mDNSPlatformDynDNSHostNameStatusChanged(const domainname *const dname, const mStatus status);
32264b22b933Srs 
3227*c65ebfc7SToomas Soome extern void       mDNSPlatformSetAllowSleep(mDNSBool allowSleep, const char *reason);
3228*c65ebfc7SToomas Soome extern void       mDNSPlatformPreventSleep(mDNSu32 timeout, const char *reason);
3229*c65ebfc7SToomas Soome extern void       mDNSPlatformSendWakeupPacket(mDNSInterfaceID InterfaceID, char *EthAddr, char *IPAddr, int iteration);
32304b22b933Srs 
32315ffb0c9bSToomas Soome extern mDNSBool   mDNSPlatformInterfaceIsD2D(mDNSInterfaceID InterfaceID);
32325ffb0c9bSToomas Soome extern mDNSBool   mDNSPlatformInterfaceIsAWDL(const NetworkInterfaceInfo *intf);
32335ffb0c9bSToomas Soome extern mDNSBool   mDNSPlatformValidRecordForQuestion(const ResourceRecord *const rr, const DNSQuestion *const q);
3234*c65ebfc7SToomas Soome extern mDNSBool   mDNSPlatformValidRecordForInterface(const AuthRecord *rr, mDNSInterfaceID InterfaceID);
32355ffb0c9bSToomas Soome extern mDNSBool   mDNSPlatformValidQuestionForInterface(DNSQuestion *q, const NetworkInterfaceInfo *intf);
32365ffb0c9bSToomas Soome 
32375ffb0c9bSToomas Soome extern void mDNSPlatformFormatTime(unsigned long t, mDNSu8 *buf, int bufsize);
32384b22b933Srs 
32394b22b933Srs #ifdef _LEGACY_NAT_TRAVERSAL_
32404b22b933Srs // Support for legacy NAT traversal protocols, implemented by the platform layer and callable by the core.
32415ffb0c9bSToomas Soome extern void     LNT_SendDiscoveryMsg(mDNS *m);
32425ffb0c9bSToomas Soome extern void     LNT_ConfigureRouterInfo(mDNS *m, const mDNSInterfaceID InterfaceID, const mDNSu8 *const data, const mDNSu16 len);
32435ffb0c9bSToomas Soome extern mStatus  LNT_GetExternalAddress(mDNS *m);
32445ffb0c9bSToomas Soome extern mStatus  LNT_MapPort(mDNS *m, NATTraversalInfo *const n);
32455ffb0c9bSToomas Soome extern mStatus  LNT_UnmapPort(mDNS *m, NATTraversalInfo *const n);
32465ffb0c9bSToomas Soome extern void     LNT_ClearState(mDNS *const m);
32474b22b933Srs #endif // _LEGACY_NAT_TRAVERSAL_
32484b22b933Srs 
32494b22b933Srs // The core mDNS code provides these functions, for the platform support code to call at appropriate times
32504b22b933Srs //
32514b22b933Srs // mDNS_SetFQDN() is called once on startup (typically from mDNSPlatformInit())
32524b22b933Srs // and then again on each subsequent change of the host name.
32534b22b933Srs //
32544b22b933Srs // mDNS_RegisterInterface() is used by the platform support layer to inform mDNSCore of what
32554b22b933Srs // physical and/or logical interfaces are available for sending and receiving packets.
32564b22b933Srs // Typically it is called on startup for each available interface, but register/deregister may be
32574b22b933Srs // called again later, on multiple occasions, to inform the core of interface configuration changes.
32584b22b933Srs // If set->Advertise is set non-zero, then mDNS_RegisterInterface() also registers the standard
32594b22b933Srs // resource records that should be associated with every publicised IP address/interface:
32604b22b933Srs // -- Name-to-address records (A/AAAA)
32614b22b933Srs // -- Address-to-name records (PTR)
32624b22b933Srs // -- Host information (HINFO)
32634b22b933Srs // IMPORTANT: The specified mDNSInterfaceID MUST NOT be 0, -1, or -2; these values have special meaning
32644b22b933Srs // mDNS_RegisterInterface does not result in the registration of global hostnames via dynamic update -
32654b22b933Srs // see mDNS_SetPrimaryInterfaceInfo, mDNS_AddDynDNSHostName, etc. for this purpose.
32664b22b933Srs // Note that the set may be deallocated immediately after it is deregistered via mDNS_DeegisterInterface.
32674b22b933Srs //
32684b22b933Srs // mDNS_RegisterDNS() is used by the platform support layer to provide the core with the addresses of
32694b22b933Srs // available domain name servers for unicast queries/updates.  RegisterDNS() should be called once for
32704b22b933Srs // each name server, typically at startup, or when a new name server becomes available.  DeregiterDNS()
32714b22b933Srs // must be called whenever a registered name server becomes unavailable.  DeregisterDNSList deregisters
32724b22b933Srs // all registered servers.  mDNS_DNSRegistered() returns true if one or more servers are registered in the core.
32734b22b933Srs //
32744b22b933Srs // mDNSCoreInitComplete() is called when the platform support layer is finished.
32754b22b933Srs // Typically this is at the end of mDNSPlatformInit(), but may be later
32764b22b933Srs // (on platforms like OT that allow asynchronous initialization of the networking stack).
32774b22b933Srs //
32784b22b933Srs // mDNSCoreReceive() is called when a UDP packet is received
32794b22b933Srs //
32804b22b933Srs // mDNSCoreMachineSleep() is called when the machine sleeps or wakes
32814b22b933Srs // (This refers to heavyweight laptop-style sleep/wake that disables network access,
32824b22b933Srs // not lightweight second-by-second CPU power management modes.)
32834b22b933Srs 
32844b22b933Srs extern void     mDNS_SetFQDN(mDNS *const m);
32855ffb0c9bSToomas Soome extern void     mDNS_ActivateNetWake_internal  (mDNS *const m, NetworkInterfaceInfo *set);
32865ffb0c9bSToomas Soome extern void     mDNS_DeactivateNetWake_internal(mDNS *const m, NetworkInterfaceInfo *set);
3287*c65ebfc7SToomas Soome 
3288*c65ebfc7SToomas Soome // Attributes that controls the Bonjour operation initiation and response speed for an interface.
3289*c65ebfc7SToomas Soome typedef enum
3290*c65ebfc7SToomas Soome {
3291*c65ebfc7SToomas Soome     FastActivation,     // For p2p* and DirectLink type interfaces
3292*c65ebfc7SToomas Soome     NormalActivation,   // For standard interface timing
3293*c65ebfc7SToomas Soome     SlowActivation      // For flapping interfaces
3294*c65ebfc7SToomas Soome } InterfaceActivationSpeed;
3295*c65ebfc7SToomas Soome 
3296*c65ebfc7SToomas Soome extern mStatus  mDNS_RegisterInterface  (mDNS *const m, NetworkInterfaceInfo *set, InterfaceActivationSpeed probeDelay);
3297*c65ebfc7SToomas Soome extern void     mDNS_DeregisterInterface(mDNS *const m, NetworkInterfaceInfo *set, InterfaceActivationSpeed probeDelay);
32984b22b933Srs extern void     mDNSCoreInitComplete(mDNS *const m, mStatus result);
3299*c65ebfc7SToomas Soome extern void     mDNSCoreReceive(mDNS *const m, DNSMessage *const msg, const mDNSu8 *const end,
33005ffb0c9bSToomas Soome                                 const mDNSAddr *const srcaddr, const mDNSIPPort srcport,
33015ffb0c9bSToomas Soome                                 const mDNSAddr *dstaddr, const mDNSIPPort dstport, const mDNSInterfaceID InterfaceID);
33025ffb0c9bSToomas Soome extern void     mDNSCoreRestartQueries(mDNS *const m);
33035ffb0c9bSToomas Soome extern void     mDNSCoreRestartQuestion(mDNS *const m, DNSQuestion *q);
33045ffb0c9bSToomas Soome extern void     mDNSCoreRestartRegistration(mDNS *const m, AuthRecord  *rr, int announceCount);
33055ffb0c9bSToomas Soome typedef void (*FlushCache)(mDNS *const m);
33065ffb0c9bSToomas Soome typedef void (*CallbackBeforeStartQuery)(mDNS *const m, void *context);
33075ffb0c9bSToomas Soome extern void     mDNSCoreRestartAddressQueries(mDNS *const m, mDNSBool SearchDomainsChanged, FlushCache flushCacheRecords,
33085ffb0c9bSToomas Soome                                               CallbackBeforeStartQuery beforeQueryStart, void *context);
33095ffb0c9bSToomas Soome extern mDNSBool mDNSCoreHaveAdvertisedMulticastServices(mDNS *const m);
33104b22b933Srs extern void     mDNSCoreMachineSleep(mDNS *const m, mDNSBool wake);
33115ffb0c9bSToomas Soome extern mDNSBool mDNSCoreReadyForSleep(mDNS *m, mDNSs32 now);
33125ffb0c9bSToomas Soome extern mDNSs32  mDNSCoreIntervalToNextWake(mDNS *const m, mDNSs32 now);
33135ffb0c9bSToomas Soome 
33145ffb0c9bSToomas Soome extern void     mDNSCoreReceiveRawPacket  (mDNS *const m, const mDNSu8 *const p, const mDNSu8 *const end, const mDNSInterfaceID InterfaceID);
33154b22b933Srs 
33164b22b933Srs extern mDNSBool mDNSAddrIsDNSMulticast(const mDNSAddr *ip);
33174b22b933Srs 
33185ffb0c9bSToomas Soome extern CacheRecord *CreateNewCacheEntry(mDNS *const m, const mDNSu32 slot, CacheGroup *cg, mDNSs32 delay, mDNSBool Add, const mDNSAddr *sourceAddress);
3319*c65ebfc7SToomas Soome extern CacheGroup *CacheGroupForName(const mDNS *const m, const mDNSu32 namehash, const domainname *const name);
33205ffb0c9bSToomas Soome extern void ReleaseCacheRecord(mDNS *const m, CacheRecord *r);
33215ffb0c9bSToomas Soome extern void ScheduleNextCacheCheckTime(mDNS *const m, const mDNSu32 slot, const mDNSs32 event);
33225ffb0c9bSToomas Soome extern void SetNextCacheCheckTimeForRecord(mDNS *const m, CacheRecord *const rr);
33235ffb0c9bSToomas Soome extern void GrantCacheExtensions(mDNS *const m, DNSQuestion *q, mDNSu32 lease);
33245ffb0c9bSToomas Soome extern void MakeNegativeCacheRecord(mDNS *const m, CacheRecord *const cr,
33255ffb0c9bSToomas Soome                                     const domainname *const name, const mDNSu32 namehash, const mDNSu16 rrtype, const mDNSu16 rrclass, mDNSu32 ttl_seconds,
33265ffb0c9bSToomas Soome                                     mDNSInterfaceID InterfaceID, DNSServer *dnsserver);
33275ffb0c9bSToomas Soome extern void CompleteDeregistration(mDNS *const m, AuthRecord *rr);
33285ffb0c9bSToomas Soome extern void AnswerCurrentQuestionWithResourceRecord(mDNS *const m, CacheRecord *const rr, const QC_result AddRecord);
33295ffb0c9bSToomas Soome extern void AnswerQuestionByFollowingCNAME(mDNS *const m, DNSQuestion *q, ResourceRecord *rr);
33305ffb0c9bSToomas Soome extern char *InterfaceNameForID(mDNS *const m, const mDNSInterfaceID InterfaceID);
33315ffb0c9bSToomas Soome extern void DNSServerChangeForQuestion(mDNS *const m, DNSQuestion *q, DNSServer *newServer);
33325ffb0c9bSToomas Soome extern void ActivateUnicastRegistration(mDNS *const m, AuthRecord *const rr);
33335ffb0c9bSToomas Soome extern void CheckSuppressUnusableQuestions(mDNS *const m);
33345ffb0c9bSToomas Soome extern void RetrySearchDomainQuestions(mDNS *const m);
33355ffb0c9bSToomas Soome extern mDNSBool DomainEnumQuery(const domainname *qname);
33365ffb0c9bSToomas Soome extern mStatus UpdateKeepaliveRData(mDNS *const m, AuthRecord *rr, NetworkInterfaceInfo *const intf, mDNSBool updateMac, char *ethAddr);
33375ffb0c9bSToomas Soome extern void  UpdateKeepaliveRMACAsync(mDNS *const m, void *context);
3338*c65ebfc7SToomas Soome extern void UpdateRMAC(mDNS *const m, void *context);
33395ffb0c9bSToomas Soome 
33405ffb0c9bSToomas Soome // Used only in logging to restrict the number of /etc/hosts entries printed
33415ffb0c9bSToomas Soome extern void FreeEtcHosts(mDNS *const m, AuthRecord *const rr, mStatus result);
33425ffb0c9bSToomas Soome // exported for using the hash for /etc/hosts AuthRecords
3343*c65ebfc7SToomas Soome extern AuthGroup *AuthGroupForName(AuthHash *r, const mDNSu32 namehash, const domainname *const name);
3344*c65ebfc7SToomas Soome extern AuthGroup *AuthGroupForRecord(AuthHash *r, const ResourceRecord *const rr);
33455ffb0c9bSToomas Soome extern AuthGroup *InsertAuthRecord(mDNS *const m, AuthHash *r, AuthRecord *rr);
33465ffb0c9bSToomas Soome extern AuthGroup *RemoveAuthRecord(mDNS *const m, AuthHash *r, AuthRecord *rr);
33475ffb0c9bSToomas Soome extern mDNSBool mDNS_CheckForCacheRecord(mDNS *const m, DNSQuestion *q, mDNSu16 qtype);
33485ffb0c9bSToomas Soome 
33495ffb0c9bSToomas Soome // For now this AutoTunnel stuff is specific to Mac OS X.
33505ffb0c9bSToomas Soome // In the future, if there's demand, we may see if we can abstract it out cleanly into the platform layer
33515ffb0c9bSToomas Soome #if APPLE_OSX_mDNSResponder
33525ffb0c9bSToomas Soome extern void AutoTunnelCallback(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord);
3353*c65ebfc7SToomas Soome extern void AddNewClientTunnel(DNSQuestion *const q);
3354*c65ebfc7SToomas Soome extern void StartServerTunnel(DomainAuthInfo *const info);
33555ffb0c9bSToomas Soome extern void UpdateAutoTunnelDomainStatuses(const mDNS *const m);
33565ffb0c9bSToomas Soome extern void RemoveAutoTunnel6Record(mDNS *const m);
3357*c65ebfc7SToomas Soome extern mDNSBool RecordReadyForSleep(AuthRecord *rr);
33585ffb0c9bSToomas Soome // For now this LocalSleepProxy stuff is specific to Mac OS X.
33595ffb0c9bSToomas Soome // In the future, if there's demand, we may see if we can abstract it out cleanly into the platform layer
3360*c65ebfc7SToomas Soome extern mStatus ActivateLocalProxy(NetworkInterfaceInfo *const intf, mDNSBool *keepaliveOnly);
3361*c65ebfc7SToomas Soome extern void mDNSPlatformUpdateDNSStatus(DNSQuestion *q);
3362*c65ebfc7SToomas Soome extern void mDNSPlatformTriggerDNSRetry(DNSQuestion *v4q, DNSQuestion *v6q);
33635ffb0c9bSToomas Soome extern void mDNSPlatformLogToFile(int log_level, const char *buffer);
33645ffb0c9bSToomas Soome extern mDNSBool SupportsInNICProxy(NetworkInterfaceInfo *const intf);
3365cda73f64SToomas Soome extern mStatus SymptomReporterDNSServerReachable(mDNS *const m, const mDNSAddr *addr);
3366cda73f64SToomas Soome extern mStatus SymptomReporterDNSServerUnreachable(DNSServer *s);
33675ffb0c9bSToomas Soome #endif
33685ffb0c9bSToomas Soome 
3369*c65ebfc7SToomas Soome typedef void ProxyCallback (void *socket, DNSMessage *const msg, const mDNSu8 *const end, const mDNSAddr *const srcaddr,
33705ffb0c9bSToomas Soome     const mDNSIPPort srcport, const mDNSAddr *dstaddr, const mDNSIPPort dstport, const mDNSInterfaceID InterfaceID, void *context);
3371*c65ebfc7SToomas Soome extern void mDNSPlatformInitDNSProxySkts(ProxyCallback *UDPCallback, ProxyCallback *TCPCallback);
33725ffb0c9bSToomas Soome extern void mDNSPlatformCloseDNSProxySkts(mDNS *const m);
33735ffb0c9bSToomas Soome extern void mDNSPlatformDisposeProxyContext(void *context);
33745ffb0c9bSToomas Soome extern mDNSu8 *DNSProxySetAttributes(DNSQuestion *q, DNSMessageHeader *h, DNSMessage *msg, mDNSu8 *start, mDNSu8 *limit);
33755ffb0c9bSToomas Soome 
33765ffb0c9bSToomas Soome #if APPLE_OSX_mDNSResponder
3377*c65ebfc7SToomas Soome extern void mDNSPlatformGetDNSRoutePolicy(DNSQuestion *q, mDNSBool *isBlocked);
33785ffb0c9bSToomas Soome #endif
3379*c65ebfc7SToomas Soome extern void mDNSPlatformSetSocktOpt(void *sock, mDNSTransport_Type transType, mDNSAddr_Type addrType, const DNSQuestion *q);
33805ffb0c9bSToomas Soome extern mDNSs32 mDNSPlatformGetPID(void);
3381cda73f64SToomas Soome extern mDNSBool mDNSValidKeepAliveRecord(AuthRecord *rr);
3382*c65ebfc7SToomas Soome extern mDNSBool CacheRecordRmvEventsForQuestion(mDNS *const m, DNSQuestion *q);
33835ffb0c9bSToomas Soome 
33845ffb0c9bSToomas Soome // ***************************************************************************
33855ffb0c9bSToomas Soome #if 0
33865ffb0c9bSToomas Soome #pragma mark -
33875ffb0c9bSToomas Soome #pragma mark - Sleep Proxy
33885ffb0c9bSToomas Soome #endif
33895ffb0c9bSToomas Soome 
33905ffb0c9bSToomas Soome // Sleep Proxy Server Property Encoding
33915ffb0c9bSToomas Soome //
33925ffb0c9bSToomas Soome // Sleep Proxy Servers are advertised using a structured service name, consisting of four
33935ffb0c9bSToomas Soome // metrics followed by a human-readable name. The metrics assist clients in deciding which
33945ffb0c9bSToomas Soome // Sleep Proxy Server(s) to use when multiple are available on the network. Each metric
33955ffb0c9bSToomas Soome // is a two-digit decimal number in the range 10-99. Lower metrics are generally better.
33965ffb0c9bSToomas Soome //
33975ffb0c9bSToomas Soome //   AA-BB-CC-DD.FF Name
33985ffb0c9bSToomas Soome //
33995ffb0c9bSToomas Soome // Metrics:
34005ffb0c9bSToomas Soome //
34015ffb0c9bSToomas Soome // AA = Intent
34025ffb0c9bSToomas Soome // BB = Portability
34035ffb0c9bSToomas Soome // CC = Marginal Power
34045ffb0c9bSToomas Soome // DD = Total Power
34055ffb0c9bSToomas Soome // FF = Features Supported (Currently TCP Keepalive only)
34065ffb0c9bSToomas Soome //
34075ffb0c9bSToomas Soome //
34085ffb0c9bSToomas Soome // ** Intent Metric **
34095ffb0c9bSToomas Soome //
34105ffb0c9bSToomas Soome // 20 = Dedicated Sleep Proxy Server -- a device, permanently powered on,
34115ffb0c9bSToomas Soome //      installed for the express purpose of providing Sleep Proxy Service.
34125ffb0c9bSToomas Soome //
34135ffb0c9bSToomas Soome // 30 = Primary Network Infrastructure Hardware -- a router, DHCP server, NAT gateway,
34145ffb0c9bSToomas Soome //      or similar permanently installed device which is permanently powered on.
34155ffb0c9bSToomas Soome //      This is hardware designed for the express purpose of being network
34165ffb0c9bSToomas Soome //      infrastructure, and for most home users is typically a single point
34175ffb0c9bSToomas Soome //      of failure for the local network -- e.g. most home users only have
34185ffb0c9bSToomas Soome //      a single NAT gateway / DHCP server. Even though in principle the
34195ffb0c9bSToomas Soome //      hardware might technically be capable of running different software,
34205ffb0c9bSToomas Soome //      a typical user is unlikely to do that. e.g. AirPort base station.
34215ffb0c9bSToomas Soome //
34225ffb0c9bSToomas Soome // 40 = Primary Network Infrastructure Software -- a general-purpose computer
34235ffb0c9bSToomas Soome //      (e.g. Mac, Windows, Linux, etc.) which is currently running DHCP server
34245ffb0c9bSToomas Soome //      or NAT gateway software, but the user could choose to turn that off
34255ffb0c9bSToomas Soome //      fairly easily. e.g. iMac running Internet Sharing
34265ffb0c9bSToomas Soome //
34275ffb0c9bSToomas Soome // 50 = Secondary Network Infrastructure Hardware -- like primary infrastructure
34285ffb0c9bSToomas Soome //      hardware, except not a single point of failure for the entire local network.
34295ffb0c9bSToomas Soome //      For example, an AirPort base station in bridge mode. This may have clients
34305ffb0c9bSToomas Soome //      associated with it, and if it goes away those clients will be inconvenienced,
34315ffb0c9bSToomas Soome //      but unlike the NAT gateway / DHCP server, the entire local network is not
34325ffb0c9bSToomas Soome //      dependent on it.
34335ffb0c9bSToomas Soome //
34345ffb0c9bSToomas Soome // 60 = Secondary Network Infrastructure Software -- like 50, but in a general-
34355ffb0c9bSToomas Soome //      purpose CPU.
34365ffb0c9bSToomas Soome //
34375ffb0c9bSToomas Soome // 70 = Incidentally Available Hardware -- a device which has no power switch
34385ffb0c9bSToomas Soome //      and is generally left powered on all the time. Even though it is not a
34395ffb0c9bSToomas Soome //      part of what we conventionally consider network infrastructure (router,
34405ffb0c9bSToomas Soome //      DHCP, NAT, DNS, etc.), and the rest of the network can operate fine
34415ffb0c9bSToomas Soome //      without it, since it's available and unlikely to be turned off, it is a
34425ffb0c9bSToomas Soome //      reasonable candidate for providing Sleep Proxy Service e.g. Apple TV,
34435ffb0c9bSToomas Soome //      or an AirPort base station in client mode, associated with an existing
34445ffb0c9bSToomas Soome //      wireless network (e.g. AirPort Express connected to a music system, or
34455ffb0c9bSToomas Soome //      being used to share a USB printer).
34465ffb0c9bSToomas Soome //
34475ffb0c9bSToomas Soome // 80 = Incidentally Available Software -- a general-purpose computer which
34485ffb0c9bSToomas Soome //      happens at this time to be set to "never sleep", and as such could be
34495ffb0c9bSToomas Soome //      useful as a Sleep Proxy Server, but has not been intentionally provided
34505ffb0c9bSToomas Soome //      for this purpose. Of all the Intent Metric categories this is the
34515ffb0c9bSToomas Soome //      one most likely to be shut down or put to sleep without warning.
34525ffb0c9bSToomas Soome //      However, if nothing else is availalable, it may be better than nothing.
34535ffb0c9bSToomas Soome //      e.g. Office computer in the workplace which has been set to "never sleep"
34545ffb0c9bSToomas Soome //
34555ffb0c9bSToomas Soome //
34565ffb0c9bSToomas Soome // ** Portability Metric **
34575ffb0c9bSToomas Soome //
34585ffb0c9bSToomas Soome // Inversely related to mass of device, on the basis that, all other things
34595ffb0c9bSToomas Soome // being equal, heavier devices are less likely to be moved than lighter devices.
34605ffb0c9bSToomas Soome // E.g. A MacBook running Internet Sharing is probably more likely to be
34615ffb0c9bSToomas Soome // put to sleep and taken away than a Mac Pro running Internet Sharing.
34625ffb0c9bSToomas Soome // The Portability Metric is a logarithmic decibel scale, computed by taking the
34635ffb0c9bSToomas Soome // (approximate) mass of the device in milligrammes, taking the base 10 logarithm
34645ffb0c9bSToomas Soome // of that, multiplying by 10, and subtracting the result from 100:
34655ffb0c9bSToomas Soome //
34665ffb0c9bSToomas Soome //   Portability Metric = 100 - (log10(mg) * 10)
34675ffb0c9bSToomas Soome //
34685ffb0c9bSToomas Soome // The Portability Metric is not necessarily computed literally from the actual
34695ffb0c9bSToomas Soome // mass of the device; the intent is just that lower numbers indicate more
34705ffb0c9bSToomas Soome // permanent devices, and higher numbers indicate devices more likely to be
34715ffb0c9bSToomas Soome // removed from the network, e.g., in order of increasing portability:
34725ffb0c9bSToomas Soome //
34735ffb0c9bSToomas Soome // Mac Pro < iMac < Laptop < iPhone
34745ffb0c9bSToomas Soome //
34755ffb0c9bSToomas Soome // Example values:
34765ffb0c9bSToomas Soome //
34775ffb0c9bSToomas Soome // 10 = 1 metric tonne
34785ffb0c9bSToomas Soome // 40 = 1kg
34795ffb0c9bSToomas Soome // 70 = 1g
34805ffb0c9bSToomas Soome // 90 = 10mg
34815ffb0c9bSToomas Soome //
34825ffb0c9bSToomas Soome //
34835ffb0c9bSToomas Soome // ** Marginal Power and Total Power Metrics **
34845ffb0c9bSToomas Soome //
34855ffb0c9bSToomas Soome // The Marginal Power Metric is the power difference between sleeping and staying awake
34865ffb0c9bSToomas Soome // to be a Sleep Proxy Server.
34875ffb0c9bSToomas Soome //
34885ffb0c9bSToomas Soome // The Total Power Metric is the total power consumption when being Sleep Proxy Server.
34895ffb0c9bSToomas Soome //
34905ffb0c9bSToomas Soome // The Power Metrics use a logarithmic decibel scale, computed as ten times the
34915ffb0c9bSToomas Soome // base 10 logarithm of the (approximate) power in microwatts:
34925ffb0c9bSToomas Soome //
34935ffb0c9bSToomas Soome //   Power Metric = log10(uW) * 10
34945ffb0c9bSToomas Soome //
34955ffb0c9bSToomas Soome // Higher values indicate higher power consumption. Example values:
34965ffb0c9bSToomas Soome //
34975ffb0c9bSToomas Soome // 10 =  10 uW
34985ffb0c9bSToomas Soome // 20 = 100 uW
34995ffb0c9bSToomas Soome // 30 =   1 mW
35005ffb0c9bSToomas Soome // 60 =   1 W
35015ffb0c9bSToomas Soome // 90 =   1 kW
35025ffb0c9bSToomas Soome 
35035ffb0c9bSToomas Soome typedef enum
35045ffb0c9bSToomas Soome {
35055ffb0c9bSToomas Soome     mDNSSleepProxyMetric_Dedicated          = 20,
35065ffb0c9bSToomas Soome     mDNSSleepProxyMetric_PrimaryHardware    = 30,
35075ffb0c9bSToomas Soome     mDNSSleepProxyMetric_PrimarySoftware    = 40,
35085ffb0c9bSToomas Soome     mDNSSleepProxyMetric_SecondaryHardware  = 50,
35095ffb0c9bSToomas Soome     mDNSSleepProxyMetric_SecondarySoftware  = 60,
35105ffb0c9bSToomas Soome     mDNSSleepProxyMetric_IncidentalHardware = 70,
35115ffb0c9bSToomas Soome     mDNSSleepProxyMetric_IncidentalSoftware = 80
35125ffb0c9bSToomas Soome } mDNSSleepProxyMetric;
35135ffb0c9bSToomas Soome 
35145ffb0c9bSToomas Soome typedef enum
35155ffb0c9bSToomas Soome {
35165ffb0c9bSToomas Soome     mDNS_NoWake        = 0, // System does not support Wake on LAN
35175ffb0c9bSToomas Soome     mDNS_WakeOnAC      = 1, // System supports Wake on LAN when connected to AC power only
35185ffb0c9bSToomas Soome     mDNS_WakeOnBattery = 2  // System supports Wake on LAN on battery
35195ffb0c9bSToomas Soome } mDNSWakeForNetworkAccess;
35205ffb0c9bSToomas Soome 
35215ffb0c9bSToomas Soome extern void mDNSCoreBeSleepProxyServer_internal(mDNS *const m, mDNSu8 sps, mDNSu8 port, mDNSu8 marginalpower, mDNSu8 totpower, mDNSu8 features);
35225ffb0c9bSToomas Soome #define mDNSCoreBeSleepProxyServer(M,S,P,MP,TP,F)                       \
35235ffb0c9bSToomas Soome     do { mDNS_Lock(m); mDNSCoreBeSleepProxyServer_internal((M),(S),(P),(MP),(TP),(F)); mDNS_Unlock(m); } while(0)
35245ffb0c9bSToomas Soome 
35255ffb0c9bSToomas Soome extern void FindSPSInCache(mDNS *const m, const DNSQuestion *const q, const CacheRecord *sps[3]);
35265ffb0c9bSToomas Soome #define PrototypeSPSName(X) ((X)[0] >= 11 && (X)[3] == '-' && (X)[ 4] == '9' && (X)[ 5] == '9' && \
35275ffb0c9bSToomas Soome                              (X)[6] == '-' && (X)[ 7] == '9' && (X)[ 8] == '9' && \
35285ffb0c9bSToomas Soome                              (X)[9] == '-' && (X)[10] == '9' && (X)[11] == '9'    )
35295ffb0c9bSToomas Soome #define ValidSPSName(X) ((X)[0] >= 5 && mDNSIsDigit((X)[1]) && mDNSIsDigit((X)[2]) && mDNSIsDigit((X)[4]) && mDNSIsDigit((X)[5]))
35305ffb0c9bSToomas Soome #define SPSMetric(X) (!ValidSPSName(X) || PrototypeSPSName(X) ? 1000000 : \
35315ffb0c9bSToomas Soome                       ((X)[1]-'0') * 100000 + ((X)[2]-'0') * 10000 + ((X)[4]-'0') * 1000 + ((X)[5]-'0') * 100 + ((X)[7]-'0') * 10 + ((X)[8]-'0'))
35325ffb0c9bSToomas Soome #define LocalSPSMetric(X) ( (X)->SPSType * 10000 + (X)->SPSPortability * 100 + (X)->SPSMarginalPower)
35335ffb0c9bSToomas Soome #define SPSFeatures(X) ((X)[0] >= 13 && (X)[12] =='.' ? ((X)[13]-'0') : 0 )
35345ffb0c9bSToomas Soome 
35355ffb0c9bSToomas Soome #define MD5_DIGEST_LENGTH   16          /* digest length in bytes */
35365ffb0c9bSToomas Soome #define MD5_BLOCK_BYTES     64          /* block size in bytes */
35375ffb0c9bSToomas Soome #define MD5_BLOCK_LONG       (MD5_BLOCK_BYTES / sizeof(mDNSu32))
35385ffb0c9bSToomas Soome 
35395ffb0c9bSToomas Soome typedef struct MD5state_st
35405ffb0c9bSToomas Soome {
35415ffb0c9bSToomas Soome     mDNSu32 A,B,C,D;
35425ffb0c9bSToomas Soome     mDNSu32 Nl,Nh;
35435ffb0c9bSToomas Soome     mDNSu32 data[MD5_BLOCK_LONG];
35445ffb0c9bSToomas Soome     int num;
35455ffb0c9bSToomas Soome } MD5_CTX;
35465ffb0c9bSToomas Soome 
35475ffb0c9bSToomas Soome extern int MD5_Init(MD5_CTX *c);
35485ffb0c9bSToomas Soome extern int MD5_Update(MD5_CTX *c, const void *data, unsigned long len);
35495ffb0c9bSToomas Soome extern int MD5_Final(unsigned char *md, MD5_CTX *c);
35505ffb0c9bSToomas Soome 
35514b22b933Srs // ***************************************************************************
35524b22b933Srs #if 0
35535ffb0c9bSToomas Soome #pragma mark -
35544b22b933Srs #pragma mark - Compile-Time assertion checks
35554b22b933Srs #endif
35564b22b933Srs 
35574b22b933Srs // Some C compiler cleverness. We can make the compiler check certain things for
35584b22b933Srs // us, and report compile-time errors if anything is wrong. The usual way to do
35594b22b933Srs // this would be to use a run-time "if" statement, but then you don't find out
35604b22b933Srs // what's wrong until you run the software. This way, if the assertion condition
35614b22b933Srs // is false, the array size is negative, and the complier complains immediately.
35624b22b933Srs 
35635ffb0c9bSToomas Soome struct CompileTimeAssertionChecks_mDNS
35645ffb0c9bSToomas Soome {
35655ffb0c9bSToomas Soome     // Check that the compiler generated our on-the-wire packet format structure definitions
35665ffb0c9bSToomas Soome     // properly packed, without adding padding bytes to align fields on 32-bit or 64-bit boundaries.
35675ffb0c9bSToomas Soome     char assert0[(sizeof(rdataSRV)         == 262                          ) ? 1 : -1];
35685ffb0c9bSToomas Soome     char assert1[(sizeof(DNSMessageHeader) ==  12                          ) ? 1 : -1];
35695ffb0c9bSToomas Soome     char assert2[(sizeof(DNSMessage)       ==  12+AbsoluteMaxDNSMessageData) ? 1 : -1];
35705ffb0c9bSToomas Soome     char assert3[(sizeof(mDNSs8)           ==   1                          ) ? 1 : -1];
35715ffb0c9bSToomas Soome     char assert4[(sizeof(mDNSu8)           ==   1                          ) ? 1 : -1];
35725ffb0c9bSToomas Soome     char assert5[(sizeof(mDNSs16)          ==   2                          ) ? 1 : -1];
35735ffb0c9bSToomas Soome     char assert6[(sizeof(mDNSu16)          ==   2                          ) ? 1 : -1];
35745ffb0c9bSToomas Soome     char assert7[(sizeof(mDNSs32)          ==   4                          ) ? 1 : -1];
35755ffb0c9bSToomas Soome     char assert8[(sizeof(mDNSu32)          ==   4                          ) ? 1 : -1];
35765ffb0c9bSToomas Soome     char assert9[(sizeof(mDNSOpaque16)     ==   2                          ) ? 1 : -1];
35775ffb0c9bSToomas Soome     char assertA[(sizeof(mDNSOpaque32)     ==   4                          ) ? 1 : -1];
35785ffb0c9bSToomas Soome     char assertB[(sizeof(mDNSOpaque128)    ==  16                          ) ? 1 : -1];
35795ffb0c9bSToomas Soome     char assertC[(sizeof(CacheRecord  )    ==  sizeof(CacheGroup)          ) ? 1 : -1];
35805ffb0c9bSToomas Soome     char assertD[(sizeof(int)              >=  4                           ) ? 1 : -1];
35815ffb0c9bSToomas Soome     char assertE[(StandardAuthRDSize       >=  256                         ) ? 1 : -1];
35825ffb0c9bSToomas Soome     char assertF[(sizeof(EthernetHeader)   ==   14                         ) ? 1 : -1];
35835ffb0c9bSToomas Soome     char assertG[(sizeof(ARP_EthIP     )   ==   28                         ) ? 1 : -1];
35845ffb0c9bSToomas Soome     char assertH[(sizeof(IPv4Header    )   ==   20                         ) ? 1 : -1];
35855ffb0c9bSToomas Soome     char assertI[(sizeof(IPv6Header    )   ==   40                         ) ? 1 : -1];
35865ffb0c9bSToomas Soome     char assertJ[(sizeof(IPv6NDP       )   ==   24                         ) ? 1 : -1];
35875ffb0c9bSToomas Soome     char assertK[(sizeof(UDPHeader     )   ==    8                         ) ? 1 : -1];
35885ffb0c9bSToomas Soome     char assertL[(sizeof(IKEHeader     )   ==   28                         ) ? 1 : -1];
35895ffb0c9bSToomas Soome     char assertM[(sizeof(TCPHeader     )   ==   20                         ) ? 1 : -1];
3590*c65ebfc7SToomas Soome 	char assertN[(sizeof(rdataOPT)		   ==   24                         ) ? 1 : -1];
3591*c65ebfc7SToomas Soome 	char assertO[(sizeof(rdataRRSig)	   ==   20                         ) ? 1 : -1];
3592*c65ebfc7SToomas Soome 	char assertP[(sizeof(PCPMapRequest)    ==   60                         ) ? 1 : -1];
3593*c65ebfc7SToomas Soome 	char assertQ[(sizeof(PCPMapReply)      ==   60                         ) ? 1 : -1];
3594*c65ebfc7SToomas Soome 
35955ffb0c9bSToomas Soome 
35965ffb0c9bSToomas Soome     // Check our structures are reasonable sizes. Including overly-large buffers, or embedding
35975ffb0c9bSToomas Soome     // other overly-large structures instead of having a pointer to them, can inadvertently
35985ffb0c9bSToomas Soome     // cause structure sizes (and therefore memory usage) to balloon unreasonably.
35995ffb0c9bSToomas Soome     char sizecheck_RDataBody           [(sizeof(RDataBody)            ==   264) ? 1 : -1];
36005ffb0c9bSToomas Soome     char sizecheck_ResourceRecord      [(sizeof(ResourceRecord)       <=    72) ? 1 : -1];
36015ffb0c9bSToomas Soome     char sizecheck_AuthRecord          [(sizeof(AuthRecord)           <=  1208) ? 1 : -1];
36025ffb0c9bSToomas Soome     char sizecheck_CacheRecord         [(sizeof(CacheRecord)          <=   232) ? 1 : -1];
36035ffb0c9bSToomas Soome     char sizecheck_CacheGroup          [(sizeof(CacheGroup)           <=   232) ? 1 : -1];
3604*c65ebfc7SToomas Soome     char sizecheck_DNSQuestion         [(sizeof(DNSQuestion)          <=   912) ? 1 : -1];
36055ffb0c9bSToomas Soome 
3606*c65ebfc7SToomas Soome     char sizecheck_ZoneData            [(sizeof(ZoneData)             <=  1744) ? 1 : -1];
36075ffb0c9bSToomas Soome     char sizecheck_NATTraversalInfo    [(sizeof(NATTraversalInfo)     <=   200) ? 1 : -1];
36085ffb0c9bSToomas Soome     char sizecheck_HostnameInfo        [(sizeof(HostnameInfo)         <=  3050) ? 1 : -1];
3609*c65ebfc7SToomas Soome     char sizecheck_DNSServer           [(sizeof(DNSServer)            <=   330) ? 1 : -1];
3610*c65ebfc7SToomas Soome     char sizecheck_NetworkInterfaceInfo[(sizeof(NetworkInterfaceInfo) <=  7376) ? 1 : -1];
36115ffb0c9bSToomas Soome     char sizecheck_ServiceRecordSet    [(sizeof(ServiceRecordSet)     <=  5540) ? 1 : -1];
36125ffb0c9bSToomas Soome     char sizecheck_DomainAuthInfo      [(sizeof(DomainAuthInfo)       <=  7888) ? 1 : -1];
36135ffb0c9bSToomas Soome #if APPLE_OSX_mDNSResponder
3614*c65ebfc7SToomas Soome     char sizecheck_ClientTunnel        [(sizeof(ClientTunnel)         <=  1256) ? 1 : -1];
36155ffb0c9bSToomas Soome #endif
36165ffb0c9bSToomas Soome };
36175ffb0c9bSToomas Soome 
36185ffb0c9bSToomas Soome // Routine to initialize device-info TXT record contents
36195ffb0c9bSToomas Soome mDNSu32 initializeDeviceInfoTXT(mDNS *m, mDNSu8 *ptr);
36205ffb0c9bSToomas Soome 
36215ffb0c9bSToomas Soome #if APPLE_OSX_mDNSResponder
36225ffb0c9bSToomas Soome extern void D2D_start_advertising_interface(NetworkInterfaceInfo *interface);
36235ffb0c9bSToomas Soome extern void D2D_stop_advertising_interface(NetworkInterfaceInfo *interface);
3624*c65ebfc7SToomas Soome extern void D2D_start_advertising_record(AuthRecord *ar);
3625*c65ebfc7SToomas Soome extern void D2D_stop_advertising_record(AuthRecord *ar);
3626*c65ebfc7SToomas Soome #else
3627*c65ebfc7SToomas Soome #define D2D_start_advertising_interface(X)
3628*c65ebfc7SToomas Soome #define D2D_stop_advertising_interface(X)
3629*c65ebfc7SToomas Soome #define D2D_start_advertising_record(X)
3630*c65ebfc7SToomas Soome #define D2D_stop_advertising_record(X)
36315ffb0c9bSToomas Soome #endif
36324b22b933Srs 
36334b22b933Srs // ***************************************************************************
36344b22b933Srs 
36354b22b933Srs #ifdef __cplusplus
36365ffb0c9bSToomas Soome }
36374b22b933Srs #endif
36384b22b933Srs 
36394b22b933Srs #endif
3640