1/* 2 * Copyright (C) 2004-2007, 2009, 2010 Internet Systems Consortium, Inc. ("ISC") 3 * Copyright (C) 2000-2002 Internet Software Consortium. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15 * PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18/* $Id: request.h,v 1.31 2010/03/04 23:50:34 tbox Exp $ */ 19 20#ifndef DNS_REQUEST_H 21#define DNS_REQUEST_H 1 22 23/***** 24 ***** Module Info 25 *****/ 26 27/*! \file dns/request.h 28 * 29 * \brief 30 * The request module provides simple request/response services useful for 31 * sending SOA queries, DNS Notify messages, and dynamic update requests. 32 * 33 * MP: 34 *\li The module ensures appropriate synchronization of data structures it 35 * creates and manipulates. 36 * 37 * Resources: 38 *\li TBS 39 * 40 * Security: 41 *\li No anticipated impact. 42 */ 43 44#include <isc/lang.h> 45#include <isc/event.h> 46 47#include <dns/types.h> 48 49#define DNS_REQUESTOPT_TCP 0x00000001U 50#define DNS_REQUESTOPT_CASE 0x00000002U 51 52typedef struct dns_requestevent { 53 ISC_EVENT_COMMON(struct dns_requestevent); 54 isc_result_t result; 55 dns_request_t *request; 56} dns_requestevent_t; 57 58ISC_LANG_BEGINDECLS 59 60isc_result_t 61dns_requestmgr_create(isc_mem_t *mctx, isc_timermgr_t *timermgr, 62 isc_socketmgr_t *socketmgr, isc_taskmgr_t *taskmgr, 63 dns_dispatchmgr_t *dispatchmgr, 64 dns_dispatch_t *dispatchv4, dns_dispatch_t *dispatchv6, 65 dns_requestmgr_t **requestmgrp); 66/*%< 67 * Create a request manager. 68 * 69 * Requires: 70 * 71 *\li 'mctx' is a valid memory context. 72 * 73 *\li 'timermgr' is a valid timer manager. 74 * 75 *\li 'socketmgr' is a valid socket manager. 76 * 77 *\li 'taskmgr' is a valid task manager. 78 * 79 *\li 'dispatchv4' is a valid dispatcher with an IPv4 UDP socket, or is NULL. 80 * 81 *\li 'dispatchv6' is a valid dispatcher with an IPv6 UDP socket, or is NULL. 82 * 83 *\li requestmgrp != NULL && *requestmgrp == NULL 84 * 85 * Ensures: 86 * 87 *\li On success, *requestmgrp is a valid request manager. 88 * 89 * Returns: 90 * 91 *\li ISC_R_SUCCESS 92 * 93 *\li Any other result indicates failure. 94 */ 95 96void 97dns_requestmgr_whenshutdown(dns_requestmgr_t *requestmgr, isc_task_t *task, 98 isc_event_t **eventp); 99/*%< 100 * Send '*eventp' to 'task' when 'requestmgr' has completed shutdown. 101 * 102 * Notes: 103 * 104 *\li It is not safe to detach the last reference to 'requestmgr' until 105 * shutdown is complete. 106 * 107 * Requires: 108 * 109 *\li 'requestmgr' is a valid request manager. 110 * 111 *\li 'task' is a valid task. 112 * 113 *\li *eventp is a valid event. 114 * 115 * Ensures: 116 * 117 *\li *eventp == NULL. 118 */ 119 120void 121dns_requestmgr_shutdown(dns_requestmgr_t *requestmgr); 122/*%< 123 * Start the shutdown process for 'requestmgr'. 124 * 125 * Notes: 126 * 127 *\li This call has no effect if the request manager is already shutting 128 * down. 129 * 130 * Requires: 131 * 132 *\li 'requestmgr' is a valid requestmgr. 133 */ 134 135void 136dns_requestmgr_attach(dns_requestmgr_t *source, dns_requestmgr_t **targetp); 137/*%< 138 * Attach to the request manager. dns_requestmgr_shutdown() must not 139 * have been called on 'source' prior to calling dns_requestmgr_attach(). 140 * 141 * Requires: 142 * 143 *\li 'source' is a valid requestmgr. 144 * 145 *\li 'targetp' to be non NULL and '*targetp' to be NULL. 146 */ 147 148void 149dns_requestmgr_detach(dns_requestmgr_t **requestmgrp); 150/*%< 151 * Detach from the given requestmgr. If this is the final detach 152 * requestmgr will be destroyed. dns_requestmgr_shutdown() must 153 * be called before the final detach. 154 * 155 * Requires: 156 * 157 *\li '*requestmgrp' is a valid requestmgr. 158 * 159 * Ensures: 160 *\li '*requestmgrp' is NULL. 161 */ 162 163isc_result_t 164dns_request_create(dns_requestmgr_t *requestmgr, dns_message_t *message, 165 isc_sockaddr_t *address, unsigned int options, 166 dns_tsigkey_t *key, 167 unsigned int timeout, isc_task_t *task, 168 isc_taskaction_t action, void *arg, 169 dns_request_t **requestp); 170/*%< 171 * Create and send a request. 172 * 173 * Notes: 174 * 175 *\li 'message' will be rendered and sent to 'address'. If the 176 * #DNS_REQUESTOPT_TCP option is set, TCP will be used. The request 177 * will timeout after 'timeout' seconds. 178 * 179 *\li If the #DNS_REQUESTOPT_CASE option is set, use case sensitive 180 * compression. 181 * 182 *\li When the request completes, successfully, due to a timeout, or 183 * because it was canceled, a completion event will be sent to 'task'. 184 * 185 * Requires: 186 * 187 *\li 'message' is a valid DNS message. 188 * 189 *\li 'address' is a valid sockaddr. 190 * 191 *\li 'timeout' > 0 192 * 193 *\li 'task' is a valid task. 194 * 195 *\li requestp != NULL && *requestp == NULL 196 */ 197 198/*% See dns_request_createvia3() */ 199isc_result_t 200dns_request_createvia(dns_requestmgr_t *requestmgr, dns_message_t *message, 201 isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, 202 unsigned int options, dns_tsigkey_t *key, 203 unsigned int timeout, isc_task_t *task, 204 isc_taskaction_t action, void *arg, 205 dns_request_t **requestp); 206 207/*% See dns_request_createvia3() */ 208isc_result_t 209dns_request_createvia2(dns_requestmgr_t *requestmgr, dns_message_t *message, 210 isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, 211 unsigned int options, dns_tsigkey_t *key, 212 unsigned int timeout, unsigned int udptimeout, 213 isc_task_t *task, isc_taskaction_t action, void *arg, 214 dns_request_t **requestp); 215 216isc_result_t 217dns_request_createvia3(dns_requestmgr_t *requestmgr, dns_message_t *message, 218 isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, 219 unsigned int options, dns_tsigkey_t *key, 220 unsigned int timeout, unsigned int udptimeout, 221 unsigned int udpretries, isc_task_t *task, 222 isc_taskaction_t action, void *arg, 223 dns_request_t **requestp); 224/*%< 225 * Create and send a request. 226 * 227 * Notes: 228 * 229 *\li 'message' will be rendered and sent to 'address'. If the 230 * #DNS_REQUESTOPT_TCP option is set, TCP will be used. The request 231 * will timeout after 'timeout' seconds. UDP requests will be resent 232 * at 'udptimeout' intervals if non-zero or 'udpretries' is non-zero. 233 * 234 *\li If the #DNS_REQUESTOPT_CASE option is set, use case sensitive 235 * compression. 236 * 237 *\li When the request completes, successfully, due to a timeout, or 238 * because it was canceled, a completion event will be sent to 'task'. 239 * 240 * Requires: 241 * 242 *\li 'message' is a valid DNS message. 243 * 244 *\li 'dstaddr' is a valid sockaddr. 245 * 246 *\li 'srcaddr' is a valid sockaddr or NULL. 247 * 248 *\li 'srcaddr' and 'dstaddr' are the same protocol family. 249 * 250 *\li 'timeout' > 0 251 * 252 *\li 'task' is a valid task. 253 * 254 *\li requestp != NULL && *requestp == NULL 255 */ 256 257/*% See dns_request_createraw3() */ 258isc_result_t 259dns_request_createraw(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf, 260 isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, 261 unsigned int options, unsigned int timeout, 262 isc_task_t *task, isc_taskaction_t action, void *arg, 263 dns_request_t **requestp); 264 265/*% See dns_request_createraw3() */ 266isc_result_t 267dns_request_createraw2(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf, 268 isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, 269 unsigned int options, unsigned int timeout, 270 unsigned int udptimeout, isc_task_t *task, 271 isc_taskaction_t action, void *arg, 272 dns_request_t **requestp); 273 274isc_result_t 275dns_request_createraw3(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf, 276 isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, 277 unsigned int options, unsigned int timeout, 278 unsigned int udptimeout, unsigned int udpretries, 279 isc_task_t *task, isc_taskaction_t action, void *arg, 280 dns_request_t **requestp); 281/*!< 282 * \brief Create and send a request. 283 * 284 * Notes: 285 * 286 *\li 'msgbuf' will be sent to 'destaddr' after setting the id. If the 287 * #DNS_REQUESTOPT_TCP option is set, TCP will be used. The request 288 * will timeout after 'timeout' seconds. UDP requests will be resent 289 * at 'udptimeout' intervals if non-zero or if 'udpretries' is not zero. 290 * 291 *\li When the request completes, successfully, due to a timeout, or 292 * because it was canceled, a completion event will be sent to 'task'. 293 * 294 * Requires: 295 * 296 *\li 'msgbuf' is a valid DNS message in compressed wire format. 297 * 298 *\li 'destaddr' is a valid sockaddr. 299 * 300 *\li 'srcaddr' is a valid sockaddr or NULL. 301 * 302 *\li 'srcaddr' and 'dstaddr' are the same protocol family. 303 * 304 *\li 'timeout' > 0 305 * 306 *\li 'task' is a valid task. 307 * 308 *\li requestp != NULL && *requestp == NULL 309 */ 310 311void 312dns_request_cancel(dns_request_t *request); 313/*%< 314 * Cancel 'request'. 315 * 316 * Requires: 317 * 318 *\li 'request' is a valid request. 319 * 320 * Ensures: 321 * 322 *\li If the completion event for 'request' has not yet been sent, it 323 * will be sent, and the result code will be ISC_R_CANCELED. 324 */ 325 326isc_result_t 327dns_request_getresponse(dns_request_t *request, dns_message_t *message, 328 unsigned int options); 329/*%< 330 * Get the response to 'request' by filling in 'message'. 331 * 332 * 'options' is passed to dns_message_parse(). See dns_message_parse() 333 * for more details. 334 * 335 * Requires: 336 * 337 *\li 'request' is a valid request for which the caller has received the 338 * completion event. 339 * 340 *\li The result code of the completion event was #ISC_R_SUCCESS. 341 * 342 * Returns: 343 * 344 *\li ISC_R_SUCCESS 345 * 346 *\li Any result that dns_message_parse() can return. 347 */ 348 349isc_boolean_t 350dns_request_usedtcp(dns_request_t *request); 351/*%< 352 * Return whether this query used TCP or not. Setting #DNS_REQUESTOPT_TCP 353 * in the call to dns_request_create() will cause the function to return 354 * #ISC_TRUE, otherwise the result is based on the query message size. 355 * 356 * Requires: 357 *\li 'request' is a valid request. 358 * 359 * Returns: 360 *\li ISC_TRUE if TCP was used. 361 *\li ISC_FALSE if UDP was used. 362 */ 363 364void 365dns_request_destroy(dns_request_t **requestp); 366/*%< 367 * Destroy 'request'. 368 * 369 * Requires: 370 * 371 *\li 'request' is a valid request for which the caller has received the 372 * completion event. 373 * 374 * Ensures: 375 * 376 *\li *requestp == NULL 377 */ 378 379ISC_LANG_ENDDECLS 380 381#endif /* DNS_REQUEST_H */ 382