]> git.meshlink.io Git - catta/blob - avahi-sharp/AddressResolver.cs
fix avahi_netlink_new to allow multiple netlinks per process
[catta] / avahi-sharp / AddressResolver.cs
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
29     internal delegate void AddressResolverCallback (IntPtr resolver, int iface, Protocol proto,
30                                                     ResolverEvent revent, IntPtr address,
31                                                     IntPtr hostname, LookupResultFlags flags, IntPtr userdata);
32
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
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")]
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")]
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
116         public AddressResolver (Client client, IPAddress address) : this (client, -1, Protocol.Unspecified,
117                                                                           address, LookupFlags.None)
118         {
119         }
120
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
131         ~AddressResolver ()
132         {
133             Dispose ();
134         }
135
136         public void Dispose ()
137         {
138             Stop (true);
139         }
140
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
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
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 }