From da76459dc21b5af2449af2d36eb95226cb186ce2 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 28 Apr 2024 11:35:11 +0200 Subject: Adding upstream version 2.6.12. Signed-off-by: Daniel Baumann --- .cirrus.yml | 13 + .gitattributes | 3 + .github/ISSUE_TEMPLATE/Bug.yml | 108 + .github/ISSUE_TEMPLATE/Code-Report.yml | 43 + .github/ISSUE_TEMPLATE/Feature.yml | 50 + .github/ISSUE_TEMPLATE/config.yml | 8 + .github/errorfile | 209 + .github/h2spec.config | 27 + .github/matrix.py | 201 + .github/vtest.json | 14 + .github/workflows/codespell.yml | 19 + .github/workflows/compliance.yml | 57 + .github/workflows/contrib.yml | 25 + .github/workflows/coverity.yml | 43 + .github/workflows/cross-zoo.yml | 110 + .github/workflows/musl.yml | 58 + .github/workflows/openssl-nodeprecated.yml | 33 + .github/workflows/vtest.yml | 155 + .github/workflows/windows.yml | 67 + .gitignore | 55 + .mailmap | 1 + .travis.yml | 54 + BRANCHES | 239 + CHANGELOG | 19097 +++++++++++++++ CONTRIBUTING | 1020 + INSTALL | 669 + LICENSE | 37 + MAINTAINERS | 152 + Makefile | 1208 + README | 22 + SUBVERS | 2 + VERDATE | 2 + VERSION | 1 + addons/51degrees/51d.c | 783 + addons/51degrees/dummy/cityhash/city.c | 4 + addons/51degrees/dummy/pattern/51Degrees.c | 114 + addons/51degrees/dummy/pattern/51Degrees.h | 147 + addons/51degrees/dummy/threading.c | 4 + addons/51degrees/dummy/trie/51Degrees.c | 89 + addons/51degrees/dummy/trie/51Degrees.h | 112 + addons/deviceatlas/Makefile | 48 + addons/deviceatlas/da.c | 501 + addons/deviceatlas/dadwsch.c | 195 + addons/deviceatlas/dummy/Makefile | 12 + addons/deviceatlas/dummy/Os/daunix.c | 9 + addons/deviceatlas/dummy/dac.c | 222 + addons/deviceatlas/dummy/dac.h | 600 + addons/deviceatlas/dummy/dadwcom.c | 1 + addons/deviceatlas/dummy/dasch.c | 1 + addons/deviceatlas/dummy/json.c | 1 + addons/ot/AUTHORS | 1 + addons/ot/MAINTAINERS | 1 + addons/ot/Makefile | 75 + addons/ot/README | 794 + addons/ot/README-func | 298 + addons/ot/README-pool | 25 + addons/ot/include/cli.h | 50 + addons/ot/include/conf.h | 228 + addons/ot/include/config.h | 46 + addons/ot/include/debug.h | 104 + addons/ot/include/define.h | 107 + addons/ot/include/event.h | 120 + addons/ot/include/filter.h | 68 + addons/ot/include/group.h | 61 + addons/ot/include/http.h | 41 + addons/ot/include/include.h | 66 + addons/ot/include/opentracing.h | 86 + addons/ot/include/parser.h | 172 + addons/ot/include/pool.h | 39 + addons/ot/include/scope.h | 126 + addons/ot/include/util.h | 109 + addons/ot/include/vars.h | 55 + addons/ot/src/cli.c | 397 + addons/ot/src/conf.c | 767 + addons/ot/src/event.c | 338 + addons/ot/src/filter.c | 1176 + addons/ot/src/group.c | 354 + addons/ot/src/http.c | 312 + addons/ot/src/opentracing.c | 1067 + addons/ot/src/parser.c | 1225 + addons/ot/src/pool.c | 223 + addons/ot/src/scope.c | 634 + addons/ot/src/util.c | 815 + addons/ot/src/vars.c | 834 + addons/ot/test/README-speed-cmp | 111 + addons/ot/test/README-speed-ctx | 111 + addons/ot/test/README-speed-fe-be | 111 + addons/ot/test/README-speed-sa | 111 + addons/ot/test/be/cfg-dd.json | 5 + addons/ot/test/be/cfg-jaeger.yml | 34 + addons/ot/test/be/cfg-zipkin.json | 4 + addons/ot/test/be/haproxy.cfg | 37 + addons/ot/test/be/ot.cfg | 62 + addons/ot/test/cmp/cfg-dd.json | 5 + addons/ot/test/cmp/cfg-jaeger.yml | 34 + addons/ot/test/cmp/cfg-zipkin.json | 4 + addons/ot/test/cmp/haproxy.cfg | 36 + addons/ot/test/cmp/ot.cfg | 83 + addons/ot/test/ctx/cfg-dd.json | 5 + addons/ot/test/ctx/cfg-jaeger.yml | 34 + addons/ot/test/ctx/cfg-zipkin.json | 4 + addons/ot/test/ctx/haproxy.cfg | 38 + addons/ot/test/ctx/ot.cfg | 197 + addons/ot/test/empty/cfg-dd.json | 5 + addons/ot/test/empty/cfg-jaeger.yml | 34 + addons/ot/test/empty/cfg-zipkin.json | 4 + addons/ot/test/empty/haproxy.cfg | 30 + addons/ot/test/empty/ot.cfg | 3 + addons/ot/test/fe/cfg-dd.json | 5 + addons/ot/test/fe/cfg-jaeger.yml | 34 + addons/ot/test/fe/cfg-zipkin.json | 4 + addons/ot/test/fe/haproxy.cfg | 37 + addons/ot/test/fe/ot.cfg | 74 + addons/ot/test/func-stat.sh | 5 + addons/ot/test/get-opentracing-plugins.sh | 45 + addons/ot/test/index.html | 1 + addons/ot/test/run-cmp.sh | 13 + addons/ot/test/run-ctx.sh | 13 + addons/ot/test/run-fe-be.sh | 47 + addons/ot/test/run-sa.sh | 13 + addons/ot/test/sa/cfg-dd.json | 5 + addons/ot/test/sa/cfg-jaeger.yml | 34 + addons/ot/test/sa/cfg-zipkin.json | 4 + addons/ot/test/sa/haproxy.cfg | 40 + addons/ot/test/sa/ot.cfg | 160 + addons/ot/test/test-speed.sh | 117 + addons/promex/README | 356 + addons/promex/service-prometheus.c | 1659 ++ addons/wurfl/dummy/Makefile | 13 + addons/wurfl/dummy/dummy-wurfl.c | 126 + addons/wurfl/dummy/wurfl/wurfl.h | 409 + addons/wurfl/wurfl.c | 779 + admin/dyncookie/dyncookie.c | 56 + admin/halog/README | 4 + admin/halog/fgets2.c | 267 + admin/halog/halog.c | 1910 ++ admin/iprange/Makefile | 13 + admin/iprange/ip6range.c | 397 + admin/iprange/iprange.c | 202 + admin/netsnmp-perl/README | 111 + .../cacti_data_query_haproxy_backends.xml | 750 + .../cacti_data_query_haproxy_frontends.xml | 750 + admin/netsnmp-perl/haproxy.pl | 249 + admin/netsnmp-perl/haproxy_backend.xml | 83 + admin/netsnmp-perl/haproxy_frontend.xml | 83 + admin/netsnmp-perl/haproxy_socket.xml | 90 + admin/release-estimator/README.md | 68 + admin/release-estimator/release-estimator.py | 429 + admin/selinux/README | 18 + admin/selinux/haproxy.fc | 6 + admin/selinux/haproxy.if | 2 + admin/selinux/haproxy.te | 66 + admin/syntax-highlight/haproxy.vim | 164 + admin/systemd/Makefile | 8 + admin/systemd/haproxy.service.in | 37 + admin/wireshark-dissectors/peers/Makefile | 17 + admin/wireshark-dissectors/peers/README | 78 + admin/wireshark-dissectors/peers/packet-happp.c | 1679 ++ .../peers/wireshark.happp.dissector.patch | 24 + dev/base64/base64rev-gen.c | 70 + dev/coccinelle/bug_on.cocci | 7 + dev/coccinelle/cs_endp_flags.cocci | 76 + dev/coccinelle/endp_flags.cocci | 76 + dev/coccinelle/ha_free.cocci | 6 + dev/coccinelle/ist.cocci | 86 + dev/coccinelle/realloc_leak.cocci | 6 + dev/coccinelle/strcmp.cocci | 309 + dev/coccinelle/xalloc_cast.cocci | 11 + dev/coccinelle/xalloc_size.cocci | 41 + dev/flags/README | 12 + dev/flags/flags.c | 496 + dev/flags/show-fd-to-flags.sh | 2 + dev/haring/README | 4 + dev/haring/haring.c | 271 + dev/hpack/README | 4 + dev/hpack/decode.c | 215 + dev/hpack/gen-enc.c | 205 + dev/hpack/gen-rht.c | 369 + dev/plug_qdisc/README | 59 + dev/plug_qdisc/plug_qdisc.c | 86 + dev/poll/Makefile | 11 + dev/poll/poll.c | 365 + dev/tcploop/Makefile | 11 + dev/tcploop/tcploop.c | 956 + dev/trace/trace.awk | 78 + dev/udp/udp-perturb.c | 519 + doc/51Degrees-device-detection.txt | 152 + doc/DeviceAtlas-device-detection.txt | 82 + doc/SOCKS4.protocol.txt | 1 + doc/SPOE.txt | 1255 + doc/WURFL-device-detection.txt | 71 + doc/acl.fig | 229 + doc/architecture.txt | 1448 ++ doc/close-options.txt | 39 + doc/coding-style.txt | 1566 ++ doc/configuration.txt | 23704 +++++++++++++++++++ doc/cookie-options.txt | 25 + doc/design-thoughts/backends-v0.txt | 27 + doc/design-thoughts/backends.txt | 125 + doc/design-thoughts/be-fe-changes.txt | 74 + doc/design-thoughts/binding-possibilities.txt | 167 + doc/design-thoughts/config-language.txt | 262 + doc/design-thoughts/connection-reuse.txt | 224 + doc/design-thoughts/connection-sharing.txt | 31 + doc/design-thoughts/dynamic-buffers.txt | 41 + doc/design-thoughts/entities-v2.txt | 276 + doc/design-thoughts/how-it-works.txt | 60 + doc/design-thoughts/http2.txt | 277 + doc/design-thoughts/http_load_time.url | 5 + doc/design-thoughts/pool-debugging.txt | 243 + doc/design-thoughts/rate-shaping.txt | 90 + doc/design-thoughts/sess_par_sec.txt | 13 + doc/design-thoughts/thread-group.txt | 528 + doc/gpl.txt | 340 + doc/haproxy.1 | 227 + doc/internals/acl.txt | 82 + doc/internals/api/appctx.txt | 142 + doc/internals/api/buffer-api.txt | 653 + doc/internals/api/filters.txt | 1186 + doc/internals/api/htx-api.txt | 570 + doc/internals/api/initcalls.txt | 360 + doc/internals/api/ist.txt | 167 + doc/internals/api/layers.txt | 190 + doc/internals/api/list.txt | 195 + doc/internals/api/pools.txt | 577 + doc/internals/api/scheduler.txt | 226 + doc/internals/body-parsing.txt | 165 + doc/internals/connect-status.txt | 28 + doc/internals/connection-header.txt | 196 + doc/internals/connection-scale.txt | 44 + doc/internals/entities-v2.txt | 193 + doc/internals/entities.txt | 96 + doc/internals/fd-migration.txt | 138 + doc/internals/hashing.txt | 83 + doc/internals/header-parser-speed.txt | 92 + doc/internals/header-tree.txt | 124 + doc/internals/http-cookies.txt | 45 + doc/internals/http-docs.txt | 5 + doc/internals/http-parsing.txt | 335 + doc/internals/list.fig | 599 + doc/internals/list.png | Bin 0 -> 33618 bytes doc/internals/listener-states.fig | 150 + doc/internals/listener-states.png | Bin 0 -> 36142 bytes doc/internals/lua_socket.fig | 113 + doc/internals/lua_socket.pdf | Bin 0 -> 14969 bytes doc/internals/muxes.fig | 401 + doc/internals/muxes.pdf | Bin 0 -> 12984 bytes doc/internals/muxes.png | Bin 0 -> 32209 bytes doc/internals/muxes.svg | 911 + doc/internals/naming.txt | 54 + doc/internals/notes-layers.txt | 330 + doc/internals/pattern.dia | Bin 0 -> 5631 bytes doc/internals/pattern.pdf | Bin 0 -> 37269 bytes doc/internals/polling-states.fig | 59 + doc/internals/repartition-be-fe-fi.txt | 20 + doc/internals/sched.fig | 748 + doc/internals/sched.pdf | Bin 0 -> 25334 bytes doc/internals/sched.png | Bin 0 -> 150457 bytes doc/internals/sched.svg | 1204 + doc/internals/ssl_cert.dia | Bin 0 -> 6700 bytes doc/internals/stats-v2.txt | 8 + doc/internals/stream-sock-states.fig | 535 + doc/intro.txt | 1700 ++ doc/lgpl.txt | 504 + doc/linux-syn-cookies.txt | 106 + doc/lua-api/Makefile | 153 + doc/lua-api/_static/channel.fig | 55 + doc/lua-api/_static/channel.png | Bin 0 -> 18457 bytes doc/lua-api/conf.py | 242 + doc/lua-api/index.rst | 3797 +++ doc/lua.txt | 966 + doc/management.txt | 4203 ++++ doc/netscaler-client-ip-insertion-protocol.txt | 55 + doc/network-namespaces.txt | 106 + doc/peers-v2.0.txt | 288 + doc/peers.txt | 491 + doc/proxy-protocol.txt | 1051 + doc/queuing.fig | 192 + doc/regression-testing.txt | 706 + doc/seamless_reload.txt | 62 + examples/basic-config-edge.cfg | 124 + examples/content-sw-sample.cfg | 65 + examples/errorfiles/400.http | 9 + examples/errorfiles/403.http | 9 + examples/errorfiles/408.http | 9 + examples/errorfiles/500.http | 9 + examples/errorfiles/502.http | 9 + examples/errorfiles/503.http | 9 + examples/errorfiles/504.http | 9 + examples/errorfiles/README | 9 + examples/haproxy.init | 137 + examples/option-http_proxy.cfg | 54 + examples/quick-test.cfg | 29 + examples/socks4.cfg | 55 + examples/transparent_proxy.cfg | 55 + examples/wurfl-example.cfg | 41 + include/haproxy/acl-t.h | 155 + include/haproxy/acl.h | 160 + include/haproxy/action-t.h | 209 + include/haproxy/action.h | 119 + include/haproxy/activity-t.h | 98 + include/haproxy/activity.h | 44 + include/haproxy/api-t.h | 40 + include/haproxy/api.h | 38 + include/haproxy/applet-t.h | 136 + include/haproxy/applet.h | 246 + include/haproxy/arg-t.h | 151 + include/haproxy/arg.h | 94 + include/haproxy/atomic.h | 895 + include/haproxy/auth-t.h | 57 + include/haproxy/auth.h | 40 + include/haproxy/backend-t.h | 184 + include/haproxy/backend.h | 152 + include/haproxy/base64.h | 28 + include/haproxy/buf-t.h | 62 + include/haproxy/buf.h | 1135 + include/haproxy/bug.h | 345 + include/haproxy/capture-t.h | 43 + include/haproxy/capture.h | 37 + include/haproxy/cbuf-t.h | 45 + include/haproxy/cbuf.h | 136 + include/haproxy/cfgcond-t.h | 103 + include/haproxy/cfgcond.h | 43 + include/haproxy/cfgdiag.h | 11 + include/haproxy/cfgparse.h | 147 + include/haproxy/channel-t.h | 311 + include/haproxy/channel.h | 1016 + include/haproxy/check-t.h | 186 + include/haproxy/check.h | 130 + include/haproxy/chunk.h | 285 + include/haproxy/cli-t.h | 95 + include/haproxy/cli.h | 110 + include/haproxy/clock.h | 47 + include/haproxy/compat.h | 305 + include/haproxy/compiler.h | 379 + include/haproxy/compression-t.h | 96 + include/haproxy/compression.h | 44 + include/haproxy/connection-t.h | 653 + include/haproxy/connection.h | 704 + include/haproxy/counters-t.h | 125 + include/haproxy/cpuset-t.h | 56 + include/haproxy/cpuset.h | 44 + include/haproxy/debug.h | 36 + include/haproxy/defaults.h | 486 + include/haproxy/dgram-t.h | 53 + include/haproxy/dgram.h | 29 + include/haproxy/dict-t.h | 46 + include/haproxy/dict.h | 36 + include/haproxy/dns-t.h | 179 + include/haproxy/dns.h | 33 + include/haproxy/dynbuf-t.h | 41 + include/haproxy/dynbuf.h | 127 + include/haproxy/errors.h | 133 + include/haproxy/extcheck.h | 49 + include/haproxy/fcgi-app-t.h | 123 + include/haproxy/fcgi-app.h | 42 + include/haproxy/fcgi.h | 133 + include/haproxy/fd-t.h | 229 + include/haproxy/fd.h | 497 + include/haproxy/filters-t.h | 258 + include/haproxy/filters.h | 187 + include/haproxy/fix-t.h | 70 + include/haproxy/fix.h | 97 + include/haproxy/flt_http_comp.h | 28 + include/haproxy/freq_ctr-t.h | 45 + include/haproxy/freq_ctr.h | 386 + include/haproxy/frontend.h | 37 + include/haproxy/global-t.h | 218 + include/haproxy/global.h | 102 + include/haproxy/h1.h | 378 + include/haproxy/h1_htx.h | 76 + include/haproxy/h2.h | 351 + include/haproxy/h3.h | 115 + include/haproxy/h3_stats-t.h | 12 + include/haproxy/h3_stats.h | 17 + include/haproxy/hash.h | 33 + include/haproxy/hlua-t.h | 215 + include/haproxy/hlua.h | 73 + include/haproxy/hlua_fcn.h | 38 + include/haproxy/hpack-dec.h | 39 + include/haproxy/hpack-enc.h | 261 + include/haproxy/hpack-huff.h | 35 + include/haproxy/hpack-tbl-t.h | 143 + include/haproxy/hpack-tbl.h | 184 + include/haproxy/hq_interop.h | 6 + include/haproxy/http-hdr-t.h | 41 + include/haproxy/http-hdr.h | 60 + include/haproxy/http-t.h | 184 + include/haproxy/http.h | 183 + include/haproxy/http_ana-t.h | 208 + include/haproxy/http_ana.h | 90 + include/haproxy/http_client-t.h | 57 + include/haproxy/http_client.h | 36 + include/haproxy/http_fetch.h | 41 + include/haproxy/http_htx-t.h | 95 + include/haproxy/http_htx.h | 82 + include/haproxy/http_rules.h | 55 + include/haproxy/htx-t.h | 225 + include/haproxy/htx.h | 862 + include/haproxy/init-t.h | 64 + include/haproxy/init.h | 79 + include/haproxy/initcall.h | 257 + include/haproxy/intops.h | 494 + include/haproxy/istbuf.h | 162 + include/haproxy/jwt-t.h | 86 + include/haproxy/jwt.h | 37 + include/haproxy/lb_chash-t.h | 40 + include/haproxy/lb_chash.h | 41 + include/haproxy/lb_fas-t.h | 39 + include/haproxy/lb_fas.h | 40 + include/haproxy/lb_fwlc-t.h | 39 + include/haproxy/lb_fwlc.h | 40 + include/haproxy/lb_fwrr-t.h | 50 + include/haproxy/lb_fwrr.h | 40 + include/haproxy/lb_map-t.h | 40 + include/haproxy/lb_map.h | 41 + include/haproxy/list-t.h | 73 + include/haproxy/list.h | 817 + include/haproxy/listener-t.h | 320 + include/haproxy/listener.h | 204 + include/haproxy/log-t.h | 254 + include/haproxy/log.h | 198 + include/haproxy/mailers-t.h | 83 + include/haproxy/mailers.h | 41 + include/haproxy/map-t.h | 34 + include/haproxy/map.h | 39 + include/haproxy/mqtt-t.h | 310 + include/haproxy/mqtt.h | 118 + include/haproxy/mux_quic-t.h | 208 + include/haproxy/mux_quic.h | 151 + include/haproxy/mworker-t.h | 51 + include/haproxy/mworker.h | 48 + include/haproxy/namespace-t.h | 39 + include/haproxy/namespace.h | 47 + include/haproxy/ncbuf-t.h | 104 + include/haproxy/ncbuf.h | 54 + include/haproxy/net_helper.h | 387 + include/haproxy/obj_type-t.h | 56 + include/haproxy/obj_type.h | 213 + include/haproxy/openssl-compat.h | 518 + include/haproxy/pattern-t.h | 230 + include/haproxy/pattern.h | 270 + include/haproxy/payload.h | 39 + include/haproxy/peers-t.h | 142 + include/haproxy/peers.h | 67 + include/haproxy/pipe-t.h | 43 + include/haproxy/pipe.h | 54 + include/haproxy/pool-os.h | 84 + include/haproxy/pool-t.h | 137 + include/haproxy/pool.h | 257 + include/haproxy/port_range-t.h | 40 + include/haproxy/port_range.h | 105 + include/haproxy/proto_quic.h | 29 + include/haproxy/proto_sockpair.h | 32 + include/haproxy/proto_tcp.h | 45 + include/haproxy/proto_udp.h | 41 + include/haproxy/proto_uxst.h | 34 + include/haproxy/protobuf-t.h | 87 + include/haproxy/protobuf.h | 577 + include/haproxy/protocol-t.h | 141 + include/haproxy/protocol.h | 97 + include/haproxy/proxy-t.h | 547 + include/haproxy/proxy.h | 219 + include/haproxy/qmux_http.h | 19 + include/haproxy/qmux_trace.h | 67 + include/haproxy/qpack-dec.h | 51 + include/haproxy/qpack-enc.h | 12 + include/haproxy/qpack-t.h | 47 + include/haproxy/qpack-tbl-t.h | 65 + include/haproxy/qpack-tbl.h | 170 + include/haproxy/queue-t.h | 59 + include/haproxy/queue.h | 134 + include/haproxy/quic_cc-t.h | 93 + include/haproxy/quic_cc.h | 75 + include/haproxy/quic_conn-t.h | 734 + include/haproxy/quic_conn.h | 732 + include/haproxy/quic_enc.h | 270 + include/haproxy/quic_frame-t.h | 305 + include/haproxy/quic_frame.h | 197 + include/haproxy/quic_loss-t.h | 60 + include/haproxy/quic_loss.h | 87 + include/haproxy/quic_sock-t.h | 21 + include/haproxy/quic_sock.h | 56 + include/haproxy/quic_stats-t.h | 97 + include/haproxy/quic_stats.h | 14 + include/haproxy/quic_stream-t.h | 48 + include/haproxy/quic_stream.h | 23 + include/haproxy/quic_tls-t.h | 167 + include/haproxy/quic_tls.h | 690 + include/haproxy/quic_tp-t.h | 118 + include/haproxy/quic_tp.h | 103 + include/haproxy/receiver-t.h | 81 + include/haproxy/regex-t.h | 78 + include/haproxy/regex.h | 144 + include/haproxy/resolvers-t.h | 297 + include/haproxy/resolvers.h | 66 + include/haproxy/ring-t.h | 114 + include/haproxy/ring.h | 50 + include/haproxy/sample-t.h | 309 + include/haproxy/sample.h | 182 + include/haproxy/sample_data-t.h | 51 + include/haproxy/sc_strm.h | 384 + include/haproxy/server-t.h | 459 + include/haproxy/server.h | 311 + include/haproxy/session-t.h | 78 + include/haproxy/session.h | 323 + include/haproxy/shctx-t.h | 59 + include/haproxy/shctx.h | 76 + include/haproxy/signal-t.h | 66 + include/haproxy/signal.h | 52 + include/haproxy/sink-t.h | 76 + include/haproxy/sink.h | 89 + include/haproxy/sock-t.h | 37 + include/haproxy/sock.h | 61 + include/haproxy/sock_inet.h | 46 + include/haproxy/sock_unix.h | 36 + include/haproxy/spoe-t.h | 412 + include/haproxy/spoe.h | 351 + include/haproxy/ssl_ckch-t.h | 158 + include/haproxy/ssl_ckch.h | 74 + include/haproxy/ssl_crtlist-t.h | 63 + include/haproxy/ssl_crtlist.h | 48 + include/haproxy/ssl_sock-t.h | 299 + include/haproxy/ssl_sock.h | 193 + include/haproxy/ssl_utils.h | 47 + include/haproxy/stats-t.h | 600 + include/haproxy/stats.h | 145 + include/haproxy/stconn-t.h | 196 + include/haproxy/stconn.h | 406 + include/haproxy/stick_table-t.h | 230 + include/haproxy/stick_table.h | 400 + include/haproxy/stream-t.h | 232 + include/haproxy/stream.h | 384 + include/haproxy/task-t.h | 150 + include/haproxy/task.h | 833 + include/haproxy/tcp_rules.h | 52 + include/haproxy/tcpcheck-t.h | 242 + include/haproxy/tcpcheck.h | 125 + include/haproxy/thread-t.h | 157 + include/haproxy/thread.h | 500 + include/haproxy/ticks.h | 157 + include/haproxy/time.h | 474 + include/haproxy/tinfo-t.h | 112 + include/haproxy/tinfo.h | 38 + include/haproxy/tools-t.h | 160 + include/haproxy/tools.h | 1107 + include/haproxy/trace-t.h | 186 + include/haproxy/trace.h | 214 + include/haproxy/uri_auth-t.h | 56 + include/haproxy/uri_auth.h | 44 + include/haproxy/uri_normalizer-t.h | 31 + include/haproxy/uri_normalizer.h | 44 + include/haproxy/vars-t.h | 71 + include/haproxy/vars.h | 72 + include/haproxy/version.h | 86 + include/haproxy/xref-t.h | 45 + include/haproxy/xref.h | 105 + include/haproxy/xxhash.h | 52 + include/import/atomic-ops.h | 569 + include/import/eb32sctree.h | 121 + include/import/eb32tree.h | 482 + include/import/eb64tree.h | 575 + include/import/ebimtree.h | 324 + include/import/ebistree.h | 329 + include/import/ebmbtree.h | 847 + include/import/ebpttree.h | 156 + include/import/ebsttree.h | 324 + include/import/ebtree-t.h | 217 + include/import/ebtree.h | 857 + include/import/ist.h | 909 + include/import/lru.h | 75 + include/import/mjson.h | 209 + include/import/plock.h | 439 + include/import/sha1.h | 35 + include/import/slz-tables.h | 240 + include/import/slz.h | 171 + include/import/xxhash.h | 4766 ++++ reg-tests/README | 71 + reg-tests/balance/balance-rr.vtc | 73 + reg-tests/balance/balance-uri-path-only.vtc | 97 + reg-tests/balance/balance-uri.vtc | 74 + reg-tests/cache/basic.vtc | 55 + reg-tests/cache/caching_rules.vtc | 256 + reg-tests/cache/expires.vtc | 127 + reg-tests/cache/if-modified-since.vtc | 154 + reg-tests/cache/if-none-match.vtc | 93 + reg-tests/cache/post_on_entry.vtc | 65 + reg-tests/cache/sample_fetches.vtc | 139 + reg-tests/cache/vary.vtc | 410 + reg-tests/cache/vary_accept_encoding.vtc | 333 + reg-tests/checks/1be_40srv_odd_health_checks.vtc | 117 + reg-tests/checks/40be_2srv_odd_health_checks.vtc | 645 + reg-tests/checks/4be_1srv_health_checks.vtc | 201 + .../4be_1srv_smtpchk_httpchk_layer47errors.vtc | 99 + reg-tests/checks/agent-check.vtc | 42 + reg-tests/checks/common.pem | 1 + reg-tests/checks/http-check-expect.vtc | 64 + reg-tests/checks/http-check-send.vtc | 168 + reg-tests/checks/http-check.vtc | 157 + reg-tests/checks/http-monitor-uri.vtc | 56 + reg-tests/checks/ldap-check.vtc | 96 + reg-tests/checks/mysql-check.vtc | 123 + reg-tests/checks/pgsql-check.vtc | 93 + reg-tests/checks/redis-check.vtc | 61 + reg-tests/checks/smtp-check.vtc | 110 + reg-tests/checks/spop-check.vtc | 94 + reg-tests/checks/ssl-hello-check.vtc | 76 + reg-tests/checks/tcp-check-ssl.vtc | 118 + reg-tests/checks/tcp-check_min-recv.vtc | 68 + reg-tests/checks/tcp-check_multiple_ports.vtc | 48 + reg-tests/checks/tcp-checks-socks4.vtc | 61 + reg-tests/checks/tls_health_checks.vtc | 118 + reg-tests/compression/basic.vtc | 378 + reg-tests/compression/common.pem | 1 + reg-tests/compression/etags_conversion.vtc | 231 + reg-tests/compression/lua_validation.lua | 19 + reg-tests/compression/lua_validation.vtc | 59 + reg-tests/compression/vary.vtc | 192 + reg-tests/connection/cli_src_dst.vtc | 290 + reg-tests/connection/common.pem | 1 + reg-tests/connection/dispatch.vtc | 42 + reg-tests/connection/http_reuse_aggressive.vtc | 45 + reg-tests/connection/http_reuse_always.vtc | 43 + reg-tests/connection/http_reuse_be_transparent.vtc | 81 + reg-tests/connection/http_reuse_conn_hash.vtc | 163 + reg-tests/connection/http_reuse_dispatch.vtc | 79 + reg-tests/connection/http_reuse_never.vtc | 79 + reg-tests/connection/http_reuse_safe.vtc | 78 + .../connection/proxy_protocol_random_fail.vtc | 60 + .../connection/proxy_protocol_send_unique_id.vtc | 42 + .../proxy_protocol_send_unique_id_alpn.vtc | 33 + .../connection/proxy_protocol_tlv_validation.vtc | 142 + reg-tests/connection/tcp_to_http_upgrade.vtc | 162 + reg-tests/contrib/prometheus.vtc | 113 + reg-tests/converter/add_item.vtc | 50 + reg-tests/converter/be2dec.vtc | 56 + reg-tests/converter/be2hex.vtc | 60 + reg-tests/converter/digest.vtc | 57 + reg-tests/converter/field.vtc | 39 + reg-tests/converter/fix.vtc | 235 + reg-tests/converter/hmac.vtc | 55 + reg-tests/converter/iif.vtc | 46 + reg-tests/converter/json.vtc | 40 + reg-tests/converter/json_query.vtc | 101 + reg-tests/converter/mqtt.vtc | 238 + reg-tests/converter/secure_memcmp.vtc | 143 + reg-tests/converter/sha2.vtc | 57 + reg-tests/converter/url_dec.vtc | 37 + reg-tests/converter/url_enc.vtc | 43 + reg-tests/filters/random-forwarding.vtc | 139 + reg-tests/http-capture/multiple_headers.vtc | 91 + reg-tests/http-cookies/cookie_insert_indirect.vtc | 54 + reg-tests/http-cookies/h2_cookie_concat.vtc | 42 + reg-tests/http-errorfiles/errorfiles.vtc | 51 + reg-tests/http-errorfiles/errors/400-1.http | 9 + reg-tests/http-errorfiles/errors/400-2.http | 9 + reg-tests/http-errorfiles/errors/400-3.http | 9 + reg-tests/http-errorfiles/errors/400.http | 9 + reg-tests/http-errorfiles/errors/403-1.http | 9 + reg-tests/http-errorfiles/errors/403-2.http | 9 + reg-tests/http-errorfiles/errors/403.http | 9 + reg-tests/http-errorfiles/errors/404-1.http | 9 + reg-tests/http-errorfiles/errors/404-2.http | 9 + reg-tests/http-errorfiles/errors/404-3.http | 9 + reg-tests/http-errorfiles/errors/404.http | 9 + reg-tests/http-errorfiles/errors/500-1.http | 9 + reg-tests/http-errorfiles/errors/500.http | 9 + reg-tests/http-errorfiles/errors/lf-403.txt | 1 + reg-tests/http-errorfiles/http-error.vtc | 75 + reg-tests/http-errorfiles/http_deny_errors.vtc | 77 + reg-tests/http-errorfiles/http_errors.vtc | 134 + reg-tests/http-errorfiles/http_return.vtc | 46 + reg-tests/http-messaging/common.pem | 1 + reg-tests/http-messaging/h1_host_normalization.vtc | 603 + reg-tests/http-messaging/h1_to_h1.vtc | 275 + reg-tests/http-messaging/h2_desync_attacks.vtc | 167 + reg-tests/http-messaging/h2_to_h1.vtc | 265 + reg-tests/http-messaging/http_abortonclose.vtc | 142 + .../http-messaging/http_bodyless_response.vtc | 127 + reg-tests/http-messaging/http_msg_full_on_eom.vtc | 62 + reg-tests/http-messaging/http_request_buffer.vtc | 135 + reg-tests/http-messaging/http_splicing.vtc | 75 + .../http-messaging/http_transfer_encoding.vtc | 202 + reg-tests/http-messaging/http_wait_for_body.vtc | 171 + reg-tests/http-messaging/protocol_upgrade.vtc | 228 + .../http-messaging/scheme_based_normalize.vtc | 125 + reg-tests/http-messaging/srv_ws.vtc | 180 + reg-tests/http-messaging/websocket.vtc | 205 + reg-tests/http-rules/1k.txt | 16 + reg-tests/http-rules/acl_cli_spaces.vtc | 79 + reg-tests/http-rules/agents.acl | 1 + .../converters_ipmask_concat_strcmp_field_word.map | 1 + .../converters_ipmask_concat_strcmp_field_word.vtc | 218 + reg-tests/http-rules/default_rules.vtc | 159 + reg-tests/http-rules/del_header.vtc | 93 + .../http-rules/except-forwardfor-originalto.vtc | 143 + reg-tests/http-rules/h1_to_h1c.vtc | 186 + reg-tests/http-rules/h1or2_to_h1c.vtc | 226 + reg-tests/http-rules/http_after_response.vtc | 192 + reg-tests/http-rules/http_return.vtc | 99 + reg-tests/http-rules/lf-file.txt | 1 + reg-tests/http-rules/map_redirect-be.map | 4 + reg-tests/http-rules/map_redirect.map | 5 + reg-tests/http-rules/map_redirect.vtc | 200 + reg-tests/http-rules/map_regm_with_backref.map | 1 + reg-tests/http-rules/map_regm_with_backref.vtc | 73 + reg-tests/http-rules/normalize_uri.vtc | 536 + reg-tests/http-rules/path_and_pathq.vtc | 64 + reg-tests/http-rules/restrict_req_hdr_names.vtc | 185 + reg-tests/http-rules/strict_rw_mode.vtc | 164 + reg-tests/http-set-timeout/set_timeout.vtc | 82 + reg-tests/jwt/build_token.py | 22 + reg-tests/jwt/es256-public.pem | 4 + reg-tests/jwt/es384-public.pem | 5 + reg-tests/jwt/es512-public.pem | 6 + reg-tests/jwt/jws_verify.vtc | 379 + reg-tests/jwt/rsa-public.pem | 14 + reg-tests/log/last_rule.vtc | 165 + reg-tests/log/load_balancing.vtc | 161 + reg-tests/log/log_forward.vtc | 57 + reg-tests/log/log_uri.vtc | 61 + reg-tests/log/wrong_ip_port_logging.vtc | 62 + reg-tests/lua/bad_http_clt_req_duration.lua | 8 + reg-tests/lua/bad_http_clt_req_duration.vtc | 76 + reg-tests/lua/close_wait_lf.lua | 1 + reg-tests/lua/close_wait_lf.vtc | 53 + reg-tests/lua/common.pem | 1 + reg-tests/lua/h_txn_get_priv.lua | 15 + reg-tests/lua/h_txn_get_priv.vtc | 33 + reg-tests/lua/httpclient_action.lua | 8 + reg-tests/lua/httpclient_action.vtc | 39 + reg-tests/lua/lua_httpclient.lua | 49 + reg-tests/lua/lua_httpclient.vtc | 68 + reg-tests/lua/lua_socket.lua | 44 + reg-tests/lua/lua_socket.vtc | 33 + reg-tests/lua/set_var.lua | 25 + reg-tests/lua/set_var.vtc | 83 + reg-tests/lua/txn_get_priv-print_r.lua | 96 + reg-tests/lua/txn_get_priv-thread.vtc | 69 + reg-tests/lua/txn_get_priv.lua | 180 + reg-tests/lua/txn_get_priv.vtc | 35 + reg-tests/lua/wrong_types_usage.lua | 3 + reg-tests/lua/wrong_types_usage.vtc | 77 + reg-tests/mailers/healthcheckmail.lua | 70 + reg-tests/mailers/healthcheckmail.vtc | 59 + reg-tests/mcli/mcli_show_info.vtc | 29 + reg-tests/mcli/mcli_start_progs.vtc | 37 + reg-tests/peers/basic_sync.vtc | 121 + reg-tests/peers/basic_sync_wo_stkt_backend.vtc | 116 + reg-tests/peers/common.pem | 1 + reg-tests/peers/tls_basic_sync.vtc | 158 + reg-tests/peers/tls_basic_sync_wo_stkt_backend.vtc | 152 + reg-tests/sample_fetches/cond_set_var.vtc | 362 + reg-tests/sample_fetches/cook.vtc | 37 + reg-tests/sample_fetches/hashes.vtc | 101 + reg-tests/sample_fetches/so_name.vtc | 22 + reg-tests/sample_fetches/srv_name.vtc | 46 + reg-tests/sample_fetches/ubase64.vtc | 57 + reg-tests/sample_fetches/vars.vtc | 84 + reg-tests/seamless-reload/abns_socket.vtc | 53 + reg-tests/server/cli_add_check_server.vtc | 161 + reg-tests/server/cli_add_server.vtc | 87 + reg-tests/server/cli_add_ssl_server.vtc | 110 + reg-tests/server/cli_add_track_server.vtc | 242 + reg-tests/server/cli_delete_dynamic_server.vtc | 94 + reg-tests/server/cli_delete_server.vtc | 60 + reg-tests/server/cli_delete_server_lua.vtc | 43 + reg-tests/server/cli_set_fdqn.vtc | 32 + reg-tests/server/cli_set_ssl.vtc | 60 + reg-tests/server/common.pem | 1 + reg-tests/server/get_srv_stats.lua | 11 + reg-tests/spoe/wrong_init.vtc | 22 + reg-tests/ssl/README | 2 + reg-tests/ssl/add_ssl_crt-list.vtc | 114 + reg-tests/ssl/ca-auth.crt | 33 + reg-tests/ssl/cert1-example.com.pem.ecdsa | 17 + reg-tests/ssl/cert1-example.com.pem.rsa | 80 + reg-tests/ssl/cert2-example.com.pem.ecdsa | 17 + reg-tests/ssl/cert2-example.com.pem.rsa | 80 + reg-tests/ssl/client.ecdsa.pem | 28 + reg-tests/ssl/client1.pem | 187 + reg-tests/ssl/client2_expired.pem | 81 + reg-tests/ssl/client3_revoked.pem | 81 + reg-tests/ssl/common.4096.dh | 13 + reg-tests/ssl/common.crt | 90 + reg-tests/ssl/common.key | 28 + reg-tests/ssl/common.pem | 117 + reg-tests/ssl/crl-auth.pem | 18 + reg-tests/ssl/del_ssl_crt-list.vtc | 102 + reg-tests/ssl/dynamic_server_ssl.vtc | 113 + reg-tests/ssl/ecdsa.crt | 12 + reg-tests/ssl/ecdsa.key | 6 + reg-tests/ssl/ecdsa.pem | 17 + reg-tests/ssl/filters.crt-list | 2 + .../ssl/generate_certificates/gen_cert_ca.pem | 23 + .../ssl/generate_certificates/gen_cert_server.pem | 18 + reg-tests/ssl/interCA1_crl.pem | 27 + reg-tests/ssl/interCA1_crl_empty.pem | 27 + reg-tests/ssl/interCA2_crl.pem | 27 + reg-tests/ssl/interCA2_crl_empty.pem | 27 + reg-tests/ssl/localhost.crt-list | 5 + reg-tests/ssl/log_forward_ssl.vtc | 60 + reg-tests/ssl/new_del_ssl_cafile.vtc | 137 + reg-tests/ssl/new_del_ssl_crlfile.vtc | 139 + reg-tests/ssl/rootCA_crl.pem | 16 + reg-tests/ssl/set_cafile_client.pem | 95 + reg-tests/ssl/set_cafile_interCA1.crt | 24 + reg-tests/ssl/set_cafile_interCA2.crt | 24 + reg-tests/ssl/set_cafile_rootCA.crt | 30 + reg-tests/ssl/set_cafile_server.pem | 95 + reg-tests/ssl/set_default_cert.crt-list | 2 + reg-tests/ssl/set_default_cert.pem | 52 + reg-tests/ssl/set_ssl_cafile.vtc | 165 + reg-tests/ssl/set_ssl_cert.vtc | 206 + reg-tests/ssl/set_ssl_cert_bundle.vtc | 111 + reg-tests/ssl/set_ssl_cert_noext.vtc | 90 + reg-tests/ssl/set_ssl_crlfile.vtc | 146 + reg-tests/ssl/set_ssl_server_cert.vtc | 129 + reg-tests/ssl/show_ocsp_server.pem | 119 + reg-tests/ssl/show_ocsp_server.pem.issuer | 30 + reg-tests/ssl/show_ocsp_server.pem.ocsp | Bin 0 -> 2281 bytes reg-tests/ssl/show_ocsp_server.pem.ocsp.revoked | Bin 0 -> 2298 bytes reg-tests/ssl/show_ssl_ocspresponse.vtc | 135 + reg-tests/ssl/simple.crt-list | 5 + reg-tests/ssl/ssl_client_auth.vtc | 83 + reg-tests/ssl/ssl_client_samples.vtc | 72 + reg-tests/ssl/ssl_crt-list_filters.vtc | 64 + reg-tests/ssl/ssl_curves.vtc | 134 + reg-tests/ssl/ssl_default_server.vtc | 142 + reg-tests/ssl/ssl_dh.vtc | 233 + reg-tests/ssl/ssl_errors.vtc | 439 + reg-tests/ssl/ssl_frontend_samples.vtc | 69 + reg-tests/ssl/ssl_generate_certificate.vtc | 168 + reg-tests/ssl/ssl_reuse.vtc | 141 + reg-tests/ssl/ssl_server_samples.vtc | 73 + reg-tests/ssl/ssl_simple_crt-list.vtc | 50 + reg-tests/ssl/wrong_ctx_storage.vtc | 45 + reg-tests/startup/automatic_maxconn.vtc | 104 + reg-tests/startup/check_condition.vtc | 32 + reg-tests/startup/common.pem | 117 + reg-tests/startup/default_rules.vtc | 185 + .../stick-table/converteers_ref_cnt_never_dec.vtc | 75 + reg-tests/stick-table/src_conn_rate.vtc | 43 + reg-tests/stick-table/unknown_key.vtc | 32 + reg-tests/stickiness/lb-services.vtc | 291 + reg-tests/stickiness/srvkey-addr.vtc | 260 + reg-tests/stream/unique-id-from-proxy.vtc | 38 + reg-tests/stream/unique-id.vtc | 49 + reg-tests/tcp-rules/default_rules.vtc | 61 + .../webstats/webstats-scope-and-post-change.vtc | 84 + scripts/announce-release | 279 + scripts/backport | 146 + scripts/build-ot.sh | 27 + scripts/build-ssl.sh | 146 + scripts/build-vtest.sh | 10 + scripts/create-release | 237 + scripts/git-show-backports | 273 + scripts/make-releases-json | 103 + scripts/publish-release | 191 + scripts/run-regtests.sh | 416 + src/acl.c | 1378 ++ src/action.c | 348 + src/activity.c | 996 + src/applet.c | 269 + src/arg.c | 479 + src/auth.c | 316 + src/backend.c | 3379 +++ src/base64.c | 303 + src/cache.c | 2764 +++ src/calltrace.c | 286 + src/cbuf.c | 59 + src/cfgcond.c | 521 + src/cfgdiag.c | 97 + src/cfgparse-global.c | 1304 + src/cfgparse-listen.c | 3207 +++ src/cfgparse-quic.c | 143 + src/cfgparse-ssl.c | 2027 ++ src/cfgparse-tcp.c | 296 + src/cfgparse-unix.c | 135 + src/cfgparse.c | 4570 ++++ src/channel.c | 591 + src/check.c | 2363 ++ src/chunk.c | 317 + src/cli.c | 3210 +++ src/clock.c | 405 + src/compression.c | 740 + src/connection.c | 2454 ++ src/cpuset.c | 120 + src/debug.c | 1467 ++ src/dgram.c | 30 + src/dict.c | 127 + src/dns.c | 1350 ++ src/dynbuf.c | 129 + src/eb32sctree.c | 472 + src/eb32tree.c | 218 + src/eb64tree.c | 218 + src/ebimtree.c | 44 + src/ebistree.c | 42 + src/ebmbtree.c | 77 + src/ebpttree.c | 208 + src/ebsttree.c | 42 + src/ebtree.c | 50 + src/errors.c | 380 + src/ev_epoll.c | 407 + src/ev_evports.c | 447 + src/ev_kqueue.c | 386 + src/ev_poll.c | 343 + src/ev_select.c | 332 + src/extcheck.c | 678 + src/fcgi-app.c | 1152 + src/fcgi.c | 294 + src/fd.c | 1214 + src/filters.c | 1133 + src/fix.c | 264 + src/flt_http_comp.c | 872 + src/flt_spoe.c | 4785 ++++ src/flt_trace.c | 675 + src/freq_ctr.c | 104 + src/frontend.c | 312 + src/h1.c | 1278 + src/h1_htx.c | 1072 + src/h2.c | 814 + src/h3.c | 1545 ++ src/h3_stats.c | 276 + src/haproxy.c | 3674 +++ src/hash.c | 189 + src/hlua.c | 12681 ++++++++++ src/hlua_fcn.c | 1780 ++ src/hpack-dec.c | 475 + src/hpack-enc.c | 210 + src/hpack-huff.c | 1532 ++ src/hpack-tbl.c | 372 + src/hq_interop.c | 172 + src/http.c | 1309 + src/http_acl.c | 185 + src/http_act.c | 2498 ++ src/http_ana.c | 5277 +++++ src/http_client.c | 1429 ++ src/http_conv.c | 453 + src/http_fetch.c | 2248 ++ src/http_htx.c | 2915 +++ src/http_rules.c | 498 + src/htx.c | 1087 + src/init.c | 249 + src/jwt.c | 461 + src/lb_chash.c | 517 + src/lb_fas.c | 348 + src/lb_fwlc.c | 375 + src/lb_fwrr.c | 623 + src/lb_map.c | 281 + src/listener.c | 1956 ++ src/log.c | 3968 ++++ src/lru.c | 305 + src/mailers.c | 321 + src/map.c | 1229 + src/mjson.c | 1048 + src/mqtt.c | 1281 + src/mux_fcgi.c | 4318 ++++ src/mux_h1.c | 4316 ++++ src/mux_h2.c | 7149 ++++++ src/mux_pt.c | 709 + src/mux_quic.c | 2321 ++ src/mworker-prog.c | 356 + src/mworker.c | 743 + src/namespace.c | 131 + src/ncbuf.c | 984 + src/pattern.c | 2702 +++ src/payload.c | 1448 ++ src/peers.c | 4076 ++++ src/pipe.c | 136 + src/pool.c | 1108 + src/proto_quic.c | 719 + src/proto_sockpair.c | 564 + src/proto_tcp.c | 824 + src/proto_udp.c | 234 + src/proto_uxdg.c | 152 + src/proto_uxst.c | 361 + src/protocol.c | 237 + src/proxy.c | 3373 +++ src/qmux_http.c | 131 + src/qmux_trace.c | 108 + src/qpack-dec.c | 563 + src/qpack-enc.c | 185 + src/qpack-tbl.c | 415 + src/queue.c | 761 + src/quic_cc.c | 49 + src/quic_cc_cubic.c | 283 + src/quic_cc_newreno.c | 173 + src/quic_conn.c | 7565 ++++++ src/quic_frame.c | 1168 + src/quic_loss.c | 205 + src/quic_sock.c | 595 + src/quic_stats.c | 204 + src/quic_stream.c | 267 + src/quic_tls.c | 672 + src/quic_tp.c | 711 + src/raw_sock.c | 489 + src/regex.c | 459 + src/resolvers.c | 3801 +++ src/ring.c | 444 + src/sample.c | 4452 ++++ src/server.c | 6074 +++++ src/server_state.c | 931 + src/session.c | 460 + src/sha1.c | 308 + src/shctx.c | 355 + src/signal.c | 284 + src/sink.c | 1434 ++ src/slz.c | 1341 ++ src/sock.c | 1000 + src/sock_inet.c | 488 + src/sock_unix.c | 350 + src/ssl_ckch.c | 3938 +++ src/ssl_crtlist.c | 1510 ++ src/ssl_sample.c | 2225 ++ src/ssl_sock.c | 8319 +++++++ src/ssl_utils.c | 419 + src/stats.c | 5361 +++++ src/stconn.c | 2012 ++ src/stick_table.c | 5190 ++++ src/stream.c | 3976 ++++ src/task.c | 1044 + src/tcp_act.c | 572 + src/tcp_rules.c | 1428 ++ src/tcp_sample.c | 530 + src/tcpcheck.c | 5209 ++++ src/thread.c | 1371 ++ src/time.c | 147 + src/tools.c | 5853 +++++ src/trace.c | 761 + src/uri_auth.c | 318 + src/uri_normalizer.c | 467 + src/vars.c | 1453 ++ src/version.c | 28 + src/wdt.c | 189 + src/xprt_handshake.c | 299 + src/xprt_quic.c | 167 + tests/conf/basic-check.cfg | 34 + tests/conf/ext-check.cfg | 26 + tests/conf/ports.cfg | 74 + tests/conf/setstatus.lua | 26 + tests/conf/tcp-check.cfg | 74 + tests/conf/test-acl-args.cfg | 36 + tests/conf/test-address-syntax.cfg | 84 + tests/conf/test-backlog.cfg | 22 + tests/conf/test-check-expect.cfg | 87 + tests/conf/test-connection.cfg | 34 + tests/conf/test-cookie-indirect.cfg | 47 + tests/conf/test-cookie-insert.cfg | 35 + tests/conf/test-cookie-passive.cfg | 35 + tests/conf/test-cookie-prefix.cfg | 35 + tests/conf/test-cookie-rewrite.cfg | 35 + tests/conf/test-disable-404.cfg | 61 + tests/conf/test-fsm.cfg | 346 + tests/conf/test-fwlc.cfg | 61 + tests/conf/test-fwrr.cfg | 51 + tests/conf/test-handshakes-chk.cfg | 148 + tests/conf/test-handshakes.cfg | 135 + tests/conf/test-http-send-name-hdr.cfg | 33 + tests/conf/test-http-set-status-lua.cfg | 31 + tests/conf/test-http-set-status.cfg | 32 + tests/conf/test-inspect-smtp.cfg | 44 + tests/conf/test-inspect-ssl.cfg | 37 + tests/conf/test-map-ports.cfg | 31 + tests/conf/test-param-hash.cfg | 23 + tests/conf/test-pollers.cfg | 15 + tests/conf/test-redirect.cfg | 49 + tests/conf/test-sample-fetch-args.cfg | 36 + tests/conf/test-sample-fetch-conv.cfg | 42 + tests/conf/test-sql.cfg | 29 + tests/conf/test-srv-verify.cfg | 57 + tests/conf/test-stats.cfg | 5045 ++++ tests/conf/test-str2sa.cfg | 60 + tests/conf/test-time.cfg | 24 + tests/conf/test-timeout.cfg | 27 + tests/conf/test-url-hash.cfg | 40 + tests/conf/test-valid-names.cfg | 37 + tests/exp/blocksig.c | 16 + tests/exp/filltab25.c | 399 + tests/exp/hash_results.txt | 218 + tests/exp/hashing-results.txt | 314 + tests/exp/io_limits.txt | 116 + tests/exp/ip-hash.c | 202 + tests/exp/test_hashes.c | 559 + tests/exp/testinet.c | 28 + tests/exp/uri_hash.c | 377 + tests/unit/ist.c | 700 + tests/unit/test-arg.c | 44 + tests/unit/test-inherited-fd.py | 23 + tests/unit/test-list.c | 98 + tests/unit/test-sockpair.py | 28 + 1091 files changed, 440300 insertions(+) create mode 100644 .cirrus.yml create mode 100644 .gitattributes create mode 100644 .github/ISSUE_TEMPLATE/Bug.yml create mode 100644 .github/ISSUE_TEMPLATE/Code-Report.yml create mode 100644 .github/ISSUE_TEMPLATE/Feature.yml create mode 100644 .github/ISSUE_TEMPLATE/config.yml create mode 100644 .github/errorfile create mode 100644 .github/h2spec.config create mode 100755 .github/matrix.py create mode 100644 .github/vtest.json create mode 100644 .github/workflows/codespell.yml create mode 100644 .github/workflows/compliance.yml create mode 100644 .github/workflows/contrib.yml create mode 100644 .github/workflows/coverity.yml create mode 100644 .github/workflows/cross-zoo.yml create mode 100644 .github/workflows/musl.yml create mode 100644 .github/workflows/openssl-nodeprecated.yml create mode 100644 .github/workflows/vtest.yml create mode 100644 .github/workflows/windows.yml create mode 100644 .gitignore create mode 100644 .mailmap create mode 100644 .travis.yml create mode 100644 BRANCHES create mode 100644 CHANGELOG create mode 100644 CONTRIBUTING create mode 100644 INSTALL create mode 100644 LICENSE create mode 100644 MAINTAINERS create mode 100644 Makefile create mode 100644 README create mode 100644 SUBVERS create mode 100644 VERDATE create mode 100644 VERSION create mode 100644 addons/51degrees/51d.c create mode 100644 addons/51degrees/dummy/cityhash/city.c create mode 100644 addons/51degrees/dummy/pattern/51Degrees.c create mode 100644 addons/51degrees/dummy/pattern/51Degrees.h create mode 100644 addons/51degrees/dummy/threading.c create mode 100644 addons/51degrees/dummy/trie/51Degrees.c create mode 100644 addons/51degrees/dummy/trie/51Degrees.h create mode 100644 addons/deviceatlas/Makefile create mode 100644 addons/deviceatlas/da.c create mode 100644 addons/deviceatlas/dadwsch.c create mode 100644 addons/deviceatlas/dummy/Makefile create mode 100644 addons/deviceatlas/dummy/Os/daunix.c create mode 100644 addons/deviceatlas/dummy/dac.c create mode 100644 addons/deviceatlas/dummy/dac.h create mode 100644 addons/deviceatlas/dummy/dadwcom.c create mode 100644 addons/deviceatlas/dummy/dasch.c create mode 100644 addons/deviceatlas/dummy/json.c create mode 100644 addons/ot/AUTHORS create mode 100644 addons/ot/MAINTAINERS create mode 100644 addons/ot/Makefile create mode 100644 addons/ot/README create mode 100644 addons/ot/README-func create mode 100644 addons/ot/README-pool create mode 100644 addons/ot/include/cli.h create mode 100644 addons/ot/include/conf.h create mode 100644 addons/ot/include/config.h create mode 100644 addons/ot/include/debug.h create mode 100644 addons/ot/include/define.h create mode 100644 addons/ot/include/event.h create mode 100644 addons/ot/include/filter.h create mode 100644 addons/ot/include/group.h create mode 100644 addons/ot/include/http.h create mode 100644 addons/ot/include/include.h create mode 100644 addons/ot/include/opentracing.h create mode 100644 addons/ot/include/parser.h create mode 100644 addons/ot/include/pool.h create mode 100644 addons/ot/include/scope.h create mode 100644 addons/ot/include/util.h create mode 100644 addons/ot/include/vars.h create mode 100644 addons/ot/src/cli.c create mode 100644 addons/ot/src/conf.c create mode 100644 addons/ot/src/event.c create mode 100644 addons/ot/src/filter.c create mode 100644 addons/ot/src/group.c create mode 100644 addons/ot/src/http.c create mode 100644 addons/ot/src/opentracing.c create mode 100644 addons/ot/src/parser.c create mode 100644 addons/ot/src/pool.c create mode 100644 addons/ot/src/scope.c create mode 100644 addons/ot/src/util.c create mode 100644 addons/ot/src/vars.c create mode 100644 addons/ot/test/README-speed-cmp create mode 100644 addons/ot/test/README-speed-ctx create mode 100644 addons/ot/test/README-speed-fe-be create mode 100644 addons/ot/test/README-speed-sa create mode 100644 addons/ot/test/be/cfg-dd.json create mode 100644 addons/ot/test/be/cfg-jaeger.yml create mode 100644 addons/ot/test/be/cfg-zipkin.json create mode 100644 addons/ot/test/be/haproxy.cfg create mode 100644 addons/ot/test/be/ot.cfg create mode 100644 addons/ot/test/cmp/cfg-dd.json create mode 100644 addons/ot/test/cmp/cfg-jaeger.yml create mode 100644 addons/ot/test/cmp/cfg-zipkin.json create mode 100644 addons/ot/test/cmp/haproxy.cfg create mode 100644 addons/ot/test/cmp/ot.cfg create mode 100644 addons/ot/test/ctx/cfg-dd.json create mode 100644 addons/ot/test/ctx/cfg-jaeger.yml create mode 100644 addons/ot/test/ctx/cfg-zipkin.json create mode 100644 addons/ot/test/ctx/haproxy.cfg create mode 100644 addons/ot/test/ctx/ot.cfg create mode 100644 addons/ot/test/empty/cfg-dd.json create mode 100644 addons/ot/test/empty/cfg-jaeger.yml create mode 100644 addons/ot/test/empty/cfg-zipkin.json create mode 100644 addons/ot/test/empty/haproxy.cfg create mode 100644 addons/ot/test/empty/ot.cfg create mode 100644 addons/ot/test/fe/cfg-dd.json create mode 100644 addons/ot/test/fe/cfg-jaeger.yml create mode 100644 addons/ot/test/fe/cfg-zipkin.json create mode 100644 addons/ot/test/fe/haproxy.cfg create mode 100644 addons/ot/test/fe/ot.cfg create mode 100755 addons/ot/test/func-stat.sh create mode 100755 addons/ot/test/get-opentracing-plugins.sh create mode 100644 addons/ot/test/index.html create mode 100755 addons/ot/test/run-cmp.sh create mode 100755 addons/ot/test/run-ctx.sh create mode 100755 addons/ot/test/run-fe-be.sh create mode 100755 addons/ot/test/run-sa.sh create mode 100644 addons/ot/test/sa/cfg-dd.json create mode 100644 addons/ot/test/sa/cfg-jaeger.yml create mode 100644 addons/ot/test/sa/cfg-zipkin.json create mode 100644 addons/ot/test/sa/haproxy.cfg create mode 100644 addons/ot/test/sa/ot.cfg create mode 100755 addons/ot/test/test-speed.sh create mode 100644 addons/promex/README create mode 100644 addons/promex/service-prometheus.c create mode 100644 addons/wurfl/dummy/Makefile create mode 100644 addons/wurfl/dummy/dummy-wurfl.c create mode 100644 addons/wurfl/dummy/wurfl/wurfl.h create mode 100644 addons/wurfl/wurfl.c create mode 100644 admin/dyncookie/dyncookie.c create mode 100644 admin/halog/README create mode 100644 admin/halog/fgets2.c create mode 100644 admin/halog/halog.c create mode 100644 admin/iprange/Makefile create mode 100644 admin/iprange/ip6range.c create mode 100644 admin/iprange/iprange.c create mode 100644 admin/netsnmp-perl/README create mode 100644 admin/netsnmp-perl/cacti_data_query_haproxy_backends.xml create mode 100644 admin/netsnmp-perl/cacti_data_query_haproxy_frontends.xml create mode 100644 admin/netsnmp-perl/haproxy.pl create mode 100644 admin/netsnmp-perl/haproxy_backend.xml create mode 100644 admin/netsnmp-perl/haproxy_frontend.xml create mode 100644 admin/netsnmp-perl/haproxy_socket.xml create mode 100644 admin/release-estimator/README.md create mode 100755 admin/release-estimator/release-estimator.py create mode 100644 admin/selinux/README create mode 100644 admin/selinux/haproxy.fc create mode 100644 admin/selinux/haproxy.if create mode 100644 admin/selinux/haproxy.te create mode 100644 admin/syntax-highlight/haproxy.vim create mode 100644 admin/systemd/Makefile create mode 100644 admin/systemd/haproxy.service.in create mode 100644 admin/wireshark-dissectors/peers/Makefile create mode 100644 admin/wireshark-dissectors/peers/README create mode 100644 admin/wireshark-dissectors/peers/packet-happp.c create mode 100644 admin/wireshark-dissectors/peers/wireshark.happp.dissector.patch create mode 100644 dev/base64/base64rev-gen.c create mode 100644 dev/coccinelle/bug_on.cocci create mode 100644 dev/coccinelle/cs_endp_flags.cocci create mode 100644 dev/coccinelle/endp_flags.cocci create mode 100644 dev/coccinelle/ha_free.cocci create mode 100644 dev/coccinelle/ist.cocci create mode 100644 dev/coccinelle/realloc_leak.cocci create mode 100644 dev/coccinelle/strcmp.cocci create mode 100644 dev/coccinelle/xalloc_cast.cocci create mode 100644 dev/coccinelle/xalloc_size.cocci create mode 100644 dev/flags/README create mode 100644 dev/flags/flags.c create mode 100755 dev/flags/show-fd-to-flags.sh create mode 100644 dev/haring/README create mode 100644 dev/haring/haring.c create mode 100644 dev/hpack/README create mode 100644 dev/hpack/decode.c create mode 100644 dev/hpack/gen-enc.c create mode 100644 dev/hpack/gen-rht.c create mode 100644 dev/plug_qdisc/README create mode 100644 dev/plug_qdisc/plug_qdisc.c create mode 100644 dev/poll/Makefile create mode 100644 dev/poll/poll.c create mode 100644 dev/tcploop/Makefile create mode 100644 dev/tcploop/tcploop.c create mode 100755 dev/trace/trace.awk create mode 100644 dev/udp/udp-perturb.c create mode 100644 doc/51Degrees-device-detection.txt create mode 100644 doc/DeviceAtlas-device-detection.txt create mode 100644 doc/SOCKS4.protocol.txt create mode 100644 doc/SPOE.txt create mode 100644 doc/WURFL-device-detection.txt create mode 100644 doc/acl.fig create mode 100644 doc/architecture.txt create mode 100644 doc/close-options.txt create mode 100644 doc/coding-style.txt create mode 100644 doc/configuration.txt create mode 100644 doc/cookie-options.txt create mode 100644 doc/design-thoughts/backends-v0.txt create mode 100644 doc/design-thoughts/backends.txt create mode 100644 doc/design-thoughts/be-fe-changes.txt create mode 100644 doc/design-thoughts/binding-possibilities.txt create mode 100644 doc/design-thoughts/config-language.txt create mode 100644 doc/design-thoughts/connection-reuse.txt create mode 100644 doc/design-thoughts/connection-sharing.txt create mode 100644 doc/design-thoughts/dynamic-buffers.txt create mode 100644 doc/design-thoughts/entities-v2.txt create mode 100644 doc/design-thoughts/how-it-works.txt create mode 100644 doc/design-thoughts/http2.txt create mode 100644 doc/design-thoughts/http_load_time.url create mode 100644 doc/design-thoughts/pool-debugging.txt create mode 100644 doc/design-thoughts/rate-shaping.txt create mode 100644 doc/design-thoughts/sess_par_sec.txt create mode 100644 doc/design-thoughts/thread-group.txt create mode 100644 doc/gpl.txt create mode 100644 doc/haproxy.1 create mode 100644 doc/internals/acl.txt create mode 100644 doc/internals/api/appctx.txt create mode 100644 doc/internals/api/buffer-api.txt create mode 100644 doc/internals/api/filters.txt create mode 100644 doc/internals/api/htx-api.txt create mode 100644 doc/internals/api/initcalls.txt create mode 100644 doc/internals/api/ist.txt create mode 100644 doc/internals/api/layers.txt create mode 100644 doc/internals/api/list.txt create mode 100644 doc/internals/api/pools.txt create mode 100644 doc/internals/api/scheduler.txt create mode 100644 doc/internals/body-parsing.txt create mode 100644 doc/internals/connect-status.txt create mode 100644 doc/internals/connection-header.txt create mode 100644 doc/internals/connection-scale.txt create mode 100644 doc/internals/entities-v2.txt create mode 100644 doc/internals/entities.txt create mode 100644 doc/internals/fd-migration.txt create mode 100644 doc/internals/hashing.txt create mode 100644 doc/internals/header-parser-speed.txt create mode 100644 doc/internals/header-tree.txt create mode 100644 doc/internals/http-cookies.txt create mode 100644 doc/internals/http-docs.txt create mode 100644 doc/internals/http-parsing.txt create mode 100644 doc/internals/list.fig create mode 100644 doc/internals/list.png create mode 100644 doc/internals/listener-states.fig create mode 100644 doc/internals/listener-states.png create mode 100644 doc/internals/lua_socket.fig create mode 100644 doc/internals/lua_socket.pdf create mode 100644 doc/internals/muxes.fig create mode 100644 doc/internals/muxes.pdf create mode 100644 doc/internals/muxes.png create mode 100644 doc/internals/muxes.svg create mode 100644 doc/internals/naming.txt create mode 100644 doc/internals/notes-layers.txt create mode 100644 doc/internals/pattern.dia create mode 100644 doc/internals/pattern.pdf create mode 100644 doc/internals/polling-states.fig create mode 100644 doc/internals/repartition-be-fe-fi.txt create mode 100644 doc/internals/sched.fig create mode 100644 doc/internals/sched.pdf create mode 100644 doc/internals/sched.png create mode 100644 doc/internals/sched.svg create mode 100644 doc/internals/ssl_cert.dia create mode 100644 doc/internals/stats-v2.txt create mode 100644 doc/internals/stream-sock-states.fig create mode 100644 doc/intro.txt create mode 100644 doc/lgpl.txt create mode 100644 doc/linux-syn-cookies.txt create mode 100644 doc/lua-api/Makefile create mode 100644 doc/lua-api/_static/channel.fig create mode 100644 doc/lua-api/_static/channel.png create mode 100644 doc/lua-api/conf.py create mode 100644 doc/lua-api/index.rst create mode 100644 doc/lua.txt create mode 100644 doc/management.txt create mode 100644 doc/netscaler-client-ip-insertion-protocol.txt create mode 100644 doc/network-namespaces.txt create mode 100644 doc/peers-v2.0.txt create mode 100644 doc/peers.txt create mode 100644 doc/proxy-protocol.txt create mode 100644 doc/queuing.fig create mode 100644 doc/regression-testing.txt create mode 100644 doc/seamless_reload.txt create mode 100644 examples/basic-config-edge.cfg create mode 100644 examples/content-sw-sample.cfg create mode 100644 examples/errorfiles/400.http create mode 100644 examples/errorfiles/403.http create mode 100644 examples/errorfiles/408.http create mode 100644 examples/errorfiles/500.http create mode 100644 examples/errorfiles/502.http create mode 100644 examples/errorfiles/503.http create mode 100644 examples/errorfiles/504.http create mode 100644 examples/errorfiles/README create mode 100644 examples/haproxy.init create mode 100644 examples/option-http_proxy.cfg create mode 100644 examples/quick-test.cfg create mode 100644 examples/socks4.cfg create mode 100644 examples/transparent_proxy.cfg create mode 100644 examples/wurfl-example.cfg create mode 100644 include/haproxy/acl-t.h create mode 100644 include/haproxy/acl.h create mode 100644 include/haproxy/action-t.h create mode 100644 include/haproxy/action.h create mode 100644 include/haproxy/activity-t.h create mode 100644 include/haproxy/activity.h create mode 100644 include/haproxy/api-t.h create mode 100644 include/haproxy/api.h create mode 100644 include/haproxy/applet-t.h create mode 100644 include/haproxy/applet.h create mode 100644 include/haproxy/arg-t.h create mode 100644 include/haproxy/arg.h create mode 100644 include/haproxy/atomic.h create mode 100644 include/haproxy/auth-t.h create mode 100644 include/haproxy/auth.h create mode 100644 include/haproxy/backend-t.h create mode 100644 include/haproxy/backend.h create mode 100644 include/haproxy/base64.h create mode 100644 include/haproxy/buf-t.h create mode 100644 include/haproxy/buf.h create mode 100644 include/haproxy/bug.h create mode 100644 include/haproxy/capture-t.h create mode 100644 include/haproxy/capture.h create mode 100644 include/haproxy/cbuf-t.h create mode 100644 include/haproxy/cbuf.h create mode 100644 include/haproxy/cfgcond-t.h create mode 100644 include/haproxy/cfgcond.h create mode 100644 include/haproxy/cfgdiag.h create mode 100644 include/haproxy/cfgparse.h create mode 100644 include/haproxy/channel-t.h create mode 100644 include/haproxy/channel.h create mode 100644 include/haproxy/check-t.h create mode 100644 include/haproxy/check.h create mode 100644 include/haproxy/chunk.h create mode 100644 include/haproxy/cli-t.h create mode 100644 include/haproxy/cli.h create mode 100644 include/haproxy/clock.h create mode 100644 include/haproxy/compat.h create mode 100644 include/haproxy/compiler.h create mode 100644 include/haproxy/compression-t.h create mode 100644 include/haproxy/compression.h create mode 100644 include/haproxy/connection-t.h create mode 100644 include/haproxy/connection.h create mode 100644 include/haproxy/counters-t.h create mode 100644 include/haproxy/cpuset-t.h create mode 100644 include/haproxy/cpuset.h create mode 100644 include/haproxy/debug.h create mode 100644 include/haproxy/defaults.h create mode 100644 include/haproxy/dgram-t.h create mode 100644 include/haproxy/dgram.h create mode 100644 include/haproxy/dict-t.h create mode 100644 include/haproxy/dict.h create mode 100644 include/haproxy/dns-t.h create mode 100644 include/haproxy/dns.h create mode 100644 include/haproxy/dynbuf-t.h create mode 100644 include/haproxy/dynbuf.h create mode 100644 include/haproxy/errors.h create mode 100644 include/haproxy/extcheck.h create mode 100644 include/haproxy/fcgi-app-t.h create mode 100644 include/haproxy/fcgi-app.h create mode 100644 include/haproxy/fcgi.h create mode 100644 include/haproxy/fd-t.h create mode 100644 include/haproxy/fd.h create mode 100644 include/haproxy/filters-t.h create mode 100644 include/haproxy/filters.h create mode 100644 include/haproxy/fix-t.h create mode 100644 include/haproxy/fix.h create mode 100644 include/haproxy/flt_http_comp.h create mode 100644 include/haproxy/freq_ctr-t.h create mode 100644 include/haproxy/freq_ctr.h create mode 100644 include/haproxy/frontend.h create mode 100644 include/haproxy/global-t.h create mode 100644 include/haproxy/global.h create mode 100644 include/haproxy/h1.h create mode 100644 include/haproxy/h1_htx.h create mode 100644 include/haproxy/h2.h create mode 100644 include/haproxy/h3.h create mode 100644 include/haproxy/h3_stats-t.h create mode 100644 include/haproxy/h3_stats.h create mode 100644 include/haproxy/hash.h create mode 100644 include/haproxy/hlua-t.h create mode 100644 include/haproxy/hlua.h create mode 100644 include/haproxy/hlua_fcn.h create mode 100644 include/haproxy/hpack-dec.h create mode 100644 include/haproxy/hpack-enc.h create mode 100644 include/haproxy/hpack-huff.h create mode 100644 include/haproxy/hpack-tbl-t.h create mode 100644 include/haproxy/hpack-tbl.h create mode 100644 include/haproxy/hq_interop.h create mode 100644 include/haproxy/http-hdr-t.h create mode 100644 include/haproxy/http-hdr.h create mode 100644 include/haproxy/http-t.h create mode 100644 include/haproxy/http.h create mode 100644 include/haproxy/http_ana-t.h create mode 100644 include/haproxy/http_ana.h create mode 100644 include/haproxy/http_client-t.h create mode 100644 include/haproxy/http_client.h create mode 100644 include/haproxy/http_fetch.h create mode 100644 include/haproxy/http_htx-t.h create mode 100644 include/haproxy/http_htx.h create mode 100644 include/haproxy/http_rules.h create mode 100644 include/haproxy/htx-t.h create mode 100644 include/haproxy/htx.h create mode 100644 include/haproxy/init-t.h create mode 100644 include/haproxy/init.h create mode 100644 include/haproxy/initcall.h create mode 100644 include/haproxy/intops.h create mode 100644 include/haproxy/istbuf.h create mode 100644 include/haproxy/jwt-t.h create mode 100644 include/haproxy/jwt.h create mode 100644 include/haproxy/lb_chash-t.h create mode 100644 include/haproxy/lb_chash.h create mode 100644 include/haproxy/lb_fas-t.h create mode 100644 include/haproxy/lb_fas.h create mode 100644 include/haproxy/lb_fwlc-t.h create mode 100644 include/haproxy/lb_fwlc.h create mode 100644 include/haproxy/lb_fwrr-t.h create mode 100644 include/haproxy/lb_fwrr.h create mode 100644 include/haproxy/lb_map-t.h create mode 100644 include/haproxy/lb_map.h create mode 100644 include/haproxy/list-t.h create mode 100644 include/haproxy/list.h create mode 100644 include/haproxy/listener-t.h create mode 100644 include/haproxy/listener.h create mode 100644 include/haproxy/log-t.h create mode 100644 include/haproxy/log.h create mode 100644 include/haproxy/mailers-t.h create mode 100644 include/haproxy/mailers.h create mode 100644 include/haproxy/map-t.h create mode 100644 include/haproxy/map.h create mode 100644 include/haproxy/mqtt-t.h create mode 100644 include/haproxy/mqtt.h create mode 100644 include/haproxy/mux_quic-t.h create mode 100644 include/haproxy/mux_quic.h create mode 100644 include/haproxy/mworker-t.h create mode 100644 include/haproxy/mworker.h create mode 100644 include/haproxy/namespace-t.h create mode 100644 include/haproxy/namespace.h create mode 100644 include/haproxy/ncbuf-t.h create mode 100644 include/haproxy/ncbuf.h create mode 100644 include/haproxy/net_helper.h create mode 100644 include/haproxy/obj_type-t.h create mode 100644 include/haproxy/obj_type.h create mode 100644 include/haproxy/openssl-compat.h create mode 100644 include/haproxy/pattern-t.h create mode 100644 include/haproxy/pattern.h create mode 100644 include/haproxy/payload.h create mode 100644 include/haproxy/peers-t.h create mode 100644 include/haproxy/peers.h create mode 100644 include/haproxy/pipe-t.h create mode 100644 include/haproxy/pipe.h create mode 100644 include/haproxy/pool-os.h create mode 100644 include/haproxy/pool-t.h create mode 100644 include/haproxy/pool.h create mode 100644 include/haproxy/port_range-t.h create mode 100644 include/haproxy/port_range.h create mode 100644 include/haproxy/proto_quic.h create mode 100644 include/haproxy/proto_sockpair.h create mode 100644 include/haproxy/proto_tcp.h create mode 100644 include/haproxy/proto_udp.h create mode 100644 include/haproxy/proto_uxst.h create mode 100644 include/haproxy/protobuf-t.h create mode 100644 include/haproxy/protobuf.h create mode 100644 include/haproxy/protocol-t.h create mode 100644 include/haproxy/protocol.h create mode 100644 include/haproxy/proxy-t.h create mode 100644 include/haproxy/proxy.h create mode 100644 include/haproxy/qmux_http.h create mode 100644 include/haproxy/qmux_trace.h create mode 100644 include/haproxy/qpack-dec.h create mode 100644 include/haproxy/qpack-enc.h create mode 100644 include/haproxy/qpack-t.h create mode 100644 include/haproxy/qpack-tbl-t.h create mode 100644 include/haproxy/qpack-tbl.h create mode 100644 include/haproxy/queue-t.h create mode 100644 include/haproxy/queue.h create mode 100644 include/haproxy/quic_cc-t.h create mode 100644 include/haproxy/quic_cc.h create mode 100644 include/haproxy/quic_conn-t.h create mode 100644 include/haproxy/quic_conn.h create mode 100644 include/haproxy/quic_enc.h create mode 100644 include/haproxy/quic_frame-t.h create mode 100644 include/haproxy/quic_frame.h create mode 100644 include/haproxy/quic_loss-t.h create mode 100644 include/haproxy/quic_loss.h create mode 100644 include/haproxy/quic_sock-t.h create mode 100644 include/haproxy/quic_sock.h create mode 100644 include/haproxy/quic_stats-t.h create mode 100644 include/haproxy/quic_stats.h create mode 100644 include/haproxy/quic_stream-t.h create mode 100644 include/haproxy/quic_stream.h create mode 100644 include/haproxy/quic_tls-t.h create mode 100644 include/haproxy/quic_tls.h create mode 100644 include/haproxy/quic_tp-t.h create mode 100644 include/haproxy/quic_tp.h create mode 100644 include/haproxy/receiver-t.h create mode 100644 include/haproxy/regex-t.h create mode 100644 include/haproxy/regex.h create mode 100644 include/haproxy/resolvers-t.h create mode 100644 include/haproxy/resolvers.h create mode 100644 include/haproxy/ring-t.h create mode 100644 include/haproxy/ring.h create mode 100644 include/haproxy/sample-t.h create mode 100644 include/haproxy/sample.h create mode 100644 include/haproxy/sample_data-t.h create mode 100644 include/haproxy/sc_strm.h create mode 100644 include/haproxy/server-t.h create mode 100644 include/haproxy/server.h create mode 100644 include/haproxy/session-t.h create mode 100644 include/haproxy/session.h create mode 100644 include/haproxy/shctx-t.h create mode 100644 include/haproxy/shctx.h create mode 100644 include/haproxy/signal-t.h create mode 100644 include/haproxy/signal.h create mode 100644 include/haproxy/sink-t.h create mode 100644 include/haproxy/sink.h create mode 100644 include/haproxy/sock-t.h create mode 100644 include/haproxy/sock.h create mode 100644 include/haproxy/sock_inet.h create mode 100644 include/haproxy/sock_unix.h create mode 100644 include/haproxy/spoe-t.h create mode 100644 include/haproxy/spoe.h create mode 100644 include/haproxy/ssl_ckch-t.h create mode 100644 include/haproxy/ssl_ckch.h create mode 100644 include/haproxy/ssl_crtlist-t.h create mode 100644 include/haproxy/ssl_crtlist.h create mode 100644 include/haproxy/ssl_sock-t.h create mode 100644 include/haproxy/ssl_sock.h create mode 100644 include/haproxy/ssl_utils.h create mode 100644 include/haproxy/stats-t.h create mode 100644 include/haproxy/stats.h create mode 100644 include/haproxy/stconn-t.h create mode 100644 include/haproxy/stconn.h create mode 100644 include/haproxy/stick_table-t.h create mode 100644 include/haproxy/stick_table.h create mode 100644 include/haproxy/stream-t.h create mode 100644 include/haproxy/stream.h create mode 100644 include/haproxy/task-t.h create mode 100644 include/haproxy/task.h create mode 100644 include/haproxy/tcp_rules.h create mode 100644 include/haproxy/tcpcheck-t.h create mode 100644 include/haproxy/tcpcheck.h create mode 100644 include/haproxy/thread-t.h create mode 100644 include/haproxy/thread.h create mode 100644 include/haproxy/ticks.h create mode 100644 include/haproxy/time.h create mode 100644 include/haproxy/tinfo-t.h create mode 100644 include/haproxy/tinfo.h create mode 100644 include/haproxy/tools-t.h create mode 100644 include/haproxy/tools.h create mode 100644 include/haproxy/trace-t.h create mode 100644 include/haproxy/trace.h create mode 100644 include/haproxy/uri_auth-t.h create mode 100644 include/haproxy/uri_auth.h create mode 100644 include/haproxy/uri_normalizer-t.h create mode 100644 include/haproxy/uri_normalizer.h create mode 100644 include/haproxy/vars-t.h create mode 100644 include/haproxy/vars.h create mode 100644 include/haproxy/version.h create mode 100644 include/haproxy/xref-t.h create mode 100644 include/haproxy/xref.h create mode 100644 include/haproxy/xxhash.h create mode 100644 include/import/atomic-ops.h create mode 100644 include/import/eb32sctree.h create mode 100644 include/import/eb32tree.h create mode 100644 include/import/eb64tree.h create mode 100644 include/import/ebimtree.h create mode 100644 include/import/ebistree.h create mode 100644 include/import/ebmbtree.h create mode 100644 include/import/ebpttree.h create mode 100644 include/import/ebsttree.h create mode 100644 include/import/ebtree-t.h create mode 100644 include/import/ebtree.h create mode 100644 include/import/ist.h create mode 100644 include/import/lru.h create mode 100644 include/import/mjson.h create mode 100644 include/import/plock.h create mode 100644 include/import/sha1.h create mode 100644 include/import/slz-tables.h create mode 100644 include/import/slz.h create mode 100644 include/import/xxhash.h create mode 100644 reg-tests/README create mode 100644 reg-tests/balance/balance-rr.vtc create mode 100644 reg-tests/balance/balance-uri-path-only.vtc create mode 100644 reg-tests/balance/balance-uri.vtc create mode 100644 reg-tests/cache/basic.vtc create mode 100644 reg-tests/cache/caching_rules.vtc create mode 100644 reg-tests/cache/expires.vtc create mode 100644 reg-tests/cache/if-modified-since.vtc create mode 100644 reg-tests/cache/if-none-match.vtc create mode 100644 reg-tests/cache/post_on_entry.vtc create mode 100644 reg-tests/cache/sample_fetches.vtc create mode 100644 reg-tests/cache/vary.vtc create mode 100644 reg-tests/cache/vary_accept_encoding.vtc create mode 100644 reg-tests/checks/1be_40srv_odd_health_checks.vtc create mode 100644 reg-tests/checks/40be_2srv_odd_health_checks.vtc create mode 100644 reg-tests/checks/4be_1srv_health_checks.vtc create mode 100644 reg-tests/checks/4be_1srv_smtpchk_httpchk_layer47errors.vtc create mode 100644 reg-tests/checks/agent-check.vtc create mode 120000 reg-tests/checks/common.pem create mode 100644 reg-tests/checks/http-check-expect.vtc create mode 100644 reg-tests/checks/http-check-send.vtc create mode 100644 reg-tests/checks/http-check.vtc create mode 100644 reg-tests/checks/http-monitor-uri.vtc create mode 100644 reg-tests/checks/ldap-check.vtc create mode 100644 reg-tests/checks/mysql-check.vtc create mode 100644 reg-tests/checks/pgsql-check.vtc create mode 100644 reg-tests/checks/redis-check.vtc create mode 100644 reg-tests/checks/smtp-check.vtc create mode 100644 reg-tests/checks/spop-check.vtc create mode 100644 reg-tests/checks/ssl-hello-check.vtc create mode 100644 reg-tests/checks/tcp-check-ssl.vtc create mode 100644 reg-tests/checks/tcp-check_min-recv.vtc create mode 100644 reg-tests/checks/tcp-check_multiple_ports.vtc create mode 100644 reg-tests/checks/tcp-checks-socks4.vtc create mode 100644 reg-tests/checks/tls_health_checks.vtc create mode 100644 reg-tests/compression/basic.vtc create mode 120000 reg-tests/compression/common.pem create mode 100644 reg-tests/compression/etags_conversion.vtc create mode 100644 reg-tests/compression/lua_validation.lua create mode 100644 reg-tests/compression/lua_validation.vtc create mode 100644 reg-tests/compression/vary.vtc create mode 100644 reg-tests/connection/cli_src_dst.vtc create mode 120000 reg-tests/connection/common.pem create mode 100644 reg-tests/connection/dispatch.vtc create mode 100644 reg-tests/connection/http_reuse_aggressive.vtc create mode 100644 reg-tests/connection/http_reuse_always.vtc create mode 100644 reg-tests/connection/http_reuse_be_transparent.vtc create mode 100644 reg-tests/connection/http_reuse_conn_hash.vtc create mode 100644 reg-tests/connection/http_reuse_dispatch.vtc create mode 100644 reg-tests/connection/http_reuse_never.vtc create mode 100644 reg-tests/connection/http_reuse_safe.vtc create mode 100644 reg-tests/connection/proxy_protocol_random_fail.vtc create mode 100644 reg-tests/connection/proxy_protocol_send_unique_id.vtc create mode 100644 reg-tests/connection/proxy_protocol_send_unique_id_alpn.vtc create mode 100644 reg-tests/connection/proxy_protocol_tlv_validation.vtc create mode 100644 reg-tests/connection/tcp_to_http_upgrade.vtc create mode 100644 reg-tests/contrib/prometheus.vtc create mode 100644 reg-tests/converter/add_item.vtc create mode 100644 reg-tests/converter/be2dec.vtc create mode 100644 reg-tests/converter/be2hex.vtc create mode 100644 reg-tests/converter/digest.vtc create mode 100644 reg-tests/converter/field.vtc create mode 100644 reg-tests/converter/fix.vtc create mode 100644 reg-tests/converter/hmac.vtc create mode 100644 reg-tests/converter/iif.vtc create mode 100644 reg-tests/converter/json.vtc create mode 100644 reg-tests/converter/json_query.vtc create mode 100644 reg-tests/converter/mqtt.vtc create mode 100644 reg-tests/converter/secure_memcmp.vtc create mode 100644 reg-tests/converter/sha2.vtc create mode 100644 reg-tests/converter/url_dec.vtc create mode 100644 reg-tests/converter/url_enc.vtc create mode 100644 reg-tests/filters/random-forwarding.vtc create mode 100644 reg-tests/http-capture/multiple_headers.vtc create mode 100644 reg-tests/http-cookies/cookie_insert_indirect.vtc create mode 100644 reg-tests/http-cookies/h2_cookie_concat.vtc create mode 100644 reg-tests/http-errorfiles/errorfiles.vtc create mode 100644 reg-tests/http-errorfiles/errors/400-1.http create mode 100644 reg-tests/http-errorfiles/errors/400-2.http create mode 100644 reg-tests/http-errorfiles/errors/400-3.http create mode 100644 reg-tests/http-errorfiles/errors/400.http create mode 100644 reg-tests/http-errorfiles/errors/403-1.http create mode 100644 reg-tests/http-errorfiles/errors/403-2.http create mode 100644 reg-tests/http-errorfiles/errors/403.http create mode 100644 reg-tests/http-errorfiles/errors/404-1.http create mode 100644 reg-tests/http-errorfiles/errors/404-2.http create mode 100644 reg-tests/http-errorfiles/errors/404-3.http create mode 100644 reg-tests/http-errorfiles/errors/404.http create mode 100644 reg-tests/http-errorfiles/errors/500-1.http create mode 100644 reg-tests/http-errorfiles/errors/500.http create mode 100644 reg-tests/http-errorfiles/errors/lf-403.txt create mode 100644 reg-tests/http-errorfiles/http-error.vtc create mode 100644 reg-tests/http-errorfiles/http_deny_errors.vtc create mode 100644 reg-tests/http-errorfiles/http_errors.vtc create mode 100644 reg-tests/http-errorfiles/http_return.vtc create mode 120000 reg-tests/http-messaging/common.pem create mode 100644 reg-tests/http-messaging/h1_host_normalization.vtc create mode 100644 reg-tests/http-messaging/h1_to_h1.vtc create mode 100644 reg-tests/http-messaging/h2_desync_attacks.vtc create mode 100644 reg-tests/http-messaging/h2_to_h1.vtc create mode 100644 reg-tests/http-messaging/http_abortonclose.vtc create mode 100644 reg-tests/http-messaging/http_bodyless_response.vtc create mode 100644 reg-tests/http-messaging/http_msg_full_on_eom.vtc create mode 100644 reg-tests/http-messaging/http_request_buffer.vtc create mode 100644 reg-tests/http-messaging/http_splicing.vtc create mode 100644 reg-tests/http-messaging/http_transfer_encoding.vtc create mode 100644 reg-tests/http-messaging/http_wait_for_body.vtc create mode 100644 reg-tests/http-messaging/protocol_upgrade.vtc create mode 100644 reg-tests/http-messaging/scheme_based_normalize.vtc create mode 100644 reg-tests/http-messaging/srv_ws.vtc create mode 100644 reg-tests/http-messaging/websocket.vtc create mode 100644 reg-tests/http-rules/1k.txt create mode 100644 reg-tests/http-rules/acl_cli_spaces.vtc create mode 100644 reg-tests/http-rules/agents.acl create mode 100644 reg-tests/http-rules/converters_ipmask_concat_strcmp_field_word.map create mode 100644 reg-tests/http-rules/converters_ipmask_concat_strcmp_field_word.vtc create mode 100644 reg-tests/http-rules/default_rules.vtc create mode 100644 reg-tests/http-rules/del_header.vtc create mode 100644 reg-tests/http-rules/except-forwardfor-originalto.vtc create mode 100644 reg-tests/http-rules/h1_to_h1c.vtc create mode 100644 reg-tests/http-rules/h1or2_to_h1c.vtc create mode 100644 reg-tests/http-rules/http_after_response.vtc create mode 100644 reg-tests/http-rules/http_return.vtc create mode 100644 reg-tests/http-rules/lf-file.txt create mode 100644 reg-tests/http-rules/map_redirect-be.map create mode 100644 reg-tests/http-rules/map_redirect.map create mode 100644 reg-tests/http-rules/map_redirect.vtc create mode 100644 reg-tests/http-rules/map_regm_with_backref.map create mode 100644 reg-tests/http-rules/map_regm_with_backref.vtc create mode 100644 reg-tests/http-rules/normalize_uri.vtc create mode 100644 reg-tests/http-rules/path_and_pathq.vtc create mode 100644 reg-tests/http-rules/restrict_req_hdr_names.vtc create mode 100644 reg-tests/http-rules/strict_rw_mode.vtc create mode 100644 reg-tests/http-set-timeout/set_timeout.vtc create mode 100755 reg-tests/jwt/build_token.py create mode 100644 reg-tests/jwt/es256-public.pem create mode 100644 reg-tests/jwt/es384-public.pem create mode 100644 reg-tests/jwt/es512-public.pem create mode 100644 reg-tests/jwt/jws_verify.vtc create mode 100644 reg-tests/jwt/rsa-public.pem create mode 100644 reg-tests/log/last_rule.vtc create mode 100644 reg-tests/log/load_balancing.vtc create mode 100644 reg-tests/log/log_forward.vtc create mode 100644 reg-tests/log/log_uri.vtc create mode 100644 reg-tests/log/wrong_ip_port_logging.vtc create mode 100644 reg-tests/lua/bad_http_clt_req_duration.lua create mode 100644 reg-tests/lua/bad_http_clt_req_duration.vtc create mode 100644 reg-tests/lua/close_wait_lf.lua create mode 100644 reg-tests/lua/close_wait_lf.vtc create mode 120000 reg-tests/lua/common.pem create mode 100644 reg-tests/lua/h_txn_get_priv.lua create mode 100644 reg-tests/lua/h_txn_get_priv.vtc create mode 100644 reg-tests/lua/httpclient_action.lua create mode 100644 reg-tests/lua/httpclient_action.vtc create mode 100644 reg-tests/lua/lua_httpclient.lua create mode 100644 reg-tests/lua/lua_httpclient.vtc create mode 100644 reg-tests/lua/lua_socket.lua create mode 100644 reg-tests/lua/lua_socket.vtc create mode 100644 reg-tests/lua/set_var.lua create mode 100644 reg-tests/lua/set_var.vtc create mode 100644 reg-tests/lua/txn_get_priv-print_r.lua create mode 100644 reg-tests/lua/txn_get_priv-thread.vtc create mode 100644 reg-tests/lua/txn_get_priv.lua create mode 100644 reg-tests/lua/txn_get_priv.vtc create mode 100644 reg-tests/lua/wrong_types_usage.lua create mode 100644 reg-tests/lua/wrong_types_usage.vtc create mode 100644 reg-tests/mailers/healthcheckmail.lua create mode 100644 reg-tests/mailers/healthcheckmail.vtc create mode 100644 reg-tests/mcli/mcli_show_info.vtc create mode 100644 reg-tests/mcli/mcli_start_progs.vtc create mode 100644 reg-tests/peers/basic_sync.vtc create mode 100644 reg-tests/peers/basic_sync_wo_stkt_backend.vtc create mode 120000 reg-tests/peers/common.pem create mode 100644 reg-tests/peers/tls_basic_sync.vtc create mode 100644 reg-tests/peers/tls_basic_sync_wo_stkt_backend.vtc create mode 100644 reg-tests/sample_fetches/cond_set_var.vtc create mode 100644 reg-tests/sample_fetches/cook.vtc create mode 100644 reg-tests/sample_fetches/hashes.vtc create mode 100644 reg-tests/sample_fetches/so_name.vtc create mode 100644 reg-tests/sample_fetches/srv_name.vtc create mode 100644 reg-tests/sample_fetches/ubase64.vtc create mode 100644 reg-tests/sample_fetches/vars.vtc create mode 100644 reg-tests/seamless-reload/abns_socket.vtc create mode 100644 reg-tests/server/cli_add_check_server.vtc create mode 100644 reg-tests/server/cli_add_server.vtc create mode 100644 reg-tests/server/cli_add_ssl_server.vtc create mode 100644 reg-tests/server/cli_add_track_server.vtc create mode 100644 reg-tests/server/cli_delete_dynamic_server.vtc create mode 100644 reg-tests/server/cli_delete_server.vtc create mode 100644 reg-tests/server/cli_delete_server_lua.vtc create mode 100644 reg-tests/server/cli_set_fdqn.vtc create mode 100644 reg-tests/server/cli_set_ssl.vtc create mode 120000 reg-tests/server/common.pem create mode 100644 reg-tests/server/get_srv_stats.lua create mode 100644 reg-tests/spoe/wrong_init.vtc create mode 100644 reg-tests/ssl/README create mode 100644 reg-tests/ssl/add_ssl_crt-list.vtc create mode 100644 reg-tests/ssl/ca-auth.crt create mode 100644 reg-tests/ssl/cert1-example.com.pem.ecdsa create mode 100644 reg-tests/ssl/cert1-example.com.pem.rsa create mode 100644 reg-tests/ssl/cert2-example.com.pem.ecdsa create mode 100644 reg-tests/ssl/cert2-example.com.pem.rsa create mode 100644 reg-tests/ssl/client.ecdsa.pem create mode 100644 reg-tests/ssl/client1.pem create mode 100644 reg-tests/ssl/client2_expired.pem create mode 100644 reg-tests/ssl/client3_revoked.pem create mode 100644 reg-tests/ssl/common.4096.dh create mode 100644 reg-tests/ssl/common.crt create mode 100644 reg-tests/ssl/common.key create mode 100644 reg-tests/ssl/common.pem create mode 100644 reg-tests/ssl/crl-auth.pem create mode 100644 reg-tests/ssl/del_ssl_crt-list.vtc create mode 100644 reg-tests/ssl/dynamic_server_ssl.vtc create mode 100644 reg-tests/ssl/ecdsa.crt create mode 100644 reg-tests/ssl/ecdsa.key create mode 100644 reg-tests/ssl/ecdsa.pem create mode 100644 reg-tests/ssl/filters.crt-list create mode 100644 reg-tests/ssl/generate_certificates/gen_cert_ca.pem create mode 100644 reg-tests/ssl/generate_certificates/gen_cert_server.pem create mode 100644 reg-tests/ssl/interCA1_crl.pem create mode 100644 reg-tests/ssl/interCA1_crl_empty.pem create mode 100644 reg-tests/ssl/interCA2_crl.pem create mode 100644 reg-tests/ssl/interCA2_crl_empty.pem create mode 100644 reg-tests/ssl/localhost.crt-list create mode 100644 reg-tests/ssl/log_forward_ssl.vtc create mode 100644 reg-tests/ssl/new_del_ssl_cafile.vtc create mode 100644 reg-tests/ssl/new_del_ssl_crlfile.vtc create mode 100644 reg-tests/ssl/rootCA_crl.pem create mode 100644 reg-tests/ssl/set_cafile_client.pem create mode 100644 reg-tests/ssl/set_cafile_interCA1.crt create mode 100644 reg-tests/ssl/set_cafile_interCA2.crt create mode 100644 reg-tests/ssl/set_cafile_rootCA.crt create mode 100644 reg-tests/ssl/set_cafile_server.pem create mode 100644 reg-tests/ssl/set_default_cert.crt-list create mode 100644 reg-tests/ssl/set_default_cert.pem create mode 100644 reg-tests/ssl/set_ssl_cafile.vtc create mode 100644 reg-tests/ssl/set_ssl_cert.vtc create mode 100644 reg-tests/ssl/set_ssl_cert_bundle.vtc create mode 100644 reg-tests/ssl/set_ssl_cert_noext.vtc create mode 100644 reg-tests/ssl/set_ssl_crlfile.vtc create mode 100644 reg-tests/ssl/set_ssl_server_cert.vtc create mode 100644 reg-tests/ssl/show_ocsp_server.pem create mode 100644 reg-tests/ssl/show_ocsp_server.pem.issuer create mode 100644 reg-tests/ssl/show_ocsp_server.pem.ocsp create mode 100644 reg-tests/ssl/show_ocsp_server.pem.ocsp.revoked create mode 100644 reg-tests/ssl/show_ssl_ocspresponse.vtc create mode 100644 reg-tests/ssl/simple.crt-list create mode 100644 reg-tests/ssl/ssl_client_auth.vtc create mode 100644 reg-tests/ssl/ssl_client_samples.vtc create mode 100644 reg-tests/ssl/ssl_crt-list_filters.vtc create mode 100644 reg-tests/ssl/ssl_curves.vtc create mode 100644 reg-tests/ssl/ssl_default_server.vtc create mode 100644 reg-tests/ssl/ssl_dh.vtc create mode 100644 reg-tests/ssl/ssl_errors.vtc create mode 100644 reg-tests/ssl/ssl_frontend_samples.vtc create mode 100644 reg-tests/ssl/ssl_generate_certificate.vtc create mode 100644 reg-tests/ssl/ssl_reuse.vtc create mode 100644 reg-tests/ssl/ssl_server_samples.vtc create mode 100644 reg-tests/ssl/ssl_simple_crt-list.vtc create mode 100644 reg-tests/ssl/wrong_ctx_storage.vtc create mode 100644 reg-tests/startup/automatic_maxconn.vtc create mode 100644 reg-tests/startup/check_condition.vtc create mode 100644 reg-tests/startup/common.pem create mode 100644 reg-tests/startup/default_rules.vtc create mode 100644 reg-tests/stick-table/converteers_ref_cnt_never_dec.vtc create mode 100644 reg-tests/stick-table/src_conn_rate.vtc create mode 100644 reg-tests/stick-table/unknown_key.vtc create mode 100644 reg-tests/stickiness/lb-services.vtc create mode 100644 reg-tests/stickiness/srvkey-addr.vtc create mode 100644 reg-tests/stream/unique-id-from-proxy.vtc create mode 100644 reg-tests/stream/unique-id.vtc create mode 100644 reg-tests/tcp-rules/default_rules.vtc create mode 100644 reg-tests/webstats/webstats-scope-and-post-change.vtc create mode 100755 scripts/announce-release create mode 100755 scripts/backport create mode 100755 scripts/build-ot.sh create mode 100755 scripts/build-ssl.sh create mode 100755 scripts/build-vtest.sh create mode 100755 scripts/create-release create mode 100755 scripts/git-show-backports create mode 100755 scripts/make-releases-json create mode 100755 scripts/publish-release create mode 100755 scripts/run-regtests.sh create mode 100644 src/acl.c create mode 100644 src/action.c create mode 100644 src/activity.c create mode 100644 src/applet.c create mode 100644 src/arg.c create mode 100644 src/auth.c create mode 100644 src/backend.c create mode 100644 src/base64.c create mode 100644 src/cache.c create mode 100644 src/calltrace.c create mode 100644 src/cbuf.c create mode 100644 src/cfgcond.c create mode 100644 src/cfgdiag.c create mode 100644 src/cfgparse-global.c create mode 100644 src/cfgparse-listen.c create mode 100644 src/cfgparse-quic.c create mode 100644 src/cfgparse-ssl.c create mode 100644 src/cfgparse-tcp.c create mode 100644 src/cfgparse-unix.c create mode 100644 src/cfgparse.c create mode 100644 src/channel.c create mode 100644 src/check.c create mode 100644 src/chunk.c create mode 100644 src/cli.c create mode 100644 src/clock.c create mode 100644 src/compression.c create mode 100644 src/connection.c create mode 100644 src/cpuset.c create mode 100644 src/debug.c create mode 100644 src/dgram.c create mode 100644 src/dict.c create mode 100644 src/dns.c create mode 100644 src/dynbuf.c create mode 100644 src/eb32sctree.c create mode 100644 src/eb32tree.c create mode 100644 src/eb64tree.c create mode 100644 src/ebimtree.c create mode 100644 src/ebistree.c create mode 100644 src/ebmbtree.c create mode 100644 src/ebpttree.c create mode 100644 src/ebsttree.c create mode 100644 src/ebtree.c create mode 100644 src/errors.c create mode 100644 src/ev_epoll.c create mode 100644 src/ev_evports.c create mode 100644 src/ev_kqueue.c create mode 100644 src/ev_poll.c create mode 100644 src/ev_select.c create mode 100644 src/extcheck.c create mode 100644 src/fcgi-app.c create mode 100644 src/fcgi.c create mode 100644 src/fd.c create mode 100644 src/filters.c create mode 100644 src/fix.c create mode 100644 src/flt_http_comp.c create mode 100644 src/flt_spoe.c create mode 100644 src/flt_trace.c create mode 100644 src/freq_ctr.c create mode 100644 src/frontend.c create mode 100644 src/h1.c create mode 100644 src/h1_htx.c create mode 100644 src/h2.c create mode 100644 src/h3.c create mode 100644 src/h3_stats.c create mode 100644 src/haproxy.c create mode 100644 src/hash.c create mode 100644 src/hlua.c create mode 100644 src/hlua_fcn.c create mode 100644 src/hpack-dec.c create mode 100644 src/hpack-enc.c create mode 100644 src/hpack-huff.c create mode 100644 src/hpack-tbl.c create mode 100644 src/hq_interop.c create mode 100644 src/http.c create mode 100644 src/http_acl.c create mode 100644 src/http_act.c create mode 100644 src/http_ana.c create mode 100644 src/http_client.c create mode 100644 src/http_conv.c create mode 100644 src/http_fetch.c create mode 100644 src/http_htx.c create mode 100644 src/http_rules.c create mode 100644 src/htx.c create mode 100644 src/init.c create mode 100644 src/jwt.c create mode 100644 src/lb_chash.c create mode 100644 src/lb_fas.c create mode 100644 src/lb_fwlc.c create mode 100644 src/lb_fwrr.c create mode 100644 src/lb_map.c create mode 100644 src/listener.c create mode 100644 src/log.c create mode 100644 src/lru.c create mode 100644 src/mailers.c create mode 100644 src/map.c create mode 100644 src/mjson.c create mode 100644 src/mqtt.c create mode 100644 src/mux_fcgi.c create mode 100644 src/mux_h1.c create mode 100644 src/mux_h2.c create mode 100644 src/mux_pt.c create mode 100644 src/mux_quic.c create mode 100644 src/mworker-prog.c create mode 100644 src/mworker.c create mode 100644 src/namespace.c create mode 100644 src/ncbuf.c create mode 100644 src/pattern.c create mode 100644 src/payload.c create mode 100644 src/peers.c create mode 100644 src/pipe.c create mode 100644 src/pool.c create mode 100644 src/proto_quic.c create mode 100644 src/proto_sockpair.c create mode 100644 src/proto_tcp.c create mode 100644 src/proto_udp.c create mode 100644 src/proto_uxdg.c create mode 100644 src/proto_uxst.c create mode 100644 src/protocol.c create mode 100644 src/proxy.c create mode 100644 src/qmux_http.c create mode 100644 src/qmux_trace.c create mode 100644 src/qpack-dec.c create mode 100644 src/qpack-enc.c create mode 100644 src/qpack-tbl.c create mode 100644 src/queue.c create mode 100644 src/quic_cc.c create mode 100644 src/quic_cc_cubic.c create mode 100644 src/quic_cc_newreno.c create mode 100644 src/quic_conn.c create mode 100644 src/quic_frame.c create mode 100644 src/quic_loss.c create mode 100644 src/quic_sock.c create mode 100644 src/quic_stats.c create mode 100644 src/quic_stream.c create mode 100644 src/quic_tls.c create mode 100644 src/quic_tp.c create mode 100644 src/raw_sock.c create mode 100644 src/regex.c create mode 100644 src/resolvers.c create mode 100644 src/ring.c create mode 100644 src/sample.c create mode 100644 src/server.c create mode 100644 src/server_state.c create mode 100644 src/session.c create mode 100644 src/sha1.c create mode 100644 src/shctx.c create mode 100644 src/signal.c create mode 100644 src/sink.c create mode 100644 src/slz.c create mode 100644 src/sock.c create mode 100644 src/sock_inet.c create mode 100644 src/sock_unix.c create mode 100644 src/ssl_ckch.c create mode 100644 src/ssl_crtlist.c create mode 100644 src/ssl_sample.c create mode 100644 src/ssl_sock.c create mode 100644 src/ssl_utils.c create mode 100644 src/stats.c create mode 100644 src/stconn.c create mode 100644 src/stick_table.c create mode 100644 src/stream.c create mode 100644 src/task.c create mode 100644 src/tcp_act.c create mode 100644 src/tcp_rules.c create mode 100644 src/tcp_sample.c create mode 100644 src/tcpcheck.c create mode 100644 src/thread.c create mode 100644 src/time.c create mode 100644 src/tools.c create mode 100644 src/trace.c create mode 100644 src/uri_auth.c create mode 100644 src/uri_normalizer.c create mode 100644 src/vars.c create mode 100644 src/version.c create mode 100644 src/wdt.c create mode 100644 src/xprt_handshake.c create mode 100644 src/xprt_quic.c create mode 100644 tests/conf/basic-check.cfg create mode 100644 tests/conf/ext-check.cfg create mode 100644 tests/conf/ports.cfg create mode 100644 tests/conf/setstatus.lua create mode 100644 tests/conf/tcp-check.cfg create mode 100644 tests/conf/test-acl-args.cfg create mode 100644 tests/conf/test-address-syntax.cfg create mode 100644 tests/conf/test-backlog.cfg create mode 100644 tests/conf/test-check-expect.cfg create mode 100644 tests/conf/test-connection.cfg create mode 100644 tests/conf/test-cookie-indirect.cfg create mode 100644 tests/conf/test-cookie-insert.cfg create mode 100644 tests/conf/test-cookie-passive.cfg create mode 100644 tests/conf/test-cookie-prefix.cfg create mode 100644 tests/conf/test-cookie-rewrite.cfg create mode 100644 tests/conf/test-disable-404.cfg create mode 100644 tests/conf/test-fsm.cfg create mode 100644 tests/conf/test-fwlc.cfg create mode 100644 tests/conf/test-fwrr.cfg create mode 100644 tests/conf/test-handshakes-chk.cfg create mode 100644 tests/conf/test-handshakes.cfg create mode 100644 tests/conf/test-http-send-name-hdr.cfg create mode 100644 tests/conf/test-http-set-status-lua.cfg create mode 100644 tests/conf/test-http-set-status.cfg create mode 100644 tests/conf/test-inspect-smtp.cfg create mode 100644 tests/conf/test-inspect-ssl.cfg create mode 100644 tests/conf/test-map-ports.cfg create mode 100644 tests/conf/test-param-hash.cfg create mode 100644 tests/conf/test-pollers.cfg create mode 100644 tests/conf/test-redirect.cfg create mode 100644 tests/conf/test-sample-fetch-args.cfg create mode 100644 tests/conf/test-sample-fetch-conv.cfg create mode 100644 tests/conf/test-sql.cfg create mode 100644 tests/conf/test-srv-verify.cfg create mode 100644 tests/conf/test-stats.cfg create mode 100644 tests/conf/test-str2sa.cfg create mode 100644 tests/conf/test-time.cfg create mode 100644 tests/conf/test-timeout.cfg create mode 100644 tests/conf/test-url-hash.cfg create mode 100644 tests/conf/test-valid-names.cfg create mode 100644 tests/exp/blocksig.c create mode 100644 tests/exp/filltab25.c create mode 100644 tests/exp/hash_results.txt create mode 100644 tests/exp/hashing-results.txt create mode 100644 tests/exp/io_limits.txt create mode 100644 tests/exp/ip-hash.c create mode 100644 tests/exp/test_hashes.c create mode 100644 tests/exp/testinet.c create mode 100644 tests/exp/uri_hash.c create mode 100644 tests/unit/ist.c create mode 100644 tests/unit/test-arg.c create mode 100644 tests/unit/test-inherited-fd.py create mode 100644 tests/unit/test-list.c create mode 100644 tests/unit/test-sockpair.py diff --git a/.cirrus.yml b/.cirrus.yml new file mode 100644 index 0000000..e6b63e1 --- /dev/null +++ b/.cirrus.yml @@ -0,0 +1,13 @@ +FreeBSD_task: + freebsd_instance: + matrix: + image_family: freebsd-13-1 + only_if: $CIRRUS_BRANCH =~ 'master|next' + install_script: + - pkg update -f && pkg upgrade -y && pkg install -y openssl git gmake lua53 socat pcre + script: + - scripts/build-vtest.sh + - gmake CC=clang V=1 ERR=1 TARGET=freebsd USE_ZLIB=1 USE_PCRE=1 USE_OPENSSL=1 USE_LUA=1 LUA_INC=/usr/local/include/lua53 LUA_LIB=/usr/local/lib LUA_LIB_NAME=lua-5.3 + - ./haproxy -vv + - ldd haproxy + - env VTEST_PROGRAM=../vtest/vtest gmake reg-tests REGTESTS_TYPES=default,bug,devel || (for folder in /tmp/*regtest*/vtc.*; do cat $folder/INFO $folder/LOG; done && exit 1) diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..4b56645 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,3 @@ +SUBVERS export-subst +VERDATE export-subst +*.[ch] diff=cpp diff --git a/.github/ISSUE_TEMPLATE/Bug.yml b/.github/ISSUE_TEMPLATE/Bug.yml new file mode 100644 index 0000000..b56ecb7 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/Bug.yml @@ -0,0 +1,108 @@ +name: Bug Report +description: Report a problem with HAProxy to help us resolve it. +labels: +- 'type: bug' +- 'status: needs-triage' +body: +- type: markdown + attributes: + value: | + ## Welcome! + + You are about to *report a bug* you encountered in HAProxy. Please use the 'Feature Request' template if you want to propose a new feature instead. + + This issue tracker is used to track actual bugs. Please use [the forum](https://discourse.haproxy.org/) or mailing list if you have a question, e.g. to get help with building a configuration to achieve your desired behavior. + + The forum is at: https://discourse.haproxy.org/ + + The mailing list (no need to subscribe) is: haproxy@formilux.org + Subscribe to the list: haproxy+subscribe@formilux.org + Unsubscribe from the list: haproxy+unsubscribe@formilux.org + + Forum and mailing list are correct places for questions about HAProxy or general suggestions and topics, e.g. usage or documentation questions! This issue tracker is for tracking bugs and feature requests directly relating to the development of the software itself. + + Thanks for understanding, and for contributing to the project! +- type: textarea + id: description + attributes: + label: Detailed Description of the Problem + description: | + In this section, please try to concentrate on observations. Only describe what you observed directly. + validations: + required: true +- type: textarea + id: expected-behavior + attributes: + label: Expected Behavior + description: | + Explain why you consider the described behavior (above) to be wrong. What did you expect instead? + + Most likely this is a mismatch between HAProxy's documentation and HAProxy's behavior. + validations: + required: true +- type: textarea + id: steps + attributes: + label: Steps to Reproduce the Behavior + description: | + The more time you spend describing an easy way to reproduce the behavior (if this is possible), the easier it is for the project developers to fix it! + placeholder: | + 1. + 2. + 3. + validations: + required: true +- type: textarea + id: possible-cause + attributes: + label: Do you have any idea what may have caused this? + description: | + Simply leave this empty if you do not. +- type: textarea + id: possible-solution + attributes: + label: Do you have an idea how to solve the issue? + description: | + Simply leave this empty if you do not. +- type: textarea + id: configuration + attributes: + label: What is your configuration? + description: | + - Include as much configuration as possible, including global and default sections. + - Replace confidential data like domain names and IP addresses. + render: haproxy + validations: + required: true +- type: textarea + id: haproxy-vv + attributes: + label: 'Output of `haproxy -vv`' + description: | + Please run `haproxy -vv` (with two `v`) and paste the output into this field. + + Please also include the output of `uname -a` if you use HAProxy 2.1 or older. + render: plain + validations: + required: true +- type: textarea + id: last-output + attributes: + label: Last Outputs and Backtraces + description: | + If HAProxy crashed then please provide: + + 1. The last output from your HAProxy logs (e.g. from journalctl or syslog). + 2. A backtrace from a coredump (`t a a bt full`). + render: plain +- type: textarea + id: additional + attributes: + label: Additional Information + description: | + Any additional information about your environment that may be useful to know about. For example: + + - Any local patches applied + - Environment specificities + - Unusual workload + - Interesting observations or coincidences with events on other components diff --git a/.github/ISSUE_TEMPLATE/Code-Report.yml b/.github/ISSUE_TEMPLATE/Code-Report.yml new file mode 100644 index 0000000..41d1dd6 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/Code-Report.yml @@ -0,0 +1,43 @@ +name: Code Report +description: File a Code Report (for example from coverity or valgrind) +labels: +- 'type: code-report' +body: +- type: markdown + attributes: + value: | + ## Welcome! + + You are about to *report an issue found using an automated tool*. Please use the 'Bug Report' template if you encountered a regular bug. + + Please use the forum or mailing list if you have a question, e.g. to get help with building a configuration to achieve your desired behavior. +- type: input + id: tool + attributes: + label: Tool Name and Version + description: The name and version of the tool you used (e.g. valgrind-3.13.0, or Coverity) + validations: + required: true +- type: textarea + id: code-report + attributes: + label: Code Report + description: Please provide the full output of the tool here. + render: plain + validations: + required: true +- type: textarea + id: additional + attributes: + label: Additional Information + description: | + Any additional information about your environment (e.g. example configurations to trigger a memory leak). +- type: textarea + id: haproxy-vv + attributes: + label: 'Output of `haproxy -vv`' + render: plain + description: | + Please add the output of `haproxy -vv` you are currently using here, this helps us later to see what has changed in HAProxy when we revisit this issue after some time. + validations: + required: true diff --git a/.github/ISSUE_TEMPLATE/Feature.yml b/.github/ISSUE_TEMPLATE/Feature.yml new file mode 100644 index 0000000..8515256 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/Feature.yml @@ -0,0 +1,50 @@ +name: Feature Request +description: Suggest a new feature or enhancement for HAProxy. +labels: +- 'type: feature' +body: +- type: markdown + attributes: + value: | + ## Welcome! + + You are about to *request a feature* you are missing in HAProxy. + + This issue tracker is used to track feature requests and bug reports. Please use [the forum](https://discourse.haproxy.org/) or mailing list if you have a question, e.g. to get help with building a configuration to achieve your desired behavior. + + The forum is at: https://discourse.haproxy.org/ + + The mailing list (no need to subscribe) is: haproxy@formilux.org + Subscribe to the list: haproxy+subscribe@formilux.org + Unsubscribe from the list: haproxy+unsubscribe@formilux.org + + Forum and mailing list are correct places for questions about HAProxy or general suggestions and topics, e.g. usage or documentation questions! This issue tracker is for tracking bugs and feature requests directly relating to the development of the software itself. + + Thanks for understanding, and for contributing to the project! +- type: textarea + id: feature-request + attributes: + label: Your Feature Request + description: | + What should HAProxy do differently? Which functionality do you think we should add? Please describe the feature you would like us to add here. + validations: + required: true +- type: textarea + id: feature-explanation + attributes: + label: What are you trying to do? + description: | + This section should contain a brief description what you're trying to do, which would be possible after implementing the new feature. + validations: + required: true +- type: textarea + id: haproxy-vv + attributes: + label: 'Output of `haproxy -vv`' + render: plain + description: > + Please add the output of `haproxy -vv` you are currently using here, this helps us later to see what has changed in HAProxy when we revisit this issue after some time. + + Please *do not* enter "future version" or something similar. We are interested in the version you are *currently using*. + validations: + required: true diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..4c1ddc6 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,8 @@ +blank_issues_enabled: true +contact_links: + - name: HAProxy Mailing List + url: https://www.mail-archive.com/haproxy@formilux.org/ + about: Questions are best directed to HAProxy Mailing list or the HAProxy Forum. + - name: HAProxy Forum + url: https://discourse.haproxy.org/ + about: Questions are best directed to HAProxy Mailing list or the HAProxy Forum. diff --git a/.github/errorfile b/.github/errorfile new file mode 100644 index 0000000..f15d8e0 --- /dev/null +++ b/.github/errorfile @@ -0,0 +1,209 @@ +HTTP/1.0 200 OK +Cache-Control: no-cache +Connection: close +Content-Type: text/html + + + +b1z6lx9BLl3rSuonLqkIJAn9k9Hsah5qGfx9aq3qWSw6Nn37AZBJ1lxI0UyI7zvjXIEjSEVdCS4U +k6rTW/LndurrbPieC6OcEBPMjzGtsfpR9IsZ3QH6/mtBGnvAtbhxAfhMZ/QQXkqfv0JPjuLdXBdM +Z9cInHOr4ykoETgRbHaNt9ykBv32nIKt81YxLtTOMyyFAzH/AVSHUs6PanUKhxG11Csqn5RnlvSj +PBCaF0lJAGvndF/1PTSIhzjEtXR3ZUzCfO03/j0q0/4+cduV5jf3XNFeICjY19OHKSMIWVN0XVht +bY2eSMG0LoL8TqWyv6VSnclsVM5S5LJe7prJtWFobEpU3AMZzzjMPsxDiyMGJhjbJa0TnsDGAwln +IVO5n56gtdUdhwWUnVn8ZYGZlFVjOQt++q6XL/Vhm+DFCArXZ6Xz8+mz1o109JpM28jHhxg6e7A1 +CF08n0mwN+adNFTi3Wg8D4RJOOQ90Q1bS/gmW7LtPjYxGuu8k27MjUspEHeeEr5rdAcBJbKiG8C9 +191DBDLxlJv/V4ZYG/FdGIqX/a2F7x03Uj7rsVnBPmOz7U0EbcHGcEEpZlSN9YLuUKvPXeZ8HWa9 +fbaGO39Yt+9DByPWC1Xyr65sPBH8eDURPdSDMh3Sr+16HH46anVI40tjK8NZC6jjFBQPfJBP6MVW +HZF1F48rZXxesnHLHaMESCvwTruBf5R4JjYB1gt1Vv76e4Pew1MTK3/1ooNPV5kvoBV5PSLkMDqx +XO6dxSC9Y3HzxhzkoRK56h7SWDbwxd5OmUHNvjm3k0QtVTAWsAEbJ5q/gp65ikG3+hGvp9xF80pU +C1dAxK9+MHg7Ya3UiV6G/dB9prc3v92lEVqtK5CNKzlFiWQHSF3H+sz4qPGlB2Ub8H0T59TSZcyu +oTFKi802BYc8UnPdUX+mf4Uda4Vad4dPE409UQ1XIEqI+2pCTgOCUm80xM2Hgyjpp8bi1mnv6rI1 +8jafv0e6S23Meb9d93E/MLm82KWfXHIjPkDFaTouGS78IJie3giG68U270AL1+gpUwNunW+Ez0Ch +AwKUOM5BUL9pFfRMeDshy8KfiDGr7enLupqa2xe65Hbo47eioZZfIb0AD3P7yzlciIUXsy5JAwCF +B+L0T+XuRUJuXCaJ+ioDmgW0PenJ6xfL/+BuJ9yVrMGYb0paL/cD7VSVDda1L7+VSbLW7sQ6BOHM +ZgFV6+O81p48hGDquMb9+eURGrFKhQFipUPEi5sTQ7ocmyRZIAI3VeEOdBsX6zuwR9a2L5aV4yZc +HoiQikOgAeF1O8FNoVBIKh6TvFIzG+JFxb64pfWiwku+njgQu/xXkhuDSnYh/tzzqwghzmKHpQQl +7fbxF7jBihOr4qTcD/fUNPNGZYAZnZk/+wuA/6NOqwJl7nV2E7Ht7N13E6RZqGzfcL8KWldZbuFL +cFUVZ7sxogftmAWhSrQ1Io4IcAqt19XL5uGFlAiELphh5v+3mWKVNh5kOaCIDcoOggaerDZMl05F +C/d5veJxVLFBsSKFfdADmGh/8g85JDQC1UJuHYXbmPKuQ3pzUZRg6a3JYoi9ssLz7GijrSmmgkXs +71+8TsvHFP193euCd9N981+Gp4NMxpVvWkrYFsjkdtkzSQBda4dUlJ/QhbbHoRAuzNl2zDkUU7SA +P7LCNw3SKJlCQlwDEtqNYuO6jiQBZcUnajdk/UKwVwiH/p6q8rg8bh+NPV04hTZraUoaKumsPG+5 +tCBRj/WxPDKWfLjpgLx2gJPU4SKJrKwbfSot+VVO0Tc9viV8Jl0PPOkcW3ixx3Hc9WEqj0QZYHsB +kUk4E/q8N5WDnvmCzp3t6tlpeNqqkXhvNOAg0XxVXmKE3pWEytX1iMdggdjnoo9dLLGcNwW5+tnw +XdAlEVuqcvTeKJfYT/RMxpfdB7bXsg6OGEokMEkZHltLPmlYkB9i+J6zpWgo0WCwjawocVc7Y9Lj +FfSezs/Fs2s8OJhFlrHQzh3SwZoyAXHgOPC1wJDanMZWjLASi6W7ds2H2FHuyKYfx/gJb02+d199 +1ac7QG3Vgi0QiNB+6D8vuj4r05jQgHj7REIvFwbvJX/eVCY2kle+nXjzOiTL9M4AoDdaW9Hfzoao +YnwcKslhmHhRl/Q+9jA0YX7TCHh/VcKg6+lao3ScQ5F+MjwZewK0lwOlE9Z7Oz5rDNwTdBe6LhwA +tTkeItrhm45IPdipFKRRcqY7OPV0GgHeqIg704hGnpzws0cJi++lpLi2c+387h28ymvUXArndPtF +at7mboqJ7XCi2mYBOa73e7Q58R5UBhNzZB+M+SbNM3Xi5hcbXMH1UtnHGx8E8uNS5oXQvm4Cm4k0 +v1g0jU5xxU3m8j6ze99Z6sFZ3EJ7IrIdIkKHl0jkr+WZww64BEKmNsJfh0nWO+5Bm50ZK+sNkvDg +PtjkehxsWaaERJ8aQeqzIVQTK81m6FqHYdcSsuxMiY2ZAQSnVRarmSJqyd2oPy5vEkCnS9yd2ha9 +bYqAREVHUEy//dw/XJAtttnZSgwAKdn+SRSQuDiWZ9GPs0k/zKuohKkSXkHPlhIDuer+lJ1Hs17m +r0JTCt2LQVXLdCbKScAHOm4wdGeeIyMsV8MJv/PIWoySW8PIm3IjjzFinphnj6COvvVJUYg6zvPb +1WN7ZU0UyI0nFklUVguc6RF2ByO9ZzZA7nmVXlFawnDc5UkotXSGYZJaiV9c44Mvqg8CgxbfLLk+ +OCOJgQF9xIEk0bUp/QAfKj6o5aP2qHr+YvKxxTxlEthlxdGyM+F8YX4WpR6wf2mbFjc6jWC67xk3 +F7zfTdXtmezimB6vUkRAf4P5yS8J6Q7m7JCE/V0CN0Z6fUG4Z/8cGxpVQwqD44McT257MqSdiwrp +C9NiXxqWiLXcj0NbUI0rxAlzSwzuFAjMdLpPOm3zjm6I3SltMKn9BPSOyz5Q4wclInCx6yvZAqK3 +r95cvb72qVEt7YJKaM3b6Vb0oQRMpSWyoYHZQ75WTwcwd8PRecAXGPqgn0e0GYUSfRqiBi5Z3tUp +eljOJvV9ujIs2rFeySLKVfkCfHvcCRVyFZwsiUO0W9NvvIy40lkHtFshFANYlDkJOznhLVSlUGNW +lNwSTjEuG/bcGiiAm4NogFSmu6ijWrrJZbFAjH2CSKkKJUxCpAeasm5nDBqXY6fmS56WLv+mZmlJ +qQx2aJ/yiGWg5h4auN4tyq7vM0S66X9+rg2c+vrxQBAaUbF+rGP6x44QE2FZS66Sptlh3/dY+CLn +7fuVLv2/2ROBRPN06XmmBF0l5VA51wCmozvcHXGgSNndTws7naVH6pu4tNwYje+sKV3xzzspY5ob +cZxtGGGfOMvGuZB8Utx7QgEXAM+RBTc3n1mCJdka2JL797YtSuysoiDmoKY16tQDzw5yQfkU5sbN +pvUFJZLTDBXdBMMisEzyfICsuIyv6A72TWdo9hGnfk1EfofSCuDWVv8Zt1L+FwtM0lkm73t0ILRa +EpmusX+2QFiJdjmpl744bCu4nsj/a/RQ4EmSdKHZXuCL8/pII+ebHY9LkruU4LgXsNa7ZCKCn8lo +RUq7p5/Iwz6tbJ/n2Zp4q5UKeTGtlAqfPicg18AmOwJZx/UunhFpAoPr3Au7wfM7aYTAm+6XRgRx +xXglcFDtGwipKH8Fkj2crhfaJ2GT2/4e0Abb70HW6yYlUHYKI8aMZ1fFXl0qzFbkOuq9I/4IEhLU +auZS898sqj2H6EZ78LE9r/tV1TjC55LS9mVVbmGptjtjSnXQKzwz0ecgUHTJ/BqugyUflq61ZjLg +6GX7+hisr1AJFs72g7aRJGXJHESmPb6fbsfWDqoLquR7NuYefaOsAJWQX8zkgocyIe9gGrHIE0Tt +ybdP4WtbUwn53drOs5A6UbpiSt1XVHps2gZcSkeGIRu7fnX9ZU53758/LKuLdyAQn44aInztqJMn +JVjFjZ4/3RwrDoPHyOwKbrjyWNWTqWBc6ewcLOFvYz4V35pvuXeT/JanX93foBv4O9aWgmjAjqC/ +j8SbRjEt145uKVP113AfvEgLFviOkKu1UOlRiOtqFsN/rSy/7AREhsH/7UO+qSYm3VsFiiUu5N00 +iENT45OeG2yGB/PcyOtSTiryHPZ0sBs9BaCmtCdHxXIRZg0oHk0As+GbsdyG+njF4DmNzrS0ypgt +tT4BkDWqn2s9zwIvOjE8G/zRHffn9VfwqGGrNVenszmkpyoGsmpfl212tUHnvF5i1Ffivj5y9ZMw +ESuq3BaH56cs4hEkq2qubjnhpcl41rSVCZLX0CNfS5uSBtPqknZTvWqH/i1y7NcA7jyj6muqR/Dk +VqoVcaAI/Oey0250AAIpnzGO4Kiv48qWqXhZjRIJvWwtwflLrqU3N5Ec1oh0/vEe33nt61rNsB8P +t0HZwz9aZfymYMRnzgA7tHDiRcGNIOWupWGnXRsisJdH/6T7HH3mup2lNklKvAwH9yM65cTeMDt1 +5/QZKTjlAKiJ8cXes6SE+HpKcTaDo1IQPXkYzv5i2x3D/Pteakic2djUXsQOB+V+Lsx2Koeb9yrq +sHtDRsl7q2uMUlH/u6vMV86AZXmm63Iji3Ktpihc+Qno9GDbA4PQYrvEPtcLGY5UJTpKUhSi5icn +RgQr1IKG0ALE9mH2nS/b9TJn34lzCaeiIMYfOe1Am9AR6bfXuI2riAT18xdGyZGOGzFjJOMtm7Ok +4VhuPnoiuYsmeH3jI/HclKKm2nbrv1g2FOK5z/7cXTFtqqzoIR+/U+Cfixi/A19M4lJwmYnZSRhJ +DMKtf4E8rrW1brFa+HJULcc775nyLTYrhPjio5ozar1/mLZm2eQiIFspHYL1oMh4IvhVXi2ABsq2 +NAyHSZ5UwxXg5jUUv9Z1I8CsNseXIGIiubTe1JQMeTrvzlnBpYhQv2W6LZ4V4EYk6/Af3ULGIQ7C +b2iS/xaa5X+JWHl1MJ4N6debH9OryCj51sPC2o7rAWu9a07RqdzarIVZuJkgvvBSyhHfF9aoOAdb +jOFW4wU79J1VDfVj3wTIGvY6qNru/s+Dapx4s9a0inqj6yX0i6uf1flNnSm+wesHLGhI1ae3uZuS +GBeo+0GiooJHFT+E9BlR+4lZKmr4+waJvCRJmyJ7y57eUWJQbviH0vazlDbJGVqdjRTKV6UgPFrV +xkVnbFBsNP40VnMfJbXiJN+iSkWPYtrQbEoFGpWhpqEcPmryiIApN2LllVGtGmkBBAM2+kQx9jud +EEV+B7+hhhC4Is1ntkbYHFVbIWFgxjbpwP408v5LGkoEnfV1Wdp3d8UtkrShvkOmG/VGtZq6uv9w +bZXMk8b1npQeN2eu7WK4cBDho4CuALLcUl+yO6BkPOibZCSEs2d3M/FMrGZfw+jm5EM30XLItvP4 +6Kg0NDudqumR3LQNtH0RGvlMmEHb47u2E97GgCiJomBP2/JxcFlSzTwLJL805UKWyISEfAvET+e9 +GkE+CoPOHbtsHUEybw3UGKfMUUMhPlC+oEUMwmyZD6JWfYSwygqL8aw0abtDMzOaEWrz0xfkd9ym +BnK9mTd79oPvFAh9qvbdUdgldxXcvIG19jzQ/1IVVz8LZVMJhOKg/yskLFABiTDJ2JXbpznjH1BH +zswQqmlcPqu/vNBFK59EYKhAZumQkjLxB/lPfJBzByPCCfM+dk7Pq5xTjbWLnrPHQoC5WaVrQiCj +Wcosd66Kg9CrXrL98auVQVIX6Oh/Sl6h6W5fqD/iOPUZp13AacEIRA38rwbsyR4ohfSxyHGkd24+ +GUJ/s+Rj7KlwiJEDQdMbJ5Dr4yqIvPLqMLyuz4soneIMdA7RCztmlieIgNnwTI5nzlESRzXoIkzk +KKvC2LPzypHnOhJ3XmZODFRs3Y/qKUIOdSBwDRayhHTnuVK1v21bB3EkFtWllqXf/qHUj19+YFuy +rD4ZvPmIuTxqXb0wPlnr52aE2M2p5068lG6hAvCpZH/uuZsNuaYATcaeBm5J0uvFpKITTHriUEcs +NtjSPf/Z7rn8VWBm6iGcTrrCC+w9LRagVdTxecg+NK5PVUoUVAGEhQXoL+ESGUanPOjFN7NwhM8J +WUagxHH7ALK8LuxrXktdkk7jalBI7U66aFnMxh44M/3yEcUsGH94/jqsC31cCNp4kE97BedfGyRR +jIkTpZAJg702y4k/LEkkcT+wzh0E3vtcpq1fx/3sXduBaxP8HrXSxAiIVDUqJcNy0PYkXLxxnVVW +8z3EDoe0ZZa7PSvYHA1NQHO/74e1T1Alv/ImPo6l7a5M+f2tXZ+75cw7dQgYmnFuGlinfvq12oNw +EwZhrs2WCAEzrjC/sFuPIn0IVqU8q6ve3BzD9YltbeEcJDLkRTOYNkvo8kF6s4uRchsig8FxFE4Q +Jxwravj5xyJpFUF6ZbhagtX3LIBT2/IrWAZgpNu9f4fq9lQ3wnP1UEgkv8o07LyyEV52ZrH6wn19 +sqB9S/6TgvTqO4FwteoxKTzhNI+0oXwloAQrYsmmkhjROu+BncuzKuj6m67mPKrjkudYup/xfVCL +ktYIcPIPCy0ahKdSD03CV2zBT8IF7B9skYoZxC0NvP3rPzl6w/h0wK0jJya12tVHZfqSu8WMD03C +AieOYB1+KoHL3PZsArTAnPGPbAU2VnwC6zFV1LXiq3yvqrtERZsD+xsZxMG2hTGM4jUCFgVrRN3X +Qh05FpC71nHR19z+vaSNJ5wJp6hWIQBTqjz/NWew908SGF1hAFAkzQAHb1a7RN/Cdq9l6WK4XmCg +0g4Vuix2sa8AceNCcuQ9LBimoUEvglkwvCxaxh0Es7xIumigdavavAPvpR2pGESn3S2dOTanYFyG +yJJfLVtH0VWgqzKRZJYg5jzHqcIE6Sh7VXroGIJezm0ykjMUVd3xOrTFW1lEqJI8YEwC5kVhjzhd +sCJNvEIENH0roJX3YiH05jatoKRRhJNF9bN45LKL319pPbZox35rZD23wxZCrrnEDxKOVhVL/ibY +8ITaT5qdDS+ngEEeZdzO8cMoPHbHKdZQgH6DivP5QTDcd9405pE41X4rSDbJaJ7fHonhQUbQR4Rb +TKp4nYKhb1stz3hvP5JqbGD5Lj+0EdeOCXdGk9mbAymoIko6D82n0tjRvA6cFoHI7aaRmzWN2N05 +hYCnpcK/NBFud7usuyAPFLBvaO5Xnar32EGnw9ykCTFjNdfgJjvOxHiE34kiRq/kn1DL5WKwq9EP +MRgEFZ+O7wElyfa6ZtRstJsdI9geoyogelNCpnv4MmRps91jNIjIqyznonsnjWv8+Nl1kzt6bGQR +QjeTfDofWHG/RuIdq9BlKUsqe/VJI1jeCG2kNZ0muWaa7G6K42W4eKp3XPLLiAahNEthtGb6PWDt +IjKhydJeLFWe2FCCBkffYflVZbDsUtS0OiFiBFXDxzKjv0lK1W+DkQ6Yyjh05bXWsdN4P8QRayx2 +SJRWqzhe05HFY75DZLnldGvP348mQmJPxsQQxiH0Gi94DajrNN5I4if1z71rLkyhbxpAu1y311AL +rKNO0CKv27lH3KdpFQlLG3xWQFD86m0RICfDf+SYdugAIPiUPqvJ/QEhkqGLXFgmYdLDfsyp95O1 +YY8K66uS7hlc+sOKRqCJ2Tu0KZP7O10NssRuUhwH1nRLmPUhFX+AyRvE52NAQ+qHppMwFWN2CqPt +YtrkBuzxWCpWuHREkvwoBFW0v8ahyAv33qZZOenJy3EY1R2XJis43tEGrh/40aMG8ktmF7mAS1d6 +ObU2MO0rqf6y7+l6OvnwhFaqokfwZxH3i/axRC3OAf2znpqDRDhsCQwFWzrgbC8ocCuOyntjx02v +yMX5gy2rSXQ0nqqrDLZ4WywJ6cBAxl6ltSP3lgnAlxMRcvbpU6DmMn9QBlTyzsrTpTq6PWjsukqX +0aARHpY5I0U334P6oTaWxDbn+N0IWNLm4MTFxMYsP04hajKfDTEtjhom4ZVy5O6mtc/UP2THyPwx +zK7ETgLItLThg0eKZApOZXpVj3NGN0VorIfrMLx9K6O1vxrkwY3Ybpk1wuSxWO51sXc211XjCOMa +r8axFnIynW2ngHy+hIVjEwG9NxK3ORYUN2I4spVJJGqLQ+b4wceUDSD/Cky1GkirdlWVkheAlkd2 +eLz9UIoJCWCx9BVhjY8ufW75pNsNjgcy27tpt49TJGpKyoXyoZGynksoCA/QzYVrCUn6VsNh0UjG +LlPQ+zFh4iyIYpvVemcOsu8HQZC1YIoumBwu8ukqpo0FBALnVX7jDmxcYMjxPBL/xWJyMF6GOfF8 +yTsxk6YKhaWZb0qCNyEqUQ5OmvoP7aboWOVXWRofWj4CriT13UzeOL5EfCh5GAmlEK8w7GdLq1QW +9LpedlGTHr/sSoeNPMqSS2KEZNvQAp1uff97M/Wr6ilWAQwQNXXESoJ8xgUTR/i8DUBVemedy6FU +DdFwv0/FOFaUqyxE5yjqibZCj82TIimq9CPPEJjHfiYswb1dwlEIWWcxg7XRb/lt2pBCaljrVDWo +64OUPoRICDbVGTiFXh2UuEpw6PDs4ouz+R+0eHeBV3VkFmO7n18nuP6CLFYTI+mz0L9E1eM5coNA +vpX4j76tnagQ3GSm5FBjcTLOG2I0f7MS+AvA5cjzLYzTCVeF73eyjgBlVwFk+U6Nkk0VPvwL22gu +sRQu0kthRNzkfd4sEFvF88vOEq1zuQEuI5zMVcNQ3eYgFXrKLnXQQJdYcJ95mkIbUfW95cNeruHc +rNv9GtoHx4RyWHB5GnTJCLvIdYsBtCd0jlW1R88kf8JeUaAOeoDRV7ScbIKO3xNRpn2P3PzPD884 +chFMCCx7qODm4/6q7onWO3lEsUEiXVFB+rBsN9ZzYmEmXfLuureTWWRZUaXfPY8LNVb+Zu+LPzcf +4kZ9+Fxowm9Q0s9r97K3fQKnxz7ptr/+D1McEKMXLGFCm1JA65PbyRsIo6drTYenzrn/QF4B+Shg +E2Fq5hlOfzpmeUNcHT6EgM02J+4bfjzOA06G9ZxPY4ZNvevOuMA+ITiXQMLpIHXTpZNvKDMBEvD6 +vfin7laoyn7zB45THToL7D1SCdj9IxtOD4UrAVSPAtjZ517JVNyMcRVGT8tfRzT8/AYVCeYY1G9M +GMv7fmTJ4FqvXQWfOIiQbQk5b6ZIkr7x55TasVxDZgDazhjgTy3gavKXTXB8NjSx6dLaP03I9A28 +44W32wh2KGCtv75P3b2WPaSt3oJVPp3SRrgt8a5QsPc21iDkAVLlOcWOqCnHXjiL5Ljtkots3idw +5qDH7vpviIhcoqxnhBcaTc0NEKHX8WxZBamiuLiceCVHTBNpbZbS031yGwHIVu3ZE3oLeCTG6Gzr +6/96lrWA9NW8NGxqS2LMlTZ6oR1pACLLnARSbhyUSpX4dmx7SjOcnBB/7tyAJ8wNHLreD3KK5Opo +IHrQInd08AefjqTaW6BUKhAKYIdeRKLWka6QnrrIOeWioL+xQaImTU3KJ1Lfao4CL9wp7c8DukoP +OYsCNtLgFNr70Yrb1jFYjYPsrtUw59NuSugmTotsCO+Etb2PsXgoCTO2j545sgSsm0y/qIXbZLAE +oB7hReI8JrT00f6YLW79C7SpZQ3P9O77G1IDfhxr+D7tIrRgqelyTiH2gBOBbC4jbaPt/Z4gsrHq +ncncllSvs6RxVHIEZbxz1eCCJDkTkbZqfzvHGh2X+RhG38Y9GaOdh+Ki26Cv6U1Wzds3t8W9DRSf +RCjz7YqN33mGQVSbG0DPTQ8VAQyfDHcyOMTvJtsiRYn0z1sXl7UcULT37IfHb7NJncWiSU6AHOkT +JaPbYs8Oh3eohYDzE6k3iSpUcSxxF0V3+kVkqAUrgFlUPRvoi65xYxqiMQ2DqAU8JbclkRPh7Gse +DEttqQiZ5vDH894otB+WxdyxlKWF/e4SBKC0d3m/4jtYN9xn/Kwc6xStW9phP59/kU+1p9YoGFOz +y8cHQSQ6aE+c9ySCYSpup2VHoI8vafA93kbZXsp8JqWgMO4hE3oqZo8y6QvapxiqWgLc3s6CeTMV +1akLpWpDFnhzA7hkB5xRLuE/XTbVSjELRcKVPFfVw42UMkzf7UXXUz2Y/MwhlnLo5H7lWUoYwQNS +mQ2bLA9jjbf/J7abcd6OgFnXtots4AnSpyY976Q589H8g0Godi2GEzZ6/lamDk7jmSaoA/r5LYVL +ecuMHI+FWP5sp+FQb1gBhxfF6zC+KMyvaDyV15/jGVbAwn9JNM+B6YJ/sjkiukVzruBz/8i3htmB +pp0RlgDfxGe5lpnVJSfoSkFi8psxkwzGraTnWhKvByrMGVJNZuchoV2Gis5ORnWLCFuok5jB43Lv +e9t9xkyXhaig95z2yy6/7cVEsIlOGfKnU1SKVu6JJ4kqDLvWd2Sf9aYq37fO3U833vA9GFHuNX93 +9gJxnrMpQpA+2T88XR2LmoMqfSQ3fV8KGkT6YZuNYe2G8GQ4bnDzO1CWN7gBNXmEw1tgusQwoX1+ +1n2zWhZkgEbxQw8H8tRtyGNzsadxCwQAmcqbwvc29s2QVBGipPTzkzqHfP9WBKr1QB2y0TQPsXcf +znTRIKSnk9/HYKkUpXHT8rdWcJQpuIpOQXpxDAb2hUOaIyOBPOHLdAVV0bbiS97DOeowytVIdr5l +KvLdo367gsKBln240ZUYxwLxU5o2fvUEdwCCxAbkFCI1NdamkOaRMS/ASNeduMWMMuFXmW4gmna0 +nponYLK1drlECpJK1LIeszRqMRnlQ2bKIZaNnhARDLx8J+qTdpVKPY5rnKPi8RueD8w4bgmETLkj +Pu7LVwGDM+KyLkfxiP5EHbjULcV23bOfucRGvUy0OP/Ciq8+IhibLohBnod6DPaJayPFN2xtYTii +aYk3e4YyaqQ5JZGMtx9TkanAdlu28rd69oO+AVHsAj+pXWTwfr3Jd7rNMlE9OCM0CBewcEhVl8XG +dERGMhSVPVARbfwaI67sFmHUr0X8mAsJ0yJoYqbLPIW5jiV1PbK6zkcaksDLLoMkIhJpASb/98+P +q5SKERK5j0rUcpTtr83wfNTPmxxTJzPK4i8Dd2dfv1zy8BF9seOylVQ5Lxw6xXaCrgStUVl8Gz0p +LJWduNunp8pqFiTK2uYeR1KcSabbEj9xPcbWw9zasQL8ycyUB9RoavKLf7MB+a8NK2OSXH5dfD5H +Pl1jcgMu6C9X9YbUtMyhOBbXirYqv80wWDAhLn0GmOn1Stg+sWjGv3UyssE9JZtfH3ExYsS6pWTz +XhFKN+Pvwrj6U2393x25W6MYqWWIIE8MVBVjB5z97WQ+B+A+jVrdno8XAWonBXwfSA7RX2+z8F+A +2AbBpIgGNbW0v7YbPdRinHWbXvccWQ+stNa8Rg3rhf0Z+c3AqMSzJMo3G1fK6565z1ZjPmQya0Qv +V0TRsXRtBPwJCaKOhweMRm/8cUoKBK0UT2D+xtbmag2hhlk+nX9rUAtAuH8zI15WZN+IzyImPNZg +xtBm9hK9yEWQcze0+vLvlGduZb0jh5nMiJaeDg8fADk8I46ZtKkbA595X12HG4szWKNPoeo6M6eg +lRRkV3UFyNqQv+EJspmiSWp3qwLN1+lAwdVRIf/58UrJCThn3FDe/EDThjMJD0/AmvEZ2QB6ptjD +ku8mAKuIM90NSkDayS1/mhAEQCThrEFsEc3yWrKtkZGl01eOTyRvVQcfzEfiG5nYJSIj7zz9NQ1K +JEoXNtz3NNmEYKxJ3IlaFcCl/RdWDcuHT3s86OoiuUb5FoQbxPsgkX75vUd0N7C4tBPFugzxDlho +e6BXgBTLS5miqes9Sld5L4q02q44VR07NfmY3LX72vFDcWX8mEpLtSOPnyu0LtzT71kVpWlt9aV2 +LvtCY1P7fsE+Ux9CtwSzLczYzxpu6d7QVQtbQQJLNDsxcGKrfiWfoP0EpAleG4DlrFgKE7DnKXw6 +uV6henTS8UGOGEgFmkAM5ogsZLsNght/Ty5PHwTWYgm/nBc3s1UEqSCpbl8CKZyRQys76I3yP4+J +bSgXCId3u2XZqYoUqfnaqcFaPzkn5evrIIelAbZQJRQioHN+++TsCh7RifuOSVMOswrFEtXfeSUI +JCvljAZBFFtl3PjzmKdP64oBaW5nMglSG1lBqTQe40qajHS0EfAsaLEbh8HsciQNE2krCKCkGSN8 +UkzmtQO7ErwvGVrmIuYbgJqzDcE2I2a/Z3Lac//hwBAcBsF+yfWLGXmNQiNcaHnmoZCkekctfJFV +lbPhaapODNLjhKoMXJkOvBk5MRJal0MMaBtUnxBCzeazIkkPxy1S6L1KGm85x+l6UtzHqPKuYF+w +KoOUlb+9jckpStrgll/o5xGUU/hgWsMZtfYTNiq2ShlpjxDT4OuimS26O2jTlCJl8nhbSxc23iC7 +EOSsV8DolO2oUF2JmBpfqQWsOG/88CZhQqN7CQWM734bLXDrSdYE4WI+YgINTnQvM6nZr+U6+kqp +2ORCVQ8huhM20uj0/+adTe1zowyijWi4aod6cLhQ7kZD4PFio5Y6omaHXLUNaPofPMFB3Bl9owKI +bhJJ0GJ8V/abRegfRHNve9w74BDFoPs1BZJBz3H9OEwguFKSk/Jr4ep5U2op9d7Um87FtUwWVtBd +bAyIanLdh3TGW1haNyhfiCk8aR5MlzAvBV9iuNK2aw5yxCgowa/VhuLQaIVFSrZrjvfwvFoYK1re +ke6nSM3n1/rmbu+BY6qG5u+3SQs4Oob9dD+y4nN7N1IhUY0jf4hYDfsUrexVdEsStu54riCyNLIL +czHtc+60dpqZFGFIbMJeDqgkUR6msurjr75bEwvuB80rMPbHTkbo9JNf4bBAxKf/IJiokE4J6Rjr +tFZTDMh48Rjp/zGumLhRPstHZHoz6ETMDmC2c5IsAF77F6ofytqS1i+81W6jIzAUhyyMKCi+EgM7 +Lo3rFzyeRVBMf4sgPajI2NnUpMzm9Zn4p/HlxxWu+wUu6bv4IjQS12jdA7OuRA03LaVr7vIJhOIc +g5lYj307khG0uIyZVa/Wh9/Bi0wCwecoACcebEeD+hIKvevZqR8VZBlB3DRoEzbOe1v9mnf7TzG4 +zReNRAT+TAuX19Ne8bmMT2ZYXsAGF3U+1aKNFuxaXVblO9HIKZ4g63/u0EK2ikt0zDpGIg0s7zD5 +dVA83t4xHTRa5H0S03336hd8FK9FgZ6+1tTCuxtdfOnGDCw53Uha0GHkK9O3GwBI7rdbP0bTvmx3 +iMawl6swyeSPAl1/yXZ6/ud8frt9V3tCiUiMO9FyN+F5E371JXHhfcY1D5/FQ0cAULzVUQtaxO/V +u/KzIZDZ/LjWl/e0iBhtZG1DFVws0djmdkZdlddoDSJyQRU4XPGQr3J9EF8+AelTMo51bGUPVEC7 +PO00NRw4XW228K61C4FTeq4vvUoCQjr73rmG/iDPS/trXsYQjU160a3Jb/aMFHY0x7kw5vT1h5Cf +ZR5sq/Ktlmattr81zgdYbN8/YHtFbISj9hctuHTTolv9zHgOJmuKMyS8UHQYrux8JFGKXjM4QNv0 +OOK09mIafWnAnlzHXwuvgdqZxUhua+Tn/C95Aps1SfwLxDmb8h++xwayZWAwGQ1/pjZGj2oneEQc +e4yF5lR+rPIMN6ggNA66WdsHUVUH8nU12a2tsPV/xN/0ODFy3R5Lt81SgUsjdhwqWrOwDWYKx7Lw +ULCsLvraD0LGdJnccojryAXkgLFRppVmwfHyEq61vAGkf6DDPPJC0nU6KogVthHztYPwjmUyaDkE +Hm5IT6qto6YhU0SwIcqdSq6xIXgVx85zKhLyXQfp8wTsAifaRqNqFePNCicZsXROlXgWMKz2VNaA +ppRsecTb+6fTbiO8GHslXR7uk5EZ/6Xa6CwKgOd5L+SzKSlVQb953TgLW16pW1yTDPrXE0ztQ2c0 +ACCm95j/y3DOhtU7/ZnijQb1VZlARiYrQ4jV5c5KkCStH5LYd2Im2PxUjfkloJQ8NCs9fTkmn7h7 +BeM6eVEXXX0J2KtLKyV4WeQxFuOuB7BSBoNKwSWV1Yt7jH2TqNQmqwp2RkHblR9ARxKPGpYDuds7 +ltfGDW/8EBPthF+ub5WNnYEjXHDxoV+OCoI9UvfNCO8gni8HJf1b+sTJhcc56S1tpcPziFcd6gTM +Mwk1ljLaBYqOhInkDi9G6ok2bsdrB1FJuvIXsmezJpal8Gn1KA/7iKtqv/w4v/O0LgH78/OCtFfl +aZgTbZ+ery6gsD7XqgB+KVBa6Ez4+5W03Q3Ocgbu1tAn1rmu+VmcVRAje/mo1ltvz3TuLDvGa9Te +5Wpg4Do/OBYu0Dsb/tjVC3f4g14/bDhpK/PJkjqtUCArMSdQcpE1aOzxS4ROGPPX/BP8uLuWbGAG +UOqbjhmn3y5AiinpTCC5BgUSvdX7igGf11d/+rktPCUtor50vzPfJFzI837MxhiWEf9Dfm9L7cV0 +HDu+PBHF1CE0gF+TaSeEgLf3cUdQfty2tfrqA+SUi8vebdaOBIVrdQwIf0MFYdxKSpYqhFshwIkx +n84YYfYNM4J8V5qwnkGaVGITbVo1orebXFKCeDYSiN+yeuZld2vV5Zz8FaptZCU0CN+rTyIldIK0 +j81EDgYcUKvjyxOYUxbH6UsuXmi2vZgQfbDMyQ79p6K03JaQAeaDvOjQLl4FdE6HGA8O4uM2aJyL +pZOnVjdj47zcX0Ah8F2TZ6YH76fMW+Qi2/s2RsVKnGLVWhzpSICmi5igcgeRSRsurUwUYUWsDl2E +zUg6G+n2AJFaJQItSJwoiixxKgVaMiducsVJ+Sr12nUKH59AGaVyx+nmk3SIMtpigPZtlnv2MRHp +3Fn9zV24EkGi6NkVLgslKEe8UOcYZOEZybzbkSz/24fiTyRAnaIb1PLH+zkwiXvPuXoaW/qRD+28 +mlCtWlm7vCSu6zcNk9Dp3AuDAB5HC5ruS1uPHHLQb6QSTElmMlYXV5UnyxQDbUBPybQ9R+5WzCp9 +A8gKZ4W3qAEALsmK6DfDayEepkLSz/1jseeq31ZkVxzytbZuGNtbVJn241QH0E/QoxPUQCfV133Z +iNec7okJorscEM9m6EfGPhBi5D5Jm/Q8fOLz2iu399MiDKDZu9yt9qEV7mh7 + + + diff --git a/.github/h2spec.config b/.github/h2spec.config new file mode 100644 index 0000000..745a637 --- /dev/null +++ b/.github/h2spec.config @@ -0,0 +1,27 @@ +global + log stdout local0 + tune.ssl.default-dh-param 2048 + tune.ssl.capture-buffer-size 1 + +defaults + mode http + + timeout connect 5s + timeout client 30s + timeout client-fin 1s + timeout server 30s + timeout server-fin 1s + timeout http-request 10s + timeout http-keep-alive 300s + + option logasap + option http-buffer-request + +frontend h2 + mode http + bind 127.0.0.1:8443 ssl crt reg-tests/ssl/common.pem alpn h2,http/1.1 + default_backend h2 + +backend h2 + errorfile 200 .github/errorfile + http-request deny deny_status 200 diff --git a/.github/matrix.py b/.github/matrix.py new file mode 100755 index 0000000..ffc3414 --- /dev/null +++ b/.github/matrix.py @@ -0,0 +1,201 @@ +#!/usr/bin/python3 + +# Copyright 2019 Ilya Shipitsin +# Copyright 2020 Tim Duesterhus +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version +# 2 of the License, or (at your option) any later version. + +import json +import sys +import urllib.request +import re +from os import environ + +if len(sys.argv) == 2: + ref_name = sys.argv[1] +else: + print("Usage: {} ".format(sys.argv[0]), file=sys.stderr) + sys.exit(1) + +print("Generating matrix for type '{}'.".format(ref_name)) + +def clean_ssl(ssl): + return ssl.replace("_VERSION", "").lower() + +def determine_latest_openssl(ssl): + openssl_tags = urllib.request.urlopen("https://api.github.com/repos/openssl/openssl/tags") + tags = json.loads(openssl_tags.read().decode('utf-8')) + latest_tag = '' + for tag in tags: + name = tag['name'] + if "openssl-" in name: + if name > latest_tag: + latest_tag = name + return "OPENSSL_VERSION={}".format(latest_tag[8:]) + +def determine_latest_libressl(ssl): + libressl_download_list = urllib.request.urlopen("http://ftp.openbsd.org/pub/OpenBSD/LibreSSL/") + for line in libressl_download_list.readlines(): + decoded_line = line.decode("utf-8") + if "libressl-" in decoded_line and ".tar.gz.asc" in decoded_line: + l = re.split("libressl-|.tar.gz.asc", decoded_line)[1] + return "LIBRESSL_VERSION={}".format(l) + +def clean_compression(compression): + return compression.replace("USE_", "").lower() + + +def get_asan_flags(cc): + return [ + "USE_OBSOLETE_LINKER=1", + 'DEBUG_CFLAGS="-g -fsanitize=address"', + 'LDFLAGS="-fsanitize=address"', + 'CPU_CFLAGS.generic="-O1"', + ] + + +matrix = [] + +# Ubuntu + +os = "ubuntu-latest" if "haproxy-" not in ref_name else "ubuntu-22.04" +TARGET = "linux-glibc" +for CC in ["gcc", "clang"]: + matrix.append( + { + "name": "{}, {}, no features".format(os, CC), + "os": os, + "TARGET": TARGET, + "CC": CC, + "FLAGS": [], + } + ) + + matrix.append( + { + "name": "{}, {}, all features".format(os, CC), + "os": os, + "TARGET": TARGET, + "CC": CC, + "FLAGS": [ + "USE_ZLIB=1", + "USE_OT=1", + "OT_INC=${HOME}/opt-ot/include", + "OT_LIB=${HOME}/opt-ot/lib", + "OT_RUNPATH=1", + "USE_PCRE=1", + "USE_PCRE_JIT=1", + "USE_LUA=1", + "USE_OPENSSL=1", + "USE_SYSTEMD=1", + "USE_WURFL=1", + "WURFL_INC=addons/wurfl/dummy", + "WURFL_LIB=addons/wurfl/dummy", + "USE_DEVICEATLAS=1", + "DEVICEATLAS_SRC=addons/deviceatlas/dummy", + "USE_PROMEX=1", + "USE_51DEGREES=1", + "51DEGREES_SRC=addons/51degrees/dummy/pattern", + ], + } + ) + +# ASAN + + matrix.append( + { + "name": "{}, {}, ASAN, all features".format(os, CC), + "os": os, + "TARGET": TARGET, + "CC": CC, + "FLAGS": get_asan_flags(CC) + + [ + "USE_ZLIB=1", + "USE_OT=1", + "OT_INC=${HOME}/opt-ot/include", + "OT_LIB=${HOME}/opt-ot/lib", + "OT_RUNPATH=1", + "USE_PCRE=1", + "USE_PCRE_JIT=1", + "USE_LUA=1", + "USE_OPENSSL=1", + "USE_SYSTEMD=1", + "USE_WURFL=1", + "WURFL_INC=addons/wurfl/dummy", + "WURFL_LIB=addons/wurfl/dummy", + "USE_DEVICEATLAS=1", + "DEVICEATLAS_SRC=addons/deviceatlas/dummy", + "USE_PROMEX=1", + "USE_51DEGREES=1", + "51DEGREES_SRC=addons/51degrees/dummy/pattern", + ], + } + ) + + for compression in ["USE_ZLIB=1"]: + matrix.append( + { + "name": "{}, {}, gz={}".format( + os, CC, clean_compression(compression) + ), + "os": os, + "TARGET": TARGET, + "CC": CC, + "FLAGS": [compression], + } + ) + + for ssl in [ + "stock", + "OPENSSL_VERSION=1.0.2u", + "OPENSSL_VERSION=1.1.1s", + "QUICTLS=yes", +# "BORINGSSL=yes", + ] + (["OPENSSL_VERSION=latest", "LIBRESSL_VERSION=latest"] if "haproxy-" not in ref_name else []): + flags = ["USE_OPENSSL=1"] + if ssl == "BORINGSSL=yes" or ssl == "QUICTLS=yes" or "LIBRESSL" in ssl: + flags.append("USE_QUIC=1") + if ssl != "stock": + flags.append("SSL_LIB=${HOME}/opt/lib") + flags.append("SSL_INC=${HOME}/opt/include") + if "LIBRESSL" in ssl and "latest" in ssl: + ssl = determine_latest_libressl(ssl) + if "OPENSSL" in ssl and "latest" in ssl: + ssl = determine_latest_openssl(ssl) + + matrix.append( + { + "name": "{}, {}, ssl={}".format(os, CC, clean_ssl(ssl)), + "os": os, + "TARGET": TARGET, + "CC": CC, + "ssl": ssl, + "FLAGS": flags, + } + ) + +# macOS + +os = "macos-latest" if "haproxy-" not in ref_name else "macos-12" +TARGET = "osx" +for CC in ["clang"]: + matrix.append( + { + "name": "{}, {}, no features".format(os, CC), + "os": os, + "TARGET": TARGET, + "CC": CC, + "FLAGS": [], + } + ) + +# Print matrix + +print(json.dumps(matrix, indent=4, sort_keys=True)) + +if environ.get('GITHUB_OUTPUT') is not None: + with open(environ.get('GITHUB_OUTPUT'), 'a') as f: + print("matrix={}".format(json.dumps({"include": matrix})), file=f) diff --git a/.github/vtest.json b/.github/vtest.json new file mode 100644 index 0000000..8e8165c --- /dev/null +++ b/.github/vtest.json @@ -0,0 +1,14 @@ +{ + "problemMatcher": [ + { + "owner": "vtest", + "pattern": [ + { + "regexp": "^#(\\s+top\\s+TEST\\s+(.*)\\s+FAILED.*)", + "file": 2, + "message": 1 + } + ] + } + ] +} diff --git a/.github/workflows/codespell.yml b/.github/workflows/codespell.yml new file mode 100644 index 0000000..2243d8b --- /dev/null +++ b/.github/workflows/codespell.yml @@ -0,0 +1,19 @@ +name: Spelling Check + +on: + schedule: + - cron: "0 0 * * 2" + +permissions: + contents: read + +jobs: + codespell: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: codespell-project/codespell-problem-matcher@v1 + - uses: codespell-project/actions-codespell@master + with: + skip: CHANGELOG,Makefile,*.fig,*.pem + ignore_words_list: ist,ists,hist,wan,ca,cas,que,ans,te,nd,referer,ot,uint,iif,fo,keep-alives,dosen,ifset,thrid,strack,ba,chck,hel,unx,mor diff --git a/.github/workflows/compliance.yml b/.github/workflows/compliance.yml new file mode 100644 index 0000000..509eaf8 --- /dev/null +++ b/.github/workflows/compliance.yml @@ -0,0 +1,57 @@ + +name: Spec Compliance + +on: + schedule: + - cron: "0 0 * * 3" + +permissions: + contents: read + +jobs: + h2spec: + name: h2spec + runs-on: ${{ matrix.os }} + strategy: + matrix: + include: + - TARGET: linux-glibc + CC: gcc + os: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Install h2spec + id: install-h2spec + run: | + H2SPEC_VERSION=`curl --silent "https://api.github.com/repos/summerwind/h2spec/releases/latest" | jq -r -j '.tag_name'` + curl -fsSL https://github.com/summerwind/h2spec/releases/download/${H2SPEC_VERSION}/h2spec_linux_amd64.tar.gz -o h2spec.tar.gz + tar xvf h2spec.tar.gz + sudo install -m755 h2spec /usr/local/bin/h2spec + echo "version=${H2SPEC_VERSION}" >> $GITHUB_OUTPUT + - name: Compile HAProxy with ${{ matrix.CC }} + run: | + make -j$(nproc) all \ + ERR=1 \ + TARGET=${{ matrix.TARGET }} \ + CC=${{ matrix.CC }} \ + DEBUG="-DDEBUG_STRICT -DDEBUG_MEMORY_POOLS -DDEBUG_POOL_INTEGRITY" \ + USE_OPENSSL=1 + sudo make install + - name: Show HAProxy version + id: show-version + run: | + echo "::group::Show dynamic libraries." + if command -v ldd > /dev/null; then + # Linux + ldd $(which haproxy) + else + # macOS + otool -L $(which haproxy) + fi + echo "::endgroup::" + haproxy -vv + echo "version=$(haproxy -v |awk 'NR==1{print $3}')" >> $GITHUB_OUTPUT + - name: Launch HAProxy ${{ steps.show-version.outputs.version }} + run: haproxy -f .github/h2spec.config -D + - name: Run h2spec ${{ steps.install-h2spec.outputs.version }} + run: h2spec -Svtk -h 127.0.0.1 -p 8443 diff --git a/.github/workflows/contrib.yml b/.github/workflows/contrib.yml new file mode 100644 index 0000000..99a1576 --- /dev/null +++ b/.github/workflows/contrib.yml @@ -0,0 +1,25 @@ +name: Contrib + +on: + push: + +permissions: + contents: read + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Compile admin/halog/halog + run: | + make admin/halog/halog + - name: Compile dev/flags/flags + run: | + make dev/flags/flags + - name: Compile dev/poll/poll + run: | + make dev/poll/poll + - name: Compile dev/hpack + run: | + make dev/hpack/decode dev/hpack/gen-enc dev/hpack/gen-rht diff --git a/.github/workflows/coverity.yml b/.github/workflows/coverity.yml new file mode 100644 index 0000000..e208c8c --- /dev/null +++ b/.github/workflows/coverity.yml @@ -0,0 +1,43 @@ + +# +# scan results: https://scan.coverity.com/projects/haproxy +# + +name: Coverity + +on: + schedule: + - cron: "0 0 * * *" + +permissions: + contents: read + +jobs: + scan: + runs-on: ubuntu-latest + if: ${{ github.repository_owner == 'haproxy' }} + env: + COVERITY_SCAN_PROJECT_NAME: 'Haproxy' + COVERITY_SCAN_BRANCH_PATTERN: '*' + COVERITY_SCAN_NOTIFICATION_EMAIL: 'chipitsine@gmail.com' + # We cannot pass the DEBUG at once here because Coverity splits + # parameters at whitespaces, without taking quoting into account. + COVERITY_SCAN_BUILD_COMMAND: "make CC=clang TARGET=linux-glibc USE_ZLIB=1 USE_PCRE=1 USE_PCRE_JIT=1 USE_LUA=1 USE_OPENSSL=1 USE_QUIC=1 USE_SYSTEMD=1 USE_WURFL=1 WURFL_INC=addons/wurfl/dummy WURFL_LIB=addons/wurfl/dummy USE_DEVICEATLAS=1 DEVICEATLAS_SRC=addons/deviceatlas/dummy USE_51DEGREES=1 51DEGREES_SRC=addons/51degrees/dummy/pattern ADDLIB=\"-Wl,-rpath,$HOME/opt/lib/\" SSL_LIB=${HOME}/opt/lib SSL_INC=${HOME}/opt/include DEBUG+=-DDEBUG_STRICT=1 DEBUG+=-DDEBUG_USE_ABORT=1" + steps: + - uses: actions/checkout@v3 + - name: Install apt dependencies + run: | + sudo apt-get update + sudo apt-get install -y \ + liblua5.3-dev \ + libsystemd-dev + - name: Install QUICTLS + run: | + QUICTLS=yes scripts/build-ssl.sh + - name: Build WURFL + run: make -C addons/wurfl/dummy + - name: Run Coverity Scan + env: + COVERITY_SCAN_TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }} + run: | + curl -fsSL "https://scan.coverity.com/scripts/travisci_build_coverity_scan.sh" | bash || true diff --git a/.github/workflows/cross-zoo.yml b/.github/workflows/cross-zoo.yml new file mode 100644 index 0000000..e2a5816 --- /dev/null +++ b/.github/workflows/cross-zoo.yml @@ -0,0 +1,110 @@ +# +# this is naamed "zoo" after OpenSSL "cross zoo pipeline" +# +name: Cross Compile + +on: + schedule: + - cron: "0 0 21 * *" + +permissions: + contents: read + +jobs: + cross-compilation: + strategy: + matrix: + platform: [ + { + arch: aarch64-linux-gnu, + libs: libc6-dev-arm64-cross, + target: linux-aarch64 + }, { + arch: alpha-linux-gnu, + libs: libc6.1-dev-alpha-cross, + target: linux-alpha-gcc + }, { + arch: arm-linux-gnueabi, + libs: libc6-dev-armel-cross, + target: linux-armv4 + }, { + arch: arm-linux-gnueabihf, + libs: libc6-dev-armhf-cross, + target: linux-armv4 + }, { + arch: hppa-linux-gnu, + libs: libc6-dev-hppa-cross, + target: -static linux-generic32 + }, { + arch: m68k-linux-gnu, + libs: libc6-dev-m68k-cross, + target: -static -m68040 linux-latomic + }, { + arch: mips-linux-gnu, + libs: libc6-dev-mips-cross, + target: -static linux-mips32 + }, { + arch: mips64-linux-gnuabi64, + libs: libc6-dev-mips64-cross, + target: -static linux64-mips64 + }, { + arch: mipsel-linux-gnu, + libs: libc6-dev-mipsel-cross, + target: linux-mips32 + }, { + arch: powerpc64le-linux-gnu, + libs: libc6-dev-ppc64el-cross, + target: linux-ppc64le + }, { + arch: riscv64-linux-gnu, + libs: libc6-dev-riscv64-cross, + target: linux64-riscv64 + }, { + arch: s390x-linux-gnu, + libs: libc6-dev-s390x-cross, + target: linux64-s390x + }, { + arch: sh4-linux-gnu, + libs: libc6-dev-sh4-cross, + target: no-async linux-latomic + }, { + arch: hppa-linux-gnu, + libs: libc6-dev-hppa-cross, + target: linux-generic32, + }, { + arch: m68k-linux-gnu, + libs: libc6-dev-m68k-cross, + target: -mcfv4e linux-latomic + }, { + arch: mips-linux-gnu, + libs: libc6-dev-mips-cross, + target: linux-mips32 + }, { + arch: mips64-linux-gnuabi64, + libs: libc6-dev-mips64-cross, + target: linux64-mips64 + }, { + arch: sparc64-linux-gnu, + libs: libc6-dev-sparc64-cross, + target: linux64-sparcv9 + } + ] + runs-on: ubuntu-latest + steps: + - name: install packages + run: | + sudo apt-get update + sudo apt-get -yq --force-yes install \ + gcc-${{ matrix.platform.arch }} \ + ${{ matrix.platform.libs }} + - uses: actions/checkout@v2 + + + - name: install quictls + run: | + QUICTLS_EXTRA_ARGS="--cross-compile-prefix=${{ matrix.platform.arch }}- ${{ matrix.platform.target }}" QUICTLS=yes scripts/build-ssl.sh + + - name: Build + run: | + make ERR=1 CC=${{ matrix.platform.arch }}-gcc TARGET=linux-glibc USE_LIBCRYPT= USE_OPENSSL=1 USE_QUIC=1 USE_PROMEX=1 SSL_LIB=${HOME}/opt/lib SSL_INC=${HOME}/opt/include ADDLIB="-Wl,-rpath,${HOME}/opt/lib" + diff --git a/.github/workflows/musl.yml b/.github/workflows/musl.yml new file mode 100644 index 0000000..8eb8310 --- /dev/null +++ b/.github/workflows/musl.yml @@ -0,0 +1,58 @@ +name: alpine/musl + +on: + push: + +permissions: + contents: read + +jobs: + musl: + name: gcc + runs-on: ubuntu-latest + container: + image: alpine:latest + options: --privileged --ulimit core=-1 --security-opt seccomp=unconfined + volumes: + - /tmp/core:/tmp/core + steps: + - name: Setup coredumps + run: | + ulimit -c unlimited + echo '/tmp/core/core.%h.%e.%t' > /proc/sys/kernel/core_pattern + - uses: actions/checkout@v3 + - name: Install dependencies + run: apk add gcc gdb make tar git python3 libc-dev linux-headers pcre-dev pcre2-dev openssl-dev lua5.3-dev grep socat curl musl-dbg lua5.3-dbg + - name: Install VTest + run: scripts/build-vtest.sh + - name: Build + run: make -j$(nproc) TARGET=linux-musl DEBUG_CFLAGS='-ggdb3' CC=cc V=1 USE_LUA=1 LUA_INC=/usr/include/lua5.3 LUA_LIB=/usr/lib/lua5.3 USE_OPENSSL=1 USE_PCRE2=1 USE_PCRE2_JIT=1 USE_PROMEX=1 + - name: Show version + run: ./haproxy -vv + - name: Show linked libraries + run: ldd haproxy + - name: Install problem matcher for VTest + # This allows one to more easily see which tests fail. + run: echo "::add-matcher::.github/vtest.json" + - name: Run VTest + id: vtest + run: make reg-tests VTEST_PROGRAM=../vtest/vtest REGTESTS_TYPES=default,bug,devel + - name: Show coredumps + if: ${{ failure() && steps.vtest.outcome == 'failure' }} + run: | + ls /tmp/core/ + for file in /tmp/core/core.*; do + printf "::group::" + gdb -ex 'thread apply all bt full' ./haproxy $file + echo "::endgroup::" + done + - name: Show results + if: ${{ failure() }} + run: | + for folder in /tmp/haregtests-*/vtc.*; do + printf "::group::" + cat $folder/INFO + cat $folder/LOG + echo "::endgroup::" + done + shopt -s nullglob diff --git a/.github/workflows/openssl-nodeprecated.yml b/.github/workflows/openssl-nodeprecated.yml new file mode 100644 index 0000000..e7f7ffa --- /dev/null +++ b/.github/workflows/openssl-nodeprecated.yml @@ -0,0 +1,33 @@ +# +# special purpose CI: test against OpenSSL built in "no-deprecated" mode +# let us run those builds weekly +# +# for example, OpenWRT uses such OpenSSL builds (those builds are smaller) +# +# +# some details might be found at NL: https://www.mail-archive.com/haproxy@formilux.org/msg35759.html +# GH: https://github.com/haproxy/haproxy/issues/367 + +name: openssl no-deprecated + +on: + schedule: + - cron: "0 0 * * 4" + +permissions: + contents: read + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Install VTest + run: | + scripts/build-vtest.sh + - name: Compile HAProxy + run: | + make DEFINE="-DOPENSSL_API_COMPAT=0x10100000L -DOPENSSL_NO_DEPRECATED" -j3 CC=gcc ERR=1 TARGET=linux-glibc USE_OPENSSL=1 + - name: Run VTest + run: | + make reg-tests VTEST_PROGRAM=../vtest/vtest REGTESTS_TYPES=default,bug,devel diff --git a/.github/workflows/vtest.yml b/.github/workflows/vtest.yml new file mode 100644 index 0000000..8c13d13 --- /dev/null +++ b/.github/workflows/vtest.yml @@ -0,0 +1,155 @@ +# Copyright 2019 Ilya Shipitsin +# Copyright 2020 Tim Duesterhus +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version +# 2 of the License, or (at your option) any later version. + +name: VTest + +on: + push: + +permissions: + contents: read + +jobs: + # The generate-matrix job generates the build matrix using JSON output + # generated by .github/matrix.py. + generate-matrix: + name: Generate Build Matrix + runs-on: ubuntu-latest + outputs: + matrix: ${{ steps.set-matrix.outputs.matrix }} + steps: + - uses: actions/checkout@v3 + - name: Generate Build Matrix + id: set-matrix + run: python3 .github/matrix.py "${{ github.ref_name }}" + + # The Test job actually runs the tests. + Test: + name: ${{ matrix.name }} + needs: generate-matrix + runs-on: ${{ matrix.os }} + strategy: + matrix: ${{ fromJson(needs.generate-matrix.outputs.matrix) }} + fail-fast: false + env: + # Configure a short TMPDIR to prevent failures due to long unix socket + # paths. + TMPDIR: /tmp + # Force ASAN output into asan.log to make the output more readable. + ASAN_OPTIONS: log_path=asan.log + OT_CPP_VERSION: 1.6.0 + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 100 +# +# Github Action cache key cannot contain comma, so we calculate it based on job name +# + - name: Generate cache key + id: generate-cache-key + run: | + echo "key=$(echo ${{ matrix.name }} | sha256sum | awk '{print $1}')" >> $GITHUB_OUTPUT + + - name: Cache SSL libs + if: ${{ matrix.ssl && matrix.ssl != 'stock' && matrix.ssl != 'BORINGSSL=yes' && matrix.ssl != 'QUICTLS=yes' }} + id: cache_ssl + uses: actions/cache@v3 + with: + path: '~/opt/' + key: ssl-${{ steps.generate-cache-key.outputs.key }} + + - name: Cache OpenTracing + if: ${{ contains(matrix.FLAGS, 'USE_OT=1') }} + id: cache_ot + uses: actions/cache@v3 + with: + path: '~/opt-ot/' + key: ot-${{ matrix.CC }}-${{ env.OT_CPP_VERSION }}-${{ contains(matrix.name, 'ASAN') }} + - name: Install apt dependencies + if: ${{ startsWith(matrix.os, 'ubuntu-') }} + run: | + sudo apt-get update + sudo apt-get install -y \ + liblua5.3-dev \ + libpcre2-dev \ + libsystemd-dev \ + ninja-build \ + socat + - name: Install brew dependencies + if: ${{ startsWith(matrix.os, 'macos-') }} + run: | + brew install socat + brew install lua + - name: Install VTest + run: | + scripts/build-vtest.sh + - name: Install SSL ${{ matrix.ssl }} + if: ${{ matrix.ssl && matrix.ssl != 'stock' && steps.cache_ssl.outputs.cache-hit != 'true' }} + run: env ${{ matrix.ssl }} scripts/build-ssl.sh + - name: Install OpenTracing libs + if: ${{ contains(matrix.FLAGS, 'USE_OT=1') && steps.cache_ot.outputs.cache-hit != 'true' }} + run: | + OT_PREFIX=${HOME}/opt-ot scripts/build-ot.sh + - name: Build WURFL + if: ${{ contains(matrix.FLAGS, 'USE_WURFL=1') }} + run: make -C addons/wurfl/dummy + - name: Compile HAProxy with ${{ matrix.CC }} + run: | + echo "::group::Show compiler's version" + echo | ${{ matrix.CC }} -v + echo "::endgroup::" + echo "::group::Show platform specific defines" + echo | ${{ matrix.CC }} -dM -xc -E - + echo "::endgroup::" + make -j$(nproc) all \ + ERR=1 \ + TARGET=${{ matrix.TARGET }} \ + CC=${{ matrix.CC }} \ + DEBUG="-DDEBUG_STRICT -DDEBUG_MEMORY_POOLS -DDEBUG_POOL_INTEGRITY" \ + ${{ join(matrix.FLAGS, ' ') }} \ + ADDLIB="-Wl,-rpath,/usr/local/lib/ -Wl,-rpath,$HOME/opt/lib/" + sudo make install + - name: Show HAProxy version + id: show-version + run: | + echo "::group::Show dynamic libraries." + if command -v ldd > /dev/null; then + # Linux + ldd $(which haproxy) + else + # macOS + otool -L $(which haproxy) + fi + echo "::endgroup::" + haproxy -vv + echo "version=$(haproxy -v |awk 'NR==1{print $3}')" >> $GITHUB_OUTPUT + - name: Install problem matcher for VTest + # This allows one to more easily see which tests fail. + run: echo "::add-matcher::.github/vtest.json" + - name: Run VTest for HAProxy ${{ steps.show-version.outputs.version }} + id: vtest + run: | + # This is required for macOS which does not actually allow to increase + # the '-n' soft limit to the hard limit, thus failing to run. + ulimit -n 65536 + make reg-tests VTEST_PROGRAM=../vtest/vtest REGTESTS_TYPES=default,bug,devel + - name: Show VTest results + if: ${{ failure() && steps.vtest.outcome == 'failure' }} + run: | + for folder in ${TMPDIR}/haregtests-*/vtc.*; do + printf "::group::" + cat $folder/INFO + cat $folder/LOG + echo "::endgroup::" + done + shopt -s nullglob + for asan in asan.log*; do + echo "::group::$asan" + cat $asan + echo "::endgroup::" + done diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml new file mode 100644 index 0000000..3030908 --- /dev/null +++ b/.github/workflows/windows.yml @@ -0,0 +1,67 @@ +# Copyright 2019 Ilya Shipitsin +# Copyright 2020 Tim Duesterhus +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version +# 2 of the License, or (at your option) any later version. + +name: Windows + +on: + push: + +permissions: + contents: read + +jobs: + msys2: + name: ${{ matrix.name }} + runs-on: ${{ matrix.os }} + defaults: + run: + shell: msys2 {0} + strategy: + matrix: + include: + - name: "Windows, gcc, all features" + TARGET: cygwin + CC: gcc + os: windows-latest + FLAGS: + - USE_OPENSSL=1 + - USE_PCRE=1 + - USE_PCRE_JIT=1 + - USE_THREAD=1 + - USE_ZLIB=1 + steps: + - uses: actions/checkout@v3 + - uses: msys2/setup-msys2@v2 + with: + install: >- + coreutils + curl + diffutils + gawk + gcc + make + tar + openssl-devel + pcre-devel + zlib-devel + - name: Compile HAProxy with ${{ matrix.CC }} + run: | + echo "::group::Show platform specific defines" + echo | ${{ matrix.CC }} -dM -xc -E - + echo "::endgroup::" + make -j$(nproc) all \ + ERR=1 \ + TARGET=${{ matrix.TARGET }} \ + CC=${{ matrix.CC }} \ + DEBUG="-DDEBUG_STRICT -DDEBUG_MEMORY_POOLS -DDEBUG_POOL_INTEGRITY" \ + ${{ join(matrix.FLAGS, ' ') }} + - name: Show HAProxy version + id: show-version + run: | + ./haproxy -vv + echo "version=$(./haproxy -v |awk 'NR==1{print $3}')" >> $GITHUB_OUTPUT diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d93100e --- /dev/null +++ b/.gitignore @@ -0,0 +1,55 @@ +# Below we forbid everything and only allow what we know, that's much easier +# than blocking about 500 different test files and bug report outputs. +/.* +/* +!/.cirrus.yml +!/.gitattributes +!/.github +!/.gitignore +!/.travis.yml +!/CHANGELOG +!/LICENSE +!/BRANCHES +!/Makefile +!/README +!/INSTALL +!/CONTRIBUTING +!/MAINTAINERS +!/SUBVERS +!/VERDATE +!/VERSION +!/addons +!/admin +!/dev +!/doc +!/ebtree +!/examples +!/include +!/src +!/tests +!/debian +!/scripts +!/reg-tests +# Reject some generic files +*.o +*.a +*~ +*.rej +*.orig +*.bak +# And reject some specific files +/admin/halog/halog +/admin/dyncookie/dyncookie +/admin/iprange/ip6range +/admin/iprange/iprange +/admin/systemd/haproxy.service +dev/base64/base64rev-gen +dev/flags/flags +dev/poll/poll +dev/tcploop/tcploop +dev/haring/haring +dev/hpack/decode +dev/hpack/gen-rht +/src/dlmalloc.c +/tests/test_hashes +doc/lua-api/_build diff --git a/.mailmap b/.mailmap new file mode 100644 index 0000000..f72077f --- /dev/null +++ b/.mailmap @@ -0,0 +1 @@ +Tim Duesterhus diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..7f5110e --- /dev/null +++ b/.travis.yml @@ -0,0 +1,54 @@ +dist: focal + +language: c + +branches: + only: + - master + +env: + global: + - FLAGS="USE_LUA=1 USE_OPENSSL=1 USE_PCRE=1 USE_PCRE_JIT=1 USE_SYSTEMD=1 USE_ZLIB=1" + - TMPDIR=/tmp + +addons: + apt: + update: true + packages: [ liblua5.3-dev, libsystemd-dev, libpcre2-dev, socat, libpcre3-dev ] + +matrix: + include: + - os: linux + arch: ppc64le + compiler: gcc + if: type == cron +# - os: linux +# arch: arm64 +# compiler: gcc +# if: type == cron + - os: linux + arch: arm64-graviton2 + group: edge + virt: vm + compiler: gcc + if: type == cron + - os: linux + arch: s390x + compiler: gcc + if: type == cron + +install: + - scripts/build-vtest.sh + +script: + - make -j$(nproc) ERR=1 TARGET=linux-glibc CC=$CC DEBUG=-DDEBUG_STRICT=1 $FLAGS + - ./haproxy -vv + - ldd haproxy + - make reg-tests VTEST_PROGRAM=../vtest/vtest REGTESTS_TYPES=default,bug,devel + +after_failure: + - | + for folder in ${TMPDIR}/*regtest*/vtc.*; do + cat $folder/INFO + cat $folder/LOG + done diff --git a/BRANCHES b/BRANCHES new file mode 100644 index 0000000..53b2ee9 --- /dev/null +++ b/BRANCHES @@ -0,0 +1,239 @@ +HAProxy branches and life cycle +=============================== + +The HAProxy project evolves quickly to stay up to date with modern features +found in web environments but also takes a great care of addressing bugs which +may affect deployed versions without forcing such users to upgrade when not +needed. For this reason the project is developed in branches. + +A branch is designated as two numbers separated by a dot, for example "1.8". +This numbering is historical. Each new development cycle increases the second +digit by one, and after it reaches '9' it goes back to zero and the first digit +increases by one. It effectively grows as a decimal number increased by 0.1 per +version. + +The complete version is made of the branch suffixed with "-dev" followed by a +sequence number during development, then by "." followed by a number when the +development of that branch is finished and the branch enters a maintenance +phase. The first release of a branch starts at ".0". Immediately after ".0" is +issued, the next branch is created as "-dev0" as an exact copy of the previous +branch's ".0" version. Thus we observe the following development sequence: + + ... 1.9-dev10 -> 1.9-dev11 -> 1.9.0 -> 2.0-dev0 -> 2.0-dev1 ... 2.0 -> ... + +Occasionally a series of "-rc" versions may be emitted between the latest -dev +and the release to mark the end of development and start of stabilizing, though +it's mostly a signal send to users that the release is approaching rather than +a change in the cycle as it is always hard to categorize patches. + +Very often the terms "branch" and "version" will be used interchangeably with +only the first two digits to designate "the latest version of that branch". So +when someone asks you "Could you please try the same on 1.8", it means "1.8.X" +with X as high as possible, thus for example 1.8.20 if this one is available at +this moment. + +During the maintenance phase, a maintenance branch is created for the just +released version. The development version remains in the development branch +called "master", or sometimes "-dev". If branches are represented vertically +and time horizontally, this will look like this: + + versions branch + 1.9-dev10 1.9-dev11 1.9.0 2.0-dev0 2.0-dev1 2.0-dev2 + ----+--------+---------+-------+---------+---------+----------> master + \ + \ 1.9.1 1.9.2 + `-----------+-------------+---------> 1.9 + +Each released version (e.g. 1.9.0 above) appears once in the master branch so +that it is easy to list history of changes between versions. + +Before version 1.4, development and maintenance were inter-mixed in the same +branch, which resulted in latest maintenance branches becoming unstable after +some point. This is why versions 1.3.14 and 1.3.15 became maintenance branches +on their own while the development pursued on 1.3 to stabilize again in the +latest versions. + +Starting with version 1.4.0, a rule has been set not to create new features +into a maintenance branch. It was not well respected and still created trouble +with certain 1.4 versions causing regressions and confusing users. + +Since 1.5.0 this "no new feature" rule has become strict and maintenance +versions only contain bug fixes that are necessary in this branch. This means +that any version X.Y.Z is necessarily more stable than X.Y.W with W master + 1.9.4 \ 1.9.5 1.9.6 1.9.7 + --+------------o-------+---------+-------------+------> 1.9 + 1.8.18 \ 1.8.19 1.8.20 + -----+-----------o------------+-------------+---------> 1.8 + +This principle ensures that you will always have a safe upgrade path from an +older branch to a newer: under no circumstances a bug that was already fixed +in an older branch will still be present in a newer one. In the diagram above, +a bug reported for 1.8.18 would be fixed between 2.0-dev4 and 2.0-dev5. The +fix will be backported into 1.9 and from there into 1.8. 1.9.5 will be issued +with the fix before 1.8.19 will be issued. This guarantees that for any version +1.8 having the fix, there always exists a version 1.9 with it as well. So if +you would upgrade to 1.8.19 to benefit from the fix and the next day decide +that for whatever new feature you need to upgrade to 1.9, you'll have 1.9.5 +available with the same set of fixes so you will not reintroduce a previously +fixed problem. + +In practice, it takes longer to release older versions than newer ones. There +are two reasons to this. One is technical: the fixes often require some +adaptations to be done for older versions. The other reason is stability: in +spite of the great care and the tests, there is always a faint risk that a fix +introduces a regression. By leaving fixes exposed in more recent versions +before appearing in older ones, there is a much smaller probability that such a +regression remains undetected when the next version of the older branch is +issued. + +So the rule for the best stability is very simple: + + STICK TO THE BRANCH THAT SUITS YOUR NEEDS AND APPLY ALL UPDATES. + +With other projects, some people developed a culture of backporting only a +selection of fixes into their own maintenance branch. Usually they consider +these fixes are critical, or security-related only. THIS IS TERRIBLY WRONG. +It is already very difficult for the developers who made the initial patch to +figure if and how it must be backported to an older branch, what extra patches +it depends on to be safe, as you can imagine it is impossible for anyone else +to make a safe guess about what to pick. + + A VERSION WHICH ONLY CONTAINS A SELECTION OF FIXES IS WAY MORE + DANGEROUS AND LESS STABLE THAN ONE WITHOUT ANY OF THESE FIXES. + +Branches up to 1.8 are all designated as "long-term supported" ("LTS" for +short), which means that they are maintained for several years after the +release. These branches were emitted at a pace of one per year since 1.5 in +2014. As of 2019, 1.5 is still supported and widely used, even though it very +rarely receives updates. After a few years these LTS branches enter a +"critical fixes only" status, which means that they will rarely receive a fix +but if that a critital issue affects them, a release will be made, with or +without any other fix. Once a version is not supported anymore, it will not +receive any fix at all and it will really be time for you to upgrade to a more +recent branch. Please note that even when an upgrade is needed, a great care is +given to backwards compatibility so that most configs written for version 1.1 +still work with little to no modification 16 years later on version 2.0. + +Since 1.9, the release pacing has increased to match faster moving feature sets +and a faster stabilization of the technical foundations. The principle is now +the following: + - one release is emitted between October and December, with an odd version + number (such as "1.9"). This version heavily focuses on risky changes that + are considered necessary to develop new features. It can for example bring + nice performance improvements as well as invisible changes that will serve + later ; these versions will only be emitted for developers and highly + skilled users. They will not be maintained for a long time, they will + receive updates for 12 to 18 months only after which they will be marked + End-Of-Life ("EOL" for short). They may receive delicate fixes during their + maintenance cycle so users have to be prepared to see some breakage once in + a while as fixes are stabilizing. THESE VERSIONS MUST ABSOLUTELY NOT BE + PACKAGED BY OPERATING SYSTEM VENDORS. + + - one release is emitted between May and June, with an even version number + (such as "2.0"). This version mostly relies on the technical foundations + brought by the previous release and tries hard not to apply risky changes. + Instead it will bring new user-visible features. Such versions will be + long-term supported and may be packaged by operating system vendors. + +This development model provides better stability for end users and better +feedback for developers: + - regular users stick to LTS versions which rely on the same foundations + as the previous releases that had 6 months to stabilize. In terms of + stability it really means that the point zero version already accumulated + 6 months of fixes and that it is much safer to use even just after it is + released. + + - for developers, given that the odd versions are solely used by highly + skilled users, it's easier to get advanced traces and captures, and there + is less pressure during bug reports because there is no doubt the user is + autonomous and knows how to work around the issue or roll back to the last + working version. + +Thus the release cycle from 1.8 to 2.2 should look like this: + + 1.8.0 1.9.0 2.0.0 2.1.0 2.2.0 + --+---------------+---------------+--------------+--------------+----> master + \ \ \ \ \ + \ \ \ \ `--> 2.2 LTS + \ \ \ `--+--+--+---+---> 2.1 + \ \ `----+-----+------+-------+----> 2.0 LTS + \ `--+-+-+--+---+------+--------+-----| EOL 1.9 + `---+---+---+-----+-------+-----------+---------------+------> 1.8 LTS + +In short the non-LTS odd releases can be seen as technological previews of the +next feature release, and will be terminated much earlier. The plan is to barely +let them overlap with the next non-LTS release, allowing advanced users to +always have the choice between the last two major releases. + +With all this in mind, what version should you use ? It's quite simple: + - if you're a first-time HAProxy user, just use the version provided by your + operating system. Just take a look at the "known bugs" section on the + haproxy.org web site to verify that it's not affected by bugs that could + have an impact for you. + + - if you don't want or cannot use the version shipped with your operating + system, it is possible that other people (including the package maintainer) + provide alternate versions. This is the case for Debian and Ubuntu for + example, where you can choose your distribution and pick the branch you + need here: https://haproxy.debian.net/ + + - if you want to build with specific options, apply some patches, you'll + have to build from sources. If you have little experience or are not + certain to devote regular time to perform this task, take an "old" branch + (i.e. 1-2 years old max, for example 1.8 when 2.0 is emitted). You'll avoid + most bugs and will not have to work too often to update your local version. + + - if you need a fresh version for application development, or to benefit from + latest improvements, take the most recent version of the most recent branch + and keep it up to date. You may even want to use the Git version or nightly + snapshots. + + - if you want to develop on HAProxy, use the master from the Git tree. + + - if you want to follow HAProxy's development by doing some tests without + the burden of entering too much into the development process, just use the + -dev versions of the master branch. At some point you'll feel the urge to + switch to the Git version anyway as it will ultimately simplify your work. + + - if you're installing it on unmanaged servers with little to no hostile + exposure, or your home router, you should pick the latest version in one + of the oldest supported branches. While it doesn't guarantee that you will + never have to upgrade it, at least as long as you don't use too complex a + setup, it's unlikely that you will need to update it often. + +And as a general rule, do not put a non-LTS version on a server unless you are +absolutely certain you are going to keep it up to date yourself and already +plan to replace it once the following LTS version is issued. If you are not +going to manage updates yourself, use pre-packaged versions exclusively and do +not expect someone else to have to deal with the burden of building from +sources. diff --git a/CHANGELOG b/CHANGELOG new file mode 100644 index 0000000..8fbe7b4 --- /dev/null +++ b/CHANGELOG @@ -0,0 +1,19097 @@ +ChangeLog : +=========== + +2023/03/28 : 2.6.12 + - BUG/MAJOR: poller: drop FD's tgid when masks don't match + - OPTIM: mux-h1: limit first read size to avoid wrapping + - BUG/MEDIUM: stream: do not try to free a failed stream-conn + - BUG/MEDIUM: mux-h2: do not try to free an unallocated h2s->sd + - BUG/MEDIUM: mux-h2: erase h2c->wait_event.tasklet on error path + - BUG/MEDIUM: stconn: don't set the type before allocation succeeds + - BUG/MINOR: stconn: fix sedesc memory leak on stream allocation failure + - BUG/MEDIUM: mux-h1: properly destroy a partially allocated h1s + - BUG/MEDIUM: applet: only set appctx->sedesc on successful allocation + - BUG/MINOR: quic: wake up MUX on probing only for 01RTT + - BUG/MINOR: trace: fix hardcoded level for TRACE_PRINTF + - BUG/MEDIUM: mux-quic: release data from conn flow-control on qcs reset + - BUG/MINOR: h3: properly handle incomplete remote uni stream type + - BUG/MINOR: mux-quic: prevent CC status to be erased by shutdown + - BUG/MEDIUM: stats: Consume the request except when parsing the POST payload + - DOC: config: set-var() dconv rendering issues + - BUG/MEDIUM: mux-h1: Wakeup H1C on shutw if there is no I/O subscription + - BUG/MINOR: applet/new: fix sedesc freeing logic + - BUG/MINOR: quic: Missing STREAM frame type updated + +2023/03/17 : 2.6.11 + - BUG/MEDIUM: proxy: properly stop backends on soft-stop + - BUG/MEDIUM: resolvers: Properly stop server resolutions on soft-stop + - DEBUG: cli/show_fd: Display connection error code + - DEBUG: ssl-sock/show_fd: Display SSL error code + - BUG/MINOR: tcp_sample: fix a bug in fc_dst_port and fc_dst_is_local sample fetches + - BUG/MINOR: quic: Missing STREAM frame length updates + - BUG/MEDIUM: connection: Preserve flags when a conn is removed from an idle list + - BUG/MINOR: mux-h2: make sure the h2c task exists before refreshing it + - MINOR: buffer: add br_single() to check if a buffer ring has more than one buf + - BUG/MEDIUM: mux-h2: only restart sending when mux buffer is decongested + - BUG/MINOR: mux-h2: set CO_SFL_STREAMER when sending lots of data + - BUG/MINOR: quic: Missing STREAM frame data pointer updates + - BUG/MEDIUM: listener: duplicate inherited FDs if needed + - MINOR: h2: add h2_phdr_to_ist() to make ISTs from pseudo headers + - MEDIUM: mux-h2/trace: add tracing support for headers + - BUG/MINOR: mux-h2: Fix possible null pointer deref on h2c in _h2_trace_header() + - BUG/MEDIUM: spoe: Don't set the default traget for the SPOE agent frontend + - BUG/MINOR: proto_ux: report correct error when bind_listener fails + - BUG/MINOR: protocol: fix minor memory leak in protocol_bind_all() + - BUG/MINOR: sock_unix: match finalname with tempname in sock_unix_addrcmp() + - MINOR: trace: add a TRACE_ENABLED() macro to determine if a trace is active + - MINOR: trace: add a trace_no_cb() dummy callback for when to use no callback + - MINOR: trace: add the long awaited TRACE_PRINTF() + - BUG/MAJOR: qpack: fix possible read out of bounds in static table + +2023/03/10 : 2.6.10 + - BUG/MINOR: mworker: stop doing strtok directly from the env + - BUG/MEDIUM: mworker: prevent inconsistent reload when upgrading from old versions + - BUG/MEDIUM: mworker: don't register mworker_accept_wrapper() when master FD is wrong + - MINOR: startup: HAPROXY_STARTUP_VERSION contains the version used to start + - BUG/MINOR: lua/httpclient: missing free in hlua_httpclient_send() + - BUG/MEDIUM: httpclient/lua: fix a race between lua GC and hlua_ctx_destroy + - MINOR: fd/cli: report the polling mask in "show fd" + - BUG/MEDIUM: stconn: Don't rearm the read expiration date if EOI was reached + - BUG/MINOR: sched: properly report long_rq when tasks remain in the queue + - BUG/MEDIUM: sched: allow a bit more TASK_HEAVY to be processed when needed + - BUG/MINOR: mworker: prevent incorrect values in uptime + - MINOR: mux-h2/traces: do not log h2s pointer for dummy streams + - MINOR: mux-h2/traces: add a missing TRACE_LEAVE() in h2s_frt_handle_headers() + - REGTESTS: Fix ssl_errors.vtc script to wait for connections close + - BUG/MINOR: cache: Cache response even if request has "no-cache" directive + - BUG/MINOR: cache: Check cache entry is complete in case of Vary + - BUG/MINOR: ring: do not realign ring contents on resize + - BUILD: thead: Fix several 32 bits compilation issues with uint64_t variables + - BUG/MEDIUM: h1-htx: Never copy more than the max data allowed during parsing + - DOC: config: Fix description of options about HTTP connection modes + - DOC: config: Add the missing tune.fail-alloc option from global listing + - DOC: config: Clarify the meaning of 'hold' in the 'resolvers' section + - BUG/MEDIUM: connection: Clear flags when a conn is removed from an idle list + - BUG/MINOR: http-check: Don't set HTX_SL_F_BODYLESS flag with a log-format body + - BUG/MINOR: http-check: Skip C-L header for empty body when it's not mandatory + - BUG/MINOR: http-ana: Don't increment conn_retries counter before the L7 retry + - BUG/MINOR: http-ana: Do a L7 retry on read error if there is no response + - BUG/MINOR: ssl: Use 'date' instead of 'now' in ocsp stapling callback + - MINOR: ssl: rename confusing ssl_bind_kws + - BUG/MINOR: config: crt-list keywords mistaken for bind ssl keywords + - BUG/MINOR: init: properly detect NUMA bindings on large systems + - BUG/MEDIUM: master: force the thread count earlier + - BUG/MINOR: init: make sure to always limit the total number of threads + - BUG/MINOR: thread: report thread and group counts in the correct order + - BUG/MINOR: ring: release the backing store name on exit + - MEDIUM: epoll: don't synchronously delete migrated FDs + - MEDIUM: poller: program the update in fd_update_events() for a migrated FD + - MAJOR: fd: remove pending updates upon real close + - MINOR: fd: delete unused updates on close() + - MEDIUM: fd: add the tgid to the fd and pass it to fd_insert() + - MINOR: cli/fd: show fd's tgid and refcount in "show fd" + - MINOR: fd: add functions to manipulate the FD's tgid + - MINOR: fd: add fd_get_running() to atomically return the running mask + - MAJOR: fd: grab the tgid before manipulating running + - MINOR: fd: make fd_clr_running() return the previous value instead + - MEDIUM: fd: make fd_insert/fd_delete atomically update fd.tgid + - BUG/MINOR: fd: Properly init the fd state in fd_insert() + - MEDIUM: fd: quit fd_update_events() when FD is closed + - MAJOR: poller: only touch/inspect the update_mask under tgid protection + - MEDIUM: fd: support broadcasting updates for foreign groups in updt_fd_polling + - BUG/MAJOR: fd/thread: fix race between updates and closing FD + - BUG/MAJOR: fd/threads: close a race on closing connections after takeover + - MINOR: h3/hq-interop: handle no data in decode_qcs() with FIN set + - BUG/MINOR: mux-quic: transfer FIN on empty STREAM frame + - BUG/MINOR: quic: Possible unexpected counter incrementation on send*() errors + - BUG/MINOR: quic: Really cancel the connection timer from qc_set_timer() + - BUG/MINOR: quic: Missing call to task_queue() in qc_idle_timer_do_rearm() + - BUG/MINOR: quic: Do not probe with too little Initial packets + - BUG/MINOR: quic: Wrong initialization for io_cb_wakeup boolean + - BUG/MINOR: quic: Do not drop too small datagrams with Initial packets + - BUG/MINOR: quic: Missing padding for short packets + - MINOR: quic: adjust request reject when MUX is already freed + - BUG/MINOR: quic: also send RESET_STREAM if MUX released + - BUG/MINOR: quic: acknowledge STREAM frame even if MUX is released + - BUG/MINOR: h3: prevent hypothetical demux failure on int overflow + - BUG/MEDIUM: quic: properly handle duplicated STREAM frames + - BUG/MINOR: quic: Do not send too small datagrams (with Initial packets) + - BUG/MINOR: quic: Ensure to be able to build datagrams to be retransmitted + - BUG/MINOR: quic: Remove force_ack for Initial,Handshake packets + - BUG/MINOR: quic: Ensure not to retransmit packets with no ack-eliciting frames + - BUG/MINOR: quic: Do not resend already acked frames + - MINOR: quic: Move code to wakeup the timer task to avoid anti-amplication deadlock + - BUG/MINOR: quic: Missing detections of amplification limit reached + - BUG/MEDIUM: quic: do not crash when handling STREAM on released MUX + - BUG/MINOR: mux-quic: properly init STREAM frame as not duplicated + - BUG/MINOR: mworker: use MASTER_MAXCONN as default maxconn value + - BUG/MINOR: quic: Missing listener accept queue tasklet wakeups + - DOC/CLEANUP: fix typos + +2023/02/14 : 2.6.9 + - BUG/MINOR: sink: make sure to always properly unmap a file-backed ring + - DEV: haring: add a new option "-r" to automatically repair broken files + - BUG/MINOR: log: release global log servers on exit + - BUG/MINOR: sink: free the forwarding task on exit + - DEV: hpack: fix `trash` build regression + - BUG/MINOR: fcgi-app: prevent 'use-fcgi-app' in default section + - MINOR: mux-quic/h3: define stream close callback + - BUG/MEDIUM: h3: handle STOP_SENDING on control stream + - BUG/MEDIUM: ssl: wrong eviction from the session cache tree + - BUG/MINOR: h3: fix crash due to h3 traces + - BUG/MINOR: stats: use proper buffer size for http dump + - BUG/MINOR: stats: fix source buffer size for http dump + - BUG/MEDIUM: stats: fix resolvers dump + - BUG/MINOR: stats: fix ctx->field update in stats_dump_proxy_to_buffer() + - BUG/MINOR: stats: fix show stats field ctx for servers + - BUG/MINOR: stats: fix STAT_STARTED behavior with full htx + - BUG/MINOR: quic: Possible stream truncations under heavy loss + - BUG/MINOR: quic: Too big PTO during handshakes + - BUG/MINOR: quic: Do not ignore coalesced packets in qc_prep_fast_retrans() + - MINOR: quic: When probing Handshake packet number space, also probe the Initial one + - BUG/MAJOR: quic: Possible crash when processing 1-RTT during 0-RTT session + - MEDIUM: quic: Remove qc_conn_finalize() from the ClientHello TLS callbacks + - BUG/MINOR: quic: Unchecked source connection ID + - BUG/MEDIUM: quic: do not split STREAM frames if no space + - BUG/MINOR: ssl/crt-list: warn when a line is malformated + - BUG/MEDIUM: stick-table: do not leave entries in end of window during purge + - BUG/MEDIUM: cache: use the correct time reference when comparing dates + - DOC: config: fix option spop-check proxy compatibility + - DOC: config: 'http-send-name-header' option may be used in default section + - MINOR: cfgparse/server: move (min/max)conn postparsing logic into dedicated function + - BUG/MINOR: server/add: ensure minconn/maxconn consistency when adding server + - BUG/MEDIUM: stconn: Schedule a shutw on shutr if data must be sent first + - BUG/MEDIUM: quic: fix crash when "option nolinger" is set in the frontend + - DOC: proxy-protocol: fix wrong byte in provided example + - BUG/CRITICAL: http: properly reject empty http header field names + +2023/01/24 : 2.6.8 + - BUG/MINOR: http-htx: Don't consider an URI as normalized after a set-uri action + - BUG/MEDIIM: stconn: Flush output data before forwarding close to write side + - CI: github: reintroduce openssl 1.1.1 + - CI: github: split ssl lib selection based on git branch + - BUILD: peers: peers-t.h depends on stick-table-t.h + - BUG/MEDIUM: ssl: Verify error codes can exceed 63 + - BUG/MINOR: ssl: Fix potential overflow + - MINOR: mworker: display an alert upon a wait-mode exit + - BUG/MEDIUM: mworker: fix segv in early failure of mworker mode with peers + - BUILD: makefile/da: also clean Os/ in Device Atlas dummy lib dir + - BUG/MEDIUM: httpclient/lua: double LIST_DELETE on end of lua task + - BUG/MINOR: promex: create haproxy_backend_agg_server_status + - MINOR: promex: introduce haproxy_backend_agg_check_status + - DOC: promex: Add missing backend metrics + - BUG/MAJOR: fcgi: Fix uninitialized reserved bytes + - REGTESTS: fix the race conditions in iff.vtc + - REGTESTS: startup: check maxconn computation + - BUG/MINOR: startup: don't use internal proxies to compute the maxconn + - CI: github: set ulimit -n to a greater value + - REGTESTS: startup: activate automatic_maxconn.vtc + - BUG/MEDIUM: resolvers: Use tick_first() to update the resolvers task timeout + - REGTESTS: startup: change the expected maxconn to 11000 + - REGTESTS: startup: add alternatives values in automatic_maxconn.vtc + - BUG/MEDIUM: h3: reject request with invalid header name + - BUG/MEDIUM: h3: reject request with invalid pseudo header + - MINOR: http: extract content-length parsing from H2 + - BUG/MEDIUM: h3: parse content-length and reject invalid messages + - CI: github: remove redundant ASAN loop + - CI: github: split matrix for development and stable branches + - BUG/MINOR: quic: properly handle alloc failure in qc_new_conn() + - BUG/MINOR: mux-quic: remove qcs from opening-list on free + - BUG/MINOR: mux-quic: handle properly alloc error in qcs_new() + - LICENSE: wurfl: clarify the dummy library license. + - BUG/MEDIUM: h3: fix cookie header parsing + - BUG/MINOR: h3: fix memleak on HEADERS parsing failure + - BUG/MINOR: ssl: Fix memory leak of find_chain in ssl_sock_load_cert_chain + - MINOR: stats: provide ctx for dumping functions + - MINOR: stats: introduce stats field ctx + - BUG/MINOR: stats: fix show stat json buffer limitation + - BUG/MINOR: quic: fix crash on PTO rearm if anti-amplification reset + - REGTESTS: startup: disable automatic_maxconn.vtc + - BUG/MEDIUM: tests: use tmpdir to create UNIX socket + - BUG/MEDIUM: stats: Rely on a local trash buffer to dump the stats + - OPTIM: pool: split the read_mostly from read_write parts in pool_head + - BUG/MEDIUM: mux-quic: fix double delete from qcc.opening_list + - BUG/MEDIUM: mux-h2: Refuse interim responses with end-stream flag set + - BUG/MINOR: pool/stats: Use ullong to report total pool usage in bytes in stats + - BUG/MINOR: mux-quic: ignore remote unidirectional stream close + - BUILD: makefile: build the features list dynamically + - BUILD: makefile: sort the features list + - BUG/MINOR: stick-table: report the correct action name in error message + - BUG/MINOR: http-fetch: Only fill txn status during prefetch if not already set + - BUG/MAJOR: buf: Fix copy of wrapping output data when a buffer is realigned + - DOC: config: fix alphabetical ordering of http-after-response rules + - DOC: config: remove duplicated "http-response sc-set-gpt0" directive + - BUG/MINOR: proxy: free orgto_hdr_name in free_proxy() + - REGTEST: fix the race conditions in json_query.vtc + - REGTEST: fix the race conditions in add_item.vtc + - REGTEST: fix the race conditions in digest.vtc + - REGTEST: fix the race conditions in hmac.vtc + - BUG/MINOR: http: Memory leak of http redirect rules' format string + - CLEANUP: htx: fix a typo in an error message of http_str_to_htx + - DOC: management: add details on "Used" status + - DOC: management: add details about @system-ca in "show ssl ca-file" + - BUG/MINOR: mux-quic: fix transfer of empty HTTP response + - MINOR: mux-quic: add traces for flow-control limit reach + - BUG/MINOR: h1-htx: Remove flags about protocol upgrade on non-101 responses + - BUG/MINOR: hlua: Fix Channel.line and Channel.data behavior regarding the doc + - BUG/MINOR: resolvers: Wait the resolution execution for a do_resolv action + - BUG/MEDIUM: peers: make "show peers" more careful about partial initialization + - BUG/MINOR: promex: Don't forget to consume the request on error + - BUG/MINOR: http-ana: Report SF_FINST_R flag on error waiting the request body + - BUG/MINOR: http-fetch: Don't block HTTP sample fetch eval in HTTP_MSG_ERROR state + - BUG/MINOR: http-ana: make set-status also update txn->status + - BUG/MINOR: listeners: fix suspend/resume of inherited FDs + - DOC: config: fix wrong section number for "protocol prefixes" + - DOC: config: fix aliases for protocol prefixes "udp4@" and "udp6@" + - DOC: config: mention the missing "quic4@" and "quic6@" in protocol prefixes + - BUG/MINOR: mux-fcgi: Correctly set pathinfo + - DOC: config: fix "Address formats" chapter syntax + - BUG/MEDIUM: jwt: Properly process ecdsa signatures (concatenated R and S params) + - BUG/MINOR: ssl: Fix compilation with OpenSSL 1.0.2 (missing ECDSA_SIG_set0) + - BUG/MINOR: listener: close tiny race between resume_listener() and stopping + - BUG/MINOR: h3: properly handle connection headers + - BUG/MINOR: mux-h2: make sure to produce a log on invalid requests + - BUG/MINOR: mux-h2: add missing traces on failed headers decoding + - BUILD: hpack: include global.h for the trash that is needed in debug mode + - BUG/MINOR: jwt: Wrong return value checked + - BUG/MINOR: quic: Do not request h3 clients to close its unidirection streams + - MINOR: h1: Consider empty port as invalid in authority for CONNECT + - MINOR: http: Considere empty ports as valid default ports + - BUG/MINOR: h1: Replace authority validation to conform RFC3986 + - REG-TESTS: http: Add more tests about authority/host matching + - BUG/MINOR: http-htx: Normalized absolute URIs with an empty port + +2022/12/02 : 2.6.7 + - REGTESTS: 4be_1srv_smtpchk_httpchk_layer47errors: Return valid SMTP replies + - BUG/MINOR: hlua: Remove \n in Lua error message built with memprintf + - BUG/MINOR: stream: Perform errors handling in right order in stream_new() + - BUG/MEDIUM: stconn: Reset SE descriptor when we fail to create a stream + - BUG/MEDIUM: resolvers: Remove aborted resolutions from query_ids tree + - BUG/MINOR: hlua: fixing hlua_http_msg_del_data behavior + - BUG/MINOR: hlua: fixing hlua_http_msg_insert_data behavior + - BUG/MINOR: hlua: _hlua_http_msg_delete incorrect behavior when offset is used + - DOC: management: httpclient can resolve server names in URLs + - BUG/MAJOR: conn-idle: fix hash indexing issues on idle conns + - BUG/MINOR: backend: only enforce turn-around state when not redispatching + - BUG/MINOR: checks: update pgsql regex on auth packet + - DOC: config: Fix pgsql-check documentation to make user param mandatory + - CLEANUP: mux-quic: remove usage of non-standard ull type + - CLEANUP: quic: remove global var definition in quic_tls header + - BUG/MINOR: quic: adjust quic_tls prototypes + - CLEANUP: quic: fix headers + - CLEANUP: quic: remove unused function prototype + - CLEANUP: quic: remove duplicated varint code from xprt_quic.h + - CLEANUP: quic: create a dedicated quic_conn module + - BUG/MINOR: mux-quic: ignore STOP_SENDING for locally closed stream + - BUG/MEDIUM: lua: Don't crash in hlua_lua2arg_check on failure + - BUG/MEDIUM: lua: handle stick table implicit arguments right. + - BUILD: h1: silence an initiialized warning with gcc-4.7 and -Os + - MINOR: fd: add a new function to only raise RLIMIT_NOFILE + - MINOR: init: do not try to shrink existing RLIMIT_NOFIlE + - BUG/MINOR: http-fetch: Update method after a prefetch in smp_fetch_meth() + - BUILD: http_fetch: silence an uninitiialized warning with gcc-4/5/6 at -Os + - BUG/MINOR: hlua: hlua_channel_insert_data() behavior conflicts with documentation + - MINOR: quic: limit usage of ssl_sock_ctx in favor of quic_conn + - MINOR: mux-quic: check quic-conn return code on Tx + - CLEANUP: quic: fix indentation + - BUG/MINOR: mux-h1: Account consumed output data on synchronous connection error + - MINOR: smtpchk: Update expect rule to fully match replies to EHLO commands + - BUG/MINOR: smtpchk: SMTP Service check should gracefully close SMTP transaction + - BUG/MINOR: config: don't count trailing spaces as empty arg (v2) + - BUG/MEDIUM: config: count line arguments without dereferencing the output + - MEDIUM: quic: retrieve frontend destination address + - CLEANUP: quic/receiver: remove the now unused tx_qring list + - BUG/MINOR: quic: set IP_PKTINFO socket option for QUIC receivers only + - DOC: configuration: missing 'if' in tcp-request content example + - BUG/MAJOR: stick-tables: do not try to index a server name for applets + - BUG/MINOR: server: make sure "show servers state" hides private bits + - MINOR: quic: New quic_cstream object implementation + - MINOR: quic: Extract CRYPTO frame parsing from qc_parse_pkt_frms() + - MINOR: quic: Use a non-contiguous buffer for RX CRYPTO data + - BUG/MINOR: quic: Stalled 0RTT connections with big ClientHello TLS message + - MINOR: quic: Split the secrets key allocation in two parts + - CLEANUP: quic: remove unused rxbufs member in receiver + - CLEANUP: quic: improve naming for rxbuf/datagrams handling + - MINOR: quic: implement datagram cleanup for quic_receiver_buf + - BUILD: ssl_sock: bind_conf uninitialized in ssl_sock_bind_verifycbk() + - BUG/MEDIUM: httpclient: Don't set EOM flag on an empty HTX message + - MINOR: httpclient/lua: Don't set req_payload callback if body is empty + - CI: Replace the deprecated `::set-output` command by writing to $GITHUB_OUTPUT in matrix.py + - CI: Replace the deprecated `::set-output` command by writing to $GITHUB_OUTPUT in workflow definition + - BUILD: quic: QUIC mux build fix for 32-bit build + - BUG/MEDIUM: httpclient: segfault when the httpclient parser fails + - BUILD: ssl_sock: fix null dereference for QUIC build + - BUILD: quic: Fix build for m68k cross-compilation + - BUG/MINOR: quic: fix buffer overflow on retry token generation + - MINOR: quic: add version field on quic_rx_packet + - MINOR: quic: extend pn_offset field from quic_rx_packet + - MINOR: quic: define first packet flag + - MINOR: quic: extract connection retrieval + - MINOR: quic: split and rename qc_lstnr_pkt_rcv() + - MINOR: quic: refactor packet drop on reception + - MINOR: quic: extend Retry token check function + - BUG/MINOR: log: Preserve message facility when the log target is a ring buffer + - BUG/MINOR: ring: Properly parse connect timeout + - BUG/MEDIUM: httpclient/lua: crash when the lua task timeout before the httpclient + - BUG/MEDIUM: httpclient: check if the httpclient was released in the IO handler + - REGTESTS: httpclient/lua: test the lua task timeout with the httpclient + - CI: github: dump the backtrace of coredumps in the alpine container + - BUILD: Makefile: add "USE_SHM_OPEN" on the linux-musl target + - BUG/MINOR: mux-quic: complete flow-control for uni streams + - BUG/MEDIUM: compression: handle rewrite errors when updating response headers + - MINOR: quic: do not crash on unhandled sendto error + - MINOR: quic: display unknown error sendto counter on stat page + - BUG/MINOR: sink: Only use backend capability for the sink proxies + - BUG/MINOR: sink: Set default connect/server timeout for implicit ring buffers + - CI: SSL: use proper version generating when "latest" semantic is used + - CI: SSL: temporarily stick to LibreSSL=3.5.3 + - DOC: management: add forgotten "show startup-logs" + - DOC: lua: add a note about compression w/ httpclient + - BUG/MAJOR: stick-table: don't process store-response rules for applets + - BUG/MEDIUM: stick-table: fix a race condition when updating the expiration task + - MINOR: quic: remove unnecessary quic_session_accept() + - BUG/MINOR: quic: fix subscribe operation + - BUG/MINOR: log: fixing bug in tcp syslog_io_handler Octet-Counting + - BUG/MINOR: quic: fix race condition on datagram purging + - CI: add monthly gcc cross compile jobs + - BUG/MINOR: httpclient: fixed memory allocation for the SSL ca_file + - BUG/MINOR: ssl: Memory leak of DH BIGNUM fields + - BUG/MINOR: ssl: Memory leak of AUTHORITY_KEYID struct when loading issuer + - BUG/MINOR: ssl: ocsp structure not freed properly in case of error + - CI: switch to the "latest" LibreSSL + - CI: enable QUIC for LibreSSL builds + - CI: emit the compiler's version in the build reports + - BUG/MEDIUM: wdt/clock: properly handle early task hangs + - BUG/MINOR: http-htx: Fix error handling during parsing http replies + - BUG/MINOR: resolvers: Don't wait periodic resolution on healthcheck failure + - BUG/MINOR: resolvers: Set port before IP address when processing SRV records + - BUG/MINOR: mux-fcgi: Be sure to send empty STDING record in case of zero-copy + - BUG/MEDIUM: mux-fcgi: Avoid value length overflow when it doesn't fit at once + - BUG/MINOR: mux-h1: Do not send a last null chunk on body-less answers + - REG-TESTS: cache: Remove T-E header for 304-Not-Modified responses + - DOC: config: fix alphabetical ordering of global section + - BUG/MEDIUM: ring: fix creation of server in uninitialized ring + - BUILD: quic: fix dubious 0-byte overflow on qc_release_lost_pkts + - BUG/MINOR: pool/cli: use ullong to report total pool usage in bytes + - BUG/MEDIUM: listener: Fix race condition when updating the global mngmt task + - BUG/MINOR: http_ana/txn: don't re-initialize txn and req var lists + - BUG/MEDIUM: raw-sock: Don't report connection error if something was received + - BUG/MINOR: ssl: don't initialize the keylog callback when not required + - BUG/MEDIUM: peers: messages about unkown tables not correctly ignored + - BUILD: peers: Remove unused variables + - MINOR: ncbuf: complete doc for ncb_advance() + - BUG/MEDIUM: quic: fix unsuccessful handshakes on ncb_advance error + - BUG/MEDIUM: quic: fix memleak for out-of-order crypto data + - MINOR: quic: complete traces/debug for handshake + - BUG/MAJOR: quic: Crash upon retransmission of dgrams with several packets + - BUG/MAJOR: quic: Crash after discarding packet number spaces + - DOC: configuration: fix quic prefix typo + - MINOR: quic: report error if force-retry without cluster-secret + - MINOR: global: generate random cluster.secret if not defined + - BUG/MINOR: server/idle: at least use atomic stores when updating max_used_conns + - BUILD: listener: fix build warning on global_listener_rwlock without threads + - DOC: quic: add note on performance issue with listener contention + - BUG/MINOR: cfgparse-listen: fix ebpt_next_dup pointer dereference on proxy "from" inheritance + - BUG/MINOR: log: fix parse_log_message rfc5424 size check + - BUG/MINOR: http-htx: Don't consider an URI as normalized after a set-uri action + - BUILD: http-htx: Silent build error about a possible NULL start-line + - DOC: configuration.txt: add default_value for table_idle signature + - BUILD: ssl-sock: Silent error about NULL deref in ssl_sock_bind_verifycbk() + - BUG/MINOR: mux-h1: Fix handling of 408-Request-Time-Out + - DOC: configuration.txt: fix typo in table_idle signature + - BUG/MEDIUM: quic: fix datagram dropping on queueing failed + - MINOR: ssl: enhance ca-file error emitting + - MINOR: ssl: forgotten newline in error messages on ca-file + - BUG/MINOR: ssl: shut the ca-file errors emitted during httpclient init + - Revert "BUG/MINOR: http-htx: Don't consider an URI as normalized after a set-uri action" + - DOC: config: provide some configuration hints for "http-reuse" + - DOC: config: refer to section about quoting in the "add_item" converter + - DOC: config: clarify the fact that SNI should not be used in HTTP scenarios + - DOC: config: mention that a single monitor-uri rule is supported + - DOC: config: explain how default matching method for ACL works + - DOC: config: clarify the fact that "retries" is not just for connections + - DOC: config: clarify the -m dir and -m dom pattern matching methods + - SCRIPTS: announce-release: add a link to the data plane API + - CLEANUP: ncbuf: remove ncb_blk args by value + - CLEANUP: ncbuf: inline small functions + - CLEANUP: ncbuf: use standard BUG_ON with DEBUG_STRICT + - BUG/MINOR: quic: Endless loop during retransmissions + - MINOR: mux-h2: add the expire task and its expiration date in "show fd" + - MINOR: mux-h1: add the expire task and its expiration date in "show fd" + +2022/09/22 : 2.6.6 + - MEDIUM: peers: limit the number of updates sent at once + - MINOR: Revert part of clarifying samples support per os commit + - BUILD: makefile: enable crypt(3) for NetBSD + - BUG/MINOR: quic: Retransmitted frames marked as acknowledged + - BUG/MINOR: quic: Possible crash with "tls-ticket-keys" on QUIC bind lines + - BUG/MINOR: h1: Support headers case adjustment for TCP proxies + - BUG/MINOR: quic: Possible crash when verifying certificates + - BUILD: quic: add some ifdef around the SSL_ERROR_* for libressl + - BUILD: ssl: fix ssl_sock_switchtx_cbk when no client_hello_cb + - BUILD: quic: temporarly ignore chacha20_poly1305 for libressl + - BUILD: quic: enable early data only with >= openssl 1.1.1 + - BUILD: ssl: fix the ifdef mess in ssl_sock_initial_ctx + - BUILD: quic: fix the #ifdef in ssl_quic_initial_ctx() + - MINOR: quic: add QUIC support when no client_hello_cb + - MINOR: quic: Add traces about sent or resent TX frames + - MINOR: quic: No TRACE_LEAVE() in retrieve_qc_conn_from_cid() + - BUG/MINOR: quic: Wrong connection ID to thread ID association + - BUG/MINOR: task: always reset a new tasklet's call date + - BUG/MINOR: task: make task_instant_wakeup() work on a task not a tasklet + - MINOR: task: permanently enable latency measurement on tasklets + - CLEANUP: task: rename ->call_date to ->wake_date + - BUG/MINOR: task: Fix detection of tasks profiling in tasklet_wakeup_after() + - BUG/MINOR: sched: properly account for the CPU time of dying tasks + - MINOR: sched: store the current profile entry in the thread context + - BUG/MINOR: stream/sched: take into account CPU profiling for the last call + - BUG/MINOR: signals/poller: set the poller timeout to 0 when there are signals + - BUG/MINOR: quic: Speed up the handshake completion only one time + - BUG/MINOR: quic: Trace fix about packet number space information. + - BUG/MINOR: h3: Crash when h3 trace verbosity is "minimal" + - MINOR: h3: Add the quic_conn object to h3 traces + - MINOR: h3: Missing connection argument for a TRACE_LEAVE() argument + - MINOR: h3: Send the h3 settings with others streams (requests) + - BUG/MINOR: signals/poller: ensure wakeup from signals + - CI: cirrus-ci: bump FreeBSD image to 13-1 + - DEV: flags: fix usage message to reflect available options + - DEV: flags: add missing CO_FL_FDLESS connection flag + - BUG/MEDIUM: proxy: ensure pause_proxy() and resume_proxy() own PROXY_LOCK + - MINOR: listener: small API change + - MINOR: proxy/listener: support for additional PAUSED state + - BUG/MINOR: stats: fixing stat shows disabled frontend status as 'OPEN' + - CLEANUP: pollers: remove dead code in the polling loop + - BUG/MINOR: mux-h1: Increment open_streams counter when H1 stream is created + - REGTESTS: healthcheckmail: Relax matching on the healthcheck log message + - CLEANUP: listener: function comment typo in stop_listener() + - BUG/MINOR: listener: null pointer dereference suspected by coverity + - REGTESTS: log: test the log-forward feature + - BUG/MEDIUM: sink: bad init sequence on tcp sink from a ring. + - REGTESTS: ssl/log: test the log-forward with SSL + - DOC: fix TOC in starter guide for subsection 3.3.8. Statistics + - MEDIUM: quic: separate path for rx and tx with set_encryption_secrets + - BUG/MEDIUM: mux-quic: fix crash on early app-ops release + - CLEANUP: mux-quic: remove stconn usage in h3/hq + - BUG/MINOR: mux-quic: do not remotely close stream too early + - BUG/MEDIUM: server: segv when adding server with hostname from CLI + - CLEANUP: quic,ssl: fix tiny typos in C comments + - BUG/MEDIUM: captures: free() an error capture out of the proxy lock + - BUILD: fd: fix a build warning on the DWCAS + - SCRIPTS: announce-release: update some URLs to https + - BUG/MEDIUM: mux-quic: fix nb_hreq decrement + - BUG/MINOR: mux-quic: do not keep detached qcs with empty Tx buffers + - REORG: mux-quic: extract traces in a dedicated source file + - REORG: mux-quic: export HTTP related function in a dedicated file + - MINOR: mux-quic: refactor snd_buf + - BUG/MEDIUM: mux-quic: properly trim HTX buffer on snd_buf reset + - REGTESTS: ssl: adopt tests to OpenSSL-3.0.N + - REGTESTS: ssl: adopt tests to OpenSSL-3.0.N + - REGTESTS: ssl: fix grep invocation to use extended regex in ssl_generate_certificate.vtc + - BUG/MINOR: log: improper behavior when escaping log data + +2022/09/03 : 2.6.5 + - BUG/MINOR: quic: Wrong list_for_each_entry() use when building packets from qc_do_build_pkt() + - BUG/MINOR: quic: Safer QUIC frame builders + - BUILD: tcp_sample: fix build of get_tcp_info() on OpenBSD + - BUG/MINOR: resolvers: return the correct value in resolvers_finalize_config() + - BUG/MINOR: mworker: does not create the "default" resolvers in wait mode + - BUG/MINOR: tcpcheck: Disable QUICKACK only if data should be sent after connect + - REGTESTS: Fix prometheus script to perform HTTP health-checks + - MINOR: resolvers: shut the warning when "default" resolvers is implicit + - BUG/MINOR: quic: Leak in qc_release_lost_pkts() for non in flight TX packets + - BUG/MINOR: quic: Stalled connections (missing I/O handler wakeup) + - CLEANUP: quic: No more use ->rx_list MT_LIST entry point (quic_rx_packet) + - CLEANUP: quic: Remove a useless check in qc_lstnr_pkt_rcv() + - DOC: configuration: do-resolve doesn't work with a port in the string + - MINOR: sample: add the host_only and port_only converters + - BUG/MINOR: httpclient: fix resolution with port + - DOC: configuration.txt: do-resolve must use host_only to remove its port. + - BUG/MINOR: quic: Frames added to packets even if not built. + - BUG/MEDIUM: spoe: Properly update streams waiting for a ACK in async mode + - BUG/MEDIUM: peers: Add connect and server timeut to peers proxy + - BUG/MEDIUM: peers: Don't use resync timer when local resync is in progress + - BUG/MEDIUM: peers: Don't start resync on reload if local peer is not up-to-date + - BUG/MINOR: hlua: Rely on CF_EOI to detect end of message in HTTP applets + - MINOR: quic: Replace MT_LISTs by LISTs for RX packets. + - BUG/MEDIUM: applet: fix incorrect check for abnormal return condition from handler + - BUG/MINOR: applet: make the call_rate only count the no-progress calls + - MINOR: quic: Add a trace to distinguish the datagram from the packets inside + - BUG/MINOR: tcpcheck: Disable QUICKACK for default tcp-check (with no rule) + - BUG/MINOR: ssl: fix deinit of the ca-file tree + - BUG/MINOR: ssl: leak of ckch_inst_link in ckch_inst_free() + - BUG/MEDIUM: ssl: Fix a UAF when old ckch instances are released + - MINOR: quic: Revert recent QUIC commits + - BUG/MINOR: ssl: revert two wrong fixes with ckhi_link + - BUG/MEDIUM: mux-h1: do not refrain from signaling errors after end of input + - BUG/MINOR: dev/udp: properly preset the rx address size + - MINOR: connection: support HTTP/3.0 for smp_*_http_major fetch + - CLEANUP: Re-apply xalloc_size.cocci (2) + - MINOR: mux-quic: simplify decode_qcs API + - MINOR: mux-quic/h3: adjust demuxing function return values + - BUG/MINOR: h3: fix return value on decode_qcs on error + - BUG/MINOR: h3: fix incorrect BUG_ON assert on SETTINGS parsing + - BUG/MEDIUM: h3: fix SETTINGS parsing + - MINOR: mux-quic: complete BUG_ON on TX flow-control enforcing + - CLEANUP: quic: use task_new_on() for single-threaded tasks + - MINOR: qpack: reduce dependencies on other modules + - MINOR: qpack: add ABORT_NOW on unimplemented decoding + - MINOR: qpack: improve decoding function + - MINOR: quic: Add several nonce and key definitions for Retry tag + - MINOR: quic: Parse long packet version from qc_parse_hd_form() + - CLEANUP: quid: QUIC draft-28 no more supported + - MEDIUM: quic: Add QUIC v2 draft support + - MINOR: quic: Released QUIC TLS extension for QUIC v2 draft + - MEDIUM: quic: Compatible version negotiation implementation (draft-08) + - CLEANUP: quic: Remove any reference to boringssl + - BUILD: quic: Wrong HKDF label constant variable initializations + - BUG/MINOR: qpack: abort on dynamic index field line decoding + - MINOR: quic: Dump version_information transport parameter + - CLEANUP: pool/quic: remove suffix "_pool" from certain pool names + - BUG/MINOR: qpack: fix build with QPACK_DEBUG + - BUG/MINOR: qpack: abort on dynamic index field line decoding + - CLEANUP: mux-quic: adjust comment on qcs_consume() + - CLEANUP: mux-quic: do not export qc_get_ncbuf + - REORG: mux-quic: reorganize flow-control fields + - MINOR: mux-quic: implement accessor for sedesc + - MEDIUM: mux-quic: refactor streams opening + - MINOR: mux-quic: rename qcs flag FIN_RECV to SIZE_KNOWN + - MINOR: mux-quic: emit FINAL_SIZE_ERROR on invalid STREAM size + - REORG: mux-quic: rename stream initialization function + - MINOR: mux-quic: rename stream purge function + - MINOR: mux-quic: add traces on frame parsing functions + - MINOR: mux-quic: implement qcs_alert() + - MINOR: mux-quic: filter send/receive-only streams on frame parsing + - MINOR: mux-quic: do not ack STREAM frames on unrecoverable error + - MINOR: mux-quic: support stream opening via MAX_STREAM_DATA + - MINOR: mux-quic: define basic stream states + - MINOR: mux-quic: use stream states to mark as detached + - MEDIUM: mux-quic: implement RESET_STREAM emission + - MEDIUM: mux-quic: implement STOP_SENDING handling + - CLEANUP: quic: clean up include on quic_frame-t.h + - MINOR: quic: define a generic QUIC error type + - MINOR: mux-quic: support app graceful shutdown + - MINOR: mux-quic/h3: prepare CONNECTION_CLOSE on release + - MEDIUM: quic: send CONNECTION_CLOSE on released MUX + - CLEANUP: mux-quic: move qc_release() + - MINOR: mux-quic: send one last time before release + - MINOR: h3: store control stream in h3c + - MINOR: h3: implement graceful shutdown with GOAWAY + - MINOR: mux-quic: save proxy instance into qcc + - MINOR: mux-quic: use timeout server for backend conns + - MEDIUM: mux-quic: adjust timeout refresh + - MINOR: mux-quic: count in-progress requests + - MEDIUM: mux-quic: implement http-keep-alive timeout + - MINOR: h3: support HTTP request framing state + - MINOR: mux-quic: refresh timeout on frame decoding + - MINOR: mux-quic: refactor refresh timeout function + - MEDIUM: mux-quic: implement http-request timeout + - MINOR: quic: Add two new stats counters for sendto() errors + - BUG/MINOR: quic: adjust errno handling on sendto + - MINOR: quic: Replace pool_zalloc() by pool_malloc() for fake datagrams + - MINOR: quic: replace custom buf on Tx by default struct buffer + - MINOR: quic: release Tx buffer on each send + - MINOR: quic: refactor datagram commit in Tx buffer + - MINOR: quic: skip sending if no frame to send in io-cb + - BUG/MINOR: mux-quic: open stream on STOP_SENDING + - BUG/MINOR: quic: fix crash on handshake io-cb for null next enc level + - MEDIUM: quic: xprt traces rework + - MINOR: quic: Remove useless lock for RX packets + - CLEANUP: quic: Remove trailing spaces + - MINOR: mux-quic: adjust enter/leave traces + - MINOR: mux-quic: define protocol error traces + - CLEANUP: mux-quic: adjust traces level + - MINOR: mux-quic: define new traces + - BUG/MEDIUM: mux-quic: fix crash due to invalid trace arg + - BUG/MEDIUM: quic: Possible use of uninitialized variable in qc_lstnr_params_init() + - BUG/MEDIUM: quic: Wrong use of in qc_lsntr_pkt_rcv() + - BUG/MINOR: mux-quic: fix crash with traces in qc_detach() + - BUG/MINOR: quic: MIssing check when building TX packets + - BUG/MINOR: quic: Wrong status returned by qc_pkt_decrypt() + - MINOR: quic: adjust quic_frame flag manipulation + - MINOR: h3: report error on control stream close + - MINOR: qpack: report error on enc/dec stream close + - BUG/MEDIUM: mux-quic: reject uni stream ID exceeding flow control + - MINOR: mux-quic: adjust traces on stream init + - MINOR: mux-quic: add missing args on some traces + - MINOR: quic: refactor application send + - BUG/MINOR: quic: do not notify MUX on frame retransmit + - BUG/MINOR: quic: Missing initializations for ducplicated frames. + - BUG/MEDIUM: quic: fix crash on MUX send notification + - REORG: h2: extract cookies concat function in http_htx + - REGTESTS: add test for HTTP/2 cookies concatenation + - MEDIUM: h3: concatenate multiple cookie headers + - BUG/MINOR: quic: Possible crashes when dereferencing ->pkt quic_frame struct member + - MINOR: quic: Add frame addresses to QUIC_EV_CONN_PRSAFRM event traces + - BUG/MINOR: quic: Wrong splitted duplicated frames handling + - MINOR: quic: Add the QUIC connection to mux traces + - MINOR: quic: Trace fix in qc_release_frm() + - MINOR: quic: Add reusable cipher contexts for header protection + - BUG/MINOR: mux-quic: Fix memleak on QUIC stream buffer for unacknowledged data + - BUG/MINOR: quix: Memleak for non in flight TX packets + - BUG/MINOR: quic: Wrong list_for_each_entry() use when building packets from qc_do_build_pkt() + - BUG/MINOR: quic: Safer QUIC frame builders + - MINOR: quic: Replace MT_LISTs by LISTs for RX packets. + - Revert "BUG/MINOR: quix: Memleak for non in flight TX packets" + - BUG/MINOR: quic: Leak in qc_release_lost_pkts() for non in flight TX packets + - BUG/MINOR: quic: Stalled connections (missing I/O handler wakeup) + - CLEANUP: quic: No more use ->rx_list MT_LIST entry point (quic_rx_packet) + - CLEANUP: quic: Remove a useless check in qc_lstnr_pkt_rcv() + - MINOR: quic: Remove useless traces about references to TX packets + - Revert "MINOR: quic: Remove useless traces about references to TX packets" + - BUG/MINOR: quic: Null packet dereferencing from qc_dup_pkt_frms() trace + - BUG/MINOR: quic: Frames added to packets even if not built. + - BUG/MINOR: quic: Missing header protection AES cipher context initialisations (draft-v2) + - MINOR: quic: Add a trace to distinguish the datagram from the packets inside + - MINOR: quic: Move traces about RX/TX bytes from QUIC_EV_CONN_PRSAFRM event + - BUG/MINOR: quic: TX frames memleak + - BUG/MINOR: ssl: leak of ckch_inst_link in ckch_inst_free() v2 + - BUILD: ring: forward-declare struct appctx to avoid a build warning + - MINOR: ring: support creating a ring from a linear area + - MINOR: ring: add support for a backing-file + - BUILD: sink: replace S_IRUSR, S_IWUSR with their octal value + - MINOR: ring: archive a previous file-backed ring on startup + - MINOR: sink/ring: rotate non-empty file-backed contents only + - DEV: haring: add a simple utility to read file-backed rings + - DEV: haring: support remapping LF in contents with CR VT + - CLEANUP: exclude haring with .gitignore + - BUILD: debug: make sure debug macros are never empty + - BUG/MINOR: regex: Properly handle PCRE2 lib compiled without JIT support + - REGTESTS: http_request_buffer: Add a barrier to not mix up log messages + - BUG/MEDIUM: mux-h1: always use RST to kill idle connections in pools + - MINOR: backend: always satisfy the first req reuse rule with l7 retries + - BUG/MINOR: quic: Do not ack when probing + - MINOR: quic: Add TX frames addresses to traces to several trace events + - MINOR: quic: Trace typo fix in qc_release_frm() + - BUG/MINOR: quic: Frames leak during retransmissions + - BUG/MINOR: h2: properly set the direction flag on HTX response + - BUG/MEDIUM: httpclient: always detach the caller before self-killing + - BUG/MINOR: httpclient: keep-alive was accidentely disabled + - BUG/MINOR: mux-h2: fix the "show fd" dest buffer for the subscriber + - BUG/MINOR: mux-h1: fix the "show fd" dest buffer for the subscriber + - BUG/MINOR: mux-fcgi: fix the "show fd" dest buffer for the subscriber + - DEBUG: stream: minor rearrangement of a few fields in struct stream. + - MINOR: debug: report applet pointer and handler in crashes when known + - BUG/MINOR: http-act: initialize http fmt head earlier + +2022/08/22 : 2.6.4 + - BUG/MINOR: ssl/cli: error when the ca-file is empty + - BUG/MAJOR: mworker: fix infinite loop on master with no proxies. + +2022/08/19 : 2.6.3 + - BUG/MINOR: sockpair: wrong return value for fd_send_uxst() + - Revert "BUG/MINOR: peers: set the proxy's name to the peers section name" + - DEBUG: fd: split the fd check + - MEDIUM: resolvers: continue startup if network is unavailable + - BUG/MINOR: mworker: PROC_O_LEAVING used but not updated + - BUG/MEDIUM: mux-quic: fix missing EOI flag to prevent streams leaks + - MINOR: quic: Congestion control architecture refactoring + - MEDIUM: quic: Cubic congestion control algorithm implementation + - MINOR: quic: New "quic-cc-algo" bind keyword + - BUG/MINOR: quic: loss time limit variable computed but not used + - MINOR: quic: Stop looking for packet loss asap + - BUG/MAJOR: quic: Useless resource intensive loop qc_ackrng_pkts() + - MINOR: quic: Send packets as much as possible from qc_send_app_pkts() + - BUG/MEDIUM: queue/threads: limit the number of entries dequeued at once + - MINOR: ebtree: add ebmb_lookup_shorter() to pursue lookups + - BUG/MEDIUM: pattern: only visit equivalent nodes when skipping versions + - BUG/MINOR: mux-quic: prevent crash if conn released during IO callback + - CLEANUP: mux-quic: remove useless app_ops is_active callback + - BUG/MINOR: mux-quic: do not free conn if attached streams + - MINOR: peers: Use a dedicated reconnect timeout when stopping the local peer + - BUG/MEDIUM: peers: limit reconnect attempts of the old process on reload + - BUG/MINOR: peers: Use right channel flag to consider the peer as connected + - BUG/MEDIUM: dns: Properly initialize new DNS session + - BUG/MINOR: backend: Don't increment conn_retries counter too early + - MINOR: server: Constify source server to copy its settings + - REORG: server: Export srv_settings_cpy() function + - BUG/MEDIUM: proxy: Perform a custom copy for default server settings + - MINOR: peers: Add a warning about incompatible SSL config for the local peer + - BUG/MINOR: quic: Missing in flight ack eliciting packet counter decrement + - BUG/MEDIUM: quic: Floating point exception in cubic_root() + - BUILD: http: silence an uninitialized warning affecting gcc-5 + - BUG/MINOR: quic: Avoid sending truncated datagrams + - BUG/MINOR: ring/cli: fix a race condition between the writer and the reader + - BUG/MEDIUM: sink: Set the sink ref for forwarders created during ring parsing + - BUG/MINOR: sink: fix a race condition between the writer and the reader + - BUG/MINOR: quic: do not reject datagrams matching minimum permitted size + - BUG/MINOR: quic: Missing Initial packet dropping case + - MINOR: quic: explicitely ignore sendto error + - BUG/MEDIUM: quic: break out of the loop in quic_lstnr_dghdlr + - CLEANUP: assorted typo fixes in the code and comments + - BUILD: cfgparse: always defined _GNU_SOURCE for sched.h and crypt.h + - BUG/MEDIUM: quic: Wrong packet length check in qc_do_rm_hp() + - MINOR: quic: Too much useless traces in qc_build_frms() + - BUG/MEDIUM: quic: Missing AEAD TAG check after removing header protection + - CLEANUP: mux-quic: remove loop on sending frames + - BUG/MEDIUM: quic: always remove the connection from the accept list on close + - BUG/MEDIUM: poller: use fd_delete() to release the poller pipes + - BUG/MEDIUM: task: relax one thread consistency check in task_unlink_wq() + - BUILD: stconn: fix build warning at -O3 about possible null sc + - BUILD: debug: silence warning on gcc-5 + - BUG/MINOR: quic: Possible infinite loop in quic_build_post_handshake_frames() + - BUG/MEDIUM: ring: fix too lax 'size' parser + - BUG/MINOR: quic: memleak on wrong datagram receipt + - MINOR: stick-table: Add table_expire() and table_idle() new converters + - BUG/MEDIUM: http-ana: fix crash or wrong header deletion by http-restrict-req-hdr-names + - MINOR: applet: add a function to reset the svcctx of an applet + - BUG/MEDIUM: cli: always reset the service context between commands + - BUG/MEDIUM: mux-h2: do not fiddle with ->dsi to indicate demux is idle + - BUG/MAJOR: log-forward: Fix log-forward proxies not fully initialized + - BUG/MAJOR: log-forward: Fix ssl layer not initialized on bind even if configured + +2022/07/22 : 2.6.2 + - MEDIUM: mux-h2: try to coalesce outgoing WINDOW_UPDATE frames + - BUG/MINOR: ssl: Do not look for key in extra files if already in pem + - BUG/MINOR: http-ana: Set method to HTTP_METH_OTHER when an HTTP txn is created + - BUG/MINOR: http-fetch: Use integer value when possible in "method" sample fetch + - MINOR: fd: add a new FD_DISOWN flag to prevent from closing a deleted FD + - BUG/MEDIUM: ssl/fd: unexpected fd close using async engine + - BUILD: Makefile: Add Lua 5.4 autodetect + - CI: re-enable gcc asan builds + - MINOR: fd: Add BUG_ON checks on fd_insert() + - BUG/MINOR: peers/config: always fill the bind_conf's argument + - BUG/MINOR: http-check: Preserve headers if not redefined by an implicit rule + - BUG/MINOR: http-act: Properly generate 103 responses when several rules are used + - BUG/MINOR: peers: fix possible NULL dereferences at config parsing + - BUG/MINOR: http-htx: Fix scheme based normalization for URIs wih userinfo + - MINOR: http: Add function to get port part of a host + - MINOR: http: Add function to detect default port + - BUG/MEDIUM: h1: Improve authority validation for CONNCET request + - MINOR: http-htx: Use new HTTP functions for the scheme based normalization + - BUG/MEDIUM: http-fetch: Don't fetch the method if there is no stream + - REGTEESTS: filters: Fix CONNECT request in random-forwarding script + - BUG/MINOR: mux-h1: Be sure to commit htx changes in the demux buffer + - BUG/MEDIUM: http-ana: Don't wait to have an empty buf to switch in TUNNEL state + - BUG/MEDIUM: mux-h1: Handle connection error after a synchronous send + - MEDIUM: mworker: set the iocb of the socketpair without using fd_insert() + - BUG/MINOR: quic: Missing acknowledgments for trailing packets + - BUG/MINOR: quic: Wrong reuse of fulfilled dgram RX buffer + - BUG/MAJOR: quic: Big RX dgrams leak when fulfilling a buffer + - BUG/MAJOR: quic: Big RX dgrams leak with POST requests + - BUILD: quic+h3: 32-bit compilation errors fixes + - BUG/MINOR: quic: Dropped packets not counted (with RX buffers full) + - MINOR: quic: Add new stats counter to diagnose RX buffer overrun + - MINOR: quic: Duplicated QUIC_RX_BUFSZ definition + - MINOR: task: Add tasklet_wakeup_after() + - MINOR: quic: Improvements for the datagrams receipt + - MINOR: quic: Increase the QUIC connections RX buffer size (upto 64Kb) + - MINOR: ncbuf: implement ncb_is_fragmented() + - BUG/MINOR: mux-quic: do not signal FIN if gap in buffer + - MINOR: h3: add h3c pointer into h3s instance + - MINOR: h3: handle errors on HEADERS parsing/QPACK decoding + - MINOR: qpack: properly handle invalid dynamic table references + - CLEANUP: h2: Typo fix in h2_unsubcribe() traces + - BUG/MEDIUM: mux-quic: fix server chunked encoding response + - BUG/MINOR: quic: fix closing state on NO_ERROR code sent + - BUG/MEDIUM: cli/threads: make "show threads" more robust on applets + - BUG/MINOR: debug: enter ha_panic() only once + - BUG/MEDIUM: tools: avoid calling dlsym() in static builds + - BUILD: makefile: Fix install(1) handling for OpenBSD/NetBSD/Solaris/AIX + - BUG/MEDIUM: tools: avoid calling dlsym() in static builds (try 2) + - MINOR: resolvers: resolvers_destroy() deinit and free a resolver + - BUG/MINOR: resolvers: shut off the warning for the default resolvers + - BUG/MINOR: ssl: allow duplicate certificates in ca-file directories + - BUG/MINOR: tools: fix statistical_prng_range()'s output range + - BUG/MINOR: quic: do not send CONNECTION_CLOSE_APP in initial/handshake + - BUG/MINOR: mworker/cli: relative pid prefix not validated anymore + - BUG/MAJOR: mux_quic: fix invalid PROTOCOL_VIOLATION on POST data overlap + - BUG/MEDIUM: mworker: proc_self incorrectly set crashes upon reload + - BUILD: add detection for unsupported compiler models + - BUG/MEDIUM: stconn: Only reset connect expiration when processing backend side + - BUILD: quic: fix anonymous union for gcc-4.4 + - BUG/MINOR: backend: Fallback on RR algo if balance on source is impossible + +2022/06/21 : 2.6.1 + - BUG/MINOR: ssl_ckch: Free error msg if commit changes on a cert entry fails + - BUG/MINOR: ssl_ckch: Free error msg if commit changes on a CA/CRL entry fails + - BUG/MEDIUM: ssl_ckch: Don't delete a cert entry if it is being modified + - BUG/MEDIUM: ssl_ckch: Don't delete CA/CRL entry if it is being modified + - BUG/MINOR: ssl_ckch: Don't duplicate path when replacing a cert entry + - BUG/MINOR: ssl_ckch: Don't duplicate path when replacing a CA/CRL entry + - BUG/MEDIUM: ssl_ckch: Rework 'commit ssl cert' to handle full buffer cases + - BUG/MEDIUM: ssl_ckch: Rework 'commit ssl ca-file' to handle full buffer cases + - BUG/MEDIUM: ssl/crt-list: Rework 'add ssl crt-list' to handle full buffer cases + - BUG/MEDIUM: httpclient: Don't remove HTX header blocks before duplicating them + - BUG/MEDIUM: httpclient: Rework CLI I/O handler to handle full buffer cases + - MEDIUM: http-ana: Always report rewrite failures as PRXCOND in logs + - MEDIUM: httpclient: Don't close CLI applet at the end of a response + - REGTESTS: abortonclose: Add a barrier to not mix up log messages + - REGTESTS: http_request_buffer: Increase client timeout to wait "slow" clients + - BUG/MINOR: ssl_ckch: Use right type for old entry in show_crlfile_ctx + - BUG/MINOR: ssl_ckch: Dump CRL transaction only once if show command yield + - BUG/MINOR: ssl_ckch: Dump CA transaction only once if show command yield + - BUG/MINOR: ssl_ckch: Dump cert transaction only once if show command yield + - BUG/MINOR: ssl_ckch: Init right field when parsing "commit ssl crl-file" cmd + - BUG/MINOR: ssl_ckch: Fix possible uninitialized value in show_cert I/O handler + - BUG/MINOR: ssl_ckch: Fix possible uninitialized value in show_cafile I/O handler + - BUG/MINOR: ssl_ckch: Fix possible uninitialized value in show_crlfile I/O handler + - REGTESTS: http_abortonclose: Extend supported versions + - REGTESTS: restrict_req_hdr_names: Extend supported versions + - BUILD: compiler: implement unreachable for older compilers too + - BUG/MEDIUM: mailers: Set the object type for check attached to an email alert + - BUG/MINOR: trace: Test server existence for health-checks to get proxy + - BUG/MINOR: checks: Properly handle email alerts in trace messages + - REGTESTS: healthcheckmail: Update the test to be functionnal again + - REGTESTS: healthcheckmail: Relax health-check failure condition + - BUG/MINOR: h3: fix frame type definition + - BUG/MINOR: cli/stats: add missing trailing LF after JSON outputs + - BUG/MINOR: server: do not enable DNS resolution on disabled proxies + - BUG/MINOR: cli/stats: add missing trailing LF after "show info json" + - BUG/MEDIUM: mux-quic: fix flow control connection Tx level + - BUG/MINOR: mux-quic: fix memleak on frames rejected by transport + - BUG/MINOR: tcp-rules: Make action call final on read error and delay expiration + - BUG/MEDIUM: stconn: Don't wakeup applet for send if it won't consume data + - BUG/MEDIUM: cli: Notify cli applet won't consume data during request processing + - BUG/MEDIUM: mux-quic: fix segfault on flow-control frame cleanup + - BUG/MINOR: qpack: support header litteral name decoding + - MINOR: qpack: add comments and remove a useless trace + - BUG/MINOR: h3/qpack: deal with too many headers + - BUG/BUILD: h3: fix wrong label name + - BUG/MINOR: quic: Stop hardcoding Retry packet Version field + - BUG/MINOR: quic: Wrong PTO calculation + - BUG/MINOR: task: fix thread assignment in tasklet_kill() + - BUG/MEDIUM: stream: Properly handle destructive client connection upgrades + - MINOR: stream: Rely on stconn flags to abort stream destructive upgrade + - BUG/MINOR: log: Properly test connection retries to fix dontlog-normal option + - BUG/MINOR: quic: Unexpected half open connection counter wrapping + - BUG/MINOR: quic_stats: Duplicate "quic_streams_data_blocked_bidi" field name + - BUG/MINOR: quic: purge conn Rx packet list on release + - BUG/MINOR: quic: free rejected Rx packets + - BUG/MEDIUM: ssl/cli: crash when crt inserted into a crt-list + - BUG/MINOR: quic: Acknowledgement must be forced during handshake + - BUG/MEDIUM: mworker: use default maxconn in wait mode + - REGTESTS: ssl: add the same cert for client/server + +2022/05/31 : 2.6.0 + - DOC: Fix formatting in configuration.txt to fix dconv + - CLEANUP: tcpcheck: Remove useless test on the stream-connector in tcpcheck_main + - CLEANUP: muxes: Consider stream's sd as defined in .show_fd callback functions + - MINOR: quic: Ignore out of packet padding. + - CLEANUP: quic: Useless QUIC_CONN_TX_BUF_SZ definition + - CLEANUP: quic: No more used handshake output buffer + - MINOR: quic: QUIC transport parameters split. + - MINOR: quic: Transport parameters dump + - DOC: quic: Update documentation for QUIC Retry + - MINOR: quic: Tunable "max_idle_timeout" transport parameter + - MINOR: quic: Tunable "initial_max_streams_bidi" transport parameter + - MINOR: quic: Clarifications about transport parameters value + - MINOIR: quic_stats: add QUIC connection errors counters + - BUG/MINOR: quic: Largest RX packet numbers mixing + - MINOR: quic_stats: Add transport new counters (lost, stateless reset, drop) + - DOC: quic: Documentation update for QUIC + - MINOR: quic: Connection TX buffer setting renaming. + - MINOR: h3: Add a statistics module for h3 + - MINOR: quic: Send STOP_SENDING frames if mux is released + - MINOR: quic: Do not drop packets with RESET_STREAM frames + - BUG/MINOR: qpack: fix buffer API usage on prefix integer encoding + - BUG/MINOR: qpack: support bigger prefix-integer encoding + - BUG/MINOR: h3: do not report bug on unknown method + - SCRIPTS: add make-releases-json to recreate a releases.json file in download dirs + - SCRIPTS: make publish-release try to launch make-releases-json + - MINOR: htx: add an unchecked version of htx_get_head_blk() + - BUILD: htx: use the unchecked version of htx_get_head_blk() where needed + - BUILD: quic: use inttypes.h instead of stdint.h + - DOC: internal: remove totally outdated diagrams + - DOC: remove the outdated ROADMAP file + - DOC: add maintainers for QUIC and HTTP/3 + - MINOR: h3: define h3 trace module + - MINOR: h3: add traces on frame recv + - MINOR: h3: add traces on frame send + - MINOR: h3: add traces on h3s init/end + - EXAMPLES: remove completely outdated acl-content-sw.cfg + - BUILD: makefile: reorder objects by build time + - DOC: fix a few spelling mistakes in the docs + - BUG/MEDIUM: peers/cli: fix "show peers" crash + - CLEANUP: peers/cli: stop misusing the appctx local variable + - CLEANUP: peers/cli: make peers_dump_peer() take an appctx instead of an stconn + - BUG/MINOR: peers: set the proxy's name to the peers section name + - MINOR: server: indicate when no address was expected for a server + - BUG/MINOR: peers: detect and warn on init_addr/resolvers/check/agent-check + - DOC: peers: indicate that some server settings are not usable + - DOC: peers: clarify when entry expiration date is renewed. + - DOC: peers: fix port number and addresses on new peers section format + - DOC: gpc/gpt: add commments of gpc/gpt array definitions on stick tables. + - DOC: install: update supported OpenSSL versions in the INSTALL doc + - MINOR: ncbuf: adjust ncb_data with NCBUF_NULL + - BUG/MINOR: h3: fix frame demuxing + - BUG/MEDIUM: h3: fix H3_EXCESSIVE_LOAD when receiving H3 frame header only + - BUG/MINOR: quic: Fix QUIC_EV_CONN_PRSAFRM event traces + - CLEANUP: quic: remove useless check on local UNI stream reception + - BUG/MINOR: qpack: do not consider empty enc/dec stream as error + - DOC: intro: adjust the numbering of paragrams to keep the output ordered + - MINOR: version: mention that it's LTS now. + +2022/05/27 : 2.6-dev12 + - CLEANUP: tools: Clean up non-QUIC error message handling in str2sa_range() + - BUG/MEDIUM: tools: Fix `inet_ntop` usage in sa2str + - CLEANUP: tools: Crash if inet_ntop fails due to ENOSPC in sa2str + - BUG/MEDIUM: mux-quic: adjust buggy proxy closing support + - Revert "MINOR: quic: activate QUIC traces at compilation" + - Revert "MINOR: mux-quic: activate qmux traces on stdout via macro" + - CLEANUP: init: address a coverity warning about possible multiply overflow + - BUG/MEDIUM: http: Properly reject non-HTTP/1.x protocols + - MEDIUM: h1: enlarge the scope of accepted version chars with accept-invalid-http-request + - BUG/MEDIUM: resolvers: Don't defer resolutions release in deinit function + - BUG/MEDIUM: peers: fix segfault using multiple bind on peers sections + - BUG/MEDIUM: peers: prevent unitialized multiple listeners on peers section + - BUG/MINOR: task: Don't defer tasks release when HAProxy is stopping + - MINOR: h3: mark ncbuf as const on h3_b_dup + - MINOR: mux-quic: do not alloc quic_stream_desc for uni remote stream + - MINOR: mux-quic: delay cs_endpoint allocation + - MINOR: mux-quic: add traces in qc_recv() + - MINOR: mux-quic: adjust return value of decode_qcs + - CLEANUP: h3: rename struct h3 -> h3c + - CLEANUP: h3: rename uni stream type constants + - BUG/MINOR: h3: prevent overflow when parsing SETTINGS + - MINOR: h3: refactor h3_control_send() + - MINOR: quic: support CONNECTION_CLOSE_APP emission + - MINOR: mux-quic: disable read on CONNECTION_CLOSE emission + - MINOR: h3: reject too big frames + - MINOR: mux-quic: emit STREAM_STATE_ERROR in qcc_recv + - BUG/MINOR: mux-quic: refactor uni streams TX/send H3 SETTINGS + - MINOR: h3/qpack: use qcs as type in decode callbacks + - MINOR: h3: define stream type + - MINOR: h3: refactor uni streams initialization + - MINOR: h3: check if frame is valid for stream type + - MINOR: h3: define non-h3 generic parsing function + - MEDIUM: quic: refactor uni streams RX + - CLEANUP: h3: remove h3 uni tasklet + - MINOR: h3: abort read on unknown uni stream + - MINOR: h3: refactor SETTINGS parsing/error reporting + - Revert "BUG/MINOR: task: Don't defer tasks release when HAProxy is stopping" + - DOC: configuration: add a warning for @system-ca on bind + - CLEANUP: init: address another coverity warning about a possible multiply overflow + - BUG/MINOR: ssl/lua: use correctly cert_ext in CertCache.set() + - BUG/MEDIUM: sample: Fix adjusting size in word converter + - REGTESTS: Do not use REQUIRE_VERSION for HAProxy 2.5+ (2) + - CLEANUP: conn_stream: remove unneeded exclusion of RX_WAIT_EP from RXBLK_ANY + - CLEANUP: conn_stream: rename the cs_endpoint's context to "conn" + - MINOR: conn_stream: add new sets of functions to set/get endpoint flags + - DEV: coccinelle: add cs_endp_flags.cocci + - CLEANUP: conn_stream: apply cs_endp_flags.cocci tree-wide + - DEV: coccinelle: add endp_flags.cocci + - CLEANUP: conn_stream: apply endp_flags.cocci tree-wide + - CLEANUP: conn_stream: rename the stream endpoint flags CS_EP_* to SE_FL_* + - CLEANUP: conn_stream: rename the cs_endpoint's target to "se" + - CLEANUP: conn_stream: rename cs_endpoint to sedesc (stream endpoint descriptor) + - CLEANUP: applet: rename the sedesc pointer from "endp" to "sedesc" + - CLEANUP: conn_stream: rename the conn_stream's endp to sedesc + - CLEANUP: conn_stream: rename cs_app_* to sc_app_* + - CLEANUP: conn_stream: tree-wide rename to stconn (stream connector) + - CLEANUP: mux-h1: add and use h1s_sc() to retrieve the stream connector + - CLEANUP: mux-h2: add and use h2s_sc() to retrieve the stream connector + - CLEANUP: mux-fcgi: add and use fcgi_strm_sc() to retrieve the stream connector + - CLEANUP: mux-pt: add and use pt_sc() to retrieve the stream connector + - CLEANUP: stdesc: rename the stream connector ->cs field to ->sc + - CLEANUP: stream: rename "csf" and "csb" to "scf" and "scb" + - CLEANUP: stconn: tree-wide rename stream connector flags CS_FL_* to SC_FL_* + - CLEANUP: stconn: tree-wide rename stconn states CS_ST/SB_* to SC_ST/SB_* + - MINOR: check: export wake_srv_chk() + - MINOR: conn_stream: test the various ops functions before calling them + - MEDIUM: stconn: merge the app_ops and the data_cb fields + - MINOR: applet: add new wrappers to put chk/blk/str/chr to channel from appctx + - CLEANUP: applet: use applet_put*() everywhere possible + - CLEANUP: stconn: rename cs_{i,o}{b,c} to sc_{i,o}{b,c} + - CLEANUP: stconn: rename cs_{check,strm,strm_task} to sc_strm_* + - CLEANUP: stconn: rename cs_conn() to sc_conn() + - CLEANUP: stconn: rename cs_mux() to sc_mux_strm() + - CLEANUP: stconn: rename cs_conn_mux() to sc_mux_ops() + - CLEANUP: stconn: rename cs_appctx() to sc_appctx() + - CLEANUP: stconn: rename __cs_endp_target() to __sc_endp() + - CLEANUP: stconn: rename cs_get_data_name() to sc_get_data_name() + - CLEANUP: stconn: rename cs_conn_*() to sc_conn_*() + - CLEANUP: stconn: rename cs_conn_get_first() to conn_get_first_sc() + - CLEANUP: stconn: rename cs_ep_set_error() to se_fl_set_error() + - CLEANUP: stconn: make a few functions take a const argument + - CLEANUP: stconn: use a single function to know if SC may send to SE + - MINOR: stconn: consider CF_SHUTW for sc_is_send_allowed() + - MINOR: stconn: remove calls to cs_done_get() + - MEDIUM: stconn: always rely on CF_SHUTR in addition to cs_rx_blocked() + - MEDIUM: stconn: remove SE_FL_RXBLK_SHUT + - MINOR: stconn: rename SE_FL_RXBLK_CONN to SE_FL_APPLET_NEED_CONN + - MEDIUM: stconn: take SE_FL_APPLET_NEED_CONN out of the RXBLK_ANY flags + - CLEANUP: stconn: rename cs_rx_room_{blk,rdy} to sc_{need,have}_room() + - CLEANUP: stconn: rename cs_rx_chan_{blk,rdy} to sc_{wont,will}_read() + - CLEANUP: stconn: rename cs_rx_buff_{blk,rdy} to sc_{need,have}_buff() + - MINOR: stconn: start to rename cs_rx_endp_{more,done}() to se_have_{no_,}more_data() + - MINOR: stconn: add sc_is_recv_allowed() to check for ability to receive + - CLEANUP: stconn: rename SE_FL_RX_WAIT_EP to SE_FL_HAVE_NO_DATA + - MEDIUM: stconn: move the RXBLK flags to the stream connector + - CLEANUP: stconn: rename SE_FL_WANT_GET to SE_FL_WILL_CONSUME + - CLEANUP: stconn: remove cs_tx_blocked() and cs_tx_endp_ready() + - CLEANUP: stconn: rename cs_{want,stop}_get() to se_{will,wont}_consume() + - CLEANUP: stconn: rename cs_cant_get() to se_need_more_data() + - CLEANUP: stconn: rename cs_{new,create,free,destroy}_* to sc_* + - CLEANUP: stconn: rename remaining management functions from cs_* to sc_* + - CLEANUP: stconn: rename cs{,_get}_{src,dst} to sc_* + - CLEANUP: stconn: rename cs_{shut,chk}* to sc_* + - CLEANUP: stconn: rename final state manipulation functions from cs_* to sc_* + - CLEANUP: quic: drop the name "conn_stream" from the pool variable names + - REORG: rename cs_utils.h to sc_strm.h + - REORG: stconn: rename conn_stream.{c,h} to stconn.{c,h} + - CLEANUP: muxes: rename "get_first_cs" to "get_first_sc" + - DEV: flags: use "sc" for stream conns instead of "cs" + - CLEANUP: check: rename all occurrences of stconn "cs" to "sc" + - CLEANUP: connection: rename all occurrences of stconn "cs" to "sc" + - CLEANUP: stconn: rename all occurrences of stconn "cs" to "sc" + - CLEANUP: quic/h3: rename all occurrences of stconn "cs" to "sc" + - CLEANUP: stream: rename all occurrences of stconn "cs" to "sc" + - CLEANUP: promex: rename all occurrences of stconn "cs" to "sc" + - CLEANUP: stats: rename all occurrences of stconn "cs" to "sc" + - CLEANUP: cli: rename all occurrences of stconn "cs" to "sc" + - CLEANUP: applet: rename all occurrences of stconn "cs" to "sc" + - CLEANUP: cache: rename all occurrences of stconn "cs" to "sc" + - CLEANUP: dns: rename all occurrences of stconn "cs" to "sc" + - CLEANUP: spoe: rename all occurrences of stconn "cs" to "sc" + - CLEANUP: hlua: rename all occurrences of stconn "cs" to "sc" + - CLEANUP: log-forward: rename all occurrences of stconn "cs" to "sc" + - CLEANUP: http-client: rename all occurrences of stconn "cs" to "sc" + - CLEANUP: mux-fcgi: rename all occurrences of stconn "cs" to "sc" + - CLEANUP: mux-h1: rename all occurrences of stconn "cs" to "sc" + - CLEANUP: mux-h2: rename all occurrences of stconn "cs" to "sc" + - CLEANUP: mux-pt: rename all occurrences of stconn "cs" to "sc" + - CLEANUP: peers: rename all occurrences of stconn "cs" to "sc" + - CLEANUP: sink: rename all occurrences of stconn "cs" to "sc" + - CLEANUP: sslsock: remove only occurrence of local variable "cs" + - CLEANUP: applet: rename appctx_cs() to appctx_sc() + - CLEANUP: stream: rename stream_upgrade_from_cs() to stream_upgrade_from_sc() + - CLEANUP: obj_type: rename OBJ_TYPE_CS to OBJ_TYPE_SC + - CLEANUP: stconn: replace a few remaining occurrences of CS in comments or traces + - DOC: internal: update the muxes doc to mention the stconn + - CLEANUP: mux-quic: rename the "endp" field to "sd" + - CLEANUP: mux-h1: rename the "endp" field to "sd" + - CLEANUP: mux-h2: rename the "endp" field to "sd" + - CLEANUP: mux-fcgi: rename the "endp" field to "sd" + - CLEANUP: mux-pt: rename the "endp" field to "sd" + - CLEANUP: stconn: rename a few "endp" arguments and variables to "sd" + - MINOR: stconn: turn SE_FL_WILL_CONSUME to SE_FL_WONT_CONSUME + - CLEANUP: stream: remove unneeded test on appctx during initialization + - CLEANUP: stconn: remove the new unneeded SE_FL_APP_MASK + - DEV: flags: fix "siet" shortcut name + - DEV: flags: rename the "endp" shortcut to "sd" for "stream descriptor" + - DEV: flags: reorder a few SC/SE flags + - DOC: internal: add a description of the stream connectors and descriptors + +2022/05/20 : 2.6-dev11 + - CI: determine actual LibreSSL version dynamically + - BUG/MEDIUM: ncbuf: fix null buffer usage + - MINOR: ncbuf: fix warnings for testing build + - MEDIUM: http-ana: Add a proxy option to restrict chars in request header names + - MEDIUM: ssl: Delay random generator initialization after config parsing + - MINOR: ssl: Add 'ssl-propquery' global option + - MINOR: ssl: Add 'ssl-provider' global option + - CLEANUP: Add missing header to ssl_utils.c + - CLEANUP: Add missing header to hlua_fcn.c + - CLEANUP: Remove unused function hlua_get_top_error_string + - BUILD: fix build warning on solaris based systems with __maybe_unused. + - MINOR: tools: add get_exec_path implementation for solaris based systems. + - BUG/MINOR: ssl: Fix crash when no private key is found in pem + - CLEANUP: conn-stream: Remove cs_applet_shut declaration from header file + - MINOR: applet: Prepare appctx to own the session on frontend side + - MINOR: applet: Let the frontend appctx release the session + - MINOR: applet: Change return value for .init callback function + - MINOR: stream: Export stream_free() + - MINOR: applet: Add appctx_init() helper fnuction + - MINOR: applet: Add a function to finalize frontend appctx startup + - MINOR: applet: Add function to release appctx on error during init stage + - MEDIUM: dns: Refactor dns appctx creation + - MEDIUM: spoe: Refactor SPOE appctx creation + - MEDIUM: lua: Refactor cosocket appctx creation + - MEDIUM: httpclient: Refactor http-client appctx creation + - MINOR: sink: Add a ref to sink in the sink_forward_target structure + - MEDIUM: sink: Refactor sink forwarder appctx creation + - MINOR: peers: Add a ref to peers section in the peer structure + - MEDIUM: peers: Refactor peer appctx creation + - MINOR: applet: Add API to start applet on a thread subset + - MEDIUM: applet: Add support for async appctx startup on a thread subset + - MINOR: peers: Track number of applets run by thread + - MEDIUM: peers: Balance applets across threads + - MINOR: conn-stream/applet: Stop setting appctx as the endpoint context + - CLEANUP: proxy: Remove dead code when parsing "http-restrict-req-hdr-names" option + - REGTESTS: abortonclose: Fix some race conditions + - MINOR: ssl: Add 'ssl-provider-path' global option + - CLEANUP: http_ana: Make use of the return value of stream_generate_unique_id() + - BUG/MINOR: spoe: Fix error handling in spoe_init_appctx() + - CLEANUP: peers: Remove unreachable code in peer_session_create() + - CLEANUP: httpclient: Remove useless test on ss_dst in httpclient_applet_init() + - BUG/MEDIUM: quic: fix Rx buffering + - OPTIM: quic: realign empty Rx buffer + - BUG/MINOR: ncbuf: fix ncb_is_empty() + - MINOR: ncbuf: refactor ncb_advance() + - BUG/MINOR: mux-quic: update session's idle delay before stream creation + - MINOR: h3: do not wait a complete frame for demuxing + - MINOR: h3: flag demux as full on HTX full + - MEDIUM: mux-quic: implement recv on io-cb + - MINOR: mux-quic: remove qcc_decode_qcs() call in XPRT + - MINOR: mux-quic: reorganize flow-control frames emission + - MINOR: mux-quic: implement MAX_STREAM_DATA emission + - MINOR: mux-quic: implement MAX_DATA emission + - BUG/MINOR: mux-quic: support nul buffer with qc_free_ncbuf() + - MINOR: mux-quic: free RX buf if empty + - BUG/MEDIUM: config: Reset outline buffer size on realloc error in readcfgfile() + - BUG/MINOR: check: Reinit the buffer wait list at the end of a check + - MEDIUM: check: No longer shutdown the connection in .wake callback function + - REORG: check: Rename and export I/O callback function + - MEDIUM: check: Use the CS to handle subscriptions for read/write events + - BUG/MINOR: quic: break for error on sendto + - MINOR: quic: abort on unlisted errno on sendto() + - MINOR: quic: detect EBADF on sendto() + - BUG/MEDIUM: quic: fix initialization for local/remote TPs + - CLEANUP: quic: adjust comment/coding style for TPs init + - BUG/MINOR: cfgparse: abort earlier in case of allocation error + - MINOR: quic: Dump initial derived secrets + - MINOR: quic_tls: Add quic_tls_derive_retry_token_secret() + - MINOR: quic_tls: Add quic_tls_decrypt2() implementation + - MINOR: quic: Retry implementation + - MINOR: cfgparse: Update for "cluster-secret" keyword for QUIC Retry + - MINOR: quic: Move quic_lstnr_dgram_dispatch() out of xprt_quic.c + - BUILD: stats: Missing headers inclusions from stats.h + - MINOR: quic_stats: Add a new stats module for QUIC + - MINOR: quic: Attach proxy QUIC stats counters to the QUIC connection + - BUG/MINOR: quic: Fix potential memory leak during QUIC connection allocations + - MINOR: quic: QUIC stats counters handling + - MINOR: quic: Add tune.quic.retry-threshold keyword + - MINOR: quic: Dynamic Retry implementation + - MINOR: quic/mux-quic: define CONNECTION_CLOSE send API + - MINOR: mux-quic: emit FLOW_CONTROL_ERROR + - MINOR: mux-quic: emit STREAM_LIMIT_ERROR + - MINOR: mux-quic: close connection on error if different data at offset + - BUG/MINOR: peers: fix error reporting of "bind" lines + - CLEANUP: config: improve address parser error report for unmatched protocols + - CLEANUP: config: provide cleare hints about unsupported QUIC addresses + - MINOR: protocol: replace ctrl_type with xprt_type and clarify it + - MINOR: listener: provide a function to process all of a bind_conf's arguments + - MINOR: config: use the new bind_parse_args_list() to parse a "bind" line + - CLEANUP: listener: add a comment about what the BC_SSL_O_* flags are for + - MINOR: listener: add a new "options" entry in bind_conf + - CLEANUP: listener: replace all uses of bind_conf->is_ssl with BC_O_USE_SSL + - CLEANUP: listener: replace bind_conf->generate_cers with BC_O_GENERATE_CERTS + - CLEANUP: listener: replace bind_conf->quic_force_retry with BC_O_QUIC_FORCE_RETRY + - CLEANUP: listener: store stream vs dgram at the bind_conf level + - MINOR: listener: detect stream vs dgram conflict during parsing + - MINOR: listener: set the QUIC xprt layer immediately after parsing the args + - MINOR: listener/ssl: set the SSL xprt layer only once the whole config is known + - MINOR: connection: add flag MX_FL_FRAMED to mark muxes relying on framed xprt + - MINOR: config: detect and report mux and transport incompatibilities + - MINOR: listener: automatically select a QUIC mux with a QUIC transport + - MINOR: listener: automatically enable SSL if a QUIC transport is found + - BUG/MINOR: quic: Fixe a typo in qc_idle_timer_task() + - BUG/MINOR: quic: Missing stats counter decrementation + - BUILD/MINOR: cpuset fix build for FreeBSD 13.1 + - CI: determine actual OpenSSL version dynamically + +2022/05/14 : 2.6-dev10 + - MINOR: ssl: ignore dotfiles when loading a dir w/ ca-file + - MEDIUM: ssl: ignore dotfiles when loading a dir w/ crt + - BUG/MINOR: ssl: Fix typos in crl-file related CLI commands + - MINOR: compiler: add a new macro to set an attribute on an enum when possible + - BUILD: stats: conditionally mark obsolete stats states as deprecated + - BUILD: ssl: work around bogus warning in gcc 12's -Wformat-truncation + - BUILD: debug: work around gcc-12 excessive -Warray-bounds warnings + - BUILD: listener: shut report of possible null-deref in listener_accept() + - BUG/MEDIUM: ssl: fix the gcc-12 broken fix :-( + - DOC: install: update gcc version requirements + - BUILD: makefile: add -Wfatal-errors to the default flags + - BUG/MINOR: server: Make SRV_STATE_LINE_MAXLEN value from 512 to 2kB (2000 bytes). + - BUG/MAJOR: dns: multi-thread concurrency issue on UDP socket + - BUG/MINOR: mux-h2: mark the stream as open before processing it not after + - MINOR: mux-h2: report a trace event when failing to create a new stream + - DOC: configuration: add the httpclient keywords to the global keywords index + - MINOR: quic: Add a debug counter for sendto() errors + - BUG/MINOR: quic: Dropped peer transport parameters + - BUG/MINOR: quic: Wrong unit for ack delay for incoming ACK frames + - MINOR: quic: Congestion controller event trace fix (loss) + - MINOR: quic: Add correct ack delay values to ACK frames + - MINOR: config: Add "cluster-secret" new global keyword + - MINOR: quic-tls: Add quic_hkdf_extract_and_expand() for HKDF + - MINOR: quic: new_quic_cid() code moving + - MINOR: quic: Initialize stateless reset tokens with HKDF secrets + - MINOR: qc_new_conn() rework for stateless reset + - MINOR: quic: Stateless reset token copy to transport parameters + - MINOR: quic: Send stateless reset tokens + - MINOR: quic: Short packets always embed a trailing AEAD TAG + - CLEANUP: quic: wrong use of eb*entry() macro + - CLEANUP: quic: Useless use of pointer for quic_hkdf_extract() + - CLEANUP: quic_tls: QUIC_TLS_IV_LEN defined two times + - MINOR: ncbuf: define non-contiguous buffer + - MINOR: ncbuf: complete API and define block interal abstraction + - MINOR: ncbuf: optimize storage for the last gap + - MINOR: ncbuf: implement insertion + - MINOR: ncbuf: define various insertion modes + - MINOR: ncbuf: implement advance + - MINOR: ncbuf: write unit tests + - BUG/MEDIUM: lua: fix argument handling in data removal functions + - DOC/MINOR: fix typos in the lua-api document + - BUG/MEDIUM: wdt: don't trigger the watchdog when p is unitialized + - MINOR: mux-h1: Add global option accpet payload for any HTTP/1.0 requests + - CLEANUP: mux-h1: Fix comments and error messages for global options + - MINOR: conn_stream: make cs_set_error() work on the endpoint instead + - CLEANUP: mux-h1: always take the endp from the h1s not the cs + - CLEANUP: mux-h2: always take the endp from the h2s not the cs + - CLEANUP: mux-pt: always take the endp from the context not the cs + - CLEANUP: mux-fcgi: always take the endp from the fstrm not the cs + - CLEANUP: mux-quic: always take the endp from the qcs not the cs + - CLEANUP: applet: use the appctx's endp instead of cs->endp + - MINOR: conn_stream: add a pointer back to the cs from the endpoint + - MINOR: mux-h1: remove the now unneeded h1s->cs + - MINOR: mux-h2: make sure any h2s always has an endpoint + - MINOR: mux-h2: remove the now unneeded conn_stream from the h2s + - MINOR: mux-fcgi: make sure any stream always has an endpoint + - MINOR: mux-fcgi: remove the now unneeded conn_stream from the fcgi_strm + - MINOR: mux-quic: remove the now unneeded conn_stream from the qcs + - MINOR: mux-pt: remove the now unneeded conn_stream from the context + - CLEANUP: muxes: make mux->attach/detach take a conn_stream endpoint + - MINOR: applet: replace cs_applet_shut() with appctx_shut() + - MINOR: applet: add appctx_strm() and appctx_cs() to access common fields + - CLEANUP: applet: remove the unneeded appctx->owner + - CLEANUP: conn_stream: merge cs_new_from_{mux,applet} into cs_new_from_endp() + - MINOR: ext-check: indicate the transport and protocol of a server + - BUG/MEDIUM: mux-quic: fix a thinko in the latest cs/endpoint cleanup + - MINOR: tools: improve error message accuracy in str2sa_range + - MINOR: config: make sure never to mix dgram and stream protocols on a bind line + - BUG/MINOR: ncbuf: fix coverity warning on uninit sz_data + - MINOR: xprt_quic: adjust flow-control according to bufsize + - MEDIUM: mux-quic/h3/hq-interop: use ncbuf for bidir streams + - MEDIUM: mux-quic/h3/qpack: use ncbuf for uni streams + - CLEANUP: mux-quic: remove unused fields for Rx + - CLEANUP: quic: remove unused quic_rx_strm_frm + +2022/05/08 : 2.6-dev9 + - MINOR: mux-quic: support full request channel buffer + - BUG/MINOR: h3: fix parsing of unknown frame type with null length + - CLEANUP: backend: make alloc_{bind,dst}_address() idempotent + - MEDIUM: stream: remove the confusing SF_ADDR_SET flag + - MINOR: conn_stream: remove the now unused CS_FL_ADDR_*_SET flags + - CLEANUP: protocol: make sure the connect_* functions always receive a dst + - MINOR: connection: get rid of the CO_FL_ADDR_*_SET flags + - MINOR: session: get rid of the now unused SESS_FL_ADDR_*_SET flags + - CLEANUP: mux: Useless xprt_quic-t.h inclusion + - MINOR: quic: Make the quic_conn be aware of the number of streams + - BUG/MINOR: quic: Dropped retransmitted STREAM frames + - BUG/MINOR: mux_quic: Dropped packet upon retransmission for closed streams + - MEDIUM: httpclient: remove url2sa to use a more flexible parser + - MEDIUM: httpclient: http-request rules for resolving + - MEDIUM: httpclient: allow address and port change for resolving + - CLEANUP: httpclient: remove the comment about resolving + - MINOR: httpclient: handle unix and other socket types in dst + - MINOR: httpclient: rename dash by dot in global option + - MINOR: init: exit() after pre-check upon error + - MINOR: httpclient: cleanup the error handling in init + - MEDIUM: httpclient: hard-error when SSL is configured + - MINOR: httpclient: allow to configure the ca-file + - MINOR: httpclient: configure the resolvers section to use + - MINOR: httpclient: allow ipv4 or ipv6 preference for resolving + - DOC: configuration: httpclient global option + - MINOR: conn-stream: Add mask from flags set by endpoint or app layer + - BUG/MEDIUM: conn-stream: Only keep app layer flags of the endpoint on reset + - BUG/MEDIUM: mux-fcgi: Be sure to never set EOM flag on an empty HTX message + - BUG/MEDIUM: mux-h1: Be able to handle trailers when C-L header was specified + - DOC: config: Update doc for PR/PH session states to warn about rewrite failures + - MINOR: resolvers: cleanup alert/warning in parse-resolve-conf + - MINOR: resolvers: move the resolv.conf parser in parse_resolv_conf() + - MINOR: resolvers: resolvers_new() create a resolvers with default values + - BUILD: debug: unify the definition of ha_backtrace_to_stderr() + - BUG/MINOR: tcp/http: release the expr of set-{src,dst}[-port] + - MEDIUM: resolvers: create a "default" resolvers section at startup + - DOC: resolvers: default resolvers section + - BUG/MINOR: startup: usage() when no -cc arguments + - BUG/MEDIUM: resolvers: make "show resolvers" properly yield + - BUG/MEDIUM: cli: make "show cli sockets" really yield + - BUG/MINOR: proxy/cli: don't enumerate internal proxies on "show backend" + - BUG/MINOR: map/cli: protect the backref list during "show map" errors + - BUG/MINOR: map/cli: make sure patterns don't vanish under "show map"'s init + - BUG/MINOR: ssl/cli: fix "show ssl ca-file/crl-file" not to mix cli+ssl contexts + - BUG/MINOR: ssl/cli: fix "show ssl ca-file " not to mix cli+ssl contexts + - BUG/MINOR: ssl/cli: fix "show ssl crl-file" not to mix cli+ssl contexts + - BUG/MINOR: ssl/cli: fix "show ssl cert" not to mix cli+ssl contexts + - CLEANUP: ssl/cli: do not loop on unknown states in "add ssl crt-list" handler + - MINOR: applet: reserve some generic storage in the applet's context + - CLEANUP: applet: make appctx_new() initialize the whole appctx + - CLEANUP: stream/cli: take the "show sess" context definition out of the appctx + - CLEANUP: stream/cli: stop using appctx->st2 for the dump state + - CLEANUP: stream/cli: remove the unneeded init state from "show sess" + - CLEANUP: stream/cli: remove the unneeded STATE_FIN state from "show sess" + - CLEANUP: stream/cli: remove the now unneeded dump state from "show sess" + - CLEANUP: proxy/cli: take the "show errors" context definition out of the appctx + - CLEANUP: stick-table/cli: take the "show table" context definition out of the appctx + - CLEANUP: stick-table/cli: stop using appctx->st2 for the dump state + - CLEANUP: stick-table/cli: remove the unneeded STATE_INIT for "show table" + - CLEANUP: map/cli: take the "show map" context definition out of the appctx + - CLEANUP: map/cli: stop using cli.i0/i1 to store the generation numbers + - CLEANUP: map/cli: stop using appctx->st2 for the dump state + - CLEANUP: map/cli: always detach the backref from the list after "show map" + - CLEANUP: peers/cli: take the "show peers" context definition out of the appctx + - CLEANUP: peers/cli: stop using appctx->st2 for the dump state + - CLEANUP: peers/cli: remove unneeded state STATE_INIT + - CLEANUP: cli: initialize the whole appctx->ctx, not just the stats part + - CLEANUP: promex: make the applet use its own context + - CLEANUP: promex: stop using appctx->st2 + - CLEANUP: stats/cli: take the "show stat" context definition out of the appctx + - CLEANUP: stats/cli: stop using appctx->st2 + - CLEANUP: hlua/cli: take the hlua_cli context definition out of the appctx + - CLEANUP: ssl/cli: use a local context for "show cafile" + - CLEANUP: ssl/cli: use a local context for "show crlfile" + - CLEANUP: ssl/cli: use a local context for "show ssl cert" + - CLEANUP: ssl/cli: use a local context for "commit ssl cert" + - CLEANUP: ssl/cli: stop using appctx->st2 for "commit ssl cert" + - CLEANUP: ssl/cli: use a local context for "set ssl cert" + - CLEANUP: ssl/cli: use a local context for "set ssl cafile" + - CLEANUP: ssl/cli: use a local context for "set ssl crlfile" + - CLEANUP: ssl/cli: use a local context for "commit ssl {ca|crl}file" + - CLEANUP: ssl/cli: stop using appctx->st2 for "commit ssl ca/crl" + - CLEANUP: ssl/cli: stop using ctx.cli.i0/i1/p0 for "show tls-keys" + - CLEANUP: ssl/cli: add a new "dump_entries" field to "show_keys_ref" + - CLEANUP: ssl/cli: make "show tlskeys" not use appctx->st2 anymore + - CLEANUP: ssl/cli: make "show ssl ocsp-response" not use cli.p0 anymore + - CLEANUP: ssl/cli: make "{show|dump} ssl crtlist" use its own context + - CLEANUP: ssl/cli: make "add ssl crtlist" use its own context + - CLEANUP: ssl/cli: make "add ssl crtlist" not use st2 anymore + - CLEANUP: dns: stop abusing the sink forwarder's context + - CLEANUP: sink: use the generic context to store the forwarder's context + - CLEANUP: activity/cli: make "show profiling" not use ctx.cli anymore + - CLEANUP: debug/cli: make "debug dev fd" not use ctx.cli anymore + - CLEANUP: debug/cli: make "debug dev memstats" not use ctx.cli anymore + - CLEANUP: ring: pass the ring watch flags to ring_attach_cli(), not in ctx.cli + - CLEANUP: ring/cli: use a locally-defined context instead of using ctx.cli + - CLEANUP: resolvers/cli: make "show resolvers" use a locally-defined context + - CLEANUP: resolvers/cli: remove the unneeded appctx->st2 from "show resolvers" + - CLEANUP: cache/cli: make use of a locally defined context for "show cache" + - CLEANUP: proxy/cli: make use of a locally defined context for "show servers" + - CLEANUP: proxy/cli: get rid of appctx->st2 in "show servers" + - CLEANUP: proxy/cli: make "show backend" only use the generic context + - CLEANUP: cli: make "show fd" use its own context + - CLEANUP: cli: make "show env" use its own context + - CLEANUP: cli: simplify the "show cli sockets" I/O handler + - CLEANUP: cli: make "show cli sockets" use its own context + - CLEANUP: httpclient/cli: use a locally-defined context instead of ctx.cli + - CLEANUP: httpclient: do not use the appctx.ctx anymore + - CLEANUP: peers: do not use appctx.ctx anymore + - CLEANUP: spoe: do not use appctx.ctx anymore + - BUILD: applet: mark the CLI's generic variables as deprecated + - BUILD: applet: mark the appctx's st2 variable as deprecated + - CLEANUP: cache: take the context out of appctx.ctx + - MEDIUM: lua: move the cosocket storage outside of appctx.ctx + - MINOR: lua: move the tcp service storage outside of appctx.ctx + - MINOR: lua: move the http service context out of appctx.ctx + - CLEANUP: cli: move the status print context into its own context + - CLEANUP: stats: rename the stats state values an mark the old ones deprecated + - DOC: internal: document the new cleaner approach to the appctx + - MINOR: tcp: socket translate TCP_KEEPIDLE for macOs equivalent + - DOC: fix typo "ant" for "and" in INSTALL + - CI: dynamically determine actual version of h2spec + +2022/04/30 : 2.6-dev8 + - BUG/MINOR: quic: fix use-after-free with trace on ACK consume + - BUG/MINOR: rules: Forbid captures in defaults section if used by a backend + - BUG/MEDIUM: rules: Be able to use captures defined in defaults section + - BUG/MINOR: rules: Fix check_capture() function to use the right rule arguments + - BUG/MINOR: http-act: make release_http_redir() more robust + - BUG/MINOR: sample: add missing use_backend/use-server contexts in smp_resolve_args + - MINOR: sample: don't needlessly call c_none() in sample_fetch_as_type() + - MINOR: sample: make the bool type cast to bin + - MEDIUM: backend: add new "balance hash " algorithm + - MINOR: init: add global setting "fd-hard-limit" to bound system limits + - BUILD: pollers: use an initcall to register the pollers + - BUILD: xprt: use an initcall to register the transport layers + - BUILD: thread: use initcall instead of a constructor + - BUILD: http: remove the two unused constructors in rules and ana + - CLEANUP: compression: move the default setting of maxzlibmem to defaults + - MINOR: tree-wide: always consider EWOULDBLOCK in addition to EAGAIN + - BUG/MINOR: connection: "connection:close" header added despite 'close-spread-time' + - MINOR: fd: add functions to set O_NONBLOCK and FD_CLOEXEC + - CLEANUP: tree-wide: use fd_set_nonblock() and fd_set_cloexec() + - CLEANUP: tree-wide: remove 25 occurrences of unneeded fcntl.h + - REGTESTS: fix the race conditions in be2dec.vtc ad field.vtc + - REGTESTS: webstats: remove unused stats socket in /tmp + - MEDIUM: httpclient: disable SSL when the ca-file couldn't be loaded + - BUG/MINOR: httpclient/lua: error when the httpclient_start() fails + - BUG/MINOR: ssl: free the cafile entries on deinit + - BUG/MINOR: ssl: memory leak when trying to load a directory with ca-file + - MEDIUM: httpclient: re-enable the verify by default + - BUG/MEDIUM: ssl/cli: fix yielding in show_cafile_detail + - BUILD: compiler: properly distinguish weak and global symbols + - MINOR: connection: Add way to disable active connection closing during soft-stop + - BUG/MEDIUM: http-ana: Fix memleak in redirect rules with ignore-empty option + - CLEANUP: Destroy `http_err_chunks` members during deinit + - BUG/MINOR: resolvers: Fix memory leak in resolvers_deinit() + - MINOR: Call deinit_and_exit(0) for `haproxy -vv` + - BUILD: fd: disguise the fd_set_nonblock/cloexec result + - BUG/MINOR: pools: make sure to also destroy shared pools in pool_destroy_all() + - MINOR: ssl: add a new global option "tune.ssl.hard-maxrecord" + - CLEANUP: errors: also call deinit_errors_buffers() on deinit() + - CLEANUP: chunks: release trash also in deinit + - CLEANUP: deinit: release the pre-check callbacks + - CLEANUP: deinit: release the config postparsers + - CLEANUP: listeners/deinit: release accept queue tasklets on deinit + - CLEANUP: connections/deinit: destroy the idle_conns tasks + - BUG/MINOR: mux-quic: fix build in release mode + - MINOR: mux-quic: adjust comment on emission function + - MINOR: mux-quic: remove unused bogus qcc_get_stream() + - BUG/MINOR: mux-quic: fix leak if cs alloc failure + - MINOR: mux-quic: count local flow-control stream limit on reception + - BUG/MINOR: h3: fix incomplete POST requests + - BUG/MEDIUM: h3: fix use-after-free on mux Rx buffer wrapping + - MINOR: mux-quic: partially copy Rx frame if almost full buf + - MINOR: h3: change frame demuxing API + - MINOR: mux-quic: add a app-layer context in qcs + - MINOR: h3: implement h3 stream context + - MINOR: h3: support DATA demux if buffer full + - MINOR: quic: decode as much STREAM as possible + - MINOR: quic: Improve qc_prep_pkts() flexibility + - MINOR: quic: Prepare quic_frame struct duplication + - MINOR: quic: Do not retransmit frames from coalesced packets + - MINOR: quic: Add traces about TX frame memory releasing + - MINOR: quic: process_timer() rework + - MEDIUM: quic: New functions for probing rework + - MEDIUM: quic: Retransmission functions rework + - MEDIUM: quic: qc_requeue_nacked_pkt_tx_frms() rework + - MINOR: quic: old data distinction for qc_send_app_pkt() + - MINOR: quic: Mark packets as probing with old data + - MEDIUM: quic: Mark copies of acknowledged frames as acknowledged + - MEDIUM: quic: Enable the new datagram probing process + - MINOR: quic: Do not send ACK frames when probing + - BUG/MINOR: quic: Wrong returned status by qc_build_frms() + - BUG/MINOR: quic: Avoid sending useless PADDING frame + - BUG/MINOR: quic: Traces fix about remaining frames upon packet build failure + - MINOR: quic: Wake up the mux to probe with new data + - BUG/MEDIUM: quic: Possible crash on STREAM frame loss + - BUG/MINOR: quic: Missing Initial packet length check + - CLEANUP: quic: Rely on the packet length set by qc_lstnr_pkt_rcv() + - MINOR: quic: Drop 0-RTT packets if not allowed + - BUG/MINOR: httpclient/ssl: use the correct verify constant + - BUG/MEDIUM: conn-stream: Don't erase endpoint flags on reset + - BUG/MEDIUM: httpclient: Fix loop consuming HTX blocks from the response channel + - BUG/MINOR: httpclient: Count metadata in size to transfer via htx_xfer_blks() + - MINOR: httpclient: Don't use co_set_data() to decrement output + - BUG/MINOR: conn_stream: do not confirm a connection from the frontend path + - MEDIUM: quic: do not ACK packet with STREAM if MUX not present + - MEDIUM: quic: do not ack packet with invalid STREAM + - MINOR: quic: Drop 0-RTT packets without secrets + - CLEANUP: quic: Remaining fprintf() debug trace + - MINOR: quic: moving code for QUIC loss detection + - BUG/MINOR: quic: Missing time threshold multiplifier for loss delay computation + - CI: github actions: update LibreSSL to 3.5.2 + - SCRIPTS: announce-release: add URL of dev packages + +2022/04/23 : 2.6-dev7 + - BUILD: calltrace: fix wrong include when building with TRACE=1 + - MINOR: ssl: Use DH parameters defined in RFC7919 instead of hard coded ones + - MEDIUM: ssl: Disable DHE ciphers by default + - BUILD: ssl: Fix compilation with OpenSSL 1.0.2 + - MINOR: mux-quic: split xfer and STREAM frames build + - REORG: quic: use a dedicated module for qc_stream_desc + - MINOR: quic-stream: use distinct tree nodes for quic stream and qcs + - MINOR: quic-stream: add qc field + - MEDIUM: quic: implement multi-buffered Tx streams + - MINOR: quic-stream: refactor ack management + - MINOR: quic: limit total stream buffers per connection + - MINOR: mux-quic: implement immediate send retry + - MINOR: cfg-quic: define tune.quic.conn-buf-limit + - MINOR: ssl: Add 'show ssl providers' cli command and providers list in -vv option + - REGTESTS: ssl: Update error messages that changed with OpenSSLv3.1.0-dev + - BUG/MEDIUM: quic: Possible crash with released mux + - BUG/MINOR: mux-quic: unsubscribe on release + - BUG/MINOR: mux-quic: handle null timeout + - BUG/MEDIUM: logs: fix http-client's log srv initialization + - BUG/MINOR: mux-quic: remove dead code in qcs_xfer_data() + - DEV: stream: Fix conn-streams dump in full stream message + - CLEANUP: conn-stream: Rename cs_conn_close() and cs_conn_drain_and_close() + - CLEANUP: conn-stream: Rename cs_applet_release() + - MINOR: conn-stream: Rely on endpoint shutdown flags to shutdown an applet + - BUG/MINOR: cache: Disable cache if applet creation fails + - BUG/MINOR: backend: Don't allow to change backend applet + - BUG/MEDIUM: conn-stream: Set back CS to RDY state when the appctx is created + - MINOR: stream: Don't needlessly detach server endpoint on early client abort + - MINOR: conn-stream: Make cs_detach_* private and use cs_destroy() from outside + - MINOR: init: add the pre-check callback + - MEDIUM: httpclient: change the init sequence + - MEDIUM: httpclient/ssl: verify required + - MINOR: httpclient/mworker: disable in the master process + - MEDIUM: httpclient/ssl: verify is configurable and disabled by default + - BUG/MAJOR: connection: Never remove connection from idle lists outside the lock + - BUG/MEDIUM: mux-quic: fix stalled POST requets + - BUG/MINOR: mux-quic: fix POST with abortonclose + - MINOR: task: add a new task_instant_wakeup() function + - MEDIUM: queue: use tasklet_instant_wakeup() to wake tasks + - DOC: remove my name from the config doc + +2022/04/16 : 2.6-dev6 + - CLEANUP: connection: reduce the with of the mux dump output + - CI: Update to actions/checkout@v3 + - CI: Update to actions/cache@v3 + - DOC: adjust QUIC instruction in INSTALL + - BUG/MINOR: stats: define the description' background color in dark color scheme + - BUILD: ssl: add USE_ENGINE and disable the openssl engine by default + - BUILD: makefile: pass USE_ENGINE to cflags + - BUILD: xprt-quic: replace ERR_func_error_string() with ERR_peek_error_func() + - DOC: install: document the fact that SSL engines are not enabled by default + - CI: github actions: disable -Wno-deprecated + - BUILD: makefile: silence unbearable OpenSSL deprecation warnings + - MINOR: sock: check configured limits at the sock layer, not the listener's + - MINOR: connection: add a new flag CO_FL_FDLESS on fd-less connections + - MINOR: connection: add conn_fd() to retrieve the FD only when it exists + - MINOR: stream: only dump connections' FDs when they are valid + - MINOR: connection: use conn_fd() when displaying connection errors + - MINOR: connection: skip FD-based syscalls for FD-less connections + - MEDIUM: connection: panic when calling FD-specific functions on FD-less conns + - MINOR: mux-quic: properly set the flags and name fields + - MINOR: connection: rearrange conn_get_src/dst to be a bit more extensible + - MINOR: protocol: add get_src() and get_dst() at the protocol level + - MINOR: quic-sock: provide a pair of get_src/get_dst functions + - MEDIUM: ssl: improve retrieval of ssl_sock_ctx and SSL detection + - MEDIUM: ssl: stop using conn->xprt_ctx to access the ssl_sock_ctx + - MEDIUM: xprt-quic: implement get_ssl_sock_ctx() + - MEDIUM: quic: move conn->qc into conn->handle + - BUILD: ssl: fix build warning with previous changes to ssl_sock_ctx + - BUILD: ssl: add an unchecked version of __conn_get_ssl_sock_ctx() + - MINOR: ssl: refine the error testing for fc_err and fc_err_str + - BUG/MINOR: sock: do not double-close the accepted socket on the error path + - CI: cirrus: switch to FreeBSD-13.0 + - MINOR: log: add '~' to frontend when the transport layer provides SSL + - BUILD/DEBUG: lru: fix printf format in debug code + - BUILD: peers: adjust some printf format to silence cppcheck + - BUILD/DEBUG: hpack-tbl: fix format string in standalone debug code + - BUILD/DEBUG: hpack: use unsigned int in printf format in debug code + - BUILD: halog: fix some incorrect signs in printf formats for integers + - BUG/MINOR: h3: fix build with DEBUG_H3 + - BUG/MINOR: mux-h2: do not send GOAWAY if SETTINGS were not sent + - BUG/MINOR: cache: do not display expired entries in "show cache" + - BUG/MINOR: mux-h1: Don't release unallocated CS on error path + - MINOR: applet: Make .init callback more generic + - MINOR: conn-stream: Add flags to set the type of the endpoint + - MEDIUM: applet: Set the appctx owner during allocation + - MAJOR: conn-stream: Invert conn-stream endpoint and its context + - REORG: Initialize the conn-stream by hand in cs_init() + - MEDIUM: conn-stream: Add an endpoint structure in the conn-stream + - MINOR: conn-stream: Move some CS flags to the endpoint + - MEDIUM: conn-stream: Be able to pass endpoint to create a conn-stream + - MEDIUM: conn-stream: Pre-allocate endpoint to create CS from muxes and applets + - REORG: applet: Uninline appctx_new function + - MAJOR: conn-stream: Share endpoint struct between the CS and the mux/applet + - MEDIUM: conn-stream: Move remaning flags from CS to endpoint + - MINOR: mux-pt: Rely on the endpoint instead of the conn-stream when possible + - MINOR: conn-stream: Add ISBACK conn-stream flag + - MINOR: conn-stream: Add header file with util functions related to conn-streams + - MEDIUM: tree-wide: Use CS util functions instead of SI ones + - MINOR: stream-int/txn: Move buffer for L7 retries in the HTTP transaction + - CLEANUP: http-ana: Remove http_alloc_txn() function + - MINOR: stream-int/stream: Move conn_retries counter in the stream + - MINOR: stream: Simplify retries counter calculation + - MEDIUM: stream-int/conn-stream: Move src/dst addresses in the conn-stream + - MINOR: stream-int/conn-stream: Move half-close timeout in the conn-stream + - MEDIUM: stream-int/stream: Use connect expiration instead of SI expiration + - MINOR: stream-int/conn-stream: Report error to the CS instead of the SI + - MEDIUM: conn-stream: Use endpoint error instead of conn-stream error + - MINOR: channel: Use conn-streams as channel producer and consumer + - MINOR: stream-int: Remove SI_FL_KILL_CON to rely on conn-stream endpoint only + - MINOR: mux-h2/mux-fcgi: Fully rely on CS_EP_KILL_CONN + - MINOR: stream-int: Remove SI_FL_NOLINGER/NOHALF to rely on CS flags instead + - MINOR: stream-int: Remove SI_FL_DONT_WAKE to rely on CS flags instead + - MINOR: stream-int: Remove SI_FL_INDEP_STR to rely on CS flags instead + - MINOR: stream-int: Remove SI_FL_SRC_ADDR to rely on stream flags instead + - CLEANUP: stream-int: Remove unused SI_FL_CLEAN_ABRT flag + - MINOR: stream: Only save previous connection state for the server side + - MEDIUM: stream-int: Move SI err_type in the stream + - MEDIUM: stream-int/conn-stream: Move stream-interface state in the conn-stream + - MINOR: stream-int/stream: Move si_retnclose() in the stream scope + - MINOR: stream-int/backend: Move si_connect() in the backend scope + - MINOR: stream-int/conn-stream: Move si_conn_ready() in the conn-stream scope + - MINOR: conn-stream/connection: Move SHR/SHW modes in the connection scope + - MEDIUM: conn-stream: Be prepared to fail to attach a cs to a mux + - MEDIUM: stream-int/conn-stream: Handle I/O subscriptions in the conn-stream + - MINOR: conn-stream: Rename CS functions dedicated to connections + - MINOR: stream-int/conn-stream: Move si_shut* and si_chk* in conn-stream scope + - MEDIUM: stream-int/conn-stream: Move si_ops in the conn-stream scope + - MINOR: applet: Use the CS to register and release applets instead of SI + - MINOR: connection: unconst mux's get_fist_cs() callback function + - MINOR: stream-int/connection: Move conn_si_send_proxy() in the connection scope + - REORG: stream-int: Export si_cs_recv(), si_cs_send() and si_cs_process() + - REORG: stream-int: Move si_is_conn_error() in the header file + - REORG: conn-stream: Move cs_shut* and cs_chk* in cs_utils + - REORG: conn-stream: Move cs_app_ops in conn_stream.c + - MINOR: stream-int-conn-stream: Move si_update_* in conn-stream scope + - MINOR: stream-int/stream: Move si_update_both in stream scope + - MEDIUM: conn-stream/applet: Add a data callback for applets + - MINOR: stream-int/conn-stream: Move stream_int_read0() in the conn-stream scope + - MINOR: stream-int/conn-stream: Move stream_int_notify() in the conn-stream scope + - MINOR: stream-int/conn-stream: Move si_cs_io_cb() in the conn-stream scope + - MINOR: stream-int/conn-stream: Move si_sync_recv/send() in conn-stream scope + - MINOR: conn-stream: Move si_conn_cb in the conn-stream scope + - MINOR: stream-int/conn-stream Move si_is_conn_error() in the conn-stream scope + - MINOR: stream-int/conn-stream: Move si_alloc_ibuf() in the conn-stream scope + - CLEANUP: stream-int: Remove unused SI functions + - MEDIUM: stream-int/conn-stream: Move blocking flags from SI to CS + - MEDIUM: stream-int/conn-stream: Move I/O functions to conn-stream + - REORG: stream-int/conn-stream: Move remaining functions to conn-stream + - MINOR: stream: Use conn-stream to report server error + - MINOR: http-ana: Use CS to perform L7 retries + - MEDIUM: stream: Don't use the stream-int anymore in process_stream() + - MINOR: conn-stream: Remove the stream-interface from the conn-stream + - DEV: flags: No longer dump SI flags + - CLEANUP: tree-wide: Remove any ref to stream-interfaces + - CLEANUP: conn-stream: Don't export internal functions + - DOC: conn-stream: Add comments on functions of the new CS api + - MEDIUM: check: Use a new conn-stream for each health-check run + - CLEANUP: muxes: Remove MX_FL_CLEAN_ABRT flag + - MINOR: conn-stream: Use a dedicated function to conditionally remove a CS + - CLEANUP: conn-stream: rename cs_register_applet() to cs_applet_create() + - MINOR: muxes: Improve show_fd callbacks to dump endpoint flags + - MINOR: mux-h1: Rely on the endpoint instead of the conn-stream when possible + - BUG/MINOR: quic: Avoid starting the mux if no ALPN sent by the client + - BUILD: debug: mark the __start_mem_stats/__stop_mem_stats symbols as weak + - BUILD: initcall: mark the __start_i_* symbols as weak, not global + - BUG/MINOR: mux-h2: do not use timeout http-keep-alive on backend side + - BUG/MINOR: mux-h2: use timeout http-request as a fallback for http-keep-alive + - MINOR: muxes: Don't expect to have a mux without connection in destroy callback + - MINOR: muxes: Don't handle proto upgrade for muxes not supporting it + - MINOR: muxes: Don't expect to call release function with no mux defined + - MINOR: conn-stream: Use unsafe functions to get conn/appctx in cs_detach_endp + - BUG/MEDIUM: mux-h1: Don't request more room on partial trailers + - BUILD: http-client: Avoid dead code when compiled without SSL support + - BUG/MINOR: mux-quic: prevent a crash in session_free on mux.destroy + - BUG/MINOR: quic-sock: do not double free session on conn init failure + - BUG/MINOR: quic: fix return value for error in start + - MINOR: quic: emit CONNECTION_CLOSE on app init error + - BUILD: sched: workaround crazy and dangerous warning in Clang 14 + - BUILD: compiler: use a more portable set of asm(".weak") statements + - BUG/MEDIUM: stream: do not abort connection setup too early + - CLEANUP: extcheck: do not needlessly preset the server's address/port + - MINOR: extcheck: fill in the server's UNIX socket address when known + - BUG/MEDIUM: connection: Don't crush context pointer location if it is a CS + - BUG/MEDIUM: quic: properly clean frames on stream free + - BUG/MEDIUM: fcgi-app: Use http_msg flags to know if C-L header can be added + - BUG/MEDIUM: compression: Don't forget to update htx_sl and http_msg flags + - MINOR: tcp_sample: clarifying samples support per os, for further expansion. + - MINOR: tcp_sample: extend support for get_tcp_info to macOs. + - SCRIPTS: announce-release: update the doc's URL + - DOC: lua: update a few doc URLs + - SCRIPTS: announce-release: add shortened links to pending issues + +2022/04/09 : 2.6-dev5 + - DOC: reflect H2 timeout changes + - BUG/MEDIUM: mux-fcgi: Properly handle return value of headers/trailers parsing + - BUG/MEDIUM: mux-h1: Properly detect full buffer cases during message parsing + - BUG/MINOR: log: Initialize the list element when allocating a new log server + - BUG/MINOR: samples: add missing context names for sample fetch functions + - MINOR: management: add some basic keyword dump infrastructure + - MINOR: config: add a function to dump all known config keywords + - MINOR: filters: extend flt_dump_kws() to dump to stdout + - MINOR: services: extend list_services() to dump to stdout + - MINOR: cli: add a new keyword dump function + - MINOR: acl: add a function to dump the list of known ACL keywords + - MINOR: samples: add a function to list register sample fetch keywords + - MINOR: sample: list registered sample converter functions + - MINOR: tools: add strordered() to check whether strings are ordered + - MINOR: action: add a function to dump the list of actions for a ruleset + - MINOR: config: alphanumerically sort config keywords output + - MINOR: sample: alphanumerically sort sample & conv keyword dumps + - MINOR: acl: alphanumerically sort the ACL dump + - MINOR: cli: alphanumerically sort the dump of supported commands + - MINOR: filters: alphabetically sort the list of filter names + - MINOR: services: alphabetically sort service names + - MEDIUM: httpclient/lua: be stricter with httpclient parameters + - MINOR: ssl: split the cert commit io handler + - MINOR: ssl: move the cert_exts and the CERT_TYPE enum + - MINOR: ssl: simplify the certificate extensions array + - MINOR: ssl: export ckch_inst_rebuild() + - MINOR: ssl: add "crt" in the cert_exts array + - MINOR: ssl/lua: CertCache.set() allows to update an SSL certificate file + - BUILD: ssl/lua: CacheCert needs OpenSSL + - DOC: lua: CertCache class documentation + - BUG/MEDIUM: quic: do not use qcs from quic_stream on ACK parsing + - MINOR: mux-quic: return qcs instance from qcc_get_qcs + - MINOR: mux-quic: reorganize qcs free + - MINOR: mux-quic: define release app-ops + - BUG/MINOR: h3: release resources on close + - BUG/MINOR: mux-quic: ensure to free all qcs on MUX release + - CLEANUP: quic: complete comment on qcs_try_to_consume + - MINOR: quic: implement stream descriptor for transport layer + - MEDIUM: quic: move transport fields from qcs to qc_conn_stream + - MEDIUM: mux-quic: remove qcs tree node + - BUG/MINOR: cli/stream: fix "shutdown session" to iterate over all threads + - DOC: management: add missing dot in 9.4.1 + - BUG/MAJOR: mux_pt: always report the connection error to the conn_stream + - DOC: remove double blanks in configuration.txt + - CI: github actions: update OpenSSL to 3.0.2 + - BUG/MEDIUM: quic: Possible crash in ha_quic_set_encryption_secrets() + - CLEANUP: quic: Remove all atomic operations on quic_conn struct + - CLEANUP: quic: Remove all atomic operations on packet number spaces + - MEDIUM: quic: Send ACK frames asap + - BUG/MINOR: quic: Missing probing packets when coalescing + - BUG/MINOR: quic: Discard Initial packet number space only one time + - MINOR: quic: Do not display any timer value from process_timer() + - BUG/MINOR: quic: Do not probe from an already probing packet number space + - BUG/MINOR: quic: Non duplicated frames upon fast retransmission + - BUG/MINOR: quic: Too much prepared retransmissions due to anti-amplification + - MINOR: quic: Useless call to SSL_CTX_set_default_verify_paths() + - MINOR: quic: Add traces about list of frames + - BUG/MINOR: h3: Missing wait event struct field initialization + - BUG/MINOR: quic: QUIC TLS secrets memory leak + - BUG/MINOR: quic: Missing ACK range deallocations + - BUG/MINOR: quic: Missing TX packet deallocations + - CLEANUP: hpack: be careful about integer promotion from uint8_t + - OPTIM: hpack: read 32 bits at once when possible. + - MEDIUM: ssl: allow loading of a directory with the ca-file directive + - BUG/MINOR: ssl: continue upon error when opening a directory w/ ca-file + - MINOR: ssl: ca-file @system-ca loads the system trusted CA + - DOC: configuration: add the ca-file changes + - MINOR: sample: converter: Add add_item convertor + - BUG/MINOR: ssl: handle X509_get_default_cert_dir() returning NULL + - BUG/MINOR: ssl/cli: Remove empty lines from CLI output + - MINOR: httpclient: enable request buffering + - MEDIUM: httpclient: enable l7-retry + - BUG/MINOR: httpclient: end callback in applet release + - MINOR: quic: Add draining connection state. + - MINOR: quic: Add closing connection state + - BUG/MEDIUM: quic: ensure quic-conn survives to the MUX + - CLEANUP: quic: use static qualifer on quic_close + - CLEANUP: mux-quic: remove unused QC_CF_CC_RECV + - BUG/MINOR: fix memleak on quic-conn streams cleaning + - MINOR: mux-quic: factorize conn-stream attach + - MINOR: mux-quic: adjust timeout to accelerate closing + - MINOR: mux-quic: define is_active app-ops + - MINOR: mux-quic: centralize send operations in qc_send + - MEDIUM: mux-quic: report CO_FL_ERROR on send + - MEDIUM: mux-quic: report errors on conn-streams + - MEDIUM: quic: report closing state for the MUX + - BUG/MINOR: fcgi-app: Don't add C-L header on response to HEAD requests + - BUG/MEDIUM: stats: Be sure to never set EOM flag on an empty HTX message + - BUG/MEDIUM: hlua: Don't set EOM flag on an empty HTX message in HTTP applet + - BUG/MEDIUM: promex: Be sure to never set EOM flag on an empty HTX message + - BUG/MEDIUM: mux-h1: Set outgoing message to DONE when payload length is reached + - BUG/MINOR: http_client: Don't add input data on an empty request buffer + - BUG/MEDIUM: http-conv: Fix url_enc() to not crush const samples + - BUG/MEDIUM: http-act: Don't replace URI if path is not found or invalid + - CLEANUP: mux-quic: remove uneeded TODO in qc_detach + - BUG/MEDIUM: mux-quic: properly release conn-stream on detach + - BUG/MINOR: quic: set the source not the destination address on accept() + - BUG/MEDIUM: quic: Possible crash from quic_free_arngs() + - MINOR: quic_tls: Add reusable cipher contexts to QUIC TLS contexts + - MINOR: quic_tls: Stop hardcoding cipher IV lengths + - CLEANUP: quic: Do not set any cipher/group from ssl_quic_initial_ctx() + - MINOR: quic: Add short packet key phase bit values to traces + - MINOR: quic_tls: Make key update use of reusable cipher contexts + - BUG/MINOR: opentracing: setting the return value in function flt_ot_var_set() + - BUG/BUILD: opentracing: fixed OT_DEFINE variable setting + - EXAMPLES: opentracing: refined shell scripts for testing filter performance + - DOC: opentracing: corrected comments in function descriptions + - CLEANUP: opentracing: removed unused function flt_ot_var_unset() + - CLEANUP: opentracing: removed unused function flt_ot_var_get() + - Revert "MINOR: opentracing: change the scope of the variable 'ot.uuid' from 'sess' to 'txn'" + - MINOR: opentracing: only takes the variables lock on shared entries + - CLEANUP: opentracing: added flt_ot_smp_init() function + - CLEANUP: opentracing: added variable to store variable length + - MINOR: opentracing: improved normalization of context variable names + - DEBUG: opentracing: show return values of all functions in the debug output + - CLEANUP: opentracing: added FLT_OT_PARSE_INVALID_enum enum + - DEBUG: opentracing: display the contents of the err variable after setting + - MAJOR: opentracing: reenable usage of vars to transmit opentracing context + - Revert "BUILD: opentracing: display warning in case of using OT_USE_VARS at compile time" + - MEDIUM: global: Add a "close-spread-time" option to spread soft-stop on time window + +2022/03/26 : 2.6-dev4 + - BUG/MEDIUM: httpclient: don't consume data before it was analyzed + - CLEANUP: htx: remove unused co_htx_remove_blk() + - BUG/MINOR: httpclient: consume partly the blocks when necessary + - BUG/MINOR: httpclient: remove the UNUSED block when parsing headers + - BUG/MEDIUM: httpclient: must manipulate head, not first + - REGTESTS: fix the race conditions in be2hex.vtc + - BUG/MEDIUM: quic: Blocked STREAM when retransmitted + - BUG/MAJOR: quic: Possible crash with full congestion control window + - BUG/MINOR: httpclient/lua: stuck when closing without data + - BUG/MEDIUM: applet: Don't call .release callback function twice + - BUG/MEDIUM: cli/debug: Properly get the stream-int in all debug I/O handlers + - BUG/MEDIUM: sink: Properly get the stream-int in appctx callback functions + - DEV: udp: switch parser to getopt() instead of positional arguments + - DEV: udp: add support for random packet corruption + - MINOR: server: export server_parse_sni_expr() function + - BUG/MINOR: httpclient: send the SNI using the host header + - BUILD: httpclient: fix build without SSL + - BUG/MINOR: server/ssl: free the SNI sample expression + - BUG/MINOR: logs: fix logsrv leaks on clean exit + - MINOR: actions: add new function free_act_rule() to free a single rule + - BUG/MINOR: tcp-rules: completely free incorrect TCP rules on error + - BUG/MINOR: http-rules: completely free incorrect TCP rules on error + - BUG/MINOR: httpclient: only check co_data() instead of HTTP_MSG_DATA + - BUG/MINOR: httpclient: process the response when received before the end of the request + - BUG/MINOR: httpclient: CF_SHUTW_NOW should be tested with channel_is_empty() + - CI: github actions: switch to LibreSSL-3.5.1 + - BUG/MEDIUM: mux-h1: only turn CO_FL_ERROR to CS_FL_ERROR with empty ibuf + - BUG/MEDIUM: stream-int: do not rely on the connection error once established + - BUG/MEDIUM: trace: avoid race condition when retrieving session from conn->owner + - MEDIUM: mux-h2: slightly relax timeout management rules + - BUG/MEDIUM: mux-h2: make use of http-request and keep-alive timeouts + - BUG/MINOR: rules: Initialize the list element when allocating a new rule + - BUG/MINOR: http-rules: Don't free new rule on allocation failure + - DEV: coccinelle: Fix incorrect replacement in ist.cocci + - CLEANUP: Reapply ist.cocci with `--include-headers-for-types --recursive-includes` + - DEV: coccinelle: Add a new pattern to ist.cocci + - CLEANUP: Reapply ist.cocci + - REGTESTS: Do not use REQUIRE_VERSION for HAProxy 2.5+ + - MINOR: quic: Code factorization (TX buffer reuse) + - CLEANUP: quic: "largest_acked_pn" pktns struc member moving + - MEDIUM: quic: Limit the number of ACK ranges + - MEDIUM: quic: Rework of the TX packets memory handling + - BUG/MINOR: quic: Possible crash in parse_retry_token() + - BUG/MINOR: quic: Possible leak in quic_build_post_handshake_frames() + - BUG/MINOR: quic: Unsent frame because of qc_build_frms() + - BUG/MINOR: mux-quic: Access to empty frame list from qc_send_frames() + - BUG/MINOR: mux-quic: Missing I/O handler events initialization + - BUG/MINOR: quic: Missing TX packet initializations + - BUG/MINOR: quic: 1RTT packets ignored after mux was released + - BUG/MINOR: quic: Incorrect peer address validation + - BUG/MINOR: quic: Non initialized variable in quic_build_post_handshake_frames() + - BUG/MINOR: quic: Wrong TX packet related counters handling + - MEDIUM: mqtt: support mqtt_is_valid and mqtt_field_value converters for MQTTv3.1 + - DOC: config: Explictly add supported MQTT versions + - MINOR: quic: Add traces about stream TX buffer consumption + - MINOR: quic: Add traces in qc_set_timer() (scheduling) + - CLEANUP: mux-quic: change comment style to not mess with git conflict + - CLEANUP: mux-quic: adjust comment for coding-style + - MINOR: mux-quic: complete trace when stream is not found + - MINOR: mux-quic: add comments for send functions + - MINOR: mux-quic: use shorter name for flow-control fields + - MEDIUM: mux-quic: respect peer bidirectional stream data limit + - MEDIUM: mux-quic: respect peer connection data limit + - MINOR: mux-quic: support MAX_STREAM_DATA frame parsing + - MINOR: mux-quic: support MAX_DATA frame parsing + - BUILD: stream-int: avoid a build warning when DEBUG is empty + - BUG/MINOR: quic: Wrong buffer length passed to generate_retry_token() + - BUG/MINOR: tools: fix url2sa return value with IPv4 + - MINOR: mux-quic: convert fin on push-frame as boolean + - BUILD: quic: add missing includes + - REORG: quic: use a dedicated quic_loss.c + - MINOR: mux-quic: declare the qmux trace module + - MINOR: mux-quic: replace printfs by traces + - MINOR: mux-quic: add trace event for frame sending + - MINOR: mux-quic: add trace event for qcs_push_frame + - MINOR: mux-quic: activate qmux traces on stdout via macro + - BUILD: qpack: fix unused value when not using DEBUG_HPACK + - CLEANUP: qpack: suppress by default stdout traces + - CLEANUP: h3: suppress by default stdout traces + - BUG/MINOR: tools: url2sa reads too far when no port nor path + +2022/03/11 : 2.6-dev3 + - DEBUG: rename WARN_ON_ONCE() to CHECK_IF() + - DEBUG: improve BUG_ON output message accuracy + - DEBUG: implement 4 levels of choices between warn and crash. + - DEBUG: add two new macros to enable debugging in hot paths + - DEBUG: buf: replace some sensitive BUG_ON() with BUG_ON_HOT() + - DEBUG: buf: add BUG_ON_HOT() to most buffer management functions + - MINOR: channel: don't use co_set_data() to decrement output + - DEBUG: channel: add consistency checks using BUG_ON_HOT() in some key functions + - MINOR: conn-stream: Improve API to have safe/unsafe accessors + - MEDIUM: tree-wide: Use unsafe conn-stream API when it is relevant + - CLEANUP: stream-int: Make si_cs_send() function static + - REORG: stream-int: Uninline si_sync_recv() and make si_cs_recv() private + - BUG/MEDIUM: mux-fcgi: Don't rely on SI src/dst addresses for FCGI health-checks + - BUG/MEDIUM: htx: Fix a possible null derefs in htx_xfer_blks() + - REGTESTS: fix the race conditions in normalize_uri.vtc + - DEBUG: stream-int: Fix BUG_ON used to test appctx in si_applet_ops callbacks + - BUILD: debug: fix build warning on older compilers around DEBUG_STRICT_ACTION + - CLEANUP: connection: Indicate unreachability to the compiler in conn_recv_proxy + - MINOR: connection: Transform safety check in PROXYv2 parsing into BUG_ON() + - DOC: install: it's DEBUG_CFLAGS, not DEBUG, which is set to -g + - DOC: install: describe the DEP variable + - DOC: install: describe how to choose options used in the DEBUG variable + - MINOR: queue: Replace if() + abort() with BUG_ON() + - CLEANUP: adjust indentation in bidir STREAM handling function + - MINOR: quic: simplify copy of STREAM frames to RX buffer + - MINOR: quic: handle partially received buffered stream frame + - MINOR: mux-quic: define flag for last received frame + - BUG/MINOR: quic: support FIN on Rx-buffered STREAM frames + - MEDIUM: quic: rearchitecture Rx path for bidirectional STREAM frames + - REGTESTS: fix the race conditions in secure_memcmp.vtc + - CLEANUP: stream: Remove useless tests on conn-stream in stream_dump() + - BUILD: ssl: another build warning on LIBRESSL_VERSION_NUMBER + - MINOR: quic: Ensure PTO timer is not set in the past + - MINOR: quic: Post handshake I/O callback switching + - MINOR: quic: Drop the packets of discarded packet number spaces + - CLEANUP: quic: Useless tests in qc_try_rm_hp() + - CLEANUP: quic: Indentation fix in qc_prep_pkts() + - MINOR: quic: Assemble QUIC TLS flags at the same level + - BUILD: conn_stream: avoid null-deref warnings on gcc 6 + - BUILD: connection: do not declare register_mux_proto() inline + - BUILD: http_rules: do not declare http_*_keywords_registre() inline + - BUILD: trace: do not declare trace_registre_source() inline + - BUILD: tcpcheck: do not declare tcp_check_keywords_register() inline + - DEBUG: reduce the footprint of BUG_ON() calls + - BUG/MEDIUM: httpclient/lua: infinite appctx loop with POST + - BUG/MINOR: pool: always align pool_heads to 64 bytes + - DEV: udp: add a tiny UDP proxy for testing + - DEV: udp: implement pseudo-random reordering/loss + - DEV: udp: add an optional argument to set the prng seed + - BUG/MINOR: quic: fix segfault on CC if mux uninitialized + - BUG/MEDIUM: pools: fix ha_free() on area in the process of being freed + - CLEANUP: tree-wide: remove a few rare non-ASCII chars + - CI: coverity: simplify debugging options + - CLEANUP: quic: complete ABORT_NOW with a TODO comment + - MINOR: quic: qc_prep_app_pkts() implementation + - MINOR: quic: Send short packet from a frame list + - MINOR: quic: Make qc_build_frms() build ack-eliciting frames from a list + - MINOR: quic: Export qc_send_app_pkts() + - MINOR: mux-quic: refactor transport parameters init + - MINOR: mux-quic: complete functions to detect stream type + - MINOR: mux-quic: define new unions for flow-control fields + - MEDIUM: mux-quic: use direct send transport API for STREAMs + - MINOR: mux-quic: retry send opportunistically for remaining frames + - MEDIUM: mux-quic: implement MAX_STREAMS emission for bidir streams + - BUILD: fix kFreeBSD build. + - MINOR: quic: Retry on qc_build_pkt() failures + - BUG/MINOR: quic: Missing recovery start timer reset + - CLEANUP: quic: Remove QUIC path manipulations out of the congestion controller + - MINOR: quic: Add a "slow start" callback to congestion controller + - MINOR: quic: Persistent congestion detection outside of controllers + - CLEANUP: quic: Remove useless definitions from quic_cc_event struct + - BUG/MINOR: quic: Confusion betwen "in_flight" and "prep_in_flight" in quic_path_prep_data() + - MINOR: quic: More precise window update calculation + - CLEANUP: quic: Remove window redundant variable from NewReno algorithm state struct + - MINOR: quic: Add quic_max_int_by_size() function + - BUG/MAJOR: quic: Wrong quic_max_available_room() returned value + - MINOR: pools: add a new global option "no-memory-trimming" + - BUG/MINOR: add missing modes in proxy_mode_str() + - BUG/MINOR: cli: shows correct mode in "show sess" + - BUG/MEDIUM: quic: do not drop packet on duplicate stream/decoding error + - MINOR: stats: Add dark mode support for socket rows + - BUILD: fix recent build breakage of freebsd caused by kFreeBSD build fix + - BUG/MINOR: httpclient: Set conn-stream/channel EOI flags at the end of request + - BUG/MINOR: hlua: Set conn-stream/channel EOI flags at the end of request + - BUG/MINOR: stats: Set conn-stream/channel EOI flags at the end of request + - BUG/MINOR: cache: Set conn-stream/channel EOI flags at the end of request + - BUG/MINOR: promex: Set conn-stream/channel EOI flags at the end of request + - BUG/MEDIUM: stream: Use the front analyzers for new listener-less streams + - DEBUG: cache: Update underlying buffer when loading HTX message in cache applet + - BUG/MEDIUM: mcli: Properly handle errors and timeouts during reponse processing + - DEBUG: stream: Add the missing descriptions for stream trace events + - DEBUG: stream: Fix stream trace message to print response buffer state + - MINOR: proxy: Store monitor_uri as a `struct ist` + - MINOR: proxy: Store fwdfor_hdr_name as a `struct ist` + - MINOR: proxy: Store orgto_hdr_name as a `struct ist` + - MEDIUM: proxy: Store server_id_hdr_name as a `struct ist` + - CLEANUP: fcgi: Replace memcpy() on ist by istcat() + - CLEANUP: fcgi: Use `istadv()` in `fcgi_strm_send_params` + - BUG/MAJOR: mux-pt: Always destroy the backend connection on detach + - DOC: sample fetch methods: move distcc_* to the right locations + - MINOR: rules: record the last http/tcp rule that gave a final verdict + - MINOR: stream: add "last_rule_file" and "last_rule_line" samples + - BUG/MINOR: session: fix theoretical risk of memleak in session_accept_fd() + - MINOR: quic: Add max_idle_timeout advertisement handling + - MEDIUM: quic: Remove the QUIC connection reference counter + - BUG/MINOR: quic: ACK_REQUIRED and ACK_RECEIVED flag collision + - BUG/MINOR: quic: Missing check when setting the anti-amplification limit as reached + - MINOR: quic: Add a function to compute the current PTO + - MEDIUM: quic: Implement the idle timeout feature + - BUG/MEDIUM: quic: qc_prep_app_pkts() retries on qc_build_pkt() failures + - CLEANUP: quic: Comments fix for qc_prep_(app)pkts() functions + - MINOR: mux-quic: prevent push frame for unidir streams + - MINOR: mux-quic: improve opportunistic retry sending for STREAM frames + - MINOR: quic: implement sending confirmation + - MEDIUM: mux-quic: improve bidir STREAM frames sending + - MEDIUM: check: do not auto configure SSL/PROXY for dynamic servers + - REGTESTS: server: test SSL/PROXY with checks for dynamic servers + - MEDIUM: server: remove experimental-mode for dynamic servers + - BUG/MINOR: buffer: fix debugging condition in b_peek_varint() + +2022/02/25 : 2.6-dev2 + - DOC: management: rework the Master CLI section + - DOC: management: add expert and experimental mode in 9.4.1 + - CLEANUP: cleanup a commentary in pcli_parse_request() + - BUG/MINOR: mworker/cli: don't display help on master applet + - MINOR: mworker/cli: mcli-debug-mode enables every command + - MINOR: mworker/cli: add flags in the prompt + - BUG/MINOR: httpclient: Revisit HC request and response buffers allocation + - BUG/MEDIUM: httpclient: Xfer the request when the stream is created + - MINOR: httpclient: Don't limit data transfer to 1024 bytes + - BUILD: ssl: adjust guard for X509_get_X509_PUBKEY(x) + - REGTESTS: ssl: skip show_ssl_ocspresponse.vtc when BoringSSL is used + - MINOR: quic: Do not modify a marked as consumed datagram + - MINOR: quic: Wrong datagram buffer passed to quic_lstnr_dgram_dispatch() + - MINOR: quic: Remove a useless test in quic_get_dgram_dcid() + - BUG/MINOR: ssl: Remove empty lines from "show ssl ocsp-response " output + - CLEANUP: ssl: Remove unused ssl_sock_create_cert function + - MINOR: ssl: Use high level OpenSSL APIs in sha2 converter + - MINOR: ssl: Remove EC_KEY related calls when preparing SSL context + - REGTESTS: ssl: Add test for "curves" and "ecdhe" SSL options + - MINOR: ssl: Remove EC_KEY related calls when creating a certificate + - REGTESTS: ssl: Add test for "generate-certificates" SSL option + - MINOR: ssl: Remove call to SSL_CTX_set_tlsext_ticket_key_cb with OpenSSLv3 + - MINOR: ssl: Remove call to HMAC_Init_ex with OpenSSLv3 + - MINOR: h3: hardcode the stream id of control stream + - MINOR: mux-quic: remove quic_transport_params_update + - MINOR: quic: rename local tid variable + - MINOR: quic: remove unused xprt rcv_buf operation + - MINOR: quic: take out xprt snd_buf operation + - CI: enable QUIC for Coverity scan + - BUG/MINOR: mworker: does not erase the pidfile upon reload + - MINOR: ssl: Remove call to ERR_func_error_string with OpenSSLv3 + - MINOR: ssl: Remove call to ERR_load_SSL_strings with OpenSSLv3 + - REGTESTS: ssl: Add tests for DH related options + - MINOR: ssl: Create HASSL_DH wrapper structure + - MINOR: ssl: Add ssl_sock_get_dh_from_bio helper function + - MINOR: ssl: Factorize ssl_get_tmp_dh and append a cbk to its name + - MINOR: ssl: Add ssl_sock_set_tmp_dh helper function + - MINOR: ssl: Add ssl_sock_set_tmp_dh_from_pkey helper function + - MINOR: ssl: Add ssl_new_dh_fromdata helper function + - MINOR: ssl: Build local DH of right size when needed + - MINOR: ssl: Set default dh size to 2048 + - MEDIUM: ssl: Replace all DH objects by EVP_PKEY on OpenSSLv3 (via HASSL_DH type) + - MINOR: ssl: Remove calls to SSL_CTX_set_tmp_dh_callback on OpenSSLv3 + - MINOR: quic: Remove an RX buffer useless lock + - MINOR: quic: Variable used before being checked in ha_quic_add_handshake_data() + - MINOR: quic: EINTR error ignored + - MINOR: quic: Potential overflow expression in qc_parse_frm() + - MINOR: quic: Possible overflow in qpack_get_varint() + - CLEANUP: h3: Unreachable target in h3_uqs_init() + - MINOR: quic: Possible memleak in qc_new_conn() + - MINOR: quic: Useless statement in quic_crypto_data_cpy() + - BUG/MEDIUM: pools: ensure items are always large enough for the pool_cache_item + - BUG/MINOR: pools: always flush pools about to be destroyed + - CLEANUP: pools: don't needlessly set a call mark during refilling of caches + - DEBUG: pools: add extra sanity checks when picking objects from a local cache + - DEBUG: pools: let's add reverse mapping from cache heads to thread and pool + - DEBUG: pools: replace the link pointer with the caller's address on pool_free() + - BUG/MAJOR: sched: prevent rare concurrent wakeup of multi-threaded tasks + - MINOR: quic: use a global dghlrs for each thread + - BUG/MEDIUM: quic: fix crash on CC if mux not present + - MINOR: qpack: fix typo in trace + - BUG/MINOR: quic: fix FIN stream signaling + - BUG/MINOR: h3: fix the header length for QPACK decoding + - MINOR: h3: remove transfer-encoding header + - MINOR: h3: add documentation on h3_decode_qcs + - MINOR: h3: set properly HTX EOM/BODYLESS on HEADERS parsing + - MINOR: mux-quic: implement rcv_buf + - MINOR: mux-quic: set EOS on rcv_buf + - MINOR: h3: set CS_FL_NOT_FIRST + - MINOR: h3: report frames bigger than rx buffer + - MINOR: h3: extract HEADERS parsing in a dedicated function + - MINOR: h3: implement DATA parsing + - MINOR: quic: Wrong smoothed rtt initialization + - MINOR: quic: Wrong loss delay computation + - MINOR: quic: Code never reached in qc_ssl_sess_init() + - MINOR: quic: ha_quic_set_encryption_secrets without server specific code + - MINOR: quic: Avoid warning about NULL pointer dereferences + - MINOR: quic: Useless test in quic_lstnr_dghdlr() + - MINOR: quic: Non checked returned value for cs_new() in hq_interop_decode_qcs() + - MINOR: h3: Dead code in h3_uqs_init() + - MINOR: quic: Non checked returned value for cs_new() in h3_decode_qcs() + - MINOR: quic: Possible frame parsers array overrun + - MINOR: quic: Do not retransmit too much packets. + - MINOR: quic: Move quic_rxbuf_pool pool out of xprt part + - MINOR: h3: report error on HEADERS/DATA parsing + - BUG/MINOR: jwt: Double free in deinit function + - BUG/MINOR: jwt: Missing pkey free during cleanup + - BUG/MINOR: jwt: Memory leak if same key is used in multiple jwt_verify calls + - BUG/MINOR: httpclient/cli: display junk characters in vsn + - MINOR: h3: remove unused return value on decode_qcs + - BUG/MAJOR: http/htx: prevent unbounded loop in http_manage_server_side_cookies + - BUG/MAJOR: spoe: properly detach all agents when releasing the applet + - REGTESTS: server: close an occasional race on dynamic_server_ssl.vtc + - REGTESTS: peers: leave a bit more time to peers to synchronize + - BUG/MEDIUM: h2/hpack: fix emission of HPACK DTSU after settings change + - BUG/MINOR: mux-h2: update the session's idle delay before creating the stream + - BUG/MINOR: httpclient: reinit flags in httpclient_start() + - BUG/MINOR: mailers: negotiate SMTP, not ESMTP + - MINOR: httpclient: sets an alternative destination + - MINOR: httpclient/lua: add 'dst' optionnal field + - BUG/MINOR: ssl: Add missing return value check in ssl_ocsp_response_print + - BUG/MINOR: ssl: Fix leak in "show ssl ocsp-response" CLI command + - BUG/MINOR: ssl: Missing return value check in ssl_ocsp_response_print + - CLEANUP: httpclient/cli: fix indentation alignment of the help message + - BUG/MINOR: tools: url2sa reads ipv4 too far + - BUG/MEDIUM: httpclient: limit transfers to the maximum available room + - DEBUG: buffer: check in __b_put_blk() whether the buffer room is respected + - MINOR: mux-quic: fix a possible null dereference in qc_timeout_task + - BUG/MEDIUM: htx: Be sure to have a buffer to perform a raw copy of a message + - BUG/MEDIUM: mux-h1: Don't wake h1s if mux is blocked on lack of output buffer + - BUG/MAJOR: mux-h2: Be sure to always report HTX parsing error to the app layer + - DEBUG: stream-int: Check CS_FL_WANT_ROOM is not set with an empty input buffer + - MINOR: quic: do not modify offset node if quic_rx_strm_frm in tree + - MINOR: h3: fix compiler warning variable set but not used + - MINOR: mux-quic: fix uninitialized return on qc_send + - MINOR: quic: fix handling of out-of-order received STREAM frames + - MINOR: pools: mark most static pool configuration variables as read-mostly + - CLEANUP: pools: remove the now unused pool_is_crowded() + - REGTESTS: fix the race conditions in 40be_2srv_odd_health_checks + - BUG/MEDIUM: stream: Abort processing if response buffer allocation fails + - MINOR: httpclient/lua: ability to set a server timeout + - BUG/MINOR: httpclient/lua: missing pop for new timeout parameter + - DOC: httpclient/lua: fix the type of the dst parameter + - CLEANUP: httpclient: initialize the client in stage INIT not REGISTER + - CLEANUP: muxes: do not use a dynamic trash in list_mux_protos() + - CLEANUP: vars: move the per-process variables initialization to vars.c + - CLEANUP: init: remove the ifdef on HAPROXY_MEMMAX + - MINOR: pools: disable redundant poisonning on pool_free() + - MINOR: pools: introduce a new pool_debugging global variable + - MINOR: pools: switch the fail-alloc test to runtime only + - MINOR: pools: switch DEBUG_DONT_SHARE_POOLS to runtime + - MINOR: pools: add a new debugging flag POOL_DBG_COLD_FIRST + - MINOR: pools: add a new debugging flag POOL_DBG_INTEGRITY + - MINOR: pools: make the global pools a runtime option. + - MEDIUM: pools: replace CONFIG_HAP_POOLS with a runtime "NO_CACHE" flag. + - MINOR: pools: store the allocated size for each pool + - MINOR: pools: get rid of POOL_EXTRA + - MINOR: pools: replace DEBUG_POOL_TRACING with runtime POOL_DBG_CALLER + - MINOR: pools: replace DEBUG_MEMORY_POOLS with runtime POOL_DBG_TAG + - MINOR: pools: add a debugging flag for memory poisonning option + - MEDIUM: initcall: move STG_REGISTER earlier + - MEDIUM: init: split the early initialization in its own function + - MINOR: init: extract args parsing to their own function + - MEDIUM: init: handle arguments earlier + - MINOR: pools: delegate parsing of command line option -dM to a new function + - MINOR: pools: support setting debugging options using -dM + - BUILD: makefile: enable both DEBUG_STRICT and DEBUG_MEMORY_POOLS by default + - CI: github: enable pool debugging by default + - DOC: Fix usage/examples of deprecated ACLs + - DOC: internal: update the pools API to mention boot-time settings + - DOC: design: add design thoughts for later simplification of the pools + - DOC: design: commit the temporary design notes on thread groups + - MINOR: stream-int: Handle appctx case first when releasing the endpoint + - MINOR: connection: Be prepared to handle conn-stream with no connection + - MINOR: stream: Handle appctx case first when creating a new stream + - MINOR: connection: Add a function to detach a conn-stream from the connection + - MINOR: stream-int: Add function to reset a SI endpoint + - MINOR: stream-int: Add function to attach a connection to a SI + - MINOR: stream-int: Be able to allocate a CS without connection + - MEDIUM: stream: No longer release backend conn-stream on connection retry + - MEDIUM: stream: Allocate backend CS when the stream is created + - REORG: conn_stream: move conn-stream stuff in dedicated files + - MEDIUM: conn-stream: No longer access connection field directly + - MEDIUM: conn-stream: Be prepared to use an appctx as conn-stream endpoint + - MAJOR: conn_stream/stream-int: move the appctx to the conn-stream + - MEDIUM: applet: Set the conn-stream as appctx owner instead of the stream-int + - MEDIUM: conn_stream: Add a pointer to the app object into the conn-stream + - MINOR: stream: Add pointer to front/back conn-streams into stream struct + - MINOR: stream: Slightly rework stream_new to separate CS/SI initialization + - MINOR: stream-int: Always access the stream-int via the conn-stream + - MINOR: backend: Always access the stream-int via the conn-stream + - MINOR: stream: Always access the stream-int via the conn-stream + - MINOR: http-ana: Always access the stream-int via the conn-stream + - MINOR: cli: Always access the stream-int via the conn-stream + - MINOR: log: Always access the stream-int via the conn-stream + - MINOR: frontend: Always access the stream-int via the conn-stream + - MINOR: proxy: Always access the stream-int via the conn-stream + - MINOR: peers: Always access the stream-int via the conn-stream + - MINOR: debug: Always access the stream-int via the conn-stream + - MINOR: hlua: Always access the stream-int via the conn-stream + - MINOR: cache: Always access the stream-int via the conn-stream + - MINOR: dns: Always access the stream-int via the conn-stream + - MINOR: http-act: Always access the stream-int via the conn-stream + - MINOR: httpclient: Always access the stream-int via the conn-stream + - MINOR: tcp-act: Always access the stream-int via the conn-stream + - MINOR: sink: Always access the stream-int via the conn-stream + - MINOR: conn-stream: Rename cs_detach() to cs_detach_endp() + - CLEANUP: conn-stream: Don't export conn-stream pool + - MAJOR: stream/conn_stream: Move the stream-interface into the conn-stream + - CLEANUP: stream-int: rename si_reset() to si_init() + - MINOR: conn-stream: Release a CS when both app and endp are detached + - MINOR: stream: Don't destroy conn-streams but detach app and endp + - MAJOR: check: Use a persistent conn-stream for health-checks + - CLEANUP: conn-stream: Remove cs_destroy() + - CLEANUP: backend: Don't export connect_server anymore + - BUG/MINOR: h3/hq_interop: Fix CS and stream creation + - BUILD: tree-wide: Avoid warnings about undefined entities retrieved from a CS + - BUG/MINOR: proxy: preset the error message pointer to NULL in parse_new_proxy() + - BUG/MEDIUM: quic: fix received ACK stream calculation + - BUILD: stream: fix build warning with older compilers + - BUG/MINOR: debug: fix get_tainted() to properly read an atomic value + - DEBUG: move the tainted stuff to bug.h for easier inclusion + - DEBUG: cleanup back trace generation + - DEBUG: cleanup BUG_ON() configuration + - DEBUG: mark ABORT_NOW() as unreachable + - DBEUG: add a new WARN_ON() macro + - DEBUG: make the _BUG_ON() macro return the condition + - DEBUG: add a new WARN_ON_ONCE() macro + - DEBUG: report BUG_ON() and WARN_ON() in the tainted flags + - MINOR: quic: adjust buffer handling for STREAM transmission + - MINOR: quic: liberate the TX stream buffer after ACK processing + - MINOR: quic: add a TODO for a memleak frame on ACK consume + +2022/02/01 : 2.6-dev1 + - BUG/MINOR: cache: Fix loop on cache entries in "show cache" + - BUG/MINOR: httpclient: allow to replace the host header + - BUG/MINOR: lua: don't expose internal proxies + - MEDIUM: mworker: seamless reload use the internal sockpairs + - BUG/MINOR: lua: remove loop initial declarations + - BUG/MINOR: mworker: does not add the -sf in wait mode + - BUG/MEDIUM: mworker: FD leak of the eventpoll in wait mode + - MINOR: quic: do not reject PADDING followed by other frames + - REORG: quic: add comment on rare thread concurrence during CID alloc + - CLEANUP: quic: add comments on CID code + - MEDIUM: quic: handle CIDs to rattach received packets to connection + - MINOR: qpack: support litteral field line with non-huff name + - MINOR: quic: activate QUIC traces at compilation + - MINOR: quic: use more verbose QUIC traces set at compile-time + - MEDIUM: pool: refactor malloc_trim/glibc and jemalloc api addition detections. + - MEDIUM: pool: support purging jemalloc arenas in trim_all_pools() + - BUG/MINOR: mworker: deinit of thread poller was called when not initialized + - BUILD: pools: only detect link-time jemalloc on ELF platforms + - CI: github actions: add the output of $CC -dM -E- + - BUG/MEDIUM: cli: Properly set stream analyzers to process one command at a time + - BUILD: evports: remove a leftover from the dead_fd cleanup + - MINOR: quic: Set "no_application_protocol" alert + - MINOR: quic: More accurate immediately close. + - MINOR: quic: Immediately close if no transport parameters extension found + - MINOR: quic: Rename qc_prep_hdshk_pkts() to qc_prep_pkts() + - MINOR: quic: Possible crash when inspecting the xprt context + - MINOR: quic: Dynamically allocate the secrete keys + - MINOR: quic: Add a function to derive the key update secrets + - MINOR: quic: Add structures to maintain key phase information + - MINOR: quic: Optional header protection key for quic_tls_derive_keys() + - MINOR: quic: Add quic_tls_key_update() function for Key Update + - MINOR: quic: Enable the Key Update process + - MINOR: quic: Delete the ODCIDs asap + - BUG/MINOR: vars: Fix the set-var and unset-var converters + - MEDIUM: pool: Following up on previous pool trimming update. + - BUG/MEDIUM: mux-h1: Fix splicing by properly detecting end of message + - BUG/MINOR: mux-h1: Fix splicing for messages with unknown length + - MINOR: mux-h1: Improve H1 traces by adding info about http parsers + - MINOR: mux-h1: register a stats module + - MINOR: mux-h1: add counters instance to h1c + - MINOR: mux-h1: count open connections/streams on stats + - MINOR: mux-h1: add stat for total count of connections/streams + - MINOR: mux-h1: add stat for total amount of bytes received and sent + - REGTESTS: h1: Add a script to validate H1 splicing support + - BUG/MINOR: server: Don't rely on last default-server to init server SSL context + - BUG/MEDIUM: resolvers: Detach query item on response error + - MEDIUM: resolvers: No longer store query items in a list into the response + - BUG/MAJOR: segfault using multiple log forward sections. + - BUG/MEDIUM: h1: Properly reset h1m flags when headers parsing is restarted + - BUG/MINOR: resolvers: Don't overwrite the error for invalid query domain name + - BUILD: bug: Fix error when compiling with -DDEBUG_STRICT_NOCRASH + - BUG/MEDIUM: sample: Fix memory leak in sample_conv_jwt_member_query + - DOC: spoe: Clarify use of the event directive in spoe-message section + - DOC: config: Specify %Ta is only available in HTTP mode + - BUILD: tree-wide: avoid warnings caused by redundant checks of obj_types + - IMPORT: slz: use the correct CRC32 instruction when running in 32-bit mode + - MINOR: quic: fix segfault on CONNECTION_CLOSE parsing + - MINOR: h3: add BUG_ON on control receive function + - MEDIUM: xprt-quic: finalize app layer initialization after ALPN nego + - MINOR: h3: remove duplicated FIN flag position + - MAJOR: mux-quic: implement a simplified mux version + - MEDIUM: mux-quic: implement release mux operation + - MEDIUM: quic: detect the stream FIN + - MINOR: mux-quic: implement subscribe on stream + - MEDIUM: mux-quic: subscribe on xprt if remaining data after send + - MEDIUM: mux-quic: wake up xprt on data transferred + - MEDIUM: mux-quic: handle when sending buffer is full + - MINOR: quic: RX buffer full due to wrong CRYPTO data handling + - MINOR: quic: Race issue when consuming RX packets buffer + - MINOR: quic: QUIC encryption level RX packets race issue + - MINOR: quic: Delete remaining RX handshake packets + - MINOR: quic: Remove QUIC TX packet length evaluation function + - MINOR: hq-interop: fix tx buffering + - MINOR: mux-quic: remove uneeded code to check fin on TX + - MINOR: quic: add HTX EOM on request end + - BUILD: mux-quic: fix compilation with DEBUG_MEM_STATS + - MINOR: http-rules: Add capture action to http-after-response ruleset + - BUG/MINOR: cli/server: Don't crash when a server is added with a custom id + - MINOR: mux-quic: do not release qcs if there is remaining data to send + - MINOR: quic: notify the mux on CONNECTION_CLOSE + - BUG/MINOR: mux-quic: properly initialize flow control + - MINOR: quic: Compilation fix for quic_rx_packet_refinc() + - MINOR: h3: fix possible invalid dereference on htx parsing + - DOC: config: retry-on list is space-delimited + - DOC: config: fix error-log-format example + - BUG/MEDIUM: mworker/cli: crash when trying to access an old PID in prompt mode + - MINOR: hq-interop: refix tx buffering + - REGTESTS: ssl: use X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY for cert check + - MINOR: cli: "show version" displays the current process version + - CLEANUP: cfgparse: modify preprocessor guards around numa detection code + - MEDIUM: cfgparse: numa detect topology on FreeBSD. + - BUILD: ssl: unbreak the build with newer libressl + - MINOR: vars: Move UPDATEONLY flag test to vars_set_ifexist + - MINOR: vars: Set variable type to ANY upon creation + - MINOR: vars: Delay variable content freeing in var_set function + - MINOR: vars: Parse optional conditions passed to the set-var converter + - MINOR: vars: Parse optional conditions passed to the set-var actions + - MEDIUM: vars: Enable optional conditions to set-var converter and actions + - DOC: vars: Add documentation about the set-var conditions + - REGTESTS: vars: Add new test for conditional set-var + - MINOR: quic: Attach timer task to thread for the connection. + - CLEANUP: quic_frame: Remove a useless suffix to STOP_SENDING + - MINOR: quic: Add traces for STOP_SENDING frame and modify others + - CLEANUP: quic: Remove cdata_len from quic_tx_packet struct + - MINOR: quic: Enable TLS 0-RTT if needed + - MINOR: quic: No TX secret at EARLY_DATA encryption level + - MINOR: quic: Add quic_set_app_ops() function + - MINOR: ssl_sock: Set the QUIC application from ssl_sock_advertise_alpn_protos. + - MINOR: quic: Make xprt support 0-RTT. + - MINOR: qpack: Missing check for truncated QPACK fields + - CLEANUP: quic: Comment fix for qc_strm_cpy() + - MINOR: hq_interop: Stop BUG_ON() truncated streams + - MINOR: quic: Do not mix packet number space and connection flags + - CLEANUP: quic: Shorten a litte bit the traces in lstnr_rcv_pkt() + - MINOR: mux-quic: fix trace on stream creation + - CLEANUP: quic: fix spelling mistake in a trace + - CLEANUP: quic: rename quic_conn conn to qc in quic_conn_free + - MINOR: quic: add missing lock on cid tree + - MINOR: quic: rename constant for haproxy CIDs length + - MINOR: quic: refactor concat DCID with address for Initial packets + - MINOR: quic: compare coalesced packets by DCID + - MINOR: quic: refactor DCID lookup + - MINOR: quic: simplify the removal from ODCID tree + - REGTESTS: vars: Remove useless ssl tunes from conditional set-var test + - MINOR: ssl: Remove empty lines from "show ssl ocsp-response" output + - MINOR: quic: Increase the RX buffer for each connection + - MINOR: quic: Add a function to list remaining RX packets by encryption level + - MINOR: quic: Stop emptying the RX buffer asap. + - MINOR: quic: Do not expect to receive only one O-RTT packet + - MINOR: quic: Do not forget STREAM frames received in disorder + - MINOR: quic: Wrong packet refcount handling in qc_pkt_insert() + - DOC: fix misspelled keyword "resolve_retries" in resolvers + - CLEANUP: quic: rename quic_conn instances to qc + - REORG: quic: move mux function outside of xprt + - MINOR: quic: add reference to quic_conn in ssl context + - MINOR: quic: add const qualifier for traces function + - MINOR: trace: add quic_conn argument definition + - MINOR: quic: use quic_conn as argument to traces + - MINOR: quic: add quic_conn instance in traces for qc_new_conn + - MINOR: quic: Add stream IDs to qcs_push_frame() traces + - MINOR: quic: unchecked qc_retrieve_conn_from_cid() returned value + - MINOR: quic: Wrong dropped packet skipping + - MINOR: quic: Handle the cases of overlapping STREAM frames + - MINOR: quic: xprt traces fixes + - MINOR: quic: Drop asap Retry or Version Negotiation packets + - MINOR: pools: work around possibly slow malloc_trim() during gc + - DEBUG: ssl: make sure we never change a servername on established connections + - MINOR: quic: Add traces for RX frames (flow control related) + - MINOR: quic: Add CONNECTION_CLOSE phrase to trace + - REORG: quic: remove qc_ prefix on functions which not used it directly + - BUG/MINOR: quic: upgrade rdlock to wrlock for ODCID removal + - MINOR: quic: remove unnecessary call to free_quic_conn_cids() + - MINOR: quic: store ssl_sock_ctx reference into quic_conn + - MINOR: quic: remove unnecessary if in qc_pkt_may_rm_hp() + - MINOR: quic: replace usage of ssl_sock_ctx by quic_conn + - MINOR: quic: delete timer task on quic_close() + - MEDIUM: quic: implement refcount for quic_conn + - BUG/MINOR: quic: fix potential null dereference + - BUG/MINOR: quic: fix potential use of uninit pointer + - BUG/MEDIUM: backend: fix possible sockaddr leak on redispatch + - BUG/MEDIUM: peers: properly skip conn_cur from incoming messages + - CI: Github Actions: do not show VTest failures if build failed + - BUILD: opentracing: display warning in case of using OT_USE_VARS at compile time + - MINOR: compat: detect support for dl_iterate_phdr() + - MINOR: debug: add ability to dump loaded shared libraries + - MINOR: debug: add support for -dL to dump library names at boot + - BUG/MEDIUM: ssl: initialize correctly ssl w/ default-server + - REGTESTS: ssl: fix ssl_default_server.vtc + - BUG/MINOR: ssl: free the fields in srv->ssl_ctx + - BUG/MEDIUM: ssl: free the ckch instance linked to a server + - REGTESTS: ssl: update of a crt with server deletion + - BUILD/MINOR: cpuset FreeBSD 14 build fix. + - MINOR: pools: always evict oldest objects first in pool_evict_from_local_cache() + - DOC: pool: document the purpose of various structures in the code + - CLEANUP: pools: do not use the extra pointer to link shared elements + - CLEANUP: pools: get rid of the POOL_LINK macro + - MINOR: pool: allocate from the shared cache through the local caches + - CLEANUP: pools: group list updates in pool_get_from_cache() + - MINOR: pool: rely on pool_free_nocache() in pool_put_to_shared_cache() + - MINOR: pool: make pool_is_crowded() always true when no shared pools are used + - MINOR: pool: check for pool's fullness outside of pool_put_to_shared_cache() + - MINOR: pool: introduce pool_item to represent shared pool items + - MINOR: pool: add a function to estimate how many may be released at once + - MEDIUM: pool: compute the number of evictable entries once per pool + - MINOR: pools: prepare pool_item to support chained clusters + - MINOR: pools: pass the objects count to pool_put_to_shared_cache() + - MEDIUM: pools: centralize cache eviction in a common function + - MEDIUM: pools: start to batch eviction from local caches + - MEDIUM: pools: release cached objects in batches + - OPTIM: pools: reduce local pool cache size to 512kB + - CLEANUP: assorted typo fixes in the code and comments This is 29th iteration of typo fixes + - CI: github actions: update OpenSSL to 3.0.1 + - BUILD/MINOR: tools: solaris build fix on dladdr. + - BUG/MINOR: cli: fix _getsocks with musl libc + - BUG/MEDIUM: http-ana: Preserve response's FLT_END analyser on L7 retry + - MINOR: quic: Wrong traces after rework + - MINOR: quic: Add trace about in flight bytes by packet number space + - MINOR: quic: Wrong first packet number space computation + - MINOR: quic: Wrong packet number space computation for PTO + - MINOR: quic: Wrong loss time computation in qc_packet_loss_lookup() + - MINOR: quic: Wrong ack_delay compution before calling quic_loss_srtt_update() + - MINOR: quic: Remove nb_pto_dgrams quic_conn struct member + - MINOR: quic: Wrong packet number space trace in qc_prep_pkts() + - MINOR: quic: Useless test in qc_prep_pkts() + - MINOR: quic: qc_prep_pkts() code moving + - MINOR: quic: Speeding up Handshake Completion + - MINOR: quic: Probe Initial packet number space more often + - MINOR: quic: Probe several packet number space upon timer expiration + - MINOR: quic: Comment fix. + - MINOR: quic: Improve qc_prep_pkts() flexibility + - MINOR: quic: Do not drop secret key but drop the CRYPTO data + - MINOR: quic: Prepare Handshake packets asap after completed handshake + - MINOR: quic: Flag asap the connection having reached the anti-amplification limit + - MINOR: quic: PTO timer too often reset + - MINOR: quic: Re-arm the PTO timer upon datagram receipt + - MINOR: proxy: add option idle-close-on-response + - MINOR: cpuset: switch to sched_setaffinity for FreeBSD 14 and above. + - CI: refactor spelling check + - CLEANUP: assorted typo fixes in the code and comments + - BUILD: makefile: add -Wno-atomic-alignment to work around clang abusive warning + - MINOR: quic: Only one CRYPTO frame by encryption level + - MINOR: quic: Missing retransmission from qc_prep_fast_retrans() + - MINOR: quic: Non-optimal use of a TX buffer + - BUG/MEDIUM: mworker: don't use _getsocks in wait mode + - BUG/MINOR: ssl: Store client SNI in SSL context in case of ClientHello error + - BUG/MAJOR: mux-h1: Don't decrement .curr_len for unsent data + - DOC: internals: document the pools architecture and API + - CI: github actions: clean default step conditions + - BUILD: cpuset: fix build issue on macos introduced by previous change + - MINOR: quic: Remaining TRACEs with connection as firt arg + - MINOR: quic: Reset ->conn quic_conn struct member when calling qc_release() + - MINOR: quic: Flag the connection as being attached to a listener + - MINOR: quic: Wrong CRYPTO frame concatenation + - MINOR: quid: Add traces quic_close() and quic_conn_io_cb() + - REGTESTS: ssl: Fix ssl_errors regtest with OpenSSL 1.0.2 + - MINOR: quic: Do not dereference ->conn quic_conn struct member + - MINOR: quic: fix return of quic_dgram_read + - MINOR: quic: add config parse source file + - MINOR: quic: implement Retry TLS AEAD tag generation + - MEDIUM: quic: implement Initial token parsing + - MINOR: quic: define retry_source_connection_id TP + - MEDIUM: quic: implement Retry emission + - MINOR: quic: free xprt tasklet on its thread + - BUG/MEDIUM: connection: properly leave stopping list on error + - MINOR: pools: enable pools with DEBUG_FAIL_ALLOC as well + - MINOR: quic: As server, skip 0-RTT packet number space + - MINOR: quic: Do not wakeup the I/O handler before the mux is started + - BUG/MEDIUM: htx: Adjust length to add DATA block in an empty HTX buffer + - CI: github actions: use cache for OpenTracing + - BUG/MINOR: httpclient: don't send an empty body + - BUG/MINOR: httpclient: set default Accept and User-Agent headers + - BUG/MINOR: httpclient/lua: don't pop the lua stack when getting headers + - BUILD/MINOR: fix solaris build with clang. + - BUG/MEDIUM: server: avoid changing healthcheck ctx with set server ssl + - CI: refactor OpenTracing build script + - DOC: management: mark "set server ssl" as deprecated + - MEDIUM: cli: yield between each pipelined command + - MINOR: channel: add new function co_getdelim() to support multiple delimiters + - BUG/MINOR: cli: avoid O(bufsize) parsing cost on pipelined commands + - MEDIUM: h2/hpack: emit a Dynamic Table Size Update after settings change + - MINOR: quic: Retransmit the TX frames in the same order + - MINOR: quic: Remove the packet number space TX MT_LIST + - MINOR: quic: Splice the frames which could not be added to packets + - MINOR: quic: Add the number of TX bytes to traces + - CLEANUP: quic: Replace by + - MINOR: quic: Send two ack-eliciting packets when probing packet number spaces + - MINOR: quic: Probe regardless of the congestion control + - MINOR: quic: Speeding up handshake completion + - MINOR: quic: Release RX Initial packets asap + - MINOR: quic: Release asap TX frames to be transmitted + - MINOR: quic: Probe even if coalescing + - BUG/MEDIUM: cli: Never wait for more data on client shutdown + - BUG/MEDIUM: mcli: do not try to parse empty buffers + - BUG/MEDIUM: mcli: always realign wrapping buffers before parsing them + - BUG/MINOR: stream: make the call_rate only count the no-progress calls + - MINOR: quic: do not use quic_conn after dropping it + - MINOR: quic: adjust quic_conn refcount decrement + - MINOR: quic: fix race-condition on xprt tasklet free + - MINOR: quic: free SSL context on quic_conn free + - MINOR: quic: Add QUIC_FT_RETIRE_CONNECTION_ID parsing case + - MINOR: quic: Wrong packet number space selection + - DEBUG: pools: add new build option DEBUG_POOL_INTEGRITY + - MINOR: quic: add missing include in quic_sock + - MINOR: quic: fix indentation in qc_send_ppkts + - MINOR: quic: remove dereferencement of connection when possible + - MINOR: quic: set listener accept cb on parsing + - MEDIUM: quic/ssl: add new ex data for quic_conn + - MINOR: quic: initialize ssl_sock_ctx alongside the quic_conn + - MINOR: ssl: fix build in release mode + - MINOR: pools: partially uninline pool_free() + - MINOR: pools: partially uninline pool_alloc() + - MINOR: pools: prepare POOL_EXTRA to be split into multiple extra fields + - MINOR: pools: extend pool_cache API to pass a pointer to a caller + - DEBUG: pools: add new build option DEBUG_POOL_TRACING + - DEBUG: cli: add a new "debug dev fd" expert command + - MINOR: fd: register the write side of the poller pipe as well + - CI: github actions: use cache for SSL libs + - BUILD: debug/cli: condition test of O_ASYNC to its existence + - BUILD: pools: fix build error on DEBUG_POOL_TRACING + - MINOR: quic: refactor header protection removal + - MINOR: quic: handle app data according to mux/connection layer status + - MINOR: quic: refactor app-ops initialization + - MINOR: receiver: define a flag for local accept + - MEDIUM: quic: flag listener for local accept + - MINOR: quic: do not manage connection in xprt snd_buf + - MINOR: quic: remove wait handshake/L6 flags on init connection + - MINOR: listener: add flags field + - MINOR: quic: define QUIC flag on listener + - MINOR: quic: create accept queue for QUIC connections + - MINOR: listener: define per-thr struct + - MAJOR: quic: implement accept queue + - CLEANUP: mworker: simplify mworker_free_child() + - BUILD/DEBUG: lru: update the standalone code to support the revision + - DEBUG: lru: use a xorshift generator in the testing code + - BUG/MAJOR: compiler: relax alignment constraints on certain structures + - BUG/MEDIUM: fd: always align fdtab[] to 64 bytes + - MINOR: quic: No DCID length for datagram context + - MINOR: quic: Comment fix about the token found in Initial packets + - MINOR: quic: Get rid of a struct buffer in quic_lstnr_dgram_read() + - MINOR: quic: Remove the QUIC haproxy server packet parser + - MINOR: quic: Add new defintion about DCIDs offsets + - MINOR: quic: Add a list to QUIC sock I/O handler RX buffer + - MINOR: quic: Allocate QUIC datagrams from sock I/O handler + - MINOR: proto_quic: Allocate datagram handlers + - MINOR: quic: Pass CID as a buffer to quic_get_cid_tid() + - MINOR: quic: Convert quic_dgram_read() into a task + - CLEANUP: quic: Remove useless definition + - MINOR: proto_quic: Wrong allocations for TX rings and RX bufs + - MINOR: quic: Do not consume the RX buffer on QUIC sock i/o handler side + - MINOR: quic: Do not reset a full RX buffer + - MINOR: quic: Attach all the CIDs to the same connection + - MINOR: quic: Make usage of by datagram handler trees + - MEDIUM: da: new optional data file download scheduler service. + - MEDIUM: da: update doc and build for new scheduler mode service. + - MEDIUM: da: update module to handle schedule mode. + - MINOR: quic: Drop Initial packets with wrong ODCID + - MINOR: quic: Wrong RX buffer tail handling when no more contiguous data + - MINOR: quic: Iterate over all received datagrams + - MINOR: quic: refactor quic CID association with threads + - BUG/MEDIUM: resolvers: Really ignore trailing dot in domain names + - DEV: flags: Add missing flags + - BUG/MINOR: sink: Use the right field in appctx context in release callback + - MINOR: sock: move the unused socket cleaning code into its own function + - BUG/MEDIUM: mworker: close unused transferred FDs on load failure + - BUILD: atomic: make the old HA_ATOMIC_LOAD() support const pointers + - BUILD: cpuset: do not use const on the source of CPU_AND/CPU_ASSIGN + - BUILD: checks: fix inlining issue on set_srv_agent_[addr,port} + - BUILD: vars: avoid overlapping field initialization + - BUILD: server-state: avoid using not-so-portable isblank() + - BUILD: mux_fcgi: avoid aliasing of a const struct in traces + - BUILD: tree-wide: mark a few numeric constants as explicitly long long + - BUILD: tools: fix warning about incorrect cast with dladdr1() + - BUILD: task: use list_to_mt_list() instead of casting list to mt_list + - BUILD: mworker: include tools.h for platforms without unsetenv() + - BUG/MINOR: mworker: fix a FD leak of a sockpair upon a failed reload + - MINOR: mworker: set the master side of ipc_fd in the worker to -1 + - MINOR: mworker: allocate and initialize a mworker_proc + - CI: Consistently use actions/checkout@v2 + - REGTESTS: Remove REQUIRE_VERSION=1.8 from all tests + - MINOR: mworker: sets used or closed worker FDs to -1 + - MINOR: quic: Try to accept 0-RTT connections + - MINOR: quic: Do not try to treat 0-RTT packets without started mux + - MINOR: quic: Do not try to accept a connection more than one time + - MINOR: quic: Initialize the connection timer asap + - MINOR: quic: Do not use connection struct xprt_ctx too soon + - Revert "MINOR: mworker: sets used or closed worker FDs to -1" + - BUILD: makefile: avoid testing all -Wno-* options when not needed + - BUILD: makefile: validate support for extra warnings by batches + - BUILD: makefile: only compute alternative options if required + - DEBUG: fd: make sure we never try to insert/delete an impossible FD number + - MINOR: mux-quic: add comment + - MINOR: mux-quic: properly initialize qcc flags + - MINOR: mux-quic: do not consider CONNECTION_CLOSE for the moment + - MINOR: mux-quic: create a timeout task + - MEDIUM: mux-quic: delay the closing with the timeout + - MINOR: mux-quic: release idle conns on process stopping + - MINOR: listener: replace the listener's spinlock with an rwlock + - BUG/MEDIUM: listener: read-lock the listener during accept() + - MINOR: mworker/cli: set expert/experimental mode from the CLI + +2021/11/23 : 2.6-dev0 + - MINOR: version: it's development again + +2021/11/23 : 2.5.0 + - BUILD: SSL: add quictls build to scripts/build-ssl.sh + - BUILD: SSL: add QUICTLS to build matrix + - CLEANUP: sock: Wrap `accept4_broken = 1` into additional parenthesis + - BUILD: cli: clear a maybe-unused warning on some older compilers + - BUG/MEDIUM: cli: make sure we can report a warning from a bind keyword + - BUG/MINOR: ssl: make SSL counters atomic + - CLEANUP: assorted typo fixes in the code and comments + - BUG/MINOR: ssl: free correctly the sni in the backend SSL cache + - MINOR: version: mention that it's stable now + +2021/11/19 : 2.5-dev15 + - BUG/MINOR: stick-table/cli: Check for invalid ipv6 key + - CLEANUP: peers: Remove useless test on peer variable in peer_trace() + - DOC: log: Add comments to specify when session's listener is defined or not + - BUG/MEDIUM: mux-h1: Handle delayed silent shut in h1_process() to release H1C + - REGTESTS: ssl_crt-list_filters: feature cmd incorrectly set + - DOC: internals: document the list API + - BUG/MINOR: h3: ignore unknown frame types + - MINOR: quic: redirect app_ops snd_buf through mux + - MEDIUM: quic: inspect ALPN to install app_ops + - MINOR: quic: support hq-interop + - MEDIUM: quic: send version negotiation packet on unknown version + - BUG/MEDIUM: mworker: cleanup the listeners when reexecuting + - DOC: internals: document the scheduler API + - BUG/MINOR: quic: fix version negotiation packet generation + - CLEANUP: ssl: fix wrong #else commentary + - MINOR: config: support default values for environment variables + - SCRIPTS: run-regtests: reduce the number of processes needed to check options + - SCRIPT: run-regtests: avoid several calls to grep to test for features + - SCRIPT: run-regtests: avoid calling awk to compute the version + - REGTEST: set retries count to zero for all tests that expect at 503 + - REGTESTS: make tcp-check_min-recv fail fast + - REGTESTS: extend the default I/O timeouts and make them overridable + - BUG/MEDIUM: ssl: backend TLS resumption with sni and TLSv1.3 + - BUG/MEDIUM: ssl: abort with the correct SSL error when SNI not found + - REGTESTS: ssl: test the TLS resumption + - BUILD: makefile: stop opening sub-shells for each and every command + - BUILD: makefile: reorder objects by build time + - BUG/MEDIUM: mux-h2: always process a pending shut read + - MINOR: quic_sock: missing CO_FL_ADDR_TO_SET flag + - MINOR: quic: Possible wrong connection identification + - MINOR: quic: Correctly pad UDP datagrams + - MINOR: quic: Support transport parameters draft TLS extension + - MINOR: quic: Anti-amplification implementation + - MINOR: quic: Wrong Initial packet connection initialization + - MINOR: quic: Wrong ACK range building + - MINOR: quic: Update some QUIC protocol errors + - MINOR: quic: Send CONNECTION_CLOSE frame upon TLS alert + - MINOR: quic: Wrong largest acked packet number parsing + - MINOR: quic: Add minimalistic support for stream flow control frames + - MINOR: quic: Wrong value for version negotiation packet 'Unused' field + - MINOR: quic: Support draft-29 QUIC version + - BUG/MINOR: quic: fix segfault on trace for version negotiation + - BUG/MINOR: hq-interop: fix potential NULL dereference + - BUILD: quic: fix potential NULL dereference on xprt_quic + - DOC: lua: documentation about the httpclient API + - BUG/MEDIUM: cache/cli: make "show cache" thread-safe + - BUG/MEDIUM: shctx: leave the block allocator when enough blocks are found + - BUG/MINOR: shctx: do not look for available blocks when the first one is enough + - MINOR: shctx: add a few BUG_ON() for consistency checks + +2021/11/14 : 2.5-dev14 + - DEV: coccinelle: Remove unused `expression e` + - DEV: coccinelle: Add rule to use `istend()` where possible + - CLEANUP: Apply ist.cocci + - CLEANUP: Re-apply xalloc_size.cocci + - CLEANUP: halog: make the default usage message fit in small screens + - MINOR: h3/qpack: fix gcc11 warnings + - MINOR: mux-quic: fix gcc11 warning + - MINOR: h3: fix potential NULL dereference + - MINOR: quic: Fix potential null pointer dereference + - CLEANUP: halog: remove unused strl2ui() + - OPTIM: halog: improve field parser speed for modern compilers + - OPTIM: halog: skip fields 64 bits at a time when supported + - DEV: coccinelle: Add rule to use `isttrim()` where possible + - CLEANUP: Apply ist.cocci + - DEV: coccinelle: Add rule to use `chunk_istcat()` instead of `chunk_memcat()` + - DEV: coccinelle: Add rule to use `chunk_istcat()` instead of `chunk_strncat()` + - CLEANUP: Apply ist.cocci + - CLEANUP: chunk: Remove duplicated chunk_Xcat implementation + - CLEANUP: chunk: remove misleading chunk_strncat() function + - BUG/MINOR: cache: properly ignore unparsable max-age in quotes + - Revert "DEV: coccinelle: Add rule to use `chunk_istcat()` instead of `chunk_strncat()`" + - DOC: stats: fix location of the text representation + - DOC: internals: document the IST API + - BUG/MINOR: httpclient/lua: rcv freeze when no request payload + - BUG/MEDIUM: httpclient: channel_add_input() must use htx->data + - MINOR: promex: backend aggregated server check status + - DOC: config: Fix typo in ssl_fc_unique_id description + - BUG/MINOR: http-ana: Apply stop to the current section for http-response rules + - Revert "BUG/MINOR: http-ana: Don't eval front after-response rules if stopped on back" + - DOC: config: Be more explicit in "allow" actions description + - DOC: lua: Be explicit with the Reply object limits + - MINOR: mux-h1: Slightly Improve H1 traces + - BUG/MEDIUM: conn-stream: Don't reset CS flags on close + - CLEANUP: mworker: remove any relative PID reference + - MEDIUM: mworker: reexec in waitpid mode after successful loading + - MINOR: mworker: clarify starting/failure messages + - MINOR: mworker: only increment the number of reload in wait mode + - MINOR: mworker: implement a reload failure counter + - MINOR: mworker: ReloadFailed shown depending on failedreload + - MINOR: mworker: change the way we set PROC_O_LEAVING + - BUG/MINOR: mworker: doesn't launch the program postparser + - DOC: management: edit the "show proc" example to show the current output + - BUG/MEDIUM: httpclient/cli: free of unallocated hc->req.uri + - REGTESTS: httpclient/lua: add greater body values + - BUG/MINOR: mux-h2: Fix H2_CF_DEM_SHORT_READ value + - BUG/MINOR: pools: don't mark ourselves as harmless in DEBUG_UAF mode + - BUG/MEDIUM: connection: make cs_shutr/cs_shutw//cs_close() idempotent + - BUILD: makefile: simplify detection of libatomic + +2021/11/06 : 2.5-dev13 + - SCRIPTS: git-show-backports: re-enable file-based filtering + - MINOR: jwt: Make invalid static JWT algorithms an error in `jwt_verify` converter + - MINOR: mux-h2: add trace on extended connect usage + - BUG/MEDIUM: mux-h2: reject upgrade if no RFC8441 support + - MINOR: stream/mux: implement websocket stream flag + - MINOR: connection: implement function to update ALPN + - MINOR: connection: add alternative mux_ops param for conn_install_mux_be + - MEDIUM: server/backend: implement websocket protocol selection + - MINOR: server: add ws keyword + - BUG/MINOR: resolvers: fix sent messages were counted twice + - BUG/MINOR: resolvers: throw log message if trash not large enough for query + - MINOR: resolvers/dns: split dns and resolver counters in dns_counter struct + - MEDIUM: resolvers: rename dns extra counters to resolvers extra counters + - BUG/MINOR: jwt: Fix jwt_parse_alg incorrectly returning JWS_ALG_NONE + - DOC: add QUIC instruction in INSTALL + - CLEANUP: halog: Remove dead stores + - DEV: coccinelle: Add ha_free.cocci + - CLEANUP: Apply ha_free.cocci + - DEV: coccinelle: Add rule to use `istnext()` where possible + - CLEANUP: Apply ist.cocci + - REGTESTS: Use `feature cmd` for 2.5+ tests (2) + - DOC: internals: move some API definitions to an "api" subdirectory + - MINOR: quic: Allocate listener RX buffers + - CLEANUP: quic: Remove useless code + - MINOR: quic: Enhance the listener RX buffering part + - MINOR: quic: Remove a useless lock for CRYPTO frames + - MINOR: quic: Use QUIC_LOCK QUIC specific lock label. + - MINOR: backend: Get client dst address to set the server's one only if needful + - MINOR: compression: Warn for 'compression offload' in defaults sections + - MEDIUM: connection: rename fc_conn_err and bc_conn_err to fc_err and bc_err + - DOC: configuration: move the default log formats to their own section + - MINOR: ssl: make the ssl_fc_sni() sample-fetch function always available + - MEDIUM: log: add the client's SNI to the default HTTPS log format + - DOC: config: add an example of reasonably complete error-log-format + - DOC: config: move error-log-format before custom log format + +2021/11/02 : 2.5-dev12 + - MINOR: httpclient: support payload within a buffer + - MINOR: httpclient/lua: support more HTTP methods + - MINOR: httpclient/lua: return an error when it can't generate the request + - CLEANUP: lua: Remove any ambiguities about lua txn execution context flags + - BUG/MEDIUM: lua: fix invalid return types in hlua_http_msg_get_body + - CLEANUP: connection: No longer export make_proxy_line_v1/v2 functions + - CLEANUP: tools: Use const address for get_net_port() and get_host_port() + - CLEANUP: lua: Use a const address to retrieve info about a connection + - MINOR: connection: Add function to get src/dst without updating the connection + - MINOR: session: Add src and dst addresses to the session + - MINOR: stream-int: Add src and dst addresses to the stream-interface + - MINOR: frontend: Rely on client src and dst addresses at stream level + - MINOR: log: Rely on client addresses at the appropriate level to log messages + - MINOR: session: Rely on client source address at session level to log error + - MINOR: http-ana: Rely on addresses at stream level to set xff and xot headers + - MINOR: http-fetch: Rely on addresses at stream level in HTTP sample fetches + - MINOR: mux-fcgi: Rely on client addresses at stream level to set default params + - MEDIUM: tcp-sample: Rely on addresses at the appropriate level in tcp samples + - MEDIUM: connection: Rely on addresses at stream level to make proxy line + - MEDIUM: backend: Rely on addresses at stream level to init server connection + - MEDIUM: connection: Assign session addresses when PROXY line is received + - MEDIUM: connection: Assign session addresses when NetScaler CIP proto is parsed + - MEDIUM: tcp-act: Set addresses at the apprioriate level in set-(src/dst) actions + - MINOR: tcp-act: Add set-src/set-src-port for "tcp-request content" rules + - DOC: config: Fix alphabetical order of fc_* samples + - MINOR: tcp-sample: Add samples to get original info about client connection + - REGTESTS: Add script to test client src/dst manipulation at different levels + - MINOR: stream: Use backend stream-interface dst address instead of target_addr + - BUILD: log: Fix compilation without SSL support + - DEBUG: protocol: yell loudly during registration of invalid sock_domain + - MINOR: protocols: add a new protocol type selector + - MINOR: protocols: make use of the protocol type to select the protocol + - MINOR: protocols: replace protocol_by_family() with protocol_lookup() + - MINOR: halog: Add -qry parameter allowing to preserve the query string in -uX + - CLEANUP: jwt: Remove the use of a trash buffer in jwt_jwsverify_hmac() + - CLEANUP: jwt: Remove the use of a trash buffer in jwt_jwsverify_rsa_ecdsa() + - DEV: coccinelle: Add realloc_leak.cocci + - CLEANUP: hlua: Remove obsolete branch in `hlua_alloc()` + - BUILD: atomic: prefer __atomic_compare_exchange_n() for __ha_cas_dw() + - BUILD: atomic: fix build on mac/arm64 + - MINOR: atomic: remove the memcpy() call and dependency on string.h + - MINOR: httpclient: request streaming with a callback + - MINOR: httpclient/lua: handle the streaming into the lua applet + - REGTESTS: lua: test httpclient with body streaming + - DOC: halog: Move the `-qry` parameter into the correct section in help text + - MINOR: halog: Rename -qry to -query + - CLEANUP: halog: Use consistent indentation in help() + - BUG/MINOR: halog: Add missing newlines in die() messages + - MINOR: halog: Add support for extracting captures using -hdr + - DOC: Typo fixed "it" should be "is" + - BUG/MINOR: mux-h1: Save shutdown mode if the shutdown is delayed + - BUG/MEDIUM: mux-h1: Perform a connection shutdown when the h1c is released + - BUG/MEDIUM: resolvers: Don't recursively perform requester unlink + - BUG/MEDIUM: http-ana: Drain request data waiting the tarpit timeout expiration + - BUG/MINOR: http: Authorization value can have multiple spaces after the scheme + - BUG/MINOR: http: http_auth_bearer fetch does not work on custom header name + - BUG/MINOR: httpclient/lua: misplaced luaL_buffinit() + - BUILD/MINOR: cpuset freebsd build fix + - BUG/MINOR: httpclient: use a placeholder value for Host header + - BUG/MEDIUM: stream-int: Block reads if channel cannot receive more data + - BUG/MEDIUM: resolvers: Track api calls with a counter to free resolutions + - MINOR: stream: Improve dump of bogus streams + - DOC/peers: some grammar fixes for peers 2.1 spec + - MEDIUM: vars: make the var() sample fetch function really return type ANY + - MINOR: vars: add "set-var" for "tcp-request connection" rules. + +2021/10/22 : 2.5-dev11 + - DEV: coccinelle: Add strcmp.cocci + - CLEANUP: Apply strcmp.cocci + - CI: Add `permissions` to GitHub Actions + - CI: Clean up formatting in GitHub Action definitions + - MINOR: add ::1 to predefined LOCALHOST acl + - CLEANUP: assorted typo fixes in the code and comments + - CLEANUP: Consistently `unsigned int` for bitfields + - MEDIUM: resolvers: lower-case labels when converting from/to DNS names + - MEDIUM: resolvers: replace bogus resolv_hostname_cmp() with memcmp() + - MINOR: jwt: Empty the certificate tree during deinit + - MINOR: jwt: jwt_verify returns negative values in case of error + - MINOR: jwt: Do not rely on enum order anymore + - BUG/MEDIUM: stream: Keep FLT_END analyzers if a stream detects a channel error + - MINOR: httpclient/cli: access should be only done from expert mode + - DOC: management: doc about the CLI httpclient + - BUG/MEDIUM: tcpcheck: Properly catch early HTTP parsing errors + - BUG/MAJOR: dns: tcp session can remain attached to a list after a free + - BUG/MAJOR: dns: attempt to lock globaly for msg waiter list instead of use barrier + - CLEANUP: dns: always detach the appctx from the dns session on release + - DEBUG: dns: add a few more BUG_ON at sensitive places + - BUG/MAJOR: resolvers: add other missing references during resolution removal + - CLEANUP: resolvers: do not export resolv_purge_resolution_answer_records() + - BUILD: resolvers: avoid a possible warning on null-deref + - BUG/MEDIUM: resolvers: always check a valid item in query_list + - CLEANUP: always initialize the answer_list + - CLEANUP: resolvers: simplify resolv_link_resolution() regarding requesters + - CLEANUP: resolvers: replace all LIST_DELETE with LIST_DEL_INIT + - MEDIUM: resolvers: use a kill list to preserve the list consistency + - MEDIUM: resolvers: remove the last occurrences of the "safe" argument + - BUG/MEDIUM: checks: fix the starting thread for external checks + - MEDIUM: resolvers: replace the answer_list with a (flat) tree + - MEDIUM: resolvers: hash the records before inserting them into the tree + - BUG/MAJOR: buf: fix varint API post- vs pre- increment + - OPTIM: resolvers: move the eb32 node before the data in the answer_item + - MINOR: list: add new macro LIST_INLIST_ATOMIC() + - OPTIM: dns: use an atomic check for the list membership + - BUG/MINOR: task: do not set TASK_F_USR1 for no reason + - BUG/MINOR: mux-h2: do not prevent from sending a final GOAWAY frame + - MINOR: connection: add a new CO_FL_WANT_DRAIN flag to force drain on close + - MINOR: mux-h2: perform a full cycle shutdown+drain on close + - CLEANUP: resolvers: get rid of single-iteration loop in resolv_get_ip_from_response() + - MINOR: quic: Increase the size of handshake RX UDP datagrams + - BUG/MEDIUM: lua: fix memory leaks with realloc() on non-glibc systems + - MINOR: memprof: report the delta between alloc and free on realloc() + - MINOR: memprof: add one pointer size to the size of allocations + - BUILD: fix compilation on NetBSD + - MINOR: backend: add traces for idle connections reuse + - BUG/MINOR: backend: fix improper insert in avail tree for always reuse + - MINOR: backend: improve perf with tcp proxies skipping idle conns + - MINOR: connection: remove unneeded memset 0 for idle conns + +2021/10/16 : 2.5-dev10 + - MINOR: initcall: Rename __GLOBL and __GLOBL1. + - MINOR: rules: add a new function new_act_rule() to allocate act_rules + - MINOR: rules: add a file name and line number to act_rules + - MINOR: stream: report the current rule in "show sess all" when known + - MINOR: stream: report the current filter in "show sess all" when known + - CLEANUP: stream: Properly indent current_rule line in "show sess all" + - BUG/MINOR: lua: Fix lua error handling in `hlua_config_prepend_path()` + - CI: github: switch to OpenSSL 3.0.0 + - REGTESTS: ssl: Fix references to removed option in test description + - MINOR: ssl: Add ssllib_name_startswith precondition + - REGTESTS: ssl: Fix ssl_errors test for OpenSSL v3 + - REGTESTS: ssl: Reenable ssl_errors test for OpenSSL only + - REGTESTS: ssl: Use mostly TLSv1.2 in ssl_errors test + - MEDIUM: mux-quic: rationalize tx buffers between qcc/qcs + - MEDIUM: h3: properly manage tx buffers for large data + - MINOR: mux-quic: standardize h3 settings sending + - CLEANUP: h3: remove dead code + - MINOR: mux-quic: implement standard method to detect if qcc is dead + - MEDIUM: mux-quic: defer stream shut if remaining tx data + - MINOR: mux: remove last occurences of qcc ring buffer + - MINOR: quic: handle CONNECTION_CLOSE frame + - REGTESTS: ssl: re-enable set_ssl_cert_bundle.vtc + - MINOR: ssl: add ssl_fc_is_resumed to "option httpslog" + - MINOR: http: Add http_auth_bearer sample fetch + - MINOR: jwt: Parse JWT alg field + - MINOR: jwt: JWT tokenizing helper function + - MINOR: jwt: Insert public certificates into dedicated JWT tree + - MINOR: jwt: jwt_header_query and jwt_payload_query converters + - MEDIUM: jwt: Add jwt_verify converter to verify JWT integrity + - REGTESTS: jwt: Add tests for the jwt_verify converter + - BUILD: jwt: fix declaration of EVP_KEY in jwt-h.h + - MINOR: proto_tcp: use chunk_appendf() to ouput socket setup errors + - MINOR: proto_tcp: also report the attempted MSS values in error message + - MINOR: inet: report the faulty interface name in "bind" errors + - MINOR: protocol: report the file and line number for binding/listening errors + - MINOR: protocol: uniformize protocol errors + - MINOR: resolvers: fix the resolv_str_to_dn_label() API about trailing zero + - BUG/MEDIUM: resolver: make sure to always use the correct hostname length + - BUG/MINOR: resolvers: do not reject host names of length 255 in SRV records + - MINOR: resolvers: fix the resolv_dn_label_to_str() API about trailing zero + - MEDIUM: listeners: split the thread mask between receiver and bind_conf + - MINOR: listeners: add clone_listener() to duplicate listeners at boot time + - MEDIUM: listener: add the "shards" bind keyword + - BUG/MEDIUM: resolvers: use correct storage for the target address + - MINOR: resolvers: merge address and target into a union "data" + - BUG/MEDIUM: resolvers: fix truncated TLD consecutive to the API fix + - BUG/MEDIUM: jwt: fix base64 decoding error detection + - BUG/MINOR: jwt: use CRYPTO_memcmp() to compare HMACs + - DOC: jwt: fix a typo in the jwt_verify() keyword description + - BUG/MEDIUM: sample/jwt: fix another instance of base64 error detection + - BUG/MINOR: http-ana: Don't eval front after-response rules if stopped on back + - BUG/MINOR: sample: Fix 'fix_tag_value' sample when waiting for more data + - DOC: config: Move 'tcp-response content' at the right place + - BUG/MINOR: proxy: Use .disabled field as a bitfield as documented + - MINOR: proxy: Introduce proxy flags to replace disabled bitfield + - MINOR: sample/arg: Be able to resolve args found in defaults sections + - MEDIUM: proxy: Warn about ambiguous use of named defaults sections + - MINOR: proxy: Be able to reference the defaults section used by a proxy + - MINOR: proxy: Add PR_FL_READY flag on fully configured and usable proxies + - MINOR: config: Finish configuration for referenced default proxies + - MINOR: config: No longer remove previous anonymous defaults section + - MINOR: tcpcheck: Support 2-steps args resolution in defaults sections + - MEDIUM: rules/acl: Parse TCP/HTTP rules and acls defined in defaults sections + - MEDIUM: tcp-rules: Eval TCP rules defined in defaults sections + - MEDIUM: http-ana: Eval HTTP rules defined in defaults sections + - BUG/MEDIUM: sample: Cumulate frontend and backend sample validity flags + - REGTESTS: Add scripts to test support of TCP/HTTP rules in defaults sections + - DOC: config: Add documentation about TCP/HTTP rules in defaults section + - DOC: config: Rework and uniformize how TCP/HTTP rules are documented + - BUG/MINOR: proxy: Release ACLs and TCP/HTTP rules of default proxies + - BUG/MEDIUM: cpuset: fix cpuset size for FreeBSD + - BUG/MINOR: sample: fix backend direction flags consecutive to last fix + - BUG/MINOR: listener: fix incorrect return on out-of-memory + - BUG/MINOR: listener: add an error check for unallocatable trash + - CLEANUP: listeners: remove unreachable code in clone_listener() + +2021/10/08 : 2.5-dev9 + - head-truc + - REGTESTS: lua: test the httpclient:get() feature + - Revert "head-truc" + - BUG/MEDIUM: httpclient: replace ist0 by istptr + - MINOR: config: use a standard parser for the "nbthread" keyword + - CLEANUP: init: remove useless test against MAX_THREADS in affinity loop + - MEDIUM: init: de-uglify the per-thread affinity setting + - MINOR: init: extract the setup and end of threads to their own functions + - MINOR: log: Try to get the status code when MUX_EXIT_STATUS is retrieved + - MINOR: mux-h1: Set error code if possible when MUX_EXIT_STATUS is returned + - MINOR: mux-h1: Be able to set custom status code on parsing error + - MEDIUM: mux-h1: Reject HTTP/1.0 GET/HEAD/DELETE requests with a payload + - MEDIUM: h1: Force close mode for invalid uses of T-E header + - BUG/MINOR: mux-h1/mux-fcgi: Sanitize TE header to only send "trailers" + - MINOR: http: Add 422-Unprocessable-Content error message + - MINOR: h1: Change T-E header parsing to fail if chunked encoding is found twice + - BUG/MEDIUM: mux-h1/mux-fcgi: Reject messages with unknown transfer encoding + - REGTESTS: Add script to validate T-E header parsing + - REORG: pools: move default settings to defaults.h + - DOC: peers: fix doc "enable" statement on "peers" sections + - MINOR: Makefile: add MEMORY_POOLS to the list of DEBUG_xxx options + - MINOR: ssl: Set connection error code in case of SSL read or write fatal failure + - MINOR: ssl: Rename ssl_bc_hsk_err to ssl_bc_err + - MINOR: ssl: Store the last SSL error code in case of read or write failure + - REGTESTS: ssl: enable show_ssl_ocspresponse.vtc again + - REGTESTS: ssl: enable ssl_crt-list_filters.vtc again + - BUG/MEDIUM: lua: fix wakeup condition from sleep() + - BUG/MAJOR: lua: use task_wakeup() to properly run a task once + - MINOR: arg: Be able to forbid unresolved args when building an argument list + - BUG/MINOR: tcpcheck: Don't use arg list for default proxies during parsing + - BUG/MINOR: tcp-rules: Stop content rules eval on read error and end-of-input + - MINOR: tasks: catch TICK_ETERNITY with BUG_ON() in __task_queue() + - REGTESTS: ssl: show_ssl_ocspresponse w/ freebsd won't use base64 + - REGTESTS: ssl: wrong feature cmd in show_ssl_ocspresponse.vtc + - CLEANUP: tasks: remove the long-unused work_lists + - MINOR: task: provide 3 task_new_* wrappers to simplify the API + - MINOR: time: uninline report_idle() and move it to task.c + - REORG: sched: move idle time calculation from time.h to task.h + - REORG: sched: move the stolen CPU time detection to sched_entering_poll() + - BUG/MEDIUM: filters: Fix a typo when a filter is attached blocking the release + - BUG/MEDIUM: http-ana: Clear request analyzers when applying redirect rule + - MINOR: httpclient: destroy() must free the headers and the ists + - MINOR: httpclient: set HTTPCLIENT_F_ENDED only in release + - MINOR: httpclient: stop_and_destroy() ask the applet to autokill + - MINOR: httpclient: test if started during stop_and_destroy() + - MINOR: httpclient/lua: implement garbage collection + - BUG/MEDIUM: httpclient/lua: crash because of b_xfer and get_trash_chunk() + - MINOR: httpclient: destroy checks if a client was started but not stopped + - BUG/MINOR: httpclient/lua: does not process headers when failed + - MINOR: httpclient/lua: supports headers via named arguments + - CLEANUP: server: always include the storage for SSL settings + - CLEANUP: sample: rename sample_conv_var2smp() to *_sint + - CLEANUP: sample: uninline sample_conv_var2smp_str() + - MINOR: sample: provide a generic var-to-sample conversion function + - BUG/MEDIUM: sample: properly verify that variables cast to sample + - BUILD: action: add the relevant structures for function arguments + - BUILD: extcheck: needs to include stream-t.h + - BUILD: hlua: needs to include stream-t.h + - BUILD: stats: define several missing structures in stats.h + - BUILD: resolvers: define missing types in resolvers.h + - BUILD: httpclient: include missing ssl_sock-t + - BUILD: sample: include openssl-compat + - BUILD: http_ana: need to include proxy-t to get redirect_rule + - BUILD: http_rules: requires http_ana-t.h for REDIRECT_* + - BUILD: vars: need to include xxhash + - BUILD: peers: need to include eb{32/mb/pt}tree.h + - BUILD: ssl_ckch: include ebpttree.h in ssl_ckch.c + - BUILD: compiler: add the container_of() and container_of_safe() macros + - BUILD: idleconns: include missing ebmbtree.h at several places + - BUILD: connection: connection.h needs list.h and server.h + - BUILD: tree-wide: add missing http_ana.h from many places + - BUILD: cfgparse-ssl: add missing errors.h + - BUILD: tcp_sample: include missing errors.h and session-t.h + - BUILD: mworker: mworker-prog needs time.h for the 'now' variable + - BUILD: tree-wide: add several missing activity.h + - BUILD: compat: fix -Wundef on SO_REUSEADDR + - CLEANUP: pools: pools-t.h doesn't need to include thread-t.h + - REORG: pools: uninline the UAF allocator and force-inline the rest + - REORG: thread: uninline the lock-debugging code + - MINOR: thread/debug: replace nsec_now() with now_mono_time() + - CLEANUP: remove some unneeded includes from applet-t.h + - REORG: listener: move bind_conf_alloc() and listener_state_str() to listener.c + - CLEANUP: listeners: do not include openssl-compat + - CLEANUP: servers: do not include openssl-compat + - REORG: ssl: move ssl_sock_is_ssl() to connection.h and rename it + - CLEANUP: mux_fcgi: remove dependency on ssl_sock + - CLEANUP: ssl/server: move ssl_sock_set_srv() to srv_set_ssl() in server.c + - REORG: ssl-sock: move the sslconns/totalsslconns counters to global + - REORG: sample: move the crypto samples to ssl_sample.c + - REORG: sched: moved samp_time and idle_time to task.c as well + - REORG: time/ticks: move now_ms and global_now_ms definitions to ticks.h + - CLEANUP: tree-wide: remove unneeded include time.h in ~20 files + - REORG: activity: uninline activity_count_runtime() + - REORG: acitvity: uninline sched_activity_entry() + - CLEANUP: stream: remove many unneeded includes from stream-t.h + - CLEANUP: stick-table: no need to include socket nor in.h + - MINOR: connection: use uint64_t for the hashes + - REORG: connection: move the hash-related stuff to connection.c + - REORG: connection: uninline conn_notify_mux() and conn_delete_from_tree() + - REORG: server: uninline the idle conns management functions + - REORG: ebtree: split structures into their own file ebtree-t.h + - CLEANUP: tree-wide: only include ebtree-t from type files + - REORG: connection: move the largest inlines from connection.h to connection.c + - CLEANUP: connection: do not include http_ana! + - CLEANUP: connection: remove unneeded tcpcheck-t.h and use only session-t.h + - REORG: connection: uninline the rest of the alloc/free stuff + - REORG: task: uninline the loop time measurement code + - CLEANUP: time: move a few configurable defines to defaults.h + - CLEANUP: fd: do not include time.h + - REORG: fd: uninline compute_poll_timeout() + - CLENAUP: wdt: use ha_tkill() instead of accessing pthread directly + - REORG: thread: move the thread init/affinity/stop to thread.c + - REORG: thread: move ha_get_pthread_id() to thread.c + - MINOR: thread: use a dedicated static pthread_t array in thread.c + - CLEANUP: thread: uninline ha_tkill/ha_tkillall/ha_cpu_relax() + - DOC: configuration: add clarification on escaping in keyword arguments + - BUG/MINOR: task: fix missing include with DEBUG_TASK + - MINOR: pools: report the amount used by thread caches in "show pools" + - MINOR: quic: Distinguish packet and SSL read enc. level in traces + - MINOR: quic: Add a function to dump SSL stack errors + - MINOR: quic: BUG_ON() SSL errors. + - MINOR: quic: Fix SSL error issues (do not use ssl_bio_and_sess_init()) + - BUG/MEDIUM: mux-quic: reinsert all streams in by_id tree + - BUG/MAJOR: xprt-quic: do not queue qc timer if not set + - MINOR: mux-quic: release connection if no more bidir streams + - BUG/MAJOR: quic: remove qc from receiver cids tree on free + - BUG/MEDIUM: mux_h2: Handle others remaining read0 cases on partial frames + - MINOR: qpack: do not encode invalid http status code + - MINOR: qpack: support non-indexed http status code encoding + - MINOR: qpack: fix memory leak on huffman decoding + - CLEANUP: mux-quic: remove unused code + - BUG/MINOR: quic: fix includes for compilation + - BUILD: connection: avoid a build warning on FreeBSD with SO_USER_COOKIE + - BUILD: init: avoid a build warning on FreeBSD with USE_PROCCTL + - REORG: time: move time-keeping code and variables to clock.c + - REORG: clock: move the updates of cpu/mono time to clock.c + - MINOR: activity: get the run_time from the clock updates + - CLEANUP: clock: stop exporting before_poll and after_poll + - REORG: clock: move the clock_id initialization to clock.c + - REORG: clock/wdt: move wdt timer initialization to clock.c + - MINOR: clock: move the clock_ids to clock.c + - MINOR: wdt: move wd_timer to wdt.c + - CLEANUP: wdt: do not remap SI_TKILL to SI_LWP, test the values directly + - REORG: thread/sched: move the task_per_thread stuff to thread_ctx + - REORG: thread/clock: move the clock parts of thread_info to thread_ctx + - REORG: thread/sched: move the thread_info flags to the thread_ctx + - REORG: thread/sched: move the last dynamic thread_info to thread_ctx + - MINOR: thread: make "ti" a const pointer and clean up thread_info a bit + - MINOR: threads: introduce a minimalistic notion of thread-group + - MINOR: global: add a new "thread-groups" directive + - MINOR: global: add a new "thread-group" directive + - MINOR: threads: make tg point to the current thread's group + - MEDIUM: threads: automatically assign threads to groups + - MINOR: threads: set the group ID and its bit in the thread group + - MINOR: threads: set the tid, ltid and their bit in thread_cfg + - MEDIUM: threads: replace ha_set_tid() with ha_set_thread() + - MINOR: threads: add the current group ID in thread-local "tgid" variable + - MINOR: debug: report the group and thread ID in the thread dumps + - MEDIUM: listeners: support the definition of thread groups on bind lines + - MINOR: threads: add a new function to resolve config groups and masks + - MEDIUM: config: resolve relative threads on bind lines to absolute ones + - MEDIUM: stick-table: never learn the "conn_cur" value from peers + +2021/09/24 : 2.5-dev8 + - BUILD: compiler: fixed a missing test on defined(__GNUC__) + - BUILD: halog: fix a -Wundef warning on non-glibc systems + - BUILD: threads: fix -Wundef for _POSIX_PRIORITY_SCHEDULING on libmusl + - BUG/MINOR: compat: make sure __WORDSIZE is always defined + - BUILD: sample: fix format warning on 32-bit archs in sample_conv_be2dec_check() + - CLEANUP: pools: factor all malloc_trim() calls into trim_all_pools() + - MINOR: pools: automatically disable malloc_trim() with external allocators + - MINOR: pools: report it when malloc_trim() is enabled + - DOC: Add .mailmap + - CLEANUP: tree-wide: fix prototypes for functions taking no arguments. + - CLEANUP: Remove prototype for non-existent thread_get_default_count() + - CLEANUP: acl: Remove unused variable when releasing an acl expression + - BUG/MAJOR: mux-h1: Don't eval input data if an error was reported + - DOC: update Tim's address in .mailmap + - MINOR: pools: use mallinfo2() when available instead of mallinfo() + - BUG/MINOR: tcpcheck: Improve LDAP response parsing to fix LDAP check + - DOC: management: certificate files must be sanitized before injection + - BUG/MINOR: connection: prevent null deref on mux cleanup task allocation + - BUILD: ist: prevent gcc11 maybe-uninitialized warning on istalloc + - BUG/MINOR: cli/payload: do not search for args inside payload + - BUILD: sockpair: do not set unused flag + - BUILD: proto_uxst: do not set unused flag + - BUILD: fd: remove unused variable totlen in fd_write_frag_line() + - MINOR: applet: remove the thread mask from appctx_new() + - REORG: threads: move ha_get_pthread_id() to tinfo.h + - CLEANUP: Apply ist.cocci + - DEV: coccinelle: Add ist.cocci + - CLEANUP: Apply bug_on.cocci + - DEV: coccinelle: Add xalloc_size.cocci + - DEV: coccinelle: Add bug_on.cocci + - CLEANUP: Apply xalloc_size.cocci + - DEV: coccinelle: Add xalloc_cast.cocci + - BUG/MINOR: flt-trace: fix an infinite loop when random-parsing is set + - MINOR: httpclient: add the EOH when no headers where provided + - CLEANUP: Include check.h in flt_spoe.c + - CLEANUP: Remove unreachable `break` from parse_time_err() + - BUG/MINOR: server: allow 'enable health' only if check configured + - BUG/MINOR: server: alloc dynamic srv ssl ctx if proxy uses ssl chk rule + - MINOR: server: enable more keywords for ssl checks for dynamic servers + - MINOR: server: enable more check related keywords for dynamic servers + - REORG: server: move slowstart init outside of checks + - MINOR: server: enable slowstart for dynamic server + - MEDIUM: listener: deprecate "process" in favor of "thread" on bind lines + - BUG/MEDIUM: leastconn: fix rare possibility of divide by zero + - BUG/MINOR: quic: Possible NULL pointer dereferencing when dumping streams. + - MINOR: quic: Move transport parmaters to anynomous struct. + - MINOR: mux_quic: Add QUIC mux layer. + - MINOR: connection: Add callbacks definitions for QUIC. + - MINOR: quic: Attach QUIC mux connection objet to QUIC connection. + - MINOR: quic: Add a new definition to store STREAM frames. + - MINOR: h3: Add HTTP/3 definitions. + - MINOR: qpack: Add QPACK compression. + - MINOR: quic_sock: Finalize the QUIC connections. + - MINOR: quic: Disable the action of ->rcv_buf() xprt callback + - MINOR: quic: Add callbacks for (un)scribing to QUIC xprt. + - MINOR: quic: Variable-length integer encoding/decoding into/from buffer struct. + - BUG/MINOR: quic: Wrong ->accept() error handling + - MINOR: quic: Add a wrapper function to update transport parameters. + - MINOR: quic: Update the streams transport parameters. + - MINOR: quic: Avoid header collisions + - MINOR: quic: Replace max_packet_size by max_udp_payload size. + - MINOR: quic: Enable some quic, h3 and qpack modules compilation. + - MINOR: quic: Move an SSL func call from QUIC I/O handler to the xprt init. + - MINOR: quic: Initialize the session before starting the xprt. + - BUG/MINOR: quic: Do not check the acception of a new conn from I/O handler. + - MINOR: quic: QUIC conn initialization from I/O handler + - MINOR: quic: Remove header protection for conn with context + - MINOR: quic: Derive the initial secrets asap + - MINOR: quic: Remove header protection also for Initial packets + - BUG/MINOR: quic: Wrong memory free in quic_update_ack_ranges_list() + - MINOR: quic: quic_update_ack_ranges_list() code factorization + - MINOR: quic: Useless test in quic_update_ack_ranges_list() + - MINOR: quic: Remove a useless variable in quic_update_ack_ranges_list() + - BUG/MINOR: quic: Missing cases treatement when updating ACK ranges + - CLEAUNUP: quic: Usage of a useless variable in qc_treat_rx_pkts() + - BUG/MINOR: quic: Wrong RX packet reference counter usage + - MINOR: quic: Do not stop the packet parsing too early in qc_treat_rx_packets() + - MINOR: quic: Add a lock for RX packets + - MINOR: quic: Move the connection state + - MINOR: quic: Replace quic_conn_ctx struct by ssl_sock_ctx struct + - MINOR: quic: Replace the RX list of packet by a thread safety one. + - MINOR: quic: Replace the RX unprotected packet list by a thread safety one. + - MINOR: quic: Add useful traces for I/O dgram handler + - MINOR: quic: Do not wakeup the xprt task on ACK receipt + - MINOR: quic: Connection allocations rework + - MINOR: quic: Move conn_prepare() to ->accept_conn() callback + - MINOR: quic: Make qc_lstnr_pkt_rcv() be thread safe. + - MINOR: quic: Add a ring buffer implementation for QUIC + - MINOR: quic: Prefer x25519 as ECDH preferred parametes. + - MINOR: quic: Add the QUIC v1 initial salt. + - BUG/MINOR: quic: Too much reduced computed space to build handshake packets + - MINOR: net_helper: add functions for pointers + - MINOR: quic: Add ring buffer definition (struct qring) for QUIC + - MINOR: proto_quic: Allocate TX ring buffers for listeners + - MINOR: quic: Initialize pointers to TX ring buffer list + - MINOR: quic: Make use of TX ring buffers to send QUIC packets + - MINOR: quic_tls: Make use of the QUIC V1 salt. + - MINOR: quic: Remove old TX buffer implementation + - MINOR: Add function for TX packets reference counting + - MINOR: quic: Add TX packets at the very last time to their tree. + - MINOR: quic: Unitialized mux context upon Client Hello message receipt. + - MINOR: quic: Missing encryption level rx.crypto member initialization and lock. + - MINOR: quic: Rename ->rx.rwlock of quic_enc_level struct to ->rx.pkts_rwlock + - MINOR: quic: Make qc_treat_rx_pkts() be thread safe. + - MINOR: quic: Make ->tx.frms quic_pktns struct member be thread safe + - MINOR: quic: Replace quic_tx_frm struct by quic_frame struct + - MINOR: quic: Add a mask for TX frame builders and their authorized packet types + - MINOR: quic: Add a useful function to compute any frame length. + - MINOR: quic: Add the QUIC connection state to traces + - MINOR: quic: Store post handshake frame in ->pktns.tx.frms MT_LIST + - MINOR: quic: Add the packet type to quic_tx_packet struct + - MINOR: quic: Modify qc_do_build_hdshk_pkt() to accept any packet type + - MINOR: quic: Atomically handle packet number space ->largest_acked_pn variable + - MINOR: quic: Modify qc_build_cfrms() to support any frame + - MINOR: quic: quic_conn_io_cb() task rework + - MINOR: quic: Make qc_build_hdshk_pkt() atomically consume a packet number + - MINOR: quic: qc_do_build_hdshk_pkt() does not need to pass a copy of CRYPTO frame + - MINOR: quic: Remove Application level related functions + - MINOR: quic: Rename functions which do not build only Handshake packets + - MINOR: quic: Make circular buffer internal buffers be variable-sized. + - MINOR: quic: Add a pool for TX ring buffer internal buffer + - MINOR: quic: Make use of the last cbuf API when initializing TX ring buffers + - MINOR: quic: Missing acks encoded size updates. + - MINOR: quic: Evaluate the packet lengths in advance + - MINOR: quic: Update the TLS extension for QUIC transport parameters + - MINOR: quic: Fix handshake state debug strings + - MINOR: quic: Atomically get/set the connection state + - MINOR: quic: Missing QUIC encryption level for qc_build_pkt() + - MINOR: quic: Coalesce Application level packets with Handshake packets. + - MINOR: quic: Wrong flags handling for acks + - MINOR: quic: Missing case when discarding HANDSHAKE secrets + - MINOR: quic: Post handshake packet building improvements + - MINOR: quic: Prepare Application level packet asap. + - MINOR: h3: Send h3 settings asap + - MINOR: quic: Wrong STREAM frame length computing + - MINOR: quic: Wrong short packet minimum length + - MINOR: quic: Prepare STREAM frames to fill QUIC packets + - MINOR: h3: change default settings + - MINOR: quic-enc: fix varint encoding + - MINOR: qpack: fix wrong comment + - MINOR: qpack: generate headers list on decoder + - MINOR: h3: parse headers to htx + - MINOR: h3: allocate stream on headers + - MEDIUM: mux-quic: implement ring buffer on stream tx + - MINOR: mux-quic: send SETTINGS on uni stream + - MINOR: h3: define snd_buf callback and divert mux ops + - MINOR: mux-quic: define FIN stream flag + - MINOR: qpack: create qpack-enc module + - MINOR: qpack: encode headers functions + - MINOR: h3: encode htx headers to QPACK + - MINOR: h3: send htx data + - MINOR: h3/mux: detect fin on last h3 frame of the stream + - MINOR: quic: Shorten some handshakes + - MINOR: quic: Make QUIC-TLS support at least two initial salts + - MINOR: quic: Attach the QUIC connection to a thread. + - MINOR: quic: Missing active_connection_id_limit default value + - MINOR: quic_sock: Do not flag QUIC connections as being set + - MINOR: buf: Add b_force_xfer() function + - MINOR: quic: Make use of buffer structs to handle STREAM frames + - MINOR: mux_quic: move qc_process() code to qc_send() + - MINOR: quic: Add a typedef for unsigned long long + - MINOR: quic: Confusion between TX/RX for the frame builders + - MINOR: quic: Wrong packet flags settings during frame building + - MINOR: quic: Constantness fixes for frame builders/parsers. + - MINOR: quic_tls: Client/serveur state reordering + - MINOR: quic: Wrong packet loss detection due to wrong pktns order + - MINOR: quic: Wrong packet number space selection in quic_loss_pktns() + - MINOR: quic: Initial packet number spaced not discarded + - MINOR: quic: Add useful trace about pktns discarding + - MINOR: mux_quic: Export the mux related flags + - MINOR: quic: Implement quic_conn_subscribe() + - MINOR: quic: Wake up the mux upon ACK receipt + - MINOR: quic: Stream FIN bit fix in qcs_push_frame() + - MINOR: quic: Implement qc_process_mux() + - MINOR: quic: Wake up the xprt from mux + - CLEANUP: quic: Remove useless inline functions + - MINOR: quic: RX packets memory leak + - MINOR: quic: Possible endless loop in qc_treat_rx_pkts() + - MINOR: quic: Crash upon too big packets receipt + - MINOR: quic: define close handler + - MEDIUM: quic: implement mux release/conn free + - MINOR: quic: fix qcc subs initialization + - BUG/MINOR: h1-htx: Fix a typo when request parser is reset + - BUG/MEDIUM: mux-h1: Adjust conditions to ask more space in the channel buffer + - BUG/MEDIUM: stream-int: Notify stream that the mux wants more room to xfer data + - BUG/MEDIUM: stream: Stop waiting for more data if SI is blocked on RXBLK_ROOM + - MINOR: stream-int: Set CO_RFL transient/persistent flags apart in si_cs_rcv() + - MINOR: htx: Add an HTX flag to know when a message is fragmented + - MINOR: htx: Add a function to know if the free space wraps + - BUG/MEDIUM: stream-int: Defrag HTX message in si_cs_recv() if necessary + - MINOR: stream-int: Notify mux when the buffer is not stuck when calling rcv_buf + - BUG/MINOR: http-ana: increment internal_errors counter on response error + - MINOR: stats: Enable dark mode on stat web page + - CLEANUP: stats: Fix some alignment mistakes + - MINOR: httpclient: httpclient_data() returns the available data + - MINOR: httpclient: httpclient_ended() returns 1 if the client ended + - MINOR: httpclient/lua: httpclient:get() API in lua + - MINOR: httpclient/lua: implement the headers in the response object + - BUG/MINOR: httpclient/lua: return an error on argument check + - CLEANUP: slz: Mark `reset_refs` as static + +2021/09/12 : 2.5-dev7 + - BUG/MINOR: config: reject configs using HTTP with bufsize >= 256 MB + - CLEANUP: htx: remove comments about "must be < 256 MB" + - BUG/MAJOR: htx: fix missing header name length check in htx_add_header/trailer + - Revert "BUG/MINOR: stream-int: Don't block reads in si_update_rx() if chn may receive" + - MINOR: proxy: add a global "grace" directive to postpone soft-stop + - MINOR: vars: rename vars_init() to vars_init_head() + - CLEANUP: vars: rename sample_clear_stream() to var_unset() + - REORG: vars: remerge sample_store{,_stream}() into var_set() + - MEDIUM: vars: make the ifexist variant of set-var only apply to the proc scope + - MINOR: vars: add a VF_CREATEONLY flag for creation + - MINOR: vars: support storing empty sample data with a variable + - MINOR: vars: store flags into variables and add VF_PERMANENT + - MEDIUM: vars: make var_clear() only reset VF_PERMANENT variables + - MEDIUM: vars: pre-create parsed SCOPE_PROC variables as permanent ones + - MINOR: vars: preset a random seed to hash variables names + - MEDIUM: vars: replace the global name index with a hash + - CLEANUP: vars: remove the now unused var_names array + - MINOR: vars: centralize the lock/unlock into static inlines + - OPTIM: vars: only takes the variables lock on shared entries + - OPTIM: vars: remove internal bookkeeping for vars_global_size + - OPTIM: vars: do not keep variables usage stats if no limit is set + - BUILD: fix dragonfly build again on __read_mostly + - CI: Github Actions: temporarily disable Opentracing + - BUG/MEDIUM: mux-h1: Remove "Upgrade:" header for requests with payload + - MINOR: htx: Skip headers with no value when adding a header list to a message + - CLEANUP: mux-h1: Remove condition rejecting upgrade requests with payload + - BUG/MEDIUM: stream-int: Don't block SI on a channel policy if EOI is reached + - BUG/MEDIUM: http-ana: Reset channels analysers when returning an error + - BUG/MINOR: filters: Set right FLT_END analyser depending on channel + - CLEANUP: Add haproxy/xxhash.h to avoid modifying import/xxhash.h + - CLEANUP: ebmbtree: Replace always-taken elseif by else + - CLEANUP: Move XXH3 macro from haproxy/compat.h to haproxy/xxhash.h + - BUILD: opentracing: exclude the use of haproxy variables for the OpenTracing context + - BUG/MINOR: opentracing: enable the use of http headers without a set value + - CLEANUP: opentracing: use the haproxy function to generate uuid + - MINOR: opentracing: change the scope of the variable 'ot.uuid' from 'sess' to 'txn' + - CI: Github Actions: re-enable Opentracing + - CLEANUP: opentracing: simplify the condition on the empty header + - BUG/MEDIUM lua: Add missing call to RESET_SAFE_LJMP in hlua_filter_new() + +2021/09/03 : 2.5-dev6 + - BUG/MINOR threads: Use get_(local|gm)time instead of (local|gm)time + - BUG/MINOR: tools: Fix loop condition in dump_text() + - BUILD: ssl: next round of build warnings on LIBRESSL_VERSION_NUMBER + - BUILD: ssl: fix two remaining occurrences of #if USE_OPENSSL + - BUILD: tools: properly guard __GLIBC__ with defined() + - BUILD: globally enable -Wundef + - MINOR: log: Remove log-error-via-logformat option + - MINOR: log: Add new "error-log-format" option + - BUG/MAJOR: queue: better protect a pendconn being picked from the proxy + - CLEANUP: Add missing include guard to signal.h + - MINOR: ssl: Add new ssl_bc_hsk_err sample fetch + - MINOR: connection: Add a connection error code sample fetch for backend side + - REGTESTS: ssl: Add tests for bc_conn_err and ssl_bc_hsk_err sample fetches + - MINOR: http-rules: add a new "ignore-empty" option to redirects. + - CI: Github Actions: temporarily disable BoringSSL builds + - BUG/MINOR: vars: fix set-var/unset-var exclusivity in the keyword parser + - BUG/MINOR: vars: improve accuracy of the rules used to check expression validity + - MINOR: sample: add missing ARGC_ entries + - BUG/MINOR: vars: properly set the argument parsing context in the expression + - DOC: configuration: remove wrong tcp-request examples in tcp-response + - MEDIUM: vars: add a new "set-var-fmt" action + - BUG/MEDIUM: vars: run over the correct list in release_store_rules() + - BUG/MINOR: vars: truncate the variable name in error reports about scope. + - BUG/MINOR: vars: do not talk about global section in CLI errors for set-var + - CLEANUP: vars: name the temporary proxy "CFG" instead of "CLI" for global vars + - MINOR: log: make log-format expressions completely usable outside of req/resp + - MINOR: vars: add a "set-var-fmt" directive to the global section + - MEDIUM: vars: also support format strings in CLI's "set var" command + - CLEANUP: vars: factor out common code from vars_get_by_{desc,name} + - MINOR: vars: make vars_get_by_* support an optional default value + - MINOR: vars: make the vars() sample fetch function support a default value + - BUILD: ot: add argument for default value to vars_get_by_name() + +2021/08/28 : 2.5-dev5 + - MINOR: httpclient: initialize the proxy + - MINOR: httpclient: implement a simple HTTP Client API + - MINOR: httpclient/cli: implement a simple client over the CLI + - MINOR: httpclient/cli: change the User-Agent to "HAProxy" + - MEDIUM: ssl: Keep a reference to the client's certificate for use in logs + - BUG/MEDIUM: h2: match absolute-path not path-absolute for :path + - BUILD/MINOR: ssl: Fix compilation with OpenSSL 1.0.2 + - MINOR: server: check if srv is NULL in free_server() + - MINOR: proxy: check if p is NULL in free_proxy() + - BUG/MEDIUM: cfgparse: do not allocate IDs to automatic internal proxies + - BUG/MINOR: http_client: make sure to preset the proxy's default settings + - REGTESTS: http_upgrade: fix incorrect expectation on TCP->H1->H2 + - REGTESTS: abortonclose: after retries, 503 is expected, not close + - REGTESTS: server: fix agent-check syntax and expectation + - BUG/MINOR: httpclient: fix uninitialized sl variable + - BUG/MINOR: httpclient/cli: change the appctx test in the callbacks + - BUG/MINOR: httpclient: check if hdr_num is not 0 + - MINOR: httpclient: cleanup the include files + - MINOR: hlua: take the global Lua lock inside a global function + - MINOR: tools: add FreeBSD support to get_exec_path() + - BUG/MINOR: systemd: ExecStartPre must use -Ws + - MINOR: systemd: remove the ExecStartPre line in the unit file + - MINOR: ssl: add an openssl version string parser + - MINOR: cfgcond: implements openssl_version_atleast and openssl_version_before + - CLEANUP: ssl: remove useless check on p in openssl_version_parser() + - BUG/MINOR: stick-table: fix the sc-set-gpt* parser when using expressions + - BUG/MINOR: httpclient: remove deinit of the httpclient + - BUG/MEDIUM: base64: check output boundaries within base64{dec,urldec} + - MINOR: httpclient: set verify none on the https server + - MINOR: httpclient: add the server to the proxy + - BUG/MINOR: httpclient: fix Host header + - BUILD: httpclient: fix build without OpenSSL + - CI: github-actions: remove obsolete options + - CLEANUP: assorted typo fixes in the code and comments + - MINOR: proc: setting the process to produce a core dump on FreeBSD. + - BUILD: adopt script/build-ssl.sh for OpenSSL-3.0.0beta2 + - MINOR: server: return the next srv instance on free_server + - BUG/MINOR: stats: use refcount to protect dynamic server on dump + - MEDIUM: server: extend refcount for all servers + - MINOR: server: define non purgeable server flag + - MINOR: server: mark referenced servers as non purgeable + - MINOR: server: mark servers referenced by LUA script as non purgeable + - MEDIUM: server: allow to remove servers at runtime except non purgeable + - BUG/MINOR: base64: base64urldec() ignores padding in output size check + - REGTEST: add missing lua requirements on server removal test + - REGTEST: fix haproxy required version for server removal test + - BUG/MINOR: proxy: don't dump servers of internal proxies + - REGTESTS: Use `feature cmd` for 2.5+ tests + - REGTESTS: Remove REQUIRE_VERSION=1.5 from all tests + - BUG/MINOR: resolvers: mark servers with name-resolution as non purgeable + - MINOR: compiler: implement an ONLY_ONCE() macro + - BUG/MINOR: lua: use strlcpy2() not strncpy() to copy sample keywords + - MEDIUM: ssl: Capture more info from Client Hello + - MINOR: sample: Expose SSL captures using new fetchers + - MINOR: sample: Add be2dec converter + - MINOR: sample: Add be2hex converter + - MEDIUM: config: Deprecate tune.ssl.capture-cipherlist-size + - BUG/MINOR: time: fix idle time computation for long sleeps + - MINOR: time: add report_idle() to report process-wide idle time + - BUG/MINOR: ebtree: remove dependency on incorrect macro for bits per long + - BUILD: activity: use #ifdef not #if on USE_MEMORY_PROFILING + - BUILD/MINOR: defaults: eliminate warning on MAXHOSTNAMELEN with -Wundef + - BUILD/MINOR: ssl: avoid a build warning on LIBRESSL_VERSION with -Wundef + - IMPORT: slz: silence a build warning with -Wundef + - BUILD/MINOR: regex: avoid a build warning on USE_PCRE2 with -Wundef + +2021/08/17 : 2.5-dev4 + - MINOR: log: rename 'dontloglegacyconnerr' to 'log-error-via-logformat' + - MINOR: doc: rename conn_status in `option httsplog` + - MINOR: proxy: disabled takes a stopping and a disabled state + - MINOR: stats: shows proxy in a stopped state + - BUG/MINOR: server: fix race on error path of 'add server' CLI if track + - CLEANUP: thread: fix fantaisist indentation of thread_harmless_till_end() + - MINOR: threads: make thread_release() not wait for other ones to complete + - MEDIUM: threads: add a stronger thread_isolate_full() call + - MEDIUM: servers: make the server deletion code run under full thread isolation + - BUG/MINOR: server: remove srv from px list on CLI 'add server' error + - MINOR: activity/fd: remove the dead_fd counter + - MAJOR: fd: get rid of the DWCAS when setting the running_mask + - CLEANUP: fd: remove the now unused fd_set_running() + - CLEANUP: fd: remove the now unneeded fd_mig_lock + - BUG/MINOR: server: update last_change on maint->ready transitions too + - MINOR: spoe: Add a pointer on the filter config in the spoe_agent structure + - BUG/MEDIUM: spoe: Create a SPOE applet if necessary when the last one is released + - BUG/MEDIUM: spoe: Fix policy to close applets when SPOE connections are queued + - MINOR: server: unmark deprecated on enable health/agent cli + - MEDIUM: task: implement tasklet kill + - MINOR: server: initialize fields for dynamic server check + - MINOR: check: allocate default check ruleset for every backends + - MINOR: check: export check init functions + - MINOR: check: do not increment global maxsock at runtime + - MINOR: server: implement a refcount for dynamic servers + - MEDIUM: check: implement check deletion for dynamic servers + - MINOR: check: enable safe keywords for dynamic servers + - MEDIUM: server: implement check for dynamic servers + - MEDIUM: server: implement agent check for dynamic servers + - REGTESTS: server: add dynamic check server test + - MINOR: doc: specify ulimit-n usage for dynamic servers + - REGTESTS: server: fix dynamic server with checks test + - CI: travis-ci: temporarily disable arm64 builds + - BUG/MINOR: check: test if server is not null in purge + - MINOR: global: define MODE_STOPPING + - BUG/MINOR: server: do not use refcount in free_server in stopping mode + - ADMIN: dyncookie: implement a simple dynamic cookie calculator + - BUG/MINOR: check: do not reset check flags on purge + - BUG/MINOR: check: fix leak on add dynamic server with agent-check error + - BUG/MEDIUM: check: fix leak on agent-check purge + - BUG/MEDIUM: server: support both check/agent-check on a dynamic instance + - BUG/MINOR: buffer: fix buffer_dump() formatting + - MINOR: channel: remove an htx block from a channel + - BUG/MINOR: tcpcheck: Properly detect pending HTTP data in output buffer + - BUG/MINOR: stream: Don't release a stream if FLT_END is still registered + - MINOR: lua: Add a flag on lua context to know the yield capability at run time + - BUG/MINOR: lua: Yield in channel functions only if lua context can yield + - BUG/MINOR: lua: Don't yield in channel.append() and channel.set() + - MINOR: filters/lua: Release filters before the lua context + - MINOR: lua: Add a function to get a reference on a table in the stack + - MEDIUM: lua: Process buffer data using an offset and a length + - MEDIUM: lua: Improve/revisit the lua api to manipulate channels + - DOC: Improve the lua documentation + - MEDIUM: filters/lua: Add support for dummy filters written in lua + - MINOR: lua: Add a function to get a filter attached to a channel class + - MINOR: lua: Add flags on the lua TXN to know the execution context + - MEDIUM: filters/lua: Be prepared to filter TCP payloads + - MEDIUM: filters/lua: Support declaration of some filter callback functions in lua + - MEDIUM: filters/lua: Add HTTPMessage class to help HTTP filtering + - MINOR: filters/lua: Add request and response HTTP messages in the lua TXN + - MINOR: filters/lua: Support the HTTP filtering from filters written in lua + - DOC: config: Fix 'http-response send-spoe-group' documentation + - BUG/MINOR: lua: Properly check negative offset in Channel/HttpMessage functions + - BUG/MINOR: lua: Properly catch alloc errors when parsing lua filter directives + - BUG/MEDIUM: cfgcheck: verify existing log-forward listeners during config check + - MINOR: cli: delare the CLI frontend as an internal proxy + - MINOR: proxy: disable warnings for internal proxies + - BUG/MINOR: filters: Always set FLT_END analyser when CF_FLT_ANALYZE flag is set + - BUG/MINOR: lua/filters: Return right code when txn:done() is called + - DOC: lua-api: Add documentation about lua filters + - CI: Remove obsolete USE_SLZ=1 CI job + - CLEANUP: assorted typo fixes in the code and comments + - CI: github actions: relax OpenSSL-3.0.0 version comparision + - BUILD: tools: get the absolute path of the current binary on NetBSD. + - DOC: Minor typo fix - 'question mark' -> 'exclamation mark' + - DOC/MINOR: fix typo in management document + - MINOR: http: add a new function http_validate_scheme() to validate a scheme + - BUG/MAJOR: h2: verify early that non-http/https schemes match the valid syntax + - BUG/MAJOR: h2: verify that :path starts with a '/' before concatenating it + - BUG/MAJOR: h2: enforce stricter syntax checks on the :method pseudo-header + - BUG/MEDIUM: h2: give :authority precedence over Host + - REGTESTS: add a test to prevent h2 desync attacks + +2021/08/01 : 2.5-dev3 + - BUG/MINOR: arg: free all args on make_arg_list()'s error path + - BUG/MINOR: cfgcond: revisit the condition freeing mechanism to avoid a leak + - MEDIUM: proxy: remove long-broken 'option http_proxy' + - CLEANUP: http_ana: Remove now unused label from http_process_request() + - MINOR: deinit: always deinit the init_mutex on failed initialization + - BUG/MEDIUM: cfgcond: limit recursion level in the condition expression parser + - BUG/MEDIUM: mworker: do not register an exit handler if exit is expected + - BUG/MINOR: mworker: do not export HAPROXY_MWORKER_REEXEC across programs + - BUILD/MINOR: memprof fix macOs build. + - BUG/MEDIUM: ssl_sample: fix segfault for srv samples on invalid request + - BUG/MINOR: stats: Add missing agent stats on servers + - BUG/MINOR: check: fix the condition to validate a port-less server + - BUILD: threads: fix pthread_mutex_unlock when !USE_THREAD + - BUG/MINOR: resolvers: Use a null-terminated string to lookup in servers tree + - MINOR: ssl: use __objt_* variant when retrieving counters + - BUG/MINOR: systemd: must check the configuration using -Ws + - BUG/MINOR: mux-h1: Obey dontlognull option for empty requests + - BUG/MINOR: mux-h2: Obey dontlognull option during the preface + - BUG/MINOR: mux-h1: Be sure to swap H1C to splice mode when rcv_pipe() is called + - BUG/MEDIUM: mux-h2: Handle remaining read0 cases on partial frames + - MINOR: proxy: rename PR_CAP_LUA to PR_CAP_INT + - MINOR: mworker: the mworker CLI proxy is internal + - MINOR: stats: don't output internal proxies (PR_CAP_INT) + - CLEANUP: mworker: use the proxy helper functions in mworker_cli_proxy_create() + - CLEANUP: mworker: PR_CAP already initialized with alloc_new_proxy() + - BUG/MINOR: connection: Add missing error labels to conn_err_code_str + - MINOR: connection: Add a connection error code sample fetch + - MINOR: ssl: Enable error fetches in case of handshake error + - MINOR: ssl: Add new ssl_fc_hsk_err sample fetch + - MINOR: ssl: Define a default https log format + - MEDIUM: connection: Add option to disable legacy error log + - REGTESTS: ssl: Add tests for the connection and SSL error fetches + - REGTESTS: ssl: ssl_errors.vtc does not work with old openssl version + - BUG/MEDIUM: connection: close a rare race between idle conn close and takeover + - BUG/MEDIUM: pollers: clear the sleeping bit after waking up, not before + - BUG/MINOR: select: fix excess number of dead/skip reported + - BUG/MINOR: poll: fix abnormally high skip_fd counter + - BUG/MINOR: pollers: always program an update for migrated FDs + - BUG/MINOR: fd: protect fd state harder against a concurrent takeover + - DOC: internals: document the FD takeover process + - MINOR: fd: update flags only once in fd_update_events() + - MINOR: poll/epoll: move detection of RDHUP support earlier + - REORG: fd: uninline fd_update_events() + - MEDIUM: fd: rely more on fd_update_events() to detect changes + - BUG/MINOR: freq_ctr: use stricter barriers between updates and readings + - MEDIUM: atomic: simplify the atomic load/store/exchange operations + - MEDIUM: atomic: relax the load/store barriers on x86_64 + - BUILD: opentracing: fixed build when using pkg-config utility + +2021/07/17 : 2.5-dev2 + - BUILD/MEDIUM: tcp: set-mark support for OpenBSD + - DOC: config: use CREATE USER for mysql-check + - BUG/MINOR: stick-table: fix several printf sign errors dumping tables + - BUG/MINOR: peers: fix data_type bit computation more than 32 data_types + - MINOR: stick-table: make skttable_data_cast to use only std types + - MEDIUM: stick-table: handle arrays of standard types into stick-tables + - MEDIUM: peers: handle arrays of std types in peers protocol + - DOC: stick-table: add missing documentation about gpt0 stored type + - MEDIUM: stick-table: add the new array of gpt data_type + - MEDIUM: stick-table: make the use of 'gpt' excluding the use of 'gpt0' + - MEDIUM: stick-table: add the new arrays of gpc and gpc_rate + - MEDIUM: stick-table: make the use of 'gpc' excluding the use of 'gpc0/1'' + - BUG/MEDIUM: sock: make sure to never miss early connection failures + - BUG/MINOR: cli: fix server name output in "show fd" + - Revert "MINOR: tcp-act: Add set-src/set-src-port for "tcp-request content" rules" + - MEDIUM: stats: include disabled proxies that hold active sessions to stats + - BUILD: stick-table: shut up invalid "uninitialized" warning in gcc 8.3 + - MINOR: http: implement http_get_scheme + - MEDIUM: http: implement scheme-based normalization + - MEDIUM: h1-htx: apply scheme-based normalization on h1 requests + - MEDIUM: h2: apply scheme-based normalization on h2 requests + - REGTESTS: add http scheme-based normalization test + - BUILD: http_htx: fix ci compilation error with isdigit for Windows + - MINOR: http: implement http uri parser + - MINOR: http: use http uri parser for scheme + - MINOR: http: use http uri parser for authority + - REORG: http_ana: split conditions for monitor-uri in wait for request + - MINOR: http: use http uri parser for path + - BUG/MEDIUM: http_ana: fix crash for http_proxy mode during uri rewrite + - MINOR: mux_h2: define config to disable h2 websocket support + - CLEANUP: applet: remove unused thread_mask + - BUG/MINOR: ssl: Default-server configuration ignored by server + - BUILD: add detection of missing important CFLAGS + - BUILD: lua: silence a build warning with TCC + - MINOR: srv: extract tracking server config function + - MINOR: srv: do not allow to track a dynamic server + - MEDIUM: server: support track keyword for dynamic servers + - REGTESTS: test track support for dynamic servers + - MINOR: init: verify that there is a single word on "-cc" + - MINOR: init: make -cc support environment variables expansion + - MINOR: arg: add a free_args() function to free an args array + - CLEANUP: config: use free_args() to release args array in cfg_eval_condition() + - CLEANUP: hlua: use free_args() to release args arrays + - REORG: config: move the condition preprocessing code to its own file + - MINOR: cfgcond: start to split the condition parser to introduce terms + - MEDIUM: cfgcond: report invalid trailing chars after expressions + - MINOR: cfgcond: remerge all arguments into a single line + - MINOR: cfgcond: support negating conditional expressions + - MINOR: cfgcond: make the conditional term parser automatically allocate nodes + - MINOR: cfgcond: insert an expression between the condition and the term + - MINOR: cfgcond: support terms made of parenthesis around expressions + - REGTEST: make check_condition.vtc fail as soon as possible + - REGTESTS: add more complex check conditions to check_conditions.vtc + - BUG/MEDIUM: init: restore behavior of command-line "-m" for memory limitation + +2021/06/30 : 2.5-dev1 + - CLEANUP: ssl: Move ssl_store related code to ssl_ckch.c + - MINOR: ssl: Allow duplicated entries in the cafile_tree + - MEDIUM: ssl: Chain ckch instances in ca-file entries + - MINOR: ssl: Add reference to default ckch instance in bind_conf + - MINOR: ssl: Add helper functions to create/delete cafile entries + - MEDIUM: ssl: Add a way to load a ca-file content from memory + - MINOR: ssl: Add helper function to add cafile entries + - MINOR: ssl: Ckch instance rebuild and cleanup factorization in CLI handler + - MEDIUM: ssl: Add "set+commit ssl ca-file" CLI commands + - REGTESTS: ssl: Add new ca-file update tests + - MINOR: ssl: Add "abort ssl ca-file" CLI command + - MINOR: ssl: Add a cafile_entry type field + - MINOR: ssl: Refactorize the "show certificate details" code + - MEDIUM: ssl: Add "show ssl ca-file" CLI command + - MEDIUM: ssl: Add "new ssl ca-file" CLI command + - MINOR: ssl: Add "del ssl ca-file" CLI command + - REGTESTS: ssl: Add "new/del ssl ca-file" tests + - DOC: ssl: Add documentation about CA file hot update commands + - DOC: internals: update the SSL architecture schema + - MINOR: ssl: Chain instances in ca-file entries + - MEDIUM: ssl: Add "set+commit ssl crl-file" CLI commands + - MEDIUM: ssl: Add "new+del crl-file" CLI commands + - MINOR: ssl: Add "abort ssl crl-file" CLI command + - MEDIUM: ssl: Add "show ssl crl-file" CLI command + - REGTESTS: ssl: Add "new/del ssl crl-file" tests + - REGTESTS: ssl: Add "set/commit ssl crl-file" test + - DOC: ssl: Add documentation about CRL file hot update commands + - BUILD/MINOR: ssl: Fix compilation with SSL enabled + - BUILD/MINOR: ssl: Fix compilation with OpenSSL 1.0.2 + - CI: introduce scripts/build-vtest.sh for installing VTest + - CLEANUP: ssl: Fix coverity issues found in CA file hot update code + - CI: github actions: add OpenTracing builds + - BUG/MEDIUM: ebtree: Invalid read when looking for dup entry + - BUG/MAJOR: server: prevent deadlock when using 'set maxconn server' + - BUILD/MINOR: opentracing: fixed build when using clang + - BUG/MEDIUM: filters: Exec pre/post analysers only one time per filter + - BUG/MINOR: http-comp: Preserve HTTP_MSGF_COMPRESSIONG flag on the response + - MINOR: map/acl: print the count of all the map/acl entries in "show map/acl" + - CLEANUP: pattern: remove export of non-existent function pattern_delete() + - MINOR: h1-htx: Update h1 parsing functions to return result as a size_t + - MEDIUM: h1-htx: Adapt H1 data parsing to copy wrapping data in one call + - MINOR: mux-h1/mux-fcgi: Don't needlessly loop on data parsing + - MINOR: h1-htx: Move HTTP chunks parsing into a dedicated function + - MEDIUM: h1-htx: Split function to parse a chunk and the loop on the buffer + - MEDIUM: h1-htx: Add a function to parse contiguous small chunks + - MINOR: h1-htx: Use a correlation table to speed-up small chunks parsing + - MINOR: buf: Add function to realign a buffer with a specific head position + - MINOR: muxes/h1-htx: Realign input buffer using b_slow_realign_ofs() + - CLEANUP: mux-h1: Rename functions parsing input buf and filling output buf + - Revert "MEDIUM: http-ana: Deal with L7 retries in HTTP analysers" + - BUG/MINOR: http-ana: Send the right error if max retries is reached on L7 retry + - BUG/MINOR: http-ana: Handle L7 retries on refused early data before K/A aborts + - MINOR: http-ana: Perform L7 retries because of status codes in response analyser + - MINOR: cfgparse: Fail when encountering extra arguments in macro + - DOC: intro: Fix typo in starter guide + - BUG/MINOR: server: Missing calloc return value check in srv_parse_source + - BUG/MINOR: peers: Missing calloc return value check in peers_register_table + - BUG/MINOR: ssl: Missing calloc return value check in ssl_init_single_engine + - BUG/MINOR: http: Missing calloc return value check in parse_http_req_capture + - BUG/MINOR: proxy: Missing calloc return value check in proxy_parse_declare + - BUG/MINOR: proxy: Missing calloc return value check in proxy_defproxy_cpy + - BUG/MINOR: http: Missing calloc return value check while parsing tcp-request/tcp-response + - BUG/MINOR: http: Missing calloc return value check while parsing tcp-request rule + - BUG/MINOR: compression: Missing calloc return value check in comp_append_type/algo + - BUG/MINOR: worker: Missing calloc return value check in mworker_env_to_proc_list + - BUG/MINOR: http: Missing calloc return value check while parsing redirect rule + - BUG/MINOR: http: Missing calloc return value check in make_arg_list + - BUG/MINOR: proxy: Missing calloc return value check in chash_init_server_tree + - CLEANUP: http-ana: Remove useless if statement about L7 retries + - BUG/MAJOR: stream-int: Release SI endpoint on server side ASAP on retry + - MINOR: backend: Don't release SI endpoint anymore in connect_server() + - BUG/MINOR: vars: Be sure to have a session to get checks variables + - DOC/MINOR: move uuid in the configuration to the right alphabetical order + - CLEANUP: mux-fcgi: Don't needlessly store result of data/trailers parsing + - BUILD: fix compilation for OpenSSL-3.0.0-alpha17 + - MINOR: http-ana: Use -1 status for client aborts during queuing and connect + - REGTESTS: Fix http_abortonclose.vtc to support -1 status for some client aborts + - CLEANUP: backend: fix incorrect comments on locking conditions for lb functions + - CLEANUP: reg-tests: Remove obsolete no-htx parameter for reg-tests + - CI: github actions: add OpenSSL-3.0.0 builds + - CI: github actions: -Wno-deprecated-declarations with OpenSSL 3.0.0 + - MINOR: errors: allow empty va_args for diag variadic macro + - REORG: errors: split errors reporting function from log.c + - CLEANUP: server: fix cosmetic of error message on sni parsing + - MEDIUM: errors: implement user messages buffer + - MINOR: log: do not discard stderr when starting is over + - MEDIUM: errors: implement parsing context type + - MINOR: errors: use user messages context in print_message + - MINOR: log: display exec path on first warning + - MINOR: errors: specify prefix "config" for parsing output + - MINOR: log: define server user message format + - REORG: server: use parsing ctx for server parsing + - REORG: config: use parsing ctx for server config check + - MINOR: server: use parsing ctx for server init addr + - MINOR: server: use ha_alert in server parsing functions + - DOC: use the req.ssl_sni in examples + - CLEANUP: cfgparse: Remove duplication of `MAX_LINE_ARGS + 1` + - CLEANUP: tools: Make errptr const in `parse_line()` + - MINOR: haproxy: Add `-cc` argument + - BUG: errors: remove printf positional args for user messages context + - CI: Make matrix.py executable and add shebang + - BUILD: make tune.ssl.keylog available again + - BUG/MINOR: ssl: OCSP stapling does not work if expire too far in the future + - Revert "BUG/MINOR: opentracing: initialization after establishing daemon mode" + - BUG/MEDIUM: opentracing: initialization before establishing daemon and/or chroot mode + - SCRIPTS: opentracing: enable parallel builds in build-ot.sh + - BUG/MEDIUM: compression: Fix loop skipping unused blocks to get the next block + - BUG/MEDIUM: compression: Properly get the next block to iterate on payload + - BUG/MEDIUM: compression: Add a flag to know the filter is still processing data + - MINOR: ssl: Keep the actual key length in the certificate_ocsp structure + - MINOR: ssl: Add new "show ssl ocsp-response" CLI command + - MINOR: ssl: Add the OCSP entry key when displaying the details of a certificate + - MINOR: ssl: Add the "show ssl cert foo.pem.ocsp" CLI command + - REGTESTS: ssl: Add "show ssl ocsp-response" test + - BUG/MINOR: server: explicitly set "none" init-addr for dynamic servers + - BUG/MINOR: pools: fix a possible memory leak in the lockless pool_flush() + - BUG/MINOR: pools: make DEBUG_UAF always write to the to-be-freed location + - MINOR: pools: do not maintain the lock during pool_flush() + - MINOR: pools: call malloc_trim() under thread isolation + - MEDIUM: pools: use a single pool_gc() function for locked and lockless + - BUG/MAJOR: pools: fix possible race with free() in the lockless variant + - CLEANUP: pools: remove now unused seq and pool_free_list + - MEDIUM: pools: remove the locked pools implementation + - BUILD: ssl: Fix compilation with BoringSSL + - BUG/MEDIUM: errors: include missing obj_type file + - REGTESTS: ssl: show_ssl_ocspresponce.vtc is broken with BoringSSL + - BUG/MAJOR: htx: Fix htx_defrag() when an HTX block is expanded + - BUG/MINOR: mux-fcgi: Expose SERVER_SOFTWARE parameter by default + - BUG/MINOR: h1-htx: Fix a signess bug with char data type when parsing chunk size + - CLEANUP: l7-retries: do not test the buffer before calling b_alloc() + - BUG/MINOR: resolvers: answser item list was randomly purged or errors + - MEDIUM: resolvers: add a ref on server to the used A/AAAA answer item + - MEDIUM: resolvers: add a ref between servers and srv request or used SRV record + - BUG/MINOR: server-state: load SRV resolution only if params match the config + - MINOR: config: remove support for deprecated option "tune.chksize" + - MINOR: config: completely remove support for "no option http-use-htx" + - MINOR: log: remove the long-deprecated early log-format tags + - MINOR: http: remove the long deprecated "set-cookie()" sample fetch function + - MINOR: config: reject long-deprecated "option forceclose" + - MINOR: config: remove deprecated option "http-tunnel" + - MEDIUM: proxy: remove the deprecated "grace" keyword + - MAJOR: config: remove parsing of the global "nbproc" directive + - BUILD: init: remove initialization of multi-process thread mappings + - BUILD: log: remove unused fmt_directive() + - REGTESTS: Remove REQUIRE_VERSION=1.6 from all tests + - REGTESTS: Remove REQUIRE_VERSION=1.7 from all tests + - CI: github actions: enable alpine/musl builds + - BUG/MAJOR: resolvers: segfault using server template without SRV RECORDs + - DOC: lua: Add a warning about buffers modification in HTTP + - MINOR: ssl: Use OpenSSL's ASN1_TIME convertor when available + - BUG/MINOR: stick-table: insert srv in used_name tree even with fixed id + - BUG/MEDIUM: server: extend thread-isolate over much of CLI 'add server' + - BUG/MEDIUM: server: clear dynamic srv on delete from proxy id/name trees + - BUG/MEDIUM: server: do not forget to generate the dynamic servers ids + - BUG/MINOR: server: do not keep an invalid dynamic server in px ids tree + - BUG/MEDIUM: server: do not auto insert a dynamic server in px addr_node + - BUG/MEDIUM: shctx: use at least thread-based locking on USE_PRIVATE_CACHE + - BUG/MINOR: ssl: use atomic ops to update global shctx stats + - BUG/MINOR: mworker: fix typo in chroot error message + - CLEANUP: global: remove unused definition of stopping_task[] + - MEDIUM: init: remove the loop over processes during init + - MINOR: mworker: remove the initialization loop over processes + - CLEANUP: global: remove the nbproc field from the global structure + - CLEANUP: global: remove pid_bit and all_proc_mask + - MEDIUM: global: remove dead code from nbproc/bind_proc removal + - MEDIUM: config: simplify cpu-map handling + - MEDIUM: cpu-set: make the proc a single bit field and not an array + - CLEANUP: global: remove unused definition of MAX_PROCS + - MEDIUM: global: remove the relative_pid from global and mworker + - DOC: update references to process numbers in cpu-map and bind-process + - MEDIUM: config: warn about "bind-process" deprecation + - CLEANUP: shctx: remove the different inter-process locking techniques + - BUG/MAJOR: queue: set SF_ASSIGNED when setting strm->target on dequeue + - MINOR: backend: only skip LB when there are actual connections + - BUG/MINOR: mux-h1: do not skip the error response on bad requests + - MINOR: connection: add helper conn_append_debug_info() + - MINOR: mux-h2/trace: report a few connection-level info during h2_init() + - CLEANUP: mux-h2/traces: better align user messages + - BUG/MINOR: stats: make "show stat typed desc" work again + - MINOR: mux-h2: obey http-ignore-probes during the preface + - BUG/MINOR: mux-h2/traces: bring back the lost "rcvd H2 REQ" trace + - BUG/MINOR: mux-h2/traces: bring back the lost "sent H2 REQ/RES" traces + - CLEANUP: assorted typo fixes in the code and comments + - CI: Replace the requirement for 'sudo' with a call to 'ulimit -n' + - REGTESTS: Replace REQUIRE_VERSION=2.5 with 'haproxy -cc' + - REGTESTS: Replace REQUIRE_OPTIONS with 'haproxy -cc' for 2.5+ tests + - REGTESTS: Replace REQUIRE_BINARIES with 'command -v' + - REGTESTS: Remove support for REQUIRE_BINARIES + - CI: ssl: enable parallel builds for OpenSSL on Linux + - CI: ssl: do not needlessly build the OpenSSL docs + - CI: ssl: keep the old method for ancient OpenSSL versions + - CLEANUP: server: a separate function for initializing the per_thr field + - BUG/MINOR: server: Forbid to set fqdn on the CLI if SRV resolution is enabled + - BUG/MEDIUM: server/cli: Fix ABBA deadlock when fqdn is set from the CLI + - MINOR: resolvers: Clean server in a dedicated function when removing a SRV item + - MINOR: resolvers: Remove server from named_servers tree when removing a SRV item + - BUG/MEDIUM: resolvers: Add a task on servers to check SRV resolution status + - BUG/MINOR: backend: restore the SF_SRV_REUSED flag original purpose + - BUG/MINOR: backend: do not set sni on connection reuse + - BUG/MINOR: resolvers: Use resolver's lock in resolv_srvrq_expire_task() + - BUG/MINOR: server/cli: Fix locking in function processing "set server" command + - BUG/MINOR: cache: Correctly handle existing-but-empty 'accept-encoding' header + - MINOR: ssl: fix typo in usage for 'new ssl ca-file' + - MINOR: ssl: always initialize random generator + - MINOR: ssl: check allocation in ssl_sock_init_srv + - MINOR: ssl: check allocation in parse ciphers/ciphersuites/verifyhost + - MINOR: ssl: check allocation in parse npn/sni + - MINOR: server: disable CLI 'set server ssl' for dynamic servers + - MINOR: ssl: render file-access optional on server crt loading + - MINOR: ssl: split parse functions for alpn/check-alpn + - MINOR: ssl: support ca-file arg for dynamic servers + - MINOR: ssl: support crt arg for dynamic servers + - MINOR: ssl: support crl arg for dynamic servers + - MINOR: ssl: enable a series of ssl keywords for dynamic servers + - MINOR: ssl: support ssl keyword for dynamic servers + - REGTESTS: server: test ssl support for dynamic servers + - MINOR: queue: update the stream's pend_pos before queuing it + - CLEANUP: Prevent channel-t.h from being detected as C++ by GitHub + - BUG/MAJOR: server: fix deadlock when changing maxconn via agent-check + - REGTESTS: fix maxconn update with agent-check + - MEDIUM: queue: make pendconn_process_next_strm() only return the pendconn + - MINOR: queue: update proxy->served once out of the loop + - MEDIUM: queue: refine the locking in process_srv_queue() + - MINOR: lb/api: remove the locked argument from take_conn/drop_conn + - MINOR: queue: create a new structure type "queue" + - MINOR: proxy: replace the pendconns-related stuff with a struct queue + - MINOR: server: replace the pendconns-related stuff with a struct queue + - MEDIUM: queue: use a dedicated lock for the queues + - MEDIUM: queue: simplify again the process_srv_queue() API + - MINOR: queue: factor out the proxy/server queuing code + - MINOR: queue: use atomic-ops to update the queue's index + - MEDIUM: queue: determine in process_srv_queue() if the proxy is usable + - MEDIUM: queue: move the queue lock manipulation to pendconn_process_next_strm() + - MEDIUM: queue: unlock as soon as possible + - MINOR: queue: make pendconn_first() take the lock by itself + - CLEANUP: backend: remove impossible case of round-robin + consistent hash + - MINOR: tcp-act: Add set-src/set-src-port for "tcp-request content" rules + - DOC: config: Add missing actions in "tcp-request session" documentation + - CLEANUP: dns: Remove a forgotten debug message + - DOC: Replace issue templates by issue forms + - Revert "MINOR: queue: make pendconn_first() take the lock by itself" + - Revert "MEDIUM: queue: unlock as soon as possible" + - Revert "MEDIUM: queue: move the queue lock manipulation to pendconn_process_next_strm()" + - Revert "MEDIUM: queue: determine in process_srv_queue() if the proxy is usable" + - Revert "MINOR: queue: use atomic-ops to update the queue's index" + - Revert "MINOR: queue: factor out the proxy/server queuing code" + - Revert "MEDIUM: queue: simplify again the process_srv_queue() API" + - Revert "MEDIUM: queue: use a dedicated lock for the queues" + - Revert "MEDIUM: queue: refine the locking in process_srv_queue()" + - Revert "MINOR: queue: update proxy->served once out of the loop" + - Revert "MEDIUM: queue: make pendconn_process_next_strm() only return the pendconn" + - MEDIUM: queue: update px->served and lb's take_conn once per loop + - MEDIUM: queue: use a dedicated lock for the queues (v2) + - MEDIUM: queue: simplify again the process_srv_queue() API (v2) + - MEDIUM: queue: determine in process_srv_queue() if the proxy is usable (v2) + - MINOR: queue: factor out the proxy/server queuing code (v2) + - MINOR: queue: use atomic-ops to update the queue's index (v2) + - MEDIUM: queue: take the proxy lock only during the px queue accesses + - MEDIUM: queue: use a trylock on the server's queue + - MINOR: queue: add queue_init() to initialize a queue + - MINOR: queue: add a pointer to the server and the proxy in the queue + - MINOR: queue: store a pointer to the queue into the pendconn + - MINOR: queue: remove the px/srv fields from pendconn + - MINOR: queue: simplify pendconn_unlink() regarding srv vs px + - BUG: backend: stop looking for queued connections once there's no more + - BUG/MINOR: queue/debug: use the correct lock labels on the queue lock + - BUG/MINOR: resolvers: Always attach server on matching record on resolution + - BUG/MINOR: resolvers: Reset server IP when no ip is found in the response + - MINOR: resolvers: Reset server IP on error in resolv_get_ip_from_response() + - BUG/MINOR: checks: return correct error code for srv_parse_agent_check + - BUILD: Makefile: fix linkage for Haiku. + - BUG/MINOR: tcpcheck: Fix numbering of implicit HTTP send/expect rules + - MINOR: http-act/tcp-act: Add "set-log-level" for tcp content rules + - MINOR: http-act/tcp-act: Add "set-nice" for tcp content rules + - MINOR: http-act/tcp-act: Add "set-mark" and "set-tos" for tcp content rules + - CLEANUP: tcp-act: Sort action lists + - BUILD/MEDIUM: tcp: set-mark setting support for FreeBSD. + - BUILD: tcp-act: avoid warning when set-mark / set-tos are not supported + - BUG/MINOR: mqtt: Fix parser for string with more than 127 characters + - BUG/MINOR: mqtt: Support empty client ID in CONNECT message + - BUG/MEDIUM: resolvers: Make 1st server of a template take part to SRV resolution + - CLEANUP: peers: re-write intdecode function comment. + +2021/05/14 : 2.5-dev0 + - MINOR: version: it's development again + +2021/05/14 : 2.4.0 + - BUG/MINOR: http_fetch: fix possible uninit sockaddr in fetch_url_ip/port + - CLEANUP: cli/activity: Remove double spacing in set profiling command + - CI: Build VTest with clang + - CI: extend spellchecker whitelist, add "ists" as well + - CLEANUP: assorted typo fixes in the code and comments + - BUG/MINOR: memprof: properly account for differences for realloc() + - MINOR: memprof: also report the method used by each call + - MINOR: memprof: also report the totals and delta alloc-free + - CLEANUP: pattern: remove the unused and dangerous pat_ref_reload() + - BUG/MINOR: http_act: Fix normalizer names in error messages + - MINOR: uri_normalizer: Add `fragment-strip` normalizer + - MINOR: uri_normalizer: Add `fragment-encode` normalizer + - IMPORT: slz: use the generic function for the last bytes of the crc32 + - IMPORT: slz: do not produce the crc32_fast table when CRC is natively supported + - BUILD/MINOR: opentracing: fixed compilation with filter enabled + - BUILD: makefile: add a few popular ARMv8 CPU targets + - BUG/MEDIUM: stick_table: fix crash when using tcp smp_fetch_src + - REGTESTS: stick-table: add src_conn_rate test + - CLEANUP: stick-table: remove a leftover of an old keyword declaration + - BUG/MINOR: stats: fix lastchk metric that got accidently lost + - EXAMPLES: add a "basic-config-edge" example config + - EXAMPLES: add a trivial config for quick testing + - DOC: management: Correct example reload command in the document + - Revert "CI: Build VTest with clang" + - MINOR: activity/cli: optionally support sorting by address on "show profiling" + - DEBUG: ssl: export ssl_sock_close() to see its symbol resolved in profiling + - BUG/MINOR: lua/vars: prevent get_var() from allocating a new name + - DOC: config: Fix configuration example for mqtt + - BUG/MAJOR: config: properly initialize cpu_map.thread[] up to MAX_THREADS + - BUILD: config: avoid a build warning on numa_detect_topology() without threads + - DOC: update min requirements in INSTALL + - IMPORT: slz: use inttypes.h instead of stdint.h + - BUILD: sample: use strtoll() instead of atoll() + - MINOR: version: mention that it's LTS now. + +2021/05/10 : 2.4-dev19 + - BUG/MINOR: hlua: Don't rely on top of the stack when using Lua buffers + - BUG/MEDIUM: cli: prevent memory leak on write errors + - BUG/MINOR: ssl/cli: fix a lock leak when no memory available + - MINOR: debug: add a new "debug dev sym" command in expert mode + - MINOR: pools/debug: slightly relax DEBUG_DONT_SHARE_POOLS + - CI: Github Actions: switch to LibreSSL-3.3.3 + - MINOR: srv: close all idle connections on shutdown + - MINOR: connection: move session_list member in a union + - MEDIUM: mux_h1: release idling frontend conns on soft-stop + - MEDIUM: connection: close front idling connection on soft-stop + - MINOR: tools: add functions to retrieve the address of a symbol + - CLEANUP: activity: mark the profiling and task_profiling_mask __read_mostly + - MINOR: activity: add a "memory" entry to "profiling" + - MINOR: activity: declare the storage for memory usage statistics + - MEDIUM: activity: collect memory allocator statistics with USE_MEMORY_PROFILING + - MINOR: activity: clean up the show profiling io_handler a little bit + - MINOR: activity: make "show profiling" support a few arguments + - MINOR: activity: make "show profiling" also dump the memoery usage + - MINOR: activity: add the profiling.memory global setting + - BUILD: makefile: add new option USE_MEMORY_PROFILING + - MINOR: channel: Rely on HTX version if appropriate in channel_may_recv() + - BUG/MINOR: stream-int: Don't block reads in si_update_rx() if chn may receive + - MINOR: conn-stream: Force mux to wait for read events if abortonclose is set + - MEDIUM: mux-h1: Don't block reads when waiting for the other side + - BUG/MEDIUM: mux-h1: Properly report client close if abortonclose option is set + - REGTESTS: Add script to test abortonclose option + - MINOR: mux-h1: clean up conditions to enabled and disabled splicing + - MINOR: mux-h1: Subscribe for sends if output buffer is not empty in h1_snd_pipe + - MINOR: mux-h1: Always subscribe for reads when splicing is disabled + - MEDIUM: mux-h1: Wake H1 stream when both sides a synchronized + - CLEANUP: mux-h1: rename WAIT_INPUT/WAIT_OUTPUT flags + - MINOR: mux-h1: Manage processing blocking flags on the H1 stream + - BUG/MINOR: stream: Decrement server current session counter on L7 retry + - BUG/MINOR: config: fix uninitialized initial state in ".if" block evaluator + - BUG/MINOR: config: add a missing "ELIF_TAKE" test for ".elif" condition evaluator + - BUG/MINOR: config: .if/.elif should also accept negative integers + - MINOR: config: centralize the ".if"/".elif" condition parser and evaluator + - MINOR: config: keep up-to-date current file/line/section in the global struct + - MINOR: config: support some pseudo-variables for file/line/section + - BUILD: activity: do not include malloc.h + - MINOR: arg: improve the error message on missing closing parenthesis + - MINOR: global: export the build features string list + - MINOR: global: add version comparison functions + - MINOR: config: improve .if condition error reporting + - MINOR: config: make cfg_eval_condition() support predicates with arguments + - MINOR: config: add predicate "defined()" to conditional expression blocks + - MINOR: config: add predicates "streq()" and "strneq()" to conditional expressions + - MINOR: config: add predicate "feature" to detect certain built-in features + - MINOR: config: add predicates "version_atleast" and "version_before" to cond blocks + - BUG/MINOR: activity: use the new pointer to calculate the new size in realloc() + - BUG/MINOR: stream: properly clear the previous error mask on L7 retries + - MEDIUM: log: slightly refine the output format of alerts/warnings/etc + - MINOR: config: add a new message directive: .diag + - CLEANUP: cli/tree-wide: properly re-align the CLI commands' help messages + - BUG/MINOR: stream: Reset stream final state and si error type on L7 retry + - BUG/MINOR: checks: Handle synchronous connect when a tcpcheck is started + - BUG/MINOR: checks: Reschedule check on observe mode only if fastinter is set + - MINOR: global: define tainted flag + - MINOR: cfgparse: add a new field flags in cfg_keyword + - MINOR: cfgparse: implement experimental config keywords + - MINOR: action: replace match_pfx by a keyword flags field + - MINOR: action: implement experimental actions + - MINOR: cli: set tainted when using CLI expert/experimental mode + - MINOR: stats: report tainted on show info + - MINOR: http_act: mark normalize-uri as experimental + - BUILD: fix usage of ha_alert without format string + - MINOR: proxy: define PR_CAP_LB + - BUG/MINOR: server: do not report diag for peer servers with null weight + - DOC: ssl: Extra files loading now works for backends too + - ADDONS: make addons/ discoverable by git via .gitignore + - DOC: ssl: Add information about crl-file option + - MINOR: sample: improve error reporting on missing arg to strcmp() converter + - DOC: management: mention that some fields may be emitted as floats + - MINOR: tools: implement trimming of floating point numbers + - MINOR: tools: add a float-to-ascii conversion function + - MINOR: freq_ctr: add new functions to report float measurements + - MINOR: stats: avoid excessive padding of float values with trailing zeroes + - MINOR: stats: add the HTML conversion for float types + - MINOR: stats: pass the appctx flags to stats_fill_info() + - MINOR: stats: support an optional "float" option to "show info" + - MINOR: stats: use tv_remain() to precisely compute the uptime + - MINOR: stats: report uptime and start time as floats with subsecond resolution + - MINOR: stats: make "show info" able to report rates as floats when asked + - MINOR: config: mark tune.fd.edge-triggered as experimental + - REORG: vars: move the "proc" scope variables out of the global struct + - REORG: threads: move all_thread_mask() to thread.h + - BUILD: wdt: include signal-t.h + - BUILD: auth: include missing list.h + - REORG: mworker: move proc_self from global to mworker + - BUILD: ssl: ssl_utils requires chunk.h + - BUILD: config: cfgparse-ssl.c needs tools.h + - BUILD: wurfl: wurfl.c needs tools.h + - BUILD: spoe: flt_spoe.c needs tools.h + - BUILD: promex: service-prometheus.c needs tools.h + - BUILD: resolvers: include tools.h + - BUILD: config: include tools.h in cfgparse-listen.c + - BUILD: htx: include tools.h in http_htx.c + - BUILD: proxy: include tools.h in proxy.c + - BUILD: session: include tools.h in session.c + - BUILD: cache: include tools.h in cache.c + - BUILD: sink: include tools.h in sink.c + - BUILD: connection: include tools.h in connection.c + - BUILD: server-state: include tools.h from server_state.c + - BUILD: dns: include tools.h in dns.c + - BUILD: payload: include tools.h in payload.c + - BUILD: vars: include tools.h in vars.c + - BUILD: compression: include tools.h in compression.c + - BUILD: mworker: include tools.h from mworker.c + - BUILD: queue: include tools.h from queue.c + - BUILD: udp: include tools.h from proto_udp.c + - BUILD: stick-table: include freq_ctr.h from stick_table.h + - BUILD: server: include tools.h from server.c + - BUILD: server: include missing proxy.h in server.c + - BUILD: sink: include proxy.h in sink.c + - BUILD: mworker: include proxy.h in mworker.c + - BUILD: filters: include proxy.h in filters.c + - BUILD: fcgi-app: include proxy.h in fcgi-app.c + - BUILD: connection: move list_mux_proto() to connection.c + - REORG: stick-table: uninline stktable_alloc_data_type() + - REORG: stick-table: move composite address functions to stick_table.h + - REORG: config: uninline warnifnotcap() and failifnotcap() + - BUILD: task: remove unused includes from task.c + - MINOR: task: stop including stream.h from task.c + - BUILD: connection: stop including listener-t.h + - BUILD: hlua: include proxy.h from hlua.c + - BUILD: mux-h1: include proxy.h from mux-h1.c + - BUILD: mux-fcgi: include proxy.h from mux-fcgi.c + - BUILD: listener: include proxy.h from listener.c + - BUILD: http-rules: include proxy.h from http_rules.c + - BUILD: thread: include log.h from thread.c + - BUILD: comp: include proxy.h from flt_http_comp.c + - BUILD: fd: include log.h from fd.c + - BUILD: config: do not include proxy.h nor errors.h anymore in cfgparse.h + - BUILD: makefile: reorder object files by build time + - DOC: Fix a few grammar/spelling issues and casing of HAProxy + - REGTESTS: run-regtests: match both "HAProxy" and "HA-Proxy" in the version + - MINOR: version: report "HAProxy" not "HA-Proxy" in the version output + - DOC: remove last occurrences of "HA-Proxy" syntax + - DOC: peers: fix the protocol tag name in the doc + - ADMIN: netsnmp: report "HAProxy" and not "Haproxy" in output descriptions + - MEDIUM: mailers: use "HAProxy" nor "HAproxy" in the subject of messages + - DOC: fix a few remainig cases of "Haproxy" and "HAproxy" in doc and comments + - MINOR: tools/rnd: compute the result outside of the CAS loop + - BUILD: http_fetch: address a few aliasing warnings with older compilers + - BUILD: ssl: define HAVE_CRYPTO_memcmp() based on the library version + - BUILD: errors: include stdarg in errors.h + - REGTESTS: disable inter-thread idle connection sharing on sensitive tests + - MINOR: cli: make "help" support a command in argument + - MINOR: cli: sort the output of the "help" keywords + - CLEANUP: cli/mworker: properly align the help messages + - BUILD: memprof: make the old caller pointer a const in get_prof_bin() + - BUILD: compat: include malloc_np.h for USE_MEMORY_PROFILING on FreeBSD + - CI: Github Actions: enable USE_QUIC=1 for BoringSSL builds + - BUG/MEDIUM: quic: fix null deref on error path in qc_conn_init() + - BUILD: cli: appease a null-deref warning in cli_gen_usage_msg() + +2021/05/01 : 2.4-dev18 + - DOC: Fix indentation for `path-strip-dot` normalizer + - DOC: Fix RFC reference for the percent-to-uppercase normalizer + - DOC: Add RFC references for the path-strip-dot(dot)? normalizers + - MINOR: uri_normalizer: Add a `percent-decode-unreserved` normalizer + - BUG/MINOR: mux-fcgi: Don't send normalized uri to FCGI application + - REORG: htx: Inline htx functions to add HTX blocks in a message + - CLEANUP: assorted typo fixes in the code and comments + - DOC: general: fix white spaces for HTML converter + - BUG/MINOR: ssl: ssl_sock_prepare_ssl_ctx does not return an error code + - BUG/MINOR: cpuset: move include guard at the very beginning + - BUG/MAJOR: fix build on musl with cpu_set_t support + - BUG/MEDIUM: cpuset: fix build on MacOS + - BUG/MINOR: htx: Preserve HTX flags when draining data from an HTX message + - MEDIUM: htx: Refactor htx_xfer_blks() to not rely on hdrs_bytes field + - CLEANUP: htx: Remove unsued hdrs_bytes field from the HTX start-line + - BUG/MINOR: mux-h2: Don't encroach on the reserve when decoding headers + - MEDIUM: http-ana: handle read error on server side if waiting for response + - MINOR: htx: Limit length of headers name/value when a HTX message is dumped + - BUG/MINOR: applet: Notify the other side if data were consumed by an applet + - BUG/MINOR: hlua: Don't consume headers when starting an HTTP lua service + - BUG/MEDIUM: mux-h2: Handle EOM flag when sending a DATA frame with zero-copy + - CLEANUP: channel: No longer notify the producer in co_skip()/co_htx_skip() + - DOC: general: fix example in set-timeout + - CLEANUP: cfgparse: de-uglify early file error handling in readcfgfile() + - MINOR: config: add a new "default-path" global directive + - BUG/MEDIUM: peers: initialize resync timer to get an initial full resync + - BUG/MEDIUM: peers: register last acked value as origin receiving a resync req + - BUG/MEDIUM: peers: stop considering ack messages teaching a full resync + - BUG/MEDIUM: peers: reset starting point if peers appears longly disconnected + - BUG/MEDIUM: peers: reset commitupdate value in new conns + - BUG/MEDIUM: peers: re-work updates lookup during the sync on the fly + - BUG/MEDIUM: peers: reset tables stage flags stages on new conns + - MINOR: peers: add informative flags about resync process for debugging + - BUG/MEDIUM: time: fix updating of global_now upon clock drift + - CLEANUP: freq_ctr: make arguments of freq_ctr_total() const + - CLEANUP: hlua: rename hlua_appctx* appctx to luactx + - MINOR: server: fix doc/trace on lb algo for dynamic server creation + - REGTESTS: server: fix cli_add_server due to previous trace update + - REGTESTS: add minimal CLI "add map" tests + - DOC: management: move "set var" to the proper place + - CLEANUP: map: slightly reorder the add map function + - MINOR: map: get rid of map_add_key_value() + - MINOR: map: show the current and next pattern version in "show map" + - MINOR: map/acl: add the possibility to specify the version in "show map/acl" + - MINOR: pattern: support purging arbitrary ranges of generations + - MINOR: map/acl: add the possibility to specify the version in "clear map/acl" + - MINOR: map/acl: add the "prepare map/acl" CLI command + - MINOR: map/acl: add the "commit map/acl" CLI command + - MINOR: map/acl: make "add map/acl" support an optional version number + - CLEANUP: map/cli: properly align the map/acl help + - BUILD: compiler: do not use already defined __read_mostly on dragonfly + +2021/04/23 : 2.4-dev17 + - MINOIR: mux-pt/trace: Register a new trace source with its events + - BUG/MINOR: mux-pt: Fix a possible UAF because of traces in mux_pt_io_cb + - CI: travis: Drastically clean up .travis.yml + - CLEANUP: pattern: make all pattern tables read-only + - MINOR: trace: replace the trace() inline function with an equivalent macro + - MINOR: initcall: uniformize the section names between MacOS and other unixes + - CLEANUP: initcall: rename HA_SECTION to HA_INIT_SECTION + - MINOR: compiler: add macros to declare section names + - CLEANUP: initcall: rely on HA_SECTION_* instead of defining its own + - MINOR: global: declare a read_mostly section + - MINOR: fd: move a few read-mostly variables to their own section + - MINOR: epoll: move epoll_fd to read_mostly + - MINOR: kqueue: move kqueue_fd to read_mostly + - MINOR: pool: move pool declarations to read_mostly + - MINOR: threads: mark all_threads_mask as read_mostly + - MINOR: server: move idle_conn_task to read_mostly + - MINOR: protocol: move __protocol_by_family to read_mostly + - MINOR: pattern: make the pat_lru_seed read_mostly + - MINOR: trace: make trace sources read_mostly + - MINOR: freq_ctr: add a generic function to report the total value + - MEDIUM: freq_ctr: make read_freq_ctr_period() use freq_ctr_total() + - MEDIUM: freq_ctr: reimplement freq_ctr_remain_period() from freq_ctr_total() + - MINOR: freq_ctr: add the missing next_event_delay_period() + - MINOR: freq_ctr: unify freq_ctr and freq_ctr_period into freq_ctr + - MEDIUM: freq_ctr: replace the per-second counters with the generic ones + - MINOR: freq_ctr: add cpu_relax in the rotation loop of update_freq_ctr_period() + - MINOR: freq_ctr: simplify and improve the update function + - CLEANUP: time: remove the now unused ms_left_scaled + - MINOR: time: move the time initialization out of tv_update_date() + - MINOR: time: remove useless variable copies in tv_update_date() + - MINOR: time: change the global timeval and the the global tick at once + - MEDIUM: time: make the clock offset global and no per-thread + - MINOR: atomic: reimplement the relaxed version of x86 BTS/BTR + - MINOR: trace: Add the checks as a possible trace source + - MINOIR: checks/trace: Register a new trace source with its events + - MINOR: hlua: Add function to release a lua function + - BUG/MINOR: hlua: Fix memory leaks on error path when registering a task + - BUG/MINOR: hlua: Fix memory leaks on error path when registering a converter + - BUG/MINOR: hlua: Fix memory leaks on error path when registering a fetch + - BUG/MINOR: hlua: Fix memory leaks on error path when parsing a lua action + - BUG/MINOR: hlua: Fix memory leaks on error path when registering an action + - BUG/MINOR: hlua: Fix memory leaks on error path when registering a service + - BUG/MINOR: hlua: Fix memory leaks on error path when registering a cli keyword + - BUG/MINOR: cfgparse/proxy: Fix some leaks during proxy section parsing + - BUG/MINOR: listener: Handle allocation error when allocating a new bind_conf + - BUG/MINOR: cfgparse/proxy: Hande allocation errors during proxy section parsing + - MINOR: cfgparse/proxy: Group alloc error handling during proxy section parsing + - DOC: internals: update the SSL architecture schema + - BUG/MEDIUM: sample: Fix adjusting size in field converter + - MINOR: sample: add ub64dec and ub64enc converters + - CLEANUP: sample: align samples list in sample.c + - MINOR: ist: Add `istclear(struct ist*)` + - CI: cirrus: install "pcre" package + - MINOR: opentracing: correct calculation of the number of arguments in the args[] + - MINOR: opentracing: transfer of context names without prefix + - MINOR: sample: converter: Add mjson library. + - MINOR: sample: converter: Add json_query converter + - CI: travis-ci: enable weekly graviton2 builds + - DOC: ssl: Certificate hot update only works on fronted certificates + - DOC: ssl: Certificate hot update works on server certificates + - BUG/MEDIUM: threads: Ignore current thread to end its harmless period + - MINOR: threads: Only consider running threads to end a thread harmeless period + - BUG/MINOR: checks: Set missing id to the dummy checks frontend + - MINOR: logs: Add support of checks as session origin to format lf strings + - BUG/MINOR: connection: Fix fc_http_major and bc_http_major for TCP connections + - MINOR: connection: Make bc_http_major compatible with tcp-checks + - BUG/MINOR: ssl-samples: Fix ssl_bc_* samples when called from a health-check + - BUG/MINOR: http-fetch: Make method smp safe if headers were already forwarded + - MINOR: tcp_samples: Add samples to get src/dst info of the backend connection + - MINOR: tcp_samples: Be able to call bc_src/bc_dst from the health-checks + - BUG/MINOR: http_htx: Remove BUG_ON() from http_get_stline() function + - BUG/MINOR: logs: Report the true number of retries if there was no connection + - BUILD: makefile: Redirect stderr to /dev/null when probing options + - MINOR: uri_normalizer: Add uri_normalizer module + - MINOR: uri_normalizer: Add `enum uri_normalizer_err` + - MINOR: uri_normalizer: Add `http-request normalize-uri` + - MINOR: uri_normalizer: Add a `merge-slashes` normalizer to http-request normalize-uri + - MINOR: uri_normalizer: Add a `dotdot` normalizer to http-request normalize-uri + - MINOR: uri_normalizer: Add support for supressing leading `../` for dotdot normalizer + - MINOR: uri_normalizer: Add a `sort-query` normalizer + - MINOR: uri_normalizer: Add a `percent-upper` normalizer + - MEDIUM: http_act: Rename uri-normalizers + - DOC: Add introduction to http-request normalize-uri + - DOC: Note that URI normalization is experimental + - BUG/MINOR: pools: maintain consistent ->allocated count on alloc failures + - BUG/MINOR: pools/buffers: make sure to always reserve the required buffers + - MINOR: pools: drop the unused static history of artificially failed allocs + - CLEANUP: pools: remove unused arguments to pool_evict_from_cache() + - MEDIUM: pools: move the cache into the pool header + - MINOR: pool: remove the size field from pool_cache_head + - MINOR: pools: rename CONFIG_HAP_LOCAL_POOLS to CONFIG_HAP_POOLS + - MINOR: pools: enable the fault injector in all allocation modes + - MINOR: pools: make the basic pool_refill_alloc()/pool_free() update needed_avg + - MEDIUM: pools: unify pool_refill_alloc() across all models + - CLEANUP: pools: re-merge pool_refill_alloc() and __pool_refill_alloc() + - MINOR: pools: call pool_alloc_nocache() out of the pool's lock + - CLEANUP: pools: move the lock to the only __pool_get_first() that needs it + - CLEANUP: pools: rename __pool_get_first() to pool_get_from_shared_cache() + - CLEANUP: pools: rename pool_*_{from,to}_cache() to *_local_cache() + - CLEANUP: pools: rename __pool_free() to pool_put_to_shared_cache() + - MINOR: tools: add statistical_prng_range() to get a random number over a range + - MINOR: pools: use cheaper randoms for fault injections + - MINOR: pools: move the fault injector to __pool_alloc() + - MINOR: pools: split the OS-based allocator in two + - MINOR: pools: always use atomic ops to maintain counters + - MINOR: pools: move pool_free_area() out of the lock in the locked version + - MINOR: pools: factor the release code into pool_put_to_os() + - MEDIUM: pools: make CONFIG_HAP_POOLS control both local and shared pools + - MINOR: pools: create unified pool_{get_from,put_to}_cache() + - MINOR: pools: evict excess objects using pool_evict_from_local_cache() + - MEDIUM: pools: make pool_put_to_cache() always call pool_put_to_local_cache() + - CLEANUP: pools: make the local cache allocator fall back to the shared cache + - CLEANUP: pools: merge pool_{get_from,put_to}_local_caches with generic ones + - CLEANUP: pools: uninline pool_put_to_cache() + - CLEANUP: pools: declare dummy pool functions to remove some ifdefs + - BUILD: pools: fix build with DEBUG_FAIL_ALLOC + - BUG/MINOR: server: make srv_alloc_lb() allocate lb_nodes for consistent hash + - CONTRIB: mod_defender: import the minimal number of includes + - CONTRIB: mod_defender: make the code build with the embedded includes + - CONTRIB: modsecurity: import the minimal number of includes + - CONTRIB: modsecurity: make the code build with the embedded includes + - CLEANUP: sample: Improve local variables in sample_conv_json_query + - CLEANUP: sample: Explicitly handle all possible enum values from mjson + - CLEANUP: sample: Use explicit return for successful `json_query`s + - CLEANUP: lists/tree-wide: rename some list operations to avoid some confusion + - CONTRIB: move spoa_example out of the tree + - BUG/MINOR: server: free srv.lb_nodes in free_server + - BUG/MINOR: logs: free logsrv.conf.file on exit + - BUG/MEDIUM: server: ensure thread-safety of server runtime creation + - MINOR: server: add log on dynamic server creation + - MINOR: server: implement delete server cli command + - CONTRIB: move spoa_server out of the tree + - CONTRIB: move modsecurity out of the tree + - BUG/MINOR: server: fix potential null gcc error in delete server + - BUG/MAJOR: mux-h2: Properly detect too large frames when decoding headers + - BUG/MEDIUM: mux-h2: Fix dfl calculation when merging CONTINUATION frames + - BUG/MINOR: uri_normalizer: Use delim parameter when building the sorted query in uri_normalizer_query_sort + - CLEANUP: uri_normalizer: Remove trailing whitespace + - MINOR: uri_normalizer: Add a `strip-dot` normalizer + - CONTRIB: move mod_defender out of the tree + - CLEANUP: contrib: remove the last references to the now dead contrib/ directory + - BUG/MEDIUM: config: fix cpu-map notation with both process and threads + - MINOR: config: add a diag for invalid cpu-map statement + - BUG/MINOR: mworker/init: don't reset nb_oldpids in non-mworker cases + - BUG/MINOR: mworker: don't use oldpids[] anymore for reload + - BUILD: makefile: fix the "make clean" target on strict bourne shells + - IMPORT: slz: import slz into the tree + - BUILD: compression: switch SLZ from out-of-tree to in-tree + - CI: github: do not build libslz any more + - CLEANUP: compression: remove calls to SLZ init functions + - BUG/MEDIUM: mux-h2: Properly handle shutdowns when received with data + - MINOR: cpuset: define a platform-independent cpuset type + - MINOR: cfgparse: use hap_cpuset for parse_cpu_set + - MEDIUM: config: use platform independent type hap_cpuset for cpu-map + - MINOR: thread: implement the detection of forced cpu affinity + - MINOR: cfgparse: support the comma separator on parse_cpu_set + - MEDIUM: cfgparse: detect numa and set affinity if needed + - MINOR: global: add option to disable numa detection + - BUG/MINOR: haproxy: fix compilation on macOS + - BUG/MINOR: cpuset: fix compilation on platform without cpu affinity + - MINOR: time: avoid unneeded updates to now_offset + - MINOR: time: avoid overwriting the same values of global_now + - CLEANUP: time: use __tv_to_ms() in tv_update_date() instead of open-coding + - MINOR: time: avoid u64 needlessly expensive computations for the 32-bit now_ms + - BUG/MINOR: peers: remove useless table check if initial resync is finished + - BUG/MEDIUM: peers: re-work connection to new process during reload. + - BUG/MEDIUM: peers: re-work refcnt on table to protect against flush + - BUG/MEDIUM: config: fix missing initialization in numa_detect_topology() + +2021/04/09 : 2.4-dev16 + - CLEANUP: dev/flags: remove useless test in the stdin number parser + - MINOR: No longer rely on deprecated sample fetches for predefined ACLs + - MINOR: acl: Add HTTP_2.0 predefined macro + - BUG/MINOR: hlua: Detect end of request when reading data for an HTTP applet + - BUG/MINOR: tools: fix parsing "us" unit for timers + - MINOR: server/bind: add support of new prefixes for addresses. + - MINOR: log: register config file and line number on log servers. + - MEDIUM: log: support tcp or stream addresses on log lines. + - BUG/MEDIUM: log: fix config parse error logging on stdout/stderr or any raw fd + - CLEANUP: fd: remove FD_POLL_DATA and FD_POLL_STICKY + - MEDIUM: fd: prepare FD_POLL_* to move to bits 8-15 + - MEDIUM: fd: merge fdtab[].ev and state for FD_EV_* and FD_POLL_* into state + - MINOR: fd: move .linger_risk into fdtab[].state + - MINOR: fd: move .cloned into fdtab[].state + - MINOR: fd: move .initialized into fdtab[].state + - MINOR: fd: move .et_possible into fdtab[].state + - MINOR: fd: move .exported into fdtab[].state + - MINOR: fd: implement an exclusive syscall bit to remove the ugly "log" lock + - MINOR: cli/show-fd: slightly reorganize the FD status flags + - MINOR: atomic/arm64: detect and use builtins for the double-word CAS + - CLEANUP: atomic: add an explicit _FETCH variant for add/sub/and/or + - CLEANUP: atomic: make all standard add/or/and/sub operations return void + - CLEANUP: atomic: add a fetch-and-xxx variant for common operations + - CLEANUP: atomic: add HA_ATOMIC_INC/DEC for unit increments + - CLEANUP: atomic/tree-wide: replace single increments/decrements with inc/dec + - CLEANUP: atomic: use the __atomic variant of BTS/BTR on modern compilers + - MINOR: atomic: implement native BTS/BTR for x86 + - MINOR: ist: Add `istappend(struct ist, char)` + - MINOR: ist: Add `istshift(struct ist*)` + - MINOR: ist: Add `istsplit(struct ist*, char)` + - BUG/MAJOR: fd: switch temp values to uint in fd_stop_both() + - MINOR: opentracing: register config file and line number on log servers + - MEDIUM: resolvers: add support of tcp address on nameserver line. + - MINOR: ist: Rename istappend() to __istappend() + - CLEANUP: htx: Make http_get_stline take a `const struct` + - CLEANUP: ist: Remove unused `count` argument from `ist2str*` + - CLEANUP: Remove useless malloc() casts + +2021/04/02 : 2.4-dev15 + - BUG/MINOR: payload: Wait for more data if buffer is empty in payload/payload_lv + - BUG/MINOR: stats: Apply proper styles in HTML status page. + - BUG/MEDIUM: time: make sure to always initialize the global tick + - BUG/MINOR: tcp: fix silent-drop workaround for IPv6 + - BUILD: tcp: use IPPROTO_IPV6 instead of SOL_IPV6 on FreeBSD/MacOS + - CLEANUP: socket: replace SOL_IP/IPV6/TCP with IPPROTO_IP/IPV6/TCP + - BUG/MINOR: http_fetch: make hdr_ip() resistant to empty fields + - BUG/MINOR: mux-h2: Don't emit log twice if an error occurred on the preface + - MINOR: stream: Don't trigger errors on destructive HTTP upgrades + - MINOR: frontend: Create HTTP txn for HTX streams + - MINOR: stream: Be sure to set HTTP analysers when creating an HTX stream + - BUG/MINOR: stream: Properly handle TCP>H1>H2 upgrades in http_wait_for_request + - BUG/MINOR: config: Add warning for http-after-response rules in TCP mode + - MINOR: muxes: Add a flag to notify a mux does not support any upgrade + - MINOR: mux-h1: Don't perform implicit HTTP/2 upgrade if not supported by mux + - MINOR: mux-pt: Don't perform implicit HTTP upgrade if not supported by mux + - MEDIUM: mux-h1: Expose h1 in the list of supported mux protocols + - MEDIUM: mux-pt: Expose passthrough in the list of supported mux protocols + - MINOR: muxes: Show muxes flags when the mux list is displayed + - DOC: config: Improve documentation about proto/check-proto keywords + - MINOR: stream: Use stream type instead of proxy mode when appropriate + - MINOR: filters/http-ana: Decide to filter HTTP headers in HTTP analysers + - MINOR: http-ana: Simplify creation/destruction of HTTP transactions + - MINOR: stream: Handle stream HTTP upgrade in a dedicated function + - MEDIUM: Add tcp-request switch-mode action to perform HTTP upgrade + - MINOR: config/proxy: Don't warn for HTTP rules in TCP if 'switch-mode http' set + - MINOR: config/proxy: Warn if a TCP proxy without backend is upgradable to HTTP + - DOC: config: Add documentation about TCP to HTTP upgrades + - REGTESTS: Add script to tests TCP to HTTP upgrades + - BUG/MINOR: payload/htx: Ingore L6 sample fetches for HTX streams/checks + - MINOR: htx: Make internal.strm.is_htx an internal sample fetch + - MINOR: action: Use a generic function to check validity of an action rule list + - MINOR: payload/config: Warn if a L6 sample fetch is used from an HTTP proxy + - MEDIUM: http-rules: Add wait-for-body action on request and response side + - REGTESTS: Add script to tests the wait-for-body HTTP action + - BUG/MINOR: http-fetch: Fix test on message state to capture the version + - CLEANUP: vars: always pre-initialize smp in vars_parse_cli_get_var() + - MINOR: global: define diagnostic mode of execution + - MINOR: cfgparse: diag for multiple nbthread statements + - MINOR: server: diag for 0 weight server + - MINOR: diag: create cfgdiag module + - MINOR: diag: diag if servers use the same cookie value + - MINOR: config: diag if global section after non-global + - TESTS: slightly reorganize the code in the tests/ directory + - TESTS: move tests/*.cfg to tests/config + - REGTESTS: ssl: "set ssl cert" and multi-certificates bundle + - REGTESTS: ssl: mark set_ssl_cert_bundle.vtc as broken + - CONTRIB: halog: fix issue with array of type char + - CONTRIB: tcploop: add a shutr command + - CONTRIB: debug: add the show-fd-to-flags script + - CONTRIB: debug: split poll from flags + - CONTRIB: move some dev-specific tools to dev/ + - BUILD: makefile: always build the flags utility + - DEV: flags: replace the unneeded makefile with a README + - BUILD: makefile: integrate the hpack tools + - CONTRIB: merge ip6range with iprange + - CONTRIB: move some admin-related sub-projects to admin/ + - CONTRIB: move halog to admin/ + - ADMIN: halog: automatically enable USE_MEMCHR on the right glibc version + - BUILD: makefile: build halog with the correct flags + - BUILD: makefile: add a "USE_PROMEX" variable to ease building prometheus-exporter + - CONTRIB: move prometheus-exporter to addons/promex + - DOC: add a few words about USE_* and the addons directory + - CONTRIB: move 51Degrees to addons/51degrees + - CONTRIB: move src/da.c and contrib/deviceatlas to addons/deviceatlas + - CONTRIB: move src/wurfl.c and contrib/wurfl to addons/wurfl + - CONTRIB: move contrib/opentracing to addons/ot + - BUG/MINOR: opentracing: initialization after establishing daemon mode + - DOC: clarify that compression works for HTTP/2 + +2021/03/27 : 2.4-dev14 + - MEDIUM: quic: Fix build. + - MEDIUM: quic: Fix build. + - CI: codespell: whitelist "Dragan Dosen" + - CLEANUP: assorted typo fixes in the code and comments + - CI: github actions: update LibreSSL to 3.2.5 + - REGTESTS: revert workaround for a crash with recent libressl on http-reuse sni + - CLEANUP: mark defproxy as const on parse tune.fail-alloc + - REGTESTS: remove unneeded experimental-mode in cli add server test + - REGTESTS: wait for proper return of enable server in cli add server test + - MINOR: compression: use pool_alloc(), not pool_alloc_dirty() + - MINOR: spoe: use pool_alloc(), not pool_alloc_dirty() + - MINOR: fcgi-app: use pool_alloc(), not pool_alloc_dirty() + - MINOR: cache: use pool_alloc(), not pool_alloc_dirty() + - MINOR: ssl: use pool_alloc(), not pool_alloc_dirty() + - MINOR: opentracing: use pool_alloc(), not pool_alloc_dirty() + - MINOR: dynbuf: make b_alloc() always check if the buffer is allocated + - CLEANUP: compression: do not test for buffer before calling b_alloc() + - CLEANUP: l7-retries: do not test the buffer before calling b_alloc() + - MINOR: channel: simplify the channel's buffer allocation + - MEDIUM: dynbuf: remove last usages of b_alloc_margin() + - CLEANUP: dynbuf: remove b_alloc_margin() + - CLEANUP: dynbuf: remove the unused b_alloc_fast() function + - CLEANUP: pools: remove the unused pool_get_first() function + - MINOR: pools: make the pool allocator support a few flags + - MINOR: pools: add pool_zalloc() to return a zeroed area + - CLEANUP: connection: use pool_zalloc() in conn_alloc_hash_node() + - CLEANUP: filters: use pool_zalloc() in flt_stream_add_filter() + - CLEANUP: spoe: use pool_zalloc() instead of pool_alloc+memset + - CLEANUP: frontend: use pool_zalloc() in frontend_accept() + - CLEANUP: mailers: use pool_zalloc() in enqueue_one_email_alert() + - CLEANUP: resolvers: use pool_zalloc() in resolv_link_resolution() + - CLEANUP: ssl: use pool_zalloc() in ssl_init_keylog() + - CLEANUP: tcpcheck: use pool_zalloc() instead of pool_alloc+memset + - CLEANUP: quic: use pool_zalloc() instead of pool_alloc+memset + - MINOR: time: also provide a global, monotonic global_now_ms timer + - BUG/MEDIUM: freq_ctr/threads: use the global_now_ms variable + - MINOR: tools: introduce new option PA_O_DEFAULT_DGRAM on str2sa_range. + - BUILD: tools: fix build error with new PA_O_DEFAULT_DGRAM + - BUG/MINOR: ssl: Prevent disk access when using "add ssl crt-list" + - CLEANUP: ssl: remove unused definitions + - BUILD: ssl: guard ecdh functions with SSL_CTX_set_tmp_ecdh macro + - MINOR: lua: Slightly improve function dumping the lua traceback + - BUG/MEDIUM: debug/lua: Use internal hlua function to dump the lua traceback + - BUG/MEDIUM: lua: Always init the lua stack before referencing the context + - MINOR: fd: make fd_clr_running() return the remaining running mask + - MINOR: fd: remove the unneeded running bit from fd_insert() + - BUG/MEDIUM: fd: do not wait on FD removal in fd_delete() + - CLEANUP: fd: remove unused fd_set_running_excl() + - CLEANUP: fd: slightly simplify up _fd_delete_orphan() + - BUG/MEDIUM: fd: Take the fd_mig_lock when closing if no DWCAS is available. + - BUG/MEDIUM: release lock on idle conn killing on reached pool high count + - BUG/MEDIUM: thread: Fix a deadlock if an isolated thread is marked as harmless + - MINOR: tools: make url2ipv4 return the exact number of bytes parsed + - BUG/MINOR: http_fetch: make hdr_ip() reject trailing characters + - BUG/MEDIUM: mux-h1: make h1_shutw_conn() idempotent + - BUG/MINOR: ssl: Fix update of default certificate + - BUG/MINOR: ssl: Prevent removal of crt-list line if the instance is a default one + - BUILD: ssl: introduce fine guard for ssl random extraction functions + - REORG: global: move initcall register code in a dedicated file + - REORG: global: move free acl/action in their related source files + - REORG: split proxy allocation functions + - MINOR: proxy: implement a free_proxy function + - MINOR: proxy: define cap PR_CAP_LUA + - MINOR: lua: properly allocate the lua Socket proxy + - MINOR: lua: properly allocate the lua Socket servers + - MINOR: vars: make get_vars() allow the session to be null + - MINOR: vars: make the var() sample fetch keyword depend on nothing + - CLEANUP: sample: remove duplicate "stopping" sample fetch keyword + - MINOR: sample: make smp_resolve_args() return an allocate error message + - MINOR: sample: add a new SMP_SRC_CONST sample capability + - MINOR: sample: mark the truly constant sample fetch keywords as such + - MINOR: sample: add a new CFG_PARSER context for samples + - MINOR: action: add a new ACT_F_CFG_PARSER origin designation + - MEDIUM: vars: add support for a "set-var" global directive + - REGTESTS: add a basic reg-test for some "set-var" commands + - MINOR: sample: add a new CLI_PARSER context for samples + - MINOR: action: add a new ACT_F_CLI_PARSER origin designation + - MINOR: vars/cli: add a "get var" CLI command to retrieve global variables + - MEDIUM: cli: add a new experimental "set var" command + - MINOR: compat: add short aliases for a few very commonly used types + - BUILD: ssl: use EVP_CIPH_GCM_MODE macro instead of HA_OPENSSL_VERSION + - MEDIUM: backend: use a trylock to grab a connection on high FD counts as well + +2021/03/19 : 2.4-dev13 + - BUG/MEDIUM: cli: fix "help" crashing since recent spelling fixes + - BUG/MINOR: cfgparse: use the GLOBAL not LISTEN keywords list for spell checking + - MINOR: tools: improve word fingerprinting by counting presence + - MINOR: tools: do not sum squares of differences for word fingerprints + - MINOR: cli: improve fuzzy matching to work on all remaining words at once + - MINOR: cli: sort the suggestions by order of relevance + - MINOR: cli: limit spelling suggestions to 5 + - MINOR: cfgparse/proxy: also support spelling fixes on options + - BUG/MINOR: resolvers: Add missing case-insensitive comparisons of DNS hostnames + - MINOR: time: export the global_now variable + - BUG/MINOR: freq_ctr/threads: make use of the last updated global time + - MINOR: freq_ctr/threads: relax when failing to update a sliding window value + - MINOR/BUG: mworker/cli: do not use the unix_bind prefix for the master CLI socket + - MINOR: mworker/cli: alert the user if we enabled a master CLI but not the master-worker mode + - MINOR: cli: implement experimental-mode + - REORG: server: add a free server function + - MINOR: cfgparse: always alloc idle conns task + - REORG: server: move keywords in srv_kws + - MINOR: server: remove fastinter from mistyped kw list + - REORG: server: split parse_server + - REORG: server: move alert traces in parse_server + - REORG: server: rename internal functions from parse_server + - REORG: server: attach servers in parse_server + - REORG: server: use flags for parse_server + - MINOR: server: prepare parsing for dynamic servers + - MINOR: stats: export function to allocate extra proxy counters + - MEDIUM: server: implement 'add server' cli command + - REGTESTS: implement test for 'add server' cli + - MINOR: server: enable standard options for dynamic servers + - MINOR: server: support keyword proto in 'add server' cli + - BUG/MINOR: protocol: add missing support of dgram unix socket. + - CLEANUP: Fix a typo in fix_is_valid description + - MINOR: raw_sock: Add a close method. + - MEDIUM: connections: Introduce a new XPRT method, start(). + - MEDIUM: connections: Implement a start() method for xprt_handshake. + - MEDIUM: connections: Implement a start() method in ssl_sock. + - MINOR: muxes: garbage collect the reset() method. + - CLEANUP: tcp-rules: Fix a typo in error messages about expect-netscaler-cip + - MEDIUM: lua: Use a per-thread counter to track some non-reentrant parts of lua + - BUG/MEDIUM: debug/lua: Don't dump the lua stack if not dumpable + +2021/03/13 : 2.4-dev12 + - CLEANUP: connection: Use `VAR_ARRAY` in `struct tlv` definition + - CLEANUP: connection: Remove useless test for NULL before calling `pool_free()` + - CLEANUP: connection: Use istptr / istlen for proxy_unique_id + - MINOR: connection: Use a `struct ist` to store proxy_authority + - CLEANUP: connection: Consistently use `struct ist` to process all TLV types + - BUILD: task: fix build at -O0 with threads disabled + - BUILD: bug: refine HA_LINK_ERROR() to only be used on gcc and derivatives + - CLEANUP: config: make the cfg_keyword parsers take a const for the defproxy + - BUILD: connection: do not use VAR_ARRAY in struct tlv + - BUG/MEDIUM: session: NULL dereference possible when accessing the listener + - MINOR: build: force CC to set a return code when probing options + - CLEANUP: stream: rename a few remaining occurrences of "stream *sess" + - BUG/MEDIUM: resolvers: handle huge responses over tcp servers. + - CLEANUP: config: also address the cfg_keyword API change in the compression code + - BUG/MEDIUM: ssl: properly remove the TASK_HEAVY flag at end of handshake + - BUG/MINOR: sample: Rename SenderComID/TargetComID to SenderCompID/TargetCompID + - MINOR: task: give the scheduler a bit more flexibility in the runqueue size + - OPTIM: task: automatically adjust the default runqueue-depth to the threads + - BUG/MINOR: connection: Missing QUIC initialization + - BUG/MEDIUM: stick-tables: fix ref counter in table entry using multiple http tracksc. + - BUILD: atomic/arm64: force the register pairs to use in __ha_cas_dw() + - BUG/MEDIUM: filters: Set CF_FL_ANALYZE on channels when filters are attached + - BUG/MINOR: tcpcheck: Update .health threshold of agent inside an agent-check + - BUG/MINOR: proxy/session: Be sure to have a listener to increment its counters + - BUG/MINOR: tcpcheck: Fix double free on error path when parsing tcp/http-check + - BUG/MINOR: server-state: properly handle the case where the base is not set + - BUG/MINOR: server-state: use the argument, not the global state + - CLEANUP: tcp-rules: add missing actions in the tcp-request error message + - CLEANUP: vars: make the error message clearer on missing arguments for set-var + - CLEANUP: http-rules: remove the unexpected comma before the list of action keywords + - CLEANUP: actions: the keyword must always be const from the rule + - MINOR: tools: add simple word fingerprinting to find similar-looking words + - MINOR: cfgparse: add cfg_find_best_match() to suggest an existing word + - MINOR: cfgparse: suggest correct spelling for unknown words in proxy sections + - MINOR: cfgparse: suggest correct spelling for unknown words in global section + - MINOR: cfgparse/server: try to fix spelling mistakes on server lines + - MINOR: cfgparse/bind: suggest correct spelling for unknown bind keywords + - MINOR: actions: add a function to suggest an action ressembling a given word + - MINOR: http-rules: suggest approaching action names on mismatch + - MINOR: tcp-rules: suggest approaching action names on mismatch + - BUG/MINOR: cfgparse/server: increment the extra keyword counter one at a time + - Revert "BUG/MINOR: resolvers: Only renew TTL for SRV records with an additional record" + - BUG/MINOR: resolvers: Consider server to have no IP on DNS resolution error + - BUG/MINOR: resolvers: Reset server address on DNS error only on status change + - BUG/MINOR: resolvers: Unlink DNS resolution to set RMAINT on SRV resolution + - BUG/MEDIUM: resolvers: Don't set an address-less server as UP + - BUG/MEDIUM: resolvers: Fix the loop looking for an existing ADD item + - MINOR: resolvers: new function find_srvrq_answer_record() + - BUG/MINOR; resolvers: Ignore DNS resolution for expired SRV item + - BUG/MEDIUM: resolvers: Trigger a DNS resolution if an ADD item is obsolete + - MINOR: resolvers: Use a function to remove answers attached to a resolution + - MINOR: resolvers: Purge answer items when a SRV resolution triggers an error + - MINOR: resolvers: Add function to change the srv status based on SRV resolution + - MINOR: resolvers: Directly call srvrq_update_srv_state() when possible + - BUG/MEDIUM: resolvers: Don't release resolution from a requester callbacks + - BUG/MEDIUM: resolvers: Skip DNS resolution at startup if SRV resolution is set + - MINOR: resolvers: Use milliseconds for cached items in resolver responses + - MINOR: resolvers: Don't try to match immediatly renewed ADD items + - CLEANUP: resolvers: Use ha_free() in srvrq_resolution_error_cb() + - CLEANUP: resolvers: Perform unsafe loop on requester list when possible + - BUG/MINOR: cli: make sure "help", "prompt", "quit" are enabled at master level + - CLEANUP: cli: fix misleading comment and better indent the access level flags + - MINOR: cli: set the ACCESS_MASTER* bits on the master bind_conf + - MINOR: cli: test the appctx level for master access instead of comparing pointers + - MINOR: cli: print the error message in the parser function itself + - MINOR: cli: filter the list of commands to the matching part + - MEDIUM: cli: apply spelling fixes for known commands before listing them + - MINOR: tools: add the ability to update a word fingerprint + - MINOR: cli: apply the fuzzy matching on the whole command instead of words + - CLEANUP: cli: rename MAX_STATS_ARGS to MAX_CLI_ARGS + - CLEANUP: cli: rename the last few "stats_" to "cli_" + - CLEANUP: task: make sure tasklet handlers always indicate their statuses + - CLEANUP: assorted typo fixes in the code and comments + +2021/03/05 : 2.4-dev11 + - CI: codespell: skip Makefile for spell check + - CLEANUP: assorted typo fixes in the code and comments + - BUG/MINOR: tcp-act: Don't forget to set the original port for IPv4 set-dst rule + - BUG/MINOR: connection: Use the client's dst family for adressless servers + - BUG/MEDIUM: spoe: Kill applets if there are pending connections and nbthread > 1 + - CLEANUP: Use ist2(const void*, size_t) whenever possible + - CLEANUP: Use IST_NULL whenever possible + - BUILD: proxy: Missing header inclusion for quic_transport_params_init() + - BUILD: quic: Implicit conversion between SSL related enums. + - DOC: spoe: Add a note about fragmentation support in HAProxy + - MINOR: contrib: add support for heartbeat control messages. + - MINOR: contrib: Enhance peers dissector heuristic. + - BUG/MINOR: mux-h2: Fix typo in scheme adjustment + - CLEANUP: Reapply the ist2() replacement patch + - CLEANUP: Use istadv(const struct ist, const size_t) whenever possible + - CLEANUP: Use isttest(const struct ist) whenever possible + - Revert "CI: Pin VTest to a known good commit" + - CLEANUP: backend: fix a wrong comment + - BUG/MINOR: backend: free allocated bind_addr if reuse conn + - MINOR: backend: handle reuse for conns with no server as target + - REGTESTS: test http-reuse if no server target + - BUG/MINOR: hlua: Don't strip last non-LWS char in hlua_pushstrippedstring() + - BUG/MINOR: server-state: Don't load server-state file for disabled backends + - CLEANUP: dns: Use DISGUISE() on a never-failing ring_attach() call + - CLEANUP: dns: Remove useless test on ns->dgram in dns_connect_nameserver() + - DOC: fix originalto except clause on destination address + - CLEANUP: Use the ist() macro whenever possible + - CLEANUP: Replace for loop with only a condition by while + - REORG: atomic: reimplement pl_cpu_relax() from atomic-ops.h + - BUG/MINOR: mt-list: always perform a cpu_relax call on failure + - MINOR: atomic: add armv8.1-a atomics variant for cas-dw + - MINOR: atomic: implement a more efficient arm64 __ha_cas_dw() using pairs + - BUG/MINOR: ssl: don't truncate the file descriptor to 16 bits in debug mode + - MEDIUM: pools: add CONFIG_HAP_NO_GLOBAL_POOLS and CONFIG_HAP_GLOBAL_POOLS + - MINOR: pools: double the local pool cache size to 1 MB + - MINOR: stream: use ABORT_NOW() and not abort() in stream_dump_and_crash() + - CLEANUP: stream: explain why we queue the stream at the head of the server list + - MEDIUM: backend: use a trylock when trying to grab an idle connection + - REORG: tools: promote the debug PRNG to more general use as a statistical one + - OPTIM: lb-random: use a cheaper PRNG to pick a server + - MINOR: task: stop abusing the nice field to detect a tasklet + - MINOR: task: move the nice field to the struct task only + - MEDIUM: task: extend the state field to 32 bits + - MINOR: task: add an application specific flag to the state: TASK_F_USR1 + - MEDIUM: muxes: mark idle conns tasklets with TASK_F_USR1 + - MINOR: xprt: add new xprt_set_idle and xprt_set_used methods + - MEDIUM: ssl: implement xprt_set_used and xprt_set_idle to relax context checks + - MINOR: server: don't read curr_used_conns multiple times + - CLEANUP: global: reorder some fields to respect cache lines + - CLEANUP: sockpair: silence a coverity check about fcntl() + - CLEANUP: lua: set a dummy file name and line number on the dummy servers + - MINOR: server: add a global list of all known servers + - MINOR: cfgparse: finish to set up servers outside of the proxy setup loop + - MINOR: server: allocate a per-thread struct for the per-thread connections stuff + - MINOR: server: move actconns to the per-thread structure + - CLEANUP: server: reorder some fields in the server struct to respect cache lines + - MINOR: backend: add a BUG_ON if conn mux NULL in connect_server + - BUG/MINOR: backend: fix condition for reuse on mode HTTP + - BUILD: Fix build when using clang without optimizing. + - CLEANUP: assorted typo fixes in the code and comments + +2021/02/26 : 2.4-dev10 + - BUILD: SSL: introduce fine guard for RAND_keep_random_devices_open + - MINOR: Configure the `cpp` userdiff driver for *.[ch] in .gitattributes + - BUG/MINOR: ssl/cli: potential null pointer dereference in "set ssl cert" + - BUG/MINOR: sample: secure convs that accept base64 string and var name as args + - BUG/MEDIUM: vars: make functions vars_get_by_{name,desc} thread-safe + - CLEANUP: vars: make smp_fetch_var() to reuse vars_get_by_desc() + - DOC: muxes: add a diagram of the exchanges between muxes and outer world + - BUG/MEDIUM: proxy: use thread-safe stream killing on hard-stop + - BUG/MEDIUM: cli/shutdown sessions: make it thread-safe + - BUG/MINOR: proxy: wake up all threads when sending the hard-stop signal + - MINOR: stream: add an "epoch" to figure which streams appeared when + - MINOR: cli/streams: make "show sess" dump all streams till the new epoch + - MINOR: streams: use one list per stream instead of a global one + - MEDIUM: streams: do not use the streams lock anymore + - BUILD: dns: avoid a build warning when threads are disabled (dss unused) + - MEDIUM: task: remove the tasks_run_queue counter and have one per thread + - MINOR: tasks: do not maintain the rqueue_size counter anymore + - CLEANUP: tasks: use a less confusing name for task_list_size + - CLEANUP: task: move the tree root detection from __task_wakeup() to task_wakeup() + - MINOR: task: limit the remote thread wakeup to the global runqueue only + - MINOR: task: move the allocated tasks counter to the per-thread struct + - CLEANUP: task: split the large tasklet_wakeup_on() function in two + - BUG/MINOR: fd: properly wait for !running_mask in fd_set_running_excl() + - BUG/MINOR: resolvers: Fix condition to release received ARs if not assigned + - BUG/MINOR: resolvers: Only renew TTL for SRV records with an additional record + - BUG/MINOR: resolvers: new callback to properly handle SRV record errors + - BUG/MEDIUM: resolvers: Reset server address and port for obselete SRV records + - BUG/MEDIUM: resolvers: Reset address for unresolved servers + - DOC: Update the module list in MAINTAINERS file + - MINOR: htx: Add function to reserve the max possible size for an HTX DATA block + - DOC: Update the HTX API documentation + - DOC: Update the filters guide + - BUG/MEDIUM: contrib/prometheus-exporter: fix segfault in listener name dump + - MINOR: task: split the counts of local and global tasks picked + - MINOR: task: do not use __task_unlink_rq() from process_runnable_tasks() + - MINOR: task: don't decrement then increment the local run queue + - CLEANUP: task: re-merge __task_unlink_rq() with task_unlink_rq() + - MINOR: task: make grq_total atomic to move it outside of the grq_lock + - MINOR: tasks: also compute the tasklet latency when DEBUG_TASK is set + - MINOR: task: make tasklet wakeup latency measurements more accurate + - MINOR: server: Be more strict on the server-state line parsing + - MINOR: server: Only fill one array when parsing a server-state line + - MEDIUM: server: Refactor apply_server_state() to make it more readable + - CLEANUP: server: Rename state_line node to node instead of name_name + - CLEANUP: server: Rename state_line structure into server_state_line + - CLEANUP: server: Use a local eb-tree to store lines of the global server-state file + - MINOR: server: Be more strict when reading the version of a server-state file + - MEDIUM: server: Store parsed params of a server-state line in the tree + - MINOR: server: Remove cached line from global server-state tree when found + - MINOR: server: Move loading state of servers in a dedicated function + - MEDIUM: server: Use a tree to store local server-state lines + - MINOR: server: Parse and store server-state lines in a dedicated function + - MEDIUM: server: Don't load server-state file if a line is corrupted + - REORG: server: Export and rename some functions updating server info + - REORG: server-state: Move functions to deal with server-state in its own file + - MINOR: server-state: Don't load server-state file for serverless proxies + - CLEANUP: muxes: Remove useless if condition in show_fd function + - BUG/MINOR: stats: fix compare of no-maint url suffix + - MINOR: task: limit the number of subsequent heavy tasks with flag TASK_HEAVY + - MINOR: ssl: mark the SSL handshake tasklet as heavy + - CLEANUP: server: rename srv_cleanup_{idle,toremove}_connections() + - BUG/MINOR: ssl: potential null pointer dereference in ckchs_dup() + - MINOR: task: add one extra tasklet class: TL_HEAVY + - MINOR: task: place the heavy elements in TL_HEAVY + - MINOR: task: only limit TL_HEAVY tasks but not others + - BUG/MINOR: http-ana: Only consider dst address to process originalto option + - MINOR: tools: Add net_addr structure describing a network addess + - MINOR: tools: Add function to compare an address to a network address + - MEDIUM: http-ana: Add IPv6 support for forwardfor and orignialto options + - CLEANUP: hlua: Use net_addr structure internally to parse and compare addresses + - REGTESTS: Add script to test except param for fowardedfor/originalto options + - DOC: scheduler: add a diagram showing the different queues and their usages + - CLEANUP: tree-wide: replace free(x);x=NULL with ha_free(&x) + - CLEANUP: config: replace a few free() with ha_free() + - CLEANUP: vars: always zero the pointers after a free() + - CLEANUP: ssl: remove a useless "if" before freeing an error message + - CLEANUP: ssl: make ssl_sock_free_srv_ctx() zero the pointers after free + - CLEANUP: ssl: use realloc() instead of free()+malloc() + +2021/02/20 : 2.4-dev9 + - BUG/MINOR: server: Remove RMAINT from admin state when loading server state + - CLEANUP: check: fix get_check_status_info declaration + - CLEANUP: contrib/prometheus-exporter: align for with srv status case + - MEDIUM: stats: allow to select one field in `stats_fill_li_stats` + - MINOR: stats: add helper to get status string + - MEDIUM: contrib/prometheus-exporter: add listen stats + - BUG/MINOR: dns: add test on result getting value from buffer into ring. + - BUG/MINOR: dns: dns_connect_server must return -1 unsupported nameserver's type + - BUG/MINOR: dns: missing test writing in output channel in session handler + - BUG/MINOR: dns: fix ring attach control on dns_session_new + - BUG/MEDIUM: dns: fix multiple double close on fd in dns.c + - BUG/MAJOR: connection: prevent double free if conn selected for removal + - BUG/MINOR: session: atomically increment the tracked sessions counter + - REGTESTS: fix http_reuse_conn_hash proxy test + - BUG/MINOR: backend: do not call smp_make_safe for sni conn hash + - MINOR: connection: remove pointers for prehash in conn_hash_params + - BUG/MINOR: checks: properly handle wrapping time in __health_adjust() + - BUG/MEDIUM: checks: don't needlessly take the server lock in health_adjust() + - DEBUG: thread: add 5 extra lock labels for statistics and debugging + - OPTIM: server: switch the actconn list to an mt-list + - Revert "MINOR: threads: change lock_t to an unsigned int" + - MINOR: lb/api: let callers of take_conn/drop_conn tell if they have the lock + - OPTIM: lb-first: do not take the server lock on take_conn/drop_conn + - OPTIM: lb-leastconn: do not take the server lock on take_conn/drop_conn + - OPTIM: lb-leastconn: do not unlink the server if it did not change + - MINOR: tasks: add DEBUG_TASK to report caller info in a task + - MINOR: tasks/debug: add some extra controls of use-after-free in DEBUG_TASK + - BUG/MINOR: sample: Always consider zero size string samples as unsafe + - MINOR: cli: add missing agent commands for set server + - BUILD/MEDIUM: da Adding pcre2 support. + - BUILD: ssl: introduce fine guard for OpenSSL specific SCTL functions + - REGTESTS: reorder reuse conn proxy protocol test + - DOC: explain the relation between pool-low-conn and tune.idle-pool.shared + - MINOR: tasks: refine the default run queue depth + - MINOR: listener: refine the default MAX_ACCEPT from 64 to 4 + - MINOR: mux_h2: do not try to remove front conn from idle trees + - REGTESTS: workaround for a crash with recent libressl on http-reuse sni + - BUG/MEDIUM: lists: Avoid an infinite loop in MT_LIST_TRY_ADDQ(). + - MINOR: connection: allocate dynamically hash node for backend conns + - DOC: DeviceAtlas documentation typo fix. + - BUG/MEDIUM: spoe: Resolve the sink if a SPOE logs in a ring buffer + - BUG/MINOR: http-rules: Always replace the response status on a return action + - BUG/MINOR: server: Init params before parsing a new server-state line + - BUG/MINOR: server: Be sure to cut the last parsed field of a server-state line + - MEDIUM: server: Don't introduce a new server-state file version + - DOC: contrib/prometheus-exporter: remove htx reference + - REGTESTS: contrib/prometheus-exporter: test NaN values + - REGTESTS: contrib/prometheus-exporter: test well known labels + - CI: github actions: switch to stable LibreSSL release + - BUG/MINOR: server: Fix test on number of fields allowed in a server-state line + - MINOR: dynbuf: make the buffer wait queue per thread + - MINOR: dynbuf: use regular lists instead of mt_lists for buffer_wait + - MINOR: dynbuf: pass offer_buffers() the number of buffers instead of a threshold + - MINOR: sched: have one runqueue ticks counter per thread + +2021/02/13 : 2.4-dev8 + - BUILD: ssl: fix typo in HAVE_SSL_CTX_ADD_SERVER_CUSTOM_EXT macro + - BUILD: ssl: guard SSL_CTX_add_server_custom_ext with special macro + - BUG/MINOR: mux-h1: Don't emit extra CRLF for empty chunked messages + - MINOR: contrib/prometheus-exporter: use stats desc when possible followup + - MEDIUM: contrib/prometheus-exporter: export base stick table stats + - CLEANUP: assorted typo fixes in the code and comments + - CLEANUP: check: fix some typo in comments + - CLEANUP: tools: typo in `strl2irc` mention + - BUILD: ssl: guard SSL_CTX_set_msg_callback with SSL_CTRL_SET_MSG_CALLBACK macro + - MEDIUM: ssl: add a rwlock for SSL server session cache + - BUG/MINOR: intops: fix mul32hi()'s off-by-one + - BUG/MINOR: freq_ctr: fix a wrong delay calculation in next_event_delay() + - MINOR: stick-tables/counters: add http_fail_cnt and http_fail_rate data types + - MINOR: ssl: add SSL_SERVER_LOCK label in threads.h + - BUG/MINOR: mux-h1: Don't increment HTTP error counter for 408/500/501 errors + - BUG/MINOR: http-ana: Don't increment HTTP error counter on internal errors + - BUG/MEDIUM: mux-h1: Always set CS_FL_EOI for response in MSG_DONE state + - BUG/MINOR: mux-h1: Fix data skipping for bodyless responses + - BUG/MINOR: mux-h1: Don't blindly skip EOT block for non-chunked messages + - BUG/MEDIUM: mux-h2: Add EOT block when EOM flag is set on an empty HTX message + - MINOR: mux-h1: Be sure EOM flag is set when processing end of outgoing message + - REGTESTS: Add a script to test payload skipping for bodyless HTTP responses + - BUG/MINOR: server: re-align state file fields number + - CLEANUP: muxes: Remove useless calls to b_realign_if_empty() + - BUG/MINOR: tools: Fix a memory leak on error path in parse_dotted_uints() + - CLEANUP: remove unused variable assigned found by Coverity + - CLEANUP: queue: Remove useless tests on p or pp in pendconn_process_next_strm() + - BUG/MINOR: backend: hold correctly lock when killing idle conn + - MEDIUM: connection: protect idle conn lists with locks + - MEDIUM: connection: replace idle conn lists by eb trees + - MINOR: backend: search conn in idle/safe trees after available + - MINOR: backend: search conn in idle tree after safe on always reuse + - MINOR: connection: prepare hash calcul for server conns + - MINOR: connection: use the srv pointer for the srv conn hash + - MINOR: backend: compare conn hash for session conn reuse + - MINOR: connection: use sni as parameter for srv conn hash + - MINOR: reg-tests: test http-reuse with sni + - MINOR: backend: rewrite alloc of stream target address + - MINOR: connection: use dst addr as parameter for srv conn hash + - MINOR: reg-test: test http-reuse with specific dst addr + - MINOR: backend: rewrite alloc of connection src address + - MINOR: connection: use src addr as parameter for srv conn hash + - MINOR: connection: use proxy protocol as parameter for srv conn hash + - MINOR: reg-tests: test http-reuse with proxy protocol + - MINOR: doc: update http reuse for new eligilible connections + - BUG/MINOR: backend: fix compilation without ssl + - REGTESTS: adjust http_reuse_conn_hash requirements + - REGTESTS: deactivate a failed test on CI in http_reuse_conn_hash + - REGTESTS: fix sni used in http_reuse_conn_hash for libressl 3.3.0 + - CI: cirrus: update FreeBSD image to 12.2 + - MEDIUM: cli: add check-addr command + - MEDIUM: cli: add agent-port command + - MEDIUM: server: add server-states version 2 + - MEDIUM: server: support {check,agent}_addr, agent_port in server state + - MINOR: server: enhance error precision when applying server state + - BUG/MINOR: server: Fix server-state-file-name directive + - CLEANUP: deinit: release global and per-proxy server-state variables on deinit + - BUG/MEDIUM: config: don't pick unset values from last defaults section + - BUG/MINOR: stats: revert the change on ST_CONVDONE + - BUG/MINOR: cfgparse: do not mention "addr:port" as supported on proxy lines + - BUG/MINOR: http-htx: defpx must be a const in proxy_dup_default_conf_errors() + - BUG/MINOR: tcpheck: the source list must be a const in dup_tcpcheck_var() + - BUILD: proxy: add missing compression-t.h to proxy-t.h + - REORG: move init_default_instance() to proxy.c and pass it the defproxy pointer + - REORG: proxy: centralize the proxy allocation code into alloc_new_proxy() + - MEDIUM: proxy: only take defaults when a default proxy is passed. + - MINOR: proxy: move the defproxy freeing code to proxy.c + - MINOR: proxy: always properly reset the just freed default instance pointers + - BUG/MINOR: extcheck: proxy_parse_extcheck() must take a const for the defproxy + - BUG/MINOR: tcpcheck: proxy_parse_*check*() must take a const for the defproxy + - BUG/MINOR: server: parse_server() must take a const for the defproxy + - MINOR: cfgparse: move defproxy to cfgparse-listen as a static + - MINOR: proxy: add a new capability PR_CAP_DEF + - MINOR: cfgparse: check PR_CAP_DEF instead of comparing poiner against defproxy + - MINOR: cfgparse: use a pointer to the current default proxy + - MINOR: proxy: also store the name for a defaults section + - MINOR: proxy: support storing defaults sections into their own tree + - MEDIUM: proxy: store the default proxies in a tree by name + - MEDIUM: cfgparse: allow a proxy to designate the defaults section to use + - MINOR: http: add baseq sample fetch + - CLEANUP: tcpcheck: Remove a useless test on port variable + - BUG/MINOR: server: Don't call fopen() with server-state filepath set to NULL + - CLEANUP: server: Remove useless "filepath" variable in apply_server_state() + - MINOR: peers/cli: do not dump the peers dictionaries by default on "show peers" + - MINOR: cfgparse: implement a simple if/elif/else/endif macro block handler + - DOC: tune: explain the origin of block size for ssl.cachesize + - MINOR: tcp: add support for defer-accept on FreeBSD. + - MINOR: ring: adds new ring_init function. + - CLEANUP: channel: fix comment in ci_putblk. + - BUG/MINOR: dns: add missing sent counter and parent id to dns counters. + - BUG/MINOR: resolvers: fix attribute packed struct for dns + - MINOR: resolvers: renames some resolvers internal types and removes dns prefix + - MINOR: resolvers: renames type dns_resolvers to resolvers. + - MINOR: resolvers: renames some resolvers specific types to not use dns prefix + - MINOR: resolvers: renames some dns prefixed types using resolv prefix. + - MINOR: resolvers: renames resolvers DNS_RESP_* errcodes RSLV_RESP_* + - MINOR: resolvers: renames resolvers DNS_UPD_* returncodes to RSLV_UPD_* + - MINOR: resolvers: rework prototype suffixes to split resolving and dns. + - MEDIUM: resolvers: move resolvers section parsing from cfgparse.c to dns.c + - MINOR: resolvers: replace nameserver's resolver ref by generic parent pointer + - MINOR: resolvers: rework dns stats prototype because specific to resolvers + - MEDIUM: resolvers: split resolving and dns message exchange layers. + - MEDIUM: resolvers/dns: split dns.c into dns.c and resolvers.c + - MEDIUM: dns: adds code to support pipelined DNS requests over TCP. + - MEDIUM: resolvers: add supports of TCP nameservers in resolvers. + +2021/02/05 : 2.4-dev7 + - BUG/MINOR: stats: Continue to fill frontend stats on unimplemented metric + - BUILD: ssl: guard Client Hello callbacks with HAVE_SSL_CLIENT_HELLO_CB macro instead of openssl version + - BUG/MINOR: stats: Init the metric variable when frontend stats are filled + - MINOR: contrib/prometheus-exporter: better output of Not-a-Number + - CLEANUP: stats: improve field selection for frontend http fields + - CLEANUP: assorted typo fixes in the code and comments + - DOC: Improve documentation of the various hdr() fetches + - MEDIUM: stats: allow to select one field in `stats_fill_be_stats` + - MINOR: contrib/prometheus-exporter: use fill_be_stats for backend dump + - MEDIUM: stats: allow to select one field in `stats_fill_sv_stats` + - MINOR: contrib/prometheus-exporter: use fill_sv_stats for server dump + - MINOR: abort() on my_unreachable() when DEBUG_USE_ABORT is set. + - BUG/MEDIUM: filters/htx: Fix data forwarding when payload length is unknown + - BUG/MINOR: config: fix leak on proxy.conn_src.bind_hdr_name + - MINOR: reg-tests: add http-reuse test + - CLEANUP: srv: fix comment for pool-max-conn + - CLEANUP: backend: remove an obsolete comment on conn_backend_get + - REORG: backend: simplify conn_backend_get + - MINOR: ssl: Server ssl context prepare function refactoring + - MINOR: ssl: Certificate chain loading refactorization + - MEDIUM: ssl: Load client certificates in a ckch for backend servers + - MEDIUM: ssl: Enable backend certificate hot update + - MINOR: ssl: Remove client_crt member of the server's ssl context + - CLEANUP: ssl/cli: rework free in cli_io_handler_commit_cert() + - CLEANUP: ssl: remove SSL_CTX function parameter + - CLEANUP: ssl: make load_srv_{ckchs,cert} match their bind counterpart + - BUILD: Include stdlib.h in compiler.h if DEBUG_USE_ABORT is set + - CI: Fix DEBUG_STRICT definition for Coverity + - BUG/MINOR: stats: Remove a break preventing ST_F_QCUR to be set for servers + - BUG/MINOR: stats: Add a break after filling ST_F_MODE field for servers + - CLEANUP: ssl: remove dead code in ckch_inst_new_load_srv_store() + - BUG/MINOR: ssl: init tmp chunk correctly in ssl_sock_load_sctl_from_file() + - BUG/MEDIUM: session: only retrieve ready idle conn from session + - BUG/MEDIUM: backend: never reuse a connection for tcp mode + - REGTESTS: set_ssl_server_cert.vtc: remove the abort command + - REGTESTS: set_ssl_server_cert.vtc: check the Sha1 Fingerprint + - REGTESTS: set_ssl_server_cert.vtc: check the sha1 from the server + - MEDIUM: stream-int: Take care of EOS if the SI wake callback function + - MINOR: mux-h1: Try to wake up data layer first before calling its wake callback + - MINOR: mux-h1: Wake up H1C after its creation if input buffer is not empty + - MEDIUM: mux-h1: Add ST_READY state for the H1 connections + - MINOR: stream: Add a function to validate TCP to H1 upgrades + - MEDIUM: http-ana: Do nothing in wait-for-request analyzer if not htx + - BUG/MEDIUM: stream: Don't immediatly ack the TCP to H1 upgrades + - BUG/MAJOR: mux-h1: Properly handle TCP to H1 upgrades + - MINOR: htx/http-ana: Save info about Upgrade option in the Connection header + - MEDIUM: http-ana: Refuse invalid 101-switching-protocols responses + - BUG/MINOR: h2/mux-h2: Reject 101 responses with a PROTOCOL_ERROR h2s error + - MINOR: mux-h1/mux-fcgi: Don't set TUNNEL mode if payload length is unknown + - MINOR: mux-h1: Split H1C_F_WAIT_OPPOSITE flag to separate input/output sides + - MINOR: mux-h2: Add 2 flags to help to properly handle tunnel mode + - MEDIUM: mux-h2: Block client data on server side waiting tunnel establishment + - MEDIUM: mux-h2: Close streams when processing data for an aborted tunnel + - MEDIUM: mux-h1: Properly handle tunnel establishments and aborts + - BUG/MAJOR: mux-h1/mux-h2/htx: Fix HTTP tunnel management at the mux level + - MINOR: htx: Rename HTX_FL_EOI flag into HTX_FL_EOM + - REGTESTS: Don't run http_msg_full_on_eom script on the 2.4 anymore + - MINOR: htx: Add a function to know if a block is the only one in a message + - MAJOR: htx: Remove the EOM block type and use HTX_FL_EOM instead + - MINOR: mux-h1: Add a flag on H1 streams with a response known to be bodyless + - MEDIUM: mux-h1: Don't emit any payload for bodyless responses + - MINOR: mux-h1: Don't emit C-L and T-E headers for 204 and 1xx responses + - MINOR: mux-h1: Don't add Connection close/keep-alive header for 1xx messages + - MINOR: h2/mux-h2: Add flags to notify the response is known to have no body + - MEDIUM: mux-h2: Don't emit DATA frame for bodyless responses + - MEDIUM: http-ana: Deal with L7 retries in HTTP analysers + - MINOR: h1: reject websocket handshake if missing key + - MEDIUM: h1: generate WebSocket key on response if needed + - MINOR: mux_h2: define H2_SF_EXT_CONNECT_SENT stream flag + - MEDIUM: h2: parse Extended CONNECT reponse to htx + - MEDIUM: mux_h2: generate Extended CONNECT from htx upgrade + - MEDIUM: h1: add a WebSocket key on handshake if needed + - MEDIUM: mux_h2: generate Extended CONNECT response + - MEDIUM: h2: parse Extended CONNECT request to htx + - MEDIUM: h2: send connect protocol h2 settings + - MINOR: vtc: add test for h1/h2 protocol upgrade translation + - MINOR: vtc: add websocket test + - REGTESTS: Fix required versions for several scripts + - REGTEST: Don't use the websocket to validate http-check + - MINOR: mux-h1/trace: add traces at level ERROR for all kind of errors + - MINOR: mux-fcgi/trace: add traces at level ERROR for all kind of errors + - MINOR: h1: Raise the chunk size limit up to (2^52 - 1) + - BUG/MEDIUM: listener: do not accept connections faster than we can process them + - REGTESTS: set_ssl_server_cert.vtc: set as broken + - Revert "BUG/MEDIUM: listener: do not accept connections faster than we can process them" + - BUG/MINOR: backend: check available list allocation for reuse + - CI: Fix the coverity builds + - DOC: management: fix "show resolvers" alphabetical ordering + - MINOR: tools: add print_time_short() to print a condensed duration value + - MINOR: activity: make profiling more manageable + - MINOR: activity: declare a new structure to collect per-function activity + - MEDIUM: tasks/activity: collect per-task statistics when profiling is enabled + - MINOR: activity: also report collected tasks stats in "show profiling" + - MINOR: activity: flush scheduler stats on "set profiling tasks on" + - MINOR: activity: add a new "show tasks" command to list currently active tasks + - MINOR: listener: export accept_queue_process + - MINOR: session: export session_expire_embryonic() + - MINOR: muxes: export the timeout and shutr task handlers + - MINOR: checks: export a few functions that appear often in trace dumps + - MINOR: peers: export process_peer_sync() to improve traces + - MINOR: stick-tables: export process_table_expire() + - MINOR: mux-h1: Remove first useless test on count in h1_process_output() + - BUG/MINOR: stick-table: Always call smp_fetch_src() with a valid arg list + - MINOR: http-fetch: Don't check if argument list is set in sample fetches + - MINOR: http-conv: Don't check if argument list is set in sample converters + - MINOR: sample: Don't check if argument list is set in sample fetches + - MINOR: ssl-sample: Don't check if argument list is set in sample fetches + - MINOR: mux-h2: Don't tests the start-line when sending HEADERS frame + - MINOR: mux-h2: Slightly improve request HEADERS frames sending + - MINOR: contrib/prometheus-exporter: declare states for objects + - MAJOR: contrib/prometheus-exporter: move ftd/bkd/srv states to labels + - MEDIUM: contrib/prometheus-exporter: Use dynamic labels instead of static ones + - MINOR: listener: export manage_global_listener_queue() + - BUG/MINOR: activity: take care of late wakeups in "show tasks" + - REGTESTS: set_ssl_server_cert.vtc: remove SSL caching and set as working + - REGTESTS: set_ssl_server_cert: cleanup the SSL caching option + - MINOR: checks: Add function to get the result code corresponding to a status + - MAJOR: contrib/prometheus-exporter: move health check status to labels + - MINOR: contrib/prometheus-exporter: improve service status description field + - MINOR: stats: improve pending connections description + - MINOR: stats: improve max stats descriptions + - MINOR: contrib/prometheus-exporter: use stats desc when possible + - MINOR: contrib/prometheus-exporter: add uweight field + - MINOR: contrib/prometheus-exporter: add recv logs_logs_total field + - CLEANUP: contrib/prometheus-exporter: remove unused includes + - CLEANUP: contrib/prometheus-exporter: align and reorder fields + - CLEANUP: contrib/prometheus-exporter: remove description in README + - DOC: contrib/prometheus-exporter: Add missing metrics in README + - BUG/MINOR: contrib/prometheus-exporter: Add missing label for ST_F_HRSP_1XX + - BUG/MINOR: contrib/prometheus-exporter: Restart labels dump at the right pos + - BUG/MEDIUM: ssl/cli: abort ssl cert is freeing the old store + - BUG/MEDIUM: ssl: check a connection's status before computing a handshake + - BUG/MINOR: mux_h2: fix incorrect stat titles + - MINOR: ssl/cli: flush the server session cache upon 'commit ssl cert' + - BUG/MINOR: cli: fix set server addr/port coherency with health checks + - MINOR: server: Don't set the check port during the update from a state file + - MINOR: dns: Don't set the check port during a server dns resolution + - MEDIUM: check: remove checkport checkaddr flag + - MEDIUM: server: adding support for check_port in server state + - BUG/MINOR: check: consitent way to set agentaddr + - MEDIUM: check: align agentaddr and agentport behaviour + - DOC: server: Add missing params in comment of the server state line parsing + - BUG/MINOR: xxhash: make sure armv6 uses memcpy() + - REGTESTS: mark http-check-send.vtc as 2.4-only + - REGTESTS: mark sample_fetches/hashes.vtc as 2.4-only + - BUG/MINOR: ssl: do not try to use early data if not configured + - REGTESTS: unbreak http-check-send.vtc + - MINOR: cli/show_fd: report local and report ports when known + - BUILD: Makefile: move REGTESTST_TYPE default setting + - BUG/MEDIUM: mux-h2: handle remaining read0 cases + - CLEANUP: http-htx: Set buffer area to NULL instead of malloc(0) + - BUG/MINOR: sock: Unclosed fd in case of connection allocation failure + - BUG/MEDIUM: mux-h2: do not quit the demux loop before setting END_REACHED + +2021/01/22 : 2.4-dev6 + - MINOR: converter: adding support for url_enc + - BUILD: SSL: guard TLS13 ciphersuites with HAVE_SSL_CTX_SET_CIPHERSUITES + - BUILD: ssl: guard EVP_PKEY_get_default_digest_nid with ASN1_PKEY_CTRL_DEFAULT_MD_NID + - BUILD: ssl: guard openssl specific with SSL_READ_EARLY_DATA_SUCCESS + - BUILD: Makefile: exclude broken tests by default + - CLEANUP: cfgparse: replace "realloc" with "my_realloc2" to fix to memory leak on error + - BUG/MINOR: hlua: Fix memory leak in hlua_alloc + - MINOR: contrib/prometheus-exporter: export build_info + - DOC: fix some spelling issues over multiple files + - CLEANUP: Fix spelling errors in comments + - SCRIPTS: announce-release: fix typo in help message + - CI: github: add a few more words to the codespell ignore list + - DOC: Add maintainers for the Prometheus exporter + - BUG/MINOR: sample: fix concat() converter's corruption with non-string variables + - BUG/MINOR: server: Memory leak of proxy.used_server_addr during deinit + - CLEANUP: sample: remove uneeded check in json validation + - MINOR: reg-tests: add a way to add service dependency + - BUG/MINOR: sample: check alloc_trash_chunk return value in concat() + - BUG/MINOR: reg-tests: fix service dependency script + - MINOR: reg-tests: add base prometheus test + - Revert "BUG/MINOR: dns: SRV records ignores duplicated AR records" + - BUG/MINOR: sample: Memory leak of sample_expr structure in case of error + - BUG/MINOR: check: Don't perform any check on servers defined in a frontend + - BUG/MINOR: init: enforce strict-limits when using master-worker + - MINOR: contrib/prometheus-exporter: avoid connection close header + - MINOR: contrib/prometheus-exporter: use fill_info for process dump + - BUG/MINOR: init: Use a dynamic buffer to set HAPROXY_CFGFILES env variable + - MINOR: config: Add failifnotcap() to emit an alert on proxy capabilities + - MINOR: server: Forbid server definitions in frontend sections + - BUG/MINOR: threads: Fixes the number of possible cpus report for Mac. + - CLEANUP: pattern: rename pat_ref_commit() to pat_ref_commit_elt() + - MINOR: pattern: add the missing generation ID manipulation functions + - MINOR: peers: Add traces for peer control messages. + - BUG/MINOR: dns: SRV records ignores duplicated AR records (v2) + - BUILD: peers: fix build warning about unused variable + - BUG/MEDIUM: stats: add missing INF_BUILD_INFO definition + - MINOR: cache: Do not store responses with an unknown encoding + - BUG/MINOR: peers: Possible appctx pointer dereference. + - MINOR: build: discard echoing in help target + - MINOR: cache: Remove the `hash` part of the accept-encoding secondary key + - CLEANUP: cache: Use proper data types in secondary_key_cmp() + - CLEANUP: Rename accept_encoding_hash_cmp to accept_encoding_bitmap_cmp + - BUG/MINOR: peers: Wrong "new_conn" value for "show peers" CLI command. + - MINOR: contrib: Make the wireshark peers dissector compile for more distribs. + - BUG/MINOR: mux_h2: missing space between "st" and ".flg" in the "show fd" helper + - CLEANUP: tools: make resolve_sym_name() take a const pointer + - CLEANUP: cli: make "show fd" use a const connection to access other fields + - MINOR: cli: make "show fd" also report the xprt and xprt_ctx + - MINOR: xprt: add a new show_fd() helper to complete some "show fd" dumps. + - MINOR: ssl: provide a "show fd" helper to report important SSL information + - MINOR: xprt/mux: export all *_io_cb functions so that "show fd" resolves them + - MINOR: mux-h2: make the "show fd" helper also decode the h2s subscriber when known + - MINOR: mux-h1: make the "show fd" helper also decode the h1s subscriber when known + - MINOR: mux-fcgi: make the "show fd" helper also decode the fstrm subscriber when known + - CI: Pin VTest to a known good commit + - MINOR: cli: give the show_fd helpers the ability to report a suspicious entry + - MINOR: cli/show_fd: report some easily detectable suspicious states + - MINOR: ssl/show_fd: report some FDs as suspicious when possible + - MINOR: mux-h2/show_fd: report as suspicious an entry with too many calls + - MINOR: mux-h1/show_fd: report as suspicious an entry with too many calls + - BUG/MINOR: mworker: define _GNU_SOURCE for strsignal() + - BUG/MEDIUM: tcpcheck: Don't destroy connection in the wake callback context + - BUG/MEDIUM: mux-h2: Xfer rxbuf to the upper layer when creating a front stream + - MINOR: http: Add HTTP 501-not-implemented error message + - MINOR: muxes: Add exit status for errors about not implemented features + - MINOR: mux-h1: Be prepared to return 501-not-implemented error during parsing + - MEDIUM: mux-h1: Return a 501-not-implemented for upgrade requests with a body + - DOC: Remove space after comma in converter signature + - DOC: Rename '' to '' in converter signature + - MINOR: stats: duplicate 3 fields in bytes in info + - MINOR: stats: add new start time field + - MINOR: contrib/prometheus-exporter: merge info description from stats + - MEDIUM: stats: allow to select one field in `stats_fill_fe_stats` + - MINOR: contrib/prometheus-exporter: use fill_fe_stats for frontend dump + - MINOR: contrib/prometheus-exporter: Don't needlessly set empty label for metrics + - MINOR: contrib/prometheus-exporter: Split the PROMEX_FL_STATS_METRIC flag + - MINOR: contrib/prometheus-exporter: Add promex_metric struct defining a metric + - MEDIUM: contrib/prometheus-exporter: Rework matrices defining Promex metrics + - BUG/MINOR: stream: Don't update counters when TCP to H2 upgrades are performed + - BUG/MEDIUM: mux-h2: fix read0 handling on partial frames + - MINOR: debug: always export the my_backtrace function + - MINOR: debug: extract the backtrace dumping code to its own function + - MINOR: debug: create ha_backtrace_to_stderr() to dump an instant backtrace + - MEDIUM: debug: now always print a backtrace on CRASH_NOW() and friends + - MINOR: debug: let ha_dump_backtrace() dump a bit further for some callers + - BUILD: debug: fix build warning by consuming the write() result + - MINOR: lua: remove unused variable + - BUILD/MINOR: lua: define _GNU_SOURCE for LLONG_MAX + +2021/01/06 : 2.4-dev5 + - BUG/MEDIUM: mux_h2: Add missing braces in h2_snd_buf()around trace+wakeup + - BUILD: hpack: hpack-tbl-t.h uses VAR_ARRAY but does not include compiler.h + - MINOR: time: increase the minimum wakeup interval to 60s + - MINOR: check: do not ignore a connection header for http-check send + - REGTESTS: complete http-check test + - CI: travis-ci: drop coverity scan builds + - MINOR: atomic: don't use ; to separate instruction on aarch64. + - IMPORT: xxhash: update to v0.8.0 that introduces stable XXH3 variant + - MEDIUM: xxhash: use the XXH3 functions to generate 64-bit hashes + - MEDIUM: xxhash: use the XXH_INLINE_ALL macro to inline all functions + - CLEANUP: xxhash: remove the unused src/xxhash.c + - MINOR: sample: add the xxh3 converter + - REGTESTS: add tests for the xxh3 converter + - MINOR: protocol: Create proto_quic QUIC protocol layer. + - MINOR: connection: Attach a "quic_conn" struct to "connection" struct. + - MINOR: quic: Redefine control layer callbacks which are QUIC specific. + - MINOR: ssl_sock: Initialize BIO and SSL objects outside of ssl_sock_init() + - MINOR: connection: Add a new xprt to connection. + - MINOR: ssl: Export definitions required by QUIC. + - MINOR: cfgparse: Do not modify the QUIC xprt when parsing "ssl". + - MINOR: tools: Add support for QUIC addresses parsing. + - MINOR: quic: Add definitions for QUIC protocol. + - MINOR: quic: Import C source code files for QUIC protocol. + - MINOR: listener: Add QUIC info to listeners and receivers. + - MINOR: server: Add QUIC definitions to servers. + - MINOR: ssl: SSL CTX initialization modifications for QUIC. + - MINOR: ssl: QUIC transport parameters parsing. + - MINOR: quic: QUIC socket management finalization. + - MINOR: cfgparse: QUIC default server transport parameters init. + - MINOR: quic: Enable the compilation of QUIC modules. + - MAJOR: quic: Make usage of ebtrees to store QUIC ACK ranges. + - MINOR: quic: Attempt to make trace more readable + - MINOR: quic: Make usage of the congestion control window. + - MINOR: quic: Flag RX packet as ack-eliciting from the generic parser. + - MINOR: quic: Code reordering to help in reviewing/modifying. + - MINOR: quic: Add traces to congestion avoidance NewReno callback. + - MINOR: quic: Display the SSL alert in ->ssl_send_alert() callback. + - MINOR: quic: Update the initial salt to that of draft-29. + - MINOR: quic: Add traces for in flght ack-eliciting packet counter. + - MINOR: quic: make a packet build fails when qc_build_frm() fails. + - MINOR: quic: Add traces for quic_packet_encrypt(). + - MINOR: cache: Refactoring of secondary_key building functions + - MINOR: cache: Avoid storing responses whose secondary key was not correctly calculated + - BUG/MINOR: cache: Manage multiple headers in accept-encoding normalization + - MINOR: cache: Add specific secondary key comparison mechanism + - MINOR: http: Add helper functions to trim spaces and tabs + - MEDIUM: cache: Manage a subset of encodings in accept-encoding normalizer + - REGTESTS: cache: Simplify vary.vtc file + - REGTESTS: cache: Add a specific test for the accept-encoding normalizer + - MINOR: cache: Remove redundant test in http_action_req_cache_use + - MINOR: cache: Replace the "process-vary" option's expected values + - CI: GitHub Actions: enable daily Coverity scan + - BUG/MEDIUM: cache: Fix hash collision in `accept-encoding` handling for `Vary` + - MEDIUM: stick-tables: Add srvkey option to stick-table + - REGTESTS: add test for stickiness using "srvkey addr" + - BUILD: Makefile: disable -Warray-bounds until it's fixed in gcc 11 + - BUG/MINOR: sink: Return an allocation failure in __sink_new if strdup() fails + - BUG/MINOR: lua: Fix memory leak error cases in hlua_config_prepend_path + - MINOR: lua: Use consistent error message 'memory allocation failed' + - CLEANUP: Compare the return value of `XXXcmp()` functions with zero + - CLEANUP: Apply the coccinelle patch for `XXXcmp()` on include/ + - CLEANUP: Apply the coccinelle patch for `XXXcmp()` on contrib/ + - MINOR: qpack: Add static header table definitions for QPACK. + - CLEANUP: qpack: Wrong comment about the draft for QPACK static header table. + - CLEANUP: quic: Remove useless QUIC event trace definitions. + - BUG/MINOR: quic: Possible CRYPTO frame building errors. + - MINOR: quic: Pass quic_conn struct to frame parsers. + - BUG/MINOR: quic: Wrong STREAM frames parsing. + - MINOR: quic: Drop packets with STREAM frames with wrong direction. + - CLEANUP: ssl: Remove useless loop in tlskeys_list_get_next() + - CLEANUP: ssl: Remove useless local variable in tlskeys_list_get_next() + - MINOR: ssl: make tlskeys_list_get_next() take a list element + - Revert "BUILD: Makefile: disable -Warray-bounds until it's fixed in gcc 11" + - BUG/MINOR: cfgparse: Fail if the strdup() for `rule->be.name` for `use_backend` fails + - CLEANUP: mworker: remove duplicate pointer tests in cfg_parse_program() + - CLEANUP: Reduce scope of `header_name` in http_action_store_cache() + - CLEANUP: Reduce scope of `hdr_age` in http_action_store_cache() + - CLEANUP: spoe: fix typo on `var_check_arg` comment + - BUG/MINOR: tcpcheck: Report a L7OK if the last evaluated rule is a send rule + - CI: github actions: build several popular "contrib" tools + - DOC: Improve the message printed when running `make` w/o `TARGET` + - BUG/MEDIUM: server: srv_set_addr_desc() crashes when a server has no address + - REGTESTS: add unresolvable servers to srvkey-addr + - BUG/MINOR: stats: Make stat_l variable used to dump a stat line thread local + - BUG/MINOR: quic: NULL pointer dereferences when building post handshake frames. + - SCRIPTS: improve announce-release to support different tag and versions + - SCRIPTS: make announce release support preparing announces before tag exists + - CLEANUP: assorted typo fixes in the code and comments + - BUG/MINOR: srv: do not init address if backend is disabled + - BUG/MINOR: srv: do not cleanup idle conns if pool max is null + - CLEANUP: assorted typo fixes in the code and comments + - CLEANUP: few extra typo and fixes over last one ("ot" -> "to") + +2020/12/21 : 2.4-dev4 + - BUG/MEDIUM: lb-leastconn: Reposition a server using the right eweight + - BUG/MEDIUM: mux-h1: Fix a deadlock when a 408 error is pending for a client + - BUG/MEDIUM: ssl/crt-list: bad behavior with "commit ssl cert" + - BUG/MAJOR: cache: Crash because of disabled entry not removed from the tree + - BUILD: SSL: fine guard for SSL_CTX_add_server_custom_ext call + - MEDIUM: cache: Add a secondary entry counter and insertion limitation + - MEDIUM: cache: Avoid going over duplicates lists too often + - MINOR: cache: Add a max-secondary-entries cache option + - CI: cirrus: drop CentOS 6 builds + - BUILD: Makefile: have "make clean" destroy .o/.a/.s in contrib subdirs as well + - MINOR: vars: replace static functions with global ones + - MINOR: opentracing: add ARGC_OT enum + - CONTRIB: opentracing: add the OpenTracing filter + - DOC: opentracing: add the OpenTracing filter section + - REGTESTS: make use of HAPROXY_ARGS and pass -dM by default + - BUG/MINOR: http: Establish a tunnel for all 2xx responses to a CONNECT + - BUG/MINOR: mux-h1: Don't set CS_FL_EOI too early for protocol upgrade requests + - BUG/MEDIUM: http-ana: Never for sending data in TUNNEL mode + - CLEANUP: mux-h2: Rename h2s_frt_make_resp_data() to be generic + - CLEANUP: mux-h2: Rename h2c_frt_handle_data() to be generic + - BUG/MEDIUM: mux-h1: Handle h1_process() failures on a pipelined request + - CLEANUP: debug: mark the RNG's seed as unsigned + - CONTRIB: halog: fix build issue caused by %L printf format + - CONTRIB: halog: mark the has_zero* functions unused + - CONTRIB: halog: fix signed/unsigned build warnings on counts and timestamps + - CONTRIB: debug: address "poll" utility build on non-linux platforms + - BUILD: plock: remove dead code that causes a warning in gcc 11 + - BUILD: ssl: fine guard for SSL_CTX_get0_privatekey call + - BUG/MINOR: dns: SRV records ignores duplicated AR records + - DOC: fix "smp_size" vs "sample_size" in "log" directive arguments + - CLEANUP: assorted typo fixes in the code and comments + - DOC: assorted typo fixes in the documentation + - CI: codespell: whitelist "te" and "nd" words + +2020/12/11 : 2.4-dev3 + - MINOR: log: Logging HTTP path only with %HPO + - BUG/MINOR: mux-h2/stats: make stream/connection proto errors more accurate + - MINOR: traces: add a new level "error" below the "user" level + - MINOR: mux-h2/trace: add traces at level ERROR for protocol errors + - BUG/MINOR: mux-h2/stats: not all GOAWAY frames are errors + - BUG/MINOR: lua: missing "\n" in error message + - BUG/MINOR: lua: lua-load doesn't check its parameters + - BUG/MINOR: lua: Post init register function are not executed beyond the first one + - BUG/MINOR: lua: Some lua init operation are processed unsafe + - MINOR: actions: Export actions lookup functions + - MINOR: actions: add a function returning a service pointer from its name + - MINOR: cli: add a function to look up a CLI service description + - BUG/MINOR: lua: warn when registering action, conv, sf, cli or applet multiple times + - MINOR: cache: Improve accept_encoding_normalizer + - MINOR: cache: Add entry to the tree as soon as possible + - BUG/MINOR: trace: Wrong displayed trace level + - BUG/MAJOR: ring: tcp forward on ring can break the reader counter. + - MINOR: lua: simplify hlua_alloc() to only rely on realloc() + - MEDIUM: lua-thread: use atomics for memory accounting + - MINOR: lua-thread: remove struct hlua from function hlua_prepend_path() + - MEDIUM: lua-thread: make hlua_post_init() no longer use the runtime execution function + - MINOR: lua-thread: hlua_ctx_renew() is never called with main gL lua state + - MINOR: lua-thread: Use NULL context for main lua state + - MINOR: lua-thread: Stop usage of struct hlua for the global lua state + - MINOR: lua-thread: Replace embedded struct hlua_function by a pointer + - MINOR: lua-thread: Split hlua_init() function in two parts + - MINOR: lua-thread: make hlua_ctx_init() get L from its caller + - MINOR: lua-thread: Split hlua_load function in two parts + - MINOR: lua-thread: Split hlua_post_init() function in two parts + - MINOR: lua-thread: Add the "thread" core variable + - MEDIUM: lua-thread: No longer use locked context in initialization parts + - MEDIUM: lua-thread: Apply lock only if the parent state is the main thread + - MINOR: lua-thread: Replace global gL var with an array of states + - MINOR: lua-thread: Replace "struct hlua_function" allocation by dedicated function + - MINOR: lua-thread: Replace state_from by state_id + - MINOR: lua-thread: Store each function reference and init reference in array + - MEDIUM: lua-thread: Add the lua-load-per-thread directive + - MINOR: lua-thread: Add verbosity in errors + - REGTESTS: add a test for the threaded Lua code + - BUILD/MINOR: haproxy DragonFlyBSD affinity build update. + - DOC/MINOR: Fix formatting in Management Guide + - MINOR: cache: Do not store stale entry + - MINOR: cache: Add extra "cache-control" value checks + - MEDIUM: cache: Remove cache entry in case of POST on the same resource + - MINOR: cache: Consider invalid Age values as stale + - BUG/MEDIUM: lua-thread: some parts must be initialized once + - BUG/MINOR: lua-thread: close all states on deinit + - BUG/MINOR: listener: use sockaddr_in6 for IPv6 + - BUG/MINOR: mux-h1: Handle keep-alive timeout for idle frontend connections + - MINOR: session: Add the idle duration field into the session + - MINOR: mux-h1: Update session idle duration when data are received + - MINOR: mux-h1: Reset session dates and durations info when the CS is detached + - MINOR: logs: Use session idle duration when no stream is provided + - MINOR: stream: Always get idle duration from the session + - MINOR: stream: Don't retrieve anymore timing info from the mux csinfo + - MINOR: mux-h1: Don't provide anymore timing info using cs_info structure + - MINOR: muxes: Remove get_cs_info callback function now useless + - MINOR: stream: Pass an optional input buffer when a stream is created + - MINOR: mux-h1: Add a flag to disable reads to wait opposite side + - MEDIUM: mux-h1: Use a h1c flag to block reads when splicing is in-progress + - MINOR: mux-h1: Introduce H1C_F_IS_BACK flag on the H1 connection + - MINOR: mux-h1: Separate parsing and formatting errors at H1 stream level + - MINOR: mux-h1: Split front/back h1 stream creation in 2 functions + - MINOR: mux-h1: Add a rxbuf into the H1 stream + - MINOR: mux-h1: Don't set CS flags in internal parsing functions + - MINOR: mux-h1: Add embryonic and attached states on the H1 connection + - MINOR: mux-h1: rework the h1_timeout_task() function + - MINOR: mux-h1: Reset more H1C flags when a H1 stream is destroyed + - MINOR: mux-h1: Disable reads if an error was reported on the H1 stream + - MINOR: mux-h1: Rework how shutdowns are handled + - MINOR: mux-h1: Rework h1_refresh_timeout to be easier to read + - MINOR: mux-h1: Process next request for IDLE connection only + - MINOR: mux-h1: Add a idle expiration date on the H1 connection + - MINOR: stick-tables: Add functions to update some values of a tracked counter + - MINOR: session: Add functions to increase http values of tracked counters + - MINOR: mux: Add a ctl parameter to get the exit status of the multiplexers + - MINOR: logs: Get the multiplexer exist status when no stream is provided + - MINOR: mux-h1: Add functions to send HTTP errors from the mux + - MAJOR: mux-h1: Create the client stream as later as possible + - DOC: config: Add notes about errors emitted by H1 mux + - CLEANUP: mux-h1: Rename H1C_F_CS_* flags and reorder H1C flags + - MINOR: http-ana: Remove useless update of t_idle duration of the stream + - CLEANUP: htx: Remove HTX_FL_UPGRADE unsued flag + - MEDIUM: http-ana: Don't process partial or empty request anymore + - CLEANUP: http-ana: Remove TX_WAIT_NEXT_RQ unsued flag + - CLEANUP: connection: Remove CS_FL_READ_PARTIAL flag + - REGTESTS: Fix proxy_protocol_tlv_validation + - MINOR: http-ana: Properly set message flags from the start-line flags + - MINOR: h1-htx/http-ana: Set BODYLESS flag on message in TUNNEL state + - MINOR: protocol: add a ->set_port() helper to address families + - MINOR: listener: automatically set the port when creating listeners + - MINOR: listener: now use a generic add_listener() function + - MEDIUM: ssl: fatal error with bundle + openssl < 1.1.1 + - BUG/MEDIUM: stream: Xfer the input buffer to a fully created stream + - BUG/MINOR: stream: Don't use input buffer after the ownership xfer + - MINOR: protocol: remove the redundant ->sock_domain field + - MINOR: protocol: export protocol definitions + - CLEANUP: protocol: group protocol struct members by usage + - MINOR: protocol: add a set of ctrl_init/ctrl_close methods for setup/teardown + - MINOR: connection: use the control layer's init/close + - MINOR: udp: export udp_suspend_receiver() and udp_resume_receiver() + - BUG/MAJOR: spoa/python: Fixing return None + - DOC: spoa/python: Fixing typo in IP related error messages + - DOC: spoa/python: Rephrasing memory related error messages + - DOC: spoa/python: Fixing typos in comments + - BUG/MINOR: spoa/python: Cleanup references for failed Module Addobject operations + - BUG/MINOR: spoa/python: Cleanup ipaddress objects if initialization fails + - BUG/MEDIUM: spoa/python: Fixing PyObject_Call positional arguments + - BUG/MEDIUM: spoa/python: Fixing references to None + - DOC: email change of the DeviceAtlas maintainer + - MINOR: cache: Dump secondary entries in "show cache" + - CLEANUP: connection: use fd_stop_both() instead of conn_stop_polling() + - MINOR: stream-int: don't touch polling anymore on shutdown + - MINOR: connection: implement cs_drain_and_close() + - MINOR: mux-pt: take care of CS_SHR_DRAIN in shutr() + - MINOR: checks: use cs_drain_and_close() instead of draining the connection + - MINOR: checks: don't call conn_cond_update_polling() anymore + - CLEANUP: connection: open-code conn_cond_update_polling() and update the comment + - CLEANUP: connection: remove the unused conn_{stop,cond_update}_polling() + - BUG/MINOR: http-check: Use right condition to consider HTX message as full + - BUG/MINOR: tcpcheck: Don't rearm the check timeout on each read + - MINOR: tcpcheck: Only wait for more payload data on HTTP expect rules + - BUG/MINOR: tools: make parse_time_err() more strict on the timer validity + - BUG/MINOR: tools: Reject size format not starting by a digit + - MINOR: action: define enum for timeout type of the set-timeout rule + - MINOR: stream: prepare the hot refresh of timeouts + - MEDIUM: stream: support a dynamic server timeout + - MEDIUM: stream: support a dynamic tunnel timeout + - MEDIUM: http_act: define set-timeout server/tunnel action + - MINOR: frontend: add client timeout sample fetch + - MINOR: backend: add timeout sample fetches + - MINOR: stream: add sample fetches + - MINOR: stream: add timeout sample fetches + - REGTESTS: add regtest for http-request set-timeout + - CLEANUP: remove the unused fd_stop_send() in conn_xprt_shutw{,_hard}() + - CLEANUP: connection: remove the unneeded fd_stop_{recv,send} on read0/shutw + - MINOR: connection: remove sock-specific code from conn_sock_send() + - REORG: connection: move the socket iocb (conn_fd_handler) to sock.c + - MINOR: protocol: add a ->drain() function at the connection control layer + - MINOR: connection: make conn_sock_drain() use the control layer's ->drain() + - MINOR: protocol: add a pair of check_events/ignore_events functions at the ctrl layer + - MEDIUM: connection: make use of the control layer check_events/ignore_events + +2020/12/01 : 2.4-dev2 + - BUILD: Make DEBUG part of .build_opts + - BUILD: Show the value of DEBUG= in haproxy -vv + - CI: Set DEBUG=-DDEBUG_STRICT=1 in GitHub Actions + - MINOR: stream: Add level 7 retries on http error 401, 403 + - CLEANUP: remove unused function "ssl_sock_is_ckch_valid" + - BUILD: SSL: add BoringSSL guarding to "RAND_keep_random_devices_open" + - BUILD: SSL: do not "update" BoringSSL version equivalent anymore + - BUG/MEDIUM: http_act: Restore init of log-format list + - DOC: better describes how to configure a fallback crt + - BUG/MAJOR: filters: Always keep all offsets up to date during data filtering + - MINOR: cache: Prepare helper functions for Vary support + - MEDIUM: cache: Add the Vary header support + - MINOR: cache: Add a process-vary option that can enable/disable Vary processing + - BUG/CRITICAL: cache: Fix trivial crash by sending accept-encoding header + - BUG/MAJOR: peers: fix partial message decoding + - DOC: cache: Add new caching limitation information + - DOC: cache: Add information about Vary support + - DOC: better document the config file format and escaping/quoting rules + - DOC: Clarify %HP description in log-format + - CI: github actions: update LibreSSL to 3.3.0 + - CI: github actions: enable 51degrees feature + - MINOR: fd/threads: silence a build warning with threads disabled + - BUG/MINOR: tcpcheck: Don't forget to reset tcp-check flags on new kind of check + - MINOR: tcpcheck: Don't handle anymore in-progress send rules in tcpcheck_main + - BUG/MAJOR: tcpcheck: Allocate input and output buffers from the buffer pool + - MINOR: tcpcheck: Don't handle anymore in-progress connect rules in tcpcheck_main + - MINOR: config: Deprecate and ignore tune.chksize global option + - MINOR: config: Add a warning if tune.chksize is used + - REORG: tcpcheck: Move check option parsing functions based on tcp-check + - MINOR: check: Always increment check health counter on CONPASS + - MINOR: tcpcheck: Add support of L7OKC on expect rules error-status argument + - DOC: config: Make disable-on-404 option clearer on transition conditions + - DOC: config: Move req.hdrs and req.hdrs_bin in L7 samples fetches section + - BUG/MINOR: http-fetch: Fix smp_fetch_body() when called from a health-check + - MINOR: plock: use an ARMv8 instruction barrier for the pause instruction + - MINOR: debug: add "debug dev sched" to stress the scheduler. + - MINOR: debug: add a trivial PRNG for scheduler stress-tests + - BUG/MEDIUM: lists: Lock the element while we check if it is in a list. + - MINOR: task: remove tasklet_insert_into_tasklet_list() + - MINOR: task: perform atomic counter increments only once per wakeup + - MINOR: task: remove __tasklet_remove_from_tasklet_list() + - BUG/MEDIUM: task: close a possible data race condition on a tasklet's list link + - BUG/MEDIUM: local log format regression. + +2020/11/21 : 2.4-dev1 + - MINOR: ist: Add istend() function to return a pointer to the end of the string + - MINOR: sample: Add converters to parse FIX messages + - REGTEST: converter: Add a regtest for fix converters + - MINOR: sample: Add converts to parses MQTT messages + - REGTEST: converter: Add a regtest for MQTT converters + - MINOR: compat: automatically include malloc.h on glibc + - MEDIUM: pools: call malloc_trim() from pool_gc() + - MEDIUM: pattern: call malloc_trim() on pat_ref_reload() + - MINOR: pattern: move the update revision to the pat_ref, not the expression + - CLEANUP: pattern: delete the back refs at once during pat_ref_reload() + - MINOR: pattern: new sflag PAT_SF_REGFREE indicates regex_free() is needed + - MINOR: pattern: make the delete and prune functions more generic + - MEDIUM: pattern: link all final elements from the reference + - MEDIUM: pattern: change the pat_del_* functions to delete from the references + - MINOR: pattern: remerge the list and tree deletion functions + - MINOR: pattern: perform a single call to pat_delete_gen() under the expression + - CLEANUP: acl: don't reference the generic pattern deletion function anymore + - CLEANUP: pattern: remove pat_delete_fcts[] and pattern_head->delete() + - MINOR: pattern: introduce pat_ref_delete_by_ptr() to delete a valid reference + - MINOR: pattern: store a generation number in the reference patterns + - MEDIUM: pattern: only match patterns that match the current generation + - MINOR: pattern: add pat_ref_commit() to commit a previously inserted element + - MINOR: pattern: implement pat_ref_load() to load a pattern at a given generation + - MINOR: pattern: add pat_ref_purge_older() to purge old entries + - MEDIUM: pattern: make pat_ref_prune() rely on pat_ref_purge_older() + - MINOR: pattern: during reload, delete elements frem the ref, not the expression + - MINOR: pattern: prepare removal of a pattern from the list head + - MEDIUM: pattern: turn the pattern chaining to single-linked list + - CLEANUP: cfgparse: remove duplicate registration for transparent build options + - BUG/MINOR: ssl: don't report 1024 bits DH param load error when it's higher + - MINOR: http-htx: Add understandable errors for the errorfiles parsing + - MINOR: ssl: instantiate stats module + - MINOR: ssl: count client hello for stats + - MINOR: ssl: add counters for ssl sessions + - DOC: config: Fix a typo on ssl_c_chain_der + - MINOR: server: remove idle lock in srv_cleanup_connections + - BUILD: ssl: silence build warning on uninitialised counters + - BUILD: http-htx: fix build warning regarding long type in printf + - REGTEST: ssl: test wildcard and multi-type + exclusions + - BUG/MEDIUM: ssl/crt-list: correctly insert crt-list line if crt already loaded + - CI: Expand use of GitHub Actions for CI + - REGTEST: ssl: mark reg-tests/ssl/ssl_crt-list_filters.vtc as broken + - BUG/MINOR: pattern: a sample marked as const could be written + - BUG/MINOR: lua: set buffer size during map lookups + - MEDIUM: cache: Change caching conditions + - BUG/MINOR: stats: free dynamically stats fields/lines on shutdown + - BUG/MEDIUM: stats: prevent crash if counters not alloc with dummy one + - MINOR: peers: Add traces to peer_treat_updatemsg(). + - BUG/MINOR: peers: Do not ignore a protocol error for dictionary entries. + - BUG/MINOR: peers: Missing TX cache entries reset. + - BUG/MEDIUM: peers: fix decoding of multi-byte length in stick-table messages + - BUG/MINOR: http-fetch: Extract cookie value even when no cookie name + - BUG/MINOR: http-fetch: Fix calls w/o parentheses of the cookie sample fetches + - BUG/MEDIUM: check: reuse srv proto only if using same mode + - MINOR: check: report error on incompatible proto + - MINOR: check: report error on incompatible connect proto + - BUG/MINOR: http-htx: Handle warnings when parsing http-error and http-errors + - BUG/MAJOR: spoe: Be sure to remove all references on a released spoe applet + - MINOR: spoe: Don't close connection in sync mode on processing timeout + - BUG/MINOR: tcpcheck: Don't warn on unused rules if check option is after + - MINOR: init: Fix the prototype for per-thread free callbacks + - MINOR: config/mux-h2: Return ERR_ flags from init_h2() instead of a status + - CLEANUP: config: Return ERR_NONE from config callbacks instead of 0 + - MINOR: cfgparse: tighten the scope of newnameserver variable, free it on error. + - REGTEST: make ssl_client_samples and ssl_server_samples require to 2.2 + - REGTESTS: Add sample_fetches/cook.vtc + - BUG/MEDIUM: filters: Forward all filtered data at the end of http filtering + - BUG/MINOR: http-ana: Don't wait for the body of CONNECT requests + - CLEANUP: flt-trace: Remove unused random-parsing option + - MINOR: flt-trace: Add an option to inhibits trace messages + - MINOR: flt-trace: Use a bitfield for the trace options + - REGTESTS: Add a script to test the random forwarding with several filters + - REGTESTS: mark the abns test as broken again + - REGTESTS: converter: add url_dec test + - CI: Stop hijacking the hosts file + - CI: Make the h2spec workflow more consistent with the VTest workflow + - CI: travis-ci: remove amd64, osx builds + - CI: travis-ci: arm64 are not allowed to fail anymore + - DOC: add missing 3.10 in the summary + - MINOR: ssl: remove client hello counters + - MEDIUM: stats: add counters for failed handshake + - MINOR: ssl: create common ssl_ctx init + - MEDIUM: cli/ssl: configure ssl on server at runtime + - REGTEST: server/cli_set_ssl.vtc requires OpenSSL + - DOC: coding-style: update a few rules about pointers + - BUG/MINOR: ssl: segv on startup when AKID but no keyid + - BUILD: ssl: use SSL_MODE_ASYNC macro instead of OPENSSL_VERSION + - BUG/MEDIUM: http-ana: Don't eval http-after-response ruleset on empty messages + - BUG/MEDIUM: ssl/crt-list: bundle support broken in crt-list + - BUG/MEDIUM: ssl: error when no certificate are found + - BUG/MINOR: ssl/crt-list: load bundle in crt-list only if activated + - BUG/MEDIUM: ssl/crt-list: fix error when no file found + - CI: Github Actions: enable prometheus exporter + - CI: Github Actions: remove LibreSSL-3.0.2 builds + - CI: Github Actions: enable BoringSSL builds + - CI: travis-ci: remove builds migrated to GH actions + - BUILD: makefile: enable crypt(3) for OpenBSD + - CI: Github Action: run "apt-get update" before packages restore + - BUILD: SSL: guard TLS13 ciphersuites with HAVE_SSL_CTX_SET_CIPHERSUITES + - CI: Pass the github.event_name to matrix.py + - CI: Clean up Windows CI + - DOC: clarify how to create a fallback crt + - CLEANUP: connection: do not use conn->owner when the session is known + - BUG/MAJOR: connection: reset conn->owner when detaching from session list + - REGTESTS: mark proxy_protocol_random_fail as broken + - BUG/MINOR: http_htx: Fix searching headers by substring + - MINOR: http_act: Add -m flag for del-header name matching method + +2020/11/05 : 2.4-dev0 + - MINOR: version: it's development again. + - DOC: mention in INSTALL that it's development again + +2020/11/05 : 2.3.0 + - CLEANUP: pattern: remove unused entry "tree" in pattern.val + - BUILD: ssl: use SSL_CTRL_GET_RAW_CIPHERLIST instead of OpenSSL versions + - BUG/MEDIUM: filters: Don't try to init filters for disabled proxies + - BUG/MINOR: proxy/server: Skip per-proxy/server post-check for disabled proxies + - BUG/MINOR: checks: Report a socket error before any connection attempt + - BUG/MINOR: server: Set server without addr but with dns in RMAINT on startup + - MINOR: server: Copy configuration file and line for server templates + - BUG/MEDIUM: mux-pt: Release the tasklet during an HTTP upgrade + - BUILD: ssl: use HAVE_OPENSSL_KEYLOG instead of OpenSSL versions + - MINOR: debug: don't count free(NULL) in memstats + - BUG/MINOR: filters: Skip disabled proxies during startup only + - MINOR: mux_h2: capitalize frame type in stats + - MINOR: mux_h2: add stat for total count of connections/streams + - MINOR: stats: do not display empty stat module title on html + - BUG/MEDIUM: stick-table: limit the time spent purging old entries + - BUG/MEDIUM: listener: only enable a listening listener if needed + - BUG/MEDIUM: listener: never suspend inherited sockets + - BUG/MEDIUM: listener: make the master also keep workers' inherited FDs + - MINOR: fd: add fd_want_recv_safe() + - MEDIUM: listeners: make use of fd_want_recv_safe() to enable early receivers + - REGTESTS: mark abns_socket as working now + - CLEANUP: mux-h2: Remove the h1 parser state from the h2 stream + - MINOR: sock: add a check against cross worker<->master socket activities + - CI: github actions: limit OpenSSL no-deprecated builds to "default,bug,devel" reg-tests + - BUG/MEDIUM: server: make it possible to kill last idle connections + - MINOR: mworker/cli: the master CLI use its own applet + - MINOR: ssl: define SSL_CTX_set1_curves_list to itself on BoringSSL + - BUILD: ssl: use feature macros for detecting ec curves manipulation support + - DOC: Add dns as an available domain to show stat + - BUILD: makefile: usual reorder of objects for faster builds + - DOC: update INSTALL to mention that TCC is supported + - DOC: mention in INSTALL that haproxy 2.3 is a stable version + - MINOR: version: mention that it's stable now + +2020/10/31 : 2.3-dev9 + - CLEANUP: http_ana: remove unused assignation of `att_beg` + - BUG/MEDIUM: ssl: OCSP must work with BoringSSL + - BUG/MINOR: log: fix memory leak on logsrv parse error + - BUG/MINOR: log: fix risk of null deref on error path + - BUILD: ssl: more elegant OpenSSL early data support check + - CI: github actions: update h2spec to 2.6.0 + - BUG/MINOR: cache: Check the return value of http_replace_res_status + - MINOR: cache: Store the "Last-Modified" date in the cache_entry + - MINOR: cache: Process the If-Modified-Since header in conditional requests + - MINOR: cache: Create res.cache_hit and res.cache_name sample fetches + - MINOR: mux-h2: register a stats module + - MINOR: mux-h2: add counters instance to h2c + - MINOR: mux-h2: add stats for received frame types + - MINOR: mux-h2: report detected error on stats + - MINOR: mux-h2: count open connections/streams on stats + - BUG/MINOR: server: fix srv downtime calcul on starting + - BUG/MINOR: server: fix down_time report for stats + - BUG/MINOR: lua: initialize sample before using it + - MINOR: cache: Add Expires header value parsing + - MINOR: ist: Add a case insensitive istmatch function + - BUG/MINOR: cache: Manage multiple values in cache-control header value + - BUG/MINOR: cache: Inverted variables in http_calc_maxage function + - MINOR: pattern: make pat_ref_append() return the newly added element + - MINOR: pattern: make pat_ref_add() rely on pat_ref_append() + - MINOR: pattern: export pat_ref_push() + - CLEANUP: pattern: use calloc() rather than malloc for structures + - CLEANUP: pattern: fix spelling/grammatical/copy-paste in comments + +2020/10/24 : 2.3-dev8 + - MINOR: backend: replace the lbprm lock with an rwlock + - MINOR: lb/map: use seek lock and read locks where appropriate + - MINOR: lb/leastconn: only take a read lock in fwlc_get_next_server() + - MINOR: lb/first: use a read lock in fas_get_next_server() + - MINOR: lb/chash: use a read lock in chash_get_server_hash() + - BUG/MINOR: disable dynamic OCSP load with BoringSSL + - BUILD: ssl: make BoringSSL use its own version numbers + - CLEANUP: threads: don't register an initcall when not debugging + - MINOR: threads: change lock_t to an unsigned int + - CLEANUP: tree-wide: reorder a few structures to plug some holes around locks + - CLEANUP: task: remove the unused and mishandled global_rqueue_size + - BUG/MEDIUM: connection: Never cleanup server lists when freeing private conns + - MEDIUM: config: report that "nbproc" is deprecated + - BUG/MINOR: listener: close before free in `listener_accept` + - MINOR: ssl: 'ssl-load-extra-del-ext' removes the certificate extension + - BUG/MINOR: queue: properly report redistributed connections + - CONTRIB: tcploop: remove unused local variables in tcp_pause() + - BUILD: makefile: add entries to build common debugging tools + - BUG/MEDIUM: server: support changing the slowstart value from state-file + - MINOR: http: Add `enum etag_type http_get_etag_type(const struct ist)` + - MINOR: http: Add etag comparison function + - MEDIUM: cache: Store the ETag information in the cache_entry + - MEDIUM: cache: Add support for 'If-None-Match' request header + - REGTEST: cache: Add if-none-match test case + - CLEANUP: compression: Make use of http_get_etag_type() + - BUG/MINOR: http-ana: Don't send payload for internal responses to HEAD requests + - BUG/MAJOR: mux-h2: Don't try to send data if we know it is no longer possible + - MINOR: threads/debug: only report used lock stats + - MINOR: threads/debug: only report lock stats for used operations + - MINOR: proxy; replace the spinlock with an rwlock + - MINOR: server: read-lock the cookie during srv_set_dyncookie() + - MINOR: proxy/cli: only take a read lock in "show errors" + - OPTIM: queue: don't call pendconn_unlink() when the pendconn is not queued + - MINOR: queue: split __pendconn_unlink() in per-srv and per-prx + - MINOR: queue: reduce the locked area in pendconn_add() + - OPTIM: queue: make the nbpend counters atomic + - OPTIM: queue: decrement the nbpend and totpend counters outside of the lock + - MINOR: leastconn: take the queue length into account when queuing servers + - MEDIUM: fwlc: re-enable per-server queuing up to maxqueue + - Revert "OPTIM: queue: don't call pendconn_unlink() when the pendconn is not queued" + - MINOR: stats: support the "up" output modifier for "show stat" + - MINOR: stats: also support a "no-maint" show stat modifier + - MINOR: stats: indicate the number of servers in a backend's status + - MEDIUM: ssl: ssl-load-extra-del-ext work only with .crt + - REGTEST: ssl: test "set ssl cert" with separate key / crt + - DOC: management: apply the "show stat" modifiers to "show stat", not "show info" + - MINOR: stats: report server's user-configured weight next to effective weight + - CI: travis-ci: switch to Ubuntu 20.04 + - CONTRIB: release-estimator: Add release estimating tool + - BUG/MEDIUM: queue: fix unsafe proxy pointer when counting nbpend + - BUG/MINOR: extcheck: add missing checks on extchk_setenv() + +2020/10/17 : 2.3-dev7 + - CI: travis-ci: replace not defined SSL_LIB, SSL_INC for BotringSSL builds + - BUG/MINOR: init: only keep rlim_fd_cur if max is unlimited + - BUG/MINOR: mux-h2: do not stop outgoing connections on stopping + - MINOR: fd: report an error message when failing initial allocations + - MINOR: proto-tcp: make use of connect(AF_UNSPEC) for the pause + - MINOR: sock: add sock_accept_conn() to test a listening socket + - MINOR: protocol: make proto_tcp & proto_uxst report listening sockets + - MINOR: sockpair: implement the .rx_listening function + - CLEANUP: tcp: make use of sock_accept_conn() where relevant + - CLEANUP: unix: make use of sock_accept_conn() where relevant + - BUG/MINOR: listener: detect and handle shared sockets stopped in other processes + - CONTRIB: tcploop: implement a disconnect operation 'D' + - CLEANUP: protocol: intitialize all of the sockaddr when disconnecting + - BUG/MEDIUM: deinit: check fdtab before fdtab[fd].owner + - BUG/MINOR: connection: fix loop iter on connection takeover + - BUG/MEDIUM: connection: fix srv idle count on conn takeover + - MINOR: connection: improve list api usage + - MINOR: mux/connection: add a new mux flag for HOL risk + - MINOR: connection: don't check priv flag on free + - MEDIUM: backend: add new conn to session if mux marked as HOL blocking + - MEDIUM: backend: add reused conn to sess if mux marked as HOL blocking + - MEDIUM: h2: remove conn from session on detach + - MEDIUM: fcgi: remove conn from session on detach + - DOC: Describe reuse safe for HOL handling + - MEDIUM: proxy: remove obsolete "mode health" + - MEDIUM: proxy: remove obsolete "monitor-net" + - CLEANUP: protocol: remove the ->drain() function + - CLEANUP: fd: finally get rid of fd_done_recv() + - MINOR: connection: make sockaddr_alloc() take the address to be copied + - MEDIUM: listener: allocate the connection before queuing a new connection + - MINOR: session: simplify error path in session_accept_fd() + - MINOR: connection: add new error codes for accept_conn() + - MINOR: sock: rename sock_accept_conn() to sock_accepting_conn() + - MINOR: protocol: add a new function accept_conn() + - MINOR: sock: implement sock_accept_conn() to accept a connection + - MINOR: sockpair: implement sockpair_accept_conn() to accept a connection + - MEDIUM: listener: use protocol->accept_conn() to accept a connection + - MEDIUM: listener: remove the second pass of fd manipulation at the end + - MINOR: protocol: add a default I/O callback and put it into the receiver + - MINOR: log: set the UDP receiver's I/O handler in the receiver + - MINOR: protocol: register the receiver's I/O handler and not the protocol's + - CLEANUP: protocol: remove the now unused field of proto_fam->bind() + - DOC: improve the documentation for "option nolinger" + - BUG/MEDIUM: proxy: properly stop backends + - BUG/MEDIUM: task: bound the number of tasks picked from the wait queue at once + - MINOR: threads: augment rwlock debugging stats to report seek lock stats + - MINOR: threads: add the transitions to/from the seek state + - MEDIUM: task: use an upgradable seek lock when scanning the wait queue + - BUILD: listener: avoir a build warning when threads are disabled + - BUG/MINOR: peers: Possible unexpected peer seesion reset after collisions. + - MINOR: ssl: add volatile flags to ssl samples + - MEDIUM: backend: reuse connection if using a static sni + - BUG/MEDIUM: spoe: Unset variable instead of set it if no data provided + - BUG/MEDIUM: mux-h1: Get the session from the H1S when capturing bad messages + - BUG/MEDIUM: lb: Always lock the server when calling server_{take,drop}_conn + - DOC: fix typo in MAX_SESS_STKCTR + +2020/10/10 : 2.3-dev6 + - REGTESTS: use "command" instead of "which" for better POSIX compatibility + - BUILD: makefile: Update feature flags for OpenBSD + - DOC: agent-check: fix typo in "fail" word expected reply + - DOC: crt: advise to move away from cert bundle + - BUG/MINOR: ssl/crt-list: exit on warning out of crtlist_parse_line() + - REGTEST: fix host part in balance-uri-path-only.vtc + - REGTEST: make ssl_client_samples and ssl_server_samples requiret to 2.3 + - REGTEST: the iif converter test requires 2.3 + - REGTEST: make agent-check.vtc require 1.8 + - REGTEST: make abns_socket.vtc require 1.8 + - REGTEST: make map_regm_with_backref require 1.7 + - BUILD: makefile: Update feature flags for FreeBSD + - OPTIM: backend/random: never queue on the server, always on the backend + - OPTIM: backend: skip LB when we know the backend is full + - BUILD: makefile: Fix building with closefrom() support enabled + - BUILD: makefile: add an EXTRAVERSION variable to ease local naming + - MINOR: tools: support for word expansion of environment in parse_line + - BUILD: tools: fix minor build issue on isspace() + - BUILD: makefile: Enable closefrom() support on Solaris + - CLEANUP: ssl: Use structured format for error line report during crt-list parsing + - MINOR: ssl: Add error if a crt-list might be truncated + - MINOR: ssl: remove uneeded check in crtlist_parse_file + - BUG/MINOR: Fix several leaks of 'log_tag' in init(). + - DOC: tcp-rules: Refresh details about L7 matching for tcp-request content rules + - MEDIUM: tcp-rules: Warn if a track-sc* content rule doesn't depend on content + - BUG/MINOR: tcpcheck: Set socks4 and send-proxy flags before the connect call + - DOC: ssl: new "cert bundle" behavior + - BUG/MEDIUM: queue: make pendconn_cond_unlink() really thread-safe + - CLEANUP: ssl: "bundle" is not an OpenSSL wording + - MINOR: counters: fix a typo in comment + - BUG/MINOR: stats: fix validity of the json schema + - REORG: stats: export some functions + - MINOR: stats: add stats size as a parameter for csv/json dump + - MINOR: stats: hide px/sv/li fields in applet struct + - REORG: stats: extract proxy json dump + - REORG: stats: extract proxies dump loop in a function + - MINOR: hlua: Display debug messages on stderr only in debug mode + - MINOR: stats: define the concept of domain for statistics + - MINOR: stats: define additional flag px cap on domain + - MEDIUM: stats: add delimiter for static proxy stats on csv + - MEDIUM: stats: define an API to register stat modules + - MEDIUM: stats: add abstract type to store counters + - MEDIUM: stats: integrate static proxies stats in new stats + - MINOR: stats: support clear counters for dynamic stats + - MINOR: stats: display extra proxy stats on the html page + - MINOR: stats: add config "stats show modules" + - MINOR: dns/stats: integrate dns counters in stats + - MINOR: stats: remove for loop declaration + - DOC: ssl: fix typo about ocsp files + - BUG/MINOR: peers: Inconsistency when dumping peer status codes. + - DOC: update INSTALL with supported OpenBSD / FreeBSD versions + - BUG/MINOR: proto_tcp: Report warning messages when listeners are bound + - CLEANUP: cache: Fix leak of cconf->c.name during config check + - CLEANUP: ssl: Release cached SSL sessions on deinit + - BUG/MINOR: mux-h1: Be sure to only set CO_RFL_READ_ONCE for the first read + - BUG/MINOR: mux-h1: Always set the session on frontend h1 stream + - MINOR: mux-h1: Don't wakeup the H1C when output buffer become available + - CLEANUP: sock-unix: Remove an unreachable goto clause + - BUG/MINOR: proxy: inc req counter on new syslog messages. + - BUG/MEDIUM: log: old processes with log foward section don't die on soft stop. + - MINOR: stats: inc req counter on listeners. + - MINOR: channel: new getword and getchar functions on channel. + - MEDIUM: log: syslog TCP support on log forward section. + - BUG/MINOR: proxy/log: frontend/backend and log forward names must differ + - DOC: re-work log forward bind statement documentation. + - DOC: fix a confusing typo on a regsub example + - BUILD: Add a DragonFlyBSD target + - BUG/MINOR: makefile: fix a tiny typo in the target list + - BUILD: makefile: Update feature flags for NetBSD + - CI: travis-ci: help Coverity to detect BUG_ON() as a real stop + - DOC: Add missing stats fields in the management doc + - BUG/MEDIUM: mux-fcgi: Don't handle pending read0 too early on streams + - BUG/MEDIUM: mux-h2: Don't handle pending read0 too early on streams + - DOC: Fix typos in configuration.txt + - BUG/MINOR: http: Fix content-length of the default 500 error + - BUG/MINOR: http-htx: Expect no body for 204/304 internal HTTP responses + - REGTESTS: mark abns_socket as broken + - MEDIUM: fd: always wake up one thread when enabling a foreing FD + - MEDIUM: listeners: don't bounce listeners management between queues + - MEDIUM: init: stop disabled proxies after initializing fdtab + - MEDIUM: listeners: make unbind_listener() converge if needed + - MEDIUM: deinit: close all receivers/listeners before scanning proxies + - MEDIUM: listeners: remove the now unused ZOMBIE state + - MINOR: listeners: do not uselessly try to close zombie listeners in soft_stop() + - CLEANUP: proxy: remove the first_to_listen hack in zombify_proxy() + - MINOR: listeners: introduce listener_set_state() + - MINOR: proxy: maintain per-state counters of listeners + - MEDIUM: proxy: remove the unused PR_STFULL state + - MEDIUM: proxy: remove the PR_STERROR state + - MEDIUM: proxy: remove state PR_STPAUSED + - MINOR: startup: don't rely on PR_STNEW to check for listeners + - CLEANUP: peers: don't use the PR_ST* states to mark enabled/disabled + - MEDIUM: proxy: replace proxy->state with proxy->disabled + - MEDIUM: proxy: remove start_proxies() + - MEDIUM: proxy: merge zombify_proxy() with stop_proxy() + - MINOR: listeners: check the current listener state in pause_listener() + - MINOR: listeners: check the current listener earlier state in resume_listener() + - MEDIUM: listener/proxy: make the listeners notify about proxy pause/resume + - MINOR: protocol: introduce protocol_{pause,resume}_all() + - MAJOR: signals: use protocol_pause_all() and protocol_resume_all() + - CLEANUP: proxy: remove the now unused pause_proxies() and resume_proxies() + - MEDIUM: proto_tcp: make the pause() more robust in multi-process + - BUG/MEDIUM: listeners: correctly report pause() errors + - MINOR: listeners: move fd_stop_recv() to the receiver's socket code + - CLEANUP: protocol: remove the ->disable_all method + - CLEANUP: listeners: remove unused disable_listener and disable_all_listeners + - MINOR: listeners: export enable_listener() + - MINOR: protocol: directly call enable_listener() from protocol_enable_all() + - CLEANUP: protocol: remove the ->enable_all method + - CLEANUP: listeners: remove the now unused enable_all_listeners() + - MINOR: protocol: rename the ->listeners field to ->receivers + - MINOR: protocol: replace ->pause(listener) with ->rx_suspend(receiver) + - MINOR: protocol: implement an ->rx_resume() method + - MINOR: listener: use the protocol's ->rx_resume() method when available + - MINOR: sock: provide a set of generic enable/disable functions + - MINOR: protocol: add a new pair of rx_enable/rx_disable methods + - MINOR: protocol: add a new pair of enable/disable methods for listeners + - MEDIUM: listeners: now use the listener's ->enable/disable + - MINOR: listeners: split delete_listener() in two versions + - MINOR: listeners: count unstoppable jobs on creation, not deletion + - MINOR: listeners: add a new stop_listener() function + - MEDIUM: proxy: make stop_proxy() now use stop_listener() + - MEDIUM: proxy: add mode PR_MODE_PEERS to flag peers frontends + - MEDIUM: proxy: centralize proxy status update and reporting + - MINOR: protocol: add protocol_stop_now() to instant-stop listeners + - MEDIUM: proxy: make soft_stop() stop most listeners using protocol_stop_now() + - MEDIUM: udp: implement udp_suspend() and udp_resume() + - MINOR: listener: add a few BUG_ON() statements to detect inconsistencies + - MEDIUM: listeners: always close master vs worker listeners + - BROKEN/MEDIUM: listeners: rework the unbind logic to make it idempotent + - MEDIUM: listener: let do_unbind_listener() decide whether to close or not + - CLEANUP: listeners: remove the do_close argument to unbind_listener() + - MINOR: listeners: move the LI_O_MWORKER flag to the receiver + - MEDIUM: receivers: add an rx_unbind() method in the protocols + - MINOR: listeners: split do_unbind_listener() in two + - MEDIUM: listeners: implement protocol level ->suspend/resume() calls + - MEDIUM: config: mark "grace" as deprecated + - MEDIUM: config: remove the deprecated and dangerous global "debug" directive + - BUG/MINOR: proxy: respect the proper format string in sig_pause/sig_listen + - MINOR: peers: heartbeat, collisions and handshake information for "show peers" command. + - BUILD: makefile: Enable getaddrinfo() on OS/X + +2020/09/25 : 2.3-dev5 + - DOC: Fix typo in iif() example + - CLEANUP: Update .gitignore + - BUILD: introduce possibility to define ABORT_NOW() conditionally + - CI: travis-ci: help Coverity to recognize abort() + - BUG/MINOR: Fix type passed of sizeof() for calloc() + - CLEANUP: Do not use a fixed type for 'sizeof' in 'calloc' + - CLEANUP: tree-wide: use VAR_ARRAY instead of [0] in various definitions + - BUILD: connection: fix build on clang after the VAR_ARRAY cleanup + - BUG/MINOR: ssl: verifyhost is case sensitive + - BUILD: makefile: change default value of CC from gcc to cc + - CI: travis-ci: split asan step out of running tests + - BUG/MINOR: server: report correct error message for invalid port on "socks4" + - BUG/MEDIUM: ssl: Don't call ssl_sock_io_cb() directly. + - BUG/MINOR: ssl/crt-list: crt-list could end without a \n + - BUG/MINOR: log-forward: fail on unknown keywords + - MEDIUM: log-forward: use "dgram-bind" instead of "bind" for the listener + - BUG/MEDIUM: log-forward: always quit on parsing errors + - MEDIUM: ssl: remove bundle support in crt-list and directories + - MEDIUM: ssl/cli: remove support for multi certificates bundle + - MINOR: ssl: crtlist_dup_ssl_conf() duplicates a ssl_bind_conf + - MINOR: ssl: crtlist_entry_dup() duplicates a crtlist_entry + - MEDIUM: ssl: emulates the multi-cert bundles in the crtlist + - MEDIUM: ssl: emulate multi-cert bundles loading in standard loading + - CLEANUP: ssl: remove test on "multi" variable in ckch functions + - CLEANUP: ssl/cli: remove test on 'multi' variable in CLI functions + - CLEANUP: ssl: remove utility functions for bundle + - DOC: explain bundle emulation in configuration.txt + - BUILD: fix build with openssl < 1.0.2 since bundle removal + - BUG/MINOR: log: gracefully handle the "udp@" address format for log servers + - BUG/MINOR: dns: gracefully handle the "udp@" address format for nameservers + - MINOR: listener: create a new struct "settings" in bind_conf + - MINOR: listener: move bind_proc and bind_thread to struct settings + - MINOR: listener: move the interface to the struct settings + - MINOR: listener: move the network namespace to the struct settings + - REORG: listener: create a new struct receiver + - REORG: listener: move the listening address to a struct receiver + - REORG: listener: move the receiving FD to struct receiver + - REORG: listener: move the listener's proto to the receiver + - MINOR: listener: make sock_find_compatible_fd() check the socket type + - REORG: listener: move the receiver part to a new file + - MINOR: receiver: link the receiver to its settings + - MINOR: receiver: link the receiver to its owner + - MINOR: listener: prefer to retrieve the socket's settings via the receiver + - MINOR: receiver: add a receiver-specific flag to indicate the socket is bound + - MINOR: listener: move the INHERITED flag down to the receiver + - MINOR: receiver: move the FOREIGN and V6ONLY options from listener to settings + - MINOR: sock: make sock_find_compatible_fd() only take a receiver + - MINOR: protocol: rename the ->bind field to ->listen + - MINOR: protocol: add a new ->bind() entry to bind the receiver + - MEDIUM: sock_inet: implement sock_inet_bind_receiver() + - MEDIUM: tcp: make use of sock_inet_bind_receiver() + - MEDIUM: udp: make use of sock_inet_bind_receiver() + - MEDIUM: sock_unix: implement sock_unix_bind_receiver() + - MEDIUM: uxst: make use of sock_unix_bind_receiver() + - MEDIUM: sockpair: implement sockpair_bind_receiver() + - MEDIUM: proto_sockpair: make use of sockpair_bind_receiver() + - MEDIUM: protocol: explicitly start the receiver before the listener + - MEDIUM: protocol: do not call proto->bind() anymore from bind_listener() + - MINOR: protocol: add a new proto_fam structure for protocol families + - MINOR: protocol: retrieve the family-specific fields from the family + - CLEANUP: protocol: remove family-specific fields from struct protocol + - MINOR: protocol: add a real family for existing FDs + - CLEANUP: tools: make str2sa_range() less awful for fd@ and sockpair@ + - MINOR: tools: make str2sa_range() take more options than just resolve + - MINOR: tools: add several PA_O_PORT_* flags in str2sa_range() callers + - MEDIUM: tools: make str2sa_range() validate callers' port specifications + - MEDIUM: config: remove all checks for missing/invalid ports/ranges + - MINOR: tools: add several PA_O_* flags in str2sa_range() callers + - MINOR: listener: remove the inherited arg to create_listener() + - MINOR: tools: make str2sa_range() optionally return the fd + - MINOR: log: detect LOG_TARGET_FD from the fd and not from the syntax + - MEDIUM: tools: make str2sa_range() resolve pre-bound listeners + - MINOR: config: do not test an inherited socket again + - MEDIUM: tools: make str2sa_range() check for the sockpair's FD usability + - MINOR: tools: start to distinguish stream and dgram in str2sa_range() + - MEDIUM: tools: make str2sa_range() only report AF_CUST_UDP on listeners + - MINOR: tools: remove the central test for "udp" in str2sa_range() + - MINOR: cfgparse: add str2receiver() to parse dgram receivers + - MINOR: log-forward: use str2receiver() to parse the dgram-bind address + - MEDIUM: config: make str2listener() not accept datagram sockets anymore + - MINOR: listener: pass the chosen protocol to create_listeners() + - MINOR: tools: make str2sa_range() directly return the protocol + - MEDIUM: tools: make str2sa_range() check that the protocol has ->connect() + - MINOR: protocol: add the control layer type in the protocol struct + - MEDIUM: protocol: store the socket and control type in the protocol array + - MEDIUM: tools: make str2sa_range() use protocol_lookup() + - MEDIUM: proto_udp: replace last AF_CUST_UDP* with AF_INET* + - MINOR: tools: drop listener detection hack from str2sa_range() + - BUILD: sock_unix: add missing errno.h + - MINOR: sock_inet: report the errno string in binding errors + - MINOR: sock_unix: report the errno string in binding errors + - BUILD: sock_inet: include errno.h + - MINOR: h2/trace: also display the remaining frame length in traces + - BUG/MINOR: h2/trace: do not display "stream error" after a frame ACK + - BUG/MEDIUM: h2: report frame bits only for handled types + - BUG/MINOR: http-fetch: Don't set the sample type during the htx prefetch + - BUG/MINOR: Fix memory leaks cfg_parse_peers + - BUG/MINOR: config: Fix memory leak on config parse listen + - MINOR: backend: make the "whole" option of balance uri take only one bit + - MINOR: backend: add a new "path-only" option to "balance uri" + - REGTESTS: add a few load balancing tests + - BUG/MEDIUM: listeners: do not pause foreign listeners + - BUG/MINOR: listeners: properly close listener FDs + - BUILD: trace: include tools.h + +2020/09/11 : 2.3-dev4 + - MINOR: hlua: Add error message relative to the Channel manipulation and HTTP mode + - BUG/MEDIUM: ssl: crt-list negative filters don't work + - DOC: overhauling github issue templates + - MEDIUM: cfgparse: Emit hard error on truncated lines + - DOC: cache: Use '' instead of '' in error message + - MINOR: cache: Reject duplicate cache names + - REGTEST: remove stray leading spaces in converteers_ref_cnt_never_dec.vtc + - MINOR: stats: prevent favicon.ico requests for stats page + - BUILD: tools: include auxv a bit later + - BUILD: task: work around a bogus warning in gcc 4.7/4.8 at -O1 + - MEDIUM: ssl: Support certificate chaining for certificate generation + - MINOR: ssl: Support SAN extension for certificate generation + - MINOR: tcp: don't try to set/clear v6only on inherited sockets + - BUG/MINOR: reload: detect the OS's v6only status before choosing an old socket + - MINOR: reload: determine the foreing binding status from the socket + - MEDIUM: reload: stop passing listener options along with FDs + - BUG/MEDIUM: ssl: fix ssl_bind_conf double free w/ wildcards + - MEDIUM: fd: replace usages of fd_remove() with fd_stop_both() + - CLEANUP: fd: remove fd_remove() and rename fd_dodelete() to fd_delete() + - MINOR: fd: add a new "exported" flag and use it for all regular listeners + - MEDIUM: reload: pass all exportable FDs, not just listeners + - DOC: add description of pidfile in master-worker mode + - BUG/MINOR: reload: do not fail when no socket is sent + - REORG: tcp: move TCP actions from proto_tcp.c to tcp_act.c + - CLEANUP: tcp: stop exporting smp_fetch_src() + - REORG: tcp: move TCP sample fetches from proto_tcp.c to tcp_sample.c + - REORG: tcp: move TCP bind/server keywords from proto_tcp.c to cfgparse-tcp.c + - REORG: unix: move UNIX bind/server keywords from proto_uxst.c to cfgparse-unix.c + - REORG: sock: start to move some generic socket code to sock.c + - MINOR: sock: introduce sock_inet and sock_unix + - MINOR: tcp/udp/unix: make use of proto->addrcmp() to compare addresses + - MINOR: sock_inet: implement sock_inet_get_dst() + - REORG: inet: replace tcp_is_foreign() with sock_inet_is_foreign() + - REORG: sock_inet: move v6only_default from proto_tcp.c to sock_inet.c + - REORG: sock_inet: move default_tcp_maxseg from proto_tcp.c + - REORG: listener: move xfer_sock_list to sock.{c,h}. + - MINOR: sock: add interface and namespace length to xfer_sock_list + - MINOR: sock: implement sock_find_compatible_fd() + - MINOR: sock_inet: move the IPv4/v6 transparent mode code to sock_inet + - REORG: sock: move get_old_sockets() from haproxy.c + - MINOR: sock: do not use LI_O_* in xfer_sock_list anymore + - MINOR: sock: distinguish dgram from stream types when retrieving old sockets + - BUILD: sock_unix: fix build issue with isdigit() + - BUG/MEDIUM: http-ana: Don't wait to send 1xx responses received from servers + - MINOR: http-htx: Add an option to eval query-string when the path is replaced + - BUG/MINOR: http-rules: Replace path and query-string in "replace-path" action + - MINOR: http-htx: Handle an optional reason when replacing the response status + - MINOR: contrib/spoa-server: allow MAX_FRAME_SIZE override + - BUG/MAJOR: contrib/spoa-server: Fix unhandled python call leading to memory leak + - BUG/MINOR: contrib/spoa-server: Ensure ip address references are freed + - BUG/MINOR: contrib/spoa-server: Do not free reference to NULL + - BUG/MINOR: contrib/spoa-server: Updating references to free in case of failure + - BUG/MEDIUM: contrib/spoa-server: Fix ipv4_address used instead of ipv6_address + - CLEANUP: http: silence a cppcheck warning in get_http_auth() + - REGTEST: increase some short timeouts to make tests more reliable + - BUG/MINOR: threads: work around a libgcc_s issue with chrooting + - BUILD: thread: limit the libgcc_s workaround to glibc only + - MINOR: protocol: do not call proto->bind_all() anymore + - MINOR: protocol: do not call proto->unbind_all() anymore + - CLEANUP: protocol: remove all ->bind_all() and ->unbind_all() functions + - MAJOR: init: start all listeners via protocols and not via proxies anymore + - BUG/MINOR: startup: haproxy -s cause 100% cpu + - Revert "BUG/MINOR: http-rules: Replace path and query-string in "replace-path" action" + - BUG/MEDIUM: doc: Fix replace-path action description + - MINOR: http-rules: Add set-pathq and replace-pathq actions + - MINOR: http-fetch: Add pathq sample fetch + - REGTEST: Add a test for request path manipulations, with and without the QS + - MINOR: Commit .gitattributes + - CLEANUP: Update .gitignore + - BUG/MEDIUM: dns: Don't store additional records in a linked-list + - BUG/MEDIUM: dns: Be sure to renew IP address for already known servers + - MINOR: server: Improve log message sent when server address is updated + - DOC: ssl-load-extra-files only applies to certificates on bind lines + - BUG/MINOR: auth: report valid crypto(3) support depending on build options + - BUG/MEDIUM: mux-h1: always apply the timeout on half-closed connections + - BUILD: threads: better workaround for late loading of libgcc_s + - BUILD: compiler: reserve the gcc version checks to the gcc compiler + - BUILD: compiler: workaround a glibc madness around __attribute__() + - BUILD: intops: on x86_64, the bswap instruction is called bswapq + - BUILD: trace: always have an argument before variadic args in macros + - BUILD: traces: don't pass an empty argument for missing ones + - BUG/MINOR: haproxy: Free uri_auth->scope during deinit + - CLEANUP: Free old_argv on deinit + - CLEANUP: haproxy: Free post_proxy_check_list in deinit() + - CLEANUP: haproxy: Free per_thread_*_list in deinit() + - CLEANUP: haproxy: Free post_check_list in deinit() + - BUG/MEDIUM: pattern: Renew the pattern expression revision when it is pruned + - REORG: tools: move PARSE_OPT_* from tools.h to tools-t.h + - MINOR: sample: Add iif(,) converter + +2020/08/14 : 2.3-dev3 + - SCRIPTS: git-show-backports: make -m most only show the left branch + - SCRIPTS: git-show-backports: emit the shell command to backport a commit + - BUILD: Makefile: require SSL_LIB, SSL_INC to be explicitly set + - CI: travis-ci: specify SLZ_LIB, SLZ_INC for travis builds + - BUG/MEDIUM: mux-h1: Refresh H1 connection timeout after a synchronous send + - CLEANUP: dns: typo in reported error message + - BUG/MAJOR: dns: disabled servers through SRV records never recover + - BUG/MINOR: spoa-server: fix size_t format printing + - DOC: spoa-server: fix false friends `actually` + - BUG/MINOR: ssl: fix memory leak at OCSP loading + - BUG/MEDIUM: ssl: memory leak of ocsp data at SSL_CTX_free() + - BUG/MEDIUM: map/lua: Return an error if a map is loaded during runtime + - MINOR: arg: Add an argument type to keep a reference on opaque data + - BUG/MINOR: converters: Store the sink in an arg pointer for debug() converter + - BUG/MINOR: lua: Duplicate map name to load it when a new Map object is created + - BUG/MINOR: arg: Fix leaks during arguments validation for fetches/converters + - BUG/MINOR: lua: Check argument type to convert it to IPv4/IPv6 arg validation + - BUG/MINOR: lua: Check argument type to convert it to IP mask in arg validation + - MINOR: hlua: Don't needlessly copy lua strings in trash during args validation + - BUG/MINOR: lua: Duplicate lua strings in sample fetches/converters arg array + - MEDIUM: lua: Don't filter exported fetches and converters + - MINOR: lua: Add support for userlist as fetches and converters arguments + - MINOR: lua: Add support for regex as fetches and converters arguments + - MINOR: arg: Use chunk_destroy() to release string arguments + - BUG/MINOR: snapshots: leak of snapshots on deinit() + - CLEANUP: ssl: ssl_sock_crt2der semicolon and spaces + - MINOR: ssl: add ssl_{c,s}_chain_der fetch methods + - CLEANUP: fix all duplicated semicolons + - BUG/MEDIUM: ssl: fix the ssl-skip-self-issued-ca option + - BUG/MINOR: ssl: ssl-skip-self-issued-ca requires >= 1.0.2 + - BUG/MINOR: stats: use strncmp() instead of memcmp() on health states + - BUILD: makefile: don't disable -Wstringop-overflow anymore + - BUG/MINOR: ssl: double free w/ smp_fetch_ssl_x_chain_der() + - BUG/MEDIUM: htx: smp_prefetch_htx() must always validate the direction + - BUG/MEDIUM: ssl: never generates the chain from the verify store + - OPTIM: regex: PCRE2 use JIT match when JIT optimisation occured. + - BUG/MEDIUM: ssl: does not look for all SNIs before chosing a certificate + - CLEANUP: ssl: remove poorly readable nested ternary + +2020/07/31 : 2.3-dev2 + - DOC: ssl: req_ssl_sni needs implicit TLS + - BUG/MEDIUM: arg: empty args list must be dropped + - BUG/MEDIUM: resolve: fix init resolving for ring and peers section. + - BUG/MAJOR: tasks: don't requeue global tasks into the local queue + - MINOR: tasks/debug: make the thread affinity BUG_ON check a bit stricter + - MINOR: tasks/debug: add a few BUG_ON() to detect use of wrong timer queue + - MINOR: tasks/debug: add a BUG_ON() check to detect requeued task on free + - BUG/MAJOR: dns: Make the do-resolve action thread-safe + - BUG/MEDIUM: dns: Release answer items when a DNS resolution is freed + - MEDIUM: htx: Add a flag on a HTX message when no more data are expected + - BUG/MEDIUM: stream-int: Don't set MSG_MORE flag if no more data are expected + - BUG/MEDIUM: http-ana: Only set CF_EXPECT_MORE flag on data filtering + - CLEANUP: dns: remove 45 "return" statements from dns_validate_dns_response() + - BUG/MINOR: htx: add two missing HTX_FL_EOI and remove an unexpected one + - BUG/MINOR: mux-fcgi: Don't url-decode the QUERY_STRING parameter anymore + - BUILD: tools: fix build with static only toolchains + - DOC: Use gender neutral language + - BUG/MINOR: debug: Don't dump the lua stack if it is not initialized + - BUG/MAJOR: dns: fix null pointer dereference in snr_update_srv_status + - BUG/MAJOR: dns: don't treat Authority records as an error + - CI : travis-ci : prepare for using stock OpenSSL + - CI: travis-ci : switch to stock openssl when openssl-1.1.1 is used + - MEDIUM: lua: Add support for the Lua 5.4 + - BUG/MEDIUM: dns: Don't yield in do-resolve action on a final evaluation + - BUG/MINOR: lua: Abort execution of actions that yield on a final evaluation + - MINOR: tcp-rules: Return an internal error if an action yields on a final eval + - BUG/MINOR: tcp-rules: Preserve the right filter analyser on content eval abort + - BUG/MINOR: tcp-rules: Set the inspect-delay when a tcp-response action yields + - MEDIUM: tcp-rules: Use a dedicated expiration date for tcp ruleset + - MEDIUM: lua: Set the analyse expiration date with smaller wake_time only + - BUG/MEDIUM: connection: Be sure to always install a mux for sync connect + - MINOR: connection: Preinstall the mux for non-ssl connect + - MINOR: stream-int: Be sure to have a mux to do sends and receives + - BUG/MINOR: lua: Fix a possible null pointer deref on lua ctx + - SCRIPTS: announce-release: add the link to the wiki in the announce messages + - CI: travis-ci: use better name for Coverity scan job + - CI: travis-ci: use proper linking flags for SLZ build + - BUG/MEDIUM: backend: always attach the transport before installing the mux + - BUG/MEDIUM: tcp-checks: always attach the transport before installing the mux + - MINOR: connection: avoid a useless recvfrom() on outgoing connections + - MINOR: mux-h1: do not even try to receive if the connection is not fully set up + - MINOR: mux-h1: do not try to receive on backend before sending a request + - CLEANUP: assorted typo fixes in the code and comments + - BUG/MEDIUM: ssl: check OCSP calloc in ssl_sock_load_ocsp() + +2020/07/17 : 2.3-dev1 + - MINOR: config: make strict limits enabled by default + - BUG/MINOR: acl: Fix freeing of expr->smp in prune_acl_expr + - BUG/MINOR: sample: Fix freeing of conv_exprs in release_sample_expr + - BUG/MINOR: haproxy: Free proxy->format_unique_id during deinit + - BUG/MINOR: haproxy: Add missing free of server->(hostname|resolvers_id) + - BUG/MINOR: haproxy: Free proxy->unique_id_header during deinit + - BUG/MINOR: haproxy: Free srule->file during deinit + - BUG/MINOR: haproxy: Free srule->expr during deinit + - BUG/MINOR: sample: Free str.area in smp_check_const_bool + - BUG/MINOR: sample: Free str.area in smp_check_const_meth + - CLEANUP: haproxy: Free proxy_deinit_list in deinit() + - CLEANUP: haproxy: Free post_deinit_list in deinit() + - CLEANUP: haproxy: Free server_deinit_list in deinit() + - CLEANUP: haproxy: Free post_server_check_list in deinit() + - CLEANUP: Add static void vars_deinit() + - CLEANUP: Add static void hlua_deinit() + - CLEANUP: contrib/prometheus-exporter: typo fixes for ssl reuse metric + - BUG/MEDIUM: lists: add missing store barrier on MT_LIST_BEHEAD() + - BUG/MEDIUM: lists: add missing store barrier in MT_LIST_ADD/MT_LIST_ADDQ + - MINOR: tcp: Support TCP keepalive parameters customization + - BUILD: tcp: condition TCP keepalive settings to platforms providing them + - MINOR: lists: rename some MT_LIST operations to clarify them + - MINOR: buffer: use MT_LIST_ADDQ() for buffer_wait lists additions + - MINOR: connection: use MT_LIST_ADDQ() to add connections to idle lists + - MINOR: tasks: use MT_LIST_ADDQ() when killing tasks. + - CONTRIB: da: fix memory leak in dummy function da_atlas_open() + - CI: travis-ci: speed up osx build by running brew scripted, switch to latest osx image + - BUG/MEDIUM: mux-h2: Don't add private connections in available connection list + - BUG/MEDIUM: mux-fcgi: Don't add private connections in available connection list + - MINOR: connection: Set the SNI on server connections before installing the mux + - MINOR: connection: Set new connection as private on reuse never + - MINOR: connection: Add a wrapper to mark a connection as private + - MEDIUM: connection: Add private connections synchronously in session server list + - MINOR: connection: Use a dedicated function to look for a session's connection + - MINOR: connection: Set the conncetion target during its initialisation + - MINOR: session: Take care to decrement idle_conns counter in session_unown_conn + - MINOR: server: Factorize code to deal with reuse of server idle connections + - MINOR: server: Factorize code to deal with connections removed from an idle list + - CLEANUP: connection: remove unused field idle_time from the connection struct + - BUG/MEDIUM: mux-h1: Continue to process request when switching in tunnel mode + - MINOR: raw_sock: Report the number of bytes emitted using the splicing + - MINOR: contrib/prometheus-exporter: Add missing global and per-server metrics + - MINOR: backend: Add sample fetches to get the server's weight + - BUG/MINOR: mux-fcgi: Handle empty STDERR record + - BUG/MINOR: mux-fcgi: Set conn state to RECORD_P when skipping the record padding + - BUG/MINOR: mux-fcgi: Set flags on the right stream field for empty FCGI_STDOUT + - BUG/MINOR: backend: fix potential null deref on srv_conn + - BUG/MEDIUM: log: issue mixing sampled to not sampled log servers. + - MEDIUM: udp: adds minimal proto udp support for message listeners. + - MEDIUM: log/sink: re-work and merge of build message API. + - MINOR: log: adds syslog udp message handler and parsing. + - MEDIUM: log: adds log forwarding section. + - MINOR: log: adds counters on received syslog messages. + - BUG/MEDIUM: fcgi-app: fix memory leak in fcgi_flt_http_headers + - BUG/MEDIUM: server: resolve state file handle leak on reload + - BUG/MEDIUM: server: fix possibly uninitialized state file on close + - BUG/MEDIUM: channel: Be aware of SHUTW_NOW flag when output data are peeked + - BUILD: config: address build warning on raspbian+rpi4 + - BUG/MAJOR: tasks: make sure to always lock the shared wait queue if needed + - BUILD: config: fix again bugs gcc warnings on calloc + +2020/07/07 : 2.3-dev0 + - [RELEASE] Released version 2.3-dev0 + - MINOR: version: back to development, update status message + +2020/07/07 : 2.3-dev0 + - exact copy of 2.2.0 + +2020/07/07 : 2.2.0 + - BUILD: mux-h2: fix typo breaking build when using DEBUG_LOCK + - CLEANUP: makefile: update the outdated list of DEBUG_xxx options + - BUILD: tools: make resolve_sym_name() return a const + - CLEANUP: auth: fix useless self-include of auth-t.h + - BUILD: tree-wide: cast arguments to tolower/toupper to unsigned char + - CLEANUP: assorted typo fixes in the code and comments + - WIP/MINOR: ssl: add sample fetches for keylog in frontend + - DOC: fix tune.ssl.keylog sample fetches array + - BUG/MINOR: ssl: check conn in keylog sample fetch + - DOC: configuration: various typo fixes + - MINOR: log: Remove unused case statement during the log-format string parsing + - BUG/MINOR: mux-h1: Fix the splicing in TUNNEL mode + - BUG/MINOR: mux-h1: Don't read data from a pipe if the mux is unable to receive + - BUG/MINOR: mux-h1: Disable splicing only if input data was processed + - BUG/MEDIUM: mux-h1: Disable splicing for the conn-stream if read0 is received + - MINOR: mux-h1: Improve traces about the splicing + - BUG/MINOR: backend: Remove CO_FL_SESS_IDLE if a client remains on the last server + - BUG/MEDIUM: connection: Don't consider new private connections as available + - BUG/MINOR: connection: See new connection as available only on reuse always + - DOC: configuration: remove obsolete mentions of H2 being converted to HTTP/1.x + - CLEANUP: ssl: remove unrelevant comment in smp_fetch_ssl_x_keylog() + - DOC: update INSTALL with new compiler versions + - DOC: minor update to coding style file + - MINOR: version: mention that it's an LTS release now + +2020/07/04 : 2.2-dev12 + - BUG/MINOR: mux_h2: don't lose the leaving trace in h2_io_cb() + - MINOR: cli: make "show sess" stop at the last known session + - CLEANUP: buffers: remove unused buffer_wq_lock lock + - BUG/MEDIUM: buffers: always allocate from the local cache first + - MINOR: connection: align toremove_{lock,connections} and cleanup into idle_conns + - CONTRIB: debug: add missing flags SI_FL_L7_RETRY & SI_FL_D_L7_RETRY + - BUG/MEDIUM: connections: Don't increase curr_used_conns for shared connections. + - BUG/MEDIUM: checks: Increment the server's curr_used_conns + - REORG: buffer: rename buffer.c to dynbuf.c + - REORG: includes: create tinfo.h for the thread_info struct + - CLEANUP: pool: only include the type files from types + - MINOR: pools: move the LRU cache heads to thread_info + - BUG/MINOR: debug: fix "show fd" null-deref when built with DEBUG_FD + - MINOR: stats: add 3 new output values for the per-server idle conn state + - MINOR: activity: add per-thread statistics on FD takeover + - BUG/MINOR: server: start cleaning idle connections from various points + - MEDIUM: server: improve estimate of the need for idle connections + - MINOR: stats: add the estimated need of concurrent connections per server + - BUG/MINOR: threads: Don't forget to init each thread toremove_lock. + - BUG/MEDIUM: lists: Lock the element while we check if it is in a list. + - Revert "BUG/MEDIUM: lists: Lock the element while we check if it is in a list." + - BUG/MINOR: haproxy: don't wake already stopping threads on exit + - BUG/MINOR: server: always count one idle slot for current thread + - MEDIUM: server: use the two thresholds for the connection release algorithm + - BUG/MINOR: http-rules: Fix ACLs parsing for http deny rules + - BUG/MINOR: sched: properly cover for a rare MT_LIST_ADDQ() race + - MINOR: mux-h1: avoid taking the toremove_lock in on dying tasks + - MINOR: mux-h2: avoid taking the toremove_lock in on dying tasks + - MINOR: mux-fcgi: avoid taking the toremove_lock in on dying tasks + - MINOR: pools: increase MAX_BASE_POOLS to 64 + - DOC: ssl: add "allow-0rtt" and "ciphersuites" in crt-list + - BUG/MEDIUM: pattern: Add a trailing \0 to match strings only if possible + - BUG/MEDIUM: log-format: fix possible endless loop in parse_logformat_string() + - BUG/MINOR: proxy: fix dump_server_state()'s misuse of the trash + - BUG/MINOR: proxy: always initialize the trash in show servers state + - MINOR: cli/proxy: add a new "show servers conn" command + - MINOR: server: skip servers with no idle conns earlier + - BUG/MINOR: server: fix the connection release logic regarding nearly full conditions + - MEDIUM: server: add a new pool-low-conn server setting + - BUG/MEDIUM: backend: always search in the safe list after failing on the idle one + - MINOR: backend: don't always takeover from the same threads + - MINOR: sched: make sched->task_list_size atomic + - MEDIUM: sched: create a new TASK_KILLED task flag + - MEDIUM: sched: implement task_kill() to kill a task + - MEDIUM: mux-h1: use task_kill() during h1_takeover() instead of task_wakeup() + - MEDIUM: mux-h2: use task_kill() during h2_takeover() instead of task_wakeup() + - MEDIUM: mux-fcgi: use task_kill() during fcgi_takeover() instead of task_wakeup() + - MINOR: list: Add MT_LIST_DEL_SAFE_NOINIT() and MT_LIST_ADDQ_NOCHECK() + - CLEANUP: connections: rename the toremove_lock to takeover_lock + - MEDIUM: connections: Don't use a lock when moving connections to remove. + - DOC: configuration: add missing index entries for tune.pool-{low,high}-fd-ratio + - DOC: configuration: fix alphabetical ordering for tune.pool-{high,low}-fd-ratio + - MINOR: config: add a new tune.idle-pool.shared global setting. + - MINOR: 51d: silence a warning about null pointer dereference + - MINOR: debug: add a new "debug dev memstats" command + - MINOR: log-format: allow to preserve spacing in log format strings + - BUILD: debug: avoid build warnings with DEBUG_MEM_STATS + - BUG/MAJOR: sched: make sure task_kill() always queues the task + - BUG/MEDIUM: muxes: Make sure nobody stole the connection before using it. + - BUG/MEDIUM: cli/proxy: don't try to dump idle connection state if there's none + - BUILD: haproxy: fix build error when RLIMIT_AS is not set + - BUG/MAJOR: sched: make it work also when not building with DEBUG_STRICT + - MINOR: log: add time second fraction field to rfc5424 log timestamp. + - BUG/MINOR: log: missing timezone on iso dates. + - BUG/MEDIUM: server: don't kill all idle conns when there are not enough + - MINOR: sched: split tasklet_wakeup() into tasklet_wakeup_on() + - BUG/MEDIUM: connections: Set the tid for the old tasklet on takeover. + - BUG/MEDIUM: connections: Let the xprt layer know a takeover happened. + - BUG/MINOR: http_act: don't check capture id in backend (2) + - BUILD: makefile: disable threads by default on OpenBSD + - BUILD: peers: fix build warning with gcc 4.2.1 + - CI: cirrus-ci: exclude slow reg-tests + +2020/06/26 : 2.2-dev11 + - REGTEST: Add a simple script to tests errorfile directives in proxy sections + - BUG/MEDIUM: fcgi-app: Resolve the sink if a fcgi-app logs in a ring buffer + - BUG/MINOR: spoe: correction of setting bits for analyzer + - BUG/MINOR: cfgparse: Support configurations without newline at EOF + - MINOR: cfgparse: Warn on truncated lines / files + - BUG/MINOR: http_ana: clarify connection pointer check on L7 retry + - MINOR: debug: add a new DEBUG_FD build option + - BUG/MINOR: tasks: make sure never to exceed max_processed + - MINOR: task: add a new pointer to current tasklet queue + - BUG/MEDIUM: task: be careful not to run too many tasks at TL_URGENT + - BUG/MINOR: cfgparse: Fix argument reference in PARSE_ERR_TOOMANY message + - BUG/MINOR: cfgparse: Fix calculation of position for PARSE_ERR_TOOMANY message + - BUG/MEDIUM: ssl: fix ssl_bind_conf double free + - MINOR: ssl: free bind_conf_node in crtlist_free() + - MINOR: ssl: free the crtlist and the ckch during the deinit() + - BUG/MINOR: ssl: fix build with ckch_deinit() and crtlist_deinit() + - BUG/MINOR: ssl/cli: certs added from the CLI can't be deleted + - MINOR: ssl: move the ckch/crtlist deinit to ssl_sock.c + - MEDIUM: tasks: apply a fair CPU distribution between tasklet classes + - MINOR: tasks: make current_queue an index instead of a pointer + - MINOR: tasks: add a mask of the queues with active tasklets + - MINOR: tasks: pass the queue index to run_task_from_list() + - MINOR: tasks: make run_tasks_from_lists() scan the queues itself + - MEDIUM: tasks: add a tune.sched.low-latency option + - BUG/MEDIUM: ssl/cli: 'commit ssl cert' crashes when no private key + - BUG/MINOR: cfgparse: don't increment linenum on incomplete lines + - MINOR: tools: make parse_line() always terminate the args list + - BUG/MINOR: cfgparse: report extraneous args *after* the string is allocated + - MINOR: cfgparse: sanitize the output a little bit + - MINOR: cli/ssl: handle trailing slashes in crt-list commands + - MINOR: ssl: add the ssl_s_* sample fetches for server side certificate + - BUG/MEDIUM: http-ana: Don't loop trying to generate a malformed 500 response + - BUG/MINOR: stream-int: Don't wait to send truncated HTTP messages + - BUG/MINOR: http-ana: Set CF_EOI on response channel for generated responses + - BUG/MINOR: http-ana: Don't wait to send 1xx responses generated by HAProxy + - MINOR: spoe: Don't systematically create new applets if processing rate is low + - DOC: fix some typos in the ssl_s_{s|i}_dn documentation + - BUILD: fix ssl_sample.c when building against BoringSSL + - CI: travis-ci: switch BoringSSL builds to ninja + - CI: extend spellchecker whitelist + - DOC: assorted typo fixes in the documentation + - CLEANUP: assorted typo fixes in the code and comments + - MINOR: http: Add support for http 413 status + - REGTEST: ssl: tests the ssl_f_* sample fetches + - REGTEST: ssl: add some ssl_c_* sample fetches test + - DOC: ssl: update the documentation of "commit ssl cert" + - BUG/MINOR: cfgparse: correctly deal with empty lines + - BUG/MEDIUM: fetch: Fix hdr_ip misparsing IPv4 addresses due to missing NUL + +2020/06/19 : 2.2-dev10 + - BUILD: include: add sys/types before netinet/tcp.h + - BUG/MEDIUM: log: don't hold the log lock during writev() on a file descriptor + - BUILD: Remove nowarn for warnings that do not trigger + - BUG/MEDIUM: pattern: fix thread safety of pattern matching + - BUILD: Re-enable -Wimplicit-fallthrough + - BUG/MINOR: ssl: fix ssl-{min,max}-ver with openssl < 1.1.0 + - BUILD: thread: add parenthesis around values of locking macros + - BUILD: proto_uxst: shut up yet another gcc's absurd warning + - BUG/MEDIUM: checks: Fix off-by-one in allocation of SMTP greeting cmd + - CI: travis-ci: use "-O1" for clang builds + - MINOR: haproxy: Add void deinit_and_exit(int) + - MINOR: haproxy: Make use of deinit_and_exit() for clean exits + - BUG/MINOR: haproxy: Free rule->arg.vars.expr during deinit_act_rules + - BUILD: compression: make gcc 10 happy with free_zlib() + - BUILD: atomic: add string.h for memcpy() on ARM64 + - BUG/MINOR: http: make smp_fetch_body() report that the contents may change + - BUG/MINOR: tcp-rules: tcp-response must check the buffer's fullness + - BUILD: haproxy: mark deinit_and_exit() as noreturn + - BUG/MAJOR: vars: Fix bogus free() during deinit() for http-request rules + - BUG/MEDIUM: ebtree: use a byte-per-byte memcmp() to compare memory blocks + - MINOR: tools: add a new configurable line parse, parse_line() + - BUG/MEDIUM: cfgparse: use parse_line() to expand/unquote/unescape config lines + - BUG/MEDIUM: cfgparse: stop after a reasonable amount of fatal error + - MINOR: http: do not close connections anymore after internal responses + - BUG/MINOR: cfgparse: Add missing fatal++ in PARSE_ERR_HEX case + - BUG/MINOR: spoe: add missing key length check before checking key names + - MINOR: version: put the compiler version output into version.c not haproxy.c + - MINOR: compiler: always define __has_feature() + - MINOR: version: report the presence of the compiler's address sanitizer + - BUILD: Fix build by including haproxy/global.h + - BUG/MAJOR: connection: always disable ready events once reported + - CLEANUP: activity: remove unused counter fd_lock + - DOC: fd: make it clear that some fields ordering must absolutely be respected + - MINOR: activity: report the number of times poll() reports I/O + - MINOR: activity: rename confusing poll_* fields in the output + - MINOR: fd: Fix a typo in a coment. + - BUG/MEDIUM: fd: Don't fd_stop_recv() a fd we don't own. + - BUG/MEDIUM: fd: Call fd_stop_recv() when we just got a fd. + - MINOR: activity: group the per-loop counters at the top + - MINOR: activity: rename the "stream" field to "stream_calls" + - MEDIUM: fd: refine the fd_takeover() migration lock + - MINOR: fd: slightly optimize the fd_takeover double-CAS loop + - MINOR: fd: factorize the fd_takeover() exit path to make it safer + - MINOR: peers: do not use localpeer as an array anymore + - MEDIUM: peers: add the "localpeer" global option + - MEDIUM: fd: add experimental support for edge-triggered polling + - CONTRIB: debug: add the missing flags CO_FL_SAFE_LIST and CO_FL_IDLE_LIST + - MINOR: haproxy: process signals before runnable tasks + - MEDIUM: tasks: clean up the front side of the wait queue in wake_expired_tasks() + - MEDIUM: tasks: also process late wakeups in process_runnable_tasks() + - BUG/MINOR: cli: allow space escaping on the CLI + - BUG/MINOR: mworker/cli: fix the escaping in the master CLI + - BUG/MINOR: mworker/cli: fix semicolon escaping in master CLI + - REGTEST: http-rules: test spaces in ACLs + - REGTEST: http-rules: test spaces in ACLs with master CLI + - BUG/MAJOR: init: properly compute the default global.maxpipes value + - MEDIUM: map: make the "clear map" operation yield + - BUG/MEDIUM: stream-int: fix loss of CO_SFL_MSG_MORE flag in forwarding + - MINOR: mux_h1: Set H1_F_CO_MSG_MORE if we know we have more to send. + - BUG/MINOR: systemd: Wait for network to be online + - DOC: configuration: Unindent non-code sentences in the protobuf example + - DOC: configuration: http-check send was missing from matrix + +2020/06/11 : 2.2-dev9 + - BUG/MINOR: http-htx: Don't forget to release the http reply in release function + - BUG/MINOR: http-htx: Fix a leak on error path during http reply parsing + - MINOR: checks: Remove dead code from process_chk_conn() + - REGTESTS: checks: Fix tls_health_checks when IPv6 addresses are used + - REGTESTS: Add missing OPENSSL to REQUIRE_OPTIONS for lua/txn_get_priv + - MINOR: lua: Use vars_unset_by_name_ifexist() + - CLEANUP: vars: Remove void vars_unset_by_name(const char*, size_t, struct sample*) + - MINOR: vars: Make vars_(un|)set_by_name(_ifexist|) return a success value + - MINOR: lua: Make `set_var()` and `unset_var()` return success + - MEDIUM: lua: Add `ifexist` parameter to `set_var` + - MEDIUM: ring: new section ring to declare custom ring buffers. + - REGTESTS: Add missing OPENSSL to REQUIRE_OPTIONS for compression/lua_validation + - REGTESTS: Require the version 2.2 to execute lua/set_var + - BUG/MEDIUM: checks: Refresh the conn-stream and the connection after a connect + - MINOR: checks: Remove useless tests on the connection and conn-stream + - BUG/MEDIUM: contrib/spoa: do not register python3.8 if --embed fail + - BUG/MEDIUM: connection: Ignore PP2 unique ID for stream-less connections + - BUG/MINOR: connection: Always get the stream when available to send PP2 line + - BUG/MEDIUM: backend: set the connection owner to the session when using alpn. + - MINOR: pools: compute an estimate of each pool's average needed objects + - MEDIUM: pools: directly free objects when pools are too much crowded + - REGTEST: Add connection/proxy_protocol_send_unique_id_alpn + - MINOR: http-ana: Make the function http_reply_to_htx() public + - MINOR: http-ana: Use proxy's error replies to emit 401/407 responses + - MINOR: http-rules: Use an action function to eval http-request auth rules + - CLEANUP: http: Remove unused HTTP message templates + - BUG/MEDIUM: checks: Don't blindly subscribe for receive if waiting for connect + - MINOR: checks: I/O callback function only rely on the data layer wake callback + - BUG/MINOR: lua: Add missing string length for lua sticktable lookup + - BUG/MEDIUM: logs: fix trailing zeros on log message. + - CI: cirrus-ci: skip reg-tests/connection/proxy_protocol_send_unique_id_alpn.vtc on CentOS 6 + - BUG/MINOR: nameservers: fix error handling in parsing of resolv.conf + - BUG/MEDIUM: checks: Don't add a tcpcheck ruleset twice in the shared tree + - MEDIUM: ssl: use TLSv1.2 as the minimum default on bind lines + - CLEANUP: pools: use the regular lock for the flush operation on lockless pools + - SCRIPTS: publish-release: pass -n to gzip to remove timestamp + - MINOR: ring: re-work ring attach generic API. + - BUG/MINOR: error on unknown statement in ring section. + - MEDIUM: ring: add server statement to forward messages from a ring + - MEDIUM: ring: add new srv statement to support octet counting forward + - MINOR: ssl: set ssl-min-ver in ambiguous configurations + - CLEANUP: ssl: remove comment from dump_crtlist_sslconf() + - BUILD: sink: address build warning on 32-bit architectures + - BUG/MINOR: peers: fix internal/network key type mapping. + - CLEANUP: regex: remove outdated support for regex actions + - Revert "MINOR: ssl: rework add cert chain to CTX to be libssl independent" + - MINOR: mux-h1/proxy: Add a proxy option to disable clear h2 upgrade + - BUG/MEDIUM: lua: Reset analyse expiration timeout before executing a lua action + - DOC: add a line about comments in crt-list + - BUG/MEDIUM: hlua: Lock pattern references to perform set/add/del operations + - BUG/MINOR: checks: Fix test on http-check rulesets during config validity check + - BUG/MEDIUM: contrib/prometheus-exporter: Properly set flags to dump metrics + - BUG/MEDIUM: mworker: fix the copy of options in copy_argv() + - BUG/MINOR: init: -x can have a parameter starting with a dash + - BUG/MINOR: init: -S can have a parameter starting with a dash + - BUG/MEDIUM: mworker: fix the reload with an -- option + - BUG/MINOR: ssl: fix a trash buffer leak in some error cases + - BUG/MINOR: mworker: fix a memleak when execvp() failed + - MINOR: sample: Add secure_memcmp converter + - REORG: ebtree: move the C files from ebtree/ to src/ + - REORG: ebtree: move the include files from ebtree to include/import/ + - REORG: ebtree: clean up remains of the ebtree/ directory + - REORG: include: create new file haproxy/api-t.h + - REORG: include: create new file haproxy/api.h + - REORG: include: update all files to use haproxy/api.h or api-t.h if needed + - CLEANUP: include: remove common/config.h + - CLEANUP: include: remove unused template.h + - REORG: include: move MIN/MAX from tools.h to compat.h + - REORG: include: move SWAP/MID_RANGE/MAX_RANGE from tools.h to standard.h + - CLEANUP: include: remove unused common/tools.h + - REORG: include: move the base files from common/ to haproxy/ + - REORG: include: move version.h to haproxy/ + - REORG: include: move base64.h, errors.h and hash.h from common to to haproxy/ + - REORG: include: move openssl-compat.h from common/ to haproxy/ + - REORG: include: move ist.h from common/ to import/ + - REORG: include: move the BUG_ON() code to haproxy/bug.h + - REORG: include: move debug.h from common/ to haproxy/ + - CLEANUP: debug: drop unused function p_malloc() + - REORG: include: split buf.h into haproxy/buf-t.h and haproxy/buf.h + - REORG: include: move istbuf.h to haproxy/ + - REORG: include: split mini-clist into haproxy/list and list-t.h + - REORG: threads: extract atomic ops from hathreads.h + - CLEANUP: threads: remove a few needless includes of hathreads.h + - REORG: include: split hathreads into haproxy/thread.h and haproxy/thread-t.h + - CLEANUP: thread: rename __decl_hathreads() to __decl_thread() + - REORG: include: move time.h from common/ to haproxy/ + - REORG: include: move integer manipulation functions from standard.h to intops.h + - CLEANUP: include: remove excessive includes of common/standard.h + - REORG: include: move freq_ctr to haproxy/ + - CLEANUP: pool: include freq_ctr.h and remove locally duplicated functions + - REORG: memory: move the pool type definitions to haproxy/pool-t.h + - REORG: memory: move the OS-level allocator to haproxy/pool-os.h + - MINOR: memory: don't let __pool_get_first() pick from the cache + - MEDIUM: memory: don't let pool_put_to_cache() free the objects itself + - MINOR: memory: move pool-specific path of the locked pool_free() to __pool_free() + - MEDIUM: memory: make local pools independent on lockless pools + - REORG: include: move common/memory.h to haproxy/pool.h + - REORG: include: move common/chunk.h to haproxy/chunk.h + - REORG: include: move activity to haproxy/ + - REORG: include: move common/buffer.h to haproxy/dynbuf{,-t}.h + - REORG: include: move common/net_helper.h to haproxy/net_helper.h + - REORG: include: move common/namespace.h to haproxy/namespace{,-t}.h + - REORG: include: split common/regex.h into haproxy/regex{,-t}.h + - REORG: include: split common/xref.h into haproxy/xref{,-t}.h + - REORG: include: move common/ticks.h to haproxy/ticks.h + - REORG: include: split common/http.h into haproxy/http{,-t}.h + - REORG: include: split common/http-hdr.h into haproxy/http-hdr{,-t}.h + - REORG: include: move common/h1.h to haproxy/h1.h + - REORG: include: split common/htx.h into haproxy/htx{,-t}.h + - REORG: include: move hpack*.h to haproxy/ and split hpack-tbl + - REORG: include: move common/h2.h to haproxy/h2.h + - REORG: include: move common/fcgi.h to haproxy/ + - REORG: include: move protocol.h to haproxy/protocol{,-t}.h + - REORG: tools: split common/standard.h into haproxy/tools{,-t}.h + - REORG: include: move dict.h to hparoxy/dict{,-t}.h + - REORG: include: move shctx to haproxy/shctx{,-t}.h + - REORG: include: move port_range.h to haproxy/port_range{,-t}.h + - REORG: include: move fd.h to haproxy/fd{,-t}.h + - REORG: include: move ring to haproxy/ring{,-t}.h + - REORG: include: move sink.h to haproxy/sink{,-t}.h + - REORG: include: move pipe.h to haproxy/pipe{,-t}.h + - CLEANUP: include: remove empty raw_sock.h + - REORG: include: move proto_udp.h to haproxy/proto_udp{,-t}.h + - REORG: include: move proto/proto_sockpair.h to haproxy/proto_sockpair.h + - REORG: include: move compression.h to haproxy/compression{,-t}.h + - REORG: include: move h1_htx.h to haproxy/h1_htx.h + - REORG: include: move http_htx.h to haproxy/http_htx{,-t}.h + - REORG: include: move hlua.h to haproxy/hlua{,-t}.h + - REORG: include: move hlua_fcn.h to haproxy/hlua_fcn.h + - REORG: include: move action.h to haproxy/action{,-t}.h + - REORG: include: move arg.h to haproxy/arg{,-t}.h + - REORG: include: move auth.h to haproxy/auth{,-t}.h + - REORG: include: move dns.h to haproxy/dns{,-t}.h + - REORG: include: move flt_http_comp.h to haproxy/ + - REORG: include: move counters.h to haproxy/counters-t.h + - REORG: include: split mailers.h into haproxy/mailers{,-t}.h + - REORG: include: move capture.h to haproxy/capture{,-t}.h + - REORG: include: move frontend.h to haproxy/frontend.h + - REORG: include: move obj_type.h to haproxy/obj_type{,-t}.h + - REORG: include: move http_rules.h to haproxy/http_rules.h + - CLEANUP: include: remove unused mux_pt.h + - REORG: include: move mworker.h to haproxy/mworker{,-t}.h + - REORG: include: move ssl_utils.h to haproxy/ssl_utils.h + - REORG: include: move ssl_ckch.h to haproxy/ssl_ckch{,-t}.h + - REORG: move ssl_crtlist.h to haproxy/ssl_crtlist{,-t}.h + - REORG: include: move lb_chash.h to haproxy/lb_chash{,-t}.h + - REORG: include: move lb_fas.h to haproxy/lb_fas{,-t}.h + - REORG: include: move lb_fwlc.h to haproxy/lb_fwlc{,-t}.h + - REORG: include: move lb_fwrr.h to haproxy/lb_fwrr{,-t}.h + - REORG: include: move listener.h to haproxy/listener{,-t}.h + - REORG: include: move pattern.h to haproxy/pattern{,-t}.h + - REORG: include: move map to haproxy/map{,-t}.h + - REORG: include: move payload.h to haproxy/payload.h + - REORG: include: move sample.h to haproxy/sample{,-t}.h + - REORG: include: move protocol_buffers.h to haproxy/protobuf{,-t}.h + - REORG: include: move vars.h to haproxy/vars{,-t}.h + - REORG: include: split global.h into haproxy/global{,-t}.h + - REORG: include: move task.h to haproxy/task{,-t}.h + - REORG: include: move proto_tcp.h to haproxy/proto_tcp.h + - REORG: include: move signal.h to haproxy/signal{,-t}.h + - REORG: include: move tcp_rules.h to haproxy/tcp_rules.h + - REORG: include: move connection.h to haproxy/connection{,-t}.h + - REORG: include: move checks.h to haproxy/check{,-t}.h + - REORG: include: move http_fetch.h to haproxy/http_fetch.h + - REORG: include: move peers.h to haproxy/peers{,-t}.h + - REORG: include: move stick_table.h to haproxy/stick_table{,-t}.h + - REORG: include: move session.h to haproxy/session{,-t}.h + - REORG: include: move trace.h to haproxy/trace{,-t}.h + - REORG: include: move acl.h to haproxy/acl.h{,-t}.h + - REORG: include: split common/uri_auth.h into haproxy/uri_auth{,-t}.h + - REORG: move applet.h to haproxy/applet{,-t}.h + - REORG: include: move stats.h to haproxy/stats{,-t}.h + - REORG: include: move cli.h to haproxy/cli{,-t}.h + - REORG: include: move lb_map.h to haproxy/lb_map{,-t}.h + - REORG: include: move ssl_sock.h to haproxy/ssl_sock{,-t}.h + - REORG: include: move stream_interface.h to haproxy/stream_interface{,-t}.h + - REORG: include: move channel.h to haproxy/channel{,-t}.h + - REORG: include: move http_ana.h to haproxy/http_ana{,-t}.h + - REORG: include: move filters.h to haproxy/filters{,-t}.h + - REORG: include: move fcgi-app.h to haproxy/fcgi-app{,-t}.h + - REORG: include: move log.h to haproxy/log{,-t}.h + - REORG: include: move proxy.h to haproxy/proxy{,-t}.h + - REORG: include: move spoe.h to haproxy/spoe{,-t}.h + - REORG: include: move backend.h to haproxy/backend{,-t}.h + - REORG: include: move queue.h to haproxy/queue{,-t}.h + - REORG: include: move server.h to haproxy/server{,-t}.h + - REORG: include: move stream.h to haproxy/stream{,-t}.h + - REORG: include: move cfgparse.h to haproxy/cfgparse.h + - CLEANUP: hpack: export debug functions and move inlines to .h + - REORG: check: move the e-mail alerting code to mailers.c + - REORG: check: move tcpchecks away from check.c + - REORG: check: move email_alert* from proxy-t.h to mailers-t.h + - REORG: check: extract the external checks from check.{c,h} + - CLEANUP: include: don't include stddef.h directly + - CLEANUP: include: don't include proxy-t.h in global-t.h + - CLEANUP: include: move sample_data out of sample-t.h + - REORG: include: move the error reporting functions to from log.h to errors.h + - BUILD: reorder objects in the Makefile for faster builds + - CLEANUP: compiler: add a THREAD_ALIGNED macro and use it where appropriate + - CLEANUP: include: make atomic.h part of the base API + - REORG: include: move MAX_THREADS to defaults.h + - REORG: include: move THREAD_LOCAL and __decl_thread() to compiler.h + - CLEANUP: include: tree-wide alphabetical sort of include files + - REORG: include: make list-t.h part of the base API + - REORG: dgram: rename proto_udp to dgram + +2020/05/22 : 2.2-dev8 + - MINOR: checks: Improve report of unexpected errors for expect rules + - MEDIUM: checks: Add matching on log-format string for expect rules + - DOC: Fix req.body and co documentation to be accurate + - MEDIUM: checks: Remove dedicated sample fetches and use response ones instead + - CLEANUP: checks: sort and rename tcpcheck_expect_type types + - MINOR: checks: Use dedicated actions to send log-format strings in send rules + - MINOR: checks: Simplify matching on HTTP headers in HTTP expect rules + - MINOR: checks/sample: Remove unnecessary tests on the sample session + - REGTEST: checks: Adapt SSL error message reported when connection is rejected + - MINOR: mworker: replace ha_alert by ha_warning when exiting successfuly + - MINOR: checks: Support log-format string to set the URI for HTTP send rules + - MINOR: checks: Support log-format string to set the body for HTTP send rules + - DOC: Be more explicit about configurable check ok/error/timeout status + - MINOR: checks: Make matching on HTTP headers for expect rules less obscure + - BUG/MEDIUM: lua: Fix dumping of stick table entries for STD_T_DICT + - BUG/MINOR: config: Make use_backend and use-server post-parsing less obscur + - REGTESTS: make the http-check-send test require version 2.2 + - BUG/MINOR: http-ana: fix NTLM response parsing again + - BUG/MEDIUM: http_ana: make the detection of NTLM variants safer + - BUG/MINOR: cfgparse: Abort parsing the current line if an invalid \x sequence is encountered + - MINOR: cfgparse: Improve error message for invalid \x sequences + - CI: travis-ci: enable arm64 builds again + - MEDIUM: ssl: increase default-dh-param to 2048 + - CI: travis-ci: skip pcre2 on arm64 build + - CI: travis-ci: extend the build time for SSL to 60 minutes + - CLEANUP: config: drop unused setting CONFIG_HAP_MEM_OPTIM + - CLEANUP: config: drop unused setting CONFIG_HAP_INLINE_FD_SET + - CLENAUP: config: move CONFIG_HAP_LOCKLESS_POOLS out of config.h + - CLEANUP: remove THREAD_LOCAL from config.h + - CI: travis-ci: upgrade LibreSSL versions + - DOC: assorted typo fixes in the documentation + - CI: extend spellchecker whitelist + - CLEANUP: assorted typo fixes in the code and comments + - MAJOR: contrib: porting spoa_server to support python3 + - BUG/MEDIUM: checks: Subscribe to I/O events on an unfinished connect + - BUG/MINOR: checks: Don't subscribe to I/O events if it is already done + - BUG/MINOR: checks: Rely on next I/O oriented rule when waiting for a connection + - MINOR: checks: Don't try to send outgoing data if waiting to be able to send + - MINOR: sample: Move aes_gcm_dec implementation into sample.c + - MINOR: sample: Add digest and hmac converters + - BUG/MEDIUM: checks: Subscribe to I/O events only if a mux was installed + - BUG/MINOR: sample/ssl: Fix digest converter for openssl < 1.1.0 + - BUG/MINOR: pools: use %u not %d to report pool stats in "show pools" + - BUG/MINOR: pollers: remove uneeded free in global init + - CLEANUP: select: enhance readability in init + - BUG/MINOR: soft-stop: always wake up waiting threads on stopping + - MINOR: soft-stop: let the first stopper only signal other threads + - BUILD: select: only declare existing local labels to appease clang + - BUG/MEDIUM: streams: Remove SF_ADDR_SET if we're retrying due to L7 retry. + - BUG/MEDIUM: stream: Only allow L7 retries when using HTTP. + - DOC: retry-on can only be used with mode http + - MEDIUM: ssl: allow to register callbacks for SSL/TLS protocol messages + - MEDIUM: ssl: split ssl_sock_msgcbk() and use a new callback mechanism + - MINOR: ssl: add a new function ssl_sock_get_ssl_object() + - MEDIUM: ssl: use ssl_sock_get_ssl_object() in fetchers where appropriate + - REORG: ssl: move macros and structure definitions to ssl_sock.h + - CLEANUP: ssl: remove the shsess_* macros + - REORG: move the crt-list structures in their own .h + - REORG: ssl: move the ckch structures to types/ssl_ckch.h + - CLEANUP: ssl: add ckch prototypes in proto/ssl_ckch.h + - REORG: ssl: move crtlist functions to src/ssl_crtlist.c + - CLEANUP: ssl: avoid circular dependencies in ssl_crtlist.h + - REORG: ssl: move the ckch_store related functions to src/ssl_ckch.c + - REORG: ssl: move ckch_inst functions to src/ssl_ckch.c + - REORG: ssl: move the crt-list CLI functions in src/ssl_crtlist.c + - REORG: ssl: move the CLI 'cert' functions to src/ssl_ckch.c + - REORG: ssl: move ssl configuration to cfgparse-ssl.c + - MINOR: ssl: remove static keyword in some SSL utility functions + - REORG: ssl: move ssl_sock_ctx and fix cross-dependencies issues + - REORG: ssl: move sample fetches to src/ssl_sample.c + - REORG: ssl: move utility functions to src/ssl_utils.c + - DOC: ssl: update MAINTAINERS file + - CI: travis-ci: switch arm64 builds to use openssl from distro + - MINOR: stats: Prepare for more accurate moving averages + - MINOR: stats: Expose native cum_req metric for a server + - MEDIUM: stats: Enable more accurate moving average calculation for stats + - BUILD: ssl: include buffer common headers for ssl_sock_ctx + - BUILD: ssl: include errno.h in ssl_crtlist.c + - CLEANUP: acl: remove unused assignment + - DOC/MINOR: halog: Add long help info for ic flag + - BUILD: ssl: fix build without OPENSSL_NO_ENGINE + - DOC: SPOE is no longer experimental + - BUG/MINOR: cache: Don't needlessly test "cache" keyword in parse_cache_flt() + - MINOR: config: Don't dump keywords if argument is NULL + - MEDIUM: checks: Make post-41 the default mode for mysql checks + - BUG/MINOR: logs: prevent double line returns in some events. + - MEDIUM: sink: build header in sink_write for log formats + - MEDIUM: logs: buffer targets now rely on new sink_write + - MEDIUM: sink: add global statement to create a new ring (sink buffer) + - MEDIUM: hpack: use a pool for the hpack table + - BUG/MAJOR: mux-fcgi: Stop sending loop if FCGI stream is blocked for any reason + - BUG/MEDIUM: ring: write-lock the ring while attaching/detaching + - MINOR: applet: adopt the wait list entry from the CLI + - MINOR: ring: make the applet code not depend on the CLI + - Revert "MEDIUM: sink: add global statement to create a new ring (sink buffer)" + - CI: travis-ci: fix libslz download URL + - MINOR: ssl: split config and runtime variable for ssl-{min,max}-ver + - CLEANUP: http_ana: Remove unused TXN flags + - BUG/MINOR: http-rules: Mark http return rules as final + - MINOR: http-htx: Add http_reply type based on what is used for http return rules + - CLEANUP: http-htx: Rename http_error structure into http_error_msg + - MINOR: http-rules: Use http_reply structure for http return rules + - MINOR: http-htx: Use a dedicated function to release http_reply objects + - MINOR: http-htx: Use a dedicated function to parse http reply arguments + - MINOR: http-htx: Use a dedicated function to check http reply validity + - MINOR: http-ana: Use a dedicated function to send a response from an http reply + - MEDIUM: http-rules: Rely on http reply for http deny/tarpit rules + - MINOR: http-htx: Store default error messages in a global http reply array + - MINOR: http-htx: Store messages of an http-errors section in a http reply array + - MINOR: http-htx: Store errorloc/errorfile messages in http replies + - MINOR: proxy: Add references on http replies for proxy error messages + - MINOR: http-htx: Use http reply from the http-errors section + - MINOR: http-ana: Use a TXN flag to prevent after-response ruleset evaluation + - MEDIUM: http-ana: Use http replies for HTTP error messages + - CLEANUP: http-htx: Remove unused storage of error messages in buffers + - MINOR: htx: Add a function to copy a buffer in an HTX message + - CLEANUP: channel: Remove channel_htx_copy_msg() function + - MINOR: http-ana: Add a function to write an http reply in an HTX message + - MINOR: http-htx/proxy: Add http-error directive using http return syntax + - DOC: Fix "errorfile" description in the configuration manual + - BUG/MINOR: checks: Respect check-ssl param when a port or an addr is specified + - BUILD: hpack: make sure the hpack table can still be built standalone + - CONTRIB: hpack: make use of the simplified standalone HPACK API + - MINOR: connection: add pp2-never-send-local to support old PP2 behavior + +2020/05/05 : 2.2-dev7 + - MINOR: version: Show uname output in display_version() + - CI: run weekly OpenSSL "no-deprecated" builds + - CLEANUP: log: fix comment of parse_logformat_string() + - DOC: Improve documentation on http-request set-src + - MINOR: ssl/cli: disallow SSL options for directory in 'add ssl crt-list' + - MINOR: ssl/cli: restrain certificate path when inserting into a directory + - MINOR: ssl: add ssl-skip-self-issued-ca global option + - BUG/MINOR: ssl: default settings for ssl server options are not used + - MINOR: config: add a global directive to set default SSL curves + - BUG/MEDIUM: http-ana: Handle NTLM messages correctly. + - DOC: internals: update the SSL architecture schema + - BUG/MINOR: tools: fix the i386 version of the div64_32 function + - BUG/MINOR: mux-fcgi/trace: fix wrong set of trace flags in fcgi_strm_add_eom() + - BUG/MINOR: http: make url_decode() optionally convert '+' to SP + - DOC: option logasap does not depend on mode + - MEDIUM: memory: make pool_gc() run under thread isolation + - MINOR: contrib: make the peers wireshark dissector a plugin + - BUG/MINOR: http-ana: Throw a 500 error if after-response ruleset fails on errors + - BUG/MINOR: check: Update server address and port to execute an external check + - MINOR: mini-clist: Add functions to iterate backward on a list + - MINOR: checks: Add a way to send custom headers and payload during http chekcs + - MINOR: server: respect warning and alert semantic + - BUG/MINOR: checks: Respect the no-check-ssl option + - BUG/MEDIUM: server/checks: Init server check during config validity check + - CLEANUP: checks: Don't export anymore init_check and srv_check_healthcheck_port + - BUG/MINOR: checks: chained expect will not properly wait for enough data + - BUG/MINOR: checks: Forbid tcp-check lines in default section as documented + - MINOR: checks: Use an enum to describe the tcp-check rule type + - MINOR: checks: Simplify connection flag parsing in tcp-check connect + - MEDIUM: checks: rewind to the first inverse expect rule of a chain on new data + - MINOR: checks: simplify tcp expect config parser + - MINOR: checks: add min-recv tcp-check expect option + - MINOR: checks: add linger option to tcp connect + - MINOR: checks: define a tcp expect type + - MEDIUM: checks: rewrite tcp-check expect block + - MINOR: checks: Stop xform buffers to null-terminated string for tcp-check rules + - MINOR: checks: add rbinary expect match type + - MINOR: checks: Simplify functions to get step id and comment + - MEDIUM: checks: capture groups in expect regexes + - MINOR: checks: Don't use a static tcp rule list head + - MEDIUM: checks: Use a non-comment rule iterator to get next rule + - MEDIUM: proxy/checks: Register a keyword to parse tcp-check rules + - MINOR: checks: Set the tcp-check rule index during parsing + - MINOR: checks: define tcp-check send type + - MINOR: checks: define a tcp-check connect type + - MEDIUM: checks: Add implicit tcp-check connect rule + - MAJOR: checks: Refactor and simplify the tcp-check loop + - MEDIUM: checks: Associate a session to each tcp-check healthcheck + - MINOR: checks/vars: Add a check scope for variables + - MEDIUM: checks: Parse custom action rules in tcp-checks + - MINOR: checks: Add support to set-var and unset-var rules in tcp-checks + - MINOR: checks: Add the sni option for tcp-check connect rules + - MINOR: checks: Add the via-socks4 option for tcp-check connect rules + - MINOR: checks: Add the alpn option for tcp-check connect rules + - MINOR: ssl: Export a generic function to parse an alpn string + - MINOR: checks: Add the default option for tcp-check connect rules + - MINOR: checks: Add the addr option for tcp-check connect rule + - MEDIUM: checks: Support expression to set the port + - MEDIUM: checks: Support log-format strings for tcp-check send rules + - MINOR: log: Don't depends on a stream to process samples in log-format string + - MINOR: log: Don't systematically set LW_REQ when a sample expr is added + - MEDIUM: checks: Add a shared list of tcp-check rules + - MINOR: sample: add htonl converter + - MINOR: sample: add cut_crlf converter + - MINOR: sample: add ltrim converter + - MINOR: sample: add rtrim converter + - MINOR: checks: Use a name for the healthcheck status enum + - MINOR: checks: Add option to tcp-check expect rules to customize error status + - MINOR: checks: Merge tcp-check comment rules with the others at config parsing + - MINOR: checks: Add a sample fetch to extract a block from the input check buffer + - MEDIUM: checks: Add on-error/on-success option on tcp-check expect rules + - MEDIUM: checks: Add status-code sample expression on tcp-check expect rules + - MINOR: checks: Relax the default option for tcp-check connect rules + - MEDIUM: checks: Add a list of vars to set before executing a tpc-check ruleset + - MINOR: checks: Export the tcpcheck_eval_ret enum + - MINOR: checks: Use dedicated function to handle onsuccess/onerror messages + - MINOR: checks: Support custom functions to eval a tcp-check expect rules + - MEDIUM: checks: Implement redis check using tcp-check rules + - MEDIUM: checks: Implement ssl-hello check using tcp-check rules + - MEDIUM: checks: Implement smtp check using tcp-check rules + - MEDIUM: checks: Implement postgres check using tcp-check rules + - MEDIUM: checks: Implement MySQL check using tcp-check rules + - MEDIUM: checks: Implement LDAP check using tcp-check rules + - MEDIUM: checks: Implement SPOP check using tcp-check rules + - MINOR: server/checks: Move parsing of agent keywords in checks.c + - MINOR: server/checks: Move parsing of server check keywords in checks.c + - MEDIUM: checks: Implement agent check using tcp-check rules + - REGTEST: Adapt regtests about checks to recent changes + - MINOR: Produce tcp-check info message for pure tcp-check rules only + - MINOR: checks: Add an option to set success status of tcp-check expect rules + - MINOR: checks: Improve log message of tcp-checks on success + - MINOR: proxy/checks: Move parsing of httpchk option in checks.c + - MINOR: proxy/checks: Move parsing of tcp-check option in checks.c + - MINOR: proxy/checks: Register a keyword to parse http-check rules + - MINOR: proxy/checks: Move parsing of external-check option in checks.c + - MINOR: proxy/checks: Register a keyword to parse external-check rules + - MEDIUM: checks: Use a shared ruleset to store tcp-check rules + - MINOR: checks: Use an indirect string to represent the expect matching string + - MINOR: checks: Introduce flags to configure in tcp-check expect rules + - MINOR: standard: Add my_memspn and my_memcspn + - MINOR: checks: Add a reverse non-comment rule iterator to get last rule + - MAJOR: checks: Implement HTTP check using tcp-check rules + - MINOR: checks: Make resume conditions more explicit in tcpcheck_main() + - MINOR: connection: Add macros to know if a conn or a cs uses an HTX mux + - MEDIUM: checks: Refactor how data are received in tcpcheck_main() + - MINOR: checks/obj_type: Add a new object type for checks + - BUG/MINOR: obj_type: Handle stream object in obj_base_ptr() function + - MINOR: checks: Use the check as origin when a session is created + - MINOR: checks: Add a mux proto to health-check and tcp-check connect rule + - MINOR: connection: Add a function to install a mux for a health-check + - MAJOR: checks: Use the best mux depending on the protocol for health checks + - MEDIUM: checks: Implement default TCP check using tcp-check rules + - MINOR: checks: Remove unused code about pure TCP checks + - CLEANUP: checks: Reorg checks.c file to be more readable + - REGTEST: Fix reg-tests about health-checks to adapt them to recent changes + - MINOR: ist: Add a function to retrieve the ist pointer + - MINOR: checks: Use ist API as far as possible + - BUG/MEDIUM: checks: Be sure to subscribe for sends if outgoing data remains + - MINOR: checks: Use a tree instead of a list to store tcp-check rulesets + - BUG/MINOR: checks: Send the right amount of outgoing data for HTTP checks + - REGTEST: Add scripts to test based tcp-check health-checks + - Revert "MEDIUM: checks: capture groups in expect regexes" + - DOC: Add documentation about comments for tcp-check and http-check directives + - DOC: Fix the tcp-check and http-check directives layout + - BUG/MEDIUM: checks: Use the mux protocol specified on the server line + - MINOR: checks: Support mux protocol definition for tcp and http health checks + - BUG/MINOR: mux-fcgi: Be sure to have a connection as session's origin to use it + - MINOR: checks: Support list of status codes on http-check expect rules + - BUG/MEDIUM: checks: Unsubscribe to mux events when a conn-stream is destroyed + - REGTEST: Add a script to validate agent checks + - BUG/MINOR: server: Fix server_finalize_init() to avoid unused variable + - BUG/MEDIUM: checks: unsubscribe for events on the old conn-stream on connect + - BUG/MINOR: checks: Only use ssl_sock_is_ssl() if compiled with SSL support + - BUG/MINOR: checks/server: use_ssl member must be signed + - BUG/MEDIUM: sessions: Always pass the mux context as argument to destroy a mux + - BUG/MEDIUM: checks: Destroy the conn-stream before the session + - BUG/MINOR: checks: Fix PostgreSQL regex on the authentication packet + - CI: cirrus-ci: remove reg-tests/checks/tcp-check-ssl.vtc on CentOS 6 + - MINOR: checks: Support HTTP/2 version (without '.0') for http-check send rules + - MINOR: checks: Use ver keyword to specify the HTTP version for http checks + - BUG/MINOR: checks: Remove wrong variable redeclaration + - BUG/MINOR: checks: Properly handle truncated mysql server messages + - CLEANUP: checks: Remove unused code when ldap server message is parsed + - MINOR: checks: Make the use of the check's server more explicit on connect + - BUG/MINOR: checks: Avoid incompatible cast when a binary string is parsed + - BUG/MINOR: checks: Remove bad call to free() when an expect rule is parsed + - BUG/MINOR: checks: Don't lose warning on proxy capability + - MINOR: log: Add "Tu" timer + - BUG/MINOR: checks: Set the output buffer length before calling parse_binary() + - BUG/MEDIUM: mux-h1: make sure we always have a timeout on front connections + - REGTEST: ssl: test the client certificate authentication + - DOC: give a more accurate description of what check does + - BUG/MEDIUM: capture: capture-req/capture-res converters crash without a stream + - BUG/MEDIUM: capture: capture.{req,res}.* crash without a stream + - BUG/MEDIUM: http: the "http_first_req" sample fetch could crash without a steeam + - BUG/MEDIUM: http: the "unique-id" sample fetch could crash without a steeam + - CLEANUP: http: add a few comments on certain functions' assumptions about streams + - BUG/MEDIUM: sample: make the CPU and latency sample fetches check for a stream + - MINOR: http-htx: Export functions to update message authority and host + - MINOR: checks: Don't support multiple host header for http-check send rule + - MINOR: checks: Skip some headers for http-check send rules + - MINOR: checks: Keep the Host header and the request uri synchronized + - CLEANUP: checks: Fix checks includes + - DOC: Fix send rules in the http-check connect example + - DOC: Add more info about request formatting in http-check send description + - REGTEST: http-rules: Require PCRE or PCRE2 option to run map_redirect script + - REGTEST: ssl: remove curl from the "add ssl crt-list" test + - REGTEST: ssl: improve the "set ssl cert" test + - CLEANUP: ssl: silence a build warning when threads are disabled + - BUG/MEDIUM: listener: mark the thread as not stuck inside the loop + - MINOR: threads: export the POSIX thread ID in panic dumps + - BUG/MINOR: debug: properly use long long instead of long for the thread ID + - BUG/MEDIUM: shctx: really check the lock's value while waiting + - BUG/MEDIUM: shctx: bound the number of loops that can happen around the lock + - MINOR: stream: report the list of active filters on stream crashes + - BUG/MEDIUM: mux-fcgi: Return from detach if server don't keep the connection + - BUG/MEDIUM: mux_fcgi: Free the FCGI connection at the end of fcgi_release() + - BUG/MEDIUM: mux-fcgi: Fix wrong test on FCGI_CF_KEEP_CONN in fcgi_detach() + - BUG/MEDIUM: connections: force connections cleanup on server changes + - BUG/MEDIUM: h1: Don't compare host and authority if only h1 headers are parsed + - BUG/MEDIUM: ssl: fix the id length check within smp_fetch_ssl_fc_session_id() + - CLEANUP: connections: align function declaration + - BUG/MINOR: sample: Set the correct type when a binary is converted to a string + - MEDIUM: checks/http-fetch: Support htx prefetch from a check for HTTP samples + - DOC: Document the log-format parameter for tcp-check send/send-binary rules + - MINOR: checks: Add support of payload-based sample fetches + - MINOR: checks: Add support of be_id, be_name, srv_id and srv_name sample fetches + - MINOR: checks: Add support of server side ssl sample fetches + - MINOR: checks: Add support of HTTP response sample fetches + - MINOR: http-htx: Support different methods to look for header names + - MINOR: checks: Set by default expect rule status to UNKNOWN during parsing + - BUG/MINOR: checks: Support multiple HTTP expect rules + - REGTEST: checks: Fix sync condition for agent-check + - MEDIUM: checks: Support matching on headers for http-check expect rules + - MINOR: lua: allow changing port with set_addr + - BUG/MINOR: da: Fix HTX message prefetch + - BUG/MINOR: wurfl: Fix HTX message prefetch + - BUG/MINOR: 51d: Fix HTX message prefetch + - MINOR: ist: add istadv() function + - MINOR: ist: add istissame() function + - MINOR: istbuf: add ist2buf() function + - BUG/MINOR: threads: fix multiple use of argument inside HA_ATOMIC_CAS() + - BUG/MINOR: threads: fix multiple use of argument inside HA_ATOMIC_UPDATE_{MIN,MAX}() + - DOC: update intro.txt for 2.2 + - DOC: intro: add a contacts section + +2020/04/17 : 2.2-dev6 + - BUG/MINOR: ssl: memory leak when find_chain is NULL + - CLEANUP: ssl: rename ssl_get_issuer_chain to ssl_get0_issuer_chain + - MINOR: ssl: rework add cert chain to CTX to be libssl independent + - BUG/MINOR: peers: init bind_proc to 1 if it wasn't initialized + - BUG/MINOR: peers: avoid an infinite loop with peers_fe is NULL + - BUG/MINOR: peers: Use after free of "peers" section. + - CI: github actions: add weekly h2spec test + - BUG/MEDIUM: mux_h1: Process a new request if we already received it. + - MINOR: build: Fix build in mux_h1 + - CLEANUP: remove obsolete comments + - BUG/MEDIUM: dns: improper parsing of aditional records + - MINOR: ssl: skip self issued CA in cert chain for ssl_ctx + - MINOR: listener: add so_name sample fetch + - MEDIUM: stream: support use-server rules with dynamic names + - MINOR: servers: Add a counter for the number of currently used connections. + - MEDIUM: connections: Revamp the way idle connections are killed + - MINOR: cli: add a general purpose pointer in the CLI struct + - MINOR: ssl: add a list of bind_conf in struct crtlist + - REORG: ssl: move SETCERT enum to ssl_sock.h + - BUG/MINOR: ssl: ckch_inst wrongly inserted in crtlist_entry + - REORG: ssl: move some functions above crtlist_load_cert_dir() + - MINOR: ssl: use crtlist_free() upon error in directory loading + - MINOR: ssl: add a list of crtlist_entry in ckch_store + - MINOR: ssl: store a ptr to crtlist in crtlist_entry + - MINOR: ssl/cli: update pointer to store in 'commit ssl cert' + - MEDIUM: ssl/cli: 'add ssl crt-list' command + - REGTEST: ssl/cli: test the 'add ssl crt-list' command + - BUG/MINOR: ssl: entry->ckch_inst not initialized + - REGTEST: ssl/cli: change test type to devel + - REGTEST: make the PROXY TLV validation depend on version 2.2 + - CLEANUP: assorted typo fixes in the code and comments + - BUG/MINOR: stats: Fix color of draining servers on stats page + - DOC: internals: Fix spelling errors in filters.txt + - MINOR: connections: Don't mark conn flags 0x00000001 and 0x00000002 as unused. + - REGTEST: make the unique-id test depend on version 2.0 + - BUG/MEDIUM: dns: Consider the fact that dns answers are case-insensitive + - MINOR: ssl: split the line parsing of the crt-list + - MINOR: ssl/cli: support filters and options in add ssl crt-list + - MINOR: ssl: add a comment above the ssl_bind_conf keywords + - REGTEST: ssl/cli: tests options and filters w/ add ssl crt-list + - REGTEST: ssl: pollute the crt-list file + - BUG/CRITICAL: hpack: never index a header into the headroom after wrapping + - BUG/MINOR: protocol_buffer: Wrong maximum shifting. + - CLEANUP: src/fd.c: mask setsockopt with DISGUISE + - BUG/MINOR: ssl/cli: initialize fcount int crtlist_entry + - REGTEST: ssl/cli: add other cases of 'add ssl crt-list' + - CLEANUP: assorted typo fixes in the code and comments + - DOC: management: add the new crt-list CLI commands + - BUG/MINOR: ssl/cli: fix spaces in 'show ssl crt-list' + - MINOR: ssl/cli: 'del ssl crt-list' delete an entry + - MINOR: ssl/cli: replace dump/show ssl crt-list by '-n' option + - CI: use better SSL library definition + - CI: travis-ci: enable DEBUG_STRICT=1 for CI builds + - CI: travis-ci: upgrade openssl to 1.1.1f + - MINOR: ssl: improve the errors when a crt can't be open + - CI: cirrus-ci: rename openssl package after it is renamed in FreeBSD + - CI: adopt openssl download script to download all versions + - BUG/MINOR: ssl/cli: lock the ckch structures during crt-list delete + - MINOR: ssl/cli: improve error for bundle in add/del ssl crt-list + - MINOR: ssl/cli: 'del ssl cert' deletes a certificate + - BUG/MINOR: ssl: trailing slashes in directory names wrongly cached + - BUG/MINOR: ssl/cli: memory leak in 'set ssl cert' + - CLEANUP: ssl: use the refcount for the SSL_CTX' + - CLEANUP: ssl/cli: use the list of filters in the crtlist_entry + - BUG/MINOR: ssl: memleak of the struct cert_key_and_chain + - CLEANUP: ssl: remove a commentary in struct ckch_inst + - MINOR: ssl: initialize all list in ckch_inst_new() + - MINOR: ssl: free instances and SNIs with ckch_inst_free() + - MINOR: ssl: replace ckchs_free() by ckch_store_free() + - BUG/MEDIUM: ssl/cli: trying to access to free'd memory + - MINOR: ssl: ckch_store_new() alloc and init a ckch_store + - MINOR: ssl: crtlist_new() alloc and initialize a struct crtlist + - REORG: ssl: move some free/new functions + - MINOR: ssl: crtlist_entry_{new, free} + - BUG/MINOR: ssl: ssl_conf always set to NULL on crt-list parsing + - MINOR: ssl: don't alloc ssl_conf if no option found + - BUG/MINOR: connection: always send address-less LOCAL PROXY connections + - BUG/MINOR: peers: Incomplete peers sections should be validated. + - MINOR: init: report in "haproxy -c" whether there were warnings or not + - MINOR: init: add -dW and "zero-warning" to reject configs with warnings + - MINOR: init: report the compiler version in haproxy -vv + - CLEANUP: assorted typo fixes in the code and comments + - MINOR: init: report the haproxy version and executable path once on errors + - DOC: Make how "option redispatch" works more explicit + - BUILD: Makefile: add linux-musl to TARGET + - CLEANUP: assorted typo fixes in the code and comments + - CLEANUP: http: Fixed small typo in parse_http_return + - DOC: hashing: update link to hashing functions + +2020/03/23 : 2.2-dev5 + - CLEANUP: ssl: is_default is a bit in ckch_inst + - BUG/MINOR: ssl/cli: sni_ctx' mustn't always be used as filters + - DOC: ssl: clarify security implications of TLS tickets + - CLEANUP: remove support for Linux i686 vsyscalls + - CLEANUP: drop support for USE_MY_ACCEPT4 + - CLEANUP: remove support for USE_MY_EPOLL + - CLEANUP: remove support for USE_MY_SPLICE + - CLEANUP: remove the now unused common/syscall.h + - BUILD: make dladdr1 depend on glibc version and not __USE_GNU + - BUILD: wdt: only test for SI_TKILL when compiled with thread support + - BUILD: Makefile: the compiler-specific flags should all be in SPEC_CFLAGS + - CLEANUP: ssl: separate the directory loading in a new function + - BUG/MINOR: buffers: MT_LIST_DEL_SAFE() expects the temporary pointer. + - BUG/MEDIUM: mt_lists: Make sure we set the deleted element to NULL; + - MINOR: init: move the maxsock calculation code to compute_ideal_maxsock() + - MEDIUM: init: always try to push the FD limit when maxconn is set from -m + - BUG/MAJOR: list: fix invalid element address calculation + - BUILD: stream-int: fix a few includes dependencies + - MINOR: mt_lists: Appease gcc. + - MINOR: lists: Implement function to convert list => mt_list and mt_list => list + - MINOR: servers: Kill priv_conns. + - MINOR: lists: fix indentation. + - BUG/MEDIUM: random: align the state on 2*64 bits for ARM64 + - BUG/MEDIUM: connections: Don't assume the connection has a valid session. + - BUG/MEDIUM: pools: Always update free_list in pool_gc(). + - BUG/MINOR: haproxy: always initialize sleeping_thread_mask + - BUG/MINOR: listener/mq: do not dispatch connections to remote threads when stopping + - BUG/MINOR: haproxy/threads: try to make all threads leave together + - Revert "BUILD: travis-ci: enable s390x builds" + - BUILD: travis-ci: enable regular s390x builds + - DOC: proxy_protocol: Reserve TLV type 0x05 as PP2_TYPE_UNIQUE_ID + - MINOR: proxy_protocol: Ingest PP2_TYPE_UNIQUE_ID on incoming connections + - MEDIUM: proxy_protocol: Support sending unique IDs using PPv2 + - CLEANUP: connection: Add blank line after declarations in PP handling + - CLEANUP: assorted typo fixes in the code and comments + - CI: add spellcheck github action + - DOC: correct typo in alert message about rspirep + - CI: travis: switch linux builds to clang-9 + - MINOR: debug: add a new DISGUISE() macro to pass a value as identity + - MINOR: debug: consume the write() result in BUG_ON() to silence a warning + - MINOR: use DISGUISE() everywhere we deliberately want to ignore a result + - BUILD: pools: silence build warnings with DEBUG_MEMORY_POOLS and DEBUG_UAF + - CLEANUP: connection: Stop directly setting an ist's .ptr + - CI: travis: revert to clang-7 for BoringSSL tests + - BUILD: on ARM, must be linked to libatomic. + - BUILD: makefile: fix regex syntax in ARM platform detection + - BUG/MEDIUM: peers: resync ended with RESYNC_PARTIAL in wrong cases. + - REORG: ssl: move ssl_sock_load_cert() + - MINOR: ssl: pass ckch_inst to ssl_sock_load_ckchs() + - MEDIUM: ssl: allow crt-list caching + - MINOR: ssl: directories are loaded like crt-list + - BUG/MINOR: ssl: can't open directories anymore + - BUG/MEDIUM: spoe: dup agent's engine_id string from trash.area + - MINOR: fd: Use a separate lock for logs instead of abusing the fd lock. + - MINOR: mux_pt: Don't try to remove the connection from the idle list. + - MINOR: ssl/cli: show/dump ssl crt-list + - BUG/MINOR: ssl/cli: free the trash chunk in dump_crtlist + - MEDIUM: fd: Introduce a running mask, and use it instead of the spinlock. + - BUG/MINOR: ssl: memory leak in crtlist_parse_file() + - MINOR: tasks: Provide the tasklet to the callback. + - BUG/MINOR: ssl: memleak of struct crtlist_entry + - BUG/MINOR: pattern: Do not pass len = 0 to calloc() + - BUILD: makefile: fix expression again to detect ARM platform + - CI: travis: re-enable ASAN on clang + - CI: travis: proper group output redirection together with travis_wait + - DOC: assorted typo fixes in the documentation + - MINOR: wdt: Move the definitions of WDTSIG and DEBUGSIG into types/signal.h. + - BUG/MEDIUM: wdt: Don't ignore WDTSIG and DEBUGSIG in __signal_process_queue(). + - MINOR: memory: Change the flush_lock to a spinlock, and don't get it in alloc. + - MINOR: ssl/cli: 'new ssl cert' command + - MINOR: ssl/cli: show certificate status in 'show ssl cert' + - MEDIUM: sessions: Don't be responsible for connections anymore. + - MEDIUM: servers: Split the connections into idle, safe, and available. + - MINOR: fd: Implement fd_takeover(). + - MINOR: connections: Add a new mux method, "takeover". + - MINOR: connections: Make the "list" element a struct mt_list instead of list. + - MINOR: connections: Add a flag to know if we're in the safe or idle list. + - MEDIUM: connections: Attempt to get idle connections from other threads. + - MEDIUM: mux_h1: Implement the takeover() method. + - MEDIUM: mux_h2: Implement the takeover() method. + - MEDIUM: mux_fcgi: Implement the takeover() method. + - MEDIUM: connections: Kill connections even if we are reusing one. + - BUG/MEDIUM: connections: Don't forget to decrement idle connection counters. + - BUG/MINOR: ssl: Do not free garbage pointers on memory allocation failure + - BUG/MINOR: ssl: Correctly add the 1 for the sentinel to the number of elements + - BUG/MINOR: ssl: crtlist_dup_filters() must return NULL with fcount == 0 + - BUG/MEDIUM: build: Fix compilation by spelling decl correctly. + - BUILD/MEDIUM: fd: Declare fd_mig_lock as extern. + - CI: run travis-ci builds on push only, skip pull requests + - CI: temporarily disable unstable travis arm64 builds + - BUG/MINOR: ssl/cli: free BIO upon error in 'show ssl cert' + - BUG/MINOR: connections: Make sure we free the connection on failure. + - BUG/MINOR: ssl/cli: fix a potential NULL dereference + - BUG/MEDIUM: h1: Make sure we subscribe before going into idle list. + - BUG/MINOR: connections: Set idle_time before adding to idle list. + - MINOR: muxes: Note that we can't usee a connection when added to the srv idle. + - REGTEST: increase timeouts on the seamless-reload test + - BUG/MINOR: haproxy/threads: close a possible race in soft-stop detection + - CLEANUP: haproxy/threads: don't check global_tasks_mask twice + +2020/03/09 : 2.2-dev4 + - MEDIUM: buffer: remove the buffer_wq lock + - MINOR: ssl: move find certificate chain code to its own function + - MINOR: ssl: resolve issuers chain later + - MINOR: ssl: resolve ocsp_issuer later + - MINOR: ssl/cli: "show ssl cert" command should print the "Chain Filename:" + - BUG/MINOR: h2: reject again empty :path pseudo-headers + - MINOR: wdt: always clear sigev_value to make valgrind happy + - MINOR: epoll: always initialize all of epoll_event to please valgrind + - BUG/MINOR: sample: Make sure to return stable IDs in the unique-id fetch + - BUG/MEDIUM: ssl: chain must be initialized with sk_X509_new_null() + - BUILD: cirrus-ci: suppress OS version check when installing packages + - BUG/MINOR: http_ana: make sure redirect flags don't have overlapping bits + - CLEANUP: fd: remove the FD_EV_STATUS aggregate + - CLEANUP: fd: remove some unneeded definitions of FD_EV_* flags + - MINOR: fd: merge the read and write error bits into RW error + - BUG/MINOR: dns: ignore trailing dot + - MINOR: contrib/prometheus-exporter: Add the last heathcheck duration metric + - BUG/MINOR: http-htx: Do case-insensive comparisons on Host header name + - MINOR: mux-h1: Remove useless case-insensitive comparisons + - MINOR: rawsock: always mark the FD not ready when we're certain it happens + - MEDIUM: connection: make the subscribe() call able to wakeup if ready + - MEDIUM: connection: don't stop receiving events in the FD handler + - MEDIUM: mux-h1: do not blindly wake up the tasklet at end of request anymore + - BUG/MINOR: arg: don't reject missing optional args + - MINOR: tools: make sure to correctly check the returned 'ms' in date2std_log + - MINOR: debug: report the task handler's pointer relative to main + - BUG/MEDIUM: debug: make the debug_handler check for the thread in threads_to_dump + - MINOR: haproxy: export main to ease access from debugger + - MINOR: haproxy: export run_poll_loop + - MINOR: task: export run_tasks_from_list + - BUILD: tools: remove obsolete and conflicting trace() from standard.c + - MINOR: tools: add new function dump_addr_and_bytes() + - MINOR: tools: add resolve_sym_name() to resolve function pointers + - MINOR: debug: use resolve_sym_name() to dump task handlers + - MINOR: cli: make "show fd" rely on resolve_sym_name() + - MEDIUM: debug: add support for dumping backtraces of stuck threads + - MINOR: debug: call backtrace() once upon startup + - MINOR: ssl: add "ca-verify-file" directive + - BUG/MINOR: wdt: do not return an error when the watchdog couldn't be enabled + - BUILD: Makefile: include librt before libpthread + - MEDIUM: wdt: fall back to CLOCK_REALTIME if CLOCK_THREAD_CPUTIME is not available + - MINOR: wdt: do not depend on USE_THREAD + - MINOR: debug: report the number of entries in the backtrace + - MINOR: debug: improve backtrace() on aarch64 and possibly other systems + - MINOR: debug: use our own backtrace function on clang+x86_64 + - MINOR: debug: dump the whole trace if we can't spot the starting point + - BUILD: tools: unbreak resolve_sym_name() on non-GNU platforms + - BUILD: tools: rely on __ELF__ not USE_DL to enable use of dladdr() + - CLEANUP: contrib/spoa_example: Fix several typos + - BUILD: makefile: do not modify the build options during make reg-tests + - BUG/MEDIUM: connection: stop polling for sending when the event is ready + - MEDIUM: stream-int: make sure to try to immediately validate the connection + - MINOR: tcp/uxst/sockpair: only ask for I/O when really waiting for a connect() + - MEDIUM: connection: only call ->wake() for connect() without I/O + - OPTIM: connection: disable receiving on disabled events when the run queue is too high + - OPTIM: mux-h1: subscribe rather than waking up at a few other places + - REGTEST: Add unique-id reg-test + - MINOR: stream: Add stream_generate_unique_id function + - MINOR: stream: Use stream_generate_unique_id + - BUG/MINOR: connection/debug: do not enforce !event_type on subscribe() anymore + - MINOR: ssl/cli: support crt-list filters + - MINOR: ssl: reach a ckch_store from a sni_ctx + - DOC: fix incorrect indentation of http_auth_* + - BUG/MINOR: ssl-sock: do not return an uninitialized pointer in ckch_inst_sni_ctx_to_sni_filters + - MINOR: debug: add CLI command "debug dev write" to write an arbitrary size + - MINOR: ist: Add `IST_NULL` macro + - MINOR: ist: Add `int isttest(const struct ist)` + - MINOR: ist: Add `struct ist istalloc(size_t)` and `void istfree(struct ist*)` + - CLEANUP: Use `isttest()` and `istfree()` + - MINOR: ist: Add `struct ist istdup(const struct ist)` + - MINOR: proxy: Make `header_unique_id` a `struct ist` + - MEDIUM: stream: Make the `unique_id` member of `struct stream` a `struct ist` + - OPTIM: startup: fast unique_id allocation for acl. + - DOC: configuration.txt: fix various typos + - DOC: assorted typo fixes in the documentation and Makefile + - BUG/MINOR: init: make the automatic maxconn consider the max of soft/hard limits + - BUG/MAJOR: proxy_protocol: Properly validate TLV lengths + - CLEANUP: proxy_protocol: Use `size_t` when parsing TLVs + - MINOR: buf: Add function to insert a string at an absolute offset in a buffer + - MINOR: htx: Add a function to return a block at a specific offset + - MINOR: htx: Use htx_find_offset() to truncate an HTX message + - MINOR: flt_trace: Use htx_find_offset() to get the available payload length + - BUG/MINOR: filters: Use filter offset to decude the amount of forwarded data + - BUG/MINOR: filters: Forward everything if no data filters are called + - BUG/MEDIUM: cache/filters: Fix loop on HTX blocks caching the response payload + - BUG/MEDIUM: compression/filters: Fix loop on HTX blocks compressing the payload + - BUG/MINOR: http-ana: Reset request analysers on a response side error + - BUG/MINOR: lua: Abort when txn:done() is called from a Lua action + - BUG/MINOR: lua: Ignore the reserve to know if a channel is full or not + - MINOR: lua: Add function to know if a channel is a response one + - MINOR: lua: Stop using the lua txn in hlua_http_get_headers() + - MINOR: lua: Stop using the lua txn in hlua_http_rep_hdr() + - MINOR: lua: Stop using lua txn in hlua_http_del_hdr() and hlua_http_add_hdr() + - MINOR: lua: Remove the flag HLUA_TXN_HTTP_RDY + - MINOR: lua: Rename hlua_action_wake_time() to hlua_set_wake_time() + - BUG/MINOR: lua: Init the lua wake_time value before calling a lua function + - BUG/MINOR: http-rules: Return ACT_RET_ABRT to abort a transaction + - BUG/MINOR: http-rules: Preserve FLT_END analyzers on reject action + - BUG/MINOR: http-rules: Fix a typo in the reject action function + - MINOR: cache/filters: Initialize the cache filter when stream is created + - MINOR: compression/filters: Initialize the comp filter when stream is created + - BUG/MINOR: rules: Preserve FLT_END analyzers on silent-drop action + - BUG/MINOR: rules: Return ACT_RET_ABRT when a silent-drop action is executed + - BUG/MINOR: rules: Increment be_counters if backend is assigned for a silent-drop + - BUG/MINOR: http-rules: Abort transaction when a redirect is applied on response + - BUILD: buffer: types/{ring.h,checks.h} should include buf.h, not buffer.h + - BUILD: ssl: include mini-clist.h + - BUILD: global: must not include common/standard.h but only types/freq_ctr.h + - BUILD: freq_ctr: proto/freq_ctr needs to include common/standard.h + - BUILD: listener: types/listener.h must not include standard.h + - BUG/MEDIUM: random: initialize the random pool a bit better + - BUG/MEDIUM: random: implement per-thread and per-process random sequences + - Revert "BUG/MEDIUM: random: implement per-thread and per-process random sequences" + - BUILD: cirrus-ci: get rid of unstable freebsd images + - MINOR: tools: add 64-bit rotate operators + - BUG/MEDIUM: random: implement a thread-safe and process-safe PRNG + - MINOR: backend: use a single call to ha_random32() for the random LB algo + - BUG/MINOR: checks/threads: use ha_random() and not rand() + - MINOR: sample: make all bits random on the rand() sample fetch + - MINOR: tools: add a generic function to generate UUIDs + - DOC: fix typo about no-tls-tickets + - DOC: improve description of no-tls-tickets + - DOC: assorted typo fixes in the documentation + - CLEANUP: remove unused code in 'my_ffsl/my_flsl' functions + +2020/02/25 : 2.2-dev3 + - SCRIPTS: announce-release: place the send command in the mail's header + - SCRIPTS: announce-release: allow the user to force to overwrite old files + - SCRIPTS: backport: fix the master branch detection + - BUG/MINOR: http-act: Set stream error flag before returning an error + - BUG/MINOR: http-act: Fix bugs on error path during parsing of return actions + - BUG/MEDIUM: ssl/cli: 'commit ssl cert' wrong SSL_CTX init + - BUG/MEDIUM: tcp-rules: Fix track-sc* actions for L4/L5 TCP rules + - DOC: schematic of the SSL certificates architecture + - BUG/MAJOR: mux-h2: don't wake streams after connection was destroyed + - BUG/MINOR: unix: better catch situations where the unix socket path length is close to the limit + - BUILD: cirrus-ci: switch to "snap" images to unify openssl naming + - BUILD: cirrus-ci: workaround "pkg install" bug + - BUILD: cirrus-ci: add ERR=1 to freebsd builds + - BUG/MINOR: connection: correctly retry I/O on signals + - CLEANUP: mini-clist: simplify nested do { while(1) {} } while (0) + - BUILD: http_act: cast file sizes when reporting file size error + - BUG/MEDIUM: listener: only consider running threads when resuming listeners + - BUG/MINOR: listener: enforce all_threads_mask on bind_thread on init + - BUG/MINOR: tcp: avoid closing fd when socket failed in tcp_bind_listener + - MINOR: build: add aix72-gcc build TARGET and power{8,9} CPUs + - BUILD: travis-ci: no more allowed failures for openssl-1.0.2 + - BUILD: travis-ci: harden builds, add ERR=1 (warning ought to be errors) + - BUILD: scripts/build-ssl.sh: use "uname" instead of ${TRAVIS_OS_NAME} + - BUG/MINOR: tcp: don't try to set defaultmss when value is negative + - SCRIPTS: make announce-release executable again + - BUG/MINOR: namespace: avoid closing fd when socket failed in my_socketat + - BUG/MEDIUM: muxes: Use the right argument when calling the destroy method. + - BUG/MINOR: mux-fcgi: Forbid special characters when matching PATH_INFO param + - CLEANUP: ssl: remove unused functions in openssl-compat.h + - MINOR: mux-fcgi: Make the capture of the path-info optional in pathinfo regex + - MINOR: tools: add is_idchar() to tell if a char may belong to an identifier + - MINOR: chunk: implement chunk_strncpy() to copy partial strings + - MINOR: sample/acl: use is_idchar() to locate the fetch/conv name + - MEDIUM: arg: make make_arg_list() stop after its own arguments + - MEDIUM: arg: copy parsed arguments into the trash instead of allocating them + - MEDIUM: arg: make make_arg_list() support quotes in arguments + - MINOR: sample: make sample_parse_expr() able to return an end pointer + - MEDIUM: log-format: make the LF parser aware of sample expressions' end + - BUG/MINOR: arg: report an error if an argument is larger than bufsize + - SCRIPTS: announce-release: use mutt -H instead of -i to include the draft + - BUILD: enable ERR=1 in github cygwin builds + - BUG/MINOR: arg: fix again incorrect argument length check + - MINOR: sample: regsub now supports backreferences + - BUG/MINOR: tools: also accept '+' as a valid character in an identifier + - MINOR: http-htx: Add a function to retrieve the headers size of an HTX message + - MINOR: filters: Forward data only if the last filter forwards something + - BUG/MINOR: filters: Count HTTP headers as filtered data but don't forward them + - BUG/MINOR: http-htx: Don't return error if authority is updated without changes + - BUG/MINOR: stream: Don't incr frontend cum_req counter when stream is closed + - BUG/MINOR: sample: exit regsub() in case of trash allocation error + - MINOR: ssl: add "issuers-chain-path" directive. + - REGTESTS: use "command -v" instead of "which" + - BUG/MINOR: http-ana: Matching on monitor-uri should be case-sensitive + - MINOR: http-ana: Match on the path if the monitor-uri starts by a / + - BUG/MINOR: ssl: Stop passing dynamic strings as format arguments + - BUG/MAJOR: http-ana: Always abort the request when a tarpit is triggered + - BUG/MINOR: mux: do not call conn_xprt_stop_recv() on buffer shortage + - MINOR: checks: do not call conn_xprt_stop_send() anymore + - CLEANUP: epoll: place the struct epoll_event in the stack + - MEDIUM: connection: remove the intermediary polling state from the connection + - MINOR: raw_sock: directly call fd_stop_send() and not conn_xprt_stop_send() + - MINOR: tcp/uxst/sockpair: use fd_want_send() instead of conn_xprt_want_send() + - MINOR: connection: remove the last calls to conn_xprt_{want,stop}_* + - CLEANUP: connection: remove the definitions of conn_xprt_{stop,want}_{send,recv} + - MINOR: connection: introduce a new receive flag: CO_RFL_READ_ONCE + - MINOR: mux-h1: pass CO_RFL_READ_ONCE to the lower layers when relevant + - MINOR: ist: add an iststop() function + - BUG/MINOR: http: http-request replace-path duplicates the query string + - CLEANUP: sample: use iststop instead of a for loop + - BUG/MEDIUM: shctx: make sure to keep all blocks aligned + - MINOR: compiler: move CPU capabilities definition from config.h and complete them + - BUG/MEDIUM: ebtree: don't set attribute packed without unaligned access support + - CLEANUP: http/h1: rely on HA_UNALIGNED_LE instead of checking for CPU families + - BUILD: fix recent build failure on unaligned archs + - MINOR: ssl: load the key from a dedicated file + - BUG/MINOR: ssl: load .key in a directory only after PEM + - MINOR: compiler: drop special cases of likely/unlikely for older compilers + - CLEANUP: conn: Do not pass a pointer to likely + - CLEANUP: net_helper: Do not negate the result of unlikely + - BUILD: remove obsolete support for -mregparm / USE_REGPARM + - CLEANUP: cfgparse: Fix type of second calloc() parameter + - BUILD: ssl: only pass unsigned chars to isspace() + - BUILD: general: always pass unsigned chars to is* functions + - BUG/MINOR: sample: fix the json converter's endian-sensitivity + - BUG/MEDIUM: ssl: fix several bad pointer aliases in a few sample fetch functions + - CLEANUP: fd: use a union in fd_rm_from_fd_list() to shut aliasing warnings + - CLEANUP: cache: use read_u32/write_u32 to access the cache entry's hash + - CLEANUP: stick-tables: use read_u32() to display a node's key + - CLEANUP: sample: use read_u64() in ipmask() to apply an IPv6 mask + - MINOR: pattern: fix all remaining strict aliasing issues + - CLEANUP: lua: fix aliasing issues in the address matching code + - CLEANUP: connection: use read_u32() instead of a cast in the netscaler parser + - BUILD: makefile: re-enable strict aliasing + - BUG/MINOR: connection: make sure to correctly tag local PROXY connections + - MINOR: compiler: add new alignment macros + - BUILD: ebtree: improve architecture-specific alignment + - MINOR: config: mark global.debug as deprecated + - BUILD: travis-ci: enable s390x builds + - MINOR: ssl/cli: 'show ssl cert' displays the chain + - MINOR: ssl/cli: 'show ssl cert'displays the issuer in the chain + - MINOR: ssl/cli: reorder 'show ssl cert' output + - CLEANUP: ssl: move issuer_chain tree and definition + - DOC: proxy-protocol: clarify IPv6 address representation in the spec + +2020/02/07 : 2.2-dev2 + - BUILD: CI: temporarily mark openssl-1.0.2 as allowed failure + - MEDIUM: cli: Allow multiple filter entries for "show table" + - BUG/MEDIUM: netscaler: Don't forget to allocate storage for conn->src/dst. + - BUG/MINOR: ssl: ssl_sock_load_pem_into_ckch is not consistent + - BUILD: stick-table: fix build errors introduced by last stick-table change + - BUG/MINOR: cli: Missing arg offset for filter data values. + - MEDIUM: streams: Always create a conn_stream in connect_server(). + - MEDIUM: connections: Get ride of the xprt_done callback. + - CLEANUP: changelog: remove the duplicate entry for 2.2-dev1 + - BUILD: CI: move cygwin builds to Github Actions + - MINOR: cli: Report location of errors or any extra data for "show table" + - BUG/MINOR: ssl/cli: free the previous ckch content once a PEM is loaded + - CLEANUP: backend: remove useless test for inexistent connection + - CLEANUP: backend: shut another false null-deref in back_handle_st_con() + - CLEANUP: stats: shut up a wrong null-deref warning from gcc 9.2 + - BUG/MINOR: ssl: increment issuer refcount if in chain + - BUG/MINOR: ssl: memory leak w/ the ocsp_issuer + - BUG/MINOR: ssl: typo in previous patch + - BUG/MEDIUM: connections: Set CO_FL_CONNECTED in conn_complete_session(). + - BUG/MINOR: ssl/cli: ocsp_issuer must be set w/ "set ssl cert" + - MEDIUM: connection: remove CO_FL_CONNECTED and only rely on CO_FL_WAIT_* + - BUG/MEDIUM: 0rtt: Only consider the SSL handshake. + - MINOR: stream-int: always report received shutdowns + - MINOR: connection: remove CO_FL_SSL_WAIT_HS from CO_FL_HANDSHAKE + - MEDIUM: connection: use CO_FL_WAIT_XPRT more consistently than L4/L6/HANDSHAKE + - MINOR: connection: remove checks for CO_FL_HANDSHAKE before I/O + - MINOR: connection: do not check for CO_FL_SOCK_RD_SH too early + - MINOR: connection: don't check for CO_FL_SOCK_WR_SH too early in handshakes + - MINOR: raw-sock: always check for CO_FL_SOCK_WR_SH before sending + - MINOR: connection: remove some unneeded checks for CO_FL_SOCK_WR_SH + - BUG/MINOR: stktable: report the current proxy name in error messages + - BUG/MEDIUM: mux-h2: make sure we don't emit TE headers with anything but "trailers" + - MINOR: lua: Add hlua_prepend_path function + - MINOR: lua: Add lua-prepend-path configuration option + - MINOR: lua: Add HLUA_PREPEND_C?PATH build option + - BUILD: cfgparse: silence a bogus gcc warning on 32-bit machines + - BUG/MINOR: http-ana: Increment the backend counters on the backend + - BUG/MINOR: stream: Be sure to have a listener to increment its counters + - BUG/MEDIUM: streams: Move the conn_stream allocation outside #IF USE_OPENSSL. + - REGTESTS: make the set_ssl_cert test require version 2.2 + - BUG/MINOR: ssl: Possible memleak when allowing the 0RTT data buffer. + - MINOR: ssl: Remove dead code. + - BUG/MEDIUM: ssl: Don't forget to free ctx->ssl on failure. + - BUG/MEDIUM: stream: Don't install the mux in back_handle_st_con(). + - MEDIUM: streams: Don't close the connection in back_handle_st_con(). + - MEDIUM: streams: Don't close the connection in back_handle_st_rdy(). + - BUILD: CI: disable slow regtests on Travis + - BUG/MINOR: tcpchecks: fix the connect() flags regarding delayed ack + - BUG/MINOR: http-rules: Always init log-format expr for common HTTP actions + - BUG/MINOR: connection: fix ip6 dst_port copy in make_proxy_line_v2 + - BUG/MINOR: dns: allow 63 char in hostname + - MINOR: proxy: clarify number of connections log when stopping + - DOC: word converter ignores delimiters at the start or end of input string + - MEDIUM: raw-sock: remove obsolete calls to fd_{cant,cond,done}_{send,recv} + - BUG/MINOR: ssl/cli: fix unused variable with openssl < 1.0.2 + - MEDIUM: pipe/thread: reduce the locking overhead + - MEDIUM: pipe/thread: maintain a per-thread local cache of recently used pipes + - BUG/MEDIUM: pipe/thread: fix atomicity of pipe counters + - MINOR: tasks: move the list walking code to its own function + - MEDIUM: tasks: implement 3 different tasklet classes with their own queues + - MEDIUM: tasks: automatically requeue into the bulk queue an already running tasklet + - OPTIM: task: refine task classes default CPU bandwidth ratios + - BUG/MEDIUM: connections: Don't forget to unlock when killing a connection. + - MINOR: task: permanently flag tasklets waking themselves up + - MINOR: task: make sched->current also reflect tasklets + - MINOR: task: detect self-wakeups on tl==sched->current instead of TASK_RUNNING + - OPTIM: task: readjust CPU bandwidth distribution since last update + - MINOR: task: don't set TASK_RUNNING on tasklets + - BUG/MEDIUM: memory_pool: Update the seq number in pool_flush(). + - MINOR: memory: Only init the pool spinlock once. + - BUG/MEDIUM: memory: Add a rwlock before freeing memory. + - BUG/MAJOR: memory: Don't forget to unlock the rwlock if the pool is empty. + - MINOR: ssl: ssl-load-extra-files configure loading of files + - SCRIPTS: add a new "backport" script to simplify long series of backports + - BUG/MINOR: ssl: we may only ignore the first 64 errors + - SCRIPTS: use /usr/bin/env bash instead of /bin/bash for scripts + - BUG/MINOR: ssl: clear the SSL errors on DH loading failure + - CLEANUP: hpack: remove a redundant test in the decoder + - CLEANUP: peers: Remove unused static function `free_dcache` + - CLEANUP: peers: Remove unused static function `free_dcache_tx` + - CONTRIB: debug: add missing flags SF_HTX and SF_MUX + - CONTRIB: debug: add the possibility to decode the value as certain types only + - CONTRIB: debug: support reporting multiple values at once + - BUG/MINOR: http-act: Use the good message to test strict rewritting mode + - MINOR: global: Set default tune.maxrewrite value during global structure init + - MINOR: http-rules: Set SF_ERR_PRXCOND termination flag when a header rewrite fails + - MINOR: http-htx: Emit a warning if an error file runs over the buffer's reserve + - MINOR: htx: Add a function to append an HTX message to another one + - MINOR: htx/channel: Add a function to copy an HTX message in a channel's buffer + - BUG/MINOR: http-ana: Don't overwrite outgoing data when an error is reported + - MINOR: dns: Dynamically allocate dns options to reduce the act_rule size + - MINOR: dns: Add function to release memory allocated for a do-resolve rule + - BUG/MINOR: http-ana: Reset HTX first index when HAPRoxy sends a response + - BUG/MINOR: http-ana: Set HTX_FL_PROXY_RESP flag if a server perform a redirect + - MINOR: http-rules: Add a flag on redirect rules to know the rule direction + - MINOR: http-rules: Handle the rule direction when a redirect is evaluated + - MINOR: http-ana: Rely on http_reply_and_close() to handle server error + - MINOR: http-ana: Add a function for forward internal responses + - MINOR: http-ana/http-rules: Use dedicated function to forward internal responses + - MEDIUM: http: Add a ruleset evaluated on all responses just before forwarding + - MEDIUM: http-rules: Add the return action to HTTP rules + - MEDIUM: http-rules: Support extra headers for HTTP return actions + - CLEANUP: lua: Remove consistency check for sample fetches and actions + - BUG/MINOR: http-ana: Increment failed_resp counters on invalid response + - MINOR: lua: Get the action return code on the stack when an action finishes + - MINOR: lua: Create the global 'act' object to register all action return codes + - MINOR: lua: Add act:wake_time() function to set a timeout when an action yields + - MEDIUM: lua: Add ability for actions to intercept HTTP messages + - REGTESTS: Add reg tests for the HTTP return action + - REGTESTS: Add a reg test for http-after-response rulesets + - BUILD: lua: silence a warning on systems where longjmp is not marked as noreturn + - MINOR: acl: Warn when an ACL is named 'or' + - CONTRIB: debug: also support reading values from stdin + - SCRIPTS: backport: use short revs and resolve the initial commit + - BUG/MINOR: acl: Fix type of log message when an acl is named 'or' + +2020/01/22 : 2.2-dev1 + - DOC: this is development again + - MINOR: version: this is development again, update the status + - SCRIPTS: update create-release to fix the changelog on new branches + - CLEANUP: ssl: Clean up error handling + - BUG/MINOR: contrib/prometheus-exporter: decode parameter and value only + - BUG/MINOR: h1: Don't test the host header during response parsing + - BUILD/MINOR: trace: fix use of long type in a few printf format strings + - DOC: Clarify behavior of server maxconn in HTTP mode + - MINOR: ssl: deduplicate ca-file + - MINOR: ssl: compute ca-list from deduplicate ca-file + - MINOR: ssl: deduplicate crl-file + - CLEANUP: dns: resolution can never be null + - BUG/MINOR: http-htx: Don't make http_find_header() fail if the value is empty + - DOC: ssl/cli: set/commit/abort ssl cert + - BUG/MINOR: ssl: fix SSL_CTX_set1_chain compatibility for openssl < 1.0.2 + - BUG/MINOR: fcgi-app: Make the directive pass-header case insensitive + - BUG/MINOR: stats: Fix HTML output for the frontends heading + - BUG/MINOR: ssl: fix X509 compatibility for openssl < 1.1.0 + - DOC: clarify matching strings on binary fetches + - DOC: Fix ordered list in summary + - DOC: move the "group" keyword at the right place + - MEDIUM: init: prevent process and thread creation at runtime + - BUG/MINOR: ssl/cli: 'ssl cert' cmd only usable w/ admin rights + - BUG/MEDIUM: stream-int: don't subscribed for recv when we're trying to flush data + - BUG/MINOR: stream-int: avoid calling rcv_buf() when splicing is still possible + - BUG/MINOR: ssl/cli: don't overwrite the filters variable + - BUG/MEDIUM: listener/thread: fix a race when pausing a listener + - BUG/MINOR: ssl: certificate choice can be unexpected with openssl >= 1.1.1 + - BUG/MEDIUM: mux-h1: Never reuse H1 connection if a shutw is pending + - BUG/MINOR: mux-h1: Don't rely on CO_FL_SOCK_RD_SH to set H1C_F_CS_SHUTDOWN + - BUG/MINOR: mux-h1: Fix conditions to know whether or not we may receive data + - BUG/MEDIUM: tasks: Make sure we switch wait queues in task_set_affinity(). + - BUG/MEDIUM: checks: Make sure we set the task affinity just before connecting. + - MINOR: debug: replace popen() with pipe+fork() in "debug dev exec" + - MEDIUM: init: set NO_NEW_PRIVS by default when supported + - BUG/MINOR: mux-h1: Be sure to set CS_FL_WANT_ROOM when EOM can't be added + - BUG/MEDIUM: mux-fcgi: Handle cases where the HTX EOM block cannot be inserted + - BUG/MINOR: proxy: make soft_stop() also close FDs in LI_PAUSED state + - BUG/MINOR: listener/threads: always use atomic ops to clear the FD events + - BUG/MINOR: listener: also clear the error flag on a paused listener + - BUG/MEDIUM: listener/threads: fix a remaining race in the listener's accept() + - MINOR: listener: make the wait paths cleaner and more reliable + - MINOR: listener: split dequeue_all_listener() in two + - REORG: listener: move the global listener queue code to listener.c + - DOC: document the listener state transitions + - BUG/MEDIUM: kqueue: Make sure we report read events even when no data. + - BUG/MAJOR: dns: add minimalist error processing on the Rx path + - BUG/MEDIUM: proto_udp/threads: recv() and send() must not be exclusive. + - DOC: listeners: add a few missing transitions + - BUG/MINOR: tasks: only requeue a task if it was already in the queue + - MINOR: tasks: split wake_expired_tasks() in two parts to avoid useless wakeups + - DOC: proxies: HAProxy only supports 3 connection modes + - DOC: remove references to the outdated architecture.txt + - BUG/MINOR: log: fix minor resource leaks on logformat error path + - BUG/MINOR: mworker: properly pass SIGTTOU/SIGTTIN to workers + - BUG/MINOR: listener: do not immediately resume on transient error + - BUG/MINOR: server: make "agent-addr" work on default-server line + - BUG/MINOR: listener: fix off-by-one in state name check + - BUILD/MINOR: unix sockets: silence an absurd gcc warning about strncpy() + - MEDIUM: h1-htx: Add HTX EOM block when the message is in H1_MSG_DONE state + - MINOR: http-htx: Add some htx sample fetches for debugging purpose + - REGTEST: Add an HTX reg-test to check an edge case + - DOC: clarify the fact that replace-uri works on a full URI + - BUG/MINOR: sample: fix the closing bracket and LF in the debug converter + - BUG/MINOR: sample: always check converters' arguments + - MINOR: sample: Validate the number of bits for the sha2 converter + - BUG/MEDIUM: ssl: Don't set the max early data we can receive too early. + - MINOR: ssl/cli: 'show ssl cert' give information on the certificates + - BUG/MINOR: ssl/cli: fix build for openssl < 1.0.2 + - MINOR: debug: support logging to various sinks + - MINOR: http: add a new "replace-path" action + - REGTEST: ssl: test the "set ssl cert" CLI command + - REGTEST: run-regtests: implement #REQUIRE_BINARIES + - MINOR: task: only check TASK_WOKEN_ANY to decide to requeue a task + - BUG/MAJOR: task: add a new TASK_SHARED_WQ flag to fix foreing requeuing + - BUG/MEDIUM: ssl: Revamp the way early data are handled. + - MINOR: fd/threads: make _GET_NEXT()/_GET_PREV() use the volatile attribute + - BUG/MEDIUM: fd/threads: fix a concurrency issue between add and rm on the same fd + - REGTEST: make the "set ssl cert" require version 2.1 + - BUG/MINOR: ssl: openssl-compat: Fix getm_ defines + - BUG/MEDIUM: state-file: do not allocate a full buffer for each server entry + - BUG/MINOR: state-file: do not store duplicates in the global tree + - BUG/MINOR: state-file: do not leak memory on parse errors + - BUG/MAJOR: mux-h1: Don't pretend the input channel's buffer is full if empty + - BUG/MEDIUM: stream: Be sure to never assign a TCP backend to an HTX stream + - BUILD: ssl: improve SSL_CTX_set_ecdh_auto compatibility + - BUILD: travis-ci: link with ssl libraries using rpath instead of LD_LIBRARY_PATH/DYLD_LIBRARY_PATH + - BUILD: travis-ci: reenable address sanitizer for clang builds + - BUG/MINOR: checks: refine which errno values are really errors. + - BUG/MINOR: connection: only wake send/recv callbacks if the FD is active + - CLEANUP: connection: conn->xprt is never NULL + - MINOR: pollers: add a new flag to indicate pollers reporting ERR & HUP + - MEDIUM: tcp: make tcp_connect_probe() consider ERR/HUP + - REORG: connection: move tcp_connect_probe() to conn_fd_check() + - MINOR: connection: check for connection validation earlier + - MINOR: connection: remove the double test on xprt_done_cb() + - CLEANUP: connection: merge CO_FL_NOTIFY_DATA and CO_FL_NOTIFY_DONE + - MINOR: poller: do not call the IO handler if the FD is not active + - OPTIM: epoll: always poll for recv if neither active nor ready + - OPTIM: polling: do not create update entries for FD removal + - BUG/MEDIUM: checks: Only attempt to do handshakes if the connection is ready. + - BUG/MEDIUM: connections: Hold the lock when wanting to kill a connection. + - BUILD: CI: modernize cirrus-ci + - MINOR: config: disable busy polling on old processes + - MINOR: ssl: Remove unused variable "need_out". + - BUG/MINOR: h1: Report the right error position when a header value is invalid + - BUG/MINOR: proxy: Fix input data copy when an error is captured + - BUG/MEDIUM: http-ana: Truncate the response when a redirect rule is applied + - BUG/MINOR: channel: inject output data at the end of output + - BUG/MEDIUM: session: do not report a failure when rejecting a session + - MEDIUM: dns: implement synchronous send + - MINOR: raw_sock: make sure to disable polling once everything is sent + - MINOR: http: Add 410 to http-request deny + - MINOR: http: Add 404 to http-request deny + - CLEANUP: mux-h2: remove unused goto "out_free_h2s" + - BUILD: cirrus-ci: choose proper openssl package name + - BUG/MAJOR: listener: do not schedule a task-less proxy + - CLEANUP: server: remove unused err section in server_finalize_init + - REGTEST: set_ssl_cert.vtc: replace "echo" with "printf" + - BUG/MINOR: stream-int: Don't trigger L7 retry if max retries is already reached + - BUG/MEDIUM: tasks: Use the MT macros in tasklet_free(). + - BUG/MINOR: mux-h2: use a safe list_for_each_entry in h2_send() + - BUG/MEDIUM: mux-h2: fix missing test on sending_list in previous patch + - CLEANUP: ssl: remove opendir call in ssl_sock_load_cert + - MEDIUM: lua: don't call the GC as often when dealing with outgoing connections + - BUG/MEDIUM: mux-h2: don't stop sending when crossing a buffer boundary + - BUG/MINOR: cli/mworker: can't start haproxy with 2 programs + - REGTEST: mcli/mcli_start_progs: start 2 programs + - BUG/MEDIUM: mworker: remain in mworker mode during reload + - DOC: clarify crt-base usage + - CLEANUP: compression: remove unused deinit_comp_ctx section + - BUG/MEDIUM: mux_h1: Don't call h1_send if we subscribed(). + - BUG/MEDIUM: raw_sock: Make sur the fd and conn are sync. + - CLEANUP: proxy: simplify proxy_parse_rate_limit proxy checks + - BUG/MAJOR: hashes: fix the signedness of the hash inputs + - REGTEST: add sample_fetches/hashes.vtc to validate hashes + - BUG/MEDIUM: cli: _getsocks must send the peers sockets + - CLEANUP: cli: deduplicate the code in _getsocks + - BUG/MINOR: stream: don't mistake match rules for store-request rules + - BUG/MEDIUM: connection: add a mux flag to indicate splice usability + - BUG/MINOR: pattern: handle errors from fgets when trying to load patterns + - MINOR: connection: move the CO_FL_WAIT_ROOM cleanup to the reader only + - MINOR: stream-int: remove dependency on CO_FL_WAIT_ROOM for rcv_buf() + - MEDIUM: connection: get rid of CO_FL_CURR_* flags + - BUILD: pattern: include errno.h + - MEDIUM: mux-h2: do not try to stop sending streams on blocked mux + - MEDIUM: mux-fcgi: do not try to stop sending streams on blocked mux + - MEDIUM: mux-h2: do not make an h2s subscribe to itself on deferred shut + - MEDIUM: mux-fcgi: do not make an fstrm subscribe to itself on deferred shut + - REORG: stream/backend: move backend-specific stuff to backend.c + - MEDIUM: backend: move the connection finalization step to back_handle_st_con() + - MEDIUM: connection: merge the send_wait and recv_wait entries + - MEDIUM: xprt: merge recv_wait and send_wait in xprt_handshake + - MEDIUM: ssl: merge recv_wait and send_wait in ssl_sock + - MEDIUM: mux-h1: merge recv_wait and send_wait + - MEDIUM: mux-h2: merge recv_wait and send_wait event notifications + - MEDIUM: mux-fcgi: merge recv_wait and send_wait event notifications + - MINOR: connection: make the last arg of subscribe() a struct wait_event* + - MINOR: ssl: Add support for returning the dn samples from ssl_(c|f)_(i|s)_dn in LDAP v3 (RFC2253) format. + - DOC: Fix copy and paste mistake in http-response replace-value doc + - BUG/MINOR: cache: Fix leak of cache name in error path + - BUG/MINOR: dns: Make dns_query_id_seed unsigned + - BUG/MINOR: 51d: Fix bug when HTX is enabled + - MINOR: http-htx: Move htx sample fetches in the scope "internal" + - MINOR: http-htx: Rename 'internal.htx_blk.val' to 'internal.htx_blk.data' + - MINOR: http-htx: Make 'internal.htx_blk_data' return a binary string + - DOC: Add a section to document the internal sample fetches + - MINOR: mux-h1: Inherit send flags from the upper layer + - MINOR: contrib/prometheus-exporter: Add heathcheck status/code in server metrics + - BUG/MINOR: http-ana/filters: Wait end of the http_end callback for all filters + - BUG/MINOR: http-rules: Remove buggy deinit functions for HTTP rules + - BUG/MINOR: stick-table: Use MAX_SESS_STKCTR as the max track ID during parsing + - MEDIUM: http-rules: Register an action keyword for all http rules + - MINOR: tcp-rules: Always set from which ruleset a rule comes from + - MINOR: actions: Use ACT_RET_CONT code to ignore an error from a custom action + - MINOR: tcp-rules: Kill connections when custom actions return ACT_RET_ERR + - MINOR: http-rules: Return an error when custom actions return ACT_RET_ERR + - MINOR: counters: Add a counter to report internal processing errors + - MEDIUM: http-ana: Properly handle internal processing errors + - MINOR: http-rules: Add a rule result to report internal error + - MINOR: http-rules: Handle internal errors during HTTP rules evaluation + - MINOR: http-rules: Add more return codes to let custom actions act as normal ones + - MINOR: tcp-rules: Handle denied/aborted/invalid connections from TCP rules + - MINOR: http-rules: Handle denied/aborted/invalid connections from HTTP rules + - MINOR: stats: Report internal errors in the proxies/listeners/servers stats + - MINOR: contrib/prometheus-exporter: Export internal errors per proxy/server + - MINOR: counters: Remove failed_secu counter and use denied_resp instead + - MINOR: counters: Review conditions to increment counters from analysers + - MINOR: http-ana: Add a txn flag to support soft/strict message rewrites + - MINOR: http-rules: Handle all message rewrites the same way + - MINOR: http-rules: Add a rule to enable or disable the strict rewriting mode + - MEDIUM: http-rules: Enable the strict rewriting mode by default + - REGTEST: Fix format of set-uri HTTP request rule in h1or2_to_h1c.vtc + - MINOR: actions: Add a function pointer to release args used by actions + - MINOR: actions: Regroup some info about HTTP rules in the same struct + - MINOR: http-rules/tcp-rules: Call the defined action function first if defined + - MINOR: actions: Rename the act_flag enum into act_opt + - MINOR: actions: Add flags to configure the action behaviour + - MINOR: actions: Use an integer to set the action type + - MINOR: http-rules: Use a specific action type for some custom HTTP actions + - MINOR: http-rules: Make replace-header and replace-value custom actions + - MINOR: http-rules: Make set-header and add-header custom actions + - MINOR: http-rules: Make set/del-map and add/del-acl custom actions + - MINOR: http-rules: Group all processing of early-hint rule in its case clause + - MEDIUM: http-rules: Make early-hint custom actions + - MINOR: http-rule/tcp-rules: Make track-sc* custom actions + - MINOR: tcp-rules: Make tcp-request capture a custom action + - MINOR: http-rules: Add release functions for existing HTTP actions + - BUG/MINOR: http-rules: Fix memory releases on error path during action parsing + - MINOR: tcp-rules: Add release functions for existing TCP actions + - BUG/MINOR: tcp-rules: Fix memory releases on error path during action parsing + - MINOR: http-htx: Add functions to read a raw error file and convert it in HTX + - MINOR: http-htx: Add functions to create HTX redirect message + - MINOR: config: Use dedicated function to parse proxy's errorfiles + - MINOR: config: Use dedicated function to parse proxy's errorloc + - MEDIUM: http-htx/proxy: Use a global and centralized storage for HTTP error messages + - MINOR: proxy: Register keywords to parse errorfile and errorloc directives + - MINOR: http-htx: Add a new section to create groups of custom HTTP errors + - MEDIUM: proxy: Add a directive to reference an http-errors section in a proxy + - MINOR: http-rules: Update txn flags and status when a deny rule is executed + - MINOR: http-rules: Support an optional status on deny rules for http reponses + - MINOR: http-rules: Use same function to parse request and response deny actions + - MINOR: http-ana: Add an error message in the txn and send it when defined + - MEDIUM: http-rules: Support an optional error message in http deny rules + - REGTEST: Add a strict rewriting mode reg test + - REGEST: Add reg tests about error files + - MINOR: ssl: accept 'verify' bind option with 'set ssl cert' + - BUG/MINOR: ssl: ssl_sock_load_ocsp_response_from_file memory leak + - BUG/MINOR: ssl: ssl_sock_load_issuer_file_into_ckch memory leak + - BUG/MINOR: ssl: ssl_sock_load_sctl_from_file memory leak + - BUG/MINOR: http_htx: Fix some leaks on error path when error files are loaded + - CLEANUP: http-ana: Remove useless test on txn when the error message is retrieved + - BUILD: CI: introduce ARM64 builds + - BUILD: ssl: more elegant anti-replay feature presence check + - MINOR: proxy/http-ana: Add support of extra attributes for the cookie directive + - MEDIUM: dns: use Additional records from SRV responses + - CLEANUP: Consistently `unsigned int` for bitfields + - CLEANUP: pattern: remove the pat_time definition + - BUG/MINOR: http_act: don't check capture id in backend + - BUG/MINOR: ssl: fix build on development versions of openssl-1.1.x + +2019/11/25 : 2.2-dev0 + - exact copy of 2.1.0 + +2019/11/25 : 2.1.0 + - BUG/MINOR: init: fix set-dumpable when using uid/gid + - MINOR: init: avoid code duplication while setting identify + - BUG/MINOR: ssl: ssl_pkey_info_index ex_data can store a dereferenced pointer + - BUG/MINOR: ssl: fix crt-list neg filter for openssl < 1.1.1 + - MINOR: peers: Alway show the table info for disconnected peers. + - MINOR: peers: Add TX/RX heartbeat counters. + - MINOR: peers: Add debugging information to "show peers". + - BUG/MINOR: peers: Wrong null "server_name" data field handling. + - MINOR: ssl/cli: 'abort ssl cert' deletes an on-going transaction + - BUG/MEDIUM: mworker: don't fill the -sf argument with -1 during the reexec + - BUG/MINOR: peers: "peer alive" flag not reset when deconnecting. + - BUILD/MINOR: ssl: fix compiler warning about useless statement + - BUG/MEDIUM: stream-int: Don't loose events on the CS when an EOS is reported + - MINOR: contrib/prometheus-exporter: filter exported metrics by scope + - MINOR: contrib/prometheus-exporter: Add a param to ignore servers in maintenance + - BUILD: debug: Avoid warnings in dev mode with -02 because of some BUG_ON tests + - BUG/MINOR: mux-h1: Fix tunnel mode detection on the response path + - BUG/MINOR: http-ana: Properly catch aborts during the payload forwarding + - DOC: Update http-buffer-request description to remove the part about chunks + - BUG/MINOR: stream-int: Fix si_cs_recv() return value + - DOC: internal: document the init calls + - MEDIUM: dns: Add resolve-opts "ignore-weight" + - MINOR: ssl: ssl_sock_prepare_ctx() return an error code + - MEDIUM: ssl/cli: apply SSL configuration on SSL_CTX during commit + - MINOR: ssl/cli: display warning during 'commit ssl cert' + - MINOR: version: report the version status in "haproxy -v" + - MINOR: version: emit the link to the known bugs in output of "haproxy -v" + - DOC: Add documentation about the use-service action + - MINOR: ssl: fix possible null dereference in error handling + - BUG/MINOR: ssl: fix curve setup with LibreSSL + - BUG/MINOR: ssl: Stop passing dynamic strings as format arguments + - CLEANUP: ssl: check if a transaction exists once before setting it + - BUG/MINOR: cli: fix out of bounds in -S parser + - MINOR: ist: add ist_find_ctl() + - BUG/MAJOR: h2: reject header values containing invalid chars + - BUG/MAJOR: h2: make header field name filtering stronger + - BUG/MAJOR: mux-h2: don't try to decode a response HEADERS frame in idle state + - MINOR: h2: add a function to report H2 error codes as strings + - MINOR: mux-h2/trace: report the connection and/or stream error code + - SCRIPTS: create-release: show the correct origin name in suggested commands + - SCRIPTS: git-show-backports: add "-s" to proposed cherry-pick commands + - BUG/MEDIUM: trace: fix a typo causing an incorrect startup error + - BUILD: reorder the objects in the makefile + - DOC: mention in INSTALL haproxy 2.1 is a stable stable version + - MINOR: version: indicate that this version is stable + +2019/11/15 : 2.1-dev5 + - BUG/MEDIUM: ssl/cli: don't alloc path when cert not found + - BUG/MINOR: ssl/cli: unable to update a certificate without bundle extension + - BUG/MINOR: ssl/cli: fix an error when a file is not found + - MINOR: ssl/cli: replace the default_ctx during 'commit ssl cert' + - DOC: fix date and http_date keywords syntax + - MINOR: peers: Add "log" directive to "peers" section. + - BUG/MEDIUM: mux-h1: Disable splicing for chunked messages + - BUG/MEDIUM: stream: Be sure to support splicing at the mux level to enable it + - MINOR: flt_trace: Rename macros to print trace messages + - MINOR: trace: Add a set of macros to trace events if HA is compiled with debug + - MEDIUM: stream/trace: Register a new trace source with its events + - MINOR: doc: http-reuse connection pool fix + - BUG/MEDIUM: stream: Be sure to release allocated captures for TCP streams + - MINOR: http-ana: Remove the unused function http_reset_txn() + - BUG/MINOR: action: do-resolve now use cached response + - BUG: dns: timeout resolve not applied for valid resolutions + - DOC: management: fix typo on "cache_lookups" stats output + - BUG/MINOR: stream: init variables when the list is empty + - BUG/MEDIUM: tasks: Make tasklet_remove_from_tasklet_list() no matter the tasklet. + - BUG/MINOR: queue/threads: make the queue unlinking atomic + - BUG/MEDIUM: Make sure we leave the session list in session_free(). + - CLEANUP: session: slightly simplify idle connection cleanup logic + - MINOR: memory: also poison the area on freeing + - CLEANUP: cli: use srv_shutdown_streams() instead of open-coding it + - CLEANUP: stats: use srv_shutdown_streams() instead of open-coding it + - BUG/MEDIUM: listeners: always pause a listener on out-of-resource condition + - BUILD: contrib/da: remove an "unused" warning + - BUG/MEDIUM: filters: Don't call TCP callbacks for HTX streams + - MEDIUM: filters: Adapt filters API to allow again TCP filtering on HTX streams + - MINOR: freq_ctr: Make the sliding window sums thread-safe + - MINOR: stream: Remove the lock on the proxy to update time stats + - MINOR: counters: Add fields to store the max observed for {q,c,d,t}_time + - MINOR: stats: Report max times in addition of the averages for sessions + - MINOR: contrib/prometheus-exporter: Report metrics about max times for sessions + - BUG/MINOR: contrib/prometheus-exporter: Rename some metrics + - MINOR: contrib/prometheus-exporter: report the number of idle conns per server + - DOC: Add missing stats fields in the management manual + - BUG/MINOR: mux-h1: Properly catch parsing errors on payload and trailers + - BUG/MINOR: mux-h1: Don't set CS_FL_EOS on a read0 when receiving data to pipe + - MINOR: mux-h1: Set EOI on the conn-stream when EOS is reported in TUNNEL state + - MINOR: sink: Set the default max length for a message to BUFSIZE + - MINOR: ring: make the parse function automatically set the handler/release + - BUG/MINOR: log: make "show startup-log" use a ring buffer instead + - MINOR: stick-table: allow sc-set-gpt0 to set value from an expression + +2019/11/03 : 2.1-dev4 + - BUG/MINOR: cli: don't call the kw->io_release if kw->parse failed + - BUG/MINOR: mux-h2: Don't pretend mux buffers aren't full anymore if nothing sent + - BUG/MAJOR: stream-int: Don't receive data from mux until SI_ST_EST is reached + - DOC: remove obsolete section about header manipulation + - BUG/MINOR: ssl/cli: cleanup on cli_parse_set_cert error + - MINOR: ssl/cli: rework the 'set ssl cert' IO handler + - BUILD: CI: comment out cygwin build, upgrade various ssl libraries + - DOC: Improve documentation of http-re(quest|sponse) replace-(header|value|uri) + - BUILD/MINOR: tools: shut up the format truncation warning in get_gmt_offset() + - BUG/MINOR: spoe: fix off-by-one length in UUID format string + - BUILD/MINOR: ssl: shut up a build warning about format truncation + - BUILD: do not disable -Wformat-truncation anymore + - MINOR: chunk: add chunk_istcat() to concatenate an ist after a chunk + - Revert "MINOR: istbuf: add b_fromist() to make a buffer from an ist" + - MINOR: mux: Add a new method to get informations about a mux. + - BUG/MEDIUM: stream_interface: Only use SI_ST_RDY when the mux is ready. + - BUG/MEDIUM: servers: Only set SF_SRV_REUSED if the connection if fully ready. + - MINOR: doc: fix busy-polling performance reference + - MINOR: config: allow no set-dumpable config option + - MINOR: init: always fail when setrlimit fails + - MINOR: ssl/cli: rework 'set ssl cert' as 'set/commit' + - CLEANUP: ssl/cli: remove leftovers of bundle/certs (it < 2) + - REGTEST: vtest can now enable mcli with its own flag + - BUG/MINOR: config: Update cookie domain warn to RFC6265 + - MINOR: sample: add us/ms support to date/http_date + - BUG/MINOR: ssl/cli: check trash allocation in cli_io_handler_commit_cert() + - BUG/MEDIUM: mux-h2: report no available stream on a connection having errors + - BUG/MEDIUM: mux-h2: immediately remove a failed connection from the idle list + - BUG/MEDIUM: mux-h2: immediately report connection errors on streams + - BUG/MINOR: stats: properly check the path and not the whole URI + - BUG/MINOR: ssl: segfault in cli_parse_set_cert with old openssl/boringssl + - BUG/MINOR: ssl: ckch->chain must be initialized + - BUG/MINOR: ssl: double free on error for ckch->{key,cert} + - MINOR: ssl: BoringSSL ocsp_response does not need issuer + - BUG/MEDIUM: ssl/cli: fix dot research in cli_parse_set_cert + - MINOR: backend: Add srv_name sample fetche + - DOC: Add GitHub issue config.yml + +2019/10/25 : 2.1-dev3 + - MINOR: mux-h2/trace: missing conn pointer in demux full message + - MINOR: mux-h2: add a per-connection list of blocked streams + - BUILD: ebtree: make eb_is_empty() and eb_is_dup() take a const + - BUG/MEDIUM: mux-h2: do not enforce timeout on long connections + - BUG/MEDIUM: tasks: Don't forget to decrement tasks_run_queue. + - BUG/MINOR: peers: crash on reload without local peer. + - BUG/MINOR: mux-h2/trace: Fix traces on h2c initialization + - MINOR: h1-htx: Update h1_copy_msg_data() to ease the traces in the mux-h1 + - MINOR: htx: Adapt htx_dump() to be used from traces + - MINOR: mux-h1/trace: register a new trace source with its events + - MINOR: proxy: Store http-send-name-header in lower case + - MINOR: http: Remove headers matching the name of http-send-name-header option + - BUG/MINOR: mux-h1: Adjust header case when the server name is add to a request + - BUG/MINOR: mux-h1: Adjust header case when chunked encoding is add to a message + - MINOR: mux-h1: Try to wakeup the stream on output buffer allocation + - MINOR: fcgi: Add function to get the string representation of a record type + - MINOR: mux-fcgi/trace: Register a new trace source with its events + - BUG/MEDIUM: cache: make sure not to cache requests with absolute-uri + - DOC: clarify some points around http-send-name-header's behavior + - MEDIUM: mux-h2: support emitting CONTINUATION frames after HEADERS + - BUG/MINOR: mux-h1/mux-fcgi/trace: Fix position of the 4th arg in some traces + - DOC: fix typo in Prometheus exporter doc + - MINOR: h2: clarify the rules for how to convert an H2 request to HTX + - MINOR: htx: Add 2 flags on the start-line to have more info about the uri + - MINOR: http: Add a function to get the authority into a URI + - MINOR: h1-htx: Set the flag HTX_SL_F_HAS_AUTHORITY during the request parsing + - MEDIUM: http-htx: Keep the Host header and the request start-line synchronized + - MINOR: h1-htx: Only use the path of a normalized URI to format a request line + - MEDIUM: h2: make the request parser rebuild a complete URI + - MINOR: h2: report in the HTX flags when the request has an authority + - MEDIUM: mux-h2: do not map Host to :authority on output + - MEDIUM: h2: use the normalized URI encoding for absolute form requests + - MINOR: stats: mention in the help message support for "json" and "typed" + - MINOR: stats: get rid of the ST_CONVDONE flag + - MINOR: stats: replace the ST_* uri_auth flags with STAT_* + - MINOR: stats: always merge the uri_auth flags into the appctx flags + - MINOR: stats: set the appctx flags when initializing the applet only + - MINOR: stats: get rid of the STAT_SHOWADMIN flag + - MINOR: stats: make stats_dump_fields_json() directly take flags + - MINOR: stats: uniformize the calling convention of the dump functions + - MINOR: stats: support the "desc" output format modifier for info and stat + - MINOR: stats: prepare to add a description with each stat/info field + - MINOR: stats: make "show stat" and "show info" + - MINOR: stats: fill all the descriptions for "show info" and "show stat" + - BUG/MEDIUM: applet: always check a fast running applet's activity before killing + - BUILD: stats: fix missing '=' sign in array declaration + - MINOR: lists: add new macro LIST_SPLICE_END_DETACHED + - MINOR: list: add new macro MT_LIST_BEHEAD + - MEDIUM: task: Split the tasklet list into two lists. + - MINOR: h2: Document traps to be avoided on multithread. + - MINOR: lists: Try to use local variables instead of macro arguments. + - MINOR: lists: Fix alignement of \ when relevant. + - MINOR: mux-h2: also support emitting CONTINUATION on trailers + - MINOR: ssl: crt-list do ckchn_lookup + - REORG: ssl: rename ckch_node to ckch_store + - REORG: ssl: move structures to ssl_sock.h + - MINOR: ssl: initialize the sni_keytypes_map as EB_ROOT + - MINOR: ssl: initialize explicitly the sni_ctx trees + - BUG/MINOR: ssl: abort on sni allocation failure + - BUG/MINOR: ssl: free the sni_keytype nodes + - BUG/MINOR: ssl: abort on sni_keytypes allocation failure + - MEDIUM: ssl: introduce the ckch instance structure + - MEDIUM: ssl: split ssl_sock_add_cert_sni() + - MINOR: ssl: ssl_sock_load_ckchn() can properly fail + - MINOR: ssl: ssl_sock_load_multi_ckchs() can properly fail + - MEDIUM: ssl: ssl_sock_load_ckchs() alloc a ckch_inst + - MINOR: ssl: ssl_sock_load_crt_file_into_ckch() is filling from a BIO + - MEDIUM: ssl/cli: 'set ssl cert' updates a certificate from the CLI + - MINOR: ssl: load the sctl in/from the ckch + - MINOR: ssl: load the ocsp in/from the ckch + - BUG/MEDIUM: ssl: NULL dereference in ssl_sock_load_cert_sni() + - BUG/MINOR: ssl: fix build without SSL + - BUG/MINOR: ssl: fix build without multi-cert bundles + - BUILD: ssl: wrong #ifdef for SSL engines code + - BUG/MINOR: ssl: fix OCSP build with BoringSSL + - BUG/MEDIUM: htx: Catch chunk_memcat() failures when HTX data are formatted to h1 + - BUG/MINOR: chunk: Fix tests on the chunk size in functions copying data + - BUG/MINOR: mux-h1: Mark the output buffer as full when the xfer is interrupted + - MINOR: mux-h1: Xfer as much payload data as possible during output processing + - CLEANUP: h1-htx: Move htx-to-h1 formatting functions from htx.c to h1_htx.c + - BUG/MINOR: mux-h1: Capture ignored parsing errors + - MINOR: h1: Reject requests with different occurrences of the header host + - MINOR: h1: Reject requests if the authority does not match the header host + - REGTESTS: Send valid URIs in peers reg-tests and fix HA config to avoid warnings + - REGTESTS: Adapt proxy_protocol_random_fail.vtc to match normalized URI too + - BUG/MINOR: WURFL: fix send_log() function arguments + - BUG/MINOR: ssl: fix error messages for OCSP loading + - BUG/MINOR: ssl: can't load ocsp files + - MINOR: version: make the version strings variables, not constants + - BUG/MINOR: http-htx: Properly set htx flags on error files to support keep-alive + - MINOR: htx: Add a flag on HTX to known when a response was generated by HAProxy + - MINOR: mux-h1: Force close mode for proxy responses with an unfinished request + - BUILD: travis-ci: limit build to branches "master" and "next" + - BUILD/MEDIUM: threads: rename thread_info struct to ha_thread_info + - BUILD/SMALL: threads: enable threads on osx + - BUILD/MEDIUM: threads: enable cpu_affinity on osx + - MINOR: istbuf: add b_fromist() to make a buffer from an ist + - BUG/MINOR: cache: also cache absolute URIs + - BUG/MINOR: mworker/ssl: close openssl FDs unconditionally + - BUG/MINOR: tcp: Don't alter counters returned by tcp info fetchers + - BUG/MEDIUM: lists: Handle 1-element-lists in MT_LIST_BEHEAD(). + - BUG/MEDIUM: mux_pt: Make sure we don't have a conn_stream before freeing. + - BUG/MEDIUM: tasklet: properly compute the sleeping threads mask in tasklet_wakeup() + - BUG/MAJOR: idle conns: schedule the cleanup task on the correct threads + - BUG/MEDIUM: task: make tasklets either local or shared but not both at once + - Revert e8826ded5fea3593d89da2be5c2d81c522070995. + - BUG/MEDIUM: mux_pt: Don't destroy the connection if we have a stream attached. + - BUG/MEDIUM: mux_pt: Only call the wake emthod if nobody subscribed to receive. + - REGTEST: mcli/mcli_show_info: launch a 'show info' on the master CLI + - CLEANUP: ssl: make ssl_sock_load_cert*() return real error codes + - CLEANUP: ssl: make ssl_sock_load_ckchs() return a set of ERR_* + - CLEANUP: ssl: make cli_parse_set_cert handle errcode and warnings. + - CLEANUP: ssl: make ckch_inst_new_load_(multi_)store handle errcode/warn + - CLEANUP: ssl: make ssl_sock_put_ckch_into_ctx handle errcode/warn + - CLEANUP: ssl: make ssl_sock_load_dh_params handle errcode/warn + - CLEANUP: bind: handle warning label on bind keywords parsing. + - BUG/MEDIUM: ssl: 'tune.ssl.default-dh-param' value ignored with openssl > 1.1.1 + - BUG/MINOR: mworker/cli: reload fail with inherited FD + - BUG/MINOR: ssl: Fix fd leak on error path when a TLS ticket keys file is parsed + - BUG/MINOR: stick-table: Never exceed (MAX_SESS_STKCTR-1) when fetching a stkctr + - BUG/MINOR: cache: alloc shctx after check config + - BUG/MINOR: sample: Make the `field` converter compatible with `-m found` + - BUG/MINOR: server: check return value of fopen() in apply_server_state() + - REGTESTS: make seamless-reload depend on 1.9 and above + - REGTESTS: server/cli_set_fqdn requires version 1.8 minimum + - BUG/MINOR: dns: allow srv record weight set to 0 + - BUG/MINOR: ssl: fix memcpy overlap without consequences. + - BUG/MINOR: stick-table: fix an incorrect 32 to 64 bit key conversion + - BUG/MEDIUM: pattern: make the pattern LRU cache thread-local and lockless + - BUG/MINOR: mux-h2: do not emit logs on backend connections + - CLEANUP: ssl: remove old TODO commentary + - CLEANUP: ssl: fix SNI/CKCH lock labels + - MINOR: ssl: OCSP functions can load from file or buffer + - MINOR: ssl: load sctl from buf OR from a file + - MINOR: ssl: load issuer from file or from buffer + - MINOR: ssl: split ssl_sock_load_crt_file_into_ckch() + - BUG/MINOR: ssl/cli: fix looking up for a bundle + - MINOR: ssl/cli: update ocsp/issuer/sctl file from the CLI + - MINOR: ssl: update ssl_sock_free_cert_key_and_chain_contents + - MINOR: ssl: copy a ckch from src to dst + - MINOR: ssl: new functions duplicate and free a ckch_store + - MINOR: ssl/cli: assignate a new ckch_store + - MEDIUM: cli/ssl: handle the creation of SSL_CTX in an IO handler + - BUG/MINOR: ssl/cli: fix build of SCTL and OCSP + - BUG/MINOR: ssl/cli: out of bounds when built without ocsp/sctl + - BUG/MINOR: ssl: fix build with openssl < 1.1.0 + - BUG/MINOR: ssl: fix build of X509_chain_up_ref() w/ libreSSL + - MINOR: tcp: avoid confusion in time parsing init + - MINOR: debug: add a new "debug dev stream" command + - MINOR: cli/debug: validate addresses using may_access() in "debug dev stream" + - REORG: move CLI access level definitions to cli.h + - MINOR: cli: add an expert mode to hide dangerous commands + - MINOR: debug: make most debug CLI commands accessible in expert mode + - MINOR: stats/debug: maintain a counter of debug commands issued + - BUG/MEDIUM: debug: address a possible null pointer dereference in "debug dev stream" + +2019/10/01 : 2.1-dev2 + - DOC: management: document reuse and connect counters in the CSV format + - DOC: management: document cache_hits and cache_lookups in the CSV format + - BUG/MINOR: dns: remove irrelevant dependency on a client connection + - MINOR: applet: make appctx use their own pool + - BUG/MEDIUM: checks: Don't attempt to receive data if we already subscribed. + - BUG/MEDIUM: http/htx: unbreak option http_proxy + - BUG/MINOR: backend: do not try to install a mux when the connection failed + - MINOR: mux-h2: Don't adjust anymore the amount of data sent in h2_snd_buf() + - BUG/MINOR: http_fetch: Fix http_auth/http_auth_group when called from TCP rules + - BUG/MINOR: http_htx: Initialize HTX error messages for TCP proxies + - BUG/MINOR: cache/htx: Make maxage calculation HTX aware + - BUG/MINOR: hlua: Make the function txn:done() HTX aware + - MINOR: proto_htx: Directly call htx_check_response_for_cacheability() + - MINOR: proto_htx: Rely on the HTX function to apply a redirect rules + - MINOR: proto_htx: Add the function htx_return_srv_error() + - MINOR: backend/htx: Don't rewind output data to set the sni on a srv connection + - MINOR: proto_htx: Don't stop forwarding when there is a post-connect processing + - DOC: htx: Update comments in HTX files + - CLEANUP: htx: Remove the unsued function htx_add_blk_type_size() + - MINOR: htx: Deduce the number of used blocks from tail and head values + - MINOR: htx: Use an array of char to store HTX blocks + - MINOR: htx: Slightly update htx_dump() to report better messages + - DOC: htx: Add internal documentation about the HTX + - MAJOR: http: Deprecate and ignore the option "http-use-htx" + - MEDIUM: mux-h2: Remove support of the legacy HTTP mode + - CLEANUP: h2: Remove functions converting h2 requests to raw HTTP/1.1 ones + - MINOR: connection: Remove the multiplexer protocol PROTO_MODE_HTX + - MINOR: stream: Rely on HTX analyzers instead of legacy HTTP ones + - MEDIUM: http_fetch: Remove code relying on HTTP legacy mode + - MINOR: config: Remove tests on the option 'http-use-htx' + - MINOR: stream: Remove tests on the option 'http-use-htx' in stream_new() + - MINOR: proxy: Remove tests on the option 'http-use-htx' during H1 upgrade + - MINOR: hlua: Remove tests on the option 'http-use-htx' to reject TCP applets + - MINOR: cache: Remove tests on the option 'http-use-htx' + - MINOR: contrib/prometheus-exporter: Remove tests on the option 'http-use-htx' + - CLEANUP: proxy: Remove the flag PR_O2_USE_HTX + - MINOR: proxy: Don't adjust connection mode of HTTP proxies anymore + - MEDIUM: backend: Remove code relying on the HTTP legacy mode + - MEDIUM: hlua: Remove code relying on the legacy HTTP mode + - MINOR: http_act: Remove code relying on the legacy HTTP mode + - MEDIUM: cache: Remove code relying on the legacy HTTP mode + - MEDIUM: compression: Remove code relying on the legacy HTTP mode + - MINOR: flt_trace: Remove code relying on the legacy HTTP mode + - MINOR: stats: Remove code relying on the legacy HTTP mode + - MAJOR: filters: Remove code relying on the legacy HTTP mode + - MINOR: stream: Remove code relying on the legacy HTTP mode + - MAJOR: http: Remove the HTTP legacy code + - MINOR: hlua: Remove useless test on TX_CON_WANT_* flags + - MINOR: proto_http: Remove unused http txn flags + - MINOR: proto_http: Remove the unused flag HTTP_MSGF_WAIT_CONN + - CLEANUP: proto_http: Group remaining flags of the HTTP transaction + - CLEANUP: channel: Remove the unused flag CF_WAKE_CONNECT + - CLEANUP: proto_http: Remove unecessary includes and comments + - CLEANUP: proto_http: Move remaining code from proto_http.c to proto_htx.c + - REORG: proto_htx: Move HTX analyzers & co to http_ana.{c,h} files + - BUG/MINOR: debug: Remove flags CO_FL_SOCK_WR_ENA/CO_FL_SOCK_RD_ENA + - MINOR: proxy: Remove support of the option 'http-tunnel' + - DOC: config: Update as a result of the legacy HTTP removal + - MEDIUM: config: Remove parsing of req* and rsp* directives + - MINOR: proxy: Remove the unused list of block rules + - MINOR: proxy/http_ana: Remove unused req_exp/rsp_exp and req_add/rsp_add lists + - DOC: config: Remove unsupported req* and rsp* keywords + - MINOR: global: Preset tune.max_http_hdr to its default value + - MINOR: http: Don't store raw HTTP errors in chunks anymore + - BUG/MINOR: session: Emit an HTTP error if accept fails only for H1 connection + - BUG/MINOR: session: Send a default HTTP error if accept fails for a H1 socket + - CLEANUP: mux-h2: Remove unused flags H2_SF_CHNK_* + - BUG/MINOR: checks: do not exit tcp-checks from the middle of the loop + - MINOR: config: Warn only if the option http-use-htx is used with "no" prefix + - BUG/MEDIUM: mux-h1: Trim excess server data at the end of a transaction + - MINOR: connection: add conn_get_src() and conn_get_dst() + - MINOR: frontend: switch to conn_get_{src,dst}() for logging and debugging + - MINOR: backend: switch to conn_get_{src,dst}() for port and address mapping + - MINOR: ssl: switch to conn_get_dst() to retrieve the destination address + - MINOR: tcp: replace various calls to conn_get_{from,to}_addr with conn_get_{src,dst} + - MINOR: stream-int: use conn_get_{src,dst} in conn_si_send_proxy() + - MINOR: stream/cli: use conn_get_{src,dst} in "show sess" and "show peers" output + - MINOR: log: use conn_get_{dst,src}() to retrieve the cli/frt/bck/srv/ addresses + - MINOR: http/htx: use conn_get_dst() to retrieve the destination address + - MINOR: lua: use conn_get_{src,dst} to retrieve connection addresses + - MINOR: http: check the source address via conn_get_src() in sample fetch functions + - CLEANUP: connection: remove the now unused conn_get_{from,to}_addr() + - MINOR: connection: add new src and dst fields + - MINOR: connection: use conn->{src,dst} instead of &conn->addr.{from,to} + - MINOR: ssl-sock: use conn->dst instead of &conn->addr.to + - MINOR: lua: switch to conn->dst for a connection's target address + - MINOR: peers: use conn->dst for the peer's target address + - MINOR: htx: switch from conn->addr.{from,to} to conn->{src,dst} + - MINOR: stream: switch from conn->addr.{from,to} to conn->{src,dst} + - MINOR: proxy: switch to conn->src in error snapshots + - MINOR: session: use conn->src instead of conn->addr.from + - MINOR: tcp: replace conn->addr.{from,to} with conn->{src,dst} + - MINOR: unix: use conn->dst for the target address in ->connect() + - MINOR: sockpair: use conn->dst for the target address in ->connect() + - MINOR: log: use conn->{src,dst} instead of conn->addr.{from,to} + - MINOR: checks: replace conn->addr.to with conn->dst + - MINOR: frontend: switch from conn->addr.{from,to} to conn->{src,dst} + - MINOR: http: convert conn->addr.from to conn->src in sample fetches + - MEDIUM: backend: turn all conn->addr.{from,to} to conn->{src,dst} + - MINOR: connection: create a new pool for struct sockaddr_storage + - MEDIUM: connection: make sure all address producers allocate their address + - MAJOR: connection: remove the addr field + - MINOR: connection: don't use clear_addr() anymore, just release the address + - MINOR: stream: add a new target_addr entry in the stream structure + - MAJOR: stream: store the target address into s->target_addr + - MINOR: peers: now remove the remote connection setup code + - MEDIUM: lua: do not allocate the remote connection anymore + - MEDIUM: backend: always release any existing prior connection in connect_server() + - MEDIUM: backend: remove impossible cases from connect_server() + - BUG/MINOR: mux-h1: Close server connection if input data remains in h1_detach() + - BUG/MEDIUM: tcp-checks: do not dereference inexisting conn_stream + - BUG/MINOR: http_ana: Be sure to have an allocated buffer to generate an error + - BUG/MINOR: http_htx: Support empty errorfiles + - BUG/CRITICAL: http_ana: Fix parsing of malformed cookies which start by a delimiter + - BUG/MEDIUM: protocols: add a global lock for the init/deinit stuff + - BUG/MINOR: proxy: always lock stop_proxy() + - MEDIUM: mux-h1: Add the support of headers adjustment for bogus HTTP/1 apps + - BUILD: threads: add the definition of PROTO_LOCK + - BUG/MEDIUM: lb-chash: Fix the realloc() when the number of nodes is increased + - BUG/MEDIUM: streams: Don't switch the SI to SI_ST_DIS if we have data to send. + - BUG/MINOR: log: make sure writev() is not interrupted on a file output + - DOC: improve the wording in CONTRIBUTING about how to document a bug fix + - MEDIUM: h1: Don't try to subscribe if we managed to read data. + - MEDIUM: h1: Don't wake the H1 tasklet if we got the whole request. + - REGTESTS: checks: exclude freebsd target for tcp-check_multiple_ports.vtc + - BUG/MINOR: hlua/htx: Reset channels analyzers when txn:done() is called + - BUG/MEDIUM: hlua: Check the calling direction in lua functions of the HTTP class + - MINOR: hlua: Don't set request analyzers on response channel for lua actions + - MINOR: hlua: Add a flag on the lua txn to know in which context it can be used + - BUG/MINOR: hlua: Only execute functions of HTTP class if the txn is HTTP ready + - BUG/MINOR: htx: Fix free space addresses calculation during a block expansion + - MINOR: ssl: merge ssl_sock_load_cert_file() and ssl_sock_load_cert_chain_file() + - MEDIUM: ssl: use cert_key_and_chain struct in ssl_sock_load_cert_file() + - MEDIUM: ssl: split the loading of the certificates + - MEDIUM: ssl: lookup and store in a ckch_node tree + - MEDIUM: ssl: load DH param in struct cert_key_and_chain + - BUG/MAJOR: queue/threads: avoid an AB/BA locking issue in process_srv_queue() + - MINOR: ssl: use STACK_OF for chain certs + - MINOR: ssl: add extra chain compatibility + - MINOR: ssl: check private key consistency in loading + - MINOR: ssl: do not look at DHparam with OPENSSL_NO_DH + - CLEANUP: ssl: ssl_sock_load_crt_file_into_ckch + - MINOR: ssl: clean ret variable in ssl_sock_load_ckchn + - MAJOR: fd: Get rid of the fd cache. + - MEDIUM: pollers: Remember the state for read and write for each threads. + - MEDIUM: mux-h2: don't try to read more than needed + - BUG/BUILD: ssl: fix build with openssl < 1.0.2 + - BUG/MEDIUM: ssl: does not try to free a DH in a ckch + - BUG/MINOR: debug: fix a small race in the thread dumping code + - MINOR: wdt: also consider that waiting in the thread dumper is normal + - REGTESTS: checks: make 4be_1srv_health_checks more reliable + - BUILD: ssl: BoringSSL add EVP_PKEY_base_id + - BUG/MEDIUM: ssl: don't free the ckch in multi-cert bundle + - BUG/MINOR: ssl: fix ressource leaks on error + - BUG/MEDIUM: lb-chash: Ensure the tree integrity when server weight is increased + - BUG/MAJOR: http/sample: use a static buffer for raw -> htx conversion + - BUG/MINOR: stream-int: make sure to always release empty buffers after sending + - BUG/MEDIUM: ssl: open the right path for multi-cert bundle + - BUG/MINOR: stream-int: also update analysers timeouts on activity + - BUG/MEDIUM: mux-h2: unbreak receipt of large DATA frames + - BUG/MEDIUM: mux-h2: split the stream's and connection's window sizes + - BUG/MEDIUM: proxy: Make sure to destroy the stream on upgrade from TCP to H2 + - DOC: Add 'Question.md' issue template, discouraging asking questions + - BUG/MEDIUM: fd: Always reset the polled_mask bits in fd_dodelete(). + - BUG/MEDIUM: pollers: Clear the poll_send bits as well. + - BUILD: travis-ci: enable daily Coverity scan + - BUG/MINOR: mux-h2: don't refrain from sending an RST_STREAM after another one + - BUG/MINOR: mux-h2: use CANCEL, not STREAM_CLOSED in h2c_frt_handle_data() + - BUG/MINOR: mux-h2: do not send REFUSED_STREAM on aborted uploads + - BUG/MEDIUM: mux-h2: do not recheck a frame type after a state transition + - BUG/MINOR: mux-h2: always send stream window update before connection's + - BUG/MINOR: mux-h2: always reset rcvd_s when switching to a new frame + - BUG/MEDIUM: checks: make sure to close nicely when we're the last to speak + - BUG/MEDIUM: stick-table: Wrong stick-table backends parsing. + - CLEANUP: mux-h2: move the demuxed frame check code in its own function + - MINOR: cache: add method to cache hash + - MINOR: cache: allow caching of OPTIONS request + - BUG/MINOR: ssl: fix 0-RTT for BoringSSL + - MINOR: ssl: ssl_fc_has_early should work for BoringSSL + - BUG/MINOR: pools: don't mark the thread harmless if already isolated + - BUG/MINOR: buffers/threads: always clear a buffer's head before releasing it + - CLEANUP: buffer: replace b_drop() with b_free() + - CLEANUP: task: move the cpu_time field to the task-only part + - MINOR: cli: add two new states to print messages on the CLI + - MINOR: cli: add cli_msg(), cli_err(), cli_dynmsg(), cli_dynerr() + - CLEANUP: cli: replace all occurrences of manual handling of return messages + - BUG/MEDIUM: proxy: Don't forget the SF_HTX flag when upgrading TCP=>H1+HTX. + - BUG/MEDIUM: proxy: Don't use cs_destroy() when freeing the conn_stream. + - BUG/MINOR: lua: fix setting netfilter mark + - BUG/MINOR: Fix prometheus '# TYPE' and '# HELP' headers + - BUG/MEDIUM: lua: Fix test on the direction to set the channel exp timeout + - BUG/MINOR: stats: Wait the body before processing POST requests + - MINOR: fd: make sure to mark the thread as not stuck in fd_update_events() + - BUG/MEDIUM: mux_pt: Don't call unsubscribe if we did not subscribe. + - BUILD: travis-ci: trigger non-mainstream configurations only on daily builds. + - MINOR: debug: indicate the applet name when the task is task_run_applet() + - MINOR: tools: add append_prefixed_str() + - MINOR: lua: export applet and task handlers + - MEDIUM: debug: make the thread dump code show Lua backtraces + - BUG/MEDIUM: h1: Always try to receive more in h1_rcv_buf(). + - MINOR: list: add LIST_SPLICE() to merge one list into another + - MINOR: tools: add a DEFNULL() macro to use NULL for empty args + - REORG: trace: rename trace.c to calltrace.c and mention it's not thread-safe + - MINOR: sink: create definitions a minimal code for event sinks + - MINOR: sink: add a support for file descriptors + - MINOR: trace: start to create a new trace subsystem + - MINOR: trace: add allocation of buffer-sized trace buffers + - MINOR: trace/cli: register the "trace" CLI keyword to list the sources + - MINOR: trace/cli: parse the "level" argument to configure the trace verbosity + - MINOR: trace/cli: add "show trace" to report trace state and statistics + - MINOR: trace: implement a very basic trace() function + - MINOR: trace: add the file name and line number in the prefix + - MINOR: trace: make trace() now also take a level in argument + - MINOR: trace: implement a call to a decode function + - MINOR: trace: add per-level macros to produce traces + - MINOR: trace: add a definition of typed arguments to trace() + - MINOR: trace: make sure to always stop the locking when stopping or pausing + - MINOR: trace: add the possibility to lock on some arguments + - MINOR: trace: parse the "lock" argument to trace + - MINOR: trace: retrieve useful pointers and enforce lock-on + - DOC: management: document the "trace" and "show trace" commands + - BUILD: trace: make the lockon_ptr const to silence a warning without threads + - BUG/MEDIUM: mux-h1: do not truncate trailing 0CRLF on buffer boundary + - BUG/MEDIUM: mux-h1: do not report errors on transfers ending on buffer full + - DOC: fixed typo in management.txt + - BUG/MINOR: mworker: disable SIGPROF on re-exec + - BUG/MEDIUM: listener/threads: fix an AB/BA locking issue in delete_listener() + - BUG/MEDIUM: url32 does not take the path part into account in the returned hash. + - MINOR: backend: Add srv_queue converter + - MINOR: sink: set the fd-type sinks to non-blocking + - MINOR: tools: add a function varint_bytes() to report the size of a varint + - MINOR: buffer: add functions to read/write varints from/to buffers + - MINOR: fd: add fd_write_frag_line() to send a fragmented line to an fd + - MINOR: sink: now call the generic fd write function + - MINOR: ring: add a new mechanism for retrieving/storing ring data in buffers + - MINOR: ring: add a ring_write() function + - MINOR: ring: add a generic CLI io_handler to dump a ring buffer + - MINOR: sink: add support for ring buffers + - MINOR: sink: implement "show events" to show supported sinks and dump the rings + - MINOR: sink: now report the number of dropped events on output + - MINOR: trace: support a default callback for the source + - MINOR: trace: extend the source location to 13 chars + - MINOR: trace: show thread number and source name in the trace + - MINOR: trace: change the TRACE() calling convention to put the args and cb last + - MINOR: connection: add the fc_pp_authority fetch -- authority TLV, from PROXYv2 + - MINOR: tools: add a generic struct "name_desc" for name-description pairs + - MINOR: trace: replace struct trace_lockon_args with struct name_desc + - MINOR: trace: change the "payload" level to "data" and move it + - MINOR: trace: prepend the function name for developer level traces + - MINOR: trace: also report the trace level in the output + - MINOR: trace: change the detail_level to per-source verbosity + - MINOR: mux-h2/trace: register a new trace source with its events + - MINOR: mux-h2/trace: add the default decoding callback + - MEDIUM: mux-h2/trace: add lots of traces all over the code + - MINOR: mux-h2: add functions to convert an h2c/h2s state to a string + - MINOR: mux-h2/trace: add a new verbosity level "clean" + - MINOR: mux-h2/trace: only decode the start-line at verbosity other than "minimal" + - MINOR: mux-h2/trace: always report the h2c/h2s state and flags + - MINOR: mux-h2/trace: report h2s->id before h2c->dsi for the stream ID + - CLEANUP: mux-h2/trace: reformat the "received" messages for better alignment + - CLEANUP: mux-h2/trace: lower-case event names + - MINOR: trace: extend default event names to 12 chars + - BUG/MINOR: ring: fix the way watchers are counted + - MINOR: cli: extend the CLI context with a list and two offsets + - MINOR: mux-h2/trace: report the connection pointer and state before FRAME_H + - MEDIUM: ring: implement a wait mode for watchers + - BUG/MEDIUM: mux-h2/trace: do not dereference h2c->conn after failed idle + - BUG/MEDIUM: mux-h2/trace: fix missing braces added with traces + - BUG/MINOR: ring: b_peek_varint() returns a uint64_t, not a size_t + - CLEANUP: fd: remove leftovers of the fdcache + - MINOR: fd: add a new "initialized" bit in the fdtab struct + - MINOR: fd/log/sink: make the non-blocking initialization depend on the initialized bit + - MEDIUM: log: use the new generic fd_write_frag_line() function + - MINOR: log: add a target type instead of hacking the address family + - MEDIUM: log: add support for logging to a ring buffer + - MINOR: send-proxy-v2: sends authority TLV according to TLV received + - MINOR: build: add linux-glibc-legacy build TARGET + - BUG/MEDIUM: peers: local peer socket not bound. + - BUILD: connection: silence gcc warning with extra parentheses + - BUG/MINOR: http-ana: Reset response flags when 1xx messages are handled + - BUG/MINOR: h1: Properly reset h1m when parsing is restarted + - BUG/MINOR: mux-h1: Fix size evaluation of HTX messages after headers parsing + - BUG/MINOR: mux-h1: Don't stop anymore input processing when the max is reached + - BUG/MINOR: mux-h1: Be sure to update the count before adding EOM after trailers + - BUG/MEDIUM: cache: Properly copy headers splitted on several shctx blocks + - BUG/MEDIUM: cache: Don't cache objects if the size of headers is too big + - BUG/MINOR: mux-h1: Fix a possible null pointer dereference in h1_subscribe() + - MEDIUM: fd: remove the FD_EV_POLLED status bit + - MEDIUM: fd: simplify the fd_*_{recv,send} functions using BTS/BTR + - MINOR: fd: make updt_fd_polling() a normal function + - CONTRIB: debug: add new program "poll" to test poll() events + - BUG/MINOR: checks: stop polling for write when we have nothing left to send + - BUG/MINOR: checks: start sending the request right after connect() + - BUG/MINOR: checks: make __event_chk_srv_r() report success before closing + - BUG/MINOR: checks: do not uselessly poll for reads before the connection is up + - BUG/MINOR: mux-h1: Fix a UAF in cfg_h1_headers_case_adjust_postparser() + - BUILD: CI: add basic CentOS 6 cirrus build + - MINOR: contrib/prometheus-exporter: Report DRAIN/MAINT/NOLB status for servers + - BUG/MINOR: lb/leastconn: ignore the server weights for empty servers + - BUG/MAJOR: ssl: ssl_sock was not fully initialized. + - MEDIUM: fd: mark the FD as ready when it's inserted + - MINOR: fd: add two new calls fd_cond_{recv,send}() + - MEDIUM: connection: enable reading only once the connection is confirmed + - MINOR: fd: add two flags ERR and SHUT to describe FD states + - MEDIUM: fd: do not use the FD_POLL_* flags in the pollers anymore + - BUG/MEDIUM: connection: don't keep more idle connections than ever needed + - MINOR: stats: report the number of idle connections for each server + - BUILD: CI: skip reg-tests/connection/proxy_protocol_random_fail.vtc on CentOS 6 + - BUILD/MINOR: auth: enabling for osx + - BUG/MINOR: listener: Fix a possible null pointer dereference + - BUG/MINOR: ssl: always check for ssl connection before getting its XPRT context + - MINOR: stats: Add JSON export from the stats page + - BUG/MINOR: filters: Properly set the HTTP status code on analysis error + - MINOR: sample: Add UUID-fetch + - CLEANUP: mux-h2: Remove unused flag H2_SF_DATA_CHNK + - BUG/MINOR: acl: Fix memory leaks when an ACL expression is parsed + - BUG/MINOR: backend: Fix a possible null pointer dereference + - BUG/MINOR: Missing stat_field_names (since f21d17bb) + - BUG/MEDIUM: stick-table: Properly handle "show table" with a data type argument + - BUILD: CI: temporarily disable ASAN + - MINOR: htx: Add a flag on HTX message to report processing errors + - MINOR: mux-h1: Report a processing error during output processing + - MINOR: http-ana: Handle HTX errors first during message analysis + - MINOR: http-ana: Remove err_state field from http_msg + - MINOR: config: Support per-proxy and per-server deinit functions callbacks + - MINOR: config: Support per-proxy and per-server post-check functions callbacks + - MINOR: http_fetch: Add sample fetches to get auth method/user/pass + - MINOR: istbuf: Add the function b_isteqi() + - MINOR: log: Provide a function to emit a log for an application + - MINOR: http: Add function to parse value of the header Status + - MEDIUM: mux-h1/h1-htx: move HTX convertion of H1 messages in dedicated file + - MINOR: h1-htx: Use the same function to copy message payload in all cases + - MINOR: muxes/htx: Ignore pseudo header during message formatting + - MINOR: fcgi: Add code related to FCGI protocol + - MEDIUM: fcgi-app: Add FCGI application and filter + - MEDIUM: mux-fcgi: Add the FCGI multiplexer + - MINOR: doc: Add documentation about the FastCGI support + - BUG/MINOR: build: Fix compilation of mux_fcgi.c when compiled without SSL + - BUILD: CI: install golang-1.13 when building BoringSSL + - BUG/MINOR: mux-h2: Be sure to have a connection to unsubcribe + - BUG/MINOR: mux-fcgi: Be sure to have a connection to unsubcribe + - CLEANUP: fcgi-app: Remove useless test on fcgi_conf pointer + - BUG/MINOR: mux-fcgi: Don't compare the filter name in its parsing callback + - BUG/MAJOR: mux-h2: Handle HEADERS frames received after a RST_STREAM frame + - BUG/MEDIUM: check/threads: make external checks run exclusively on thread 1 + - MEDIUM: list: Separate "locked" list from regular list. + - MINOR: mt_lists: Add new macroes. + - MEDIUM: servers: Use LIST_DEL_INIT() instead of LIST_DEL(). + - MINOR: mt_lists: Do nothing in MT_LIST_ADD/MT_LIST_ADDQ if already in list. + - MINOR: mt_lists: Give MT_LIST_ADD, MT_LIST_ADDQ and MT_LIST_DEL a return value. + - MEDIUM: tasklets: Make the tasklet list a struct mt_list. + - TESTS: Add a stress-test for mt_lists. + - BUILD: travis-ci: add PCRE2, SLZ build + - BUG/MINOR: build: fix event ports (Solaris) + - BUG/MEDIUM: namespace: fix fd leak in master-worker mode + - OPTIM: listeners: use tasklets for the multi-queue rings + - BUILD: makefile: work around yet another GCC fantasy (-Wstring-plus-int) + - BUG/MINOR: stream-int: Process connection/CS errors first in si_cs_send() + - BUG/MEDIUM: stream-int: Process connection/CS errors during synchronous sends + - BUG/MEDIUM: checks: make sure the connection is ready before trying to recv + - CLEANUP: task: remove impossible test + - CLEANUP: task: cache the task_per_thread pointer + - MINOR: task: split the tasklet vs task code in process_runnable_tasks() + - MINOR: task: introduce a thread-local "sched" variable for local scheduler stuff + - CLEANUP: mux-fcgi: Remove the unused function fcgi_strm_id() + - BUG/MINOR: mux-fcgi: Use a literal string as format in app_log() + - BUG/MEDIUM: tasklets: Make sure we're waking the target thread if it sleeps. + - MINOR: h2/trace: indicate 'F' or 'B' to locate the side of an h2c in traces + - MINOR: h2/trace: report the frame type when known + - BUG/MINOR: mux-h2: do not wake up blocked streams before the mux is ready + - BUG/MEDIUM: namespace: close open namespaces during soft shutdown + - MINOR: time: add timeofday_as_iso_us() to return instant time as ISO + - MINOR: sink: finally implement support for SINK_FMT_{TIMED,ISO} + - MINOR: sink: change ring buffer "buf0"'s format to "timed" + - BUG/MEDIUM: mux-h2: don't reject valid frames on closed streams + - BUG/MINOR: mux-fcgi: silence a gcc warning about null dereference + - BUG/MINOR: mux-h2: Fix missing braces because of traces in h2_detach() + - BUG/MINOR: mux-h2: Use the dummy error when decoding headers for a closed stream + - BUG/MAJOR: mux_h2: Don't consume more payload than received for skipped frames + - BUG/MINOR: mux-h1: Do h2 upgrade only on the first request + - BUG/MEDIUM: spoe: Use a different engine-id per process + - MINOR: spoe: Improve generation of the engine-id + - MINOR: spoe: Support the async mode with several threads + - MINOR: http: Add server name header from HTTP multiplexers + - CLEANUP: http-ana: Remove the unused function http_send_name_header() + - MINOR: stats: Add the support of float fields in stats + - BUG/MINOR: contrib/prometheus-exporter: Return the time averages in seconds + - DOC: Fix documentation about the cli command to get resolver stats + - BUG/MEDIUM: fcgi: fix missing list tail in sample fetch registration + - BUG/MINOR: stats: Add a missing break in a switch statement + - BUG/MINOR: lua: Properly initialize the buffer's fields for string samples in hlua_lua2(smp|arg) + - CLEANUP: lua: Get rid of obsolete (size_t *) cast in hlua_lua2(smp|arg) + - BUG/MEDIUM: lua: Store stick tables into the sample's `t` field + - CLEANUP: proxy: Remove `proxy_tbl_by_name` + - BUILD: ssl: fix a warning when built with openssl < 1.0.2 + - DOC: replace utf-8 quotes by ascii ones + - BUG/MEDIUM: fd: HUP is an error only when write is active + - BUG/MINOR: action: do-resolve does not yield on requests with body + - Revert "MINOR: cache: allow caching of OPTIONS request" + +2019/07/16 : 2.1-dev1 + - BUG/MEDIUM: h2/htx: Update data length of the HTX when the cookie list is built + - DOC: this is a development branch again. + - MEDIUM: Make 'block' directive fatal + - MEDIUM: Make 'redispatch' directive fatal + - MEDIUM: Make '(cli|con|srv)timeout' directive fatal + - MEDIUM: Remove 'option independant-streams' + - MINOR: sample: Add sha2([]) converter + - MEDIUM: server: server-state global file stored in a tree + - BUG/MINOR: lua/htx: Make txn.req_req_* and txn.res_rep_* HTX aware + - BUG/MINOR: mux-h1: Add the header connection in lower case in outgoing messages + - BUG/MEDIUM: compression: Set Vary: Accept-Encoding for compressed responses + - MINOR: htx: Add the function htx_change_blk_value_len() + - BUG/MEDIUM: htx: Fully update HTX message when the block value is changed + - BUG/MEDIUM: mux-h2: Reset padlen when several frames are demux + - BUG/MEDIUM: mux-h2: Remove the padding length when a DATA frame size is checked + - BUG/MEDIUM: lb_fwlc: Don't test the server's lb_tree from outside the lock + - BUG/MAJOR: sample: Wrong stick-table name parsing in "if/unless" ACL condition. + - BUILD: mworker: silence two printf format warnings around getpid() + - BUILD: makefile: use :space: instead of digits to count commits + - BUILD: makefile: adjust the sed expression of "make help" for solaris + - BUILD: makefile: do not rely on shell substitutions to determine git version + - BUG/MINOR: mworker-prog: Fix segmentation fault during cfgparse + - BUG/MINOR: spoe: Fix memory leak if failing to allocate memory + - BUG/MEDIUM: mworker: don't call the thread and fdtab deinit + - BUG/MEDIUM: stream_interface: Don't add SI_FL_ERR the state is < SI_ST_CON. + - BUG/MEDIUM: connections: Always add the xprt handshake if needed. + - BUG/MEDIUM: ssl: Don't do anything in ssl_subscribe if we have no ctx. + - BUG/MEDIUM: mworker/cli: command pipelining doesn't work anymore + - BUG/MINOR: htx: Save hdrs_bytes when the HTX start-line is replaced + - BUG/MAJOR: mux-h1: Don't crush trash chunk area when outgoing message is formatted + - BUG/MINOR: memory: Set objects size for pools in the per-thread cache + - BUG/MINOR: log: Detect missing sampling ranges in config + - BUG/MEDIUM: proto_htx: Don't add EOM on 1xx informational messages + - BUG/MEDIUM: mux-h1: Use buf_room_for_htx_data() to detect too large messages + - BUG/MINOR: mux-h1: Make format errors during output formatting fatal + - BUG/MEDIUM: ssl: Don't attempt to set alpn if we're not using SSL. + - BUG/MEDIUM: mux-h1: Always release H1C if a shutdown for writes was reported + - BUG/MINOR: mworker/cli: don't output a \n before the response + - BUG/MEDIUM: checks: unblock signals in external checks + - BUG/MINOR: mux-h1: Skip trailers for non-chunked outgoing messages + - BUG/MINOR: mux-h1: Don't return the empty chunk on HEAD responses + - BUG/MEDIUM: connections: Always call shutdown, with no linger. + - BUG/MEDIUM: checks: Make sure the tasklet won't run if the connection is closed. + - BUG/MINOR: contrib/prometheus-exporter: Don't use channel_htx_recv_max() + - BUG/MINOR: hlua: Don't use channel_htx_recv_max() + - BUG/MEDIUM: channel/htx: Use the total HTX size in channel_htx_recv_limit() + - BUG/MINOR: hlua/htx: Respect the reserve when HTX data are sent + - BUG/MINOR: contrib/prometheus-exporter: Respect the reserve when data are sent + - BUG/MEDIUM: connections: Make sure we're unsubscribe before upgrading the mux. + - BUG/MEDIUM: servers: Authorize tfo in default-server. + - BUG/MEDIUM: sessions: Don't keep an extra idle connection in sessions. + - MINOR: server: Add "no-tfo" option. + - BUG/MINOR: contrib/prometheus-exporter: Don't try to add empty data blocks + - MINOR: action: Add the return code ACT_RET_DONE for actions + - BUG/MEDIUM: http/applet: Finish request processing when a service is registered + - BUG/MEDIUM: lb_fas: Don't test the server's lb_tree from outside the lock + - BUG/MEDIUM: mux-h1: Handle TUNNEL state when outgoing messages are formatted + - BUG/MINOR: mux-h1: Don't process input or ouput if an error occurred + - MINOR: stream-int: Factorize processing done after sending data in si_cs_send() + - BUG/MEDIUM: stream-int: Don't rely on CF_WRITE_PARTIAL to unblock opposite si + - DOC: contrib: spoa_server Add some hints for building spoa_server + - DOC: Fix typo in intro.txt + - BUG/MEDIUM: servers: Don't forget to set srv_cs to NULL if we can't reuse it. + - BUG/MINOR: ssl: revert empty handshake detection in OpenSSL <= 1.0.2 + - MINOR: pools: release the pool's lock during the malloc/free calls + - MINOR: pools: always pre-initialize allocated memory outside of the lock + - MINOR: pools: make the thread harmless during the mmap/munmap syscalls + - BUG/MEDIUM: fd/threads: fix excessive CPU usage on multi-thread accept + - BUG/MINOR: server: Be really able to keep "pool-max-conn" idle connections + - BUG/MEDIUM: checks: Don't attempt to read if we destroyed the connection. + - BUG/MEDIUM: da: cast the chunk to string. + - DOC: Fix typos and grammer in configuration.txt + - CLEANUP: proto_tcp: Remove useless header inclusions. + - BUG/MEDIUM: servers: Fix a race condition with idle connections. + - MINOR: task: introduce work lists + - BUG/MAJOR: listener: fix thread safety in resume_listener() + - BUG/MEDIUM: mux-h1: Don't release h1 connection if there is still data to send + - BUG/MINOR: mux-h1: Correctly report Ti timer when HTX and keepalives are used + - BUG/MEDIUM: streams: Don't give up if we couldn't send the request. + - BUG/MEDIUM: streams: Don't redispatch with L7 retries if redispatch isn't set. + - BUG/MINOR: mux-pt: do not pretend there's more data after a read0 + - BUG/MEDIUM: tcp-check: unbreak multiple connect rules again + - MEDIUM: mworker-prog: Add user/group options to program section + - REGTESTS: checks: tcp-check connect to multiple ports + - BUG/MEDIUM: threads: cpu-map designating a single thread/process are ignored + +2019/06/16 : 2.1-dev0 + - exact copy of 2.0.0 + +2019/06/16 : 2.0.0 + - MINOR: fd: Don't use atomic operations when it's not needed. + - DOC: mworker-prog: documentation for the program section + - MINOR: http: add a new "http-request replace-uri" action + - BUG/MINOR: 51d/htx: The _51d_fetch method, and the methods it calls are now HTX aware. + - MINOR: 51d: Added dummy libraries for the 51Degrees module for testing. + - MINOR: mworker: change formatting in uptime field of "show proc" + - MINOR: mworker: add the HAProxy version in "show proc" + - MINOR: doc: Remove -Ds option in man page + - MINOR: doc: add master-worker in the man page + - MINOR: doc: mention HAPROXY_LOCALPEER in the man + - BUILD: Silence gcc warning about unused return value + - CLEANUP: 51d: move the 51d dummy lib to contrib/51d/src to match the real lib + - BUILD: travis-ci: add 51Degree device detection, update openssl to 1.1.1c + - MINOR: doc: update the manpage and usage message about -S + - BUILD/MINOR: 51d: Updated build registration output to indicate thatif the library is a dummy one or not. + - BUG/MEDIUM: h1: Don't wait for handshake if we had an error. + - BUG/MEDIUM: h1: Wait for the connection if the handshake didn't complete. + - BUG/MINOR: task: prevent schedulable tasks from starving under high I/O activity + - BUG/MINOR: fl_trace/htx: Be sure to always forward trailers and EOM + - BUG/MINOR: channel/htx: Call channel_htx_full() from channel_full() + - BUG/MINOR: http: Use the global value to limit the number of parsed headers + - BUG/MINOR: htx: Detect when tail_addr meet end_addr to maximize free rooms + - BUG/MEDIUM: htx: Don't change position of the first block during HTX analysis + - CLEANUP: channel: Remove channel_htx_fwd_payload() and channel_htx_fwd_all() + - BUG/MEDIUM: proto_htx: Introduce the state ENDING during forwarding + - MINOR: htx: Add 3 flags on the start-line to deal with the request schemes + - MINOR: h2: Set flags about the request's scheme on the start-line + - MINOR: mux-h1: Set flags about the request's scheme on the start-line + - MINOR: mux-h2: Forward clients scheme to servers checking start-line flags + - MEDIUM: server: server-state only rely on server name + - CLEANUP: connection: rename the wait_event.task field to .tasklet + - CLEANUP: tasks: rename task_remove_from_tasklet_list() to tasklet_remove_* + - BUG/MEDIUM: connections: Don't call shutdown() if we want to disable linger. + - DOC: add some environment variables in section 2.3 + - BUILD: makefile: clarify the "help" output and list options + - BUG/MINOR: mux-h1: Wake busy mux for I/O when message is fully sent + - BUG: tasks: fix bug introduced by latest scheduler cleanup + - BUG/MEDIUM: mux-h2: fix early close with option abortonclose + - BUG/MEDIUM: connections: Don't use ALPN to pick mux when in mode TCP. + - BUG/MEDIUM: connections: Don't try to send early data if we have no mux. + - BUG/MEDIUM: mux-h2: properly account for the appended data in HTX + - BUILD: makefile: further clarify the "help" output and list targets + - BUILD: makefile: rename "linux2628" to "linux-glibc" and remove older targets + - BUILD: travis-ci: switch to linux-glibc instead of linux2628 + - DOC: update few references to the linux* targets and change them to linux-glibc + - BUILD: makefile: detect and reject recently removed linux targets + - BUILD: makefile: enable linux namespaces by default on linux + - BUILD: makefile: enable TFO on linux platforms + - BUILD: makefile: enable getaddrinfo on the linux-glibc target + - DOC: small updates to the CONTRIBUTING file + - BUG/MEDIUM: ssl: Make sure we initiate the handshake after using early data. + - CLEANUP: removed obsolete examples an move a few to better places + - DOC: Fix typos in CONTRIBUTING + - DOC: update the outdated ROADMAP file + - DOC: create a BRANCHES file to explain the life cycle + - DOC: mention in INSTALL haproxy 2.0 is a long-term supported stable version + - BUILD: travis-ci: TFO and GETADDRINFO are now enabled by default + - BUILD: makefile: make the obsolete target detection compatible with make-3.80 + - BUILD: tools: work around an internal compiler bug in gcc-3.4 + - BUILD: pattern: work around an internal compiler bug in gcc-3.4 + - BUILD: makefile: enable USE_RT on Solaris + - BUILD: makefile: do not use echo -n + - DOC: mention a few common build errors in the INSTALL file + +2019/06/11 : 2.0-dev7 + - BUG/MEDIUM: mux-h2: make sure the connection timeout is always set + - MINOR: tools: add new bitmap manipulation functions + - MINOR: logs: use the new bitmap functions instead of fd_sets for encoding maps + - MINOR: chunks: Make sure trash_size is only set once. + - Revert "MINOR: chunks: Make sure trash_size is only set once." + - MINOR: threads: serialize threads initialization + - MINOR peers: data structure simplifications for server names dictionary cache. + - DOC: peers: Update for dictionary cache entries for peers protocol. + - MINOR: dict: Store the length of the dictionary entries. + - MINOR: peers: A bit of optimization when encoding cached server names. + - MINOR: peers: Optimization for dictionary cache lookup. + - MEDIUM: tools: improve time format error detection + - BUG/MEDIUM: H1: When upgrading, make sure we don't free the buffer too early. + - BUG/MEDIUM: stream_interface: Make sure we call si_cs_process() if CS_FL_EOI. + - MINOR: threads: avoid clearing harmless twice in thread_release() + - MEDIUM: threads: add thread_sync_release() to synchronize steps + - BUG/MEDIUM: init/threads: prevent initialized threads from starting before others + - OPTIM/MINOR: init/threads: only call protocol_enable_all() on first thread + - BUG/MINOR: dict: race condition fix when inserting dictionary entries. + - MEDIUM: init/threads: don't use spinlocks during the init phase + - BUG/MINOR: cache/htx: Fix the counting of data already sent by the cache applet + - BUG/MEDIUM: compression/htx: Fix the adding of the last data block + - MINOR: flt_trace: Don't scrash the original offset during the random forwarding + - MAJOR: htx: Rework how free rooms are tracked in an HTX message + - MINOR: htx: Add the function htx_move_blk_before() + - Revert "BUG/MEDIUM: H1: When upgrading, make sure we don't free the buffer too early." + - BUG/MINOR: http-rules: mention "deny_status" for "deny" in the error message + - MINOR: http: turn default error files to HTTP/1.1 + - BUG/MEDIUM: h1: Don't try to subscribe if we had a connection error. + - BUG/MEDIUM: h1: Don't consider we're connected if the handshake isn't done. + - MINOR: contrib/spoa_server: Upgrade SPOP to 2.0 + - BUG/MEDIUM: contrib/spoa_server: Set FIN flag on agent frames + - MINOR: contrib/spoa_server: Add random IP score + - DOC/MINOR: contrib/spoa_server: Fix typo in README + +2019/06/07 : 2.0-dev6 + - BUG/MEDIUM: connection: fix multiple handshake polling issues + - MINOR: connection: also stop receiving after a SOCKS4 response + - MINOR: mux-h1: don't try to recv() before the connection is ready + - BUG/MEDIUM: mux-h1: only check input data for the current stream, not next one + - MEDIUM: mux-h1: don't use CS_FL_REOS anymore + - CLEANUP: connection: remove the now unused CS_FL_REOS flag + - CONTRIB: debug: add 4 missing connection/conn_stream flags + - MEDIUM: stream: make a full process_stream() loop when completing I/O on exit + - MINOR: server: increase the default pool-purge-delay to 5 seconds + - BUILD: tools: do not use the weak attribute for trace() on obsolete linkers + - BUG/MEDIUM: vars: make sure the scope is always valid when accessing vars + - BUG/MEDIUM: vars: make the tcp/http unset-var() action support conditions + - BUILD: task: fix a build warning when threads are disabled + - CLEANUP: peers: Remove tabs characters. + - CLEANUP: peers: Replace hard-coded values by macros. + - BUG/MINOR: peers: Wrong stick-table update message building. + - MINOR: dict: Add dictionary new data structure. + - MINOR: peers: Add a LRU cache implementation for dictionaries. + - MINOR: stick-table: Add "server_name" new data type. + - MINOR: cfgparse: Space allocation for "server_name" stick-table data type. + - MINOR: proxy: Add a "server by name" tree to proxy. + - MINOR: server: Add a dictionary for server names. + - MINOR: stream: Stickiness server lookup by name. + - MINOR: peers: Make peers protocol support new "server_name" data type. + - MINOR: stick-table: Make the CLI stick-table handler support dictionary entry data type. + - REGTEST: Add a basic server by name stickiness reg test. + - MINOR: peers: Add dictionary cache information to "show peers" CLI command. + - MINOR: peers: Replace hard-coded for peer protocol 64-bits value encoding by macros. + - MINOR: peers: Replace hard-coded values for peer protocol messaging by macros. + - CLEANUP: ssl: remove unneeded defined(OPENSSL_IS_BORINGSSL) + - BUILD: travis-ci improvements + - MINOR: SSL: add client/server random sample fetches + - BUG/MINOR: channel/htx: Don't alter channel during forward for empty HTX message + - BUG/MINOR: contrib/prometheus-exporter: Add HTX data block in one time + - BUG/MINOR: mux-h1: errflag must be set on H1S and not H1M during output processing + - MEDIUM: mux-h1: refactor output processing + - MINOR: mux-h1: Add the flag HAVE_O_CONN on h1s + - MINOR: mux-h1: Add h1_eval_htx_hdrs_size() to estimate size of the HTX headers + - MINOR: mux-h1: Don't count the EOM in the estimated size of headers + - MEDIUM: cache/htx: Always store info about HTX blocks in the cache + - MEDIUM: htx: Add the parsing of trailers of chunked messages + - MINOR: htx: Don't use end-of-data blocks anymore + - BUG/MINOR: mux-h1: Don't send more data than expected + - BUG/MINOR: flt_trace/htx: Only apply the random forwarding on the message body. + - BUG/MINOR: peers: Wrong "server_name" decoding. + - BUG/MEDIUM: servers: Don't attempt to destroy idle connections if disabled. + - MEDIUM: checks: Make sure we unsubscribe before calling cs_destroy(). + - MEDIUM: connections: Wake the upper layer even if sending/receiving is disabled. + - MEDIUM: ssl: Handle subscribe by itself. + - MINOR: ssl: Make ssl_sock_handshake() static. + - MINOR: connections: Add a new xprt method, remove_xprt. + - MINOR: connections: Add a new xprt method, add_xprt(). + - MEDIUM: connections: Introduce a handshake pseudo-XPRT. + - MEDIUM: connections: Remove CONN_FL_SOCK* + - BUG/MEDIUM: ssl: Don't forget to initialize ctx->send_recv and ctx->recv_wait. + - BUG/MINOR: peers: Wrong server name parsing. + - MINOR: server: really increase the pool-purge-delay default to 5 seconds + - BUG/MINOR: stream: don't emit a send-name-header in conn error or disconnect states + - MINOR: stream-int: use bit fields to match multiple stream-int states at once + - MEDIUM: stream-int: remove dangerous interval checks for stream-int states + - MEDIUM: stream-int: introduce a new state SI_ST_RDY + - MAJOR: stream-int: switch from SI_ST_CON to SI_ST_RDY on I/O + - MEDIUM: stream-int: make idle-conns switch to ST_RDY + - MEDIUM: stream: re-arrange the connection setup status reporting + - MINOR: stream-int: split si_update() into si_update_rx() and si_update_tx() + - MINOR: stream-int: make si_sync_send() from the send code of si_update_both() + - MEDIUM: stream: rearrange the events to remove the loop + - MEDIUM: stream: only loop on flags relevant to the analysers + - MEDIUM: stream: don't abusively loop back on changes on CF_SHUT*_NOW + - BUILD: stream-int: avoid a build warning in dev mode in si_state_bit() + - BUILD: peers: fix a build warning about an incorrect intiialization + - BUG/MINOR: time: make sure only one thread sets global_now at boot + - BUG/MEDIUM: tcp: Make sure we keep the polling consistent in tcp_probe_connect. + +2019/06/02 : 2.0-dev5 + - BUILD: watchdog: use si_value.sival_int, not si_int for the timer's value + - BUILD: signals: FreeBSD has SI_LWP instead of SI_TKILL + - BUILD: watchdog: condition it to USE_RT + - MINOR: raw_sock: report global traffic statistics + - MINOR: stats: report the global output bit rate in human readable form + - BUG/MINOR: proto-htx: Try to keep connections alive on redirect + - BUG/MEDIUM: spoe: Don't use the SPOE applet after releasing it + - BUG/MINOR: lua: Set right direction and flags on new HTTP objects + - BUG/MINOR: mux-h2: Count EOM in bytes sent when a HEADERS frame is formatted + - BUG/MINOR: mux-h1: Report EOI instead EOS on parsing error or H2 upgrade + - BUG/MEDIUM: proto-htx: Not forward too much data when 1xx reponses are handled + - BUG/MINOR: htx: Remove a forgotten while loop in htx_defrag() + - DOC: fix typos + - BUG/MINOR: ssl_sock: Fix memory leak when disabling compression + - OPTIM: freq-ctr: don't take the date lock for most updates + - MEDIUM: mux-h2: avoid doing expensive buffer realigns when not absolutely needed + - CLEANUP: debug: remove the TRACE() macro + - MINOR: buffer: introduce b_make() to make a buffer from its parameters + - MINOR: buffer: add a new buffer ring API to manipulate rings of buffers + - MEDIUM: mux-h2: replace all occurrences of mbuf with a buffer ring + - MEDIUM: mux-h2: make the conditions to send based on mbuf, not just its tail + - MINOR: mux-h2: introduce h2_release_mbuf() to release all buffers in the mbuf ring + - MEDIUM: mux-h2: make the send() function iterate over all mux buffers + - CLEANUP: mux-h2: consistently use a local variable for the mbuf + - MINOR: mux-h2: report the mbuf's head and tail in "show fd" + - MAJOR: mux-h2: switch to next mux buffer on buffer full condition. + - BUILD: connections: shut up gcc about impossible out-of-bounds warning + - BUILD: ssl: fix latest LibreSSL reg-test error + - MINOR: cli/activity: remove "fd_del" and "fd_skip" from show activity + - MINOR: cli/activity: add 3 general purpose counters in development mode + - BUG/MAJOR: lb/threads: make sure the avoided server is not full on second pass + - BUG/MEDIUM: queue: fix the tree walk in pendconn_redistribute. + - BUG/MEDIUM: threads: fix double-word CAS on non-optimized 32-bit platforms + - MEDIUM: config: now alert when two servers have the same name + - MINOR: htx: Remove the macro IS_HTX_SMP() and always use IS_HTX_STRM() instead + - MINOR: htx: Move the macro IS_HTX_STRM() in proto/stream.h + - MINOR: htx: Store the head position instead of the wrap one + - MINOR: htx: Store start-line block's position instead of address of its payload + - MINOR: htx: Add functions to get the first block of an HTX message + - MINOR: mux-h2/htx: Get the start-line from the head when HEADERS frame is built + - MINOR: htx: Replace the function http_find_stline() by http_get_stline() + - CLEANUP: htx: Remove unused function htx_get_stline() + - MINOR: http/htx: Use sl_pos directly to replace the start-line + - MEDIUM: http/htx: Perform analysis relatively to the first block + - MINOR: channel/htx: Call channel_htx_recv_max() from channel_recv_max() + - MINOR: htx: Add function htx_get_max_blksz() + - BUG/MINOR: htx: Change htx_xfer_blk() to also count metadata + - MEDIUM: mux-h1: Use the count value received from the SI in h1_rcv_buf() + - MINOR: mux-h2: Use the count value received from the SI in h2_rcv_buf() + - MINOR: stream-int: Don't use the flag CO_RFL_KEEP_RSV anymore in si_cs_recv() + - MINOR: connection: Remove the unused flag CO_RFL_KEEP_RSV + - MINOR: mux-h2/htx: Support zero-copy when possible in h2_rcv_buf() + - MINOR: htx: Add a field to set the memory used by headers in the HTX start-line + - MINOR: h2/htx: Set hdrs_bytes on the SL when an HTX message is produced + - MINOR: mux-h1: Set hdrs_bytes on the SL when an HTX message is produced + - MINOR: htx: Be sure to xfer all headers in one time in htx_xfer_blks() + - MEDIUM: htx: 1xx messages are now part of the final reponses + - MINOR: channel/htx: Add function to forward headers of an HTX message + - MINOR: filters/htx: Use channel_htx_fwd_headers() after headers filtering + - MINOR: proto-htx: Use channel_htx_fwd_headers() to forward 1xx responses + - MEDIUM: htx: Store the first block position instead of the start-line one + - MINOR: stats/htx: don't use the first block position but the head one + - MINOR: channel/htx: Add functions to forward a part or all HTX payload + - MINOR: proto-htx: Use channel_htx_fwd_all() when unfiltered body are forwarded + - MEDIUM: filters/htx: Filter body relatively to the first block + - MINOR: htx: Optimize htx_drain() when all data are drained + - MINOR: htx: don't rely on htx_find_blk() anymore in the function htx_truncate() + - MINOR: htx: remove the unused function htx_find_blk() + - MINOR: htx: Remove support of pseudo headers because it is unused + - BUG/MEDIUM: http: fix "http-request reject" when not final + - MINOR: ssl: Make sure the underlying xprt's init method doesn't fail. + - MINOR: ssl: Don't forget to call the close method of the underlying xprt. + - MINOR: htx: rename htx_append_blk_value() to htx_add_data_atonce() + - MINOR: htx: make htx_add_data() return the transmitted byte count + - MEDIUM: htx: make htx_add_data() never defragment the buffer + - MINOR: activity: write totals on the "show activity" output + - MINOR: activity: report totals and average separately + - MEDIUM: poller: separate the wait time from the wake events + - MINOR: activity: report the number of failed pool/buffer allocations + - MEDIUM: buffers: relax the buffer lock a little bit + - MINOR: task: turn the WQ lock to an RW_LOCK + - MEDIUM: task: don't grab the WR lock just to check the WQ + - BUG/MEDIUM: mux-h1: Don't skip the TCP splicing when there is no more data to read + - MEDIUM: sessions: Introduce session flags. + - BUG/MEDIUM: h2: Don't forget to set h2s->cs to NULL after having free'd cs. + - BUG/MEDIUM: mux-h2: fix the conditions to end the h2_send() loop + - BUG/MEDIUM: mux-h2: don't refrain from offering oneself a used buffer + - BUG/MEDIUM: connection: Use the session to get the origin address if needed. + - MEDIUM: tasks: Get rid of active_tasks_mask. + - MEDIUM: connection: Upstream SOCKS4 proxy support + - BUILD: contrib/prometheus: fix build breakage caused by move of idle_pct + - BUG/MINOR: deinit/threads: make hard-stop-after perform a clean exit + +2019/05/22 : 2.0-dev4 + - BUILD: enable freebsd builds on cirrus-ci + - BUG/MINOR: http_fetch: Rely on the smp direction for "cookie()" and "hdr()" + - MEDIUM: Make 'option forceclose' actually warn + - MEDIUM: Make 'resolution_pool_size' directive fatal + - DOC: management: place "show activity" at the right place + - MINOR: cli/activity: show the dumping thread ID starting at 1 + - MINOR: task: export global_task_mask + - MINOR: cli/debug: add a thread dump function + - BUG/MEDIUM: streams: Don't use CF_EOI to decide if the request is complete. + - BUG/MEDIUM: streams: Try to L7 retry before aborting the connection. + - BUG/MINOR: debug: make ha_task_dump() always check the task before dumping it + - BUG/MINOR: debug: make ha_task_dump() actually dump the requested task + - MINOR: debug: make ha_thread_dump() and ha_task_dump() take a buffer + - BUG/MINOR: debug: don't check the call date on tasklets + - MINOR: thread: implement ha_thread_relax() + - MINOR: task: put barriers after each write to curr_task + - MINOR: task: always reset curr_task when freeing a task or tasklet + - MINOR: stream: detach the stream from its own task on stream_free() + - MEDIUM: debug/threads: implement an advanced thread dump system + - REGTEST: extend the check duration on tls_health_checks and mark it slow + - DOC: fix "successful" typo + - MINOR: init: setenv HAPROXY_CFGFILES + - MINOR: threads/init: synchronize the threads startup + - MEDIUM: init/mworker: make the pipe register function a regular initcall + - CLEANUP: memory: make the fault injection code use the OTHER_LOCK label + - CLEANUP: threads: remove the now unused START_LOCK label + - MINOR: init/threads: make the global threads an array of structs + - MINOR: threads: add each thread's clockid into the global thread_info + - CLEANUP: stream: remove an obsolete debugging test + - MINOR: tools: add dump_hex() + - MINOR: debug: implement ha_panic() + - MINOR: debug/cli: add some debugging commands for developers + - MINOR: tools: provide a may_access() function and make dump_hex() use it + - MINOR: debug: make ha_panic() report threads starting at 1 + - REORG: compat: move some integer limit definitions from standard.h to compat.h + - REORG: threads: move the struct thread_info from global.h to hathreads.h + - MINOR: compat: make sure to always define clockid_t + - MINOR: threads: always place the clockid in the struct thread_info + - MINOR: threads: add a thread-local thread_info pointer "ti" + - MINOR: time: move the cpu, mono, and idle time to thread_info + - MINOR: time: add a function to retrieve another thread's cputime + - MINOR: debug: report each thread's cpu usage in "show thread" + - BUILD: threads: only assign the clock_id when supported + - BUILD: makefile: use USE_OBSOLETE_LINKER for solaris + - BUILD: makefile: remove -fomit-frame-pointer optimisation (solaris) + - MAJOR: polling: add event ports support (Solaris) + - BUG/MEDIUM: streams: Don't switch from SI_ST_CON to SI_ST_DIS on read0. + - CLEANUP: time: refine the test on _POSIX_TIMERS + - MINOR: compat: define a new empty type empty_t for non-implemented fields + - CLEANUP: time: switch clockid_t to empty_t when not available + - BUG/MINOR: mworker: Fix memory leak of mworker_proc members + - CLEANUP: objtype: make obj_type() and obj_type_name() take consts + - MINOR: debug: switch to SIGURG for thread dumps + - CLEANUP: threads: really move thread_info to hathreads.c + - MINOR: threads: make threads_{harmless|want_rdv}_mask constant 0 without threads + - CLEANUP: debug: always report harmless/want_rdv even without threads + - MINOR: threads: implement ha_tkill() and ha_tkillall() + - CLEANUP: debug: make use of ha_tkill() and remove ifdefs + - MINOR: stream: introduce a stream_dump() function and use it in stream_dump_and_crash() + - MINOR: debug: dump streams when an applet, iocb or stream is known + - MINOR: threads: add a "stuck" flag to the thread_info struct + - MINOR: threads: add a timer_t per thread in thread_info + - MAJOR: watchdog: implement a thread lockup detection mechanism + - MINOR: stream: remove the cpu time detection from process_stream() + - MINOR: connection: report the mux names in "haproxy -vv" + - CLEANUP: mux-h1: use "H1" and not "h1" as the mux's name + - BUG/MEDIUM: WURFL: segfault in wurfl-get() with missing info. + - MINOR: WURFL: call header_retireve_callback() in dummy library + - MINOR: WURFL: fixed Engine load failed error when wurfl-information-list contains wurfl_root_id + - MINOR: WURFL: shows log messages during module initialization + - MINOR: WURFL: removes heading wurfl-information-separator from wurfl-get-all() and wurfl-get() results + - MINOR: WURFL: wurfl_get() and wurfl_get_all() now return an empty string if device detection fails + - MEDIUM: WURFL: HTX awareness. + - MINOR: WURFL: module version bump to 2.0 + - MINOR: WURFL: do not emit warnings when not configured + - CONTRIB: wurfl: address 3 build issues in the wurfl dummy library + - BUG/MEDIUM: init/threads: provide per-thread alloc/free function callbacks + - BUILD: travis: add sanitizers to travis-ci builds + - BUILD: time: remove the test on _POSIX_C_SOURCE + - CLEANUP: build: rename some build macros to use the USE_* ones + - CLEANUP: raw_sock: remove support for very old linux splice bug workaround + - BUG/MEDIUM: dns: make the port numbers unsigned + - MEDIUM: config: deprecate the antique req* and rsp* commands + +2019/05/15 : 2.0-dev3 + - BUG/MINOR: peers: Really close the sessions with no heartbeat. + - CLEANUP: peers: remove useless annoying tabulations. + - CLEANUP: peers: replace timeout constants by macros. + - REGTEST: Enable again reg tests with HEAD HTTP method usage. + - DOC: The option httplog is no longer valid in a backend. + - DOC: peers: Peers protocol documentation update. + - REGTEST: remove unexpected "nbthread" statement from Lua test cases + - BUILD: Makefile: remove 11-years old workarounds for deprecated options + - BUILD: remove 10-years old error message for obsolete option USE_TCPSPLICE + - BUILD: Makefile: remove outdated support for dlmalloc + - BUILD: Makefile: consider a variable's origin and not its value for the options list + - BUILD: Makefile: also report disabled options in the BUILD_OPTIONS variable + - BUILD: Makefile: shorten default settings declaration + - BUILD: Makefile: clean up the target declarations + - BUILD: report the whole feature set with their status in haproxy -vv + - BUILD: pass all "USE_*" variables as -DUSE_* to the compiler + - REGTEST: script: make the script use the new features list + - REGTEST: script: remove platform-specific assigments of OPTIONS + - BUG/MINOR: peers: Missing initializations after peer session shutdown. + - BUG/MINOR: contrib/prometheus-exporter: Fix applet accordingly to recent changes + - BUILD/MINOR: listener: Silent a few signedness warnings. + - BUG/MINOR: mux-h1: Only skip invalid C-L headers on output + - BUG/MEDIUM: mworker: don't free the wrong child when not found + - BUG/MEDIUM: checks: Don't bother subscribing if we have a connection error. + - BUG/MAJOR: checks: segfault during tcpcheck_main + - BUILD: makefile: work around an old bug in GNU make-3.80 + - BUILD: makefile: work around another bug in make 3.80 + - BUILD: http: properly mark some struct as extern + - BUILD: chunk: properly declare pool_head_trash as extern + - BUILD: cache: avoid a build warning with some compilers/linkers + - MINOR: tools: make memvprintf() never pass a NULL target to vsnprintf() + - MINOR: tools: add an unsetenv() implementation + - BUILD: re-implement an initcall variant without using executable sections + - BUILD: use inttypes.h instead of stdint.h + - BUILD: connection: fix naming of ip_v field + - BUILD: makefile: fix build of IPv6 header on aix51 + - BUILD: makefile: add _LINUX_SOURCE_COMPAT to build on AIX-51 + - BUILD: define unsetenv on AIX 5.1 + - BUILD: Makefile: disable shared cache on AIX 5.1 + - MINOR: ssl: Add aes_gcm_dec converter + - REORG: mworker: move serializing functions to mworker.c + - REORG: mworker: move signals functions to mworker.c + - REORG: mworker: move IPC functions to mworker.c + - REORG: mworker: move signal handlers and related functions + - REORG: mworker: move mworker_cleanlisteners to mworker.c + - MINOR: mworker: calloc mworker_proc structures + - MINOR: mworker: don't use children variable anymore + - MINOR: cli: export cli_parse_default() definition in cli.h + - REORG: mworker/cli: move CLI functions to mworker.c + - MEDIUM: mworker-prog: implement program for master-worker + - MINOR: mworker/cli: show programs in 'show proc' + - BUG/MINOR: cli: correctly handle abns in 'show cli sockets' + - MINOR: cli: start addresses by a prefix in 'show cli sockets' + - MINOR: cli: export HAPROXY_CLI environment variable + - BUG/MINOR: htx: Preserve empty HTX messages with an unprocessed parsing error + - BUG/MINOR: proto_htx: Reset to_forward value when a message is set to DONE + - REGTEST: http-capture/h00000: Relax a regex matching the log message + - REGTEST: http-messaging/h00000: Fix the test when the HTX is enabled + - REGTEST: http-rules/h00003: Use a different client for requests expecting a 301 + - REGTEST: log/b00000: Be sure the client always hits its timeout + - REGTEST: lua/b00003: Relax the regex matching the log message + - REGTEST: lua/b00003: Specify the HAProxy pid when the command ss is executed + - BUG/MEDIUM: peers: fix a case where peer session is not cleanly reset on release. + - BUG/MEDIUM: h2: Don't attempt to recv from h2_process_demux if we subscribed. + - BUG/MEDIUM: htx: fix random premature abort of data transfers + - BUG/MEDIUM: streams: Don't remove the SI_FL_ERR flag in si_update_both(). + - BUG/MEDIUM: streams: Store prev_state before calling si_update_both(). + - BUG/MEDIUM: stream: Don't clear the stream_interface flags in si_update_both. + - MINOR: initcall: Don't forget to define the __start/stop_init_##stg symbols. + - MINOR: threads: Implement thread_cpus_enabled() for FreeBSD. + - BUG/MEDIUM: pattern: assign pattern IDs after checking the config validity + - MINOR: skip get_gmtime where tm is unused + - MINOR: ssl: Activate aes_gcm_dec converter for BoringSSL + - BUG/MEDIUM: streams: Only re-run process_stream if we're in a connected state. + - BUG/MEDIUM: stream_interface: Don't bother doing chk_rcv/snd if not connected. + - BUG/MEDIUM: task/threads: address a fairness issue between local and global tasks + - BUG/MINOR: tasks: make sure the first task to be queued keeps its nice value + - BUG/MINOR: listener: renice the accept ring processing task + - MINOR: cli/listener: report the number of accepts on "show activity" + - MINOR: cli/activity: report the accept queue sizes in "show activity" + - BUG/MEDIUM: spoe: Queue message only if no SPOE applet is attached to the stream + - BUG/MEDIUM: spoe: Return an error if nothing is encoded for fragmented messages + - BUG/MINOR: spoe: Be sure to set tv_request when each message fragment is encoded + - BUG/MEDIUM: htx: Defrag if blocks position is changed and the payloads wrap + - BUG/MEDIUM: htx: Don't crush blocks payload when append is done on a data block + - MEDIUM: htx: Deprecate the option 'http-tunnel' and ignore it in HTX + - MINOR: proto_htx: Don't adjust transaction mode anymore in HTX analyzers + - BUG/MEDIUM: htx: Fix the process of HTTP CONNECT with h2 connections + - MINOR: mux-h1: Simplify handling of 1xx responses + - MINOR: stats/htx: Don't add "Connection: close" header anymore in stats responses + - MEDIUM: h1: Add an option to sanitize connection headers during parsing + - MEDIUM: mux-h1: Simplify the connection mode management by sanitizing headers + - MINOR: mux-h1: Don't release the conn_stream anymore when h1s is destroyed + - BUG/MINOR: mux-h1: Handle the flag CS_FL_KILL_CONN during a shutdown read/write + - MINOR: mux-h2: Add a mux_ops dedicated to the HTX mode + - MINOR: muxes: Add a flag to specify a multiplexer uses the HTX + - MINOR: stream: Set a flag when the stream uses the HTX + - MINOR: http: update the macro IS_HTX_STRM() to check the stream flag SF_HTX + - MINOR: http_fetch/htx: Use stream flags instead of px mode in smp_prefetch_htx + - MINOR: filters/htx: Use stream flags instead of px mode to instanciate a filter + - MINOR: muxes: Rely on conn_is_back() during init to handle front/back conn + - MEDIUM: muxes: Add an optional input buffer during mux initialization + - MINOR: muxes: Pass the context of the mux to destroy() instead of the connection + - MEDIUM: muxes: Be prepared to don't own connection during the release + - MEDIUM: connection: Add conn_upgrade_mux_fe() to handle mux upgrades + - MEDIUM: htx: Allow the option http-use-htx to be used on TCP proxies too + - MAJOR: proxy/htx: Handle mux upgrades from TCP to HTTP in HTX mode + - MAJOR: muxes/htx: Handle inplicit upgrades from h1 to h2 + - MAJOR: htx: Enable the HTX mode by default for all proxies + - REGTEST: Use HTX by default and add '--no-htx' option to disable it + - BUG/MEDIUM: muxes: Don't dereference mux context if null in release functions + - CLEANUP: task: do not export rq_next anymore + - MEDIUM: tasks: improve fairness between the local and global queues + - MEDIUM: tasks: only base the nice offset on the run queue depth + - MINOR: tasks: restore the lower latency scheduling when niced tasks are present + - BUG/MEDIUM: map: Fix memory leak in the map converter + - BUG/MINOR: ssl: Fix 48 byte TLS ticket key rotation + - BUILD: task/thread: fix single-threaded build of task.c + - BUILD: cli/threads: fix build in single-threaded mode + - BUG/MEDIUM: muxes: Make sure we unsubcribed when destroying mux ctx. + - BUG/MEDIUM: h2: Make sure we're not already in the send_list in h2_subscribe(). + - BUG/MEDIUM: h2: Revamp the way send subscriptions works. + - MINOR: connections: Remove the SUB_CALL_UNSUBSCRIBE flag. + - BUG/MEDIUM: Threads: Only use the gcc >= 4.7 builtins when using gcc >= 4.7. + - BUILD: address a few cases of "static inline foo()" + - BUILD: do not specify "const" on functions returning structs or scalars + - BUILD: htx: fix a used uninitialized warning on is_cookie2 + - MINOR: peers: Add a new command to the CLI for peers. + - DOC: update for "show peers" CLI command. + - BUG/MAJOR: lb/threads: fix insufficient locking on round-robin LB + - MEDIUM: mworker: store the leaving state of a process + - MEDIUM: mworker-prog: implements 'option start-on-reload' + - CLEANUP: mworker: remove the type field in mworker_proc + - MEDIUM: mworker/cli: export the HAPROXY_MASTER_CLI variable + - MINOR: cli: don't add a semicolon at the end of HAPROXY_CLI + - MINOR: mworker: export HAPROXY_MWORKER=1 when running in mworker mode + - MINOR: init: add a "set-dumpable" global directive to enable core dumps + - BUG/MINOR: listener/mq: correctly scan all bound threads under low load + - BUG/MINOR: mworker: mworker_kill should apply on every children + - BUG/MINOR: mworker: don't exit with an ambiguous value + - BUG/MINOR: mworker: ensure that we still quits with SIGINT + - REGTESTS: exclude tests that require ssl, pcre if no such feature is enabled + - BUG/MINOR: mux-h1: Process input even if the input buffer is empty + - BUG/MINOR: mux-h1: Don't switch the parser in busy mode if other side has done + - BUG/MEDIUM: mux-h1: Notify the stream waiting for TCP splicing if ibuf is empty + - BUG/MEDIUM: mux-h1: Enable TCP splicing to exchange data only + - MINOR: mux-h1: Handle read0 during TCP splicing + - BUG/MEDIUM: htx: Don't return the start-line if the HTX message is empty + - BUG/MAJOR: http_fetch: Get the channel depending on the keyword used + - BUG/MINOR: http_fetch/htx: Allow permissive sample prefetch for the HTX + - BUG/MINOR: http_fetch/htx: Use HTX versions if the proxy enables the HTX mode + - BUG/MEDIUM: tasks: Make sure we set TASK_QUEUED before adding a task to the rq. + - BUG/MEDIUM: tasks: Make sure we modify global_tasks_mask with the rq_lock. + - MINOR: tasks: Don't consider we can wake task with tasklet_wakeup(). + - MEDIUM: tasks: No longer use rq.node.leaf_p as a lock. + - MINOR: tasks: Don't set the TASK_RUNNING flag when adding in the tasklet list. + - BUG/MEDIUM: applets: Don't use task_in_rq(). + - BUG/MAJOR: task: make sure never to delete a queued task + - MINOR: task/thread: factor out a wake-up condition + - CLEANUP: task: remain consistent when using the task's handler + - MEDIUM: tasks: Merge task_delete() and task_free() into task_destroy(). + - MEDIUM: tasks: Don't account a destroyed task as a runned task. + - BUG/MINOR: contrib/prometheus-exporter: Fix a typo in the run-queue metric type + - MINOR: contrib/prometheus-exporter: Remove usless rate metrics + - MINOR: contrib/prometheus-exporter: Rename some metrics to be more usable + - MINOR: contrib/prometheus-exporter: Follow best practices about metrics type + - BUG/MINOR: mworker: disable busy polling in the master process + - MEDIUM: tasks: Use __ha_barrier_store after modifying global_tasks_mask. + - MEDIUM: ssl: Give ssl_sock its own context. + - MEDIUM: connections: Move some fields from struct connection to ssl_sock_ctx. + - MEDIUM: ssl: provide its own subscribe/unsubscribe function. + - MEDIUM: connections: Provide a xprt_ctx for each xprt method. + - MEDIUM: ssl: provide our own BIO. + - BUILD/medium: ssl: Fix build with OpenSSL < 1.1.0 + - MINOR: peers: adds counters on show peers about tasks calls. + - MEDIUM: enable travis-ci builds + - MINOR: fd: Add a counter of used fds. + - MEDIUM: connections: Add a way to control the number of idling connections. + - BUG/MEDIUM: maps: only try to parse the default value when it's present + - BUG/MINOR: acl: properly detect pattern type SMP_T_ADDR + - REGTEST: Missing REQUIRE_VERSION declarations. + - MINOR: proto_tcp: tcp-request content: enable set-dst and set-dst-var + - BUG/MEDIUM: h1: Don't parse chunks CRLF if not enough data are available + - BUG/MEDIUM: thread/http: Add missing locks in set-map and add-acl HTTP rules + - BUG/MEDIUM: stream: Don't request a server connection if a shutw was scheduled + - BUG/MINOR: 51d: Get the request channel to call CHECK_HTTP_MESSAGE_FIRST() + - BUG/MINOR: da: Get the request channel to call CHECK_HTTP_MESSAGE_FIRST() + - MINOR: gcc: Fix a silly gcc warning in connect_server() + - MINOR: ssl/cli: async fd io-handlers printable on show fd + - Revert "CLEANUP: wurfl: remove dead, broken and unmaintained code" + - BUILD: add USE_WURFL to the list of known build options + - MINOR: wurfl: indicate in haproxy -vv the wurfl version in use + - BUILD: wurfl: build fix for 1.9/2.0 code base + - CLEANUP: wurfl: removed deprecated methods + - DOC: wurfl: added point of contact in MAINTAINERS file + - MINOR: wurfl: enabled multithreading mode + - MINOR: contrib: dummy wurfl library + - MINOR: dns: dns_requester structures are now in a memory pool + - MINOR: dns: move callback affection in dns_link_resolution() + - MINOR: obj_type: new object type for struct stream + - MINOR: action: new '(http-request|tcp-request content) do-resolve' action + - MINOR: log: Extract some code to send syslog messages. + - REGTEST: replace LEVEL option by a more human readable one. + - REGTEST: rename the reg test files. + - REGTEST: adapt some reg tests after renaming. + - REGTEST: make the "run-regtests" script search for tests in reg-tests by default + - BUG/MAJOR: stream: Missing DNS context initializations. + - BUG/MEDIUM: stream: Fix the way early aborts on the client side are handled + - BUG/MINOR: spoe: Don't systematically wakeup SPOE stream in the applet handler + - BUG/MEDIUM: ssl: Return -1 on recv/send if we got EAGAIN. + - BUG/MAJOR: lb/threads: fix AB/BA locking issue in round-robin LB + - BUG/MAJOR: muxes: Use the HTX mode to find the best mux for HTTP proxies only + - BUG/MINOR: htx: Exclude TCP proxies when the HTX mode is handled during startup + - CLEANUP: task: report calls as unsigned in show sess + - MINOR: tasks/activity: report the context switch and task wakeup rates + - MINOR: stream: measure and report a stream's call rate in "show sess" + - MINOR: applet: measure and report an appctx's call rate in "show sess" + - BUILD: extend Travis CI config to support more platforms + - REGTEST: exclude osx and generic targets for 40be_2srv_odd_health_checks + - REGTEST: relax the IPv6 address format checks in converters_ipmask_concat_strcmp_field_word + - REGTEST: exclude OSX and generic targets from abns_socket.vtc + - BUILD: travis: remove the "allow_failures" entry + - BUG/MINOR: activity: always initialize the profiling variable + - MINOR: activity: make the profiling status per thread and not global + - MINOR: activity: enable automatic profiling turn on/off + - CLEANUP: standard: use proper const to addr_to_str() and port_to_str() + - BUG/MINOR: proto_http: properly reset the stream's call rate on keep-alive + - MINOR: connection: make the debugging helper functions safer + - MINOR: stream/debug: make a stream dump and crash function + - MEDIUM: appctx/debug: force a crash if an appctx spins over itself forever + - MEDIUM: stream/debug: force a crash if a stream spins over itself forever + - MEDIUM: streams: measure processing time and abort when detecting bugs + - BUILD/MEDIUM: contrib: Dummy DeviceAtlas API. + - MEDIUM: da: HTX mode support. + - BUG/MEDIUM: mux-h2: properly deal with too large headers frames + - BUG/MINOR: http: Call stream_inc_be_http_req_ctr() only one time per request + - BUG/MEDIUM: spoe: arg len encoded in previous frag frame but len changed + - MINOR: spoe: Use the sample context to pass frag_ctx info during encoding + - DOC: contrib/modsecurity: Typos and fix the reject example + - BUG/MEDIUM: contrib/modsecurity: If host header is NULL, don't try to strdup it + - MINOR: log: Add "sample" new keyword to "log" lines. + - MINOR: log: Enable the log sampling and load-balancing feature. + - DOC: log: Document the sampling and load-balancing logging feature. + - REGTEST: Add a new reg test for log load-balancing feature. + - BUG/MAJOR: map/acl: real fix segfault during show map/acl on CLI + - REGTEST: Make this reg test be Linux specific. + - CLEANUP: task: move the task_per_thread definition to task.h + - MINOR: activity: report context switch counts instead of rates + - MINOR: threads: Implement HA_ATOMIC_LOAD(). + - BUG/MEDIUM: port_range: Make the ring buffer lock-free. + - BUG/MEDIUM: listener: Fix how unlimited number of consecutive accepts is handled + - MINOR: config: Test validity of tune.maxaccept during the config parsing + - CLEANUP: config: Don't alter listener->maxaccept when nbproc is set to 1 + - BUG/MEDIUM: servers: fix typo "src" instead of "srv" + - BUG/MEDIUM: ssl: Don't pretend we can retry a recv/send if we got a shutr/w. + - BUG/MINOR: haproxy: fix rule->file memory leak + - BUG/MINOR: log: properly free memory on logformat parse error and deinit() + - BUG/MINOR: checks: free memory allocated for tasklets + - BUG/MEDIUM: pattern: fix memory leak in regex pattern functions + - BUG/MEDIUM: channels: Don't forget to reset output in channel_erase(). + - BUG/MEDIUM: connections: Make sure we remove CO_FL_SESS_IDLE on disown. + - MINOR: threads: flatten the per-thread cpu-map + - MINOR: init/threads: remove the useless tids[] array + - MINOR: init/threads: make the threads array global + - BUG/MEDIUM: ssl: Use the early_data API the right way. + - BUG/MEDIUM: streams: Don't add CF_WRITE_ERROR if early data were rejected. + - MEDIUM: streams: Add the ability to retry a request on L7 failure. + - MEDIUM: streams: Add a way to replay failed 0rtt requests. + - MEDIUM: streams: Add a new keyword for retry-on, "junk-response" + - BUG/MINOR: stream: also increment the retry stats counter on L7 retries + - BUG/MEDIUM: checks: make sure the warmup task takes the server lock + - BUG/MINOR: logs/threads: properly split the log area upon startup + - BUILD: extend travis-ci matrix + - CLEANUP: Remove appsession documentation + - DOC: Fix typo in keyword matrix + - BUILD: remove "build_libressl" duplicate declaration + - BUILD: travis-ci: get back to osx without openssl support + - BUILD: enable several LibreSSL hacks, including + - BUILD: temporarily mark LibreSSL builds as allowed to fail + - BUILD: travis: TMPDIR replacement. + - BUG/MEDIUM: ssl: Don't attempt to use early data with libressl. + - MINOR: doc: Document allow-0rtt on the server line. + - MINOR: doc: Document the interaction of allow-0rtt and retry-on 0rtt-rejected. + - MEDIUM: proto: Change the prototype of the connect() method. + - MEDIUM: tcp: add the "tfo" option to support TCP fastopen on the server + - MINOR: config: Extract the code of "stick-table" line parsing. + - BUILD/MINOR: stick-table: Compilation fix. + - MEDIUM: stick-table: Stop handling stick-tables as proxies. + - MINOR: stick-tables: Add peers process binding computing. + - MINOR: stick-table: Add prefixes to stick-table names. + - MINOR: peers: Do not emit global stick-table names. + - DOC: Update for "table" lines in "peers" section. + - REGTEST: Add reg tests for "table" lines in "peers" sections. + - MEDIUM: regex: modify regex_comp() to atomically allocate/free the my_regex struct + - REGTEST: make the tls_health_checks test much faster + - REGTEST: make the "table in peers" test require v2.0 + - BUG/MINOR: mux-h2: rely on trailers output not input to turn them to empty data + - BUG/MEDIUM: h2/htx: always fail on too large trailers + - MEDIUM: mux-h2: discard contents that are to be sent after a shutdown + - BUG/MEDIUM: mux-h2/htx: never wait for EOM when processing trailers + - BUG/MEDIUM: h2/htx: never leave a trailers block alone with no EOM block + - REGTEST: Flag some slow reg tests. + - REGTEST: Reg tests file renaming. + - REGTEST: Wrong renaming for one reg test. + - REGTEST: Wrong assumption in IP:port logging test. + - BUG/MINOR: mworker/ssl: close OpenSSL FDs on reload + - MINOR: systemd: Use the variables from /etc/default/haproxy + - MINOR: systemd: Make use of master socket in systemd unit + - MINOR: systemd: support /etc/sysconfig/ for redhat based distrib + - BUG/MEDIUM: stick-table: fix regression caused by a change in proxy struct + - BUG/MEDIUM: tasks: fix possible segfault on task_destroy() + - CLEANUP: task: remove unneeded tests before task_destroy() + - MINOR: mworker: support a configurable maximum number of reloads + - BUG/MINOR: mux-h2: fix the condition to close a cs-less h2s on the backend + - BUG/MEDIUM: spoe: Be sure the sample is found before setting its context + - BUG/MINOR: mux-h1: Fix the parsing of trailers + - BUG/MINOR: htx: Never transfer more than expected in htx_xfer_blks() + - MINOR: htx: Split on DATA blocks only when blocks are moved to an HTX message + - MINOR: htx: Don't try to append a trailer block with the previous one + - MINOR: htx: Remove support for unused OOB HTX blocks + - BUILD: travis-ci bugfixes and improvements + - BUG/MEDIUM: servers: Don't use the same srv flag for cookie-set and TFO. + - BUG/MEDIUM: h2: Make sure we set send_list to NULL in h2_detach(). + - BUILD: ssl: fix again a libressl build failure after the openssl FD leak fix + - CLEANUP: ssl-sock: use HA_OPENSSL_VERSION_NUMBER instead of OPENSSL_VERSION_NUMBER + - BUILD: ssl: make libressl use its own version numbers + - CLEANUP: ssl: remove 57 occurrences of useless tests on LIBRESSL_VERSION_NUMBER + - MINOR: ssl: enable aes_gcm_dec on LibreSSL + - BUILD: ssl: fix libressl build again after aes-gcm-enc + - REORG: ssl: move openssl-compat from proto to common + - REORG: ssl: move some OpenSSL defines from ssl_sock to openssl-compat + - CLEANUP: ssl: never include openssl/*.h outside of openssl-compat.h anymore + - CLEANUP: ssl: make inclusion of openssl headers safe + - BUILD: add BoringSSL to travis-ci build matrix + - BUILD: threads: Add __ha_cas_dw fallback for single threaded builds + - BUG/MINOR: stream: Attach the read side on the response as soon as possible + - BUG/MEDIUM: http: Use pointer to the begining of input to parse message headers + - BUG/MEDIUM: h2: Don't check send_wait to know if we're in the send_list. + - BUG/MEDIUM: streams: Make sur SI_FL_L7_RETRY is set before attempting a retry. + - MEDIUM: streams: Add a new http action, disable-l7-retry. + - MINOR: streams: Introduce a new retry-on keyword, all-retryable-errors. + - BUG/MINOR: vars: Fix memory leak in vars_check_arg + - BUILD: travis-ci: make TMPDIR global variable in travis-ci + - CLEANUP: ssl: move the SSL_OP_* and SSL_MODE_* definitions to openssl-compat + - CLEANUP: ssl: remove ifdef around SSL_CTX_get_extra_chain_certs() + - CLEANUP: ssl: move all BIO_* definitions to openssl-compat + - BUILD: threads: fix again the __ha_cas_dw() definition + - BUG/MAJOR: mux-h2: do not add a stream twice to the send list + - Revert "BUG/MINOR: vars: Fix memory leak in vars_check_arg" + - BUG/MINOR: peers: Fix memory leak in cfg_parse_peers + - BUG/MINOR: htx: make sure to always initialize the HTTP method when parsing a buffer + - REGTEST: fix tls_health_checks random failures on MacOS in Travis-CI + - MINOR: spoe: Set the argument chunk size to 0 when SPOE variables are checked + - BUG/MINOR: vars: Fix memory leak in vars_check_arg + - BUG/MAJOR: ssl: segfault upon an heartbeat request + - MINOR: spoa-server: Clone the v1.7 spoa-example project + - MINOR: spoa-server: move some definition from spoa_server.c to spoa_server.h + - MINOR: spoa-server: Externalise debug functions + - MINOR: spoe-server: rename "worker" functions + - MINOR: spoa-server: Replace the thread init system by processes + - MINOR: spoa-server: With debug mode, start only one process + - MINOR: spoa-server: Allow registering external processes + - MINOR: spoa-server: Allow registering message processors + - MINOR: spoa-server: Load files + - MINOR: spoa-server: Prepare responses + - MINOR: spoa-server: Execute registered callbacks + - MINOR: spoa-server: Add Lua processing + - MINOR: spoa-server: Add python + - MINOR/DOC: spoe-server: Add documentation + - BUG/MEDIUM: connections: Don't forget to set xprt_ctx to NULL on close. + - MINOR: lists: add LIST_ADDED() to check if an element belongs to a list + - CLEANUP: mux-h2: use LIST_ADDED() instead of LIST_ISEMPTY() where relevant + - MINOR: mux-h2: add two H2S flags to report the need for shutr/shutw + - CLEANUP: mux-h2: simply use h2s->flags instead of ret in h2_deferred_shut() + - CLEANUP: connection: remove the handle field from the wait_event struct + - BUG/MINOR: log: Wrong log format initialization. + - BUG/MINOR: mux-h2: make the do_shut{r,w} functions more robust against retries + - BUG/MINOR: mworker: use after free when the PID not assigned + - MINOR: mux-h2: remove useless test on stream ID vs last in wake function + - MINOR: mux-h2: make h2_wake_some_streams() not depend on the CS flags + - MINOR: mux-h2: make h2s_wake_one_stream() the only function to deal with CS + - MINOR: mux-h2: make h2s_wake_one_stream() not depend on temporary CS flags + - BUG/MINOR: mux-h2: make sure to honor KILL_CONN in do_shut{r,w} + - CLEANUP: mux-h2: don't test for impossible CS_FL_REOS conditions + - MINOR: mux-h2: add macros to check multiple stream states at once + - MINOR: mux-h2: stop relying on CS_FL_REOS + - BUG/MEDIUM: mux-h2: Set EOI on the conn_stream during h2_rcv_buf() + - BUILD: debug: make gcc not complain on the ABORT_NOW() macro + - MINOR: debug: add a new BUG_ON macro + - MINOR: h2: Use BUG_ON() to enforce rules in subscribe/unsubscribe. + - MINOR: h1: Use BUG_ON() to enforce rules in subscribe/unsubscribe. + - MINOR: connections: Use BUG_ON() to enforce rules in subscribe/unsubscribe. + - BUILD: ist: turn the lower/upper case tables to literal on obsolete linkers + +2019/03/26 : 2.0-dev2 + - CLEANUP: http: Remove unreachable code in parse_http_req_capture + - CLEANUP: stream: Remove bogus loop in conn_si_send_proxy + - MINOR: lists: Implement locked variations. + - MEDIUM: servers: Used a locked list for idle_orphan_conns. + - MEDIUM: servers: Reorganize the way idle connections are cleaned. + - BUG/MEDIUM: lists: Properly handle the case we're removing the first elt. + - MINOR: cfgparse: Add a cast to make gcc happier. + - BUG/MEDIUM: standard: Wrong reallocation size. + - BUG/MINOR: listener: keep accept rate counters accurate under saturation + - DOC: fix alphabetic ordering for "tune.fail-alloc" setting + - MAJOR: config: disable support for nbproc and nbthread in parallel + - MEDIUM: listener: keep a single thread-mask and warn on "process" misuse + - MAJOR: listener: do not hold the listener lock in listener_accept() + - MINOR: listener: maintain a per-thread count of the number of connections on a listener + - MINOR: tools: implement functions to look up the nth bit set in a mask + - MINOR: listener: pre-compute some thread counts per bind_conf + - MINOR: listener: implement multi-queue accept for threads + - MAJOR: listener: use the multi-queue for multi-thread listeners + - MINOR: activity: add accept queue counters for pushed and overflows + - MINOR: config: add global tune.listener.multi-queue setting + - MAJOR: threads: enable one thread per CPU by default + - DOC: update management.txt to reflect that threads are used by default + - BUG/MINOR: config: don't over-count the global maxsock value + - BUG/MEDIUM: list: fix the rollback on addq in the locked liss + - BUG/MEDIUM: list: fix LIST_POP_LOCKED's removal of the last pointer + - BUG/MEDIUM: list: add missing store barriers when updating elements and head + - MINOR: list: make the delete and pop operations idempotent + - MINOR: server: remove a few unneeded LIST_INIT calls after LIST_DEL_LOCKED + - BUG/MEDIUM: listener: use a self-locked list for the dequeue lists + - BUG/MEDIUM: listener: make sure the listener never accepts too many conns + - BUG/MEDIUM: list: correct fix for LIST_POP_LOCKED's removal of last element + - MINOR: listener: introduce listener_backlog() to report the backlog value + - MINOR: listener: do not needlessly set l->maxconn + - MINOR: proxy: do not change the listeners' maxconn when updating the frontend's + - MEDIUM: config: don't enforce a low frontend maxconn value anymore + - MINOR: peers: Add a message for heartbeat. + - MINOR: global: keep a copy of the initial rlim_fd_cur and rlim_fd_max values + - BUG/MINOR: init: never lower rlim_fd_max + - BUG/MINOR: checks: make external-checks restore the original rlim_fd_cur/max + - BUG/MINOR: mworker: be careful to restore the original rlim_fd_cur/max on reload + - MINOR: init: make the maxpipe computation more accurate + - MINOR: init: move some maxsock updates earlier + - MEDIUM: init: make the global maxconn default to what rlim_fd_cur permits + - REGTEST: fix a spurious "nbthread 4" in the connection test + - DOC: update the text related to the global maxconn value + - BUG/MAJOR: mux-h2: fix race condition between close on both ends + - MINOR: sample: Replace "req.ungrpc" smp fetch by a "ungrpc" converter. + - BUG/MEDIUM: list: fix again LIST_ADDQ_LOCKED + - MINOR: htx: unconditionally handle parsing errors in requests or responses + - MINOR: mux-h2: always pass HTX_FL_PARSING_ERROR between h2s and buf on RX + - BUG/MEDIUM: h2/htx: verify that :path doesn't contain invalid chars + - MINOR: sample: Code factorization "ungrpc" converter. + - MINOR: sample: Rework gRPC converter code. + - CLEANUP: wurfl: remove dead, broken and unmaintained code + - MINOR: config: relax the range checks on cpu-map + - BUG/MINOR: ssl: fix warning about ssl-min/max-ver support + - MINOR: sample: Extract some protocol buffers specific code. + - DOC: Remove tabs and fixed punctuation. + - MINOR: sample: Add a protocol buffers specific converter. + - REGTEST: Peers reg tests. + - REGTEST: Enable reg tests with HEAD HTTP method usage. + - MINOR: lists: add a LIST_DEL_INIT() macro + - MINOR: task: use LIST_DEL_INIT() to remove a task from the queue + - MINOR: listener: improve incoming traffic distribution + - MINOR: tools: implement my_flsl() + - MEDIUM: listener: change the LB algorithm again to use two round robins instead + - CLEANUP: listener: remove old thread bit mapping + - MINOR: listener: move thr_idx from the bind_conf to the listener + - BUG/MEDIUM: logs: Only attempt to free startup_logs once. + - BUG/MAJOR: config: Wrong maxconn adjustment. + - BUG/MEDIUM: 51d: fix possible segfault on deinit_51degrees() + - OPTIM: task: limit the impact of memory barriers in taks_remove_from_task_list() + - MINOR: fd: Remove debugging code. + - BUG/MEDIUM: listeners: Don't call fd_stop_recv() if fd_updt is NULL. + - MINOR: threads: Implement __ha_barrier_atomic*. + - MEDIUM: threads: Use __ATOMIC_SEQ_CST when using the newer atomic API. + - MINOR: threads: Add macros to do atomic operation with no memory barrier. + - MEDIUM: various: Use __ha_barrier_atomic* when relevant. + - MEDIUM: applets: Use the new _HA_ATOMIC_* macros. + - MEDIUM: xref: Use the new _HA_ATOMIC_* macros. + - MEDIUM: fd: Use the new _HA_ATOMIC_* macros. + - MEDIUM: freq_ctr: Use the new _HA_ATOMIC_* macros. + - MEDIUM: proxy: Use the new _HA_ATOMIC_* macros. + - MEDIUM: server: Use the new _HA_ATOMIC_* macros. + - MEDIUM: task: Use the new _HA_ATOMIC_* macros. + - MEDIUM: activity: Use the new _HA_ATOMIC_* macros. + - MEDIUM: backend: Use the new _HA_ATOMIC_* macros. + - MEDIUM: cache: Use the new _HA_ATOMIC_* macros. + - MEDIUM: checks: Use the new _HA_ATOMIC_* macros. + - MEDIUM: pollers: Use the new _HA_ATOMIC_* macros. + - MEDIUM: compression: Use the new _HA_ATOMIC_* macros. + - MEDIUM: spoe: Use the new _HA_ATOMIC_* macros. + - MEDIUM: threads: Use the new _HA_ATOMIC_* macros. + - MEDIUM: http: Use the new _HA_ATOMIC_* macros. + - MEDIUM: lb/threads: Use the new _HA_ATOMIC_* macros. + - MEDIUM: listeners: Use the new _HA_ATOMIC_* macros. + - MEDIUM: logs: Use the new _HA_ATOMIC_* macros. + - MEDIUM: memory: Use the new _HA_ATOMIC_* macros. + - MEDIUM: peers: Use the new _HA_ATOMIC_* macros. + - MEDIUM: proto_tcp: Use the new _HA_ATOMIC_* macros. + - MEDIUM: queues: Use the new _HA_ATOMIC_* macros. + - MEDIUM: sessions: Use the new _HA_ATOMIC_* macros. + - MEDIUM: ssl: Use the new _HA_ATOMIC_* macros. + - MEDIUM: stream: Use the new _HA_ATOMIC_* macros. + - MEDIUM: tcp_rules: Use the new _HA_ATOMIC_* macros. + - MEDIUM: time: Use the new _HA_ATOMIC_* macros. + - MEDIUM: vars: Use the new _HA_ATOMIC_* macros. + - MINOR: config: remove obsolete use of DEFAULT_MAXCONN at various places + - MINOR: config: continue to rely on DEFAULT_MAXCONN to set the minimum maxconn + - BUG/MEDIUM: list: fix incorrect pointer unlocking in LIST_DEL_LOCKED() + - BUG/MEDIUM: listener: make sure we don't pick stopped threads + - MEDIUM: list: Remove useless barriers. + - MEDIUM: list: Use _HA_ATOMIC_* + - MEDIUM: connections: Use _HA_ATOMIC_* + - BUG/MAJOR: tasks: Use the TASK_GLOBAL flag to know if we're in the global rq. + - BUG/MEDIUM: threads/fd: do not forget to take into account epoll_fd/pipes + - BUG/MEDIUM: init/threads: consider epoll_fd/pipes for automatic maxconn calculation + - BUG/MEDIUM: tasks: Make sure we wake sleeping threads if needed. + - BUG/MINOR: mux-h1: Don't report an error on EOS if no message was received + - BUG/MINOR: stats/htx: Call channel_add_input() when response headers are sent + - BUG/MINOR: lua/htx: Use channel_add_input() when response data are added + - BUG/MINOR: lua/htx: Don't forget to call htx_to_buf() when appropriate + - MINOR: stats: Add the status code STAT_STATUS_IVAL to handle invalid requests + - MINOR: stats: Move stuff about the stats status codes in stats files + - BUG/MINOR: stats: Be more strict on what is a valid request to the stats applet + - Revert "REGTEST: Enable reg tests with HEAD HTTP method usage." + - BUILD: listener: shut up a build warning when threads are disabled + - BUILD: Makefile: allow the reg-tests target to be verbose + - BUILD: Makefile: resolve LEVEL before calling run-regtests + - BUG/MAJOR: spoe: Fix initialization of thread-dependent fields + - BUG/MAJOR: stats: Fix how huge POST data are read from the channel + - BUG/MINOR: http/counters: fix missing increment of fe->srv_aborts + - BUG/MEDIUM: mux-h2: Always wakeup streams with no id to avoid frozen streams + - MINOR: mux-h2: Set REFUSED_STREAM error to reset a stream if no data was never sent + - MINOR: muxes: Report the Last read with a dedicated flag + - MINOR: proto-http/proto-htx: Make error handling clearer during data forwarding + - BUILD: tools: fix a build warning on some 32-bit archs + - MINOR: init: report the list of optionally available services + - MEDIUM: proto_htx: Switch to infinite forwarding if there is no data filter + - BUG/MINOR: cache: Fully consume large requests in the cache applet + - BUG/MINOR: stats: Fully consume large requests in the stats applet + - BUG/MEDIUM: lua: Fully consume large requests when an HTTP applet ends + - MINOR: proto_http: Add function to handle the header "Expect: 100-continue" + - MINOR: proto_htx: Add function to handle the header "Expect: 100-continue" + - MINOR: stats/cache: Handle the header Expect when applets are registered + - MINOR: http/applets: Handle all applets intercepting HTTP requests the same way + - CLEANUP: cache: don't export http_cache_applet anymore + - MINOR: lua: Don't handle the header Expect in lua HTTP applets anymore + - BUG/MINOR: doc: Be accurate on the behavior on pool-purge-delay. + - Revert "MEDIUM: proto_htx: Switch to infinite forwarding if there is no data filter" + - BUG/MEDIUM: mux-h2: Make sure we destroyed the h2s once shutr/shutw is done. + - BUG/MEDIUM: mux-h2: Don't bother keeping the h2s if detaching and nothing to send. + - BUG/MEDIUM: mux-h2: Use the right list in h2_stop_senders(). + - MINOR: mux-h2: copy small data blocks more often and reduce the number of pauses + - CLEANUP: mux-h2: add some comments to help understand the code + - BUG/MEDIUM: ssl: ability to set TLS 1.3 ciphers using ssl-default-server-ciphersuites + - BUG/MINOR: log: properly format IPv6 address when LOG_OPT_HEXA modifier is used. + - BUG/MEDIUM: h2: Try to be fair when sending data. + - BUG/MINOR: proto-http: Don't forward request body anymore on error + - MINOR: mux-h2: Remove useless test on ES flag in h2_frt_transfer_data() + - MINOR: connection: and new flag to mark end of input (EOI) + - MINOR: channel: Report EOI on the input channel if it was reached in the mux + - MEDIUM: mux-h2: Don't mix the end of the message with the end of stream + - MINOR: mux-h1: Set CS_FL_EOI the end of the message is reached + - BUG/MEDIUM: http/htx: Fix handling of the option abortonclose + - CLEANUP: muxes/stream-int: Remove flags CS_FL_READ_NULL and SI_FL_READ_NULL + - MEDIUM: proto_htx: Reintroduce the infinite forwarding on data + - BUG/MEDIUM: h2: only destroy the h2s if h2s->cs is NULL. + - BUG/MEDIUM: h2: Use the new sending_list in h2s_notify_send(). + - BUG/MEDIUM: h2: Follow the same logic in h2_deferred_shut than in h2_snd_buf. + - BUG/MEDIUM: h2: Remove the tasklet from the task list if unsubscribing. + - BUG/MEDIUM: task/h2: add an idempotent task removal fucntion + - CLEANUP: task: only perform a LIST_DEL() when the list is not empty + - BUG/MEDIUM: mux-h2: make sure to always notify streams of EOS condition + - CONTRIB: debug: report the CS and CF's EOI flags + - MINOR: channel: don't unset CF_SHUTR_NOW after shutting down. + +2019/02/26 : 2.0-dev1 + - MINOR: mux-h2: only increase the connection window with the first update + - REGTESTS: remove the expected window updates from H2 handshakes + - BUG/MINOR: mux-h2: make empty HEADERS frame return a connection error + - BUG/MEDIUM: mux-h2: mark that we have too many CS once we have more than the max + - MEDIUM: mux-h2: remove padlen during headers phase + - MINOR: h2: add a bit-based frame type representation + - MINOR: mux-h2: remove useless check for empty frame length in h2s_decode_headers() + - MEDIUM: mux-h2: decode HEADERS frames before allocating the stream + - MINOR: mux-h2: make h2c_send_rst_stream() use the dummy stream's error code + - MINOR: mux-h2: add a new dummy stream for the REFUSED_STREAM error code + - MINOR: mux-h2: fail stream creation more cleanly using RST_STREAM + - MINOR: buffers: add a new b_move() function + - MINOR: mux-h2: make h2_peek_frame_hdr() support an offset + - MEDIUM: mux-h2: handle decoding of CONTINUATION frames + - CLEANUP: mux-h2: remove misleading comments about CONTINUATION + - BUG/MEDIUM: servers: Don't try to reuse connection if we switched server. + - BUG/MEDIUM: tasks: Decrement tasks_run_queue in tasklet_free(). + - BUG/MINOR: htx: send the proper authenticate header when using http-request auth + - BUG/MEDIUM: mux_h2: Don't add to the idle list if we're full. + - BUG/MEDIUM: servers: Fail if we fail to allocate a conn_stream. + - BUG/MAJOR: servers: Use the list api correctly to avoid crashes. + - BUG/MAJOR: servers: Correctly use LIST_ELEM(). + - BUG/MAJOR: sessions: Use an unlimited number of servers for the conn list. + - BUG/MEDIUM: servers: Flag the stream_interface on handshake error. + - MEDIUM: servers: Be smarter when switching connections. + - MEDIUM: sessions: Keep track of which connections are idle. + - MINOR: payload: add sample fetch for TLS ALPN + - BUG/MEDIUM: log: don't mark log FDs as non-blocking on terminals + - MINOR: channel: Add the function channel_add_input + - MINOR: stats/htx: Call channel_add_input instead of updating channel state by hand + - BUG/MEDIUM: cache: Be sure to end the forwarding when XFER length is unknown + - BUG/MAJOR: htx: Return the good block address after a defrag + - MINOR: lb: allow redispatch when using consistent hash + - CLEANUP: mux-h2: fix end-of-stream flag name when processing headers + - BUG/MEDIUM: mux-h2: always restart reading if data are available + - BUG/MINOR: mux-h2: set the stream-full flag when leaving h2c_decode_headers() + - BUG/MINOR: mux-h2: don't check the CS count in h2c_bck_handle_headers() + - BUG/MINOR: mux-h2: mark end-of-stream after processing response HEADERS, not before + - BUG/MINOR: mux-h2: only update rxbuf's length for H1 headers + - BUG/MEDIUM: mux-h1: use per-direction flags to indicate transitions + - BUG/MEDIUM: mux-h1: make HTX chunking consistent with H2 + - BUG/MAJOR: stream-int: Update the stream expiration date in stream_int_notify() + - BUG/MEDIUM: proto-htx: Set SI_FL_NOHALF on server side when request is done + - BUG/MEDIUM: mux-h1: Add a task to handle connection timeouts + - MINOR: mux-h2: make h2c_decode_headers() return a status, not a count + - MINOR: mux-h2: add a new dummy stream : h2_error_stream + - MEDIUM: mux-h2: make h2c_decode_headers() support recoverable errors + - BUG/MINOR: mux-h2: detect when the HTX EOM block cannot be added after headers + - MINOR: mux-h2: remove a misleading and impossible test + - CLEANUP: mux-h2: clean the stream error path on HEADERS frame processing + - MINOR: mux-h2: check for too many streams only for idle streams + - MINOR: mux-h2: set H2_SF_HEADERS_RCVD when a HEADERS frame was decoded + - BUG/MEDIUM: mux-h2: decode trailers in HEADERS frames + - MINOR: h2: add h2_make_h1_trailers to turn H2 headers to H1 trailers + - MEDIUM: mux-h2: pass trailers to H1 (legacy mode) + - MINOR: htx: add a new function to add a block without filling it + - MINOR: h2: add h2_make_htx_trailers to turn H2 headers to HTX trailers + - MEDIUM: mux-h2: pass trailers to HTX + - MINOR: mux-h1: parse the content-length header on output and set H1_MF_CLEN + - BUG/MEDIUM: mux-h1: don't enforce chunked encoding on requests + - MINOR: mux-h2: make HTX_BLK_EOM processing idempotent + - MINOR: h1: make the H1 headers block parser able to parse headers only + - MEDIUM: mux-h2: emit HEADERS frames when facing HTX trailers blocks + - MINOR: stream/htx: Add info about the HTX structs in "show sess all" command + - MINOR: stream: Add the subscription events of SIs in "show sess all" command + - MINOR: mux-h1: Add the subscription events in "show fd" command + - BUG/MEDIUM: h1: Get the h1m state when restarting the headers parsing + - BUG/MINOR: cache/htx: Be sure to count partial trailers + - BUG/MEDIUM: h1: In h1_init(), wake the tasklet instead of calling h1_recv(). + - BUG/MEDIUM: server: Defer the mux init until after xprt has been initialized. + - MINOR: connections: Remove a stall comment. + - BUG/MEDIUM: cli: make "show sess" really thread-safe + - BUILD: add a new file "version.c" to carry version updates + - MINOR: stream/htx: add the HTX flags output in "show sess all" + - MINOR: stream/cli: fix the location of the waiting flag in "show sess all" + - MINOR: stream/cli: report more info about the HTTP messages on "show sess all" + - BUG/MINOR: lua: bad args are returned for Lua actions + - BUG/MEDIUM: lua: dead lock when Lua tasks are trigerred + - MINOR: htx: Add an helper function to get the max space usable for a block + - MINOR: channel/htx: Add HTX version for some helper functions + - BUG/MEDIUM: cache/htx: Respect the reserve when cached objects are served + - BUG/MINOR: stats/htx: Respect the reserve when the stats page is dumped + - DOC: regtest: make it clearer what the purpose of the "broken" series is + - REGTEST: mailers: add new test for 'mailers' section + - REGTEST: Add a reg test for health-checks over SSL/TLS. + - BUG/MINOR: mux-h1: Close connection on shutr only when shutw was really done + - MEDIUM: mux-h1: Clarify how shutr/shutw are handled + - BUG/MINOR: compression: Disable it if another one is already in progress + - BUG/MINOR: filters: Detect cache+compression config on legacy HTTP streams + - BUG/MINOR: cache: Disable the cache if any compression filter precedes it + - REGTEST: Add some informatoin to test results. + - MINOR: htx: Add a function to truncate all blocks after a specific offset + - MINOR: channel/htx: Add the HTX version of channel_truncate/erase + - BUG/MINOR: proto_htx: Use HTX versions to truncate or erase a buffer + - BUG/CRITICAL: mux-h2: re-check the frame length when PRIORITY is used + - DOC: Fix typo in req.ssl_alpn example (commit 4afdd138424ab...) + - DOC: http-request cache-use / http-response cache-store expects cache name + - REGTEST: "capture (request|response)" regtest. + - BUG/MINOR: lua/htx: Respect the reserve when data are send from an HTX applet + - REGTEST: filters: add compression test + - BUG/MEDIUM: init: Initialize idle_orphan_conns for first server in server-template + - BUG/MEDIUM: ssl: Disable anti-replay protection and set max data with 0RTT. + - DOC: Be a bit more explicit about allow-0rtt security implications. + - MINOR: mux-h1: make the mux_h1_ops struct static + - BUILD: makefile: add an EXTRA_OBJS variable to help build optional code + - BUG/MEDIUM: connection: properly unregister the mux on failed initialization + - BUG/MAJOR: cache: fix confusion between zero and uninitialized cache key + - REGTESTS: test case for map_regm commit 271022150d + - REGTESTS: Basic tests for concat,strcmp,word,field,ipmask converters + - REGTESTS: Basic tests for using maps to redirect requests / select backend + - DOC: REGTESTS README varnishtest -Dno-htx= define. + - MINOR: spoe: Make the SPOE filter compatible with HTX proxies + - MINOR: checks: Store the proxy in checks. + - BUG/MEDIUM: checks: Avoid having an associated server for email checks. + - REGTEST: Switch to vtest. + - REGTEST: Adapt reg test doc files to vtest. + - BUG/MEDIUM: h1: Make sure we destroy an inactive connectin that did shutw. + - BUG/MINOR: base64: dec func ignores padding for output size checking + - BUG/MEDIUM: ssl: missing allocation failure checks loading tls key file + - MINOR: ssl: add support of aes256 bits ticket keys on file and cli. + - BUG/MINOR: backend: don't use url_param_name as a hint for BE_LB_ALGO_PH + - BUG/MINOR: backend: balance uri specific options were lost across defaults + - BUG/MINOR: backend: BE_LB_LKUP_CHTREE is a value, not a bit + - MINOR: backend: move url_param_name/len to lbprm.arg_str/len + - MINOR: backend: make headers and RDP cookie also use arg_str/len + - MINOR: backend: add new fields in lbprm to store more LB options + - MINOR: backend: make the header hash use arg_opt1 for use_domain_only + - MINOR: backend: remap the balance uri settings to lbprm.arg_opt{1,2,3} + - MINOR: backend: move hash_balance_factor out of chash + - MEDIUM: backend: move all LB algo parameters into an union + - MINOR: backend: make the random algorithm support a number of draws + - BUILD/MEDIUM: da: Necessary code changes for new buffer API. + - BUG/MINOR: stick_table: Prevent conn_cur from underflowing + - BUG: 51d: Changes to the buffer API in 1.9 were not applied to the 51Degrees code. + - BUG/MEDIUM: stats: Get the right scope pointer depending on HTX is used or not + - DOC: add a missing space in the documentation for bc_http_major + - REGTEST: checks basic stats webpage functionality + - BUG/MEDIUM: servers: Make assign_tproxy_address work when ALPN is set. + - BUG/MEDIUM: connections: Add the CO_FL_CONNECTED flag if a send succeeded. + - DOC: add github issue templates + - MINOR: cfgparse: Extract some code to be re-used. + - CLEANUP: cfgparse: Return asap from cfg_parse_peers(). + - CLEANUP: cfgparse: Code reindentation. + - MINOR: cfgparse: Useless frontend initialization in "peers" sections. + - MINOR: cfgparse: Rework peers frontend init. + - MINOR: cfgparse: Simplication. + - MINOR: cfgparse: Make "peer" lines be parsed as "server" lines. + - MINOR: peers: Make outgoing connection to SSL/TLS peers work. + - MINOR: cfgparse: SSL/TLS binding in "peers" sections. + - DOC: peers: SSL/TLS documentation for "peers" + - BUG/MINOR: startup: certain goto paths in init_pollers fail to free + - BUG/MEDIUM: checks: fix recent regression on agent-check making it crash + - BUG/MINOR: server: don't always trust srv_check_health when loading a server state + - BUG/MINOR: check: Wake the check task if the check is finished in wake_srv_chk() + - BUG/MEDIUM: ssl: Fix handling of TLS 1.3 KeyUpdate messages + - DOC: mention the effect of nf_conntrack_tcp_loose on src/dst + - BUG/MINOR: proto-htx: Return an error if all headers cannot be received at once + - BUG/MEDIUM: mux-h2/htx: Respect the channel's reserve + - BUG/MINOR: mux-h1: Apply the reserve on the channel's buffer only + - BUG/MINOR: mux-h1: avoid copying output over itself in zero-copy + - BUG/MAJOR: mux-h2: don't destroy the stream on failed allocation in h2_snd_buf() + - BUG/MEDIUM: backend: also remove from idle list muxes that have no more room + - BUG/MEDIUM: mux-h2: properly abort on trailers decoding errors + - MINOR: h2: declare new sets of frame types + - BUG/MINOR: mux-h2: CONTINUATION in closed state must always return GOAWAY + - BUG/MINOR: mux-h2: headers-type frames in HREM are always a connection error + - BUG/MINOR: mux-h2: make it possible to set the error code on an already closed stream + - BUG/MINOR: hpack: return a compression error on invalid table size updates + - MINOR: server: make sure pool-max-conn is >= -1 + - BUG/MINOR: stream: take care of synchronous errors when trying to send + - CLEANUP: server: fix indentation mess on idle connections + - BUG/MINOR: mux-h2: always check the stream ID limit in h2_avail_streams() + - BUG/MINOR: mux-h2: refuse to allocate a stream with too high an ID + - BUG/MEDIUM: backend: never try to attach to a mux having no more stream available + - MINOR: server: add a max-reuse parameter + - MINOR: mux-h2: always consider a server's max-reuse parameter + - MEDIUM: stream-int: always mark pending outgoing SI_ST_CON + - MINOR: stream: don't wait before retrying after a failed connection reuse + - MEDIUM: h2: always parse and deduplicate the content-length header + - BUG/MINOR: mux-h2: always compare content-length to the sum of DATA frames + - CLEANUP: h2: Remove debug printf in mux_h2.c + - MINOR: cfgparse: make the process/thread parser support a maximum value + - MINOR: threads: make MAX_THREADS configurable at build time + - DOC: nbthread is no longer experimental. + - BUG/MINOR: listener: always fill the source address for accepted socketpairs + - BUG/MINOR: mux-h2: do not report available outgoing streams after GOAWAY + - BUG/MINOR: spoe: corrected fragmentation string size + - BUG/MINOR: task: fix possibly missed event in inter-thread wakeups + - BUG/MEDIUM: servers: Attempt to reuse an unfinished connection on retry. + - BUG/MEDIUM: backend: always call si_detach_endpoint() on async connection failure + - SCRIPTS: add the issue tracker URL to the announce script + - MINOR: peers: Extract some code to be reused. + - CLEANUP: peers: Indentation fixes. + - MINOR: peers: send code factorization. + - MINOR: peers: Add new functions to send code and reduce the I/O handler. + - MEDIUM: peers: synchronizaiton code factorization to reduce the size of the I/O handler. + - MINOR: peers: Move update receive code to reduce the size of the I/O handler. + - MINOR: peers: Move ack, switch and definition receive code to reduce the size of the I/O handler. + - MINOR: peers: Move high level receive code to reduce the size of I/O handler. + - CLEANUP: peers: Be more generic. + - MINOR: peers: move error handling to reduce the size of the I/O handler. + - MINOR: peers: move messages treatment code to reduce the size of the I/O handler. + - MINOR: peers: move send code to reduce the size of the I/O handler. + - CLEANUP: peers: Remove useless statements. + - MINOR: peers: move "hello" message treatment code to reduce the size of the I/O handler. + - MINOR: peers: move peer initializations code to reduce the size of the I/O handler. + - CLEANUP: peers: factor the error handling code in peer_treet_updatemsg() + - CLEANUP: peers: factor error handling in peer_treat_definedmsg() + - BUILD/MINOR: peers: shut up a build warning introduced during last cleanup + - BUG/MEDIUM: mux-h2: only close connection on request frames on closed streams + - CLEANUP: mux-h2: remove two useless but misleading assignments + - BUG/MEDIUM: checks: Check that conn_install_mux succeeded. + - BUG/MEDIUM: servers: Only destroy a conn_stream we just allocated. + - BUG/MEDIUM: servers: Don't add an incomplete conn to the server idle list. + - BUG/MEDIUM: checks: Don't try to set ALPN if connection failed. + - BUG/MEDIUM: h2: In h2_send(), stop the loop if we failed to alloc a buf. + - BUG/MEDIUM: peers: Handle mux creation failure. + - BUG/MEDIUM: servers: Close the connection if we failed to install the mux. + - BUG/MEDIUM: compression: Rewrite strong ETags + - BUG/MINOR: deinit: tcp_rep.inspect_rules not deinit, add to deinit + - CLEANUP: mux-h2: remove misleading leftover test on h2s' nullity + - BUG/MEDIUM: mux-h2: wake up flow-controlled streams on initial window update + - BUG/MEDIUM: mux-h2: fix two half-closed to closed transitions + - BUG/MEDIUM: mux-h2: make sure never to send GOAWAY on too old streams + - BUG/MEDIUM: mux-h2: do not abort HEADERS frame before decoding them + - BUG/MINOR: mux-h2: make sure response HEADERS are not received in other states than OPEN and HLOC + - MINOR: h2: add a generic frame checker + - MEDIUM: mux-h2: check the frame validity before considering the stream state + - CLEANUP: mux-h2: remove stream ID and frame length checks from the frame parsers + - BUG/MINOR: mux-h2: make sure request trailers on aborted streams don't break the connection + - DOC: compression: Update the reasons for disabled compression + - BUG/MEDIUM: buffer: Make sure b_is_null handles buffers waiting for allocation. + - DOC: htx: make it clear that htxbuf() and htx_from_buf() always return valid pointers + - MINOR: htx: never check for null htx pointer in htx_is_{,not_}empty() + - MINOR: mux-h2: consistently rely on the htx variable to detect the mode + - BUG/MEDIUM: peers: Peer addresses parsing broken. + - BUG/MEDIUM: mux-h1: Don't add "transfer-encoding" if message-body is forbidden + - BUG/MEDIUM: connections: Don't forget to remove CO_FL_SESS_IDLE. + - BUG/MINOR: stream: don't close the front connection when facing a backend error + - BUG/MEDIUM: mux-h2: wait for the mux buffer to be empty before closing the connection + - MINOR: stream-int: add a new flag to mention that we want the connection to be killed + - MINOR: connstream: have a new flag CS_FL_KILL_CONN to kill a connection + - BUG/MEDIUM: mux-h2: do not close the connection on aborted streams + - BUG/MINOR: server: fix logic flaw in idle connection list management + - MINOR: mux-h2: max-concurrent-streams should be unsigned + - MINOR: mux-h2: make sure to only check concurrency limit on the frontend + - MINOR: mux-h2: learn and store the peer's advertised MAX_CONCURRENT_STREAMS setting + - BUG/MEDIUM: mux-h2: properly consider the peer's advertised max-concurrent-streams + - MINOR: xref: Add missing barriers. + - MINOR: muxes: Don't bother to LIST_DEL(&conn->list) before calling conn_free(). + - MINOR: debug: Add an option that causes random allocation failures. + - BUG/MEDIUM: backend: always release the previous connection into its own target srv_list + - BUG/MEDIUM: htx: check the HTX compatibility in dynamic use-backend rules + - BUG/MINOR: tune.fail-alloc: Don't forget to initialize ret. + - BUG/MINOR: backend: check srv_conn before dereferencing it + - BUG/MEDIUM: mux-h2: always omit :scheme and :path for the CONNECT method + - BUG/MEDIUM: mux-h2: always set :authority on request output + - BUG/MEDIUM: stream: Don't forget to free s->unique_id in stream_free(). + - BUG/MINOR: threads: fix the process range of thread masks + - BUG/MINOR: config: fix bind line thread mask validation + - CLEANUP: threads: fix misleading comment about all_threads_mask + - CLEANUP: threads: use nbits to calculate the thread mask + - OPTIM: listener: optimize cache-line packing for struct listener + - MINOR: tools: improve the popcount() operation + - MINOR: config: keep an all_proc_mask like we have all_threads_mask + - MINOR: global: add proc_mask() and thread_mask() + - MINOR: config: simplify bind_proc processing using proc_mask() + - MINOR: threads: make use of thread_mask() to simplify some thread calculations + - BUG/MINOR: compression: properly report compression stats in HTX mode + - BUG/MINOR: task: close a tiny race in the inter-thread wakeup + - BUG/MAJOR: config: verify that targets of track-sc and stick rules are present + - BUG/MAJOR: spoe: verify that backends used by SPOE cover all their callers' processes + - BUG/MAJOR: htx/backend: Make all tests on HTTP messages compatible with HTX + - BUG/MINOR: config: make sure to count the error on incorrect track-sc/stick rules + - DOC: ssl: Clarify when pre TLSv1.3 cipher can be used + - DOC: ssl: Stop documenting ciphers example to use + - BUG/MINOR: spoe: do not assume agent->rt is valid on exit + - BUG/MINOR: lua: initialize the correct idle conn lists for the SSL sockets + - BUG/MEDIUM: spoe: initialization depending on nbthread must be done last + - BUG/MEDIUM: server: initialize the idle conns list after parsing the config + - BUG/MEDIUM: server: initialize the orphaned conns lists and tasks at the end + - MINOR: config: make MAX_PROCS configurable at build time + - BUG/MAJOR: spoe: Don't try to get agent config during SPOP healthcheck + - BUG/MINOR: config: Reinforce validity check when a process number is parsed + - BUG/MEDIUM: peers: check that p->srv actually exists before using p->srv->use_ssl + - CONTRIB: contrib/prometheus-exporter: Add a Prometheus exporter for HAProxy + - BUG/MINOR: mux-h1: verify the request's version before dropping connection: keep-alive + - BUG: 51d: In Hash Trie, multi header matching was affected by the header names stored globaly. + - MEDIUM: 51d: Enabled multi threaded operation in the 51Degrees module. + - BUG/MAJOR: stream: avoid double free on unique_id + - BUILD/MINOR: stream: avoid a build warning with threads disabled + - BUILD/MINOR: tools: fix build warning in the date conversion functions + - BUILD/MINOR: peers: remove an impossible null test in intencode() + - BUILD/MINOR: htx: fix some potential null-deref warnings with http_find_stline + - BUG/MEDIUM: peers: Missing peer initializations. + - BUG/MEDIUM: http_fetch: fix the "base" and "base32" fetch methods in HTX mode + - BUG/MEDIUM: proto_htx: Fix data size update if end of the cookie is removed + - BUG/MEDIUM: http_fetch: fix "req.body_len" and "req.body_size" fetch methods in HTX mode + - BUILD/MEDIUM: initcall: Fix build on MacOS. + - BUG/MEDIUM: mux-h2/htx: Always set CS flags before exiting h2_rcv_buf() + - MINOR: h2/htx: Set the flag HTX_SL_F_BODYLESS for messages without body + - BUG/MINOR: mux-h1: Add "transfer-encoding" header on outgoing requests if needed + - BUG/MINOR: mux-h2: Don't add ":status" pseudo-header on trailers + - BUG/MINOR: proto-htx: Consider a XFER_LEN message as chunked by default + - BUG/MEDIUM: h2/htx: Correctly handle interim responses when HTX is enabled + - MINOR: mux-h2: Set HTX extra value when possible + - BUG/MEDIUM: htx: count the amount of copied data towards the final count + - MINOR: mux-h2: make the H2 MAX_FRAME_SIZE setting configurable + - BUG/MEDIUM: mux-h2/htx: send an empty DATA frame on empty HTX trailers + - BUG/MEDIUM: servers: Use atomic operations when handling curr_idle_conns. + - BUG/MEDIUM: servers: Add a per-thread counter of idle connections. + - MINOR: fd: add a new my_closefrom() function to close all FDs + - MINOR: checks: use my_closefrom() to close all FDs + - MINOR: fd: implement an optimised my_closefrom() function + - BUG/MINOR: fd: make sure my_closefrom() doesn't miss some FDs + - BUG/MAJOR: fd/threads, task/threads: ensure all spin locks are unlocked + - BUG/MAJOR: listener: Make sure the listener exist before using it. + - MINOR: fd: Use closefrom() as my_closefrom() if supported. + - BUG/MEDIUM: mux-h1: Report the right amount of data xferred in h1_rcv_buf() + - BUG/MINOR: channel: Set CF_WROTE_DATA when outgoing data are skipped + - MINOR: htx: Add function to drain data from an HTX message + - MINOR: channel/htx: Add function to skips output bytes from an HTX channel + - BUG/MAJOR: cache/htx: Set the start-line offset when a cached object is served + - BUG/MEDIUM: cache: Get objects from the cache only for GET and HEAD requests + - BUG/MINOR: cache/htx: Return only the headers of cached objects to HEAD requests + - BUG/MINOR: mux-h1: Always initilize h1m variable in h1_process_input() + - BUG/MEDIUM: proto_htx: Fix functions applying regex filters on HTX messages + - BUG/MEDIUM: h2: advertise to servers that we don't support push + - MINOR: standard: Add a function to parse uints (dotted notation). + - MINOR: arg: Add support for ARGT_PBUF_FNUM arg type. + - MINOR: http_fetch: add "req.ungrpc" sample fetch for gRPC. + - MINOR: sample: Add two sample converters for protocol buffers. + - DOC: sample: Add gRPC related documentation. + +2018/12/22 : 2.0-dev0 + - BUG/MAJOR: connections: Close the connection before freeing it. + - REGTEST: Require the option LUA to run lua tests + - REGTEST: script: Process script arguments before everything else + - REGTEST: script: Evaluate the varnishtest command to allow quoted parameters + - REGTEST: script: Add the option --clean to remove previous log direcotries + - REGTEST: script: Add the option --debug to show logs on standard ouput + - REGTEST: script: Add the option --keep-logs to keep all log directories + - REGTEST: script: Add the option --use-htx to enable the HTX in regtests + - REGTEST: script: Print only errors in the results report + - REGTEST: Add option to use HTX prefixed by the macro 'no-htx' + - REGTEST: Make reg-tests target support argument. + - REGTEST: Fix a typo about barrier type. + - REGTEST: Be less Linux specific with a syslog regex. + - REGTEST: Missing enclosing quotes for ${tmpdir} macro. + - REGTEST: Exclude freebsd target for some reg tests. + - BUG/MEDIUM: h2: Don't forget to quit the sending_list if SUB_CALL_UNSUBSCRIBE. + - BUG/MEDIUM: mux-h2: Don't forget to quit the send list on error reports + - BUG/MEDIUM: dns: Don't prevent reading the last byte of the payload in dns_validate_response() + - BUG/MEDIUM: dns: overflowed dns name start position causing invalid dns error + - BUG/MINOR: compression/htx: Don't compress responses with unknown body length + - BUG/MINOR: compression/htx: Don't add the last block of data if it is empty + - MEDIUM: mux_h1: Implement h1_show_fd. + - REGTEST: script: Add support of alternatives in requited options list + - REGTEST: Add a basic test for the compression + - BUG/MEDIUM: mux-h2: don't needlessly wake up the demux on short frames + - REGTEST: A basic test for "http-buffer-request" + - BUG/MEDIUM: server: Also copy "check-sni" for server templates. + - MINOR: ssl: Add ssl_sock_set_alpn(). + - MEDIUM: checks: Add check-alpn. + - wip + +2018/12/19 : 1.9.0 + - BUG/MEDIUM: compression: Use the right buffer pointers to compress input data + - BUG/MINOR: mux_pt: Set CS_FL_WANT_ROOM when count is zero in rcv_buf() callback + - BUG/MEDIUM: connection: Add a new CS_FL_ERR_PENDING flag to conn_streams. + - CONTRIB: debug: teach the "flags" utility about new conn_stream flags + - BUG/MEDIUM: stream-int: always clear CS_FL_WANT_ROOM before receiving + - BUG/MEDIUM: mux-h2: also restart demuxing when data are pending in demux + - BUG/MEDIUM: mux-h2: restart demuxing as soon as demux data are available + - BUG/MEDIUM: h2: fix aggregated cookie length computation in HTX mode + - MINOR: mux-h2: report more h2c, last h2s and cs information on "show fd" + - CONTRIB: debug: report stream-int's flag SI_FL_CLEAN_ABRT + - MINOR: cli/stream: add the conn_stream in "show sess" output + - BUG/MINOR: mux-h2: don't report a fantom h2s in "show fd" + - BUG/MINOR: cli/fd: don't isolate the thread for each individual fd + - MINOR: objtype: report a few missing types in names and base pointers + - BUG/MEDIUM: mux-h2: make sure to report synchronous errors after EOS + - BUG/MEDIUM: mux-h2: report asynchronous errors in h2_wake_some_streams() + - BUG/MEDIUM: mux-h2: make sure the demux also wakes streams up on errors + - BUG/MINOR: mux-h1: report the correct frontend in error captures + - BUG/MEDIUM: stream-int: also wake the stream up on end of transfer + - MEDIUM: h2: properly check and deduplicate the content-length header in HTX + - BUG/MEDIUM: stream: Forward the right amount of data before infinite forwarding + - BUG/MINOR: proto_htx: Call the HTX version of the function managing client cookies + - BUG/MEDIUM: lua/htx: Handle EOM in receive/get_line calls in HTTP applets + - BUG/MINOR: lua: Return an error if a legacy HTTP applet doesn't send anything + - MINOR: compression: Remove the thread_local variable buf_output + - CLEANUP: connection: rename subscription events values and event field + - CLEANUP: connection: rename conn->mux_ctx to conn->ctx + - MINOR: connection: remove an unwelcome dependency on struct stream + - CLEANUP: stream-int: consistently call the si/stream_int functions + - BUG/MEDIUM: h1: Don't shutw/shutr the connection if we have keepalive. + - BUG/MEDIUM: H2: Make sure htx is set even on empty frames. + - BUG/MEDIUM: mux-h2: pass CS_FL_ERR_PENDING to h2_wake_some_streams() + - MEDIUM: stream-int: always consider all CS errors on the send side + - BUG/MEDIUM: h2: Make sure we don't set CS_FL_ERROR if there's still data. + - CLEANUP: mux-h2: implement h2s_notify_{send,recv} to report events to subscribers + - MINOR: mux-h2: add a new function h2s_alert() to call the data layer + - BUG/MEDIUM: mux-h2: make use of h2s_alert() to report aborts + - MINOR: connection: add cs_set_error() to set the error bits + - CLEANUP: mux-h2: make use of cs_set_error() + - BUG/MINOR: mux-h2: make sure we check the conn_stream in early data + - BUG/MEDIUM: h2: Don't wait for flow control if the connection had a shutr. + - MINOR: cli/show_fd: report that a connection is back or not + - SCRIPTS: add the slack channel URL to the announce script + - CLEANUP: remove my name and address from the copyright banner + - DOC: mention in the readme that 1.9 is a stable version now + +2018/12/16 : 1.9-dev11 + - BUG/MEDIUM: connection: Don't use the provided conn_stream if it was tried. + - REGTEST/MINOR: remove double body specification for server txresp + - BUG/MEDIUM: connections: Remove error flags when retrying. + - REGTEST/MINOR: skip seamless-reload test with abns socket on freebsd + - REGTEST/MINOR: remove health-check that can make the test fail + - DOC: clarify that check-sni needs an argument. + - DOC: refer to check-sni in the documentation of sni + - BUG/MEDIUM: mux-h2: fix encoding of non-GET/POST methods + - BUG/MINOR: mux-h1: Fix conn_mode processing for headerless outgoing messages + - BUG/MEDIUM: mux-h1: Add a BUSY mode to not loop on pipelinned requests + - BUG/MEDIUM: mux-h1: Don't loop on the headers parsing if the read0 was received + - BUG/MEDIUM: htx: Always do a defrag if a block value is replace by a bigger one + - BUG/MEDIUM: mux-h2: Don't forget to set the CS_FL_EOS flag with htx. + - BUG/MINOR: hpack: fix off-by-one in header name encoding length calculation + - CLEANUP: hpack: no need to include chunk.h, only include buf.h + - MINOR: hpack: simplify the len to bytes conversion + - MINOR: hpack: use ist2bin() to copy header names in hpack_encode_header() + - MINOR: hpack: optimize header encoding for short names + - CONTRIB: hpack: add a compressed stream generator for the encoder + - MEDIUM: hpack: make it possible to encode any static header name + - MINOR: hpack: move the length computation and encoding functions to .h + - MINOR: hpack: provide a function to encode a short indexed header + - MINOR: hpack: provide a function to encode a long indexed header + - MINOR: hpack: provide new functions to encode the ":status" header + - MEDIUM: mux-h2: make use of standard HPACK encoding functions for the status + - MINOR: hpack: provide a function to encode an HTTP method + - MEDIUM: mux-h2: make use of hpack_encode_method() to encode the method + - MINOR: hpack: provide a function to encode an HTTP scheme + - MEDIUM: mux-h2: make use of hpack_encode_scheme() to encode the scheme + - MINOR: hpack: provide a function to encode an HTTP path + - MEDIUM: mux-h2: make use of hpack_encode_path() to encode the path + - REGTEST: add the HTTP rules test involving HTX processing + - REORG: connection: centralize the conn_set_{tos,mark,quickack} functions + - MEDIUM: cli: rework the CLI proxy parser + - MINOR: cli: parse prompt command in the CLI proxy + - MINOR: cli: implements 'quit' in the CLI proxy + - BUG/MINOR: cli: wait for payload data even without prompt + - MEDIUM: cli: handle payload in CLI proxy + - MINOR: cli: use pcli_flags for prompt activation + - MINOR: compression: Rename the function check_legacy_http_comp_flt() + - MINOR: cache/htx: Don't use the same cache on HTX and legacy HTTP proxies + - MINOR: cache: Register the cache as a data filter only if response is cacheable + - MEDIUM: cache/htx: Add the HTX support into the cache + - MINOR: cache: Improve and simplify the cache configuration check + - MINOR: filters: Export the name of known filters + - MEDIUM: cache/compression: Add a way to safely combined compression and cache + - MEDIUM: cache: Require an explicit filter declaration if other filters are used + - REORG: htx: merge types+proto into common/htx.h + - REORG: http: create http_msg.c to place there some legacy HTTP parts + - REORG: h1: move legacy http functions to http_msg.c + - REORG: h1: move the h1_state definition to proto_http + - CLEANUP: h1: remove some occurrences of unneeded h1.h inclusions + - REORG: h1: merge types+proto into common/h1.h + - CLEANUP: stream: remove SF_TUNNEL, SF_INITIALIZED, SF_CONN_TAR + - MEDIUM: mux-h1: implement true zero-copy of DATA blocks + - MINOR: config: round up global.tune.bufsize to the next multiple of 2 void* + - BUG/MINOR: mux-h2: refrain from muxing during the preface + - BUG/MINOR: mux-h2: advertise a larger connection window size + - DOC: master CLI documentation in management.txt + - MINOR: mux-h2: avoid copying large blocks into full buffers + - MEDIUM: mux-h2: implement true zero-copy send of large HTX DATA blocks + - MINOR: mux-h2: force reads to be HTX-aligned in HTX mode + - MINOR: cli: change 'show proc' output of old processes + - BUG/MEDIUM: mux-h1: Fix the zero-copy on output for chunked messages + - BUG: dns: Prevent stack-exhaustion via recursion loop in dns_read_name + - BUG: dns: Prevent out-of-bounds read in dns_read_name() + - BUG: dns: Prevent out-of-bounds read in dns_validate_dns_response() + - BUG: dns: Fix out-of-bounds read via signedness error in dns_validate_dns_response() + - BUG: dns: Fix off-by-one write in dns_validate_dns_response() + - REGTEST: the cache regtest requires haproxy 1.9 + - MEDIUM: cli: store CLI level in the appctx + - MEDIUM: cli: show and change CLI permissions + - CLEANUP: cli: use dedicated define instead of appctx ones + - MEDIUM: cli: handle CLI level from the master CLI + - BUG/MEDIUM: cli: handle correctly prefix and payload + - BUILD: Makefile: Implements the help target + - REGTESTS: adjust the http-rules regtest to support window updates + - BUG/MEDIUM: connections: Remove CS_FL_EOS | CS_FL_REOS on retry. + - BUG/MEDIUM: stream_interface: Don't report read0 if we were not connected. + - BUG/MEDIUM: connection: Just make sure we closed the fd on connection failure. + - MEDIUM: mux: Add an optional "reset" method. + - BUG/MEDIUM: mux-h1: Fix loop if server closes its connection with unparsed data + - MINOR: mux-h1: Add helper functions to wake a stream from recv or send + - BUG/MEDIUM: mux-h1: Wake the stream for send once the connection is established + - BUG/MEDIUM: connections: Don't attempt to reuse an unusable connection. + - MEDIUM: htx: Try to take a connection over if it has no owner. + - REGTEST: Reg testing improvements. + - REGTEST: Add a first test for health-checks. + - REGTEST: Reg test for "check" health-check option. + - REGTEST: level 1 health-check test 2. + - REGTEST: Add miscellaneous reg tests for health-checks. + - REGTEST: add a few HTTP messaging tests + - MINOR: lb: make the leastconn algorithm more accurate + - REGTEST: fix missing space in checks/s00001 + - REGTEST: http-messaging: add "option http-buffer-request" for H2 tests + - BUG/MEDIUM: cache: fix random crash on filter parser's error path + - MINOR: connection: realign empty buffers in muxes, not transport layers + - MINOR: mux_h1/h2: simplify the zero-copy Rx alignment + - MINOR: backend: count the number of connect and reuse per server and per backend + - BUG/MINOR: stats: fix inversion of failed header rewrites and other statuses + - MINOR: tools: increase the number of ITOA strings to 16 + - MINOR: cache: report the number of cache lookups and cache hits + - MEDIUM: tasks: check the global task mask instead of the thread number + - MINOR: mworker: set all_threads_mask and pid_bit to 1 + - BUG/MINOR: proto_htx: Fix htx_res_set_status to also set the reason + - BUG/MINOR: stats: Parse post data for HTX streams + - MINOR: payload/htx: Adapt smp_fetch_len to be HTX aware + - MINOR: http_fecth: Implement body_len and body_size sample fetches for the HTX + - MAJOR: lua: Forbid calls to Channel functions for LUA scripts in HTTP proxies + - MEDIUM: lua/htx: Adapt functions of the HTTP to be compatible with HTX + - MINOR: lua/htx: Adapt the functions get_in_length and is_full to be HTX aware + - MAJOR: lua/htx: Adapt HTTP applets to support HTX messages + - MINOR: lua: Remove useless check on the messages state in HTTP functions + - BUG/MEDIUM: htx: When performing zero-copy, start from the right offset. + - BUG/MINOR: mworker: don't use unitialized mworker_proc struct + - MINOR: mworker/cli: indicate in the master prompt when a reload failed + - MINOR: cli: implements 'reload' on master CLI + - BUG/MEDIUM: log: Don't call sample_fetch_as_type if we don't have a stream. + - BUG/MEDIUM: mux-h1: make sure we always have at least one HTX block to send + - BUG/MAJOR: backend: only update server's counters when the server exists + - MINOR: tools: preset the port of fd-based "sockets" to zero + - BUG/MINOR: log: fix logging to both FD and IP + - REGTEST: Add a reg test for HTTP cookies. + - BUILD: ssl: Fix compilation without deprecated OpenSSL 1.1 APIs + - BUILD: thread: properly report multi-thread support + - BUG/MINOR: logs: leave startup-logs global and not per-thread + - BUG/MEDIUM: threads: don't close the thread waker pipe if not init + - BUG/MAJOR: compression/cache: Make it really works with these both filters + - BUG/MEDIUM: h2: Don't forget to destroy the h2s after deferred shut. + - MEDIUM: proxy: Set http-reuse safe as default. + - MEDIUM: servers: Add a command to limit the number of idling connections. + - MEDIUM: servers: Replace idle-timeout with pool-purge-delay. + - MEDIUM: mux: Destroy the stream before trying to add the conn to the idle list. + - MEDIUM: mux: provide the session to the init() and attach() method. + - MEDIUM: sessions: Don't keep an infinite number of idling connections. + - MEDIUM: servers: Be more agressive when adding H2 connection to idle lists. + - MEDIUM: mux_h2: Always set CS_FL_NOT_FIRST for new conn_streams. + - BUG/MEDIUM: htx/cache: use the correct class of error codes on abort + - BUG/MINOR: cache: also consider CF_SHUTR to abort delivery + - MINOR: pools: Cast to volatile int * instead of int *. + - MINOR: debug: make the ABORT_NOW macro use a volatile int + - BUG/MEDIUM: h2: Don't destroy the h2s if it still has a cs attached. + - BUG/MEDIUM: mux-h1: don't try to process an empty input buffer + - DOC: clarify the agent-check status line syntax + - BUG/MAJOR: hpack: fix length check for short names encoding + - DOC: split the README into README + INSTALL + +2018/12/08 : 1.9-dev10 + - MINOR: htx: Rename functions htx_*_to_str() to be H1 specific + - BUG/MINOR: htx: Force HTTP/1.1 on H1 formatting when version is 1.1 or above + - BUG/MINOR: fix ssl_fc_alpn and actually add ssl_bc_alpn + - BUG/MEDIUM: mworker: stop proxies which have no listener in the master + - BUG/MEDIUM: h1: Destroy a connection after detach if it has no owner. + - BUG/MEDIUM: h2: Don't forget to wake the tasklet after shutr/shutw. + - BUG/MINOR: flt_trace/compression: Use the right flag to add the HTX support + - BUG/MEDIUM: stream_interface: Make REALLY sure we read all the data. + - MEDIUM: mux-h1: Revamp the way subscriptions are handled. + - BUG/MEDIUM: mux-h1: Always set CS_FL_RCV_MORE when data are received in h1_recv() + - MINOR: mux-h1: Make sure to return 1 in h1_recv() when needed + - BUG/MEDIUM: mux-h1: Release the mux H1 in h1_process() if there is no h1s + - BUG/MINOR: proto_htx: Truncate the request when an error is detected + - BUG/MEDIUM: h2: When sending in HTX, make sure the caller knows we sent all. + - BUG/MEDIUM: mux-h2: properly update the window size in HTX mode + - BUG/MEDIUM: mux-h2: make sure to always report HTX EOM when consumed by headers + - BUG/MEDIUM: mux-h2: stop sending HTX once the mux is blocked + - BUG/MEDIUM: mux-h2: don't send more HTX data than requested + - MINOR: mux-h2: stop on non-DATA and non-EOM HTX blocks + - BUG/MEDIUM: h1: Correctly report used data with no len. + - MEDIUM: h1: Realign the ibuf before calling rcv_buf if needed. + - BUG/MEDIUM: mux_pt: Always set CS_FL_RCV_MORE. + - MINOR: htx: make htx_from_buf() adjust the size only on new buffers + - MINOR: htx: add buf_room_for_htx_data() to help optimize buffer transfers + - MEDIUM: mux-h1: make use of buf_room_for_htx_data() instead of b_room() + - MEDIUM: mux-h1: attempt to zero-copy Rx DATA transfers + - MEDIUM: mux-h1: avoid a double copy on the Tx path whenever possible + - BUG/MEDIUM: stream-int: don't mark as blocked an empty buffer on Rx + - BUG/MINOR: mux-h1: Check h1m flags to set the server conn_mode on request path + - MEDIUM: htx: Rework conversion from a buffer to an htx structure + - MEDIUM: channel/htx: Add functions for forward HTX data + - MINOR: mux-h1: Don't adjust anymore the amount of data sent in h1_snd_buf() + - CLEANUP: htx: Fix indentation here and there in HTX files + - MINOR: mux-h1: Allow partial data consumption during outgoing data processing + - BUG/MEDIUM: mux-h2: use the correct offset for the HTX start line + - BUG/MEDIUM: mux-h2: stop sending using HTX on errors + - MINOR: mux-h1: Drain obuf if the output is closed after sending data + - BUG/MEDIUM: mworker: stop every tasks in the master + - BUG/MEDIUM: htx: Set the right start-line offset after a defrag + - BUG/MEDIUM: stream: Don't dereference s->txn when it is not there yet. + - BUG/MEDIUM: connections: Reuse an already attached conn_stream. + - MINOR: stream-int: add a new blocking condition on the remote connection + - BUG/MEDIUM: stream-int: don't attempt to receive if the connection is not established + - BUG/MEDIUM: lua: block on remote connection establishment + - BUG/MEDIUM: mworker: fix several typos in mworker_cleantasks() + - SCRIPTS/REGTEST: merge grep+sed into sed in run-regtests + - BUG/MEDIUM: connections: Split CS_FL_RCV_MORE into 2 flags. + - BUG/MEDIUM: h1: Don't free the connection if it's an outgoing connection. + - BUG/MEDIUM: h1: Set CS_FL_REOS if we had a read0. + - BUG/MEDIUM: mux-h1: Be sure to have a conn_stream to set CS_FL_REOS in h1_recv + - REGTEST: Move LUA reg test 4 to level 1. + - MINOR: ist: add functions to copy/uppercase/lowercase into a buffer or string + - MEDIUM: ist: always turn header names to lower case + - MINOR: h2: don't turn HTX header names to lower case anymore + - MEDIUM: ist: use local conversion arrays to case conversion + - MINOR: htx: switch to case sensitive search of lower case header names + - MINOR: mux-h1: Set CS_FL_EOS when read0 is detected and no data are pending + - BUG/MINOR: stream-int: Process read0 even if no data was received in si_cs_recv + - REGTEST: fix the Lua test file name in test lua/h00002 :-) + - REGTEST: add a basic test for HTTP rules manipulating headers + - BUG/MEDIUM: sample: Don't treat SMP_T_METH as SMP_T_STR. + - MINOR: sample: add bc_http_major + - BUG/MEDIUM: htx: fix typo in htx_replace_stline() making it fail all the time + - REGTEST: make the HTTP rules test compatible with HTTP/2 as well + - BUG/MEDIUM: h2: Don't try to chunk data when using HTX. + - MINOR: compiler: add a new macro ALREADY_CHECKED() + - BUILD: h2: mark the start line already checked to avoid warnings + - BUG/MINOR: mux-h1: Remove the connection header when it is useless + +2018/12/02 : 1.9-dev9 + - BUILD/MINOR: ssl: fix build with non-alpn/non-npn libssl + - BUG/MINOR: mworker: Do not attempt to close(2) fd -1 + - BUILD: compression: fix build error with DEFAULT_MAXZLIBMEM + - MINOR: compression: always create the compression pool + - BUG/MEDIUM: mworker: fix FD leak upon reload + - BUILD: htx: fix fprintf format inconsistency on 32-bit platforms + - BUILD: buffers: buf.h requires unistd to get ssize_t on libmusl + - MINOR: initcall: introduce a way to register init functions to call at boot + - MINOR: init: process all initcalls in order at boot time + - MEDIUM: init: convert all trivial registration calls to initcalls + - MINOR: thread: provide a set of lock initialisers + - MINOR: threads: add new macros to declare self-initializing locks + - MEDIUM: init: use self-initializing spinlocks and rwlocks + - MINOR: initcall: apply initcall to all register_build_opts() calls + - MINOR: initcall: use initcalls for most post_{check,deinit} and per_thread* + - MINOR: initcall: use initcalls for section parsers + - MINOR: memory: add a callback function to create a pool + - MEDIUM: init: use initcall for all fixed size pool creations + - MEDIUM: memory: use pool_destroy_all() to destroy all pools on deinit() + - MEDIUM: initcall: use initcalls for a few initialization functions + - MEDIUM: memory: make the pool cache an array and not a thread_local + - MINOR: ssl: free ctx when libssl doesn't support NPN + - BUG/MINOR: proto_htx: only mark connections private if NTLM is detected + - MINOR: h2: make struct h2_ops static + - BUG/MEDIUM: mworker: avoid leak of client socket + - REORG: mworker: declare master variable in global.h + - BUG/MEDIUM: listeners: CLOEXEC flag is not correctly set + - CLEANUP: http: Fix typo in init_http's comment + - BUILD: Makefile: Disable -Wcast-function-type if it exists. + - BUG/MEDIUM: h2: Don't bogusly error if the previous stream was closed. + - REGTEST/MINOR: script: add run-regtests.sh script + - REGTEST: Add a basic test for the cache. + - BUG/MEDIUM: mux_pt: Don't forget to unsubscribe() on attach. + - BUG/MINOR: ssl: ssl_sock_parse_clienthello ignores session id + - BUG/MEDIUM: connections: Wake the stream once the mux is chosen. + - BUG/MEDIUM: connections: Don't forget to detach the connection from the SI. + - BUG/MEDIUM: stream_interface: Don't check if the handshake is done. + - BUG/MEDIUM: stream_interface: Make sure we read all the data available. + - BUG/MEDIUM: h2: Call h2_process() if there's an error on the connection. + - REGTEST: Fix several issues. + - REGTEST: lua: check socket functionality from a lua-task + - BUG/MEDIUM: session: Remove the session from the session_list in session_free. + - BUG/MEDIUM: streams: Don't assume we have a CS in sess_update_st_con_tcp. + - BUG/MEDIUM: connections: Don't assume we have a mux in connect_server(). + - BUG/MEDIUM: connections: Remove the connection from the idle list before destroy. + - BUG/MEDIUM: session: properly clean the outgoing connection before freeing. + - BUG/MEDIUM: mux_pt: Don't try to send if handshake is not done. + - MEDIUM: connections: Put H2 connections in the idle list if http-reuse always. + - MEDIUM: h2: Destroy a connection with no stream if it has no owner. + - MAJOR: sessions: Store multiple outgoing connections in the session. + - MEDIUM: session: Steal owner-less connections on end of transaction. + - MEDIUM: server: Be smarter about deciding to reuse the last server. + - BUG/MEDIUM: Special-case http_proxy when dealing with outgoing connections. + - BUG/MINOR: cfgparse: Fix transition between 2 sections with the same name + - BUG/MINOR: http: Use out buffer instead of trash to display error snapshot + - BUG/MINOR: htx: Fix block size calculation when a start-line is added/replaced + - BUG/MINOR: mux-h1: Fix processing of "Connection: " header on outgoing messages + - BUG/MEDIUM: mux-h1: Reset the H1 parser when an outgoing message is processed + - BUG/MINOR: proto_htx: Send outgoing data to client to start response processing + - BUG/MINOR: htx: Stop a header or a start line lookup on the first EOH or EOM + - BUG/MINOR: connection: report mux modes when HTX is supported + - MINOR: htx: add a function to cut the beginning of a DATA block + - MEDIUM: conn_stream: Add a way to get mux's info on a CS from the upper layer + - MINOR: mux-h1: Implement get_cs_info() callback + - MINOR: stream: Rely on CS's info if it exists and fallback on session's ones + - MINOR: proto_htx: Use conn_stream's info to set t_idle duration when possible + - MINOR: mux-h1: Don't rely on the stream anymore in h1_set_srv_conn_mode() + - MINOR: mux-h1: Write last chunk and trailers if not found in the HTX message + - MINOR: mux-h1: Be prepare to fail when EOM is added during trailers parsing + - MINOR: mux-h1: Subscribe to send in h1_snd_buf() when not all data have been sent + - MINOR: mux-h1: Consume channel's data in a loop in h1_snd_buf() + - MEDIUM: mux-h1: Add keep-alive outgoing connections in connections list + - MINOR: htx: Add function to add an HTX block just before another one + - MINOR: htx: Add function to iterate on an HTX message using HTX blocks + - MINOR: htx: Add a function to find the HTX block corresponding to a data offset + - MINOR: stats: Don't add end-of-data marker and trailers in the HTX response + - MEDIUM: htx: Change htx_sl to be a struct instead of an union + - MINOR: htx: Add the start-line offset for the HTX message in the HTX structure + - MEDIUM: htx: Don't rely on h1_sl anymore except during H1 header parsing + - MINOR: proto-htx: Use the start-line flags to set the HTTP messsage ones + - MINOR: htx: Add BODYLESS flags on the HTX start-line and the HTTP message + - MINOR: proto_htx: Use full HTX messages to send 100-Continue responses + - MINOR: proto_htx: Use full HTX messages to send 103-Early-Hints responses + - MINOR: proto_htx: Use full HTX messages to send 401 and 407 responses + - MINOR: proto_htx: Send valid HTX message when redir mode is enabled on a server + - MINOR: proto_htx: Send valid HTX message to send 30x responses + - MEDIUM: proto_htx: Convert all HTTP error messages into HTX + - MINOR: mux-h1: Process conn_mode on the EOH when no connection header is found + - MINOR: mux-h1: Change client conn_mode on an explicit close for the response + - MINOR: mux-h1: Capture bad H1 messages + - MAJOR: filters: Adapt filters API to be compatible with the HTX represenation + - MEDIUM: proto_htx/filters: Add data filtering during the forwarding + - MINOR: flt_trace: Adapt to be compatible with the HTX representation + - MEDIUM: compression: Adapt to be compatible with the HTX representation + - MINOR: h2: implement H2->HTX request header frame transcoding + - MEDIUM: mux-h2: register mux for both HTTP and HTX modes + - MEDIUM: mux-h2: make h2_rcv_buf() support HTX transfers + - MEDIUM: mux-h2: make h2_snd_buf() HTX-aware + - MEDIUM: mux-h2: add basic H2->HTX transcoding support for headers + - MEDIUM: mux-h2: implement emission of H2 headers frames from HTX blocks + - MEDIUM: mux-h2: implement the emission of DATA frames from HTX DATA blocks + - MEDIUM: mux-h2: support passing H2 DATA frames to HTX blocks + - BUG/MINOR: cfgparse: Fix the call to post parser of the last sections parsed + - BUG/MEDIUM: mux-h2: don't lose the first response header in HTX mode + - BUG/MEDIUM: mux-h2: remove the HTX EOM block on H2 response headers + - MINOR: listener: the mux_proto entry in the bind_conf is const + - MINOR: connection: create conn_get_best_mux_entry() + - MINOR: server: the mux_proto entry in the server is const + - MINOR: config: make sure to associate the proper mux to bind and servers + - MINOR: hpack: add ":path" to the list of common header fields + - MINOR: h2: add new functions to produce an HTX message from an H2 response + - MINOR: mux-h2: mention that the mux is compatible with both sides + - MINOR: mux-h2: implement an outgoing stream allocator : h2c_bck_stream_new() + - MEDIUM: mux-h2: start to create the outgoing mux + - MEDIUM: mux-h2: implement encoding of H2 request on the backend side + - MEDIUM: mux-h2: make h2_frt_decode_headers() direction-agnostic + - MEDIUM: mux-h2: make h2_process_demux() capable of processing responses as well + - MEDIUM: mux-h2: Implement h2_attach(). + - MEDIUM: mux-h2: Don't bother flagging outgoing connections as TOOMANY. + - REGTEST: Fix LEVEL 4 script 0 of "connection" module. + - MINOR: connection: Fix a comment. + - MINOR: mux: add a "max_streams" method. + - MEDIUM: servers: Add a way to keep idle connections alive. + - CLEANUP: fix typos in the htx subsystem + - CLEANUP: Fix typo in the chunk headers file + - CLEANUP: Fix typos in the h1 subsystem + - CLEANUP: Fix typos in the h2 subsystem + - CLEANUP: Fix a typo in the mini-clist header + - CLEANUP: Fix a typo in the proto_htx subsystem + - CLEANUP: Fix typos in the proto_tcp subsystem + - CLEANUP: Fix a typo in the signal subsystem + - CLEANUP: Fix a typo in the session subsystem + - CLEANUP: Fix a typo in the queue subsystem + - CLEANUP: Fix typos in the shctx subsystem + - CLEANUP: Fix typos in the socket pair protocol subsystem + - CLEANUP: Fix typos in the map management functions + - CLEANUP: Fix typo in the fwrr subsystem + - CLEANUP: Fix typos in the cli subsystem + - CLEANUP: Fix typo in the 51d subsystem + - CLEANUP: Fix a typo in the base64 subsystem + - CLEANUP: Fix a typo in the connection subsystem + - CLEANUP: Fix a typo in the protocol header file + - CLEANUP: Fix a typo in the checks header file + - CLEANUP: Fix typos in the file descriptor subsystem + - CLEANUP: Fix a typo in the listener subsystem + - BUG/MINOR: lb-map: fix unprotected update to server's score + - BUILD: threads: fix minor build warnings when threads are disabled + +2018/11/25 : 1.9-dev8 + - REORG: config: extract the global section parser into cfgparse-global + - REORG: config: extract the proxy parser into cfgparse-listen.c + - BUILD: update the list of supported targets and compilers in makefile and readme + - BUILD: reorder the objects in the makefile + - BUILD: Makefile: make "V=1" show some of the commands that are executed + - BUILD: Makefile: add the quiet mode to a few more targets + - BUILD: Makefile: add "$(Q)" to clean, tags and cscope targets + - BUILD: Makefile: switch to quiet mode by default for CC/LD/AR + - MINOR: cli: format `show proc` to be more readable + - MINOR: cli: displays uptime in `show proc` + - MINOR: cli: show master information in 'show proc' + - BUG/MEDIUM: hpack: fix encoding of "accept-ranges" field + - MAJOR: mux-h1: Remove the rxbuf and decode HTTP messages in channel's buffer + - BUG/MINOR: mux-h1: Enable keep-alive on server side + - BUG/MEDIUM: mux-h1: Fix freeze when the kernel splicing is used + - BUG/MEDIUM: mux-h1: Don't set the flag CS_FL_RCV_MORE when nothing was parsed + - BUG/MINOR: stats/htx: Remove channel's output when the request is eaten + - BUG/MINOR: proto_htx: Fix request/response synchronisation on error + - MINOR: stream-int: Notify caller when an error is reported after a rcv_pipe() + - MINOR: stream-int: Notify caller when an error is reported after a rcv_buf() + - BUG/MINOR: stream-int: Don't call snd_buf() if there are still data in the pipe + - MINOR: stream-int: remove useless checks on CS and conn flags in si_cs_send() + - BUG/MINOR: config: Be aware of the HTX during the check of mux protocols + - BUG/MINOR: mux-htx: Fix bad test on h1c flags in h1_recv_allowed() + - MEDIUM: mworker: wait mode use standard init code path + - MINOR: log: introduce ha_notice() + - MINOR: mworker: use ha_notice to announce a new worker + - BUG/MEDIUM: http_fetch: Make sure name is initialized before http_find_header. + - MINOR: cli: add mworker_accept_wrapper to 'show fd' + - MEDIUM: signal: signal_unregister() removes every handlers + - BUG/MEDIUM: mworker: unregister the signals of main() + - MINOR: cli: add a few missing includes in proto/cli.h + - REORG: time/activity: move activity measurements to activity.{c,h} + - MINOR: activity: report the average loop time in "show activity" + - MINOR: activity: add configuration and CLI support for "profiling.tasks" + - MEDIUM: tasks: collect per-task CPU time and latency + - MINOR: sample: add cpu_calls, cpu_ns_avg, cpu_ns_tot, lat_ns_avg, lat_ns_tot + - MINOR: cli/activity: rename the stolen CPU time fields to mention milliseconds + - BUG/MINOR: cli: Fix memory leak + - BUG/MINOR: mworker: fix FD leak and memory leak in error path + - MINOR: poller: move the call of tv_update_date() back to the pollers + - MINOR: polling: add an option to support busy polling + - MINOR: server: Add "alpn" and "npn" keywords. + - MEDIUM: connection: Don't bother reactivating polling after connection retry. + - MAJOR: connections: Defer mux creation for outgoing connection if alpn is set. + - MEDIUM: ssl: Add ssl_bc_alpn and ssl_bc_npn sample fetches. + - MINOR: servers: Free [idle|safe|priv]_conns on exit. + - REGTEST: add the option to test only a specific set of files + - REGTEST: add a test for connections to a "dispatch" address + - BUG/MEDIUM: connections: Don't reset the conn flags in *connect_server(). + - MINOR: server: Only defined conn_complete_server if USE_OPENSSL is set. + - BUG/MEDIUM: servers: Don't check if we have a conn_stream too soon. + - BUG/MEDIUM: sessions: Set sess->origin to NULL if the origin was destroyed. + - MEDIUM: servers: Store the connection in the SI until we have a mux. + - BUG/MEDIUM: h2: wake the processing task up after demuxing + - BUG/MEDIUM: h2: restart demuxing after releasing buffer space + +2018/11/18 : 1.9-dev7 + - BUILD: cache: fix a build warning regarding too large an integer for the age + - CLEANUP: fix typos in the comments of the Makefile + - CLEANUP: fix a typo in a comment for the contrib/halog subsystem + - CLEANUP: fix typos in comments for the contrib/modsecurity subsystem + - CLEANUP: fix typos in comments for contrib/spoa_example + - CLEANUP: fix typos in comments for contrib/wireshark-dissectors + - DOC: Fix typos in README and CONTRIBUTING + - MINOR: log: slightly improve error message syntax on log failure + - DOC: logs: the format directive was missing from the second log part + - MINOR: log: report the number of dropped logs in the stats + - MEDIUM: log: add support for logging to existing file descriptors + - MEDIUM: log: support a new "short" format + - MEDIUM: log: add a new "raw" format + - BUG/MEDIUM: stream-int: change the way buffer room is requested by a stream-int + - BUG/MEDIUM: stream-int: convert some co_data() checks to channel_is_empty() + - MINOR: namespaces: don't build namespace.c if disabled + - BUILD/MEDIUM: threads/affinity: DragonFly build fix + - MINOR: http: Add new "early-hint" http-request action. + - MINOR: http: Make new "early-hint" http-request action really be parsed. + - MINOR: http: Implement "early-hint" http request rules. + - MINOR: doc: Add information about "early-hint" http-request action. + - DOC: early-hints: fix truncated line. + - MINOR: mworker: only close std{in,out,err} in daemon mode + - BUG/MEDIUM: log: don't CLOEXEC the inherited FDs + - BUG/MEDIUM: Make sure stksess is properly aligned. + - BUG/MEDIUM: stream-int: make failed splice_in always subscribe to recv + - BUG/MEDIUM: stream-int: clear CO_FL_WAIT_ROOM after splicing data in + - BUG/MINOR: stream-int: make sure not to go through the rcv_buf path after splice() + - CONTRIB: debug: fix build related to conn_stream flags change + - REGTEST: fix scripts 1 and 3 to accept development version + - BUG/MINOR: http_fetch: Remove the version part when capturing the request uri + - MINOR: http: Regroup return statements of http_req_get_intercept_rule at the end + - MINOR: http: Regroup return statements of http_res_get_intercept_rule at the end + - BUG/MINOR: http: Be sure to sent fully formed HTTP 103 responses + - MEDIUM: jobs: support unstoppable jobs for soft stop + - MEDIUM: listeners: support unstoppable listener + - MEDIUM: cli: worker socketpair is unstoppable + - BUG/MINOR: stream-int: set SI_FL_WANT_PUT in sess_establish() + - MINOR: stream: move the conn_stream specific calls to the stream-int + - BUG/MINOR: config: Copy default error messages when parsing of a backend starts + - CLEANUP: h2: minimum documentation for recent API changes + - MINOR: mux: implement a get_first_cs() method + - MINOR: stream-int: make conn_si_send_proxy() use cs_get_first() + - MINOR: stream-int: relax the forwarding rules in stream_int_notify() + - MINOR: stream-int: expand the flags to 32-bit + - MINOR: stream-int: rename SI_FL_WAIT_ROOM to SI_FL_RXBLK_ROOM + - MINOR: stream-int: introduce new SI_FL_RXBLK flags + - MINOR: stream-int: add new functions si_{rx,tx}_{blocked,endp_ready}() + - MINOR: stream-int: replace SI_FL_WANT_PUT with !SI_FL_RX_WAIT_EP + - MINOR: stream-int: use si_rx_blocked()/si_tx_blocked() to check readiness + - MEDIUM: stream-int: use si_rx_buff_{rdy,blk} to report buffer readiness + - MINOR: stream-int: replace si_{want,stop}_put() with si_rx_endp_{more,done}() + - MEDIUM: stream-int: update the endp polling status only at the end of si_cs_recv() + - MINOR: stream-int: make si_sync_recv() simply check ENDP before si_cs_recv() + - MINOR: stream-int: automatically mark applets as ready if they block on the channel + - MEDIUM: stream-int: fix the si_cant_put() calls used for end point readiness + - MEDIUM: stream-int: fix the si_cant_put() calls used for buffer readiness + - MEDIUM: stream-int: use si_rx_shut_blk() to indicate the SI is closed + - MEDIUM: stream-int: unconditionally call si_chk_rcv() in update and notify + - MEDIUM: stream-int: make use of si_rx_chan_{rdy,blk} to control the stream-int from the channel + - MINOR: stream-int: replace si_cant_put() with si_rx_room_{blk,rdy}() + - MEDIUM: connections: Wait until the connection is established to try to recv. + - MEDIUM: mux: Teach the mux_pt how to deal with idle connections. + - MINOR: mux: Add a new "avail_streams" method. + - MINOR: mux: Add a destroy() method. + - MINOR: sessions: Start to store the outgoing connection in sessions. + - MAJOR: connections: Detach connections from streams. + - MINOR: conn_stream: Add a flag to notify the mux it should flush its buffers + - MINOR: htx: Add proto_htx.c file + - MINOR: conn_stream: Add a flag to notify the mux it must respect the reserve + - MINOR: http: Add standalone functions to parse a start-line or a header + - MINOR: http: Call http_send_name_header with the stream instead of the txn + - MINOR: conn_stream: Add a flag to notify the SI some data were received + - MINOR: http: Add macros to check if a stream uses the HTX representation + - MEDIUM: proto_htx: Add HTX analyzers and use it when the mux H1 is used + - MEDIUM: mux-h1: Add dummy mux to handle HTTP/1.1 connections + - MEDIUM: mux-h1: Add parsing of incoming and ougoing HTTP messages + - MAJOR: mux-h1/proto_htx: Handle keep-alive connections in the mux + - MEDIUM: mux-h1: Add support of the kernel TCP splicing to forward data + - MEDIUM: htx: Add API to deal with the internal representation of HTTP messages + - MINOR: http_htx: Add functions to manipulate HTX messages in http_htx.c + - MINOR: proto_htx: Add some functions to handle HTX messages + - MAJOR: mux-h1/proto_htx: Switch mux-h1 and HTX analyzers on the HTX representation + - MINOR: http_htx: Add functions to replace part of the start-line + - MINOR: http_htx: Add functions to retrieve a specific occurrence of a header + - MINOR: proto_htx: Rewrite htx_apply_redirect_rule to handle HTX messages + - MINOR: proto_htx: Add the internal function htx_del_hdr_value + - MINOR: proto_htx: Add the internal function htx_fmt_res_line + - MINOR: proto_htx: Add functions htx_transform_header and htx_transform_header_str + - MINOR: proto_htx: Add functions htx_req_replace_stline and htx_res_set_status + - MINOR: proto_htx: Add function to build and send HTTP 103 responses + - MINOR: proto_htx: Add functions htx_req_get_intercept_rule and htx_res_get_intercept_rule + - MINOR: proto_htx: Add functions to apply req* and rsp* rules on HTX messages + - MINOR: proto_htx: Add functions to manage cookies on HTX messages + - MINOR: proto_htx: Add functions to check the cacheability of HTX messages + - MINOR: proto_htx: Add functions htx_send_name_header + - MINOR: proto_htx: Add functions htx_perform_server_redirect + - MINOR: proto_htx: Add functions to handle the stats applet + - MEDIUM: proto_htx: Adapt htx_process_req_common to handle HTX messages + - MEDIUM: proto_htx: Adapt htx_process_request to handle HTX messages + - MINOR: proto_htx: Adapt htx_process_tarpit to handle HTX messages + - MEDIUM: proto_htx: Adapt htx_wait_for_request_body to handle HTX messages + - MEDIUM: proto_htx: Adapt htx_process_res_common to handle HTX messages + - MINOR: http_fetch: Add smp_prefetch_htx + - MEDIUM: http_fetch: Adapt all fetches to handle HTX messages + - MEDIUM: mux-h1: Wait for connection establishment before consuming channel's data + - MINOR: stats/htx: Adapt the stats applet to handle HTX messages + - MINOR: stream: Don't reset sov value with HTX messages + - MEDIUM: mux-h1: Handle errors and timeouts in the stream + - MINOR: filters/htx: Forbid filters when the HTX is enabled on a proxy + - MINOR: lua/htx: Forbid lua usage when the HTX is enabled on a proxy + - CLEANUP: Fix some typos in the haproxy subsystem + - CLEANUP: Fix typos in the dns subsystem + - CLEANUP: Fix typos in the pattern subsystem + - CLEANUP: fix 2 typos in the xxhash subsystem + - CLEANUP: fix a few typos in the comments of the server subsystem + - CLEANUP: fix a misspell in tests/filltab25.c + - CLEANUP: fix a typo found in the stream subsystem + - CLEANUP: fix typos in comments in ebtree + - CLEANUP: fix typos in reg-tests + - CLEANUP: fix typos in the comments of the vars subsystem + - CLEANUP: fix typos in the hlua_fcn subsystem + - CLEANUP: fix typos in the proto_http subsystem + - CLEANUP: fix typos in the proxy subsystem + - CLEANUP: fix typos in the ssl_sock subsystem + - DOC: Fix typos in different subsections of the documentation + - DOC: fix a few typos in the documentation + - MINOR: Fix an error message thrown when we run out of memory + - MINOR: Fix typos in error messages in the proxy subsystem + - MINOR: fix typos in the examples files + - CLEANUP: Fix a typo in the stats subsystem + - CLEANUP: Fix typos in the acl subsystem + - CLEANUP: Fix typos in the cache subsystem + - CLEANUP: Fix typos in the cfgparse subsystem + - CLEANUP: Fix typos in the filters subsystem + - CLEANUP: Fix typos in the http subsystem + - CLEANUP: Fix typos in the log subsystem + - CLEANUP: Fix typos in the peers subsystem + - CLEANUP: Fix typos in the regex subsystem + - CLEANUP: Fix typos in the sample subsystem + - CLEANUP: Fix typos in the spoe subsystem + - CLEANUP: Fix typos in the standard subsystem + - CLEANUP: Fix typos in the stick_table subsystem + - CLEANUP: Fix typos in the task subsystem + - MINOR: Fix typo in error message in the standard subsystem + - CLEANUP: fix typos in the comments of hlua + - MINOR: Fix typo in the error 500 output of hlua + - MINOR: Fix a typo in a warning message in the spoe subsystem + +2018/11/11 : 1.9-dev6 + - BUG/MEDIUM: tools: fix direction of my_ffsl() + - BUG/MINOR: cli: forward the whole command on master CLI + - BUG/MEDIUM: auth/threads: use of crypt() is not thread-safe + - MINOR: compat: automatically detect support for crypt_r() + - MEDIUM: auth/threads: make use of crypt_r() on systems supporting it + - DOC: split the http-request actions in their own section + - DOC: split the http-response actions in their own section + - BUG/MAJOR: stream-int: don't call si_cs_recv() in stream_int_chk_rcv_conn() + - BUG/MINOR: tasks: make sure wakeup events are properly reported to subscribers + - MINOR: stats: report the number of active jobs and listeners in "show info" + - MINOR: stats: report the number of active peers in "show info" + - MINOR: stats: report the number of currently connected peers + - MINOR: cli: show the number of reload in 'show proc' + - MINOR: cli: can't connect to the target CLI + - MEDIUM: mworker: does not create the CLI proxy when no listener + - MINOR: mworker: displays more information when leaving + - MEDIUM: mworker: exit with the incriminated exit code + - MINOR: mworker: displays a message when a worker is forked + - MEDIUM: mworker: leave when the master die + - CLEANUP: stream-int: retro-document si_cs_io_cb() + - BUG/MEDIUM: mworker: does not abort() in mworker_pipe_register() + - BUG/MEDIUM: stream-int: don't wake up for nothing during SI_ST_CON + - BUG/MEDIUM: cli: crash when trying to access a worker + - DOC: restore note about "independant" typo + - MEDIUM: stream: implement stream_buf_available() + - MEDIUM: appctx: check for allocation attempts in buffer allocation callbacks + - MINOR: stream-int: rename si_applet_{want|stop|cant}_{get|put} + - MINOR: stream-int: add si_done_{get,put} to indicate that we won't do it anymore + - MINOR: stream-int: use si_cant_put() instead of setting SI_FL_WAIT_ROOM + - MINOR: stream-int: make use of si_done_{get,put}() in shut{w,r} + - MINOR: stream-int: make it clear that si_ops cannot be null + - MEDIUM: stream-int: temporarily make si_chk_rcv() take care of SI_FL_WAIT_ROOM + - MINOR: stream-int: factor the SI_ST_EST state test into si_chk_rcv() + - MEDIUM: stream-int: make SI_FL_WANT_PUT reflect CF_DONT_READ + - MEDIUM: stream-int: always call si_chk_rcv() when we make room in the buffer + - MEDIUM: stream-int: make si_chk_rcv() check that SI_FL_WAIT_ROOM is cleared + - MINOR: stream-int: replace si_update() with si_update_both() + - MEDIUM: stream-int: make stream_int_update() aware of the lower layers + - CLEANUP: stream-int: remove the now unused si->update() function + - MEDIUM: stream-int: Rely only on SI_FL_WAIT_ROOM to stop data receipt + - MEDIUM: stream-int: Try to read data even if channel's buffer seems to be full + - BUG/MINOR: config: better detect the presence of the h2 pattern in npn/alpn + +2018/10/28 : 1.9-dev5 + - BUILD: Makefile: add the new ERR variable to force -Werror + - MINOR: freq_ctr: add swrate_add_scaled() to work with large samples + - MINOR: stream_interface: Avoid calling si_cs_send/recv if not needed. + - CLEANUP: http: Remove the unused function http_find_header + - MINOR: h1: Export some functions parsing the value of some HTTP headers + - BUG/MEDIUM: stream-int: don't set SI_FL_WAIT_ROOM on CF_READ_DONTWAIT + - MINOR: proxy: add a new option "http-use-htx" + - BUG/MEDIUM: pools: fix the minimum allocation size + - MINOR: shctx: Shared objects block by block allocation. + - MINOR: cache: Larger HTTP objects caching. + - MINOR: shctx: Add a maximum object size parameter. + - MINOR: cache: Add "max-object-size" option. + - DOC: Update about the cache support for big objects. + - BUG/MINOR: cache: Crashes with "total-max-size" > 2047(MB). + - BUG/MINOR: cache: Wrong usage of shctx_init(). + - BUG/MINOR: ssl: Wrong usage of shctx_init(). + - MINOR: cache: Avoid usage of atoi() when parsing "max-object-size". + - MINOR: shctx: Change max. object size type to unsigned int. + - DOC: cache: Missing information about "total-max-size" and "max-object-size" + - CLEANUP: tools: fix misleading comment above function LIM2A + - MEDIUM: channel: merge back flags CF_WRITE_PARTIAL and CF_WRITE_EVENT + - BUG/MINOR: only mark connections private if NTLM is detected + - BUG/MINOR: only auto-prefer last server if lb-alg is non-deterministic + - MINOR: stream: don't prune variables if the list is empty + - MINOR: stream-int: add si_alloc_ibuf() to ease input buffer allocation + - MEDIUM: stream-int: replace channel_alloc_buffer() with si_alloc_ibuf() everywhere + - MEDIUM: stream: always call si_cs_recv() after a failed buffer allocation + - MEDIUM: stream: don't try to send first in process_stream() + - MEDIUM: stream-int: make si_update() synchronize flag changes before the I/O + - MEDIUM: stream-int: call si_cs_process() in stream_int_update_conn + - MINOR: stream-int: don't needlessly call tasklet_wakeup() in stream_int_chk_snd_conn() + - MINOR: stream-int: make stream_int_notify() not wake the tasklet up + - MINOR: stream-int: don't needlessly call si_cs_send() in si_cs_process() + - MINOR: mworker: number of reload in the life of a worker + - MEDIUM: mworker: each worker socketpair is a CLI listener + - REORG: mworker: move struct mworker_proc to global.h + - MINOR: server: export new_server() function + - MEDIUM: mworker: move proc_list gen before proxies startup + - MEDIUM: mworker: add proc_list in global.h + - MEDIUM: mworker: proxy for the master CLI + - MEDIUM: mworker: create CLI listeners from argv[] + - MEDIUM: cli: disable some keywords in the master + - MEDIUM: mworker: find the server ptr using a CLI prefix + - MEDIUM: cli: 'show proc' displays processus + - MEDIUM: cli: implement 'mode cli' proxy analyzers + - MINOR: cli: displays sockpair@ in "show cli sockets" + - MEDIUM: cli: enable "show cli sockets" for the master + - MINOR: cli: put @master @ @! in the help + - MEDIUM: listeners: set O_CLOEXEC on the accepted FDs + - MEDIUM: mworker: stop the master proxy in the workers + - MEDIUM: channel: reorder the channel analyzers for the cli + - MEDIUM: cli: write a prompt for the CLI proxy of the master + - MINOR: cli: helper to write an response message and close + - MINOR: cache: Add "Age" header. + - REGTEST: make the IP+port logging test more reliable + - BUG/MINOR: memory: make the thread-local cache allocator set the debugging link + - BUG/MAJOR: http: http_txn_get_path() may deference an inexisting buffer + - BUG/MINOR: backend: assign the wait list after the error check + +2018/10/21 : 1.9-dev4 + - BUILD: Allow configuration of pcre-config path + - DOC: clarify force-private-cache is an option + - BUG/MINOR: connection: avoid null pointer dereference in send-proxy-v2 + - REORG: http: move the code to different files + - REORG: http: move HTTP rules parsing to http_rules.c + - CLEANUP: http: remove some leftovers from recent cleanups + - BUILD: Makefile: add a "make opts" target to simply show the build options + - BUILD: Makefile: speed up compiler options detection + - BUG/MINOR: backend: check that the mux installed properly + - BUG/MEDIUM: h2: check that the connection is still valid at the end of init() + - BUG/MEDIUM: h2: make h2_stream_new() return an error on memory allocation failure + - REGTEST/MINOR: compatibility: use unix@ instead of abns@ sockets + - MINOR: ssl: cleanup old openssl API call + - MINOR: ssl: generate-certificates for BoringSSL + - BUG/MEDIUM: buffers: Make sure we don't wrap in ci_insert_line2/b_rep_blk. + - MEDIUM: ssl: add support for ciphersuites option for TLSv1.3 + - CLEANUP: haproxy: Remove unused variable + - CLEANUP: h1: Fix debug warnings for h1 headers + - CLEANUP: stick-tables: Remove unneeded double (()) around conditional clause + - MEDIUM: task: perform a single tree lookup per run queue batch + - BUG/MEDIUM: Cur/CumSslConns counters not threadsafe. + - BUG/MINOR: threads: move declaration of capabilities to config.h + - OPTIM: tools: optimize my_ffsl() for x86_64 + - BUG/MINOR: h2: null-deref + - BUG/MINOR: checks: queues null-deref + - MINOR: connections: Introduce an unsubscribe method. + - MEDIUM: connections: Change struct wait_list to wait_event. + - BUG/MEDIUM: h2: Make sure we're not in the send list on flow control. + - BUG/MEDIUM: mworker: segfault receiving SIGUSR1 followed by SIGTERM. + - BUG/MEDIUM: stream: Make sure to unsubscribe before si_release_endpoint. + - MINOR: http: Move comment about some HTTP macros in the right header file + - MINOR: stats: Add missing include + - MINOR: http: Export some functions and do cleanup to prepare HTTP refactoring + - MEDIUM: http: Ignore http-pretend-keepalive option on frontend + - MEDIUM: http: Ignore http-tunnel option on backend + - MINOR: http: Use same flag for httpclose and forceclose options + - MINOR: h1: Add EOH marker during headers parsing + - MINOR: conn-stream: Add CL_FL_NOT_FIRST flag + - MINOR: h1: Change the union h1_sl to use indirect strings to store infos + - MINOR: h1: Add the flag H1_MF_NO_PHDR to not add pseudo-headers during parsing + - MINOR: log: make sess_log() support sess=NULL + - MINOR: chunk: add chunk_cpy() and chunk_cat() + - MEDIUM: h2: stop relying on H2_SS_IDLE / H2_SS_CLOSED + - CLEANUP: h2: rename h2c_snd_settings() to h2c_send_settings() + - MINOR: h2: don't try to send data before preface + - MINOR: h2: unify the mux init function + - MINOR: h2: retrieve the front proxy from the caller instead of the session + - MINOR: h2: split h2c_stream_new() into h2s_new() + h2c_frt_stream_new() + - MINOR: h2: add a new flag to quickly distinguish front vs back connection + - BUG/MEDIUM: mworker: don't poll on LI_O_INHERITED listeners + - BUG/MEDIUM: stream: don't crash on out-of-memory + - BUILD: compiler: add a new statement "__unreachable()" + - BUILD: lua: silence some compiler warnings about potential null derefs + - BUILD: ssl: fix null-deref warning in ssl_fc_cipherlist_str sample fetch + - BUILD: ssl: fix another null-deref warning in ssl_sock_switchctx_cbk() + - BUILD: stick-table: make sure not to fail on task_new() during initialization + - BUILD: peers: check allocation error during peers_init_sync() + - MINOR: tools: add a new function atleast2() to test masks for more than 1 bit + - MINOR: config: use atleast2() instead of my_popcountl() where relevant + - MEDIUM: fd/threads: only grab the fd's lock if the FD has more than one thread + - MAJOR: tasks: create per-thread wait queues + - OPTIM: tasks: group all tree roots per cache line + - DOC: Fix a few typos + - MINOR: pools: allocate most memory pools from an array + - MINOR: pools: split pool_free() in the lockfree variant + - MEDIUM: pools: implement a thread-local cache for pool entries + - BUG/MEDIUM: threads: fix thread_release() at the end of the rendez-vous point + - Revert "BUILD: lua: silence some compiler warnings about potential null derefs" + - BUILD: lua: silence some compiler warnings about potential null derefs (#2) + - MINOR: lua: all functions calling lua_yieldk() may return + - BUILD: lua: silence some compiler warnings after WILL_LJMP + - BUILD: Makefile: silence an option conflict warning with clang + - MINOR: server: Use memcpy() instead of strncpy(). + - CLEANUP: state-file: make the path concatenation code a bit more consistent + - MINOR: build: Disable -Wstringop-overflow. + - MINOR: cfgparse: Write 130 as 128 as 0x82 and 0x80. + - MINOR: peers: use defines instead of enums to appease clang. + - DOC: fix reference to map files in MAINTAINERS + - MINOR: fd: centralize poll timeout computation in compute_poll_timeout() + - MINOR: poller: move time and date computation out of the pollers + - BUILD: memory: fix pointer declaration for atomic CAS + - BUILD: Makefile: add USE_RT to pass -lrt for clock_gettime() and friends + - MINOR: time: add now_mono_time() and now_cpu_time() + - MEDIUM: time: measure the time stolen by other threads + - BUILD: memory: fix free_list pointer declaration again for atomic CAS + - BUILD: compiler: rename __unreachable() to my_unreachable() + - BUG/MEDIUM: pools: Fix the usage of mmap()) with DEBUG_UAF. + - BUILD: memory: fix free_list pointer declaration again for atomic CAS + - BUG/MEDIUM: h2: Close connection if no stream is left an GOAWAY was sent. + - BUG/MEDIUM: connections: Remove subscription if going in idle mode. + - BUG/MEDIUM: stream: Make sure polling is right on retry. + - MINOR: h2: Make sure to return 1 in h2_recv() when needed. + - MEDIUM: connections: Don't directly mess with the polling from the upper layers. + - MINOR: streams: Call tasklet_free() after si_release_endpoint(). + - MINOR: connection: Add a SUB_CALL_UNSUBSCRIBE event. + - MINOR: h2: Don't run tasks that are waiting to send if mux in full. + - MINOR: ebtree: save 8 bytes in struct eb32sc_node + +2018/09/29 : 1.9-dev3 + - BUG/MINOR: h1: don't consider the status for each header + - MINOR: h1: report in the h1m struct if the HTTP version is 1.1 or above + - MINOR: h1: parse the Connection header field + - DOC: Fix typos in lua documentation + - MINOR: h1: Add H1_MF_XFER_LEN flag + - MINOR: http: add http_hdr_del() to remove a header from a list + - MINOR: h1: add headers to the list after controls, not before + - MEDIUM: h1: better handle transfer-encoding vs content-length + - MEDIUM: h1: deduplicate the content-length header + - BUG/MEDIUM: patterns: fix possible double free when reloading a pattern list + - BUG/MEDIUM: h1: Really skip all updates when incomplete messages are parsed + - CLEANUP/CONTRIB: hpack: remove some h1 build warnings + - BUG/MINOR: tools: fix set_net_port() / set_host_port() on IPv4 + - BUG/MINOR: cli: make sure the "getsock" command is only called on connections + - MINOR: stktable: provide an unchecked version of stktable_data_ptr() + - MINOR: stream-int: make si_appctx() never fail + - BUILD: ssl_sock: remove build warnings on potential null-derefs + - BUILD: stats: remove build warnings on potential null-derefs + - BUILD: stream: address null-deref build warnings at -Wextra + - BUILD: http: address a couple of null-deref warnings at -Wextra + - BUILD: log: silent build warnings due to unchecked __objt_{server,applet} + - BUILD: dns: fix null-deref build warning at -Wextra + - BUILD: checks: silence a null-deref build warning at -Wextra + - BUILD: connection: silence a couple of null-deref build warnings at -Wextra + - BUILD: backend: fix 3 build warnings related to null-deref at -Wextra + - BUILD: sockpair: silence a build warning at -Wextra + - BUILD: build with -Wextra and sort out certain warnings + - BUG/CRITICAL: hpack: fix improper sign check on the header index value + - BUG/MEDIUM: http: Don't parse chunked body if there is no input data + - DOC: Update configuration doc about the maximum number of stick counters. + - BUG/MEDIUM: process_stream: Don't use si_cs_io_cb() in process_stream(). + - MINOR: h2/stream_interface: Reintroduce te wake() method. + - BUG/MEDIUM: h2: Wake the task instead of calling h2_recv()/h2_process(). + - BUG/MEDIUM: process_stream(): Don't wake the task if no new data was received. + - MEDIUM: lua: Add stick table support for Lua. + +2018/09/12 : 1.9-dev2 + - BUG/MINOR: buffers: Fix b_slow_realign when a buffer is realign without output + - BUG/MEDIUM: threads: fix the no-thread case after the change to the sync point + - BUG/MEDIUM: servers: check the queues once enabling a server + - BUG/MEDIUM: queue: prevent a backup server from draining the proxy's connections + - MEDIUM: mux: Remove const on the buffer in mux->snd_buf() + - CLEANUP: backend: Move mux install to call it at only one place + - MINOR: conn_stream: add an tx buffer to the conn_stream + - MINOR: conn_stream: add cs_send() as a default snd_buf() function + - MINOR: backend: Try to find the best mux for outgoing connections + - MEDIUM: backend: don't rely on mux_pt_ops in connect_server() + - MINOR: mux: Add info about the supported side in alpn_mux_list structure + - MINOR: mux: Unlink ALPN and multiplexers to rather speak of mux protocols + - MINOR: mux: Print the list of existing mux protocols during HA startup + - MEDIUM: checks: use the new rendez-vous point to spread check result + - MEDIUM: haproxy: don't use sync_poll_loop() anymore in the main loop + - MINOR: threads: remove the previous synchronization point + - MAJOR: server: make server state changes synchronous again + - CLEANUP: server: remove the update list and the update lock + - BUG/MINOR: threads: Remove the unexisting lock label "UPDATED_SERVERS_LOCK" + - BUG/MEDIUM: stream_int: Don't check CO_FL_SOCK_RD_SH flag to trigger cs receive + - MINOR: mux: Change get_mux_proto to get an ist as parameter + - MINOR: mux: Improve the message with the list of existing mux protocols + - MINOR: mux/frontend: Add 'proto' keyword to force the mux protocol + - MINOR: mux/server: Add 'proto' keyword to force the multiplexer's protocol + - MEDIUM: mux: Use the mux protocol specified on bind/server lines + - BUG/MEDIUM: connection/mux: take care of serverless proxies + - MINOR: queue: make sure the pendconn is released before logging + - MINOR: stream: rename {srv,prx}_queue_size to *_queue_pos + - MINOR: queue: store the queue index in the stream when enqueuing + - MINOR: queue: replace the linked list with a tree + - MEDIUM: add set-priority-class and set-priority-offset + - MEDIUM: queue: adjust position based on priority-class and priority-offset + - DOC: update the roadmap about priority queues + - BUG/MINOR: ssl: empty connections reported as errors. + - MINOR: connections: Make rcv_buf mandatory and nuke cs_recv(). + - MINOR: connections: Move rxbuf from the conn_stream to the h2s. + - MINOR: connections: Get rid of txbuf. + - MINOR: tasks: Allow tasklet_wakeup() to wakeup a task. + - MINOR: connections/mux: Add the wait reason(s) to wait_list. + - MINOR: stream_interface: Don't use si_cs_send() as a task handler. + - MINOR: stream_interface: Give stream_interface its own wait_list. + - MINOR: mux_h2: Don't use h2_send() as a callback. + - MINOR: checks: Add event_srv_chk_io(). + - BUG/MEDIUM: tasks: Don't insert in the global rqueue if nbthread == 1 + - BUG/MEDIUM: sessions: Don't use t->state. + - BUG/MEDIUM: ssl: fix missing error loading a keytype cert from a bundle. + - BUG/MEDIUM: ssl: loading dh param from certifile causes unpredictable error. + - BUG/MINOR: map: fix map_regm with backref + - DOC: dns: explain set server ... fqdn requires resolver + - DOC: add documentation for prio_class and prio_offset sample fetches. + - DOC: ssl: Use consistent naming for TLS protocols + - DOC: update the layering design notes + - MINOR: tasks: Don't special-case when nbthreads == 1 + - MINOR: fd cache: And the thread_mask with all_threads_mask. + - BUG/MEDIUM: lua: socket timeouts are not applied + - BUG/MINOR: lua: fix extra 500ms added to socket timeouts + - BUG/MEDIUM: server: update our local state before propagating changes + - BUG/MEDIUM: cli/threads: protect all "proxy" commands against concurrent updates + - DOC: server/threads: document which functions need to be called with/without locks + - BUG/MEDIUM: cli/threads: protect some server commands against concurrent operations + - BUG/MEDIUM: streams: Don't forget to remove the si from the wait list. + - BUG/MEDIUM: tasklets: Add the thread as active when waking a tasklet. + - BUG/MEDIUM: stream-int: Check if the conn_stream exist in si_cs_io_cb. + - BUG/MEDIUM: H2: Activate polling after successful h2_snd_buf(). + - BUG/MEDIUM: stream_interface: Call the wake callback after sending. + - BUG/MAJOR: queue/threads: make pendconn_redistribute not lock the server + - BUG/MEDIUM: connection: don't forget to always delete the list's head + - BUG/MEDIUM: lb/threads: always properly lock LB algorithms on maintenance operations + - BUG/MEDIUM: check/threads: do not involve the rendez-vous point for status updates + - BUG/MINOR: chunks: do not store -1 into chunk_printf() in case of error + - BUG/MEDIUM: http: don't store exp_replace() result in the trash's length + - BUG/MEDIUM: http: don't store url_decode() result in the samples's length + - BUG/MEDIUM: dns: don't store dns_build_query() result in the trash's length + - BUG/MEDIUM: map: don't store exp_replace() result in the trash's length + - BUG/MEDIUM: connection: don't store recv() result into trash.data + - BUG/MEDIUM: cli/ssl: don't store base64dec() result in the trash's length + - MINOR: chunk: remove impossible tests on negative chunk->data + - MINOR: sample: remove impossible tests on negative smp->data.u.str.data + - DOC: Fix spelling error in configuration doc + - REGTEST/MINOR: Missing mandatory "ignore_unknown_macro". + - REGTEST/MINOR: Add a new class of regression testing files. + - BUG/MEDIUM: unix: provide a ->drain() function + - MINOR: connection: make conn_sock_drain() work for all socket families + - BUG/MINOR: lua: Bad HTTP client request duration. + - REGEST/MINOR: Add reg testing files. + - BUG/MEDIUM: mux_pt: dereference the connection with care in mux_pt_wake() + - REGTEST/MINOR: Add a reg testing file for b406b87 commit. + - BUG/MEDIUM: lua: reset lua transaction between http requests + - MINOR: add be_conn_free sample fetch + - MINOR: Add srv_conn_free sample fetch + - BUG/MEDIUM: hlua: Make sure we drain the output buffer when done. + - MINOR: checks: Call wake_srv_chk() when we can finally send data. + - BUG/MEDIUM: stream_interface: try to call si_cs_send() earlier. + - BUG/MAJOR: thread: lua: Wrong SSL context initialization. + - REGTEST/MINOR: Add a reg testing file for 3e60b11. + - BUG/MEDIUM: hlua: Don't call RESET_SAFE_LJMP if SET_SAFE_LJMP returns 0. + - REGTEST/MINOR: lua: Add reg testing files for 70d318c. + - BUG/MEDIUM: dns/server: fix incomatibility between SRV resolution and server state file + - BUG/MEDIUM: ECC cert should work with TLS < v1.2 and openssl >= 1.1.1 + - MINOR: tools: make date2str_log() take some consts + - MINOR: thread: implement HA_ATOMIC_XADD() + - BUG/MINOR: stream: use atomic increments for the request counter + - BUG/MEDIUM: session: fix reporting of handshake processing time in the logs + - BUG/MEDIUM: h2: fix risk of memory leak on malformated wrapped frames + - BUG/MAJOR: buffer: fix incorrect check in __b_putblk() + - MINOR: log: move the log code to sess_build_logline() to add extra arguments + - MINOR: log: make the backend fall back to the frontend when there's no stream + - MINOR: log: make sess_build_logline() not dereference a NULL stream for txn + - MINOR: log: don't unconditionally pick log info from s->logs + - CLEANUP: log: make the low_level lf_{ip,port,text,text_len} functions take consts + - MINOR: log: keep a copy of the backend connection early in sess_build_logline() + - MINOR: log: do not dereference a null stream to access captures + - MINOR: log: be sure not to dereference a null stream for a target + - MINOR: log: don't check the stream-int's conn_retries if the stream is NULL + - MINOR: log: use NULL for the unique_id if there is no stream + - MINOR: log: keep a copy of s->flags early to avoid a dereference + - MINOR: log: use zero as the request counter if there is no stream + - MEDIUM: log: make sess_build_logline() support being called with no stream + - MINOR: log: provide a function to emit a log for a session + - MEDIUM: h2: produce some logs on early errors that prevent streams from being created + - BUG/MINOR: h1: fix buffer shift after realignment + - MINOR: connection: make the initialization more consistent + - MINOR: connection: add new function conn_get_proxy() + - MINOR: connection: add new function conn_is_back() + - MINOR: log: One const should be enough. + - BUG/MINOR: dns: check and link servers' resolvers right after config parsing + - BUG/MINOR: http/threads: atomically increment the error snapshot ID + - MINOR: snapshot: restart on the event ID and not the stream ID + - MINOR: snapshot: split the error snapshots into common and proto-specific parts + - MEDIUM: snapshot: start to reorder the HTTP snapshot output a little bit + - MEDIUM: snapshot: implement a show() callback and use it for HTTP + - MINOR: proxy: add a new generic proxy_capture_error() + - MINOR: http: make the HTTP error capture rely on the generic proxy code + - MINOR: http: remove the pointer to the error snapshot in http_capture_bad_message() + - REORG: cli: move the "show errors" handler from http to proxy + - BUG/MEDIUM: snapshot: take the proxy's lock while dumping errors + - MEDIUM: snapshots: dynamically allocate the snapshots + - MEDIUM: snapshot: merge the captured data after the descriptor + - MEDIUM: mworker: remove register/unregister signal functions + - MEDIUM: mworker: use the haproxy poll loop + - BUG/MINOR: mworker: no need to stop peers for each proxy + - MINOR: mworker: mworker_cleanlisteners() delete the listeners + - MEDIUM: mworker: block SIGCHLD until the master is ready + - MEDIUM: mworker: never block SIG{TERM,INT} during reload + - MEDIUM: startup: unify signal init between daemon and mworker mode + - MINOR: mworker: don't deinit the poller fd when in wait mode + - MEDIUM: mworker: master wait mode use its own initialization + - MEDIUM: mworker: replace the master pipe by socketpairs + - MINOR: mworker: keep and clean the listeners + - MEDIUM: threads: close the thread-waker pipe during deinit + - MEDIUM: mworker: call per_thread deinit in mworker_reload() + - REORG: http: move the HTTP semantics definitions to http.h/http.c + - REORG: http: move http_get_path() to http.c + - REORG: http: move error codes production and processing to http.c + - REORG: http: move the log encoding tables to log.c + - REORG: http: move some header value processing functions to http.c + - BUG/MAJOR: kqueue: Don't reset the changes number by accident. + - MEDIUM: protocol: use a custom AF_MAX to help protocol parser + - MEDIUM: protocol: sockpair protocol + - TESTS: add a python wrapper for sockpair@ + - BUG/MINOR: server: Crash when setting FQDN via CLI. + - BUG/MINOR: h2: report asynchronous end of stream on closed connections + - BUILD: fix build without thread + - BUG/MEDIUM: tasks: Don't forget to decrement task_list_size in tasklet_free(). + - MEDIUM: connections: Don't reset the polling flags in conn_fd_handler(). + - MEDIUM: connections/mux: Add a recv and a send+recv wait list. + - MEDIUM: connections: Get rid of the recv() method. + - MINOR: h2: Let user of h2_recv() and h2_send() know xfer has been done. + - MEDIUM: h2: always subscribe to receive if allowed. + - MEDIUM: h2: Don't use a wake() method anymore. + - MEDIUM: stream_interface: Make recv() subscribe when more data is needed. + - MINOR: connections: Add a "handle" field to wait_list. + - MEDIUM: mux_h2: Revamp the send path when blocking. + - MEDIUM: stream_interfaces: Starts receiving from the upper layers. + - MINOR: checks: Give checks their own wait_list. + - MINOR: conn_streams: Remove wait_list from conn_streams. + - REORG: h1: create a new h1m_state + - MINOR: h1: add the restart offsets into struct h1m + - MINOR: h1: remove the unused states from h1m_state + - MINOR: h1: provide a distinct init() function for request and response + - MINOR: h1: add a message flag to indicate that a message carries a response + - MINOR: h2: make sure h1m->err_pos field is correct on chunk error + - MINOR: h1: properly pre-initialize err_pos to -2 + - MINOR: mux_h2: replace the req,res h1 messages with a single h1 message + - MINOR: h2: pre-initialize h1m->err_pos to -1 on the output path + - MEDIUM: h1: consider err_pos before deciding to accept a header name or not + - MEDIUM: h1: make the parser support a pointer to a start line + - MEDIUM: h1: let the caller pass the initial parser's state + - MINOR: h1: make the message parser support a null argument + - MEDIUM: h1: support partial message parsing + - MEDIUM: h1: remove the useless H1_MSG_BODY state + - MINOR: h2: store the HTTP status into the H2S, not the H1M + - MINOR: h1: remove the HTTP status from the H1M struct + - MEDIUM: h1: implement the request parser as well + - MINOR: h1: add H1_MF_TOLOWER to decide when to turn header names to lower case + - MINOR: connection: pass the proxy when creating a connection + - BUG/MEDIUM: h2: Don't forget to empty the wait lists on destroy. + - BUG/MEDIUM: h2: Don't forget to set recv_wait_list to NULL in h2_detach. + - BUG/MAJOR: h2: reset the parser's state on mux buffer full + +2018/08/02 : 1.9-dev1 + - BUG/MEDIUM: kqueue: Don't bother closing the kqueue after fork. + - DOC: cache: update sections and fix some typos + - BUILD/MINOR: deviceatlas: enable thread support + - BUG/MEDIUM: tcp-check: Don't lock the server in tcpcheck_main + - BUG/MEDIUM: ssl: don't allocate shctx several time + - BUG/MEDIUM: cache: bad computation of the remaining size + - BUILD: checks: don't include server.h + - BUG/MEDIUM: stream: fix session leak on applet-initiated connections + - BUILD/MINOR: haproxy : FreeBSD/cpu affinity needs pthread_np header + - BUILD/MINOR: Makefile : enabling USE_CPU_AFFINITY + - BUG/MINOR: ssl: CO_FL_EARLY_DATA removal is managed by stream + - BUG/MEDIUM: threads/peers: decrement, not increment jobs on quitting + - BUG/MEDIUM: h2: don't report an error after parsing a 100-continue response + - BUG/MEDIUM: peers: fix some track counter rules dont register entries for sync. + - BUG/MAJOR: thread/peers: fix deadlock on peers sync. + - BUILD/MINOR: haproxy: compiling config cpu parsing handling when needed + - MINOR: config: report when "monitor fail" rules are misplaced + - BUG/MINOR: mworker: fix validity check for the pipe FDs + - BUG/MINOR: mworker: detach from tty when in daemon mode + - MINOR: threads: Fix pthread_setaffinity_np on FreeBSD. + - BUG/MAJOR: thread: Be sure to request a sync between threads only once at a time + - BUILD: Fix LDFLAGS vs. LIBS re linking order in various makefiles + - BUG/MEDIUM: checks: Be sure we have a mux if we created a cs. + - BUG/MINOR: hpack: fix debugging output of pseudo header names + - BUG/MINOR: hpack: must reject huffman literals padded with more than 7 bits + - BUG/MINOR: hpack: reject invalid header index + - BUG/MINOR: hpack: dynamic table size updates are only allowed before headers + - BUG/MAJOR: h2: correctly check the request length when building an H1 request + - BUG/MINOR: h2: immediately close if receiving GOAWAY after the last stream + - BUG/MINOR: h2: try to abort closed streams as soon as possible + - BUG/MINOR: h2: ":path" must not be empty + - BUG/MINOR: h2: fix a typo causing PING/ACK to be responded to + - BUG/MINOR: h2: the TE header if present may only contain trailers + - BUG/MEDIUM: h2: enforce the per-connection stream limit + - BUG/MINOR: h2: do not accept SETTINGS_ENABLE_PUSH other than 0 or 1 + - BUG/MINOR: h2: reject incorrect stream dependencies on HEADERS frame + - BUG/MINOR: h2: properly check PRIORITY frames + - BUG/MINOR: h2: reject response pseudo-headers from requests + - BUG/MEDIUM: h2: remove connection-specific headers from request + - BUG/MEDIUM: h2: do not accept upper case letters in request header names + - BUG/MINOR: h2: use the H2_F_DATA_* macros for DATA frames + - BUG/MINOR: action: Don't check http capture rules when no id is defined + - BUG/MAJOR: hpack: don't pretend large headers fit in empty table + - BUG/MINOR: ssl: support tune.ssl.cachesize 0 again + - BUG/MEDIUM: mworker: also close peers sockets in the master + - BUG/MEDIUM: ssl engines: Fix async engines fds were not considered to fix fd limit automatically. + - BUG/MEDIUM: checks: a down server going to maint remains definitely stucked on down state. + - BUG/MEDIUM: peers: set NOLINGER on the outgoing stream interface + - BUG/MEDIUM: h2: fix handling of end of stream again + - MINOR: mworker: Update messages referencing exit-on-failure + - MINOR: mworker: Improve wording in `void mworker_wait()` + - CONTRIB: halog: Add help text for -s switch in halog program + - BUG/MEDIUM: email-alert: don't set server check status from a email-alert task + - BUG/MEDIUM: threads/vars: Fix deadlock in register_name + - MINOR: systemd: remove comment about HAPROXY_STATS_SOCKET + - DOC: notifications: add precisions about thread usage + - BUG/MEDIUM: lua/notification: memory leak + - MINOR: conn_stream: add new flag CS_FL_RCV_MORE to indicate pending data + - BUG/MEDIUM: stream-int: always set SI_FL_WAIT_ROOM on CS_FL_RCV_MORE + - BUG/MEDIUM: h2: automatically set CS_FL_RCV_MORE when the output buffer is full + - BUG/MEDIUM: h2: enable recv polling whenever demuxing is possible + - BUG/MEDIUM: h2: work around a connection API limitation + - BUG/MEDIUM: h2: debug incoming traffic in h2_wake() + - MINOR: h2: store the demux padding length in the h2c struct + - BUG/MEDIUM: h2: support uploading partial DATA frames + - MINOR: h2: don't demand that a DATA frame is complete before processing it + - BUG/MEDIUM: h2: don't switch the state to HREM before end of DATA frame + - BUG/MEDIUM: h2: don't close after the first DATA frame on tunnelled responses + - BUG/MEDIUM: http: don't disable lingering on requests with tunnelled responses + - BUG/MEDIUM: h2: fix stream limit enforcement + - BUG/MINOR: stream-int: don't try to receive again after receiving an EOS + - MINOR: sample: add len converter + - BUG: MAJOR: lb_map: server map calculation broken + - BUG: MINOR: http: don't check http-request capture id when len is provided + - MINOR: sample: rename the "len" converter to "length" + - BUG/MEDIUM: mworker: Set FD_CLOEXEC flag on log fd + - DOC/MINOR: intro: typo, wording, formatting fixes + - MINOR: netscaler: respect syntax + - MINOR: netscaler: remove the use of cip_magic only used once + - MINOR: netscaler: rename cip_len to clarify its uage + - BUG/MEDIUM: netscaler: use the appropriate IPv6 header size + - BUG/MAJOR: netscaler: address truncated CIP header detection + - MINOR: netscaler: check in one-shot if buffer is large enough for IP and TCP header + - MEDIUM: netscaler: do not analyze original IP packet size + - MEDIUM: netscaler: add support for standard NetScaler CIP protocol + - MINOR: spoe: add force-set-var option in spoe-agent configuration + - CONTRIB: iprange: Fix compiler warning in iprange.c + - CONTRIB: halog: Fix compiler warnings in halog.c + - BUG/MINOR: h2: properly report a stream error on RST_STREAM + - MINOR: mux: add flags to describe a mux's capabilities + - MINOR: stream-int: set flag SI_FL_CLEAN_ABRT when mux supports clean aborts + - BUG/MEDIUM: stream: don't consider abortonclose on muxes which close cleanly + - BUG/MEDIUM: checks: a server passed in maint state was not forced down. + - BUG/MEDIUM: lua: fix crash when using bogus mode in register_service() + - MINOR: http: adjust the list of supposedly cacheable methods + - MINOR: http: update the list of cacheable status codes as per RFC7231 + - MINOR: http: start to compute the transaction's cacheability from the request + - BUG/MINOR: http: do not ignore cache-control: public + - BUG/MINOR: http: properly detect max-age=0 and s-maxage=0 in responses + - BUG/MINOR: cache: do not force the TX_CACHEABLE flag before checking cacheability + - MINOR: http: add a function to check request's cache-control header field + - BUG/MEDIUM: cache: do not try to retrieve host-less requests from the cache + - BUG/MEDIUM: cache: replace old object on store + - BUG/MEDIUM: cache: respect the request cache-control header + - BUG/MEDIUM: cache: don't cache the response on no-cache="set-cookie" + - BUG/MAJOR: connection: refine the situations where we don't send shutw() + - BUG/MEDIUM: checks: properly set servers to stopping state on 404 + - BUG/MEDIUM: h2: properly handle and report some stream errors + - BUG/MEDIUM: h2: improve handling of frames received on closed streams + - DOC/MINOR: configuration: typo, formatting fixes + - BUG/MEDIUM: h2: ensure we always know the stream before sending a reset + - BUG/MEDIUM: mworker: don't close stdio several time + - MINOR: don't close stdio anymore + - BUG/MEDIUM: http: don't automatically forward request close + - BUG/MAJOR: hpack: don't return direct references to the dynamic headers table + - MINOR: h2: add a function to report pseudo-header names + - DEBUG: hpack: make hpack_dht_dump() expose the output file + - DEBUG: hpack: add more traces to the hpack decoder + - CONTRIB: hpack: add an hpack decoder + - MEDIUM: h2: prepare a graceful shutdown when the frontend is stopped + - BUG/MEDIUM: h2: properly handle the END_STREAM flag on empty DATA frames + - BUILD: ssl: silence a warning when building without NPN nor ALPN support + - CLEANUP: rbtree: remove + - BUG/MEDIUM: ssl: cache doesn't release shctx blocks + - BUG/MINOR: lua: Fix default value for pattern in Socket.receive + - DOC: lua: Fix typos in comments of hlua_socket_receive + - BUG/MEDIUM: lua: Fix IPv6 with separate port support for Socket.connect + - BUG/MINOR: lua: Fix return value of Socket.settimeout + - MINOR: dns: Handle SRV record weight correctly. + - BUG/MEDIUM: mworker: execvp failure depending on argv[0] + - MINOR: hathreads: add support for gcc < 4.7 + - BUILD/MINOR: ancient gcc versions atomic fix + - BUG/MEDIUM: stream: properly handle client aborts during redispatch + - MINOR: spoe: add register-var-names directive in spoe-agent configuration + - MINOR: spoe: Don't queue a SPOE context if nothing is sent + - DOC: clarify the scope of ssl_fc_is_resumed + - CONTRIB: debug: fix a few flags definitions + - BUG/MINOR: poll: too large size allocation for FD events + - MINOR: sample: add date_us sample + - BUG/MEDIUM: peers: fix expire date wasn't updated if entry is modified remotely. + - MINOR: servers: Don't report duplicate dyncookies for disabled servers. + - MINOR: global/threads: move cpu_map at the end of the global struct + - MINOR: threads: add a MAX_THREADS define instead of LONGBITS + - MINOR: global: add some global activity counters to help debugging + - MINOR: threads/fd: Use a bitfield to know if there are FDs for a thread in the FD cache + - BUG/MEDIUM: threads/polling: Use fd_cache_mask instead of fd_cache_num + - BUG/MEDIUM: fd: maintain a per-thread update mask + - MINOR: fd: add a bitmask to indicate that an FD is known by the poller + - BUG/MEDIUM: epoll/threads: use one epoll_fd per thread + - BUG/MEDIUM: kqueue/threads: use one kqueue_fd per thread + - BUG/MEDIUM: threads/mworker: fix a race on startup + - BUG/MINOR: mworker: only write to pidfile if it exists + - MINOR: threads: Fix build when we're not compiling with threads. + - BUG/MINOR: threads: always set an owner to the thread_sync pipe + - BUG/MEDIUM: threads/server: Fix deadlock in srv_set_stopping/srv_set_admin_flag + - BUG/MEDIUM: checks: Don't try to release undefined conn_stream when a check is freed + - BUG/MINOR: kqueue/threads: Don't forget to close kqueue_fd[tid] on each thread + - MINOR: threads: Use __decl_hathreads instead of #ifdef/#endif + - BUILD: epoll/threads: Add test on MAX_THREADS to avoid warnings when complied without threads + - BUILD: kqueue/threads: Add test on MAX_THREADS to avoid warnings when complied without threads + - CLEANUP: sample: Fix comment encoding of sample.c + - CLEANUP: sample: Fix outdated comment about sample casts functions + - BUG/MINOR: sample: Fix output type of c_ipv62ip + - CLEANUP: Fix typo in ARGT_MSK6 comment + - CLEANUP: standard: Use len2mask4 in str2mask + - MINOR: standard: Add str2mask6 function + - MINOR: config: Add support for ARGT_MSK6 + - MEDIUM: sample: Add IPv6 support to the ipmask converter + - MINOR: config: Enable tracking of up to MAX_SESS_STKCTR stick counters. + - BUG/MINOR: cli: use global.maxsock and not maxfd to list all FDs + - MINOR: polling: make epoll and kqueue not depend on maxfd anymore + - MINOR: fd: don't report maxfd in alert messages + - MEDIUM: polling: start to move maxfd computation to the pollers + - CLEANUP: fd/threads: remove the now unused fdtab_lock + - MINOR: poll: more accurately compute the new maxfd in the loop + - CLEANUP: fd: remove the unused "new" field + - MINOR: fd: move the hap_fd_{clr,set,isset} functions to fd.h + - MEDIUM: select: make use of hap_fd_* functions + - MEDIUM: fd: use atomic ops for hap_fd_{clr,set} and remove poll_lock + - MEDIUM: select: don't use the old FD state anymore + - MEDIUM: poll: don't use the old FD state anymore + - MINOR: fd: pass the iocb and owner to fd_insert() + - BUG/MINOR: threads: Update labels array because of changes in lock_label enum + - MINOR: stick-tables: Adds support for new "gpc1" and "gpc1_rate" counters. + - BUG/MINOR: epoll/threads: only call epoll_ctl(DEL) on polled FDs + - DOC: don't suggest using http-server-close + - MINOR: introduce proxy-v2-options for send-proxy-v2 + - BUG/MEDIUM: spoe: Always try to receive or send the frame to detect shutdowns + - BUG/MEDIUM: spoe: Allow producer to read and to forward shutdown on request side + - MINOR: spoe: Remove check on min_applets number when a SPOE context is queued + - MINOR: spoe: Always link a SPOE context with the applet processing it + - MINOR: spoe: Replace sending_rate by a frequency counter + - MINOR: spoe: Count the number of frames waiting for an ack for each applet + - MEDIUM: spoe: Use an ebtree to manage idle applets + - MINOR: spoa_example: Count the number of frames processed by each worker + - MINOR: spoe: Add max-waiting-frames directive in spoe-agent configuration + - MINOR: init: make stdout unbuffered + - MINOR: early data: Don't rely on CO_FL_EARLY_DATA to wake up streams. + - MINOR: early data: Never remove the CO_FL_EARLY_DATA flag. + - MINOR: compiler: introduce offsetoff(). + - MINOR: threads: Introduce double-width CAS on x86_64 and arm. + - MINOR: threads: add test and set/reset operations + - MINOR: pools/threads: Implement lockless memory pools. + - MAJOR: fd/threads: Make the fdcache mostly lockless. + - MEDIUM: fd/threads: Make sure we don't miss a fd cache entry. + - MAJOR: fd: compute the new fd polling state out of the fd lock + - MINOR: epoll: get rid of the now useless fd_compute_new_polled_status() + - MINOR: kqueue: get rid of the now useless fd_compute_new_polled_status() + - MINOR: poll: get rid of the now useless fd_compute_new_polled_status() + - MINOR: select: get rid of the now useless fd_compute_new_polled_status() + - CLEANUP: fd: remove the now unused fd_compute_new_polled_status() function + - MEDIUM: fd: make updt_fd_polling() use atomics + - MEDIUM: poller: use atomic ops to update the fdtab mask + - MINOR: fd: move the fd_{add_to,rm_from}_fdlist functions to fd.c + - BUG/MINOR: fd/threads: properly dereference fdcache as volatile + - MINOR: fd: remove the unneeded last CAS when adding an fd to the list + - MINOR: fd: reorder fd_add_to_fd_list() + - BUG/MINOR: time/threads: ensure the adjusted time is always correct + - BUG/MEDIUM: standard: Fix memory leak in str2ip2() + - MINOR: init: emit warning when -sf/-sd cannot parse argument + - BUILD: fd/threads: fix breakage build breakage without threads + - DOC: Describe routing impact of using interface keyword on bind lines + - DOC: Mention -Ws in the list of available options + - BUG/MINOR: config: don't emit a warning when global stats is incompletely configured + - BUG/MINOR: fd/threads: properly lock the FD before adding it to the fd cache. + - BUG/MEDIUM: threads: fix the double CAS implementation for ARMv7 + - BUG/MEDIUM: ssl: Don't always treat SSL_ERROR_SYSCALL as unrecovarable. + - BUILD/MINOR: memory: stdint is needed for uintptr_t + - BUG/MINOR: init: Add missing brackets in the code parsing -sf/-st + - DOC: lua: new prototype for function "register_action()" + - DOC: cfgparse: Warn on option (tcp|http)log in backend + - BUG/MINOR: ssl/threads: Make management of the TLS ticket keys files thread-safe + - MINOR: sample: add a new "concat" converter + - BUG/MEDIUM: ssl: Shutdown the connection for reading on SSL_ERROR_SYSCALL + - BUG/MEDIUM: http: Switch the HTTP response in tunnel mode as earlier as possible + - BUG/MEDIUM: ssl/sample: ssl_bc_* fetch keywords are broken. + - MINOR: ssl/sample: adds ssl_bc_is_resumed fetch keyword. + - CLEANUP: cfgparse: Remove unused label end + - CLEANUP: spoe: Remove unused label retry + - CLEANUP: h2: Remove unused labels from mux_h2.c + - CLEANUP: pools: Remove unused end label in memory.h + - CLEANUP: standard: Fix typo in IPv6 mask example + - BUG/MINOR: pools/threads: don't ignore DEBUG_UAF on double-word CAS capable archs + - BUG/MINOR: debug/pools: properly handle out-of-memory when building with DEBUG_UAF + - MINOR: debug/pools: make DEBUG_UAF also detect underflows + - MINOR: stats: display the number of threads in the statistics. + - BUG/MINOR: h2: Set the target of dbuf_wait to h2c + - BUG/MEDIUM: h2: always consume any trailing data after end of output buffers + - BUG/MEDIUM: buffer: Fix the wrapping case in bo_putblk + - BUG/MEDIUM: buffer: Fix the wrapping case in bi_putblk + - BUG/MEDIUM: spoe: Remove idle applets from idle list when HAProxy is stopping + - Revert "BUG/MINOR: send-proxy-v2: string size must include ('\0')" + - MINOR: ssl: extract full pkey info in load_certificate + - MINOR: ssl: add ssl_sock_get_pkey_algo function + - MINOR: ssl: add ssl_sock_get_cert_sig function + - MINOR: connection: add proxy-v2-options ssl-cipher,cert-sig,cert-key + - MINOR: connection: add proxy-v2-options authority + - MINOR: systemd: Add section for SystemD sandboxing to unit file + - MINOR: systemd: Add SystemD's Protect*= options to the unit file + - MINOR: systemd: Add SystemD's SystemCallFilter option to the unit file + - CLEANUP: h2: rename misleading h2c_stream_close() to h2s_close() + - MINOR: h2: provide and use h2s_detach() and h2s_free() + - MEDIUM: h2: use a single buffer allocator + - MINOR/BUILD: fix Lua build on Mac OS X + - BUILD/MINOR: fix Lua build on Mac OS X (again) + - BUG/MINOR: session: Fix tcp-request session failure if handshake. + - CLEANUP: .gitignore: Ignore binaries from the contrib directory + - BUG/MINOR: unix: Don't mess up when removing the socket from the xfer_sock_list. + - DOC: buffers: clarify the purpose of the pointer in offer_buffers() + - BUG/MEDIUM: h2: also arm the h2 timeout when sending + - BUG/MINOR: cli: Fix a crash when passing a negative or too large value to "show fd" + - CLEANUP: ssl: Remove a duplicated #include + - CLEANUP: cli: Remove a leftover debug message + - BUG/MINOR: cli: Fix a typo in the 'set rate-limit' usage + - BUG/MEDIUM: fix a 100% cpu usage with cpu-map and nbthread/nbproc + - BUG/MINOR: force-persist and ignore-persist only apply to backends + - BUG/MEDIUM: threads/unix: Fix a deadlock when a listener is temporarily disabled + - BUG/MAJOR: threads/queue: Fix thread-safety issues on the queues management + - BUG/MINOR: dns: don't downgrade DNS accepted payload size automatically + - TESTS: Add a testcase for multi-port + multi-server listener issue + - CLEANUP: dns: remove duplicate code in src/dns.c + - BUG/MINOR: seemless reload: Fix crash when an interface is specified. + - BUG/MINOR: cli: Ensure all command outputs end with a LF + - BUG/MINOR: cli: Fix a crash when sending a command with too many arguments + - BUILD: ssl: Fix build with OpenSSL without NPN capability + - BUG/MINOR: spoa-example: unexpected behavior for more than 127 args + - BUG/MINOR: lua: return bad error messages + - CLEANUP: lua/syntax: lua is a name and not an acronym + - BUG/MEDIUM: tcp-check: single connect rule can't detect DOWN servers + - BUG/MINOR: tcp-check: use the server's service port as a fallback + - BUG/MEDIUM: threads/queue: wake up other threads upon dequeue + - MINOR: log: stop emitting alerts when it's not possible to write on the socket + - BUILD/BUG: enable -fno-strict-overflow by default + - BUG/MEDIUM: fd/threads: ensure the fdcache_mask always reflects the cache contents + - DOC: log: more than 2 log servers are allowed + - MINOR: hash: add new function hash_crc32c + - MINOR: proxy-v2-options: add crc32c + - MINOR: accept-proxy: support proxy protocol v2 CRC32c checksum + - REORG: compact "struct server" + - MINOR: samples: add crc32c converter + - BUG/MEDIUM: h2: properly account for DATA padding in flow control + - BUG/MINOR: h2: ensure we can never send an RST_STREAM in response to an RST_STREAM + - BUG/MINOR: listener: Don't decrease actconn twice when a new session is rejected + - CLEANUP: map, stream: remove duplicate code in src/map.c, src/stream.c + - BUG/MINOR: lua: the function returns anything + - BUG/MINOR: lua funtion hlua_socket_settimeout don't check negative values + - CLEANUP: lua: typo fix in comments + - BUILD/MINOR: fix build when USE_THREAD is not defined + - MINOR: lua: allow socket api settimeout to accept integers, float, and doubles + - BUG/MINOR: hpack: fix harmless use of uninitialized value in hpack_dht_insert + - MINOR: cli/threads: make "show fd" report thread_sync_io_handler instead of "unknown" + - MINOR: cli: make "show fd" report the mux and mux_ctx pointers when available + - BUILD/MINOR: cli: fix a build warning introduced by last commit + - BUG/MAJOR: h2: remove orphaned streams from the send list before closing + - MINOR: h2: always call h2s_detach() in h2_detach() + - MINOR: h2: fuse h2s_detach() and h2s_free() into h2s_destroy() + - BUG/MEDIUM: h2/threads: never release the task outside of the task handler + - BUG/MEDIUM: h2: don't consider pending data on detach if connection is in error + - BUILD/MINOR: threads: always export thread_sync_io_handler() + - MINOR: mux: add a "show_fd" function to dump debugging information for "show fd" + - MINOR: h2: implement a basic "show_fd" function + - MINOR: cli: report cache indexes in "show fd" + - BUG/MINOR: h2: remove accidental debug code introduced with show_fd function + - BUG/MEDIUM: h2: always add a stream to the send or fctl list when blocked + - BUG/MINOR: checks: check the conn_stream's readiness and not the connection + - BUG/MINOR: fd: Don't clear the update_mask in fd_insert. + - BUG/MINOR: email-alert: Set the mailer port during alert initialization + - BUG/MINOR: cache: fix "show cache" output + - BUG/MAJOR: cache: fix random crashes caused by incorrect delete() on non-first blocks + - BUG/MINOR: spoe: Initialize variables used during conf parsing before any check + - BUG/MINOR: spoe: Don't release the context buffer in .check_timeouts callbaclk + - BUG/MINOR: spoe: Register the variable to set when an error occurred + - BUG/MINOR: spoe: Don't forget to decrement fpa when a processing is interrupted + - MINOR: spoe: Add metrics in to know time spent in the SPOE + - MINOR: spoe: Add options to store processing times in variables + - MINOR: log: move 'log' keyword parsing in dedicated function + - MINOR: log: Keep the ref when a log server is copied to avoid duplicate entries + - MINOR: spoe: Add loggers dedicated to the SPOE agent + - MINOR: spoe: Add support for option dontlog-normal in the SPOE agent section + - MINOR: spoe: use agent's logger to log SPOE messages + - MINOR: spoe: Add counters to log info about SPOE agents + - BUG/MAJOR: cache: always initialize newly created objects + - MINOR: servers: Support alphanumeric characters for the server templates names + - BUG/MEDIUM: threads: Fix the max/min calculation because of name clashes + - BUG/MEDIUM: connection: Make sure we have a mux before calling detach(). + - BUG/MINOR: http: Return an error in proxy mode when url2sa fails + - MINOR: proxy: Add fe_defbe fetcher + - MINOR: config: Warn if resolvers has no nameservers + - BUG/MINOR: cli: Guard against NULL messages when using CLI_ST_PRINT_FREE + - MINOR: cli: Ensure the CLI always outputs an error when it should + - MEDIUM: sample: Extend functionality for field/word converters + - MINOR: export localpeer as an environment variable + - BUG/MEDIUM: kqueue: When adding new events, provide an output to get errors. + - BUILD: sample: avoid build warning in sample.c + - BUG/CRITICAL: h2: fix incorrect frame length check + - DOC: lua: update the links to the config and Lua API + - BUG/MINOR: pattern: Add a missing HA_SPIN_INIT() in pat_ref_newid() + - BUG/MAJOR: channel: Fix crash when trying to read from a closed socket + - BUG/MINOR: log: t_idle (%Ti) is not set for some requests + - BUG/MEDIUM: lua: Fix segmentation fault if a Lua task exits + - MINOR: h2: detect presence of CONNECT and/or content-length + - BUG/MEDIUM: h2: implement missing support for chunked encoded uploads + - BUG/MINOR: spoe: Fix counters update when processing is interrupted + - BUG/MINOR: spoe: Fix parsing of dontlog-normal option + - MEDIUM: cli: Add payload support + - MINOR: map: Add payload support to "add map" + - MINOR: ssl: Add payload support to "set ssl ocsp-response" + - BUG/MINOR: lua/threads: Make lua's tasks sticky to the current thread + - MINOR: sample: Add strcmp sample converter + - MINOR: http: Add support for 421 Misdirected Request + - BUG/MINOR: config: disable http-reuse on TCP proxies + - MINOR: ssl: disable SSL sample fetches when unsupported + - MINOR: ssl: add fetch 'ssl_fc_session_key' and 'ssl_bc_session_key' + - BUG/MINOR: checks: Fix check->health computation for flapping servers + - BUG/MEDIUM: threads: Fix the sync point for more than 32 threads + - BUG/MINOR, BUG/MINOR: lua: Put tasks to sleep when waiting for data + - MINOR: backend: implement random-based load balancing + - DOC/MINOR: clean up LUA documentation re: servers & array/table. + - MINOR: lua: Add server name & puid to LUA Server class. + - MINOR: lua: add get_maxconn and set_maxconn to LUA Server class. + - BUG/MINOR: map: correctly track reference to the last ref_elt being dumped + - BUG/MEDIUM: task: Don't free a task that is about to be run. + - MINOR: fd: Make the lockless fd list work with multiple lists. + - BUG/MEDIUM: pollers: Use a global list for fd shared between threads. + - MINOR: pollers: move polled_mask outside of struct fdtab. + - BUG/MINOR: lua: schedule socket task upon lua connect() + - BUG/MINOR: lua: ensure large proxy IDs can be represented + - BUG/MEDIUM: pollers/kqueue: use incremented position in event list + - BUG/MINOR: cli: don't stop cli_gen_usage_msg() when kw->usage == NULL + - BUG/MEDIUM: http: don't always abort transfers on CF_SHUTR + - BUG/MEDIUM: ssl: properly protect SSL cert generation + - BUG/MINOR: lua: Socket.send threw runtime error: 'close' needs 1 arguments. + - BUG/MINOR: spoe: Mistake in error message about SPOE configuration + - BUG/MEDIUM: spoe: Flags are not encoded in network order + - CLEANUP: spoe: Remove unused variables the agent structure + - DOC: spoe: fix a typo + - BUG/MEDIUM: contrib/mod_defender: Use network order to encode/decode flags + - BUG/MEDIUM: contrib/modsecurity: Use network order to encode/decode flags + - DOC: add some description of the pending rework of the buffer structure + - BUG/MINOR: ssl/lua: prevent lua from affecting automatic maxconn computation + - MINOR: lua: Improve error message + - BUG/MEDIUM: cache: don't cache when an Authorization header is present + - MINOR: ssl: set SSL_OP_PRIORITIZE_CHACHA + - BUG/MEDIUM: dns: Delay the attempt to run a DNS resolution on check failure. + - BUG/BUILD: threads: unbreak build without threads + - BUG/MEDIUM: servers: Add srv_addr default placeholder to the state file + - BUG/MEDIUM: lua/socket: Length required read doesn't work + - MINOR: tasks: Change the task API so that the callback takes 3 arguments. + - MAJOR: tasks: Create a per-thread runqueue. + - MAJOR: tasks: Introduce tasklets. + - MINOR: tasks: Make the number of tasks to run at once configurable. + - MAJOR: applets: Use tasks, instead of rolling our own scheduler. + - BUG/MEDIUM: stick-tables: Decrement ref_cnt in table_* converters + - MINOR: http: Log warning if (add|set)-header fails + - DOC: management: add the new wrew stats column + - MINOR: stats: also report the failed header rewrites warnings on the stats page + - BUG/MEDIUM: tasks: Don't forget to increase/decrease tasks_run_queue. + - BUG/MEDIUM: task: Don't forget to decrement max_processed after each task. + - MINOR: task: Also consider the task list size when getting global tasks. + - MINOR: dns: Implement `parse-resolv-conf` directive + - BUG/MEDIUM: spoe: Return an error when the wrong ACK is received in sync mode + - MINOR: task/notification: Is notifications registered ? + - BUG/MEDIUM: lua/socket: wrong scheduling for sockets + - BUG/MAJOR: lua: Dead lock with sockets + - BUG/MEDIUM: lua/socket: Notification error + - BUG/MEDIUM: lua/socket: Sheduling error on write: may dead-lock + - BUG/MEDIUM: lua/socket: Buffer error, may segfault + - DOC: contrib/modsecurity: few typo fixes + - DOC: SPOE.txt: fix a typo + - MAJOR: spoe: upgrade the SPOP version to 2.0 and remove the support for 1.0 + - BUG/MINOR: contrib/spoa_example: Don't reset the status code during disconnect + - BUG/MINOR: contrib/mod_defender: Don't reset the status code during disconnect + - BUG/MINOR: contrib/modsecurity: Don't reset the status code during disconnect + - BUG/MINOR: contrib/mod_defender: update pointer on the end of the frame + - BUG/MINOR: contrib/modsecurity: update pointer on the end of the frame + - MINOR: task: Fix a compiler warning by adding a cast. + - MINOR: stats: also report the nice and number of calls for applets + - MINOR: applet: assign the same nice value to a new appctx as its owner task + - MINOR: task: Fix compiler warning. + - BUG/MEDIUM: tasks: Use the local runqueue when building without threads. + - MINOR: tasks: Don't define rqueue if we're building without threads. + - BUG/MINOR: unix: Make sure we can transfer abns sockets on seamless reload. + - MINOR: lua: Increase debug information + - BUG/MEDIUM: threads: handle signal queue only in thread 0 + - BUG/MINOR: don't ignore SIG{BUS,FPE,ILL,SEGV} during signal processing + - BUG/MINOR: signals: ha_sigmask macro for multithreading + - BUG/MAJOR: map: fix a segfault when using http-request set-map + - DOC: regression testing: Add a short starting guide. + - MINOR: tasks: Make sure we correctly init and deinit a tasklet. + - BUG/MINOR: tasklets: Just make sure we don't pass a tasklet to the handler. + - BUG/MINOR: lua: Segfaults with wrong usage of types. + - BUG/MAJOR: ssl: Random crash with cipherlist capture + - BUG/MAJOR: ssl: OpenSSL context is stored in non-reserved memory slot + - BUG/MEDIUM: ssl: do not store pkinfo with SSL_set_ex_data + - MINOR: tests: First regression testing file. + - MINOR: reg-tests: Add reg-tests/README file. + - MINOR: reg-tests: Add a few regression testing files. + - DOC: Add new REGTEST tag info about reg testing. + - BUG/MEDIUM: fd: Don't modify the update_mask in fd_dodelete(). + - MINOR: Some spelling cleanup in the comments. + - BUG/MEDIUM: threads: Use the sync point to check active jobs and exit + - MINOR: threads: Be sure to remove threads from all_threads_mask on exit + - REGTEST/MINOR: Wrong URI in a reg test for SSL/TLS. + - REGTEST/MINOR: Set HAPROXY_PROGRAM default value. + - REGTEST/MINOR: Add levels to reg-tests target. + - BUG/MAJOR: Stick-tables crash with segfault when the key is not in the stick-table + - BUG/BUILD: threads: unbreak build without threads + - BUG/MAJOR: stick_table: Complete incomplete SEGV fix + - MINOR: stick-tables: make stktable_release() do nothing on NULL + - BUG/MEDIUM: lua: possible CLOSE-WAIT state with '\n' headers + - MINOR: startup: change session/process group settings + - MINOR: systemd: consider exit status 143 as successful + - REGTEST/MINOR: Wrong URI syntax. + - CLEANUP: dns: remove obsolete macro DNS_MAX_IP_REC + - CLEANUP: dns: inacurate comment about prefered IP score + - MINOR: dns: fix wrong score computation in dns_get_ip_from_response + - MINOR: dns: new DNS options to allow/prevent IP address duplication + - REGTEST/MINOR: Unexpected curl URL globling. + - BUG/MINOR: ssl: properly ref-count the tls_keys entries + - MINOR: h2: keep a count of the number of conn_streams attached to the mux + - BUG/MEDIUM: h2: don't accept new streams if conn_streams are still in excess + - MINOR: h2: add the mux and demux buffer lengths on "show fd" + - BUG/MEDIUM: h2: never leave pending data in the output buffer on close + - BUG/MEDIUM: h2: make sure the last stream closes the connection after a timeout + - MINOR: tasklet: Set process to NULL. + - MINOR: buffer: implement a new file for low-level buffer manipulation functions + - MINOR: buffer: switch buffer sizes and offsets to size_t + - MINOR: buffer: add a few basic functions for the new API + - MINOR: buffer: Introduce b_sub(), b_add(), and bo_add() + - MINOR: buffer: Add b_set_data(). + - MINOR: buffer: introduce b_realign_if_empty() + - MINOR: compression: pass the channel to http_compression_buffer_end() + - MINOR: channel: add a few basic functions for the new buffer API + - MINOR: channel/buffer: use c_realign_if_empty() instead of buffer_realign() + - MINOR: channel/buffer: replace buffer_slow_realign() with channel_slow_realign() and b_slow_realign() + - MEDIUM: channel: make channel_slow_realign() take a swap buffer + - MINOR: h2: use b_slow_realign() with the trash as a swap buffer + - MINOR: buffer: remove buffer_slow_realign() and the swap_buffer allocation code + - MINOR: channel/buffer: replace b_{adv,rew} with c_{adv,rew} + - MINOR: buffer: replace calls to buffer_space_wraps() with b_space_wraps() + - MINOR: buffer: remove bi_getblk() and bi_getblk_nc() + - MINOR: buffer: split bi_contig_data() into ci_contig_data and b_config_data() + - MINOR: buffer: remove bi_ptr() + - MINOR: buffer: remove bo_ptr() + - MINOR: buffer: remove bo_end() + - MINOR: buffer: remove bi_end() + - MINOR: buffer: remove bo_contig_data() + - MINOR: buffer: merge b{i,o}_contig_space() + - MINOR: buffer: replace bo_getblk() with direction agnostic b_getblk() + - MINOR: buffer: replace bo_getblk_nc() with b_getblk_nc() which takes an offset + - MINOR: buffer: replace bi_del() and bo_del() with b_del() + - MINOR: buffer: convert most b_ptr() calls to c_ptr() + - MINOR: h1: make h1_measure_trailers() take the byte count in argument + - MINOR: h2: clarify the fact that the send functions are unsigned + - MEDIUM: h2: prevent the various mux encoders from modifying the buffer + - MINOR: h1: make h1_skip_chunk_crlf() not depend on b_ptr() anymore + - MINOR: h1: make h1_parse_chunk_size() not depend on b_ptr() anymore + - MINOR: h1: make h1_measure_trailers() use an offset and a count + - MEDIUM: h2: do not use buf->o anymore inside h2_snd_buf's loop + - MEDIUM: h2: don't use b_ptr() nor b_end() anymore + - MINOR: buffer: get rid of b_end() and b_to_end() + - MINOR: buffer: make b_getblk_nc() take const pointers + - MINOR: buffer: make b_getblk_nc() take size_t for the block sizes + - MEDIUM: connection: make xprt->snd_buf() take the byte count in argument + - MEDIUM: mux: make mux->snd_buf() take the byte count in argument + - MEDIUM: connection: make xprt->rcv_buf() use size_t for the count + - MEDIUM: mux: make mux->rcv_buf() take a size_t for the count + - MINOR: connection: add a flags argument to rcv_buf() + - MINOR: connection: add a new receive flag : CO_RFL_BUF_WET + - MINOR: buffer: get rid of b_ptr() and convert its last users + - MINOR: buffer: use b_room() to determine available space in a buffer + - MINOR: buffer: replace buffer_not_empty() with b_data() or c_data() + - MINOR: buffer: replace buffer_empty() with b_empty() or c_empty() + - MINOR: buffer: make bo_putchar() use b_tail() + - MINOR: buffer: replace buffer_full() with channel_full() + - MINOR: buffer: replace bi_space_for_replace() with ci_space_for_replace() + - MINOR: buffer: replace buffer_pending() with ci_data() + - MINOR: buffer: replace buffer_flush() with c_adv(chn, ci_data(chn)) + - MINOR: buffer: use c_head() instead of buffer_wrap_sub(c->buf, p-o) + - MINOR: buffer: use b_orig() to replace most references to b->data + - MINOR: buffer: Use b_add()/bo_add() instead of accessing b->i/b->o. + - MINOR: channel: remove almost all references to buf->i and buf->o + - MINOR: channel: Add co_set_data(). + - MEDIUM: channel: adapt to the new buffer API + - MINOR: checks: adapt to the new buffer API + - MEDIUM: h2: update to the new buffer API + - MINOR: buffer: remove unused bo_add() + - MEDIUM: spoe: use the new buffer API for the SPOE buffer + - MINOR: stats: adapt to the new buffers API + - MINOR: cli: use the new buffer API + - MINOR: cache: use the new buffer API + - MINOR: stream-int: use the new buffer API + - MINOR: stream: use wrappers instead of directly manipulating buffers + - MINOR: backend: use new buffer API + - MEDIUM: http: use wrappers instead of directly manipulating buffers states + - MINOR: filters: convert to the new buffer API + - MINOR: payload: convert to the new buffer API + - MEDIUM: h1: port to new buffer API. + - MINOR: flt_trace: adapt to the new buffer API + - MEDIUM: compression: start to move to the new buffer API + - MINOR: lua: use the wrappers instead of directly manipulating buffer states + - MINOR: buffer: convert part bo_putblk() and bi_putblk() to the new API + - MINOR: buffer: adapt buffer_slow_realign() and buffer_dump() to the new API + - MAJOR: start to change buffer API + - MINOR: buffer: remove the check for output on b_del() + - MINOR: buffer: b_set_data() doesn't truncate output data anymore + - MINOR: buffer: rename the "data" field to "area" + - MEDIUM: buffers: move "output" from struct buffer to struct channel + - MINOR: buffer: replace bi_fast_delete() with b_del() + - MINOR: buffer: replace b{i,o}_put* with b_put* + - MINOR: buffer: add a new file for ist + buffer manipulation functions + - MINOR: checks: use b_putist() instead of b_putstr() + - MINOR: buffers: remove b_putstr() + - CLEANUP: buffer: minor cleanups to buffer.h + - MINOR: buffers/channel: replace buffer_insert_line2() with ci_insert_line2() + - MINOR: buffer: replace buffer_replace2() with b_rep_blk() + - MINOR: buffer: rename the data length member to '->data' + - MAJOR: buffer: finalize buffer detachment + - MEDIUM: chunks: make the chunk struct's fields match the buffer struct + - MAJOR: chunks: replace struct chunk with struct buffer + - DOC: buffers: document the new buffers API + - DOC: buffers: remove obsolete docs about buffers + - MINOR: tasklets: Don't attempt to add a tasklet in the list twice. + - MINOR: connections/mux: Add a new "subscribe" method. + - MEDIUM: connections/mux: Revamp the send direction. + - MINOR: connection: simplify subscription by adding a registration function + - BUG/MINOR: http: Set brackets for the unlikely macro at the right place + - BUG/MINOR: build: Fix compilation with debug mode enabled + - BUILD: Generate sha256 checksums in publish-release + - MINOR: debug: Add check for CO_FL_WILL_UPDATE + - MINOR: debug: Add checks for conn_stream flags + - MINOR: ist: Add the function isteqi + - BUG/MEDIUM: threads: Fix the exit condition of the thread barrier + - BUG/MEDIUM: mux_h2: Call h2_send() before updating polling. + - MINOR: buffers: simplify b_contig_space() + - MINOR: buffers: split b_putblk() into __b_putblk() + - MINOR: buffers: add b_xfer() to transfer data between buffers + - DOC: add some design notes about the new layering model + - MINOR: conn_stream: add a new CS_FL_REOS flag + - MINOR: conn_stream: add an rx buffer to the conn_stream + - MEDIUM: conn_stream: add cs_recv() as a default rcv_buf() function + - MEDIUM: stream-int: automatically call si_cs_recv_cb() if the cs has data on wake() + - MINOR: h2: make each H2 stream support an intermediary input buffer + - MEDIUM: h2: make h2_frt_decode_headers() use an intermediary buffer + - MEDIUM: h2: make h2_frt_transfer_data() copy via an intermediary buffer + - MEDIUM: h2: centralize transfer of decoded frames in h2_rcv_buf() + - MEDIUM: h2: move headers and data frame decoding to their respective parsers + - MEDIUM: buffers: make b_xfer() automatically swap buffers when possible + - MEDIUM: h2: perform a single call to the data layer in demux() + - MEDIUM: h2: don't call data_cb->recv() anymore + - MINOR: h2: make use of CS_FL_REOS to indicate that end of stream was seen + - MEDIUM: h2: use the default conn_stream's receive function + - DOC: add more design feedback on the new layering model + - MINOR: h2: add the error code and the max/last stream IDs to "show fd" + - BUG/MEDIUM: stream-int: don't immediately enable reading when the buffer was reportedly full + - BUG/MEDIUM: stats: don't ask for more data as long as we're responding + - BUG/MINOR: servers: Don't make "server" in a frontend fatal. + - BUG/MEDIUM: tasks: make sure we pick all tasks in the run queue + - BUG/MEDIUM: tasks: Decrement rqueue_size at the right time. + - BUG/MEDIUM: tasks: use atomic ops for active_tasks_mask + - BUG/MEDIUM: tasks: Make sure there's no task left before considering inactive. + - MINOR: signal: don't pass the signal number anymore as the wakeup reason + - MINOR: tasks: extend the state bits from 8 to 16 and remove the reason + - MINOR: tasks: Add a flag that tells if we're in the global runqueue. + - BUG/MEDIUM: tasks: make __task_unlink_rq responsible for the rqueue size. + - MINOR: queue: centralize dequeuing code a bit better + - MEDIUM: queue: make pendconn_free() work on the stream instead + - DOC: queue: document the expected locking model for the server's queue + - MINOR: queue: make sure pendconn->strm->pend_pos is always valid + - MINOR: queue: use a distinct variable for the assigned server and the queue + - MINOR: queue: implement pendconn queue locking functions + - MEDIUM: queue: get rid of the pendconn lock + - MINOR: tasks: Make active_tasks_mask volatile. + - MINOR: tasks: Make global_tasks_mask volatile. + - MINOR: pollers: Add a way to wake a thread sleeping in the poller. + - MINOR: threads/queue: Get rid of THREAD_WANT_SYNC in the queue code. + - BUG/MEDIUM: threads/sync: use sched_yield when available + - MINOR: ssl: BoringSSL matches OpenSSL 1.1.0 + - BUG/MEDIUM: h2: prevent orphaned streams from blocking a connection forever + - BUG/MINOR: config: stick-table is not supported in defaults section + - BUILD/MINOR: threads: unbreak build with threads disabled + - BUG/MINOR: threads: Handle nbthread == MAX_THREADS. + - BUG/MEDIUM: threads: properly fix nbthreads == MAX_THREADS + - MINOR: threads: move "nbthread" parsing to hathreads.c + - BUG/MEDIUM: threads: unbreak "bind" referencing an incorrect thread number + - MEDIUM: proxy_protocol: Convert IPs to v6 when protocols are mixed + - BUILD/MINOR: compiler: fix offsetof() on older compilers + - SCRIPTS: git-show-backports: add missing quotes to "echo" + - MINOR: threads: add more consistency between certain variables in no-thread case + - MEDIUM: hathreads: implement a more flexible rendez-vous point + - BUG/MEDIUM: cli: make "show fd" thread-safe + +2017/11/26 : 1.9-dev0 + +2017/11/26 : 1.8.0 + - BUG/MEDIUM: stream: don't automatically forward connect nor close + - BUG/MAJOR: stream: ensure analysers are always called upon close + - BUG/MINOR: stream-int: don't try to read again when CF_READ_DONTWAIT is set + - MEDIUM: mworker: Add systemd `Type=notify` support + - BUG/MEDIUM: cache: free callback to remove from tree + - CLEANUP: cache: remove unused struct + - MEDIUM: cache: enable the HTTP analysers + - CLEANUP: cache: remove wrong comment + - MINOR: threads/atomic: rename local variables in macros to avoid conflicts + - MINOR: threads/plock: rename local variables in macros to avoid conflicts + - MINOR: threads/atomic: implement pl_mb() in asm on x86 + - MINOR: threads/atomic: implement pl_bts() on non-x86 + - MINOR: threads/build: atomic: replace the few inlines with macros + - BUILD: threads/plock: fix a build issue on Clang without optimization + - BUILD: ebtree: don't redefine types u32/s32 in scope-aware trees + - BUILD: compiler: add a new type modifier __maybe_unused + - BUILD: h2: mark some inlined functions "unused" + - BUILD: server: check->desc always exists + - BUG/MEDIUM: h2: properly report connection errors in headers and data handlers + - MEDIUM: h2: add a function to emit an HTTP/1 request from a headers list + - MEDIUM: h2: change hpack_decode_headers() to only provide a list of headers + - BUG/MEDIUM: h2: always reassemble the Cookie request header field + - BUG/MINOR: systemd: ignore daemon mode + - CONTRIB: spoa_example: allow to compile outside HAProxy. + - CONTRIB: spoa_example: remove bref, wordlist, cond_wordlist + - CONTRIB: spoa_example: remove last dependencies on type "sample" + - CONTRIB: spoa_example: remove SPOE enums that are useless for clients + - CLEANUP: cache: reorder includes + - MEDIUM: shctx: use unsigned int for len and block_count + - MEDIUM: cache: "show cache" on the cli + - BUG/MEDIUM: cache: use key=0 as a condition for freeing + - BUG/MEDIUM: cache: refcount forbids to free the objects + - BUG/MEDIUM: cache fix cli_kws structure + - BUG/MEDIUM: deinit: correctly deinitialize the proxy and global listener tasks + - BUG/MINOR: ssl: Always start the handshake if we can't send early data. + - MINOR: ssl: Don't disable early data handling if we could not write. + - MINOR: pools: prepare functions to override malloc/free in pools + - MINOR: pools: implement DEBUG_UAF to detect use after free + - BUG/MEDIUM: threads/time: fix time drift correction + - BUG/MEDIUM: threads/time: maintain a common time reference between all threads + - MINOR: sample: Add "thread" sample fetch + - BUG/MINOR: Use crt_base instead of ca_base when crt is parsed on a server line + - BUG/MINOR: stream: fix tv_request calculation for applets + - BUG/MAJOR: h2: always remove a stream from the send list before freeing it + - BUG/MAJOR: threads/task: dequeue expired tasks under the WQ lock + - MINOR: ssl: Handle reading early data after writing better. + - MINOR: mux: Make sure every string is woken up after the handshake. + - MEDIUM: cache: store sha1 for hashing the cache key + - MINOR: http: implement the "http-request reject" rule + - MINOR: h2: send RST_STREAM before GOAWAY on reject + - MEDIUM: h2: don't gracefully close the connection anymore on Connection: close + - MINOR: h2: make use of client-fin timeout after GOAWAY + - MEDIUM: config: ensure that tune.bufsize is at least 16384 when using HTTP/2 + - MINOR: ssl: Handle early data with BoringSSL + - BUG/MEDIUM: stream: always release the stream-interface on abort + - BUG/MEDIUM: cache: free ressources in chn_end_analyze + - MINOR: cache: move the refcount decrease in the applet release + - BUG/MINOR: listener: Allow multiple "process" options on "bind" lines + - MINOR: config: Support a range to specify processes in "cpu-map" parameter + - MINOR: config: Slightly change how parse_process_number works + - MINOR: config: Export parse_process_number and use it wherever it's applicable + - MINOR: standard: Add my_ffsl function to get the position of the bit set to one + - MINOR: config: Add auto-increment feature for cpu-map + - MINOR: config: Support partial ranges in cpu-map directive + - MINOR:: config: Remove thread-map directive + - MINOR: config: Add the threads support in cpu-map directive + - MINOR: config: Add threads support for "process" option on "bind" lines + - MEDIUM: listener: Bind listeners on a thread subset if specified + - CLEANUP: debug: Use DPRINTF instead of fprintf into #ifdef DEBUG_FULL/#endif + - CLEANUP: log: Rename Alert/Warning in ha_alert/ha_warning + - MINOR/CLEANUP: proxy: rename "proxy" to "proxies_list" + - CLEANUP: pools: rename all pool functions and pointers to remove this "2" + - DOC: update the roadmap file with the latest changes merged in 1.8 + - DOC: fix mangled version in peers protocol documentation + - DOC: add initial peers protovol v2.0 documentation. + - DOC: mention William as maintainer of the cache and master-worker + - DOC: add Christopher and Emeric as maintainers of the threads + - MINOR: cache: replace a fprint() by an abort() + - MEDIUM: cache: max-age configuration keyword + - DOC: explain HTTP2 timeout behavior + - DOC: cache: configuration and management + - MAJOR: mworker: exits the master on failure + - BUG/MINOR: threads: don't drop "extern" on the lock in include files + - MINOR: task: keep a pointer to the currently running task + - MINOR: task: align the rq and wq locks + - MINOR: fd: cache-align fdtab and fdcache locks + - MINOR: buffers: cache-align buffer_wq_lock + - CLEANUP: server: reorder some fields in struct server to save 40 bytes + - CLEANUP: proxy: slightly reorder the struct proxy to reduce holes + - CLEANUP: checks: remove 16 bytes of holes in struct check + - CLEANUP: cache: more efficiently pack the struct cache + - CLEANUP: fd: place the lock at the beginning of struct fdtab + - CLEANUP: pools: align pools on a cache line + - DOC: config: add a few bits about how to configure HTTP/2 + - BUG/MAJOR: threads/queue: avoid recursive locking in pendconn_get_next_strm() + - BUILD: Makefile: reorder object files by size + +2017/11/19 : 1.8-rc4 + - BUG/MEDIUM: cache: does not cache if no Content-Length + - BUILD: thread/pipe: fix build without threads + - BUG/MINOR: spoe: check buffer size before acquiring or releasing it + - MINOR: debug/flags: Add missing flags + - MINOR: threads: Use __decl_hathreads to declare locks + - BUG/MINOR: buffers: Fix b_alloc_margin to be "fonctionnaly" thread-safe + - BUG/MAJOR: ebtree/scope: fix insertion and removal of duplicates in scope-aware trees + - BUG/MAJOR: ebtree/scope: fix lookup of next node in scope-aware trees + - MINOR: ebtree/scope: add a function to find next node from a parent + - MINOR: ebtree/scope: simplify the lookup functions by using eb32sc_next_with_parent() + - BUG/MEDIUM: mworker: Fix re-exec when haproxy is started from PATH + - BUG/MEDIUM: cache: use msg->sov to forward header + - MINOR: cache: forward data with headers + - MINOR: cache: disable cache if shctx_row_data_append fail + - BUG/MINOR: threads: tid_bit must be a unsigned long + - CLEANUP: tasks: Remove useless double test on rq_next + - BUG/MEDIUM: standard: itao_str/idx and quote_str/idx must be thread-local + - MINOR: tools: add a function to dump a scope-aware tree to a file + - MINOR: tools: improve the DOT dump of the ebtree + - MINOR: tools: emphasize the node being worked on in the tree dump + - BUG/MAJOR: ebtree/scope: properly tag upper nodes during insertion + - DOC: peers: Add a first version of peers protocol v2.1. + - CONTRIB: Wireshark dissector for HAProxy Peer Protocol. + - MINOR: mworker: display an accurate error when the reexec fail + - BUG/MEDIUM: mworker: wait again for signals when execvp fail + - BUG/MEDIUM: mworker: does not deinit anymore + - BUG/MEDIUM: mworker: does not close inherited FD + - MINOR: tests: add a python wrapper to test inherited fd + - BUG/MINOR: Allocate the log buffers before the proxies startup + - MINOR: tasks: Use a bitfield to track tasks activity per-thread + - MAJOR: polling: Use active_tasks_mask instead of tasks_run_queue + - MINOR: applets: Use a bitfield to track applets activity per-thread + - MAJOR: polling: Use active_appels_mask instead of applets_active_queue + - MEDIUM: applets: Don't process more than 200 active applets at once + - MINOR: stream: Add thread-mask of tasks/FDs/applets in "show sess all" command + - MINOR: SSL: Store the ASN1 representation of client sessions. + - MINOR: ssl: Make sure we don't shutw the connection before the handshake. + - BUG/MEDIUM: deviceatlas: ignore not valuable HTTP request data + +2017/11/11 : 1.8-rc3 + - BUILD: use MAXPATHLEN instead of NAME_MAX. + - BUG/MAJOR: threads/checks: add 4 missing spin_unlock() in various functions + - BUG/MAJOR: threads/server: missing unlock in CLI fqdn parser + - BUG/MINOR: cli: do not perform an invalid action on "set server check-port" + - BUG/MAJOR: threads/checks: wrong use of SPIN_LOCK instead of SPIN_UNLOCK + - CLEANUP: checks: remove return statements in locked functions + - BUG/MINOR: cli: add severity in "set server addr" parser + - CLEANUP: server: get rid of return statements in the CLI parser + - BUG/MAJOR: cli/streams: missing unlock on exit "show sess" + - BUG/MAJOR: threads/dns: add missing unlock on allocation failure path + - BUG/MAJOR: threads/lb: fix missing unlock on consistent hash LB + - BUG/MAJOR: threads/lb: fix missing unlock on map-based hash LB + - BUG/MEDIUM: threads/stick-tables: close a race condition on stktable_trash_expired() + - BUG/MAJOR: h2: set the connection's task to NULL when no client timeout is set + - BUG/MAJOR: thread/listeners: enable_listener must not call unbind_listener() + - BUG/MEDIUM: threads: don't try to free build option message on exit + - MINOR: applets: no need to check for runqueue's emptiness in appctx_res_wakeup() + - MINOR: add master-worker in the warning about nbproc + - MINOR: mworker: allow pidfile in mworker + foreground + - MINOR: mworker: write parent pid in the pidfile + - MINOR: mworker: do not store child pid anymore in the pidfile + - MINOR: ebtree: implement the scope-aware functions for eb32 + - MEDIUM: ebtree: specify the scope of every node inserted via eb32sc + - MINOR: ebtree: update the eb32sc parent node's scope on delete + - MEDIUM: ebtree: only consider the branches matching the scope in lookups + - MINOR: ebtree: implement eb32sc_lookup_ge_or_first() + - MAJOR: task: make use of the scope-aware ebtree functions + - MINOR: task: simplify wake_expired_tasks() to avoid unlocking in the loop + - MEDIUM: task: change the construction of the loop in process_runnable_tasks() + - MINOR: threads: use faster locks for the spin locks + - MINOR: tasks: only visit filled task slots after processing them + - MEDIUM: tasks: implement a lockless scheduler for single-thread usage + - BUG/MINOR: dns: Don't try to get the server lock if it's already held. + - BUG/MINOR: dns: Don't lock the server lock in snr_check_ip_callback(). + - DOC: Add note about encrypted password CPU usage + - BUG/MINOR: h2: set the "HEADERS_SENT" flag on stream, not connection + - BUG/MEDIUM: h2: properly send an RST_STREAM on mux stream error + - BUG/MEDIUM: h2: properly send the GOAWAY frame in the mux + - BUG/MEDIUM: h2: don't try (and fail) to send non-existing data in the mux + - MEDIUM: h2: remove the H2_SS_RESET intermediate state + - BUG/MEDIUM: h2: fix some wrong error codes on connections + - BUILD: threads: Rename SPIN/RWLOCK macros using HA_ prefix + - BUILD: enable USE_THREAD for Solaris build. + - BUG/MEDIUM: h2: don't close the connection is there are data left + - MINOR: h2: don't re-enable the connection's task when we're closing + - BUG/MEDIUM: h2: properly set H2_SF_ES_SENT when sending the final frame + - BUG/MINOR: h2: correctly check for H2_SF_ES_SENT before closing + - MINOR: h2: add new stream flag H2_SF_OUTGOING_DATA + - BUG/MINOR: h2: don't send GOAWAY on failed response + - BUG/MEDIUM: splice/threads: pipe reuse list was not protected. + - BUG/MINOR: comp: fix compilation warning compiling without compression. + - BUG/MINOR: stream-int: don't set MSG_MORE on closed request path + - BUG/MAJOR: threads/tasks: fix the scheduler again + - BUG/MINOR; ssl: Don't assume we have a ssl_bind_conf because a SNI is matched. + - MINOR: ssl: Handle session resumption with TLS 1.3 + - MINOR: ssl: Spell 0x10101000L correctly. + - MINOR: ssl: Handle sending early data to server. + - BUILD: ssl: fix build of backend without ssl + - BUILD: shctx: do not depend on openssl anymore + - BUG/MINOR: h1: the HTTP/1 make status code parser check for digits + - BUG/MEDIUM: h2: reject non-3-digit status codes + - BUG/MEDIUM: stream-int: Don't loss write's notifs when a stream is woken up + - BUG/MINOR: pattern: Rely on the sample type to copy it in pattern_exec_match + - BUG/MEDIUM: h2: split the function to send RST_STREAM + - BUG/MEDIUM: h1: ensure the chunk size parser can deal with full buffers + - MINOR: tools: don't use unlikely() in hex2i() + - BUG/MEDIUM: h2: support orphaned streams + - BUG/MEDIUM: threads/cli: fix "show sess" locking on release + - CLEANUP: mux: remove the unused "release()" function + - MINOR: cli: make "show fd" report the fd's thread mask + - BUG/MEDIUM: stream: don't ignore res.analyse_exp anymore + - CLEANUP: global: introduce variable pid_bit to avoid shifts with relative_pid + - MEDIUM: http: always reject the "PRI" method + +2017/11/03 : 1.8-rc2 + - BUG/MINOR: send-proxy-v2: fix dest_len in make_tlv call + - BUG/MINOR: send-proxy-v2: string size must include ('\0') + - MINOR: mux: Only define pipe functions on linux. + - MINOR: cache: Remove useless test for nonzero. + - MINOR: cache: Don't confuse act_return and act_parse_ret. + - BUG/MEDIUM: h2: don't try to parse incomplete H1 responses + - BUG/MEDIUM: checks/mux: always enable send-polling after connecting + - BUG/MAJOR: fix deadlock on healthchecks. + - BUG/MINOR: thread: fix a typo in the debug code + - BUILD: shctx: allow to be built without openssl + - BUG/MEDIUM: cache: don't try to resolve wrong filters + - BUG/MAJOR: buffers: fix get_buffer_nc() for data at end of buffer + - BUG/MINOR: freq: fix infinite loop on freq_ctr_period. + - BUG/MINOR: stdarg.h inclusion + - BUG/MINOR: dns: fix missing lock protection on server. + - BUG/MINOR: lua: fix missing lock protection on server. + - BUILD: enable USE_THREAD for OpenBSD build. + - BUG/MAJOR: mux_pt: don't dereference a connstream after ->wake() + - MINOR: thread: report multi-thread support in haproxy -vv + +2017/10/31 : 1.8-rc1 + - BUG/MEDIUM: server: Allocate tmptrash before using it. + - CONTRIB: trace: add the possibility to place trace calls in the code + - CONTRIB: trace: try to display the function's return value on exit + - CONTRIB: trace: report the base name only for file names + - BUILD: ssl: support OPENSSL_NO_ASYNC #define + - MINOR: ssl: build with recent BoringSSL library + - BUG/MINOR: ssl: OCSP_single_get0_status can return -1 + - BUG/MINOR: cli: restore "set ssl tls-key" command + - CLEANUP: cli: remove undocumented "set ssl tls-keys" command + - IMPORT: sha1: import SHA1 functions + - MINOR: sample: add the sha1 converter + - MINOR: sample: add the hex2i converter + - MINOR: stream-int: stop checking for useless connection flags in chk_snd_conn + - MINOR: ssl: don't abort after sending 16kB + - MINOR: connection: move the cleanup of flag CO_FL_WAIT_ROOM + - MINOR: connection: add flag CO_FL_WILL_UPDATE to indicate when updates are granted + - MEDIUM: connection: make use of CO_FL_WILL_UPDATE in conn_sock_shutw() + - MINOR: raw_sock: make use of CO_FL_WILL_UPDATE + - MINOR: ssl_sock: make use of CO_FL_WILL_UPDATE + - BUG/MINOR: checks: Don't forget to release the connection on error case. + - MINOR: buffer: add the buffer input manipulation functions + - BUG/MEDIUM: prevent buffers being overwritten during build_logline() execution + - MEDIUM: cfgparse: post section callback + - MEDIUM: cfgparse: post parsing registration + - MINOR: lua: add uuid to the Class Proxy + - MINOR: hlua: Add regex class + - MINOR: http: Mark the 425 code as "Too Early". + - MEDIUM: ssl: convert CBS (BoringSSL api) usage to neutral code + - MINOR: ssl: support Openssl 1.1.1 early callback for switchctx + - MINOR: ssl: generated certificate is missing in switchctx early callback + - MEDIUM: ssl: Handle early data with OpenSSL 1.1.1 + - BUILD: Makefile: disable -Wunused-label + - MINOR: ssl/proto_http: Add keywords to take care of early data. + - BUG/MINOR: lua: const attribute of a string is overridden + - MINOR: ssl: Don't abuse ssl_options. + - MINOR: update proxy-protocol-v2 #define + - MINOR: merge ssl_sock_get calls for log and ppv2 + - MINOR: add ALPN information to send-proxy-v2 + - MEDIUM: h1: ensure that 1xx, 204 and 304 don't have a payload body + - CLEANUP: shctx: get ride of the shsess_packet{_hdr} structures + - MEDIUM: lists: list_for_each_entry{_safe}_from functions + - REORG: shctx: move lock functions and struct + - MEDIUM: shctx: allow the use of multiple shctx + - REORG: shctx: move ssl functions to ssl_sock.c + - MEDIUM: shctx: separate ssl and shctx + - MINOR: shctx: rename lock functions + - MINOR: h1: store the status code in the H1 message + - BUG/MINOR: spoe: Don't compare engine name and SPOE scope when both are NULL + - BUG/MINOR: spoa: Update pointer on the end of the frame when a reply is encoded + - MINOR: action: Add trk_idx inline function + - MINOR: action: Use trk_idx instead of tcp/http_trk_idx + - MINOR: action: Add a function pointer in act_rule struct to check its validity + - MINOR: action: Add function to check rules using an action ACT_ACTION_TRK_* + - MINOR: action: Add a functions to check http capture rules + - MINOR: action: Factorize checks on rules calling check_ptr if defined + - MINOR: acl: Pass the ACLs as an explicit parameter of build_acl_cond + - MEDIUM: spoe: Add support of ACLS to enable or disable sending of SPOE messages + - MINOR: spoe: Check uniqness of SPOE engine names during config parsing + - MEDIUM: spoe: Parse new "spoe-group" section in SPOE config file + - MEDIUM: spoe/rules: Add "send-spoe-group" action for tcp/http rules + - MINOR: spoe: Move message encoding in its own function + - MINOR: spoe: Add a type to qualify the message list during encoding + - MINOR: spoe: Add a generic function to encode a list of SPOE message + - MEDIUM: spoe/rules: Process "send-spoe-group" action + - BUG/MINOR: dns: Fix CLI keyword declaration + - MAJOR: dns: Refactor the DNS code + - BUG/MINOR: mailers: Fix a memory leak when email alerts are released + - MEDIUM: mailers: Init alerts during conf parsing and refactor their processing + - MINOR: mailers: Use pools to allocate email alerts and its tcpcheck_rules + - MINOR: standard: Add memvprintf function + - MINOR: log: Save alerts and warnings emitted during HAProxy startup + - MINOR: cli: Add "show startup-logs" command + - MINOR: startup: Extend the scope the MODE_STARTING flag + - MINOR: threads: Prepare makefile to link with pthread + - MINOR: threads: Add THREAD_LOCAL macro + - MINOR: threads: Add atomic-ops and plock includes in import dir + - MEDIUM: threads: Add hathreads header file + - MINOR: threads: Add mechanism to register per-thread init/deinit functions + - MINOR: threads: Add nbthread parameter + - MEDIUM: threads: Adds a set of functions to handle sync-point + - MAJOR: threads: Start threads to experiment multithreading + - MINOR: threads: Define the sync-point inside run_poll_loop + - MEDIUM: threads/buffers: Define and register per-thread init/deinit functions + - MEDIUM: threads/chunks: Transform trash chunks in thread-local variables + - MEDIUM: threads/time: Many global variables from time.h are now thread-local + - MEDIUM: threads/logs: Make logs thread-safe + - MEDIUM: threads/pool: Make pool thread-safe by locking all access to a pool + - MAJOR: threads/fd: Make fd stuffs thread-safe + - MINOR: threads/fd: Add a mask of threads allowed to process on each fd in fdtab array + - MEDIUM: threads/fd: Initialize the process mask during the call to fd_insert + - MINOR: threads/fd: Process cached events of FDs depending on the process mask + - MINOR: threads/polling: pollers now handle FDs depending on the process mask + - WIP: SQUASH WITH SYNC POINT + - MAJOR: threads/task: handle multithread on task scheduler + - MEDIUM: threads/signal: Add a lock to make signals thread-safe + - MEDIUM: threads/listeners: Make listeners thread-safe + - MEDIUM: threads/proxy: Add a lock per proxy and atomically update proxy vars + - MEDIUM: threads/server: Make connection list (priv/idle/safe) thread-safe + - MEDIUM: threads/server: Add a lock per server and atomically update server vars + - MINOR: threads/server: Add a lock to deal with insert in updates_servers list + - MEDIUM: threads/lb: Make LB algorithms (lb_*.c) thread-safe + - MEDIUM: threads/stick-tables: handle multithreads on stick tables + - MINOR: threads/sample: Change temp_smp into a thread local variable + - MEDIUM: threads/http: Make http_capture_bad_message thread-safe + - MINOR: threads/regex: Change Regex trash buffer into a thread local variable + - MAJOR: threads/applet: Handle multithreading for applets + - MAJOR: threads/peers: Make peers thread safe + - MAJOR: threads/buffer: Make buffer wait queue thread safe + - MEDIUM: threads/stream: Make streams list thread safe + - MAJOR: threads/ssl: Make SSL part thread-safe + - MEDIUM: threads/queue: Make queues thread-safe + - MAJOR: threads/map: Make acls/maps thread safe + - MEDIUM: threads/freq_ctr: Make the frequency counters thread-safe + - MEDIUM: thread/vars: Make vars thread-safe + - MEDIUM: threads/filters: Add init/deinit callback per thread + - MINOR: threads/filters: Update trace filter to add _per_thread callbacks + - MEDIUM: threads/compression: Make HTTP compression thread-safe + - MEDIUM: threads/lua: Makes the jmpbuf and some other buffers local to the current thread. + - MEDIUM: threads/lua: Add locks around the Lua execution parts. + - MEDIUM: threads/lua: Ensure that the launched tasks runs on the same threads than me + - MEDIUM: threads/lua: Cannot acces to the socket if we try to access from another thread. + - MEDIUM: threads/xref: Convert xref function to a thread safe model + - MEDIUM: threads/tasks: Add lock around notifications + - MEDIUM: thread/spoe: Make the SPOE thread-safe + - MEDIUM: thread/dns: Make DNS thread-safe + - MINOR: threads: Add thread-map config parameter in the global section + - MINOR: threads/checks: Add a lock to protect the pid list used by external checks + - MINOR: threads/checks: Set the task process_mask when a check is executed + - MINOR: threads/mailers: Add a lock to protect queues of email alerts + - MEDIUM: threads/server: Use the server lock to protect health check and cli concurrency + - MINOR: threads: Don't start when device a detection module is used + - BUG/MEDIUM: threads: Run the poll loop on the main thread too + - BUG/MINOR: threads: Add missing THREAD_LOCAL on static here and there + - MAJOR: threads: Offically enable the threads support in HAProxy + - BUG/MAJOR: threads/freq_ctr: fix lock on freq counters. + - BUG/MAJOR: threads/time: Store the time deviation in an 64-bits integer + - BUILD: stick-tables: silence an uninitialized variable warning + - BUG/MINOR: dns: Fix SRV records with the new thread code. + - MINOR: ssl: Remove the global allow-0rtt option. + - CLEANUP: threads: replace the last few 1UL<detach() release the connection + - MEDIUM: stream: do not forcefully close the client connection anymore + - MEDIUM: checks: exclusively use cs_destroy() to release a connection + - MEDIUM: connection: add a destroy callback + - MINOR: session: release the listener with the session, not the stream + - MEDIUM: session: make use of the connection's destroy callback + - CONTRIB: hpack: implement a reverse huffman table generator for hpack + - MINOR: hpack: implement the HPACK Huffman table decoder + - MINOR: hpack: implement the header tables management + - MINOR: hpack: implement the decoder + - MEDIUM: hpack: implement basic hpack encoding + - MINOR: h2: centralize all HTTP/2 protocol elements and constants + - MINOR: h2: create a very minimalistic h2 mux + - MINOR: h2: expose tune.h2.header-table-size to configure the table size + - MINOR: h2: expose tune.h2.initial-window-size to configure the window size + - MINOR: h2: expose tune.h2.max-concurrent-streams to limit the number of streams + - MINOR: h2: create the h2c struct and allocate its pool + - MINOR: h2: create the h2s struct and the associated pool + - MINOR: h2: handle two extra stream states for errors + - MINOR: h2: add a frame header descriptor for incoming frames + - MEDIUM: h2: allocate and release the h2c context on connection init/end + - MEDIUM: h2: implement basic recv/send/wake functions + - MEDIUM: h2: dynamically allocate the demux buffer on Rx + - MEDIUM: h2: implement the mux buffer allocator + - MINOR: h2: add the connection and stream flags listing the causes for blocking + - MINOR: h2: add function h2s_id() to report a stream's ID + - MINOR: h2: small function to know when the mux is busy + - MINOR: h2: new function h2c_error to mark an error on the connection + - MINOR: h2: new function h2s_error() to mark an error on a stream + - MINOR: h2: add h2_set_frame_size() to update the size in a binary frame + - MINOR: h2: new function h2_peek_frame_hdr() to retrieve a new frame header + - MINOR: h2: add a few functions to retrieve contents from a wrapping buffer + - MINOR: h2: add stream lookup function based on the stream ID + - MINOR: h2: create dummy idle and closed streams + - MINOR: h2: add the function to create a new stream + - MINOR: h2: update the {MUX,DEM}_{M,D}ALLOC flags on buffer availability + - MEDIUM: h2: start to consider the H2_CF_{MUX,DEM}_* flags for polling + - MINOR: h2: also terminate the connection on shutr + - MEDIUM: h2: properly consider all conditions for end of connection + - MEDIUM: h2: wake the connection up for send on pending streams + - MEDIUM: h2: start to implement the frames processing loop + - MINOR: h2: add a function to send a GOAWAY error frame + - MINOR: h2: match the H2 connection preface on init + - MEDIUM: h2: enable connection polling for send when a cs wants to emit + - MEDIUM: h2: enable reading again on the connection if it was blocked on stream buffer full + - MEDIUM: h2: process streams pending for sending + - MINOR: h2: send a real SETTINGS frame based on the configuration + - MEDIUM: h2: detect the presence of the first settings frame + - MINOR: h2: create a stream parser for the demuxer + - MINOR: h2: implement PING frames + - MEDIUM: h2: decode SETTINGS frames and extract relevant settings + - MINOR: h2: lookup the stream during demuxing + - MEDIUM: h2: honor WINDOW_UPDATE frames + - MINOR: h2: implement h2_send_rst_stream() to send RST_STREAM frames + - MINOR: h2: handle CONTINUATION frames + - MEDIUM: h2: partial implementation of h2_detach() + - MEDIUM: h2: unblock a connection when its current stream detaches + - MEDIUM: h2: basic processing of HEADERS frame + - MEDIUM: h2: don't use trash to decode headers! + - MEDIUM: h2: implement the response HEADERS frame to encode the H1 response + - MEDIUM: h2: send the H1 response body as DATA frames + - MEDIUM: h2: skip the response trailers if any + - MEDIUM: h2: properly continue to parse header block when facing a 1xx response + - MEDIUM: h2: send WINDOW_UPDATE frames for connection + - MEDIUM: h2: handle request body in DATA frames + - MINOR: h2: handle RST_STREAM frames + - MEDIUM: h2: send DATA+ES or RST_STREAM on shutw/shutr + - MINOR: h2: use a common function to signal some and all streams. + - MEDIUM: h2: handle GOAWAY frames + - MINOR: h2: centralize the check for the idle streams + - MINOR: h2: centralize the check for the half-closed(remote) streams + - MEDIUM: h2: silently ignore frames higher than last_id after GOAWAY + - MINOR: h2: properly reject PUSH_PROMISE frames coming from the client + - MEDIUM: h2: perform a graceful shutdown on "Connection: close" + - MEDIUM: h2: send a GOAWAY frame when dealing with an empty response + - MEDIUM: h2: apply a timeout to h2 connections + - BUG/MEDIUM: h2: fix incorrect timeout handling on the connection + - MEDIUM: shctx: forbid shctx to read more than expected + - MEDIUM: cache: configuration parsing and initialization + - MEDIUM: cache: store objects in cache + - MEDIUM: cache: deliver objects from cache + +2017/10/22 : 1.8-dev3 + - REORG: ssl: move defines and methodVersions table upper + - MEDIUM: ssl: ctx_set_version/ssl_set_version func for methodVersions table + - MINOR: ssl: support ssl-min-ver and ssl-max-ver with crt-list + - MEDIUM: ssl: disable SSLv3 per default for bind + - BUG/MAJOR: ssl: fix segfault on connection close using async engines. + - BUG/MAJOR: ssl: buffer overflow using offloaded ciphering on async engine + - BUG/MINOR: ssl: do not call directly the conn_fd_handler from async_fd_handler + - BUG/MINOR: haproxy/cli : fix for solaris/illumos distros for CMSG* macros + - BUG/MEDIUM: build without openssl broken + - BUG/MINOR: warning: need_resend may be used uninitialized + - BUG/MEDIUM: misplaced exit and wrong exit code + - BUG/MINOR: Makefile: fix compile error with USE_LUA=1 in ubuntu16.04 + - BUILD: scripts: make publish-release support bare repositories + - BUILD: scripts: add an automatic mode for publish-release + - BUILD: scripts: add a "quiet" mode to publish-release + - BUG/MAJOR: http: call manage_client_side_cookies() before erasing the buffer + - BUG/MINOR: buffers: Fix bi/bo_contig_space to handle full buffers + - CONTRIB: plug qdiscs: Plug queuing disciplines mini HOWTO. + - BUG/MINOR: acls: Set the right refflag when patterns are loaded from a map + - BUG/MINOR: ssl: Be sure that SSLv3 connection methods exist for openssl < 1.1.0 + - BUG/MINOR: http/filters: Be sure to wait if a filter loops in HTTP_MSG_ENDING + - BUG/MEDIUM: peers: Peers CLOSE_WAIT issue. + - BUG/MAJOR: server: Segfault after parsing server state file. + - BUG/MEDIUM: unix: never unlink a unix socket from the file system + - scripts: create-release pass -n to tail + - SCRIPTS: create-release: enforce GIT_COMMITTER_{NAME|EMAIL} validity + - BUG/MEDIUM: fix segfault when no argument to -x option + - MINOR: warning on multiple -x + - MINOR: mworker: don't copy -x argument anymore in copy_argv() + - BUG/MEDIUM: mworker: don't reuse PIDs passed to the master + - BUG/MINOR: Wrong peer task expiration handling during synchronization processing. + - BUG/MINOR: cfgparse: Check if tune.http.maxhdr is in the range 1..32767 + - BUG/MINOR: log: pin the front connection when front ip/ports are logged + - DOC: fix references to the section about the unix socket + - BUG/MINOR: stream: flag TASK_WOKEN_RES not set if task in runqueue + - MAJOR: task: task scheduler rework. + - MINOR: task/stream: tasks related to a stream must be init by the caller. + - MINOR: queue: Change pendconn_get_next_strm into private function + - MINOR: backends: Change get_server_sh/get_server_uh into private function + - MINOR: queue: Change pendconn_from_srv/pendconn_from_px into private functions + - MEDIUM: stream: make stream_new() always set the target and analysers + - MINOR: frontend: initialize HTTP layer after the debugging code + - MINOR: connection: add a .get_alpn() method to xprt_ops + - MINOR: ssl: add a get_alpn() method to ssl_sock + - MINOR: frontend: retrieve the ALPN name when available + - MINOR: frontend: report the connection's ALPN in the debug output + - MINOR: stream: don't set backend's nor response analysers on SF_TUNNEL + - MINOR: connection: send data before receiving + - MAJOR: applet: applet scheduler rework. + - BUG/MAJOR: frontend: don't dereference a null conn on outgoing connections + - BUG/MAJOR: cli: fix custom io_release was crushed by NULL. + - BUG/MAJOR: map: fix segfault during 'show map/acl' on cli. + - BUG/MAJOR: compression: Be sure to release the compression state in all cases + - MINOR: compression: Use a memory pool to allocate compression states + - BUG/MAJOR: applet: fix a freeze if data is immedately forwarded. + - DOC: fix references to the section about time format. + - BUG/MEDIUM: map/acl: fix unwanted flags inheritance. + - BUG/MAJOR: http: fix buffer overflow on loguri buffer. + - MINOR: ssl: compare server certificate names to the SNI on outgoing connections + - BUG/MINOR: stream: Don't forget to remove CF_WAKE_ONCE flag on response channel + - BUG/MINOR: http: Don't reset the transaction if there are still data to send + - BUG/MEDIUM: filters: Be sure to call flt_end_analyze for both channels + - MINOR: peers: Add additional information to stick-table definition messages. + - BUG/MINOR: http: properly handle all 1xx informational responses + - OPTIM: ssl: don't consider a small ssl_read() as an indication of end of buffer + - BUG/MINOR: peers: peer synchronization issue (with several peers sections). + - CLEANUP: hdr_idx: make some function arguments const where possible + - BUG/MINOR: Prevent a use-after-free on error scenario on option "-x". + - BUG/MINOR: lua: In error case, the safe mode is not removed + - BUG/MINOR: lua: executes the function destroying the Lua session in safe mode + - BUG/MAJOR: lua/socket: resources not detroyed when the socket is aborted + - BUG/MEDIUM: lua: bad memory access + - BUG/MINOR: Lua: variable already initialized + - DOC: update CONTRIBUTING regarding optional parts and message format + - DOC: update the list of OpenSSL versions in the README + - BUG/MINOR: http: Set the response error state in http_sync_res_state + - MINOR: http: Reorder/rewrite checks in http_resync_states + - MINOR: http: Switch requests/responses in TUNNEL mode only by checking txn flags + - BUG/MEDIUM: http: Switch HTTP responses in TUNNEL mode when body length is undefined + - MINOR: http: Rely on analyzers mask to end processing in forward_body functions + - BUG/MINOR: http: Fix bug introduced in previous patch in http_resync_states + - BUG/MINOR: contrib/modsecurity: BSD build fix + - BUG/MINOR: contrib/mod_defender: build fix + - BUG/MINOR: ssl: remove haproxy SSLv3 support when ssl lib have no SSLv3 + - MINOR: ssl: remove an unecessary SSL_OP_NO_* dependancy + - BUILD: ssl: fix compatibility with openssl without TLSEXT_signature_* + - MINOR: tools: add a portable timegm() alternative + - BUILD: lua: replace timegm() with my_timegm() to fix build on Solaris 10 + - DOC: Updated 51Degrees git URL to point to a stable version. + - BUG/MAJOR: http: Fix possible infinity loop in http_sync_(req|res)_state + - MINOR: memory: remove macros + - BUG/MINOR: lua: Fix Server.get_addr() port values + - BUG/MINOR: lua: Correctly use INET6_ADDRSTRLEN in Server.get_addr() + - MINOR: samples: Handle the type SMP_T_METH when we duplicate a sample in smp_dup + - MINOR: samples: Handle the type SMP_T_METH in smp_is_safe and smp_is_rw + - MINOR: samples: Don't allocate memory for SMP_T_METH sample when method is known + - BUG/MINOR: lua: always detach the tcp/http tasks before freeing them + - MINOR: task: always preinitialize the task's timeout in task_init() + - CLEANUP: task: remove all initializations to TICK_ETERNITY after task_new() + - BUG/MAJOR: lua: properly dequeue hlua_applet_wakeup() for new scheduler + - MINOR: lua: Add proxy as member of proxy object. + - DOC: lua: Proxy class doc update + - MINOR: lua: Add lists of frontends and backends + - BUG/MINOR: ssl: Fix check against SNI during server certificate verification + - BUG/MINOR: ssl: make use of the name in SNI before verifyhost + - MINOR: ssl: add a new error codes for wrong server certificates + - BUG/MEDIUM: stream: don't retry SSL connections which fail the SNI name check + - MINOR: ssl: add "no-ca-names" parameter for bind + - BUG/MINOR: lua: Fix bitwise logic for hlua_server_check_* functions. + - DOC: fix alphabetical order of "show commands" in management.txt + - MINOR: listener: add a function to return a listener's state as a string + - MINOR: cli: add a new "show fd" command + - BUG/MEDIUM: ssl: Fix regression about certificates generation + - MINOR: Add server port field to server state file. + - MINOR: ssl: allow to start without certificate if strict-sni is set + - MINOR: dns: Cache previous DNS answers. + - MINOR: obj: Add a new type of object, OBJ_TYPE_SRVRQ. + - Add a few functions to do unaligned access. + - MINOR: dns: Handle SRV records. + - MINOR: check: Fix checks when using SRV records. + - MINOR: doc: Document SRV label usage. + - BUILD/MINOR: cli: shut a minor gcc warning in "show fd" + - BUILD: ssl: replace SSL_CTX_get0_privatekey for openssl < 1.0.2 + - BUILD/MINOR: build without openssl still broken + - BUG/MAJOR: stream: in stream_free(), close the front endpoint and not the origin + - CLEANUP: raw_sock: Use a better name for the constructor than __ssl_sock_deinit() + - MINOR: init: Fix CPU affinity setting on FreeBSD. + - MINOR: dns: Update analysis of TRUNCATED response for SRV records + - MINOR: dns: update record dname matching for SRV query types + - MINOR: dns: update dns response buffer reading pointer due to SRV record + - MINOR: dns: duplicate entries in resolution wait queue for SRV records + - MINOR: dns: make debugging function dump_dns_config() compatible with SRV records + - MINOR: dns: ability to use a SRV resolution for multiple backends + - MINOR: dns: enable caching of responses for server set by a SRV record + - MINOR: dns: new dns record type (RTYPE) for OPT + - MINOR: dns: enabled edns0 extension and make accpeted payload size tunable + - MINOR: dns: default "hold obsolete" timeout set to 0 + - MINOR: chunks: add chunk_memcpy() and chunk_memcat() + - MINOR: session: add a streams field to the session struct + - MINOR: stream: link the stream to its session + - MEDIUM: session: do not free a session until no stream references it + - MINOR: ist: implement very simple indirect strings + - TESTS: ist: add a test file for the functions + - MINOR: http: export some of the HTTP parser macros + - BUG/MINOR: Wrong type used as argument for spoe_decode_buffer(). + - BUG/MINOR: dns: server set by SRV records stay in "no resolution" status + - MINOR: dns: Maximum DNS udp payload set to 8192 + - MINOR: dns: automatic reduction of DNS accpeted payload size + - MINOR: dns: make SRV record processing more verbose + - CLEANUP: dns: remove duplicated code in dns_resolve_recv() + - CLEANUP: dns: remove duplicated code in dns_validate_dns_response() + - BUG/MINOR: dns: wrong resolution interval lead to 100% CPU + - BUG/MEDIUM: dns: fix accepted_payload_size parser to avoid integer overflow + - BUG/MAJOR: lua: fix the impact of the scheduler changes again + - BUG/MEDIUM: lua: HTTP services must take care of body-less status codes + - MINOR: lua: properly process the contents of the content-length field + - BUG/MEDIUM: stream: properly set the required HTTP analysers on use-service + - OPTIM: lua: don't use expensive functions to parse headers in the HTTP applet + - OPTIM: lua: don't add "Connection: close" on the response + - REORG/MEDIUM: connection: introduce the notion of connection handle + - BUG/MINOR: stream-int: don't check the CO_FL_CURR_WR_ENA flag + - MEDIUM: connection: get rid of data->init() which was not for data + - MEDIUM: stream: make stream_new() allocate its own task + - CLEANUP: listener: remove the unused handler field + - MEDIUM: session: add a pointer to a struct task in the session + - MINOR: stream: provide a new stream creation function for connections + - MEDIUM: connection: remove useless flag CO_FL_DATA_RD_SH + - CLEANUP: connection: remove the unused conn_sock_shutw_pending() + - MEDIUM: connection: remove useless flag CO_FL_DATA_WR_SH + - DOC: add CLI info on privilege levels + - DOC: Refer to Mozilla TLS info / config generator + - MINOR: ssl: remove duplicate ssl_methods in struct bind_conf + - BUG/MEDIUM: http: Fix a regression bug when a HTTP response is in TUNNEL mode + - DOC: Add note about "* " prefix in CSV stats + - CLEANUP: memory: Remove unused function pool_destroy + - MINOR: listeners: Change listener_full and limit_listener into private functions + - MINOR: listeners: Change enable_listener and disable_listener into private functions + - MINOR: fd: Don't forget to reset fdtab[fd].update when a fd is added/removed + - MINOR: fd: Set owner and iocb field before inserting a new fd in the fdtab + - MINOR: backends: Make get_server_* functions explicitly static + - MINOR: applet: Check applets_active_queue before processing applets queue + - MINOR: chunks: Use dedicated function to init/deinit trash buffers + - MEDIUM: chunks: Realloc trash buffers only after the config is parsed and checked + - MINOR: logs: Use dedicated function to init/deinit log buffers + - MINOR: logs: Realloc log buffers only after the config is parsed and checked + - MINOR: buffers: Move swap_buffer into buffer.c and add deinit_buffer function + - MINOR: stick-tables: Make static_table_key a struct variable instead of a pointer + - MINOR: http: Use a trash chunk to store decoded string of the HTTP auth header + - MINOR: fd: Add fd_active function + - MINOR: fd: Use inlined functions to check fd state in fd_*_send/recv functions + - MINOR: fd: Move (de)allocation of fdtab and fdinfo in (de)init_pollers + - MINOR: freq_ctr: Return the new value after an update + - MEDIUM: check: server states and weight propagation re-work + - BUG/MEDIUM: epoll: ensure we always consider HUP and ERR + - MINOR: fd: Add fd_update_events function + - MINOR: polling: Use fd_update_events to update events seen for a fd + - BUG/MINOR: server: Remove FQDN requirement for using init-addr and state file + - Revert "BUG/MINOR: server: Remove FQDN requirement for using init-addr and state file" + - MINOR: ssl: rework smp_fetch_ssl_fc_cl_str without internal ssl use + - BUG/MEDIUM: http: Close streams for connections closed before a redirect + - BUG/MINOR: Lua: The socket may be destroyed when we try to access. + - MINOR: xref: Add a new xref system + - MEDIUM: xref/lua: Use xref for referencing cosocket relation between stream and lua + - MINOR: tasks: Move Lua notification from Lua to tasks + - MINOR: net_helper: Inline functions meant to be inlined. + - MINOR: cli: add socket commands and config to prepend informational messages with severity + - MINOR: add severity information to cli feedback messages + - BUILD: Makefile: add a function to detect support by the compiler of certain options + - BUILD: Makefile: shut certain gcc/clang stupid warnings + - BUILD: Makefile: improve detection of support for compiler warnings + - MINOR: peers: don't reference the incoming listener on outgoing connections + - MINOR: frontend: don't retrieve ALPN on the critical path + - MINOR: protocols: always pass a "port" argument to the listener creation + - MINOR: protocols: register the ->add function and stop calling them directly + - MINOR: unix: remove the now unused proto_uxst.h file + - MINOR: listeners: new function create_listeners + - MINOR: listeners: make listeners count consistent with reality + - MEDIUM: session: take care of incrementing/decrementing jobs + - MINOR: listener: new function listener_release + - MINOR: session: small cleanup of conn_complete_session() + - MEDIUM: session: factor out duplicated code for conn_complete_session + - MEDIUM: session: count the frontend's connections at a single place + - BUG/MEDIUM: compression: Fix check on txn in smp_fetch_res_comp_algo + - BUG/MINOR: compression: Check response headers before http-response rules eval + - BUG/MINOR: spoe: Don't rely on SPOE ctx in debug message when its creation failed + - BUG/MINOR: dns: Fix check on nameserver in snr_resolution_cb + - MINOR: ssl: Remove useless checks on bind_conf or bind_conf->is_ssl + - BUG/MINOR: contrib/mod_defender: close the va_list argp before return + - BUG/MINOR: contrib/modsecurity: close the va_list ap before return + - MINOR: tools: make my_htonll() more efficient on x86_64 + - MINOR: buffer: add b_del() to delete a number of characters + - MINOR: buffer: add b_end() and b_to_end() + - MINOR: net_helper: add functions to read from vectors + - MINOR: net_helper: add write functions + - MINOR: net_helper: add 64-bit read/write functions + - MINOR: connection: adjust CO_FL_NOTIFY_DATA after removal of flags + - MINOR: ist: add a macro to ease const array initialization + - BUG/MEDIUM: server: unwanted behavior leaving maintenance mode on tracked stopping server + - BUG/MEDIUM: server: unwanted behavior leaving maintenance mode on tracked stopping server (take2) + - BUG/MINOR: log: fixing small memory leak in error code path. + - BUG/MINOR: contrib/halog: fixing small memory leak + - BUG/MEDIUM: tcp/http: set-dst-port action broken + - CLEANUUP: checks: don't set conn->handle.fd to -1 + - BUG/MEDIUM: tcp-check: properly indicate polling state before performing I/O + - BUG/MINOR: tcp-check: don't quit with pending data in the send buffer + - BUG/MEDIUM: tcp-check: don't call tcpcheck_main() from the I/O handlers! + - BUG/MINOR: unix: properly check for octal digits in the "mode" argument + - MINOR: checks: make chk_report_conn_err() take a check, not a connection + - CLEANUP: checks: remove misleading comments and statuses for external process + - CLEANUP: checks: don't report report the fork() error twice + - CLEANUP: checks: do not allocate a connection for process checks + - TESTS: checks: add a simple test config for external checks + - BUG/MINOR: tcp-check: don't initialize then break a connection starting with a comment + - TESTS: checks: add a simple test config for tcp-checks + - MINOR: tcp-check: make tcpcheck_main() take a check, not a connection + - MINOR: checks: don't create then kill a dummy connection before tcp-checks + - MEDIUM: checks: make tcpcheck_main() indicate if it recycled a connection + - MEDIUM: checks: do not allocate a permanent connection anymore + - BUG/MEDIUM: cli: fix "show fd" crash when dumping closed FDs + - BUG/MEDIUM: http: Return an error when url_dec sample converter failed + - BUG/MAJOR: stream-int: don't re-arm recv if send fails + - BUILD/MINOR: 51d: fix warning when building with 51Degrees release version 3.2.12.12 + - DOC: 51d: add 51Degrees git URL that points to release version 3.2.12.12 + - DOC: 51d: Updated git URL and instructions for getting Hash Trie data files. + - MINOR: compiler: restore the likely() wrapper for gcc 5.x + - MINOR: session: remove the list of streams from struct session + - DOC: fix some typos + - MINOR: server: add the srv_queue() sample fetch method + - MINOR: payload: add new sample fetch functions to process distcc protocol + - MAJOR: servers: propagate server status changes asynchronously. + - BUG/MEDIUM: ssl: fix OCSP expiry calculation + - BUG/MINOR: stream-int: don't set MSG_MORE on SHUTW_NOW without AUTO_CLOSE + - MINOR: server: Handle weight increase in consistent hash. + - MINOR: checks: Add a new keyword to specify a SNI when doing SSL checks. + - BUG/MINOR: tools: fix my_htonll() on x86_64 + - BUG/MINOR: stats: Clear a bit more counters with in cli_parse_clear_counters(). + - BUG/MAJOR: lua: scheduled task is freezing. + - MINOR: buffer: add bo_del() to delete a number of characters from output + - MINOR: buffer: add a function to match against string patterns + - MINOR: buffer: add two functions to inject data into buffers + - MINOR: buffer: add buffer_space_wraps() + - REORG: channel: finally rename the last bi_* / bo_* functions + - MINOR: buffer: add bo_getblk() and bo_getblk_nc() + - MINOR: channel: make use of bo_getblk{,_nc} for their channel equivalents + - MINOR: channel: make the channel be a const in all {ci,co}_get* functions + - MINOR: ist: add ist0() to add a trailing zero to a string. + - BUG/MEDIUM: log: check result details truncated. + - MINOR: buffer: make bo_getblk_nc() not return 2 for a full buffer + - REORG: http: move some very http1-specific parts to h1.{c,h} + - REORG: http: move the HTTP/1 chunk parser to h1.{c,h} + - REORG: http: move the HTTP/1 header block parser to h1.c + - MEDIUM: http: make the chunk size parser only depend on the buffer + - MEDIUM: http: make the chunk crlf parser only depend on the buffer + - MINOR: h1: add struct h1m for basic HTTP/1 messages + - MINOR: http: add very simple header management based on double strings + - MEDIUM: h1: reimplement the http/1 response parser for the gateway + - REORG: connection: rename CO_FL_DATA_* -> CO_FL_XPRT_* + - MEDIUM: connection: make conn_sock_shutw() aware of lingering + - MINOR: connection: ensure conn_ctrl_close() also resets the fd + - MINOR: connection: add conn_stop_tracking() to disable tracking + - MINOR: tcp: use conn_full_close() instead of conn_force_close() + - MINOR: unix: use conn_full_close() instead of conn_force_close() + - MINOR: checks: use conn_full_close() instead of conn_force_close() + - MINOR: session: use conn_full_close() instead of conn_force_close() + - MINOR: stream: use conn_full_close() instead of conn_force_close() + - MINOR: stream: use conn_full_close() instead of conn_force_close() + - MINOR: backend: use conn_full_close() instead of conn_force_close() + - MINOR: stream-int: use conn_full_close() instead of conn_force_close() + - MINOR: connection: remove conn_force_close() + - BUG/MINOR: ssl: ocsp response with 'revoked' status is correct + +2017/06/02 : 1.8-dev2 + - CLEANUP: server: moving netinet/tcp.h inclusion + - DOC: changed "block"(deprecated) examples to http-request deny + - DOC: add few comments to examples. + - DOC: update sample code for PROXY protocol + - DOC: mention lighttpd 1.4.46 implements PROXY + - MINOR server: Restrict dynamic cookie check to the same proxy. + - DOC: stick-table is available in frontend sections + - BUG/MINOR: server : no transparent proxy for DragonflyBSD + - BUILD/MINOR: stats: remove unexpected argument to stats_dump_json_header() + - BUILD/MINOR: tools: fix build warning in debug_hexdump() + - BUG/MINOR: dns: Wrong address family used when creating IPv6 sockets. + - BUG/MINOR: config: missing goto out after parsing an incorrect ACL character + - BUG/MINOR: arg: don't try to add an argument on failed memory allocation + - MEDIUM: server: Inherit CLI weight changes and agent-check weight responses + - BUG/MEDIUM: arg: ensure that we properly unlink unresolved arguments on error + - BUG/MEDIUM: acl: don't free unresolved args in prune_acl_expr() + - BUG/MEDIUM: servers: unbreak server weight propagation + - MINOR: lua: ensure the memory allocator is used all the time + - MINOR: cli: Add a command to send listening sockets. + - MINOR: global: Add an option to get the old listening sockets. + - MINOR: tcp: When binding socket, attempt to reuse one from the old proc. + - MINOR: doc: document the -x flag + - MINOR: proxy: Don't close FDs if not our proxy. + - MINOR: socket transfer: Set a timeout on the socket. + - MINOR: systemd wrapper: add support for passing the -x option. + - BUG/MINOR: server: Fix a wrong error message during 'usesrc' keyword parsing. + - BUG/MAJOR: Broken parsing for valid keywords provided after 'source' setting. + - CLEANUP: logs: typo: simgle => single + - BUG/MEDIUM: acl: proprely release unused args in prune_acl_expr() + - MEDIUM: config: don't check config validity when there are fatal errors + - BUG/MAJOR: Use -fwrapv. + - BUG/MINOR: server: don't use "proxy" when px is really meant. + - BUG/MEDIUM: http: Drop the connection establishment when a redirect is performed + - BUG/MINOR: server: missing default server 'resolvers' setting duplication. + - MINOR: server: Extract the code responsible of copying default-server settings. + - MINOR: server: Extract the code which finalizes server initializations after 'server' lines parsing. + - MINOR: server: Add 'server-template' new keyword supported in backend sections. + - MINOR: server: Add server_template_init() function to initialize servers from a templates. + - DOC: Add documentation for new "server-template" keyword. + - DOC: add layer 4 links/cross reference to "block" keyword. + - DOC: errloc/errorloc302/errorloc303 missing status codes. + - BUG/MEDIUM: lua: memory leak + - CLEANUP: lua: remove test + - BUG/MINOR: hash-balance-factor isn't effective in certain circumstances + - BUG/MINOR: change header-declared function to static inline + - REORG: spoe: move spoe_encode_varint / spoe_decode_varint from spoe to common + - MINOR: Add binary encoding request header sample fetch + - MINOR: proto-http: Add sample fetch wich returns all HTTP headers + - MINOR: Add ModSecurity wrapper as contrib + - BUG/MINOR: ssl: fix warnings about methods for opensslv1.1. + - DOC: update RFC references + - CONTRIB: tcploop: add action "X" to execute a command + - MINOR: server: cli: Add server FQDNs to server-state file and stats socket. + - BUG/MINOR: contrib/mod_security: fix build on FreeBSD + - BUG/MINOR: checks: don't send proxy protocol with agent checks + - MINOR: ssl: add prefer-client-ciphers + - MEDIUM: ssl: revert ssl/tls version settings relative to default-server. + - MEDIUM: ssl: ssl_methods implementation is reworked and factored for min/max tlsxx + - MEDIUM: ssl: calculate the real min/max TLS version and find holes + - MINOR: ssl: support TLSv1.3 for bind and server + - MINOR: ssl: show methods supported by openssl + - MEDIUM: ssl: add ssl-min-ver and ssl-max-ver parameters for bind and server + - MEDIUM: ssl: ssl-min-ver and ssl-max-ver compatibility. + - CLEANUP: retire obsoleted USE_GETSOCKNAME build option + - BUG/MAJOR: dns: Broken kqueue events handling (BSD systems). + - MINOR: sample: Add b64dec sample converter + - BUG/MEDIUM: lua: segfault if a converter or a sample doesn't return anything + - MINOR: cli: add ACCESS_LVL_MASK to store the access level + - MINOR: cli: add 'expose-fd listeners' to pass listeners FDs + - MEDIUM: proxy: zombify proxies only when the expose-fd socket is bound + - MEDIUM: ssl: add basic support for OpenSSL crypto engine + - MAJOR: ssl: add openssl async mode support + - MEDIUM: ssl: handle multiple async engines + - MINOR: boringssl: basic support for OCSP Stapling + - MEDIUM: mworker: replace systemd mode by master worker mode + - MEDIUM: mworker: handle reload and signals + - MEDIUM: mworker: wait mode on reload failure + - MEDIUM: mworker: try to guess the next stats socket to use with -x + - MEDIUM: mworker: exit-on-failure option + - MEDIUM: mworker: workers exit when the master leaves + - DOC: add documentation for the master-worker mode + - MEDIUM: systemd: Type=forking in unit file + - MAJOR: systemd-wrapper: get rid of the wrapper + - MINOR: log: Add logurilen tunable. + - CLEANUP: server.c: missing prototype of srv_free_dns_resolution + - MINOR: dns: smallest DNS fqdn size + - MINOR: dns: functions to manage memory for a DNS resolution structure + - MINOR: dns: parse_server() now uses srv_alloc_dns_resolution() + - REORG: dns: dns_option structure, storage of hostname_dn + - MINOR: dns: new snr_check_ip_callback function + - MAJOR: dns: save a copy of the DNS response in struct resolution + - MINOR: dns: implement a LRU cache for DNS resolutions + - MINOR: dns: make 'ancount' field to match the number of saved records + - MINOR: dns: introduce roundrobin into the internal cache (WIP) + - MAJOR/REORG: dns: DNS resolution task and requester queues + - BUILD: ssl: fix build with OPENSSL_NO_ENGINE + - MINOR: Add Mod Defender integration as contrib + - CLEANUP: str2mask return code comment: non-zero -> zero. + - MINOR: tools: make debug_hexdump() use a const char for the string + - MINOR: tools: make debug_hexdump() take a string prefix + - CLEANUP: connection: remove unused CO_FL_WAIT_DATA + +2017/04/03 : 1.8-dev1 + - BUG/MEDIUM: proxy: return "none" and "unknown" for unknown LB algos + - BUG/MINOR: stats: make field_str() return an empty string on NULL + - DOC: Spelling fixes + - BUG/MEDIUM: http: Fix tunnel mode when the CONNECT method is used + - BUG/MINOR: http: Keep the same behavior between 1.6 and 1.7 for tunneled txn + - BUG/MINOR: filters: Protect args in macros HAS_DATA_FILTERS and IS_DATA_FILTER + - BUG/MINOR: filters: Invert evaluation order of HTTP_XFER_BODY and XFER_DATA analyzers + - BUG/MINOR: http: Call XFER_DATA analyzer when HTTP txn is switched in tunnel mode + - BUG/MAJOR: stream: fix session abort on resource shortage + - OPTIM: stream-int: don't disable polling anymore on DONT_READ + - BUG/MINOR: cli: allow the backslash to be escaped on the CLI + - BUG/MEDIUM: cli: fix "show stat resolvers" and "show tls-keys" + - DOC: Fix map table's format + - DOC: Added 51Degrees conv and fetch functions to documentation. + - BUG/MINOR: http: don't send an extra CRLF after a Set-Cookie in a redirect + - DOC: mention that req_tot is for both frontends and backends + - BUG/MEDIUM: variables: some variable name can hide another ones + - MINOR: lua: Allow argument for actions + - BUILD: rearrange target files by build time + - CLEANUP: hlua: just indent functions + - MINOR: lua: give HAProxy variable access to the applets + - BUG/MINOR: stats: fix be/sessions/max output in html stats + - MINOR: proxy: Add fe_name/be_name fetchers next to existing fe_id/be_id + - DOC: lua: Documentation about some entry missing + - DOC: lua: Add documentation about variable manipulation from applet + - MINOR: Do not forward the header "Expect: 100-continue" when the option http-buffer-request is set + - DOC: Add undocumented argument of the trace filter + - DOC: Fix some typo in SPOE documentation + - MINOR: cli: Remove useless call to bi_putchk + - BUG/MINOR: cli: be sure to always warn the cli applet when input buffer is full + - MINOR: applet: Count number of (active) applets + - MINOR: task: Rename run_queue and run_queue_cur counters + - BUG/MEDIUM: stream: Save unprocessed events for a stream + - BUG/MAJOR: Fix how the list of entities waiting for a buffer is handled + - BUILD/MEDIUM: Fixing the build using LibreSSL + - BUG/MEDIUM: lua: In some case, the return of sample-fetches is ignored (2) + - SCRIPTS: git-show-backports: fix a harmless typo + - SCRIPTS: git-show-backports: add -H to use the hash of the commit message + - BUG/MINOR: stream-int: automatically release SI_FL_WAIT_DATA on SHUTW_NOW + - CLEANUP: applet/lua: create a dedicated ->fcn entry in hlua_cli context + - CLEANUP: applet/table: add an "action" entry in ->table context + - CLEANUP: applet: remove the now unused appctx->private field + - DOC: lua: documentation about time parser functions + - DOC: lua: improve links + - DOC: lua: section declared twice + - MEDIUM: cli: 'show cli sockets' list the CLI sockets + - BUG/MINOR: cli: "show cli sockets" wouldn't list all processes + - BUG/MINOR: cli: "show cli sockets" would always report process 64 + - CLEANUP: lua: rename one of the lua appctx union + - BUG/MINOR: lua/cli: bad error message + - MEDIUM: lua: use memory pool for hlua struct in applets + - MINOR: lua/signals: Remove Lua part from signals. + - DOC: cli: show cli sockets + - MINOR: cli: automatically enable a CLI I/O handler when there's no parser + - CLEANUP: memory: remove the now unused cli_parse_show_pools() function + - CLEANUP: applet: group all CLI contexts together + - CLEANUP: stats: move a misplaced stats context initialization + - MINOR: cli: add two general purpose pointers and integers in the CLI struct + - MINOR: appctx/cli: remove the cli_socket entry from the appctx union + - MINOR: appctx/cli: remove the env entry from the appctx union + - MINOR: appctx/cli: remove the "be" entry from the appctx union + - MINOR: appctx/cli: remove the "dns" entry from the appctx union + - MINOR: appctx/cli: remove the "server_state" entry from the appctx union + - MINOR: appctx/cli: remove the "tlskeys" entry from the appctx union + - CONTRIB: tcploop: add limits.h to fix build issue with some compilers + - MINOR/DOC: lua: just precise one thing + - DOC: fix small typo in fe_id (backend instead of frontend) + - BUG/MINOR: Fix the sending function in Lua's cosocket + - BUG/MINOR: lua: memory leak executing tasks + - BUG/MINOR: lua: bad return code + - BUG/MINOR: lua: memleak when Lua/cli fails + - MEDIUM: lua: remove Lua struct from session, and allocate it with memory pools + - CLEANUP: haproxy: statify unexported functions + - MINOR: haproxy: add a registration for build options + - CLEANUP: wurfl: use the build options list to report it + - CLEANUP: 51d: use the build options list to report it + - CLEANUP: da: use the build options list to report it + - CLEANUP: namespaces: use the build options list to report it + - CLEANUP: tcp: use the build options list to report transparent modes + - CLEANUP: lua: use the build options list to report it + - CLEANUP: regex: use the build options list to report the regex type + - CLEANUP: ssl: use the build options list to report the SSL details + - CLEANUP: compression: use the build options list to report the algos + - CLEANUP: auth: use the build options list to report its support + - MINOR: haproxy: add a registration for post-check functions + - CLEANUP: checks: make use of the post-init registration to start checks + - CLEANUP: filters: use the function registration to initialize all proxies + - CLEANUP: wurfl: make use of the late init registration + - CLEANUP: 51d: make use of the late init registration + - CLEANUP: da: make use of the late init registration code + - MINOR: haproxy: add a registration for post-deinit functions + - CLEANUP: wurfl: register the deinit function via the dedicated list + - CLEANUP: 51d: register the deinitialization function + - CLEANUP: da: register the deinitialization function + - CLEANUP: wurfl: move global settings out of the global section + - CLEANUP: 51d: move global settings out of the global section + - CLEANUP: da: move global settings out of the global section + - MINOR: cfgparse: add two new functions to check arguments count + - MINOR: cfgparse: move parsing of "ca-base" and "crt-base" to ssl_sock + - MEDIUM: cfgparse: move all tune.ssl.* keywords to ssl_sock + - MEDIUM: cfgparse: move maxsslconn parsing to ssl_sock + - MINOR: cfgparse: move parsing of ssl-default-{bind,server}-ciphers to ssl_sock + - MEDIUM: cfgparse: move ssl-dh-param-file parsing to ssl_sock + - MEDIUM: compression: move the zlib-specific stuff from global.h to compression.c + - BUG/MEDIUM: ssl: properly reset the reused_sess during a forced handshake + - BUG/MEDIUM: ssl: avoid double free when releasing bind_confs + - BUG/MINOR: stats: fix be/sessions/current out in typed stats + - MINOR: tcp-rules: check that the listener exists before updating its counters + - MEDIUM: spoe: don't create a dummy listener for outgoing connections + - MINOR: listener: move the transport layer pointer to the bind_conf + - MEDIUM: move listener->frontend to bind_conf->frontend + - MEDIUM: ssl: remote the proxy argument from most functions + - MINOR: connection: add a new prepare_bind_conf() entry to xprt_ops + - MEDIUM: ssl_sock: implement ssl_sock_prepare_bind_conf() + - MINOR: connection: add a new destroy_bind_conf() entry to xprt_ops + - MINOR: ssl_sock: implement ssl_sock_destroy_bind_conf() + - MINOR: server: move the use_ssl field out of the ifdef USE_OPENSSL + - MINOR: connection: add a minimal transport layer registration system + - CLEANUP: connection: remove all direct references to raw_sock and ssl_sock + - CLEANUP: connection: unexport raw_sock and ssl_sock + - MINOR: connection: add new prepare_srv()/destroy_srv() entries to xprt_ops + - MINOR: ssl_sock: implement and use prepare_srv()/destroy_srv() + - CLEANUP: ssl: move tlskeys_finalize_config() to a post_check callback + - CLEANUP: ssl: move most ssl-specific global settings to ssl_sock.c + - BUG/MINOR: backend: nbsrv() should return 0 if backend is disabled + - BUG/MEDIUM: ssl: for a handshake when server-side SNI changes + - BUG/MINOR: systemd: potential zombie processes + - DOC: Add timings events schemas + - BUILD: lua: build failed on FreeBSD. + - MINOR: samples: add xx-hash functions + - MEDIUM: regex: pcre2 support + - BUG/MINOR: option prefer-last-server must be ignored in some case + - MINOR: stats: Support "select all" for backend actions + - BUG/MINOR: sample-fetches/stick-tables: bad type for the sample fetches sc*_get_gpt0 + - BUG/MAJOR: channel: Fix the definition order of channel analyzers + - BUG/MINOR: http: report real parser state in error captures + - BUILD: scripts: automatically update the branch in version.h when releasing + - MINOR: tools: add a generic hexdump function for debugging + - BUG/MAJOR: http: fix risk of getting invalid reports of bad requests + - MINOR: http: custom status reason. + - MINOR: connection: add sample fetch "fc_rcvd_proxy" + - BUG/MINOR: config: emit a warning if http-reuse is enabled with incompatible options + - BUG/MINOR: tools: fix off-by-one in port size check + - BUG/MEDIUM: server: consider AF_UNSPEC as a valid address family + - MEDIUM: server: split the address and the port into two different fields + - MINOR: tools: make str2sa_range() return the port in a separate argument + - MINOR: server: take the destination port from the port field, not the addr + - MEDIUM: server: disable protocol validations when the server doesn't resolve + - BUG/MEDIUM: tools: do not force an unresolved address to AF_INET:0.0.0.0 + - BUG/MINOR: ssl: EVP_PKEY must be freed after X509_get_pubkey usage + - BUG/MINOR: ssl: assert on SSL_set_shutdown with BoringSSL + - MINOR: Use "500 Internal Server Error" for 500 error/status code message. + - MINOR: proto_http.c 502 error txt typo. + - DOC: add deprecation notice to "block" + - MINOR: compression: fix -vv output without zlib/slz + - BUG/MINOR: Reset errno variable before calling strtol(3) + - MINOR: ssl: don't show prefer-server-ciphers output + - OPTIM/MINOR: config: Optimize fullconn automatic computation loading configuration + - BUG/MINOR: stream: Fix how backend-specific analyzers are set on a stream + - MAJOR: ssl: bind configuration per certificat + - MINOR: ssl: add curve suite for ECDHE negotiation + - MINOR: checks: Add agent-addr config directive + - MINOR: cli: Add possiblity to change agent config via CLI/socket + - MINOR: doc: Add docs for agent-addr configuration variable + - MINOR: doc: Add docs for agent-addr and agent-send CLI commands + - BUILD: ssl: fix to build (again) with boringssl + - BUILD: ssl: fix build on OpenSSL 1.0.0 + - BUILD: ssl: silence a warning reported for ERR_remove_state() + - BUILD: ssl: eliminate warning with OpenSSL 1.1.0 regarding RAND_pseudo_bytes() + - BUILD: ssl: kill a build warning introduced by BoringSSL compatibility + - BUG/MEDIUM: tcp: don't poll for write when connect() succeeds + - BUG/MINOR: unix: fix connect's polling in case no data are scheduled + - MINOR: server: extend the flags to 32 bits + - BUG/MINOR: lua: Map.end are not reliable because "end" is a reserved keyword + - MINOR: dns: give ability to dns_init_resolvers() to close a socket when requested + - BUG/MAJOR: dns: restart sockets after fork() + - MINOR: chunks: implement a simple dynamic allocator for trash buffers + - BUG/MEDIUM: http: prevent redirect from overwriting a buffer + - BUG/MEDIUM: filters: Do not truncate HTTP response when body length is undefined + - BUG/MEDIUM: http: Prevent replace-header from overwriting a buffer + - BUG/MINOR: http: Return an error when a replace-header rule failed on the response + - BUG/MINOR: sendmail: The return of vsnprintf is not cleanly tested + - BUG/MAJOR: ssl: fix a regression in ssl_sock_shutw() + - BUG/MAJOR: lua segmentation fault when the request is like 'GET ?arg=val HTTP/1.1' + - BUG/MEDIUM: config: reject anything but "if" or "unless" after a use-backend rule + - MINOR: http: don't close when redirect location doesn't start with "/" + - MEDIUM: boringssl: support native multi-cert selection without bundling + - BUG/MEDIUM: ssl: fix verify/ca-file per certificate + - BUG/MEDIUM: ssl: switchctx should not return SSL_TLSEXT_ERR_ALERT_WARNING + - MINOR: ssl: removes SSL_CTX_set_ssl_version call and cleanup CTX creation. + - BUILD: ssl: fix build with -DOPENSSL_NO_DH + - MEDIUM: ssl: add new sample-fetch which captures the cipherlist + - MEDIUM: ssl: remove ssl-options from crt-list + - BUG/MEDIUM: ssl: in bind line, ssl-options after 'crt' are ignored. + - BUG/MINOR: ssl: fix cipherlist captures with sustainable SSL calls + - MINOR: ssl: improved cipherlist captures + - BUG/MINOR: spoe: Fix soft stop handler using a specific id for spoe filters + - BUG/MINOR: spoe: Fix parsing of arguments in spoe-message section + - MAJOR: spoe: Add support of pipelined and asynchronous exchanges with agents + - MINOR: spoe: Add support for pipelining/async capabilities in the SPOA example + - MINOR: spoe: Remove SPOE details from the appctx structure + - MINOR: spoe: Add status code in error variable instead of hardcoded value + - MINOR: spoe: Send a log message when an error occurred during event processing + - MINOR: spoe: Check the scope of sample fetches used in SPOE messages + - MEDIUM: spoe: Be sure to wakeup the good entity waiting for a buffer + - MINOR: spoe: Use the min of all known max_frame_size to encode messages + - MAJOR: spoe: Add support of payload fragmentation in NOTIFY frames + - MINOR: spoe: Add support for fragmentation capability in the SPOA example + - MAJOR: spoe: refactor the filter to clean up the code + - MINOR: spoe: Handle NOTIFY frames cancellation using ABORT bit in ACK frames + - REORG: spoe: Move struct and enum definitions in dedicated header file + - REORG: spoe: Move low-level encoding/decoding functions in dedicated header file + - MINOR: spoe: Improve implementation of the payload fragmentation + - MINOR: spoe: Add support of negation for options in SPOE configuration file + - MINOR: spoe: Add "pipelining" and "async" options in spoe-agent section + - MINOR: spoe: Rely on alertif_too_many_arg during configuration parsing + - MINOR: spoe: Add "send-frag-payload" option in spoe-agent section + - MINOR: spoe: Add "max-frame-size" statement in spoe-agent section + - DOC: spoe: Update SPOE documentation to reflect recent changes + - MINOR: config: warn when some HTTP rules are used in a TCP proxy + - BUG/MEDIUM: ssl: Clear OpenSSL error stack after trying to parse OCSP file + - BUG/MEDIUM: cli: Prevent double free in CLI ACL lookup + - BUG/MINOR: Fix "get map " CLI command + - MINOR: Add nbsrv sample converter + - CLEANUP: Replace repeated code to count usable servers with be_usable_srv() + - MINOR: Add hostname sample fetch + - CLEANUP: Remove comment that's no longer valid + - MEDIUM: http_error_message: txn->status / http_get_status_idx. + - MINOR: http-request tarpit deny_status. + - CLEANUP: http: make http_server_error() not set the status anymore + - MEDIUM: stats: Add JSON output option to show (info|stat) + - MEDIUM: stats: Add show json schema + - BUG/MAJOR: connection: update CO_FL_CONNECTED before calling the data layer + - MINOR: server: Add dynamic session cookies. + - MINOR: cli: Let configure the dynamic cookies from the cli. + - BUG/MINOR: checks: attempt clean shutw for SSL check + - CONTRIB: tcploop: make it build on FreeBSD + - CONTRIB: tcploop: fix time format to silence build warnings + - CONTRIB: tcploop: report action 'K' (kill) in usage message + - CONTRIB: tcploop: fix connect's address length + - CONTRIB: tcploop: use the trash instead of NULL for recv() + - BUG/MEDIUM: listener: do not try to rebind another process' socket + - BUG/MEDIUM server: Fix crash when dynamic is defined, but not key is provided. + - CLEANUP: config: Typo in comment. + - BUG/MEDIUM: filters: Fix channels synchronization in flt_end_analyze + - TESTS: add a test configuration to stress handshake combinations + - BUG/MAJOR: stream-int: do not depend on connection flags to detect connection + - BUG/MEDIUM: connection: ensure to always report the end of handshakes + - MEDIUM: connection: don't test for CO_FL_WAKE_DATA + - CLEANUP: connection: completely remove CO_FL_WAKE_DATA + - BUG: payload: fix payload not retrieving arbitrary lengths + - BUILD: ssl: simplify SSL_CTX_set_ecdh_auto compatibility + - BUILD: ssl: fix OPENSSL_NO_SSL_TRACE for boringssl and libressl + - BUG/MAJOR: http: fix typo in http_apply_redirect_rule + - MINOR: doc: 2.4. Examples should be 2.5. Examples + - BUG/MEDIUM: stream: fix client-fin/server-fin handling + - MINOR: fd: add a new flag HAP_POLL_F_RDHUP to struct poller + - BUG/MINOR: raw_sock: always perfom the last recv if RDHUP is not available + - OPTIM: poll: enable support for POLLRDHUP + - MINOR: kqueue: exclusively rely on the kqueue returned status + - MEDIUM: kqueue: take care of EV_EOF to improve polling status accuracy + - MEDIUM: kqueue: only set FD_POLL_IN when there are pending data + - DOC/MINOR: Fix typos in proxy protocol doc + - DOC: Protocol doc: add checksum, TLV type ranges + - DOC: Protocol doc: add SSL TLVs, rename CHECKSUM + - DOC: Protocol doc: add noop TLV + - MEDIUM: global: add a 'hard-stop-after' option to cap the soft-stop time + - MINOR: dns: improve DNS response parsing to use as many available records as possible + - BUG/MINOR: cfgparse: loop in tracked servers lists not detected by check_config_validity(). + - MINOR: server: irrelevant error message with 'default-server' config file keyword. + - MINOR: server: Make 'default-server' support 'backup' keyword. + - MINOR: server: Make 'default-server' support 'check-send-proxy' keyword. + - CLEANUP: server: code alignement. + - MINOR: server: Make 'default-server' support 'non-stick' keyword. + - MINOR: server: Make 'default-server' support 'send-proxy' and 'send-proxy-v2 keywords. + - MINOR: server: Make 'default-server' support 'check-ssl' keyword. + - MINOR: server: Make 'default-server' support 'force-sslv3' and 'force-tlsv1[0-2]' keywords. + - CLEANUP: server: code alignement. + - MINOR: server: Make 'default-server' support 'no-ssl*' and 'no-tlsv*' keywords. + - MINOR: server: Make 'default-server' support 'ssl' keyword. + - MINOR: server: Make 'default-server' support 'send-proxy-v2-ssl*' keywords. + - CLEANUP: server: code alignement. + - MINOR: server: Make 'default-server' support 'verify' keyword. + - MINOR: server: Make 'default-server' support 'verifyhost' setting. + - MINOR: server: Make 'default-server' support 'check' keyword. + - MINOR: server: Make 'default-server' support 'track' setting. + - MINOR: server: Make 'default-server' support 'ca-file', 'crl-file' and 'crt' settings. + - MINOR: server: Make 'default-server' support 'redir' keyword. + - MINOR: server: Make 'default-server' support 'observe' keyword. + - MINOR: server: Make 'default-server' support 'cookie' keyword. + - MINOR: server: Make 'default-server' support 'ciphers' keyword. + - MINOR: server: Make 'default-server' support 'tcp-ut' keyword. + - MINOR: server: Make 'default-server' support 'namespace' keyword. + - MINOR: server: Make 'default-server' support 'source' keyword. + - MINOR: server: Make 'default-server' support 'sni' keyword. + - MINOR: server: Make 'default-server' support 'addr' keyword. + - MINOR: server: Make 'default-server' support 'disabled' keyword. + - MINOR: server: Add 'no-agent-check' server keyword. + - DOC: server: Add docs for "server" and "default-server" new "no-*" and other settings. + - MINOR: doc: fix use-server example (imap vs mail) + - BUG/MEDIUM: tcp: don't require privileges to bind to device + - BUILD: make the release script use shortlog for the final changelog + - BUILD: scripts: fix typo in announce-release error message + - CLEANUP: time: curr_sec_ms doesn't need to be exported + - BUG/MEDIUM: server: Wrong server default CRT filenames initialization. + - BUG/MEDIUM: peers: fix buffer overflow control in intdecode. + - BUG/MEDIUM: buffers: Fix how input/output data are injected into buffers + - BUG/MINOR: http: Fix conditions to clean up a txn and to handle the next request + - CLEANUP: http: Remove channel_congested function + - CLEANUP: buffers: Remove buffer_bounce_realign function + - CLEANUP: buffers: Remove buffer_contig_area and buffer_work_area functions + - MINOR: http: remove useless check on HTTP_MSGF_XFER_LEN for the request + - MINOR: http: Add debug messages when HTTP body analyzers are called + - BUG/MEDIUM: http: Fix blocked HTTP/1.0 responses when compression is enabled + - BUG/MINOR: filters: Don't force the stream's wakeup when we wait in flt_end_analyze + - DOC: fix parenthesis and add missing "Example" tags + - DOC: update the contributing file + - DOC: log-format/tcplog/httplog update + - MINOR: config parsing: add warning when log-format/tcplog/httplog is overriden in "defaults" sections + +2016/11/25 : 1.8-dev0 + +2016/11/25 : 1.7.0 + - SCRIPTS: make publish-release also copy the new SPOE doc + - BUILD: http: include types/sample.h in proto_http.h + - BUILD: debug/flags: remove test for SF_COMP_READY + - CONTRIB: debug/flags: add check for SF_ERR_CHK_PORT + - MINOR: lua: add function which return true if the channel is full. + - MINOR: lua: add ip addresses and network manipulation function + - CONTRIB: tcploop: scriptable TCP I/O for debugging purposes + - CONTRIB: tcploop: implement fork() + - CONTRIB: tcploop: implement logging when called with -v + - CONTRIB: tcploop: update the usage output + - CONTRIB: tcploop: support sending plain strings + - CONTRIB: tcploop: don't report failed send() or recv() + - CONTRIB: tcploop: add basic loops via a jump instruction + - BUG/MEDIUM: channel: bad unlikely macro + - CLEANUP: lua: move comment + - CLEANUP: lua: control executed twice + - BUG/MEDIUM: ssl: Store certificate filename in a variable + - BUG/MINOR: ssl: Print correct filename when error occurs reading OCSP + - CLEANUP: ssl: Remove goto after return dead code + - CLEANUP: ssl: Fix bind keywords name in comments + - DOC: ssl: Use correct wording for ca-sign-pass + - CLEANUP: lua: avoid directly calling getsockname/getpeername() + - BUG/MINOR: stick-table: handle out-of-memory condition gracefully + - MINOR: cli: add private pointer and release function + - MEDIUM: lua: Add cli handler for Lua + - BUG/MEDIUM: connection: check the control layer before stopping polling + - DEBUG: connection: mark the closed FDs with a value that is easier to detect + - BUG/MEDIUM: stick-table: fix regression caused by recent fix for out-of-memory + - BUG/MINOR: cli: properly decrement ref count on tables during failed dumps + - BUG/MEDIUM: lua: In some case, the return of sample-fetche is ignored + - MINOR: filters: Add check_timeouts callback to handle timers expiration on streams + - MINOR: spoe: Add 'timeout processing' option to limit time to process an event + - MINOR: spoe: Remove useless 'timeout ack' option + - MINOR: spoe: Add 'option continue-on-error' statement in spoe-agent section + - MINOR: spoe: Add "maxconnrate" and "maxerrrate" statements + - MINOR: spoe: Add "option set-on-error" statement + - MINOR: stats: correct documentation of process ID for typed output + - BUILD: contrib: fix ip6range build on Centos 7 + - BUILD: fix build on Solaris 10/11 + - BUG/MINOR: cli: fix pointer size when reporting data/transport layer name + - BUG/MINOR: cli: dequeue from the proxy when changing a maxconn + - BUG/MINOR: cli: wake up the CLI's task after a timeout update + - MINOR: connection: add a few functions to report the data and xprt layers' names + - MINOR: connection: add names for transport and data layers + - REORG: cli: split dumpstats.c in src/cli.c and src/stats.c + - REORG: cli: split dumpstats.h in stats.h and cli.h + - REORG: cli: move ssl CLI functions to ssl_sock.c + - REORG: cli: move map and acl code to map.c + - REORG: cli: move show stat resolvers to dns.c + - MINOR: cli: create new function cli_has_level() to validate permissions + - MINOR: server: create new function cli_find_server() to find a server + - MINOR: proxy: create new function cli_find_frontend() to find a frontend + - REORG: cli: move 'set server' to server.c + - REORG: cli: move 'show pools' to memory.c + - REORG: cli: move 'show servers' to proxy.c + - REORG: cli: move 'show sess' to stream.c + - REORG: cli: move 'show backend' to proxy.c + - REORG: cli: move get/set weight to server.c + - REORG: cli: move "show stat" to stats.c + - REORG: cli: move "show info" to stats.c + - REORG: cli: move dump_text(), dump_text_line(), and dump_binary() to standard.c + - REORG: cli: move table dump/clear/set to stick_table.c + - REORG: cli: move "show errors" out of cli.c + - REORG: cli: make "show env" also use the generic keyword registration + - REORG: cli: move "set timeout" to its own handler + - REORG: cli: move "clear counters" to stats.c + - REORG: cli: move "set maxconn global" to its own handler + - REORG: cli: move "set maxconn server" to server.c + - REORG: cli: move "set maxconn frontend" to proxy.c + - REORG: cli: move "shutdown sessions server" to stream.c + - REORG: cli: move "shutdown session" to stream.c + - REORG: cli: move "shutdown frontend" to proxy.c + - REORG: cli: move "{enable|disable} frontend" to proxy.c + - REORG: cli: move "{enable|disable} server" to server.c + - REORG: cli: move "{enable|disable} health" to server.c + - REORG: cli: move "{enable|disable} agent" to server.c + - REORG: cli: move the "set rate-limit" functions to their own parser + - CLEANUP: cli: rename STAT_CLI_* to CLI_ST_* + - CLEANUP: cli: simplify the request parser a little bit + - CLEANUP: cli: remove assignments to st0 and st2 in keyword parsers + - BUILD: server: remove a build warning introduced by latest series + - BUG/MINOR: log-format: uncatched memory allocation functions + - CLEANUP: log-format: useless file and line in json converter + - CLEANUP/MINOR: log-format: unexport functions parse_logformat_var_args() and parse_logformat_var() + - CLEANUP: log-format: fix return code of the function parse_logformat_var() + - CLEANUP: log-format: fix return code of function parse_logformat_var_args() + - CLEANUP: log-format: remove unused arguments + - MEDIUM: log-format: strict parsing and enable fail + - MEDIUM: log-format/conf: take into account the parse_logformat_string() return code + - BUILD: ssl: make the SSL layer build again with openssl 0.9.8 + - BUILD: vars: remove a build warning on vars.c + - MINOR: lua: add utility function for check boolean argument + - MINOR: lua: Add tokenize function. + - BUG/MINOR: conf: calloc untested + - MINOR: http/conf: store the use_backend configuration file and line for logs + - MEDIUM: log-format: Use standard HAProxy log system to report errors + - CLEANUP: sample: report "converter" instead of "conv method" in error messages + - BUG: spoe: Fix parsing of SPOE actions in ACK frames + - MINOR: cli: make "show stat" support a proxy name + - MINOR: cli: make "show errors" support a proxy name + - MINOR: cli: make "show errors" capable of dumping only request or response + - BUG/MINOR: freq-ctr: make swrate_add() support larger values + - CLEANUP: counters: move from 3 types to 2 types + - CLEANUP: cfgparse: cascade the warnif_misplaced_* rules + - REORG: tcp-rules: move tcp rules processing to their own file + - REORG: stkctr: move all the stick counters processing to stick-tables.c + - DOC: update the roadmap file with the latest changes + +2016/11/09 : 1.7-dev6 + - DOC: fix the entry for hash-balance-factor config option + - DOC: Fix typo in description of `-st` parameter in man page + - CLEANUP: cfgparse: Very minor spelling correction + - MINOR: examples: Update haproxy.spec URLs to haproxy.org + - BUG/MEDIUM: peers: on shutdown, wake up the appctx, not the stream + - BUG/MEDIUM: peers: fix use after free in peer_session_create() + - MINOR: peers: make peer_session_forceshutdown() use the appctx and not the stream + - MINOR: peers: remove the pointer to the stream + - BUG/MEDIUM: systemd-wrapper: return correct exit codes + - DOC: stats: provide state details for show servers state + - MEDIUM: tools: make str2ip2() preserve existing ports + - CLEANUP: tools: make ipcpy() preserve the original port + - OPTIM: http: move all http character classs tables into a single one + - OPTIM: http: improve parsing performance of long header lines + - OPTIM: http: improve parsing performance of long URIs + - OPTIM: http: optimize lookup of comma and quote in header values + - BUG/MEDIUM: srv-state: properly restore the DRAIN state + - BUG/MINOR: srv-state: allow to have both CMAINT and FDRAIN flags + - MINOR: server: do not emit warnings/logs/alerts on server state changes at boot + - BUG/MEDIUM: servers: properly propagate the maintenance states during startup + - MEDIUM: wurfl: add Scientiamobile WURFL device detection module + - DOC: move the device detection modules documentation to their own files + - CLEANUP: wurfl: reduce exposure in the rest of the code + - MEDIUM: ssl: Add support for OpenSSL 1.1.0 + - MINOR: stream: make option contstats usable again + - MEDIUM: tools: make str2sa_range() return the FQDN even when not resolving + - MINOR: init: move apply_server_state in haproxy.c before MODE_CHECK + - MAJOR: server: postpone address resolution + - MINOR: new srv_admin flag: SRV_ADMF_RMAINT + - MINOR: server: indicate in the logs when RMAINT is cleared + - MINOR: stats: indicate it when a server is down due to resolution + - MINOR: server: make srv_set_admin_state() capable of telling why this happens + - MINOR: dns: implement extra 'hold' timers. + - MAJOR: dns: runtime resolution can change server admin state + - MEDIUM: cli: leave the RMAINT state when setting an IP address on the CLI + - MEDIUM: server: add a new init-addr server line setting + - MEDIUM: server: make use of init-addr + - MINOR: server: implement init-addr none + - MEDIUM: server: make libc resolution failure non-fatal + - MINOR: server: add support for explicit numeric address in init-addr + - DOC: add some documentation for the "init-addr" server keyword + - MINOR: init: add -dr to ignore server address resolution failures + - MEDIUM: server: do not restrict anymore usage of IP address from the state file + - BUG: vars: Fix 'set-var' converter because of a typo + - CLEANUP: remove last references to 'ruleset' section + - MEDIUM: filters: Add attch/detach and stream_set_backend callbacks + - MINOR: filters: Update filters documentation accordingly to recent changes + - MINOR: filters: Call stream_set_backend callbacks before updating backend stats + - MINOR: filters: Remove backend filters attached to a stream only for HTTP streams + - MINOR: flt_trace: Add hexdump option to dump forwarded data + - MINOR: cfgparse: Add functions to backup and restore registered sections + - MINOR: cfgparse: Parse scope lines and save the last one parsed + - REORG: sample: move code to release a sample expression in sample.c + - MINOR: vars: Allow '.' in variable names + - MINOR: vars: Add vars_set_by_name_ifexist function + - MEDIUM: vars: Add a per-process scope for variables + - MINOR: vars: Add 'unset-var' action/converter + - MAJOR: spoe: Add an experimental Stream Processing Offload Engine + - MINOR: spoe: add random ip-reputation service as SPOA example + - MINOR: spoe/checks: Add support for SPOP health checks + - DOC: update ROADMAP file + +2016/10/25 : 1.7-dev5 + - MINOR: cfgparse: few memory leaks fixes. + - MEDIUM: log: Decompose %Tq in %Th %Ti %TR + - CLEANUP: logs: remove unused log format field definitions + - BUILD/MAJOR:updated 51d Trie implementation to incorperate latest update to 51Degrees.c + - BUG/MAJOR: stream: properly mark the server address as unset on connect retry + - CLEANUP: proto_http: Removing useless variable assignation + - CLEANUP: dumpstats: Removing useless variables allocation + - CLEANUP: dns: Removing usless variable & assignation + - BUG/MINOR: payload: fix SSLv2 version parser + - MINOR: cli: allow the semi-colon to be escaped on the CLI + - MINOR: cli: change a server health check port through the stats socket + - BUG/MINOR: Fix OSX compilation errors + - MAJOR: check: find out which port to use for health check at run time + - MINOR: server: introduction of 3 new server flags + - MINOR: new update_server_addr_port() function to change both server's ADDR and service PORT + - MINOR: cli: ability to change a server's port + - CLEANUP/MINOR dns: comment do not follow up code update + - MINOR: chunk: new strncat function + - MINOR: dns: wrong DNS_MAX_UDP_MESSAGE value + - MINOR: dns: new MAX values + - MINOR: dns: new macro to compute DNS header size + - MINOR: dns: new DNS structures to store received packets + - MEDIUM: dns: new DNS response parser + - MINOR: dns: query type change when last record is a CNAME + - MINOR: dns: proper domain name validation when receiving DNS response + - MINOR: dns: comments in types/dns.h about structures endianness + - BUG/MINOR: displayed PCRE version is running release + - MINOR: show Built with PCRE version + - MINOR: show Running on zlib version + - MEDIUM: make SO_REUSEPORT configurable + - MINOR: enable IP_BIND_ADDRESS_NO_PORT on backend connections + - BUG/MEDIUM: http/compression: Fix how chunked data are copied during the HTTP body parsing + - BUG/MINOR: stats: report the correct conn_time in backend's html output + - BUG/MEDIUM: dns: don't randomly crash on out-of-memory + - MINOR: Add fe_req_rate sample fetch + - MEDIUM: peers: Fix a peer stick-tables synchronization issue. + - MEDIUM: cli: register CLI keywords with cli_register_kw() + - BUILD: Make use of accept4() on OpenBSD. + - MINOR: tcp: make set-src/set-src-port and set-dst/set-dst-port commutative + - DOC: fix missed entry for "set-{src,dst}{,-port}" + - BUG/MINOR: vars: use sess and not s->sess in action_store() + - BUG/MINOR: vars: make smp_fetch_var() more robust against misuses + - BUG/MINOR: vars: smp_fetch_var() doesn't depend on HTTP but on the session + - MINOR: stats: output dcon + - CLEANUP: tcp rules: mention everywhere that tcp-conn rules are L4 + - MINOR: counters: add new fields for denied_sess + - MEDIUM: tcp: add registration and processing of TCP L5 rules + - MINOR: stats: emit dses + - DOC: document tcp-request session + - MINOR: ssl: add debug traces + - BUILD/CLEANUP: ssl: Check BIO_reset() return code + - BUG/MINOR: ssl: Check malloc return code + - BUG/MINOR: ssl: prevent multiple entries for the same certificate + - BUG/MINOR: systemd: make the wrapper return a non-null status code on error + - BUG/MINOR: systemd: always restore signals before execve() + - BUG/MINOR: systemd: check return value of calloc() + - MINOR: systemd: report it when execve() fails + - BUG/MEDIUM: systemd: let the wrapper know that haproxy has completed or failed + - MINOR: proxy: add 'served' field to proxy, equal to total of all servers' + - MINOR: backend: add hash-balance-factor option for hash-type consistent + - MINOR: server: compute a "cumulative weight" to allow chash balancing to hit its target + - MEDIUM: server: Implement bounded-load hash algorithm + - SCRIPTS: make git-show-backports also dump a "git show" command + - MINOR: build: Allow linking to device-atlas library file + - MINOR: stats: Escape equals sign on socket dump + +2016/08/14 : 1.7-dev4 + - MINOR: add list_append_word function + - MEDIUM: init: use list_append_word in haproxy.c + - MEDIUM: init: allow directory as argument of -f + - CLEANUP: config: detect double registration of a config section + - MINOR: log: add the %Td log-format specifier + - MEDIUM: filters: Move HTTP headers filtering in its own callback + - MINOR: filters: Simplify calls to analyzers using 2 new macros + - MEDIUM: filters: Add pre and post analyzer callbacks + - DOC: filters: Update the filters documentation accordingly to recent changes + - BUG/MEDIUM: init: don't use environment locale + - SCRIPTS: teach git-show-backports how to report upstream commits + - SCRIPTS: make git-show-backports capable of limiting its history + - BUG/MAJOR: fix listening IP address storage for frontends + - BUG/MINOR: fix listening IP address storage for frontends (cont) + - DOC: Fix typo so fetch is properly parsed by Cyril's converter + - BUG/MAJOR: http: fix breakage of "reqdeny" causing random crashes + - BUG/MEDIUM: stick-tables: fix breakage in table converters + - MINOR: stick-table: change all stick-table converters' inputs to SMP_T_ANY + - BUG/MEDIUM: dns: unbreak DNS resolver after header fix + - BUILD: fix build on Solaris 11 + - BUG/MEDIUM: config: fix multiple declaration of section parsers + - BUG/MEDIUM: stats: show servers state may show an servers from another backend + - BUG/MEDIUM: fix risk of segfault with "show tls-keys" + - MEDIUM: dumpstats: 'show tls-keys' is now able to show secrets + - DOC: update doc about tls-tickets-keys dump + - MEDIUM: tcp: add 'set-src' to 'tcp-request connection' + - MINOR: set the CO_FL_ADDR_FROM_SET flags with 'set-src' + - MEDIUM: tcp/http: add 'set-src-port' action + - MEDIUM: tcp/http: new set-dst/set-dst-port actions + - BUG/MEDIUM: sticktables: segfault in some configuration error cases + - BUILD/MEDIUM: rebuild everything when an include file is changed + - BUILD/MEDIUM: force a full rebuild if some build options change + - BUG/MEDIUM: lua: converters doesn't work + - BUG/MINOR: http: add-header: header name copied twice + - BUG/MEDIUM: http: add-header: buffer overwritten + - BUG/MINOR: ssl: fix potential memory leak in ssl_sock_load_dh_params() + - MINOR: stream: export the function 'smp_create_src_stkctr' + - BUG/MEDIUM: dumpstats: undefined behavior in stats_tlskeys_list() + - MEDIUM: dumpstats: make stats_tlskeys_list() yield-aware during tls-keys dump + - BUG/MINOR: http: url32+src should use the big endian version of url32 + - BUG/MINOR: http: url32+src should check cli_conn before using it + - DOC: http: add documentation for url32 and url32+src + - BUG/MINOR: fix http-response set-log-level parsing error + - MINOR: systemd: Use variable for config and pidfile paths + - MINOR: systemd: Perform sanity check on config before reload + - MEDIUM: ssl: support SNI filters with multicerts + - MINOR: ssl: crt-list parsing factor + - BUILD: ssl: fix typo causing a build failure in the multicert patch + - MINOR: listener: add the "accept-netscaler-cip" option to the "bind" keyword + - MINOR: tcp: add "tcp-request connection expect-netscaler-cip layer4" + - BUG/MINOR: init: always ensure that global.rlimit_nofile matches actual limits + - BUG/MINOR: init: ensure that FD limit is raised to the max allowed + - BUG/MEDIUM: external-checks: close all FDs right after the fork() + - BUG/MAJOR: external-checks: use asynchronous signal delivery + - BUG/MINOR: external-checks: do not unblock undesired signals + - CLEANUP: external-check: don't block/unblock SIGCHLD when manipulating the list + - BUG/MEDIUM: filters: Fix data filtering when data are modified + - BUG/MINOR: filters: Fix HTTP parsing when a filter loops on data forwarding + - BUG/MINOR: srv-state: fix incorrect output of state file + - BUG/MINOR: ssl: close ssl key file on error + - BUG/MINOR: http: fix misleading error message for response captures + - BUG/BUILD: don't automatically run "make" on "make install" + - DOC: add missing doc for http-request deny [deny_status ] + - CLEANUP: dumpstats: u64 field is an unsigned type. + - BUG/MEDIUM: http: unbreak uri/header/url_param hashing + - BUG/MINOR: Rework slightly commit 9962f8fc to clean code and avoid mistakes + - MINOR: new function my_realloc2 = realloc + free upon failure + - CLEANUP: fixed some usages of realloc leading to memory leak + - Revert "BUG/MINOR: ssl: fix potential memory leak in ssl_sock_load_dh_params()" + - CLEANUP: connection: using internal struct to hold source and dest port. + - DOC: spelling fixes + - BUG/MINOR: ssl: fix potential memory leak in ssl_sock_load_dh_params() + - BUG/MEDIUM: dns: fix alignment issues in the DNS response parser + - BUG/MINOR: Fix endiness issue in DNS header creation code + - BUG/MEDIUM: lua: the function txn_done() from sample fetches can crash + - BUG/MEDIUM: lua: the function txn_done() from action wrapper can crash + - MEDIUM: http: implement http-response track-sc* directive + - BUG/MINOR: peers: Fix peers data decoding issue + - BUG/MINOR: peers: don't count track-sc multiple times on errors + - MINOR: standard: add function "escape_string" + - BUG/MEDIUM: log: use function "escape_string" instead of "escape_chunk" + - MINOR: tcp: Return TCP statistics like RTT and RTT variance + - DOC: lua: remove old functions + - BUG/MEDIUM: lua: somme HTTP manipulation functions are called without valid requests + - DOC: fix json converter example and error message + - BUG/MEDIUM: stream-int: completely detach connection on connect error + - DOC: minor typo fixes to improve HTML parsing by haproxy-dconv + - BUILD: make proto_tcp.c compatible with musl library + - BUG/MAJOR: compression: initialize avail_in/next_in even during flush + - BUG/MEDIUM: samples: make smp_dup() always duplicate the sample + - MINOR: sample: implement smp_is_safe() and smp_make_safe() + - MINOR: sample: provide smp_is_rw() and smp_make_rw() + - BUG/MAJOR: server: the "sni" directive could randomly cause trouble + - BUG/MEDIUM: stick-tables: do not fail on string keys with no allocated size + - BUG/MEDIUM: stick-table: properly convert binary samples to keys + - MINOR: sample: use smp_make_rw() in upper/lower converters + - MINOR: tcp: add dst_is_local and src_is_local + - BUG/MINOR: peers: some updates are pushed twice after a resync. + - BUILD: protocol: fix some build errors on OpenBSD + - BUILD: log: iovec requires to include sys/uio.h on OpenBSD + - BUILD: tcp: do not include netinet/ip.h for IP_TTL + - BUILD: connection: fix build breakage on openbsd due to missing in_systm.h + - BUILD: checks: remove the last strcat and eliminate a warning on OpenBSD + - BUILD: tcp: define SOL_TCP when only IPPROTO_TCP exists + - BUILD: compression: remove a warning when no compression lib is used + - BUILD: poll: remove unused hap_fd_isset() which causes a warning with clang + - MINOR: tcp: add further tcp info fetchers + - BUG/MINOR: peers: empty chunks after a resync. + - BUG/MAJOR: stick-counters: possible crash when using sc_trackers with wrong table + - MINOR: standard.c: ipcmp() function to compare 2 IP addresses stored in 2 struct sockaddr_storage + - MINOR: standard.c: ipcpy() function to copy an IP address from a struct sockaddr_storage into an other one + - MAJOR: listen section: don't use first bind port anymore when no server ports are provided + +2016/05/10 : 1.7-dev3 + - MINOR: sample: Moves ARGS underlying type from 32 to 64 bits. + - BUG/MINOR: log: Don't use strftime() which can clobber timezone if chrooted + - BUILD: namespaces: fix a potential build warning in namespaces.c + - MINOR: da: Using ARG12 macro for the sample fetch and the convertor. + - DOC: add encoding to json converter example + - BUG/MINOR: conf: "listener id" expects integer, but its not checked + - DOC: Clarify tunes.vars.xxx-max-size settings + - CLEANUP: chunk: adding NULL check to chunk_dup allocation. + - CLEANUP: connection: fix double negation on memcmp() + - BUG/MEDIUM: peers: fix incorrect age in frequency counters + - BUG/MEDIUM: Fix RFC5077 resumption when more than TLS_TICKETS_NO are present + - BUG/MAJOR: Fix crash in http_get_fhdr with exactly MAX_HDR_HISTORY headers + - BUG/MINOR: lua: can't load external libraries + - BUG/MINOR: prevent the dump of uninitialized vars + - CLEANUP: map: it seems that the map were planed to be chained + - MINOR: lua: move class registration facilities + - MINOR: lua: remove some useless checks + - CLEANUP: lua: Remove two same functions + - MINOR: lua: refactor the Lua object registration + - MINOR: lua: precise message when a critical error is catched + - MINOR: lua: post initialization + - MINOR: lua: Add internal function which strip spaces + - MINOR: lua: convert field to lua type + - DOC: "addr" parameter applies to both health and agent checks + - DOC: timeout client: pointers to timeout http-request + - DOC: typo on stick-store response + - DOC: stick-table: amend paragraph blaming the loss of table upon reload + - DOC: typo: ACL subdir match + - DOC: typo: maxconn paragraph is wrong due to a wrong buffer size + - DOC: regsub: parser limitation about the inability to use closing square brackets + - DOC: typo: req.uri is now replaced by capture.req.uri + - DOC: name set-gpt0 mismatch with the expected keyword + - MINOR: http: sample fetch which returns unique-id + - MINOR: dumpstats: extract stats fields enum and names + - MINOR: dumpstats: split stats_dump_info_to_buffer() in two parts + - MINOR: dumpstats: split stats_dump_fe_stats() in two parts + - MINOR: dumpstats: split stats_dump_li_stats() in two parts + - MINOR: dumpstats: split stats_dump_sv_stats() in two parts + - MINOR: dumpstats: split stats_dump_be_stats() in two parts + - MINOR: lua: dump general info + - MINOR: lua: add class proxy + - MINOR: lua: add class server + - MINOR: lua: add class listener + - BUG/MEDIUM: stick-tables: some sample-fetch doesn't work in the connection state. + - MEDIUM: proxy: use dynamic allocation for error dumps + - CLEANUP: remove unneeded casts + - CLEANUP: uniformize last argument of malloc/calloc + - DOC: fix "needed" typo + - BUG/MINOR: dumpstats: fix write to global chunk + - BUG/MINOR: dns: inapropriate way out after a resolution timeout + - BUG/MINOR: dns: trigger a DNS query type change on resolution timeout + - CLEANUP: proto_http: few corrections for gcc warnings. + - BUG/MINOR: DNS: resolution structure change + - BUG/MINOR : allow to log cookie for tarpit and denied request + - BUG/MEDIUM: ssl: rewind the BIO when reading certificates + - OPTIM/MINOR: session: abort if possible before connecting to the backend + - DOC: http: rename the unique-id sample and add the documentation + - BUG/MEDIUM: trace.c: rdtsc() is defined in two files + - BUG/MEDIUM: channel: fix miscalculation of available buffer space (2nd try) + - BUG/MINOR: server: risk of over reading the pref_net array. + - BUG/MINOR: cfgparse: couple of small memory leaks. + - BUG/MEDIUM: sample: initialize the pointer before parse_binary call. + - DOC: fix discrepancy in the example for http-request redirect + - MINOR: acl: Add predefined METH_DELETE, METH_PUT + - CLEANUP: .gitignore cleanup + - DOC: Clarify IPv4 address / mask notation rules + - CLEANUP: fix inconsistency between fd->iocb, proto->accept and accept() + - BUG/MEDIUM: fix maxaccept computation on per-process listeners + - BUG/MINOR: listener: stop unbound listeners on startup + - BUG/MINOR: fix maxaccept computation according to the frontend process range + - TESTS: add blocksig.c to run tests with all signals blocked + - MEDIUM: unblock signals on startup. + - MINOR: filters: Print the list of existing filters during HA startup + - MINOR: filters: Typo in an error message + - MINOR: filters: Filters must define the callbacks struct during config parsing + - DOC: filters: Add filters documentation + - BUG/MEDIUM: channel: don't allow to overwrite the reserve until connected + - BUG/MEDIUM: channel: incorrect polling condition may delay event delivery + - BUG/MEDIUM: channel: fix miscalculation of available buffer space (3rd try) + - BUG/MEDIUM: log: fix risk of segfault when logging HTTP fields in TCP mode + - MINOR: Add ability for agent-check to set server maxconn + - CLEANUP: Use server_parse_maxconn_change_request for maxconn CLI updates + - MINOR: filters: add opaque data + - BUG/MEDIUM: lua: protects the upper boundary of the argument list for converters/fetches. + - MINOR: lua: migrate the argument mask to 64 bits type. + - BUG/MINOR: dumpstats: Fix the "Total bytes saved" counter in backends stats + - BUG/MINOR: log: fix a typo that would cause %HP to log + - BUG/MEDIUM: http: fix incorrect reporting of server errors + - MINOR: channel: add new function channel_congested() + - BUG/MEDIUM: http: fix risk of CPU spikes with pipelined requests from dead client + - BUG/MAJOR: channel: fix miscalculation of available buffer space (4th try) + - BUG/MEDIUM: stream: ensure the SI_FL_DONT_WAKE flag is properly cleared + - BUG/MEDIUM: channel: fix inconsistent handling of 4GB-1 transfers + - BUG/MEDIUM: stats: show servers state may show an empty or incomplete result + - BUG/MEDIUM: stats: show backend may show an empty or incomplete result + - MINOR: stats: fix typo in help messages + - MINOR: stats: show stat resolvers missing in the help message + - BUG/MINOR: dns: fix DNS header definition + - BUG/MEDIUM: dns: fix alignment issue when building DNS queries + - CLEANUP: don't ignore scripts in .gitignore + - BUILD: add a few release and backport scripts in scripts/ + +2016/03/14 : 1.7-dev2 + - DOC: lua: fix lua API + - DOC: mailers: typo in 'hostname' description + - DOC: compression: missing mention of libslz for compression algorithm + - BUILD/MINOR: regex: missing header + - BUG/MINOR: stream: bad return code + - DOC: lua: fix somme errors and add implicit types + - MINOR: lua: add set/get priv for applets + - BUG/MINOR: http: fix several off-by-one errors in the url_param parser + - BUG/MINOR: http: Be sure to process all the data received from a server + - MINOR: filters/http: Use a wrapper function instead of stream_int_retnclose + - BUG/MINOR: chunk: make chunk_dup() always check and set dst->size + - DOC: ssl: fixed some formatting errors in crt tag + - MINOR: chunks: ensure that chunk_strcpy() adds a trailing zero + - MINOR: chunks: add chunk_strcat() and chunk_newstr() + - MINOR: chunk: make chunk_initstr() take a const string + - MEDIUM: tools: add csv_enc_append() to preserve the original chunk + - MINOR: tools: make csv_enc_append() always start at the first byte of the chunk + - MINOR: lru: new function to delete least recently used keys + - DOC: add Ben Shillito as the maintainer of 51d + - BUG/MINOR: 51d: Ensures a unique domain for each configuration + - BUG/MINOR: 51d: Aligns Pattern cache implementation with HAProxy best practices. + - BUG/MINOR: 51d: Releases workset back to pool. + - BUG/MINOR: 51d: Aligned const pointers to changes in 51Degrees. + - CLEANUP: 51d: Aligned if statements with HAProxy best practices and removed casts from malloc. + - MINOR: rename master process name in -Ds (systemd mode) + - DOC: fix a few spelling mistakes + - DOC: fix "workaround" spelling + - BUG/MINOR: examples: Fixing haproxy.spec to remove references to .cfg files + - MINOR: fix the return type for dns_response_get_query_id() function + - MINOR: server state: missing LF (\n) on error message printed when parsing server state file + - BUG/MEDIUM: dns: no DNS resolution happens if no ports provided to the nameserver + - BUG/MAJOR: servers state: server port is erased when dns resolution is enabled on a server + - BUG/MEDIUM: servers state: server port is used uninitialized + - BUG/MEDIUM: config: Adding validation to stick-table expire value. + - BUG/MEDIUM: sample: http_date() doesn't provide the right day of the week + - BUG/MEDIUM: channel: fix miscalculation of available buffer space. + - MEDIUM: pools: add a new flag to avoid rounding pool size up + - BUG/MEDIUM: buffers: do not round up buffer size during allocation + - BUG/MINOR: stream: don't force retries if the server is DOWN + - BUG/MINOR: counters: make the sc-inc-gpc0 and sc-set-gpt0 touch the table + - MINOR: unix: don't mention free ports on EAGAIN + - BUG/CLEANUP: CLI: report the proper field states in "show sess" + - MINOR: stats: send content-length with the redirect to allow keep-alive + - BUG: stream_interface: Reuse connection even if the output channel is empty + - DOC: remove old tunnel mode assumptions + - BUG/MAJOR: http-reuse: fix risk of orphaned connections + - BUG/MEDIUM: http-reuse: do not share private connections across backends + - BUG/MINOR: ssl: Be sure to use unique serial for regenerated certificates + - BUG/MINOR: stats: fix missing comma in stats on agent drain + - MAJOR: filters: Add filters support + - MINOR: filters: Do not reset stream analyzers if the client is gone + - REORG: filters: Prepare creation of the HTTP compression filter + - MAJOR: filters/http: Rewrite the HTTP compression as a filter + - MEDIUM: filters: Use macros to call filters callbacks to speed-up processing + - MEDIUM: filters: remove http_start_chunk, http_last_chunk and http_chunk_end + - MEDIUM: filters: Replace filter_http_headers callback by an analyzer + - MEDIUM: filters/http: Move body parsing of HTTP messages in dedicated functions + - MINOR: filters: Add stream_filters structure to hide filters info + - MAJOR: filters: Require explicit registration to filter HTTP body and TCP data + - MINOR: filters: Remove unused or useless stuff and do small optimizations + - MEDIUM: filters: Optimize the HTTP compression for chunk encoded response + - MINOR: filters/http: Slightly update the parsing of chunks + - MINOR: filters/http: Forward remaining data when a channel has no "data" filters + - MINOR: filters: Add an filter example + - MINOR: filters: Extract proxy stuff from the struct filter + - MINOR: map: Add regex matching replacement + - BUG/MINOR: lua: unsafe initialization + - DOC: lua: fix somme errors + - MINOR: lua: file dedicated to unsafe functions + - MINOR: lua: add "now" time function + - MINOR: standard: add RFC HTTP date parser + - MINOR: lua: Add date functions + - MINOR: lua: move common function + - MINOR: lua: merge function + - MINOR: lua: Add concat class + - MINOR: standard: add function "escape_chunk" + - MEDIUM: log: add a new log format flag "E" + - DOC: add server name at rate-limit sessions example + - BUG/MEDIUM: ssl: fix off-by-one in ALPN list allocation + - BUG/MEDIUM: ssl: fix off-by-one in NPN list allocation + - DOC: LUA: fix some typos and syntax errors + - MINOR: cli: add a new "show env" command + - MEDIUM: config: allow to manipulate environment variables in the global section + - MEDIUM: cfgparse: reject incorrect 'timeout retry' keyword spelling in resolvers + - MINOR: mailers: increase default timeout to 10 seconds + - MINOR: mailers: use for all line endings + - BUG/MAJOR: lua: segfault using Concat object + - DOC: lua: copyrights + - MINOR: common: mask conversion + - MEDIUM: dns: extract options + - MEDIUM: dns: add a "resolve-net" option which allow to prefer an ip in a network + - MINOR: mailers: make it possible to configure the connection timeout + - BUG/MAJOR: lua: applets can't sleep. + - BUG/MINOR: server: some prototypes are renamed + - BUG/MINOR: lua: Useless copy + - BUG/MEDIUM: stats: stats bind-process doesn't propagate the process mask correctly + - BUG/MINOR: server: fix the format of the warning on address change + - CLEANUP: server: add "const" to some message strings + - MINOR: server: generalize the "updater" source + - BUG/MEDIUM: chunks: always reject negative-length chunks + - BUG/MINOR: systemd: ensure we don't miss signals + - BUG/MINOR: systemd: report the correct signal in debug message output + - BUG/MINOR: systemd: propagate the correct signal to haproxy + - MINOR: systemd: ensure a reload doesn't mask a stop + - BUG/MEDIUM: cfgparse: wrong argument offset after parsing server "sni" keyword + - CLEANUP: stats: Avoid computation with uninitialized bits. + - CLEANUP: pattern: Ignore unknown samples in pat_match_ip(). + - CLEANUP: map: Avoid memory leak in out-of-memory condition. + - BUG/MINOR: tcpcheck: fix incorrect list usage resulting in failure to load certain configs + - BUG/MAJOR: samples: check smp->strm before using it + - MINOR: sample: add a new helper to initialize the owner of a sample + - MINOR: sample: always set a new sample's owner before evaluating it + - BUG/MAJOR: vars: always retrieve the stream and session from the sample + - CLEANUP: payload: remove useless and confusing nullity checks for channel buffer + - BUG/MINOR: ssl: fix usage of the various sample fetch functions + - MINOR: stats: create fields types suitable for all CSV output data + - MINOR: stats: add all the "show info" fields in a table + - MEDIUM: stats: fill all the show info elements prior to displaying them + - MINOR: stats: add a function to emit fields into a chunk + - MINOR: stats: add stats_dump_info_fields() to dump one field per line + - MEDIUM: stats: make use of stats_dump_info_fields() for "show info" + - MINOR: stats: add a declaration of all stats fields + - MINOR: stats: don't hard-code the CSV fields list anymore + - MINOR: stats: create stats fields storage and CSV dump function + - MEDIUM: stats: convert stats_dump_fe_stats() to use stats_dump_fields_csv() + - MEDIUM: stats: make stats_dump_fe_stats() use stats fields for HTML dump + - MEDIUM: stats: convert stats_dump_li_stats() to use stats_dump_fields_csv() + - MEDIUM: stats: make stats_dump_li_stats() use stats fields for HTML dump + - MEDIUM: stats: convert stats_dump_be_stats() to use stats_dump_fields_csv() + - MEDIUM: stats: make stats_dump_be_stats() use stats fields for HTML dump + - MEDIUM: stats: convert stats_dump_sv_stats() to use stats_dump_fields_csv() + - MEDIUM: stats: make stats_dump_sv_stats() use the stats field for HTML + - MEDIUM: stats: move the server state coloring logic to the server dump function + - MINOR: stats: do not use srv->admin & STATS_ADMF_MAINT in HTML dumps + - MINOR: stats: do not check srv->state for SRV_ST_STOPPED in HTML dumps + - MINOR: stats: make CSV report server check status only when enabled + - MINOR: stats: only report backend's down time if it has servers + - MINOR: stats: prepend '*' in front of the check status when in progress + - MINOR: stats: make HTML stats dump rely on the table for the check status + - MINOR: stats: add agent_status, agent_code, agent_duration to output + - MINOR: stats: add check_desc and agent_desc to the output fields + - MINOR: stats: add check and agent's health values in the output + - MEDIUM: stats: make the HTML server state dump use the CSV states + - MEDIUM: stats: only report observe errors when observe is set + - MEDIUM: stats: expose the same flags for CLI and HTTP accesses + - MEDIUM: stats: report server's address in the CSV output + - MEDIUM: stats: report the cookie value in the server & backend CSV dumps + - MEDIUM: stats: compute the color code only in the HTML form + - MEDIUM: stats: report the listeners' address in the CSV output + - MEDIUM: stats: make it possible to report the WAITING state for listeners + - REORG: stats: dump the frontend's HTML stats via a generic function + - REORG: stats: dump the socket stats via the generic function + - REORG: stats: dump the server stats via the generic function + - REORG: stats: dump the backend stats via the generic function + - MEDIUM: stats: add a new "mode" column to report the proxy mode + - MINOR: stats: report the load balancing algorithm in CSV output + - MINOR: stats: add 3 fields to report the frontend-specific connection stats + - MINOR: stats: report number of intercepted requests for frontend and backends + - MINOR: stats: introduce stats_dump_one_line() to dump one stats line + - CLEANUP: stats: make stats_dump_fields_html() not rely on proxy anymore + - MINOR: stats: add ST_SHOWADMIN to pass the admin info in the regular flags + - MINOR: stats: make stats_dump_fields_html() not use &trash by default + - MINOR: stats: add functions to emit typed fields into a chunk + - MEDIUM: stats: support "show info typed" on the CLI + - MEDIUM: stats: implement a typed output format for stats + - DOC: document the "show info typed" and "show stat typed" output formats + - MINOR: cfgparse: warn when uid parameter is not a number + - MINOR: cfgparse: warn when gid parameter is not a number + - BUG/MINOR: standard: Avoid free of non-allocated pointer + - BUG/MINOR: pattern: Avoid memory leak on out-of-memory condition + - CLEANUP: http: fix a build warning introduced by a recent fix + - BUG/MINOR: log: GMT offset not updated when entering/leaving DST + +2015/12/20 : 1.7-dev1 + - DOC: specify that stats socket doc (section 9.2) is in management + - BUILD: install only relevant and existing documentation + - CLEANUP: don't ignore debian/ directory if present + - BUG/MINOR: dns: parsing error of some DNS response + - BUG/MEDIUM: namespaces: don't fail if no namespace is used + - BUG/MAJOR: ssl: free the generated SSL_CTX if the LRU cache is disabled + - MEDIUM: dns: Don't use the ANY query type + - BUILD: ssl: fix build error introduced in commit 7969a3 with OpenSSL < 1.0.0 + - DOC: fix a typo for a "deviceatlas" keyword + - FIX: small typo in an example using the "Referer" header + - MINOR: cli: ability to set per-server maxconn + - DEBUG/MINOR: memory: add a build option to disable memory pools sharing + - DEBUG/MEDIUM: memory: optionally protect free data in pools + - DEBUG/MEDIUM: memory: add optional control pool memory operations + - MEDIUM: memory: add accounting for failed allocations + - BUG/MEDIUM: config: count memory limits on 64 bits, not 32 + - BUG/MAJOR: dns: first DNS response packet not matching queried hostname may lead to a loop + - BUG/MINOR: dns: unable to parse CNAMEs response + - BUG/MINOR: examples/haproxy.init: missing brace in quiet_check() + - DOC: deviceatlas: more example use cases. + - MINOR: config: allow IPv6 bracketed literals + - BUG/BUILD: replace haproxy-systemd-wrapper with $(EXTRA) in install-bin. + - BUILD: add Haiku as supported target. + - BUG/MAJOR: http: don't requeue an idle connection that is already queued + - DOC: typo on capture.res.hdr and capture.req.hdr + - BUG/MINOR: dns: check for duplicate nameserver id in a resolvers section was missing + - CLEANUP: use direction names in place of numeric values + - BUG/MEDIUM: lua: sample fetches based on response doesn't work + - MINOR: check: add agent-send server parameter + - BUG/MINOR: http rule: http capture 'id' rule points to a non existing id + - BUG/MINOR: server: check return value of fgets() in apply_server_state() + - BUG/MINOR: acl: don't use record layer in req_ssl_ver + - BUILD: freebsd: double declaration + - BUG/MEDIUM: lua: clean output buffer + - BUILD: check for libressl to be able to build against it + - DOC: lua-api/index.rst small example fixes, spelling correction. + - DOC: lua: architecture and first steps + - DOC: relation between timeout http-request and option http-buffer-request + - BUILD: Make deviceatlas require PCRE + - BUG: http: do not abort keep-alive connections on server timeout + - BUG/MEDIUM: http: switch the request channel to no-delay once done. + - BUG/MINOR: lua: don't force-sslv3 LUA's SSL socket + - BUILD/MINOR: http: proto_http.h needs sample.h + - BUG/MEDIUM: http: don't enable auto-close on the response side + - BUG/MEDIUM: stream: fix half-closed timeout handling + - CLEANUP: compression: don't allocate DEFAULT_MAXZLIBMEM without USE_ZLIB + - BUG/MEDIUM: cli: changing compression rate-limiting must require admin level + - BUG/MEDIUM: sample: urlp can't match an empty value + - BUILD: dumpstats: silencing warning for printf format specifier / time_t + - CLEANUP: proxy: calloc call inverted arguments + - MINOR: da: silent logging by default and displaying DeviceAtlas support if built. + - BUG/MEDIUM: da: stop DeviceAtlas processing in the convertor if there is no input. + - DOC: Edited 51Degrees section of README/ + - BUG/MEDIUM: checks: email-alert not working when declared in defaults + - BUG/MINOR: checks: email-alert causes a segfault when an unknown mailers section is configured + - BUG/MINOR: checks: typo in an email-alert error message + - BUG/MINOR: tcpcheck: conf parsing error when no port configured on server and last rule is a CONNECT with no port + - BUG/MINOR: tcpcheck: conf parsing error when no port configured on server and first rule(s) is (are) COMMENT + - BUG/MEDIUM: http: fix http-reuse when frontend and backend differ + - DOC: prefer using http-request/response over reqXXX/rspXXX directives + - CLEANUP: haproxy: using _GNU_SOURCE instead of __USE_GNU macro. + - MINOR: ssl: Added cert_key_and_chain struct + - MEDIUM: ssl: Added support for creating SSL_CTX with multiple certs + - MINOR: ssl: Added multi cert support for crt-list config keyword + - MEDIUM: ssl: Added multi cert support for loading crt directories + - MEDIUM: ssl: Added support for Multi-Cert OCSP Stapling + - BUILD: ssl: set SSL_SOCK_NUM_KEYTYPES with openssl < 1.0.2 + - MINOR: config: make tune.recv_enough configurable + - BUG/MEDIUM: config: properly adjust maxconn with nbproc when memmax is forced + - DOC: ssl: Adding docs for Multi-Cert bundling + - BUG/MEDIUM: peers: table entries learned from a remote are pushed to others after a random delay. + - BUG/MEDIUM: peers: old stick table updates could be repushed. + - MINOR: lua: service/applet can have access to the HTTP headers when a POST is received + - REORG/MINOR: lua: convert boolean "int" to bitfield + - BUG/MEDIUM: lua: Lua applets must not fetch samples using http_txn + - BUG/MINOR: lua: Lua applets must not use http_txn + - BUG/MEDIUM: lua: Forbid HTTP applets from being called from tcp rulesets + - BUG/MAJOR: lua: Do not force the HTTP analysers in use-services + - CLEANUP: lua: bad error messages + - CONTRIB: initiate a debugging suite to make debugging easier + +2015/10/13 : 1.7-dev0 + - exact copy of 1.6.0 + +2015/10/13 : 1.6.0 + - BUG/MINOR: Handle interactive mode in cli handler + - DOC: global section missing parameters + - DOC: backend section missing parameters + - DOC: stats paramaters available in frontend + - MINOR: lru: do not allocate useless memory in lru64_lookup + - BUG/MINOR: http: Add OPTIONS in supported http methods (found by find_http_meth) + - BUG/MINOR: ssl: fix management of the cache where forged certificates are stored + - MINOR: ssl: Release Servers SSL context when HAProxy is shut down + - MINOR: ssl: Read the file used to generate certificates in any order + - MINOR: ssl: Add support for EC for the CA used to sign generated certificates + - MINOR: ssl: Add callbacks to set DH/ECDH params for generated certificates + - BUG/MEDIUM: logs: fix time zone offset format in RFC5424 + - BUILD: Fix the build on OSX (htonll/ntohll) + - BUILD: enable build on Linux/s390x + - BUG/MEDIUM: lua: direction test failed + - MINOR: lua: fix a spelling error in some error messages + - CLEANUP: cli: ensure we can never double-free error messages + - BUG/MEDIUM: lua: force server-close mode on Lua services + - MEDIUM: init: support more command line arguments after pid list + - MEDIUM: init: support a list of files on the command line + - MINOR: debug: enable memory poisonning to use byte 0 + - BUILD: ssl: fix build error introduced by recent commit + - BUG/MINOR: config: make the stats socket pass the correct proxy to the parsers + - MEDIUM: server: implement TCP_USER_TIMEOUT on the server + - DOC: mention the "namespace" options for bind and server lines + - DOC: add the "management" documentation + - DOC: move the stats socket documentation from config to management + - MINOR: examples: update haproxy.spec to mention new docs + - DOC: mention management.txt in README + - DOC: remove haproxy-{en,fr}.txt + - BUILD: properly report when USE_ZLIB and USE_SLZ are used together + - MINOR: init: report use of libslz instead of "no compression" + - CLEANUP: examples: remove some obsolete and confusing files + - CLEANUP: examples: remove obsolete configuration file samples + - CLEANUP: examples: fix the example file content-sw-sample.cfg + - CLEANUP: examples: update sample file option-http_proxy.cfg + - CLEANUP: examples: update sample file ssl.cfg + - CLEANUP: tests: move a test file from examples/ to tests/ + - CLEANUP: examples: shut up warnings in transparent proxy example + - CLEANUP: tests: removed completely obsolete test files + - DOC: update ROADMAP to remove what was done in 1.6 + - BUG/MEDIUM: pattern: fixup use_after_free in the pat_ref_delete_by_id + +2015/10/06 : 1.6-dev7 + - MINOR: cli: Dump all resolvers stats if no resolver section is given + - BUG: config: external-check command validation is checking for incorrect arguments. + - DOC: documentation format cleanups + - DOC: lua: few typos. + - BUG/MEDIUM: str2ip: make getaddrinfo() consider local address selection policy + - BUG/MEDIUM: logs: segfault writing to log from Lua + - DOC: fix lua use-service example + - MINOR: payload: add support for tls session ticket ext + - MINOR: lua: remove the run flag + - MEDIUM: lua: change the timeout execution + - MINOR: lua: rename the tune.lua.applet-timeout + - DOC: lua: update Lua doc + - DOC: lua: update doc according with the last Lua changes + - MINOR: http/tcp: fill the avalaible actions + - DOC: reorder misplaced res.ssl_hello_type in the doc + - BUG/MINOR: tcp: make silent-drop always force a TCP reset + - CLEANUP: tcp: silent-drop: only drain the connection when quick-ack is disabled + - BUILD: tcp: use IPPROTO_IP when SOL_IP is not available + - BUILD: server: fix build warnings introduced by load-server-state + - BUG/MEDIUM: server: fix misuse of format string in load-server-state's warnings + +2015/09/28 : 1.6-dev6 + - BUG/MAJOR: can't enable a server through the stat socket + - MINOR: server: Macro definition for server-state + - MINOR: cli: new stats socket command: show servers state + - DOC: stats socket command: show servers state + - MINOR: config: new global directive server-state-base + - DOC: global directive server-state-base + - MINOR: config: new global section directive: server-state-file + - DOC: new global directive: server-state-file + - MINOR: config: new backend directives: load-server-state-from-file and server-state-file-name + - DOC: load-server-state-from-file + - MINOR: init: server state loaded from file + - MINOR: server: startup slowstart task when using seamless reload of HAProxy + - MINOR: cli: new stats socket command: show backend + - DOC: servers state seamless reload example + - BUG: dns: can't connect UDP socket on FreeBSD + - MINOR: cfgparse: New function cfg_unregister_sections() + - MINOR: chunk: New function free_trash_buffers() + - BUG/MEDIUM: main: Freeing a bunch of static pointers + - MINOR: proto_http: Externalisation of previously internal functions + - MINOR: global: Few new struct fields for da module + - MAJOR: da: Update of the DeviceAtlas API module + - DOC: DeviceAtlas new keywords + - DOC: README: DeviceAtlas sample configuration updates + - MEDIUM: log: replace sendto() with sendmsg() in __send_log() + - MEDIUM: log: use a separate buffer for the header and for the message + - MEDIUM: logs: remove the hostname, tag and pid part from the logheader + - MEDIUM: logs: add support for RFC5424 header format per logger + - MEDIUM: logs: add a new RFC5424 log-format for the structured-data + - DOC: mention support for the RFC5424 syslog message format + - MEDIUM: logs: have global.log_send_hostname not contain the trailing space + - MEDIUM: logs: pass the trailing "\n" as an iovec + - BUG/MEDIUM: peers: some table updates are randomly not pushed. + - BUG/MEDIUM: peers: same table updates re-pushed after a re-connect + - BUG/MINOR: fct peer_prepare_ackmsg should not use trash. + - MINOR: http: made CHECK_HTTP_MESSAGE_FIRST accessible to other functions + - MINOR: global: Added new fields for 51Degrees device detection + - DOC: Added more explanation for 51Degrees V3.2 + - BUILD: Changed 51Degrees option to support V3.2 + - MAJOR: 51d: Upgraded to support 51Degrees V3.2 and new features + - MINOR: 51d: Improved string handling for LRU cache + - DOC: add references to rise/fall for the fastinter explanation + - MINOR: support cpu-map feature through the compile option USE_CPU_AFFINITY on FreeBSD + - BUG/MAJOR: lua: potential unexpected aborts() + - BUG/MINOR: lua: breaks the log message if his size exceed one buffer + - MINOR: action: add private configuration + - MINOR: action: add reference to the original keywork matched for the called parser. + - MINOR: lua: change actions registration + - MEDIUM: proto_http: smp_prefetch_http initialize txn + - MINOR: channel: rename function chn_sess to chn_strm + - CLEANUP: lua: align defines + - MINOR: http: export http_get_path() function + - MINOR: http: export the get_reason() function + - MINOR: http: export function http_msg_analyzer() + - MINOR: http: split initialization + - MINOR: lua: reset pointer after use + - MINOR: lua: identify userdata objects + - MEDIUM: lua: use the function lua_rawset in place of lua_settable + - BUG/MAJOR: lua: segfault after the channel data is modified by some Lua action. + - CLEANUP: lua: use calloc in place of malloc + - BUG/MEDIUM: lua: longjmp function must be unregistered + - BUG/MEDIUM: lua: forces a garbage collection + - BUG/MEDIUM: lua: wakeup task on bad conditions + - MINOR: standard: avoid DNS resolution from the function str2sa_range() + - MINOR: lua: extend socket address to support non-IP families + - MINOR: lua/applet: the cosocket applet should use appctx_wakeup in place of task_wakeup + - BUG/MEDIUM: lua: socket destroy before reading pending data + - MEDIUM: lua: change the GC policy + - OPTIM/MEDIUM: lua: executes the garbage collector only when using cosocket + - BUG/MEDIUM: lua: don't reset undesired flags in hlua_ctx_resume + - MINOR: applet: add init function + - MINOR: applet: add an execution timeout + - MINOR: stream/applet: add use-service action + - MINOR: lua: add AppletTCP class and service + - MINOR: lua: add AppletHTTP class and service + - DOC: lua: some documentation update + - DOC: add the documentation about internal circular lists + - DOC: add a CONTRIBUTING file + - DOC: add a MAINTAINERS file + - BUG/MAJOR: peers: fix a crash when stopping peers on unbound processes + - DOC: update coding-style to reference checkpatch.pl + - BUG/MEDIUM: stick-tables: fix double-decrement of tracked entries + - BUG/MINOR: args: add name for ARGT_VAR + - DOC: add more entries to MAINTAINERS + - DOC: add more entries to MAINTAINERS + - CLEANUP: stream-int: remove obsolete function si_applet_call() + - BUG/MAJOR: cli: do not dereference strm_li()->proto->name + - BUG/MEDIUM: http: do not dereference strm_li(stream) + - BUG/MEDIUM: proxy: do not dereference strm_li(stream) + - BUG/MEDIUM: stream: do not dereference strm_li(stream) + - MINOR: stream-int: use si_release_endpoint() to close idle conns + - BUG/MEDIUM: payload: make req.payload and payload_lv aware of dynamic buffers + - BUG/MEDIUM: acl: always accept match "found" + - MINOR: applet: rename applet_runq to applet_active_queue + - BUG/MAJOR: applet: use a separate run queue to maintain list integrity + - MEDIUM: stream-int: split stream_int_update_conn() into si- and conn-specific parts + - MINOR: stream-int: implement a new stream_int_update() function + - MEDIUM: stream-int: factor out the stream update functions + - MEDIUM: stream-int: call stream_int_update() from si_update() + - MINOR: stream-int: export stream_int_update_* + - MINOR: stream-int: move the applet_pause call out of the stream updates + - MEDIUM: stream-int: clean up the conditions to enable reading in si_conn_wake_cb + - MINOR: stream-int: implement the stream_int_notify() function + - MEDIUM: stream-int: use the same stream notification function for applets and conns + - MEDIUM: stream-int: completely remove stream_int_update_embedded() + - MINOR: stream-int: rename si_applet_done() to si_applet_wake_cb() + - BUG/MEDIUM: applet: fix reporting of broken write situation + - BUG/MINOR: stats: do not call cli_release_handler 3 times + - BUG/MEDIUM: cli: properly handle closed output + - MINOR: cli: do not call the release handler on internal error. + - BUG/MEDIUM: stream-int: avoid double-call to applet->release + - DEBUG: add p_malloc() to return a poisonned memory area + - CLEANUP: lua: remove unneeded memset(0) after calloc() + - MINOR: lua: use the proper applet wakeup mechanism + - BUG/MEDIUM: lua: better fix for the protocol check + - BUG/MEDIUM: lua: properly set the target on the connection + - MEDIUM: actions: pass a new "flags" argument to custom actions + - MEDIUM: actions: add new flag ACT_FLAG_FINAL to notify about last call + - MEDIUM: http: pass ACT_FLAG_FINAL to custom actions + - MEDIUM: lua: only allow actions to yield if not in a final call + - DOC: clarify how to make use of abstract sockets in socat + - CLEANUP: config: make the errorloc/errorfile messages less confusing + - MEDIUM: action: add a new flag ACT_FLAG_FIRST + - BUG/MINOR: config: check that tune.bufsize is always positive + - MEDIUM: config: set tune.maxrewrite to 1024 by default + - DOC: add David Carlier as maintainer of da.c + - DOC: fix some broken unexpected unicode chars in the Lua doc. + - BUG/MEDIUM: proxy: ignore stopped peers + - BUG/MEDIUM: proxy: do not wake stopped proxies' tasks during soft_stop() + - MEDIUM: init: completely deallocate unused peers + - BUG/MEDIUM: tcp: fix inverted condition to call custom actions + - DOC: remove outdated actions lists on tcp-request/response + - MEDIUM: tcp: add new tcp action "silent-drop" + - DOC: add URLs to optional libraries in the README + +2015/09/14 : 1.6-dev5 + - MINOR: dns: dns_resolution structure update: time_t to unsigned int + - BUG/MEDIUM: dns: DNS resolution doesn't start + - BUG/MAJOR: dns: dns client resolution infinite loop + - MINOR: dns: coding style update + - MINOR: dns: new bitmasks to use against DNS flags + - MINOR: dns: dns_nameserver structure update: new counter for truncated response + - MINOR: dns: New DNS response analysis code: DNS_RESP_TRUNCATED + - MEDIUM: dns: handling of truncated response + - MINOR: DNS client query type failover management + - MINOR: dns: no expected DNS record type found + - MINOR: dns: new flag to report that no IP can be found in a DNS response packet + - BUG/MINOR: DNS request retry counter used for retry only + - DOC: DNS documentation updated + - MEDIUM: actions: remove ACTION_STOP + - BUG/MEDIUM: lua: outgoing connection was broken since 1.6-dev2 (bis) + - BUG/MINOR: lua: last log character truncated. + - CLEANUP: typo: bad indent + - CLEANUP: actions: missplaced includes + - MINOR: build: missing header + - CLEANUP: lua: Merge log functions + - BUG/MAJOR: http: don't manipulate the server connection if it's killed + - BUG/MINOR: http: remove stupid HTTP_METH_NONE entry + - BUG/MAJOR: http: don't call http_send_name_header() after an error + - MEDIUM: tools: make str2sa_range() optionally return the FQDN + - BUG/MINOR: tools: make str2sa_range() report unresolvable addresses + - BUG/MEDIUM: dns: use the correct server hostname when resolving + +2015/08/30 : 1.6-dev4 + - MINOR: log: Add log-format variable %HQ, to log HTTP query strings + - DOC: typo in 'redirect', 302 code meaning + - DOC: typos in tcp-check expect examples + - DOC: resolve-prefer default value and default-server update + - MINOR: DNS counters: increment valid counter + - BUG/MEDIUM: DNS resolution response parsing broken + - MINOR: server: add new SRV_ADMF_CMAINT flag + - MINOR: server SRV_ADMF_CMAINT flag doesn't imply SRV_ADMF_FMAINT + - BUG/MEDIUM: dns: wrong first time DNS resolution + - BUG/MEDIUM: lua: Lua tasks fail to start. + - BUILD: add USE_LUA to BUILD_OPTIONS when it's used + - DOC/MINOR: fix OpenBSD versions where haproxy works + - MINOR: 51d: unable to start haproxy without "51degrees-data-file" + - BUG/MEDIUM: peers: fix wrong message id on stick table updates acknowledgement. + - BUG/MAJOR: peers: fix current table pointer not re-initialized on session release. + - BUILD: ssl: Allow building against libssl without SSLv3. + - DOC: clarify some points about SSL and the proxy protocol + - DOC: mention support for RFC 5077 TLS Ticket extension in starter guide + - BUG/MEDIUM: mailer: DATA part must be terminated with . + - DOC: match several lua configuration option names to those implemented in code + - MINOR cfgparse: Correct the mailer warning text to show the right names to the user + - BUG/MINOR: ssl: TLS Ticket Key rotation broken via socket command + - MINOR: stream: initialize the current_rule field to NULL on stream init + - BUG/MEDIUM: lua: timeout error with converters, wrapper and actions. + - CLEANUP: proto_http: remove useless initialisation + - CLEANUP: http/tcp actions: remove the scope member + - BUG/MINOR: proto_tcp: custom action continue is ignored + - MINOR: proto_tcp: add session in the action prototype + - MINOR: vars: reduce the code size of some wrappers + - MINOR: Move http method enum from proto_http to sample + - MINOR: sample: Add ipv6 to ipv4 and sint to ipv6 casts + - MINOR: sample/proto_tcp: export "smp_fetch_src" + - MEDIUM: cli: rely on the map's output type instead of the sample type + - BUG/MEDIUM: stream: The stream doen't inherit SC from the session + - BUG/MEDIUM: vars: segfault during the configuration parsing + - BUG/MEDIUM: stick-tables: refcount error after copying SC for the session to the stream + - BUG/MEDIUM: lua: bad error processing + - MINOR: samples: rename a struct from sample_storage to sample_data + - MINOR: samples: rename some struct member from "smp" to "data" + - MEDIUM: samples: Use the "struct sample_data" in the "struct sample" + - MINOR: samples: extract the anonymous union and create the union sample_value + - MINOR: samples: rename union from "data" to "u" + - MEDIUM: 51degrees: Adapt the 51Degrees library + - MINOR: samples: data assignation simplification + - MEDIUM: pattern/map: Maps can returns various types + - MINOR: map: The map can return IPv4 and IPv6 + - MEDIUM: actions: Merge (http|tcp)-(request|reponse) action structs + - MINOR: actions: Remove the data opaque pointer + - MINOR: lua: use the hlua_rule type in place of opaque type + - MINOR: vars: use the vars types as argument in place of opaque type + - MINOR: proto_http: use an "expr" type in place of generic opaque type. + - MINOR: proto_http: replace generic opaque types by real used types for the actions on thr request line + - MINOR: proto_http: replace generic opaque types by real used types in "http_capture" + - MINOR: proto_http: replace generic opaque types by real used types in "http_capture" by id + - MEDIUM: track-sc: Move the track-sc configuration storage in the union + - MEDIUM: capture: Move the capture configuration storage in the union + - MINOR: actions: add "from" information + - MINOR: actions: remove the mark indicating the last entry in enum + - MINOR: actions: Declare all the embedded actions in the same header file + - MINOR: actions: change actions names + - MEDIUM: actions: Add standard return code for the action API + - MEDIUM: actions: Merge (http|tcp)-(request|reponse) keywords structs + - MINOR: proto_tcp: proto_tcp.h is now useles + - MINOR: actions: mutualise the action keyword lookup + - MEDIUM: actions: Normalize the return code of the configuration parsers + - MINOR: actions: Remove wrappers + - MAJOR: stick-tables: use sample types in place of dedicated types + - MEDIUM: stick-tables: use the sample type names + - MAJOR: stick-tables: remove key storage from the key struct + - MEDIUM: stick-tables: Add GPT0 in the stick tables + - MINOR: stick-tables: Add GPT0 access + - MINOR: stick-tables: Add GPC0 actions + - BUG/MEDIUM: lua: the lua fucntion Channel:close() causes a segfault + - DOC: ssl: missing LF + - MINOR: lua: add core.done() function + - DOC: fix function name + - BUG/MINOR: lua: in some case a sample may remain undefined + - DOC: fix "http_action_set_req_line()" comments + - MINOR: http: Action for manipulating the returned status code. + - MEDIUM: lua: turns txn:close into txn:done + - BUG/MEDIUM: lua: cannot process more Lua hooks after a "done()" function call + - BUILD: link with libdl if needed for Lua support + - CLEANUP: backend: factor out objt_server() in connect_server() + - MEDIUM: backend: don't call si_alloc_conn() when we reuse a valid connection + - MEDIUM: stream-int: simplify si_alloc_conn() + - MINOR: stream-int: add new function si_detach_endpoint() + - MINOR: server: add a list of private idle connections + - MINOR: connection: add a new list member in the connection struct + - MEDIUM: stream-int: queue idle connections at the server + - MINOR: stream-int: make si_idle_conn() only accept valid connections + - MINOR: server: add a list of already used idle connections + - MINOR: connection: add a new flag CO_FL_PRIVATE + - MINOR: config: add new setting "http-reuse" + - MAJOR: backend: initial work towards connection reuse + - MAJOR: backend: improve the connection reuse mechanism + - MEDIUM: backend: implement "http-reuse safe" + - MINOR: server: add a list of safe, already reused idle connections + - MEDIUM: backend: add the "http-reuse aggressive" strategy + - DOC: document the new http-reuse directive + - DOC: internals: document next steps for HTTP connection reuse + - DOC: mention that %ms is left-padded with zeroes. + - MINOR: init: indicate to check 'bind' lines when no listeners were found. + - MAJOR: http: remove references to appsession + - CLEANUP: config: remove appsession initialization + - CLEANUP: appsession: remove appsession.c and sessionhash.c + - CLEANUP: tests: remove sessionhash_test.c and test-cookie-appsess.cfg + - CLEANUP: proxy: remove last references to appsession + - CLEANUP: appsession: remove the last include files + - DOC: remove documentation about appsession + - CLEANUP: .gitignore: ignore more test files + - CLEANUP: .gitignore: finally ignore everything but what is known. + - MEDIUM: config: emit a warning on a frontend without listener + - DOC: add doc/internals/entities-v2.txt + - DOC: add doc/linux-syn-cookies.txt + - DOC: add design thoughts on HTTP/2 + - DOC: add some thoughts on connection sharing for HTTP/2 + - DOC: add design thoughts on dynamic buffer allocation + - BUG/MEDIUM: counters: ensure that src_{inc,clr}_gpc0 creates a missing entry + - DOC: add new file intro.txt + - MAJOR: tproxy: remove support for cttproxy + - BUG/MEDIUM: lua: outgoing connection was broken since 1.6-dev2 + - DOC: lua: replace txn:close with txn:done in lua-api + - DOC: intro: minor updates and fixes + - DOC: intro: fix too long line. + - DOC: fix example of http-request using ssl_fc_session_id + - BUG/MEDIUM: lua: txn:done() still causes a segfault in TCP mode + - CLEANUP: lua: fix some indent issues + - BUG/MEDIUM: lua: fix a segfault in txn:done() if called twice + - DOC: lua: mention than txn:close was renamed txn:done. + +2015/07/22 : 1.6-dev3 + - CLEANUP: sample: generalize sample_fetch_string() as sample_fetch_as_type() + - MEDIUM: http: Add new 'set-src' option to http-request + - DOC usesrc root privileges requirments + - BUG/MINOR: dns: wrong time unit for some DNS default parameters + - MINOR: proxy: bit field for proxy_find_best_match diff status + - MINOR: server: new server flag: SRV_F_FORCED_ID + - MINOR: server: server_find functions: id, name, best_match + - DOC: dns: fix chapters syntax + - BUILD/MINOR: tools: rename popcount to my_popcountl + - BUILD: add netbsd TARGET + - MEDIUM: 51Degrees code refactoring and cleanup + - MEDIUM: 51d: add LRU-based cache on User-Agent string detection + - DOC: add notes about the "51degrees-cache-size" parameter + - BUG/MEDIUM: 51d: possible incorrect operations on smp->data.str.str + - BUG/MAJOR: connection: fix TLV offset calculation for proxy protocol v2 parsing + - MINOR: Add sample fetch to detect Supported Elliptic Curves Extension + - BUG/MINOR: payload: Add volatile flag to smp_fetch_req_ssl_ec_ext + - BUG/MINOR: lua: type error in the arguments wrapper + - CLEANUP: vars: remove unused struct + - BUG/MINOR: http/sample: gmtime/localtime can fail + - MINOR: standard: add 64 bits conversion functions + - MAJOR: sample: converts uint and sint in 64 bits signed integer + - MAJOR: arg: converts uint and sint in sint + - MEDIUM: sample: switch to saturated arithmetic + - MINOR: vars: returns variable content + - MEDIUM: vars/sample: operators can use variables as parameter + - BUG/MINOR: ssl: fix smp_fetch_ssl_fc_session_id + - BUILD/MINOR: lua: fix a harmless build warning + - BUILD/MINOR: stats: fix build warning due to condition always true + - BUG/MAJOR: lru: fix unconditional call to free due to unexpected semi-colon + - BUG/MEDIUM: logs: fix improper systematic use of quotes with a few tags + - BUILD/MINOR: lua: ensure that hlua_ctx_destroy is properly defined + - BUG/MEDIUM: lru: fix possible memory leak when ->free() is used + - MINOR: vars: make the accounting not depend on the stream + - MEDIUM: vars: move the session variables to the session, not the stream + - BUG/MEDIUM: vars: do not freeze the connection when the expression cannot be fetched + - BUG/MAJOR: buffers: make the buffer_slow_realign() function respect output data + - BUG/MAJOR: tcp: tcp rulesets were still broken + - MINOR: stats: improve compression stats reporting + - MINOR: ssl: make self-generated certs also work with raw IPv6 addresses + - CLEANUP: ssl: make ssl_sock_generated_cert_serial() take a const + - CLEANUP: ssl: make ssl_sock_generate_certificate() use ssl_sock_generated_cert_serial() + - BUG/MINOR: log: missing some ARGC_* entries in fmt_directives() + - MINOR: args: add new context for servers + - MINOR: stream: maintain consistence between channel_forward and HTTP forward + - MINOR: ssl: provide ia function to set the SNI extension on a connection + - MEDIUM: ssl: add sni support on the server lines + - CLEANUP: stream: remove a useless call to si_detach() + - CLEANUP: stream-int: fix a few outdated comments about stream_int_register_handler() + - CLEANUP: stream-int: remove stream_int_unregister_handler() and si_detach() + - MINOR: stream-int: only use si_release_endpoint() to release a connection + - MINOR: standard: provide htonll() and ntohll() + - CLEANUP/MINOR: dns: dns_str_to_dn_label() only needs a const char + - BUG/MAJOR: dns: fix the length of the string to be copied + +2015/06/17 : 1.6-dev2 + - BUG/MINOR: ssl: Display correct filename in error message + - MEDIUM: logs: Add HTTP request-line log format directives + - BUG/MEDIUM: check: tcpcheck regression introduced by e16c1b3f + - BUG/MINOR: check: fix tcpcheck error message + - MINOR: use an int instead of calling tcpcheck_get_step_id + - MINOR: tcpcheck_rule structure update + - MINOR: include comment in tcpcheck error log + - DOC: tcpcheck comment documentation + - MEDIUM: server: add support for changing a server's address + - MEDIUM: server: change server ip address from stats socket + - MEDIUM: protocol: add minimalist UDP protocol client + - MEDIUM: dns: implement a DNS resolver + - MAJOR: server: add DNS-based server name resolution + - DOC: server name resolution + proto DNS + - MINOR: dns: add DNS statistics + - MEDIUM: http: configurable http result codes for http-request deny + - BUILD: Compile clean when debug options defined + - MINOR: lru: Add the possibility to free data when an item is removed + - MINOR: lru: Add lru64_lookup function + - MEDIUM: ssl: Add options to forge SSL certificates + - MINOR: ssl: Export functions to manipulate generated certificates + - MEDIUM: config: add DeviceAtlas global keywords + - MEDIUM: global: add the DeviceAtlas required elements to struct global + - MEDIUM: sample: add the da-csv converter + - MEDIUM: init: DeviceAtlas initialization + - BUILD: Makefile: add options to build with DeviceAtlas + - DOC: README: explain how to build with DeviceAtlas + - BUG/MEDIUM: http: fix the url_param fetch + - BUG/MEDIUM: init: segfault if global._51d_property_names is not initialized + - MAJOR: peers: peers protocol version 2.0 + - MINOR: peers: avoid re-scheduling of pending stick-table's updates still not pushed. + - MEDIUM: peers: re-schedule stick-table's entry for sync when data is modified. + - MEDIUM: peers: support of any stick-table data-types for sync + - BUG/MAJOR: sample: regression on sample cast to stick table types. + - CLEANUP: deinit: remove codes for cleaning p->block_rules + - DOC: Fix L4TOUT typo in documentation + - DOC: set-log-level in Logging section preamble + - BUG/MEDIUM: compat: fix segfault on FreeBSD + - MEDIUM: check: include server address and port in the send-state header + - MEDIUM: backend: Allow redispatch on retry intervals + - MINOR: Add TLS ticket keys reference and use it in the listener struct + - MEDIUM: Add support for updating TLS ticket keys via socket + - DOC: Document new socket commands "show tls-keys" and "set ssl tls-key" + - MINOR: Add sample fetch which identifies if the SSL session has been resumed + - DOC: Update doc about weight, act and bck fields in the statistics + - BUG/MEDIUM: ssl: fix tune.ssl.default-dh-param value being overwritten + - MINOR: ssl: add a destructor to free allocated SSL ressources + - MEDIUM: ssl: add the possibility to use a global DH parameters file + - MEDIUM: ssl: replace standards DH groups with custom ones + - MEDIUM: stats: Add enum srv_stats_state + - MEDIUM: stats: Separate server state and colour in stats + - MEDIUM: stats: Only report drain state in stats if server has SRV_ADMF_DRAIN set + - MEDIUM: stats: Differentiate between DRAIN and DRAIN (agent) + - MEDIUM: Lower priority of email alerts for log-health-checks messages + - MEDIUM: Send email alerts when servers are marked as UP or enter the drain state + - MEDIUM: Document when email-alerts are sent + - BUG/MEDIUM: lua: bad argument number in analyser and in error message + - MEDIUM: lua: automatically converts strings in proxy, tables, server and ip + - BUG/MINOR: utf8: remove compilator warning + - MEDIUM: map: uses HAProxy facilities to store default value + - BUG/MINOR: lua: error in detection of mandatory arguments + - BUG/MINOR: lua: set current proxy as default value if it is possible + - BUG/MEDIUM: http: the action set-{method|path|query|uri} doesn't run. + - BUG/MEDIUM: lua: undetected infinite loop + - BUG/MAJOR: http: don't read past buffer's end in http_replace_value + - BUG/MEDIUM: http: the function "(req|res)-replace-value" doesn't respect the HTTP syntax + - MEDIUM/CLEANUP: http: rewrite and lighten http_transform_header() prototype + - BUILD: lua: it miss the '-ldl' directive + - MEDIUM: http: allows 'R' and 'S' in the protocol alphabet + - MINOR: http: split the function http_action_set_req_line() in two parts + - MINOR: http: split http_transform_header() function in two parts. + - MINOR: http: export function inet_set_tos() + - MINOR: lua: txn: add function set_(loglevel|tos|mark) + - MINOR: lua: create and register HTTP class + - DOC: lua: fix some typos + - MINOR: lua: add log functions + - BUG/MINOR: lua: Fix SSL initialisation + - DOC: lua: some fixes + - MINOR: lua: (req|res)_get_headers return more than one header value + - MINOR: lua: map system integration in Lua + - BUG/MEDIUM: http: functions set-{path,query,method,uri} breaks the HTTP parser + - MINOR: sample: add url_dec converter + - MEDIUM: sample: fill the struct sample with the session, proxy and stream pointers + - MEDIUM: sample change the prototype of sample-fetches and converters functions + - MINOR: sample: fill the struct sample with the options. + - MEDIUM: sample: change the prototype of sample-fetches functions + - MINOR: http: split the url_param in two parts + - CLEANUP: http: bad indentation + - MINOR: http: add body_param fetch + - MEDIUM: http: url-encoded parsing function can run throught wrapped buffer + - DOC: http: req.body_param documentation + - MINOR: proxy: custom capture declaration + - MINOR: capture: add two "capture" converters + - MEDIUM: capture: Allow capture with slot identifier + - MINOR: http: add array of generic pointers in http_res_rules + - MEDIUM: capture: adds http-response capture + - MINOR: common: escape CSV strings + - MEDIUM: stats: escape some strings in the CSV dump + - MINOR: tcp: add custom actions that can continue tcp-(request|response) processing + - MINOR: lua: Lua tcp action are not final action + - DOC: lua: schematics about lua socket organization + - BUG/MINOR: debug: display (null) in place of "meth" + - DOC: mention the "lua action" in documentation + - MINOR: standard: add function that converts signed int to a string + - BUG/MINOR: sample: wrong conversion of signed values + - MEDIUM: sample: Add type any + - MINOR: debug: add a special converter which display its input sample content. + - MINOR: tcp: increase the opaque data array + - MINOR: tcp/http/conf: extends the keyword registration options + - MINOR: build: fix build dependency + - MEDIUM: vars: adds support of variables + - MINOR: vars: adds get and set functions + - MINOR: lua: Variable access + - MINOR: samples: add samples which returns constants + - BUG/MINOR: vars/compil: fix some warnings + - BUILD: add 51degrees options to makefile. + - MINOR: global: add several 51Degrees members to global + - MINOR: config: add 51Degrees config parsing. + - MINOR: init: add 51Degrees initialisation code + - MEDIUM: sample: add fiftyone_degrees converter. + - MEDIUM: deinit: add cleanup for 51Degrees to deinit + - MEDIUM: sample: add trie support to 51Degrees + - DOC: add 51Degrees notes to configuration.txt. + - DOC: add build indications for 51Degrees to README. + - MEDIUM: cfgparse: introduce weak and strong quoting + - BUG/MEDIUM: cfgparse: incorrect memmove in quotes management + - MINOR: cfgparse: remove line size limitation + - MEDIUM: cfgparse: expand environment variables + - BUG/MINOR: cfgparse: fix typo in 'option httplog' error message + - BUG/MEDIUM: cfgparse: segfault when userlist is misused + - CLEANUP: cfgparse: remove reference to 'ruleset' section + - MEDIUM: cfgparse: check section maximum number of arguments + - MEDIUM: cfgparse: max arguments check in the global section + - MEDIUM: cfgparse: check max arguments in the proxies sections + - CLEANUP: stream-int: remove a redundant clearing of the linger_risk flag + - MINOR: connection: make conn_sock_shutw() actually perform the shutdown() call + - MINOR: stream-int: use conn_sock_shutw() to shutdown a connection + - MINOR: connection: perform the call to xprt->shutw() in conn_data_shutw() + - MEDIUM: stream-int: replace xprt->shutw calls with conn_data_shutw() + - MINOR: checks: use conn_data_shutw_hard() instead of call via xprt + - MINOR: connection: implement conn_sock_send() + - MEDIUM: stream-int: make conn_si_send_proxy() use conn_sock_send() + - MEDIUM: connection: make conn_drain() perform more controls + - REORG: connection: move conn_drain() to connection.c and rename it + - CLEANUP: stream-int: remove inclusion of fd.h that is not used anymore + - MEDIUM: channel: don't always set CF_WAKE_WRITE on bi_put* + - CLEANUP: lua: don't use si_ic/si_oc on known stream-ints + - BUG/MEDIUM: peers: correctly configure the client timeout + - MINOR: peers: centralize configuration of the peers frontend + - MINOR: proxy: store the default target into the frontend's configuration + - MEDIUM: stats: use frontend_accept() as the accept function + - MEDIUM: peers: use frontend_accept() instead of peer_accept() + - CLEANUP: listeners: remove unused timeout + - MEDIUM: listener: store the default target per listener + - BUILD: fix automatic inclusion of libdl. + - MEDIUM: lua: implement a simple memory allocator + - MEDIUM: compression: postpone buffer adjustments after compression + - MEDIUM: compression: don't send leading zeroes with chunk size + - BUG/MINOR: compression: consider the expansion factor in init + - MINOR: http: check the algo name "identity" instead of the function pointer + - CLEANUP: compression: statify all algo-specific functions + - MEDIUM: compression: add a distinction between UA- and config- algorithms + - MEDIUM: compression: add new "raw-deflate" compression algorithm + - MEDIUM: compression: split deflate_flush() into flush and finish + - CLEANUP: compression: remove unused reset functions + - MAJOR: compression: integrate support for libslz + - BUG/MEDIUM: http: hdr_cnt would not count any header when called without name + - BUG/MAJOR: http: null-terminate the http actions keywords list + - CLEANUP: lua: remove the unused hlua_sleep memory pool + - BUG/MAJOR: lua: use correct object size when initializing a new converter + - CLEANUP: lua: remove hard-coded sizeof() in object creations and mallocs + - CLEANUP: lua: fix confusing local variable naming in hlua_txn_new() + - CLEANUP: hlua: stop using variable name "s" alternately for hlua_txn and hlua_smp + - CLEANUP: lua: get rid of the last "*ht" for struct hlua_txn. + - CLEANUP: lua: rename last occurrences of "*s" to "*htxn" for hlua_txn + - CLEANUP: lua: rename variable "sc" for struct hlua_smp + - CLEANUP: lua: get rid of the last two "*hs" for hlua_smp + - REORG/MAJOR: session: rename the "session" entity to "stream" + - REORG/MEDIUM: stream: rename stream flags from SN_* to SF_* + - MINOR: session: start to reintroduce struct session + - MEDIUM: stream: allocate the session when a stream is created + - MEDIUM: stream: move the listener's pointer to the session + - MEDIUM: stream: move the frontend's pointer to the session + - MINOR: session: add a pointer to the session's origin + - MEDIUM: session: use the pointer to the origin instead of s->si[0].end + - CLEANUP: sample: remove useless tests in fetch functions for l4 != NULL + - MEDIUM: http: move header captures from http_txn to struct stream + - MINOR: http: create a dedicated pool for http_txn + - MAJOR: http: move http_txn out of struct stream + - MAJOR: sample: don't pass l7 anymore to sample fetch functions + - CLEANUP: lua: remove unused hlua_smp->l7 and hlua_txn->l7 + - MEDIUM: http: remove the now useless http_txn from {req/res} rules + - CLEANUP: lua: don't pass http_txn anymore to hlua_request_act_wrapper() + - MAJOR: sample: pass a pointer to the session to each sample fetch function + - MINOR: stream: provide a few helpers to retrieve frontend, listener and origin + - CLEANUP: stream: don't set ->target to the incoming connection anymore + - MINOR: stream: move session initialization before the stream's + - MINOR: session: store the session's accept date + - MINOR: session: don't rely on s->logs.logwait in embryonic sessions + - MINOR: session: implement session_free() and use it everywhere + - MINOR: session: add stick counters to the struct session + - REORG: stktable: move the stkctr_* functions from stream to sticktable + - MEDIUM: streams: support looking up stkctr in the session + - MEDIUM: session: update the session's stick counters upon session_free() + - MEDIUM: proto_tcp: track the session's counters in the connection ruleset + - MAJOR: tcp: make tcp_exec_req_rules() only rely on the session + - MEDIUM: stream: don't call stream_store_counters() in kill_mini_session() nor session_accept() + - MEDIUM: stream: move all the session-specific stuff of stream_accept() earlier + - MAJOR: stream: don't initialize the stream anymore in stream_accept + - MEDIUM: session: remove the task pointer from the session + - REORG: session: move the session parts out of stream.c + - MINOR: stream-int: make appctx_new() take the applet in argument + - MEDIUM: peers: move the appctx initialization earlier + - MINOR: session: introduce session_new() + - MINOR: session: make use of session_new() when creating a new session + - MINOR: peers: make use of session_new() when creating a new session + - MEDIUM: peers: initialize the task before the stream + - MINOR: session: set the CO_FL_CONNECTED flag on the connection once ready + - CLEANUP: stream.c: do not re-attach the connection to the stream + - MEDIUM: stream: isolate connection-specific initialization code + - MEDIUM: stream: also accept appctx as origin in stream_accept_session() + - MEDIUM: peers: make use of stream_accept_session() + - MEDIUM: frontend: make ->accept only return +/-1 + - MEDIUM: stream: return the stream upon accept() + - MEDIUM: frontend: move some stream initialisation to stream_new() + - MEDIUM: frontend: move the fd-specific settings to session_accept_fd() + - MEDIUM: frontend: don't restrict frontend_accept() to connections anymore + - MEDIUM: frontend: move some remaining stream settings to stream_new() + - CLEANUP: frontend: remove one useless local variable + - MEDIUM: stream: don't rely on the session's listener anymore in stream_new() + - MEDIUM: lua: make use of stream_new() to create an outgoing connection + - MINOR: lua: minor cleanup in hlua_socket_new() + - MINOR: lua: no need for setting timeouts / conn_retries in hlua_socket_new() + - MINOR: peers: no need for setting timeouts / conn_retries in peer_session_create() + - CLEANUP: stream-int: swap stream-int and appctx declarations + - CLEANUP: namespaces: fix protection against multiple inclusions + - MINOR: session: maintain the session count stats in the session, not the stream + - MEDIUM: session: adjust the connection flags before stream_new() + - MINOR: stream: pass the pointer to the origin explicitly to stream_new() + - CLEANUP: poll: move the conditions for waiting out of the poll functions + - BUG/MEDIUM: listener: don't report an error when resuming unbound listeners + - BUG/MEDIUM: init: don't limit cpu-map to the first 32 processes only + - BUG/MAJOR: tcp/http: fix current_rule assignment when restarting over a ruleset + - BUG/MEDIUM: stream-int: always reset si->ops when si->end is nullified + - DOC: update the entities diagrams + - BUG/MEDIUM: http: properly retrieve the front connection + - MINOR: applet: add a new "owner" pointer in the appctx + - MEDIUM: applet: make the applet not depend on a stream interface anymore + - REORG: applet: move the applet definitions out of stream_interface + - CLEANUP: applet: rename struct si_applet to applet + - REORG: stream-int: create si_applet_ops dedicated to applets + - MEDIUM: applet: add basic support for an applet run queue + - MEDIUM: applet: implement a run queue for active appctx + - MEDIUM: stream-int: add a new function si_applet_done() + - MAJOR: applet: now call si_applet_done() instead of si_update() in I/O handlers + - MAJOR: stream: use a regular ->update for all stream interfaces + - MEDIUM: dumpstats: don't unregister the applet anymore + - MEDIUM: applet: centralize the call to si_applet_done() in the I/O handler + - MAJOR: stream: do not allocate request buffers anymore when the left side is an applet + - MINOR: stream-int: add two flags to indicate an applet's wishes regarding I/O + - MEDIUM: applet: make the applets only use si_applet_{cant|want|stop}_{get|put} + - MEDIUM: stream-int: pause the appctx if the task is woken up + - BUG/MAJOR: tcp: only call registered actions when they're registered + - BUG/MEDIUM: peers: fix applet scheduling + - BUG/MEDIUM: peers: recent applet changes broke peers updates scheduling + - MINOR: tools: provide an rdtsc() function for time comparisons + - IMPORT: lru: import simple ebtree-based LRU functions + - IMPORT: hash: import xxhash-r39 + - MEDIUM: pattern: add a revision to all pattern expressions + - MAJOR: pattern: add LRU-based cache on pattern matching + - BUG/MEDIUM: http: remove content-length from chunked messages + - DOC: http: update the comments about the rules for determining transfer-length + - BUG/MEDIUM: http: do not restrict parsing of transfer-encoding to HTTP/1.1 + - BUG/MEDIUM: http: incorrect transfer-coding in the request is a bad request + - BUG/MEDIUM: http: remove content-length form responses with bad transfer-encoding + - MEDIUM: http: restrict the HTTP version token to 1 digit as per RFC7230 + - MEDIUM: http: disable support for HTTP/0.9 by default + - MEDIUM: http: add option-ignore-probes to get rid of the floods of 408 + - BUG/MINOR: config: clear proxy->table.peers.p for disabled proxies + - MEDIUM: init: don't stop proxies in parent process when exiting + - MINOR: stick-table: don't attach to peers in stopped state + - MEDIUM: config: initialize stick-tables after peers, not before + - MEDIUM: peers: add the ability to disable a peers section + - MINOR: peers: store the pointer to the signal handler + - MEDIUM: peers: unregister peers that were never started + - MEDIUM: config: propagate the table's process list to the peers sections + - MEDIUM: init: stop any peers section not bound to the correct process + - MEDIUM: config: validate that peers sections are bound to exactly one process + - MAJOR: peers: allow peers section to be used with nbproc > 1 + - DOC: relax the peers restriction to single-process + - DOC: document option http-ignore-probes + - DOC: fix the comments about the meaning of msg->sol in HTTP + - BUG/MEDIUM: http: wait for the exact amount of body bytes in wait_for_request_body + - BUG/MAJOR: http: prevent risk of reading past end with balance url_param + - MEDIUM: stream: move HTTP request body analyser before process_common + - MEDIUM: http: add a new option http-buffer-request + - MEDIUM: http: provide 3 fetches for the body + - DOC: update the doc on the proxy protocol + - BUILD: pattern: fix build warnings introduced in the LRU cache + - BUG/MEDIUM: stats: properly initialize the scope before dumping stats + - CLEANUP: config: fix misleading information in error message. + - MINOR: config: report the number of processes using a peers section in the error case + - BUG/MEDIUM: config: properly compute the default number of processes for a proxy + - MEDIUM: http: add new "capture" action for http-request + - BUG/MEDIUM: http: fix the http-request capture parser + - BUG/MEDIUM: http: don't forward client shutdown without NOLINGER except for tunnels + - BUILD/MINOR: ssl: fix build failure introduced by recent patch + - BUG/MAJOR: check: fix breakage of inverted tcp-check rules + - CLEANUP: checks: fix double usage of cur / current_step in tcp-checks + - BUG/MEDIUM: checks: do not dereference head of a tcp-check at the end + - CLEANUP: checks: simplify the loop processing of tcp-checks + - BUG/MAJOR: checks: always check for end of list before proceeding + - BUG/MEDIUM: checks: do not dereference a list as a tcpcheck struct + - BUG/MAJOR: checks: break infinite loops when tcp-checks starts with comment + - MEDIUM: http: make url_param iterate over multiple occurrences + - BUG/MEDIUM: peers: apply a random reconnection timeout + - MEDIUM: config: reject invalid config with name duplicates + - MEDIUM: config: reject conflicts in table names + - CLEANUP: proxy: make the proxy lookup functions more user-friendly + - MINOR: proxy: simply ignore duplicates in proxy name lookups + - MINOR: config: don't open-code proxy name lookups + - MEDIUM: config: clarify the conflicting modes detection for backend rules + - CLEANUP: proxy: remove now unused function findproxy_mode() + - MEDIUM: stick-table: remove the now duplicate find_stktable() function + - MAJOR: config: remove the deprecated reqsetbe / reqisetbe actions + - MINOR: proxy: add a new function proxy_find_by_id() + - MINOR: proxy: add a flag to memorize that the proxy's ID was forced + - MEDIUM: proxy: add a new proxy_find_best_match() function + - CLEANUP: http: explicitly reference request in http_apply_redirect_rules() + - MINOR: http: prepare support for parsing redirect actions on responses + - MEDIUM: http: implement http-response redirect rules + - MEDIUM: http: no need to close the request on redirect if data was parsed + - BUG/MEDIUM: http: fix body processing for the stats applet + - BUG/MINOR: da: fix log-level comparison to emove annoying warning + - CLEANUP: global: remove one ifdef USE_DEVICEATLAS + - CLEANUP: da: move the converter registration to da.c + - CLEANUP: da: register the config keywords in da.c + - CLEANUP: adjust the envelope name in da.h to reflect the file name + - CLEANUP: da: remove ifdef USE_DEVICEATLAS from da.c + - BUILD: make 51D easier to build by defaulting to 51DEGREES_SRC + - BUILD: fix build warning when not using 51degrees + - BUILD: make DeviceAtlas easier to build by defaulting to DEVICEATLAS_SRC + - BUILD: ssl: fix recent build breakage on older SSL libs + +2015/03/11 : 1.6-dev1 + - CLEANUP: extract temporary $CFG to eliminate duplication + - CLEANUP: extract temporary $BIN to eliminate duplication + - CLEANUP: extract temporary $PIDFILE to eliminate duplication + - CLEANUP: extract temporary $LOCKFILE to eliminate duplication + - CLEANUP: extract quiet_check() to avoid duplication + - BUG/MINOR: don't start haproxy on reload + - DOC: Address issue where documentation is excluded due to a gitignore rule. + - BUG/MEDIUM: systemd: set KillMode to 'mixed' + - BUILD: fix "make install" to support spaces in the install dirs + - BUG/MINOR: config: http-request replace-header arg typo + - BUG: config: error in http-response replace-header number of arguments + - DOC: missing track-sc* in http-request rules + - BUILD: lua: missing ifdef related to SSL when enabling LUA + - BUG/MEDIUM: regex: fix pcre_study error handling + - MEDIUM: regex: Use pcre_study always when PCRE is used, regardless of JIT + - BUG/MINOR: Fix search for -p argument in systemd wrapper. + - MEDIUM: Improve signal handling in systemd wrapper. + - DOC: fix typo in Unix Socket commands + - BUG/MEDIUM: checks: external checks can't change server status to UP + - BUG/MEDIUM: checks: segfault with external checks in a backend section + - BUG/MINOR: checks: external checks shouldn't wait for timeout to return the result + - BUG/MEDIUM: auth: fix segfault with http-auth and a configuration with an unknown encryption algorithm + - BUG/MEDIUM: config: userlists should ensure that encrypted passwords are supported + - BUG/MINOR: config: don't propagate process binding for dynamic use_backend + - BUG/MINOR: log: fix request flags when keep-alive is enabled + - BUG/MEDIUM: checks: fix conflicts between agent checks and ssl healthchecks + - MINOR: checks: allow external checks in backend sections + - MEDIUM: checks: provide environment variables to the external checks + - MINOR: checks: update dynamic environment variables in external checks + - DOC: checks: environment variables used by "external-check command" + - BUG/MEDIUM: backend: correctly detect the domain when use_domain_only is used + - MINOR: ssl: load certificates in alphabetical order + - BUG/MINOR: checks: prevent http keep-alive with http-check expect + - MINOR: lua: typo in an error message + - MINOR: report the Lua version in -vv + - MINOR: lua: add a compilation error message when compiled with an incompatible version + - BUG/MEDIUM: lua: segfault when calling haproxy sample fetches from lua + - BUILD: try to automatically detect the Lua library name + - BUILD/CLEANUP: systemd: avoid a warning due to mixed code and declaration + - BUG/MEDIUM: backend: Update hash to use unsigned int throughout + - BUG/MEDIUM: connection: fix memory corruption when building a proxy v2 header + - MEDIUM: connection: add new bit in Proxy Protocol V2 + - BUG/MINOR: ssl: rejects OCSP response without nextupdate. + - BUG/MEDIUM: ssl: Fix to not serve expired OCSP responses. + - BUG/MINOR: ssl: Fix OCSP resp update fails with the same certificate configured twice. + - BUG/MINOR: ssl: Fix external function in order not to return a pointer on an internal trash buffer. + - MINOR: add fetchs 'ssl_c_der' and 'ssl_f_der' to return DER formatted certs + - MINOR: ssl: add statement to force some ssl options in global. + - BUG/MINOR: ssl: correctly initialize ssl ctx for invalid certificates + - BUG/MEDIUM: ssl: fix bad ssl context init can cause segfault in case of OOM. + - BUG/MINOR: samples: fix unnecessary memcopy converting binary to string. + - MINOR: samples: adds the bytes converter. + - MINOR: samples: adds the field converter. + - MINOR: samples: add the word converter. + - BUG/MINOR: server: move the directive #endif to the end of file + - BUG/MAJOR: buffer: check the space left is enough or not when input data in a buffer is wrapped + - DOC: fix a few typos + - CLEANUP: epoll: epoll_events should be allocated according to global.tune.maxpollevents + - BUG/MINOR: http: fix typo: "401 Unauthorized" => "407 Unauthorized" + - BUG/MINOR: parse: refer curproxy instead of proxy + - BUG/MINOR: parse: check the validity of size string in a more strict way + - BUILD: add new target 'make uninstall' to support uninstalling haproxy from OS + - DOC: expand the docs for the provided stats. + - BUG/MEDIUM: unix: do not unlink() abstract namespace sockets upon failure. + - MEDIUM: ssl: Certificate Transparency support + - MEDIUM: stats: proxied stats admin forms fix + - MEDIUM: http: Compress HTTP responses with status codes 201,202,203 in addition to 200 + - BUG/MEDIUM: connection: sanitize PPv2 header length before parsing address information + - MAJOR: namespace: add Linux network namespace support + - MINOR: systemd: Check configuration before start + - BUILD: ssl: handle boringssl in openssl version detection + - BUILD: ssl: disable OCSP when using boringssl + - BUILD: ssl: don't call get_rfc2409_prime when using boringssl + - MINOR: ssl: don't use boringssl's cipher_list + - BUILD: ssl: use OPENSSL_NO_OCSP to detect OCSP support + - MINOR: stats: fix minor typo in HTML page + - MINOR: Also accept SIGHUP/SIGTERM in systemd-wrapper + - MEDIUM: Add support for configurable TLS ticket keys + - DOC: Document the new tls-ticket-keys bind keyword + - DOC: clearly state that the "show sess" output format is not fixed + - MINOR: stats: fix minor typo fix in stats_dump_errors_to_buffer() + - DOC: httplog does not support 'no' + - BUG/MEDIUM: ssl: Fix a memory leak in DHE key exchange + - MINOR: ssl: use SSL_get_ciphers() instead of directly accessing the cipher list. + - BUG/MEDIUM: Consistently use 'check' in process_chk + - MEDIUM: Add external check + - BUG/MEDIUM: Do not set agent health to zero if server is disabled in config + - MEDIUM/BUG: Only explicitly report "DOWN (agent)" if the agent health is zero + - MEDIUM: Remove connect_chk + - MEDIUM: Refactor init_check and move to checks.c + - MEDIUM: Add free_check() helper + - MEDIUM: Move proto and addr fields struct check + - MEDIUM: Attach tcpcheck_rules to check + - MEDIUM: Add parsing of mailers section + - MEDIUM: Allow configuration of email alerts + - MEDIUM: Support sending email alerts + - DOC: Document email alerts + - MINOR: Remove trailing '.' from email alert messages + - MEDIUM: Allow suppression of email alerts by log level + - BUG/MEDIUM: Do not consider an agent check as failed on L7 error + - MINOR: deinit: fix memory leak + - MINOR: http: export the function 'smp_fetch_base32' + - BUG/MEDIUM: http: tarpit timeout is reset + - MINOR: sample: add "json" converter + - BUG/MEDIUM: pattern: don't load more than once a pattern list. + - MINOR: map/acl/dumpstats: remove the "Done." message + - BUG/MAJOR: ns: HAProxy segfault if the cli_conn is not from a network connection + - BUG/MINOR: pattern: error message missing + - BUG/MEDIUM: pattern: some entries are not deleted with case insensitive match + - BUG/MINOR: ARG6 and ARG7 don't fit in a 32 bits word + - MAJOR: poll: only rely on wake_expired_tasks() to compute the wait delay + - MEDIUM: task: call session analyzers if the task is woken by a message. + - MEDIUM: protocol: automatically pick the proto associated to the connection. + - MEDIUM: channel: wake up any request analyzer on response activity + - MINOR: converters: add a "void *private" argument to converters + - MINOR: converters: give the session pointer as converter argument + - MINOR: sample: add private argument to the struct sample_fetch + - MINOR: global: export function and permits to not resolve DNS names + - MINOR: sample: add function for browsing samples. + - MINOR: global: export many symbols. + - MINOR: includes: fix a lot of missing or useless includes + - MEDIUM: tcp: add register keyword system. + - MEDIUM: buffer: make bo_putblk/bo_putstr/bo_putchk return the number of bytes copied. + - MEDIUM: http: change the code returned by the response processing rule functions + - MEDIUM: http/tcp: permit to resume http and tcp custom actions + - MINOR: channel: functions to get data from a buffer without copy + - MEDIUM: lua: lua integration in the build and init system. + - MINOR: lua: add ease functions + - MINOR: lua: add runtime execution context + - MEDIUM: lua: "com" signals + - MINOR: lua: add the configuration directive "lua-load" + - MINOR: lua: core: create "core" class and object + - MINOR: lua: post initialisation bindings + - MEDIUM: lua: add coroutine as tasks. + - MINOR: lua: add sample and args type converters + - MINOR: lua: txn: create class TXN associated with the transaction. + - MINOR: lua: add shared context in the lua stack + - MINOR: lua: txn: import existing sample-fetches in the class TXN + - MINOR: lua: txn: add lua function in TXN that returns an array of http headers + - MINOR: lua: register and execute sample-fetches in LUA + - MINOR: lua: register and execute converters in LUA + - MINOR: lua: add bindings for tcp and http actions + - MINOR: lua: core: add sleep functions + - MEDIUM: lua: socket: add "socket" class for TCP I/O + - MINOR: lua: core: pattern and acl manipulation + - MINOR: lua: channel: add "channel" class + - MINOR: lua: txn: object "txn" provides two objects "channel" + - MINOR: lua: core: can set the nice of the current task + - MINOR: lua: core: can yield an execution stack + - MINOR: lua: txn: add binding for closing the client connection. + - MEDIUM: lua: Lua initialisation "on demand" + - BUG/MAJOR: lua: send function fails and return bad bytes + - MINOR: remove unused declaration. + - MINOR: lua: remove some #define + - MINOR: lua: use bitfield and macro in place of integer and enum + - MINOR: lua: set skeleton for Lua execution expiration + - MEDIUM: lua: each yielding function returns a wake up time. + - MINOR: lua: adds "forced yield" flag + - MEDIUM: lua: interrupt the Lua execution for running other process + - MEDIUM: lua: change the sleep function core + - BUG/MEDIUM: lua: the execution timeout is ignored in yield case + - DOC: lua: Lua configuration documentation + - MINOR: lua: add the struct session in the lua channel struct + - BUG/MINOR: lua: set buffer if it is nnot avalaible. + - BUG/MEDIUM: lua: reset flags before resuming execution + - BUG/MEDIUM: lua: fix infinite loop about channel + - BUG/MEDIUM: lua: the Lua process is not waked up after sending data on requests side + - BUG/MEDIUM: lua: many errors when we try to send data with the channel API + - MEDIUM: lua: use the Lua-5.3 version of the library + - BUG/MAJOR: lua: some function are not yieldable, the forced yield causes errors + - BUG/MEDIUM: lua: can't handle the response bytes + - BUG/MEDIUM: lua: segfault with buffer_replace2 + - BUG/MINOR: lua: check buffers before initializing socket + - BUG/MINOR: log: segfault if there are no proxy reference + - BUG/MEDIUM: lua: sockets don't have buffer to write data + - BUG/MEDIUM: lua: cannot connect socket + - BUG/MINOR: lua: sockets receive behavior doesn't follows the specs + - BUG/BUILD: lua: The strict Lua 5.3 version check is not done. + - BUG/MEDIUM: buffer: one byte miss in buffer free space check + - MEDIUM: lua: make the functions hlua_gethlua() and hlua_sethlua() faster + - MINOR: replace the Core object by a simple model. + - MEDIUM: lua: change the objects configuration + - MEDIUM: lua: create a namespace for the fetches + - MINOR: converters: add function to browse converters + - MINOR: lua: wrapper for converters + - MINOR: lua: replace function (req|get)_channel by a variable + - MINOR: lua: fetches and converters can return an empty string in place of nil + - DOC: lua api + - BUG/MEDIUM: sample: fix random number upper-bound + - BUG/MINOR: stats:Fix incorrect printf type. + - BUG/MAJOR: session: revert all the crappy client-side timeout changes + - BUG/MINOR: logs: properly initialize and count log sockets + - BUG/MEDIUM: http: fetch "base" is not compatible with set-header + - BUG/MINOR: counters: do not untrack counters before logging + - BUG/MAJOR: sample: correctly reinitialize sample fetch context before calling sample_process() + - MINOR: stick-table: make stktable_fetch_key() indicate why it failed + - BUG/MEDIUM: counters: fix track-sc* to wait on unstable contents + - BUILD: remove TODO from the spec file and add README + - MINOR: log: make MAX_SYSLOG_LEN overridable at build time + - MEDIUM: log: support a user-configurable max log line length + - DOC: provide an example of how to use ssl_c_sha1 + - BUILD: checks: external checker needs signal.h + - BUILD: checks: kill a minor warning on Solaris in external checks + - BUILD: http: fix isdigit & isspace warnings on Solaris + - BUG/MINOR: listener: set the listener's fd to -1 after deletion + - BUG/MEDIUM: unix: failed abstract socket binding is retryable + - MEDIUM: listener: implement a per-protocol pause() function + - MEDIUM: listener: support rebinding during resume() + - BUG/MEDIUM: unix: completely unbind abstract sockets during a pause() + - DOC: explicitly mention the limits of abstract namespace sockets + - DOC: minor fix on {sc,src}_kbytes_{in,out} + - DOC: fix alphabetical sort of converters + - MEDIUM: stick-table: implement lookup from a sample fetch + - MEDIUM: stick-table: add new converters to fetch table data + - MINOR: samples: add two converters for the date format + - BUG/MAJOR: http: correctly rewind the request body after start of forwarding + - DOC: remove references to CPU=native in the README + - DOC: mention that "compression offload" is ignored in defaults section + - DOC: mention that Squid correctly responds 400 to PPv2 header + - BUILD: fix dependencies between config and compat.h + - MINOR: session: export the function 'smp_fetch_sc_stkctr' + - MEDIUM: stick-table: make it easier to register extra data types + - BUG/MINOR: http: base32+src should use the big endian version of base32 + - MINOR: sample: allow IP address to cast to binary + - MINOR: sample: add new converters to hash input + - MINOR: sample: allow integers to cast to binary + - BUILD: report commit ID in git versions as well + - CLEANUP: session: move the stick counters declarations to stick_table.h + - MEDIUM: http: add the track-sc* actions to http-request rules + - BUG/MEDIUM: connection: fix proxy v2 header again! + - BUG/MAJOR: tcp: fix a possible busy spinning loop in content track-sc* + - OPTIM/MINOR: proxy: reduce struct proxy by 48 bytes on 64-bit archs + - MINOR: log: add a new field "%lc" to implement a per-frontend log counter + - BUG/MEDIUM: http: fix inverted condition in pat_match_meth() + - BUG/MEDIUM: http: fix improper parsing of HTTP methods for use with ACLs + - BUG/MINOR: pattern: remove useless allocation of unused trash in pat_parse_reg() + - BUG/MEDIUM: acl: correctly compute the output type when a converter is used + - CLEANUP: acl: cleanup some of the redundancy and spaghetti after last fix + - BUG/CRITICAL: http: don't update msg->sov once data start to leave the buffer + - MEDIUM: http: enable header manipulation for 101 responses + - BUG/MEDIUM: config: propagate frontend to backend process binding again. + - MEDIUM: config: properly propagate process binding between proxies + - MEDIUM: config: make the frontends automatically bind to the listeners' processes + - MEDIUM: config: compute the exact bind-process before listener's maxaccept + - MEDIUM: config: only warn if stats are attached to multi-process bind directives + - MEDIUM: config: report it when tcp-request rules are misplaced + - DOC: indicate in the doc that track-sc* can wait if data are missing + - MINOR: config: detect the case where a tcp-request content rule has no inspect-delay + - MEDIUM: systemd-wrapper: support multiple executable versions and names + - BUG/MEDIUM: remove debugging code from systemd-wrapper + - BUG/MEDIUM: http: adjust close mode when switching to backend + - BUG/MINOR: config: don't propagate process binding on fatal errors. + - BUG/MEDIUM: check: rule-less tcp-check must detect connect failures + - BUG/MINOR: tcp-check: report the correct failed step in the status + - DOC: indicate that weight zero is reported as DRAIN + - BUG/MEDIUM: config: avoid skipping disabled proxies + - BUG/MINOR: config: do not accept more track-sc than configured + - BUG/MEDIUM: backend: fix URI hash when a query string is present + - BUG/MEDIUM: http: don't dump debug headers on MSG_ERROR + - BUG/MAJOR: cli: explicitly call cli_release_handler() upon error + - BUG/MEDIUM: tcp: fix outgoing polling based on proxy protocol + - BUILD/MINOR: ssl: de-constify "ciphers" to avoid a warning on openssl-0.9.8 + - BUG/MEDIUM: tcp: don't use SO_ORIGINAL_DST on non-AF_INET sockets + - BUG/BUILD: revert accidental change in the makefile from latest SSL fix + - BUG/MEDIUM: ssl: force a full GC in case of memory shortage + - MEDIUM: ssl: add support for smaller SSL records + - MINOR: session: release a few other pools when stopping + - MINOR: task: release the task pool when stopping + - BUG/MINOR: config: don't inherit the default balance algorithm in frontends + - BUG/MAJOR: frontend: initialize capture pointers earlier + - BUG/MINOR: stats: correctly set the request/response analysers + - MAJOR: polling: centralize calls to I/O callbacks + - DOC: fix typo in the body parser documentation for msg.sov + - BUG/MINOR: peers: the buffer size is global.tune.bufsize, not trash.size + - MINOR: sample: add a few basic internal fetches (nbproc, proc, stopping) + - DEBUG: pools: apply poisonning on every allocated pool + - BUG/MAJOR: sessions: unlink session from list on out of memory + - BUG/MEDIUM: patterns: previous fix was incomplete + - BUG/MEDIUM: payload: ensure that a request channel is available + - BUG/MINOR: tcp-check: don't condition data polling on check type + - BUG/MEDIUM: tcp-check: don't rely on random memory contents + - BUG/MEDIUM: tcp-checks: disable quick-ack unless next rule is an expect + - BUG/MINOR: config: fix typo in condition when propagating process binding + - BUG/MEDIUM: config: do not propagate processes between stopped processes + - BUG/MAJOR: stream-int: properly check the memory allocation return + - BUG/MEDIUM: memory: fix freeing logic in pool_gc2() + - BUG/MAJOR: namespaces: conn->target is not necessarily a server + - BUG/MEDIUM: compression: correctly report zlib_mem + - CLEANUP: lists: remove dead code + - CLEANUP: memory: remove dead code + - CLEANUP: memory: replace macros pool_alloc2/pool_free2 with functions + - MINOR: memory: cut pool allocator in 3 layers + - MEDIUM: memory: improve pool_refill_alloc() to pass a refill count + - MINOR: stream-int: retrieve session pointer from stream-int + - MINOR: buffer: reset a buffer in b_reset() and not channel_init() + - MEDIUM: buffer: use b_alloc() to allocate and initialize a buffer + - MINOR: buffer: move buffer initialization after channel initialization + - MINOR: buffer: only use b_free to release buffers + - MEDIUM: buffer: always assign a dummy empty buffer to channels + - MEDIUM: buffer: add a new buf_wanted dummy buffer to report failed allocations + - MEDIUM: channel: do not report full when buf_empty is present on a channel + - MINOR: session: group buffer allocations together + - MINOR: buffer: implement b_alloc_fast() + - MEDIUM: buffer: implement b_alloc_margin() + - MEDIUM: session: implement a basic atomic buffer allocator + - MAJOR: session: implement a wait-queue for sessions who need a buffer + - MAJOR: session: only allocate buffers when needed + - MINOR: stats: report a "waiting" flags for sessions + - MAJOR: session: only wake up as many sessions as available buffers permit + - MINOR: config: implement global setting tune.buffers.reserve + - MINOR: config: implement global setting tune.buffers.limit + - MEDIUM: channel: implement a zero-copy buffer transfer + - MEDIUM: stream-int: support splicing from applets + - OPTIM: stream-int: try to send pending spliced data + - CLEANUP: session: remove session_from_task() + - DOC: add missing entry for log-format and clarify the text + - MINOR: logs: add a new per-proxy "log-tag" directive + - BUG/MEDIUM: http: fix header removal when previous header ends with pure LF + - MINOR: config: extend the default max hostname length to 64 and beyond + - BUG/MEDIUM: channel: fix possible integer overflow on reserved size computation + - BUG/MINOR: channel: compare to_forward with buf->i, not buf->size + - MINOR: channel: add channel_in_transit() + - MEDIUM: channel: make buffer_reserved() use channel_in_transit() + - MEDIUM: channel: make bi_avail() use channel_in_transit() + - BUG/MEDIUM: channel: don't schedule data in transit for leaving until connected + - CLEANUP: channel: rename channel_reserved -> channel_is_rewritable + - MINOR: channel: rename channel_full() to !channel_may_recv() + - MINOR: channel: rename buffer_reserved() to channel_reserved() + - MINOR: channel: rename buffer_max_len() to channel_recv_limit() + - MINOR: channel: rename bi_avail() to channel_recv_max() + - MINOR: channel: rename bi_erase() to channel_truncate() + - BUG/MAJOR: log: don't try to emit a log if no logger is set + - MINOR: tools: add new round_2dig() function to round integers + - MINOR: global: always export some SSL-specific metrics + - MINOR: global: report information about the cost of SSL connections + - MAJOR: init: automatically set maxconn and/or maxsslconn when possible + - MINOR: http: add a new fetch "query" to extract the request's query string + - MINOR: hash: add new function hash_crc32 + - MINOR: samples: provide a "crc32" converter + - MEDIUM: backend: add the crc32 hash algorithm for load balancing + - BUG/MINOR: args: add missing entry for ARGT_MAP in arg_type_names + - BUG/MEDIUM: http: make http-request set-header compute the string before removal + - MEDIUM: args: use #define to specify the number of bits used by arg types and counts + - MEDIUM: args: increase arg type to 5 bits and limit arg count to 5 + - MINOR: args: add type-specific flags for each arg in a list + - MINOR: args: implement a new arg type for regex : ARGT_REG + - MEDIUM: regex: add support for passing regex flags to regex_exec_match() + - MEDIUM: samples: add a regsub converter to perform regex-based transformations + - BUG/MINOR: sample: fix case sensitivity for the regsub converter + - MEDIUM: http: implement http-request set-{method,path,query,uri} + - DOC: fix missing closing brackend on regsub + - MEDIUM: samples: provide basic arithmetic and bitwise operators + - MEDIUM: init: continue to enforce SYSTEM_MAXCONN with auto settings if set + - BUG/MINOR: http: fix incorrect header value offset in replace-hdr/replace-value + - BUG/MINOR: http: abort request processing on filter failure + - MEDIUM: tcp: implement tcp-ut bind option to set TCP_USER_TIMEOUT + - MINOR: ssl/server: add the "no-ssl-reuse" server option + - BUG/MAJOR: peers: initialize s->buffer_wait when creating the session + - MINOR: http: add a new function to iterate over each header line + - MINOR: http: add the new sample fetches req.hdr_names and res.hdr_names + - MEDIUM: task: always ensure that the run queue is consistent + - BUILD: Makefile: add -Wdeclaration-after-statement + - BUILD/CLEANUP: ssl: avoid a warning due to mixed code and declaration + - BUILD/CLEANUP: config: silent 3 warnings about mixed declarations with code + - MEDIUM: protocol: use a family array to index the protocol handlers + - BUILD: lua: cleanup many mixed occurrences declarations & code + - BUG/MEDIUM: task: fix recently introduced scheduler skew + - BUG/MINOR: lua: report the correct function name in an error message + - BUG/MAJOR: http: fix stats regression consecutive to HTTP_RULE_RES_YIELD + - Revert "BUG/MEDIUM: lua: can't handle the response bytes" + - MINOR: lua: convert IP addresses to type string + - CLEANUP: lua: use the same function names in C and Lua + - REORG/MAJOR: move session's req and resp channels back into the session + - CLEANUP: remove now unused channel pool + - REORG/MEDIUM: stream-int: introduce si_ic/si_oc to access channels + - MEDIUM: stream-int: add a flag indicating which side the SI is on + - MAJOR: stream-int: only rely on SI_FL_ISBACK to find the requested channel + - MEDIUM: stream-interface: remove now unused pointers to channels + - MEDIUM: stream-int: make si_sess() use the stream int's side + - MEDIUM: stream-int: use si_task() to retrieve the task from the stream int + - MEDIUM: stream-int: remove any reference to the owner + - CLEANUP: stream-int: add si_ib/si_ob to dereference the buffers + - CLEANUP: stream-int: add si_opposite() to find the other stream interface + - REORG/MEDIUM: channel: only use chn_prod / chn_cons to find stream-interfaces + - MEDIUM: channel: add a new flag "CF_ISRESP" for the response channel + - MAJOR: channel: only rely on the new CF_ISRESP flag to find the SI + - MEDIUM: channel: remove now unused ->prod and ->cons pointers + - CLEANUP: session: simplify references to chn_{prod,cons}(&s->{req,res}) + - CLEANUP: session: use local variables to access channels / stream ints + - CLEANUP: session: don't needlessly pass a pointer to the stream-int + - CLEANUP: session: don't use si_{ic,oc} when we know the session. + - CLEANUP: stream-int: limit usage of si_ic/si_oc + - CLEANUP: lua: limit usage of si_ic/si_oc + - MINOR: channel: add chn_sess() helper to retrieve session from channel + - MEDIUM: session: simplify receive buffer allocator to only use the channel + - MEDIUM: lua: use CF_ISRESP to detect the channel's side + - CLEANUP: lua: remove the session pointer from hlua_channel + - CLEANUP: lua: hlua_channel_new() doesn't need the pointer to the session anymore + - MEDIUM: lua: remove struct hlua_channel + - MEDIUM: lua: remove hlua_sample_fetch + +2014/06/19 : 1.6-dev0 + - exact copy of 1.5.0 + +2014/06/19 : 1.5.0 + - MEDIUM: ssl: ignored file names ending as '.issuer' or '.ocsp'. + - MEDIUM: ssl: basic OCSP stapling support. + - MINOR: ssl/cli: Fix unapropriate comment in code on 'set ssl ocsp-response' + - MEDIUM: ssl: add 300s supported time skew on OCSP response update. + - MINOR: checks: mysql-check: Add support for v4.1+ authentication + - MEDIUM: ssl: Add the option to use standardized DH parameters >= 1024 bits + - MEDIUM: ssl: fix detection of ephemeral diffie-hellman key exchange by using the cipher description. + - MEDIUM: http: add actions "replace-header" and "replace-values" in http-req/resp + - MEDIUM: Break out check establishment into connect_chk() + - MEDIUM: Add port_to_str helper + - BUG/MEDIUM: fix ignored values for half-closed timeouts (client-fin and server-fin) in defaults section. + - BUG/MEDIUM: Fix unhandled connections problem with systemd daemon mode and SO_REUSEPORT. + - MINOR: regex: fix a little configuration memory leak. + - MINOR: regex: Create JIT compatible function that return match strings + - MEDIUM: regex: replace all standard regex function by own functions + - MEDIUM: regex: Remove null terminated strings. + - MINOR: regex: Use native PCRE API. + - MINOR: missing regex.h include + - DOC: Add Exim as Proxy Protocol implementer. + - BUILD: don't use type "uint" which is not portable + - BUILD: stats: workaround stupid and bogus -Werror=format-security behaviour + - BUG/MEDIUM: http: clear CF_READ_NOEXP when preparing a new transaction + - CLEANUP: http: don't clear CF_READ_NOEXP twice + - DOC: fix proxy protocol v2 decoder example + - DOC: fix remaining occurrences of "pattern extraction" + - MINOR: log: allow the HTTP status code to be logged even in TCP frontends + - MINOR: logs: don't limit HTTP header captures to HTTP frontends + - MINOR: sample: improve sample_fetch_string() to report partial contents + - MINOR: capture: extend the captures to support non-header keys + - MINOR: tcp: prepare support for the "capture" action + - MEDIUM: tcp: add a new tcp-request capture directive + - MEDIUM: session: allow shorter retry delay if timeout connect is small + - MEDIUM: session: don't apply the retry delay when redispatching + - MEDIUM: session: redispatch earlier when possible + - MINOR: config: warn when tcp-check rules are used without option tcp-check + - BUG/MINOR: connection: make proxy protocol v1 support the UNKNOWN protocol + - DOC: proxy protocol example parser was still wrong + - DOC: minor updates to the proxy protocol doc + - CLEANUP: connection: merge proxy proto v2 header and address block + - MEDIUM: connection: add support for proxy protocol v2 in accept-proxy + - MINOR: tools: add new functions to quote-encode strings + - DOC: clarify the CSV format + - MEDIUM: stats: report the last check and last agent's output on the CSV status + - MINOR: freq_ctr: introduce a new averaging method + - MEDIUM: session: maintain per-backend and per-server time statistics + - MEDIUM: stats: report per-backend and per-server time stats in HTML and CSV outputs + - BUG/MINOR: http: fix typos in previous patch + - DOC: remove the ultra-obsolete TODO file + - DOC: update roadmap + - DOC: minor updates to the README + - DOC: mention the maxconn limitations with the select poller + - DOC: commit a few old design thoughts files + +2014/05/28 : 1.5-dev26 + - BUG/MEDIUM: polling: fix possible CPU hogging of worker processes after receiving SIGUSR1. + - BUG/MINOR: stats: fix a typo on a closing tag for a server tracking another one + - OPTIM: stats: avoid the calculation of a useless link on tracking servers in maintenance + - MINOR: fix a few memory usage errors + - CONTRIB: halog: Filter input lines by date and time through timestamp + - MINOR: ssl: SSL_CTX_set_options() and SSL_CTX_set_mode() take a long, not an int + - BUG/MEDIUM: regex: fix risk of buffer overrun in exp_replace() + - MINOR: acl: set "str" as default match for strings + - DOC: Add some precisions about acl default matching method + - MEDIUM: acl: strenghten the option parser to report invalid options + - BUG/MEDIUM: config: a stats-less config crashes in 1.5-dev25 + - BUG/MINOR: checks: tcp-check must not stop on '\0' for binary checks + - MINOR: stats: improve alignment of color codes to save one line of header + - MINOR: checks: simplify and improve reporting of state changes when using log-health-checks + - MINOR: server: remove the SRV_DRAIN flag which can always be deduced + - MINOR: server: use functions to detect state changes and to update them + - MINOR: server: create srv_was_usable() from srv_is_usable() and use a pointer + - BUG/MINOR: stats: do not report "100%" in the thottle column when server is draining + - BUG/MAJOR: config: don't free valid regex memory + - BUG/MEDIUM: session: don't clear CF_READ_NOEXP if analysers are not called + - BUG/MINOR: stats: tracking servers may incorrectly report an inherited DRAIN status + - MEDIUM: proxy: make timeout parser a bit stricter + - REORG/MEDIUM: server: split server state and flags in two different variables + - REORG/MEDIUM: server: move the maintenance bits out of the server state + - MAJOR: server: use states instead of flags to store the server state + - REORG: checks: put the functions in the appropriate files ! + - MEDIUM: server: properly support and propagate the maintenance status + - MEDIUM: server: allow multi-level server tracking + - CLEANUP: checks: rename the server_status_printf function + - MEDIUM: checks: simplify server up/down/nolb transitions + - MAJOR: checks: move health checks changes to set_server_check_status() + - MINOR: server: make the status reporting function support a reason + - MINOR: checks: simplify health check reporting functions + - MINOR: server: implement srv_set_stopped() + - MINOR: server: implement srv_set_running() + - MINOR: server: implement srv_set_stopping() + - MEDIUM: checks: simplify failure notification using srv_set_stopped() + - MEDIUM: checks: simplify success notification using srv_set_running() + - MEDIUM: checks: simplify stopping mode notification using srv_set_stopping() + - MEDIUM: stats: report a server's own state instead of the tracked one's + - MINOR: server: make use of srv_is_usable() instead of checking eweight + - MAJOR: checks: add support for a new "drain" administrative mode + - MINOR: stats: use the admin flags for soft enable/disable/stop/start on the web page + - MEDIUM: stats: introduce new actions to simplify admin status management + - MINOR: cli: introduce a new "set server" command + - MINOR: stats: report a distinct output for DOWN caused by agent + - MINOR: checks: support specific check reporting for the agent + - MINOR: checks: support a neutral check result + - BUG/MINOR: cli: "agent" was missing from the "enable"/"disable" help message + - MEDIUM: cli: add support for enabling/disabling health checks. + - MEDIUM: stats: report down caused by agent prior to reporting up + - MAJOR: agent: rework the response processing and support additional actions + - MINOR: stats: improve the stats web page to support more actions + - CONTRIB: halog: avoid calling time/localtime/mktime for each line + - DOC: document the workarouds for Google Chrome's bogus pre-connect + - MINOR: stats: report SSL key computations per second + - MINOR: stats: add counters for SSL cache lookups and misses + +2014/05/10 : 1.5-dev25 + - MEDIUM: connection: Implement and extented PROXY Protocol V2 + - MINOR: ssl: clean unused ACLs declarations + - MINOR: ssl: adds fetchs and ACLs for ssl back connection. + - MINOR: ssl: merge client's and frontend's certificate functions. + - MINOR: ssl: adds ssl_f_sha1 fetch to return frontend's certificate fingerprint + - MINOR: ssl: adds sample converter base64 for binary type. + - MINOR: ssl: convert to binary ssl_fc_unique_id and ssl_bc_unique_id. + - BUG/MAJOR: ssl: Fallback to private session cache if current lock mode is not supported. + - MAJOR: ssl: Change default locks on ssl session cache. + - BUG/MINOR: chunk: Fix function chunk_strcmp and chunk_strcasecmp match a substring. + - MINOR: ssl: add global statement tune.ssl.force-private-cache. + - MINOR: ssl: remove fallback to SSL session private cache if lock init fails. + - BUG/MEDIUM: patterns: last fix was still not enough + - MINOR: http: export the smp_fetch_cookie function + - MINOR: http: generic pointer to rule argument + - BUG/MEDIUM: pattern: a typo breaks automatic acl/map numbering + - BUG/MAJOR: patterns: -i and -n are ignored for inlined patterns + - BUG/MINOR: proxy: unsafe initialization of HTTP transaction when switching from TCP frontend + - BUG/MINOR: http: log 407 in case of proxy auth + - MINOR: http: rely on the message body parser to send 100-continue + - MEDIUM: http: move reqadd after execution of http_request redirect + - MEDIUM: http: jump to dedicated labels after http-request processing + - BUG/MINOR: http: block rules forgot to increment the denied_req counter + - BUG/MINOR: http: block rules forgot to increment the session's request counter + - MEDIUM: http: move Connection header processing earlier + - MEDIUM: http: remove even more of the spaghetti in the request path + - MINOR: http: silently support the "block" action for http-request + - CLEANUP: proxy: rename "block_cond" to "block_rules" + - MEDIUM: http: emulate "block" rules using "http-request" rules + - MINOR: http: remove the now unused loop over "block" rules + - MEDIUM: http: factorize the "auth" action of http-request and stats + - MEDIUM: http: make http-request rules processing return a verdict instead of a rule + - MINOR: config: add minimum support for emitting warnings only once + - MEDIUM: config: inform the user about the deprecatedness of "block" rules + - MEDIUM: config: inform the user that "reqsetbe" is deprecated + - MEDIUM: config: inform the user only once that "redispatch" is deprecated + - MEDIUM: config: warn that '{cli,con,srv}timeout' are deprecated + - BUG/MINOR: auth: fix wrong return type in pat_match_auth() + - BUILD: config: remove a warning with clang + - BUG/MAJOR: http: connection setup may stall on balance url_param + - BUG/MEDIUM: http/session: disable client-side expiration only after body + - BUG/MEDIUM: http: correctly report request body timeouts + - BUG/MEDIUM: http: disable server-side expiration until client has sent the body + - MEDIUM: listener: make the accept function more robust against pauses + - BUILD: syscalls: remove improper inline statement in front of syscalls + - BUILD: ssl: SSL_CTX_set_msg_callback() needs openssl >= 0.9.7 + - BUG/MAJOR: session: recover the correct connection pointer in half-initialized sessions + - DOC: add some explanation on the shared cache build options in the readme. + - MEDIUM: proxy: only adjust the backend's bind-process when already set + - MEDIUM: config: limit nbproc to the machine's word size + - MEDIUM: config: check the bind-process settings according to nbproc + - MEDIUM: listener: parse the new "process" bind keyword + - MEDIUM: listener: inherit the process mask from the proxy + - MAJOR: listener: only start listeners bound to the same processes + - MINOR: config: only report a warning when stats sockets are bound to more than 1 process + - CLEANUP: config: set the maxaccept value for peers listeners earlier + - BUG/MINOR: backend: only match IPv4 addresses with RDP cookies + - BUG/MINOR: checks: correctly configure the address family and protocol + - MINOR: tools: split is_addr() and is_inet_addr() + - MINOR: protocols: use is_inet_addr() when only INET addresses are desired + - MEDIUM: unix: add preliminary support for connecting to servers over UNIX sockets + - MEDIUM: checks: only complain about the missing port when the check uses TCP + - MEDIUM: unix: implement support for Linux abstract namespace sockets + - DOC: map_beg was missing from the table of map_* converters + - DOC: ebtree: indicate that prefix insertion/lookup may be used with strings + - MEDIUM: pattern: use ebtree's longest match to index/lookup string beginning + - BUILD: remove the obsolete BSD and OSX makefiles + - MEDIUM: unix: avoid a double connect probe when no data are sent + - DOC: stop referencing the slow git repository in the README + - BUILD: only build the systemd wrapper on Linux 2.6 and above + - DOC: update roadmap with completed tasks + - MEDIUM: session: implement half-closed timeouts (client-fin and server-fin) + +2014/04/26 : 1.5-dev24 + - MINOR: pattern: find element in a reference + - MEDIUM: http: ACL and MAP updates through http-(request|response) rules + - MEDIUM: ssl: explicitly log failed handshakes after a heartbeat + - DOC: Full section dedicated to the converters + - MEDIUM: http: register http-request and http-response keywords + - BUG/MINOR: compression: correctly report incoming byte count + - BUG/MINOR: http: don't report server aborts as client aborts + - BUG/MEDIUM: channel: bi_putblk() must not wrap before the end of buffer + - CLEANUP: buffers: remove unused function buffer_contig_space_with_res() + - MEDIUM: stats: reimplement HTTP keep-alive on the stats page + - BUG/MAJOR: http: fix timeouts during data forwarding + - BUG/MEDIUM: http: 100-continue responses must process the next part immediately + - MEDIUM: http: move skipping of 100-continue earlier + - BUILD: stats: let gcc know that last_fwd cannot be used uninitialized... + - CLEANUP: general: get rid of all old occurrences of "session *t" + - CLEANUP: http: remove the useless "if (1)" inherited from version 1.4 + - BUG/MEDIUM: stats: mismatch between behaviour and doc about front/back + - MEDIUM: http: enable analysers to have keep-alive on stats + - REORG: http: move HTTP Connection response header parsing earlier + - MINOR: stats: always emit HTTP/1.1 in responses + - MINOR: http: add capture.req.ver and capture.res.ver + - MINOR: checks: add a new global max-spread-checks directive + - BUG/MAJOR: http: fix the 'next' pointer when performing a redirect + - MINOR: http: implement the max-keep-alive-queue setting + - DOC: fix alphabetic order of tcp-check + - MINOR: connection: add a new error code for SSL with heartbeat + - MEDIUM: ssl: implement a workaround for the OpenSSL heartbleed attack + - BUG/MEDIUM: Revert "MEDIUM: ssl: Add standardized DH parameters >= 1024 bits" + - BUILD: http: remove a warning on strndup + - BUILD: ssl: avoid a warning about conn not used with OpenSSL < 1.0.1 + - BUG/MINOR: ssl: really block OpenSSL's response to heartbleed attack + - MINOR: ssl: finally catch the heartbeats missing the padding + +2014/04/23 : 1.5-dev23 + - BUG/MINOR: reject malformed HTTP/0.9 requests + - MINOR: systemd wrapper: re-execute on SIGUSR2 + - MINOR: systemd wrapper: improve logging + - MINOR: systemd wrapper: propagate exit status + - BUG/MINOR: tcpcheck connect wrong behavior + - MEDIUM: proxy: support use_backend with dynamic names + - MINOR: stats: Enhancement to stats page to provide information of last session time. + - BUG/MEDIUM: peers: fix key consistency for integer stick tables + - DOC: fix a typo on http-server-close and encapsulate options with double-quotes + - DOC: fix fetching samples syntax + - MINOR: ssl: add ssl_fc_unique_id to fetch TLS Unique ID + - MEDIUM: ssl: Use ALPN support as it will be available in OpenSSL 1.0.2 + - DOC: fix typo + - CLEANUP: code style: use tabs to indent codes instead of spaces + - DOC: fix a few config typos. + - BUG/MINOR: raw_sock: also consider ENOTCONN in addition to EAGAIN for recv() + - DOC: lowercase format string in unique-id + - MINOR: set IP_FREEBIND on IPv6 sockets in transparent mode + - BUG/MINOR: acl: req_ssl_sni fails with SSLv3 record version + - BUG/MINOR: build: add missing objects in osx and bsd Makefiles + - BUG/MINOR: build: handle whitespaces in wc -l output + - BUG/MINOR: Fix name lookup ordering when compiled with USE_GETADDRINFO + - MEDIUM: ssl: Add standardized DH parameters >= 1024 bits + - BUG/MEDIUM: map: The map parser includes blank lines. + - BUG/MINOR: log: The log of quotted capture header has been terminated by 2 quotes. + - MINOR: standard: add function "encode_chunk" + - BUG/MINOR: http: fix encoding of samples used in http headers + - MINOR: sample: add hex converter + - MEDIUM: sample: change the behavior of the bin2str cast + - MAJOR: auth: Change the internal authentication system. + - MEDIUM: acl/pattern: standardisation "of pat_parse_int()" and "pat_parse_dotted_ver()" + - MEDIUM: pattern: The pattern parser no more uses and just takes one string. + - MEDIUM: pattern: Change the prototype of the function pattern_register(). + - CONTRIB: ip6range: add a network IPv6 range to mask converter + - MINOR: pattern: separe list element from the data part. + - MEDIUM: pattern: add indexation function. + - MEDIUM: pattern: The parse functions just return "struct pattern" without memory allocation + - MINOR: pattern: Rename "pat_idx_elt" to "pattern_tree" + - MINOR: sample: dont call the sample cast function "c_none" + - MINOR: standard: Add function for converting cidr to network mask. + - MEDIUM: sample: Remove types SMP_T_CSTR and SMP_T_CBIN, replace it by SMP_F_CONST flags + - MEDIUM: sample/http_proto: Add new type called method + - MINOR: dumpstats: Group map inline help + - MEDIUM: pattern: The function pattern_exec_match() returns "struct pattern" if the patten match. + - MINOR: dumpstats: change map inline sentences + - MINOR: dumpstats: change the "get map" display management + - MINOR: map/dumpstats: The cli cmd "get map ..." display the "int" format. + - MEDIUM: pattern: The match function browse itself the list or the tree. + - MEDIUM: pattern: Index IPv6 addresses in a tree. + - MEDIUM: pattern: add delete functions + - MEDIUM: pattern: add prune function + - MEDIUM: pattern: add sample lookup function. + - MEDIUM: pattern/dumpstats: The function pattern_lookup() is no longer used + - MINOR: map/pattern: The sample parser is stored in the pattern + - MAJOR: pattern/map: Extends the map edition system in the patterns + - MEDIUM: pattern: merge same pattern + - MEDIUM: pattern: The expected type is stored in the pattern head, and conversion is executed once. + - MINOR: pattern: Each pattern is identified by unique id. + - MINOR: pattern/acl: Each pattern of each acl can be load with specified id + - MINOR: pattern: The function "pattern_register()" is no longer used. + - MINOR: pattern: Merge function pattern_add() with pat_ref_push(). + - MINOR: pattern: store configuration reference for each acl or map pattern. + - MINOR: pattern: Each pattern expression element store the reference struct. + - MINOR: dumpstats: display the reference for th key/pattern and value. + - MEDIUM: pattern: delete() function uses the pat_ref_elt to find the element to be removed + - MEDIUM: pattern_find_smp: functions find_smp uses the pat_ref_elt to find the element to be removed + - MEDIUM: dumpstats/pattern: display and use each pointer of each pattern dumped + - MINOR: pattern/map/acl: Centralization of the file parsers + - MINOR: pattern: Check if the file reference is not used with acl and map + - MINOR: acl/pattern: Acl "-M" option force to load file as map file with two columns + - MEDIUM: dumpstats: Display error message during add of values. + - MINOR: pattern: The function pat_ref_set() have now atomic behavior + - MINOR: regex: The pointer regstr in the struc regex is no longer used. + - MINOR: cli: Block the usage of the command "acl add" in many cases. + - MINOR: doc: Update the documentation about the map and acl + - MINOR: pattern: index duplicates + - MINOR: configuration: File and line propagation + - MINOR: dumpstat/conf: display all the configuration lines that using pattern reference + - MINOR: standard: Disable ip resolution during the runtime + - MINOR: pattern: Remove the flag "PAT_F_FROM_FILE". + - MINOR: pattern: forbid dns resolutions + - DOC: document "get map" / "get acl" on the CLI + - MEDIUM: acl: Change the acl register struct + - BUG/MEDIUM: acl: boolean only matches were broken by recent changes + - DOC: pattern: pattern organisation schematics + - MINOR: pattern/cli: Update used terms in documentation and cli + - MINOR: cli: remove information about acl or map owner. + - MINOR: session: don't always assume there's a listener + - MINOR: pattern: Add function to prune and reload pattern list. + - MINOR: standard: Add ipv6 support in the function url2sa(). + - MEDIUM: config: Dynamic sections. + - BUG/MEDIUM: stick-table: fix IPv4-to-IPv6 conversion in src_* fetches + - MINOR: http: Add the "language" converter to for use with accept-language + - BUG/MINOR: log: Don't dump empty unique-id + - BUG/MAJOR: session: fix a possible crash with src_tracked + - DOC: Update "language" documentation + - MINOR: http: add the function "del-header" to the directives http-request and http-response + - DOC: add some information on capture.(req|res).hdr + - MINOR: http: capture.req.method and capture.req.uri + - MINOR: http: optimize capture.req.method and capture.req.uri + - MINOR: session: clean up the connection free code + - BUG/MEDIUM: checks: immediately report a connection success + - MEDIUM: connection: don't use real send() flags in snd_buf() + - OPTIM: ssl: implement dynamic record size adjustment + - MINOR: stats: report exact last session time in backend too + - BUG/MEDIUM: stats: the "lastsess" field must appear last in the CSV. + - BUG/MAJOR: check: fix memory leak in "tcp-check connect" over SSL + - BUG/MINOR: channel: initialize xfer_small/xfer_large on new buffers + - MINOR: channel: add the date of last read in the channel + - MEDIUM: stream-int: automatically disable CF_STREAMER flags after idle + - MINOR: ssl: add DEFAULT_SSL_MAX_RECORD to set the record size at build time + - MINOR: config: make the stream interface idle timer user-configurable + - MINOR: config: add global directives to set default SSL ciphers + - MINOR: sample: add a rand() sample fetch to return a sample. + - BUG/MEDIUM: config: immediately abort if peers section has no name + - BUG/MINOR: ssl: fix syntax in config error message + - BUG/MEDIUM: ssl: always send a full buffer after EAGAIN + - BUG/MINOR: config: server on-marked-* statement is ignored in default-server + - BUG/MEDIUM: backend: prefer-last-server breaks redispatch + - BUG/MEDIUM: http: continue to emit 503 on keep-alive to different server + - MEDIUM: acl: fix pattern type for payload / payload_lv + - BUG/MINOR: config: fix a crash on startup when a disabled backend references a peer + - BUG/MEDIUM: compression: fix the output type of the compressor name + - BUG/MEDIUM: http: don't start to forward request data before the connect + - MINOR: http: release compression context only in http_end_txn() + - MINOR: protect ebimtree/ebistree against multiple inclusions + - MEDIUM: proxy: create a tree to store proxies by name + - MEDIUM: proxy: make findproxy() use trees to look up proxies + - MEDIUM: proxy: make get_backend_server() use findproxy() to lookup proxies + - MEDIUM: stick-table: lookup table names using trees. + - MEDIUM: config: faster lookup for duplicated proxy name + - CLEANUP: acl: remove obsolete test in parse_acl_expr() + - MINOR: sample: move smp_to_type to sample.c + - MEDIUM: compression: consider the "q=" attribute in Accept-Encoding + - REORG: cfgparse: move server keyword parsing to server.c + - BUILD: adjust makefile for AIX 5.1 + - BUG/MEDIUM: pattern: fix wrong definition of the pat_prune_fcts array + - CLEANUP: pattern: move array definitions to proto/ and not types/ + - BUG/MAJOR: counters: check for null-deref when looking up an alternate table + - BUILD: ssl: previous patch failed + - BUILD/MEDIUM: standard: get rid of the last strcpy() + - BUILD/MEDIUM: standard: get rid of sprintf() + - BUILD/MEDIUM: cfgparse: get rid of sprintf() + - BUILD/MEDIUM: checks: get rid of sprintf() + - BUILD/MEDIUM: http: remove calls to sprintf() + - BUG/MEDIUM: systemd-wrapper: fix locating of haproxy binary + - BUILD/MINOR: ssl: remove one call to sprintf() + - MEDIUM: http: don't reject anymore message bodies not containing the url param + - MEDIUM: http: wait for the first chunk or message body length in http_process_body + - CLEANUP: http: rename http_process_request_body() + - CLEANUP: http: prepare dedicated processing for chunked encoded message bodies + - MINOR: http: make msg->eol carry the last CRLF length + - MAJOR: http: do not use msg->sol while processing messages or forwarding data + - MEDIUM: http: http_parse_chunk_crlf() must not advance the buffer pointer + - MAJOR: http: don't update msg->sov anymore while processing the body + - MINOR: http: add a small helper to compute the amount of body bytes present + - MEDIUM: http: add a small helper to compute how far to rewind to find headers + - MINOR: http: add a small helper to compute how far to rewind to find URI + - MEDIUM: http: small helpers to compute how far to rewind to find BODY and DATA + - MAJOR: http: reset msg->sov after headers are forwarded + - MEDIUM: http: forward headers again while waiting for connection to complete + - BUG/MINOR: http: deinitialize compression after a parsing error + - BUG/MINOR: http: deinitialize compression after a compression error + - MEDIUM: http: headers must be forwarded even if data was already inspected + - MAJOR: http: re-enable compression on chunked encoding + - MAJOR: http/compression: fix chunked-encoded response processing + - MEDIUM: http: cleanup: centralize a little bit HTTP compression end + - MEDIUM: http: start to centralize the forwarding code + - MINOR: http: further cleanups of response forwarding function + - MEDIUM: http: only allocate the temporary compression buffer when needed + - MAJOR: http: centralize data forwarding in the request path + - CLEANUP: http: document the response forwarding states + - CLEANUP: http: remove all calls to http_silent_debug() + - DOC: internal: add some reminders about HTTP parsing and pointer states + - BUG/MAJOR: http: fix bug in parse_qvalue() when selecting compression algo + - BUG/MINOR: stats: last session was not always set + - DOC: add pointer to the Cyril's HTML doc in the README + - MEDIUM: config: relax use_backend check to make the condition optional + - MEDIUM: config: report misplaced http-request rules + - MEDIUM: config: report misplaced use-server rules + - DOC: update roadmap with what was done. + +2014/02/03 : 1.5-dev22 + - MEDIUM: tcp-check new feature: connect + - MEDIUM: ssl: Set verify 'required' as global default for servers side. + - MINOR: ssl: handshake optim for long certificate chains. + - BUG/MINOR: pattern: pattern comparison executed twice + - BUG/MEDIUM: map: segmentation fault with the stats's socket command "set map ..." + - BUG/MEDIUM: pattern: Segfault in binary parser + - MINOR: pattern: move functions for grouping pat_match_* and pat_parse_* and add documentation. + - MINOR: standard: The parse_binary() returns the length consumed and his documentation is updated + - BUG/MINOR: payload: the patterns of the acl "req.ssl_ver" are no parsed with the good function. + - BUG/MEDIUM: pattern: "pat_parse_dotted_ver()" set bad expect_type. + - BUG/MINOR: sample: The c_str2int converter does not fail if the entry is not an integer + - BUG/MEDIUM: http/auth: Sometimes the authentication credentials can be mix between two requests + - MINOR: doc: Bad cli function name. + - MINOR: http: smp_fetch_capture_header_* fetch captured headers + - BUILD: last release inadvertently prepended a "+" in front of the date + - BUG/MEDIUM: stream-int: fix the keep-alive idle connection handler + - BUG/MEDIUM: backend: do not re-initialize the connection's context upon reuse + - BUG: Revert "OPTIM/MEDIUM: epoll: fuse active events into polled ones during polling changes" + - BUG/MINOR: checks: successful check completion must not re-enable MAINT servers + - MINOR: http: try to stick to same server after status 401/407 + - BUG/MINOR: http: always disable compression on HTTP/1.0 + - OPTIM: poll: restore polling after a poll/stop/want sequence + - OPTIM: http: don't stop polling for read on the client side after a request + - BUG/MEDIUM: checks: unchecked servers could not be enabled anymore + - BUG/MEDIUM: stats: the web interface must check the tracked servers before enabling + - BUG/MINOR: channel: CHN_INFINITE_FORWARD must be unsigned + - BUG/MINOR: stream-int: do not clear the owner upon unregister + - MEDIUM: stats: add support for HTTP keep-alive on the stats page + - BUG/MEDIUM: stats: fix HTTP/1.0 breakage introduced in previous patch + - Revert "MEDIUM: stats: add support for HTTP keep-alive on the stats page" + - MAJOR: channel: add a new flag CF_WAKE_WRITE to notify the task of writes + - OPTIM: session: set the READ_DONTWAIT flag when connecting + - BUG/MINOR: http: don't clear the SI_FL_DONT_WAKE flag between requests + - MINOR: session: factor out the connect time measurement + - MEDIUM: session: prepare to support earlier transitions to the established state + - MEDIUM: stream-int: make si_connect() return an established state when possible + - MINOR: checks: use an inline function for health_adjust() + - OPTIM: session: put unlikely() around the freewheeling code + - MEDIUM: config: report a warning when multiple servers have the same name + - BUG: Revert "OPTIM: poll: restore polling after a poll/stop/want sequence" + - BUILD/MINOR: listener: remove a glibc warning on accept4() + - BUG/MAJOR: connection: fix mismatch between rcv_buf's API and usage + - BUILD: listener: fix recent accept4() again + - BUG/MAJOR: ssl: fix breakage caused by recent fix abf08d9 + - BUG/MEDIUM: polling: ensure we update FD status when there's no more activity + - MEDIUM: listener: fix polling management in the accept loop + - MINOR: protocol: improve the proto->drain() API + - MINOR: connection: add a new conn_drain() function + - MEDIUM: tcp: report in tcp_drain() that lingering is already disabled on close + - MEDIUM: connection: update callers of ctrl->drain() to use conn_drain() + - MINOR: connection: add more error codes to report connection errors + - MEDIUM: tcp: report connection error at the connection level + - MEDIUM: checks: make use of chk_report_conn_err() for connection errors + - BUG/MEDIUM: unique_id: HTTP request counter is not stable + - DOC: fix misleading information about SIGQUIT + - BUG/MAJOR: fix freezes during compression + - BUG/MEDIUM: stream-interface: don't wake the task up before end of transfer + - BUILD: fix VERDATE exclusion regex + - CLEANUP: polling: rename "spec_e" to "state" + - DOC: add a diagram showing polling state transitions + - REORG: polling: rename "spec_e" to "state" and "spec_p" to "cache" + - REORG: polling: rename "fd_spec" to "fd_cache" + - REORG: polling: rename the cache allocation functions + - REORG: polling: rename "fd_process_spec_events()" to "fd_process_cached_events()" + - MAJOR: polling: rework the whole polling system + - MAJOR: connection: remove the CO_FL_WAIT_{RD,WR} flags + - MEDIUM: connection: remove conn_{data,sock}_poll_{recv,send} + - MEDIUM: connection: add check for readiness in I/O handlers + - MEDIUM: stream-interface: the polling flags must always be updated in chk_snd_conn + - MINOR: stream-interface: no need to call fd_stop_both() on error + - MEDIUM: connection: no need to recheck FD state + - CLEANUP: connection: use conn_ctrl_ready() instead of checking the flag + - CLEANUP: connection: use conn_xprt_ready() instead of checking the flag + - CLEANUP: connection: fix comments in connection.h to reflect new behaviour. + - OPTIM: raw-sock: don't speculate after a short read if polling is enabled + - MEDIUM: polling: centralize polled events processing + - MINOR: polling: create function fd_compute_new_polled_status() + - MINOR: cli: add more information to the "show info" output + - MEDIUM: listener: add support for limiting the session rate in addition to the connection rate + - MEDIUM: listener: apply a limit on the session rate submitted to SSL + - REORG: stats: move the stats socket states to dumpstats.c + - MINOR: cli: add the new "show pools" command + - BUG/MEDIUM: counters: flush content counters after each request + - BUG/MEDIUM: counters: fix stick-table entry leak when using track-sc2 in connection + - MINOR: tools: add very basic support for composite pointers + - MEDIUM: counters: stop relying on session flags at all + - BUG/MINOR: cli: fix missing break in command line parser + - BUG/MINOR: config: correctly report when log-format headers require HTTP mode + - MAJOR: http: update connection mode configuration + - MEDIUM: http: make keep-alive + httpclose be passive mode + - MAJOR: http: switch to keep-alive mode by default + - BUG/MEDIUM: http: fix regression caused by recent switch to keep-alive by default + - BUG/MEDIUM: listener: improve detection of non-working accept4() + - BUILD: listener: add fcntl.h and unistd.h + - BUG/MINOR: raw_sock: correctly set the MSG_MORE flag + +2013/12/17 : 1.5-dev21 + - MINOR: stats: don't use a monospace font to report numbers + - MINOR: session: remove debugging code + - BUG/MAJOR: patterns: fix double free caused by loading strings from files + - MEDIUM: http: make option http_proxy automatically rewrite the URL + - BUG/MEDIUM: http: cook_cnt() forgets to set its output type + - BUG/MINOR: stats: correctly report throttle rate of low weight servers + - BUG/MEDIUM: checks: servers must not start in slowstart mode + - BUG/MINOR: acl: parser must also stop at comma on ACL-only keywords + - MEDIUM: stream-int: implement a very simplistic idle connection manager + - DOC: update the ROADMAP file + +2013/12/16 : 1.5-dev20 + - DOC: add missing options to the manpage + - DOC: add manpage references to all system calls + - DOC: update manpage reference to haproxy-en.txt + - DOC: remove -s and -l options from the manpage + - DOC: missing information for the "description" keyword + - DOC: missing http-send-name-header keyword in keyword table + - MINOR: tools: function my_memmem() to lookup binary contents + - MEDIUM: checks: add send/expect tcp based check + - MEDIUM: backend: Enhance hash-type directive with an algorithm options + - MEDIUM: backend: Implement avalanche as a modifier of the hashing functions. + - DOC: Documentation for hashing function, with test results. + - BUG/MEDIUM: ssl: potential memory leak using verifyhost + - BUILD: ssl: compilation issue with openssl v0.9.6. + - BUG/MINOR: ssl: potential memory leaks using ssl_c_key_alg or ssl_c_sig_alg. + - MINOR: ssl: optimization of verifyhost on wildcard certificates. + - BUG/MINOR: ssl: verifyhost does not match empty strings on wildcard. + - MINOR: ssl: Add statement 'verifyhost' to "server" statements + - CLEANUP: session: remove event_accept() which was not used anymore + - BUG/MINOR: deinit: free fdinfo while doing cleanup + - DOC: minor typo fix in documentation + - BUG/MEDIUM: server: set the macro for server's max weight SRV_UWGHT_MAX to SRV_UWGHT_RANGE + - BUG/MINOR: use the same check condition for server as other algorithms + - DOC: fix typo in comments + - BUG/MINOR: deinit: free server map which is allocated in init_server_map() + - CLEANUP: stream_interface: cleanup loop information in si_conn_send_loop() + - MINOR: buffer: align the last output line of buffer_dump() + - MINOR: buffer: align the last output line if there are less than 8 characters left + - DOC: stick-table: modify the description + - OPTIM: stream_interface: return directly if the connection flag CO_FL_ERROR has been set + - CLEANUP: code style: use tabs to indent codes + - DOC: checkcache: block responses with cacheable cookies + - BUG/MINOR: check_config_validity: check the returned value of stktable_init() + - MEDIUM: haproxy-systemd-wrapper: Use haproxy in same directory + - MEDIUM: systemd-wrapper: Kill child processes when interrupted + - LOW: systemd-wrapper: Write debug information to stdout + - BUG/MINOR: http: fix "set-tos" not working in certain configurations + - MEDIUM: http: add IPv6 support for "set-tos" + - DOC: ssl: update build instructions to use new SSL_* variables + - BUILD/MINOR: systemd: fix compiler warning about unused result + - url32+src - like base32+src but whole url including parameters + - BUG/MINOR: fix forcing fastinter in "on-error" + - CLEANUP: Make parameters of srv_downtime and srv_getinter const + - CLEANUP: Remove unused 'last_slowstart_change' field from struct peer + - MEDIUM: Split up struct server's check element + - MEDIUM: Move result element to struct check + - MEDIUM: Paramatise functions over the check of a server + - MEDIUM: cfgparse: Factor out check initialisation + - MEDIUM: Add state to struct check + - MEDIUM: Move health element to struct check + - MEDIUM: Add helper for task creation for checks + - MEDIUM: Add helper function for failed checks + - MEDIUM: Log agent fail, stopped or down as info + - MEDIUM: Remove option lb-agent-chk + - MEDIUM: checks: Add supplementary agent checks + - MEDIUM: Do not mark a server as down if the agent is unavailable + - MEDIUM: Set rise and fall of agent checks to 1 + - MEDIUM: Add enable and disable agent unix socket commands + - MEDIUM: Add DRAIN state and report it on the stats page + - BUILD/MINOR: missing header file + - CLEANUP: regex: Create regex_comp function that compiles regex using compilation options + - CLEANUP: The function "regex_exec" needs the string length but in many case they expect null terminated char. + - MINOR: http: some exported functions were not in the header file + - MINOR: http: change url_decode to return the size of the decoded string. + - BUILD/MINOR: missing header file + - BUG/MEDIUM: sample: The function v4tov6 cannot support input and output overlap + - BUG/MINOR: arg: fix error reporting for add-header/set-header sample fetch arguments + - MINOR: sample: export the generic sample conversion parser + - MINOR: sample: export sample_casts + - MEDIUM: acl: use the fetch syntax 'fetch(args),conv(),conv()' into the ACL keyword + - MINOR: stick-table: use smp_expr_output_type() to retrieve the output type of a "struct sample_expr" + - MINOR: sample: provide the original sample_conv descriptor struct to the argument checker function. + - MINOR: tools: Add a function to convert buffer to an ipv6 address + - MINOR: acl: export acl arrays + - MINOR: acl: Extract the pattern parsing and indexation from the "acl_read_patterns_from_file()" function + - MINOR: acl: Extract the pattern matching function + - MINOR: sample: Define new struct sample_storage + - MEDIUM: acl: associate "struct sample_storage" to each "struct acl_pattern" + - REORG: acl/pattern: extract pattern matching from the acl file and create pattern.c + - MEDIUM: pattern: create pattern expression + - MEDIUM: pattern: rename "acl" prefix to "pat" + - MEDIUM: sample: let the cast functions set their output type + - MINOR: sample: add a private field to the struct sample_conv + - MINOR: map: Define map types + - MEDIUM: sample: add the "map" converter + - MEDIUM: http: The redirect strings follows the log format rules. + - BUG/MINOR: acl: acl parser does not recognize empty converter list + - BUG/MINOR: map: The map list was declared in the map.h file + - MINOR: map: Cleanup the initialisation of map descriptors. + - MEDIUM: map: merge identical maps + - BUG/MEDIUM: pattern: Pattern node has type of "struct pat_idx_elt" in place of "struct eb_node" + - BUG/MEDIUM: map: Bad map file parser + - CLEANUP/MINOR: standard: use the system define INET6_ADDRSTRLEN in place of MAX_IP6_LEN + - BUG/MEDIUM: sample: conversion from str to ipv6 may read data past end + - MINOR: map: export map_get_reference() function + - MINOR: pattern: Each pattern sets the expected input type + - MEDIUM: acl: Last patch change the output type + - MEDIUM: pattern: Extract the index process from the pat_parse_*() functions + - MINOR: standard: The function parse_binary() can use preallocated buffer + - MINOR: regex: Change the struct containing regex + - MINOR: regex: Copy the original regex expression into string. + - MINOR: pattern: add support for compiling patterns for lookups + - MINOR: pattern: make the pattern matching function return a pointer to the matched element + - MINOR: map: export parse output sample functions + - MINOR: pattern: add function to lookup a specific entry in pattern list + - MINOR: pattern/map: Each pattern must free the associated sample + - MEDIUM: dumpstat: make the CLI parser understand the backslash as an escape char + - MEDIUM: map: dynamic manipulation of maps + - BUG/MEDIUM: unique_id: junk in log on empty unique_id + - BUG/MINOR: log: junk at the end of syslog packet + - MINOR: Makefile: provide cscope rule + - DOC: compression: chunk are not compressed anymore + - MEDIUM: session: disable lingering on the server when the client aborts + - BUG/MEDIUM: prevent gcc from moving empty keywords lists into BSS + - DOC: remove the comment saying that SSL certs are not checked on the server side + - BUG: counters: third counter was not stored if others unset + - BUG/MAJOR: http: don't emit the send-name-header when no server is available + - BUG/MEDIUM: http: "option checkcache" fails with the no-cache header + - BUG/MAJOR: http: sample prefetch code was not properly migrated + - BUG/MEDIUM: splicing: fix abnormal CPU usage with splicing + - BUG/MINOR: stream_interface: don't call chk_snd() on polled events + - OPTIM: splicing: use splice() for the last block when relevant + - MEDIUM: sample: handle comma-delimited converter list + - MINOR: sample: fix sample_process handling of unstable data + - CLEANUP: acl: move the 3 remaining sample fetches to samples.c + - MINOR: sample: add a new "date" fetch to return the current date + - MINOR: samples: add the http_date([]) sample converter. + - DOC: minor improvements to the part on the stats socket. + - MEDIUM: sample: systematically pass the keyword pointer to the keyword + - MINOR: payload: split smp_fetch_rdp_cookie() + - MINOR: counters: factor out smp_fetch_sc*_tracked + - MINOR: counters: provide a generic function to retrieve a stkctr for sc* and src. + - MEDIUM: counters: factor out smp_fetch_sc*_get_gpc0 + - MEDIUM: counters: factor out smp_fetch_sc*_gpc0_rate + - MEDIUM: counters: factor out smp_fetch_sc*_inc_gpc0 + - MEDIUM: counters: factor out smp_fetch_sc*_clr_gpc0 + - MEDIUM: counters: factor out smp_fetch_sc*_conn_cnt + - MEDIUM: counters: factor out smp_fetch_sc*_conn_rate + - MEDIUM: counters: factor out smp_fetch_sc*_conn_cur + - MEDIUM: counters: factor out smp_fetch_sc*_sess_cnt + - MEDIUM: counters: factor out smp_fetch_sc*_sess_rate + - MEDIUM: counters: factor out smp_fetch_sc*_http_req_cnt + - MEDIUM: counters: factor out smp_fetch_sc*_http_req_rate + - MEDIUM: counters: factor out smp_fetch_sc*_http_err_cnt + - MEDIUM: counters: factor out smp_fetch_sc*_http_err_rate + - MEDIUM: counters: factor out smp_fetch_sc*_kbytes_in + - MEDIUM: counters: factor out smp_fetch_sc*_bytes_in_rate + - MEDIUM: counters: factor out smp_fetch_sc*_kbytes_out + - MEDIUM: counters: factor out smp_fetch_sc*_bytes_out_rate + - MEDIUM: counters: factor out smp_fetch_sc*_trackers + - MINOR: session: make the number of stick counter entries more configurable + - MEDIUM: counters: support passing the counter number as a fetch argument + - MEDIUM: counters: support looking up a key in an alternate table + - MEDIUM: cli: adjust the method for feeding frequency counters in tables + - MINOR: cli: make it possible to enter multiple values at once with "set table" + - MINOR: payload: allow the payload sample fetches to retrieve arbitrary lengths + - BUG/MINOR: cli: "clear table" must not kill entries that don't match condition + - MINOR: ssl: use MAXPATHLEN instead of PATH_MAX + - MINOR: config: warn when a server with no specific port uses rdp-cookie + - BUG/MEDIUM: unique_id: HTTP request counter must be unique! + - DOC: add a mention about the limited chunk size + - BUG/MEDIUM: fix broken send_proxy on FreeBSD + - MEDIUM: stick-tables: flush old entries upon soft-stop + - MINOR: tcp: add new "close" action for tcp-response + - MINOR: payload: provide the "res.len" fetch method + - BUILD: add SSL_INC/SSL_LIB variables to force the path to openssl + - MINOR: http: compute response time before processing headers + - BUG/MINOR: acl: fix improper string size assignment in proxy argument + - BUG/MEDIUM: http: accept full buffers on smp_prefetch_http + - BUG/MINOR: acl: implicit arguments of ACL keywords were not properly resolved + - BUG/MEDIUM: session: risk of crash on out of memory conditions + - BUG/MINOR: peers: set the accept date in outgoing connections + - BUG/MEDIUM: tcp: do not skip tracking rules on second pass + - BUG/MEDIUM: acl: do not evaluate next terms after a miss + - MINOR: acl: add a warning when an ACL keyword is used without any value + - MINOR: tcp: don't use tick_add_ifset() when timeout is known to be set + - BUG/MINOR: acl: remove patterns from the tree before freeing them + - MEDIUM: backend: add support for the wt6 hash + - OPTIM/MEDIUM: epoll: fuse active events into polled ones during polling changes + - OPTIM/MINOR: mark the source address as already known on accept() + - BUG/MINOR: stats: don't count tarpitted connections twice + - CLEANUP: http: homogenize processing of denied req counter + - CLEANUP: http: merge error handling for req* and http-request * + - BUG/MEDIUM: http: fix possible parser crash when parsing erroneous "http-request redirect" rules + - BUG/MINOR: http: fix build warning introduced with url32/url32_src + - BUG/MEDIUM: checks: fix slow start regression after fix attempt + - BUG/MAJOR: server: weight calculation fails for map-based algorithms + - MINOR: stats: report correct throttling percentage for servers in slowstart + - OPTIM: connection: fold the error handling with handshake handling + - MINOR: peers: accept to learn strings of different lengths + - BUG/MAJOR: fix haproxy crash when using server tracking instead of checks + - BUG/MAJOR: check: fix haproxy crash during soft-stop/soft-start + - BUG/MINOR: stats: do not report "via" on tracking servers in maintenance + - BUG/MINOR: connection: fix typo in error message report + - BUG/MINOR: backend: fix target address retrieval in transparent mode + - BUG/MINOR: config: report the correct track-sc number in tcp-rules + - BUG/MINOR: log: fix log-format parsing errors + - DOC: add some information about how to apply converters to samples + - MINOR: acl/pattern: use types different from int to clarify who does what. + - MINOR: pattern: import acl_find_match_name() into pattern.h + - MEDIUM: stick-tables: support automatic conversion from ipv4<->ipv6 + - MEDIUM: log-format: relax parsing of '%' followed by unsupported characters + - BUG/MINOR: http: usual deinit stuff in last commit + - BUILD: log: silent a warning about isblank() with latest patches + - BUG/MEDIUM: checks: fix health check regression causing them to depend on declaration order + - BUG/MEDIUM: checks: fix a long-standing issue with reporting connection errors + - BUG/MINOR: checks: don't consider errno and use conn->err_code + - BUG/MEDIUM: checks: also update the DRAIN state from the web interface + - MINOR: stats: remove some confusion between the DRAIN state and NOLB + - BUG/MINOR: tcp: check that no error is pending during a connect probe + - BUG/MINOR: connection: check EINTR when sending a PROXY header + - MEDIUM: connection: set the socket shutdown flags on socket errors + - BUG/MEDIUM: acl: fix regression introduced by latest converters support + - MINOR: connection: clear errno prior to checking for errors + - BUG/MINOR: checks: do not trust errno in write event before any syscall + - MEDIUM: checks: centralize error reporting + - OPTIM: checks: don't poll on recv when using plain TCP connects + - OPTIM: checks: avoid setting SO_LINGER twice + - MINOR: tools: add a generic binary hex string parser + - BUG/MEDIUM: checks: tcp-check: do not poll when there's nothing to send + - BUG/MEDIUM: check: tcp-check might miss some outgoing data when socket buffers are full + - BUG/MEDIUM: args: fix double free on error path in argument expression parser + - BUG/MINOR: acl: fix sample expression error reporting + - BUG/MINOR: checks: tcp-check actions are enums, not flags + - MEDIUM: checks: make tcp-check perform multiple send() at once + - BUG/MEDIUM: stick: completely remove the unused flag from the store entries + - OPTIM: ebtree: pack the struct eb_node to avoid holes on 64-bit + - BUG/MEDIUM: stick-tables: complete the latest fix about store-responses + - CLEANUP: stream_interface: remove unused field err_loc + - MEDIUM: stats: don't use conn->xprt_st anymore + - MINOR: session: add a simple function to retrieve a session from a task + - MEDIUM: stats: don't use conn->xprt_ctx anymore + - MEDIUM: peers: don't rely on conn->xprt_ctx anymore + - MINOR: http: prevent smp_fetch_url_{ip,port} from using si->conn + - MINOR: connection: make it easier to emit proxy protocol for unknown addresses + - MEDIUM: stats: prepare the HTTP stats I/O handler to support more states + - MAJOR: stats: move the HTTP stats handling to its applet + - MEDIUM: stats: move request argument processing to the final step + - MEDIUM: session: detect applets from the session by using s->target + - MAJOR: session: check for a connection to an applet in sess_prepare_conn_req() + - MAJOR: session: pass applet return traffic through the response analysers + - MEDIUM: stream-int: split the shutr/shutw functions between applet and conn + - MINOR: stream-int: make the shutr/shutw functions void + - MINOR: obj: provide a safe and an unsafe access to pointed objects + - MINOR: connection: add a field to store an object type + - MINOR: connection: always initialize conn->objt_type to OBJ_TYPE_CONN + - MEDIUM: stream interface: move the peers' ptr into the applet context + - MINOR: stream-interface: move the applet context to its own struct + - MINOR: obj: introduce a new type appctx + - MINOR: stream-int: rename ->applet to ->appctx + - MINOR: stream-int: split si_prepare_embedded into si_prepare_none and si_prepare_applet + - MINOR: stream-int: add a new pointer to the end point + - MEDIUM: stream-interface: set the pointer to the applet into the applet context + - MAJOR: stream interface: remove the ->release function pointer + - MEDIUM: stream-int: make ->end point to the connection or the appctx + - CLEANUP: stream-int: remove obsolete si_ctrl function + - MAJOR: stream-int: stop using si->conn and use si->end instead + - MEDIUM: stream-int: do not allocate a connection in parallel to applets + - MEDIUM: session: attach incoming connection to target on embryonic sessions + - MINOR: connection: add conn_init() to (re)initialize a connection + - MINOR: checks: call conn_init() to properly initialize the connection. + - MINOR: peers: make use of conn_init() to initialize the connection + - MINOR: session: use conn_init() to initialize the connections + - MINOR: http: use conn_init() to reinitialize the server connection + - MEDIUM: connection: replace conn_prepare with conn_assign + - MINOR: get rid of si_takeover_conn() + - MINOR: connection: add conn_new() / conn_free() + - MAJOR: connection: add two new flags to indicate readiness of control/transport + - MINOR: stream-interface: introduce si_reset() and si_set_state() + - MINOR: connection: reintroduce conn_prepare to set the protocol and transport + - MINOR: connection: replace conn_assign with conn_attach + - MEDIUM: stream-interface: introduce si_attach_conn to replace si_prepare_conn + - MAJOR: stream interface: dynamically allocate the outgoing connection + - MEDIUM: connection: move the send_proxy offset to the connection + - MINOR: connection: check for send_proxy during the connect(), not the SI + - MEDIUM: connection: merge the send_proxy and local_send_proxy calls + - MEDIUM: stream-int: replace occurrences of si->appctx with si_appctx() + - MEDIUM: stream-int: return the allocated appctx in stream_int_register_handler() + - MAJOR: stream-interface: dynamically allocate the applet context + - MEDIUM: session: automatically register the applet designated by the target + - MEDIUM: stats: delay appctx initialization + - CLEANUP: peers: use less confusing state/status code names + - MEDIUM: peers: delay appctx initialization + - MINOR: stats: provide some appctx information in "show sess all" + - DIET/MINOR: obj: pack the obj_type enum to 8 bits + - DIET/MINOR: connection: rearrange a few fields to save 8 bytes in the struct + - DIET/MINOR: listener: rearrange a few fields in struct listener to save 16 bytes + - DIET/MINOR: proxy: rearrange a few fields in struct proxy to save 16 bytes + - DIET/MINOR: session: reduce the struct session size by 8 bytes + - DIET/MINOR: stream-int: rearrange a few fields in struct stream_interface to save 8 bytes + - DIET/MINOR: http: reduce the size of struct http_txn by 8 bytes + - MINOR: http: switch the http state to an enum + - MINOR: http: use an enum for the auth method in http_auth_data + - DIET/MINOR: task: reduce struct task size by 8 bytes + - MINOR: stream_interface: add reporting of ressouce allocation errors + - MINOR: session: report lack of resources using the new stream-interface's error code + - BUILD: simplify the date and version retrieval in the makefile + - BUILD: prepare the makefile to skip format lines in SUBVERS and VERDATE + - BUILD: use format tags in VERDATE and SUBVERS files + - BUG/MEDIUM: channel: bo_getline() must wait for \n until buffer is full + - CLEANUP: check: server port is unsigned + - BUG/MEDIUM: checks: agent doesn't get the response if server does not closes + - MINOR: tools: buf2ip6 must not modify output on failure + - MINOR: pattern: do not assign SMP_TYPES by default to patterns + - MINOR: sample: make sample_parse_expr() use memprintf() to report parse errors + - MINOR: arg: improve wording on error reporting + - BUG/MEDIUM: sample: simplify and fix the argument parsing + - MEDIUM: acl: fix the argument parser to let the lower layer report detailed errors + - MEDIUM: acl: fix the initialization order of the ACL expression + - CLEANUP: acl: remove useless blind copy-paste from sample converters + - TESTS: add regression tests for ACL and sample expression parsers + - BUILD: time: adapt the type of TV_ETERNITY to the local system + - MINOR: chunks: allocate the trash chunks before parsing the config + - BUILD: definitely silence some stupid GCC warnings + - MINOR: chunks: always initialize the output chunk in get_trash_chunk() + - MINOR: checks: improve handling of the servers tracking chain + - REORG: checks: retrieve the check-specific defines from server.h to checks.h + - MINOR: checks: use an enum instead of flags to report a check result + - MINOR: checks: rename the state flags + - MINOR: checks: replace state DISABLED with CONFIGURED and ENABLED + - MINOR: checks: use check->state instead of srv->state & SRV_CHECKED + - MINOR: checks: fix agent check interval computation + - MINOR: checks: add a PAUSED state for the checks + - MINOR: checks: create the agent tasks even when no check is configured + - MINOR: checks: add a flag to indicate what check is an agent + - MEDIUM: checks: enable agent checks even if health checks are disabled + - BUG/MEDIUM: checks: ensure we can enable a server after boot + - BUG/MEDIUM: checks: tracking servers must not inherit the MAINT flag + - BUG/MAJOR: session: repair tcp-request connection rules + - BUILD: fix SUBVERS extraction in the Makefile + - BUILD: pattern: silence a warning about uninitialized value + - BUILD: log: fix build warning on Solaris + - BUILD: dumpstats: fix build error on Solaris + - DOC: move option pgsql-check to the correct place + - DOC: move option tcp-check to the proper place + - MINOR: connection: add simple functions to report connection readiness + - MEDIUM: connection: centralize handling of nolinger in fd management + - OPTIM: http: set CF_READ_DONTWAIT on response message + - OPTIM: http: do not re-enable reading on client side while closing the server side + - MINOR: config: add option http-keep-alive + - MEDIUM: connection: inform si_alloc_conn() whether existing conn is OK or not + - MAJOR: stream-int: handle the connection reuse in si_connect() + - MAJOR: http: add the keep-alive transition on the server side + - MAJOR: backend: enable connection reuse + - MINOR: http: add option prefer-last-server + - MEDIUM: http: do not report connection errors for second and further requests + +2013/06/17 : 1.5-dev19 + - MINOR: stats: remove the autofocus on the scope input field + - BUG/MEDIUM: Fix crt-list file parsing error: filtered name was ignored. + - BUG/MEDIUM: ssl: EDH ciphers are not usable if no DH parameters present in pem file. + - BUG/MEDIUM: shctx: makes the code independent on SSL runtime version. + - MEDIUM: ssl: improve crt-list format to support negation + - BUG: ssl: fix crt-list for clients not supporting SNI + - MINOR: stats: show soft-stopped servers in different color + - BUG/MINOR: config: "source" does not work in defaults section + - BUG: regex: fix pcre compile error when using JIT + - MINOR: ssl: add pattern fetch 'ssl_c_sha1' + - BUG: ssl: send payload gets corrupted if tune.ssl.maxrecord is used + - MINOR: show PCRE version and JIT status in -vv + - BUG/MINOR: jit: don't rely on USE flag to detect support + - DOC: readme: add suggestion to link against static openssl + - DOC: examples: provide simplified ssl configuration + - REORG: tproxy: prepare the transparent proxy defines for accepting other OSes + - MINOR: tproxy: add support for FreeBSD + - MINOR: tproxy: add support for OpenBSD + - DOC: examples: provide an example of transparent proxy configuration for FreeBSD 8 + - CLEANUP: fix minor typo in error message. + - CLEANUP: fix missing include in proto/listener.h + - CLEANUP: protect checks.h from multiple inclusions + - MINOR: compression: acl "res.comp" and fetch "res.comp_algo" + - BUG/MINOR: http: add-header/set-header did not accept the ACL condition + - BUILD: mention in the Makefile that USE_PCRE_JIT is for libpcre >= 8.32 + - BUG/MEDIUM: splicing is broken since 1.5-dev12 + - BUG/MAJOR: acl: add implicit arguments to the resolve list + - BUG/MINOR: tcp: fix error reporting for TCP rules + - CLEANUP: peers: remove a bit of spaghetti to prepare for the next bugfix + - MINOR: stick-table: allow to allocate an entry without filling it + - BUG/MAJOR: peers: fix an overflow when syncing strings larger than 16 bytes + - MINOR: session: only call http_send_name_header() when changing the server + - MINOR: tcp: report the erroneous word in tcp-request track* + - BUG/MAJOR: backend: consistent hash can loop forever in certain circumstances + - BUG/MEDIUM: log: fix regression on log-format handling + - MEDIUM: log: report file name, line number, and directive name with log-format errors + - BUG/MINOR: cli: "clear table" did not work anymore without a key + - BUG/MINOR: cli: "clear table xx data.xx" does not work anymore + - BUG/MAJOR: http: compression still has defects on chunked responses + - BUG/MINOR: stats: fix confirmation links on the stats interface + - BUG/MINOR: stats: the status bar does not appear anymore after a change + - BUG/MEDIUM: stats: allocate the stats frontend also on "stats bind-process" + - BUG/MEDIUM: stats: fix a regression when dealing with POST requests + - BUG/MINOR: fix unterminated ACL array in compression + - BUILD: last fix broke non-linux platforms + - MINOR: init: indicate the SSL runtime version on -vv. + - BUG/MEDIUM: compression: the deflate algorithm must use global settings as well + - BUILD: stdbool is not portable (again) + - DOC: readme: add a small reminder about restrictions to respect in the code + - MINOR: ebtree: add new eb_next_dup/eb_prev_dup() functions to visit duplicates + - BUG/MINOR: acl: fix a double free during exit when using PCRE_JIT + - DOC: fix wrong copy-paste in the rspdel example + - MINOR: counters: make it easier to extend the amount of tracked counters + - MEDIUM: counters: add support for tracking a third counter + - MEDIUM: counters: add a new "gpc0_rate" counter in stick-tables + - BUG/MAJOR: http: always ensure response buffer has some room for a response + - MINOR: counters: add fetch/acl sc*_tracked to indicate whether a counter is tracked + - MINOR: defaults: allow REQURI_LEN and CAPTURE_LEN to be redefined + - MINOR: log: add a new flag 'L' for locally processed requests + - MINOR: http: add full-length header fetch methods + - MEDIUM: protocol: implement a "drain" function in protocol layers + - MEDIUM: http: add a new "http-response" ruleset + - MEDIUM: http: add the "set-nice" action to http-request and http-response + - MEDIUM: log: add a log level override value in struct session + - MEDIUM: http: add support for action "set-log-level" in http-request/http-response + - MEDIUM: http: add support for "set-tos" in http-request/http-response + - MEDIUM: http: add the "set-mark" action on http-request/http-response rules + - MEDIUM: tcp: add "tcp-request connection expect-proxy layer4" + - MEDIUM: acl: automatically detect the type of certain fetches + - MEDIUM: acl: remove a lot of useless ACLs that are equivalent to their fetches + - MEDIUM: acl: remove 15 additional useless ACLs that are equivalent to their fetches + - DOC: major reorg of ACL + sample fetch + - CLEANUP: http: remove the bogus urlp_ip ACL match + - MINOR: acl: add the new "env()" fetch method to retrieve an environment variable + - BUG/MINOR: acl: correctly consider boolean fetches when doing casts + - BUG/CRITICAL: fix a possible crash when using negative header occurrences + - DOC: update ROADMAP file + - MEDIUM: counters: use sc0/sc1/sc2 instead of sc1/sc2/sc3 + - MEDIUM: stats: add proxy name filtering on the statistic page + +2013/04/03 : 1.5-dev18 + - DOCS: Add explanation of intermediate certs to crt paramater + - DOC: typo and minor fixes in compression paragraph + - MINOR: config: http-request configuration error message misses new keywords + - DOC: minor typo fix in documentation + - BUG/MEDIUM: ssl: ECDHE ciphers not usable without named curve configured. + - MEDIUM: ssl: add bind-option "strict-sni" + - MEDIUM: ssl: add mapping from SNI to cert file using "crt-list" + - MEDIUM: regex: Use PCRE JIT in acl + - DOC: simplify bind option "interface" explanation + - DOC: tfo: bump required kernel to linux-3.7 + - BUILD: add explicit support for TFO with USE_TFO + - MEDIUM: New cli option -Ds for systemd compatibility + - MEDIUM: add haproxy-systemd-wrapper + - MEDIUM: add systemd service + - BUG/MEDIUM: systemd-wrapper: don't leak zombie processes + - BUG/MEDIUM: remove supplementary groups when changing gid + - BUG/MEDIUM: config: fix parser crash with bad bind or server address + - BUG/MINOR: Correct logic in cut_crlf() + - CLEANUP: checks: Make desc argument to set_server_check_status const + - CLEANUP: dumpstats: Make cli_release_handler() static + - MEDIUM: server: Break out set weight processing code + - MEDIUM: server: Allow relative weights greater than 100% + - MEDIUM: server: Tighten up parsing of weight string + - MEDIUM: checks: Add agent health check + - BUG/MEDIUM: ssl: openssl 0.9.8 doesn't open /dev/random before chroot + - BUG/MINOR: time: frequency counters are not totally accurate + - BUG/MINOR: http: don't process abortonclose when request was sent + - BUG/MEDIUM: stream_interface: don't close outgoing connections on shutw() + - BUG/MEDIUM: checks: ignore late resets after valid responses + - DOC: fix bogus recommendation on usage of gpc0 counter + - BUG/MINOR: http-compression: lookup Cache-Control in the response, not the request + - MINOR: signal: don't block SIGPROF by default + - OPTIM: epoll: make use of EPOLLRDHUP + - OPTIM: splice: detect shutdowns and avoid splice() == 0 + - OPTIM: splice: assume by default that splice is working correctly + - BUG/MINOR: log: temporary fix for lost SSL info in some situations + - BUG/MEDIUM: peers: only the last peers section was used by tables + - BUG/MEDIUM: config: verbosely reject peers sections with multiple local peers + - BUG/MINOR: epoll: use a fix maxevents argument in epoll_wait() + - BUG/MINOR: config: fix improper check for failed memory alloc in ACL parser + - BUG/MINOR: config: free peer's address when exiting upon parsing error + - BUG/MINOR: config: check the proper variable when parsing log minlvl + - BUG/MEDIUM: checks: ensure the health_status is always within bounds + - BUG/MINOR: cli: show sess should always validate s->listener + - BUG/MINOR: log: improper NULL return check on utoa_pad() + - CLEANUP: http: remove a useless null check + - CLEANUP: tcp/unix: remove useless NULL check in {tcp,unix}_bind_listener() + - BUG/MEDIUM: signal: signal handler does not properly check for signal bounds + - BUG/MEDIUM: tools: off-by-one in quote_arg() + - BUG/MEDIUM: uri_auth: missing NULL check and memory leak on memory shortage + - BUG/MINOR: unix: remove the 'level' field from the ux struct + - CLEANUP: http: don't try to deinitialize http compression if it fails before init + - CLEANUP: config: slowstart is never negative + - CLEANUP: config: maxcompcpuusage is never negative + - BUG/MEDIUM: log: emit '-' for empty fields again + - BUG/MEDIUM: checks: fix a race condition between checks and observe layer7 + - BUILD: fix a warning emitted by isblank() on non-c99 compilers + - BUILD: improve the makefile's support for libpcre + - MEDIUM: halog: add support for counting per source address (-ic) + - MEDIUM: tools: make str2sa_range support all address syntaxes + - MEDIUM: config: make use of str2sa_range() instead of str2sa() + - MEDIUM: config: use str2sa_range() to parse server addresses + - MEDIUM: config: use str2sa_range() to parse peers addresses + - MINOR: tests: add a config file to ease address parsing tests. + - MINOR: ssl: add a global tunable for the max SSL/TLS record size + - BUG/MINOR: syscall: fix NR_accept4 system call on sparc/linux + - BUILD/MINOR: syscall: add definition of NR_accept4 for ARM + - MINOR: config: report missing peers section name + - BUG/MEDIUM: tools: fix bad character handling in str2sa_range() + - BUG/MEDIUM: stats: never apply "unix-bind prefix" to the global stats socket + - MINOR: tools: prepare str2sa_range() to return an error message + - BUG/MEDIUM: checks: don't call connect() on unsupported address families + - MINOR: tools: prepare str2sa_range() to accept a prefix + - MEDIUM: tools: make str2sa_range() parse unix addresses too + - MEDIUM: config: make str2listener() use str2sa_range() to parse unix addresses + - MEDIUM: config: use a single str2sa_range() call to parse bind addresses + - MEDIUM: config: use str2sa_range() to parse log addresses + - CLEANUP: tools: remove str2sun() which is not used anymore. + - MEDIUM: config: add complete support for str2sa_range() in dispatch + - MEDIUM: config: add complete support for str2sa_range() in server addr + - MEDIUM: config: add complete support for str2sa_range() in 'server' + - MEDIUM: config: add complete support for str2sa_range() in 'peer' + - MEDIUM: config: add complete support for str2sa_range() in 'source' and 'usesrc' + - CLEANUP: minor cleanup in str2sa_range() and str2ip() + - CLEANUP: config: do not use multiple errmsg at once + - MEDIUM: tools: support specifying explicit address families in str2sa_range() + - MAJOR: listener: support inheriting a listening fd from the parent + - MAJOR: tools: support environment variables in addresses + - BUG/MEDIUM: http: add-header should not emit "-" for empty fields + - BUG/MEDIUM: config: ACL compatibility check on "redirect" was wrong + - BUG/MEDIUM: http: fix another issue caused by http-send-name-header + - DOC: mention the new HTTP 307 and 308 redirect statues + - MEDIUM: poll: do not use FD_* macros anymore + - BUG/MAJOR: ev_select: disable the select() poller if maxsock > FD_SETSIZE + - BUG/MINOR: acl: ssl_fc_{alg,use}_keysize must parse integers, not strings + - BUG/MINOR: acl: ssl_c_used, ssl_fc{,_has_crt,_has_sni} take no pattern + - BUILD: fix usual isdigit() warning on solaris + - BUG/MEDIUM: tools: vsnprintf() is not always reliable on Solaris + - OPTIM: buffer: remove one jump in buffer_count() + - OPTIM: http: improve branching in chunk size parser + - OPTIM: http: optimize the response forward state machine + - BUILD: enable poll() by default in the makefile + - BUILD: add explicit support for Mac OS/X + - BUG/MAJOR: http: use a static storage for sample fetch context + - BUG/MEDIUM: ssl: improve error processing and reporting in ssl_sock_load_cert_list_file() + - BUG/MAJOR: http: fix regression introduced by commit a890d072 + - BUG/MAJOR: http: fix regression introduced by commit d655ffe + - BUG/CRITICAL: using HTTP information in tcp-request content may crash the process + - MEDIUM: acl: remove flag ACL_MAY_LOOKUP which is improperly used + - MEDIUM: samples: use new flags to describe compatibility between fetches and their usages + - MINOR: log: indicate it when some unreliable sample fetches are logged + - MEDIUM: samples: move payload-based fetches and ACLs to their own file + - MINOR: backend: rename sample fetch functions and declare the sample keywords + - MINOR: frontend: rename sample fetch functions and declare the sample keywords + - MINOR: listener: rename sample fetch functions and declare the sample keywords + - MEDIUM: http: unify acl and sample fetch functions + - MINOR: session: rename sample fetch functions and declare the sample keywords + - MAJOR: acl: make all ACLs reference the fetch function via a sample. + - MAJOR: acl: remove the arg_mask from the ACL definition and use the sample fetch's + - MAJOR: acl: remove fetch argument validation from the ACL struct + - MINOR: http: add new direction-explicit sample fetches for headers and cookies + - MINOR: payload: add new direction-explicit sample fetches + - CLEANUP: acl: remove ACL hooks which were never used + - MEDIUM: proxy: remove acl_requires and just keep a flag "http_needed" + - MINOR: sample: provide a function to report the name of a sample check point + - MAJOR: acl: convert all ACL requires to SMP use+val instead of ->requires + - CLEANUP: acl: remove unused references to ACL_USE_* + - MINOR: http: replace acl_parse_ver with acl_parse_str + - MEDIUM: acl: move the ->parse, ->match and ->smp fields to acl_expr + - MAJOR: acl: add option -m to change the pattern matching method + - MINOR: acl: remove the use_count in acl keywords + - MEDIUM: acl: have a pointer to the keyword name in acl_expr + - MEDIUM: acl: support using sample fetches directly in ACLs + - MEDIUM: http: remove val_usr() to validate user_lists + - MAJOR: sample: maintain a per-proxy list of the fetch args to resolve + - MINOR: ssl: add support for the "alpn" bind keyword + - MINOR: http: status code 303 is HTTP/1.1 only + - MEDIUM: http: implement redirect 307 and 308 + - MINOR: http: status 301 should not be marked non-cacheable + +2012/12/28 : 1.5-dev17 + - MINOR: ssl: Setting global tune.ssl.cachesize value to 0 disables SSL session cache. + - BUG/MEDIUM: stats: fix stats page regression introduced by commit 20b0de5 + - BUG/MINOR: stats: last fix was still wrong + - BUG/MINOR: stats: http-request rules still don't cope with stats + - BUG/MINOR: http: http-request add-header emits a corrupted header + - BUG/MEDIUM: stats: disable request analyser when processing POST or HEAD + - BUG/MINOR: log: make log-format, unique-id-format and add-header more independant + - BUILD: log: unused variable svid + - CLEANUP: http: rename the misleading http_check_access_rule + - MINOR: http: move redirect rule processing to its own function + - REORG: config: move the http redirect rule parser to proto_http.c + - MEDIUM: http: add support for "http-request redirect" rules + - MEDIUM: http: add support for "http-request tarpit" rule + +2012/12/24 : 1.5-dev16 + - BUG/MEDIUM: ssl: Prevent ssl error from affecting other connections. + - BUG/MINOR: ssl: error is not reported if it occurs simultaneously with peer close detection. + - MINOR: ssl: add fetch and acl "ssl_c_used" to check if current SSL session uses a client certificate. + - MINOR: contrib: make the iprange tool grep for addresses + - CLEANUP: polling: gcc doesn't always optimize constants away + - OPTIM: poll: optimize fd management functions for low register count CPUs + - CLEANUP: poll: remove a useless double-check on fdtab[fd].owner + - OPTIM: epoll: use a temp variable for intermediary flag computations + - OPTIM: epoll: current fd does not count as a new one + - BUG/MINOR: poll: the I/O handler was called twice for polled I/Os + - MINOR: http: make resp_ver and status ACLs check for the presence of a response + - BUG/MEDIUM: stream-interface: fix possible stalls during transfers + - BUG/MINOR: stream_interface: don't return when the fd is already set + - BUG/MEDIUM: connection: always update connection flags prior to computing polling + - CLEANUP: buffer: use buffer_empty() instead of buffer_len()==0 + - BUG/MAJOR: stream_interface: fix occasional data transfer freezes + - BUG/MEDIUM: stream_interface: fix another case where the reader might not be woken up + - BUG/MINOR: http: don't abort client connection on premature responses + - BUILD: no need to clean up when making git-tar + - MINOR: log: add a tag for amount of bytes uploaded from client to server + - BUG/MEDIUM: log: fix possible segfault during config parsing + - MEDIUM: log: change a few log tokens to make them easier to remember + - BUG/MINOR: log: add_to_logformat_list() used the wrong constants + - MEDIUM: log-format: make the format parser more robust and more extensible + - MINOR: sample: support cast from bool to string + - MINOR: samples: add a function to fetch and convert any sample to a string + - MINOR: log: add lf_text_len + - MEDIUM: log: add the ability to include samples in logs + - REORG: stats: massive code reorg and cleanup + - REORG: stats: move the HTTP header injection to proto_http + - REORG: stats: functions are now HTTP/CLI agnostic + - BUG/MINOR: log: fix regression introduced by commit 8a3f52 + - MINOR: chunks: centralize the trash chunk allocation + - MEDIUM: stats: use hover boxes instead of title to report details + - MEDIUM: stats: use multi-line tips to display detailed counters + - MINOR: tools: simplify the use of the int to ascii macros + - MINOR: stats: replace STAT_FMT_CSV with STAT_FMT_HTML + - MINOR: http: prepare to support more http-request actions + - MINOR: log: make parse_logformat_string() take a const char * + - MEDIUM: http: add http-request 'add-header' and 'set-header' to build headers + +2012/12/12 : 1.5-dev15 + - DOC: add a few precisions on compression + - BUG/MEDIUM: ssl: Fix handshake failure on session resumption with client cert. + - BUG/MINOR: ssl: One free session in cache remains unused. + - BUG/MEDIUM: ssl: first outgoing connection would fail with {ca,crt}-ignore-err + - MEDIUM: ssl: manage shared cache by blocks for huge sessions. + - MINOR: acl: add fetch for server session rate + - BUG/MINOR: compression: Content-Type is case insensitive + - MINOR: compression: disable on multipart or status != 200 + - BUG/MINOR: http: don't report client aborts as server errors + - MINOR: stats: compute the ratio of compressed response based on 2xx responses + - MINOR: http: factor out the content-type checks + - BUG/MAJOR: stats: correctly check for a possible divide error when showing compression ratios + - BUILD: ssl: OpenSSL 0.9.6 has no renegociation + - BUG/MINOR: http: disable compression when message has no body + - MINOR: compression: make the stats a bit more robust + - BUG/MEDIUM: comp: DEFAULT_MAXZLIBMEM was expressed in bytes and not megabytes + - MINOR: connection: don't remove failed handshake flags + - MEDIUM: connection: add an error code in connections + - MEDIUM: connection: add minimal error reporting in logs for incomplete connections + - MEDIUM: connection: add error reporting for the PROXY protocol header + - MEDIUM: connection: add error reporting for the SSL + - DOC: document the connection error format in logs + - BUG/MINOR: http: don't log a 503 on client errors while waiting for requests + - BUILD: stdbool is not portable + - BUILD: ssl: NAME_MAX is not portable, use MAXPATHLEN instead + - BUG/MAJOR: raw_sock: must check error code on hangup + - BUG/MAJOR: polling: do not set speculative events on ERR nor HUP + - BUG/MEDIUM: session: fix FD leak when transport layer logging is enabled + - MINOR: stats: add a few more information on session dump + - BUG/MINOR: tcp: set the ADDR_TO_SET flag on outgoing connections + - CLEANUP: connection: remove unused server/proxy/task/si_applet declarations + - BUG/MEDIUM: tcp: process could theorically crash on lack of source ports + - MINOR: cfgparse: mention "interface" in the list of allowed "source" options + - MEDIUM: connection: introduce "struct conn_src" for servers and proxies + - CLEANUP: proto_tcp: use the same code to bind servers and backends + - CLEANUP: backend: use the same tproxy address selection code for servers and backends + - BUG/MEDIUM: stick-tables: conversions to strings were broken in dev13 + - MEDIUM: proto_tcp: add support for tracking L7 information + - MEDIUM: counters: add sc1_trackers/sc2_trackers + - MINOR: http: add the "base32" pattern fetch function + - MINOR: http: add the "base32+src" fetch method. + - CLEANUP: session: use an array for the stick counters + - BUG/MINOR: proto_tcp: fix parsing of "table" in track-sc1/2 + - BUG/MINOR: proto_tcp: bidirectional fetches not supported anymore in track-sc1/2 + - BUG/MAJOR: connection: always recompute polling status upon I/O + - BUG/MINOR: connection: remove a few synchronous calls to polling updates + - MINOR: config: improve error checking on TCP stick-table tracking + - DOC: add some clarifications to the readme + +2012/11/26 : 1.5-dev14 + - DOC: fix minor typos + - BUG/MEDIUM: compression: does not forward trailers + - MINOR: buffer_dump with ASCII + - BUG/MEDIUM: checks: mark the check as stopped after a connect error + - BUG/MEDIUM: checks: ensure we completely disable polling upon success + - BUG/MINOR: checks: don't mark the FD as closed before transport close + - MEDIUM: checks: avoid accumulating TIME_WAITs during checks + - MINOR: cli: report the msg state in full text in "show sess $PTR" + - CLEANUP: checks: rename some server check flags + - MAJOR: checks: rework completely bogus state machine + - BUG/MINOR: checks: slightly clean the state machine up + - MEDIUM: checks: avoid waking the application up for pure TCP checks + - MEDIUM: checks: close the socket as soon as we have a response + - BUG/MAJOR: checks: close FD on all timeouts + - MINOR: checks: fix recv polling after connect() + - MEDIUM: connection: provide a common conn_full_close() function + - BUG/MEDIUM: checks: prevent TIME_WAITs from appearing also on timeouts + - BUG/MAJOR: peers: the listener's maxaccept was not set and caused loops + - MINOR: listeners: make the accept loop more robust when maxaccept==0 + - BUG/MEDIUM: acl: correctly resolve all args, not just the first one + - BUG/MEDIUM: acl: make prue_acl_expr() correctly free ACL expressions upon exit + - BUG/MINOR: stats: fix inversion of the report of a check in progress + - MEDIUM: tcp: add explicit support for delayed ACK in connect() + - BUG/MEDIUM: connection: always disable polling upon error + - MINOR: connection: abort earlier when errors are detected + - BUG/MEDIUM: checks: report handshake failures + - BUG/MEDIUM: connection: local_send_proxy must wait for connection to establish + - MINOR: tcp: add support for the "v6only" bind option + - MINOR: stats: also report the computed compression savings in html stats + - MINOR: stats: report the total number of compressed responses per front/back + - MINOR: tcp: add support for the "v4v6" bind option + - DOC: stats: document the comp_rsp stats column + - BUILD: buffer: fix another isprint() warning on solaris + - MINOR: cli: add support for the "show sess all" command + - BUG/MAJOR: cli: show sess may randomly corrupt the back-ref list + - MINOR: cli: improve output format for show sess $ptr + +2012/11/22 : 1.5-dev13 + - BUILD: fix build issue without USE_OPENSSL + - BUILD: fix compilation error with DEBUG_FULL + - DOC: ssl: remove prefer-server-ciphers documentation + - DOC: ssl: surround keywords with quotes + - DOC: fix minor typo on http-send-name-header + - BUG/MEDIUM: acls using IPv6 subnets patterns incorrectly match IPs + - BUG/MAJOR: fix a segfault on option http_proxy and url_ip acl + - MEDIUM: http: accept IPv6 values with (s)hdr_ip acl + - BUILD: report zlib support in haproxy -vv + - DOC: compression: add some details and clean up the formatting + - DOC: Change is_ssl acl to ssl_fc acl in example + - DOC: make it clear what the HTTP request size is + - MINOR: ssl: try to load Diffie-Hellman parameters from cert file + - DOC: ssl: update 'crt' statement on 'bind' about Diffie-Hellman parameters loading + - MINOR: ssl: add elliptic curve Diffie-Hellman support for ssl key generation + - DOC: ssl: add 'ecdhe' statement on 'bind' + - MEDIUM: ssl: add client certificate authentication support + - DOC: ssl: add 'verify', 'cafile' and 'crlfile' statements on 'bind' + - MINOR: ssl: add fetch and ACL 'client_crt' to test a client cert is present + - DOC: ssl: add fetch and ACL 'client_cert' + - MINOR: ssl: add ignore verify errors options + - DOC: ssl: add 'ca-ignore-err' and 'crt-ignore-err' statements on 'bind' + - MINOR: ssl: add fetch and ACL 'ssl_verify_result' + - DOC: ssl: add fetch and ACL 'ssl_verify_result' + - MINOR: ssl: add fetches and ACLs to return verify errors + - DOC: ssl: add fetches and ACLs 'ssl_verify_crterr', 'ssl_verify_caerr', and 'ssl_verify_crterr_depth' + - MINOR: ssl: disable shared memory and locks on session cache if nbproc == 1 + - MINOR: ssl: add build param USE_PRIVATE_CACHE to build cache without shared memory + - MINOR: ssl : add statements 'notlsv11' and 'notlsv12' and rename 'notlsv1' to 'notlsv10'. + - DOC: ssl : add statements 'notlsv11' and 'notlsv12' and rename 'notlsv1' to 'notlsv10'. + - MEDIUM: config: authorize frontend and listen without bind. + - MINOR: ssl: add statement 'no-tls-tickets' on bind to disable stateless session resumption + - DOC: ssl: add 'no-tls-tickets' statement documentation. + - BUG/MINOR: ssl: Fix CRL check was not enabled when crlfile was specified. + - BUG/MINOR: build: Fix compilation issue on openssl 0.9.6 due to missing CRL feature. + - BUG/MINOR: conf: Fix 'maxsslconn' statement error if built without OPENSSL. + - BUG/MINOR: build: Fix failure with USE_OPENSSL=1 and USE_FUTEX=1 on archs i486 and i686. + - MINOR: ssl: remove prefer-server-ciphers statement and set it as the default on ssl listeners. + - BUG/MEDIUM: ssl: subsequent handshakes fail after server configuration changes + - MINOR: ssl: add 'crt-base' and 'ca-base' global statements. + - MEDIUM: conf: rename 'nosslv3' and 'notlsvXX' statements 'no-sslv3' and 'no-tlsvXX'. + - MEDIUM: conf: rename 'cafile' and 'crlfile' statements 'ca-file' and 'crl-file' + - MINOR: ssl: use bit fields to store ssl options instead of one int each + - MINOR: ssl: add 'force-sslv3' and 'force-tlsvXX' statements on bind. + - MINOR: ssl: add 'force-sslv3' and 'force-tlsvXX' statements on server + - MINOR: ssl: add defines LISTEN_DEFAULT_CIPHERS and CONNECT_DEFAULT_CIPHERS. + - BUG/MINOR: ssl: Fix issue on server statements 'no-tls*' and 'no-sslv3' + - MINOR: ssl: move ssl context init for servers from cfgparse.c to ssl_sock.c + - MEDIUM: ssl: reject ssl server keywords in default-server statement + - MINOR: ssl: add statement 'no-tls-tickets' on server side. + - MINOR: ssl: add statements 'verify', 'ca-file' and 'crl-file' on servers. + - DOC: Fix rename of options cafile and crlfile to ca-file and crl-file. + - MINOR: sample: manage binary to string type convertion in stick-table and samples. + - MINOR: acl: add parse and match primitives to use binary type on ACLs + - MINOR: sample: export 'sample_get_trash_chunk(void)' + - MINOR: conf: rename all ssl modules fetches using prefix 'ssl_fc' and 'ssl_c' + - MINOR: ssl: add pattern and ACLs fetches 'ssl_fc_protocol', 'ssl_fc_cipher', 'ssl_fc_use_keysize' and 'ssl_fc_alg_keysize' + - MINOR: ssl: add pattern fetch 'ssl_fc_session_id' + - MINOR: ssl: add pattern and ACLs fetches 'ssl_c_version' and 'ssl_f_version' + - MINOR: ssl: add pattern and ACLs fetches 'ssl_c_s_dn', 'ssl_c_i_dn', 'ssl_f_s_dn' and 'ssl_c_i_dn' + - MINOR: ssl: add pattern and ACLs 'ssl_c_sig_alg' and 'ssl_f_sig_alg' + - MINOR: ssl: add pattern and ACLs fetches 'ssl_c_key_alg' and 'ssl_f_key_alg' + - MINOR: ssl: add pattern and ACLs fetches 'ssl_c_notbefore', 'ssl_c_notafter', 'ssl_f_notbefore' and 'ssl_f_notafter' + - MINOR: ssl: add 'crt' statement on server. + - MINOR: ssl: checks the consistency of a private key with the corresponding certificate + - BUG/MEDIUM: ssl: review polling on reneg. + - BUG/MEDIUM: ssl: Fix some reneg cases not correctly handled. + - BUG/MEDIUM: ssl: Fix sometimes reneg fails if requested by server. + - MINOR: build: allow packagers to specify the ssl cache size + - MINOR: conf: add warning if ssl is not enabled and a certificate is present on bind. + - MINOR: ssl: Add tune.ssl.lifetime statement in global. + - MINOR: compression: Enable compression for IE6 w/SP2, IE7 and IE8 + - BUG: http: revert broken optimisation from 82fe75c1a79dac933391501b9d293bce34513755 + - DOC: duplicate ssl_sni section + - MEDIUM: HTTP compression (zlib library support) + - CLEANUP: use struct comp_ctx instead of union + - BUILD: remove dependency to zlib.h + - MINOR: compression: memlevel and windowsize + - MEDIUM: use pool for zlib + - MINOR: compression: try init in cfgparse.c + - MINOR: compression: init before deleting headers + - MEDIUM: compression: limit RAM usage + - MINOR: compression: tune.comp.maxlevel + - MINOR: compression: maximum compression rate limit + - MINOR: log-format: check number of arguments in cfgparse.c + - BUG/MEDIUM: compression: no Content-Type header but type in configuration + - BUG/MINOR: compression: deinit zlib only when required + - MEDIUM: compression: don't compress when no data + - MEDIUM: compression: use pool for comp_ctx + - MINOR: compression: rate limit in 'show info' + - MINOR: compression: report zlib memory usage + - BUG/MINOR: compression: dynamic level increase + - DOC: compression: unsupported cases. + - MINOR: compression: CPU usage limit + - MEDIUM: http: add "redirect scheme" to ease HTTP to HTTPS redirection + - BUG/MAJOR: ssl: missing tests in ACL fetch functions + - MINOR: config: add a function to indent error messages + - REORG: split "protocols" files into protocol and listener + - MEDIUM: config: replace ssl_conf by bind_conf + - CLEANUP: listener: remove unused conf->file and conf->line + - MEDIUM: listener: add a minimal framework to register "bind" keyword options + - MEDIUM: config: move the "bind" TCP parameters to proto_tcp + - MEDIUM: move bind SSL parsing to ssl_sock + - MINOR: config: improve error reporting for "bind" lines + - MEDIUM: config: move the common "bind" settings to listener.c + - MEDIUM: config: move all unix-specific bind keywords to proto_uxst.c + - MEDIUM: config: enumerate full list of registered "bind" keywords upon error + - MINOR: listener: add a scope field in the bind keyword lists + - MINOR: config: pass the file and line to config keyword parsers + - MINOR: stats: fill the file and line numbers in the stats frontend + - MINOR: config: set the bind_conf entry on listeners created from a "listen" line. + - MAJOR: listeners: use dual-linked lists to chain listeners with frontends + - REORG: listener: move unix perms from the listener to the bind_conf + - BUG: backend: balance hdr was broken since 1.5-dev11 + - MINOR: standard: make memprintf() support a NULL destination + - MINOR: config: make str2listener() use memprintf() to report errors. + - MEDIUM: stats: remove the stats_sock struct from the global struct + - MINOR: ssl: set the listeners' data layer to ssl during parsing + - MEDIUM: stats: make use of the standard "bind" parsers to parse global socket + - DOC: move bind options to their own section + - DOC: stats: refer to "bind" section for "stats socket" settings + - DOC: fix index to reference bind and server options + - BUG: http: do not print garbage on invalid requests in debug mode + - BUG/MINOR: config: check the proper pointer to report unknown protocol + - CLEANUP: connection: offer conn_prepare() to set up a connection + - CLEANUP: config: fix typo inteface => interface + - BUG: stats: fix regression introduced by commit 4348fad1 + - MINOR: cli: allow to set frontend maxconn to zero + - BUG/MAJOR: http: chunk parser was broken with buffer changes + - MEDIUM: monitor: simplify handling of monitor-net and mode health + - MINOR: connection: add a pointer to the connection owner + - MEDIUM: connection: make use of the owner instead of container_of + - BUG/MINOR: ssl: report the L4 connection as established when possible + - BUG/MEDIUM: proxy: must not try to stop disabled proxies upon reload + - BUG/MINOR: config: use a copy of the file name in proxy configurations + - BUG/MEDIUM: listener: don't pause protocols that do not support it + - MEDIUM: proxy: add the global frontend to the list of normal proxies + - BUG/MINOR: epoll: correctly disable FD polling in fd_rem() + - MINOR: signal: really ignore signals configured with no handler + - MINOR: buffers: add a few functions to write chars, strings and blocks + - MINOR: raw_sock: always report asynchronous connection errors + - MEDIUM: raw_sock: improve connection error reporting + - REORG: connection: rename the data layer the "transport layer" + - REORG: connection: rename app_cb "data" + - MINOR: connection: provide a generic data layer wakeup callback + - MINOR: connection: split conn_prepare() in two functions + - MINOR: connection: add an init callback to the data_cb struct + - MEDIUM: session: use a specific data_cb for embryonic sessions + - MEDIUM: connection: use a generic data-layer init() callback + - MEDIUM: connection: reorganize connection flags + - MEDIUM: connection: only call the data->wake callback on activity + - MEDIUM: connection: make it possible for data->wake to return an error + - MEDIUM: session: register a data->wake callback to process errors + - MEDIUM: connection: don't call the data->init callback upon error + - MEDIUM: connection: it's not the data layer's role to validate the connection + - MEDIUM: connection: automatically disable polling on error + - REORG: connection: move the PROXY protocol management to connection.c + - MEDIUM: connection: add a new local send-proxy transport callback + - MAJOR: checks: make use of the connection layer to send checks + - REORG: server: move the check-specific parts into a check subsection + - MEDIUM: checks: use real buffers to store requests and responses + - MEDIUM: check: add the ctrl and transport layers in the server check structure + - MAJOR: checks: completely use the connection transport layer + - MEDIUM: checks: add the "check-ssl" server option + - MEDIUM: checks: enable the PROXY protocol with health checks + - CLEANUP: checks: remove minor warnings for assigned but not used variables + - MEDIUM: tcp: enable TCP Fast Open on systems which support it + - BUG: connection: fix regression from commit 9e272bf9 + - CLEANUP: cttproxy: remove a warning on undeclared close() + - BUG/MAJOR: ensure that hdr_idx is always reserved when L7 fetches are used + - MEDIUM: listener: add support for linux's accept4() syscall + - MINOR: halog: sort output by cookie code + - BUG/MINOR: halog: -ad/-ac report the correct number of output lines + - BUG/MINOR: halog: fix help message for -ut/-uto + - MINOR: halog: add a parameter to limit output line count + - BUILD: accept4: move the socketcall declaration outside of accept4() + - MINOR: server: add minimal infrastructure to parse keywords + - MINOR: standard: make indent_msg() support empty messages + - MEDIUM: server: check for registered keywords when parsing unknown keywords + - MEDIUM: server: move parsing of keyword "id" to server.c + - BUG/MEDIUM: config: check-send-proxy was ignored if SSL was not builtin + - MEDIUM: ssl: move "server" keyword SSL options parsing to ssl_sock.c + - MEDIUM: log: suffix the frontend's name with '~' when using SSL + - MEDIUM: connection: always unset the transport layer upon close + - BUG/MINOR: session: fix some leftover from debug code + - BUG/MEDIUM: session: enable the conn_session_update() callback + - MEDIUM: connection: add a flag to hold the transport layer + - MEDIUM: log: add a new LW_XPRT flag to pin the transport layer + - MINOR: log: make lf_text use a const char * + - MEDIUM: log: report SSL ciphers and version in logs using logformat %sslc/%sslv + - REORG: http: rename msg->buf to msg->chn since it's a channel + - CLEANUP: http: use 'chn' to name channel variables, not 'buf' + - CLEANUP: channel: use 'chn' instead of 'buf' as local variable names + - CLEANUP: tcp: use 'chn' instead of 'buf' or 'b' for channel pointer names + - CLEANUP: stream_interface: use 'chn' instead of 'b' to name channel pointers + - CLEANUP: acl: use 'chn' instead of 'b' to name channel pointers + - MAJOR: channel: replace the struct buffer with a pointer to a buffer + - OPTIM: channel: reorganize struct members to improve cache efficiency + - CLEANUP: session: remove term_trace which is not used anymore + - OPTIM: session: reorder struct session fields + - OPTIM: connection: pack the struct target + - DOC: document relations between internal entities + - MINOR: ssl: add 'ssl_npn' sample/acl to extract TLS/NPN information + - BUILD: ssl: fix shctx build on older compilers + - MEDIUM: ssl: add support for the "npn" bind keyword + - BUG: ssl: fix ssl_sni ACLs to correctly process regular expressions + - MINOR: chunk: provide string compare functions + - MINOR: sample: accept fetch keywords without parenthesis + - MEDIUM: sample: pass an empty list instead of a null for fetch args + - MINOR: ssl: improve socket behaviour upon handshake abort. + - BUG/MEDIUM: http: set DONTWAIT on data when switching to tunnel mode + - MEDIUM: listener: provide a fallback for accept4() when not supported + - BUG/MAJOR: connection: risk of crash on certain tricky close scenario + - MEDIUM: cli: allow the stats socket to be bound to a specific set of processes + - OPTIM: channel: inline channel_forward's fast path + - OPTIM: http: inline http_parse_chunk_size() and http_skip_chunk_crlf() + - OPTIM: tools: inline hex2i() + - CLEANUP: http: rename HTTP_MSG_DATA_CRLF state + - MINOR: compression: automatically disable compression for older browsers + - MINOR: compression: optimize memLevel to improve byte rate + - BUG/MINOR: http: compression should consider all Accept-Encoding header values + - BUILD: fix coexistence of openssl and zlib + - MINOR: ssl: add pattern and ACLs fetches 'ssl_c_serial' and 'ssl_f_serial' + - BUG/MEDIUM: command-line option -D must have precedence over "debug" + - MINOR: tools: add a clear_addr() function to unset an address + - BUG/MEDIUM: tcp: transparent bind to the source only when address is set + - CLEANUP: remove trashlen + - MAJOR: session: detach the connections from the stream interfaces + - DOC: update document describing relations between internal entities + - BUILD: make it possible to specify ZLIB path + - MINOR: compression: add an offload option to remove the Accept-Encoding header + - BUG: compression: disable auto-close and enable MSG_MORE during transfer + - CLEANUP: completely remove trashlen + - MINOR: chunk: add a function to reset a chunk + - CLEANUP: replace chunk_printf() with chunk_appendf() + - MEDIUM: make the trash be a chunk instead of a char * + - MEDIUM: remove remains of BUFSIZE in HTTP auth and sample conversions + - MEDIUM: stick-table: allocate the table key of size buffer size + - BUG/MINOR: stream_interface: don't loop over ->snd_buf() + - BUG/MINOR: session: ensure that we don't retry connection if some data were sent + - OPTIM: session: don't process the whole session when only timers need a refresh + - BUG/MINOR: session: mark the handshake as complete earlier + - MAJOR: connection: remove the CO_FL_CURR_*_POL flag + - BUG/MAJOR: always clear the CO_FL_WAIT_* flags after updating polling flags + - MAJOR: sepoll: make the poller totally event-driven + - OPTIM: stream_interface: disable reading when CF_READ_DONTWAIT is set + - BUILD: compression: remove a build warning + - MEDIUM: fd: don't unset fdtab[].updated upon delete + - REORG: fd: move the speculative I/O management from ev_sepoll + - REORG: fd: move the fd state management from ev_sepoll + - REORG: fd: centralize the processing of speculative events + - BUG: raw_sock: also consider ENOTCONN in addition to EAGAIN + - BUILD: stream_interface: remove si_fd() and its references + - BUILD: compression: enable build in BSD and OSX Makefiles + - MAJOR: ev_select: make the poller support speculative events + - MAJOR: ev_poll: make the poller support speculative events + - MAJOR: ev_kqueue: make the poller support speculative events + - MAJOR: polling: replace epoll with sepoll and remove sepoll + - MAJOR: polling: remove unused callbacks from the poller struct + - MEDIUM: http: refrain from sending "Connection: close" when Upgrade is present + - CLEANUP: channel: remove any reference of the hijackers + - CLEANUP: stream_interface: remove the external task type target + - MAJOR: connection: replace struct target with a pointer to an enum + - BUG: connection: fix typo in previous commit + - BUG: polling: don't skip polled events in the spec list + - MINOR: splice: disable it when the system returns EBADF + - MINOR: build: allow packagers to specify the default maxzlibmem + - BUG: halog: fix broken output limitation + - BUG: proxy: fix server name lookup in get_backend_server() + - BUG: compression: do not always increment the round counter on allocation failure + - BUG/MEDIUM: compression: release the zlib pools between keep-alive requests + - MINOR: global: don't prevent nbproc from being redefined + - MINOR: config: support process ranges for "bind-process" + - MEDIUM: global: add support for CPU binding on Linux ("cpu-map") + - MINOR: ssl: rename and document the tune.ssl.cachesize option + - DOC: update the PROXY protocol spec to support v2 + - MINOR: standard: add a simple popcount function + - MEDIUM: adjust the maxaccept per listener depending on the number of processes + - BUG: compression: properly disable compression when content-type does not match + - MINOR: cli: report connection status in "show sess xxx" + - BUG/MAJOR: stream_interface: certain workloads could cause get stuck + - BUILD: cli: fix build when SSL is enabled + - MINOR: cli: report the fd state in "show sess xxx" + - MINOR: cli: report an error message on missing argument to compression rate + - MINOR: http: add some debugging functions to pretty-print msg state names + - BUG/MAJOR: stream_interface: read0 not always handled since dev12 + - DOC: documentation on http header capture is wrong + - MINOR: http: allow the cookie capture size to be changed + - DOC: http header capture has not been limited in size for a long time + - DOC: update readme with build methods for BSD + - BUILD: silence a warning on Solaris about usage of isdigit() + - MINOR: stats: report HTTP compression stats per frontend and per backend + - MINOR: log: add '%Tl' to log-format + - MINOR: samples: update the url_param fetch to match parameters in the path + +2012/09/10 : 1.5-dev12 + - CONTRIB: halog: sort URLs by avg bytes_read or total bytes_read + - MEDIUM: ssl: add support for prefer-server-ciphers option + - MINOR: IPv6 support for transparent proxy + - MINOR: protocol: add SSL context to listeners if USE_OPENSSL is defined + - MINOR: server: add SSL context to servers if USE_OPENSSL is defined + - MEDIUM: connection: add a new handshake flag for SSL (CO_FL_SSL_WAIT_HS). + - MEDIUM: ssl: add new files ssl_sock.[ch] to provide the SSL data layer + - MEDIUM: config: add the 'ssl' keyword on 'bind' lines + - MEDIUM: config: add support for the 'ssl' option on 'server' lines + - MEDIUM: ssl: protect against client-initiated renegociation + - BUILD: add optional support for SSL via the USE_OPENSSL flag + - MEDIUM: ssl: add shared memory session cache implementation. + - MEDIUM: ssl: replace OpenSSL's session cache with the shared cache + - MINOR: ssl add global setting tune.sslcachesize to set SSL session cache size. + - MEDIUM: ssl: add support for SNI and wildcard certificates + - DOC: Typos cleanup + - DOC: fix name for "option independant-streams" + - DOC: specify the default value for maxconn in the context of a proxy + - BUG/MINOR: to_log erased with unique-id-format + - LICENSE: add licence exception for OpenSSL + - BUG/MAJOR: cookie prefix doesn't support cookie-less servers + - BUILD: add an AIX 5.2 (and later) target. + - MEDIUM: fd/si: move peeraddr from struct fdinfo to struct connection + - MINOR: halog: use the more recent dual-mode fgets2 implementation + - BUG/MEDIUM: ebtree: ebmb_insert() must not call cmp_bits on full-length matches + - CLEANUP: halog: make clean should also remove .o files + - OPTIM: halog: make use of memchr() on platforms which provide a fast one + - OPTIM: halog: improve cold-cache behaviour when loading a file + - BUG/MINOR: ACL implicit arguments must be created with unresolved flag + - MINOR: replace acl_fetch_{path,url}* with smp_fetch_* + - MEDIUM: pattern: add the "base" sample fetch method + - OPTIM: i386: make use of kernel-mode-linux when available + - BUG/MINOR: tarpit: fix condition to return the HTTP 500 message + - BUG/MINOR: polling: some events were not set in various pollers + - MINOR: http: add the urlp_val ACL match + - BUG: stktable: tcp_src_to_stktable_key() must return NULL on invalid families + - MINOR: stats/cli: add plans to support more stick-table actions + - MEDIUM: stats/cli: add support for "set table key" to enter values + - REORG/MEDIUM: fd: remove FD_STCLOSE from struct fdtab + - REORG/MEDIUM: fd: remove checks for FD_STERROR in ev_sepoll + - REORG/MEDIUM: fd: get rid of FD_STLISTEN + - REORG/MINOR: connection: move declaration to its own include file + - REORG/MINOR: checks: put a struct connection into the server + - MINOR: connection: add flags to the connection struct + - MAJOR: get rid of fdtab[].state and use connection->flags instead + - MINOR: fd: add a new I/O handler to fdtab + - MEDIUM: polling: prepare to call the iocb() function when defined. + - MEDIUM: checks: make use of fdtab->iocb instead of cb[] + - MEDIUM: protocols: use the generic I/O callback for accept callbacks + - MINOR: connection: add a handler for fd-based connections + - MAJOR: connection: replace direct I/O callbacks with the connection callback + - MINOR: fd: make fdtab->owner a connection and not a stream_interface anymore + - MEDIUM: connection: remove the FD_POLL_* flags only once + - MEDIUM: connection: extract the send_proxy callback from proto_tcp + - MAJOR: tcp: remove the specific I/O callbacks for TCP connection probes + - CLEANUP: remove the now unused fdtab direct I/O callbacks + - MAJOR: remove the stream interface and task management code from sock_* + - MEDIUM: stream_interface: pass connection instead of fd in sock_ops + - MEDIUM: stream_interface: centralize the SI_FL_ERR management + - MAJOR: connection: add a new CO_FL_CONNECTED flag + - MINOR: rearrange tcp_connect_probe() and fix wrong return codes + - MAJOR: connection: call data layer handshakes from the handler + - MEDIUM: fd: remove the EV_FD_COND_* primitives + - MINOR: sock_raw: move calls to si_data_close upper + - REORG: connection: replace si_data_close() with conn_data_close() + - MEDIUM: sock_raw: introduce a read0 callback that is different from shutr + - MAJOR: stream_int: use a common stream_int_shut*() functions regardless of the data layer + - MAJOR: fd: replace all EV_FD_* macros with new fd_*_* inline calls + - MEDIUM: fd: add fd_poll_{recv,send} for use when explicit polling is required + - MEDIUM: connection: add definitions for dual polling mechanisms + - MEDIUM: connection: make use of the new polling functions + - MAJOR: make use of conn_{data|sock}_{poll|stop|want}* in connection handlers + - MEDIUM: checks: don't use FD_WAIT_* anymore + - MINOR: fd: get rid of FD_WAIT_* + - MEDIUM: stream_interface: offer a generic function for connection updates + - MEDIUM: stream-interface: offer a generic chk_rcv function for connections + - MEDIUM: stream-interface: add a snd_buf() callback to sock_ops + - MEDIUM: stream-interface: provide a generic stream_int_chk_snd_conn() function + - MEDIUM: stream-interface: provide a generic si_conn_send_cb callback + - MEDIUM: stream-interface: provide a generic stream_sock_read0() function + - REORG/MAJOR: use "struct channel" instead of "struct buffer" + - REORG/MAJOR: extract "struct buffer" from "struct channel" + - MINOR: connection: provide conn_{data|sock}_{read0|shutw} functions + - REORG: sock_raw: rename the files raw_sock* + - MAJOR: raw_sock: extract raw_sock_to_buf() from raw_sock_read() + - MAJOR: raw_sock: temporarily disable splicing + - MINOR: stream-interface: add an rcv_buf callback to sock_ops + - REORG: stream-interface: move sock_raw_read() to si_conn_recv_cb() + - MAJOR: connection: split the send call into connection and stream interface + - MAJOR: stream-interface: restore splicing mechanism + - MAJOR: stream-interface: make conn_notify_si() more robust + - MEDIUM: proxy-proto: don't use buffer flags in conn_si_send_proxy() + - MAJOR: stream-interface: don't commit polling changes in every callback + - MAJOR: stream-interface: fix splice not to call chk_snd by itself + - MEDIUM: stream-interface: don't remove WAIT_DATA when a handshake is in progress + - CLEANUP: connection: split sock_ops into data_ops, app_cp and si_ops + - REORG: buffers: split buffers into chunk,buffer,channel + - MAJOR: channel: remove the BF_OUT_EMPTY flag + - REORG: buffer: move buffer_flush, b_adv and b_rew to buffer.h + - MINOR: channel: rename bi_full to channel_full as it checks the whole channel + - MINOR: buffer: provide a new buffer_full() function + - MAJOR: channel: stop relying on BF_FULL to take action + - MAJOR: channel: remove the BF_FULL flag + - REORG: channel: move buffer_{replace,insert_line}* to buffer.{c,h} + - CLEANUP: channel: usr CF_/CHN_ prefixes instead of BF_/BUF_ + - CLEANUP: channel: use "channel" instead of "buffer" in function names + - REORG: connection: move the target pointer from si to connection + - MAJOR: connection: move the addr field from the stream_interface + - MEDIUM: stream_interface: remove CAP_SPLTCP/CAP_SPLICE flags + - MEDIUM: proto_tcp: remove any dependence on stream_interface + - MINOR: tcp: replace tcp_src_to_stktable_key with addr_to_stktable_key + - MEDIUM: connection: add an ->init function to data layer + - MAJOR: session: introduce embryonic sessions + - MAJOR: connection: make the PROXY decoder a handshake handler + - CLEANUP: frontend: remove the old proxy protocol decoder + - MAJOR: connection: rearrange the polling flags. + - MEDIUM: connection: only call tcp_connect_probe when nothing was attempted yet + - MEDIUM: connection: complete the polling cleanups + - MEDIUM: connection: avoid calling handshakes when polling is required + - MAJOR: stream_interface: continue to update data polling flags during handshakes + - CLEANUP: fd: remove fdtab->flags + - CLEANUP: fdtab: flatten the struct and merge the spec struct with the rest + - CLEANUP: includes: fix includes for a number of users of fd.h + - MINOR: ssl: disable TCP quick-ack by default on SSL listeners + - MEDIUM: config: add a "ciphers" keyword to set SSL cipher suites + - MEDIUM: config: add "nosslv3" and "notlsv1" on bind and server lines + - BUG: ssl: mark the connection as waiting for an SSL connection during the handshake + - BUILD: http: rename error_message http_error_message to fix conflicts on RHEL + - BUILD: ssl: fix shctx build on RHEL with futex + - BUILD: include sys/socket.h to fix build failure on FreeBSD + - BUILD: fix build error without SSL (ssl_cert) + - BUILD: ssl: use MAP_ANON instead of MAP_ANONYMOUS + - BUG/MEDIUM: workaround an eglibc bug which truncates the pidfiles when nbproc > 1 + - MEDIUM: config: support per-listener backlog and maxconn + - MINOR: session: do not send an HTTP/500 error on SSL sockets + - MEDIUM: config: implement maxsslconn in the global section + - BUG: tcp: close socket fd upon connect error + - MEDIUM: connection: improve error handling around the data layer + - MINOR: config: make the tasks "nice" value configurable on "bind" lines. + - BUILD: shut a gcc warning introduced by commit 269ab31 + - MEDIUM: config: centralize handling of SSL config per bind line + - BUILD: makefile: report USE_OPENSSL status in build options + - BUILD: report openssl build settings in haproxy -vv + - MEDIUM: ssl: add sample fetches for is_ssl, ssl_has_sni, ssl_sni_* + - DOC: add a special acknowledgement for the stud project + - DOC: add missing SSL options for servers and listeners + - BUILD: automatically add -lcrypto for SSL + - DOC: add some info about openssl build in the README + +2012/06/04 : 1.5-dev11 + - BUG/MEDIUM: option forwardfor if-none doesn't work with some configurations + - BUG/MAJOR: trash must always be the size of a buffer + - DOC: fix minor regex example issue and improve doc on stats + - MINOR: stream_interface: add a pointer to the listener for TARG_TYPE_CLIENT + - MEDIUM: protocol: add a pointer to struct sock_ops to the listener struct + - MINOR: checks: add on-marked-up option + - MINOR: balance uri: added 'whole' parameter to include query string in hash calculation + - MEDIUM: stream_interface: remove the si->init + - MINOR: buffers: add a rewind function + - BUG/MAJOR: fix regression on content-based hashing and http-send-name-header + - MAJOR: http: stop using msg->sol outside the parsers + - CLEANUP: http: make it more obvious that msg->som is always null outside of chunks + - MEDIUM: http: get rid of msg->som which is not used anymore + - MEDIUM: http: msg->sov and msg->sol will never wrap + - BUG/MAJOR: checks: don't call set_server_status_* when no LB algo is set + - BUG/MINOR: stop connect timeout when connect succeeds + - REORG: move the send-proxy code to tcp_connect_write() + - REORG/MINOR: session: detect the TCP monitor checks at the protocol accept + - MINOR: stream_interface: introduce a new "struct connection" type + - REORG/MINOR: stream_interface: move si->fd to struct connection + - REORG/MEDIUM: stream_interface: move applet->state and private to connection + - MINOR: stream_interface: add a data channel close function + - MEDIUM: stream_interface: call si_data_close() before releasing the si + - MINOR: peers: use the socket layer operations from the peer instead of sock_raw + - BUG/MINOR: checks: expire on timeout.check if smaller than timeout.connect + - MINOR: add a new function call tracer for debugging purposes + - BUG/MINOR: perform_http_redirect also needs to rewind the buffer + - BUG/MAJOR: b_rew() must pass a signed offset to b_ptr() + - BUG/MEDIUM: register peer sync handler in the proper order + - BUG/MEDIUM: buffers: fix bi_putchr() to correctly advance the pointer + - BUG/MINOR: fix option httplog validation with TCP frontends + - BUG/MINOR: log: don't report logformat errors in backends + - REORG/MINOR: use dedicated proxy flags for the cookie handling + - BUG/MINOR: config: do not report twice the incompatibility between cookie and non-http + - MINOR: http: add support for "httponly" and "secure" cookie attributes + - BUG/MEDIUM: ensure that unresolved arguments are freed exactly once + - BUG/MINOR: commit 196729ef used wrong condition resulting in freeing constants + - MEDIUM: stats: add support for soft stop/soft start in the admin interface + - MEDIUM: stats: add the ability to kill sessions from the admin interface + - BUILD: add support for linux kernels >= 2.6.28 + +2012/05/14 : 1.5-dev10 + - BUG/MINOR: stats admin: "Unexpected result" was displayed unconditionally + - BUG/MAJOR: acl: http_auth_group() must not accept any user from the userlist + - CLEANUP: auth: make the code build again with DEBUG_AUTH + - BUG/MEDIUM: config: don't crash at config load time on invalid userlist names + - REORG: use the name sock_raw instead of stream_sock + - MINOR: stream_interface: add a client target : TARG_TYPE_CLIENT + - BUG/MEDIUM: stream_interface: restore get_src/get_dst + - CLEANUP: sock_raw: remove last references to stream_sock + - CLEANUP: stream_interface: stop exporting socket layer functions + - MINOR: stream_interface: add an init callback to sock_ops + - MEDIUM: stream_interface: derive the socket operations from the target + - MAJOR: fd: remove the need for the socket layer to recheck the connection + - MINOR: session: call the socket layer init function when a session establishes + - MEDIUM: session: add support for tunnel timeouts + - MINOR: standard: add a new debug macro : fddebug() + - CLEANUP: fd: remove unused cb->b pointers in the struct fdtab + - OPTIM: proto_http: don't enable quick-ack on empty buffers + - OPTIM/MAJOR: ev_sepoll: process spec events after polled events + - OPTIM/MEDIUM: stream_interface: add a new SI_FL_NOHALF flag + +2012/05/08 : 1.5-dev9 + - MINOR: Add release callback to si_applet + - CLEANUP: Fix some minor typos + - MINOR: Add TO/FROM_SET flags to struct stream_interface + - CLEANUP: Fix some minor whitespace issues + - MINOR: stats admin: allow unordered parameters in POST requests + - CLEANUP: fix typo in findserver() log message + - MINOR: stats admin: use the backend id instead of its name in the form + - MINOR: stats admin: reduce memcmp()/strcmp() calls on status codes + - DOC: cleanup indentation, alignment, columns and chapters + - DOC: fix some keywords arguments documentation + - MINOR: cli: display the 4 IP addresses and ports on "show sess XXX" + - BUG/MAJOR: log: possible segfault with logformat + - MEDIUM: log: split of log_format generation + - MEDIUM: log: New format-log flags: %Fi %Fp %Si %Sp %Ts %rt %H %pid + - MEDIUM: log: Unique ID + - MINOR: log: log-format: usable without httplog and tcplog + - BUG/MEDIUM: balance source did not properly hash IPv6 addresses + - MINOR: contrib/iprange: add a network IP range to mask converter + - MEDIUM: session: implement the "use-server" directive + - MEDIUM: log: add a new cookie flag 'U' to report situations where cookie is not used + - MEDIUM: http: make extract_cookie_value() iterate over cookie values + - MEDIUM: http: add cookie and scookie ACLs + - CLEANUP: lb_first: add reference to a paper describing the original idea + - MEDIUM: stream_sock: add a get_src and get_dst callback and remove SN_FRT_ADDR_SET + - BUG/MINOR: acl: req_ssl_sni would randomly fail if a session ID is present + - BUILD: http: make extract_cookie_value() return an int not size_t + - BUILD: http: stop gcc-4.1.2 from complaining about possibly uninitialized values + - CLEANUP: http: message parser must ignore HTTP_MSG_ERROR + - MINOR: standard: add a memprintf() function to build formatted error messages + - CLEANUP: remove a few warning about unchecked return values in debug code + - MEDIUM: move message-related flags from transaction to message + - DOC: add a diagram to explain how circular buffers work + - MAJOR: buffer rework: replace ->send_max with ->o + - MAJOR: buffer: replace buf->l with buf->{o+i} + - MINOR: buffers: provide simple pointer normalization functions + - MINOR: buffers: remove unused function buffer_contig_data() + - MAJOR: buffers: replace buf->w with buf->p - buf->o + - MAJOR: buffers: replace buf->r with buf->p + buf->i + - MAJOR: http: move buffer->lr to http_msg->next + - MAJOR: http: change msg->{som,col,sov,eoh} to be relative to buffer origin + - CLEANUP: http: remove unused http_msg->col + - MAJOR: http: turn http_msg->eol to a buffer-relative offset + - MEDIUM: http: add a pointer to the buffer in http_msg + - MAJOR: http: make http_msg->sol relative to buffer's origin + - MEDIUM: http: http_send_name_header: remove references to msg and buffer + - MEDIUM: http: remove buffer arg in a few header manipulation functions + - MEDIUM: http: remove buffer arg in http_capture_bad_message + - MEDIUM: http: remove buffer arg in http_msg_analyzer + - MEDIUM: http: remove buffer arg in http_upgrade_v09_to_v10 + - MEDIUM: http: remove buffer arg in http_buffer_heavy_realign + - MEDIUM: http: remove buffer arg in chunk parsing functions + - MINOR: http: remove useless wrapping checks in http_msg_analyzer + - MEDIUM: buffers: fix unsafe use of buffer_ignore at some places + - MEDIUM: buffers: add new pointer wrappers and get rid of almost all buffer_wrap_add calls + - MEDIUM: buffers: implement b_adv() to advance a buffer's pointer + - MEDIUM: buffers: rename a number of buffer management functions + - MEDIUM: http: add a prefetch function for ACL pattern fetch + - MEDIUM: http: make all ACL fetch function use acl_prefetch_http() + - BUG/MINOR: http_auth: ACLs are volatile, not permanent + - MEDIUM: http/acl: merge all request and response ACL fetches of headers and cookies + - MEDIUM: http/acl: make acl_fetch_hdr_{ip,val} rely on acl_fetch_hdr() + - MEDIUM: add a new typed argument list parsing framework + - MAJOR: acl: make use of the new argument parsing framework + - MAJOR: acl: store the ACL argument types in the ACL keyword declaration + - MEDIUM: acl: acl_find_target() now resolves arguments based on their types + - MAJOR: acl: make acl_find_targets also resolve proxy names at config time + - MAJOR: acl: ensure that implicit table and proxies are valid + - MEDIUM: acl: remove unused tests for missing args when args are mandatory + - MEDIUM: pattern: replace type pattern_arg with type arg + - MEDIUM: pattern: get rid of arg_i in all functions making use of arguments + - MEDIUM: pattern: use the standard arg parser + - MEDIUM: pattern: add an argument validation callback to pattern descriptors + - MEDIUM: pattern: report the precise argument parsing error when known. + - MEDIUM: acl: remove the ACL_TEST_F_NULL_MATCH flag + - MINOR: pattern: add a new 'sample' type to store fetched data + - MEDIUM: pattern: add new sample types to replace pattern types + - MAJOR: acl: make use of the new sample struct and get rid of acl_test + - MEDIUM: pattern/acl: get rid of temp_pattern in ACLs + - MEDIUM: acl: get rid of the SET_RES flags + - MEDIUM: get rid of SMP_F_READ_ONLY and SMP_F_MUST_FREE + - MINOR: pattern: replace struct pattern with struct sample + - MEDIUM: pattern: integrate pattern_data into sample and use sample everywhere + - MEDIUM: pattern: retrieve the sample type in the sample, not in the keyword description + - MEDIUM: acl/pattern: switch rdp_cookie functions stack up-down + - MEDIUM: acl: replace acl_expr with args in acl fetch_* functions + - MINOR: tcp: replace acl_fetch_rdp_cookie with smp_fetch_rdp_cookie + - MEDIUM: acl/pattern: use the same direction scheme + - MEDIUM: acl/pattern: start merging common sample fetch functions + - MEDIUM: pattern: ensure that sample types always cast into other types. + - MEDIUM: acl/pattern: factor out the src/dst address fetches + - MEDIUM: acl: implement payload and payload_lv + - CLEANUP: pattern: ensure that payload and payload_lv always stay in the buffer + - MINOR: stick_table: centralize the handling of empty keys + - MINOR: pattern: centralize handling of unstable data in pattern_process() + - MEDIUM: pattern: use smp_fetch_rdp_cookie instead of the pattern specific version + - MINOR: acl: set SMP_OPT_ITERATE on fetch functions + - MINOR: acl: add a val_args field to keywords + - MINOR: proto_tcp: validate arguments of payload and payload_lv ACLs + - MEDIUM: http: merge acl and pattern header fetch functions + - MEDIUM: http: merge ACL and pattern cookie fetches into a single one + - MEDIUM: acl: report parsing errors to the caller + - MINOR: arg: improve error reporting on invalid arguments + - MINOR: acl: report errors encountered when loading patterns from files + - MEDIUM: acl: extend the pattern parsers to report meaningful errors + - REORG: use the name "sample" instead of "pattern" to designate extracted data + - REORG: rename "pattern" files + - MINOR: acl: add types to ACL patterns + - MINOR: standard: add an IPv6 parsing function (str62net) + - MEDIUM: acl: support IPv6 address matching + - REORG: stream_interface: create a struct sock_ops to hold socket operations + - REORG/MEDIUM: move protocol->{read,write} to sock_ops + - REORG/MEDIUM: stream_interface: initialize socket ops from descriptors + - REORG/MEDIUM: replace stream interface protocol functions by a proto pointer + - REORG/MEDIUM: move the default accept function from sockstream to protocols.c + - MEDIUM: proto_tcp: remove src6 and dst6 pattern fetch methods + - BUG/MINOR: http: error snapshots are wrong if buffer wraps + - BUG/MINOR: http: ensure that msg->err_pos is always relative to buf->p + - MEDIUM: http: improve error capture reports + - MINOR: acl: add the cook_val() match to match a cookie against an integer + - BUG/MEDIUM: send_proxy: fix initialisation of send_proxy_ofs + - MEDIUM: memory: add the ability to poison memory at run time + - BUG/MEDIUM: log: ensure that unique_id is properly initialized + - MINOR: cfgparse: use a common errmsg pointer for all parsers + - MEDIUM: cfgparse: make backend_parse_balance() use memprintf to report errors + - MEDIUM: cfgparse: use the new error reporting framework for remaining cfg_keywords + - MINOR: http: replace http_message_realign() with buffer_slow_realign() + +2012/03/26 : 1.5-dev8 + - MINOR: patch for minor typo (ressources/resources) + - MEDIUM: http: add support for sending the server's name in the outgoing request + - DOC: mention that default checks are TCP connections + - BUG/MINOR: fix options forwardfor if-none when an alternative header name is specified + - CLEANUP: Make check_statuses, analyze_statuses and process_chk static + - CLEANUP: Fix HCHK spelling errors + - BUG/MINOR: fix typo in processing of http-send-name-header + - MEDIUM: log: Use linked lists for loggers + - BUILD: fix declaration inside a scope block + - REORG: log: split send_log function + - MINOR: config: Parse the string of the log-format config keyword + - MINOR: add ultoa, ulltoa, ltoa, lltoa implementations + - MINOR: Date and time fonctions that don't use snprintf + - MEDIUM: log: make http_sess_log use log_format + - DOC: log-format documentation + - MEDIUM: log: use log_format for mode tcplog + - MEDIUM: log-format: backend source address %Bi %Bp + - BUG/MINOR: log-format: fix %o flag + - BUG/MEDIUM: bad length in log_format and __send_log + - MINOR: logformat %st is signed + - BUILD/MINOR: fix the source URL in the spec file + - DOC: acl is http_first_req, not http_req_first + - BUG/MEDIUM: don't trim last spaces from headers consisting only of spaces + - MINOR: acl: add new matches for header/path/url length + - BUILD: halog: make halog build on solaris + - BUG/MINOR: don't use a wrong port when connecting to a server with mapped ports + - MINOR: remove the client/server side distinction in SI addresses + - MINOR: halog: add support for matching queued requests + - DOC: indicate that cookie "prefix" and "indirect" should not be mixed + - OPTIM/MINOR: move struct sockaddr_storage to the tail of structs + - OPTIM/MINOR: make it possible to change pipe size (tune.pipesize) + - BUILD/MINOR: silent a build warning in src/pipe.c (fcntl) + - OPTIM/MINOR: move the hdr_idx pools out of the proxy struct + - MEDIUM: tune.http.maxhdr makes it possible to configure the maximum number of HTTP headers + - BUG/MINOR: fix a segfault when parsing a config with undeclared peers + - CLEANUP: rename possibly confusing struct field "tracked" + - BUG/MEDIUM: checks: fix slowstart behaviour when server tracking is in use + - MINOR: config: tolerate server "cookie" setting in non-HTTP mode + - MEDIUM: buffers: add some new primitives and rework existing ones + - BUG: buffers: don't return a negative value on buffer_total_space_res() + - MINOR: buffers: make buffer_pointer() support negative pointers too + - CLEANUP: kill buffer_replace() and use an inline instead + - BUG: tcp: option nolinger does not work on backends + - CLEANUP: ebtree: remove a few annoying signedness warnings + - CLEANUP: ebtree: clarify licence and update to 6.0.6 + - CLEANUP: ebtree: remove 4-year old harmless typo in duplicates insertion code + - CLEANUP: ebtree: remove another typo, a wrong initialization in insertion code + - BUG: ebtree: ebst_lookup() could return the wrong entry + - OPTIM: stream_sock: reduce the amount of in-flight spliced data + - OPTIM: stream_sock: save a failed recv syscall when splice returns EAGAIN + - MINOR: acl: add support for TLS server name matching using SNI + - BUG: http: re-enable TCP quick-ack upon incomplete HTTP requests + - BUG: proto_tcp: don't try to bind to a foreign address if sin_family is unknown + - MINOR: pattern: export the global temporary pattern + - CLEANUP: patterns: get rid of pattern_data_setstring() + - MEDIUM: acl: use temp_pattern to store fetched information in the "method" match + - MINOR: acl: include pattern.h to make pattern migration more transparent + - MEDIUM: pattern: change the pattern data integer from unsigned to signed + - MEDIUM: acl: use temp_pattern to store any integer-type information + - MEDIUM: acl: use temp_pattern to store any address-type information + - CLEANUP: acl: integer part of acl_test is not used anymore + - MEDIUM: acl: use temp_pattern to store any string-type information + - CLEANUP: acl: remove last data fields from the acl_test struct + - MEDIUM: http: replace get_ip_from_hdr2() with http_get_hdr() + - MEDIUM: patterns: the hdr() pattern is now of type string + - DOC: add minimal documentation on how ACLs work internally + - DOC: add a coding-style file + - OPTIM: halog: keep a fast path for the lines-count only + - CLEANUP: silence a warning when building on sparc + - BUG: http: tighten the list of allowed characters in a URI + - MEDIUM: http: block non-ASCII characters in URIs by default + - DOC: add some documentation from RFC3986 about URI format + - BUG/MINOR: cli: correctly remove the whole table on "clear table" + - BUG/MEDIUM: correctly disable servers tracking another disabled servers. + - BUG/MEDIUM: zero-weight servers must not dequeue requests from the backend + - MINOR: halog: add some help on the command line + - BUILD: fix build error on FreeBSD + - BUG: fix double free in peers config error path + - MEDIUM: improve config check return codes + - BUILD: make it possible to look for pcre in the default system paths + - MINOR: config: emit a warning when 'default_backend' masks servers + - MINOR: backend: rework the LC definition to support other connection-based algos + - MEDIUM: backend: add the 'first' balancing algorithm + - BUG: fix httplog trailing LF + - MEDIUM: increase chunk-size limit to 2GB-1 + - BUG: queue: fix dequeueing sequence on HTTP keep-alive sessions + - BUG: http: disable TCP delayed ACKs when forwarding content-length data + - BUG: checks: fix server maintenance exit sequence + - BUG/MINOR: stream_sock: don't remove BF_EXPECT_MORE and BF_SEND_DONTWAIT on partial writes + - DOC: enumerate valid status codes for "observe layer7" + - MINOR: buffer: switch a number of buffer args to const + - CLEANUP: silence signedness warning in acl.c + - BUG: stream_sock: si->release was not called upon shutw() + - MINOR: log: use "%ts" to log term status only and "%tsc" to log with cookie + - BUG/CRITICAL: log: fix risk of crash in development snapshot + - BUG/MAJOR: possible crash when using capture headers on TCP frontends + - MINOR: config: disable header captures in TCP mode and complain + +2011/09/10 : 1.5-dev7 + - [BUG] fix binary stick-tables + - [MINOR] http: *_dom matching header functions now also split on ":" + - [BUG] checks: fix support of Mysqld >= 5.5 for mysql-check + - [MINOR] acl: add srv_conn acl to count connections on a specific backend server + - [MINOR] check: add redis check support + - [DOC] small fixes to clearly distinguish between keyword and variables + - [MINOR] halog: add support for termination code matching (-tcn/-TCN) + - [DOC] Minor spelling fixes and grammatical enhancements + - [CLEANUP] dumpstats: make symbols static where possible + - [MINOR] Break out dumping table + - [MINOR] Break out processing of clear table + - [MINOR] Allow listing of stick table by key + - [MINOR] Break out all stick table socat command parsing + - [MINOR] More flexible clearing of stick table + - [MINOR] Allow showing and clearing by key of ipv6 stick tables + - [MINOR] Allow showing and clearing by key of integer stick tables + - [MINOR] Allow showing and clearing by key of string stick tables + - [CLEANUP] Remove assigned but unused variables + - [CLEANUP] peers.h: fix declarations + - [CLEANUP] session.c: Make functions static where possible + - [MINOR] Add active connection list to server + - [MINOR] Allow shutdown of sessions when a server becomes unavailable + - [MINOR] Add down termination condition + - [MINOR] Make appsess{,ion}_refresh static + - [MINOR] Add rdp_cookie pattern fetch function + - [CLEANUP] Remove unnecessary casts + - [MINOR] Add non-stick server option + - [MINOR] Consistently use error in tcp_parse_tcp_req() + - [MINOR] Consistently free expr on error in cfg_parse_listen() + - [MINOR] Free rdp_cookie_name on denint() + - [MINOR] Free tcp rules on denint() + - [MINOR] Free stick table pool on denint() + - [MINOR] Free stick rules on denint() + - [MEDIUM] Fix stick-table replication on soft-restart + - [MEDIUM] Correct ipmask() logic + - [MINOR] Correct type in table dump examples + - [MINOR] Fix build error in stream_int_register_handler() + - [MINOR] Use DPRINTF in assign_server() + - [BUG] checks: http-check expect could fail a check on multi-packet responses + - [DOC] fix minor typo in the "dispatch" doc + - [BUG] proto_tcp: fix address binding on remote source + - [MINOR] http: don't report the "haproxy" word on the monitoring response + - [REORG] http: move HTTP error codes back to proto_http.h + - [MINOR] http: make the "HTTP 200" status code configurable. + - [MINOR] http: partially revert the chunking optimization for now + - [MINOR] stream_sock: always clear BF_EXPECT_MORE upon complete transfer + - [CLEANUP] stream_sock: remove unneeded FL_TCP and factor out test + - [MEDIUM] http: add support for "http-no-delay" + - [OPTIM] http: optimize chunking again in non-interactive mode + - [OPTIM] stream_sock: avoid fast-forwarding of partial data + - [OPTIM] stream_sock: don't use splice on too small payloads + - [MINOR] config: make it possible to specify a cookie even without a server + - [BUG] stats: support url-encoded forms + - [MINOR] config: automatically compute a default fullconn value + - [CLEANUP] config: remove some left-over printf debugging code from previous patch + - [DOC] add missing entry or stick store-response + - [MEDIUM] http: add support for 'cookie' and 'set-cookie' patterns + - [BUG] halog: correctly handle truncated last line + - [MINOR] halog: make SKIP_CHAR stop on field delimiters + - [MINOR] halog: add support for HTTP log matching (-H) + - [MINOR] halog: gain back performance before SKIP_CHAR fix + - [OPTIM] halog: cache some common fields positions + - [OPTIM] halog: check once for correct line format and reuse the pointer + - [OPTIM] halog: remove many 'if' by using a function pointer for the filters + - [OPTIM] halog: remove support for tab delimiters in input data + - [BUG] session: risk of crash on out of memory (1.5-dev regression) + - [MINOR] session: try to emit a 500 response on memory allocation errors + - [OPTIM] stream_sock: reduce the default number of accepted connections at once + - [BUG] stream_sock: disable listener when system resources are exhausted + - [MEDIUM] proxy: add a PAUSED state to listeners and move socket tricks out of proxy.c + - [BUG] stream_sock: ensure orphan listeners don't accept too many connections + - [MINOR] listeners: add listen_full() to mark a listener full + - [MINOR] listeners: add support for queueing resource limited listeners + - [MEDIUM] listeners: put listeners in queue upon resource shortage + - [MEDIUM] listeners: queue proxy-bound listeners at the proxy's + - [MEDIUM] listeners: don't stop proxies when global maxconn is reached + - [MEDIUM] listeners: don't change listeners states anymore in maintain_proxies + - [CLEANUP] proxy: rename a few proxy states (PR_STIDLE and PR_STRUN) + - [MINOR] stats: report a "WAITING" state for sockets waiting for resource + - [MINOR] proxy: make session rate-limit more accurate + - [MINOR] sessions: only wake waiting listeners up if rate limit is OK + - [BUG] proxy: peers must only be stopped once, not upon every call to maintain_proxies + - [CLEANUP] proxy: merge maintain_proxies() operation inside a single loop + - [MINOR] task: new function task_schedule() to schedule a wake up + - [MAJOR] proxy: finally get rid of maintain_proxies() + - [BUG] proxy: stats frontend and peers were missing many initializers + - [MEDIUM] listeners: add a global listener management task + - [MINOR] proxy: make findproxy() return proxies from numeric IDs too + - [DOC] fix typos, "#" is a sharp, not a dash + - [MEDIUM] stats: add support for changing frontend's maxconn at runtime + - [MEDIUM] checks: group health checks methods by values and save option bits + - [MINOR] session-counters: add the ability to clear the counters + - [BUG] check: http-check expect + regex would crash in defaults section + - [MEDIUM] http: make x-forwarded-for addition conditional + - [REORG] build: move syscall redefinition to specific places + - [CLEANUP] update the year in the copyright banner + - [BUG] possible crash in 'show table' on stats socket + - [BUG] checks: use the correct destination port for sending checks + - [BUG] backend: risk of picking a wrong port when mapping is used with crossed families + - [MINOR] make use of set_host_port() and get_host_port() to get rid of family mismatches + - [DOC] fixed a few "sensible" -> "sensitive" errors + - [MINOR] make use of addr_to_str() and get_host_port() to replace many inet_ntop() + - [BUG] http: trailing white spaces must also be trimmed after headers + - [MINOR] stats: display "" instead of the frontend name when unknown + - [MINOR] http: take a capture of too large requests and responses + - [MINOR] http: take a capture of truncated responses + - [MINOR] http: take a capture of bad content-lengths. + - [DOC] add a few old and uncommitted docs + - [CLEANUP] cfgparse: fix reported options for the "bind" keyword + - [MINOR] halog: add -hs/-HS to filter by HTTP status code range + - [MINOR] halog: support backslash-escaped quotes + - [CLEANUP] remove dirty left-over of a debugging message + - [MEDIUM] stats: disable complex socket reservation for stats socket + - [CLEANUP] remove a useless test in manage_global_listener_queue() + - [MEDIUM] stats: add the "set maxconn" setting to the command line interface + - [MEDIUM] add support for global.maxconnrate to limit the per-process conn rate. + - [MINOR] stats: report the current and max global connection rates + - [MEDIUM] stats: add the ability to adjust the global maxconnrate + - [BUG] peers: don't pre-allocate 65000 connections to each peer + - [MEDIUM] don't limit peers nor stats socket to maxconn nor maxconnrate + - [BUG] peers: the peer frontend must not emit any log + - [CLEANUP] proxy: make pause_proxy() perform the required controls and emit the logs + - [BUG] peers: don't keep a peers section which has a NULL frontend + - [BUG] peers: ensure the peers are resumed if they were paused + - [MEDIUM] stats: add the ability to enable/disable/shutdown a frontend at runtime + - [MEDIUM] session: make session_shutdown() an independant function + - [MEDIUM] stats: offer the possibility to kill a session from the CLI + - [CLEANUP] stats: centralize tests for backend/server inputs on the CLI + - [MEDIUM] stats: offer the possibility to kill sessions by server + - [MINOR] halog: do not consider byte 0x8A as end of line + - [MINOR] frontend: ensure debug message length is always initialized + - [OPTIM] halog: make fgets parse more bytes by blocks + - [OPTIM] halog: add assembly version of the field lookup code + - [MEDIUM] poll: add a measurement of idle vs work time + - [CLEANUP] startup: report only the basename in the usage message + - [MINOR] startup: add an option to change to a new directory + - [OPTIM] task: don't scan the run queue if we know it's empty + - [BUILD] stats: stdint is not present on solaris + - [DOC] update the README file to reflect new naming rules for patches + - [MINOR] stats: report the number of requests intercepted by the frontend + - [DOC] update ROADMAP file + +2011/04/08 : 1.5-dev6 + - [BUG] stream_sock: use get_addr_len() instead of sizeof() on sockaddr_storage + - [BUG] TCP source tracking was broken with IPv6 changes + - [BUG] stick-tables did not work when converting IPv6 to IPv4 + - [CRITICAL] fix risk of crash when dealing with space in response cookies + +2011/03/29 : 1.5-dev5 + - [BUG] standard: is_addr return value for IPv4 was inverted + - [MINOR] update comment about IPv6 support for server + - [MEDIUM] use getaddrinfo to resolve names if gethostbyname fail + - [DOC] update IPv6 support for bind + - [DOC] document IPv6 support for server + - [DOC] fix a minor typo + - [MEDIUM] IPv6 support for syslog + - [DOC] document IPv6 support for syslog + - [MEDIUM] IPv6 support for stick-tables + - [DOC] document IPv6 support for stick-tables + - [DOC] update ROADMAP file + - [BUG] session: src_conn_cur was returning src_conn_cnt instead + - [MINOR] frontend: add a make_proxy_line function + - [MEDIUM] stream_sock: add support for sending the proxy protocol header line + - [MEDIUM] server: add support for the "send-proxy" option + - [DOC] update the spec on the proxy protocol + - [BUILD] proto_tcp: fix build issue with CTTPROXY + - [DOC] update ROADMAP file + - [MEDIUM] config: rework the IPv4/IPv6 address parser to support host-only addresses + - [MINOR] cfgparse: better report wrong listening addresses and make use of str2sa_range + - [BUILD] add the USE_GETADDRINFO build option + - [TESTS] provide a test case for various address formats + - [BUG] session: conn_retries was not always initialized + - [BUG] log: retrieve the target from the session, not the SI + - [BUG] http: fix possible incorrect forwarded wrapping chunk size (take 2) + - [MINOR] tools: add two macros MID_RANGE and MAX_RANGE + - [BUG] http: fix content-length handling on 32-bit platforms + - [OPTIM] buffers: uninline buffer_forward() + - [BUG] stream_sock: fix handling for server side PROXY protocol + - [MINOR] acl: add support for table_cnt and table_avl matches + - [DOC] update ROADMAP file + +2011/03/13 : 1.5-dev4 + - [MINOR] cfgparse: Check whether the path given for the stats socket actually fits into the sockaddr_un structure to avoid truncation. + - [MINOR] unix sockets : inherits the backlog size from the listener + - [CLEANUP] unix sockets : move create_uxst_socket() in uxst_bind_listener() + - [DOC] fix a minor typo + - [DOC] fix ignore-persist documentation + - [MINOR] add warnings on features not compatible with multi-process mode + - [BUG] http: fix http-pretend-keepalive and httpclose/tunnel mode + - [MINOR] stats: add support for several packets in stats admin + - [BUG] stats: admin commands must check the proxy state + - [BUG] stats: admin web interface must check the proxy state + - [MINOR] http: add pattern extraction method to stick on query string parameter + - [MEDIUM] add internal support for IPv6 server addresses + - [MINOR] acl: add be_id/srv_id to match backend's and server's id + - [MINOR] log: add support for passing the forwarded hostname + - [MINOR] log: ability to override the syslog tag + - [MINOR] checks: add PostgreSQL health check + - [DOC] update ROADMAP file + - [BUILD] pattern: use 'int' instead of 'int32_t' + - [OPTIM] linux: add support for bypassing libc to force using vsyscalls + - [BUG] debug: report the correct poller list in verbose mode + - [BUG] capture: do not capture a cookie if there is no memory left + - [BUG] appsession: fix possible double free in case of out of memory + - [CRITICAL] cookies: mixing cookies in indirect mode and appsession can crash the process + - [BUG] http: correctly update the header list when removing two consecutive headers + - [BUILD] add the CPU=native and ARCH=32/64 build options + - [BUILD] add -fno-strict-aliasing to fix warnings with gcc >= 4.4 + - [CLEANUP] hash: move the avalanche hash code globally available + - [MEDIUM] hash: add support for an 'avalanche' hash-type + - [DOC] update roadmap file + - [BUG] http: do not re-enable the PROXY analyser on keep-alive + - [OPTIM] http: don't send each chunk in a separate packet + - [DOC] fix minor typos reported recently in the peers section + - [DOC] fix another typo in the doc + - [MINOR] stats: report HTTP message state and buffer flags in error dumps + - [BUG] http chunking: don't report a parsing error on connection errors + - [BUG] stream_interface: truncate buffers when sending error messages + - [MINOR] http: support wrapping messages in error captures + - [MINOR] http: capture incorrectly chunked message bodies + - [MINOR] stats: add global event ID and count + - [BUG] http: analyser optimizations broke pipelining + - [CLEANUP] frontend: only apply TCP-specific settings to TCP/TCP6 sockets + - [BUG] http: fix incorrect error reporting during data transfers + - [CRITICAL] session: correctly leave turn-around and queue states on abort + - [BUG] session: release slot before processing pending connections + - [MINOR] tcp: add support for dynamic MSS setting + - [BUG] stick-table: correctly terminate string keys during lookups + - [BUG] acl: fix handling of empty lines in pattern files + - [BUG] stick-table: use the private buffer when padding strings + - [BUG] ebtree: fix ebmb_lookup() with len smaller than the tree's keys + - [OPTIM] ebtree: ebmb_lookup: reduce stack usage by moving the return code out of the loop + - [OPTIM] ebtree: inline ebst_lookup_len and ebis_lookup_len + - [REVERT] undo the stick-table string key lookup fixes + - [MINOR] http: improve url_param pattern extraction to ignore empty values + - [BUILD] frontend: shut a warning with TCP_MAXSEG + - [BUG] http: update the header list's tail when removing the last header + - [DOC] fix minor typo in the proxy protocol doc + - [DOC] fix typos (http-request instead of http-check) + - [BUG] http: use correct ACL pointer when evaluating authentication + - [BUG] cfgparse: correctly count one socket per port in ranges + - [BUG] startup: set the rlimits before binding ports, not after. + - [BUG] acl: srv_id must return no match when the server is NULL + - [MINOR] acl: add ability to check for internal response-only parameters + - [MINOR] acl: srv_id is only valid in responses + - [MINOR] config: warn if response-only conditions are used in "redirect" rules + - [BUG] acl: fd leak when reading patterns from file + - [DOC] fix minor typo in "usesrc" + - [BUG] http: fix possible incorrect forwarded wrapping chunk size + - [BUG] http: fix computation of message body length after forwarding has started + - [BUG] http: balance url_param did not work with first parameters on POST + - [TESTS] update the url_param regression test to test check_post too + - [DOC] update ROADMAP + - [DOC] internal: reflect the fact that SI_ST_ASS is transient + - [BUG] config: don't crash on empty pattern files. + - [MINOR] stream_interface: make use of an applet descriptor for IO handlers + - [REORG] stream_interface: move the st0, st1 and private members to the applet + - [REORG] stream_interface: split the struct members in 3 parts + - [REORG] session: move client and server address to the stream interface + - [REORG] tcp: make tcpv4_connect_server() take the target address from the SI + - [MEDIUM] stream_interface: store the target pointer and type + - [CLEANUP] stream_interface: remove the applet.handler pointer + - [MEDIUM] log: take the logged server name from the stream interface + - [CLEANUP] session: remove data_source from struct session + - [CLEANUP] stats: make all dump functions only rely on the stream interface + - [REORG] session: move the data_ctx struct to the stream interface's applet + - [MINOR] proxy: add PR_O2_DISPATCH to detect dispatch mode + - [MINOR] cfgparse: only keep one of dispatch, transparent, http_proxy + - [MINOR] session: add a pointer to the new target into the session + - [MEDIUM] session: remove s->prev_srv which is not needed anymore + - [CLEANUP] stream_interface: use inline functions to manipulate targets + - [MAJOR] session: remove the ->srv pointer from struct session + - [MEDIUM] stats: split frontend and backend stats + - [MEDIUM] http: always evaluate http-request rules before stats http-request + - [REORG] http: move the http-request rules to proto_http + - [BUG] http: stats were not incremented on http-request deny + - [MINOR] checks: report it if checks fail due to socket creation error + +2010/11/11 : 1.5-dev3 + - [DOC] fix http-request documentation + - [MEDIUM] enable/disable servers from the stats web interface + - [MEDIUM] stats: add an admin level + - [DOC] stats: document the "stats admin" statement + - [MINOR] startup: print the proxy socket which caused an error + - [CLEANUP] Remove unneeded chars allocation + - [MINOR] config: detect options not supported due to compilation options + - [MINOR] Add pattern's fetchs payload and payload_lv + - [MINOR] frontend: improve accept-proxy header parsing + - [MINOR] frontend: add tcpv6 support on accept-proxy bind + - [MEDIUM] Enhance message errors management on binds + - [MINOR] Manage unix socket source field on logs + - [MINOR] Manage unix socket source field on session dump on sock stats + - [MINOR] Support of unix listener sockets for debug and log event messages on frontend.c + - [MINOR] Add some tests on sockets family for port remapping and mode transparent. + - [MINOR] Manage socket type unix for some logs + - [MINOR] Enhance controls of socket's family on acls and pattern fetch + - [MINOR] Support listener's sockets unix on http logs. + - [MEDIUM] Add supports of bind on unix sockets. + - [BUG] stick table purge failure if size less than 255 + - [BUG] stick table entries expire on counters updates/read or show table, even if there is no "expire" parameter + - [MEDIUM] Implement tcp inspect response rules + - [DOC] tcp-response content and inspect + - [MINOR] new acls fetch req_ssl_hello_type and rep_ssl_hello_type + - [DOC] acls rep_ssl_hello and req_ssl_hello + - [MEDIUM] Create new protected pattern types CONSTSTRING and CONSTDATA to force memcpy if data from protected areas need to be manipulated. + - [DOC] new type binary in stick-table + - [DOC] stick store-response and new patterns payload and payload_lv + - [MINOR] Manage all types (ip, integer, string, binary) on cli "show table" command + - [MEDIUM] Create updates tree on stick table to manage sync. + - [MAJOR] Add new files src/peer.c, include/proto/peers.h and include/types/peers.h for sync stick table management + - [MEDIUM] Manage peers section parsing and stick table registration on peers. + - [MEDIUM] Manage soft stop on peers proxy + - [DOC] add documentation for peers section + - [MINOR] checks: add support for LDAPv3 health checks + - [MINOR] add better support to "mysql-check" + - [BUG] Restore info about available active/backup servers + - [CONTRIB] Update haproxy.pl + - [CONTRIB] Update Cacti Tempates + - [CONTRIB] add templates for Cacti. + - [BUG] http: don't consider commas as a header delimitor within quotes + - [MINOR] support a global jobs counter + - [DOC] add a summary about cookie incompatibilities between specs and browsers + - [DOC] fix description of cookie "insert" and "indirect" modes + - [MEDIUM] http: fix space handling in the request cookie parser + - [MEDIUM] http: fix space handling in the response cookie parser + - [DOC] fix typo in the queue() definition (backend, not frontend) + - [BUG] deinit: unbind listeners before freeing them + - [BUG] stream_interface: only call si->release when both dirs are closed + - [MEDIUM] buffers: rework the functions to exchange between SI and buffers + - [DOC] fix typo in the avg_queue() and be_conn() definition (backend, not frontend) + - [MINOR] halog: add '-tc' to sort by termination codes + - [MINOR] halog: skip non-traffic logs for -st and -tc + - [BUG] stream_sock: cleanly disable the listener in case of resource shortage + - [BUILD] stream_sock: previous fix lacked the #include, causing a warning. + - [DOC] bind option is "defer-accept", not "defer_accept" + - [DOC] missing index entry for http-check send-state + - [DOC] tcp-request inspect-delay is for backends too + - [BUG] ebtree: string_equal_bits() could return garbage on identical strings + - [BUG] stream_sock: try to flush any extra pending request data after a POST + - [BUILD] proto_http: eliminate some build warnings with gcc-2.95 + - [MEDIUM] make it possible to combine http-pretend-keepalived with httpclose + - [MEDIUM] tcp-request : don't wait for inspect-delay to expire when the buffer is full + - [MEDIUM] checks: add support for HTTP contents lookup + - [TESTS] add test-check-expect to test various http-check methods + - [MINOR] global: add "tune.chksize" to change the default check buffer size + - [MINOR] cookie: add options "maxidle" and "maxlife" + - [MEDIUM] cookie: support client cookies with some contents appended to their value + - [MINOR] http: make some room in the transaction flags to extend cookies + - [MINOR] cookie: add the expired (E) and old (O) flags for request cookies + - [MEDIUM] cookie: reassign set-cookie status flags to store more states + - [MINOR] add encode/decode function for 30-bit integers from/to base64 + - [MEDIUM] cookie: check for maxidle and maxlife for incoming dated cookies + - [MEDIUM] cookie: set the date in the cookie if needed + - [DOC] document the cookie maxidle and maxlife parameters + - [BUG] checks: don't log backend down for all zero-weight servers + - [MEDIUM] checks: set server state to one state from failure when leaving maintenance + - [BUG] config: report correct keywords for "observe" + - [MINOR] checks: ensure that we can inherit binary checks from the defaults section + - [MINOR] acl: add the http_req_first match + - [DOC] fix typos about bind-process syntax + - [BUG] cookie: correctly unset default cookie parameters + - [MINOR] cookie: add support for the "preserve" option + - [BUG] ebtree: fix duplicate strings insertion + - [CONTRIB] halog: report per-url counts, errors and times + - [CONTRIB] halog: minor speed improvement in timer parser + - [MINOR] buffers: add a new request analyser flag for PROXY mode + - [MINOR] listener: add the "accept-proxy" option to the "bind" keyword + - [MINOR] standard: add read_uint() to parse a delimited unsigned integer + - [MINOR] standard: change arg type from const char* to char* + - [MINOR] frontend: add a new analyser to parse a proxied connection + - [MEDIUM] session: call the frontend_decode_proxy analyser on proxied connections + - [DOC] add the proxy protocol's specifications + - [DOC] document the 'accept-proxy' bind option + - [MINOR] cfgparse: report support of for the 'bind' statements + - [DOC] add references to unix socket handling + - [MINOR] move MAXPATHLEN definition to compat.h + - [MEDIUM] unix sockets: cleanup the error reporting path + - [BUG] session: don't stop forwarding of data upon last packet + - [CLEANUP] accept: replace some inappropriate Alert() calls with send_log() + - [BUILD] peers: shut a printf format warning (key_size is a size_t) + - [BUG] accept: don't close twice upon error + - [OPTIM] session: don't recheck analysers when buffer flags have not changed + - [OPTIM] stream_sock: don't clear FDs that are already cleared + - [BUG] proto_tcp: potential bug on pattern fetch dst and dport + +2010/08/28 : 1.5-dev2 + - [MINOR] startup: release unused structs after forking + - [MINOR] startup: don't wait for nothing when no old pid remains + - [CLEANUP] reference product branch 1.5 + - [MEDIUM] signals: add support for registering functions and tasks + - [MEDIUM] signals: support redistribution of signal zero when stopping + - [BUG] http: don't set auto_close if more data are expected + +2010/08/25 : 1.5-dev1 + - [BUG] stats: session rate limit gets garbaged in the stats + - [DOC] mention 'option http-server-close' effect in Tq section + - [DOC] summarize and highlight persistent connections behaviour + - [DOC] add configuration samples + - [BUG] http: dispatch and http_proxy modes were broken for a long time + - [BUG] http: the transaction must be initialized even in TCP mode + - [BUG] tcp: dropped connections must be counted as "denied" not "failed" + - [BUG] consistent hash: balance on all servers, not only 2 ! + - [CONTRIB] halog: report per-server status codes, errors and response times + - [BUG] http: the transaction must be initialized even in TCP mode (part 2) + - [BUG] client: always ensure to zero rep->analysers + - [BUG] session: clear BF_READ_ATTACHED before next I/O + - [BUG] http: automatically close response if req is aborted + - [BUG] proxy: connection rate limiting was eating lots of CPU + - [BUG] http: report correct flags in case of client aborts during body + - [TESTS] refine non-regression tests and add 4 new tests + - [BUG] debug: wrong pointer was used to report a status line + - [BUG] debug: correctly report truncated messages + - [DOC] document the "dispatch" keyword + - [BUG] stick_table: fix possible memory leak in case of connection error + - [CLEANUP] acl: use 'L6' instead of 'L4' in ACL flags relying on contents + - [MINOR] accept: count the incoming connection earlier + - [CLEANUP] tcp: move some non tcp-specific layer6 processing out of proto_tcp + - [CLEANUP] client: move some ACLs away to their respective locations + - [CLEANUP] rename client -> frontend + - [MEDIUM] separate protocol-level accept() from the frontend's + - [MINOR] proxy: add a list to hold future layer 4 rules + - [MEDIUM] config: parse tcp layer4 rules (tcp-request accept/reject) + - [MEDIUM] tcp: check for pure layer4 rules immediately after accept() + - [OPTIM] frontend: tell the compiler that errors are unlikely to occur + - [MEDIUM] frontend: check for LI_O_TCP_RULES in the listener + - [MINOR] frontend: only check for monitor-net rules if LI_O_CHK_MONNET is set + - [CLEANUP] buffer->cto is not used anymore + - [MEDIUM] session: finish session establishment sequence in with I/O handlers + - [MEDIUM] session: initialize server-side timeouts after connect() + - [MEDIUM] backend: initialize the server stream_interface upon connect() + - [MAJOR] frontend: don't initialize the server-side stream_int anymore + - [MEDIUM] session: move the conn_retries attribute to the stream interface + - [MEDIUM] session: don't assign conn_retries upon accept() anymore + - [MINOR] frontend: rely on the frontend and not the backend for INDEPSTR + - [MAJOR] frontend: reorder the session initialization upon accept + - [MINOR] proxy: add an accept() callback for the application layer + - [MAJOR] frontend: split accept() into frontend_accept() and session_accept() + - [MEDIUM] stats: rely on the standard session_accept() function + - [MINOR] buffer: refine the flags that may wake an analyser up. + - [MINOR] stream_sock: don't dereference a non-existing frontend + - [MINOR] session: differenciate between accepted connections and received connections + - [MEDIUM] frontend: count the incoming connection earlier + - [MINOR] frontend: count denied TCP requests separately + - [CLEANUP] stick_table: add/clarify some comments + - [BUILD] memory: add a few missing parenthesis to the pool management macros + - [MINOR] stick_table: add support for variable-sized data + - [CLEANUP] stick_table: rename some stksess struct members to avoid confusion + - [CLEANUP] stick_table: move pattern to key functions to stick_table.c + - [MEDIUM] stick_table: add room for extra data types + - [MINOR] stick_table: add support for "conn_cum" data type. + - [MEDIUM] stick_table: don't overwrite data when storing an entry + - [MINOR] config: initialize stick tables after all the parsing + - [MINOR] stick_table: provide functions to return stksess data from a type + - [MEDIUM] stick_table: move the server ID to a generic data type + - [MINOR] stick_table: enable it for frontends too + - [MINOR] stick_table: export the stick_table_key + - [MINOR] tcp: add per-source connection rate limiting + - [MEDIUM] stick_table: separate storage and update of session entries + - [MEDIUM] stick-tables: add a reference counter to each entry + - [MINOR] session: add a pointer to the tracked counters for the source + - [CLEANUP] proto_tcp: make the config parser a little bit more flexible + - [BUG] config: report the correct proxy type in tcp-request errors + - [MINOR] config: provide a function to quote args in a more friendly way + - [BUG] stick_table: the fix for the memory leak caused a regression + - [MEDIUM] backend: support servers on 0.0.0.0 + - [BUG] stick-table: correctly refresh expiration timers + - [MEDIUM] stream-interface: add a ->release callback + - [MINOR] proxy: add a "parent" member to the structure + - [MEDIUM] session: make it possible to call an I/O handler on both SI + - [MINOR] tools: add a fast div64_32 function + - [MINOR] freq_ctr: add new types and functions for periods different from 1s + - [MINOR] errors: provide new status codes for config parsing functions + - [BUG] http: denied requests must not be counted as denied resps in listeners + - [MINOR] tools: add a get_std_op() function to parse operators + - [MEDIUM] acl: make use of get_std_op() to parse intger ranges + - [MAJOR] stream_sock: better wakeup conditions on read() + - [BUG] session: analysers must be checked when SI state changes + - [MINOR] http: reset analysers to listener's, not frontend's + - [MEDIUM] session: support "tcp-request content" rules in backends + - [BUILD] always match official tags when doing git-tar + - [MAJOR] stream_interface: fix the wakeup conditions for embedded iohandlers + - [MEDIUM] buffer: make buffer_feed* support writing non-contiguous chunks + - [MINOR] tcp: src_count acl does not have a permanent result + - [MAJOR] session: add track-counters to track counters related to the session + - [MINOR] stick-table: provide a table lookup function + - [MINOR] stick-table: use suffix "_cnt" for cumulated counts + - [MEDIUM] session: move counter ACL fetches from proto_tcp + - [MEDIUM] session: add concurrent connections counter + - [MEDIUM] session: add data in and out volume counters + - [MINOR] session: add the trk_conn_cnt ACL keyword to track connection counts + - [MEDIUM] session-counters: automatically update tracked connection count + - [MINOR] session: add the trk_conn_cur ACL keyword to track concurrent connection + - [MINOR] session: add trk_kbytes_* ACL keywords to track data size + - [MEDIUM] session: add a counter on the cumulated number of sessions + - [MINOR] config: support a comma-separated list of store data types in stick-table + - [MEDIUM] stick-tables: add support for arguments to data_types + - [MEDIUM] stick-tables: add stored data argument type checking + - [MEDIUM] session counters: add conn_rate and sess_rate counters + - [MEDIUM] session counters: add bytes_in_rate and bytes_out_rate counters + - [MINOR] stktable: add a stktable_update_key() function + - [MINOR] session-counters: add a general purpose counter (gpc0) + - [MEDIUM] session-counters: add HTTP req/err tracking + - [MEDIUM] stats: add "show table []" to dump a stick-table + - [MEDIUM] stats: add "clear table key " to clear table entries + - [CLEANUP] stick-table: declare stktable_data_types as extern + - [MEDIUM] stick-table: make use of generic types for stored data + - [MINOR] stats: correctly report errors on "show table" and "clear table" + - [MEDIUM] stats: add the ability to dump table entries matching criteria + - [DOC] configuration: document all the new tracked counters + - [DOC] stats: document "show table" and "clear table" + - [MAJOR] session-counters: split FE and BE track counters + - [MEDIUM] tcp: accept the "track-counters" in "tcp-request content" rules + - [MEDIUM] session counters: automatically remove expired entries. + - [MEDIUM] config: replace 'tcp-request ' with "tcp-request connection" + - [MEDIUM] session-counters: make it possible to count connections from frontend + - [MINOR] session-counters: use "track-sc{1,2}" instead of "track-{fe,be}-counters" + - [MEDIUM] session-counters: correctly unbind the counters tracked by the backend + - [CLEANUP] stats: use stksess_kill() to remove table entries + - [DOC] update the references to session counters and to tcp-request connection + - [DOC] cleanup: split a few long lines + - [MEDIUM] http: forward client's close when abortonclose is set + - [BUG] queue: don't dequeue proxy-global requests on disabled servers + - [BUG] stats: global stats timeout may be specified before stats socket. + - [BUG] conf: add tcp-request content rules to the correct list + +2010/05/23 : 1.5-dev0 + - exact copy of 1.4.6 + +2010/05/16 : 1.4.6 + - [BUILD] ebtree: update to v6.0.1 to remove references to dprintf() + - [CLEANUP] acl: make use of eb_is_empty() instead of open coding the tree's emptiness test + - [MINOR] acl: add srv_is_up() to check that a specific server is up or not + - [DOC] add a few precisions about the use of RDP cookies + +2010/05/13 : 1.4.5 + - [DOC] report minimum kernel version for tproxy in the Makefile + - [MINOR] add the "ignore-persist" option to conditionally ignore persistence + - [DOC] add the "ignore-persist" option to conditionally ignore persistence + - [DOC] fix ignore-persist/force-persist documentation + - [BUG] cttproxy: socket fd leakage in check_cttproxy_version + - [DOC] doc/configuration.txt: fix typos + - [MINOR] option http-pretend-keepalive is both for FEs and BEs + - [MINOR] fix possible crash in debug mode with invalid responses + - [MINOR] halog: add support for statisticts on status codes + - [OPTIM] halog: use a faster zero test in fgets() + - [OPTIM] halog: minor speedup by using unlikely() + - [OPTIM] halog: speed up fgets2-64 by about 10% + - [DOC] refresh the README file and merge the CONTRIB file into it + - [MINOR] acl: support loading values from files + - [MEDIUM] ebtree: upgrade to version 6.0 + - [MINOR] acl trees: add flags and union members to store values in trees + - [MEDIUM] acl: add ability to insert patterns in trees + - [MEDIUM] acl: add tree-based lookups of exact strings + - [MEDIUM] acl: add tree-based lookups of networks + - [MINOR] acl: ignore empty lines and comments in pattern files + - [MINOR] stick-tables: add support for "stick on hdr" + +2010/04/07 : 1.4.4 + - [BUG] appsession should match the whole cookie name + - [CLEANUP] proxy: move PR_O_SSL3_CHK to options2 to release one flag + - [MEDIUM] backend: move the transparent proxy address selection to backend + - [MINOR] add very fast IP parsing functions + - [MINOR] add new tproxy flags for dynamic source address binding + - [MEDIUM] add ability to connect to a server from an IP found in a header + - [BUILD] config: last patch breaks build without CONFIG_HAP_LINUX_TPROXY + - [MINOR] http: make it possible to pretend keep-alive when doing close + - [MINOR] config: report "default-server" instead of "(null)" in error messages + +2010/03/30 : 1.4.3 + - [CLEANUP] stats: remove printf format warning in stats_dump_full_sess_to_buffer() + - [MEDIUM] session: better fix for connection to servers with closed input + - [DOC] indicate in the doc how to bind to port ranges + - [BUG] backend: L7 hashing must not be performed on incomplete requests + - [TESTS] add a simple program to test connection resets + - [MINOR] cli: "show errors" should display "backend " when backend was not used + - [MINOR] config: emit warnings when HTTP-only options are used in TCP mode + - [MINOR] config: allow "slowstart 0s" + - [BUILD] 'make tags' did not consider files ending in '.c' + - [MINOR] checks: add the ability to disable a server in the config + +2010/03/17 : 1.4.2 + - [CLEANUP] product branch update + - [DOC] Some more documentation cleanups + - [BUG] clf logs segfault when capturing a non existant header + - [OPTIM] config: only allocate check buffer when checks are enabled + - [MEDIUM] checks: support multi-packet health check responses + - [CLEANUP] session: remove duplicate test + - [BUG] http: don't wait for response data to leave buffer is client has left + - [MINOR] proto_uxst: set accept_date upon accept() to the wall clock time + - [MINOR] stats: don't send empty lines in "show errors" + - [MINOR] stats: make the data dump function reusable for other purposes + - [MINOR] stats socket: add show sess to dump details about a session + - [BUG] stats: connection reset counters must be plain ascii, not HTML + - [BUG] url_param hash may return a down server + - [MINOR] force null-termination of hostname + - [MEDIUM] connect to servers even when the input has already been closed + - [BUG] don't merge anonymous ACLs ! + - [BUG] config: fix endless loop when parsing "on-error" + - [MINOR] http: don't mark a server as failed when it returns 501/505 + - [OPTIM] checks: try to detect the end of response without polling again + - [BUG] checks: don't report an error when recv() returns an error after data + - [BUG] checks: don't abort when second poll returns an error + - [MINOR] checks: make shutdown() silently fail + - [BUG] http: fix truncated responses on chunk encoding when size divides buffer size + - [BUG] init: unconditionally catch SIGPIPE + - [BUG] checks: don't wait for a close to start parsing the response + +2010/03/04 : 1.4.1 + - [BUG] Clear-cookie path issue + - [DOC] fix typo on stickiness rules + - [BUILD] fix BSD and OSX makefiles for missing files + - [BUILD] includes order breaks OpenBSD build + - [BUILD] fix some build warnings on Solaris with is* macros + - [BUG] logs: don't report "last data" when we have just closed after an error + - [BUG] logs: don't report "proxy request" when server closes early + - [BUILD] fix platform-dependant build issues related to crypt() + - [STATS] count transfer aborts caused by client and by server + - [STATS] frontend requests were not accounted for failed requests + - [MINOR] report total number of processed connections when stopping a proxy + - [DOC] be more clear about the limitation to one single monitor-net entry + +2010/02/26 : 1.4.0 + - [MINOR] stats: report maint state for tracking servers too + - [DOC] fix summary to add pattern extraction + - [DOC] Documentation cleanups + - [BUG] cfgparse memory leak and missing free calls in deinit() + - [BUG] pxid/puid/luid: don't shift IDs when some of them are forced + - [EXAMPLES] add auth.cfg + - [BUG] uri_auth: ST_SHLGNDS should be 0x00000008 not 0x0000008 + - [BUG] uri_auth: do not attemp to convert uri_auth -> http-request more than once + - [BUILD] auth: don't use unnamed unions + - [BUG] config: report unresolvable host names as errors + - [BUILD] fix build breakage with DEBUG_FULL + - [DOC] fix a typo about timeout check and clarify the explanation. + - [MEDIUM] http: don't use trash to realign large buffers + - [STATS] report HTTP requests (total and rate) in frontends + - [STATS] separate frontend and backend HTTP stats + - [MEDIUM] http: revert to use a swap buffer for realignment + - [MINOR] stats: report the request rate in frontends as cell titles + - [MINOR] stats: mark areas with an underline when tooltips are available + - [DOC] reorder some entries to maintain the alphabetical order + - [DOC] cleanup of the keyword matrix + +2010/02/02 : 1.4-rc1 + - [MEDIUM] add a maintenance mode to servers + - [MINOR] http-auth: last fix was wrong + - [CONTRIB] add base64rev-gen.c that was used to generate the base64rev table. + - [MINOR] Base64 decode + - [MINOR] generic auth support with groups and encrypted passwords + - [MINOR] add ACL_TEST_F_NULL_MATCH + - [MINOR] http-request: allow/deny/auth support for frontend/backend/listen + - [MINOR] acl: add http_auth and http_auth_group + - [MAJOR] use the new auth framework for http stats + - [DOC] add info about userlists, http-request and http_auth/http_auth_group acls + - [STATS] make it possible to change a CLI connection timeout + - [BUG] patterns: copy-paste typo in type conversion arguments + - [MINOR] pattern: make the converter more flexible by supporting void* and int args + - [MINOR] standard: str2mask: string to netmask converter + - [MINOR] pattern: add support for argument parsers for converters + - [MINOR] pattern: add the "ipmask()" converting function + - [MINOR] config: off-by-one in "stick-table" after list of converters + - [CLEANUP] acl, patterns: make use of my_strndup() instead of malloc+memcpy + - [BUG] restore accidentely removed line in last patch ! + - [MINOR] checks: make the HTTP check code add the CRLF itself + - [MINOR] checks: add the server's status in the checks + - [BUILD] halog: make without arch-specific optimizations + - [BUG] halog: fix segfault in case of empty log in PCT mode (cherry picked from commit fe362fe4762151d209b9656639ee1651bc2b329d) + - [MINOR] http: disable keep-alive when process is going down + - [MINOR] acl: add build_acl_cond() to make it easier to add ACLs in config + - [CLEANUP] config: use build_acl_cond() instead of parse_acl_cond() + - [CLEANUP] config: use warnif_cond_requires_resp() to check for bad ACLs + - [MINOR] prepare req_*/rsp_* to receive a condition + - [CLEANUP] config: specify correct const char types to warnif_* functions + - [MEDIUM] config: factor out the parsing of 20 req*/rsp* keywords + - [MEDIUM] http: make the request filter loop check for optional conditions + - [MEDIUM] http: add support for conditional request filter execution + - [DOC] add some build info about the AIX platform (cherry picked from commit e41914c77edbc40aebf827b37542d37d758e371e) + - [MEDIUM] http: add support for conditional request header addition + - [MEDIUM] http: add support for conditional response header rewriting + - [DOC] add some missing ACLs about response header matching + - [MEDIUM] http: add support for proxy authentication + - [MINOR] http-auth: make the 'unless' keyword work as expected + - [CLEANUP] config: use build_acl_cond() to simplify http-request ACL parsing + - [MEDIUM] add support for anonymous ACLs + - [MEDIUM] http: switch to tunnel mode after status 101 responses + - [MEDIUM] http: stricter processing of the CONNECT method + - [BUG] config: reset check request to avoid double free when switching to ssl/sql + - [MINOR] config: fix too large ssl-hello-check message. + - [BUG] fix error response in case of server error + +2010/01/25 : 1.4-dev8 + - [CLEANUP] Keep in sync "defaults" support between documentation and code + - [MEDIUM] http: add support for Proxy-Connection header + - [CRITICAL] buffers: buffer_insert_line2 must not change the ->w entry + - [MINOR] http: remove a copy-paste typo in transaction cleaning + - [BUG] http: trim any excess buffer data when recycling a connection + +2010/01/25 : 1.4-dev7 + - [BUG] appsession: possible memory leak in case of out of memory condition + - [MINOR] config: don't accept 'appsession' in defaults section + - [MINOR] Add function to parse a size in configuration + - [MEDIUM] Add stick table (persistence) management functions and types + - [MEDIUM] Add pattern fetch management types and functions + - [MEDIUM] Add src dst and dport pattern fetches. + - [MEDIUM] Add stick table configuration and init. + - [MEDIUM] Add stick and store rules analysers. + - [MINOR] add option "mysql-check" to use MySQL health checks + - [BUG] health checks: fix requeued message + - [OPTIM] remove SSP_O_VIA and SSP_O_STATUS + - [BUG] checks: fix newline termination + - [MINOR] acl: add fe_id/so_id to match frontend's and socket's id + - [BUG] appsession's sessid must be reset at end of transaction + - [BUILD] appsession did not build anymore under gcc-2.95 + - [BUG] server redirection used an uninitialized string. + - [MEDIUM] http: fix handling of message pointers + - [MINOR] http: fix double slash prefix with server redirect + - [MINOR] http redirect: add the ability to append a '/' to the URL + - [BUG] stream_interface: fix retnclose and remove cond_close + - [MINOR] http redirect: don't explicitly state keep-alive on 1.1 + - [MINOR] http: move appsession 'sessid' from session to http_txn + - [OPTIM] reorder http_txn to optimize cache lines placement + - [MINOR] http: differentiate waiting for new request and waiting for a complete requst + - [MINOR] http: add a separate "http-keep-alive" timeout + - [MINOR] config: remove undocumented and buggy 'timeout appsession' + - [DOC] fix various too large lines + - [DOC] remove several trailing spaces + - [DOC] add the doc about stickiness + - [BUILD] remove a warning in standard.h on AIX + - [BUG] checks: chars are unsigned on AIX, check was always true + - [CLEANUP] stream_sock: MSG_NOSIGNAL is only for send(), not recv() + - [BUG] check: we must not check for error before reading a response + - [BUG] buffers: remove remains of wrong obsolete length check + - [OPTIM] stream_sock: don't shutdown(write) when the socket is in error + - [BUG] http: don't count req errors on client resets or t/o during keep-alive + - [MEDIUM] http: don't switch to tunnel mode upon close + - [DOC] add documentation about connection header processing + - [MINOR] http: add http_remove_header2() to remove a header value. + - [MINOR] tools: add a "word_match()" function to match words and ignore spaces + - [MAJOR] http: rework request Connection header handling + - [MAJOR] http: rework response Connection header handling + - [MINOR] add the ability to force kernel socket buffer size. + - [BUG] http_server_error() must not purge a previous pending response + - [OPTIM] http: don't delay response if next request is incomplete + - [MINOR] add the "force-persist" statement to force persistence on down servers + - [MINOR] http: logs must report persistent connections to down servers + - [BUG] buffer_replace2 must never change the ->w entry + +2010/01/08 : 1.4-dev6 + - [BUILD] warning in stream_interface.h + - [BUILD] warning ultoa_r returns char * + - [MINOR] hana: only report stats if it is enabled + - [MINOR] stats: add "a link" & "a href" for sockets + - [MINOR]: stats: add show-legends to report additional informations + - [MEDIUM] default-server support + - [BUG]: add 'observer', 'on-error', 'error-limit' to supported options list + - [MINOR] stats: add href to tracked server + - [BUG] stats: show UP/DOWN status also in tracking servers + - [DOC] Restore ability to search a keyword at the beginning of a line + - [BUG] stats: cookie should be reported under backend not under proxy + - [BUG] cfgparser/stats: fix error message + - [BUG] http: disable auto-closing during chunk analysis + - [BUG] http: fix hopefully last closing issue on data forwarding + - [DEBUG] add an http_silent_debug function to debug HTTP states + - [MAJOR] http: fix again the forward analysers + - [BUG] http_process_res_common() must not skip the forward analyser + - [BUG] http: some possible missed close remain in the forward chain + - [BUG] http: redirect needed to be updated after recent changes + - [BUG] http: don't set no-linger on response in case of forced close + - [MEDIUM] http: restore the original behaviour of option httpclose + - [TESTS] add a file to test various connection modes + - [BUG] http: check options before the connection header + - [MAJOR] session: fix the order by which the analysers are run + - [MEDIUM] session: also consider request analysers added during response + - [MEDIUM] http: make safer use of the DONT_READ and AUTO_CLOSE flags + - [BUG] http: memory leak with captures when using keep-alive + - [BUG] http: fix for capture memory leak was incorrect + - [MINOR] http redirect: use proper call to return last response + - [MEDIUM] http: wait for some flush of the response buffer before a new request + - [MEDIUM] session: limit the number of analyser loops + +2010/01/03 : 1.4-dev5 + - [MINOR] server tracking: don't care about the tracked server's mode + - [MEDIUM] appsession: add "len", "prefix" and "mode" options + - [MEDIUM] appsession: add the "request-learn" option + - [BUG] Configuration parser bug when escaping characters + - [MINOR] CSS & HTML fun + - [MINOR] Collect & provide http response codes received from servers + - [BUG] Fix silly typo: hspr_other -> hrsp_other + - [MINOR] Add "a name" to stats page + - [MINOR] add additional "a href"s to stats page + - [MINOR] Collect & provide http response codes for frontends, fix backends + - [DOC] some small spell fixes and unifications + - [MEDIUM] Decrease server health based on http responses / events, version 3 + - [BUG] format '%d' expects type 'int', but argument 5 has type 'long int' + - [BUG] config: fix erroneous check on cookie domain names, again + - [BUG] Healthchecks: get a proper error code if connection cannot be completed immediately + - [DOC] trivial fix for man page + - [MINOR] config: report all supported options for the "bind" keyword + - [MINOR] tcp: add support for the defer_accept bind option + - [MINOR] unix socket: report the socket path in case of bind error + - [CONTRIB] halog: support searching by response time + - [DOC] add a reminder about obsolete documents + - [DOC] point to 1.4 doc, not 1.3 + - [DOC] option tcp-smart-connect was missing from index + - [MINOR] http: detect connection: close earlier + - [CLEANUP] sepoll: clean up the fd_clr/fd_set functions + - [OPTIM] move some rarely used fields out of fdtab + - [MEDIUM] fd: merge fd_list into fdtab + - [MAJOR] buffer: flag BF_DONT_READ to disable reads when not required + - [MINOR] http: add new transaction flags for keep-alive and content-length + - [MEDIUM] http request: parse connection, content-length and transfer-encoding + - [MINOR] http request: update the TX_SRV_CONN_KA flag on rewrite + - [MINOR] http request: simplify the test of no-data + - [MEDIUM] http request: simplify POST length detection + - [MEDIUM] http request: make use of pre-parsed transfer-encoding header + - [MAJOR] http: create the analyser which waits for a response + - [MINOR] http: pre-set the persistent flags in the transaction + - [MEDIUM] http response: check body length and set transaction flags + - [MINOR] http response: update the TX_CLI_CONN_KA flag on rewrite + - [MINOR] http: remove the last call to stream_int_return + - [IMPORT] import ebtree v5.0 into directory ebtree/ + - [MEDIUM] build: switch ebtree users to use new ebtree version + - [CLEANUP] ebtree: remove old unused files + - [BUG] definitely fix regparm issues between haproxy core and ebtree + - [CLEANUP] ebtree: cast to char * to get rid of gcc warning + - [BUILD] missing #ifndef in ebmbtree.h + - [BUILD] missing #ifndef in ebsttree.h + - [MINOR] tools: add hex2i() function to convert hex char to int + - [MINOR] http: create new MSG_BODY sub-states + - [BUG] stream_sock: BUF_INFINITE_FORWARD broke splice on 64-bit platforms + - [DOC] option is "defer-accept", not "defer_accept" + - [MINOR] http: keep pointer to beginning of data + - [BUG] x-original-to: name was not set in default instance + - [MINOR] http: detect tunnel mode and set it in the session + - [BUG] config: fix error message when config file is not found + - [BUG] config: fix wrong handling of too large argument count + - [BUG] config: disable 'option httplog' on TCP proxies + - [BUG] config: fix erroneous check on cookie domain names + - [BUG] config: cookie domain was ignored in defaults sections + - [MINOR] config: support passing multiple "domain" statements to cookies + - [MINOR] ebtree: add functions to lookup non-null terminated strings + - [MINOR] config: don't report error on all subsequent files on failure + - [BUG] second fix for the printf format warning + - [BUG] check_post: limit analysis to the buffer length + - [MEDIUM] http: process request body in a specific analyser + - [MEDIUM] backend: remove HTTP POST parsing from get_server_ph_post() + - [MAJOR] http: completely process the "connection" header + - [MINOR] http: only consider chunk encoding with HTTP/1.1 + - [MAJOR] buffers: automatically compute the maximum buffer length + - [MINOR] http: move the http transaction init/cleanup code to proto_http + - [MINOR] http: move 1xx handling earlier to eliminate a lot of ifs + - [MINOR] http: introduce a new synchronisation state : HTTP_MSG_DONE + - [MEDIUM] http: rework chunk-size parser + - [MEDIUM] http: add a new transaction flags indicating if we know the transfer length + - [MINOR] buffers: add buffer_ignore() to skip some bytes + - [BUG] http: offsets are relative to the buffer, not to ->som + - [MEDIUM] http: automatically re-aling request buffer + - [BUG] http: body parsing must consider the start of message + - [MINOR] new function stream_int_cond_close() + - [MAJOR] http: implement body parser + - [BUG] http: typos on several unlikely() around header insertion + - [BUG] stream_sock: wrong max computation on recv + - [MEDIUM] http: rework the buffer alignment logic + - [BUG] buffers: wrong size calculation for displaced data + - [MINOR] stream_sock: prepare for closing when all pending data are sent + - [MEDIUM] http: add two more states for the closing period + - [MEDIUM] http: properly handle "option forceclose" + - [MINOR] stream_sock: add SI_FL_NOLINGER for faster close + - [MEDIUM] http: make forceclose use SI_FL_NOLINGER + - [MEDIUM] session: set SI_FL_NOLINGER when aborting on write timeouts + - [MEDIUM] http: add some SI_FL_NOLINGER around server errors + - [MINOR] config: option forceclose is valid in frontends too + - [BUILD] halog: insufficient include path in makefile + - [MEDIUM] http: make the analyser not rely on msg being initialized anymore + - [MEDIUM] http: make the parsers able to wait for a buffer flush + - [MAJOR] http: add support for option http-server-close + - [BUG] http: ensure we abort data transfer on write error + - [BUG] last fix was overzealous and disabled server-close + - [BUG] http: fix erroneous trailers size computation + - [MINOR] stream_sock: enable MSG_MORE when forwarding finite amount of data + - [OPTIM] http: set MSG_MORE on response when a pipelined request is pending + - [BUG] http: redirects were broken by chunk changes + - [BUG] http: the request URI pointer is relative to the buffer + - [OPTIM] http: don't immediately enable reading on request + - [MINOR] http: move redirect messages to HTTP/1.1 with a content-length + - [BUG] http: take care of errors, timeouts and aborts during the data phase + - [MINOR] http: don't wait for sending requests to the server + - [MINOR] http: make the conditional redirect support keep-alive + - [BUG] http: fix cookie parser to support spaces and commas in values + - [MINOR] config: some options were missing for "redirect" + - [MINOR] redirect: add support for unconditional rules + - [MINOR] config: centralize proxy struct initialization + - [MEDIUM] config: remove the limitation of 10 reqadd/rspadd statements + - [MEDIUM] config: remove the limitation of 10 config files + - [CLEANUP] http: remove a remaining impossible condition + - [OPTIM] http: optimize a bit the construct of the forward loops + +2009/10/12 : 1.4-dev4 + - [DOC] add missing rate_lim and rate_max + - [MAJOR] struct chunk rework + - [MEDIUM] Health check reporting code rework + health logging, v3 + - [BUG] check if rise/fall has an argument and it is > 0 + - [MINOR] health checks logging unification + - [MINOR] add "description", "node" and show-node"/"show-desc", remove "node-name", v2 + - [MINOR] Allow dots in show-node & add "white-space: nowrap" in th.pxname. + - [DOC] Add information about http://haproxy.1wt.eu/contrib.html + - [MINOR] Introduce include/types/counters.h + - [CLEANUP] Move counters to dedicated structures + - [MINOR] Add "clear counters" to clear statistics counters + - [MEDIUM] Collect & provide separate statistics for sockets, v2 + - [BUG] Fix NULL pointer dereference in stats_check_uri_auth(), v2 + - [MINOR] acl: don't report valid acls as potential mistakes + - [MINOR] Add cut_crlf(), ltrim(), rtrim() and alltrim() + - [MINOR] Add chunk_htmlencode and chunk_asciiencode + - [MINOR] Capture & display more data from health checks, v2 + - [BUG] task.c: don't assing last_timer to node-less entries + - [BUG] http stats: large outputs sometimes got some parts chopped off + - [MINOR] backend: export some functions to recount servers + - [MINOR] backend: uninline some LB functions + - [MINOR] include time.h from freq_ctr.h as is uses "now". + - [CLEANUP] backend: move LB algos to individual files + - [MINOR] lb_map: reorder code in order to ease integration of new hash functions + - [CLEANUP] proxy: move last lb-specific bits to their respective files + - [MINOR] backend: separate declarations of LB algos from their lookup method + - [MINOR] backend: reorganize the LB algorithm selection + - [MEDIUM] backend: introduce the "static-rr" LB algorithm + - [MINOR] report list of supported pollers with -vv + - [DOC] log-health-checks is an option, not a directive + - [MEDIUM] new option "independant-streams" to stop updating read timeout on writes + - [BUG] stats: don't call buffer_shutw(), but ->shutw() instead + - [MINOR] stats: strip CR and LF from the input command line + - [BUG] don't refresh timeouts late after detected activity + - [MINOR] stats_dump_errors_to_buffer: use buffer_feed_chunk() + - [MINOR] stats_dump_sess_to_buffer: use buffer_feed_chunk() + - [MINOR] stats: make stats_dump_raw_to_buffer() use buffer_feed_chunk + - [MEDIUM] stats: don't use s->ana_state anymore + - [MINOR] remove now obsolete ana_state from the session struct + - [MEDIUM] stats: make HTTP stats use an I/O handler + - [MEDIUM] stream_int: adjust WAIT_ROOM handling + - [BUG] config: look for ID conflicts in all sockets, not only last ones. + - [MINOR] config: reference file and line with any listener/proxy/server declaration + - [MINOR] config: report places of duplicate names or IDs + - [MINOR] config: add pointer to file name in block/redirect/use_backend/monitor rules + - [MINOR] tools: add a new get_next_id() function + - [MEDIUM] config: automatically find unused IDs for proxies, servers and listeners + - [OPTIM] counters: move some max numbers to the counters struct + - [BUG] counters: fix segfault on missing counters for a listener + - [MEDIUM] backend: implement consistent hashing variation + - [MINOR] acl: add fe_conn, be_conn, queue, avg_queue + - [MINOR] stats: use 'clear counters all' to clear all values + - [MEDIUM] add access restrictions to the stats socket + - [MINOR] buffers: add buffer_feed2() and make buffer_feed() measure string length + - [MINOR] proxy: provide function to retrieve backend/server pointers + - [MINOR] add the "initial weight" to the server struct. + - [MEDIUM] stats: add the "get weight" command to report a server's weight + - [MEDIUM] stats: add the "set weight" command + - [BUILD] add a 'make tags' target + - [MINOR] stats: add support for numeric IDs in set weight/get weight + - [MINOR] stats: use a dedicated state to output static data + - [OPTIM] stats: check free space before trying to print + +2009/09/24 : 1.4-dev3 + - [BUILD] compilation of haproxy-1.4-dev2 on FreeBSD + - [MEDIUM] Collect & show information about last health check, v3 + - [MINOR] export the hostname variable so that all the code can access it + - [MINOR] stats: add a new node-name setting + - [MEDIUM] remove old experimental tcpsplice option + - [BUILD] fix build for systems without SOL_TCP + - [MEDIUM] move connection establishment from backend to the SI. + - [MEDIUM] make the global stats socket part of a frontend + - [MEDIUM] session: account per-listener connections + - [MINOR] session: switch to established state if no connect function + - [MEDIUM] make the unix stats sockets use the generic session handler + - [CLEANUP] unix: remove uxst_process_session() + - [CLEANUP] move remaining stats sockets code to dumpstats + - [MINOR] move the initial task's nice value to the listener + - [MINOR] cleanup set_session_backend by using pre-computed analysers + - [MINOR] set s->srv_error according to the analysers + - [MEDIUM] set rep->analysers from fe and be analysers + - [MEDIUM] replace BUFSIZE with buf->size in computations + - [MEDIUM] make it possible to change the buffer size in the configuration + - [MEDIUM] report error on buffer writes larger than buffer size + - [MEDIUM] stream_interface: add and use ->update function to resync + - [CLEANUP] remove ifdef MSG_NOSIGNAL and define it instead + - [MEDIUM] remove TCP_CORK and make use of MSG_MORE instead + - [BUG] tarpit did not work anymore + - [MINOR] acl: add support for hdr_ip to match IP addresses in headers + - [MAJOR] buffers: fix misuse of the BF_SHUTW_NOW flag + - [MINOR] buffers: provide more functions to handle buffer data + - [MEDIUM] buffers: provide new buffer_feed*() function + - [MINOR] buffers: add peekchar and peekline functions for stream interfaces + - [MINOR] buffers: provide buffer_si_putchar() to send a char from a stream interface + - [BUG] buffer_forward() would not correctly consider data already scheduled + - [MINOR] buffers: add buffer_cut_tail() to cut only unsent data + - [MEDIUM] stream_interface: make use of buffer_cut_tail() to report errors + - [MAJOR] http: add support for HTTP 1xx informational responses + - [MINOR] buffers: inline buffer_si_putchar() + - [MAJOR] buffers: split BF_WRITE_ENA into BF_AUTO_CONNECT and BF_AUTO_CLOSE + - [MAJOR] buffers: fix the BF_EMPTY flag's meaning + - [BUG] stream_interface: SI_ST_CLO must have buffers SHUT + - [MINOR] stream_sock: don't set SI_FL_WAIT_DATA if BF_SHUTW_NOW is set + - [MEDIUM] add support for infinite forwarding + - [BUILD] stream_interface: fix conflicting declaration + - [BUG] buffers: buffer_forward() must not always clear BF_OUT_EMPTY + - [BUG] variable buffer size ignored at initialization time + - [MINOR] ensure that buffer_feed() and buffer_skip() set BF_*_PARTIAL + - [BUG] fix buffer_skip() and buffer_si_getline() to correctly handle wrap-arounds + - [MINOR] stream_interface: add SI_FL_DONT_WAKE flag + - [MINOR] stream_interface: add iohandler callback + - [MINOR] stream_interface: add functions to support running as internal/external tasks + - [MEDIUM] session: call iohandler for embedded tasks (applets) + - [MINOR] add a ->private member to the stream_interface + - [MEDIUM] stats: prepare the connection for closing before dumping + - [MEDIUM] stats: replace the stats socket analyser with an SI applet + +2009/08/09 : 1.4-dev2 + - [BUG] task: fix possible crash when some timeouts are not configured + - [BUG] log: option tcplog would log to global if no logger was defined + +2009/07/29 : 1.4-dev1 + - [MINOR] acl: add support for matching of RDP cookies + - [MEDIUM] add support for RDP cookie load-balancing + - [MEDIUM] add support for RDP cookie persistence + - [MINOR] add a new CLF log format + - [MINOR] startup: don't imply -q with -D + - [BUG] ensure that we correctly re-start old process in case of error + - [MEDIUM] add support for binding to source port ranges during connect + - [MINOR] config: track "no option"/"option" changes + - [MINOR] config: support resetting options do default values + - [MEDIUM] implement option tcp-smart-accept at the frontend + - [MEDIUM] stream_sock: implement tcp-cork for use during shutdowns on Linux + - [MEDIUM] implement tcp-smart-connect option at the backend + - [MEDIUM] add support for TCP MSS adjustment for listeners + - [MEDIUM] support setting a server weight to zero + - [MINOR] make DEFAULT_MAXCONN user-configurable at build time + - [MAJOR] session: don't clear buffer status flags anymore + - [MAJOR] session: only check for timeouts when they have just occurred. + - [MAJOR] session: simplify buffer error handling + - [MEDIUM] config: split parser and checker in two functions + - [MEDIUM] config: support loading multiple configuration files + - [MEDIUM] stream_sock: don't close prematurely when nolinger is set + - [MEDIUM] session: rework buffer analysis to permit permanent analysers + - [MEDIUM] splice: set the capability on each stream_interface + - [BUG] http: redirect rules were processed too early + - [CLEANUP] remove unused DEBUG_PARSE_NO_SPEEDUP define + - [MEDIUM] http: split request waiter from request processor + - [MEDIUM] session: tell analysers what bit they were called for + - [MAJOR] http: complete splitting of the remaining stages + - [MINOR] report in the proxies the requirements for ACLs + - [MINOR] http: rely on proxy->acl_requires to allocate hdr_idx + - [MINOR] acl: add HTTP protocol detection (req_proto_http) + - [MINOR] prepare callers of session_set_backend to handle errors + - [BUG] default ACLs did not properly set the ->requires flag + - [MEDIUM] allow a TCP frontend to switch to an HTTP backend + - [MINOR] ensure we can jump from swiching rules to http without data + - [MINOR] http: take http request timeout from the backend + - [MINOR] allow TCP inspection rules to make use of HTTP ACLs + - [BUILD] report commit date and not author's date as build date + - [MINOR] acl: don't complain anymore when using L7 acls in TCP + - [BUG] stream_sock: always shutdown(SHUT_WR) before closing + - [BUG] stream_sock: don't stop reading when the poller reports an error + - [BUG] config: tcp-request content only accepts "if" or "unless" + - [BUG] task: fix possible timer drift after update + - [MINOR] apply tcp-smart-connect option for the checks too + - [MINOR] stats: better displaying in MSIE + - [MINOR] config: improve error reporting in global section + - [MINOR] config: improve error reporting in listen sections + - [MINOR] config: the "capture" keyword is not allowed in backends + - [MINOR] config: improve error reporting when checking configuration + - [BUILD] fix a minor build warning on AIX + - [BUILD] use "git cmd" instead of "git-cmd" + - [CLEANUP] report 2009 not 2008 in the copyright banner. + - [MINOR] print usage on the stats sockets upon invalid commands + - [MINOR] acl: detect and report potential mistakes in ACLs + - [BUILD] fix incorrect printf arg count with tcp_splice + - [BUG] fix random pauses on last segment of a series + - [BUILD] add support for build under Cygwin + +2009/06/09 : 1.4-dev0 + - exact copy of 1.3.18 + +2009/05/10 : 1.3.18 + - [MEDIUM] add support for "balance hdr(name)" + - [CLEANUP] give a little bit more information in error message + - [MINOR] add X-Original-To: header + - [BUG] x-original-to: fix missing initialization to default value + - [BUILD] spec file: fix broken pipe during rpmbuild and add man file + - [MINOR] improve reporting of misplaced acl/reqxxx rules + - [MEDIUM] http: add options to ignore invalid header names + - [MEDIUM] http: capture invalid requests/responses even if accepted + - [BUILD] add format(printf) to printf-like functions + - [MINOR] fix several printf formats and missing arguments + - [BUG] stats: total and lbtot are unsigned + - [MINOR] fix a few remaining printf-like formats on 64-bit platforms + - [CLEANUP] remove unused make option from haproxy.spec + - [BUILD] make it possible to pass alternative arch at build time + - [MINOR] switch all stat counters to 64-bit + - [MEDIUM] ensure we don't recursively call pool_gc2() + - [CRITICAL] uninitialized response field can sometimes cause crashes + - [BUG] fix wrong pointer arithmetics in HTTP message captures + - [MINOR] rhel init script : support the reload operation + - [MINOR] add basic signal handling functions + - [BUILD] add signal.o to all makefiles + - [MEDIUM] call signal_process_queue from run_poll_loop + - [MEDIUM] pollers: don't wait if a signal is pending + - [MEDIUM] convert all signals to asynchronous signals + - [BUG] O(1) pollers should check their FD before closing it + - [MINOR] don't close stdio fds twice + - [MINOR] add options dontlog-normal and log-separate-errors + - [DOC] minor fixes and rearrangements + - [BUG] fix parser crash on unconditional tcp content rules + - [DOC] rearrange the configuration manual and add a summary + - [MINOR] standard: provide a new 'my_strndup' function + - [MINOR] implement per-logger log level limitation + - [MINOR] compute the max of sessions/s on fe/be/srv + - [MINOR] stats: report max sessions/s and limit in CSV export + - [MINOR] stats: report max sessions/s and limit in HTML stats + - [MINOR] stats/html: use the arial font before helvetica + +2009/03/29 : 1.3.17 + - Update specfile to build for v2.6 kernel. + - [BUG] reset the stream_interface connect timeout upon connect or error + - [BUG] reject unix accepts when connection limit is reached + - [MINOR] show sess: report number of calls to each task + - [BUG] don't call epoll_ctl() on closed sockets + - [BUG] stream_sock: disable I/O on fds reporting an error + - [MINOR] sepoll: don't count two events on the same FD. + - [MINOR] show sess: report a lot more information about sessions + - [BUG] stream_sock: check for shut{r,w} before refreshing some timeouts + - [BUG] don't set an expiration date directly from now_ms + - [MINOR] implement ulltoh() to write HTML-formatted numbers + - [MINOR] stats/html: group digits by 3 to clarify numbers + - [BUILD] remove haproxy-small.spec + - [BUILD] makefile: remove unused references to linux24eold and EPOLL_CTL_WORKAROUND + +2009/03/22 : 1.3.16 + - [BUILD] Fixed Makefile for linking pcre + - [CONTRIB] selinux policy for haproxy + - [MINOR] show errors: encode backslash as well as non-ascii characters + - [MINOR] cfgparse: some cleanups in the consistency checks + - [MINOR] cfgparse: set backends to "balance roundrobin" by default + - [MINOR] tcp-inspect: permit the use of no-delay inspection + - [MEDIUM] reverse internal proxy declaration order to match configuration + - [CLEANUP] config: catch and report some possibly wrong rule ordering + - [BUG] connect timeout is in the stream interface, not the buffer + - [BUG] session: errors were not reported in termination flags in TCP mode + - [MINOR] tcp_request: let the caller take care of errors and timeouts + - [CLEANUP] http: remove some commented out obsolete code in process_response + - [MINOR] update ebtree to version 4.1 + - [MEDIUM] scheduler: get rid of the 4 trees thanks and use ebtree v4.1 + - [BUG] sched: don't leave 3 lasts tasks unprocessed when niced tasks are present + - [BUG] scheduler: fix improper handling of duplicates __task_queue() + - [MINOR] sched: permit a task to stay up between calls + - [MINOR] task: keep a task count and clean up task creators + - [MINOR] stats: report number of tasks (active and running) + - [BUG] server check intervals must not be null + - [OPTIM] stream_sock: don't retry to read after a large read + - [OPTIM] buffer: new BF_READ_DONTWAIT flag reduces EAGAIN rates + - [MEDIUM] session: don't resync FSMs on non-interesting changes + - [BUG] check for global.maxconn before doing accept() + - [OPTIM] sepoll: do not re-check whole list upon accepts + +2009/03/09 : 1.3.16-rc2 + - [BUG] stream_sock: write timeout must be updated when forwarding ! + +2009/03/09 : 1.3.16-rc1 + - appsessions: cleanup DEBUG_HASH and initialize request_counter + - [MINOR] acl: add new keyword "connslots" + - [MINOR] cfgparse: fix off-by 2 in error message size + - [BUILD] fix build with gcc 4.3 + - [BUILD] fix MANDIR default location to match documentation + - [TESTS] add a debug patch to help trigger the stats bug + - [BUG] Flush buffers also where there are exactly 0 bytes left + - [MINOR] Allow to specify a domain for a cookie + - [BUG/CLEANUP] cookiedomain -> cookie_domain rename + free(p->cookie_domain) + - [MEDIUM] Fix memory freeing at exit + - [MEDIUM] Fix memory freeing at exit, part 2 + - [BUG] Fix listen & more of 2 couples : + - [DOC] remove buggy comment for use_backend + - [CRITICAL] fix server state tracking: it was O(n!) instead of O(n) + - [MEDIUM] add support for URI hash depth and length limits + - [MINOR] permit renaming of x-forwarded-for header + - [BUILD] fix Makefile.bsd and Makefile.osx for stream_interface + - [BUILD] Haproxy won't compile if DEBUG_FULL is defined + - [MEDIUM] upgrade to ebtree v4.0 + - [DOC] update the README file with new build options + - [MEDIUM] reduce risk of event starvation in ev_sepoll + - [MEDIUM] detect streaming buffers and tag them as such + - [MEDIUM] add support for conditional HTTP redirection + - [BUILD] make install should depend on haproxy not "all" + - [DEBUG] add a TRACE macro to facilitate runtime data extraction + - [BUG] event pollers must not wait if a task exists in the run queue + - [BUG] queue management: wake oldest request in queues + - [BUG] log: reported queue position was offed-by-one + - [BUG] fix the dequeuing logic to ensure that all requests get served + - [DOC] documentation for the "retries" parameter was missing. + - [MEDIUM] implement a monotonic internal clock + - [MEDIUM] further improve monotonic clock by check forward jumps + - [OPTIM] add branch prediction hints in list manipulations + - [MAJOR] replace ultree with ebtree in wait-queues + - [BUG] we could segfault during exit while freeing uri_auths + - [BUG] wqueue: perform proper timeout comparisons with wrapping values + - [MINOR] introduce now_ms, the current date in milliseconds + - [BUG] disable buffer read timeout when reading stats + - [MEDIUM] rework the wait queue mechanism + - [BUILD] change declaration of base64tab to fix build with Intel C++ + - [OPTIM] shrink wake_expired_tasks() by using task_wakeup() + - [MAJOR] use an ebtree instead of a list for the run queue + - [MEDIUM] introduce task->nice and boot access to statistics + - [OPTIM] task_queue: assume most consecutive timers are equal + - [BUILD] silent a warning in unlikely() with gcc 4.x + - [MAJOR] convert all expiration timers from timeval to ticks + - [BUG] use_backend would not correctly consider "unless" + - [TESTS] added test-acl.cfg to test some ACL combinations + - [MEDIUM] add support for configuration keyword registration + - [MEDIUM] modularize the global "stats" keyword configuration parser + - [MINOR] cfgparse: add support for warnings in external functions + - [MEDIUM] modularize the "timeout" keyword configuration parser + - [MAJOR] implement tcp request content inspection + - [MINOR] acl: add a new parsing function: parse_dotted_ver + - [MINOR] acl: add req_ssl_ver in TCP, to match an SSL version + - [CLEANUP] remove unused include/types/client.h + - [CLEANUP] remove many #include from C files + - [CLEANUP] remove dependency on obsolete INTBITS macro + - [DOC] document the new "tcp-request" keyword and associated ACLs + - [MINOR] acl: add REQ_CONTENT to the list of default acls + - [MEDIUM] acl: permit fetch() functions to set the result themselves + - [MEDIUM] acl: get rid of dummy values in always_true/always_false + - [MINOR] acl: add the "wait_end" acl verb + - [MEDIUM] acl: enforce ACL type checking + - [MEDIUM] acl: set types on all currently known ACL verbs + - [MEDIUM] acl: when possible, report the name and requirements of ACLs in warnings + - [CLEANUP] remove 65 useless NULL checks before free + - [MEDIUM] memory: update pool_free2() to support NULL pointers + - [MEDIUM] buffers: ensure buffer_shut* are properly called upon shutdowns + - [MEDIUM] process_srv: rely on buffer flags for client shutdown + - [MEDIUM] process_srv: don't rely at all on client state + - [MEDIUM] process_cli: don't rely at all on server state + - [BUG] fix segfault with url_param + check_post + - [BUG] server timeout was not considered in some circumstances + - [BUG] client timeout incorrectly rearmed while waiting for server + - [MAJOR] kill CL_STINSPECT and CL_STHEADERS (step 1) + - [MAJOR] get rid of SV_STANALYZE (step 2) + - [MEDIUM] simplify and centralize request timeout cancellation and request forwarding + - [MAJOR] completely separate HTTP and TCP states on the request path + - [BUG] fix recently introduced loop when client closes early + - [MAJOR] get rid of the SV_STHEADERS state + - [MAJOR] better separation of response processing and server state + - [MAJOR] clearly separate HTTP response processing from TCP server state + - [MEDIUM] remove unused references to {CL|SV}_STSHUT* + - [MINOR] term_trace: add better instrumentations to trace the code + - [BUG] ev_sepoll: closed file descriptors could persist in the spec list + - [BUG] process_response must not enable the read FD + - [BUG] buffers: remove BF_MAY_CONNECT and fix forwarding issue + - [BUG] process_response: do not touch srv_state + - [BUG] maintain_proxies must not disable backends + - [CLEANUP] get rid of BF_SHUT*_PENDING + - [MEDIUM] buffers: add BF_EMPTY and BF_FULL to remove dependency on req/rep->l + - [MAJOR] process_session: rely only on buffer flags + - [MEDIUM] use buffer->wex instead of buffer->cex for connect timeout + - [MEDIUM] centralize buffer timeout checks at the top of process_session + - [MINOR] ensure the termination flags are set by process_xxx + - [MEDIUM] session: move the analysis bit field to the buffer + - [OPTIM] process_cli/process_srv: reduce the number of tests + - [BUG] regparm is broken on gcc < 3 + - [BUILD] fix warning in proto_tcp.c with gcc >= 4 + - [MEDIUM] merge inspect_exp and txn->exp into request buffer + - [BUG] process_cli/process_srv: don't call shutdown when already done + - [BUG] process_request: HTTP body analysis must return zero if missing data + - [TESTS] test-fsm: 22 regression tests for state machines + - [BUG] Fix empty X-Forwarded-For header name when set in defaults section + - [BUG] fix harmless but wrong fd insertion sequence + - [MEDIUM] make it possible for analysers to follow the whole session + - [MAJOR] rework of the server FSM + - [OPTIM] remove useless fd_set(read) upon shutdown(write) + - [MEDIUM] massive cleanup of process_srv() + - [MEDIUM] second level of code cleanup for process_srv_data + - [MEDIUM] third cleanup and optimization of process_srv_data() + - [MEDIUM] process_srv_data: ensure that we always correctly re-arm timeouts + - [MEDIUM] stream_sock_process_data moved to stream_sock.c + - [MAJOR] make the client side use stream_sock_process_data() + - [MEDIUM] split stream_sock_process_data + - [OPTIM] stream_sock_read must check for null-reads more often + - [MINOR] only call flow analysers when their read side is connected. + - [MEDIUM] reintroduce BF_HIJACK with produce_content + - [MINOR] re-arrange buffer flags and rename some of them + - [MINOR] do not check for BF_SHUTR when computing write timeout + - [OPTIM] ev_sepoll: detect newly created FDs and check them once + - [OPTIM] reduce the number of calls to task_wakeup() + - [OPTIM] force inlining of large functions with gcc >= 3 + - [MEDIUM] indicate a reason for a task wakeup + - [MINOR] change type of fdtab[]->owner to void* + - [MAJOR] make stream sockets aware of the stream interface + - [MEDIUM] stream interface: add the ->shutw method as well as in and out buffers + - [MEDIUM] buffers: add BF_READ_ATTACHED and BF_ANA_TIMEOUT + - [MEDIUM] process_session: make use of the new buffer flags + - [CLEANUP] process_session: move debug outputs out of the critical loop + - [MEDIUM] move QUEUE and TAR timers to stream interfaces + - [OPTIM] add compiler hints in tick_is_expired() + - [MINOR] add buffer_check_timeouts() to check what timeouts have fired. + - [MEDIUM] use buffer_check_timeouts instead of stream_sock_check_timeouts() + - [MINOR] add an expiration flag to the stream_sock_interface + - [MAJOR] migrate the connection logic to stream interface + - [MAJOR] add a connection error state to the stream_interface + - [MEDIUM] add the SN_CURR_SESS flag to the session to track open sessions + - [MEDIUM] continue layering cleanups. + - [MEDIUM] stream_interface: added a DISconnected state between CON/EST and CLO + - [MEDIUM] remove stream_sock_update_data() + - [MINOR] maintain a global session list in order to ease debugging + - [BUG] shutw must imply close during a connect + - [MEDIUM] process shutw during connection attempt + - [MEDIUM] make the stream interface control the SHUT{R,W} bits + - [MAJOR] complete layer4/7 separation + - [CLEANUP] move the session-related functions to session.c + - [MINOR] call session->do_log() for logging + - [MINOR] replace the ambiguous client_return function by stream_int_return + - [MINOR] replace client_retnclose() with stream_int_retnclose() + - [MINOR] replace srv_close_with_err() with http_server_error() + - [MEDIUM] make the http server error function a pointer in the session + - [CLEANUP] session.c: removed some migration left-overs in sess_establish() + - [MINOR] stream_sock_data_finish() should not expose fd + - [MEDIUM] extract TCP request processing from HTTP + - [MEDIUM] extract the HTTP tarpit code from process_request(). + - [MEDIUM] move the HTTP request body analyser out of process_request(). + - [MEDIUM] rename process_request to http_process_request + - [BUG] fix forgotten server session counter + - [MINOR] declare process_session in session.h, not proto_http.h + - [MEDIUM] first pass of lifting to proto_uxst.c:uxst_event_accept() + - [MINOR] add an analyser code for UNIX stats request + - [MINOR] pre-set analyser flags on the listener at registration time + - [BUG] do not forward close from cons to prod with analysers + - [MEDIUM] ensure that sock->shutw() also closes read for init states + - [MINOR] add an analyser state in struct session + - [MAJOR] make unix sockets work again with stats + - [MEDIUM] remove cli_fd, srv_fd, cli_state and srv_state from the session + - [MINOR] move the listener reference from fd to session + - [MEDIUM] reference the current hijack function in the buffer itself + - [MINOR] slightly rebalance stats_dump_{raw,http} + - [MINOR] add a new back-reference type : struct bref + - [MINOR] add back-references to sessions for later use by a dumper. + - [MEDIUM] add support for "show sess" in unix stats socket + - [BUG] do not release the connection slot during a retry + - [BUG] dynamic connection throttling could return a max of zero conns + - [BUG] do not try to pause backends during reload + - [BUG] ensure that listeners from disabled proxies are correctly unbound. + - [BUG] acl-related keywords are not allowed in defaults sections + - [BUG] cookie capture is declared in the frontend but checked on the backend + - [BUG] critical errors should be reported even in daemon mode + - [MINOR] redirect: add support for the "drop-query" option + - [MINOR] redirect: add support for "set-cookie" and "clear-cookie" + - [MINOR] redirect: in prefix mode a "/" means not to change the URI + - [BUG] do not dequeue requests on a dead server + - [BUG] do not dequeue the backend's pending connections on a dead server + - [MINOR] stats: indicate if a task is running in "show sess" + - [BUG] check timeout must not be changed if timeout.check is not set + - [BUG] "option transparent" is for backend, not frontend ! + - [MINOR] transfer errors were not reported anymore in data phase + - [MEDIUM] add a send limit to a buffer + - [MEDIUM] don't report buffer timeout when there is I/O activity + - [MEDIUM] indicate when we don't care about read timeout + - [MINOR] add flags to indicate when a stream interface is waiting for space/data + - [MEDIUM] enable inter-stream_interface wakeup calls + - [MAJOR] implement autonomous inter-socket forwarding + - [MINOR] add the splice_len member to the buffer struct in preparation of splice support + - [MEDIUM] stream_sock: factor out the return path in case of no-writes + - [MEDIUM] i/o: rework ->to_forward and ->send_max + - [OPTIM] stream_sock: do not ask for polling on EAGAIN if we have read + - [OPTIM] buffer: replace rlim by max_len + - [OPTIM] stream_sock: factor out the buffer full handling out of the loop + - [CLEANUP] replace a few occurrences of (flags & X) && !(flags & Y) + - [CLEANUP] stream_sock: move the write-nothing condition out of the loop + - [MEDIUM] split stream_sock_write() into callback and core functions + - [MEDIUM] stream_sock_read: call ->chk_snd whenever there are data pending + - [MINOR] stream_sock: fix a few wrong empty calculations + - [MEDIUM] stream_sock: try to send pending data on chk_snd() + - [MINOR] global.maxpipes: add the ability to reserve file descriptors for pipes + - [MEDIUM] splice: add configuration options and set global.maxpipes + - [MINOR] introduce structures required to support Linux kernel splicing + - [MEDIUM] add definitions for Linux kernel splicing + - [MAJOR] complete support for linux 2.6 kernel splicing + - [BUG] reserve some pipes for backends with splice enabled + - [MEDIUM] splice: add hints to support older buggy kernels + - [MEDIUM] introduce pipe pools + - [MEDIUM] splice: make use of pipe pools + - [STATS] report pipe usage in the statistics + - [OPTIM] make global.maxpipes default to global.maxconn/4 when not specified + - [BUILD] fix snapshot date extraction with negative timezones + - [MEDIUM] move global tuning options to the global structure + - [MEDIUM] splice: add the global "nosplice" option + - [BUILD] add USE_LINUX_SPLICE to enable LINUX_SPLICE on linux 2.6 + - [BUG] we must not exit if protocol binding only returns a warning + - [MINOR] add support for bind interface name + - [BUG] inform the user when root is expected but not set + - [MEDIUM] add support for source interface binding + - [MEDIUM] add support for source interface binding at the server level + - [MEDIUM] implement bind-process to limit service presence by process + - [DOC] document maxpipes, nosplice, option splice-{auto,request,response} + - [DOC] filled the logging section of the configuration manual + - [DOC] document HTTP status codes + - [DOC] document a few missing info about errorfile + - [BUG] fix random memory corruption using "show sess" + - [BUG] fix unix socket processing of interrupted output + - [DOC] add diagrams of queuing and future ACL design + - [BUILD] proto_http did not build on gcc-2.95 + - [BUG] the "source" keyword must first clear optional settings + - [BUG] global.tune.maxaccept must be limited even in mono-process mode + - [MINOR] ensure that http_msg_analyzer updates pointer to invalid char + - [MEDIUM] store a complete dump of request and response errors in proxies + - [MEDIUM] implement error dump on unix socket with "show errors" + - [DOC] document "show errors" + - [MINOR] errors dump must use user-visible date, not internal date. + - [MINOR] time: add __usec_to_1024th to convert usecs to 1024th of second + - [MINOR] add curr_sec_ms and curr_sec_ms_scaled for current second. + - [MEDIUM] measure and report session rate on frontend, backends and servers + - [BUG] the "connslots" keyword was matched as "connlots" + - [MINOR] acl: add 2 new verbs: fe_sess_rate and be_sess_rate + - [MEDIUM] implement "rate-limit sessions" for the frontend + - [BUG] interface binding: length must include the trailing zero + - [BUG] typo in timeout error reporting : report *res and not *err + - [OPTIM] maintain_proxies: only wake up when the frontend will be ready + - [OPTIM] rate-limit: cleaner behaviour on low rates and reduce consumption + - [BUG] switch server-side stream interface to close in case of abort + - [CLEANUP] remove last references to term_trace + - [OPTIM] freq_ctr: do not rotate the counters when reading + - [BUG] disable any analysers for monitoring requests + - [BUG] rate-limit in defaults section was ignored + - [BUG] task: fix handling of duplicate keys + - [OPTIM] task: don't unlink a task from a wait queue when waking it up + - [OPTIM] displace tasks in the wait queue only if absolutely needed + - [MEDIUM] minor update to the task api: let the scheduler queue itself + - [BUG] event_accept() must always wake the task up, even in health mode + - [CLEANUP] task: distinguish between clock ticks and timers + - [OPTIM] task: reduce the number of calls to task_queue() + - [OPTIM] do not re-check req buffer when only response has changed + - [CLEANUP] don't enable kernel splicing when socket is closed + - [CLEANUP] buffer_flush() was misleading, rename it as buffer_erase + - [MINOR] buffers: implement buffer_flush() + - [MEDIUM] rearrange forwarding condition to enable splice during analysis + - [BUILD] build fixes for Solaris + - [BUILD] proto_http did not build on gcc-2.95 (again) + - [CONTRIB] halog: fast log parser for haproxy + - [CONTRIB] halog: faster fgets() and add support for percentile reporting + +2008/04/19 : 1.3.15 + - [BUILD] Added support for 'make install' + - [BUILD] Added 'install-man' make target for installing the man page + - [BUILD] Added 'install-bin' make target + - [BUILD] Added 'install-doc' make target + - [BUILD] Removed "/" after '$(DESTDIR)' in install targets + - [BUILD] Changed 'install' target to install the binaries first + - [BUILD] Replace hardcoded 'LD = gcc' with 'LD = $(CC)' + - [MEDIUM]: Inversion for options + - [MEDIUM]: Count retries and redispatches also for servers, fix redistribute_pending, extend logs, %d->%u cleanup + - [BUG]: Restore clearing t->logs.bytes + - [MEDIUM]: rework checks handling + - [DOC] Update a "contrib" file with a hint about a scheme used for formathing subjects + - [MEDIUM] Implement "track [/]" + - [MINOR] Implement persistent id for proxies and servers + - [BUG] Don't increment server connections too much + fix retries + - [MEDIUM]: Prevent redispatcher from selecting the same server, version #3 + - [MAJOR] proto_uxst rework -> SNMP support + - [BUG] appsession lookup in URL does not work + - [BUG] transparent proxy address was ignored in backend + - [BUG] hot reconfiguration failed because of a wrong error check + - [DOC] big update to the configuration manual + - [DOC] large update to the configuration manual + - [DOC] document more options + - [BUILD] major rework of the GNU Makefile + - [STATS] add support for "show info" on the unix socket + - [DOC] document options forwardfor to logasap + - [MINOR] add support for the "backlog" parameter + - [OPTIM] introduce global parameter "tune.maxaccept" + - [MEDIUM] introduce "timeout http-request" in frontends + - [MINOR] tarpit timeout is also allowed in backends + - [BUG] increment server connections for each connect() + - [MEDIUM] add a turn-around state of one second after a connection failure + - [BUG] fix typo in redispatched connection + - [DOC] document options nolinger to ssl-hello-chk + - [DOC] added documentation for "option tcplog" to "use_backend" + - [BUG] connect_server: server might not exist when sending error report + - [MEDIUM] support fully transparent proxy on Linux (USE_LINUX_TPROXY) + - [MEDIUM] add non-local bind to connect() on Linux + - [MINOR] add transparent proxy support for balabit's Tproxy v4 + - [BUG] use backend's source and not server's source with tproxy + - [BUG] fix overlapping server flags + - [MEDIUM] fix server health checks source address selection + - [BUG] build failed on CONFIG_HAP_LINUX_TPROXY without CONFIG_HAP_CTTPROXY + - [DOC] added "server", "source" and "stats" keywords + - [DOC] all server parameters have been documented + - [DOC] document all req* and rsp* keywords. + - [DOC] added documentation about HTTP header manipulations + - [BUG] log response byte count, not request + - [BUILD] code did not build in full debug mode + - [BUG] fix truncated responses with sepoll + - [MINOR] use s->frt_addr as the server's address in transparent proxy + - [MINOR] fix configuration hint about timeouts + - [DOC] minor cleanup of the doc and notice to contributors + - [MINOR] report correct section type for unknown keywords. + - [BUILD] update MacOS Makefile to build on newer versions + - [DOC] fix erroneous "useallbackups" option in the doc + - [DOC] applied small fixes from early readers + - [MINOR] add configuration support for "redir" server keyword + - [MEDIUM] completely implement the server redirection method + - [TESTS] add a test case for the server redirection mechanism + - [DOC] add a configuration entry for "server ... redir " + - [BUILD] backend.c and checks.c did not build without tproxy ! + - Revert "[BUILD] backend.c and checks.c did not build without tproxy !" + - [BUILD] backend.c and checks.c did not build without tproxy ! + - [OPTIM] used unsigned ints for HTTP state and message offsets + - [OPTIM] GCC4's builtin_expect() is suboptimal + - [BUG] failed conns were sometimes incremented in the frontend! + - [BUG] timeout.check was not pre-set to eternity + - [TESTS] add test-pollers.cfg to easily report pollers in use + - [BUG] do not apply timeout.connect in checks if unset + - [BUILD] ensure that makefile understands USE_DLMALLOC=1 + - [MINOR] silent gcc for a wrong warning + - [CLEANUP] update .gitignore to ignore more temporary files + - [CLEANUP] report dlmalloc's source path only if explictly specified + - [BUG] str2sun could leak a small buffer in case of error during parsing + - [BUG] option allbackups was not working anymore in roundrobin mode + - [MAJOR] implementation of the "leastconn" load balancing algorithm + - [BUILD] ensure that users don't build without setting the target anymore. + - [DOC] document the leastconn LB algo + - [MEDIUM] fix stats socket limitation to 16 kB + - [DOC] fix unescaped space in httpchk example. + - [BUG] fix double-decrement of server connections + - [TESTS] add a test case for port mapping + - [TESTS] add a benchmark for integer hashing + - [TESTS] add new methods in ip-hash test file + - [MAJOR] implement parameter hashing for POST requests + +2007/12/06 : 1.3.14 + - New option http_proxy (Alexandre Cassen) + - add support for "maxqueue" to limit server queue overload (Elijah Epifanov) + - Check for duplicated conflicting proxies (Krzysztof Oledzki) + - stats: report server and backend cumulated downtime (Krzysztof Oledzki) + - use backends only with use_backend directive (Krzysztof Oledzki) + - Handle long lines properly (Krzysztof Oledzki) + - Implement and use generic findproxy and relax duplicated proxy check (Krzysztof Oledzki) + - continous statistics (Krzysztof Oledzki) + - add support for logging via a UNIX socket (Robert Tsai) + - fix error checking in strl2ic/strl2uic() + - fix calls to localtime() + - provide easier-to-use ultoa_* functions + - provide easy-to-use limit_r and LIM2A* macros + - add a simple test for the status page + - move error codes to common/errors.h + - silent warning about LIST_* being redefined on OpenBSD + - add socket address length to the protocols + - group PR_O_BALANCE_* bits into a checkable value + - externalize the "balance" option parser to backend.c + - introduce the "url_param" balance method + - make default_backend work in TCP mode too + - disable warning about localtime_r on Solaris + - adjust error messages about conflicting proxies + - avoid calling some layer7 functions if not needed + - simplify error path in event_accept() + - add an options field to the listeners + - added a new state to listeners + - unbind_listener() must use fd_delete() and not close() + - add a generic unbind_listener() primitive + - add a generic delete_listener() primitive + - add a generic unbind_all_listeners() primitive + - create proto_tcp and move initialization of proxy listeners + - stats: report numerical process ID, proxy ID and server ID + - relative_pid was not initialized + - missing header names in raw stats output + - fix missing parenthesis in check_response_for_cacheability + - small optimization on session_process_counters() + - merge ebtree version 3.0 + - make ebtree headers multiple-include compatible + - ebtree: include config.h for REGPRM* + - differentiate between generic LB params and map-specific ones + - add a weight divisor to the struct proxy + - implement the Fast Weighted Round Robin (FWRR) algo + - include filltab25.c to experiment on FWRR for dynamic weights + - merge test-fwrr.cfg to validate dynamic weights + - move the load balancing algorithm to be->lbprm.algo + - change server check result to a bit field + - implement "http-check disable-on-404" for graceful shutdown + - secure the calling conditions of ->set_server_status_{up,down} + - report disabled servers as "NOLB" when they are still UP + - document the "http-check disable-on-404" option + - http-check disable-on-404 is not limited to HTTP mode + - add a test file for disable-on-404 + - use distinct bits per load-balancing algorithm type + - implement the slowstart parameter for servers + - document the server's slowstart parameter + - stats: report the server warm up status in a "throttle" column + - fix 2 minor issues on AIX + - add the "nbsrv" ACL verb + - add the "fail" condition to monitor requests + - remove a warning from gcc due to htons() in standard.c + - fwrr: ensure that we never overflow in placements + - store the build options to report with -vv + - fix the status return of the init script (R.I. Pienaar) + - stats: real time monitoring script for unix socket (Prizee) + - document "nbsrv" and "monitor fail" + - restrict the set of allowed characters for identifiers + - implement a time parsing function + - add support for time units in the configuration + - add a bit of documentation about timers + - introduce separation between contimeout, and tarpit + queue + - introduce the "timeout" keyword + - grouped all timeouts in one structure + - slowstart is in ms, not seconds + - slowstart: ensure we don't start with a null weight + - report the number of times each server was selected + - fix build on AIX due to recent log changes + - fix build on Solaris due to recent log changes + +2007/10/18 : 1.3.13 + - replace the code under O'Reilly license (Arnaud Cornet) + - add a small man page (Arnaud Cornet) + - stats: report haproxy's version by default (Krzysztof Oledzki) + - stats: count server retries and redispatches (Krzysztof Oledzki) + - core: added easy support for Doug Lea's malloc (dlmalloc) + - core: fade out memory usage when stopping proxies + - core: moved the sockaddr pointer to the fdtab structure + - core: add generic protocol support + - core: implement client-side support for PF_UNIX sockets + - stats: implement the CSV output + - stats: add a link to the CSV export HTML page + - stats: implement the statistics output on a unix socket + - config: introduce the "stats" keyword in global section + - build: centralize version and date into one file for each + - tests: added a new hash algorithm + +2007/10/18 : 1.3.12.3 + - add the "nolinger" option to disable data lingering (Alexandre Cassen) + - fix double-free during clean exit (Krzysztof Oledzki) + - prevent the system from sending an RST when closing health-checks + (Krzysztof Oledzki) + - do not add a cache-control header when on non-cacheable responses + (Krzysztof Oledzki) + - spread health checks even more (Krzysztof Oledzki) + - stats: scope "." must match the backend and not the frontend + - fixed call to chroot() during startup + - fix wrong timeout computation in event_accept() + - remove condition for exit() under fork() failure + +2007/09/20 : 1.3.12.2 + - fix configuration sanity checks for TCP listeners + - set the log socket receive window to zero bytes + - pre-initialize timeouts to infinity, not zero + - fix the SIGHUP message not to alert on server-less proxies + - timeouts and retries could be ignored when switching backend + - added a file to check that "retries" works. + - O'Reilly has clarified its license + +2007/09/05 : 1.3.12.1 + - spec I/O: fix allocations of spec entries for an FD + - ensure we never overflow in chunk_printf() + - improve behaviour with large number of servers per proxy + - add support for "stats refresh " + - stats page: added links for 'refresh' and 'hide down' + - fix backend's weight in the stats page. + - the "stats" keyword is not allowed in a pure frontend. + - provide a test configuration file for stats and checks + +2007/06/17 : 1.3.12 + - fix segfault at exit when using captures + - bug: negation in ACL conds was not cleared between terms + - errorfile: use a local file to feed error messages + - acl: support '-i' to ignore case when matching + - acl: smarter integer comparison with operators eq,lt,gt,le,ge + - acl: support maching on 'path' component + - acl: implement matching on header values + - acl: distinguish between request and response headers + - acl: permit to return any header when no name specified + - acl: provide default ACLs + - added the 'use_backend' keyword for full content-switching + - acl: specify the direction during fetches + - acl: provide the argument length for fetch functions + - acl: provide a reference to the expr to fetch() + - improve memory freeing upon exit + - str2net() must not change the const char * + - shut warnings 'is*' macros from ctype.h on solaris + +2007/06/03 : 1.3.11.4 + - do not re-arm read timeout in SHUTR state ! + - optimize I/O by detecting system starvation + - the epoll FD must not be shared between processes + - limit the number of events returned by *poll* + +2007/05/14 : 1.3.11.3 + - pre-initialize timeouts with tv_eternity during parsing + +2007/05/14 : 1.3.11.2 + - fixed broken health-checks since switch to timeval + +2007/05/14 : 1.3.11.1 + - fixed ev_kqueue which was forgotten during the switch to timeval + - allowed null timeouts for past events in select + +2007/05/14 : 1.3.11 + - fixed ev_sepoll again by rewriting the state machine + - switched all timeouts to timevals instead of milliseconds + - improved memory management using mempools v2. + - several minor optimizations + +2007/05/09 : 1.3.10.2 + - fixed build on OpenBSD (missing types.h) + +2007/05/09 : 1.3.10.1 + - fixed sepoll transition matrix (two states were missing) + +2007/05/08 : 1.3.10 + - several fixes in ev_sepoll + - fixed some expiration dates on some tasks + - fixed a bug in connection establishment detection due to speculative I/O + - fixed rare bug occuring on TCP with early close (reported by Andy Smith) + - implemented URI hashing algorithm (Guillaume Dallaire) + - implemented SMTP health checks (Peter van Dijk) + - replaced the rbtree with ul2tree from old scheduler project + - new framework for generic ACL support + - added the 'acl' and 'block' keywords to the config language + - added several ACL criteria and matches (IP, port, URI, ...) + - cleaned up and better modularization for some time functions + - fixed list macros + - fixed useless memory allocation in str2net() + - store the original destination address in the session + +2007/04/15 : 1.3.9 + - modularized the polling mechanisms and use function pointers instead + of macros at many places + - implemented support for FreeBSD's kqueue() polling mechanism + - fixed a warning on OpenBSD : MIN/MAX redefined + - change socket registration order at startup to accomodate kqueue. + - several makefile cleanups to support old shells + - fix build with limits.h once for all + - ev_epoll: do not rely on fd_sets anymore, use changes stacks instead. + - fdtab now holds the results of polling + - implemented support for speculative I/O processing with epoll() + - remove useless calls to shutdown(SHUT_RD), resulting in small speed boost + - auto-registering of pollers at load time + +2007/04/03 : 1.3.8.2 + - rewriting either the status line or request line could crash the + process due to a pointer which ought to be reset before parsing. + - rewriting the status line in the response did not work, it caused + a 502 Bad Gateway due to an erroneous state during parsing + +2007/04/01 : 1.3.8.1 + - fix reqadd when no option httpclose is used. + - removed now unused fiprm and beprm from proxies + - split logs into two versions : TCP and HTTP + - added some docs about http headers storage and acls + - added a VIM script for syntax color highlighting (Bruno Michel) + +2007/03/25 : 1.3.8 + - fixed several bugs which might have caused a crash with bad configs + - several optimizations in header processing + - many progresses towards transaction-based processing + - option forwardfor may be used in frontends + - completed HTTP response processing + - some code refactoring between request and response processing + - new HTTP header manipulation functions + - optimizations on the recv() patch to reduce CPU usage under very + high data rates. + - more user-friendly help about the 'usesrc' keyword (CTTPROXY) + - username/groupname support from Marcus Rueckert + - added the "except" keyword to the "forwardfor" option (Bryan German) + - support for health-checks on other addresses (Fabrice Dulaunoy) + - makefile for MacOS 10.4 / Darwin (Dan Zinngrabe) + - do not insert "Connection: close" in HTTP/1.0 messages + +2007/01/26 : 1.3.7 + - fix critical bug introduced with 1.3.6 : an empty request header + may lead to a crash due to missing pointer assignment + - hdr_idx might be left uninitialized in debug mode + - fixed build on FreeBSD due to missing fd_set declaration + +2007/01/22 : 1.3.6.1 + - change in the header chaining broke cookies and authentication + +2007/01/22 : 1.3.6 + - stats now support the HEAD method too + - extracted http request from the session + - huge rework of the HTTP parser which is now a 28-state FSM. + - linux-style likely/unlikely macros for optimization hints + - do not create a server socket when there's no server + - imported lots of docs + +2007/01/07 : 1.3.5 + - stats: swap color sets for active and backup servers + - try to guess server check port when unset + - added complete support and doc for TCP Splicing + - replace the wait-queue linked list with an rbtree. + - a few bugfixes and cleanups + +2007/01/02 : 1.3.4 + - support for cttproxy on the server side to present the client + address to the server. + - added support for SO_REUSEPORT on Linux (needs kernel patch) + - new RFC2616-compliant HTTP request parser with header indexing + - split proxies in frontends, rulesets and backends + - implemented the 'req[i]setbe' to select a backend depending + on the contents + - added the 'default_backend' keyword to select a default BE. + - new stats page featuring FEs and BEs + bytes in both dirs + - improved log format to indicate the backend and the time in ms. + - lots of cleanups + +2006/10/15 : 1.3.3 + - fix broken redispatch option in case the connection has already + been marked "in progress" (ie: nearly always). + - support regparm on x86 to speed up some often called functions + - removed a few useless calls to gettimeofday() in log functions. + - lots of 'const char*' cleanups + - turn every FD_* into functions which are faster on recent CPUs + +2006/09/03 : 1.3.2 + - started the changes towards I/O completion callbacks. stream_sock* have + replaced event_*. + - added the new "reqtarpit" and "reqitarpit" protection features + +2006/07/09 : 1.3.1 (1.2.15) + - now, haproxy warns about missing timeout during startup to try to + eliminate all those buggy configurations. + - added "Content-Type: text/html" in responses wherever appropriate, as + suggested by Cameron Simpson. + - implemented "option ssl-hello-chk" to use SSLv3 CLIENT HELLO messages to + test server's health + - implemented "monitor-uri" so that haproxy can reply to a specific URI with + an "HTTP/1.0 200 OK" response. This is useful to validate multiple proxies + at once. + +2006/06/29 : 1.3.0 + - exploded the whole file into multiple .c and .h. No functionnal + difference is expected at all. + - fixed a bug by which neither stats nor error messages could be returned if + 'clitimeout' was missing. + +2006/05/21 : 1.2.14 + - new HTML status report with the 'stats' keyword. + - added the 'abortonclose' option to better resist traffic surges + - implemented dynamic traffic regulation with the 'minconn' option + - show request time on denied requests + - definitely fixed hot reconf on OpenBSD by the use of SO_REUSEPORT + - now a proxy instance is allowed to run without servers, which is + useful to dedicate one instance to stats + - added lots of error counters + - a missing parenthesis preventd matching of cacheable cookies + - a missing parenthesis in poll_loop() might have caused missed events. + +2006/05/14 : 1.2.13.1 + - an uninitialized field in the struct session could cause a crash when + the session was freed. This has been encountered on Solaris only. + - Solaris and OpenBSD no not support shutdown() on listening socket. Let's + be nice to them by performing a soft stop if pause fails. + +2006/05/13 : 1.2.13 + - 'maxconn' server parameter to do per-server session limitation + - queueing to support non-blocking session limitation + - fixed removal of cookies for cookie-less servers such as backup servers + - two separate wait queues for expirable and non-expirable tasks provide + better performance with lots of sessions. + - some code cleanups and performance improvements + - made state dumps a bit more verbose + - fixed missing checks for NULL srv in dispatch mode + - load balancing on backup servers was not possible in source hash mode. + - two session flags shared the same bit, but fortunately they were not + compatible. + +2006/04/15 : 1.2.12 + Very few changes preparing for more important changes to support per-server + session limitations and queueing : + - ignore leading empty lines in HTTP requests as suggested by RFC2616. + - added the 'weight' parameter to the servers, limited to 1..256. It applies + to roundrobin and source hash. + - the optional '-s' option could clobber '-st' and '-sf' if compiled in. + +2006/03/30 : 1.2.11.1 + - under some conditions, it might have been possible that when the + last dead server became available, it would not have been used + till another one would have changed state. Could not be reproduced + at all, however seems possible from the code. + +2006/03/25 : 1.2.11 + - added the '-db' command-line option to disable backgrounding. + - added the -sf/-st command-line arguments which are used to specify + a list of pids to send a FINISH or TERMINATE signal upon startup. + They will also be asked to release their port if a bind fails. + - reworked the startup mechanism to allow the sending of a signal to a list + of old pids if a socket cannot be bound, with a retry for a limited amount + of time (1 second by default). + - added the ability to enforce limits on memory usage. + - added the 'source' load-balancing algorithm which uses the source IP(v4|v6) + - re-architectured the server round-robin mechanism to ease integration of + other algorithms. It now relies on the number of active and backup servers. + - added a counter for the number of active and backup servers, and report + these numbers upon SIGHUP or state change. + +2006/03/23 : 1.2.10.1 + - while fixing the backup server round-robin "feature", a new bug was + introduced which could miss some backup servers. + - the displayed proxy name was wrong when dumping upon SIGHUP. + +2006/03/19 : 1.2.10 + - assert.h is needed when DEBUG is defined. + - ENORMOUS long standing bug affecting the epoll polling system : + event_data is a union, not a structure ! + - Make fd management more robust and easier to debug. Also some + micro-optimisations. + - Limit the number of consecutive accept() in multi-process mode. + This produces a more evenly distributed load across the processes and + slightly improves performance by reducing bottlenecks. + - Make health-checks be more regular, and faster to retry after a timeout. + - Fixed some messages to ease parsing of alerts. + - provided a patch to enable epoll on RHEL3 kernels. + - Separated OpenBSD build from the main Makefile into a new one. + +2006/03/15 : 1.2.9 + - haproxy could not be stopped after being paused, it had to be woken up + first. This has been fixed. + - the 'ulimit-n' parameter is now optional and by default computed from + maxconn + the number of listeners + the number of health-checks. + - it is now possible to specify a maximum number of connections at build + time with the SYSTEM_MAXCONN define. The value set in the configuration + file will then be limited to this value, and only the command-line '-n' + option will be able to bypass it. It will prevent against accidental + high memory usage on small systems. + - RFC2616 expects that any HTTP agent accepts multi-line headers. Earlier + versions did not detect a line beginning with a space as the continuation + of previous header. It is now correct. + - health checks sent to servers configured with identical intervals were + sent in perfect synchronisation because the initial time was the same + for all. This could induce high load peaks when fragile servers were + hosting tens of instances for the same application. Now the load is + spread evenly across the smallest interval amongst a listener. + - a new 'forceclose' option was added to make the proxy close the outgoing + channel to the server once it has sent all its headers and the server + starts responding. This helps some servers which don't close upon the + 'Connection: close' header. It implies 'option httpclose'. + - there was a bug in the way the backup servers were handled. They were + erroneously load-balanced while the doc said the opposite. Since + load-balanced backup servers is one of the features some people have + been asking for, the problem was fixed to reflect the documented + behaviour and a new option 'allbackups' was introduced to provide the + feature to those who need it. + - a never ending connect() could lead to a fast select() loop if its + timeout times the number of retransmits exceeded the server read or write + timeout, because the later was used to compute select()'s timeout while + the connection timeout was not reached. + - now we initialize the libc's localtime structures very early so that even + under OOM conditions, we can still send dated error messages without + segfaulting. + - the 'daemon' mode implies 'quiet' and disables 'verbose' because file + descriptors are closed. + +2006/01/29 : 1.2.8 + - fixed a nasty bug affecting poll/epoll which could return unmodified data + from the server to the client, and sometimes lead to memory corruption + crashing the process. + - added the new pause/play mechanism with SIGTTOU/SIGTTIN for hot-reconf. + +2005/12/18 : 1.2.7.1 + - the "retries" option was ignored because connect() could not return an + error if the connection failed before the timeout. + - TCP health-checks could not detect a connection refused in poll/epoll + mode. + +2005/11/13 : 1.2.7 + - building with -DUSE_PCRE should include PCRE headers and not regex.h. At + least on Solaris, this caused the libc's regex primitives to be used instead + of PCRE, which caused trouble on group references. This is now fixed. + - delayed the quiet mode during startup so that most of the startup alerts can + be displayed even in quiet mode. + - display an alert when a listener has no address, invalid or no port, or when + there are no enabled listeners upon startup. + - added "static-pcre" to the list of supported regex options in the Makefile. + +2005/10/09 : 1.2.7rc (1.1.33rc) + - second batch of socklen_t changes. + - clean-ups from Cameron Simpson. + - because tv_remain() does not know about eternity, using no timeout can + make select() spin around a null time-out. Bug reported by Cameron Simpson. + - client read timeout was not properly set to eternity initialized after an + accept() if it was not set in the config. It remained undetected so long + because eternity is 0 and newly allocated pages are zeroed by the system. + - do not call get_original_dst() when not in transparent mode. + - implemented a workaround for a bug in certain epoll() implementations on + linux-2.4 kernels (epoll-lt <= 0.21). + - implemented TCP keepalive with new options : tcpka, clitcpka, srvtcpka. + +2005/08/07 : 1.2.6 + - clean-up patch from Alexander Lazic fixes build on Debian 3.1 (socklen_t). + +2005/07/06 : 1.2.6-pre5 (1.1.32) + - added the number of active sessions (proxy/process) in the logs + +2005/07/06 : 1.2.6-pre4 (1.1.32-pre4) + - the time-out fix introduced in 1.1.25 caused a corner case where it was + possible for a client to keep a connection maintained regardless of the + timeout if the server closed the connection during the HEADER phase, + while the client ignored the close request while doing nothing in the + other direction. This has been fixed now by ensuring that read timeouts + are re-armed when switching to any SHUTW state. + +2005/07/05 : 1.2.6-pre3 (1.1.32-pre3) + - enhanced error reporting in the logs. Now the proxy will precisely detect + various error conditions related to the system and/or process limits, and + generate LOG_EMERG logs indicating that a resource has been exhausted. + - logs will contain two new characters for the error cause : 'R' indicates + a resource exhausted, and 'I' indicates an internal error, though this + one should never happen. + - server connection timeouts can now be reported in the logs (sC), as well + as connections refused because of maxconn limitations (PC). + +2005/07/05 : 1.2.6-pre2 (1.1.32-pre2) + - new global configuration keyword "ulimit-n" may be used to raise the FD + limit to usable values. + - a warning is now displayed on startup if the FD limit is lower than the + configured maximum number of sockets. + +2005/07/05 : 1.2.6-pre1 (1.1.32-pre1) + - new configuration keyword "monitor-net" makes it possible to be monitored + by external devices which connect to the proxy without being logged nor + forwarded to any server. Particularly useful on generic TCPv4 relays. + +2005/06/21 : 1.2.5.2 + - fixed build on PPC where chars are unsigned by default + +2005/05/02 : 1.2.5.1 + - dirty hack to fix a bug introduced with epoll : if we close an FD and + immediately reassign it to another session through a connect(), the + Prev{Read,Write}Events are not updated, which causes trouble detecting + changes, thus leading to many timeouts at high loads. + +2005/04/30 : 1.2.5 (1.1.31) + - changed the runtime argument to disable epoll() to '-de' + - changed the runtime argument to disable poll() to '-dp' + - added global options 'nopoll' and 'noepoll' to do the same at the + configuration level. + - added a 'linux24e' target to the Makefile for Linux 2.4 systems patched to + support epoll(). + - changed default FD_SETSIZE to 65536 on Solaris (default=1024) + - conditionned signals redirection to #ifdef DEBUG_MEMORY + +2005/04/26 : 1.2.5-pre4 + - made epoll() support a compile-time option : ENABLE_EPOLL + - provided a very little libc replacement for a possibly missing epoll() + implementation which can be enabled by -DUSE_MY_EPOLL + - implemented the poll() poller, which can be enabled with -DENABLE_POLL. + The equivalent runtime argument becomes '-P'. A few tests show that it + performs like select() with many fds, but slightly slower (certainly + because of the higher amount of memory involved). + - separated the 3 polling methods and the tasks scheduler into 4 distinct + functions which makes the code a lot more modular. + - moved some event tables to private static declarations inside the poller + functions. + - the poller functions can now initialize themselves, run, and cleanup. + - changed the runtime argument to enable epoll() to '-E'. + - removed buggy epoll_ctl() code in the client_retnclose() function. This + function was never meant to remove anything. + - fixed a typo which caused glibc to yell about a double free on exit. + - removed error checking after epoll_ctl(DEL) because we can never know if + the fd is still active or already closed. + - added a few entries in the makefile + +2005/04/25 : 1.2.5-pre3 + - experimental epoll() support (use temporary '-e' argument) + +2005/04/24 : 1.2.5-pre2 + - implemented the HTTP 303 code for error redirection. This forces the + browser to fetch the given URI with a GET request. The new keyword for + this is 'errorloc303', and a new 'errorloc302' keyword has been created + to make them easily distinguishable. + - added more controls in the parser for valid use of '\x' sequence. + - few fixes from Alex & Klaus + +2005/02/17 : 1.2.5-pre1 + - fixed a few errors in the documentation + +2005/02/13 + - do not pre-initialize unused file-descriptors before select() anymore. + +2005/01/22 : 1.2.4 + - merged Alexander Lazic's and Klaus Wagner's work on application + cookie-based persistence. Since this is the first merge, this version is + not intended for general use and reports are more than welcome. Some + documentation is really needed though. + +2005/01/22 : 1.2.3 (1.1.30) + - add an architecture guide to the documentation + - released without any changes + +2004/12/26 : 1.2.3-pre1 (1.1.30-pre1) + - increased default BUFSIZE to 16 kB to accept max headers of 8 kB which is + compatible with Apache. This limit can be configured in the makefile now. + Thanks to Eric Fehr for the checks. + - added a per-server "source" option which now makes it possible to bind to + a different source for each (potentially identical) server. + - changed cookie-based server selection slightly to allow several servers to + share a same cookie, thus making it possible to associate backup servers to + live servers and ease soft-stop for maintenance periods. (Alexander Lazic) + - added the cookie 'prefix' mode which makes it possible to use persistence + with thin clients which support only one cookie. The server name is prefixed + before the application cookie, and restore back. + - fixed the order of servers within an instance to match documentation. Now + the servers are *really* used in the order of their declaration. This is + particularly important when multiple backup servers are in use. + +2004/10/18 : 1.2.2 (1.1.29) + - fixed a bug where a TCP connection would be logged twice if the 'logasap' + option was enabled without the 'tcplog' option. + - encode_string() would use hdr_encode_map instead of the map argument. + +2004/08/10 : (1.1.29-pre2) + - the logged request is now encoded with '#XX' for unprintable characters + - new keywords 'capture request header' and 'capture response header' enable + logging of arbitrary HTTP headers in requests and responses + - removed "-DSOLARIS" after replacing the last inet_aton() with inet_pton() + +2004/06/06 : 1.2.1 (1.1.28) + - added the '-V' command line option to verbosely report errors even though + the -q or 'quiet' options are specified. This is useful with '-c'. + - added a Red Hat init script and a .spec from Simon Matter + +2004/06/05 : + - added the "logasap" option which produces a log without waiting for the data + to be transferred from the server to the client. + - added the "httpclose" option which removes any "connection:" header and adds + "Connection: close" in both direction. + - added the 'checkcache' option which blocks cacheable responses containing + dangerous headers, such as 'set-cookie'. + - added 'rspdeny' and 'rspideny' to block certain responses to avoid sensible + information leak from servers. + +2004/04/18 : + - send an EMERG log when no server is available for a given proxy + - added the '-c' command line option to syntactically check the + configuration file without starting the service. + +2003/11/09 : 1.2.0 + - the same as 1.1.27 + IPv6 support on the client side + +2003/10/27 : 1.1.27 + - the configurable HTTP health check introduced in 1.1.23 revealed a shameful + bug : the code still assumed that HTTP requests were the same size as the + original ones (22 bytes), and failed if they were not. + - added support for pidfiles. + +2003/10/22 : 1.1.26 + - the fix introduced in 1.1.25 for client timeouts while waiting for servers + broke almost all compatibility with POST requests, because the proxy + stopped to read anything from the client as soon as it got all of its + headers. + +2003/10/15 : 1.1.25 + - added the 'tcplog' option, which provides enhanced, HTTP-like logs for + generic TCP proxies, or lighter logs for HTTP proxies. + - fixed a time-out condition wrongly reported as client time-out in data + phase if the client timeout was lower than the connect timeout times the + number of retries. + +2003/09/21 : 1.1.24 + - if a client sent a full request then shut its write connection down, then + the request was aborted. This case was detected only when using haproxy + both as health-check client and as a server. + - if 'option httpchk' is used in a 'health' mode server, then responses will + change from 'OK' to 'HTTP/1.0 200 OK'. + - fixed a Linux-only bug in case of HTTP server health-checks, where a single + server response followed by a close could be ignored, and the server seen + as failed. + +2003/09/19 : 1.1.23 + - fixed a stupid bug introduced in 1.1.22 which caused second and subsequent + 'default' sections to keep previous parameters, and not initialize logs + correctly. + - fixed a second stupid bug introduced in 1.1.22 which caused configurations + relying on 'dispatch' mode to segfault at the first connection. + - 'option httpchk' now supports method, HTTP version and a few headers. + - now, 'option httpchk', 'cookie' and 'capture' can be specified in + 'defaults' section + +2003/09/10 : 1.1.22 + - 'listen' now supports optionnal address:port-range lists + - 'bind' introduced to add new listen addresses + - fixed a bug which caused a session to be kept established on a server till + it timed out if the client closed during the DATA phase. + - the port part of each server address can now be empty to make the proxy + connect to the server on the same port it was connected to, be an absolute + unsigned number to reflect a single port (as in older versions), or an + explicitly signed number (+N/-N) to indicate that this offset must be + applied to the port the proxy was connected to, when connecting to the + server. + - the 'port' server option allows the user to specify a different + health-check port than the service one. It is mandatory when only relative + ports have been specified and check is required. By default, the checks are + sent to the service port. + - new 'defaults' section which is rather similar to 'listen' except that all + values are only used as default values for future 'listen' sections, until + a new 'defaults' resets them. At the moment, server options, regexes, + cookie names and captures cannot be set in the 'defaults' section. + +2003/05/06 : 1.1.21 + - changed the debug output format so that it now includes the session unique + ID followed by the instance name at the beginning of each line. + - in debug mode, accept now shows the client's IP and port. + - added one 3 small debugging scripts to search and pretty print debug output + - changed the default health check request to "OPTIONS /" instead of + "OPTIONS *" since not all servers implement the later one. + - "option httpchk" now accepts an optional parameter allowing the user to + specify and URI other than '/' during health-checks. + +2003/04/21 : 1.1.20 + - fixed two problems with time-outs, one where a server would be logged as + timed out during transfer that take longer to complete than the fixed + time-out, and one where clients were logged as timed-out during the data + phase because they didn't have anything to send. This sometimes caused + slow client connections to close too early while in fact there was no + problem. The proper fix would be to have a per-fd time-out with + conditions depending on the state of the HTTP FSM. + +2003/04/16 : 1.1.19 + - haproxy was NOT RFC compliant because it was case-sensitive on HTTP + "Cookie:" and "Set-Cookie:" headers. This caused JVM 1.4 to fail on + cookie persistence because it uses "cookie:". Two memcmp() have been + replaced with strncasecmp(). + +2003/04/02 : 1.1.18 + - Haproxy can be compiled with PCRE regex instead of libc regex, by setting + REGEX=pcre on the make command line. + - HTTP health-checks now use "OPTIONS *" instead of "OPTIONS /". + - when explicit source address binding is required, it is now also used for + health-checks. + - added 'reqpass' and 'reqipass' to allow certain headers but not the request + itself. + - factored several strings to reduce binary size by about 2 kB. + - replaced setreuid() and setregid() with more standard setuid() and setgid(). + - added 4 status flags to the log line indicating who ended the connection + first, the sessions state, the validity of the cookie, and action taken on + the set-cookie header. + +2002/10/18 : 1.1.17 + - add the notion of "backup" servers, which are used only when all other + servers are down. + - make Set-Cookie return "" instead of "(null)" when the server has no + cookie assigned (useful for backup servers). + - "log" now supports an optionnal level name (info, notice, err ...) above + which nothing is sent. + - replaced some strncmp() with memcmp() for better efficiency. + - added "capture cookie" option which logs client and/or server cookies + - cleaned up/down messages and dump servers states upon SIGHUP + - added a redirection feature for errors : "errorloc " + - now we won't insist on connecting to a dead server, even with a cookie, + unless option "persist" is specified. + - added HTTP/408 response for client request time-out and HTTP/50[234] for + server reply time-out or errors. + +2002/09/01 : 1.1.16 + - implement HTTP health checks when option "httpchk" is specified. + +2002/08/07 : 1.1.15 + - replaced setpgid()/setpgrp() with setsid() for better portability, because + setpgrp() doesn't have the same meaning under Solaris, Linux, and OpenBSD. + +2002/07/20 : 1.1.14 + - added "postonly" cookie mode + +2002/07/15 : 1.1.13 + - tv_diff used inverted parameters which led to negative times ! + +2002/07/13 : 1.1.12 + - fixed stats monitoring, and optimized some tv_* for most common cases. + - replaced temporary 'newhdr' with 'trash' to reduce stack size + - made HTTP errors more HTML-fiendly. + - renamed strlcpy() to strlcpy2() because of a slightly difference between + their behaviour (return value), to avoid confusion. + - restricted HTTP messages to HTTP proxies only + - added a 502 message when the connection has been refused by the server, + to prevent clients from believing this is a zero-byte HTTP 0.9 reply. + - changed 'Cache-control:' from 'no-cache="set-cookie"' to 'private' when + inserting a cookie, because some caches (apache) don't understand it. + - fixed processing of server headers when client is in SHUTR state + +2002/07/04 : + - automatically close fd's 0,1 and 2 when going daemon ; setpgrp() after + setpgid() + +2002/06/04 : 1.1.11 + - fixed multi-cookie handling in client request to allow clean deletion + in insert+indirect mode. Now, only the server cookie is deleted and not + all the header. Should now be compliant to RFC2965. + - added a "nocache" option to "cookie" to specify that we explicitly want + to add a "cache-control" header when we add a cookie. + It is also possible to add an "Expires: " to keep compatibility + with old/broken caches. + +2002/05/10 : 1.1.10 + - if a cookie is used in insert+indirect mode, it's desirable that the + the servers don't see it. It was not possible to remove it correctly + with regexps, so now it's removed automatically. + +2002/04/19 : 1.1.9 + - don't use snprintf()'s return value as an end of message since it may + be larger. This caused bus errors and segfaults in internal libc's + getenv() during localtime() in send_log(). + - removed dead insecure send_syslog() function and all references to it. + - fixed warnings on Solaris due to buggy implementation of isXXXX(). + +2002/04/18 : 1.1.8 + - option "dontlognull" + - fixed "double space" bug in config parser + - fixed an uninitialized server field in case of dispatch + with no existing server which could cause a segfault during + logging. + - the pid logged was always the father's, which was wrong for daemons. + - fixed wrong level "LOG_INFO" for message "proxy started". + +2002/04/13 : + - http logging is now complete : + - ip:port, date, proxy, server + - req_time, conn_time, hdr_time, tot_time + - status, size, request + - source address + +2002/04/12 : 1.1.7 + - added option forwardfor + - added reqirep, reqidel, reqiallow, reqideny, rspirep, rspidel + - added "log global" in "listen" section. + +2002/04/09 : + - added a new "global" section : + - logs + - debug, quiet, daemon modes + - uid, gid, chroot, nbproc, maxconn + +2002/04/08 : 1.1.6 + - regex are now chained and not limited anymore. + - unavailable server now returns HTTP/502. + - increased per-line args limit to 40 + - added reqallow/reqdeny to block some request on matches + - added HTTP 400/403 responses + +2002/04/03 : 1.1.5 + - connection logging displayed incorrect source address. + - added proxy start/stop and server up/down log events. + - replaced log message short buffers with larger trash. + - enlarged buffer to 8 kB and replace buffer to 4 kB. + +2002/03/25 : 1.1.4 + - made rise/fall/interval time configurable + +2002/03/22 : 1.1.3 + - fixed a bug : cr_expire and cw_expire were inverted in CL_STSHUT[WR] + which could lead to loops. + +2002/03/21 : 1.1.2 + - fixed a bug in buffer management where we could have a loop + between event_read() and process_{cli|srv} if R==BUFSIZE-MAXREWRITE. + => implemented an adjustable buffer limit. + - fixed a bug : expiration of tasks in wait queue timeout is used again, + and running tasks are skipped. + - added some debug lines for accept events. + - send warnings for servers up/down. + +2002/03/12 : 1.1.1 + - fixed a bug in total failure handling + - fixed a bug in timestamp comparison within same second (tv_cmp_ms) + +2002/03/10 : 1.1.0 + - fixed a few timeout bugs + - rearranged the task scheduler subsystem to improve performance, + add new tasks, and make it easier to later port to librt ; + - allow multiple accept() for one select() wake up ; + - implemented internal load balancing with basic health-check ; + - cookie insertion and header add/replace/delete, with better strings + support. + +2002/03/08 + - reworked buffer handling to fix a few rewrite bugs, and + improve overall performance. + - implement the "purge" option to delete server cookies in direct mode. + +2002/03/07 + - fixed some error cases where the maxfd was not decreased. + +2002/02/26 + - now supports transparent proxying, at least on linux 2.4. + +2002/02/12 + - soft stop works again (fixed select timeout computation). + - it seems that TCP proxies sometimes cannot timeout. + - added a "quiet" mode. + - enforce file descriptor limitation on socket() and accept(). + +2001/12/30 : release of version 1.0.2 : fixed a bug in header processing +2001/12/19 : release of version 1.0.1 : no MSG_NOSIGNAL on solaris +2001/12/16 : release of version 1.0.0. +2001/12/16 : added syslog capability for each accepted connection. +2001/11/19 : corrected premature end of files and occasional SIGPIPE. +2001/10/31 : added health-check type servers (mode health) which replies OK then closes. +2001/10/30 : added the ability to support standard TCP proxies and HTTP proxies + with or without cookies (use keyword http for this). +2001/09/01 : added client/server header replacing with regexps. + eg: + cliexp ^(Host:\ [^:]*).* Host:\ \1:80 + srvexp ^Server:\ .* Server:\ Apache +2000/11/29 : first fully working release with complete FSMs and timeouts. +2000/11/28 : major rewrite +2000/11/26 : first write diff --git a/CONTRIBUTING b/CONTRIBUTING new file mode 100644 index 0000000..60a78ba --- /dev/null +++ b/CONTRIBUTING @@ -0,0 +1,1020 @@ + HOW TO GET YOUR CODE ACCEPTED IN HAPROXY + READ THIS CAREFULLY BEFORE SUBMITTING CODE + +THIS DOCUMENT PROVIDES SOME RULES TO FOLLOW WHEN SENDING CONTRIBUTIONS. PATCHES +NOT FOLLOWING THESE RULES WILL SIMPLY BE IGNORED IN ORDER TO PROTECT ALL OTHER +RESPECTFUL CONTRIBUTORS' VALUABLE TIME. + + +Abstract +-------- + +If you have never contributed to HAProxy before, or if you did so and noticed +that nobody seems to be interested in reviewing your submission, please do read +this long document carefully. HAProxy maintainers are particularly demanding on +respecting certain simple rules related to general code and documentation style +as well as splitting your patches and providing high quality commit messages. +The reason behind this is that your patch will be met multiple times in the +future, when doing some backporting work or when bisecting a bug, and it is +critical that anyone can quickly decide if the patch is right, wrong, if it +misses something, if it must be reverted or needs to be backported. Maintainers +are generally benevolent with newcomers and will help them provided their work +indicates they have at least read this document. Some have improved over time, +to the point of being totally trusted and gaining commit access so they don't +need to depend on anyone to pick their code. On the opposite, those who insist +not making minimal efforts however will simply be ignored. + + +Background +---------- + +HAProxy is a community-driven project. But like most highly technical projects +it takes a lot of time to develop the skills necessary to be autonomous in the +project, and there is a very small core team helped by a small set of very +active participants. While most of the core team members work on the code as +part of their day job, most participants do it on a voluntary basis during +their spare time. The ideal model for developers is to spend their time: + 1) developing new features + 2) fixing bugs + 3) doing maintenance backports + 4) reviewing other people's code + +It turns out that on a project like HAProxy, like many other similarly complex +projects, the time spent is exactly the opposite: + 1) reviewing other people's code + 2) doing maintenance backports + 3) fixing bugs + 4) developing new features + +A large part of the time spent reviewing code often consists in giving basic +recommendations that are already explained in this file. In addition to taking +time, it is not appealing for people willing to spend one hour helping others +to do the same thing over and over instead of discussing the code design, and +it tends to delay the start of code reviews. + +Regarding backports, they are necessary to provide a set of stable branches +that are deployed in production at many places. Load balancers are complex and +new features often induce undesired side effects in other areas, which we will +call bugs. Thus it's common for users to stick to a branch featuring everything +they need and not to upgrade too often. This backporting job is critical to the +ecosystem's health and must be done regularly. Very often the person devoting +some time on backports has little to no information about the relevance (let +alone importance) of a patch and is unlikely to be an expert in the area +affected by the patch. It's the role of the commit message to explain WHAT +problem the patch tries to solve, WHY it is estimated that it is a problem, and +HOW it tries to address it. With these elements, the person in charge of the +backports can decide whether or not to pick the patch. And if the patch does +not apply (which is common for older versions) they have information in the +commit message about the principle and choices that the initial developer made +and will try to adapt the patch sticking to these principles. Thus, the time +spent backporting patches solely depends on the code quality and the commit +message details and accuracy. + +When it turns to fixing bugs, before declaring a bug, there is an analysis +phase. It starts with "is this behaviour expected", "is it normal", "under what +circumstances does it happen", "when did it start to happen", "was it intended", +"was it just overlooked", and "how to fix it without breaking the initial +intent". A utility called "git bisect" is usually involved in determining when +the behaviour started to happen. It determines the first patch which introduced +the new behaviour. If the patch is huge, touches many areas, is really difficult +to read because it needlessly reindents code or adds/removes line breaks out of +context, it will be very difficult to figure what part of this patch broke the +behaviour. Then once the part is figured, if the commit message doesn't provide +a detailed description about the intent of the patch, i.e. the problem it was +trying to solve, why and how, the developer landing on that patch will really +feel powerless. And very often in this case, the fix for the problem will break +something else or something that depended on the original patch. + +But contrary to what it could look like, providing great quality patches is not +difficult, and developers will always help contributors improve their patches +quality because it's in their interest as well. History has shown that first +time contributors can provide an excellent work when they have carefully read +this document, and that people coming from projects with different practices +can grow from first-time contributor to trusted committer in about 6 months. + + +Preparation +----------- + +It is possible that you'll want to add a specific feature to satisfy your needs +or one of your customers'. Contributions are welcome, however maintainers are +often very picky about changes. Patches that change massive parts of the code, +or that touch the core parts without any good reason will generally be rejected +if those changes have not been discussed first. + +The proper place to discuss your changes is the HAProxy Mailing List. There are +enough skilled readers to catch hazardous mistakes and to suggest improvements. +There is no other place where you'll find as many skilled people on the project, +and these people can help you get your code integrated quickly. You can +subscribe to it by sending an empty e-mail at the following address : + + haproxy+subscribe@formilux.org + +It is not even necessary to subscribe, you can post there and verify via the +public list archives that your message was properly delivered. In this case you +should indicate in your message that you'd like responders to keep you CCed. +Please visit http://haproxy.org/ to figure available options to join the list. + +If you have an idea about something to implement, *please* discuss it on the +list first. It has already happened several times that two persons did the same +thing simultaneously. This is a waste of time for both of them. It's also very +common to see some changes rejected because they're done in a way that will +conflict with future evolutions, or that does not leave a good feeling. It's +always unpleasant for the person who did the work, and it is unpleasant in +general because people's time and efforts are valuable and would be better +spent working on something else. That would not happen if these were discussed +first. There is no problem posting work in progress to the list, it happens +quite often in fact. Just prefix your mail subject with "RFC" (it stands for +"request for comments") and everyone will understand you'd like some opinion +on your work in progress. Also, don't waste your time with the doc when +submitting patches for review, only add the doc with the patch you consider +ready to merge (unless you need some help on the doc itself, of course). + +Another important point concerns code portability. HAProxy requires gcc as the +C compiler, and may or may not work with other compilers. However it's known to +build using gcc 2.95 or any later version. As such, it is important to keep in +mind that certain facilities offered by recent versions must not be used in the +code: + + - declarations mixed in the code (requires gcc >= 3.x and is a bad practice) + - GCC builtins without checking for their availability based on version and + architecture ; + - assembly code without any alternate portable form for other platforms + - use of stdbool.h, "bool", "false", "true" : simply use "int", "0", "1" + - in general, anything which requires C99 (such as declaring variables in + "for" statements) + +Since most of these restrictions are just a matter of coding style, it is +normally not a problem to comply. Please read doc/coding-style.txt for all the +details. + +When modifying some optional subsystem (SSL, Lua, compression, device detection +engines), please make sure the code continues to build (and to work) when these +features are disabled. Similarly, when modifying the SSL stack, please always +ensure that supported OpenSSL versions continue to build and to work, especially +if you modify support for alternate libraries. Clean support for the legacy +OpenSSL libraries is mandatory, support for its derivatives is a bonus and may +occasionally break even though a great care is taken. In other words, if you +provide a patch for OpenSSL you don't need to test its derivatives, but if you +provide a patch for a derivative you also need to test with OpenSSL. + +If your work is very confidential and you can't publicly discuss it, you can +also mail willy@haproxy.org directly about it, but your mail may be waiting +several days in the queue before you get a response, if you get a response at +all. Retransmit if you don't get a response by one week. Please note that +direct sent e-mails to this address for non-confidential subjects may simply +be forwarded to the list or be deleted without notification. An auto-responder +bot is in place to try to detect e-mails from people asking for help and to +redirect them to the mailing list. Do not be surprised if this happens to you. + +If you'd like a feature to be added but you think you don't have the skills to +implement it yourself, you should follow these steps : + + 1. discuss the feature on the mailing list. It is possible that someone + else has already implemented it, or that someone will tell you how to + proceed without it, or even why not to do it. It is also possible that + in fact it's quite easy to implement and people will guide you through + the process. That way you'll finally have YOUR patch merged, providing + the feature YOU need. + + 2. if you really can't code it yourself after discussing it, then you may + consider contacting someone to do the job for you. Some people on the + list might sometimes be OK with trying to do it. + +The version control system used by the project (Git) keeps authorship +information in the form of the patch author's e-mail address. This way you will +be credited for your work in the project's history. If you contract with +someone to implement your idea you may have to discuss such modalities with +the person doing the work as by default this person will be mentioned as the +work's author. + + +Rules: the 12 laws of patch contribution +---------------------------------------- + +People contributing patches must apply the following rules. That may sound heavy +at the beginning but it's common sense more than anything else and contributors +do not think about them anymore after a few patches. + +1) Comply with the license + + Before modifying some code, you have read the LICENSE file ("main license") + coming with the sources, and all the files this file references. Certain + files may be covered by different licenses, in which case it will be + indicated in the files themselves. In any case, you agree to respect these + licenses and to contribute your changes under the same licenses. If you want + to create new files, they will be under the main license, or any license of + your choice that you have verified to be compatible with the main license, + and that will be explicitly mentioned in the affected files. The project's + maintainers are free to reject contributions proposing license changes they + feel are not appropriate or could cause future trouble. + +2) Develop on development branch, not stable ones + + Your work may only be based on the latest development version. No development + is made on a stable branch. If your work needs to be applied to a stable + branch, it will first be applied to the development branch and only then will + be backported to the stable branch. You are responsible for ensuring that + your work correctly applies to the development version. If at any moment you + are going to work on restructuring something important which may impact other + contributors, the rule that applies is that the first sent is the first + served. However it is considered good practice and politeness to warn others + in advance if you know you're going to make changes that may force them to + re-adapt their code, because they did probably not expect to have to spend + more time discovering your changes and rebasing their work. + +3) Read and respect the coding style + + You have read and understood "doc/coding-style.txt", and you're actively + determined to respect it and to enforce it on your coworkers if you're going + to submit a team's work. We don't care what text editor you use, whether it's + an hex editor, cat, vi, emacs, Notepad, Word, or even Eclipse. The editor is + only the interface between you and the text file. What matters is what is in + the text file in the end. The editor is not an excuse for submitting poorly + indented code, which only proves that the person has no consideration for + quality and/or has done it in a hurry (probably worse). Please note that most + bugs were found in low-quality code. Reviewers know this and tend to be much + more reluctant to accept poorly formatted code because by experience they + won't trust their author's ability to write correct code. It is also worth + noting that poor quality code is painful to read and may result in nobody + willing to waste their time even reviewing your work. + +4) Present clean work + + The time it takes for you to polish your code is always much smaller than the + time it takes others to do it for you, because they always have to wonder if + what they see is intended (meaning they didn't understand something) or if it + is a mistake that needs to be fixed. And since there are less reviewers than + submitters, it is vital to spread the effort closer to where the code is + written and not closer to where it gets merged. For example if you have to + write a report for a customer that your boss wants to review before you send + it to the customer, will you throw on his desk a pile of paper with stains, + typos and copy-pastes everywhere ? Will you say "come on, OK I made a mistake + in the company's name but they will find it by themselves, it's obvious it + comes from us" ? No. When in doubt, simply ask for help on the mailing list. + +5) Documentation is very important + + There are four levels of importance of quality in the project : + + - The most important one, and by far, is the quality of the user-facing + documentation. This is the first contact for most users and it immediately + gives them an accurate idea of how the project is maintained. Dirty docs + necessarily belong to a dirty project. Be careful to the way the text you + add is presented and indented. Be very careful about typos, usual mistakes + such as double consonants when only one is needed or "it's" instead of + "its", don't mix US English and UK English in the same paragraph, etc. + When in doubt, check in a dictionary. Fixes for existing typos in the doc + are always welcome and chasing them is a good way to become familiar with + the project and to get other participants' respect and consideration. + + - The second most important level is user-facing messages emitted by the + code. You must try to see all the messages your code produces to ensure + they are understandable outside of the context where you wrote them, + because the user often doesn't expect them. That's true for warnings, and + that's even more important for errors which prevent the program from + working and which require an immediate and well understood fix in the + configuration. It's much better to say "line 35: compression level must be + an integer between 1 and 9" than "invalid argument at line 35". In HAProxy, + error handling roughly represents half of the code, and that's about 3/4 of + the configuration parser. Take the time to do something you're proud of. A + good rule of thumb is to keep in mind that your code talks to a human and + tries to teach them how to proceed. It must then speak like a human. + + - The third most important level is the code and its accompanying comments, + including the commit message which is a complement to your code and + comments. It's important for all other contributors that the code is + readable, fluid, understandable and that the commit message describes what + was done, the choices made, the possible alternatives you thought about, + the reason for picking this one and its limits if any. Comments should be + written where it's easy to have a doubt or after some error cases have been + wiped out and you want to explain what possibilities remain. All functions + must have a comment indicating what they take on input and what they + provide on output. Please adjust the comments when you copy-paste a + function or change its prototype, this type of lazy mistake is too common + and very confusing when reading code later to debug an issue. Do not forget + that others will feel really angry at you when they have to dig into your + code for a bug that your code caused and they feel like this code is dirty + or confusing, that the commit message doesn't explain anything useful and + that the patch should never have been accepted in the first place. That + will strongly impact your reputation and will definitely affect your + chances to contribute again! + + - The fourth level of importance is in the technical documentation that you + may want to add with your code. Technical documentation is always welcome + as it helps others make the best use of your work and to go exactly in the + direction you thought about during the design. This is also what reduces + the risk that your design gets changed in the near future due to a misuse + and/or a poor understanding. All such documentation is actually considered + as a bonus. It is more important that this documentation exists than that + it looks clean. Sometimes just copy-pasting your draft notes in a file to + keep a record of design ideas is better than losing them. Please do your + best so that other ones can read your doc. If these docs require a special + tool such as a graphics utility, ensure that the file name makes it + unambiguous how to process it. So there are no rules here for the contents, + except one. Please write the date in your file. Design docs tend to stay + forever and to remain long after they become obsolete. At this point that + can cause harm more than it can help. Writing the date in the document + helps developers guess the degree of validity and/or compare them with the + date of certain commits touching the same area. + +6) US-ASCII only! + + All text files and commit messages are written using the US-ASCII charset. + Please be careful that your contributions do not contain any character not + printable using this charset, as they will render differently in different + editors and/or terminals. Avoid latin1 and more importantly UTF-8 which some + editors tend to abuse to replace some US-ASCII characters with their + typographic equivalent which aren't readable anymore in other editors. The + only place where alternative charsets are tolerated is in your name in the + commit message, but it's at your own risk as it can be mangled during the + merge. Anyway if you have an e-mail address, you probably have a valid + US-ASCII representation for it as well. + +7) Comments + + Be careful about comments when you move code around. It's not acceptable that + a block of code is moved to another place leaving irrelevant comments at the + old place, just like it's not acceptable that a function is duplicated without + the comments being adjusted. The example below started to become quite common + during the 1.6 cycle, it is not acceptable and wastes everyone's time : + + /* Parse switching to build rule . Returns 0 on error. */ + int parse_switching_rule(const char *str, struct rule *rule) + { + ... + } + + /* Parse switching to build rule . Returns 0 on error. */ + void execute_switching_rule(struct rule *rule) + { + ... + } + + This patch is not acceptable either (and it's unfortunately not that rare) : + + + if (!session || !arg || list_is_empty(&session->rules->head)) + + return 0; + + + /* Check if session->rules is valid before dereferencing it */ + if (!session->rules_allocated) + return 0; + + - if (!arg || list_is_empty(&session->rules->head)) + - return 0; + - + +8) Short, readable identifiers + + Limit the length of your identifiers in the code. When your identifiers start + to sound like sentences, it's very hard for the reader to keep on track with + what operation they are observing. Also long names force expressions to fit + on several lines which also cause some difficulties to the reader. See the + example below : + + int file_name_len_including_global_path; + int file_name_len_without_global_path; + int global_path_len_or_zero_if_default; + + if (global_path) + global_path_len_or_zero_if_default = strlen(global_path); + else + global_path_len_or_zero_if_default = 0; + + file_name_len_without_global_path = strlen(file_name); + file_name_len_including_global_path = + file_name_len_without_global_path + 1 + /* for '/' */ + global_path_len_or_zero_if_default ? + global_path_len_or_zero_if_default : default_path_len; + + Compare it to this one : + + int f, p; + + p = global_path ? strlen(global_path) : default_path_len; + f = p + 1 + strlen(file_name); /* 1 for '/' */ + + A good rule of thumb is that if your identifiers start to contain more than + 3 words or more than 15 characters, they can become confusing. For function + names it's less important especially if these functions are rarely used or + are used in a complex context where it is important to differentiate between + their multiple variants. + +9) Unified diff only + + The best way to build your patches is to use "git format-patch". This means + that you have committed your patch to a local branch, with an appropriate + subject line and a useful commit message explaining what the patch attempts + to do. It is not strictly required to use git, but what is strictly required + is to have all these elements in the same mail, easily distinguishable, and + a patch in "diff -up" format (which is also the format used by Git). This + means the "unified" diff format must be used exclusively, and with the + function name printed in the diff header of each block. That significantly + helps during reviews. Keep in mind that most reviews are done on the patch + and not on the code after applying the patch. Your diff must keep some + context (3 lines above and 3 lines below) so that there's no doubt where the + code has to be applied. Don't change code outside of the context of your + patch (eg: take care of not adding/removing empty lines once you remove + your debugging code). If you are using Git (which is strongly recommended), + always use "git show" after doing a commit to ensure it looks good, and + enable syntax coloring that will automatically report in red the trailing + spaces or tabs that your patch added to the code and that must absolutely be + removed. These ones cause a real pain to apply patches later because they + mangle the context in an invisible way. Such patches with trailing spaces at + end of lines will be rejected. + +10) One patch per feature + + Please cut your work in series of patches that can be independently reviewed + and merged. Each patch must do something on its own that you can explain to + someone without being ashamed of what you did. For example, you must not say + "This is the patch that implements SSL, it was tricky". There's clearly + something wrong there, your patch will be huge, will definitely break things + and nobody will be able to figure what exactly introduced the bug. However + it's much better to say "I needed to add some fields in the session to store + the SSL context so this patch does this and doesn't touch anything else, so + it's safe". Also when dealing with series, you will sometimes fix a bug that + one of your patches introduced. Please do merge these fixes (eg: using git + rebase -i and squash or fixup), as it is not acceptable to see patches which + introduce known bugs even if they're fixed later. Another benefit of cleanly + splitting patches is that if some of your patches need to be reworked after + a review, the other ones can still be merged so that you don't need to care + about them anymore. When sending multiple patches for review, prefer to send + one e-mail per patch than all patches in a single e-mail. The reason is that + not everyone is skilled in all areas nor has the time to review everything + at once. With one patch per e-mail, it's easy to comment on a single patch + without giving an opinion on the other ones, especially if a long thread + starts about one specific patch on the mailing list. "git send-email" does + that for you though it requires a few trials before getting it right. + + If you can, please always put all the bug fixes at the beginning of the + series. This often makes it easier to backport them because they will not + depend on context that your other patches changed. As a hint, if you can't + do this, there are little chances that your bug fix can be backported. + +11) Real commit messages please! + + The commit message is how you're trying to convince a maintainer to adopt + your work and maintain it as long as possible. A dirty commit message almost + always comes with dirty code. Too short a commit message indicates that too + short an analysis was done and that side effects are extremely likely to be + encountered. It's the maintainer's job to decide to accept this work in its + current form or not, with the known constraints. Some patches which rework + architectural parts or fix sensitive bugs come with 20-30 lines of design + explanations, limitations, hypothesis or even doubts, and despite this it + happens when reading them 6 months later while trying to identify a bug that + developers still miss some information about corner cases. + + So please properly format your commit messages. To get an idea, just run + "git log" on the file you've just modified. Patches always have the format + of an e-mail made of a subject, a description and the actual patch. If you + are sending a patch as an e-mail formatted this way, it can quickly be + applied with limited effort so that's acceptable : + + - A subject line (may wrap to the next line, but please read below) + - an empty line (subject delimiter) + - a non-empty description (the body of the e-mail) + - the patch itself + + The subject describes the "What" of the change ; the description explains + the "why", the "how" and sometimes "what next". For example a commit message + looking like this will be rejected : + + | From: Mr Foobar + | Subject: BUG: fix typo in ssl_sock + | + + This one as well (too long subject, not the right place for the details) : + + | From: Mr Foobar + | Subject: BUG/MEDIUM: ssl: use an error flag to prevent ssl_read() from + | returning 0 when dealing with large buffers because that can cause + | an infinite loop + | + + This one ought to be used instead : + + | From: Mr Foobar + | Subject: BUG/MEDIUM: ssl: fix risk of infinite loop in ssl_sock + | + | ssl_read() must not return 0 on error or the caller may loop forever. + | Instead we add a flag to the connection to notify about the error and + | check it at all call places. This situation can only happen with large + | buffers so a workaround is to limit buffer sizes. Another option would + | have been to return -1 but it required to use signed ints everywhere + | and would have made the patch larger and riskier. This fix should be + | backported to versions 1.2 and upper. + + It is important to understand that for any reader to guess the text above + when it's absent, it will take a huge amount of time. If you made the + analysis leading to your patch, you must explain it, including the ideas + you dropped if you had a good reason for this. + + While it's not strictly required to use Git, it is strongly recommended + because it helps you do the cleanest job with the least effort. But if you + are comfortable with writing clean e-mails and inserting your patches, you + don't need to use Git. + + But in any case, it is important that there is a clean description of what + the patch does, the motivation for what it does, why it's the best way to do + it, its impacts, and what it does not yet cover. And this is particularly + important for bugs. A patch tagged "BUG" must absolutely explain what the + problem is, why it is considered as a bug. Anybody, even non-developers, + should be able to tell whether or not a patch is likely to address an issue + they are facing. Indicating what the code will do after the fix doesn't help + if it does not say what problem is encountered without the patch. Note that + in some cases the bug is purely theoretical and observed by reading the code. + In this case it's perfectly fine to provide an estimate about possible + effects. Also, in HAProxy, like many projects which take a great care of + maintaining stable branches, patches are reviewed later so that some of them + can be backported to stable releases. + + While reviewing hundreds of patches can seem cumbersome, with a proper + formatting of the subject line it actually becomes very easy. For example, + here's how one can find patches that need to be reviewed for backports (bugs + and doc) between since commit ID 827752e : + + $ git log --oneline 827752e.. | grep 'BUG\|DOC' + 0d79cf6 DOC: fix function name + bc96534 DOC: ssl: missing LF + 10ec214 BUG/MEDIUM: lua: the lua function Channel:close() causes a segf + bdc97a8 BUG/MEDIUM: lua: outgoing connection was broken since 1.6-dev2 + ba56d9c DOC: mention support for RFC 5077 TLS Ticket extension in start + f1650a8 DOC: clarify some points about SSL and the proxy protocol + b157d73 BUG/MAJOR: peers: fix current table pointer not re-initialized + e1ab808 BUG/MEDIUM: peers: fix wrong message id on stick table updates + cc79b00 BUG/MINOR: ssl: TLS Ticket Key rotation broken via socket comma + d8e42b6 DOC: add new file intro.txt + c7d7607 BUG/MEDIUM: lua: bad error processing + 386a127 DOC: match several lua configuration option names to those impl + 0f4eadd BUG/MEDIUM: counters: ensure that src_{inc,clr}_gpc0 creates a + + It is made possible by the fact that subject lines are properly formatted and + always respect the same principle : one part indicating the nature and + severity of the patch, another one to indicate which subsystem is affected, + and the last one is a succinct description of the change, with the important + part at the beginning so that it's obvious what it does even when lines are + truncated like above. The whole stable maintenance process relies on this. + For this reason, it is mandatory to respect some easy rules regarding the + way the subject is built. Please see the section below for more information + regarding this formatting. + + As a rule of thumb, your patch MUST NEVER be made only of a subject line, + it *must* contain a description. Even one or two lines, or indicating + whether a backport is desired or not. It turns out that single-line commits + are so rare in the Git world that they require special manual (hence + painful) handling when they are backported, and at least for this reason + it's important to keep this in mind. + + Maintainers who pick your patch may slightly adjust the description as they + see fit. Do not see this as a failure to do a clean job, it just means they + think it will help them do their daily job this way. The code may also be + slightly adjusted before being merged (non-functional changes only, fix for + typos, tabs vs spaces for example), unless your patch contains a + Signed-off-By tag, in which case they will either modify it and mention the + changes after your Signed-off-By line, or (more likely) ask you to perform + these changes yourself. This ability to slightly adjust a patch before + merging is is the main reason for not using pull requests which do not + provide this facility and will require to iterate back and forth with the + submitter and significantly delay the patch inclusion. + + Each patch fixing a bug MUST be tagged with "BUG", a severity level, an + indication of the affected subsystem and a brief description of the nature + of the issue in the subject line, and a detailed analysis in the message + body. The explanation of the user-visible impact and the need for + backporting to stable branches or not are MANDATORY. Bug fixes with no + indication will simply be rejected as they are very likely to cause more + harm when nobody is able to tell whether or not the patch needs to be + backported or can be reverted in case of regression. + + When fixing a bug which is reproducible, if possible, the contributors are + strongly encouraged to write a regression testing VTC file for varnishtest + to add to reg-tests directory. More information about varnishtest may be + found in README file of reg-tests directory and in doc/regression-testing.txt + file. + +12) Discuss on the mailing list + + Note, some first-time contributors might feel impressed or scared by posting + to a list. This list is frequented only by nice people who are willing to + help you polish your work so that it is perfect and can last long. What you + think could be perceived as a proof of incompetence or lack of care will + instead be a proof of your ability to work with a community. You will not be + judged nor blamed for making mistakes. The project maintainers are the ones + creating the most bugs and mistakes anyway, and nobody knows the project in + its entirety anymore so you're just like anyone else. And people who have no + consideration for other's work are quickly ejected from the list so the + place is as safe and welcoming to new contributors as it is to long time + ones. + + When submitting changes, please always CC the mailing list address so that + everyone gets a chance to spot any issue in your code. It will also serve + as an advertisement for your work, you'll get more testers quicker and + you'll feel better knowing that people really use your work. It's often + convenient to prepend "[PATCH]" in front of your mail's subject to mention + that this e-mail contains a patch (or a series of patches), because it will + easily catch reviewer's attention. It's automatically done by tools such as + "git format-patch" and "git send-email". If you don't want your patch to be + merged yet and prefer to show it for discussion, better tag it as "[RFC]" + (stands for "Request For Comments") and it will be reviewed but not merged + without your approval. It is also important to CC any author mentioned in + the file you change, or a subsystem maintainers whose address is mentioned + in a MAINTAINERS file. Not everyone reads the list on a daily basis so it's + very easy to miss some changes. Don't consider it as a failure when a + reviewer tells you you have to modify your patch, actually it's a success + because now you know what is missing for your work to get accepted. That's + why you should not hesitate to CC enough people. Don't copy people who have + no deal with your work area just because you found their address on the + list. That's the best way to appear careless about their time and make them + reject your changes in the future. + + +Patch classifying rules +----------------------- + +There are 3 criteria of particular importance in any patch : + - its nature (is it a fix for a bug, a new feature, an optimization, ...) + - its importance, which generally reflects the risk of merging/not merging it + - what area it applies to (eg: http, stats, startup, config, doc, ...) + +It's important to make these 3 criteria easy to spot in the patch's subject, +because it's the first (and sometimes the only) thing which is read when +reviewing patches to find which ones need to be backported to older versions. +It also helps when trying to find which patch is the most likely to have caused +a regression. + +Specifically, bugs must be clearly easy to spot so that they're never missed. +Any patch fixing a bug must have the "BUG" tag in its subject. Most common +patch types include : + + - BUG fix for a bug. The severity of the bug should also be indicated + when known. Similarly, if a backport is needed to older versions, + it should be indicated on the last line of the commit message. The + commit message MUST ABSOLUTELY describe the problem and its impact + to non-developers. Any user must be able to guess if this patch is + likely to fix a problem they are facing. Even if the bug was + discovered by accident while reading the code or running an + automated tool, it is mandatory to try to estimate what potential + issue it might cause and under what circumstances. There may even + be security implications sometimes so a minimum analysis is really + required. Also please think about stable maintainers who have to + build the release notes, they need to have enough input about the + bug's impact to explain it. If the bug has been identified as a + regression brought by a specific patch or version, this indication + will be appreciated too. New maintenance releases are generally + emitted when a few of these patches are merged. If the bug is a + vulnerability for which a CVE identifier was assigned before you + publish the fix, you can mention it in the commit message, it will + help distro maintainers. + + - CLEANUP code cleanup, silence of warnings, etc... theoretically no impact. + These patches will rarely be seen in stable branches, though they + may appear when they remove some annoyance or when they make + backporting easier. By nature, a cleanup is always of minor + importance and it's not needed to mention it. + + - DOC updates to any of the documentation files, including README. Many + documentation updates are backported since they don't impact the + product's stability and may help users avoid bugs. So please + indicate in the commit message if a backport is desired. When a + feature gets documented, it's preferred that the doc patch appears + in the same patch or after the feature patch, but not before, as it + becomes confusing when someone working on a code base including + only the doc patch won't understand why a documented feature does + not work as documented. + + - REORG code reorganization. Some blocks may be moved to other places, + some important checks might be swapped, etc... These changes + always present a risk of regression. For this reason, they should + never be mixed with any bug fix nor functional change. Code is + only moved as-is. Indicating the risk of breakage is highly + recommended. Minor breakage is tolerated in such patches if trying + to fix it at once makes the whole change even more confusing. That + may happen for example when some #ifdefs need to be propagated in + every file consecutive to the change. + + - BUILD updates or fixes for build issues. Changes to makefiles also fall + into this category. The risk of breakage should be indicated if + known. It is also appreciated to indicate what platforms and/or + configurations were tested after the change. + + - OPTIM some code was optimised. Sometimes if the regression risk is very + low and the gains significant, such patches may be merged in the + stable branch. Depending on the amount of code changed or replaced + and the level of trust the author has in the change, the risk of + regression should be indicated. If the optimization depends on the + architecture or on build options, it is important to verify that + the code continues to work without it. + + - RELEASE release of a new version (development or stable). + + - LICENSE licensing updates (may impact distro packagers). + + - REGTEST updates to any of the regression testing files found in reg-tests + directory, including README or any documentation file. + + +When the patch cannot be categorized, it's best not to put any type tag, and to +only use a risk or complexity information only as below. This is commonly the +case for new features, which development versions are mostly made of. + +The importance, complexity of the patch, or severity of the bug it fixes must +be indicated when relevant. A single upper-case word is preferred, among : + + - MINOR minor change, very low risk of impact. It is often the case for + code additions that don't touch live code. As a rule of thumb, a + patch tagged "MINOR" is safe enough to be backported to stable + branches. For a bug, it generally indicates an annoyance, nothing + more. + + - MEDIUM medium risk, may cause unexpected regressions of low importance or + which may quickly be discovered. In short, the patch is safe but + touches working areas and it is always possible that you missed + something you didn't know existed (eg: adding a "case" entry or + an error message after adding an error code to an enum). For a bug, + it generally indicates something odd which requires changing the + configuration in an undesired way to work around the issue. + + - MAJOR major risk of hidden regression. This happens when large parts of + the code are rearranged, when new timeouts are introduced, when + sensitive parts of the session scheduling are touched, etc... We + should only exceptionally find such patches in stable branches when + there is no other option to fix a design issue. For a bug, it + indicates severe reliability issues for which workarounds are + identified with or without performance impacts. + + - CRITICAL medium-term reliability or security is at risk and workarounds, + if they exist, might not always be acceptable. An upgrade is + absolutely required. A maintenance release may be emitted even if + only one of these bugs are fixed. Note that this tag is only used + with bugs. Such patches must indicate what is the first version + affected, and if known, the commit ID which introduced the issue. + +The expected length of the commit message grows with the importance of the +change. While a MINOR patch may sometimes be described in 1 or 2 lines, MAJOR +or CRITICAL patches cannot have less than 10-15 lines to describe exactly the +impacts otherwise the submitter's work will be considered as rough sabotage. +If you are sending a new patch series after a review, it is generally good to +enumerate at the end of the commit description what changed from the previous +one as it helps reviewers quickly glance over such changes and not re-read the +rest. + +For BUILD, DOC and CLEANUP types, this tag is not always relevant and may be +omitted. + +The area the patch applies to is quite important, because some areas are known +to be similar in older versions, suggesting a backport might be desirable, and +conversely, some areas are known to be specific to one version. The area is a +single-word lowercase name the contributor find clear enough to describe what +part is being touched. The following list of tags is suggested but not +exhaustive: + + - examples example files. Be careful, sometimes these files are packaged. + + - tests regression test files. No code is affected, no need to upgrade. + + - reg-tests regression test files for varnishtest. No code is affected, no + need to upgrade. + + - init initialization code, arguments parsing, etc... + + - config configuration parser, mostly used when adding new config keywords + + - http the HTTP engine + + - stats the stats reporting engine + + - cli the stats socket CLI + + - checks the health checks engine (eg: when adding new checks) + + - sample the sample fetch system (new fetch or converter functions) + + - acl the ACL processing core or some ACLs from other areas + + - filters everything related to the filters core + + - peers the peer synchronization engine + + - lua the Lua scripting engine + + - listeners everything related to incoming connection settings + + - frontend everything related to incoming connection processing + + - backend everything related to LB algorithms and server farm + + - session session processing and flags (very sensible, be careful) + + - server server connection management, queueing + + - spoe SPOE code + + - ssl the SSL/TLS interface + + - proxy proxy maintenance (start/stop) + + - log log management + + - poll any of the pollers + + - halog the halog sub-component in the admin directory + + - htx general HTX subsystem + + - mux-h1 HTTP/1.x multiplexer/demultiplexer + + - mux-h2 HTTP/2 multiplexer/demultiplexer + + - h1 general HTTP/1.x protocol parser + + - h2 general HTTP/2 protocol parser + +Other names may be invented when more precise indications are meaningful, for +instance : "cookie" which indicates cookie processing in the HTTP core. Last, +indicating the name of the affected file is also a good way to quickly spot +changes. Many commits were already tagged with "stream_sock" or "cfgparse" for +instance. + +It is required that the type of change and the severity when relevant are +indicated, as well as the touched area when relevant as well in the patch +subject. Normally, we would have the 3 most often. The two first criteria should +be present before a first colon (':'). If both are present, then they should be +delimited with a slash ('/'). The 3rd criterion (area) should appear next, also +followed by a colon. Thus, all of the following subject lines are valid : + +Examples of subject lines : + - DOC: document options forwardfor to logasap + - DOC/MAJOR: reorganize the whole document and change indenting + - BUG: stats: connection reset counters must be plain ascii, not HTML + - BUG/MINOR: stats: connection reset counters must be plain ascii, not HTML + - MEDIUM: checks: support multi-packet health check responses + - RELEASE: Released version 1.4.2 + - BUILD: stats: stdint is not present on solaris + - OPTIM/MINOR: halog: make fgets parse more bytes by blocks + - REORG/MEDIUM: move syscall redefinition to specific places + +Please do not use square brackets anymore around the tags, because they induce +more work when merging patches, which need to be hand-edited not to lose the +enclosed part. + +In fact, one of the only square bracket tags that still makes sense is '[RFC]' +at the beginning of the subject, when you're asking for someone to review your +change before getting it merged. If the patch is OK to be merged, then it can +be merge as-is and the '[RFC]' tag will automatically be removed. If you don't +want it to be merged at all, you can simply state it in the message, or use an +alternate 'WIP/' prefix in front of your tag tag ("work in progress"). + +The tags are not rigid, follow your intuition first, and they may be readjusted +when your patch is merged. It may happen that a same patch has a different tag +in two distinct branches. The reason is that a bug in one branch may just be a +cleanup or safety measure in the other one because the code cannot be triggered. + + +Working with Git +---------------- + +For a more efficient interaction between the mainline code and your code, you +are strongly encouraged to try the Git version control system : + + http://git-scm.com/ + +It's very fast, lightweight and lets you undo/redo your work as often as you +want, without making your mistakes visible to the rest of the world. It will +definitely help you contribute quality code and take other people's feedback +in consideration. In order to clone the HAProxy Git repository : + + $ git clone http://git.haproxy.org/git/haproxy.git/ (development) + +If you decide to use Git for your developments, then your commit messages will +have the subject line in the format described above, then the whole description +of your work (mainly why you did it) will be in the body. You can directly send +your commits to the mailing list, the format is convenient to read and process. + +It is recommended to create a branch for your work that is based on the master +branch : + + $ git checkout -b 20150920-fix-stats master + +You can then do your work and even experiment with multiple alternatives if you +are not completely sure that your solution is the best one : + + $ git checkout -b 20150920-fix-stats-v2 + +Then reorder/merge/edit your patches : + + $ git rebase -i master + +When you think you're ready, reread your whole patchset to ensure there is no +formatting or style issue : + + $ git show master.. + +And once you're satisfied, you should update your master branch to be sure that +nothing changed during your work (only needed if you left it unattended for days +or weeks) : + + $ git checkout -b 20150920-fix-stats-rebased + $ git fetch origin master:master + $ git rebase master + +You can build a list of patches ready for submission like this : + + $ git format-patch master + +The output files are the patches ready to be sent over e-mail, either via a +regular e-mail or via git send-email (carefully check the man page). Don't +destroy your other work branches until your patches get merged, it may happen +that earlier designs will be preferred for various reasons. Patches should be +sent to the mailing list : haproxy@formilux.org and CCed to relevant subsystem +maintainers or authors of the modified files if their address appears at the +top of the file. + +Please don't send pull requests, they are really inconvenient as they make it +much more complicate to perform minor adjustments, and nobody benefits from +any comment on the code while on a list all subscribers learn a little bit on +each review of anyone else's code. + + +What to do if your patch is ignored +----------------------------------- + +All patches merged are acknowledged by the maintainer who picked it. If you +didn't get an acknowledgement, check the mailing list archives to see if your +mail was properly delivered there and possibly if anyone responded and you did +not get their response (please look at http://haproxy.org/ for the mailing list +archive's address). + +If you see that your mail is there but nobody responded, please recheck: + - was the subject clearly indicating that it was a patch and/or that you were + seeking some review? + + - was your email mangled by your mail agent? If so it's possible that + nobody had the willingness yet to mention it. + + - was your email sent as HTML? If so it definitely ended in spam boxes + regardless of the archives. + + - did the patch violate some of the principles explained in this document? + +If none of these cases matches, it might simply be that everyone was busy when +your patch was sent and that it was overlooked. In this case it's fine to +either resubmit it or respond to your own email asking if anything's wrong +about it. In general don't expect a response after one week of silence, just +because your email will not appear in anyone else's current window. So after +one week it's time to resubmit. + +Among the mistakes that tend to make reviewers not respond are those who send +multiple versions of a patch in a row. It's natural for others then to wait for +the series to stabilize. And once it doesn't move anymore everyone forgot about +it. As a rule of thumb, if you have to update your original email more than +twice, first double-check that your series is really ready for submission, and +second, start a new thread and stop responding to the previous one. In this +case it is well appreciated to mention a version of your patch set in the +subject such as "[PATCH v2]", so that reviewers can immediately spot the new +version and not waste their time on the old one. + +If you still do not receive any response, it is possible that you've already +played your last card by not respecting the basic principles multiple times +despite being told about it several times, and that nobody is willing to spend +more of their time than normally needed with your work anymore. Your best +option at this point probably is to ask "did I do something wrong" than to +resend the same patches. + + +How to be sure to irritate everyone +----------------------------------- + +Among the best ways to quickly lose everyone's respect, there is this small +selection, which should help you improve the way you work with others, if +you notice you're already practising some of them: + - repeatedly send improperly formatted commit messages, with no type or + severity, or with no commit message body. These ones require manual + edition, maintainers will quickly learn to recognize your name. + + - repeatedly send patches which break something, and disappear or take a long + time to provide a fix. + + - fail to respond to questions related to features you have contributed in + the past, which can further lead to the feature being declared unmaintained + and removed in a future version. + + - send a new patch iteration without taking *all* comments from previous + review into consideration, so that the reviewer discovers they have to do + the exact same work again. + + - "hijack" an existing thread to discuss something different or promote your + work. This will generally make you look like a fool so that everyone wants + to stay away from your e-mails. + + - continue to send pull requests after having been explained why they are not + welcome. + + - give wrong advices to people asking for help, or sending them patches to + try which make no sense, waste their time, and give them a bad impression + of the people working on the project. + + - be disrespectful to anyone asking for help or contributing some work. This + may actually even get you kicked out of the list and banned from it. + +-- end diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..92daeef --- /dev/null +++ b/INSTALL @@ -0,0 +1,669 @@ +Installation instructions for HAProxy +===================================== + +HAProxy 2.6 is a long-term supported version, which means that it will get +fixes for bugs as they are discovered till around Q2 2027 and will not receive +new features. This version is suitable for general deployment as it is expected +to receive less frequent updates than regular stable branches which have an odd +digit in the minor version number. New users are encouraged to use long-term +supported versions such as the ones provided by their software vendor, Linux +distribution, or by a trusted package maintainer. Experienced users who manage +a fleet of load balancers are encouraged to deploy at least one node with the +latest weekly development version to get familiar with upcoming changes and +possibly detect unwelcome changes or bugs before the release. This is also a +great way to get new features implemented exactly as needed. + +If for any reason you would prefer a different version than the one packaged +for your system, you want to be certain to have all the fixes or to get some +commercial support, other choices are available at http://www.haproxy.com/. + + +Areas covered in this document +============================== + +1) Quick build & install +2) Basic principles +3) Build environment +4) Dependencies +5) Advanced build options +6) How to install HAProxy + + +1) Quick build & install +======================== + +If you've already built HAProxy and are just looking for a quick reminder, here +are a few build examples : + + - recent Linux system with all options, make and install : + $ make clean + $ make -j $(nproc) TARGET=linux-glibc \ + USE_OPENSSL=1 USE_LUA=1 USE_PCRE=1 USE_SYSTEMD=1 + $ sudo make install + + - FreeBSD and OpenBSD, build with all options : + $ gmake -j 4 TARGET=freebsd USE_OPENSSL=1 USE_LUA=1 USE_PCRE=1 + + - embedded Linux, build using a cross-compiler : + $ make -j $(nproc) TARGET=linux-glibc USE_OPENSSL=1 USE_PCRE=1 \ + CC=/opt/cross/gcc730-arm/bin/gcc ADDLIB=-latomic + + - Build with static PCRE on Solaris / UltraSPARC : + $ make TARGET=solaris CPU=ultrasparc USE_STATIC_PCRE=1 + +For more advanced build options or if a command above reports an error, please +read the following sections. + + +2) Basic principles +=================== + +HAProxy uses a single GNU Makefile which supports options on the command line, +so that there is no need to hack a "configure" file to work on your system. The +makefile totally supports parallel build using "make -j " where +matches the number of usable processors, which on some platforms is returned by +the "nproc" utility. The explanations below may occasionally refer to some +options, usually in the form "name=value", which have to be passed to the +command line. This means that the option has to be passed after the "make" +command. For example : + + $ make -j $(nproc) TARGET=generic USE_GZIP=1 + +One required option is TARGET, it must be set to a target platform name, which +provides a number of presets. The list of known platforms is displayed when no +target is specified. It is not strictly required to use the exact target, you +can use a relatively similar one and adjust specific variables by hand. + +Most configuration variables are in fact booleans. Some options are detected and +enabled by default if available on the target platform. This is the case for all +those named "USE_". These booleans are enabled by "USE_=1" +and are disabled by "USE_=" (with no value). An exhaustive list of the +supported USE_* features is located at the top of the main Makefile. The last +occurrence of such an option on the command line overrides any previous one. +Example : + + $ make TARGET=generic USE_THREAD= + +In case of error or missing TARGET, a help screen is displayed. It is also +possible to display a list of all known options using "make help". + +Some optional components which may depend on third-party libraries, are used +with popular tools which are not necessarily standard implementations, or are +maintained at slower pace than the core of the project, are located in the +"addons/" directory. These ones may disappear in a future version if the +product they depend on disappears or if their maintainers do not assign enough +resources to maintain them any more. For this reason they are not built by +default, but some USE_* options are usually provided for them, and their build +is routinely tested anyway. + + +3) Build environment +==================== + +HAProxy requires a working GCC or Clang toolchain and GNU make : + + - GNU make >= 3.80. Note that neither Solaris nor OpenBSD's make work with + the GNU Makefile. If you get many syntax errors when running "make", you + may want to retry with "gmake" which is the name commonly used for GNU make + on BSD systems. + + - GCC >= 4.2 (up to 12 tested). Older versions can be made to work with a + few minor adaptations if really needed. Newer versions may sometimes break + due to compiler regressions or behaviour changes. The version shipped with + your operating system is very likely to work with no trouble. Clang >= 3.0 + is also known to work as an alternative solution. Recent versions may emit + a bit more warnings that are worth reporting as they may reveal real bugs. + TCC (https://repo.or.cz/tinycc.git) is also usable for developers but will + not support threading and was found at least once to produce bad code in + some rare corner cases (since fixed). But it builds extremely quickly + (typically half a second for the whole project) and is very convenient to + run quick tests during API changes or code refactoring. + + - GNU ld (binutils package), with no particular version. Other linkers might + work but were not tested. + +On debian or Ubuntu systems and their derivatives, you may get all these tools +at once by issuing the two following commands : + + $ sudo apt-get update + $ sudo apt-get install build-essential + +On Fedora, CentOS, RHEL and derivatives, you may get the equivalent packages +with the following command : + + $ sudo yum groupinstall "Development Tools" + +Please refer to your operating system's documentation for other systems. + +It is also possible to build HAProxy for another system or platform using a +cross-compiler but in this case you probably already have installed these +tools. + +Building HAProxy may require between 60 and 80 MB of free space in the +directory where the sources have been extracted, depending on the debugging +options involved. + + +4) Dependencies +=============== + +HAProxy in its basic form does not depend on anything beyond a working libc. +However a number of options are enabled by default, or are highly recommended, +and these options will typically involve some external components or libraries, +depending on the targeted platform. + +Optional dependencies may be split into several categories : + + - memory allocation + - regular expressions + - multi-threading + - password encryption + - cryptography + - compression + - lua + - device detection + - miscellaneous + + +4.1) Memory allocation +---------------------- +By default, HAProxy uses the standard malloc() call provided by the libc. It +may also be built to use jemalloc, which is fast and thread-safe. In order to +use it, please add "-ljemalloc" to the ADDLIB variable. You may possibly also +need to append "-lpthread" and/or "-ldl" depending on the operating system. + + +4.2) Regular expressions +------------------------ +HAProxy may make use regular expressions (regex) to match certain patterns. The +regex engine is provided by default in the libc. On some operating systems, it +might happen that the original regex library provided by the libc is too slow, +too limited or even bogus. For example, on older Solaris versions up to 8, the +default regex used not to properly extract group references, without reporting +compilation errors. Also, some early versions of the GNU libc used to include a +regex engine which could be slow or even crash on certain patterns. + +If you plan on importing a particularly heavy configuration involving a lot of +regex, you may benefit from using some alternative regex implementations such as +PCRE. HAProxy natively supports PCRE and PCRE2, both in standard and JIT +flavors (Just In Time). The following options are available depending on the +library version provided on your system : + + - "USE_PCRE=1" : enable PCRE version 1, dynamic linking + - "USE_STATIC_PCRE=1" : enable PCRE version 1, static linking + - "USE_PCRE_JIT=1" : enable PCRE version 1 in JIT mode + - "USE_PCRE2=1" : enable PCRE version 2, dynamic linking + - "USE_STATIC_PCRE2=1" : enable PCRE version 2, static linking + - "USE_PCRE2_JIT=1" : enable PCRE version 2 in JIT mode + +Both of these libraries may be downloaded from https://www.pcre.org/. + +By default, the include and library paths are figured from the "pcre-config" +and "pcre2-config" utilities. If these ones are not installed or inaccurate +(for example when cross-compiling), it is possible to force the path to include +files using "PCRE_INC" and "PCRE2_INC" respectively, and the path to library +files using "PCRE_LIB" and "PCRE2_LIB" respectively. For example : + + $ make TARGET=generic \ + USE_PCRE2_JIT=1 PCRE2_INC=/opt/cross/include PCRE2_LIB=/opt/cross/lib + + +4.3) Multi-threading +-------------------- +On some systems for which positive feedback was reported, multi-threading will +be enabled by default. When multi-threading is used, the libpthread library +(POSIX threading) will be used. If the target system doesn't contain such a +library, it is possible to forcefully disable multi-threading by adding +"USE_THREAD=" on the command line. + + +4.4) Password encryption +------------------------ +Many systems provide password encryption functions used for authentication. On +some systems these functions are part of the libc. On others, they're part of a +separate library called "libcrypt". The default targets are pre-configured +based on which system needs the library. It is possible to forcefully disable +the linkage against libcrypt by adding "USE_LIBCRYPT=" on the command line, or +to forcefully enable it using "USE_LIBCRYPT=1". + + +4.5) Cryptography +----------------- +For SSL/TLS, it is necessary to use a cryptography library. HAProxy currently +supports the OpenSSL library, and is known to build and work with branches +1.0.0, 1.0.1, 1.0.2, 1.1.0, 1.1.1, and 3.0.x. OpenSSL follows a long-term +support cycle similar to HAProxy's, and each of the branches above receives its +own fixes, without forcing you to upgrade to another branch. There is no excuse +for staying vulnerable by not applying a fix available for your version. There +is always a small risk of regression when jumping from one branch to another +one, especially when it's very new, so it's preferable to observe for a while +if you use a different version than your system's defaults. + +Three OpenSSL derivatives called LibreSSL, BoringSSL and QUICTLS are reported +to work as well. While there are some efforts from the community to ensure they +work well, OpenSSL remains the primary target and this means that in case of +conflicting choices, OpenSSL support will be favored over other options. Note +that OpenSSL is not compatible when building haproxy with QUIC support. In this +case, QUICTLS is the preferred alternative. See the section about QUIC in this +document. + +In order to enable SSL/TLS support, simply pass "USE_OPENSSL=1" on the command +line and the default library present on your system will be used : + + $ make TARGET=generic USE_OPENSSL=1 + +If you want to use a different version from the one provided by your system +(which is not recommended due to the risk of missing security fixes), it is +possible to indicate the path to the SSL include files using SSL_INC, and the +SSL library files using SSL_LIB. Example : + + $ make TARGET=generic \ + USE_OPENSSL=1 SSL_INC=/opt/ssl-1.1.1/include SSL_LIB=/opt/ssl-1.1.1/lib + +In order to link OpenSSL statically against HAProxy, first download OpenSSL +from https://www.openssl.org/ then build it with the "no-shared" keyword and +install it to a local directory, so your system is not affected : + + $ export STATICLIBSSL=/tmp/staticlibssl + $ ./config --prefix=$STATICLIBSSL no-shared + $ make && make install_sw + +Then when building haproxy, pass that path via SSL_INC and SSL_LIB : + + $ make TARGET=generic \ + USE_OPENSSL=1 SSL_INC=$STATICLIBSSL/include SSL_LIB=$STATICLIBSSL/lib + +When building with OpenSSL on some systems, you may also need to enable support +for the "libz" library, which is visible if the linker complains about function +"deflateInit()" not being found. In this case, simply append "ADDLIB=-lz" to +the command line. + +It is worth mentioning that asynchronous cryptography engines are supported on +OpenSSL 1.1.0 and above. Such engines are used to access hardware cryptography +acceleration that might be present on your system. Due to API changes that +appeared with OpenSSL 3.0 and cause lots of build warnings, engines are not +enabled by default anymore in HAProxy 2.6. It is required to pass USE_ENGINE=1 +if they are desired. + + +4.6) Compression +---------------- +HAProxy can compress HTTP responses before delivering them to clients, in order +to save network bandwidth. Two compression options are available. The first one +relies on the libslz library (http://libslz.org) that is embedded in haproxy. +It is enabled by default as it is very fast and does not keep a copy of the +contents in memory. It is possible to disable it, for example for very small +systems, by passing "USE_SLZ=" to the "make" command. + +Please note that SLZ will benefit from some CPU-specific instructions like the +availability of the CRC32 extension on some ARM processors. Thus it can further +improve its performance to build with "CPU=native" on the target system, or +"CPU=armv81" (modern systems such as Graviton2 or A55/A75 and beyond), +"CPU=a72" (e.g. for RPi4, or AWS Graviton), "CPU=a53" (e.g. for RPi3), or +"CPU=armv8-auto" (automatic detection with minor runtime penalty). + +A second option involves the widely known zlib library, which is very likely +installed on your system. In order to use zlib, simply pass "USE_ZLIB=1" to the +"make" command line, which will also automatically disable SLZ. If the library +is not installed in your default system's path, it is possible to specify the +path to the include files using ZLIB_INC, and the path to the library files +using ZLIB_LIB : + + $ make TARGET=generic \ + USE_ZLIB=1 ZLIB_INC=/opt/zlib-1.2.11/include ZLIB_LIB=/opt/zlib-1.2.11/lib + +Zlib is commonly found on most systems, otherwise updates can be retrieved from +http://www.zlib.net/. It is easy and fast to build, and new versions sometimes +provide better performance so it might be worth using an up-to-date one. + +Zlib compresses a bit better than libslz but at the expense of more CPU usage +(about 3.5 times more minimum), and a huge memory usage (~260 kB per compressed +stream). The only valid reason for uzing Zlib instead of SLZ here usually is to +deal with a very limited internet bandwidth while CPU and RAM are abundant so +that the last few percent of compression ratio are worth the invested hardware. + + +4.7) Lua +-------- +Lua is an embedded programming language supported by HAProxy to provide more +advanced scripting capabilities. Only versions 5.3 and above are supported. +In order to enable Lua support, please specify "USE_LUA=1" on the command line. +Some systems provide this library under various names to avoid conflicts with +previous versions. By default, HAProxy looks for "lua5.4", "lua54", "lua5.3", +"lua53", "lua". If your system uses a different naming, you may need to set the +library name in the "LUA_LIB_NAME" variable. + +If Lua is not provided on your system, it can be very simply built locally. It +can be downloaded from https://www.lua.org/, extracted and built, for example : + + $ cd /opt/lua-5.3.5 + $ make linux + +The path to the include files and library files may be set using "LUA_INC" and +"LUA_LIB" respectively. For example : + + $ make TARGET=generic \ + USE_LUA=1 LUA_INC=/opt/lua-5.3.5/src LUA_LIB=/opt/lua-5.3.5/src + + +4.8) Device detection +--------------------- +HAProxy supports several device detection modules relying on third party +products. Some of them may provide free code, others free libs, others free +evaluation licenses. Please read about their respective details in the +following files : + + doc/DeviceAtlas-device-detection.txt for DeviceAtlas + doc/51Degrees-device-detection.txt for 51Degrees + doc/WURFL-device-detection.txt for Scientiamobile WURFL + + +4.9) Miscellaneous +------------------ +Some systems have specificities. Usually these specificities are known and/or +detected and properly set for you. If you need to adjust the behaviour, here +are the extra libraries that may be referenced at build time : + + - USE_RT=1 build with librt, which is sometimes needed on some systems + when using threads. It is set by default on Linux platforms, + and may be disabled using "USE_RT=" if your system doesn't + have one. You may have to set it as well if you face an error + indicating that clock_gettime() was not found. + + - USE_DL=1 build with libdl, which is usually needed for Lua and OpenSSL + on Linux. It is automatically detected and may be disabled + using "USE_DL=", though it should never harm. + + - USE_SYSTEMD=1 enables support for the sdnotify features of systemd, + allowing better integration with systemd on Linux systems + which come with it. It is never enabled by default so there + is no need to disable it. + + +4.10) Common errors +------------------- +Some build errors may happen depending on the options combinations or the +selected target. When facing build errors, if you know that your system is a +bit special or particularly old, start from TARGET=generic, it is easier to +start from there and fix the remaining issues than trying to degrade another +target. Common issues may include: + + - clock_gettime() not found + => your system needs USE_RT=1 + + - many __sync_ errors in many files + => your gcc is too old, build without threads. + + - many openssl errors + => your OpenSSL version really is too old, do not enable OpenSSL + + +4.11) QUIC +---------- +QUIC is the new transport layer protocol and is required for HTTP/3. This +protocol stack is currently supported as an experimental feature in haproxy on +the frontend side. In order to enable it, use "USE_QUIC=1 USE_OPENSSL=1". + +Note that the OpenSSL library is not compatible with QUIC. The preferred option +is to use QUICTLS. This is a fork of OpenSSL with a QUIC-compatible API. Its +repository is available at https://github.com/quictls/openssl. You can use the +following instruction to build a functional QUICTLS. + + $ ./config --libdir=lib [--prefix=/opt/quictls] + $ make + $ make install + +On a development environment, use SSL_INC and SSL_LIB when building haproxy to +point to the correct cryptographic library. It may be useful to specify QUICTLS +location via rpath for haproxy execution. Example : + + $ make TARGET=generic \ + USE_QUIC=1 \ + USE_OPENSSL=1 SSL_INC=/opt/quictls/include SSL_LIB=/opt/quictls/lib \ + LDFLAGS="-Wl,-rpath,/opt/quictls/lib" + +5) How to build HAProxy +======================= + +This section assumes that you have already read section 2 (basic principles) +and section 3 (build environment). It often refers to section 4 (dependencies). + +To build haproxy, you have to choose your target OS amongst the following ones +and assign it to the TARGET variable : + + - linux-glibc for Linux kernel 2.6.28 and above + - linux-glibc-legacy for Linux kernel 2.6.28 and above without new features + - linux-musl for Linux kernel 2.6.28 and above with musl libc + - solaris for Solaris 10 and above + - freebsd for FreeBSD 10 and above + - dragonfly for DragonFlyBSD 4.3 and above + - netbsd for NetBSD 8 and above + - osx for Mac OS/X + - openbsd for OpenBSD 6.3 and above + - aix51 for AIX 5.1 + - aix52 for AIX 5.2 + - aix72-gcc for AIX 7.2 (using gcc) + - cygwin for Cygwin + - haiku for Haiku + - generic for any other OS or version. + - custom to manually adjust every setting + +You may also choose your CPU to benefit from some optimizations. This is +particularly important on UltraSparc machines. For this, you can assign +one of the following choices to the CPU variable : + + - i686 for intel PentiumPro, Pentium 2 and above, AMD Athlon (32 bits) + - i586 for intel Pentium, AMD K6, VIA C3. + - ultrasparc : Sun UltraSparc I/II/III/IV processor + - power8 : IBM POWER8 processor + - power9 : IBM POWER9 processor + - armv81 : modern ARM cores (Cortex A55/A75/A76/A78/X1, Neoverse, Graviton2) + - a72 : ARM Cortex-A72 or A73 (e.g. RPi4, Odroid N2, AWS Graviton) + - a53 : ARM Cortex-A53 or any of its successors in 64-bit mode (e.g. RPi3) + - armv8-auto : support both older and newer armv8 cores with a minor penalty, + thanks to gcc 10's outline atomics (default with gcc 10.2). + - native : use the build machine's specific processor optimizations. Use with + extreme care, and never in virtualized environments (known to break). + - generic : any other processor or no CPU-specific optimization. (default) + +Alternatively, you may just set the CPU_CFLAGS value to the optimal GCC options +for your platform. A second variable named SMALL_OPTS also supports passing a +number of defines and compiler options usually for small systems. For better +clarity it's recommended to pass the options which result in a smaller binary +(like memory limits or -Os) into this variable. + +If you are building for a different system than the one you're building on, +this is called "cross-compiling". HAProxy supports cross-compilation pretty +well and tries to ease it by letting you adjust paths to all libraries (please +read section 4 on dependencies for more details). When cross-compiling, you +just need to pass the path to your compiler in the "CC" variable, and the path +to the linker in the "LD" variable. Most of the time, setting the CC variable +is enough since LD points to it by default. + +By default the build process runs in quiet mode and hide the details of the +commands that are executed. This allows to more easily catch build warnings +and see what is happening. However it is not convenient at all to observe what +flags are passed to the compiler nor what compiler is involved. Simply append +"V=1" to the "make" command line to switch to verbose mode and display the +details again. It is recommended to use this option when cross-compiling to +verify that the paths are correct and that /usr/include is never invovled. + +You may want to build specific target binaries which do not match your native +compiler's target. This is particularly true on 64-bit systems when you want +to build a 32-bit binary. Use the ARCH variable for this purpose. Right now +it only knows about a few x86 variants (i386,i486,i586,i686,x86_64), two +generic ones (32,64) and sets -m32/-m64 as well as -march= accordingly. +This variable is only used to set ARCH_FLAGS to preset values, so if you know +the arch-specific flags that your system needs, you may prefer to set +ARCH_FLAGS instead. Note that these flags are passed both to the compiler and +to the linker. For example, in order to build a 32-bit binary on an x86_64 +Linux system with SSL support without support for compression but when OpenSSL +requires ZLIB anyway : + + $ make TARGET=linux-glibc ARCH=i386 USE_OPENSSL=1 ADDLIB=-lz + +Recent systems can resolve IPv6 host names using getaddrinfo(). This primitive +is not present in all libcs and does not work in all of them either. Support in +glibc was broken before 2.3. Some embedded libs may not properly work either, +thus, support is disabled by default, meaning that some host names which only +resolve as IPv6 addresses will not resolve and configs might emit an error +during parsing. If you know that your OS libc has reliable support for +getaddrinfo(), you can add USE_GETADDRINFO=1 on the make command line to enable +it. This is the recommended option for most Linux distro packagers since it's +working fine on all recent mainstream distros. It is automatically enabled on +Solaris 8 and above, as it's known to work. + +If your system supports PCRE (Perl Compatible Regular Expressions), then you +really should build with libpcre which is between 2 and 10 times faster than +other libc implementations. Regex are used for header processing (deletion, +rewriting, allow, deny). Please see section 4 about dependencies to figure +how to build with PCRE support. + +It is possible to add native support for SSL, by passing "USE_OPENSSL=1" on the +make command line. The libssl and libcrypto will automatically be linked with +HAProxy. Some systems also require libz, so if the build fails due to missing +symbols such as deflateInit(), then try again with "ADDLIB=-lz". Please check +section 4 about dependencies for more information on how to build with OpenSSL. + +HAProxy can compress HTTP responses to save bandwidth. Please see section 4 +about dependencies to see the available libraries and associated options. + +By default, the DEBUG_CFLAGS variable is set to '-g' to enable debug symbols. +It is not wise to disable it on uncommon systems, because it's often the only +way to get a usable core when you need one. Otherwise, you can set DEBUG to +'-s' to strip the binary. + +If the ERR variable is set to any non-empty value, then -Werror will be added +to the compiler so that any build warning will trigger an error. This is the +recommended way to build when developing, and it is expected that contributed +patches were tested with ERR=1. + +The DEBUG variable is used to extend the CFLAGS and is preset to a list of +build-time options that are known for providing significant reliability +improvements and a barely perceptible performance cost. Unless instructed to do +so by some project developers, or trying to save the last ounce of performance, +these options should not be changed. Among the usable ones are: + - -DDEBUG_STRICT: enable some runtime assertions at key places in the code. + The goal is to emit a warning or stop the program if certain expected + conditions are not met, and whose violation will result in a misbehaving + process due to memory corruption or other significant trouble, possibly + caused by an attempt to exploit a bug in the program or a library it relies + on. The option knows 3 values: 0 (disable all such assertions, the default + when the option is not set), 1 (enable all inexpensive assertions), and + 2 (enable all assertions even in fast paths). Setting the option with no + value corresponds to 1, which is the recommended value for production. + + - -DDEBUG_STRICT_ACTION: indicates how to react to a check violation. There + are 3 types of checks: BUG (condition that is known to have serious + consequences), WARN (warning about a highly suspicious condition which the + process may recover from, but whose unknown cause may also have serious + consequences), CHECK (verification whether a condition that developers now + consider impossible still happens). The variable takes a value from 0 to 3, + that adjusts the behavior on these 3 violations: + + BUG WARN CHECK + 0 warn warn warn + 1 stop warn warn + 2 stop stop warn + 3 stop stop stop + + The default value is 1, which is the best balance for production in that it + will do its best to prevent a known bogus process from running away, but + will let it run if it believes it can recover. Users running the process in + sensitive environments (finance etc) may prefer to run at level 2 to make + sure to stop any detected anomaly before it may have an impact. Level 3 + should only be used at the request of developers. In any case, any emitted + warning should be reported to developers. + + - -DDEBUG_MEMORY_POOLS: this enables by default extra controls around memory + allocation that will help detect coding errors such as double-frees and + freeing a bad memory location. It will also detect earlier risks of memory + overflows, which may have security implications. The cost is extremely low + (less than 1% increase in memory footprint). This is equivalent to adding + "-dMtag" on the command line. This option is enabled in the default build + options. + + - -DDEBUG_DONT_SHARE_POOLS: this will keep separate pools for same-sized + objects of different types. Using this increases the memory usage a little + bit but further reduces the risk of memory management related bugs and will + lead to more accurate traces in case of error. It is equivalent to adding + "-dMno-merge" on the command line. It is not enabled in the default build + options. + + - -DDEBUG_POOL_INTEGRITY: this will enable runtime detection and stopping of + a class of bugs known as "use after free", which consists in modifying a + memory area after freeing it while it was reused for something else. This + option is quite powerful but such bugs are fortunately extremely rare, and + it will cause a measurable performance degradation (a few percent). This is + equivalent to adding "-dMcold-first,integrity" on the command line. This + option is not enabled by default but users running development versions on + moderate performance sites in order to participate to reliability testing + are encouraged to use it, in combination with -DDEBUG_DONT_SHARE_POOLS and + -DDEBUG_MEMORY_POOLS, as this could catch dangerous regressions. + +As such, for regular production, "-DDEBUG_STRICT -DDEBUG_MEMORY_POOLS" is +recommended. For security sensitive environments, it is recommended to use +"-DDEBUG_STRICT -DDEBUG_STRICT_ACTION=2 -DDEBUG_MEMORY_POOLS \ +-DDEBUG_DONT_SHARE_POOLS". For deployments dedicated to testing new versions or +when trying to nail a bug down, use "-DDEBUG_STRICT=2 -DDEBUG_STRICT_ACTION=2 \ +-DDEBUG_MEMORY_POOLS -DDEBUG_DONT_SHARE_POOLS -DDEBUG_POOL_INTEGRITY". + +The DEP variable is automatically set to the list of include files and also +designates a file that contains the last build options used. It is used during +the build process to compute dependencies and decide whether or not to rebuild +everything (we do rebuild everything when .h files are touched or when build +options change). Sometimes when performing fast build iterations on inline +functions it may be desirable to avoid a full rebuild. Forcing this variable +to be empty will be sufficient to achieve this. This variable must never be +forced to produce final binaries, and must not be used during bisect sessions, +as it will often lead to the wrong commit. + +If you need to pass other defines, includes, libraries, etc... then please +check the Makefile to see which ones will be available in your case, and +use/override the USE_* variables from the Makefile. + +AIX 5.3 is known to work with the generic target. However, for the binary to +also run on 5.2 or earlier, you need to build with DEFINE="-D_MSGQSUPPORT", +otherwise __fd_select() will be used while not being present in the libc, but +this is easily addressed using the "aix52" target. If you get build errors +because of strange symbols or section mismatches, simply remove -g from +DEBUG_CFLAGS. + +Building on AIX 7.2 works fine using the "aix72-gcc" TARGET. It adds two +special CFLAGS to prevent the loading of AIX's xmem.h and var.h. This is done +by defining the corresponding include-guards _H_XMEM and _H_VAR. Without +excluding those header-files the build fails because of redefinition errors. +Furthermore, the atomic library is added to the LDFLAGS to allow for +multithreading via USE_THREAD. + +You can easily define your own target with the GNU Makefile. Unknown targets +are processed with no default option except USE_POLL=default. So you can very +well use that property to define your own set of options. USE_POLL and USE_SLZ +can even be disabled by setting them to an empty string. For example : + + $ gmake TARGET=tiny USE_POLL="" USE_SLZ="" TARGET_CFLAGS=-fomit-frame-pointer + +If you need to pass some defines to the preprocessor or compiler, you may pass +them all in the DEFINE variable. Example: + + $ make TARGET=generic DEFINE="-DDEBUG_DONT_SHARE_POOLS -DDEBUG_MEMORY_POOLS" + +The ADDINC variable may be used to add some extra include paths; this is +sometimes needed when cross-compiling. Similarly the ADDLIB variable may be +used to specifify extra paths to library files. Example : + + $ make TARGET=generic ADDINC=-I/opt/cross/include ADDLIB=-L/opt/cross/lib64 + + +6) How to install HAProxy +========================= + +To install haproxy, you can either copy the single resulting binary to the +place you want, or run : + + $ sudo make install + +If you're packaging it for another system, you can specify its root directory +in the usual DESTDIR variable. + +-- end diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..717e303 --- /dev/null +++ b/LICENSE @@ -0,0 +1,37 @@ +HAPROXY's license - 2006/06/15 + +Historically, haproxy has been covered by GPL version 2. However, an issue +appeared in GPL which will prevent external non-GPL code from being built +using the headers provided with haproxy. My long-term goal is to build a core +system able to load external modules to support specific application protocols. + +Since some protocols are found in rare environments (finance, industry, ...), +some of them might be accessible only after signing an NDA. Enforcing GPL on +such modules would only prevent them from ever being implemented, while not +providing anything useful to ordinary users. + +For this reason, I *want* to be able to support binary only external modules +when needed, with a GPL core and GPL modules for standard protocols, so that +people fixing bugs don't keep them secretly to try to stay over competition. + +The solution was then to apply the LGPL license to the exportable include +files, while keeping the GPL for all the rest. This way, it still is mandatory +to redistribute modified code under customer request, but at the same time, it +is expressly permitted to write, compile, link and load non-GPL code using the +LGPL header files and not to distribute them if it causes a legal problem. + +Of course, users are strongly encouraged to continue the work under GPL as long +as possible, since this license has allowed useful enhancements, contributions +and fixes from talented people around the world. + +Due to the incompatibility between the GPL and the OpenSSL licence, you must +apply the GPL/LGPL licence with the following exception: +This program is released under the GPL with the additional exemption that +compiling, linking, and/or using OpenSSL is allowed. + +The text of the licenses lies in the "doc" directory. All the files provided in +this package are covered by the GPL unless expressly stated otherwise in them. +Every patch or contribution provided by external people will by default comply +with the license of the files it affects, or be rejected. + +Willy Tarreau - w@1wt.eu diff --git a/MAINTAINERS b/MAINTAINERS new file mode 100644 index 0000000..c56ac24 --- /dev/null +++ b/MAINTAINERS @@ -0,0 +1,152 @@ +This file contains a list of people who are responsible for certain parts of +the HAProxy project and who have authority on them. This means that these +people have to be consulted before doing any change in the parts they maintain, +including when fixing bugs. These persons are allowed to reject any change on +the parts they maintain, and in parallel they try their best to ensure these +parts work well. Similarly, any change to these parts not being validated by +them will be rejected. + +The best way to deal with such subsystems when sending patches is to send the +patches to the mailing list and to CC these people. When no maintainer is +listed for a subsystem, you can simply send your changes the usual way, and it +is also a sign that if you want to strengthen your skills on certain parts you +can become yourself a maintainer of the parts you care a lot about. + +Please do not ask them to troubleshoot your bugs, it's not their job eventhough +they may occasionally help as time permits. + +List of maintainers +------------------- + +51Degrees device identification +Maintainer: Ben Shillito +Files: addons/51degrees, doc/51Degrees-device-detection.txt + +Cache +Maintainer: William Lallemand +Files: src/cache.c, include/haproxy/cache*.h + +DeviceAtlas device identification +Maintainer: David Carlier +Files: addons/deviceatlas, doc/DeviceAtlas-device-detection.txt + +DNS and Resolvers +Maintainer: Emeric Brun +Maintainer: Baptiste Assmann +Files: src/dns.c, include/haproxy/dns*.h +Files: src/resolvers.c, include/haproxy/resolvers*.h + +Doc to HTML converter (dconv) +Maintainer: Cyril Bonté +Files: doc/*.txt +Note: ask Cyril before changing any doc's format or structure. + +EBTree +Maintainer: Willy Tarreau +Files: src/eb*.c, include/import/eb*.h + +FCGI: +Maintainer: Christopher Faulet +Files: src/mux_fcgi.c, src/fcgi*.c, include/haproxy/fcgi*.h + +Filters: +Maintainer: Christopher Faulet +Files: src/filters.c, src/flt_*.c, include/haproxy/filters*.h +Files: doc/internals/filters.txt + +H1 and HTX +Maintainer: Christopher Faulet +Files: src/mux_h1.c src/h1_htx.c, include/haproxy/h1_htx.h + +H2 and HPACK +Maintainer: Willy Tarreau +Files: src/mux_h2.c src/h2.c src/hpack*.c +Files: include/haproxy/h2.h, include/haproxy/hpack*.h + +Health checks +Maintainer: Christopher Faulet +Files: src/checks.c, include/haproxy/check*.h +Files: src/tcpcheck.c, include/haproxy/tcpcheck*.h +Note: health checks are fragile and have been broken many times, so please + consult the relevant maintainers if you want to change these specific + parts. + +HTTP +Maintainer: Willy Tarreau +Maintainer: Christopher Faulet +Files: src/http*.h, include/haproxy/http*.h + +HTX +Maintainer: Christopher Faulet +Files: src/htx.c, include/haproxy/htx*.c, doc/internals/htx-api.txt + +Lua +Maintainer: Thierry Fournier +Files: src/hlua.c, include/haproxy/hlua*.h + +Mailers +Maintainer: Simon Horman +Files: src/mailers.c, include/haproxy/mailers*.h + +Maps and pattern matching +Maintainer: Thierry Fournier +Files: src/map.c, include/haproxy/map*.h +Files: src/pattern.c, include/haproxy/pattern*.h + +Master-worker +Maintainer: William Lallemand +Note: Please CC William when touching src/haproxy.c and admin/systemd + +Multi-threading +Maintainer: Christopher Faulet +Maintainer: Emeric Brun +Files: src/thread.c, include/haproxy/thread*.h +Note: every change around the locking or synchronization point will require + approval from one of these maintainers. Problems which only appear when + nbthread is greater than 1 and which disappear otherwise are also + relevant. + +Multi-threaded task scheduler +Maintainer: Willy Tarreau +Maintainer: Olivier Houchard +Files: include/haproxy/task*.h src/task.c + +Peers +Maintainer: Emeric Brun +Frédéric Lécaille +Files: src/peers.c, include/haproxy/peers*.h + +Prometheus Exporter +Maintainer: Christopher Faulet +Maintainer: William Dauchy +Files: addons/promex +Note: William is the referent regarding Prometheus. He should be consulted for + all additions and modifications of features. Christopher is the referent + for the code itself. He should be consulted for questions regarding the + exporter integration into HAProxy, as well as for the bugs. + +QUIC and HTTP/3 +Maintainer: Frédéric Lécaille +Maintainer: Amaury Denoyelle +Files: src/quic*.c, src/cfgparse-quic.c, include/haproxy/quic*.h +Files: src/mux_quic.c, include/haproxy/mux_quic.h, +Files: src/proto_quic.c, include/haproxy/proto_quic.h +Files: src/xprt_quic.c, include/haproxy/xprt_quic.h +Files: src/h3*.c, include/haproxy/h3*.h + +ScientiaMobile WURFL Device Detection +Maintainer: Paul Borile, Massimiliano Bellomi +Files: addons/wurfl, doc/WURFL-device-detection.txt + +SPOE +Maintainer: Christopher Faulet +Files: src/flt_spoe.c, include/haproxy/spoe*.h, doc/SPOE.txt + +SSL +Maintainer: Emeric Brun +Maintainer: William Lallemand +Files: src/cfgparse-ssl.c, src/ssl_*.c, include/haproxy/ssl_*.h + +Thread-safe lists +Maintainer: Olivier Houchard +Files: include/haproxy/list*.h diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..31b6008 --- /dev/null +++ b/Makefile @@ -0,0 +1,1208 @@ +# This GNU Makefile supports different OS and CPU combinations. +# +# You should use it this way : +# [g]make TARGET=os [ARCH=arch] [CPU=cpu] USE_xxx=1 ... +# +# When in doubt, invoke help, possibly with a known target : +# [g]make help +# [g]make help TARGET=linux-glibc +# +# By default the detailed commands are hidden for a cleaner output, but you may +# see them by appending "V=1" to the make command. +# +# Valid USE_* options are enumerated in the "use_opts" variable and are listed +# below. Most of them are automatically set by the TARGET, others have to be +# explicitly specified : +# USE_EPOLL : enable epoll() on Linux 2.6. Automatic. +# USE_KQUEUE : enable kqueue() on BSD. Automatic. +# USE_EVPORTS : enable event ports on SunOS systems. Automatic. +# USE_NETFILTER : enable netfilter on Linux. Automatic. +# USE_PCRE : enable use of libpcre for regex. Recommended. +# USE_PCRE_JIT : enable JIT for faster regex on libpcre >= 8.32 +# USE_PCRE2 : enable use of libpcre2 for regex. +# USE_PCRE2_JIT : enable JIT for faster regex on libpcre2 +# USE_POLL : enable poll(). Automatic. +# USE_THREAD : enable threads support. +# USE_STATIC_PCRE : enable static libpcre. Recommended. +# USE_STATIC_PCRE2 : enable static libpcre2. +# USE_TPROXY : enable transparent proxy. Automatic. +# USE_LINUX_TPROXY : enable full transparent proxy. Automatic. +# USE_LINUX_SPLICE : enable kernel 2.6 splicing. Automatic. +# USE_LIBCRYPT : enable encrypted passwords using -lcrypt +# USE_CRYPT_H : set it if your system requires including crypt.h +# USE_GETADDRINFO : use getaddrinfo() to resolve IPv6 host names. +# USE_OPENSSL : enable use of OpenSSL. Recommended, but see below. +# USE_ENGINE : enable use of OpenSSL Engine. +# USE_LUA : enable Lua support. +# USE_ACCEPT4 : enable use of accept4() on linux. Automatic. +# USE_CLOSEFROM : enable use of closefrom() on *bsd, solaris. Automatic. +# USE_PRCTL : enable use of prctl(). Automatic. +# USE_PROCCTL : enable use of procctl(). Automatic. +# USE_ZLIB : enable zlib library support and disable SLZ +# USE_SLZ : enable slz library instead of zlib (default=enabled) +# USE_CPU_AFFINITY : enable pinning processes to CPU on Linux. Automatic. +# USE_TFO : enable TCP fast open. Supported on Linux >= 3.7. +# USE_NS : enable network namespace support. Supported on Linux >= 2.6.24. +# USE_DL : enable it if your system requires -ldl. Automatic on Linux. +# USE_RT : enable it if your system requires -lrt. Automatic on Linux. +# USE_BACKTRACE : enable backtrace(). Automatic on Linux. +# USE_PROMEX : enable the Prometheus exporter +# USE_DEVICEATLAS : enable DeviceAtlas api. +# USE_51DEGREES : enable third party device detection library from 51Degrees +# USE_WURFL : enable WURFL detection library from Scientiamobile +# USE_SYSTEMD : enable sd_notify() support. +# USE_OBSOLETE_LINKER : use when the linker fails to emit __start_init/__stop_init +# USE_THREAD_DUMP : use the more advanced thread state dump system. Automatic. +# USE_OT : enable the OpenTracing filter +# USE_MEMORY_PROFILING : enable the memory profiler. Linux-glibc only. +# USE_LIBATOMIC : force to link with/without libatomic. Automatic. +# +# Options can be forced by specifying "USE_xxx=1" or can be disabled by using +# "USE_xxx=" (empty string). The list of enabled and disabled options for a +# given TARGET is enumerated at the end of "make help". +# +# Variables useful for packagers : +# CC is set to "cc" by default and is used for compilation only. +# LD is set to "cc" by default and is used for linking only. +# ARCH may be useful to force build of 32-bit binary on 64-bit systems +# CFLAGS is automatically set for the specified CPU and may be overridden. +# LDFLAGS is automatically set to -g and may be overridden. +# DEP may be cleared to ignore changes to include files during development +# SMALL_OPTS may be used to specify some options to shrink memory usage. +# DEBUG may be used to set some internal debugging options. +# ERR may be set to non-empty to pass -Werror to the compiler +# ADDINC may be used to complete the include path in the form -Ipath. +# ADDLIB may be used to complete the library list in the form -Lpath -llib. +# DEFINE may be used to specify any additional define, which will be reported +# by "haproxy -vv" in CFLAGS. +# SILENT_DEFINE may be used to specify other defines which will not be +# reported by "haproxy -vv". +# EXTRA is used to force building or not building some extra tools. +# DESTDIR is not set by default and is used for installation only. +# It might be useful to set DESTDIR if you want to install haproxy +# in a sandbox. +# INSTALL is set to "install" by default and is used to provide the name of +# the install binary used by the install targets and any additional +# flags. +# PREFIX is set to "/usr/local" by default and is used for installation only. +# SBINDIR is set to "$(PREFIX)/sbin" by default and is used for installation +# only. +# MANDIR is set to "$(PREFIX)/share/man" by default and is used for +# installation only. +# DOCDIR is set to "$(PREFIX)/doc/haproxy" by default and is used for +# installation only. +# HLUA_PREPEND_PATH may be used to prepend a folder to Lua's default package.path. +# HLUA_PREPEND_CPATH may be used to prepend a folder to Lua's default package.cpath. +# +# Other variables : +# PCRE_CONFIG : force the binary path to get pcre config (by default +# pcre-config) +# PCREDIR : force the path to libpcre. +# PCRE_LIB : force the lib path to libpcre (defaults to $PCREDIR/lib). +# PCRE_INC : force the include path to libpcre ($PCREDIR/inc) +# PCRE2_CONFIG : force the binary path to get pcre2 config (by default +# pcre2-config) +# SSL_LIB : force the lib path to libssl/libcrypto +# SSL_INC : force the include path to libssl/libcrypto +# LUA_LIB : force the lib path to lua +# LUA_INC : force the include path to lua +# LUA_LIB_NAME : force the lib name (or automatically evaluated, by order of +# priority : lua5.4, lua54, lua5.3, lua53, lua). +# OT_DEBUG : compile the OpenTracing filter in debug mode +# OT_INC : force the include path to libopentracing-c-wrapper +# OT_LIB : force the lib path to libopentracing-c-wrapper +# OT_RUNPATH : add RUNPATH for libopentracing-c-wrapper to haproxy executable +# OT_USE_VARS : allows the use of variables for the OpenTracing context +# IGNOREGIT : ignore GIT commit versions if set. +# VERSION : force haproxy version reporting. +# SUBVERS : add a sub-version (eg: platform, model, ...). +# EXTRAVERSION : local version string to append (e.g. build number etc) +# VERDATE : force haproxy's release date. +# VTEST_PROGRAM : location of the vtest program to run reg-tests. +# DEBUG_USE_ABORT: use abort() for program termination, see include/haproxy/bug.h for details + +# verbosity: pass V=1 for verbose shell invocation +V = 0 +Q = @ +ifeq ($V,1) +Q= +endif + +# WARNING: Do not change cc-opt, cc-opt-alt or cc-warning without checking if +# clang bug #49364 is fixed. stderr is redirected to /dev/null on +# purpose, to work around a clang 11 bug that crashes if stderr is +# redirected to stdin. +# +# Function used to detect support of a given option by the compiler. +# Usage: CFLAGS += $(call cc-opt,option). Eg: $(call cc-opt,-fwrapv) +# Note: ensure the referencing variable is assigned using ":=" and not "=" to +# call it only once. +cc-opt = $(shell set -e; if $(CC) -Werror $(1) -E -xc - -o /dev/null &0 2>/dev/null; then echo "$(1)"; fi;) + +# same but tries with $2 if $1 is not supported +cc-opt-alt = $(if $(shell set -e; if $(CC) -Werror $(1) -E -xc - -o /dev/null &0 2>/dev/null; then echo 1;fi),$(1),$(call cc-opt,$(2))) + +# validate a list of options one at a time +cc-all-opts = $(foreach a,$(1),$(call cc-opt,$(a))) + +# try to pass plenty of options at once, take them on success or try them +# one at a time on failure and keep successful ones. This is handy to quickly +# validate most common options. +cc-all-fast = $(if $(call cc-opt,$(1)),$(1),$(call cc-all-opts,$(1))) + +# Below we verify that the compiler supports any -Wno-something option to +# disable any warning, or if a special option is needed to achieve that. This +# will allow to get rid of testing when the compiler doesn't care. The result +# is made of two variables: +# - cc-anywno that's non-empty if the compiler supports disabling anything +# - cc-wnouwo that may contain an option needed to enable this behavior +# Gcc 4.x and above do not need any option but will still complain about unknown +# options if another warning or error happens, and as such they're not testable. +# Clang needs a special option -Wno-unknown-warning-option. Compilers not +# supporting this option will check all warnings individually. +cc-anywno := $(call cc-opt,-Wno-haproxy-warning) +cc-wnouwo := $(if $(cc-anywno),,$(call cc-opt,-Wno-unknown-warning-option)) +cc-anywno := $(if $(cc-anywno)$(cc-wnouwo),1) + +# Disable a warning when supported by the compiler. Don't put spaces around the +# warning! And don't use cc-opt which doesn't always report an error until +# another one is also returned. If "cc-anywno" is set, the compiler supports +# -Wno- followed by anything so we don't even need to start the compiler. +# Usage: CFLAGS += $(call cc-nowarn,warning). Eg: $(call cc-opt,format-truncation) +cc-nowarn = $(if $(cc-anywno),-Wno-$(1),$(shell set -e; if $(CC) -Werror -W$(1) -E -xc - -o /dev/null &0 2>/dev/null; then echo "-Wno-$(1)"; fi;)) + +#### Installation options. +DESTDIR = +INSTALL = install +PREFIX = /usr/local +SBINDIR = $(PREFIX)/sbin +MANDIR = $(PREFIX)/share/man +DOCDIR = $(PREFIX)/doc/haproxy + +#### TARGET system +# Use TARGET= to optimize for a specific target OS among the +# following list (use the default "generic" if uncertain) : +# linux-glibc, linux-glibc-legacy, linux-musl, solaris, freebsd, freebsd-glibc, +# dragonfly, openbsd, netbsd, cygwin, haiku, aix51, aix52, aix72-gcc, osx, generic, +# custom +TARGET = + +#### TARGET CPU +# Use CPU= to optimize for a particular CPU, among the following +# list : +# generic, native, i586, i686, ultrasparc, power8, power9, custom, +# a53, a72, armv81, armv8-auto +CPU = generic + +#### Architecture, used when not building for native architecture +# Use ARCH= to force build for a specific architecture. Known +# architectures will lead to "-m32" or "-m64" being added to CFLAGS and +# LDFLAGS. This can be required to build 32-bit binaries on 64-bit targets. +# Currently, only 32, 64, x86_64, i386, i486, i586 and i686 are understood. +ARCH = + +#### Toolchain options. +CC = cc +LD = $(CC) + +#### Debug flags (typically "-g"). +# Those flags only feed CFLAGS so it is not mandatory to use this form. +DEBUG_CFLAGS = -g + +#### Add -Werror when set to non-empty +ERR = + +#### May be used to force running a specific set of reg-tests +REG_TEST_FILES = +REG_TEST_SCRIPT=./scripts/run-regtests.sh + +#### Compiler-specific flags that may be used to disable some negative over- +# optimization or to silence some warnings. +# We rely on signed integer wraparound on overflow, however clang think it +# can do whatever it wants since it's an undefined behavior, so use -fwrapv +# to be sure we get the intended behavior. +WARN_CFLAGS := -Wtype-limits -Wshift-negative-value -Wshift-overflow=2 \ + -Wduplicated-cond -Wnull-dereference +SPEC_CFLAGS := -Wall -Wextra -Wundef -Wdeclaration-after-statement -Wfatal-errors +SPEC_CFLAGS += $(call cc-all-fast,$(WARN_CFLAGS)) + +SPEC_CFLAGS += $(call cc-opt-alt,-fwrapv,-fno-strict-overflow) +SPEC_CFLAGS += $(cc-wnouwo) +SPEC_CFLAGS += $(call cc-nowarn,address-of-packed-member) +SPEC_CFLAGS += $(call cc-nowarn,unused-label) +SPEC_CFLAGS += $(call cc-nowarn,sign-compare) +SPEC_CFLAGS += $(call cc-nowarn,unused-parameter) +SPEC_CFLAGS += $(call cc-nowarn,clobbered) +SPEC_CFLAGS += $(call cc-nowarn,missing-field-initializers) +SPEC_CFLAGS += $(call cc-nowarn,cast-function-type) +SPEC_CFLAGS += $(call cc-nowarn,string-plus-int) +SPEC_CFLAGS += $(call cc-nowarn,atomic-alignment) + +ifneq ($(ERR),) +SPEC_CFLAGS += -Werror +endif + +#### Memory usage tuning +# If small memory footprint is required, you can reduce the buffer size. There +# are 2 buffers per concurrent session, so 16 kB buffers will eat 32 MB memory +# with 1000 concurrent sessions. Putting it slightly lower than a page size +# will prevent the additional parameters to go beyond a page. 8030 bytes is +# exactly 5.5 TCP segments of 1460 bytes and is generally good. Useful tuning +# macros include : +# SYSTEM_MAXCONN, BUFSIZE, MAXREWRITE, REQURI_LEN, CAPTURE_LEN. +# Example: SMALL_OPTS = -DBUFSIZE=8030 -DMAXREWRITE=1030 -DSYSTEM_MAXCONN=1024 +SMALL_OPTS = + +#### Debug settings +# You can enable debugging on specific code parts by setting DEBUG=-DDEBUG_xxx. +# Use quotes and spaces if multiple options are needed (the DEBUG variables is +# passed as-is to CFLAGS). Please check sources for their exact meaning or do +# not use them at all. Some even more obscure ones might also be available +# without appearing here. Currently defined DEBUG macros include DEBUG_FULL, +# DEBUG_MEM_STATS, DEBUG_DONT_SHARE_POOLS, DEBUG_FD, DEBUG_POOL_INTEGRITY, +# DEBUG_NO_POOLS, DEBUG_FAIL_ALLOC, DEBUG_STRICT_ACTION=[0-3], DEBUG_HPACK, +# DEBUG_AUTH, DEBUG_SPOE, DEBUG_UAF, DEBUG_THREAD, DEBUG_STRICT, DEBUG_DEV, +# DEBUG_TASK, DEBUG_MEMORY_POOLS, DEBUG_POOL_TRACING, DEBUG_QPACK. +DEBUG = -DDEBUG_STRICT -DDEBUG_MEMORY_POOLS + +#### Trace options +# Use TRACE=1 to trace function calls to file "trace.out" or to stderr if not +# possible. +TRACE = + +#### Additional include and library dirs +# Redefine this if you want to add some special PATH to include/libs +ADDINC = +ADDLIB = + +#### Specific macro definitions +# Use DEFINE=-Dxxx to set any tunable macro. Anything declared here will appear +# in the build options reported by "haproxy -vv". Use SILENT_DEFINE if you do +# not want to pollute the report with complex defines. +# The following settings might be of interest when SSL is enabled : +# LISTEN_DEFAULT_CIPHERS is a cipher suite string used to set the default SSL +# ciphers on "bind" lines instead of using OpenSSL's defaults. +# CONNECT_DEFAULT_CIPHERS is a cipher suite string used to set the default +# SSL ciphers on "server" lines instead of using OpenSSL's defaults. +DEFINE = +SILENT_DEFINE = + +#### extra programs to build +# Force this to enable building extra programs or to disable them. +# It's automatically appended depending on the targets. +EXTRA = + +#### CPU dependent optimizations +# Some CFLAGS are set by default depending on the target CPU. Those flags only +# feed CPU_CFLAGS, which in turn feed CFLAGS, so it is not mandatory to use +# them. You should not have to change these options. Better use CPU_CFLAGS or +# even CFLAGS instead. +CPU_CFLAGS.generic = -O2 +CPU_CFLAGS.native = -O2 -march=native +CPU_CFLAGS.i586 = -O2 -march=i586 +CPU_CFLAGS.i686 = -O2 -march=i686 +CPU_CFLAGS.ultrasparc = -O6 -mcpu=v9 -mtune=ultrasparc +CPU_CFLAGS.power8 = -O2 -mcpu=power8 -mtune=power8 +CPU_CFLAGS.power9 = -O2 -mcpu=power9 -mtune=power9 +CPU_CFLAGS.a53 = -O2 -mcpu=cortex-a53 +CPU_CFLAGS.a72 = -O2 -mcpu=cortex-a72 +CPU_CFLAGS.armv81 = -O2 -march=armv8.1-a +CPU_CFLAGS.armv8-auto = -O2 -march=armv8-a+crc -moutline-atomics +CPU_CFLAGS = $(CPU_CFLAGS.$(CPU)) + +#### ARCH dependent flags, may be overridden by CPU flags +ARCH_FLAGS.32 = -m32 +ARCH_FLAGS.64 = -m64 +ARCH_FLAGS.i386 = -m32 -march=i386 +ARCH_FLAGS.i486 = -m32 -march=i486 +ARCH_FLAGS.i586 = -m32 -march=i586 +ARCH_FLAGS.i686 = -m32 -march=i686 +ARCH_FLAGS.x86_64 = -m64 -march=x86-64 +ARCH_FLAGS = $(ARCH_FLAGS.$(ARCH)) + +#### Common CFLAGS +# These CFLAGS contain general optimization options, CPU-specific optimizations +# and debug flags. They may be overridden by some distributions which prefer to +# set all of them at once instead of playing with the CPU and DEBUG variables. +CFLAGS = $(ARCH_FLAGS) $(CPU_CFLAGS) $(DEBUG_CFLAGS) $(SPEC_CFLAGS) + +#### Common LDFLAGS +# These LDFLAGS are used as the first "ld" options, regardless of any library +# path or any other option. They may be changed to add any linker-specific +# option at the beginning of the ld command line. +LDFLAGS = $(ARCH_FLAGS) -g + +#### list of all "USE_*" options. These ones must be updated if new options are +# added, so that the relevant options are properly added to the CFLAGS and to +# the reported build options. +use_opts = USE_EPOLL USE_KQUEUE USE_NETFILTER \ + USE_PCRE USE_PCRE_JIT USE_PCRE2 USE_PCRE2_JIT USE_POLL \ + USE_THREAD USE_BACKTRACE \ + USE_STATIC_PCRE USE_STATIC_PCRE2 USE_TPROXY USE_LINUX_TPROXY \ + USE_LINUX_SPLICE USE_LIBCRYPT USE_CRYPT_H USE_ENGINE \ + USE_GETADDRINFO USE_OPENSSL USE_LUA USE_ACCEPT4 \ + USE_CLOSEFROM USE_ZLIB USE_SLZ USE_CPU_AFFINITY USE_TFO USE_NS \ + USE_DL USE_RT USE_DEVICEATLAS USE_51DEGREES USE_WURFL USE_SYSTEMD \ + USE_OBSOLETE_LINKER USE_PRCTL USE_PROCCTL USE_THREAD_DUMP \ + USE_EVPORTS USE_OT USE_QUIC USE_PROMEX USE_MEMORY_PROFILING + +#### Target system options +# Depending on the target platform, some options are set, as well as some +# CFLAGS and LDFLAGS. All variables pre-set here will not appear in the build +# options string. They may be set to any value, but are historically set to +# "implicit" which eases debugging. You should not have to change anything +# there unless you're adding support for a new platform. +default_opts = $(foreach name,$(1),$(eval $(name)=implicit)) + +# poll() is always supported, unless explicitly disabled by passing USE_POLL="" +# on the make command line. +USE_POLL = default + +# SLZ is always supported unless explicitly disabled by passing USE_SLZ="" +# or disabled by enabling ZLIB using USE_ZLIB=1 +ifeq ($(USE_ZLIB),) +USE_SLZ = default +endif + +# generic system target has nothing specific +ifeq ($(TARGET),generic) + set_target_defaults = $(call default_opts,USE_POLL USE_TPROXY) +endif + +# Haiku +ifeq ($(TARGET),haiku) + TARGET_LDFLAGS = -lnetwork + set_target_defaults = $(call default_opts,USE_POLL USE_TPROXY USE_OBSOLETE_LINKER) +endif + +# For linux >= 2.6.28 and glibc +ifeq ($(TARGET),linux-glibc) + set_target_defaults = $(call default_opts, \ + USE_POLL USE_TPROXY USE_LIBCRYPT USE_DL USE_RT USE_CRYPT_H USE_NETFILTER \ + USE_CPU_AFFINITY USE_THREAD USE_EPOLL USE_LINUX_TPROXY \ + USE_ACCEPT4 USE_LINUX_SPLICE USE_PRCTL USE_THREAD_DUMP USE_NS USE_TFO \ + USE_GETADDRINFO USE_BACKTRACE) + INSTALL = install -v +endif + +# For linux >= 2.6.28, glibc without new features +ifeq ($(TARGET),linux-glibc-legacy) + set_target_defaults = $(call default_opts, \ + USE_POLL USE_TPROXY USE_LIBCRYPT USE_DL USE_RT USE_CRYPT_H USE_NETFILTER \ + USE_CPU_AFFINITY USE_THREAD USE_EPOLL USE_LINUX_TPROXY \ + USE_ACCEPT4 USE_LINUX_SPLICE USE_PRCTL USE_THREAD_DUMP USE_GETADDRINFO) + INSTALL = install -v +endif + +# For linux >= 2.6.28 and musl +ifeq ($(TARGET),linux-musl) + set_target_defaults = $(call default_opts, \ + USE_POLL USE_TPROXY USE_LIBCRYPT USE_DL USE_RT USE_CRYPT_H USE_NETFILTER \ + USE_CPU_AFFINITY USE_THREAD USE_EPOLL USE_LINUX_TPROXY \ + USE_ACCEPT4 USE_LINUX_SPLICE USE_PRCTL USE_THREAD_DUMP USE_NS USE_TFO \ + USE_GETADDRINFO USE_SHM_OPEN) + INSTALL = install -v +endif + +# Solaris 10 and above +ifeq ($(TARGET),solaris) + set_target_defaults = $(call default_opts, \ + USE_POLL USE_TPROXY USE_LIBCRYPT USE_CRYPT_H USE_GETADDRINFO USE_THREAD \ + USE_RT USE_OBSOLETE_LINKER USE_EVPORTS USE_CLOSEFROM) + TARGET_CFLAGS = -DFD_SETSIZE=65536 -D_REENTRANT -D_XOPEN_SOURCE=600 -D__EXTENSIONS__ + TARGET_LDFLAGS = -lnsl -lsocket +endif + +# FreeBSD 10 and above +ifeq ($(TARGET),freebsd) + set_target_defaults = $(call default_opts, \ + USE_POLL USE_TPROXY USE_LIBCRYPT USE_THREAD USE_CPU_AFFINITY USE_KQUEUE \ + USE_ACCEPT4 USE_CLOSEFROM USE_GETADDRINFO USE_PROCCTL) +endif + +# kFreeBSD glibc +ifeq ($(TARGET),freebsd-glibc) + set_target_defaults = $(call default_opts, \ + USE_POLL USE_TPROXY USE_LIBCRYPT USE_THREAD USE_CPU_AFFINITY USE_KQUEUE \ + USE_ACCEPT4 USE_GETADDRINFO USE_CRYPT_H USE_DL) +endif + +# DragonFlyBSD 4.3 and above +ifeq ($(TARGET),dragonfly) + set_target_defaults = $(call default_opts, \ + USE_POLL USE_TPROXY USE_LIBCRYPT USE_THREAD USE_CPU_AFFINITY USE_KQUEUE \ + USE_ACCEPT4 USE_CLOSEFROM USE_GETADDRINFO) +endif + +# Mac OS/X +ifeq ($(TARGET),osx) + set_target_defaults = $(call default_opts, \ + USE_POLL USE_TPROXY USE_LIBCRYPT USE_THREAD USE_CPU_AFFINITY USE_KQUEUE \ + USE_GETADDRINFO) + EXPORT_SYMBOL = -export_dynamic +endif + +# OpenBSD 6.3 and above +ifeq ($(TARGET),openbsd) + set_target_defaults = $(call default_opts, \ + USE_POLL USE_TPROXY USE_LIBCRYPT USE_THREAD USE_KQUEUE USE_ACCEPT4 \ + USE_CLOSEFROM USE_GETADDRINFO) +endif + +# NetBSD 8 and above +ifeq ($(TARGET),netbsd) + set_target_defaults = $(call default_opts, \ + USE_POLL USE_TPROXY USE_LIBCRYPT USE_THREAD USE_KQUEUE USE_ACCEPT4 \ + USE_CLOSEFROM USE_GETADDRINFO) +endif + +# AIX 5.1 only +ifeq ($(TARGET),aix51) + set_target_defaults = $(call default_opts, \ + USE_POLL USE_LIBCRYPT USE_OBSOLETE_LINKER) + TARGET_CFLAGS = -Dss_family=__ss_family -Dip6_hdr=ip6hdr -DSTEVENS_API -D_LINUX_SOURCE_COMPAT -Dunsetenv=my_unsetenv + DEBUG_CFLAGS = +endif + +# AIX 5.2 +ifeq ($(TARGET),aix52) + set_target_defaults = $(call default_opts, \ + USE_POLL USE_LIBCRYPT USE_OBSOLETE_LINKER) + TARGET_CFLAGS = -D_MSGQSUPPORT + DEBUG_CFLAGS = +endif + +# AIX 7.2 and above +ifeq ($(TARGET),aix72-gcc) + set_target_defaults = $(call default_opts, \ + USE_POLL USE_THREAD USE_LIBCRYPT USE_OBSOLETE_LINKER USE_GETADDRINFO) + TARGET_CFLAGS = -D_H_XMEM -D_H_VAR + TARGET_LDFLAGS = -latomic +endif + +# Cygwin +ifeq ($(TARGET),cygwin) + set_target_defaults = $(call default_opts, \ + USE_POLL USE_TPROXY USE_OBSOLETE_LINKER) + # Cygwin adds IPv6 support only in version 1.7 (in beta right now). + TARGET_CFLAGS = $(if $(filter 1.5.%, $(shell uname -r)), -DUSE_IPV6 -DAF_INET6=23 -DINET6_ADDRSTRLEN=46, ) +endif + +# set the default settings according to the target above +$(set_target_defaults) + +# Some architectures require to link with libatomic for atomics of certain +# sizes. These ones are reported as value 1 in the *_LOCK_FREE macros. Value +# 2 indicates that the builtin is native thus doesn't require libatomic. Hence +# any occurrence of 1 indicates libatomic is necessary. It's better to avoid +# linking with it by default as it's not always available nor deployed +# (especially on archs which do not need it). +ifneq ($(USE_THREAD),) +ifneq ($(shell $(CC) $(CFLAGS) -dM -E -xc - /dev/null | grep -c 'LOCK_FREE.*1'),0) + USE_LIBATOMIC=1 +endif +endif + +#### Determine version, sub-version and release date. +# If GIT is found, and IGNOREGIT is not set, VERSION, SUBVERS and VERDATE are +# extracted from the last commit. Otherwise, use the contents of the files +# holding the same names in the current directory. + +ifeq ($(IGNOREGIT),) +VERSION := $(shell [ -d .git/. ] && (git describe --tags --match 'v*' --abbrev=0 | cut -c 2-) 2>/dev/null) +ifneq ($(VERSION),) +# OK git is there and works. +SUBVERS := $(shell comms=`git log --format=oneline --no-merges v$(VERSION).. 2>/dev/null | wc -l | tr -d '[:space:]'`; commit=`(git log -1 --pretty=%h --abbrev=6) 2>/dev/null`; [ $$comms -gt 0 ] && echo "-$$commit-$$comms") +VERDATE := $(shell git log -1 --pretty=format:%ci | cut -f1 -d' ' | tr '-' '/') +endif +endif + +# Last commit version not found, take it from the files. +ifeq ($(VERSION),) +VERSION := $(shell cat VERSION 2>/dev/null || touch VERSION) +endif +ifeq ($(SUBVERS),) +SUBVERS := $(shell (grep -v '\$$Format' SUBVERS 2>/dev/null || touch SUBVERS) | head -n 1) +endif +ifeq ($(VERDATE),) +VERDATE := $(shell (grep -v '^\$$Format' VERDATE 2>/dev/null || touch VERDATE) | head -n 1 | cut -f1 -d' ' | tr '-' '/') +endif + +# this one is always empty by default and appended verbatim +EXTRAVERSION = + +#### Build options +# Do not change these ones, enable USE_* variables instead. +OPTIONS_CFLAGS = +OPTIONS_LDFLAGS = +OPTIONS_OBJS = + +#### Extra objects to be built and integrated (used only for development) +EXTRA_OBJS = + +# Return USE_xxx=$(USE_xxx) if the variable was set from the environment or the +# command line. +# Usage: +# BUILD_OPTIONS += $(call ignore_implicit,USE_xxx) +ignore_implicit = $(if $(subst environment,,$(origin $(1))), \ + $(if $(subst command line,,$(origin $(1))),, \ + $(1)=$($(1))), \ + $(1)=$($(1))) \ + +# This variable collects all USE_* values except those set to "implicit". This +# is used to report a list of all flags which were used to build this version. +# Do not assign anything to it. +BUILD_OPTIONS := $(foreach opt,$(use_opts),$(call ignore_implicit,$(opt))) + +# Make a list of all known features with +/- prepended depending on their +# activation status. Must be a macro so that dynamically enabled ones are +# evaluated with their current status. +BUILD_FEATURES = $(foreach opt,$(patsubst USE_%,%,$(sort $(use_opts))),$(if $(USE_$(opt)),+$(opt),-$(opt))) + +# All USE_* options have their equivalent macro defined in the code (some might +# possibly be unused though) +OPTIONS_CFLAGS += $(foreach opt,$(use_opts),$(if $($(opt)),-D$(opt),)) + +ifneq ($(USE_LIBCRYPT),) +ifneq ($(TARGET),openbsd) +ifneq ($(TARGET),osx) +OPTIONS_LDFLAGS += -lcrypt +endif +endif +endif + +ifneq ($(USE_ZLIB),) +# Use ZLIB_INC and ZLIB_LIB to force path to zlib.h and libz.{a,so} if needed. +ZLIB_INC = +ZLIB_LIB = +OPTIONS_CFLAGS += $(if $(ZLIB_INC),-I$(ZLIB_INC)) +OPTIONS_LDFLAGS += $(if $(ZLIB_LIB),-L$(ZLIB_LIB)) -lz +endif + +ifneq ($(USE_SLZ),) +OPTIONS_OBJS += src/slz.o +endif + +ifneq ($(USE_POLL),) +OPTIONS_OBJS += src/ev_poll.o +endif + +ifneq ($(USE_EPOLL),) +OPTIONS_OBJS += src/ev_epoll.o +endif + +ifneq ($(USE_KQUEUE),) +OPTIONS_OBJS += src/ev_kqueue.o +endif + +ifneq ($(USE_EVPORTS),) +OPTIONS_OBJS += src/ev_evports.o +endif + +ifneq ($(USE_DL),) +OPTIONS_LDFLAGS += -ldl +endif + +ifneq ($(USE_RT),) +OPTIONS_LDFLAGS += -lrt +endif + +ifneq ($(USE_THREAD),) +OPTIONS_LDFLAGS += -lpthread +endif + +ifneq ($(USE_BACKTRACE),) +OPTIONS_LDFLAGS += -Wl,$(if $(EXPORT_SYMBOL),$(EXPORT_SYMBOL),--export-dynamic) +endif + +ifneq ($(USE_CPU_AFFINITY),) +OPTIONS_OBJS += src/cpuset.o +endif + +ifneq ($(USE_OPENSSL),) +SSL_INC = +SSL_LIB = +# OpenSSL is packaged in various forms and with various dependencies. +# In general -lssl is enough, but on some platforms, -lcrypto may be needed, +# reason why it's added by default. Some even need -lz, then you'll need to +# pass it in the "ADDLIB" variable if needed. If your SSL libraries are not +# in the usual path, use SSL_INC=/path/to/inc and SSL_LIB=/path/to/lib. +OPTIONS_CFLAGS += $(if $(SSL_INC),-I$(SSL_INC)) +OPTIONS_LDFLAGS += $(if $(SSL_LIB),-L$(SSL_LIB)) -lssl -lcrypto +ifneq ($(USE_DL),) +OPTIONS_LDFLAGS += -ldl +endif +OPTIONS_OBJS += src/ssl_sample.o src/ssl_sock.o src/ssl_crtlist.o src/ssl_ckch.o src/ssl_utils.o src/cfgparse-ssl.o src/jwt.o +endif + +ifneq ($(USE_ENGINE),) +# OpenSSL 3.0 emits loud deprecation warnings by default when building with +# engine support, and this option is made to silence them. Better use it +# only when absolutely necessary, until there's a viable alternative to the +# engine API. +OPTIONS_CFLAGS += -DOPENSSL_SUPPRESS_DEPRECATED +endif + +ifneq ($(USE_QUIC),) +OPTIONS_OBJS += src/quic_sock.o src/proto_quic.o src/xprt_quic.o src/quic_tls.o \ + src/quic_frame.o src/quic_cc.o src/quic_cc_newreno.o src/mux_quic.o \ + src/cbuf.o src/qpack-dec.o src/qpack-tbl.o src/h3.o src/qpack-enc.o \ + src/hq_interop.o src/cfgparse-quic.o src/quic_loss.o \ + src/quic_tp.o src/quic_stream.o src/quic_stats.o src/h3_stats.o \ + src/quic_cc_cubic.o src/qmux_trace.o src/qmux_http.o \ + src/quic_conn.o +endif + +ifneq ($(USE_LUA),) +check_lua_lib = $(shell echo "int main(){}" | $(CC) -o /dev/null -x c - $(2) -l$(1) 2>/dev/null && echo $(1)) +check_lua_inc = $(shell if [ -d $(2)$(1) ]; then echo $(2)$(1); fi;) + +OPTIONS_CFLAGS += $(if $(LUA_INC),-I$(LUA_INC)) +LUA_LD_FLAGS := -Wl,$(if $(EXPORT_SYMBOL),$(EXPORT_SYMBOL),--export-dynamic) $(if $(LUA_LIB),-L$(LUA_LIB)) +ifeq ($(LUA_LIB_NAME),) +# Try to automatically detect the Lua library +LUA_LIB_NAME := $(firstword $(foreach lib,lua5.4 lua54 lua5.3 lua53 lua,$(call check_lua_lib,$(lib),$(LUA_LD_FLAGS)))) +ifeq ($(LUA_LIB_NAME),) +$(error unable to automatically detect the Lua library name, you can enforce its name with LUA_LIB_NAME= (where can be lua5.4, lua54, lua, ...)) +endif +LUA_INC := $(firstword $(foreach lib,lua5.4 lua54 lua5.3 lua53 lua,$(call check_lua_inc,$(lib),"/usr/include/"))) +ifneq ($(LUA_INC),) +OPTIONS_CFLAGS += -I$(LUA_INC) +endif +ifneq ($(HLUA_PREPEND_PATH),) +OPTIONS_CFLAGS += -DHLUA_PREPEND_PATH=$(HLUA_PREPEND_PATH) +BUILD_OPTIONS += HLUA_PREPEND_PATH=$(HLUA_PREPEND_PATH) +endif +ifneq ($(HLUA_PREPEND_CPATH),) +OPTIONS_CFLAGS += -DHLUA_PREPEND_CPATH=$(HLUA_PREPEND_CPATH) +BUILD_OPTIONS += HLUA_PREPEND_CPATH=$(HLUA_PREPEND_CPATH) +endif +endif + +OPTIONS_LDFLAGS += $(LUA_LD_FLAGS) -l$(LUA_LIB_NAME) -lm +ifneq ($(USE_DL),) +OPTIONS_LDFLAGS += -ldl +endif +OPTIONS_OBJS += src/hlua.o src/hlua_fcn.o +endif + +ifneq ($(USE_PROMEX),) +OPTIONS_OBJS += addons/promex/service-prometheus.o +endif + +ifneq ($(USE_DEVICEATLAS),) +# Use DEVICEATLAS_SRC and possibly DEVICEATLAS_INC and DEVICEATLAS_LIB to force path +# to DeviceAtlas headers and libraries if needed. +DEVICEATLAS_SRC = +DEVICEATLAS_INC = $(DEVICEATLAS_SRC) +DEVICEATLAS_LIB = $(DEVICEATLAS_SRC) +ifeq ($(DEVICEATLAS_SRC),) +OPTIONS_LDFLAGS += -lda +else +ifeq ($(USE_PCRE),) +ifeq ($(USE_PCRE2),) +$(error the DeviceAtlas module needs the PCRE or the PCRE2 library in order to compile) +endif +endif +ifneq ($(USE_PCRE2),) +OPTIONS_CFLAGS += -DDA_REGEX_HDR=\"dac_pcre2.c\" -DDA_REGEX_TAG=2 +endif +OPTIONS_OBJS += $(DEVICEATLAS_LIB)/Os/daunix.o +OPTIONS_OBJS += $(DEVICEATLAS_LIB)/dadwcom.o +OPTIONS_OBJS += $(DEVICEATLAS_LIB)/dasch.o +OPTIONS_OBJS += $(DEVICEATLAS_LIB)/json.o +OPTIONS_OBJS += $(DEVICEATLAS_LIB)/dac.o +endif +OPTIONS_OBJS += addons/deviceatlas/da.o +OPTIONS_CFLAGS += $(if $(DEVICEATLAS_INC),-I$(DEVICEATLAS_INC)) +endif + +ifneq ($(USE_51DEGREES),) +# Use 51DEGREES_SRC and possibly 51DEGREES_INC and 51DEGREES_LIB to force path +# to 51degrees headers and libraries if needed. +51DEGREES_SRC = +51DEGREES_INC = $(51DEGREES_SRC) +51DEGREES_LIB = $(51DEGREES_SRC) +OPTIONS_OBJS += $(51DEGREES_LIB)/../cityhash/city.o +OPTIONS_OBJS += $(51DEGREES_LIB)/51Degrees.o +OPTIONS_OBJS += addons/51degrees/51d.o +OPTIONS_CFLAGS += $(if $(51DEGREES_INC),-I$(51DEGREES_INC)) +ifeq ($(USE_THREAD),) +OPTIONS_CFLAGS += -DFIFTYONEDEGREES_NO_THREADING +else +OPTIONS_OBJS += $(51DEGREES_LIB)/../threading.o +endif + +OPTIONS_LDFLAGS += $(if $(51DEGREES_LIB),-L$(51DEGREES_LIB)) -lm +endif + +ifneq ($(USE_WURFL),) +# Use WURFL_SRC and possibly WURFL_INC and WURFL_LIB to force path +# to WURFL headers and libraries if needed. +WURFL_SRC = +WURFL_INC = $(WURFL_SRC) +WURFL_LIB = $(WURFL_SRC) +OPTIONS_OBJS += addons/wurfl/wurfl.o +OPTIONS_CFLAGS += $(if $(WURFL_INC),-I$(WURFL_INC)) +ifneq ($(WURFL_DEBUG),) +OPTIONS_CFLAGS += -DWURFL_DEBUG +endif +ifneq ($(WURFL_HEADER_WITH_DETAILS),) +OPTIONS_CFLAGS += -DWURFL_HEADER_WITH_DETAILS +endif +OPTIONS_LDFLAGS += $(if $(WURFL_LIB),-L$(WURFL_LIB)) -lwurfl +endif + +ifneq ($(USE_SYSTEMD),) +OPTIONS_LDFLAGS += -lsystemd +endif + +ifneq ($(USE_PCRE)$(USE_STATIC_PCRE)$(USE_PCRE_JIT),) +ifneq ($(USE_PCRE2)$(USE_STATIC_PCRE2)$(USE_PCRE2_JIT),) +$(error cannot compile both PCRE and PCRE2 support) +endif +# PCREDIR is used to automatically construct the PCRE_INC and PCRE_LIB paths, +# by appending /include and /lib respectively. If your system does not use the +# same sub-directories, simply force these variables instead of PCREDIR. It is +# automatically detected but can be forced if required (for cross-compiling). +# Forcing PCREDIR to an empty string will let the compiler use the default +# locations. + +PCRE_CONFIG := pcre-config +PCREDIR := $(shell $(PCRE_CONFIG) --prefix 2>/dev/null || echo /usr/local) +ifneq ($(PCREDIR),) +PCRE_INC := $(PCREDIR)/include +PCRE_LIB := $(PCREDIR)/lib +endif + +ifeq ($(USE_STATIC_PCRE),) +# dynamic PCRE +OPTIONS_CFLAGS += -DUSE_PCRE $(if $(PCRE_INC),-I$(PCRE_INC)) +OPTIONS_LDFLAGS += $(if $(PCRE_LIB),-L$(PCRE_LIB)) -lpcreposix -lpcre +else +# static PCRE +OPTIONS_CFLAGS += -DUSE_PCRE $(if $(PCRE_INC),-I$(PCRE_INC)) +OPTIONS_LDFLAGS += $(if $(PCRE_LIB),-L$(PCRE_LIB)) -Wl,-Bstatic -lpcreposix -lpcre -Wl,-Bdynamic +endif +endif + +ifneq ($(USE_PCRE2)$(USE_STATIC_PCRE2)$(USE_PCRE2_JIT),) +PCRE2_CONFIG := pcre2-config +PCRE2DIR := $(shell $(PCRE2_CONFIG) --prefix 2>/dev/null || echo /usr/local) +ifneq ($(PCRE2DIR),) +PCRE2_INC := $(PCRE2DIR)/include +PCRE2_LIB := $(PCRE2DIR)/lib + +ifeq ($(PCRE2_WIDTH),) +PCRE2_WIDTH = 8 +endif + +ifneq ($(PCRE2_WIDTH),8) +ifneq ($(PCRE2_WIDTH),16) +ifneq ($(PCRE2_WIDTH),32) +$(error PCRE2_WIDTH needs to be set to either 8,16 or 32) +endif +endif +endif + + +PCRE2_LDFLAGS := $(shell $(PCRE2_CONFIG) --libs$(PCRE2_WIDTH) 2>/dev/null || echo -L/usr/local/lib -lpcre2-$(PCRE2_WIDTH)) + +ifeq ($(PCRE2_LDFLAGS),) +$(error libpcre2-$(PCRE2_WIDTH) not found) +else +ifeq ($(PCRE2_WIDTH),8) +PCRE2_LDFLAGS += -lpcre2-posix +endif +endif + +OPTIONS_CFLAGS += -DUSE_PCRE2 -DPCRE2_CODE_UNIT_WIDTH=$(PCRE2_WIDTH) +OPTIONS_CFLAGS += $(if $(PCRE2_INC), -I$(PCRE2_INC)) + +ifneq ($(USE_STATIC_PCRE2),) +OPTIONS_LDFLAGS += $(if $(PCRE2_LIB),-L$(PCRE2_LIB)) -Wl,-Bstatic -L$(PCRE2_LIB) $(PCRE2_LDFLAGS) -Wl,-Bdynamic +else +OPTIONS_LDFLAGS += $(if $(PCRE2_LIB),-L$(PCRE2_LIB)) -L$(PCRE2_LIB) $(PCRE2_LDFLAGS) +endif + +endif +endif + +#### Global compile options +VERBOSE_CFLAGS = $(CFLAGS) $(TARGET_CFLAGS) $(SMALL_OPTS) $(DEFINE) +COPTS = -Iinclude + +COPTS += $(CFLAGS) $(TARGET_CFLAGS) $(SMALL_OPTS) $(DEFINE) $(SILENT_DEFINE) +COPTS += $(DEBUG) $(OPTIONS_CFLAGS) $(ADDINC) + +ifneq ($(VERSION)$(SUBVERS)$(EXTRAVERSION),) +COPTS += -DCONFIG_HAPROXY_VERSION=\"$(VERSION)$(SUBVERS)$(EXTRAVERSION)\" +endif + +ifneq ($(VERDATE),) +COPTS += -DCONFIG_HAPROXY_DATE=\"$(VERDATE)\" +endif + +ifneq ($(TRACE),) +# if tracing is enabled, we want it to be as fast as possible +TRACE_COPTS := $(filter-out -O0 -O1 -O2 -pg -finstrument-functions,$(COPTS)) -O3 -fomit-frame-pointer +COPTS += -finstrument-functions +endif + +ifneq ($(USE_NS),) +OPTIONS_OBJS += src/namespace.o +endif + +ifneq ($(USE_OT),) +include addons/ot/Makefile +endif + +ifneq ($(USE_LIBATOMIC),) + TARGET_LDFLAGS += -latomic +endif + +#### Global link options +# These options are added at the end of the "ld" command line. Use LDFLAGS to +# add options at the beginning of the "ld" command line if needed. +LDOPTS = $(TARGET_LDFLAGS) $(OPTIONS_LDFLAGS) $(ADDLIB) + +ifeq ($V,1) +cmd_CC = $(CC) +cmd_LD = $(LD) +cmd_AR = $(AR) +else +ifeq (3.81,$(firstword $(sort $(MAKE_VERSION) 3.81))) +# 3.81 or above +cmd_CC = $(info $ CC $@) $(Q)$(CC) +cmd_LD = $(info $ LD $@) $(Q)$(LD) +cmd_AR = $(info $ AR $@) $(Q)$(AR) +else +# 3.80 or older +cmd_CC = $(Q)echo " CC $@";$(CC) +cmd_LD = $(Q)echo " LD $@";$(LD) +cmd_AR = $(Q)echo " AR $@";$(AR) +endif +endif + +ifeq ($(TARGET),) +all: + @echo "Building HAProxy without specifying a TARGET is not supported." + @echo + @echo "Usage:" + @echo + @echo " $ make help # To print a full explanation." + @echo " $ make TARGET=xxx USE_=1 # To build HAProxy." + @echo + @echo "The most commonly used targets are:" + @echo + @echo " linux-glibc - Modern Linux with glibc" + @echo " linux-musl - Modern Linux with musl" + @echo " freebsd - FreeBSD" + @echo " openbsd - OpenBSD" + @echo " netbsd - NetBSD" + @echo " osx - macOS" + @echo " solaris - Solaris" + @echo + @echo "Choose the target which matches your OS the most in order to" + @echo "gain the maximum performance out of it." + @echo + @echo "Common features you might want to include in your build are:" + @echo + @echo " USE_OPENSSL=1 - Support for TLS encrypted connections" + @echo " USE_ZLIB=1 - Support for HTTP response compression" + @echo " USE_PCRE=1 - Support for PCRE regular expressions" + @echo " USE_LUA=1 - Support for dynamic processing using Lua" + @echo + @echo "Use 'make help' to print a full explanation of supported targets" + @echo "and features." + @echo + @exit 1 +else +ifneq ($(filter $(TARGET), linux linux22 linux24 linux24e linux26 linux2628),) +all: + @echo + @echo "Target '$(TARGET)' was removed from HAProxy 2.0 due to being irrelevant and" + @echo "often wrong. Please use 'linux-glibc' instead or define your custom target" + @echo "by checking available options using 'make help TARGET='." + @echo + @exit 1 +else +all: haproxy dev/flags/flags $(EXTRA) +endif +endif + +OBJS = + +ifneq ($(EXTRA_OBJS),) +OBJS += $(EXTRA_OBJS) +endif + +OBJS += src/mux_h2.o src/mux_fcgi.o src/mux_h1.o src/tcpcheck.o \ + src/stream.o src/stats.o src/http_ana.o src/server.o \ + src/stick_table.o src/sample.o src/flt_spoe.o src/tools.o \ + src/log.o src/cfgparse.o src/peers.o src/backend.o src/resolvers.o \ + src/cli.o src/connection.o src/proxy.o src/http_htx.o \ + src/cfgparse-listen.o src/pattern.o src/check.o src/haproxy.o \ + src/cache.o src/stconn.o src/http_act.o src/http_fetch.o \ + src/http_client.o src/listener.o src/dns.o src/vars.o src/debug.o \ + src/tcp_rules.o src/sink.o src/h1_htx.o src/task.o src/mjson.o \ + src/h2.o src/filters.o src/server_state.o src/payload.o \ + src/fcgi-app.o src/map.o src/htx.o src/h1.o src/pool.o \ + src/cfgparse-global.o src/trace.o src/tcp_sample.o \ + src/flt_http_comp.o src/mux_pt.o src/flt_trace.o src/mqtt.o \ + src/acl.o src/sock.o src/mworker.o src/tcp_act.o src/ring.o \ + src/session.o src/proto_tcp.o src/fd.o src/channel.o src/activity.o \ + src/queue.o src/lb_fas.o src/http_rules.o src/extcheck.o \ + src/thread.o src/http.o src/lb_chash.o src/applet.o \ + src/compression.o src/raw_sock.o src/ncbuf.o src/frontend.o \ + src/errors.o src/uri_normalizer.o src/http_conv.o src/lb_fwrr.o \ + src/sha1.o src/proto_sockpair.o src/mailers.o src/lb_fwlc.o \ + src/ebmbtree.o src/cfgcond.o src/action.o src/xprt_handshake.o \ + src/protocol.o src/proto_uxst.o src/proto_udp.o src/lb_map.o \ + src/fix.o src/ev_select.o src/arg.o src/sock_inet.o \ + src/mworker-prog.o src/hpack-dec.o src/cfgparse-tcp.o \ + src/sock_unix.o src/shctx.o src/proto_uxdg.o src/fcgi.o \ + src/eb64tree.o src/clock.o src/chunk.o src/cfgdiag.o src/signal.o \ + src/regex.o src/lru.o src/eb32tree.o src/eb32sctree.o \ + src/cfgparse-unix.o src/hpack-tbl.o src/ebsttree.o src/ebimtree.o \ + src/base64.o src/auth.o src/uri_auth.o src/time.o src/ebistree.o \ + src/dynbuf.o src/wdt.o src/pipe.o src/init.o src/http_acl.o \ + src/hpack-huff.o src/hpack-enc.o src/dict.o src/freq_ctr.o \ + src/ebtree.o src/hash.o src/dgram.o src/version.o + +ifneq ($(TRACE),) +OBJS += src/calltrace.o +endif + +# Used only for forced dependency checking. May be cleared during development. +INCLUDES = $(wildcard include/*/*.h) +DEP = $(INCLUDES) .build_opts + +help: + @sed -ne "/^[^#]*$$/q;s/^# \{0,1\}\(.*\)/\1/;p" Makefile + @echo; \ + if [ -n "$(TARGET)" ]; then \ + if [ -n "$(set_target_defaults)" ]; then \ + echo "Current TARGET: $(TARGET)"; \ + else \ + echo "Current TARGET: $(TARGET) (custom target)"; \ + fi; \ + else \ + echo "TARGET not set, you may pass 'TARGET=xxx' to set one among :";\ + echo " linux-glibc, linux-glibc-legacy, solaris, freebsd, dragonfly, netbsd,"; \ + echo " osx, openbsd, aix51, aix52, aix72-gcc, cygwin, haiku, generic,"; \ + echo " custom"; \ + fi + @echo;echo "Enabled features for TARGET '$(TARGET)' (disable with 'USE_xxx=') :" + @set -- $(foreach opt,$(patsubst USE_%,%,$(use_opts)),$(if $(USE_$(opt)),$(opt),)); echo " $$*" | (fmt || cat) 2>/dev/null + @echo;echo "Disabled features for TARGET '$(TARGET)' (enable with 'USE_xxx=1') :" + @set -- $(foreach opt,$(patsubst USE_%,%,$(use_opts)),$(if $(USE_$(opt)),,$(opt))); echo " $$*" | (fmt || cat) 2>/dev/null + +# Used only to force a rebuild if some build options change, but we don't do +# it for certain targets which take no build options +ifneq (reg-tests, $(firstword $(MAKECMDGOALS))) +build_opts = $(shell rm -f .build_opts.new; echo \'$(TARGET) $(BUILD_OPTIONS) $(VERBOSE_CFLAGS) $(DEBUG)\' > .build_opts.new; if cmp -s .build_opts .build_opts.new; then rm -f .build_opts.new; else mv -f .build_opts.new .build_opts; fi) +.build_opts: $(build_opts) +else +.build_opts: +endif + +haproxy: $(OPTIONS_OBJS) $(OBJS) + $(cmd_LD) $(LDFLAGS) -o $@ $^ $(LDOPTS) + +objsize: haproxy + $(Q)objdump -t $^|grep ' g '|grep -F '.text'|awk '{print $$5 FS $$6}'|sort + +%.o: %.c $(DEP) + $(cmd_CC) $(COPTS) -c -o $@ $< + +admin/halog/halog: admin/halog/halog.o admin/halog/fgets2.o src/ebtree.o src/eb32tree.o src/eb64tree.o src/ebmbtree.o src/ebsttree.o src/ebistree.o src/ebimtree.o + $(cmd_LD) $(LDFLAGS) -o $@ $^ $(LDOPTS) + +admin/dyncookie/dyncookie: admin/dyncookie/dyncookie.o + $(cmd_LD) $(LDFLAGS) -o $@ $^ $(LDOPTS) + +dev/flags/flags: dev/flags/flags.o + $(cmd_LD) $(LDFLAGS) -o $@ $^ $(LDOPTS) + +dev/haring/haring: dev/haring/haring.o + $(cmd_LD) $(LDFLAGS) -o $@ $^ $(LDOPTS) + +dev/hpack/%: dev/hpack/%.o + $(cmd_LD) $(LDFLAGS) -o $@ $^ $(LDOPTS) + +dev/poll/poll: + $(Q)$(MAKE) -C dev/poll poll CC='$(cmd_CC)' OPTIMIZE='$(COPTS)' + +dev/tcploop/tcploop: + $(Q)$(MAKE) -C dev/tcploop tcploop CC='$(cmd_CC)' OPTIMIZE='$(COPTS)' + +# rebuild it every time +.PHONY: src/version.c + +src/calltrace.o: src/calltrace.c $(DEP) + $(cmd_CC) $(TRACE_COPTS) -c -o $@ $< + +src/haproxy.o: src/haproxy.c $(DEP) + $(cmd_CC) $(COPTS) \ + -DBUILD_TARGET='"$(strip $(TARGET))"' \ + -DBUILD_ARCH='"$(strip $(ARCH))"' \ + -DBUILD_CPU='"$(strip $(CPU))"' \ + -DBUILD_CC='"$(strip $(CC))"' \ + -DBUILD_CFLAGS='"$(strip $(VERBOSE_CFLAGS))"' \ + -DBUILD_OPTIONS='"$(strip $(BUILD_OPTIONS))"' \ + -DBUILD_DEBUG='"$(strip $(DEBUG))"' \ + -DBUILD_FEATURES='"$(strip $(BUILD_FEATURES))"' \ + -c -o $@ $< + +install-man: + $(Q)$(INSTALL) -d "$(DESTDIR)$(MANDIR)"/man1 + $(Q)$(INSTALL) -m 644 doc/haproxy.1 "$(DESTDIR)$(MANDIR)"/man1 + +EXCLUDE_DOCUMENTATION = lgpl gpl coding-style +DOCUMENTATION = $(filter-out $(EXCLUDE_DOCUMENTATION),$(patsubst doc/%.txt,%,$(wildcard doc/*.txt))) + +install-doc: + $(Q)$(INSTALL) -d "$(DESTDIR)$(DOCDIR)" + $(Q)for x in $(DOCUMENTATION); do \ + $(INSTALL) -m 644 doc/$$x.txt "$(DESTDIR)$(DOCDIR)" ; \ + done + +install-bin: + $(Q)for i in haproxy $(EXTRA); do \ + if ! [ -e "$$i" ]; then \ + echo "Please run 'make' before 'make install'."; \ + exit 1; \ + fi; \ + done + $(Q)$(INSTALL) -d "$(DESTDIR)$(SBINDIR)" + $(Q)$(INSTALL) haproxy $(EXTRA) "$(DESTDIR)$(SBINDIR)" + +install: install-bin install-man install-doc + +uninstall: + $(Q)rm -f "$(DESTDIR)$(MANDIR)"/man1/haproxy.1 + $(Q)for x in $(DOCUMENTATION); do \ + rm -f "$(DESTDIR)$(DOCDIR)"/$$x.txt ; \ + done + $(Q)-rmdir "$(DESTDIR)$(DOCDIR)" + $(Q)rm -f "$(DESTDIR)$(SBINDIR)"/haproxy + +clean: + $(Q)rm -f *.[oas] src/*.[oas] haproxy test .build_opts .build_opts.new + $(Q)for dir in . src dev/* admin/* addons/* include/* doc; do rm -f $$dir/*~ $$dir/*.rej $$dir/core; done + $(Q)rm -f haproxy-$(VERSION).tar.gz haproxy-$(VERSION)$(SUBVERS)$(EXTRAVERSION).tar.gz + $(Q)rm -f haproxy-$(VERSION) haproxy-$(VERSION)$(SUBVERS)$(EXTRAVERSION) nohup.out gmon.out + $(Q)rm -f addons/promex/*.[oas] + $(Q)rm -f addons/51degrees/*.[oas] addons/51degrees/dummy/*.[oas] addons/51degrees/dummy/*/*.[oas] + $(Q)rm -f addons/deviceatlas/*.[oas] addons/deviceatlas/dummy/*.[oas] addons/deviceatlas/dummy/*.o + $(Q)rm -f addons/deviceatlas/dummy/Os/*.o + $(Q)rm -f addons/ot/src/*.[oas] + $(Q)rm -f addons/wurfl/*.[oas] addons/wurfl/dummy/*.[oas] + $(Q)rm -f admin/*/*.[oas] admin/*/*/*.[oas] + $(Q)rm -f admin/iprange/iprange admin/iprange/ip6range admin/halog/halog + $(Q)rm -f admin/dyncookie/dyncookie + $(Q)rm -f dev/*/*.[oas] + $(Q)rm -f dev/flags/flags dev/haring/haring dev/poll/poll dev/tcploop/tcploop + $(Q)rm -f dev/hpack/decode dev/hpack/gen-enc dev/hpack/gen-rht + +tags: + $(Q)find src include \( -name '*.c' -o -name '*.h' \) -print0 | \ + xargs -0 etags --declarations --members + +cscope: + $(Q)find src include -name "*.[ch]" -print | cscope -q -b -i - + +tar: clean + $(Q)ln -s . haproxy-$(VERSION)$(SUBVERS)$(EXTRAVERSION) + $(Q)tar --exclude=haproxy-$(VERSION)$(SUBVERS)$(EXTRAVERSION)/.git \ + --exclude=haproxy-$(VERSION)$(SUBVERS)$(EXTRAVERSION)/haproxy-$(VERSION)$(SUBVERS)$(EXTRAVERSION) \ + --exclude=haproxy-$(VERSION)$(SUBVERS)$(EXTRAVERSION)/haproxy-$(VERSION)$(SUBVERS)$(EXTRAVERSION).tar.gz \ + -cf - haproxy-$(VERSION)$(SUBVERS)$(EXTRAVERSION)/* | gzip -c9 >haproxy-$(VERSION)$(SUBVERS)$(EXTRAVERSION).tar.gz + $(Q)echo haproxy-$(VERSION)$(SUBVERS)$(EXTRAVERSION).tar.gz + $(Q)rm -f haproxy-$(VERSION)$(SUBVERS)$(EXTRAVERSION) + +git-tar: + $(Q)git archive --format=tar --prefix="haproxy-$(VERSION)$(SUBVERS)$(EXTRAVERSION)/" HEAD | gzip -9 > haproxy-$(VERSION)$(SUBVERS)$(EXTRAVERSION).tar.gz + $(Q)echo haproxy-$(VERSION)$(SUBVERS)$(EXTRAVERSION).tar.gz + +version: + @echo "VERSION: $(VERSION)" + @echo "SUBVERS: $(SUBVERS)" + @echo "VERDATE: $(VERDATE)" + +# never use this one if you don't know what it is used for. +update-version: + @echo "Ready to update the following versions :" + @echo "VERSION: $(VERSION)" + @echo "SUBVERS: $(SUBVERS)" + @echo "VERDATE: $(VERDATE)" + @echo "Press [ENTER] to continue or Ctrl-C to abort now.";read + echo "$(VERSION)" > VERSION + echo "$(SUBVERS)" > SUBVERS + echo "$(VERDATE)" > VERDATE + +# just display the build options +opts: + @echo -n 'Using: ' + @echo -n 'TARGET="$(strip $(TARGET))" ' + @echo -n 'ARCH="$(strip $(ARCH))" ' + @echo -n 'CPU="$(strip $(CPU))" ' + @echo -n 'CC="$(strip $(CC))" ' + @echo -n 'ARCH_FLAGS="$(strip $(ARCH_FLAGS))" ' + @echo -n 'CPU_CFLAGS="$(strip $(CPU_CFLAGS))" ' + @echo -n 'DEBUG_CFLAGS="$(strip $(DEBUG_CFLAGS))" ' + @echo "$(strip $(BUILD_OPTIONS))" + @echo 'COPTS="$(strip $(COPTS))"' + @echo 'LDFLAGS="$(strip $(LDFLAGS))"' + @echo 'LDOPTS="$(strip $(LDOPTS))"' + @echo 'OPTIONS_OBJS="$(strip $(OPTIONS_OBJS))"' + @echo 'OBJS="$(strip $(OBJS))"' + +ifeq (reg-tests, $(firstword $(MAKECMDGOALS))) + REGTEST_ARGS := $(wordlist 2, $(words $(MAKECMDGOALS)), $(MAKECMDGOALS)) + $(eval $(REGTEST_ARGS):;@true) +endif + +# Target to run the regression testing script files. +reg-tests: + $(Q)$(REG_TEST_SCRIPT) --type "$(REGTESTS_TYPES)" $(REGTEST_ARGS) $(REG_TEST_FILES) +.PHONY: $(REGTEST_ARGS) + +reg-tests-help: + @echo + @echo "To launch the reg tests for haproxy, first export to your environment " + @echo "VTEST_PROGRAM variable to point to your vtest program:" + @echo " $$ export VTEST_PROGRAM=/opt/local/bin/vtest" + @echo "or" + @echo " $$ setenv VTEST_PROGRAM /opt/local/bin/vtest" + @echo + @echo "The same thing may be done to set your haproxy program with HAPROXY_PROGRAM " + @echo "but with ./haproxy as default value." + @echo + @echo "To run all the tests:" + @echo " $$ make reg-tests" + @echo + @echo "You can also set the programs to be used on the command line:" + @echo " $$ VTEST_PROGRAM=<...> HAPROXY_PROGRAM=<...> make reg-tests" + @echo + @echo "To run tests with specific types:" + @echo " $$ REGTESTS_TYPES=slow,default make reg-tests" + @echo + @echo "with 'default,bug,devel,slow' as default value for REGTESTS_TYPES variable." + @echo + @echo "About the reg test types:" + @echo " any : all the tests without distinction (this is the default" + @echo " value of REGTESTS_TYPES." + @echo " default : dedicated to pure haproxy compliance tests." + @echo " slow : scripts which take non negligible time to run." + @echo " bug : scripts in relation with bugs they help to reproduce." + @echo " broken : scripts triggering known broken behaviors for which" + @echo " there is still no fix." + @echo " experimental: for scripts which are experimental, typically used to" + @echo " develop new scripts." + @echo + @echo "Note that 'reg-tests' target run '"$(REG_TEST_SCRIPT)"' script" + @echo "(see --help option of this script for more information)." + +.PHONY: reg-tests reg-tests-help diff --git a/README b/README new file mode 100644 index 0000000..a2c8b19 --- /dev/null +++ b/README @@ -0,0 +1,22 @@ +The HAProxy documentation has been split into a number of different files for +ease of use. + +Please refer to the following files depending on what you're looking for : + + - INSTALL for instructions on how to build and install HAProxy + - BRANCHES to understand the project's life cycle and what version to use + - LICENSE for the project's license + - CONTRIBUTING for the process to follow to submit contributions + +The more detailed documentation is located into the doc/ directory : + + - doc/intro.txt for a quick introduction on HAProxy + - doc/configuration.txt for the configuration's reference manual + - doc/lua.txt for the Lua's reference manual + - doc/SPOE.txt for how to use the SPOE engine + - doc/network-namespaces.txt for how to use network namespaces under Linux + - doc/management.txt for the management guide + - doc/regression-testing.txt for how to use the regression testing suite + - doc/peers.txt for the peers protocol reference + - doc/coding-style.txt for how to adopt HAProxy's coding style + - doc/internals for developer-specific documentation (not all up to date) diff --git a/SUBVERS b/SUBVERS new file mode 100644 index 0000000..784a711 --- /dev/null +++ b/SUBVERS @@ -0,0 +1,2 @@ +-f588462 + diff --git a/VERDATE b/VERDATE new file mode 100644 index 0000000..f7f2b00 --- /dev/null +++ b/VERDATE @@ -0,0 +1,2 @@ +2023-03-28 15:01:16 +0200 +2023/03/28 diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..c959dfb --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +2.6.12 diff --git a/addons/51degrees/51d.c b/addons/51degrees/51d.c new file mode 100644 index 0000000..5d68695 --- /dev/null +++ b/addons/51degrees/51d.c @@ -0,0 +1,783 @@ +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include <51Degrees.h> + +struct _51d_property_names { + struct list list; + char *name; +}; + +#ifdef FIFTYONEDEGREES_H_PATTERN_INCLUDED +static struct lru64_head *_51d_lru_tree = NULL; +static unsigned long long _51d_lru_seed; + +__decl_spinlock(_51d_lru_lock); +#endif + +static struct { + char property_separator; /* the separator to use in the response for the values. this is taken from 51degrees-property-separator from config. */ + struct list property_names; /* list of properties to load into the data set. this is taken from 51degrees-property-name-list from config. */ + char *data_file_path; + int header_count; /* number of HTTP headers related to device detection. */ + struct buffer *header_names; /* array of HTTP header names. */ + fiftyoneDegreesDataSet data_set; /* data set used with the pattern and trie detection methods. */ +#ifdef FIFTYONEDEGREES_H_PATTERN_INCLUDED + fiftyoneDegreesWorksetPool *pool; /* pool of worksets to avoid creating a new one for each request. */ +#endif +#ifdef FIFTYONEDEGREES_H_TRIE_INCLUDED + int32_t *header_offsets; /* offsets to the HTTP header name string. */ +#ifdef FIFTYONEDEGREES_NO_THREADING + fiftyoneDegreesDeviceOffsets device_offsets; /* Memory used for device offsets. */ +#endif +#endif + int cache_size; +} global_51degrees = { + .property_separator = ',', + .property_names = LIST_HEAD_INIT(global_51degrees.property_names), + .data_file_path = NULL, +#ifdef FIFTYONEDEGREES_H_PATTERN_INCLUDED + .data_set = { }, +#endif + .cache_size = 0, +}; + +static int _51d_data_file(char **args, int section_type, struct proxy *curpx, + const struct proxy *defpx, const char *file, int line, + char **err) +{ + if (*(args[1]) == 0) { + memprintf(err, + "'%s' expects a filepath to a 51Degrees trie or pattern data file.", + args[0]); + return -1; + } + + if (global_51degrees.data_file_path) + free(global_51degrees.data_file_path); + global_51degrees.data_file_path = strdup(args[1]); + + return 0; +} + +static int _51d_property_name_list(char **args, int section_type, struct proxy *curpx, + const struct proxy *defpx, const char *file, int line, + char **err) +{ + int cur_arg = 1; + struct _51d_property_names *name; + + if (*(args[cur_arg]) == 0) { + memprintf(err, + "'%s' expects at least one 51Degrees property name.", + args[0]); + return -1; + } + + while (*(args[cur_arg])) { + name = calloc(1, sizeof(*name)); + name->name = strdup(args[cur_arg]); + LIST_APPEND(&global_51degrees.property_names, &name->list); + ++cur_arg; + } + + return 0; +} + +static int _51d_property_separator(char **args, int section_type, struct proxy *curpx, + const struct proxy *defpx, const char *file, int line, + char **err) +{ + if (*(args[1]) == 0) { + memprintf(err, + "'%s' expects a single character.", + args[0]); + return -1; + } + if (strlen(args[1]) > 1) { + memprintf(err, + "'%s' expects a single character, got '%s'.", + args[0], args[1]); + return -1; + } + + global_51degrees.property_separator = *args[1]; + + return 0; +} + +static int _51d_cache_size(char **args, int section_type, struct proxy *curpx, + const struct proxy *defpx, const char *file, int line, + char **err) +{ + if (*(args[1]) == 0) { + memprintf(err, + "'%s' expects a positive numeric value.", + args[0]); + return -1; + } + + global_51degrees.cache_size = atoi(args[1]); + if (global_51degrees.cache_size < 0) { + memprintf(err, + "'%s' expects a positive numeric value, got '%s'.", + args[0], args[1]); + return -1; + } + + return 0; +} + +static int _51d_fetch_check(struct arg *arg, char **err_msg) +{ + if (global_51degrees.data_file_path) + return 1; + + memprintf(err_msg, "51Degrees data file is not specified (parameter '51degrees-data-file')"); + return 0; +} + +static int _51d_conv_check(struct arg *arg, struct sample_conv *conv, + const char *file, int line, char **err_msg) +{ + if (global_51degrees.data_file_path) + return 1; + + memprintf(err_msg, "51Degrees data file is not specified (parameter '51degrees-data-file')"); + return 0; +} + +#ifdef FIFTYONEDEGREES_H_PATTERN_INCLUDED +static void _51d_lru_free(void *cache_entry) +{ + struct buffer *ptr = cache_entry; + + if (!ptr) + return; + + free(ptr->area); + free(ptr); +} + +/* Allocates memory freeing space in the cache if necessary. +*/ +static void *_51d_malloc(int size) +{ + void *ptr = malloc(size); + + if (!ptr) { + /* free the oldest 10 entries from lru to free up some memory + * then try allocating memory again */ + lru64_kill_oldest(_51d_lru_tree, 10); + ptr = malloc(size); + } + + return ptr; +} + +/* Insert the data associated with the sample into the cache as a fresh item. + */ +static void _51d_insert_cache_entry(struct sample *smp, struct lru64 *lru, void* domain) +{ + struct buffer *cache_entry = _51d_malloc(sizeof(*cache_entry)); + + if (!cache_entry) + return; + + cache_entry->area = _51d_malloc(smp->data.u.str.data + 1); + if (!cache_entry->area) { + free(cache_entry); + return; + } + + memcpy(cache_entry->area, smp->data.u.str.area, smp->data.u.str.data); + cache_entry->area[smp->data.u.str.data] = 0; + cache_entry->data = smp->data.u.str.data; + HA_SPIN_LOCK(OTHER_LOCK, &_51d_lru_lock); + lru64_commit(lru, cache_entry, domain, 0, _51d_lru_free); + HA_SPIN_UNLOCK(OTHER_LOCK, &_51d_lru_lock); +} + +/* Retrieves the data from the cache and sets the sample data to this string. + */ +static void _51d_retrieve_cache_entry(struct sample *smp, struct lru64 *lru) +{ + struct buffer *cache_entry = lru->data; + smp->data.u.str.area = cache_entry->area; + smp->data.u.str.data = cache_entry->data; +} +#endif + +#ifdef FIFTYONEDEGREES_H_PATTERN_INCLUDED +/* Sets the important HTTP headers ahead of the detection + */ +static void _51d_set_headers(struct sample *smp, fiftyoneDegreesWorkset *ws) +{ + struct channel *chn; + struct htx *htx; + struct http_hdr_ctx ctx; + struct ist name; + int i; + + ws->importantHeadersCount = 0; + chn = (smp->strm ? &smp->strm->req : NULL); + + // No need to null check as this has already been carried out in the + // calling method + htx = smp_prefetch_htx(smp, chn, NULL, 1); + ALREADY_CHECKED(htx); + + for (i = 0; i < global_51degrees.header_count; i++) { + name = ist2((global_51degrees.header_names + i)->area, + (global_51degrees.header_names + i)->data); + ctx.blk = NULL; + + if (http_find_header(htx, name, &ctx, 1)) { + ws->importantHeaders[ws->importantHeadersCount].header = ws->dataSet->httpHeaders + i; + ws->importantHeaders[ws->importantHeadersCount].headerValue = ctx.value.ptr; + ws->importantHeaders[ws->importantHeadersCount].headerValueLength = ctx.value.len; + ws->importantHeadersCount++; + } + } +} +#endif + +#ifdef FIFTYONEDEGREES_H_TRIE_INCLUDED +static void _51d_init_device_offsets(fiftyoneDegreesDeviceOffsets *offsets) { + int i; + for (i = 0; i < global_51degrees.data_set.uniqueHttpHeaders.count; i++) { + offsets->firstOffset[i].userAgent = NULL; + } +} + +static void _51d_set_device_offsets(struct sample *smp, fiftyoneDegreesDeviceOffsets *offsets) +{ + struct channel *chn; + struct htx *htx; + struct http_hdr_ctx ctx; + struct ist name; + int i; + + offsets->size = 0; + chn = (smp->strm ? &smp->strm->req : NULL); + + // No need to null check as this has already been carried out in the + // calling method + htx = smp_prefetch_htx(smp, chn, NULL, 1); + ALREADY_CHECKED(htx); + + for (i = 0; i < global_51degrees.header_count; i++) { + name = ist2((global_51degrees.header_names + i)->area, + (global_51degrees.header_names + i)->data); + ctx.blk = NULL; + + if (http_find_header(htx, name, &ctx, 1)) { + (offsets->firstOffset + offsets->size)->httpHeaderOffset = *(global_51degrees.header_offsets + i); + (offsets->firstOffset + offsets->size)->deviceOffset = fiftyoneDegreesGetDeviceOffset(&global_51degrees.data_set, ctx.value.ptr); + offsets->size++; + } + } + +} +#endif + +#ifdef FIFTYONEDEGREES_H_PATTERN_INCLUDED +/* Provides a hash code for the important HTTP headers. + */ +unsigned long long _51d_req_hash(const struct arg *args, fiftyoneDegreesWorkset* ws) +{ + unsigned long long seed = _51d_lru_seed ^ (long)args; + unsigned long long hash = 0; + int i; + for(i = 0; i < ws->importantHeadersCount; i++) { + hash ^= ws->importantHeaders[i].header->headerNameOffset; + hash ^= XXH3(ws->importantHeaders[i].headerValue, + ws->importantHeaders[i].headerValueLength, + seed); + } + return hash; +} +#endif + +#ifdef FIFTYONEDEGREES_H_PATTERN_INCLUDED +static void _51d_process_match(const struct arg *args, struct sample *smp, fiftyoneDegreesWorkset* ws) +{ + char *methodName; +#endif +#ifdef FIFTYONEDEGREES_H_TRIE_INCLUDED +static void _51d_process_match(const struct arg *args, struct sample *smp, fiftyoneDegreesDeviceOffsets *offsets) +{ + char valuesBuffer[1024]; + const char **requiredProperties = fiftyoneDegreesGetRequiredPropertiesNames(&global_51degrees.data_set); + int requiredPropertiesCount = fiftyoneDegreesGetRequiredPropertiesCount(&global_51degrees.data_set); +#endif + + char no_data[] = "NoData"; /* response when no data could be found */ + struct buffer *temp = get_trash_chunk(); + int j, i = 0, found; + const char* property_name; + + /* Loop through property names passed to the filter and fetch them from the dataset. */ + while (args[i].data.str.area) { + /* Try to find request property in dataset. */ + found = 0; +#ifdef FIFTYONEDEGREES_H_PATTERN_INCLUDED + if (strcmp("Method", args[i].data.str.area) == 0) { + switch(ws->method) { + case EXACT: methodName = "Exact"; break; + case NUMERIC: methodName = "Numeric"; break; + case NEAREST: methodName = "Nearest"; break; + case CLOSEST: methodName = "Closest"; break; + default: + case NONE: methodName = "None"; break; + } + chunk_appendf(temp, "%s", methodName); + found = 1; + } + else if (strcmp("Difference", args[i].data.str.area) == 0) { + chunk_appendf(temp, "%d", ws->difference); + found = 1; + } + else if (strcmp("Rank", args[i].data.str.area) == 0) { + chunk_appendf(temp, "%d", fiftyoneDegreesGetSignatureRank(ws)); + found = 1; + } + else { + for (j = 0; j < ws->dataSet->requiredPropertyCount; j++) { + property_name = fiftyoneDegreesGetPropertyName(ws->dataSet, ws->dataSet->requiredProperties[j]); + if (strcmp(property_name, args[i].data.str.area) == 0) { + found = 1; + fiftyoneDegreesSetValues(ws, j); + chunk_appendf(temp, "%s", fiftyoneDegreesGetValueName(ws->dataSet, *ws->values)); + break; + } + } + } +#endif +#ifdef FIFTYONEDEGREES_H_TRIE_INCLUDED + found = 0; + for (j = 0; j < requiredPropertiesCount; j++) { + property_name = requiredProperties[j]; + if (strcmp(property_name, args[i].data.str.area) == 0 && + fiftyoneDegreesGetValueFromOffsets(&global_51degrees.data_set, offsets, j, valuesBuffer, 1024) > 0) { + found = 1; + chunk_appendf(temp, "%s", valuesBuffer); + break; + } + } +#endif + if (!found) + chunk_appendf(temp, "%s", no_data); + + /* Add separator. */ + chunk_appendf(temp, "%c", global_51degrees.property_separator); + ++i; + } + + if (temp->data) { + --temp->data; + temp->area[temp->data] = '\0'; + } + + smp->data.u.str.area = temp->area; + smp->data.u.str.data = temp->data; +} + +/* Sets the sample data as a constant string. This ensures that the + * string will be processed correctly. + */ +static void _51d_set_smp(struct sample *smp) +{ + /* + * Data type has to be set to ensure the string output is processed + * correctly. + */ + smp->data.type = SMP_T_STR; + + /* Flags the sample to show it uses constant memory. */ + smp->flags |= SMP_F_CONST; +} + +static int _51d_fetch(const struct arg *args, struct sample *smp, const char *kw, void *private) +{ +#ifdef FIFTYONEDEGREES_H_PATTERN_INCLUDED + fiftyoneDegreesWorkset* ws; /* workset for detection */ + struct lru64 *lru = NULL; +#endif +#ifdef FIFTYONEDEGREES_H_TRIE_INCLUDED + fiftyoneDegreesDeviceOffsets *offsets; /* Offsets for detection */ + +#endif + struct channel *chn; + struct htx *htx; + + chn = (smp->strm ? &smp->strm->req : NULL); + htx = smp_prefetch_htx(smp, chn, NULL, 1); + if (!htx) + return 0; + + +#ifdef FIFTYONEDEGREES_H_PATTERN_INCLUDED + + /* Get only the headers needed for device detection so they can be used + * with the cache to return previous results. Pattern is slower than + * Trie so caching will help improve performance. + */ + + /* Get a workset from the pool which will later contain detection results. */ + ws = fiftyoneDegreesWorksetPoolGet(global_51degrees.pool); + if (!ws) + return 0; + + /* Set the important HTTP headers for this request in the workset. */ + _51d_set_headers(smp, ws); + + /* Check the cache to see if there's results for these headers already. */ + if (_51d_lru_tree) { + HA_SPIN_LOCK(OTHER_LOCK, &_51d_lru_lock); + + lru = lru64_get(_51d_req_hash(args, ws), + _51d_lru_tree, (void*)args, 0); + + if (lru && lru->domain) { + fiftyoneDegreesWorksetPoolRelease(global_51degrees.pool, ws); + _51d_retrieve_cache_entry(smp, lru); + HA_SPIN_UNLOCK(OTHER_LOCK, &_51d_lru_lock); + + _51d_set_smp(smp); + return 1; + } + HA_SPIN_UNLOCK(OTHER_LOCK, &_51d_lru_lock); + } + + fiftyoneDegreesMatchForHttpHeaders(ws); + + _51d_process_match(args, smp, ws); + +#endif + +#ifdef FIFTYONEDEGREES_H_TRIE_INCLUDED +#ifndef FIFTYONEDEGREES_NO_THREADING + offsets = fiftyoneDegreesCreateDeviceOffsets(&global_51degrees.data_set); + _51d_init_device_offsets(offsets); +#else + offsets = &global_51degrees.device_offsets; +#endif + + /* Trie is very fast so all the headers can be passed in and the result + * returned faster than the hashing algorithm process. + */ + _51d_set_device_offsets(smp, offsets); + _51d_process_match(args, smp, offsets); + +#ifndef FIFTYONEDEGREES_NO_THREADING + fiftyoneDegreesFreeDeviceOffsets(offsets); +#endif + +#endif + +#ifdef FIFTYONEDEGREES_H_PATTERN_INCLUDED + fiftyoneDegreesWorksetPoolRelease(global_51degrees.pool, ws); + if (lru) + _51d_insert_cache_entry(smp, lru, (void*)args); +#endif + + _51d_set_smp(smp); + return 1; +} + +static int _51d_conv(const struct arg *args, struct sample *smp, void *private) +{ +#ifdef FIFTYONEDEGREES_H_PATTERN_INCLUDED + fiftyoneDegreesWorkset* ws; /* workset for detection */ + struct lru64 *lru = NULL; +#endif +#ifdef FIFTYONEDEGREES_H_TRIE_INCLUDED + fiftyoneDegreesDeviceOffsets *offsets; /* Offsets for detection */ +#endif + +#ifdef FIFTYONEDEGREES_H_PATTERN_INCLUDED + + /* Look in the list. */ + if (_51d_lru_tree) { + unsigned long long seed = _51d_lru_seed ^ (long)args; + + HA_SPIN_LOCK(OTHER_LOCK, &_51d_lru_lock); + lru = lru64_get(XXH3(smp->data.u.str.area, smp->data.u.str.data, seed), + _51d_lru_tree, (void*)args, 0); + if (lru && lru->domain) { + _51d_retrieve_cache_entry(smp, lru); + HA_SPIN_UNLOCK(OTHER_LOCK, &_51d_lru_lock); + return 1; + } + HA_SPIN_UNLOCK(OTHER_LOCK, &_51d_lru_lock); + } + + /* Create workset. This will later contain detection results. */ + ws = fiftyoneDegreesWorksetPoolGet(global_51degrees.pool); + if (!ws) + return 0; +#endif + + /* Duplicate the data and remove the "const" flag before device detection. */ + if (!smp_dup(smp)) + return 0; + + smp->data.u.str.area[smp->data.u.str.data] = '\0'; + + /* Perform detection. */ +#ifdef FIFTYONEDEGREES_H_PATTERN_INCLUDED + fiftyoneDegreesMatch(ws, smp->data.u.str.area); + _51d_process_match(args, smp, ws); +#endif +#ifdef FIFTYONEDEGREES_H_TRIE_INCLUDED +#ifndef FIFTYONEDEGREES_NO_THREADING + offsets = fiftyoneDegreesCreateDeviceOffsets(&global_51degrees.data_set); + _51d_init_device_offsets(offsets); +#else + offsets = &global_51degrees.device_offsets; +#endif + + offsets->firstOffset->deviceOffset = fiftyoneDegreesGetDeviceOffset(&global_51degrees.data_set, + smp->data.u.str.area); + offsets->size = 1; + _51d_process_match(args, smp, offsets); +#endif + +#ifdef FIFTYONEDEGREES_H_PATTERN_INCLUDED + fiftyoneDegreesWorksetPoolRelease(global_51degrees.pool, ws); + if (lru) + _51d_insert_cache_entry(smp, lru, (void*)args); +#endif + +#ifdef FIFTYONEDEGREES_H_TRIE_INCLUDED +#ifndef FIFTYONEDEGREES_NO_THREADING + fiftyoneDegreesFreeDeviceOffsets(offsets); +#endif +#endif + + _51d_set_smp(smp); + return 1; +} + +#ifdef FIFTYONEDEGREES_H_PATTERN_INCLUDED +void _51d_init_http_headers() +{ + int index = 0; + const fiftyoneDegreesAsciiString *headerName; + fiftyoneDegreesDataSet *ds = &global_51degrees.data_set; + global_51degrees.header_count = ds->httpHeadersCount; + global_51degrees.header_names = malloc(global_51degrees.header_count * sizeof(struct buffer)); + for (index = 0; index < global_51degrees.header_count; index++) { + headerName = fiftyoneDegreesGetString(ds, ds->httpHeaders[index].headerNameOffset); + (global_51degrees.header_names + index)->area = (char*)&headerName->firstByte; + (global_51degrees.header_names + index)->data = headerName->length - 1; + (global_51degrees.header_names + index)->size = (global_51degrees.header_names + index)->data; + } +} +#endif + +#ifdef FIFTYONEDEGREES_H_TRIE_INCLUDED +void _51d_init_http_headers() +{ + int index = 0; + fiftyoneDegreesDataSet *ds = &global_51degrees.data_set; + global_51degrees.header_count = fiftyoneDegreesGetHttpHeaderCount(ds); +#ifdef FIFTYONEDEGREES_NO_THREADING + global_51degrees.device_offsets.firstOffset = malloc( + global_51degrees.header_count * sizeof(fiftyoneDegreesDeviceOffset)); + _51d_init_device_offsets(&global_51degrees.device_offsets); +#endif + global_51degrees.header_names = malloc(global_51degrees.header_count * sizeof(struct buffer)); + global_51degrees.header_offsets = malloc(global_51degrees.header_count * sizeof(int32_t)); + for (index = 0; index < global_51degrees.header_count; index++) { + global_51degrees.header_offsets[index] = fiftyoneDegreesGetHttpHeaderNameOffset(ds, index); + global_51degrees.header_names[index].area = (char*)fiftyoneDegreesGetHttpHeaderNamePointer(ds, index); + global_51degrees.header_names[index].data = strlen(global_51degrees.header_names[index].area); + global_51degrees.header_names[index].size = global_51degrees.header_names->data; + } +} +#endif + +/* + * module init / deinit functions. Returns 0 if OK, or a combination of ERR_*. + */ +static int init_51degrees(void) +{ + int i = 0; + struct buffer *temp; + struct _51d_property_names *name; + char **_51d_property_list = NULL; + fiftyoneDegreesDataSetInitStatus _51d_dataset_status = DATA_SET_INIT_STATUS_NOT_SET; + + if (!global_51degrees.data_file_path) + return ERR_NONE; + + if (global.nbthread < 1) { + ha_alert("51Degrees: The thread count cannot be zero or negative.\n"); + return (ERR_FATAL | ERR_ALERT); + } + + if (!LIST_ISEMPTY(&global_51degrees.property_names)) { + i = 0; + list_for_each_entry(name, &global_51degrees.property_names, list) + ++i; + _51d_property_list = calloc(i, sizeof(*_51d_property_list)); + + i = 0; + list_for_each_entry(name, &global_51degrees.property_names, list) + _51d_property_list[i++] = name->name; + } + + _51d_dataset_status = fiftyoneDegreesInitWithPropertyArray(global_51degrees.data_file_path, &global_51degrees.data_set, (const char**)_51d_property_list, i); + + temp = get_trash_chunk(); + chunk_reset(temp); + + switch (_51d_dataset_status) { + case DATA_SET_INIT_STATUS_SUCCESS: +#ifdef FIFTYONEDEGREES_H_PATTERN_INCLUDED + global_51degrees.pool = fiftyoneDegreesWorksetPoolCreate(&global_51degrees.data_set, NULL, global.nbthread); +#endif + _51d_init_http_headers(); + break; + case DATA_SET_INIT_STATUS_INSUFFICIENT_MEMORY: + chunk_printf(temp, "Insufficient memory."); + break; + case DATA_SET_INIT_STATUS_CORRUPT_DATA: +#ifdef FIFTYONEDEGREES_H_PATTERN_INCLUDED + chunk_printf(temp, "Corrupt data file. Check that the data file provided is uncompressed and Pattern data format."); +#endif +#ifdef FIFTYONEDEGREES_H_TRIE_INCLUDED + chunk_printf(temp, "Corrupt data file. Check that the data file provided is uncompressed and Trie data format."); +#endif + break; + case DATA_SET_INIT_STATUS_INCORRECT_VERSION: +#ifdef FIFTYONEDEGREES_H_PATTERN_INCLUDED + chunk_printf(temp, "Incorrect version. Check that the data file provided is uncompressed and Pattern data format."); +#endif +#ifdef FIFTYONEDEGREES_H_TRIE_INCLUDED + chunk_printf(temp, "Incorrect version. Check that the data file provided is uncompressed and Trie data format."); +#endif + break; + case DATA_SET_INIT_STATUS_FILE_NOT_FOUND: + chunk_printf(temp, "File not found."); + break; + case DATA_SET_INIT_STATUS_NULL_POINTER: + chunk_printf(temp, "Null pointer to the existing dataset or memory location."); + break; + case DATA_SET_INIT_STATUS_POINTER_OUT_OF_BOUNDS: + chunk_printf(temp, "Allocated continuous memory containing 51Degrees data file appears to be smaller than expected. Most likely" + " because the data file was not fully loaded into the allocated memory."); + break; + case DATA_SET_INIT_STATUS_NOT_SET: + chunk_printf(temp, "Data set not initialised."); + break; + default: + chunk_printf(temp, "Other error."); + break; + } + if (_51d_dataset_status != DATA_SET_INIT_STATUS_SUCCESS) { + if (temp->data) + ha_alert("51Degrees Setup - Error reading 51Degrees data file. %s\n", + temp->area); + else + ha_alert("51Degrees Setup - Error reading 51Degrees data file.\n"); + return ERR_ALERT | ERR_FATAL; + } + free(_51d_property_list); + +#ifdef FIFTYONEDEGREES_H_PATTERN_INCLUDED + _51d_lru_seed = ha_random(); + if (global_51degrees.cache_size) { + _51d_lru_tree = lru64_new(global_51degrees.cache_size); + } +#endif + + return ERR_NONE; +} + +static void deinit_51degrees(void) +{ + struct _51d_property_names *_51d_prop_name, *_51d_prop_nameb; + + free(global_51degrees.header_names); +#ifdef FIFTYONEDEGREES_H_PATTERN_INCLUDED + if (global_51degrees.pool) + fiftyoneDegreesWorksetPoolFree(global_51degrees.pool); +#endif +#ifdef FIFTYONEDEGREES_H_TRIE_INCLUDED +#ifdef FIFTYONEDEGREES_NO_THREADING + free(global_51degrees.device_offsets.firstOffset); +#endif + free(global_51degrees.header_offsets); +#endif + fiftyoneDegreesDataSetFree(&global_51degrees.data_set); + + ha_free(&global_51degrees.data_file_path); + list_for_each_entry_safe(_51d_prop_name, _51d_prop_nameb, &global_51degrees.property_names, list) { + LIST_DELETE(&_51d_prop_name->list); + free(_51d_prop_name); + } + +#ifdef FIFTYONEDEGREES_H_PATTERN_INCLUDED + while (lru64_destroy(_51d_lru_tree)); +#endif +} + +static struct cfg_kw_list _51dcfg_kws = {{ }, { + { CFG_GLOBAL, "51degrees-data-file", _51d_data_file }, + { CFG_GLOBAL, "51degrees-property-name-list", _51d_property_name_list }, + { CFG_GLOBAL, "51degrees-property-separator", _51d_property_separator }, + { CFG_GLOBAL, "51degrees-cache-size", _51d_cache_size }, + { 0, NULL, NULL }, +}}; + +INITCALL1(STG_REGISTER, cfg_register_keywords, &_51dcfg_kws); + +/* Note: must not be declared as its list will be overwritten */ +static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, { + { "51d.all", _51d_fetch, ARG5(1,STR,STR,STR,STR,STR), _51d_fetch_check, SMP_T_STR, SMP_USE_HRQHV }, + { NULL, NULL, 0, 0, 0 }, +}}; + +INITCALL1(STG_REGISTER, sample_register_fetches, &sample_fetch_keywords); + +/* Note: must not be declared as its list will be overwritten */ +static struct sample_conv_kw_list conv_kws = {ILH, { + { "51d.single", _51d_conv, ARG5(1,STR,STR,STR,STR,STR), _51d_conv_check, SMP_T_STR, SMP_T_STR }, + { NULL, NULL, 0, 0, 0 }, +}}; + +INITCALL1(STG_REGISTER, sample_register_convs, &conv_kws); + +REGISTER_POST_CHECK(init_51degrees); +REGISTER_POST_DEINIT(deinit_51degrees); + +#if defined(FIFTYONEDEGREES_H_PATTERN_INCLUDED) +#ifndef FIFTYONEDEGREES_DUMMY_LIB + REGISTER_BUILD_OPTS("Built with 51Degrees Pattern support."); +#else + REGISTER_BUILD_OPTS("Built with 51Degrees Pattern support (dummy library)."); +#endif +#elif defined(FIFTYONEDEGREES_H_TRIE_INCLUDED) +#ifndef FIFTYONEDEGREES_DUMMY_LIB + REGISTER_BUILD_OPTS("Built with 51Degrees Trie support."); +#else + REGISTER_BUILD_OPTS("Built with 51Degrees Trie support (dummy library)."); +#endif +#endif diff --git a/addons/51degrees/dummy/cityhash/city.c b/addons/51degrees/dummy/cityhash/city.c new file mode 100644 index 0000000..b6b08bf --- /dev/null +++ b/addons/51degrees/dummy/cityhash/city.c @@ -0,0 +1,4 @@ +typedef struct cityhash_t { + // This is an empty structure to ensure a city.o is generated + // by the dummy library, it is never used. +} dummyCityHash; \ No newline at end of file diff --git a/addons/51degrees/dummy/pattern/51Degrees.c b/addons/51degrees/dummy/pattern/51Degrees.c new file mode 100644 index 0000000..c002e5c --- /dev/null +++ b/addons/51degrees/dummy/pattern/51Degrees.c @@ -0,0 +1,114 @@ +/* ********************************************************************* + * This Source Code Form is copyright of 51Degrees Mobile Experts Limited. + * Copyright 2019 51Degrees Mobile Experts Limited, 5 Charlotte Close, + * Caversham, Reading, Berkshire, United Kingdom RG4 7BY + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. + * + * If a copy of the MPL was not distributed with this file, You can obtain + * one at http://mozilla.org/MPL/2.0/. + * + * This Source Code Form is "Incompatible With Secondary Licenses", as + * defined by the Mozilla Public License, v. 2.0. + * *********************************************************************/ + +/* ********************************************************************* + * Dummy library for HAProxy. This does not function, and is designed + * solely for HAProxy testing purposes. + * *********************************************************************/ +#include "51Degrees.h" +#include + +int32_t fiftyoneDegreesGetSignatureRank(fiftyoneDegreesWorkset *ws) { + return 0; +} + +const char* fiftyoneDegreesGetPropertyName( + const fiftyoneDegreesDataSet *dataSet, + const fiftyoneDegreesProperty *property) { + return "dummy-property"; +} + +int32_t fiftyoneDegreesSetValues( + fiftyoneDegreesWorkset *ws, + int32_t requiredPropertyIndex) { + return 0; +} + +const char* fiftyoneDegreesGetValueName( + const fiftyoneDegreesDataSet *dataSet, + const fiftyoneDegreesValue *value) { + return "dummy-value"; +} + +static fiftyoneDegreesDataSet dummyDataSet = { + 0, + (fiftyoneDegreesHttpHeader*)NULL, + 0, + (const fiftyoneDegreesProperty**)NULL +}; + +static fiftyoneDegreesWorkset dummyWorkset = { + &dummyDataSet, + 0, + (fiftyoneDegreesHttpHeaderWorkset*)NULL, + EXACT, + 0, + (const fiftyoneDegreesValue **)NULL +}; + +fiftyoneDegreesWorkset *fiftyoneDegreesWorksetPoolGet( + fiftyoneDegreesWorksetPool *pool) { + return &dummyWorkset; +} + +void fiftyoneDegreesWorksetPoolRelease( + fiftyoneDegreesWorksetPool *pool, + fiftyoneDegreesWorkset *ws) { + return; +} + +void fiftyoneDegreesMatchForHttpHeaders(fiftyoneDegreesWorkset *ws) { + return; +} + +void fiftyoneDegreesMatch( + fiftyoneDegreesWorkset *ws, + const char* userAgent) { + return; +} + +fiftyoneDegreesDataSetInitStatus fiftyoneDegreesInitWithPropertyArray( + const char *fileName, + fiftyoneDegreesDataSet *dataSet, + const char** properties, + int32_t count) { + return DATA_SET_INIT_STATUS_SUCCESS; +} + +static fiftyoneDegreesWorksetPool dummyWorksetPool; + +fiftyoneDegreesWorksetPool *fiftyoneDegreesWorksetPoolCreate( + fiftyoneDegreesDataSet *dataSet, + fiftyoneDegreesResultsetCache *cache, + int32_t size) { + return &dummyWorksetPool; +} + +void fiftyoneDegreesWorksetPoolFree( + const fiftyoneDegreesWorksetPool *pool) { + return; +} + +void fiftyoneDegreesDataSetFree(const fiftyoneDegreesDataSet *dataSet) { + return; +} + +static fiftyoneDegreesAsciiString dummyAsciiString = {0, 0}; + +const fiftyoneDegreesAsciiString* fiftyoneDegreesGetString( + const fiftyoneDegreesDataSet *dataSet, + int32_t offset) { + return &dummyAsciiString; +} \ No newline at end of file diff --git a/addons/51degrees/dummy/pattern/51Degrees.h b/addons/51degrees/dummy/pattern/51Degrees.h new file mode 100644 index 0000000..9aaf949 --- /dev/null +++ b/addons/51degrees/dummy/pattern/51Degrees.h @@ -0,0 +1,147 @@ +/* ********************************************************************* + * This Source Code Form is copyright of 51Degrees Mobile Experts Limited. + * Copyright 2019 51Degrees Mobile Experts Limited, 5 Charlotte Close, + * Caversham, Reading, Berkshire, United Kingdom RG4 7BY + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. + * + * If a copy of the MPL was not distributed with this file, You can obtain + * one at http://mozilla.org/MPL/2.0/. + * + * This Source Code Form is "Incompatible With Secondary Licenses", as + * defined by the Mozilla Public License, v. 2.0. + * *********************************************************************/ + +/* ********************************************************************* + * Dummy library for HAProxy. This does not function, and is designed + * solely for HAProxy testing purposes. + * *********************************************************************/ +#ifndef FIFTYONEDEGREES_H_INCLUDED +#define FIFTYONEDEGREES_H_INCLUDED + +#ifndef FIFTYONEDEGREES_H_PATTERN_INCLUDED +#define FIFTYONEDEGREES_H_PATTERN_INCLUDED +#endif + +#ifndef FIFTYONEDEGREES_DUMMY_LIB +#define FIFTYONEDEGREES_DUMMY_LIB +#endif + +#include + +typedef enum e_fiftyoneDegrees_MatchMethod { + NONE, + EXACT, + NUMERIC, + NEAREST, + CLOSEST +} fiftyoneDegreesMatchMethod; + +typedef enum e_fiftyoneDegrees_DataSetInitStatus { + DATA_SET_INIT_STATUS_SUCCESS, + DATA_SET_INIT_STATUS_INSUFFICIENT_MEMORY, + DATA_SET_INIT_STATUS_CORRUPT_DATA, + DATA_SET_INIT_STATUS_INCORRECT_VERSION, + DATA_SET_INIT_STATUS_FILE_NOT_FOUND, + DATA_SET_INIT_STATUS_NOT_SET, + DATA_SET_INIT_STATUS_POINTER_OUT_OF_BOUNDS, + DATA_SET_INIT_STATUS_NULL_POINTER +} fiftyoneDegreesDataSetInitStatus; + +typedef struct fiftyoneDegrees_ascii_string_t { + const int16_t length; + const char firstByte; +} fiftyoneDegreesAsciiString; + +typedef struct fiftyoneDegrees_dataset_header_t { +} fiftyoneDegreesDataSetHeader; + +typedef struct fiftyoneDegrees_workset_pool_t { +} fiftyoneDegreesWorksetPool; + +typedef struct fiftyoneDegrees_property_t { +} fiftyoneDegreesProperty; + +typedef struct fiftyoneDegrees_value_t { +} fiftyoneDegreesValue; + +typedef struct fiftyoneDegrees_resultset_cache_t { +} fiftyoneDegreesResultsetCache; + +typedef struct fiftyoneDegrees_http_header_t { + int32_t headerNameOffset; + const char *headerName; +} fiftyoneDegreesHttpHeader; + +typedef struct fiftyoneDegrees_http_header_workset_t { + fiftyoneDegreesHttpHeader *header; + const char *headerValue; + int headerValueLength; +} fiftyoneDegreesHttpHeaderWorkset; + + +typedef struct fiftyoneDegrees_dataset_t { + int32_t httpHeadersCount; + fiftyoneDegreesHttpHeader *httpHeaders; + int32_t requiredPropertyCount; + const fiftyoneDegreesProperty **requiredProperties; +} fiftyoneDegreesDataSet; + +typedef struct fiftyoneDegrees_workset_t { + fiftyoneDegreesDataSet *dataSet; + int32_t importantHeadersCount; + fiftyoneDegreesHttpHeaderWorkset *importantHeaders; + fiftyoneDegreesMatchMethod method; + int32_t difference; + const fiftyoneDegreesValue **values; +} fiftyoneDegreesWorkset; + +int32_t fiftyoneDegreesGetSignatureRank(fiftyoneDegreesWorkset *ws); + +const char* fiftyoneDegreesGetPropertyName( + const fiftyoneDegreesDataSet *dataSet, + const fiftyoneDegreesProperty *property); + +int32_t fiftyoneDegreesSetValues( + fiftyoneDegreesWorkset *ws, + int32_t requiredPropertyIndex); + +const char* fiftyoneDegreesGetValueName( + const fiftyoneDegreesDataSet *dataSet, + const fiftyoneDegreesValue *value); + +fiftyoneDegreesWorkset *fiftyoneDegreesWorksetPoolGet( + fiftyoneDegreesWorksetPool *pool); + +void fiftyoneDegreesWorksetPoolRelease( + fiftyoneDegreesWorksetPool *pool, + fiftyoneDegreesWorkset *ws); + +void fiftyoneDegreesMatchForHttpHeaders(fiftyoneDegreesWorkset *ws); + +void fiftyoneDegreesMatch( + fiftyoneDegreesWorkset *ws, + const char* userAgent); + +fiftyoneDegreesDataSetInitStatus fiftyoneDegreesInitWithPropertyArray( + const char *fileName, + fiftyoneDegreesDataSet *dataSet, + const char** properties, + int32_t count); + +fiftyoneDegreesWorksetPool *fiftyoneDegreesWorksetPoolCreate( + fiftyoneDegreesDataSet *dataSet, + fiftyoneDegreesResultsetCache *cache, + int32_t size); + +void fiftyoneDegreesWorksetPoolFree( + const fiftyoneDegreesWorksetPool *pool); + +void fiftyoneDegreesDataSetFree(const fiftyoneDegreesDataSet *dataSet); + +const fiftyoneDegreesAsciiString* fiftyoneDegreesGetString( + const fiftyoneDegreesDataSet *dataSet, + int32_t offset); + +#endif \ No newline at end of file diff --git a/addons/51degrees/dummy/threading.c b/addons/51degrees/dummy/threading.c new file mode 100644 index 0000000..e65678d --- /dev/null +++ b/addons/51degrees/dummy/threading.c @@ -0,0 +1,4 @@ +typedef struct fiftyoneDegrees_threading_t { + // This is an empty structure to ensure a threading.o is generated + // by the dummy library, it is never used. +} dummyFiftyoneDegreesThreading; \ No newline at end of file diff --git a/addons/51degrees/dummy/trie/51Degrees.c b/addons/51degrees/dummy/trie/51Degrees.c new file mode 100644 index 0000000..7453061 --- /dev/null +++ b/addons/51degrees/dummy/trie/51Degrees.c @@ -0,0 +1,89 @@ +/* ********************************************************************* + * This Source Code Form is copyright of 51Degrees Mobile Experts Limited. + * Copyright 2019 51Degrees Mobile Experts Limited, 5 Charlotte Close, + * Caversham, Reading, Berkshire, United Kingdom RG4 7BY + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. + * + * If a copy of the MPL was not distributed with this file, You can obtain + * one at http://mozilla.org/MPL/2.0/. + * + * This Source Code Form is "Incompatible With Secondary Licenses", as + * defined by the Mozilla Public License, v. 2.0. + * *********************************************************************/ + +/* ********************************************************************* + * Dummy library for HAProxy. This does not function, and is designed + * solely for HAProxy testing purposes. + * *********************************************************************/ +#include "51Degrees.h" +#include + +int fiftyoneDegreesGetDeviceOffset( + fiftyoneDegreesDataSet *dataSet, + const char *userAgent) { + return 0; +} + +const char** fiftyoneDegreesGetRequiredPropertiesNames( + fiftyoneDegreesDataSet *dataSet) { + return NULL; +} + +int fiftyoneDegreesGetRequiredPropertiesCount( + fiftyoneDegreesDataSet *dataSet) { + return 0; +} + +int fiftyoneDegreesGetValueFromOffsets( + fiftyoneDegreesDataSet *dataSet, + fiftyoneDegreesDeviceOffsets* deviceOffsets, + int requiredPropertyIndex, + char* values, + int size) { + return 0; +} + +static fiftyoneDegreesDeviceOffset dummyOffset = { 0, 0, "dummy-user-agent" }; + +static fiftyoneDegreesDeviceOffsets dummyOffsets = { 1, &dummyOffset, NULL }; + +fiftyoneDegreesDeviceOffsets* fiftyoneDegreesCreateDeviceOffsets( + fiftyoneDegreesDataSet *dataSet) { + return &dummyOffsets; +} + +void fiftyoneDegreesFreeDeviceOffsets( + fiftyoneDegreesDeviceOffsets* offsets) { + return; +} + +int fiftyoneDegreesGetHttpHeaderCount( + fiftyoneDegreesDataSet *dataSet) { + return 0; +} + +int fiftyoneDegreesGetHttpHeaderNameOffset( + fiftyoneDegreesDataSet *dataSet, + int httpHeaderIndex) { + return 0; +} + +const char* fiftyoneDegreesGetHttpHeaderNamePointer( + fiftyoneDegreesDataSet *dataSet, + int httpHeaderIndex) { + return "dummy-header-name"; +} + +fiftyoneDegreesDataSetInitStatus fiftyoneDegreesInitWithPropertyArray( + const char* fileName, + fiftyoneDegreesDataSet *dataSet, + const char** properties, + int propertyCount) { + return DATA_SET_INIT_STATUS_SUCCESS; +} + +void fiftyoneDegreesDataSetFree(fiftyoneDegreesDataSet *dataSet) { + return; +} \ No newline at end of file diff --git a/addons/51degrees/dummy/trie/51Degrees.h b/addons/51degrees/dummy/trie/51Degrees.h new file mode 100644 index 0000000..bedcfd7 --- /dev/null +++ b/addons/51degrees/dummy/trie/51Degrees.h @@ -0,0 +1,112 @@ +/* ********************************************************************* + * This Source Code Form is copyright of 51Degrees Mobile Experts Limited. + * Copyright 2019 51Degrees Mobile Experts Limited, 5 Charlotte Close, + * Caversham, Reading, Berkshire, United Kingdom RG4 7BY + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. + * + * If a copy of the MPL was not distributed with this file, You can obtain + * one at http://mozilla.org/MPL/2.0/. + * + * This Source Code Form is "Incompatible With Secondary Licenses", as + * defined by the Mozilla Public License, v. 2.0. + * *********************************************************************/ + +/* ********************************************************************* + * Dummy library for HAProxy. This does not function, and is designed + * solely for HAProxy testing purposes. + * *********************************************************************/ +#ifndef FIFTYONEDEGREES_H_INCLUDED +#define FIFTYONEDEGREES_H_INCLUDED + +#ifndef FIFTYONEDEGREES_H_TRIE_INCLUDED +#define FIFTYONEDEGREES_H_TRIE_INCLUDED +#endif + +#ifndef FIFTYONEDEGREES_DUMMY_LIB +#define FIFTYONEDEGREES_DUMMY_LIB +#endif + +#include + +typedef enum e_fiftyoneDegrees_DataSetInitStatus { + DATA_SET_INIT_STATUS_SUCCESS, + DATA_SET_INIT_STATUS_INSUFFICIENT_MEMORY, + DATA_SET_INIT_STATUS_CORRUPT_DATA, + DATA_SET_INIT_STATUS_INCORRECT_VERSION, + DATA_SET_INIT_STATUS_FILE_NOT_FOUND, + DATA_SET_INIT_STATUS_NOT_SET, + DATA_SET_INIT_STATUS_POINTER_OUT_OF_BOUNDS, + DATA_SET_INIT_STATUS_NULL_POINTER +} fiftyoneDegreesDataSetInitStatus; + +typedef struct fiftyoneDegrees_integers_t { + int32_t *firstElement; + unsigned int count; + int freeMemory; +} fiftyoneDegreesIntegers; + +typedef struct fiftyoneDegrees_dataset_t { + fiftyoneDegreesIntegers uniqueHttpHeaders; +} fiftyoneDegreesDataSet; + +typedef struct fiftyoneDegrees_active_dataset_t { + +} fiftyoneDegreesActiveDataSet; + +typedef struct fiftyoneDegrees_device_offset_t { + int httpHeaderOffset; + int deviceOffset; + char *userAgent; +} fiftyoneDegreesDeviceOffset; + +typedef struct fiftyoneDegrees_device_offsets_t { + int size; + fiftyoneDegreesDeviceOffset *firstOffset; + fiftyoneDegreesActiveDataSet *active; +} fiftyoneDegreesDeviceOffsets; + +int fiftyoneDegreesGetDeviceOffset( + fiftyoneDegreesDataSet *dataSet, + const char *userAgent); + +const char** fiftyoneDegreesGetRequiredPropertiesNames( + fiftyoneDegreesDataSet *dataSet); + +int fiftyoneDegreesGetRequiredPropertiesCount( + fiftyoneDegreesDataSet *dataSet); + +int fiftyoneDegreesGetValueFromOffsets( + fiftyoneDegreesDataSet *dataSet, + fiftyoneDegreesDeviceOffsets* deviceOffsets, + int requiredPropertyIndex, + char* values, + int size); + +fiftyoneDegreesDeviceOffsets* fiftyoneDegreesCreateDeviceOffsets( + fiftyoneDegreesDataSet *dataSet); + +void fiftyoneDegreesFreeDeviceOffsets( + fiftyoneDegreesDeviceOffsets* offsets); + +int fiftyoneDegreesGetHttpHeaderCount( + fiftyoneDegreesDataSet *dataSet); + +int fiftyoneDegreesGetHttpHeaderNameOffset( + fiftyoneDegreesDataSet *dataSet, + int httpHeaderIndex); + +const char* fiftyoneDegreesGetHttpHeaderNamePointer( + fiftyoneDegreesDataSet *dataSet, + int httpHeaderIndex); + +fiftyoneDegreesDataSetInitStatus fiftyoneDegreesInitWithPropertyArray( + const char* fileName, + fiftyoneDegreesDataSet *dataSet, + const char** properties, + int propertyCount); + +void fiftyoneDegreesDataSetFree(fiftyoneDegreesDataSet *dataSet); + +#endif \ No newline at end of file diff --git a/addons/deviceatlas/Makefile b/addons/deviceatlas/Makefile new file mode 100644 index 0000000..fbcffca --- /dev/null +++ b/addons/deviceatlas/Makefile @@ -0,0 +1,48 @@ +# DEVICEATLAS_SRC : DeviceAtlas API source root path + + +OS := $(shell uname -s) +OBJS := dadwsch.o +CFLAGS := -g -O2 +LDFLAGS := + +CURL_CONFIG := curl-config +CURLDIR := $(shell $(CURL_CONFIG) --prefix 2>/dev/null || echo /usr/local) +CURL_INC := $(CURLDIR)/include +CURL_LIB := $(CURLDIR)/lib +CURL_LDFLAGS := $(shell $(CURL_CONFIG) --libs 2>/dev/null || echo -L /usr/local/lib -lcurl) + +PCRE2_CONFIG := pcre2-config +PCRE2DIR := $(shell $(PCRE2_CONFIG) --prefix 2>/dev/null || echo /usr/local) +PCRE2_INC := $(PCRE2DIR)/include +PCRE2_LIB := $(PCRE2DIR)/lib +PCRE2_LDFLAGS := $(shell $(PCRE2_CONFIG) --libs8 2>/dev/null || echo /usr/local) + +ifeq ($(DEVICEATLAS_SRC),) +dadwsch: dadwsch.c + $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) + +LDFLAGS += -lda +else +DEVICEATLAS_INC = $(DEVICEATLAS_SRC) +DEVICEATLAS_LIB = $(DEVICEATLAS_SRC) +CFLAGS += -DDA_REGEX_HDR=\"dac_pcre2.c\" -DDA_REGEX_TAG=2 +CFLAGS += -DMOBI_CURL -DMOBI_CURLSSET -DMOBI_GZ -DMOBI_ZIP +CFLAGS += -I$(DEVICEATLAS_INC) -I$(CURL_INC) -I$(PCRE2DIR) +LDFLAGS += $(CURL_LDFLAGS) $(PCRE2_LDFLAGS) -lz -lzip -lpthread + +dadwsch: dadwsch.c $(DEVICEATLAS_SRC)/dac.c $(DEVICEATLAS_SRC)/dasch.c $(DEVICEATLAS_SRC)/dadwarc.c $(DEVICEATLAS_SRC)/dadwcom.c $(DEVICEATLAS_SRC)/dadwcurl.c $(DEVICEATLAS_SRC)/json.c $(DEVICEATLAS_SRC)/Os/daunix.c + $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) +endif + +ifeq ($(OS), Linux) +LDFLAGS += -lrt +endif +ifeq ($(OS), SunOS) +LDFLAGS += -lrt +endif + +clean: + rm -f *.o + rm -f $(DEVICEATLAS_LIB)*.o + rm -f dadwsch diff --git a/addons/deviceatlas/da.c b/addons/deviceatlas/da.c new file mode 100644 index 0000000..969dfaa --- /dev/null +++ b/addons/deviceatlas/da.c @@ -0,0 +1,501 @@ +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ATLASTOKSZ PATH_MAX +#define ATLASMAPNM "/hapdeviceatlas" + +static struct { + void *atlasimgptr; + void *atlasmap; + char *jsonpath; + char *cookiename; + size_t cookienamelen; + int atlasfd; + da_atlas_t atlas; + da_evidence_id_t useragentid; + da_severity_t loglevel; + char separator; + unsigned char daset:1; +} global_deviceatlas = { + .loglevel = 0, + .jsonpath = 0, + .cookiename = 0, + .cookienamelen = 0, + .atlasmap = NULL, + .atlasfd = -1, + .useragentid = 0, + .daset = 0, + .separator = '|', +}; + +__decl_thread(HA_SPINLOCK_T dadwsch_lock); + +static int da_json_file(char **args, int section_type, struct proxy *curpx, + const struct proxy *defpx, const char *file, int line, + char **err) +{ + if (*(args[1]) == 0) { + memprintf(err, "deviceatlas json file : expects a json path.\n"); + return -1; + } + global_deviceatlas.jsonpath = strdup(args[1]); + return 0; +} + +static int da_log_level(char **args, int section_type, struct proxy *curpx, + const struct proxy *defpx, const char *file, int line, + char **err) +{ + int loglevel; + if (*(args[1]) == 0) { + memprintf(err, "deviceatlas log level : expects an integer argument.\n"); + return -1; + } + + loglevel = atol(args[1]); + if (loglevel < 0 || loglevel > 3) { + memprintf(err, "deviceatlas log level : expects a log level between 0 and 3, %s given.\n", args[1]); + } else { + global_deviceatlas.loglevel = (da_severity_t)loglevel; + } + + return 0; +} + +static int da_property_separator(char **args, int section_type, struct proxy *curpx, + const struct proxy *defpx, const char *file, int line, + char **err) +{ + if (*(args[1]) == 0) { + memprintf(err, "deviceatlas property separator : expects a character argument.\n"); + return -1; + } + global_deviceatlas.separator = *args[1]; + return 0; +} + +static int da_properties_cookie(char **args, int section_type, struct proxy *curpx, + const struct proxy *defpx, const char *file, int line, + char **err) +{ + if (*(args[1]) == 0) { + memprintf(err, "deviceatlas cookie name : expects a string argument.\n"); + return -1; + } else { + global_deviceatlas.cookiename = strdup(args[1]); + } + global_deviceatlas.cookienamelen = strlen(global_deviceatlas.cookiename); + return 0; +} + +static size_t da_haproxy_read(void *ctx, size_t len, char *buf) +{ + return fread(buf, 1, len, ctx); +} + +static da_status_t da_haproxy_seek(void *ctx, off_t off) +{ + return fseek(ctx, off, SEEK_SET) != -1 ? DA_OK : DA_SYS; +} + +static void da_haproxy_log(da_severity_t severity, da_status_t status, + const char *fmt, va_list args) +{ + if (global_deviceatlas.loglevel && severity <= global_deviceatlas.loglevel) { + char logbuf[256]; + vsnprintf(logbuf, sizeof(logbuf), fmt, args); + ha_warning("deviceatlas : %s.\n", logbuf); + } +} + +#define DA_COOKIENAME_DEFAULT "DAPROPS" + +/* + * module init / deinit functions. Returns 0 if OK, or a combination of ERR_*. + */ +static int init_deviceatlas(void) +{ + int err_code = ERR_NONE; + + if (global_deviceatlas.jsonpath != 0) { + FILE *jsonp; + da_property_decl_t extraprops[] = {{0, 0}}; + size_t atlasimglen; + da_status_t status; + + jsonp = fopen(global_deviceatlas.jsonpath, "r"); + if (jsonp == 0) { + ha_alert("deviceatlas : '%s' json file has invalid path or is not readable.\n", + global_deviceatlas.jsonpath); + err_code |= ERR_ALERT | ERR_FATAL; + goto out; + } + + da_init(); + da_seterrorfunc(da_haproxy_log); + status = da_atlas_compile(jsonp, da_haproxy_read, da_haproxy_seek, + &global_deviceatlas.atlasimgptr, &atlasimglen); + fclose(jsonp); + if (status != DA_OK) { + ha_alert("deviceatlas : '%s' json file is invalid.\n", + global_deviceatlas.jsonpath); + err_code |= ERR_ALERT | ERR_FATAL; + goto out; + } + + status = da_atlas_open(&global_deviceatlas.atlas, extraprops, + global_deviceatlas.atlasimgptr, atlasimglen); + + if (status != DA_OK) { + ha_alert("deviceatlas : data could not be compiled.\n"); + err_code |= ERR_ALERT | ERR_FATAL; + goto out; + } + + if (global_deviceatlas.cookiename == 0) { + global_deviceatlas.cookiename = strdup(DA_COOKIENAME_DEFAULT); + global_deviceatlas.cookienamelen = strlen(global_deviceatlas.cookiename); + } + + global_deviceatlas.useragentid = da_atlas_header_evidence_id(&global_deviceatlas.atlas, + "user-agent"); + if ((global_deviceatlas.atlasfd = shm_open(ATLASMAPNM, O_RDWR, 0660)) != -1) { + global_deviceatlas.atlasmap = mmap(NULL, ATLASTOKSZ, PROT_READ | PROT_WRITE, MAP_SHARED, global_deviceatlas.atlasfd, 0); + if (global_deviceatlas.atlasmap == MAP_FAILED) { + close(global_deviceatlas.atlasfd); + global_deviceatlas.atlasfd = -1; + global_deviceatlas.atlasmap = NULL; + } else { + fprintf(stdout, "Deviceatlas : scheduling support enabled.\n"); + } + } + global_deviceatlas.daset = 1; + + fprintf(stdout, "Deviceatlas module loaded.\n"); + } + +out: + return err_code; +} + +static void deinit_deviceatlas(void) +{ + if (global_deviceatlas.jsonpath != 0) { + free(global_deviceatlas.jsonpath); + } + + if (global_deviceatlas.daset == 1) { + free(global_deviceatlas.cookiename); + da_atlas_close(&global_deviceatlas.atlas); + free(global_deviceatlas.atlasimgptr); + } + + if (global_deviceatlas.atlasfd != -1) { + munmap(global_deviceatlas.atlasmap, ATLASTOKSZ); + close(global_deviceatlas.atlasfd); + shm_unlink(ATLASMAPNM); + } + + da_fini(); +} + +static void da_haproxy_checkinst(void) +{ + if (global_deviceatlas.atlasmap != 0) { + char *base; + base = (char *)global_deviceatlas.atlasmap; + + if (base[0] != 0) { + void *cnew; + size_t atlassz; + char atlasp[ATLASTOKSZ] = {0}; + da_atlas_t inst; + da_property_decl_t extraprops[1] = {{NULL, 0}}; +#ifdef USE_THREAD + HA_SPIN_LOCK(OTHER_LOCK, &dadwsch_lock); +#endif + strlcpy2(atlasp, base, sizeof(atlasp)); + if (da_atlas_read_mapped(atlasp, NULL, &cnew, &atlassz) == DA_OK) { + if (da_atlas_open(&inst, extraprops, cnew, atlassz) == DA_OK) { + char jsonbuf[26]; + time_t jsond; + + da_atlas_close(&global_deviceatlas.atlas); + free(global_deviceatlas.atlasimgptr); + global_deviceatlas.atlasimgptr = cnew; + global_deviceatlas.atlas = inst; + memset(base, 0, ATLASTOKSZ); + jsond = da_getdatacreation(&global_deviceatlas.atlas); + ctime_r(&jsond, jsonbuf); + jsonbuf[24] = 0; + printf("deviceatlas: new instance, data file date `%s`.\n", jsonbuf); + } else { + ha_warning("deviceatlas: instance update failed.\n"); + memset(base, 0, ATLASTOKSZ); + free(cnew); + } + } +#ifdef USE_THREAD + HA_SPIN_UNLOCK(OTHER_LOCK, &dadwsch_lock); +#endif + } + } +} + +static int da_haproxy(const struct arg *args, struct sample *smp, da_deviceinfo_t *devinfo) +{ + struct buffer *tmp; + da_propid_t prop, *pprop; + da_status_t status; + da_type_t proptype; + const char *propname; + int i; + + tmp = get_trash_chunk(); + chunk_reset(tmp); + + propname = (const char *) args[0].data.str.area; + i = 0; + + for (; propname != 0; i ++, + propname = (const char *) args[i].data.str.area) { + status = da_atlas_getpropid(&global_deviceatlas.atlas, + propname, &prop); + if (status != DA_OK) { + chunk_appendf(tmp, "%c", global_deviceatlas.separator); + continue; + } + pprop = ∝ + da_atlas_getproptype(&global_deviceatlas.atlas, *pprop, &proptype); + + switch (proptype) { + case DA_TYPE_BOOLEAN: { + bool val; + status = da_getpropboolean(devinfo, *pprop, &val); + if (status == DA_OK) { + chunk_appendf(tmp, "%d", val); + } + break; + } + case DA_TYPE_INTEGER: + case DA_TYPE_NUMBER: { + long val; + status = da_getpropinteger(devinfo, *pprop, &val); + if (status == DA_OK) { + chunk_appendf(tmp, "%ld", val); + } + break; + } + case DA_TYPE_STRING: { + const char *val; + status = da_getpropstring(devinfo, *pprop, &val); + if (status == DA_OK) { + chunk_appendf(tmp, "%s", val); + } + break; + } + default: + break; + } + + chunk_appendf(tmp, "%c", global_deviceatlas.separator); + } + + da_close(devinfo); + + if (tmp->data) { + --tmp->data; + tmp->area[tmp->data] = 0; + } + + smp->data.u.str.area = tmp->area; + smp->data.u.str.data = tmp->data; + smp->data.type = SMP_T_STR; + + return 1; +} + +static int da_haproxy_conv(const struct arg *args, struct sample *smp, void *private) +{ + da_deviceinfo_t devinfo; + da_status_t status; + const char *useragent; + char useragentbuf[1024] = { 0 }; + int i; + + if (global_deviceatlas.daset == 0 || smp->data.u.str.data == 0) { + return 1; + } + + da_haproxy_checkinst(); + + i = smp->data.u.str.data > sizeof(useragentbuf) ? sizeof(useragentbuf) : smp->data.u.str.data; + memcpy(useragentbuf, smp->data.u.str.area, i - 1); + useragentbuf[i - 1] = 0; + + useragent = (const char *)useragentbuf; + + status = da_search(&global_deviceatlas.atlas, &devinfo, + global_deviceatlas.useragentid, useragent, 0); + + return status != DA_OK ? 0 : da_haproxy(args, smp, &devinfo); +} + +#define DA_MAX_HEADERS 24 + +static int da_haproxy_fetch(const struct arg *args, struct sample *smp, const char *kw, void *private) +{ + da_evidence_t ev[DA_MAX_HEADERS]; + da_deviceinfo_t devinfo; + da_status_t status; + struct channel *chn; + struct htx *htx; + struct htx_blk *blk; + char vbuf[DA_MAX_HEADERS][1024] = {{ 0 }}; + int i, nbh = 0; + + if (global_deviceatlas.daset == 0) { + return 0; + } + + da_haproxy_checkinst(); + + chn = (smp->strm ? &smp->strm->req : NULL); + htx = smp_prefetch_htx(smp, chn, NULL, 1); + if (!htx) + return 0; + + i = 0; + for (blk = htx_get_first_blk(htx); nbh < DA_MAX_HEADERS && blk; blk = htx_get_next_blk(htx, blk)) { + size_t vlen; + char *pval; + da_evidence_id_t evid; + enum htx_blk_type type; + struct ist n, v; + char hbuf[24] = { 0 }; + char tval[1024] = { 0 }; + + type = htx_get_blk_type(blk); + + if (type == HTX_BLK_HDR) { + n = htx_get_blk_name(htx, blk); + v = htx_get_blk_value(htx, blk); + } else if (type == HTX_BLK_EOH) { + break; + } else { + continue; + } + + /* The HTTP headers used by the DeviceAtlas API are not longer */ + if (n.len >= sizeof(hbuf)) { + continue; + } + + memcpy(hbuf, n.ptr, n.len); + hbuf[n.len] = 0; + pval = v.ptr; + vlen = v.len; + evid = -1; + i = v.len > sizeof(tval) - 1 ? sizeof(tval) - 1 : v.len; + memcpy(tval, v.ptr, i); + tval[i] = 0; + pval = tval; + + if (strcasecmp(hbuf, "Accept-Language") == 0) { + evid = da_atlas_accept_language_evidence_id(&global_deviceatlas.atlas); + } else if (strcasecmp(hbuf, "Cookie") == 0) { + char *p, *eval; + size_t pl; + + eval = pval + vlen; + /** + * The cookie value, if it exists, is located between the current header's + * value position and the next one + */ + if (http_extract_cookie_value(pval, eval, global_deviceatlas.cookiename, + global_deviceatlas.cookienamelen, 1, &p, &pl) == NULL) { + continue; + } + + vlen -= global_deviceatlas.cookienamelen - 1; + pval = p; + evid = da_atlas_clientprop_evidence_id(&global_deviceatlas.atlas); + } else { + evid = da_atlas_header_evidence_id(&global_deviceatlas.atlas, hbuf); + } + + if (evid == -1) { + continue; + } + + i = vlen > sizeof(vbuf[nbh]) - 1 ? sizeof(vbuf[nbh]) - 1 : vlen; + memcpy(vbuf[nbh], pval, i); + vbuf[nbh][i] = 0; + ev[nbh].key = evid; + ev[nbh].value = vbuf[nbh]; + ++ nbh; + } + + status = da_searchv(&global_deviceatlas.atlas, &devinfo, + ev, nbh); + + return status != DA_OK ? 0 : da_haproxy(args, smp, &devinfo); +} + +static struct cfg_kw_list dacfg_kws = {{ }, { + { CFG_GLOBAL, "deviceatlas-json-file", da_json_file }, + { CFG_GLOBAL, "deviceatlas-log-level", da_log_level }, + { CFG_GLOBAL, "deviceatlas-property-separator", da_property_separator }, + { CFG_GLOBAL, "deviceatlas-properties-cookie", da_properties_cookie }, + { 0, NULL, NULL }, +}}; + +INITCALL1(STG_REGISTER, cfg_register_keywords, &dacfg_kws); + +/* Note: must not be declared as its list will be overwritten */ +static struct sample_fetch_kw_list fetch_kws = {ILH, { + { "da-csv-fetch", da_haproxy_fetch, ARG12(1,STR,STR,STR,STR,STR,STR,STR,STR,STR,STR,STR,STR), NULL, SMP_T_STR, SMP_USE_HRQHV }, + { NULL, NULL, 0, 0, 0 }, +}}; + +INITCALL1(STG_REGISTER, sample_register_fetches, &fetch_kws); + +/* Note: must not be declared as its list will be overwritten */ +static struct sample_conv_kw_list conv_kws = {ILH, { + { "da-csv-conv", da_haproxy_conv, ARG12(1,STR,STR,STR,STR,STR,STR,STR,STR,STR,STR,STR,STR), NULL, SMP_T_STR, SMP_T_STR }, + { NULL, NULL, 0, 0, 0 }, +}}; + +static void da_haproxy_register_build_options() +{ + char *ptr = NULL; + +#ifdef MOBI_DA_DUMMY_LIBRARY + memprintf(&ptr, "Built with DeviceAtlas support (dummy library only)."); +#else + memprintf(&ptr, "Built with DeviceAtlas support (library version %u.%u).", MOBI_DA_MAJOR, MOBI_DA_MINOR); +#endif + hap_register_build_opts(ptr, 1); +} + +INITCALL1(STG_REGISTER, sample_register_convs, &conv_kws); + +REGISTER_POST_CHECK(init_deviceatlas); +REGISTER_POST_DEINIT(deinit_deviceatlas); +INITCALL0(STG_REGISTER, da_haproxy_register_build_options); diff --git a/addons/deviceatlas/dadwsch.c b/addons/deviceatlas/dadwsch.c new file mode 100644 index 0000000..e35566a --- /dev/null +++ b/addons/deviceatlas/dadwsch.c @@ -0,0 +1,195 @@ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ATLASTOKSZ PATH_MAX +#define ATLASMAPNM "/hapdeviceatlas" + +const char *__pgname; + +static struct { + da_dwatlas_t o; + int ofd; + void* atlasmap; +} global_deviceatlassch = { + .ofd = -1, + .atlasmap = NULL +}; + + +void usage(void) +{ + fprintf(stderr, "%s -u download URL [-d hour (in H:M:S format) current hour by default] [-p path for the downloaded file, /tmp by default]\n", __pgname); + exit(EXIT_FAILURE); +} + +static size_t jsonread(void *ctx, size_t count, char *buf) +{ + return fread(buf, 1, count, ctx); +} + +static da_status_t jsonseek(void *ctx, off_t pos) +{ + return fseek(ctx, pos, SEEK_SET) != -1 ? DA_OK : DA_SYS; +} + +static void dadwlog(dw_config_t cfg, const char* msg) +{ + time_t now = time(NULL); + char buf[26] = {0}; + ctime_r(&now, buf); + buf[24] = 0; + fprintf(stderr, "%s: %s\n", buf, msg); +} + +static dw_status_t dadwnot(void *a, dw_config_t *cfg) +{ + da_dwatlas_t *o = (da_dwatlas_t *)a; + if (!o) + return DW_ERR; + char *e; + char jsondbuf[26] = {0}, buf[26] = {0}, atlasp[ATLASTOKSZ] = {0}; + time_t now = time(NULL); + time_t jsond; + int fd = -1; + (void)a; + jsond = da_getdatacreation(&o->atlas); + dwgetfinalp(o->dcfg.info, atlasp, sizeof(atlasp)); + ctime_r(&jsond, jsondbuf); + ctime_r(&now, buf); + jsondbuf[24] = 0; + buf[24] = 0; + + printf("%s: data file generated on `%s`\n", buf, jsondbuf); + int val = 1; + unsigned char *ptr = (unsigned char *)global_deviceatlassch.atlasmap; + memset(ptr, 0, sizeof(atlasp)); + strcpy(ptr, atlasp); + return DW_OK; +} + +static da_status_t dadwinit(void) +{ + if ((global_deviceatlassch.ofd = shm_open(ATLASMAPNM, O_RDWR | O_CREAT, 0660)) == -1) { + fprintf(stderr, "%s\n", strerror(errno)); + return DA_SYS; + } + + if (ftruncate(global_deviceatlassch.ofd, ATLASTOKSZ) == -1) { + close(global_deviceatlassch.ofd); + return DA_SYS; + } + lseek(global_deviceatlassch.ofd, 0, SEEK_SET); + global_deviceatlassch.atlasmap = mmap(0, ATLASTOKSZ, PROT_READ | PROT_WRITE, MAP_SHARED, global_deviceatlassch.ofd, 0); + if (global_deviceatlassch.atlasmap == MAP_FAILED) { + fprintf(stderr, "%s\n", strerror(errno)); + return DA_SYS; + } else { + memset(global_deviceatlassch.atlasmap, 0, ATLASTOKSZ); + return DA_OK; + } +} + +static void dadwexit(int sig __attribute__((unused)), siginfo_t *s __attribute__((unused)), void *ctx __attribute__((unused))) +{ + ssize_t w; + + fprintf(stderr, "%s: exit\n", __pgname); + dw_daatlas_close(&global_deviceatlassch.o); + da_fini(); + munmap(global_deviceatlassch.atlasmap, ATLASTOKSZ); + close(global_deviceatlassch.ofd); + shm_unlink(ATLASMAPNM); + exit(EXIT_SUCCESS); +} + +int main(int argc, char **argv) +{ + const char *opts = "u:p:d:h"; + bool dset = false; + size_t i; + int ch; + + da_property_decl_t extraprops[1] = { + { 0, 0 } + }; + + __pgname = argv[0]; + + dw_df_dainit_fn = curldwinit; + dw_df_dacleanup_fn = curldwcleanup; + + da_init(); + memset(&global_deviceatlassch.o.dcfg, 0, sizeof(global_deviceatlassch.o.dcfg)); + while ((ch = getopt(argc, argv, opts)) != -1) { + switch (ch) { + case 'u': + global_deviceatlassch.o.dcfg.info.url = strdup(optarg); + break; + case 'p': + global_deviceatlassch.o.dcfg.info.path = strdup(optarg); + break; + case 'd': + if (strptime(optarg, "%H:%M:%S", &global_deviceatlassch.o.dcfg.info.rtm) != NULL) + dset = true; + else + usage(); + break; + case 'h': + default: + usage(); + } + } + + if (!dset) { + time_t now = time(NULL); + struct tm *cnow = gmtime(&now); + memcpy(&global_deviceatlassch.o.dcfg.info.rtm, cnow, offsetof(struct tm, tm_mday)); + } + + if (!global_deviceatlassch.o.dcfg.info.url) + usage(); + + struct sigaction sa; + memset(&sa, 0, sizeof(sa)); + sa.sa_flags = SA_SIGINFO | SA_RESTART; + sa.sa_sigaction = dadwexit; + + global_deviceatlassch.o.dcfg.info.datatm = 1; + global_deviceatlassch.o.dcfg.info.chksum = 1; + global_deviceatlassch.o.dcfg.info.reload = 1; + global_deviceatlassch.o.dcfg.info.tobin = 1; + global_deviceatlassch.o.dcfg.ep = extraprops; + global_deviceatlassch.o.dcfg.dwproc = curldwproc; + global_deviceatlassch.o.dcfg.dwextract = dadwextract; + global_deviceatlassch.o.dcfg.lptr = (void *)stderr; + global_deviceatlassch.o.dcfg.dwlog = &dadwlog; + global_deviceatlassch.o.dcfg.dwnotify_n = &dadwnot; + global_deviceatlassch.o.rfn = jsonread; + global_deviceatlassch.o.posfn = jsonseek; + + if (dadwinit() != DA_OK) { + fprintf(stderr, "%s init failed\n", __pgname); + exit(EXIT_FAILURE); + } + + if (da_atlas_open_schedule(&global_deviceatlassch.o) != DA_OK) { + fprintf(stderr, "%s scheduling failed\n", __pgname); + exit(EXIT_FAILURE); + } + + sigaction(SIGINT, &sa, NULL); + sigaction(SIGQUIT, &sa, NULL); + sigaction(SIGTERM, &sa, NULL); + + while (true) sleep(1); + + return 0; +} diff --git a/addons/deviceatlas/dummy/Makefile b/addons/deviceatlas/dummy/Makefile new file mode 100644 index 0000000..8bba840 --- /dev/null +++ b/addons/deviceatlas/dummy/Makefile @@ -0,0 +1,12 @@ +# makefile for dummy DeviceAtlas library +# +# To enable the DeviceAtlas module support, the following are needed +# make TARGET= DEVICEATLAS_SRC=addons/deviceatlas/dummy USE_PCRE=1 USE_DEVICEATLAS=1 + +build: libda.a + +libda.a: dac.o + ar rv $@ $< + +clean: + rm -rf *.a *.o diff --git a/addons/deviceatlas/dummy/Os/daunix.c b/addons/deviceatlas/dummy/Os/daunix.c new file mode 100644 index 0000000..ca696f9 --- /dev/null +++ b/addons/deviceatlas/dummy/Os/daunix.c @@ -0,0 +1,9 @@ +#include "dac.h" + +static char const __attribute__((unused)) rcsid[] = "$Id: dac.c, v dummy 1970/01/01 00:00:01 dcarlier Exp $"; + +da_status_t +da_atlas_read_mapped(const char *path, void *m, void **p, size_t *l) +{ + return DA_SYS; +} diff --git a/addons/deviceatlas/dummy/dac.c b/addons/deviceatlas/dummy/dac.c new file mode 100644 index 0000000..720dc6a --- /dev/null +++ b/addons/deviceatlas/dummy/dac.c @@ -0,0 +1,222 @@ +#include "dac.h" +#include +#include +#include + +static char const __attribute__((unused)) rcsid[] = "$Id: dac.c, v dummy 1970/01/01 00:00:01 dcarlier Exp $"; + +struct da_bitset { + unsigned long bits[8]; + size_t bit_count; +}; + +/* + * Constructor/Destructor for possible globals. + */ + +void +da_init() +{ +} + +void +da_fini() +{ +} + + +void +da_seterrorfunc(da_errorfunc_t callback) +{ +} + +const char * +da_typename(da_type_t fieldtype) +{ + return "none"; +} + +char * +da_getdataversion(da_atlas_t *atlas) +{ + return "dummy library version 1.0"; +} + +time_t +da_getdatacreation(da_atlas_t *atlas) +{ + return time(NULL); +} + +int +da_getdatarevision(da_atlas_t *atlas) +{ + return 1; +} + +da_status_t +da_atlas_compile(void *ctx, da_read_fn readfn, da_setpos_fn rewind, void **ptr, size_t *size) +{ + return DA_OK; +} + +da_status_t +da_atlas_open(da_atlas_t *atlas, da_property_decl_t *extraprops, const void *ptr, size_t len) +{ + void *ptr2 = malloc(len); + free(ptr2); + return ptr2 ? DA_OK : DA_NOMEM; +} + +void +da_atlas_close(da_atlas_t *atlas) +{ +} + +da_evidence_id_t +da_atlas_clientprop_evidence_id(const da_atlas_t *atlas) +{ + return (da_evidence_id_t)2; +} + +da_evidence_id_t +da_atlas_accept_language_evidence_id(const da_atlas_t *atlas) +{ + return (da_evidence_id_t)3; +} + +da_evidence_id_t +da_atlas_header_evidence_id(const da_atlas_t *atlas, const char *evidence_name) +{ + return (da_evidence_id_t)1; +} + +da_status_t +da_atlas_getproptype(const da_atlas_t *atlas, da_propid_t propid, da_type_t *type) +{ + *type = DA_TYPE_BOOLEAN; + return DA_OK; +} + +da_status_t +da_atlas_getpropname(const da_atlas_t *atlas, da_propid_t propid, const char **name) +{ + *name = "isRobot"; + return DA_OK; +} + +da_status_t +da_atlas_getpropid(const da_atlas_t *atlas, const char *propname, da_propid_t *property) +{ + *property = (da_propid_t)1; + return DA_OK; +} + +size_t +da_atlas_getpropcount(const da_atlas_t *atlas) +{ + return 1; +} + +void +da_atlas_setconfig(da_atlas_t *atlas, da_config_t *config) +{ +} + +da_status_t +da_searchv(const da_atlas_t *atlas, da_deviceinfo_t *result, da_evidence_t *evidence, size_t count) +{ + memset(result, 0, sizeof(*result)); + result->propcount = count; + return DA_OK; +} + +da_status_t +da_search(const da_atlas_t *atlas, da_deviceinfo_t *result, ...) +{ + da_evidence_t vec[4]; /* XXX: this will have to grow if more evidence is supported. */ + size_t i; + va_list args; + va_start(args, result); + for (i = 0; i < sizeof vec / sizeof vec[0];) { + vec[i].key = va_arg(args, da_evidence_id_t); + if (vec[i].key == 0) + break; + vec[i++].value = va_arg(args, char *); + } + va_end(args); + return da_searchv(atlas, result, vec, i); +} + +/* + * Search-result centric functions. + */ +size_t +da_getpropcount(const da_deviceinfo_t *info) +{ + return info->propcount; +} + +da_status_t +da_getfirstprop(const da_deviceinfo_t *info, da_propid_t **propid) +{ + if (info->propcount == 0) + return DA_NOMORE; + *propid = &info->proplist[0]; + return DA_OK; +} + +da_status_t +da_getnextprop(const da_deviceinfo_t *info, da_propid_t **propid) +{ + if (*propid - info->proplist >= info->propcount - 1) + return DA_NOMORE; + ++*propid; + return DA_OK; +} + +void +da_close(da_deviceinfo_t *sr) +{ +} + +da_status_t +da_getpropname(const da_deviceinfo_t *info, da_propid_t propid, const char **name) +{ + *name = "isRobot"; + return DA_OK; +} + +da_status_t +da_getproptype(const da_deviceinfo_t *info, da_propid_t propid, da_type_t *type) +{ + *type = DA_TYPE_BOOLEAN; + return DA_OK; +} + +da_status_t +da_getpropinteger(const da_deviceinfo_t *info, da_propid_t property, long *vp) +{ + *vp = -1; + return DA_OK; +} + +da_status_t +da_getpropstring(const da_deviceinfo_t *info, da_propid_t property, const char **vp) +{ + *vp = NULL; + return DA_OK; +} + +da_status_t +da_getpropboolean(const da_deviceinfo_t *info, da_propid_t property, bool *vp) +{ + *vp = true; + return DA_OK; +} + +const char * +da_get_property_name(const da_atlas_t *atlas, da_propid_t property) +{ + return "isRobot"; +} diff --git a/addons/deviceatlas/dummy/dac.h b/addons/deviceatlas/dummy/dac.h new file mode 100644 index 0000000..bf166ae --- /dev/null +++ b/addons/deviceatlas/dummy/dac.h @@ -0,0 +1,600 @@ +#ifndef MOBI_DA_DAC_H +#define MOBI_DA_DAC_H + +/** + * @file dac.h + * @author Afilias Technologies + * + * @brief API main header file + */ + +#include +#include +#include +#include +#include + +#ifndef __cplusplus +#ifndef true +#ifdef HAVE_NO_BUILTIN__BOOL +typedef int _Bool; +#endif +#define bool _Bool + +#define true 1 +#define false 0 +#endif +#endif + +#define MOBI_DA_MAJOR 2 +#define MOBI_DA_MINOR 1 +#define MOBI_DA_DUMMY_LIBRARY 1 + + +/** + * @brief All values returned by the API have one of these types. + * da_getprop*() return data in the appropriate C type for the given da_type. + */ +enum da_type { + DA_TYPE_NONE, + DA_TYPE_BOOLEAN, + DA_TYPE_INTEGER, + DA_TYPE_NUMBER, + DA_TYPE_STRING, + DA_TYPE_ARRAY, + DA_TYPE_OBJECT, + DA_TYPE_NULL +}; + +/** + * Any method that returns a da_status may potentially fail for one of these reasons. + * XXX: Error reporting needs to be improved. + */ +enum da_status { + DA_OK, /* Success. */ + DA_INVALID_JSON, /* The JSON format is invalid, or the content is unexpected in a given context. */ + DA_OVERFLOW, /* Overflow occurred. Note this is used to indicate an unfinished string parse in JSON */ + DA_FORMAT_ERROR, /* The data supplied is formatted incorrectly. */ + DA_NOMEM, /* There was not enough space to complete the operation */ + DA_SYS, /* A system error occurred - consult the OS for more details (eg, check errno) */ + DA_NOTIMPL, /* This method is not implemented */ + DA_NOTFOUND, /* The requested item was not found. */ + DA_REGEXBAD, /* An invalid regex was provided. */ + DA_NOMORE, /* Used to indicate the end of an iterator. */ + DA_INVALID_COOKIE, /* Cookie value supplied was invalid */ + DA_INVALID_TYPE, /* A value of an unexpected type was found. */ + DA_INTERNAL_ERROR, + DA_STATUS_LAST /* Placeholder to indicate highest possible error value. (value will change as API matures) */ +}; + +enum da_severity { + DA_SEV_FATAL, /* The operation will not continue, and the operation will return an error. */ + DA_SEV_ERROR, /* An error occurred, but the API call will return at least some valid information */ + DA_SEV_WARN, /* An unexpected event occurred, but the system dealt with it */ + DA_SEV_INFO /* An informational message. */ +}; +/* Forward references to tagged types */ +struct atlas_image; +struct da_atlas; +struct da_deviceinfo; +struct da_jsonparser; +struct da_node; +struct da_propset; +union da_value; +struct da_evidence; +struct da_bitset; +struct da_allocator; +struct da_config; + +/** + * @brief Primary types of the interface. + * Primary types used by API client. + * Non-typedef structures and unions are considered private to the API. + * + */ +typedef enum da_severity da_severity_t; /* A severity for the error callback. */ +typedef enum da_status da_status_t; /* An error code - returned from most API calls. */ +typedef da_status_t (*da_setpos_fn)(void *ctx, off_t off); /* callback provided to API to rewind input stream */ +typedef enum da_type da_type_t; /* A value type (integer, string, etc) */ + +/** + * @brief An operation on an atlas involves converting a set of evidence strings into a set of property/value pairs. + * The ID for a particular type of evidence is extract from the atlas (eg, for a specific HTTP header, use: + * + * da_evidence_id_t evidence = da_atlas_header_evidence_id(atlas, "User-Agent"); + * + */ +typedef int da_evidence_id_t; + +/** + * @brief The search result encompasses a key/value set. Keys are handles retrieved via + * _either_ da_atlas_getpropid() or da_getpropid(). + * Some search results may have keys not available when the atlas is opened (eg, + * when the name of the property itself is contained within the evidence) + * Such properties by necessity are given a "local" da_propid_t + * + * You can ensure any properties you are interested in get a global propid by + * passing a list of interesting named properties to da_atlas_open() + */ +typedef int da_propid_t; +typedef size_t (*da_read_fn)(void *ctx, size_t maxlen, char *ptr); +typedef struct da_atlas da_atlas_t; +typedef struct da_deviceinfo da_deviceinfo_t; +typedef struct da_evidence da_evidence_t; +typedef struct da_jsonparser da_jsonparser_t; +typedef struct da_node da_node_t; +typedef struct da_property_decl da_property_decl_t; +typedef struct da_propset da_propset_t; +typedef struct da_config da_config_t; +typedef void *(*da_alloc_fn)(void *ctx, size_t); +typedef void (*da_free_fn)(void *ctx, void *); +typedef void *(*da_realloc_fn)(void *ctx, void *, size_t); +typedef void (*da_errorfunc_t)(da_severity_t severity, da_status_t status, const char *msg, va_list args); + + +/* Manifest constants. */ +enum { + /* + * used as the initial guess for the compiled size of an atlas. + * If atlas sizes grow more beyond this, it can be expanded to avoid multiple scans of the data. + */ + DA_INITIAL_MEMORY_ESTIMATE = 1024 * 1024 * 14 +}; + +struct da_config { + unsigned int ua_props; + unsigned int lang_props; + unsigned int __reserved[14]; /* enough reserved keywords for future use */ +}; + +/** + * Functional interface. + */ + +/** + * @brief Initialize process to use the DA API. + */ +void da_init(void); + + +/** + * @brief Release all resources used by the API + */ +void da_fini(void); + +/** + * @brief User-supplied callback to be invoked with information about an error. + * Note this may use thread-local storage etc to store the info on return from the current call + * It is guaranteed that an error-reporting function returning an error-code will have called + * this function at least once. + * @param callback function + */ +void da_seterrorfunc(da_errorfunc_t callback); + +/** + * @brief Given a specific HTTP header, return the associated ID for that header. + * When passing evidence to the API, its type is identified using its da_evidince_id_t. + * @param atlas atlas instance + * @param header_name Header's name + * @return evidence id + */ +da_evidence_id_t da_atlas_header_evidence_id(const da_atlas_t *atlas, const char *header_name); +/** + * @brief Return the associated ID of the client side properties evidence + * @param atlas Atlas instance + * @return evidence id + */ +da_evidence_id_t da_atlas_clientprop_evidence_id(const da_atlas_t *atlas); +/** + * @brief Return the associated ID of the accept language header evidence + * @param atlas Atlas instance + * @return evidence id + */ +da_evidence_id_t da_atlas_accept_language_evidence_id(const da_atlas_t *atlas); + +/** + * @brief readfn should present JSON content from ctx. + * atlasp points to an uninitialized da_atlas structure. + * Result is a compiled atlas at atlasp. + * Result is allocated via normal memory-allocation methods, malloc/calloc/realloc, so should be + * Free'd with free() + * XXX TODO: Change this to take a da_allocator + * @param ctx pointer given to read the json file + * @param readfn function pointer, set accordingly to the attended given pointer + * @param setposfn function pointer + * @param ptr Pointer dynamically allocated if the json parsing happened normally + * @param len size of the atlas image + * @return status of atlas compilation + */ +da_status_t da_atlas_compile(void *ctx, da_read_fn readfn, da_setpos_fn setposfn, void **ptr, size_t *len); + +/** + * @brief opens a previously compiled atlas for operations. extra_props will be available in calls to + * da_getpropid on the atlas, and if generated by the search, the ID will be consistent across + * different calls to search. + * Properties added by a search that are neither in the compiled atlas, nor in the extra_props list + * Are assigned an ID within the context that is not transferrable through different search results + * within the same atlas. + * @param atlas Atlas instance + * @param extra_props properties + * @param ptr given pointer from previously compiled atlas + * @param pos atlas image size + * @return status of atlas data opening + */ +da_status_t da_atlas_open(da_atlas_t *atlas, da_property_decl_t *extra_props, const void *ptr, size_t pos); + +/** + * @brief read from a mapped data which then replace da_atlas_compile call + * + * @param dumppath, anonymous if NULL + * @param map for anonymous, it is the responsibility of the caller to unmap it, ignored otherwise + * @param maplen for anonymous, it is the size of the mapped data, ignored otherwise + * @param ptr Pointer dynamically allocated if the mapping happened normally + * @param len size of the atlas image + * @return status of mapping + */ +da_status_t da_atlas_read_mapped(const char *path, void *m, void **p, size_t *l); +/** + * @brief Release any resources associated with the atlas structure atlas, which was previously generated from + * da_read_atlas or da_compile_atlas. + * @param atlas instance + */ +void da_atlas_close(da_atlas_t *atlas); + +/** + * @brief Find device properties given a set of evidence. + * Search results are returned in da_deviceinfo_t, and must be cleaned using da_close + * "Evidence" is an array of length count, of string data tagged with an evidence ID. + * @param atlas Atlas instance + * @param info Device info + * @param ev Array of evidences + * @param count Number of evidence given + * @return status of the search + */ +da_status_t da_searchv(const da_atlas_t *atlas, da_deviceinfo_t *info, da_evidence_t *ev, size_t count); + +/** + * @brief As da_search, but unrolls the evidence array into variable arguments for simpler calling + * convention with known evidence types. + * varargs are pairs of (da_evidence_id, string), terminated with da_evidence_id DA_END + * @code da_search(&myAtlas, &deviceInfo, da_get_header_evidence_id("User-Agent"), + * "Mozilla/5.0 (Linux...", DA_END); + * @endcode + * @param atlas Atlas instance + * @param info given device info which holds on device properties + * @param pairs of evidence id / evidence value + * @return status of the search + */ +da_status_t da_search(const da_atlas_t *atlas, da_deviceinfo_t *info, ...); + +/** + * @brief After finishing with a search result, release resources associated with it. + * @param info Device info previously allocated by search functions + */ +void da_close(da_deviceinfo_t *info); + +/** + * @brief Given a property name (Eg, "displayWidth"), return the property ID associated with it for the + * specified atlas. + * @param atlas Atlas instance + * @param propname Property name + * @param propid Property id + * @return status of the property id search + */ +da_status_t da_atlas_getpropid(const da_atlas_t *atlas, const char *propname, da_propid_t *propid); + +/** + * @brief Given a property ID, return the type of that property. + * @code + * da_getproptype(&myAtlas, da_getpropid(&myAtlas, "displayWidth"), &propertyType); + * assert(propertyType == DA_TYPE_INT); + * @endcode + * @param atlas Atlas instance + * @param propid Property id + * @param type Type id of the property + * @return status of the type id search + */ +da_status_t da_atlas_getproptype(const da_atlas_t *atlas, da_propid_t propid, da_type_t *type); + +/** + * @brief Given a property ID, return the name of that property. + * @code + * da_atlas_getpropname(&myAtlas, da_getpropid(&myAtlas, "displayWidth"), &propertyName); + * assert(strcmp("displayWidth", propertyName) == 0); + * @endcode + * @param atlas Atlas instance + * @param propid property id + * @param propname property name returned + * @return status of the property name search + */ +da_status_t da_atlas_getpropname(const da_atlas_t *atlas, da_propid_t propid, const char **propname); + + +/** + * @brief Given an atlas instance, return its counters + the builtins + * @code + * da_atlas_getpropcount(&myAtlas); + * @endcode + * @param atlas Atlas instance + * @return counters + */ +size_t da_atlas_getpropcount(const da_atlas_t *atlas); + +/** + * @brief Given an atlas instance, set the detection config + * @param atlas Atlas instance + * @param config instance + */ +void da_atlas_setconfig(da_atlas_t *atlas, da_config_t *config); + +/** + * @brief Given a search result, find the value of a specific property. + * @code + * long displayWidth; // width of display in pixels. + * da_getpropinteger(&deviceInfo, da_getpropid(&myAtlas, "displayWidth"), &displayWidth); + * @endcode + * String contents are owned by the search result, and are valid until the search is closed. + */ +/** + * @brief returns a property value as a string from a given string typed property id + * @param info Device info + * @param propid Property id + * @param value Value of the property + * @return status of property value search + */ +da_status_t da_getpropstring(const da_deviceinfo_t *info, da_propid_t propid, const char **value); +/** + * @brief returns a property value as a long from a given long typed property id + * @param info Device info + * @param propid Property id + * @param value Value of the property + * @return status of property value search + */ +da_status_t da_getpropinteger(const da_deviceinfo_t *info, da_propid_t propid, long *value); +/** + * @brief returns a property value as a boolean from a given boolean typed property id + * @param info Device info + * @param propid Property id + * @param value Value of the property + * @return status of property value search + */ +da_status_t da_getpropboolean(const da_deviceinfo_t *info, da_propid_t propid, bool *value); +/** + * @brief returns a property value as a float from a given float typed property id + * @param info Device info + * @param propid Property id + * @param value Value of the property + * @return status of property value search + */ +da_status_t da_getpropfloat(const da_deviceinfo_t *info, da_propid_t propid, double *value); + +/** + * @brief Some properties may not be not known to the atlas before the search commences. + * Such properties cannot have a da_propid_t assigned to them on the atlas, but will + * have a local property assigned during search. The name and type of such properties + * can be discovered here. + * + * Properties that are used in the atlas source and properties specifically registered + * with da_atlas_open() will always be assigned to a property discovered during search. + * Therefore, if there are specific properties that you want to use, and are unsure + * if they are in your device atlas source, registering them with da_atlas_open will + * make access to them easier and more efficient + */ +/** + * @brief returns the type of a given device property from the search functions + * @param info Device info + * @param propid Property id + * @param type Type id + * @return status of property type search + */ +da_status_t da_getproptype(const da_deviceinfo_t *info, da_propid_t propid, da_type_t *type); +/** + * @brief returns the name of a given device property from the search functions + * @param info Device info + * @param propid Property id + * @param propname Property name + * @return status of property type search + */ +da_status_t da_getpropname(const da_deviceinfo_t *info, da_propid_t propid, const char **propname); + +/** + * @brief da_getfirstprop/da_getnextprop provide iteration over all properties + * in a search result. + * Both will return DA_OK if there is a result available, and DA_NOMORE + * if the search is complete. + * @code + * + * da_propid_t *propidp; + * for (da_status_t status = da_getfirstprop(&result, &propidp); + * status == DA_OK; + * status = da_getnextprop(&result, &propidp)) { + * const char *propname; + * if (da_getpropname(&result, *propidp, &propname) == DA_OK) + * fprintf("found property %s\n", propname); + * } + * @endcode + */ + +/** + * @brief returns the first property from device info + * @param info Device info + * @param propid Property + * @return status + */ +da_status_t da_getfirstprop(const da_deviceinfo_t *info, da_propid_t **propid); +/** + * @brief device info properties iterator + * @param info Device info + * @param propid Property + * @return status + */ +da_status_t da_getnextprop(const da_deviceinfo_t *info, da_propid_t **propid); + +/** + * @brief Report an error, as per a report from the API to the user-callback. + * @param severity Severity level of the error + * @param fmt format error message + * @param va_list + * @return status + */ +da_status_t da_reporterror(da_status_t severity, const char *fmt, ...); + +/** + * @brief returns a textual description of the type "type". + * @param type Type id + * @return type name + */ +const char *da_typename(da_type_t type); + +/** + * @brief returns the version from the JSON in memory + * @param atlas + * @return version + */ +char *da_getdataversion(da_atlas_t *atlas); + +/** + * @brief returns the date creation's timestamp from the JSON in memory + * @param atlas + * @return version + */ +time_t da_getdatacreation(da_atlas_t *atlas); + +/** + * @brief returns the revision's number from the JSON in memory + * @param atlas + * @return version + */ +int da_getdatarevision(da_atlas_t *atlas); + +/** + * @brief returns the name of a global property + * @param atlas Atlas instance + * @param propid Property id + * @return property name + */ +const char *da_get_property_name(const da_atlas_t *atlas, da_propid_t propid); + +/** + * @brief returns the number of properties in a result. + * @param info Device info + * @return properties count + */ +size_t da_getpropcount(const da_deviceinfo_t *info); + +/* + * Details below should not be required for usage of the API + */ + +/** + * @brief Represents a usable device atlas interface. + * + * No user servicable parts inside: access should + * be via the functional API. + */ +struct da_atlas { + const struct atlas_image *image; + struct header_evidence_entry *header_priorities; + size_t header_evidence_count; + + struct pcre_regex_info *uar_regexes; + size_t uar_regex_count; + + struct pcre_regex_info *replacement_regexes; + size_t replacement_regex_count; + + da_evidence_id_t user_agent_evidence; + da_evidence_id_t clientprops_evidence; + da_evidence_id_t accept_language_evidence; + da_evidence_id_t next_evidence; + + da_propset_t *properties; + da_propid_t id_propid; + da_propid_t id_proplang; + da_propid_t id_proplang_locale; + + da_config_t config; + + da_deviceinfo_t **cpr_props; + size_t cpr_count; +}; + +/* fixed constants. */ +enum { + DA_BUFSIZE = 16000 +}; + +/** + * Represents a chunk of memory. See comments on da_deviceinfo. + * This is presented here to allow aggregation in da_deviceinfo: + * Not for public consumption. + */ +struct da_buf { + struct da_buf *next; + char *cur; + char *limit; + char buf[DA_BUFSIZE]; +}; + +/** + * A callback interface for allocating memory from some source + * Not for public consumption. + */ +struct da_allocator { + da_alloc_fn alloc; + da_free_fn free; + da_realloc_fn realloc; + void *context; +}; + + +/** + * Represents a search result + * Can be used to retrieve values of known properties discovered from the evidence, + * iterate over the properties with known values, and query property types that are + * local to this result. + * + * The atlas the search is carried out on must survive any da_deviceinfo results + * it provides. + */ +struct da_deviceinfo { + struct da_allocator allocator; + const da_atlas_t *atlas; /* reference to the atlas the search was carried out on. */ + struct da_bitset *present; /* property received from tree */ + struct da_bitset *localprop; /* property was received from UAR rule or CPR */ + struct da_bitset *cprprop; /* property was received from CPR */ + union da_value *properties; /* properties - indexed by property id. */ + da_propid_t *proplist; /* list of properties present in this result. */ + size_t propcount; /* size of proplist */ + da_propset_t *local_types; /* property descriptors local to this search result. */ + + /** + * The per-deviceinfo heap is stored here. Allocations for data in the result + * come from the raw data in these buffers. The size of the fixed-size buffer + * built in to da_buf is sized such that all known search results will not + * require memory allocation via malloc() + */ + struct da_buf *heap; + struct da_buf initial_heap; +}; + +/** + * Used to pass evidence to da_searchv() + */ +struct da_evidence { + da_evidence_id_t key; + char *value; +}; + +/** + * Used to pass properties the API intends to query to the da_atlas_open function + * This can be used to improve performance of lookup on properties well-known + * to the API user, but not present in the JSON database. + */ +struct da_property_decl { + const char *name; + da_type_t type; +}; + + +#endif /* DEVATLAS_DAC_H */ diff --git a/addons/deviceatlas/dummy/dadwcom.c b/addons/deviceatlas/dummy/dadwcom.c new file mode 100644 index 0000000..53c5fdf --- /dev/null +++ b/addons/deviceatlas/dummy/dadwcom.c @@ -0,0 +1 @@ +#include diff --git a/addons/deviceatlas/dummy/dasch.c b/addons/deviceatlas/dummy/dasch.c new file mode 100644 index 0000000..53c5fdf --- /dev/null +++ b/addons/deviceatlas/dummy/dasch.c @@ -0,0 +1 @@ +#include diff --git a/addons/deviceatlas/dummy/json.c b/addons/deviceatlas/dummy/json.c new file mode 100644 index 0000000..53c5fdf --- /dev/null +++ b/addons/deviceatlas/dummy/json.c @@ -0,0 +1 @@ +#include diff --git a/addons/ot/AUTHORS b/addons/ot/AUTHORS new file mode 100644 index 0000000..92b2831 --- /dev/null +++ b/addons/ot/AUTHORS @@ -0,0 +1 @@ +Miroslav Zagorac diff --git a/addons/ot/MAINTAINERS b/addons/ot/MAINTAINERS new file mode 100644 index 0000000..92b2831 --- /dev/null +++ b/addons/ot/MAINTAINERS @@ -0,0 +1 @@ +Miroslav Zagorac diff --git a/addons/ot/Makefile b/addons/ot/Makefile new file mode 100644 index 0000000..2ee74d3 --- /dev/null +++ b/addons/ot/Makefile @@ -0,0 +1,75 @@ +# USE_OT : enable the OpenTracing filter +# OT_DEBUG : compile the OpenTracing filter in debug mode +# OT_INC : force the include path to libopentracing-c-wrapper +# OT_LIB : force the lib path to libopentracing-c-wrapper +# OT_RUNPATH : add libopentracing-c-wrapper RUNPATH to haproxy executable +# OT_USE_VARS : allows the use of variables for the OpenTracing context + +OT_DEFINE = +OT_CFLAGS = +OT_LDFLAGS = +OT_DEBUG_EXT = +OT_PKGSTAT = +OTC_WRAPPER = opentracing-c-wrapper + +ifneq ($(OT_DEBUG),) +OT_DEBUG_EXT = _dbg +OT_DEFINE = -DDEBUG_OT +endif + +ifeq ($(OT_INC),) +OT_PKGSTAT = $(shell pkg-config --exists $(OTC_WRAPPER)$(OT_DEBUG_EXT); echo $$?) +OT_CFLAGS = $(shell pkg-config --silence-errors --cflags $(OTC_WRAPPER)$(OT_DEBUG_EXT)) +else +ifneq ($(wildcard $(OT_INC)/$(OTC_WRAPPER)/.*),) +OT_CFLAGS = -I$(OT_INC) $(if $(OT_DEBUG),-DOTC_DBG_MEM) +endif +endif + +ifeq ($(OT_PKGSTAT),) +ifeq ($(OT_CFLAGS),) +$(error OpenTracing C wrapper : can't find headers) +endif +else +ifneq ($(OT_PKGSTAT),0) +$(error OpenTracing C wrapper : can't find package) +endif +endif + +ifeq ($(OT_LIB),) +OT_LDFLAGS = $(shell pkg-config --silence-errors --libs $(OTC_WRAPPER)$(OT_DEBUG_EXT)) +else +ifneq ($(wildcard $(OT_LIB)/lib$(OTC_WRAPPER).*),) +OT_LDFLAGS = -L$(OT_LIB) -l$(OTC_WRAPPER)$(OT_DEBUG_EXT) +ifneq ($(OT_RUNPATH),) +OT_LDFLAGS += -Wl,--rpath,$(OT_LIB) +endif +endif +endif + +ifeq ($(OT_LDFLAGS),) +$(error OpenTracing C wrapper : can't find library) +endif + +OPTIONS_OBJS += \ + addons/ot/src/cli.o \ + addons/ot/src/conf.o \ + addons/ot/src/event.o \ + addons/ot/src/filter.o \ + addons/ot/src/group.o \ + addons/ot/src/http.o \ + addons/ot/src/opentracing.o \ + addons/ot/src/parser.o \ + addons/ot/src/pool.o \ + addons/ot/src/scope.o \ + addons/ot/src/util.o + +ifneq ($(OT_USE_VARS),) +OT_DEFINE += -DUSE_OT_VARS +OPTIONS_OBJS += \ + addons/ot/src/vars.o +endif + +OPTIONS_CFLAGS += $(OT_CFLAGS) -Iaddons/ot/include +OPTIONS_LDFLAGS += $(OT_LDFLAGS) +OPTIONS_CFLAGS += $(OT_DEFINE) diff --git a/addons/ot/README b/addons/ot/README new file mode 100644 index 0000000..a08f471 --- /dev/null +++ b/addons/ot/README @@ -0,0 +1,794 @@ + ----------------------------------------- + The HAProxy OpenTracing filter (OT) + Version 1.0 + ( Last update: 2020-12-10 ) + ----------------------------------------- + Author : Miroslav Zagorac + Contact : mzagorac at haproxy dot com + + +SUMMARY +-------- + + 0. Terms + 1. Introduction + 2. Build instructions + 3. Basic concepts in OpenTracing + 4. OT configuration + 4.1. OT scope + 4.2. "ot-tracer" section + 4.3. "ot-scope" section + 4.4. "ot-group" section + 5. Examples + 5.1 Benchmarking results + 6. OT CLI + 7. Known bugs and limitations + + +0. Terms +--------- + +* OT: The HAProxy OpenTracing filter + + OT is the HAProxy filter that allows you to send data to distributed + tracing systems via the OpenTracing API. + + +1. Introduction +---------------- + +Nowadays there is a growing need to divide a process into microservices and +there is a problem of monitoring the work of the same process. One way to +solve this problem is to use distributed tracing service in a central location, +the so-called tracer. + +OT is a feature introduced in HAProxy 2.4. This filter enables communication +via the OpenTracing API with OpenTracing compatible servers (tracers). +Currently, tracers that support this API include Datadog, Jaeger, LightStep +and Zipkin. + +The OT filter was primarily tested with the Jaeger tracer, while configurations +for both Datadog and Zipkin tracers were also set in the test directory. + +The OT filter is a standard HAProxy filter, so what applies to others also +applies to this one (of course, by that I mean what is described in the +documentation, more precisely in the doc/internals/filters.txt file). + +The OT filter activation is done explicitly by specifying it in the HAProxy +configuration. If this is not done, the OT filter in no way participates +in the work of HAProxy. + +As for the impact on HAProxy speed, this is documented with several tests +located in the test directory, and the result is found in the README-speed-* +files. In short, the speed of operation depends on the way it is used and +the complexity of the configuration, from an almost immeasurable impact to +a significant deceleration (5x and more). I think that in some normal use +the speed of HAProxy with the filter on will be quite satisfactory with a +slowdown of less than 4% (provided that no more than 10% of requests are +sent to the tracer, which is determined by the keyword 'rate-limit'). + +The OT filter allows intensive use of ACLs, which can be defined anywhere in +the configuration. Thus, it is possible to use the filter only for those +connections that are of interest to us. + + +2. Build instructions +---------------------- + +OT is the HAProxy filter and as such is compiled together with HAProxy. + +To communicate with some OpenTracing compatible tracer, the OT filter uses the +OpenTracing C Wrapper library (which again uses the OpenTracing CPP library). +This means that we must have both libraries installed on the system on which +we want to compile or use HAProxy. + +Instructions for compiling and installing both required libraries can be +found at https://github.com/haproxytech/opentracing-c-wrapper . + +Also, to use the OT filter when running HAProxy we need to have an OpenTracing +plugin for the tracer we want to use. We will return to this later, in +section 5. + +The OT filter can be more easily compiled using the pkg-config tool, if we +have the OpenTracing C Wrapper library installed so that it contains pkg-config +files (which have the .pc extension). If the pkg-config tool cannot be used, +then the path to the directory where the include files and libraries are +located can be explicitly specified. + +Below are examples of the two ways to compile HAProxy with the OT filter, the +first using the pkg-congfig tool and the second explicitly specifying the path +to the OpenTracing C Wrapper include and library. + +Note: prompt '%' indicates that the command is executed under a unprivileged + user, while prompt '#' indicates that the command is executed under the + root user. + +Example of compiling HAProxy using the pkg-congfig tool (assuming the +OpenTracing C Wrapper library is installed in the /opt directory): + + % PKG_CONFIG_PATH=/opt/lib/pkgconfig make USE_OT=1 TARGET=linux-glibc + +The OT filter can also be compiled in debug mode as follows: + + % PKG_CONFIG_PATH=/opt/lib/pkgconfig make USE_OT=1 OT_DEBUG=1 TARGET=linux-glibc + +HAProxy compilation example explicitly specifying path to the OpenTracing C +Wrapper include and library: + + % make USE_OT=1 OT_INC=/opt/include OT_LIB=/opt/lib TARGET=linux-glibc + +In case we want to use debug mode, then it looks like this: + + % make USE_OT=1 OT_DEBUG=1 OT_INC=/opt/include OT_LIB=/opt/lib TARGET=linux-glibc + +If the library we want to use is not installed on a unix system, then a locally +installed library can be used (say, which is compiled and installed in the user +home directory). In this case instead of /opt/include and /opt/lib the +equivalent paths to the local installation should be specified. Of course, +in that case the pkg-config tool can also be used if we have a complete +installation (with .pc files). + +last but not least, if the pkg-config tool is not used when compiling, then +HAProxy executable may not be able to find the OpenTracing C Wrapper library +at startup. This can be solved in several ways, for example using the +LD_LIBRARY_PATH environment variable which should be set to the path where the +library is located before starting the HAProxy. + + % LD_LIBRARY_PATH=/opt/lib /path-to/haproxy ... + +Another way is to add RUNPATH to HAProxy executable that contains the path to +the library in question. + + % make USE_OT=1 OT_RUNPATH=1 OT_INC=/opt/include OT_LIB=/opt/lib TARGET=linux-glibc + +After HAProxy is compiled, we can check if the OT filter is enabled: + + % ./haproxy -vv | grep opentracing + --- command output ---------- + [ OT] opentracing + --- command output ---------- + + +3. Basic concepts in OpenTracing +--------------------------------- + +Basic concepts of OpenTracing can be read on the OpenTracing documentation +website https://opentracing.io/docs/overview/. + +Here we will list only the most important elements of distributed tracing and +these are 'trace', 'span' and 'span context'. Trace is a description of the +complete transaction we want to record in the tracing system. A span is an +operation that represents a unit of work that is recorded in a tracing system. +Span context is a group of information related to a particular span that is +passed on to the system (from service to service). Using this context, we can +add new spans to already open trace (or supplement data in already open spans). + +An individual span may contain one or more tags, logs and baggage items. +The tag is a key-value element that is valid for the entire span. Log is a +key-value element that allows you to write some data at a certain time, it +can be used for debugging. A baggage item is a key-value data pair that can +be used for the duration of an entire trace, from the moment it is added to +the span. + + +4. OT configuration +-------------------- + +In order for the OT filter to be used, it must be included in the HAProxy +configuration, in the proxy section (frontend / listen / backend): + + frontend ot-test + ... + filter opentracing [id ] config + ... + +If no filter id is specified, 'ot-filter' is used as default. The 'config' +parameter must be specified and it contains the path of the file used to +configure the OT filter. + + +4.1 OT scope +------------- + +If the filter id is defined for the OT filter, then the OT scope with +the same name should be defined in the configuration file. In the same +configuration file we can have several defined OT scopes. + +Each OT scope must have a defined (only one) "ot-tracer" section that is +used to configure the operation of the OT filter and define the used groups +and scopes. + +OT scope starts with the id of the filter specified in square brackets and +ends with the end of the file or when a new OT scope is defined. + +For example, this defines two OT scopes in the same configuration file: + [my-first-ot-filter] + ot-tracer tracer1 + ... + ot-group group1 + ... + ot-scope scope1 + ... + + [my-second-ot-filter] + ... + + +4.2. "ot-tracer" section +------------------------- + +Only one "ot-tracer" section must be defined for each OT scope. + +There are several keywords that must be defined for the OT filter to work. +These are 'config' which defines the configuration file for the OpenTracing +API, and 'plugin' which defines the OpenTracing plugin used. + +Through optional keywords can be defined ACLs, logging, rate limit, and groups +and scopes that define the tracing model. + + +ot-tracer + A new OT with the name is created. + + Arguments : + name - the name of the tracer section + + + The following keywords are supported in this section: + - mandatory keywords: + - config + - plugin + + - optional keywords: + - acl + - debug-level + - groups + - [no] log + - [no] option disabled + - [no] option dontlog-normal + - [no] option hard-errors + - rate-limit + - scopes + + +acl [flags] [operator] ... + Declare or complete an access list. + + To configure and use the ACL, see section 7 of the HAProxy Configuration + Manual. + + +config + 'config' is one of the two mandatory keywords associated with the OT tracer + configuration. This keyword sets the path of the configuration file for the + OpenTracing tracer plugin. To set the contents of this configuration file, + it is best to look at the documentation related to the OpenTracing tracer we + want to use. + + Arguments : + file - the path of the configuration file + + +debug-level + This keyword sets the value of the debug level related to the display of + debug messages in the OT filter. The 'debug-level' value is binary, ie + a single value bit enables or disables the display of the corresponding + debug message that uses that bit. The default value is set via the + FLT_OT_DEBUG_LEVEL macro in the include/config.h file. Debug level value + is used only if the OT filter is compiled with the debug mode enabled, + otherwise it is ignored. + + Arguments : + value - binary value ranging from 0 to 255 (8 bits) + + +groups ... + A list of "ot-group" groups used for the currently defined tracer is declared. + Several groups can be specified in one line. + + Arguments : + name - the name of the OT group + + +log global +log [len ] [format ] [ []] +no log + Enable per-instance logging of events and traffic. + + To configure and use the logging system, see section 4.2 of the HAProxy + Configuration Manual. + + +option disabled +no option disabled + Keyword which turns the operation of the OT filter on or off. By default + the filter is on. + + +option dontlog-normal +no option dontlog-normal + Enable or disable logging of normal, successful processing. By default, + this option is disabled. For this option to be considered, logging must + be turned on. + + See also: 'log' keyword description. + + +option hard-errors +no option hard-errors + During the operation of the filter, some errors may occur, caused by + incorrect configuration of the tracer or some error related to the operation + of HAProxy. By default, such an error will not interrupt the filter + operation for the stream in which the error occurred. If the 'hard-error' + option is enabled, the operation error prohibits all further processing of + events and groups in the stream in which the error occurred. + + +plugin + 'plugin' is one of the two mandatory keywords associated with the OT tracer + configuration. This keyword sets the path of the OpenTracing tracer plugin. + + Arguments : + file - the name of the plugin used + + +rate-limit + This option allows limiting the use of the OT filter, ie it can be influenced + whether the OT filter is activated for a stream or not. Determining whether + or not a filter is activated depends on the value of this option that is + compared to a randomly selected value when attaching the filter to the stream. + By default, the value of this option is set to 100.0, ie the OT filter is + activated for each stream. + + Arguments : + value - floating point value ranging from 0.0 to 100.0 + + +scopes ... + This keyword declares a list of "ot-scope" definitions used for the currently + defined tracer. Multiple scopes can be specified in the same line. + + Arguments : + name - the name of the OT scope + + +4.3. "ot-scope" section +------------------------ + +Stream processing begins with filter attachment, then continues with the +processing of a number of defined events and groups, and ends with filter +detachment. The "ot-scope" section is used to define actions related to +individual events. However, this section may be part of a group, so the +event does not have to be part of the definition. + + +ot-scope + Creates a new OT scope definition named . + + Arguments : + name - the name of the OT scope + + + The following keywords are supported in this section: + - acl + - baggage + - event + - extract + - finish + - inject + - log + - span + - tag + + +acl [flags] [operator] ... + Declare or complete an access list. + + To configure and use the ACL, see section 7 of the HAProxy Configuration + Manual. + + +baggage ... + Baggage items allow the propagation of data between spans, ie allow the + assignment of metadata that is propagated to future children spans. + This data is formatted in the style of key-value pairs and is part of + the context that can be transferred between processes that are part of + a server architecture. + + This kewyord allows setting the baggage for the currently active span. The + data type is always a string, ie any sample type is converted to a string. + The exception is a binary value that is not supported by the OT filter. + + See the 'tag' keyword description for the data type conversion table. + + Arguments : + name - key part of a data pair + sample - sample expression (value part of a data pair), at least one + sample must be present + + +event [{ if | unless } ] + Set the event that triggers the 'ot-scope' to which it is assigned. + Optionally, it can be followed by an ACL-based condition, in which case it + will only be evaluated if the condition is true. + + ACL-based conditions are executed in the context of a stream that processes + the client and server connections. To configure and use the ACL, see + section 7 of the HAProxy Configuration Manual. + + Arguments : + name - the event name + condition - a standard ACL-based condition + + Supported events are (the table gives the names of the events in the OT + filter and the corresponding equivalent in the SPOE filter): + + -------------------------------------|------------------------------ + the OT filter | the SPOE filter + -------------------------------------|------------------------------ + on-client-session-start | on-client-session + on-frontend-tcp-request | on-frontend-tcp-request + on-http-wait-request | - + on-http-body-request | - + on-frontend-http-request | on-frontend-http-request + on-switching-rules-request | - + on-backend-tcp-request | on-backend-tcp-request + on-backend-http-request | on-backend-http-request + on-process-server-rules-request | - + on-http-process-request | - + on-tcp-rdp-cookie-request | - + on-process-sticking-rules-request | - + on-client-session-end | - + on-server-unavailable | - + -------------------------------------|------------------------------ + on-server-session-start | on-server-session + on-tcp-response | on-tcp-response + on-http-wait-response | - + on-process-store-rules-response | - + on-http-response | on-http-response + on-server-session-end | - + -------------------------------------|------------------------------ + + +extract [use-vars | use-headers] + For a more detailed description of the propagation process of the span + context, see the description of the keyword 'inject'. Only the process + of extracting data from the carrier is described here. + + Arguments : + name-prefix - data name prefix (ie key element prefix) + use-vars - data is extracted from HAProxy variables + use-headers - data is extracted from the HTTP header + + + Below is an example of using HAProxy variables to transfer span context data: + + --- test/ctx/ot.cfg -------------------------------------------------------- + ... + ot-scope client_session_start_2 + extract "ot_ctx_1" use-vars + span "Client session" child-of "ot_ctx_1" + ... + ---------------------------------------------------------------------------- + + +finish ... + Closing a particular span or span context. Instead of the name of the span, + there are several specially predefined names with which we can finish certain + groups of spans. So it can be used as the name '*req*' for all open spans + related to the request channel, '*res*' for all open spans related to the + response channel and '*' for all open spans regardless of which channel they + are related to. Several spans and/or span contexts can be specified in one + line. + + Arguments : + name - the name of the span or context context + + +inject [use-vars] [use-headers] + In OpenTracing, the transfer of data related to the tracing process between + microservices that are part of a larger service is done through the + propagation of the span context. The basic operations that allow us to + access and transfer this data are 'inject' and 'extract'. + + 'inject' allows us to extract span context so that the obtained data can + be forwarded to another process (microservice) via the selected carrier. + 'inject' in the name actually means inject data into carrier. Carrier is + an interface here (ie a data structure) that allows us to transfer tracing + state from one process to another. + + Data transfer can take place via one of two selected storage methods, the + first is by adding data to the HTTP header and the second is by using HAProxy + variables. Only data transfer via HTTP header can be used to transfer data + to another process (ie microservice). All data is organized in the form of + key-value data pairs. + + No matter which data transfer method you use, we need to specify a prefix + for the key element. All alphanumerics (lowercase only) and underline + character can be used to construct the data name prefix. Uppercase letters + can actually be used, but they will be converted to lowercase when creating + the prefix. + + Arguments : + name-prefix - data name prefix (ie key element prefix) + use-vars - HAProxy variables are used to store and transfer data + use-headers - HTTP headers are used to store and transfer data + + + Below is an example of using HTTP headers and variables, and how this is + reflected in the internal data of the HAProxy process. + + --- test/ctx/ot.cfg -------------------------------------------------------- + ... + ot-scope client_session_start_1 + span "HAProxy session" root + inject "ot_ctx_1" use-headers use-vars + ... + ---------------------------------------------------------------------------- + + - generated HAProxy variable (key -> value): + txn.ot_ctx_1.uberDtraceDid -> 8f1a05a3518d2283:8f1a05a3518d2283:0:1 + + - generated HTTP header (key: value): + ot_ctx_1-uber-trace-id: 8f1a05a3518d2283:8f1a05a3518d2283:0:1 + + Because HAProxy does not allow the '-' character in the variable name (which + is automatically generated by the OpenTracing API and on which we have no + influence), it is converted to the letter 'D'. We can see that there is no + such conversion in the name of the HTTP header because the '-' sign is allowed + there. Due to this conversion, initially all uppercase letters are converted + to lowercase because otherwise we would not be able to distinguish whether + the disputed sign '-' is used or not. + + Thus created HTTP headers and variables are deleted when executing the + 'finish' keyword or when detaching the stream from the filter. + + +log ... + This kewyord allows setting the log for the currently active span. The + data type is always a string, ie any sample type is converted to a string. + The exception is a binary value that is not supported by the OT filter. + + See the 'tag' keyword description for the data type conversion table. + + Arguments : + name - key part of a data pair + sample - sample expression (value part of a data pair), at least one + sample must be present + + +span [] + Creating a new span (or referencing an already opened one). If a new span + is created, it can be a child of the referenced span, follow from the + referenced span, or be root 'span'. In case we did not specify a reference + to the previously created span, the new span will become the root span. + We need to pay attention to the fact that in one trace there can be only + one root span. In case we have specified a non-existent span as a reference, + a new span will not be created. + + Arguments : + name - the name of the span being created or referenced (operation + name) + reference - span or span context to which the created span is referenced + + +tag ... + This kewyord allows setting a tag for the currently active span. The first + argument is the name of the tag (tag ID) and the second its value. A value + can consist of one or more data. If the value is only one data, then the + type of that data depends on the type of the HAProxy sample. If the value + contains more data, then the data type is string. The data conversion table + is below: + + HAProxy sample data type | the OpenTracing data type + --------------------------+--------------------------- + NULL | NULL + BOOL | BOOL + INT32 | INT64 + UINT32 | UINT64 + INT64 | INT64 + UINT64 | UINT64 + IPV4 | STRING + IPV6 | STRING + STRING | STRING + BINARY | UNSUPPORTED + --------------------------+--------------------------- + + Arguments : + name - key part of a data pair + sample - sample expression (value part of a data pair), at least one + sample must be present + + +4.4. "ot-group" section +------------------------ + +This section allows us to define a group of OT scopes, that is not activated +via an event but is triggered from TCP or HTTP rules. More precisely, these +are the following rules: 'tcp-request', 'tcp-response', 'http-request', +'http-response' and 'http-after-response'. These rules can be defined in the +HAProxy configuration file. + + +ot-group + Creates a new OT group definition named . + + Arguments : + name - the name of the OT group + + + The following keywords are supported in this section: + - scopes + + +scopes ... + 'ot-scope' sections that are part of the specified group are defined. If + the mentioned 'ot-scope' sections are used only in some OT group, they do + not have to have defined events. Several 'ot-scope' sections can be + specified in one line. + + Arguments : + name - the name of the 'ot-scope' section + + +5. Examples +------------ + +Several examples of the OT filter configuration can be found in the test +directory. A brief description of the prepared configurations follows: + +cmp - the configuration very similar to that of the spoa-opentracing project. + It was made to compare the speed of the OT filter with the + implementation of distributed tracing via spoa-opentracing application. + +sa - the configuration in which all possible events are used. + +ctx - the configuration is very similar to the previous one, with the only + difference that the spans are opened using the span context as a span + reference. + +fe be - a slightly more complicated example of the OT filter configuration + that uses two cascaded HAProxy services. The span context between + HAProxy processes is transmitted via the HTTP header. + +empty - the empty configuration in which the OT filter is initialized but + no event is triggered. It is not very usable, except to check the + behavior of the OT filter in the case of a similar configuration. + + +In order to be able to collect data (and view results via the web interface) +we need to install some of the supported tracers. We will use the Jaeger +tracer as an example. Installation instructions can be found on the website +https://www.jaegertracing.io/download/. For the impatient, here we will list +how the image to test the operation of the tracer system can be installed +without much reading of the documentation. + + # docker pull jaegertracing/all-in-one:latest + # docker run -d --name jaeger -e COLLECTOR_ZIPKIN_HTTP_PORT=9411 \ + -p 5775:5775/udp -p 6831:6831/udp -p 6832:6832/udp -p 5778:5778 \ + -p 16686:16686 -p 14268:14268 -p 9411:9411 jaegertracing/all-in-one:latest + +The last command will also initialize and run the Jaeger container. If we +want to use that container later, it can be started and stopped in the classic +way, using the 'docker container start/stop' commands. + + +In order to be able to use any of the configurations from the test directory, +we must also have a tracer plugin in that directory (all examples use the +Jaeger tracer plugin). The simplest way is to download the tracer plugin +using the already prepared shell script get-opentracing-plugins.sh. +The script accepts one argument, the directory in which the download is made. +If run without an argument, the script downloads all plugins to the current +directory. + + % ./get-opentracing-plugins.sh + +After that, we can run one of the pre-configured configurations using the +provided script run-xxx.sh (where xxx is the name of the configuration being +tested). For example: + + % ./run-sa.sh + +The script will create a new log file each time it is run (because part of the +log file name is the start time of the script). + +Eh, someone will surely notice that all test configurations use the Jaeger +tracing plugin that cannot be downloaded using the get-opentracing-plugins.sh +script. Unfortunately, the latest precompiled version that can be downloaded +is 0.4.2, for newer ones only the source code can be found. Version 0.4.2 has +a bug that can cause the operation of the OT filter to get stuck, so it is +better not to use this version. Here is the procedure by which we can compile +a newer version of the plugin (in our example it is 0.5.0). + +Important note: the GCC version must be at least 4.9 or later. + + % wget https://github.com/jaegertracing/jaeger-client-cpp/archive/v0.5.0.tar.gz + % tar xf v0.5.0.tar.gz + % cd jaeger-client-cpp-0.5.0 + % mkdir build + % cd build + % cmake -DCMAKE_INSTALL_PREFIX=/opt -DJAEGERTRACING_PLUGIN=ON -DHUNTER_CONFIGURATION_TYPES=Release -DHUNTER_BUILD_SHARED_LIBS=OFF .. + % make + +After the plugin is compiled, it will be in the current directory. The name +of the plugin is libjaegertracing_plugin.so. + + +5.1. Benchmarking results +-------------------------- + +To check the operation of the OT filter, several different test configurations +have been made which are located in the test directory. The test results of +the same configurations (with the names README-speed-xxx, where xxx is the name +of the configuration being tested) are also in the directory of the same name. + +All tests were performed on the same debian 9.13 system, CPU i7-4770, 32 GB RAM. +For the purpose of testing, the thttpd web server on port 8000 was used. +Testing was done with the wrk utility running via run-xxx.sh scripts; that is, +via the test-speed.sh script that is run as follows: + + % ./test-speed.sh all + +The above mentioned thttpd web server is run from that script and it should be +noted that we need to have the same installed on the system (or change the path +to the thttpd server in that script if it is installed elsewhere). + +Each test is performed several times over a period of 5 minutes per individual +test. The only difference when running the tests for the same configuration +was in changing the 'rate-limit' parameter (and the 'option disabled' option), +which is set to the following values: 100.0, 50.0, 10.0, 2.5 and 0.0 percent. +Then a test is performed with the OT filter active but disabled for request +processing ('option disabled' is included in the ot.cfg configuration). In +the last test, the OT filter is not used at all, ie it is not active and does +not affect the operation of HAProxy in any way. + + +6. OT CLI +---------- + +Via the HAProxy CLI interface we can find out the current status of the OT +filter and change several of its settings. + +All supported CLI commands can be found in the following way, using the +socat utility with the assumption that the HAProxy CLI socket path is set +to /tmp/haproxy.sock (of course, instead of socat, nc or other utility can +be used with a change in arguments when running the same): + + % echo "help" | socat - UNIX-CONNECT:/tmp/haproxy.sock | grep flt-ot + --- command output ---------- + flt-ot debug [level] : set the OT filter debug level (default: get current debug level) + flt-ot disable : disable the OT filter + flt-ot enable : enable the OT filter + flt-ot soft-errors : turning off hard-errors mode + flt-ot hard-errors : enabling hard-errors mode + flt-ot logging [state] : set logging state (default: get current logging state) + flt-ot rate [value] : set the rate limit (default: get current rate value) + flt-ot status : show the OT filter status + --- command output ---------- + +'flt-ot debug' can only be used in case the OT filter is compiled with the +debug mode enabled. + + +7. Known bugs and limitations +------------------------------ + +The name of the span context definition can contain only letters, numbers and +characters '_' and '-'. Also, all uppercase letters in the name are converted +to lowercase. The character '-' is converted internally to the 'D' character, +and since a HAProxy variable is generated from that name, this should be taken +into account if we want to use it somewhere in the HAProxy configuration. +The above mentioned span context is used in the 'inject' and 'extract' keywords. + +Let's look a little at the example test/fe-be (configurations are in the +test/fe and test/be directories, 'fe' is here the abbreviation for frontend +and 'be' for backend). In case we have the 'rate-limit' set to a value less +than 100.0, then distributed tracing will not be started with each new HTTP +request. It also means that the span context will not be delivered (via the +HTTP header) to the backend HAProxy process. The 'rate-limit' on the backend +HAProxy must be set to 100.0, but because the frontend HAProxy does not send +a span context every time, all such cases will cause an error to be reported +on the backend server. Therefore, the 'hard-errors' option must be set on the +backend server, so that processing on that stream is stopped as soon as the +first error occurs. Such cases will slow down the backend server's response +a bit (in the example in question it is about 3%). diff --git a/addons/ot/README-func b/addons/ot/README-func new file mode 100644 index 0000000..273c7f9 --- /dev/null +++ b/addons/ot/README-func @@ -0,0 +1,298 @@ +Here I will write down some specifics of certain parts of the source, these are +just some of my thoughts and clues and they are probably not too important for +a wider audience. + +src/parser.c +------------------------------------------------------------------------------ +The first thing to run when starting the HAProxy is the flt_ot_parse() function +which actually parses the filter configuration. + +In case of correct configuration, the function returns ERR_NONE (or 0), while +in case of incorrect configuration it returns the combination of ERR_* flags +(ERR_NONE here does not belong to that bit combination because its value is 0). + +One of the parameters of the function is in which an error message +can be returned, if it exists. In that case the return value of the function +should have some of the ERR_* flags set. + +Let's look at an example of the following filter configuration what the function +call sequence looks like. + +Filter configuration line: + filter opentracing [id ] config + +Function call sequence: + flt_ot_parse() { + /* Initialization of the filter configuration data. */ + flt_ot_conf_init() { + } + + /* Setting the filter name. */ + flt_ot_parse_keyword() { + flt_ot_parse_strdup() { + } + } + + /* Setting the filter configuration file name. */ + flt_ot_parse_keyword() { + flt_ot_parse_strdup() { + } + } + + /* Checking the configuration of the filter. */ + flt_ot_parse_cfg() { + flt_ot_parse_cfg_tracer() { + } + ... + flt_ot_post_parse_cfg_tracer() { + } + flt_ot_parse_cfg_group() { + } + ... + flt_ot_post_parse_cfg_group() { + } + flt_ot_parse_cfg_scope() { + } + ... + flt_ot_post_parse_cfg_scope() { + } + } + } + +Checking the filter configuration is actually much more complicated, only the +name of the main function flt_ot_parse_cfg() that does it is listed here. + +All functions that use the parameter should set the error status using +that pointer. All other functions (actually these are all functions called +by the flt_ot_parse_cfg() function) should set the error message using the +ha_warning()/ha_alert() HAProxy functions. Of course, the return value (the +mentioned combination of ERR_* bits) is set in all these functions and it +indicates whether the filter configuration is correct or not. + + +src/group.c +------------------------------------------------------------------------------ +The OT filter allows the use of groups within which one or more 'ot-scope' +declarations can be found. These groups can be used using several HAProxy +rules, more precisely 'http-request', 'http-response', 'tcp-request', +'tcp-response' and 'http-after-response' rules. + +Configuration example for the specified rules: + ot-group [ { if | unless } ] + +Parsing each of these rules is performed by the flt_ot_group_parse() function. +After parsing the configuration, its verification is performed via the +flt_ot_group_check() function. One parsing function and one configuration +check function are called for each defined rule. + + flt_ot_group_parse() { + } + ... + flt_ot_group_check() { + } + ... + + +When deinitializing the module, the function flt_ot_group_release() is called +(which is actually an release_ptr callback function from one of the above +rules). One callback function is called for each defined rule. + + flt_ot_group_release() { + } + ... + + +src/filter.c +------------------------------------------------------------------------------ +After parsing and checking the configuration, the flt_ot_check() function is +called which associates the 'ot-group' and 'ot-scope' definitions with their +declarations. This procedure concludes the configuration of the OT filter and +after that its initialization is possible. + + flt_ops.check = flt_ot_check; + flt_ot_check() { + } + + +The initialization of the OT filter is done via the flt_ot_init() callback +function. In this function the OpenTracing API library is also initialized. +It is also possible to initialize for each thread individually, but nothing +is being done here for now. + + flt_ops.init = flt_ot_init; + flt_ot_init() { + flt_ot_cli_init() { + } + /* Initialization of the OpenTracing API. */ + ot_init() { + } + } + + flt_ops.init_per_thread = flt_ot_init_per_thread; + flt_ot_init_per_thread() { + } + ... + + +After the filter instance is created and attached to the stream, the +flt_ot_attach() function is called. In this function a new OT runtime +context is created, and flags are set that define which analyzers are used. + + flt_ops.attach = flt_ot_attach; + flt_ot_attach() { + /* In case OT is disabled, nothing is done on this stream further. */ + flt_ot_runtime_context_init() { + flt_ot_pool_alloc() { + } + /* Initializing and setting the variable 'sess.ot.uuid'. */ + if (flt_ot_var_register() != -1) { + flt_ot_var_set() { + } + } + } + } + + +When a stream is started, this function is called. At the moment, nothing +is being done in it. + + flt_ops.stream_start = flt_ot_stream_start; + flt_ot_stream_start() { + } + + +Channel analyzers are called when executing individual filter events. +For each of the four analyzer functions, the events associated with them +are listed. + + Events: + - 1 'on-client-session-start' + - 15 'on-server-session-start' +------------------------------------------------------------------------ + flt_ops.channel_start_analyze = flt_ot_channel_start_analyze; + flt_ot_channel_start_analyze() { + flt_ot_event_run() { + /* Run event. */ + flt_ot_scope_run() { + /* Processing of all ot-scopes defined for the current event. */ + } + } + } + + + Events: + - 2 'on-frontend-tcp-request' + - 4 'on-http-body-request' + - 5 'on-frontend-http-request' + - 6 'on-switching-rules-request' + - 7 'on-backend-tcp-request' + - 8 'on-backend-http-request' + - 9 'on-process-server-rules-request' + - 10 'on-http-process-request' + - 11 'on-tcp-rdp-cookie-request' + - 12 'on-process-sticking-rules-request + - 16 'on-tcp-response' + - 18 'on-process-store-rules-response' + - 19 'on-http-response' +------------------------------------------------------------------------ + flt_ops.channel_pre_analyze = flt_ot_channel_pre_analyze; + flt_ot_channel_pre_analyze() { + flt_ot_event_run() { + /* Run event. */ + flt_ot_scope_run() { + /* Processing of all ot-scopes defined for the current event. */ + } + } + } + + + Events: + - 3 'on-http-wait-request' + - 17 'on-http-wait-response' +------------------------------------------------------------------------ + flt_ops.channel_post_analyze = flt_ot_channel_post_analyze; + flt_ot_channel_post_analyze() { + flt_ot_event_run() { + /* Run event. */ + flt_ot_scope_run() { + /* Processing of all ot-scopes defined for the current event. */ + } + } + } + + + Events: + - 13 'on-client-session-end' + - 14 'on-server-unavailable' + - 20 'on-server-session-end' +------------------------------------------------------------------------ + flt_ops.channel_end_analyze = flt_ot_channel_end_analyze; + flt_ot_channel_end_analyze() { + flt_ot_event_run() { + /* Run event. */ + flt_ot_scope_run() { + /* Processing of all ot-scopes defined for the current event. */ + } + } + + /* In case the backend server does not work, event 'on-server-unavailable' + is called here before event 'on-client-session-end'. */ + if ('on-server-unavailable') { + flt_ot_event_run() { + /* Run event. */ + flt_ot_scope_run() { + /* Processing of all ot-scopes defined for the current event. */ + } + } + } + } + + +After the stream has stopped, this function is called. At the moment, nothing +is being done in it. + + flt_ops.stream_stop = flt_ot_stream_stop; + flt_ot_stream_stop() { + } + + +Then, before the instance filter is detached from the stream, the following +function is called. It deallocates the runtime context of the OT filter. + + flt_ops.detach = flt_ot_detach; + flt_ot_detach() { + flt_ot_runtime_context_free() { + flt_ot_pool_free() { + } + } + } + + +Module deinitialization begins with deinitialization of individual threads +(as many threads as configured for the HAProxy process). Because nothing +special is connected to the process threads, nothing is done in this function. + + flt_ops.deinit_per_thread = flt_ot_deinit_per_thread; + flt_ot_deinit_per_thread() { + } + ... + + +For this function see the above description related to the src/group.c file. + + flt_ot_group_release() { + } + ... + + +Module deinitialization ends with the flt_ot_deinit() function, in which all +memory occupied by module operation (and OpenTracing API operation, of course) +is freed. + + flt_ops.deinit = flt_ot_deinit; + flt_ot_deinit() { + ot_close() { + } + flt_ot_conf_free() { + } + } diff --git a/addons/ot/README-pool b/addons/ot/README-pool new file mode 100644 index 0000000..8164b04 --- /dev/null +++ b/addons/ot/README-pool @@ -0,0 +1,25 @@ +Used pools: + +-------------------------------+-----------------------------+----------------------------- + head / name | size | define +-------------------------------+-----------------------------+----------------------------- + pool_head_ buffer | global.tune.bufsize = 16384 | USE_POOL_BUFFER + pool_head_ trash | 32 + 16384 | USE_TRASH_CHUNK +-------------------------------+-----------------------------+----------------------------- + pool_head_ ot_scope_span | 96 | USE_POOL_OT_SCOPE_SPAN + pool_head_ ot_scope_context | 64 | USE_POOL_OT_SCOPE_CONTEXT + pool_head_ ot_runtime_context | 128 | USE_POOL_OT_RUNTIME_CONTEXT + pool_head_ ot_span_context | 96 | USE_POOL_OT_SPAN_CONTEXT +-------------------------------+-----------------------------+----------------------------- + +By defining individual definitions in file include/config.h, it is possible to +switch individual pools on / off. If a particular pool is not used, memory is +used in a 'normal' way instead, using malloc()/free() functions. + +This is made only from the aspect of debugging the program, i.e. comparing the +speed of operation using different methods of working with memory. + +In general, it would be better to use memory pools, due to less fragmentation +of memory space after long operation of the program. The speed of operation +is similar to when using standard allocation functions (when testing it was +shown that pool use was fast by about 1%). diff --git a/addons/ot/include/cli.h b/addons/ot/include/cli.h new file mode 100644 index 0000000..80ed6e8 --- /dev/null +++ b/addons/ot/include/cli.h @@ -0,0 +1,50 @@ +/*** + * Copyright 2020 HAProxy Technologies + * + * This file is part of the HAProxy OpenTracing filter. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef _OPENTRACING_CLI_H_ +#define _OPENTRACING_CLI_H_ + +#define FLT_OT_CLI_CMD "flt-ot" + +#define FLT_OT_CLI_LOGGING_OFF "off" +#define FLT_OT_CLI_LOGGING_ON "on" +#define FLT_OT_CLI_LOGGING_NOLOGNORM "dontlog-normal" +#define FLT_OT_CLI_LOGGING_STATE(a) ((a) & FLT_OT_LOGGING_ON) ? (((a) & FLT_OT_LOGGING_NOLOGNORM) ? "enabled, " FLT_OT_CLI_LOGGING_NOLOGNORM : "enabled") : "disabled" + +#define FLT_OT_CLI_MSG_CAT(a) ((a) == NULL) ? "" : (a), ((a) == NULL) ? "" : "\n" + +enum FLT_OT_LOGGING_enum { + FLT_OT_LOGGING_OFF = 0, + FLT_OT_LOGGING_ON = 1 << 0, + FLT_OT_LOGGING_NOLOGNORM = 1 << 1, +}; + + +void flt_ot_cli_init(void); + +#endif /* _OPENTRACING_CLI_H_ */ + +/* + * Local variables: + * c-indent-level: 8 + * c-basic-offset: 8 + * End: + * + * vi: noexpandtab shiftwidth=8 tabstop=8 + */ diff --git a/addons/ot/include/conf.h b/addons/ot/include/conf.h new file mode 100644 index 0000000..a4bb7fc --- /dev/null +++ b/addons/ot/include/conf.h @@ -0,0 +1,228 @@ +/*** + * Copyright 2020 HAProxy Technologies + * + * This file is part of the HAProxy OpenTracing filter. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef _OPENTRACING_CONF_H_ +#define _OPENTRACING_CONF_H_ + +#define FLT_OT_CONF(f) ((struct flt_ot_conf *)FLT_CONF(f)) +#define FLT_OT_CONF_HDR_FMT "%p:{ { '%.*s' %zu %d } " +#define FLT_OT_CONF_HDR_ARGS(a,b) (a), (int)(a)->b##_len, (a)->b, (a)->b##_len, (a)->cfg_line +#define FLT_OT_STR_HDR_ARGS(a,b) (a)->b, (a)->b##_len + +#define FLT_OT_DBG_CONF_SAMPLE_EXPR(f,a) \ + FLT_OT_DBG(3, "%s%p:{ '%s' %p }", (f), (a), (a)->value, (a)->expr) + +#define FLT_OT_DBG_CONF_SAMPLE(f,a) \ + FLT_OT_DBG(3, "%s%p:{ '%s' '%s' %s %d }", \ + (f), (a), (a)->key, (a)->value, flt_ot_list_debug(&((a)->exprs)), (a)->num_exprs) + +#define FLT_OT_DBG_CONF_STR(f,a) \ + FLT_OT_DBG(3, f FLT_OT_CONF_HDR_FMT "}", FLT_OT_CONF_HDR_ARGS(a, str)) + +#define FLT_OT_DBG_CONF_CONTEXT(f,a) \ + FLT_OT_DBG(3, f FLT_OT_CONF_HDR_FMT "0x%02hhx }", FLT_OT_CONF_HDR_ARGS(a, id), (a)->flags) + +#define FLT_OT_DBG_CONF_SPAN(f,a) \ + FLT_OT_DBG(3, f FLT_OT_CONF_HDR_FMT "'%s' %zu %d '%s' %zu %hhu 0x%02hhx %s %s %s }", \ + FLT_OT_CONF_HDR_ARGS(a, id), FLT_OT_STR_HDR_ARGS(a, ref_id), (a)->ref_type, \ + FLT_OT_STR_HDR_ARGS(a, ctx_id), (a)->flag_root, (a)->ctx_flags, flt_ot_list_debug(&((a)->tags)), \ + flt_ot_list_debug(&((a)->logs)), flt_ot_list_debug(&((a)->baggages))) + +#define FLT_OT_DBG_CONF_SCOPE(f,a) \ + FLT_OT_DBG(3, f FLT_OT_CONF_HDR_FMT "%hhu %d %s %p %s %s %s }", \ + FLT_OT_CONF_HDR_ARGS(a, id), (a)->flag_used, (a)->event, flt_ot_list_debug(&((a)->acls)), \ + (a)->cond, flt_ot_list_debug(&((a)->contexts)), flt_ot_list_debug(&((a)->spans)), \ + flt_ot_list_debug(&((a)->finish))) + +#define FLT_OT_DBG_CONF_GROUP(f,a) \ + FLT_OT_DBG(3, f FLT_OT_CONF_HDR_FMT "%hhu %s }", \ + FLT_OT_CONF_HDR_ARGS(a, id), (a)->flag_used, flt_ot_list_debug(&((a)->ph_scopes))) + +#define FLT_OT_DBG_CONF_PH(f,a) \ + FLT_OT_DBG(3, f FLT_OT_CONF_HDR_FMT "%p }", FLT_OT_CONF_HDR_ARGS(a, id), (a)->ptr) + +#define FLT_OT_DBG_CONF_TRACER(f,a) \ + FLT_OT_DBG(3, f FLT_OT_CONF_HDR_FMT "'%s' %p '%s' %p %u %hhu %hhu 0x%02hhx %p:%s 0x%08x %s %s %s }", \ + FLT_OT_CONF_HDR_ARGS(a, id), (a)->config, (a)->cfgbuf, (a)->plugin, (a)->tracer, (a)->rate_limit, (a)->flag_harderr, \ + (a)->flag_disabled, (a)->logging, &((a)->proxy_log), flt_ot_list_debug(&((a)->proxy_log.logsrvs)), (a)->analyzers, \ + flt_ot_list_debug(&((a)->acls)), flt_ot_list_debug(&((a)->ph_groups)), flt_ot_list_debug(&((a)->ph_scopes))) + +#define FLT_OT_DBG_CONF(f,a) \ + FLT_OT_DBG(3, "%s%p:{ %p '%s' '%s' %p %s %s }", \ + (f), (a), (a)->proxy, (a)->id, (a)->cfg_file, (a)->tracer, \ + flt_ot_list_debug(&((a)->groups)), flt_ot_list_debug(&((a)->scopes))) + +#define FLT_OT_STR_HDR(a) \ + struct { \ + char *a; \ + size_t a##_len; \ + } + +#define FLT_OT_CONF_HDR(a) \ + struct { \ + FLT_OT_STR_HDR(a); \ + int cfg_line; \ + struct list list; \ + } + + +struct flt_ot_conf_hdr { + FLT_OT_CONF_HDR(id); +}; + +/* flt_ot_conf_sample->exprs */ +struct flt_ot_conf_sample_expr { + FLT_OT_CONF_HDR(value); /* The sample value. */ + struct sample_expr *expr; /* The sample expression. */ +}; + +/* + * flt_ot_conf_span->tags + * flt_ot_conf_span->logs + * flt_ot_conf_span->baggages + */ +struct flt_ot_conf_sample { + FLT_OT_CONF_HDR(key); /* The sample name. */ + char *value; /* The sample content. */ + struct list exprs; /* Used to chain sample expressions. */ + int num_exprs; /* Number of defined expressions. */ +}; + +/* flt_ot_conf_scope->finish */ +struct flt_ot_conf_str { + FLT_OT_CONF_HDR(str); /* String content/length. */ +}; + +/* flt_ot_conf_scope->contexts */ +struct flt_ot_conf_context { + FLT_OT_CONF_HDR(id); /* The name of the context. */ + uint8_t flags; /* The type of storage from which the span context is extracted. */ +}; + +/* flt_ot_conf_scope->spans */ +struct flt_ot_conf_span { + FLT_OT_CONF_HDR(id); /* The name of the span. */ + FLT_OT_STR_HDR(ref_id); /* The reference name, if used. */ + int ref_type; /* The reference type. */ + FLT_OT_STR_HDR(ctx_id); /* The span context name, if used. */ + uint8_t ctx_flags; /* The type of storage used for the span context. */ + bool flag_root; /* Whether this is a root span. */ + struct list tags; /* The set of key:value tags. */ + struct list logs; /* The set of key:value logs. */ + struct list baggages; /* The set of key:value baggage items. */ +}; + +struct flt_ot_conf_scope { + FLT_OT_CONF_HDR(id); /* The scope name. */ + bool flag_used; /* The indication that the scope is being used. */ + int event; /* FLT_OT_EVENT_* */ + struct list acls; /* ACLs declared on this scope. */ + struct acl_cond *cond; /* ACL condition to meet. */ + struct list contexts; /* Declared contexts. */ + struct list spans; /* Declared spans. */ + struct list finish; /* The list of spans to be finished. */ +}; + +struct flt_ot_conf_group { + FLT_OT_CONF_HDR(id); /* The group name. */ + bool flag_used; /* The indication that the group is being used. */ + struct list ph_scopes; /* List of all used scopes. */ +}; + +struct flt_ot_conf_ph { + FLT_OT_CONF_HDR(id); /* The scope/group name. */ + void *ptr; /* Pointer to real placeholder structure. */ +}; +#define flt_ot_conf_ph_group flt_ot_conf_ph +#define flt_ot_conf_ph_scope flt_ot_conf_ph + +struct flt_ot_conf_tracer { + FLT_OT_CONF_HDR(id); /* The tracer name. */ + char *config; /* The OpenTracing configuration file name. */ + char *cfgbuf; /* The OpenTracing configuration. */ + char *plugin; /* The OpenTracing plugin library file name. */ + struct otc_tracer *tracer; /* The OpenTracing tracer handle. */ + uint32_t rate_limit; /* [0 2^32-1] <-> [0.0 100.0] */ + bool flag_harderr; /* [0 1] */ + bool flag_disabled; /* [0 1] */ + uint8_t logging; /* [0 1 3] */ + struct proxy proxy_log; /* The log server list. */ + uint analyzers; /* Defined channel analyzers. */ + struct list acls; /* ACLs declared on this tracer. */ + struct list ph_groups; /* List of all used groups. */ + struct list ph_scopes; /* List of all used scopes. */ +}; + +struct flt_ot_counters { +#ifdef DEBUG_OT + struct { + bool flag_used; /* Whether this event is used. */ + uint64_t htx[2]; /* htx_is_empty() function result counter. */ + } event[FLT_OT_EVENT_MAX]; +#endif + + uint64_t disabled[2]; /* How many times stream processing is disabled. */ +}; + +/* The OpenTracing filter configuration. */ +struct flt_ot_conf { + struct proxy *proxy; /* Proxy owning the filter. */ + char *id; /* The OpenTracing filter id. */ + char *cfg_file; /* The OpenTracing filter configuration file name. */ + struct flt_ot_conf_tracer *tracer; /* There can only be one tracer. */ + struct list groups; /* List of all available groups. */ + struct list scopes; /* List of all available scopes. */ + struct flt_ot_counters cnt; /* Various counters related to filter operation. */ +}; + + +#define flt_ot_conf_ph_group_free flt_ot_conf_ph_free +#define flt_ot_conf_ph_scope_free flt_ot_conf_ph_free + +struct flt_ot_conf_ph *flt_ot_conf_ph_init(const char *id, int linenum, struct list *head, char **err); +void flt_ot_conf_ph_free(struct flt_ot_conf_ph **ptr); +struct flt_ot_conf_sample_expr *flt_ot_conf_sample_expr_init(const char *id, int linenum, struct list *head, char **err); +void flt_ot_conf_sample_expr_free(struct flt_ot_conf_sample_expr **ptr); +struct flt_ot_conf_sample *flt_ot_conf_sample_init(char **args, int linenum, struct list *head, char **err); +void flt_ot_conf_sample_free(struct flt_ot_conf_sample **ptr); +struct flt_ot_conf_str *flt_ot_conf_str_init(const char *id, int linenum, struct list *head, char **err); +void flt_ot_conf_str_free(struct flt_ot_conf_str **ptr); +struct flt_ot_conf_context *flt_ot_conf_context_init(const char *id, int linenum, struct list *head, char **err); +void flt_ot_conf_context_free(struct flt_ot_conf_context **ptr); +struct flt_ot_conf_span *flt_ot_conf_span_init(const char *id, int linenum, struct list *head, char **err); +void flt_ot_conf_span_free(struct flt_ot_conf_span **ptr); +struct flt_ot_conf_scope *flt_ot_conf_scope_init(const char *id, int linenum, struct list *head, char **err); +void flt_ot_conf_scope_free(struct flt_ot_conf_scope **ptr); +struct flt_ot_conf_group *flt_ot_conf_group_init(const char *id, int linenum, struct list *head, char **err); +void flt_ot_conf_group_free(struct flt_ot_conf_group **ptr); +struct flt_ot_conf_tracer *flt_ot_conf_tracer_init(const char *id, int linenum, char **err); +void flt_ot_conf_tracer_free(struct flt_ot_conf_tracer **ptr); +struct flt_ot_conf *flt_ot_conf_init(struct proxy *px); +void flt_ot_conf_free(struct flt_ot_conf **ptr); + +#endif /* _OPENTRACING_CONF_H_ */ + +/* + * Local variables: + * c-indent-level: 8 + * c-basic-offset: 8 + * End: + * + * vi: noexpandtab shiftwidth=8 tabstop=8 + */ diff --git a/addons/ot/include/config.h b/addons/ot/include/config.h new file mode 100644 index 0000000..3b26365 --- /dev/null +++ b/addons/ot/include/config.h @@ -0,0 +1,46 @@ +/*** + * Copyright 2020 HAProxy Technologies + * + * This file is part of the HAProxy OpenTracing filter. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef _OPENTRACING_CONFIG_H_ +#define _OPENTRACING_CONFIG_H_ + +#undef DEBUG_OT_SYSTIME +#define USE_POOL_BUFFER +#define USE_POOL_OT_SPAN_CONTEXT +#define USE_POOL_OT_SCOPE_SPAN +#define USE_POOL_OT_SCOPE_CONTEXT +#define USE_POOL_OT_RUNTIME_CONTEXT +#define USE_TRASH_CHUNK + +#define FLT_OT_ID_MAXLEN 64 +#define FLT_OT_MAXTAGS 8 +#define FLT_OT_MAXBAGGAGES 8 +#define FLT_OT_RATE_LIMIT_MAX 100.0 +#define FLT_OT_DEBUG_LEVEL 0b00001111 + +#endif /* _OPENTRACING_CONFIG_H_ */ + +/* + * Local variables: + * c-indent-level: 8 + * c-basic-offset: 8 + * End: + * + * vi: noexpandtab shiftwidth=8 tabstop=8 + */ diff --git a/addons/ot/include/debug.h b/addons/ot/include/debug.h new file mode 100644 index 0000000..6274961 --- /dev/null +++ b/addons/ot/include/debug.h @@ -0,0 +1,104 @@ +/*** + * Copyright 2020 HAProxy Technologies + * + * This file is part of the HAProxy OpenTracing filter. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef _OPENTRACING_DEBUG_H_ +#define _OPENTRACING_DEBUG_H_ + +#ifdef DEBUG_FULL +# define DEBUG_OT +#endif + +#ifdef DEBUG_OT +# ifdef DEBUG_OT_SYSTIME +# define FLT_OT_DBG_FMT(f) "[% 2d] %ld.%06ld [" FLT_OT_SCOPE "]: " f, tid, now.tv_sec, now.tv_usec +# else +# define FLT_OT_DBG_FMT(f) "[% 2d] %11.6f [" FLT_OT_SCOPE "]: " f, tid, FLT_OT_TV_UDIFF(&(flt_ot_debug.start), &now) / 1e6 +# endif +# define FLT_OT_DBG_INDENT " " +# define FLT_OT_DBG(l,f, ...) \ + do { \ + if (!(l) || (flt_ot_debug.level & (1 << (l)))) \ + (void)fprintf(stderr, FLT_OT_DBG_FMT("%.*s" f "\n"), \ + dbg_indent_level, FLT_OT_DBG_INDENT, ##__VA_ARGS__); \ + } while (0) +# define FLT_OT_FUNC(f, ...) do { FLT_OT_DBG(1, "%s(" f ") {", __func__, ##__VA_ARGS__); dbg_indent_level += 3; } while (0) +# define FLT_OT_RETURN(a) do { dbg_indent_level -= 3; FLT_OT_DBG(1, "}"); return a; } while (0) +# define FLT_OT_RETURN_EX(a,t,f) do { dbg_indent_level -= 3; { t _r = (a); FLT_OT_DBG(1, "} = " f, _r); return _r; } } while (0) +# define FLT_OT_RETURN_INT(a) FLT_OT_RETURN_EX((a), int, "%d") +# define FLT_OT_RETURN_PTR(a) FLT_OT_RETURN_EX((a), void *, "%p") +# define FLT_OT_DBG_IFDEF(a,b) a +# define FLT_OT_DBG_ARGS(a, ...) a, ##__VA_ARGS__ +# define FLT_OT_DBG_BUF(a,b) do { FLT_OT_DBG((a), "%p:{ %zu %p %zu %zu }", (b), (b)->size, (b)->area, (b)->data, (b)->head); } while (0) + +struct flt_ot_debug { +#ifndef DEBUG_OT_SYSTIME + struct timeval start; +#endif + uint8_t level; +}; + + +extern THREAD_LOCAL int dbg_indent_level; +extern struct flt_ot_debug flt_ot_debug; + +#else + +# define FLT_OT_DBG(...) while (0) +# define FLT_OT_FUNC(...) while (0) +# define FLT_OT_RETURN(a) return a +# define FLT_OT_RETURN_EX(a,t,f) return a +# define FLT_OT_RETURN_INT(a) return a +# define FLT_OT_RETURN_PTR(a) return a +# define FLT_OT_DBG_IFDEF(a,b) b +# define FLT_OT_DBG_ARGS(...) +# define FLT_OT_DBG_BUF(a,b) while (0) +#endif /* DEBUG_OT */ + +/* + * ON | NOLOGNORM | + * -----+-----------+------------- + * 0 | 0 | no log + * 0 | 1 | no log + * 1 | 0 | log all + * 1 | 1 | log errors + * -----+-----------+------------- + */ +#define FLT_OT_LOG(l,f, ...) \ + do { \ + if (!(conf->tracer->logging & FLT_OT_LOGGING_ON)) \ + FLT_OT_DBG(3, "NOLOG[%d]: [" FLT_OT_SCOPE "]: [%s] " f, (l), conf->id, ##__VA_ARGS__); \ + else if ((conf->tracer->logging & FLT_OT_LOGGING_NOLOGNORM) && ((l) > LOG_ERR)) \ + FLT_OT_DBG(2, "NOLOG[%d]: [" FLT_OT_SCOPE "]: [%s] " f, (l), conf->id, ##__VA_ARGS__); \ + else { \ + send_log(&(conf->tracer->proxy_log), (l), "[" FLT_OT_SCOPE "]: [%s] " f "\n", conf->id, ##__VA_ARGS__); \ + \ + FLT_OT_DBG(1, "LOG[%d]: %s", (l), logline); \ + } \ + } while (0) + +#endif /* _OPENTRACING_DEBUG_H_ */ + +/* + * Local variables: + * c-indent-level: 8 + * c-basic-offset: 8 + * End: + * + * vi: noexpandtab shiftwidth=8 tabstop=8 + */ diff --git a/addons/ot/include/define.h b/addons/ot/include/define.h new file mode 100644 index 0000000..3c3e4a3 --- /dev/null +++ b/addons/ot/include/define.h @@ -0,0 +1,107 @@ +/*** + * Copyright 2020 HAProxy Technologies + * + * This file is part of the HAProxy OpenTracing filter. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef _OPENTRACING_DEFINE_H_ +#define _OPENTRACING_DEFINE_H_ + +#define FLT_OT_DEREF(a,m,v) (((a) != NULL) ? (a)->m : (v)) +#define FLT_OT_DDEREF(a,m,v) ((((a) != NULL) && (*(a) != NULL)) ? (*(a))->m : (v)) +#define FLT_OT_TABLESIZE(a) (sizeof(a) / sizeof((a)[0])) +#define FLT_OT_IN_RANGE(v,a,b) (((v) >= (a)) && ((v) <= (b))) +#define FLT_OT_DPTR_ARGS(a) (a), ((a) == NULL) ? NULL : *(a) +#define FLT_OT_ARG_ISVALID(n) ((args[n] != NULL) && *args[n]) +#define FLT_OT_TV_UDIFF(a,b) (((b)->tv_sec - (a)->tv_sec) * 1000000 + (b)->tv_usec - (a)->tv_usec) +#define FLT_OT_U32_FLOAT(a,b) ((a) * (double)(b) / UINT32_MAX) +#define FLT_OT_FLOAT_U32(a,b) ((uint32_t)((a) / (double)(b) * UINT32_MAX + 0.5)) + +#define FLT_OT_STR_DASH_72 "------------------------------------------------------------------------" +#define FLT_OT_STR_DASH_78 FLT_OT_STR_DASH_72 "------" +#define FLT_OT_STR_FLAG_YN(a) (a) ? "yes" : "no" + +#define FLT_OT_STR_SIZE(a) (sizeof(a) - 1) +#define FLT_OT_STR_ADDRSIZE(a) (a), FLT_OT_STR_SIZE(a) +#define FLT_OT_STR_ISVALID(a) (((a) != NULL) && (*(a) != '\0')) +#define FLT_OT_STR_CMP(S,s,l) (((l) == FLT_OT_STR_SIZE(S)) && (memcmp((s), FLT_OT_STR_ADDRSIZE(S)) == 0)) +#define FLT_OT_STR_ELLIPSIS(a,n) do { if ((a) != NULL) { if ((n) > 0) (a)[(n) - 1] = '\0'; if ((n) > 3) (a)[(n) - 2] = (a)[(n) - 3] = (a)[(n) - 4] = '.'; } } while (0) +#define FLT_OT_NIBBLE_TO_HEX(a) ((a) + (((a) < 10) ? '0' : ('a' - 10))) + +#define FLT_OT_FREE(a) do { if ((a) != NULL) OTC_DBG_FREE(a); } while (0) +#define FLT_OT_FREE_VOID(a) do { if ((a) != NULL) OTC_DBG_FREE((void *)(a)); } while (0) +#define FLT_OT_FREE_CLEAR(a) do { if ((a) != NULL) { OTC_DBG_FREE(a); (a) = NULL; } } while (0) +#define FLT_OT_STRDUP(s) OTC_DBG_STRDUP(s) +#define FLT_OT_STRNDUP(s,n) OTC_DBG_STRNDUP((s), (n)) +#define FLT_OT_CALLOC(n,e) OTC_DBG_CALLOC((n), (e)) +#define FLT_OT_MALLOC(s) OTC_DBG_MALLOC((s)) +#define FLT_OT_MEMINFO() OTC_DBG_MEMINFO() + +#define FLT_OT_RUN_ONCE(f) do { static bool __f = 1; if (__f) { __f = 0; f; } } while (0) + +#define FLT_OT_LIST_ISVALID(a) (((a) != NULL) && ((a)->n != NULL) && ((a)->p != NULL)) +#define FLT_OT_LIST_DEL(a) do { if (FLT_OT_LIST_ISVALID(a)) LIST_DELETE(a); } while (0) +#define FLT_OT_LIST_DESTROY(t,h) \ + do { \ + struct flt_ot_conf_##t *_ptr, *_back; \ + \ + if (!FLT_OT_LIST_ISVALID(h) || LIST_ISEMPTY(h)) \ + break; \ + \ + FLT_OT_DBG(2, "- deleting " #t " list %s", flt_ot_list_debug(h)); \ + \ + list_for_each_entry_safe(_ptr, _back, (h), list) \ + flt_ot_conf_##t##_free(&_ptr); \ + } while (0) + +#define FLT_OT_BUFFER_THR(b,m,n,p) \ + static THREAD_LOCAL char b[m][n]; \ + static THREAD_LOCAL size_t __idx = 0; \ + char *p = b[__idx]; \ + __idx = (__idx + 1) % (m) + +#define FLT_OT_ERR(f, ...) \ + do { \ + if ((err != NULL) && (*err == NULL)) { \ + (void)memprintf(err, f, ##__VA_ARGS__); \ + \ + FLT_OT_DBG(3, "%d err: '%s'", __LINE__, *err); \ + } \ + } while (0) +#define FLT_OT_ERR_APPEND(f, ...) \ + do { \ + if (err != NULL) \ + (void)memprintf(err, f, ##__VA_ARGS__); \ + } while (0) +#define FLT_OT_ERR_FREE(p) \ + do { \ + if ((p) == NULL) \ + break; \ + \ + FLT_OT_DBG(0, "%s:%d: ERROR: %s", __func__, __LINE__, (p)); \ + FLT_OT_FREE_CLEAR(p); \ + } while (0) + +#endif /* _OPENTRACING_DEFINE_H_ */ + +/* + * Local variables: + * c-indent-level: 8 + * c-basic-offset: 8 + * End: + * + * vi: noexpandtab shiftwidth=8 tabstop=8 + */ diff --git a/addons/ot/include/event.h b/addons/ot/include/event.h new file mode 100644 index 0000000..8d59163 --- /dev/null +++ b/addons/ot/include/event.h @@ -0,0 +1,120 @@ +/*** + * Copyright 2020 HAProxy Technologies + * + * This file is part of the HAProxy OpenTracing filter. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef _OPENTRACING_EVENT_H_ +#define _OPENTRACING_EVENT_H_ + +/* + * This must be defined in order for macro FLT_OT_EVENT_DEFINES + * and structure flt_ot_event_data to have the correct contents. + */ +#define AN_REQ_NONE 0 +#define AN_REQ_CLIENT_SESS_START 0 +#define AN_REQ_SERVER_UNAVAILABLE 0 +#define AN_REQ_CLIENT_SESS_END 0 +#define AN_RES_SERVER_SESS_START 0 +#define AN_RES_SERVER_SESS_END 0 +#define SMP_VAL_FE_ 0 +#define SMP_VAL_BE_ 0 + +/* + * Event names are selected to be somewhat compatible with the SPOE filter, + * from which the following names are taken: + * - on-client-session -> on-client-session-start + * - on-frontend-tcp-request + * - on-frontend-http-request + * - on-backend-tcp-request + * - on-backend-http-request + * - on-server-session -> on-server-session-start + * - on-tcp-response + * - on-http-response + * + * FLT_OT_EVENT_NONE is used as an index for 'ot-scope' sections that do not + * have an event defined. The 'ot-scope' sections thus defined can be used + * within the 'ot-group' section. + * + * A description of the macro arguments can be found in the structure + * flt_ot_event_data definition + */ +#define FLT_OT_EVENT_DEFINES \ + FLT_OT_EVENT_DEF( NONE, REQ, , , 0, "") \ + FLT_OT_EVENT_DEF( CLIENT_SESS_START, REQ, CON_ACC, , 1, "on-client-session-start") \ + FLT_OT_EVENT_DEF( INSPECT_FE, REQ, REQ_CNT, , 1, "on-frontend-tcp-request") \ + FLT_OT_EVENT_DEF( WAIT_HTTP, REQ, , , 1, "on-http-wait-request") \ + FLT_OT_EVENT_DEF( HTTP_BODY, REQ, , , 1, "on-http-body-request") \ + FLT_OT_EVENT_DEF( HTTP_PROCESS_FE, REQ, HRQ_HDR, , 1, "on-frontend-http-request") \ + FLT_OT_EVENT_DEF( SWITCHING_RULES, REQ, , , 1, "on-switching-rules-request") \ + FLT_OT_EVENT_DEF( INSPECT_BE, REQ, REQ_CNT, REQ_CNT, 1, "on-backend-tcp-request") \ + FLT_OT_EVENT_DEF( HTTP_PROCESS_BE, REQ, HRQ_HDR, HRQ_HDR, 1, "on-backend-http-request") \ +/* FLT_OT_EVENT_DEF( HTTP_TARPIT, REQ, , , 1, "on-http-tarpit-request") */ \ + FLT_OT_EVENT_DEF( SRV_RULES, REQ, , , 1, "on-process-server-rules-request") \ + FLT_OT_EVENT_DEF( HTTP_INNER, REQ, , , 1, "on-http-process-request") \ + FLT_OT_EVENT_DEF( PRST_RDP_COOKIE, REQ, , , 1, "on-tcp-rdp-cookie-request") \ + FLT_OT_EVENT_DEF( STICKING_RULES, REQ, , , 1, "on-process-sticking-rules-request") \ + FLT_OT_EVENT_DEF( CLIENT_SESS_END, REQ, , , 0, "on-client-session-end") \ + FLT_OT_EVENT_DEF(SERVER_UNAVAILABLE, REQ, , , 0, "on-server-unavailable") \ + \ + FLT_OT_EVENT_DEF( SERVER_SESS_START, RES, , SRV_CON, 0, "on-server-session-start") \ + FLT_OT_EVENT_DEF( INSPECT, RES, RES_CNT, RES_CNT, 0, "on-tcp-response") \ + FLT_OT_EVENT_DEF( WAIT_HTTP, RES, , , 1, "on-http-wait-response") \ + FLT_OT_EVENT_DEF( STORE_RULES, RES, , , 1, "on-process-store-rules-response") \ + FLT_OT_EVENT_DEF( HTTP_PROCESS_BE, RES, HRS_HDR, HRS_HDR, 1, "on-http-response") \ + FLT_OT_EVENT_DEF( SERVER_SESS_END, RES, , , 0, "on-server-session-end") + +enum FLT_OT_EVENT_enum { +#define FLT_OT_EVENT_DEF(a,b,c,d,e,f) FLT_OT_EVENT_##b##_##a, + FLT_OT_EVENT_DEFINES + FLT_OT_EVENT_MAX +#undef FLT_OT_EVENT_DEF +}; + +enum FLT_OT_EVENT_SAMPLE_enum { + FLT_OT_EVENT_SAMPLE_TAG = 0, + FLT_OT_EVENT_SAMPLE_LOG, + FLT_OT_EVENT_SAMPLE_BAGGAGE, +}; + +struct flt_ot_event_data { + uint an_bit; /* Used channel analyser. */ + uint smp_opt_dir; /* Fetch direction (request/response). */ + uint smp_val_fe; /* Valid FE fetch location. */ + uint smp_val_be; /* Valid BE fetch location. */ + bool flag_http_inject; /* Span context injection allowed. */ + const char *name; /* Filter event name. */ +}; + +struct flt_ot_conf_scope; + + +extern const struct flt_ot_event_data flt_ot_event_data[FLT_OT_EVENT_MAX]; + + +int flt_ot_scope_run(struct stream *s, struct filter *f, struct channel *chn, struct flt_ot_conf_scope *conf_scope, const struct timespec *ts, uint dir, char **err); +int flt_ot_event_run(struct stream *s, struct filter *f, struct channel *chn, int event, char **err); + +#endif /* _OPENTRACING_EVENT_H_ */ + +/* + * Local variables: + * c-indent-level: 8 + * c-basic-offset: 8 + * End: + * + * vi: noexpandtab shiftwidth=8 tabstop=8 + */ diff --git a/addons/ot/include/filter.h b/addons/ot/include/filter.h new file mode 100644 index 0000000..c97a0cc --- /dev/null +++ b/addons/ot/include/filter.h @@ -0,0 +1,68 @@ +/*** + * Copyright 2020 HAProxy Technologies + * + * This file is part of the HAProxy OpenTracing filter. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef _OPENTRACING_FILTER_H_ +#define _OPENTRACING_FILTER_H_ + +#define FLT_OT_FMT_NAME "'" FLT_OT_OPT_NAME "' : " +#define FLT_OT_FMT_TYPE "'filter' : " +#define FLT_OT_VAR_UUID "sess", "ot", "uuid" +#define FLT_OT_ALERT(f, ...) ha_alert(FLT_OT_FMT_TYPE FLT_OT_FMT_NAME f "\n", ##__VA_ARGS__) + +#define FLT_OT_CONDITION_IF "if" +#define FLT_OT_CONDITION_UNLESS "unless" + +enum FLT_OT_RET_enum { + FLT_OT_RET_ERROR = -1, + FLT_OT_RET_WAIT = 0, + FLT_OT_RET_IGNORE = 0, + FLT_OT_RET_OK = 1, +}; + +#define FLT_OT_DBG_LIST(d,m,p,t,v,f) \ + do { \ + if (LIST_ISEMPTY(&((d)->m##s))) { \ + FLT_OT_DBG(3, p "- no " #m "s " t); \ + } else { \ + const struct flt_ot_conf_##m *v; \ + \ + FLT_OT_DBG(3, p "- " t " " #m "s: %s", \ + flt_ot_list_debug(&((d)->m##s))); \ + list_for_each_entry(v, &((d)->m##s), list) \ + do { f; } while (0); \ + } \ + } while (0) + + +extern const char *ot_flt_id; +extern struct flt_ops flt_ot_ops; + + +bool flt_ot_is_disabled(const struct filter *f FLT_OT_DBG_ARGS(, int event)); + +#endif /* _OPENTRACING_FILTER_H_ */ + +/* + * Local variables: + * c-indent-level: 8 + * c-basic-offset: 8 + * End: + * + * vi: noexpandtab shiftwidth=8 tabstop=8 + */ diff --git a/addons/ot/include/group.h b/addons/ot/include/group.h new file mode 100644 index 0000000..a9bfcc6 --- /dev/null +++ b/addons/ot/include/group.h @@ -0,0 +1,61 @@ +/*** + * Copyright 2020 HAProxy Technologies + * + * This file is part of the HAProxy OpenTracing filter. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef _OPENTRACING_GROUP_H_ +#define _OPENTRACING_GROUP_H_ + +#define FLT_OT_ACTION_GROUP "ot-group" + +enum FLT_OT_ARG_enum { + FLT_OT_ARG_FILTER_ID = 0, + FLT_OT_ARG_GROUP_ID, + + FLT_OT_ARG_FLT_CONF = 0, + FLT_OT_ARG_CONF, + FLT_OT_ARG_GROUP, +}; + +/* + * A description of the macro arguments can be found in the structure + * flt_ot_group_data definition + */ +#define FLT_OT_GROUP_DEFINES \ + FLT_OT_GROUP_DEF(ACT_F_TCP_REQ_CON, SMP_VAL_FE_CON_ACC, SMP_OPT_DIR_REQ) \ + FLT_OT_GROUP_DEF(ACT_F_TCP_REQ_SES, SMP_VAL_FE_SES_ACC, SMP_OPT_DIR_REQ) \ + FLT_OT_GROUP_DEF(ACT_F_TCP_REQ_CNT, SMP_VAL_FE_REQ_CNT, SMP_OPT_DIR_REQ) \ + FLT_OT_GROUP_DEF(ACT_F_TCP_RES_CNT, SMP_VAL_BE_RES_CNT, SMP_OPT_DIR_RES) \ + FLT_OT_GROUP_DEF(ACT_F_HTTP_REQ, SMP_VAL_FE_HRQ_HDR, SMP_OPT_DIR_REQ) \ + FLT_OT_GROUP_DEF(ACT_F_HTTP_RES, SMP_VAL_BE_HRS_HDR, SMP_OPT_DIR_RES) + +struct flt_ot_group_data { + enum act_from act_from; /* ACT_F_* */ + uint smp_val; /* Valid FE/BE fetch location. */ + uint smp_opt_dir; /* Fetch direction (request/response). */ +}; + +#endif /* _OPENTRACING_GROUP_H_ */ + +/* + * Local variables: + * c-indent-level: 8 + * c-basic-offset: 8 + * End: + * + * vi: noexpandtab shiftwidth=8 tabstop=8 + */ diff --git a/addons/ot/include/http.h b/addons/ot/include/http.h new file mode 100644 index 0000000..c323cde --- /dev/null +++ b/addons/ot/include/http.h @@ -0,0 +1,41 @@ +/*** + * Copyright 2020 HAProxy Technologies + * + * This file is part of the HAProxy OpenTracing filter. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef _OPENTRACING_HTTP_H_ +#define _OPENTRACING_HTTP_H_ + +#ifndef DEBUG_OT +# define flt_ot_http_headers_dump(...) while (0) +#else +void flt_ot_http_headers_dump(const struct channel *chn); +#endif +struct otc_text_map *flt_ot_http_headers_get(struct channel *chn, const char *prefix, size_t len, char **err); +int flt_ot_http_header_set(struct channel *chn, const char *prefix, const char *name, const char *value, char **err); +int flt_ot_http_headers_remove(struct channel *chn, const char *prefix, char **err); + +#endif /* _OPENTRACING_HTTP_H_ */ + +/* + * Local variables: + * c-indent-level: 8 + * c-basic-offset: 8 + * End: + * + * vi: noexpandtab shiftwidth=8 tabstop=8 + */ diff --git a/addons/ot/include/include.h b/addons/ot/include/include.h new file mode 100644 index 0000000..f1a5672 --- /dev/null +++ b/addons/ot/include/include.h @@ -0,0 +1,66 @@ +/*** + * Copyright 2020 HAProxy Technologies + * + * This file is part of the HAProxy OpenTracing filter. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef _OPENTRACING_INCLUDE_H_ +#define _OPENTRACING_INCLUDE_H_ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "config.h" +#include "debug.h" +#include "define.h" +#include "cli.h" +#include "event.h" +#include "conf.h" +#include "filter.h" +#include "group.h" +#include "http.h" +#include "opentracing.h" +#include "parser.h" +#include "pool.h" +#include "scope.h" +#include "util.h" +#include "vars.h" + +#endif /* _OPENTRACING_INCLUDE_H_ */ + +/* + * Local variables: + * c-indent-level: 8 + * c-basic-offset: 8 + * End: + * + * vi: noexpandtab shiftwidth=8 tabstop=8 + */ diff --git a/addons/ot/include/opentracing.h b/addons/ot/include/opentracing.h new file mode 100644 index 0000000..2b88a33 --- /dev/null +++ b/addons/ot/include/opentracing.h @@ -0,0 +1,86 @@ +/*** + * Copyright 2020 HAProxy Technologies + * + * This file is part of the HAProxy OpenTracing filter. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef _OPENTRACING_OT_H_ +#define _OPENTRACING_OT_H_ + +#include + + +#define FLT_OT_VSET(p,t,v) \ + do { (p)->type = otc_value_##t; (p)->value.t##_value = (v); } while (0) + +#define FLT_OT_DBG_TEXT_MAP(a) \ + FLT_OT_DBG(3, "%p:{ %p %p %zu/%zu %hhu }", \ + (a), (a)->key, (a)->value, (a)->count, (a)->size, (a)->is_dynamic) + +#define FLT_OT_DBG_TEXT_CARRIER(a,f) \ + FLT_OT_DBG(3, "%p:{ { %p %p %zu/%zu %hhu } %p }", \ + (a), (a)->text_map.key, (a)->text_map.value, (a)->text_map.count, \ + (a)->text_map.size, (a)->text_map.is_dynamic, (a)->f) + +#define FLT_OT_DBG_CUSTOM_CARRIER(a,f) \ + FLT_OT_DBG(3, "%p:{ { %p %zu %hhu } %p }", \ + (a), (a)->binary_data.data, (a)->binary_data.size, \ + (a)->binary_data.is_dynamic, (a)->f) + +#define FLT_OT_DBG_SPAN_CONTEXT(a) \ + FLT_OT_DBG(3, "%p:{ %" PRId64 " %p %p }", (a), (a)->idx, (a)->span, (a)->destroy) + + +#ifndef DEBUG_OT +# define ot_debug() while (0) +# define ot_text_map_show(...) while (0) +#else +void ot_text_map_show(const struct otc_text_map *text_map); +void ot_debug(void); +#endif +int ot_init(struct otc_tracer **tracer, const char *plugin, char **err); +int ot_start(struct otc_tracer *tracer, const char *cfgbuf, char **err); +struct otc_span *ot_span_init(struct otc_tracer *tracer, const char *operation_name, const struct timespec *ts_steady, const struct timespec *ts_system, int ref_type, int ref_ctx_idx, const struct otc_span *ref_span, const struct otc_tag *tags, int num_tags, char **err); +int ot_span_tag(struct otc_span *span, const struct otc_tag *tags, int num_tags); +int ot_span_log(struct otc_span *span, const struct otc_log_field *log_fields, int num_fields); +int ot_span_set_baggage(struct otc_span *span, const struct otc_text_map *baggage); +struct otc_span_context *ot_inject_http_headers(struct otc_tracer *tracer, const struct otc_span *span, struct otc_http_headers_writer *carrier, char **err); +struct otc_span_context *ot_extract_http_headers(struct otc_tracer *tracer, struct otc_http_headers_reader *carrier, const struct otc_text_map *text_map, char **err); +void ot_span_finish(struct otc_span **span, const struct timespec *ts_finish, const struct timespec *log_ts, const char *log_key, const char *log_value, ...); +void ot_close(struct otc_tracer **tracer); + +/* Unused code. */ +struct otc_span *ot_span_init_va(struct otc_tracer *tracer, const char *operation_name, const struct timespec *ts_steady, const struct timespec *ts_system, int ref_type, int ref_ctx_idx, const struct otc_span *ref_span, char **err, const char *tag_key, const char *tag_value, ...); +int ot_span_tag_va(struct otc_span *span, const char *key, int type, ...); +int ot_span_log_va(struct otc_span *span, const char *key, const char *value, ...); +int ot_span_log_fmt(struct otc_span *span, const char *key, const char *format, ...) __attribute__ ((format(printf, 3, 4))); +int ot_span_set_baggage_va(struct otc_span *span, const char *key, const char *value, ...); +struct otc_text_map *ot_span_baggage_va(const struct otc_span *span, const char *key, ...); +struct otc_span_context *ot_inject_text_map(struct otc_tracer *tracer, const struct otc_span *span, struct otc_text_map_writer *carrier); +struct otc_span_context *ot_inject_binary(struct otc_tracer *tracer, const struct otc_span *span, struct otc_custom_carrier_writer *carrier); +struct otc_span_context *ot_extract_text_map(struct otc_tracer *tracer, struct otc_text_map_reader *carrier, const struct otc_text_map *text_map); +struct otc_span_context *ot_extract_binary(struct otc_tracer *tracer, struct otc_custom_carrier_reader *carrier, const struct otc_binary_data *binary_data); + +#endif /* _OPENTRACING_OT_H_ */ + +/* + * Local variables: + * c-indent-level: 8 + * c-basic-offset: 8 + * End: + * + * vi: noexpandtab shiftwidth=8 tabstop=8 + */ diff --git a/addons/ot/include/parser.h b/addons/ot/include/parser.h new file mode 100644 index 0000000..53e414b --- /dev/null +++ b/addons/ot/include/parser.h @@ -0,0 +1,172 @@ +/*** + * Copyright 2020 HAProxy Technologies + * + * This file is part of the HAProxy OpenTracing filter. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef _OPENTRACING_PARSER_H_ +#define _OPENTRACING_PARSER_H_ + +#define FLT_OT_SCOPE "OT" + +/* + * filter FLT_OT_OPT_NAME FLT_OT_OPT_FILTER_ID FLT_OT_OPT_CONFIG + */ +#define FLT_OT_OPT_NAME "opentracing" +#define FLT_OT_OPT_FILTER_ID "id" +#define FLT_OT_OPT_FILTER_ID_DEFAULT "ot-filter" +#define FLT_OT_OPT_CONFIG "config" + +#define FLT_OT_PARSE_SECTION_TRACER_ID "ot-tracer" +#define FLT_OT_PARSE_SECTION_GROUP_ID "ot-group" +#define FLT_OT_PARSE_SECTION_SCOPE_ID "ot-scope" + +#define FLT_OT_PARSE_SPAN_ROOT "root" +#define FLT_OT_PARSE_SPAN_REF_CHILD "child-of" +#define FLT_OT_PARSE_SPAN_REF_FOLLOWS "follows-from" +#define FLT_OT_PARSE_CTX_AUTONAME "-" +#define FLT_OT_PARSE_CTX_IGNORE_NAME '-' +#define FLT_OT_PARSE_CTX_USE_HEADERS "use-headers" +#define FLT_OT_PARSE_CTX_USE_VARS "use-vars" +#define FLT_OT_PARSE_OPTION_HARDERR "hard-errors" +#define FLT_OT_PARSE_OPTION_DISABLED "disabled" +#define FLT_OT_PARSE_OPTION_NOLOGNORM "dontlog-normal" + +/* + * A description of the macro arguments can be found in the structure + * flt_ot_parse_data definition + */ +#define FLT_OT_PARSE_TRACER_DEFINES \ + FLT_OT_PARSE_TRACER_DEF( ID, 0, CHAR, 2, 2, "ot-tracer", " ") \ + FLT_OT_PARSE_TRACER_DEF( ACL, 0, CHAR, 3, 0, "acl", " [flags] [operator] ...") \ + FLT_OT_PARSE_TRACER_DEF( LOG, 0, CHAR, 2, 0, "log", " { global | [len ] [format ] [ []] }") \ + FLT_OT_PARSE_TRACER_DEF( CONFIG, 0, NONE, 2, 2, "config", " ") \ + FLT_OT_PARSE_TRACER_DEF( PLUGIN, 0, NONE, 2, 2, "plugin", " ") \ + FLT_OT_PARSE_TRACER_DEF( GROUPS, 0, NONE, 2, 0, "groups", " ...") \ + FLT_OT_PARSE_TRACER_DEF( SCOPES, 0, NONE, 2, 0, "scopes", " ...") \ + FLT_OT_PARSE_TRACER_DEF( RATE_LIMIT, 0, NONE, 2, 2, "rate-limit", " ") \ + FLT_OT_PARSE_TRACER_DEF( OPTION, 0, NONE, 2, 2, "option", " { disabled | dontlog-normal | hard-errors }") \ + FLT_OT_PARSE_TRACER_DEF(DEBUG_LEVEL, 0, NONE, 2, 2, "debug-level", " ") + +#define FLT_OT_PARSE_GROUP_DEFINES \ + FLT_OT_PARSE_GROUP_DEF( ID, 0, CHAR, 2, 2, "ot-group", " ") \ + FLT_OT_PARSE_GROUP_DEF(SCOPES, 0, NONE, 2, 0, "scopes", " ...") + +#ifdef USE_OT_VARS +# define FLT_OT_PARSE_SCOPE_INJECT_HELP " [use-vars] [use-headers]" +# define FLT_OT_PARSE_SCOPE_EXTRACT_HELP " [use-vars | use-headers]" +#else +# define FLT_OT_PARSE_SCOPE_INJECT_HELP " [use-headers]" +# define FLT_OT_PARSE_SCOPE_EXTRACT_HELP " [use-headers]" +#endif + +/* + * In case the possibility of working with OpenTracing context via HAProxyu + * variables is not used, args_max member of the structure flt_ot_parse_data + * should be reduced for 'inject' keyword. However, this is not critical + * because in this case the 'use-vars' argument cannot be entered anyway, + * so I will not complicate it here with additional definitions. + */ +#define FLT_OT_PARSE_SCOPE_DEFINES \ + FLT_OT_PARSE_SCOPE_DEF( ID, 0, CHAR, 2, 2, "ot-scope", " ") \ + FLT_OT_PARSE_SCOPE_DEF( SPAN, 0, NONE, 2, 5, "span", " [] [root]") \ + FLT_OT_PARSE_SCOPE_DEF( TAG, 1, NONE, 3, 0, "tag", " ...") \ + FLT_OT_PARSE_SCOPE_DEF( LOG, 1, NONE, 3, 0, "log", " ...") \ + FLT_OT_PARSE_SCOPE_DEF(BAGGAGE, 1, VAR, 3, 0, "baggage", " ...") \ + FLT_OT_PARSE_SCOPE_DEF( INJECT, 1, CTX, 2, 4, "inject", FLT_OT_PARSE_SCOPE_INJECT_HELP) \ + FLT_OT_PARSE_SCOPE_DEF(EXTRACT, 0, CTX, 2, 3, "extract", FLT_OT_PARSE_SCOPE_EXTRACT_HELP) \ + FLT_OT_PARSE_SCOPE_DEF( FINISH, 0, NONE, 2, 0, "finish", " ...") \ + FLT_OT_PARSE_SCOPE_DEF( ACL, 0, CHAR, 3, 0, "acl", " [flags] [operator] ...") \ + FLT_OT_PARSE_SCOPE_DEF( EVENT, 0, NONE, 2, 0, "event", " [{ if | unless } ]") + +enum FLT_OT_PARSE_INVCHAR_enum { + FLT_OT_PARSE_INVALID_NONE, + FLT_OT_PARSE_INVALID_CHAR, + FLT_OT_PARSE_INVALID_DOM, + FLT_OT_PARSE_INVALID_CTX, + FLT_OT_PARSE_INVALID_VAR, +}; + +enum FLT_OT_PARSE_TRACER_enum { +#define FLT_OT_PARSE_TRACER_DEF(a,b,c,d,e,f,g) FLT_OT_PARSE_TRACER_##a, + FLT_OT_PARSE_TRACER_DEFINES +#undef FLT_OT_PARSE_TRACER_DEF +}; + +enum FLT_OT_PARSE_GROUP_enum { +#define FLT_OT_PARSE_GROUP_DEF(a,b,c,d,e,f,g) FLT_OT_PARSE_GROUP_##a, + FLT_OT_PARSE_GROUP_DEFINES +#undef FLT_OT_PARSE_GROUP_DEF +}; + +enum FLT_OT_PARSE_SCOPE_enum { +#define FLT_OT_PARSE_SCOPE_DEF(a,b,c,d,e,f,g) FLT_OT_PARSE_SCOPE_##a, + FLT_OT_PARSE_SCOPE_DEFINES +#undef FLT_OT_PARSE_SCOPE_DEF +}; + +enum FLT_OT_CTX_USE_enum { + FLT_OT_CTX_USE_VARS = 1 << 0, + FLT_OT_CTX_USE_HEADERS = 1 << 1, +}; + +struct flt_ot_parse_data { + int keyword; /* Keyword index. */ + bool flag_check_id; /* Whether the group ID must be defined for the keyword. */ + int check_name; /* Checking allowed characters in the name. */ + int args_min; /* The minimum number of arguments required. */ + int args_max; /* The maximum number of arguments allowed. */ + const char *name; /* Keyword name. */ + const char *usage; /* Usage text to be printed in case of an error. */ +}; + +#define FLT_OT_PARSE_WARNING(f, ...) \ + ha_warning("parsing [%s:%d] : " FLT_OT_FMT_TYPE FLT_OT_FMT_NAME "'" f "'\n", ##__VA_ARGS__); +#define FLT_OT_PARSE_ALERT(f, ...) \ + do { \ + ha_alert("parsing [%s:%d] : " FLT_OT_FMT_TYPE FLT_OT_FMT_NAME "'" f "'\n", ##__VA_ARGS__); \ + \ + retval |= ERR_ABORT | ERR_ALERT; \ + } while (0) +#define FLT_OT_POST_PARSE_ALERT(f, ...) \ + FLT_OT_PARSE_ALERT(f, flt_ot_current_config->cfg_file, ##__VA_ARGS__) + +#define FLT_OT_PARSE_ERR(e,f, ...) \ + do { \ + if (*(e) == NULL) \ + (void)memprintf((e), f, ##__VA_ARGS__); \ + \ + retval |= ERR_ABORT | ERR_ALERT; \ + } while (0) +#define FLT_OT_PARSE_IFERR_ALERT() \ + do { \ + if (err == NULL) \ + break; \ + \ + FLT_OT_PARSE_ALERT("%s", file, linenum, err); \ + FLT_OT_ERR_FREE(err); \ + } while (0) + +#endif /* _OPENTRACING_PARSER_H_ */ + +/* + * Local variables: + * c-indent-level: 8 + * c-basic-offset: 8 + * End: + * + * vi: noexpandtab shiftwidth=8 tabstop=8 + */ diff --git a/addons/ot/include/pool.h b/addons/ot/include/pool.h new file mode 100644 index 0000000..df72c84 --- /dev/null +++ b/addons/ot/include/pool.h @@ -0,0 +1,39 @@ +/*** + * Copyright 2020 HAProxy Technologies + * + * This file is part of the HAProxy OpenTracing filter. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef _OPENTRACING_POOL_H_ +#define _OPENTRACING_POOL_H_ + +void *flt_ot_pool_alloc(struct pool_head *pool, size_t size, bool flag_clear, char **err); +void *flt_ot_pool_strndup(struct pool_head *pool, const char *s, size_t size, char **err); +void flt_ot_pool_free(struct pool_head *pool, void **ptr); + +struct buffer *flt_ot_trash_alloc(bool flag_clear, char **err); +void flt_ot_trash_free(struct buffer **ptr); + +#endif /* _OPENTRACING_POOL_H_ */ + +/* + * Local variables: + * c-indent-level: 8 + * c-basic-offset: 8 + * End: + * + * vi: noexpandtab shiftwidth=8 tabstop=8 + */ diff --git a/addons/ot/include/scope.h b/addons/ot/include/scope.h new file mode 100644 index 0000000..7a3a776 --- /dev/null +++ b/addons/ot/include/scope.h @@ -0,0 +1,126 @@ +/*** + * Copyright 2020 HAProxy Technologies + * + * This file is part of the HAProxy OpenTracing filter. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef _OPENTRACING_SCOPE_H_ +#define _OPENTRACING_SCOPE_H_ + +#define FLT_OT_SCOPE_SPAN_FINISH_REQ "*req*" +#define FLT_OT_SCOPE_SPAN_FINISH_RES "*res*" +#define FLT_OT_SCOPE_SPAN_FINISH_ALL "*" + +#define FLT_OT_RT_CTX(a) ((struct flt_ot_runtime_context *)(a)) + +#define FLT_OT_DBG_SCOPE_SPAN(f,a) \ + FLT_OT_DBG(3, "%s%p:{ '%s' %zu %u %hhu %p %d %p %p }", \ + (f), (a), FLT_OT_STR_HDR_ARGS(a, id), (a)->smp_opt_dir, \ + (a)->flag_finish, (a)->span, (a)->ref_type, (a)->ref_span, (a)->ref_ctx) + +#define FLT_OT_DBG_SCOPE_CONTEXT(f,a) \ + FLT_OT_DBG(3, "%s%p:{ '%s' %zu %u %hhu %p }", \ + (f), (a), FLT_OT_STR_HDR_ARGS(a, id), (a)->smp_opt_dir, \ + (a)->flag_finish, (a)->context) + +#define FLT_OT_DBG_SCOPE_DATA(f,a) \ + FLT_OT_DBG(3, "%s%p:{ %p %d %p %p %d }", \ + (f), (a), (a)->tags, (a)->num_tags, (a)->baggage, (a)->log_fields, (a)->num_log_fields) + +#define FLT_OT_DBG_RUNTIME_CONTEXT(f,a) \ + FLT_OT_DBG(3, "%s%p:{ %p %p '%s' %hhu %hhu 0x%02hhx 0x%08x %s %s }", \ + (f), (a), (a)->stream, (a)->filter, (a)->uuid, (a)->flag_harderr, \ + (a)->flag_disabled, (a)->logging, (a)->analyzers, flt_ot_list_debug(&((a)->spans)), \ + flt_ot_list_debug(&((a)->contexts))) + +#define FLT_OT_CONST_STR_HDR(a) \ + struct { \ + const char *a; \ + size_t a##_len; \ + } + + +struct flt_ot_scope_data { + struct otc_tag tags[FLT_OT_MAXTAGS]; /* Defined tags. */ + int num_tags; /* The number of tags used. */ + struct otc_text_map *baggage; /* Defined baggage. */ + struct otc_log_field log_fields[OTC_MAXLOGFIELDS]; /* Defined logs. */ + int num_log_fields; /* The number of log fields used. */ +}; + +/* flt_ot_runtime_context->spans */ +struct flt_ot_scope_span { + FLT_OT_CONST_STR_HDR(id); /* The span operation name/len. */ + uint smp_opt_dir; /* SMP_OPT_DIR_RE(Q|S) */ + bool flag_finish; /* Whether the span is marked for completion. */ + struct otc_span *span; /* The current span. */ + otc_span_reference_type_t ref_type; /* Span reference type. */ + struct otc_span *ref_span; /* Span to which the current span refers. */ + struct otc_span_context *ref_ctx; /* Span context to which the current span refers. */ + struct list list; /* Used to chain this structure. */ +}; + +/* flt_ot_runtime_context->contexts */ +struct flt_ot_scope_context { + FLT_OT_CONST_STR_HDR(id); /* The span context name/len. */ + uint smp_opt_dir; /* SMP_OPT_DIR_RE(Q|S) */ + bool flag_finish; /* Whether the span context is marked for completion. */ + struct otc_span_context *context; /* The current span context. */ + struct list list; /* Used to chain this structure. */ +}; + +/* The runtime filter context attached to a stream. */ +struct flt_ot_runtime_context { + struct stream *stream; /* The stream to which the filter is attached. */ + struct filter *filter; /* The OpenTracing filter. */ + char uuid[40]; /* Randomly generated UUID. */ + bool flag_harderr; /* [0 1] */ + bool flag_disabled; /* [0 1] */ + uint8_t logging; /* [0 1 3] */ + uint analyzers; /* Executed channel analyzers. */ + struct list spans; /* The scope spans. */ + struct list contexts; /* The scope contexts. */ +}; + + +#ifndef DEBUG_OT +# define flt_ot_pools_info() while (0) +#else +void flt_ot_pools_info(void); +#endif +struct flt_ot_runtime_context *flt_ot_runtime_context_init(struct stream *s, struct filter *f, char **err); +void flt_ot_runtime_context_free(struct filter *f); + +struct flt_ot_scope_span *flt_ot_scope_span_init(struct flt_ot_runtime_context *rt_ctx, const char *id, size_t id_len, otc_span_reference_type_t ref_type, const char *ref_id, size_t ref_id_len, uint dir, char **err); +void flt_ot_scope_span_free(struct flt_ot_scope_span **ptr); +struct flt_ot_scope_context *flt_ot_scope_context_init(struct flt_ot_runtime_context *rt_ctx, struct otc_tracer *tracer, const char *id, size_t id_len, const struct otc_text_map *text_map, uint dir, char **err); +void flt_ot_scope_context_free(struct flt_ot_scope_context **ptr); +void flt_ot_scope_data_free(struct flt_ot_scope_data *ptr); + +int flt_ot_scope_finish_mark(const struct flt_ot_runtime_context *rt_ctx, const char *id, size_t id_len); +void flt_ot_scope_finish_marked(const struct flt_ot_runtime_context *rt_ctx, const struct timespec *ts_finish); +void flt_ot_scope_free_unused(struct flt_ot_runtime_context *rt_ctx, struct channel *chn); + +#endif /* _OPENTRACING_SCOPE_H_ */ + +/* + * Local variables: + * c-indent-level: 8 + * c-basic-offset: 8 + * End: + * + * vi: noexpandtab shiftwidth=8 tabstop=8 + */ diff --git a/addons/ot/include/util.h b/addons/ot/include/util.h new file mode 100644 index 0000000..776ddd2 --- /dev/null +++ b/addons/ot/include/util.h @@ -0,0 +1,109 @@ +/*** + * Copyright 2020 HAProxy Technologies + * + * This file is part of the HAProxy OpenTracing filter. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef _OPENTRACING_UTIL_H_ +#define _OPENTRACING_UTIL_H_ + +#define HTTP_METH_STR_OPTIONS "OPTIONS" +#define HTTP_METH_STR_GET "GET" +#define HTTP_METH_STR_HEAD "HEAD" +#define HTTP_METH_STR_POST "POST" +#define HTTP_METH_STR_PUT "PUT" +#define HTTP_METH_STR_DELETE "DELETE" +#define HTTP_METH_STR_TRACE "TRACE" +#define HTTP_METH_STR_CONNECT "CONNECT" + +/* Defined in include/haproxy/channel-t.h. */ +#define FLT_OT_AN_DEFINES \ + FLT_OT_AN_DEF(AN_REQ_INSPECT_FE) \ + FLT_OT_AN_DEF(AN_REQ_WAIT_HTTP) \ + FLT_OT_AN_DEF(AN_REQ_HTTP_BODY) \ + FLT_OT_AN_DEF(AN_REQ_HTTP_PROCESS_FE) \ + FLT_OT_AN_DEF(AN_REQ_SWITCHING_RULES) \ + FLT_OT_AN_DEF(AN_REQ_INSPECT_BE) \ + FLT_OT_AN_DEF(AN_REQ_HTTP_PROCESS_BE) \ + FLT_OT_AN_DEF(AN_REQ_HTTP_TARPIT) \ + FLT_OT_AN_DEF(AN_REQ_SRV_RULES) \ + FLT_OT_AN_DEF(AN_REQ_HTTP_INNER) \ + FLT_OT_AN_DEF(AN_REQ_PRST_RDP_COOKIE) \ + FLT_OT_AN_DEF(AN_REQ_STICKING_RULES) \ + FLT_OT_AN_DEF(AN_REQ_HTTP_XFER_BODY) \ + FLT_OT_AN_DEF(AN_REQ_WAIT_CLI) \ + FLT_OT_AN_DEF(AN_RES_INSPECT) \ + FLT_OT_AN_DEF(AN_RES_WAIT_HTTP) \ + FLT_OT_AN_DEF(AN_RES_STORE_RULES) \ + FLT_OT_AN_DEF(AN_RES_HTTP_PROCESS_BE) \ + FLT_OT_AN_DEF(AN_RES_HTTP_PROCESS_FE) \ + FLT_OT_AN_DEF(AN_RES_HTTP_XFER_BODY) \ + FLT_OT_AN_DEF(AN_RES_WAIT_CLI) + +#define FLT_OT_PROXIES_LIST_START() \ + do { \ + struct flt_conf *fconf; \ + struct proxy *px; \ + \ + for (px = proxies_list; px != NULL; px = px->next) \ + list_for_each_entry(fconf, &(px->filter_configs), list) \ + if (fconf->id == ot_flt_id) { \ + struct flt_ot_conf *conf = fconf->conf; +#define FLT_OT_PROXIES_LIST_END() \ + } \ + } while (0) + +#ifdef DEBUG_OT +# define FLT_OT_ARGS_DUMP() do { if (flt_ot_debug.level & (1 << 2)) flt_ot_args_dump(args); } while (0) +#else +# define FLT_OT_ARGS_DUMP() while (0) +#endif + + +#ifndef DEBUG_OT +# define flt_ot_filters_dump() while (0) +#else +void flt_ot_args_dump(char **args); +void flt_ot_filters_dump(void); +const char *flt_ot_chn_label(const struct channel *chn); +const char *flt_ot_pr_mode(const struct stream *s); +const char *flt_ot_stream_pos(const struct stream *s); +const char *flt_ot_type(const struct filter *f); +const char *flt_ot_analyzer(uint an_bit); +const char *flt_ot_str_hex(const void *data, size_t size); +const char *flt_ot_str_ctrl(const void *data, size_t size); +const char *flt_ot_list_debug(const struct list *head); +#endif + +ssize_t flt_ot_chunk_add(struct buffer *chk, const void *src, size_t n, char **err); +int flt_ot_args_count(char **args); +void flt_ot_args_to_str(char **args, int idx, char **str); +double flt_ot_strtod(const char *nptr, double limit_min, double limit_max, char **err); +int64_t flt_ot_strtoll(const char *nptr, int64_t limit_min, int64_t limit_max, char **err); +int flt_ot_sample_to_str(const struct sample_data *data, char *value, size_t size, char **err); +int flt_ot_sample_to_value(const char *key, const struct sample_data *data, struct otc_value *value, char **err); +int flt_ot_sample_add(struct stream *s, uint dir, struct flt_ot_conf_sample *sample, struct flt_ot_scope_data *data, int type, char **err); + +#endif /* _OPENTRACING_UTIL_H_ */ + +/* + * Local variables: + * c-indent-level: 8 + * c-basic-offset: 8 + * End: + * + * vi: noexpandtab shiftwidth=8 tabstop=8 + */ diff --git a/addons/ot/include/vars.h b/addons/ot/include/vars.h new file mode 100644 index 0000000..550cc89 --- /dev/null +++ b/addons/ot/include/vars.h @@ -0,0 +1,55 @@ +/*** + * Copyright 2020 HAProxy Technologies + * + * This file is part of the HAProxy OpenTracing filter. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef _OPENTRACING_VARS_H_ +#define _OPENTRACING_VARS_H_ + +#define FLT_OT_VARS_SCOPE "txn" +#define FLT_OT_VAR_CTX_SIZE int8_t +#define FLT_OT_VAR_CHAR_DASH 'D' +#define FLT_OT_VAR_CHAR_SPACE 'S' + +struct flt_ot_ctx { + char value[BUFSIZ]; + int value_len; +}; + +typedef int (*flt_ot_ctx_loop_cb)(struct sample *, size_t, const char *, const char *, const char *, FLT_OT_VAR_CTX_SIZE, char **, void *); + + +#ifndef DEBUG_OT +# define flt_ot_vars_dump(...) while (0) +#else +void flt_ot_vars_dump(struct stream *s); +#endif +int flt_ot_var_register(const char *scope, const char *prefix, const char *name, char **err); +int flt_ot_var_set(struct stream *s, const char *scope, const char *prefix, const char *name, const char *value, uint opt, char **err); +int flt_ot_vars_unset(struct stream *s, const char *scope, const char *prefix, uint opt, char **err); +struct otc_text_map *flt_ot_vars_get(struct stream *s, const char *scope, const char *prefix, uint opt, char **err); + +#endif /* _OPENTRACING_VARS_H_ */ + +/* + * Local variables: + * c-indent-level: 8 + * c-basic-offset: 8 + * End: + * + * vi: noexpandtab shiftwidth=8 tabstop=8 + */ diff --git a/addons/ot/src/cli.c b/addons/ot/src/cli.c new file mode 100644 index 0000000..9132fe9 --- /dev/null +++ b/addons/ot/src/cli.c @@ -0,0 +1,397 @@ +/*** + * Copyright 2020 HAProxy Technologies + * + * This file is part of the HAProxy OpenTracing filter. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include "include.h" + + +/*** + * NAME + * flt_ot_cli_set_msg - + * + * ARGUMENTS + * appctx - + * err - + * msg - + * cli_state - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * This function does not return a value. + */ +static void cmn_cli_set_msg(struct appctx *appctx, char *err, char *msg, int cli_state) +{ + struct cli_print_ctx *ctx = applet_reserve_svcctx(appctx, sizeof(*ctx)); + + FLT_OT_FUNC("%p, %p, %p, %d", appctx, err, msg, cli_state); + + if ((appctx == NULL) || ((err == NULL) && (msg == NULL))) + FLT_OT_RETURN(); + + ctx->err = (err == NULL) ? msg : err; + appctx->st0 = (ctx->err == NULL) ? CLI_ST_PROMPT : cli_state; + + FLT_OT_DBG(1, "err(%d): \"%s\"", appctx->st0, ctx->err); + + FLT_OT_RETURN(); +} + + +#ifdef DEBUG_OT + +/*** + * NAME + * flt_ot_cli_parse_debug - + * + * ARGUMENTS + * args - + * payload - + * appctx - + * private - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +static int flt_ot_cli_parse_debug(char **args, char *payload, struct appctx *appctx, void *private) +{ + char *err = NULL, *msg = NULL; + uint8_t value; + int retval = 0; + + FLT_OT_FUNC("%p, \"%s\", %p, %p", args, payload, appctx, private); + + FLT_OT_ARGS_DUMP(); + + if (FLT_OT_ARG_ISVALID(2)) { + value = flt_ot_strtoll(args[2], 0, 255, &err); + if (err == NULL) { + _HA_ATOMIC_STORE(&(flt_ot_debug.level), value); + + (void)memprintf(&msg, FLT_OT_CLI_CMD " : debug level set to %hhu", value); + } else { + retval = 1; + } + } else { + value = _HA_ATOMIC_LOAD(&(flt_ot_debug.level)); + + (void)memprintf(&msg, FLT_OT_CLI_CMD " : current debug level is %hhu", value); + } + + cmn_cli_set_msg(appctx, err, msg, CLI_ST_PRINT_FREE); + + FLT_OT_RETURN_INT(retval); +} + +#endif /* DEBUG_OT */ + + +/*** + * NAME + * flt_ot_cli_parse_disabled - + * + * ARGUMENTS + * args - + * payload - + * appctx - + * private - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +static int flt_ot_cli_parse_disabled(char **args, char *payload, struct appctx *appctx, void *private) +{ + char *msg = NULL; + bool value = (uintptr_t)private; + int retval = 0; + + FLT_OT_FUNC("%p, \"%s\", %p, %p", args, payload, appctx, private); + + FLT_OT_ARGS_DUMP(); + + FLT_OT_PROXIES_LIST_START() { + _HA_ATOMIC_STORE(&(conf->tracer->flag_disabled), value); + + (void)memprintf(&msg, "%s%s" FLT_OT_CLI_CMD " : filter %sabled", FLT_OT_CLI_MSG_CAT(msg), value ? "dis" : "en"); + } FLT_OT_PROXIES_LIST_END(); + + cmn_cli_set_msg(appctx, NULL, msg, CLI_ST_PRINT_FREE); + + FLT_OT_RETURN_INT(retval); +} + + +/*** + * NAME + * flt_ot_cli_parse_option - + * + * ARGUMENTS + * args - + * payload - + * appctx - + * private - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +static int flt_ot_cli_parse_option(char **args, char *payload, struct appctx *appctx, void *private) +{ + char *msg = NULL; + bool value = (uintptr_t)private; + int retval = 0; + + FLT_OT_FUNC("%p, \"%s\", %p, %p", args, payload, appctx, private); + + FLT_OT_ARGS_DUMP(); + + FLT_OT_PROXIES_LIST_START() { + _HA_ATOMIC_STORE(&(conf->tracer->flag_harderr), value); + + (void)memprintf(&msg, "%s%s" FLT_OT_CLI_CMD " : filter set %s-errors", FLT_OT_CLI_MSG_CAT(msg), value ? "hard" : "soft"); + } FLT_OT_PROXIES_LIST_END(); + + cmn_cli_set_msg(appctx, NULL, msg, CLI_ST_PRINT_FREE); + + FLT_OT_RETURN_INT(retval); +} + + +/*** + * NAME + * flt_ot_cli_parse_logging - + * + * ARGUMENTS + * args - + * payload - + * appctx - + * private - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +static int flt_ot_cli_parse_logging(char **args, char *payload, struct appctx *appctx, void *private) +{ + char *err = NULL, *msg = NULL; + uint8_t value; + int retval = 0; + + FLT_OT_FUNC("%p, \"%s\", %p, %p", args, payload, appctx, private); + + FLT_OT_ARGS_DUMP(); + + if (FLT_OT_ARG_ISVALID(2)) { + if (strcasecmp(args[2], FLT_OT_CLI_LOGGING_OFF) == 0) { + value = FLT_OT_LOGGING_OFF; + } + else if (strcasecmp(args[2], FLT_OT_CLI_LOGGING_ON) == 0) { + value = FLT_OT_LOGGING_ON; + } + else if (strcasecmp(args[2], FLT_OT_CLI_LOGGING_NOLOGNORM) == 0) { + value = FLT_OT_LOGGING_ON | FLT_OT_LOGGING_NOLOGNORM; + } + else { + (void)memprintf(&err, "'%s' : invalid value, use <" FLT_OT_CLI_LOGGING_OFF " | " FLT_OT_CLI_LOGGING_ON " | " FLT_OT_CLI_LOGGING_NOLOGNORM ">", args[2]); + + retval = 1; + } + + if (retval == 0) { + FLT_OT_PROXIES_LIST_START() { + _HA_ATOMIC_STORE(&(conf->tracer->logging), value); + + (void)memprintf(&msg, "%s%s" FLT_OT_CLI_CMD " : logging is %s", FLT_OT_CLI_MSG_CAT(msg), FLT_OT_CLI_LOGGING_STATE(value)); + } FLT_OT_PROXIES_LIST_END(); + } + } else { + FLT_OT_PROXIES_LIST_START() { + value = _HA_ATOMIC_LOAD(&(conf->tracer->logging)); + + (void)memprintf(&msg, "%s%s" FLT_OT_CLI_CMD " : logging is currently %s", FLT_OT_CLI_MSG_CAT(msg), FLT_OT_CLI_LOGGING_STATE(value)); + } FLT_OT_PROXIES_LIST_END(); + } + + cmn_cli_set_msg(appctx, err, msg, CLI_ST_PRINT_FREE); + + FLT_OT_RETURN_INT(retval); +} + + +/*** + * NAME + * flt_ot_cli_parse_rate - + * + * ARGUMENTS + * args - + * payload - + * appctx - + * private - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +static int flt_ot_cli_parse_rate(char **args, char *payload, struct appctx *appctx, void *private) +{ + char *err = NULL, *msg = NULL; + uint32_t value; + int retval = 0; + + FLT_OT_FUNC("%p, \"%s\", %p, %p", args, payload, appctx, private); + + FLT_OT_ARGS_DUMP(); + + if (FLT_OT_ARG_ISVALID(2)) { + value = FLT_OT_FLOAT_U32(flt_ot_strtod(args[2], 0.0, FLT_OT_RATE_LIMIT_MAX, &err), FLT_OT_RATE_LIMIT_MAX); + if (err == NULL) { + FLT_OT_PROXIES_LIST_START() { + _HA_ATOMIC_STORE(&(conf->tracer->rate_limit), value); + + (void)memprintf(&msg, "%s%s" FLT_OT_CLI_CMD " : rate limit set to %.2f", FLT_OT_CLI_MSG_CAT(msg), FLT_OT_U32_FLOAT(value, FLT_OT_RATE_LIMIT_MAX)); + } FLT_OT_PROXIES_LIST_END(); + } else { + retval = 1; + } + } else { + FLT_OT_PROXIES_LIST_START() { + value = _HA_ATOMIC_LOAD(&(conf->tracer->rate_limit)); + + (void)memprintf(&msg, "%s%s" FLT_OT_CLI_CMD " : current rate limit is %.2f", FLT_OT_CLI_MSG_CAT(msg), FLT_OT_U32_FLOAT(value, FLT_OT_RATE_LIMIT_MAX)); + } FLT_OT_PROXIES_LIST_END(); + } + + cmn_cli_set_msg(appctx, err, msg, CLI_ST_PRINT_FREE); + + FLT_OT_RETURN_INT(retval); +} + + +/*** + * NAME + * flt_ot_cli_parse_status - + * + * ARGUMENTS + * args - + * payload - + * appctx - + * private - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +static int flt_ot_cli_parse_status(char **args, char *payload, struct appctx *appctx, void *private) +{ + const char *nl = ""; + char *msg = NULL; + int retval = 0; + + FLT_OT_FUNC("%p, \"%s\", %p, %p", args, payload, appctx, private); + + FLT_OT_ARGS_DUMP(); + flt_ot_filters_dump(); + + (void)memprintf(&msg, " " FLT_OT_OPT_NAME " filter status\n" FLT_OT_STR_DASH_78); +#ifdef DEBUG_OT + (void)memprintf(&msg, "%s\n debug level: 0x%02hhx\n", msg, flt_ot_debug.level); +#endif + + FLT_OT_PROXIES_LIST_START() { + (void)memprintf(&msg, "%s\n%s filter %s\n", msg, nl, conf->id); + (void)memprintf(&msg, "%s configuration: %s\n", msg, conf->cfg_file); + (void)memprintf(&msg, "%s disable count: %" PRIu64 " %" PRIu64 "\n\n", msg, conf->cnt.disabled[0], conf->cnt.disabled[1]); + (void)memprintf(&msg, "%s tracer %s\n", msg, conf->tracer->id); + (void)memprintf(&msg, "%s configuration: %s\n", msg, conf->tracer->config); + (void)memprintf(&msg, "%s plugin: %s\n", msg, conf->tracer->plugin); + (void)memprintf(&msg, "%s rate limit: %.2f %%\n", msg, FLT_OT_U32_FLOAT(conf->tracer->rate_limit, FLT_OT_RATE_LIMIT_MAX)); + (void)memprintf(&msg, "%s hard errors: %s\n", msg, FLT_OT_STR_FLAG_YN(conf->tracer->flag_harderr)); + (void)memprintf(&msg, "%s disabled: %s\n", msg, FLT_OT_STR_FLAG_YN(conf->tracer->flag_disabled)); + (void)memprintf(&msg, "%s logging: %s\n", msg, FLT_OT_CLI_LOGGING_STATE(conf->tracer->logging)); + (void)memprintf(&msg, "%s analyzers: %08x", msg, conf->tracer->analyzers); + + nl = "\n"; + } FLT_OT_PROXIES_LIST_END(); + + cmn_cli_set_msg(appctx, NULL, msg, CLI_ST_PRINT_FREE); + + FLT_OT_RETURN_INT(retval); +} + + +static struct cli_kw_list cli_kws = { { }, { +#ifdef DEBUG_OT + { { FLT_OT_CLI_CMD, "debug", NULL }, FLT_OT_CLI_CMD " debug [level] : set the OT filter debug level (default: get current debug level)", flt_ot_cli_parse_debug, NULL, NULL, NULL, 0 }, +#endif + { { FLT_OT_CLI_CMD, "disable", NULL }, FLT_OT_CLI_CMD " disable : disable the OT filter", flt_ot_cli_parse_disabled, NULL, NULL, (void *)1, 0 }, + { { FLT_OT_CLI_CMD, "enable", NULL }, FLT_OT_CLI_CMD " enable : enable the OT filter", flt_ot_cli_parse_disabled, NULL, NULL, (void *)0, 0 }, + { { FLT_OT_CLI_CMD, "soft-errors", NULL }, FLT_OT_CLI_CMD " soft-errors : turning off hard-errors mode", flt_ot_cli_parse_option, NULL, NULL, (void *)0, 0 }, + { { FLT_OT_CLI_CMD, "hard-errors", NULL }, FLT_OT_CLI_CMD " hard-errors : enabling hard-errors mode", flt_ot_cli_parse_option, NULL, NULL, (void *)1, 0 }, + { { FLT_OT_CLI_CMD, "logging", NULL }, FLT_OT_CLI_CMD " logging [state] : set logging state (default: get current logging state)", flt_ot_cli_parse_logging, NULL, NULL, NULL, 0 }, + { { FLT_OT_CLI_CMD, "rate", NULL }, FLT_OT_CLI_CMD " rate [value] : set the rate limit (default: get current rate value)", flt_ot_cli_parse_rate, NULL, NULL, NULL, 0 }, + { { FLT_OT_CLI_CMD, "status", NULL }, FLT_OT_CLI_CMD " status : show the OT filter status", flt_ot_cli_parse_status, NULL, NULL, NULL, 0 }, + { /* END */ } +}}; + + +/*** + * NAME + * flt_ot_cli_init - + * + * ARGUMENTS + * This function takes no arguments. + * + * DESCRIPTION + * - + * + * RETURN VALUE + * This function does not return a value. + */ +void flt_ot_cli_init(void) +{ + FLT_OT_FUNC(""); + + /* Register CLI keywords. */ + cli_register_kw(&cli_kws); + + FLT_OT_RETURN(); +} + +/* + * Local variables: + * c-indent-level: 8 + * c-basic-offset: 8 + * End: + * + * vi: noexpandtab shiftwidth=8 tabstop=8 + */ diff --git a/addons/ot/src/conf.c b/addons/ot/src/conf.c new file mode 100644 index 0000000..d575e3a --- /dev/null +++ b/addons/ot/src/conf.c @@ -0,0 +1,767 @@ +/*** + * Copyright 2020 HAProxy Technologies + * + * This file is part of the HAProxy OpenTracing filter. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include "include.h" + + +/*** + * NAME + * flt_ot_conf_hdr_init - + * + * ARGUMENTS + * size - + * id - + * linenum - + * head - + * err - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +static void *flt_ot_conf_hdr_init(size_t size, const char *id, int linenum, struct list *head, char **err) +{ + struct flt_ot_conf_hdr *retptr = NULL, *ptr; + + FLT_OT_FUNC("%zu, \"%s\", %d, %p, %p:%p", size, id, linenum, head, FLT_OT_DPTR_ARGS(err)); + + if (head != NULL) + list_for_each_entry(ptr, head, list) + if (strcmp(ptr->id, id) == 0) { + FLT_OT_ERR("'%s' : already defined", id); + + FLT_OT_RETURN_PTR(retptr); + } + + retptr = FLT_OT_CALLOC(1, size); + if (retptr != NULL) { + retptr->id_len = strlen(id); + if (retptr->id_len >= FLT_OT_ID_MAXLEN) + FLT_OT_ERR("'%s' : name too long", id); + else + retptr->id = FLT_OT_STRDUP(id); + + if (retptr->id == NULL) + FLT_OT_FREE_CLEAR(retptr); + } + + if (retptr != NULL) { + retptr->cfg_line = linenum; + + if (head != NULL) + LIST_APPEND(head, &(retptr->list)); + } else { + FLT_OT_ERR("out of memory"); + } + + FLT_OT_RETURN_PTR(retptr); +} + + +/*** + * NAME + * flt_ot_conf_ph_init - + * + * ARGUMENTS + * id - + * linenum - + * head - + * err - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +struct flt_ot_conf_ph *flt_ot_conf_ph_init(const char *id, int linenum, struct list *head, char **err) +{ + struct flt_ot_conf_ph *retptr; + + FLT_OT_FUNC("\"%s\", %d, %p, %p:%p", id, linenum, head, FLT_OT_DPTR_ARGS(err)); + + retptr = flt_ot_conf_hdr_init(sizeof(*retptr), id, linenum, head, err); + if (retptr != NULL) + FLT_OT_DBG_CONF_PH("- init ", retptr); + + FLT_OT_RETURN_PTR(retptr); +} + + +/*** + * NAME + * flt_ot_conf_ph_free - + * + * ARGUMENTS + * ptr - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * This function does not return a value. + */ +void flt_ot_conf_ph_free(struct flt_ot_conf_ph **ptr) +{ + FLT_OT_FUNC("%p:%p", FLT_OT_DPTR_ARGS(ptr)); + + if ((ptr == NULL) || (*ptr == NULL)) + FLT_OT_RETURN(); + + FLT_OT_DBG_CONF_PH("- free ", *ptr); + + FLT_OT_FREE((*ptr)->id); + FLT_OT_LIST_DEL(&((*ptr)->list)); + FLT_OT_FREE_CLEAR(*ptr); + + FLT_OT_RETURN(); +} + + +/*** + * NAME + * flt_ot_conf_sample_expr_init - + * + * ARGUMENTS + * id - + * linenum - + * head - + * err - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +struct flt_ot_conf_sample_expr *flt_ot_conf_sample_expr_init(const char *id, int linenum, struct list *head, char **err) +{ + struct flt_ot_conf_sample_expr *retptr; + + FLT_OT_FUNC("\"%s\", %d, %p, %p:%p", id, linenum, head, FLT_OT_DPTR_ARGS(err)); + + retptr = flt_ot_conf_hdr_init(sizeof(*retptr), id, linenum, head, err); + if (retptr != NULL) + FLT_OT_DBG_CONF_SAMPLE_EXPR("- init ", retptr); + + FLT_OT_RETURN_PTR(retptr); +} + + +/*** + * NAME + * flt_ot_conf_sample_expr_free - + * + * ARGUMENTS + * ptr - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * This function does not return a value. + */ +void flt_ot_conf_sample_expr_free(struct flt_ot_conf_sample_expr **ptr) +{ + FLT_OT_FUNC("%p:%p", FLT_OT_DPTR_ARGS(ptr)); + + if ((ptr == NULL) || (*ptr == NULL)) + FLT_OT_RETURN(); + + FLT_OT_DBG_CONF_SAMPLE_EXPR("- free ", *ptr); + + FLT_OT_FREE((*ptr)->value); + release_sample_expr((*ptr)->expr); + FLT_OT_LIST_DEL(&((*ptr)->list)); + FLT_OT_FREE_CLEAR(*ptr); + + FLT_OT_RETURN(); +} + + +/*** + * NAME + * flt_ot_conf_sample_init - + * + * ARGUMENTS + * args - + * linenum - + * head - + * err - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +struct flt_ot_conf_sample *flt_ot_conf_sample_init(char **args, int linenum, struct list *head, char **err) +{ + struct flt_ot_conf_sample *retptr; + + FLT_OT_FUNC("%p, %d, %p, %p:%p", args, linenum, head, FLT_OT_DPTR_ARGS(err)); + + retptr = flt_ot_conf_hdr_init(sizeof(*retptr), args[1], linenum, head, err); + if (retptr == NULL) + FLT_OT_RETURN_PTR(retptr); + + flt_ot_args_to_str(args, 2, &(retptr->value)); + if (retptr->value == NULL) { + FLT_OT_FREE_CLEAR(retptr); + + FLT_OT_RETURN_PTR(retptr); + } + + retptr->num_exprs = flt_ot_args_count(args) - 2; + LIST_INIT(&(retptr->exprs)); + + FLT_OT_DBG_CONF_SAMPLE("- init ", retptr); + + FLT_OT_RETURN_PTR(retptr); +} + + +/*** + * NAME + * flt_ot_conf_sample_free - + * + * ARGUMENTS + * ptr - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * This function does not return a value. + */ +void flt_ot_conf_sample_free(struct flt_ot_conf_sample **ptr) +{ + FLT_OT_FUNC("%p:%p", FLT_OT_DPTR_ARGS(ptr)); + + if ((ptr == NULL) || (*ptr == NULL)) + FLT_OT_RETURN(); + + FLT_OT_DBG_CONF_SAMPLE("- free ", *ptr); + + FLT_OT_FREE((*ptr)->key); + FLT_OT_FREE((*ptr)->value); + FLT_OT_LIST_DESTROY(sample_expr, &((*ptr)->exprs)); + FLT_OT_LIST_DEL(&((*ptr)->list)); + FLT_OT_FREE_CLEAR(*ptr); + + FLT_OT_RETURN(); +} + + +/*** + * NAME + * flt_ot_conf_str_init - + * + * ARGUMENTS + * id - + * linenum - + * head - + * err - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +struct flt_ot_conf_str *flt_ot_conf_str_init(const char *id, int linenum, struct list *head, char **err) +{ + struct flt_ot_conf_str *retptr; + + FLT_OT_FUNC("\"%s\", %d, %p, %p:%p", id, linenum, head, FLT_OT_DPTR_ARGS(err)); + + retptr = flt_ot_conf_hdr_init(sizeof(*retptr), id, linenum, head, err); + if (retptr != NULL) + FLT_OT_DBG_CONF_STR("- init ", retptr); + + FLT_OT_RETURN_PTR(retptr); +} + + +/*** + * NAME + * flt_ot_conf_str_free - + * + * ARGUMENTS + * ptr - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * This function does not return a value. + */ +void flt_ot_conf_str_free(struct flt_ot_conf_str **ptr) +{ + FLT_OT_FUNC("%p:%p", FLT_OT_DPTR_ARGS(ptr)); + + if ((ptr == NULL) || (*ptr == NULL)) + FLT_OT_RETURN(); + + FLT_OT_DBG_CONF_STR("- free ", *ptr); + + FLT_OT_FREE((*ptr)->str); + FLT_OT_LIST_DEL(&((*ptr)->list)); + FLT_OT_FREE_CLEAR(*ptr); + + FLT_OT_RETURN(); +} + + +/*** + * NAME + * flt_ot_conf_context_init - + * + * ARGUMENTS + * id - + * linenum - + * head - + * err - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +struct flt_ot_conf_context *flt_ot_conf_context_init(const char *id, int linenum, struct list *head, char **err) +{ + struct flt_ot_conf_context *retptr; + + FLT_OT_FUNC("\"%s\", %d, %p, %p:%p", id, linenum, head, FLT_OT_DPTR_ARGS(err)); + + retptr = flt_ot_conf_hdr_init(sizeof(*retptr), id, linenum, head, err); + if (retptr != NULL) + FLT_OT_DBG_CONF_CONTEXT("- init ", retptr); + + FLT_OT_RETURN_PTR(retptr); +} + + +/*** + * NAME + * flt_ot_conf_context_free - + * + * ARGUMENTS + * ptr - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * This function does not return a value. + */ +void flt_ot_conf_context_free(struct flt_ot_conf_context **ptr) +{ + FLT_OT_FUNC("%p:%p", FLT_OT_DPTR_ARGS(ptr)); + + if ((ptr == NULL) || (*ptr == NULL)) + FLT_OT_RETURN(); + + FLT_OT_DBG_CONF_CONTEXT("- free ", *ptr); + + FLT_OT_FREE((*ptr)->id); + FLT_OT_LIST_DEL(&((*ptr)->list)); + FLT_OT_FREE_CLEAR(*ptr); + + FLT_OT_RETURN(); +} + + +/*** + * NAME + * flt_ot_conf_span_init - + * + * ARGUMENTS + * id - + * linenum - + * head - + * err - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +struct flt_ot_conf_span *flt_ot_conf_span_init(const char *id, int linenum, struct list *head, char **err) +{ + struct flt_ot_conf_span *retptr; + + FLT_OT_FUNC("\"%s\", %d, %p, %p:%p", id, linenum, head, FLT_OT_DPTR_ARGS(err)); + + retptr = flt_ot_conf_hdr_init(sizeof(*retptr), id, linenum, head, err); + if (retptr == NULL) + FLT_OT_RETURN_PTR(retptr); + + LIST_INIT(&(retptr->tags)); + LIST_INIT(&(retptr->logs)); + LIST_INIT(&(retptr->baggages)); + + FLT_OT_DBG_CONF_SPAN("- init ", retptr); + + FLT_OT_RETURN_PTR(retptr); +} + + +/*** + * NAME + * flt_ot_conf_span_free - + * + * ARGUMENTS + * ptr - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * This function does not return a value. + */ +void flt_ot_conf_span_free(struct flt_ot_conf_span **ptr) +{ + FLT_OT_FUNC("%p:%p", FLT_OT_DPTR_ARGS(ptr)); + + if ((ptr == NULL) || (*ptr == NULL)) + FLT_OT_RETURN(); + + FLT_OT_DBG_CONF_SPAN("- free ", *ptr); + + FLT_OT_FREE((*ptr)->id); + FLT_OT_FREE((*ptr)->ref_id); + FLT_OT_FREE((*ptr)->ctx_id); + FLT_OT_LIST_DESTROY(sample, &((*ptr)->tags)); + FLT_OT_LIST_DESTROY(sample, &((*ptr)->logs)); + FLT_OT_LIST_DESTROY(sample, &((*ptr)->baggages)); + FLT_OT_LIST_DEL(&((*ptr)->list)); + FLT_OT_FREE_CLEAR(*ptr); + + FLT_OT_RETURN(); +} + + +/*** + * NAME + * flt_ot_conf_scope_init - + * + * ARGUMENTS + * id - + * linenum - + * head - + * err - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +struct flt_ot_conf_scope *flt_ot_conf_scope_init(const char *id, int linenum, struct list *head, char **err) +{ + struct flt_ot_conf_scope *retptr = NULL; + + FLT_OT_FUNC("\"%s\", %d, %p, %p:%p", id, linenum, head, FLT_OT_DPTR_ARGS(err)); + + retptr = flt_ot_conf_hdr_init(sizeof(*retptr), id, linenum, head, err); + if (retptr == NULL) + FLT_OT_RETURN_PTR(retptr); + + LIST_INIT(&(retptr->acls)); + LIST_INIT(&(retptr->contexts)); + LIST_INIT(&(retptr->spans)); + LIST_INIT(&(retptr->finish)); + + FLT_OT_DBG_CONF_SCOPE("- init ", retptr); + + FLT_OT_RETURN_PTR(retptr); +} + +/*** + * NAME + * flt_ot_conf_scope_free - + * + * ARGUMENTS + * ptr - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * This function does not return a value. + */ +void flt_ot_conf_scope_free(struct flt_ot_conf_scope **ptr) +{ + struct acl *acl, *aclback; + + FLT_OT_FUNC("%p:%p", FLT_OT_DPTR_ARGS(ptr)); + + if ((ptr == NULL) || (*ptr == NULL)) + FLT_OT_RETURN(); + + FLT_OT_DBG_CONF_SCOPE("- free ", *ptr); + + FLT_OT_FREE((*ptr)->id); + list_for_each_entry_safe(acl, aclback, &((*ptr)->acls), list) { + prune_acl(acl); + FLT_OT_LIST_DEL(&(acl->list)); + FLT_OT_FREE(acl); + } + if ((*ptr)->cond != NULL) { + prune_acl_cond((*ptr)->cond); + FLT_OT_FREE((*ptr)->cond); + } + FLT_OT_LIST_DESTROY(context, &((*ptr)->contexts)); + FLT_OT_LIST_DESTROY(span, &((*ptr)->spans)); + FLT_OT_LIST_DESTROY(str, &((*ptr)->finish)); + FLT_OT_LIST_DEL(&((*ptr)->list)); + FLT_OT_FREE_CLEAR(*ptr); + + FLT_OT_RETURN(); +} + + +/*** + * NAME + * flt_ot_conf_group_init - + * + * ARGUMENTS + * id - + * linenum - + * head - + * err - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +struct flt_ot_conf_group *flt_ot_conf_group_init(const char *id, int linenum, struct list *head, char **err) +{ + struct flt_ot_conf_group *retptr; + + FLT_OT_FUNC("\"%s\", %d, %p, %p:%p", id, linenum, head, FLT_OT_DPTR_ARGS(err)); + + retptr = flt_ot_conf_hdr_init(sizeof(*retptr), id, linenum, head, err); + if (retptr == NULL) + FLT_OT_RETURN_PTR(retptr); + + LIST_INIT(&(retptr->ph_scopes)); + + FLT_OT_DBG_CONF_GROUP("- init ", retptr); + + FLT_OT_RETURN_PTR(retptr); +} + + +/*** + * NAME + * flt_ot_conf_group_free - + * + * ARGUMENTS + * ptr - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * This function does not return a value. + */ +void flt_ot_conf_group_free(struct flt_ot_conf_group **ptr) +{ + FLT_OT_FUNC("%p:%p", FLT_OT_DPTR_ARGS(ptr)); + + if ((ptr == NULL) || (*ptr == NULL)) + FLT_OT_RETURN(); + + FLT_OT_DBG_CONF_GROUP("- free ", *ptr); + + FLT_OT_FREE((*ptr)->id); + FLT_OT_LIST_DESTROY(ph_scope, &((*ptr)->ph_scopes)); + FLT_OT_LIST_DEL(&((*ptr)->list)); + FLT_OT_FREE_CLEAR(*ptr); + + FLT_OT_RETURN(); +} + + +/*** + * NAME + * flt_ot_conf_tracer_init - + * + * ARGUMENTS + * id - + * linenum - + * err - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +struct flt_ot_conf_tracer *flt_ot_conf_tracer_init(const char *id, int linenum, char **err) +{ + struct flt_ot_conf_tracer *retptr; + + FLT_OT_FUNC("\"%s\", %d, %p:%p", id, linenum, FLT_OT_DPTR_ARGS(err)); + + retptr = flt_ot_conf_hdr_init(sizeof(*retptr), id, linenum, NULL, err); + if (retptr == NULL) + FLT_OT_RETURN_PTR(retptr); + + retptr->rate_limit = FLT_OT_FLOAT_U32(FLT_OT_RATE_LIMIT_MAX, FLT_OT_RATE_LIMIT_MAX); + init_new_proxy(&(retptr->proxy_log)); + LIST_INIT(&(retptr->acls)); + LIST_INIT(&(retptr->ph_groups)); + LIST_INIT(&(retptr->ph_scopes)); + + FLT_OT_DBG_CONF_TRACER("- init ", retptr); + + FLT_OT_RETURN_PTR(retptr); +} + + +/*** + * NAME + * flt_ot_conf_tracer_free - + * + * ARGUMENTS + * ptr - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * This function does not return a value. + */ +void flt_ot_conf_tracer_free(struct flt_ot_conf_tracer **ptr) +{ + struct acl *acl, *aclback; + struct logsrv *logsrv, *logsrvback; + + FLT_OT_FUNC("%p:%p", FLT_OT_DPTR_ARGS(ptr)); + + if ((ptr == NULL) || (*ptr == NULL)) + FLT_OT_RETURN(); + + FLT_OT_DBG_CONF_TRACER("- free ", *ptr); + + FLT_OT_FREE((*ptr)->id); + FLT_OT_FREE((*ptr)->config); + FLT_OT_FREE((*ptr)->cfgbuf); + FLT_OT_FREE((*ptr)->plugin); + FLT_OT_DBG(2, "- deleting acls list %s", flt_ot_list_debug(&((*ptr)->acls))); + list_for_each_entry_safe(acl, aclback, &((*ptr)->acls), list) { + prune_acl(acl); + FLT_OT_LIST_DEL(&(acl->list)); + FLT_OT_FREE(acl); + } + FLT_OT_DBG(2, "- deleting proxy_log.logsrvs list %s", flt_ot_list_debug(&((*ptr)->proxy_log.logsrvs))); + list_for_each_entry_safe(logsrv, logsrvback, &((*ptr)->proxy_log.logsrvs), list) { + LIST_DELETE(&(logsrv->list)); + FLT_OT_FREE(logsrv); + } + FLT_OT_LIST_DESTROY(ph_group, &((*ptr)->ph_groups)); + FLT_OT_LIST_DESTROY(ph_scope, &((*ptr)->ph_scopes)); + FLT_OT_FREE_CLEAR(*ptr); + + FLT_OT_RETURN(); +} + + +/*** + * NAME + * flt_ot_conf_init - + * + * ARGUMENTS + * px - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +struct flt_ot_conf *flt_ot_conf_init(struct proxy *px) +{ + struct flt_ot_conf *retptr; + + FLT_OT_FUNC("%p", px); + + retptr = FLT_OT_CALLOC(1, sizeof(*retptr)); + if (retptr == NULL) + FLT_OT_RETURN_PTR(retptr); + + retptr->proxy = px; + LIST_INIT(&(retptr->groups)); + LIST_INIT(&(retptr->scopes)); + + FLT_OT_DBG_CONF("- init ", retptr); + + FLT_OT_RETURN_PTR(retptr); +} + + +/*** + * NAME + * flt_ot_conf_free - + * + * ARGUMENTS + * ptr - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * This function does not return a value. + */ +void flt_ot_conf_free(struct flt_ot_conf **ptr) +{ + FLT_OT_FUNC("%p:%p", FLT_OT_DPTR_ARGS(ptr)); + + if ((ptr == NULL) || (*ptr == NULL)) + FLT_OT_RETURN(); + + FLT_OT_DBG_CONF("- free ", *ptr); + + FLT_OT_FREE((*ptr)->id); + FLT_OT_FREE((*ptr)->cfg_file); + flt_ot_conf_tracer_free(&((*ptr)->tracer)); + FLT_OT_LIST_DESTROY(group, &((*ptr)->groups)); + FLT_OT_LIST_DESTROY(scope, &((*ptr)->scopes)); + FLT_OT_FREE_CLEAR(*ptr); + + FLT_OT_RETURN(); +} + +/* + * Local variables: + * c-indent-level: 8 + * c-basic-offset: 8 + * End: + * + * vi: noexpandtab shiftwidth=8 tabstop=8 + */ diff --git a/addons/ot/src/event.c b/addons/ot/src/event.c new file mode 100644 index 0000000..dc29d52 --- /dev/null +++ b/addons/ot/src/event.c @@ -0,0 +1,338 @@ +/*** + * Copyright 2020 HAProxy Technologies + * + * This file is part of the HAProxy OpenTracing filter. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include "include.h" + + +#define FLT_OT_EVENT_DEF(a,b,c,d,e,f) { AN_##b##_##a, SMP_OPT_DIR_##b, SMP_VAL_FE_##c, SMP_VAL_BE_##d, e, f }, +const struct flt_ot_event_data flt_ot_event_data[FLT_OT_EVENT_MAX] = { FLT_OT_EVENT_DEFINES }; +#undef FLT_OT_EVENT_DEF + + +/*** + * NAME + * flt_ot_scope_run_span - + * + * ARGUMENTS + * s - + * f - + * chn - + * dir - + * span - + * data - + * conf_span - + * ts - + * err - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * Returns a negative value if an error occurs, 0 if it needs to wait, + * any other value otherwise. + */ +static int flt_ot_scope_run_span(struct stream *s, struct filter *f, struct channel *chn, uint dir, struct flt_ot_scope_span *span, struct flt_ot_scope_data *data, const struct flt_ot_conf_span *conf_span, const struct timespec *ts, char **err) +{ + struct flt_ot_conf *conf = FLT_OT_CONF(f); + int retval = FLT_OT_RET_OK; + + FLT_OT_FUNC("%p, %p, %p, %u, %p, %p, %p, %p, %p:%p", s, f, chn, dir, span, data, conf_span, ts, FLT_OT_DPTR_ARGS(err)); + + if (span == NULL) + FLT_OT_RETURN_INT(retval); + + if (span->span == NULL) { + span->span = ot_span_init(conf->tracer->tracer, span->id, ts, NULL, span->ref_type, FLT_OT_DEREF(span->ref_ctx, idx, -1), span->ref_span, data->tags, data->num_tags, err); + if (span->span == NULL) + retval = FLT_OT_RET_ERROR; + } + else if (data->num_tags > 0) + if (ot_span_tag(span->span, data->tags, data->num_tags) == -1) + retval = FLT_OT_RET_ERROR; + + if ((span->span != NULL) && (data->baggage != NULL)) + if (ot_span_set_baggage(span->span, data->baggage) == -1) + retval = FLT_OT_RET_ERROR; + + if ((span->span != NULL) && (data->num_log_fields > 0)) + if (ot_span_log(span->span, data->log_fields, data->num_log_fields) == -1) + retval = FLT_OT_RET_ERROR; + + if ((span->span != NULL) && (conf_span->ctx_id != NULL)) { + struct otc_http_headers_writer writer; + struct otc_text_map *text_map = NULL; + struct otc_span_context *span_ctx; + + span_ctx = ot_inject_http_headers(conf->tracer->tracer, span->span, &writer, err); + if (span_ctx != NULL) { + int i = 0; + + if (conf_span->ctx_flags & (FLT_OT_CTX_USE_VARS | FLT_OT_CTX_USE_HEADERS)) { + for (text_map = &(writer.text_map); i < text_map->count; i++) { +#ifdef USE_OT_VARS + if (!(conf_span->ctx_flags & FLT_OT_CTX_USE_VARS)) + /* Do nothing. */; + else if (flt_ot_var_register(FLT_OT_VARS_SCOPE, conf_span->ctx_id, text_map->key[i], err) == -1) + retval = FLT_OT_RET_ERROR; + else if (flt_ot_var_set(s, FLT_OT_VARS_SCOPE, conf_span->ctx_id, text_map->key[i], text_map->value[i], dir, err) == -1) + retval = FLT_OT_RET_ERROR; +#endif + + if (!(conf_span->ctx_flags & FLT_OT_CTX_USE_HEADERS)) + /* Do nothing. */; + else if (flt_ot_http_header_set(chn, conf_span->ctx_id, text_map->key[i], text_map->value[i], err) == -1) + retval = FLT_OT_RET_ERROR; + } + } + + span_ctx->destroy(&span_ctx); + otc_text_map_destroy(&text_map, OTC_TEXT_MAP_FREE_KEY | OTC_TEXT_MAP_FREE_VALUE); + } + } + + FLT_OT_RETURN_INT(retval); +} + + +/*** + * NAME + * flt_ot_scope_run - + * + * ARGUMENTS + * s - + * f - + * chn - + * conf_scope - + * ts - + * dir - + * err - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * Returns a negative value if an error occurs, 0 if it needs to wait, + * any other value otherwise. + */ +int flt_ot_scope_run(struct stream *s, struct filter *f, struct channel *chn, struct flt_ot_conf_scope *conf_scope, const struct timespec *ts, uint dir, char **err) +{ + struct flt_ot_conf *conf = FLT_OT_CONF(f); + struct flt_ot_conf_context *conf_ctx; + struct flt_ot_conf_span *conf_span; + struct flt_ot_conf_str *finish; + struct timespec ts_now; + int retval = FLT_OT_RET_OK; + + FLT_OT_FUNC("%p, %p, %p, %p, %p, %u, %p:%p", s, f, chn, conf_scope, ts, dir, FLT_OT_DPTR_ARGS(err)); + + FLT_OT_DBG(3, "channel: %s, mode: %s (%s)", flt_ot_chn_label(chn), flt_ot_pr_mode(s), flt_ot_stream_pos(s)); + FLT_OT_DBG(3, "run scope '%s' %d", conf_scope->id, conf_scope->event); + FLT_OT_DBG_CONF_SCOPE("run scope ", conf_scope); + + if (ts == NULL) { + (void)clock_gettime(CLOCK_MONOTONIC, &ts_now); + + ts = &ts_now; + } + + if (conf_scope->cond != NULL) { + enum acl_test_res res; + int rc; + + res = acl_exec_cond(conf_scope->cond, s->be, s->sess, s, dir | SMP_OPT_FINAL); + rc = acl_pass(res); + if (conf_scope->cond->pol == ACL_COND_UNLESS) + rc = !rc; + + FLT_OT_DBG(3, "the ACL rule %s", rc ? "matches" : "does not match"); + + /* + * If the rule does not match, the current scope is skipped. + * + * If it is a root span, further processing of the session is + * disabled. As soon as the first span is encountered which + * is marked as root, further search is interrupted. + */ + if (!rc) { + list_for_each_entry(conf_span, &(conf_scope->spans), list) + if (conf_span->flag_root) { + FLT_OT_DBG(0, "session disabled"); + + FLT_OT_RT_CTX(f->ctx)->flag_disabled = 1; + + _HA_ATOMIC_ADD(conf->cnt.disabled + 0, 1); + + break; + } + + FLT_OT_RETURN_INT(retval); + } + } + + list_for_each_entry(conf_ctx, &(conf_scope->contexts), list) { + struct otc_text_map *text_map = NULL; + + FLT_OT_DBG(3, "run context '%s' -> '%s'", conf_scope->id, conf_ctx->id); + FLT_OT_DBG_CONF_CONTEXT("run context ", conf_ctx); + + /* + * The OpenTracing context is read from the HTTP header + * or from HAProxy variables. + */ + if (conf_ctx->flags & FLT_OT_CTX_USE_HEADERS) + text_map = flt_ot_http_headers_get(chn, conf_ctx->id, conf_ctx->id_len, err); +#ifdef USE_OT_VARS + else + text_map = flt_ot_vars_get(s, FLT_OT_VARS_SCOPE, conf_ctx->id, dir, err); +#endif + + if (text_map != NULL) { + if (flt_ot_scope_context_init(f->ctx, conf->tracer->tracer, conf_ctx->id, conf_ctx->id_len, text_map, dir, err) == NULL) + retval = FLT_OT_RET_ERROR; + + otc_text_map_destroy(&text_map, OTC_TEXT_MAP_FREE_KEY | OTC_TEXT_MAP_FREE_VALUE); + } else { + retval = FLT_OT_RET_ERROR; + } + } + + list_for_each_entry(conf_span, &(conf_scope->spans), list) { + struct flt_ot_scope_data data; + struct flt_ot_scope_span *span; + struct flt_ot_conf_sample *sample; + + FLT_OT_DBG(3, "run span '%s' -> '%s'", conf_scope->id, conf_span->id); + FLT_OT_DBG_CONF_SPAN("run span ", conf_span); + + (void)memset(&data, 0, sizeof(data)); + + span = flt_ot_scope_span_init(f->ctx, conf_span->id, conf_span->id_len, conf_span->ref_type, conf_span->ref_id, conf_span->ref_id_len, dir, err); + if (span == NULL) + retval = FLT_OT_RET_ERROR; + + list_for_each_entry(sample, &(conf_span->tags), list) { + FLT_OT_DBG(3, "adding tag '%s' -> '%s'", sample->key, sample->value); + + if (flt_ot_sample_add(s, dir, sample, &data, FLT_OT_EVENT_SAMPLE_TAG, err) == FLT_OT_RET_ERROR) + retval = FLT_OT_RET_ERROR; + } + + list_for_each_entry(sample, &(conf_span->logs), list) { + FLT_OT_DBG(3, "adding log '%s' -> '%s'", sample->key, sample->value); + + if (flt_ot_sample_add(s, dir, sample, &data, FLT_OT_EVENT_SAMPLE_LOG, err) == FLT_OT_RET_ERROR) + retval = FLT_OT_RET_ERROR; + } + + list_for_each_entry(sample, &(conf_span->baggages), list) { + FLT_OT_DBG(3, "adding baggage '%s' -> '%s'", sample->key, sample->value); + + if (flt_ot_sample_add(s, dir, sample, &data, FLT_OT_EVENT_SAMPLE_BAGGAGE, err) == FLT_OT_RET_ERROR) + retval = FLT_OT_RET_ERROR; + } + + if (retval != FLT_OT_RET_ERROR) + if (flt_ot_scope_run_span(s, f, chn, dir, span, &data, conf_span, ts, err) == FLT_OT_RET_ERROR) + retval = FLT_OT_RET_ERROR; + + flt_ot_scope_data_free(&data); + } + + list_for_each_entry(finish, &(conf_scope->finish), list) + if (flt_ot_scope_finish_mark(f->ctx, finish->str, finish->str_len) == -1) + retval = FLT_OT_RET_ERROR; + + flt_ot_scope_finish_marked(f->ctx, ts); + flt_ot_scope_free_unused(f->ctx, chn); + + FLT_OT_RETURN_INT(retval); +} + + +/*** + * NAME + * flt_ot_event_run - + * + * ARGUMENTS + * s - + * f - + * chn - + * event - + * err - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * Returns a negative value if an error occurs, 0 if it needs to wait, + * any other value otherwise. + */ +int flt_ot_event_run(struct stream *s, struct filter *f, struct channel *chn, int event, char **err) +{ + struct flt_ot_conf *conf = FLT_OT_CONF(f); + struct flt_ot_conf_scope *conf_scope; + struct timespec ts; + int retval = FLT_OT_RET_OK; + + FLT_OT_FUNC("%p, %p, %p, %d, %p:%p", s, f, chn, event, FLT_OT_DPTR_ARGS(err)); + + FLT_OT_DBG(3, "channel: %s, mode: %s (%s)", flt_ot_chn_label(chn), flt_ot_pr_mode(s), flt_ot_stream_pos(s)); + FLT_OT_DBG(3, "run event '%s' %d", flt_ot_event_data[event].name, event); + +#ifdef DEBUG_OT + _HA_ATOMIC_ADD(conf->cnt.event[event].htx + (htx_is_empty(htxbuf(&(chn->buf))) ? 1 : 0), 1); +#endif + + FLT_OT_RT_CTX(f->ctx)->analyzers |= flt_ot_event_data[event].an_bit; + + /* All spans should be created/completed at the same time. */ + (void)clock_gettime(CLOCK_MONOTONIC, &ts); + + /* + * It is possible that there are defined multiple scopes that use the + * same event. Therefore, there must not be a 'break' here, ie an + * exit from the 'for' loop. + */ + list_for_each_entry(conf_scope, &(conf->scopes), list) { + if (conf_scope->event != event) + /* Do nothing. */; + else if (!conf_scope->flag_used) + FLT_OT_DBG(3, "scope '%s' %d not used", conf_scope->id, conf_scope->event); + else if (flt_ot_scope_run(s, f, chn, conf_scope, &ts, flt_ot_event_data[event].smp_opt_dir, err) == FLT_OT_RET_ERROR) + retval = FLT_OT_RET_ERROR; + } + +#ifdef USE_OT_VARS + flt_ot_vars_dump(s); +#endif + flt_ot_http_headers_dump(chn); + + FLT_OT_DBG(3, "event = %d, chn = %p, s->req = %p, s->res = %p", event, chn, &(s->req), &(s->res)); + + FLT_OT_RETURN_INT(retval); +} + +/* + * Local variables: + * c-indent-level: 8 + * c-basic-offset: 8 + * End: + * + * vi: noexpandtab shiftwidth=8 tabstop=8 + */ diff --git a/addons/ot/src/filter.c b/addons/ot/src/filter.c new file mode 100644 index 0000000..cf67fd2 --- /dev/null +++ b/addons/ot/src/filter.c @@ -0,0 +1,1176 @@ +/*** + * Copyright 2020 HAProxy Technologies + * + * This file is part of the HAProxy OpenTracing filter. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include "include.h" + + +/* + * OpenTracing filter id, used to identify OpenTracing filters. + * The name of this variable is consistent with the other filter names + * declared in include/haproxy/filters.h . + */ +const char *ot_flt_id = "the OpenTracing filter"; + + +/*** + * NAME + * flt_ot_is_disabled - + * + * ARGUMENTS + * f - + * event - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +bool flt_ot_is_disabled(const struct filter *f FLT_OT_DBG_ARGS(, int event)) +{ +#ifdef DEBUG_OT + const struct flt_ot_conf *conf = FLT_OT_CONF(f); + const char *msg; +#endif + bool retval; + + retval = FLT_OT_RT_CTX(f->ctx)->flag_disabled ? 1 : 0; + +#ifdef DEBUG_OT + msg = retval ? " (disabled)" : ""; + + if (FLT_OT_IN_RANGE(event, 0, FLT_OT_EVENT_MAX - 1)) + FLT_OT_DBG(2, "filter '%s', type: %s, event: '%s' %d%s", conf->id, flt_ot_type(f), flt_ot_event_data[event].name, event, msg); + else + FLT_OT_DBG(2, "filter '%s', type: %s%s", conf->id, flt_ot_type(f), msg); +#endif + + return retval; +} + + +/*** + * NAME + * flt_ot_return_int - + * + * ARGUMENTS + * f - + * err - + * retval - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +static int flt_ot_return_int(const struct filter *f, char **err, int retval) +{ + struct flt_ot_runtime_context *rt_ctx = f->ctx; + + if ((retval == FLT_OT_RET_ERROR) || ((err != NULL) && (*err != NULL))) { + if (rt_ctx->flag_harderr) { + FLT_OT_DBG(1, "WARNING: filter hard-error (disabled)"); + + rt_ctx->flag_disabled = 1; + + _HA_ATOMIC_ADD(FLT_OT_CONF(f)->cnt.disabled + 1, 1); + } else { + FLT_OT_DBG(1, "WARNING: filter soft-error"); + } + + retval = FLT_OT_RET_OK; + } + + FLT_OT_ERR_FREE(*err); + + return retval; +} + + +/*** + * NAME + * flt_ot_return_void - + * + * ARGUMENTS + * f - + * err - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * This function does not return a value. + */ +static void flt_ot_return_void(const struct filter *f, char **err) +{ + struct flt_ot_runtime_context *rt_ctx = f->ctx; + + if ((err != NULL) && (*err != NULL)) { + if (rt_ctx->flag_harderr) { + FLT_OT_DBG(1, "WARNING: filter hard-error (disabled)"); + + rt_ctx->flag_disabled = 1; + + _HA_ATOMIC_ADD(FLT_OT_CONF(f)->cnt.disabled + 1, 1); + } else { + FLT_OT_DBG(1, "WARNING: filter soft-error"); + } + } + + FLT_OT_ERR_FREE(*err); +} + + +/*** + * NAME + * flt_ot_init - Initialize the filter. + * + * ARGUMENTS + * p - + * fconf - + * + * DESCRIPTION + * It initializes the filter for a proxy. You may define this callback + * if you need to complete your filter configuration. + * + * RETURN VALUE + * Returns a negative value if an error occurs, any other value otherwise. + */ +static int flt_ot_init(struct proxy *p, struct flt_conf *fconf) +{ + struct flt_ot_conf *conf = FLT_OT_DEREF(fconf, conf, NULL); + char *err = NULL; + int retval = FLT_OT_RET_ERROR; + + FLT_OT_FUNC("%p, %p", p, fconf); + + if (conf == NULL) + FLT_OT_RETURN_INT(retval); + + flt_ot_cli_init(); + + /* + * Initialize the OpenTracing library. + */ + retval = ot_init(&(conf->tracer->tracer), conf->tracer->plugin, &err); + if (retval != FLT_OT_RET_ERROR) + /* Do nothing. */; + else if (err != NULL) { + FLT_OT_ALERT("%s", err); + + FLT_OT_ERR_FREE(err); + } + + FLT_OT_RETURN_INT(retval); +} + + +/*** + * NAME + * flt_ot_deinit - Free resources allocated by the filter. + * + * ARGUMENTS + * p - + * fconf - + * + * DESCRIPTION + * It cleans up what the parsing function and the init callback have done. + * This callback is useful to release memory allocated for the filter + * configuration. + * + * RETURN VALUE + * This function does not return a value. + */ +static void flt_ot_deinit(struct proxy *p, struct flt_conf *fconf) +{ + struct flt_ot_conf **conf = (fconf == NULL) ? NULL : (typeof(conf))&(fconf->conf); +#ifdef DEBUG_OT + int i; +#endif + + FLT_OT_FUNC("%p, %p", p, fconf); + + if (conf == NULL) + FLT_OT_RETURN(); + + ot_debug(); + ot_close(&((*conf)->tracer->tracer)); + +#ifdef DEBUG_OT + FLT_OT_DBG(0, "--- used events ----------"); + for (i = 0; i < FLT_OT_TABLESIZE((*conf)->cnt.event); i++) + if ((*conf)->cnt.event[i].flag_used) + FLT_OT_DBG(0, " %02d: %" PRIu64 " / %" PRIu64, i, (*conf)->cnt.event[i].htx[0], (*conf)->cnt.event[i].htx[1]); +#endif + + flt_ot_conf_free(conf); + + FLT_OT_MEMINFO(); + + FLT_OT_RETURN(); +} + + +/*** + * NAME + * flt_ot_check - Check configuration of the filter for the specified proxy. + * + * ARGUMENTS + * p - + * fconf - + * + * DESCRIPTION + * Optionally, by implementing the flt_ot_check() callback, you add a + * step to check the internal configuration of your filter after the + * parsing phase, when the HAProxy configuration is fully defined. + * + * RETURN VALUE + * Returns the number of encountered errors. + */ +static int flt_ot_check(struct proxy *p, struct flt_conf *fconf) +{ + struct proxy *px; + struct flt_ot_conf *conf = FLT_OT_DEREF(fconf, conf, NULL); + struct flt_ot_conf_group *conf_group; + struct flt_ot_conf_scope *conf_scope; + struct flt_ot_conf_ph *ph_group, *ph_scope; + int retval = 0, scope_unused_cnt = 0, span_root_cnt = 0; + + FLT_OT_FUNC("%p, %p", p, fconf); + + if (conf == NULL) + FLT_OT_RETURN_INT(++retval); + + /* + * If only the proxy specified with the

parameter is checked, then + * no duplicate filters can be found that are not defined in the same + * configuration sections. + */ + for (px = proxies_list; px != NULL; px = px->next) { + struct flt_conf *fconf_tmp; + + FLT_OT_DBG(2, "proxy '%s'", px->id); + + /* + * The names of all OT filters (filter ID) should be checked, + * they must be unique. + */ + list_for_each_entry(fconf_tmp, &(px->filter_configs), list) + if ((fconf_tmp != fconf) && (fconf_tmp->id == ot_flt_id)) { + struct flt_ot_conf *conf_tmp = fconf_tmp->conf; + + FLT_OT_DBG(2, " OT filter '%s'", conf_tmp->id); + + if (strcmp(conf_tmp->id, conf->id) == 0) { + FLT_OT_ALERT("''%s' : duplicated filter ID'", conf_tmp->id); + + retval++; + } + } + } + + if (FLT_OT_DEREF(conf->tracer, id, NULL) == NULL) { + FLT_OT_ALERT("''%s' : no tracer found'", conf->id); + + retval++; + } + + /* + * Checking that all defined 'ot-group' sections have correctly declared + * 'ot-scope' sections (ie whether the declared 'ot-scope' sections have + * corresponding definitions). + */ + list_for_each_entry(conf_group, &(conf->groups), list) + list_for_each_entry(ph_scope, &(conf_group->ph_scopes), list) { + bool flag_found = 0; + + list_for_each_entry(conf_scope, &(conf->scopes), list) + if (strcmp(ph_scope->id, conf_scope->id) == 0) { + ph_scope->ptr = conf_scope; + conf_scope->flag_used = 1; + flag_found = 1; + + break; + } + + if (!flag_found) { + FLT_OT_ALERT("'" FLT_OT_PARSE_SECTION_GROUP_ID " '%s' : try to use undefined " FLT_OT_PARSE_SECTION_SCOPE_ID " '%s''", conf_group->id, ph_scope->id); + + retval++; + } + } + + if (conf->tracer != NULL) { + /* + * Checking that all declared 'groups' keywords have correctly + * defined 'ot-group' sections. + */ + list_for_each_entry(ph_group, &(conf->tracer->ph_groups), list) { + bool flag_found = 0; + + list_for_each_entry(conf_group, &(conf->groups), list) + if (strcmp(ph_group->id, conf_group->id) == 0) { + ph_group->ptr = conf_group; + conf_group->flag_used = 1; + flag_found = 1; + + break; + } + + if (!flag_found) { + FLT_OT_ALERT("'" FLT_OT_PARSE_SECTION_TRACER_ID " '%s' : try to use undefined " FLT_OT_PARSE_SECTION_GROUP_ID " '%s''", conf->tracer->id, ph_group->id); + + retval++; + } + } + + /* + * Checking that all declared 'scopes' keywords have correctly + * defined 'ot-scope' sections. + */ + list_for_each_entry(ph_scope, &(conf->tracer->ph_scopes), list) { + bool flag_found = 0; + + list_for_each_entry(conf_scope, &(conf->scopes), list) + if (strcmp(ph_scope->id, conf_scope->id) == 0) { + ph_scope->ptr = conf_scope; + conf_scope->flag_used = 1; + flag_found = 1; + + break; + } + + if (!flag_found) { + FLT_OT_ALERT("'" FLT_OT_PARSE_SECTION_TRACER_ID " '%s' : try to use undefined " FLT_OT_PARSE_SECTION_SCOPE_ID " '%s''", conf->tracer->id, ph_scope->id); + + retval++; + } + } + } + + FLT_OT_DBG(3, "--- filter '%s' configuration ----------", conf->id); + FLT_OT_DBG(3, "- defined spans ----------"); + + list_for_each_entry(conf_scope, &(conf->scopes), list) { + if (conf_scope->flag_used) { + struct flt_ot_conf_span *conf_span; + + /* + * In principle, only one span should be labeled + * as a root span. + */ + list_for_each_entry(conf_span, &(conf_scope->spans), list) { + FLT_OT_DBG_CONF_SPAN(" ", conf_span); + + span_root_cnt += conf_span->flag_root ? 1 : 0; + } + +#ifdef DEBUG_OT + conf->cnt.event[conf_scope->event].flag_used = 1; +#endif + + /* Set the flags of the analyzers used. */ + conf->tracer->analyzers |= flt_ot_event_data[conf_scope->event].an_bit; + } else { + FLT_OT_ALERT("''%s' : unused " FLT_OT_PARSE_SECTION_SCOPE_ID " '%s''", conf->id, conf_scope->id); + + scope_unused_cnt++; + } + } + + /* + * Unused scopes or a number of root spans other than one do not + * necessarily have to be errors, but it is good to print it when + * starting HAProxy. + */ + if (scope_unused_cnt > 0) + FLT_OT_ALERT("''%s' : %d scope(s) not in use'", conf->id, scope_unused_cnt); + + if (LIST_ISEMPTY(&(conf->scopes))) + /* Do nothing. */; + else if (span_root_cnt == 0) + FLT_OT_ALERT("''%s' : no span is marked as the root span'", conf->id); + else if (span_root_cnt > 1) + FLT_OT_ALERT("''%s' : multiple spans are marked as the root span'", conf->id); + + FLT_OT_DBG_LIST(conf, group, "", "defined", _group, + FLT_OT_DBG_CONF_GROUP(" ", _group); + FLT_OT_DBG_LIST(_group, ph_scope, " ", "used", _scope, FLT_OT_DBG_CONF_PH(" ", _scope))); + FLT_OT_DBG_LIST(conf, scope, "", "defined", _scope, FLT_OT_DBG_CONF_SCOPE(" ", _scope)); + + if (conf->tracer != NULL) { + FLT_OT_DBG(3, " --- tracer '%s' configuration ----------", conf->tracer->id); + FLT_OT_DBG_LIST(conf->tracer, ph_group, " ", "used", _group, FLT_OT_DBG_CONF_PH(" ", _group)); + FLT_OT_DBG_LIST(conf->tracer, ph_scope, " ", "used", _scope, FLT_OT_DBG_CONF_PH(" ", _scope)); + } + + FLT_OT_RETURN_INT(retval); +} + + +/*** + * NAME + * flt_ot_init_per_thread - + * + * ARGUMENTS + * p - + * fconf - + * + * DESCRIPTION + * It initializes the filter for each thread. It works the same way than + * flt_ot_init() but in the context of a thread. This callback is called + * after the thread creation. + * + * RETURN VALUE + * Returns a negative value if an error occurs, any other value otherwise. + */ +static int flt_ot_init_per_thread(struct proxy *p, struct flt_conf *fconf) +{ + struct flt_ot_conf *conf = FLT_OT_DEREF(fconf, conf, NULL); + char *err = NULL; + int retval = FLT_OT_RET_ERROR; + + FLT_OT_FUNC("%p, %p", p, fconf); + + if (conf == NULL) + FLT_OT_RETURN_INT(retval); + + /* + * Start the OpenTracing library tracer thread. + * Enable HTX streams filtering. + */ + if (!(fconf->flags & FLT_CFG_FL_HTX)) { + retval = ot_start(conf->tracer->tracer, conf->tracer->cfgbuf, &err); + if (retval != FLT_OT_RET_ERROR) + fconf->flags |= FLT_CFG_FL_HTX; + else if (err != NULL) { + FLT_OT_ALERT("%s", err); + + FLT_OT_ERR_FREE(err); + } + } else { + retval = FLT_OT_RET_OK; + } + + FLT_OT_RETURN_INT(retval); +} + + +#ifdef DEBUG_OT + +/*** + * NAME + * flt_ot_deinit_per_thread - + * + * ARGUMENTS + * p - + * fconf - + * + * DESCRIPTION + * It cleans up what the init_per_thread callback have done. It is called + * in the context of a thread, before exiting it. + * + * RETURN VALUE + * This function does not return a value. + */ +static void flt_ot_deinit_per_thread(struct proxy *p, struct flt_conf *fconf) +{ + FLT_OT_FUNC("%p, %p", p, fconf); + + FLT_OT_RETURN(); +} + +#endif /* DEBUG_OT */ + + +/*** + * NAME + * flt_ot_attach - Called when a filter instance is created and attach to a stream. + * + * ARGUMENTS + * s - + * f - + * + * DESCRIPTION + * It is called after a filter instance creation, when it is attached to a + * stream. This happens when the stream is started for filters defined on + * the stream's frontend and when the backend is set for filters declared + * on the stream's backend. It is possible to ignore the filter, if needed, + * by returning 0. This could be useful to have conditional filtering. + * + * RETURN VALUE + * Returns a negative value if an error occurs, 0 to ignore the filter, + * any other value otherwise. + */ +static int flt_ot_attach(struct stream *s, struct filter *f) +{ + const struct flt_ot_conf *conf = FLT_OT_CONF(f); + char *err = NULL; + + FLT_OT_FUNC("%p, %p", s, f); + + if (conf->tracer->flag_disabled) { + FLT_OT_DBG(2, "filter '%s', type: %s (disabled)", conf->id, flt_ot_type(f)); + + FLT_OT_RETURN_INT(FLT_OT_RET_IGNORE); + } + else if (conf->tracer->rate_limit < FLT_OT_FLOAT_U32(FLT_OT_RATE_LIMIT_MAX, FLT_OT_RATE_LIMIT_MAX)) { + uint32_t rnd = ha_random32(); + + if (conf->tracer->rate_limit <= rnd) { + FLT_OT_DBG(2, "filter '%s', type: %s (ignored: %u <= %u)", conf->id, flt_ot_type(f), conf->tracer->rate_limit, rnd); + + FLT_OT_RETURN_INT(FLT_OT_RET_IGNORE); + } + } + + FLT_OT_DBG(2, "filter '%s', type: %s (run)", conf->id, flt_ot_type(f)); + + f->ctx = flt_ot_runtime_context_init(s, f, &err); + FLT_OT_ERR_FREE(err); + if (f->ctx == NULL) { + FLT_OT_LOG(LOG_EMERG, "failed to create context"); + + FLT_OT_RETURN_INT(FLT_OT_RET_IGNORE); + } + + /* + * AN_REQ_WAIT_HTTP and AN_RES_WAIT_HTTP analyzers can only be used + * in the .channel_post_analyze callback function. + */ + f->pre_analyzers |= conf->tracer->analyzers & ((AN_REQ_ALL & ~AN_REQ_WAIT_HTTP & ~AN_REQ_HTTP_TARPIT) | (AN_RES_ALL & ~AN_RES_WAIT_HTTP)); + f->post_analyzers |= conf->tracer->analyzers & (AN_REQ_WAIT_HTTP | AN_RES_WAIT_HTTP); + + FLT_OT_LOG(LOG_INFO, "%08x %08x", f->pre_analyzers, f->post_analyzers); + +#ifdef USE_OT_VARS + flt_ot_vars_dump(s); +#endif + flt_ot_http_headers_dump(&(s->req)); + + FLT_OT_RETURN_INT(FLT_OT_RET_OK); +} + + +#ifdef DEBUG_OT + +/*** + * NAME + * flt_ot_stream_start - Called when a stream is created. + * + * ARGUMENTS + * s - + * f - + * + * DESCRIPTION + * It is called when a stream is started. This callback can fail by + * returning a negative value. It will be considered as a critical error + * by HAProxy which disabled the listener for a short time. + * + * RETURN VALUE + * Returns a negative value if an error occurs, any other value otherwise. + */ +static int flt_ot_stream_start(struct stream *s, struct filter *f) +{ + char *err = NULL; + int retval = FLT_OT_RET_OK; + + FLT_OT_FUNC("%p, %p", s, f); + + if (flt_ot_is_disabled(f FLT_OT_DBG_ARGS(, -1))) + FLT_OT_RETURN_INT(retval); + + FLT_OT_RETURN_INT(flt_ot_return_int(f, &err, retval)); +} + + +/*** + * NAME + * flt_ot_stream_set_backend - Called when a backend is set for a stream. + * + * ARGUMENTS + * s - + * f - + * be - + * + * DESCRIPTION + * It is called when a backend is set for a stream. This callbacks will be + * called for all filters attached to a stream (frontend and backend). Note + * this callback is not called if the frontend and the backend are the same. + * + * RETURN VALUE + * Returns a negative value if an error occurs, any other value otherwise. + */ +static int flt_ot_stream_set_backend(struct stream *s, struct filter *f, struct proxy *be) +{ + char *err = NULL; + int retval = FLT_OT_RET_OK; + + FLT_OT_FUNC("%p, %p, %p", s, f, be); + + if (flt_ot_is_disabled(f FLT_OT_DBG_ARGS(, -1))) + FLT_OT_RETURN_INT(retval); + + FLT_OT_DBG(3, "backend: %s", be->id); + + FLT_OT_RETURN_INT(flt_ot_return_int(f, &err, retval)); +} + + +/*** + * NAME + * flt_ot_stream_stop - Called when a stream is destroyed. + * + * ARGUMENTS + * s - + * f - + * + * DESCRIPTION + * It is called when a stream is stopped. This callback always succeed. + * Anyway, it is too late to return an error. + * + * RETURN VALUE + * This function does not return a value. + */ +static void flt_ot_stream_stop(struct stream *s, struct filter *f) +{ + char *err = NULL; + + FLT_OT_FUNC("%p, %p", s, f); + + if (flt_ot_is_disabled(f FLT_OT_DBG_ARGS(, -1))) + FLT_OT_RETURN(); + + flt_ot_return_void(f, &err); + + FLT_OT_RETURN(); +} + +#endif /* DEBUG_OT */ + + +/*** + * NAME + * flt_ot_detach - Called when a filter instance is detach from a stream, just before its destruction. + * + * ARGUMENTS + * s - + * f - + * + * DESCRIPTION + * It is called when a filter instance is detached from a stream, before its + * destruction. This happens when the stream is stopped for filters defined + * on the stream's frontend and when the analyze ends for filters defined on + * the stream's backend. + * + * RETURN VALUE + * This function does not return a value. + */ +static void flt_ot_detach(struct stream *s, struct filter *f) +{ + FLT_OT_FUNC("%p, %p", s, f); + + FLT_OT_DBG(2, "filter '%s', type: %s", FLT_OT_CONF(f)->id, flt_ot_type(f)); + + flt_ot_runtime_context_free(f); + + FLT_OT_RETURN(); +} + + +/*** + * NAME + * flt_ot_check_timeouts - Called when a stream is woken up because of an expired timer. + * + * ARGUMENTS + * s - + * f - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * This function does not return a value. + */ +static void flt_ot_check_timeouts(struct stream *s, struct filter *f) +{ + char *err = NULL; + + FLT_OT_FUNC("%p, %p", s, f); + + if (flt_ot_is_disabled(f FLT_OT_DBG_ARGS(, -1))) + FLT_OT_RETURN(); + + s->pending_events |= TASK_WOKEN_MSG; + + flt_ot_return_void(f, &err); + + FLT_OT_RETURN(); +} + + +/*** + * NAME + * flt_ot_channel_start_analyze - Called when analyze starts for a given channel. + * + * ARGUMENTS + * s - + * f - + * chn - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * Returns a negative value if an error occurs, 0 if it needs to wait, + * any other value otherwise. + */ +static int flt_ot_channel_start_analyze(struct stream *s, struct filter *f, struct channel *chn) +{ + char *err = NULL; + int retval; + + FLT_OT_FUNC("%p, %p, %p", s, f, chn); + + if (flt_ot_is_disabled(f FLT_OT_DBG_ARGS(, (chn->flags & CF_ISRESP) ? FLT_OT_EVENT_RES_SERVER_SESS_START : FLT_OT_EVENT_REQ_CLIENT_SESS_START))) + FLT_OT_RETURN_INT(FLT_OT_RET_OK); + + FLT_OT_DBG(3, "channel: %s, mode: %s (%s)", flt_ot_chn_label(chn), flt_ot_pr_mode(s), flt_ot_stream_pos(s)); + + if (chn->flags & CF_ISRESP) { + /* The response channel. */ + chn->analysers |= f->pre_analyzers & AN_RES_ALL; + + /* The event 'on-server-session-start'. */ + retval = flt_ot_event_run(s, f, chn, FLT_OT_EVENT_RES_SERVER_SESS_START, &err); + if (retval == FLT_OT_RET_WAIT) { + channel_dont_read(chn); + channel_dont_close(chn); + } + } else { + /* The request channel. */ + chn->analysers |= f->pre_analyzers & AN_REQ_ALL; + + /* The event 'on-client-session-start'. */ + retval = flt_ot_event_run(s, f, chn, FLT_OT_EVENT_REQ_CLIENT_SESS_START, &err); + } + +// register_data_filter(s, chn, f); + + FLT_OT_RETURN_INT(flt_ot_return_int(f, &err, retval)); +} + + +/*** + * NAME + * flt_ot_channel_pre_analyze - Called before a processing happens on a given channel. + * + * ARGUMENTS + * s - + * f - + * chn - the channel on which the analyzing is done + * an_bit - the analyzer id + * + * DESCRIPTION + * - + * + * RETURN VALUE + * Returns a negative value if an error occurs, 0 if it needs to wait, + * any other value otherwise. + */ +static int flt_ot_channel_pre_analyze(struct stream *s, struct filter *f, struct channel *chn, uint an_bit) +{ + char *err = NULL; + int i, event = -1, retval; + + FLT_OT_FUNC("%p, %p, %p, 0x%08x", s, f, chn, an_bit); + + for (i = 0; i < FLT_OT_TABLESIZE(flt_ot_event_data); i++) + if (flt_ot_event_data[i].an_bit == an_bit) { + event = i; + + break; + } + + if (flt_ot_is_disabled(f FLT_OT_DBG_ARGS(, event))) + FLT_OT_RETURN_INT(FLT_OT_RET_OK); + + FLT_OT_DBG(3, "channel: %s, mode: %s (%s), analyzer: %s", flt_ot_chn_label(chn), flt_ot_pr_mode(s), flt_ot_stream_pos(s), flt_ot_analyzer(an_bit)); + + retval = flt_ot_event_run(s, f, chn, event, &err); + + if ((retval == FLT_OT_RET_WAIT) && (chn->flags & CF_ISRESP)) { + channel_dont_read(chn); + channel_dont_close(chn); + } + + FLT_OT_RETURN_INT(flt_ot_return_int(f, &err, retval)); +} + + +/*** + * NAME + * flt_ot_channel_post_analyze - Called after a processing happens on a given channel. + * + * ARGUMENTS + * s - + * f - + * chn - + * an_bit - + * + * DESCRIPTION + * This function, for its part, is not resumable. It is called when a + * filterable analyzer finishes its processing. So it called once for + * the same analyzer. + * + * RETURN VALUE + * Returns a negative value if an error occurs, 0 if it needs to wait, + * any other value otherwise. + */ +static int flt_ot_channel_post_analyze(struct stream *s, struct filter *f, struct channel *chn, uint an_bit) +{ + char *err = NULL; + int i, event = -1, retval; + + FLT_OT_FUNC("%p, %p, %p, 0x%08x", s, f, chn, an_bit); + + for (i = 0; i < FLT_OT_TABLESIZE(flt_ot_event_data); i++) + if (flt_ot_event_data[i].an_bit == an_bit) { + event = i; + + break; + } + + if (flt_ot_is_disabled(f FLT_OT_DBG_ARGS(, event))) + FLT_OT_RETURN_INT(FLT_OT_RET_OK); + + FLT_OT_DBG(3, "channel: %s, mode: %s (%s), analyzer: %s", flt_ot_chn_label(chn), flt_ot_pr_mode(s), flt_ot_stream_pos(s), flt_ot_analyzer(an_bit)); + + retval = flt_ot_event_run(s, f, chn, event, &err); + + FLT_OT_RETURN_INT(flt_ot_return_int(f, &err, retval)); +} + + +/*** + * NAME + * flt_ot_channel_end_analyze - Called when analyze ends for a given channel. + * + * ARGUMENTS + * s - + * f - + * chn - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * Returns a negative value if an error occurs, 0 if it needs to wait, + * any other value otherwise. + */ +static int flt_ot_channel_end_analyze(struct stream *s, struct filter *f, struct channel *chn) +{ + char *err = NULL; + int rc, retval; + + FLT_OT_FUNC("%p, %p, %p", s, f, chn); + + if (flt_ot_is_disabled(f FLT_OT_DBG_ARGS(, (chn->flags & CF_ISRESP) ? FLT_OT_EVENT_RES_SERVER_SESS_END : FLT_OT_EVENT_REQ_CLIENT_SESS_END))) + FLT_OT_RETURN_INT(FLT_OT_RET_OK); + + FLT_OT_DBG(3, "channel: %s, mode: %s (%s)", flt_ot_chn_label(chn), flt_ot_pr_mode(s), flt_ot_stream_pos(s)); + + if (chn->flags & CF_ISRESP) { + /* The response channel, event 'on-server-session-end'. */ + retval = flt_ot_event_run(s, f, chn, FLT_OT_EVENT_RES_SERVER_SESS_END, &err); + } else { + /* The request channel, event 'on-client-session-end'. */ + retval = flt_ot_event_run(s, f, chn, FLT_OT_EVENT_REQ_CLIENT_SESS_END, &err); + + /* + * In case an event using server response is defined and not + * executed, event 'on-server-unavailable' is called here. + */ + if ((FLT_OT_CONF(f)->tracer->analyzers & AN_RES_ALL) && !(FLT_OT_RT_CTX(f->ctx)->analyzers & AN_RES_ALL)) { + rc = flt_ot_event_run(s, f, chn, FLT_OT_EVENT_REQ_SERVER_UNAVAILABLE, &err); + if ((retval == FLT_OT_RET_OK) && (rc != FLT_OT_RET_OK)) + retval = rc; + } + } + + FLT_OT_RETURN_INT(flt_ot_return_int(f, &err, retval)); +} + + +#ifdef DEBUG_OT + +/*** + * NAME + * flt_ot_http_headers - + * + * ARGUMENTS + * s - + * f - + * msg - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * Returns a negative value if an error occurs, 0 if it needs to wait, + * any other value otherwise. + */ +static int flt_ot_http_headers(struct stream *s, struct filter *f, struct http_msg *msg) +{ + char *err = NULL; + struct htx *htx = htxbuf(&(msg->chn->buf)); + struct htx_sl *sl = http_get_stline(htx); + int retval = FLT_OT_RET_OK; + + FLT_OT_FUNC("%p, %p, %p", s, f, msg); + + if (flt_ot_is_disabled(f FLT_OT_DBG_ARGS(, -1))) + FLT_OT_RETURN_INT(retval); + + FLT_OT_DBG(3, "channel: %s, mode: %s (%s), %.*s %.*s %.*s", flt_ot_chn_label(msg->chn), flt_ot_pr_mode(s), flt_ot_stream_pos(s), HTX_SL_P1_LEN(sl), HTX_SL_P1_PTR(sl), HTX_SL_P2_LEN(sl), HTX_SL_P2_PTR(sl), HTX_SL_P3_LEN(sl), HTX_SL_P3_PTR(sl)); + + FLT_OT_RETURN_INT(flt_ot_return_int(f, &err, retval)); +} + + +/*** + * NAME + * flt_ot_http_payload - + * + * ARGUMENTS + * s - + * f - + * msg - + * offset - + * len - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * Returns a negative value if an error occurs, any other value otherwise. + */ +static int flt_ot_http_payload(struct stream *s, struct filter *f, struct http_msg *msg, uint offset, uint len) +{ + char *err = NULL; + int retval = len; + + FLT_OT_FUNC("%p, %p, %p, %u, %u", s, f, msg, offset, len); + + if (flt_ot_is_disabled(f FLT_OT_DBG_ARGS(, -1))) + FLT_OT_RETURN_INT(len); + + FLT_OT_DBG(3, "channel: %s, mode: %s (%s), offset: %u, len: %u, forward: %d", flt_ot_chn_label(msg->chn), flt_ot_pr_mode(s), flt_ot_stream_pos(s), offset, len, retval); + + if (retval != len) + task_wakeup(s->task, TASK_WOKEN_MSG); + + FLT_OT_RETURN_INT(flt_ot_return_int(f, &err, retval)); +} + + +/*** + * NAME + * flt_ot_http_end - + * + * ARGUMENTS + * s - + * f - + * msg - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * Returns a negative value if an error occurs, 0 if it needs to wait, + * any other value otherwise. + */ +static int flt_ot_http_end(struct stream *s, struct filter *f, struct http_msg *msg) +{ + char *err = NULL; + int retval = FLT_OT_RET_OK; + + FLT_OT_FUNC("%p, %p, %p", s, f, msg); + + if (flt_ot_is_disabled(f FLT_OT_DBG_ARGS(, -1))) + FLT_OT_RETURN_INT(retval); + + FLT_OT_DBG(3, "channel: %s, mode: %s (%s)", flt_ot_chn_label(msg->chn), flt_ot_pr_mode(s), flt_ot_stream_pos(s)); + + FLT_OT_RETURN_INT(flt_ot_return_int(f, &err, retval)); +} + + +/*** + * NAME + * flt_ot_http_reset - + * + * ARGUMENTS + * s - + * f - + * msg - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * This function does not return a value. + */ +static void flt_ot_http_reset(struct stream *s, struct filter *f, struct http_msg *msg) +{ + char *err = NULL; + + FLT_OT_FUNC("%p, %p, %p", s, f, msg); + + if (flt_ot_is_disabled(f FLT_OT_DBG_ARGS(, -1))) + FLT_OT_RETURN(); + + FLT_OT_DBG(3, "channel: %s, mode: %s (%s)", flt_ot_chn_label(msg->chn), flt_ot_pr_mode(s), flt_ot_stream_pos(s)); + + flt_ot_return_void(f, &err); + + FLT_OT_RETURN(); +} + + +/*** + * NAME + * flt_ot_http_reply - + * + * ARGUMENTS + * s - + * f - + * status - + * msg - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * This function does not return a value. + */ +static void flt_ot_http_reply(struct stream *s, struct filter *f, short status, const struct buffer *msg) +{ + char *err = NULL; + + FLT_OT_FUNC("%p, %p, %hd, %p", s, f, status, msg); + + if (flt_ot_is_disabled(f FLT_OT_DBG_ARGS(, -1))) + FLT_OT_RETURN(); + + FLT_OT_DBG(3, "channel: -, mode: %s (%s)", flt_ot_pr_mode(s), flt_ot_stream_pos(s)); + + flt_ot_return_void(f, &err); + + FLT_OT_RETURN(); +} + + +/*** + * NAME + * flt_ot_tcp_payload - + * + * ARGUMENTS + * s - + * f - + * chn - + * offset - + * len - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * Returns a negative value if an error occurs, any other value otherwise. + */ +static int flt_ot_tcp_payload(struct stream *s, struct filter *f, struct channel *chn, uint offset, uint len) +{ + char *err = NULL; + int retval = len; + + FLT_OT_FUNC("%p, %p, %p, %u, %u", s, f, chn, offset, len); + + if (flt_ot_is_disabled(f FLT_OT_DBG_ARGS(, -1))) + FLT_OT_RETURN_INT(len); + + FLT_OT_DBG(3, "channel: %s, mode: %s (%s), offset: %u, len: %u, forward: %d", flt_ot_chn_label(chn), flt_ot_pr_mode(s), flt_ot_stream_pos(s), offset, len, retval); + + if (s->flags & SF_HTX) { + } else { + } + + if (retval != len) + task_wakeup(s->task, TASK_WOKEN_MSG); + + FLT_OT_RETURN_INT(flt_ot_return_int(f, &err, retval)); +} + +#endif /* DEBUG_OT */ + + +struct flt_ops flt_ot_ops = { + /* Callbacks to manage the filter lifecycle. */ + .init = flt_ot_init, + .deinit = flt_ot_deinit, + .check = flt_ot_check, + .init_per_thread = flt_ot_init_per_thread, + .deinit_per_thread = FLT_OT_DBG_IFDEF(flt_ot_deinit_per_thread, NULL), + + /* Stream callbacks. */ + .attach = flt_ot_attach, + .stream_start = FLT_OT_DBG_IFDEF(flt_ot_stream_start, NULL), + .stream_set_backend = FLT_OT_DBG_IFDEF(flt_ot_stream_set_backend, NULL), + .stream_stop = FLT_OT_DBG_IFDEF(flt_ot_stream_stop, NULL), + .detach = flt_ot_detach, + .check_timeouts = flt_ot_check_timeouts, + + /* Channel callbacks. */ + .channel_start_analyze = flt_ot_channel_start_analyze, + .channel_pre_analyze = flt_ot_channel_pre_analyze, + .channel_post_analyze = flt_ot_channel_post_analyze, + .channel_end_analyze = flt_ot_channel_end_analyze, + + /* HTTP callbacks. */ + .http_headers = FLT_OT_DBG_IFDEF(flt_ot_http_headers, NULL), + .http_payload = FLT_OT_DBG_IFDEF(flt_ot_http_payload, NULL), + .http_end = FLT_OT_DBG_IFDEF(flt_ot_http_end, NULL), + .http_reset = FLT_OT_DBG_IFDEF(flt_ot_http_reset, NULL), + .http_reply = FLT_OT_DBG_IFDEF(flt_ot_http_reply, NULL), + + /* TCP callbacks. */ + .tcp_payload = FLT_OT_DBG_IFDEF(flt_ot_tcp_payload, NULL) +}; + + +REGISTER_BUILD_OPTS("Built with OpenTracing support."); + +/* + * Local variables: + * c-indent-level: 8 + * c-basic-offset: 8 + * End: + * + * vi: noexpandtab shiftwidth=8 tabstop=8 + */ diff --git a/addons/ot/src/group.c b/addons/ot/src/group.c new file mode 100644 index 0000000..52b872d --- /dev/null +++ b/addons/ot/src/group.c @@ -0,0 +1,354 @@ +/*** + * Copyright 2020 HAProxy Technologies + * + * This file is part of the HAProxy OpenTracing filter. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include "include.h" + + +#define FLT_OT_GROUP_DEF(a,b,c) { a, b, c }, +const struct flt_ot_group_data flt_ot_group_data[] = { FLT_OT_GROUP_DEFINES }; +#undef FLT_OT_GROUP_DEF + + +/*** + * NAME + * flt_ot_group_action - + * + * ARGUMENTS + * rule - + * px - + * sess - + * s - + * opts - + * + * DESCRIPTION + * This is the action_ptr callback of a rule associated to the + * FLT_OT_ACTION_GROUP action. + * + * RETURN VALUE + * The function returns ACT_RET_CONT if processing is finished (with error or + * not), otherwise, it returns ACT_RET_YIELD if the action is in progress. + */ +static enum act_return flt_ot_group_action(struct act_rule *rule, struct proxy *px, struct session *sess, struct stream *s, int opts) +{ + const struct filter *filter; + const struct flt_conf *fconf; + const struct flt_ot_conf *conf; + const struct flt_ot_conf_group *conf_group; + const struct flt_ot_runtime_context *rt_ctx = NULL; + const struct flt_ot_conf_ph *ph_scope; + char *err = NULL; + int i, rc; + + FLT_OT_FUNC("%p, %p, %p, %p, %d", rule, px, sess, s, opts); + + FLT_OT_DBG(3, "from: %d, arg.act %p:{ %p %p %p %p }", rule->from, &(rule->arg.act), rule->arg.act.p[0], rule->arg.act.p[1], rule->arg.act.p[2], rule->arg.act.p[3]); + + fconf = rule->arg.act.p[FLT_OT_ARG_FLT_CONF]; + conf = rule->arg.act.p[FLT_OT_ARG_CONF]; + conf_group = ((const struct flt_ot_conf_ph *)(rule->arg.act.p[FLT_OT_ARG_GROUP]))->ptr; + + if ((fconf == NULL) || (conf == NULL) || (conf_group == NULL)) { + FLT_OT_LOG(LOG_ERR, FLT_OT_ACTION_GROUP ": internal error, invalid group action"); + + FLT_OT_RETURN_EX(ACT_RET_CONT, enum act_return, "%d"); + } + + if (conf->tracer->flag_disabled) { + FLT_OT_DBG(1, "filter '%s' disabled, group action '%s' ignored", conf->id, conf_group->id); + + FLT_OT_RETURN_EX(ACT_RET_CONT, enum act_return, "%d"); + } + + /* Find the OpenTracing filter instance from the current stream. */ + list_for_each_entry(filter, &(s->strm_flt.filters), list) + if (filter->config == fconf) { + rt_ctx = filter->ctx; + + break; + } + + if (rt_ctx == NULL) { + FLT_OT_DBG(1, "cannot find filter, probably not attached to the stream"); + + FLT_OT_RETURN_EX(ACT_RET_CONT, enum act_return, "%d"); + } + else if (flt_ot_is_disabled(filter FLT_OT_DBG_ARGS(, -1))) { + FLT_OT_RETURN_EX(ACT_RET_CONT, enum act_return, "%d"); + } + else { + FLT_OT_DBG(3, "run group '%s'", conf_group->id); + FLT_OT_DBG_CONF_GROUP("run group ", conf_group); + } + + /* + * Check the value of rule->from; in case it is incorrect, + * report an error. + */ + for (i = 0; i < FLT_OT_TABLESIZE(flt_ot_group_data); i++) + if (flt_ot_group_data[i].act_from == rule->from) + break; + + if (i >= FLT_OT_TABLESIZE(flt_ot_group_data)) { + FLT_OT_LOG(LOG_ERR, FLT_OT_ACTION_GROUP ": internal error, invalid rule->from=%d", rule->from); + + FLT_OT_RETURN_EX(ACT_RET_CONT, enum act_return, "%d"); + } + + list_for_each_entry(ph_scope, &(conf_group->ph_scopes), list) { + rc = flt_ot_scope_run(s, rt_ctx->filter, &(s->res), ph_scope->ptr, NULL, SMP_OPT_DIR_RES, &err); + if ((rc == FLT_OT_RET_ERROR) && (opts & ACT_OPT_FINAL)) { + /* XXX */ + } + } + + FLT_OT_RETURN_EX(ACT_RET_CONT, enum act_return, "%d"); +} + + +/*** + * NAME + * flt_ot_group_check - + * + * ARGUMENTS + * rule - + * px - + * err - + * + * DESCRIPTION + * This is the check_ptr callback of a rule associated to the + * FLT_OT_ACTION_GROUP action. + * + * RETURN VALUE + * The function returns 1 in success case, otherwise, + * it returns 0 and err is filled. + */ +static int flt_ot_group_check(struct act_rule *rule, struct proxy *px, char **err) +{ + struct flt_conf *fconf_tmp, *fconf = NULL; + struct flt_ot_conf *conf; + struct flt_ot_conf_ph *ph_group; + const char *filter_id; + const char *group_id; + bool flag_found = 0; + int i; + + FLT_OT_FUNC("%p, %p, %p:%p", rule, px, FLT_OT_DPTR_ARGS(err)); + + filter_id = rule->arg.act.p[FLT_OT_ARG_FILTER_ID]; + group_id = rule->arg.act.p[FLT_OT_ARG_GROUP_ID]; + + FLT_OT_DBG(2, "checking filter_id='%s', group_id='%s'", filter_id, group_id); + + /* + * Check the value of rule->from; in case it is incorrect, + * report an error. + */ + for (i = 0; i < FLT_OT_TABLESIZE(flt_ot_group_data); i++) + if (flt_ot_group_data[i].act_from == rule->from) + break; + + if (i >= FLT_OT_TABLESIZE(flt_ot_group_data)) { + FLT_OT_ERR("internal error, unexpected rule->from=%d, please report this bug!", rule->from); + + FLT_OT_RETURN_INT(0); + } + + /* + * Try to find the OpenTracing filter by checking all filters + * for the proxy . + */ + list_for_each_entry(fconf_tmp, &(px->filter_configs), list) { + conf = fconf_tmp->conf; + + if (fconf_tmp->id != ot_flt_id) { + /* This is not an OpenTracing filter. */ + continue; + } + else if (strcmp(conf->id, filter_id) == 0) { + /* This is the good filter ID. */ + fconf = fconf_tmp; + + break; + } + } + + if (fconf == NULL) { + FLT_OT_ERR("unable to find the OpenTracing filter '%s' used by the " FLT_OT_ACTION_GROUP " '%s'", filter_id, group_id); + + FLT_OT_RETURN_INT(0); + } + + /* + * Attempt to find if the group is defined in the OpenTracing filter + * configuration. + */ + list_for_each_entry(ph_group, &(conf->tracer->ph_groups), list) + if (strcmp(ph_group->id, group_id) == 0) { + flag_found = 1; + + break; + } + + if (!flag_found) { + FLT_OT_ERR("unable to find group '%s' in the OpenTracing filter '%s' configuration", group_id, filter_id); + + FLT_OT_RETURN_INT(0); + } + + FLT_OT_FREE_CLEAR(rule->arg.act.p[FLT_OT_ARG_FILTER_ID]); + FLT_OT_FREE_CLEAR(rule->arg.act.p[FLT_OT_ARG_GROUP_ID]); + + rule->arg.act.p[FLT_OT_ARG_FLT_CONF] = fconf; + rule->arg.act.p[FLT_OT_ARG_CONF] = conf; + rule->arg.act.p[FLT_OT_ARG_GROUP] = ph_group; + + FLT_OT_RETURN_INT(1); +} + + +/*** + * NAME + * flt_ot_group_release - + * + * ARGUMENTS + * rule - + * + * DESCRIPTION + * This is the release_ptr callback of a rule associated to the + * FLT_OT_ACTION_GROUP action. + * + * RETURN VALUE + * This function does not return a value. + */ +static void flt_ot_group_release(struct act_rule *rule) +{ + FLT_OT_FUNC("%p", rule); + + FLT_OT_RETURN(); +} + + +/*** + * NAME + * flt_ot_group_parse - + * + * ARGUMENTS + * args - + * cur_arg - + * px - + * rule - + * err - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * Returns ACT_RET_PRS_ERR if an error occurs, ACT_RET_PRS_OK otherwise. + */ +static enum act_parse_ret flt_ot_group_parse(const char **args, int *cur_arg, struct proxy *px, struct act_rule *rule, char **err) +{ + FLT_OT_FUNC("%p, %p, %p, %p, %p:%p", args, cur_arg, px, rule, FLT_OT_DPTR_ARGS(err)); + + if (!FLT_OT_ARG_ISVALID(*cur_arg) || + !FLT_OT_ARG_ISVALID(*cur_arg + 1) || + (FLT_OT_ARG_ISVALID(*cur_arg + 2) && + (strcmp(args[*cur_arg + 2], FLT_OT_CONDITION_IF) != 0) && + (strcmp(args[*cur_arg + 2], FLT_OT_CONDITION_UNLESS) != 0))) { + FLT_OT_ERR("expects: [{ if | unless } ...]"); + + FLT_OT_RETURN_EX(ACT_RET_PRS_ERR, enum act_parse_ret, "%d"); + } + + /* Copy the OpenTracing filter id. */ + rule->arg.act.p[FLT_OT_ARG_FILTER_ID] = FLT_OT_STRDUP(args[*cur_arg]); + if (rule->arg.act.p[FLT_OT_ARG_FILTER_ID] == NULL) { + FLT_OT_ERR("%s : out of memory", args[*cur_arg]); + + FLT_OT_RETURN_EX(ACT_RET_PRS_ERR, enum act_parse_ret, "%d"); + } + + /* Copy the OpenTracing group id. */ + rule->arg.act.p[FLT_OT_ARG_GROUP_ID] = FLT_OT_STRDUP(args[*cur_arg + 1]); + if (rule->arg.act.p[FLT_OT_ARG_GROUP_ID] == NULL) { + FLT_OT_ERR("%s : out of memory", args[*cur_arg + 1]); + + FLT_OT_FREE_CLEAR(rule->arg.act.p[FLT_OT_ARG_FILTER_ID]); + + FLT_OT_RETURN_EX(ACT_RET_PRS_ERR, enum act_parse_ret, "%d"); + } + + rule->action = ACT_CUSTOM; + rule->action_ptr = flt_ot_group_action; + rule->check_ptr = flt_ot_group_check; + rule->release_ptr = flt_ot_group_release; + + *cur_arg += 2; + + FLT_OT_RETURN_EX(ACT_RET_PRS_OK, enum act_parse_ret, "%d"); +} + + +static struct action_kw_list tcp_req_action_kws = { ILH, { + { FLT_OT_ACTION_GROUP, flt_ot_group_parse }, + { /* END */ }, + } +}; + +INITCALL1(STG_REGISTER, tcp_req_cont_keywords_register, &tcp_req_action_kws); + +static struct action_kw_list tcp_res_action_kws = { ILH, { + { FLT_OT_ACTION_GROUP, flt_ot_group_parse }, + { /* END */ }, + } +}; + +INITCALL1(STG_REGISTER, tcp_res_cont_keywords_register, &tcp_res_action_kws); + +static struct action_kw_list http_req_action_kws = { ILH, { + { FLT_OT_ACTION_GROUP, flt_ot_group_parse }, + { /* END */ }, + } +}; + +INITCALL1(STG_REGISTER, http_req_keywords_register, &http_req_action_kws); + +static struct action_kw_list http_res_action_kws = { ILH, { + { FLT_OT_ACTION_GROUP, flt_ot_group_parse }, + { /* END */ }, + } +}; + +INITCALL1(STG_REGISTER, http_res_keywords_register, &http_res_action_kws); + +static struct action_kw_list http_after_res_actions_kws = { ILH, { + { FLT_OT_ACTION_GROUP, flt_ot_group_parse }, + { /* END */ }, + } +}; + +INITCALL1(STG_REGISTER, http_after_res_keywords_register, &http_after_res_actions_kws); + +/* + * Local variables: + * c-indent-level: 8 + * c-basic-offset: 8 + * End: + * + * vi: noexpandtab shiftwidth=8 tabstop=8 + */ diff --git a/addons/ot/src/http.c b/addons/ot/src/http.c new file mode 100644 index 0000000..517bd0d --- /dev/null +++ b/addons/ot/src/http.c @@ -0,0 +1,312 @@ +/*** + * Copyright 2020 HAProxy Technologies + * + * This file is part of the HAProxy OpenTracing filter. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include "include.h" + + +#ifdef DEBUG_OT + +/*** + * NAME + * flt_ot_http_headers_dump - + * + * ARGUMENTS + * chn - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * This function does not return a value. + */ +void flt_ot_http_headers_dump(const struct channel *chn) +{ + const struct htx *htx; + int32_t pos; + + FLT_OT_FUNC("%p", chn); + + if (chn == NULL) + FLT_OT_RETURN(); + + htx = htxbuf(&(chn->buf)); + + if (htx_is_empty(htx)) + FLT_OT_RETURN(); + + for (pos = htx_get_first(htx); pos != -1; pos = htx_get_next(htx, pos)) { + struct htx_blk *blk = htx_get_blk(htx, pos); + enum htx_blk_type type = htx_get_blk_type(blk); + + if (type == HTX_BLK_HDR) { + struct ist n = htx_get_blk_name(htx, blk); + struct ist v = htx_get_blk_value(htx, blk); + + FLT_OT_DBG(2, "'%.*s: %.*s'", (int)n.len, n.ptr, (int)v.len, v.ptr); + } + else if (type == HTX_BLK_EOH) + break; + } + + FLT_OT_RETURN(); +} + +#endif /* DEBUG_OT */ + + +/*** + * NAME + * flt_ot_http_headers_get - + * + * ARGUMENTS + * chn - + * prefix - + * len - + * err - + * + * DESCRIPTION + * This function is very similar to function http_action_set_header(), from + * the HAProxy source. + * + * RETURN VALUE + * - + */ +struct otc_text_map *flt_ot_http_headers_get(struct channel *chn, const char *prefix, size_t len, char **err) +{ + const struct htx *htx; + size_t prefix_len = (!FLT_OT_STR_ISVALID(prefix) || (len == 0)) ? 0 : (len + 1); + int32_t pos; + struct otc_text_map *retptr = NULL; + + FLT_OT_FUNC("%p, \"%s\", %zu, %p:%p", chn, prefix, len, FLT_OT_DPTR_ARGS(err)); + + if (chn == NULL) + FLT_OT_RETURN_PTR(retptr); + + /* + * The keyword 'inject' allows you to define the name of the OpenTracing + * context without using a prefix. In that case all HTTP headers are + * transferred because it is not possible to separate them from the + * OpenTracing context (this separation is usually done via a prefix). + * + * When using the 'extract' keyword, the context name must be specified. + * To allow all HTTP headers to be extracted, the first character of + * that name must be set to FLT_OT_PARSE_CTX_IGNORE_NAME. + */ + if (FLT_OT_STR_ISVALID(prefix) && (*prefix == FLT_OT_PARSE_CTX_IGNORE_NAME)) + prefix_len = 0; + + htx = htxbuf(&(chn->buf)); + + for (pos = htx_get_first(htx); pos != -1; pos = htx_get_next(htx, pos)) { + struct htx_blk *blk = htx_get_blk(htx, pos); + enum htx_blk_type type = htx_get_blk_type(blk); + + if (type == HTX_BLK_HDR) { + struct ist v, n = htx_get_blk_name(htx, blk); + + if ((prefix_len == 0) || ((n.len >= prefix_len) && (strncasecmp(n.ptr, prefix, len) == 0))) { + if (retptr == NULL) { + retptr = otc_text_map_new(NULL, 8); + if (retptr == NULL) { + FLT_OT_ERR("failed to create HTTP header data"); + + break; + } + } + + v = htx_get_blk_value(htx, blk); + + /* + * In case the data of the HTTP header is not + * specified, v.ptr will have some non-null + * value and v.len will be equal to 0. The + * otc_text_map_add() function will not + * interpret this well. In this case v.ptr + * is set to an empty string. + */ + if (v.len == 0) + v = ist(""); + + /* + * Here, an HTTP header (which is actually part + * of the span context is added to the text_map. + * + * Before adding, the prefix is removed from the + * HTTP header name. + */ + if (otc_text_map_add(retptr, n.ptr + prefix_len, n.len - prefix_len, v.ptr, v.len, OTC_TEXT_MAP_DUP_KEY | OTC_TEXT_MAP_DUP_VALUE) == -1) { + FLT_OT_ERR("failed to add HTTP header data"); + + otc_text_map_destroy(&retptr, OTC_TEXT_MAP_FREE_KEY | OTC_TEXT_MAP_FREE_VALUE); + + break; + } + } + } + else if (type == HTX_BLK_EOH) + break; + } + + ot_text_map_show(retptr); + + if ((retptr != NULL) && (retptr->count == 0)) { + FLT_OT_DBG(2, "WARNING: no HTTP headers found"); + + otc_text_map_destroy(&retptr, OTC_TEXT_MAP_FREE_KEY | OTC_TEXT_MAP_FREE_VALUE); + } + + FLT_OT_RETURN_PTR(retptr); +} + + +/*** + * NAME + * flt_ot_http_header_set - + * + * ARGUMENTS + * chn - + * prefix - + * name - + * value - + * err - + * + * DESCRIPTION + * This function is very similar to function http_action_set_header(), from + * the HAProxy source. + * + * RETURN VALUE + * - + */ +int flt_ot_http_header_set(struct channel *chn, const char *prefix, const char *name, const char *value, char **err) +{ + struct http_hdr_ctx ctx = { .blk = NULL }; + struct ist ist_name; + struct buffer *buffer = NULL; + struct htx *htx; + int retval = -1; + + FLT_OT_FUNC("%p, \"%s\", \"%s\", \"%s\", %p:%p", chn, prefix, name, value, FLT_OT_DPTR_ARGS(err)); + + if ((chn == NULL) || (!FLT_OT_STR_ISVALID(prefix) && !FLT_OT_STR_ISVALID(name))) + FLT_OT_RETURN_INT(retval); + + htx = htxbuf(&(chn->buf)); + + /* + * Very rare (about 1% of cases), htx is empty. + * In order to avoid segmentation fault, we exit this function. + */ + if (htx_is_empty(htx)) { + FLT_OT_ERR("HTX is empty"); + + FLT_OT_RETURN_INT(retval); + } + + if (!FLT_OT_STR_ISVALID(prefix)) { + ist_name = ist2((char *)name, strlen(name)); + } + else if (!FLT_OT_STR_ISVALID(name)) { + ist_name = ist2((char *)prefix, strlen(prefix)); + } + else { + buffer = flt_ot_trash_alloc(0, err); + if (buffer == NULL) + FLT_OT_RETURN_INT(retval); + + (void)chunk_printf(buffer, "%s-%s", prefix, name); + + ist_name = ist2(buffer->area, buffer->data); + } + + /* Remove all occurrences of the header. */ + while (http_find_header(htx, ist(""), &ctx, 1) == 1) { + struct ist n = htx_get_blk_name(htx, ctx.blk); +#ifdef DEBUG_OT + struct ist v = htx_get_blk_value(htx, ctx.blk); +#endif + + /* + * If the parameter is not set, then remove all headers + * that start with the contents of the parameter. + */ + if (!FLT_OT_STR_ISVALID(name)) + n.len = ist_name.len; + + if (isteqi(n, ist_name)) + if (http_remove_header(htx, &ctx) == 1) + FLT_OT_DBG(3, "HTTP header '%.*s: %.*s' removed", (int)n.len, n.ptr, (int)v.len, v.ptr); + } + + /* + * If the value pointer has a value of NULL, the HTTP header is not set + * after deletion. + */ + if (value == NULL) { + /* Do nothing. */ + } + else if (http_add_header(htx, ist_name, ist(value)) == 1) { + retval = 0; + + FLT_OT_DBG(3, "HTTP header '%s: %s' added", ist_name.ptr, value); + } + else { + FLT_OT_ERR("failed to set HTTP header '%s: %s'", ist_name.ptr, value); + } + + flt_ot_trash_free(&buffer); + + FLT_OT_RETURN_INT(retval); +} + + +/*** + * NAME + * flt_ot_http_headers_remove - + * + * ARGUMENTS + * chn - + * prefix - + * err - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +int flt_ot_http_headers_remove(struct channel *chn, const char *prefix, char **err) +{ + int retval; + + FLT_OT_FUNC("%p, \"%s\", %p:%p", chn, prefix, FLT_OT_DPTR_ARGS(err)); + + retval = flt_ot_http_header_set(chn, prefix, NULL, NULL, err); + + FLT_OT_RETURN_INT(retval); +} + +/* + * Local variables: + * c-indent-level: 8 + * c-basic-offset: 8 + * End: + * + * vi: noexpandtab shiftwidth=8 tabstop=8 + */ diff --git a/addons/ot/src/opentracing.c b/addons/ot/src/opentracing.c new file mode 100644 index 0000000..8ae5f02 --- /dev/null +++ b/addons/ot/src/opentracing.c @@ -0,0 +1,1067 @@ +/*** + * Copyright 2020 HAProxy Technologies + * + * This file is part of the HAProxy OpenTracing filter. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include "include.h" + + +static struct pool_head *pool_head_ot_span_context __read_mostly = NULL; + +#ifdef USE_POOL_OT_SPAN_CONTEXT +REGISTER_POOL(&pool_head_ot_span_context, "ot_span_context", MAX(sizeof(struct otc_span), sizeof(struct otc_span_context))); +#endif + + +#ifdef DEBUG_OT + +/*** + * NAME + * ot_text_map_show - + * + * ARGUMENTS + * text_map - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * This function does not return a value. + */ +void ot_text_map_show(const struct otc_text_map *text_map) +{ + FLT_OT_FUNC("%p", text_map); + + if (text_map == NULL) + FLT_OT_RETURN(); + + FLT_OT_DBG_TEXT_MAP(text_map); + + if ((text_map->key != NULL) && (text_map->value != NULL) && (text_map->count > 0)) { + size_t i; + + for (i = 0; i < text_map->count; i++) + FLT_OT_DBG(3, " \"%s\" -> \"%s\"", text_map->key[i], text_map->value[i]); + } + + FLT_OT_RETURN(); +} + + +/*** + * NAME + * ot_debug - + * + * ARGUMENTS + * This function takes no arguments. + * + * DESCRIPTION + * - + * + * RETURN VALUE + * This function does not return a value. + */ +void ot_debug(void) +{ + char buffer[BUFSIZ]; + + FLT_OT_FUNC(""); + + otc_statistics(buffer, sizeof(buffer)); + FLT_OT_DBG(0, "%s", buffer); + + FLT_OT_RETURN(); +} + +#endif /* DEBUG_OT */ + + +/*** + * NAME + * ot_mem_malloc - + * + * ARGUMENTS + * func - + * line - + * size - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +static void *ot_mem_malloc(FLT_OT_DBG_ARGS(const char *func, int line, ) size_t size) +{ + return flt_ot_pool_alloc(pool_head_ot_span_context, size, 1, NULL); +} + + +/*** + * NAME + * ot_mem_free - + * + * ARGUMENTS + * func - + * line - + * ptr - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * This function does not return a value. + */ +static void ot_mem_free(FLT_OT_DBG_ARGS(const char *func, int line, ) void *ptr) +{ + flt_ot_pool_free(pool_head_ot_span_context, &ptr); +} + + +/*** + * NAME + * ot_init - + * + * ARGUMENTS + * tracer - + * plugin - + * err - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +int ot_init(struct otc_tracer **tracer, const char *plugin, char **err) +{ + char cwd[PATH_MAX], path[PATH_MAX], errbuf[BUFSIZ] = ""; + int rc, retval = -1; + + FLT_OT_FUNC("%p:%p, \"%s\", %p:%p", FLT_OT_DPTR_ARGS(tracer), plugin, FLT_OT_DPTR_ARGS(err)); + + flt_ot_pools_info(); +#ifdef USE_POOL_OT_SPAN_CONTEXT + FLT_OT_DBG(2, "sizeof_pool(ot_span_context) = %u", pool_head_ot_span_context->size); +#endif + + if (getcwd(cwd, sizeof(cwd)) == NULL) { + FLT_OT_ERR("failed to get current working directory"); + + FLT_OT_RETURN_INT(retval); + } + rc = snprintf(path, sizeof(path), "%s/%s", cwd, plugin); + if ((rc == -1) || (rc >= sizeof(path))) { + FLT_OT_ERR("failed to construct the OpenTracing plugin path"); + + FLT_OT_RETURN_INT(retval); + } + + *tracer = otc_tracer_load(path, errbuf, sizeof(errbuf)); + if (*tracer == NULL) { + FLT_OT_ERR("%s", (*errbuf == '\0') ? "failed to initialize tracing library" : errbuf); + } else { + otc_ext_init(ot_mem_malloc, ot_mem_free); + + retval = 0; + } + + FLT_OT_RETURN_INT(retval); +} + + +/*** + * NAME + * ot_start - + * + * ARGUMENTS + * tracer - + * cfgbuf - + * err - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * This function does not return a value. + */ +int ot_start(struct otc_tracer *tracer, const char *cfgbuf, char **err) +{ + char errbuf[BUFSIZ] = ""; + int retval = -1; + + FLT_OT_FUNC("%p, %p, %p:%p", tracer, cfgbuf, FLT_OT_DPTR_ARGS(err)); + + if (cfgbuf == NULL) + FLT_OT_RETURN_INT(retval); + + retval = otc_tracer_start(NULL, cfgbuf, errbuf, sizeof(errbuf)); + if (retval == -1) + FLT_OT_ERR("%s", (*errbuf == '\0') ? "failed to start tracer" : errbuf); + + FLT_OT_RETURN_INT(retval); +} + + +/*** + * NAME + * ot_close - + * + * ARGUMENTS + * tracer - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * This function does not return a value. + */ +void ot_close(struct otc_tracer **tracer) +{ + FLT_OT_FUNC("%p:%p", FLT_OT_DPTR_ARGS(tracer)); + + if ((tracer == NULL) || (*tracer == NULL)) + FLT_OT_RETURN(); + + (*tracer)->close(*tracer); + + *tracer = NULL; + + FLT_OT_RETURN(); +} + + +/*** + * NAME + * ot_span_init - + * + * ARGUMENTS + * tracer - + * operation_name - + * ts_steady - + * ts_system - + * ref_type - + * ref_ctx_idx - + * ref_span - + * tags - + * num_tags - + * err - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +struct otc_span *ot_span_init(struct otc_tracer *tracer, const char *operation_name, const struct timespec *ts_steady, const struct timespec *ts_system, int ref_type, int ref_ctx_idx, const struct otc_span *ref_span, const struct otc_tag *tags, int num_tags, char **err) +{ + struct otc_start_span_options options; + struct otc_span_context context = { .idx = ref_ctx_idx, .span = ref_span }; + struct otc_span_reference references = { ref_type, &context }; + struct otc_span *retptr = NULL; + + FLT_OT_FUNC("%p, \"%s\", %p, %p, %d, %d, %p, %p, %d, %p:%p", tracer, operation_name, ts_steady, ts_system, ref_type, ref_ctx_idx, ref_span, tags, num_tags, FLT_OT_DPTR_ARGS(err)); + + if (operation_name == NULL) + FLT_OT_RETURN_PTR(retptr); + else if (tracer == NULL) + FLT_OT_RETURN_PTR(retptr); + + (void)memset(&options, 0, sizeof(options)); + + if (ts_steady != NULL) + (void)memcpy(&(options.start_time_steady.value), ts_steady, sizeof(options.start_time_steady.value)); + + if (ts_system != NULL) + (void)memcpy(&(options.start_time_system.value), ts_system, sizeof(options.start_time_system.value)); + + if (FLT_OT_IN_RANGE(ref_type, otc_span_reference_child_of, otc_span_reference_follows_from)) { + options.references = &references; + options.num_references = 1; + } + + options.tags = tags; + options.num_tags = num_tags; + + retptr = tracer->start_span_with_options(tracer, operation_name, &options); + if (retptr == NULL) + FLT_OT_ERR("failed to init new span"); + else + FLT_OT_DBG(2, "span %p:%zd initialized", retptr, retptr->idx); + + FLT_OT_RETURN_PTR(retptr); +} + + +/*** + * NAME + * ot_span_init_va - + * + * ARGUMENTS + * tracer - + * operation_name - + * ts_steady - + * ts_system - + * ref_type - + * ref_ctx_idx - + * ref_span - + * err - + * tag_key - + * tag_value - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +struct otc_span *ot_span_init_va(struct otc_tracer *tracer, const char *operation_name, const struct timespec *ts_steady, const struct timespec *ts_system, int ref_type, int ref_ctx_idx, const struct otc_span *ref_span, char **err, const char *tag_key, const char *tag_value, ...) +{ + struct otc_tag tags[FLT_OT_MAXTAGS]; + int num_tags = 0; + struct otc_span *retptr; + + FLT_OT_FUNC("%p, \"%s\", %p, %p, %d, %d, %p, %p:%p, \"%s\", \"%s\", ...", tracer, operation_name, ts_steady, ts_system, ref_type, ref_ctx_idx, ref_span, FLT_OT_DPTR_ARGS(err), tag_key, tag_value); + + if (tag_key != NULL) { + va_list ap; + + va_start(ap, tag_value); + for (num_tags = 0; (num_tags < FLT_OT_TABLESIZE(tags)) && (tag_key != NULL) && (tag_value != NULL); num_tags++) { + tags[num_tags].key = (char *)tag_key; + FLT_OT_VSET(&(tags[num_tags].value), string, tag_value); + + tag_key = va_arg(ap, typeof(tag_key)); + if (tag_key != NULL) + tag_value = va_arg(ap, typeof(tag_value)); + } + va_end(ap); + } + + retptr = ot_span_init(tracer, operation_name, ts_steady, ts_system, ref_type, ref_ctx_idx, ref_span, tags, num_tags, err); + + FLT_OT_RETURN_PTR(retptr); +} + + +/*** + * NAME + * ot_span_tag - + * + * ARGUMENTS + * span - + * tags - + * num_tags - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +int ot_span_tag(struct otc_span *span, const struct otc_tag *tags, int num_tags) +{ + int retval = -1; + + FLT_OT_FUNC("%p, %p, %d", span, tags, num_tags); + + if ((span == NULL) || (tags == NULL)) + FLT_OT_RETURN_INT(retval); + + for (retval = 0; retval < num_tags; retval++) + span->set_tag(span, tags[retval].key, &(tags[retval].value)); + + FLT_OT_RETURN_INT(retval); +} + + +/*** + * NAME + * ot_span_tag_va - + * + * ARGUMENTS + * span - + * key - + * type - + * value - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +int ot_span_tag_va(struct otc_span *span, const char *key, int type, ...) +{ + va_list ap; + struct otc_value ot_value; + int retval = -1; + + FLT_OT_FUNC("%p, \"%s\", %d, ...", span, key, type); + + if ((span == NULL) || (key == NULL)) + FLT_OT_RETURN_INT(retval); + + va_start(ap, type); + for (retval = 0; (key != NULL) && FLT_OT_IN_RANGE(type, otc_value_bool, otc_value_null); retval++) { + ot_value.type = type; + if (type == otc_value_bool) + ot_value.value.bool_value = va_arg(ap, typeof(ot_value.value.bool_value)); + else if (type == otc_value_double) + ot_value.value.double_value = va_arg(ap, typeof(ot_value.value.double_value)); + else if (type == otc_value_int64) + ot_value.value.int64_value = va_arg(ap, typeof(ot_value.value.int64_value)); + else if (type == otc_value_uint64) + ot_value.value.uint64_value = va_arg(ap, typeof(ot_value.value.uint64_value)); + else if (type == otc_value_string) + ot_value.value.string_value = va_arg(ap, typeof(ot_value.value.string_value)); + else if (type == otc_value_null) + ot_value.value.string_value = va_arg(ap, typeof(ot_value.value.string_value)); + span->set_tag(span, key, &ot_value); + + key = va_arg(ap, typeof(key)); + if (key != NULL) + type = va_arg(ap, typeof(type)); + } + va_end(ap); + + FLT_OT_RETURN_INT(retval); +} + + +/*** + * NAME + * ot_span_log - + * + * ARGUMENTS + * span - + * log_fields - + * num_fields - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +int ot_span_log(struct otc_span *span, const struct otc_log_field *log_fields, int num_fields) +{ + int retval = -1; + + FLT_OT_FUNC("%p, %p, %d", span, log_fields, num_fields); + + if ((span == NULL) || (log_fields == NULL)) + FLT_OT_RETURN_INT(retval); + + retval = MIN(OTC_MAXLOGFIELDS, num_fields); + + span->log_fields(span, log_fields, retval); + + FLT_OT_RETURN_INT(retval); +} + + +/*** + * NAME + * ot_span_log_va - + * + * ARGUMENTS + * span - + * key - + * value - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +int ot_span_log_va(struct otc_span *span, const char *key, const char *value, ...) +{ + va_list ap; + struct otc_log_field log_field[OTC_MAXLOGFIELDS]; + int retval = -1; + + FLT_OT_FUNC("%p, \"%s\", \"%s\", ...", span, key, value); + + if ((span == NULL) || (key == NULL) || (value == NULL)) + FLT_OT_RETURN_INT(retval); + + va_start(ap, value); + for (retval = 0; (retval < FLT_OT_TABLESIZE(log_field)) && (key != NULL); retval++) { + log_field[retval].key = key; + log_field[retval].value.type = otc_value_string; + log_field[retval].value.value.string_value = value; + + key = va_arg(ap, typeof(key)); + if (key != NULL) + value = va_arg(ap, typeof(value)); + } + va_end(ap); + + span->log_fields(span, log_field, retval); + + FLT_OT_RETURN_INT(retval); +} + + +/*** + * NAME + * ot_span_log_fmt - + * + * ARGUMENTS + * span - + * key - + * format - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +int ot_span_log_fmt(struct otc_span *span, const char *key, const char *format, ...) +{ + va_list ap; + char value[BUFSIZ]; + int n; + + FLT_OT_FUNC("%p, \"%s\", \"%s\", ...", span, key, format); + + if ((span == NULL) || (key == NULL) || (format == NULL)) + FLT_OT_RETURN_INT(-1); + + va_start(ap, format); + n = vsnprintf(value, sizeof(value), format, ap); + if (!FLT_OT_IN_RANGE(n, 0, sizeof(value) - 1)) { + FLT_OT_DBG(2, "WARNING: log buffer too small (%d > %zu)", n, sizeof(value)); + + FLT_OT_STR_ELLIPSIS(value, sizeof(value)); + } + va_end(ap); + + FLT_OT_RETURN_INT(ot_span_log_va(span, key, value, NULL)); +} + + +/*** + * NAME + * ot_span_set_baggage - + * + * ARGUMENTS + * span - + * baggage - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +int ot_span_set_baggage(struct otc_span *span, const struct otc_text_map *baggage) +{ + size_t i; + int retval = -1; + + FLT_OT_FUNC("%p, %p", span, baggage); + + if ((span == NULL) || (baggage == NULL)) + FLT_OT_RETURN_INT(retval); + + if ((baggage->key == NULL) || (baggage->value == NULL)) + FLT_OT_RETURN_INT(retval); + + for (retval = i = 0; i < baggage->count; i++) { + FLT_OT_DBG(3, "set baggage: \"%s\" -> \"%s\"", baggage->key[i], baggage->value[i]); + + if ((baggage->key[i] != NULL) && (baggage->value[i] != NULL)) { + span->set_baggage_item(span, baggage->key[i], baggage->value[i]); + + retval++; + } + } + + FLT_OT_RETURN_INT(retval); +} + + +/*** + * NAME + * ot_span_set_baggage_va - + * + * ARGUMENTS + * span - + * key - + * value - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +int ot_span_set_baggage_va(struct otc_span *span, const char *key, const char *value, ...) +{ + va_list ap; + int retval = -1; + + FLT_OT_FUNC("%p, \"%s\", \"%s\", ...", span, key, value); + + if ((span == NULL) || (key == NULL) || (value == NULL)) + FLT_OT_RETURN_INT(retval); + + va_start(ap, value); + for (retval = 0; (key != NULL); retval++) { + FLT_OT_DBG(3, "set baggage: \"%s\" -> \"%s\"", key, value); + + span->set_baggage_item(span, key, value); + + key = va_arg(ap, typeof(key)); + if (key != NULL) + value = va_arg(ap, typeof(value)); + } + va_end(ap); + + FLT_OT_RETURN_INT(retval); +} + + +/*** + * NAME + * ot_span_baggage_va - + * + * ARGUMENTS + * span - + * key - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +struct otc_text_map *ot_span_baggage_va(const struct otc_span *span, const char *key, ...) +{ + va_list ap; + struct otc_text_map *retptr = NULL; + int i, n; + + FLT_OT_FUNC("%p, \"%s\", ...", span, key); + + if ((span == NULL) || (key == NULL)) + FLT_OT_RETURN_PTR(retptr); + + va_start(ap, key); + for (n = 1; va_arg(ap, typeof(key)) != NULL; n++); + va_end(ap); + + retptr = otc_text_map_new(NULL, n); + if (retptr == NULL) + FLT_OT_RETURN_PTR(retptr); + + va_start(ap, key); + for (i = 0; (i < n) && (key != NULL); i++) { + char *value = (char *)span->baggage_item(span, key); + + if (value != NULL) { + (void)otc_text_map_add(retptr, key, 0, value, 0, OTC_TEXT_MAP_DUP_KEY | OTC_TEXT_MAP_DUP_VALUE); + + FLT_OT_DBG(3, "get baggage[%d]: \"%s\" -> \"%s\"", i, retptr->key[i], retptr->value[i]); + } else { + FLT_OT_DBG(3, "get baggage[%d]: \"%s\" -> invalid key", i, key); + } + + key = va_arg(ap, typeof(key)); + } + va_end(ap); + + FLT_OT_RETURN_PTR(retptr); +} + + +/*** + * NAME + * ot_inject_text_map - + * + * ARGUMENTS + * tracer - + * span - + * carrier - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +struct otc_span_context *ot_inject_text_map(struct otc_tracer *tracer, const struct otc_span *span, struct otc_text_map_writer *carrier) +{ + struct otc_span_context *retptr = NULL; + int rc; + + FLT_OT_FUNC("%p, %p, %p", tracer, span, carrier); + + if ((span == NULL) || (carrier == NULL)) + FLT_OT_RETURN_PTR(retptr); + else if (tracer == NULL) + FLT_OT_RETURN_PTR(retptr); + + retptr = span->span_context((struct otc_span *)span); + if (retptr == NULL) + FLT_OT_RETURN_PTR(retptr); + + (void)memset(carrier, 0, sizeof(*carrier)); + + rc = tracer->inject_text_map(tracer, carrier, retptr); + if (rc != otc_propagation_error_code_success) { + FLT_OT_FREE_CLEAR(retptr); + } else { +#ifdef DEBUG_OT + FLT_OT_DBG_TEXT_CARRIER(carrier, set); + ot_text_map_show(&(carrier->text_map)); + FLT_OT_DBG_SPAN_CONTEXT(retptr); +#endif + } + + FLT_OT_RETURN_PTR(retptr); +} + + +/*** + * NAME + * ot_inject_http_headers - + * + * ARGUMENTS + * tracer - + * span - + * carrier - + * err - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +struct otc_span_context *ot_inject_http_headers(struct otc_tracer *tracer, const struct otc_span *span, struct otc_http_headers_writer *carrier, char **err) +{ + struct otc_span_context *retptr = NULL; + int rc; + + FLT_OT_FUNC("%p, %p, %p, %p:%p", tracer, span, carrier, FLT_OT_DPTR_ARGS(err)); + + if ((span == NULL) || (carrier == NULL)) + FLT_OT_RETURN_PTR(retptr); + else if (tracer == NULL) + FLT_OT_RETURN_PTR(retptr); + + retptr = span->span_context((struct otc_span *)span); + if (retptr == NULL) { + FLT_OT_ERR("failed to create span context"); + + FLT_OT_RETURN_PTR(retptr); + } + + (void)memset(carrier, 0, sizeof(*carrier)); + + rc = tracer->inject_http_headers(tracer, carrier, retptr); + if (rc != otc_propagation_error_code_success) { + FLT_OT_ERR("failed to inject HTTP headers data"); + + FLT_OT_FREE_CLEAR(retptr); + } else { +#ifdef DEBUG_OT + FLT_OT_DBG_TEXT_CARRIER(carrier, set); + ot_text_map_show(&(carrier->text_map)); + FLT_OT_DBG_SPAN_CONTEXT(retptr); +#endif + } + + FLT_OT_RETURN_PTR(retptr); +} + + +/*** + * NAME + * ot_inject_binary - + * + * ARGUMENTS + * tracer - + * span - + * carrier - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +struct otc_span_context *ot_inject_binary(struct otc_tracer *tracer, const struct otc_span *span, struct otc_custom_carrier_writer *carrier) +{ + struct otc_span_context *retptr = NULL; + int rc; + + FLT_OT_FUNC("%p, %p, %p", tracer, span, carrier); + + if ((span == NULL) || (carrier == NULL)) + FLT_OT_RETURN_PTR(retptr); + else if (tracer == NULL) + FLT_OT_RETURN_PTR(retptr); + + retptr = span->span_context((struct otc_span *)span); + if (retptr == NULL) + FLT_OT_RETURN_PTR(retptr); + + (void)memset(carrier, 0, sizeof(*carrier)); + + rc = tracer->inject_binary(tracer, carrier, retptr); + if (rc != otc_propagation_error_code_success) { + FLT_OT_FREE_CLEAR(retptr); + } else { +#ifdef DEBUG_OT + struct otc_jaeger_trace_context *ctx = carrier->binary_data.data; + + FLT_OT_DBG_CUSTOM_CARRIER(carrier, inject); + FLT_OT_DBG(3, "trace context: %016" PRIx64 "%016" PRIx64 ":%016" PRIx64 ":%016" PRIx64 ":%02hhx <%s> <%s>", + ctx->trace_id[0], ctx->trace_id[1], ctx->span_id, ctx->parent_span_id, ctx->flags, + flt_ot_str_hex(ctx->baggage, carrier->binary_data.size - sizeof(*ctx)), + flt_ot_str_ctrl(ctx->baggage, carrier->binary_data.size - sizeof(*ctx))); + FLT_OT_DBG_SPAN_CONTEXT(retptr); +#endif + } + + FLT_OT_RETURN_PTR(retptr); +} + + +/*** + * NAME + * ot_extract_text_map - + * + * ARGUMENTS + * tracer - + * carrier - + * text_map - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +struct otc_span_context *ot_extract_text_map(struct otc_tracer *tracer, struct otc_text_map_reader *carrier, const struct otc_text_map *text_map) +{ + struct otc_span_context *retptr = NULL; + int rc; + + FLT_OT_FUNC("%p, %p, %p", tracer, carrier, text_map); + + if (carrier == NULL) + FLT_OT_RETURN_PTR(retptr); + else if (tracer == NULL) + FLT_OT_RETURN_PTR(retptr); + + if (text_map != NULL) { + (void)memset(carrier, 0, sizeof(*carrier)); + (void)memcpy(&(carrier->text_map), text_map, sizeof(carrier->text_map)); + + FLT_OT_DBG_TEXT_CARRIER(carrier, foreach_key); + } + + rc = tracer->extract_text_map(tracer, carrier, &retptr); + if (rc != otc_propagation_error_code_success) + FLT_OT_FREE_CLEAR(retptr); + else if (retptr != NULL) + FLT_OT_DBG_SPAN_CONTEXT(retptr); + + FLT_OT_RETURN_PTR(retptr); +} + + +/*** + * NAME + * ot_extract_http_headers - + * + * ARGUMENTS + * tracer - + * carrier - + * text_map - + * err - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +struct otc_span_context *ot_extract_http_headers(struct otc_tracer *tracer, struct otc_http_headers_reader *carrier, const struct otc_text_map *text_map, char **err) +{ + struct otc_span_context *retptr = NULL; + int rc; + + FLT_OT_FUNC("%p, %p, %p, %p:%p", tracer, carrier, text_map, FLT_OT_DPTR_ARGS(err)); + + if (carrier == NULL) + FLT_OT_RETURN_PTR(retptr); + else if (tracer == NULL) + FLT_OT_RETURN_PTR(retptr); + + if (text_map != NULL) { + (void)memset(carrier, 0, sizeof(*carrier)); + (void)memcpy(&(carrier->text_map), text_map, sizeof(carrier->text_map)); + + FLT_OT_DBG_TEXT_CARRIER(carrier, foreach_key); + } + + rc = tracer->extract_http_headers(tracer, carrier, &retptr); + if (rc != otc_propagation_error_code_success) { + FLT_OT_ERR("failed to extract HTTP headers data"); + + FLT_OT_FREE_CLEAR(retptr); + } + else if (retptr != NULL) + FLT_OT_DBG_SPAN_CONTEXT(retptr); + + FLT_OT_RETURN_PTR(retptr); +} + + +/*** + * NAME + * ot_extract_binary - + * + * ARGUMENTS + * tracer - + * carrier - + * binary_data - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +struct otc_span_context *ot_extract_binary(struct otc_tracer *tracer, struct otc_custom_carrier_reader *carrier, const struct otc_binary_data *binary_data) +{ + struct otc_span_context *retptr = NULL; + int rc; + + FLT_OT_FUNC("%p, %p, %p", tracer, carrier, binary_data); + + if (carrier == NULL) + FLT_OT_RETURN_PTR(retptr); + else if (tracer == NULL) + FLT_OT_RETURN_PTR(retptr); + + if ((FLT_OT_DEREF(binary_data, data, NULL) != NULL) && (binary_data->size > 0)) { + (void)memset(carrier, 0, sizeof(*carrier)); + (void)memcpy(&(carrier->binary_data), binary_data, sizeof(carrier->binary_data)); + + FLT_OT_DBG_CUSTOM_CARRIER(carrier, extract); + } + + rc = tracer->extract_binary(tracer, carrier, &retptr); + if (rc != otc_propagation_error_code_success) + FLT_OT_FREE_CLEAR(retptr); + else if (retptr != NULL) + FLT_OT_DBG_SPAN_CONTEXT(retptr); + + FLT_OT_RETURN_PTR(retptr); +} + + +/*** + * NAME + * ot_span_finish - + * + * ARGUMENTS + * span - + * ts_finish - + * log_ts - + * log_key - + * log_value - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * This function does not return a value. + */ +void ot_span_finish(struct otc_span **span, const struct timespec *ts_finish, const struct timespec *log_ts, const char *log_key, const char *log_value, ...) +{ + struct otc_finish_span_options options; + struct otc_log_field log_field[OTC_MAXLOGFIELDS]; + struct otc_log_record log_records = { .fields = log_field, .num_fields = 0 }; +#ifdef DEBUG_OT + typeof((*span)->idx) idx = FLT_OT_DDEREF(span, idx, 0); +#endif + + FLT_OT_FUNC("%p:%p, %p, %p, \"%s\", \"%s\", ...", FLT_OT_DPTR_ARGS(span), ts_finish, log_ts, log_key, log_value); + + if ((span == NULL) || (*span == NULL)) + FLT_OT_RETURN(); + + (void)memset(&options, 0, sizeof(options)); + + if (ts_finish != NULL) + (void)memcpy(&(options.finish_time.value), ts_finish, sizeof(options.finish_time.value)); + + if (log_key != NULL) { + va_list ap; + int i; + + if (log_ts != NULL) + (void)memcpy(&(log_records.timestamp.value), log_ts, sizeof(log_records.timestamp.value)); + + va_start(ap, log_value); + for (i = 0; (i < FLT_OT_TABLESIZE(log_field)) && (log_key != NULL); i++) { + log_field[i].key = log_key; + log_field[i].value.type = otc_value_string; + log_field[i].value.value.string_value = log_value; + + log_key = va_arg(ap, typeof(log_key)); + if (log_key != NULL) + log_value = va_arg(ap, typeof(log_value)); + } + va_end(ap); + + log_records.num_fields = i; + options.log_records = &log_records; + options.num_log_records = 1; + } + + /* + * Caution: memory allocated for the span is released + * in the function finish_with_options(). + */ + (*span)->finish_with_options(*span, &options); + + FLT_OT_DBG(2, "span %p:%zu finished", *span, idx); + + *span = NULL; + + FLT_OT_RETURN(); +} + +/* + * Local variables: + * c-indent-level: 8 + * c-basic-offset: 8 + * End: + * + * vi: noexpandtab shiftwidth=8 tabstop=8 + */ diff --git a/addons/ot/src/parser.c b/addons/ot/src/parser.c new file mode 100644 index 0000000..1fd7007 --- /dev/null +++ b/addons/ot/src/parser.c @@ -0,0 +1,1225 @@ +/*** + * Copyright 2020 HAProxy Technologies + * + * This file is part of the HAProxy OpenTracing filter. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include "include.h" + + +#ifdef DEBUG_OT +struct flt_ot_debug flt_ot_debug; +THREAD_LOCAL int dbg_indent_level = 0; +#endif + +#ifdef OTC_DBG_MEM +static struct otc_dbg_mem_data dbg_mem_data[1000000]; +static struct otc_dbg_mem dbg_mem; +#endif + +static struct flt_ot_conf *flt_ot_current_config = NULL; +static struct flt_ot_conf_tracer *flt_ot_current_tracer = NULL; +static struct flt_ot_conf_group *flt_ot_current_group = NULL; +static struct flt_ot_conf_scope *flt_ot_current_scope = NULL; +static struct flt_ot_conf_span *flt_ot_current_span = NULL; + + +/*** + * NAME + * flt_ot_parse_strdup - + * + * ARGUMENTS + * ptr - + * str - + * err - + * err_msg - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * Returns ERR_NONE (== 0) in case of success, + * or a combination of ERR_* flags if an error is encountered. + */ +static int flt_ot_parse_strdup(char **ptr, const char *str, char **err, const char *err_msg) +{ + int retval = ERR_NONE; + + FLT_OT_FUNC("%p:%p, %p, %p:%p, \"%s\"", FLT_OT_DPTR_ARGS(ptr), str, FLT_OT_DPTR_ARGS(err), err_msg); + + *ptr = FLT_OT_STRDUP(str); + if (*ptr == NULL) { + FLT_OT_PARSE_ERR(err, "'%s' : out of memory", err_msg); + + retval |= ERR_ABORT | ERR_ALERT; + } + + FLT_OT_RETURN_INT(retval); +} + + +/*** + * NAME + * flt_ot_parse_keyword - + * + * ARGUMENTS + * ptr - + * args - + * cur_arg - + * pos - + * err - + * err_msg - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * Returns ERR_NONE (== 0) in case of success, + * or a combination of ERR_* flags if an error is encountered. + */ +static int flt_ot_parse_keyword(char **ptr, char **args, int cur_arg, int pos, char **err, const char *err_msg) +{ + int retval = ERR_NONE; + + FLT_OT_FUNC("%p:%p, %p, %d, %d, %p:%p, \"%s\"", FLT_OT_DPTR_ARGS(ptr), args, cur_arg, pos, FLT_OT_DPTR_ARGS(err), err_msg); + + if (*ptr != NULL) { + if (cur_arg == pos) + FLT_OT_PARSE_ERR(err, FLT_OT_FMT_TYPE "%s already set", err_msg); + else + FLT_OT_PARSE_ERR(err, "'%s' : %s already set", args[cur_arg], err_msg); + } + else if (!FLT_OT_ARG_ISVALID(pos + 1)) { + if (cur_arg == pos) + FLT_OT_PARSE_ERR(err, FLT_OT_FMT_TYPE "no %s set", err_msg); + else + FLT_OT_PARSE_ERR(err, "'%s' : no %s set", args[cur_arg], err_msg); + } + else { + retval = flt_ot_parse_strdup(ptr, args[pos + 1], err, args[cur_arg]); + } + + FLT_OT_RETURN_INT(retval); +} + + +/*** + * NAME + * flt_ot_parse_invalid_char - + * + * ARGUMENTS + * name - + * type - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +static const char *flt_ot_parse_invalid_char(const char *name, int type) +{ + const char *retptr = NULL; + + FLT_OT_FUNC("\"%s\", %d", name, type); + + if (!FLT_OT_STR_ISVALID(name)) + FLT_OT_RETURN_EX(retptr, const char *, "%p"); + + if (type == FLT_OT_PARSE_INVALID_CHAR) { + retptr = invalid_char(name); + } + else if (type == FLT_OT_PARSE_INVALID_DOM) { + retptr = invalid_domainchar(name); + } + else if (type == FLT_OT_PARSE_INVALID_CTX) { + retptr = invalid_prefix_char(name); + } + else if (type == FLT_OT_PARSE_INVALID_VAR) { + retptr = name; + + /* + * Allowed characters are letters, numbers and '_', the first + * character in the string must not be a number. + */ + if (!isdigit(*retptr)) + for (++retptr; (*retptr == '_') || isalnum(*retptr); retptr++); + + if (*retptr == '\0') + retptr = NULL; + } + + FLT_OT_RETURN_EX(retptr, const char *, "%p"); +} + + +/*** + * NAME + * flt_ot_parse_cfg_check - + * + * ARGUMENTS + * file - + * linenum - + * args - + * id - + * parse_data - + * parse_data_size - + * pdata - + * err - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * Returns ERR_NONE (== 0) in case of success, + * or a combination of ERR_* flags if an error is encountered. + */ +static int flt_ot_parse_cfg_check(const char *file, int linenum, char **args, const void *id, const struct flt_ot_parse_data *parse_data, size_t parse_data_size, const struct flt_ot_parse_data **pdata, char **err) +{ + int i, argc, retval = ERR_NONE; + + FLT_OT_FUNC("\"%s\", %d, %p, %p, %p, %zu, %p:%p, %p:%p", file, linenum, args, id, parse_data, parse_data_size, FLT_OT_DPTR_ARGS(pdata), FLT_OT_DPTR_ARGS(err)); + + FLT_OT_ARGS_DUMP(); + + *pdata = NULL; + + /* First check here if args[0] is the correct keyword. */ + for (i = 0; (*pdata == NULL) && (i < parse_data_size); i++) + if (strcmp(parse_data[i].name, args[0]) == 0) + *pdata = parse_data + i; + + if (*pdata == NULL) + FLT_OT_PARSE_ERR(err, "'%s' : unknown keyword", args[0]); + else + argc = flt_ot_args_count(args); + + if ((retval & ERR_CODE) || (id == NULL)) + /* Do nothing. */; + else if ((id != flt_ot_current_tracer) && (flt_ot_current_config->tracer == NULL)) + FLT_OT_PARSE_ERR(err, "tracer not defined"); + + /* + * Checking that fewer arguments are specified in the configuration + * line than is required. + */ + if (!(retval & ERR_CODE)) + if (argc < (*pdata)->args_min) + FLT_OT_PARSE_ERR(err, "'%s' : too few arguments (use '%s%s')", args[0], (*pdata)->name, (*pdata)->usage); + + /* + * Checking that more arguments are specified in the configuration + * line than the maximum allowed. + */ + if (!(retval & ERR_CODE) && ((*pdata)->args_max > 0)) + if (argc > (*pdata)->args_max) + FLT_OT_PARSE_ERR(err, "'%s' : too many arguments (use '%s%s')", args[0], (*pdata)->name, (*pdata)->usage); + + /* Checking that the first argument has only allowed characters. */ + if (!(retval & ERR_CODE) && ((*pdata)->check_name != FLT_OT_PARSE_INVALID_NONE)) { + const char *ic; + + ic = flt_ot_parse_invalid_char(args[1], (*pdata)->check_name); + if (ic != NULL) + FLT_OT_PARSE_ERR(err, "%s '%s' : invalid character '%c'", args[0], args[1], *ic); + } + + /* Checking that the data group name is defined. */ + if (!(retval & ERR_CODE) && (*pdata)->flag_check_id && (id == NULL)) + FLT_OT_PARSE_ERR(err, "'%s' : %s ID not set (use '%s%s')", args[0], parse_data[1].name, parse_data[1].name, parse_data[1].usage); + + FLT_OT_RETURN_INT(retval); +} + + +/*** + * NAME + * flt_ot_parse_cfg_sample_expr - + * + * ARGUMENTS + * file - + * linenum - + * args - + * idx - + * head - + * err - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * Returns ERR_NONE (== 0) in case of success, + * or a combination of ERR_* flags if an error is encountered. + */ +static int flt_ot_parse_cfg_sample_expr(const char *file, int linenum, char **args, int *idx, struct list *head, char **err) +{ + struct flt_ot_conf_sample_expr *expr; + int retval = ERR_NONE; + + FLT_OT_FUNC("\"%s\", %d, %p, %p, %p, %p:%p", file, linenum, args, idx, head, FLT_OT_DPTR_ARGS(err)); + + expr = flt_ot_conf_sample_expr_init(args[*idx], linenum, head, err); + if (expr != NULL) { + expr->expr = sample_parse_expr(args, idx, file, linenum, err, &(flt_ot_current_config->proxy->conf.args), NULL); + if (expr->expr != NULL) + FLT_OT_DBG(3, "sample expression '%s' added", expr->value); + else + retval |= ERR_ABORT | ERR_ALERT; + } else { + retval |= ERR_ABORT | ERR_ALERT; + } + + if (retval & ERR_CODE) + flt_ot_conf_sample_expr_free(&expr); + + FLT_OT_RETURN_INT(retval); +} + + +/*** + * NAME + * flt_ot_parse_cfg_sample - + * + * ARGUMENTS + * file - + * linenum - + * args - + * head - + * err - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * Returns ERR_NONE (== 0) in case of success, + * or a combination of ERR_* flags if an error is encountered. + */ +static int flt_ot_parse_cfg_sample(const char *file, int linenum, char **args, struct list *head, char **err) +{ + struct flt_ot_conf_sample *sample; + int idx = 2, retval = ERR_NONE; + + FLT_OT_FUNC("\"%s\", %d, %p, %p, %p:%p", file, linenum, args, head, FLT_OT_DPTR_ARGS(err)); + + sample = flt_ot_conf_sample_init(args, linenum, head, err); + if (sample == NULL) + FLT_OT_PARSE_ERR(err, "'%s' : out of memory", args[0]); + + if (!(retval & ERR_CODE)) { + flt_ot_current_config->proxy->conf.args.ctx = ARGC_OT; + flt_ot_current_config->proxy->conf.args.file = file; + flt_ot_current_config->proxy->conf.args.line = linenum; + + while (!(retval & ERR_CODE) && FLT_OT_ARG_ISVALID(idx)) + retval = flt_ot_parse_cfg_sample_expr(file, linenum, args, &idx, &(sample->exprs), err); + + flt_ot_current_config->proxy->conf.args.file = NULL; + flt_ot_current_config->proxy->conf.args.line = 0; + } + + if (retval & ERR_CODE) + flt_ot_conf_sample_free(&sample); + else + FLT_OT_DBG(3, "sample '%s' -> '%s' added", sample->key, sample->value); + + FLT_OT_RETURN_INT(retval); +} + + +/*** + * NAME + * flt_ot_parse_cfg_str - + * + * ARGUMENTS + * file - + * linenum - + * args - + * head - + * err - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * Returns ERR_NONE (== 0) in case of success, + * or a combination of ERR_* flags if an error is encountered. + */ +static int flt_ot_parse_cfg_str(const char *file, int linenum, char **args, struct list *head, char **err) +{ + struct flt_ot_conf_str *str = NULL; + int i, retval = ERR_NONE; + + FLT_OT_FUNC("\"%s\", %d, %p, %p, %p:%p", file, linenum, args, head, FLT_OT_DPTR_ARGS(err)); + + for (i = 1; !(retval & ERR_CODE) && FLT_OT_ARG_ISVALID(i); i++) + if (flt_ot_conf_str_init(args[i], linenum, head, err) == NULL) + retval |= ERR_ABORT | ERR_ALERT; + + if (retval & ERR_CODE) + flt_ot_conf_str_free(&str); + + FLT_OT_RETURN_INT(retval); +} + + +/*** + * NAME + * flt_ot_parse_cfg_file - + * + * ARGUMENTS + * ptr - + * file - + * linenum - + * args - + * err - + * err_msg - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * Returns ERR_NONE (== 0) in case of success, + * or a combination of ERR_* flags if an error is encountered. + */ +static int flt_ot_parse_cfg_file(char **ptr, const char *file, int linenum, char **args, char **err, const char *err_msg) +{ + int retval = ERR_NONE; + + FLT_OT_FUNC("%p:%p, \"%s\", %d, %p, %p:%p, \"%s\"", FLT_OT_DPTR_ARGS(ptr), file, linenum, args, FLT_OT_DPTR_ARGS(err), err_msg); + + if (!FLT_OT_ARG_ISVALID(1)) + FLT_OT_PARSE_ERR(err, "'%s' : no %s specified", flt_ot_current_tracer->id, err_msg); + else if (alertif_too_many_args(1, file, linenum, args, &retval)) + retval |= ERR_ABORT | ERR_ALERT; + else if (access(args[1], R_OK) == -1) + FLT_OT_PARSE_ERR(err, "'%s' : %s", args[1], strerror(errno)); + else + retval = flt_ot_parse_keyword(ptr, args, 0, 0, err, err_msg); + + FLT_OT_RETURN_INT(retval); +} + + +/*** + * NAME + * flt_ot_parse_check_scope - + * + * ARGUMENTS + * This function takes no arguments. + * + * DESCRIPTION + * - + * + * RETURN VALUE + * Returns TRUE in case the configuration is not in the currently defined + * scope, FALSE otherwise. + */ +static bool flt_ot_parse_check_scope(void) +{ + bool retval = 0; + + if ((cfg_scope != NULL) && (flt_ot_current_config->id != NULL) && (strcmp(flt_ot_current_config->id, cfg_scope) != 0)) { + FLT_OT_DBG(1, "cfg_scope: '%s', id: '%s'", cfg_scope, flt_ot_current_config->id); + + retval = 1; + } + + return retval; +} + + +/*** + * NAME + * flt_ot_parse_cfg_tracer - + * + * ARGUMENTS + * file - + * linenum - + * args - + * kw_mod - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * Returns ERR_NONE (== 0) in case of success, + * or a combination of ERR_* flags if an error is encountered. + */ +static int flt_ot_parse_cfg_tracer(const char *file, int linenum, char **args, int kw_mod) +{ +#define FLT_OT_PARSE_TRACER_DEF(a,b,c,d,e,f,g) { FLT_OT_PARSE_TRACER_##a, b, FLT_OT_PARSE_INVALID_##c, d, e, f, g }, + static const struct flt_ot_parse_data parse_data[] = { FLT_OT_PARSE_TRACER_DEFINES }; +#undef FLT_OT_PARSE_TRACER_DEF + const struct flt_ot_parse_data *pdata = NULL; + char *err = NULL, *err_log = NULL; + int i, retval = ERR_NONE; + + FLT_OT_FUNC("\"%s\", %d, %p, 0x%08x", file, linenum, args, kw_mod); + + if (flt_ot_parse_check_scope()) + FLT_OT_RETURN_INT(retval); + + retval = flt_ot_parse_cfg_check(file, linenum, args, flt_ot_current_tracer, parse_data, FLT_OT_TABLESIZE(parse_data), &pdata, &err); + if (retval & ERR_CODE) { + FLT_OT_PARSE_IFERR_ALERT(); + + FLT_OT_RETURN_INT(retval); + } + + if (pdata->keyword == FLT_OT_PARSE_TRACER_ID) { + if (flt_ot_current_config->tracer != NULL) { + FLT_OT_PARSE_ERR(&err, "'%s' : tracer can be defined only once", args[1]); + } else { + flt_ot_current_tracer = flt_ot_conf_tracer_init(args[1], linenum, &err); + if (flt_ot_current_tracer == NULL) + retval |= ERR_ABORT | ERR_ALERT; + } + } + else if (pdata->keyword == FLT_OT_PARSE_TRACER_LOG) { + if (parse_logsrv(args, &(flt_ot_current_tracer->proxy_log.logsrvs), kw_mod == KWM_NO, file, linenum, &err_log) == 0) { + FLT_OT_PARSE_ERR(&err, "'%s %s ...' : %s", args[0], args[1], err_log); + FLT_OT_FREE_CLEAR(err_log); + + retval |= ERR_ABORT | ERR_ALERT; + } else { + flt_ot_current_tracer->logging |= FLT_OT_LOGGING_ON; + } + } + else if (pdata->keyword == FLT_OT_PARSE_TRACER_CONFIG) { + retval = flt_ot_parse_cfg_file(&(flt_ot_current_tracer->config), file, linenum, args, &err, "configuration file"); + } + else if (pdata->keyword == FLT_OT_PARSE_TRACER_PLUGIN) { + retval = flt_ot_parse_cfg_file(&(flt_ot_current_tracer->plugin), file, linenum, args, &err, "plugin library"); + } + else if (pdata->keyword == FLT_OT_PARSE_TRACER_GROUPS) { + for (i = 1; !(retval & ERR_CODE) && FLT_OT_ARG_ISVALID(i); i++) + if (flt_ot_conf_ph_init(args[i], linenum, &(flt_ot_current_tracer->ph_groups), &err) == NULL) + retval |= ERR_ABORT | ERR_ALERT; + } + else if (pdata->keyword == FLT_OT_PARSE_TRACER_SCOPES) { + for (i = 1; !(retval & ERR_CODE) && FLT_OT_ARG_ISVALID(i); i++) + if (flt_ot_conf_ph_init(args[i], linenum, &(flt_ot_current_tracer->ph_scopes), &err) == NULL) + retval |= ERR_ABORT | ERR_ALERT; + } + else if (pdata->keyword == FLT_OT_PARSE_TRACER_ACL) { + if (strcasecmp(args[1], "or") == 0) + FLT_OT_PARSE_ERR(&err, "'%s %s ...' : invalid ACL name", args[0], args[1]); + else if (parse_acl((const char **)args + 1, &(flt_ot_current_tracer->acls), &err, &(flt_ot_current_config->proxy->conf.args), file, linenum) == NULL) + retval |= ERR_ABORT | ERR_ALERT; + } + else if (pdata->keyword == FLT_OT_PARSE_TRACER_RATE_LIMIT) { + flt_ot_current_tracer->rate_limit = FLT_OT_FLOAT_U32(flt_ot_strtod(args[1], 0.0, FLT_OT_RATE_LIMIT_MAX, &err), FLT_OT_RATE_LIMIT_MAX); + } + else if (pdata->keyword == FLT_OT_PARSE_TRACER_OPTION) { + if (strcmp(args[1], FLT_OT_PARSE_OPTION_DISABLED) == 0) { + flt_ot_current_tracer->flag_disabled = (kw_mod == KWM_NO) ? 0 : 1; + } + else if (strcmp(args[1], FLT_OT_PARSE_OPTION_HARDERR) == 0) { + flt_ot_current_tracer->flag_harderr = (kw_mod == KWM_NO) ? 0 : 1; + } + else if (strcmp(args[1], FLT_OT_PARSE_OPTION_NOLOGNORM) == 0) { + if (kw_mod == KWM_NO) + flt_ot_current_tracer->logging &= ~FLT_OT_LOGGING_NOLOGNORM; + else + flt_ot_current_tracer->logging |= FLT_OT_LOGGING_NOLOGNORM; + } + else + FLT_OT_PARSE_ERR(&err, "'%s' : unknown option '%s'", args[0], args[1]); + } +#ifdef DEBUG_OT + else if (pdata->keyword == FLT_OT_PARSE_TRACER_DEBUG_LEVEL) { + flt_ot_debug.level = flt_ot_strtoll(args[1], 0, 255, &err); + } +#else + else { + FLT_OT_PARSE_WARNING("'%s' : keyword ignored", file, linenum, args[0]); + } +#endif + + FLT_OT_PARSE_IFERR_ALERT(); + + if ((retval & ERR_CODE) && (flt_ot_current_tracer != NULL)) + flt_ot_conf_tracer_free(&flt_ot_current_tracer); + + FLT_OT_RETURN_INT(retval); +} + + +/*** + * NAME + * flt_ot_post_parse_cfg_tracer - + * + * ARGUMENTS + * This function takes no arguments. + * + * DESCRIPTION + * - + * + * RETURN VALUE + * Returns ERR_NONE (== 0) in case of success, + * or a combination of ERR_* flags if an error is encountered. + */ +static int flt_ot_post_parse_cfg_tracer(void) +{ + char errbuf[BUFSIZ] = ""; + int retval = ERR_NONE; + + FLT_OT_FUNC(""); + + if (flt_ot_current_tracer == NULL) + FLT_OT_RETURN_INT(retval); + + flt_ot_current_config->tracer = flt_ot_current_tracer; + + if (flt_ot_current_tracer->id == NULL) + FLT_OT_RETURN_INT(retval); + + if (flt_ot_current_tracer->config == NULL) { + FLT_OT_POST_PARSE_ALERT("tracer '%s' has no configuration file specified", flt_ot_current_tracer->cfg_line, flt_ot_current_tracer->id); + } else { + flt_ot_current_tracer->cfgbuf = otc_file_read(flt_ot_current_tracer->config, "#", errbuf, sizeof(errbuf)); + if (flt_ot_current_tracer->cfgbuf == NULL) + FLT_OT_POST_PARSE_ALERT("tracer '%s' %s", flt_ot_current_tracer->cfg_line, flt_ot_current_tracer->id, (*errbuf == '\0') ? "cannot load configuration file" : errbuf); + } + + if (flt_ot_current_tracer->plugin == NULL) + FLT_OT_POST_PARSE_ALERT("tracer '%s' has no plugin library specified", flt_ot_current_tracer->cfg_line, flt_ot_current_tracer->id); + + flt_ot_current_tracer = NULL; + + FLT_OT_RETURN_INT(retval); +} + + +/*** + * NAME + * flt_ot_parse_cfg_group - + * + * ARGUMENTS + * file - + * linenum - + * args - + * kw_mod - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * Returns ERR_NONE (== 0) in case of success, + * or a combination of ERR_* flags if an error is encountered. + */ +static int flt_ot_parse_cfg_group(const char *file, int linenum, char **args, int kw_mod) +{ +#define FLT_OT_PARSE_GROUP_DEF(a,b,c,d,e,f,g) { FLT_OT_PARSE_GROUP_##a, b, FLT_OT_PARSE_INVALID_##c, d, e, f, g }, + static const struct flt_ot_parse_data parse_data[] = { FLT_OT_PARSE_GROUP_DEFINES }; +#undef FLT_OT_PARSE_GROUP_DEF + const struct flt_ot_parse_data *pdata = NULL; + char *err = NULL; + int i, retval = ERR_NONE; + + FLT_OT_FUNC("\"%s\", %d, %p, 0x%08x", file, linenum, args, kw_mod); + + if (flt_ot_parse_check_scope()) + FLT_OT_RETURN_INT(retval); + + retval = flt_ot_parse_cfg_check(file, linenum, args, flt_ot_current_group, parse_data, FLT_OT_TABLESIZE(parse_data), &pdata, &err); + if (retval & ERR_CODE) { + FLT_OT_PARSE_IFERR_ALERT(); + + FLT_OT_RETURN_INT(retval); + } + + if (pdata->keyword == FLT_OT_PARSE_GROUP_ID) { + flt_ot_current_group = flt_ot_conf_group_init(args[1], linenum, &(flt_ot_current_config->groups), &err); + if (flt_ot_current_config == NULL) + retval |= ERR_ABORT | ERR_ALERT; + } + else if (pdata->keyword == FLT_OT_PARSE_GROUP_SCOPES) { + for (i = 1; !(retval & ERR_CODE) && FLT_OT_ARG_ISVALID(i); i++) + if (flt_ot_conf_ph_init(args[i], linenum, &(flt_ot_current_group->ph_scopes), &err) == NULL) + retval |= ERR_ABORT | ERR_ALERT; + } + + FLT_OT_PARSE_IFERR_ALERT(); + + if ((retval & ERR_CODE) && (flt_ot_current_group != NULL)) + flt_ot_conf_group_free(&flt_ot_current_group); + + FLT_OT_RETURN_INT(retval); +} + + +/*** + * NAME + * flt_ot_post_parse_cfg_group - + * + * ARGUMENTS + * This function takes no arguments. + * + * DESCRIPTION + * - + * + * RETURN VALUE + * Returns ERR_NONE (== 0) in case of success, + * or a combination of ERR_* flags if an error is encountered. + */ +static int flt_ot_post_parse_cfg_group(void) +{ + int retval = ERR_NONE; + + FLT_OT_FUNC(""); + + if (flt_ot_current_group == NULL) + FLT_OT_RETURN_INT(retval); + + /* Check that the group has at least one scope defined. */ + if (LIST_ISEMPTY(&(flt_ot_current_group->ph_scopes))) + FLT_OT_POST_PARSE_ALERT("group '%s' has no defined scope(s)", flt_ot_current_group->cfg_line, flt_ot_current_group->id); + + flt_ot_current_group = NULL; + + FLT_OT_RETURN_INT(retval); +} + + +/*** + * NAME + * flt_ot_parse_cfg_scope_ctx - + * + * ARGUMENTS + * args - + * cur_arg - + * err - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * Returns ERR_NONE (== 0) in case of success, + * or a combination of ERR_* flags if an error is encountered. + */ +static int flt_ot_parse_cfg_scope_ctx(char **args, int cur_arg, char **err) +{ + uint8_t flags = 0; + int retval = ERR_NONE; + + FLT_OT_FUNC("%p, %d, %p:%p", args, cur_arg, FLT_OT_DPTR_ARGS(err)); + + if (strcmp(args[cur_arg], FLT_OT_PARSE_CTX_USE_HEADERS) == 0) + flags = FLT_OT_CTX_USE_HEADERS; +#ifdef USE_OT_VARS + else if (strcmp(args[cur_arg], FLT_OT_PARSE_CTX_USE_VARS) == 0) + flags = FLT_OT_CTX_USE_VARS; +#endif + else + FLT_OT_PARSE_ERR(err, "'%s' : invalid context storage type", args[0]); + + if (flags == 0) + /* Do nothing. */; + else if (flt_ot_current_span->ctx_flags & flags) + FLT_OT_PARSE_ERR(err, "'%s' : %s already used", args[0], args[cur_arg]); + else + flt_ot_current_span->ctx_flags |= flags; + + FLT_OT_DBG(2, "ctx_flags: 0x%02hhx (0x%02hhx)", flt_ot_current_span->ctx_flags, flags); + + FLT_OT_RETURN_INT(retval); +} + + +/*** + * NAME + * flt_ot_parse_acl - + * + * ARGUMENTS + * file - + * linenum - + * px - + * args - + * err - + * head - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +static struct acl_cond *flt_ot_parse_acl(const char *file, int linenum, struct proxy *px, const char **args, char **err, struct list *head, ...) +{ + va_list ap; + int n = 0; + struct acl_cond *retptr = NULL; + + FLT_OT_FUNC("\"%s\", %d, %p, %p, %p:%p, %p, ...", file, linenum, px, args, FLT_OT_DPTR_ARGS(err), head); + + for (va_start(ap, head); (retptr == NULL) && (head != NULL); head = va_arg(ap, typeof(head)), n++) { + retptr = build_acl_cond(file, linenum, head, px, args, (n == 0) ? err : NULL); + if (retptr != NULL) + FLT_OT_DBG(2, "ACL build done, using list %p %d", head, n); + } + va_end(ap); + + if ((retptr != NULL) && (err != NULL)) + FLT_OT_FREE_CLEAR(*err); + + FLT_OT_RETURN_PTR(retptr); +} + + +/*** + * NAME + * flt_ot_parse_cfg_scope - + * + * ARGUMENTS + * file - + * linenum - + * args - + * kw_mod - + * + * DESCRIPTION + * Function used to load the scope block configuration. + * + * RETURN VALUE + * Returns ERR_NONE (== 0) in case of success, + * or a combination of ERR_* flags if an error is encountered. + */ +static int flt_ot_parse_cfg_scope(const char *file, int linenum, char **args, int kw_mod) +{ +#define FLT_OT_PARSE_SCOPE_DEF(a,b,c,d,e,f,g) { FLT_OT_PARSE_SCOPE_##a, b, FLT_OT_PARSE_INVALID_##c, d, e, f, g }, + static const struct flt_ot_parse_data parse_data[] = { FLT_OT_PARSE_SCOPE_DEFINES }; +#undef FLT_OT_PARSE_SCOPE_DEF + const struct flt_ot_parse_data *pdata = NULL; + char *err = NULL; + int i, retval = ERR_NONE; + + FLT_OT_FUNC("\"%s\", %d, %p, 0x%08x", file, linenum, args, kw_mod); + + if (flt_ot_parse_check_scope()) + FLT_OT_RETURN_INT(retval); + + retval = flt_ot_parse_cfg_check(file, linenum, args, flt_ot_current_span, parse_data, FLT_OT_TABLESIZE(parse_data), &pdata, &err); + if (retval & ERR_CODE) { + FLT_OT_PARSE_IFERR_ALERT(); + + FLT_OT_RETURN_INT(retval); + } + + if (pdata->keyword == FLT_OT_PARSE_SCOPE_ID) { + /* Initialization of a new scope. */ + flt_ot_current_scope = flt_ot_conf_scope_init(args[1], linenum, &(flt_ot_current_config->scopes), &err); + if (flt_ot_current_scope == NULL) + retval |= ERR_ABORT | ERR_ALERT; + } + else if (pdata->keyword == FLT_OT_PARSE_SCOPE_SPAN) { + /* + * Checking if this is the beginning of the definition of + * a new span. + */ + if (flt_ot_current_span != NULL) { + FLT_OT_DBG(3, "span '%s' (done)", flt_ot_current_span->id); + + flt_ot_current_span = NULL; + } + + /* Initialization of a new span. */ + flt_ot_current_span = flt_ot_conf_span_init(args[1], linenum, &(flt_ot_current_scope->spans), &err); + + /* + * In case the span has a defined reference, + * the correctness of the arguments is checked here. + */ + if (flt_ot_current_span == NULL) { + retval |= ERR_ABORT | ERR_ALERT; + } + else if (FLT_OT_ARG_ISVALID(2)) { + for (i = 2; (i < pdata->args_max) && FLT_OT_ARG_ISVALID(i); i++) + if (strcmp(args[i], FLT_OT_PARSE_SPAN_ROOT) == 0) { + if (flt_ot_current_span->flag_root) + FLT_OT_PARSE_ERR(&err, "'%s' : already set (use '%s%s')", args[i], pdata->name, pdata->usage); + else + flt_ot_current_span->flag_root = 1; + } + else if ((strcmp(args[i], FLT_OT_PARSE_SPAN_REF_CHILD) == 0) || (strcmp(args[i], FLT_OT_PARSE_SPAN_REF_FOLLOWS) == 0)) { + if (!FLT_OT_ARG_ISVALID(i + 1)) { + FLT_OT_PARSE_ERR(&err, "'%s' : too few arguments (use '%s%s')", args[i], pdata->name, pdata->usage); + } + else if (strcmp(args[i++], FLT_OT_PARSE_SPAN_REF_CHILD) == 0) { + flt_ot_current_span->ref_type = otc_span_reference_child_of; + flt_ot_current_span->ref_id_len = strlen(args[i]); + + retval = flt_ot_parse_strdup(&(flt_ot_current_span->ref_id), args[i], &err, args[1]); + } + else { + flt_ot_current_span->ref_type = otc_span_reference_follows_from; + flt_ot_current_span->ref_id_len = strlen(args[i]); + + retval = flt_ot_parse_strdup(&(flt_ot_current_span->ref_id), args[i], &err, args[1]); + } + } + else { + FLT_OT_PARSE_ERR(&err, "'%s' : invalid argument (use '%s%s')", args[i], pdata->name, pdata->usage); + } + } + else { + /* + * This is not a faulty configuration, only such a case + * will be logged. + */ + FLT_OT_DBG(3, "new span '%s' without reference", flt_ot_current_span->id); + } + } + else if (pdata->keyword == FLT_OT_PARSE_SCOPE_TAG) { + retval = flt_ot_parse_cfg_sample(file, linenum, args, &(flt_ot_current_span->tags), &err); + } + else if (pdata->keyword == FLT_OT_PARSE_SCOPE_LOG) { + retval = flt_ot_parse_cfg_sample(file, linenum, args, &(flt_ot_current_span->logs), &err); + } + else if (pdata->keyword == FLT_OT_PARSE_SCOPE_BAGGAGE) { + retval = flt_ot_parse_cfg_sample(file, linenum, args, &(flt_ot_current_span->baggages), &err); + } + else if (pdata->keyword == FLT_OT_PARSE_SCOPE_INJECT) { + /* + * Automatic context name generation can be specified here + * if the contents of the FLT_OT_PARSE_CTX_AUTONAME macro + * are used as the name. In that case, if the context is + * after a particular event, it gets its name; otherwise + * it gets the name of the current span. + */ + if (flt_ot_current_span->ctx_id != NULL) + FLT_OT_PARSE_ERR(&err, "'%s' : only one context per span is allowed", args[1]); + else if (strcmp(args[1], FLT_OT_PARSE_CTX_AUTONAME) != 0) + retval = flt_ot_parse_strdup(&(flt_ot_current_span->ctx_id), args[1], &err, args[0]); + else if (flt_ot_current_scope->event != FLT_OT_EVENT_REQ_NONE) + retval = flt_ot_parse_strdup(&(flt_ot_current_span->ctx_id), flt_ot_event_data[flt_ot_current_scope->event].name, &err, args[0]); + else + retval = flt_ot_parse_strdup(&(flt_ot_current_span->ctx_id), flt_ot_current_span->id, &err, args[0]); + + if (flt_ot_current_span->ctx_id != NULL) { + flt_ot_current_span->ctx_id_len = strlen(flt_ot_current_span->ctx_id); + + /* + * Here is checked the context storage type; which, if + * not explicitly specified, is set to HTTP headers. + * + * It is possible to use both types of context storage + * at the same time. + */ + if (FLT_OT_ARG_ISVALID(2)) { + retval = flt_ot_parse_cfg_scope_ctx(args, 2, &err); + if (!(retval & ERR_CODE) && FLT_OT_ARG_ISVALID(3)) + retval = flt_ot_parse_cfg_scope_ctx(args, 3, &err); + } else { + flt_ot_current_span->ctx_flags = FLT_OT_CTX_USE_HEADERS; + } + } + } + else if (pdata->keyword == FLT_OT_PARSE_SCOPE_EXTRACT) { + struct flt_ot_conf_context *conf_ctx; + + /* + * Here is checked the context storage type; which, if + * not explicitly specified, is set to HTTP headers. + */ + conf_ctx = flt_ot_conf_context_init(args[1], linenum, &(flt_ot_current_scope->contexts), &err); + if (conf_ctx == NULL) + retval |= ERR_ABORT | ERR_ALERT; + else if (!FLT_OT_ARG_ISVALID(2)) + conf_ctx->flags = FLT_OT_CTX_USE_HEADERS; + else if (strcmp(args[2], FLT_OT_PARSE_CTX_USE_HEADERS) == 0) + conf_ctx->flags = FLT_OT_CTX_USE_HEADERS; +#ifdef USE_OT_VARS + else if (strcmp(args[2], FLT_OT_PARSE_CTX_USE_VARS) == 0) + conf_ctx->flags = FLT_OT_CTX_USE_VARS; +#endif + else + FLT_OT_PARSE_ERR(&err, "'%s' : invalid context storage type", args[2]); + } + else if (pdata->keyword == FLT_OT_PARSE_SCOPE_FINISH) { + retval = flt_ot_parse_cfg_str(file, linenum, args, &(flt_ot_current_scope->finish), &err); + } + else if (pdata->keyword == FLT_OT_PARSE_SCOPE_ACL) { + if (strcasecmp(args[1], "or") == 0) + FLT_OT_PARSE_ERR(&err, "'%s %s ...' : invalid ACL name", args[0], args[1]); + else if (parse_acl((const char **)args + 1, &(flt_ot_current_scope->acls), &err, &(flt_ot_current_config->proxy->conf.args), file, linenum) == NULL) + retval |= ERR_ABORT | ERR_ALERT; + } + else if (pdata->keyword == FLT_OT_PARSE_SCOPE_EVENT) { + /* Scope can only have one event defined. */ + if (flt_ot_current_scope->event != FLT_OT_EVENT_REQ_NONE) { + FLT_OT_PARSE_ERR(&err, "'%s' : event already set", flt_ot_current_scope->id); + } else { + /* Check the event name. */ + for (i = 0; i < FLT_OT_TABLESIZE(flt_ot_event_data); i++) + if (strcmp(flt_ot_event_data[i].name, args[1]) == 0) { + flt_ot_current_scope->event = i; + + break; + } + + /* + * The event can have some condition defined and this + * is checked here. + */ + if (flt_ot_current_scope->event == FLT_OT_EVENT_REQ_NONE) { + FLT_OT_PARSE_ERR(&err, "'%s' : unknown event", args[1]); + } + else if (!FLT_OT_ARG_ISVALID(2)) { + /* Do nothing. */ + } + else if ((strcmp(args[2], FLT_OT_CONDITION_IF) == 0) || (strcmp(args[2], FLT_OT_CONDITION_UNLESS) == 0)) { + /* + * We will first try to build ACL condition using + * local settings and then if that fails, using + * global settings (from tracer block). If it + * also fails, then try to use ACL defined in + * the HAProxy configuration. + */ + flt_ot_current_scope->cond = flt_ot_parse_acl(file, linenum, flt_ot_current_config->proxy, (const char **)args + 2, &err, &(flt_ot_current_scope->acls), &(flt_ot_current_config->tracer->acls), &(flt_ot_current_config->proxy->acl), NULL); + if (flt_ot_current_scope->cond == NULL) + retval |= ERR_ABORT | ERR_ALERT; + } + else { + FLT_OT_PARSE_ERR(&err, "'%s' : expects either 'if' or 'unless' followed by a condition but found '%s'", args[1], args[2]); + } + + if (!(retval & ERR_CODE)) + FLT_OT_DBG(3, "event '%s'", args[1]); + } + } + + FLT_OT_PARSE_IFERR_ALERT(); + + if ((retval & ERR_CODE) && (flt_ot_current_scope != NULL)) { + flt_ot_conf_scope_free(&flt_ot_current_scope); + + flt_ot_current_span = NULL; + } + + FLT_OT_RETURN_INT(retval); +} + + +/*** + * NAME + * flt_ot_post_parse_cfg_scope - + * + * ARGUMENTS + * This function takes no arguments. + * + * DESCRIPTION + * In this function the correctness of the complete scope block is examined. + * This does not mean that all elements are checked here, but only those for + * which it has not been possible to establish their complete correctness in + * the function flt_ot_parse_cfg_scope(). + * + * RETURN VALUE + * Returns ERR_NONE (== 0) in case of success, + * or a combination of ERR_* flags if an error is encountered. + */ +static int flt_ot_post_parse_cfg_scope(void) +{ + struct flt_ot_conf_span *conf_span; + int retval = ERR_NONE; + + FLT_OT_FUNC(""); + + if (flt_ot_current_scope == NULL) + FLT_OT_RETURN_INT(retval); + + /* If span context inject is used, check that this is possible. */ + list_for_each_entry(conf_span, &(flt_ot_current_scope->spans), list) + if ((conf_span->ctx_id != NULL) && (conf_span->ctx_flags & FLT_OT_CTX_USE_HEADERS)) + if (!flt_ot_event_data[flt_ot_current_scope->event].flag_http_inject) + FLT_OT_POST_PARSE_ALERT("inject '%s' : cannot use on this event", conf_span->cfg_line, conf_span->ctx_id); + + if (retval & ERR_CODE) + flt_ot_conf_scope_free(&flt_ot_current_scope); + + flt_ot_current_scope = NULL; + flt_ot_current_span = NULL; + + FLT_OT_RETURN_INT(retval); +} + + +/*** + * NAME + * flt_ot_parse_cfg - + * + * ARGUMENTS + * conf - + * flt_name - + * err - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * Returns ERR_NONE (== 0) in case of success, + * or a combination of ERR_* flags if an error is encountered. + */ +static int flt_ot_parse_cfg(struct flt_ot_conf *conf, const char *flt_name, char **err) +{ + struct list backup_sections; + int retval = ERR_ABORT | ERR_ALERT; + + FLT_OT_FUNC("%p, \"%s\", %p:%p", conf, flt_name, FLT_OT_DPTR_ARGS(err)); + + flt_ot_current_config = conf; + + /* Backup sections. */ + LIST_INIT(&backup_sections); + cfg_backup_sections(&backup_sections); + + /* Register new OT sections and parse the OT filter configuration file. */ + if (!cfg_register_section(FLT_OT_PARSE_SECTION_TRACER_ID, flt_ot_parse_cfg_tracer, flt_ot_post_parse_cfg_tracer)) + /* Do nothing. */; + else if (!cfg_register_section(FLT_OT_PARSE_SECTION_GROUP_ID, flt_ot_parse_cfg_group, flt_ot_post_parse_cfg_group)) + /* Do nothing. */; + else if (!cfg_register_section(FLT_OT_PARSE_SECTION_SCOPE_ID, flt_ot_parse_cfg_scope, flt_ot_post_parse_cfg_scope)) + /* Do nothing. */; + else if (access(conf->cfg_file, R_OK) == -1) + FLT_OT_PARSE_ERR(err, "'%s' : %s", conf->cfg_file, strerror(errno)); + else + retval = readcfgfile(conf->cfg_file); + + /* Unregister OT sections and restore previous sections. */ + cfg_unregister_sections(); + cfg_restore_sections(&backup_sections); + + flt_ot_current_config = NULL; + + FLT_OT_RETURN_INT(retval); +} + + +/*** + * NAME + * flt_ot_parse - + * + * ARGUMENTS + * args - + * cur_arg - + * px - + * fconf - + * err - + * private - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * Returns ERR_NONE (== 0) in case of success, + * or a combination of ERR_* flags if an error is encountered. + */ +static int flt_ot_parse(char **args, int *cur_arg, struct proxy *px, struct flt_conf *fconf, char **err, void *private) +{ + struct flt_ot_conf *conf = NULL; + int pos, retval = ERR_NONE; + +#ifdef DEBUG_OT + FLT_OT_RUN_ONCE( +# ifndef DEBUG_OT_SYSTIME + (void)memcpy(&(flt_ot_debug.start), &now, sizeof(flt_ot_debug.start)); +# endif + + flt_ot_debug.level = FLT_OT_DEBUG_LEVEL; + ); +#endif + + FLT_OT_FUNC("%p, %p, %p, %p, %p:%p, %p", args, cur_arg, px, fconf, FLT_OT_DPTR_ARGS(err), private); + +#ifdef OTC_DBG_MEM + FLT_OT_RUN_ONCE( + if (otc_dbg_mem_init(&dbg_mem, dbg_mem_data, FLT_OT_TABLESIZE(dbg_mem_data), 0xff) == -1) { + FLT_OT_PARSE_ERR(err, "cannot initialize memory debugger"); + + FLT_OT_RETURN_INT(retval); + } + ); +#endif + + FLT_OT_ARGS_DUMP(); + + conf = flt_ot_conf_init(px); + if (conf == NULL) { + FLT_OT_PARSE_ERR(err, "'%s' : out of memory", args[*cur_arg]); + + FLT_OT_RETURN_INT(retval); + } + + for (pos = *cur_arg + 1; !(retval & ERR_CODE) && FLT_OT_ARG_ISVALID(pos); pos++) { + FLT_OT_DBG(3, "args[%d:2] : { '%s' '%s' }", pos, args[pos], args[pos + 1]); + + if (strcmp(args[pos], FLT_OT_OPT_FILTER_ID) == 0) { + retval = flt_ot_parse_keyword(&(conf->id), args, *cur_arg, pos, err, "name"); + pos++; + } + else if (strcmp(args[pos], FLT_OT_OPT_CONFIG) == 0) { + retval = flt_ot_parse_keyword(&(conf->cfg_file), args, *cur_arg, pos, err, "configuration file"); + if (!(retval & ERR_CODE)) + retval = flt_ot_parse_cfg(conf, args[*cur_arg], err); + pos++; + } + else { + FLT_OT_PARSE_ERR(err, "'%s' : unknown keyword '%s'", args[*cur_arg], args[pos]); + } + } + + /* If the OpenTracing filter ID is not set, use default name. */ + if (!(retval & ERR_CODE) && (conf->id == NULL)) { + ha_warning("parsing : " FLT_OT_FMT_TYPE FLT_OT_FMT_NAME "'no filter id set, using default id '%s'\n", FLT_OT_OPT_FILTER_ID_DEFAULT); + + retval = flt_ot_parse_strdup(&(conf->id), FLT_OT_OPT_FILTER_ID_DEFAULT, err, args[*cur_arg]); + } + + if (!(retval & ERR_CODE) && (conf->cfg_file == NULL)) + FLT_OT_PARSE_ERR(err, "'%s' : no configuration file specified", args[*cur_arg]); + + if (retval & ERR_CODE) { + flt_ot_conf_free(&conf); + } else { + fconf->id = ot_flt_id; + fconf->ops = &flt_ot_ops; + fconf->conf = conf; + + *cur_arg = pos; + + FLT_OT_DBG(3, "filter set: id '%s', config '%s'", conf->id, conf->cfg_file); + } + + FLT_OT_RETURN_INT(retval); +} + + +/* Declare the filter parser for FLT_OT_OPT_NAME keyword. */ +static struct flt_kw_list flt_kws = { FLT_OT_SCOPE, { }, { + { FLT_OT_OPT_NAME, flt_ot_parse, NULL }, + { NULL, NULL, NULL }, + } +}; + +INITCALL1(STG_REGISTER, flt_register_keywords, &flt_kws); + +/* + * Local variables: + * c-indent-level: 8 + * c-basic-offset: 8 + * End: + * + * vi: noexpandtab shiftwidth=8 tabstop=8 + */ diff --git a/addons/ot/src/pool.c b/addons/ot/src/pool.c new file mode 100644 index 0000000..fbcdbfc --- /dev/null +++ b/addons/ot/src/pool.c @@ -0,0 +1,223 @@ +/*** + * Copyright 2020 HAProxy Technologies + * + * This file is part of the HAProxy OpenTracing filter. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include "include.h" + + +/*** + * NAME + * flt_ot_pool_alloc - + * + * ARGUMENTS + * pool - + * size - + * flag_clear - + * err - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +void *flt_ot_pool_alloc(struct pool_head *pool, size_t size, bool flag_clear, char **err) +{ + void *retptr; + + FLT_OT_FUNC("%p, %zu, %hhu, %p:%p", pool, size, flag_clear, FLT_OT_DPTR_ARGS(err)); + + if (pool != NULL) { + retptr = pool_alloc(pool); + if (retptr != NULL) + FLT_OT_DBG(2, "POOL_ALLOC: %s:%d(%p %zu)", __func__, __LINE__, retptr, FLT_OT_DEREF(pool, size, size)); + } else { + retptr = FLT_OT_MALLOC(size); + } + + if (retptr == NULL) + FLT_OT_ERR("out of memory"); + else if (flag_clear) + (void)memset(retptr, 0, size); + + FLT_OT_RETURN_PTR(retptr); +} + + +/*** + * NAME + * flt_ot_pool_strndup - + * + * ARGUMENTS + * pool - + * s - + * size - + * err - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +void *flt_ot_pool_strndup(struct pool_head *pool, const char *s, size_t size, char **err) +{ + void *retptr; + + FLT_OT_FUNC("%p, \"%.*s\", %zu, %p:%p", pool, (int)size, s, size, FLT_OT_DPTR_ARGS(err)); + + if (pool != NULL) { + retptr = pool_alloc(pool); + if (retptr != NULL) { + (void)memcpy(retptr, s, MIN(pool->size - 1, size)); + + ((uint8_t *)retptr)[MIN(pool->size - 1, size)] = '\0'; + } + } else { + retptr = FLT_OT_STRNDUP(s, size); + } + + if (retptr != NULL) + FLT_OT_DBG(2, "POOL_STRNDUP: %s:%d(%p %zu)", __func__, __LINE__, retptr, FLT_OT_DEREF(pool, size, size)); + else + FLT_OT_ERR("out of memory"); + + FLT_OT_RETURN_PTR(retptr); +} + + +/*** + * NAME + * flt_ot_pool_free - + * + * ARGUMENTS + * pool - + * ptr - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * This function does not return a value. + */ +void flt_ot_pool_free(struct pool_head *pool, void **ptr) +{ + FLT_OT_FUNC("%p, %p:%p", pool, FLT_OT_DPTR_ARGS(ptr)); + + if ((ptr == NULL) || (*ptr == NULL)) + FLT_OT_RETURN(); + + FLT_OT_DBG(2, "POOL_FREE: %s:%d(%p %u)", __func__, __LINE__, *ptr, FLT_OT_DEREF(pool, size, 0)); + + if (pool != NULL) + pool_free(pool, *ptr); + else + FLT_OT_FREE(*ptr); + + *ptr = NULL; + + FLT_OT_RETURN(); +} + + +/*** + * NAME + * flt_ot_trash_alloc - + * + * ARGUMENTS + * flag_clear - + * err - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +struct buffer *flt_ot_trash_alloc(bool flag_clear, char **err) +{ + struct buffer *retptr; + + FLT_OT_FUNC("%hhu, %p:%p", flag_clear, FLT_OT_DPTR_ARGS(err)); + +#ifdef USE_TRASH_CHUNK + retptr = alloc_trash_chunk(); + if (retptr != NULL) + FLT_OT_DBG(2, "TRASH_ALLOC: %s:%d(%p %zu)", __func__, __LINE__, retptr, retptr->size); +#else + retptr = FLT_OT_MALLOC(sizeof(*retptr)); + if (retptr != NULL) { + chunk_init(retptr, FLT_OT_MALLOC(global.tune.bufsize), global.tune.bufsize); + if (retptr->area == NULL) + FLT_OT_FREE_CLEAR(retptr); + else + *(retptr->area) = '\0'; + } +#endif + + if (retptr == NULL) + FLT_OT_ERR("out of memory"); + else if (flag_clear) + (void)memset(retptr->area, 0, retptr->size); + + FLT_OT_RETURN_PTR(retptr); +} + + +/*** + * NAME + * flt_ot_trash_free - + * + * ARGUMENTS + * ptr - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * This function does not return a value. + */ +void flt_ot_trash_free(struct buffer **ptr) +{ + FLT_OT_FUNC("%p:%p", FLT_OT_DPTR_ARGS(ptr)); + + if ((ptr == NULL) || (*ptr == NULL)) + FLT_OT_RETURN(); + + FLT_OT_DBG(2, "TRASH_FREE: %s:%d(%p %zu)", __func__, __LINE__, *ptr, (*ptr)->size); + +#ifdef USE_TRASH_CHUNK + free_trash_chunk(*ptr); +#else + FLT_OT_FREE((*ptr)->area); + FLT_OT_FREE(*ptr); +#endif + + *ptr = NULL; + + FLT_OT_RETURN(); +} + +/* + * Local variables: + * c-indent-level: 8 + * c-basic-offset: 8 + * End: + * + * vi: noexpandtab shiftwidth=8 tabstop=8 + */ diff --git a/addons/ot/src/scope.c b/addons/ot/src/scope.c new file mode 100644 index 0000000..efe8fe2 --- /dev/null +++ b/addons/ot/src/scope.c @@ -0,0 +1,634 @@ +/*** + * Copyright 2020 HAProxy Technologies + * + * This file is part of the HAProxy OpenTracing filter. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include "include.h" + + +static struct pool_head *pool_head_ot_scope_span __read_mostly = NULL; +static struct pool_head *pool_head_ot_scope_context __read_mostly = NULL; +static struct pool_head *pool_head_ot_runtime_context __read_mostly = NULL; + +#ifdef USE_POOL_OT_SCOPE_SPAN +REGISTER_POOL(&pool_head_ot_scope_span, "ot_scope_span", sizeof(struct flt_ot_scope_span)); +#endif +#ifdef USE_POOL_OT_SCOPE_CONTEXT +REGISTER_POOL(&pool_head_ot_scope_context, "ot_scope_context", sizeof(struct flt_ot_scope_context)); +#endif +#ifdef USE_POOL_OT_RUNTIME_CONTEXT +REGISTER_POOL(&pool_head_ot_runtime_context, "ot_runtime_context", sizeof(struct flt_ot_runtime_context)); +#endif + + +#ifdef DEBUG_OT + +/*** + * NAME + * flt_ot_pools_info - + * + * ARGUMENTS + * This function takes no arguments. + * + * DESCRIPTION + * - + * + * RETURN VALUE + * This function does not return a value. + */ +void flt_ot_pools_info(void) +{ + /* + * In case we have some error in the configuration file, + * it is possible that this pool was not initialized. + */ +#ifdef USE_POOL_BUFFER + FLT_OT_DBG(2, "sizeof_pool(buffer) = %u", FLT_OT_DEREF(pool_head_buffer, size, 0)); +#endif +#ifdef USE_TRASH_CHUNK + FLT_OT_DBG(2, "sizeof_pool(trash) = %u", FLT_OT_DEREF(pool_head_trash, size, 0)); +#endif + +#ifdef USE_POOL_OT_SCOPE_SPAN + FLT_OT_DBG(2, "sizeof_pool(ot_scope_span) = %u", pool_head_ot_scope_span->size); +#endif +#ifdef USE_POOL_OT_SCOPE_CONTEXT + FLT_OT_DBG(2, "sizeof_pool(ot_scope_context) = %u", pool_head_ot_scope_context->size); +#endif +#ifdef USE_POOL_OT_RUNTIME_CONTEXT + FLT_OT_DBG(2, "sizeof_pool(ot_runtime_context) = %u", pool_head_ot_runtime_context->size); +#endif +} + +#endif /* DEBUG_OT */ + + +/*** + * NAME + * flt_ot_runtime_context_init - + * + * ARGUMENTS + * s - + * f - + * err - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +struct flt_ot_runtime_context *flt_ot_runtime_context_init(struct stream *s, struct filter *f, char **err) +{ + const struct flt_ot_conf *conf = FLT_OT_CONF(f); + struct buffer uuid; + struct flt_ot_runtime_context *retptr = NULL; + + FLT_OT_FUNC("%p, %p, %p:%p", s, f, FLT_OT_DPTR_ARGS(err)); + + retptr = flt_ot_pool_alloc(pool_head_ot_runtime_context, sizeof(*retptr), 1, err); + if (retptr == NULL) + FLT_OT_RETURN_PTR(retptr); + + retptr->stream = s; + retptr->filter = f; + retptr->flag_harderr = conf->tracer->flag_harderr; + retptr->flag_disabled = conf->tracer->flag_disabled; + retptr->logging = conf->tracer->logging; + LIST_INIT(&(retptr->spans)); + LIST_INIT(&(retptr->contexts)); + + uuid = b_make(retptr->uuid, sizeof(retptr->uuid), 0, 0); + ha_generate_uuid(&uuid); + +#ifdef USE_OT_VARS + /* + * The HAProxy variable 'sess.ot.uuid' is registered here, + * after which its value is set to runtime context UUID. + */ + if (flt_ot_var_register(FLT_OT_VAR_UUID, err) != -1) + (void)flt_ot_var_set(s, FLT_OT_VAR_UUID, retptr->uuid, SMP_OPT_DIR_REQ, err); +#endif + + FLT_OT_DBG_RUNTIME_CONTEXT("session context: ", retptr); + + FLT_OT_RETURN_PTR(retptr); +} + + +/*** + * NAME + * flt_ot_runtime_context_free - + * + * ARGUMENTS + * f - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * This function does not return a value. + */ +void flt_ot_runtime_context_free(struct filter *f) +{ + struct flt_ot_runtime_context *rt_ctx = f->ctx; + + FLT_OT_FUNC("%p", f); + + if (rt_ctx == NULL) + FLT_OT_RETURN(); + + FLT_OT_DBG_RUNTIME_CONTEXT("session context: ", rt_ctx); + + if (!LIST_ISEMPTY(&(rt_ctx->spans))) { + struct timespec ts; + struct flt_ot_scope_span *span, *span_back; + + /* All spans should be completed at the same time. */ + (void)clock_gettime(CLOCK_MONOTONIC, &ts); + + list_for_each_entry_safe(span, span_back, &(rt_ctx->spans), list) { + ot_span_finish(&(span->span), &ts, NULL, NULL, NULL); + flt_ot_scope_span_free(&span); + } + } + + if (!LIST_ISEMPTY(&(rt_ctx->contexts))) { + struct flt_ot_scope_context *ctx, *ctx_back; + + list_for_each_entry_safe(ctx, ctx_back, &(rt_ctx->contexts), list) + flt_ot_scope_context_free(&ctx); + } + + flt_ot_pool_free(pool_head_ot_runtime_context, &(f->ctx)); + + FLT_OT_RETURN(); +} + + +/*** + * NAME + * flt_ot_scope_span_init - + * + * ARGUMENTS + * rt_ctx - + * id - + * id_len - + * ref_type - + * ref_id - + * ref_id_len - + * dir - + * err - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +struct flt_ot_scope_span *flt_ot_scope_span_init(struct flt_ot_runtime_context *rt_ctx, const char *id, size_t id_len, otc_span_reference_type_t ref_type, const char *ref_id, size_t ref_id_len, uint dir, char **err) +{ + struct otc_span *ref_span = NULL; + struct otc_span_context *ref_ctx = NULL; + struct flt_ot_scope_span *span, *retptr = NULL; + struct flt_ot_scope_context *ctx; + + FLT_OT_FUNC("%p, \"%s\", %zu, %d, \"%s\", %zu, %u, %p:%p", rt_ctx, id, id_len, ref_type, ref_id, ref_id_len, dir, FLT_OT_DPTR_ARGS(err)); + + if ((rt_ctx == NULL) || (id == NULL)) + FLT_OT_RETURN_PTR(retptr); + + list_for_each_entry(span, &(rt_ctx->spans), list) + if ((span->id_len == id_len) && (memcmp(span->id, id, id_len) == 0)) { + FLT_OT_DBG(2, "found span %p", span); + + FLT_OT_RETURN_PTR(span); + } + + if (ref_id != NULL) { + list_for_each_entry(span, &(rt_ctx->spans), list) + if ((span->id_len == ref_id_len) && (memcmp(span->id, ref_id, ref_id_len) == 0)) { + ref_span = span->span; + + break; + } + + if (ref_span != NULL) { + FLT_OT_DBG(2, "found referenced span %p", span); + } else { + list_for_each_entry(ctx, &(rt_ctx->contexts), list) + if ((ctx->id_len == ref_id_len) && (memcmp(ctx->id, ref_id, ref_id_len) == 0)) { + ref_ctx = ctx->context; + + break; + } + + if (ref_ctx != NULL) { + FLT_OT_DBG(2, "found referenced context %p", ctx); + } else { + FLT_OT_ERR("cannot find referenced span/context '%s'", ref_id); + + FLT_OT_RETURN_PTR(retptr); + } + } + } + + retptr = flt_ot_pool_alloc(pool_head_ot_scope_span, sizeof(*retptr), 1, err); + if (retptr == NULL) + FLT_OT_RETURN_PTR(retptr); + + retptr->id = id; + retptr->id_len = id_len; + retptr->smp_opt_dir = dir; + retptr->ref_type = ref_type; + retptr->ref_span = ref_span; + retptr->ref_ctx = ref_ctx; + LIST_INSERT(&(rt_ctx->spans), &(retptr->list)); + + FLT_OT_DBG_SCOPE_SPAN("new span ", retptr); + + FLT_OT_RETURN_PTR(retptr); +} + + +/*** + * NAME + * flt_ot_scope_span_free - + * + * ARGUMENTS + * ptr - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * This function does not return a value. + */ +void flt_ot_scope_span_free(struct flt_ot_scope_span **ptr) +{ + FLT_OT_FUNC("%p:%p", FLT_OT_DPTR_ARGS(ptr)); + + if ((ptr == NULL) || (*ptr == NULL)) + FLT_OT_RETURN(); + + FLT_OT_DBG_SCOPE_SPAN("", *ptr); + + /* If the span is still active, do nothing. */ + if ((*ptr)->span != NULL) { + FLT_OT_DBG(2, "cannot finish active span"); + + FLT_OT_RETURN(); + } + + FLT_OT_LIST_DEL(&((*ptr)->list)); + flt_ot_pool_free(pool_head_ot_scope_span, (void **)ptr); + + FLT_OT_RETURN(); +} + + +/*** + * NAME + * flt_ot_scope_context_init - + * + * ARGUMENTS + * rt_ctx - + * tracer - + * id - + * id_len - + * text_map - + * dir - + * err - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +struct flt_ot_scope_context *flt_ot_scope_context_init(struct flt_ot_runtime_context *rt_ctx, struct otc_tracer *tracer, const char *id, size_t id_len, const struct otc_text_map *text_map, uint dir, char **err) +{ + struct otc_http_headers_reader reader; + struct otc_span_context *span_ctx; + struct flt_ot_scope_context *retptr = NULL; + + FLT_OT_FUNC("%p, %p, \"%s\", %zu, %p, %u, %p:%p", rt_ctx, tracer, id, id_len, text_map, dir, FLT_OT_DPTR_ARGS(err)); + + if ((rt_ctx == NULL) || (tracer == NULL) || (id == NULL) || (text_map == NULL)) + FLT_OT_RETURN_PTR(retptr); + + list_for_each_entry(retptr, &(rt_ctx->contexts), list) + if ((retptr->id_len == id_len) && (memcmp(retptr->id, id, id_len) == 0)) { + FLT_OT_DBG(2, "found context %p", retptr); + + FLT_OT_RETURN_PTR(retptr); + } + + retptr = flt_ot_pool_alloc(pool_head_ot_scope_context, sizeof(*retptr), 1, err); + if (retptr == NULL) + FLT_OT_RETURN_PTR(retptr); + + span_ctx = ot_extract_http_headers(tracer, &reader, text_map, err); + if (span_ctx == NULL) { + flt_ot_scope_context_free(&retptr); + + FLT_OT_RETURN_PTR(retptr); + } + + retptr->id = id; + retptr->id_len = id_len; + retptr->smp_opt_dir = dir; + retptr->context = span_ctx; + LIST_INSERT(&(rt_ctx->contexts), &(retptr->list)); + + FLT_OT_DBG_SCOPE_CONTEXT("new context ", retptr); + + FLT_OT_RETURN_PTR(retptr); +} + + +/*** + * NAME + * flt_ot_scope_context_free - + * + * ARGUMENTS + * ptr - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * This function does not return a value. + */ +void flt_ot_scope_context_free(struct flt_ot_scope_context **ptr) +{ + FLT_OT_FUNC("%p:%p", FLT_OT_DPTR_ARGS(ptr)); + + if ((ptr == NULL) || (*ptr == NULL)) + FLT_OT_RETURN(); + + FLT_OT_DBG_SCOPE_CONTEXT("", *ptr); + + if ((*ptr)->context != NULL) + (*ptr)->context->destroy(&((*ptr)->context)); + + FLT_OT_LIST_DEL(&((*ptr)->list)); + flt_ot_pool_free(pool_head_ot_scope_context, (void **)ptr); + + FLT_OT_RETURN(); +} + + +/*** + * NAME + * flt_ot_scope_data_free - + * + * ARGUMENTS + * ptr - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * This function does not return a value. + */ +void flt_ot_scope_data_free(struct flt_ot_scope_data *ptr) +{ + int i; + + FLT_OT_FUNC("%p", ptr); + + if (ptr == NULL) + FLT_OT_RETURN(); + + FLT_OT_DBG_SCOPE_DATA("", ptr); + + for (i = 0; i < ptr->num_tags; i++) + if (ptr->tags[i].value.type == otc_value_string) + FLT_OT_FREE_VOID(ptr->tags[i].value.value.string_value); + otc_text_map_destroy(&(ptr->baggage), OTC_TEXT_MAP_FREE_VALUE); + for (i = 0; i < ptr->num_log_fields; i++) + if (ptr->log_fields[i].value.type == otc_value_string) + FLT_OT_FREE_VOID(ptr->log_fields[i].value.value.string_value); + + (void)memset(ptr, 0, sizeof(*ptr)); + + FLT_OT_RETURN(); +} + + +/*** + * NAME + * flt_ot_scope_finish_mark - + * + * ARGUMENTS + * rt_ctx - + * id - + * id_len - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +int flt_ot_scope_finish_mark(const struct flt_ot_runtime_context *rt_ctx, const char *id, size_t id_len) +{ + struct flt_ot_scope_span *span; + struct flt_ot_scope_context *ctx; + int span_cnt = 0, ctx_cnt = 0, retval; + + FLT_OT_FUNC("%p, \"%s\", %zu", rt_ctx, id, id_len); + + if (FLT_OT_STR_CMP(FLT_OT_SCOPE_SPAN_FINISH_ALL, id, id_len)) { + list_for_each_entry(span, &(rt_ctx->spans), list) { + span->flag_finish = 1; + span_cnt++; + } + + list_for_each_entry(ctx, &(rt_ctx->contexts), list) { + ctx->flag_finish = 1; + ctx_cnt++; + } + + FLT_OT_DBG(2, "marked %d span(s), %d context(s)", span_cnt, ctx_cnt); + } + else if (FLT_OT_STR_CMP(FLT_OT_SCOPE_SPAN_FINISH_REQ, id, id_len)) { + list_for_each_entry(span, &(rt_ctx->spans), list) + if (span->smp_opt_dir == SMP_OPT_DIR_REQ) { + span->flag_finish = 1; + span_cnt++; + } + + list_for_each_entry(ctx, &(rt_ctx->contexts), list) + if (ctx->smp_opt_dir == SMP_OPT_DIR_REQ) { + ctx->flag_finish = 1; + span_cnt++; + } + + FLT_OT_DBG(2, "marked REQuest channel %d span(s), %d context(s)", span_cnt, ctx_cnt); + } + else if (FLT_OT_STR_CMP(FLT_OT_SCOPE_SPAN_FINISH_RES, id, id_len)) { + list_for_each_entry(span, &(rt_ctx->spans), list) + if (span->smp_opt_dir == SMP_OPT_DIR_RES) { + span->flag_finish = 1; + span_cnt++; + } + + list_for_each_entry(ctx, &(rt_ctx->contexts), list) + if (ctx->smp_opt_dir == SMP_OPT_DIR_RES) { + ctx->flag_finish = 1; + ctx_cnt++; + } + + FLT_OT_DBG(2, "marked RESponse channel %d span(s), %d context(s)", span_cnt, ctx_cnt); + } + else { + list_for_each_entry(span, &(rt_ctx->spans), list) + if ((span->id_len == id_len) && (memcmp(span->id, id, id_len) == 0)) { + span->flag_finish = 1; + span_cnt++; + + break; + } + + list_for_each_entry(ctx, &(rt_ctx->contexts), list) + if ((ctx->id_len == id_len) && (memcmp(ctx->id, id, id_len) == 0)) { + ctx->flag_finish = 1; + ctx_cnt++; + + break; + } + + if (span_cnt > 0) + FLT_OT_DBG(2, "marked span '%s'", id); + if (ctx_cnt > 0) + FLT_OT_DBG(2, "marked context '%s'", id); + if ((span_cnt + ctx_cnt) == 0) + FLT_OT_DBG(2, "cannot find span/context '%s'", id); + } + + retval = span_cnt + ctx_cnt; + + FLT_OT_RETURN_INT(retval); +} + + +/*** + * NAME + * flt_ot_scope_finish_marked - + * + * ARGUMENTS + * rt_ctx - + * ts_finish - + * + * DESCRIPTION + * Finish marked spans. + * + * RETURN VALUE + * This function does not return a value. + */ +void flt_ot_scope_finish_marked(const struct flt_ot_runtime_context *rt_ctx, const struct timespec *ts_finish) +{ + struct flt_ot_scope_span *span; + struct flt_ot_scope_context *ctx; + + FLT_OT_FUNC("%p, %p", rt_ctx, ts_finish); + + list_for_each_entry(span, &(rt_ctx->spans), list) + if (span->flag_finish) { + FLT_OT_DBG_SCOPE_SPAN("finishing span ", span); + + ot_span_finish(&(span->span), ts_finish, NULL, NULL, NULL); + + span->flag_finish = 0; + } + + list_for_each_entry(ctx, &(rt_ctx->contexts), list) + if (ctx->flag_finish) { + FLT_OT_DBG_SCOPE_CONTEXT("finishing context ", ctx); + + if (ctx->context != NULL) + ctx->context->destroy(&(ctx->context)); + + ctx->flag_finish = 0; + } + + FLT_OT_RETURN(); +} + + +/*** + * NAME + * flt_ot_scope_free_unused - + * + * ARGUMENTS + * rt_ctx - + * chn - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * This function does not return a value. + */ +void flt_ot_scope_free_unused(struct flt_ot_runtime_context *rt_ctx, struct channel *chn) +{ + FLT_OT_FUNC("%p", rt_ctx); + + if (rt_ctx == NULL) + FLT_OT_RETURN(); + + if (!LIST_ISEMPTY(&(rt_ctx->spans))) { + struct flt_ot_scope_span *span, *span_back; + + list_for_each_entry_safe(span, span_back, &(rt_ctx->spans), list) + if (span->span == NULL) + flt_ot_scope_span_free(&span); + } + + if (!LIST_ISEMPTY(&(rt_ctx->contexts))) { + struct flt_ot_scope_context *ctx, *ctx_back; + + list_for_each_entry_safe(ctx, ctx_back, &(rt_ctx->contexts), list) + if (ctx->context == NULL) { + /* + * All headers and variables associated with + * the context in question should be deleted. + */ + (void)flt_ot_http_headers_remove(chn, ctx->id, NULL); +#ifdef USE_OT_VARS + (void)flt_ot_vars_unset(rt_ctx->stream, FLT_OT_VARS_SCOPE, ctx->id, ctx->smp_opt_dir, NULL); +#endif + + flt_ot_scope_context_free(&ctx); + } + } + + FLT_OT_DBG_RUNTIME_CONTEXT("session context: ", rt_ctx); + + FLT_OT_RETURN(); +} + +/* + * Local variables: + * c-indent-level: 8 + * c-basic-offset: 8 + * End: + * + * vi: noexpandtab shiftwidth=8 tabstop=8 + */ diff --git a/addons/ot/src/util.c b/addons/ot/src/util.c new file mode 100644 index 0000000..767685e --- /dev/null +++ b/addons/ot/src/util.c @@ -0,0 +1,815 @@ +/*** + * Copyright 2020 HAProxy Technologies + * + * This file is part of the HAProxy OpenTracing filter. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include "include.h" + + +#ifdef DEBUG_OT + +/*** + * NAME + * flt_ot_args_dump - + * + * ARGUMENTS + * args - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * This function does not return a value. + */ +void flt_ot_args_dump(char **args) +{ + int i, argc; + + argc = flt_ot_args_count(args); + + (void)fprintf(stderr, FLT_OT_DBG_FMT("%.*sargs[%d]: { '%s' "), dbg_indent_level, FLT_OT_DBG_INDENT, argc, args[0]); + + for (i = 1; i < argc; i++) + (void)fprintf(stderr, "'%s' ", args[i]); + + (void)fprintf(stderr, "}\n"); +} + + +/*** + * NAME + * flt_ot_filters_dump - + * + * ARGUMENTS + * This function takes no arguments. + * + * DESCRIPTION + * - + * + * RETURN VALUE + * This function does not return a value. + */ +void flt_ot_filters_dump(void) +{ + struct flt_conf *fconf; + struct proxy *px; + + FLT_OT_FUNC(""); + + for (px = proxies_list; px != NULL; px = px->next) { + FLT_OT_DBG(2, "proxy '%s'", px->id); + + list_for_each_entry(fconf, &(px->filter_configs), list) + if (fconf->id == ot_flt_id) { + struct flt_ot_conf *conf = fconf->conf; + + FLT_OT_DBG(2, " OT filter '%s'", conf->id); + } + } + + FLT_OT_RETURN(); +} + + +/*** + * NAME + * flt_ot_chn_label - + * + * ARGUMENTS + * chn - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +const char *flt_ot_chn_label(const struct channel *chn) +{ + return (chn->flags & CF_ISRESP) ? "RESponse" : "REQuest"; +} + + +/*** + * NAME + * flt_ot_pr_mode - + * + * ARGUMENTS + * s - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +const char *flt_ot_pr_mode(const struct stream *s) +{ + struct proxy *px = (s->flags & SF_BE_ASSIGNED) ? s->be : strm_fe(s); + + return (px->mode == PR_MODE_HTTP) ? "HTTP" : "TCP"; +} + + +/*** + * NAME + * flt_ot_stream_pos - + * + * ARGUMENTS + * s - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +const char *flt_ot_stream_pos(const struct stream *s) +{ + return (s->flags & SF_BE_ASSIGNED) ? "backend" : "frontend"; +} + + +/*** + * NAME + * flt_ot_type - + * + * ARGUMENTS + * f - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +const char *flt_ot_type(const struct filter *f) +{ + return (f->flags & FLT_FL_IS_BACKEND_FILTER) ? "backend" : "frontend"; +} + + +/*** + * NAME + * flt_ot_analyzer - + * + * ARGUMENTS + * an_bit - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +const char *flt_ot_analyzer(uint an_bit) +{ +#define FLT_OT_AN_DEF(a) { a, #a }, + static const struct { + uint an_bit; + const char *str; + } flt_ot_an[] = { FLT_OT_AN_DEFINES }; +#undef FLT_OT_AN_DEF + const char *retptr = "invalid an_bit"; + int i; + + for (i = 0; i < FLT_OT_TABLESIZE(flt_ot_an); i++) + if (flt_ot_an[i].an_bit == an_bit) { + retptr = flt_ot_an[i].str; + + break; + } + + return retptr; +} + + +/*** + * NAME + * flt_ot_str_hex - + * + * ARGUMENTS + * data - + * size - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +const char *flt_ot_str_hex(const void *data, size_t size) +{ + static THREAD_LOCAL char retbuf[BUFSIZ]; + const uint8_t *ptr = data; + size_t i; + + if (data == NULL) + return "(null)"; + else if (size == 0) + return "()"; + + for (i = 0, size <<= 1; (i < (sizeof(retbuf) - 2)) && (i < size); ptr++) { + retbuf[i++] = FLT_OT_NIBBLE_TO_HEX(*ptr >> 4); + retbuf[i++] = FLT_OT_NIBBLE_TO_HEX(*ptr & 0x0f); + } + + retbuf[i] = '\0'; + + return retbuf; +} + + +/*** + * NAME + * flt_ot_str_ctrl - + * + * ARGUMENTS + * data - + * size - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +const char *flt_ot_str_ctrl(const void *data, size_t size) +{ + static THREAD_LOCAL char retbuf[BUFSIZ]; + const uint8_t *ptr = data; + size_t i, n = 0; + + if (data == NULL) + return "(null)"; + else if (size == 0) + return "()"; + + for (i = 0; (n < (sizeof(retbuf) - 1)) && (i < size); i++) + retbuf[n++] = ((ptr[i] >= 0x20) && (ptr[i] <= 0x7e)) ? ptr[i] : '.'; + + retbuf[n] = '\0'; + + return retbuf; +} + + +/*** + * NAME + * flt_ot_list_debug - + * + * ARGUMENTS + * head - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +const char *flt_ot_list_debug(const struct list *head) +{ + FLT_OT_BUFFER_THR(retbuf, 4, 64, retptr); + + if ((head == NULL) || LIST_ISEMPTY(head)) { + (void)strncpy(retptr, (head == NULL) ? "{ null list }" : "{ empty list }", sizeof(retbuf[0])); + } + else if (head->p == head->n) { + (void)snprintf(retptr, sizeof(retbuf[0]), "{ %p * 1 }", head->p); + } + else { + const struct list *ptr; + size_t count = 0; + + for (ptr = head->n; ptr != head; ptr = ptr->n, count++); + + (void)snprintf(retptr, sizeof(retbuf[0]), "{ %p %p %zu }", head->p, head->n, count); + } + + return (retptr); +} + +#endif /* DEBUG_OT */ + + +/*** + * NAME + * flt_ot_chunk_add - + * + * ARGUMENTS + * chk - + * src - + * n - + * err - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +ssize_t flt_ot_chunk_add(struct buffer *chk, const void *src, size_t n, char **err) +{ + FLT_OT_FUNC("%p, %p, %zu, %p:%p", chk, src, n, FLT_OT_DPTR_ARGS(err)); + + if ((chk == NULL) || (src == NULL)) + FLT_OT_RETURN_EX(-1, ssize_t, "%ld"); + + if (chk->area == NULL) + chunk_init(chk, FLT_OT_CALLOC(1, global.tune.bufsize), global.tune.bufsize); + + if (chk->area == NULL) { + FLT_OT_ERR("out of memory"); + + FLT_OT_RETURN_EX(-1, ssize_t, "%ld"); + } + else if (n > (chk->size - chk->data)) { + FLT_OT_ERR("chunk size too small"); + + FLT_OT_RETURN_EX(-1, ssize_t, "%ld"); + } + + (void)memcpy(chk->area + chk->data, src, n); + chk->data += n; + + FLT_OT_RETURN_EX(chk->data, ssize_t, "%ld"); +} + + +/*** + * NAME + * flt_ot_args_count - + * + * ARGUMENTS + * args - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +int flt_ot_args_count(char **args) +{ + int i, retval = 0; + + if (args == NULL) + return retval; + + /* + * It is possible that some arguments within the configuration line + * are not specified; that is, they are set to a blank string. + * + * For example: + * keyword '' arg_2 + * + * In that case the content of the args field will be like this: + * args[0]: 'keyword' + * args[1]: NULL pointer + * args[2]: 'arg_2' + * args[3 .. MAX_LINE_ARGS): NULL pointers + * + * The total number of arguments is the index of the last argument + * (increased by 1) that is not a NULL pointer. + */ + for (i = 0; i < MAX_LINE_ARGS; i++) + if (FLT_OT_ARG_ISVALID(i)) + retval = i + 1; + + return retval; +} + + +/*** + * NAME + * flt_ot_args_to_str - + * + * ARGUMENTS + * args - + * idx - + * str - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * This function does not return a value. + */ +void flt_ot_args_to_str(char **args, int idx, char **str) +{ + int i, argc; + + if ((args == NULL) || (*args == NULL)) + return; + + argc = flt_ot_args_count(args); + + for (i = idx; i < argc; i++) + (void)memprintf(str, "%s%s%s", (*str == NULL) ? "" : *str, (i == idx) ? "" : " ", (args[i] == NULL) ? "" : args[i]); +} + + +/*** + * NAME + * flt_ot_strtod - + * + * ARGUMENTS + * nptr - + * limit_min - + * limit_max - + * err - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +double flt_ot_strtod(const char *nptr, double limit_min, double limit_max, char **err) +{ + char *endptr = NULL; + double retval; + + errno = 0; + + retval = strtod(nptr, &endptr); + if ((errno != 0) || FLT_OT_STR_ISVALID(endptr)) + FLT_OT_ERR("'%s' : invalid value", nptr); + else if (!FLT_OT_IN_RANGE(retval, limit_min, limit_max)) + FLT_OT_ERR("'%s' : value out of range [%.2f, %.2f]", nptr, limit_min, limit_max); + + return retval; +} + + +/*** + * NAME + * flt_ot_strtoll - + * + * ARGUMENTS + * nptr - + * limit_min - + * limit_max - + * err - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +int64_t flt_ot_strtoll(const char *nptr, int64_t limit_min, int64_t limit_max, char **err) +{ + char *endptr = NULL; + int64_t retval; + + errno = 0; + + retval = strtoll(nptr, &endptr, 0); + if ((errno != 0) || FLT_OT_STR_ISVALID(endptr)) + FLT_OT_ERR("'%s' : invalid value", nptr); + else if (!FLT_OT_IN_RANGE(retval, limit_min, limit_max)) + FLT_OT_ERR("'%s' : value out of range [%" PRId64 ", %" PRId64 "]", nptr, limit_min, limit_max); + + return retval; +} + + +/*** + * NAME + * flt_ot_sample_to_str - + * + * ARGUMENTS + * data - + * value - + * size - + * err - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +int flt_ot_sample_to_str(const struct sample_data *data, char *value, size_t size, char **err) +{ + int retval = -1; + + FLT_OT_FUNC("%p, %p, %zu, %p:%p", data, value, size, FLT_OT_DPTR_ARGS(err)); + + if ((data == NULL) || (value == NULL) || (size == 0)) + FLT_OT_RETURN_INT(retval); + + *value = '\0'; + + if (data->type == SMP_T_ANY) { + FLT_OT_ERR("invalid sample data type %d", data->type); + } + else if (data->type == SMP_T_BOOL) { + value[0] = data->u.sint ? '1' : '0'; + value[1] = '\0'; + + retval = 1; + } + else if (data->type == SMP_T_SINT) { + retval = snprintf(value, size, "%lld", data->u.sint); + } + else if (data->type == SMP_T_ADDR) { + /* This type is never used to qualify a sample. */ + } + else if (data->type == SMP_T_IPV4) { + if (INET_ADDRSTRLEN > size) + FLT_OT_ERR("sample data size too large"); + else if (inet_ntop(AF_INET, &(data->u.ipv4), value, INET_ADDRSTRLEN) == NULL) + FLT_OT_ERR("invalid IPv4 address"); + else + retval = strlen(value); + } + else if (data->type == SMP_T_IPV6) { + if (INET6_ADDRSTRLEN > size) + FLT_OT_ERR("sample data size too large"); + else if (inet_ntop(AF_INET6, &(data->u.ipv6), value, INET6_ADDRSTRLEN) == NULL) + FLT_OT_ERR("invalid IPv6 address"); + else + retval = strlen(value); + } + else if (data->type == SMP_T_STR) { + if (data->u.str.data >= size) { + FLT_OT_ERR("sample data size too large"); + } + else if (data->u.str.data > 0) { + retval = data->u.str.data; + + (void)strncat(value, data->u.str.area, retval); + } + else { + /* + * There is no content to add but we will still return + * the correct status. + */ + retval = 0; + } + } + else if (data->type == SMP_T_BIN) { + FLT_OT_ERR("invalid sample data type %d", data->type); + } + else if (data->type != SMP_T_METH) { + FLT_OT_ERR("invalid sample data type %d", data->type); + } + else if (data->u.meth.meth == HTTP_METH_OPTIONS) { + retval = FLT_OT_STR_SIZE(HTTP_METH_STR_OPTIONS); + + (void)memcpy(value, HTTP_METH_STR_OPTIONS, retval + 1); + } + else if (data->u.meth.meth == HTTP_METH_GET) { + retval = FLT_OT_STR_SIZE(HTTP_METH_STR_GET); + + (void)memcpy(value, HTTP_METH_STR_GET, retval + 1); + } + else if (data->u.meth.meth == HTTP_METH_HEAD) { + retval = FLT_OT_STR_SIZE(HTTP_METH_STR_HEAD); + + (void)memcpy(value, HTTP_METH_STR_HEAD, retval + 1); + } + else if (data->u.meth.meth == HTTP_METH_POST) { + retval = FLT_OT_STR_SIZE(HTTP_METH_STR_POST); + + (void)memcpy(value, HTTP_METH_STR_POST, retval + 1); + } + else if (data->u.meth.meth == HTTP_METH_PUT) { + retval = FLT_OT_STR_SIZE(HTTP_METH_STR_PUT); + + (void)memcpy(value, HTTP_METH_STR_PUT, retval + 1); + } + else if (data->u.meth.meth == HTTP_METH_DELETE) { + retval = FLT_OT_STR_SIZE(HTTP_METH_STR_DELETE); + + (void)memcpy(value, HTTP_METH_STR_DELETE, retval + 1); + } + else if (data->u.meth.meth == HTTP_METH_TRACE) { + retval = FLT_OT_STR_SIZE(HTTP_METH_STR_TRACE); + + (void)memcpy(value, HTTP_METH_STR_TRACE, retval + 1); + } + else if (data->u.meth.meth == HTTP_METH_CONNECT) { + retval = FLT_OT_STR_SIZE(HTTP_METH_STR_CONNECT); + + (void)memcpy(value, HTTP_METH_STR_CONNECT, retval + 1); + } + else if (data->u.meth.meth == HTTP_METH_OTHER) { + if (data->u.meth.str.data >= size) { + FLT_OT_ERR("sample data size too large"); + } else { + retval = data->u.meth.str.data; + + (void)strncat(value, data->u.meth.str.area, retval); + } + } + else { + FLT_OT_ERR("invalid HTTP method"); + } + + FLT_OT_RETURN_INT(retval); +} + + +/*** + * NAME + * flt_ot_sample_to_value - + * + * ARGUMENTS + * key - + * data - + * value - + * err - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +int flt_ot_sample_to_value(const char *key, const struct sample_data *data, struct otc_value *value, char **err) +{ + int retval = -1; + + FLT_OT_FUNC("\"%s\", %p, %p, %p:%p", key, data, value, FLT_OT_DPTR_ARGS(err)); + + if ((data == NULL) || (value == NULL)) + FLT_OT_RETURN_INT(retval); + + if (data->type == SMP_T_BOOL) { + value->type = otc_value_bool; + value->value.bool_value = data->u.sint ? 1 : 0; + + retval = sizeof(value->value.bool_value); + } + else if (data->type == SMP_T_SINT) { + value->type = otc_value_int64; + value->value.int64_value = data->u.sint; + + retval = sizeof(value->value.int64_value); + } + else { + value->type = otc_value_string; + value->value.string_value = FLT_OT_MALLOC(global.tune.bufsize); + + if (value->value.string_value == NULL) + FLT_OT_ERR("out of memory"); + else + retval = flt_ot_sample_to_str(data, (char *)value->value.string_value, global.tune.bufsize, err); + } + + FLT_OT_RETURN_INT(retval); +} + + +/*** + * NAME + * flt_ot_sample_add - + * + * ARGUMENTS + * s - + * dir - + * sample - + * data - + * type - + * err - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * Returns a negative value if an error occurs, 0 if it needs to wait, + * any other value otherwise. + */ +int flt_ot_sample_add(struct stream *s, uint dir, struct flt_ot_conf_sample *sample, struct flt_ot_scope_data *data, int type, char **err) +{ + const struct flt_ot_conf_sample_expr *expr; + struct sample smp; + struct otc_value value; + struct buffer buffer; + int idx = 0, rc, retval = FLT_OT_RET_OK; + + FLT_OT_FUNC("%p, %u, %p, %p, %d, %p:%p", s, dir, data, sample, type, FLT_OT_DPTR_ARGS(err)); + + FLT_OT_DBG_CONF_SAMPLE("sample ", sample); + + (void)memset(&buffer, 0, sizeof(buffer)); + + list_for_each_entry(expr, &(sample->exprs), list) { + FLT_OT_DBG_CONF_SAMPLE_EXPR("sample expression ", expr); + + (void)memset(&smp, 0, sizeof(smp)); + + /* + * If we have only one expression to process, then the data + * type that is the result of the expression is converted to + * an equivalent data type (if possible) that is written to + * the tracer. + * + * If conversion is not possible, or if we have multiple + * expressions to process, then the result is converted to + * a string and as such sent to the tracer. + */ + if (sample_process(s->be, s->sess, s, dir | SMP_OPT_FINAL, expr->expr, &smp) != NULL) { + FLT_OT_DBG(3, "data type %d: '%s'", smp.data.type, expr->value); + } else { + FLT_OT_DBG(2, "WARNING: failed to fetch '%s' value", expr->value); + + /* + * In case the fetch failed, we will set the result + * (sample) to an empty static string. + */ + (void)memset(&(smp.data), 0, sizeof(smp.data)); + smp.data.type = SMP_T_STR; + smp.data.u.str.area = ""; + } + + if ((sample->num_exprs == 1) && (type == FLT_OT_EVENT_SAMPLE_TAG)) { + if (flt_ot_sample_to_value(sample->key, &(smp.data), &value, err) == -1) + retval = FLT_OT_RET_ERROR; + } else { + if (buffer.area == NULL) { + chunk_init(&buffer, FLT_OT_CALLOC(1, global.tune.bufsize), global.tune.bufsize); + if (buffer.area == NULL) { + FLT_OT_ERR("out of memory"); + + retval = FLT_OT_RET_ERROR; + + break; + } + } + + rc = flt_ot_sample_to_str(&(smp.data), buffer.area + buffer.data, buffer.size - buffer.data, err); + if (rc == -1) { + retval = FLT_OT_RET_ERROR; + } else { + buffer.data += rc; + + if (sample->num_exprs == ++idx) { + value.type = otc_value_string; + value.value.string_value = buffer.area; + } + } + } + } + + if (retval == FLT_OT_RET_ERROR) { + /* Do nothing. */ + } + else if (type == FLT_OT_EVENT_SAMPLE_TAG) { + struct otc_tag *tag = data->tags + data->num_tags++; + + tag->key = sample->key; + (void)memcpy(&(tag->value), &value, sizeof(tag->value)); + } + else if (type == FLT_OT_EVENT_SAMPLE_LOG) { + struct otc_log_field *log_field = data->log_fields + data->num_log_fields++; + + log_field->key = sample->key; + (void)memcpy(&(log_field->value), &value, sizeof(log_field->value)); + } + else { + if (data->baggage == NULL) + data->baggage = otc_text_map_new(NULL, FLT_OT_MAXBAGGAGES); + + if (data->baggage == NULL) { + FLT_OT_ERR("out of memory"); + + retval = FLT_OT_RET_ERROR; + } + else if (otc_text_map_add(data->baggage, sample->key, 0, value.value.string_value, 0, 0) == -1) { + FLT_OT_ERR("out of memory"); + + retval = FLT_OT_RET_ERROR; + } + else + FLT_OT_DBG(3, "baggage[%zu]: '%s' -> '%s'", data->baggage->count - 1, data->baggage->key[data->baggage->count - 1], data->baggage->value[data->baggage->count - 1]); + } + + FLT_OT_RETURN_INT(retval); +} + +/* + * Local variables: + * c-indent-level: 8 + * c-basic-offset: 8 + * End: + * + * vi: noexpandtab shiftwidth=8 tabstop=8 + */ diff --git a/addons/ot/src/vars.c b/addons/ot/src/vars.c new file mode 100644 index 0000000..e99bab1 --- /dev/null +++ b/addons/ot/src/vars.c @@ -0,0 +1,834 @@ +/*** + * Copyright 2020 HAProxy Technologies + * + * This file is part of the HAProxy OpenTracing filter. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include "include.h" + + +#ifdef DEBUG_OT + +/*** + * NAME + * flt_ot_vars_scope_dump - + * + * ARGUMENTS + * vars - + * scope - + * + * DESCRIPTION + * Function prints the contents of all variables defined for a particular + * scope. + * + * RETURN VALUE + * This function does not return a value. + */ +static void flt_ot_vars_scope_dump(struct vars *vars, const char *scope) +{ + const struct var *var; + + if (vars == NULL) + return; + + vars_rdlock(vars); + list_for_each_entry(var, &(vars->head), l) + FLT_OT_DBG(2, "'%s.%016" PRIx64 "' -> '%.*s'", scope, var->name_hash, (int)b_data(&(var->data.u.str)), b_orig(&(var->data.u.str))); + vars_rdunlock(vars); +} + + +/*** + * NAME + * flt_ot_vars_dump - + * + * ARGUMENTS + * s - + * + * DESCRIPTION + * Function prints the contents of all variables grouped by individual + * scope. + * + * RETURN VALUE + * This function does not return a value. + */ +void flt_ot_vars_dump(struct stream *s) +{ + FLT_OT_FUNC("%p", s); + + /* + * It would be nice if we could use the get_vars() function from HAProxy + * source here to get the value of the 'vars' pointer, but it is defined + * as 'static inline', so unfortunately none of this is possible. + */ + flt_ot_vars_scope_dump(&(proc_vars), "PROC"); + flt_ot_vars_scope_dump(&(s->sess->vars), "SESS"); + flt_ot_vars_scope_dump(&(s->vars_txn), "TXN"); + flt_ot_vars_scope_dump(&(s->vars_reqres), "REQ/RES"); + + FLT_OT_RETURN(); +} + +#endif /* DEBUG_OT */ + + +/*** + * NAME + * flt_ot_smp_init - + * + * ARGUMENTS + * s - + * smp - + * opt - + * type - + * data - + * + * DESCRIPTION + * The function initializes the value of the 'smp' structure. If the 'data' + * argument is set, then the 'sample_data' member of the 'smp' structure is + * also initialized. + * + * RETURN VALUE + * This function does not return a value. + */ +static inline void flt_ot_smp_init(struct stream *s, struct sample *smp, uint opt, int type, const char *data) +{ + (void)memset(smp, 0, sizeof(*smp)); + (void)smp_set_owner(smp, s->be, s->sess, s, opt | SMP_OPT_FINAL); + + if (data != NULL) { + smp->data.type = type; + + chunk_initstr(&(smp->data.u.str), data); + } +} + + +/*** + * NAME + * flt_ot_smp_add - + * + * ARGUMENTS + * data - + * blk - + * len - + * err - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +static int flt_ot_smp_add(struct sample_data *data, const char *name, size_t len, char **err) +{ + bool flag_alloc = 0; + int retval = FLT_OT_RET_ERROR; + + FLT_OT_FUNC("%p, \"%.*s\", %zu, %p:%p", data, (int)len, name, len, FLT_OT_DPTR_ARGS(err)); + + FLT_OT_DBG_BUF(2, &(data->u.str)); + + if (b_orig(&(data->u.str)) == NULL) { + data->type = SMP_T_BIN; + chunk_init(&(data->u.str), FLT_OT_MALLOC(global.tune.bufsize), global.tune.bufsize); + + flag_alloc = (b_orig(&(data->u.str)) != NULL); + } + + if (b_orig(&(data->u.str)) == NULL) { + FLT_OT_ERR("failed to add ctx '%.*s', not enough memory", (int)len, name); + } + else if (len > ((UINT64_C(1) << ((sizeof(FLT_OT_VAR_CTX_SIZE) << 3) - 1)) - 1)) { + FLT_OT_ERR("failed to add ctx '%.*s', too long name", (int)len, name); + } + else if ((len + sizeof(FLT_OT_VAR_CTX_SIZE)) > b_room(&(data->u.str))) { + FLT_OT_ERR("failed to add ctx '%.*s', too many names", (int)len, name); + } + else { + retval = b_data(&(data->u.str)); + + b_putchr(&(data->u.str), len); + (void)__b_putblk(&(data->u.str), name, len); + + FLT_OT_DBG_BUF(2, &(data->u.str)); + } + + if ((retval == FLT_OT_RET_ERROR) && flag_alloc) + FLT_OT_FREE(b_orig(&(data->u.str))); + + FLT_OT_RETURN_INT(retval); +} + + +/*** + * NAME + * flt_ot_normalize_name - + * + * ARGUMENTS + * var_name - + * size - + * len - + * name - + * flag_cpy - + * err - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +static int flt_ot_normalize_name(char *var_name, size_t size, int *len, const char *name, bool flag_cpy, char **err) +{ + int retval = 0; + + FLT_OT_FUNC("%p, %zu, %p, \"%s\", %hhu, %p:%p", var_name, size, len, name, flag_cpy, FLT_OT_DPTR_ARGS(err)); + + if (!FLT_OT_STR_ISVALID(name)) + FLT_OT_RETURN_INT(retval); + + /* + * In case the name of the variable consists of several elements, + * the character '.' is added between them. + */ + if ((*len == 0) || (var_name[*len - 1] == '.')) + /* Do nothing. */; + else if (*len < (size - 1)) + var_name[(*len)++] = '.'; + else { + FLT_OT_ERR("failed to normalize variable name, buffer too small"); + + retval = -1; + } + + if (flag_cpy) { + /* Copy variable name without modification. */ + retval = strlen(name); + if ((*len + retval + 1) > size) { + FLT_OT_ERR("failed to normalize variable name, buffer too small"); + + retval = -1; + } else { + (void)memcpy(var_name + *len, name, retval + 1); + + *len += retval; + } + } else { + /* + * HAProxy does not allow the use of variable names containing '-' + * or ' '. This of course applies to HTTP header names as well. + * Also, here the capital letters are converted to lowercase. + */ + while (retval != -1) + if (*len >= (size - 1)) { + FLT_OT_ERR("failed to normalize variable name, buffer too small"); + + retval = -1; + } else { + uint8_t ch = name[retval]; + + if (ch == '\0') + break; + else if (ch == '-') + ch = FLT_OT_VAR_CHAR_DASH; + else if (ch == ' ') + ch = FLT_OT_VAR_CHAR_SPACE; + else if (isupper(ch)) + ch = ist_lc[ch]; + + var_name[(*len)++] = ch; + retval++; + } + + var_name[*len] = '\0'; + } + + FLT_OT_DBG(3, "var_name: \"%s\" %d/%d", var_name, retval, *len); + + if (retval == -1) + *len = retval; + + FLT_OT_RETURN_INT(retval); +} + + +/*** + * NAME + * flt_ot_var_name - + * + * ARGUMENTS + * scope - + * prefix - + * name - + * flag_cpy - + * var_name - + * size - + * err - + * + * DESCRIPTION + * The function initializes the value of the 'smp' structure. If the 'data' + * argument is set, then the 'sample_data' member of the 'smp' structure is + * also initialized. + * + * RETURN VALUE + * - + */ +static int flt_ot_var_name(const char *scope, const char *prefix, const char *name, bool flag_cpy, char *var_name, size_t size, char **err) +{ + int retval = 0; + + FLT_OT_FUNC("\"%s\", \"%s\", \"%s\", %hhu, %p, %zu, %p:%p", scope, prefix, name, flag_cpy, var_name, size, FLT_OT_DPTR_ARGS(err)); + + if (flt_ot_normalize_name(var_name, size, &retval, scope, 0, err) >= 0) + if (flt_ot_normalize_name(var_name, size, &retval, prefix, 0, err) >= 0) + (void)flt_ot_normalize_name(var_name, size, &retval, name, flag_cpy, err); + + if (retval == -1) + FLT_OT_ERR("failed to construct variable name '%s.%s.%s'", scope, prefix, name); + + FLT_OT_RETURN_INT(retval); +} + + +/*** + * NAME + * flt_ot_ctx_loop - + * + * ARGUMENTS + * smp - + * scope - + * prefix - + * err - + * func - + * ptr - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +static int flt_ot_ctx_loop(struct sample *smp, const char *scope, const char *prefix, char **err, flt_ot_ctx_loop_cb func, void *ptr) +{ + FLT_OT_VAR_CTX_SIZE var_ctx_size; + char var_name[BUFSIZ], var_ctx[BUFSIZ]; + int i, var_name_len, var_ctx_len, rc, n = 1, retval = 0; + + FLT_OT_FUNC("%p, \"%s\", \"%s\", %p:%p, %p, %p", smp, scope, prefix, FLT_OT_DPTR_ARGS(err), func, ptr); + + /* + * The variable in which we will save the name of the OpenTracing + * context variable. + */ + var_name_len = flt_ot_var_name(scope, prefix, NULL, 0, var_name, sizeof(var_name), err); + if (var_name_len == -1) + FLT_OT_RETURN_INT(FLT_OT_RET_ERROR); + + /* + * Here we will try to find all the previously recorded variables from + * the currently set OpenTracing context. If we find the required + * variable and it is marked as deleted, we will mark it as active. + * If we do not find it, then it is added to the end of the previously + * saved names. + */ + if (vars_get_by_name(var_name, var_name_len, smp, NULL) == 0) { + FLT_OT_DBG(2, "ctx '%s' no variable found", var_name); + } + else if (smp->data.type != SMP_T_BIN) { + FLT_OT_ERR("ctx '%s' invalid data type %d", var_name, smp->data.type); + + retval = FLT_OT_RET_ERROR; + } + else { + FLT_OT_DBG_BUF(2, &(smp->data.u.str)); + + for (i = 0; i < b_data(&(smp->data.u.str)); i += sizeof(var_ctx_size) + var_ctx_len, n++) { + var_ctx_size = *((typeof(var_ctx_size) *)(b_orig(&(smp->data.u.str)) + i)); + var_ctx_len = abs(var_ctx_size); + + if ((i + sizeof(var_ctx_size) + var_ctx_len) > b_data(&(smp->data.u.str))) { + FLT_OT_ERR("ctx '%s' invalid data size", var_name); + + retval = FLT_OT_RET_ERROR; + + break; + } + + (void)memcpy(var_ctx, b_orig(&(smp->data.u.str)) + i + sizeof(var_ctx_size), var_ctx_len); + var_ctx[var_ctx_len] = '\0'; + + rc = func(smp, i, scope, prefix, var_ctx, var_ctx_size, err, ptr); + if (rc == FLT_OT_RET_ERROR) { + retval = FLT_OT_RET_ERROR; + + break; + } + else if (rc > 0) { + retval = n; + + break; + } + } + } + + FLT_OT_RETURN_INT(retval); +} + + +/*** + * NAME + * flt_ot_ctx_set_cb - + * + * ARGUMENTS + * smp - + * idx - + * scope - + * prefix - + * name - + * name_len - + * err - + * ptr - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +static int flt_ot_ctx_set_cb(struct sample *smp, size_t idx, const char *scope, const char *prefix, const char *name, FLT_OT_VAR_CTX_SIZE name_len, char **err, void *ptr) +{ + struct flt_ot_ctx *ctx = ptr; + int retval = 0; + + FLT_OT_FUNC("%p, %zu, \"%s\", \"%s\", \"%s\", %hhd, %p:%p, %p", smp, idx, scope, prefix, name, name_len, FLT_OT_DPTR_ARGS(err), ptr); + + if ((name_len == ctx->value_len) && (strncmp(name, ctx->value, name_len) == 0)) { + FLT_OT_DBG(2, "ctx '%s' found\n", name); + + retval = 1; + } + + FLT_OT_RETURN_INT(retval); +} + + +/*** + * NAME + * flt_ot_ctx_set - + * + * ARGUMENTS + * s - + * scope - + * prefix - + * name - + * opt - + * err - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +static int flt_ot_ctx_set(struct stream *s, const char *scope, const char *prefix, const char *name, uint opt, char **err) +{ + struct flt_ot_ctx ctx; + struct sample smp_ctx; + char var_name[BUFSIZ]; + bool flag_alloc = 0; + int rc, var_name_len, retval = FLT_OT_RET_ERROR; + + FLT_OT_FUNC("%p, \"%s\", \"%s\", \"%s\", %u, %p:%p", s, scope, prefix, name, opt, FLT_OT_DPTR_ARGS(err)); + + /* + * The variable in which we will save the name of the OpenTracing + * context variable. + */ + var_name_len = flt_ot_var_name(scope, prefix, NULL, 0, var_name, sizeof(var_name), err); + if (var_name_len == -1) + FLT_OT_RETURN_INT(retval); + + /* Normalized name of the OpenTracing context variable. */ + ctx.value_len = flt_ot_var_name(name, NULL, NULL, 0, ctx.value, sizeof(ctx.value), err); + if (ctx.value_len == -1) + FLT_OT_RETURN_INT(retval); + + flt_ot_smp_init(s, &smp_ctx, opt, 0, NULL); + + retval = flt_ot_ctx_loop(&smp_ctx, scope, prefix, err, flt_ot_ctx_set_cb, &ctx); + if (retval == 0) { + rc = flt_ot_smp_add(&(smp_ctx.data), ctx.value, ctx.value_len, err); + if (rc == FLT_OT_RET_ERROR) + retval = FLT_OT_RET_ERROR; + + flag_alloc = (rc == 0); + } + + if (retval == FLT_OT_RET_ERROR) { + /* Do nothing. */ + } + else if (retval > 0) { + FLT_OT_DBG(2, "ctx '%s' data found", ctx.value); + } + else if (vars_set_by_name_ifexist(var_name, var_name_len, &smp_ctx) == 0) { + FLT_OT_ERR("failed to set ctx '%s'", var_name); + + retval = FLT_OT_RET_ERROR; + } + else { + FLT_OT_DBG(2, "ctx '%s' -> '%.*s' set", var_name, (int)b_data(&(smp_ctx.data.u.str)), b_orig(&(smp_ctx.data.u.str))); + + retval = b_data(&(smp_ctx.data.u.str)); + } + + if (flag_alloc) + FLT_OT_FREE(b_orig(&(smp_ctx.data.u.str))); + + FLT_OT_RETURN_INT(retval); +} + + +/*** + * NAME + * flt_ot_var_register - + * + * ARGUMENTS + * scope - + * prefix - + * name - + * err - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +int flt_ot_var_register(const char *scope, const char *prefix, const char *name, char **err) +{ + struct arg arg; + char var_name[BUFSIZ]; + int retval = -1, var_name_len; + + FLT_OT_FUNC("\"%s\", \"%s\", \"%s\", %p:%p", scope, prefix, name, FLT_OT_DPTR_ARGS(err)); + + var_name_len = flt_ot_var_name(scope, prefix, name, 0, var_name, sizeof(var_name), err); + if (var_name_len == -1) + FLT_OT_RETURN_INT(retval); + + /* Set to 0 to not release var_name memory in vars_check_arg(). */ + (void)memset(&arg, 0, sizeof(arg)); + arg.type = ARGT_STR; + arg.data.str.area = var_name; + arg.data.str.data = var_name_len; + + if (vars_check_arg(&arg, err) == 0) { + FLT_OT_ERR_APPEND("failed to register variable '%s': %s", var_name, *err); + } else { + FLT_OT_DBG(2, "variable '%s' registered", var_name); + + retval = var_name_len; + } + + FLT_OT_RETURN_INT(retval); +} + + +/*** + * NAME + * flt_ot_var_set - + * + * ARGUMENTS + * s - + * scope - + * prefix - + * name - + * value - + * opt - + * err - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +int flt_ot_var_set(struct stream *s, const char *scope, const char *prefix, const char *name, const char *value, uint opt, char **err) +{ + struct sample smp; + char var_name[BUFSIZ]; + int retval = -1, var_name_len; + + FLT_OT_FUNC("%p, \"%s\", \"%s\", \"%s\", \"%s\", %u, %p:%p", s, scope, prefix, name, value, opt, FLT_OT_DPTR_ARGS(err)); + + var_name_len = flt_ot_var_name(scope, prefix, name, 0, var_name, sizeof(var_name), err); + if (var_name_len == -1) + FLT_OT_RETURN_INT(retval); + + flt_ot_smp_init(s, &smp, opt, SMP_T_STR, value); + + if (vars_set_by_name_ifexist(var_name, var_name_len, &smp) == 0) { + FLT_OT_ERR("failed to set variable '%s'", var_name); + } else { + FLT_OT_DBG(2, "variable '%s' set", var_name); + + retval = var_name_len; + + if (strcmp(scope, FLT_OT_VARS_SCOPE) == 0) + retval = flt_ot_ctx_set(s, scope, prefix, name, opt, err); + } + + FLT_OT_RETURN_INT(retval); +} + + +/*** + * NAME + * flt_ot_vars_unset_cb - + * + * ARGUMENTS + * smp - + * idx - + * scope - + * prefix - + * name - + * name_len - + * err - + * ptr - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +static int flt_ot_vars_unset_cb(struct sample *smp, size_t idx, const char *scope, const char *prefix, const char *name, FLT_OT_VAR_CTX_SIZE name_len, char **err, void *ptr) +{ + struct sample smp_ctx; + char var_ctx[BUFSIZ]; + int var_ctx_len, retval = FLT_OT_RET_ERROR; + + FLT_OT_FUNC("%p, %zu, \"%s\", \"%s\", \"%s\", %hhd, %p:%p, %p", smp, idx, scope, prefix, name, name_len, FLT_OT_DPTR_ARGS(err), ptr); + + var_ctx_len = flt_ot_var_name(scope, prefix, name, 1, var_ctx, sizeof(var_ctx), err); + if (var_ctx_len == -1) { + FLT_OT_ERR("ctx '%s' invalid", name); + + FLT_OT_RETURN_INT(retval); + } + + flt_ot_smp_init(smp->strm, &smp_ctx, smp->opt, 0, NULL); + + if (vars_unset_by_name_ifexist(var_ctx, var_ctx_len, &smp_ctx) == 0) { + FLT_OT_ERR("ctx '%s' no variable found", var_ctx); + } else { + FLT_OT_DBG(2, "ctx '%s' unset", var_ctx); + + retval = 0; + } + + FLT_OT_RETURN_INT(retval); +} + + +/*** + * NAME + * flt_ot_vars_unset - + * + * ARGUMENTS + * s - + * scope - + * prefix - + * opt - + * err - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +int flt_ot_vars_unset(struct stream *s, const char *scope, const char *prefix, uint opt, char **err) +{ + struct sample smp_ctx; + char var_name[BUFSIZ]; + int var_name_len, retval; + + FLT_OT_FUNC("%p, \"%s\", \"%s\", %u, %p:%p", s, scope, prefix, opt, FLT_OT_DPTR_ARGS(err)); + + flt_ot_smp_init(s, &smp_ctx, opt, 0, NULL); + + retval = flt_ot_ctx_loop(&smp_ctx, scope, prefix, err, flt_ot_vars_unset_cb, NULL); + if (retval != FLT_OT_RET_ERROR) { + /* + * After all ctx variables have been unset, the variable used + * to store their names should also be unset. + */ + var_name_len = flt_ot_var_name(scope, prefix, NULL, 0, var_name, sizeof(var_name), err); + if (var_name_len == -1) + FLT_OT_RETURN_INT(FLT_OT_RET_ERROR); + + flt_ot_smp_init(s, &smp_ctx, opt, 0, NULL); + + if (vars_unset_by_name_ifexist(var_name, var_name_len, &smp_ctx) == 0) { + FLT_OT_DBG(2, "variable '%s' not found", var_name); + } else { + FLT_OT_DBG(2, "variable '%s' unset", var_name); + + retval = 1; + } + } + + FLT_OT_RETURN_INT(retval); +} + + +/*** + * NAME + * flt_ot_vars_get_cb - + * + * ARGUMENTS + * smp - + * idx - + * scope - + * prefix - + * name - + * name_len - + * err - + * ptr - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +static int flt_ot_vars_get_cb(struct sample *smp, size_t idx, const char *scope, const char *prefix, const char *name, FLT_OT_VAR_CTX_SIZE name_len, char **err, void *ptr) +{ + struct otc_text_map **map = ptr; + struct sample smp_ctx; + char var_ctx[BUFSIZ], ot_var_name[BUFSIZ], ch; + int var_ctx_len, ot_var_name_len, retval = FLT_OT_RET_ERROR; + + FLT_OT_FUNC("%p, %zu, \"%s\", \"%s\", \"%s\", %hhd, %p:%p, %p", smp, idx, scope, prefix, name, name_len, FLT_OT_DPTR_ARGS(err), ptr); + + var_ctx_len = flt_ot_var_name(scope, prefix, name, 1, var_ctx, sizeof(var_ctx), err); + if (var_ctx_len == -1) { + FLT_OT_ERR("ctx '%s' invalid", name); + + FLT_OT_RETURN_INT(retval); + } + + flt_ot_smp_init(smp->strm, &smp_ctx, smp->opt, 0, NULL); + + if (vars_get_by_name(var_ctx, var_ctx_len, &smp_ctx, NULL) != 0) { + FLT_OT_DBG(2, "'%s' -> '%.*s'", var_ctx, (int)b_data(&(smp_ctx.data.u.str)), b_orig(&(smp_ctx.data.u.str))); + + if (*map == NULL) { + *map = otc_text_map_new(NULL, 8); + if (*map == NULL) { + FLT_OT_ERR("failed to create map data"); + + FLT_OT_RETURN_INT(FLT_OT_RET_ERROR); + } + } + + /* + * Eh, because the use of some characters is not allowed + * in the variable name, the conversion of the replaced + * characters to the original is performed here. + */ + for (ot_var_name_len = 0; (ch = name[ot_var_name_len]) != '\0'; ot_var_name_len++) + if (ot_var_name_len >= (FLT_OT_TABLESIZE(ot_var_name) - 1)) { + FLT_OT_ERR("failed to reverse variable name, buffer too small"); + + otc_text_map_destroy(map, OTC_TEXT_MAP_FREE_KEY | OTC_TEXT_MAP_FREE_VALUE); + + break; + } else { + ot_var_name[ot_var_name_len] = (ch == FLT_OT_VAR_CHAR_DASH) ? '-' : ((ch == FLT_OT_VAR_CHAR_SPACE) ? ' ' : ch); + } + ot_var_name[ot_var_name_len] = '\0'; + + if (*map == NULL) { + retval = FLT_OT_RET_ERROR; + } + else if (otc_text_map_add(*map, ot_var_name, ot_var_name_len, b_orig(&(smp_ctx.data.u.str)), b_data(&(smp_ctx.data.u.str)), OTC_TEXT_MAP_DUP_KEY | OTC_TEXT_MAP_DUP_VALUE) == -1) { + FLT_OT_ERR("failed to add map data"); + + otc_text_map_destroy(map, OTC_TEXT_MAP_FREE_KEY | OTC_TEXT_MAP_FREE_VALUE); + + retval = FLT_OT_RET_ERROR; + } + else { + retval = 0; + } + } else { + FLT_OT_DBG(2, "ctx '%s' no variable found", var_ctx); + } + + FLT_OT_RETURN_INT(retval); +} + + +/*** + * NAME + * flt_ot_vars_get - + * + * ARGUMENTS + * s - + * scope - + * prefix - + * opt - + * err - + * + * DESCRIPTION + * - + * + * RETURN VALUE + * - + */ +struct otc_text_map *flt_ot_vars_get(struct stream *s, const char *scope, const char *prefix, uint opt, char **err) +{ + struct sample smp_ctx; + struct otc_text_map *retptr = NULL; + + FLT_OT_FUNC("%p, \"%s\", \"%s\", %u, %p:%p", s, scope, prefix, opt, FLT_OT_DPTR_ARGS(err)); + + flt_ot_smp_init(s, &smp_ctx, opt, 0, NULL); + + (void)flt_ot_ctx_loop(&smp_ctx, scope, prefix, err, flt_ot_vars_get_cb, &retptr); + + ot_text_map_show(retptr); + + if ((retptr != NULL) && (retptr->count == 0)) { + FLT_OT_DBG(2, "WARNING: no variables found"); + + otc_text_map_destroy(&retptr, OTC_TEXT_MAP_FREE_KEY | OTC_TEXT_MAP_FREE_VALUE); + } + + FLT_OT_RETURN_PTR(retptr); +} + +/* + * Local variables: + * c-indent-level: 8 + * c-basic-offset: 8 + * End: + * + * vi: noexpandtab shiftwidth=8 tabstop=8 + */ diff --git a/addons/ot/test/README-speed-cmp b/addons/ot/test/README-speed-cmp new file mode 100644 index 0000000..9251faa --- /dev/null +++ b/addons/ot/test/README-speed-cmp @@ -0,0 +1,111 @@ +--- rate-limit 100.0 -------------------------------------------------- +Running 5m test @ http://localhost:10080/index.html + 8 threads and 8 connections + Thread Stats Avg Stdev Max +/- Stdev + Latency 650.95us 431.15us 46.44ms 96.67% + Req/Sec 1.44k 51.39 2.57k 74.89% + Latency Distribution + 50% 608.00us + 75% 760.00us + 90% 0.91ms + 99% 1.31ms + 3434836 requests in 5.00m, 0.89GB read +Requests/sec: 11446.99 +Transfer/sec: 3.03MB +---------------------------------------------------------------------- + +--- rate-limit 50.0 -------------------------------------------------- +Running 5m test @ http://localhost:10080/index.html + 8 threads and 8 connections + Thread Stats Avg Stdev Max +/- Stdev + Latency 398.00us 371.39us 22.56ms 97.23% + Req/Sec 2.32k 84.01 2.76k 74.84% + Latency Distribution + 50% 350.00us + 75% 467.00us + 90% 593.00us + 99% 1.03ms + 5530848 requests in 5.00m, 1.43GB read +Requests/sec: 18434.31 +Transfer/sec: 4.89MB +---------------------------------------------------------------------- + +--- rate-limit 10.0 -------------------------------------------------- +Running 5m test @ http://localhost:10080/index.html + 8 threads and 8 connections + Thread Stats Avg Stdev Max +/- Stdev + Latency 316.75us 351.92us 23.00ms 98.57% + Req/Sec 2.87k 94.02 3.22k 79.30% + Latency Distribution + 50% 273.00us + 75% 342.00us + 90% 424.00us + 99% 0.94ms + 6859293 requests in 5.00m, 1.78GB read +Requests/sec: 22862.16 +Transfer/sec: 6.06MB +---------------------------------------------------------------------- + +--- rate-limit 2.5 -------------------------------------------------- +Running 5m test @ http://localhost:10080/index.html + 8 threads and 8 connections + Thread Stats Avg Stdev Max +/- Stdev + Latency 307.90us 368.64us 26.08ms 98.71% + Req/Sec 2.96k 103.84 3.23k 83.76% + Latency Distribution + 50% 264.00us + 75% 327.00us + 90% 402.00us + 99% 0.97ms + 7065667 requests in 5.00m, 1.83GB read +Requests/sec: 23550.37 +Transfer/sec: 6.24MB +---------------------------------------------------------------------- + +--- rate-limit 0.0 -------------------------------------------------- +Running 5m test @ http://localhost:10080/index.html + 8 threads and 8 connections + Thread Stats Avg Stdev Max +/- Stdev + Latency 304.60us 376.36us 30.26ms 98.74% + Req/Sec 2.99k 106.93 3.24k 83.08% + Latency Distribution + 50% 262.00us + 75% 323.00us + 90% 396.00us + 99% 0.95ms + 7136261 requests in 5.00m, 1.85GB read +Requests/sec: 23785.77 +Transfer/sec: 6.31MB +---------------------------------------------------------------------- + +--- rate-limit disabled -------------------------------------------------- +Running 5m test @ http://localhost:10080/index.html + 8 threads and 8 connections + Thread Stats Avg Stdev Max +/- Stdev + Latency 300.90us 342.35us 22.13ms 98.74% + Req/Sec 3.00k 95.67 3.33k 81.11% + Latency Distribution + 50% 261.00us + 75% 322.00us + 90% 394.00us + 99% 806.00us + 7159525 requests in 5.00m, 1.85GB read +Requests/sec: 23863.05 +Transfer/sec: 6.33MB +---------------------------------------------------------------------- + +--- rate-limit off -------------------------------------------------- +Running 5m test @ http://localhost:10080/index.html + 8 threads and 8 connections + Thread Stats Avg Stdev Max +/- Stdev + Latency 302.51us 371.99us 30.26ms 98.77% + Req/Sec 3.00k 104.43 3.73k 83.74% + Latency Distribution + 50% 260.00us + 75% 321.00us + 90% 394.00us + 99% 0.89ms + 7170345 requests in 5.00m, 1.86GB read +Requests/sec: 23898.19 +Transfer/sec: 6.34MB +---------------------------------------------------------------------- diff --git a/addons/ot/test/README-speed-ctx b/addons/ot/test/README-speed-ctx new file mode 100644 index 0000000..fa8fc2c --- /dev/null +++ b/addons/ot/test/README-speed-ctx @@ -0,0 +1,111 @@ +--- rate-limit 100.0 -------------------------------------------------- +Running 5m test @ http://localhost:10080/index.html + 8 threads and 8 connections + Thread Stats Avg Stdev Max +/- Stdev + Latency 2.49ms 799.87us 43.00ms 70.90% + Req/Sec 393.01 20.61 696.00 71.68% + Latency Distribution + 50% 2.50ms + 75% 3.00ms + 90% 3.38ms + 99% 4.23ms + 939237 requests in 5.00m, 249.01MB read +Requests/sec: 3130.01 +Transfer/sec: 849.75KB +---------------------------------------------------------------------- + +--- rate-limit 50.0 -------------------------------------------------- +Running 5m test @ http://localhost:10080/index.html + 8 threads and 8 connections + Thread Stats Avg Stdev Max +/- Stdev + Latency 1.27ms 0.97ms 40.77ms 56.91% + Req/Sec 778.22 70.30 1.36k 69.10% + Latency Distribution + 50% 1.36ms + 75% 1.80ms + 90% 2.49ms + 99% 3.51ms + 1859055 requests in 5.00m, 492.88MB read +Requests/sec: 6195.58 +Transfer/sec: 1.64MB +---------------------------------------------------------------------- + +--- rate-limit 10.0 -------------------------------------------------- +Running 5m test @ http://localhost:10080/index.html + 8 threads and 8 connections + Thread Stats Avg Stdev Max +/- Stdev + Latency 442.00us 481.47us 31.61ms 90.27% + Req/Sec 2.25k 130.05 2.73k 72.83% + Latency Distribution + 50% 287.00us + 75% 526.00us + 90% 0.92ms + 99% 1.76ms + 5380213 requests in 5.00m, 1.39GB read +Requests/sec: 17930.27 +Transfer/sec: 4.75MB +---------------------------------------------------------------------- + +--- rate-limit 2.5 -------------------------------------------------- +Running 5m test @ http://localhost:10080/index.html + 8 threads and 8 connections + Thread Stats Avg Stdev Max +/- Stdev + Latency 346.65us 414.65us 28.50ms 95.63% + Req/Sec 2.75k 159.74 3.23k 84.68% + Latency Distribution + 50% 271.00us + 75% 353.00us + 90% 505.00us + 99% 1.55ms + 6560093 requests in 5.00m, 1.70GB read +Requests/sec: 21864.43 +Transfer/sec: 5.80MB +---------------------------------------------------------------------- + +--- rate-limit 0.0 -------------------------------------------------- +Running 5m test @ http://localhost:10080/index.html + 8 threads and 8 connections + Thread Stats Avg Stdev Max +/- Stdev + Latency 313.32us 402.25us 24.73ms 98.55% + Req/Sec 2.95k 145.03 3.21k 88.99% + Latency Distribution + 50% 264.00us + 75% 327.00us + 90% 403.00us + 99% 1.33ms + 7050847 requests in 5.00m, 1.83GB read +Requests/sec: 23501.14 +Transfer/sec: 6.23MB +---------------------------------------------------------------------- + +--- rate-limit disabled -------------------------------------------------- +Running 5m test @ http://localhost:10080/index.html + 8 threads and 8 connections + Thread Stats Avg Stdev Max +/- Stdev + Latency 310.19us 384.76us 22.18ms 98.66% + Req/Sec 2.96k 115.62 3.37k 84.30% + Latency Distribution + 50% 265.00us + 75% 327.00us + 90% 402.00us + 99% 1.10ms + 7058682 requests in 5.00m, 1.83GB read +Requests/sec: 23526.70 +Transfer/sec: 6.24MB +---------------------------------------------------------------------- + +--- rate-limit off -------------------------------------------------- +Running 5m test @ http://localhost:10080/index.html + 8 threads and 8 connections + Thread Stats Avg Stdev Max +/- Stdev + Latency 305.86us 367.56us 25.76ms 98.65% + Req/Sec 2.99k 116.93 3.43k 85.59% + Latency Distribution + 50% 261.00us + 75% 322.00us + 90% 396.00us + 99% 1.09ms + 7137173 requests in 5.00m, 1.85GB read +Requests/sec: 23788.84 +Transfer/sec: 6.31MB +---------------------------------------------------------------------- diff --git a/addons/ot/test/README-speed-fe-be b/addons/ot/test/README-speed-fe-be new file mode 100644 index 0000000..ab2b7af --- /dev/null +++ b/addons/ot/test/README-speed-fe-be @@ -0,0 +1,111 @@ +--- rate-limit 100.0 -------------------------------------------------- +Running 5m test @ http://localhost:10080/index.html + 8 threads and 8 connections + Thread Stats Avg Stdev Max +/- Stdev + Latency 0.89ms 466.84us 35.44ms 94.39% + Req/Sec 1.09k 39.30 1.32k 72.60% + Latency Distribution + 50% 823.00us + 75% 1.00ms + 90% 1.20ms + 99% 2.14ms + 2594524 requests in 5.00m, 687.86MB read +Requests/sec: 8645.83 +Transfer/sec: 2.29MB +---------------------------------------------------------------------- + +--- rate-limit 50.0 -------------------------------------------------- +Running 5m test @ http://localhost:10080/index.html + 8 threads and 8 connections + Thread Stats Avg Stdev Max +/- Stdev + Latency 681.74us 463.28us 20.45ms 95.46% + Req/Sec 1.41k 54.00 1.60k 68.97% + Latency Distribution + 50% 613.00us + 75% 785.00us + 90% 0.98ms + 99% 2.06ms + 3367473 requests in 5.00m, 0.87GB read +Requests/sec: 11222.76 +Transfer/sec: 2.98MB +---------------------------------------------------------------------- + +--- rate-limit 10.0 -------------------------------------------------- +Running 5m test @ http://localhost:10080/index.html + 8 threads and 8 connections + Thread Stats Avg Stdev Max +/- Stdev + Latency 558.32us 458.54us 29.40ms 97.73% + Req/Sec 1.72k 60.67 2.05k 73.10% + Latency Distribution + 50% 494.00us + 75% 610.00us + 90% 743.00us + 99% 2.08ms + 4105420 requests in 5.00m, 1.06GB read +Requests/sec: 13683.36 +Transfer/sec: 3.63MB +---------------------------------------------------------------------- + +--- rate-limit 2.5 -------------------------------------------------- +Running 5m test @ http://localhost:10080/index.html + 8 threads and 8 connections + Thread Stats Avg Stdev Max +/- Stdev + Latency 542.66us 440.31us 22.63ms 97.88% + Req/Sec 1.76k 60.02 2.00k 72.27% + Latency Distribution + 50% 481.00us + 75% 588.00us + 90% 710.00us + 99% 2.05ms + 4214525 requests in 5.00m, 1.09GB read +Requests/sec: 14046.76 +Transfer/sec: 3.72MB +---------------------------------------------------------------------- + +--- rate-limit 0.0 -------------------------------------------------- +Running 5m test @ http://localhost:10080/index.html + 8 threads and 8 connections + Thread Stats Avg Stdev Max +/- Stdev + Latency 529.06us 414.38us 30.09ms 97.97% + Req/Sec 1.80k 59.34 2.05k 74.47% + Latency Distribution + 50% 473.00us + 75% 576.00us + 90% 692.00us + 99% 1.79ms + 4287428 requests in 5.00m, 1.11GB read +Requests/sec: 14290.45 +Transfer/sec: 3.79MB +---------------------------------------------------------------------- + +--- rate-limit disabled -------------------------------------------------- +Running 5m test @ http://localhost:10080/index.html + 8 threads and 8 connections + Thread Stats Avg Stdev Max +/- Stdev + Latency 517.81us 463.10us 36.81ms 98.25% + Req/Sec 1.85k 62.39 2.21k 75.65% + Latency Distribution + 50% 458.00us + 75% 558.00us + 90% 670.00us + 99% 1.96ms + 4416273 requests in 5.00m, 1.14GB read +Requests/sec: 14719.43 +Transfer/sec: 3.90MB +---------------------------------------------------------------------- + +--- rate-limit off -------------------------------------------------- +Running 5m test @ http://localhost:10080/index.html + 8 threads and 8 connections + Thread Stats Avg Stdev Max +/- Stdev + Latency 511.67us 428.18us 27.68ms 98.15% + Req/Sec 1.86k 60.67 2.05k 75.44% + Latency Distribution + 50% 455.00us + 75% 554.00us + 90% 666.00us + 99% 1.81ms + 4441271 requests in 5.00m, 1.15GB read +Requests/sec: 14803.32 +Transfer/sec: 3.92MB +---------------------------------------------------------------------- diff --git a/addons/ot/test/README-speed-sa b/addons/ot/test/README-speed-sa new file mode 100644 index 0000000..ea8749d --- /dev/null +++ b/addons/ot/test/README-speed-sa @@ -0,0 +1,111 @@ +--- rate-limit 100.0 -------------------------------------------------- +Running 5m test @ http://localhost:10080/index.html + 8 threads and 8 connections + Thread Stats Avg Stdev Max +/- Stdev + Latency 1.24ms 522.78us 35.59ms 79.12% + Req/Sec 767.71 38.72 3.02k 72.19% + Latency Distribution + 50% 1.20ms + 75% 1.51ms + 90% 1.78ms + 99% 2.37ms + 1834067 requests in 5.00m, 486.25MB read +Requests/sec: 6111.57 +Transfer/sec: 1.62MB +---------------------------------------------------------------------- + +--- rate-limit 50.0 -------------------------------------------------- +Running 5m test @ http://localhost:10080/index.html + 8 threads and 8 connections + Thread Stats Avg Stdev Max +/- Stdev + Latency 593.11us 476.81us 43.00ms 91.27% + Req/Sec 1.59k 81.15 2.07k 71.14% + Latency Distribution + 50% 549.00us + 75% 788.00us + 90% 1.03ms + 99% 1.62ms + 3795987 requests in 5.00m, 0.98GB read +Requests/sec: 12650.65 +Transfer/sec: 3.35MB +---------------------------------------------------------------------- + +--- rate-limit 10.0 -------------------------------------------------- +Running 5m test @ http://localhost:10080/index.html + 8 threads and 8 connections + Thread Stats Avg Stdev Max +/- Stdev + Latency 326.02us 355.00us 29.23ms 98.05% + Req/Sec 2.80k 88.05 3.30k 75.36% + Latency Distribution + 50% 277.00us + 75% 356.00us + 90% 456.00us + 99% 0.97ms + 6675563 requests in 5.00m, 1.73GB read +Requests/sec: 22249.78 +Transfer/sec: 5.90MB +---------------------------------------------------------------------- + +--- rate-limit 2.5 -------------------------------------------------- +Running 5m test @ http://localhost:10080/index.html + 8 threads and 8 connections + Thread Stats Avg Stdev Max +/- Stdev + Latency 311.77us 357.45us 24.11ms 98.62% + Req/Sec 2.91k 94.70 3.18k 78.52% + Latency Distribution + 50% 268.00us + 75% 334.00us + 90% 413.00us + 99% 0.94ms + 6960933 requests in 5.00m, 1.80GB read +Requests/sec: 23201.07 +Transfer/sec: 6.15MB +---------------------------------------------------------------------- + +--- rate-limit 0.0 -------------------------------------------------- +Running 5m test @ http://localhost:10080/index.html + 8 threads and 8 connections + Thread Stats Avg Stdev Max +/- Stdev + Latency 302.51us 330.50us 25.84ms 98.69% + Req/Sec 2.98k 91.46 3.40k 78.84% + Latency Distribution + 50% 263.00us + 75% 325.00us + 90% 397.00us + 99% 812.00us + 7112084 requests in 5.00m, 1.84GB read +Requests/sec: 23705.14 +Transfer/sec: 6.28MB +---------------------------------------------------------------------- + +--- rate-limit disabled -------------------------------------------------- +Running 5m test @ http://localhost:10080/index.html + 8 threads and 8 connections + Thread Stats Avg Stdev Max +/- Stdev + Latency 303.01us 353.98us 28.03ms 98.76% + Req/Sec 2.99k 93.97 3.34k 81.12% + Latency Distribution + 50% 262.00us + 75% 323.00us + 90% 395.00us + 99% 838.00us + 7133837 requests in 5.00m, 1.85GB read +Requests/sec: 23777.95 +Transfer/sec: 6.30MB +---------------------------------------------------------------------- + +--- rate-limit off -------------------------------------------------- +Running 5m test @ http://localhost:10080/index.html + 8 threads and 8 connections + Thread Stats Avg Stdev Max +/- Stdev + Latency 302.61us 349.74us 25.48ms 98.75% + Req/Sec 2.99k 94.85 3.49k 80.75% + Latency Distribution + 50% 262.00us + 75% 323.00us + 90% 395.00us + 99% 822.00us + 7132714 requests in 5.00m, 1.85GB read +Requests/sec: 23773.35 +Transfer/sec: 6.30MB +---------------------------------------------------------------------- diff --git a/addons/ot/test/be/cfg-dd.json b/addons/ot/test/be/cfg-dd.json new file mode 100644 index 0000000..8b69b03 --- /dev/null +++ b/addons/ot/test/be/cfg-dd.json @@ -0,0 +1,5 @@ +{ + "service": "BE", + "agent_host": "localhost", + "agent_port": 8126 +} diff --git a/addons/ot/test/be/cfg-jaeger.yml b/addons/ot/test/be/cfg-jaeger.yml new file mode 100644 index 0000000..0893166 --- /dev/null +++ b/addons/ot/test/be/cfg-jaeger.yml @@ -0,0 +1,34 @@ +service_name: + BE + +### +# When using configuration object to instantiate the tracer, the type of +# sampling can be selected via sampler.type and sampler.param properties. +# Jaeger libraries support the following samplers: +# +# - Constant (sampler.type=const) sampler always makes the same decision for +# all traces. It either samples all traces (sampler.param=1) or none of +# them (sampler.param=0). +# +# - Probabilistic (sampler.type=probabilistic) sampler makes a random sampling +# decision with the probability of sampling equal to the value of +# sampler.param property. For example, with sampler.param=0.1 approximately +# 1 in 10 traces will be sampled. +# +# - Rate Limiting (sampler.type=ratelimiting) sampler uses a leaky bucket rate +# limiter to ensure that traces are sampled with a certain constant rate. +# For example, when sampler.param=2.0 it will sample requests with the rate +# of 2 traces per second. +# +# - Remote (sampler.type=remote, which is also the default) sampler consults +# Jaeger agent for the appropriate sampling strategy to use in the current +# service. This allows controlling the sampling strategies in the services +# from a central configuration in Jaeger backend, or even dynamically. +# +sampler: + type: ratelimiting + param: 10.0 + +reporter: + logSpans: true + localAgentHostPort: localhost:6831 diff --git a/addons/ot/test/be/cfg-zipkin.json b/addons/ot/test/be/cfg-zipkin.json new file mode 100644 index 0000000..f0e30d5 --- /dev/null +++ b/addons/ot/test/be/cfg-zipkin.json @@ -0,0 +1,4 @@ +{ + "service_name": "BE", + "collector_host": "localhost" +} diff --git a/addons/ot/test/be/haproxy.cfg b/addons/ot/test/be/haproxy.cfg new file mode 100644 index 0000000..c225a2f --- /dev/null +++ b/addons/ot/test/be/haproxy.cfg @@ -0,0 +1,37 @@ +global +# nbthread 1 + maxconn 5000 + hard-stop-after 10s +# log localhost:514 local7 debug +# debug + stats socket /tmp/haproxy-be.sock mode 666 level admin + +defaults + log global + mode http + option httplog + option dontlognull + option httpclose + retries 3 + maxconn 4000 + timeout connect 5000 + timeout client 50000 + timeout server 50000 + +listen stats + mode http + bind *:8002 + stats uri / + stats admin if TRUE + stats refresh 10s + +frontend ot-test-be-frontend + bind *:11080 + mode http + default_backend servers-backend + + filter opentracing id ot-test-be config be/ot.cfg + +backend servers-backend + mode http + server server-1 127.0.0.1:8000 diff --git a/addons/ot/test/be/ot.cfg b/addons/ot/test/be/ot.cfg new file mode 100644 index 0000000..edd3f76 --- /dev/null +++ b/addons/ot/test/be/ot.cfg @@ -0,0 +1,62 @@ +[ot-test-be] + ot-tracer ot-test-tracer + config be/cfg-jaeger.yml + plugin libjaeger_opentracing_plugin-0.5.0.so +# log localhost:514 local7 debug + option dontlog-normal + option hard-errors + no option disabled + + scopes frontend_http_request + scopes backend_tcp_request + scopes backend_http_request + scopes client_session_end + + scopes server_session_start + scopes tcp_response + scopes http_response + scopes server_session_end + + ot-scope frontend_http_request + extract "ot-ctx" use-headers + span "HAProxy session" child-of "ot-ctx" root + baggage "haproxy_id" var(sess.ot.uuid) + span "Client session" child-of "HAProxy session" + span "Frontend HTTP request" child-of "Client session" + tag "http.method" method + tag "http.url" url + tag "http.version" str("HTTP/") req.ver + event on-frontend-http-request + + ot-scope backend_tcp_request + span "Backend TCP request" follows-from "Frontend HTTP request" + finish "Frontend HTTP request" + event on-backend-tcp-request + + ot-scope backend_http_request + span "Backend HTTP request" follows-from "Backend TCP request" + finish "Backend TCP request" + event on-backend-http-request + + ot-scope client_session_end + finish "Client session" + event on-client-session-end + + ot-scope server_session_start + span "Server session" child-of "HAProxy session" + finish "Backend HTTP request" + event on-server-session-start + + ot-scope tcp_response + span "TCP response" child-of "Server session" + event on-tcp-response + + ot-scope http_response + span "HTTP response" follows-from "TCP response" + tag "http.status_code" status + finish "TCP response" + event on-http-response + + ot-scope server_session_end + finish * + event on-server-session-end diff --git a/addons/ot/test/cmp/cfg-dd.json b/addons/ot/test/cmp/cfg-dd.json new file mode 100644 index 0000000..a931f45 --- /dev/null +++ b/addons/ot/test/cmp/cfg-dd.json @@ -0,0 +1,5 @@ +{ + "service": "CMP", + "agent_host": "localhost", + "agent_port": 8126 +} diff --git a/addons/ot/test/cmp/cfg-jaeger.yml b/addons/ot/test/cmp/cfg-jaeger.yml new file mode 100644 index 0000000..78efc2d --- /dev/null +++ b/addons/ot/test/cmp/cfg-jaeger.yml @@ -0,0 +1,34 @@ +service_name: + CMP + +### +# When using configuration object to instantiate the tracer, the type of +# sampling can be selected via sampler.type and sampler.param properties. +# Jaeger libraries support the following samplers: +# +# - Constant (sampler.type=const) sampler always makes the same decision for +# all traces. It either samples all traces (sampler.param=1) or none of +# them (sampler.param=0). +# +# - Probabilistic (sampler.type=probabilistic) sampler makes a random sampling +# decision with the probability of sampling equal to the value of +# sampler.param property. For example, with sampler.param=0.1 approximately +# 1 in 10 traces will be sampled. +# +# - Rate Limiting (sampler.type=ratelimiting) sampler uses a leaky bucket rate +# limiter to ensure that traces are sampled with a certain constant rate. +# For example, when sampler.param=2.0 it will sample requests with the rate +# of 2 traces per second. +# +# - Remote (sampler.type=remote, which is also the default) sampler consults +# Jaeger agent for the appropriate sampling strategy to use in the current +# service. This allows controlling the sampling strategies in the services +# from a central configuration in Jaeger backend, or even dynamically. +# +sampler: + type: ratelimiting + param: 10.0 + +reporter: + logSpans: true + localAgentHostPort: localhost:6831 diff --git a/addons/ot/test/cmp/cfg-zipkin.json b/addons/ot/test/cmp/cfg-zipkin.json new file mode 100644 index 0000000..7e9d3dd --- /dev/null +++ b/addons/ot/test/cmp/cfg-zipkin.json @@ -0,0 +1,4 @@ +{ + "service_name": "CMP", + "collector_host": "localhost" +} diff --git a/addons/ot/test/cmp/haproxy.cfg b/addons/ot/test/cmp/haproxy.cfg new file mode 100644 index 0000000..9d22725 --- /dev/null +++ b/addons/ot/test/cmp/haproxy.cfg @@ -0,0 +1,36 @@ +global +# nbthread 1 + maxconn 5000 + hard-stop-after 10s + stats socket /tmp/haproxy.sock mode 666 level admin + +defaults + log global + mode http + option httplog + option dontlognull + option httpclose + retries 3 + maxconn 4000 + timeout connect 5000 + timeout client 50000 + timeout server 50000 + +listen stats + mode http + bind *:8001 + stats uri / + stats admin if TRUE + stats refresh 10s + +frontend ot-test-cmp-frontend + bind *:10080 + mode http + default_backend servers-backend + + acl acl-http-status-ok status 100:399 + filter opentracing id ot-test-cmp config cmp/ot.cfg + +backend servers-backend + mode http + server server-1 127.0.0.1:8000 diff --git a/addons/ot/test/cmp/ot.cfg b/addons/ot/test/cmp/ot.cfg new file mode 100644 index 0000000..21b15dd --- /dev/null +++ b/addons/ot/test/cmp/ot.cfg @@ -0,0 +1,83 @@ +[ot-test-cmp] + ot-tracer ot-test-tracer + config cmp/cfg-jaeger.yml + plugin libjaeger_opentracing_plugin-0.5.0.so +# log localhost:514 local7 debug + option dontlog-normal + option hard-errors + no option disabled + rate-limit 100.0 + + scopes client_session_start + scopes frontend_tcp_request + scopes frontend_http_request + scopes backend_tcp_request + scopes backend_http_request + scopes server_unavailable + + scopes server_session_start + scopes tcp_response + scopes http_response http_response-error server_session_end client_session_end + + ot-scope client_session_start + span "HAProxy session" root + baggage "haproxy_id" var(sess.ot.uuid) + span "Client session" child-of "HAProxy session" + event on-client-session-start + + ot-scope frontend_tcp_request + span "Frontend TCP request" child-of "Client session" + event on-frontend-tcp-request + + ot-scope frontend_http_request + span "Frontend HTTP request" follows-from "Frontend TCP request" + tag "http.method" method + tag "http.url" url + tag "http.version" str("HTTP/") req.ver + finish "Frontend TCP request" + event on-frontend-http-request + + ot-scope backend_tcp_request + span "Backend TCP request" follows-from "Frontend HTTP request" + finish "Frontend HTTP request" + event on-backend-tcp-request + + ot-scope backend_http_request + span "Backend HTTP request" follows-from "Backend TCP request" + finish "Backend TCP request" + event on-backend-http-request + + ot-scope server_unavailable + span "HAProxy session" + tag "error" bool(true) + log "status" str("503 Service Unavailable") + finish * + event on-server-unavailable + + ot-scope server_session_start + span "Server session" child-of "HAProxy session" + finish "Backend HTTP request" + event on-server-session-start + + ot-scope tcp_response + span "TCP response" child-of "Server session" + event on-tcp-response + + ot-scope http_response + span "HTTP response" follows-from "TCP response" + tag "http.status_code" status + finish "TCP response" + event on-http-response + + ot-scope http_response-error + span "HTTP response" + tag "error" bool(true) + event on-http-response if !acl-http-status-ok + + ot-scope server_session_end + finish "HTTP response" "Server session" + event on-http-response + + ot-scope client_session_end + finish "*" + event on-http-response diff --git a/addons/ot/test/ctx/cfg-dd.json b/addons/ot/test/ctx/cfg-dd.json new file mode 100644 index 0000000..f68d97a --- /dev/null +++ b/addons/ot/test/ctx/cfg-dd.json @@ -0,0 +1,5 @@ +{ + "service": "CTX", + "agent_host": "localhost", + "agent_port": 8126 +} diff --git a/addons/ot/test/ctx/cfg-jaeger.yml b/addons/ot/test/ctx/cfg-jaeger.yml new file mode 100644 index 0000000..659724a --- /dev/null +++ b/addons/ot/test/ctx/cfg-jaeger.yml @@ -0,0 +1,34 @@ +service_name: + CTX + +### +# When using configuration object to instantiate the tracer, the type of +# sampling can be selected via sampler.type and sampler.param properties. +# Jaeger libraries support the following samplers: +# +# - Constant (sampler.type=const) sampler always makes the same decision for +# all traces. It either samples all traces (sampler.param=1) or none of +# them (sampler.param=0). +# +# - Probabilistic (sampler.type=probabilistic) sampler makes a random sampling +# decision with the probability of sampling equal to the value of +# sampler.param property. For example, with sampler.param=0.1 approximately +# 1 in 10 traces will be sampled. +# +# - Rate Limiting (sampler.type=ratelimiting) sampler uses a leaky bucket rate +# limiter to ensure that traces are sampled with a certain constant rate. +# For example, when sampler.param=2.0 it will sample requests with the rate +# of 2 traces per second. +# +# - Remote (sampler.type=remote, which is also the default) sampler consults +# Jaeger agent for the appropriate sampling strategy to use in the current +# service. This allows controlling the sampling strategies in the services +# from a central configuration in Jaeger backend, or even dynamically. +# +sampler: + type: ratelimiting + param: 10.0 + +reporter: + logSpans: true + localAgentHostPort: localhost:6831 diff --git a/addons/ot/test/ctx/cfg-zipkin.json b/addons/ot/test/ctx/cfg-zipkin.json new file mode 100644 index 0000000..3a3a257 --- /dev/null +++ b/addons/ot/test/ctx/cfg-zipkin.json @@ -0,0 +1,4 @@ +{ + "service_name": "CTX", + "collector_host": "localhost" +} diff --git a/addons/ot/test/ctx/haproxy.cfg b/addons/ot/test/ctx/haproxy.cfg new file mode 100644 index 0000000..d240a99 --- /dev/null +++ b/addons/ot/test/ctx/haproxy.cfg @@ -0,0 +1,38 @@ +global +# nbthread 1 + maxconn 5000 + hard-stop-after 10s + stats socket /tmp/haproxy.sock mode 666 level admin + +defaults + log global + mode http + option httplog + option dontlognull + option httpclose + retries 3 + maxconn 4000 + timeout connect 5000 + timeout client 50000 + timeout server 50000 + +listen stats + mode http + bind *:8001 + stats uri / + stats admin if TRUE + stats refresh 10s + +frontend ot-test-ctx-frontend + bind *:10080 + mode http + default_backend servers-backend + + acl acl-http-status-ok status 100:399 + filter opentracing id ot-test-ctx config ctx/ot.cfg + http-response ot-group ot-test-ctx http_response_group if acl-http-status-ok + http-after-response ot-group ot-test-ctx http_after_response_group if !acl-http-status-ok + +backend servers-backend + mode http + server server-1 127.0.0.1:8000 diff --git a/addons/ot/test/ctx/ot.cfg b/addons/ot/test/ctx/ot.cfg new file mode 100644 index 0000000..a06a4e0 --- /dev/null +++ b/addons/ot/test/ctx/ot.cfg @@ -0,0 +1,197 @@ +[ot-test-ctx] + ot-tracer ot-test-tracer + log localhost:514 local7 debug + config ctx/cfg-jaeger.yml + plugin libjaeger_opentracing_plugin-0.5.0.so + option dontlog-normal + option hard-errors + no option disabled + rate-limit 100.0 + + groups http_response_group + groups http_after_response_group + + scopes client_session_start_1 + scopes client_session_start_2 + scopes frontend_tcp_request + scopes http_wait_request + scopes http_body_request + scopes frontend_http_request + scopes switching_rules_request + scopes backend_tcp_request + scopes backend_http_request + scopes process_server_rules_request + scopes http_process_request + scopes tcp_rdp_cookie_request + scopes process_sticking_rules_request + scopes client_session_end + scopes server_unavailable + + scopes server_session_start + scopes tcp_response + scopes http_wait_response + scopes process_store_rules_response + scopes http_response http_response-error + scopes server_session_end + + ot-group http_response_group + scopes http_response_1 + scopes http_response_2 + + ot-scope http_response_1 + span "HTTP response" + log "hdr.content" res.hdr("content-type") str("; length: ") res.hdr("content-length") str(" bytes") + + ot-scope http_response_2 + span "HTTP response" + log "hdr.date" res.hdr("date") str(" / ") res.hdr("last-modified") + + ot-group http_after_response_group + scopes http_after_response + + ot-scope http_after_response + span "HAProxy response" child-of "HAProxy session" + tag "error" bool(true) + tag "http.status_code" status + + ot-scope client_session_start_1 + span "HAProxy session" root + inject "ot_ctx_1" use-headers use-vars + baggage "haproxy_id" var(sess.ot.uuid) + event on-client-session-start + + ot-scope client_session_start_2 + extract "ot_ctx_1" use-vars + span "Client session" child-of "ot_ctx_1" + inject "ot_ctx_2" use-headers use-vars + event on-client-session-start + + ot-scope frontend_tcp_request + extract "ot_ctx_2" use-vars + span "Frontend TCP request" child-of "ot_ctx_2" + inject "ot_ctx_3" use-headers use-vars + event on-frontend-tcp-request + + ot-scope http_wait_request + extract "ot_ctx_3" use-vars + span "HTTP wait request" follows-from "ot_ctx_3" + inject "ot_ctx_4" use-headers use-vars + finish "Frontend TCP request" "ot_ctx_3" + event on-http-wait-request + + ot-scope http_body_request + extract "ot_ctx_4" use-vars + span "HTTP body request" follows-from "ot_ctx_4" + inject "ot_ctx_5" use-headers use-vars + finish "HTTP wait request" "ot_ctx_4" + event on-http-body-request + + ot-scope frontend_http_request + extract "ot_ctx_5" use-vars + span "Frontend HTTP request" follows-from "ot_ctx_5" + tag "http.method" method + tag "http.url" url + tag "http.version" str("HTTP/") req.ver + inject "ot_ctx_6" use-headers use-vars + finish "HTTP body request" "ot_ctx_5" + event on-frontend-http-request + + ot-scope switching_rules_request + extract "ot_ctx_6" use-vars + span "Switching rules request" follows-from "ot_ctx_6" + inject "ot_ctx_7" use-headers use-vars + finish "Frontend HTTP request" "ot_ctx_6" + event on-switching-rules-request + + ot-scope backend_tcp_request + extract "ot_ctx_7" use-vars + span "Backend TCP request" follows-from "ot_ctx_7" + inject "ot_ctx_8" use-headers use-vars + finish "Switching rules request" "ot_ctx_7" + event on-backend-tcp-request + + ot-scope backend_http_request + extract "ot_ctx_8" use-vars + span "Backend HTTP request" follows-from "ot_ctx_8" + inject "ot_ctx_9" use-headers use-vars + finish "Backend TCP request" "ot_ctx_8" + event on-backend-http-request + + ot-scope process_server_rules_request + extract "ot_ctx_9" use-vars + span "Process server rules request" follows-from "ot_ctx_9" + inject "ot_ctx_10" use-headers use-vars + finish "Backend HTTP request" "ot_ctx_9" + event on-process-server-rules-request + + ot-scope http_process_request + extract "ot_ctx_10" use-vars + span "HTTP process request" follows-from "ot_ctx_10" + inject "ot_ctx_11" use-headers use-vars + finish "Process server rules request" "ot_ctx_10" + event on-http-process-request + + ot-scope tcp_rdp_cookie_request + extract "ot_ctx_11" use-vars + span "TCP RDP cookie request" follows-from "ot_ctx_11" + inject "ot_ctx_12" use-headers use-vars + finish "HTTP process request" "ot_ctx_11" + event on-tcp-rdp-cookie-request + + ot-scope process_sticking_rules_request + extract "ot_ctx_12" use-vars + span "Process sticking rules request" follows-from "ot_ctx_12" + inject "ot_ctx_13" use-headers use-vars + finish "TCP RDP cookie request" "ot_ctx_12" + event on-process-sticking-rules-request + + ot-scope client_session_end + finish "Client session" "ot_ctx_2" + event on-client-session-end + + ot-scope server_unavailable + finish * + event on-server-unavailable + + ot-scope server_session_start + span "Server session" child-of "ot_ctx_1" + inject "ot_ctx_14" use-vars + extract "ot_ctx_13" use-vars + finish "Process sticking rules request" "ot_ctx_13" + event on-server-session-start + + ot-scope tcp_response + extract "ot_ctx_14" use-vars + span "TCP response" child-of "ot_ctx_14" + inject "ot_ctx_15" use-vars + event on-tcp-response + + ot-scope http_wait_response + extract "ot_ctx_15" use-vars + span "HTTP wait response" follows-from "ot_ctx_15" + inject "ot_ctx_16" use-headers use-vars + finish "TCP response" "ot_ctx_15" + event on-http-wait-response + + ot-scope process_store_rules_response + extract "ot_ctx_16" use-vars + span "Process store rules response" follows-from "ot_ctx_16" + inject "ot_ctx_17" use-headers use-vars + finish "HTTP wait response" "ot_ctx_16" + event on-process-store-rules-response + + ot-scope http_response + extract "ot_ctx_17" use-vars + span "HTTP response" follows-from "ot_ctx_17" + tag "http.status_code" status + finish "Process store rules response" "ot_ctx_17" + event on-http-response + + ot-scope http_response-error + span "HTTP response" + tag "error" bool(true) + event on-http-response if !acl-http-status-ok + + ot-scope server_session_end + finish * + event on-server-session-end diff --git a/addons/ot/test/empty/cfg-dd.json b/addons/ot/test/empty/cfg-dd.json new file mode 100644 index 0000000..38b65f1 --- /dev/null +++ b/addons/ot/test/empty/cfg-dd.json @@ -0,0 +1,5 @@ +{ + "service": "EMPTY", + "agent_host": "localhost", + "agent_port": 8126 +} diff --git a/addons/ot/test/empty/cfg-jaeger.yml b/addons/ot/test/empty/cfg-jaeger.yml new file mode 100644 index 0000000..08fadd8 --- /dev/null +++ b/addons/ot/test/empty/cfg-jaeger.yml @@ -0,0 +1,34 @@ +service_name: + EMPTY + +### +# When using configuration object to instantiate the tracer, the type of +# sampling can be selected via sampler.type and sampler.param properties. +# Jaeger libraries support the following samplers: +# +# - Constant (sampler.type=const) sampler always makes the same decision for +# all traces. It either samples all traces (sampler.param=1) or none of +# them (sampler.param=0). +# +# - Probabilistic (sampler.type=probabilistic) sampler makes a random sampling +# decision with the probability of sampling equal to the value of +# sampler.param property. For example, with sampler.param=0.1 approximately +# 1 in 10 traces will be sampled. +# +# - Rate Limiting (sampler.type=ratelimiting) sampler uses a leaky bucket rate +# limiter to ensure that traces are sampled with a certain constant rate. +# For example, when sampler.param=2.0 it will sample requests with the rate +# of 2 traces per second. +# +# - Remote (sampler.type=remote, which is also the default) sampler consults +# Jaeger agent for the appropriate sampling strategy to use in the current +# service. This allows controlling the sampling strategies in the services +# from a central configuration in Jaeger backend, or even dynamically. +# +sampler: + type: ratelimiting + param: 10.0 + +reporter: + logSpans: true + localAgentHostPort: localhost:6831 diff --git a/addons/ot/test/empty/cfg-zipkin.json b/addons/ot/test/empty/cfg-zipkin.json new file mode 100644 index 0000000..55fde9f --- /dev/null +++ b/addons/ot/test/empty/cfg-zipkin.json @@ -0,0 +1,4 @@ +{ + "service_name": "EMPTY", + "collector_host": "localhost" +} diff --git a/addons/ot/test/empty/haproxy.cfg b/addons/ot/test/empty/haproxy.cfg new file mode 100644 index 0000000..9d40db9 --- /dev/null +++ b/addons/ot/test/empty/haproxy.cfg @@ -0,0 +1,30 @@ +global + stats socket /tmp/haproxy.sock mode 666 level admin + +defaults + log global + mode http + option httplog + option dontlognull + option httpclose + timeout connect 5000 + timeout client 50000 + timeout server 50000 + +listen stats + mode http + bind *:8001 + stats uri / + stats admin if TRUE + stats refresh 10s + +frontend ot-test-empty + bind *:10080 + mode http + default_backend servers-backend + + filter opentracing id ot-test-empty config empty/ot.cfg + +backend servers-backend + mode http + server server-1 127.0.0.1:8000 diff --git a/addons/ot/test/empty/ot.cfg b/addons/ot/test/empty/ot.cfg new file mode 100644 index 0000000..961c8bc --- /dev/null +++ b/addons/ot/test/empty/ot.cfg @@ -0,0 +1,3 @@ +ot-tracer ot-test-tracer + config empty/cfg-jaeger.yml + plugin libjaeger_opentracing_plugin-0.5.0.so diff --git a/addons/ot/test/fe/cfg-dd.json b/addons/ot/test/fe/cfg-dd.json new file mode 100644 index 0000000..84afe56 --- /dev/null +++ b/addons/ot/test/fe/cfg-dd.json @@ -0,0 +1,5 @@ +{ + "service": "FE", + "agent_host": "localhost", + "agent_port": 8126 +} diff --git a/addons/ot/test/fe/cfg-jaeger.yml b/addons/ot/test/fe/cfg-jaeger.yml new file mode 100644 index 0000000..1365efa --- /dev/null +++ b/addons/ot/test/fe/cfg-jaeger.yml @@ -0,0 +1,34 @@ +service_name: + FE + +### +# When using configuration object to instantiate the tracer, the type of +# sampling can be selected via sampler.type and sampler.param properties. +# Jaeger libraries support the following samplers: +# +# - Constant (sampler.type=const) sampler always makes the same decision for +# all traces. It either samples all traces (sampler.param=1) or none of +# them (sampler.param=0). +# +# - Probabilistic (sampler.type=probabilistic) sampler makes a random sampling +# decision with the probability of sampling equal to the value of +# sampler.param property. For example, with sampler.param=0.1 approximately +# 1 in 10 traces will be sampled. +# +# - Rate Limiting (sampler.type=ratelimiting) sampler uses a leaky bucket rate +# limiter to ensure that traces are sampled with a certain constant rate. +# For example, when sampler.param=2.0 it will sample requests with the rate +# of 2 traces per second. +# +# - Remote (sampler.type=remote, which is also the default) sampler consults +# Jaeger agent for the appropriate sampling strategy to use in the current +# service. This allows controlling the sampling strategies in the services +# from a central configuration in Jaeger backend, or even dynamically. +# +sampler: + type: ratelimiting + param: 10.0 + +reporter: + logSpans: true + localAgentHostPort: localhost:6831 diff --git a/addons/ot/test/fe/cfg-zipkin.json b/addons/ot/test/fe/cfg-zipkin.json new file mode 100644 index 0000000..1546b10 --- /dev/null +++ b/addons/ot/test/fe/cfg-zipkin.json @@ -0,0 +1,4 @@ +{ + "service_name": "FE", + "collector_host": "localhost" +} diff --git a/addons/ot/test/fe/haproxy.cfg b/addons/ot/test/fe/haproxy.cfg new file mode 100644 index 0000000..bfc0ec9 --- /dev/null +++ b/addons/ot/test/fe/haproxy.cfg @@ -0,0 +1,37 @@ +global +# nbthread 1 + maxconn 5000 + hard-stop-after 10s +# log localhost:514 local7 debug +# debug + stats socket /tmp/haproxy-fe.sock mode 666 level admin + +defaults + log global + mode http + option httplog + option dontlognull + option httpclose + retries 3 + maxconn 4000 + timeout connect 5000 + timeout client 50000 + timeout server 50000 + +listen stats + mode http + bind *:8001 + stats uri / + stats admin if TRUE + stats refresh 10s + +frontend ot-test-fe-frontend + bind *:10080 + mode http + default_backend servers-backend + + filter opentracing id ot-test-fe config fe/ot.cfg + +backend servers-backend + mode http + server server-1 127.0.0.1:11080 diff --git a/addons/ot/test/fe/ot.cfg b/addons/ot/test/fe/ot.cfg new file mode 100644 index 0000000..11de828 --- /dev/null +++ b/addons/ot/test/fe/ot.cfg @@ -0,0 +1,74 @@ +[ot-test-fe] + ot-tracer ot-test-tracer + config fe/cfg-jaeger.yml + plugin libjaeger_opentracing_plugin-0.5.0.so +# log localhost:514 local7 debug + option dontlog-normal + option hard-errors + no option disabled + rate-limit 100.0 + + scopes client_session_start + scopes frontend_tcp_request + scopes frontend_http_request + scopes backend_tcp_request + scopes backend_http_request + scopes client_session_end + + scopes server_session_start + scopes tcp_response + scopes http_response + scopes server_session_end + + ot-scope client_session_start + span "HAProxy session" root + baggage "haproxy_id" var(sess.ot.uuid) + span "Client session" child-of "HAProxy session" + event on-client-session-start + + ot-scope frontend_tcp_request + span "Frontend TCP request" child-of "Client session" + event on-frontend-tcp-request + + ot-scope frontend_http_request + span "Frontend HTTP request" follows-from "Frontend TCP request" + tag "http.method" method + tag "http.url" url + tag "http.version" str("HTTP/") req.ver + finish "Frontend TCP request" + event on-frontend-http-request + + ot-scope backend_tcp_request + span "Backend TCP request" follows-from "Frontend HTTP request" + finish "Frontend HTTP request" + event on-backend-tcp-request + + ot-scope backend_http_request + span "Backend HTTP request" follows-from "Backend TCP request" + finish "Backend TCP request" + span "HAProxy session" + inject "ot-ctx" use-headers + event on-backend-http-request + + ot-scope client_session_end + finish "Client session" + event on-client-session-end + + ot-scope server_session_start + span "Server session" child-of "HAProxy session" + finish "Backend HTTP request" + event on-server-session-start + + ot-scope tcp_response + span "TCP response" child-of "Server session" + event on-tcp-response + + ot-scope http_response + span "HTTP response" follows-from "TCP response" + tag "http.status_code" status + finish "TCP response" + event on-http-response + + ot-scope server_session_end + finish * + event on-server-session-end diff --git a/addons/ot/test/func-stat.sh b/addons/ot/test/func-stat.sh new file mode 100755 index 0000000..cf5bd9e --- /dev/null +++ b/addons/ot/test/func-stat.sh @@ -0,0 +1,5 @@ +#!/bin/sh +# +test ${#} -lt 1 && exit 1 + +awk '/ {$/ { sub(/\(.*/, "", $5); print $5 }' "${@}" | sort | uniq -c diff --git a/addons/ot/test/get-opentracing-plugins.sh b/addons/ot/test/get-opentracing-plugins.sh new file mode 100755 index 0000000..f2fe2d6 --- /dev/null +++ b/addons/ot/test/get-opentracing-plugins.sh @@ -0,0 +1,45 @@ +#!/bin/sh +# +_ARG_DIR="${1:-.}" + + +get () +{ + local _arg_tracer="${1}" + local _arg_version="${2}" + local _arg_url="${3}" + local _arg_file="${4}" + local _var_tmpfile="_tmpfile_" + local _var_plugin="lib${_arg_tracer}_opentracing_plugin-${_arg_version}.so" + + test -e "${_var_plugin}" && return 0 + + wget "https://github.com/${_arg_url}/releases/download/v${_arg_version}/${_arg_file}" -O "${_var_tmpfile}" || { + rm "${_var_tmpfile}" + return 1 + } + + case "$(file ${_var_tmpfile})" in + *shared\ object*) + mv "${_var_tmpfile}" "${_var_plugin}" ;; + + *gzip\ compressed\ data*) + gzip -cd "${_var_tmpfile}" > "${_var_plugin}" + rm "${_var_tmpfile}" ;; + esac +} + + +mkdir -p "${_ARG_DIR}" && cd "${_ARG_DIR}" || exit 1 + +get dd 1.1.2 DataDog/dd-opentracing-cpp linux-amd64-libdd_opentracing_plugin.so.gz +get dd 1.2.0 DataDog/dd-opentracing-cpp linux-amd64-libdd_opentracing_plugin.so.gz + +get jaeger 0.4.2 jaegertracing/jaeger-client-cpp libjaegertracing_plugin.linux_amd64.so +#et jaeger 0.5.0 jaegertracing/jaeger-client-cpp libjaegertracing_plugin.linux_amd64.so +#et jaeger 0.6.0 jaegertracing/jaeger-client-cpp libjaegertracing_plugin.linux_amd64.so + +get lightstep 0.12.0 lightstep/lightstep-tracer-cpp linux-amd64-liblightstep_tracer_plugin.so.gz +get lightstep 0.13.0 lightstep/lightstep-tracer-cpp linux-amd64-liblightstep_tracer_plugin.so.gz + +get zipkin 0.5.2 rnburn/zipkin-cpp-opentracing linux-amd64-libzipkin_opentracing_plugin.so.gz diff --git a/addons/ot/test/index.html b/addons/ot/test/index.html new file mode 100644 index 0000000..09ed6fa --- /dev/null +++ b/addons/ot/test/index.html @@ -0,0 +1 @@ +

Did I err?

diff --git a/addons/ot/test/run-cmp.sh b/addons/ot/test/run-cmp.sh new file mode 100755 index 0000000..8e678b7 --- /dev/null +++ b/addons/ot/test/run-cmp.sh @@ -0,0 +1,13 @@ +#!/bin/sh +# +_ARG_HAPROXY="${1:-$(realpath -L ${PWD}/../../../haproxy)}" + _ARGS="-f cmp/haproxy.cfg" + _LOG_DIR="_logs" + _LOG="${_LOG_DIR}/_log-$(basename "${0}" .sh)-$(date +%s)" + + +test -x "${_ARG_HAPROXY}" || exit 1 +mkdir -p "${_LOG_DIR}" || exit 2 + +echo "executing: ${_ARG_HAPROXY} ${_ARGS} > ${_LOG}" +"${_ARG_HAPROXY}" ${_ARGS} >"${_LOG}" 2>&1 diff --git a/addons/ot/test/run-ctx.sh b/addons/ot/test/run-ctx.sh new file mode 100755 index 0000000..bfac617 --- /dev/null +++ b/addons/ot/test/run-ctx.sh @@ -0,0 +1,13 @@ +#!/bin/sh +# +_ARG_HAPROXY="${1:-$(realpath -L ${PWD}/../../../haproxy)}" + _ARGS="-f ctx/haproxy.cfg" + _LOG_DIR="_logs" + _LOG="${_LOG_DIR}/_log-$(basename "${0}" .sh)-$(date +%s)" + + +test -x "${_ARG_HAPROXY}" || exit 1 +mkdir -p "${_LOG_DIR}" || exit 2 + +echo "executing: ${_ARG_HAPROXY} ${_ARGS} > ${_LOG}" +"${_ARG_HAPROXY}" ${_ARGS} >"${_LOG}" 2>&1 diff --git a/addons/ot/test/run-fe-be.sh b/addons/ot/test/run-fe-be.sh new file mode 100755 index 0000000..68b250c --- /dev/null +++ b/addons/ot/test/run-fe-be.sh @@ -0,0 +1,47 @@ +#!/bin/sh +# +_ARG_HAPROXY="${1:-$(realpath -L ${PWD}/../../../haproxy)}" + _ARGS_FE="-f fe/haproxy.cfg" + _ARGS_BE="-f be/haproxy.cfg" + _TIME="$(date +%s)" + _LOG_DIR="_logs" + _LOG_FE="${_LOG_DIR}/_log-$(basename "${0}" fe-be.sh)fe-${_TIME}" + _LOG_BE="${_LOG_DIR}/_log-$(basename "${0}" fe-be.sh)be-${_TIME}" + + +__exit () +{ + test -z "${2}" && { + echo + echo "Script killed!" + + echo "Waiting for jobs to complete..." + pkill --signal SIGUSR1 haproxy + wait + } + + test -n "${1}" && { + echo + echo "${1}" + echo + } + + exit ${2:-100} +} + + +trap __exit INT TERM + +test -x "${_ARG_HAPROXY}" || __exit "${_ARG_HAPROXY}: executable does not exist" 1 +mkdir -p "${_LOG_DIR}" || __exit "${_ARG_HAPROXY}: cannot create log directory" 2 + +echo "\n------------------------------------------------------------------------" +echo "--- executing: ${_ARG_HAPROXY} ${_ARGS_BE} > ${_LOG_BE}" +"${_ARG_HAPROXY}" ${_ARGS_BE} >"${_LOG_BE}" 2>&1 & + +echo "--- executing: ${_ARG_HAPROXY} ${_ARGS_FE} > ${_LOG_FE}" +"${_ARG_HAPROXY}" ${_ARGS_FE} >"${_LOG_FE}" 2>&1 & +echo "------------------------------------------------------------------------\n" + +echo "Press CTRL-C to quit..." +wait diff --git a/addons/ot/test/run-sa.sh b/addons/ot/test/run-sa.sh new file mode 100755 index 0000000..04a303a --- /dev/null +++ b/addons/ot/test/run-sa.sh @@ -0,0 +1,13 @@ +#!/bin/sh +# +_ARG_HAPROXY="${1:-$(realpath -L ${PWD}/../../../haproxy)}" + _ARGS="-f sa/haproxy.cfg" + _LOG_DIR="_logs" + _LOG="${_LOG_DIR}/_log-$(basename "${0}" .sh)-$(date +%s)" + + +test -x "${_ARG_HAPROXY}" || exit 1 +mkdir -p "${_LOG_DIR}" || exit 2 + +echo "executing: ${_ARG_HAPROXY} ${_ARGS} > ${_LOG}" +"${_ARG_HAPROXY}" ${_ARGS} >"${_LOG}" 2>&1 diff --git a/addons/ot/test/sa/cfg-dd.json b/addons/ot/test/sa/cfg-dd.json new file mode 100644 index 0000000..0c476f7 --- /dev/null +++ b/addons/ot/test/sa/cfg-dd.json @@ -0,0 +1,5 @@ +{ + "service": "SA", + "agent_host": "localhost", + "agent_port": 8126 +} diff --git a/addons/ot/test/sa/cfg-jaeger.yml b/addons/ot/test/sa/cfg-jaeger.yml new file mode 100644 index 0000000..e14f91e --- /dev/null +++ b/addons/ot/test/sa/cfg-jaeger.yml @@ -0,0 +1,34 @@ +service_name: + SA + +### +# When using configuration object to instantiate the tracer, the type of +# sampling can be selected via sampler.type and sampler.param properties. +# Jaeger libraries support the following samplers: +# +# - Constant (sampler.type=const) sampler always makes the same decision for +# all traces. It either samples all traces (sampler.param=1) or none of +# them (sampler.param=0). +# +# - Probabilistic (sampler.type=probabilistic) sampler makes a random sampling +# decision with the probability of sampling equal to the value of +# sampler.param property. For example, with sampler.param=0.1 approximately +# 1 in 10 traces will be sampled. +# +# - Rate Limiting (sampler.type=ratelimiting) sampler uses a leaky bucket rate +# limiter to ensure that traces are sampled with a certain constant rate. +# For example, when sampler.param=2.0 it will sample requests with the rate +# of 2 traces per second. +# +# - Remote (sampler.type=remote, which is also the default) sampler consults +# Jaeger agent for the appropriate sampling strategy to use in the current +# service. This allows controlling the sampling strategies in the services +# from a central configuration in Jaeger backend, or even dynamically. +# +sampler: + type: ratelimiting + param: 10.0 + +reporter: + logSpans: true + localAgentHostPort: localhost:6831 diff --git a/addons/ot/test/sa/cfg-zipkin.json b/addons/ot/test/sa/cfg-zipkin.json new file mode 100644 index 0000000..9d155ba --- /dev/null +++ b/addons/ot/test/sa/cfg-zipkin.json @@ -0,0 +1,4 @@ +{ + "service_name": "SA", + "collector_host": "localhost" +} diff --git a/addons/ot/test/sa/haproxy.cfg b/addons/ot/test/sa/haproxy.cfg new file mode 100644 index 0000000..988e3ab --- /dev/null +++ b/addons/ot/test/sa/haproxy.cfg @@ -0,0 +1,40 @@ +global +# nbthread 1 + maxconn 5000 + hard-stop-after 10s +# log localhost:514 local7 debug +# debug + stats socket /tmp/haproxy.sock mode 666 level admin + +defaults + log global + mode http + option httplog + option dontlognull + option httpclose + retries 3 + maxconn 4000 + timeout connect 5000 + timeout client 50000 + timeout server 50000 + +listen stats + mode http + bind *:8001 + stats uri / + stats admin if TRUE + stats refresh 10s + +frontend ot-test-sa-frontend + bind *:10080 + mode http + default_backend servers-backend + + acl acl-http-status-ok status 100:399 + filter opentracing id ot-test-sa config sa/ot.cfg + http-response ot-group ot-test-sa http_response_group if acl-http-status-ok + http-after-response ot-group ot-test-sa http_after_response_group if !acl-http-status-ok + +backend servers-backend + mode http + server server-1 127.0.0.1:8000 diff --git a/addons/ot/test/sa/ot.cfg b/addons/ot/test/sa/ot.cfg new file mode 100644 index 0000000..ae7413b --- /dev/null +++ b/addons/ot/test/sa/ot.cfg @@ -0,0 +1,160 @@ +[ot-test-sa] + ot-tracer ot-test-tracer + log localhost:514 local7 debug + config sa/cfg-jaeger.yml + plugin libjaeger_opentracing_plugin-0.5.0.so + option dontlog-normal + option hard-errors + no option disabled + rate-limit 100.0 + + groups http_response_group + groups http_after_response_group + + scopes client_session_start + scopes frontend_tcp_request + scopes http_wait_request + scopes http_body_request + scopes frontend_http_request + scopes switching_rules_request + scopes backend_tcp_request + scopes backend_http_request + scopes process_server_rules_request + scopes http_process_request + scopes tcp_rdp_cookie_request + scopes process_sticking_rules_request + scopes client_session_end + scopes server_unavailable + + scopes server_session_start + scopes tcp_response + scopes http_wait_response + scopes process_store_rules_response + scopes http_response http_response-error + scopes server_session_end + + ot-group http_response_group + scopes http_response_1 + scopes http_response_2 + + ot-scope http_response_1 + span "HTTP response" + log "hdr.content" res.hdr("content-type") str("; length: ") res.hdr("content-length") str(" bytes") + + ot-scope http_response_2 + span "HTTP response" + log "hdr.date" res.hdr("date") str(" / ") res.hdr("last-modified") + + ot-group http_after_response_group + scopes http_after_response + + ot-scope http_after_response + span "HAProxy response" child-of "HAProxy session" + tag "error" bool(true) + tag "http.status_code" status + + ot-scope client_session_start + span "HAProxy session" root + baggage "haproxy_id" var(sess.ot.uuid) + span "Client session" child-of "HAProxy session" + acl acl-test-src-ip src 127.0.0.1 + event on-client-session-start if acl-test-src-ip + + ot-scope frontend_tcp_request + span "Frontend TCP request" child-of "Client session" + event on-frontend-tcp-request + + ot-scope http_wait_request + span "HTTP wait request" follows-from "Frontend TCP request" + finish "Frontend TCP request" + event on-http-wait-request + + ot-scope http_body_request + span "HTTP body request" follows-from "HTTP wait request" + finish "HTTP wait request" + event on-http-body-request + + ot-scope frontend_http_request + span "Frontend HTTP request" follows-from "HTTP body request" + tag "http.method" method + tag "http.url" url + tag "http.version" str("HTTP/") req.ver + finish "HTTP body request" + event on-frontend-http-request + + ot-scope switching_rules_request + span "Switching rules request" follows-from "Frontend HTTP request" + finish "Frontend HTTP request" + event on-switching-rules-request + + ot-scope backend_tcp_request + span "Backend TCP request" follows-from "Switching rules request" + finish "Switching rules request" + event on-backend-tcp-request + + ot-scope backend_http_request + span "Backend HTTP request" follows-from "Backend TCP request" + finish "Backend TCP request" + event on-backend-http-request + + ot-scope process_server_rules_request + span "Process server rules request" follows-from "Backend HTTP request" + finish "Backend HTTP request" + event on-process-server-rules-request + + ot-scope http_process_request + span "HTTP process request" follows-from "Process server rules request" + finish "Process server rules request" + event on-http-process-request + + ot-scope tcp_rdp_cookie_request + span "TCP RDP cookie request" follows-from "HTTP process request" + finish "HTTP process request" + event on-tcp-rdp-cookie-request + + ot-scope process_sticking_rules_request + span "Process sticking rules request" follows-from "TCP RDP cookie request" + finish "TCP RDP cookie request" + event on-process-sticking-rules-request + + ot-scope client_session_end + finish "Client session" + event on-client-session-end + + ot-scope server_unavailable + finish * + event on-server-unavailable + + ot-scope server_session_start + span "Server session" child-of "HAProxy session" + finish "Process sticking rules request" + event on-server-session-start + + ot-scope tcp_response + span "TCP response" child-of "Server session" + event on-tcp-response + + ot-scope http_wait_response + span "HTTP wait response" follows-from "TCP response" + finish "TCP response" + event on-http-wait-response + + ot-scope process_store_rules_response + span "Process store rules response" follows-from "HTTP wait response" + finish "HTTP wait response" + event on-process-store-rules-response + + ot-scope http_response + span "HTTP response" follows-from "Process store rules response" + tag "http.status_code" status + finish "Process store rules response" + event on-http-response + + ot-scope http_response-error + span "HTTP response" + tag "error" bool(true) + event on-http-response if !acl-http-status-ok + + ot-scope server_session_end + finish * + event on-server-session-end diff --git a/addons/ot/test/test-speed.sh b/addons/ot/test/test-speed.sh new file mode 100755 index 0000000..f2ac514 --- /dev/null +++ b/addons/ot/test/test-speed.sh @@ -0,0 +1,117 @@ +#!/bin/sh +# + _ARG_CFG="${1}" + _ARG_DIR="${2:-${1}}" + _LOG_DIR="_logs" +_HTTPD_PIDFILE="${_LOG_DIR}/thttpd.pid" + _USAGE_MSG="usage: $(basename "${0}") cfg [dir]" + + +sh_exit () +{ + test -z "${2}" && { + echo + echo "Script killed!" + } + + test -n "${1}" && { + echo + echo "${1}" + echo + } + + exit ${2:-64} +} + +httpd_run () +{ + + test -e "${_HTTPD_PIDFILE}" && return + + thttpd -p 8000 -d . -nos -nov -l /dev/null -i "${_HTTPD_PIDFILE}" +} + +httpd_stop () +{ + test -e "${_HTTPD_PIDFILE}" || return + + kill -TERM "$(cat ${_HTTPD_PIDFILE})" + rm "${_HTTPD_PIDFILE}" +} + +haproxy_run () +{ + _arg_ratio="${1}" + _var_sed_ot= + _var_sed_haproxy= + + if test "${_arg_ratio}" = "disabled"; then + _var_sed_ot="s/no \(option disabled\)/\1/" + elif test "${_arg_ratio}" = "off"; then + _var_sed_haproxy="s/^\(.* filter opentracing .*\)/#\1/g; s/^\(.* ot-group .*\)/#\1/g" + else + _var_sed_ot="s/\(rate-limit\) 100.0/\1 ${_arg_ratio}/" + fi + + sed "${_var_sed_haproxy}" "${_ARG_DIR}/haproxy.cfg.in" > "${_ARG_DIR}/haproxy.cfg" + sed "${_var_sed_ot}" "${_ARG_DIR}/ot.cfg.in" > "${_ARG_DIR}/ot.cfg" + + if test "${_ARG_DIR}" = "fe"; then + if test "${_arg_ratio}" = "disabled" -o "${_arg_ratio}" = "off"; then + sed "${_var_sed_haproxy}" "be/haproxy.cfg.in" > "be/haproxy.cfg" + sed "${_var_sed_ot}" "be/ot.cfg.in" > "be/ot.cfg" + fi + fi + + ./run-${_ARG_CFG}.sh & + sleep 5 +} + +wrk_run () +{ + _arg_ratio="${1}" + + echo "--- rate-limit ${_arg_ratio} --------------------------------------------------" + wrk -c8 -d300 -t8 --latency http://localhost:10080/index.html + echo "----------------------------------------------------------------------" + echo + + sleep 10 +} + + +command -v thttpd >/dev/null 2>&1 || sh_exit "thttpd: command not found" 5 +command -v wrk >/dev/null 2>&1 || sh_exit "wrk: command not found" 6 + +mkdir -p "${_LOG_DIR}" || sh_exit "${_LOG_DIR}: Cannot create log directory" 1 + +if test "${_ARG_CFG}" = "all"; then + "${0}" fe-be fe > "${_LOG_DIR}/README-speed-fe-be" + "${0}" sa sa > "${_LOG_DIR}/README-speed-sa" + "${0}" cmp cmp > "${_LOG_DIR}/README-speed-cmp" + "${0}" ctx ctx > "${_LOG_DIR}/README-speed-ctx" + exit 0 +fi + +test -z "${_ARG_CFG}" -o -z "${_ARG_DIR}" && sh_exit "${_USAGE_MSG}" 4 +test -f "run-${_ARG_CFG}.sh" || sh_exit "run-${_ARG_CFG}.sh: No such configuration script" 2 +test -d "${_ARG_DIR}" || sh_exit "${_ARG_DIR}: No such directory" 3 + +test -e "${_ARG_DIR}/haproxy.cfg.in" || cp -af "${_ARG_DIR}/haproxy.cfg" "${_ARG_DIR}/haproxy.cfg.in" +test -e "${_ARG_DIR}/ot.cfg.in" || cp -af "${_ARG_DIR}/ot.cfg" "${_ARG_DIR}/ot.cfg.in" +if test "${_ARG_DIR}" = "fe"; then + test -e "be/haproxy.cfg.in" || cp -af "be/haproxy.cfg" "be/haproxy.cfg.in" + test -e "be/ot.cfg.in" || cp -af "be/ot.cfg" "be/ot.cfg.in" +fi + +httpd_run + +for _var_ratio in 100.0 50.0 10.0 2.5 0.0 disabled off; do + haproxy_run "${_var_ratio}" + wrk_run "${_var_ratio}" + + pkill --signal SIGUSR1 haproxy + wait +done + +httpd_stop diff --git a/addons/promex/README b/addons/promex/README new file mode 100644 index 0000000..4e29e23 --- /dev/null +++ b/addons/promex/README @@ -0,0 +1,356 @@ +PROMEX: A Prometheus exporter for HAProxy +------------------------------------------- + +Prometheus is a monitoring and alerting system. More and more people use it to +monitor their environment (this is written February 2019). It collects metrics +from monitored targets by scraping metrics HTTP endpoints on these targets. For +HAProxy, The Prometheus team officially supports an exporter written in Go +(https://github.com/prometheus/haproxy_exporter). But it requires an extra +software to deploy and monitor. PROMEX, on its side, is a built-in Prometheus +exporter for HAProxy. It was developed as a service and is directly available in +HAProxy, like the stats applet. + +However, PROMEX is not built by default with HAProxy. It is provided as an extra +component for everyone want to use it. So you need to explicitly build HAProxy +with the PROMEX service, setting the Makefile variable "USE_PROMEX" to "1". For +instance: + + > make TARGET=linux-glibc USE_PROMEX=1 + +if HAProxy provides the PROMEX service, the following build option will be +reported by the command "haproxy -vv": + + Built with the Prometheus exporter as a service + +To be used, it must be enabled in the configuration with an "http-request" rule +and the corresponding HTTP proxy must enable the HTX support. For instance: + + frontend test + mode http + ... + http-request use-service prometheus-exporter if { path /metrics } + ... + + +This service has been developed as a third-party component because it could +become obsolete, depending on how much time Prometheus will remain heavily +used. This is said with no ulterior motive of course. Prometheus is a great +software and I hope all the well for it. But we involve in a environment moving +quickly and a solution may be obvious today could be deprecated the next +year. And because PROMEX is not integrated by default into the HAProxy codebase, +it will need some interest to be actively supported. All contribution of any +kind are welcome. + +You must also be careful if you use with huge configurations. Unlike the stats +applet, all metrics are not grouped by service (proxy, listener or server). With +PROMEX, all lines for a given metric are provided as one single group. So +instead of collecting all metrics for a proxy before moving to the next one, we +must loop on all proxies for each metric. Same for the servers. Thus, it will +spend much more resources to produce the Prometheus metrics than the CSV export +through the stats page. To give a comparison order, quick benchmarks shown that +a PROMEX dump is 5x slower and 20x more verbose than a CSV export. + + +metrics filtering +------------------- + +It is possible to dynamically select the metrics to export if you don't use all +of them passing parameters in the query-string. + +* Filtering on scopes + +The metrics may be filtered by scopes. Multiple parameters with "scope" as name +may be passed in the query-string to filter exported metrics, with one of those +values: global, frontend, backend, server or '*' (means all). A scope parameter +with no value means to filter out all scopes (nothing is returned). The scope +parameters are parsed in their appearance order in the query-string. So an empty +scope will reset all scopes already parsed. But it can be overridden by +following scope parameters in the query-string. By default everything is +exported. Here are examples: + + /metrics?scope=server # ==> server metrics will be exported + /metrics?scope=frontend&scope=backend # ==> Frontend and backend metrics will be exported + /metrics?scope=listener # ==> listener metrics will be exported + /metrics?scope=*&scope= # ==> no metrics will be exported + /metrics?scope=&scope=global # ==> global metrics will be exported + /metrics?scope=sticktable # ==> stick tables metrics will be exported + +* How do I prevent my prometheus instance to explode? + +** Filtering on servers state + +It is possible to exclude from returned metrics all servers in maintenance mode +passing the parameter "no-maint" in the query-string. This parameter may help to +solve performance issues of configuration that use the server templates to +manage dynamic provisionning. Note there is no consistency check on the servers +state. So, if the state of a server changes while the exporter is running, only +a part of the metrics for this server will be dumped. + +prometheus example config: + +For server-template users: +- + params: + no-maint: + - empty + +** Scrap server health checks only + +All health checks status are dump through `state` label values. If you want to +scrap server health check status but prevent all server metrics to be saved, +except the server_check_status, you may configure prometheus that way: + +- + metric_relabel_configs: + - source_labels: ['__name__'] + regex: 'haproxy_(process_|frontend_|listener_|backend_|server_check_status).*' + action: keep + +Exported metrics +------------------ + +See prometheus export for the description of each field. + +* Globals metrics + ++------------------------------------------------+ +| Metric name | ++------------------------------------------------+ +| haproxy_process_nbthread | +| haproxy_process_nbproc | +| haproxy_process_relative_process_id | +| haproxy_process_uptime_seconds | +| haproxy_process_pool_failures_total | +| haproxy_process_max_fds | +| haproxy_process_max_sockets | +| haproxy_process_max_connections | +| haproxy_process_hard_max_connections | +| haproxy_process_current_connections | +| haproxy_process_connections_total | +| haproxy_process_requests_total | +| haproxy_process_max_ssl_connections | +| haproxy_process_current_ssl_connections | +| haproxy_process_ssl_connections_total | +| haproxy_process_max_pipes | +| haproxy_process_pipes_used_total | +| haproxy_process_pipes_free_total | +| haproxy_process_current_connection_rate | +| haproxy_process_limit_connection_rate | +| haproxy_process_max_connection_rate | +| haproxy_process_current_session_rate | +| haproxy_process_limit_session_rate | +| haproxy_process_max_session_rate | +| haproxy_process_current_ssl_rate | +| haproxy_process_limit_ssl_rate | +| haproxy_process_max_ssl_rate | +| haproxy_process_current_frontend_ssl_key_rate | +| haproxy_process_max_frontend_ssl_key_rate | +| haproxy_process_frontend_ssl_reuse | +| haproxy_process_current_backend_ssl_key_rate | +| haproxy_process_max_backend_ssl_key_rate | +| haproxy_process_ssl_cache_lookups_total | +| haproxy_process_ssl_cache_misses_total | +| haproxy_process_http_comp_bytes_in_total | +| haproxy_process_http_comp_bytes_out_total | +| haproxy_process_limit_http_comp | +| haproxy_process_current_zlib_memory | +| haproxy_process_max_zlib_memory | +| haproxy_process_current_tasks | +| haproxy_process_current_run_queue | +| haproxy_process_idle_time_percent | +| haproxy_process_stopping | +| haproxy_process_jobs | +| haproxy_process_unstoppable_jobs | +| haproxy_process_listeners | +| haproxy_process_active_peers | +| haproxy_process_connected_peers | +| haproxy_process_dropped_logs_total | +| haproxy_process_busy_polling_enabled | +| haproxy_process_failed_resolutions | +| haproxy_process_bytes_out_total | +| haproxy_process_spliced_bytes_out_total | +| haproxy_process_bytes_out_rate | +| haproxy_process_recv_logs_total | +| haproxy_process_build_info | +| haproxy_process_max_memory_bytes | +| haproxy_process_pool_allocated_bytes | +| haproxy_process_pool_used_bytes | +| haproxy_process_start_time_seconds | ++------------------------------------------------+ + +* Frontend metrics + ++-------------------------------------------------+ +| Metric name | ++-------------------------------------------------+ +| haproxy_frontend_current_sessions | +| haproxy_frontend_max_sessions | +| haproxy_frontend_limit_sessions | +| haproxy_frontend_sessions_total | +| haproxy_frontend_bytes_in_total | +| haproxy_frontend_bytes_out_total | +| haproxy_frontend_requests_denied_total | +| haproxy_frontend_responses_denied_total | +| haproxy_frontend_request_errors_total | +| haproxy_frontend_status | +| haproxy_frontend_limit_session_rate | +| haproxy_frontend_max_session_rate | +| haproxy_frontend_http_responses_total | +| haproxy_frontend_http_requests_rate_max | +| haproxy_frontend_http_requests_total | +| haproxy_frontend_http_comp_bytes_in_total | +| haproxy_frontend_http_comp_bytes_out_total | +| haproxy_frontend_http_comp_bytes_bypassed_total | +| haproxy_frontend_http_comp_responses_total | +| haproxy_frontend_connections_rate_max | +| haproxy_frontend_connections_total | +| haproxy_frontend_intercepted_requests_total | +| haproxy_frontend_denied_connections_total | +| haproxy_frontend_denied_sessions_total | +| haproxy_frontend_failed_header_rewriting_total | +| haproxy_frontend_http_cache_lookups_total | +| haproxy_frontend_http_cache_hits_total | +| haproxy_frontend_internal_errors_total | ++-------------------------------------------------+ + +* Listener metrics + ++-------------------------------------------------+ +| Metric name | ++-------------------------------------------------+ +| haproxy_listener_current_sessions | +| haproxy_listener_max_sessions | +| haproxy_listener_limit_sessions | +| haproxy_listener_sessions_total | +| haproxy_listener_bytes_in_total | +| haproxy_listener_bytes_out_total | +| haproxy_listener_requests_denied_total | +| haproxy_listener_responses_denied_total | +| haproxy_listener_request_errors_total | +| haproxy_listener_status | +| haproxy_listener_denied_connections_total | +| haproxy_listener_denied_sessions_total | +| haproxy_listener_failed_header_rewriting_total | +| haproxy_listener_internal_errors_total | ++-------------------------------------------------+ + +* Backend metrics + ++-----------------------------------------------------+ +| Metric name | ++-----------------------------------------------------+ +| haproxy_backend_current_queue | +| haproxy_backend_max_queue | +| haproxy_backend_current_sessions | +| haproxy_backend_max_sessions | +| haproxy_backend_limit_sessions | +| haproxy_backend_sessions_total | +| haproxy_backend_bytes_in_total | +| haproxy_backend_bytes_out_total | +| haproxy_backend_requests_denied_total | +| haproxy_backend_responses_denied_total | +| haproxy_backend_connection_errors_total | +| haproxy_backend_response_errors_total | +| haproxy_backend_retry_warnings_total | +| haproxy_backend_redispatch_warnings_total | +| haproxy_backend_status | +| haproxy_backend_weight | +| haproxy_backend_active_servers | +| haproxy_backend_backup_servers | +| haproxy_backend_check_up_down_total | +| haproxy_backend_check_last_change_seconds | +| haproxy_backend_downtime_seconds_total | +| haproxy_backend_loadbalanced_total | +| haproxy_backend_max_session_rate | +| haproxy_backend_http_responses_total | +| haproxy_backend_http_requests_total | +| haproxy_backend_client_aborts_total | +| haproxy_backend_server_aborts_total | +| haproxy_backend_http_comp_bytes_in_total | +| haproxy_backend_http_comp_bytes_out_total | +| haproxy_backend_http_comp_bytes_bypassed_total | +| haproxy_backend_http_comp_responses_total | +| haproxy_backend_last_session_seconds | +| haproxy_backend_queue_time_average_seconds | +| haproxy_backend_connect_time_average_seconds | +| haproxy_backend_response_time_average_seconds | +| haproxy_backend_total_time_average_seconds | +| haproxy_backend_failed_header_rewriting_total | +| haproxy_backend_connection_attempts_total | +| haproxy_backend_connection_reuses_total | +| haproxy_backend_http_cache_lookups_total | +| haproxy_backend_http_cache_hits_total | +| haproxy_backend_max_queue_time_seconds | +| haproxy_backend_max_connect_time_seconds | +| haproxy_backend_max_response_time_seconds | +| haproxy_backend_max_total_time_seconds | +| haproxy_backend_internal_errors_total | +| haproxy_backend_uweight | +| haproxy_backend_agg_server_status | +| haproxy_backend_agg_check_status | ++-----------------------------------------------------+ + +* Server metrics + ++----------------------------------------------------+ +| Metric name | ++----------------------------------------------------+ +| haproxy_server_current_queue | +| haproxy_server_max_queue | +| haproxy_server_current_sessions | +| haproxy_server_max_sessions | +| haproxy_server_limit_sessions | +| haproxy_server_sessions_total | +| haproxy_server_bytes_in_total | +| haproxy_server_bytes_out_total | +| haproxy_server_responses_denied_total | +| haproxy_server_connection_errors_total | +| haproxy_server_response_errors_total | +| haproxy_server_retry_warnings_total | +| haproxy_server_redispatch_warnings_total | +| haproxy_server_status | +| haproxy_server_weight | +| haproxy_server_check_failures_total | +| haproxy_server_check_up_down_total | +| haproxy_server_check_last_change_seconds | +| haproxy_server_downtime_seconds_total | +| haproxy_server_queue_limit | +| haproxy_server_current_throttle | +| haproxy_server_loadbalanced_total | +| haproxy_server_max_session_rate | +| haproxy_server_check_status | +| haproxy_server_check_code | +| haproxy_server_check_duration_seconds | +| haproxy_server_http_responses_total | +| haproxy_server_client_aborts_total | +| haproxy_server_server_aborts_total | +| haproxy_server_last_session_seconds | +| haproxy_server_queue_time_average_seconds | +| haproxy_server_connect_time_average_seconds | +| haproxy_server_response_time_average_seconds | +| haproxy_server_total_time_average_seconds | +| haproxy_server_failed_header_rewriting_total | +| haproxy_server_connection_attempts_total | +| haproxy_server_connection_reuses_total | +| haproxy_server_idle_connections_current | +| haproxy_server_idle_connections_limit | +| haproxy_server_max_queue_time_seconds | +| haproxy_server_max_connect_time_seconds | +| haproxy_server_max_response_time_seconds | +| haproxy_server_max_total_time_seconds | +| haproxy_server_internal_errors_total | +| haproxy_server_unsafe_idle_connections_current | +| haproxy_server_safe_idle_connections_current | +| haproxy_server_used_connections_current | +| haproxy_server_need_connections_current | +| haproxy_server_uweight | ++----------------------------------------------------+ + +* Stick table metrics + ++----------------------------------------------------+ +| Metric name | ++----------------------------------------------------+ +| haproxy_sticktable_size | +| haproxy_sticktable_used | ++----------------------------------------------------+ diff --git a/addons/promex/service-prometheus.c b/addons/promex/service-prometheus.c new file mode 100644 index 0000000..e3a6475 --- /dev/null +++ b/addons/promex/service-prometheus.c @@ -0,0 +1,1659 @@ +/* + * Promex is a Prometheus exporter for HAProxy + * + * It is highly inspired by the official Prometheus exporter. + * See: https://github.com/prometheus/haproxy_exporter + * + * Copyright 2019 Christopher Faulet + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Prometheus exporter applet states (appctx->st0) */ +enum { + PROMEX_ST_INIT = 0, /* initialized */ + PROMEX_ST_HEAD, /* send headers before dump */ + PROMEX_ST_DUMP, /* dumping stats */ + PROMEX_ST_DONE, /* finished */ + PROMEX_ST_END, /* treatment terminated */ +}; + +/* Prometheus exporter dumper states (appctx->st1) */ +enum { + PROMEX_DUMPER_INIT = 0, /* initialized */ + PROMEX_DUMPER_GLOBAL, /* dump metrics of globals */ + PROMEX_DUMPER_FRONT, /* dump metrics of frontend proxies */ + PROMEX_DUMPER_BACK, /* dump metrics of backend proxies */ + PROMEX_DUMPER_LI, /* dump metrics of listeners */ + PROMEX_DUMPER_SRV, /* dump metrics of servers */ + PROMEX_DUMPER_STICKTABLE, /* dump metrics of stick tables */ + PROMEX_DUMPER_DONE, /* finished */ +}; + +/* Prometheus exporter flags (ctx->flags) */ +#define PROMEX_FL_METRIC_HDR 0x00000001 +#define PROMEX_FL_INFO_METRIC 0x00000002 +#define PROMEX_FL_FRONT_METRIC 0x00000004 +#define PROMEX_FL_BACK_METRIC 0x00000008 +#define PROMEX_FL_SRV_METRIC 0x00000010 +#define PROMEX_FL_LI_METRIC 0x00000020 +#define PROMEX_FL_STICKTABLE_METRIC 0x00000040 +#define PROMEX_FL_SCOPE_GLOBAL 0x00000080 +#define PROMEX_FL_SCOPE_FRONT 0x00000100 +#define PROMEX_FL_SCOPE_BACK 0x00000200 +#define PROMEX_FL_SCOPE_SERVER 0x00000400 +#define PROMEX_FL_SCOPE_LI 0x00000800 +#define PROMEX_FL_SCOPE_STICKTABLE 0x00001000 +#define PROMEX_FL_NO_MAINT_SRV 0x00002000 + +#define PROMEX_FL_SCOPE_ALL (PROMEX_FL_SCOPE_GLOBAL | PROMEX_FL_SCOPE_FRONT | \ + PROMEX_FL_SCOPE_LI | PROMEX_FL_SCOPE_BACK | \ + PROMEX_FL_SCOPE_SERVER | PROMEX_FL_SCOPE_STICKTABLE) + +/* the context of the applet */ +struct promex_ctx { + struct proxy *px; /* current proxy */ + struct stktable *st; /* current table */ + struct listener *li; /* current listener */ + struct server *sv; /* current server */ + unsigned int flags; /* PROMEX_FL_* */ + unsigned field_num; /* current field number (ST_F_* etc) */ + int obj_state; /* current state among PROMEX_{FRONT|BACK|SRV|LI}_STATE_* */ +}; + +/* Promtheus metric type (gauge or counter) */ +enum promex_mt_type { + PROMEX_MT_GAUGE = 1, + PROMEX_MT_COUNTER = 2, +}; + +/* The max length for metrics name. It is a hard limit but it should be + * enough. + */ +#define PROMEX_MAX_NAME_LEN 128 + +/* The expected max length for a metric dump, including its header lines. It is + * just a soft limit to avoid extra work. We don't try to dump a metric if less + * than this size is available in the HTX. + */ +#define PROMEX_MAX_METRIC_LENGTH 512 + +/* The max number of labels per metric */ +#define PROMEX_MAX_LABELS 8 + +/* Describe a prometheus metric */ +struct promex_metric { + const struct ist n; /* The metric name */ + enum promex_mt_type type; /* The metric type (gauge or counter) */ + unsigned int flags; /* PROMEX_FL_* flags */ +}; + +/* Describe a prometheus metric label. It is just a key/value pair */ +struct promex_label { + struct ist name; + struct ist value; +}; + +/* Global metrics */ +const struct promex_metric promex_global_metrics[INF_TOTAL_FIELDS] = { + //[INF_NAME] ignored + //[INF_VERSION], ignored + //[INF_RELEASE_DATE] ignored + [INF_NBTHREAD] = { .n = IST("nbthread"), .type = PROMEX_MT_GAUGE, .flags = PROMEX_FL_INFO_METRIC }, + [INF_NBPROC] = { .n = IST("nbproc"), .type = PROMEX_MT_GAUGE, .flags = PROMEX_FL_INFO_METRIC }, + [INF_PROCESS_NUM] = { .n = IST("relative_process_id"), .type = PROMEX_MT_GAUGE, .flags = PROMEX_FL_INFO_METRIC }, + //[INF_PID] ignored + //[INF_UPTIME] ignored + [INF_UPTIME_SEC] = { .n = IST("uptime_seconds"), .type = PROMEX_MT_GAUGE, .flags = PROMEX_FL_INFO_METRIC }, + [INF_START_TIME_SEC] = { .n = IST("start_time_seconds"), .type = PROMEX_MT_GAUGE, .flags = PROMEX_FL_INFO_METRIC }, + //[INF_MEMMAX_MB] ignored + [INF_MEMMAX_BYTES] = { .n = IST("max_memory_bytes"), .type = PROMEX_MT_GAUGE, .flags = PROMEX_FL_INFO_METRIC }, + //[INF_POOL_ALLOC_MB] ignored + [INF_POOL_ALLOC_BYTES] = { .n = IST("pool_allocated_bytes"), .type = PROMEX_MT_GAUGE, .flags = PROMEX_FL_INFO_METRIC }, + //[INF_POOL_USED_MB] ignored + [INF_POOL_USED_BYTES] = { .n = IST("pool_used_bytes"), .type = PROMEX_MT_GAUGE, .flags = PROMEX_FL_INFO_METRIC }, + [INF_POOL_FAILED] = { .n = IST("pool_failures_total"), .type = PROMEX_MT_COUNTER, .flags = PROMEX_FL_INFO_METRIC }, + [INF_ULIMIT_N] = { .n = IST("max_fds"), .type = PROMEX_MT_GAUGE, .flags = PROMEX_FL_INFO_METRIC }, + [INF_MAXSOCK] = { .n = IST("max_sockets"), .type = PROMEX_MT_GAUGE, .flags = PROMEX_FL_INFO_METRIC }, + [INF_MAXCONN] = { .n = IST("max_connections"), .type = PROMEX_MT_GAUGE, .flags = PROMEX_FL_INFO_METRIC }, + [INF_HARD_MAXCONN] = { .n = IST("hard_max_connections"), .type = PROMEX_MT_GAUGE, .flags = PROMEX_FL_INFO_METRIC }, + [INF_CURR_CONN] = { .n = IST("current_connections"), .type = PROMEX_MT_GAUGE, .flags = PROMEX_FL_INFO_METRIC }, + [INF_CUM_CONN] = { .n = IST("connections_total"), .type = PROMEX_MT_COUNTER, .flags = PROMEX_FL_INFO_METRIC }, + [INF_CUM_REQ] = { .n = IST("requests_total"), .type = PROMEX_MT_COUNTER, .flags = PROMEX_FL_INFO_METRIC }, + [INF_MAX_SSL_CONNS] = { .n = IST("max_ssl_connections"), .type = PROMEX_MT_GAUGE, .flags = PROMEX_FL_INFO_METRIC }, + [INF_CURR_SSL_CONNS] = { .n = IST("current_ssl_connections"), .type = PROMEX_MT_GAUGE, .flags = PROMEX_FL_INFO_METRIC }, + [INF_CUM_SSL_CONNS] = { .n = IST("ssl_connections_total"), .type = PROMEX_MT_COUNTER, .flags = PROMEX_FL_INFO_METRIC }, + [INF_MAXPIPES] = { .n = IST("max_pipes"), .type = PROMEX_MT_GAUGE, .flags = PROMEX_FL_INFO_METRIC }, + [INF_PIPES_USED] = { .n = IST("pipes_used_total"), .type = PROMEX_MT_COUNTER, .flags = PROMEX_FL_INFO_METRIC }, + [INF_PIPES_FREE] = { .n = IST("pipes_free_total"), .type = PROMEX_MT_COUNTER, .flags = PROMEX_FL_INFO_METRIC }, + [INF_CONN_RATE] = { .n = IST("current_connection_rate"), .type = PROMEX_MT_GAUGE, .flags = PROMEX_FL_INFO_METRIC }, + [INF_CONN_RATE_LIMIT] = { .n = IST("limit_connection_rate"), .type = PROMEX_MT_GAUGE, .flags = PROMEX_FL_INFO_METRIC }, + [INF_MAX_CONN_RATE] = { .n = IST("max_connection_rate"), .type = PROMEX_MT_GAUGE, .flags = PROMEX_FL_INFO_METRIC }, + [INF_SESS_RATE] = { .n = IST("current_session_rate"), .type = PROMEX_MT_GAUGE, .flags = PROMEX_FL_INFO_METRIC }, + [INF_SESS_RATE_LIMIT] = { .n = IST("limit_session_rate"), .type = PROMEX_MT_GAUGE, .flags = PROMEX_FL_INFO_METRIC }, + [INF_MAX_SESS_RATE] = { .n = IST("max_session_rate"), .type = PROMEX_MT_GAUGE, .flags = PROMEX_FL_INFO_METRIC }, + [INF_SSL_RATE] = { .n = IST("current_ssl_rate"), .type = PROMEX_MT_GAUGE, .flags = PROMEX_FL_INFO_METRIC }, + [INF_SSL_RATE_LIMIT] = { .n = IST("limit_ssl_rate"), .type = PROMEX_MT_GAUGE, .flags = PROMEX_FL_INFO_METRIC }, + [INF_MAX_SSL_RATE] = { .n = IST("max_ssl_rate"), .type = PROMEX_MT_GAUGE, .flags = PROMEX_FL_INFO_METRIC }, + [INF_SSL_FRONTEND_KEY_RATE] = { .n = IST("current_frontend_ssl_key_rate"), .type = PROMEX_MT_GAUGE, .flags = PROMEX_FL_INFO_METRIC }, + [INF_SSL_FRONTEND_MAX_KEY_RATE] = { .n = IST("max_frontend_ssl_key_rate"), .type = PROMEX_MT_GAUGE, .flags = PROMEX_FL_INFO_METRIC }, + [INF_SSL_FRONTEND_SESSION_REUSE_PCT] = { .n = IST("frontend_ssl_reuse"), .type = PROMEX_MT_GAUGE, .flags = PROMEX_FL_INFO_METRIC }, + [INF_SSL_BACKEND_KEY_RATE] = { .n = IST("current_backend_ssl_key_rate"), .type = PROMEX_MT_GAUGE, .flags = PROMEX_FL_INFO_METRIC }, + [INF_SSL_BACKEND_MAX_KEY_RATE] = { .n = IST("max_backend_ssl_key_rate"), .type = PROMEX_MT_GAUGE, .flags = PROMEX_FL_INFO_METRIC }, + [INF_SSL_CACHE_LOOKUPS] = { .n = IST("ssl_cache_lookups_total"), .type = PROMEX_MT_COUNTER, .flags = PROMEX_FL_INFO_METRIC }, + [INF_SSL_CACHE_MISSES] = { .n = IST("ssl_cache_misses_total"), .type = PROMEX_MT_COUNTER, .flags = PROMEX_FL_INFO_METRIC }, + [INF_COMPRESS_BPS_IN] = { .n = IST("http_comp_bytes_in_total"), .type = PROMEX_MT_COUNTER, .flags = PROMEX_FL_INFO_METRIC }, + [INF_COMPRESS_BPS_OUT] = { .n = IST("http_comp_bytes_out_total"), .type = PROMEX_MT_COUNTER, .flags = PROMEX_FL_INFO_METRIC }, + [INF_COMPRESS_BPS_RATE_LIM] = { .n = IST("limit_http_comp"), .type = PROMEX_MT_GAUGE, .flags = PROMEX_FL_INFO_METRIC }, + [INF_ZLIB_MEM_USAGE] = { .n = IST("current_zlib_memory"), .type = PROMEX_MT_GAUGE, .flags = PROMEX_FL_INFO_METRIC }, + [INF_MAX_ZLIB_MEM_USAGE] = { .n = IST("max_zlib_memory"), .type = PROMEX_MT_GAUGE, .flags = PROMEX_FL_INFO_METRIC }, + [INF_TASKS] = { .n = IST("current_tasks"), .type = PROMEX_MT_GAUGE, .flags = PROMEX_FL_INFO_METRIC }, + [INF_RUN_QUEUE] = { .n = IST("current_run_queue"), .type = PROMEX_MT_GAUGE, .flags = PROMEX_FL_INFO_METRIC }, + [INF_IDLE_PCT] = { .n = IST("idle_time_percent"), .type = PROMEX_MT_GAUGE, .flags = PROMEX_FL_INFO_METRIC }, + //[INF_NODE] ignored + //[INF_DESCRIPTION] ignored + [INF_STOPPING] = { .n = IST("stopping"), .type = PROMEX_MT_GAUGE, .flags = PROMEX_FL_INFO_METRIC }, + [INF_JOBS] = { .n = IST("jobs"), .type = PROMEX_MT_GAUGE, .flags = PROMEX_FL_INFO_METRIC }, + [INF_UNSTOPPABLE_JOBS] = { .n = IST("unstoppable_jobs"), .type = PROMEX_MT_GAUGE, .flags = PROMEX_FL_INFO_METRIC }, + [INF_LISTENERS] = { .n = IST("listeners"), .type = PROMEX_MT_GAUGE, .flags = PROMEX_FL_INFO_METRIC }, + [INF_ACTIVE_PEERS] = { .n = IST("active_peers"), .type = PROMEX_MT_GAUGE, .flags = PROMEX_FL_INFO_METRIC }, + [INF_CONNECTED_PEERS] = { .n = IST("connected_peers"), .type = PROMEX_MT_GAUGE, .flags = PROMEX_FL_INFO_METRIC }, + [INF_DROPPED_LOGS] = { .n = IST("dropped_logs_total"), .type = PROMEX_MT_COUNTER, .flags = PROMEX_FL_INFO_METRIC }, + [INF_BUSY_POLLING] = { .n = IST("busy_polling_enabled"), .type = PROMEX_MT_GAUGE, .flags = PROMEX_FL_INFO_METRIC }, + [INF_FAILED_RESOLUTIONS] = { .n = IST("failed_resolutions"), .type = PROMEX_MT_COUNTER, .flags = PROMEX_FL_INFO_METRIC }, + [INF_TOTAL_BYTES_OUT] = { .n = IST("bytes_out_total"), .type = PROMEX_MT_COUNTER, .flags = PROMEX_FL_INFO_METRIC }, + [INF_TOTAL_SPLICED_BYTES_OUT] = { .n = IST("spliced_bytes_out_total"), .type = PROMEX_MT_COUNTER, .flags = PROMEX_FL_INFO_METRIC }, + [INF_BYTES_OUT_RATE] = { .n = IST("bytes_out_rate"), .type = PROMEX_MT_GAUGE, .flags = PROMEX_FL_INFO_METRIC }, + //[INF_DEBUG_COMMANDS_ISSUED] ignored + [INF_CUM_LOG_MSGS] = { .n = IST("recv_logs_total"), .type = PROMEX_MT_COUNTER, .flags = PROMEX_FL_INFO_METRIC }, + [INF_BUILD_INFO] = { .n = IST("build_info"), .type = PROMEX_MT_GAUGE, .flags = PROMEX_FL_INFO_METRIC }, +}; + +/* frontend/backend/server fields */ +const struct promex_metric promex_st_metrics[ST_F_TOTAL_FIELDS] = { + //[ST_F_PXNAME] ignored + //[ST_F_SVNAME] ignored + [ST_F_QCUR] = { .n = IST("current_queue"), .type = PROMEX_MT_GAUGE, .flags = ( PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) }, + [ST_F_QMAX] = { .n = IST("max_queue"), .type = PROMEX_MT_GAUGE, .flags = ( PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) }, + [ST_F_SCUR] = { .n = IST("current_sessions"), .type = PROMEX_MT_GAUGE, .flags = (PROMEX_FL_FRONT_METRIC | PROMEX_FL_LI_METRIC | PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) }, + [ST_F_SMAX] = { .n = IST("max_sessions"), .type = PROMEX_MT_GAUGE, .flags = (PROMEX_FL_FRONT_METRIC | PROMEX_FL_LI_METRIC | PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) }, + [ST_F_SLIM] = { .n = IST("limit_sessions"), .type = PROMEX_MT_GAUGE, .flags = (PROMEX_FL_FRONT_METRIC | PROMEX_FL_LI_METRIC | PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) }, + [ST_F_STOT] = { .n = IST("sessions_total"), .type = PROMEX_MT_COUNTER, .flags = (PROMEX_FL_FRONT_METRIC | PROMEX_FL_LI_METRIC | PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) }, + [ST_F_BIN] = { .n = IST("bytes_in_total"), .type = PROMEX_MT_COUNTER, .flags = (PROMEX_FL_FRONT_METRIC | PROMEX_FL_LI_METRIC | PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) }, + [ST_F_BOUT] = { .n = IST("bytes_out_total"), .type = PROMEX_MT_COUNTER, .flags = (PROMEX_FL_FRONT_METRIC | PROMEX_FL_LI_METRIC | PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) }, + [ST_F_DREQ] = { .n = IST("requests_denied_total"), .type = PROMEX_MT_COUNTER, .flags = (PROMEX_FL_FRONT_METRIC | PROMEX_FL_LI_METRIC | PROMEX_FL_BACK_METRIC ) }, + [ST_F_DRESP] = { .n = IST("responses_denied_total"), .type = PROMEX_MT_COUNTER, .flags = (PROMEX_FL_FRONT_METRIC | PROMEX_FL_LI_METRIC | PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) }, + [ST_F_EREQ] = { .n = IST("request_errors_total"), .type = PROMEX_MT_COUNTER, .flags = (PROMEX_FL_FRONT_METRIC | PROMEX_FL_LI_METRIC ) }, + [ST_F_ECON] = { .n = IST("connection_errors_total"), .type = PROMEX_MT_COUNTER, .flags = ( PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) }, + [ST_F_ERESP] = { .n = IST("response_errors_total"), .type = PROMEX_MT_COUNTER, .flags = ( PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) }, + [ST_F_WRETR] = { .n = IST("retry_warnings_total"), .type = PROMEX_MT_COUNTER, .flags = ( PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) }, + [ST_F_WREDIS] = { .n = IST("redispatch_warnings_total"), .type = PROMEX_MT_COUNTER, .flags = ( PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) }, + [ST_F_STATUS] = { .n = IST("status"), .type = PROMEX_MT_GAUGE, .flags = (PROMEX_FL_FRONT_METRIC | PROMEX_FL_LI_METRIC | PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) }, + [ST_F_WEIGHT] = { .n = IST("weight"), .type = PROMEX_MT_GAUGE, .flags = ( PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) }, + [ST_F_ACT] = { .n = IST("active_servers"), .type = PROMEX_MT_GAUGE, .flags = ( PROMEX_FL_BACK_METRIC ) }, + [ST_F_BCK] = { .n = IST("backup_servers"), .type = PROMEX_MT_GAUGE, .flags = ( PROMEX_FL_BACK_METRIC ) }, + [ST_F_CHKFAIL] = { .n = IST("check_failures_total"), .type = PROMEX_MT_COUNTER, .flags = ( PROMEX_FL_SRV_METRIC) }, + [ST_F_CHKDOWN] = { .n = IST("check_up_down_total"), .type = PROMEX_MT_COUNTER, .flags = ( PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) }, + [ST_F_LASTCHG] = { .n = IST("check_last_change_seconds"), .type = PROMEX_MT_GAUGE, .flags = ( PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) }, + [ST_F_DOWNTIME] = { .n = IST("downtime_seconds_total"), .type = PROMEX_MT_COUNTER, .flags = ( PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) }, + [ST_F_QLIMIT] = { .n = IST("queue_limit"), .type = PROMEX_MT_GAUGE, .flags = ( PROMEX_FL_SRV_METRIC) }, + //[ST_F_PID] ignored + //[ST_F_IID] ignored + //[ST_F_SID] ignored + [ST_F_THROTTLE] = { .n = IST("current_throttle"), .type = PROMEX_MT_GAUGE, .flags = ( PROMEX_FL_SRV_METRIC) }, + [ST_F_LBTOT] = { .n = IST("loadbalanced_total"), .type = PROMEX_MT_COUNTER, .flags = ( PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) }, + //[ST_F_TRACKED] ignored + //[ST_F_TYPE] ignored + //[ST_F_RATE] ignored + [ST_F_RATE_LIM] = { .n = IST("limit_session_rate"), .type = PROMEX_MT_GAUGE, .flags = (PROMEX_FL_FRONT_METRIC ) }, + [ST_F_RATE_MAX] = { .n = IST("max_session_rate"), .type = PROMEX_MT_GAUGE, .flags = (PROMEX_FL_FRONT_METRIC | PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) }, + [ST_F_CHECK_STATUS] = { .n = IST("check_status"), .type = PROMEX_MT_GAUGE, .flags = ( PROMEX_FL_SRV_METRIC) }, + [ST_F_CHECK_CODE] = { .n = IST("check_code"), .type = PROMEX_MT_GAUGE, .flags = ( PROMEX_FL_SRV_METRIC) }, + [ST_F_CHECK_DURATION] = { .n = IST("check_duration_seconds"), .type = PROMEX_MT_GAUGE, .flags = ( PROMEX_FL_SRV_METRIC) }, + [ST_F_HRSP_1XX] = { .n = IST("http_responses_total"), .type = PROMEX_MT_COUNTER, .flags = (PROMEX_FL_FRONT_METRIC | PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) }, + [ST_F_HRSP_2XX] = { .n = IST("http_responses_total"), .type = PROMEX_MT_COUNTER, .flags = (PROMEX_FL_FRONT_METRIC | PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) }, + [ST_F_HRSP_3XX] = { .n = IST("http_responses_total"), .type = PROMEX_MT_COUNTER, .flags = (PROMEX_FL_FRONT_METRIC | PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) }, + [ST_F_HRSP_4XX] = { .n = IST("http_responses_total"), .type = PROMEX_MT_COUNTER, .flags = (PROMEX_FL_FRONT_METRIC | PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) }, + [ST_F_HRSP_5XX] = { .n = IST("http_responses_total"), .type = PROMEX_MT_COUNTER, .flags = (PROMEX_FL_FRONT_METRIC | PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) }, + [ST_F_HRSP_OTHER] = { .n = IST("http_responses_total"), .type = PROMEX_MT_COUNTER, .flags = (PROMEX_FL_FRONT_METRIC | PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) }, + //[ST_F_HANAFAIL] ignored + //[ST_F_REQ_RATE] ignored + [ST_F_REQ_RATE_MAX] = { .n = IST("http_requests_rate_max"), .type = PROMEX_MT_GAUGE, .flags = (PROMEX_FL_FRONT_METRIC ) }, + [ST_F_REQ_TOT] = { .n = IST("http_requests_total"), .type = PROMEX_MT_COUNTER, .flags = (PROMEX_FL_FRONT_METRIC | PROMEX_FL_BACK_METRIC ) }, + [ST_F_CLI_ABRT] = { .n = IST("client_aborts_total"), .type = PROMEX_MT_COUNTER, .flags = ( PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) }, + [ST_F_SRV_ABRT] = { .n = IST("server_aborts_total"), .type = PROMEX_MT_COUNTER, .flags = ( PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) }, + [ST_F_COMP_IN] = { .n = IST("http_comp_bytes_in_total"), .type = PROMEX_MT_COUNTER, .flags = (PROMEX_FL_FRONT_METRIC | PROMEX_FL_BACK_METRIC ) }, + [ST_F_COMP_OUT] = { .n = IST("http_comp_bytes_out_total"), .type = PROMEX_MT_COUNTER, .flags = (PROMEX_FL_FRONT_METRIC | PROMEX_FL_BACK_METRIC ) }, + [ST_F_COMP_BYP] = { .n = IST("http_comp_bytes_bypassed_total"), .type = PROMEX_MT_COUNTER, .flags = (PROMEX_FL_FRONT_METRIC | PROMEX_FL_BACK_METRIC ) }, + [ST_F_COMP_RSP] = { .n = IST("http_comp_responses_total"), .type = PROMEX_MT_COUNTER, .flags = (PROMEX_FL_FRONT_METRIC | PROMEX_FL_BACK_METRIC ) }, + [ST_F_LASTSESS] = { .n = IST("last_session_seconds"), .type = PROMEX_MT_GAUGE, .flags = ( PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) }, + //[ST_F_LAST_CHK] ignored + //[ST_F_LAST_AGT] ignored + [ST_F_QTIME] = { .n = IST("queue_time_average_seconds"), .type = PROMEX_MT_GAUGE, .flags = ( PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) }, + [ST_F_CTIME] = { .n = IST("connect_time_average_seconds"), .type = PROMEX_MT_GAUGE, .flags = ( PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) }, + [ST_F_RTIME] = { .n = IST("response_time_average_seconds"), .type = PROMEX_MT_GAUGE, .flags = ( PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) }, + [ST_F_TTIME] = { .n = IST("total_time_average_seconds"), .type = PROMEX_MT_GAUGE, .flags = ( PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) }, + //[ST_F_AGENT_STATUS] ignored + //[ST_F_AGENT_CODE] ignored + //[ST_F_AGENT_DURATION] ignored + //[ST_F_CHECK_DESC] ignored + //[ST_F_AGENT_DESC] ignored + //[ST_F_CHECK_RISE] ignored + //[ST_F_CHECK_FALL] ignored + //[ST_F_CHECK_HEALTH] ignored + //[ST_F_AGENT_RISE] ignored + //[ST_F_AGENT_FALL] ignored + //[ST_F_AGENT_HEALTH] ignored + //[ST_F_ADDR] ignored + //[ST_F_COOKIE] ignored + //[ST_F_MODE] ignored + //[ST_F_ALGO] ignored + //[ST_F_CONN_RATE] ignored + [ST_F_CONN_RATE_MAX] = { .n = IST("connections_rate_max"), .type = PROMEX_MT_GAUGE, .flags = (PROMEX_FL_FRONT_METRIC ) }, + [ST_F_CONN_TOT] = { .n = IST("connections_total"), .type = PROMEX_MT_COUNTER, .flags = (PROMEX_FL_FRONT_METRIC ) }, + [ST_F_INTERCEPTED] = { .n = IST("intercepted_requests_total"), .type = PROMEX_MT_COUNTER, .flags = (PROMEX_FL_FRONT_METRIC ) }, + [ST_F_DCON] = { .n = IST("denied_connections_total"), .type = PROMEX_MT_COUNTER, .flags = (PROMEX_FL_FRONT_METRIC | PROMEX_FL_LI_METRIC ) }, + [ST_F_DSES] = { .n = IST("denied_sessions_total"), .type = PROMEX_MT_COUNTER, .flags = (PROMEX_FL_FRONT_METRIC | PROMEX_FL_LI_METRIC ) }, + [ST_F_WREW] = { .n = IST("failed_header_rewriting_total"), .type = PROMEX_MT_COUNTER, .flags = (PROMEX_FL_FRONT_METRIC | PROMEX_FL_LI_METRIC | PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) }, + [ST_F_CONNECT] = { .n = IST("connection_attempts_total"), .type = PROMEX_MT_COUNTER, .flags = ( PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) }, + [ST_F_REUSE] = { .n = IST("connection_reuses_total"), .type = PROMEX_MT_COUNTER, .flags = ( PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) }, + [ST_F_CACHE_LOOKUPS] = { .n = IST("http_cache_lookups_total"), .type = PROMEX_MT_COUNTER, .flags = (PROMEX_FL_FRONT_METRIC | PROMEX_FL_BACK_METRIC ) }, + [ST_F_CACHE_HITS] = { .n = IST("http_cache_hits_total"), .type = PROMEX_MT_COUNTER, .flags = (PROMEX_FL_FRONT_METRIC | PROMEX_FL_BACK_METRIC ) }, + [ST_F_SRV_ICUR] = { .n = IST("idle_connections_current"), .type = PROMEX_MT_GAUGE, .flags = ( PROMEX_FL_SRV_METRIC) }, + [ST_F_SRV_ILIM] = { .n = IST("idle_connections_limit"), .type = PROMEX_MT_GAUGE, .flags = ( PROMEX_FL_SRV_METRIC) }, + [ST_F_QT_MAX] = { .n = IST("max_queue_time_seconds"), .type = PROMEX_MT_GAUGE, .flags = ( PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) }, + [ST_F_CT_MAX] = { .n = IST("max_connect_time_seconds"), .type = PROMEX_MT_GAUGE, .flags = ( PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) }, + [ST_F_RT_MAX] = { .n = IST("max_response_time_seconds"), .type = PROMEX_MT_GAUGE, .flags = ( PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) }, + [ST_F_TT_MAX] = { .n = IST("max_total_time_seconds"), .type = PROMEX_MT_GAUGE, .flags = ( PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) }, + [ST_F_EINT] = { .n = IST("internal_errors_total"), .type = PROMEX_MT_COUNTER, .flags = (PROMEX_FL_FRONT_METRIC | PROMEX_FL_LI_METRIC | PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) }, + [ST_F_IDLE_CONN_CUR] = { .n = IST("unsafe_idle_connections_current"), .type = PROMEX_MT_GAUGE, .flags = ( PROMEX_FL_SRV_METRIC) }, + [ST_F_SAFE_CONN_CUR] = { .n = IST("safe_idle_connections_current"), .type = PROMEX_MT_GAUGE, .flags = ( PROMEX_FL_SRV_METRIC) }, + [ST_F_USED_CONN_CUR] = { .n = IST("used_connections_current"), .type = PROMEX_MT_GAUGE, .flags = ( PROMEX_FL_SRV_METRIC) }, + [ST_F_NEED_CONN_EST] = { .n = IST("need_connections_current"), .type = PROMEX_MT_GAUGE, .flags = ( PROMEX_FL_SRV_METRIC) }, + [ST_F_UWEIGHT] = { .n = IST("uweight"), .type = PROMEX_MT_GAUGE, .flags = ( PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) }, + [ST_F_AGG_SRV_CHECK_STATUS] = { .n = IST("agg_server_check_status"), .type = PROMEX_MT_GAUGE, .flags = ( PROMEX_FL_BACK_METRIC ) }, + [ST_F_AGG_SRV_STATUS ] = { .n = IST("agg_server_status"), .type = PROMEX_MT_GAUGE, .flags = ( PROMEX_FL_BACK_METRIC ) }, + [ST_F_AGG_CHECK_STATUS] = { .n = IST("agg_check_status"), .type = PROMEX_MT_GAUGE, .flags = ( PROMEX_FL_BACK_METRIC ) }, +}; + +/* Description of overridden stats fields */ +const struct ist promex_st_metric_desc[ST_F_TOTAL_FIELDS] = { + [ST_F_STATUS] = IST("Current status of the service, per state label value."), + [ST_F_CHECK_STATUS] = IST("Status of last health check, per state label value."), + [ST_F_CHECK_CODE] = IST("layer5-7 code, if available of the last health check."), + [ST_F_CHECK_DURATION] = IST("Total duration of the latest server health check, in seconds."), + [ST_F_QTIME] = IST("Avg. queue time for last 1024 successful connections."), + [ST_F_CTIME] = IST("Avg. connect time for last 1024 successful connections."), + [ST_F_RTIME] = IST("Avg. response time for last 1024 successful connections."), + [ST_F_TTIME] = IST("Avg. total time for last 1024 successful connections."), + [ST_F_QT_MAX] = IST("Maximum observed time spent in the queue"), + [ST_F_CT_MAX] = IST("Maximum observed time spent waiting for a connection to complete"), + [ST_F_RT_MAX] = IST("Maximum observed time spent waiting for a server response"), + [ST_F_TT_MAX] = IST("Maximum observed total request+response time (request+queue+connect+response+processing)"), +}; + +/* stick table base fields */ +enum sticktable_field { + STICKTABLE_SIZE = 0, + STICKTABLE_USED, + /* must always be the last one */ + STICKTABLE_TOTAL_FIELDS +}; + +const struct promex_metric promex_sticktable_metrics[STICKTABLE_TOTAL_FIELDS] = { + [STICKTABLE_SIZE] = { .n = IST("size"), .type = PROMEX_MT_GAUGE, .flags = PROMEX_FL_STICKTABLE_METRIC }, + [STICKTABLE_USED] = { .n = IST("used"), .type = PROMEX_MT_GAUGE, .flags = PROMEX_FL_STICKTABLE_METRIC }, +}; + +/* stick table base description */ +const struct ist promex_sticktable_metric_desc[STICKTABLE_TOTAL_FIELDS] = { + [STICKTABLE_SIZE] = IST("Stick table size."), + [STICKTABLE_USED] = IST("Number of entries used in this stick table."), +}; + +/* Specific labels for all ST_F_HRSP_* fields */ +const struct ist promex_hrsp_code[1 + ST_F_HRSP_OTHER - ST_F_HRSP_1XX] = { + [ST_F_HRSP_1XX - ST_F_HRSP_1XX] = IST("1xx"), + [ST_F_HRSP_2XX - ST_F_HRSP_1XX] = IST("2xx"), + [ST_F_HRSP_3XX - ST_F_HRSP_1XX] = IST("3xx"), + [ST_F_HRSP_4XX - ST_F_HRSP_1XX] = IST("4xx"), + [ST_F_HRSP_5XX - ST_F_HRSP_1XX] = IST("5xx"), + [ST_F_HRSP_OTHER - ST_F_HRSP_1XX] = IST("other"), +}; + +enum promex_front_state { + PROMEX_FRONT_STATE_DOWN = 0, + PROMEX_FRONT_STATE_UP, + + PROMEX_FRONT_STATE_COUNT /* must be last */ +}; + +const struct ist promex_front_st[PROMEX_FRONT_STATE_COUNT] = { + [PROMEX_FRONT_STATE_DOWN] = IST("DOWN"), + [PROMEX_FRONT_STATE_UP] = IST("UP"), +}; + +enum promex_back_state { + PROMEX_BACK_STATE_DOWN = 0, + PROMEX_BACK_STATE_UP, + + PROMEX_BACK_STATE_COUNT /* must be last */ +}; + +const struct ist promex_back_st[PROMEX_BACK_STATE_COUNT] = { + [PROMEX_BACK_STATE_DOWN] = IST("DOWN"), + [PROMEX_BACK_STATE_UP] = IST("UP"), +}; + +enum promex_srv_state { + PROMEX_SRV_STATE_DOWN = 0, + PROMEX_SRV_STATE_UP, + PROMEX_SRV_STATE_MAINT, + PROMEX_SRV_STATE_DRAIN, + PROMEX_SRV_STATE_NOLB, + + PROMEX_SRV_STATE_COUNT /* must be last */ +}; + +const struct ist promex_srv_st[PROMEX_SRV_STATE_COUNT] = { + [PROMEX_SRV_STATE_DOWN] = IST("DOWN"), + [PROMEX_SRV_STATE_UP] = IST("UP"), + [PROMEX_SRV_STATE_MAINT] = IST("MAINT"), + [PROMEX_SRV_STATE_DRAIN] = IST("DRAIN"), + [PROMEX_SRV_STATE_NOLB] = IST("NOLB"), +}; + +/* Return the server status. */ +enum promex_srv_state promex_srv_status(struct server *sv) +{ + int state = PROMEX_SRV_STATE_DOWN; + + if (sv->cur_state == SRV_ST_RUNNING || sv->cur_state == SRV_ST_STARTING) { + state = PROMEX_SRV_STATE_UP; + if (sv->cur_admin & SRV_ADMF_DRAIN) + state = PROMEX_SRV_STATE_DRAIN; + } + else if (sv->cur_state == SRV_ST_STOPPING) + state = PROMEX_SRV_STATE_NOLB; + + if (sv->cur_admin & SRV_ADMF_MAINT) + state = PROMEX_SRV_STATE_MAINT; + + return state; +} + +/* Convert a field to its string representation and write it in , followed + * by a newline, if there is enough space. non-numeric value are converted in + * "NaN" because Prometheus only support numerical values (but it is unexepceted + * to process this kind of value). It returns 1 on success. Otherwise, it + * returns 0. The buffer's length must not exceed value. + */ +static int promex_metric_to_str(struct buffer *out, struct field *f, size_t max) +{ + int ret = 0; + + switch (field_format(f, 0)) { + case FF_EMPTY: ret = chunk_strcat(out, "NaN\n"); break; + case FF_S32: ret = chunk_appendf(out, "%d\n", f->u.s32); break; + case FF_U32: ret = chunk_appendf(out, "%u\n", f->u.u32); break; + case FF_S64: ret = chunk_appendf(out, "%lld\n", (long long)f->u.s64); break; + case FF_U64: ret = chunk_appendf(out, "%llu\n", (unsigned long long)f->u.u64); break; + case FF_FLT: ret = chunk_appendf(out, "%f\n", f->u.flt); break; + case FF_STR: ret = chunk_strcat(out, "NaN\n"); break; + default: ret = chunk_strcat(out, "NaN\n"); break; + } + if (!ret || out->data > max) + return 0; + return 1; +} + +/* Dump the header lines for . It is its #HELP and #TYPE strings. It + * returns 1 on success. Otherwise, if length exceeds , it returns 0. + */ +static int promex_dump_metric_header(struct appctx *appctx, struct htx *htx, + const struct promex_metric *metric, const struct ist name, + struct ist *out, size_t max) +{ + struct promex_ctx *ctx = appctx->svcctx; + struct ist type; + struct ist desc; + + switch (metric->type) { + case PROMEX_MT_COUNTER: + type = ist("counter"); + break; + default: + type = ist("gauge"); + } + + if (istcat(out, ist("# HELP "), max) == -1 || + istcat(out, name, max) == -1 || + istcat(out, ist(" "), max) == -1) + goto full; + + if (metric->flags & PROMEX_FL_INFO_METRIC) + desc = ist(info_fields[ctx->field_num].desc); + else if (metric->flags & PROMEX_FL_STICKTABLE_METRIC) + desc = promex_sticktable_metric_desc[ctx->field_num]; + else if (!isttest(promex_st_metric_desc[ctx->field_num])) + desc = ist(stat_fields[ctx->field_num].desc); + else + desc = promex_st_metric_desc[ctx->field_num]; + + if (istcat(out, desc, max) == -1 || + istcat(out, ist("\n# TYPE "), max) == -1 || + istcat(out, name, max) == -1 || + istcat(out, ist(" "), max) == -1 || + istcat(out, type, max) == -1 || + istcat(out, ist("\n"), max) == -1) + goto full; + + return 1; + + full: + return 0; +} + +/* Dump the line for . It starts by the metric name followed by its + * labels (proxy name, server name...) between braces and finally its value. If + * not already done, the header lines are dumped first. It returns 1 on + * success. Otherwise if length exceeds , it returns 0. + */ +static int promex_dump_metric(struct appctx *appctx, struct htx *htx, struct ist prefix, + const struct promex_metric *metric, struct field *val, + struct promex_label *labels, struct ist *out, size_t max) +{ + struct ist name = { .ptr = (char[PROMEX_MAX_NAME_LEN]){ 0 }, .len = 0 }; + struct promex_ctx *ctx = appctx->svcctx; + size_t len = out->len; + + if (out->len + PROMEX_MAX_METRIC_LENGTH > max) + return 0; + + /* Fill the metric name */ + istcat(&name, prefix, PROMEX_MAX_NAME_LEN); + istcat(&name, metric->n, PROMEX_MAX_NAME_LEN); + + + if ((ctx->flags & PROMEX_FL_METRIC_HDR) && + !promex_dump_metric_header(appctx, htx, metric, name, out, max)) + goto full; + + if (istcat(out, name, max) == -1) + goto full; + + if (isttest(labels[0].name)) { + int i; + + if (istcat(out, ist("{"), max) == -1) + goto full; + + for (i = 0; isttest(labels[i].name); i++) { + if (!isttest(labels[i].value)) + continue; + + if ((i && istcat(out, ist(","), max) == -1) || + istcat(out, labels[i].name, max) == -1 || + istcat(out, ist("=\""), max) == -1 || + istcat(out, labels[i].value, max) == -1 || + istcat(out, ist("\""), max) == -1) + goto full; + } + + if (istcat(out, ist("}"), max) == -1) + goto full; + + } + + if (istcat(out, ist(" "), max) == -1) + goto full; + + trash.data = out->len; + if (!promex_metric_to_str(&trash, val, max)) + goto full; + out->len = trash.data; + + ctx->flags &= ~PROMEX_FL_METRIC_HDR; + return 1; + full: + // Restore previous length + out->len = len; + return 0; + +} + + +/* Dump global metrics (prefixed by "haproxy_process_"). It returns 1 on success, + * 0 if is full and -1 in case of any error. */ +static int promex_dump_global_metrics(struct appctx *appctx, struct htx *htx) +{ + static struct ist prefix = IST("haproxy_process_"); + struct promex_ctx *ctx = appctx->svcctx; + struct field val; + struct channel *chn = sc_ic(appctx_sc(appctx)); + struct ist out = ist2(trash.area, 0); + size_t max = htx_get_max_blksz(htx, channel_htx_recv_max(chn, htx)); + int ret = 1; + + if (!stats_fill_info(info, INF_TOTAL_FIELDS, 0)) + return -1; + + for (; ctx->field_num < INF_TOTAL_FIELDS; ctx->field_num++) { + struct promex_label labels[PROMEX_MAX_LABELS-1] = {}; + + if (!(promex_global_metrics[ctx->field_num].flags & ctx->flags)) + continue; + + switch (ctx->field_num) { + case INF_BUILD_INFO: + labels[0].name = ist("version"); + labels[0].value = ist(HAPROXY_VERSION); + val = mkf_u32(FN_GAUGE, 1); + break; + + default: + val = info[ctx->field_num]; + } + + if (!promex_dump_metric(appctx, htx, prefix, &promex_global_metrics[ctx->field_num], + &val, labels, &out, max)) + goto full; + + ctx->flags |= PROMEX_FL_METRIC_HDR; + } + + end: + if (out.len) { + if (!htx_add_data_atonce(htx, out)) + return -1; /* Unexpected and unrecoverable error */ + channel_add_input(chn, out.len); + } + return ret; + full: + ret = 0; + goto end; +} + +/* Dump frontends metrics (prefixed by "haproxy_frontend_"). It returns 1 on success, + * 0 if is full and -1 in case of any error. */ +static int promex_dump_front_metrics(struct appctx *appctx, struct htx *htx) +{ + static struct ist prefix = IST("haproxy_frontend_"); + struct promex_ctx *ctx = appctx->svcctx; + struct proxy *px; + struct field val; + struct channel *chn = sc_ic(appctx_sc(appctx)); + struct ist out = ist2(trash.area, 0); + size_t max = htx_get_max_blksz(htx, channel_htx_recv_max(chn, htx)); + struct field *stats = stat_l[STATS_DOMAIN_PROXY]; + int ret = 1; + enum promex_front_state state; + + for (;ctx->field_num < ST_F_TOTAL_FIELDS; ctx->field_num++) { + if (!(promex_st_metrics[ctx->field_num].flags & ctx->flags)) + continue; + + while (ctx->px) { + struct promex_label labels[PROMEX_MAX_LABELS-1] = {}; + + px = ctx->px; + + labels[0].name = ist("proxy"); + labels[0].value = ist2(px->id, strlen(px->id)); + + /* skip the disabled proxies, global frontend and non-networked ones */ + if ((px->flags & PR_FL_DISABLED) || px->uuid <= 0 || !(px->cap & PR_CAP_FE)) + goto next_px; + + if (!stats_fill_fe_stats(px, stats, ST_F_TOTAL_FIELDS, &(ctx->field_num))) + return -1; + + switch (ctx->field_num) { + case ST_F_STATUS: + state = !(px->flags & PR_FL_STOPPED); + for (; ctx->obj_state < PROMEX_FRONT_STATE_COUNT; ctx->obj_state++) { + labels[1].name = ist("state"); + labels[1].value = promex_front_st[ctx->obj_state]; + val = mkf_u32(FO_STATUS, state == ctx->obj_state); + if (!promex_dump_metric(appctx, htx, prefix, &promex_st_metrics[ctx->field_num], + &val, labels, &out, max)) + goto full; + } + ctx->obj_state = 0; + goto next_px; + case ST_F_REQ_RATE_MAX: + case ST_F_REQ_TOT: + case ST_F_INTERCEPTED: + case ST_F_CACHE_LOOKUPS: + case ST_F_CACHE_HITS: + case ST_F_COMP_IN: + case ST_F_COMP_OUT: + case ST_F_COMP_BYP: + case ST_F_COMP_RSP: + if (px->mode != PR_MODE_HTTP) + goto next_px; + val = stats[ctx->field_num]; + break; + case ST_F_HRSP_1XX: + case ST_F_HRSP_2XX: + case ST_F_HRSP_3XX: + case ST_F_HRSP_4XX: + case ST_F_HRSP_5XX: + case ST_F_HRSP_OTHER: + if (px->mode != PR_MODE_HTTP) + goto next_px; + if (ctx->field_num != ST_F_HRSP_1XX) + ctx->flags &= ~PROMEX_FL_METRIC_HDR; + labels[1].name = ist("code"); + labels[1].value = promex_hrsp_code[ctx->field_num - ST_F_HRSP_1XX]; + val = stats[ctx->field_num]; + break; + + default: + val = stats[ctx->field_num]; + } + + if (!promex_dump_metric(appctx, htx, prefix, &promex_st_metrics[ctx->field_num], + &val, labels, &out, max)) + goto full; + next_px: + ctx->px = px->next; + } + ctx->flags |= PROMEX_FL_METRIC_HDR; + ctx->px = proxies_list; + } + + end: + if (out.len) { + if (!htx_add_data_atonce(htx, out)) + return -1; /* Unexpected and unrecoverable error */ + channel_add_input(chn, out.len); + } + return ret; + full: + ret = 0; + goto end; +} + +/* Dump listener metrics (prefixed by "haproxy_listen_"). It returns 1 on + * success, 0 if is full and -1 in case of any error. */ +static int promex_dump_listener_metrics(struct appctx *appctx, struct htx *htx) +{ + static struct ist prefix = IST("haproxy_listener_"); + struct promex_ctx *ctx = appctx->svcctx; + struct proxy *px; + struct field val; + struct channel *chn = sc_ic(appctx_sc(appctx)); + struct ist out = ist2(trash.area, 0); + size_t max = htx_get_max_blksz(htx, channel_htx_recv_max(chn, htx)); + struct field *stats = stat_l[STATS_DOMAIN_PROXY]; + struct listener *li; + int ret = 1; + enum li_status status; + + for (;ctx->field_num < ST_F_TOTAL_FIELDS; ctx->field_num++) { + if (!(promex_st_metrics[ctx->field_num].flags & ctx->flags)) + continue; + + while (ctx->px) { + struct promex_label labels[PROMEX_MAX_LABELS-1] = {}; + + px = ctx->px; + + labels[0].name = ist("proxy"); + labels[0].value = ist2(px->id, strlen(px->id)); + + /* skip the disabled proxies, global frontend and non-networked ones */ + if ((px->flags & PR_FL_DISABLED) || px->uuid <= 0 || !(px->cap & PR_CAP_FE)) + goto next_px; + + li = ctx->li; + list_for_each_entry_from(li, &px->conf.listeners, by_fe) { + + if (!li->counters) + continue; + + labels[1].name = ist("listener"); + labels[1].value = ist2(li->name, strlen(li->name)); + + if (!stats_fill_li_stats(px, li, 0, stats, + ST_F_TOTAL_FIELDS, &(ctx->field_num))) + return -1; + + switch (ctx->field_num) { + case ST_F_STATUS: + status = get_li_status(li); + for (; ctx->obj_state < LI_STATE_COUNT; ctx->obj_state++) { + val = mkf_u32(FO_STATUS, status == ctx->obj_state); + labels[2].name = ist("state"); + labels[2].value = ist(li_status_st[ctx->obj_state]); + if (!promex_dump_metric(appctx, htx, prefix, &promex_st_metrics[ctx->field_num], + &val, labels, &out, max)) + goto full; + } + ctx->obj_state = 0; + continue; + default: + val = stats[ctx->field_num]; + } + + if (!promex_dump_metric(appctx, htx, prefix, + &promex_st_metrics[ctx->field_num], + &val, labels, &out, max)) + goto full; + } + + next_px: + px = px->next; + ctx->px = px; + ctx->li = (px ? LIST_NEXT(&px->conf.listeners, struct listener *, by_fe) : NULL); + } + ctx->flags |= PROMEX_FL_METRIC_HDR; + ctx->px = proxies_list; + ctx->li = LIST_NEXT(&proxies_list->conf.listeners, struct listener *, by_fe); + } + + end: + if (out.len) { + if (!htx_add_data_atonce(htx, out)) + return -1; /* Unexpected and unrecoverable error */ + channel_add_input(chn, out.len); + } + return ret; + full: + ctx->li = li; + ret = 0; + goto end; +} + +/* Dump backends metrics (prefixed by "haproxy_backend_"). It returns 1 on success, + * 0 if is full and -1 in case of any error. */ +static int promex_dump_back_metrics(struct appctx *appctx, struct htx *htx) +{ + static struct ist prefix = IST("haproxy_backend_"); + struct promex_ctx *ctx = appctx->svcctx; + struct proxy *px; + struct server *sv; + struct field val; + struct channel *chn = sc_ic(appctx_sc(appctx)); + struct ist out = ist2(trash.area, 0); + size_t max = htx_get_max_blksz(htx, channel_htx_recv_max(chn, htx)); + struct field *stats = stat_l[STATS_DOMAIN_PROXY]; + int ret = 1; + double secs; + enum promex_back_state bkd_state; + enum promex_srv_state srv_state; + enum healthcheck_status srv_check_status; + + for (;ctx->field_num < ST_F_TOTAL_FIELDS; ctx->field_num++) { + if (!(promex_st_metrics[ctx->field_num].flags & ctx->flags)) + continue; + + while (ctx->px) { + struct promex_label labels[PROMEX_MAX_LABELS-1] = {}; + unsigned int srv_state_count[PROMEX_SRV_STATE_COUNT] = { 0 }; + unsigned int srv_check_count[HCHK_STATUS_SIZE] = { 0 }; + const char *check_state; + + px = ctx->px; + + labels[0].name = ist("proxy"); + labels[0].value = ist2(px->id, strlen(px->id)); + + /* skip the disabled proxies, global frontend and non-networked ones */ + if ((px->flags & PR_FL_DISABLED) || px->uuid <= 0 || !(px->cap & PR_CAP_BE)) + goto next_px; + + if (!stats_fill_be_stats(px, 0, stats, ST_F_TOTAL_FIELDS, &(ctx->field_num))) + return -1; + + switch (ctx->field_num) { + case ST_F_AGG_SRV_CHECK_STATUS: // DEPRECATED + case ST_F_AGG_SRV_STATUS: + if (!px->srv) + goto next_px; + sv = px->srv; + while (sv) { + srv_state = promex_srv_status(sv); + srv_state_count[srv_state] += 1; + sv = sv->next; + } + for (; ctx->obj_state < PROMEX_SRV_STATE_COUNT; ctx->obj_state++) { + val = mkf_u32(FN_GAUGE, srv_state_count[ctx->obj_state]); + labels[1].name = ist("state"); + labels[1].value = promex_srv_st[ctx->obj_state]; + if (!promex_dump_metric(appctx, htx, prefix, &promex_st_metrics[ctx->field_num], + &val, labels, &out, max)) + goto full; + } + ctx->obj_state = 0; + goto next_px; + case ST_F_AGG_CHECK_STATUS: + if (!px->srv) + goto next_px; + sv = px->srv; + while (sv) { + srv_check_status = sv->check.status; + srv_check_count[srv_check_status] += 1; + sv = sv->next; + } + for (; ctx->obj_state < HCHK_STATUS_SIZE; ctx->obj_state++) { + if (get_check_status_result(ctx->obj_state) < CHK_RES_FAILED) + continue; + val = mkf_u32(FO_STATUS, srv_check_count[ctx->obj_state]); + check_state = get_check_status_info(ctx->obj_state); + labels[1].name = ist("state"); + labels[1].value = ist(check_state); + if (!promex_dump_metric(appctx, htx, prefix, &promex_st_metrics[ctx->field_num], + &val, labels, &out, max)) + goto full; + } + ctx->obj_state = 0; + goto next_px; + case ST_F_STATUS: + bkd_state = ((px->lbprm.tot_weight > 0 || !px->srv) ? 1 : 0); + for (; ctx->obj_state < PROMEX_BACK_STATE_COUNT; ctx->obj_state++) { + labels[1].name = ist("state"); + labels[1].value = promex_back_st[ctx->obj_state]; + val = mkf_u32(FO_STATUS, bkd_state == ctx->obj_state); + if (!promex_dump_metric(appctx, htx, prefix, &promex_st_metrics[ctx->field_num], + &val, labels, &out, max)) + goto full; + } + ctx->obj_state = 0; + goto next_px; + case ST_F_QTIME: + secs = (double)swrate_avg(px->be_counters.q_time, TIME_STATS_SAMPLES) / 1000.0; + val = mkf_flt(FN_AVG, secs); + break; + case ST_F_CTIME: + secs = (double)swrate_avg(px->be_counters.c_time, TIME_STATS_SAMPLES) / 1000.0; + val = mkf_flt(FN_AVG, secs); + break; + case ST_F_RTIME: + secs = (double)swrate_avg(px->be_counters.d_time, TIME_STATS_SAMPLES) / 1000.0; + val = mkf_flt(FN_AVG, secs); + break; + case ST_F_TTIME: + secs = (double)swrate_avg(px->be_counters.t_time, TIME_STATS_SAMPLES) / 1000.0; + val = mkf_flt(FN_AVG, secs); + break; + case ST_F_QT_MAX: + secs = (double)px->be_counters.qtime_max / 1000.0; + val = mkf_flt(FN_MAX, secs); + break; + case ST_F_CT_MAX: + secs = (double)px->be_counters.ctime_max / 1000.0; + val = mkf_flt(FN_MAX, secs); + break; + case ST_F_RT_MAX: + secs = (double)px->be_counters.dtime_max / 1000.0; + val = mkf_flt(FN_MAX, secs); + break; + case ST_F_TT_MAX: + secs = (double)px->be_counters.ttime_max / 1000.0; + val = mkf_flt(FN_MAX, secs); + break; + case ST_F_REQ_TOT: + case ST_F_CACHE_LOOKUPS: + case ST_F_CACHE_HITS: + case ST_F_COMP_IN: + case ST_F_COMP_OUT: + case ST_F_COMP_BYP: + case ST_F_COMP_RSP: + if (px->mode != PR_MODE_HTTP) + goto next_px; + val = stats[ctx->field_num]; + break; + case ST_F_HRSP_1XX: + case ST_F_HRSP_2XX: + case ST_F_HRSP_3XX: + case ST_F_HRSP_4XX: + case ST_F_HRSP_5XX: + case ST_F_HRSP_OTHER: + if (px->mode != PR_MODE_HTTP) + goto next_px; + if (ctx->field_num != ST_F_HRSP_1XX) + ctx->flags &= ~PROMEX_FL_METRIC_HDR; + labels[1].name = ist("code"); + labels[1].value = promex_hrsp_code[ctx->field_num - ST_F_HRSP_1XX]; + val = stats[ctx->field_num]; + break; + + default: + val = stats[ctx->field_num]; + } + + if (!promex_dump_metric(appctx, htx, prefix, &promex_st_metrics[ctx->field_num], + &val, labels, &out, max)) + goto full; + next_px: + ctx->px = px->next; + } + ctx->flags |= PROMEX_FL_METRIC_HDR; + ctx->px = proxies_list; + } + + end: + if (out.len) { + if (!htx_add_data_atonce(htx, out)) + return -1; /* Unexpected and unrecoverable error */ + channel_add_input(chn, out.len); + } + return ret; + full: + ret = 0; + goto end; +} + +/* Dump servers metrics (prefixed by "haproxy_server_"). It returns 1 on success, + * 0 if is full and -1 in case of any error. */ +static int promex_dump_srv_metrics(struct appctx *appctx, struct htx *htx) +{ + static struct ist prefix = IST("haproxy_server_"); + struct promex_ctx *ctx = appctx->svcctx; + struct proxy *px; + struct server *sv; + struct field val; + struct channel *chn = sc_ic(appctx_sc(appctx)); + struct ist out = ist2(trash.area, 0); + size_t max = htx_get_max_blksz(htx, channel_htx_recv_max(chn, htx)); + struct field *stats = stat_l[STATS_DOMAIN_PROXY]; + int ret = 1; + double secs; + enum promex_srv_state state; + const char *check_state; + + for (;ctx->field_num < ST_F_TOTAL_FIELDS; ctx->field_num++) { + if (!(promex_st_metrics[ctx->field_num].flags & ctx->flags)) + continue; + + while (ctx->px) { + struct promex_label labels[PROMEX_MAX_LABELS-1] = {}; + + px = ctx->px; + + labels[0].name = ist("proxy"); + labels[0].value = ist2(px->id, strlen(px->id)); + + /* skip the disabled proxies, global frontend and non-networked ones */ + if ((px->flags & PR_FL_DISABLED) || px->uuid <= 0 || !(px->cap & PR_CAP_BE)) + goto next_px; + + while (ctx->sv) { + sv = ctx->sv; + + labels[1].name = ist("server"); + labels[1].value = ist2(sv->id, strlen(sv->id)); + + if (!stats_fill_sv_stats(px, sv, 0, stats, ST_F_TOTAL_FIELDS, &(ctx->field_num))) + return -1; + + if ((ctx->flags & PROMEX_FL_NO_MAINT_SRV) && (sv->cur_admin & SRV_ADMF_MAINT)) + goto next_sv; + + switch (ctx->field_num) { + case ST_F_STATUS: + state = promex_srv_status(sv); + for (; ctx->obj_state < PROMEX_SRV_STATE_COUNT; ctx->obj_state++) { + val = mkf_u32(FO_STATUS, state == ctx->obj_state); + labels[2].name = ist("state"); + labels[2].value = promex_srv_st[ctx->obj_state]; + if (!promex_dump_metric(appctx, htx, prefix, &promex_st_metrics[ctx->field_num], + &val, labels, &out, max)) + goto full; + } + ctx->obj_state = 0; + goto next_sv; + case ST_F_QTIME: + secs = (double)swrate_avg(sv->counters.q_time, TIME_STATS_SAMPLES) / 1000.0; + val = mkf_flt(FN_AVG, secs); + break; + case ST_F_CTIME: + secs = (double)swrate_avg(sv->counters.c_time, TIME_STATS_SAMPLES) / 1000.0; + val = mkf_flt(FN_AVG, secs); + break; + case ST_F_RTIME: + secs = (double)swrate_avg(sv->counters.d_time, TIME_STATS_SAMPLES) / 1000.0; + val = mkf_flt(FN_AVG, secs); + break; + case ST_F_TTIME: + secs = (double)swrate_avg(sv->counters.t_time, TIME_STATS_SAMPLES) / 1000.0; + val = mkf_flt(FN_AVG, secs); + break; + case ST_F_QT_MAX: + secs = (double)sv->counters.qtime_max / 1000.0; + val = mkf_flt(FN_MAX, secs); + break; + case ST_F_CT_MAX: + secs = (double)sv->counters.ctime_max / 1000.0; + val = mkf_flt(FN_MAX, secs); + break; + case ST_F_RT_MAX: + secs = (double)sv->counters.dtime_max / 1000.0; + val = mkf_flt(FN_MAX, secs); + break; + case ST_F_TT_MAX: + secs = (double)sv->counters.ttime_max / 1000.0; + val = mkf_flt(FN_MAX, secs); + break; + case ST_F_CHECK_STATUS: + if ((sv->check.state & (CHK_ST_ENABLED|CHK_ST_PAUSED)) != CHK_ST_ENABLED) + goto next_sv; + + for (; ctx->obj_state < HCHK_STATUS_SIZE; ctx->obj_state++) { + if (get_check_status_result(ctx->obj_state) < CHK_RES_FAILED) + continue; + val = mkf_u32(FO_STATUS, sv->check.status == ctx->obj_state); + check_state = get_check_status_info(ctx->obj_state); + labels[2].name = ist("state"); + labels[2].value = ist(check_state); + if (!promex_dump_metric(appctx, htx, prefix, &promex_st_metrics[ctx->field_num], + &val, labels, &out, max)) + goto full; + } + ctx->obj_state = 0; + goto next_sv; + case ST_F_CHECK_CODE: + if ((sv->check.state & (CHK_ST_ENABLED|CHK_ST_PAUSED)) != CHK_ST_ENABLED) + goto next_sv; + val = mkf_u32(FN_OUTPUT, (sv->check.status < HCHK_STATUS_L57DATA) ? 0 : sv->check.code); + break; + case ST_F_CHECK_DURATION: + if (sv->check.status < HCHK_STATUS_CHECKED) + goto next_sv; + secs = (double)sv->check.duration / 1000.0; + val = mkf_flt(FN_DURATION, secs); + break; + case ST_F_REQ_TOT: + if (px->mode != PR_MODE_HTTP) + goto next_px; + val = stats[ctx->field_num]; + break; + case ST_F_HRSP_1XX: + case ST_F_HRSP_2XX: + case ST_F_HRSP_3XX: + case ST_F_HRSP_4XX: + case ST_F_HRSP_5XX: + case ST_F_HRSP_OTHER: + if (px->mode != PR_MODE_HTTP) + goto next_px; + if (ctx->field_num != ST_F_HRSP_1XX) + ctx->flags &= ~PROMEX_FL_METRIC_HDR; + labels[2].name = ist("code"); + labels[2].value = promex_hrsp_code[ctx->field_num - ST_F_HRSP_1XX]; + val = stats[ctx->field_num]; + break; + + default: + val = stats[ctx->field_num]; + } + + if (!promex_dump_metric(appctx, htx, prefix, &promex_st_metrics[ctx->field_num], + &val, labels, &out, max)) + goto full; + next_sv: + ctx->sv = sv->next; + } + + next_px: + ctx->px = px->next; + ctx->sv = (ctx->px ? ctx->px->srv : NULL); + } + ctx->flags |= PROMEX_FL_METRIC_HDR; + ctx->px = proxies_list; + ctx->sv = (ctx->px ? ctx->px->srv : NULL); + } + + + end: + if (out.len) { + if (!htx_add_data_atonce(htx, out)) + return -1; /* Unexpected and unrecoverable error */ + channel_add_input(chn, out.len); + } + return ret; + full: + ret = 0; + goto end; +} + +/* Dump stick table metrics (prefixed by "haproxy_sticktable_"). It returns 1 on success, + * 0 if is full and -1 in case of any error. */ +static int promex_dump_sticktable_metrics(struct appctx *appctx, struct htx *htx) +{ + static struct ist prefix = IST("haproxy_sticktable_"); + struct promex_ctx *ctx = appctx->svcctx; + struct field val; + struct channel *chn = sc_ic(appctx_sc(appctx)); + struct ist out = ist2(trash.area, 0); + size_t max = htx_get_max_blksz(htx, channel_htx_recv_max(chn, htx)); + int ret = 1; + struct stktable *t; + + for (; ctx->field_num < STICKTABLE_TOTAL_FIELDS; ctx->field_num++) { + if (!(promex_sticktable_metrics[ctx->field_num].flags & ctx->flags)) + continue; + + while (ctx->st) { + struct promex_label labels[PROMEX_MAX_LABELS - 1] = {}; + + t = ctx->st; + if (!t->size) + goto next_px; + + labels[0].name = ist("name"); + labels[0].value = ist2(t->id, strlen(t->id)); + labels[1].name = ist("type"); + labels[1].value = ist2(stktable_types[t->type].kw, strlen(stktable_types[t->type].kw)); + switch (ctx->field_num) { + case STICKTABLE_SIZE: + val = mkf_u32(FN_GAUGE, t->size); + break; + case STICKTABLE_USED: + val = mkf_u32(FN_GAUGE, t->current); + break; + default: + goto next_px; + } + + if (!promex_dump_metric(appctx, htx, prefix, + &promex_sticktable_metrics[ctx->field_num], + &val, labels, &out, max)) + goto full; + + next_px: + ctx->st = t->next; + } + ctx->flags |= PROMEX_FL_METRIC_HDR; + ctx->st = stktables_list; + } + + end: + if (out.len) { + if (!htx_add_data_atonce(htx, out)) + return -1; /* Unexpected and unrecoverable error */ + channel_add_input(chn, out.len); + } + return ret; + full: + ret = 0; + goto end; +} + +/* Dump all metrics (global, frontends, backends and servers) depending on the + * dumper state (appctx->st1). It returns 1 on success, 0 if is full and + * -1 in case of any error. + * Uses as a pointer to the current proxy and /
  • + * as pointers to the current server/listener respectively. + */ +static int promex_dump_metrics(struct appctx *appctx, struct stconn *sc, struct htx *htx) +{ + struct promex_ctx *ctx = appctx->svcctx; + int ret; + + switch (appctx->st1) { + case PROMEX_DUMPER_INIT: + ctx->px = NULL; + ctx->st = NULL; + ctx->li = NULL; + ctx->sv = NULL; + ctx->flags |= (PROMEX_FL_METRIC_HDR|PROMEX_FL_INFO_METRIC); + ctx->obj_state = 0; + ctx->field_num = INF_NAME; + appctx->st1 = PROMEX_DUMPER_GLOBAL; + /* fall through */ + + case PROMEX_DUMPER_GLOBAL: + if (ctx->flags & PROMEX_FL_SCOPE_GLOBAL) { + ret = promex_dump_global_metrics(appctx, htx); + if (ret <= 0) { + if (ret == -1) + goto error; + goto full; + } + } + + ctx->px = proxies_list; + ctx->st = NULL; + ctx->li = NULL; + ctx->sv = NULL; + ctx->flags &= ~PROMEX_FL_INFO_METRIC; + ctx->flags |= (PROMEX_FL_METRIC_HDR|PROMEX_FL_FRONT_METRIC); + ctx->obj_state = 0; + ctx->field_num = ST_F_PXNAME; + appctx->st1 = PROMEX_DUMPER_FRONT; + /* fall through */ + + case PROMEX_DUMPER_FRONT: + if (ctx->flags & PROMEX_FL_SCOPE_FRONT) { + ret = promex_dump_front_metrics(appctx, htx); + if (ret <= 0) { + if (ret == -1) + goto error; + goto full; + } + } + + ctx->px = proxies_list; + ctx->st = NULL; + ctx->li = LIST_NEXT(&proxies_list->conf.listeners, struct listener *, by_fe); + ctx->sv = NULL; + ctx->flags &= ~PROMEX_FL_FRONT_METRIC; + ctx->flags |= (PROMEX_FL_METRIC_HDR|PROMEX_FL_LI_METRIC); + ctx->obj_state = 0; + ctx->field_num = ST_F_PXNAME; + appctx->st1 = PROMEX_DUMPER_LI; + /* fall through */ + + case PROMEX_DUMPER_LI: + if (ctx->flags & PROMEX_FL_SCOPE_LI) { + ret = promex_dump_listener_metrics(appctx, htx); + if (ret <= 0) { + if (ret == -1) + goto error; + goto full; + } + } + + ctx->px = proxies_list; + ctx->st = NULL; + ctx->li = NULL; + ctx->sv = NULL; + ctx->flags &= ~PROMEX_FL_LI_METRIC; + ctx->flags |= (PROMEX_FL_METRIC_HDR|PROMEX_FL_BACK_METRIC); + ctx->obj_state = 0; + ctx->field_num = ST_F_PXNAME; + appctx->st1 = PROMEX_DUMPER_BACK; + /* fall through */ + + case PROMEX_DUMPER_BACK: + if (ctx->flags & PROMEX_FL_SCOPE_BACK) { + ret = promex_dump_back_metrics(appctx, htx); + if (ret <= 0) { + if (ret == -1) + goto error; + goto full; + } + } + + ctx->px = proxies_list; + ctx->st = NULL; + ctx->li = NULL; + ctx->sv = ctx->px ? ctx->px->srv : NULL; + ctx->flags &= ~PROMEX_FL_BACK_METRIC; + ctx->flags |= (PROMEX_FL_METRIC_HDR|PROMEX_FL_SRV_METRIC); + ctx->obj_state = 0; + ctx->field_num = ST_F_PXNAME; + appctx->st1 = PROMEX_DUMPER_SRV; + /* fall through */ + + case PROMEX_DUMPER_SRV: + if (ctx->flags & PROMEX_FL_SCOPE_SERVER) { + ret = promex_dump_srv_metrics(appctx, htx); + if (ret <= 0) { + if (ret == -1) + goto error; + goto full; + } + } + + ctx->px = NULL; + ctx->st = stktables_list; + ctx->li = NULL; + ctx->sv = NULL; + ctx->flags &= ~(PROMEX_FL_METRIC_HDR|PROMEX_FL_SRV_METRIC); + ctx->flags |= (PROMEX_FL_METRIC_HDR|PROMEX_FL_STICKTABLE_METRIC); + ctx->field_num = STICKTABLE_SIZE; + appctx->st1 = PROMEX_DUMPER_STICKTABLE; + /* fall through */ + + case PROMEX_DUMPER_STICKTABLE: + if (ctx->flags & PROMEX_FL_SCOPE_STICKTABLE) { + ret = promex_dump_sticktable_metrics(appctx, htx); + if (ret <= 0) { + if (ret == -1) + goto error; + goto full; + } + } + + ctx->px = NULL; + ctx->st = NULL; + ctx->li = NULL; + ctx->sv = NULL; + ctx->flags &= ~(PROMEX_FL_METRIC_HDR|PROMEX_FL_STICKTABLE_METRIC); + ctx->field_num = 0; + appctx->st1 = PROMEX_DUMPER_DONE; + /* fall through */ + + case PROMEX_DUMPER_DONE: + default: + break; + } + + return 1; + + full: + sc_need_room(sc); + return 0; + error: + /* unrecoverable error */ + ctx->px = NULL; + ctx->st = NULL; + ctx->li = NULL; + ctx->sv = NULL; + ctx->flags = 0; + ctx->field_num = 0; + appctx->st1 = PROMEX_DUMPER_DONE; + return -1; +} + +/* Parse the query string of request URI to filter the metrics. It returns 1 on + * success and -1 on error. */ +static int promex_parse_uri(struct appctx *appctx, struct stconn *sc) +{ + struct promex_ctx *ctx = appctx->svcctx; + struct channel *req = sc_oc(sc); + struct channel *res = sc_ic(sc); + struct htx *req_htx, *res_htx; + struct htx_sl *sl; + char *p, *key, *value; + const char *end; + struct buffer *err; + int default_scopes = PROMEX_FL_SCOPE_ALL; + int len; + + /* Get the query-string */ + req_htx = htxbuf(&req->buf); + sl = http_get_stline(req_htx); + if (!sl) + goto error; + p = http_find_param_list(HTX_SL_REQ_UPTR(sl), HTX_SL_REQ_ULEN(sl), '?'); + if (!p) + goto end; + end = HTX_SL_REQ_UPTR(sl) + HTX_SL_REQ_ULEN(sl); + + /* copy the query-string */ + len = end - p; + chunk_reset(&trash); + memcpy(trash.area, p, len); + trash.area[len] = 0; + p = trash.area; + end = trash.area + len; + + /* Parse the query-string */ + while (p < end && *p && *p != '#') { + value = NULL; + + /* decode parameter name */ + key = p; + while (p < end && *p != '=' && *p != '&' && *p != '#') + ++p; + /* found a value */ + if (*p == '=') { + *(p++) = 0; + value = p; + } + else if (*p == '&') + *(p++) = 0; + else if (*p == '#') + *p = 0; + len = url_decode(key, 1); + if (len == -1) + goto error; + + /* decode value */ + if (value) { + while (p < end && *p != '=' && *p != '&' && *p != '#') + ++p; + if (*p == '=') + goto error; + if (*p == '&') + *(p++) = 0; + else if (*p == '#') + *p = 0; + len = url_decode(value, 1); + if (len == -1) + goto error; + } + + if (strcmp(key, "scope") == 0) { + default_scopes = 0; /* at least a scope defined, unset default scopes */ + if (!value) + goto error; + else if (*value == 0) + ctx->flags &= ~PROMEX_FL_SCOPE_ALL; + else if (*value == '*') + ctx->flags |= PROMEX_FL_SCOPE_ALL; + else if (strcmp(value, "global") == 0) + ctx->flags |= PROMEX_FL_SCOPE_GLOBAL; + else if (strcmp(value, "server") == 0) + ctx->flags |= PROMEX_FL_SCOPE_SERVER; + else if (strcmp(value, "backend") == 0) + ctx->flags |= PROMEX_FL_SCOPE_BACK; + else if (strcmp(value, "frontend") == 0) + ctx->flags |= PROMEX_FL_SCOPE_FRONT; + else if (strcmp(value, "listener") == 0) + ctx->flags |= PROMEX_FL_SCOPE_LI; + else if (strcmp(value, "sticktable") == 0) + ctx->flags |= PROMEX_FL_SCOPE_STICKTABLE; + else + goto error; + } + else if (strcmp(key, "no-maint") == 0) + ctx->flags |= PROMEX_FL_NO_MAINT_SRV; + } + + end: + ctx->flags |= default_scopes; + return 1; + + error: + err = &http_err_chunks[HTTP_ERR_400]; + channel_erase(res); + res->buf.data = b_data(err); + memcpy(res->buf.area, b_head(err), b_data(err)); + res_htx = htx_from_buf(&res->buf); + channel_add_input(res, res_htx->data); + appctx->st0 = PROMEX_ST_END; + return -1; +} + +/* Send HTTP headers of the response. It returns 1 on success and 0 if is + * full. */ +static int promex_send_headers(struct appctx *appctx, struct stconn *sc, struct htx *htx) +{ + struct channel *chn = sc_ic(sc); + struct htx_sl *sl; + unsigned int flags; + + flags = (HTX_SL_F_IS_RESP|HTX_SL_F_VER_11|HTX_SL_F_XFER_ENC|HTX_SL_F_XFER_LEN|HTX_SL_F_CHNK); + sl = htx_add_stline(htx, HTX_BLK_RES_SL, flags, ist("HTTP/1.1"), ist("200"), ist("OK")); + if (!sl) + goto full; + sl->info.res.status = 200; + if (!htx_add_header(htx, ist("Cache-Control"), ist("no-cache")) || + !htx_add_header(htx, ist("Content-Type"), ist("text/plain; version=0.0.4")) || + !htx_add_header(htx, ist("Transfer-Encoding"), ist("chunked")) || + !htx_add_endof(htx, HTX_BLK_EOH)) + goto full; + + channel_add_input(chn, htx->data); + return 1; + full: + htx_reset(htx); + sc_need_room(sc); + return 0; +} + +/* The function returns 1 if the initialisation is complete, 0 if + * an errors occurs and -1 if more data are required for initializing + * the applet. + */ +static int promex_appctx_init(struct appctx *appctx) +{ + applet_reserve_svcctx(appctx, sizeof(struct promex_ctx)); + appctx->st0 = PROMEX_ST_INIT; + return 0; +} + +/* The main I/O handler for the promex applet. */ +static void promex_appctx_handle_io(struct appctx *appctx) +{ + struct stconn *sc = appctx_sc(appctx); + struct stream *s = __sc_strm(sc); + struct channel *req = sc_oc(sc); + struct channel *res = sc_ic(sc); + struct htx *req_htx, *res_htx; + int ret; + + res_htx = htx_from_buf(&res->buf); + if (unlikely(sc->state == SC_ST_DIS || sc->state == SC_ST_CLO)) + goto out; + + /* Check if the input buffer is available. */ + if (!b_size(&res->buf)) { + sc_need_room(sc); + goto out; + } + + switch (appctx->st0) { + case PROMEX_ST_INIT: + ret = promex_parse_uri(appctx, sc); + if (ret <= 0) { + if (ret == -1) + goto error; + goto out; + } + appctx->st0 = PROMEX_ST_HEAD; + appctx->st1 = PROMEX_DUMPER_INIT; + /* fall through */ + + case PROMEX_ST_HEAD: + if (!promex_send_headers(appctx, sc, res_htx)) + goto out; + appctx->st0 = ((s->txn->meth == HTTP_METH_HEAD) ? PROMEX_ST_DONE : PROMEX_ST_DUMP); + /* fall through */ + + case PROMEX_ST_DUMP: + ret = promex_dump_metrics(appctx, sc, res_htx); + if (ret <= 0) { + if (ret == -1) + goto error; + goto out; + } + appctx->st0 = PROMEX_ST_DONE; + /* fall through */ + + case PROMEX_ST_DONE: + /* no more data are expected. If the response buffer is + * empty, be sure to add something (EOT block in this + * case) to have something to send. It is important to + * be sure the EOM flags will be handled by the + * endpoint. + */ + if (htx_is_empty(res_htx)) { + if (!htx_add_endof(res_htx, HTX_BLK_EOT)) { + sc_need_room(sc); + goto out; + } + channel_add_input(res, 1); + } + res_htx->flags |= HTX_FL_EOM; + res->flags |= CF_EOI; + se_fl_set(appctx->sedesc, SE_FL_EOI); + appctx->st0 = PROMEX_ST_END; + /* fall through */ + + case PROMEX_ST_END: + if (!(res->flags & CF_SHUTR)) { + res->flags |= CF_READ_NULL; + sc_shutr(sc); + } + } + + out: + htx_to_buf(res_htx, &res->buf); + + /* eat the whole request */ + if (co_data(req)) { + req_htx = htx_from_buf(&req->buf); + co_htx_skip(req, req_htx, co_data(req)); + } + return; + + error: + res->flags |= CF_READ_NULL; + sc_shutr(sc); + sc_shutw(sc); + goto out; +} + +struct applet promex_applet = { + .obj_type = OBJ_TYPE_APPLET, + .name = "", /* used for logging */ + .init = promex_appctx_init, + .fct = promex_appctx_handle_io, +}; + +static enum act_parse_ret service_parse_prometheus_exporter(const char **args, int *cur_arg, struct proxy *px, + struct act_rule *rule, char **err) +{ + /* Prometheus exporter service is only available on "http-request" rulesets */ + if (rule->from != ACT_F_HTTP_REQ) { + memprintf(err, "Prometheus exporter service only available on 'http-request' rulesets"); + return ACT_RET_PRS_ERR; + } + + /* Add applet pointer in the rule. */ + rule->applet = promex_applet; + + return ACT_RET_PRS_OK; +} +static void promex_register_build_options(void) +{ + char *ptr = NULL; + + memprintf(&ptr, "Built with the Prometheus exporter as a service"); + hap_register_build_opts(ptr, 1); +} + + +static struct action_kw_list service_actions = { ILH, { + { "prometheus-exporter", service_parse_prometheus_exporter }, + { /* END */ } +}}; + +INITCALL1(STG_REGISTER, service_keywords_register, &service_actions); +INITCALL0(STG_REGISTER, promex_register_build_options); diff --git a/addons/wurfl/dummy/Makefile b/addons/wurfl/dummy/Makefile new file mode 100644 index 0000000..df08288 --- /dev/null +++ b/addons/wurfl/dummy/Makefile @@ -0,0 +1,13 @@ +# makefile for dummy wurfl library +# builds shared library +# installs it in /usr/lib/ with header file wurfl.h in /usr/include/wurfl +# +# install needs to be run as root + +build: libwurfl.a + +libwurfl.a: dummy-wurfl.o + ar rv $@ $< + +clean: + rm -rf *.a *.o diff --git a/addons/wurfl/dummy/dummy-wurfl.c b/addons/wurfl/dummy/dummy-wurfl.c new file mode 100644 index 0000000..0d5f068 --- /dev/null +++ b/addons/wurfl/dummy/dummy-wurfl.c @@ -0,0 +1,126 @@ +/* + * InFuze C API - HAPROXY Dummy library version of include + * + * Author : Paul Stephen Borile, Mon Apr 8, 2019 + * Copyright (c) ScientiaMobile, Inc. + * http://www.scientiamobile.com + * + * This is a dummy implementation of the wurfl C API that builds and runs + * like the normal API simply without returning device detection data + * + * + */ + +#include "wurfl/wurfl.h" + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" + +const char *wurfl_get_api_version(void) +{ + return "1.11.2.100"; // 100 indicates the dummy +} + +wurfl_handle wurfl_create(void) +{ + return (void*) 0xbeffa; +} + +void wurfl_destroy(wurfl_handle handle) +{ + return; +} + +wurfl_error wurfl_set_root(wurfl_handle hwurfl, const char* root) +{ + return WURFL_OK; +} +wurfl_error wurfl_add_patch(wurfl_handle hwurfl, const char *patch) +{ + return WURFL_OK; +} + +wurfl_error wurfl_add_requested_capability(wurfl_handle hwurfl, const char *requested_capability) +{ + return WURFL_OK; +} + +const char *wurfl_get_error_message(wurfl_handle hwurfl) +{ + return "wurfl dummy library error message"; +} + +int wurfl_has_virtual_capability(wurfl_handle hwurfl, const char *virtual_capability) +{ + return 0; +} + +wurfl_error wurfl_set_cache_provider(wurfl_handle hwurfl, wurfl_cache_provider cache_provider, const char *config) +{ + return WURFL_OK; +} + +wurfl_error wurfl_load(wurfl_handle hwurfl) +{ + return WURFL_OK; +} + +wurfl_device_handle wurfl_lookup(wurfl_handle hwurfl, wurfl_header_retrieve_callback header_retrieve_callback, const void *header_retrieve_callback_data) +{ + // call callback, on a probably existing header + const char *hvalue = header_retrieve_callback("User-Agent", header_retrieve_callback_data); + // and on a non existing one + hvalue = header_retrieve_callback("Non-Existing-Header", header_retrieve_callback_data); + (void)hvalue; + return (void *) 0xdeffa; +} + +const char *wurfl_device_get_capability(wurfl_device_handle hwurfldevice, const char *capability) +{ + return "dummy_cap_val"; +} + +const char *wurfl_device_get_virtual_capability(wurfl_device_handle hwurfldevice, const char *capability) +{ + return "dummy_vcap_val"; +} + +void wurfl_device_destroy(wurfl_device_handle handle) +{ + return; +} + +const char *wurfl_device_get_id(wurfl_device_handle hwurfldevice) +{ + return "generic_dummy_device"; +} + +const char *wurfl_device_get_root_id(wurfl_device_handle hwurfldevice) +{ + return "generic_dummy_device"; +} + +const char *wurfl_device_get_original_useragent(wurfl_device_handle hwurfldevice) +{ + return "original_useragent"; +} +const char *wurfl_device_get_normalized_useragent(wurfl_device_handle hwurfldevice) +{ + return "normalized_useragent"; +} +int wurfl_device_is_actual_device_root(wurfl_device_handle hwurfldevice) +{ + return 1; +} + +const char *wurfl_get_wurfl_info(wurfl_handle hwurfl) +{ + return "dummy wurfl info"; +} + +const char *wurfl_get_last_load_time_as_string(wurfl_handle hwurfl) +{ + return "dummy wurfl last load time"; +} + +#pragma GCC diagnostic pop diff --git a/addons/wurfl/dummy/wurfl/wurfl.h b/addons/wurfl/dummy/wurfl/wurfl.h new file mode 100644 index 0000000..7659561 --- /dev/null +++ b/addons/wurfl/dummy/wurfl/wurfl.h @@ -0,0 +1,409 @@ +/* + * InFuze C API - HAPROXY Dummy library version of include + * + * Copyright (c) ScientiaMobile, Inc. + * http://www.scientiamobile.com + * + * This software package is the property of ScientiaMobile Inc. and is distributed under + * a dual licensing scheme: + * + * 1) commercially according to a contract between the Licensee and ScientiaMobile Inc. (Licensor). + * If you represent the Licensee, please refer to the licensing agreement which has been signed + * between the two parties. If you do not represent the Licensee, you are not authorized to use + * this software in any way. + * + * 2) LGPL when used in the context of the HAProxy project with the purpose of testing compatibility + * of HAProxy with ScientiaMobile software. + * + */ + +#ifndef _WURFL_H_ +#define _WURFL_H_ + +#include + +#if defined (__GNUC__) || defined (__clang__) +#define DEPRECATED __attribute__((deprecated)) +#elif defined(_MSC_VER) +#define DEPRECATED __declspec(deprecated) +#else +#pragma message("WARNING: You need to implement DEPRECATED for this compiler") +#define DEPRECATED +#endif + +// WURFL error enumeration +typedef enum { + WURFL_OK = 0, //!< no error + WURFL_ERROR_INVALID_HANDLE = 1, //!< handle passed to the function is invalid + WURFL_ERROR_ALREADY_LOAD = 2, //!< wurfl_load has already been invoked on the specific wurfl_handle + WURFL_ERROR_FILE_NOT_FOUND = 3, //!< file not found during wurfl_load or remote data file update + WURFL_ERROR_UNEXPECTED_END_OF_FILE = 4, //!< unexpected end of file or parsing error during wurfl_load + WURFL_ERROR_INPUT_OUTPUT_FAILURE = 5, //!< error reading stream during wurfl_load or updater accessing local updated data file + WURFL_ERROR_DEVICE_NOT_FOUND = 6, //!< specified device is missing + WURFL_ERROR_CAPABILITY_NOT_FOUND = 7, //!< specified capability is missing + WURFL_ERROR_INVALID_CAPABILITY_VALUE = 8, //!< invalid capability value + WURFL_ERROR_VIRTUAL_CAPABILITY_NOT_FOUND = 9, //!< specified virtual capability is missing + WURFL_ERROR_CANT_LOAD_CAPABILITY_NOT_FOUND = 10, //!< specified capability is missing + WURFL_ERROR_CANT_LOAD_VIRTUAL_CAPABILITY_NOT_FOUND = 11, //!< specified virtual capability is missing + WURFL_ERROR_EMPTY_ID = 12, //!< missing id in searching device + WURFL_ERROR_CAPABILITY_GROUP_NOT_FOUND = 13, //!< specified capability is missing in its group + WURFL_ERROR_CAPABILITY_GROUP_MISMATCH = 14, //!< specified capability mismatch in its group + WURFL_ERROR_DEVICE_ALREADY_DEFINED = 15, //!< specified device is already defined + WURFL_ERROR_USERAGENT_ALREADY_DEFINED = 16, //!< specified user agent is already defined + WURFL_ERROR_DEVICE_HIERARCHY_CIRCULAR_REFERENCE = 17, //!< circular reference in device hierarchy + WURFL_ERROR_UNKNOWN = 18, //!< unknown error + WURFL_ERROR_INVALID_USERAGENT_PRIORITY = 19, //!< specified override sideloaded browser user agent configuration not valid + WURFL_ERROR_INVALID_PARAMETER = 20, //!< invalid parameter + WURFL_ERROR_INVALID_CACHE_SIZE = 21, //!< specified an invalid cache size, 0 or a negative value. + WURFL_ERROR_XML_CONSISTENCY = 22, //!< WURFL data file is out of date or wrong - some needed device_id/capability is missing + WURFL_ERROR_INTERNAL = 23, //!< internal error. If this is an updater issue, please enable and check updater log using wurfl_updater_set_log_path() + WURFL_ERROR_VIRTUAL_CAPABILITY_NOT_AVAILABLE = 24, //!< the requested virtual capability has not been licensed + WURFL_ERROR_MISSING_USERAGENT = 25, // an XML device definition without mandatory UA has been detected + WURFL_ERROR_XML_PARSE = 26, // the XML data file is malformed + WURFL_ERROR_UPDATER_INVALID_DATA_URL = 27, // updater data URL is missing or invalid (note: only .zip and .gz formats allowed) + WURFL_ERROR_UPDATER_INVALID_LICENSE = 28, // client license is invalid, expired etc + WURFL_ERROR_UPDATER_NETWORK_ERROR = 29, // updater request returned an HTTP response != 200, or SSL error, etc. Please enable and check updater log using wurfl_updater_set_log_path() + WURFL_ERROR_ENGINE_NOT_INITIALIZED = 30, // prerequisite for executing an update is that the engine has been initialized (i.e., wurfl_load() has been called) + WURFL_ERROR_UPDATER_ALREADY_RUNNING = 31, // wurfl_updater_start() can be called just once, when the updater is not running + WURFL_ERROR_UPDATER_NOT_RUNNING = 32, // wurfl_updater_stop() can be called just once, when the updater is running + WURFL_ERROR_UPDATER_TOO_MANY_REQUESTS = 33, // Updater encountered HTTP 429 error + WURFL_ERROR_UPDATER_CMDLINE_DOWNLOADER_UNAVAILABLE = 34, // Curl executable not found. Please check path, etc + WURFL_ERROR_UPDATER_TIMEDOUT = 35, // Curl operation timed out. + WURFL_ERROR_ROOT_NOT_SET = 36, // set_root() must be called before any load() / reload() and update attempt + WURFL_ERROR_WRONG_ENGINE_TARGET = 37, // set_engine_target() was called with a wrong/unrecognized parameter + // new errors added in + + WURFL_ERROR_CANNOT_FILTER_STATIC_CAP = 38, + WURFL_ENGINE_UNABLE_TO_ALLOCATE_MEMORY = 39, + WURFL_ENGINE_NOT_LOADED = 40, + WURFL_ERROR_UPDATER_CANNOT_START_THREAD = 41, + WURFL_ERROR_ENUM_EMPTY_SET = 42, + + // update when adding errors + WURFL_ERROR_LAST = 43 +} wurfl_error; + +typedef enum { + WURFL_ENGINE_TARGET_HIGH_ACCURACY = 0, + WURFL_ENGINE_TARGET_HIGH_PERFORMANCE = 1, + WURFL_ENGINE_TARGET_DEFAULT = 2, + WURFL_ENGINE_TARGET_FAST_DESKTOP_BROWSER_MATCH = 3, +} wurfl_engine_target; + +typedef enum { + WURFL_USERAGENT_PRIORITY_OVERRIDE_SIDELOADED_BROWSER_USERAGENT, + WURFL_USERAGENT_PRIORITY_USE_PLAIN_USERAGENT, + WURFL_USERAGENT_PRIORITY_INVALID, +} wurfl_useragent_priority; + +typedef enum { + WURFL_CACHE_PROVIDER_NONE, + WURFL_CACHE_PROVIDER_LRU, + WURFL_CACHE_PROVIDER_DOUBLE_LRU, +} wurfl_cache_provider; + +typedef enum { + WURFL_MATCH_TYPE_EXACT = 0, + WURFL_MATCH_TYPE_CONCLUSIVE = 1, + WURFL_MATCH_TYPE_RECOVERY = 2, + WURFL_MATCH_TYPE_CATCHALL = 3, + WURFL_MATCH_TYPE_HIGHPERFORMANCE = 4, // deprecated. See hereunder. + WURFL_MATCH_TYPE_NONE = 5, + WURFL_MATCH_TYPE_CACHED = 6, + WURFL_MATCH_TYPE_FAST_DESKTOP_BROWSER_MATCH = 7 +} wurfl_match_type; + + +typedef enum { + WURFL_UPDATER_FREQ_DAILY = 0, + WURFL_UPDATER_FREQ_WEEKLY = 1, +} wurfl_updater_frequency; + + +#ifdef __cplusplus +extern "C" { +#endif + +// typedef struct _we_h * wurfl_handle; +// typedef struct _en_t * wurfl_enum_handle; +// typedef struct _en_t * wurfl_device_capability_enumerator_handle; +// typedef struct _en_t * wurfl_capability_enumerator_handle; +// typedef struct _en_t * wurfl_device_id_enumerator_handle; +// typedef struct _md_t * wurfl_device_handle; + +typedef void * wurfl_handle; +typedef void * wurfl_enum_handle; +typedef void * wurfl_device_capability_enumerator_handle; +typedef void * wurfl_capability_enumerator_handle; +typedef void * wurfl_device_id_enumerator_handle; +typedef void * wurfl_device_handle; + +const char *wurfl_get_api_version(void); +wurfl_handle wurfl_create(void); +void wurfl_destroy(wurfl_handle handle); + +// NEW : enable/set api logfile +wurfl_error wurfl_set_log_path(wurfl_handle hwurfl, const char *log_path); +// allow writing user stuff on logs : mesg will be prepended by a "USER LOG :" string +wurfl_error wurfl_log_print(wurfl_handle hwurfl, char *msg); + +// Errors + +const char *wurfl_get_error_message(wurfl_handle hwurfl); +wurfl_error wurfl_get_error_code(wurfl_handle hwurfl); +int wurfl_has_error_message(wurfl_handle hwurfl); +// deprecated +void wurfl_clear_error_message(wurfl_handle hwurfl); + +const char *wurfl_get_wurfl_info(wurfl_handle hwurfl); +wurfl_error wurfl_set_root(wurfl_handle hwurfl, const char* root); +wurfl_error wurfl_add_patch(wurfl_handle hwurfl, const char *patch); +wurfl_error wurfl_add_requested_capability(wurfl_handle hwurfl, const char *requested_capability); +DEPRECATED wurfl_error wurfl_set_engine_target(wurfl_handle hwurfl, wurfl_engine_target target); +DEPRECATED wurfl_engine_target wurfl_get_engine_target(wurfl_handle hwurfl); +DEPRECATED const char *wurfl_get_engine_target_as_string(wurfl_handle hwurfl); +DEPRECATED wurfl_error wurfl_set_useragent_priority(wurfl_handle hwurfl, wurfl_useragent_priority useragent_priority); +DEPRECATED wurfl_useragent_priority wurfl_get_useragent_priority(wurfl_handle hwurfl); +DEPRECATED const char *wurfl_get_useragent_priority_as_string(wurfl_handle hwurfl); +wurfl_error wurfl_set_cache_provider(wurfl_handle hwurfl, wurfl_cache_provider cache_provider, const char *config); +wurfl_error wurfl_load(wurfl_handle hwurfl); +struct tm *wurfl_get_last_load_time(wurfl_handle hwurfl); +const char *wurfl_get_last_load_time_as_string(wurfl_handle hwurfl); +int wurfl_has_capability(wurfl_handle hwurfl, const char *capability); +int wurfl_has_virtual_capability(wurfl_handle hwurfl, const char *virtual_capability); + +/* + * enumerators + */ + +/* + * new enumerators implementation + * + * a selector is used to indicate which enumerator we needed + WURFL_ENUM_VIRTUAL_CAPABILITIES, WURFL_ENUM_STATIC_CAPABILITIES, WURFL_ENUM_MANDATORY_CAPABILITIES, WURFL_ENUM_WURFLID, + */ + +typedef enum { + WURFL_ENUM_STATIC_CAPABILITIES, + WURFL_ENUM_VIRTUAL_CAPABILITIES, + WURFL_ENUM_MANDATORY_CAPABILITIES, + WURFL_ENUM_WURFLID, +} wurfl_enum_type; + +wurfl_enum_handle wurfl_enum_create(wurfl_handle, wurfl_enum_type); +const char *wurfl_enum_get_name(wurfl_enum_handle handle); +int wurfl_enum_is_valid(wurfl_enum_handle handle); +void wurfl_enum_move_next(wurfl_enum_handle handle); +void wurfl_enum_destroy(wurfl_enum_handle handle); + +/* deprecated enumerators */ +// virtual caps +//DEPRECATED wurfl_capability_enumerator_handle wurfl_get_virtual_capability_enumerator(wurfl_handle hwurfl); +wurfl_capability_enumerator_handle wurfl_get_virtual_capability_enumerator(wurfl_handle hwurfl); + +// all mandatories +//DEPRECATED wurfl_capability_enumerator_handle wurfl_get_mandatory_capability_enumerator(wurfl_handle hwurfl); +wurfl_capability_enumerator_handle wurfl_get_mandatory_capability_enumerator(wurfl_handle hwurfl); + +// all capabilities +//DEPRECATED wurfl_capability_enumerator_handle wurfl_get_capability_enumerator(wurfl_handle hwurfl); +wurfl_capability_enumerator_handle wurfl_get_capability_enumerator(wurfl_handle hwurfl); +//DEPRECATED const char *wurfl_capability_enumerator_get_name(wurfl_capability_enumerator_handle hwurflcapabilityenumeratorhandle); +const char *wurfl_capability_enumerator_get_name(wurfl_capability_enumerator_handle hwurflcapabilityenumeratorhandle); +//DEPRECATED int wurfl_capability_enumerator_is_valid(wurfl_capability_enumerator_handle handle); +int wurfl_capability_enumerator_is_valid(wurfl_capability_enumerator_handle handle); +//DEPRECATED void wurfl_capability_enumerator_move_next(wurfl_capability_enumerator_handle handle); +void wurfl_capability_enumerator_move_next(wurfl_capability_enumerator_handle handle); +//DEPRECATED void wurfl_capability_enumerator_destroy(wurfl_capability_enumerator_handle handle); +void wurfl_capability_enumerator_destroy(wurfl_capability_enumerator_handle handle); + +// device id enumerator +//DEPRECATED wurfl_device_id_enumerator_handle wurfl_get_device_id_enumerator(wurfl_handle hwurfl); +wurfl_device_id_enumerator_handle wurfl_get_device_id_enumerator(wurfl_handle hwurfl); +//DEPRECATED const char *wurfl_device_id_enumerator_get_device_id(wurfl_device_id_enumerator_handle hwurfldeviceidenumeratorhandle); +const char *wurfl_device_id_enumerator_get_device_id(wurfl_device_id_enumerator_handle hwurfldeviceidenumeratorhandle); +//DEPRECATED int wurfl_device_id_enumerator_is_valid(wurfl_device_id_enumerator_handle handle); +int wurfl_device_id_enumerator_is_valid(wurfl_device_id_enumerator_handle handle); +//DEPRECATED void wurfl_device_id_enumerator_move_next(wurfl_device_id_enumerator_handle handle); +void wurfl_device_id_enumerator_move_next(wurfl_device_id_enumerator_handle handle); +//DEPRECATED void wurfl_device_id_enumerator_destroy(wurfl_device_id_enumerator_handle handle); +void wurfl_device_id_enumerator_destroy(wurfl_device_id_enumerator_handle handle); + +/* + * deprecated device enumerators + */ + +//DEPRECATED wurfl_device_capability_enumerator_handle wurfl_device_get_capability_enumerator(wurfl_device_handle hwurfldevice); +wurfl_device_capability_enumerator_handle wurfl_device_get_capability_enumerator(wurfl_device_handle hwurfldevice); +//DEPRECATED wurfl_device_capability_enumerator_handle wurfl_device_get_virtual_capability_enumerator(wurfl_device_handle hwurfldevice); +wurfl_device_capability_enumerator_handle wurfl_device_get_virtual_capability_enumerator(wurfl_device_handle hwurfldevice); +//DEPRECATED const char *wurfl_device_capability_enumerator_get_name(wurfl_device_capability_enumerator_handle); +const char *wurfl_device_capability_enumerator_get_name(wurfl_device_capability_enumerator_handle); +//DEPRECATED int wurfl_device_capability_enumerator_is_valid(wurfl_device_capability_enumerator_handle); +int wurfl_device_capability_enumerator_is_valid(wurfl_device_capability_enumerator_handle); +//DEPRECATED void wurfl_device_capability_enumerator_move_next(wurfl_device_capability_enumerator_handle); +void wurfl_device_capability_enumerator_move_next(wurfl_device_capability_enumerator_handle); +//DEPRECATED void wurfl_device_capability_enumerator_destroy(wurfl_device_capability_enumerator_handle); +void wurfl_device_capability_enumerator_destroy(wurfl_device_capability_enumerator_handle); + +//DEPRECATED const char *wurfl_device_capability_enumerator_get_value(wurfl_device_capability_enumerator_handle); +const char *wurfl_device_capability_enumerator_get_value(wurfl_device_capability_enumerator_handle); +//DEPRECATED int wurfl_device_capability_enumerator_get_value_as_int(wurfl_device_capability_enumerator_handle hwurfldevicecapabilityenumeratorhandle); +int wurfl_device_capability_enumerator_get_value_as_int(wurfl_device_capability_enumerator_handle hwurfldevicecapabilityenumeratorhandle); +//DEPRECATED int wurfl_device_capability_enumerator_get_value_as_bool(wurfl_device_capability_enumerator_handle hwurfldevicecapabilityenumeratorhandle); +int wurfl_device_capability_enumerator_get_value_as_bool(wurfl_device_capability_enumerator_handle hwurfldevicecapabilityenumeratorhandle); + + +/* + * Device lookup methods + */ + +typedef const char *(*wurfl_header_retrieve_callback)(const char *header_name, const void *callback_data); + +wurfl_device_handle wurfl_lookup(wurfl_handle hwurfl, wurfl_header_retrieve_callback header_retrieve_callback, const void *header_retrieve_callback_data); +wurfl_device_handle wurfl_lookup_useragent(wurfl_handle hwurfl, const char *useragent); +wurfl_device_handle wurfl_get_device(wurfl_handle hwurfl, const char *deviceid); +wurfl_device_handle wurfl_get_device_with_headers(wurfl_handle hwurfl, const char *deviceid, wurfl_header_retrieve_callback header_retrieve_callback, const void *header_retrieve_callback_data); + +/* + * device related methods + */ + +const char *wurfl_device_get_id(wurfl_device_handle hwurfldevice); +const char *wurfl_device_get_root_id(wurfl_device_handle hwurfldevice); +const char *wurfl_device_get_useragent(wurfl_device_handle hwurfldevice); +const char *wurfl_device_get_original_useragent(wurfl_device_handle hwurfldevice); +const char *wurfl_device_get_normalized_useragent(wurfl_device_handle hwurfldevice); +int wurfl_device_is_actual_device_root(wurfl_device_handle hwurfldevice); +wurfl_match_type wurfl_device_get_match_type(wurfl_device_handle hwurfldevice); +const char *wurfl_device_get_matcher_name(wurfl_device_handle hwurfldevice); +const char *wurfl_device_get_bucket_matcher_name(wurfl_device_handle hwurfldevice); +void wurfl_device_destroy(wurfl_device_handle handle); + + +/* + * static capability, virtual capability methods + */ + +int wurfl_device_has_capability(wurfl_device_handle hwurfldevice, const char *capability); + +const char *wurfl_device_get_capability(wurfl_device_handle hwurfldevice, const char *capability); +int wurfl_device_get_capability_as_int(wurfl_device_handle hwurfldevice, const char *capability); +int wurfl_device_get_capability_as_bool(wurfl_device_handle hwurfldevice, const char *capability); + +int wurfl_device_has_virtual_capability(wurfl_device_handle hwurfldevice, const char *capability); + +const char *wurfl_device_get_virtual_capability(wurfl_device_handle hwurfldevice, const char *capability); +int wurfl_device_get_virtual_capability_as_int(wurfl_device_handle hwurfldevice, const char *capability); +int wurfl_device_get_virtual_capability_as_bool(wurfl_device_handle hwurfldevice, const char *capability); + +/* + * static capability, virtual capability NEW methods + */ + +const char *wurfl_device_get_static_cap(wurfl_device_handle hwdev, const char *cap, wurfl_error *err); +int wurfl_device_get_static_cap_as_int(wurfl_device_handle hwdev, const char *cap, wurfl_error *err); +int wurfl_device_get_static_cap_as_bool(wurfl_device_handle hwdev, const char *cap, wurfl_error *err); + +const char *wurfl_device_get_virtual_cap(wurfl_device_handle hwdev, const char *vcap, wurfl_error *err); +int wurfl_device_get_virtual_cap_as_int(wurfl_device_handle hwdev, const char *vcap, wurfl_error *err); +int wurfl_device_get_virtual_cap_as_bool(wurfl_device_handle hwdev, const char *vcap, wurfl_error *err); + +/* + * Updater methods + */ + +// Instruct the updater module to log to file any operation/error. If not used, the updater will not log anything. +// Returns: WURLF_OK if no errors, WURFL_ERROR_INPUT_OUTPUT_FAILURE if the log file cannot be created (no write access rights?) +// or if you try to reopen the log file anywhere else, i.e. this call can be made just once, any attempt to reopen a different log file will fail. +wurfl_error wurfl_updater_set_log_path(wurfl_handle hwurfl, const char *log_path); + +// Set remote data file URL for downloading via internal updater. Will execute various validation tests +// eventually returning WURFL_ERROR_UPDATER_XXX errors for various error conditions and logging detailed infos if +// update logger is enabled. +wurfl_error wurfl_updater_set_data_url(wurfl_handle hwurfl, const char *data_url); + +// Set the updater frequency of automatic updates. Will run a background task with given update frequency. +wurfl_error wurfl_updater_set_data_frequency(wurfl_handle hwurfl, wurfl_updater_frequency freq); + +// Set updater timeouts. +// There are two timeouts, both in milliseconds : connection timeout and operation timeout. +// The values are mapped to CURL --connect-timeout and --max-time parameters +// (after millisecs-to-secs conversion). Note that CURL sub millisecond timeouts don't work for +// lack of a way to specify decimal values for timeout to curl (using 0.05 for example fails to work +// on docker machines with "POSIX" locale installed. +// Connection timeout has a default value of 10 seconds (10000 ms) and refers only to connection phase. Passing 0 will use CURL value "no timeout used". +// Data transfer timeout has a default value of 600 seconds (600000 ms). Passing 0 will use CURL default value "no timeout used" +// So, pass 0 to either parameter to set it to "no timeout used" +// Pass -1 to either parameter to use default values (10 secs, 600 secs) +// The specified timeouts (if any) are used just in the synchronous (i.e., wurfl_updater_runonce()) API call. +// The asynchronous background updater always runs with default (CURL) timeouts (i.e., it will wait "as long as needed" for a new data file to be downloaded) +wurfl_error wurfl_updater_set_data_url_timeouts(wurfl_handle hwurfl, int connection_timeout, int data_transfer_timeout); + +// Call a synchronous update. This is a blocking call and will execute the whole process +// of downloading the new data file, checking for correctness, replacing the data file and restarting the engine. +// Will keep all old configurations (patches, cache, etc) +// Returns WURLF_OK if no errors, +// or WURFL_ERROR_UPDATER_XXX errors for various error conditions, eventually logging detailed infos if +// update logger is enabled. +wurfl_error wurfl_updater_runonce(wurfl_handle hwurfl); + +// Start the asynchronous update thread. Can be called just once when the updater is stopped; +// Subsequent/wrong calls will return WURFL_ERROR_UPDATER_ALREADY_RUNNING +// Will also return WURFL_ERROR_UPDATER_XXX errors for various initialization error conditions (see above), eventually logging detailed infos if +// update logger is enabled. +// On success will return WURLF_OK +wurfl_error wurfl_updater_start(wurfl_handle hwurfl); + +// Stop the asynchronous update thread. Can be called just once when the updater is started; +// Subsequent/wrong calls will return WURFL_ERROR_UPDATER_NOT_RUNNING. +// On success will return WURLF_OK +wurfl_error wurfl_updater_stop(wurfl_handle hwurfl); + +// Reload and reboot the engine with the given data file. Basically, the same process of a wurfl_updater_runonce but without the file download. +// Will synchronously load the new root testing for errors, restart the engine with the new data file and overwrite the old data file with the new one. +// Will keep old configuration (patches, cache, etc) +// Preconditions: wurfl_set_root() and wurfl_load() must have been called and the new root must be of the same kind (i.e, same extension) as the actual root +// You can force a reload of the actual set_root() file passing NULL as the newroot +wurfl_error wurfl_updater_reload_root(wurfl_handle hwurfl, const char *newroot); + +// Alternative API for passing headers to lookup functions + +// An opaque type representing a name/value headers map +// You can create, fill and destroy this object directly. +typedef struct _ih_h * wurfl_important_header_handle; +wurfl_important_header_handle wurfl_important_header_create(wurfl_handle); +wurfl_error wurfl_important_header_set(wurfl_important_header_handle, const char *name, const char *value); +void wurfl_important_header_destroy(wurfl_important_header_handle); + +// Alternative lookup functions using the above wurfl_important_header_handle object. +// Once called, you can destroy the wurfl_important_header_handle object. Headers values are cached internally in the wurfl_device_handle. +wurfl_device_handle wurfl_lookup_with_important_header(wurfl_handle, wurfl_important_header_handle); +wurfl_device_handle wurfl_get_device_with_important_header(wurfl_handle, const char *deviceid, wurfl_important_header_handle); + +// Enumerator of all headers that should be passed to a lookup function. Returns a null-termninated list of const char* +// +// Example usage: +// +// const char** importantHeadersNames = wurfl_get_important_header_names(); +// int i = 0; +// while (importantHeadersNames[i]) +// { +// printf("important header %i: %s\n", i, headerNames[i]); +// i++; +// } +const char **wurfl_get_important_header_names(void); + +// classic WURFL iterator version of the enumerator hereabove. +typedef void *wurfl_important_header_enumerator_handle; +wurfl_important_header_enumerator_handle wurfl_get_important_header_enumerator(wurfl_handle hwurfl); +void wurfl_important_header_enumerator_destroy(wurfl_important_header_enumerator_handle); +const char *wurfl_important_header_enumerator_get_value(wurfl_important_header_enumerator_handle); +int wurfl_important_header_enumerator_is_valid(wurfl_important_header_enumerator_handle); +void wurfl_important_header_enumerator_move_next(wurfl_important_header_enumerator_handle); + +#ifdef __cplusplus +} +#endif + +#endif // _WURFL_H_ diff --git a/addons/wurfl/wurfl.c b/addons/wurfl/wurfl.c new file mode 100644 index 0000000..4df6473 --- /dev/null +++ b/addons/wurfl/wurfl.c @@ -0,0 +1,779 @@ +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +static struct { + char *data_file; /* the WURFL data file */ + char *cache_size; /* the WURFL cache parameters */ + struct list patch_file_list; /* the list of WURFL patch file to use */ + char information_list_separator; /* the separator used in request to separate values */ + struct list information_list; /* the list of WURFL data to return into request */ + void *handle; /* the handle to WURFL engine */ + struct eb_root btree; /* btree containing info (name/type) on WURFL data to return */ +} global_wurfl = { + .data_file = NULL, + .cache_size = NULL, + .information_list_separator = ',', + .information_list = LIST_HEAD_INIT(global_wurfl.information_list), + .patch_file_list = LIST_HEAD_INIT(global_wurfl.patch_file_list), + .handle = NULL, +}; + +#ifdef WURFL_DEBUG +inline static void ha_wurfl_log(char * message, ...) +{ + char logbuf[256]; + va_list argp; + + va_start(argp, message); + vsnprintf(logbuf, sizeof(logbuf), message, argp); + va_end(argp); + send_log(NULL, LOG_NOTICE, "%s", logbuf); +} +#else +inline static void ha_wurfl_log(char * message, ...) +{ +} +#endif + +#define HA_WURFL_MAX_HEADER_LENGTH 1024 + +typedef char *(*PROP_CALLBACK_FUNC)(wurfl_handle wHandle, wurfl_device_handle dHandle); + +enum wurfl_data_type { + HA_WURFL_DATA_TYPE_UNKNOWN = 0, + HA_WURFL_DATA_TYPE_CAP = 100, + HA_WURFL_DATA_TYPE_VCAP = 200, + HA_WURFL_DATA_TYPE_PROPERTY = 300 +}; + +typedef struct { + char *name; + enum wurfl_data_type type; + PROP_CALLBACK_FUNC func_callback; + struct ebmb_node nd; +} wurfl_data_t; + +static const char HA_WURFL_MODULE_VERSION[] = "2.0"; +static const char HA_WURFL_ISDEVROOT_FALSE[] = "FALSE"; +static const char HA_WURFL_ISDEVROOT_TRUE[] = "TRUE"; + +static const char HA_WURFL_DATA_TYPE_UNKNOWN_STRING[] = "unknown"; +static const char HA_WURFL_DATA_TYPE_CAP_STRING[] = "capability"; +static const char HA_WURFL_DATA_TYPE_VCAP_STRING[] = "virtual_capability"; +static const char HA_WURFL_DATA_TYPE_PROPERTY_STRING[] = "property"; + +static const char *ha_wurfl_retrieve_header(const char *header_name, const void *wh); +static const char *ha_wurfl_get_wurfl_root_id (wurfl_handle wHandle, wurfl_device_handle dHandle); +static const char *ha_wurfl_get_wurfl_id (wurfl_handle wHandle, wurfl_device_handle dHandle); +static const char *ha_wurfl_get_wurfl_isdevroot (wurfl_handle wHandle, wurfl_device_handle dHandle); +static const char *ha_wurfl_get_wurfl_useragent (wurfl_handle wHandle, wurfl_device_handle dHandle); +static const char *ha_wurfl_get_wurfl_api_version (wurfl_handle wHandle, wurfl_device_handle dHandle); +static const char *ha_wurfl_get_wurfl_engine_target (wurfl_handle wHandle, wurfl_device_handle dHandle); +static const char *ha_wurfl_get_wurfl_info (wurfl_handle wHandle, wurfl_device_handle dHandle); +static const char *ha_wurfl_get_wurfl_last_load_time (wurfl_handle wHandle, wurfl_device_handle dHandle); +static const char *ha_wurfl_get_wurfl_normalized_useragent (wurfl_handle wHandle, wurfl_device_handle dHandle); +static const char *ha_wurfl_get_wurfl_useragent_priority (wurfl_handle wHandle, wurfl_device_handle dHandle); +static const char *(*ha_wurfl_get_property_callback(char *name)) (wurfl_handle wHandle, wurfl_device_handle dHandle); + +// ordered property=>function map, suitable for binary search +static const struct { + const char *name; + const char *(*func)(wurfl_handle wHandle, wurfl_device_handle dHandle); +} wurfl_properties_function_map [] = { + {"wurfl_api_version", ha_wurfl_get_wurfl_api_version}, + {"wurfl_engine_target", ha_wurfl_get_wurfl_engine_target}, // kept for backward conf file compat + {"wurfl_id", ha_wurfl_get_wurfl_id }, + {"wurfl_info", ha_wurfl_get_wurfl_info }, + {"wurfl_isdevroot", ha_wurfl_get_wurfl_isdevroot}, + {"wurfl_last_load_time", ha_wurfl_get_wurfl_last_load_time}, + {"wurfl_normalized_useragent", ha_wurfl_get_wurfl_normalized_useragent}, + {"wurfl_root_id", ha_wurfl_get_wurfl_root_id}, + {"wurfl_useragent", ha_wurfl_get_wurfl_useragent}, + {"wurfl_useragent_priority", ha_wurfl_get_wurfl_useragent_priority }, // kept for backward conf file compat +}; +static const int HA_WURFL_PROPERTIES_NBR = 10; + +typedef struct { + struct list list; + wurfl_data_t data; +} wurfl_information_t; + +typedef struct { + struct list list; + char *patch_file_path; +} wurfl_patches_t; + +typedef struct { + struct sample *wsmp; + char header_value[HA_WURFL_MAX_HEADER_LENGTH + 1]; +} ha_wurfl_header_t; + +/* + * configuration parameters parsing functions + */ +static int ha_wurfl_cfg_data_file(char **args, int section_type, struct proxy *curpx, + const struct proxy *defpx, const char *file, int line, + char **err) +{ + + if (*(args[1]) == 0) { + memprintf(err, "WURFL: %s expects a value.\n", args[0]); + return -1; + } + + global_wurfl.data_file = strdup(args[1]); + return 0; +} + +static int ha_wurfl_cfg_cache(char **args, int section_type, struct proxy *curpx, + const struct proxy *defpx, const char *file, int line, + char **err) +{ + if (*(args[1]) == 0) { + memprintf(err, "WURFL: %s expects a value.\n", args[0]); + return -1; + } + + global_wurfl.cache_size = strdup(args[1]); + return 0; +} + +static int ha_wurfl_cfg_engine_mode(char **args, int section_type, struct proxy *curpx, + const struct proxy *defpx, const char *file, int line, + char **err) +{ + // kept for backward conf file compat + return 0; +} + +static int ha_wurfl_cfg_information_list_separator(char **args, int section_type, struct proxy *curpx, + const struct proxy *defpx, const char *file, int line, + char **err) +{ + if (*(args[1]) == 0) { + memprintf(err, "WURFL: %s expects a single character.\n", args[0]); + return -1; + } + + if (strlen(args[1]) > 1) { + memprintf(err, "WURFL: %s expects a single character, got %s.\n", args[0], args[1]); + return -1; + } + + global_wurfl.information_list_separator = *args[1]; + return 0; +} + +static int ha_wurfl_cfg_information_list(char **args, int section_type, struct proxy *curpx, + const struct proxy *defpx, const char *file, int line, + char **err) +{ + int argIdx = 1; + wurfl_information_t *wi; + + if (*(args[argIdx]) == 0) { + memprintf(err, "WURFL: %s expects a value.\n", args[0]); + return -1; + } + + while (*(args[argIdx])) { + wi = calloc(1, sizeof(*wi)); + + if (wi == NULL) { + memprintf(err, "WURFL: Error allocating memory for %s element.\n", args[0]); + return -1; + } + + wi->data.name = strdup(args[argIdx]); + wi->data.type = HA_WURFL_DATA_TYPE_UNKNOWN; + wi->data.func_callback = NULL; + LIST_APPEND(&global_wurfl.information_list, &wi->list); + ++argIdx; + } + + return 0; +} + +static int ha_wurfl_cfg_patch_file_list(char **args, int section_type, struct proxy *curpx, + const struct proxy *defpx, const char *file, int line, + char **err) +{ + int argIdx = 1; + wurfl_patches_t *wp; + + if (*(args[argIdx]) == 0) { + memprintf(err, "WURFL: %s expects a value.\n", args[0]); + return -1; + } + + while (*(args[argIdx])) { + wp = calloc(1, sizeof(*wp)); + + if (wp == NULL) { + memprintf(err, "WURFL: Error allocating memory for %s element.\n", args[0]); + return -1; + } + + wp->patch_file_path = strdup(args[argIdx]); + LIST_APPEND(&global_wurfl.patch_file_list, &wp->list); + ++argIdx; + } + + return 0; +} + +static int ha_wurfl_cfg_useragent_priority(char **args, int section_type, struct proxy *curpx, + const struct proxy *defpx, const char *file, int line, + char **err) +{ + // this feature is deprecated, keeping only not to break compatibility + // with old configuration files. + return 0; +} + +/* + * module init / deinit functions. Returns 0 if OK, or a combination of ERR_*. + */ + +static int ha_wurfl_init(void) +{ + wurfl_information_t *wi; + wurfl_patches_t *wp; + wurfl_data_t * wn; + int wurfl_result_code = WURFL_OK; + int len; + + // wurfl-data-file not configured, WURFL is not used so don't try to + // configure it. + if (global_wurfl.data_file == NULL) + return ERR_NONE; + + ha_notice("WURFL: Loading module v.%s\n", HA_WURFL_MODULE_VERSION); + // creating WURFL handler + global_wurfl.handle = wurfl_create(); + + if (global_wurfl.handle == NULL) { + ha_warning("WURFL: Engine handler creation failed\n"); + return ERR_WARN; + } + + ha_notice("WURFL: Engine handler created - API version %s\n", wurfl_get_api_version() ); + + // set wurfl data file + if (wurfl_set_root(global_wurfl.handle, global_wurfl.data_file) != WURFL_OK) { + ha_warning("WURFL: Engine setting root file failed - %s\n", wurfl_get_error_message(global_wurfl.handle)); + return ERR_WARN; + } + + ha_notice("WURFL: Engine root file set to %s\n", global_wurfl.data_file); + // just a log to inform which separator char has to be used + ha_notice("WURFL: Information list separator set to '%c'\n", global_wurfl.information_list_separator); + + // load wurfl data needed ( and filter whose are supposed to be capabilities ) + if (LIST_ISEMPTY(&global_wurfl.information_list)) { + ha_warning("WURFL: missing wurfl-information-list parameter in global configuration\n"); + return ERR_WARN; + } else { + // ebtree initialization + global_wurfl.btree = EB_ROOT; + + // checking if information is valid WURFL data ( cap, vcaps, properties ) + list_for_each_entry(wi, &global_wurfl.information_list, list) { + // check if information is already loaded looking into btree + if (ebst_lookup(&global_wurfl.btree, wi->data.name) == NULL) { + if ((wi->data.func_callback = (PROP_CALLBACK_FUNC) ha_wurfl_get_property_callback(wi->data.name)) != NULL) { + wi->data.type = HA_WURFL_DATA_TYPE_PROPERTY; +#ifdef WURFL_DEBUG + ha_notice("WURFL: [%s] is a valid wurfl data [property]\n",wi->data.name); +#endif + } else if (wurfl_has_virtual_capability(global_wurfl.handle, wi->data.name)) { + wi->data.type = HA_WURFL_DATA_TYPE_VCAP; +#ifdef WURFL_DEBUG + ha_notice("WURFL: [%s] is a valid wurfl data [virtual capability]\n",wi->data.name); +#endif + } else { + // by default a cap type is assumed to be and we control it on engine load + wi->data.type = HA_WURFL_DATA_TYPE_CAP; + + if (wurfl_add_requested_capability(global_wurfl.handle, wi->data.name) != WURFL_OK) { + ha_warning("WURFL: capability filtering failed - %s\n", wurfl_get_error_message(global_wurfl.handle)); + return ERR_WARN; + } + + ha_notice("WURFL: [%s] treated as wurfl capability. Will check its validity later, on engine load\n",wi->data.name); + } + + // ebtree insert here + len = strlen(wi->data.name); + + wn = malloc(sizeof(wurfl_data_t) + len + 1); + + if (wn == NULL) { + ha_warning("WURFL: Error allocating memory for information tree element.\n"); + return ERR_WARN; + } + + wn->name = wi->data.name; + wn->type = wi->data.type; + wn->func_callback = wi->data.func_callback; + memcpy(wn->nd.key, wi->data.name, len); + wn->nd.key[len] = 0; + + if (!ebst_insert(&global_wurfl.btree, &wn->nd)) { + ha_warning("WURFL: [%s] not inserted in btree\n",wn->name); + return ERR_WARN; + } + + } else { +#ifdef WURFL_DEBUG + ha_notice("WURFL: [%s] already loaded\n",wi->data.name); +#endif + } + + } + + } + + + // adding WURFL patches if needed + if (!LIST_ISEMPTY(&global_wurfl.patch_file_list)) { + + list_for_each_entry(wp, &global_wurfl.patch_file_list, list) { + if (wurfl_add_patch(global_wurfl.handle, wp->patch_file_path) != WURFL_OK) { + ha_warning("WURFL: Engine adding patch file failed - %s\n", wurfl_get_error_message(global_wurfl.handle)); + return ERR_WARN; + } + ha_notice("WURFL: Engine patch file added %s\n", wp->patch_file_path); + + } + + } + + // setting cache provider if specified in cfg, otherwise let engine choose + if (global_wurfl.cache_size != NULL) { + if (strpbrk(global_wurfl.cache_size, ",") != NULL) { + wurfl_result_code = wurfl_set_cache_provider(global_wurfl.handle, WURFL_CACHE_PROVIDER_DOUBLE_LRU, global_wurfl.cache_size) ; + } else { + if (strcmp(global_wurfl.cache_size, "0")) { + wurfl_result_code = wurfl_set_cache_provider(global_wurfl.handle, WURFL_CACHE_PROVIDER_LRU, global_wurfl.cache_size) ; + } else { + wurfl_result_code = wurfl_set_cache_provider(global_wurfl.handle, WURFL_CACHE_PROVIDER_NONE, 0); + } + + } + + if (wurfl_result_code != WURFL_OK) { + ha_warning("WURFL: Setting cache to [%s] failed - %s\n", global_wurfl.cache_size, wurfl_get_error_message(global_wurfl.handle)); + return ERR_WARN; + } + + ha_notice("WURFL: Cache set to [%s]\n", global_wurfl.cache_size); + } + + // loading WURFL engine + if (wurfl_load(global_wurfl.handle) != WURFL_OK) { + ha_warning("WURFL: Engine load failed - %s\n", wurfl_get_error_message(global_wurfl.handle)); + return ERR_WARN; + } + + ha_notice("WURFL: Engine loaded\n"); + ha_notice("WURFL: Module load completed\n"); + return ERR_NONE; +} + +static void ha_wurfl_deinit(void) +{ + wurfl_information_t *wi, *wi2; + wurfl_patches_t *wp, *wp2; + + send_log(NULL, LOG_NOTICE, "WURFL: Unloading module v.%s\n", HA_WURFL_MODULE_VERSION); + wurfl_destroy(global_wurfl.handle); + global_wurfl.handle = NULL; + ha_free(&global_wurfl.data_file); + ha_free(&global_wurfl.cache_size); + + list_for_each_entry_safe(wi, wi2, &global_wurfl.information_list, list) { + LIST_DELETE(&wi->list); + free(wi); + } + + list_for_each_entry_safe(wp, wp2, &global_wurfl.patch_file_list, list) { + LIST_DELETE(&wp->list); + free(wp); + } + + send_log(NULL, LOG_NOTICE, "WURFL: Module unloaded\n"); +} + +static int ha_wurfl_get_all(const struct arg *args, struct sample *smp, const char *kw, void *private) +{ + wurfl_device_handle dHandle; + struct buffer *temp; + wurfl_information_t *wi; + ha_wurfl_header_t wh; + struct channel *chn; + struct htx *htx; + + ha_wurfl_log("WURFL: starting ha_wurfl_get_all\n"); + + chn = (smp->strm ? &smp->strm->req : NULL); + htx = smp_prefetch_htx(smp, chn, NULL, 1); + if (!htx) + return 0; + + wh.wsmp = smp; + + dHandle = wurfl_lookup(global_wurfl.handle, &ha_wurfl_retrieve_header, &wh); + + temp = get_trash_chunk(); + chunk_reset(temp); + + if (!dHandle) { + ha_wurfl_log("WURFL: unable to retrieve device from request %s\n", wurfl_get_error_message(global_wurfl.handle)); + goto wurfl_get_all_completed; + } + + list_for_each_entry(wi, &global_wurfl.information_list, list) { + + switch(wi->data.type) { + case HA_WURFL_DATA_TYPE_UNKNOWN : + ha_wurfl_log("WURFL: %s is of an %s type\n", wi->data.name, HA_WURFL_DATA_TYPE_UNKNOWN_STRING); +#ifdef WURFL_HEADER_WITH_DETAILS + // write WURFL property type and name before its value... + chunk_appendf(temp, "%s=%s", HA_WURFL_DATA_TYPE_UNKNOWN_STRING, wi->data.name); +#endif + break; + case HA_WURFL_DATA_TYPE_CAP : + ha_wurfl_log("WURFL: %s is a %s\n", wi->data.name, HA_WURFL_DATA_TYPE_CAP_STRING); +#ifdef WURFL_HEADER_WITH_DETAILS + // write WURFL property type and name before its value... + chunk_appendf(temp, "%s=%s=", HA_WURFL_DATA_TYPE_CAP_STRING, wi->data.name); +#endif + chunk_appendf(temp, "%s", wurfl_device_get_capability(dHandle, wi->data.name)); + break; + case HA_WURFL_DATA_TYPE_VCAP : + ha_wurfl_log("WURFL: %s is a %s\n", wi->data.name, HA_WURFL_DATA_TYPE_VCAP_STRING); +#ifdef WURFL_HEADER_WITH_DETAILS + // write WURFL property type and name before its value... + chunk_appendf(temp, "%s=%s=", HA_WURFL_DATA_TYPE_VCAP_STRING, wi->data.name); +#endif + chunk_appendf(temp, "%s", wurfl_device_get_virtual_capability(dHandle, wi->data.name)); + break; + case HA_WURFL_DATA_TYPE_PROPERTY : + ha_wurfl_log("WURFL: %s is a %s\n", wi->data.name, HA_WURFL_DATA_TYPE_PROPERTY_STRING); +#ifdef WURFL_HEADER_WITH_DETAILS + // write WURFL property type and name before its value... + chunk_appendf(temp, "%s=%s=", HA_WURFL_DATA_TYPE_PROPERTY_STRING, wi->data.name); +#endif + chunk_appendf(temp, "%s", wi->data.func_callback(global_wurfl.handle, dHandle)); + break; + } + + // append wurfl-information-list-separator + chunk_appendf(temp, "%c", global_wurfl.information_list_separator); + } + +wurfl_get_all_completed: + + wurfl_device_destroy(dHandle); + smp->data.u.str.area = temp->area; + smp->data.u.str.data = temp->data; + + // remove trailing wurfl-information-list-separator + if (temp->data) { + temp->area[temp->data] = '\0'; + --smp->data.u.str.data; + } + + smp->data.type = SMP_T_STR; + return 1; +} + +static int ha_wurfl_get(const struct arg *args, struct sample *smp, const char *kw, void *private) +{ + wurfl_device_handle dHandle; + struct buffer *temp; + wurfl_data_t *wn = NULL; + struct ebmb_node *node; + ha_wurfl_header_t wh; + int i = 0; + struct channel *chn; + struct htx *htx; + + ha_wurfl_log("WURFL: starting ha_wurfl_get\n"); + + chn = (smp->strm ? &smp->strm->req : NULL); + htx = smp_prefetch_htx(smp, chn, NULL, 1); + if (!htx) + return 0; + + wh.wsmp = smp; + + dHandle = wurfl_lookup(global_wurfl.handle, &ha_wurfl_retrieve_header, &wh); + + temp = get_trash_chunk(); + chunk_reset(temp); + + if (!dHandle) { + ha_wurfl_log("WURFL: unable to retrieve device from request %s\n", wurfl_get_error_message(global_wurfl.handle)); + goto wurfl_get_completed; + } + + while (args[i].data.str.area) { + node = ebst_lookup(&global_wurfl.btree, args[i].data.str.area); + + if (node) { + + wn = container_of(node, wurfl_data_t, nd); + + switch(wn->type) { + case HA_WURFL_DATA_TYPE_UNKNOWN : + ha_wurfl_log("WURFL: %s is of an %s type\n", wn->name, HA_WURFL_DATA_TYPE_UNKNOWN_STRING); +#ifdef WURFL_HEADER_WITH_DETAILS + // write WURFL property type and name before its value... + chunk_appendf(temp, "%s=%s", HA_WURFL_DATA_TYPE_UNKNOWN_STRING, wn->name); +#endif + break; + case HA_WURFL_DATA_TYPE_CAP : + ha_wurfl_log("WURFL: %s is a %s\n", wn->name, HA_WURFL_DATA_TYPE_CAP_STRING); +#ifdef WURFL_HEADER_WITH_DETAILS + // write WURFL property type and name before its value... + chunk_appendf(temp, "%s=%s=", HA_WURFL_DATA_TYPE_CAP_STRING, wn->name); +#endif + chunk_appendf(temp, "%s", wurfl_device_get_capability(dHandle, wn->name)); + break; + case HA_WURFL_DATA_TYPE_VCAP : + ha_wurfl_log("WURFL: %s is a %s\n", wn->name, HA_WURFL_DATA_TYPE_VCAP_STRING); +#ifdef WURFL_HEADER_WITH_DETAILS + // write WURFL property type and name before its value... + chunk_appendf(temp, "%s=%s=", HA_WURFL_DATA_TYPE_VCAP_STRING, wn->name); +#endif + chunk_appendf(temp, "%s", wurfl_device_get_virtual_capability(dHandle, wn->name)); + break; + case HA_WURFL_DATA_TYPE_PROPERTY : + ha_wurfl_log("WURFL: %s is a %s\n", wn->name, HA_WURFL_DATA_TYPE_PROPERTY_STRING); +#ifdef WURFL_HEADER_WITH_DETAILS + // write WURFL property type and name before its value... + chunk_appendf(temp, "%s=%s=", HA_WURFL_DATA_TYPE_PROPERTY_STRING, wn->name); +#endif + chunk_appendf(temp, "%s", wn->func_callback(global_wurfl.handle, dHandle)); + break; + } + + // append wurfl-information-list-separator + chunk_appendf(temp, "%c", global_wurfl.information_list_separator); + + } else { + ha_wurfl_log("WURFL: %s not in wurfl-information-list \n", + args[i].data.str.area); + } + + i++; + } + +wurfl_get_completed: + + wurfl_device_destroy(dHandle); + smp->data.u.str.area = temp->area; + smp->data.u.str.data = temp->data; + + // remove trailing wurfl-information-list-separator + if (temp->data) { + temp->area[temp->data] = '\0'; + --smp->data.u.str.data; + } + + smp->data.type = SMP_T_STR; + return 1; +} + +static struct cfg_kw_list wurflcfg_kws = {{ }, { + { CFG_GLOBAL, "wurfl-data-file", ha_wurfl_cfg_data_file }, + { CFG_GLOBAL, "wurfl-information-list-separator", ha_wurfl_cfg_information_list_separator }, + { CFG_GLOBAL, "wurfl-information-list", ha_wurfl_cfg_information_list }, + { CFG_GLOBAL, "wurfl-patch-file", ha_wurfl_cfg_patch_file_list }, + { CFG_GLOBAL, "wurfl-cache-size", ha_wurfl_cfg_cache }, + { CFG_GLOBAL, "wurfl-engine-mode", ha_wurfl_cfg_engine_mode }, + { CFG_GLOBAL, "wurfl-useragent-priority", ha_wurfl_cfg_useragent_priority }, + { 0, NULL, NULL }, + } +}; + +INITCALL1(STG_REGISTER, cfg_register_keywords, &wurflcfg_kws); + +/* Note: must not be declared as its list will be overwritten */ +static struct sample_fetch_kw_list fetch_kws = {ILH, { + { "wurfl-get-all", ha_wurfl_get_all, 0, NULL, SMP_T_STR, SMP_USE_HRQHV }, + { "wurfl-get", ha_wurfl_get, ARG12(1,STR,STR,STR,STR,STR,STR,STR,STR,STR,STR,STR,STR), NULL, SMP_T_STR, SMP_USE_HRQHV }, + { NULL, NULL, 0, 0, 0 }, + } +}; + +INITCALL1(STG_REGISTER, sample_register_fetches, &fetch_kws); + +/* Note: must not be declared as its list will be overwritten */ +static struct sample_conv_kw_list conv_kws = {ILH, { + { NULL, NULL, 0, 0, 0 }, + } +}; + +INITCALL1(STG_REGISTER, sample_register_convs, &conv_kws); + +// WURFL properties wrapper functions +static const char *ha_wurfl_get_wurfl_root_id (wurfl_handle wHandle, wurfl_device_handle dHandle) +{ + if (wurfl_device_get_root_id(dHandle)) + return wurfl_device_get_root_id(dHandle); + else + return ""; +} + +static const char *ha_wurfl_get_wurfl_id (wurfl_handle wHandle, wurfl_device_handle dHandle) +{ + return wurfl_device_get_id(dHandle); +} + +static const char *ha_wurfl_get_wurfl_isdevroot (wurfl_handle wHandle, wurfl_device_handle dHandle) +{ + if (wurfl_device_is_actual_device_root(dHandle)) + return HA_WURFL_ISDEVROOT_TRUE; + else + return HA_WURFL_ISDEVROOT_FALSE; +} + +static const char *ha_wurfl_get_wurfl_useragent (wurfl_handle wHandle, wurfl_device_handle dHandle) +{ + return wurfl_device_get_original_useragent(dHandle); +} + +static const char *ha_wurfl_get_wurfl_api_version (wurfl_handle wHandle, wurfl_device_handle dHandle) +{ + return wurfl_get_api_version(); +} + +static const char *ha_wurfl_get_wurfl_engine_target (wurfl_handle wHandle, wurfl_device_handle dHandle) +{ + return "default"; +} + +static const char *ha_wurfl_get_wurfl_info (wurfl_handle wHandle, wurfl_device_handle dHandle) +{ + return wurfl_get_wurfl_info(wHandle); +} + +static const char *ha_wurfl_get_wurfl_last_load_time (wurfl_handle wHandle, wurfl_device_handle dHandle) +{ + return wurfl_get_last_load_time_as_string(wHandle); +} + +static const char *ha_wurfl_get_wurfl_normalized_useragent (wurfl_handle wHandle, wurfl_device_handle dHandle) +{ + return wurfl_device_get_normalized_useragent(dHandle); +} + +static const char *ha_wurfl_get_wurfl_useragent_priority (wurfl_handle wHandle, wurfl_device_handle dHandle) +{ + return "default"; +} + +// call function for WURFL properties +static const char *(*ha_wurfl_get_property_callback(char *name)) (wurfl_handle wHandle, wurfl_device_handle dHandle) +{ + int position; + int begin = 0; + int end = HA_WURFL_PROPERTIES_NBR - 1; + int cond = 0; + + while(begin <= end) { + position = (begin + end) / 2; + + if((cond = strcmp(wurfl_properties_function_map[position].name, name)) == 0) { + ha_wurfl_log("WURFL: ha_wurfl_get_property_callback match %s\n", wurfl_properties_function_map[position].name ); + return wurfl_properties_function_map[position].func; + } else if(cond < 0) + begin = position + 1; + else + end = position - 1; + + } + + return NULL; +} + +static const char *ha_wurfl_retrieve_header(const char *header_name, const void *wh) +{ + struct sample *smp; + struct channel *chn; + struct htx *htx; + struct http_hdr_ctx ctx; + struct ist name; + int header_len = HA_WURFL_MAX_HEADER_LENGTH; + + smp = ((ha_wurfl_header_t *)wh)->wsmp; + chn = (smp->strm ? &smp->strm->req : NULL); + + ha_wurfl_log("WURFL: retrieve header (HTX) request [%s]\n", header_name); + + //the header is searched from the beginning + ctx.blk = NULL; + + // We could skip this check since ha_wurfl_retrieve_header is called from inside + // ha_wurfl_get()/ha_wurfl_get_all() that already perform the same check + // We choose to keep it in case ha_wurfl_retrieve_header will be called directly + htx = smp_prefetch_htx(smp, chn, NULL, 1); + if (!htx) { + return NULL; + } + + name = ist2((char *)header_name, strlen(header_name)); + + // If 4th param is set, it works on full-line headers in whose comma is not a delimiter but is + // part of the syntax + if (!http_find_header(htx, name, &ctx, 1)) { + return NULL; + } + + if (header_len > ctx.value.len) + header_len = ctx.value.len; + + strncpy(((ha_wurfl_header_t *)wh)->header_value, ctx.value.ptr, header_len); + + ((ha_wurfl_header_t *)wh)->header_value[header_len] = '\0'; + + ha_wurfl_log("WURFL: retrieve header request returns [%s]\n", ((ha_wurfl_header_t *)wh)->header_value); + return ((ha_wurfl_header_t *)wh)->header_value; +} + +static void ha_wurfl_register_build_options() +{ + const char *ver = wurfl_get_api_version(); + char *ptr = NULL; + + memprintf(&ptr, "Built with WURFL support (%sversion %s)", + strcmp(ver, "1.11.2.100") ? "" : "dummy library ", + ver); + hap_register_build_opts(ptr, 1); +} + +REGISTER_POST_CHECK(ha_wurfl_init); +REGISTER_POST_DEINIT(ha_wurfl_deinit); +INITCALL0(STG_REGISTER, ha_wurfl_register_build_options); diff --git a/admin/dyncookie/dyncookie.c b/admin/dyncookie/dyncookie.c new file mode 100644 index 0000000..ddb71a7 --- /dev/null +++ b/admin/dyncookie/dyncookie.c @@ -0,0 +1,56 @@ +/* + * Dynamic server cookie calculator + * + * Copyright 2021 Willy Tarreau + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + */ + +#include +#include +#include +#include + +#include + +__attribute__((noreturn)) void die(int code, const char *format, ...) +{ + va_list args; + + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); + exit(code); +} + +int main(int argc, char **argv) +{ + size_t key_len; + int addr_len; + char *buf; + int port; + + if (argc < 4) + die(1, "Usage: %s \n", argv[0]); + + key_len = strlen(argv[1]); + buf = realloc(strdup(argv[1]), key_len + 16 + 4); + if (!buf) + die(2, "Not enough memory\n"); + + if (inet_pton(AF_INET, argv[2], buf + key_len) > 0) + addr_len = 4; + else if (inet_pton(AF_INET6, argv[2], buf + key_len) > 0) + addr_len = 16; + else + die(3, "Cannot parse address <%s> as IPv4/IPv6\n", argv[2]); + + port = htonl(atoi(argv[3])); + memcpy(buf + key_len + addr_len, &port, 4); + printf("%016llx\n", (long long)XXH64(buf, key_len + addr_len + 4, 0)); + return 0; +} diff --git a/admin/halog/README b/admin/halog/README new file mode 100644 index 0000000..ff1bb12 --- /dev/null +++ b/admin/halog/README @@ -0,0 +1,4 @@ +This needs to be built from the top makefile, for example : + + make admin/halog/halog + diff --git a/admin/halog/fgets2.c b/admin/halog/fgets2.c new file mode 100644 index 0000000..7fbe16b --- /dev/null +++ b/admin/halog/fgets2.c @@ -0,0 +1,267 @@ +/* + * fast fgets() replacement for log parsing + * + * Copyright 2000-2012 Willy Tarreau + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, version 2.1 + * exclusively. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * This function manages its own buffer and returns a pointer to that buffer + * in order to avoid expensive memory copies. It also checks for line breaks + * 32 or 64 bits at a time. It could be improved a lot using mmap() but we + * would not be allowed to replace trailing \n with zeroes and we would be + * limited to small log files on 32-bit machines. + * + */ + +#include +#include +#include +#include + +#ifndef FGETS2_BUFSIZE +#define FGETS2_BUFSIZE (256*1024) +#endif + +/* memchr() is faster in glibc with SSE since commit 093ecf92998de2 */ +#if defined(__x86_64__) && defined(__GLIBC__) && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 15)) +#define USE_MEMCHR +#endif + +/* return non-zero if the integer contains at least one zero byte */ +static inline __attribute__((unused)) unsigned int has_zero32(unsigned int x) +{ + unsigned int y; + + /* Principle: we want to perform 4 tests on one 32-bit int at once. For + * this, we have to simulate an SIMD instruction which we don't have by + * default. The principle is that a zero byte is the only one which + * will cause a 1 to appear on the upper bit of a byte/word/etc... when + * we subtract 1. So we can detect a zero byte if a one appears at any + * of the bits 7, 15, 23 or 31 where it was not. It takes only one + * instruction to test for the presence of any of these bits, but it is + * still complex to check for their initial absence. Thus, we'll + * proceed differently : we first save and clear only those bits, then + * we check in the final result if one of them is present and was not. + * The order of operations below is important to save registers and + * tests. The result is used as a boolean, so the last test must apply + * on the constant so that it can efficiently be inlined. + */ +#if defined(__i386__) + /* gcc on x86 loves copying registers over and over even on code that + * simple, so let's do it by hand to prevent it from doing so :-( + */ + asm("lea -0x01010101(%0),%1\n" + "not %0\n" + "and %1,%0\n" + : "=a" (x), "=r"(y) + : "0" (x) + ); + return x & 0x80808080; +#else + y = x - 0x01010101; /* generate a carry */ + x = ~x & y; /* clear the bits that were already set */ + return x & 0x80808080; +#endif +} + +/* return non-zero if the argument contains at least one zero byte. See principle above. */ +static inline __attribute__((unused)) unsigned long long has_zero64(unsigned long long x) +{ + unsigned long long y; + + y = x - 0x0101010101010101ULL; /* generate a carry */ + y &= ~x; /* clear the bits that were already set */ + return y & 0x8080808080808080ULL; +} + +static inline __attribute__((unused)) unsigned long has_zero(unsigned long x) +{ + return (sizeof(x) == 8) ? has_zero64(x) : has_zero32(x); +} + +/* find a '\n' between and . Warning: may read slightly past . + * If no '\n' is found, is returned. + */ +static char *find_lf(char *next, char *end) +{ +#if defined USE_MEMCHR + /* some recent libc use platform-specific optimizations to provide more + * efficient byte search than below (eg: glibc 2.11 on x86_64). + */ + next = memchr(next, '\n', end - next); + if (!next) + next = end; +#else + if (sizeof(long) == 4) { /* 32-bit system */ + /* this is a speed-up, we read 32 bits at once and check for an + * LF character there. We stop if found then continue one at a + * time. + */ + while (next < end && (((unsigned long)next) & 3) && *next != '\n') + next++; + + /* Now next is multiple of 4 or equal to end. We know we can safely + * read up to 32 bytes past end if needed because they're allocated. + */ + while (next < end) { + if (has_zero32(*(unsigned int *)next ^ 0x0A0A0A0A)) + break; + next += 4; + if (has_zero32(*(unsigned int *)next ^ 0x0A0A0A0A)) + break; + next += 4; + if (has_zero32(*(unsigned int *)next ^ 0x0A0A0A0A)) + break; + next += 4; + if (has_zero32(*(unsigned int *)next ^ 0x0A0A0A0A)) + break; + next += 4; + if (has_zero32(*(unsigned int *)next ^ 0x0A0A0A0A)) + break; + next += 4; + if (has_zero32(*(unsigned int *)next ^ 0x0A0A0A0A)) + break; + next += 4; + if (has_zero32(*(unsigned int *)next ^ 0x0A0A0A0A)) + break; + next += 4; + if (has_zero32(*(unsigned int *)next ^ 0x0A0A0A0A)) + break; + next += 4; + } + } + else { /* 64-bit system */ + /* this is a speed-up, we read 64 bits at once and check for an + * LF character there. We stop if found then continue one at a + * time. + */ + if (next <= end) { + /* max 3 bytes tested here */ + while ((((unsigned long)next) & 3) && *next != '\n') + next++; + + /* maybe we have can skip 4 more bytes */ + if ((((unsigned long)next) & 4) && !has_zero32(*(unsigned int *)next ^ 0x0A0A0A0AU)) + next += 4; + } + + /* now next is multiple of 8 or equal to end */ + while (next <= (end-68)) { + if (has_zero64(*(unsigned long long *)next ^ 0x0A0A0A0A0A0A0A0AULL)) + break; + next += 8; + if (has_zero64(*(unsigned long long *)next ^ 0x0A0A0A0A0A0A0A0AULL)) + break; + next += 8; + if (has_zero64(*(unsigned long long *)next ^ 0x0A0A0A0A0A0A0A0AULL)) + break; + next += 8; + if (has_zero64(*(unsigned long long *)next ^ 0x0A0A0A0A0A0A0A0AULL)) + break; + next += 8; + if (has_zero64(*(unsigned long long *)next ^ 0x0A0A0A0A0A0A0A0AULL)) + break; + next += 8; + if (has_zero64(*(unsigned long long *)next ^ 0x0A0A0A0A0A0A0A0AULL)) + break; + next += 8; + if (has_zero64(*(unsigned long long *)next ^ 0x0A0A0A0A0A0A0A0AULL)) + break; + next += 8; + if (has_zero64(*(unsigned long long *)next ^ 0x0A0A0A0A0A0A0A0AULL)) + break; + next += 8; + } + + /* maybe we can skip 4 more bytes */ + if (!has_zero32(*(unsigned int *)next ^ 0x0A0A0A0AU)) + next += 4; + } + + /* We finish if needed : if is below , it means we + * found an LF in one of the 4 following bytes. + */ + while (next < end) { + if (*next == '\n') + break; + next++; + } +#endif + return next; +} + +const char *fgets2(FILE *stream) +{ + static char buffer[FGETS2_BUFSIZE + 68]; /* Note: +32 is enough on 32-bit systems */ + static char *end = buffer; + static char *line = buffer; + char *next; + int ret; + + next = line; + + while (1) { + next = find_lf(next, end); + if (next < end) { + const char *start = line; + *next = '\0'; + line = next + 1; + return start; + } + + /* we found an incomplete line. First, let's move the + * remaining part of the buffer to the beginning, then + * try to complete the buffer with a new read. We can't + * rely on anymore because it went past . + */ + if (line > buffer) { + if (end != line) + memmove(buffer, line, end - line); + end = buffer + (end - line); + next = end; + line = buffer; + } else { + if (end == buffer + FGETS2_BUFSIZE) + return NULL; + } + + ret = read(fileno(stream), end, buffer + FGETS2_BUFSIZE - end); + + if (ret <= 0) { + if (end == line) + return NULL; + + *end = '\0'; + end = line; /* ensure we stop next time */ + return line; + } + + end += ret; + *end = '\n'; /* make parser stop ASAP */ + /* search for '\n' again */ + } +} + +#ifdef BENCHMARK +int main() { + const char *p; + unsigned int lines = 0; + + while ((p=fgets2(stdin))) + lines++; + printf("lines=%u\n", lines); + return 0; +} +#endif diff --git a/admin/halog/halog.c b/admin/halog/halog.c new file mode 100644 index 0000000..45eec75 --- /dev/null +++ b/admin/halog/halog.c @@ -0,0 +1,1910 @@ +/* + * haproxy log statistics reporter + * + * Copyright 2000-2012 Willy Tarreau + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#define SOURCE_FIELD 5 +#define ACCEPT_FIELD 6 +#define SERVER_FIELD 8 +#define TIME_FIELD 9 +#define STATUS_FIELD 10 +#define BYTES_SENT_FIELD 11 +#define TERM_CODES_FIELD 14 +#define CONN_FIELD 15 +#define QUEUE_LEN_FIELD 16 +#define METH_FIELD 17 +#define URL_FIELD 18 +#define MAXLINE 16384 +#define QBITS 4 + +#define SEP(c) ((unsigned char)(c) <= ' ') +#define SKIP_CHAR(p,c) do { while (1) { int __c = (unsigned char)*p++; if (__c == c) break; if (__c <= ' ') { p--; break; } } } while (0) + +/* [0] = err/date, [1] = req, [2] = conn, [3] = resp, [4] = data */ +static struct eb_root timers[5] = { + EB_ROOT_UNIQUE, EB_ROOT_UNIQUE, EB_ROOT_UNIQUE, + EB_ROOT_UNIQUE, EB_ROOT_UNIQUE, +}; + +struct timer { + struct eb32_node node; + unsigned int count; +}; + +struct srv_st { + unsigned int st_cnt[6]; /* 0xx to 5xx */ + unsigned int nb_ct, nb_rt, nb_ok; + unsigned long long cum_ct, cum_rt; + struct ebmb_node node; + /* don't put anything else here, the server name will be there */ +}; + +struct url_stat { + union { + struct ebpt_node url; + struct eb64_node val; + } node; + char *url; + unsigned long long total_time; /* sum(all reqs' times) */ + unsigned long long total_time_ok; /* sum(all OK reqs' times) */ + unsigned long long total_bytes_sent; /* sum(all bytes sent) */ + unsigned int nb_err, nb_req; +}; + +#define FILT_COUNT_ONLY 0x01 +#define FILT_INVERT 0x02 +#define FILT_QUIET 0x04 +#define FILT_ERRORS_ONLY 0x08 +#define FILT_ACC_DELAY 0x10 +#define FILT_ACC_COUNT 0x20 +#define FILT_GRAPH_TIMERS 0x40 +#define FILT_PERCENTILE 0x80 +#define FILT_TIME_RESP 0x100 + +#define FILT_INVERT_ERRORS 0x200 +#define FILT_INVERT_TIME_RESP 0x400 + +#define FILT_COUNT_STATUS 0x800 +#define FILT_COUNT_SRV_STATUS 0x1000 +#define FILT_COUNT_TERM_CODES 0x2000 + +#define FILT_COUNT_URL_ONLY 0x004000 +#define FILT_COUNT_URL_COUNT 0x008000 +#define FILT_COUNT_URL_ERR 0x010000 +#define FILT_COUNT_URL_TTOT 0x020000 +#define FILT_COUNT_URL_TAVG 0x040000 +#define FILT_COUNT_URL_TTOTO 0x080000 +#define FILT_COUNT_URL_TAVGO 0x100000 + +#define FILT_HTTP_ONLY 0x200000 +#define FILT_TERM_CODE_NAME 0x400000 +#define FILT_INVERT_TERM_CODE_NAME 0x800000 + +#define FILT_HTTP_STATUS 0x1000000 +#define FILT_INVERT_HTTP_STATUS 0x2000000 +#define FILT_QUEUE_ONLY 0x4000000 +#define FILT_QUEUE_SRV_ONLY 0x8000000 + +#define FILT_COUNT_URL_BAVG 0x10000000 +#define FILT_COUNT_URL_BTOT 0x20000000 + +#define FILT_COUNT_URL_ANY (FILT_COUNT_URL_ONLY|FILT_COUNT_URL_COUNT|FILT_COUNT_URL_ERR| \ + FILT_COUNT_URL_TTOT|FILT_COUNT_URL_TAVG|FILT_COUNT_URL_TTOTO|FILT_COUNT_URL_TAVGO| \ + FILT_COUNT_URL_BAVG|FILT_COUNT_URL_BTOT) + +#define FILT_COUNT_COOK_CODES 0x40000000 +#define FILT_COUNT_IP_COUNT 0x80000000 + +#define FILT2_TIMESTAMP 0x01 +#define FILT2_PRESERVE_QUERY 0x02 +#define FILT2_EXTRACT_CAPTURE 0x04 + +unsigned int filter = 0; +unsigned int filter2 = 0; +unsigned int filter_invert = 0; +const char *line; +int linenum = 0; +int parse_err = 0; +int lines_out = 0; +int lines_max = -1; + +const char *fgets2(FILE *stream); + +void filter_count_url(const char *accept_field, const char *time_field, struct timer **tptr); +void filter_count_ip(const char *source_field, const char *accept_field, const char *time_field, struct timer **tptr); +void filter_count_srv_status(const char *accept_field, const char *time_field, struct timer **tptr); +void filter_count_cook_codes(const char *accept_field, const char *time_field, struct timer **tptr); +void filter_count_term_codes(const char *accept_field, const char *time_field, struct timer **tptr); +void filter_count_status(const char *accept_field, const char *time_field, struct timer **tptr); +void filter_graphs(const char *accept_field, const char *time_field, struct timer **tptr); +void filter_output_line(const char *accept_field, const char *time_field, struct timer **tptr); +void filter_extract_capture(const char *accept_field, const char *time_field, unsigned int, unsigned int); +void filter_accept_holes(const char *accept_field, const char *time_field, struct timer **tptr); + +void usage(FILE *output, const char *msg) +{ + fprintf(output, + "%s" + "Usage:\n" + " halog [-h|--help] for long help\n" + " halog [input_filters]* [modifiers]* [output_format] < log\n" + " inp = [-e|-E] [-H] [-Q|-QS] [-rt|-RT