mirror of
https://github.com/isc-projects/bind9.git
synced 2026-02-28 20:41:18 -05:00
388 lines
10 KiB
C
388 lines
10 KiB
C
/*
|
|
* Copyright (C) 1996, 1997, 1998, 1999, 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.
|
|
*/
|
|
|
|
/*****
|
|
***** Private master include file for the OMAPI library.
|
|
*****/
|
|
|
|
#ifndef OMAPI_PRIVATE_H
|
|
#define OMAPI_PRIVATE_H
|
|
|
|
#include <isc/condition.h>
|
|
#include <isc/lang.h>
|
|
#include <isc/mem.h>
|
|
#include <isc/mutex.h>
|
|
#include <isc/net.h>
|
|
#include <isc/socket.h>
|
|
#include <isc/task.h>
|
|
#include <isc/timer.h>
|
|
#include <isc/util.h>
|
|
|
|
#include <omapi/omapi.h>
|
|
#include <omapi/result.h>
|
|
|
|
ISC_LANG_BEGINDECLS
|
|
|
|
#define OMAPI_BUFFER_SIZE 4096
|
|
|
|
/*
|
|
* Types shared among multiple library files.
|
|
*/
|
|
typedef struct omapi_generic omapi_generic_t;
|
|
typedef struct omapi_message omapi_message_t;
|
|
typedef struct omapi_connection omapi_connection_t;
|
|
typedef struct omapi_protocol omapi_protocol_t;
|
|
|
|
typedef enum {
|
|
omapi_connection_unconnected,
|
|
omapi_connection_connecting,
|
|
omapi_connection_connected,
|
|
omapi_connection_disconnecting,
|
|
omapi_connection_closed
|
|
} omapi_connection_state_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;
|
|
|
|
/*
|
|
* OMAPI data types.
|
|
*/
|
|
|
|
struct omapi_data {
|
|
#define OMAPI_DATA_HEADER_LEN (sizeof(int) + sizeof(omapi_datatype_t))
|
|
int refcnt;
|
|
omapi_datatype_t type;
|
|
|
|
union {
|
|
/*
|
|
* OMAPI_DATA_NOBUFFER_LEN purposefully does not
|
|
* include the 'value' byte, which only serves as a
|
|
* handle to memory allocated for (usually) more than
|
|
* one byte that begins at the 'value' location.
|
|
*/
|
|
#define OMAPI_DATA_NOBUFFER_LEN (OMAPI_DATA_HEADER_LEN + sizeof(int))
|
|
struct {
|
|
unsigned int len;
|
|
unsigned char value[1];
|
|
} buffer;
|
|
|
|
#define OMAPI_DATA_OBJECT_LEN \
|
|
(OMAPI_DATA_HEADER_LEN + sizeof(omapi_object_t *))
|
|
omapi_object_t *object;
|
|
|
|
#define OMAPI_DATA_INT_LEN (OMAPI_DATA_HEADER_LEN + sizeof(int))
|
|
int integer;
|
|
} u;
|
|
};
|
|
|
|
struct omapi_string {
|
|
/*
|
|
* OMAPI_STRING_EMPTY_SIZE purposefully does not
|
|
* include the 'value' byte, which only serves as a
|
|
* handle to memory allocated for (usually) more than
|
|
* one byte that begins at the 'value' location.
|
|
*/
|
|
#define OMAPI_STRING_EMPTY_SIZE (2 * sizeof(int))
|
|
int refcnt;
|
|
unsigned int len;
|
|
unsigned char value[1];
|
|
};
|
|
|
|
struct omapi_value {
|
|
int refcnt;
|
|
omapi_string_t * name;
|
|
omapi_data_t * value;
|
|
};
|
|
|
|
struct omapi_generic {
|
|
OMAPI_OBJECT_PREAMBLE;
|
|
omapi_value_t ** values;
|
|
unsigned int nvalues;
|
|
unsigned int va_max;
|
|
};
|
|
|
|
struct omapi_message {
|
|
OMAPI_OBJECT_PREAMBLE;
|
|
omapi_message_t * next;
|
|
omapi_message_t * prev;
|
|
omapi_object_t * object;
|
|
omapi_object_t * notify_object;
|
|
isc_uint32_t authlen;
|
|
omapi_data_t * authenticator;
|
|
isc_uint32_t authid;
|
|
isc_uint32_t op;
|
|
omapi_handle_t h;
|
|
isc_uint32_t id;
|
|
isc_uint32_t rid;
|
|
};
|
|
|
|
struct omapi_connection {
|
|
OMAPI_OBJECT_PREAMBLE;
|
|
/*
|
|
* The wait lock is necessary to ensure that connection_wait is
|
|
* blocking for the signal before any event is received that might
|
|
* potentially free the connection. This ensures that end_connection
|
|
* will unblock connection_wait so that connection_wait can free
|
|
* the connection.
|
|
*
|
|
* Consider, for example, the problem that send_intro has without
|
|
* this lock. It first needs to call connection_require to start
|
|
* a recv task to get the server's intro. Then it needs to send
|
|
* the intro itself. One sample problem that can then arise from
|
|
* this is that the recv task completes before the wait is established
|
|
* and it triggers an error, such as an premature EOF or an unsupported
|
|
* version number in the header. The client would have no way of
|
|
* knowing an error occurred.
|
|
*
|
|
* Fortunately, there is no such problem in the server. Since all
|
|
* uses of the connection object happen from the socket thread,
|
|
* no function will continue to use a connection object after there
|
|
* has been an error on it, no other event can be posted until the
|
|
* current event handler is done, and all events subsequent to
|
|
* abandoning the connection will be ISC_R_CANCELED, so the event
|
|
* handlers will not try to use the connection object.
|
|
*
|
|
* XXXDCL the above comments are somewhat out of date.
|
|
*/
|
|
isc_mutex_t wait_lock;
|
|
isc_socket_t *socket;
|
|
isc_task_t *task;
|
|
/*
|
|
* The error that caused the connection to be freed.
|
|
*/
|
|
isc_result_t result;
|
|
/*
|
|
* Number of socket events outstanding. This should always be
|
|
* either 0 or 1 under the current model; having any more than
|
|
* one event pending at any given time complicates the thread
|
|
* locking issues.
|
|
*/
|
|
unsigned int events_pending;
|
|
/*
|
|
* Blocks connection_wait until the outstanding event completes.
|
|
*/
|
|
isc_condition_t waiter;
|
|
/*
|
|
* True if connection_wait is blocking on the water condition variable.
|
|
*/
|
|
isc_boolean_t waiting;
|
|
omapi_connection_state_t state;
|
|
/*
|
|
* These are set when a connection is made, but not currently used.
|
|
*/
|
|
isc_sockaddr_t remote_addr;
|
|
isc_sockaddr_t local_addr;
|
|
/*
|
|
* Bytes of input needed before wakeup.
|
|
*/
|
|
isc_uint32_t bytes_needed;
|
|
/*
|
|
* Bytes of input already buffered.
|
|
* XXXDCL use isc_bufferlist_available() instead?
|
|
*/
|
|
isc_uint32_t in_bytes;
|
|
isc_bufferlist_t input_buffers;
|
|
/*
|
|
* Bytes of output in output buffers.
|
|
*/
|
|
isc_uint32_t out_bytes;
|
|
isc_bufferlist_t output_buffers;
|
|
/*
|
|
* True if the connection was created by omapi_protocol_connect.
|
|
*/
|
|
isc_boolean_t is_client;
|
|
/*
|
|
* The listener that accepted the connection.
|
|
* XXXDCL (Means is_client is false, making is_client is somewhat
|
|
* redundant.)
|
|
*/
|
|
omapi_object_t * listener;
|
|
/*
|
|
* The server links known connections in a list at the connections
|
|
* member of the omapi_listener_t struct.
|
|
*/
|
|
ISC_LINK(omapi_connection_t) link;
|
|
};
|
|
|
|
struct omapi_protocol {
|
|
OMAPI_OBJECT_PREAMBLE;
|
|
isc_uint32_t header_size;
|
|
isc_uint32_t protocol_version;
|
|
isc_uint32_t next_xid;
|
|
omapi_object_t * authinfo; /* Default authinfo. */
|
|
omapi_protocol_state_t state; /* Input state. */
|
|
isc_boolean_t reading_message_values;
|
|
omapi_message_t * message; /* Incoming message. */
|
|
omapi_string_t * name; /* Incoming name. */
|
|
omapi_data_t * value; /* Incoming value. */
|
|
};
|
|
|
|
/*****
|
|
***** Private Global Library Variables.
|
|
*****/
|
|
extern omapi_objecttype_t *omapi_type_connection;
|
|
extern omapi_objecttype_t *omapi_type_listener;
|
|
extern omapi_objecttype_t *omapi_type_generic;
|
|
extern omapi_objecttype_t *omapi_type_protocol;
|
|
extern omapi_objecttype_t *omapi_type_message;
|
|
extern omapi_objecttype_t *omapi_object_types;
|
|
|
|
/*
|
|
* Everything needs a memory context.
|
|
*/
|
|
extern isc_mem_t *omapi_mctx;
|
|
|
|
/*
|
|
* XXXDCL comment, localize?
|
|
*/
|
|
extern isc_taskmgr_t *omapi_taskmgr;
|
|
|
|
/*
|
|
* XXXDCL comment, localize?
|
|
*/
|
|
extern isc_socketmgr_t *omapi_socketmgr;
|
|
|
|
/*****
|
|
***** Convenience macros.
|
|
*****/
|
|
#define OBJECT_REF(objectp, object) \
|
|
omapi_object_reference((omapi_object_t **)objectp, \
|
|
(omapi_object_t *)object)
|
|
|
|
#define OBJECT_DEREF(objectp) \
|
|
omapi_object_dereference((omapi_object_t **)objectp)
|
|
|
|
#define PASS_CHECK(object, function) \
|
|
(object->inner != NULL && object->inner->type->function != NULL)
|
|
|
|
/*
|
|
* Private library functions defined in connection.c.
|
|
*/
|
|
isc_result_t
|
|
connection_init(void);
|
|
|
|
isc_result_t
|
|
connect_toserver(omapi_object_t *connection, const char *server, int port);
|
|
|
|
isc_result_t
|
|
connection_send(omapi_connection_t *connection);
|
|
|
|
isc_result_t
|
|
connection_require(omapi_connection_t *connection, unsigned int bytes);
|
|
|
|
void
|
|
connection_copyout(unsigned char *data, omapi_connection_t *connection,
|
|
unsigned int length);
|
|
|
|
void
|
|
connection_getuint32(omapi_connection_t *c, isc_uint32_t *value);
|
|
|
|
void
|
|
connection_getuint16(omapi_connection_t *c, isc_uint16_t *value);
|
|
|
|
/*
|
|
* Private library functions defined in generic.c.
|
|
*/
|
|
isc_result_t
|
|
generic_init(void);
|
|
|
|
/*
|
|
* Private functions defined in handle.c.
|
|
*/
|
|
isc_result_t
|
|
object_gethandle(omapi_handle_t *handle, omapi_object_t *object);
|
|
|
|
isc_result_t
|
|
handle_lookup(omapi_object_t **object, omapi_handle_t handle);
|
|
|
|
void
|
|
handle_destroy(void);
|
|
|
|
/*
|
|
* Private library functions defined in listener.c.
|
|
*/
|
|
isc_result_t
|
|
listener_init(void);
|
|
|
|
/*
|
|
* Private library functions defined in message.c.
|
|
*/
|
|
isc_result_t
|
|
message_init(void);
|
|
|
|
isc_result_t
|
|
message_process(omapi_object_t *message, omapi_object_t *protocol);
|
|
|
|
/*
|
|
* Private library functions defined in object.c.
|
|
*/
|
|
isc_result_t
|
|
object_signal(omapi_object_t *handle, const char *name, ...);
|
|
|
|
isc_result_t
|
|
object_vsignal(omapi_object_t *handle, const char *name, va_list ap);
|
|
|
|
isc_result_t
|
|
object_stuffvalues(omapi_object_t *handle, omapi_object_t *object);
|
|
|
|
isc_result_t
|
|
object_update(omapi_object_t *object, omapi_object_t *source,
|
|
omapi_handle_t handle);
|
|
|
|
omapi_objecttype_t *
|
|
object_findtype(omapi_value_t *tv);
|
|
|
|
isc_result_t
|
|
object_methodlookup(omapi_objecttype_t *type, omapi_object_t **object,
|
|
omapi_object_t *key);
|
|
|
|
isc_result_t
|
|
object_methodcreate(omapi_objecttype_t *type, omapi_object_t **object);
|
|
|
|
isc_result_t
|
|
object_methodremove(omapi_objecttype_t *type, omapi_object_t *object);
|
|
|
|
void
|
|
object_destroytypes(void);
|
|
|
|
/*
|
|
* Private library functions defined in protocol.c.
|
|
*/
|
|
isc_result_t
|
|
protocol_init(void);
|
|
|
|
isc_result_t
|
|
send_intro(omapi_object_t *object, unsigned int version);
|
|
|
|
isc_result_t
|
|
send_status(omapi_object_t *protcol, isc_result_t waitstatus,
|
|
unsigned int response_id, const char *message);
|
|
|
|
isc_result_t
|
|
send_update(omapi_object_t *protocol, unsigned int response_id,
|
|
omapi_object_t *object);
|
|
|
|
ISC_LANG_ENDDECLS
|
|
|
|
#endif /* OMAPIP_PRIVATE_H */
|