]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - contrib/bind9/lib/dns/include/dns/client.h
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / contrib / bind9 / lib / dns / include / dns / client.h
1 /*
2  * Copyright (C) 2009  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  * Create a DNS client.  These functions create a new client object with
154  * minimal internal resources such as the default 'view' for the IN class and
155  * IPv4/IPv6 dispatches for the view.
156  *
157  * dns_client_createx() takes 'manager' arguments so that the caller can
158  * control the behavior of the client through the underlying event framework.
159  * On the other hand, dns_client_create() simplifies the interface and creates
160  * the managers internally.  A DNS client object created via
161  * dns_client_create() is expected to be used by an application that only needs
162  * simple synchronous services or by a thread-based application.
163  *
164  * If the DNS_CLIENTCREATEOPT_USECACHE flag is set in 'options',
165  * dns_client_create(x) will create a cache database with the view.
166  *
167  * Requires:
168  *
169  *\li   'mctx' is a valid memory context.
170  *
171  *\li   'actx' is a valid application context.
172  *
173  *\li   'taskmgr' is a valid task manager.
174  *
175  *\li   'socketmgr' is a valid socket manager.
176  *
177  *\li   'timermgr' is a valid timer manager.
178  *
179  *\li   clientp != NULL && *clientp == NULL.
180  *
181  * Returns:
182  *
183  *\li   #ISC_R_SUCCESS                          On success.
184  *
185  *\li   Anything else                           Failure.
186  */
187
188 void
189 dns_client_destroy(dns_client_t **clientp);
190 /*%<
191  * Destroy 'client'.
192  *
193  * Requires:
194  *
195  *\li   '*clientp' is a valid client.
196  *
197  * Ensures:
198  *
199  *\li   *clientp == NULL.
200  */
201
202 isc_result_t
203 dns_client_setservers(dns_client_t *client, dns_rdataclass_t rdclass,
204                       dns_name_t *namespace, isc_sockaddrlist_t *addrs);
205 /*%<
206  * Specify a list of addresses of recursive name servers that the client will
207  * use for name resolution.  A view for the 'rdclass' class must be created
208  * beforehand.  If 'namespace' is non NULL, the specified server will be used
209  * if and only if the query name is a subdomain of 'namespace'.  When servers
210  * for multiple 'namespace's are provided, and a query name is covered by
211  * more than one 'namespace', the servers for the best (longest) matching
212  * namespace will be used.  If 'namespace' is NULL, it works as if
213  * dns_rootname (.) were specified.
214  *
215  * Requires:
216  *
217  *\li   'client' is a valid client.
218  *
219  *\li   'namespace' is NULL or a valid name.
220  *
221  *\li   'addrs' != NULL.
222  *
223  * Returns:
224  *
225  *\li   #ISC_R_SUCCESS                          On success.
226  *
227  *\li   Anything else                           Failure.
228  */
229
230 isc_result_t
231 dns_client_clearservers(dns_client_t *client, dns_rdataclass_t rdclass,
232                         dns_name_t *namespace);
233 /*%<
234  * Remove configured recursive name servers for the 'rdclass' and 'namespace'
235  * from the client.  See the description of dns_client_setservers() for
236  * the requirements about 'rdclass' and 'namespace'.
237  *
238  * Requires:
239  *
240  *\li   'client' is a valid client.
241  *
242  *\li   'namespace' is NULL or a valid name.
243  *
244  * Returns:
245  *
246  *\li   #ISC_R_SUCCESS                          On success.
247  *
248  *\li   Anything else                           Failure.
249  */
250
251 isc_result_t
252 dns_client_resolve(dns_client_t *client, dns_name_t *name,
253                    dns_rdataclass_t rdclass, dns_rdatatype_t type,
254                    unsigned int options, dns_namelist_t *namelist);
255
256 isc_result_t
257 dns_client_startresolve(dns_client_t *client, dns_name_t *name,
258                         dns_rdataclass_t rdclass, dns_rdatatype_t type,
259                         unsigned int options, isc_task_t *task,
260                         isc_taskaction_t action, void *arg,
261                         dns_clientrestrans_t **transp);
262 /*%<
263  * Perform name resolution for 'name', 'rdclass', and 'type'.
264  *
265  * If any trusted keys are configured and the query name is considered to
266  * belong to a secure zone, these functions also validate the responses
267  * using DNSSEC by default.  If the DNS_CLIENTRESOPT_NODNSSEC flag is set
268  * in 'options', DNSSEC validation is disabled regardless of the configured
269  * trusted keys or the query name.
270  *
271  * dns_client_resolve() provides a synchronous service.  This function starts
272  * name resolution internally and blocks until it completes.  On success,
273  * 'namelist' will contain a list of answer names, each of which has
274  * corresponding RRsets.  The caller must provide a valid empty list, and
275  * is responsible for freeing the list content via dns_client_freeresanswer().
276  * If the name resolution fails due to an error in DNSSEC validation,
277  * dns_client_resolve() returns the result code indicating the validation
278  * error. Otherwise, it returns the result code of the entire resolution
279  * process, either success or failure.
280  *
281  * It is typically expected that the client object passed to
282  * dns_client_resolve() was created via dns_client_create() and has its own
283  * managers and contexts.  However, if the DNS_CLIENTRESOPT_ALLOWRUN flag is
284  * set in 'options', this function performs the synchronous service even if
285  * it does not have its own manager and context structures.
286  *
287  * dns_client_startresolve() is an asynchronous version of dns_client_resolve()
288  * and does not block.  When name resolution is completed, 'action' will be
289  * called with the argument of a 'dns_clientresevent_t' object, which contains
290  * the resulting list of answer names (on success).  On return, '*transp' is
291  * set to an opaque transaction ID so that the caller can cancel this
292  * resolution process.
293  *
294  * Requires:
295  *
296  *\li   'client' is a valid client.
297  *
298  *\li   'addrs' != NULL.
299  *
300  *\li   'name' is a valid name.
301  *
302  *\li   'namelist' != NULL and is not empty.
303  *
304  *\li   'task' is a valid task.
305  *
306  *\li   'transp' != NULL && *transp == NULL;
307  *
308  * Returns:
309  *
310  *\li   #ISC_R_SUCCESS                          On success.
311  *
312  *\li   Anything else                           Failure.
313  */
314
315 void
316 dns_client_cancelresolve(dns_clientrestrans_t *trans);
317 /*%<
318  * Cancel an ongoing resolution procedure started via
319  * dns_client_startresolve().
320  *
321  * Notes:
322  *
323  *\li   If the resolution procedure has not completed, post its CLIENTRESDONE
324  *      event with a result code of #ISC_R_CANCELED.
325  *
326  * Requires:
327  *
328  *\li   'trans' is a valid transaction ID.
329  */
330
331 void
332 dns_client_destroyrestrans(dns_clientrestrans_t **transp);
333 /*%<
334  * Destroy name resolution transaction state identified by '*transp'.
335  *
336  * Requires:
337  *
338  *\li   '*transp' is a valid transaction ID.
339  *
340  *\li   The caller has received the CLIENTRESDONE event (either because the
341  *      resolution completed or because dns_client_cancelresolve() was called).
342  *
343  * Ensures:
344  *
345  *\li   *transp == NULL.
346  */
347
348 void
349 dns_client_freeresanswer(dns_client_t *client, dns_namelist_t *namelist);
350 /*%<
351  * Free resources allocated for the content of 'namelist'.
352  *
353  * Requires:
354  *
355  *\li   'client' is a valid client.
356  *
357  *\li   'namelist' != NULL.
358  */
359
360 isc_result_t
361 dns_client_addtrustedkey(dns_client_t *client, dns_rdataclass_t rdclass,
362                          dns_name_t *keyname, isc_buffer_t *keydatabuf);
363 /*%<
364  * Add a DNSSEC trusted key for the 'rdclass' class.  A view for the 'rdclass'
365  * class must be created beforehand.  'keyname' is the DNS name of the key,
366  * and 'keydatabuf' stores the resource data of the key.
367  *
368  * Requires:
369  *
370  *\li   'client' is a valid client.
371  *
372  *\li   'keyname' is a valid name.
373  *
374  *\li   'keydatabuf' is a valid buffer.
375  *
376  * Returns:
377  *
378  *\li   #ISC_R_SUCCESS                          On success.
379  *
380  *\li   Anything else                           Failure.
381  */
382
383 isc_result_t
384 dns_client_request(dns_client_t *client, dns_message_t *qmessage,
385                    dns_message_t *rmessage, isc_sockaddr_t *server,
386                    unsigned int options, unsigned int parseoptions,
387                    dns_tsec_t *tsec, unsigned int timeout,
388                    unsigned int udptimeout, unsigned int udpretries);
389
390 isc_result_t
391 dns_client_startrequest(dns_client_t *client, dns_message_t *qmessage,
392                         dns_message_t *rmessage, isc_sockaddr_t *server,
393                         unsigned int options, unsigned int parseoptions,
394                         dns_tsec_t *tsec, unsigned int timeout,
395                         unsigned int udptimeout, unsigned int udpretries,
396                         isc_task_t *task, isc_taskaction_t action, void *arg,
397                         dns_clientreqtrans_t **transp);
398
399 /*%<
400  * Send a DNS request containig a query message 'query' to 'server'.
401  *
402  * 'parseoptions' will be used when the response packet is parsed, and will be
403  * passed to dns_message_parse() via dns_request_getresponse().  See
404  * dns_message_parse() for more details.
405  *
406  * 'tsec' is a transaction security object containing, e.g. a TSIG key for
407  * authenticating the request/response transaction.  This is optional and can
408  * be NULL, in which case this library performs the transaction  without any
409  * transaction authentication.
410  *
411  * 'timeout', 'udptimeout', and 'udpretries' are passed to
412  * dns_request_createvia3().  See dns_request_createvia3() for more details.
413  *
414  * dns_client_request() provides a synchronous service.  This function sends
415  * the request and blocks until a response is received.  On success,
416  * 'rmessage' will contain the response message.  The caller must provide a
417  * valid initialized message.
418  *
419  * It is usually expected that the client object passed to
420  * dns_client_request() was created via dns_client_create() and has its own
421  * managers and contexts.  However, if the DNS_CLIENTREQOPT_ALLOWRUN flag is
422  * set in 'options', this function performs the synchronous service even if
423  * it does not have its own manager and context structures.
424  *
425  * dns_client_startrequest() is an asynchronous version of dns_client_request()
426  * and does not block.  When the transaction is completed, 'action' will be
427  * called with the argument of a 'dns_clientreqevent_t' object, which contains
428  * the response message (on success).  On return, '*transp' is set to an opaque
429  * transaction ID so that the caller can cancel this request.
430  *
431  * Requires:
432  *
433  *\li   'client' is a valid client.
434  *
435  *\li   'qmessage' and 'rmessage' are valid initialized message.
436  *
437  *\li   'server' is a valid socket address structure.
438  *
439  *\li   'task' is a valid task.
440  *
441  *\li   'transp' != NULL && *transp == NULL;
442  *
443  * Returns:
444  *
445  *\li   #ISC_R_SUCCESS                          On success.
446  *
447  *\li   Anything else                           Failure.
448  *
449  *\li   Any result that dns_message_parse() can return.
450  */
451
452 void
453 dns_client_cancelrequest(dns_clientreqtrans_t *transp);
454 /*%<
455  * Cancel an ongoing DNS request procedure started via
456  * dns_client_startrequest().
457  *
458  * Notes:
459  *
460  *\li   If the request procedure has not completed, post its CLIENTREQDONE
461  *      event with a result code of #ISC_R_CANCELED.
462  *
463  * Requires:
464  *
465  *\li   'trans' is a valid transaction ID.
466  */
467
468 void
469 dns_client_destroyreqtrans(dns_clientreqtrans_t **transp);
470 /*%
471  * Destroy DNS request transaction state identified by '*transp'.
472  *
473  * Requires:
474  *
475  *\li   '*transp' is a valid transaction ID.
476  *
477  *\li   The caller has received the CLIENTREQDONE event (either because the
478  *      request completed or because dns_client_cancelrequest() was called).
479  *
480  * Ensures:
481  *
482  *\li   *transp == NULL.
483  */
484
485 isc_result_t
486 dns_client_update(dns_client_t *client, dns_rdataclass_t rdclass,
487                   dns_name_t *zonename, dns_namelist_t *prerequisites,
488                   dns_namelist_t *updates, isc_sockaddrlist_t *servers,
489                   dns_tsec_t *tsec, unsigned int options);
490
491 isc_result_t
492 dns_client_startupdate(dns_client_t *client, dns_rdataclass_t rdclass,
493                        dns_name_t *zonename, dns_namelist_t *prerequisites,
494                        dns_namelist_t *updates, isc_sockaddrlist_t *servers,
495                        dns_tsec_t *tsec, unsigned int options,
496                        isc_task_t *task, isc_taskaction_t action, void *arg,
497                        dns_clientupdatetrans_t **transp);
498 /*%<
499  * Perform DNS dynamic update for 'updates' of the 'rdclass' class with
500  * optional 'prerequisites'.
501  *
502  * 'updates' are a list of names with associated RRsets to be updated.
503  *
504  * 'prerequisites' are a list of names with associated RRsets corresponding to
505  * the prerequisites of the updates.  This is optional and can be NULL, in
506  * which case the prerequisite section of the update message will be empty.
507  *
508  * Both 'updates' and 'prerequisites' must be constructed as specified in
509  * RFC2136.
510  *
511  * 'zonename' is the name of the zone in which the updated names exist.
512  * This is optional and can be NULL.  In this case, these functions internally
513  * identify the appropriate zone through some queries for the SOA RR starting
514  * with the first name in prerequisites or updates.
515  *
516  * 'servers' is a list of authoritative servers to which the update message
517  * should be sent.  This is optional and can be NULL.  In this case, these
518  * functions internally identify the appropriate primary server name and its
519  * addresses through some queries for the SOA RR (like the case of zonename)
520  * and supplemental A/AAAA queries for the server name.
521  * Note: The client module generally assumes the given addresses are of the
522  * primary server of the corresponding zone.  It will work even if a secondary
523  * server address is specified as long as the server allows update forwarding,
524  * it is generally discouraged to include secondary server addresses unless
525  * there's strong reason to do so.
526  *
527  * 'tsec' is a transaction security object containing, e.g. a TSIG key for
528  * authenticating the update transaction (and the supplemental query/response
529  * transactions if the server is specified).  This is optional and can be
530  * NULL, in which case the library tries the update without any transaction
531  * authentication.
532  *
533  * dns_client_update() provides a synchronous service.  This function blocks
534  * until the entire update procedure completes, including the additional
535  * queries when necessary.
536  *
537  * dns_client_startupdate() is an asynchronous version of dns_client_update().
538  * It immediately returns (typically with *transp being set to a non-NULL
539  * pointer), and performs the update procedure through a set of internal
540  * events.  All transactions including the additional query exchanges are
541  * performed as a separate event, so none of these events cause blocking
542  * operation.  When the update procedure completes, the specified function
543  * 'action' will be called with the argument of a 'dns_clientupdateevent_t'
544  * structure.  On return, '*transp' is set to an opaque transaction ID so that
545  * the caller can cancel this update process.
546  *
547  * Notes:
548  *\li   No options are currently defined.
549  *
550  * Requires:
551  *
552  *\li   'client' is a valid client.
553  *
554  *\li   'updates' != NULL.
555  *
556  *\li   'task' is a valid task.
557  *
558  *\li   'transp' != NULL && *transp == NULL;
559  *
560  * Returns:
561  *
562  *\li   #ISC_R_SUCCESS                          On success.
563  *
564  *\li   Anything else                           Failure.
565  */
566
567 void
568 dns_client_cancelupdate(dns_clientupdatetrans_t *trans);
569 /*%<
570  * Cancel an ongoing dynamic update procedure started via
571  * dns_client_startupdate().
572  *
573  * Notes:
574  *
575  *\li   If the update procedure has not completed, post its UPDATEDONE
576  *      event with a result code of #ISC_R_CANCELED.
577  *
578  * Requires:
579  *
580  *\li   'trans' is a valid transaction ID.
581  */
582
583 void
584 dns_client_destroyupdatetrans(dns_clientupdatetrans_t **transp);
585 /*%<
586  * Destroy dynamic update transaction identified by '*transp'.
587  *
588  * Requires:
589  *
590  *\li   '*transp' is a valid transaction ID.
591  *
592  *\li   The caller has received the UPDATEDONE event (either because the
593  *      update completed or because dns_client_cancelupdate() was called).
594  *
595  * Ensures:
596  *
597  *\li   *transp == NULL.
598  */
599
600 isc_result_t
601 dns_client_updaterec(dns_client_updateop_t op, dns_name_t *owner,
602                      dns_rdatatype_t type, dns_rdata_t *source,
603                      dns_ttl_t ttl, dns_name_t *target,
604                      dns_rdataset_t *rdataset, dns_rdatalist_t *rdatalist,
605                      dns_rdata_t *rdata, isc_mem_t *mctx);
606 /*%<
607  * TBD
608  */
609
610 void
611 dns_client_freeupdate(dns_name_t **namep);
612 /*%<
613  * TBD
614  */
615
616 isc_mem_t *
617 dns_client_mctx(dns_client_t *client);
618
619 ISC_LANG_ENDDECLS
620
621 #endif /* DNS_CLIENT_H */