2 * Copyright (C) 2009, 2013 Internet Systems Consortium, Inc. ("ISC")
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.
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.
17 /* $Id: client.h,v 1.3 2009/09/02 23:48:02 tbox Exp $ */
20 #define DNS_CLIENT_H 1
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.
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
44 *\li This module does not handle any low-level data directly, and so no
45 * security issue specific to this module is anticipated.
48 #include <isc/event.h>
49 #include <isc/sockaddr.h>
52 #include <dns/types.h>
61 updateop_notexist = 4,
63 } dns_client_updateop_t;
72 * Optional flags for dns_client_create(x).
74 /*%< Enable caching resolution results (experimental). */
75 #define DNS_CLIENTCREATEOPT_USECACHE 0x8000
78 * Optional flags for dns_client_(start)resolve.
80 /*%< Disable DNSSEC validation. */
81 #define DNS_CLIENTRESOPT_NODNSSEC 0x01
82 /*%< Allow running external context. */
83 #define DNS_CLIENTRESOPT_ALLOWRUN 0x02
86 * Optional flags for dns_client_(start)request.
88 /*%< Allow running external context. */
89 #define DNS_CLIENTREQOPT_ALLOWRUN 0x01
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.
100 typedef struct dns_clientresevent {
101 ISC_EVENT_COMMON(struct dns_clientresevent);
103 isc_result_t vresult;
104 dns_namelist_t answerlist;
105 } dns_clientresevent_t; /* too long? */
108 * Status of a dynamic update procedure.
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;
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.
124 typedef struct dns_clientreqevent {
125 ISC_EVENT_COMMON(struct dns_clientreqevent);
127 dns_message_t *rmessage;
128 } dns_clientreqevent_t; /* too long? */
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.
139 typedef struct dns_clientupdateevent {
140 ISC_EVENT_COMMON(struct dns_clientupdateevent);
142 dns_clientupdatestate_t state;
143 } dns_clientupdateevent_t; /* too long? */
146 dns_client_create(dns_client_t **clientp, unsigned int options);
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);
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);
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.
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.
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.
177 * If the DNS_CLIENTCREATEOPT_USECACHE flag is set in 'options',
178 * dns_client_create(x) will create a cache database with the view.
182 *\li 'mctx' is a valid memory context.
184 *\li 'actx' is a valid application context.
186 *\li 'taskmgr' is a valid task manager.
188 *\li 'socketmgr' is a valid socket manager.
190 *\li 'timermgr' is a valid timer manager.
192 *\li clientp != NULL && *clientp == NULL.
196 *\li #ISC_R_SUCCESS On success.
198 *\li Anything else Failure.
202 dns_client_destroy(dns_client_t **clientp);
208 *\li '*clientp' is a valid client.
212 *\li *clientp == NULL.
216 dns_client_setservers(dns_client_t *client, dns_rdataclass_t rdclass,
217 dns_name_t *namespace, isc_sockaddrlist_t *addrs);
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.
230 *\li 'client' is a valid client.
232 *\li 'namespace' is NULL or a valid name.
234 *\li 'addrs' != NULL.
238 *\li #ISC_R_SUCCESS On success.
240 *\li Anything else Failure.
244 dns_client_clearservers(dns_client_t *client, dns_rdataclass_t rdclass,
245 dns_name_t *namespace);
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'.
253 *\li 'client' is a valid client.
255 *\li 'namespace' is NULL or a valid name.
259 *\li #ISC_R_SUCCESS On success.
261 *\li Anything else Failure.
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);
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);
276 * Perform name resolution for 'name', 'rdclass', and 'type'.
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.
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.
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.
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.
309 *\li 'client' is a valid client.
311 *\li 'addrs' != NULL.
313 *\li 'name' is a valid name.
315 *\li 'namelist' != NULL and is not empty.
317 *\li 'task' is a valid task.
319 *\li 'transp' != NULL && *transp == NULL;
323 *\li #ISC_R_SUCCESS On success.
325 *\li Anything else Failure.
329 dns_client_cancelresolve(dns_clientrestrans_t *trans);
331 * Cancel an ongoing resolution procedure started via
332 * dns_client_startresolve().
336 *\li If the resolution procedure has not completed, post its CLIENTRESDONE
337 * event with a result code of #ISC_R_CANCELED.
341 *\li 'trans' is a valid transaction ID.
345 dns_client_destroyrestrans(dns_clientrestrans_t **transp);
347 * Destroy name resolution transaction state identified by '*transp'.
351 *\li '*transp' is a valid transaction ID.
353 *\li The caller has received the CLIENTRESDONE event (either because the
354 * resolution completed or because dns_client_cancelresolve() was called).
358 *\li *transp == NULL.
362 dns_client_freeresanswer(dns_client_t *client, dns_namelist_t *namelist);
364 * Free resources allocated for the content of 'namelist'.
368 *\li 'client' is a valid client.
370 *\li 'namelist' != NULL.
374 dns_client_addtrustedkey(dns_client_t *client, dns_rdataclass_t rdclass,
375 dns_name_t *keyname, isc_buffer_t *keydatabuf);
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.
383 *\li 'client' is a valid client.
385 *\li 'keyname' is a valid name.
387 *\li 'keydatabuf' is a valid buffer.
391 *\li #ISC_R_SUCCESS On success.
393 *\li Anything else Failure.
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);
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);
413 * Send a DNS request containig a query message 'query' to 'server'.
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.
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.
424 * 'timeout', 'udptimeout', and 'udpretries' are passed to
425 * dns_request_createvia3(). See dns_request_createvia3() for more details.
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.
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.
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.
446 *\li 'client' is a valid client.
448 *\li 'qmessage' and 'rmessage' are valid initialized message.
450 *\li 'server' is a valid socket address structure.
452 *\li 'task' is a valid task.
454 *\li 'transp' != NULL && *transp == NULL;
458 *\li #ISC_R_SUCCESS On success.
460 *\li Anything else Failure.
462 *\li Any result that dns_message_parse() can return.
466 dns_client_cancelrequest(dns_clientreqtrans_t *transp);
468 * Cancel an ongoing DNS request procedure started via
469 * dns_client_startrequest().
473 *\li If the request procedure has not completed, post its CLIENTREQDONE
474 * event with a result code of #ISC_R_CANCELED.
478 *\li 'trans' is a valid transaction ID.
482 dns_client_destroyreqtrans(dns_clientreqtrans_t **transp);
484 * Destroy DNS request transaction state identified by '*transp'.
488 *\li '*transp' is a valid transaction ID.
490 *\li The caller has received the CLIENTREQDONE event (either because the
491 * request completed or because dns_client_cancelrequest() was called).
495 *\li *transp == NULL.
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);
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);
512 * Perform DNS dynamic update for 'updates' of the 'rdclass' class with
513 * optional 'prerequisites'.
515 * 'updates' are a list of names with associated RRsets to be updated.
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.
521 * Both 'updates' and 'prerequisites' must be constructed as specified in
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.
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.
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
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.
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.
561 *\li No options are currently defined.
565 *\li 'client' is a valid client.
567 *\li 'updates' != NULL.
569 *\li 'task' is a valid task.
571 *\li 'transp' != NULL && *transp == NULL;
575 *\li #ISC_R_SUCCESS On success.
577 *\li Anything else Failure.
581 dns_client_cancelupdate(dns_clientupdatetrans_t *trans);
583 * Cancel an ongoing dynamic update procedure started via
584 * dns_client_startupdate().
588 *\li If the update procedure has not completed, post its UPDATEDONE
589 * event with a result code of #ISC_R_CANCELED.
593 *\li 'trans' is a valid transaction ID.
597 dns_client_destroyupdatetrans(dns_clientupdatetrans_t **transp);
599 * Destroy dynamic update transaction identified by '*transp'.
603 *\li '*transp' is a valid transaction ID.
605 *\li The caller has received the UPDATEDONE event (either because the
606 * update completed or because dns_client_cancelupdate() was called).
610 *\li *transp == NULL.
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);
624 dns_client_freeupdate(dns_name_t **namep);
630 dns_client_mctx(dns_client_t *client);
634 #endif /* DNS_CLIENT_H */