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;
>      }
>

Reply via email to