omapi_test.c revision 40f53fa8d9c6a4fc38c0014495e7a42b08f52481
/*
* Copyright (C) 1996-2000 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
* DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
* INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
* FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: omapi_test.c,v 1.27 2000/08/01 01:13:09 tale Exp $ */
/*
* Test code for OMAPI.
*/
#include <config.h>
#include <stdlib.h>
#include <isc/commandline.h>
#include <isc/condition.h>
char *progname;
/*
* 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 (with the other variables
* that are not in common between them being stored elsewhere).
*/
typedef struct server_object {
unsigned long value;
typedef struct client_object {
unsigned long value;
static server_object_t master_data;
static omapi_objecttype_t *server_type;
static omapi_objecttype_t *client_type;
static isc_condition_t waiter;
static isc_mutex_t mutex;
/*
* This is a string that names the registry of objects of type server_object_t.
*/
#define SERVER_OBJECT_TYPE "test-data"
/*
* This is the name of the variable that is being manipulated in the server.
* Note that it necessarily has no direct relevance to the *real* name of
* the variable (but of course, making them the same would make for clearer
* programming).
*/
#define MASTER_VALUE "amount"
#define KEY1_NAME "test-key"
#define KEY2_NAME "another-key"
/*
* Create an OMAPI message on the client that requests an object on the
* server be opened. If the boolean 'update' is given, then the value
* of the client's object will set the value of the server's object,
* otherwise the server just refreshes the values in the client's object
* with the master data.
*/
static isc_result_t
{
/*
* Create a new message object to store the information that will
* be sent to the server.
*/
/*
* Specify the OPEN operation, and the UPDATE option if requested.
*/
== ISC_R_SUCCESS);
if (update)
== ISC_R_SUCCESS);
/*
* Tell the server the type of the object being opened; it needs
* to know this so that it can apply the proper object methods
*/
== ISC_R_SUCCESS);
/*
* Associate the client object with the message, so that it
* will have its values stuffed in the message. Without it,
* pair to use as a key for looking up the desired object at
* the server.
*/
if (! error_noobject)
== ISC_R_SUCCESS);
/*
* Set up an object that will receive the "status" signal in its
* signal handler when the response is received from the server.
* This is not needed as a general rule, because normally the
* the object associated with the name "object" in the message
* is what gets that message. However, in this case the
* particular error that is being tested when error_noobject is true
* is one where no item named "object" has been set, so not only
* can it not be used as a key when the server gets the message,
* it can't be used to get the "status" signal on the client
* when the server's "no key" error message comes back.
*
* If both "object" and "notify-object" are set, only the latter
* will receive the signal (as currently written; it was originally
* the other way 'round). In this particular case it hardly matters,
* as both "object" and "notify-object" are the same object.
*/
== ISC_R_SUCCESS);
/*
* Add the new message to the list of known messages. When the
* server's response comes back, the client will verify that
* the response was for a message it really sent.
*/
/*
* Deliver the message to the server. The manager's outer object
* is the connection object to the server.
*/
/*
* Free the message.
*/
return (ISC_R_SUCCESS);
}
/*
* client_setvalue() is called on the client by the library's internal
* message_process() function when the server replies to the OPEN operation
* with its own REFRESH message for the client. It is how the client learns
* what data is on the server.
*/
static isc_result_t
{
/*
* Only the MASTER_VALUE value has meaning in this program.
*/
return (ISC_R_SUCCESS);
/*
* The server will also set "remote-handle" to let the client
* have an identifier for the object on the server that could
* be used with the other OMAPI operations, such as
* OMAPI_OP_DELETE. The value of remote-handle is an integer,
* fetched with:
* omapi_data_getint(&remote_handle, value).
*
* It is not used by this test program.
*/
return (ISC_R_SUCCESS);
}
return (ISC_R_NOTFOUND);
}
/*
* This function is used by omapi_message_send to publish the values of
* the data in a client object.
*/
static isc_result_t
/*
* Write the MASTER_VALUE name, followed by the value length,
* follwed by its value.
*/
== ISC_R_SUCCESS);
sizeof(isc_uint32_t))
== ISC_R_SUCCESS);
== ISC_R_SUCCESS);
return (ISC_R_SUCCESS);
}
static isc_result_t
/*
* "status" is signalled with the result of the message's
* operation.
*/
(error_nosig &&
(error_badsig &&
}
} else {
/*
* Pass any unknown signal any internal object.
* (This normally does not happen; there is no
* inner object, nor anything else being signalled.)
*/
}
return (ISC_R_SUCCESS);
}
/*
* This is the function that is called when an incoming OMAPI_OP_OPEN
* message is received with either the create or update option set.
* value list.
*
* (Primary caller: message_process())
*/
static isc_result_t
{
/*
* Only one name is supported for this object, MASTER_VALUE.
*/
/*
* 32 is an arbitrary disconnect point.
*/
}
return (ISC_R_SUCCESS);
}
return (ISC_R_NOTFOUND);
}
/*
* This is the function that is called by the library's internal
* message_process() function when an incoming OMAPI_OP_OPEN
* message is received. It is normally supposed to look up the object
* in 'ref'.
*/
static isc_result_t
/*
* For this test program, there is only one static structure
* which is being used, so key is not needed.
*/
return (ISC_R_SUCCESS);
}
/*
* This function is called when the server is sending a reply to a client
* that opened an object of its type. It needs to output all published
* for any inner objects (but in this program, there will be no inner
* objects).
*/
static isc_result_t
/*
* Write the MASTER_VALUE name, followed by the value length,
* follwed by its value.
*/
== ISC_R_SUCCESS);
sizeof(isc_uint32_t))
== ISC_R_SUCCESS);
== ISC_R_SUCCESS);
return (ISC_R_SUCCESS);
}
static void
const char *key;
const char *bad_secret1 = "this secret is wrong";
const char *bad_secret2 = "Yet Another Secret";
NULL, /* getvalue */
NULL, /* destroy */
NULL, /* lookup */
NULL, /* create */
NULL) /* remove */
== ISC_R_SUCCESS);
/*
* Create the top level object which will manage the
* connection to the server.
*/
== ISC_R_SUCCESS);
if (result != ISC_R_SUCCESS) {
return;
}
/*
* Authenticate to the server.
*/
if (error_badsig) {
== ISC_R_SUCCESS);
} else if (error_unknownsig) {
== ISC_R_SUCCESS);
}
if (! error_nosig) {
if (result != ISC_R_SUCCESS)
? "expected" : "UNEXPECTED");
}
if (result == ISC_R_SUCCESS) {
/*
* Create the client's object.
*/
sizeof(client_object_t));
/*
* even before it contacts the server so the server will know
* that there is an object that needs values filled in. This
* value would work.
*/
MASTER_VALUE, 0)
== ISC_R_SUCCESS);
== ISC_R_SUCCESS);
/*
* Set the new value to be stored at the server and
* reopen the server object with an UPDATE operation.
*/
== ISC_R_SUCCESS);
}
}
/*
* Close the connection and wait to be disconnected.
*/
/*
* Free the protocol manager and client object.
*/
if (omapi_client != NULL)
}
static void
}
static isc_boolean_t
/* XXXDCL test the connection verification code */
return (ISC_TRUE);
}
static isc_boolean_t
/* XXXDCL test the key verification code */
return (ISC_TRUE);
}
static void
/*
* Create the manager for handling incoming server connections.
*/
== ISC_R_SUCCESS);
/*
* Register the server_object. The SERVER_OBJECT_TYPE is what
* a client would need to specify as a value for the name "type"
* when contacting the server in order to be able to find objects
* server_type.
*/
NULL, /* getvalue */
NULL, /* destroy */
NULL, /* signalhandler */
NULL, /* create */
NULL) /* remove */
== ISC_R_SUCCESS);
/*
* Initialize the server_object data.
*/
/*
* Set the access control list for valid connections.
*/
if (error_denyall)
else
/*
* Start listening for connections.
*/
== ISC_R_SUCCESS);
/*
* Lose one reference to the acl; the omapi library holds another
* reference and should free it when it is done.
*/
/*
* Block until done. "Done" is when server_setvalue has reached
* its trigger value.
*/
do {
} while (! master_data.target_reached);
}
int
const char *secret = "shhh, this is a secret";
int ch;
progname++;
else
switch (ch) {
case 'e':
if (ARG_IS("noobject"))
else if (ARG_IS("nosig"))
else if (ARG_IS("badsig"))
else if (ARG_IS("unknownsig"))
else if (ARG_IS("denyall"))
else {
"noobject nosig badsig unknownsig\n");
exit(1);
}
break;
case 'm':
break;
}
}
== ISC_R_SUCCESS);
== ISC_R_SUCCESS);
== ISC_R_SUCCESS);
/*
* Initialize the signature library.
*/
/*
* The secret key is shared on both the client and server side.
*/
== ISC_R_SUCCESS);
if (argc != 2) {
exit (1);
}
if (argc != 3) {
progname);
exit (1);
}
} else {
progname);
exit (1);
}
if (show_final_mem)
return (0);
}