include $(MAKEFILEPATH)/pb_makefiles/platform.make
-MVERS = "mDNSResponder-379.27.1"
+MVERS = "mDNSResponder-379.32.1"
DDNSWRITECONFIG = "$(DSTROOT)/Library/Application Support/Bonjour/ddnswriteconfig"
VER =
SendResponses(m);
}
+/*
+ * This function attempts to detect if multiple interfaces are on the same subnet.
+ * It makes this determination based only on the IPv4 Addresses and subnet masks.
+ * IPv6 link local addresses that are configured by default on all interfaces make
+ * it hard to make this determination
+ *
+ * The 'real' fix for this would be to send out multicast packets over one interface
+ * and conclude that multiple interfaces are on the same subnet only if these packets
+ * are seen on other interfaces on the same system
+ */
mDNSlocal mDNSBool skipSameSubnetRegistration(mDNS *const m, mDNSInterfaceID *regID, mDNSu32 count, mDNSInterfaceID intfid)
{
NetworkInterfaceInfo *intf;
NetworkInterfaceInfo *newIntf;
mDNSu32 i;
- newIntf = FirstInterfaceForID(m, intfid);
- if (newIntf == mDNSNULL)
- {
- LogMsg("%s : Could not get Interface for id %d", __func__, intfid);
- return (mDNSfalse);
- }
-
- for ( i = 0; i < count; i++)
+ for (newIntf = FirstInterfaceForID(m, intfid); newIntf; newIntf = newIntf->next)
{
- intf = FirstInterfaceForID(m, regID[i]);
- if (intf == mDNSNULL)
+ if ((newIntf->InterfaceID != intfid) ||
+ (newIntf->ip.type != mDNSAddrType_IPv4))
{
- LogMsg("%s : Could not get Interface for id %d", __func__, regID[i]);
- return (mDNSfalse);
- }
-
- if ((newIntf->ip.type == mDNSAddrType_IPv4) &&
- (((intf->ip.ip.v4.NotAnInteger ^ newIntf->ip.ip.v4.NotAnInteger) & intf->mask.ip.v4.NotAnInteger) == 0))
- {
- LogSPS("%s : Already registered for the same subnet (IPv4) for interface %s", __func__, intf->ifname);
- return (mDNStrue);
+ continue;
}
-
- if ( (newIntf->ip.type == mDNSAddrType_IPv6) &&
- ((((intf->ip.ip.v6.l[0] ^ newIntf->ip.ip.v6.l[0]) & intf->mask.ip.v6.l[0]) == 0) &&
- (((intf->ip.ip.v6.l[1] ^ newIntf->ip.ip.v6.l[1]) & intf->mask.ip.v6.l[1]) == 0) &&
- (((intf->ip.ip.v6.l[2] ^ newIntf->ip.ip.v6.l[2]) & intf->mask.ip.v6.l[2]) == 0) &&
- (((intf->ip.ip.v6.l[3] ^ newIntf->ip.ip.v6.l[3]) & intf->mask.ip.v6.l[3]) == 0)))
+ for ( i = 0; i < count; i++)
{
- LogSPS("%s : Already registered for the same subnet (IPv6) for interface %s", __func__, intf->ifname);
- return (mDNStrue);
+ for (intf = FirstInterfaceForID(m, regID[i]); intf; intf = intf->next)
+ {
+ if ((intf->InterfaceID != regID[i]) ||
+ (intf->ip.type != mDNSAddrType_IPv4))
+ {
+ continue;
+ }
+ if ((intf->ip.ip.v4.NotAnInteger & intf->mask.ip.v4.NotAnInteger) == (newIntf->ip.ip.v4.NotAnInteger & newIntf->mask.ip.v4.NotAnInteger))
+ {
+ LogSPS("%s : Already registered for the same subnet (IPv4) for interface %s", __func__, intf->ifname);
+ return (mDNStrue);
+ }
+ }
}
}
return (mDNSfalse);
mDNSlocal void FreeD2DARElemCallback(mDNS *const m, AuthRecord *const rr, mStatus result);
mDNSlocal void PrintHex(mDNSu8 *data, mDNSu16 len);
-static ARListElem *D2DRecords = NULL; // List of locally-generated PTR records to records found via D2D
+typedef struct D2DRecordListElem
+{
+ struct D2DRecordListElem *next;
+ AuthRecord ar;
+ D2DServiceInstance instanceHandle;
+ D2DTransportType transportType;
+} D2DRecordListElem;
+
+static D2DRecordListElem *D2DRecords = NULL; // List of records returned with D2DServiceFound events
typedef struct D2DBrowseListElem
{
(void)m; // unused
if (result == mStatus_MemFree)
{
- ARListElem **ptr = &D2DRecords;
- ARListElem *tmp;
+ D2DRecordListElem **ptr = &D2DRecords;
+ D2DRecordListElem *tmp;
while (*ptr && &(*ptr)->ar != rr) ptr = &(*ptr)->next;
if (!*ptr) { LogMsg("FreeD2DARElemCallback: Could not find in D2DRecords: %s", ARDisplayString(m, rr)); return; }
LogInfo("FreeD2DARElemCallback: Found in D2DRecords: %s", ARDisplayString(m, rr));
}
}
+mDNSexport void external_connection_release(const domainname *instance)
+{
+ (void) instance;
+ D2DRecordListElem *ptr = D2DRecords;
+
+ for ( ; ptr ; ptr = ptr->next)
+ {
+ if ((ptr->ar.resrec.rrtype == kDNSServiceType_PTR) &&
+ SameDomainName(&ptr->ar.rdatastorage.u.name, instance))
+ {
+ LogInfo("external_connection_release: Calling D2DRelease(instanceHandle = %p, transportType = %d",
+ ptr->instanceHandle, ptr->transportType);
+ if (D2DRelease) D2DRelease(ptr->instanceHandle, ptr->transportType);
+ }
+ }
+}
+
mDNSlocal void xD2DClearCache(const domainname *regType)
{
- ARListElem *ptr = D2DRecords;
+ D2DRecordListElem *ptr = D2DRecords;
for ( ; ptr ; ptr = ptr->next)
{
if (SameDomainName(&ptr->ar.namestorage, regType))
mDNSlocal void xD2DAddToCache(mDNS *const m, D2DStatus result, D2DServiceInstance instanceHandle, D2DTransportType transportType, const Byte *key, size_t keySize, const Byte *value, size_t valueSize)
{
- (void)transportType; // We don't care about this, yet.
- (void)instanceHandle; // We don't care about this, yet.
-
if (result == kD2DSuccess)
{
if ( key == NULL || value == NULL || keySize == 0 || valueSize == 0) { LogMsg("xD2DAddToCache: NULL Byte * passed in or length == 0"); return; }
mStatus err;
- ARListElem *ptr = mDNSPlatformMemAllocate(sizeof(ARListElem) + (valueSize < sizeof(RData) ? 0 : valueSize - sizeof(RData)));
+ D2DRecordListElem *ptr = mDNSPlatformMemAllocate(sizeof(D2DRecordListElem) + (valueSize < sizeof(RData) ? 0 : valueSize - sizeof(RData)));
if (ptr == NULL) { LogMsg("xD2DAddToCache: memory allocation failure"); return; }
}
LogInfo("xD2DAddToCache: mDNS_Register succeeded for %s", ARDisplayString(m, &ptr->ar));
+ ptr->instanceHandle = instanceHandle;
+ ptr->transportType = transportType;
ptr->next = D2DRecords;
D2DRecords = ptr;
}
LogMsg("xD2DAddToCache: Unexpected result %d", result);
}
-mDNSlocal ARListElem * xD2DFindInList(mDNS *const m, const Byte *const key, const size_t keySize, const Byte *const value, const size_t valueSize)
+mDNSlocal D2DRecordListElem * xD2DFindInList(mDNS *const m, const Byte *const key, const size_t keySize, const Byte *const value, const size_t valueSize)
{
- ARListElem *ptr = D2DRecords;
- ARListElem *arptr;
+ D2DRecordListElem *ptr = D2DRecords;
+ D2DRecordListElem *arptr;
if ( key == NULL || value == NULL || keySize == 0 || valueSize == 0) { LogMsg("xD2DFindInList: NULL Byte * passed in or length == 0"); return NULL; }
- arptr = mDNSPlatformMemAllocate(sizeof(ARListElem) + (valueSize < sizeof(RData) ? 0 : valueSize - sizeof(RData)));
+ arptr = mDNSPlatformMemAllocate(sizeof(D2DRecordListElem) + (valueSize < sizeof(RData) ? 0 : valueSize - sizeof(RData)));
if (arptr == NULL) { LogMsg("xD2DFindInList: memory allocation failure"); return NULL; }
if (xD2DParse(m, (const mDNSu8 *const)key, (const mDNSu16)keySize, (const mDNSu8 *const)value, (const mDNSu16)valueSize, &arptr->ar) != mStatus_NoError)
if (result == kD2DSuccess)
{
- ARListElem *ptr = xD2DFindInList(m, key, keySize, value, valueSize);
+ D2DRecordListElem *ptr = xD2DFindInList(m, key, keySize, value, valueSize);
if (ptr)
{
LogInfo("xD2DRemoveFromCache: Remove from cache: %s", ARDisplayString(m, &ptr->ar));
// with the kDNSServiceFlagsIncludeAWDL flag set.
mDNSexport mDNSBool mDNSPlatformValidRecordForQuestion(const ResourceRecord *const rr, const DNSQuestion *const q)
{
- // Don't do AWDL specific filtering if AWDL support is not enabled.
- if (!mDNSStorage.mDNSHandlePeerEvents)
- return mDNStrue;
-
if (!rr->InterfaceID || (rr->InterfaceID == q->InterfaceID))
return mDNStrue;
*/
#ifndef _DNS_SD_H
-#define _DNS_SD_H 3792701
+#define _DNS_SD_H 3793201
#ifdef __cplusplus
extern "C" {
* 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
+ * mapped internally to kDNSServiceInterfaceIndexAny with the kDNSServiceFlagsIncludeP2P
+ * set, 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
const void *rdata
);
-
/*********************************************************************************************
*
* NAT Port Mapping
(void)rdata; // Unused
return(kDNSServiceErr_Unsupported);
}
-#endif
+
+#endif // !MDNS_BUILDINGSTUBLIBRARY
port_mapping_request, // New in Leopard and B4W 2.0
addrinfo_request,
send_bpf, // New in SL
+ release_request,
cancel_request = 63
} request_op_t;
return(status);
}
+#if APPLE_OSX_mDNSResponder
+
+mDNSlocal mStatus handle_release_request(request_state *request)
+{
+ mStatus err = 0;
+ char name[256], regtype[MAX_ESCAPED_DOMAIN_NAME], domain[MAX_ESCAPED_DOMAIN_NAME];
+ domainname instance;
+
+ // extract the data from the message
+ DNSServiceFlags flags = get_flags(&request->msgptr, request->msgend);
+
+ if (get_string(&request->msgptr, request->msgend, name, 256) < 0 ||
+ get_string(&request->msgptr, request->msgend, regtype, MAX_ESCAPED_DOMAIN_NAME) < 0 ||
+ get_string(&request->msgptr, request->msgend, domain, MAX_ESCAPED_DOMAIN_NAME) < 0)
+ {
+ LogMsg("ERROR: handle_release_request - Couldn't read name/regtype/domain");
+ return(mStatus_BadParamErr);
+ }
+
+ if (!request->msgptr)
+ {
+ LogMsg("%3d: PeerConnectionRelease(unreadable parameters)", request->sd);
+ return(mStatus_BadParamErr);
+ }
+
+ if (build_domainname_from_strings(&instance, name, regtype, domain) < 0)
+ {
+ LogMsg("ERROR: handle_release_request bad “%s” “%s” “%s”", name, regtype, domain);
+ return(mStatus_BadParamErr);
+ }
+
+ LogOperation("%3d: PeerConnectionRelease(%X %##s) START PID[%d](%s)",
+ request->sd, flags, instance.c, get_peer_pid(request->sd, pid_name), pid_name);
+
+ external_connection_release(&instance);
+ return(err);
+}
+
+#else // APPLE_OSX_mDNSResponder
+
+mDNSlocal mStatus handle_release_request(request_state *request)
+{
+ (void) request;
+ return mStatus_UnsupportedErr;
+}
+
+#endif // APPLE_OSX_mDNSResponder
+
mDNSlocal mStatus handle_setdomain_request(request_state *request)
{
char domainstr[MAX_ESCAPED_DOMAIN_NAME];
case addrinfo_request: min_size += sizeof(mDNSu32) + 4 /* v4/v6 */ + 1 /* hostname */; break;
case send_bpf: // Same as cancel_request below
case cancel_request: min_size = 0; break;
+ case release_request: min_size += sizeof(mDNSu32) + 3 /* type, type, domain */; break;
default: LogMsg("ERROR: validate_message - unsupported req type: %d", req->hdr.op); min_size = -1; break;
}
case update_record_request: err = handle_update_request (req); break;
case remove_record_request: err = handle_removerecord_request(req); break;
case cancel_request: handle_cancel_request (req); break;
+ case release_request: err = handle_release_request (req); break;
default: LogMsg("%3d: ERROR: Unsupported UDS req: %d", req->sd, req->hdr.op);
}
extern void external_stop_advertising_service(const ResourceRecord *const resourceRecord, DNSServiceFlags flags);
extern void external_start_resolving_service(mDNSInterfaceID InterfaceID, const domainname *const fqdn, DNSServiceFlags flags);
extern void external_stop_resolving_service(mDNSInterfaceID InterfaceID, const domainname *const fqdn, DNSServiceFlags flags);
+extern void external_connection_release(const domainname *instance);
#else
#define external_start_browsing_for_service(A,B,C,D) (void)(A)
#define external_stop_browsing_for_service(A,B,C,D) (void)(A)
#define external_stop_advertising_service(A,B) (void)(A)
#define external_start_resolving_service(A,B,C) (void)(A)
#define external_stop_resolving_service(A,B,C) (void)(A)
+#define external_connection_release(A) (void)(A)
#endif // APPLE_OSX_mDNSResponder
extern const char mDNSResponderVersionString_SCCS[];