Commit 8d471c36 authored by Tollef Fog Heen's avatar Tollef Fog Heen

Merge r5080: Add a new VCL variable "client.identity" which defaults to...

Merge r5080: 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/branches/2.1@5303 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent e67c7bd4
......@@ -390,6 +390,7 @@ struct sess {
/* formatted ascii client address */
char *addr;
char *port;
char *client_identity;
/* HTTP request */
const char *doclose;
......
......@@ -1041,6 +1041,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;
}
......
......@@ -372,7 +372,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) \
{ \
......@@ -390,6 +390,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
......@@ -7,6 +7,8 @@
*/
struct sockaddr * VRT_r_client_ip(const struct sess *);
const char * VRT_r_client_identity(struct sess *);
void VRT_l_client_identity(struct sess *, const char *, ...);
struct sockaddr * VRT_r_server_ip(struct sess *);
const char * VRT_r_server_hostname(struct sess *);
const char * VRT_r_server_identity(struct sess *);
......
/*
* $Id: vcc_gen_fixed_token.tcl 4428 2010-01-06 17:38:59Z tfheen $
* $Id: vcc_gen_fixed_token.tcl 5171 2010-09-06 14:11:53Z martin $
*
* NB: This file is machine generated, DO NOT EDIT!
*
......@@ -159,8 +159,8 @@ vcl_output_lang_h(struct vsb *sb)
/* ../../include/vcl.h */
vsb_cat(sb, "/*\n * $Id: vcc_gen_fixed_token.tcl 4428 2010-01-06 17");
vsb_cat(sb, ":38:59Z tfheen $\n *\n * NB: This file is machine gen");
vsb_cat(sb, "/*\n * $Id: vcc_gen_fixed_token.tcl 5171 2010-09-06 14");
vsb_cat(sb, ":11:53Z martin $\n *\n * NB: This file is machine gen");
vsb_cat(sb, "erated, DO NOT EDIT!\n *\n * Edit and run vcc_gen_fixe");
vsb_cat(sb, "d_token.tcl instead\n */\n\nstruct sess;\n");
vsb_cat(sb, "struct cli;\n\ntypedef void vcl_init_f(struct cli *);\n");
......@@ -314,15 +314,17 @@ vcl_output_lang_h(struct vsb *sb)
/* ../../include/vrt_obj.h */
vsb_cat(sb, "/*\n * $Id: vcc_gen_fixed_token.tcl 4428 2010-01-06 17");
vsb_cat(sb, ":38:59Z tfheen $\n *\n * NB: This file is machine gen");
vsb_cat(sb, "/*\n * $Id: vcc_gen_fixed_token.tcl 5171 2010-09-06 14");
vsb_cat(sb, ":11:53Z martin $\n *\n * NB: This file is machine gen");
vsb_cat(sb, "erated, DO NOT EDIT!\n *\n * Edit and run vcc_gen_fixe");
vsb_cat(sb, "d_token.tcl instead\n */\n\nstruct sockaddr * VRT_r_cl");
vsb_cat(sb, "ient_ip(const struct sess *);\n");
vsb_cat(sb, "struct sockaddr * VRT_r_server_ip(struct sess *);\n");
vsb_cat(sb, "const char * VRT_r_server_hostname(struct sess *);\n");
vsb_cat(sb, "const char * VRT_r_server_identity(struct sess *);\n");
vsb_cat(sb, "int VRT_r_server_port(struct sess *);\n");
vsb_cat(sb, "const char * VRT_r_client_identity(struct sess *);\n");
vsb_cat(sb, "void VRT_l_client_identity(struct sess *, const char *");
vsb_cat(sb, ", ...);\nstruct sockaddr * VRT_r_server_ip(struct sess");
vsb_cat(sb, " *);\nconst char * VRT_r_server_hostname(struct sess *");
vsb_cat(sb, ");\nconst char * VRT_r_server_identity(struct sess *);");
vsb_cat(sb, "\nint VRT_r_server_port(struct sess *);\n");
vsb_cat(sb, "const char * VRT_r_req_request(const struct sess *);\n");
vsb_cat(sb, "void VRT_l_req_request(const struct sess *, const char");
vsb_cat(sb, " *, ...);\nconst char * VRT_r_req_url(const struct ses");
......
......@@ -92,6 +92,11 @@ set spobj {
all
"const struct sess *"
}
{ client.identity STRING
RW
all
"struct sess *"
}
{ server.ip IP
RO
all
......
/*
* $Id: vcc_gen_fixed_token.tcl 4428 2010-01-06 17:38:59Z tfheen $
* $Id: vcc_gen_fixed_token.tcl 5171 2010-09-06 14:11:53Z martin $
*
* NB: This file is machine generated, DO NOT EDIT!
*
......@@ -19,6 +19,14 @@ struct var vcc_vars[] = {
| VCL_MET_MISS | VCL_MET_HIT | VCL_MET_FETCH | VCL_MET_DELIVER
| VCL_MET_ERROR
},
{ "client.identity", STRING, 15,
"VRT_r_client_identity(sp)",
"VRT_l_client_identity(sp, ",
V_RW, 0,
VCL_MET_RECV | VCL_MET_PIPE | VCL_MET_PASS | VCL_MET_HASH
| VCL_MET_MISS | VCL_MET_HIT | VCL_MET_FETCH | VCL_MET_DELIVER
| VCL_MET_ERROR
},
{ "server.ip", IP, 9,
"VRT_r_server_ip(sp)",
NULL,
......
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