Commit 8b654534 authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Add support for checking "server.ip" in addition to "client.ip".

The definition of "server.ip" is what getsockname(2) returns
for our end of the connection.

Don't report ACL matches for acls created as a result of '==' or
'!=' usage on IP number variables.

Move storage for sess->sockaddr away from sessmem and expose
more code to <sys/socket.h>.  This is a network application
after all.

XXX: somebody with IPv6 connectivity needs to look at
ACLs in IPv6 context.



git-svn-id: http://www.varnish-cache.org/svn/trunk/varnish-cache@1390 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent ccc1feed
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include <sys/time.h> #include <sys/time.h>
#include <sys/uio.h> #include <sys/uio.h>
#include <sys/socket.h>
#include <pthread.h> #include <pthread.h>
#include <stdint.h> #include <stdint.h>
...@@ -255,7 +256,8 @@ struct sess { ...@@ -255,7 +256,8 @@ struct sess {
struct worker *wrk; struct worker *wrk;
unsigned sockaddrlen; unsigned sockaddrlen;
struct sockaddr *sockaddr; struct sockaddr sockaddr[2];
struct sockaddr mysockaddr[2];
/* formatted ascii client address */ /* formatted ascii client address */
char addr[TCP_ADDRBUFSIZE]; char addr[TCP_ADDRBUFSIZE];
......
...@@ -65,7 +65,6 @@ struct sessmem { ...@@ -65,7 +65,6 @@ struct sessmem {
struct sess sess; struct sess sess;
struct http http; struct http http;
struct sockaddr sockaddr[2]; /* INET6 hack */
unsigned workspace; unsigned workspace;
TAILQ_ENTRY(sessmem) list; TAILQ_ENTRY(sessmem) list;
}; };
...@@ -298,8 +297,7 @@ SES_New(struct sockaddr *addr, unsigned len) ...@@ -298,8 +297,7 @@ SES_New(struct sockaddr *addr, unsigned len)
sm->sess.mem = sm; sm->sess.mem = sm;
sm->sess.http = &sm->http; sm->sess.http = &sm->http;
sm->sess.sockaddr = sm->sockaddr; assert(len < sizeof(sm->sess.sockaddr));
assert(len < sizeof(sm->sockaddr));
if (addr != NULL) { if (addr != NULL) {
memcpy(sm->sess.sockaddr, addr, len); memcpy(sm->sess.sockaddr, addr, len);
sm->sess.sockaddrlen = len; sm->sess.sockaddrlen = len;
......
...@@ -250,3 +250,25 @@ VRT_r_req_##n1(struct sess *sp) \ ...@@ -250,3 +250,25 @@ VRT_r_req_##n1(struct sess *sp) \
VREQ(request, HTTP_HDR_REQ) VREQ(request, HTTP_HDR_REQ)
VREQ(url, HTTP_HDR_URL) VREQ(url, HTTP_HDR_URL)
VREQ(proto, HTTP_HDR_PROTO) VREQ(proto, HTTP_HDR_PROTO)
/*--------------------------------------------------------------------*/
struct sockaddr *
VRT_r_client_ip(struct sess *sp)
{
return (sp->sockaddr);
}
struct sockaddr *
VRT_r_server_ip(struct sess *sp)
{
socklen_t l;
if (sp->mysockaddr->sa_len == 0) {
l = sizeof sp->mysockaddr;
AZ(getsockname(sp->fd, sp->mysockaddr, &l));
assert(l == sp->mysockaddr->sa_len);
}
return (sp->mysockaddr);
}
...@@ -60,35 +60,37 @@ static uint32_t ipv4mask[] = { ...@@ -60,35 +60,37 @@ static uint32_t ipv4mask[] = {
}; };
static int static int
vrt_acl_vsl(struct sess *sp, const char *acl, struct vrt_acl *ap, int r) vrt_acl_vsl(struct sess *sp, const char *acln, struct vrt_acl *ap, int r)
{ {
AN(ap); AN(ap);
if (ap->name == NULL) { if (acln != NULL) {
assert(r == 0); if (ap->name == NULL) {
VSL(SLT_VCL_acl, sp->fd, "NO_MATCH %s", acl); assert(r == 0);
return (r); VSL(SLT_VCL_acl, sp->fd, "NO_MATCH %s", acln);
} return (r);
if (ap->priv == NULL) { }
assert(r == 0); if (ap->priv == NULL) {
VSL(SLT_VCL_acl, sp->fd, "FAIL %s %s", acl, ap->desc); assert(r == 0);
return (r); VSL(SLT_VCL_acl, sp->fd, "FAIL %s %s", acln, ap->desc);
} return (r);
}
VSL(SLT_VCL_acl, sp->fd, "%s %s %s", VSL(SLT_VCL_acl, sp->fd, "%s %s %s",
r ? "MATCH" : "NEG_MATCH", acl, ap->desc); r ? "MATCH" : "NEG_MATCH", acln, ap->desc);
}
return (r); return (r);
} }
int int
VRT_acl_match(struct sess *sp, const char *acl, struct vrt_acl *ap) VRT_acl_match(struct sess *sp, struct sockaddr *sa, const char *acln, struct vrt_acl *ap)
{ {
struct addrinfo *a1; struct addrinfo *a1;
struct sockaddr_in *sin1, *sin2; struct sockaddr_in *sin1, *sin2;
if (sp->sockaddr->sa_family == AF_INET) { if (sa->sa_family == AF_INET) {
assert(sp->sockaddrlen >= sizeof *sin1); assert(sa->sa_len >= sizeof *sin1);
sin1 = (void*)sp->sockaddr; sin1 = (void*)sa;
} else { } else {
sin1 = NULL; sin1 = NULL;
} }
...@@ -97,7 +99,7 @@ VRT_acl_match(struct sess *sp, const char *acl, struct vrt_acl *ap) ...@@ -97,7 +99,7 @@ VRT_acl_match(struct sess *sp, const char *acl, struct vrt_acl *ap)
if (ap->priv == NULL && ap->paren) if (ap->priv == NULL && ap->paren)
continue; continue;
if (ap->priv == NULL && ap->not) { if (ap->priv == NULL && ap->not) {
return (vrt_acl_vsl(sp, acl, ap, 0)); return (vrt_acl_vsl(sp, acln, ap, 0));
} }
if (ap->priv == NULL) if (ap->priv == NULL)
continue; continue;
...@@ -116,16 +118,16 @@ VRT_acl_match(struct sess *sp, const char *acl, struct vrt_acl *ap) ...@@ -116,16 +118,16 @@ VRT_acl_match(struct sess *sp, const char *acl, struct vrt_acl *ap)
htonl(sin2->sin_addr.s_addr)) & htonl(sin2->sin_addr.s_addr)) &
ipv4mask[ap->mask > 32 ? 32 : ap->mask])) ipv4mask[ap->mask > 32 ? 32 : ap->mask]))
return ( return (
vrt_acl_vsl(sp, acl, ap, !ap->not)); vrt_acl_vsl(sp, acln, ap, !ap->not));
continue; continue;
} }
/* Not rules for unknown protos match */ /* Not rules for unknown protos match */
if (ap->not) if (ap->not)
return (vrt_acl_vsl(sp, acl, ap, 0)); return (vrt_acl_vsl(sp, acln, ap, 0));
} }
} }
return (vrt_acl_vsl(sp, acl, ap, 0)); return (vrt_acl_vsl(sp, acln, ap, 0));
} }
void void
...@@ -164,5 +166,3 @@ VRT_acl_fini(struct vrt_acl *ap) ...@@ -164,5 +166,3 @@ VRT_acl_fini(struct vrt_acl *ap)
freeaddrinfo(a1); freeaddrinfo(a1);
} }
} }
...@@ -38,6 +38,7 @@ struct sess; ...@@ -38,6 +38,7 @@ struct sess;
struct vsb; struct vsb;
struct backend; struct backend;
struct VCL_conf; struct VCL_conf;
struct sockaddr;
struct vrt_ref { struct vrt_ref {
unsigned source; unsigned source;
...@@ -58,7 +59,7 @@ struct vrt_acl { ...@@ -58,7 +59,7 @@ struct vrt_acl {
}; };
/* ACL related */ /* ACL related */
int VRT_acl_match(struct sess *, const char *, struct vrt_acl *); int VRT_acl_match(struct sess *, struct sockaddr *, const char *, struct vrt_acl *);
void VRT_acl_init(struct vrt_acl *); void VRT_acl_init(struct vrt_acl *);
void VRT_acl_fini(struct vrt_acl *); void VRT_acl_fini(struct vrt_acl *);
......
...@@ -12,8 +12,10 @@ const char * VRT_r_backend_port(struct backend *); ...@@ -12,8 +12,10 @@ const char * VRT_r_backend_port(struct backend *);
void VRT_l_backend_port(struct backend *, const char *); void VRT_l_backend_port(struct backend *, const char *);
double VRT_r_backend_dnsttl(struct backend *); double VRT_r_backend_dnsttl(struct backend *);
void VRT_l_backend_dnsttl(struct backend *, double); void VRT_l_backend_dnsttl(struct backend *, double);
const unsigned char * VRT_r_client_ip(struct sess *); struct sockaddr * VRT_r_client_ip(struct sess *);
void VRT_l_client_ip(struct sess *, const unsigned char *); void VRT_l_client_ip(struct sess *, struct sockaddr *);
struct sockaddr * VRT_r_server_ip(struct sess *);
void VRT_l_server_ip(struct sess *, struct sockaddr *);
const char * VRT_r_req_request(struct sess *); const char * VRT_r_req_request(struct sess *);
void VRT_l_req_request(struct sess *, const char *); void VRT_l_req_request(struct sess *, const char *);
const char * VRT_r_req_host(struct sess *); const char * VRT_r_req_host(struct sess *);
......
...@@ -113,15 +113,13 @@ vcc_Cond_Ip(struct var *vp, struct tokenlist *tl) ...@@ -113,15 +113,13 @@ vcc_Cond_Ip(struct var *vp, struct tokenlist *tl)
unsigned tcond; unsigned tcond;
char *acln; char *acln;
(void)vp; /* only client.ip at this time */
switch (tl->t->tok) { switch (tl->t->tok) {
case '~': case '~':
vcc_NextToken(tl); vcc_NextToken(tl);
ExpectErr(tl, ID); ExpectErr(tl, ID);
vcc_AddRef(tl, tl->t, R_ACL); vcc_AddRef(tl, tl->t, R_ACL);
Fb(tl, 1, "VRT_acl_match(sp, \"%.*s\", acl_%.*s)\n", Fb(tl, 1, "VRT_acl_match(sp, %s, \"%.*s\", acl_%.*s)\n",
PF(tl->t), PF(tl->t)); vp->rname, PF(tl->t), PF(tl->t));
vcc_NextToken(tl); vcc_NextToken(tl);
break; break;
case T_EQ: case T_EQ:
...@@ -133,8 +131,8 @@ vcc_Cond_Ip(struct var *vp, struct tokenlist *tl) ...@@ -133,8 +131,8 @@ vcc_Cond_Ip(struct var *vp, struct tokenlist *tl)
vcc_acl_top(tl, acln); vcc_acl_top(tl, acln);
vcc_acl_entry(tl); vcc_acl_entry(tl);
vcc_acl_bot(tl, acln); vcc_acl_bot(tl, acln);
Fb(tl, 1, "%sVRT_acl_match(sp, \"%s\", acl_%s)\n", Fb(tl, 1, "%sVRT_acl_match(sp, %s, 0, acl_%s)\n",
(tcond == T_NEQ ? "!" : ""), acln, acln); (tcond == T_NEQ ? "!" : ""), vp->rname, acln);
free(acln); free(acln);
break; break;
default: default:
......
...@@ -391,6 +391,7 @@ vcl_output_lang_h(struct vsb *sb) ...@@ -391,6 +391,7 @@ vcl_output_lang_h(struct vsb *sb)
vsb_cat(sb, "struct vsb;\n"); vsb_cat(sb, "struct vsb;\n");
vsb_cat(sb, "struct backend;\n"); vsb_cat(sb, "struct backend;\n");
vsb_cat(sb, "struct VCL_conf;\n"); vsb_cat(sb, "struct VCL_conf;\n");
vsb_cat(sb, "struct sockaddr;\n");
vsb_cat(sb, "\n"); vsb_cat(sb, "\n");
vsb_cat(sb, "struct vrt_ref {\n"); vsb_cat(sb, "struct vrt_ref {\n");
vsb_cat(sb, " unsigned source;\n"); vsb_cat(sb, " unsigned source;\n");
...@@ -411,7 +412,7 @@ vcl_output_lang_h(struct vsb *sb) ...@@ -411,7 +412,7 @@ vcl_output_lang_h(struct vsb *sb)
vsb_cat(sb, "};\n"); vsb_cat(sb, "};\n");
vsb_cat(sb, "\n"); vsb_cat(sb, "\n");
vsb_cat(sb, "/* ACL related */\n"); vsb_cat(sb, "/* ACL related */\n");
vsb_cat(sb, "int VRT_acl_match(struct sess *, const char *, struct vrt_acl *);\n"); vsb_cat(sb, "int VRT_acl_match(struct sess *, struct sockaddr *, const char *, struct vrt_acl *);\n");
vsb_cat(sb, "void VRT_acl_init(struct vrt_acl *);\n"); vsb_cat(sb, "void VRT_acl_init(struct vrt_acl *);\n");
vsb_cat(sb, "void VRT_acl_fini(struct vrt_acl *);\n"); vsb_cat(sb, "void VRT_acl_fini(struct vrt_acl *);\n");
vsb_cat(sb, "\n"); vsb_cat(sb, "\n");
...@@ -455,8 +456,10 @@ vcl_output_lang_h(struct vsb *sb) ...@@ -455,8 +456,10 @@ vcl_output_lang_h(struct vsb *sb)
vsb_cat(sb, "void VRT_l_backend_port(struct backend *, const char *);\n"); vsb_cat(sb, "void VRT_l_backend_port(struct backend *, const char *);\n");
vsb_cat(sb, "double VRT_r_backend_dnsttl(struct backend *);\n"); vsb_cat(sb, "double VRT_r_backend_dnsttl(struct backend *);\n");
vsb_cat(sb, "void VRT_l_backend_dnsttl(struct backend *, double);\n"); vsb_cat(sb, "void VRT_l_backend_dnsttl(struct backend *, double);\n");
vsb_cat(sb, "const unsigned char * VRT_r_client_ip(struct sess *);\n"); vsb_cat(sb, "struct sockaddr * VRT_r_client_ip(struct sess *);\n");
vsb_cat(sb, "void VRT_l_client_ip(struct sess *, const unsigned char *);\n"); vsb_cat(sb, "void VRT_l_client_ip(struct sess *, struct sockaddr *);\n");
vsb_cat(sb, "struct sockaddr * VRT_r_server_ip(struct sess *);\n");
vsb_cat(sb, "void VRT_l_server_ip(struct sess *, struct sockaddr *);\n");
vsb_cat(sb, "const char * VRT_r_req_request(struct sess *);\n"); vsb_cat(sb, "const char * VRT_r_req_request(struct sess *);\n");
vsb_cat(sb, "void VRT_l_req_request(struct sess *, const char *);\n"); vsb_cat(sb, "void VRT_l_req_request(struct sess *, const char *);\n");
vsb_cat(sb, "const char * VRT_r_req_host(struct sess *);\n"); vsb_cat(sb, "const char * VRT_r_req_host(struct sess *);\n");
......
...@@ -41,6 +41,7 @@ set beobj { ...@@ -41,6 +41,7 @@ set beobj {
set spobj { set spobj {
{ client.ip IP } { client.ip IP }
{ server.ip IP }
{ req.request STRING } { req.request STRING }
{ req.host STRING } { req.host STRING }
{ req.url STRING } { req.url STRING }
...@@ -53,7 +54,7 @@ set spobj { ...@@ -53,7 +54,7 @@ set spobj {
{ resp.http. HEADER } { resp.http. HEADER }
} }
set tt(IP) "const unsigned char *" set tt(IP) "struct sockaddr *"
set tt(STRING) "const char *" set tt(STRING) "const char *"
set tt(BOOL) "double" set tt(BOOL) "double"
set tt(BACKEND) "struct backend *" set tt(BACKEND) "struct backend *"
......
...@@ -30,6 +30,10 @@ struct var vcc_vars[] = { ...@@ -30,6 +30,10 @@ struct var vcc_vars[] = {
"VRT_r_client_ip(sp)", "VRT_r_client_ip(sp)",
"VRT_l_client_ip(sp, ", "VRT_l_client_ip(sp, ",
}, },
{ "server.ip", IP, 9,
"VRT_r_server_ip(sp)",
"VRT_l_server_ip(sp, ",
},
{ "req.request", STRING, 11, { "req.request", STRING, 11,
"VRT_r_req_request(sp)", "VRT_r_req_request(sp)",
"VRT_l_req_request(sp, ", "VRT_l_req_request(sp, ",
......
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