<rdar://problem/7299177> DNS-SD sometimes delivers duplicate browse add events during...
authormparthasarathy@apple.com <mparthasarathy@apple.com@214c2c4a-bf3b-4dcf-9390-e4dd3010487d>
Tue, 13 Oct 2009 19:54:00 +0000 (19:54 +0000)
committermparthasarathy@apple.com <mparthasarathy@apple.com@214c2c4a-bf3b-4dcf-9390-e4dd3010487d>
Tue, 13 Oct 2009 19:54:00 +0000 (19:54 +0000)
The Platform layer registers interface indices instead of Interface pointers so that registering multiple times with the Core does not cause duplicate events

git-svn-id: http://svn.macosforge.org/repository/mDNSResponder/trunk@6738 214c2c4a-bf3b-4dcf-9390-e4dd3010487d

mDNSCore/DNSCommon.c
mDNSCore/mDNS.c
mDNSCore/mDNSEmbeddedAPI.h
mDNSMacOSX/daemon.c
mDNSMacOSX/mDNSMacOSX.c
mDNSMacOSX/mDNSMacOSX.h
mDNSShared/uds_daemon.c

index e80bead..76508ce 100644 (file)
@@ -47,8 +47,8 @@ mDNSexport const mDNSEthAddr     onesEthAddr       = { { 255, 255, 255, 255, 255
 mDNSexport const OwnerOptData    zeroOwner         = { 0, 0, { { 0 } }, { { 0 } }, { { 0 } } };
 
 mDNSexport const mDNSInterfaceID mDNSInterface_Any       = 0;
-mDNSexport const mDNSInterfaceID mDNSInterface_LocalOnly = (mDNSInterfaceID)1;
-mDNSexport const mDNSInterfaceID mDNSInterface_Unicast   = (mDNSInterfaceID)2;
+mDNSexport const mDNSInterfaceID mDNSInterface_LocalOnly = (mDNSInterfaceID)-1;
+mDNSexport const mDNSInterfaceID mDNSInterface_Unicast   = (mDNSInterfaceID)-2;
 
 // Note: Microsoft's proposed "Link Local Multicast Name Resolution Protocol" (LLMNR) is essentially a limited version of
 // Multicast DNS, using the same packet formats, naming syntax, and record types as Multicast DNS, but on a different UDP
index 5af01d6..cca6b6d 100755 (executable)
@@ -167,10 +167,10 @@ mDNSlocal NetworkInterfaceInfo *FirstInterfaceForID(mDNS *const m, const mDNSInt
        return(intf);
        }
 
-mDNSlocal char *InterfaceNameForID(mDNS *const m, const mDNSInterfaceID InterfaceID)
+mDNSexport char *InterfaceNameForID(mDNS *const m, const mDNSInterfaceID InterfaceID)
        {
        NetworkInterfaceInfo *intf = FirstInterfaceForID(m, InterfaceID);
-       return(intf ? intf->ifname : "<NULL InterfaceID>");
+       return(intf ? intf->ifname : mDNSNULL);
        }
 
 // For a single given DNSQuestion, deliver an add/remove result for the single given AuthRecord
@@ -2090,7 +2090,9 @@ mDNSlocal void SendQueries(mDNS *const m)
                                        {
                                        if (rr->AddressProxy.type == mDNSAddrType_IPv4)
                                                {
-                                               LogSPS("SendQueries ARP Probe %d %s %s", rr->ProbeCount, InterfaceNameForID(m, rr->resrec.InterfaceID), ARDisplayString(m,rr));
+                                               char *ifname = InterfaceNameForID(m, rr->resrec.InterfaceID);
+                                               if (!ifname) ifname = "<NULL InterfaceID>";
+                                               LogSPS("SendQueries ARP Probe %d %s %s", rr->ProbeCount, ifname, ARDisplayString(m,rr));
                                                SendARP(m, 1, rr, zerov4Addr.b, zeroEthAddr.b, rr->AddressProxy.ip.v4.b, rr->WakeUp.IMAC.b);
                                                }
                                        else if (rr->AddressProxy.type == mDNSAddrType_IPv6)
@@ -5410,8 +5412,9 @@ mDNSlocal void SPSRecordCallback(mDNS *const m, AuthRecord *const ar, mStatus re
 
        if (result == mStatus_NameConflict)
                {
-               LogMsg("Received Conflicting mDNS -- waking %s %.6a %s",
-                       InterfaceNameForID(m, ar->resrec.InterfaceID), &ar->WakeUp.HMAC, ARDisplayString(m, ar));
+               char *ifname = InterfaceNameForID(m, ar->resrec.InterfaceID);
+               if (!ifname) ifname = "<NULL InterfaceID>";
+               LogMsg("Received Conflicting mDNS -- waking %s %.6a %s", ifname, &ar->WakeUp.HMAC, ARDisplayString(m, ar));
                SendWakeup(m, ar->resrec.InterfaceID, &ar->WakeUp.IMAC, &ar->WakeUp.password);
                }
        else if (result == mStatus_MemFree)
@@ -7854,6 +7857,8 @@ mDNSexport void mDNSCoreReceiveRawPacket(mDNS *const m, const mDNSu8 *const p, c
                        for (rr = m->ResourceRecords; rr; rr=rr->next)
                                if (rr->resrec.InterfaceID == InterfaceID && rr->AddressProxy.type == mDNSAddrType_IPv4 && mDNSSameIPv4Address(rr->AddressProxy.ip.v4, arp->tpa))
                                        {
+                                       char *ifname = InterfaceNameForID(m, InterfaceID);
+                                       if (!ifname) ifname = "<NULL InterfaceID>";
                                        static const char msg1[] = "ARP Req from owner -- re-probing";
                                        static const char msg2[] = "Ignoring  ARP Request from      ";
                                        static const char msg3[] = "Creating Local ARP Cache entry  ";
@@ -7862,7 +7867,7 @@ mDNSexport void mDNSCoreReceiveRawPacket(mDNS *const m, const mDNSu8 *const p, c
                                                                                        (rr->AnnounceCount == InitialAnnounceCount)     ? msg2 :
                                                                                        mDNSSameEthAddress(&arp->sha, &intf->MAC)       ? msg3 : msg4;
                                        LogSPS("%-7s %s %.6a %.4a for %.4a -- H-MAC %.6a I-MAC %.6a %s",
-                                               InterfaceNameForID(m, InterfaceID), msg, &arp->sha, &arp->spa, &arp->tpa, &rr->WakeUp.HMAC, &rr->WakeUp.IMAC, ARDisplayString(m, rr));
+                                               ifname, msg, &arp->sha, &arp->spa, &arp->tpa, &rr->WakeUp.HMAC, &rr->WakeUp.IMAC, ARDisplayString(m, rr));
                                        if      (msg == msg1) RestartARPProbing(m, rr);
                                        else if (msg == msg3) mDNSPlatformSetLocalARP(&arp->tpa, &rr->WakeUp.IMAC, InterfaceID);
                                        else if (msg == msg4) SendARP(m, 2, rr, arp->tpa.b, arp->sha.b, arp->spa.b, arp->sha.b);
@@ -7884,16 +7889,19 @@ mDNSexport void mDNSCoreReceiveRawPacket(mDNS *const m, const mDNSu8 *const p, c
                                for (rr = m->ResourceRecords; rr; rr=rr->next)
                                        if (rr->resrec.InterfaceID == InterfaceID && rr->AddressProxy.type == mDNSAddrType_IPv4 && mDNSSameIPv4Address(rr->AddressProxy.ip.v4, arp->spa))
                                                {
+                                               char *ifname = InterfaceNameForID(m, InterfaceID);
+                                               if (!ifname) ifname = "<NULL InterfaceID>";
+
                                                RestartARPProbing(m, rr);
                                                if (mDNSSameEthAddress(&arp->sha, &rr->WakeUp.IMAC))
                                                        LogSPS("%-7s ARP %s from owner %.6a %.4a for %-15.4a -- re-starting probing for %s",
-                                                               InterfaceNameForID(m, InterfaceID),
+                                                               ifname,
                                                                mDNSSameIPv4Address(arp->spa, arp->tpa) ? "Announcement" : mDNSSameOpaque16(arp->op, ARP_op_request) ? "Request     " : "Response    ",
                                                                &arp->sha, &arp->spa, &arp->tpa, ARDisplayString(m, rr));
                                                else
                                                        {
                                                        LogMsg("%-7s Conflicting ARP from %.6a %.4a for %.4a -- waking H-MAC %.6a I-MAC %.6a %s",
-                                                               InterfaceNameForID(m, InterfaceID), &arp->sha, &arp->spa, &arp->tpa, &rr->WakeUp.HMAC, &rr->WakeUp.IMAC, ARDisplayString(m, rr));
+                                                               ifname, &arp->sha, &arp->spa, &arp->tpa, &rr->WakeUp.HMAC, &rr->WakeUp.IMAC, ARDisplayString(m, rr));
                                                        SendWakeup(m, rr->resrec.InterfaceID, &rr->WakeUp.IMAC, &rr->WakeUp.password);
                                                        }
                                                }
@@ -8006,16 +8014,18 @@ mDNSexport void mDNSCoreReceiveRawPacket(mDNS *const m, const mDNSu8 *const p, c
                                                                SameDomainLabel(ThirdLabel(r2->resrec.name)->c, tp))
                                                                break;
                                                if (!r2 && mDNSSameIPPort(port, IPSECPort)) r2 = rr;    // So that we wake for BTMM IPSEC packets, even without a matching SRV record
+                                               char *ifname = InterfaceNameForID(m, rr->resrec.InterfaceID);
+                                               if (!ifname) ifname = "<NULL InterfaceID>";
                                                if (r2)
                                                        {
                                                        rr->AnnounceCount = 0;
                                                        LogMsg("Waking host at %s %.4a H-MAC %.6a I-MAC %.6a for %s",
-                                                               InterfaceNameForID(m, rr->resrec.InterfaceID), &v4->dst, &rr->WakeUp.HMAC, &rr->WakeUp.IMAC, ARDisplayString(m, r2));
+                                                               ifname, &v4->dst, &rr->WakeUp.HMAC, &rr->WakeUp.IMAC, ARDisplayString(m, r2));
                                                        SendWakeup(m, rr->resrec.InterfaceID, &rr->WakeUp.IMAC, &rr->WakeUp.password);
                                                        }
                                                else
                                                        LogSPS("Sleeping host at %s %.4a %.6a has no service on %#s %d",
-                                                               InterfaceNameForID(m, rr->resrec.InterfaceID), &v4->dst, &rr->WakeUp.HMAC, tp, mDNSVal16(port));
+                                                               ifname, &v4->dst, &rr->WakeUp.HMAC, tp, mDNSVal16(port));
                                                }
                                mDNS_Unlock(m);
                                }
index f381de9..4d9a212 100755 (executable)
@@ -2512,6 +2512,7 @@ extern void AddNewClientTunnel(mDNS *const m, DNSQuestion *const q);
 extern void SetupLocalAutoTunnelInterface_internal(mDNS *const m);
 extern void UpdateAutoTunnelDomainStatuses(const mDNS *const m);
 extern mStatus ActivateLocalProxy(mDNS *const m, char *ifname);
+extern char *InterfaceNameForID(mDNS *const m, const mDNSInterfaceID InterfaceID);
 #endif
 
 // ***************************************************************************
index e4881cc..758578a 100644 (file)
@@ -822,7 +822,7 @@ mDNSlocal void FoundInstanceInfo(mDNS *const m, ServiceInfoQuery *query)
        {
        kern_return_t status;
        DNSServiceResolver *x = (DNSServiceResolver *)query->ServiceInfoQueryContext;
-       NetworkInterfaceInfoOSX *ifx = (NetworkInterfaceInfoOSX *)query->info->InterfaceID;
+       NetworkInterfaceInfoOSX *ifx = IfindexToInterfaceInfoOSX(m, query->info->InterfaceID);
        if (query->info->InterfaceID == mDNSInterface_LocalOnly) ifx = mDNSNULL;
        struct sockaddr_storage interface;
        struct sockaddr_storage address;
index d8e47fc..831344e 100644 (file)
@@ -245,40 +245,55 @@ mDNSlocal int myIfIndexToName(u_short ifindex, char *name)
        return -1;
        }
 
+mDNSexport NetworkInterfaceInfoOSX *IfindexToInterfaceInfoOSX(const mDNS *const m, mDNSInterfaceID ifindex)
+{
+       mDNSu32 scope_id = (mDNSu32)(uintptr_t)ifindex;
+       NetworkInterfaceInfoOSX *i;
+
+       // Don't get tricked by inactive interfaces
+       for (i = m->p->InterfaceList; i; i = i->next)
+               if (i->Registered && i->scope_id == scope_id) return(i);
+
+       return mDNSNULL;
+}
+
 mDNSexport mDNSInterfaceID mDNSPlatformInterfaceIDfromInterfaceIndex(mDNS *const m, mDNSu32 ifindex)
        {
-       NetworkInterfaceInfoOSX *i;
        if (ifindex == kDNSServiceInterfaceIndexLocalOnly) return(mDNSInterface_LocalOnly);
        if (ifindex == kDNSServiceInterfaceIndexAny      ) return(mDNSNULL);
 
-       // Don't get tricked by inactive interfaces with no InterfaceID set
-       for (i = m->p->InterfaceList; i; i = i->next)
-               if (i->ifinfo.InterfaceID && i->scope_id == ifindex) return(i->ifinfo.InterfaceID);
-
-       // Not found. Make sure our interface list is up to date, then try again.
-       LogInfo("InterfaceID for interface index %d not found; Updating interface list", ifindex);
-       mDNSMacOSXNetworkChanged(m);
-       for (i = m->p->InterfaceList; i; i = i->next)
-               if (i->ifinfo.InterfaceID && i->scope_id == ifindex) return(i->ifinfo.InterfaceID);
+       NetworkInterfaceInfoOSX* ifi = IfindexToInterfaceInfoOSX(m, (mDNSInterfaceID)(uintptr_t)ifindex);
+       if (!ifi)
+               {
+               // Not found. Make sure our interface list is up to date, then try again.
+               LogInfo("mDNSPlatformInterfaceIDfromInterfaceIndex: InterfaceID for interface index %d not found; Updating interface list", ifindex);
+               mDNSMacOSXNetworkChanged(m);
+               ifi = IfindexToInterfaceInfoOSX(m, (mDNSInterfaceID)(uintptr_t)ifindex);
+               }
 
-       return(mDNSNULL);
+       if (!ifi) return(mDNSNULL);     
+       
+       return(ifi->ifinfo.InterfaceID);
        }
 
+
 mDNSexport mDNSu32 mDNSPlatformInterfaceIndexfromInterfaceID(mDNS *const m, mDNSInterfaceID id)
        {
        NetworkInterfaceInfoOSX *i;
        if (id == mDNSInterface_LocalOnly) return(kDNSServiceInterfaceIndexLocalOnly);
        if (id == mDNSInterface_Any      ) return(0);
 
-       // Don't use i->ifinfo.InterfaceID here, because we DO want to find inactive interfaces, which have no InterfaceID set
+       mDNSu32 scope_id = (mDNSu32)(uintptr_t)id;
+
+       // Don't use i->Registered here, because we DO want to find inactive interfaces, which have no Registered set
        for (i = m->p->InterfaceList; i; i = i->next)
-               if ((mDNSInterfaceID)i == id) return(i->scope_id);
+               if (i->scope_id == scope_id) return(i->scope_id);
 
        // Not found. Make sure our interface list is up to date, then try again.
        LogInfo("Interface index for InterfaceID %p not found; Updating interface list", id);
        mDNSMacOSXNetworkChanged(m);
        for (i = m->p->InterfaceList; i; i = i->next)
-               if ((mDNSInterfaceID)i == id) return(i->scope_id);
+               if (i->scope_id == scope_id) return(i->scope_id);
 
        return(0);
        }
@@ -346,15 +361,23 @@ mDNSlocal mDNSBool AddrRequiresPPPConnection(const struct sockaddr *addr)
 mDNSexport mStatus mDNSPlatformSendUDP(const mDNS *const m, const void *const msg, const mDNSu8 *const end,
        mDNSInterfaceID InterfaceID, UDPSocket *src, const mDNSAddr *dst, mDNSIPPort dstPort)
        {
-       // Note: For this platform we've adopted the convention that InterfaceIDs are secretly pointers
-       // to the NetworkInterfaceInfoOSX structure that holds the active sockets. The mDNSCore code
-       // doesn't know that and doesn't need to know that -- it just treats InterfaceIDs as opaque identifiers.
-       NetworkInterfaceInfoOSX *info = (NetworkInterfaceInfoOSX *)InterfaceID;
-       char *ifa_name = info ? info->ifinfo.ifname : "unicast";
+       NetworkInterfaceInfoOSX *info = mDNSNULL;
        struct sockaddr_storage to;
        int s = -1, err;
        mStatus result = mStatus_NoError;
 
+       if (InterfaceID)
+               {
+               info = IfindexToInterfaceInfoOSX(m, InterfaceID);
+               if (info == NULL)
+                       {
+                       LogMsg("mDNSPlatformSendUDP: Invalid interface index %p", InterfaceID);
+                       return mStatus_BadParamErr;
+                       }
+               }
+
+       char *ifa_name = InterfaceID ? info->ifinfo.ifname : "unicast";
+
        if (dst->type == mDNSAddrType_IPv4)
                {
                struct sockaddr_in *sin_to = (struct sockaddr_in*)&to;
@@ -603,14 +626,18 @@ mDNSlocal void myKQSocketCallBack(int s1, short filter, void *context)
 
                // Note: When handling multiple packets in a batch, MUST reset InterfaceID before handling each packet
                mDNSInterfaceID InterfaceID = mDNSNULL;
-               NetworkInterfaceInfo *intf = m->HostInterfaces;
-               while (intf && strcmp(intf->ifname, packetifname)) intf = intf->next;
+               //NetworkInterfaceInfo *intf = m->HostInterfaces;
+               //while (intf && strcmp(intf->ifname, packetifname)) intf = intf->next;
+
+               NetworkInterfaceInfoOSX *intf = m->p->InterfaceList;
+               while (intf && strcmp(intf->ifinfo.ifname, packetifname)) intf = intf->next;
+
                // When going to sleep we deregister all our interfaces, but if the machine
                // takes a few seconds to sleep we may continue to receive multicasts
                // during that time, which would confuse mDNSCoreReceive, because as far
                // as it's concerned, we should have no active interfaces any more.
                // Hence we ignore multicasts for which we can find no matching InterfaceID.
-               if (intf) InterfaceID = intf->InterfaceID;
+               if (intf) InterfaceID = intf->ifinfo.InterfaceID;
                else if (mDNSAddrIsDNSMulticast(&destAddr)) continue;
 
 //             LogMsg("myKQSocketCallBack got packet from %#a to %#a on interface %#a/%s",
@@ -1379,7 +1406,15 @@ mDNSexport void mDNSPlatformUDPClose(UDPSocket *sock)
 mDNSexport void mDNSPlatformSendRawPacket(const void *const msg, const mDNSu8 *const end, mDNSInterfaceID InterfaceID)
        {
        if (!InterfaceID) { LogMsg("mDNSPlatformSendRawPacket: No InterfaceID specified"); return; }
-       NetworkInterfaceInfoOSX *info = (NetworkInterfaceInfoOSX *)InterfaceID;
+       NetworkInterfaceInfoOSX *info;
+
+       extern mDNS mDNSStorage;
+       info = IfindexToInterfaceInfoOSX(&mDNSStorage, InterfaceID);
+       if (info == NULL)
+               {
+               LogMsg("mDNSPlatformSendUDP: Invalid interface index %p", InterfaceID);
+               return;
+               }
        if (info->BPF_fd < 0)
                LogMsg("mDNSPlatformSendRawPacket: %s BPF_fd %d not ready", info->ifinfo.ifname, info->BPF_fd);
        else
@@ -1393,7 +1428,14 @@ mDNSexport void mDNSPlatformSendRawPacket(const void *const msg, const mDNSu8 *c
 mDNSexport void mDNSPlatformSetLocalARP(const mDNSv4Addr *const tpa, const mDNSEthAddr *const tha, mDNSInterfaceID InterfaceID)
        {
        if (!InterfaceID) { LogMsg("mDNSPlatformSetLocalARP: No InterfaceID specified"); return; }
-       NetworkInterfaceInfoOSX *info = (NetworkInterfaceInfoOSX *)InterfaceID;
+       NetworkInterfaceInfoOSX *info;
+       extern mDNS mDNSStorage;
+       info = IfindexToInterfaceInfoOSX(&mDNSStorage, InterfaceID);
+       if (info == NULL)
+               {
+               LogMsg("mDNSPlatformSendUDP: Invalid interface index %p", InterfaceID);
+               return;
+               }
        // Manually inject an entry into our local ARP cache.
        // (We can't do this by sending an ARP broadcast, because the kernel only pays attention to incoming ARP packets, not outgoing.)
        mDNSBool makearp = mDNSv4AddressIsLinkLocal(tpa);
@@ -1474,16 +1516,16 @@ mDNSlocal int CountProxyTargets(mDNS *const m, NetworkInterfaceInfoOSX *x, int *
        AuthRecord *rr;
 
        for (rr = m->ResourceRecords; rr; rr=rr->next)
-               if (rr->resrec.InterfaceID == (mDNSInterfaceID)x && rr->AddressProxy.type == mDNSAddrType_IPv4)
+               if (rr->resrec.InterfaceID == x->ifinfo.InterfaceID && rr->AddressProxy.type == mDNSAddrType_IPv4)
                        {
-                       if (p4) LogSPS("mDNSPlatformUpdateProxyList: fd %d %-7s IP%2d %.4a", x->BPF_fd, x->ifinfo.ifname, numv4, &rr->AddressProxy.ip.v4);
+                       if (p4) LogSPS("CountProxyTargets: fd %d %-7s IP%2d %.4a", x->BPF_fd, x->ifinfo.ifname, numv4, &rr->AddressProxy.ip.v4);
                        numv4++;
                        }
 
        for (rr = m->ResourceRecords; rr; rr=rr->next)
-               if (rr->resrec.InterfaceID == (mDNSInterfaceID)x && rr->AddressProxy.type == mDNSAddrType_IPv6)
+               if (rr->resrec.InterfaceID == x->ifinfo.InterfaceID && rr->AddressProxy.type == mDNSAddrType_IPv6)
                        {
-                       if (p6) LogSPS("mDNSPlatformUpdateProxyList: fd %d %-7s IP%2d %.16a", x->BPF_fd, x->ifinfo.ifname, numv6, &rr->AddressProxy.ip.v6);
+                       if (p6) LogSPS("CountProxyTargets: fd %d %-7s IP%2d %.16a", x->BPF_fd, x->ifinfo.ifname, numv6, &rr->AddressProxy.ip.v6);
                        numv6++;
                        }
 
@@ -1495,7 +1537,10 @@ mDNSlocal int CountProxyTargets(mDNS *const m, NetworkInterfaceInfoOSX *x, int *
 mDNSexport void mDNSPlatformUpdateProxyList(mDNS *const m, const mDNSInterfaceID InterfaceID)
        {
        NetworkInterfaceInfoOSX *x;
-       for (x = m->p->InterfaceList; x; x = x->next) if (x == (NetworkInterfaceInfoOSX *)InterfaceID) break;
+
+       //NOTE: We can't use IfIndexToInterfaceInfoOSX because that looks for Registered also.
+       for (x = m->p->InterfaceList; x; x = x->next) if (x->ifinfo.InterfaceID == InterfaceID) break;
+
        if (!x) { LogMsg("mDNSPlatformUpdateProxyList: ERROR InterfaceID %p not found", InterfaceID); return; }
 
        #define MAX_BPF_ADDRS 250
@@ -1675,7 +1720,7 @@ mDNSexport void mDNSPlatformReceiveBPF_fd(mDNS *const m, int fd)
                        i->BPF_cfs = CFSocketCreateWithNative(kCFAllocatorDefault, fd, kCFSocketReadCallBack, bpf_callback, &myCFSocketContext);
                        i->BPF_rls = CFSocketCreateRunLoopSource(kCFAllocatorDefault, i->BPF_cfs, 0);
                        CFRunLoopAddSource(i->m->p->CFRunLoop, i->BPF_rls, kCFRunLoopDefaultMode);
-                       mDNSPlatformUpdateProxyList(m, (mDNSInterfaceID)i);
+                       mDNSPlatformUpdateProxyList(m, i->ifinfo.InterfaceID);
                        }
                }
 
@@ -1984,7 +2029,7 @@ mDNSlocal NetworkInterfaceInfoOSX *AddInterfaceToList(mDNS *const m, struct ifad
                                // If this interface is not already registered (i.e. it's a dormant interface we had in our list
                                // from when we previously saw it) then we mustn't do that, because mDNSCore doesn't know about it yet.
                                // In this case, the mDNS_RegisterInterface() call will take care of starting the NetWake browse if necessary.
-                               if ((*p)->ifinfo.InterfaceID)
+                               if ((*p)->Registered)
                                        {
                                        mDNS_Lock(m);
                                        if (NetWake) mDNS_ActivateNetWake_internal  (m, &(*p)->ifinfo);
@@ -2000,7 +2045,7 @@ mDNSlocal NetworkInterfaceInfoOSX *AddInterfaceToList(mDNS *const m, struct ifad
        debugf("AddInterfaceToList: Making   new   interface %lu %.6a with address %#a at %p", scope_id, &bssid, &ip, i);
        if (!i) return(mDNSNULL);
        mDNSPlatformMemZero(i, sizeof(NetworkInterfaceInfoOSX));
-       i->ifinfo.InterfaceID = mDNSNULL;
+       i->ifinfo.InterfaceID = (mDNSInterfaceID)(uintptr_t)scope_id;
        i->ifinfo.ip          = ip;
        i->ifinfo.mask        = mask;
        strlcpy(i->ifinfo.ifname, ifa->ifa_name, sizeof(i->ifinfo.ifname));
@@ -2023,6 +2068,7 @@ mDNSlocal NetworkInterfaceInfoOSX *AddInterfaceToList(mDNS *const m, struct ifad
        i->sa_family       = ifa->ifa_addr->sa_family;
        i->BPF_fd          = -1;
        i->BPF_len         = 0;
+       i->Registered      = mDNSNULL;
 
        // Do this AFTER i->BSSID has been set up
        i->ifinfo.NetWake  = NetWakeInterface(i);
@@ -2806,6 +2852,11 @@ mDNSlocal mStatus UpdateInterfaceList(mDNS *const m, mDNSs32 utc)
                                        LogMsg("getifaddrs ifa_netmask for %5s(%d) Flags %04X Family %2d %#a has different family: %d",
                                                ifa->ifa_name, if_nametoindex(ifa->ifa_name), ifa->ifa_flags, ifa->ifa_addr->sa_family, &ip, ifa->ifa_netmask->sa_family);
                                        }
+                                       // Currently we use a few internal ones like mDNSInterfaceID_LocalOnly etc. that are negative values (0, -1, -2).
+                               else if ((int)if_nametoindex(ifa->ifa_name) <= 0)
+                                       {
+                                       LogMsg("UpdateInterfaceList: if_nametoindex returned zero/negative value for %5s(%d)", ifa->ifa_name, if_nametoindex(ifa->ifa_name));
+                                       }
                                else
                                        {
                                        // Make sure ifa_netmask->sa_family is set correctly
@@ -2987,18 +3038,20 @@ mDNSlocal int SetupActiveInterfaces(mDNS *const m, mDNSs32 utc)
                        NetworkInterfaceInfoOSX *primary = SearchForInterfaceByName(m, i->ifinfo.ifname, AAAA_OVER_V4 ? AF_UNSPEC : i->sa_family);
                        if (!primary) LogMsg("SetupActiveInterfaces ERROR! SearchForInterfaceByName didn't find %s", i->ifinfo.ifname);
 
-                       if (n->InterfaceID && n->InterfaceID != (mDNSInterfaceID)primary)       // Sanity check
+                       if (i->Registered && i->Registered != primary)  // Sanity check
                                {
-                               LogMsg("SetupActiveInterfaces ERROR! n->InterfaceID %p != primary %p", n->InterfaceID, primary);
-                               n->InterfaceID = mDNSNULL;
+                               LogMsg("SetupActiveInterfaces ERROR! n->Registered %p != primary %p", i->Registered, primary);
+                               i->Registered = mDNSNULL;
                                }
 
-                       if (!n->InterfaceID)
+                       if (!i->Registered)
                                {
-                               // Note: If n->InterfaceID is set, that means we've called mDNS_RegisterInterface() for this interface,
+                               // Note: If i->Registered is set, that means we've called mDNS_RegisterInterface() for this interface,
                                // so we need to make sure we call mDNS_DeregisterInterface() before disposing it.
-                               // If n->InterfaceID is NOT set, then we haven't registered it and we should not try to deregister it
-                               n->InterfaceID = (mDNSInterfaceID)primary;
+                               // If i->Registered is NOT set, then we haven't registered it and we should not try to deregister it
+                               //
+
+                               i->Registered = primary;
 
                                // If i->LastSeen == utc, then this is a brand-new interface, just created, or an interface that never went away.
                                // If i->LastSeen != utc, then this is an old interface, previously seen, that went away for (utc - i->LastSeen) seconds.
@@ -3006,15 +3059,16 @@ mDNSlocal int SetupActiveInterfaces(mDNS *const m, mDNSs32 utc)
                                i->Occulting = !(i->ifa_flags & IFF_LOOPBACK) && (utc - i->LastSeen > 0 && utc - i->LastSeen < 60);
 
                                mDNS_RegisterInterface(m, n, i->Flashing && i->Occulting);
+
                                if (!mDNSAddressIsLinkLocal(&n->ip)) count++;
-                               LogInfo("SetupActiveInterfaces:   Registered    %5s(%lu) %.6a InterfaceID %p %#a/%d%s%s%s",
-                                       i->ifinfo.ifname, i->scope_id, &i->BSSID, primary, &n->ip, CountMaskBits(&n->mask),
+                               LogInfo("SetupActiveInterfaces:   Registered    %5s(%lu) %.6a InterfaceID %p(%p), primary %p, %#a/%d%s%s%s",
+                                       i->ifinfo.ifname, i->scope_id, &i->BSSID, i->ifinfo.InterfaceID, i, primary, &n->ip, CountMaskBits(&n->mask),
                                        i->Flashing        ? " (Flashing)"  : "",
                                        i->Occulting       ? " (Occulting)" : "",
                                        n->InterfaceActive ? " (Primary)"   : "");
 
                                if (!n->McastTxRx)
-                                       debugf("SetupActiveInterfaces:   No Tx/Rx on   %5s(%lu) %.6a InterfaceID %p %#a", i->ifinfo.ifname, i->scope_id, &i->BSSID, primary, &n->ip);
+                                       debugf("SetupActiveInterfaces:   No Tx/Rx on   %5s(%lu) %.6a InterfaceID %p %#a", i->ifinfo.ifname, i->scope_id, &i->BSSID, i->ifinfo.InterfaceID, &n->ip);
                                else
                                        {
                                        if (i->sa_family == AF_INET)
@@ -3101,22 +3155,22 @@ mDNSlocal int ClearInactiveInterfaces(mDNS *const m, mDNSs32 utc)
                {
                // If this interface is no longer active, or its InterfaceID is changing, deregister it
                NetworkInterfaceInfoOSX *primary = SearchForInterfaceByName(m, i->ifinfo.ifname, AAAA_OVER_V4 ? AF_UNSPEC : i->sa_family);
-               if (i->ifinfo.InterfaceID)
-                       if (i->Exists == 0 || i->Exists == 2 || i->ifinfo.InterfaceID != (mDNSInterfaceID)primary)
+               if (i->Registered)
+                       if (i->Exists == 0 || i->Exists == 2 || i->Registered != primary)
                                {
                                i->Flashing = !(i->ifa_flags & IFF_LOOPBACK) && (utc - i->AppearanceTime < 60);
-                               LogInfo("ClearInactiveInterfaces: Deregistering %5s(%lu) %.6a InterfaceID %p %#a/%d%s%s%s",
-                                       i->ifinfo.ifname, i->scope_id, &i->BSSID, i->ifinfo.InterfaceID,
+                               LogInfo("ClearInactiveInterfaces: Deregistering %5s(%lu) %.6a InterfaceID %p(%p), primary %p, %#a/%d%s%s%s",
+                                       i->ifinfo.ifname, i->scope_id, &i->BSSID, i->ifinfo.InterfaceID, i, primary,
                                        &i->ifinfo.ip, CountMaskBits(&i->ifinfo.mask),
                                        i->Flashing               ? " (Flashing)"  : "",
                                        i->Occulting              ? " (Occulting)" : "",
                                        i->ifinfo.InterfaceActive ? " (Primary)"   : "");
                                mDNS_DeregisterInterface(m, &i->ifinfo, i->Flashing && i->Occulting);
                                if (!mDNSAddressIsLinkLocal(&i->ifinfo.ip)) count++;
-                               i->ifinfo.InterfaceID = mDNSNULL;
-                               // Note: If i->ifinfo.InterfaceID is set, that means we've called mDNS_RegisterInterface() for this interface,
+                               i->Registered = mDNSNULL;
+                               // Note: If i->Registered is set, that means we've called mDNS_RegisterInterface() for this interface,
                                // so we need to make sure we call mDNS_DeregisterInterface() before disposing it.
-                               // If i->ifinfo.InterfaceID is NOT set, then it's not registered and we should not call mDNS_DeregisterInterface() on it.
+                               // If i->Registered is NOT set, then it's not registered and we should not call mDNS_DeregisterInterface() on it.
 
                                // Caution: If we ever decide to add code here to leave the multicast group, we need to make sure that this
                                // is the LAST representative of this physical interface, or we'll unsubscribe from the group prematurely.
@@ -3133,9 +3187,9 @@ mDNSlocal int ClearInactiveInterfaces(mDNS *const m, mDNSs32 utc)
                if (!i->Exists)
                        {
                        if (i->LastSeen == utc) i->LastSeen = utc - 1;
-                       mDNSBool delete = (NumCacheRecordsForInterfaceID(m, (mDNSInterfaceID)i) == 0) && (utc - i->LastSeen >= 60);
-                       LogInfo("ClearInactiveInterfaces: %-13s %5s(%lu) %.6a InterfaceID %p %#a/%d Age %d%s", delete ? "Deleting" : "Holding",
-                               i->ifinfo.ifname, i->scope_id, &i->BSSID, i->ifinfo.InterfaceID,
+                       mDNSBool delete = (NumCacheRecordsForInterfaceID(m, i->ifinfo.InterfaceID) == 0) && (utc - i->LastSeen >= 60);
+                       LogInfo("ClearInactiveInterfaces: %-13s %5s(%lu) %.6a InterfaceID %p(%p) %#a/%d Age %d%s", delete ? "Deleting" : "Holding",
+                               i->ifinfo.ifname, i->scope_id, &i->BSSID, i->ifinfo.InterfaceID, i,
                                &i->ifinfo.ip, CountMaskBits(&i->ifinfo.mask), utc - i->LastSeen,
                                i->ifinfo.InterfaceActive ? " (Primary)" : "");
 #if APPLE_OSX_mDNSResponder
@@ -4442,7 +4496,7 @@ mDNSexport void mDNSMacOSXNetworkChanged(mDNS *const m)
                        }
                else                                                            // else, we're Sleep Proxy Server; open BPF fds
                        {
-                       if (i->Exists && i->ifinfo.InterfaceID == (mDNSInterfaceID)i && !(i->ifa_flags & IFF_LOOPBACK) && i->BPF_fd == -1)
+                       if (i->Exists && i->Registered == i && !(i->ifa_flags & IFF_LOOPBACK) && i->BPF_fd == -1)
                                { LogSPS("%s requesting BPF", i->ifinfo.ifname); i->BPF_fd = -2; mDNSRequestBPF(); }
                        }
                }
index c236964..f773b3b 100644 (file)
@@ -82,6 +82,7 @@ struct NetworkInterfaceInfoOSX_struct
        u_int                    BPF_len;
        CFSocketRef              BPF_cfs;
        CFRunLoopSourceRef       BPF_rls;
+       NetworkInterfaceInfoOSX *Registered;            // non-NULL means registered with mDNS Core
        };
 
 struct mDNS_PlatformSupport_struct
@@ -139,6 +140,7 @@ extern void NotifyOfElusiveBug(const char *title, const char *msg); // Both stri
 extern void SetDomainSecrets(mDNS *m);
 extern void mDNSMacOSXNetworkChanged(mDNS *const m);
 extern int mDNSMacOSXSystemBuildNumber(char *HINFO_SWstring);
+extern NetworkInterfaceInfoOSX *IfindexToInterfaceInfoOSX(const mDNS *const m, mDNSInterfaceID ifindex);
 
 extern int KQueueSet(int fd, u_short flags, short filter, const KQueueEntry *const entryRef);
 
index a5d746a..d31c9bc 100644 (file)
@@ -3258,7 +3258,7 @@ mDNSlocal void LogAuthRecords(mDNS *const m, const mDNSs32 now, AuthRecord *Reso
                LogMsgNoIdent("    Int    Next  Expire   State");
                for (ar = ResourceRecords; ar; ar=ar->next)
                        {
-                       NetworkInterfaceInfo *info = (NetworkInterfaceInfo *)ar->resrec.InterfaceID;
+                       char *ifname = InterfaceNameForID(m, ar->resrec.InterfaceID);
                        if (ar->WakeUp.HMAC.l[0]) (*proxy)++;
                        if (!mDNSSameEthAddress(&owner, &ar->WakeUp.HMAC))
                                {
@@ -3281,7 +3281,7 @@ mDNSlocal void LogAuthRecords(mDNS *const m, const mDNSs32 now, AuthRecord *Reso
                                        ar->ThisAPInterval / mDNSPlatformOneSecond,
                                        ar->AnnounceCount ? (ar->LastAPTime + ar->ThisAPInterval - now) / mDNSPlatformOneSecond : 0,
                                        ar->TimeExpire    ? (ar->TimeExpire                      - now) / mDNSPlatformOneSecond : 0,
-                                       info ? info->ifname : "ALL",
+                                       ifname ? ifname : "ALL",
                                        ARDisplayString(m, ar));
                        else
                                LogMsgNoIdent("                             LO %s", ARDisplayString(m, ar));
@@ -3311,14 +3311,14 @@ mDNSexport void udsserver_info(mDNS *const m)
                        for (cr = cg->members; cr; cr=cr->next)
                                {
                                mDNSs32 remain = cr->resrec.rroriginalttl - (now - cr->TimeRcvd) / mDNSPlatformOneSecond;
-                               NetworkInterfaceInfo *info = (NetworkInterfaceInfo *)cr->resrec.InterfaceID;
+                               char *ifname = InterfaceNameForID(m, cr->resrec.InterfaceID);
                                CacheUsed++;
                                if (cr->CRActiveQuestion) CacheActive++;
                                LogMsgNoIdent("%3d %s%8ld %-7s%s %-6s%s",
                                        slot,
                                        cr->CRActiveQuestion ? "*" : " ",
                                        remain,
-                                       info ? info->ifname : "-U-",
+                                       ifname ? ifname : "-U-",
                                        (cr->resrec.RecordType == kDNSRecordTypePacketNegative)  ? "-" :
                                        (cr->resrec.RecordType & kDNSRecordTypePacketUniqueMask) ? " " : "+",
                                        DNSTypeName(cr->resrec.rrtype),
@@ -3364,12 +3364,12 @@ mDNSexport void udsserver_info(mDNS *const m)
                        {
                        mDNSs32 i = q->ThisQInterval / mDNSPlatformOneSecond;
                        mDNSs32 n = (q->LastQTime + q->ThisQInterval - now) / mDNSPlatformOneSecond;
-                       NetworkInterfaceInfo *info = (NetworkInterfaceInfo *)q->InterfaceID;
+                       char *ifname = InterfaceNameForID(m, q->InterfaceID);
                        CacheUsed++;
                        if (q->ThisQInterval) CacheActive++;
                        LogMsgNoIdent("%6d%6d %-7s%s%s %5d  %-6s%##s%s",
                                i, n,
-                               info ? info->ifname : mDNSOpaque16IsZero(q->TargetQID) ? "" : "-U-",
+                               ifname ? ifname : mDNSOpaque16IsZero(q->TargetQID) ? "" : "-U-",
                                mDNSOpaque16IsZero(q->TargetQID) ? (q->LongLived ? "l" : " ") : (q->LongLived ? "L" : "O"),
                                q->AuthInfo    ? "P" : " ",
                                q->CurrentAnswers,