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 Mono.Unix; 25 26 namespace Avahi 27 { 28 AddressResolverCallback(IntPtr resolver, int iface, Protocol proto, ResolverEvent revent, IntPtr address, IntPtr hostname, LookupResultFlags flags, IntPtr userdata)29 internal delegate void AddressResolverCallback (IntPtr resolver, int iface, Protocol proto, 30 ResolverEvent revent, IntPtr address, 31 IntPtr hostname, LookupResultFlags flags, IntPtr userdata); 32 HostAddressHandler(object o, HostAddressArgs args)33 public delegate void HostAddressHandler (object o, HostAddressArgs args); 34 35 public class HostAddressArgs : EventArgs 36 { 37 private string host; 38 private IPAddress address; 39 40 public string Host 41 { 42 get { return host; } 43 } 44 45 public IPAddress Address 46 { 47 get { return address; } 48 } 49 HostAddressArgs(string host, IPAddress address)50 public HostAddressArgs (string host, IPAddress address) 51 { 52 this.host = host; 53 this.address = address; 54 } 55 } 56 57 public class AddressResolver : ResolverBase, IDisposable 58 { 59 private IntPtr handle; 60 private Client client; 61 private int iface; 62 private Protocol proto; 63 private IPAddress address; 64 private LookupFlags flags; 65 private AddressResolverCallback cb; 66 67 private IPAddress currentAddress; 68 private string currentHost; 69 70 private ArrayList foundListeners = new ArrayList (); 71 private ArrayList timeoutListeners = new ArrayList (); 72 73 [DllImport ("avahi-client")] avahi_address_resolver_new(IntPtr client, int iface, Protocol proto, IntPtr address, LookupFlags flags, AddressResolverCallback cb, IntPtr userdata)74 private static extern IntPtr avahi_address_resolver_new (IntPtr client, int iface, Protocol proto, 75 IntPtr address, LookupFlags flags, 76 AddressResolverCallback cb, 77 IntPtr userdata); 78 79 [DllImport ("avahi-client")] avahi_address_resolver_free(IntPtr handle)80 private static extern void avahi_address_resolver_free (IntPtr handle); 81 82 public event HostAddressHandler Found 83 { 84 add { 85 foundListeners.Add (value); 86 Start (); 87 } 88 remove { 89 foundListeners.Remove (value); 90 Stop (false); 91 } 92 } 93 94 public event EventHandler Timeout 95 { 96 add { 97 timeoutListeners.Add (value); 98 Start (); 99 } 100 remove { 101 timeoutListeners.Remove (value); 102 Stop (false); 103 } 104 } 105 106 public IPAddress Address 107 { 108 get { return currentAddress; } 109 } 110 111 public string HostName 112 { 113 get { return currentHost; } 114 } 115 AddressResolver(Client client, IPAddress address)116 public AddressResolver (Client client, IPAddress address) : this (client, -1, Protocol.Unspecified, 117 address, LookupFlags.None) 118 { 119 } 120 AddressResolver(Client client, int iface, Protocol proto, IPAddress address, LookupFlags flags)121 public AddressResolver (Client client, int iface, Protocol proto, IPAddress address, LookupFlags flags) 122 { 123 this.client = client; 124 this.iface = iface; 125 this.proto = proto; 126 this.address = address; 127 this.flags = flags; 128 cb = OnAddressResolverCallback; 129 } 130 ~AddressResolver()131 ~AddressResolver () 132 { 133 Dispose (); 134 } 135 Dispose()136 public void Dispose () 137 { 138 Stop (true); 139 } 140 Start()141 private void Start () 142 { 143 if (client.Handle == IntPtr.Zero || handle != IntPtr.Zero || 144 (foundListeners.Count == 0 && timeoutListeners.Count == 0)) 145 return; 146 147 IntPtr addrPtr = Utility.AddressToPtr (address); 148 149 lock (client) { 150 handle = avahi_address_resolver_new (client.Handle, iface, proto, addrPtr, flags, 151 cb, IntPtr.Zero); 152 153 if (handle == IntPtr.Zero) 154 client.ThrowError (); 155 } 156 157 Utility.Free (addrPtr); 158 } 159 Stop(bool force)160 private void Stop (bool force) 161 { 162 if (client.Handle != IntPtr.Zero && handle != IntPtr.Zero && 163 (force || (foundListeners.Count == 0 && timeoutListeners.Count == 0))) { 164 165 lock (client) { 166 avahi_address_resolver_free (handle); 167 handle = IntPtr.Zero; 168 } 169 } 170 } 171 OnAddressResolverCallback(IntPtr resolver, int iface, Protocol proto, ResolverEvent revent, IntPtr address, IntPtr hostname, LookupResultFlags flags, IntPtr userdata)172 private void OnAddressResolverCallback (IntPtr resolver, int iface, Protocol proto, 173 ResolverEvent revent, IntPtr address, 174 IntPtr hostname, LookupResultFlags flags, IntPtr userdata) 175 { 176 switch (revent) { 177 case ResolverEvent.Found: 178 currentAddress = Utility.PtrToAddress (address); 179 currentHost = Utility.PtrToString (hostname); 180 181 foreach (HostAddressHandler handler in foundListeners) 182 handler (this, new HostAddressArgs (currentHost, currentAddress)); 183 break; 184 case ResolverEvent.Failure: 185 EmitFailure (client.LastError); 186 break; 187 } 188 } 189 } 190 } 191