JDNS
jdns.h
1 /*
2  * Copyright (C) 2005,2006 Justin Karneges
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the
6  * "Software"), to deal in the Software without restriction, including
7  * without limitation the rights to use, copy, modify, merge, publish,
8  * distribute, sublicense, and/or sell copies of the Software, and to
9  * permit persons to whom the Software is furnished to do so, subject to
10  * the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included
13  * in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22  */
23 
24 #ifndef JDNS_H
25 #define JDNS_H
26 
27 #include "jdns_export.h"
28 
29 #ifdef __cplusplus
30 extern "C" {
31 #endif
32 
33 typedef void (*jdns_object_dtor_func)(void *);
34 typedef void *(*jdns_object_cctor_func)(const void *);
35 
36 #define JDNS_OBJECT \
37  jdns_object_dtor_func dtor; \
38  jdns_object_cctor_func cctor;
39 
40 #define JDNS_OBJECT_NEW(name) \
41  (name##_t *)jdns_object_new(sizeof(name##_t), \
42  (jdns_object_dtor_func)name##_delete, \
43  (jdns_object_cctor_func)name##_copy);
44 
45 typedef struct jdns_object
46 {
47  JDNS_OBJECT
49 
50 JDNS_EXPORT void *jdns_object_new(int size, void (*dtor)(void *),
51  void *(*cctor)(const void *));
52 JDNS_EXPORT void *jdns_object_copy(const void *a);
53 JDNS_EXPORT void jdns_object_delete(void *a);
54 JDNS_EXPORT void jdns_object_free(void *a);
55 
56 #define JDNS_LIST_DECLARE(name) \
57  JDNS_OBJECT \
58  int count; \
59  name##_t **item;
60 
61 typedef struct jdns_list
62 {
63  JDNS_OBJECT
64  int count;
65  void **item;
66  int valueList;
67  int autoDelete;
68 } jdns_list_t;
69 
70 JDNS_EXPORT jdns_list_t *jdns_list_new();
71 JDNS_EXPORT jdns_list_t *jdns_list_copy(const jdns_list_t *a);
72 JDNS_EXPORT void jdns_list_delete(jdns_list_t *a);
73 JDNS_EXPORT void jdns_list_clear(jdns_list_t *a);
74 JDNS_EXPORT void jdns_list_insert(jdns_list_t *a, void *item, int pos);
75 JDNS_EXPORT void jdns_list_insert_value(jdns_list_t *a, const void *item, int pos);
76 JDNS_EXPORT void jdns_list_remove(jdns_list_t *a, void *item);
77 JDNS_EXPORT void jdns_list_remove_at(jdns_list_t *a, int pos);
78 
79 typedef struct jdns_string
80 {
81  JDNS_OBJECT
82  unsigned char *data;
83  int size;
85 
86 JDNS_EXPORT jdns_string_t *jdns_string_new();
87 JDNS_EXPORT jdns_string_t *jdns_string_copy(const jdns_string_t *s);
88 JDNS_EXPORT void jdns_string_delete(jdns_string_t *s);
89 JDNS_EXPORT void jdns_string_set(jdns_string_t *s, const unsigned char *str,
90  int str_len);
91 JDNS_EXPORT void jdns_string_set_cstr(jdns_string_t *s, const char *str);
92 
93  // overlays jdns_list
94 typedef struct jdns_stringlist
95 {
96  JDNS_OBJECT
97  int count;
98  jdns_string_t **item;
100 
101 JDNS_EXPORT jdns_stringlist_t *jdns_stringlist_new();
102 JDNS_EXPORT jdns_stringlist_t *jdns_stringlist_copy(const jdns_stringlist_t *a);
103 JDNS_EXPORT void jdns_stringlist_delete(jdns_stringlist_t *a);
104 JDNS_EXPORT void jdns_stringlist_append(jdns_stringlist_t *a, const jdns_string_t *str);
105 
106 typedef struct jdns_address
107 {
108  int isIpv6;
109  union
110  {
111  unsigned long int v4;
112  unsigned char *v6; // 16 bytes
113  } addr;
114  char *c_str;
116 
117 JDNS_EXPORT jdns_address_t *jdns_address_new();
118 JDNS_EXPORT jdns_address_t *jdns_address_copy(const jdns_address_t *a);
119 JDNS_EXPORT void jdns_address_delete(jdns_address_t *a);
120 JDNS_EXPORT void jdns_address_set_ipv4(jdns_address_t *a, unsigned long int ipv4);
121 JDNS_EXPORT void jdns_address_set_ipv6(jdns_address_t *a, const unsigned char *ipv6);
122 // return 1 if string was ok, else 0. Note: IPv4 addresses only!
123 JDNS_EXPORT int jdns_address_set_cstr(jdns_address_t *a, const char *str);
124 // return 1 if the same, else 0
125 JDNS_EXPORT int jdns_address_cmp(const jdns_address_t *a, const jdns_address_t *b);
126 
127 // convenient predefined addresses/ports
128 #define JDNS_UNICAST_PORT 53
129 #define JDNS_MULTICAST_PORT 5353
130 JDNS_EXPORT jdns_address_t *jdns_address_multicast4_new(); // 224.0.0.251
131 JDNS_EXPORT jdns_address_t *jdns_address_multicast6_new(); // FF02::FB
132 
133 typedef struct jdns_server
134 {
135  unsigned char *name;
136  int port; // SRV only
137  int priority;
138  int weight; // SRV only
139 } jdns_server_t;
140 
141 JDNS_EXPORT jdns_server_t *jdns_server_new();
142 JDNS_EXPORT jdns_server_t *jdns_server_copy(const jdns_server_t *s);
143 JDNS_EXPORT void jdns_server_delete(jdns_server_t *s);
144 JDNS_EXPORT void jdns_server_set_name(jdns_server_t *s, const unsigned char *name);
145 
146 typedef struct jdns_nameserver
147 {
148  jdns_address_t *address;
149  int port;
151 
152 JDNS_EXPORT jdns_nameserver_t *jdns_nameserver_new();
153 JDNS_EXPORT jdns_nameserver_t *jdns_nameserver_copy(const jdns_nameserver_t *a);
154 JDNS_EXPORT void jdns_nameserver_delete(jdns_nameserver_t *a);
155 JDNS_EXPORT void jdns_nameserver_set(jdns_nameserver_t *a, const jdns_address_t *addr,
156  int port);
157 
158 typedef struct jdns_nameserverlist
159 {
160  int count;
161  jdns_nameserver_t **item;
163 
164 JDNS_EXPORT jdns_nameserverlist_t *jdns_nameserverlist_new();
165 JDNS_EXPORT jdns_nameserverlist_t *jdns_nameserverlist_copy(const jdns_nameserverlist_t *a);
166 JDNS_EXPORT void jdns_nameserverlist_delete(jdns_nameserverlist_t *a);
167 JDNS_EXPORT void jdns_nameserverlist_append(jdns_nameserverlist_t *a,
168  const jdns_address_t *addr, int port);
169 
170 typedef struct jdns_dnshost
171 {
172  jdns_string_t *name;
173  jdns_address_t *address;
175 
176 typedef struct jdns_dnshostlist
177 {
178  int count;
179  jdns_dnshost_t **item;
181 
182 typedef struct jdns_dnsparams
183 {
184  jdns_nameserverlist_t *nameservers;
185  jdns_stringlist_t *domains;
186  jdns_dnshostlist_t *hosts;
188 
189 JDNS_EXPORT jdns_dnsparams_t *jdns_dnsparams_new();
190 JDNS_EXPORT jdns_dnsparams_t *jdns_dnsparams_copy(jdns_dnsparams_t *a);
191 JDNS_EXPORT void jdns_dnsparams_delete(jdns_dnsparams_t *a);
192 JDNS_EXPORT void jdns_dnsparams_append_nameserver(jdns_dnsparams_t *a,
193  const jdns_address_t *addr, int port);
194 JDNS_EXPORT void jdns_dnsparams_append_domain(jdns_dnsparams_t *a,
195  const jdns_string_t *domain);
196 JDNS_EXPORT void jdns_dnsparams_append_host(jdns_dnsparams_t *a,
197  const jdns_string_t *name, const jdns_address_t *address);
198 
199 #define JDNS_RTYPE_A 1
200 #define JDNS_RTYPE_AAAA 28
201 #define JDNS_RTYPE_MX 15
202 #define JDNS_RTYPE_SRV 33
203 #define JDNS_RTYPE_CNAME 5
204 #define JDNS_RTYPE_PTR 12
205 #define JDNS_RTYPE_TXT 16
206 #define JDNS_RTYPE_HINFO 13
207 #define JDNS_RTYPE_NS 2
208 #define JDNS_RTYPE_ANY 255
209 
210 typedef struct jdns_rr
211 {
212  unsigned char *owner;
213  int ttl;
214  int type;
215  int qclass;
216  int rdlength;
217  unsigned char *rdata;
218  int haveKnown;
219 
220  union
221  {
222  jdns_address_t *address; // for A, AAAA
223  jdns_server_t *server; // for MX, SRV
224  unsigned char *name; // for CNAME, PTR, NS
225  jdns_stringlist_t *texts; // for TXT
226  struct
227  {
228  jdns_string_t *cpu;
229  jdns_string_t *os;
230  } hinfo; // for HINFO
231  } data;
232 } jdns_rr_t;
233 
234 JDNS_EXPORT jdns_rr_t *jdns_rr_new();
235 JDNS_EXPORT jdns_rr_t *jdns_rr_copy(const jdns_rr_t *r);
236 JDNS_EXPORT void jdns_rr_delete(jdns_rr_t *r);
237 JDNS_EXPORT void jdns_rr_set_owner(jdns_rr_t *r, const unsigned char *name);
238 JDNS_EXPORT void jdns_rr_set_record(jdns_rr_t *r, int type, const unsigned char *rdata,
239  int rdlength);
240 JDNS_EXPORT void jdns_rr_set_A(jdns_rr_t *r, const jdns_address_t *address);
241 JDNS_EXPORT void jdns_rr_set_AAAA(jdns_rr_t *r, const jdns_address_t *address);
242 JDNS_EXPORT void jdns_rr_set_MX(jdns_rr_t *r, const unsigned char *name, int priority);
243 JDNS_EXPORT void jdns_rr_set_SRV(jdns_rr_t *r, const unsigned char *name, int port,
244  int priority, int weight);
245 JDNS_EXPORT void jdns_rr_set_CNAME(jdns_rr_t *r, const unsigned char *name);
246 JDNS_EXPORT void jdns_rr_set_PTR(jdns_rr_t *r, const unsigned char *name);
247 JDNS_EXPORT void jdns_rr_set_TXT(jdns_rr_t *r, const jdns_stringlist_t *texts);
248 JDNS_EXPORT void jdns_rr_set_HINFO(jdns_rr_t *r, const jdns_string_t *cpu,
249  const jdns_string_t *os);
250 JDNS_EXPORT void jdns_rr_set_NS(jdns_rr_t *r, const unsigned char *name);
251 // note: only works on known types
252 JDNS_EXPORT int jdns_rr_verify(const jdns_rr_t *r);
253 
254 typedef struct jdns_response
255 {
256  int answerCount;
257  jdns_rr_t **answerRecords;
258  int authorityCount;
259  jdns_rr_t **authorityRecords;
260  int additionalCount;
261  jdns_rr_t **additionalRecords;
263 
264 JDNS_EXPORT jdns_response_t *jdns_response_new();
265 JDNS_EXPORT jdns_response_t *jdns_response_copy(const jdns_response_t *r);
266 JDNS_EXPORT void jdns_response_delete(jdns_response_t *r);
267 JDNS_EXPORT void jdns_response_append_answer(jdns_response_t *r, const jdns_rr_t *rr);
268 JDNS_EXPORT void jdns_response_append_authority(jdns_response_t *r, const jdns_rr_t *rr);
269 JDNS_EXPORT void jdns_response_append_additional(jdns_response_t *r,
270  const jdns_rr_t *rr);
271 
272 #define JDNS_PUBLISH_SHARED 0x0001
273 #define JDNS_PUBLISH_UNIQUE 0x0002
274 
275 #define JDNS_STEP_TIMER 0x0001
276 #define JDNS_STEP_HANDLE 0x0002
277 
278 #define JDNS_EVENT_RESPONSE 0x0001
279 #define JDNS_EVENT_PUBLISH 0x0002
280 #define JDNS_EVENT_SHUTDOWN 0x0003
281 
282 #define JDNS_STATUS_SUCCESS 0x0001
283 #define JDNS_STATUS_NXDOMAIN 0x0002
284 #define JDNS_STATUS_ERROR 0x0003
285 #define JDNS_STATUS_TIMEOUT 0x0004
286 #define JDNS_STATUS_CONFLICT 0x0005
287 
288 typedef struct jdns_session jdns_session_t;
289 
290 typedef struct jdns_callbacks
291 {
292  void *app; // user-supplied context
293 
294  // time_now:
295  // s: session
296  // app: user-supplied context
297  // return: milliseconds since session started
298  int (*time_now)(jdns_session_t *s, void *app);
299 
300  // rand_int:
301  // s: session
302  // app: user-supplied context
303  // return: random integer between 0-65535
304  int (*rand_int)(jdns_session_t *s, void *app);
305 
306  // debug_line:
307  // s: session
308  // app: user-supplied context
309  // str: a line of debug text
310  // return: nothing
311  void (*debug_line)(jdns_session_t *s, void *app, const char *str);
312 
313  // udp_bind:
314  // s: session
315  // app: user-supplied context
316  // addr: ip address of interface to bind to. 0 for all
317  // port: port of interface to bind to. 0 for any
318  // maddr: multicast address. 0 if not using multicast
319  // return: handle (>0) of bound socket, or 0 on error
320  // note: for multicast, the following must be done:
321  // use SO_REUSEPORT to share with other mdns programs
322  // use IP_ADD_MEMBERSHIP to associate addr and maddr
323  // set IP_MULTICAST_TTL to 255
324  int (*udp_bind)(jdns_session_t *s, void *app,
325  const jdns_address_t *addr, int port,
326  const jdns_address_t *maddr);
327 
328  // udp_unbind:
329  // s: session
330  // app: user-supplied context
331  // handle: handle of socket obtained with udp_bind
332  // return: nothing
333  void (*udp_unbind)(jdns_session_t *s, void *app, int handle);
334 
335  // udp_read:
336  // s: session
337  // app: user-supplied context
338  // handle: handle of socket obtained with udp_bind
339  // addr: store ip address of sender
340  // port: store port of sender
341  // buf: store packet content
342  // bufsize: value contains max size, to be changed to real size
343  // return: 1 if packet read, 0 if none available
344  int (*udp_read)(jdns_session_t *s, void *app, int handle,
345  jdns_address_t *addr, int *port, unsigned char *buf,
346  int *bufsize);
347 
348  // udp_write:
349  // s: session
350  // app: user-supplied context
351  // handle: handle of socket obtained with udp_bind
352  // addr: ip address of recipient
353  // port: port of recipient
354  // buf: packet content
355  // bufsize: size of packet
356  // return: 1 if packet taken for writing, 0 if this is a bad time
357  int (*udp_write)(jdns_session_t *s, void *app, int handle,
358  const jdns_address_t *addr, int port, unsigned char *buf,
359  int bufsize);
361 
362 typedef struct jdns_event
363 {
364  int type; // JDNS_EVENT
365  int id; // query id or publish id
366 
367  // for query, this can be SUCCESS, NXDOMAIN, ERROR, or TIMEOUT
368  // for publish, this can be SUCCESS, ERROR, or CONFLICT
369  int status;
370 
371  // for query
372  jdns_response_t *response;
373 } jdns_event_t;
374 
375 JDNS_EXPORT void jdns_event_delete(jdns_event_t *e);
376 
377 // jdns_session_new:
378 // callbacks: the struct of callbacks
379 // return: newly allocated session
380 JDNS_EXPORT jdns_session_t *jdns_session_new(jdns_callbacks_t *callbacks);
381 
382 // jdns_session_delete:
383 // s: session to free
384 // return: nothing
385 JDNS_EXPORT void jdns_session_delete(jdns_session_t *s);
386 
387 // jdns_init_unicast:
388 // s: session
389 // addr: ip address of interface to bind to. NULL for all
390 // port: port of interface to bind to. 0 for any
391 // return: 1 on success, 0 on failure
392 JDNS_EXPORT int jdns_init_unicast(jdns_session_t *s, const jdns_address_t *addr,
393  int port);
394 
395 // jdns_init_multicast:
396 // s: session
397 // addr: ip address of interface to bind to. NULL for all
398 // port: port of interface to bind to. 0 for any
399 // addr: multicast address to associate with. cannot be NULL
400 // return: 1 on success, 0 on failure
401 JDNS_EXPORT int jdns_init_multicast(jdns_session_t *s, const jdns_address_t *addr,
402  int port, const jdns_address_t *maddr);
403 
404 // jdns_shutdown:
405 // s: session
406 // return: nothing
407 JDNS_EXPORT void jdns_shutdown(jdns_session_t *s);
408 
409 // jdns_set_nameservers:
410 // s: session
411 // nslist: list of nameservers
412 // return nothing
413 JDNS_EXPORT void jdns_set_nameservers(jdns_session_t *s,
414  const jdns_nameserverlist_t *nslist);
415 
416 // jdns_probe:
417 // s: session
418 // return: nothing
419 JDNS_EXPORT void jdns_probe(jdns_session_t *s);
420 
421 // jdns_query:
422 // s: session
423 // name: the name to look up
424 // rtype: the record type
425 // return: id of this operation
426 JDNS_EXPORT int jdns_query(jdns_session_t *s, const unsigned char *name, int rtype);
427 
428 // jdns_cancel_query:
429 // s: session
430 // id: the operation id to cancel
431 // return: nothing
432 JDNS_EXPORT void jdns_cancel_query(jdns_session_t *s, int id);
433 
434 // jdns_publish:
435 // s: session
436 // mode: JDNS_PUBLISH shared or unique
437 // rec: the record data
438 // return: id of this operation
439 // note: supported record types: A, AAAA, SRV, CNAME, PTR, TXT, and HINFO.
440 // if the published type is not one of these, raw rdata must be set.
441 JDNS_EXPORT int jdns_publish(jdns_session_t *s, int mode, const jdns_rr_t *rec);
442 
443 // jdns_update_publish:
444 // s: session
445 // id: the operation id to update
446 // rec: the record data
447 // return: nothing
448 // note: update only works on successfully published records, and no event
449 // is generated for a successful update.
450 JDNS_EXPORT void jdns_update_publish(jdns_session_t *s, int id, const jdns_rr_t *rec);
451 
452 // jdns_cancel_publish:
453 // s: session
454 // id: the operation id to cancel
455 // return: nothing
456 JDNS_EXPORT void jdns_cancel_publish(jdns_session_t *s, int id);
457 
458 // jdns_step:
459 // s: session
460 // return: JDNS_STEP flags OR'd together
461 JDNS_EXPORT int jdns_step(jdns_session_t *s);
462 
463 // jdns_next_timer:
464 // s: session
465 // return: milliseconds until timeout
466 JDNS_EXPORT int jdns_next_timer(jdns_session_t *s);
467 
468 // jdns_set_handle_readable:
469 // s: session
470 // handle: handle that is now readable
471 // return: nothing
472 JDNS_EXPORT void jdns_set_handle_readable(jdns_session_t *s, int handle);
473 
474 // jdns_set_handle_writable:
475 // s: session
476 // handle: handle that is now writable
477 // return: nothing
478 JDNS_EXPORT void jdns_set_handle_writable(jdns_session_t *s, int handle);
479 
480 // jdns_next_event:
481 // s: session
482 // return: newly allocated event, or zero if none are ready
483 JDNS_EXPORT jdns_event_t *jdns_next_event(jdns_session_t *s);
484 
485 // jdns_system_dnsparams:
486 // return: newly allocated dnsparams from the system
487 JDNS_EXPORT jdns_dnsparams_t *jdns_system_dnsparams();
488 
489 // jdns_set_hold_ids_enabled
490 // s: session
491 // enabled: whether to enable id holding. default is 0 (disabled)
492 // return: nothing
493 // normally, when a unicast query completes or any kind of query or publish
494 // operation results in an error, the operation is automatically "canceled".
495 // when id holding is enabled, the operation still stops internally, but the
496 // id value used by that operation is "held" until the application
497 // explicitly calls jdns_cancel_query() or jdns_cancel_publish() to release
498 // it. this allows the application to ensure there is no ambiguity when
499 // determining which operation a particular event belongs to. it is disabled
500 // be default so as to not introduce memory leaks in existing applications,
501 // however new applications really should use it.
502 JDNS_EXPORT void jdns_set_hold_ids_enabled(jdns_session_t *s, int enabled);
503 
504 #ifdef __cplusplus
505 }
506 #endif
507 
508 #endif
jdns_dnsparams
Definition: jdns.h:182
jdns_callbacks
Definition: jdns.h:290
jdns_server
Definition: jdns.h:133
jdns_list
Definition: jdns.h:61
jdns_stringlist
Definition: jdns.h:94
jdns_dnshostlist
Definition: jdns.h:176
jdns_nameserverlist
Definition: jdns.h:158
jdns_string
Definition: jdns.h:79
jdns_response
Definition: jdns.h:254
jdns_object
Definition: jdns.h:45
jdns_event
Definition: jdns.h:362
jdns_address
Definition: jdns.h:106
jdns_dnshost
Definition: jdns.h:170
jdns_rr
Definition: jdns.h:210
jdns_nameserver
Definition: jdns.h:146