[master] f6b9c11 Give the tcp-pool API a protocol identifier, so we don't accidentally recycle connections between protocols.

Poul-Henning Kamp phk at FreeBSD.org
Thu Oct 5 14:17:07 UTC 2017


commit f6b9c11a2ed6234a64792e5756215c76df3f6c55
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Thu Oct 5 14:15:23 2017 +0000

    Give the tcp-pool API a protocol identifier, so we don't accidentally
    recycle connections between protocols.

diff --git a/bin/varnishd/cache/cache_backend.c b/bin/varnishd/cache/cache_backend.c
index a642304..0956afb 100644
--- a/bin/varnishd/cache/cache_backend.c
+++ b/bin/varnishd/cache/cache_backend.c
@@ -163,14 +163,14 @@ vbe_dir_finish(const struct director *d, struct worker *wrk,
 	if (bo->htc->doclose != SC_NULL || bp->proxy_header != 0) {
 		VSLb(bo->vsl, SLT_BackendClose, "%d %s", vtp->fd,
 		    bp->display_name);
-		VTP_Close(bp->tcp_pool, &vtp);
+		VTP_Close(&vtp);
 		Lck_Lock(&bp->mtx);
 	} else {
 		VSLb(bo->vsl, SLT_BackendReuse, "%d %s", vtp->fd,
 		    bp->display_name);
 		Lck_Lock(&bp->mtx);
 		VSC_C_main->backend_recycle++;
-		VTP_Recycle(wrk, bp->tcp_pool, &vtp);
+		VTP_Recycle(wrk, &vtp);
 	}
 	assert(bp->n_conn > 0);
 	bp->n_conn--;
diff --git a/bin/varnishd/cache/cache_backend_cfg.c b/bin/varnishd/cache/cache_backend_cfg.c
index 15b650b..efb3dc0 100644
--- a/bin/varnishd/cache/cache_backend_cfg.c
+++ b/bin/varnishd/cache/cache_backend_cfg.c
@@ -50,6 +50,8 @@
 
 #include "VSC_vbe.h"
 
+const char *vbe_proto_ident = "HTTP Backend";
+
 static VTAILQ_HEAD(, backend) backends = VTAILQ_HEAD_INITIALIZER(backends);
 static VTAILQ_HEAD(, backend) cool_backends =
     VTAILQ_HEAD_INITIALIZER(cool_backends);
@@ -115,7 +117,8 @@ VRT_new_backend(VRT_CTX, const struct vrt_backend *vrt)
 	Lck_Lock(&backends_mtx);
 	VTAILQ_INSERT_TAIL(&backends, b, list);
 	VSC_C_main->n_backend++;
-	b->tcp_pool = VTP_Ref(vrt->ipv4_suckaddr, vrt->ipv6_suckaddr);
+	b->tcp_pool = VTP_Ref(vrt->ipv4_suckaddr, vrt->ipv6_suckaddr,
+	    vbe_proto_ident);
 	Lck_Unlock(&backends_mtx);
 
 	VBE_fill_director(b);
diff --git a/bin/varnishd/cache/cache_tcp_pool.c b/bin/varnishd/cache/cache_tcp_pool.c
index fa95b18..5c351a4 100644
--- a/bin/varnishd/cache/cache_tcp_pool.c
+++ b/bin/varnishd/cache/cache_tcp_pool.c
@@ -48,7 +48,7 @@ struct tcp_pool {
 	unsigned		magic;
 #define TCP_POOL_MAGIC		0x28b0e42a
 
-	char			*name;
+	const void		*id;
 	struct suckaddr		*ip4;
 	struct suckaddr		*ip6;
 
@@ -63,7 +63,6 @@ struct tcp_pool {
 	int			n_kill;
 
 	int			n_used;
-
 };
 
 static struct lock		tcp_pools_mtx;
@@ -119,7 +118,7 @@ tcp_handle(struct waited *w, enum wait_event ev, double now)
  */
 
 struct tcp_pool *
-VTP_Ref(const struct suckaddr *ip4, const struct suckaddr *ip6)
+VTP_Ref(const struct suckaddr *ip4, const struct suckaddr *ip6, const void *id)
 {
 	struct tcp_pool *tp;
 
@@ -127,6 +126,8 @@ VTP_Ref(const struct suckaddr *ip4, const struct suckaddr *ip6)
 	Lck_Lock(&tcp_pools_mtx);
 	VTAILQ_FOREACH(tp, &tcp_pools, list) {
 		assert(tp->refcnt > 0);
+		if (tp->id != id)
+			continue;
 		if (ip4 == NULL) {
 			if (tp->ip4 != NULL)
 				continue;
@@ -158,6 +159,7 @@ VTP_Ref(const struct suckaddr *ip4, const struct suckaddr *ip6)
 	if (ip6 != NULL)
 		tp->ip6 = VSA_Clone(ip6);
 	tp->refcnt = 1;
+	tp->id = id;
 	Lck_New(&tp->mtx, lck_tcp_pool);
 	VTAILQ_INIT(&tp->connlist);
 	VTAILQ_INIT(&tp->killlist);
@@ -206,7 +208,6 @@ VTP_Rel(struct tcp_pool **tpp)
 	VTAILQ_REMOVE(&tcp_pools, tp, list);
 	Lck_Unlock(&tcp_pools_mtx);
 
-	free(tp->name);
 	free(tp->ip4);
 	free(tp->ip6);
 	Lck_Lock(&tp->mtx);
@@ -254,7 +255,9 @@ VTP_Open(const struct tcp_pool *tp, double tmo, const struct suckaddr **sa)
 	}
 	*sa = tp->ip4;
 	s = VTCP_connect(tp->ip4, msec);
-	if (s < 0 && !cache_param->prefer_ipv6) {
+	if (s >= 0)
+		return (s);
+	if (!cache_param->prefer_ipv6) {
 		*sa = tp->ip6;
 		s = VTCP_connect(tp->ip6, msec);
 	}
@@ -266,16 +269,18 @@ VTP_Open(const struct tcp_pool *tp, double tmo, const struct suckaddr **sa)
  */
 
 void
-VTP_Recycle(const struct worker *wrk, struct tcp_pool *tp, struct vtp **vtpp)
+VTP_Recycle(const struct worker *wrk, struct vtp **vtpp)
 {
 	struct vtp *vtp;
+	struct tcp_pool *tp;
 	int i = 0;
 
 	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
-	CHECK_OBJ_NOTNULL(tp, TCP_POOL_MAGIC);
 	vtp = *vtpp;
 	*vtpp = NULL;
 	CHECK_OBJ_NOTNULL(vtp, VTP_MAGIC);
+	tp = vtp->tcp_pool;
+	CHECK_OBJ_NOTNULL(tp, TCP_POOL_MAGIC);
 
 	assert(vtp->state == VTP_STATE_USED);
 	assert(vtp->fd > 0);
@@ -327,14 +332,16 @@ VTP_Recycle(const struct worker *wrk, struct tcp_pool *tp, struct vtp **vtpp)
  */
 
 void
-VTP_Close(struct tcp_pool *tp, struct vtp **vtpp)
+VTP_Close(struct vtp **vtpp)
 {
 	struct vtp *vtp;
+	struct tcp_pool *tp;
 
-	CHECK_OBJ_NOTNULL(tp, TCP_POOL_MAGIC);
 	vtp = *vtpp;
 	*vtpp = NULL;
 	CHECK_OBJ_NOTNULL(vtp, VTP_MAGIC);
+	tp = vtp->tcp_pool;
+	CHECK_OBJ_NOTNULL(tp, TCP_POOL_MAGIC);
 
 	assert(vtp->state == VTP_STATE_USED);
 	assert(vtp->fd > 0);
diff --git a/bin/varnishd/cache/cache_tcp_pool.h b/bin/varnishd/cache/cache_tcp_pool.h
index 8e83140..11b0f82 100644
--- a/bin/varnishd/cache/cache_tcp_pool.h
+++ b/bin/varnishd/cache/cache_tcp_pool.h
@@ -26,7 +26,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * TCP connection pools
+ * Outgoing TCP connection pools
  *
  */
 
@@ -53,12 +53,45 @@ struct vtp {
  * Prototypes
  */
 
-/* cache_tcp_pool.c */
-struct tcp_pool *VTP_Ref(const struct suckaddr *ip4, const struct suckaddr *ip6);
+struct tcp_pool *VTP_Ref(const struct suckaddr *ip4, const struct suckaddr *ip6, const void *id);
+	/*
+	 * Get a reference to a TCP pool.  Either ip4 or ip6 arg must be non-NULL.
+	 * If recycling is to be used, the id pointer distinguishes the pool per protocol.
+	 */
+
 void VTP_AddRef(struct tcp_pool *);
-void VTP_Rel(struct tcp_pool **tpp);
-int VTP_Open(const struct tcp_pool *tp, double tmo, const struct suckaddr **sa);
-void VTP_Recycle(const struct worker *, struct tcp_pool *, struct vtp **);
-void VTP_Close(struct tcp_pool *tp, struct vtp **);
+	/*
+	 * Get another reference to an already referenced TCP pool.
+	 */
+
+void VTP_Rel(struct tcp_pool **);
+	/*
+	 * Release reference to a TCP pool.  When last reference is released
+	 * the pool is destroyed and all cached connections closed.
+	 */
+
+int VTP_Open(const struct tcp_pool *, double tmo, const struct suckaddr **);
+	/*
+	 * Open a new connection and return the adress used.
+	 */
+
+void VTP_Close(struct vtp **);
+	/*
+	 * Close a connection.
+	 */
+
+void VTP_Recycle(const struct worker *, struct vtp **);
+	/*
+	 * Recycle an open connection.
+	 */
+
 struct vtp *VTP_Get(struct tcp_pool *, double tmo, struct worker *);
+	/*
+	 * Get a (possibly) recycled connection.
+	 */
+
 void VTP_Wait(struct worker *, struct vtp *);
+	/*
+	 * If the connection was recycled (state != VTP_STATE_USED) call this
+	 * function before attempting to receive on the connection.
+	 */


More information about the varnish-commit mailing list