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.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.
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.
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
39 #include "DNSCommon.h"
40 #include "uds_daemon.h"
45 typedef struct SearchListElem
47 struct SearchListElem
*next
;
51 DNSQuestion DefBrowseQ
;
52 DNSQuestion LegacyBrowseQ
;
53 DNSQuestion RegisterQ
;
54 DNSQuestion DefRegisterQ
;
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
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
;
69 mDNSlocal mStatus
RegisterNameServers( mDNS
*const m
);
70 mDNSlocal mStatus
RegisterSearchDomains( mDNS
*const m
);
73 mStatus
dDNS_SetupAddr(mDNSAddr
*ip
, const struct sockaddr
*const sa
)
75 if (!sa
) { LogMsg("SetupAddr ERROR: NULL sockaddr"); return(mStatus_Invalid
); }
77 if (sa
->sa_family
== AF_INET
)
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
);
85 if (sa
->sa_family
== AF_INET6
)
87 struct sockaddr_in6
*ifa_addr
= (struct sockaddr_in6
*)sa
;
88 ip
->type
= mDNSAddrType_IPv6
;
90 if (IN6_IS_ADDR_LINKLOCAL(&ifa_addr
->sin6_addr
)) ifa_addr
->sin6_addr
.__u6_addr
.__u6_addr16
[1] = 0;
92 if (IN6_IS_ADDR_LINKLOCAL(&ifa_addr
->sin6_addr
)) ifa_addr
->sin6_addr
.u
.Word
[1] = 0;
94 ip
->ip
.v6
= *(mDNSv6Addr
*)&ifa_addr
->sin6_addr
;
95 return(mStatus_NoError
);
98 LogMsg("SetupAddr invalid sa_family %d", sa
->sa_family
);
99 return(mStatus_Invalid
);
103 mStatus
dDNS_RegisterSearchDomains( mDNS
* const m
)
105 mStatus err
= mStatus_NoError
;
107 dDNSRegisterSearchDomains
= mDNStrue
;
108 RegisterSearchDomains( m
);
114 mDNSlocal
void MarkSearchListElem(domainname
*domain
)
116 SearchListElem
*new, *ptr
;
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
))
122 if (ptr
->flag
!= 1) ptr
->flag
= 0; // gracefully handle duplicates - if it is already marked as add, don't bump down to preexistent
126 // if domain not in list, add to list, mark as add (1)
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
;
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
)
143 debugf("SCPrefsdDNSCallback: result %d for registration of name %##s", result
, rr
->resrec
.name
->c
);
144 dDNSPlatformSetNameStatus(rr
->resrec
.name
, result
);
147 mDNSlocal
void FreeARElemCallback(mDNS
*const m
, AuthRecord
*const rr
, mStatus result
)
149 ARListElem
*elem
= rr
->RecordContext
;
153 if (result
== mStatus_MemFree
) freeL("FreeARElemCallback", elem
);
156 mDNSlocal
void FoundDomain(mDNS
*const m
, DNSQuestion
*question
, const ResourceRecord
*const answer
, mDNSBool AddRecord
)
158 SearchListElem
*slElem
= question
->QuestionContext
;
159 ARListElem
*arElem
, *ptr
, *prev
;
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; }
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
);
182 LogMsg("ERROR: FoundDomain - mDNS_Register returned %d", err
);
183 freeL("FoundDomain - arElem", arElem
);
186 arElem
->next
= slElem
->AuthRecs
;
187 slElem
->AuthRecs
= arElem
;
191 ptr
= slElem
->AuthRecs
;
195 if (SameDomainName(&ptr
->ar
.resrec
.rdata
->u
.name
, &answer
->rdata
->u
.name
))
197 debugf("Deregistering PTR %##s -> %##s", ptr
->ar
.resrec
.name
->c
, ptr
->ar
.resrec
.rdata
->u
.name
.c
);
199 if (prev
) prev
->next
= ptr
->next
;
200 else slElem
->AuthRecs
= ptr
->next
;
202 err
= mDNS_Deregister(m
, dereg
);
203 if (err
) LogMsg("ERROR: FoundDomain - mDNS_Deregister returned %d", err
);
214 mDNSexport DNameListElem
*mDNSPlatformGetSearchDomainList(void)
216 return mDNS_CopyDNameList(DefBrowseList
);
219 mDNSexport DNameListElem
*mDNSPlatformGetRegDomainList(void)
221 return mDNS_CopyDNameList(DefRegList
);
224 mDNSlocal
void AddDefRegDomain(domainname
*d
)
226 DNameListElem
*newelem
= NULL
, *ptr
;
228 // make sure name not already in list
229 for (ptr
= DefRegList
; ptr
; ptr
= ptr
->next
)
231 if (SameDomainName(&ptr
->name
, d
))
232 { debugf("duplicate addition of default reg domain %##s", d
->c
); return; }
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
;
241 dDNSPlatformDefaultRegDomainChanged(d
, mDNStrue
);
242 udsserver_default_reg_domain_changed(d
, mDNStrue
);
245 mDNSlocal
void RemoveDefRegDomain(domainname
*d
)
247 DNameListElem
*ptr
= DefRegList
, *prev
= NULL
;
251 if (SameDomainName(&ptr
->name
, d
))
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
);
263 debugf("Requested removal of default registration domain %##s not in contained in list", d
->c
);
267 mDNSlocal
void FoundDefBrowseDomain(mDNS
*const m
, DNSQuestion
*question
, const ResourceRecord
*const answer
, mDNSBool AddRecord
)
269 DNameListElem
*ptr
, *prev
, *new;
271 (void)question
; // unused
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
;
280 dDNSPlatformDefaultBrowseDomainChanged(&new->name
, mDNStrue
);
281 udsserver_default_browse_domain_changed(&new->name
, mDNStrue
);
290 if (SameDomainName(&ptr
->name
, &answer
->rdata
->u
.name
))
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
);
302 LogMsg("FoundDefBrowseDomain: Got remove event for domain %##s not in list", answer
->rdata
->u
.name
.c
);
307 mDNSlocal mStatus
RegisterNameServers( mDNS
*const m
)
309 IPAddrListElem
* list
;
310 IPAddrListElem
* elem
;
312 mDNS_DeleteDNSServers(m
); // deregister orig list
314 list
= dDNSPlatformGetDNSServers();
316 for ( elem
= list
; elem
; elem
= elem
->next
)
318 LogOperation("RegisterNameServers: Adding %#a", &elem
->addr
);
319 mDNS_AddDNSServer(m
, &elem
->addr
, NULL
);
322 dDNS_FreeIPAddrList( list
);
324 return mStatus_NoError
;
328 mDNSlocal mStatus
RegisterSearchDomains( mDNS
*const m
)
330 SearchListElem
*ptr
, *prev
, *freeSLPtr
;
331 DNameListElem
* elem
;
332 DNameListElem
* list
;
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;
340 // get all the domains from "Search Domains" field of sharing prefs
342 list
= dDNSPlatformGetSearchDomainList();
344 for ( elem
= list
; elem
; elem
= elem
->next
)
346 MarkSearchListElem(&elem
->name
);
349 mDNS_FreeDNameList( list
);
351 list
= dDNSPlatformGetDomainName();
355 MarkSearchListElem( &list
->name
);
356 mDNS_FreeDNameList( list
);
359 list
= dDNSPlatformGetReverseMapSearchDomainList( );
361 for ( elem
= list
; elem
; elem
= elem
->next
)
363 MarkSearchListElem(&elem
->name
);
366 mDNS_FreeDNameList( list
);
368 if (dDNSRegDomain
.c
[0]) MarkSearchListElem(&dDNSRegDomain
); // implicitly browse reg domain too (no-op if same as BrowseDomain)
370 // delete elems marked for removal, do queries for elems marked add
375 if (ptr
->flag
== -1) // remove
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
);
383 // deregister records generated from answers to the query
384 arList
= ptr
->AuthRecs
;
385 ptr
->AuthRecs
= mDNSNULL
;
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
);
395 // remove elem from list, delete
396 if (prev
) prev
->next
= ptr
->next
;
397 else SearchList
= ptr
->next
;
400 freeL("RegisterSearchDomains - freeSLPtr", freeSLPtr
);
404 if (ptr
->flag
== 1) // add
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
);
423 if (ptr
->flag
) { LogMsg("RegisterSearchDomains - unknown flag %d. Skipping.", ptr
->flag
); }
429 return mStatus_NoError
;
433 mDNSlocal
void RegisterBrowseDomainPTR(mDNS
*m
, const domainname
*d
, int type
)
435 // allocate/register legacy and non-legacy _browse PTR record
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
);
445 LogMsg("SetSCPrefsBrowseDomain: mDNS_Register returned error %d", err
);
446 freeL("ARListElem", browse
);
450 browse
->next
= SCPrefBrowseDomains
;
451 SCPrefBrowseDomains
= browse
;
455 mDNSlocal
void DeregisterBrowseDomainPTR(mDNS
*m
, const domainname
*d
, int type
)
457 ARListElem
*remove
, **ptr
= &SCPrefBrowseDomains
;
458 domainname lhs
; // left-hand side of PTR, for comparison
460 MakeDomainNameFromDNSNameString(&lhs
, mDNS_DomainTypeNames
[type
]);
461 AppendDNSNameString (&lhs
, "local");
465 if (SameDomainName(&(*ptr
)->ar
.resrec
.rdata
->u
.name
, d
) && SameDomainName((*ptr
)->ar
.resrec
.name
, &lhs
))
469 mDNS_Deregister(m
, &remove
->ar
);
472 else ptr
= &(*ptr
)->next
;
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
)
480 LogMsg("%s default browse domain %##s", add
? "Adding" : "Removing", d
->c
);
484 RegisterBrowseDomainPTR(m
, d
, mDNS_DomainTypeBrowse
);
485 RegisterBrowseDomainPTR(m
, d
, mDNS_DomainTypeBrowseLegacy
);
489 DeregisterBrowseDomainPTR(m
, d
, mDNS_DomainTypeBrowse
);
490 DeregisterBrowseDomainPTR(m
, d
, mDNS_DomainTypeBrowseLegacy
);
494 mDNSlocal
void SetSCPrefsBrowseDomains(mDNS
*m
, DNameListElem
* browseDomains
, mDNSBool add
)
496 DNameListElem
* browseDomain
;
498 for ( browseDomain
= browseDomains
; browseDomain
; browseDomain
= browseDomain
->next
)
500 if ( !browseDomain
->name
.c
[0] )
502 LogMsg("SetSCPrefsBrowseDomains bad DDNS browse domain: %##s", browseDomain
->name
.c
[0] ? (char*) browseDomain
->name
.c
: "(unknown)");
506 SetSCPrefsBrowseDomain(m
, &browseDomain
->name
, add
);
511 mStatus
dDNS_Setup( mDNS
*const m
)
513 static mDNSBool LegacyNATInitialized
= mDNSfalse
;
514 mDNSBool dict
= mDNStrue
;
517 DNameListElem
* BrowseDomains
;
518 domainname RegDomain
, fqdn
;
520 // get fqdn, zone from SCPrefs
521 dDNSPlatformGetConfig(&fqdn
, &RegDomain
, &BrowseDomains
);
523 // YO if (!fqdn.c[0] && !RegDomain.c[0]) ReadDDNSSettingsFromConfFile(m, CONFIG_FILE, &fqdn, &RegDomain);
525 if (!SameDomainName(&RegDomain
, &dDNSRegDomain
))
527 if (dDNSRegDomain
.c
[0])
529 RemoveDefRegDomain(&dDNSRegDomain
);
530 SetSCPrefsBrowseDomain(m
, &dDNSRegDomain
, mDNSfalse
); // if we were automatically browsing in our registration domain, stop
533 AssignDomainName(&dDNSRegDomain
, &RegDomain
);
535 if (dDNSRegDomain
.c
[0])
537 dDNSPlatformSetSecretForDomain(m
, &dDNSRegDomain
);
538 AddDefRegDomain(&dDNSRegDomain
);
539 SetSCPrefsBrowseDomain(m
, &dDNSRegDomain
, mDNStrue
);
543 // Add new browse domains to internal list
547 SetSCPrefsBrowseDomains( m
, BrowseDomains
, mDNStrue
);
550 // Remove old browse domains from internal list
552 if ( dDNSBrowseDomains
)
554 SetSCPrefsBrowseDomains( m
, dDNSBrowseDomains
, mDNSfalse
);
555 mDNS_FreeDNameList( dDNSBrowseDomains
);
558 // Replace the old browse domains array with the new array
560 dDNSBrowseDomains
= BrowseDomains
;
563 if (!SameDomainName(&fqdn
, &dDNSHostname
))
565 if (dDNSHostname
.c
[0]) mDNS_RemoveDynDNSHostName(m
, &dDNSHostname
);
566 AssignDomainName(&dDNSHostname
, &fqdn
);
567 if (dDNSHostname
.c
[0])
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);
576 // YO SCDynamicStoreRef store = SCDynamicStoreCreate(mDNSNULL, CFSTR("mDNSResponder:dDNSConfigChanged"), mDNSNULL, mDNSNULL);
577 // YO if (!store) return;
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);
584 // handle any changes to search domains and DNS server addresses
586 if ( dDNSPlatformRegisterSplitDNS(m
) != mStatus_NoError
)
587 if (dict
) RegisterNameServers( m
); // fall back to non-split DNS aware configuration on failure
589 if ( dDNSRegisterSearchDomains
== mDNStrue
)
590 dDNS_RegisterSearchDomains( m
); // note that we register name servers *before* search domains
592 // if (dict) CFRelease(dict);
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);
601 // YO { mDNS_SetPrimaryInterfaceInfo(m, mDNSNULL, mDNSNULL); return; } // lost v4
603 // handle router changes
606 // YO r.type = mDNSAddrType_IPv4;
607 // YO r.ip.v4.NotAnInteger = 0;
608 // YO CFStringRef router = CFDictionaryGetValue(dict, kSCPropNetIPv4Router);
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);
616 // handle router and primary interface changes
618 ip
.type
= r
.type
= mDNSAddrType_IPv4
;
619 ip
.ip
.v4
.NotAnInteger
= r
.ip
.v4
.NotAnInteger
= 0;
621 if ( dDNSPlatformGetPrimaryInterface( m
, &ip
, &r
) == mStatus_NoError
)
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
);
629 return mStatus_NoError
;
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)
643 mStatus
dDNS_InitDNSConfig(mDNS
*const m
)
646 static AuthRecord LocalRegPTR
;
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
);
651 // provide .local automatically
652 SetSCPrefsBrowseDomain(m
, &localdomain
, mDNStrue
);
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
);
663 LogMsg("ERROR: dDNS_InitDNSConfig - mDNS_Register returned error %d", err
);
666 return mStatus_NoError
;
670 dDNS_FreeIPAddrList(IPAddrListElem
* list
)
672 IPAddrListElem
* fptr
;
678 mDNSPlatformMemFree(fptr
);