Commit bca3f901 authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Go over the simple backend and make it more readable.


git-svn-id: http://www.varnish-cache.org/svn/trunk/varnish-cache@1964 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent 31e909f0
......@@ -28,10 +28,6 @@
*
* $Id$
*
*
* XXX: When we switch VCL we can have vbe_conn's dangling from
* XXX: the backends no longer used. When the VCL's refcount
* XXX: drops to zero we should zap them.
*/
#include <sys/types.h>
......@@ -62,64 +58,97 @@ struct bes {
TAILQ_HEAD(, vbe_conn) connlist;
};
/*--------------------------------------------------------------------*/
/*--------------------------------------------------------------------
* Try to get a socket connected to one of the addresses on the list.
* We start from the cached "last good" address and try all items on
* the list exactly once.
* If a new DNS lookup is made while we try, we start over and try the
* new list exactly once.
*/
static int
bes_conn_try_list(struct sess *sp, struct bes *bes)
{
struct addrinfo *ai, *from;
struct sockaddr_storage ss;
int fam, sockt, proto;
socklen_t alen;
int s, loops;
char abuf1[TCP_ADDRBUFSIZE], abuf2[TCP_ADDRBUFSIZE];
char pbuf1[TCP_PORTBUFSIZE], pbuf2[TCP_PORTBUFSIZE];
unsigned myseq;
CHECK_OBJ_NOTNULL(bes, BES_MAGIC);
if (bes->addr == NULL)
return (-1);
AN(bes->last_addr);
/* Called with lock held */
myseq = bes->dnsseq;
loops = 0;
from = bes->last_addr;
for (ai = from; ai != NULL && (loops != 1 || ai != from);) {
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);
UNLOCK(&sp->backend->mtx);
s = socket(fam, sockt, proto);
if (s >= 0 && connect(s, (void *)&ss, alen)) {
AZ(close(s));
s = -1;
}
if (s >= 0) {
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);
if (s >= 0) {
ai = from = bes->last_addr;
while (1) {
/* NB: releases/acquires lock */
s = VBE_TryConnect(sp, ai);
if (s >= 0) {
/* Update cached "last good" if still valid */
if (myseq == bes->dnsseq)
bes->last_addr = ai;
return (s);
}
if (myseq != bes->dnsseq) {
/* A DNS-lookup happended, try again from start */
loops = 0;
from = bes->last_addr;
ai = from;
} else {
/* Try next one */
ai = ai->ai_next;
if (ai == NULL) {
loops++;
ai = bes->addr;
}
}
if (loops == 1 && ai == from)
return (-1);
}
return (-1);
}
/*--------------------------------------------------------------------*/
static const char *
bes_dns_lookup(struct backend *bp)
{
struct addrinfo *res, hint, *old;
struct bes *bes;
int error;
CHECK_OBJ_NOTNULL(bp, BACKEND_MAGIC);
CAST_OBJ_NOTNULL(bes, bp->priv, BES_MAGIC);
bes->dnstime = TIM_mono();
/* Let go of lock while we do sleepable stuff */
UNLOCK(&bp->mtx);
memset(&hint, 0, sizeof hint);
hint.ai_family = PF_UNSPEC;
hint.ai_socktype = SOCK_STREAM;
res = NULL;
error = getaddrinfo(bes->hostname,
bes->portname == NULL ? "http" : bes->portname,
&hint, &res);
LOCK(&bp->mtx);
if (error) {
if (res != NULL)
freeaddrinfo(res);
return(gai_strerror(error));
}
bes->dnsseq++;
old = bes->addr;
bes->last_addr = res;
bes->addr = res;
if (old != NULL)
freeaddrinfo(old);
return (NULL);
}
/*--------------------------------------------------------------------*/
......@@ -129,8 +158,6 @@ bes_conn_try(struct sess *sp, struct backend *bp)
{
int s;
struct bes *bes;
struct addrinfo *res, hint, *old;
int error;
CAST_OBJ_NOTNULL(bes, bp->priv, BES_MAGIC);
......@@ -148,31 +175,7 @@ bes_conn_try(struct sess *sp, struct backend *bp)
return (-1);
}
/* Then do another lookup to catch DNS changes */
bes->dnstime = TIM_mono();
UNLOCK(&bp->mtx);
memset(&hint, 0, sizeof hint);
hint.ai_family = PF_UNSPEC;
hint.ai_socktype = SOCK_STREAM;
res = NULL;
error = getaddrinfo(bes->hostname,
bes->portname == NULL ? "http" : bes->portname,
&hint, &res);
if (error) {
if (res != NULL)
freeaddrinfo(res);
printf("getaddrinfo: %s\n", gai_strerror(error)); /* XXX */
LOCK(&bp->mtx);
} else {
LOCK(&bp->mtx);
bes->dnsseq++;
old = bes->addr;
bes->last_addr = res;
bes->addr = res;
if (old != NULL)
freeaddrinfo(old);
}
(void)bes_dns_lookup(bp);
/* And try the entire list */
s = bes_conn_try_list(sp, bes);
......@@ -363,6 +366,7 @@ VRT_init_simple_backend(struct backend **bp, struct vrt_simple_backend *t)
{
struct backend *b;
struct bes *bes;
const char *p;
/*
* Scan existing backends to see if we can recycle one of them.
......@@ -402,5 +406,16 @@ VRT_init_simple_backend(struct backend **bp, struct vrt_simple_backend *t)
AN(t->host);
REPLACE(bes->hostname, t->host);
/*
* The VCL compiler already did a lookup, but we'll do another one
* here, just in case...
*/
LOCK(&b->mtx);
p = bes_dns_lookup(b);
UNLOCK(&b->mtx);
if (p != NULL)
printf("Warning: could not lookup backend %s (%s:%s): %s",
t->name, t->host, t->port, p);
*bp = b;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment