You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1393 lines
44 KiB
1393 lines
44 KiB
/* -*- Mode: C; tab-width: 4 -*-
|
|
*
|
|
* Copyright (c) 2003-2004 Apple Computer, Inc. All rights reserved.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
|
|
*
|
|
* NOTE:
|
|
*
|
|
* These .Net APIs are a work in progress, currently being discussed and refined.
|
|
* If you plan to build an application based on these APIs, you may wish to
|
|
* statically link this code into your application, or otherwise distribute
|
|
* the DLL so that it installs into the same folder as your application
|
|
* (not into any common system area where it might interfere with other
|
|
* applications using a future completed version of these APIs).
|
|
* If you plan to do this, please be sure to inform us by sending email
|
|
* to bonjour@apple.com to let us know.
|
|
* You may want to discuss what you're doing on the Bonjour mailing
|
|
* list to see if others in similar positions have any suggestions for you:
|
|
*
|
|
* <http://lists.apple.com/bonjour-dev/>
|
|
*
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <dns_sd.h>
|
|
#include <vcclr.h>
|
|
#include <memory>
|
|
#include <winsock2.h>
|
|
|
|
using namespace System;
|
|
using namespace System::Net;
|
|
using namespace System::Runtime::InteropServices;
|
|
using namespace System::Threading;
|
|
using namespace System::Collections;
|
|
|
|
|
|
namespace Apple
|
|
{
|
|
namespace DNSSD
|
|
{
|
|
public __gc class ServiceRef;
|
|
|
|
public __value enum ServiceFlags : int
|
|
{
|
|
MoreComing = 1,
|
|
/* MoreComing indicates to a callback that at least one more result is
|
|
* queued and will be delivered following immediately after this one.
|
|
* Applications should not update their UI to display browse
|
|
* results when the MoreComing flag is set, because this would
|
|
* result in a great deal of ugly flickering on the screen.
|
|
* Applications should instead wait until until MoreComing is not set,
|
|
* and then update their UI.
|
|
* When MoreComing is not set, that doesn't mean there will be no more
|
|
* answers EVER, just that there are no more answers immediately
|
|
* available right now at this instant. If more answers become available
|
|
* in the future they will be delivered as usual.
|
|
*/
|
|
|
|
Add = 2,
|
|
Default = 4,
|
|
/* Flags for domain enumeration and browse/query reply callbacks.
|
|
* "Default" applies only to enumeration and is only valid in
|
|
* conjuction with "Add". An enumeration callback with the "Add"
|
|
* flag NOT set indicates a "Remove", i.e. the domain is no longer
|
|
* valid.
|
|
*/
|
|
|
|
NoAutoRename = 8,
|
|
/* Flag for specifying renaming behavior on name conflict when registering
|
|
* non-shared records. By default, name conflicts are automatically handled
|
|
* by renaming the service. NoAutoRename overrides this behavior - with this
|
|
* flag set, name conflicts will result in a callback. The NoAutorename flag
|
|
* is only valid if a name is explicitly specified when registering a service
|
|
* (i.e. the default name is not used.)
|
|
*/
|
|
|
|
Shared = 16,
|
|
Unique = 32,
|
|
/* Flag for registering individual records on a connected
|
|
* DNSServiceRef. Shared indicates that there may be multiple records
|
|
* with this name on the network (e.g. PTR records). Unique indicates that
|
|
the
|
|
* record's name is to be unique on the network (e.g. SRV records).
|
|
*/
|
|
|
|
BrowseDomains = 64,
|
|
RegistrationDomains = 128,
|
|
/* Flags for specifying domain enumeration type in DNSServiceEnumerateDomain
|
|
s.
|
|
* BrowseDomains enumerates domains recommended for browsing, RegistrationDo
|
|
mains
|
|
* enumerates domains recommended for registration.
|
|
*/
|
|
};
|
|
|
|
|
|
public __value enum ErrorCode : int
|
|
{
|
|
NoError = 0,
|
|
Unknown = -65537,
|
|
NoSuchName = -65538,
|
|
NoMemory = -65539,
|
|
BadParam = -65540,
|
|
BadReference = -65541,
|
|
BadState = -65542,
|
|
BadFlags = -65543,
|
|
Unsupported = -65544,
|
|
AlreadyRegistered = -65547,
|
|
NameConflict = -65548,
|
|
Invalid = -65549,
|
|
Incompatible = -65551,
|
|
BadinterfaceIndex = -65552
|
|
|
|
/*
|
|
* mDNS Error codes are in the range
|
|
* FFFE FF00 (-65792) to FFFE FFFF (-65537)
|
|
*/
|
|
};
|
|
|
|
public __gc class DNSServiceException
|
|
:
|
|
public Exception
|
|
{
|
|
public:
|
|
|
|
DNSServiceException
|
|
(
|
|
int err
|
|
);
|
|
|
|
DNSServiceException
|
|
(
|
|
String * message,
|
|
System::Exception * innerException
|
|
);
|
|
|
|
int err;
|
|
};
|
|
|
|
|
|
/*
|
|
* class RecordRef
|
|
*
|
|
* This is a thin MC++ class facade on top of a DNSRecordRef
|
|
*/
|
|
public __gc class RecordRef
|
|
{
|
|
public:
|
|
|
|
RecordRef()
|
|
{
|
|
m_impl = new RecordRefImpl;
|
|
m_impl->m_ref = NULL;
|
|
}
|
|
|
|
~RecordRef()
|
|
{
|
|
delete m_impl;
|
|
}
|
|
|
|
__nogc class RecordRefImpl
|
|
{
|
|
public:
|
|
|
|
DNSRecordRef m_ref;
|
|
};
|
|
|
|
RecordRefImpl * m_impl;
|
|
};
|
|
|
|
|
|
/*
|
|
* class ServiceRef
|
|
*
|
|
* This is a thin MC++ class facade on top of a DNSServiceRef
|
|
*/
|
|
public __gc class ServiceRef : public IDisposable
|
|
{
|
|
public:
|
|
|
|
ServiceRef(Object * callback);
|
|
|
|
~ServiceRef();
|
|
|
|
/*
|
|
* This does an underlying DNSServiceRefDeallocate(). After
|
|
* calling Dispose, the ServiceRef is no longer usable.
|
|
*/
|
|
void
|
|
Dispose();
|
|
|
|
/*
|
|
* Internal - Dispatch an EnumerateDomains callback
|
|
*/
|
|
void
|
|
EnumerateDomainsDispatch
|
|
(
|
|
ServiceFlags flags,
|
|
int interfaceIndex,
|
|
ErrorCode errorCode,
|
|
String * replyDomain
|
|
);
|
|
|
|
/*
|
|
* Internal - Dispatch a Register callback
|
|
*/
|
|
void
|
|
RegisterDispatch
|
|
(
|
|
ServiceFlags flags,
|
|
ErrorCode errorCode,
|
|
String * name,
|
|
String * regtype,
|
|
String * domain
|
|
);
|
|
|
|
/*
|
|
* Internal - Dispatch a Browse callback
|
|
*/
|
|
void
|
|
BrowseDispatch
|
|
(
|
|
ServiceFlags flags,
|
|
int interfaceIndex,
|
|
ErrorCode errorCode,
|
|
String * serviceName,
|
|
String * regtype,
|
|
String * replyDomain
|
|
);
|
|
|
|
/*
|
|
* Internal - Dispatch a Resolve callback
|
|
*/
|
|
void
|
|
ResolveDispatch
|
|
(
|
|
ServiceFlags flags,
|
|
int interfaceIndex,
|
|
ErrorCode errorCode,
|
|
String * fullname,
|
|
String * hosttarget,
|
|
int port,
|
|
Byte txtRecord[]
|
|
);
|
|
|
|
/*
|
|
* Internal - Dispatch a RegisterRecord callback
|
|
*/
|
|
void
|
|
RegisterRecordDispatch
|
|
(
|
|
ServiceFlags flags,
|
|
ErrorCode errorCode,
|
|
RecordRef * record
|
|
);
|
|
|
|
/*
|
|
* Internal - Dispatch a QueryRecord callback
|
|
*/
|
|
void
|
|
QueryRecordDispatch
|
|
(
|
|
ServiceFlags flags,
|
|
int interfaceIndex,
|
|
ErrorCode errorCode,
|
|
String * fullname,
|
|
int rrtype,
|
|
int rrclass,
|
|
Byte rdata[],
|
|
int ttl
|
|
);
|
|
|
|
/*
|
|
* Internal - A non managed class to wrap a DNSServiceRef
|
|
*/
|
|
__nogc class ServiceRefImpl
|
|
{
|
|
public:
|
|
|
|
ServiceRefImpl
|
|
(
|
|
ServiceRef * outer
|
|
);
|
|
|
|
~ServiceRefImpl();
|
|
|
|
/*
|
|
* Sets up events for threaded operation
|
|
*/
|
|
void
|
|
SetupEvents();
|
|
|
|
/*
|
|
* Main processing thread
|
|
*/
|
|
void
|
|
ProcessingThread();
|
|
|
|
/*
|
|
* Calls DNSServiceRefDeallocate()
|
|
*/
|
|
void
|
|
Dispose();
|
|
|
|
/*
|
|
* Called from dnssd.dll
|
|
*/
|
|
static void DNSSD_API
|
|
EnumerateDomainsCallback
|
|
(
|
|
DNSServiceRef sdRef,
|
|
DNSServiceFlags flags,
|
|
uint32_t interfaceIndex,
|
|
DNSServiceErrorType errorCode,
|
|
const char * replyDomain,
|
|
void * context
|
|
);
|
|
|
|
static void DNSSD_API
|
|
RegisterCallback
|
|
(
|
|
DNSServiceRef ref,
|
|
DNSServiceFlags flags,
|
|
DNSServiceErrorType errorCode,
|
|
const char * name,
|
|
const char * regtype,
|
|
const char * domain,
|
|
void * context
|
|
);
|
|
|
|
static void DNSSD_API
|
|
BrowseCallback
|
|
(
|
|
DNSServiceRef sdRef,
|
|
DNSServiceFlags flags,
|
|
uint32_t interfaceIndex,
|
|
DNSServiceErrorType errorCode,
|
|
const char * serviceName,
|
|
const char * regtype,
|
|
const char * replyDomain,
|
|
void * context
|
|
);
|
|
|
|
static void DNSSD_API
|
|
ResolveCallback
|
|
(
|
|
DNSServiceRef sdRef,
|
|
DNSServiceFlags flags,
|
|
uint32_t interfaceIndex,
|
|
DNSServiceErrorType errorCode,
|
|
const char * fullname,
|
|
const char * hosttarget,
|
|
uint16_t notAnIntPort,
|
|
uint16_t txtLen,
|
|
const char * txtRecord,
|
|
void * context
|
|
);
|
|
|
|
static void DNSSD_API
|
|
RegisterRecordCallback
|
|
(
|
|
DNSServiceRef sdRef,
|
|
DNSRecordRef RecordRef,
|
|
DNSServiceFlags flags,
|
|
DNSServiceErrorType errorCode,
|
|
void * context
|
|
);
|
|
|
|
static void DNSSD_API
|
|
QueryRecordCallback
|
|
(
|
|
DNSServiceRef DNSServiceRef,
|
|
DNSServiceFlags flags,
|
|
uint32_t interfaceIndex,
|
|
DNSServiceErrorType errorCode,
|
|
const char * fullname,
|
|
uint16_t rrtype,
|
|
uint16_t rrclass,
|
|
uint16_t rdlen,
|
|
const void * rdata,
|
|
uint32_t ttl,
|
|
void * context
|
|
);
|
|
|
|
SOCKET m_socket;
|
|
HANDLE m_socketEvent;
|
|
HANDLE m_stopEvent;
|
|
DWORD m_threadId;
|
|
bool m_disposed;
|
|
DNSServiceRef m_ref;
|
|
gcroot<ServiceRef*> m_outer;
|
|
};
|
|
|
|
void
|
|
StartThread();
|
|
|
|
void
|
|
ProcessingThread();
|
|
|
|
bool m_bDisposed;
|
|
Object * m_callback;
|
|
Thread * m_thread;
|
|
ServiceRefImpl * m_impl;
|
|
};
|
|
|
|
/*********************************************************************************************
|
|
*
|
|
* TXT Record Construction Functions
|
|
*
|
|
*********************************************************************************************/
|
|
|
|
/*
|
|
* A typical calling sequence for TXT record construction is something like:
|
|
*
|
|
* DNSService.TextRecord tr = new DNSService.TextRecord(1024);
|
|
* tr.SetValue();
|
|
* tr.SetValue();
|
|
* tr.SetValue();
|
|
* ...
|
|
* DNSServiceRegister( ... tr.GetLength(), tr.GetBytes() ... );
|
|
*/
|
|
|
|
|
|
/* TextRecord
|
|
*
|
|
* Opaque internal data type.
|
|
* Note: Represents a DNS-SD TXT record.
|
|
*/
|
|
|
|
|
|
/* TextRecord::TextRecord()
|
|
*
|
|
* Creates a new empty TextRecord .
|
|
*
|
|
*/
|
|
|
|
public __gc class TextRecord
|
|
{
|
|
public:
|
|
|
|
TextRecord()
|
|
{
|
|
m_impl = new TextRecordImpl();
|
|
TXTRecordCreate(&m_impl->m_ref, 0, NULL);
|
|
}
|
|
|
|
~TextRecord()
|
|
{
|
|
TXTRecordDeallocate(&m_impl->m_ref);
|
|
delete m_impl;
|
|
}
|
|
|
|
__nogc class TextRecordImpl
|
|
{
|
|
public:
|
|
|
|
TXTRecordRef m_ref;
|
|
};
|
|
|
|
TextRecordImpl * m_impl;
|
|
|
|
|
|
/* SetValue()
|
|
*
|
|
* Adds a key (optionally with value) to a TextRecord. If the "key" already
|
|
* exists in the TextRecord, then the current value will be replaced with
|
|
* the new value.
|
|
* Keys may exist in four states with respect to a given TXT record:
|
|
* - Absent (key does not appear at all)
|
|
* - Present with no value ("key" appears alone)
|
|
* - Present with empty value ("key=" appears in TXT record)
|
|
* - Present with non-empty value ("key=value" appears in TXT record)
|
|
* For more details refer to "Data Syntax for DNS-SD TXT Records" in
|
|
* <http://files.dns-sd.org/draft-cheshire-dnsext-dns-sd.txt>
|
|
*
|
|
* key: A null-terminated string which only contains printable ASCII
|
|
* values (0x20-0x7E), excluding '=' (0x3D). Keys should be
|
|
* 14 characters or less (not counting the terminating null).
|
|
*
|
|
* value: Any binary value. For values that represent
|
|
* textual data, UTF-8 is STRONGLY recommended.
|
|
* For values that represent textual data, valueSize
|
|
* should NOT include the terminating null (if any)
|
|
* at the end of the string.
|
|
* If NULL, then "key" will be added with no value.
|
|
* If non-NULL but valueSize is zero, then "key=" will be
|
|
* added with empty value.
|
|
*
|
|
* exceptions: Throws kDNSServiceErr_Invalid if the "key" string contains
|
|
* illegal characters.
|
|
* Throws kDNSServiceErr_NoMemory if adding this key would
|
|
* exceed the available storage.
|
|
*/
|
|
|
|
void
|
|
SetValue
|
|
(
|
|
String * key,
|
|
Byte value[] /* may be NULL */
|
|
);
|
|
|
|
|
|
/* RemoveValue()
|
|
*
|
|
* Removes a key from a TextRecord. The "key" must be an
|
|
* ASCII string which exists in the TextRecord.
|
|
*
|
|
* key: A key name which exists in the TextRecord.
|
|
*
|
|
* exceptions: Throws kDNSServiceErr_NoSuchKey if the "key" does not
|
|
* exist in the TextRecord.
|
|
*
|
|
*/
|
|
|
|
void
|
|
RemoveValue
|
|
(
|
|
String * key
|
|
);
|
|
|
|
|
|
/* GetLength()
|
|
*
|
|
* Allows you to determine the length of the raw bytes within a TextRecord.
|
|
*
|
|
* return value : Returns the size of the raw bytes inside a TextRecord
|
|
* which you can pass directly to DNSServiceRegister() or
|
|
* to DNSServiceUpdateRecord().
|
|
* Returns 0 if the TextRecord is empty.
|
|
*
|
|
*/
|
|
|
|
int
|
|
GetLength
|
|
(
|
|
);
|
|
|
|
|
|
/* GetBytes()
|
|
*
|
|
* Allows you to retrieve a pointer to the raw bytes within a TextRecord.
|
|
*
|
|
* return value: Returns a pointer to the bytes inside the TextRecord
|
|
* which you can pass directly to DNSServiceRegister() or
|
|
* to DNSServiceUpdateRecord().
|
|
*
|
|
*/
|
|
|
|
Byte
|
|
GetBytes
|
|
(
|
|
) __gc[];
|
|
|
|
|
|
/*********************************************************************************************
|
|
*
|
|
* TXT Record Parsing Functions
|
|
*
|
|
*********************************************************************************************/
|
|
|
|
/*
|
|
* A typical calling sequence for TXT record parsing is something like:
|
|
*
|
|
* Receive TXT record data in DNSServiceResolve() callback
|
|
* if (TXTRecordContainsKey(txtLen, txtRecord, "key")) then do something
|
|
* val1ptr = DNSService.TextService.GetValue(txtRecord, "key1", &len1);
|
|
* val2ptr = DNSService.TextService.GetValue(txtRecord, "key2", &len2);
|
|
* ...
|
|
* return;
|
|
*
|
|
*/
|
|
|
|
/* ContainsKey()
|
|
*
|
|
* Allows you to determine if a given TXT Record contains a specified key.
|
|
*
|
|
* txtRecord: Pointer to the received TXT Record bytes.
|
|
*
|
|
* key: A null-terminated ASCII string containing the key name.
|
|
*
|
|
* return value: Returns 1 if the TXT Record contains the specified key.
|
|
* Otherwise, it returns 0.
|
|
*
|
|
*/
|
|
|
|
static public bool
|
|
ContainsKey
|
|
(
|
|
Byte txtRecord[],
|
|
String * key
|
|
);
|
|
|
|
|
|
/* GetValueBytes()
|
|
*
|
|
* Allows you to retrieve the value for a given key from a TXT Record.
|
|
*
|
|
* txtRecord: Pointer to the received TXT Record bytes.
|
|
*
|
|
* key: A null-terminated ASCII string containing the key name.
|
|
*
|
|
* return value: Returns NULL if the key does not exist in this TXT record,
|
|
* or exists with no value (to differentiate between
|
|
* these two cases use ContainsKey()).
|
|
* Returns byte array
|
|
* if the key exists with empty or non-empty value.
|
|
* For empty value, length of byte array will be zero.
|
|
* For non-empty value, it will be the length of value data.
|
|
*/
|
|
|
|
static public Byte
|
|
GetValueBytes
|
|
(
|
|
Byte txtRecord[],
|
|
String * key
|
|
) __gc[];
|
|
|
|
|
|
/* GetCount()
|
|
*
|
|
* Returns the number of keys stored in the TXT Record. The count
|
|
* can be used with TXTRecordGetItemAtIndex() to iterate through the keys.
|
|
*
|
|
* txtRecord: Pointer to the received TXT Record bytes.
|
|
*
|
|
* return value: Returns the total number of keys in the TXT Record.
|
|
*
|
|
*/
|
|
|
|
static public int
|
|
GetCount
|
|
(
|
|
Byte txtRecord[]
|
|
);
|
|
|
|
|
|
/* GetItemAtIndex()
|
|
*
|
|
* Allows you to retrieve a key name and value pointer, given an index into
|
|
* a TXT Record. Legal index values range from zero to TXTRecordGetCount()-1.
|
|
* It's also possible to iterate through keys in a TXT record by simply
|
|
* calling TXTRecordGetItemAtIndex() repeatedly, beginning with index zero
|
|
* and increasing until TXTRecordGetItemAtIndex() returns kDNSServiceErr_Invalid.
|
|
*
|
|
* On return:
|
|
* For keys with no value, *value is set to NULL and *valueLen is zero.
|
|
* For keys with empty value, *value is non-NULL and *valueLen is zero.
|
|
* For keys with non-empty value, *value is non-NULL and *valueLen is non-zero.
|
|
*
|
|
* txtRecord: Pointer to the received TXT Record bytes.
|
|
*
|
|
* index: An index into the TXT Record.
|
|
*
|
|
* key: A string buffer used to store the key name.
|
|
* On return, the buffer contains a string
|
|
* giving the key name. DNS-SD TXT keys are usually
|
|
* 14 characters or less.
|
|
*
|
|
* return value: Record bytes that holds the value data.
|
|
*
|
|
* exceptions: Throws kDNSServiceErr_Invalid if index is greater than
|
|
* GetCount()-1.
|
|
*/
|
|
|
|
static public Byte
|
|
GetItemAtIndex
|
|
(
|
|
Byte txtRecord[],
|
|
int index,
|
|
[Out] String ** key
|
|
) __gc[];
|
|
};
|
|
|
|
|
|
public __abstract __gc class DNSService
|
|
{
|
|
public:
|
|
|
|
/*********************************************************************************************
|
|
*
|
|
* Domain Enumeration
|
|
*
|
|
*********************************************************************************************/
|
|
|
|
/* DNSServiceEnumerateDomains()
|
|
*
|
|
* Asynchronously enumerate domains available for browsing and registration.
|
|
* Currently, the only domain returned is "local.", but other domains will be returned in future.
|
|
*
|
|
* The enumeration MUST be cancelled via DNSServiceRefDeallocate() when no more domains
|
|
* are to be found.
|
|
*
|
|
*
|
|
* EnumerateDomainsReply Delegate
|
|
*
|
|
* This Delegate is invoked upon a reply from an EnumerateDomains call.
|
|
*
|
|
* sdRef: The DNSServiceRef initialized by DNSServiceEnumerateDomains().
|
|
*
|
|
* flags: Possible values are:
|
|
* MoreComing
|
|
* Add
|
|
* Default
|
|
*
|
|
* interfaceIndex: Specifies the interface on which the domain exists. (The index for a given
|
|
* interface is determined via the if_nametoindex() family of calls.)
|
|
*
|
|
* errorCode: Will be NoError (0) on success, otherwise indicates
|
|
* the failure that occurred (other parameters are undefined if errorCode is nonzero).
|
|
*
|
|
* replyDomain: The name of the domain.
|
|
*
|
|
*/
|
|
|
|
__delegate void
|
|
EnumerateDomainsReply
|
|
(
|
|
ServiceRef * sdRef,
|
|
ServiceFlags flags,
|
|
int interfaceIndex,
|
|
ErrorCode errorCode,
|
|
String * replyDomain
|
|
);
|
|
|
|
/* DNSServiceEnumerateDomains() Parameters:
|
|
*
|
|
*
|
|
* flags: Possible values are:
|
|
* BrowseDomains to enumerate domains recommended for browsing.
|
|
* RegistrationDomains to enumerate domains recommended
|
|
* for registration.
|
|
*
|
|
* interfaceIndex: If non-zero, specifies the interface on which to look for domains.
|
|
* (the index for a given interface is determined via the if_nametoindex()
|
|
* family of calls.) Most applications will pass 0 to enumerate domains on
|
|
* all interfaces.
|
|
*
|
|
* callback: The delegate to be called when a domain is found or the call asynchronously
|
|
* fails.
|
|
*
|
|
*
|
|
* return value: Returns initialize ServiceRef on succeses (any subsequent, asynchronous
|
|
* errors are delivered to the delegate), otherwise throws an exception indicating
|
|
* the error that occurred (the callback is not invoked and the ServiceRef
|
|
* is not initialized.)
|
|
*/
|
|
|
|
static public ServiceRef*
|
|
EnumerateDomains
|
|
(
|
|
int flags,
|
|
int interfaceIndex,
|
|
EnumerateDomainsReply * callback
|
|
);
|
|
|
|
/*********************************************************************************************
|
|
*
|
|
* Service Registration
|
|
*
|
|
*********************************************************************************************/
|
|
|
|
/* Register a service that is discovered via Browse() and Resolve() calls.
|
|
*
|
|
* RegisterReply() Callback Parameters:
|
|
*
|
|
* sdRef: The ServiceRef initialized by Register().
|
|
*
|
|
* flags: Currently unused, reserved for future use.
|
|
*
|
|
* errorCode: Will be NoError on success, otherwise will
|
|
* indicate the failure that occurred (including name conflicts, if the
|
|
* NoAutoRename flag was passed to the
|
|
* callout.) Other parameters are undefined if errorCode is nonzero.
|
|
*
|
|
* name: The service name registered (if the application did not specify a name in
|
|
* DNSServiceRegister(), this indicates what name was automatically chosen).
|
|
*
|
|
* regtype: The type of service registered, as it was passed to the callout.
|
|
*
|
|
* domain: The domain on which the service was registered (if the application did not
|
|
* specify a domain in Register(), this indicates the default domain
|
|
* on which the service was registered).
|
|
*
|
|
*/
|
|
|
|
__delegate void
|
|
RegisterReply
|
|
(
|
|
ServiceRef * sdRef,
|
|
ServiceFlags flags,
|
|
ErrorCode errorCode,
|
|
String * name,
|
|
String * regtype,
|
|
String * domain
|
|
);
|
|
|
|
/* Register() Parameters:
|
|
*
|
|
* flags: Indicates the renaming behavior on name conflict (most applications
|
|
* will pass 0). See flag definitions above for details.
|
|
*
|
|
* interfaceIndex: If non-zero, specifies the interface on which to register the service
|
|
* (the index for a given interface is determined via the if_nametoindex()
|
|
* family of calls.) Most applications will pass 0 to register on all
|
|
* available interfaces. Pass -1 to register a service only on the local
|
|
* machine (service will not be visible to remote hosts.)
|
|
*
|
|
* name: If non-NULL, specifies the service name to be registered.
|
|
* Most applications will not specify a name, in which case the
|
|
* computer name is used (this name is communicated to the client via
|
|
* the callback).
|
|
*
|
|
* regtype: The service type followed by the protocol, separated by a dot
|
|
* (e.g. "_ftp._tcp"). The transport protocol must be "_tcp" or "_udp".
|
|
* New service types should be registered at htp://www.dns-sd.org/ServiceTypes.html.
|
|
*
|
|
* domain: If non-NULL, specifies the domain on which to advertise the service.
|
|
* Most applications will not specify a domain, instead automatically
|
|
* registering in the default domain(s).
|
|
*
|
|
* host: If non-NULL, specifies the SRV target host name. Most applications
|
|
* will not specify a host, instead automatically using the machine's
|
|
* default host name(s). Note that specifying a non-NULL host does NOT
|
|
* create an address record for that host - the application is responsible
|
|
* for ensuring that the appropriate address record exists, or creating it
|
|
* via DNSServiceRegisterRecord().
|
|
*
|
|
* port: The port, in host byte order, on which the service accepts connections.
|
|
* Pass 0 for a "placeholder" service (i.e. a service that will not be discovered
|
|
* by browsing, but will cause a name conflict if another client tries to
|
|
* register that same name). Most clients will not use placeholder services.
|
|
*
|
|
* txtRecord: The txt record rdata. May be NULL. Note that a non-NULL txtRecord
|
|
* MUST be a properly formatted DNS TXT record, i.e. <length byte> <data>
|
|
* <length byte> <data> ...
|
|
*
|
|
* callback: The delegate to be called when the registration completes or asynchronously
|
|
* fails. The client MAY pass NULL for the callback - The client will NOT be notified
|
|
* of the default values picked on its behalf, and the client will NOT be notified of any
|
|
* asynchronous errors (e.g. out of memory errors, etc.) that may prevent the registration
|
|
* of the service. The client may NOT pass the NoAutoRename flag if the callback is NULL.
|
|
* The client may still deregister the service at any time via DNSServiceRefDeallocate().
|
|
*
|
|
* return value: Returns initialize ServiceRef (any subsequent, asynchronous
|
|
* errors are delivered to the callback), otherwise throws an exception indicating
|
|
* the error that occurred (the callback is never invoked and the DNSServiceRef
|
|
* is not initialized.)
|
|
*
|
|
*/
|
|
static public ServiceRef*
|
|
Register
|
|
(
|
|
int flags,
|
|
int interfaceIndex,
|
|
String * name,
|
|
String * regtype,
|
|
String * domain,
|
|
String * host,
|
|
int port,
|
|
Byte txtRecord[],
|
|
RegisterReply * callback
|
|
);
|
|
|
|
/* AddRecord()
|
|
*
|
|
* Add a record to a registered service. The name of the record will be the same as the
|
|
* registered service's name.
|
|
* The record can later be updated or deregistered by passing the RecordRef initialized
|
|
* by this function to UpdateRecord() or RemoveRecord().
|
|
*
|
|
*
|
|
* Parameters;
|
|
*
|
|
* sdRef: A ServiceRef initialized by Register().
|
|
*
|
|
* RecordRef: A pointer to an uninitialized RecordRef. Upon succesfull completion of this
|
|
* call, this ref may be passed to UpdateRecord() or RemoveRecord().
|
|
* If the above ServiceRef is disposed, RecordRef is also
|
|
* invalidated and may not be used further.
|
|
*
|
|
* flags: Currently ignored, reserved for future use.
|
|
*
|
|
* rrtype: The type of the record (e.g. TXT, SRV, etc), as defined in nameser.h.
|
|
*
|
|
* rdata: The raw rdata to be contained in the added resource record.
|
|
*
|
|
* ttl: The time to live of the resource record, in seconds.
|
|
*
|
|
* return value: Returns initialized RecordRef, otherwise throws
|
|
* an exception indicating the error that occurred (the RecordRef is not initialized).
|
|
*/
|
|
|
|
static public RecordRef*
|
|
AddRecord
|
|
(
|
|
ServiceRef * sref,
|
|
int flags,
|
|
int rrtype,
|
|
Byte rdata[],
|
|
int ttl
|
|
);
|
|
|
|
/* UpdateRecord
|
|
*
|
|
* Update a registered resource record. The record must either be:
|
|
* - The primary txt record of a service registered via Register()
|
|
* - A record added to a registered service via AddRecord()
|
|
* - An individual record registered by RegisterRecord()
|
|
*
|
|
*
|
|
* Parameters:
|
|
*
|
|
* sdRef: A ServiceRef that was initialized by Register()
|
|
* or CreateConnection().
|
|
*
|
|
* RecordRef: A RecordRef initialized by AddRecord, or NULL to update the
|
|
* service's primary txt record.
|
|
*
|
|
* flags: Currently ignored, reserved for future use.
|
|
*
|
|
* rdata: The new rdata to be contained in the updated resource record.
|
|
*
|
|
* ttl: The time to live of the updated resource record, in seconds.
|
|
*
|
|
* return value: No return value on success, otherwise throws an exception
|
|
* indicating the error that occurred.
|
|
*/
|
|
static public void
|
|
UpdateRecord
|
|
(
|
|
ServiceRef * sref,
|
|
RecordRef * record,
|
|
int flags,
|
|
Byte rdata[],
|
|
int ttl
|
|
);
|
|
|
|
/* RemoveRecord
|
|
*
|
|
* Remove a record previously added to a service record set via AddRecord(), or deregister
|
|
* an record registered individually via RegisterRecord().
|
|
*
|
|
* Parameters:
|
|
*
|
|
* sdRef: A ServiceRef initialized by Register() (if the
|
|
* record being removed was registered via AddRecord()) or by
|
|
* CreateConnection() (if the record being removed was registered via
|
|
* RegisterRecord()).
|
|
*
|
|
* recordRef: A RecordRef initialized by a successful call to AddRecord()
|
|
* or RegisterRecord().
|
|
*
|
|
* flags: Currently ignored, reserved for future use.
|
|
*
|
|
* return value: Nothing on success, otherwise throws an
|
|
* exception indicating the error that occurred.
|
|
*/
|
|
|
|
static public void
|
|
RemoveRecord
|
|
(
|
|
ServiceRef * sref,
|
|
RecordRef * record,
|
|
int flags
|
|
);
|
|
|
|
/*********************************************************************************************
|
|
*
|
|
* Service Discovery
|
|
*
|
|
*********************************************************************************************/
|
|
|
|
/* Browse for instances of a service.
|
|
*
|
|
*
|
|
* BrowseReply() Parameters:
|
|
*
|
|
* sdRef: The DNSServiceRef initialized by Browse().
|
|
*
|
|
* flags: Possible values are MoreComing and Add.
|
|
* See flag definitions for details.
|
|
*
|
|
* interfaceIndex: The interface on which the service is advertised. This index should
|
|
* be passed to Resolve() when resolving the service.
|
|
*
|
|
* errorCode: Will be NoError (0) on success, otherwise will
|
|
* indicate the failure that occurred. Other parameters are undefined if
|
|
* the errorCode is nonzero.
|
|
*
|
|
* serviceName: The service name discovered.
|
|
*
|
|
* regtype: The service type, as passed in to Browse().
|
|
*
|
|
* domain: The domain on which the service was discovered (if the application did not
|
|
* specify a domain in Browse(), this indicates the domain on which the
|
|
* service was discovered.)
|
|
*
|
|
*/
|
|
|
|
__delegate void
|
|
BrowseReply
|
|
(
|
|
ServiceRef * sdRef,
|
|
ServiceFlags flags,
|
|
int interfaceIndex,
|
|
ErrorCode errorCode,
|
|
String * name,
|
|
String * type,
|
|
String * domain
|
|
);
|
|
|
|
/* DNSServiceBrowse() Parameters:
|
|
*
|
|
* sdRef: A pointer to an uninitialized ServiceRef. Call ServiceRef.Dispose()
|
|
* to terminate the browse.
|
|
*
|
|
* flags: Currently ignored, reserved for future use.
|
|
*
|
|
* interfaceIndex: If non-zero, specifies the interface on which to browse for services
|
|
* (the index for a given interface is determined via the if_nametoindex()
|
|
* family of calls.) Most applications will pass 0 to browse on all available
|
|
* interfaces. Pass -1 to only browse for services provided on the local host.
|
|
*
|
|
* regtype: The service type being browsed for followed by the protocol, separated by a
|
|
* dot (e.g. "_ftp._tcp"). The transport protocol must be "_tcp" or "_udp".
|
|
*
|
|
* domain: If non-NULL, specifies the domain on which to browse for services.
|
|
* Most applications will not specify a domain, instead browsing on the
|
|
* default domain(s).
|
|
*
|
|
* callback: The delegate to be called when an instance of the service being browsed for
|
|
* is found, or if the call asynchronously fails.
|
|
*
|
|
* return value: Returns initialized ServiceRef on succeses (any subsequent, asynchronous
|
|
* errors are delivered to the callback), otherwise throws an exception indicating
|
|
* the error that occurred (the callback is not invoked and the ServiceRef
|
|
* is not initialized.)
|
|
*/
|
|
|
|
static public ServiceRef*
|
|
Browse
|
|
(
|
|
int flags,
|
|
int interfaceIndex,
|
|
String * regtype,
|
|
String * domain,
|
|
BrowseReply * callback
|
|
);
|
|
|
|
/* ResolveReply() Parameters:
|
|
*
|
|
* Resolve a service name discovered via Browse() to a target host name, port number, and
|
|
* txt record.
|
|
*
|
|
* Note: Applications should NOT use Resolve() solely for txt record monitoring - use
|
|
* QueryRecord() instead, as it is more efficient for this task.
|
|
*
|
|
* Note: When the desired results have been returned, the client MUST terminate the resolve by calling
|
|
* ServiceRef.Dispose().
|
|
*
|
|
* Note: Resolve() behaves correctly for typical services that have a single SRV record and
|
|
* a single TXT record (the TXT record may be empty.) To resolve non-standard services with multiple
|
|
* SRV or TXT records, QueryRecord() should be used.
|
|
*
|
|
* ResolveReply Callback Parameters:
|
|
*
|
|
* sdRef: The DNSServiceRef initialized by Resolve().
|
|
*
|
|
* flags: Currently unused, reserved for future use.
|
|
*
|
|
* interfaceIndex: The interface on which the service was resolved.
|
|
*
|
|
* errorCode: Will be NoError (0) on success, otherwise will
|
|
* indicate the failure that occurred. Other parameters are undefined if
|
|
* the errorCode is nonzero.
|
|
*
|
|
* fullname: The full service domain name, in the form <servicename>.<protocol>.<domain>.
|
|
* (Any literal dots (".") are escaped with a backslash ("\."), and literal
|
|
* backslashes are escaped with a second backslash ("\\"), e.g. a web server
|
|
* named "Dr. Pepper" would have the fullname "Dr\.\032Pepper._http._tcp.local.").
|
|
* This is the appropriate format to pass to standard system DNS APIs such as
|
|
* res_query(), or to the special-purpose functions included in this API that
|
|
* take fullname parameters.
|
|
*
|
|
* hosttarget: The target hostname of the machine providing the service. This name can
|
|
* be passed to functions like gethostbyname() to identify the host's IP address.
|
|
*
|
|
* port: The port, in host byte order, on which connections are accepted for this service.
|
|
*
|
|
* txtRecord: The service's primary txt record, in standard txt record format.
|
|
*
|
|
*/
|
|
|
|
__delegate void
|
|
ResolveReply
|
|
(
|
|
ServiceRef * sdRef,
|
|
ServiceFlags flags,
|
|
int interfaceIndex,
|
|
ErrorCode errorCode,
|
|
String * fullName,
|
|
String * hostName,
|
|
int port,
|
|
Byte txtRecord[]
|
|
);
|
|
|
|
/* Resolve() Parameters
|
|
*
|
|
* flags: Currently ignored, reserved for future use.
|
|
*
|
|
* interfaceIndex: The interface on which to resolve the service. The client should
|
|
* pass the interface on which the servicename was discovered, i.e.
|
|
* the interfaceIndex passed to the DNSServiceBrowseReply callback,
|
|
* or 0 to resolve the named service on all available interfaces.
|
|
*
|
|
* name: The servicename to be resolved.
|
|
*
|
|
* regtype: The service type being resolved followed by the protocol, separated by a
|
|
* dot (e.g. "_ftp._tcp"). The transport protocol must be "_tcp" or "_udp".
|
|
*
|
|
* domain: The domain on which the service is registered, i.e. the domain passed
|
|
* to the DNSServiceBrowseReply callback.
|
|
*
|
|
* callback: The delegate to be called when a result is found, or if the call
|
|
* asynchronously fails.
|
|
*
|
|
*
|
|
* return value: Returns initialized ServiceRef on succeses (any subsequent, asynchronous
|
|
* errors are delivered to the callback), otherwise throws an exception indicating
|
|
* the error that occurred (the callback is never invoked and the DNSServiceRef
|
|
* is not initialized.)
|
|
*/
|
|
|
|
static public ServiceRef*
|
|
Resolve
|
|
(
|
|
int flags,
|
|
int interfaceIndex,
|
|
String * name,
|
|
String * regtype,
|
|
String * domain,
|
|
ResolveReply * callback
|
|
);
|
|
|
|
/*********************************************************************************************
|
|
*
|
|
* Special Purpose Calls (most applications will not use these)
|
|
*
|
|
*********************************************************************************************/
|
|
|
|
/* CreateConnection/RegisterRecord
|
|
*
|
|
* Register an individual resource record on a connected ServiceRef.
|
|
*
|
|
* Note that name conflicts occurring for records registered via this call must be handled
|
|
* by the client in the callback.
|
|
*
|
|
*
|
|
* RecordReply() parameters:
|
|
*
|
|
* sdRef: The connected ServiceRef initialized by
|
|
* CreateConnection().
|
|
*
|
|
* RecordRef: The RecordRef initialized by RegisterRecord(). If the above
|
|
* ServiceRef.Dispose is called, this RecordRef is
|
|
* invalidated, and may not be used further.
|
|
*
|
|
* flags: Currently unused, reserved for future use.
|
|
*
|
|
* errorCode: Will be NoError on success, otherwise will
|
|
* indicate the failure that occurred (including name conflicts.)
|
|
* Other parameters are undefined if errorCode is nonzero.
|
|
*
|
|
*/
|
|
|
|
__delegate void
|
|
RegisterRecordReply
|
|
(
|
|
ServiceRef * sdRef,
|
|
ServiceFlags flags,
|
|
ErrorCode errorCode,
|
|
RecordRef * record
|
|
);
|
|
|
|
/* CreateConnection()
|
|
*
|
|
* Create a connection to the daemon allowing efficient registration of
|
|
* multiple individual records.
|
|
*
|
|
*
|
|
* Parameters:
|
|
*
|
|
* callback: The delegate to be called when a result is found, or if the call
|
|
* asynchronously fails (e.g. because of a name conflict.)
|
|
*
|
|
* return value: Returns initialize ServiceRef on success, otherwise throws
|
|
* an exception indicating the specific failure that occurred (in which
|
|
* case the ServiceRef is not initialized).
|
|
*/
|
|
|
|
static public ServiceRef*
|
|
CreateConnection
|
|
(
|
|
RegisterRecordReply * callback
|
|
);
|
|
|
|
|
|
/* RegisterRecord() Parameters:
|
|
*
|
|
* sdRef: A ServiceRef initialized by CreateConnection().
|
|
*
|
|
* RecordRef: A pointer to an uninitialized RecordRef. Upon succesfull completion of this
|
|
* call, this ref may be passed to UpdateRecord() or RemoveRecord().
|
|
* (To deregister ALL records registered on a single connected ServiceRef
|
|
* and deallocate each of their corresponding RecordRefs, call
|
|
* ServiceRef.Dispose()).
|
|
*
|
|
* flags: Possible values are Shared or Unique
|
|
* (see flag type definitions for details).
|
|
*
|
|
* interfaceIndex: If non-zero, specifies the interface on which to register the record
|
|
* (the index for a given interface is determined via the if_nametoindex()
|
|
* family of calls.) Passing 0 causes the record to be registered on all interfaces.
|
|
* Passing -1 causes the record to only be visible on the local host.
|
|
*
|
|
* fullname: The full domain name of the resource record.
|
|
*
|
|
* rrtype: The numerical type of the resource record (e.g. PTR, SRV, etc), as defined
|
|
* in nameser.h.
|
|
*
|
|
* rrclass: The class of the resource record, as defined in nameser.h (usually 1 for the
|
|
* Internet class).
|
|
*
|
|
* rdata: A pointer to the raw rdata, as it is to appear in the DNS record.
|
|
*
|
|
* ttl: The time to live of the resource record, in seconds.
|
|
*
|
|
*
|
|
* return value: Returns initialize RecordRef on succeses (any subsequent, asynchronous
|
|
* errors are delivered to the callback), otherwise throws an exception indicating
|
|
* the error that occurred (the callback is never invoked and the RecordRef is
|
|
* not initialized.)
|
|
*/
|
|
static public RecordRef*
|
|
RegisterRecord
|
|
(
|
|
ServiceRef * sdRef,
|
|
ServiceFlags flags,
|
|
int interfaceIndex,
|
|
String * fullname,
|
|
int rrtype,
|
|
int rrclass,
|
|
Byte rdata[],
|
|
int ttl
|
|
);
|
|
|
|
|
|
/* DNSServiceQueryRecord
|
|
*
|
|
* Query for an arbitrary DNS record.
|
|
*
|
|
*
|
|
* QueryRecordReply() Delegate Parameters:
|
|
*
|
|
* sdRef: The ServiceRef initialized by QueryRecord().
|
|
*
|
|
* flags: Possible values are MoreComing and
|
|
* Add. The Add flag is NOT set for PTR records
|
|
* with a ttl of 0, i.e. "Remove" events.
|
|
*
|
|
* interfaceIndex: The interface on which the query was resolved (the index for a given
|
|
* interface is determined via the if_nametoindex() family of calls).
|
|
*
|
|
* errorCode: Will be kDNSServiceErr_NoError on success, otherwise will
|
|
* indicate the failure that occurred. Other parameters are undefined if
|
|
* errorCode is nonzero.
|
|
*
|
|
* fullname: The resource record's full domain name.
|
|
*
|
|
* rrtype: The resource record's type (e.g. PTR, SRV, etc) as defined in nameser.h.
|
|
*
|
|
* rrclass: The class of the resource record, as defined in nameser.h (usually 1).
|
|
*
|
|
* rdata: The raw rdata of the resource record.
|
|
*
|
|
* ttl: The resource record's time to live, in seconds.
|
|
*
|
|
*/
|
|
|
|
__delegate void
|
|
QueryRecordReply
|
|
(
|
|
ServiceRef * sdRef,
|
|
ServiceFlags flags,
|
|
int interfaceIndex,
|
|
ErrorCode errorCode,
|
|
String * fullName,
|
|
int rrtype,
|
|
int rrclass,
|
|
Byte rdata[],
|
|
int ttl
|
|
);
|
|
|
|
/* QueryRecord() Parameters:
|
|
*
|
|
* flags: Pass LongLivedQuery to create a "long-lived" unicast
|
|
* query in a non-local domain. Without setting this flag, unicast queries
|
|
* will be one-shot - that is, only answers available at the time of the call
|
|
* will be returned. By setting this flag, answers (including Add and Remove
|
|
* events) that become available after the initial call is made will generate
|
|
* callbacks. This flag has no effect on link-local multicast queries.
|
|
*
|
|
* interfaceIndex: If non-zero, specifies the interface on which to issue the query
|
|
* (the index for a given interface is determined via the if_nametoindex()
|
|
* family of calls.) Passing 0 causes the name to be queried for on all
|
|
* interfaces. Passing -1 causes the name to be queried for only on the
|
|
* local host.
|
|
*
|
|
* fullname: The full domain name of the resource record to be queried for.
|
|
*
|
|
* rrtype: The numerical type of the resource record to be queried for (e.g. PTR, SRV, etc)
|
|
* as defined in nameser.h.
|
|
*
|
|
* rrclass: The class of the resource record, as defined in nameser.h
|
|
* (usually 1 for the Internet class).
|
|
*
|
|
* callback: The delegate to be called when a result is found, or if the call
|
|
* asynchronously fails.
|
|
*
|
|
*
|
|
* return value: Returns initialized ServiceRef on succeses (any subsequent, asynchronous
|
|
* errors are delivered to the callback), otherwise throws an exception indicating
|
|
* the error that occurred (the callback is never invoked and the ServiceRef
|
|
* is not initialized.)
|
|
*/
|
|
|
|
static public ServiceRef*
|
|
QueryRecord
|
|
(
|
|
ServiceFlags flags,
|
|
int interfaceIndex,
|
|
String * fullname,
|
|
int rrtype,
|
|
int rrclass,
|
|
QueryRecordReply * callback
|
|
);
|
|
|
|
/* ReconfirmRecord
|
|
*
|
|
* Instruct the daemon to verify the validity of a resource record that appears to
|
|
* be out of date (e.g. because tcp connection to a service's target failed.)
|
|
* Causes the record to be flushed from the daemon's cache (as well as all other
|
|
* daemons' caches on the network) if the record is determined to be invalid.
|
|
*
|
|
* Parameters:
|
|
*
|
|
* flags: Currently unused, reserved for future use.
|
|
*
|
|
* fullname: The resource record's full domain name.
|
|
*
|
|
* rrtype: The resource record's type (e.g. PTR, SRV, etc) as defined in nameser.h.
|
|
*
|
|
* rrclass: The class of the resource record, as defined in nameser.h (usually 1).
|
|
*
|
|
* rdata: The raw rdata of the resource record.
|
|
*
|
|
*/
|
|
static public void
|
|
ReconfirmRecord
|
|
(
|
|
ServiceFlags flags,
|
|
int interfaceIndex,
|
|
String * fullname,
|
|
int rrtype,
|
|
int rrclass,
|
|
Byte rdata[]
|
|
);
|
|
};
|
|
}
|
|
}
|