This could be useful in many situations... I've got no objections. david
----- Original Message ----- From: "Jeff Trawick" <[EMAIL PROTECTED]> To: <dev@apr.apache.org> Sent: Thursday, February 20, 2003 6:06 PM Subject: [PATCH] clean up debug patch used with Apache 2 on daedalus > Network apps can all too often be tricked by clients into segfaulting or > worse. When this occurs the first time, it can be important to know > what data was received and with what boundaries (i.e., how much was > passed up at a time to the app). > > For quite a while (>1.5 years I think) www.apache.org has run with a > patch to APR which saves a certain amount of data read from the client. > It is then used for debugging in the case of a segfault. Having > access to the actual data and in what segments it was returned to Apache > helped fix some bugs pretty quickly. > > I've cleaned up that patch a bit in hopes of showing how the > functionality could be added to APR. In this new patch, the saving of > data is turned on by the app via a socket option rather than always > enabled as in the www.apache.org patch. > > Is anybody for/against putting something like this in APR? > > It would be nice to enable the app to change the parameters (how many > buffers to save, how much of each buffer to save). I guess those could > be separate options in the future, with the current constants "20" and > "1024" simply the defaults. > > It would also be nice to allow the app to retrieve the list of saved > input buffers, though it is still useful even without that feature. > ---------------------------------------------------------------------------- ---- > Index: include/apr_network_io.h > =================================================================== > RCS file: /home/cvs/apr/include/apr_network_io.h,v > retrieving revision 1.136 > diff -u -r1.136 apr_network_io.h > --- include/apr_network_io.h 1 Jan 2003 00:01:45 -0000 1.136 > +++ include/apr_network_io.h 20 Feb 2003 17:53:17 -0000 > @@ -133,6 +133,9 @@ > #define APR_IPV6_V6ONLY 16384 /**< Don't accept IPv4 connections on an > * IPv6 listening socket. > */ > +#define APR_SO_SAVE_INPUT 32768 /**< Maintain a copy of data read from the > + * network. > + */ > > /** @} */ > > Index: include/arch/unix/apr_arch_networkio.h > =================================================================== > RCS file: /home/cvs/apr/include/arch/unix/apr_arch_networkio.h,v > retrieving revision 1.1 > diff -u -r1.1 apr_arch_networkio.h > --- include/arch/unix/apr_arch_networkio.h 6 Jan 2003 23:44:26 -0000 1.1 > +++ include/arch/unix/apr_arch_networkio.h 20 Feb 2003 17:53:17 -0000 > @@ -111,6 +111,9 @@ > #if APR_HAVE_SYS_SENDFILE_H > #include <sys/sendfile.h> > #endif > +#ifdef HAVE_STDDEF_H > +#include <stddef.h> > +#endif > /* End System Headers */ > > #ifndef HAVE_POLLIN > @@ -122,6 +125,14 @@ > #define POLLNVAL 32 > #endif > > +typedef struct apr_net_input_buffer_t apr_net_input_buffer_t; > +struct apr_net_input_buffer_t { > + struct apr_net_input_buffer_t *prev; > + apr_int32_t saved_len; > + apr_int32_t actual_len; > + char data[1]; /* actual data starts here */ > +}; > + > struct apr_socket_t { > apr_pool_t *cntxt; > int socketdes; > @@ -138,6 +149,8 @@ > int remote_addr_unknown; > apr_int32_t netmask; > apr_int32_t inherit; > + apr_int32_t num_input_buffers; > + apr_net_input_buffer_t *input_buffers; > }; > > const char *apr_inet_ntop(int af, const void *src, char *dst, apr_size_t size); > Index: network_io/unix/sendrecv.c > =================================================================== > RCS file: /home/cvs/apr/network_io/unix/sendrecv.c,v > retrieving revision 1.95 > diff -u -r1.95 sendrecv.c > --- network_io/unix/sendrecv.c 7 Jan 2003 00:52:56 -0000 1.95 > +++ network_io/unix/sendrecv.c 20 Feb 2003 17:53:17 -0000 > @@ -141,6 +141,21 @@ > sock->netmask |= APR_INCOMPLETE_READ; > } > (*len) = rv; > + if (sock->netmask & APR_SO_SAVE_INPUT) { > + if (sock->num_input_buffers < 20) { > + apr_size_t bytes_to_save = (*len > 1024) ? 1024 : *len; > + apr_net_input_buffer_t *new = > + apr_palloc(sock->cntxt, > + offsetof(struct apr_net_input_buffer_t, > + data) + bytes_to_save); > + > + new->saved_len = bytes_to_save; > + new->actual_len = *len; > + new->prev = sock->input_buffers; > + sock->input_buffers = new; > + ++sock->num_input_buffers; > + } > + } > if (rv == 0) { > return APR_EOF; > } > Index: network_io/unix/sockopt.c > =================================================================== > RCS file: /home/cvs/apr/network_io/unix/sockopt.c,v > retrieving revision 1.66 > diff -u -r1.66 sockopt.c > --- network_io/unix/sockopt.c 7 Feb 2003 20:34:27 -0000 1.66 > +++ network_io/unix/sockopt.c 20 Feb 2003 17:53:17 -0000 > @@ -325,6 +325,9 @@ > return APR_ENOTIMPL; > #endif > break; > + case APR_SO_SAVE_INPUT: > + apr_set_option(&sock->netmask, APR_SO_SAVE_INPUT, on); > + break; > default: > return APR_EINVAL; > } >