Пример #1
0
// PrintServiceInfo prints the service information to standard out
// A real application might want to do something else with the information
static void PrintServiceInfo(SearcherServices *services)
	{
	OTLink *link = OTReverseList(OTLIFOStealList(&services->serviceinfolist));
	
	while (link)
		{
		linkedServiceInfo *s = OTGetLinkObject(link, linkedServiceInfo, link);

		if (!services->headerPrinted)
			{
			printf("%-55s Type             Domain         Target Host     IP Address      Port Info\n", "Name");
			services->headerPrinted = true;
			}

		if (s->dom)
			{
			if (s->add) printf("%-55s available for browsing\n", s->domn);
			else        printf("%-55s no longer available for browsing\n", s->domn);
			}
		else
			{
			char ip[16];
			unsigned char *p = (unsigned char *)&s->address;
			sprintf(ip, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
			printf("%-55s %-16s %-14s ", s->name, s->type, s->domn);
			if (s->add) printf("%-15s %-15s %5d %s\n", s->host, ip, mDNSVal16(s->notAnIntPort), s->text);
			else        printf("Removed\n");
			}

		link = link->fNext;
		OTFreeMem(s);
		}
	}
static OSStatus MemTest(void)
{
	OSStatus err;
	OSStatus junk;
	EndpointRef ep;
	void *p1;
	void *p2;
	
	p1 = NULL;
	p2 = NULL;
	ep = OTOpenEndpointInContext(OTCreateConfiguration("tcp"), 0, NULL, &err, NULL);
	if (err == noErr) {
		p1 = OTAllocInContext(ep, T_BIND, T_ALL, &err, NULL);
	}
	if (err == noErr) {
		p2 = OTAllocMemInContext(100, NULL);
	}
	if (p2 != NULL) {
		OTFreeMem(p2);
	}
	if (p1 != NULL) {
		junk = OTFree(p1, T_BIND);
		assert(junk == noErr);
	}
	if (ep != NULL) {
		junk = OTCloseProvider(ep);
		assert(junk == noErr);
	}
	return err;
}
// When a new named instance of a service is found, FoundInstance() is called.
// In this sample code we turn around and immediately issue a query to resolve that service name to
// find its address, port, and txtinfo, but a normal browing application would just display the name.
static void FoundInstance(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord)
	{
	#pragma unused (question)
	SearcherServices *services = (SearcherServices *)question->QuestionContext;
	linkedServiceInfo *info;

	debugf("FoundInstance %##s PTR %##s", answer->name->c, answer->rdata->u.name.c);

	if (answer->rrtype != kDNSType_PTR) return;
	if (!services) { debugf("FoundInstance: services is NULL"); return; }
	
	info = (linkedServiceInfo *)OTAllocMem(sizeof(linkedServiceInfo));
	if (!info) { services->lostRecords = true; return; }
	
	info->i.name          = answer->rdata->u.name;
	info->i.InterfaceID   = answer->InterfaceID;
	info->i.ip.type		  = mDNSAddrType_IPv4;
	info->i.ip.ip.v4      = zerov4Addr;
	info->i.port          = zeroIPPort;
	info->add             = AddRecord;
	info->dom             = mDNSfalse;
	
	if (!AddRecord)	// If TTL == 0 we're deleting a service,
		OTLIFOEnqueue(&services->serviceinfolist, &info->link);
	else								// else we're adding a new service
		{
		ServiceInfoQuery *q = (ServiceInfoQuery *)OTAllocMem(sizeof(ServiceInfoQuery));
		if (!q) { OTFreeMem(info); services->lostRecords = true; return; }
		mDNS_StartResolveService(m, q, &info->i, FoundInstanceInfo, services);
		}
	}
static OSStatus RunServersForInterface(InetInterfaceInfo* interfaceInfo, SInt32 interfaceIndex)
	// Run HTTP servers for all of the IP addresses associated
	// with the interface denoted by interfaceInfo and interfaceIndex.
	// This routine first starts a server for the primary address
	// of the interface, then iterates through the secondary addresses on
	// the interface, starting a server thread for each one.
{
	OSStatus err;
	InetHost *secondaryAddressBuffer;
	UInt32   numberOfSecondaryAddresses;
	UInt32   addressIndex;

	secondaryAddressBuffer = NULL;
	
	// First run the server for the interfaces primary address.
	
	err = RunOneServer(interfaceInfo->fAddress);
	
	// Now start a server for each of the interface's secondary
	// addresses.  This stuff can only be done on systems that
	// support IP single link multihoming.

	numberOfSecondaryAddresses = interfaceInfo->fIPSecondaryCount;
	
	if ( err == noErr && gHaveIPSingleLinkMultihoming && numberOfSecondaryAddresses > 0 ) {

		// Allocate a buffer for the secondary address info.
		
		secondaryAddressBuffer = (InetHost *) OTAllocMemInContext( numberOfSecondaryAddresses * sizeof(InetHost) , NULL);
		if (secondaryAddressBuffer == NULL) {
			err = kENOMEMErr;
		}
		
		// Ask OT for the list of secondary addresses on this interface.
		
		if (err == noErr) {
			err = OTInetGetSecondaryAddresses(secondaryAddressBuffer, &numberOfSecondaryAddresses, interfaceIndex);
		}
		
		// Start a server for each secondary address.
		
		addressIndex = 0;
		while (err == noErr && addressIndex < numberOfSecondaryAddresses) {
			err = RunOneServer(secondaryAddressBuffer[addressIndex]);
			if (err == noErr) {
				addressIndex += 1;
			}
		}
	}

	// Clean up.
	
	if (secondaryAddressBuffer != NULL) {
		OTFreeMem(secondaryAddressBuffer);
	}

	return err;
}
Пример #5
0
int main()
	{
	OSStatus err;
	void *tempmem;
	DNSServiceRef sdRef;
	DNSServiceErrorType dse;

	SIOUXSettings.asktosaveonclose = false;
	SIOUXSettings.userwindowtitle  = "\pMulticast DNS Searcher";
	SIOUXSettings.rows             = 40;
	SIOUXSettings.columns          = 160;

	printf("DNS-SD Search Client\n\n");
	printf("This software reports errors using MacsBug breaks,\n");
	printf("so if you don't have MacsBug installed your Mac may crash.\n\n");
	printf("******************************************************************************\n\n");

	if (DNSServiceBrowse == (void*)kUnresolvedCFragSymbolAddress)
		{
		printf("Before you can use mDNS/DNS-SD clients, you need to place the \n");
		printf("\"Multicast DNS & DNS-SD\" Extension in the Extensions Folder and restart\n");
		return(-1);
		}

	err = InitOpenTransport();
	if (err) { printf("InitOpenTransport failed %d", err); return(err); }

	// Make sure OT has a large enough memory pool for us to draw from at OTNotifier (interrupt) time
	tempmem = OTAllocMem(0x10000);
	if (tempmem) OTFreeMem(tempmem);
	else printf("**** Warning: OTAllocMem couldn't pre-allocate 64K for us.\n");

	services.serviceinfolist.fHead = NULL;
	services.headerPrinted         = false;
	services.lostRecords           = false;

	printf("Sending mDNS service lookup queries and waiting for responses...\n\n");
    dse = DNSServiceBrowse(&sdRef, 0, 0, "_http._tcp", "", FoundInstance, &services);
	if (dse == kDNSServiceErr_NoError)
		{
		while (!YieldSomeTime(35))
			{
			if (services.serviceinfolist.fHead)
				PrintServiceInfo(&services);

			if (services.lostRecords)
				{
				services.lostRecords = false;
				printf("**** Warning: Out of memory: Records have been missed.\n");
				}
			}
		}

	DNSServiceRefDeallocate(sdRef);
	CloseOpenTransport();
	return(0);
	}
Пример #6
0
static void _interruptSafeDispose(void *data)
{
	#if (OP_PLATFORM_MAC_CFM)
		OTFreeMem(data);
	#elif (OP_PLATFORM_WINDOWS)
		GlobalFree((HGLOBAL)data);
	#elif (OP_PLATFORM_UNIX)
		free(data);
	#endif

}
// When the name, address, port, and txtinfo for a service is found, FoundInstanceInfo()
// enqueues a record for PrintServiceInfo() to print.
// Note, a browsing application would *not* normally need to get all this information --
// all it needs is the name, to display to the user.
// Finding out the address, port, and txtinfo should be deferred to the time that the user
// actually needs to contact the service to use it.
static void FoundInstanceInfo(mDNS *const m, ServiceInfoQuery *query)
	{
	SearcherServices *services = (SearcherServices *)query->ServiceInfoQueryContext;
	linkedServiceInfo *info = (linkedServiceInfo *)(query->info);
	if (query->info->ip.type == mDNSAddrType_IPv4)
		{
		mDNS_StopResolveService(m, query);		// For this test code, one answer is sufficient
		OTLIFOEnqueue(&services->serviceinfolist, &info->link);
		OTFreeMem(query);
		}
	}
Пример #8
0
	void OTMemoryReserveTest(void)
		// This routine is designed to help test OTMemoryReserve 
		// by allocating all the memory in the reserve and checking 
		// that it roughly matches the expected size of the reserve.
	{
		OTLink *thisBlock;
		OTList blockList;
		ByteCount bytesAllocated;
		ByteCount targetBytes = (((gReserveChunksAllocated * gReserveChunkSize) * 9) / 10);
		op_assert(gReserveChunkSize != 0);		// You must init the module before doing the test.

		#if (OP_PLATFORM_MAC_CARBON_FLAG)
			return; //cant use OTEnterIntertupt();
		#endif
		
		// Tell OT that weÕre at interrupt time so that it wonÕt 
		// grow the client pool.
		
		#if (!OP_PLATFORM_MAC_CARBON_FLAG)
			OTEnterInterrupt();
		#endif
		
		// Allocate all of the memory that OT will give us - or until we get what we need...
		blockList.fHead = nil;
		bytesAllocated  = 0;
		do {
			thisBlock = (OTLink*)OTAllocMemFromReserve(1024);
			if (thisBlock != nil) {
				OTAddFirst(&blockList, thisBlock);
				bytesAllocated += 1024;
			}
		} while ((thisBlock != nil) && (bytesAllocated < targetBytes));
		
		// Check that itÕs approproximately what the client asked for.
		
		// Note that the * 9 / 10 wonÕt work properly for very large client pools.

		op_assert( bytesAllocated >= targetBytes );

		// Free the memory we allocated.
		
		do {
			thisBlock = OTRemoveFirst(&blockList);
			if (thisBlock != nil) {
				OTFreeMem(thisBlock);
			}
		} while (thisBlock != nil);
		
		#if (!OP_PLATFORM_MAC_CARBON_FLAG)
			OTLeaveInterrupt();		
		#endif
		
	}
Пример #9
0
void TermOTMemoryReserve(void)
	// See comment in interface part.
{
	do {
		OTLink *thisChunk;
		
		thisChunk = OTLIFODequeue(&gMemoryReserve);
		if (thisChunk != nil) {
			OTFreeMem(thisChunk);
		}
	} while ( gMemoryReserve.fHead != nil );
}
// PrintServiceInfo prints the service information to standard out
// A real application might want to do something else with the information
static void PrintServiceInfo(SearcherServices *services)
	{
	OTLink *link = OTReverseList(OTLIFOStealList(&services->serviceinfolist));
	
	while (link)
		{
		linkedServiceInfo *ls = OTGetLinkObject(link, linkedServiceInfo, link);
		ServiceInfo *s = &ls->i;

		if (!services->headerPrinted)
			{
			printf("%-55s Type             Domain         IP Address       Port Info\n", "Name");
			services->headerPrinted = true;
			}

		if (ls->dom)
			{
			char c_dom[MAX_ESCAPED_DOMAIN_NAME];
			ConvertDomainNameToCString(&s->name, c_dom);
			if (ls->add) printf("%-55s available for browsing\n", c_dom);
			else         printf("%-55s no longer available for browsing\n", c_dom);
			}
		else
			{
			domainlabel name;
			domainname type, domain;
			char c_name[MAX_DOMAIN_LABEL+1], c_type[MAX_ESCAPED_DOMAIN_NAME], c_dom[MAX_ESCAPED_DOMAIN_NAME], c_ip[20];
			DeconstructServiceName(&s->name, &name, &type, &domain);
			ConvertDomainLabelToCString_unescaped(&name, c_name);
			ConvertDomainNameToCString(&type, c_type);
			ConvertDomainNameToCString(&domain, c_dom);
			sprintf(c_ip, "%d.%d.%d.%d", s->ip.ip.v4.b[0], s->ip.ip.v4.b[1], s->ip.ip.v4.b[2], s->ip.ip.v4.b[3]);

			printf("%-55s %-16s %-14s ", c_name, c_type, c_dom);
			if (ls->add) printf("%-15s %5d %#s\n", c_ip, mDNSVal16(s->port), s->TXTinfo);
			else         printf("Removed\n");
			}

		link = link->fNext;
		OTFreeMem(ls);
		}
	}
Пример #11
0
void *OTAllocMemFromReserve(OTByteCount size)
	// See comment in interface part.
{
	void *result;
	
	// First try to allocate the memory from the OT client pool.
	// If this succeeds, weÕre done.  If it fails, the failure
	// will trigger OT to try and grow the client pool the next 
	// time SystemTask is called.  However, if the memory reserve 
	// still has memory we free a block of the reserve and retry 
	// the allocation.  Hopefully that will allow the allocation to 
	// succeed.
	//
	// Note that I originally wrapped this in a do {} while loop, 
	// however I deleted that because I figured that all of the 
	// blocks are the same size, so if freeing one block didnÕt 
	// help then freeing another wonÕt help either.  Except 
	// OT might try to coallesce the memory blocks if they live 
	// in the same Mac OS Memory Manager memory block.  However, 
	// they probably wonÕt live in the same Memory Manager block 
	// because the blocks are large.  Regardless, freeing all of 
	// our reserve blocks at once will cause the entire reserve 
	// to go the first time if the client tries to allocate a 
	// block large than our block size, which is not good.
		
	//ECF:  we're doing the while() thing again - since we refill the cache
	// its not terribly catastrophic, and there is a chance it will work...
	
	//if the memory-reserve hasnt been inited yet, just return a normal call
	if (gReserveInited == false)
#ifdef OP_PLATFORM_MAC_CARBON_FLAG
		return OTAllocMemInContext(size,gOTClientContext);
	#else
		return OTAllocMem(size);
#endif
	
	//when running OSX we just return what we get the first time
	#if OP_PLATFORM_MAC_CARBON_FLAG
		if (gRunningOSX)
			return OTAllocMemInContext(size,gOTClientContext);
	
		result = OTAllocMemInContext(size,gOTClientContext);
	#else
		result = OTAllocMem(size);
	#endif
	while (result == nil) {
		OTLink *thisChunk;
		
		//if theres nothing left to release, give up
		if (gReserveChunksAllocated == 0)
			break;
			
		thisChunk = OTLIFODequeue(&gMemoryReserve);
		if (thisChunk != nil) {
			OTFreeMem(thisChunk);
			gReserveChunksAllocated--;
				
			#if (OP_PLATFORM_MAC_CARBON_FLAG)
				result = OTAllocMemInContext(size,gOTClientContext);
			#else
				result = OTAllocMem(size);
			#endif
		}
	}
	
	return result;
}
int main()
	{
	mStatus err;
	Boolean DoneSetup = false;
	void *tempmem;

	SIOUXSettings.asktosaveonclose = false;
	SIOUXSettings.userwindowtitle  = "\pMulticast DNS Searcher";
	SIOUXSettings.rows             = 40;
	SIOUXSettings.columns          = 132;

	printf("Multicast DNS Searcher\n\n");
	printf("This software reports errors using MacsBug breaks,\n");
	printf("so if you don't have MacsBug installed your Mac may crash.\n\n");
	printf("******************************************************************************\n");

	err = InitOpenTransport();
	if (err) { debugf("InitOpenTransport failed %d", err); return(err); }

	err = mDNS_Init(&mDNSStorage, &PlatformSupportStorage, rrcachestorage, RR_CACHE_SIZE,
		mDNS_Init_DontAdvertiseLocalAddresses, mDNS_Init_NoInitCallback, mDNS_Init_NoInitCallbackContext);
	if (err) return(err);

	// Make sure OT has a large enough memory pool for us to draw from at OTNotifier (interrupt) time
	tempmem = OTAllocMem(0x10000);
	if (tempmem) OTFreeMem(tempmem);
	else printf("**** Warning: OTAllocMem couldn't pre-allocate 64K for us.\n");

	services.serviceinfolist.fHead = NULL;
	services.headerPrinted         = false;
	services.lostRecords           = false;

	while (!YieldSomeTime(35))
		{
#if MDNS_ONLYSYSTEMTASK
		// For debugging, use "#define MDNS_ONLYSYSTEMTASK 1" and call mDNSPlatformIdle() periodically.
		// For shipping code, don't define MDNS_ONLYSYSTEMTASK, and you don't need to call mDNSPlatformIdle()
		extern void mDNSPlatformIdle(mDNS *const m);
		mDNSPlatformIdle(&mDNSStorage);	// Only needed for debugging version
#endif
		if (mDNSStorage.mDNSPlatformStatus == mStatus_NoError && !DoneSetup)
			{
			domainname srvtype, srvdom;
			DoneSetup = true;
			printf("\nSending mDNS service lookup queries and waiting for responses...\n\n");
			MakeDomainNameFromDNSNameString(&srvtype, "_http._tcp.");
			MakeDomainNameFromDNSNameString(&srvdom, "local.");
			err = mDNS_StartBrowse(&mDNSStorage, &browsequestion, &srvtype, &srvdom, mDNSInterface_Any, mDNSfalse, FoundInstance, &services);
			if (err) break;
			err = mDNS_GetDomains(&mDNSStorage, &domainquestion, mDNS_DomainTypeBrowse, NULL, mDNSInterface_Any, FoundDomain, &services);
			if (err) break;
			}

		if (services.serviceinfolist.fHead)
			PrintServiceInfo(&services);

		if (services.lostRecords)
			{
			services.lostRecords = false;
			printf("**** Warning: Out of memory: Records have been missed.\n");
			}
		}

	mDNS_StopBrowse(&mDNSStorage, &browsequestion);
	mDNS_Close(&mDNSStorage);
	return(0);
	}