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