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/include/proto/stream_interface.h b/include/proto/stream_interface.h
index 511099c..2c69649 100644
--- a/include/proto/stream_interface.h
+++ b/include/proto/stream_interface.h
@@ -70,13 +70,24 @@
 	si->state = si->prev_state = state;
 }
 
-static inline void si_detach(struct stream_interface *si)
+/* release the endpoint if it's a connection, then nullify it */
+static inline void si_release_endpoint(struct stream_interface *si)
 {
-	si->ops = &si_embedded_ops;
+	struct connection *conn;
+
+	conn = objt_conn(si->end);
+	if (conn)
+		pool_free2(pool2_connection, conn);
 	si->end = NULL;
 	si->appctx.applet = NULL;
 }
 
+static inline void si_detach(struct stream_interface *si)
+{
+	si_release_endpoint(si);
+	si->ops = &si_embedded_ops;
+}
+
 /* Attach connection <conn> to the stream interface <si>. The stream interface
  * is configured to work with a connection and the connection it configured
  * with a stream interface data layer.
@@ -90,6 +101,7 @@
 
 static inline void si_attach_applet(struct stream_interface *si, struct si_applet *applet)
 {
+	si_release_endpoint(si);
 	si->ops = &si_embedded_ops;
 	si->appctx.applet = applet;
 	si->appctx.obj_type = OBJ_TYPE_APPCTX;
@@ -129,6 +141,28 @@
 		applet->release(si);
 }
 
+/* Returns the stream interface's existing connection if one such already
+ * exists, or tries to allocate and initialize a new one which is then
+ * assigned to the stream interface.
+ */
+static inline struct connection *si_alloc_conn(struct stream_interface *si)
+{
+	struct connection *conn;
+
+	/* we return the connection whether it's a real connection or NULL
+	 * in case another entity (an applet) is registered instead.
+	 */
+	conn = objt_conn(si->end);
+	if (si->end)
+		return conn;
+
+	conn = conn_new();
+	if (conn)
+		si_attach_conn(si, conn);
+
+	return conn;
+}
+
 /* Sends a shutr to the connection using the data layer */
 static inline void si_shutr(struct stream_interface *si)
 {