1 /*** 2 This file is part of avahi. 3 4 avahi is free software; you can redistribute it and/or modify it 5 under the terms of the GNU Lesser General Public License as 6 published by the Free Software Foundation; either version 2.1 of the 7 License, or (at your option) any later version. 8 9 avahi is distributed in the hope that it will be useful, but WITHOUT 10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 11 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General 12 Public License for more details. 13 14 You should have received a copy of the GNU Lesser General Public 15 License along with avahi; if not, write to the Free Software 16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 17 USA. 18 ***/ 19 20 using System; 21 using System.Collections; 22 using System.Net; 23 using System.Runtime.InteropServices; 24 using System.Text; 25 using Mono.Unix; 26 27 namespace Avahi 28 { 29 HostNameResolverCallback(IntPtr resolver, int iface, Protocol proto, ResolverEvent revent, IntPtr hostname, IntPtr address, LookupResultFlags flags, IntPtr userdata)30 internal delegate void HostNameResolverCallback (IntPtr resolver, int iface, Protocol proto, 31 ResolverEvent revent, IntPtr hostname, IntPtr address, 32 LookupResultFlags flags, IntPtr userdata); 33 34 public class HostNameResolver : ResolverBase, IDisposable 35 { 36 private IntPtr handle; 37 private Client client; 38 private int iface; 39 private Protocol proto; 40 private string hostname; 41 private Protocol aproto; 42 private LookupFlags flags; 43 private HostNameResolverCallback cb; 44 45 private IPAddress currentAddress; 46 private string currentHost; 47 48 private ArrayList foundListeners = new ArrayList (); 49 private ArrayList timeoutListeners = new ArrayList (); 50 51 [DllImport ("avahi-client")] avahi_host_name_resolver_new(IntPtr client, int iface, Protocol proto, byte[] hostname, Protocol aproto, LookupFlags flags, HostNameResolverCallback cb, IntPtr userdata)52 private static extern IntPtr avahi_host_name_resolver_new (IntPtr client, int iface, Protocol proto, 53 byte[] hostname, Protocol aproto, LookupFlags flags, 54 HostNameResolverCallback cb, IntPtr userdata); 55 56 [DllImport ("avahi-client")] avahi_host_name_resolver_free(IntPtr handle)57 private static extern void avahi_host_name_resolver_free (IntPtr handle); 58 59 public event HostAddressHandler Found 60 { 61 add { 62 foundListeners.Add (value); 63 Start (); 64 } 65 remove { 66 foundListeners.Remove (value); 67 Stop (false); 68 } 69 } 70 71 public event EventHandler Timeout 72 { 73 add { 74 timeoutListeners.Add (value); 75 Start (); 76 } 77 remove { 78 timeoutListeners.Remove (value); 79 Stop (false); 80 } 81 } 82 83 public IPAddress Address 84 { 85 get { return currentAddress; } 86 } 87 88 public string HostName 89 { 90 get { return currentHost; } 91 } 92 HostNameResolver(Client client, string hostname)93 public HostNameResolver (Client client, string hostname) : this (client, -1, Protocol.Unspecified, 94 hostname, Protocol.Unspecified, 95 LookupFlags.None) 96 { 97 } 98 HostNameResolver(Client client, int iface, Protocol proto, string hostname, Protocol aproto, LookupFlags flags)99 public HostNameResolver (Client client, int iface, Protocol proto, string hostname, 100 Protocol aproto, LookupFlags flags) 101 { 102 this.client = client; 103 this.iface = iface; 104 this.proto = proto; 105 this.hostname = hostname; 106 this.aproto = aproto; 107 this.flags = flags; 108 cb = OnHostNameResolverCallback; 109 } 110 ~HostNameResolver()111 ~HostNameResolver () 112 { 113 Dispose (); 114 } 115 Dispose()116 public void Dispose () 117 { 118 Stop (true); 119 } 120 Start()121 private void Start () 122 { 123 if (client.Handle == IntPtr.Zero || handle != IntPtr.Zero || 124 (foundListeners.Count == 0 && timeoutListeners.Count == 0)) 125 return; 126 127 lock (client) { 128 handle = avahi_host_name_resolver_new (client.Handle, iface, proto, 129 Utility.StringToBytes (hostname), aproto, flags, 130 cb, IntPtr.Zero); 131 132 if (handle == IntPtr.Zero) 133 client.ThrowError (); 134 } 135 } 136 Stop(bool force)137 private void Stop (bool force) 138 { 139 if (client.Handle != IntPtr.Zero && handle != IntPtr.Zero && 140 (force || (foundListeners.Count == 0 && timeoutListeners.Count == 0))) { 141 142 lock (client) { 143 avahi_host_name_resolver_free (handle); 144 handle = IntPtr.Zero; 145 } 146 } 147 } 148 OnHostNameResolverCallback(IntPtr resolver, int iface, Protocol proto, ResolverEvent revent, IntPtr hostname, IntPtr address, LookupResultFlags flags, IntPtr userdata)149 private void OnHostNameResolverCallback (IntPtr resolver, int iface, Protocol proto, 150 ResolverEvent revent, IntPtr hostname, IntPtr address, 151 LookupResultFlags flags, IntPtr userdata) 152 { 153 switch (revent) { 154 case ResolverEvent.Found: 155 currentAddress = Utility.PtrToAddress (address); 156 currentHost = Utility.PtrToString (hostname); 157 158 foreach (HostAddressHandler handler in foundListeners) 159 handler (this, new HostAddressArgs (currentHost, currentAddress)); 160 break; 161 case ResolverEvent.Failure: 162 EmitFailure (client.LastError); 163 break; 164 } 165 } 166 } 167 } 168