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 20using System; 21using System.Collections; 22using System.Net; 23using System.Runtime.InteropServices; 24using System.Text; 25using Mono.Unix; 26 27namespace Avahi 28{ 29 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")] 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")] 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 93 public HostNameResolver (Client client, string hostname) : this (client, -1, Protocol.Unspecified, 94 hostname, Protocol.Unspecified, 95 LookupFlags.None) 96 { 97 } 98 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 111 ~HostNameResolver () 112 { 113 Dispose (); 114 } 115 116 public void Dispose () 117 { 118 Stop (true); 119 } 120 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 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 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