MAJOR: stream interface: dynamically allocate the outgoing connection

The outgoing connection is now allocated dynamically upon the first attempt
to touch the connection's source or destination address. If this allocation
fails, we fail on SN_ERR_RESOURCE.

As we didn't use si->conn anymore, it was removed. The endpoints are released
upon session_free(), on the error path, and upon a new transaction. That way
we are able to carry the existing server's address across retries.

The stream interfaces are not initialized anymore before session_complete(),
so we could even think about allocating them dynamically as well, though
that would not provide much savings.

The session initialization now makes use of conn_new()/conn_free(). This
slightly simplifies the code and makes it more logical. The connection
initialization code is now shorter by about 120 bytes because it's done
at once, allowing the compiler to remove all redundant initializations.

The si_attach_applet() function now takes care of first detaching the
existing endpoint, and it is called from stream_int_register_handler(),
so we can safely remove the calls to si_release_endpoint() in the
application code around this call.

A call to si_detach() was made upon stream_int_unregister_handler() to
ensure we always free the allocated connection if one was allocated in
parallel to setting an applet (eg: detect HTTP proxy while proceeding
with stats maybe).
diff --git a/src/backend.c b/src/backend.c
index a06a332..fdfbb9b 100644
--- a/src/backend.c
+++ b/src/backend.c
@@ -708,14 +708,14 @@
  * Upon successful return, the session flag SN_ADDR_SET is set. This flag is
  * not cleared, so it's to the caller to clear it if required.
  *
- * The address is set on si->conn only. This connection is expected to be
- * already allocated and initialized.
+ * The caller is responsible for having already assigned a connection
+ * to si->end.
  *
  */
 int assign_server_address(struct session *s)
 {
 	struct connection *cli_conn = objt_conn(s->req->prod->end);
-	struct connection *srv_conn = s->req->cons->conn;
+	struct connection *srv_conn = objt_conn(s->req->cons->end);
 
 #ifdef DEBUG_FULL
 	fprintf(stderr,"assign_server_address : s=%p\n",s);
@@ -907,7 +907,7 @@
 /* If an explicit source binding is specified on the server and/or backend, and
  * this source makes use of the transparent proxy, then it is extracted now and
  * assigned to the session's pending connection. This function assumes that an
- * outgoing connection has already been allocated into s->req->cons->conn.
+ * outgoing connection has already been assigned to s->req->cons->end.
  */
 static void assign_tproxy_address(struct session *s)
 {
@@ -915,7 +915,7 @@
 	struct server *srv = objt_server(s->target);
 	struct conn_src *src;
 	struct connection *cli_conn;
-	struct connection *srv_conn = s->req->cons->conn;
+	struct connection *srv_conn = objt_conn(s->req->cons->end);
 
 	if (srv && srv->conn_src.opts & CO_SRC_BIND)
 		src = &srv->conn_src;
@@ -982,10 +982,13 @@
 int connect_server(struct session *s)
 {
 	struct connection *cli_conn;
-	struct connection *srv_conn = s->req->cons->conn;
+	struct connection *srv_conn = si_alloc_conn(s->req->cons);
 	struct server *srv;
 	int err;
 
+	if (!srv_conn)
+		return SN_ERR_RESOURCE;
+
 	if (!(s->flags & SN_ADDR_SET)) {
 		err = assign_server_address(s);
 		if (err != SRV_STATUS_OK)