Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

vcc: Internal type for the reserved 'default' symbol #4190

Merged
merged 1 commit into from
Sep 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions bin/varnishtest/tests/c00042.vtc
Original file line number Diff line number Diff line change
Expand Up @@ -176,3 +176,9 @@ varnish v1 -errvcl "Cannot stack .via backends" {
set bereq.backend = c;
}
}

# issue #4177: backend named default with .via property
varnish v1 -vcl {
backend via { .host = "${localhost}"; }
backend default { .via = via; .host = "${localhost}"; }
}
69 changes: 33 additions & 36 deletions lib/libvcc/vcc_backend.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,19 +40,6 @@
#include "vcc_compile.h"
#include "vus.h"

const char *
vcc_default_probe(struct vcc *tl)
{

if (tl->default_probe != NULL)
return (tl->default_probe);
VSB_cat(tl->sb, "No default probe defined\n");
vcc_ErrToken(tl, tl->t);
VSB_cat(tl->sb, " at\n");
vcc_ErrWhere(tl, tl->t);
return ("");
}

/*--------------------------------------------------------------------
* Struct sockaddr is not really designed to be a compile time
* initialized data structure, so we encode it as a byte-string
Expand Down Expand Up @@ -346,16 +333,16 @@ vcc_ParseProbe(struct vcc *tl)

vcc_ExpectVid(tl, "backend probe"); /* ID: name */
ERRCHK(tl);
if (vcc_IdIs(tl->t, "default")) {
vcc_NextToken(tl);
vcc_ParseProbeSpec(tl, NULL, &p);

sym = VCC_HandleSymbol(tl, PROBE);
ERRCHK(tl);
AN(sym);
vcc_ParseProbeSpec(tl, sym, &p);

if (sym->type == DEFAULT)
tl->default_probe = p;
} else {
sym = VCC_HandleSymbol(tl, PROBE);
ERRCHK(tl);
AN(sym);
vcc_ParseProbeSpec(tl, sym, NULL);
}
else
free(p);
}

/*--------------------------------------------------------------------
Expand All @@ -370,6 +357,7 @@ vcc_ParseHostDef(struct vcc *tl, struct symbol *sym,
{
const struct token *t_field;
const struct token *t_val;
const struct token *t_probe;
const struct token *t_host = NULL;
const struct token *t_port = NULL;
const struct token *t_path = NULL;
Expand Down Expand Up @@ -526,16 +514,23 @@ vcc_ParseHostDef(struct vcc *tl, struct symbol *sym,
free(p);
ERRCHK(tl);
} else if (vcc_IdIs(t_field, "probe") && tl->t->tok == ID) {
if (vcc_IdIs(tl->t, "default")) {
vcc_NextToken(tl);
(void)vcc_default_probe(tl);
} else {
pb = VCC_SymbolGet(tl, SYM_MAIN, SYM_PROBE,
SYMTAB_EXISTING, XREF_REF);
ERRCHK(tl);
AN(pb);
Fb(tl, 0, "\t.probe = %s,\n", pb->rname);
t_probe = tl->t;
pb = VCC_SymbolGet(tl, SYM_MAIN, SYM_PROBE,
SYMTAB_EXISTING, XREF_REF);
ERRCHK(tl);
AN(pb);
if (pb->type == DEFAULT) {
if (tl->default_probe == NULL) {
VSB_cat(tl->sb,
"No default probe defined\n");
vcc_ErrToken(tl, t_probe);
VSB_cat(tl->sb, " at\n");
vcc_ErrWhere(tl, t_probe);
}
pb = PROBE->default_sym;
}
ERRCHK(tl);
Fb(tl, 0, "\t.probe = %s,\n", pb->rname);
SkipToken(tl, ';');
} else if (vcc_IdIs(t_field, "probe")) {
VSB_cat(tl->sb, "Expected '{' or name of probe, got ");
Expand Down Expand Up @@ -720,7 +715,12 @@ vcc_ParseBackend(struct vcc *tl)
ERRCHK(tl);

t_be = tl->t;
if (vcc_IdIs(tl->t, "default")) {

sym = VCC_HandleSymbol(tl, BACKEND);
ERRCHK(tl);
AN(sym);

if (sym->type == DEFAULT) {
if (tl->first_director != NULL) {
tl->first_director->noref = 0;
tl->first_director = NULL;
Expand All @@ -732,20 +732,17 @@ vcc_ParseBackend(struct vcc *tl)
vcc_ErrWhere(tl, t_first);
return;
}
vcc_NextToken(tl);
dn = "vgc_backend_default";
tl->default_director = dn;
} else {
sym = VCC_HandleSymbol(tl, BACKEND);
ERRCHK(tl);
AN(sym);
dn = sym->rname;
if (tl->default_director == NULL) {
tl->first_director = sym;
tl->default_director = dn;
sym->noref = 1;
}
}

Fh(tl, 0, "\nstatic VCL_BACKEND %s;\n", dn);
vcc_ParseHostDef(tl, sym, t_be, dn);
if (tl->err) {
Expand Down
5 changes: 4 additions & 1 deletion lib/libvcc/vcc_compile.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ struct type {
const char *global_pfx;
const char *tostring;
vcc_type_t multype;
struct symbol *default_sym;

int stringform;
int bodyform;
int noindent;
Expand All @@ -126,6 +128,8 @@ struct type {
#define VCC_TYPE(UC, lc) extern const struct type UC[1];
#include "vcc_types.h"

extern const struct type DEFAULT[1]; /* type for pseudo-symbol "default" */

/*---------------------------------------------------------------------*/

typedef const struct kind *vcc_kind_t;
Expand Down Expand Up @@ -317,7 +321,6 @@ void vcc_Action_Init(struct vcc *);
/* vcc_backend.c */
struct fld_spec;

const char *vcc_default_probe(struct vcc *);
void vcc_Backend_Init(struct vcc *tl);
void vcc_ParseProbe(struct vcc *tl);
void vcc_ParseBackend(struct vcc *tl);
Expand Down
11 changes: 5 additions & 6 deletions lib/libvcc/vcc_expr.c
Original file line number Diff line number Diff line change
Expand Up @@ -1606,14 +1606,13 @@ vcc_Eval_Default(struct vcc *tl, struct expr **e, struct token *t,
(void)sym;
(void)t;

if (fmt == PROBE)
*e = vcc_mk_expr(PROBE, "%s", vcc_default_probe(tl));
else if (fmt == BACKEND)
*e = vcc_mk_expr(BACKEND, "*(VCL_conf.default_director)");
else {
if (fmt->default_sym == NULL) {
VSB_cat(tl->sb, "Symbol 'default' is a reserved word.\n");
vcc_ErrWhere(tl, t);
return;
}

*e = vcc_mk_expr(fmt, "%s", fmt->default_sym->rname);
}

/*--------------------------------------------------------------------
Expand Down Expand Up @@ -1650,6 +1649,6 @@ vcc_Expr_Init(struct vcc *tl)

sym = VCC_MkSym(tl, "default", SYM_MAIN, SYM_FUNC, VCL_LOW, VCL_HIGH);
AN(sym);
sym->type = BACKEND; // ... can also (sometimes) deliver PROBE
sym->type = DEFAULT;
sym->eval = vcc_Eval_Default;
}
7 changes: 6 additions & 1 deletion lib/libvcc/vcc_symb.c
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ VCC_SymbolGet(struct vcc *tl, vcc_ns_t ns, vcc_kind_t kind,
vcc_ErrWhere2(tl, t0, tl->t);
return (NULL);
}
if (kind != SYM_NONE && kind != sym->kind) {
if (kind != SYM_NONE && kind != sym->kind && sym->type != DEFAULT) {
VSB_cat(tl->sb, "Symbol '");
vcc_PrintTokens(tl, t0, tl->t);
VSB_printf(tl->sb, "' has wrong type (%s), expected %s:",
Expand Down Expand Up @@ -577,6 +577,11 @@ VCC_HandleSymbol(struct vcc *tl, vcc_type_t fmt)
struct token *t;
const char *p;

if (vcc_IdIs(tl->t, "default") && fmt->default_sym != NULL) {
vcc_NextToken(tl);
return (fmt->default_sym);
}

kind = VCC_HandleKind(fmt);
assert(kind != SYM_NONE);

Expand Down
27 changes: 27 additions & 0 deletions lib/libvcc/vcc_types.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,23 @@ static const struct vcc_method backend_methods[] = {
{ VCC_METHOD_MAGIC, NULL },
};

static struct symbol default_backend[1] = {{
.magic = SYMBOL_MAGIC,
.name = "default",
.lorev = 0,
.hirev = 99,
.kind = SYM_BACKEND,
.type = DEFAULT,
.rname = "*(VCL_conf.default_director)",
}};

const struct type BACKEND[1] = {{
.magic = TYPE_MAGIC,
.name = "BACKEND",
.methods = backend_methods,
.global_pfx = "vgc_backend",
.tostring = "VRT_BACKEND_string(\v1)",
.default_sym = default_backend,
}};

const struct type BLOB[1] = {{
Expand Down Expand Up @@ -101,6 +112,11 @@ const struct type BYTES[1] = {{
.multype = REAL, // XXX: wrong
}};

const struct type DEFAULT[1] = {{
.magic = TYPE_MAGIC,
.name = "DEFAULT",
}};

const struct type DURATION[1] = {{
.magic = TYPE_MAGIC,
.name = "DURATION",
Expand Down Expand Up @@ -144,10 +160,21 @@ const struct type IP[1] = {{
.tostring = "VRT_IP_string(ctx, \v1)",
}};

static struct symbol default_probe[1] = {{
.magic = SYMBOL_MAGIC,
.name = "default",
.lorev = 0,
.hirev = 99,
.kind = SYM_PROBE,
.type = DEFAULT,
.rname = "vgc_probe_default",
}};

const struct type PROBE[1] = {{
.magic = TYPE_MAGIC,
.name = "PROBE",
.global_pfx = "vgc_probe",
.default_sym = default_probe,
}};

const struct type REAL[1] = {{
Expand Down