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