[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#771043: unblock: haproxy/1.5.9-1 (pre-approval)



Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: unblock

Hi,

We would like to get your approval before uploading 1.5.9-1 to unstable.
Upstream has released a new stable release in the 1.5 branch, containing 
important bugfixes and a minor new feature. The bugfixes (sorted by 
severity) are:

 - BUG/MAJOR: frontend: initialize capture pointers earlier
 - BUG/MAJOR: sessions: unlink session from list on out of memory
 - BUG/MEDIUM: checks: fix conflicts between agent checks and ssl healthchecks
 - BUG/MEDIUM: connection: sanitize PPv2 header length before parsing
               address information
 - BUG/MEDIUM: pattern: don't load more than once a pattern list.
 - BUG/MEDIUM: ssl: fix bad ssl context init can cause segfault in case of OOM.
 - BUG/MEDIUM: ssl: force a full GC in case of memory shortage
 - BUG/MINOR: config: don't inherit the default balance algorithm in frontends
 - BUG/MINOR: peers: the buffer size is global.tune.bufsize, not trash.size
 - BUG/MINOR: samples: fix unnecessary memcopy converting binary to string.
 - BUG/MINOR: stats: correctly set the request/response analysers
 - BUILD: fix "make install" to support spaces in the install dirs
 - DOC: fix typo in the body parser documentation for msg.sov

The first major bugfix fixes a segfault when haproxy is used in TCP mode 
and payload inspection is performed, as reported in

          http://marc.info/?l=haproxy&m=141694607720769&w=2

The other major bugfix fixes a potential memory corruption under memory 
pressure.

The only new feature is adding access to three internal variables (the 
number of processes, the process number and whether a process is
shutting down) that can be used for logging and debugging purposes.

The full changes against 1.5.8-1 are attached as a debdiff.

unblock haproxy/1.5.9-1

-- System Information:
Debian Release: jessie/sid
  APT prefers testing
  APT policy: (500, 'testing'), (90, 'unstable'), (1, 'experimental')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 3.16-3-amd64 (SMP w/4 CPU cores)
Locale: LANG=el_GR.UTF-8, LC_CTYPE=el_GR.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
diff -Nru haproxy-1.5.8/CHANGELOG haproxy-1.5.9/CHANGELOG
--- haproxy-1.5.8/CHANGELOG	2014-10-31 11:06:53.000000000 +0200
+++ haproxy-1.5.9/CHANGELOG	2014-11-26 01:38:07.000000000 +0200
@@ -1,6 +1,22 @@
 ChangeLog :
 ===========
 
+2014/11/26 : 1.5.9
+    - BUILD: fix "make install" to support spaces in the install dirs
+    - BUG/MEDIUM: checks: fix conflicts between agent checks and ssl healthchecks
+    - 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.
+    - BUG/MEDIUM: connection: sanitize PPv2 header length before parsing address information
+    - BUG/MEDIUM: pattern: don't load more than once a pattern list.
+    - BUG/MEDIUM: ssl: force a full GC in case of memory shortage
+    - 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
+    - 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)
+    - BUG/MAJOR: sessions: unlink session from list on out of memory
+
 2014/10/31 : 1.5.8
     - BUG/MAJOR: buffer: check the space left is enough or not when input data in a buffer is wrapped
     - BUG/BUILD: revert accidental change in the makefile from latest SSL fix
diff -Nru haproxy-1.5.8/debian/changelog haproxy-1.5.9/debian/changelog
--- haproxy-1.5.8/debian/changelog	2014-10-31 14:54:12.000000000 +0200
+++ haproxy-1.5.9/debian/changelog	2014-11-26 11:14:25.000000000 +0200
@@ -1,3 +1,28 @@
+haproxy (1.5.9-1) unstable; urgency=medium
+
+  * New upstream stable release including the following fixes:
+     + BUG/MAJOR: frontend: initialize capture pointers earlier
+     + BUG/MAJOR: sessions: unlink session from list on out of memory
+     + BUG/MEDIUM: checks: fix conflicts between agent checks and ssl
+                   healthchecks
+     + BUG/MEDIUM: connection: sanitize PPv2 header length before parsing
+                   address information
+     + BUG/MEDIUM: pattern: don't load more than once a pattern list.
+     + BUG/MEDIUM: ssl: fix bad ssl context init can cause segfault in case of
+                   OOM.
+     + BUG/MEDIUM: ssl: force a full GC in case of memory shortage
+     + BUG/MINOR: config: don't inherit the default balance algorithm in
+                  frontends
+     + BUG/MINOR: peers: the buffer size is global.tune.bufsize, not trash.size
+     + BUG/MINOR: samples: fix unnecessary memcopy converting binary to string.
+     + BUG/MINOR: stats: correctly set the request/response analysers
+     + BUILD: fix "make install" to support spaces in the install dirs
+     + DOC: fix typo in the body parser documentation for msg.sov
+   * Also includes the following new features:
+     + MINOR: sample: add a few basic internal fetches (nbproc, proc, stopping)
+
+ -- Apollon Oikonomopoulos <apoikos@debian.org>  Wed, 26 Nov 2014 11:08:43 +0200
+
 haproxy (1.5.8-1) unstable; urgency=medium
 
   * New upstream stable release including the following fixes:
diff -Nru haproxy-1.5.8/doc/configuration.txt haproxy-1.5.9/doc/configuration.txt
--- haproxy-1.5.8/doc/configuration.txt	2014-10-31 11:06:53.000000000 +0200
+++ haproxy-1.5.9/doc/configuration.txt	2014-11-26 01:38:07.000000000 +0200
@@ -2,9 +2,9 @@
                                 HAProxy
                           Configuration Manual
                          ----------------------
-                             version 1.5.8
+                             version 1.5.9
                              willy tarreau
-                              2014/10/31
+                              2014/11/25
 
 
 This document covers the configuration language as implemented in the version
@@ -10180,6 +10180,11 @@
             tcp-request content accept if ! too_fast
             tcp-request content accept if WAIT_END
 
+nbproc : integer
+  Returns an integer value corresponding to the number of processes that were
+  started (it equals the global "nbproc" setting). This is useful for logging
+  and debugging purposes.
+
 nbsrv([<backend>]) : integer
   Returns an integer value corresponding to the number of usable servers of
   either the current backend or the named backend. This is mostly used with
@@ -10188,6 +10193,11 @@
   to handle some load. It is useful to report a failure when combined with
   "monitor fail".
 
+proc : integer
+  Returns an integer value corresponding to the position of the process calling
+  the function, between 1 and global.nbproc. This is useful for logging and
+  debugging purposes.
+
 queue([<backend>]) : integer
   Returns the total number of queued connections of the designated backend,
   including all the connections in server queues. If no backend name is
@@ -10238,6 +10248,11 @@
         acl srv2_full srv_sess_rate(be1/srv2) gt 50
         use_backend be2 if srv1_full or srv2_full
 
+stopping : boolean
+  Returns TRUE if the process calling the function is currently stopping. This
+  can be useful for logging, or for relaxing certain checks or helping close
+  certain connections upon graceful shutdown.
+
 table_avl([<table>]) : integer
   Returns the total number of available entries in the current proxy's
   stick-table or in the designated stick-table. See also table_cnt.
diff -Nru haproxy-1.5.8/doc/internals/body-parsing.txt haproxy-1.5.9/doc/internals/body-parsing.txt
--- haproxy-1.5.8/doc/internals/body-parsing.txt	2014-10-31 11:06:53.000000000 +0200
+++ haproxy-1.5.9/doc/internals/body-parsing.txt	2014-11-26 01:38:07.000000000 +0200
@@ -69,7 +69,7 @@
 msg.sov  : start of value. First character of the header's value in the header
            states, start of the body in the data states. Strictly positive
            values indicate that headers were not forwarded yet (<buf.p> is
-           before the start of the body), and null or positive values are seen
+           before the start of the body), and null or negative values are seen
            after headers are forwarded (<buf.p> is at or past the start of the
            body). The value stops changing when data start to leave the buffer
            (in order to avoid integer overflows). So the maximum possible range
diff -Nru haproxy-1.5.8/examples/haproxy.spec haproxy-1.5.9/examples/haproxy.spec
--- haproxy-1.5.8/examples/haproxy.spec	2014-10-31 11:06:53.000000000 +0200
+++ haproxy-1.5.9/examples/haproxy.spec	2014-11-26 01:38:07.000000000 +0200
@@ -1,6 +1,6 @@
 Summary: HA-Proxy is a TCP/HTTP reverse proxy for high availability environments
 Name: haproxy
-Version: 1.5.8
+Version: 1.5.9
 Release: 1
 License: GPL
 Group: System Environment/Daemons
@@ -76,6 +76,9 @@
 %attr(0755,root,root) %config %{_sysconfdir}/rc.d/init.d/%{name}
 
 %changelog
+* Wed Nov 26 2014 Willy Tarreau <w@1wt.eu>
+- updated to 1.5.9
+
 * Fri Oct 31 2014 Willy Tarreau <w@1wt.eu>
 - updated to 1.5.8
 
diff -Nru haproxy-1.5.8/include/proto/pattern.h haproxy-1.5.9/include/proto/pattern.h
--- haproxy-1.5.8/include/proto/pattern.h	2014-10-31 11:06:53.000000000 +0200
+++ haproxy-1.5.9/include/proto/pattern.h	2014-11-26 01:38:07.000000000 +0200
@@ -206,7 +206,8 @@
  */
 void pattern_init_expr(struct pattern_expr *expr);
 struct pattern_expr *pattern_lookup_expr(struct pattern_head *head, struct pat_ref *ref);
-struct pattern_expr *pattern_new_expr(struct pattern_head *head, struct pat_ref *ref, char **err);
+struct pattern_expr *pattern_new_expr(struct pattern_head *head, struct pat_ref *ref,
+                                      char **err, int *reuse);
 struct sample_storage **pattern_find_smp(struct pattern_expr *expr, struct pat_ref_elt *elt);
 int pattern_delete(struct pattern_expr *expr, struct pat_ref_elt *ref);
 
diff -Nru haproxy-1.5.8/include/types/checks.h haproxy-1.5.9/include/types/checks.h
--- haproxy-1.5.8/include/types/checks.h	2014-10-31 11:06:53.000000000 +0200
+++ haproxy-1.5.9/include/types/checks.h	2014-11-26 01:38:07.000000000 +0200
@@ -125,6 +125,7 @@
 };
 
 struct check {
+	struct xprt_ops *xprt;			/* transport layer operations for health checks */
 	struct connection *conn;		/* connection state for health checks */
 	unsigned short port;			/* the port to use for the health checks */
 	struct buffer *bi, *bo;			/* input and output buffers to send/recv check */
@@ -132,7 +133,7 @@
 	struct timeval start;			/* last health check start time */
 	long duration;				/* time in ms took to finish last health check */
 	short status, code;			/* check result, check code */
-	char desc[HCHK_DESC_LEN];		/* health check descritpion */
+	char desc[HCHK_DESC_LEN];		/* health check description */
 	int use_ssl;				/* use SSL for health checks */
 	int send_proxy;				/* send a PROXY protocol header with checks */
 	struct tcpcheck_rule *current_step;     /* current step when using tcpcheck */
diff -Nru haproxy-1.5.8/include/types/server.h haproxy-1.5.9/include/types/server.h
--- haproxy-1.5.8/include/types/server.h	2014-10-31 11:06:53.000000000 +0200
+++ haproxy-1.5.9/include/types/server.h	2014-11-26 01:38:07.000000000 +0200
@@ -194,7 +194,6 @@
 
 	struct {                                /* configuration  used by health-check and agent-check */
 		struct protocol *proto;	        /* server address protocol for health checks */
-		struct xprt_ops *xprt;          /* transport layer operations for health checks */
 		struct sockaddr_storage addr;   /* the address to check, if different from <addr> */
 	} check_common;
 
diff -Nru haproxy-1.5.8/Makefile haproxy-1.5.9/Makefile
--- haproxy-1.5.8/Makefile	2014-10-31 11:06:53.000000000 +0200
+++ haproxy-1.5.9/Makefile	2014-11-26 01:38:07.000000000 +0200
@@ -710,19 +710,19 @@
 	$(CC) $(COPTS) -DDEFAULT_MMAP_THRESHOLD=$(DLMALLOC_THRES) -c -o $@ $<
 
 install-man:
-	install -d $(DESTDIR)$(MANDIR)/man1
-	install -m 644 doc/haproxy.1 $(DESTDIR)$(MANDIR)/man1
+	install -d "$(DESTDIR)$(MANDIR)"/man1
+	install -m 644 doc/haproxy.1 "$(DESTDIR)$(MANDIR)"/man1
 
 install-doc:
-	install -d $(DESTDIR)$(DOCDIR)
+	install -d "$(DESTDIR)$(DOCDIR)"
 	for x in configuration architecture haproxy-en haproxy-fr; do \
-		install -m 644 doc/$$x.txt $(DESTDIR)$(DOCDIR) ; \
+		install -m 644 doc/$$x.txt "$(DESTDIR)$(DOCDIR)" ; \
 	done
 
 install-bin: haproxy haproxy-systemd-wrapper
-	install -d $(DESTDIR)$(SBINDIR)
-	install haproxy $(DESTDIR)$(SBINDIR)
-	install haproxy-systemd-wrapper $(DESTDIR)$(SBINDIR)
+	install -d "$(DESTDIR)$(SBINDIR)"
+	install haproxy "$(DESTDIR)$(SBINDIR)"
+	install haproxy-systemd-wrapper "$(DESTDIR)$(SBINDIR)"
 
 install: install-bin install-man install-doc
 
diff -Nru haproxy-1.5.8/README haproxy-1.5.9/README
--- haproxy-1.5.8/README	2014-10-31 11:06:53.000000000 +0200
+++ haproxy-1.5.9/README	2014-11-26 01:38:07.000000000 +0200
@@ -1,9 +1,9 @@
                          ----------------------
                              HAProxy how-to
                          ----------------------
-                             version 1.5.8
+                             version 1.5.9
                              willy tarreau
-                               2014/10/31
+                               2014/11/25
 
 
 1) How to build it
diff -Nru haproxy-1.5.8/src/acl.c haproxy-1.5.9/src/acl.c
--- haproxy-1.5.8/src/acl.c	2014-10-31 11:06:53.000000000 +0200
+++ haproxy-1.5.9/src/acl.c	2014-11-26 01:38:07.000000000 +0200
@@ -532,7 +532,7 @@
 	}
 
 	/* Create new pattern expression associated to this reference. */
-	pattern_expr = pattern_new_expr(&expr->pat, ref, err);
+	pattern_expr = pattern_new_expr(&expr->pat, ref, err, NULL);
 	if (!pattern_expr)
 		goto out_free_expr;
 
diff -Nru haproxy-1.5.8/src/cfgparse.c haproxy-1.5.9/src/cfgparse.c
--- haproxy-1.5.8/src/cfgparse.c	2014-10-31 11:06:53.000000000 +0200
+++ haproxy-1.5.9/src/cfgparse.c	2014-11-26 01:38:07.000000000 +0200
@@ -2003,7 +2003,6 @@
 		curproxy->no_options = defproxy.no_options;
 		curproxy->no_options2 = defproxy.no_options2;
 		curproxy->bind_proc = defproxy.bind_proc;
-		curproxy->lbprm.algo = defproxy.lbprm.algo;
 		curproxy->except_net = defproxy.except_net;
 		curproxy->except_mask = defproxy.except_mask;
 		curproxy->except_to = defproxy.except_to;
@@ -2037,6 +2036,7 @@
 		}
 
 		if (curproxy->cap & PR_CAP_BE) {
+			curproxy->lbprm.algo = defproxy.lbprm.algo;
 			curproxy->fullconn = defproxy.fullconn;
 			curproxy->conn_retries = defproxy.conn_retries;
 			curproxy->max_ka_queue = defproxy.max_ka_queue;
diff -Nru haproxy-1.5.8/src/checks.c haproxy-1.5.9/src/checks.c
--- haproxy-1.5.8/src/checks.c	2014-10-31 11:06:53.000000000 +0200
+++ haproxy-1.5.9/src/checks.c	2014-11-26 01:38:07.000000000 +0200
@@ -1413,7 +1413,7 @@
 
 	/* prepare a new connection */
 	conn_init(conn);
-	conn_prepare(conn, s->check_common.proto, s->check_common.xprt);
+	conn_prepare(conn, s->check_common.proto, check->xprt);
 	conn_attach(conn, check, &check_conn_cb);
 	conn->target = &s->obj_type;
 
diff -Nru haproxy-1.5.8/src/connection.c haproxy-1.5.9/src/connection.c
--- haproxy-1.5.8/src/connection.c	2014-10-31 11:06:53.000000000 +0200
+++ haproxy-1.5.9/src/connection.c	2014-11-26 01:38:07.000000000 +0200
@@ -424,6 +424,9 @@
 	case 0x01: /* PROXY command */
 		switch (hdr_v2->fam) {
 		case 0x11:  /* TCPv4 */
+			if (ntohs(hdr_v2->len) < PP2_ADDR_LEN_INET)
+				goto bad_header;
+
 			((struct sockaddr_in *)&conn->addr.from)->sin_family = AF_INET;
 			((struct sockaddr_in *)&conn->addr.from)->sin_addr.s_addr = hdr_v2->addr.ip4.src_addr;
 			((struct sockaddr_in *)&conn->addr.from)->sin_port = hdr_v2->addr.ip4.src_port;
@@ -433,6 +436,9 @@
 			conn->flags |= CO_FL_ADDR_FROM_SET | CO_FL_ADDR_TO_SET;
 			break;
 		case 0x21:  /* TCPv6 */
+			if (ntohs(hdr_v2->len) < PP2_ADDR_LEN_INET6)
+				goto bad_header;
+
 			((struct sockaddr_in6 *)&conn->addr.from)->sin6_family = AF_INET6;
 			memcpy(&((struct sockaddr_in6 *)&conn->addr.from)->sin6_addr, hdr_v2->addr.ip6.src_addr, 16);
 			((struct sockaddr_in6 *)&conn->addr.from)->sin6_port = hdr_v2->addr.ip6.src_port;
diff -Nru haproxy-1.5.8/src/frontend.c haproxy-1.5.9/src/frontend.c
--- haproxy-1.5.8/src/frontend.c	2014-10-31 11:06:53.000000000 +0200
+++ haproxy-1.5.9/src/frontend.c	2014-11-26 01:38:07.000000000 +0200
@@ -106,11 +106,17 @@
 	if (global.tune.client_rcvbuf)
 		setsockopt(cfd, SOL_SOCKET, SO_RCVBUF, &global.tune.client_rcvbuf, sizeof(global.tune.client_rcvbuf));
 
-	if (unlikely(s->fe->nb_req_cap > 0 && (s->txn.req.cap = pool_alloc2(s->fe->req_cap_pool)) == NULL))
-		goto out_return;	/* no memory */
+	if (unlikely(s->fe->nb_req_cap > 0)) {
+		if ((s->txn.req.cap = pool_alloc2(s->fe->req_cap_pool)) == NULL)
+			goto out_return;	/* no memory */
+		memset(s->txn.req.cap, 0, s->fe->nb_req_cap * sizeof(void *));
+	}
 
-	if (unlikely(s->fe->nb_rsp_cap > 0 && (s->txn.rsp.cap = pool_alloc2(s->fe->rsp_cap_pool)) == NULL))
-		goto out_free_reqcap;	/* no memory */
+	if (unlikely(s->fe->nb_rsp_cap > 0)) {
+		if ((s->txn.rsp.cap = pool_alloc2(s->fe->rsp_cap_pool)) == NULL)
+			goto out_free_reqcap;	/* no memory */
+		memset(s->txn.rsp.cap, 0, s->fe->nb_rsp_cap * sizeof(void *));
+	}
 
 	if (s->fe->http_needed) {
 		/* we have to allocate header indexes only if we know
diff -Nru haproxy-1.5.8/src/pattern.c haproxy-1.5.9/src/pattern.c
--- haproxy-1.5.8/src/pattern.c	2014-10-31 11:06:53.000000000 +0200
+++ haproxy-1.5.9/src/pattern.c	2014-11-26 01:38:07.000000000 +0200
@@ -1855,12 +1855,19 @@
  * <ref> can be NULL. If an error is occured, the function returns NULL and
  * <err> is filled. Otherwise, the function returns new pattern_expr linked
  * with <head> and <ref>.
+ *
+ * The returned value can be a alredy filled pattern list, in this case the
+ * flag <reuse> is set.
  */
-struct pattern_expr *pattern_new_expr(struct pattern_head *head, struct pat_ref *ref, char **err)
+struct pattern_expr *pattern_new_expr(struct pattern_head *head, struct pat_ref *ref,
+                                      char **err, int *reuse)
 {
 	struct pattern_expr *expr;
 	struct pattern_expr_list *list;
 
+	if (reuse)
+		*reuse = 0;
+
 	/* Memory and initialization of the chain element. */
 	list = malloc(sizeof(*list));
 	if (!list) {
@@ -1915,6 +1922,8 @@
 		 * with ref and we must not free it.
 		 */
 		list->do_free = 0;
+		if (reuse)
+			*reuse = 1;
 	}
 
 	/* The new list element reference the pattern_expr. */
@@ -2087,6 +2096,7 @@
 	struct pat_ref *ref;
 	struct pattern_expr *expr;
 	struct pat_ref_elt *elt;
+	int reuse;
 
 	/* Lookup for the existing reference. */
 	ref = pat_ref_lookup(filename);
@@ -2161,12 +2171,20 @@
 	 */
 	expr = pattern_lookup_expr(head, ref);
 	if (!expr || (expr->mflags != patflags)) {
-		expr = pattern_new_expr(head, ref, err);
+		expr = pattern_new_expr(head, ref, err, &reuse);
 		if (!expr)
 			return 0;
 		expr->mflags = patflags;
 	}
 
+	/* The returned expression may be not empty, because the function
+	 * "pattern_new_expr" lookup for similar pattern list and can
+	 * reuse a already filled pattern list. In this case, we can not
+	 * reload the patterns.
+	 */
+	if (reuse)
+		return 1;
+
 	/* Load reference content in the pattern expression. */
 	list_for_each_entry(elt, &ref->head, list) {
 		if (!pat_ref_push(elt, expr, patflags, err)) {
diff -Nru haproxy-1.5.8/src/peers.c haproxy-1.5.9/src/peers.c
--- haproxy-1.5.8/src/peers.c	2014-10-31 11:06:53.000000000 +0200
+++ haproxy-1.5.9/src/peers.c	2014-11-26 01:38:07.000000000 +0200
@@ -1240,7 +1240,7 @@
 	if ((s->req->buf = pool_alloc2(pool2_buffer)) == NULL)
 		goto out_fail_req_buf; /* no memory */
 
-	s->req->buf->size = trash.size;
+	s->req->buf->size = global.tune.bufsize;
 	channel_init(s->req);
 	s->req->prod = &s->si[0];
 	s->req->cons = &s->si[1];
@@ -1266,7 +1266,7 @@
 	if ((s->rep->buf = pool_alloc2(pool2_buffer)) == NULL)
 		goto out_fail_rep_buf; /* no memory */
 
-	s->rep->buf->size = trash.size;
+	s->rep->buf->size = global.tune.bufsize;
 	channel_init(s->rep);
 	s->rep->prod = &s->si[1];
 	s->rep->cons = &s->si[0];
diff -Nru haproxy-1.5.8/src/proto_http.c haproxy-1.5.9/src/proto_http.c
--- haproxy-1.5.8/src/proto_http.c	2014-10-31 11:06:53.000000000 +0200
+++ haproxy-1.5.9/src/proto_http.c	2014-11-26 01:38:07.000000000 +0200
@@ -4086,8 +4086,7 @@
 			select_compression_request_header(s, req->buf);
 
 		/* enable the minimally required analyzers to handle keep-alive and compression on the HTTP response */
-		req->analysers = (req->analysers & AN_REQ_HTTP_BODY) |
-		                 AN_REQ_HTTP_XFER_BODY | AN_RES_WAIT_HTTP | AN_RES_HTTP_PROCESS_BE | AN_RES_HTTP_XFER_BODY;
+		req->analysers = (req->analysers & AN_REQ_HTTP_BODY) | AN_REQ_HTTP_XFER_BODY;
 		goto done;
 	}
 
diff -Nru haproxy-1.5.8/src/sample.c haproxy-1.5.9/src/sample.c
--- haproxy-1.5.8/src/sample.c	2014-10-31 11:06:53.000000000 +0200
+++ haproxy-1.5.9/src/sample.c	2014-11-26 01:38:07.000000000 +0200
@@ -497,27 +497,20 @@
 	return 1;
 }
 
-/* The sample is always copied into a new one so that smp->size is always
- * valid. The NULL char always enforces the end of string if it is met.
+/*
+ * The NULL char always enforces the end of string if it is met.
+ * Data is never changed, so we can ignore the CONST case
  */
 static int c_bin2str(struct sample *smp)
 {
-	struct chunk *trash = get_trash_chunk();
-	unsigned char c;
-	int ptr = 0;
+	int i;
 
-	while (ptr < smp->data.str.len) {
-		c = smp->data.str.str[ptr];
-		if (!c)
+	for (i = 0; i < smp->data.str.len; i++) {
+		if (!smp->data.str.str[i]) {
+			smp->data.str.len = i;
 			break;
-		trash->str[ptr] = c;
-		ptr++;
+		}
 	}
-	trash->len = ptr;
-	trash->str[ptr] = 0;
-	smp->data.str = *trash;
-	smp->type = SMP_T_STR;
-	smp->flags &= ~SMP_F_CONST;
 	return 1;
 }
 
@@ -1345,6 +1338,26 @@
 	return 1;
 }
 
+/* returns the number of processes */
+static int
+smp_fetch_nbproc(struct proxy *px, struct session *s, void *l7, unsigned int opt,
+                 const struct arg *args, struct sample *smp, const char *kw)
+{
+	smp->type = SMP_T_UINT;
+	smp->data.uint = global.nbproc;
+	return 1;
+}
+
+/* returns the number of the current process (between 1 and nbproc */
+static int
+smp_fetch_proc(struct proxy *px, struct session *s, void *l7, unsigned int opt,
+               const struct arg *args, struct sample *smp, const char *kw)
+{
+	smp->type = SMP_T_UINT;
+	smp->data.uint = relative_pid;
+	return 1;
+}
+
 /* generate a random 32-bit integer for whatever purpose, with an optional
  * range specified in argument.
  */
@@ -1363,6 +1376,16 @@
 	return 1;
 }
 
+/* returns true if the current process is stopping */
+static int
+smp_fetch_stopping(struct proxy *px, struct session *s, void *l7, unsigned int opt,
+                   const struct arg *args, struct sample *smp, const char *kw)
+{
+	smp->type = SMP_T_BOOL;
+	smp->data.uint = stopping;
+	return 1;
+}
+
 /* Note: must not be declared <const> as its list will be overwritten.
  * Note: fetches that may return multiple types must be declared as the lowest
  * common denominator, the type that can be casted into all other ones. For
@@ -1373,7 +1396,10 @@
 	{ "always_true",  smp_fetch_true,  0,            NULL, SMP_T_BOOL, SMP_USE_INTRN },
 	{ "env",          smp_fetch_env,   ARG1(1,STR),  NULL, SMP_T_STR,  SMP_USE_INTRN },
 	{ "date",         smp_fetch_date,  ARG1(0,SINT), NULL, SMP_T_UINT, SMP_USE_INTRN },
+	{ "nbproc",       smp_fetch_nbproc,0,            NULL, SMP_T_UINT, SMP_USE_INTRN },
+	{ "proc",         smp_fetch_proc,  0,            NULL, SMP_T_UINT, SMP_USE_INTRN },
 	{ "rand",         smp_fetch_rand,  ARG1(0,UINT), NULL, SMP_T_UINT, SMP_USE_INTRN },
+	{ "stopping",     smp_fetch_stopping, 0,         NULL, SMP_T_BOOL, SMP_USE_INTRN },
 	{ /* END */ },
 }};
 
diff -Nru haproxy-1.5.8/src/server.c haproxy-1.5.9/src/server.c
--- haproxy-1.5.8/src/server.c	2014-10-31 11:06:53.000000000 +0200
+++ haproxy-1.5.9/src/server.c	2014-11-26 01:38:07.000000000 +0200
@@ -929,7 +929,7 @@
 
 			newsrv->addr = *sk;
 			newsrv->proto = newsrv->check_common.proto = protocol_by_family(newsrv->addr.ss_family);
-			newsrv->xprt  = newsrv->check_common.xprt  = &raw_sock;
+			newsrv->xprt  = newsrv->check.xprt = newsrv->agent.xprt = &raw_sock;
 
 			if (!newsrv->proto) {
 				Alert("parsing [%s:%d] : Unknown protocol family %d '%s'\n",
diff -Nru haproxy-1.5.8/src/session.c haproxy-1.5.9/src/session.c
--- haproxy-1.5.8/src/session.c	2014-10-31 11:06:53.000000000 +0200
+++ haproxy-1.5.9/src/session.c	2014-11-26 01:38:07.000000000 +0200
@@ -579,6 +579,7 @@
 	/* and restore the connection pointer in case we destroyed it,
 	 * because kill_mini_session() will need it.
 	 */
+	LIST_DEL(&s->list);
 	s->target = &conn->obj_type;
 	return ret;
 }
diff -Nru haproxy-1.5.8/src/ssl_sock.c haproxy-1.5.9/src/ssl_sock.c
--- haproxy-1.5.8/src/ssl_sock.c	2014-10-31 11:06:53.000000000 +0200
+++ haproxy-1.5.9/src/ssl_sock.c	2014-11-26 01:38:07.000000000 +0200
@@ -1812,7 +1812,7 @@
 	if (srv->use_ssl)
 		srv->xprt = &ssl_sock;
 	if (srv->check.use_ssl)
-		srv->check_common.xprt = &ssl_sock;
+		srv->check.xprt = &ssl_sock;
 
 	srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
 	if (!srv->ssl_ctx.ctx) {
@@ -2033,22 +2033,51 @@
 	/* If it is in client mode initiate SSL session
 	   in connect state otherwise accept state */
 	if (objt_server(conn->target)) {
+		int may_retry = 1;
+
+	retry_connect:
 		/* Alloc a new SSL session ctx */
 		conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
 		if (!conn->xprt_ctx) {
+			if (may_retry--) {
+				pool_gc2();
+				goto retry_connect;
+			}
 			conn->err_code = CO_ER_SSL_NO_MEM;
 			return -1;
 		}
 
-		SSL_set_connect_state(conn->xprt_ctx);
-		if (objt_server(conn->target)->ssl_ctx.reused_sess)
-			SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess);
-
 		/* set fd on SSL session context */
-		SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd);
+		if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
+			SSL_free(conn->xprt_ctx);
+			conn->xprt_ctx = NULL;
+			if (may_retry--) {
+				pool_gc2();
+				goto retry_connect;
+			}
+			conn->err_code = CO_ER_SSL_NO_MEM;
+			return -1;
+		}
 
 		/* set connection pointer */
-		SSL_set_app_data(conn->xprt_ctx, conn);
+		if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
+			SSL_free(conn->xprt_ctx);
+			conn->xprt_ctx = NULL;
+			if (may_retry--) {
+				pool_gc2();
+				goto retry_connect;
+			}
+			conn->err_code = CO_ER_SSL_NO_MEM;
+			return -1;
+		}
+
+		SSL_set_connect_state(conn->xprt_ctx);
+		if (objt_server(conn->target)->ssl_ctx.reused_sess) {
+			if(!SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess)) {
+				SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
+				objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
+			}
+		}
 
 		/* leave init state and start handshake */
 		conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
@@ -2058,20 +2087,45 @@
 		return 0;
 	}
 	else if (objt_listener(conn->target)) {
+		int may_retry = 1;
+
+	retry_accept:
 		/* Alloc a new SSL session ctx */
 		conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
 		if (!conn->xprt_ctx) {
+			if (may_retry--) {
+				pool_gc2();
+				goto retry_accept;
+			}
 			conn->err_code = CO_ER_SSL_NO_MEM;
 			return -1;
 		}
 
-		SSL_set_accept_state(conn->xprt_ctx);
-
 		/* set fd on SSL session context */
-		SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd);
+		if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
+			SSL_free(conn->xprt_ctx);
+			conn->xprt_ctx = NULL;
+			if (may_retry--) {
+				pool_gc2();
+				goto retry_accept;
+			}
+			conn->err_code = CO_ER_SSL_NO_MEM;
+			return -1;
+		}
 
 		/* set connection pointer */
-		SSL_set_app_data(conn->xprt_ctx, conn);
+		if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
+			SSL_free(conn->xprt_ctx);
+			conn->xprt_ctx = NULL;
+			if (may_retry--) {
+				pool_gc2();
+				goto retry_accept;
+			}
+			conn->err_code = CO_ER_SSL_NO_MEM;
+			return -1;
+		}
+
+		SSL_set_accept_state(conn->xprt_ctx);
 
 		/* leave init state and start handshake */
 		conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
diff -Nru haproxy-1.5.8/VERDATE haproxy-1.5.9/VERDATE
--- haproxy-1.5.8/VERDATE	2014-10-31 11:06:53.000000000 +0200
+++ haproxy-1.5.9/VERDATE	2014-11-26 01:38:07.000000000 +0200
@@ -1,2 +1,2 @@
 $Format:%ci$
-2014/10/31
+2014/11/25
diff -Nru haproxy-1.5.8/VERSION haproxy-1.5.9/VERSION
--- haproxy-1.5.8/VERSION	2014-10-31 11:06:53.000000000 +0200
+++ haproxy-1.5.9/VERSION	2014-11-26 01:38:07.000000000 +0200
@@ -1 +1 @@
-1.5.8
+1.5.9

Attachment: signature.asc
Description: Digital signature


Reply to: