2 * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
23 Change History (most recent first):
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
33 #include "DNSCommon.h"
34 #include "uds_daemon.h"
39 typedef struct SearchListElem
41 struct SearchListElem
*next
;
45 DNSQuestion DefBrowseQ
;
46 DNSQuestion LegacyBrowseQ
;
47 DNSQuestion RegisterQ
;
48 DNSQuestion DefRegisterQ
;
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
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
;
63 mStatus
dDNS_SetupAddr(mDNSAddr
*ip
, const struct sockaddr
*const sa
)
65 if (!sa
) { LogMsg("SetupAddr ERROR: NULL sockaddr"); return(mStatus_Invalid
); }
67 if (sa
->sa_family
== AF_INET
)
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
);
75 if (sa
->sa_family
== AF_INET6
)
77 struct sockaddr_in6
*ifa_addr
= (struct sockaddr_in6
*)sa
;
78 ip
->type
= mDNSAddrType_IPv6
;
80 if (IN6_IS_ADDR_LINKLOCAL(&ifa_addr
->sin6_addr
)) ifa_addr
->sin6_addr
.__u6_addr
.__u6_addr16
[1] = 0;
82 if (IN6_IS_ADDR_LINKLOCAL(&ifa_addr
->sin6_addr
)) ifa_addr
->sin6_addr
.u
.Word
[1] = 0;
84 ip
->ip
.v6
= *(mDNSv6Addr
*)&ifa_addr
->sin6_addr
;
85 return(mStatus_NoError
);
88 LogMsg("SetupAddr invalid sa_family %d", sa
->sa_family
);
89 return(mStatus_Invalid
);
92 mDNSlocal
void MarkSearchListElem(domainname
*domain
)
94 SearchListElem
*new, *ptr
;
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
))
100 if (ptr
->flag
!= 1) ptr
->flag
= 0; // gracefully handle duplicates - if it is already marked as add, don't bump down to preexistent
104 // if domain not in list, add to list, mark as add (1)
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
;
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
)
121 debugf("SCPrefsdDNSCallback: result %d for registration of name %##s", result
, rr
->resrec
.name
->c
);
122 dDNSPlatformSetNameStatus(rr
->resrec
.name
, result
);
125 mDNSlocal
void FreeARElemCallback(mDNS
*const m
, AuthRecord
*const rr
, mStatus result
)
127 ARListElem
*elem
= rr
->RecordContext
;
131 if (result
== mStatus_MemFree
) freeL("FreeARElemCallback", elem
);
134 mDNSlocal
void FoundDomain(mDNS
*const m
, DNSQuestion
*question
, const ResourceRecord
*const answer
, mDNSBool AddRecord
)
136 SearchListElem
*slElem
= question
->QuestionContext
;
137 ARListElem
*arElem
, *ptr
, *prev
;
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; }
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
);
160 LogMsg("ERROR: FoundDomain - mDNS_Register returned %d", err
);
161 freeL("FoundDomain - arElem", arElem
);
164 arElem
->next
= slElem
->AuthRecs
;
165 slElem
->AuthRecs
= arElem
;
169 ptr
= slElem
->AuthRecs
;
173 if (SameDomainName(&ptr
->ar
.resrec
.rdata
->u
.name
, &answer
->rdata
->u
.name
))
175 debugf("Deregistering PTR %##s -> %##s", ptr
->ar
.resrec
.name
->c
, ptr
->ar
.resrec
.rdata
->u
.name
.c
);
177 if (prev
) prev
->next
= ptr
->next
;
178 else slElem
->AuthRecs
= ptr
->next
;
180 err
= mDNS_Deregister(m
, dereg
);
181 if (err
) LogMsg("ERROR: FoundDomain - mDNS_Deregister returned %d", err
);
192 mDNSexport DNameListElem
*mDNSPlatformGetSearchDomainList(void)
194 return mDNS_CopyDNameList(DefBrowseList
);
197 mDNSexport DNameListElem
*mDNSPlatformGetRegDomainList(void)
199 return mDNS_CopyDNameList(DefRegList
);
202 mDNSlocal
void AddDefRegDomain(domainname
*d
)
204 DNameListElem
*newelem
= NULL
, *ptr
;
206 // make sure name not already in list
207 for (ptr
= DefRegList
; ptr
; ptr
= ptr
->next
)
209 if (SameDomainName(&ptr
->name
, d
))
210 { debugf("duplicate addition of default reg domain %##s", d
->c
); return; }
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
;
219 dDNSPlatformDefaultRegDomainChanged(d
, mDNStrue
);
220 udsserver_default_reg_domain_changed(d
, mDNStrue
);
223 mDNSlocal
void RemoveDefRegDomain(domainname
*d
)
225 DNameListElem
*ptr
= DefRegList
, *prev
= NULL
;
229 if (SameDomainName(&ptr
->name
, d
))
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
);
241 debugf("Requested removal of default registration domain %##s not in contained in list", d
->c
);
245 mDNSlocal
void FoundDefBrowseDomain(mDNS
*const m
, DNSQuestion
*question
, const ResourceRecord
*const answer
, mDNSBool AddRecord
)
247 DNameListElem
*ptr
, *prev
, *new;
249 (void)question
; // unused
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
;
258 dDNSPlatformDefaultBrowseDomainChanged(&new->name
, mDNStrue
);
259 udsserver_default_browse_domain_changed(&new->name
, mDNStrue
);
268 if (SameDomainName(&ptr
->name
, &answer
->rdata
->u
.name
))
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
);
280 LogMsg("FoundDefBrowseDomain: Got remove event for domain %##s not in list", answer
->rdata
->u
.name
.c
);
285 mDNSlocal mStatus
RegisterNameServers( mDNS
*const m
)
287 IPAddrListElem
* list
;
288 IPAddrListElem
* elem
;
290 mDNS_DeleteDNSServers(m
); // deregister orig list
292 list
= dDNSPlatformGetDNSServers();
294 for ( elem
= list
; elem
; elem
= elem
->next
)
296 LogOperation("RegisterNameServers: Adding %#a", &elem
->addr
);
297 mDNS_AddDNSServer(m
, &elem
->addr
, NULL
);
300 dDNS_FreeIPAddrList( list
);
302 return mStatus_NoError
;
306 mDNSlocal mStatus
RegisterSearchDomains( mDNS
*const m
)
308 SearchListElem
*ptr
, *prev
, *freeSLPtr
;
309 DNameListElem
* elem
;
310 DNameListElem
* list
;
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;
318 // get all the domains from "Search Domains" field of sharing prefs
320 list
= dDNSPlatformGetSearchDomainList();
322 for ( elem
= list
; elem
; elem
= elem
->next
)
324 MarkSearchListElem(&elem
->name
);
327 mDNS_FreeDNameList( list
);
329 list
= dDNSPlatformGetDomainName();
333 MarkSearchListElem( &list
->name
);
334 mDNS_FreeDNameList( list
);
337 list
= dDNSPlatformGetReverseMapSearchDomainList( );
339 for ( elem
= list
; elem
; elem
= elem
->next
)
341 MarkSearchListElem(&elem
->name
);
344 mDNS_FreeDNameList( list
);
346 if (dDNSRegDomain
.c
[0]) MarkSearchListElem(&dDNSRegDomain
); // implicitly browse reg domain too (no-op if same as BrowseDomain)
348 // delete elems marked for removal, do queries for elems marked add
353 if (ptr
->flag
== -1) // remove
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
);
361 // deregister records generated from answers to the query
362 arList
= ptr
->AuthRecs
;
363 ptr
->AuthRecs
= mDNSNULL
;
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
);
373 // remove elem from list, delete
374 if (prev
) prev
->next
= ptr
->next
;
375 else SearchList
= ptr
->next
;
378 freeL("RegisterSearchDomains - freeSLPtr", freeSLPtr
);
382 if (ptr
->flag
== 1) // add
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
);
401 if (ptr
->flag
) { LogMsg("RegisterSearchDomains - unknown flag %d. Skipping.", ptr
->flag
); }
407 return mStatus_NoError
;
411 mDNSlocal
void RegisterBrowseDomainPTR(mDNS
*m
, const domainname
*d
, int type
)
413 // allocate/register legacy and non-legacy _browse PTR record
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
);
423 LogMsg("SetSCPrefsBrowseDomain: mDNS_Register returned error %d", err
);
424 freeL("ARListElem", browse
);
428 browse
->next
= SCPrefBrowseDomains
;
429 SCPrefBrowseDomains
= browse
;
433 mDNSlocal
void DeregisterBrowseDomainPTR(mDNS
*m
, const domainname
*d
, int type
)
435 ARListElem
*remove
, **ptr
= &SCPrefBrowseDomains
;
436 domainname lhs
; // left-hand side of PTR, for comparison
438 MakeDomainNameFromDNSNameString(&lhs
, mDNS_DomainTypeNames
[type
]);
439 AppendDNSNameString (&lhs
, "local");
443 if (SameDomainName(&(*ptr
)->ar
.resrec
.rdata
->u
.name
, d
) && SameDomainName((*ptr
)->ar
.resrec
.name
, &lhs
))
447 mDNS_Deregister(m
, &remove
->ar
);
450 else ptr
= &(*ptr
)->next
;
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
)
458 LogMsg("%s default browse domain %##s", add
? "Adding" : "Removing", d
->c
);
462 RegisterBrowseDomainPTR(m
, d
, mDNS_DomainTypeBrowse
);
463 RegisterBrowseDomainPTR(m
, d
, mDNS_DomainTypeBrowseLegacy
);
467 DeregisterBrowseDomainPTR(m
, d
, mDNS_DomainTypeBrowse
);
468 DeregisterBrowseDomainPTR(m
, d
, mDNS_DomainTypeBrowseLegacy
);
472 mDNSlocal
void SetSCPrefsBrowseDomains(mDNS
*m
, DNameListElem
* browseDomains
, mDNSBool add
)
474 DNameListElem
* browseDomain
;
476 for ( browseDomain
= browseDomains
; browseDomain
; browseDomain
= browseDomain
->next
)
478 if ( !browseDomain
->name
.c
[0] )
480 LogMsg("SetSCPrefsBrowseDomains bad DDNS browse domain: %##s", browseDomain
->name
.c
[0] ? (char*) browseDomain
->name
.c
: "(unknown)");
484 SetSCPrefsBrowseDomain(m
, &browseDomain
->name
, add
);
489 mStatus
dDNS_Setup( mDNS
*const m
)
491 static mDNSBool LegacyNATInitialized
= mDNSfalse
;
492 mDNSBool dict
= mDNStrue
;
495 DNameListElem
* BrowseDomains
;
496 domainname RegDomain
, fqdn
;
498 // get fqdn, zone from SCPrefs
499 dDNSPlatformGetConfig(&fqdn
, &RegDomain
, &BrowseDomains
);
501 // YO if (!fqdn.c[0] && !RegDomain.c[0]) ReadDDNSSettingsFromConfFile(m, CONFIG_FILE, &fqdn, &RegDomain);
503 if (!SameDomainName(&RegDomain
, &dDNSRegDomain
))
505 if (dDNSRegDomain
.c
[0])
507 RemoveDefRegDomain(&dDNSRegDomain
);
508 SetSCPrefsBrowseDomain(m
, &dDNSRegDomain
, mDNSfalse
); // if we were automatically browsing in our registration domain, stop
511 AssignDomainName(&dDNSRegDomain
, &RegDomain
);
513 if (dDNSRegDomain
.c
[0])
515 dDNSPlatformSetSecretForDomain(m
, &dDNSRegDomain
);
516 AddDefRegDomain(&dDNSRegDomain
);
517 SetSCPrefsBrowseDomain(m
, &dDNSRegDomain
, mDNStrue
);
521 // Add new browse domains to internal list
525 SetSCPrefsBrowseDomains( m
, BrowseDomains
, mDNStrue
);
528 // Remove old browse domains from internal list
530 if ( dDNSBrowseDomains
)
532 SetSCPrefsBrowseDomains( m
, dDNSBrowseDomains
, mDNSfalse
);
533 mDNS_FreeDNameList( dDNSBrowseDomains
);
536 // Replace the old browse domains array with the new array
538 dDNSBrowseDomains
= BrowseDomains
;
541 if (!SameDomainName(&fqdn
, &dDNSHostname
))
543 if (dDNSHostname
.c
[0]) mDNS_RemoveDynDNSHostName(m
, &dDNSHostname
);
544 AssignDomainName(&dDNSHostname
, &fqdn
);
545 if (dDNSHostname
.c
[0])
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);
554 // YO SCDynamicStoreRef store = SCDynamicStoreCreate(mDNSNULL, CFSTR("mDNSResponder:dDNSConfigChanged"), mDNSNULL, mDNSNULL);
555 // YO if (!store) return;
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);
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);
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);
575 // YO { mDNS_SetPrimaryInterfaceInfo(m, mDNSNULL, mDNSNULL); return; } // lost v4
577 // handle router changes
580 // YO r.type = mDNSAddrType_IPv4;
581 // YO r.ip.v4.NotAnInteger = 0;
582 // YO CFStringRef router = CFDictionaryGetValue(dict, kSCPropNetIPv4Router);
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);
590 // handle router and primary interface changes
592 ip
.type
= r
.type
= mDNSAddrType_IPv4
;
593 ip
.ip
.v4
.NotAnInteger
= r
.ip
.v4
.NotAnInteger
= 0;
595 if ( dDNSPlatformGetPrimaryInterface( m
, &ip
, &r
) == mStatus_NoError
)
597 mDNS_SetPrimaryInterfaceInfo(m
, &ip
, r
.ip
.v4
.NotAnInteger
? &r
: mDNSNULL
);
600 return mStatus_NoError
;
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)
614 mStatus
dDNS_InitDNSConfig(mDNS
*const m
)
617 static AuthRecord LocalRegPTR
;
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
);
622 // provide .local automatically
623 SetSCPrefsBrowseDomain(m
, &localdomain
, mDNStrue
);
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
);
634 LogMsg("ERROR: dDNS_InitDNSConfig - mDNS_Register returned error %d", err
);
637 return mStatus_NoError
;
641 dDNS_FreeIPAddrList(IPAddrListElem
* list
)
643 IPAddrListElem
* fptr
;
649 mDNSPlatformMemFree(fptr
);