Re: [PATCH] Add "FreeListen" to support IP_FREEBIND

2016-03-08 Thread Jacob Champion
On 03/08/2016 10:47 AM, Tim Bannister wrote:
>> On 8 Mar 2016, at 18:13, William A Rowe Jr  wrote:
>> If a websocket implementation is properly stacked on top of the
>> core, there is no need for special-casing this interaction.  It
>> will be able to speak over http or https, or conceivably even over
>> a single h2, or h2c stream, and will support httpready or freebind
>> mechanics.
> 
> I chose WebSocket precisely because it's a pain and will illustrate
> awkward cases. WebSocket over HTTP/2 sounds like a red herring, as
> normal WebSocket runs over a stream transport (TCP). In RFC 6455 it's
> an upgrade, and once that upgrade has happened then HTTP is not part
> of the stack any more. WebSocket Secure runs over TLS but, again,
> discards HTTP after the upgrade.

Right. WebSocket is WebSocket, and isn't communicating "over" or
"inside" another stream. There is only one way to create a WebSocket
connection, and that's by upgrading from an HTTP/1.1 request. AFAIK,
HTTP/2 + WebSocket does not exist, nor does ALPN of a "pure" WebSocket
stream.

--Jacob


configuring alternate algorithms for CGI variables (yet again?)

2016-03-08 Thread Jeff Trawick
Synopsis:

CGIVariable variable keyword-applicable-to-variable

e.g.,

CGIVariable REQUEST_URI from-active-request|from-request-line

(Please oh please think of a better directive name :) )

from-active-request:  REQUEST_URI will be set from the active request
(possibly a subrequest).
from-request-line (default):  REQUEST_URI will be set from the original
request line received from the client.

This kind of setting would be part of core's request_config, and would be
consulted as appropriate by different code bundled with httpd
(ap_add_cgi_vars(), mod_proxy_FOO, etc.) or even third-party modules
(mod_xSGI), like the CGIPassAuth directive.

The problem at hand: Make REQUEST_URI in a script invoked via SSI represent
the script invocation, not the original request.  It worked this way in
very early 2.0.x for a while, until https://archive.apache.org/gnats/7580
which restored the 1.3 behavior.  The current value in httpd is a pain for
a particular customer app that can be used with httpd 2.4 or with a
different web server.  (FWIW, ssl_var_lookup("REQUEST_URI") uses r->uri; I
didn't even know it cared.)

Generally: An more obvious variable that could use such configuration is
PATH_INFO; this is implemented (inconsistently) in multiple proxy backends,
and configured using an "envvar" that isn't effective if you do the obvious
thing, SetEnv.  While PATH_INFO is out of scope for me for the moment, I'd
like to control how REQUEST_URI is set in a manner that is extensible to
other CGI variables in the future.

Thoughts?

-- 
Born in Roswell... married an alien...
http://emptyhammock.com/


Re: [PATCH] Add "FreeListen" to support IP_FREEBIND

2016-03-08 Thread Tim Bannister

> On 8 Mar 2016, at 18:13, William A Rowe Jr  wrote:
>> 
>> On Tue, Mar 8, 2016 at 11:38 AM, Tim Bannister  
>> wrote:
>> On 8 Mar 2016, at 10:43, Jan Kaluža  wrote:
>> > On 03/08/2016 10:25 AM, Yann Ylavic wrote:
>> >> On Tue, Mar 8, 2016 at 9:46 AM, Yann Ylavic  wrote:
>> >>> On Tue, Mar 8, 2016 at 9:28 AM, Jan Kaluža  wrote:
>> 
>>  I have chosen FreeListen over the flags
>> >>>
>> >>> FWIW, should be take the YAD path, I'd prefer ListenFree (over
>> >>> FreeListen) to emphasize on the "Listen directive family" with a
>> >>> prefix...
>> >>
>> >> Thinking more about this, I think I second Jim on the wish to have a
>> >> single Listen directive with some parameter like
>> >> "options=freebind,backlog:4095,reuseport,...".
>> >
>> > Thinking about right syntax for options...
>> >
>> > I would personally like something like "Listen [IP-address:]portnumber 
>> > [protocol] [option1] [option2] ...". Do we have list of supported 
>> > protocols by Listen directive, or we support whatever protocol is there?
>> >
>> > If we have explicit list of protocols, then the protocols itself could 
>> > become an options.
>> >
>> > If not, can it be acceptable, that you always have to define protocol when 
>> > you wan to use options?
>> 
>> That sounds fine too.
>> 
>> One proviso comes with the idea of a single socket that can serve several 
>> protocols. Think of WebSocket, because it is awkward: from an HTTP 
>> point-of-view, the protocol is initially HTTP and then upgrades to 
>> WebSocket; however, from a WebSocket point of view, the protocol is 
>> WebSocket throughout with a preamble that also happens to resemble HTTP/1.1.
>> 
>> Using the first model, only one protocol need be specified (but it's not 
>> clear which upgrades are valid for this socket). Using the second model, the 
>> Listen directive needs a way for the admin to specify multiple protocols. 
>> Maybe the answer is for that to be set in the Protocols directive only?

Either mental model might be valid, and I wouldn't presume to say which we 
should be using. Maybe it's not even feasible to have a single abstraction for 
how httpd works (because things like HTTP/2, TLS, WebSocket confuse matters by 
each using their own interpretation).

…

> Keep in mind this becomes a nightmare entanglement between optional, loadable 
> support modules and the server core.  The existing implementation
> of listen was flexible enough to provide new arbitrary protocols and resolve 
> these at runtime.  There is no reason to distinguish http/1.1, as we would 
> have already done so (e.g. http/1.0, http/0.9 etc).  It isn't necessary.

I agree, but: Protocols vs. Protocol is already awkward to document and use. I 
hope we don't accidentally make anything worse.


> If a websocket implementation is properly stacked on top of the core, there 
> is no need for special-casing this interaction.  It will be able to speak 
> over http or https, or conceivably even over a single h2, or h2c stream, and 
> will support httpready or freebind mechanics.

I chose WebSocket precisely because it's a pain and will illustrate awkward 
cases. WebSocket over HTTP/2 sounds like a red herring, as normal WebSocket 
runs over a stream transport (TCP). In RFC 6455 it's an upgrade, and once that 
upgrade has happened then HTTP is not part of the stack any more. WebSocket 
Secure runs over TLS but, again, discards HTTP after the upgrade.

> Re-implementing the handshake entirely in a WebSocket module seems like 
> overkill, much like re-implementing the h2c handshake would be.

No worries there – sounds like you're more in favour of the first of the two 
models then? In that case the Listen directive simplifies to one of:
Listen [2001:db8::a00:20ff:fea7:ccea]:1234 http options=freebind

or:
Listen [2001:db8::a00:20ff:fea7:ccea]:1234 options=protocol:http,freebind


I'm mindful that there is already an overlap between Listen, Protocol, and 
Protocols. Making the Listen directive more complex makes sense to me; the 
added complexity makes it more important to try get it right.



My aim here is that we agree on a new definition of Listen that's 
implementable, understandable, and has a way to specify use of IP_FREEBIND. 
It's nice to have it extensible but that is not as strong a consideration as 
the other details. Which choice do people like best?


-- 
Tim Bannister – is...@c8h10n4o2.org.uk

Re: [PATCH] Add "FreeListen" to support IP_FREEBIND

2016-03-08 Thread William A Rowe Jr
On Tue, Mar 8, 2016 at 11:38 AM, Tim Bannister 
wrote:

> On 8 Mar 2016, at 10:43, Jan Kaluža  wrote:
> > On 03/08/2016 10:25 AM, Yann Ylavic wrote:
> >> On Tue, Mar 8, 2016 at 9:46 AM, Yann Ylavic 
> wrote:
> >>> On Tue, Mar 8, 2016 at 9:28 AM, Jan Kaluža  wrote:
> 
>  I have chosen FreeListen over the flags
> >>>
> >>> FWIW, should be take the YAD path, I'd prefer ListenFree (over
> >>> FreeListen) to emphasize on the "Listen directive family" with a
> >>> prefix...
> >>
> >> Thinking more about this, I think I second Jim on the wish to have a
> >> single Listen directive with some parameter like
> >> "options=freebind,backlog:4095,reuseport,...".
> >
> > Thinking about right syntax for options...
> >
> > I would personally like something like "Listen [IP-address:]portnumber
> [protocol] [option1] [option2] ...". Do we have list of supported protocols
> by Listen directive, or we support whatever protocol is there?
> >
> > If we have explicit list of protocols, then the protocols itself could
> become an options.
> >
> > If not, can it be acceptable, that you always have to define protocol
> when you wan to use options?
>
> That sounds fine too.
>
> One proviso comes with the idea of a single socket that can serve several
> protocols. Think of WebSocket, because it is awkward: from an HTTP
> point-of-view, the protocol is initially HTTP and then upgrades to
> WebSocket; however, from a WebSocket point of view, the protocol is
> WebSocket throughout with a preamble that also happens to resemble HTTP/1.1.
>
> Using the first model, only one protocol need be specified (but it's not
> clear which upgrades are valid for this socket). Using the second model,
> the Listen directive needs a way for the admin to specify multiple
> protocols. Maybe the answer is for that to be set in the Protocols
> directive only?
>

Keep in mind, the protocol at this layer is simply the 'first responder' to
react
to an incoming connection, which in your case is the http (or h2?) protocol.
The truly critical aspect is what the kernel may do to defer the accept,
whether
that is looking for a complete http request (or h2c request, someday), or
the
server must instigate the first response (no incoming bytes from the client)
in the case of ftp and similar, or whether this may be an ssl handshake.

In the case of WebSocket, that module should be reacting to the headers,
the initial protocol state is still HTTP/1.1 from httpd's perspective.


> What should the Listen directive look like, ideally, for a
> freebind-enabled socket that can be either HTTP or WebSocket, and needs to
> specify options? Like this perhaps:
>
> Listen [2001:db8::a00:20ff:fea7:ccea]:1234 http/1.1,websocket
> options=freebind


Keep in mind this becomes a nightmare entanglement between optional,
loadable support modules and the server core.  The existing implementation
of listen was flexible enough to provide new arbitrary protocols and resolve
these at runtime.  There is no reason to distinguish http/1.1, as we would
have already done so (e.g. http/1.0, http/0.9 etc).  It isn't necessary.

If a websocket implementation is properly stacked on top of the core, there
is no need for special-casing this interaction.  It will be able to speak
over
http or https, or conceivably even over a single h2, or h2c stream, and will
support httpready or freebind mechanics.

Re-implementing the handshake entirely in a WebSocket module seems
like overkill, much like re-implementing the h2c handshake would be.


Re: mod_proxy_wstunnel incomplete handshake

2016-03-08 Thread Yann Ylavic
Actually I was working on these lands lately to implement some Upgrade
forwarding.

I ended up with the attached patch (still incomplete, but working)
which moves some mod_proxy_wstunnel parts (TCP-forwarding) to
proxy_util and finally uses the parsing/power of mod_proxy_http for
this achievement.
The patch is based on 2.4.18 and does not apply to trunk or 2.4.x due
latest changes wrt lifetime_transform buckets, but could be easily
adapted...

I think handling Upgrade in mod_proxy_http would "deprecate"
mod_proxy_wstunnel which, as Tijs noticed, can't handle conditional
Upgrade w/o some logic already in mod_proxy_http, and which does not
play well with mod_proxy_http either when the requested (sub)paths
collide.

I'm proposing it now (quite quickly) to see if the approach looks
relevant/suitable/viable (and I could work further on it), or if it is
simply not a good idea :)

Thoughts?
Index: include/http_protocol.h
===
--- include/http_protocol.h	(revision 1734109)
+++ include/http_protocol.h	(working copy)
@@ -976,10 +976,13 @@ AP_DECLARE(void) ap_set_sub_req_protocol(request_r
  */
 AP_DECLARE(void) ap_finalize_sub_req_protocol(request_rec *sub_r);
 
+#define AP_SEND_INTERIM_KEEP_HEADERS 0xdeadbeef
 /**
  * Send an interim (HTTP 1xx) response immediately.
  * @param r The request
  * @param send_headers Whether to send headers in r->headers_out
+ * @remark send_headers == AP_SEND_INTERIM_KEEP_HEADERS allows to send
+ * but not clear r->headers_out
  */
 AP_DECLARE(void) ap_send_interim_response(request_rec *r, int send_headers);
 
Index: modules/proxy/mod_proxy.h
===
--- modules/proxy/mod_proxy.h	(revision 1734109)
+++ modules/proxy/mod_proxy.h	(working copy)
@@ -1004,6 +1004,9 @@ PROXY_DECLARE(int) ap_proxy_pass_brigade(apr_bucke
  conn_rec *origin, apr_bucket_brigade *bb,
  int flush);
 
+PROXY_DECLARE(int) ap_proxy_tunnel_request(apr_pool_t *p, request_rec *r,
+   proxy_conn_rec *backend);
+
 /**
  * Clear the headers referenced by the Connection header from the given
  * table, and remove the Connection header.
Index: modules/proxy/mod_proxy_http.c
===
--- modules/proxy/mod_proxy_http.c	(revision 1734109)
+++ modules/proxy/mod_proxy_http.c	(working copy)
@@ -712,6 +712,7 @@ int ap_proxy_http_request(apr_pool_t *p, request_r
 enum rb_methods rb_method = RB_INIT;
 char *old_cl_val = NULL;
 char *old_te_val = NULL;
+const char *upgrade = NULL;
 apr_off_t bytes_read = 0;
 apr_off_t bytes;
 int force10, rv;
@@ -723,6 +724,9 @@ int ap_proxy_http_request(apr_pool_t *p, request_r
 }
 force10 = 1;
 } else {
+if (apr_table_get(r->subprocess_env, "proxy-forward-upgrade")) {
+upgrade = apr_table_get(r->headers_in, "Upgrade");
+}
 force10 = 0;
 }
 
@@ -925,6 +929,10 @@ skip_body:
 if (!ap_proxy_connection_reusable(p_conn)) {
 buf = apr_pstrdup(p, "Connection: close" CRLF);
 }
+else if (upgrade) {
+buf = apr_pstrcat(p, "Connection: Keep-Alive, Upgrade" CRLF
+ "Upgrade: ", upgrade, CRLF, NULL);
+}
 else {
 buf = apr_pstrdup(p, "Connection: Keep-Alive" CRLF);
 }
@@ -1248,7 +1256,6 @@ apr_status_t ap_proxy_http_process_response(apr_po
 static const char *hop_by_hop_hdrs[] =
 {"Keep-Alive", "Proxy-Authenticate", "TE", "Trailer", "Upgrade", NULL};
 int i;
-const char *te = NULL;
 int original_status = r->status;
 int proxy_status = OK;
 const char *original_status_line = r->status_line;
@@ -1295,6 +1302,7 @@ apr_status_t ap_proxy_http_process_response(apr_po
origin->local_addr->port));
 tmp_bb = apr_brigade_create(p, c->bucket_alloc);
 do {
+const char *te = NULL, *upgrade = NULL;
 apr_status_t rc;
 
 apr_brigade_cleanup(bb);
@@ -1490,6 +1498,11 @@ apr_status_t ap_proxy_http_process_response(apr_po
  */
 te = apr_table_get(r->headers_out, "Transfer-Encoding");
 
+/* Likewise for Upgrade header */
+if (r->status == HTTP_SWITCHING_PROTOCOLS) {
+upgrade = apr_table_get(r->headers_out, "Upgrade");
+}
+
 /* strip connection listed hop-by-hop headers from response */
 toclose = ap_proxy_clear_connection_fn(r, r->headers_out);
 if (toclose) {
@@ -1583,10 +1596,27 @@ apr_status_t ap_proxy_http_process_response(apr_po
"proxy-interim-response");
 ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
   "HTTP: received interim %d response", 

Re: [PATCH] Add "FreeListen" to support IP_FREEBIND

2016-03-08 Thread Tim Bannister
On 8 Mar 2016, at 10:43, Jan Kaluža  wrote:
> On 03/08/2016 10:25 AM, Yann Ylavic wrote:
>> On Tue, Mar 8, 2016 at 9:46 AM, Yann Ylavic  wrote:
>>> On Tue, Mar 8, 2016 at 9:28 AM, Jan Kaluža  wrote:
 
 I have chosen FreeListen over the flags
>>> 
>>> FWIW, should be take the YAD path, I'd prefer ListenFree (over
>>> FreeListen) to emphasize on the "Listen directive family" with a
>>> prefix...
>> 
>> Thinking more about this, I think I second Jim on the wish to have a
>> single Listen directive with some parameter like
>> "options=freebind,backlog:4095,reuseport,...".
> 
> Thinking about right syntax for options...
> 
> I would personally like something like "Listen [IP-address:]portnumber 
> [protocol] [option1] [option2] ...". Do we have list of supported protocols 
> by Listen directive, or we support whatever protocol is there?
> 
> If we have explicit list of protocols, then the protocols itself could become 
> an options.
> 
> If not, can it be acceptable, that you always have to define protocol when 
> you wan to use options?

That sounds fine too.

One proviso comes with the idea of a single socket that can serve several 
protocols. Think of WebSocket, because it is awkward: from an HTTP 
point-of-view, the protocol is initially HTTP and then upgrades to WebSocket; 
however, from a WebSocket point of view, the protocol is WebSocket throughout 
with a preamble that also happens to resemble HTTP/1.1.

Using the first model, only one protocol need be specified (but it's not clear 
which upgrades are valid for this socket). Using the second model, the Listen 
directive needs a way for the admin to specify multiple protocols. Maybe the 
answer is for that to be set in the Protocols directive only?

What should the Listen directive look like, ideally, for a freebind-enabled 
socket that can be either HTTP or WebSocket, and needs to specify options? Like 
this perhaps:

Listen [2001:db8::a00:20ff:fea7:ccea]:1234 http/1.1,websocket options=freebind




-- 
Tim Bannister – is...@c8h10n4o2.org.uk



Re: [PATCH] Add "FreeListen" to support IP_FREEBIND

2016-03-08 Thread Tim Bannister
On 8 Mar 2016, at 09:25, Yann Ylavic  wrote:
> On Tue, Mar 8, 2016 at 9:46 AM, Yann Ylavic  wrote:
>> On Tue, Mar 8, 2016 at 9:28 AM, Jan Kaluža  wrote:
>>> 
>>> I have chosen FreeListen over the flags
>> 
>> FWIW, should be take the YAD path, I'd prefer ListenFree (over
>> FreeListen) to emphasize on the "Listen directive family" with a
>> prefix...
> 
> Thinking more about this, I think I second Jim on the wish to have a
> single Listen directive with some parameter like
> "options=freebind,backlog:4095,reuseport,...".
> 
> We could then whatever (new) IP option more easily (less docs work...)
> and maybe deprecate ListenBacklog.

+1

I thought of having an feature / module for having a separate process bind the 
listening TCP socket (and send the FD to httpd over an AF_UNIX socket*), ending 
up with the same "options=freebind,backlog:4095,reuseport,..." concept.

I'm presuming that “options=protocol:https” would be fine too, and “https” on 
its own would be taken to be a deprecated shorthand?


* similar to how https://github.com/JiriHorky/privbind works

-- 
Tim Bannister – is...@c8h10n4o2.org.uk



Re: mod_proxy_wstunnel incomplete handshake

2016-03-08 Thread Jim Jagielski
Thank you for your email. I am forwarding this to the
correct Email list, which is dev@httpd.apache.org.

> On Mar 8, 2016, at 11:28 AM, t...@able.be wrote:
> 
> Hi,
> 
> I'm currently testing a Web socket application behind an apache reverse 
> proxy. I started off with apache version 2.4.12, but after some weird 
> behavior decided to test versions 2.4.16, 2.4.18 and latest svn.
> 
> https://httpd.apache.org/docs/2.4/mod/mod_proxy_wstunnel.html[1] 
> says that
> 
> "It provides support for the tunnelling of web socket connections to a 
> backend websockets server. The connection is automatically upgraded 
> to a websocket connection".
> 
> Consider the following config, where reverse proxy listens on 
> 192.168.0.1 port 80 and web socket application is hosted on internal 
> web server 192.168.15.233 port .
> 
> LoadModule proxy_module  modules/mod_proxy.so 
> LoadModule proxy_wstunnel_module 
> modules/mod_proxy_wstunnel.so
> 
> Listen 192.168.0.1:80 
> 
> 
>Servername test-ws.domain.org
> 
>ProxyRequests Off 
> 
> 
>RewriteRule ^/([a-zA-Z0-9\.\_\ -:/]*)$  ws://192.168.15.233:/$1 [P]
> 
>RewriteRule .* - [F]
> 
>ProxyPass / ws://192.168.15.233:/
>ProxyPassReverse / ws://192.168.15.233:/
> 
> 
> 
> From reading the docs it appeared as if HTTP requests are processed 
> as normal, unless it is requested to upgrade it to a web socket. 
> Basically in apache 2.4.12 the above config expects everything to be a 
> web socket. The first request on a connection is processed as normal, 
> but once considered a web socket, data is proxied as is without any 
> further processing.
> 
> On 2.4.18 the behavior is different, only requests with the "Upgrade: 
> Websocket" present are considered valid, any other request is denied 
> stating unsupported protocol.
> 
> 
> For instance:
> 
> $ telnet 192.168.0.1 80
> Trying 192.168.0.1... 
> 
> 
> The error log shows: 
> 
> "[Mon Mar 07 11:26:03.133185 2016] [proxy:warn] [pid 26745] [client 
> 192.168.0.1:33296] AH01144: No protocol handler was valid for the URL 
> /. If you are using a DSO ve
> 
> 
> 
> 
> The source code also reads that only the request is considered, and a 
> response of the server is not/never expected. The only expectation is 
> that the connection is opened at both sides (and readable), where it 
> should expect a response to complete the handshake of the HTTP 
> upgrade mechanism.
> 
> Any success or failure of the web server is not considered, eg. in 
> success situations a 101 "Switching protocols" can be expected, any 
> error status code to indicate a failure. Moreover this allows anyone to 
> open a (secure) tunnel towards the back-end server, and possibly 
> request anything (other) through it without apache noticing or notifying 
> about it (no access/error logs).
> 
> Consider the following configuration on 2.4.18:
> 
> LoadModule proxy_module  modules/mod_proxy.so 
> LoadModule proxy_wstunnel_module 
> modules/mod_proxy_wstunnel.so
> 
> Listen 192.168.0.1:80 
> 
> 
>Servername test-ws.domain.org
> 
>ProxyRequests Off 
> 
> 
>RewriteRule ^/(TEST/[a-zA-Z0-9\.\_\ -:/]*)$ 
> ws://192.168.15.233:/$1 [P]
>RewriteRule ^/[a-zA-Z0-9\.\_\ -:/]*)$  http://192.168.15.233:/$1 [P]
> 
>RewriteRule .* - [F]
> 
>ProxyPass /TEST/ ws://192.168.15.233:/TEST/
>ProxyPassReverse /TEST ws://192.168.15.233:/TEST/
> 
>ProxyPass / ws://192.168.15.233:/
>ProxyPassReverse / ws://192.168.15.233:/
> 
> 
> 
> $ telnet 192.168.0.1 80
> 
> HTTP/1.1 404 Not Found 
> 
> 
> HTTP/1.1 200 OK 
> 
> 
> 
> 
> The access log is empty, no trace of any failure. Still the connection is 
> persistent and tunneling is further allowed.
> 
> 
> The error log shows :
> [Tue Mar 08 12:58:31.391351 2016] [rewrite:trace1] [pid 5988] 
> mod_rewrite.c(476): [client 192.168.0.1:34207] 192.168.0.1 - - 
> [192.168.0.1/sid#8c95ed8][rid#8cf0130/initial] go-ahead with proxy 
> request proxy:wss://192.168.15.233:/TEST/anyapp [OK] [Tue Mar 
> 08 12:58:31.391726 2016] [ssl:info] [pid 5988] [remote 
> 192.168.15.233:] AH01964: Connection to child 0 established 
> (server 192.168.0.1:80)
> 
> 
> Later when the connection is terminated or times out, the access log 
> shows:
> 
> 192.168.0.1 - - [08/Mar/2016:12:58:30 +0100] "GET /INS-
> AWINGU/anyapp HTTP/1.1" 200 -
> 
> Shouldn't there be some additional processing that at least completes 
> the HTTP upgrade handshake before opening the tunnel permanently. If 
> not, connections are left open and can be reused for other purposes.
> 
> Kind regards,
> Tijs



Re: HTTP/2 in massive file transfers

2016-03-08 Thread Stefan Eissing
José,

there is a newer version 2.4.18 of Apache httpd which is be better suited
for performance testing. 2.4.17 was the first release of the module and much
has happened since.

Test throughput here on localhost, the limit of http/1.1 and http/2 on
Apache are several gigabytes/s, without any super special configuration.

It is interesting to know how latency affects this and I would like to
see results on this.

As to the calibration of your test client, I recommend getting alternate
figures from servers such has h2o and nghttpd and also using other clients
like the h2load which is part of the nghttp2 distribution. That way, you
can check where difference in client implementation might affect your
performance results.

Cheers,

  Stefan

> Am 08.03.2016 um 14:05 schrieb Joshua Marantz :
> 
> That's a great benchmark, José.  A couple of questions:
> 1. When using http 1.1, is your connection over SSL?  I assume that your h2
> connection is over ssl, and that might account for a speed penalty.
> 2. Have you tried this on other h2 implementations (h2o, nginx)?
> 3. Can you take some other data points?  If you just have 100 shards rather
> than 1000, how does that affect the results?
> 4. Can you also vary the size of each shard?
> 
> Publishing your results in a more comprehensive study would be quite
> valuable.
> 
> -Josh
> 
> On Tue, Mar 8, 2016 at 6:33 AM, Molina  wrote:
> 
>> Hello,
>> 
>> I’m testing the HTTP/2 performance to add support to the software I’m
>> working for. My benchmark consist on an apache 2.4.17 server with the
>> following http2-related configuration:
>> 
>> LoadModule http2_module modules/mod_http2.so
>> 
>>  Protocols h2c http/1.1
>>  H2WindowSize 146000
>>  H2StreamMaxMemSize 146000
>>  H2MinWorkers 8
>>  H2Direct on
>>  LogLevel http2:info
>>  H2MaxSessionStreams 100
>>  H2SessionExtraFiles 1000
>>  H2MaxWorkers 100
>> 
>> 
>> The rest is simply the default apache configuration.
>> My client is a C application that downloads 1024 files of exactly 1MiB
>> each, so totally 1GB. When performing the test with normal HTTP/1.1 the
>> download speed is around 20MiB/s, while when using HTTP/2 is 1.5MiB/s. The
>> client uses exactly one  multiplexed connection and works as expected
>> Lastly, the client and server are located in center Europe and center USA
>> respectively to increase the impact of opening many HTTP/1.1 connections
>> with such a high physical distance due to latency.
>> 
>> I tried to increase the Linux window size, as well as the TCP buffer to
>> increase the download speed, but without success so far.
>> 
>> Is there some configuration parameter I’m missing to make it perform
>> better? Or perhaps the module itself needs an special configuration for
>> such a use case?
>> 
>> Thanks a lot in advance. Best regards,
>> José Molina
>> 
>> 



Re: HTTP/2 in massive file transfers

2016-03-08 Thread Joshua Marantz
That's a great benchmark, José.  A couple of questions:
1. When using http 1.1, is your connection over SSL?  I assume that your h2
connection is over ssl, and that might account for a speed penalty.
2. Have you tried this on other h2 implementations (h2o, nginx)?
3. Can you take some other data points?  If you just have 100 shards rather
than 1000, how does that affect the results?
4. Can you also vary the size of each shard?

Publishing your results in a more comprehensive study would be quite
valuable.

-Josh

On Tue, Mar 8, 2016 at 6:33 AM, Molina  wrote:

> Hello,
>
> I’m testing the HTTP/2 performance to add support to the software I’m
> working for. My benchmark consist on an apache 2.4.17 server with the
> following http2-related configuration:
>
> LoadModule http2_module modules/mod_http2.so
> 
>   Protocols h2c http/1.1
>   H2WindowSize 146000
>   H2StreamMaxMemSize 146000
>   H2MinWorkers 8
>   H2Direct on
>   LogLevel http2:info
>   H2MaxSessionStreams 100
>   H2SessionExtraFiles 1000
>   H2MaxWorkers 100
> 
>
> The rest is simply the default apache configuration.
> My client is a C application that downloads 1024 files of exactly 1MiB
> each, so totally 1GB. When performing the test with normal HTTP/1.1 the
> download speed is around 20MiB/s, while when using HTTP/2 is 1.5MiB/s. The
> client uses exactly one  multiplexed connection and works as expected
> Lastly, the client and server are located in center Europe and center USA
> respectively to increase the impact of opening many HTTP/1.1 connections
> with such a high physical distance due to latency.
>
> I tried to increase the Linux window size, as well as the TCP buffer to
> increase the download speed, but without success so far.
>
> Is there some configuration parameter I’m missing to make it perform
> better? Or perhaps the module itself needs an special configuration for
> such a use case?
>
> Thanks a lot in advance. Best regards,
> José Molina
>
>


HTTP/2 in massive file transfers

2016-03-08 Thread Molina
Hello,

I’m testing the HTTP/2 performance to add support to the software I’m working 
for. My benchmark consist on an apache 2.4.17 server with the following 
http2-related configuration:

LoadModule http2_module modules/mod_http2.so

  Protocols h2c http/1.1
  H2WindowSize 146000
  H2StreamMaxMemSize 146000
  H2MinWorkers 8
  H2Direct on
  LogLevel http2:info
  H2MaxSessionStreams 100
  H2SessionExtraFiles 1000
  H2MaxWorkers 100


The rest is simply the default apache configuration.
My client is a C application that downloads 1024 files of exactly 1MiB each, so 
totally 1GB. When performing the test with normal HTTP/1.1 the download speed 
is around 20MiB/s, while when using HTTP/2 is 1.5MiB/s. The client uses exactly 
one  multiplexed connection and works as expected
Lastly, the client and server are located in center Europe and center USA 
respectively to increase the impact of opening many HTTP/1.1 connections with 
such a high physical distance due to latency.

I tried to increase the Linux window size, as well as the TCP buffer to 
increase the download speed, but without success so far.

Is there some configuration parameter I’m missing to make it perform better? Or 
perhaps the module itself needs an special configuration for such a use case?

Thanks a lot in advance. Best regards,
José Molina



signature.asc
Description: Message signed with OpenPGP using GPGMail


Re: [PATCH] Add "FreeListen" to support IP_FREEBIND

2016-03-08 Thread Jan Kaluža

On 03/08/2016 10:25 AM, Yann Ylavic wrote:

On Tue, Mar 8, 2016 at 9:46 AM, Yann Ylavic  wrote:

On Tue, Mar 8, 2016 at 9:28 AM, Jan Kaluža  wrote:


I have chosen FreeListen over the flags


FWIW, should be take the YAD path, I'd prefer ListenFree (over
FreeListen) to emphasize on the "Listen directive family" with a
prefix...


Thinking more about this, I think I second Jim on the wish to have a
single Listen directive with some parameter like
"options=freebind,backlog:4095,reuseport,...".


Thinking about right syntax for options...

I would personally like something like "Listen [IP-address:]portnumber 
[protocol] [option1] [option2] ...". Do we have list of supported 
protocols by Listen directive, or we support whatever protocol is there?


If we have explicit list of protocols, then the protocols itself could 
become an options.


If not, can it be acceptable, that you always have to define protocol 
when you wan to use options?


Otherwise I can always implement Yann's idea with "Listen 
[IP-address:]portnumber [protocol] [options=[option1,option2,...]]".


Regards,
Jan Kaluza



We could then whatever (new) IP option more easily (less docs work...)
and maybe deprecate ListenBacklog.

For example, the "reuseport" (SO_REUSEPORT) option seem to be usable
w/o the current buckets mechanism in latest linux kernels, so indeed
we may add more and more options there...





Re: [PATCH] Add "FreeListen" to support IP_FREEBIND

2016-03-08 Thread Yann Ylavic
On Mon, Mar 7, 2016 at 12:41 PM, Jan Kaluža  wrote:
>
> This is needed for httpd startup with systemd when one wants to use
> particular IP address to bind. There is no way how to start httpd after the
> IP address has been configured in systemd and according to systemd
> developers, the applications should become more robust to handle network
> changes like that. The full reasoning is explained here [1].

Another use case is keepalived (VRRP) where the IPs are set by the
daemon when needed (eg. fail-over), and hence not always available at
startup.
It may be worth mentioning in the docs that this new feature would
help in such case, and could replace settings like sysctl's
net.ipv[46].ip_nonlocal_bind which are system (or at least network
namespace) wide.

Regards,
Yann.


Re: [PATCH] Add "FreeListen" to support IP_FREEBIND

2016-03-08 Thread Yann Ylavic
On Tue, Mar 8, 2016 at 9:46 AM, Yann Ylavic  wrote:
> On Tue, Mar 8, 2016 at 9:28 AM, Jan Kaluža  wrote:
>>
>> I have chosen FreeListen over the flags
>
> FWIW, should be take the YAD path, I'd prefer ListenFree (over
> FreeListen) to emphasize on the "Listen directive family" with a
> prefix...

Thinking more about this, I think I second Jim on the wish to have a
single Listen directive with some parameter like
"options=freebind,backlog:4095,reuseport,...".

We could then whatever (new) IP option more easily (less docs work...)
and maybe deprecate ListenBacklog.

For example, the "reuseport" (SO_REUSEPORT) option seem to be usable
w/o the current buckets mechanism in latest linux kernels, so indeed
we may add more and more options there...


Re: [PATCH] Add "FreeListen" to support IP_FREEBIND

2016-03-08 Thread Yann Ylavic
On Tue, Mar 8, 2016 at 9:28 AM, Jan Kaluža  wrote:
>
> I have chosen FreeListen over the flags

FWIW, should be take the YAD path, I'd prefer ListenFree (over
FreeListen) to emphasize on the "Listen directive family" with a
prefix...

Regards,
Yann.


Re: [PATCH] Add "FreeListen" to support IP_FREEBIND

2016-03-08 Thread Jan Kaluža

On 03/08/2016 06:32 AM, William A Rowe Jr wrote:

On Mar 7, 2016 21:59, "Yehuda Katz" > wrote:
 >
 > On Mon, Mar 7, 2016 at 9:06 PM, William A Rowe Jr
> wrote:
 >>
 >> On Mar 7, 2016 13:54, "Jan Kaluža" > wrote:
 >> >
 >> > On 03/07/2016 04:17 PM, Jim Jagielski wrote:
 >> >>
 >> >> Intstead of adding YAD (yet another directive ;) ), would it
 >> >> be possible to somehow leverage Listen itself, maybe with some
 >> >> sort of flag?
 >> >
 >> >
 >> > Yes, that would be quite possible. I was thinking about that way,
but I have chosen YAD as a first approach. If you think adding flag to
Listen is better way, I can rework my patch.
 >> >
 >> > Regards,
 >> > Jan Kaluza
 >> >
 >>
 >> Reviewing the behavior, an unadorned new directive makes more sense
to me than cluttering Listen, which already takes one optional protocol
behavior argument.
 >>
 >> The same handler can process both directives.
 >
 > A benefit of using a flag is: what happens if the default changes at
some point? YAD would need to be created to go back to the old behavior
- which would make things more complicated.  Is it possible to use
something like a plus/minus or question mark symbol with each
address:port which would allow the default to be changed at some future
point without requiring having this discussion again?
 >
 > Example:
 > Listen ?192.170.2.1:80   # Use IP_FREEBIND to
listen when IP is available (new behavior)
 > Listen +192.170.2.5:8000   # Require IP to
be available (old behavior)
 > Listen [2001:db8::a00:20ff:fea7:ccea]:80  # Current default behavior
(old)

Interesting point, I raised the same consideration for piped logging
syntax some years ago.  But at that time it was the consensus that the
default would change with the next major version.

I see small probably that this would become a default behavior, from the
perspective of robustness alone.  I see that you simply suggest a
tri-state (and trailing '?' Vs '!' makes more intuitive sense to me),
but I'm not seeing a consensus yet that the default would change in the
future.


I think that the default behaviour should not be changed, at least not 
in major version.


I have chosen FreeListen over the flags, because I personally think it's 
better to have two directives than single one with more and more flags 
changing its behaviour. But I care more about that feature, not about a 
way how it is enabled in the end :).


Jan Kaluza



The same can be accomplished by adding a third 'FixedListen' directive,
leaving Listen itself free to switch behaviors.

But from the migration perspective, I'd be loath to switch any default
Listen behavior without the admin's explicit intervention.  POLS.