From 0de1ed55a25b71dfe9a89f6962466490d733ea9c Mon Sep 17 00:00:00 2001 From: phk Date: Thu, 20 Sep 2007 08:14:40 +0000 Subject: [PATCH] Add a VBE_TryConnect() which tries to connected to a given backend+addrinfo combination. This will be necessary in most if not all backend methods, so it should be generic. git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@1963 d4fa192b-c00b-0410-8231-f00ffab90ce4 --- varnish-cache/bin/varnishd/cache.h | 2 + varnish-cache/bin/varnishd/cache_backend.c | 62 ++++++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/varnish-cache/bin/varnishd/cache.h b/varnish-cache/bin/varnishd/cache.h index 01f4b6d4..0c3e1f61 100644 --- a/varnish-cache/bin/varnishd/cache.h +++ b/varnish-cache/bin/varnishd/cache.h @@ -68,6 +68,7 @@ struct sess; struct object; struct objhead; struct workreq; +struct addrinfo; /*--------------------------------------------------------------------*/ @@ -399,6 +400,7 @@ struct backend *VBE_NewBackend(struct backend_method *method); struct vbe_conn *VBE_NewConn(void); void VBE_ReleaseConn(struct vbe_conn *); void VBE_UpdateHealth(struct sess *sp, struct vbe_conn *, int); +int VBE_TryConnect(struct sess *sp, struct addrinfo *ai); /* cache_backend_simple.c */ extern struct backend_method backend_method_simple; diff --git a/varnish-cache/bin/varnishd/cache_backend.c b/varnish-cache/bin/varnishd/cache_backend.c index cad9b488..da8ecc1c 100644 --- a/varnish-cache/bin/varnishd/cache_backend.c +++ b/varnish-cache/bin/varnishd/cache_backend.c @@ -33,8 +33,12 @@ */ #include +#include #include +#include +#include + #include "heritage.h" #include "shmlog.h" #include "cache.h" @@ -46,6 +50,64 @@ static MTX VBE_mtx; struct backendlist backendlist = TAILQ_HEAD_INITIALIZER(backendlist); + +/*-------------------------------------------------------------------- + * Attempt to connect to a given addrinfo entry. + * + * Must be called with locked backend, but will release the backend + * lock during the slow/sleeping stuff, so that other worker threads + * can have a go, while we ponder. + * + */ + +int +VBE_TryConnect(struct sess *sp, struct addrinfo *ai) +{ + struct sockaddr_storage ss; + int fam, sockt, proto; + socklen_t alen; + int s; + char abuf1[TCP_ADDRBUFSIZE], abuf2[TCP_ADDRBUFSIZE]; + char pbuf1[TCP_PORTBUFSIZE], pbuf2[TCP_PORTBUFSIZE]; + + /* + * ai is only valid with the lock held, so copy out the bits + * we need to make the connection + */ + fam = ai->ai_family; + sockt = ai->ai_socktype; + proto = ai->ai_protocol; + alen = ai->ai_addrlen; + assert(alen <= sizeof ss); + memcpy(&ss, ai->ai_addr, alen); + + /* release lock during stuff that can take a long time */ + UNLOCK(&sp->backend->mtx); + + s = socket(fam, sockt, proto); + if (s < 0) { + LOCK(&sp->backend->mtx); + return (s); + } + + if (connect(s, (void *)&ss, alen) != 0) { + close(s); + LOCK(&sp->backend->mtx); + return (-1); + } + + TCP_myname(s, abuf1, sizeof abuf1, pbuf1, sizeof pbuf1); + TCP_name((void*)&ss, alen, + abuf2, sizeof abuf2, pbuf2, sizeof pbuf2); + WSL(sp->wrk, SLT_BackendOpen, s, "%s %s %s %s %s", + sp->backend->vcl_name, abuf1, pbuf1, abuf2, pbuf2); + + LOCK(&sp->backend->mtx); + return (s); +} + + + /*-------------------------------------------------------------------- * Get a http structure for talking to the backend. */ -- 2.39.5