2
0
mirror of https://gitlab.isc.org/isc-projects/dhcp synced 2025-08-31 06:15:55 +00:00

Add tracing support for OMAPI connects and disconnects.

This commit is contained in:
Ted Lemon
2001-02-15 05:38:52 +00:00
parent c1a3453e6b
commit ef5cc1830b

View File

@@ -45,6 +45,17 @@
#include <arpa/inet.h>
#include <arpa/nameser.h>
#if defined (TRACING)
static void trace_connect_input (trace_type_t *, unsigned, char *);
static void trace_connect_stop (trace_type_t *);
static void trace_disconnect_input (trace_type_t *, unsigned, char *);
static void trace_disconnect_stop (trace_type_t *);
trace_type_t *trace_connect;
trace_type_t *trace_disconnect;
extern omapi_array_t *trace_listeners;
#endif
OMAPI_OBJECT_ALLOC (omapi_connection,
omapi_connection_object_t, omapi_type_connection)
@@ -224,14 +235,27 @@ isc_result_t omapi_connect_list (omapi_object_t *c,
}
#if defined (TRACING)
static omapi_array_t *omapi_connections;
omapi_array_t *omapi_connections;
OMAPI_ARRAY_TYPE(omapi_connection, omapi_connection_object_t);
void omapi_connection_trace_setup (void) {
trace_connect = trace_type_register ("connect", (void *)0,
trace_connect_input,
trace_connect_stop, MDL);
trace_disconnect = trace_type_register ("disconnect", (void *)0,
trace_disconnect_input,
trace_disconnect_stop, MDL);
}
void omapi_connection_register (omapi_connection_object_t *obj,
const char *file, int line)
{
isc_result_t status;
trace_iov_t iov [6];
int iov_count = 0;
int32_t connect_index, listener_index;
static int32_t index;
if (!omapi_connections) {
status = omapi_connection_array_allocate (&omapi_connections,
@@ -240,7 +264,168 @@ void omapi_connection_register (omapi_connection_object_t *obj,
return;
}
status = omapi_connection_array_extend (omapi_connections, obj,
(u_int32_t *)0, file, line);
if (status != ISC_R_SUCCESS) {
obj -> index = -1;
return;
}
if (trace_record ()) {
/* Connection registration packet:
int32_t index
int32_t listener_index [-1 means no listener]
u_int16_t remote_port
u_int16_t local_port
u_int32_t remote_addr
u_int32_t local_addr */
connect_index = htonl (index);
index++;
if (obj -> listener)
listener_index = htonl (obj -> listener -> index);
else
listener_index = htonl (-1);
iov [iov_count].buf = (char *)&connect_index;
iov [iov_count++].len = sizeof connect_index;
iov [iov_count].buf = (char *)&listener_index;
iov [iov_count++].len = sizeof listener_index;
iov [iov_count].buf = (char *)&obj -> remote_addr.sin_port;
iov [iov_count++].len = sizeof obj -> remote_addr.sin_port;
iov [iov_count].buf = (char *)&obj -> local_addr.sin_port;
iov [iov_count++].len = sizeof obj -> local_addr.sin_port;
iov [iov_count].buf = (char *)&obj -> remote_addr.sin_addr;
iov [iov_count++].len = sizeof obj -> remote_addr.sin_addr;
iov [iov_count].buf = (char *)&obj -> local_addr.sin_addr;
iov [iov_count++].len = sizeof obj -> local_addr.sin_addr;
status = trace_write_packet_iov (trace_connect,
iov_count, iov, file, line);
}
}
static void trace_connect_input (trace_type_t *ttype,
unsigned length, char *buf)
{
struct sockaddr_in remote, local;
int32_t connect_index, listener_index;
char *s = buf;
omapi_connection_object_t *obj;
isc_result_t status;
if (length != ((sizeof connect_index) +
(sizeof remote.sin_port) +
(sizeof remote.sin_addr)) * 2) {
log_error ("Trace connect: invalid length %d", length);
return;
}
memset (&remote, 0, sizeof remote);
memset (&local, 0, sizeof local);
memcpy (&connect_index, buf, sizeof connect_index);
s += sizeof connect_index;
memcpy (&listener_index, buf, sizeof listener_index);
s += sizeof listener_index;
memcpy (&remote.sin_port, s, sizeof remote.sin_port);
s += sizeof remote.sin_port;
memcpy (&local.sin_port, s, sizeof local.sin_port);
s += sizeof local.sin_port;
memcpy (&remote.sin_addr, s, sizeof remote.sin_addr);
s += sizeof remote.sin_addr;
memcpy (&local.sin_addr, s, sizeof local.sin_addr);
s += sizeof local.sin_addr;
connect_index = ntohl (connect_index);
listener_index = ntohl (listener_index);
/* If this was a connect to a listener, then we just slap together
a new connection. */
if (listener_index != -1) {
omapi_listener_object_t *listener;
listener = (omapi_listener_object_t *)0;
omapi_array_foreach_begin (trace_listeners,
omapi_listener_object_t, lp) {
if (lp -> address.sin_port == local.sin_port) {
omapi_listener_reference (&listener, lp, MDL);
omapi_listener_dereference (&lp, MDL);
break;
}
} omapi_array_foreach_end (trace_listeners,
omapi_listener_object_t, lp);
if (!listener) {
log_error ("%s%d, addr %s, port %d",
"Spurious traced listener connect - index ",
listener_index, inet_ntoa (local.sin_addr),
ntohs (local.sin_port));
return;
}
obj = (omapi_connection_object_t *)0;
status = omapi_listener_connect (&obj, listener, -1, &remote);
if (status != ISC_R_SUCCESS) {
log_error ("traced listener connect: %s",
isc_result_totext (status));
}
if (obj)
omapi_connection_dereference (&obj, MDL);
omapi_listener_dereference (&listener, MDL);
return;
}
/* Find the matching connect object, if there is one. */
omapi_array_foreach_begin (omapi_connections,
omapi_connection_object_t, lp) {
if (lp -> local_addr.sin_port == local.sin_port &&
(lp -> local_addr.sin_addr.s_addr == htonl (INADDR_ANY) ||
(lp -> local_addr.sin_addr.s_addr ==
local.sin_addr.s_addr))) {
lp -> state = omapi_connection_connected;
lp -> remote_addr = remote;
lp -> remote_addr.sin_family = AF_INET;
omapi_addr_list_dereference (&lp -> connect_list, MDL);
lp -> index = connect_index;
status = omapi_signal_in ((omapi_object_t *)lp,
"connect");
omapi_connection_dereference (&lp, MDL);
return;
}
} omapi_array_foreach_end (omapi_connections,
omapi_connection_object_t, lp);
log_error ("Spurious traced connect - index %d, addr %s, port %d",
connect_index, inet_ntoa (remote.sin_addr),
ntohs (remote.sin_port));
return;
}
static void trace_connect_stop (trace_type_t *ttype) { }
static void trace_disconnect_input (trace_type_t *ttype,
unsigned length, char *buf)
{
int32_t *index;
if (length != sizeof *index) {
log_error ("trace disconnect: wrong length %d", length);
return;
}
index = (int32_t *)buf;
omapi_array_foreach_begin (omapi_connections,
omapi_connection_object_t, lp) {
if (lp -> index == ntohl (*index)) {
omapi_disconnect ((omapi_object_t *)lp, 1);
omapi_connection_dereference (&lp, MDL);
return;
}
} omapi_array_foreach_end (omapi_connections,
omapi_connection_object_t, lp);
log_error ("trace disconnect: no connection matching index %d",
ntohl (*index));
}
static void trace_disconnect_stop (trace_type_t *ttype) { }
#endif
/* Disconnect a connection object from the remote end. If force is nonzero,
@@ -251,6 +436,7 @@ isc_result_t omapi_disconnect (omapi_object_t *h,
int force)
{
omapi_connection_object_t *c;
isc_result_t status;
#ifdef DEBUG_PROTOCOL
log_debug ("omapi_disconnect(%s)", force ? "force" : "");
@@ -260,24 +446,45 @@ isc_result_t omapi_disconnect (omapi_object_t *h,
if (c -> type != omapi_type_connection)
return ISC_R_INVALIDARG;
if (!force) {
/* If we're already disconnecting, we don't have to do
anything. */
if (c -> state == omapi_connection_disconnecting)
return ISC_R_SUCCESS;
#if defined (TRACING)
if (trace_record ()) {
int32_t index;
/* Try to shut down the socket - this sends a FIN to the
remote end, so that it won't send us any more data. If
the shutdown succeeds, and we still have bytes left to
write, defer closing the socket until that's done. */
if (!shutdown (c -> socket, SHUT_RD)) {
if (c -> out_bytes > 0) {
c -> state = omapi_connection_disconnecting;
return ISC_R_SUCCESS;
}
index = htonl (c -> index);
status = trace_write_packet (trace_disconnect,
sizeof index, (char *)&index,
MDL);
if (status != ISC_R_SUCCESS) {
trace_stop ();
log_error ("trace_write_packet: %s",
isc_result_totext (status));
}
}
close (c -> socket);
if (!trace_playback ()) {
#endif
if (!force) {
/* If we're already disconnecting, we don't have to do
anything. */
if (c -> state == omapi_connection_disconnecting)
return ISC_R_SUCCESS;
/* Try to shut down the socket - this sends a FIN to
the remote end, so that it won't send us any more
data. If the shutdown succeeds, and we still
have bytes left to write, defer closing the socket
until that's done. */
if (!shutdown (c -> socket, SHUT_RD)) {
if (c -> out_bytes > 0) {
c -> state =
omapi_connection_disconnecting;
return ISC_R_SUCCESS;
}
}
}
close (c -> socket);
#if defined (TRACING)
}
#endif
c -> state = omapi_connection_closed;
/* Disconnect from I/O object, if any. */