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

Add a new VCL variable "client.identity" which defaults to client.ip

(without port number).

This variable is used by the "client" director to distribute sessions
across multiple backends.

Having it be a separate variable from client.ip makes it possible to
fill it from X-Forwarded-For: or Cookie headers.



git-svn-id: http://www.varnish-cache.org/svn/trunk/varnish-cache@5080 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent 979881cf
......@@ -390,6 +390,7 @@ struct sess {
/* formatted ascii client address */
char *addr;
char *port;
char *client_identity;
/* HTTP request */
const char *doclose;
......
......@@ -1038,6 +1038,7 @@ cnt_recv(struct sess *sp)
sp->disable_esi = 0;
sp->pass = 0;
sp->client_identity = NULL;
VCL_recv_method(sp);
recv_handling = sp->handling;
......
......@@ -106,7 +106,11 @@ vdi_random_getfd(const struct director *d, struct sess *sp)
*/
SHA256_Init(&ctx);
AN(sp->addr);
SHA256_Update(&ctx, sp->addr, strlen(sp->addr));
if (sp->client_identity != NULL)
SHA256_Update(&ctx, sp->client_identity,
strlen(sp->client_identity));
else
SHA256_Update(&ctx, sp->addr, strlen(sp->addr));
SHA256_Final(sign, &ctx);
hp = sign;
}
......
......@@ -371,7 +371,7 @@ VRT_r_resp_status(const struct sess *sp)
/*--------------------------------------------------------------------*/
#define VBEREQ(dir, type,onm,field) \
#define VBEREQ(dir, type, onm, field) \
void \
VRT_l_##dir##_##onm(const struct sess *sp, type a) \
{ \
......@@ -389,6 +389,30 @@ VRT_r_##dir##_##onm(const struct sess *sp) \
VBEREQ(beresp, unsigned, cacheable, cacheable)
VBEREQ(beresp, double, grace, grace)
/*--------------------------------------------------------------------*/
const char *
VRT_r_client_identity(struct sess *sp)
{
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
if (sp->client_identity != NULL)
return (sp->client_identity);
else
return (sp->addr);
}
void
VRT_l_client_identity(struct sess *sp, const char *str, ...)
{
va_list ap;
char *b;
va_start(ap, str);
b = vrt_assemble_string(sp->http, NULL, str, ap);
va_end(ap);
sp->client_identity = b;
}
/*--------------------------------------------------------------------
* XXX: Working relative to t_req is maybe not the right thing, we could
* XXX: have spent a long time talking to the backend since then.
......
......@@ -187,8 +187,7 @@ mcf_askchild(struct cli *cli, const char * const *av, void *priv)
}
assert(i == 1 || errno == EPIPE);
(void)cli_readres(cli_i,
&u, &q, params->cli_timeout);
(void)cli_readres(cli_i, &u, &q, params->cli_timeout);
cli_result(cli, u);
cli_out(cli, "%s", q);
free(q);
......
# $Id$
test "Client director"
server s1 {
rxreq
txresp -hdr "be: s1" -bodylen 1
} -start
server s2 {
rxreq
txresp -hdr "be: s2" -bodylen 2
rxreq
txresp -hdr "be: s2" -bodylen 4
} -start
varnish v1 -vcl+backend {
director d1 client {
{ .backend = s1; .weight = 1; }
{ .backend = s2; .weight = 1; }
}
sub vcl_recv {
set req.backend = d1;
if (req.http.id) {
set client.identity = req.http.id;
}
return (pass);
}
sub vcl_deliver {
set resp.http.id = client.identity;
}
} -start
client c1 {
txreq
rxresp
expect resp.http.id == "127.0.0.1"
expect resp.http.be == s2
expect resp.bodylen == 2
txreq -hdr "id: foo"
rxresp
expect resp.http.id == "foo"
expect resp.http.be == s1
expect resp.bodylen == 1
txreq -hdr "id: baz"
rxresp
expect resp.http.id == "baz"
expect resp.http.be == s2
expect resp.bodylen == 4
} -run
......@@ -106,6 +106,12 @@ sp_variables = (
( ),
'const struct sess *'
),
('client.identity',
'STRING',
( 'all',),
( 'all',),
'struct sess *'
),
('server.ip',
'IP',
( 'all',),
......
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