]> CyberLeo.Net >> Repos - FreeBSD/releng/9.3.git/blob - contrib/bind9/lib/dns/include/dns/client.h
Copy stable/9 to releng/9.3 as part of the 9.3-RELEASE cycle.
[FreeBSD/releng/9.3.git] / contrib / bind9 / lib / dns / include / dns / client.h
1 /*
2  * Copyright (C) 2009, 2013  Internet Systems Consortium, Inc. ("ISC")
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
9  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
11  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
13  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14  * PERFORMANCE OF THIS SOFTWARE.
15  */
16
17 /* $Id: client.h,v 1.3 2009/09/02 23:48:02 tbox Exp $ */
18
19 #ifndef DNS_CLIENT_H
20 #define DNS_CLIENT_H 1
21
22 /*****
23  ***** Module Info
24  *****/
25
26 /*! \file
27  *
28  * \brief
29  * The DNS client module provides convenient programming interfaces to various
30  * DNS services, such as name resolution with or without DNSSEC validation or
31  * dynamic DNS update.  This module is primarily expected to be used by other
32  * applications than BIND9-related ones that need such advanced DNS features.
33  *
34  * MP:
35  *\li   In the typical usage of this module, application threads will not share
36  *      the same data structures created and manipulated in this module.
37  *      However, the module still ensures appropriate synchronization of such
38  *      data structures.
39  *
40  * Resources:
41  *\li   TBS
42  *
43  * Security:
44  *\li   This module does not handle any low-level data directly, and so no
45  *      security issue specific to this module is anticipated.
46  */
47
48 #include <isc/event.h>
49 #include <isc/sockaddr.h>
50
51 #include <dns/tsig.h>
52 #include <dns/types.h>
53
54 #include <dst/dst.h>
55
56 typedef enum {
57         updateop_none = 0,
58         updateop_add = 1,
59         updateop_delete = 2,
60         updateop_exist = 3,
61         updateop_notexist = 4,
62         updateop_max = 5
63 } dns_client_updateop_t;
64
65 ISC_LANG_BEGINDECLS
66
67 /***
68  *** Types
69  ***/
70
71 /*%
72  * Optional flags for dns_client_create(x).
73  */
74 /*%< Enable caching resolution results (experimental). */
75 #define DNS_CLIENTCREATEOPT_USECACHE    0x8000
76
77 /*%
78  * Optional flags for dns_client_(start)resolve.
79  */
80 /*%< Disable DNSSEC validation. */
81 #define DNS_CLIENTRESOPT_NODNSSEC       0x01
82 /*%< Allow running external context. */
83 #define DNS_CLIENTRESOPT_ALLOWRUN       0x02
84
85 /*%
86  * Optional flags for dns_client_(start)request.
87  */
88 /*%< Allow running external context. */
89 #define DNS_CLIENTREQOPT_ALLOWRUN       0x01
90
91 /*%
92  * A dns_clientresevent_t is sent when name resolution performed by a client
93  * completes.  'result' stores the result code of the entire resolution
94  * procedure.  'vresult' specifically stores the result code of DNSSEC
95  * validation if it is performed.  When name resolution successfully completes,
96  * 'answerlist' is typically non empty, containing answer names along with
97  * RRsets.  It is the receiver's responsibility to free this list by calling
98  * dns_client_freeresanswer() before freeing the event structure.
99  */
100 typedef struct dns_clientresevent {
101         ISC_EVENT_COMMON(struct dns_clientresevent);
102         isc_result_t    result;
103         isc_result_t    vresult;
104         dns_namelist_t  answerlist;
105 } dns_clientresevent_t;         /* too long? */
106
107 /*%
108  * Status of a dynamic update procedure.
109  */
110 typedef enum {
111         dns_clientupdatestate_prepare,  /*%< no updates have been sent */
112         dns_clientupdatestate_sent,     /*%< updates were sent, no response */
113         dns_clientupdatestate_done      /*%< update was sent and succeeded */
114 } dns_clientupdatestate_t;
115
116 /*%
117  * A dns_clientreqevent_t is sent when a DNS request is completed by a client.
118  * 'result' stores the result code of the entire transaction.
119  * If the transaction is successfully completed but the response packet cannot
120  * be parsed, 'result' will store the result code of dns_message_parse().
121  * If the response packet is received, 'rmessage' will contain the response
122  * message, whether it is successfully parsed or not.
123  */
124 typedef struct dns_clientreqevent {
125         ISC_EVENT_COMMON(struct dns_clientreqevent);
126         isc_result_t    result;
127         dns_message_t   *rmessage;
128 } dns_clientreqevent_t;         /* too long? */
129
130 /*%
131  * A dns_clientupdateevent_t is sent when dynamic update performed by a client
132  * completes.  'result' stores the result code of the entire update procedure.
133  * 'state' specifies the status of the update procedure when this event is
134  * sent.  This can be used as a hint by the receiver to determine whether
135  * the update attempt was ever made.  In particular, if the state is
136  * dns_clientupdatestate_prepare, the receiver can be sure that the requested
137  * update was not applied.
138  */
139 typedef struct dns_clientupdateevent {
140         ISC_EVENT_COMMON(struct dns_clientupdateevent);
141         isc_result_t            result;
142         dns_clientupdatestate_t state;
143 } dns_clientupdateevent_t;      /* too long? */
144
145 isc_result_t
146 dns_client_create(dns_client_t **clientp, unsigned int options);
147
148 isc_result_t
149 dns_client_createx(isc_mem_t *mctx, isc_appctx_t *actx, isc_taskmgr_t *taskmgr,
150                    isc_socketmgr_t *socketmgr, isc_timermgr_t *timermgr,
151                    unsigned int options, dns_client_t **clientp);
152
153 isc_result_t
154 dns_client_createx2(isc_mem_t *mctx, isc_appctx_t *actx,
155            isc_taskmgr_t *taskmgr, isc_socketmgr_t *socketmgr,
156            isc_timermgr_t *timermgr, unsigned int options,
157            dns_client_t **clientp,
158            isc_sockaddr_t *localaddr4, isc_sockaddr_t *localaddr6);
159 /*%<
160  * Create a DNS client.  These functions create a new client object with
161  * minimal internal resources such as the default 'view' for the IN class and
162  * IPv4/IPv6 dispatches for the view.
163  *
164  * dns_client_createx() takes 'manager' arguments so that the caller can
165  * control the behavior of the client through the underlying event framework.
166  * On the other hand, dns_client_create() simplifies the interface and creates
167  * the managers internally.  A DNS client object created via
168  * dns_client_create() is expected to be used by an application that only needs
169  * simple synchronous services or by a thread-based application.
170  *
171  * dns_client_createx2 takes two additional parameters, 'localaddr4' and
172  * 'localaddr6', to specify the local address to use for each family. If
173  * both are set to NULL, then wildcard addresses will be used for both
174  * families. If only one is NULL, then the other address will be used
175  * as the local address, and the other protocol family will not be used.
176  *
177  * If the DNS_CLIENTCREATEOPT_USECACHE flag is set in 'options',
178  * dns_client_create(x) will create a cache database with the view.
179  *
180  * Requires:
181  *
182  *\li   'mctx' is a valid memory context.
183  *
184  *\li   'actx' is a valid application context.
185  *
186  *\li   'taskmgr' is a valid task manager.
187  *
188  *\li   'socketmgr' is a valid socket manager.
189  *
190  *\li   'timermgr' is a valid timer manager.
191  *
192  *\li   clientp != NULL && *clientp == NULL.
193  *
194  * Returns:
195  *
196  *\li   #ISC_R_SUCCESS                          On success.
197  *
198  *\li   Anything else                           Failure.
199  */
200
201 void
202 dns_client_destroy(dns_client_t **clientp);
203 /*%<
204  * Destroy 'client'.
205  *
206  * Requires:
207  *
208  *\li   '*clientp' is a valid client.
209  *
210  * Ensures:
211  *
212  *\li   *clientp == NULL.
213  */
214
215 isc_result_t
216 dns_client_setservers(dns_client_t *client, dns_rdataclass_t rdclass,
217                       dns_name_t *namespace, isc_sockaddrlist_t *addrs);
218 /*%<
219  * Specify a list of addresses of recursive name servers that the client will
220  * use for name resolution.  A view for the 'rdclass' class must be created
221  * beforehand.  If 'namespace' is non NULL, the specified server will be used
222  * if and only if the query name is a subdomain of 'namespace'.  When servers
223  * for multiple 'namespace's are provided, and a query name is covered by
224  * more than one 'namespace', the servers for the best (longest) matching
225  * namespace will be used.  If 'namespace' is NULL, it works as if
226  * dns_rootname (.) were specified.
227  *
228  * Requires:
229  *
230  *\li   'client' is a valid client.
231  *
232  *\li   'namespace' is NULL or a valid name.
233  *
234  *\li   'addrs' != NULL.
235  *
236  * Returns:
237  *
238  *\li   #ISC_R_SUCCESS                          On success.
239  *
240  *\li   Anything else                           Failure.
241  */
242
243 isc_result_t
244 dns_client_clearservers(dns_client_t *client, dns_rdataclass_t rdclass,
245                         dns_name_t *namespace);
246 /*%<
247  * Remove configured recursive name servers for the 'rdclass' and 'namespace'
248  * from the client.  See the description of dns_client_setservers() for
249  * the requirements about 'rdclass' and 'namespace'.
250  *
251  * Requires:
252  *
253  *\li   'client' is a valid client.
254  *
255  *\li   'namespace' is NULL or a valid name.
256  *
257  * Returns:
258  *
259  *\li   #ISC_R_SUCCESS                          On success.
260  *
261  *\li   Anything else                           Failure.
262  */
263
264 isc_result_t
265 dns_client_resolve(dns_client_t *client, dns_name_t *name,
266                    dns_rdataclass_t rdclass, dns_rdatatype_t type,
267                    unsigned int options, dns_namelist_t *namelist);
268
269 isc_result_t
270 dns_client_startresolve(dns_client_t *client, dns_name_t *name,
271                         dns_rdataclass_t rdclass, dns_rdatatype_t type,
272                         unsigned int options, isc_task_t *task,
273                         isc_taskaction_t action, void *arg,
274                         dns_clientrestrans_t **transp);
275 /*%<
276  * Perform name resolution for 'name', 'rdclass', and 'type'.
277  *
278  * If any trusted keys are configured and the query name is considered to
279  * belong to a secure zone, these functions also validate the responses
280  * using DNSSEC by default.  If the DNS_CLIENTRESOPT_NODNSSEC flag is set
281  * in 'options', DNSSEC validation is disabled regardless of the configured
282  * trusted keys or the query name.
283  *
284  * dns_client_resolve() provides a synchronous service.  This function starts
285  * name resolution internally and blocks until it completes.  On success,
286  * 'namelist' will contain a list of answer names, each of which has
287  * corresponding RRsets.  The caller must provide a valid empty list, and
288  * is responsible for freeing the list content via dns_client_freeresanswer().
289  * If the name resolution fails due to an error in DNSSEC validation,
290  * dns_client_resolve() returns the result code indicating the validation
291  * error. Otherwise, it returns the result code of the entire resolution
292  * process, either success or failure.
293  *
294  * It is typically expected that the client object passed to
295  * dns_client_resolve() was created via dns_client_create() and has its own
296  * managers and contexts.  However, if the DNS_CLIENTRESOPT_ALLOWRUN flag is
297  * set in 'options', this function performs the synchronous service even if
298  * it does not have its own manager and context structures.
299  *
300  * dns_client_startresolve() is an asynchronous version of dns_client_resolve()
301  * and does not block.  When name resolution is completed, 'action' will be
302  * called with the argument of a 'dns_clientresevent_t' object, which contains
303  * the resulting list of answer names (on success).  On return, '*transp' is
304  * set to an opaque transaction ID so that the caller can cancel this
305  * resolution process.
306  *
307  * Requires:
308  *
309  *\li   'client' is a valid client.
310  *
311  *\li   'addrs' != NULL.
312  *
313  *\li   'name' is a valid name.
314  *
315  *\li   'namelist' != NULL and is not empty.
316  *
317  *\li   'task' is a valid task.
318  *
319  *\li   'transp' != NULL && *transp == NULL;
320  *
321  * Returns:
322  *
323  *\li   #ISC_R_SUCCESS                          On success.
324  *
325  *\li   Anything else                           Failure.
326  */
327
328 void
329 dns_client_cancelresolve(dns_clientrestrans_t *trans);
330 /*%<
331  * Cancel an ongoing resolution procedure started via
332  * dns_client_startresolve().
333  *
334  * Notes:
335  *
336  *\li   If the resolution procedure has not completed, post its CLIENTRESDONE
337  *      event with a result code of #ISC_R_CANCELED.
338  *
339  * Requires:
340  *
341  *\li   'trans' is a valid transaction ID.
342  */
343
344 void
345 dns_client_destroyrestrans(dns_clientrestrans_t **transp);
346 /*%<
347  * Destroy name resolution transaction state identified by '*transp'.
348  *
349  * Requires:
350  *
351  *\li   '*transp' is a valid transaction ID.
352  *
353  *\li   The caller has received the CLIENTRESDONE event (either because the
354  *      resolution completed or because dns_client_cancelresolve() was called).
355  *
356  * Ensures:
357  *
358  *\li   *transp == NULL.
359  */
360
361 void
362 dns_client_freeresanswer(dns_client_t *client, dns_namelist_t *namelist);
363 /*%<
364  * Free resources allocated for the content of 'namelist'.
365  *
366  * Requires:
367  *
368  *\li   'client' is a valid client.
369  *
370  *\li   'namelist' != NULL.
371  */
372
373 isc_result_t
374 dns_client_addtrustedkey(dns_client_t *client, dns_rdataclass_t rdclass,
375                          dns_name_t *keyname, isc_buffer_t *keydatabuf);
376 /*%<
377  * Add a DNSSEC trusted key for the 'rdclass' class.  A view for the 'rdclass'
378  * class must be created beforehand.  'keyname' is the DNS name of the key,
379  * and 'keydatabuf' stores the resource data of the key.
380  *
381  * Requires:
382  *
383  *\li   'client' is a valid client.
384  *
385  *\li   'keyname' is a valid name.
386  *
387  *\li   'keydatabuf' is a valid buffer.
388  *
389  * Returns:
390  *
391  *\li   #ISC_R_SUCCESS                          On success.
392  *
393  *\li   Anything else                           Failure.
394  */
395
396 isc_result_t
397 dns_client_request(dns_client_t *client, dns_message_t *qmessage,
398                    dns_message_t *rmessage, isc_sockaddr_t *server,
399                    unsigned int options, unsigned int parseoptions,
400                    dns_tsec_t *tsec, unsigned int timeout,
401                    unsigned int udptimeout, unsigned int udpretries);
402
403 isc_result_t
404 dns_client_startrequest(dns_client_t *client, dns_message_t *qmessage,
405                         dns_message_t *rmessage, isc_sockaddr_t *server,
406                         unsigned int options, unsigned int parseoptions,
407                         dns_tsec_t *tsec, unsigned int timeout,
408                         unsigned int udptimeout, unsigned int udpretries,
409                         isc_task_t *task, isc_taskaction_t action, void *arg,
410                         dns_clientreqtrans_t **transp);
411
412 /*%<
413  * Send a DNS request containig a query message 'query' to 'server'.
414  *
415  * 'parseoptions' will be used when the response packet is parsed, and will be
416  * passed to dns_message_parse() via dns_request_getresponse().  See
417  * dns_message_parse() for more details.
418  *
419  * 'tsec' is a transaction security object containing, e.g. a TSIG key for
420  * authenticating the request/response transaction.  This is optional and can
421  * be NULL, in which case this library performs the transaction  without any
422  * transaction authentication.
423  *
424  * 'timeout', 'udptimeout', and 'udpretries' are passed to
425  * dns_request_createvia3().  See dns_request_createvia3() for more details.
426  *
427  * dns_client_request() provides a synchronous service.  This function sends
428  * the request and blocks until a response is received.  On success,
429  * 'rmessage' will contain the response message.  The caller must provide a
430  * valid initialized message.
431  *
432  * It is usually expected that the client object passed to
433  * dns_client_request() was created via dns_client_create() and has its own
434  * managers and contexts.  However, if the DNS_CLIENTREQOPT_ALLOWRUN flag is
435  * set in 'options', this function performs the synchronous service even if
436  * it does not have its own manager and context structures.
437  *
438  * dns_client_startrequest() is an asynchronous version of dns_client_request()
439  * and does not block.  When the transaction is completed, 'action' will be
440  * called with the argument of a 'dns_clientreqevent_t' object, which contains
441  * the response message (on success).  On return, '*transp' is set to an opaque
442  * transaction ID so that the caller can cancel this request.
443  *
444  * Requires:
445  *
446  *\li   'client' is a valid client.
447  *
448  *\li   'qmessage' and 'rmessage' are valid initialized message.
449  *
450  *\li   'server' is a valid socket address structure.
451  *
452  *\li   'task' is a valid task.
453  *
454  *\li   'transp' != NULL && *transp == NULL;
455  *
456  * Returns:
457  *
458  *\li   #ISC_R_SUCCESS                          On success.
459  *
460  *\li   Anything else                           Failure.
461  *
462  *\li   Any result that dns_message_parse() can return.
463  */
464
465 void
466 dns_client_cancelrequest(dns_clientreqtrans_t *transp);
467 /*%<
468  * Cancel an ongoing DNS request procedure started via
469  * dns_client_startrequest().
470  *
471  * Notes:
472  *
473  *\li   If the request procedure has not completed, post its CLIENTREQDONE
474  *      event with a result code of #ISC_R_CANCELED.
475  *
476  * Requires:
477  *
478  *\li   'trans' is a valid transaction ID.
479  */
480
481 void
482 dns_client_destroyreqtrans(dns_clientreqtrans_t **transp);
483 /*%
484  * Destroy DNS request transaction state identified by '*transp'.
485  *
486  * Requires:
487  *
488  *\li   '*transp' is a valid transaction ID.
489  *
490  *\li   The caller has received the CLIENTREQDONE event (either because the
491  *      request completed or because dns_client_cancelrequest() was called).
492  *
493  * Ensures:
494  *
495  *\li   *transp == NULL.
496  */
497
498 isc_result_t
499 dns_client_update(dns_client_t *client, dns_rdataclass_t rdclass,
500                   dns_name_t *zonename, dns_namelist_t *prerequisites,
501                   dns_namelist_t *updates, isc_sockaddrlist_t *servers,
502                   dns_tsec_t *tsec, unsigned int options);
503
504 isc_result_t
505 dns_client_startupdate(dns_client_t *client, dns_rdataclass_t rdclass,
506                        dns_name_t *zonename, dns_namelist_t *prerequisites,
507                        dns_namelist_t *updates, isc_sockaddrlist_t *servers,
508                        dns_tsec_t *tsec, unsigned int options,
509                        isc_task_t *task, isc_taskaction_t action, void *arg,
510                        dns_clientupdatetrans_t **transp);
511 /*%<
512  * Perform DNS dynamic update for 'updates' of the 'rdclass' class with
513  * optional 'prerequisites'.
514  *
515  * 'updates' are a list of names with associated RRsets to be updated.
516  *
517  * 'prerequisites' are a list of names with associated RRsets corresponding to
518  * the prerequisites of the updates.  This is optional and can be NULL, in
519  * which case the prerequisite section of the update message will be empty.
520  *
521  * Both 'updates' and 'prerequisites' must be constructed as specified in
522  * RFC2136.
523  *
524  * 'zonename' is the name of the zone in which the updated names exist.
525  * This is optional and can be NULL.  In this case, these functions internally
526  * identify the appropriate zone through some queries for the SOA RR starting
527  * with the first name in prerequisites or updates.
528  *
529  * 'servers' is a list of authoritative servers to which the update message
530  * should be sent.  This is optional and can be NULL.  In this case, these
531  * functions internally identify the appropriate primary server name and its
532  * addresses through some queries for the SOA RR (like the case of zonename)
533  * and supplemental A/AAAA queries for the server name.
534  * Note: The client module generally assumes the given addresses are of the
535  * primary server of the corresponding zone.  It will work even if a secondary
536  * server address is specified as long as the server allows update forwarding,
537  * it is generally discouraged to include secondary server addresses unless
538  * there's strong reason to do so.
539  *
540  * 'tsec' is a transaction security object containing, e.g. a TSIG key for
541  * authenticating the update transaction (and the supplemental query/response
542  * transactions if the server is specified).  This is optional and can be
543  * NULL, in which case the library tries the update without any transaction
544  * authentication.
545  *
546  * dns_client_update() provides a synchronous service.  This function blocks
547  * until the entire update procedure completes, including the additional
548  * queries when necessary.
549  *
550  * dns_client_startupdate() is an asynchronous version of dns_client_update().
551  * It immediately returns (typically with *transp being set to a non-NULL
552  * pointer), and performs the update procedure through a set of internal
553  * events.  All transactions including the additional query exchanges are
554  * performed as a separate event, so none of these events cause blocking
555  * operation.  When the update procedure completes, the specified function
556  * 'action' will be called with the argument of a 'dns_clientupdateevent_t'
557  * structure.  On return, '*transp' is set to an opaque transaction ID so that
558  * the caller can cancel this update process.
559  *
560  * Notes:
561  *\li   No options are currently defined.
562  *
563  * Requires:
564  *
565  *\li   'client' is a valid client.
566  *
567  *\li   'updates' != NULL.
568  *
569  *\li   'task' is a valid task.
570  *
571  *\li   'transp' != NULL && *transp == NULL;
572  *
573  * Returns:
574  *
575  *\li   #ISC_R_SUCCESS                          On success.
576  *
577  *\li   Anything else                           Failure.
578  */
579
580 void
581 dns_client_cancelupdate(dns_clientupdatetrans_t *trans);
582 /*%<
583  * Cancel an ongoing dynamic update procedure started via
584  * dns_client_startupdate().
585  *
586  * Notes:
587  *
588  *\li   If the update procedure has not completed, post its UPDATEDONE
589  *      event with a result code of #ISC_R_CANCELED.
590  *
591  * Requires:
592  *
593  *\li   'trans' is a valid transaction ID.
594  */
595
596 void
597 dns_client_destroyupdatetrans(dns_clientupdatetrans_t **transp);
598 /*%<
599  * Destroy dynamic update transaction identified by '*transp'.
600  *
601  * Requires:
602  *
603  *\li   '*transp' is a valid transaction ID.
604  *
605  *\li   The caller has received the UPDATEDONE event (either because the
606  *      update completed or because dns_client_cancelupdate() was called).
607  *
608  * Ensures:
609  *
610  *\li   *transp == NULL.
611  */
612
613 isc_result_t
614 dns_client_updaterec(dns_client_updateop_t op, dns_name_t *owner,
615                      dns_rdatatype_t type, dns_rdata_t *source,
616                      dns_ttl_t ttl, dns_name_t *target,
617                      dns_rdataset_t *rdataset, dns_rdatalist_t *rdatalist,
618                      dns_rdata_t *rdata, isc_mem_t *mctx);
619 /*%<
620  * TBD
621  */
622
623 void
624 dns_client_freeupdate(dns_name_t **namep);
625 /*%<
626  * TBD
627  */
628
629 isc_mem_t *
630 dns_client_mctx(dns_client_t *client);
631
632 ISC_LANG_ENDDECLS
633
634 #endif /* DNS_CLIENT_H */