lwdgabn.c revision 307d2084502eddc7ce921e5ce439aec3531d90e0
/*
* Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001 Internet Software Consortium.
*
* 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 ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC 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: lwdgabn.c,v 1.23 2009/09/01 00:22:25 jinmei Exp $ */
/*! \file */
#include <config.h>
#include <stdlib.h>
#include <isc/sockaddr.h>
#include <named/lwdclient.h>
#include <named/lwsearch.h>
#include <named/sortlist.h>
static void restart_find(ns_lwdclient_t *);
static void init_gabn(ns_lwdclient_t *);
/*%
* Destroy any finds. This can be used to "start over from scratch" and
* should only be called when events are _not_ being generated by the finds.
*/
static void
else
}
}
static void
int af;
if (at == DNS_ADBFIND_INET)
else
goto next;
if (result != ISC_R_SUCCESS)
goto next;
next:
}
}
typedef struct {
int rank;
static int
}
static void
unsigned int naddrs;
const void *arg;
unsigned int i;
return;
return;
sizeof(rankedaddress) * naddrs);
return;
}
for (i = 0; i < naddrs; i++) {
}
for (i = 0; i < naddrs; i++) {
}
}
static void
int lwres;
isc_region_t r;
/*
* We must make certain the client->find is not still active.
* If it is either the v4 or v6 answer, just set it to NULL and
* let the cleanup code destroy it. Otherwise, destroy it now.
*/
else
/*
* perhaps there are some here?
*/
/*
* Run through the finds we have and wire them up to the gabn
* structure.
*/
/*
* If there are no addresses, try the next element in the search
* path, if there are any more. Otherwise, fall through into
* the error handling code below.
*/
do {
if (result == ISC_R_SUCCESS) {
if (result == ISC_R_SUCCESS)
return;
}
} while (result == ISC_R_SUCCESS);
}
/*
* Render the packet.
*/
/*
* If there are no addresses, return failure.
*/
else
if (lwres != LWRES_R_SUCCESS)
goto out;
if (result != ISC_R_SUCCESS)
goto out;
/*
* All done!
*/
return;
out:
}
/*
* Take the current real name, move it to an alias slot (if any are
* open) then put this new name in as the real name for the target.
*
* Return success if it can be rendered, otherwise failure. Note that
* not having enough alias slots open is NOT a failure.
*/
static isc_result_t
isc_buffer_t b;
b = client->recv_buffer;
/*
* Render the new name to the buffer.
*/
if (result != ISC_R_SUCCESS)
return (result);
/*
* Are there any open slots?
*/
if (naliases < LWRES_MAX_ALIASES) {
}
/*
* Save this name away as the current real name.
*/
return (ISC_R_SUCCESS);
}
static isc_result_t
isc_buffer_t b;
b = client->recv_buffer;
if (result != ISC_R_SUCCESS)
return (result);
/*
* Render the new name to the buffer.
*/
if (result != ISC_R_SUCCESS)
return (result);
/*
* Save this name away as the current real name.
*/
return (ISC_R_SUCCESS);
}
static void
isc_event_free(&ev);
/*
* No more info to be had? If so, we have all the good stuff
* right now, so we can render things.
*/
if (evtype == DNS_EVENT_ADBNOMOREADDRESSES) {
}
}
if (claimed)
else
}
return;
}
/*
* We probably don't need this find anymore. We're either going to
* reissue it, or an error occurred. Either way, we're done with
* it.
*/
} else {
}
/*
* We have some new information we can gather. Run off and fetch
* it.
*/
if (evtype == DNS_EVENT_ADBMOREADDRESSES) {
return;
}
/*
* An error or other strangeness happened. Drop this query.
*/
}
static void
unsigned int options;
/*
* Issue a find for the name contained in the request. We won't
* set the bit that says "anything is good enough" -- we want it
* all.
*/
options = 0;
/*
* Set the bits up here to mark that we want this address family
* and that we do not currently have a find pending. We will
* set that bit again below if it turns out we will get an event.
*/
dns_rootname, 0, options, 0,
/*
* Did we get an alias? If so, save it and re-issue the query.
*/
if (result == DNS_R_ALIAS) {
if (result != ISC_R_SUCCESS) {
ns_lwdclient_log(50,
"out of buffer space adding alias");
return;
}
goto find_again;
}
/*
* Did we get an error?
*/
if (result != ISC_R_SUCCESS) {
return;
}
/*
* Did we get our answer to V4 addresses?
*/
}
/*
* Did we get our answer to V6 addresses?
*/
}
/*
* If we're going to get an event, set our internal pending flag
* and return. When we get an event back we'll do the right
* thing, basically by calling this function again, perhaps with a
* new target name.
*
* If we have both v4 and v6, and we are still getting an event,
* we have a programming error, so die hard.
*/
return;
}
if (claimed)
else
/*
* We seem to have everything we asked for, or at least we are
* able to respond with things we've learned.
*/
}
static isc_result_t
/*
* Initialize the real name and alias arrays in the reply we're
* going to build up.
*/
if (result != ISC_R_SUCCESS)
return (result);
return (ISC_R_SUCCESS);
}
static void
int i;
/*
* Initialize the real name and alias arrays in the reply we're
* going to build up.
*/
for (i = 0; i < LWRES_MAX_ALIASES; i++) {
}
for (i = 0; i < LWRES_MAX_ADDRS; i++) {
}
/*
* Set up the internal buffer to point to the receive region.
*/
}
/*
* When we are called, we can be assured that:
*
* client->sockaddr contains the address we need to reply to,
*
* client->pkt contains the packet header data,
*
* the packet "checks out" overall -- any MD5 hashes or crypto
* bits have been verified,
*
* "b" points to the remaining data after the packet header
* was parsed off.
*
* We are in a the RECVDONE state.
*
* From this state we will enter the SEND state if we happen to have
* everything we need or we need to return an error packet, or to the
* FINDWAIT state if we need to look things up.
*/
void
if (result != LWRES_R_SUCCESS)
goto out;
goto out;
if (result != ISC_R_SUCCESS)
goto out;
/*
* We no longer need to keep this around.
*/
/*
* Start the find.
*/
if (result != ISC_R_SUCCESS)
goto out;
return;
/*
* We're screwed. Return an error packet to our caller.
*/
out:
}