2
0
mirror of https://gitlab.isc.org/isc-projects/dhcp synced 2025-08-30 05:47:45 +00:00

Add some support for tracing connections.

This commit is contained in:
Ted Lemon 2001-02-12 20:49:54 +00:00
parent c790b906de
commit 3ce5a42015
3 changed files with 326 additions and 164 deletions

View File

@ -3,7 +3,7 @@
Subroutines for dealing with connections. */ Subroutines for dealing with connections. */
/* /*
* Copyright (c) 1999-2000 Internet Software Consortium. * Copyright (c) 1999-2001 Internet Software Consortium.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -108,6 +108,10 @@ isc_result_t omapi_connect_list (omapi_object_t *c,
omapi_connection_object_t *obj; omapi_connection_object_t *obj;
int flag; int flag;
struct sockaddr_in local_sin; struct sockaddr_in local_sin;
#if defined (TRACING)
trace_addr_t *addrs;
u_int16_t naddrs;
#endif
obj = (omapi_connection_object_t *)0; obj = (omapi_connection_object_t *)0;
status = omapi_connection_allocate (&obj, MDL); status = omapi_connection_allocate (&obj, MDL);
@ -126,12 +130,23 @@ isc_result_t omapi_connect_list (omapi_object_t *c,
return status; return status;
} }
/* Store the address list on the object. */
omapi_addr_list_reference (&obj -> connect_list, remote_addrs, MDL);
obj -> cptr = 0;
obj -> state = omapi_connection_unconnected;
#if defined (TRACING)
/* If we're playing back, don't actually try to connect - just leave
the object available for a subsequent connect or disconnect. */
if (!trace_playback ()) {
#endif
/* Create a socket on which to communicate. */ /* Create a socket on which to communicate. */
obj -> socket = obj -> socket =
socket (PF_INET, SOCK_STREAM, IPPROTO_TCP); socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (obj -> socket < 0) { if (obj -> socket < 0) {
omapi_connection_dereference (&obj, MDL); omapi_connection_dereference (&obj, MDL);
if (errno == EMFILE || errno == ENFILE || errno == ENOBUFS) if (errno == EMFILE || errno == ENFILE
|| errno == ENOBUFS)
return ISC_R_NORESOURCES; return ISC_R_NORESOURCES;
return ISC_R_UNEXPECTED; return ISC_R_UNEXPECTED;
} }
@ -151,12 +166,13 @@ isc_result_t omapi_connect_list (omapi_object_t *c,
local_sin.sin_len = sizeof local_addr; local_sin.sin_len = sizeof local_addr;
#endif #endif
local_sin.sin_family = AF_INET; local_sin.sin_family = AF_INET;
memset (&local_sin.sin_zero, 0, sizeof local_sin.sin_zero); memset (&local_sin.sin_zero, 0,
sizeof local_sin.sin_zero);
if (bind (obj -> socket, (struct sockaddr *)&local_sin, if (bind (obj -> socket, (struct sockaddr *)&local_sin,
sizeof local_sin) < 0) { sizeof local_sin) < 0) {
omapi_object_dereference ((omapi_object_t **)&obj, omapi_object_dereference ((omapi_object_t **)
MDL); &obj, MDL);
if (errno == EADDRINUSE) if (errno == EADDRINUSE)
return ISC_R_ADDRINUSE; return ISC_R_ADDRINUSE;
if (errno == EADDRNOTAVAIL) if (errno == EADDRNOTAVAIL)
@ -189,10 +205,6 @@ isc_result_t omapi_connect_list (omapi_object_t *c,
return ISC_R_UNEXPECTED; return ISC_R_UNEXPECTED;
} }
/* Store the address list on the object. */
omapi_addr_list_reference (&obj -> connect_list, remote_addrs, MDL);
obj -> cptr = 0;
status = (omapi_register_io_object status = (omapi_register_io_object
((omapi_object_t *)obj, ((omapi_object_t *)obj,
0, omapi_connection_writefd, 0, omapi_connection_writefd,
@ -200,13 +212,37 @@ isc_result_t omapi_connect_list (omapi_object_t *c,
omapi_connection_reaper)); omapi_connection_reaper));
if (status != ISC_R_SUCCESS) if (status != ISC_R_SUCCESS)
goto out; goto out;
obj -> state = omapi_connection_unconnected;
status = omapi_connection_connect ((omapi_object_t *)obj); status = omapi_connection_connect ((omapi_object_t *)obj);
#if defined (TRACING)
}
omapi_connection_register (obj, MDL);
#endif
out: out:
omapi_connection_dereference (&obj, MDL); omapi_connection_dereference (&obj, MDL);
return status; return status;
} }
#if defined (TRACING)
static omapi_array_t *omapi_connections;
OMAPI_ARRAY_TYPE(omapi_connection, omapi_connection_object_t);
void omapi_connection_register (omapi_connection_object_t *obj,
const char *file, int line)
{
isc_result_t status;
if (!omapi_connections) {
status = omapi_connection_array_allocate (&omapi_connections,
file, line);
if (status != ISC_R_SUCCESS)
return;
}
}
#endif
/* Disconnect a connection object from the remote end. If force is nonzero, /* Disconnect a connection object from the remote end. If force is nonzero,
close the connection immediately. Otherwise, shut down the receiving end close the connection immediately. Otherwise, shut down the receiving end
but allow any unsent data to be sent before actually closing the socket. */ but allow any unsent data to be sent before actually closing the socket. */
@ -374,7 +410,6 @@ isc_result_t omapi_connection_connect (omapi_object_t *h)
} }
return status; return status;
} }
printf("EINPROGRESS\n");
c -> state = omapi_connection_connecting; c -> state = omapi_connection_connecting;
return ISC_R_INCOMPLETE; return ISC_R_INCOMPLETE;
} }

View File

@ -3,7 +3,7 @@
Subroutines that support the generic listener object. */ Subroutines that support the generic listener object. */
/* /*
* Copyright (c) 1999-2000 Internet Software Consortium. * Copyright (c) 1999-2001 Internet Software Consortium.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -43,6 +43,15 @@
#include <omapip/omapip_p.h> #include <omapip/omapip_p.h>
#if defined (TRACING)
static omapi_array_t *trace_listeners;
static void trace_listener_accept_input (trace_type_t *, unsigned, char *);
static void trace_listener_remember (omapi_listener_object_t *,
const char *, int);
static void trace_listener_accept_stop (trace_type_t *);
trace_type_t *trace_listener_accept;
#endif
OMAPI_OBJECT_ALLOC (omapi_listener, OMAPI_OBJECT_ALLOC (omapi_listener,
omapi_listener_object_t, omapi_type_listener) omapi_listener_object_t, omapi_type_listener)
@ -110,11 +119,19 @@ isc_result_t omapi_listen_addr (omapi_object_t *h,
memset (&(obj -> address.sin_zero), 0, memset (&(obj -> address.sin_zero), 0,
sizeof obj -> address.sin_zero); sizeof obj -> address.sin_zero);
#if defined (TRACING)
/* If we're playing back a trace file, we remember the object
on the trace listener queue. */
if (trace_playback ()) {
trace_listener_remember (obj, MDL);
} else {
#endif
/* Create a socket on which to listen. */ /* Create a socket on which to listen. */
obj -> socket = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP); obj -> socket = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (!obj -> socket) { if (!obj -> socket) {
omapi_listener_dereference (&obj, MDL); omapi_listener_dereference (&obj, MDL);
if (errno == EMFILE || errno == ENFILE || errno == ENOBUFS) if (errno == EMFILE
|| errno == ENFILE || errno == ENOBUFS)
return ISC_R_NORESOURCES; return ISC_R_NORESOURCES;
return ISC_R_UNEXPECTED; return ISC_R_UNEXPECTED;
} }
@ -137,11 +154,11 @@ isc_result_t omapi_listen_addr (omapi_object_t *h,
return ISC_R_UNEXPECTED; return ISC_R_UNEXPECTED;
} }
/* Try to bind to the wildcard address using the port number /* Try to bind to the wildcard address using the port number
we were given. */ we were given. */
i = bind (obj -> socket, i = bind (obj -> socket,
(struct sockaddr *)&obj -> address, sizeof obj -> address); (struct sockaddr *)&obj -> address,
sizeof obj -> address);
if (i < 0) { if (i < 0) {
omapi_listener_dereference (&obj, MDL); omapi_listener_dereference (&obj, MDL);
if (errno == EADDRINUSE) if (errno == EADDRINUSE)
@ -165,6 +182,9 @@ isc_result_t omapi_listen_addr (omapi_object_t *h,
status = omapi_register_io_object ((omapi_object_t *)obj, status = omapi_register_io_object ((omapi_object_t *)obj,
omapi_listener_readfd, 0, omapi_listener_readfd, 0,
omapi_accept, 0, 0); omapi_accept, 0, 0);
#if defined (TRACING)
}
#endif
omapi_listener_dereference (&obj, MDL); omapi_listener_dereference (&obj, MDL);
return status; return status;
} }
@ -189,51 +209,46 @@ isc_result_t omapi_accept (omapi_object_t *h)
SOCKLEN_T len; SOCKLEN_T len;
omapi_connection_object_t *obj; omapi_connection_object_t *obj;
omapi_listener_object_t *listener; omapi_listener_object_t *listener;
omapi_addr_t addr; omapi_addr_t remote_addr;
int i; int i;
struct sockaddr_in addr;
int socket;
if (h -> type != omapi_type_listener) if (h -> type != omapi_type_listener)
return ISC_R_INVALIDARG; return ISC_R_INVALIDARG;
listener = (omapi_listener_object_t *)h; listener = (omapi_listener_object_t *)h;
#ifdef DEBUG_PROTOCOL
log_debug ("omapi_accept()");
#endif
/* Get the handle. */
obj = (omapi_connection_object_t *)0;
status = omapi_connection_allocate (&obj, MDL);
if (status != ISC_R_SUCCESS)
return status;
/* Accept the connection. */ /* Accept the connection. */
len = sizeof obj -> remote_addr; len = sizeof addr;
obj -> socket = socket = accept (listener -> socket,
accept (listener -> socket, ((struct sockaddr *)&(addr)), &len);
((struct sockaddr *) if (socket < 0) {
&(obj -> remote_addr)), &len);
if (obj -> socket < 0) {
omapi_connection_dereference (&obj, MDL);
if (errno == EMFILE || errno == ENFILE || errno == ENOBUFS) if (errno == EMFILE || errno == ENFILE || errno == ENOBUFS)
return ISC_R_NORESOURCES; return ISC_R_NORESOURCES;
return ISC_R_UNEXPECTED; return ISC_R_UNEXPECTED;
} }
obj -> state = omapi_connection_connected; #if defined (TRACING)
/* If we're recording a trace, remember the connection. */
/* Verify that this host is allowed to connect. */ if (trace_record ()) {
if (listener -> verify_addr) { trace_iov_t iov [3];
addr.addrtype = AF_INET; u_int32_t lsock;
addr.addrlen = sizeof (obj -> remote_addr.sin_addr); iov [0].buf = (char *)&addr.sin_port;
memcpy (addr.address, &obj -> remote_addr.sin_addr, iov [0].len = sizeof addr.sin_port;
sizeof (obj -> remote_addr.sin_addr)); iov [1].buf = (char *)&addr.sin_addr;
addr.port = ntohs(obj -> remote_addr.sin_port); iov [1].len = sizeof addr.sin_addr;
iov [2].buf = (char *)&listener -> address.sin_port;
status = (listener -> verify_addr) (h, &addr); iov [2].len = sizeof listener -> address.sin_port;
if (status != ISC_R_SUCCESS) { trace_write_packet_iov (trace_listener_accept,
omapi_disconnect ((omapi_object_t *)obj, 1); 3, iov, MDL);
return status;
} }
#endif
obj = (omapi_connection_object_t *)0;
status = omapi_listener_connect (&obj, listener, socket, &addr);
if (status != ISC_R_SUCCESS) {
close (socket);
return status;
} }
status = omapi_register_io_object ((omapi_object_t *)obj, status = omapi_register_io_object ((omapi_object_t *)obj,
@ -242,21 +257,129 @@ isc_result_t omapi_accept (omapi_object_t *h)
omapi_connection_reader, omapi_connection_reader,
omapi_connection_writer, omapi_connection_writer,
omapi_connection_reaper); omapi_connection_reaper);
if (status != ISC_R_SUCCESS) {
omapi_connection_dereference (&obj, MDL);
return status;
}
omapi_listener_reference (&obj -> listener, listener, MDL);
status = omapi_signal (h, "connect", obj);
/* Lose our reference to the connection, so it'll be gc'd when it's /* Lose our reference to the connection, so it'll be gc'd when it's
reaped. */ reaped. */
omapi_connection_dereference (&obj, MDL); omapi_connection_dereference (&obj, MDL);
if (status != ISC_R_SUCCESS)
omapi_disconnect ((omapi_object_t *)(obj), 1);
return status; return status;
} }
isc_result_t omapi_listener_connect (omapi_connection_object_t **obj,
omapi_listener_object_t *listener,
int socket,
struct sockaddr_in *remote_addr)
{
isc_result_t status;
omapi_object_t *h = (omapi_object_t *)listener;
omapi_addr_t addr;
#ifdef DEBUG_PROTOCOL
log_debug ("omapi_accept()");
#endif
/* Get the handle. */
status = omapi_connection_allocate (obj, MDL);
if (status != ISC_R_SUCCESS)
return status;
(*obj) -> state = omapi_connection_connected;
(*obj) -> remote_addr = *remote_addr;
(*obj) -> socket = socket;
/* Verify that this host is allowed to connect. */
if (listener -> verify_addr) {
addr.addrtype = AF_INET;
addr.addrlen = sizeof (remote_addr -> sin_addr);
memcpy (addr.address, &remote_addr -> sin_addr,
sizeof (remote_addr -> sin_addr));
addr.port = ntohs(remote_addr -> sin_port);
status = (listener -> verify_addr) (h, &addr);
if (status != ISC_R_SUCCESS) {
omapi_disconnect ((omapi_object_t *)(*obj), 1);
omapi_connection_dereference (obj, MDL);
return status;
}
}
omapi_listener_reference (&(*obj) -> listener, listener, MDL);
#if defined (TRACING)
omapi_connection_register (*obj, MDL);
#endif
status = omapi_signal (h, "connect", (*obj));
return status;
}
#if defined (TRACING)
OMAPI_ARRAY_TYPE(omapi_listener, omapi_listener_object_t);
void omapi_listener_trace_setup (void) {
trace_listener_accept =
trace_type_register ("listener_accept", (void *)0,
trace_listener_accept_input,
trace_listener_accept_stop, MDL);
}
static void trace_listener_remember (omapi_listener_object_t *obj,
const char *file, int line)
{
isc_result_t status;
if (!trace_listeners) {
status = omapi_listener_array_allocate (&trace_listeners,
file, line);
if (status != ISC_R_SUCCESS) {
foo:
log_error ("trace_listener_remember: %s",
isc_result_totext (status));
return;
}
}
status = omapi_listener_array_extend (trace_listeners,
obj, (int *)0, MDL);
if (status != ISC_R_SUCCESS)
goto foo;
}
static void trace_listener_accept_input (trace_type_t *ttype,
unsigned length, char *buf)
{
struct in_addr *addr;
u_int16_t *remote_port;
u_int16_t *local_port;
omapi_connection_object_t *obj;
isc_result_t status;
struct sockaddr_in remote_addr;
addr = (struct in_addr *)buf;
remote_port = (u_int16_t *)(addr + 1);
local_port = remote_port + 1;
memset (&remote_addr, 0, sizeof remote_addr);
remote_addr.sin_addr = *addr;
remote_addr.sin_port = *remote_port;
omapi_array_foreach_begin (trace_listeners,
omapi_listener_object_t, lp) {
if (lp -> address.sin_port == *local_port) {
obj = (omapi_connection_object_t *)0;
status = omapi_listener_connect (&obj,
lp, 0, &remote_addr);
return;
}
} omapi_array_foreach_end (trace_listeners,
omapi_listener_object_t, lp);
log_error ("trace_listener_accept: %s from %s/%d to port %d",
"unexpected connect",
inet_ntoa (*addr), *remote_port, *local_port);
}
static void trace_listener_accept_stop (trace_type_t *ttype) { }
#endif
isc_result_t omapi_listener_configure_security (omapi_object_t *h, isc_result_t omapi_listener_configure_security (omapi_object_t *h,
isc_result_t (*verify_addr) isc_result_t (*verify_addr)
(omapi_object_t *, (omapi_object_t *,

View File

@ -3,7 +3,7 @@
Subroutines providing general support for objects. */ Subroutines providing general support for objects. */
/* /*
* Copyright (c) 1999-2000 Internet Software Consortium. * Copyright (c) 1999-2001 Internet Software Consortium.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -180,6 +180,10 @@ isc_result_t omapi_init (void)
if (status != ISC_R_SUCCESS) if (status != ISC_R_SUCCESS)
return status; return status;
#if defined (TRACING)
omapi_listener_trace_setup ();
#endif
/* This seems silly, but leave it. */ /* This seems silly, but leave it. */
return ISC_R_SUCCESS; return ISC_R_SUCCESS;
} }