BUG/MEDIUM: mux-h2: properly consider the peer's advertised max-concurrent-streams

Till now we used to only rely on tune.h2.max-concurrent-streams but if
a peer advertises a lower limit this can cause streams to be reset or
even the conection to be killed. Let's respect the peer's value for
outgoing streams.

This patch should be backported to 1.9, though it depends on the following
ones :
    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
diff --git a/src/mux_h2.c b/src/mux_h2.c
index 4c87d72..fabbe1c 100644
--- a/src/mux_h2.c
+++ b/src/mux_h2.c
@@ -433,13 +433,13 @@
 	if (h2c->last_sid >= 0)
 		return 0;
 
-	/* XXX Should use the negociated max concurrent stream nb instead of the conf value */
-	ret1 = h2_settings_max_concurrent_streams - h2c->nb_streams;
+	/* note: may be negative if a SETTINGS frame changes the limit */
+	ret1 = h2c->streams_limit - h2c->nb_streams;
 
 	/* we must also consider the limit imposed by stream IDs */
 	ret2 = h2_streams_left(h2c);
 	ret1 = MIN(ret1, ret2);
-	if (ret1 && srv && srv->max_reuse >= 0) {
+	if (ret1 > 0 && srv && srv->max_reuse >= 0) {
 		ret2 = h2c->stream_cnt <= srv->max_reuse ? srv->max_reuse - h2c->stream_cnt + 1: 0;
 		ret1 = MIN(ret1, ret2);
 	}
@@ -976,7 +976,7 @@
 {
 	struct h2s *h2s = NULL;
 
-	if (h2c->nb_streams >= h2_settings_max_concurrent_streams)
+	if (h2c->nb_streams >= h2c->streams_limit)
 		goto out;
 
 	if (h2_streams_left(h2c) < 1)
@@ -2997,7 +2997,7 @@
 			/* Never ever allow to reuse a connection from a non-reuse backend */
 			if ((h2c->proxy->options & PR_O_REUSE_MASK) == PR_O_REUSE_NEVR)
 				h2c->conn->flags |= CO_FL_PRIVATE;
-			if (LIST_ISEMPTY(&h2c->conn->list) && h2c->nb_streams < h2_settings_max_concurrent_streams) {
+			if (LIST_ISEMPTY(&h2c->conn->list) && h2c->nb_streams < h2c->streams_limit) {
 				struct server *srv = objt_server(h2c->conn->target);
 
 				if (srv) {