2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-09-01 06:55:30 +00:00

checkpoint

This commit is contained in:
David Lawrence
2000-01-17 20:06:37 +00:00
parent eb421ff1a1
commit 4c9113533d
10 changed files with 361 additions and 576 deletions

View File

@@ -27,7 +27,9 @@
#include <isc/assertions.h>
#include <isc/commandline.h>
#include <isc/condition.h>
#include <isc/mem.h>
#include <isc/mutex.h>
#include <isc/result.h>
#include <omapi/omapip.h>
@@ -38,11 +40,17 @@ isc_mem_t *mctx;
/*
* Two different structures are used in this program to store the
* value of interest on both the client and the server, but the
* same structure can be used on each if desired.
* same structure can be used on each if desired (with the other variables
* that are not in common between them being stored elsewhere).
*/
typedef struct server_object {
OMAPI_OBJECT_PREAMBLE;
unsigned long value;
struct {
isc_boolean_t finished;
isc_mutex_t lock;
isc_condition_t wait;
} listen;
} server_object_t;
typedef struct client_object {
@@ -87,15 +95,15 @@ open_object(omapi_object_t *handle, omapi_object_t *manager,
* Create a new message object to store the information that will
* be sent to the server.
*/
ENSURE(omapi_message_new(&message, "open_object") == ISC_R_SUCCESS);
INSIST(omapi_message_new(&message) == ISC_R_SUCCESS);
/*
* Specify the OPEN operation, and the UPDATE option if requested.
*/
ENSURE(omapi_set_int_value(message, NULL, "op", OMAPI_OP_OPEN)
INSIST(omapi_set_int_value(message, NULL, "op", OMAPI_OP_OPEN)
== ISC_R_SUCCESS);
if (update)
ENSURE(omapi_set_boolean_value(message, NULL, "update", 1)
INSIST(omapi_set_boolean_value(message, NULL, "update", 1)
== ISC_R_SUCCESS);
/*
@@ -103,7 +111,7 @@ open_object(omapi_object_t *handle, omapi_object_t *manager,
* to know this so that it can apply the proper object methods
* for lookup/setvalue.
*/
ENSURE(omapi_set_string_value(message, NULL, "type",SERVER_OBJECT_TYPE)
INSIST(omapi_set_string_value(message, NULL, "type",SERVER_OBJECT_TYPE)
== ISC_R_SUCCESS);
/*
@@ -113,14 +121,14 @@ open_object(omapi_object_t *handle, omapi_object_t *manager,
* pair to use as a key for looking up the desired object at
* the server.
*/
ENSURE(omapi_set_object_value(message, NULL, "object", handle)
INSIST(omapi_set_object_value(message, NULL, "object", handle)
== ISC_R_SUCCESS);
/*
* Add the new message to the list of known messages.
* XXXDCL Why exactly?
*/
ENSURE(omapi_message_register(message) == ISC_R_SUCCESS);
omapi_message_register(message);
/*
* Deliver the message to the server. The manager's outer object
@@ -154,7 +162,7 @@ client_setvalue(omapi_object_t *handle, omapi_object_t *id,
*/
if (omapi_ds_strcmp(name, MASTER_VALUE) == 0) {
ENSURE(omapi_get_int_value(&server_value, value)
INSIST(omapi_get_int_value(&server_value, value)
== ISC_R_SUCCESS);
client->value = server_value;
@@ -199,13 +207,13 @@ client_stuffvalues(omapi_object_t *connection, omapi_object_t *id,
* Write the MASTER_VALUE name, followed by the value length,
* follwed by its value.
*/
ENSURE(omapi_connection_putname(connection, MASTER_VALUE)
INSIST(omapi_connection_putname(connection, MASTER_VALUE)
== ISC_R_SUCCESS);
ENSURE(omapi_connection_putuint32(connection, sizeof(isc_uint32_t))
INSIST(omapi_connection_putuint32(connection, sizeof(isc_uint32_t))
== ISC_R_SUCCESS);
ENSURE(omapi_connection_putuint32(connection, client->value)
INSIST(omapi_connection_putuint32(connection, client->value)
== ISC_R_SUCCESS);
return (ISC_R_SUCCESS);
@@ -272,7 +280,7 @@ server_setvalue(omapi_object_t *handle, omapi_object_t *id,
(void)id; /* Unused. */
ENSURE(handle == (omapi_object_t *)&master_data);
INSIST(handle == (omapi_object_t *)&master_data);
/*
* Only one name is supported for this object, MASTER_VALUE.
@@ -280,7 +288,7 @@ server_setvalue(omapi_object_t *handle, omapi_object_t *id,
if (omapi_ds_strcmp(name, MASTER_VALUE) == 0) {
fprintf(stderr, "existing value: %lu\n", master_data.value);
ENSURE(omapi_get_int_value(&new_value, value)
INSIST(omapi_get_int_value(&new_value, value)
== ISC_R_SUCCESS);
master_data.value = new_value;
@@ -336,13 +344,13 @@ server_stuffvalues(omapi_object_t *connection, omapi_object_t *id,
* Write the MASTER_VALUE name, followed by the value length,
* follwed by its value.
*/
ENSURE(omapi_connection_putname(connection, MASTER_VALUE)
INSIST(omapi_connection_putname(connection, MASTER_VALUE)
== ISC_R_SUCCESS);
ENSURE(omapi_connection_putuint32(connection, sizeof(isc_uint32_t))
INSIST(omapi_connection_putuint32(connection, sizeof(isc_uint32_t))
== ISC_R_SUCCESS);
ENSURE(omapi_connection_putuint32(connection, master->value)
INSIST(omapi_connection_putuint32(connection, master->value)
== ISC_R_SUCCESS);
return (ISC_R_SUCCESS);
@@ -355,7 +363,7 @@ do_connect(const char *host, int port) {
omapi_object_t *omapi_client;
client_object_t *client;
ENSURE(omapi_object_type_register(&client_type, "client",
INSIST(omapi_object_register(&client_type, "client",
client_setvalue,
NULL, /* getvalue */
NULL, /* destroy */
@@ -371,10 +379,10 @@ do_connect(const char *host, int port) {
* connection to the server.
*/
manager = NULL;
ENSURE(omapi_generic_new(&manager, "main")
INSIST(omapi_object_create(&manager, NULL, 0)
== ISC_R_SUCCESS);
ENSURE(omapi_protocol_connect(manager, host, port, NULL)
INSIST(omapi_protocol_connect(manager, host, port, NULL)
== ISC_R_SUCCESS);
connection = manager->outer->outer;
@@ -382,19 +390,15 @@ do_connect(const char *host, int port) {
/*
* Wait to be connected.
*/
ENSURE(omapi_connection_wait(manager, connection, NULL)
INSIST(omapi_connection_wait(manager, connection, NULL)
== ISC_R_SUCCESS);
/*
* Create the client's object.
*/
client = malloc(sizeof(client_object_t));
ENSURE(client != NULL);
memset(client, 0, sizeof(client_object_t));
client->type = client_type;
client->refcnt = 1;
client = NULL;
omapi_object_create((omapi_object_t **)&client, client_type,
sizeof(client_object_t));
omapi_client = (omapi_object_t *)client;
/*
@@ -404,16 +408,16 @@ do_connect(const char *host, int port) {
* name/value is created with the value of 0, but any interger
* value would work.
*/
ENSURE(omapi_set_int_value(omapi_client, NULL, MASTER_VALUE, 0)
INSIST(omapi_set_int_value(omapi_client, NULL, MASTER_VALUE, 0)
== ISC_R_SUCCESS);
ENSURE(open_object(omapi_client, manager, ISC_FALSE)
INSIST(open_object(omapi_client, manager, ISC_FALSE)
== ISC_R_SUCCESS);
ENSURE(omapi_connection_wait(omapi_client, connection, NULL)
INSIST(omapi_connection_wait(omapi_client, connection, NULL)
== ISC_R_SUCCESS);
ENSURE(client->waitresult == ISC_R_SUCCESS);
INSIST(client->waitresult == ISC_R_SUCCESS);
/*
* Set the new value to be stored at the server and reopen the
@@ -421,48 +425,39 @@ do_connect(const char *host, int port) {
*/
fprintf(stderr, "existing value: %lu\n", client->value);
client->value *= 2;
if (client->value == 0) /* Check overflow. */
client->value = 1;
fprintf(stderr, "new value: %lu\n", client->value);
ENSURE(open_object(omapi_client, manager, ISC_TRUE)
INSIST(open_object(omapi_client, manager, ISC_TRUE)
== ISC_R_SUCCESS);
ENSURE(omapi_connection_wait(omapi_client, connection, NULL)
INSIST(omapi_connection_wait(omapi_client, connection, NULL)
== ISC_R_SUCCESS);
ENSURE(client->waitresult == ISC_R_SUCCESS);
INSIST(client->waitresult == ISC_R_SUCCESS);
/*
* Close the connection and wait to be disconnected.
* XXXDCL This problem has been biting my butt for two days
* straight! I am totally zoning on how to best accomplish
* making disconnection be either sync or async, and some
* internal thread race conditions i am having in the omapi library.
* grr grr grr grr GRRRRR
* at the moment things work ok enough by requiring that
* the connection be waited before calling omapi_connection_disconnect
* and sleeping a moment. clearly this is BOGUS
*/
sleep(1);
omapi_connection_disconnect(connection, ISC_FALSE);
ENSURE(client->waitresult == ISC_R_SUCCESS);
omapi_connection_disconnect(connection, OMAPI_CLEAN_DISCONNECT);
/*
* Free the protocol manager.
* Free the protocol manager and client object.
*/
omapi_object_dereference(&manager, "do_connect");
omapi_object_dereference(&manager);
omapi_object_dereference((omapi_object_t **)&client);
}
static void
do_listen(int port) {
omapi_object_t *listener;
omapi_object_t *listener = NULL;
isc_result_t result;
/*
* Create the manager for handling incoming server connections.
*/
listener = NULL;
ENSURE(omapi_generic_new(&listener, "main")
== ISC_R_SUCCESS);
INSIST(omapi_object_create(&listener, NULL, 0) == ISC_R_SUCCESS);
/*
* Register the server_object. The SERVER_OBJECT_TYPE is what
@@ -470,7 +465,7 @@ do_listen(int port) {
* when * contacting the server in order to be able to find objects
* server_type.
*/
ENSURE(omapi_object_type_register(&server_type, SERVER_OBJECT_TYPE,
INSIST(omapi_object_register(&server_type, SERVER_OBJECT_TYPE,
server_setvalue,
NULL, /* setvalue */
NULL, /* destroy */
@@ -486,19 +481,38 @@ do_listen(int port) {
*/
master_data.type = server_type;
master_data.value = 2;
master_data.listen.finished = ISC_FALSE;
INSIST(isc_mutex_init(&master_data.listen.lock) == ISC_R_SUCCESS);
INSIST(isc_condition_init(&master_data.listen.wait) == ISC_R_SUCCESS);
INSIST(isc_mutex_lock(&master_data.listen.lock) == ISC_R_SUCCESS);
/*
* Start listening for connections.
*/
ENSURE(omapi_protocol_listen(listener, port, 1)
INSIST(omapi_protocol_listen(listener, port, 1)
== ISC_R_SUCCESS);
fprintf(stderr, "SERVER STARTED\n");
/*
* Loop forever getting connections.
* Block until done.
* XXX Currently "until done" has no real meaning. I'm going
* to add a shutdown trigger that will signal the condition,
* to test memory cleanup in the server side.
*/
omapi_dispatch(NULL);
do {
result = isc_condition_wait(&master_data.listen.wait,
&master_data.listen.lock);
} while (result == ISC_R_SUCCESS && ! master_data.listen.finished);
INSIST(result == ISC_R_SUCCESS);
INSIST(isc_mutex_unlock(&master_data.listen.lock) == ISC_R_SUCCESS);
INSIST(isc_mutex_destroy(&master_data.listen.lock) == ISC_R_SUCCESS);
INSIST(isc_condition_destroy(&master_data.listen.wait) ==
ISC_R_SUCCESS);
}
int
@@ -523,9 +537,9 @@ main (int argc, char **argv) {
argc -= isc_commandline_index;
argv += isc_commandline_index;
ENSURE(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS);
INSIST(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS);
ENSURE(omapi_init(mctx) == ISC_R_SUCCESS);
INSIST(omapi_init(mctx) == ISC_R_SUCCESS);
if (argc > 1 && strcmp(argv[0], "listen") == 0) {
if (argc < 2) {
@@ -550,7 +564,7 @@ main (int argc, char **argv) {
exit (1);
}
omapi_shutdown();
omapi_destroy();
if (show_final_mem)
isc_mem_stats(mctx, stderr);

View File

@@ -31,12 +31,12 @@ CDEFINES =
CWARNINGS =
# Alphabetically
OBJS = connection.@O@ data.@O@ dispatch.@O@ generic.@O@ \
OBJS = connection.@O@ data.@O@ generic.@O@ \
handle.@O@ lib.@O@ listener.@O@ message.@O@ object.@O@ \
protocol.@O@ result.@O@ support.@O@ version.@O@
# Alphabetically
SRCS = connection.c data.c dispatch.c generic.c \
SRCS = connection.c data.c generic.c \
handle.c lib.c listener.c message.c object.c \
protocol.c result.c support.c version.c

View File

@@ -15,7 +15,7 @@
* SOFTWARE.
*/
/* $Id: connection.c,v 1.9 2000/01/17 18:02:04 tale Exp $ */
/* $Id: connection.c,v 1.10 2000/01/17 20:06:31 tale Exp $ */
/* Principal Author: Ted Lemon */
@@ -524,9 +524,7 @@ connection_send(omapi_connection_object_t *connection) {
* Make an outgoing connection to an OMAPI server.
*/
isc_result_t
omapi_connection_toserver(omapi_object_t *protocol, const char *server_name,
int port)
{
connect_toserver(omapi_object_t *protocol, const char *server_name, int port) {
isc_result_t result;
isc_sockaddr_t sockaddr;
isc_buffer_t *ibuffer = NULL, *obuffer = NULL;

View File

@@ -1,41 +0,0 @@
/*
* 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.
*/
/* $Id: dispatch.c,v 1.8 2000/01/17 18:02:05 tale Exp $ */
/* Principal Author: Ted Lemon */
/*
* I/O dispatcher.
*/
#include <stddef.h> /* NULL */
#include <string.h> /* memset */
#include <isc/assertions.h>
#include <isc/int.h>
#include <omapi/private.h>
isc_result_t
omapi_dispatch(struct timeval *t) {
/*
* XXXDCL sleep forever? The socket thread will be doing all the work.
*/
select(0, NULL, NULL, NULL, t ? t : NULL);
return (ISC_R_SUCCESS);
}

View File

@@ -144,8 +144,7 @@ struct omapi_object_type {
omapi_data_string_t *name,
omapi_value_t **value);
void (*destroy)(omapi_object_t *object,
const char *name);
void (*destroy)(omapi_object_t *object);
isc_result_t (*signal_handler)(omapi_object_t *object,
const char *name,
@@ -199,51 +198,12 @@ isc_result_t
omapi_protocol_send_intro(omapi_object_t *object, unsigned int version,
unsigned int object_size);
isc_result_t
omapi_protocol_set_value(omapi_object_t *object, omapi_object_t *id,
omapi_data_string_t *name, omapi_typed_data_t *value);
isc_result_t
omapi_protocol_get_value(omapi_object_t *object, omapi_object_t *id,
omapi_data_string_t *name, omapi_value_t **value);
isc_result_t
omapi_protocol_stuff_values(omapi_object_t *connection, omapi_object_t *id,
omapi_object_t *object);
void
omapi_protocol_destroy(omapi_object_t *object);
isc_result_t
omapi_protocol_send_message(omapi_object_t *protocol,
omapi_object_t *id,
omapi_object_t *message,
omapi_object_t *original_message);
isc_result_t
omapi_protocol_signal_handler(omapi_object_t *protocol, const char *name,
va_list args);
isc_result_t
omapi_protocol_listener_set_value(omapi_object_t *object, omapi_object_t *id,
omapi_data_string_t *name,
omapi_typed_data_t *value);
isc_result_t
omapi_protocol_listener_get_value(omapi_object_t *object, omapi_object_t *id,
omapi_data_string_t *name,
omapi_value_t **value);
void
omapi_protocol_listener_destroy(omapi_object_t *object);
isc_result_t
omapi_protocol_listener_signal(omapi_object_t *protocol_listener,
const char *names, va_list args);
isc_result_t
omapi_protocol_listener_stuff(omapi_object_t *connection, omapi_object_t *id,
omapi_object_t *object);
isc_result_t
omapi_protocol_send_status(omapi_object_t *protcol, omapi_object_t *id,
isc_result_t waitstatus, unsigned int response_id,
@@ -256,13 +216,6 @@ omapi_protocol_send_update(omapi_object_t *protocl, omapi_object_t *id,
/*
* connection.c (XXX and buffer.c)
*/
isc_result_t
omapi_connect(omapi_object_t *connection, const char *server, int port);
isc_result_t
omapi_connection_toserver(omapi_object_t *connection, const char *server,
int port);
void
omapi_connection_disconnect(omapi_object_t *connection, isc_boolean_t force);

View File

@@ -108,6 +108,46 @@ typedef struct omapi_generic_object {
unsigned int va_max;
} omapi_generic_object_t;
typedef enum {
omapi_protocol_intro_wait,
omapi_protocol_header_wait,
omapi_protocol_signature_wait,
omapi_protocol_name_wait,
omapi_protocol_name_length_wait,
omapi_protocol_value_wait,
omapi_protocol_value_length_wait
} omapi_protocol_state_t;
typedef struct {
OMAPI_OBJECT_PREAMBLE;
unsigned int header_size;
unsigned int protocol_version;
isc_uint32_t next_xid;
omapi_object_t * authinfo; /* Default authinfo. */
omapi_protocol_state_t state; /* Input state. */
/* XXXDCL make isc_boolean_t */
/*
* True when reading message-specific values.
*/
isc_boolean_t reading_message_values;
omapi_message_object_t * message; /* Incoming message. */
omapi_data_string_t * name; /* Incoming name. */
omapi_typed_data_t * value; /* Incoming value. */
} omapi_protocol_object_t;
/*
* OMAPI protocol header, version 1.00
*/
typedef struct {
unsigned int authlen; /* Length of authenticator. */
unsigned int authid; /* Authenticator object ID. */
unsigned int op; /* Opcode. */
omapi_handle_t handle; /* Handle of object being operated on, or 0. */
unsigned int id; /* Transaction ID. */
unsigned int rid; /* ID of transaction responding to. */
} omapi_protocol_header_t;
typedef struct omapi_waiter_object {
OMAPI_OBJECT_PREAMBLE;
isc_mutex_t mutex;
@@ -127,8 +167,7 @@ extern omapi_object_type_t *omapi_type_message;
extern omapi_object_type_t *omapi_object_types;
/*
* Everything needs a memory context. This will likely be made a parameter
* where needed rather than a single global context. XXXDCL
* Everything needs a memory context.
*/
extern isc_mem_t *omapi_mctx;
@@ -144,9 +183,6 @@ extern isc_socketmgr_t *omapi_socketmgr;
extern isc_boolean_t omapi_ipv6;
void
connection_send(omapi_connection_object_t *connection);
#define OBJECT_REF(objectp, object) \
omapi_object_reference((omapi_object_t **)objectp, \
(omapi_object_t *)object)
@@ -205,6 +241,15 @@ omapi_generic_init(void);
isc_result_t
omapi_message_init(void);
isc_result_t
omapi_protocol_init(void);
void
connection_send(omapi_connection_object_t *connection);
isc_result_t
connect_toserver(omapi_object_t *connection, const char *server, int port);
ISC_LANG_ENDDECLS
#endif /* OMAPIP_OMAPIP_P_H */

View File

@@ -42,11 +42,12 @@ typedef struct omapi_listener_object {
static void
listener_accept(isc_task_t *task, isc_event_t *event) {
isc_result_t result;
isc_buffer_t *ibuffer, *obuffer;
isc_buffer_t *ibuffer = NULL;
isc_buffer_t *obuffer = NULL;
isc_task_t *connection_task = NULL;
isc_socket_newconnev_t *incoming;
isc_socket_t *socket;
omapi_connection_object_t *connection = NULL;
omapi_object_t *listener;
omapi_object_t *protocol = NULL;
/*
* XXXDCL What are the meaningful things the listen/accept function
@@ -56,21 +57,28 @@ listener_accept(isc_task_t *task, isc_event_t *event) {
*/
/*
* Set up another listen task for the socket.
* Immediately set up another listen task for the socket.
*/
isc_socket_accept(event->sender, task, listener_accept,
event->arg);
isc_socket_accept(event->sender, task, listener_accept, event->arg);
result = ((isc_socket_newconnev_t *)event)->result;
socket = ((isc_socket_newconnev_t *)event)->newsocket;
/*
* No more need for the event, once all the desired data has been
* used from it.
*/
isc_event_free(&event);
/*
* Check for the validity of new connection event.
*/
incoming = (isc_socket_newconnev_t *)event;
if (incoming->result != ISC_R_SUCCESS)
if (result != ISC_R_SUCCESS)
/*
* The result is probably ISC_R_UNEXPECTED; what can really be
* done about this other than just flunking out of here?
*/
goto free_event;
return;
/*
* The new connection is good to go. Allocate the buffers for it and
@@ -102,16 +110,9 @@ listener_accept(isc_task_t *task, isc_event_t *event) {
connection->task = connection_task;
connection->state = omapi_connection_connected;
connection->socket = incoming->newsocket;
connection->socket = socket;
connection->is_client = ISC_FALSE;
/*
* No more need for the event, once all the desired data has been
* used from it.
*/
listener = event->arg;
isc_event_free(&event);
ISC_LIST_INIT(connection->input_buffers);
ISC_LIST_APPEND(connection->input_buffers, ibuffer, link);
ISC_LIST_INIT(connection->output_buffers);
@@ -121,24 +122,57 @@ listener_accept(isc_task_t *task, isc_event_t *event) {
RUNTIME_CHECK(isc_mutex_init(&connection->recv_lock) == ISC_R_SUCCESS);
/*
* Notify the listener object that a connection was made.
* Create a new protocol object to oversee the handling of this
* connection.
*/
result = omapi_signal(listener, "connect", connection);
protocol = NULL;
result = omapi_object_create(&protocol, omapi_type_protocol,
sizeof(omapi_protocol_object_t));
if (result != ISC_R_SUCCESS)
goto free_object;
goto free_connection_object;
/*
* Tie the protocol object bidirectionally to the connection
* object, with the connection as the outer object.
*/
OBJECT_REF(&protocol->outer, connection);
OBJECT_REF(&connection->inner, protocol);
/*
* Send the introductory message.
*/
result = omapi_protocol_send_intro(protocol, OMAPI_PROTOCOL_VERSION,
sizeof(omapi_protocol_header_t));
if (result != ISC_R_SUCCESS)
goto free_protocol_object;
/*
* Lose one reference to the connection, so it'll be gc'd when it's
* reaped. The omapi_protocol_listener_signal function added a
* reference when it created a protocol object as connection->inner.
* XXXDCL that's Ted's comment, but I don't see how it can be true.
* I don't see how it will "lose one reference" since
* omapi_object_dereference does not decrement refcnt.
*/
OBJECT_DEREF(&connection);
return;
free_object:
free_protocol_object:
/*
* Remove the protocol object's reference to the connection
* object, so that the connection object will be destroyed.
* XXXDCL aigh, this is so confusing. I don't think the
* right thing is being done.
*/
OBJECT_DEREF(&connection->inner);
OBJECT_DEREF(&protocol);
/* FALLTHROUGH */
free_connection_object:
/*
* Destroy the connection. This will free everything created
* in this function but the event.
* in this function but the event, which was already freed.
*/
OBJECT_DEREF(&connection);
return;
@@ -152,8 +186,6 @@ free_ibuffer:
isc_buffer_free(&ibuffer);
free_task:
isc_task_destroy(&connection_task);
free_event:
isc_event_free(&event);
return;
}
@@ -169,23 +201,19 @@ omapi_listener_listen(omapi_object_t *caller, int port, int max) {
if (result != ISC_R_SUCCESS)
return (result);
#if 0 /*XXXDCL*/
result = isc_task_onshutdown(task, omapi_listener_shutdown, NULL);
if (result != ISC_R_SUCCESS)
return (result);
#endif
/*
* Get the handle.
* Create the listener object.
*/
listener = isc_mem_get(omapi_mctx, sizeof(*listener));
if (listener == NULL)
return (ISC_R_NOMEMORY);
memset(listener, 0, sizeof(*listener));
listener->object_size = sizeof(*listener);
listener->refcnt = 1;
listener = NULL;
result = omapi_object_create((omapi_object_t **)&listener,
omapi_type_listener, sizeof(*listener));
if (result != ISC_R_SUCCESS) {
isc_task_destroy(&task);
return (result);
}
listener->task = task;
listener->type = omapi_type_listener;
/*
* Tie the listener object to the calling object.
@@ -199,47 +227,37 @@ omapi_listener_listen(omapi_object_t *caller, int port, int max) {
listener->socket = NULL;
result = isc_socket_create(omapi_socketmgr, PF_INET,
isc_sockettype_tcp, &listener->socket);
if (result != ISC_R_SUCCESS) {
/* XXXDCL this call and later will not free the listener
* because it has two refcnts, one for existing plus one
* for the tie to h->outer. This does not seem right to me.
*/
OBJECT_DEREF(&listener);
return (result);
}
if (result == ISC_R_SUCCESS) {
/*
* Set up the address on which we will listen.
* Set up the addressses on which to listen and bind to it.
*/
inaddr.s_addr = INADDR_ANY;
isc_sockaddr_fromin(&listener->address, &inaddr, port);
/*
* Try to bind to the wildcard address using the port number
* we were given.
*/
result = isc_socket_bind(listener->socket, &listener->address);
if (result != ISC_R_SUCCESS) {
OBJECT_DEREF(&listener);
return (result);
}
if (result == ISC_R_SUCCESS)
/*
* Now tell the kernel to listen for connections.
*/
result = isc_socket_listen(listener->socket, max);
if (result != ISC_R_SUCCESS) {
OBJECT_DEREF(&listener);
return (result);
}
if (result == ISC_R_SUCCESS)
/*
* Queue up the first accept event. The listener object
* will be passed to listener_accept() when it is called.
* will be passed to listener_accept() when it is called,
* though currently nothing is done with it.
*/
result = isc_socket_accept(listener->socket, task,
listener_accept, listener);
if (result != ISC_R_SUCCESS)
/*
* The listener has a refcnt of 2, so this does not really
* free it. XXXDCL
*/
OBJECT_DEREF(&listener);
return (result);
@@ -279,6 +297,8 @@ listener_destroy(omapi_object_t *object) {
listener = (omapi_listener_object_t *)object;
isc_task_destroy(&listener->task);
if (listener->socket != NULL) {
#if 0 /*XXXDCL*/
isc_socket_cancel(listener->socket, NULL, ISC_SOCKCANCEL_ALL);
@@ -323,8 +343,7 @@ listener_stuffvalues(omapi_object_t *connection, omapi_object_t *id,
isc_result_t
omapi_listener_init(void) {
return (omapi_object_register(&omapi_type_listener,
"listener",
return (omapi_object_register(&omapi_type_listener, "listener",
listener_setvalue,
listener_getvalue,
listener_destroy,

View File

@@ -15,7 +15,7 @@
* SOFTWARE.
*/
/* $Id: object.c,v 1.5 2000/01/17 18:02:08 tale Exp $ */
/* $Id: object.c,v 1.6 2000/01/17 20:06:34 tale Exp $ */
/* Principal Author: Ted Lemon */
@@ -159,7 +159,7 @@ omapi_object_dereference(omapi_object_t **h) {
if (outer_reference != 0)
OBJECT_DEREF(&(*h)->outer->inner);
if ((*h)->type->destroy != NULL)
(*((*h)->type->destroy))(*h, NULL);
(*((*h)->type->destroy))(*h);
isc_mem_put(omapi_mctx, *h, (*h)->object_size);
}
}

View File

@@ -27,50 +27,10 @@
#include <omapi/private.h>
typedef enum {
omapi_protocol_intro_wait,
omapi_protocol_header_wait,
omapi_protocol_signature_wait,
omapi_protocol_name_wait,
omapi_protocol_name_length_wait,
omapi_protocol_value_wait,
omapi_protocol_value_length_wait
} omapi_protocol_state_t;
typedef struct {
OMAPI_OBJECT_PREAMBLE;
} omapi_protocol_listener_object_t;
typedef struct {
OMAPI_OBJECT_PREAMBLE;
unsigned int header_size;
unsigned int protocol_version;
isc_uint32_t next_xid;
omapi_object_t * authinfo; /* Default authinfo. */
omapi_protocol_state_t state; /* Input state. */
/* XXXDCL make isc_boolean_t */
/*
* True when reading message-specific values.
*/
isc_boolean_t reading_message_values;
omapi_message_object_t * message; /* Incoming message. */
omapi_data_string_t * name; /* Incoming name. */
omapi_typed_data_t * value; /* Incoming value. */
} omapi_protocol_object_t;
/*
* OMAPI protocol header, version 1.00
*/
typedef struct {
unsigned int authlen; /* Length of authenticator. */
unsigned int authid; /* Authenticator object ID. */
unsigned int op; /* Opcode. */
omapi_handle_t handle; /* Handle of object being operated on, or 0. */
unsigned int id; /* Transaction ID. */
unsigned int rid; /* ID of transaction responding to. */
} omapi_protocol_header_t;
isc_result_t
omapi_protocol_connect(omapi_object_t *h, const char *server_name,
int port, omapi_object_t *authinfo)
@@ -84,8 +44,7 @@ omapi_protocol_connect(omapi_object_t *h, const char *server_name,
if (result != ISC_R_SUCCESS)
return (result);
result = omapi_connection_toserver((omapi_object_t *)obj,
server_name, port);
result = connect_toserver((omapi_object_t *)obj, server_name, port);
if (result != ISC_R_SUCCESS) {
OBJECT_DEREF(&obj);
return (result);
@@ -345,8 +304,93 @@ disconnect:
return (result);
}
/*
* Set up a listener for the omapi protocol.
*/
isc_result_t
omapi_protocol_signal_handler(omapi_object_t *h, const char *name, va_list ap)
omapi_protocol_listen(omapi_object_t *manager, int port, int max) {
return (omapi_listener_listen((omapi_object_t *)manager, port, max));
}
isc_result_t
omapi_protocol_send_status(omapi_object_t *po, omapi_object_t *id,
isc_result_t waitstatus,
unsigned int rid, const char *msg)
{
isc_result_t result;
omapi_object_t *message = NULL;
REQUIRE(po != NULL && po->type == omapi_type_protocol);
result = omapi_message_new(&message);
if (result != ISC_R_SUCCESS)
return (result);
result = omapi_set_int_value(message, NULL, "op", OMAPI_OP_STATUS);
if (result == ISC_R_SUCCESS)
result = omapi_set_int_value(message, NULL, "rid", (int)rid);
if (result == ISC_R_SUCCESS)
result = omapi_set_int_value(message, NULL, "result",
(int)waitstatus);
/*
* If a message has been provided, send it.
*/
if (result == ISC_R_SUCCESS && msg != NULL)
result = omapi_set_string_value(message, NULL, "message", msg);
if (result != ISC_R_SUCCESS) {
OBJECT_DEREF(&message);
return (result);
}
return (omapi_protocol_send_message(po, id, message, NULL));
}
isc_result_t
omapi_protocol_send_update(omapi_object_t *po, omapi_object_t *id,
unsigned int rid, omapi_object_t *object)
{
isc_result_t result;
omapi_object_t *message = NULL;
REQUIRE(po != NULL && po->type == omapi_type_protocol);
result = omapi_message_new(&message);
if (result != ISC_R_SUCCESS)
return (result);
result = omapi_set_int_value(message, NULL, "op", OMAPI_OP_UPDATE);
if (result == ISC_R_SUCCESS && rid != 0) {
omapi_handle_t handle;
result = omapi_set_int_value(message, NULL, "rid", (int)rid);
if (result == ISC_R_SUCCESS)
result = omapi_object_handle(&handle, object);
if (result == ISC_R_SUCCESS)
result = omapi_set_int_value(message, NULL,
"handle", (int)handle);
}
if (result == ISC_R_SUCCESS)
result = omapi_set_object_value(message, NULL,
"object", object);
if (result != ISC_R_SUCCESS) {
OBJECT_DEREF(&message);
return (result);
}
return (omapi_protocol_send_message(po, id, message, NULL));
}
static isc_result_t
protocol_signalhandler(omapi_object_t *h, const char *name, va_list ap)
{
isc_result_t result;
omapi_protocol_object_t *p;
@@ -781,8 +825,8 @@ disconnect:
return (result);
}
isc_result_t
omapi_protocol_set_value(omapi_object_t *h, omapi_object_t *id,
static isc_result_t
protocol_setvalue(omapi_object_t *h, omapi_object_t *id,
omapi_data_string_t *name, omapi_typed_data_t *value)
{
REQUIRE(h != NULL && h->type == omapi_type_protocol);
@@ -790,18 +834,17 @@ omapi_protocol_set_value(omapi_object_t *h, omapi_object_t *id,
PASS_SETVALUE(h);
}
isc_result_t
omapi_protocol_get_value(omapi_object_t *h, omapi_object_t *id,
omapi_data_string_t *name,
omapi_value_t **value)
static isc_result_t
protocol_getvalue(omapi_object_t *h, omapi_object_t *id,
omapi_data_string_t *name, omapi_value_t **value)
{
REQUIRE(h != NULL && h->type == omapi_type_protocol);
PASS_GETVALUE(h);
}
void
omapi_protocol_destroy(omapi_object_t *h) {
static void
protocol_destroy(omapi_object_t *h) {
omapi_protocol_object_t *p;
REQUIRE(h != NULL && h->type == omapi_type_protocol);
@@ -815,13 +858,8 @@ omapi_protocol_destroy(omapi_object_t *h) {
OBJECT_DEREF(&p->authinfo);
}
/*
* Write all the published values associated with the object through the
* specified connection.
*/
isc_result_t
omapi_protocol_stuff_values(omapi_object_t *connection, omapi_object_t *id,
static isc_result_t
protocol_stuffvalues(omapi_object_t *connection, omapi_object_t *id,
omapi_object_t *h)
{
REQUIRE(h != NULL && h->type == omapi_type_protocol);
@@ -829,227 +867,13 @@ omapi_protocol_stuff_values(omapi_object_t *connection, omapi_object_t *id,
PASS_STUFFVALUES(h);
}
/*
* Set up a listener for the omapi protocol. The handle stored points to
* a listener object, not a protocol object.
*/
isc_result_t
omapi_protocol_listen(omapi_object_t *h, int port, int max) {
isc_result_t result;
omapi_protocol_listener_object_t *obj;
obj = isc_mem_get(omapi_mctx, sizeof(*obj));
if (obj == NULL)
return (ISC_R_NOMEMORY);
memset(obj, 0, sizeof(*obj));
obj->object_size = sizeof(*obj);
obj->refcnt = 1;
obj->type = omapi_type_protocol_listener;
OBJECT_REF(&h->outer, obj);
OBJECT_REF(&obj->inner, h);
result = omapi_listener_listen((omapi_object_t *)obj, port, max);
OBJECT_DEREF(&obj);
return (result);
}
/*
* Signal handler for protocol listener - if we get a connect signal,
* create a new protocol connection, otherwise pass the signal down.
*/
isc_result_t
omapi_protocol_listener_signal(omapi_object_t *h, const char *name, va_list ap)
{
isc_result_t result;
omapi_object_t *c;
omapi_protocol_object_t *obj;
omapi_protocol_listener_object_t *p;
REQUIRE(h != NULL && h->type == omapi_type_protocol_listener);
p = (omapi_protocol_listener_object_t *)h;
/*
* Not a signal we recognize?
*/
if (strcmp(name, "connect") != 0) {
PASS_SIGNAL(h);
}
c = va_arg(ap, omapi_object_t *);
ENSURE(c != NULL && c->type == omapi_type_connection);
/*
* Create a new protocol object to oversee the handling of this
* connection.
*/
obj = NULL;
result = omapi_object_create((omapi_object_t **)&obj,
omapi_type_protocol, sizeof(*obj));
if (result != ISC_R_SUCCESS)
/*
* When the unsuccessful return value is percolated back to
* omapi_listener_accept, then it will remove the only
* reference, which will close and cleanup the connection.
*/
return (result);
/*
* Tie the protocol object bidirectionally to the connection
* object, with the connection as the outer object.
*/
OBJECT_REF(&obj->outer, c);
OBJECT_REF(&c->inner, obj);
/*
* Send the introductory message.
*/
result = omapi_protocol_send_intro((omapi_object_t *)obj,
OMAPI_PROTOCOL_VERSION,
sizeof(omapi_protocol_header_t));
if (result != ISC_R_SUCCESS)
/*
* Remove the protocol object's reference to the connection
* object, so that when the unsuccessful return value is
* received in omapi_listener_accept, the connection object
* will be destroyed.
* XXXDCL aigh, this is so confusing. I don't think the
* right thing is being done.
*/
OBJECT_DEREF(&c->inner);
/*
* Remove one of the references to the object, so it will be
* freed when the connection dereferences its inner object.
* XXXDCL this is what ted did, but i'm not sure my explanation
* is correct.
*/
OBJECT_DEREF(&obj);
return (result);
}
isc_result_t
omapi_protocol_listener_set_value(omapi_object_t *h, omapi_object_t *id,
omapi_data_string_t *name,
omapi_typed_data_t *value)
{
REQUIRE(h != NULL && h->type == omapi_type_protocol_listener);
PASS_SETVALUE(h);
}
isc_result_t
omapi_protocol_listener_get_value(omapi_object_t *h, omapi_object_t *id,
omapi_data_string_t *name,
omapi_value_t **value)
{
REQUIRE(h != NULL && h->type == omapi_type_protocol_listener);
PASS_GETVALUE(h);
}
void
omapi_protocol_listener_destroy(omapi_object_t *h) {
REQUIRE(h != NULL && h->type == omapi_type_protocol_listener);
/* XXXDCL currently NOTHING */
}
/*
* Write all the published values associated with the object through the
* specified connection.
*/
isc_result_t
omapi_protocol_listener_stuff(omapi_object_t *connection, omapi_object_t *id,
omapi_object_t *h)
{
REQUIRE(h != NULL && h->type == omapi_type_protocol_listener);
PASS_STUFFVALUES(h);
}
isc_result_t
omapi_protocol_send_status(omapi_object_t *po, omapi_object_t *id,
isc_result_t waitstatus,
unsigned int rid, const char *msg)
{
isc_result_t result;
omapi_object_t *message = NULL;
REQUIRE(po != NULL && po->type == omapi_type_protocol);
result = omapi_message_new(&message);
if (result != ISC_R_SUCCESS)
return (result);
result = omapi_set_int_value(message, NULL, "op", OMAPI_OP_STATUS);
if (result == ISC_R_SUCCESS)
result = omapi_set_int_value(message, NULL, "rid", (int)rid);
if (result == ISC_R_SUCCESS)
result = omapi_set_int_value(message, NULL, "result",
(int)waitstatus);
/*
* If a message has been provided, send it.
*/
if (result == ISC_R_SUCCESS && msg != NULL)
result = omapi_set_string_value(message, NULL, "message", msg);
if (result != ISC_R_SUCCESS) {
OBJECT_DEREF(&message);
return (result);
}
return (omapi_protocol_send_message(po, id, message, NULL));
}
isc_result_t
omapi_protocol_send_update(omapi_object_t *po, omapi_object_t *id,
unsigned int rid, omapi_object_t *object)
{
isc_result_t result;
omapi_object_t *message = NULL;
REQUIRE(po != NULL && po->type == omapi_type_protocol);
result = omapi_message_new(&message);
if (result != ISC_R_SUCCESS)
return (result);
result = omapi_set_int_value(message, NULL, "op", OMAPI_OP_UPDATE);
if (result == ISC_R_SUCCESS && rid != 0) {
omapi_handle_t handle;
result = omapi_set_int_value(message, NULL, "rid", (int)rid);
if (result == ISC_R_SUCCESS)
result = omapi_object_handle(&handle, object);
if (result == ISC_R_SUCCESS)
result = omapi_set_int_value(message, NULL,
"handle", (int)handle);
}
if (result == ISC_R_SUCCESS)
result = omapi_set_object_value(message, NULL,
"object", object);
if (result != ISC_R_SUCCESS) {
OBJECT_DEREF(&message);
return (result);
}
return (omapi_protocol_send_message(po, id, message, NULL));
omapi_protocol_init(void) {
return (omapi_object_register(&omapi_type_protocol, "protocol",
protocol_setvalue,
protocol_getvalue,
protocol_destroy,
protocol_signalhandler,
protocol_stuffvalues,
NULL, NULL, NULL));
}

View File

@@ -45,10 +45,6 @@ isc_result_t
omapi_init(isc_mem_t *mctx) {
isc_result_t result;
/*
* XXXDCL probeipv6?
*/
if (mctx != NULL)
omapi_mctx = mctx;
@@ -75,42 +71,19 @@ omapi_init(isc_mem_t *mctx) {
omapi_ipv6 = ISC_FALSE;
/*
* Initialize all the standard object types.
* Initialize the standard object types.
*/
result = omapi_generic_init();
if (result != ISC_R_SUCCESS)
return (result);
if (result == ISC_R_SUCCESS)
result = omapi_listener_init();
if (result != ISC_R_SUCCESS)
return (result);
if (result == ISC_R_SUCCESS)
result = omapi_connection_init();
if (result != ISC_R_SUCCESS)
return (result);
result = omapi_object_register(&omapi_type_protocol,
"protocol",
omapi_protocol_set_value,
omapi_protocol_get_value,
omapi_protocol_destroy,
omapi_protocol_signal_handler,
omapi_protocol_stuff_values,
0, 0, 0);
if (result != ISC_R_SUCCESS)
return (result);
result = omapi_object_register(&omapi_type_protocol_listener,
"protocol-listener",
omapi_protocol_listener_set_value,
omapi_protocol_listener_get_value,
omapi_protocol_listener_destroy,
omapi_protocol_listener_signal,
omapi_protocol_listener_stuff,
0, 0, 0);
if (result != ISC_R_SUCCESS)
return (result);
if (result == ISC_R_SUCCESS)
result = omapi_protocol_init();
if (result == ISC_R_SUCCESS)
result = omapi_message_init();
return (result);