request.c revision 40f53fa8d9c6a4fc38c0014495e7a42b08f52481
/*
* Copyright (C) 2000 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
* DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
* INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
* FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: request.c,v 1.31 2000/08/01 01:22:50 tale Exp $ */
#include <config.h>
#include <dns/dispatch.h>
#include <dns/rdatastruct.h>
#define DNS_REQUEST_NLOCKS 7
struct dns_requestmgr {
/* locked */
unsigned int hash;
};
struct dns_request {
unsigned int hash;
};
#define DNS_REQUEST_F_CONNECTING 0x0001
#define DNS_REQUEST_F_CANCELED 0x0002
#define DNS_REQUEST_CANCELED(r) \
(((r)->flags & DNS_REQUEST_F_CANCELED) != 0)
#define DNS_REQUEST_CONNECTING(r) \
(((r)->flags & DNS_REQUEST_F_CONNECTING) != 0)
/***
*** Forward
***/
/***
*** Public
***/
{
int i;
if (dispatchv4 != NULL) {
}
if (dispatchv6 != NULL) {
}
if (requestmgr == NULL)
return (ISC_R_NOMEMORY);
if (result != ISC_R_SUCCESS) {
return (result);
}
for (i = 0; i < DNS_REQUEST_NLOCKS; i++) {
if (result != ISC_R_SUCCESS) {
while (--i >= 0)
return (result);
}
}
if (dispatchv4 != NULL)
if (dispatchv6 != NULL)
requestmgr->iref = 0;
requestmgr->hash = 0;
return (ISC_R_SUCCESS);
}
void
{
if (requestmgr->exiting) {
/*
* We're already shutdown. Send the event.
*/
} else {
}
}
void
}
static void
/*
* Caller holds lock.
*/
if (!requestmgr->exiting) {
}
if (requestmgr->iref == 0) {
}
}
}
static void
/*
* Locked by caller.
*/
}
static void
*requestmgrp = NULL;
requestmgr->iref--;
if (requestmgr->eref == 0)
}
if (need_destroy)
}
void
}
void
requestmgr->eref--;
}
if (need_destroy)
*requestmgrp = NULL;
}
static void
/*
* Caller must be holding the manager lock.
*/
event = next_event) {
}
}
static void
int i;
for (i = 0; i < DNS_REQUEST_NLOCKS; i++)
requestmgr->magic = 0;
}
static unsigned int
/*
* Locked by caller.
*/
requestmgr->hash++;
}
static inline isc_result_t
isc_region_t r;
}
{
unsigned int attrs;
return (ISC_R_NOMEMORY);
}
/*
* Zero structure.
*/
/*
* Create timer now. We will set it below once.
*/
if (result != ISC_R_SUCCESS)
goto cleanup;
goto cleanup;
}
if ((options & DNS_REQUESTOPT_TCP) != 0) {
if (result != ISC_R_SUCCESS)
goto cleanup;
if (result != ISC_R_SUCCESS) {
goto cleanup;
}
attrs = 0;
else
if (result != ISC_R_SUCCESS)
goto cleanup;
} else {
switch (isc_sockaddr_pf(address)) {
case PF_INET:
break;
case PF_INET6:
break;
default:
goto cleanup;
}
}
if (result != ISC_R_SUCCESS)
goto cleanup;
if (result == DNS_R_USETCP &&
(options & DNS_REQUESTOPT_TCP) == 0) {
/*
* Try again using TCP.
*/
goto use_tcp;
}
if (result != ISC_R_SUCCESS)
goto cleanup;
if (result != ISC_R_SUCCESS)
goto cleanup;
if (requestmgr->exiting) {
goto cleanup;
}
if (result != ISC_R_SUCCESS)
goto unlink;
if (result != ISC_R_SUCCESS)
goto unlink;
if ((options & DNS_REQUESTOPT_TCP) != 0) {
if (result != ISC_R_SUCCESS)
goto unlink;
} else {
if (result != ISC_R_SUCCESS)
goto unlink;
}
return (ISC_R_SUCCESS);
return (result);
}
static isc_result_t
{
isc_region_t r;
/*
* Create buffer able to hold largest possible message.
*/
if (result != ISC_R_SUCCESS)
return (result);
/*
* Render message.
*/
if (result != ISC_R_SUCCESS)
goto cleanup;
if (result != ISC_R_SUCCESS)
goto cleanup;
if (result != ISC_R_SUCCESS)
goto cleanup;
if (result != ISC_R_SUCCESS)
goto cleanup;
if (result != ISC_R_SUCCESS)
goto cleanup;
if (result != ISC_R_SUCCESS)
goto cleanup;
/*
* Copy rendered message to exact sized buffer.
*/
isc_buffer_usedregion(buf1, &r);
if ((options & DNS_REQUESTOPT_TCP) != 0) {
} else if (r.length > 512) {
goto cleanup;
}
if (result != ISC_R_SUCCESS)
goto cleanup;
if (tcp)
if (result != ISC_R_SUCCESS)
goto cleanup;
/*
* Cleanup and return.
*/
return (ISC_R_SUCCESS);
return (result);
}
if (!DNS_REQUEST_CANCELED(request)) {
}
return (ISC_R_SUCCESS);
}
{
request);
if (result != ISC_R_SUCCESS)
return (result);
return (result);
}
}
void
if (!DNS_REQUEST_CONNECTING(request))
if (need_destroy)
}
/***
*** Private: request.
***/
static void
if (DNS_REQUEST_CANCELED(request)) {
} else {
if (result == ISC_R_SUCCESS)
}
}
static void
(void)task;
}
static void
isc_region_t r;
if (result != ISC_R_SUCCESS)
goto done;
/*
* Copy buffer to request.
*/
r.length);
if (result != ISC_R_SUCCESS)
goto done;
if (result != ISC_R_SUCCESS)
done:
/*
* Cleanup.
*/
/*
* Send completion event.
*/
}
static void
}
static void
/*
* Lock held by caller.
*/
}
static void
}
static void
/*
* Lock held by caller.
*/
if (DNS_REQUEST_CONNECTING(request)) {
}
}
static void
}