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