protocol.c revision 40f53fa8d9c6a4fc38c0014495e7a42b08f52481
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * Copyright (C) 1996-2000 Internet Software Consortium.
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * Permission to use, copy, modify, and distribute this software for any
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * purpose with or without fee is hereby granted, provided that the above
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * copyright notice and this permission notice appear in all copies.
c46ce2d79b4398a3db7c25b50c7ca3b292f0afa8Evan Hunt * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
28a8f5b0de57d269cf2845c69cb6abe18cbd3b3aMark Andrews * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
c46ce2d79b4398a3db7c25b50c7ca3b292f0afa8Evan Hunt * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
c46ce2d79b4398a3db7c25b50c7ca3b292f0afa8Evan Hunt * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
c46ce2d79b4398a3db7c25b50c7ca3b292f0afa8Evan Hunt * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
c46ce2d79b4398a3db7c25b50c7ca3b292f0afa8Evan Hunt * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
c46ce2d79b4398a3db7c25b50c7ca3b292f0afa8Evan Hunt * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
c46ce2d79b4398a3db7c25b50c7ca3b292f0afa8Evan Hunt * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
c46ce2d79b4398a3db7c25b50c7ca3b292f0afa8Evan Hunt/* $Id: protocol.c,v 1.31 2000/08/01 01:32:58 tale Exp $ */
c46ce2d79b4398a3db7c25b50c7ca3b292f0afa8Evan Hunt * Functions supporting the object management protocol.
c46ce2d79b4398a3db7c25b50c7ca3b292f0afa8Evan Hunt * OMAPI protocol header, version 1.00
c46ce2d79b4398a3db7c25b50c7ca3b292f0afa8Evan Hunt unsigned int authlen; /* Length of authenticator. */
c46ce2d79b4398a3db7c25b50c7ca3b292f0afa8Evan Hunt unsigned int authid; /* Authenticator object ID. */
c46ce2d79b4398a3db7c25b50c7ca3b292f0afa8Evan Hunt omapi_handle_t handle; /* Handle of object being operated on or 0. */
c46ce2d79b4398a3db7c25b50c7ca3b292f0afa8Evan Hunt unsigned int rid; /* ID of transaction responding to. */
c46ce2d79b4398a3db7c25b50c7ca3b292f0afa8Evan Huntomapi_protocol_connect(omapi_object_t *h, const char *server_name,
c46ce2d79b4398a3db7c25b50c7ca3b292f0afa8Evan Hunt result = omapi_object_create((omapi_object_t **)&obj,
c46ce2d79b4398a3db7c25b50c7ca3b292f0afa8Evan Hunt * Drop this function's direct reference to the protocol object
c46ce2d79b4398a3db7c25b50c7ca3b292f0afa8Evan Hunt * so that connect_toserver or send_intro can free the connection
c46ce2d79b4398a3db7c25b50c7ca3b292f0afa8Evan Hunt * and protocol objects in the event of an error.
c46ce2d79b4398a3db7c25b50c7ca3b292f0afa8Evan Hunt result = connect_toserver(h->outer, server_name, port);
c46ce2d79b4398a3db7c25b50c7ca3b292f0afa8Evan Hunt * Send the introductory message. This will also wait (via
c46ce2d79b4398a3db7c25b50c7ca3b292f0afa8Evan Hunt * connection_send) for the server's introductory message before
c46ce2d79b4398a3db7c25b50c7ca3b292f0afa8Evan Hunt * proceeding. While the original design for OMAPI declared that this
c46ce2d79b4398a3db7c25b50c7ca3b292f0afa8Evan Hunt * was to be entirely asynchronous, it just won't work for the client
c46ce2d79b4398a3db7c25b50c7ca3b292f0afa8Evan Hunt * side program to go storming ahead, making calls that try to use the
c46ce2d79b4398a3db7c25b50c7ca3b292f0afa8Evan Hunt * connection object, when it is possible that the thread that reads
c46ce2d79b4398a3db7c25b50c7ca3b292f0afa8Evan Hunt * the socket will wake up with the server's intro message, find some
c46ce2d79b4398a3db7c25b50c7ca3b292f0afa8Evan Hunt * sort of problem, and then blow away the connection object while the
c46ce2d79b4398a3db7c25b50c7ca3b292f0afa8Evan Hunt * client program is asynchronously trying to use it. (This could be
c46ce2d79b4398a3db7c25b50c7ca3b292f0afa8Evan Hunt * done, of course, with a lot more thread locking than currently
c46ce2d79b4398a3db7c25b50c7ca3b292f0afa8Evan Hunt * If send_intro fails, the connection is already destroyed.
c46ce2d79b4398a3db7c25b50c7ca3b292f0afa8Evan Hunt result = send_intro(h->outer, OMAPI_PROTOCOL_VERSION);
c46ce2d79b4398a3db7c25b50c7ca3b292f0afa8Evan Hunt OBJECT_REF(&((omapi_protocol_t *)h->outer)->authinfo,authinfo);
c46ce2d79b4398a3db7c25b50c7ca3b292f0afa8Evan Huntomapi_protocol_disconnect(omapi_object_t *handle, isc_boolean_t force) {
c46ce2d79b4398a3db7c25b50c7ca3b292f0afa8Evan Hunt return; /* Already disconnected. */
f07b2fccaf6be13d9440d323e9e79ee84fe345e2Evan Hunt connection = (omapi_connection_t *)protocol->outer;
c46ce2d79b4398a3db7c25b50c7ca3b292f0afa8Evan Hunt omapi_connection_disconnect((omapi_object_t *)connection, force);
c46ce2d79b4398a3db7c25b50c7ca3b292f0afa8Evan Hunt * Send the protocol introduction message.
c46ce2d79b4398a3db7c25b50c7ca3b292f0afa8Evan Hunt REQUIRE(h != NULL && h->type == omapi_type_protocol);
c46ce2d79b4398a3db7c25b50c7ca3b292f0afa8Evan Hunt REQUIRE(h->outer != NULL && h->outer->type == omapi_type_connection);
c46ce2d79b4398a3db7c25b50c7ca3b292f0afa8Evan Hunt result = omapi_connection_putuint32((omapi_object_t *)connection, ver);
8a2ab2b9203120c3e2a883a5ee8c0b5d60c1808cEvan Hunt omapi_connection_putuint32((omapi_object_t *)connection,
8a2ab2b9203120c3e2a883a5ee8c0b5d60c1808cEvan Hunt * Require the other end to send an intro - this kicks off the
8a2ab2b9203120c3e2a883a5ee8c0b5d60c1808cEvan Hunt * protocol input state machine. This does not use connection_require
8a2ab2b9203120c3e2a883a5ee8c0b5d60c1808cEvan Hunt * to set the number of bytes required because then a socket recv would
8a2ab2b9203120c3e2a883a5ee8c0b5d60c1808cEvan Hunt * be queued. To simplify the MT issues, the library only expects to
8a2ab2b9203120c3e2a883a5ee8c0b5d60c1808cEvan Hunt * have one task outstanding at a time, so the number of bytes
8a2ab2b9203120c3e2a883a5ee8c0b5d60c1808cEvan Hunt * that will be expected is set here, but the actual recv for
8a2ab2b9203120c3e2a883a5ee8c0b5d60c1808cEvan Hunt * them is not queued until after the send event posts.
8a2ab2b9203120c3e2a883a5ee8c0b5d60c1808cEvan Hunt * Make up an initial transaction ID for this connection.
8a2ab2b9203120c3e2a883a5ee8c0b5d60c1808cEvan Hunt * XXXDCL better generator than random()?
8a2ab2b9203120c3e2a883a5ee8c0b5d60c1808cEvan Hunt * The client waited for the result; the server did not.
8a2ab2b9203120c3e2a883a5ee8c0b5d60c1808cEvan Hunt * The server's result will always be ISC_R_SUCCESS.
8a2ab2b9203120c3e2a883a5ee8c0b5d60c1808cEvan Hunt * If the client's result is not ISC_R_SUCCESS, the connection
8a2ab2b9203120c3e2a883a5ee8c0b5d60c1808cEvan Hunt * was already closed by the socket event handler that got
8a2ab2b9203120c3e2a883a5ee8c0b5d60c1808cEvan Hunt * the error.
8a2ab2b9203120c3e2a883a5ee8c0b5d60c1808cEvan Hunt * One of the calls to omapi_connection_put* failed. As of the
8a2ab2b9203120c3e2a883a5ee8c0b5d60c1808cEvan Hunt * time of writing this comment, that would pretty much only
8a2ab2b9203120c3e2a883a5ee8c0b5d60c1808cEvan Hunt * happen if the required output buffer space could be
8a2ab2b9203120c3e2a883a5ee8c0b5d60c1808cEvan Hunt * dynamically allocated.
8a2ab2b9203120c3e2a883a5ee8c0b5d60c1808cEvan Hunt * The server is in listener_accept, so the connection can just
8a2ab2b9203120c3e2a883a5ee8c0b5d60c1808cEvan Hunt * be freed right here; listener_accept will not try to
8a2ab2b9203120c3e2a883a5ee8c0b5d60c1808cEvan Hunt * use it when this function exits.
8a2ab2b9203120c3e2a883a5ee8c0b5d60c1808cEvan Hunt * The client is in omapi_protocol_connect, its driving thread.
8a2ab2b9203120c3e2a883a5ee8c0b5d60c1808cEvan Hunt * It too has no events pending, so the connection will
8a2ab2b9203120c3e2a883a5ee8c0b5d60c1808cEvan Hunt omapi_connection_disconnect(h->outer, OMAPI_FORCE_DISCONNECT);
c46ce2d79b4398a3db7c25b50c7ca3b292f0afa8Evan Hunt * Set up a listener for the omapi protocol.
8a2ab2b9203120c3e2a883a5ee8c0b5d60c1808cEvan Huntomapi_protocol_listen(omapi_object_t *manager, isc_sockaddr_t *addr,
(const char *name,
unsigned int algorithm,
void *key_arg)),
return (result);
(int)waitstatus);
return (result);
return (result);
(int)handle);
return (result);
static isc_result_t
return (OMAPI_R_VERSIONMISMATCH);
return (OMAPI_R_PROTOCOLERROR);
sizeof(omapi_protocolheader_t)));
if (nlen == 0) {
goto need_name_length;
goto message_done;
goto signature_wait;
case omapi_protocol_name_wait:
if (vlen == 0)
goto insert_new_value;
NULL, 0);
goto need_name_length;
return (result);
return (result);
static isc_result_t
omapi_protocol_t *p;
p = (omapi_protocol_t *)h;
return (result);
static isc_result_t
omapi_protocol_t *p;
p = (omapi_protocol_t *)h;
return (ISC_R_NOMEMORY);
if (p->algorithm == 0)
return (DST_R_UNSUPPORTEDALG);
unsigned int sigsize;
p->verify_key_arg))
return (ISC_R_NOPERM);
&p->signature_out,
sigsize);
p->algorithm = 0;
return (result);
static isc_result_t
omapi_protocol_t *p;
p = (omapi_protocol_t *)h;
static isc_result_t
protocol_init(void) {