]> git.saurik.com Git - apple/mdnsresponder.git/commitdiff
mDNSResponder-25.tar.gz mac-os-x-1024 v25
authorApple <opensource@apple.com>
Wed, 15 Jan 2003 01:12:03 +0000 (01:12 +0000)
committerApple <opensource@apple.com>
Wed, 15 Jan 2003 01:12:03 +0000 (01:12 +0000)
CFSocket.c
daemon.c
mDNSCore/mDNS.c
mDNSCore/mDNSClientAPI.h

index 12b463a42d687bbe1aff28c008c5eac45ca0c980..2fcd97cc069532581050affacb0d4fdadbccf8e7 100644 (file)
@@ -38,6 +38,8 @@
 // to zero will cause CFSocket.c to not set the Advertise flag in its mDNS_RegisterInterface calls.
 int mDNS_AdvertiseLocalAddresses = 1;
 
+void (*NotifyClientNetworkChanged)(void);
+
 #include "mDNSClientAPI.h"           // Defines the interface provided to the client layer above
 #include "mDNSPlatformFunctions.h"   // Defines the interface to the supporting layer below
 #include "mDNSPlatformEnvironment.h" // Defines the specific types needed to run mDNS on this platform
@@ -664,8 +666,10 @@ mDNSlocal void NetworkChanged(SCDynamicStoreRef store, CFArrayRef changedKeys, v
        debugf("***   Network Configuration Change   ***");
        (void)store;            // Parameter not used
        (void)changedKeys;      // Parameter not used
+       
        ClearInterfaceList(m);
        SetupInterfaceList(m);
+       if (NotifyClientNetworkChanged) NotifyClientNetworkChanged();
        mDNSCoreSleep(m, false);
        }
 
@@ -677,7 +681,7 @@ mDNSlocal mStatus WatchForNetworkChanges(mDNS *const m)
        CFStringRef           key1     = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL, kSCDynamicStoreDomainState, kSCEntNetIPv4);
        CFStringRef           key2     = SCDynamicStoreKeyCreateComputerName(NULL);
        CFStringRef           key3     = SCDynamicStoreKeyCreateHostNames(NULL);
-       CFStringRef           pattern  = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL, kSCDynamicStoreDomainState, kSCCompAnyRegex, kSCEntNetIPv4);
+       CFStringRef           pattern  = SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL, kSCDynamicStoreDomainState, kSCCompAnyRegex, kSCEntNetIPv4);
        CFMutableArrayRef     keys     = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
        CFMutableArrayRef     patterns = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
 
@@ -809,7 +813,6 @@ mDNSexport void mDNSPlatformClose(mDNS *const m)
                }
        }
 
-// To Do: Find out how to implement a proper modular time function in CF
 mDNSexport void mDNSPlatformScheduleTask(const mDNS *const m, SInt32 NextTaskTime)
        {
        if (m->p->CFTimer)
index c012ab16bd2cb3d15e0a69efec47a981bd769b06..67365aef218597ebb0dc75f86cdc365c664a34d7 100644 (file)
--- a/daemon.c
+++ b/daemon.c
@@ -119,6 +119,8 @@ struct DNSServiceRegistration_struct
        DNSServiceRegistration *next;
        mach_port_t ClientMachPort;
        mDNSBool autoname;
+       mDNSBool autorename;
+       domainlabel name;
        ServiceRecordSet s;
        // Don't add any fields after ServiceRecordSet.
        // This is where the implicit extra space goes if we allocate an oversized ServiceRecordSet object
@@ -264,6 +266,7 @@ mDNSlocal void AbortClient(mach_port_t ClientMachPort)
                {
                DNSServiceRegistration *x = *r;
                *r = (*r)->next;
+               x->autorename = mDNSfalse;
                mDNS_DeregisterService(&mDNSStorage, &x->s);
                // Note that we don't do the "free(x);" here -- wait for the mStatus_MemFree message
                return;
@@ -598,7 +601,7 @@ mDNSlocal void RegCallback(mDNS *const m, ServiceRecordSet *const sr, mStatus re
                // Note: By the time we get the mStatus_NameConflict message, the service is already deregistered
                // and the memory is free, so we don't have to wait for an mStatus_MemFree message as well.
                if (x->autoname)
-                       mDNS_RenameAndReregisterService(m, sr);
+                       mDNS_RenameAndReregisterService(m, sr, mDNSNULL);
                else
                        {
                        kern_return_t status;
@@ -613,15 +616,25 @@ mDNSlocal void RegCallback(mDNS *const m, ServiceRecordSet *const sr, mStatus re
 
        if (result == mStatus_MemFree)
                {
-               DNSServiceRegistration **r = &DNSServiceRegistrationList;
-               while (*r && *r != x) r = &(*r)->next;
-               if (*r)
+               if (x->autorename)
                        {
-                       debugf("RegCallback: %##s Still in DNSServiceRegistration list; removing now", sr->RR_SRV.name.c);
-                       *r = (*r)->next;
+                       debugf("RegCallback renaming %#s to %#s", &x->name, &mDNSStorage.nicelabel);
+                       x->autorename = mDNSfalse;
+                       x->name = mDNSStorage.nicelabel;
+                       mDNS_RenameAndReregisterService(m, &x->s, &x->name);
+                       }
+               else
+                       {
+                       DNSServiceRegistration **r = &DNSServiceRegistrationList;
+                       while (*r && *r != x) r = &(*r)->next;
+                       if (*r)
+                               {
+                               debugf("RegCallback: %##s Still in DNSServiceRegistration list; removing now", sr->RR_SRV.name.c);
+                               *r = (*r)->next;
+                               }
+                       debugf("RegCallback: Freeing DNSServiceRegistration %##s %d", sr->RR_SRV.name.c, x->ClientMachPort);
+                       FreeDNSServiceRegistration(x);
                        }
-               debugf("RegCallback: Freeing DNSServiceRegistration %##s %d", sr->RR_SRV.name.c, x->ClientMachPort);
-               FreeDNSServiceRegistration(x);
                }
        }
 
@@ -651,7 +664,6 @@ mDNSexport kern_return_t provide_DNSServiceRegistrationCreate_rpc(mach_port_t un
        DNSCString name, DNSCString regtype, DNSCString domain, int notAnIntPort, DNSCString txtRecord)
        {
        mStatus err;
-       domainlabel n;
        domainname t, d;
        mDNSIPPort port;
        unsigned char txtinfo[1024] = "";
@@ -693,17 +705,18 @@ mDNSexport kern_return_t provide_DNSServiceRegistrationCreate_rpc(mach_port_t un
        DNSServiceRegistrationList = x;
 
        x->autoname = (*name == 0);
-       if (x->autoname) n = mDNSStorage.nicelabel;
-       else ConvertCStringToDomainLabel(name, &n);
+       x->autorename = mDNSfalse;
+       if (x->autoname) x->name = mDNSStorage.nicelabel;
+       else ConvertCStringToDomainLabel(name, &x->name);
        ConvertCStringToDomainName(regtype, &t);
        ConvertCStringToDomainName(*domain ? domain : "local.", &d);
        port.NotAnInteger = notAnIntPort;
 
        debugf("Client %d: provide_DNSServiceRegistrationCreate_rpc", client);
        debugf("Client %d: Register Service: %#s.%##s%##s %d %.30s",
-               client, &n, &t, &d, (int)port.b[0] << 8 | port.b[1], txtRecord);
-       CheckForDuplicateRegistrations(x, &n, &t, &d);
-       err = mDNS_RegisterService(&mDNSStorage, &x->s, &n, &t, &d, mDNSNULL, port, txtinfo, data_len, RegCallback, x);
+               client, &x->name, &t, &d, (int)port.b[0] << 8 | port.b[1], txtRecord);
+       CheckForDuplicateRegistrations(x, &x->name, &t, &d);
+       err = mDNS_RegisterService(&mDNSStorage, &x->s, &x->name, &t, &d, mDNSNULL, port, txtinfo, data_len, RegCallback, x);
 
        if (err) AbortClient(client);
        else EnableDeathNotificationForClient(client);
@@ -714,6 +727,18 @@ mDNSexport kern_return_t provide_DNSServiceRegistrationCreate_rpc(mach_port_t un
        return(err);
        }
 
+void NetworkChanged(void)
+       {
+       DNSServiceRegistration *r;
+       for (r = DNSServiceRegistrationList; r; r=r->next)
+               if (r->autoname && !SameDomainLabel(r->name.c, mDNSStorage.nicelabel.c))
+                       {
+                       debugf("NetworkChanged renaming %#s to %#s", &r->name, &mDNSStorage.nicelabel);
+                       r->autorename = mDNStrue;
+                       mDNS_DeregisterService(&mDNSStorage, &r->s);
+                       }
+       }
+
 mDNSexport kern_return_t provide_DNSServiceRegistrationAddRecord_rpc(mach_port_t unusedserver, mach_port_t client,
        int type, const char *data, mach_msg_type_number_t data_len, uint32_t ttl, natural_t *reference)
        {
@@ -1010,6 +1035,7 @@ mDNSlocal void ExitCallback(CFMachPortRef port, void *msg, CFIndex size, void *i
 
 mDNSlocal kern_return_t start(const char *bundleName, const char *bundleDir)
        {
+       extern void (*NotifyClientNetworkChanged)(void);        // Temp fix for catching name changes
        mStatus            err;
        CFRunLoopTimerContext myCFRunLoopTimerContext = { 0, &mDNSStorage, NULL, NULL, NULL };
        CFMachPortRef      d_port = CFMachPortCreate(NULL, ClientDeathCallback, NULL, NULL);
@@ -1056,6 +1082,8 @@ mDNSlocal kern_return_t start(const char *bundleName, const char *bundleDir)
        CFRelease(e_rls);
        if (debug_mode) printf("Service registered with Mach Port %d\n", m_port);
 
+       NotifyClientNetworkChanged = NetworkChanged;
+
        return(err);
        }
 
index fc678e0b8d100fbcb0936172f36bd134249ba98b..e216582b1fa20bc21255cddf73d80a05c878320d 100755 (executable)
@@ -166,7 +166,7 @@ mDNSexport mDNSu32 DomainNameLength(const domainname *const name)
        return((mDNSu32)(src - name->c + 1));
        }
 
-mDNSlocal mDNSBool SameDomainLabel(const mDNSu8 *a, const mDNSu8 *b)
+mDNSexport mDNSBool SameDomainLabel(const mDNSu8 *a, const mDNSu8 *b)
        {
        int i;
        const int len = *a++;
@@ -569,13 +569,15 @@ mDNSlocal void IncrementLabelSuffix(domainlabel *name, mDNSBool RichText)
        ((RR)->InterfaceAddr.NotAnInteger == 0 || (RR)->InterfaceAddr.NotAnInteger == (I).NotAnInteger))
 
 #define DefaultProbeCountForTypeUnique ((mDNSu8)3)
+#define DefaultProbeCountForRecordType(X)      ((X) == kDNSRecordTypeUnique ? DefaultProbeCountForTypeUnique : (mDNSu8)0)
 
 #define DefaultAnnounceCountForTypeShared ((mDNSu8)10)
 #define DefaultAnnounceCountForTypeUnique ((mDNSu8)2)
 
-#define DefaultAnnounceCountForRecordType(X)   ((X) == kDNSRecordTypeShared   ? DefaultAnnounceCountForTypeShared : \
-                                                                                               (X) == kDNSRecordTypeUnique   ? DefaultAnnounceCountForTypeUnique : \
-                                                                                               (X) == kDNSRecordTypeVerified ? DefaultAnnounceCountForTypeUnique : (mDNSu8)0)
+#define DefaultAnnounceCountForRecordType(X)   ((X) == kDNSRecordTypeShared      ? DefaultAnnounceCountForTypeShared : \
+                                                                                               (X) == kDNSRecordTypeUnique      ? DefaultAnnounceCountForTypeUnique : \
+                                                                                               (X) == kDNSRecordTypeVerified    ? DefaultAnnounceCountForTypeUnique : \
+                                                                                               (X) == kDNSRecordTypeKnownUnique ? DefaultAnnounceCountForTypeUnique : (mDNSu8)0)
 
 #define DefaultSendIntervalForRecordType(X)    ((X) == kDNSRecordTypeShared   ? mDNSPlatformOneSecond   : \
                                                                                                (X) == kDNSRecordTypeUnique   ? mDNSPlatformOneSecond/4 : \
@@ -713,7 +715,11 @@ mDNSlocal void SetTargetToHostName(const mDNS *const m, ResourceRecord *const rr
        
        // If we're in the middle of probing this record, we need to start again,
        // because changing its rdata may change the outcome of the tie-breaker.
-       if (rr->RecordType == kDNSRecordTypeUnique) rr->ProbeCount = DefaultProbeCountForTypeUnique;
+       rr->ProbeCount       = DefaultProbeCountForRecordType(rr->RecordType);
+       rr->AnnounceCount    = DefaultAnnounceCountForRecordType(rr->RecordType);
+       rr->NextSendTime     = mDNSPlatformTimeNow();
+       rr->NextSendInterval = DefaultSendIntervalForRecordType(rr->RecordType);
+       if (rr->RecordType == kDNSRecordTypeUnique && m->SuppressProbes) rr->NextSendTime = m->SuppressProbes;
        }
 
 mDNSlocal void UpdateHostNameTargets(const mDNS *const m)
@@ -766,7 +772,7 @@ mDNSlocal mStatus mDNS_Register_internal(mDNS *const m, ResourceRecord *const rr
 
        // Field Group 2: Transient state for Authoritative Records
        rr->Acknowledged      = mDNSfalse;
-       rr->ProbeCount        = (rr->RecordType == kDNSRecordTypeUnique) ? DefaultProbeCountForTypeUnique : (mDNSu8)0;
+       rr->ProbeCount        = DefaultProbeCountForRecordType(rr->RecordType);
        rr->AnnounceCount     = DefaultAnnounceCountForRecordType(rr->RecordType);
        rr->IncludeInProbe    = mDNSfalse;
        rr->SendPriority      = 0;
@@ -823,7 +829,7 @@ mDNSlocal void mDNS_Deregister_internal(mDNS *const m, ResourceRecord *const rr,
        mDNSu8 RecordType = rr->RecordType;
        // If this is a shared record and we've announced it at least once,
        // we need to retract that announcement before we delete the record
-       if (RecordType == kDNSRecordTypeShared && rr->AnnounceCount < DefaultAnnounceCountForTypeShared)
+       if (RecordType == kDNSRecordTypeShared && rr->AnnounceCount <= DefaultAnnounceCountForTypeShared)
                {
                debugf("mDNS_Deregister_internal: Sending deregister for %##s (%s)", rr->name.c, DNSTypeName(rr->rrtype));
                rr->RecordType     = kDNSRecordTypeDeregistering;
@@ -864,9 +870,10 @@ mDNSlocal void mDNS_Deregister_internal(mDNS *const m, ResourceRecord *const rr,
                // If we have an update queued up which never executed, give the client a chance to free that memory
                if (rr->NewRData)
                        {
-                       RData *n = rr->NewRData;
+                       RData *OldRData = rr->rdata;
+                       rr->rdata = rr->NewRData;       // Update our rdata
                        rr->NewRData = mDNSNULL;        // Clear the NewRData pointer ...
-                       if (rr->UpdateCallback) rr->UpdateCallback(m, rr, n); // ...and let the client free this memory, if necessary
+                       if (rr->UpdateCallback) rr->UpdateCallback(m, rr, OldRData);    // ... and let the client know
                        }
                
                if (RecordType == kDNSRecordTypeShared && rr->Callback)
@@ -1460,7 +1467,7 @@ mDNSlocal void DiscardDeregistrations(mDNS *const m, mDNSs32 timenow)
                if (rr->RecordType == kDNSRecordTypeDeregistering)
                        {
                        rr->RecordType    = kDNSRecordTypeShared;
-                       rr->AnnounceCount = DefaultAnnounceCountForTypeShared;
+                       rr->AnnounceCount = DefaultAnnounceCountForTypeShared+1;
                        mDNS_Deregister_internal(m, rr, timenow, mDNS_Dereg_normal);
                        }
                }
@@ -1480,6 +1487,7 @@ mDNSlocal mDNSu8 *BuildResponse(mDNS *const m,
        int numDereg    = 0;
        int numAnnounce = 0;
        int numAnswer   = 0;
+       mDNSs32 minExistingAnnounceInterval = 0;
 
        if (m->CurrentRecord) debugf("BuildResponse ERROR m->CurrentRecord already set");
        m->CurrentRecord = m->ResourceRecords;
@@ -1534,7 +1542,7 @@ mDNSlocal mDNSu8 *BuildResponse(mDNS *const m,
                                        numDereg++;
                                        responseptr = newptr;
                                        rr->RecordType    = kDNSRecordTypeShared;
-                                       rr->AnnounceCount = DefaultAnnounceCountForTypeShared;
+                                       rr->AnnounceCount = DefaultAnnounceCountForTypeShared+1;
                                        mDNS_Deregister_internal(m, rr, timenow, mDNS_Dereg_normal);
                                        }
                                }
@@ -1560,6 +1568,8 @@ mDNSlocal mDNSu8 *BuildResponse(mDNS *const m,
                                        if (response->h.numAnswers == 0) debugf("BuildResponse announcements failed");
                                        if (newptr || response->h.numAnswers == 0)
                                                {
+                                               if (minExistingAnnounceInterval > rr->NextSendInterval)
+                                                       minExistingAnnounceInterval = rr->NextSendInterval;
                                                rr->SendPriority      = 0;
                                                rr->Requester         = zeroIPAddr;
                                                rr->AnnounceCount--;
@@ -1571,6 +1581,38 @@ mDNSlocal mDNSu8 *BuildResponse(mDNS *const m,
                                        }
                        }
        
+               // 2a. Look for additional announcements that are worth accelerating
+               // They must be (a) at least half-way to their next announcement and
+               // (b) at an interval equal or less than any of the ones we've already put in
+               for (rr = m->ResourceRecords; rr; rr=rr->next)
+                       {
+                       if (rr->InterfaceAddr.NotAnInteger == InterfaceAddr.NotAnInteger &&
+                               rr->AnnounceCount && ResourceRecordIsValidAnswer(rr) &&
+                               timenow - (rr->LastSendTime + rr->NextSendInterval/4) >= 0 &&
+                               rr->NextSendInterval <= minExistingAnnounceInterval)
+                                       {
+                                       newptr = putResourceRecord(response, responseptr, &response->h.numAnswers, rr, m, timenow);
+                                       if (newptr)
+                                               {
+                                               numAnnounce++;
+                                               responseptr = newptr;
+                                               }
+                                       // If we were able to put the record, then update the state variables
+                                       // If we were unable to put the record because it is too large to fit, even though
+                                       // there are no other answers in the packet, then pretend we succeeded anyway,
+                                       // or we'll end up in an infinite loop trying to send a record that will never fit
+                                       if (response->h.numAnswers == 0) debugf("BuildResponse announcements failed");
+                                       if (newptr || response->h.numAnswers == 0)
+                                               {
+                                               rr->SendPriority      = 0;
+                                               rr->Requester         = zeroIPAddr;
+                                               rr->AnnounceCount--;
+                                               rr->NextSendTime      = timenow + rr->NextSendInterval;
+                                               rr->NextSendInterval *= 2;
+                                               }
+                                       }
+                       }
+       
                // 3. Look for answers we need to send
                for (rr = m->ResourceRecords; rr; rr=rr->next)
                        if (rr->InterfaceAddr.NotAnInteger == InterfaceAddr.NotAnInteger &&
@@ -2356,7 +2398,7 @@ mDNSexport void mDNSCoreSleep(mDNS *const m, mDNSBool sleepstate)
                {
                // First mark all the records we need to deregister
                for (rr = m->ResourceRecords; rr; rr=rr->next)
-                       if (rr->RecordType == kDNSRecordTypeShared && rr->AnnounceCount < DefaultAnnounceCountForTypeShared)
+                       if (rr->RecordType == kDNSRecordTypeShared && rr->AnnounceCount <= DefaultAnnounceCountForTypeShared)
                                rr->rrremainingttl = 0;
                while (HaveResponses(m, timenow)) SendResponses(m, timenow);
                }
@@ -2367,10 +2409,10 @@ mDNSexport void mDNSCoreSleep(mDNS *const m, mDNSBool sleepstate)
                for (rr = m->ResourceRecords; rr; rr=rr->next)
                        {
                        if (rr->RecordType == kDNSRecordTypeVerified) rr->RecordType = kDNSRecordTypeUnique;
-                       rr->ProbeCount        = (rr->RecordType == kDNSRecordTypeUnique) ? DefaultProbeCountForTypeUnique : (mDNSu8)0;
+                       rr->ProbeCount        = DefaultProbeCountForRecordType(rr->RecordType);
                        rr->AnnounceCount     = DefaultAnnounceCountForRecordType(rr->RecordType);
-                       rr->NextSendInterval  = DefaultSendIntervalForRecordType(rr->RecordType);
                        rr->NextSendTime      = timenow;
+                       rr->NextSendInterval  = DefaultSendIntervalForRecordType(rr->RecordType);
                        }
                for (q = m->ActiveQuestions; q; q=q->next)              // Scan our list of questions
                        if (!q->DuplicateOf)
@@ -2888,7 +2930,7 @@ mDNSlocal void mDNSCoreReceiveResponse(mDNS *const m,
                                else
                                        {
                                        // else, the packet RR has different rdata -- check to see if this is a conflict
-                                       if (PacketRRConflict(m, rr, &pktrr))
+                                       if (pktrr.rroriginalttl > 0 && PacketRRConflict(m, rr, &pktrr))
                                                {
                                                if (rr->rrtype == kDNSType_SRV)
                                                        {
@@ -3715,7 +3757,7 @@ mDNSexport mStatus mDNS_RemoveRecordFromService(mDNS *const m, ServiceRecordSet
        return(mStatus_NoError);
        }
 
-mDNSexport mStatus mDNS_RenameAndReregisterService(mDNS *const m, ServiceRecordSet *const sr)
+mDNSexport mStatus mDNS_RenameAndReregisterService(mDNS *const m, ServiceRecordSet *const sr, const domainlabel *newname)
        {
        domainlabel name;
        domainname type, domain;
@@ -3724,11 +3766,15 @@ mDNSexport mStatus mDNS_RenameAndReregisterService(mDNS *const m, ServiceRecordS
        mStatus err;
 
        DeconstructServiceName(&sr->RR_SRV.name, &name, &type, &domain);
-       IncrementLabelSuffix(&name, mDNStrue);
-       debugf("Reregistering as %#s", name.c);
+       if (!newname)
+               {
+               IncrementLabelSuffix(&name, mDNStrue);
+               newname = &name;
+               }
+       debugf("Reregistering as %#s", newname->c);
        if (sr->RR_SRV.HostTarget == mDNSfalse && sr->Host.c[0]) host = &sr->Host;
        
-       err = mDNS_RegisterService(m, sr, &name, &type, &domain,
+       err = mDNS_RegisterService(m, sr, newname, &type, &domain,
                host, sr->RR_SRV.rdata->u.srv.port, sr->RR_TXT.rdata->u.txt.c, sr->RR_TXT.rdata->RDLength,
                sr->Callback, sr->Context);
 
@@ -3748,16 +3794,16 @@ mDNSexport mStatus mDNS_RenameAndReregisterService(mDNS *const m, ServiceRecordS
 mDNSexport void mDNS_DeregisterService(mDNS *const m, ServiceRecordSet *sr)
        {
        const mDNSs32 timenow = mDNS_Lock(m);
+       ExtraResourceRecord *e = sr->Extras;
 
        // We use mDNS_Dereg_repeat because, in the event of a collision, some or all of
        // these records could have already been automatically deregistered, and that's okay
        mDNS_Deregister_internal(m, &sr->RR_SRV, timenow, mDNS_Dereg_repeat);
        mDNS_Deregister_internal(m, &sr->RR_TXT, timenow, mDNS_Dereg_repeat);
-       while (sr->Extras)
+       while (e)
                {
-               ExtraResourceRecord *e = sr->Extras;
-               sr->Extras = sr->Extras->next;
                mDNS_Deregister_internal(m, &e->r, timenow, mDNS_Dereg_repeat);
+               e=e->next;
                }
 
        // Be sure to deregister the PTR last!
index 923e59f0cd8c3f9cffce18969a027f6ebcabebc2..c919500178883221242313c937f2a61eeefeeab0 100755 (executable)
@@ -477,7 +477,7 @@ extern mStatus mDNS_RegisterService  (mDNS *const m, ServiceRecordSet *sr,
                mDNSServiceCallback Callback, void *Context);
 extern mStatus mDNS_AddRecordToService(mDNS *const m, ServiceRecordSet *sr, ExtraResourceRecord *extra, RData *rdata, mDNSu32 ttl);
 extern mStatus mDNS_RemoveRecordFromService(mDNS *const m, ServiceRecordSet *sr, ExtraResourceRecord *extra);
-extern mStatus mDNS_RenameAndReregisterService(mDNS *const m, ServiceRecordSet *const sr);
+extern mStatus mDNS_RenameAndReregisterService(mDNS *const m, ServiceRecordSet *const sr, const domainlabel *newname);
 extern void    mDNS_DeregisterService(mDNS *const m, ServiceRecordSet *sr);
 
 extern mStatus mDNS_StartBrowse(mDNS *const m, DNSQuestion *const question,
@@ -511,6 +511,7 @@ extern mStatus mDNS_AdvertiseDomains(mDNS *const m, ResourceRecord *rr, mDNSu8 D
 // work with DNS's native length-prefixed strings. For convenience in C, the following utility functions
 // are provided for converting between C's null-terminated strings and DNS's length-prefixed strings.
 
+extern mDNSBool SameDomainLabel(const mDNSu8 *a, const mDNSu8 *b);
 extern mDNSBool SameDomainName(const domainname *const d1, const domainname *const d2);
 
 extern mDNSu32 DomainNameLength(const domainname *const name);