2016-08-03 23 views
0

Ich versuche die Kommunikation zwischen zwei iOS-Apps durch einen Bonjour-Service zu implementieren. Lassen Sie uns nicht diskutieren, dass dies wahrscheinlich nicht von der App-Store-Rezension akzeptiert wird. Es wird sowieso nicht im Laden veröffentlicht.Wie kann DNSService auf die Loopback-Schnittstelle beschränkt werden?

Ich versuche eine Bonjour-Ankündigung für den Dienst auf die Loopback-Schnittstelle zu beschränken, um nur Verbindungen auf demselben Gerät zuzulassen.

Ich habe die lowlevel DNSServiceRegister Methode implementiert, um den Dienst in der folgenden Art und Weise bekannt zu geben: in der

DNSServiceErrorType error = DNSServiceBrowse(&serviceBrowseRef, 
               kDNSServiceFlagsDefault, 
               if_nametoindex("lo0"), //limit discovery to loopback as well 
               "_myservicetype._tcp", 
               NULL, 
               &serviceBrowseReply, 
               (__bridge void *)(self) 
               ); 

Testing:

DNSServiceErrorType err = DNSServiceRegister( 
               &dnsServiceRef, 
               kDNSServiceFlagsDefault, 
               if_nametoindex("lo0"), //limit to loopback interface 
               "myServiceName", 
               "_myservicetype._tcp", 
               NULL, 
               NULL, 
               htons(port), 
               0, 
               NULL, 
               &DNSServiceRegisterCallback, 
               (__bridge void *)(self) 
          ); 

Auf der Clientseite I Entdeckung implementiert haben wie folgt Der iPhone-Simulator gibt die erwarteten Ergebnisse nicht zurück. Die Entdeckung findet den angekündigten Dienst nicht.

Einige weitere Graben:

Der Versuch, auf der Kommandozeile zu überprüfen, ob es dns-sd -B _myservicetype._tcp gearbeitet, aber es findet nichts

Seltsamer folgende dns-sd -lo -B _myservicetype._tcp (Limit für alle lokalen Schnittstellen statt Loopback) zeigt die erwartete, aber die Interface 0 (aber if_nametoindex sagt der Index 1)

kDNSServiceInterfaceIndexLocalOnly anstelle von if_nametoindex("lo0") als der Parameter für DNSServiceBrowse den angekündigten Dienst zurückgibt. Der im Callback angegebene interfaceIndex ist wieder 0 (dasselbe Verhalten wie das Befehlszeilentool).

Und noch seltsamer, wenn ich kDNSServiceInterfaceIndexLocalOnly verwenden, während der Dienst registrieren, die Interface des entdeckten Service ist 4294967295 (uint Überlauf?)

Ist das erwartete Verhalten (nicht erlaubt zu begrenzen Schnittstelle Loopback?) Oder sind Ich habe hier einen seltsamen Fehler bei der internen Handhabung von Schnittstellenindizes?

+0

Für jetzt bin ich Registrierung und das Surfen mit kDNSServiceInterfaceIndexLocalOnly Konstanten, die Loopback oder eine andere lokale Schnittstelle verwenden können. Um eine Verbindung zu dem Socket herstellen zu können, der nur Verbindungen über die Loopback-Schnittstelle zulässt, lösche ich den aufgelösten Hostnamen und benutze stattdessen 'localhost' – JanR

Antwort

0

Der Grund für die Verwendung von lo0 funktioniert nicht, weil mDNSResponder die Loopback-Schnittstelle nicht verwendet, wenn eine echte Schnittstelle (die Multicast-Loopback unterstützt, IP_MULTICAST_LOOP) registriert ist. Siehe UpdateInterfaceList im Backend von MacOS X

Die DNS-SD-API hat spezielle Case-Indexdefinitionen, die keine gültigen Indizes sind, die von if_nametoidex() zurückgegeben werden. Normalerweise beginnt der Index bei 1, siehe die Dokumentation von dns_sd.h über was 0 und -1 bedeuten. Folgen Sie der Anleitung, wie man für nur lokale Dienstleistungen werben und durchsuchen:

/* 
* Constants for specifying an interface index 
* 
* Specific interface indexes are identified via a 32-bit unsigned integer returned 
* by the if_nametoindex() family of calls. 
* 
* If the client passes 0 for interface index, that means "do the right thing", 
* which (at present) means, "if the name is in an mDNS local multicast domain 
* (e.g. 'local.', '254.169.in-addr.arpa.', '{8,9,A,B}.E.F.ip6.arpa.') then multicast 
* on all applicable interfaces, otherwise send via unicast to the appropriate 
* DNS server." Normally, most clients will use 0 for interface index to 
* automatically get the default sensible behaviour. 
* 
* If the client passes a positive interface index, then for multicast names that 
* indicates to do the operation only on that one interface. For unicast names the 
* interface index is ignored unless kDNSServiceFlagsForceMulticast is also set. 
* 
* If the client passes kDNSServiceInterfaceIndexLocalOnly when registering 
* a service, then that service will be found *only* by other local clients 
* on the same machine that are browsing using kDNSServiceInterfaceIndexLocalOnly 
* or kDNSServiceInterfaceIndexAny. 
* If a client has a 'private' service, accessible only to other processes 
* running on the same machine, this allows the client to advertise that service 
* in a way such that it does not inadvertently appear in service lists on 
* all the other machines on the network. 
* 
* If the client passes kDNSServiceInterfaceIndexLocalOnly when browsing 
* then it will find *all* records registered on that same local machine. 
* Clients explicitly wishing to discover *only* LocalOnly services can 
* accomplish this by inspecting the interfaceIndex of each service reported 
* to their DNSServiceBrowseReply() callback function, and discarding those 
* where the interface index is not kDNSServiceInterfaceIndexLocalOnly. 
* 
* kDNSServiceInterfaceIndexP2P is meaningful only in Browse, QueryRecord, 
* and Resolve operations. It should not be used in other DNSService APIs. 
* 
* - If kDNSServiceInterfaceIndexP2P is passed to DNSServiceBrowse or 
* DNSServiceQueryRecord, it restricts the operation to P2P. 
* 
* - If kDNSServiceInterfaceIndexP2P is passed to DNSServiceResolve, it is 
* mapped internally to kDNSServiceInterfaceIndexAny, because resolving 
* a P2P service may create and/or enable an interface whose index is not 
* known a priori. The resolve callback will indicate the index of the 
* interface via which the service can be accessed. 
* 
* If applications pass kDNSServiceInterfaceIndexAny to DNSServiceBrowse 
* or DNSServiceQueryRecord, they must set the kDNSServiceFlagsIncludeP2P flag 
* to include P2P. In this case, if a service instance or the record being queried 
* is found over P2P, the resulting ADD event will indicate kDNSServiceInterfaceIndexP2P 
* as the interface index. 
*/ 

#define kDNSServiceInterfaceIndexAny 0 
#define kDNSServiceInterfaceIndexLocalOnly ((uint32_t)-1) 
#define kDNSServiceInterfaceIndexUnicast ((uint32_t)-2) 
#define kDNSServiceInterfaceIndexP2P  ((uint32_t)-3)