cache_session.c \
cache_vcl.c \
cache_vrt.c \
+ cache_vrt_acl.c \
cli_event.c \
hash_simple_list.c \
hash_classic.c \
}
}
+void
+VRT_free_backends(struct VCL_conf *cp)
+{
+
+ (void)cp;
+}
+
+void
+VRT_fini_backend(struct backend *be)
+{
+ (void)be;
+}
+
/*--------------------------------------------------------------------*/
#define VBACKEND(type,onm,field) \
--- /dev/null
+/*
+ * $Id$
+ *
+ * Runtime support for compiled VCL programs, ACLs
+ *
+ * XXX: getaddrinfo() does not return a TTL. We might want to add
+ * XXX: a refresh facility.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "shmlog.h"
+#include "vrt.h"
+#include "vrt_obj.h"
+#include "vcl.h"
+#include "cache.h"
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+
+
+int
+VRT_acl_match(struct sess *sp, struct vrt_acl *ap)
+{
+ (void)sp;
+ (void)ap;
+ return (0);
+}
+
+void
+VRT_acl_init(struct vrt_acl *ap)
+{
+ struct addrinfo a0, *a1;
+ int i;
+
+ memset(&a0, 0, sizeof a0);
+ a0.ai_socktype = SOCK_STREAM;
+
+ for ( ; ap->name != NULL; ap++) {
+ a1 = NULL;
+ i = getaddrinfo(ap->name, NULL, &a0, &a1);
+ if (i != 0) {
+ fprintf(stderr, "getaddrinfo(%s) = %s\n",
+ ap->name, gai_strerror(i));
+ if (a1 != NULL)
+ freeaddrinfo(a1);
+ a1 = NULL;
+ }
+ ap->priv = a1;
+ }
+}
+
+void
+VRT_acl_fini(struct vrt_acl *ap)
+{
+ struct addrinfo *a1;
+
+ for ( ; ap->name != NULL; ap++) {
+ if (ap->priv == NULL)
+ continue;
+ a1 = ap->priv;
+ ap->priv = NULL;
+ freeaddrinfo(a1);
+ }
+}
+
+
struct sess;
typedef void vcl_init_f(void);
+typedef void vcl_fini_f(void);
typedef int vcl_func_f(struct sess *sp);
struct VCL_conf {
unsigned busy;
vcl_init_f *init_func;
+ vcl_fini_f *fini_func;
vcl_func_f *recv_func;
vcl_func_f *miss_func;
/*
- * $Id: vcc_gen_fixed_token.tcl 545 2006-07-21 20:43:56Z phk $
+ * $Id: vcc_gen_fixed_token.tcl 553 2006-07-21 21:57:43Z phk $
*
* NB: This file is machine generated, DO NOT EDIT!
*
};
struct vrt_acl {
- unsigned ip;
- unsigned mask;
+ unsigned char not;
+ unsigned char paren;
+ unsigned char mask;
+ const char *name;
+ void *priv;
};
+/* ACL related */
+int VRT_acl_match(struct sess *, struct vrt_acl *);
+void VRT_acl_init(struct vrt_acl *);
+void VRT_acl_fini(struct vrt_acl *);
+
void VRT_count(struct sess *, unsigned);
-#if 0
-int ip_match(unsigned, struct vcl_acl *);
-int string_match(const char *, const char *);
-#endif
int VRT_rewrite(const char *, const char *);
void VRT_error(struct sess *, unsigned, const char *);
int VRT_switch_config(const char *);
char *VRT_GetHdr(struct sess *, const char *);
void VRT_handling(struct sess *sp, unsigned hand);
+/* Backend related */
void VRT_set_backend_name(struct backend *, const char *);
-
void VRT_alloc_backends(struct VCL_conf *cp);
+void VRT_free_backends(struct VCL_conf *cp);
+void VRT_fini_backend(struct backend *be);
+
#define VRT_done(sp, hand) \
do { \
/*
- * $Id: vcc_gen_obj.tcl 550 2006-07-21 21:13:43Z phk $
+ * $Id: vcc_gen_obj.tcl 555 2006-07-22 08:02:47Z phk $
*
* NB: This file is machine generated, DO NOT EDIT!
*
#include "libvcl.h"
-unsigned
-vcc_IpVal(struct tokenlist *tl)
-{
- unsigned u, v;
- struct token *t;
-
- t = tl->t;
- u = UintVal(tl);
- if (u < 256) {
- v = u << 24;
- Expect(tl, '.');
- vcc_NextToken(tl);
- t = tl->t;
- u = UintVal(tl);
- if (u < 256) {
- v |= u << 16;
- Expect(tl, '.');
- vcc_NextToken(tl);
- t = tl->t;
- u = UintVal(tl);
- if (u < 256) {
- v |= u << 8;
- Expect(tl, '.');
- vcc_NextToken(tl);
- t = tl->t;
- u = UintVal(tl);
- if (u < 256) {
- v |= u;
- return (v);
- }
- }
- }
- }
- sbuf_printf(tl->sb, "Illegal octet in IP number\n");
- vcc_ErrWhere(tl, t);
- return (0);
-}
-
void
vcc_Cond_Ip(struct var *vp, struct tokenlist *tl)
{
- unsigned u;
+
+ (void)vp; /* only client.ip at this time */
switch (tl->t->tok) {
case '~':
vcc_NextToken(tl);
ExpectErr(tl, ID);
AddRef(tl, tl->t, R_ACL);
- Fc(tl, 1, "ip_match(%s, acl_%T)\n", vp->rname, tl->t);
- vcc_NextToken(tl);
- break;
- case T_EQ:
- case T_NEQ:
- Fc(tl, 1, "%s %T ", vp->rname, tl->t);
+ Fc(tl, 1, "VRT_acl_match(sp, acl_%T)\n", tl->t);
vcc_NextToken(tl);
- u = vcc_IpVal(tl);
- Fc(tl, 0, "%uU /* %u.%u.%u.%u */\n", u,
- (u >> 24) & 0xff, (u >> 16) & 0xff,
- (u >> 8) & 0xff, (u) & 0xff);
break;
default:
sbuf_printf(tl->sb, "Illegal condition ");
void
vcc_Acl(struct tokenlist *tl)
{
- unsigned u, m;
+ unsigned mask, para, not;
+ struct token *t, *an;
vcc_NextToken(tl);
ExpectErr(tl, ID);
- AddDef(tl, tl->t, R_ACL);
- Fh(tl, 0, "static struct vcl_acl acl_%T[];\n", tl->t);
- Fc(tl, 1, "static struct vcl_acl acl_%T[] = {\n", tl->t);
+ an = tl->t;
vcc_NextToken(tl);
+ AddDef(tl, an, R_ACL);
+ Fh(tl, 0, "static struct vrt_acl acl_%T[];\n", an);
+ Fc(tl, 1, "static struct vrt_acl acl_%T[] = {\n", an);
+
tl->indent += INDENT;
ExpectErr(tl, '{');
vcc_NextToken(tl);
- while (tl->t->tok == CNUM) {
- u = vcc_IpVal(tl);
+ while (tl->t->tok != '}') {
+
+ not = para = mask = 0;
+
+ if (tl->t->tok == '!') {
+ not = 1;
+ vcc_NextToken(tl);
+ }
+
+ if (tl->t->tok == '(') {
+ para = 1;
+ vcc_NextToken(tl);
+ }
+
+ ExpectErr(tl, CSTR);
+ /* XXX: try to look it up, warn if failure */
+ t = tl->t;
+ vcc_NextToken(tl);
if (tl->t->tok == '/') {
vcc_NextToken(tl);
ExpectErr(tl, CNUM);
- m = UintVal(tl);
- } else
- m = 32;
+ mask = UintVal(tl);
+ }
+ Fc(tl, 1, "{ %u, %u, %u, %T },\n", not, mask, para, t);
+
+ if (para) {
+ ExpectErr(tl, ')');
+ vcc_NextToken(tl);
+ }
ExpectErr(tl, ';');
vcc_NextToken(tl);
- Fc(tl, 1, "{ %11uU, %3uU }, /* %u.%u.%u.%u/%u */\n",
- u, m,
- (u >> 24) & 0xff, (u >> 16) & 0xff,
- (u >> 8) & 0xff, (u) & 0xff, m);
}
- ExpectErr(tl, '}');
- Fc(tl, 1, "{ %11uU, %3uU }\n", 0, 0);
-
+ Fc(tl, 1, "{ 0, 0, 0, (void*)0}\n", 0, 0);
tl->indent -= INDENT;
-
Fc(tl, 1, "};\n\n");
+
+ ExpectErr(tl, '}');
vcc_NextToken(tl);
+
+ Fi(tl, 1, "\tVRT_acl_init(acl_%T);\n", an);
+ Ff(tl, 1, "\tVRT_acl_fini(acl_%T);\n", an);
}
va_end(ap);
}
+void
+Fi(struct tokenlist *tl, int indent, const char *fmt, ...)
+{
+ va_list ap;
+
+ if (indent)
+ sbuf_printf(tl->fi, "%*.*s", tl->indent, tl->indent, "");
+ va_start(ap, fmt);
+ sbuf_vprintf(tl->fi, fmt, ap);
+ va_end(ap);
+}
+
+void
+Ff(struct tokenlist *tl, int indent, const char *fmt, ...)
+{
+ va_list ap;
+
+ if (indent)
+ sbuf_printf(tl->ff, "%*.*s", tl->indent, tl->indent, "");
+ va_start(ap, fmt);
+ sbuf_vprintf(tl->ff, fmt, ap);
+ va_end(ap);
+}
+
/*--------------------------------------------------------------------*/
-static char *
+char *
EncString(struct token *t)
{
char *p, *q;
AddRef(tl, tl->t, R_BACKEND);
Fh(tl, 1, "#define VGC_backend_%T (VCL_conf.backend[%d])\n",
tl->t, tl->nbackend);
+ Fc(tl, 0, "\n");
Fc(tl, 0, "static void\n");
Fc(tl, 1, "VGC_init_backend_%T (void)\n", tl->t);
Fc(tl, 1, "{\n");
Fc(tl, 1, "\tstruct backend *backend = VGC_backend_%T;\n", tl->t);
- Fc(tl, 1, "\tconst char *p;\n");
Fc(tl, 1, "\n");
Fc(tl, 1, "\tVRT_set_backend_name(backend, \"%T\");\n", tl->t);
vcc_NextToken(tl);
vcc_NextToken(tl);
Fc(tl, 1, "}\n");
Fc(tl, 0, "\n");
+ Fi(tl, 0, "\tVGC_init_backend_%T();\n", t_be);
+ Ff(tl, 0, "\tVRT_fini_backend(VGC_backend_%T);\n", t_be);
tl->nbackend++;
}
static void
EmitInitFunc(struct tokenlist *tl)
{
- struct ref *r;
Fc(tl, 0, "\nstatic void\nVGC_Init(void)\n{\n\n");
- Fc(tl, 0, "\tVRT_alloc_backends(&VCL_conf);\n");
-
- TAILQ_FOREACH(r, &tl->refs, list) {
- switch(r->type) {
- case R_FUNC:
- break;
- case R_ACL:
- break;
- case R_BACKEND:
- Fc(tl, 0, "\tVGC_init_backend_%T();\n", r->name);
- break;
- }
- }
+ sbuf_finish(tl->fi);
+ sbuf_cat(tl->fc, sbuf_data(tl->fi));
+ Fc(tl, 0, "}\n");
+}
+
+static void
+EmitFiniFunc(struct tokenlist *tl)
+{
+
+ Fc(tl, 0, "\nstatic void\nVGC_Fini(void)\n{\n\n");
+ sbuf_finish(tl->ff);
+ sbuf_cat(tl->fc, sbuf_data(tl->ff));
Fc(tl, 0, "}\n");
}
Fc(tl, 0, "\nstruct VCL_conf VCL_conf = {\n");
Fc(tl, 0, "\t.magic = VCL_CONF_MAGIC,\n");
Fc(tl, 0, "\t.init_func = VGC_Init,\n");
+ Fc(tl, 0, "\t.fini_func = VGC_Fini,\n");
Fc(tl, 0, "\t.nbackend = %d,\n", tl->nbackend);
Fc(tl, 0, "\t.ref = VGC_ref,\n");
Fc(tl, 0, "\t.nref = VGC_NREFS,\n");
tokens.fh = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND);
assert(tokens.fh != NULL);
+ tokens.fi = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND);
+ assert(tokens.fi != NULL);
+
+ tokens.ff = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND);
+ assert(tokens.ff != NULL);
+
Fh(&tokens, 0, "extern struct VCL_conf VCL_conf;\n");
+ Fi(&tokens, 0, "\tVRT_alloc_backends(&VCL_conf);\n");
+
tokens.b = b;
if (e == NULL)
e = strchr(b, '\0');
goto done;
LocTable(&tokens);
+ Ff(&tokens, 0, "\tVRT_free_backends(&VCL_conf);\n");
+
EmitInitFunc(&tokens);
+ EmitFiniFunc(&tokens);
+
EmitStruct(&tokens);
if (CheckRefs(&tokens))
struct token *t;
int indent;
unsigned cnt;
- struct sbuf *fc, *fh;
+ struct sbuf *fc, *fh, *fi, *ff;
TAILQ_HEAD(, ref) refs;
struct sbuf *sb;
int err;
/* vcc_acl.c */
void vcc_Acl(struct tokenlist *tl);
-unsigned vcc_IpVal(struct tokenlist *tl);
void vcc_Cond_Ip(struct var *vp, struct tokenlist *tl);
/* vcc_compile.c */
extern const char *vcc_default_vcl_b, *vcc_default_vcl_e;
void Fh(struct tokenlist *tl, int indent, const char *fmt, ...);
void Fc(struct tokenlist *tl, int indent, const char *fmt, ...);
+void Fi(struct tokenlist *tl, int indent, const char *fmt, ...);
+void Ff(struct tokenlist *tl, int indent, const char *fmt, ...);
unsigned UintVal(struct tokenlist *tl);
void AddDef(struct tokenlist *tl, struct token *t, enum ref_type type);
void AddRef(struct tokenlist *tl, struct token *t, enum ref_type type);
+char *EncString(struct token *t);
+
/* vcc_obj.c */
extern struct var vcc_be_vars[];
fputs("struct sess;\n", f);
fputs("\n", f);
fputs("typedef void vcl_init_f(void);\n", f);
+ fputs("typedef void vcl_fini_f(void);\n", f);
fputs("typedef int vcl_func_f(struct sess *sp);\n", f);
fputs("\n", f);
fputs("struct VCL_conf {\n", f);
fputs(" unsigned busy;\n", f);
fputs("\n", f);
fputs(" vcl_init_f *init_func;\n", f);
+ fputs(" vcl_fini_f *fini_func;\n", f);
fputs("\n", f);
fputs(" vcl_func_f *recv_func;\n", f);
fputs(" vcl_func_f *miss_func;\n", f);
fputs("};\n", f);
fputs("\n", f);
fputs("struct vrt_acl {\n", f);
- fputs(" unsigned ip;\n", f);
- fputs(" unsigned mask;\n", f);
+ fputs(" unsigned char not;\n", f);
+ fputs(" unsigned char paren;\n", f);
+ fputs(" unsigned char mask;\n", f);
+ fputs(" const char *name;\n", f);
+ fputs(" void *priv;\n", f);
fputs("};\n", f);
fputs("\n", f);
+ fputs("/* ACL related */\n", f);
+ fputs("int VRT_acl_match(struct sess *, struct vrt_acl *);\n", f);
+ fputs("void VRT_acl_init(struct vrt_acl *);\n", f);
+ fputs("void VRT_acl_fini(struct vrt_acl *);\n", f);
+ fputs("\n", f);
fputs("void VRT_count(struct sess *, unsigned);\n", f);
- fputs("#if 0\n", f);
- fputs("int ip_match(unsigned, struct vcl_acl *);\n", f);
- fputs("int string_match(const char *, const char *);\n", f);
- fputs("#endif\n", f);
fputs("int VRT_rewrite(const char *, const char *);\n", f);
fputs("void VRT_error(struct sess *, unsigned, const char *);\n", f);
fputs("int VRT_switch_config(const char *);\n", f);
fputs("char *VRT_GetHdr(struct sess *, const char *);\n", f);
fputs("void VRT_handling(struct sess *sp, unsigned hand);\n", f);
fputs("\n", f);
+ fputs("/* Backend related */\n", f);
fputs("void VRT_set_backend_name(struct backend *, const char *);\n", f);
- fputs("\n", f);
fputs("void VRT_alloc_backends(struct VCL_conf *cp);\n", f);
+ fputs("void VRT_free_backends(struct VCL_conf *cp);\n", f);
+ fputs("void VRT_fini_backend(struct backend *be);\n", f);
+ fputs("\n", f);
fputs("\n", f);
fputs("#define VRT_done(sp, hand) \\\n", f);
fputs(" do { \\\n", f);
puts $fo {struct sess;
typedef void vcl_init_f(void);
+typedef void vcl_fini_f(void);
typedef int vcl_func_f(struct sess *sp);
}
puts $fo "struct VCL_conf {"
unsigned busy;
vcl_init_f *init_func;
+ vcl_fini_f *fini_func;
}
foreach m $methods {
puts $fo "\tvcl_func_f\t*[lindex $m 0]_func;"