12258Scsgr/*
22258Scsgr * Copyright (C) 2009, 2013  Internet Systems Consortium, Inc. ("ISC")
32258Scsgr *
42258Scsgr * Permission to use, copy, modify, and/or distribute this software for any
52258Scsgr * purpose with or without fee is hereby granted, provided that the above
62258Scsgr * copyright notice and this permission notice appear in all copies.
72258Scsgr *
82258Scsgr * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
916519Snate * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
102258Scsgr * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
112258Scsgr * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
122258Scsgr * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
132258Scsgr * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
142258Scsgr * PERFORMANCE OF THIS SOFTWARE.
152258Scsgr */
162258Scsgr
172258Scsgr/* $Id: client.h,v 1.3 2009/09/02 23:48:02 tbox Exp $ */
182258Scsgr
192258Scsgr#ifndef DNS_CLIENT_H
202258Scsgr#define DNS_CLIENT_H 1
212258Scsgr
222258Scsgr/*****
232258Scsgr ***** Module Info
242258Scsgr *****/
252258Scsgr
262258Scsgr/*! \file
272258Scsgr *
282258Scsgr * \brief
2916519Snate * The DNS client module provides convenient programming interfaces to various
302258Scsgr * DNS services, such as name resolution with or without DNSSEC validation or
312258Scsgr * dynamic DNS update.  This module is primarily expected to be used by other
322258Scsgr * applications than BIND9-related ones that need such advanced DNS features.
332258Scsgr *
342258Scsgr * MP:
352258Scsgr *\li	In the typical usage of this module, application threads will not share
362258Scsgr *	the same data structures created and manipulated in this module.
372258Scsgr *	However, the module still ensures appropriate synchronization of such
382258Scsgr *	data structures.
392258Scsgr *
402258Scsgr * Resources:
412258Scsgr *\li	TBS
422258Scsgr *
432258Scsgr * Security:
442258Scsgr *\li	This module does not handle any low-level data directly, and so no
452258Scsgr *	security issue specific to this module is anticipated.
462258Scsgr */
472258Scsgr
482258Scsgr#include <isc/event.h>
492258Scsgr#include <isc/sockaddr.h>
502258Scsgr
512258Scsgr#include <dns/tsig.h>
522258Scsgr#include <dns/types.h>
532258Scsgr
542258Scsgr#include <dst/dst.h>
552258Scsgr
562258Scsgrtypedef enum {
572258Scsgr	updateop_none = 0,
582258Scsgr	updateop_add = 1,
592258Scsgr	updateop_delete = 2,
602258Scsgr	updateop_exist = 3,
612258Scsgr	updateop_notexist = 4,
622258Scsgr	updateop_max = 5
632258Scsgr} dns_client_updateop_t;
642258Scsgr
652258ScsgrISC_LANG_BEGINDECLS
662258Scsgr
672258Scsgr/***
682258Scsgr *** Types
692258Scsgr ***/
702258Scsgr
712258Scsgr/*%
722258Scsgr * Optional flags for dns_client_create(x).
732258Scsgr */
742258Scsgr/*%< Enable caching resolution results (experimental). */
752258Scsgr#define DNS_CLIENTCREATEOPT_USECACHE	0x8000
762258Scsgr
772258Scsgr/*%
782258Scsgr * Optional flags for dns_client_(start)resolve.
792258Scsgr */
802258Scsgr/*%< Disable DNSSEC validation. */
812258Scsgr#define DNS_CLIENTRESOPT_NODNSSEC	0x01
822258Scsgr/*%< Allow running external context. */
832258Scsgr#define DNS_CLIENTRESOPT_ALLOWRUN	0x02
842258Scsgr
852258Scsgr/*%
862258Scsgr * Optional flags for dns_client_(start)request.
872258Scsgr */
882258Scsgr/*%< Allow running external context. */
892258Scsgr#define DNS_CLIENTREQOPT_ALLOWRUN	0x01
902258Scsgr
912258Scsgr/*%
922258Scsgr * A dns_clientresevent_t is sent when name resolution performed by a client
932258Scsgr * completes.  'result' stores the result code of the entire resolution
942258Scsgr * procedure.  'vresult' specifically stores the result code of DNSSEC
952258Scsgr * validation if it is performed.  When name resolution successfully completes,
962258Scsgr * 'answerlist' is typically non empty, containing answer names along with
972258Scsgr * RRsets.  It is the receiver's responsibility to free this list by calling
982258Scsgr * dns_client_freeresanswer() before freeing the event structure.
992258Scsgr */
1002258Scsgrtypedef struct dns_clientresevent {
1012258Scsgr	ISC_EVENT_COMMON(struct dns_clientresevent);
1022258Scsgr	isc_result_t	result;
1032258Scsgr	isc_result_t	vresult;
1042258Scsgr	dns_namelist_t	answerlist;
1052258Scsgr} dns_clientresevent_t;		/* too long? */
1062258Scsgr
1072258Scsgr/*%
1082258Scsgr * Status of a dynamic update procedure.
1092258Scsgr */
1102258Scsgrtypedef enum {
1112258Scsgr	dns_clientupdatestate_prepare,	/*%< no updates have been sent */
1122258Scsgr	dns_clientupdatestate_sent,	/*%< updates were sent, no response */
1132258Scsgr	dns_clientupdatestate_done	/*%< update was sent and succeeded */
1142258Scsgr} dns_clientupdatestate_t;
1152258Scsgr
1162258Scsgr/*%
1172258Scsgr * A dns_clientreqevent_t is sent when a DNS request is completed by a client.
1182258Scsgr * 'result' stores the result code of the entire transaction.
1192258Scsgr * If the transaction is successfully completed but the response packet cannot
1202258Scsgr * be parsed, 'result' will store the result code of dns_message_parse().
1212258Scsgr * If the response packet is received, 'rmessage' will contain the response
1222258Scsgr * message, whether it is successfully parsed or not.
1232258Scsgr */
1242258Scsgrtypedef struct dns_clientreqevent {
1252258Scsgr	ISC_EVENT_COMMON(struct dns_clientreqevent);
1262258Scsgr	isc_result_t	result;
1272258Scsgr	dns_message_t	*rmessage;
1282258Scsgr} dns_clientreqevent_t;		/* too long? */
1292258Scsgr
1302258Scsgr/*%
1312258Scsgr * A dns_clientupdateevent_t is sent when dynamic update performed by a client
1322258Scsgr * completes.  'result' stores the result code of the entire update procedure.
1332258Scsgr * 'state' specifies the status of the update procedure when this event is
1342258Scsgr * sent.  This can be used as a hint by the receiver to determine whether
1352258Scsgr * the update attempt was ever made.  In particular, if the state is
1362258Scsgr * dns_clientupdatestate_prepare, the receiver can be sure that the requested
1372258Scsgr * update was not applied.
1382258Scsgr */
1392258Scsgrtypedef struct dns_clientupdateevent {
1402258Scsgr	ISC_EVENT_COMMON(struct dns_clientupdateevent);
1412258Scsgr	isc_result_t		result;
1422258Scsgr	dns_clientupdatestate_t	state;
1432258Scsgr} dns_clientupdateevent_t;	/* too long? */
1442258Scsgr
1452258Scsgrisc_result_t
1462258Scsgrdns_client_create(dns_client_t **clientp, unsigned int options);
1472258Scsgr
1482258Scsgrisc_result_t
1492258Scsgrdns_client_createx(isc_mem_t *mctx, isc_appctx_t *actx, isc_taskmgr_t *taskmgr,
1502258Scsgr		   isc_socketmgr_t *socketmgr, isc_timermgr_t *timermgr,
1512258Scsgr		   unsigned int options, dns_client_t **clientp);
1522258Scsgr
1532258Scsgrisc_result_t
1542258Scsgrdns_client_createx2(isc_mem_t *mctx, isc_appctx_t *actx,
1552258Scsgr	   isc_taskmgr_t *taskmgr, isc_socketmgr_t *socketmgr,
1562258Scsgr	   isc_timermgr_t *timermgr, unsigned int options,
1572258Scsgr	   dns_client_t **clientp,
1582258Scsgr	   isc_sockaddr_t *localaddr4, isc_sockaddr_t *localaddr6);
1592258Scsgr/*%<
1602258Scsgr * Create a DNS client.  These functions create a new client object with
1612258Scsgr * minimal internal resources such as the default 'view' for the IN class and
1622258Scsgr * IPv4/IPv6 dispatches for the view.
1632258Scsgr *
1642258Scsgr * dns_client_createx() takes 'manager' arguments so that the caller can
1652258Scsgr * control the behavior of the client through the underlying event framework.
1662258Scsgr * On the other hand, dns_client_create() simplifies the interface and creates
1672258Scsgr * the managers internally.  A DNS client object created via
1682258Scsgr * dns_client_create() is expected to be used by an application that only needs
1692258Scsgr * simple synchronous services or by a thread-based application.
1702258Scsgr *
1712258Scsgr * dns_client_createx2 takes two additional parameters, 'localaddr4' and
1722258Scsgr * 'localaddr6', to specify the local address to use for each family. If
1732258Scsgr * both are set to NULL, then wildcard addresses will be used for both
1742258Scsgr * families. If only one is NULL, then the other address will be used
1752258Scsgr * as the local address, and the other protocol family will not be used.
1762258Scsgr *
1772258Scsgr * If the DNS_CLIENTCREATEOPT_USECACHE flag is set in 'options',
1782258Scsgr * dns_client_create(x) will create a cache database with the view.
1792258Scsgr *
1802258Scsgr * Requires:
1812258Scsgr *
1822258Scsgr *\li	'mctx' is a valid memory context.
1832258Scsgr *
1842258Scsgr *\li	'actx' is a valid application context.
1852258Scsgr *
1862258Scsgr *\li	'taskmgr' is a valid task manager.
1872258Scsgr *
1882258Scsgr *\li	'socketmgr' is a valid socket manager.
1892258Scsgr *
1902258Scsgr *\li	'timermgr' is a valid timer manager.
1912258Scsgr *
1922258Scsgr *\li	clientp != NULL && *clientp == NULL.
1932258Scsgr *
1942258Scsgr * Returns:
1952258Scsgr *
1962258Scsgr *\li	#ISC_R_SUCCESS				On success.
1972258Scsgr *
1982258Scsgr *\li	Anything else				Failure.
1992258Scsgr */
2002258Scsgr
2012258Scsgrvoid
2022258Scsgrdns_client_destroy(dns_client_t **clientp);
2032258Scsgr/*%<
2042258Scsgr * Destroy 'client'.
2052258Scsgr *
2062258Scsgr * Requires:
2072258Scsgr *
2082258Scsgr *\li	'*clientp' is a valid client.
2092258Scsgr *
2102258Scsgr * Ensures:
2112258Scsgr *
2122258Scsgr *\li	*clientp == NULL.
2132258Scsgr */
2142258Scsgr
2152258Scsgrisc_result_t
2162258Scsgrdns_client_setservers(dns_client_t *client, dns_rdataclass_t rdclass,
2172258Scsgr		      dns_name_t *namespace, isc_sockaddrlist_t *addrs);
2182258Scsgr/*%<
2192258Scsgr * Specify a list of addresses of recursive name servers that the client will
2202258Scsgr * use for name resolution.  A view for the 'rdclass' class must be created
2212258Scsgr * beforehand.  If 'namespace' is non NULL, the specified server will be used
2222258Scsgr * if and only if the query name is a subdomain of 'namespace'.  When servers
2232258Scsgr * for multiple 'namespace's are provided, and a query name is covered by
2242258Scsgr * more than one 'namespace', the servers for the best (longest) matching
2252258Scsgr * 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
243isc_result_t
244dns_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
264isc_result_t
265dns_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
269isc_result_t
270dns_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
328void
329dns_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
344void
345dns_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
361void
362dns_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
373isc_result_t
374dns_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
396isc_result_t
397dns_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
403isc_result_t
404dns_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
465void
466dns_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
481void
482dns_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
498isc_result_t
499dns_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
504isc_result_t
505dns_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
580void
581dns_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
596void
597dns_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
613isc_result_t
614dns_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
623void
624dns_client_freeupdate(dns_name_t **namep);
625/*%<
626 * TBD
627 */
628
629isc_mem_t *
630dns_client_mctx(dns_client_t *client);
631
632ISC_LANG_ENDDECLS
633
634#endif /* DNS_CLIENT_H */
635