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