listener.c revision 49dbdb0186eb23d87d685b96eaefa9ec3c71d9b8
/*
* Copyright (C) 1996-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.
*/
/*
* Subroutines that support the generic listener object.
*/
#include <config.h>
#include <stdlib.h> /* NULL and abort() */
#include <isc/bufferlist.h>
typedef struct omapi_listener_object {
/*
* Locked by mutex.
*/
static void
/*
* Break the link between the listener object and its parent
* (usually a generic object); this is done so the server's
* reference to its managing object does not prevent the
* listener object from being destroyed.
*/
/*
* The listener object can now be freed.
*/
}
/*
* Reader callback for a listener object. Accept an incoming connection.
*/
static void
int match;
/*
* XXXDCL audit error handling
*/
/*
* No more need for the event, once all the desired data has been
* used from it.
*/
if (result == ISC_R_CANCELED) {
/*
* omapi_listener_shutdown was called.
*/
} else {
/*
* All connections this listener was responsible for
* must be removed.
*
* XXXDCL
* Since it is possible that this shutdown was
* triggered by one of the clients, it would be nice
* to give it a little time to exit, as well as allow
* any other connections to finish up cleanly.
* Unfortunately, since this could be called in the
* no other events can be delivered while this routine
* blocks, so a loop to use isc_condition_waituntil
* until all of the connections are gone is pointless.
*/
connection != NULL;
}
return;
}
/*
* Set up another accept task for the socket.
*/
/*
* Check for the validity of new connection event.
* If the result is not ISC_R_SUCCESS, what can really
* be done about it other than just flunking out of here?
*/
if (result != ISC_R_SUCCESS)
return;
/*
* Is the connection from a valid host?
*/
if (result == ISC_R_SUCCESS) {
}
/*
* Permission denied. Close the connection.
* XXXDCL isc_log_write an error.
*/
return;
}
/*
* The new connection is good to go. Allocate the buffers for it and
* prepare its own task.
*/
goto free_task;
if (result != ISC_R_SUCCESS)
goto free_ibuffer;
if (result != ISC_R_SUCCESS)
goto free_obuffer;
/*
* Create a new connection object.
*/
omapi_type_connection, sizeof(*connection));
if (result != ISC_R_SUCCESS)
goto free_obuffer;
/*
* Create a new protocol object to oversee the handling of this
* connection.
*/
sizeof(omapi_protocol_t));
if (result != ISC_R_SUCCESS)
goto free_connection_object;
/*
* Tie the protocol object bidirectionally to the connection
* object, with the connection as the outer object.
*/
/*
* Lose the external reference to the protocol object so both the
* connection object and protocol object will be freed when the
* connection ends.
*/
/*
* Add the connection to the list of connections known by the
* listener. This is an added reference to the connection
* object, but since there's no easy way to use omapi_object_reference
* with the ISC_LIST macros, that reference is just not counted.
*/
/*
* Remember the listener that accepted the connection, so it
* can be told when the connection goes away.
*/
/*
* Send the introductory message. The return value does not
* matter; if send_intro failed, it already destroyed the connection.
*/
return;
/*
* Destroy the connection. This will free everything created
* in this function but the event, which was already freed.
*/
return;
/*
* Free resources that were being created for the connection object.
*/
}
{
if (result != ISC_R_SUCCESS)
return (result);
/*
* Create the listener object.
*/
omapi_type_listener, sizeof(*listener));
if (result != ISC_R_SUCCESS) {
return (result);
}
/*
* Create a socket on which to listen.
*/
if (result == ISC_R_SUCCESS)
if (result == ISC_R_SUCCESS)
/*
* Now tell the kernel to listen for connections.
*/
if (result == ISC_R_SUCCESS) {
/*
* Queue up the first accept event. The listener object
* will be passed to listener_accept() when it is called.
*/
}
if (result == ISC_R_SUCCESS) {
/*
* Tie the listener object to the calling object.
*/
/*
* The callback is not set until here because it should
* only be called if the listener was successfully set up.
*/
} else {
/*
* Failed to set up the listener.
*/
}
return (result);
}
void
omapi_listener_t *l;
l = (omapi_listener_t *)listener;
else
/*
* It is improper to call this function without having had a successful
* run of omapi_listener_listen.
*/
/*
* Stop accepting connections.
*/
}
static isc_result_t
{
/*
* Nothing meaningful can be set in a listener object; just
* continue the call through the object chain.
*/
}
static isc_result_t
{
/*
* Nothing meaningful can be fetched from a listener object; just
* continue the call through the object chain.
*/
}
static void
omapi_listener_t *l;
l = (omapi_listener_t *)listener;
isc_task_destroy(&l->task);
isc_socket_detach(&l->socket);
dns_acl_detach(&l->acl);
}
static isc_result_t
{
omapi_listener_t *l;
l = (omapi_listener_t *)listener;
/*
* free_connection() signals the listener when one of the connections
* it accepted has gone away.
*/
/*
* The listener has been shutdown and the last
* connection was received.
*/
free_listener(l);
} else
} else
return (result);
}
/*
* Write all the published values associated with the object through the
* specified connection.
*/
static isc_result_t
{
}
listener_init(void) {
}