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