Re: Proposed change to mpm_register_socket_callback(): apr_socket_t -> apr_pollfd_t

2016-03-13 Thread Graham Leggett
On 13 Mar 2016, at 10:55 PM, Eric Covener  wrote:

> I also meant the original feature never made it, so we can whatever we
> want to it.

What do you think of this?

It includes a cleanup to the original pool to remove any unfired pollsets from 
the core.

Index: include/ap_mpm.h
===
--- include/ap_mpm.h(revision 1734657)
+++ include/ap_mpm.h(working copy)
@@ -207,50 +207,48 @@
void *baton);
 
 /**
- * Register a callback on the readability or writability on a group of sockets
- * @param s Null-terminated list of sockets
+ * Register a callback on the readability or writability on a group of
+ * sockets/pipes.
+ * @param pds Null-terminated list of apr_pollfd_t
  * @param p pool for use between registration and callback
- * @param for_read Whether the sockets are monitored for read or writability
  * @param cbfn The callback function
  * @param baton userdata for the callback function
- * @return APR_SUCCESS if all sockets could be added to a pollset, 
+ * @return APR_SUCCESS if all sockets/pipes could be added to a pollset,
  * APR_ENOTIMPL if no asynch support, or an apr_pollset_add error.
- * @remark When activity is found on any 1 socket in the list, all are removed 
+ * @remark When activity is found on any 1 socket/pipe in the list, all are 
removed
  * from the pollset and only 1 callback is issued.
  */
 
-AP_DECLARE(apr_status_t) ap_mpm_register_socket_callback(apr_socket_t **s,
- apr_pool_t *p,
- int for_read, 
- ap_mpm_callback_fn_t 
*cbfn,
- void *baton);
+AP_DECLARE(apr_status_t) ap_mpm_register_poll_callback(apr_pollfd_t **pds,
+   apr_pool_t *p,
+   ap_mpm_callback_fn_t 
*cbfn,
+   void *baton);
  /**
- * Register a callback on the readability or writability on a group of 
sockets, with a timeout
- * @param s Null-terminated list of sockets
+ * Register a callback on the readability or writability on a group of 
sockets/pipes,
+ * with a timeout.
+ * @param pds Null-terminated list of apr_polldf_t
  * @param p pool for use between registration and callback
- * @param for_read Whether the sockets are monitored for read or writability
  * @param cbfn The callback function
  * @param tofn The callback function if the timeout expires
  * @param baton userdata for the callback function
  * @param timeout timeout for I/O in microseconds, unlimited if <= 0
- * @return APR_SUCCESS if all sockets could be added to a pollset, 
+ * @return APR_SUCCESS if all sockets/pipes could be added to a pollset,
  * APR_ENOTIMPL if no asynch support, or an apr_pollset_add error.
- * @remark When activity is found on any 1 socket in the list, all are removed 
+ * @remark When activity is found on any 1 socket/pipe in the list, all are 
removed
  * from the pollset and only 1 callback is issued. 
  * @remark For each call, only one of tofn or cbfn will be called, never both.
  */
 
-AP_DECLARE(apr_status_t) ap_mpm_register_socket_callback_timeout(apr_socket_t 
**s,
+AP_DECLARE(apr_status_t) ap_mpm_register_poll_callback_timeout(apr_pollfd_t 
**pfds,
  apr_pool_t *p,
- int for_read, 
  ap_mpm_callback_fn_t 
*cbfn,
  ap_mpm_callback_fn_t 
*tofn,
  void *baton,
  apr_time_t timeout);
 
 
-AP_DECLARE(apr_status_t) ap_mpm_unregister_socket_callback(apr_socket_t **s, 
-   apr_pool_t *p);
+AP_DECLARE(apr_status_t) ap_mpm_unregister_poll_callback(apr_pollfd_t **pfds,
+ apr_pool_t *p);
 
 typedef enum mpm_child_status {
 MPM_CHILD_STARTED,
Index: include/mpm_common.h
===
--- include/mpm_common.h(revision 1734657)
+++ include/mpm_common.h(working copy)
@@ -426,15 +426,15 @@
  * register the specified callback
  * @ingroup hooks
  */
-AP_DECLARE_HOOK(apr_status_t, mpm_register_socket_callback,
-(apr_socket_t **s, apr_pool_t *p, int for_read, 
ap_mpm_callback_fn_t *cbfn, void *baton))
+AP_DECLARE_HOOK(apr_status_t, mpm_register_poll_callback,
+(apr_pollfd_t **pds, apr_pool_t *p, ap_mpm_callback_fn_t 
*cbfn, void *baton))
 
 /* register the specified callback, with timeout 
  

r1619483

2016-03-13 Thread Christophe JAILLET

Hi,

while looking at potential backport to synch and trunk, I arrived on 
r1619483.


This is a follow up of r1619444 which is a follow up of r1619383.
These 2 have been bakcported (see r1669555)

So I was wondering if r1619483 should also have been backported at the 
same time?


Best regards,
CJ



Re: Proposed change to mpm_register_socket_callback(): apr_socket_t -> apr_pollfd_t

2016-03-13 Thread Eric Covener
On Sun, Mar 13, 2016 at 4:54 PM, Graham Leggett  wrote:
> From what I can see, this was never backported to v2.4.

I also meant the original feature never made it, so we can whatever we
want to it.


Re: Proposed change to mpm_register_socket_callback(): apr_socket_t -> apr_pollfd_t

2016-03-13 Thread Graham Leggett
On 13 Mar 2016, at 10:53 PM, Eric Covener  wrote:

> I don't think I had a good reason for going one way or the other, +1
> here.  Trunk-only and presumably nobody consuming it from the lack of
> feedback.

From what I can see, this was never backported to v2.4.

Regards,
Graham
—



Re: Proposed change to mpm_register_socket_callback(): apr_socket_t -> apr_pollfd_t

2016-03-13 Thread Eric Covener
On Sun, Mar 13, 2016 at 4:29 PM, Graham Leggett  wrote:
> What I have in mind is to swap the apr_socket_t with a apr_pollfd_t, with all 
> operation staying the same.

I don't think I had a good reason for going one way or the other, +1
here.  Trunk-only and presumably nobody consuming it from the lack of
feedback.


-- 
Eric Covener
cove...@gmail.com


Proposed change to mpm_register_socket_callback(): apr_socket_t -> apr_pollfd_t

2016-03-13 Thread Graham Leggett
Hi all,

I would like to propose a change to the mpm_register_socket_callback() hooks to 
add the ability to support both pipes as well as sockets. In addition, I need 
more control over the individual events to support the idea that one 
socket/pipe might want to read at the same time another might want to write.

What I have in mind is to swap the apr_socket_t with a apr_pollfd_t, with all 
operation staying the same.

Index: include/mpm_common.h
===
--- include/mpm_common.h(revision 1734657)
+++ include/mpm_common.h(working copy)
@@ -427,14 +427,14 @@
  * @ingroup hooks
  */
 AP_DECLARE_HOOK(apr_status_t, mpm_register_socket_callback,
-(apr_socket_t **s, apr_pool_t *p, int for_read, 
ap_mpm_callback_fn_t *cbfn, void *baton))
+(apr_pollfd_t **pds, apr_pool_t *p, ap_mpm_callback_fn_t 
*cbfn, void *baton))
 
 /* register the specified callback, with timeout 
  * @ingroup hooks
  *
  */
 AP_DECLARE_HOOK(apr_status_t, mpm_register_socket_callback_timeout,
-(apr_socket_t **s, apr_pool_t *p, int for_read, 
+(apr_pollfd_t **pds, apr_pool_t *p,
  ap_mpm_callback_fn_t *cbfn,  
  ap_mpm_callback_fn_t *tofn, 
  void *baton, 
@@ -444,7 +444,7 @@
  * @ingroup hooks
  */
 AP_DECLARE_HOOK(apr_status_t, mpm_unregister_socket_callback,
-(apr_socket_t **s, apr_pool_t *p))
+(apr_pollfd_t **pds, apr_pool_t *p))
 
 /** Resume the suspended connection 
  * @ingroup hooks

Regards,
Graham
—



Re: [Patch] mod_tcp / mod_proxy_tcp / mod_ssl_tcp

2016-03-13 Thread Daniel Ruggeri
+1
Really nice work

-- 
Daniel Ruggeri

On 3/13/2016 10:45 AM, Jim Jagielski wrote:
> I've given it a quick look-thru and I. Am. Impressed.
>
> This is more Super Cool Mojo!



Re: [Patch] mod_tcp / mod_proxy_tcp / mod_ssl_tcp

2016-03-13 Thread Jim Jagielski
I've given it a quick look-thru and I. Am. Impressed.

This is more Super Cool Mojo!

> On Mar 12, 2016, at 10:46 AM, Graham Leggett  wrote:
> 
> Hi all,
> 
> The following patch provides support for TCP proxying to httpd.
> 
> It consists of the following three parts:
> 
> - mod_tcp: Allows the frontend to receive pure TCP connections
> - mod_proxy_tcp: Allows the proxy to make pure tcp or tls connections to a 
> backend
> - mod_ssl_tcp: Allows the proxy to route incoming connections based on the 
> SNI header (tlsext)
> 
> In the following example config, incoming TCP connections are routed based on 
> their SNI (the tlsext protocol) to given backend servers, which then complete 
> the SSL connections as raw tunnels.
> 
> This allows you to use client certificates through the httpd proxy balancer 
> all the way to the backend server without the proxy terminating any SSL along 
> the way.
> 
> 
>  Protocol tlsext
> 
>  ServerName jira.example.com
> 
>  ProxyPass / tcp://john.example.com:443
> 
> 
> 
>  Protocol tlsext
> 
>  ServerName www.example.com
> 
>  ProxyPass / tcp://erica.example.com:443
> 
> 
> In order for mod_ssl_tcp to work, it needs to read ahead to see if any client 
> hello message is present, and then set aside any extra data so it could be 
> read again. This is fundamentally incompatible with c->data_in_input_filters 
> which only allows the core filter to set aside unread data. For this reason 
> the ability to set aside data was rolled out to all filters.
> 
> mod_ssl_tcp just cares about SNI for now, but could conceivably support APLN 
> too, making a configuration something like this:
> 
> 
>  Protocol tlsext
>  ServerName secure.example.com
>  
>ProxyPass / tcp://imap.example.com:993
>  
>  
>ProxyPass / tcp://pop3.example.com:995
>  
> 
> 
> Regards,
> Graham
> --
> 
> 



Re: [Patch] mod_tcp / mod_proxy_tcp / mod_ssl_tcp

2016-03-13 Thread Graham Leggett
On 12 Mar 2016, at 6:26 PM, Eric Covener  wrote:

> Very cool stuff. Only looked on the surface so far, but one thing it
> reminded me of in the async case is that the MPM knows the "suspended"
> count but we never gave an API to really "unsuspend" when using a
> timed or socket callback.  Longer term we really need to find a way to
> share that raw forwarding code as it's now probably in three modules.

I am slowly working through this, teasing out each problem that prevents async 
behaviour.

A key part of mod_tcp is the “switch ladder”, which allows 
tcp_process_connection() to exit at any time and be called again, at which 
point it will continue where it left off. We need corresponding ladders deeper 
into the core to make each layer down able to continue where it left off if it 
got EAGAIN. We also need to fix some of the function signatures - 
ap_process_request() is void, and so cannot signal to us elegantly that it 
wants to be called again, or whether it is done and we can move on.

Another problem that has become apparent is that the MPMs are too limiting with 
respect to the events the core is willing to wait on. Right now the only event 
the core will handle for us is to wait for the underlying socket to be 
readable/writable. What I have in mind is a more general mechanism, where 
instead of “one socket” we have “a stack of sockets/pipes/files[1]”, and the 
event we wait for is the socket/pipe/file on the top of the stack. This gives 
us AND behaviour. If browser socket is writable AND backend socket is readable 
then [do stuff].

To state it another way, we wait for the browser socket to be writable, this 
triggers the normal pattern of events until we need to block on something else, 
for example we might block waiting for the backend proxy socket to be readable. 
That socket is added to the stack and the MPM now waits for that event. When 
that event triggers the top of the stack is popped off and we’re back to 
waiting on the underlying event (the socket).

I just need to find an elegant way to trigger all of this. It would be really 
nice if we had SOCKET, PIPE, FILE (etc) buckets that pushed themselves onto 
this stack as soon as they returned EAGAIN via some kind of callback.

I need to think this through to work out how to incorporate OR into this. 
Perhaps a list of stacks. This would allow a set of read events to run 
concurrently with write events. Then the sense of the connection has to be 
worked into it too so mod_ssl works non blocking.

[1] files are typically not pollable, but we shouldn't restrict our API. It’s 
pipes we want to block on and in our world that’s apr_file_t.

Regards,
Graham
—