source: source/ariba/utility/bootstrap/modules/multicastdns/MulticastDns.cpp@ 4733

Last change on this file since 4733 was 4733, checked in by Christoph Mayer, 15 years ago

-integrated avahi and a bootstrap manager and stuff (still not working, but compiling)

File size: 9.3 KB
Line 
1// [License]
2// The Ariba-Underlay Copyright
3//
4// Copyright (c) 2008-2009, Institute of Telematics, UniversitÀt Karlsruhe (TH)
5//
6// Institute of Telematics
7// UniversitÀt Karlsruhe (TH)
8// Zirkel 2, 76128 Karlsruhe
9// Germany
10//
11// Redistribution and use in source and binary forms, with or without
12// modification, are permitted provided that the following conditions are
13// met:
14//
15// 1. Redistributions of source code must retain the above copyright
16// notice, this list of conditions and the following disclaimer.
17// 2. Redistributions in binary form must reproduce the above copyright
18// notice, this list of conditions and the following disclaimer in the
19// documentation and/or other materials provided with the distribution.
20//
21// THIS SOFTWARE IS PROVIDED BY THE INSTITUTE OF TELEMATICS ``AS IS'' AND
22// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ARIBA PROJECT OR
25// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32//
33// The views and conclusions contained in the software and documentation
34// are those of the authors and should not be interpreted as representing
35// official policies, either expressed or implied, of the Institute of
36// Telematics.
37// [License]
38
39#include "MulticastDns.h"
40
41namespace ariba {
42namespace utility {
43
44use_logging_cpp(MulticastDns);
45
46MulticastDns::MulticastDns(string type, BootstrapInformationCallback* _callback)
47 : BootstrapModule(type, _callback), serviceType(type){
48 #ifdef HAVE_LIBAVAHI_CLIENT
49 avahiclient = NULL;
50 avahigroup = NULL;
51 avahipoll = NULL;
52 avahibrowser = NULL;
53 #endif // HAVE_LIBAVAHI_CLIENT
54}
55
56MulticastDns::~MulticastDns(){
57}
58
59string MulticastDns::getName(){
60 return "MulticastDns";
61}
62
63string MulticastDns::getInformation(){
64 return "bootstrap module based on multicast-dns using the avahi library";
65}
66
67bool MulticastDns::isFunctional(){
68 #ifdef HAVE_LIBAVAHI_CLIENT
69 return true;
70 #else
71 return false;
72 #endif
73}
74
75void MulticastDns::start(){
76 #ifdef HAVE_LIBAVAHI_CLIENT
77
78 int error = 0;
79
80 // create a new avahi polling thread
81 avahipoll = avahi_threaded_poll_new();
82 assert( avahipoll != NULL );
83
84 // create a new avahi client
85 avahiclient = avahi_client_new( avahi_threaded_poll_get(avahipoll),
86 (AvahiClientFlags)0, MulticastDns::client_callback, this, &error );
87 assert( avahiclient != NULL );
88
89 // block the event loop
90 avahi_threaded_poll_lock( avahipoll );
91
92 // create the service browser
93 avahibrowser = avahi_service_browser_new(
94 avahiclient, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC,
95 serviceType.c_str(), NULL,
96 (AvahiLookupFlags)0, MulticastDns::browse_callback, this);
97
98 //unblock the event loop and let it run
99 avahi_threaded_poll_unlock( avahipoll );
100 avahi_threaded_poll_start( avahipoll );
101
102 #endif // HAVE_LIBAVAHI_CLIENT
103}
104
105void MulticastDns::stop(){
106 #ifdef HAVE_LIBAVAHI_CLIENT
107
108 avahi_threaded_poll_stop( avahipoll );
109 avahi_service_browser_free( avahibrowser );
110 if( avahigroup != NULL ) avahi_entry_group_free( avahigroup );
111 avahi_client_free( avahiclient );
112 avahi_threaded_poll_free( avahipoll );
113
114 #endif // HAVE_LIBAVAHI_CLIENT
115}
116
117void MulticastDns::publishService(string name, string info){
118 #ifdef HAVE_LIBAVAHI_CLIENT
119
120 avahi_threaded_poll_lock(avahipoll);
121 assert( avahiclient != NULL );
122
123 char* n = NULL;
124 int ret = 0;
125
126 if( avahigroup == NULL){
127 avahigroup = avahi_entry_group_new(avahiclient, MulticastDns::entry_group_callback, this);
128
129 if(avahigroup == NULL) {
130 logging_warn("avahi_entry_group_new failed " << avahi_strerror(avahi_client_errno(avahiclient)));
131 avahi_threaded_poll_quit(avahipoll);
132 return;
133 }
134 }
135
136 logging_debug("avahi adding service " << name);
137
138 ret = avahi_entry_group_add_service(
139 avahigroup, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, (AvahiPublishFlags)0,
140 name.c_str(), serviceType.c_str(), NULL, NULL, 0, info.c_str(), NULL);
141
142 if( ret < 0 ){
143
144 logging_warn("failed to add service " << name << ": " << avahi_strerror(ret));
145 avahi_threaded_poll_quit(avahipoll);
146 return;
147
148 }
149
150 // tell the server to register the service
151 ret = avahi_entry_group_commit(avahigroup);
152 if(ret < 0) {
153 logging_warn("failed to commit entry group: " << avahi_strerror(ret));
154 avahi_threaded_poll_quit(avahipoll);
155 }
156
157 avahi_threaded_poll_unlock(avahipoll);
158
159 #endif // HAVE_LIBAVAHI_CLIENT
160}
161
162void MulticastDns::revokeService(string name){
163 #ifdef HAVE_LIBAVAHI_CLIENT
164
165 if (avahigroup)
166 avahi_entry_group_reset(avahigroup);
167
168 #endif // HAVE_LIBAVAHI_CLIENT
169}
170
171#ifdef HAVE_LIBAVAHI_CLIENT
172
173void MulticastDns::client_callback(AvahiClient* client, AvahiClientState state, void* userdata){
174
175 MulticastDns* obj = (MulticastDns*)userdata;
176 assert( obj != NULL );
177
178 switch (state) {
179 case AVAHI_CLIENT_S_RUNNING:
180
181 // server has startup successfully and registered its host
182 // name on the network, so it's time to create our services
183
184 logging_debug("avahi client is running");
185 break;
186
187 case AVAHI_CLIENT_FAILURE:
188
189 logging_warn( "avahi client failure " << avahi_strerror(avahi_client_errno(client)) );
190 avahi_threaded_poll_quit(obj->avahipoll);
191
192 break;
193
194 case AVAHI_CLIENT_S_COLLISION:
195
196 logging_warn("avahi client collision");
197 break;
198
199 case AVAHI_CLIENT_S_REGISTERING:
200
201 //
202 // the server records are now being established. This
203 // might be caused by a host name change. We need to wait
204 // for our own records to register until the host name is
205 // properly esatblished
206 //
207
208 if( obj->avahigroup != NULL )
209 avahi_entry_group_reset(obj->avahigroup);
210
211 break;
212
213 case AVAHI_CLIENT_CONNECTING:
214 break;
215 }
216}
217
218void MulticastDns::entry_group_callback(AvahiEntryGroup* group, AvahiEntryGroupState state, void* userdata){
219
220 AvahiClient* client = avahi_entry_group_get_client( group );
221 assert( client != NULL);
222
223 MulticastDns* obj = (MulticastDns*)userdata;
224 assert(obj != NULL);
225 obj->avahigroup = group;
226
227 //
228 // called whenever the entry group state changes
229 //
230
231 switch(state) {
232 case AVAHI_ENTRY_GROUP_ESTABLISHED:
233
234 // entry group has been established successfully
235 logging_debug( "service entry group successfully established" );
236 break;
237
238 case AVAHI_ENTRY_GROUP_COLLISION:
239
240 // service name collision
241 logging_warn("service name collision for name");
242 break;
243
244 case AVAHI_ENTRY_GROUP_FAILURE:
245
246 logging_warn("service group failure: " << avahi_strerror(avahi_client_errno(client)));
247 avahi_threaded_poll_quit(obj->avahipoll);
248
249 break;
250
251 case AVAHI_ENTRY_GROUP_UNCOMMITED:
252 break;
253
254 case AVAHI_ENTRY_GROUP_REGISTERING:
255 break;
256 } //switch(state)
257}
258
259void MulticastDns::browse_callback(AvahiServiceBrowser* browser, AvahiIfIndex interface,
260 AvahiProtocol protocol, AvahiBrowserEvent event, const char* name,
261 const char* type, const char* domain, AvahiLookupResultFlags flags, void* userdata){
262
263 AvahiClient* client = avahi_service_browser_get_client(browser);
264 MulticastDns* obj = (MulticastDns*)userdata;
265
266 assert( client != NULL);
267 assert( obj != NULL );
268
269 switch (event) {
270 case AVAHI_BROWSER_FAILURE:
271
272 logging_warn("avahi browser failure " << avahi_strerror(avahi_client_errno(client)));
273 avahi_threaded_poll_quit( obj->avahipoll );
274
275 break;
276
277 case AVAHI_BROWSER_NEW:
278
279 if (!(avahi_service_resolver_new(client,
280 interface, protocol, name, type, domain,
281 AVAHI_PROTO_UNSPEC, (AvahiLookupFlags)0,
282 MulticastDns::resolve_callback, obj))){
283 logging_warn( "failed to resolve service " << name << ", error " << avahi_strerror(avahi_client_errno(client)));
284 }
285
286 break;
287
288 case AVAHI_BROWSER_REMOVE:
289 break;
290
291 case AVAHI_BROWSER_ALL_FOR_NOW:
292 break;
293
294 case AVAHI_BROWSER_CACHE_EXHAUSTED:
295 break;
296 }
297}
298
299void MulticastDns::resolve_callback(AvahiServiceResolver* resolver, AvahiIfIndex interface,
300 AvahiProtocol protocol, AvahiResolverEvent event, const char *name,
301 const char* type, const char* domain, const char* host_name,
302 const AvahiAddress* address, uint16_t port, AvahiStringList* txt,
303 AvahiLookupResultFlags flags, void* userdata){
304
305 AvahiClient* client = avahi_service_resolver_get_client(resolver);
306 MulticastDns* obj = (MulticastDns*)userdata;
307
308 assert( client != NULL );
309 assert( obj != NULL );
310
311 switch(event) {
312 case AVAHI_RESOLVER_FAILURE:
313
314 logging_warn("resolver failed to resolve service " << name << ", error " << avahi_strerror(avahi_client_errno(client)));
315 break;
316
317 case AVAHI_RESOLVER_FOUND: {
318
319 char a[AVAHI_ADDRESS_STR_MAX];
320 char* t = NULL;
321
322 avahi_address_snprint(a, sizeof(a), address);
323 t = avahi_string_list_to_string(txt);
324
325 if(obj != NULL && obj->callback != NULL){
326 obj->callback->onBootstrapServiceFound(name, t);
327 //foundNewService(name, type, domain, host_name, (int)port, a, t);
328 }
329
330 avahi_free( resolver );
331 break;
332 }
333 }
334
335 avahi_service_resolver_free( resolver );
336}
337
338#endif // HAVE_LIBAVAHI_CLIENT
339
340}} //namespace ariba, utility
Note: See TracBrowser for help on using the repository browser.