]> git.meshlink.io Git - catta/blob - avahi-sharp/AddressResolver.cs
3025102c4cce16cf06338203756b9bb5a7d34b90
[catta] / avahi-sharp / AddressResolver.cs
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
22 using System;
23 using System.Collections;
24 using System.Net;
25 using System.Runtime.InteropServices;
26 using Mono.Unix;
27
28 namespace 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 }