From: Ted Lemon Date: Thu, 15 Feb 2001 05:38:52 +0000 (+0000) Subject: Add tracing support for OMAPI connects and disconnects. X-Git-Tag: V3-BETA-2-PATCH-18~47 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ef5cc1830bd3bea561eea811425fca73d0eb4c63;p=thirdparty%2Fdhcp.git Add tracing support for OMAPI connects and disconnects. --- diff --git a/omapip/connection.c b/omapip/connection.c index f3908eac1..048dd659c 100644 --- a/omapip/connection.c +++ b/omapip/connection.c @@ -45,6 +45,17 @@ #include #include + +#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; - - /* 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; +#if defined (TRACING) + if (trace_record ()) { + int32_t index; + + 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)); + } + } + 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) } - close (c -> socket); +#endif c -> state = omapi_connection_closed; /* Disconnect from I/O object, if any. */