haproxy/include/proto
Willy Tarreau ef907fee12 BUG/MAJOR: channel: fix miscalculation of available buffer space (4th try)
Unfortunately, commit 169c470 ("BUG/MEDIUM: channel: fix miscalculation of
available buffer space (3rd try)") was still not enough to completely
address the issue. It fell into an integer comparison trap. Contrary to
expectations, chn->to_forward may also have the sign bit set when
forwarding regular data having a large content-length, resulting in
an incomplete check of the result and of the reserve because the with
to_forward very large, to_forward+o could become very small and also
the reserve could become positive again and make channel_recv_limit()
return a negative value.

One way to reproduce this situation is to transfer a large file (> 2GB)
with http-keep-alive or http-server-close, without splicing, and ensure
that the server uses content-length instead of chunks. The transfer
should stall very early after the first buffer has been transferred
to the client.

This fix now properly checks 1) for an overflow caused by summing o and
to_forward, and 2) for o+to_forward being smaller or larger than maxrw
before performing the subtract, so that all sensitive operations are
properly performed on 33-bit arithmetics.

The code was subjected again to a series of tests using inject+httpterm
scanning a wide range of object sizes (+10MB after each new request) :

  $ printf "new page 1\nget 127.0.0.1:8002 / s=%%s0m\n" | \
      inject64 -o 1 -u 1 -f /dev/stdin

With previous fix, the transfer would suddenly stop when reaching 2GB :

   hits ^hits hits/s  ^h/s     bytes  kB/s  last  errs  tout htime  sdht ptime
    203     1      2     1 216816173354 2710202 3144892     0     0 685.0 0.0 685.0
    205     2      2     2 219257283186 2706880 2441109     0     0 679.5 6.5 679.5
    205     0      2     0 219257283186 2673836     0     0     0 0.0 0.0 0.0
    205     0      2     0 219257283186 2641622     0     0     0 0.0 0.0 0.0
    205     0      2     0 219257283186 2610174     0     0     0 0.0 0.0 0.0

Now it's fine even past 4 GB.

Many thanks to Vedran Furac for reporting this issue early with a common
access pattern helping to troubleshoot this.

This fix must be backported to 1.6 and 1.5 where the commit above was
already backported.
2016-05-03 17:58:03 +02:00
..
acl.h MAJOR: sample: pass a pointer to the session to each sample fetch function 2015-04-06 11:37:25 +02:00
action.h MINOR: http/tcp: fill the avalaible actions 2015-10-02 22:56:11 +02:00
applet.h MINOR: applet: rename applet_runq to applet_active_queue 2015-09-25 18:02:44 +02:00
arg.h MINOR: sample: Moves ARGS underlying type from 32 to 64 bits. 2016-03-15 22:11:52 +01:00
auth.h MEDIUM: pattern: The match function browse itself the list or the tree. 2014-03-17 18:06:07 +01:00
backend.h REORG/MAJOR: session: rename the "session" entity to "stream" 2015-04-06 11:23:56 +02:00
channel.h BUG/MAJOR: channel: fix miscalculation of available buffer space (4th try) 2016-05-03 17:58:03 +02:00
checks.h MAJOR: server: add DNS-based server name resolution 2015-06-13 22:07:35 +02:00
compression.h REORG: filters: Prepare creation of the HTTP compression filter 2016-02-09 14:53:15 +01:00
connection.h CLEANUP: fix inconsistency between fd->iocb, proto->accept and accept() 2016-04-14 11:18:22 +02:00
dns.h MEDIUM: dns: extract options 2016-02-19 14:37:46 +01:00
dumpstats.h MINOR: dumpstats: split stats_dump_be_stats() in two parts 2016-03-30 17:26:19 +02:00
fd.h MAJOR: polling: centralize calls to I/O callbacks 2014-11-21 20:37:32 +01:00
filters.h MINOR: filters: Print the list of existing filters during HA startup 2016-04-21 06:58:08 +02:00
flt_http_comp.h MAJOR: filters/http: Rewrite the HTTP compression as a filter 2016-02-09 14:53:15 +01:00
freq_ctr.h MINOR: freq_ctr: introduce a new averaging method 2014-06-17 17:15:51 +02:00
frontend.h REORG/MAJOR: session: rename the "session" entity to "stream" 2015-04-06 11:23:56 +02:00
hdr_idx.h OPTIM/MINOR: move the hdr_idx pools out of the proxy struct 2011-10-24 18:15:04 +02:00
hlua_fcn.h MINOR: lua: post initialization 2016-03-30 15:44:58 +02:00
hlua.h BUILD/MINOR: lua: ensure that hlua_ctx_destroy is properly defined 2015-06-17 20:18:54 +02:00
lb_chash.h [MEDIUM] backend: implement consistent hashing variation 2009-10-09 07:17:58 +02:00
lb_fas.h MEDIUM: backend: add the 'first' balancing algorithm 2012-02-21 22:27:27 +01:00
lb_fwlc.h [CLEANUP] backend: move LB algos to individual files 2009-10-01 11:19:37 +02:00
lb_fwrr.h [CLEANUP] backend: move LB algos to individual files 2009-10-01 11:19:37 +02:00
lb_map.h [MINOR] lb_map: reorder code in order to ease integration of new hash functions 2009-10-01 21:11:15 +02:00
listener.h CLEANUP: fix inconsistency between fd->iocb, proto->accept and accept() 2016-04-14 11:18:22 +02:00
log.h MEDIUM: log: add a new log format flag "E" 2016-02-12 13:36:47 +01:00
map.h MINOR: samples: rename some struct member from "smp" to "data" 2015-08-20 17:13:46 +02:00
obj_type.h CLEANUP: applet: rename struct si_applet to applet 2015-04-23 17:56:16 +02:00
pattern.h MINOR: map: Add regex matching replacement 2016-02-10 23:38:34 +01:00
payload.h REORG/MAJOR: session: rename the "session" entity to "stream" 2015-04-06 11:23:56 +02:00
peers.h MAJOR: peers: peers protocol version 2.0 2015-05-29 15:50:33 +02:00
pipe.h [MEDIUM] introduce pipe pools 2009-01-25 13:49:53 +01:00
port_range.h [MEDIUM] add support for binding to source port ranges during connect 2009-06-10 12:23:32 +02:00
proto_http.h REORG: filters: Prepare creation of the HTTP compression filter 2016-02-09 14:53:15 +01:00
proto_tcp.h CLEANUP: actions: missplaced includes 2015-09-10 21:17:04 +02:00
proto_udp.h CLEANUP: fix inconsistency between fd->iocb, proto->accept and accept() 2016-04-14 11:18:22 +02:00
proto_uxst.h REORG/MAJOR: session: rename the "session" entity to "stream" 2015-04-06 11:23:56 +02:00
protocol.h MEDIUM: protocol: use a family array to index the protocol handlers 2015-02-28 23:12:31 +01:00
proxy.h CLEANUP: proxy: remove last references to appsession 2015-08-10 19:42:30 +02:00
queue.h REORG/MAJOR: session: rename the "session" entity to "stream" 2015-04-06 11:23:56 +02:00
raw_sock.h REORG: connection: rename the data layer the "transport layer" 2012-10-04 22:26:09 +02:00
sample.h MINOR: sample: add a new helper to initialize the owner of a sample 2016-03-10 16:42:58 +01:00
server.h MINOR: Add ability for agent-check to set server maxconn 2016-04-25 17:23:50 +02:00
session.h MINOR: session: introduce session_new() 2015-04-06 11:37:33 +02:00
shctx.h BUG/MAJOR: ssl: Fallback to private session cache if current lock mode is not supported. 2014-05-08 22:46:32 +02:00
signal.h CLEANUP: includes: fix includes for a number of users of fd.h 2012-09-03 20:49:14 +02:00
ssl_sock.h BUG/MINOR: ssl: Be sure to use unique serial for regenerated certificates 2016-02-09 09:04:53 +01:00
stick_table.h MEDIUM: stick-table: remove the now duplicate find_stktable() function 2015-05-26 12:08:07 +02:00
stream_interface.h BUG: stream_interface: Reuse connection even if the output channel is empty 2016-02-03 14:22:55 +01:00
stream.h MINOR: stream/applet: add use-service action 2015-09-28 01:03:48 +02:00
task.h MAJOR: poll: only rely on wake_expired_tasks() to compute the wait delay 2015-02-28 23:12:30 +01:00
template.h [CLEANUP] included common/version.h everywhere 2006-06-29 18:54:54 +02:00
vars.h BUG/MAJOR: vars: always retrieve the stream and session from the sample 2016-03-10 17:28:04 +01:00