Fawkes API Fawkes Development Version
service.cpp
1
2/***************************************************************************
3 * service.cpp - Network service representation
4 *
5 * Generated: Tue Nov 07 18:02:23 2006
6 * Copyright 2006-2007 Tim Niemueller [www.niemueller.de]
7 *
8 ****************************************************************************/
9
10/* This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version. A runtime exception applies to
14 * this software (see LICENSE.GPL_WRE file mentioned below for details).
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Library General Public License for more details.
20 *
21 * Read the full text in the LICENSE.GPL_WRE file in the doc directory.
22 */
23
24#include <arpa/inet.h>
25#include <core/exceptions/system.h>
26#include <netcomm/service_discovery/service.h>
27#include <netcomm/utils/resolver.h>
28#include <netinet/in.h>
29#include <sys/types.h>
30
31#include <cstdarg>
32#include <cstddef>
33#include <cstdio>
34#include <cstdlib>
35#include <cstring>
36#include <inttypes.h>
37
38namespace fawkes {
39
40/** @class NetworkService <netcomm/service_discovery/service.h>
41 * Representation of a service announced or found via service
42 * discovery (i.e. mDNS/DNS-SD via Avahi).
43 * This class is used in the C++ wrapper to talk about services.
44 *
45 * @ingroup NetComm
46 * @author Tim Niemueller
47 */
48
49/** Constructor.
50 * This constructor sets all parameters.
51 * @param name name of service
52 * @param type type of service
53 * @param domain domain of service
54 * @param host host of service
55 * @param port port of service
56 */
58 const char * type,
59 const char * domain,
60 const char * host,
61 unsigned short int port)
62{
63 _name = strdup(name);
64 _type = strdup(type);
65 _domain = strdup(domain);
66 _host = strdup(host);
67 _port = port;
68
69 _modified_name = NULL;
70
71 memset(&_addr, 0, sizeof(_addr));
72}
73
74/** Constructor.
75 * This constructor sets all parameters.
76 * @param name name of service
77 * @param type type of service
78 * @param domain domain of service
79 * @param host host of service
80 * @param port port of service
81 * @param addr address of the service
82 * @param addr_size size in bytes of addr parameter
83 * @param txt list of TXT records
84 */
86 const char * type,
87 const char * domain,
88 const char * host,
89 unsigned short int port,
90 const struct sockaddr * addr,
91 const socklen_t addr_size,
92 std::list<std::string> &txt)
93{
94 _name = strdup(name);
95 _type = strdup(type);
96 _domain = strdup(domain);
97 _host = strdup(host);
98 _port = port;
99
100 _modified_name = NULL;
101
102 if (addr_size > sizeof(_addr)) {
103 throw Exception("Address size too large");
104 }
105 memcpy(&_addr, addr, addr_size);
106 list = txt;
107}
108
109/** Constructor.
110 * This constructor sets all parameters. Host and domain are the
111 * default values, which means local host name in domain .local
112 * (if not set otherwise in Avahi system configuration).
113 * @param name name of service
114 * @param type type of service
115 * @param port port of service
116 */
117NetworkService::NetworkService(const char *name, const char *type, unsigned short int port)
118{
119 _name = strdup(name);
120 _type = strdup(type);
121 _domain = NULL;
122 _host = NULL;
123 _port = port;
124
125 _modified_name = NULL;
126
127 memset(&_addr, 0, sizeof(_addr));
128}
129
130/** Constructor.
131 * This constructor sets all parameters. Host and domain are the
132 * default values, which means local host name in domain .local
133 * (if not set otherwise in Avahi system configuration).
134 * This specific constructor allows the usage of a "%h" token in
135 * the name, which is replaced with the short hostname.
136 * @param nnresolver network name resolver to get the host from for
137 * the replacement of a %h token.
138 * @param name name of service
139 * @param type type of service
140 * @param port port of service
141 */
143 const char * name,
144 const char * type,
145 unsigned short int port)
146{
147 std::string s = name;
148 std::string::size_type hpos = s.find("%h");
149 if (nnresolver && (hpos != std::string::npos)) {
150 s.replace(hpos, 2, nnresolver->short_hostname());
151 }
152 _name = strdup(s.c_str());
153 _type = strdup(type);
154 _domain = NULL;
155 _host = NULL;
156 _port = port;
157
158 _modified_name = NULL;
159
160 memset(&_addr, 0, sizeof(_addr));
161}
162
163/** Constructor.
164 * This constructor sets all parameters.
165 * @param name name of service
166 * @param type type of service
167 * @param domain domain of service
168 */
169NetworkService::NetworkService(const char *name, const char *type, const char *domain)
170{
171 _name = strdup(name);
172 _type = strdup(type);
173 _domain = strdup(domain);
174
175 _modified_name = NULL;
176
177 _host = NULL;
178 _port = 0;
179
180 memset(&_addr, 0, sizeof(_addr));
181}
182
183/** Destructor. */
185{
186 if (_name != NULL)
187 free(_name);
188 if (_type != NULL)
189 free(_type);
190 if (_domain != NULL)
191 free(_domain);
192 if (_host != NULL)
193 free(_host);
194 if (_modified_name != NULL)
195 free(_modified_name);
196}
197
198/** Copy constructor (pointer).
199 * Create a copy of given NetworkService.
200 * @param s network service to copy from
201 */
203{
204 _name = strdup(s->_name);
205 _type = strdup(s->_type);
206 _port = s->_port;
207 if (s->_domain != NULL) {
208 _domain = strdup(s->_domain);
209 } else {
210 _domain = NULL;
211 }
212 if (s->_host != NULL) {
213 _host = strdup(s->_host);
214 } else {
215 _host = NULL;
216 }
217
218 _modified_name = NULL;
219 if (s->_modified_name != NULL) {
220 _modified_name = strdup(s->_modified_name);
221 }
222
223 memcpy(&_addr, &s->_addr, sizeof(_addr));
224
225 list = s->list;
226}
227
228/** Copy constructor (reference).
229 * Create a copy of given NetworkService.
230 * @param s network service to copy from
231 */
233{
234 _name = strdup(s._name);
235 _type = strdup(s._type);
236 _port = s._port;
237 if (s._domain != NULL) {
238 _domain = strdup(s._domain);
239 } else {
240 _domain = NULL;
241 }
242 if (s._host != NULL) {
243 _host = strdup(s._host);
244 } else {
245 _host = NULL;
246 }
247
248 _modified_name = NULL;
249 if (s._modified_name != NULL) {
250 _modified_name = strdup(s._modified_name);
251 }
252
253 memcpy(&_addr, &s._addr, sizeof(_addr));
254
255 list = s.list;
256}
257
258/** Assignment operator.
259 * @param s network service to copy from
260 * @return reference to this instance
261 */
264{
265 if (_name != NULL)
266 free(_name);
267 if (_type != NULL)
268 free(_type);
269 if (_domain != NULL)
270 free(_domain);
271 if (_host != NULL)
272 free(_host);
273 if (_modified_name != NULL)
274 free(_modified_name);
275
276 _name = NULL;
277 _type = NULL;
278 _domain = NULL;
279 _host = NULL;
280 _modified_name = NULL;
281
282 _name = strdup(s._name);
283 _type = strdup(s._type);
284 _port = s._port;
285 if (s._domain != NULL) {
286 _domain = strdup(s._domain);
287 } else {
288 _domain = NULL;
289 }
290 if (s._host != NULL) {
291 _host = strdup(s._host);
292 } else {
293 _host = NULL;
294 }
295
296 _modified_name = NULL;
297 if (s._modified_name != NULL) {
298 _modified_name = strdup(s._modified_name);
299 }
300
301 memcpy(&_addr, &s._addr, sizeof(_addr));
302
303 list = s.list;
304
305 return *this;
306}
307
308/** Add a TXT record.
309 * @param format format for TXT record to add, must be a "key=value" string,
310 * takes the same arguments as sprintf.
311 */
312void
313NetworkService::add_txt(const char *format, ...)
314{
315 va_list arg;
316 va_start(arg, format);
317 char *tmp;
318 if (vasprintf(&tmp, format, arg) == -1) {
319 throw OutOfMemoryException("Cannot add txt record, no memory");
320 }
321 list.push_back(tmp);
322 free(tmp);
323 va_end(arg);
324}
325
326/** Set TXT records all at once.
327 * @param txtlist list of TXT records
328 */
329void
330NetworkService::set_txt(std::list<std::string> &txtlist)
331{
332 list = txtlist;
333}
334
335/** Set name of service.
336 * @param new_name new name
337 */
338void
339NetworkService::set_name(const char *new_name)
340{
341 free(_name);
342 _name = strdup(new_name);
343}
344
345/** Get name of service.
346 * @return name of service
347 */
348const char *
350{
351 return _name;
352}
353
354/** Set modified name of service.
355 * The modified name is the original name with a suffix that has been added
356 * to resolve a name collision.
357 * @param new_name new name
358 */
359void
360NetworkService::set_modified_name(const char *new_name) const
361{
362 if (_modified_name)
363 free(_modified_name);
364 _modified_name = strdup(new_name);
365}
366
367/** Get modified name of service.
368 * The modified name is the original name with a suffix that has been added
369 * to resolve a name collision.
370 * @return modified name of service, this may be NULL if the name has not
371 * been modified
372 */
373const char *
375{
376 return _modified_name;
377}
378
379/** Get type of service.
380 * @return type of service
381 */
382const char *
384{
385 return _type;
386}
387
388/** Get domain of service.
389 * @return domain of service
390 */
391const char *
393{
394 return _domain;
395}
396
397/** Get host of service.
398 * @return host of service
399 */
400const char *
402{
403 return _host;
404}
405
406/** Get port of service.
407 * @return port of service
408 */
409unsigned short int
411{
412 return _port;
413}
414
415/** Get IP address of entry as string.
416 * @return IP address as string
417 * @exception NullPointerException thrown if the address has not been set
418 */
419std::string
421{
422 if (_addr.ss_family == AF_INET) {
423 char ipaddr[INET_ADDRSTRLEN];
424 struct sockaddr_in *saddr = (struct sockaddr_in *)&_addr;
425 if (inet_ntop(AF_INET, &(saddr->sin_addr), ipaddr, sizeof(ipaddr)) != NULL) {
426 return ipaddr;
427 } else {
428 throw Exception("Failed to convert IPv4 address to string");
429 }
430 } else if (_addr.ss_family == AF_INET6) {
431 char ipaddr[INET6_ADDRSTRLEN];
432 struct sockaddr_in6 *saddr = (struct sockaddr_in6 *)&_addr;
433 if (inet_ntop(AF_INET6, &(saddr->sin6_addr), ipaddr, sizeof(ipaddr)) != NULL) {
434 return ipaddr;
435 } else {
436 throw Exception("Failed to convert IPv6 address to string");
437 }
438 } else {
439 throw Exception("Unknown address family");
440 }
441}
442
443/** Get TXT record list of service.
444 * @return TXT record list of service
445 */
446const std::list<std::string> &
448{
449 return list;
450}
451
452/** Equal operator for NetworkService reference.
453 * @param s reference of service to compare to.
454 * @return true, if the services are the same (same name and type), false otherwise
455 */
456bool
458{
459 return ((strcmp(_name, s._name) == 0) && (strcmp(_type, s._type) == 0));
460}
461
462/** Equal operator for NetworkService pointer.
463 * @param s pointer to service to compare to.
464 * @return true, if the services are the same (same name and type), false otherwise
465 */
466bool
468{
469 return ((strcmp(_name, s->_name) == 0) && (strcmp(_type, s->_type) == 0));
470}
471
472/** Less than operator.
473 * @param s reference of service to compare to
474 * @return true, if either the type is less than (according to strcmp) or if types
475 * are equal if the service name is less than the given service's name.
476 */
477bool
479{
480 int typediff = strcmp(_type, s._type);
481 if (typediff == 0) {
482 return (strcmp(_name, s._name) < 0);
483 } else {
484 return (typediff < 0);
485 }
486}
487
488} // end namespace fawkes
Base class for exceptions in Fawkes.
Definition: exception.h:36
Network name and address resolver.
Definition: resolver.h:45
const char * short_hostname()
Get short hostname.
Definition: resolver.cpp:354
Representation of a service announced or found via service discovery (i.e.
Definition: service.h:38
std::string addr_string() const
Get IP address of entry as string.
Definition: service.cpp:420
~NetworkService()
Destructor.
Definition: service.cpp:184
bool operator==(const NetworkService &s) const
Equal operator for NetworkService reference.
Definition: service.cpp:457
void set_modified_name(const char *new_name) const
Set modified name of service.
Definition: service.cpp:360
const char * modified_name() const
Get modified name of service.
Definition: service.cpp:374
const char * type() const
Get type of service.
Definition: service.cpp:383
void set_txt(std::list< std::string > &txtlist)
Set TXT records all at once.
Definition: service.cpp:330
void add_txt(const char *format,...)
Add a TXT record.
Definition: service.cpp:313
unsigned short int port() const
Get port of service.
Definition: service.cpp:410
NetworkService & operator=(const NetworkService &s)
Assignment operator.
Definition: service.cpp:263
void set_name(const char *new_name)
Set name of service.
Definition: service.cpp:339
NetworkService(const char *name, const char *type, const char *domain, const char *host, unsigned short int port)
Constructor.
Definition: service.cpp:57
const char * name() const
Get name of service.
Definition: service.cpp:349
const char * host() const
Get host of service.
Definition: service.cpp:401
bool operator<(const NetworkService &s) const
Less than operator.
Definition: service.cpp:478
const char * domain() const
Get domain of service.
Definition: service.cpp:392
const std::list< std::string > & txt() const
Get TXT record list of service.
Definition: service.cpp:447
System ran out of memory and desired operation could not be fulfilled.
Definition: system.h:32
Fawkes library namespace.