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 { ...@@ -390,6 +390,7 @@ struct sess {
/* formatted ascii client address */ /* formatted ascii client address */
char *addr; char *addr;
char *port; char *port;
char *client_identity;
/* HTTP request */ /* HTTP request */
const char *doclose; const char *doclose;
......
...@@ -1041,6 +1041,7 @@ cnt_recv(struct sess *sp) ...@@ -1041,6 +1041,7 @@ cnt_recv(struct sess *sp)
sp->disable_esi = 0; sp->disable_esi = 0;
sp->pass = 0; sp->pass = 0;
sp->client_identity = NULL;
VCL_recv_method(sp); VCL_recv_method(sp);
recv_handling = sp->handling; recv_handling = sp->handling;
......
...@@ -106,7 +106,11 @@ vdi_random_getfd(const struct director *d, struct sess *sp) ...@@ -106,7 +106,11 @@ vdi_random_getfd(const struct director *d, struct sess *sp)
*/ */
SHA256_Init(&ctx); SHA256_Init(&ctx);
AN(sp->addr); 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); SHA256_Final(sign, &ctx);
hp = sign; hp = sign;
} }
......
...@@ -372,7 +372,7 @@ VRT_r_resp_status(const struct sess *sp) ...@@ -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 \ void \
VRT_l_##dir##_##onm(const struct sess *sp, type a) \ VRT_l_##dir##_##onm(const struct sess *sp, type a) \
{ \ { \
...@@ -390,6 +390,30 @@ VRT_r_##dir##_##onm(const struct sess *sp) \ ...@@ -390,6 +390,30 @@ VRT_r_##dir##_##onm(const struct sess *sp) \
VBEREQ(beresp, unsigned, cacheable, cacheable) VBEREQ(beresp, unsigned, cacheable, cacheable)
VBEREQ(beresp, double, grace, grace) 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: 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. * 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) ...@@ -187,8 +187,7 @@ mcf_askchild(struct cli *cli, const char * const *av, void *priv)
} }
assert(i == 1 || errno == EPIPE); assert(i == 1 || errno == EPIPE);
(void)cli_readres(cli_i, (void)cli_readres(cli_i, &u, &q, params->cli_timeout);
&u, &q, params->cli_timeout);
cli_result(cli, u); cli_result(cli, u);
cli_out(cli, "%s", q); cli_out(cli, "%s", q);
free(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 @@ ...@@ -7,6 +7,8 @@
*/ */
struct sockaddr * VRT_r_client_ip(const struct sess *); 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 *); struct sockaddr * VRT_r_server_ip(struct sess *);
const char * VRT_r_server_hostname(struct sess *); const char * VRT_r_server_hostname(struct sess *);
const char * VRT_r_server_identity(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! * NB: This file is machine generated, DO NOT EDIT!
* *
...@@ -159,8 +159,8 @@ vcl_output_lang_h(struct vsb *sb) ...@@ -159,8 +159,8 @@ vcl_output_lang_h(struct vsb *sb)
/* ../../include/vcl.h */ /* ../../include/vcl.h */
vsb_cat(sb, "/*\n * $Id: vcc_gen_fixed_token.tcl 4428 2010-01-06 17"); vsb_cat(sb, "/*\n * $Id: vcc_gen_fixed_token.tcl 5171 2010-09-06 14");
vsb_cat(sb, ":38:59Z tfheen $\n *\n * NB: This file is machine gen"); 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, "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, "d_token.tcl instead\n */\n\nstruct sess;\n");
vsb_cat(sb, "struct cli;\n\ntypedef void vcl_init_f(struct cli *);\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) ...@@ -314,15 +314,17 @@ vcl_output_lang_h(struct vsb *sb)
/* ../../include/vrt_obj.h */ /* ../../include/vrt_obj.h */
vsb_cat(sb, "/*\n * $Id: vcc_gen_fixed_token.tcl 4428 2010-01-06 17"); vsb_cat(sb, "/*\n * $Id: vcc_gen_fixed_token.tcl 5171 2010-09-06 14");
vsb_cat(sb, ":38:59Z tfheen $\n *\n * NB: This file is machine gen"); 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, "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, "d_token.tcl instead\n */\n\nstruct sockaddr * VRT_r_cl");
vsb_cat(sb, "ient_ip(const struct sess *);\n"); 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_client_identity(struct sess *);\n");
vsb_cat(sb, "const char * VRT_r_server_hostname(struct sess *);\n"); vsb_cat(sb, "void VRT_l_client_identity(struct sess *, const char *");
vsb_cat(sb, "const char * VRT_r_server_identity(struct sess *);\n"); vsb_cat(sb, ", ...);\nstruct sockaddr * VRT_r_server_ip(struct sess");
vsb_cat(sb, "int VRT_r_server_port(struct sess *);\n"); 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, "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, "void VRT_l_req_request(const struct sess *, const char");
vsb_cat(sb, " *, ...);\nconst char * VRT_r_req_url(const struct ses"); vsb_cat(sb, " *, ...);\nconst char * VRT_r_req_url(const struct ses");
......
...@@ -92,6 +92,11 @@ set spobj { ...@@ -92,6 +92,11 @@ set spobj {
all all
"const struct sess *" "const struct sess *"
} }
{ client.identity STRING
RW
all
"struct sess *"
}
{ server.ip IP { server.ip IP
RO RO
all 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! * NB: This file is machine generated, DO NOT EDIT!
* *
...@@ -19,6 +19,14 @@ struct var vcc_vars[] = { ...@@ -19,6 +19,14 @@ struct var vcc_vars[] = {
| VCL_MET_MISS | VCL_MET_HIT | VCL_MET_FETCH | VCL_MET_DELIVER | VCL_MET_MISS | VCL_MET_HIT | VCL_MET_FETCH | VCL_MET_DELIVER
| VCL_MET_ERROR | 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, { "server.ip", IP, 9,
"VRT_r_server_ip(sp)", "VRT_r_server_ip(sp)",
NULL, 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