Mono.Zeroconf

Subversion Repositories:
Compare Path: Rev
With Path: Rev
?path1? @ 1  →  ?path2? @ 2
/trunk/Mono.Zeroconf.sln
@@ -1,6 +1,8 @@

Microsoft Visual Studio Solution File, Format Version 9.00
# Visual C# Express 2005
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.28307.572
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MZClient", "src\MZClient\MZClient.csproj", "{839D9048-31CF-4010-B427-6A8362556485}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.Zeroconf", "src\Mono.Zeroconf\Mono.Zeroconf.csproj", "{5CF88E3A-13DD-4114-BAD9-DA826946516F}"
@@ -14,21 +16,23 @@
Debug|Any CPU = Debug|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{839D9048-31CF-4010-B427-6A8362556485}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{839D9048-31CF-4010-B427-6A8362556485}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5CF88E3A-13DD-4114-BAD9-DA826946516F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5CF88E3A-13DD-4114-BAD9-DA826946516F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{623325E2-5821-4701-A40C-3759097008DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{623325E2-5821-4701-A40C-3759097008DD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{839D9048-31CF-4010-B427-6A8362556485}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{839D9048-31CF-4010-B427-6A8362556485}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EF6ED6D1-D201-42ED-B680-5A77641BEB77}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EF6ED6D1-D201-42ED-B680-5A77641BEB77}.Debug|Any CPU.Build.0 = Debug|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {408D8048-93CB-4BFE-90EE-9A3466056346}
EndGlobalSection
GlobalSection(MonoDevelopProperties) = preSolution
name = Mono.Zeroconf
version = 0.1
StartupItem = src\MZClient\MZClient.csproj
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
/trunk/src/MZClient/MZClient.csproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="15.0">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
@@ -13,6 +13,11 @@
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<StartupObject>MZClient</StartupObject>
<FileUpgradeFlags>
</FileUpgradeFlags>
<UpgradeBackupLocation>
</UpgradeBackupLocation>
<OldToolsVersion>2.0</OldToolsVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
/trunk/src/Mono.Zeroconf/Mono.Zeroconf.Providers/ProviderFactory.cs
@@ -89,20 +89,31 @@
directories.Add(Path.Combine(new_path, "mono-zeroconf"));
}
foreach(string directory in directories) {
foreach(string file in Directory.GetFiles(directory, "Mono.Zeroconf.Providers.*.dll")) {
if(Path.GetFileName(file) != Path.GetFileName(this_asm_path)) {
Assembly provider_asm = Assembly.LoadFile(file);
foreach(Attribute attr in provider_asm.GetCustomAttributes(false)) {
if(attr is ZeroconfProviderAttribute) {
Type type = (attr as ZeroconfProviderAttribute).ProviderType;
IZeroconfProvider provider = (IZeroconfProvider)Activator.CreateInstance(type);
try {
provider.Initialize();
providers_list.Add(provider);
} catch (Exception e) {
Console.WriteLine (e);
 
try
{
foreach (string directory in directories)
{
foreach (string file in Directory.GetFiles(directory, "Mono.Zeroconf.Providers.*.dll"))
{
if (Path.GetFileName(file) != Path.GetFileName(this_asm_path))
{
Assembly provider_asm = Assembly.LoadFile(file);
foreach (Attribute attr in provider_asm.GetCustomAttributes(false))
{
if (attr is ZeroconfProviderAttribute)
{
Type type = (attr as ZeroconfProviderAttribute).ProviderType;
IZeroconfProvider provider = (IZeroconfProvider) Activator.CreateInstance(type);
try
{
provider.Initialize();
providers_list.Add(provider);
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
}
}
@@ -109,7 +120,11 @@
}
}
}
catch
{
// Could not load a provider.
}
 
if(providers_list.Count == 0) {
throw new Exception("No Zeroconf providers could be found or initialized. Necessary daemon may not be running.");
}
/trunk/src/Mono.Zeroconf/Mono.Zeroconf.csproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="15.0">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
@@ -12,6 +12,11 @@
<AssemblyName>Mono.Zeroconf</AssemblyName>
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<FileUpgradeFlags>
</FileUpgradeFlags>
<UpgradeBackupLocation>
</UpgradeBackupLocation>
<OldToolsVersion>2.0</OldToolsVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
/trunk/src/Mono.Zeroconf.Providers.AvahiDBus/Mono.Zeroconf.Providers.AvahiDBus/RegisterService.cs
@@ -38,7 +38,10 @@
private IAvahiEntryGroup entry_group;
public event RegisterServiceEventHandler Response;
 
private string originalName;
private int retryNameModifier = 2;
 
public RegisterService ()
{
}
@@ -95,12 +98,20 @@
switch (state) {
case EntryGroupState.Collision:
if (!OnResponse (ErrorCode.Collision)) {
throw new ApplicationException ();
if (originalName == null)
originalName = Name;
 
Name = originalName + " (" + retryNameModifier + ")";
retryNameModifier++;
 
Console.WriteLine("ZeroConf had a name collision, trying: " + Name);
 
Register();
}
break;
case EntryGroupState.Failure:
if (!OnResponse (ErrorCode.Failure)) {
throw new ApplicationException ();
Console.WriteLine("Mono.ZeroConf failed to register name with AvahiDBus");
}
break;
case EntryGroupState.Established:
/trunk/src/Mono.Zeroconf.Providers.AvahiDBus/Mono.Zeroconf.Providers.AvahiDBus.csproj
@@ -1,96 +1,102 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.50727</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{EF6ED6D1-D201-42ED-B680-5A77641BEB77}</ProjectGuid>
<OutputType>Library</OutputType>
<AssemblyName>Mono.Zeroconf.Providers.AvahiDBus</AssemblyName>
<UseParentDirectoryAsNamespace>true</UseParentDirectoryAsNamespace>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>.</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>
<ProjectReference Include="..\Mono.Zeroconf\Mono.Zeroconf.csproj">
<Project>{EF6ED6D1-D201-42ED-B680-5A77641BEB77}</Project>
<Name>Mono.Zeroconf</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
<Compile Include="Mono.Zeroconf.Providers.AvahiDBus\DBusManager.cs" />
<Compile Include="Mono.Zeroconf.Providers.AvahiDBus\IAvahiServer.cs" />
<Compile Include="Mono.Zeroconf.Providers.AvahiDBus\IAvahiServiceBrowser.cs" />
<Compile Include="Mono.Zeroconf.Providers.AvahiDBus\ServiceBrowser.cs" />
<Compile Include="Mono.Zeroconf.Providers.AvahiDBus\ZeroconfProvider.cs" />
<Compile Include="Mono.Zeroconf.Providers.AvahiDBus\Protocol.cs" />
<Compile Include="Mono.Zeroconf.Providers.AvahiDBus\LookupFlags.cs" />
<Compile Include="Mono.Zeroconf.Providers.AvahiDBus\LookupResultFlags.cs" />
<Compile Include="Mono.Zeroconf.Providers.AvahiDBus\IAvahiServiceResolver.cs" />
<Compile Include="Mono.Zeroconf.Providers.AvahiDBus\AvahiServerState.cs" />
<Compile Include="Mono.Zeroconf.Providers.AvahiDBus\AvahiUtils.cs" />
<Compile Include="Mono.Zeroconf.Providers.AvahiDBus\Service.cs" />
<Compile Include="Mono.Zeroconf.Providers.AvahiDBus\BrowseService.cs" />
<Compile Include="Mono.Zeroconf.Providers.AvahiDBus\TxtRecord.cs" />
<Compile Include="NDesk.DBus\Address.cs" />
<Compile Include="NDesk.DBus\Authentication.cs" />
<Compile Include="NDesk.DBus\Bus.cs" />
<Compile Include="NDesk.DBus\BusObject.cs" />
<Compile Include="NDesk.DBus\Connection.cs" />
<Compile Include="NDesk.DBus\DBus.cs" />
<Compile Include="NDesk.DBus\DProxy.cs" />
<Compile Include="NDesk.DBus\ExportObject.cs" />
<Compile Include="NDesk.DBus\Introspection.cs" />
<Compile Include="NDesk.DBus\IntrospectionSchema.cs" />
<Compile Include="NDesk.DBus\Mapper.cs" />
<Compile Include="NDesk.DBus\MatchRule.cs" />
<Compile Include="NDesk.DBus\Message.cs" />
<Compile Include="NDesk.DBus\MessageFilter.cs" />
<Compile Include="NDesk.DBus\MessageReader.cs" />
<Compile Include="NDesk.DBus\MessageWriter.cs" />
<Compile Include="NDesk.DBus\PendingCall.cs" />
<Compile Include="NDesk.DBus\Protocol.cs" />
<Compile Include="NDesk.DBus\Server.cs" />
<Compile Include="NDesk.DBus\Signature.cs" />
<Compile Include="NDesk.DBus\SocketTransport.cs" />
<Compile Include="NDesk.DBus\Transport.cs" />
<Compile Include="NDesk.DBus\TypeDefiner.cs" />
<Compile Include="NDesk.DBus\TypeImplementer.cs" />
<Compile Include="NDesk.DBus\UnixMonoTransport.cs" />
<Compile Include="NDesk.DBus\UnixNativeTransport.cs" />
<Compile Include="NDesk.DBus\UnixTransport.cs" />
<Compile Include="NDesk.DBus\Wrapper.cs" />
<Compile Include="Mono.Zeroconf.Providers.AvahiDBus\RegisterService.cs" />
<Compile Include="Mono.Zeroconf.Providers.AvahiDBus\IAvahiEntryGroup.cs" />
<Compile Include="Mono.Zeroconf.Providers.AvahiDBus\PublishFlags.cs" />
<Compile Include="Mono.Zeroconf.Providers.AvahiDBus\EntryGroupState.cs" />
<Compile Include="Mono.Zeroconf.Providers.AvahiDBus\ErrorCode.cs" />
</ItemGroup>
<ProjectExtensions>
<MonoDevelop>
<Properties>
<Deployment.LinuxDeployData generateScript="false" />
<MonoDevelop.Autotools.MakefileInfo IntegrationEnabled="true" RelativeMakefileName="Makefile.am" IsAutotoolsProject="true" RelativeConfigureInPath="../..">
<BuildFilesVar Sync="true" Name="MONO_ZEROCONF_PROVIDERS_AVAHI_SRC" />
<DeployFilesVar />
<ResourcesVar />
<OthersVar />
<GacRefVar />
<AsmRefVar />
<ProjectRefVar />
</MonoDevelop.Autotools.MakefileInfo>
</Properties>
</MonoDevelop>
</ProjectExtensions>
</Project>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="15.0">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.50727</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{EF6ED6D1-D201-42ED-B680-5A77641BEB77}</ProjectGuid>
<OutputType>Library</OutputType>
<AssemblyName>Mono.Zeroconf.Providers.AvahiDBus</AssemblyName>
<UseParentDirectoryAsNamespace>true</UseParentDirectoryAsNamespace>
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
<FileUpgradeFlags>
</FileUpgradeFlags>
<UpgradeBackupLocation>
</UpgradeBackupLocation>
<OldToolsVersion>2.0</OldToolsVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>.</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>
<ProjectReference Include="..\Mono.Zeroconf\Mono.Zeroconf.csproj">
<Project>{EF6ED6D1-D201-42ED-B680-5A77641BEB77}</Project>
<Name>Mono.Zeroconf</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
<Compile Include="Mono.Zeroconf.Providers.AvahiDBus\DBusManager.cs" />
<Compile Include="Mono.Zeroconf.Providers.AvahiDBus\IAvahiServer.cs" />
<Compile Include="Mono.Zeroconf.Providers.AvahiDBus\IAvahiServiceBrowser.cs" />
<Compile Include="Mono.Zeroconf.Providers.AvahiDBus\ServiceBrowser.cs" />
<Compile Include="Mono.Zeroconf.Providers.AvahiDBus\ZeroconfProvider.cs" />
<Compile Include="Mono.Zeroconf.Providers.AvahiDBus\Protocol.cs" />
<Compile Include="Mono.Zeroconf.Providers.AvahiDBus\LookupFlags.cs" />
<Compile Include="Mono.Zeroconf.Providers.AvahiDBus\LookupResultFlags.cs" />
<Compile Include="Mono.Zeroconf.Providers.AvahiDBus\IAvahiServiceResolver.cs" />
<Compile Include="Mono.Zeroconf.Providers.AvahiDBus\AvahiServerState.cs" />
<Compile Include="Mono.Zeroconf.Providers.AvahiDBus\AvahiUtils.cs" />
<Compile Include="Mono.Zeroconf.Providers.AvahiDBus\Service.cs" />
<Compile Include="Mono.Zeroconf.Providers.AvahiDBus\BrowseService.cs" />
<Compile Include="Mono.Zeroconf.Providers.AvahiDBus\TxtRecord.cs" />
<Compile Include="NDesk.DBus\Address.cs" />
<Compile Include="NDesk.DBus\Authentication.cs" />
<Compile Include="NDesk.DBus\Bus.cs" />
<Compile Include="NDesk.DBus\BusObject.cs" />
<Compile Include="NDesk.DBus\Connection.cs" />
<Compile Include="NDesk.DBus\DBus.cs" />
<Compile Include="NDesk.DBus\DProxy.cs" />
<Compile Include="NDesk.DBus\ExportObject.cs" />
<Compile Include="NDesk.DBus\Introspection.cs" />
<Compile Include="NDesk.DBus\IntrospectionSchema.cs" />
<Compile Include="NDesk.DBus\Mapper.cs" />
<Compile Include="NDesk.DBus\MatchRule.cs" />
<Compile Include="NDesk.DBus\Message.cs" />
<Compile Include="NDesk.DBus\MessageFilter.cs" />
<Compile Include="NDesk.DBus\MessageReader.cs" />
<Compile Include="NDesk.DBus\MessageWriter.cs" />
<Compile Include="NDesk.DBus\PendingCall.cs" />
<Compile Include="NDesk.DBus\Protocol.cs" />
<Compile Include="NDesk.DBus\Server.cs" />
<Compile Include="NDesk.DBus\Signature.cs" />
<Compile Include="NDesk.DBus\SocketTransport.cs" />
<Compile Include="NDesk.DBus\Transport.cs" />
<Compile Include="NDesk.DBus\TypeDefiner.cs" />
<Compile Include="NDesk.DBus\TypeImplementer.cs" />
<Compile Include="NDesk.DBus\UnixMonoTransport.cs" />
<Compile Include="NDesk.DBus\UnixNativeTransport.cs" />
<Compile Include="NDesk.DBus\UnixTransport.cs" />
<Compile Include="NDesk.DBus\Wrapper.cs" />
<Compile Include="Mono.Zeroconf.Providers.AvahiDBus\RegisterService.cs" />
<Compile Include="Mono.Zeroconf.Providers.AvahiDBus\IAvahiEntryGroup.cs" />
<Compile Include="Mono.Zeroconf.Providers.AvahiDBus\PublishFlags.cs" />
<Compile Include="Mono.Zeroconf.Providers.AvahiDBus\EntryGroupState.cs" />
<Compile Include="Mono.Zeroconf.Providers.AvahiDBus\ErrorCode.cs" />
</ItemGroup>
<ProjectExtensions>
<MonoDevelop>
<Properties>
<Deployment.LinuxDeployData generateScript="false" />
<MonoDevelop.Autotools.MakefileInfo IntegrationEnabled="true" RelativeMakefileName="Makefile.am" IsAutotoolsProject="true" RelativeConfigureInPath="../..">
<BuildFilesVar Sync="true" Name="MONO_ZEROCONF_PROVIDERS_AVAHI_SRC" />
<DeployFilesVar />
<ResourcesVar />
<OthersVar />
<GacRefVar />
<AsmRefVar />
<ProjectRefVar />
</MonoDevelop.Autotools.MakefileInfo>
</Properties>
</MonoDevelop>
</ProjectExtensions>
</Project>
/trunk/src/Mono.Zeroconf.Providers.Bonjour/Mono.Zeroconf.Providers.Bonjour/BrowseService.cs
@@ -1,209 +1,231 @@
//
// BrowseService.cs
//
// Authors:
// Aaron Bockover <abockover@novell.com>
//
// Copyright (C) 2006-2008 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
 
using System;
using System.Net;
using System.Text;
using System.Collections;
using System.Runtime.InteropServices;
 
namespace Mono.Zeroconf.Providers.Bonjour
{
public sealed class BrowseService : Service, IResolvableService
{
private bool is_resolved = false;
private bool resolve_pending = false;
private Native.DNSServiceResolveReply resolve_reply_handler;
private Native.DNSServiceQueryRecordReply query_record_reply_handler;
public event ServiceResolvedEventHandler Resolved;
 
public BrowseService()
{
SetupCallbacks();
}
public BrowseService(string name, string replyDomain, string regtype) : base(name, replyDomain, regtype)
{
SetupCallbacks();
}
private void SetupCallbacks()
{
resolve_reply_handler = new Native.DNSServiceResolveReply(OnResolveReply);
query_record_reply_handler = new Native.DNSServiceQueryRecordReply(OnQueryRecordReply);
}
 
public void Resolve()
{
Resolve(false);
}
public void Resolve(bool requery)
{
if(resolve_pending) {
return;
}
is_resolved = false;
resolve_pending = true;
if(requery) {
InterfaceIndex = 0;
}
ServiceRef sd_ref;
ServiceError error = Native.DNSServiceResolve(out sd_ref, ServiceFlags.None,
InterfaceIndex, Name, RegType, ReplyDomain, resolve_reply_handler, IntPtr.Zero);
if(error != ServiceError.NoError) {
throw new ServiceErrorException(error);
}
sd_ref.Process();
}
public void RefreshTxtRecord()
{
// Should probably make this async?
ServiceRef sd_ref;
ServiceError error = Native.DNSServiceQueryRecord(out sd_ref, ServiceFlags.None, 0,
fullname, ServiceType.TXT, ServiceClass.IN, query_record_reply_handler, IntPtr.Zero);
if(error != ServiceError.NoError) {
throw new ServiceErrorException(error);
}
sd_ref.Process();
}
private void OnResolveReply(ServiceRef sdRef, ServiceFlags flags, uint interfaceIndex,
ServiceError errorCode, string fullname, string hosttarget, ushort port, ushort txtLen,
IntPtr txtRecord, IntPtr contex)
{
is_resolved = true;
resolve_pending = false;
InterfaceIndex = interfaceIndex;
FullName = fullname;
this.port = port;
TxtRecord = new TxtRecord(txtLen, txtRecord);
 
sdRef.Deallocate();
// Run an A query to resolve the IP address
ServiceRef sd_ref;
if (AddressProtocol == AddressProtocol.Any || AddressProtocol == AddressProtocol.IPv4) {
ServiceError error = Native.DNSServiceQueryRecord(out sd_ref, ServiceFlags.None, interfaceIndex,
hosttarget, ServiceType.A, ServiceClass.IN, query_record_reply_handler, IntPtr.Zero);
if(error != ServiceError.NoError) {
throw new ServiceErrorException(error);
}
sd_ref.Process();
}
if (AddressProtocol == AddressProtocol.Any || AddressProtocol == AddressProtocol.IPv6) {
ServiceError error = Native.DNSServiceQueryRecord(out sd_ref, ServiceFlags.None, interfaceIndex,
hosttarget, ServiceType.AAAA, ServiceClass.IN, query_record_reply_handler, IntPtr.Zero);
if(error != ServiceError.NoError) {
throw new ServiceErrorException(error);
}
sd_ref.Process();
}
}
private void OnQueryRecordReply(ServiceRef sdRef, ServiceFlags flags, uint interfaceIndex,
ServiceError errorCode, string fullname, ServiceType rrtype, ServiceClass rrclass, ushort rdlen,
IntPtr rdata, uint ttl, IntPtr context)
{
switch(rrtype) {
case ServiceType.A:
IPAddress address;
 
if(rdlen == 4) {
// ~4.5 times faster than Marshal.Copy into byte[4]
uint address_raw = (uint)(Marshal.ReadByte (rdata, 3) << 24);
address_raw |= (uint)(Marshal.ReadByte (rdata, 2) << 16);
address_raw |= (uint)(Marshal.ReadByte (rdata, 1) << 8);
address_raw |= (uint)Marshal.ReadByte (rdata, 0);
 
address = new IPAddress(address_raw);
} else if(rdlen == 16) {
byte [] address_raw = new byte[rdlen];
Marshal.Copy(rdata, address_raw, 0, rdlen);
address = new IPAddress(address_raw, interfaceIndex);
} else {
break;
}
 
if(hostentry == null) {
hostentry = new IPHostEntry();
hostentry.HostName = hosttarget;
}
if(hostentry.AddressList != null) {
ArrayList list = new ArrayList(hostentry.AddressList);
list.Add(address);
hostentry.AddressList = list.ToArray(typeof(IPAddress)) as IPAddress [];
} else {
hostentry.AddressList = new IPAddress [] { address };
}
ServiceResolvedEventHandler handler = Resolved;
if(handler != null) {
handler(this, new ServiceResolvedEventArgs(this));
}
break;
case ServiceType.TXT:
if(TxtRecord != null) {
TxtRecord.Dispose();
}
TxtRecord = new TxtRecord(rdlen, rdata);
break;
default:
break;
}
sdRef.Deallocate();
}
public bool IsResolved {
get { return is_resolved; }
}
}
}
 
//
// BrowseService.cs
//
// Authors:
// Aaron Bockover <abockover@novell.com>
//
// Copyright (C) 2006-2008 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
 
using System;
using System.Net;
using System.Text;
using System.Collections;
using System.Runtime.InteropServices;
 
namespace Mono.Zeroconf.Providers.Bonjour
{
public sealed class BrowseService : Service, IResolvableService
{
private bool is_resolved = false;
private bool resolve_pending = false;
private Native.DNSServiceResolveReply resolve_reply_handler;
private Native.DNSServiceQueryRecordReply query_record_reply_handler;
public event ServiceResolvedEventHandler Resolved;
 
public BrowseService()
{
SetupCallbacks();
}
public BrowseService(string name, string replyDomain, string regtype) : base(name, replyDomain, regtype)
{
SetupCallbacks();
}
private void SetupCallbacks()
{
resolve_reply_handler = new Native.DNSServiceResolveReply(OnResolveReply);
query_record_reply_handler = new Native.DNSServiceQueryRecordReply(OnQueryRecordReply);
resolveAction = new Action<bool>(Resolve);
}
 
private Action<bool> resolveAction;
 
public void Resolve()
{
Resolve(false);
// If people call this in a ServiceAdded eventhandler (which they genreally do)
// We need to invoke onto another thread otherwise we block processing any more results.
 
resolveAction.BeginInvoke(false, null, null);
}
public void Resolve(bool requery)
{
if(resolve_pending) {
return;
}
is_resolved = false;
resolve_pending = true;
if(requery) {
InterfaceIndex = 0;
}
ServiceRef sd_ref;
ServiceError error = Native.DNSServiceResolve(out sd_ref, ServiceFlags.None,
InterfaceIndex, Encoding.UTF8.GetBytes(Name), RegType, ReplyDomain, resolve_reply_handler, IntPtr.Zero);
if(error != ServiceError.NoError) {
throw new ServiceErrorException(error);
}
sd_ref.Process();
}
public void RefreshTxtRecord()
{
// Should probably make this async?
ServiceRef sd_ref;
ServiceError error = Native.DNSServiceQueryRecord(out sd_ref, ServiceFlags.None, 0,
fullname, ServiceType.TXT, ServiceClass.IN, query_record_reply_handler, IntPtr.Zero);
if(error != ServiceError.NoError) {
throw new ServiceErrorException(error);
}
sd_ref.Process();
}
private void OnResolveReply(ServiceRef sdRef, ServiceFlags flags, uint interfaceIndex,
ServiceError errorCode, IntPtr fullname, string hosttarget, ushort port, ushort txtLen,
IntPtr txtRecord, IntPtr contex)
{
is_resolved = true;
resolve_pending = false;
InterfaceIndex = interfaceIndex;
FullName = Native.Utf8toString(fullname);
this.port = (ushort)IPAddress.NetworkToHostOrder((short)port);
TxtRecord = new TxtRecord(txtLen, txtRecord);
this.hosttarget = hosttarget;
 
sdRef.Deallocate();
// Run an A query to resolve the IP address
ServiceRef sd_ref;
if (AddressProtocol == AddressProtocol.Any || AddressProtocol == AddressProtocol.IPv4) {
ServiceError error = Native.DNSServiceQueryRecord(out sd_ref, ServiceFlags.None, interfaceIndex,
hosttarget, ServiceType.A, ServiceClass.IN, query_record_reply_handler, IntPtr.Zero);
if(error != ServiceError.NoError) {
throw new ServiceErrorException(error);
}
sd_ref.Process();
}
if (AddressProtocol == AddressProtocol.Any || AddressProtocol == AddressProtocol.IPv6) {
ServiceError error = Native.DNSServiceQueryRecord(out sd_ref, ServiceFlags.None, interfaceIndex,
hosttarget, ServiceType.AAAA, ServiceClass.IN, query_record_reply_handler, IntPtr.Zero);
if(error != ServiceError.NoError) {
throw new ServiceErrorException(error);
}
sd_ref.Process();
}
 
if (hostentry.AddressList != null)
{
ServiceResolvedEventHandler handler = Resolved;
if (handler != null)
{
handler(this, new ServiceResolvedEventArgs(this));
}
}
}
private void OnQueryRecordReply(ServiceRef sdRef, ServiceFlags flags, uint interfaceIndex,
ServiceError errorCode, string fullname, ServiceType rrtype, ServiceClass rrclass, ushort rdlen,
IntPtr rdata, uint ttl, IntPtr context)
{
switch(rrtype) {
case ServiceType.A:
case ServiceType.AAAA:
IPAddress address;
 
if(rdlen == 4) {
// ~4.5 times faster than Marshal.Copy into byte[4]
uint address_raw = (uint)(Marshal.ReadByte (rdata, 3) << 24);
address_raw |= (uint)(Marshal.ReadByte (rdata, 2) << 16);
address_raw |= (uint)(Marshal.ReadByte (rdata, 1) << 8);
address_raw |= (uint)Marshal.ReadByte (rdata, 0);
 
address = new IPAddress(address_raw);
} else if(rdlen == 16) {
byte [] address_raw = new byte[rdlen];
Marshal.Copy(rdata, address_raw, 0, rdlen);
address = new IPAddress(address_raw, interfaceIndex);
} else {
break;
}
 
if(hostentry == null) {
hostentry = new IPHostEntry();
hostentry.HostName = hosttarget;
}
if(hostentry.AddressList != null) {
ArrayList list = new ArrayList(hostentry.AddressList);
list.Add(address);
hostentry.AddressList = list.ToArray(typeof(IPAddress)) as IPAddress [];
} else {
hostentry.AddressList = new IPAddress [] { address };
}
ServiceResolvedEventHandler handler = Resolved;
if(handler != null) {
handler(this, new ServiceResolvedEventArgs(this));
}
break;
case ServiceType.TXT:
if(TxtRecord != null) {
TxtRecord.Dispose();
}
TxtRecord = new TxtRecord(rdlen, rdata);
break;
default:
break;
}
 
 
if ((flags & ServiceFlags.MoreComing) != ServiceFlags.MoreComing)
{
sdRef.Deallocate();
}
}
public bool IsResolved {
get { return is_resolved; }
}
}
}
 
/trunk/src/Mono.Zeroconf.Providers.Bonjour/Mono.Zeroconf.Providers.Bonjour/Native.cs
@@ -27,6 +27,7 @@
//
 
using System;
using System.Text;
using System.Runtime.InteropServices;
 
namespace Mono.Zeroconf.Providers.Bonjour
@@ -50,7 +51,7 @@
// DNSServiceBrowse
public delegate void DNSServiceBrowseReply(ServiceRef sdRef, ServiceFlags flags, uint interfaceIndex,
ServiceError errorCode, string serviceName, string regtype, string replyDomain,
ServiceError errorCode, IntPtr serviceName, string regtype, string replyDomain,
IntPtr context);
[DllImport("dnssd.dll")]
@@ -61,22 +62,23 @@
// DNSServiceResolve
public delegate void DNSServiceResolveReply(ServiceRef sdRef, ServiceFlags flags, uint interfaceIndex,
ServiceError errorCode, string fullname, string hosttarget, ushort port, ushort txtLen,
ServiceError errorCode, IntPtr fullname, string hosttarget, ushort port, ushort txtLen,
IntPtr txtRecord, IntPtr context);
[DllImport("dnssd.dll")]
public static extern ServiceError DNSServiceResolve(out ServiceRef sdRef, ServiceFlags flags,
uint interfaceIndex, string name, string regtype, string domain, DNSServiceResolveReply callBack,
uint interfaceIndex, byte[] name, string regtype, string domain, DNSServiceResolveReply callBack,
IntPtr context);
// DNSServiceRegister
public delegate void DNSServiceRegisterReply(ServiceRef sdRef, ServiceFlags flags, ServiceError errorCode,
string name, string regtype, string domain, IntPtr context);
IntPtr name, string regtype, string domain, IntPtr context);
 
 
[DllImport("dnssd.dll")]
public static extern ServiceError DNSServiceRegister(out ServiceRef sdRef, ServiceFlags flags,
uint interfaceIndex, string name, string regtype, string domain, string host, ushort port,
uint interfaceIndex, byte[] name, string regtype, string domain, string host, ushort port,
ushort txtLen, byte [] txtRecord, DNSServiceRegisterReply callBack, IntPtr context);
 
// DNSServiceQueryRecord
@@ -117,5 +119,17 @@
[DllImport("dnssd.dll")]
public static extern ushort TXTRecordGetCount(ushort txtLen, IntPtr txtRecord);
 
public static string Utf8toString(IntPtr ptr)
{
int len = 0;
while (Marshal.ReadByte(ptr, len) != 0)
{
len++;
}
byte[] raw = new byte[len];
Marshal.Copy(ptr, raw, 0, len);
return Encoding.UTF8.GetString(raw);
}
}
}
/trunk/src/Mono.Zeroconf.Providers.Bonjour/Mono.Zeroconf.Providers.Bonjour/RegisterService.cs
@@ -30,6 +30,7 @@
using System.Net;
using System.Threading;
using System.Runtime.InteropServices;
using System.Text;
 
namespace Mono.Zeroconf.Providers.Bonjour
{
@@ -42,7 +43,7 @@
private Native.DNSServiceRegisterReply register_reply_handler;
public event RegisterServiceEventHandler Response;
 
public RegisterService()
{
SetupCallback();
@@ -107,7 +108,7 @@
ServiceError error = Native.DNSServiceRegister(out sd_ref,
auto_rename ? ServiceFlags.None : ServiceFlags.NoAutoRename, InterfaceIndex,
Name, RegType, ReplyDomain, HostTarget, (ushort)IPAddress.HostToNetworkOrder((short)port), txt_rec_length, txt_rec,
Encoding.UTF8.GetBytes(Name), RegType, ReplyDomain, HostTarget, (ushort)IPAddress.HostToNetworkOrder((short)port), txt_rec_length, txt_rec,
register_reply_handler, IntPtr.Zero);
 
if(error != ServiceError.NoError) {
@@ -128,7 +129,7 @@
}
private void OnRegisterReply(ServiceRef sdRef, ServiceFlags flags, ServiceError errorCode,
string name, string regtype, string domain, IntPtr context)
IntPtr name, string regtype, string domain, IntPtr context)
{
RegisterServiceEventArgs args = new RegisterServiceEventArgs();
@@ -137,7 +138,7 @@
args.ServiceError = (ServiceErrorCode)errorCode;
if(errorCode == ServiceError.NoError) {
Name = name;
Name = Native.Utf8toString(name);
RegType = regtype;
ReplyDomain = domain;
args.IsRegistered = true;
/trunk/src/Mono.Zeroconf.Providers.Bonjour/Mono.Zeroconf.Providers.Bonjour/ServiceBrowser.cs
@@ -167,12 +167,13 @@
return GetEnumerator ();
}
private void OnBrowseReply(ServiceRef sdRef, ServiceFlags flags, uint interfaceIndex, ServiceError errorCode,
string serviceName, string regtype, string replyDomain, IntPtr context)
private void OnBrowseReply(ServiceRef sdRef, ServiceFlags flags, uint interfaceIndex, ServiceError errorCode,
IntPtr serviceName, string regtype, string replyDomain, IntPtr context)
{
string name = Native.Utf8toString(serviceName);
BrowseService service = new BrowseService();
service.Flags = flags;
service.Name = serviceName;
service.Name = name;
service.RegType = regtype;
service.ReplyDomain = replyDomain;
service.InterfaceIndex = interfaceIndex;
@@ -183,10 +184,10 @@
if((flags & ServiceFlags.Add) != 0) {
lock (service_table) {
if (service_table.ContainsKey (serviceName)) {
service_table[serviceName] = service;
if (service_table.ContainsKey (name)) {
service_table[name] = service;
} else {
service_table.Add (serviceName, service);
service_table.Add(name, service);
}
}
@@ -196,8 +197,8 @@
}
} else {
lock (service_table) {
if (service_table.ContainsKey (serviceName)) {
service_table.Remove (serviceName);
if (service_table.ContainsKey (name)) {
service_table.Remove (name);
}
}
/trunk/src/Mono.Zeroconf.Providers.Bonjour/Mono.Zeroconf.Providers.Bonjour.csproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="15.0">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
@@ -12,6 +12,11 @@
<AssemblyName>Mono.Zeroconf.Providers.Bonjour</AssemblyName>
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<FileUpgradeFlags>
</FileUpgradeFlags>
<UpgradeBackupLocation>
</UpgradeBackupLocation>
<OldToolsVersion>2.0</OldToolsVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>