]> git.saurik.com Git - apple/mdnsresponder.git/blob - mDNSWindows/dDNS.c
mDNSResponder-107.6.tar.gz
[apple/mdnsresponder.git] / mDNSWindows / dDNS.c
1 /* -*- Mode: C; tab-width: 4 -*-
2 *
3 * Copyright (c) 2002-2004 Apple Computer, 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 Change History (most recent first):
18
19 $Log: dDNS.c,v $
20 Revision 1.8.2.1 2006/08/29 06:24:39 cheshire
21 Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
22
23 Revision 1.8 2005/09/12 07:13:33 herscher
24 <rdar://problem/4248878> Workaround for router crash. Lazily call RegisterSearchDomains rather than call it always at startup.
25
26 Revision 1.7 2005/08/10 01:43:23 herscher
27 Pass NULL in for the IPv6 paramter to mDNS_SetPrimaryInterfaceInfo to get this code to compile on Windows.
28
29 Revision 1.6 2005/03/23 05:54:48 cheshire
30 <rdar://problem/4021486> Fix build warnings
31 Fix %s where it should be %##s in debugf & LogMsg calls
32
33 */
34
35 #include "dDNS.h"
36 #include "DNSCommon.h"
37 #include "uds_daemon.h"
38 #include <winsock2.h>
39 #include <iphlpapi.h>
40 #include <ws2tcpip.h>
41
42 typedef struct SearchListElem
43 {
44 struct SearchListElem *next;
45 domainname domain;
46 int flag;
47 DNSQuestion BrowseQ;
48 DNSQuestion DefBrowseQ;
49 DNSQuestion LegacyBrowseQ;
50 DNSQuestion RegisterQ;
51 DNSQuestion DefRegisterQ;
52 ARListElem *AuthRecs;
53 } SearchListElem;
54 // for domain enumeration and default browsing/registration
55 static SearchListElem *SearchList = mDNSNULL; // where we search for _browse domains
56 static DNSQuestion LegacyBrowseDomainQ; // our local enumeration query for _legacy._browse domains
57 static DNameListElem *DefBrowseList = mDNSNULL; // cache of answers to above query (where we search for empty string browses)
58 static DNameListElem *DefRegList = mDNSNULL; // manually generated list of domains where we register for empty string registrations
59 static ARListElem *SCPrefBrowseDomains = mDNSNULL; // manually generated local-only PTR records for browse domains we get from SCPreferences
60
61 static domainname dDNSRegDomain; // Default wide-area zone for service registration
62 static DNameListElem * dDNSBrowseDomains; // Default wide-area zone for legacy ("empty string") browses
63 static domainname dDNSHostname;
64 static mDNSBool dDNSRegisterSearchDomains = mDNSfalse;
65
66 mDNSlocal mStatus RegisterNameServers( mDNS *const m );
67 mDNSlocal mStatus RegisterSearchDomains( mDNS *const m );
68
69
70 mStatus dDNS_SetupAddr(mDNSAddr *ip, const struct sockaddr *const sa)
71 {
72 if (!sa) { LogMsg("SetupAddr ERROR: NULL sockaddr"); return(mStatus_Invalid); }
73
74 if (sa->sa_family == AF_INET)
75 {
76 struct sockaddr_in *ifa_addr = (struct sockaddr_in *)sa;
77 ip->type = mDNSAddrType_IPv4;
78 ip->ip.v4.NotAnInteger = ifa_addr->sin_addr.s_addr;
79 return(mStatus_NoError);
80 }
81
82 if (sa->sa_family == AF_INET6)
83 {
84 struct sockaddr_in6 *ifa_addr = (struct sockaddr_in6 *)sa;
85 ip->type = mDNSAddrType_IPv6;
86 #if !defined(_WIN32)
87 if (IN6_IS_ADDR_LINKLOCAL(&ifa_addr->sin6_addr)) ifa_addr->sin6_addr.__u6_addr.__u6_addr16[1] = 0;
88 #else
89 if (IN6_IS_ADDR_LINKLOCAL(&ifa_addr->sin6_addr)) ifa_addr->sin6_addr.u.Word[1] = 0;
90 #endif
91 ip->ip.v6 = *(mDNSv6Addr*)&ifa_addr->sin6_addr;
92 return(mStatus_NoError);
93 }
94
95 LogMsg("SetupAddr invalid sa_family %d", sa->sa_family);
96 return(mStatus_Invalid);
97 }
98
99
100 mStatus dDNS_RegisterSearchDomains( mDNS * const m )
101 {
102 mStatus err = mStatus_NoError;
103
104 dDNSRegisterSearchDomains = mDNStrue;
105 RegisterSearchDomains( m );
106
107 return err;
108 }
109
110
111 mDNSlocal void MarkSearchListElem(domainname *domain)
112 {
113 SearchListElem *new, *ptr;
114
115 // if domain is in list, mark as pre-existent (0)
116 for (ptr = SearchList; ptr; ptr = ptr->next)
117 if (SameDomainName(&ptr->domain, domain))
118 {
119 if (ptr->flag != 1) ptr->flag = 0; // gracefully handle duplicates - if it is already marked as add, don't bump down to preexistent
120 break;
121 }
122
123 // if domain not in list, add to list, mark as add (1)
124 if (!ptr)
125 {
126 new = mallocL("MarkSearchListElem - SearchListElem", sizeof(SearchListElem));
127 if (!new) { LogMsg("ERROR: MarkSearchListElem - malloc"); return; }
128 bzero(new, sizeof(SearchListElem));
129 AssignDomainName(&new->domain, domain);
130 new->flag = 1; // add
131 new->next = SearchList;
132 SearchList = new;
133 }
134 }
135
136 //!!!KRS here is where we will give success/failure notification to the UI
137 mDNSlocal void SCPrefsdDNSCallback(mDNS *const m, AuthRecord *const rr, mStatus result)
138 {
139 (void)m; // unused
140 debugf("SCPrefsdDNSCallback: result %d for registration of name %##s", result, rr->resrec.name->c);
141 dDNSPlatformSetNameStatus(rr->resrec.name, result);
142 }
143
144 mDNSlocal void FreeARElemCallback(mDNS *const m, AuthRecord *const rr, mStatus result)
145 {
146 ARListElem *elem = rr->RecordContext;
147
148 (void)m; // unused
149
150 if (result == mStatus_MemFree) freeL("FreeARElemCallback", elem);
151 }
152
153 mDNSlocal void FoundDomain(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, mDNSBool AddRecord)
154 {
155 SearchListElem *slElem = question->QuestionContext;
156 ARListElem *arElem, *ptr, *prev;
157 AuthRecord *dereg;
158 const char *name;
159 mStatus err;
160
161 if (AddRecord)
162 {
163 arElem = mallocL("FoundDomain - arElem", sizeof(ARListElem));
164 if (!arElem) { LogMsg("ERROR: malloc"); return; }
165 mDNS_SetupResourceRecord(&arElem->ar, mDNSNULL, mDNSInterface_LocalOnly, kDNSType_PTR, 7200, kDNSRecordTypeShared, FreeARElemCallback, arElem);
166 if (question == &slElem->BrowseQ) name = mDNS_DomainTypeNames[mDNS_DomainTypeBrowse];
167 else if (question == &slElem->DefBrowseQ) name = mDNS_DomainTypeNames[mDNS_DomainTypeBrowseDefault];
168 else if (question == &slElem->LegacyBrowseQ) name = mDNS_DomainTypeNames[mDNS_DomainTypeBrowseLegacy];
169 else if (question == &slElem->RegisterQ) name = mDNS_DomainTypeNames[mDNS_DomainTypeRegistration];
170 else if (question == &slElem->DefRegisterQ) name = mDNS_DomainTypeNames[mDNS_DomainTypeRegistrationDefault];
171 else { LogMsg("FoundDomain - unknown question"); return; }
172
173 MakeDomainNameFromDNSNameString(arElem->ar.resrec.name, name);
174 AppendDNSNameString (arElem->ar.resrec.name, "local");
175 AssignDomainName(&arElem->ar.resrec.rdata->u.name, &answer->rdata->u.name);
176 err = mDNS_Register(m, &arElem->ar);
177 if (err)
178 {
179 LogMsg("ERROR: FoundDomain - mDNS_Register returned %d", err);
180 freeL("FoundDomain - arElem", arElem);
181 return;
182 }
183 arElem->next = slElem->AuthRecs;
184 slElem->AuthRecs = arElem;
185 }
186 else
187 {
188 ptr = slElem->AuthRecs;
189 prev = NULL;
190 while (ptr)
191 {
192 if (SameDomainName(&ptr->ar.resrec.rdata->u.name, &answer->rdata->u.name))
193 {
194 debugf("Deregistering PTR %##s -> %##s", ptr->ar.resrec.name->c, ptr->ar.resrec.rdata->u.name.c);
195 dereg = &ptr->ar;
196 if (prev) prev->next = ptr->next;
197 else slElem->AuthRecs = ptr->next;
198 ptr = ptr->next;
199 err = mDNS_Deregister(m, dereg);
200 if (err) LogMsg("ERROR: FoundDomain - mDNS_Deregister returned %d", err);
201 }
202 else
203 {
204 prev = ptr;
205 ptr = ptr->next;
206 }
207 }
208 }
209 }
210
211 mDNSexport DNameListElem *mDNSPlatformGetSearchDomainList(void)
212 {
213 return mDNS_CopyDNameList(DefBrowseList);
214 }
215
216 mDNSexport DNameListElem *mDNSPlatformGetRegDomainList(void)
217 {
218 return mDNS_CopyDNameList(DefRegList);
219 }
220
221 mDNSlocal void AddDefRegDomain(domainname *d)
222 {
223 DNameListElem *newelem = NULL, *ptr;
224
225 // make sure name not already in list
226 for (ptr = DefRegList; ptr; ptr = ptr->next)
227 {
228 if (SameDomainName(&ptr->name, d))
229 { debugf("duplicate addition of default reg domain %##s", d->c); return; }
230 }
231
232 newelem = mallocL("DNameListElem", sizeof(*newelem));
233 if (!newelem) { LogMsg("Error - malloc"); return; }
234 AssignDomainName(&newelem->name, d);
235 newelem->next = DefRegList;
236 DefRegList = newelem;
237
238 dDNSPlatformDefaultRegDomainChanged(d, mDNStrue);
239 udsserver_default_reg_domain_changed(d, mDNStrue);
240 }
241
242 mDNSlocal void RemoveDefRegDomain(domainname *d)
243 {
244 DNameListElem *ptr = DefRegList, *prev = NULL;
245
246 while (ptr)
247 {
248 if (SameDomainName(&ptr->name, d))
249 {
250 if (prev) prev->next = ptr->next;
251 else DefRegList = ptr->next;
252 freeL("DNameListElem", ptr);
253 dDNSPlatformDefaultRegDomainChanged(d, mDNSfalse);
254 udsserver_default_reg_domain_changed(d, mDNSfalse);
255 return;
256 }
257 prev = ptr;
258 ptr = ptr->next;
259 }
260 debugf("Requested removal of default registration domain %##s not in contained in list", d->c);
261 }
262
263
264 mDNSlocal void FoundDefBrowseDomain(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, mDNSBool AddRecord)
265 {
266 DNameListElem *ptr, *prev, *new;
267 (void)m; // unused;
268 (void)question; // unused
269
270 if (AddRecord)
271 {
272 new = mallocL("FoundDefBrowseDomain", sizeof(DNameListElem));
273 if (!new) { LogMsg("ERROR: malloc"); return; }
274 AssignDomainName(&new->name, &answer->rdata->u.name);
275 new->next = DefBrowseList;
276 DefBrowseList = new;
277 dDNSPlatformDefaultBrowseDomainChanged(&new->name, mDNStrue);
278 udsserver_default_browse_domain_changed(&new->name, mDNStrue);
279 return;
280 }
281 else
282 {
283 ptr = DefBrowseList;
284 prev = NULL;
285 while (ptr)
286 {
287 if (SameDomainName(&ptr->name, &answer->rdata->u.name))
288 {
289 dDNSPlatformDefaultBrowseDomainChanged(&ptr->name, mDNSfalse);
290 udsserver_default_browse_domain_changed(&ptr->name, mDNSfalse);
291 if (prev) prev->next = ptr->next;
292 else DefBrowseList = ptr->next;
293 freeL("FoundDefBrowseDomain", ptr);
294 return;
295 }
296 prev = ptr;
297 ptr = ptr->next;
298 }
299 LogMsg("FoundDefBrowseDomain: Got remove event for domain %##s not in list", answer->rdata->u.name.c);
300 }
301 }
302
303
304 mDNSlocal mStatus RegisterNameServers( mDNS *const m )
305 {
306 IPAddrListElem * list;
307 IPAddrListElem * elem;
308
309 mDNS_DeleteDNSServers(m); // deregister orig list
310
311 list = dDNSPlatformGetDNSServers();
312
313 for ( elem = list; elem; elem = elem->next )
314 {
315 LogOperation("RegisterNameServers: Adding %#a", &elem->addr);
316 mDNS_AddDNSServer(m, &elem->addr, NULL);
317 }
318
319 dDNS_FreeIPAddrList( list );
320
321 return mStatus_NoError;
322 }
323
324
325 mDNSlocal mStatus RegisterSearchDomains( mDNS *const m )
326 {
327 SearchListElem *ptr, *prev, *freeSLPtr;
328 DNameListElem * elem;
329 DNameListElem * list;
330 ARListElem *arList;
331 mStatus err;
332 mDNSBool dict = 1;
333
334 // step 1: mark each elem for removal (-1), unless we aren't passed a dictionary in which case we mark as preexistent
335 for (ptr = SearchList; ptr; ptr = ptr->next) ptr->flag = dict ? -1 : 0;
336
337 // get all the domains from "Search Domains" field of sharing prefs
338
339 list = dDNSPlatformGetSearchDomainList();
340
341 for ( elem = list; elem; elem = elem->next )
342 {
343 MarkSearchListElem(&elem->name);
344 }
345
346 mDNS_FreeDNameList( list );
347
348 list = dDNSPlatformGetDomainName();
349
350 if ( list )
351 {
352 MarkSearchListElem( &list->name );
353 mDNS_FreeDNameList( list );
354 }
355
356 list = dDNSPlatformGetReverseMapSearchDomainList( );
357
358 for ( elem = list; elem; elem = elem->next )
359 {
360 MarkSearchListElem(&elem->name);
361 }
362
363 mDNS_FreeDNameList( list );
364
365 if (dDNSRegDomain.c[0]) MarkSearchListElem(&dDNSRegDomain); // implicitly browse reg domain too (no-op if same as BrowseDomain)
366
367 // delete elems marked for removal, do queries for elems marked add
368 prev = mDNSNULL;
369 ptr = SearchList;
370 while (ptr)
371 {
372 if (ptr->flag == -1) // remove
373 {
374 mDNS_StopQuery(m, &ptr->BrowseQ);
375 mDNS_StopQuery(m, &ptr->RegisterQ);
376 mDNS_StopQuery(m, &ptr->DefBrowseQ);
377 mDNS_StopQuery(m, &ptr->DefRegisterQ);
378 mDNS_StopQuery(m, &ptr->LegacyBrowseQ);
379
380 // deregister records generated from answers to the query
381 arList = ptr->AuthRecs;
382 ptr->AuthRecs = mDNSNULL;
383 while (arList)
384 {
385 AuthRecord *dereg = &arList->ar;
386 arList = arList->next;
387 debugf("Deregistering PTR %##s -> %##s", dereg->resrec.name->c, dereg->resrec.rdata->u.name.c);
388 err = mDNS_Deregister(m, dereg);
389 if (err) LogMsg("ERROR: RegisterSearchDomains mDNS_Deregister returned %d", err);
390 }
391
392 // remove elem from list, delete
393 if (prev) prev->next = ptr->next;
394 else SearchList = ptr->next;
395 freeSLPtr = ptr;
396 ptr = ptr->next;
397 freeL("RegisterSearchDomains - freeSLPtr", freeSLPtr);
398 continue;
399 }
400
401 if (ptr->flag == 1) // add
402 {
403 mStatus err1, err2, err3, err4, err5;
404 err1 = mDNS_GetDomains(m, &ptr->BrowseQ, mDNS_DomainTypeBrowse, &ptr->domain, mDNSInterface_Any, FoundDomain, ptr);
405 err2 = mDNS_GetDomains(m, &ptr->DefBrowseQ, mDNS_DomainTypeBrowseDefault, &ptr->domain, mDNSInterface_Any, FoundDomain, ptr);
406 err3 = mDNS_GetDomains(m, &ptr->RegisterQ, mDNS_DomainTypeRegistration, &ptr->domain, mDNSInterface_Any, FoundDomain, ptr);
407 err4 = mDNS_GetDomains(m, &ptr->DefRegisterQ, mDNS_DomainTypeRegistrationDefault, &ptr->domain, mDNSInterface_Any, FoundDomain, ptr);
408 err5 = mDNS_GetDomains(m, &ptr->LegacyBrowseQ, mDNS_DomainTypeBrowseLegacy, &ptr->domain, mDNSInterface_Any, FoundDomain, ptr);
409 if (err1 || err2 || err3 || err4 || err5)
410 LogMsg("GetDomains for domain %##s returned error(s):\n"
411 "%d (mDNS_DomainTypeBrowse)\n"
412 "%d (mDNS_DomainTypeBrowseDefault)\n"
413 "%d (mDNS_DomainTypeRegistration)\n"
414 "%d (mDNS_DomainTypeRegistrationDefault)"
415 "%d (mDNS_DomainTypeBrowseLegacy)\n",
416 ptr->domain.c, err1, err2, err3, err4, err5);
417 ptr->flag = 0;
418 }
419
420 if (ptr->flag) { LogMsg("RegisterSearchDomains - unknown flag %d. Skipping.", ptr->flag); }
421
422 prev = ptr;
423 ptr = ptr->next;
424 }
425
426 return mStatus_NoError;
427 }
428
429
430 mDNSlocal void RegisterBrowseDomainPTR(mDNS *m, const domainname *d, int type)
431 {
432 // allocate/register legacy and non-legacy _browse PTR record
433 mStatus err;
434 ARListElem *browse = mallocL("ARListElem", sizeof(*browse));
435 mDNS_SetupResourceRecord(&browse->ar, mDNSNULL, mDNSInterface_LocalOnly, kDNSType_PTR, 7200, kDNSRecordTypeShared, FreeARElemCallback, browse);
436 MakeDomainNameFromDNSNameString(browse->ar.resrec.name, mDNS_DomainTypeNames[type]);
437 AppendDNSNameString (browse->ar.resrec.name, "local");
438 AssignDomainName(&browse->ar.resrec.rdata->u.name, d);
439 err = mDNS_Register(m, &browse->ar);
440 if (err)
441 {
442 LogMsg("SetSCPrefsBrowseDomain: mDNS_Register returned error %d", err);
443 freeL("ARListElem", browse);
444 }
445 else
446 {
447 browse->next = SCPrefBrowseDomains;
448 SCPrefBrowseDomains = browse;
449 }
450 }
451
452 mDNSlocal void DeregisterBrowseDomainPTR(mDNS *m, const domainname *d, int type)
453 {
454 ARListElem *remove, **ptr = &SCPrefBrowseDomains;
455 domainname lhs; // left-hand side of PTR, for comparison
456
457 MakeDomainNameFromDNSNameString(&lhs, mDNS_DomainTypeNames[type]);
458 AppendDNSNameString (&lhs, "local");
459
460 while (*ptr)
461 {
462 if (SameDomainName(&(*ptr)->ar.resrec.rdata->u.name, d) && SameDomainName((*ptr)->ar.resrec.name, &lhs))
463 {
464 remove = *ptr;
465 *ptr = (*ptr)->next;
466 mDNS_Deregister(m, &remove->ar);
467 return;
468 }
469 else ptr = &(*ptr)->next;
470 }
471 }
472
473 // Add or remove a user-specified domain to the list of empty-string browse domains
474 // Also register a non-legacy _browse PTR record so that the domain appears in enumeration lists
475 mDNSlocal void SetSCPrefsBrowseDomain(mDNS *m, const domainname *d, mDNSBool add)
476 {
477 LogMsg("%s default browse domain %##s", add ? "Adding" : "Removing", d->c);
478
479 if (add)
480 {
481 RegisterBrowseDomainPTR(m, d, mDNS_DomainTypeBrowse);
482 RegisterBrowseDomainPTR(m, d, mDNS_DomainTypeBrowseLegacy);
483 }
484 else
485 {
486 DeregisterBrowseDomainPTR(m, d, mDNS_DomainTypeBrowse);
487 DeregisterBrowseDomainPTR(m, d, mDNS_DomainTypeBrowseLegacy);
488 }
489 }
490
491 mDNSlocal void SetSCPrefsBrowseDomains(mDNS *m, DNameListElem * browseDomains, mDNSBool add)
492 {
493 DNameListElem * browseDomain;
494
495 for ( browseDomain = browseDomains; browseDomain; browseDomain = browseDomain->next )
496 {
497 if ( !browseDomain->name.c[0] )
498 {
499 LogMsg("SetSCPrefsBrowseDomains bad DDNS browse domain: %##s", browseDomain->name.c[0] ? (char*) browseDomain->name.c : "(unknown)");
500 }
501 else
502 {
503 SetSCPrefsBrowseDomain(m, &browseDomain->name, add);
504 }
505 }
506 }
507
508 mStatus dDNS_Setup( mDNS *const m )
509 {
510 static mDNSBool LegacyNATInitialized = mDNSfalse;
511 mDNSBool dict = mDNStrue;
512 mDNSAddr ip;
513 mDNSAddr r;
514 DNameListElem * BrowseDomains;
515 domainname RegDomain, fqdn;
516
517 // get fqdn, zone from SCPrefs
518 dDNSPlatformGetConfig(&fqdn, &RegDomain, &BrowseDomains);
519
520 // YO if (!fqdn.c[0] && !RegDomain.c[0]) ReadDDNSSettingsFromConfFile(m, CONFIG_FILE, &fqdn, &RegDomain);
521
522 if (!SameDomainName(&RegDomain, &dDNSRegDomain))
523 {
524 if (dDNSRegDomain.c[0])
525 {
526 RemoveDefRegDomain(&dDNSRegDomain);
527 SetSCPrefsBrowseDomain(m, &dDNSRegDomain, mDNSfalse); // if we were automatically browsing in our registration domain, stop
528 }
529
530 AssignDomainName(&dDNSRegDomain, &RegDomain);
531
532 if (dDNSRegDomain.c[0])
533 {
534 dDNSPlatformSetSecretForDomain(m, &dDNSRegDomain);
535 AddDefRegDomain(&dDNSRegDomain);
536 SetSCPrefsBrowseDomain(m, &dDNSRegDomain, mDNStrue);
537 }
538 }
539
540 // Add new browse domains to internal list
541
542 if ( BrowseDomains )
543 {
544 SetSCPrefsBrowseDomains( m, BrowseDomains, mDNStrue );
545 }
546
547 // Remove old browse domains from internal list
548
549 if ( dDNSBrowseDomains )
550 {
551 SetSCPrefsBrowseDomains( m, dDNSBrowseDomains, mDNSfalse );
552 mDNS_FreeDNameList( dDNSBrowseDomains );
553 }
554
555 // Replace the old browse domains array with the new array
556
557 dDNSBrowseDomains = BrowseDomains;
558
559
560 if (!SameDomainName(&fqdn, &dDNSHostname))
561 {
562 if (dDNSHostname.c[0]) mDNS_RemoveDynDNSHostName(m, &dDNSHostname);
563 AssignDomainName(&dDNSHostname, &fqdn);
564 if (dDNSHostname.c[0])
565 {
566 dDNSPlatformSetSecretForDomain(m, &fqdn); // no-op if "zone" secret, above, is to be used for hostname
567 mDNS_AddDynDNSHostName(m, &dDNSHostname, SCPrefsdDNSCallback, mDNSNULL);
568 dDNSPlatformSetNameStatus(&dDNSHostname, 1);
569 }
570 }
571
572 // get DNS settings
573 // YO SCDynamicStoreRef store = SCDynamicStoreCreate(mDNSNULL, CFSTR("mDNSResponder:dDNSConfigChanged"), mDNSNULL, mDNSNULL);
574 // YO if (!store) return;
575
576 // YO key = SCDynamicStoreKeyCreateNetworkGlobalEntity(mDNSNULL, kSCDynamicStoreDomainState, kSCEntNetDNS);
577 // YO if (!key) { LogMsg("ERROR: DNSConfigChanged - SCDynamicStoreKeyCreateNetworkGlobalEntity"); CFRelease(store); return; }
578 // YO dict = SCDynamicStoreCopyValue(store, key);
579 // YO CFRelease(key);
580
581 // handle any changes to search domains and DNS server addresses
582
583 if ( dDNSPlatformRegisterSplitDNS(m) != mStatus_NoError)
584 if (dict) RegisterNameServers( m ); // fall back to non-split DNS aware configuration on failure
585
586 if ( dDNSRegisterSearchDomains == mDNStrue )
587 dDNS_RegisterSearchDomains( m ); // note that we register name servers *before* search domains
588
589 // if (dict) CFRelease(dict);
590
591 // get IPv4 settings
592 // YO key = SCDynamicStoreKeyCreateNetworkGlobalEntity(mDNSNULL,kSCDynamicStoreDomainState, kSCEntNetIPv4);
593 // YO if (!key) { LogMsg("ERROR: RouterChanged - SCDynamicStoreKeyCreateNetworkGlobalEntity"); CFRelease(store); return; }
594 // YO dict = SCDynamicStoreCopyValue(store, key);
595 // YO CFRelease(key);
596 // YO CFRelease(store);
597 // YO if (!dict)
598 // YO { mDNS_SetPrimaryInterfaceInfo(m, mDNSNULL, mDNSNULL); return; } // lost v4
599
600 // handle router changes
601 // YO mDNSAddr r;
602 // YO char buf[256];
603 // YO r.type = mDNSAddrType_IPv4;
604 // YO r.ip.v4.NotAnInteger = 0;
605 // YO CFStringRef router = CFDictionaryGetValue(dict, kSCPropNetIPv4Router);
606 // YO if (router)
607 // YO {
608 // YO if (!CFStringGetCString(router, buf, 256, kCFStringEncodingUTF8))
609 // YO LogMsg("Could not convert router to CString");
610 // YO else inet_aton(buf, (struct in_addr *)&r.ip.v4);
611 // YO }
612
613 // handle router and primary interface changes
614
615 ip.type = r.type = mDNSAddrType_IPv4;
616 ip.ip.v4.NotAnInteger = r.ip.v4.NotAnInteger = 0;
617
618 if ( dDNSPlatformGetPrimaryInterface( m, &ip, &r ) == mStatus_NoError )
619 {
620 // For now, we're going to pass NULL for the IPv6 parameter so that the Windows code compiles. What needs
621 // to happen is that the implementation of dDNSPlatformGetPrimaryInterface() needs to call the
622 // IPv6 aware "GetAdaptersAddresses" rather than GetAdaptersInfo().
623 mDNS_SetPrimaryInterfaceInfo(m, &ip, NULL, r.ip.v4.NotAnInteger ? &r : mDNSNULL);
624 }
625
626 return mStatus_NoError;
627 }
628
629
630 // Construction of Default Browse domain list (i.e. when clients pass NULL) is as follows:
631 // 1) query for b._dns-sd._udp.local on LocalOnly interface
632 // (.local manually generated via explicit callback)
633 // 2) for each search domain (from prefs pane), query for b._dns-sd._udp.<searchdomain>.
634 // 3) for each result from (2), register LocalOnly PTR record b._dns-sd._udp.local. -> <result>
635 // 4) result above should generate a callback from question in (1). result added to global list
636 // 5) global list delivered to client via GetSearchDomainList()
637 // 6) client calls to enumerate domains now go over LocalOnly interface
638 // (!!!KRS may add outgoing interface in addition)
639
640 mStatus dDNS_InitDNSConfig(mDNS *const m)
641 {
642 mStatus err;
643 static AuthRecord LocalRegPTR;
644
645 // start query for domains to be used in default (empty string domain) browses
646 err = mDNS_GetDomains(m, &LegacyBrowseDomainQ, mDNS_DomainTypeBrowseLegacy, NULL, mDNSInterface_LocalOnly, FoundDefBrowseDomain, NULL);
647
648 // provide .local automatically
649 SetSCPrefsBrowseDomain(m, &localdomain, mDNStrue);
650
651 // <rdar://problem/4055653> dns-sd -E does not return "local."
652 // register registration domain "local"
653 mDNS_SetupResourceRecord(&LocalRegPTR, mDNSNULL, mDNSInterface_LocalOnly, kDNSType_PTR, 7200, kDNSRecordTypeShared, NULL, NULL);
654 MakeDomainNameFromDNSNameString(LocalRegPTR.resrec.name, mDNS_DomainTypeNames[mDNS_DomainTypeRegistration]);
655 AppendDNSNameString (LocalRegPTR.resrec.name, "local");
656 AssignDomainName(&LocalRegPTR.resrec.rdata->u.name, &localdomain);
657 err = mDNS_Register(m, &LocalRegPTR);
658 if (err)
659 {
660 LogMsg("ERROR: dDNS_InitDNSConfig - mDNS_Register returned error %d", err);
661 }
662
663 return mStatus_NoError;
664 }
665
666 void
667 dDNS_FreeIPAddrList(IPAddrListElem * list)
668 {
669 IPAddrListElem * fptr;
670
671 while (list)
672 {
673 fptr = list;
674 list = list->next;
675 mDNSPlatformMemFree(fptr);
676 }
677 }