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