#include <sys/time.h>
#include <sys/uio.h>
+#include <sys/socket.h>
#include <pthread.h>
#include <stdint.h>
struct worker *wrk;
unsigned sockaddrlen;
- struct sockaddr *sockaddr;
+ struct sockaddr sockaddr[2];
+ struct sockaddr mysockaddr[2];
/* formatted ascii client address */
char addr[TCP_ADDRBUFSIZE];
struct sess sess;
struct http http;
- struct sockaddr sockaddr[2]; /* INET6 hack */
unsigned workspace;
TAILQ_ENTRY(sessmem) list;
};
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;
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);
+}
};
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;
}
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;
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
freeaddrinfo(a1);
}
}
-
-
struct vsb;
struct backend;
struct VCL_conf;
+struct sockaddr;
struct vrt_ref {
unsigned source;
};
/* 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 *);
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 *);
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:
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:
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");
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");
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");
set spobj {
{ client.ip IP }
+ { server.ip IP }
{ req.request STRING }
{ req.host STRING }
{ req.url STRING }
{ 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 *"
"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, ",