1 /* -*- Mode: C; tab-width: 4 -*-
3 * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 Change History (most recent first):
20 Revision 1.92 2008/06/19 23:42:03 mcguire
21 <rdar://problem/4206534> Use all configured DNS servers
23 Revision 1.91 2008/06/19 01:20:50 mcguire
24 <rdar://problem/4206534> Use all configured DNS servers
26 Revision 1.90 2007/12/22 02:25:30 cheshire
27 <rdar://problem/5661128> Records and Services sometimes not re-registering on wake from sleep
29 Revision 1.89 2007/12/15 01:12:27 cheshire
30 <rdar://problem/5526796> Need to remove active LLQs from server upon question cancellation, on sleep, and on shutdown
32 Revision 1.88 2007/10/25 20:06:13 cheshire
33 Don't try to do SOA queries using private DNS (TLS over TCP) queries
35 Revision 1.87 2007/10/24 22:40:06 cheshire
36 Renamed: RecordRegistrationCallback -> RecordRegistrationGotZoneData
37 Renamed: ServiceRegistrationZoneDataComplete -> ServiceRegistrationGotZoneData
39 Revision 1.86 2007/10/18 23:06:42 cheshire
40 <rdar://problem/5519458> BTMM: Machines don't appear in the sidebar on wake from sleep
41 Additional fixes and refinements
43 Revision 1.85 2007/10/18 20:23:17 cheshire
44 Moved SuspendLLQs into mDNS.c, since it's only called from one place
46 Revision 1.84 2007/10/17 22:49:54 cheshire
47 <rdar://problem/5519458> BTMM: Machines don't appear in the sidebar on wake from sleep
49 Revision 1.83 2007/10/17 22:37:23 cheshire
50 <rdar://problem/5536979> BTMM: Need to create NAT port mapping for receiving LLQ events
52 Revision 1.82 2007/10/17 21:53:51 cheshire
53 Improved debugging messages; renamed startLLQHandshakeCallback to LLQGotZoneData
55 Revision 1.81 2007/10/16 21:16:50 cheshire
56 Get rid of unused uDNS_Sleep() routine
58 Revision 1.80 2007/10/16 20:59:41 cheshire
59 Export SuspendLLQs/SleepServiceRegistrations/SleepRecordRegistrations so they're callable from other files
61 Revision 1.79 2007/09/20 01:13:19 cheshire
62 Export CacheGroupForName so it's callable from other files
64 Revision 1.78 2007/09/14 21:26:09 cheshire
65 <rdar://problem/5482627> BTMM: Need to manually avoid port conflicts when using UPnP gateways
67 Revision 1.77 2007/09/12 23:03:08 cheshire
68 <rdar://problem/5476978> DNSServiceNATPortMappingCreate callback not giving correct interface index
70 Revision 1.76 2007/09/12 19:22:19 cheshire
71 Variable renaming in preparation for upcoming fixes e.g. priv/pub renamed to intport/extport
72 Made NAT Traversal packet handlers take typed data instead of anonymous "mDNSu8 *" byte pointers
74 Revision 1.75 2007/08/28 23:53:21 cheshire
75 Rename serviceRegistrationCallback -> ServiceRegistrationZoneDataComplete
77 Revision 1.74 2007/08/24 00:15:20 cheshire
78 Renamed GetAuthInfoForName() to GetAuthInfoForName_internal() to make it clear that it may only be called with the lock held
80 Revision 1.73 2007/08/01 03:09:22 cheshire
81 <rdar://problem/5344587> BTMM: Create NAT port mapping for autotunnel port
83 Revision 1.72 2007/08/01 00:04:13 cheshire
84 <rdar://problem/5261696> Crash in tcpKQSocketCallback
85 Half-open TCP connections were not being cancelled properly
87 Revision 1.71 2007/07/30 23:31:26 cheshire
88 Code for respecting TTL received in uDNS responses should exclude LLQ-type responses
90 Revision 1.70 2007/07/27 20:52:29 cheshire
91 Made uDNS_recvLLQResponse() return tri-state result: LLQ_Not, LLQ_First, or LLQ_Events
93 Revision 1.69 2007/07/27 19:30:40 cheshire
94 Changed mDNSQuestionCallback parameter from mDNSBool to QC_result,
95 to properly reflect tri-state nature of the possible responses
97 Revision 1.68 2007/07/27 18:38:56 cheshire
98 Rename "uDNS_CheckQuery" to more informative "uDNS_CheckCurrentQuestion"
100 Revision 1.67 2007/07/20 23:11:12 cheshire
103 Revision 1.66 2007/07/16 23:54:48 cheshire
104 <rdar://problem/5338850> Crash when removing or changing DNS keys
106 Revision 1.65 2007/07/16 20:14:22 vazquez
107 <rdar://problem/3867231> LegacyNATTraversal: Need complete rewrite
109 Revision 1.64 2007/07/11 02:53:36 cheshire
110 <rdar://problem/5303807> Register IPv6-only hostname and don't create port mappings for AutoTunnel services
111 Add ServiceRecordSet parameter in GetServiceTarget
113 Revision 1.63 2007/06/29 00:09:24 vazquez
114 <rdar://problem/5301908> Clean up NAT state machine (necessary for 6 other fixes)
116 Revision 1.62 2007/05/14 23:53:00 cheshire
117 Export mDNS_StartQuery_internal and mDNS_StopQuery_internal so they can be called from uDNS.c
119 Revision 1.61 2007/05/07 20:43:45 cheshire
120 <rdar://problem/4241419> Reduce the number of queries and announcements
122 Revision 1.60 2007/05/04 21:46:10 cheshire
123 Get rid of uDNS_Close (synonym for uDNS_Sleep)
125 Revision 1.59 2007/05/03 22:40:38 cheshire
126 <rdar://problem/4669229> mDNSResponder ignores bogus null target in SRV record
128 Revision 1.58 2007/05/02 22:21:33 cheshire
129 <rdar://problem/5167331> RegisterRecord and RegisterService need to cancel StartGetZoneData
131 Revision 1.57 2007/04/27 19:28:02 cheshire
132 Any code that calls StartGetZoneData needs to keep a handle to the structure, so
133 it can cancel it if necessary. (First noticed as a crash in Apple Remote Desktop
134 -- it would start a query and then quickly cancel it, and then when
135 StartGetZoneData completed, it had a dangling pointer and crashed.)
137 Revision 1.56 2007/04/25 02:14:38 cheshire
138 <rdar://problem/4246187> uDNS: Identical client queries should reference a single shared core query
139 Additional fixes to make LLQs work properly
141 Revision 1.55 2007/04/22 06:02:03 cheshire
142 <rdar://problem/4615977> Query should immediately return failure when no server
144 Revision 1.54 2007/04/04 21:48:53 cheshire
145 <rdar://problem/4720694> Combine unicast authoritative answer list with multicast list
147 Revision 1.53 2007/03/28 15:56:37 cheshire
148 <rdar://problem/5085774> Add listing of NAT port mapping and GetAddrInfo requests in SIGINFO output
150 Revision 1.52 2007/02/28 01:44:26 cheshire
151 <rdar://problem/5027863> Byte order bugs in uDNS.c, uds_daemon.c, dnssd_clientstub.c
153 Revision 1.51 2007/01/27 03:34:27 cheshire
154 Made GetZoneData use standard queries (and cached results);
155 eliminated GetZoneData_Callback() packet response handler
157 Revision 1.50 2007/01/19 21:17:32 cheshire
158 StartLLQPolling needs to call SetNextQueryTime() to cause query to be done in a timely fashion
160 Revision 1.49 2007/01/17 21:35:31 cheshire
161 For clarity, rename zoneData_t field "isPrivate" to "zonePrivate"
163 Revision 1.48 2007/01/10 22:51:57 cheshire
164 <rdar://problem/4917539> Add support for one-shot private queries as well as long-lived private queries
166 Revision 1.47 2007/01/05 08:30:43 cheshire
167 Trim excessive "$Log" checkin history from before 2006
168 (checkin history still available via "cvs log ..." of course)
170 Revision 1.46 2007/01/04 01:41:47 cheshire
171 Use _dns-update-tls/_dns-query-tls/_dns-llq-tls instead of creating a new "_tls" subdomain
173 Revision 1.45 2006/12/22 20:59:49 cheshire
174 <rdar://problem/4742742> Read *all* DNS keys from keychain,
175 not just key for the system-wide default registration domain
177 Revision 1.44 2006/12/20 04:07:35 cheshire
178 Remove uDNS_info substructure from AuthRecord_struct
180 Revision 1.43 2006/12/16 01:58:32 cheshire
181 <rdar://problem/4720673> uDNS: Need to start caching unicast records
183 Revision 1.42 2006/11/30 23:07:56 herscher
184 <rdar://problem/4765644> uDNS: Sync up with Lighthouse changes for Private DNS
186 Revision 1.41 2006/11/18 05:01:30 cheshire
187 Preliminary support for unifying the uDNS and mDNS code,
188 including caching of uDNS answers
190 Revision 1.40 2006/11/10 07:44:04 herscher
191 <rdar://problem/4825493> Fix Daemon locking failures while toggling BTMM
193 Revision 1.39 2006/10/20 05:35:05 herscher
194 <rdar://problem/4720713> uDNS: Merge unicast active question list with multicast list.
196 Revision 1.38 2006/09/26 01:54:02 herscher
197 <rdar://problem/4245016> NAT Port Mapping API (for both NAT-PMP and UPnP Gateway Protocol)
199 Revision 1.37 2006/09/15 21:20:15 cheshire
200 Remove uDNS_info substructure from mDNS_struct
202 Revision 1.36 2006/08/14 23:24:23 cheshire
203 Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
205 Revision 1.35 2006/07/30 05:45:36 cheshire
206 <rdar://problem/4304215> Eliminate MIN_UCAST_PERIODIC_EXEC
208 Revision 1.34 2006/07/15 02:01:29 cheshire
209 <rdar://problem/4472014> Add Private DNS client functionality to mDNSResponder
210 Fix broken "empty string" browsing
212 Revision 1.33 2006/07/05 22:53:28 cheshire
213 <rdar://problem/4472014> Add Private DNS client functionality to mDNSResponder
220 #include "mDNSEmbeddedAPI.h"
221 #include "DNSCommon.h"
227 #define RESTART_GOODBYE_DELAY (6 * mDNSPlatformOneSecond) // delay after restarting LLQ before nuking previous known answers (avoids flutter if we restart before we have networking up)
228 #define INIT_UCAST_POLL_INTERVAL (3 * mDNSPlatformOneSecond) // this interval is used after send failures on network transitions
229 // which typically heal quickly, so we start agressively and exponentially back off
230 #define MAX_UCAST_POLL_INTERVAL (60 * 60 * mDNSPlatformOneSecond)
231 //#define MAX_UCAST_POLL_INTERVAL (1 * 60 * mDNSPlatformOneSecond)
232 #define LLQ_POLL_INTERVAL (15 * 60 * mDNSPlatformOneSecond) // Polling interval for zones w/ an advertised LLQ port (ie not static zones) if LLQ fails due to NAT, etc.
233 #define RESPONSE_WINDOW (60 * mDNSPlatformOneSecond) // require server responses within one minute of request
234 #define MAX_UCAST_UNANSWERED_QUERIES 2 // the number of unanswered queries from any one uDNS server before trying another server
236 #define DEFAULT_UPDATE_LEASE 7200
238 #define QuestionIntervalStep 3
239 #define QuestionIntervalStep2 (QuestionIntervalStep*QuestionIntervalStep)
240 #define QuestionIntervalStep3 (QuestionIntervalStep*QuestionIntervalStep*QuestionIntervalStep)
241 #define InitialQuestionInterval ((mDNSPlatformOneSecond + QuestionIntervalStep-1) / QuestionIntervalStep)
243 // Entry points into unicast-specific routines
245 extern void LLQGotZoneData(mDNS
*const m
, mStatus err
, const ZoneData
*zoneInfo
);
246 extern void startLLQHandshake(mDNS
*m
, DNSQuestion
*q
);
247 extern void sendLLQRefresh(mDNS
*m
, DNSQuestion
*q
);
249 extern void SleepServiceRegistrations(mDNS
*m
);
250 extern void SleepRecordRegistrations(mDNS
*m
);
253 // following fields must be set, and the update validated, upon entry.
256 // rr->UpdateCallback
258 extern mStatus
uDNS_AddRecordToService(mDNS
*const m
, ServiceRecordSet
*sr
, ExtraResourceRecord
*extra
);
259 extern mStatus
uDNS_UpdateRecord(mDNS
*m
, AuthRecord
*rr
);
261 extern void SetNextQueryTime(mDNS
*const m
, const DNSQuestion
*const q
);
262 extern CacheGroup
*CacheGroupForName(const mDNS
*const m
, const mDNSu32 slot
, const mDNSu32 namehash
, const domainname
*const name
);
263 extern mStatus
mDNS_Register_internal(mDNS
*const m
, AuthRecord
*const rr
);
264 // mDNS_Dereg_normal is used for most calls to mDNS_Deregister_internal
265 // mDNS_Dereg_conflict is used to indicate that this record is being forcibly deregistered because of a conflict
266 // mDNS_Dereg_repeat is used when cleaning up, for records that may have already been forcibly deregistered
267 typedef enum { mDNS_Dereg_normal
, mDNS_Dereg_conflict
, mDNS_Dereg_repeat
} mDNS_Dereg_type
;
268 extern mStatus
mDNS_Deregister_internal(mDNS
*const m
, AuthRecord
*const rr
, mDNS_Dereg_type drt
);
269 extern mStatus
mDNS_StartQuery_internal(mDNS
*const m
, DNSQuestion
*const question
);
270 extern mStatus
mDNS_StopQuery_internal(mDNS
*const m
, DNSQuestion
*const question
);
271 extern mStatus
mDNS_StartNATOperation_internal(mDNS
*const m
, NATTraversalInfo
*traversal
);
273 extern void RecordRegistrationGotZoneData(mDNS
*const m
, mStatus err
, const ZoneData
*zoneData
);
274 extern mStatus
uDNS_DeregisterRecord(mDNS
*const m
, AuthRecord
*const rr
);
276 extern void ServiceRegistrationGotZoneData(mDNS
*const m
, mStatus err
, const ZoneData
*result
);
277 extern const domainname
*GetServiceTarget(mDNS
*m
, ServiceRecordSet
*srs
);
278 extern mStatus
uDNS_DeregisterService(mDNS
*const m
, ServiceRecordSet
*srs
);
280 extern void uDNS_CheckCurrentQuestion(mDNS
*const m
);
282 // integer fields of msg header must be in HOST byte order before calling this routine
283 extern void uDNS_ReceiveMsg(mDNS
*const m
, DNSMessage
*const msg
, const mDNSu8
*const end
,
284 const mDNSAddr
*const srcaddr
, const mDNSIPPort srcport
);
286 // returns time of next scheduled event
287 extern void uDNS_Execute(mDNS
*const m
);
289 extern mStatus
uDNS_SetupDNSConfig(mDNS
*const m
);
290 extern mStatus
uDNS_RegisterSearchDomains(mDNS
*const m
);
294 uDNS_LLQ_Not
= 0, // Normal uDNS answer: Flush any stale records from cache, and respect record TTL
295 uDNS_LLQ_Ignore
, // LLQ initial challenge packet: ignore -- has no useful records for us
296 uDNS_LLQ_Entire
, // LLQ initial set of answers: Flush any stale records from cache, but assume TTL is 2 x LLQ refresh interval
297 uDNS_LLQ_Events
// LLQ event packet: don't flush cache; assume TTL is 2 x LLQ refresh interval
300 extern uDNS_LLQType
uDNS_recvLLQResponse(mDNS
*const m
, const DNSMessage
*const msg
, const mDNSu8
*const end
, const mDNSAddr
*const srcaddr
, const mDNSIPPort srcport
);
301 extern DomainAuthInfo
*GetAuthInfoForName_internal(mDNS
*m
, const domainname
*const name
);
302 extern DomainAuthInfo
*GetAuthInfoForQuestion(mDNS
*m
, const DNSQuestion
*const q
);
303 extern void DisposeTCPConn(struct tcpInfo_t
*tcp
);
306 extern void uDNS_ReceiveNATPMPPacket(mDNS
*m
, const mDNSInterfaceID InterfaceID
, mDNSu8
*pkt
, mDNSu16 len
); // Called for each received NAT-PMP packet
307 extern void natTraversalHandleAddressReply(mDNS
*const m
, mDNSu16 err
, mDNSv4Addr ExtAddr
);
308 extern void natTraversalHandlePortMapReply(mDNS
*const m
, NATTraversalInfo
*n
, const mDNSInterfaceID InterfaceID
, mDNSu16 err
, mDNSIPPort extport
, mDNSu32 lease
);