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