2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-23 18:49:54 +00:00
bind/lib/omapi/connection.c

1223 lines
36 KiB
C
Raw Normal View History

checkpoint conversion to ISC (doc/dev/coding.html) style. * no spaces around " -> " in indirect postfix expression. * no space between function name and open parenthesis. * no space between array name and open bracket. * use NULL not 0 for pointers. * explicitly compare pointers to NULL. * explicitly compare integers to 0. * Do not cast NULL. * return type of function declaration on line by itself. * open brace of function definition follows close parenthesis if parameters all fit on one line. * comment-only lines start with /* on line by itself, and end with */ on line by itself. * variable names in structures separated from their types in a column. * name the parameters in function prototypes. * ifndef multiple header file inclusion. and other BIND9 conventions not in coding.html: * private structures defined in relevant source module, not private header. * RCS /* $Id: $ */ comments. * Principal Author (Ted Lemon) comments. * Updated ISC copyrights. * Parenthesize value of return(). * Parenthesize argument of sizeof(). * "unsigned int foo" not "unsigned foo". * ISC_LANG_(BEGIN|END)DECLS in header files. * header files included directly by source/header file that needs them. * ... and others I am probably forgetting. and conversion to some libisc.a modules: * use isc/int.h for isc_uintXX_t types, not u_intXX_t. * use isc/assertions.h for REQUIRE() and INSIST(). * use isc/error.h for UNEXPECTED_ERROR. * use isc/boolean.h for isc_boolean_t flags instead of int flags. * use isc/net.h for networking types. * use isc/netdb.h for gethostby*. STILL TO COME ... * more isc_boolean_t. * isc/time.h to replace struct timeval. * isc/socket.h to replace socket/listen/select/etc. * isc/mem.h to replace malloc/free. * namespace overhaul & omapi/compatibility.h. Please collect all your belongings but stand clear of the doors until this train has come to a complete stop.
1999-11-02 04:01:34 +00:00
/*
* Copyright (C) 1996, 1997, 1998, 1999 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.
*/
1999-10-27 22:24:32 +00:00
2000-01-22 00:18:05 +00:00
/* $Id: connection.c,v 1.11 2000/01/22 00:17:47 tale Exp $ */
checkpoint conversion to ISC (doc/dev/coding.html) style. * no spaces around " -> " in indirect postfix expression. * no space between function name and open parenthesis. * no space between array name and open bracket. * use NULL not 0 for pointers. * explicitly compare pointers to NULL. * explicitly compare integers to 0. * Do not cast NULL. * return type of function declaration on line by itself. * open brace of function definition follows close parenthesis if parameters all fit on one line. * comment-only lines start with /* on line by itself, and end with */ on line by itself. * variable names in structures separated from their types in a column. * name the parameters in function prototypes. * ifndef multiple header file inclusion. and other BIND9 conventions not in coding.html: * private structures defined in relevant source module, not private header. * RCS /* $Id: $ */ comments. * Principal Author (Ted Lemon) comments. * Updated ISC copyrights. * Parenthesize value of return(). * Parenthesize argument of sizeof(). * "unsigned int foo" not "unsigned foo". * ISC_LANG_(BEGIN|END)DECLS in header files. * header files included directly by source/header file that needs them. * ... and others I am probably forgetting. and conversion to some libisc.a modules: * use isc/int.h for isc_uintXX_t types, not u_intXX_t. * use isc/assertions.h for REQUIRE() and INSIST(). * use isc/error.h for UNEXPECTED_ERROR. * use isc/boolean.h for isc_boolean_t flags instead of int flags. * use isc/net.h for networking types. * use isc/netdb.h for gethostby*. STILL TO COME ... * more isc_boolean_t. * isc/time.h to replace struct timeval. * isc/socket.h to replace socket/listen/select/etc. * isc/mem.h to replace malloc/free. * namespace overhaul & omapi/compatibility.h. Please collect all your belongings but stand clear of the doors until this train has come to a complete stop.
1999-11-02 04:01:34 +00:00
/* Principal Author: Ted Lemon */
1999-10-27 22:24:32 +00:00
/*
checkpoint conversion to ISC (doc/dev/coding.html) style. * no spaces around " -> " in indirect postfix expression. * no space between function name and open parenthesis. * no space between array name and open bracket. * use NULL not 0 for pointers. * explicitly compare pointers to NULL. * explicitly compare integers to 0. * Do not cast NULL. * return type of function declaration on line by itself. * open brace of function definition follows close parenthesis if parameters all fit on one line. * comment-only lines start with /* on line by itself, and end with */ on line by itself. * variable names in structures separated from their types in a column. * name the parameters in function prototypes. * ifndef multiple header file inclusion. and other BIND9 conventions not in coding.html: * private structures defined in relevant source module, not private header. * RCS /* $Id: $ */ comments. * Principal Author (Ted Lemon) comments. * Updated ISC copyrights. * Parenthesize value of return(). * Parenthesize argument of sizeof(). * "unsigned int foo" not "unsigned foo". * ISC_LANG_(BEGIN|END)DECLS in header files. * header files included directly by source/header file that needs them. * ... and others I am probably forgetting. and conversion to some libisc.a modules: * use isc/int.h for isc_uintXX_t types, not u_intXX_t. * use isc/assertions.h for REQUIRE() and INSIST(). * use isc/error.h for UNEXPECTED_ERROR. * use isc/boolean.h for isc_boolean_t flags instead of int flags. * use isc/net.h for networking types. * use isc/netdb.h for gethostby*. STILL TO COME ... * more isc_boolean_t. * isc/time.h to replace struct timeval. * isc/socket.h to replace socket/listen/select/etc. * isc/mem.h to replace malloc/free. * namespace overhaul & omapi/compatibility.h. Please collect all your belongings but stand clear of the doors until this train has come to a complete stop.
1999-11-02 04:01:34 +00:00
* Subroutines for dealing with connections.
1999-10-27 22:24:32 +00:00
*/
2000-01-11 01:49:24 +00:00
#include <config.h>
checkpoint conversion to ISC (doc/dev/coding.html) style. * no spaces around " -> " in indirect postfix expression. * no space between function name and open parenthesis. * no space between array name and open bracket. * use NULL not 0 for pointers. * explicitly compare pointers to NULL. * explicitly compare integers to 0. * Do not cast NULL. * return type of function declaration on line by itself. * open brace of function definition follows close parenthesis if parameters all fit on one line. * comment-only lines start with /* on line by itself, and end with */ on line by itself. * variable names in structures separated from their types in a column. * name the parameters in function prototypes. * ifndef multiple header file inclusion. and other BIND9 conventions not in coding.html: * private structures defined in relevant source module, not private header. * RCS /* $Id: $ */ comments. * Principal Author (Ted Lemon) comments. * Updated ISC copyrights. * Parenthesize value of return(). * Parenthesize argument of sizeof(). * "unsigned int foo" not "unsigned foo". * ISC_LANG_(BEGIN|END)DECLS in header files. * header files included directly by source/header file that needs them. * ... and others I am probably forgetting. and conversion to some libisc.a modules: * use isc/int.h for isc_uintXX_t types, not u_intXX_t. * use isc/assertions.h for REQUIRE() and INSIST(). * use isc/error.h for UNEXPECTED_ERROR. * use isc/boolean.h for isc_boolean_t flags instead of int flags. * use isc/net.h for networking types. * use isc/netdb.h for gethostby*. STILL TO COME ... * more isc_boolean_t. * isc/time.h to replace struct timeval. * isc/socket.h to replace socket/listen/select/etc. * isc/mem.h to replace malloc/free. * namespace overhaul & omapi/compatibility.h. Please collect all your belongings but stand clear of the doors until this train has come to a complete stop.
1999-11-02 04:01:34 +00:00
#include <errno.h>
#include <stddef.h> /* NULL */
#include <string.h> /* memset */
1999-10-27 22:24:32 +00:00
checkpoint conversion to ISC (doc/dev/coding.html) style. * no spaces around " -> " in indirect postfix expression. * no space between function name and open parenthesis. * no space between array name and open bracket. * use NULL not 0 for pointers. * explicitly compare pointers to NULL. * explicitly compare integers to 0. * Do not cast NULL. * return type of function declaration on line by itself. * open brace of function definition follows close parenthesis if parameters all fit on one line. * comment-only lines start with /* on line by itself, and end with */ on line by itself. * variable names in structures separated from their types in a column. * name the parameters in function prototypes. * ifndef multiple header file inclusion. and other BIND9 conventions not in coding.html: * private structures defined in relevant source module, not private header. * RCS /* $Id: $ */ comments. * Principal Author (Ted Lemon) comments. * Updated ISC copyrights. * Parenthesize value of return(). * Parenthesize argument of sizeof(). * "unsigned int foo" not "unsigned foo". * ISC_LANG_(BEGIN|END)DECLS in header files. * header files included directly by source/header file that needs them. * ... and others I am probably forgetting. and conversion to some libisc.a modules: * use isc/int.h for isc_uintXX_t types, not u_intXX_t. * use isc/assertions.h for REQUIRE() and INSIST(). * use isc/error.h for UNEXPECTED_ERROR. * use isc/boolean.h for isc_boolean_t flags instead of int flags. * use isc/net.h for networking types. * use isc/netdb.h for gethostby*. STILL TO COME ... * more isc_boolean_t. * isc/time.h to replace struct timeval. * isc/socket.h to replace socket/listen/select/etc. * isc/mem.h to replace malloc/free. * namespace overhaul & omapi/compatibility.h. Please collect all your belongings but stand clear of the doors until this train has come to a complete stop.
1999-11-02 04:01:34 +00:00
#include <isc/assertions.h>
2000-01-06 03:36:32 +00:00
#include <isc/error.h>
checkpoint conversion to ISC (doc/dev/coding.html) style. * no spaces around " -> " in indirect postfix expression. * no space between function name and open parenthesis. * no space between array name and open bracket. * use NULL not 0 for pointers. * explicitly compare pointers to NULL. * explicitly compare integers to 0. * Do not cast NULL. * return type of function declaration on line by itself. * open brace of function definition follows close parenthesis if parameters all fit on one line. * comment-only lines start with /* on line by itself, and end with */ on line by itself. * variable names in structures separated from their types in a column. * name the parameters in function prototypes. * ifndef multiple header file inclusion. and other BIND9 conventions not in coding.html: * private structures defined in relevant source module, not private header. * RCS /* $Id: $ */ comments. * Principal Author (Ted Lemon) comments. * Updated ISC copyrights. * Parenthesize value of return(). * Parenthesize argument of sizeof(). * "unsigned int foo" not "unsigned foo". * ISC_LANG_(BEGIN|END)DECLS in header files. * header files included directly by source/header file that needs them. * ... and others I am probably forgetting. and conversion to some libisc.a modules: * use isc/int.h for isc_uintXX_t types, not u_intXX_t. * use isc/assertions.h for REQUIRE() and INSIST(). * use isc/error.h for UNEXPECTED_ERROR. * use isc/boolean.h for isc_boolean_t flags instead of int flags. * use isc/net.h for networking types. * use isc/netdb.h for gethostby*. STILL TO COME ... * more isc_boolean_t. * isc/time.h to replace struct timeval. * isc/socket.h to replace socket/listen/select/etc. * isc/mem.h to replace malloc/free. * namespace overhaul & omapi/compatibility.h. Please collect all your belongings but stand clear of the doors until this train has come to a complete stop.
1999-11-02 04:01:34 +00:00
#include <isc/netdb.h>
1999-10-27 22:24:32 +00:00
2000-01-04 20:04:42 +00:00
#include <omapi/private.h>
checkpoint conversion to ISC (doc/dev/coding.html) style. * no spaces around " -> " in indirect postfix expression. * no space between function name and open parenthesis. * no space between array name and open bracket. * use NULL not 0 for pointers. * explicitly compare pointers to NULL. * explicitly compare integers to 0. * Do not cast NULL. * return type of function declaration on line by itself. * open brace of function definition follows close parenthesis if parameters all fit on one line. * comment-only lines start with /* on line by itself, and end with */ on line by itself. * variable names in structures separated from their types in a column. * name the parameters in function prototypes. * ifndef multiple header file inclusion. and other BIND9 conventions not in coding.html: * private structures defined in relevant source module, not private header. * RCS /* $Id: $ */ comments. * Principal Author (Ted Lemon) comments. * Updated ISC copyrights. * Parenthesize value of return(). * Parenthesize argument of sizeof(). * "unsigned int foo" not "unsigned foo". * ISC_LANG_(BEGIN|END)DECLS in header files. * header files included directly by source/header file that needs them. * ... and others I am probably forgetting. and conversion to some libisc.a modules: * use isc/int.h for isc_uintXX_t types, not u_intXX_t. * use isc/assertions.h for REQUIRE() and INSIST(). * use isc/error.h for UNEXPECTED_ERROR. * use isc/boolean.h for isc_boolean_t flags instead of int flags. * use isc/net.h for networking types. * use isc/netdb.h for gethostby*. STILL TO COME ... * more isc_boolean_t. * isc/time.h to replace struct timeval. * isc/socket.h to replace socket/listen/select/etc. * isc/mem.h to replace malloc/free. * namespace overhaul & omapi/compatibility.h. Please collect all your belongings but stand clear of the doors until this train has come to a complete stop.
1999-11-02 04:01:34 +00:00
2000-01-04 20:04:42 +00:00
/*
* Swiped from bin/tests/sdig.c.
*/
static isc_result_t
get_address(const char *hostname, in_port_t port, isc_sockaddr_t *sockaddr) {
struct in_addr in4;
struct in6_addr in6;
1999-10-27 22:24:32 +00:00
struct hostent *he;
2000-01-04 20:04:42 +00:00
/*
* Is this an IPv6 numeric address?
*/
if (omapi_ipv6 && inet_pton(AF_INET6, hostname, &in6) == 1)
isc_sockaddr_fromin6(sockaddr, &in6, port);
/*
* What about an IPv4 numeric address?
*/
else if (inet_pton(AF_INET, hostname, &in4) == 1)
isc_sockaddr_fromin(sockaddr, &in4, port);
else {
/*
* Look up the host name.
*/
he = gethostbyname(hostname);
if (he == NULL)
return (ISC_R_NOTFOUND);
INSIST(he->h_addrtype == AF_INET);
isc_sockaddr_fromin(sockaddr,
(struct in_addr *)(he->h_addr_list[0]),
port);
}
return (ISC_R_SUCCESS);
}
2000-01-14 23:10:04 +00:00
/*
* Called when there are no more events are pending on the socket.
* It can be detached and data for the connection object freed.
*/
2000-01-06 03:36:32 +00:00
static void
2000-01-22 00:18:05 +00:00
free_connection(omapi_connection_t *connection) {
2000-01-06 03:36:32 +00:00
isc_buffer_t *buffer;
2000-01-22 00:18:05 +00:00
connection->state = omapi_connection_disconnecting;
2000-01-14 23:10:04 +00:00
/*
* The mutex is locked when this routine is called. Unlock
* it so that the isc_condition_signal below will allow
2000-01-22 00:18:05 +00:00
* connection_wait to be able to acquire the lock.
2000-01-14 23:10:04 +00:00
*/
RUNTIME_CHECK(isc_mutex_unlock(&connection->mutex) == ISC_R_SUCCESS);
2000-01-06 03:36:32 +00:00
2000-01-17 18:02:11 +00:00
/*
* This one is locked too, unlock it so it can be destroyed.
*/
RUNTIME_CHECK(isc_mutex_unlock(&connection->recv_lock) ==
ISC_R_SUCCESS);
2000-01-06 03:36:32 +00:00
while ((buffer = ISC_LIST_HEAD(connection->input_buffers)) != NULL) {
ISC_LIST_UNLINK(connection->input_buffers, buffer, link);
isc_buffer_free(&buffer);
}
while ((buffer = ISC_LIST_HEAD(connection->output_buffers)) != NULL) {
ISC_LIST_UNLINK(connection->output_buffers, buffer, link);
isc_buffer_free(&buffer);
}
2000-01-14 23:10:04 +00:00
if (connection->task != NULL)
isc_task_destroy(&connection->task);
2000-01-06 03:36:32 +00:00
2000-01-14 23:10:04 +00:00
if (connection->socket != NULL)
isc_socket_detach(&connection->socket);
2000-01-06 03:36:32 +00:00
2000-01-14 23:10:04 +00:00
RUNTIME_CHECK(isc_mutex_destroy(&connection->mutex) == ISC_R_SUCCESS);
2000-01-17 18:02:11 +00:00
RUNTIME_CHECK(isc_mutex_destroy(&connection->recv_lock) ==
ISC_R_SUCCESS);
RUNTIME_CHECK(isc_condition_destroy(&connection->waiter) ==
ISC_R_SUCCESS);
2000-01-14 23:10:04 +00:00
/*
* If whatever created us registered a signal handler, send it
* a disconnect signal.
*/
2000-01-22 00:18:05 +00:00
object_signal((omapi_object_t *)connection, "disconnect", connection);
2000-01-14 23:10:04 +00:00
2000-01-17 18:02:11 +00:00
#if 0
/*
* Free the inner generic object via the protocol object.
* XXXDCL wildass stab in the dark
*/
OBJECT_DEREF(&connection->inner->inner);
#endif
2000-01-14 23:10:04 +00:00
/*
* Finally, free the object itself.
*/
2000-01-17 18:02:11 +00:00
OBJECT_DEREF(&connection);
2000-01-14 23:10:04 +00:00
}
static void
2000-01-22 00:18:05 +00:00
end_connection(omapi_connection_t *connection, isc_event_t *event,
2000-01-14 23:10:04 +00:00
isc_result_t result)
{
if (event != NULL)
isc_event_free(&event);
/*
* XXXDCL would be nice to send the result as an
2000-01-22 00:18:05 +00:00
* object_signal(object, "status", result) but i don't
2000-01-14 23:10:04 +00:00
* think this can be done with the connection as the object.
*/
2000-01-17 18:02:11 +00:00
/*
* Don't proceed until recv_done() has finished whatever
* it was doing that decremented events_pending to 0.
*/
RUNTIME_CHECK(isc_mutex_lock(&connection->recv_lock) == ISC_R_SUCCESS);
2000-01-14 23:10:04 +00:00
/*
* Lock the connection's mutex to examine connection->events_pending.
*/
RUNTIME_CHECK(isc_mutex_lock(&connection->mutex) == ISC_R_SUCCESS);
if (connection->events_pending == 0) {
2000-01-17 18:02:11 +00:00
if (connection->waiting) {
/*
* This must have been an error, since
2000-01-22 00:18:05 +00:00
* connection_wait can't be called after
2000-01-17 18:02:11 +00:00
* omapi_connection_disconnect is called for
* a normal close.
*
2000-01-22 00:18:05 +00:00
* Signal connection_wait and have it do the
2000-01-17 18:02:11 +00:00
* cleanup. free_connection can't be called
* directly here because it can't be sure
* that the mutex has been finished being touched
2000-01-22 00:18:05 +00:00
* by connection_wait even if it
2000-01-17 18:02:11 +00:00
* free_connection signals it. (Nasty little
* race condition with the lock.)
*
* Make sure that when it is awakened, it exits its
* wait loop by setting messages_expected to 0.
*/
connection->state = omapi_connection_closed;
connection->messages_expected = 0;
RUNTIME_CHECK(isc_condition_signal(&connection->waiter)
== ISC_R_SUCCESS);
} else
free_connection(connection);
2000-01-14 23:10:04 +00:00
return;
}
2000-01-17 18:02:11 +00:00
RUNTIME_CHECK(isc_mutex_unlock(&connection->mutex) == ISC_R_SUCCESS);
RUNTIME_CHECK(isc_mutex_unlock(&connection->recv_lock) ==
2000-01-14 23:10:04 +00:00
ISC_R_SUCCESS);
/*
* There are events pending. Cancel them, and each will generate
* a call with ISC_R_CANCELED to this routine until finally
* events_pending is 0 and the connection is freed. The
* only time ISC_R_CANCELED should be generated is after this
* function already called isc_socket_cancel, because it is
* the only place in the omapi library that isc_socket_cancel is used.
*/
if (result != ISC_R_CANCELED)
isc_socket_cancel(connection->socket, NULL,
ISC_SOCKCANCEL_ALL);
2000-01-06 03:36:32 +00:00
}
2000-01-04 20:04:42 +00:00
/*
2000-01-06 03:36:32 +00:00
* This is the function that is called when a connect event is posted on
2000-01-04 20:04:42 +00:00
* the socket as a result of isc_socket_connect.
*/
static void
2000-01-06 03:36:32 +00:00
connect_done(isc_task_t *task, isc_event_t *event) {
2000-01-04 20:04:42 +00:00
isc_result_t result;
2000-01-06 03:36:32 +00:00
isc_socket_t *socket;
isc_socket_connev_t *connectevent;
2000-01-22 00:18:05 +00:00
omapi_connection_t *connection;
2000-01-04 20:04:42 +00:00
2000-01-06 03:36:32 +00:00
socket = event->sender;
connectevent = (isc_socket_connev_t *)event;
connection = event->arg;
2000-01-04 20:04:42 +00:00
2000-01-17 18:02:11 +00:00
INSIST(socket == connection->socket && task == connection->task);
2000-01-06 03:36:32 +00:00
2000-01-14 23:10:04 +00:00
RUNTIME_CHECK(isc_mutex_lock(&connection->mutex) == ISC_R_SUCCESS);
/*
* XXXDCL I may have made an unwarranted assumption about
* events_pending becoming 0 on the client when disconnecting
* only in recv_done. I'm concerned that there might be some
* sort of logic window, however small, where that isn't true.
*/
2000-01-17 18:02:11 +00:00
INSIST(connection->events_pending > 0);
2000-01-14 23:10:04 +00:00
if (--connection->events_pending == 0 && connection->is_client &&
connection->state == omapi_connection_disconnecting)
FATAL_ERROR(__FILE__, __LINE__,
"events_pending == 0 in connect_done while "
"disconnecting, this should not happen!");
RUNTIME_CHECK(isc_mutex_unlock(&connection->mutex) == ISC_R_SUCCESS);
2000-01-06 03:36:32 +00:00
2000-01-13 06:13:26 +00:00
/*
* XXXDCL For some reason, a "connection refused" error is not
* being indicated here when it would be expected. I wonder
* how that error is indicated.
*/
2000-01-14 23:10:04 +00:00
if (connectevent->result != ISC_R_SUCCESS)
goto abandon;
2000-01-04 20:04:42 +00:00
result = isc_socket_getpeername(connection->socket,
&connection->remote_addr);
2000-01-14 23:10:04 +00:00
if (result != ISC_R_SUCCESS)
goto abandon;
2000-01-04 20:04:42 +00:00
result = isc_socket_getsockname(connection->socket,
&connection->local_addr);
2000-01-14 23:10:04 +00:00
if (result != ISC_R_SUCCESS)
goto abandon;
2000-01-04 20:04:42 +00:00
connection->state = omapi_connection_connected;
isc_event_free(&event);
return;
2000-01-14 23:10:04 +00:00
abandon:
end_connection(connection, event, connectevent->result);
2000-01-04 20:04:42 +00:00
}
2000-01-06 03:36:32 +00:00
/*
* This is the function that is called when a recv event is posted on
* the socket as a result of isc_socket_recv*.
*/
static void
recv_done(isc_task_t *task, isc_event_t *event) {
isc_buffer_t *buffer;
isc_socket_t *socket;
isc_socketevent_t *socketevent;
2000-01-22 00:18:05 +00:00
omapi_connection_t *connection;
2000-01-13 06:13:26 +00:00
unsigned int original_bytes_needed;
2000-01-06 03:36:32 +00:00
socket = event->sender;
socketevent = (isc_socketevent_t *)event;
connection = event->arg;
2000-01-17 18:02:11 +00:00
INSIST(socket == connection->socket && task == connection->task);
/*
* XXXDCL This recv_lock is a dirty, ugly, nasty hack and I
* am ashamed for it. I have struggled for days with how to
* prevent the driving progam's call of omapi_connection_disconnect
* from conflicting with the execution of the task thread
* (this one, where recv_done is being called).
*
* Basically, most of the real work happens in the task thread,
* all kicked off by signalling "ready" a few lines below. If
* this recv_done() is processing the last expected bytes of a message,
* then it will wake up the driving program, and the driving program
* can go ahead and issue a disconnect. Since there are neither
* events_pending nor messages_expected, end_connecton goes ahead
* and frees the connection. But that can happen before this
* very function can go finish up what it is doing with the
* connection structure, which is clearly a bad thing.
*
* The regular mutex in the connection (the one named "mutex") is
* being used throughout the code in a much more localized fashion,
* and while it might be possible to more broadly scope it so that
* it essentially does the job that recv_lock is doing, I honestly
* have not yet fully thought that out and I have already burned
* so much time trying other approaches before I struck on this
* recv_lock idea. My gut reaction is I don't like how long
* a lock on 'mutex' would be held, and I am not entirely sure
* that there aren't deadlock situations. I have to think about it
* ... LATER.
*/
RUNTIME_CHECK(isc_mutex_lock(&connection->recv_lock) == ISC_R_SUCCESS);
2000-01-06 03:36:32 +00:00
2000-01-14 23:10:04 +00:00
RUNTIME_CHECK(isc_mutex_lock(&connection->mutex) == ISC_R_SUCCESS);
2000-01-17 18:02:11 +00:00
INSIST(connection->events_pending > 0);
2000-01-06 03:36:32 +00:00
connection->events_pending--;
2000-01-14 23:10:04 +00:00
RUNTIME_CHECK(isc_mutex_unlock(&connection->mutex) == ISC_R_SUCCESS);
2000-01-06 03:36:32 +00:00
/*
* Restore the input buffers to the connection object.
*/
for (buffer = ISC_LIST_HEAD(socketevent->bufferlist);
buffer != NULL;
buffer = ISC_LIST_NEXT(buffer, link))
ISC_LIST_APPEND(connection->input_buffers, buffer, link);
2000-01-14 23:10:04 +00:00
if (socketevent->result != ISC_R_SUCCESS)
goto abandon;
2000-01-06 03:36:32 +00:00
connection->in_bytes += socketevent->n;
2000-01-13 06:13:26 +00:00
original_bytes_needed = connection->bytes_needed;
2000-01-17 18:02:11 +00:00
/*
* Signal omapi_protocol_signal_handler that the bytes it requested
* are present.
*
* XXXDCL it will then isc_condition_signal the driving thread,
* which is free to go ahead and call omapi_connection_disconnect.
* since there are possibly no more events pending and no more messages
* expected at that point, the driving thread may end up freeing the
* connection before this routine is done manipulating it.
* what a big, ugly, pain in the rump.
*/
2000-01-06 03:36:32 +00:00
while (connection->bytes_needed <= connection->in_bytes &&
connection->bytes_needed > 0)
2000-01-17 18:02:11 +00:00
2000-01-22 00:18:05 +00:00
if (object_signal((omapi_object_t *)connection, "ready",
connection) != ISC_R_SUCCESS)
2000-01-14 23:10:04 +00:00
goto abandon;
2000-01-06 03:36:32 +00:00
2000-01-17 18:02:11 +00:00
2000-01-06 03:36:32 +00:00
/*
2000-01-13 06:13:26 +00:00
* Queue up another recv request. If the bufferlist is empty,
2000-01-22 00:18:05 +00:00
* then, something under object_signal already called
2000-01-13 06:13:26 +00:00
* omapi_connection_require and queued the recv (which is
2000-01-22 00:18:05 +00:00
* what emptied the bufferlist). Using a value of 0 will cause
* the recv to be queued without adding any more to bytes_needed.
2000-01-06 03:36:32 +00:00
*/
2000-01-13 06:13:26 +00:00
if (! ISC_LIST_EMPTY(connection->input_buffers))
2000-01-22 00:18:05 +00:00
connection_require(connection, 0);
2000-01-06 03:36:32 +00:00
2000-01-14 23:10:04 +00:00
/*
* See if that was the last event the client was expecting, so
2000-01-17 18:02:11 +00:00
* that the connection can be freed. This test needs to be
* done, because it is possible omapi_connection_disconnect has
* already been called, before the signal handler managed to
* decrement messages_expected. That means that _disconnect
* set the state to disconnecting but didn't call the
* end_connection routine. If this was the last event,
* no more events are going to come in and call recv_done again,
* so this is the only time that it can be identified that
* the conditions for finally freeing the connection are all true.
*
* XXXDCL I don't *think* this has to be done in the send_done or
* connect_done handlers, because a normal termination (one defined as
* "omapi_connection_disconnect called by the client with 'force' as
* false") will only happen after the last of the expected data is
* received.
2000-01-14 23:10:04 +00:00
*/
if (connection->is_client) {
RUNTIME_CHECK(isc_mutex_lock(&connection->mutex) ==
ISC_R_SUCCESS);
if (connection->events_pending == 0 &&
connection->state == omapi_connection_disconnecting) {
2000-01-17 18:02:11 +00:00
INSIST(connection->messages_expected == 1);
2000-01-14 23:10:04 +00:00
2000-01-17 18:02:11 +00:00
/*
* omapi_connection_disconnect was called, but
* end_connection has not been. Call it now.
*/
RUNTIME_CHECK(isc_mutex_unlock(&connection->mutex)
== ISC_R_SUCCESS);
RUNTIME_CHECK(isc_mutex_unlock(&connection->recv_lock)
== ISC_R_SUCCESS);
2000-01-14 23:10:04 +00:00
end_connection(connection, event, ISC_R_SUCCESS);
return;
}
RUNTIME_CHECK(isc_mutex_unlock(&connection->mutex) ==
ISC_R_SUCCESS);
}
2000-01-17 18:02:11 +00:00
RUNTIME_CHECK(isc_mutex_unlock(&connection->recv_lock) ==
ISC_R_SUCCESS);
2000-01-14 23:10:04 +00:00
2000-01-06 03:36:32 +00:00
isc_event_free(&event);
2000-01-14 23:10:04 +00:00
return;
2000-01-06 03:36:32 +00:00
2000-01-14 23:10:04 +00:00
abandon:
2000-01-17 18:02:11 +00:00
RUNTIME_CHECK(isc_mutex_unlock(&connection->recv_lock) ==
ISC_R_SUCCESS);
2000-01-14 23:10:04 +00:00
end_connection(connection, event, socketevent->result);
2000-01-06 03:36:32 +00:00
}
/*
* This is the function that is called when a send event is posted on
* the socket as a result of isc_socket_send*.
*/
static void
send_done(isc_task_t *task, isc_event_t *event) {
isc_buffer_t *buffer;
isc_socket_t *socket;
isc_socketevent_t *socketevent;
2000-01-22 00:18:05 +00:00
omapi_connection_t *connection;
2000-01-06 03:36:32 +00:00
socket = event->sender;
socketevent = (isc_socketevent_t *)event;
connection = event->arg;
2000-01-17 18:02:11 +00:00
INSIST(socket == connection->socket && task == connection->task);
2000-01-06 03:36:32 +00:00
2000-01-06 23:56:51 +00:00
/*
* XXXDCL I am assuming that partial writes are not done. I hope this
2000-01-13 06:13:26 +00:00
* does not prove to be incorrect. But the assumption can be tested ...
2000-01-06 23:56:51 +00:00
*/
2000-01-17 18:02:11 +00:00
INSIST(socketevent->n == connection->out_bytes &&
2000-01-06 23:56:51 +00:00
socketevent->n ==
isc_bufferlist_usedcount(&socketevent->bufferlist));
2000-01-14 23:10:04 +00:00
RUNTIME_CHECK(isc_mutex_lock(&connection->mutex) == ISC_R_SUCCESS);
/*
* XXXDCL I may have made an unwarranted assumption about
* events_pending becoming 0 on the client when disconnecting
* only in recv_done. I'm concerned that there might be some
* sort of logic window, however small, where that isn't true.
*/
2000-01-17 18:02:11 +00:00
INSIST(connection->events_pending > 0);
2000-01-14 23:10:04 +00:00
if (--connection->events_pending == 0 && connection->is_client &&
connection->state == omapi_connection_disconnecting)
FATAL_ERROR(__FILE__, __LINE__,
"events_pending == 0 in send_done while "
"disconnecting, this should not happen!");
RUNTIME_CHECK(isc_mutex_unlock(&connection->mutex) == ISC_R_SUCCESS);
2000-01-06 03:36:32 +00:00
/*
2000-01-06 23:56:51 +00:00
* Restore the head of bufferlist into the connection object, resetting
* it to have zero used space, and free the remaining buffers.
* This is done before the test of the socketevent's result so that
2000-01-14 23:10:04 +00:00
* end_connection() can free the buffer, if it is called below.
2000-01-06 03:36:32 +00:00
*/
2000-01-06 23:56:51 +00:00
buffer = ISC_LIST_HEAD(socketevent->bufferlist);
ISC_LIST_APPEND(connection->output_buffers, buffer, link);
isc_buffer_clear(buffer);
while ((buffer = ISC_LIST_NEXT(buffer, link)) != NULL) {
ISC_LIST_UNLINK(socketevent->bufferlist, buffer, link);
isc_buffer_free(&buffer);
}
2000-01-06 03:36:32 +00:00
2000-01-14 23:10:04 +00:00
if (socketevent->result != ISC_R_SUCCESS)
goto abandon;
2000-01-06 03:36:32 +00:00
connection->out_bytes -= socketevent->n;
isc_event_free(&event);
2000-01-14 23:10:04 +00:00
return;
2000-01-06 03:36:32 +00:00
2000-01-14 23:10:04 +00:00
abandon:
end_connection(connection, event, socketevent->result);
2000-01-06 03:36:32 +00:00
}
void
2000-01-22 00:18:05 +00:00
connection_send(omapi_connection_t *connection) {
2000-01-06 03:36:32 +00:00
REQUIRE(connection != NULL &&
connection->type == omapi_type_connection);
2000-01-14 23:10:04 +00:00
REQUIRE(connection->state == omapi_connection_connected);
2000-01-06 03:36:32 +00:00
if (connection->out_bytes > 0) {
2000-01-17 18:02:11 +00:00
INSIST(!ISC_LIST_EMPTY(connection->output_buffers));
2000-01-06 03:36:32 +00:00
2000-01-14 23:10:04 +00:00
RUNTIME_CHECK(isc_mutex_lock(&connection->mutex) ==
ISC_R_SUCCESS);
connection->events_pending++;
RUNTIME_CHECK(isc_mutex_unlock(&connection->mutex) ==
ISC_R_SUCCESS);
2000-01-06 03:36:32 +00:00
isc_socket_sendv(connection->socket,
&connection->output_buffers, connection->task,
send_done, connection);
}
}
2000-01-04 20:04:42 +00:00
/*
* Make an outgoing connection to an OMAPI server.
*/
isc_result_t
2000-01-17 20:06:37 +00:00
connect_toserver(omapi_object_t *protocol, const char *server_name, int port) {
checkpoint conversion to ISC (doc/dev/coding.html) style. * no spaces around " -> " in indirect postfix expression. * no space between function name and open parenthesis. * no space between array name and open bracket. * use NULL not 0 for pointers. * explicitly compare pointers to NULL. * explicitly compare integers to 0. * Do not cast NULL. * return type of function declaration on line by itself. * open brace of function definition follows close parenthesis if parameters all fit on one line. * comment-only lines start with /* on line by itself, and end with */ on line by itself. * variable names in structures separated from their types in a column. * name the parameters in function prototypes. * ifndef multiple header file inclusion. and other BIND9 conventions not in coding.html: * private structures defined in relevant source module, not private header. * RCS /* $Id: $ */ comments. * Principal Author (Ted Lemon) comments. * Updated ISC copyrights. * Parenthesize value of return(). * Parenthesize argument of sizeof(). * "unsigned int foo" not "unsigned foo". * ISC_LANG_(BEGIN|END)DECLS in header files. * header files included directly by source/header file that needs them. * ... and others I am probably forgetting. and conversion to some libisc.a modules: * use isc/int.h for isc_uintXX_t types, not u_intXX_t. * use isc/assertions.h for REQUIRE() and INSIST(). * use isc/error.h for UNEXPECTED_ERROR. * use isc/boolean.h for isc_boolean_t flags instead of int flags. * use isc/net.h for networking types. * use isc/netdb.h for gethostby*. STILL TO COME ... * more isc_boolean_t. * isc/time.h to replace struct timeval. * isc/socket.h to replace socket/listen/select/etc. * isc/mem.h to replace malloc/free. * namespace overhaul & omapi/compatibility.h. Please collect all your belongings but stand clear of the doors until this train has come to a complete stop.
1999-11-02 04:01:34 +00:00
isc_result_t result;
2000-01-04 20:04:42 +00:00
isc_sockaddr_t sockaddr;
2000-01-06 03:36:32 +00:00
isc_buffer_t *ibuffer = NULL, *obuffer = NULL;
isc_task_t *task = NULL;
2000-01-22 00:18:05 +00:00
omapi_connection_t *connection = NULL;
2000-01-04 20:04:42 +00:00
result = get_address(server_name, port, &sockaddr);
if (result != ISC_R_SUCCESS)
return (result);
2000-01-13 06:13:26 +00:00
/* XXXDCL Make cleanup better */
2000-01-04 20:04:42 +00:00
/*
* Prepare the task that will wait for the connection to be made.
*/
result = isc_task_create(omapi_taskmgr, NULL, 0, &task);
if (result != ISC_R_SUCCESS)
return (result);
result = isc_buffer_allocate(omapi_mctx, &ibuffer, OMAPI_BUFFER_SIZE,
ISC_BUFFERTYPE_BINARY);
2000-01-14 23:10:04 +00:00
if (result != ISC_R_SUCCESS)
goto free_task;
2000-01-04 20:04:42 +00:00
result = isc_buffer_allocate(omapi_mctx, &obuffer, OMAPI_BUFFER_SIZE,
ISC_BUFFERTYPE_BINARY);
2000-01-14 23:10:04 +00:00
if (result != ISC_R_SUCCESS)
goto free_ibuffer;
1999-10-27 22:24:32 +00:00
2000-01-04 20:04:42 +00:00
/*
* Create a new connection object.
*/
2000-01-17 18:02:11 +00:00
result = omapi_object_create((omapi_object_t **)&connection,
2000-01-22 00:18:05 +00:00
omapi_type_connection,
sizeof(*connection));
2000-01-14 23:10:04 +00:00
if (result != ISC_R_SUCCESS)
goto free_obuffer;
2000-01-06 03:36:32 +00:00
2000-01-13 06:13:26 +00:00
connection->is_client = ISC_TRUE;
2000-01-17 18:02:11 +00:00
connection->waiting = ISC_FALSE;
2000-01-13 06:13:26 +00:00
2000-01-06 03:36:32 +00:00
connection->task = task;
ISC_LIST_INIT(connection->input_buffers);
ISC_LIST_APPEND(connection->input_buffers, ibuffer, link);
ISC_LIST_INIT(connection->output_buffers);
ISC_LIST_APPEND(connection->output_buffers, obuffer, link);
checkpoint conversion to ISC (doc/dev/coding.html) style. * no spaces around " -> " in indirect postfix expression. * no space between function name and open parenthesis. * no space between array name and open bracket. * use NULL not 0 for pointers. * explicitly compare pointers to NULL. * explicitly compare integers to 0. * Do not cast NULL. * return type of function declaration on line by itself. * open brace of function definition follows close parenthesis if parameters all fit on one line. * comment-only lines start with /* on line by itself, and end with */ on line by itself. * variable names in structures separated from their types in a column. * name the parameters in function prototypes. * ifndef multiple header file inclusion. and other BIND9 conventions not in coding.html: * private structures defined in relevant source module, not private header. * RCS /* $Id: $ */ comments. * Principal Author (Ted Lemon) comments. * Updated ISC copyrights. * Parenthesize value of return(). * Parenthesize argument of sizeof(). * "unsigned int foo" not "unsigned foo". * ISC_LANG_(BEGIN|END)DECLS in header files. * header files included directly by source/header file that needs them. * ... and others I am probably forgetting. and conversion to some libisc.a modules: * use isc/int.h for isc_uintXX_t types, not u_intXX_t. * use isc/assertions.h for REQUIRE() and INSIST(). * use isc/error.h for UNEXPECTED_ERROR. * use isc/boolean.h for isc_boolean_t flags instead of int flags. * use isc/net.h for networking types. * use isc/netdb.h for gethostby*. STILL TO COME ... * more isc_boolean_t. * isc/time.h to replace struct timeval. * isc/socket.h to replace socket/listen/select/etc. * isc/mem.h to replace malloc/free. * namespace overhaul & omapi/compatibility.h. Please collect all your belongings but stand clear of the doors until this train has come to a complete stop.
1999-11-02 04:01:34 +00:00
2000-01-14 23:10:04 +00:00
RUNTIME_CHECK(isc_mutex_init(&connection->mutex) == ISC_R_SUCCESS);
2000-01-17 18:02:11 +00:00
RUNTIME_CHECK(isc_mutex_init(&connection->recv_lock) == ISC_R_SUCCESS);
2000-01-14 23:10:04 +00:00
RUNTIME_CHECK(isc_condition_init(&connection->waiter) ==
ISC_R_SUCCESS);
2000-01-13 06:13:26 +00:00
/*
* An introductory message is expected from the server.
* It is not necessary to lock the mutex here because there
* will be no recv() tasks that could possibly compete for the
* messages_expected variable, since isc_socket_create has
* not even been called yet.
*/
connection->messages_expected = 1;
checkpoint conversion to ISC (doc/dev/coding.html) style. * no spaces around " -> " in indirect postfix expression. * no space between function name and open parenthesis. * no space between array name and open bracket. * use NULL not 0 for pointers. * explicitly compare pointers to NULL. * explicitly compare integers to 0. * Do not cast NULL. * return type of function declaration on line by itself. * open brace of function definition follows close parenthesis if parameters all fit on one line. * comment-only lines start with /* on line by itself, and end with */ on line by itself. * variable names in structures separated from their types in a column. * name the parameters in function prototypes. * ifndef multiple header file inclusion. and other BIND9 conventions not in coding.html: * private structures defined in relevant source module, not private header. * RCS /* $Id: $ */ comments. * Principal Author (Ted Lemon) comments. * Updated ISC copyrights. * Parenthesize value of return(). * Parenthesize argument of sizeof(). * "unsigned int foo" not "unsigned foo". * ISC_LANG_(BEGIN|END)DECLS in header files. * header files included directly by source/header file that needs them. * ... and others I am probably forgetting. and conversion to some libisc.a modules: * use isc/int.h for isc_uintXX_t types, not u_intXX_t. * use isc/assertions.h for REQUIRE() and INSIST(). * use isc/error.h for UNEXPECTED_ERROR. * use isc/boolean.h for isc_boolean_t flags instead of int flags. * use isc/net.h for networking types. * use isc/netdb.h for gethostby*. STILL TO COME ... * more isc_boolean_t. * isc/time.h to replace struct timeval. * isc/socket.h to replace socket/listen/select/etc. * isc/mem.h to replace malloc/free. * namespace overhaul & omapi/compatibility.h. Please collect all your belongings but stand clear of the doors until this train has come to a complete stop.
1999-11-02 04:01:34 +00:00
/*
2000-01-04 20:04:42 +00:00
* Tie the new connection object to the protocol object.
checkpoint conversion to ISC (doc/dev/coding.html) style. * no spaces around " -> " in indirect postfix expression. * no space between function name and open parenthesis. * no space between array name and open bracket. * use NULL not 0 for pointers. * explicitly compare pointers to NULL. * explicitly compare integers to 0. * Do not cast NULL. * return type of function declaration on line by itself. * open brace of function definition follows close parenthesis if parameters all fit on one line. * comment-only lines start with /* on line by itself, and end with */ on line by itself. * variable names in structures separated from their types in a column. * name the parameters in function prototypes. * ifndef multiple header file inclusion. and other BIND9 conventions not in coding.html: * private structures defined in relevant source module, not private header. * RCS /* $Id: $ */ comments. * Principal Author (Ted Lemon) comments. * Updated ISC copyrights. * Parenthesize value of return(). * Parenthesize argument of sizeof(). * "unsigned int foo" not "unsigned foo". * ISC_LANG_(BEGIN|END)DECLS in header files. * header files included directly by source/header file that needs them. * ... and others I am probably forgetting. and conversion to some libisc.a modules: * use isc/int.h for isc_uintXX_t types, not u_intXX_t. * use isc/assertions.h for REQUIRE() and INSIST(). * use isc/error.h for UNEXPECTED_ERROR. * use isc/boolean.h for isc_boolean_t flags instead of int flags. * use isc/net.h for networking types. * use isc/netdb.h for gethostby*. STILL TO COME ... * more isc_boolean_t. * isc/time.h to replace struct timeval. * isc/socket.h to replace socket/listen/select/etc. * isc/mem.h to replace malloc/free. * namespace overhaul & omapi/compatibility.h. Please collect all your belongings but stand clear of the doors until this train has come to a complete stop.
1999-11-02 04:01:34 +00:00
*/
2000-01-17 18:02:11 +00:00
OBJECT_REF(&protocol->outer, connection);
OBJECT_REF(&connection->inner, protocol);
checkpoint conversion to ISC (doc/dev/coding.html) style. * no spaces around " -> " in indirect postfix expression. * no space between function name and open parenthesis. * no space between array name and open bracket. * use NULL not 0 for pointers. * explicitly compare pointers to NULL. * explicitly compare integers to 0. * Do not cast NULL. * return type of function declaration on line by itself. * open brace of function definition follows close parenthesis if parameters all fit on one line. * comment-only lines start with /* on line by itself, and end with */ on line by itself. * variable names in structures separated from their types in a column. * name the parameters in function prototypes. * ifndef multiple header file inclusion. and other BIND9 conventions not in coding.html: * private structures defined in relevant source module, not private header. * RCS /* $Id: $ */ comments. * Principal Author (Ted Lemon) comments. * Updated ISC copyrights. * Parenthesize value of return(). * Parenthesize argument of sizeof(). * "unsigned int foo" not "unsigned foo". * ISC_LANG_(BEGIN|END)DECLS in header files. * header files included directly by source/header file that needs them. * ... and others I am probably forgetting. and conversion to some libisc.a modules: * use isc/int.h for isc_uintXX_t types, not u_intXX_t. * use isc/assertions.h for REQUIRE() and INSIST(). * use isc/error.h for UNEXPECTED_ERROR. * use isc/boolean.h for isc_boolean_t flags instead of int flags. * use isc/net.h for networking types. * use isc/netdb.h for gethostby*. STILL TO COME ... * more isc_boolean_t. * isc/time.h to replace struct timeval. * isc/socket.h to replace socket/listen/select/etc. * isc/mem.h to replace malloc/free. * namespace overhaul & omapi/compatibility.h. Please collect all your belongings but stand clear of the doors until this train has come to a complete stop.
1999-11-02 04:01:34 +00:00
/*
* Create a socket on which to communicate.
*/
2000-01-04 20:04:42 +00:00
result = isc_socket_create(omapi_socketmgr, isc_sockaddr_pf(&sockaddr),
2000-01-06 03:36:32 +00:00
isc_sockettype_tcp, &connection->socket);
2000-01-14 23:10:04 +00:00
if (result != ISC_R_SUCCESS)
goto free_object;
1999-10-27 22:24:32 +00:00
2000-01-06 03:36:32 +00:00
#if 0
checkpoint conversion to ISC (doc/dev/coding.html) style. * no spaces around " -> " in indirect postfix expression. * no space between function name and open parenthesis. * no space between array name and open bracket. * use NULL not 0 for pointers. * explicitly compare pointers to NULL. * explicitly compare integers to 0. * Do not cast NULL. * return type of function declaration on line by itself. * open brace of function definition follows close parenthesis if parameters all fit on one line. * comment-only lines start with /* on line by itself, and end with */ on line by itself. * variable names in structures separated from their types in a column. * name the parameters in function prototypes. * ifndef multiple header file inclusion. and other BIND9 conventions not in coding.html: * private structures defined in relevant source module, not private header. * RCS /* $Id: $ */ comments. * Principal Author (Ted Lemon) comments. * Updated ISC copyrights. * Parenthesize value of return(). * Parenthesize argument of sizeof(). * "unsigned int foo" not "unsigned foo". * ISC_LANG_(BEGIN|END)DECLS in header files. * header files included directly by source/header file that needs them. * ... and others I am probably forgetting. and conversion to some libisc.a modules: * use isc/int.h for isc_uintXX_t types, not u_intXX_t. * use isc/assertions.h for REQUIRE() and INSIST(). * use isc/error.h for UNEXPECTED_ERROR. * use isc/boolean.h for isc_boolean_t flags instead of int flags. * use isc/net.h for networking types. * use isc/netdb.h for gethostby*. STILL TO COME ... * more isc_boolean_t. * isc/time.h to replace struct timeval. * isc/socket.h to replace socket/listen/select/etc. * isc/mem.h to replace malloc/free. * namespace overhaul & omapi/compatibility.h. Please collect all your belongings but stand clear of the doors until this train has come to a complete stop.
1999-11-02 04:01:34 +00:00
/*
* Set the SO_REUSEADDR flag (this should not fail).
2000-01-06 03:36:32 +00:00
* XXXDCL is this needed? isc_socket_* does not support it.
checkpoint conversion to ISC (doc/dev/coding.html) style. * no spaces around " -> " in indirect postfix expression. * no space between function name and open parenthesis. * no space between array name and open bracket. * use NULL not 0 for pointers. * explicitly compare pointers to NULL. * explicitly compare integers to 0. * Do not cast NULL. * return type of function declaration on line by itself. * open brace of function definition follows close parenthesis if parameters all fit on one line. * comment-only lines start with /* on line by itself, and end with */ on line by itself. * variable names in structures separated from their types in a column. * name the parameters in function prototypes. * ifndef multiple header file inclusion. and other BIND9 conventions not in coding.html: * private structures defined in relevant source module, not private header. * RCS /* $Id: $ */ comments. * Principal Author (Ted Lemon) comments. * Updated ISC copyrights. * Parenthesize value of return(). * Parenthesize argument of sizeof(). * "unsigned int foo" not "unsigned foo". * ISC_LANG_(BEGIN|END)DECLS in header files. * header files included directly by source/header file that needs them. * ... and others I am probably forgetting. and conversion to some libisc.a modules: * use isc/int.h for isc_uintXX_t types, not u_intXX_t. * use isc/assertions.h for REQUIRE() and INSIST(). * use isc/error.h for UNEXPECTED_ERROR. * use isc/boolean.h for isc_boolean_t flags instead of int flags. * use isc/net.h for networking types. * use isc/netdb.h for gethostby*. STILL TO COME ... * more isc_boolean_t. * isc/time.h to replace struct timeval. * isc/socket.h to replace socket/listen/select/etc. * isc/mem.h to replace malloc/free. * namespace overhaul & omapi/compatibility.h. Please collect all your belongings but stand clear of the doors until this train has come to a complete stop.
1999-11-02 04:01:34 +00:00
*/
1999-10-27 22:24:32 +00:00
flag = 1;
2000-01-06 03:36:32 +00:00
if (setsockopt(connection->socket, SOL_SOCKET, SO_REUSEADDR,
checkpoint conversion to ISC (doc/dev/coding.html) style. * no spaces around " -> " in indirect postfix expression. * no space between function name and open parenthesis. * no space between array name and open bracket. * use NULL not 0 for pointers. * explicitly compare pointers to NULL. * explicitly compare integers to 0. * Do not cast NULL. * return type of function declaration on line by itself. * open brace of function definition follows close parenthesis if parameters all fit on one line. * comment-only lines start with /* on line by itself, and end with */ on line by itself. * variable names in structures separated from their types in a column. * name the parameters in function prototypes. * ifndef multiple header file inclusion. and other BIND9 conventions not in coding.html: * private structures defined in relevant source module, not private header. * RCS /* $Id: $ */ comments. * Principal Author (Ted Lemon) comments. * Updated ISC copyrights. * Parenthesize value of return(). * Parenthesize argument of sizeof(). * "unsigned int foo" not "unsigned foo". * ISC_LANG_(BEGIN|END)DECLS in header files. * header files included directly by source/header file that needs them. * ... and others I am probably forgetting. and conversion to some libisc.a modules: * use isc/int.h for isc_uintXX_t types, not u_intXX_t. * use isc/assertions.h for REQUIRE() and INSIST(). * use isc/error.h for UNEXPECTED_ERROR. * use isc/boolean.h for isc_boolean_t flags instead of int flags. * use isc/net.h for networking types. * use isc/netdb.h for gethostby*. STILL TO COME ... * more isc_boolean_t. * isc/time.h to replace struct timeval. * isc/socket.h to replace socket/listen/select/etc. * isc/mem.h to replace malloc/free. * namespace overhaul & omapi/compatibility.h. Please collect all your belongings but stand clear of the doors until this train has come to a complete stop.
1999-11-02 04:01:34 +00:00
(char *)&flag, sizeof(flag)) < 0) {
2000-01-17 18:02:11 +00:00
OBJECT_DEREF(&connection);
checkpoint conversion to ISC (doc/dev/coding.html) style. * no spaces around " -> " in indirect postfix expression. * no space between function name and open parenthesis. * no space between array name and open bracket. * use NULL not 0 for pointers. * explicitly compare pointers to NULL. * explicitly compare integers to 0. * Do not cast NULL. * return type of function declaration on line by itself. * open brace of function definition follows close parenthesis if parameters all fit on one line. * comment-only lines start with /* on line by itself, and end with */ on line by itself. * variable names in structures separated from their types in a column. * name the parameters in function prototypes. * ifndef multiple header file inclusion. and other BIND9 conventions not in coding.html: * private structures defined in relevant source module, not private header. * RCS /* $Id: $ */ comments. * Principal Author (Ted Lemon) comments. * Updated ISC copyrights. * Parenthesize value of return(). * Parenthesize argument of sizeof(). * "unsigned int foo" not "unsigned foo". * ISC_LANG_(BEGIN|END)DECLS in header files. * header files included directly by source/header file that needs them. * ... and others I am probably forgetting. and conversion to some libisc.a modules: * use isc/int.h for isc_uintXX_t types, not u_intXX_t. * use isc/assertions.h for REQUIRE() and INSIST(). * use isc/error.h for UNEXPECTED_ERROR. * use isc/boolean.h for isc_boolean_t flags instead of int flags. * use isc/net.h for networking types. * use isc/netdb.h for gethostby*. STILL TO COME ... * more isc_boolean_t. * isc/time.h to replace struct timeval. * isc/socket.h to replace socket/listen/select/etc. * isc/mem.h to replace malloc/free. * namespace overhaul & omapi/compatibility.h. Please collect all your belongings but stand clear of the doors until this train has come to a complete stop.
1999-11-02 04:01:34 +00:00
return (ISC_R_UNEXPECTED);
1999-10-27 22:24:32 +00:00
}
2000-01-04 20:04:42 +00:00
#endif
checkpoint conversion to ISC (doc/dev/coding.html) style. * no spaces around " -> " in indirect postfix expression. * no space between function name and open parenthesis. * no space between array name and open bracket. * use NULL not 0 for pointers. * explicitly compare pointers to NULL. * explicitly compare integers to 0. * Do not cast NULL. * return type of function declaration on line by itself. * open brace of function definition follows close parenthesis if parameters all fit on one line. * comment-only lines start with /* on line by itself, and end with */ on line by itself. * variable names in structures separated from their types in a column. * name the parameters in function prototypes. * ifndef multiple header file inclusion. and other BIND9 conventions not in coding.html: * private structures defined in relevant source module, not private header. * RCS /* $Id: $ */ comments. * Principal Author (Ted Lemon) comments. * Updated ISC copyrights. * Parenthesize value of return(). * Parenthesize argument of sizeof(). * "unsigned int foo" not "unsigned foo". * ISC_LANG_(BEGIN|END)DECLS in header files. * header files included directly by source/header file that needs them. * ... and others I am probably forgetting. and conversion to some libisc.a modules: * use isc/int.h for isc_uintXX_t types, not u_intXX_t. * use isc/assertions.h for REQUIRE() and INSIST(). * use isc/error.h for UNEXPECTED_ERROR. * use isc/boolean.h for isc_boolean_t flags instead of int flags. * use isc/net.h for networking types. * use isc/netdb.h for gethostby*. STILL TO COME ... * more isc_boolean_t. * isc/time.h to replace struct timeval. * isc/socket.h to replace socket/listen/select/etc. * isc/mem.h to replace malloc/free. * namespace overhaul & omapi/compatibility.h. Please collect all your belongings but stand clear of the doors until this train has come to a complete stop.
1999-11-02 04:01:34 +00:00
2000-01-14 23:10:04 +00:00
RUNTIME_CHECK(isc_mutex_lock(&connection->mutex) == ISC_R_SUCCESS);
connection->events_pending++;
RUNTIME_CHECK(isc_mutex_unlock(&connection->mutex) == ISC_R_SUCCESS);
2000-01-06 03:36:32 +00:00
result = isc_socket_connect(connection->socket, &sockaddr, task,
connect_done, connection);
if (result != ISC_R_SUCCESS) {
2000-01-14 23:10:04 +00:00
end_connection(connection, NULL, result);
2000-01-06 03:36:32 +00:00
return (result);
}
2000-01-14 23:10:04 +00:00
return (ISC_R_SUCCESS);
free_object:
2000-01-17 18:02:11 +00:00
OBJECT_DEREF(&connection);
OBJECT_DEREF(&protocol->outer);
2000-01-14 23:10:04 +00:00
return (result);
free_obuffer:
isc_buffer_free(&obuffer);
free_ibuffer:
isc_buffer_free(&ibuffer);
free_task:
isc_task_destroy(&task);
2000-01-13 06:13:26 +00:00
checkpoint conversion to ISC (doc/dev/coding.html) style. * no spaces around " -> " in indirect postfix expression. * no space between function name and open parenthesis. * no space between array name and open bracket. * use NULL not 0 for pointers. * explicitly compare pointers to NULL. * explicitly compare integers to 0. * Do not cast NULL. * return type of function declaration on line by itself. * open brace of function definition follows close parenthesis if parameters all fit on one line. * comment-only lines start with /* on line by itself, and end with */ on line by itself. * variable names in structures separated from their types in a column. * name the parameters in function prototypes. * ifndef multiple header file inclusion. and other BIND9 conventions not in coding.html: * private structures defined in relevant source module, not private header. * RCS /* $Id: $ */ comments. * Principal Author (Ted Lemon) comments. * Updated ISC copyrights. * Parenthesize value of return(). * Parenthesize argument of sizeof(). * "unsigned int foo" not "unsigned foo". * ISC_LANG_(BEGIN|END)DECLS in header files. * header files included directly by source/header file that needs them. * ... and others I am probably forgetting. and conversion to some libisc.a modules: * use isc/int.h for isc_uintXX_t types, not u_intXX_t. * use isc/assertions.h for REQUIRE() and INSIST(). * use isc/error.h for UNEXPECTED_ERROR. * use isc/boolean.h for isc_boolean_t flags instead of int flags. * use isc/net.h for networking types. * use isc/netdb.h for gethostby*. STILL TO COME ... * more isc_boolean_t. * isc/time.h to replace struct timeval. * isc/socket.h to replace socket/listen/select/etc. * isc/mem.h to replace malloc/free. * namespace overhaul & omapi/compatibility.h. Please collect all your belongings but stand clear of the doors until this train has come to a complete stop.
1999-11-02 04:01:34 +00:00
return (result);
1999-10-27 22:24:32 +00:00
}
2000-01-06 03:36:32 +00:00
/*
* Put some bytes into the output buffer for a connection.
*/
isc_result_t
2000-01-22 00:18:05 +00:00
omapi_connection_putmem(omapi_object_t *generic, unsigned char *src,
2000-01-06 03:36:32 +00:00
unsigned int len)
{
2000-01-22 00:18:05 +00:00
omapi_connection_t *connection;
2000-01-06 03:36:32 +00:00
isc_buffer_t *buffer;
2000-01-06 23:56:51 +00:00
isc_bufferlist_t bufferlist;
isc_result_t result;
unsigned int space_available;
2000-01-06 03:36:32 +00:00
2000-01-06 23:56:51 +00:00
REQUIRE(generic != NULL && generic->type == omapi_type_connection);
2000-01-06 03:36:32 +00:00
2000-01-22 00:18:05 +00:00
connection = (omapi_connection_t *)generic;
2000-01-06 03:36:32 +00:00
2000-01-06 23:56:51 +00:00
/*
* Check for enough space in the output buffers.
*/
bufferlist = connection->output_buffers;
space_available = isc_bufferlist_availablecount(&bufferlist);
2000-01-06 03:36:32 +00:00
2000-01-06 23:56:51 +00:00
while (space_available < len) {
/*
* Add new buffers until there is sufficient space.
*/
buffer = NULL;
result = isc_buffer_allocate(omapi_mctx, &buffer,
OMAPI_BUFFER_SIZE,
ISC_BUFFERTYPE_BINARY);
if (result != ISC_R_SUCCESS)
return (result);
2000-01-06 03:36:32 +00:00
2000-01-06 23:56:51 +00:00
space_available += OMAPI_BUFFER_SIZE;
ISC_LIST_APPEND(bufferlist, buffer, link);
}
2000-01-06 03:36:32 +00:00
2000-01-06 23:56:51 +00:00
/*
* XXXDCL out_bytes hardly seems needed as it is easy to get a
* total of how much data is in the output buffers.
*/
2000-01-06 03:36:32 +00:00
connection->out_bytes += len;
2000-01-06 23:56:51 +00:00
/*
2000-01-11 01:49:24 +00:00
* Copy the data into the buffers, splitting across buffers
* as necessary.
2000-01-06 23:56:51 +00:00
*/
for (buffer = ISC_LIST_HEAD(bufferlist); len > 0;
buffer = ISC_LIST_NEXT(buffer, link)) {
space_available = ISC_BUFFER_AVAILABLECOUNT(buffer);
if (space_available > len)
space_available = len;
isc_buffer_putmem(buffer, src, space_available);
src += space_available;
len -= space_available;
}
2000-01-06 03:36:32 +00:00
return (ISC_R_SUCCESS);
}
/*
* Copy some bytes from the input buffer, and advance the input buffer
* pointer beyond the bytes copied out.
*/
2000-01-22 00:18:05 +00:00
void
connection_copyout(unsigned char *dst, omapi_connection_t *connection,
unsigned int size)
2000-01-06 03:36:32 +00:00
{
2000-01-06 23:56:51 +00:00
isc_buffer_t *buffer;
unsigned int copy_bytes;
2000-01-06 03:36:32 +00:00
2000-01-22 00:18:05 +00:00
REQUIRE(connection != NULL &&
connection->type == omapi_type_connection);
2000-01-06 03:36:32 +00:00
2000-01-22 00:18:05 +00:00
INSIST(size <= connection->in_bytes);
2000-01-06 03:36:32 +00:00
2000-01-13 06:13:26 +00:00
connection->bytes_needed -= size;
2000-01-06 23:56:51 +00:00
buffer = ISC_LIST_HEAD(connection->input_buffers);
2000-01-06 03:36:32 +00:00
2000-01-06 23:56:51 +00:00
/*
* The data could potentially be split across multiple buffers,
* so rather than a simple memcpy, a loop is needed.
*/
while (size > 0) {
copy_bytes = buffer->used - buffer->current;
if (copy_bytes > size)
copy_bytes = size;
2000-01-13 06:13:26 +00:00
/*
* When dst == NULL, this function is being used to skip
* over uninteresting input.
*/
if (dst != NULL)
(void)memcpy(dst, buffer->base + buffer->current,
copy_bytes);
2000-01-06 23:56:51 +00:00
isc_buffer_forward(buffer, copy_bytes);
size -= copy_bytes;
connection->in_bytes -= copy_bytes;
buffer = ISC_LIST_NEXT(buffer, link);
}
2000-01-06 03:36:32 +00:00
}
checkpoint conversion to ISC (doc/dev/coding.html) style. * no spaces around " -> " in indirect postfix expression. * no space between function name and open parenthesis. * no space between array name and open bracket. * use NULL not 0 for pointers. * explicitly compare pointers to NULL. * explicitly compare integers to 0. * Do not cast NULL. * return type of function declaration on line by itself. * open brace of function definition follows close parenthesis if parameters all fit on one line. * comment-only lines start with /* on line by itself, and end with */ on line by itself. * variable names in structures separated from their types in a column. * name the parameters in function prototypes. * ifndef multiple header file inclusion. and other BIND9 conventions not in coding.html: * private structures defined in relevant source module, not private header. * RCS /* $Id: $ */ comments. * Principal Author (Ted Lemon) comments. * Updated ISC copyrights. * Parenthesize value of return(). * Parenthesize argument of sizeof(). * "unsigned int foo" not "unsigned foo". * ISC_LANG_(BEGIN|END)DECLS in header files. * header files included directly by source/header file that needs them. * ... and others I am probably forgetting. and conversion to some libisc.a modules: * use isc/int.h for isc_uintXX_t types, not u_intXX_t. * use isc/assertions.h for REQUIRE() and INSIST(). * use isc/error.h for UNEXPECTED_ERROR. * use isc/boolean.h for isc_boolean_t flags instead of int flags. * use isc/net.h for networking types. * use isc/netdb.h for gethostby*. STILL TO COME ... * more isc_boolean_t. * isc/time.h to replace struct timeval. * isc/socket.h to replace socket/listen/select/etc. * isc/mem.h to replace malloc/free. * namespace overhaul & omapi/compatibility.h. Please collect all your belongings but stand clear of the doors until this train has come to a complete stop.
1999-11-02 04:01:34 +00:00
/*
* Disconnect a connection object from the remote end. If force is true,
* close the connection immediately. Otherwise, shut down the receiving end
* but allow any unsent data to be sent before actually closing the socket.
2000-01-14 23:10:04 +00:00
*
* This routine is called in the following situations:
*
* The client wants to exit normally after all its transactions are
* processed. Closing the connection causes an ISC_R_EOF event result
* to be given to the server's recv_done, which then causes the
* server's recv_done to close its side of the connection.
*
* The client got some sort of error it could not handle gracefully, so
* it wants to just tear down the connection. This can be caused either
* internally in the omapi library, or by the calling program.
*
* The server is dropping the connection. This is always asynchronous;
* the server will never block waiting for a connection to be completed
* because it never initiates a "normal" close of the connection.
* (Receipt of ISC_R_EOF is always treated as though it were an error,
* no matter what the client had been intending; it's the nature of
* the protocol.)
*
* The client might or might not want to block on the disconnection.
2000-01-22 00:18:05 +00:00
* Currently the way to accomplish this is to call connection_wait
2000-01-17 18:02:11 +00:00
* before calling this function. A more complex method could be developed,
* but after spending (too much) time thinking about it, it hardly seems to
* be worth the effort when it is easy to just insist that the
2000-01-22 00:18:05 +00:00
* connection_wait be done.
2000-01-17 18:02:11 +00:00
*
2000-01-14 23:10:04 +00:00
* Also, if the error is being thrown from the library, the client
* might *already* be waiting on (or intending to wait on) whatever messages
* it has already sent, so it needs to be awakened. That will be handled
* by free_connection after all of the cancelled events are processed.
checkpoint conversion to ISC (doc/dev/coding.html) style. * no spaces around " -> " in indirect postfix expression. * no space between function name and open parenthesis. * no space between array name and open bracket. * use NULL not 0 for pointers. * explicitly compare pointers to NULL. * explicitly compare integers to 0. * Do not cast NULL. * return type of function declaration on line by itself. * open brace of function definition follows close parenthesis if parameters all fit on one line. * comment-only lines start with /* on line by itself, and end with */ on line by itself. * variable names in structures separated from their types in a column. * name the parameters in function prototypes. * ifndef multiple header file inclusion. and other BIND9 conventions not in coding.html: * private structures defined in relevant source module, not private header. * RCS /* $Id: $ */ comments. * Principal Author (Ted Lemon) comments. * Updated ISC copyrights. * Parenthesize value of return(). * Parenthesize argument of sizeof(). * "unsigned int foo" not "unsigned foo". * ISC_LANG_(BEGIN|END)DECLS in header files. * header files included directly by source/header file that needs them. * ... and others I am probably forgetting. and conversion to some libisc.a modules: * use isc/int.h for isc_uintXX_t types, not u_intXX_t. * use isc/assertions.h for REQUIRE() and INSIST(). * use isc/error.h for UNEXPECTED_ERROR. * use isc/boolean.h for isc_boolean_t flags instead of int flags. * use isc/net.h for networking types. * use isc/netdb.h for gethostby*. STILL TO COME ... * more isc_boolean_t. * isc/time.h to replace struct timeval. * isc/socket.h to replace socket/listen/select/etc. * isc/mem.h to replace malloc/free. * namespace overhaul & omapi/compatibility.h. Please collect all your belongings but stand clear of the doors until this train has come to a complete stop.
1999-11-02 04:01:34 +00:00
*/
void
2000-01-06 23:56:51 +00:00
omapi_connection_disconnect(omapi_object_t *generic, isc_boolean_t force) {
2000-01-22 00:18:05 +00:00
omapi_connection_t *connection;
1999-10-27 22:24:32 +00:00
2000-01-04 20:04:42 +00:00
REQUIRE(generic != NULL);
checkpoint conversion to ISC (doc/dev/coding.html) style. * no spaces around " -> " in indirect postfix expression. * no space between function name and open parenthesis. * no space between array name and open bracket. * use NULL not 0 for pointers. * explicitly compare pointers to NULL. * explicitly compare integers to 0. * Do not cast NULL. * return type of function declaration on line by itself. * open brace of function definition follows close parenthesis if parameters all fit on one line. * comment-only lines start with /* on line by itself, and end with */ on line by itself. * variable names in structures separated from their types in a column. * name the parameters in function prototypes. * ifndef multiple header file inclusion. and other BIND9 conventions not in coding.html: * private structures defined in relevant source module, not private header. * RCS /* $Id: $ */ comments. * Principal Author (Ted Lemon) comments. * Updated ISC copyrights. * Parenthesize value of return(). * Parenthesize argument of sizeof(). * "unsigned int foo" not "unsigned foo". * ISC_LANG_(BEGIN|END)DECLS in header files. * header files included directly by source/header file that needs them. * ... and others I am probably forgetting. and conversion to some libisc.a modules: * use isc/int.h for isc_uintXX_t types, not u_intXX_t. * use isc/assertions.h for REQUIRE() and INSIST(). * use isc/error.h for UNEXPECTED_ERROR. * use isc/boolean.h for isc_boolean_t flags instead of int flags. * use isc/net.h for networking types. * use isc/netdb.h for gethostby*. STILL TO COME ... * more isc_boolean_t. * isc/time.h to replace struct timeval. * isc/socket.h to replace socket/listen/select/etc. * isc/mem.h to replace malloc/free. * namespace overhaul & omapi/compatibility.h. Please collect all your belongings but stand clear of the doors until this train has come to a complete stop.
1999-11-02 04:01:34 +00:00
2000-01-22 00:18:05 +00:00
connection = (omapi_connection_t *)generic;
checkpoint conversion to ISC (doc/dev/coding.html) style. * no spaces around " -> " in indirect postfix expression. * no space between function name and open parenthesis. * no space between array name and open bracket. * use NULL not 0 for pointers. * explicitly compare pointers to NULL. * explicitly compare integers to 0. * Do not cast NULL. * return type of function declaration on line by itself. * open brace of function definition follows close parenthesis if parameters all fit on one line. * comment-only lines start with /* on line by itself, and end with */ on line by itself. * variable names in structures separated from their types in a column. * name the parameters in function prototypes. * ifndef multiple header file inclusion. and other BIND9 conventions not in coding.html: * private structures defined in relevant source module, not private header. * RCS /* $Id: $ */ comments. * Principal Author (Ted Lemon) comments. * Updated ISC copyrights. * Parenthesize value of return(). * Parenthesize argument of sizeof(). * "unsigned int foo" not "unsigned foo". * ISC_LANG_(BEGIN|END)DECLS in header files. * header files included directly by source/header file that needs them. * ... and others I am probably forgetting. and conversion to some libisc.a modules: * use isc/int.h for isc_uintXX_t types, not u_intXX_t. * use isc/assertions.h for REQUIRE() and INSIST(). * use isc/error.h for UNEXPECTED_ERROR. * use isc/boolean.h for isc_boolean_t flags instead of int flags. * use isc/net.h for networking types. * use isc/netdb.h for gethostby*. STILL TO COME ... * more isc_boolean_t. * isc/time.h to replace struct timeval. * isc/socket.h to replace socket/listen/select/etc. * isc/mem.h to replace malloc/free. * namespace overhaul & omapi/compatibility.h. Please collect all your belongings but stand clear of the doors until this train has come to a complete stop.
1999-11-02 04:01:34 +00:00
2000-01-04 20:04:42 +00:00
REQUIRE(connection->type == omapi_type_connection);
checkpoint conversion to ISC (doc/dev/coding.html) style. * no spaces around " -> " in indirect postfix expression. * no space between function name and open parenthesis. * no space between array name and open bracket. * use NULL not 0 for pointers. * explicitly compare pointers to NULL. * explicitly compare integers to 0. * Do not cast NULL. * return type of function declaration on line by itself. * open brace of function definition follows close parenthesis if parameters all fit on one line. * comment-only lines start with /* on line by itself, and end with */ on line by itself. * variable names in structures separated from their types in a column. * name the parameters in function prototypes. * ifndef multiple header file inclusion. and other BIND9 conventions not in coding.html: * private structures defined in relevant source module, not private header. * RCS /* $Id: $ */ comments. * Principal Author (Ted Lemon) comments. * Updated ISC copyrights. * Parenthesize value of return(). * Parenthesize argument of sizeof(). * "unsigned int foo" not "unsigned foo". * ISC_LANG_(BEGIN|END)DECLS in header files. * header files included directly by source/header file that needs them. * ... and others I am probably forgetting. and conversion to some libisc.a modules: * use isc/int.h for isc_uintXX_t types, not u_intXX_t. * use isc/assertions.h for REQUIRE() and INSIST(). * use isc/error.h for UNEXPECTED_ERROR. * use isc/boolean.h for isc_boolean_t flags instead of int flags. * use isc/net.h for networking types. * use isc/netdb.h for gethostby*. STILL TO COME ... * more isc_boolean_t. * isc/time.h to replace struct timeval. * isc/socket.h to replace socket/listen/select/etc. * isc/mem.h to replace malloc/free. * namespace overhaul & omapi/compatibility.h. Please collect all your belongings but stand clear of the doors until this train has come to a complete stop.
1999-11-02 04:01:34 +00:00
2000-01-14 23:10:04 +00:00
/*
* Only the client can request an unforced disconnection. The server's
* disconnection will always happen when the client goes away.
* XXXDCL ... hmm, can timeouts of the client on the server be handled?
*/
REQUIRE(force || connection->is_client);
/*
* XXXDCL this has to be fixed up when isc_socket_shutdown is
* available, because then the shutdown can be done asynchronously.
* It is currently done synchronously.
*/
checkpoint conversion to ISC (doc/dev/coding.html) style. * no spaces around " -> " in indirect postfix expression. * no space between function name and open parenthesis. * no space between array name and open bracket. * use NULL not 0 for pointers. * explicitly compare pointers to NULL. * explicitly compare integers to 0. * Do not cast NULL. * return type of function declaration on line by itself. * open brace of function definition follows close parenthesis if parameters all fit on one line. * comment-only lines start with /* on line by itself, and end with */ on line by itself. * variable names in structures separated from their types in a column. * name the parameters in function prototypes. * ifndef multiple header file inclusion. and other BIND9 conventions not in coding.html: * private structures defined in relevant source module, not private header. * RCS /* $Id: $ */ comments. * Principal Author (Ted Lemon) comments. * Updated ISC copyrights. * Parenthesize value of return(). * Parenthesize argument of sizeof(). * "unsigned int foo" not "unsigned foo". * ISC_LANG_(BEGIN|END)DECLS in header files. * header files included directly by source/header file that needs them. * ... and others I am probably forgetting. and conversion to some libisc.a modules: * use isc/int.h for isc_uintXX_t types, not u_intXX_t. * use isc/assertions.h for REQUIRE() and INSIST(). * use isc/error.h for UNEXPECTED_ERROR. * use isc/boolean.h for isc_boolean_t flags instead of int flags. * use isc/net.h for networking types. * use isc/netdb.h for gethostby*. STILL TO COME ... * more isc_boolean_t. * isc/time.h to replace struct timeval. * isc/socket.h to replace socket/listen/select/etc. * isc/mem.h to replace malloc/free. * namespace overhaul & omapi/compatibility.h. Please collect all your belongings but stand clear of the doors until this train has come to a complete stop.
1999-11-02 04:01:34 +00:00
if (! force) {
/*
2000-01-14 23:10:04 +00:00
* Client wants a clean disconnect.
*
* Increment the count of messages expected. Even though
* no message is really expected, this will keep
2000-01-22 00:18:05 +00:00
* connection_wait from exiting until free_connection()
2000-01-14 23:10:04 +00:00
* signals it.
checkpoint conversion to ISC (doc/dev/coding.html) style. * no spaces around " -> " in indirect postfix expression. * no space between function name and open parenthesis. * no space between array name and open bracket. * use NULL not 0 for pointers. * explicitly compare pointers to NULL. * explicitly compare integers to 0. * Do not cast NULL. * return type of function declaration on line by itself. * open brace of function definition follows close parenthesis if parameters all fit on one line. * comment-only lines start with /* on line by itself, and end with */ on line by itself. * variable names in structures separated from their types in a column. * name the parameters in function prototypes. * ifndef multiple header file inclusion. and other BIND9 conventions not in coding.html: * private structures defined in relevant source module, not private header. * RCS /* $Id: $ */ comments. * Principal Author (Ted Lemon) comments. * Updated ISC copyrights. * Parenthesize value of return(). * Parenthesize argument of sizeof(). * "unsigned int foo" not "unsigned foo". * ISC_LANG_(BEGIN|END)DECLS in header files. * header files included directly by source/header file that needs them. * ... and others I am probably forgetting. and conversion to some libisc.a modules: * use isc/int.h for isc_uintXX_t types, not u_intXX_t. * use isc/assertions.h for REQUIRE() and INSIST(). * use isc/error.h for UNEXPECTED_ERROR. * use isc/boolean.h for isc_boolean_t flags instead of int flags. * use isc/net.h for networking types. * use isc/netdb.h for gethostby*. STILL TO COME ... * more isc_boolean_t. * isc/time.h to replace struct timeval. * isc/socket.h to replace socket/listen/select/etc. * isc/mem.h to replace malloc/free. * namespace overhaul & omapi/compatibility.h. Please collect all your belongings but stand clear of the doors until this train has come to a complete stop.
1999-11-02 04:01:34 +00:00
*/
2000-01-14 23:10:04 +00:00
RUNTIME_CHECK(isc_mutex_lock(&connection->mutex) ==
ISC_R_SUCCESS);
2000-01-17 18:02:11 +00:00
INSIST(connection->state == omapi_connection_connected);
2000-01-14 23:10:04 +00:00
connection->messages_expected++;
checkpoint conversion to ISC (doc/dev/coding.html) style. * no spaces around " -> " in indirect postfix expression. * no space between function name and open parenthesis. * no space between array name and open bracket. * use NULL not 0 for pointers. * explicitly compare pointers to NULL. * explicitly compare integers to 0. * Do not cast NULL. * return type of function declaration on line by itself. * open brace of function definition follows close parenthesis if parameters all fit on one line. * comment-only lines start with /* on line by itself, and end with */ on line by itself. * variable names in structures separated from their types in a column. * name the parameters in function prototypes. * ifndef multiple header file inclusion. and other BIND9 conventions not in coding.html: * private structures defined in relevant source module, not private header. * RCS /* $Id: $ */ comments. * Principal Author (Ted Lemon) comments. * Updated ISC copyrights. * Parenthesize value of return(). * Parenthesize argument of sizeof(). * "unsigned int foo" not "unsigned foo". * ISC_LANG_(BEGIN|END)DECLS in header files. * header files included directly by source/header file that needs them. * ... and others I am probably forgetting. and conversion to some libisc.a modules: * use isc/int.h for isc_uintXX_t types, not u_intXX_t. * use isc/assertions.h for REQUIRE() and INSIST(). * use isc/error.h for UNEXPECTED_ERROR. * use isc/boolean.h for isc_boolean_t flags instead of int flags. * use isc/net.h for networking types. * use isc/netdb.h for gethostby*. STILL TO COME ... * more isc_boolean_t. * isc/time.h to replace struct timeval. * isc/socket.h to replace socket/listen/select/etc. * isc/mem.h to replace malloc/free. * namespace overhaul & omapi/compatibility.h. Please collect all your belongings but stand clear of the doors until this train has come to a complete stop.
1999-11-02 04:01:34 +00:00
/*
2000-01-17 18:02:11 +00:00
* If there are other messages expected for the socket,
* then set the state to disconnecting. Based on that
* flag, when recv_done gets the last output from the server,
* it will then end the connection. The reason the state
* is set to disconnecting only here and not while falling
* through to end_connection below is that it is the
* flag which says whether end_connection has been called or
* not.
checkpoint conversion to ISC (doc/dev/coding.html) style. * no spaces around " -> " in indirect postfix expression. * no space between function name and open parenthesis. * no space between array name and open bracket. * use NULL not 0 for pointers. * explicitly compare pointers to NULL. * explicitly compare integers to 0. * Do not cast NULL. * return type of function declaration on line by itself. * open brace of function definition follows close parenthesis if parameters all fit on one line. * comment-only lines start with /* on line by itself, and end with */ on line by itself. * variable names in structures separated from their types in a column. * name the parameters in function prototypes. * ifndef multiple header file inclusion. and other BIND9 conventions not in coding.html: * private structures defined in relevant source module, not private header. * RCS /* $Id: $ */ comments. * Principal Author (Ted Lemon) comments. * Updated ISC copyrights. * Parenthesize value of return(). * Parenthesize argument of sizeof(). * "unsigned int foo" not "unsigned foo". * ISC_LANG_(BEGIN|END)DECLS in header files. * header files included directly by source/header file that needs them. * ... and others I am probably forgetting. and conversion to some libisc.a modules: * use isc/int.h for isc_uintXX_t types, not u_intXX_t. * use isc/assertions.h for REQUIRE() and INSIST(). * use isc/error.h for UNEXPECTED_ERROR. * use isc/boolean.h for isc_boolean_t flags instead of int flags. * use isc/net.h for networking types. * use isc/netdb.h for gethostby*. STILL TO COME ... * more isc_boolean_t. * isc/time.h to replace struct timeval. * isc/socket.h to replace socket/listen/select/etc. * isc/mem.h to replace malloc/free. * namespace overhaul & omapi/compatibility.h. Please collect all your belongings but stand clear of the doors until this train has come to a complete stop.
1999-11-02 04:01:34 +00:00
*/
2000-01-14 23:10:04 +00:00
if (connection->messages_expected > 1) {
2000-01-17 18:02:11 +00:00
connection->state = omapi_connection_disconnecting;
2000-01-14 23:10:04 +00:00
RUNTIME_CHECK(isc_mutex_unlock(&connection->mutex) ==
ISC_R_SUCCESS);
2000-01-04 20:04:42 +00:00
return;
1999-10-27 22:24:32 +00:00
}
2000-01-17 18:02:11 +00:00
2000-01-14 23:10:04 +00:00
/*
* ... else fall through.
*/
2000-01-17 18:02:11 +00:00
INSIST(connection->events_pending == 0);
2000-01-14 23:10:04 +00:00
RUNTIME_CHECK(isc_mutex_unlock(&connection->mutex) ==
ISC_R_SUCCESS);
1999-10-27 22:24:32 +00:00
}
2000-01-14 23:10:04 +00:00
checkpoint conversion to ISC (doc/dev/coding.html) style. * no spaces around " -> " in indirect postfix expression. * no space between function name and open parenthesis. * no space between array name and open bracket. * use NULL not 0 for pointers. * explicitly compare pointers to NULL. * explicitly compare integers to 0. * Do not cast NULL. * return type of function declaration on line by itself. * open brace of function definition follows close parenthesis if parameters all fit on one line. * comment-only lines start with /* on line by itself, and end with */ on line by itself. * variable names in structures separated from their types in a column. * name the parameters in function prototypes. * ifndef multiple header file inclusion. and other BIND9 conventions not in coding.html: * private structures defined in relevant source module, not private header. * RCS /* $Id: $ */ comments. * Principal Author (Ted Lemon) comments. * Updated ISC copyrights. * Parenthesize value of return(). * Parenthesize argument of sizeof(). * "unsigned int foo" not "unsigned foo". * ISC_LANG_(BEGIN|END)DECLS in header files. * header files included directly by source/header file that needs them. * ... and others I am probably forgetting. and conversion to some libisc.a modules: * use isc/int.h for isc_uintXX_t types, not u_intXX_t. * use isc/assertions.h for REQUIRE() and INSIST(). * use isc/error.h for UNEXPECTED_ERROR. * use isc/boolean.h for isc_boolean_t flags instead of int flags. * use isc/net.h for networking types. * use isc/netdb.h for gethostby*. STILL TO COME ... * more isc_boolean_t. * isc/time.h to replace struct timeval. * isc/socket.h to replace socket/listen/select/etc. * isc/mem.h to replace malloc/free. * namespace overhaul & omapi/compatibility.h. Please collect all your belongings but stand clear of the doors until this train has come to a complete stop.
1999-11-02 04:01:34 +00:00
/*
2000-01-14 23:10:04 +00:00
* XXXDCL
* This might be improved if the 'force' argument to this function
2000-01-22 00:18:05 +00:00
* were instead an isc_reault_t argument. Then object_signal
* could send a "status" back up to a signal handler that could set
* a waitresult.
checkpoint conversion to ISC (doc/dev/coding.html) style. * no spaces around " -> " in indirect postfix expression. * no space between function name and open parenthesis. * no space between array name and open bracket. * use NULL not 0 for pointers. * explicitly compare pointers to NULL. * explicitly compare integers to 0. * Do not cast NULL. * return type of function declaration on line by itself. * open brace of function definition follows close parenthesis if parameters all fit on one line. * comment-only lines start with /* on line by itself, and end with */ on line by itself. * variable names in structures separated from their types in a column. * name the parameters in function prototypes. * ifndef multiple header file inclusion. and other BIND9 conventions not in coding.html: * private structures defined in relevant source module, not private header. * RCS /* $Id: $ */ comments. * Principal Author (Ted Lemon) comments. * Updated ISC copyrights. * Parenthesize value of return(). * Parenthesize argument of sizeof(). * "unsigned int foo" not "unsigned foo". * ISC_LANG_(BEGIN|END)DECLS in header files. * header files included directly by source/header file that needs them. * ... and others I am probably forgetting. and conversion to some libisc.a modules: * use isc/int.h for isc_uintXX_t types, not u_intXX_t. * use isc/assertions.h for REQUIRE() and INSIST(). * use isc/error.h for UNEXPECTED_ERROR. * use isc/boolean.h for isc_boolean_t flags instead of int flags. * use isc/net.h for networking types. * use isc/netdb.h for gethostby*. STILL TO COME ... * more isc_boolean_t. * isc/time.h to replace struct timeval. * isc/socket.h to replace socket/listen/select/etc. * isc/mem.h to replace malloc/free. * namespace overhaul & omapi/compatibility.h. Please collect all your belongings but stand clear of the doors until this train has come to a complete stop.
1999-11-02 04:01:34 +00:00
*/
2000-01-14 23:10:04 +00:00
end_connection(connection, NULL,
force ? ISC_R_UNEXPECTED : ISC_R_SUCCESS);
1999-10-27 22:24:32 +00:00
}
2000-01-06 03:36:32 +00:00
/*
* The caller wants a specific amount of bytes to be read. Queue up a
* recv for the socket.
*/
checkpoint conversion to ISC (doc/dev/coding.html) style. * no spaces around " -> " in indirect postfix expression. * no space between function name and open parenthesis. * no space between array name and open bracket. * use NULL not 0 for pointers. * explicitly compare pointers to NULL. * explicitly compare integers to 0. * Do not cast NULL. * return type of function declaration on line by itself. * open brace of function definition follows close parenthesis if parameters all fit on one line. * comment-only lines start with /* on line by itself, and end with */ on line by itself. * variable names in structures separated from their types in a column. * name the parameters in function prototypes. * ifndef multiple header file inclusion. and other BIND9 conventions not in coding.html: * private structures defined in relevant source module, not private header. * RCS /* $Id: $ */ comments. * Principal Author (Ted Lemon) comments. * Updated ISC copyrights. * Parenthesize value of return(). * Parenthesize argument of sizeof(). * "unsigned int foo" not "unsigned foo". * ISC_LANG_(BEGIN|END)DECLS in header files. * header files included directly by source/header file that needs them. * ... and others I am probably forgetting. and conversion to some libisc.a modules: * use isc/int.h for isc_uintXX_t types, not u_intXX_t. * use isc/assertions.h for REQUIRE() and INSIST(). * use isc/error.h for UNEXPECTED_ERROR. * use isc/boolean.h for isc_boolean_t flags instead of int flags. * use isc/net.h for networking types. * use isc/netdb.h for gethostby*. STILL TO COME ... * more isc_boolean_t. * isc/time.h to replace struct timeval. * isc/socket.h to replace socket/listen/select/etc. * isc/mem.h to replace malloc/free. * namespace overhaul & omapi/compatibility.h. Please collect all your belongings but stand clear of the doors until this train has come to a complete stop.
1999-11-02 04:01:34 +00:00
isc_result_t
2000-01-22 00:18:05 +00:00
connection_require(omapi_connection_t *connection, unsigned int bytes) {
REQUIRE(connection != NULL &&
connection->type == omapi_type_connection);
1999-10-27 22:24:32 +00:00
2000-01-17 18:02:11 +00:00
INSIST(connection->state == omapi_connection_connected ||
2000-01-14 23:10:04 +00:00
connection->state == omapi_connection_disconnecting);
2000-01-06 03:36:32 +00:00
connection->bytes_needed += bytes;
2000-01-04 20:04:42 +00:00
if (connection->bytes_needed <= connection->in_bytes)
checkpoint conversion to ISC (doc/dev/coding.html) style. * no spaces around " -> " in indirect postfix expression. * no space between function name and open parenthesis. * no space between array name and open bracket. * use NULL not 0 for pointers. * explicitly compare pointers to NULL. * explicitly compare integers to 0. * Do not cast NULL. * return type of function declaration on line by itself. * open brace of function definition follows close parenthesis if parameters all fit on one line. * comment-only lines start with /* on line by itself, and end with */ on line by itself. * variable names in structures separated from their types in a column. * name the parameters in function prototypes. * ifndef multiple header file inclusion. and other BIND9 conventions not in coding.html: * private structures defined in relevant source module, not private header. * RCS /* $Id: $ */ comments. * Principal Author (Ted Lemon) comments. * Updated ISC copyrights. * Parenthesize value of return(). * Parenthesize argument of sizeof(). * "unsigned int foo" not "unsigned foo". * ISC_LANG_(BEGIN|END)DECLS in header files. * header files included directly by source/header file that needs them. * ... and others I am probably forgetting. and conversion to some libisc.a modules: * use isc/int.h for isc_uintXX_t types, not u_intXX_t. * use isc/assertions.h for REQUIRE() and INSIST(). * use isc/error.h for UNEXPECTED_ERROR. * use isc/boolean.h for isc_boolean_t flags instead of int flags. * use isc/net.h for networking types. * use isc/netdb.h for gethostby*. STILL TO COME ... * more isc_boolean_t. * isc/time.h to replace struct timeval. * isc/socket.h to replace socket/listen/select/etc. * isc/mem.h to replace malloc/free. * namespace overhaul & omapi/compatibility.h. Please collect all your belongings but stand clear of the doors until this train has come to a complete stop.
1999-11-02 04:01:34 +00:00
return (ISC_R_SUCCESS);
2000-01-06 03:36:32 +00:00
if (connection->bytes_needed >
isc_bufferlist_availablecount(&connection->input_buffers)) {
/*
* Not enough space to put the required volume of information.
* See if the space can be attained by getting rid of the
* used buffer space.
*
* This could be made more efficient by not freeing
* the completely used buffers, but honestly the free/allocate
* code will probably *never* be used in practice; to even test
* the free/allocate stuff OMAPI_BUFFER_SIZE has to be set to
* an absurdly low value (like 4).
*/
isc_bufferlist_t bufferlist = connection->input_buffers;
isc_buffer_t *buffer;
isc_result_t result;
buffer = ISC_LIST_HEAD(bufferlist);
/*
2000-01-06 23:56:51 +00:00
* Lop off any completely used buffers, except the last one.
2000-01-06 03:36:32 +00:00
*/
while (ISC_BUFFER_AVAILABLECOUNT(buffer) == 0 &&
buffer != ISC_LIST_TAIL(bufferlist)) {
ISC_LIST_UNLINK(bufferlist, buffer, link);
isc_buffer_free(&buffer);
buffer = ISC_LIST_HEAD(bufferlist);
}
/*
* Reclaim any used space. (Any buffers after this one,
* if they exist at all, will be empty.)
*/
isc_buffer_compact(buffer);
/*
* Create as many new buffers as necessary to fit the
* entire size requirement.
*/
while (connection->bytes_needed >
isc_bufferlist_availablecount(&bufferlist)) {
buffer = NULL;
result = isc_buffer_allocate(omapi_mctx, &buffer,
OMAPI_BUFFER_SIZE,
ISC_BUFFERTYPE_BINARY);
if (result != ISC_R_SUCCESS)
return (result);
ISC_LIST_APPEND(bufferlist, buffer, link);
}
}
2000-01-14 23:10:04 +00:00
RUNTIME_CHECK(isc_mutex_lock(&connection->mutex) == ISC_R_SUCCESS);
2000-01-17 18:02:11 +00:00
2000-01-06 03:36:32 +00:00
/*
2000-01-17 18:02:11 +00:00
* Queue the receive task.
* XXXDCL The "minimum" arg has not been fully thought out.
2000-01-06 03:36:32 +00:00
*/
2000-01-17 18:02:11 +00:00
connection->events_pending++;
isc_socket_recvv(connection->socket, &connection->input_buffers,
connection->bytes_needed - connection->in_bytes,
connection->task, recv_done, connection);
2000-01-06 03:36:32 +00:00
2000-01-14 23:10:04 +00:00
RUNTIME_CHECK(isc_mutex_unlock(&connection->mutex) ==
ISC_R_SUCCESS);
2000-01-13 06:13:26 +00:00
2000-01-06 03:36:32 +00:00
return (OMAPI_R_NOTYET);
1999-10-27 22:24:32 +00:00
}
2000-01-13 06:13:26 +00:00
/*
2000-01-22 00:18:05 +00:00
* Pause the client until it has received a message from the server, either the
* introductory message or a response to a message it has sent. This is
* necessary because the underlying socket library is multithreaded, and
* it is possible that reading incoming data would trigger an error
* that causes the connection to be destroyed --- while the client program
* is still trying to use it. I don't *think* this problem exists in the
* server. If it does, that's clearly really bad. The server is checking
* all its return values and should not use a connection any more once it has
* decided to blow it away. The only way I could imagine that happening
* is if the socket library would post events of anything other than
* ISC_R_CANCELED after an isc_socket_cancel(ISC_SOCKCANCEL_ALL) is done.
2000-01-13 06:13:26 +00:00
*/
isc_result_t
2000-01-22 00:18:05 +00:00
connection_wait(omapi_object_t *connection_handle, isc_time_t *timeout) {
omapi_connection_t *connection;
2000-01-17 18:02:11 +00:00
isc_result_t result = ISC_R_SUCCESS;
2000-01-13 06:13:26 +00:00
2000-01-22 00:18:05 +00:00
REQUIRE(connection_handle != NULL &&
connection_handle->type == omapi_type_connection);
2000-01-13 06:13:26 +00:00
2000-01-22 00:18:05 +00:00
connection = (omapi_connection_t *)connection_handle;
2000-01-13 06:13:26 +00:00
/*
* This routine is not valid for server connections.
*/
2000-01-17 18:02:11 +00:00
INSIST(connection->is_client);
2000-01-13 06:13:26 +00:00
2000-01-17 18:02:11 +00:00
RUNTIME_CHECK(isc_mutex_lock(&connection->mutex) == ISC_R_SUCCESS);
INSIST(connection->state == omapi_connection_connected);
connection->waiting = ISC_TRUE;
2000-01-13 06:13:26 +00:00
2000-01-17 18:02:11 +00:00
while (connection->messages_expected > 0 && result == ISC_R_SUCCESS)
2000-01-14 23:10:04 +00:00
2000-01-13 06:13:26 +00:00
if (timeout == NULL)
2000-01-17 18:02:11 +00:00
result = isc_condition_wait(&connection->waiter,
&connection->mutex);
2000-01-13 06:13:26 +00:00
else
2000-01-17 18:02:11 +00:00
result = isc_condition_waituntil(&connection->waiter,
&connection->mutex,
timeout);
2000-01-14 23:10:04 +00:00
2000-01-17 18:02:11 +00:00
RUNTIME_CHECK(result == ISC_R_SUCCESS || result == ISC_R_TIMEDOUT);
1999-10-27 22:24:32 +00:00
2000-01-17 18:02:11 +00:00
connection->waiting = ISC_FALSE;
2000-01-13 06:13:26 +00:00
2000-01-17 18:02:11 +00:00
if (connection->state == omapi_connection_closed)
/*
* An error occurred and end_connection needs to have
* free_connection called now that we're done looking
* at connection->messages_expected.
*
* XXXDCL something better to do with the result value?
*/
free_connection(connection);
else
RUNTIME_CHECK(isc_mutex_unlock(&connection->mutex) ==
ISC_R_SUCCESS);
1999-10-27 22:24:32 +00:00
2000-01-17 18:02:11 +00:00
return (result);
1999-10-27 22:24:32 +00:00
}
2000-01-06 03:36:32 +00:00
2000-01-22 00:18:05 +00:00
void
connection_getuint32(omapi_connection_t *connection,
isc_uint32_t *value)
{
2000-01-06 03:36:32 +00:00
isc_uint32_t inbuf;
2000-01-22 00:18:05 +00:00
REQUIRE(connection != NULL &&
connection->type == omapi_type_connection);
connection_copyout((unsigned char *)&inbuf, connection, sizeof(inbuf));
2000-01-06 03:36:32 +00:00
*value = ntohl(inbuf);
2000-01-22 00:18:05 +00:00
}
void
connection_getuint16(omapi_connection_t *connection,
isc_uint16_t *value) {
isc_uint16_t inbuf;
REQUIRE(connection != NULL &&
connection->type == omapi_type_connection);
connection_copyout((unsigned char *)&inbuf, connection, sizeof(inbuf));
*value = ntohs(inbuf);
2000-01-06 03:36:32 +00:00
}
isc_result_t
omapi_connection_putuint32(omapi_object_t *c, isc_uint32_t value) {
isc_uint32_t inbuf;
inbuf = htonl(value);
2000-01-22 00:18:05 +00:00
return (omapi_connection_putmem(c, (unsigned char *)&inbuf,
2000-01-06 03:36:32 +00:00
sizeof(inbuf)));
}
isc_result_t
omapi_connection_putuint16(omapi_object_t *c, isc_uint32_t value) {
isc_uint16_t inbuf;
REQUIRE(value < 65536);
inbuf = htons((isc_uint16_t)value);
2000-01-22 00:18:05 +00:00
return (omapi_connection_putmem(c, (unsigned char *)&inbuf,
2000-01-06 03:36:32 +00:00
sizeof(inbuf)));
}
isc_result_t
2000-01-22 00:18:05 +00:00
omapi_connection_putdata(omapi_object_t *c, omapi_data_t *data) {
2000-01-06 03:36:32 +00:00
isc_result_t result;
omapi_handle_t handle;
REQUIRE(data != NULL &&
(data->type == omapi_datatype_int ||
data->type == omapi_datatype_data ||
2000-01-22 00:18:05 +00:00
data->type == omapi_datatype_string ||
2000-01-06 03:36:32 +00:00
data->type == omapi_datatype_object));
switch (data->type) {
case omapi_datatype_int:
result = omapi_connection_putuint32(c, sizeof(isc_uint32_t));
if (result != ISC_R_SUCCESS)
return (result);
return (omapi_connection_putuint32(c, ((isc_uint32_t)
(data->u.integer))));
case omapi_datatype_string:
case omapi_datatype_data:
result = omapi_connection_putuint32(c, data->u.buffer.len);
if (result != ISC_R_SUCCESS)
return (result);
if (data->u.buffer.len > 0)
2000-01-22 00:18:05 +00:00
return (omapi_connection_putmem(c,
2000-01-06 03:36:32 +00:00
data->u.buffer.value,
data->u.buffer.len));
return (ISC_R_SUCCESS);
case omapi_datatype_object:
if (data->u.object != NULL) {
2000-01-22 00:18:05 +00:00
result = object_gethandle(&handle, data->u.object);
2000-01-06 03:36:32 +00:00
if (result != ISC_R_SUCCESS)
return (result);
} else
handle = 0;
result = omapi_connection_putuint32(c, sizeof(handle));
if (result != ISC_R_SUCCESS)
return (result);
return (omapi_connection_putuint32(c, handle));
}
UNEXPECTED_ERROR(__FILE__, __LINE__,
2000-01-22 00:18:05 +00:00
"unknown type in omapi_connection_putdata: "
2000-01-06 03:36:32 +00:00
"%d\n", data->type);
return (ISC_R_UNEXPECTED);
}
isc_result_t
omapi_connection_putname(omapi_object_t *c, const char *name) {
isc_result_t result;
unsigned int len = strlen(name);
if (len > 65535)
/* XXXDCL better error? */
return (ISC_R_FAILURE);
result = omapi_connection_putuint16(c, len);
if (result != ISC_R_SUCCESS)
return (result);
2000-01-22 00:18:05 +00:00
return (omapi_connection_putmem(c, (char *)name, len));
2000-01-06 03:36:32 +00:00
}
isc_result_t
omapi_connection_putstring(omapi_object_t *c, const char *string) {
isc_result_t result;
unsigned int len;
if (string != NULL)
len = strlen(string);
else
len = 0;
result = omapi_connection_putuint32(c, len);
if (result == ISC_R_SUCCESS && len > 0)
2000-01-22 00:18:05 +00:00
result = omapi_connection_putmem(c, (char *)string, len);
2000-01-06 03:36:32 +00:00
return (result);
}
isc_result_t
omapi_connection_puthandle(omapi_object_t *c, omapi_object_t *h) {
isc_result_t result;
omapi_handle_t handle;
if (h != NULL) {
2000-01-22 00:18:05 +00:00
result = object_gethandle(&handle, h);
2000-01-06 03:36:32 +00:00
if (result != ISC_R_SUCCESS)
return (result);
} else
handle = 0; /* The null handle. */
result = omapi_connection_putuint32(c, sizeof(handle));
if (result == ISC_R_SUCCESS)
result = omapi_connection_putuint32(c, handle);
return (result);
}
2000-01-17 18:02:11 +00:00
static isc_result_t
2000-01-22 00:18:05 +00:00
connection_setvalue(omapi_object_t *connection, omapi_string_t *name,
omapi_data_t *value)
2000-01-17 18:02:11 +00:00
{
REQUIRE(connection != NULL &&
connection->type == omapi_type_connection);
2000-01-22 00:18:05 +00:00
return (omapi_object_passsetvalue(connection, name, value));
2000-01-17 18:02:11 +00:00
}
static isc_result_t
2000-01-22 00:18:05 +00:00
connection_getvalue(omapi_object_t *connection, omapi_string_t *name,
omapi_value_t **value)
2000-01-17 18:02:11 +00:00
{
REQUIRE(connection != NULL &&
connection->type == omapi_type_connection);
2000-01-22 00:18:05 +00:00
return (omapi_object_passgetvalue(connection, name, value));
2000-01-17 18:02:11 +00:00
}
static void
connection_destroy(omapi_object_t *handle) {
2000-01-22 00:18:05 +00:00
omapi_connection_t *connection;
2000-01-17 18:02:11 +00:00
REQUIRE(handle != NULL && handle->type == omapi_type_connection);
2000-01-22 00:18:05 +00:00
connection = (omapi_connection_t *)handle;
2000-01-17 18:02:11 +00:00
2000-01-22 00:18:05 +00:00
if (connection->state != omapi_connection_disconnecting) {
UNEXPECTED_ERROR(__FILE__, __LINE__,
"Unexpected path to connection_destroy\n"
"The connection object was dereferenced "
"without a previous disconnect.\n");
2000-01-17 18:02:11 +00:00
omapi_connection_disconnect(handle, OMAPI_FORCE_DISCONNECT);
2000-01-22 00:18:05 +00:00
}
2000-01-17 18:02:11 +00:00
}
static isc_result_t
connection_signalhandler(omapi_object_t *connection, const char *name,
va_list ap)
{
REQUIRE(connection != NULL &&
connection->type == omapi_type_connection);
2000-01-22 00:18:05 +00:00
return (omapi_object_passsignal(connection, name, ap));
2000-01-17 18:02:11 +00:00
}
/*
* Write all the published values associated with the object through the
* specified connection.
*/
static isc_result_t
2000-01-22 00:18:05 +00:00
connection_stuffvalues(omapi_object_t *connection, omapi_object_t *handle)
2000-01-17 18:02:11 +00:00
{
REQUIRE(connection != NULL &&
connection->type == omapi_type_connection);
2000-01-22 00:18:05 +00:00
return (omapi_object_passstuffvalues(connection, handle));
2000-01-17 18:02:11 +00:00
}
isc_result_t
2000-01-22 00:18:05 +00:00
connection_init(void) {
return (omapi_object_register(&omapi_type_connection, "connection",
connection_setvalue,
connection_getvalue,
connection_destroy,
connection_signalhandler,
connection_stuffvalues,
NULL, NULL, NULL));
2000-01-17 18:02:11 +00:00
}