MEDIUM: config: centralize handling of SSL config per bind line

SSL config holds many parameters which are per bind line and not per
listener. Let's use a per-bind line config instead of having it
replicated for each listener.

At the moment we only do this for the SSL part but this should probably
evolved to handle more of the configuration and maybe even the state per
bind line.
diff --git a/include/proto/protocols.h b/include/proto/protocols.h
index 91334da..ec98e59 100644
--- a/include/proto/protocols.h
+++ b/include/proto/protocols.h
@@ -134,6 +134,23 @@
 /* returns the protocol associated to family <family> or NULL if not found */
 struct protocol *protocol_by_family(int family);
 
+/* allocate an ssl_conf struct for a bind line, and chain it to list head <lh>.
+ * If <arg> is not NULL, it is duplicated into ->arg to store useful config
+ * information for error reporting.
+ */
+static inline struct ssl_conf *ssl_conf_alloc(struct list *lh, const char *file, int line, const char *arg)
+{
+	struct ssl_conf *ssl_conf = (void *)calloc(1, sizeof(struct ssl_conf));
+
+	ssl_conf->file = strdup(file);
+	ssl_conf->line = line;
+	if (lh)
+		LIST_ADDQ(lh, &ssl_conf->by_fe);
+	if (arg)
+		ssl_conf->arg = strdup(arg);
+	return ssl_conf;
+}
+
 #endif /* _PROTO_PROTOCOLS_H */
 
 /*
diff --git a/include/types/protocols.h b/include/types/protocols.h
index 1d962ea..1ff448e 100644
--- a/include/types/protocols.h
+++ b/include/types/protocols.h
@@ -94,6 +94,23 @@
  * maxconn setting to the global.maxsock value so that its resources are reserved.
  */
 
+/* "bind" line SSL settings */
+struct ssl_conf {
+#ifdef USE_OPENSSL
+	char *ciphers;             /* cipher suite to use if non-null */
+	char *cert;                /* ssl main certificate */
+	int nosslv3;               /* disable SSLv3 */
+	int notlsv1;               /* disable TLSv1 */
+	int prefer_server_ciphers; /* Prefer server ciphers */
+	SSL_CTX *ctx;              /* SSL configuration */
+#endif
+	int ref_cnt;               /* number of users of this config, maybe 0 on error */
+	struct list by_fe;         /* next binding for the same frontend, or NULL */
+	char *arg;                 /* argument passed to "bind" for better error reporting */
+	char *file;                /* file where the section appears */
+	int line;                  /* line where the section appears */
+};
+
 /* The listener will be directly referenced by the fdtab[] which holds its
  * socket. The listener provides the protocol-specific accept() function to
  * the fdtab.
@@ -130,16 +147,8 @@
 	char *interface;		/* interface name or NULL */
 	int maxseg;			/* for TCP, advertised MSS */
 
-	char *ssl_cert;			/* ssl certificate */
-#ifdef USE_OPENSSL
-	struct {
-		SSL_CTX *ctx;
-		char *ciphers;		/* cipher suite to use if non-null */
-		int nosslv3;		/* disable SSLv3 */
-		int notlsv1;		/* disable TLSv1 */
-		int prefer_server_ciphers; /* Prefer server ciphers */
-	} ssl_ctx;
-#endif
+	struct ssl_conf *ssl_conf;	/* SSL settings, otherwise NULL */
+
 	/* warning: this struct is huge, keep it at the bottom */
 	struct sockaddr_storage addr;	/* the address we listen to */
 	struct {
diff --git a/include/types/proxy.h b/include/types/proxy.h
index 13a08a5..1080568 100644
--- a/include/types/proxy.h
+++ b/include/types/proxy.h
@@ -360,6 +360,7 @@
 		struct eb32_node id;		/* place in the tree of used IDs */
 		struct eb_root used_listener_id;/* list of listener IDs in use */
 		struct eb_root used_server_id;	/* list of server IDs in use */
+		struct list ssl_bind;		/* list of SSL bind settings */
 	} conf;					/* config information */
 	void *parent;				/* parent of the proxy when applicable */
 };