Why not tie this feature as a compile-time option, perhaps work it into
our --maintainer-mode builds.  It doesn't help if APR releases are built
without any debugging information anyways.

Bill

At 12:06 PM 2/20/2003, Jeff Trawick wrote:
>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