6528 Commits

Author SHA1 Message Date
Willy Tarreau
ca3610251b CLEANUP: listener: remove the unused handler field
Historically listeners used to have a handler depending on the upper
layer. But now it's exclusively process_stream() and nothing uses it
anymore so it can safely be removed.
2017-08-30 07:05:08 +02:00
Willy Tarreau
87787acf72 MEDIUM: stream: make stream_new() allocate its own task
Currently a task is allocated in session_new() and serves two purposes :
  - either the handshake is complete and it is offered to the stream via
    the second arg of stream_new()

  - or the handshake is not complete and it's diverted to be used as a
    timeout handler for the embryonic session and repurposed once we land
    into conn_complete_session()

Furthermore, the task's process() function was taken from the listener's
handler in conn_complete_session() prior to being replaced by a call to
stream_new(). This will become a serious mess with the mux.

Since it's impossible to have a stream without a task, this patch removes
the second arg from stream_new() and make this function allocate its own
task. In session_accept_fd(), we now only allocate the task if needed for
the embryonic session and delete it later.
2017-08-30 07:05:04 +02:00
Willy Tarreau
8e3c6ce75a MEDIUM: connection: get rid of data->init() which was not for data
The ->init() callback of the connection's data layer was only used to
complete the session's initialisation since sessions and streams were
split apart in 1.6. The problem is that it creates a big confusion in
the layers' roles as the session has to register a dummy data layer
when waiting for a handshake to complete, then hand it off to the
stream which will replace it.

The real need is to notify that the transport has finished initializing.
This should enable a better splitting between these layers.

This patch thus introduces a connection-specific callback called
xprt_done_cb() which informs about handshake successes or failures. With
this, data->init() can disappear, CO_FL_INIT_DATA as well, and we don't
need to register a dummy data->wake() callback to be notified of errors.
2017-08-30 07:04:04 +02:00
Willy Tarreau
8ff5a8d87f BUG/MINOR: stream-int: don't check the CO_FL_CURR_WR_ENA flag
The stream interface chk_snd() code checks if the connection has already
subscribed to write events in order to avoid attempting a useless write()
which will fail. But it used to check both the CO_FL_CURR_WR_ENA and the
CO_FL_DATA_WR_ENA flags, while the former may only be present without the
latterif either the other side just disabled writing did not synchronize
yet (which is harmless) or if it's currently performing a handshake, which
is being checked by the next condition and will be better dealt with by
properly subscribing to the data events.

This code was added back in 1.5-dev20 to limit the number of useless calls
to splice() but both flags were checked at once while only CO_FL_DATA_WR_ENA
was needed. This bug seems to have no impact other than making code changes
more painful. This fix may be backported down to 1.5 though is unlikely to
be needed there.
2017-08-30 07:03:34 +02:00
Willy Tarreau
585744bf2e REORG/MEDIUM: connection: introduce the notion of connection handle
Till now connections used to rely exclusively on file descriptors. It
was planned in the past that alternative solutions would be implemented,
leading to member "union t" presenting sock.fd only for now.

With QUIC, the connection will need to continue to exist but will not
rely on a file descriptor but a connection ID.

So this patch introduces a "connection handle" which is either a file
descriptor or a connection ID, to replace the existing "union t". We've
now removed the intermediate "struct sock" which was never used. There
is no functional change at all, though the struct connection was inflated
by 32 bits on 64-bit platforms due to alignment.
2017-08-24 19:30:04 +02:00
Willy Tarreau
ee1bdd5a03 OPTIM: lua: don't add "Connection: close" on the response
Haproxy doesn't need this anymore, we're wasting cycles checking for
a Connection header in order to add "Connection: close" only in the
1.1 case so that haproxy sees it and removes it. All tests were run
in 1.0 and 1.1, with/without the request header, and in the various
keep-alive/close modes, with/without compression, and everything works
fine. It's worth noting that this header was inherited from the stats
applet and that the same cleanup probably ought to be done there as
well.
2017-08-23 16:11:38 +02:00
Willy Tarreau
a329463655 OPTIM: lua: don't use expensive functions to parse headers in the HTTP applet
In the HTTP applet, we have to parse the response headers provided by
the application and to produce a response. strcasecmp() is expensive,
and chunk_append() even more as it uses a format string.

Here we check the string length before calling strcasecmp(), which
results in strcasecmp() being called only on the relevant header in
practise due to very few collisions on the name lengths, effectively
dividing the number of calls by 3, and we replace chunk_appendf()
with memcpy() as we already know the string lengths.

Doing just this makes the "hello-world" applet 5% faster, reaching
41400 requests/s on a core i5-3320M.
2017-08-23 16:11:38 +02:00
Willy Tarreau
85cb0aecf5 BUG/MEDIUM: stream: properly set the required HTTP analysers on use-service
Commit 4850e51 ("BUG/MAJOR: lua: Do not force the HTTP analysers in
use-services") fixed a bug in how services are used in Lua, but this
fix broke the ability for Lua services to support keep-alive.

The cause is that we branch to a service while we have not yet set the
body analysers on the request nor the response, and when we start to
deal with the response we don't have any request analyser anymore. This
leads the response forward engine to detect an error and abort. It's
very likely that this also causes some random truncation of responses
though this has not been observed during the tests.

The root cause is not the Lua part in fact, the commit above was correct,
the problem is the implementation of the "use-service" action. When done
in an HTTP request, it bypasses the load balancing decisions and the
connect() phase. These ones are normally the ones preparing the request
analysers to parse the body when keep-alive is set. This should be dealt
with in the main process_use_service() function in fact.

That's what this patch does. If process_use_service() is called from the
http-request rule set, it enables the XFER_BODY analyser on the request
(since the same is always set on the response). Note that it's exactly
what is being done on the stats page which properly supports keep-alive
and compression.

This fix must be backported to 1.7 and 1.6 as the breakage appeared in 1.6.3.
2017-08-23 16:11:38 +02:00
Willy Tarreau
c9f4ea0f61 MINOR: lua: properly process the contents of the content-length field
The header's value was parsed with atoi() then compared against -1,
meaning that all the unparsable stuff returning zero was not considered
and that all multiples of 2^32 + 0xFFFFFFFF would continue to emit a
chunk.

Now instead we parse the value using a long long, only accept positive
values and consider all unparsable values as incorrect and switch to
either close or chunked encoding. This is more in line with what a
client (including haproxy's parser) would expect.

This may be backported as a cleanup to stable versions, though it's
really unlikely that Lua applications are facing side effects of this.
2017-08-23 16:11:38 +02:00
Willy Tarreau
06c75fec17 BUG/MEDIUM: lua: HTTP services must take care of body-less status codes
The following Lua code causes emission of a final chunk after the body,
which is wrong :

core.register_service("send204", "http", function(applet)
   applet:set_status(204)
   applet:start_response()
end)

Indeed, responses with status codes 1xx, 204 and 304 do not contain any
body and the message ends immediately after the empty header (cf RFC7230)
so by emitting a 0<CR><LF> we're disturbing keep-alive responses. There's
a workaround against this for now which consists in always emitting
"Content-length: 0" but it may not be cool with 304 when clients use
the headers to update their cache.

This fix must be backported to stable versions back to 1.6.
2017-08-23 16:11:38 +02:00
Willy Tarreau
d958741886 BUG/MAJOR: lua: fix the impact of the scheduler changes again
Commit d1aa41f ("BUG/MAJOR: lua: properly dequeue hlua_applet_wakeup()
for new scheduler") tried to address the side effects of the scheduler
changes on Lua, but it was not enough. Having some Lua code send data
in chunks separated by one second each clearly shows busy polling being
done.

The issue was tracked down to hlua_applet_wakeup() being woken up on
timer expiration, and returning itself without clearing the timeout,
causing the task to be re-inserted with an expiration date in the past,
thus firing again. In the past it was not a problem, as returning NULL
was enough to clear the timer. Now we can't rely on this anymore so
it's important to clear this timeout.

No backport is needed, this issue is specific to 1.8-dev and results
from an incomplete fix in the commit above.
2017-08-23 16:07:33 +02:00
Willy Tarreau
0c219be3df BUG/MEDIUM: dns: fix accepted_payload_size parser to avoid integer overflow
Since commit 9d8dbbc ("MINOR: dns: Maximum DNS udp payload set to 8192") it's
possible to specify a packet size, but passing too large a size or a negative
size is not detected and results in memset() being performed over a 2GB+ area
upon receipt of the first DNS response, causing runtime crashes.

We now check that the size is not smaller than the smallest packet which is
the DNS header size (12 bytes).

No backport is needed.
2017-08-22 12:03:46 +02:00
Baptiste Assmann
f5f71304b0 BUG/MINOR: dns: wrong resolution interval lead to 100% CPU
Since the DNS layer split and the use of obj_type structure, we did not
updated propoerly the code used to compute the interval between 2
resolutions.
A nasty loop was then created when:
- resolver's hold.valid is shorter than servers' check.inter
- a valid response is available in the DNS cache

A task was woken up for a server's resolution. The servers pick up the IP
in the cache and returns without updating the 'last update' timestamp of
the resolution (which is normal...). Then the task is woken up again for
the same server.
The fix simply computes now properly the interval between 2 resolutions
and the cache is used properly while a new resolution is triggered if
the data is not fresh enough.
2017-08-22 11:40:00 +02:00
Baptiste Assmann
8d11236234 CLEANUP: dns: remove duplicated code in dns_validate_dns_response()
a reader pointer comparison to the end of the buffer was performed twice
while once is obviously enough.

backport status: this patch can be backported into HAProxy 1.6 (with some
modification. Please contact me)
2017-08-22 11:40:00 +02:00
Baptiste Assmann
60e9c264c9 CLEANUP: dns: remove duplicated code in dns_resolve_recv()
by mistake, I duplicated a block when introductiing the list_for_each loop
on a resolution's requester list.
2017-08-22 11:40:00 +02:00
Baptiste Assmann
e2d03d2a43 MINOR: dns: make SRV record processing more verbose
For troubleshooting purpose, it may be important to know when a server
got its fqdn updated by a SRV record.
This patch makes HAProxy to report such events through stderr and logs.
2017-08-22 11:40:00 +02:00
Baptiste Assmann
e70bc05b3a MINOR: dns: automatic reduction of DNS accpeted payload size
RFC 6891 states that if a DNS client announces "big" payload size and
doesn't receive a response (because some equipments on the path may
block/drop UDP fragmented packets), then it should try asking for
smaller responses.
2017-08-22 11:40:00 +02:00
Baptiste Assmann
9d8dbbc56b MINOR: dns: Maximum DNS udp payload set to 8192
Following up DNS extension introduction, this patch aims at making the
computation of the maximum number of records in DNS response dynamic.
This computation is based on the announced payload size accepted by
HAProxy.
2017-08-22 11:39:57 +02:00
Baptiste Assmann
747359eeca BUG/MINOR: dns: server set by SRV records stay in "no resolution" status
This patch fixes a bug where some servers managed by SRV record query
types never ever recover from a "no resolution" status.
The problem is due to a wrong function called when breaking the
server/resolution (A/AAAA) relationship: this is performed when a server's SRV
record disappear from the SRV response.
2017-08-22 11:34:49 +02:00
Frdric Lcaille
6ca71a9297 BUG/MINOR: Wrong type used as argument for spoe_decode_buffer().
Contrary to 64-bits libCs where size_t type size is 8, on systems with 32-bits
size of size_t is 4 (the size of a long) which does not equal to size of uint64_t type.
This was revealed by such GCC warnings on 32bits systems:

src/flt_spoe.c:2259:40: warning: passing argument 4 of spoe_decode_buffer from
incompatible pointer type
  if (spoe_decode_buffer(&p, end, &str, &sz) == -1)
                                         ^
As the already existing code using spoe_decode_buffer() already use such pointers to
uint64_t, in place of pointer to size_t ;), most of this code is in contrib directory,
this simple patch modifies the prototype of spoe_decode_buffer() so that to use a
pointer to uint64_t in place of a pointer to size_t, uint64_t type being the type
finally required for decode_varint().
2017-08-22 11:27:20 +02:00
Willy Tarreau
a5480694bf MINOR: http: export some of the HTTP parser macros
The two macros EXPECT_LF_HERE and EAT_AND_JUMP_OR_RETURN were exported
for use outside the HTTP parser. They now take extra arguments to avoid
implicit pointers and jump labels. These will be used to reimplement a
minimalist HTTP/1 parser in the H1->H2 gateway.
2017-08-18 13:38:47 +02:00
Willy Tarreau
b6b3f660d0 TESTS: ist: add a test file for the functions
This test file covers the various functions provided by ist.h. It allows
both to test them for absence of regression, and to observe the code
emitted at different optimization levels.
2017-08-18 13:38:47 +02:00
Willy Tarreau
e11f727c95 MINOR: ist: implement very simple indirect strings
For HPACK we'll need to perform a lot of string manipulation between the
dynamic headers table and the output stream, and we need an efficient way
to deal with that, considering that the zero character is not an end of
string marker here. It turns out that gcc supports returning structs from
functions and is able to place up to two words directly in registers when
-freg-struct is used, which is the case by default on x86 and armv8. On
other architectures the caller reserves some stack space where the callee
can write, which is equivalent to passing a pointer to the return value.

So let's implement a few functions to deal with this as the resulting code
will be optimized on certain architectures where retrieving the length of
a string will simply consist in reading one of the two returned registers.

Extreme care was taken to ensure that the compiler gets maximum opportunities
to optimize out every bit of unused code. This is also the reason why no
call to regular string functions (such as strlen(), memcmp(), memcpy() etc)
were used. The code involving them is often larger than when they are open
coded. Given that strings are usually very small, especially when manipulating
headers, the time spent calling a function optimized for large vectors often
ends up being higher than the few cycles needed to count a few bytes.

An issue was met with __builtin_strlen() which can automatically convert
a constant string to its constant length. It doesn't accept NULLs and there
is no way to hide them using expressions as the check is made before the
optimizer is called. On gcc 4 and above, using an intermediary variable
is enough to hide it. On older versions, calls to ist() with an explicit
NULL argument will issue a warning. There is normally no reason to do this
but taking care of it the best possible still seems important.
2017-08-18 13:38:47 +02:00
Willy Tarreau
f92a73d2fc MEDIUM: session: do not free a session until no stream references it
We now refrain from clearing a session's variables, counters, and from
releasing it as long as at least one stream references it. For now it
never happens but with H2 this will be mandatory to avoid double frees.
2017-08-18 13:26:35 +02:00
Willy Tarreau
2bfd35885e MINOR: stream: link the stream to its session
Now each stream is added to the session's list of streams, so that it
will be possible to know all the streams belonging to a session, and
to know if any stream is still attached to a sessoin.
2017-08-18 13:26:35 +02:00
Willy Tarreau
bcb86abaca MINOR: session: add a streams field to the session struct
This will be used to hold the list of streams belonging to a given session.
2017-08-18 13:26:35 +02:00
Willy Tarreau
82032f1223 MINOR: chunks: add chunk_memcpy() and chunk_memcat()
These two functions respectively copy a memory area onto the chunk, and
append the contents of a memory area over a chunk. They are convenient
to prepare binary output data to be sent and will be used for HTTP/2.
2017-08-18 13:26:20 +02:00
Baptiste Assmann
686408bb6c MINOR: dns: default "hold obsolete" timeout set to 0
The "hold obsolete" timer is used to prevent HAProxy from moving a server to
an other IP or from considering the server as DOWN if the IP currently
affected to this server has not been seen for this period of time in DNS
responses.

That said, historically, HAProxy used to update servers as soon as the IP
has disappeared from the response. Current default timeout break this
historical behavior and may change HAProxy's behavior when people will
upgrade to 1.8.

This patch changes the default value to 0 to keep backward compatibility.
2017-08-18 11:26:14 +02:00
Baptiste Assmann
2af08fe3de MINOR: dns: enabled edns0 extension and make accpeted payload size tunable
Edns extensions may be used to negotiate some settings between a DNS
client and a server.
For now we only use it to announce the maximum response payload size accpeted
by HAProxy.
This size can be set through a configuration parameter in the resolvers
section. If not set, it defaults to 512 bytes.
2017-08-18 11:25:56 +02:00
Baptiste Assmann
572ab8b269 MINOR: dns: new dns record type (RTYPE) for OPT
DNS record type OPT is required to send additional records.
OPT has been assigned ID 41.
2017-08-18 11:25:49 +02:00
Baptiste Assmann
6fb8192b28 MINOR: dns: enable caching of responses for server set by a SRV record
The function srv_set_fqdn() is used to update a server's fqdn and set
accordingly its DNS resolution.
Current implementation prevents a server whose update is triggered by a
SRV record from being linked to an existing resolution in the cache (if
applicable).
This patch aims at fixing this.
2017-08-18 11:25:41 +02:00
Baptiste Assmann
7d2a12662b MINOR: dns: ability to use a SRV resolution for multiple backends
Current code implementation prevents multiple backends from relying on
the same SRV resolution. Actually, only the first backend which triggers
the resolution gets updated.

This patch makes HAProxy to process the whole list of the 'curr'
requesters to apply the changes everywhere (hence, the cache also applies
to SRV records...)
2017-08-18 11:25:31 +02:00
Baptiste Assmann
a644aa8e39 MINOR: dns: make debugging function dump_dns_config() compatible with SRV records
This function is particularly useful when debugging DNS resolution at
run time in HAProxy.
SRV records must be read differently, hence we have to update this
function.
2017-08-18 11:25:25 +02:00
Baptiste Assmann
2043327170 MINOR: dns: duplicate entries in resolution wait queue for SRV records
This loop is useless and duplicates entries into the resolution queue
for nothing.
Entries are already added a bit sooner in the same function.
2017-08-18 11:25:04 +02:00
Baptiste Assmann
63a2811077 MINOR: dns: update dns response buffer reading pointer due to SRV record
DNS SRV records uses "dns name compression" to store the target name.
"dns compression" principle is simple. Let's take the name below:
  3336633266663038.red.default.svc.cluster.local.
It can be stored "as is" in the response or it can be compressed like
this:
  3336633266663038<POINTER>
and <POINTER> would point to the string
'.red.default.svc.cluster.local.' availble in the question section for
example.
This mechanism allows storing much more data in a single DNS response.

This means the flag "record->data_len" which stores the size of the
record (hence the whole string, uncompressed) can't be used to move the
pointer forward when reading responses. We must use the "offset" integer
which means the real number of bytes occupied by the target name.

If we don't do that, we can properly read the first SRV record, then we
loose alignment and we start reading unrelated data (still in the
response) leading to a false negative error treated as an "invalid"
response...
2017-08-18 11:24:57 +02:00
Baptiste Assmann
ddc8ce6d29 MINOR: dns: update record dname matching for SRV query types
DNS response for SRV queries look like this:
- query dname looks like '_http._tcp.red.default.svc.cluster.local'
- answer record dname looks like
  '3336633266663038.red.default.svc.cluster.local.'

Of course, it never matches... and it triggers many false positive in
the current code (which is suitable for A/AAAA/CNAME).

This patch simply ignores this dname matching in the case of SRV query
type.
2017-08-18 11:24:45 +02:00
Baptiste Assmann
251abb9cbe MINOR: dns: Update analysis of TRUNCATED response for SRV records
First implementation of the DNS parser used to consider TRUNCATED
responses as errors and triggered a failover to an other query type
(usually A to AAAA or vice-versa).

When we query for SRV records, a TRUNCATED response still contains valid
records we can exploit, so we shouldn't trigger a failover in such case.

Note that we had to move the maching against the flag later in the
response parsing (actually, until we can read the query type....)
2017-08-18 11:24:35 +02:00
Olivier Houchard
97148f60b8 MINOR: init: Fix CPU affinity setting on FreeBSD.
Use a cpuset_t instead of assuming the cpu mask is an unsigned long.
This should fix setting the CPU affinity on FreeBSD >= 11.

This patch should be backported to stable releases.
2017-08-17 18:39:52 +02:00
Olivier Houchard
0d00593361 CLEANUP: raw_sock: Use a better name for the constructor than __ssl_sock_deinit()
I just noticed the raw socket constructor was called __ssl_sock_deinit,
which is a bit confusing, and wrong twice, so the attached patch renames it
to __raw_sock_init, which seems more correct.
2017-08-17 18:33:21 +02:00
Willy Tarreau
7632548d97 BUG/MAJOR: stream: in stream_free(), close the front endpoint and not the origin
stream_free() used to close the front connection by using s->sess->origin,
instead of using s->si[0].end. This is very visible in HTTP/2 where the
front connection is abusively closed and causes all sort of issues including
crashes caused by double closes due to the same origin being referenced many
times.

It's also suspected that it may have caused some of the early issues met
during the Lua development.

It's uncertain whether stable branches are affected. It might be worth
backporting it once it has been confirmed not to create new impacts.
2017-08-17 18:26:56 +02:00
Willy Tarreau
50bc31d4d6 BUILD/MINOR: build without openssl still broken
As mentionned in commit cf4e496c9 ("BUG/MEDIUM: build without openssl broken"),
commit 872f9c213 ("MEDIUM: ssl: add basic support for OpenSSL crypto engine")
broke the build without openssl support. But the former did only fix it when
openssl is not enabled, but not when it's not installed on the system :

In file included from src/haproxy.c:112:
include/proto/ssl_sock.h:24:25: openssl/ssl.h: No such file or directory
In file included from src/haproxy.c:112:
include/proto/ssl_sock.h:45: error: syntax error before "SSL_CTX"
include/proto/ssl_sock.h:75: error: syntax error before '*' token
include/proto/ssl_sock.h:75: warning: type defaults to `int' in declaration of `ssl_sock_create_cert'
include/proto/ssl_sock.h:75: warning: data definition has no type or storage class
include/proto/ssl_sock.h:76: error: syntax error before '*' token
include/proto/ssl_sock.h:76: warning: type defaults to `int' in declaration of `ssl_sock_get_generated_cert'
include/proto/ssl_sock.h:76: warning: data definition has no type or storage class
include/proto/ssl_sock.h:77: error: syntax error before '*' token

Now we also surround the include with #ifdef USE_OPENSSL to fix this. No
backport is needed since openssl async engines were not backported.
2017-08-16 19:21:31 +02:00
Emmanuel Hocdet
15969297af BUILD: ssl: replace SSL_CTX_get0_privatekey for openssl < 1.0.2
Commit 48a8332a introduce SSL_CTX_get0_privatekey in openssl-compat.h but
SSL_CTX_get0_privatekey access internal structure and can't be a candidate
to openssl-compat.h. The workaround with openssl < 1.0.2 is to use SSL_new
then SSL_get_privatekey.
2017-08-11 11:35:26 +02:00
Willy Tarreau
286ec68f82 BUILD/MINOR: cli: shut a minor gcc warning in "show fd"
Recent commit 7a4a0ac ("MINOR: cli: add a new "show fd" command") introduced
a warning when building at -O2 and above. The compiler doesn't know if a
variable's value might have changed between two if blocks so warns that some
values might be used uninitialized, which is not the case. Let's simply
initialize them to shut the warning.
2017-08-09 16:35:44 +02:00
Olivier Houchard
ecfa18dda6 MINOR: doc: Document SRV label usage. 2017-08-09 16:32:50 +02:00
Olivier Houchard
b68fda40d7 MINOR: check: Fix checks when using SRV records.
When started, a server may not yet have an associated protocol, so don't
bother trying to run the checks until it is there.
2017-08-09 16:32:50 +02:00
Olivier Houchard
8da5f98fbe MINOR: dns: Handle SRV records.
Make it so for each server, instead of specifying a hostname, one can use
a SRV label.
When doing so, haproxy will first resolve the SRV label, then use the
resulting hostnames, as well as port and weight (priority is ignored right
now), to each server using the SRV label.
It is resolved periodically, and any server disappearing from the SRV records
will be removed, and any server appearing will be added, assuming there're
free servers in haproxy.
2017-08-09 16:32:49 +02:00
Olivier Houchard
e962fd880d Add a few functions to do unaligned access.
Add a few functions to read 16bits and 32bits integers that may be
unaligned, both in host and network order.
2017-08-09 16:32:49 +02:00
Olivier Houchard
e2c222b12f MINOR: obj: Add a new type of object, OBJ_TYPE_SRVRQ.
dns_srvrq will be objects used for dealing with SRV records.
2017-08-09 16:32:49 +02:00
Olivier Houchard
a8c6db8d2d MINOR: dns: Cache previous DNS answers.
As DNS servers may not return all IPs in one answer, we want to cache the
previous entries. Those entries are removed when considered obsolete, which
happens when the IP hasn't been returned by the DNS server for a time
defined in the "hold obsolete" parameter of the resolver section. The default
is 30s.
2017-08-09 16:32:49 +02:00
Emmanuel Hocdet
aa0d637292 MINOR: ssl: allow to start without certificate if strict-sni is set
With strict-sni, ssl connection will fail if no certificate match. Have no
certificate in bind line, fail on all ssl connections. It's ok with the
behavior of strict-sni. When 'generate-certificates' is set 'strict-sni' is
never used. When 'strict-sni' is set, default_ctx is never used. Allow to start
without certificate only in this case.

Use case is to start haproxy with ssl before customer start to use certificates.
Typically with 'crt' on a empty directory and 'strict-sni' parameters.
2017-08-09 16:30:28 +02:00