varnish-cache/lib/libvcc/vcc_backend.c
0
/*-
1
 * Copyright (c) 2006 Verdens Gang AS
2
 * Copyright (c) 2006-2015 Varnish Software AS
3
 * All rights reserved.
4
 *
5
 * Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
6
 *
7
 * SPDX-License-Identifier: BSD-2-Clause
8
 *
9
 * Redistribution and use in source and binary forms, with or without
10
 * modification, are permitted provided that the following conditions
11
 * are met:
12
 * 1. Redistributions of source code must retain the above copyright
13
 *    notice, this list of conditions and the following disclaimer.
14
 * 2. Redistributions in binary form must reproduce the above copyright
15
 *    notice, this list of conditions and the following disclaimer in the
16
 *    documentation and/or other materials provided with the distribution.
17
 *
18
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21
 * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
22
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28
 * SUCH DAMAGE.
29
 *
30
 */
31
32
#include "config.h"
33
34
#include <math.h>
35
#include <stdlib.h>
36
#include <string.h>
37
#include <sys/stat.h>
38
39
#include "vcc_compile.h"
40
#include "vus.h"
41
42
/*--------------------------------------------------------------------
43
 * Struct sockaddr is not really designed to be a compile time
44
 * initialized data structure, so we encode it as a byte-string
45
 * and put it in an official sockaddr when we load the VCL.
46
 */
47
48
static void
49 53320
Emit_Sockaddr(struct vcc *tl, struct vsb *vsb1, const struct token *t_host,
50
    const struct token *t_port)
51
{
52
        const char *ipv4, *ipv4a, *ipv6, *ipv6a, *pa;
53
        char buf[BUFSIZ];
54
55 53320
        AN(t_host->dec);
56
57 53320
        if (t_port != NULL)
58 40440
                bprintf(buf, "%s %s", t_host->dec, t_port->dec);
59
        else
60 12880
                bprintf(buf, "%s", t_host->dec);
61 106640
        Resolve_Sockaddr(tl, buf, "80",
62 53320
            &ipv4, &ipv4a, &ipv6, &ipv6a, &pa, 2, t_host, "Backend host");
63 53320
        ERRCHK(tl);
64 53240
        if (ipv4 != NULL) {
65 106000
                VSB_printf(vsb1,
66
                    "\t.ipv4 = (const struct suckaddr *)%s,\n",
67 53000
                    ipv4);
68 53000
        }
69 53240
        if (ipv6 != NULL) {
70 560
                VSB_printf(vsb1,
71
                    "\t.ipv6 = (const struct suckaddr *)%s,\n",
72 280
                    ipv6);
73 280
        }
74 53240
        VSB_cat(vsb1, "\t.uds_path = (void *) 0,\n");
75 53320
}
76
77
/*
78
 * For UDS, we do not create a VSA. We run the VUS_resolver() checks and, if
79
 * it's a path, can be accessed, and is a socket. If so, just emit the path
80
 * field and set the IP suckaddrs to NULL.
81
 */
82
83
static int
84 1280
uds_resolved(void *priv, const struct sockaddr_un *uds)
85
{
86 1280
        (void) priv;
87 1280
        (void) uds;
88 1280
        return (42);
89
}
90
91
static void
92 1240
emit_path(struct vsb *vsb1, char *path)
93
{
94 1240
        VSB_printf(vsb1, "\t.uds_path = \"%s\",\n", path);
95 1240
        VSB_cat(vsb1, "\t.ipv4 = (void *) 0,\n");
96 1240
        VSB_cat(vsb1, "\t.ipv6 = (void *) 0,\n");
97 1240
}
98
99
static void
100 1360
Emit_UDS_Path(struct vcc *tl, struct vsb *vsb1,
101
    const struct token *t_path, const char *errid)
102
{
103
        struct stat st;
104
        const char *vus_err;
105
106 1360
        AN(t_path);
107 1360
        AN(t_path->dec);
108
109 1360
        if (! VUS_is(t_path->dec)) {
110 80
                VSB_printf(tl->sb,
111
                           "%s: Must be a valid path or abstract socket:\n",
112 40
                           errid);
113 40
                vcc_ErrWhere(tl, t_path);
114 40
                return;
115
        }
116 1320
        if (VUS_resolver(t_path->dec, uds_resolved, NULL, &vus_err) != 42) {
117 40
                VSB_printf(tl->sb, "%s: %s\n", errid, vus_err);
118 40
                vcc_ErrWhere(tl, t_path);
119 40
                return;
120
        }
121 1280
        if (*t_path->dec == '@') {
122 0
                emit_path(vsb1, t_path->dec);
123 0
                return;
124
        }
125 1280
        assert(*t_path->dec == '/');
126 1280
        errno = 0;
127 1280
        if (stat(t_path->dec, &st) != 0) {
128 40
                int err = errno;
129 80
                VSB_printf(tl->sb, "%s: Cannot stat: %s\n", errid,
130 40
                           strerror(errno));
131 40
                vcc_ErrWhere(tl, t_path);
132 40
                if (err == ENOENT || err == EACCES)
133 40
                        vcc_Warn(tl);
134
                else
135 0
                        return;
136 1280
        } else if (!S_ISSOCK(st.st_mode)) {
137 40
                VSB_printf(tl->sb, "%s: Not a socket:\n", errid);
138 40
                vcc_ErrWhere(tl, t_path);
139 40
                return;
140
        }
141 1240
        emit_path(vsb1, t_path->dec);
142 1360
}
143
144
/*--------------------------------------------------------------------
145
 * Disallow mutually exclusive field definitions
146
 */
147
148
static void
149 56080
vcc_Redef(struct vcc *tl, const char *redef, const struct token **t_did,
150
    const struct token *t_field)
151
{
152 56080
        if (*t_did != NULL) {
153 120
                VSB_printf(tl->sb, "%s redefinition at:\n", redef);
154 120
                vcc_ErrWhere(tl, t_field);
155 120
                VSB_cat(tl->sb, "Previous definition:\n");
156 120
                vcc_ErrWhere(tl, *t_did);
157 120
                return;
158
        }
159 55960
        *t_did = t_field;
160 56080
}
161
162
/*--------------------------------------------------------------------
163
 * Parse a backend probe specification
164
 */
165
166
static void
167 1880
vcc_ParseProbeSpec(struct vcc *tl, const struct symbol *sym, char **namep)
168
{
169
        struct fld_spec *fs;
170
        const struct token *t_field;
171 1880
        const struct token *t_did = NULL, *t_window = NULL, *t_threshold = NULL;
172 1880
        struct token *t_initial = NULL;
173
        unsigned window, threshold, initial, status, exp_close;
174
        char buf[32];
175
        const char *name;
176
        double t;
177
178 1880
        fs = vcc_FldSpec(tl,
179
            "?url",
180
            "?request",
181
            "?expected_response",
182
            "?timeout",
183
            "?interval",
184
            "?window",
185
            "?threshold",
186
            "?initial",
187
            "?expect_close",
188
            NULL);
189
190 1880
        SkipToken(tl, '{');
191
192 1880
        if (sym != NULL) {
193 840
                name = sym->rname;
194 840
        } else {
195 1040
                bprintf(buf, "vgc_probe__%d", tl->nprobe++);
196 1040
                name = buf;
197
        }
198 1880
        Fh(tl, 0, "static const struct vrt_backend_probe %s[] = {{\n", name);
199 1880
        Fh(tl, 0, "\t.magic = VRT_BACKEND_PROBE_MAGIC,\n");
200 1880
        if (namep != NULL)
201 1880
                *namep = TlDup(tl, name);
202
203 1880
        window = 0;
204 1880
        threshold = 0;
205 1880
        initial = 0;
206 1880
        status = 0;
207 1880
        exp_close = 1;
208 6280
        while (tl->t->tok != '}') {
209
210 4640
                vcc_IsField(tl, &t_field, fs);
211 4640
                ERRCHK(tl);
212 4640
                if (vcc_IdIs(t_field, "url")) {
213 520
                        vcc_Redef(tl, "Probe request", &t_did, t_field);
214 520
                        ERRCHK(tl);
215 480
                        ExpectErr(tl, CSTR);
216 480
                        Fh(tl, 0, "\t.url = ");
217 480
                        EncToken(tl->fh, tl->t);
218 480
                        Fh(tl, 0, ",\n");
219 480
                        vcc_NextToken(tl);
220 4600
                } else if (vcc_IdIs(t_field, "request")) {
221 200
                        vcc_Redef(tl, "Probe request", &t_did, t_field);
222 200
                        ERRCHK(tl);
223 160
                        ExpectErr(tl, CSTR);
224 160
                        Fh(tl, 0, "\t.request =\n");
225 640
                        while (tl->t->tok == CSTR) {
226 480
                                Fh(tl, 0, "\t\t");
227 480
                                EncToken(tl->fh, tl->t);
228 480
                                Fh(tl, 0, " \"\\r\\n\"\n");
229 480
                                vcc_NextToken(tl);
230
                        }
231 160
                        Fh(tl, 0, "\t\t\"\\r\\n\",\n");
232 4080
                } else if (vcc_IdIs(t_field, "timeout")) {
233 400
                        Fh(tl, 0, "\t.timeout = ");
234 400
                        vcc_Duration(tl, &t);
235 400
                        ERRCHK(tl);
236 360
                        Fh(tl, 0, "%g,\n", t);
237 3880
                } else if (vcc_IdIs(t_field, "interval")) {
238 1040
                        Fh(tl, 0, "\t.interval = ");
239 1040
                        vcc_Duration(tl, &t);
240 1040
                        ERRCHK(tl);
241 1040
                        Fh(tl, 0, "%g,\n", t);
242 3520
                } else if (vcc_IdIs(t_field, "window")) {
243 800
                        t_window = tl->t;
244 800
                        window = vcc_UintVal(tl);
245 800
                        ERRCHK(tl);
246 2480
                } else if (vcc_IdIs(t_field, "initial")) {
247 560
                        t_initial = tl->t;
248 560
                        initial = vcc_UintVal(tl);
249 560
                        ERRCHK(tl);
250 1680
                } else if (vcc_IdIs(t_field, "expected_response")) {
251 80
                        status = vcc_UintVal(tl);
252 80
                        if (status < 100 || status > 999) {
253 40
                                VSB_cat(tl->sb,
254
                                    "Must specify .expected_response with "
255
                                    "exactly three digits "
256
                                    "(100 <= x <= 999)\n");
257 40
                                vcc_ErrWhere(tl, tl->t);
258 40
                                return;
259
                        }
260 40
                        ERRCHK(tl);
261 1080
                } else if (vcc_IdIs(t_field, "threshold")) {
262 880
                        t_threshold = tl->t;
263 880
                        threshold = vcc_UintVal(tl);
264 880
                        ERRCHK(tl);
265 1040
                } else if (vcc_IdIs(t_field, "expect_close")) {
266 160
                        exp_close = vcc_BoolVal(tl);
267 160
                        ERRCHK(tl);
268 80
                } else {
269 0
                        vcc_ErrToken(tl, t_field);
270 0
                        vcc_ErrWhere(tl, t_field);
271 0
                        ErrInternal(tl);
272 0
                        return;
273
                }
274
275 4400
                SkipToken(tl, ';');
276
        }
277 1640
        free(fs);
278
279 1640
        if (t_threshold != NULL || t_window != NULL) {
280 920
                if (t_threshold == NULL && t_window != NULL) {
281 40
                        VSB_cat(tl->sb,
282
                            "Must specify .threshold with .window\n");
283 40
                        vcc_ErrWhere(tl, t_window);
284 40
                        return;
285 880
                } else if (t_threshold != NULL && t_window == NULL) {
286 120
                        if (threshold > 64) {
287 40
                                VSB_cat(tl->sb,
288
                                    "Threshold must be 64 or less.\n");
289 40
                                vcc_ErrWhere(tl, t_threshold);
290 40
                                return;
291
                        }
292 80
                        window = threshold + 1;
293 840
                } else if (window > 64) {
294 40
                        AN(t_window);
295 40
                        VSB_cat(tl->sb, "Window must be 64 or less.\n");
296 40
                        vcc_ErrWhere(tl, t_window);
297 40
                        return;
298
                }
299 800
                if (threshold > window ) {
300 40
                        VSB_cat(tl->sb,
301
                            "Threshold cannot be greater than window.\n");
302 40
                        AN(t_threshold);
303 40
                        vcc_ErrWhere(tl, t_threshold);
304 40
                        AN(t_window);
305 40
                        vcc_ErrWhere(tl, t_window);
306 40
                }
307 800
                Fh(tl, 0, "\t.window = %u,\n", window);
308 800
                Fh(tl, 0, "\t.threshold = %u,\n", threshold);
309 800
        }
310 1520
        if (t_initial != NULL)
311 560
                Fh(tl, 0, "\t.initial = %u,\n", initial);
312
        else
313 960
                Fh(tl, 0, "\t.initial = ~0U,\n");
314 1520
        if (status > 0)
315 40
                Fh(tl, 0, "\t.exp_status = %u,\n", status);
316 1520
        Fh(tl, 0, "\t.exp_close = %u,\n", exp_close);
317 1520
        Fh(tl, 0, "}};\n");
318 1520
        SkipToken(tl, '}');
319 1880
}
320
321
/*--------------------------------------------------------------------
322
 * Parse and emit a probe definition
323
 */
324
325
void
326 880
vcc_ParseProbe(struct vcc *tl)
327
{
328
        struct symbol *sym;
329
        char *p;
330
331 880
        vcc_NextToken(tl);                      /* ID: probe */
332
333 880
        vcc_ExpectVid(tl, "backend probe");     /* ID: name */
334 880
        ERRCHK(tl);
335
336 880
        sym = VCC_HandleSymbol(tl, PROBE);
337 880
        ERRCHK(tl);
338 840
        AN(sym);
339 840
        vcc_ParseProbeSpec(tl, sym, &p);
340
341 840
        if (sym->type == DEFAULT)
342 400
                tl->default_probe = p;
343
        else
344 440
                free(p);
345 880
}
346
347
/*--------------------------------------------------------------------
348
 * Parse and emit a backend host definition
349
 *
350
 * The struct vrt_backend is emitted to Fh().
351
 */
352
353
static void
354 65000
vcc_ParseHostDef(struct vcc *tl, struct symbol *sym,
355
    const struct token *t_be, const char *vgcname)
356
{
357
        const struct token *t_field;
358
        const struct token *t_val;
359
        const struct token *t_probe;
360 65000
        const struct token *t_host = NULL;
361 65000
        const struct token *t_port = NULL;
362 65000
        const struct token *t_path = NULL;
363 65000
        const struct token *t_hosthdr = NULL;
364 65000
        const struct token *t_authority = NULL;
365 65000
        const struct token *t_did = NULL;
366 65000
        const struct token *t_preamble = NULL;
367
        struct symbol *pb;
368
        struct fld_spec *fs;
369
        struct inifin *ifp;
370
        struct vsb *vsb1;
371 65000
        struct symbol *via = NULL;
372 65000
        vtim_dur connect_timeout = NAN;
373 65000
        vtim_dur first_byte_timeout = NAN;
374 65000
        vtim_dur between_bytes_timeout = NAN;
375 65000
        vtim_dur backend_wait_timeout = NAN;
376
        char *p;
377
        unsigned u;
378
379 69160
        if (tl->t->tok == ID &&
380 9480
            (vcc_IdIs(tl->t, "none") || vcc_IdIs(tl->t, "None"))) {
381 9480
                vcc_NextToken(tl);
382 9480
                SkipToken(tl, ';');
383 9480
                ifp = New_IniFin(tl);
384 9480
                VSB_printf(ifp->ini, "\t(void)%s;", vgcname);
385 9480
                VSB_printf(ifp->fin, "\t\t(void)%s;", vgcname);
386 9480
                return;
387
        }
388
389 55520
        SkipToken(tl, '{');
390
391
        /* Check for old syntax */
392 55520
        if (tl->t->tok == ID && vcc_IdIs(tl->t, "set")) {
393 40
                VSB_cat(tl->sb,
394
                    "NB: Backend Syntax has changed:\n"
395
                    "Remove \"set\" and \"backend\" in front"
396
                    " of backend fields.\n" );
397 40
                vcc_ErrToken(tl, tl->t);
398 40
                VSB_cat(tl->sb, " at ");
399 40
                vcc_ErrWhere(tl, tl->t);
400 40
                return;
401
        }
402
403 55480
        fs = vcc_FldSpec(tl,
404
            "?host",
405
            "?port",
406
            "?path",
407
            "?host_header",
408
            "?connect_timeout",
409
            "?first_byte_timeout",
410
            "?between_bytes_timeout",
411
            "?probe",
412
            "?max_connections",
413
            "?proxy_header",
414
            "?preamble",
415
            "?via",
416
            "?authority",
417
            "?wait_timeout",
418
            "?wait_limit",
419
            NULL);
420
421 55480
        tl->fb = VSB_new_auto();
422 55480
        AN(tl->fb);
423
424 110960
        Fb(tl, 0, "\nstatic const struct vrt_backend vgc_dir_priv_%s = {\n",
425 55480
            vgcname);
426
427 55480
        Fb(tl, 0, "\t.magic = VRT_BACKEND_MAGIC,\n");
428 55480
        Fb(tl, 0, "\t.endpoint = &vgc_dir_ep_%s,\n", vgcname);
429 55480
        Fb(tl, 0, "\t.vcl_name = \"%.*s", PF(t_be));
430 55480
        Fb(tl, 0, "\",\n");
431
432 154360
        while (tl->t->tok != '}') {
433
434 99600
                vcc_IsField(tl, &t_field, fs);
435 99600
                ERRCHK(tl);
436 99520
                if (vcc_IdIs(t_field, "host")) {
437 53920
                        vcc_Redef(tl, "Address", &t_did, t_field);
438 53920
                        ERRCHK(tl);
439 53920
                        ExpectErr(tl, CSTR);
440 53920
                        assert(tl->t->dec != NULL);
441 53920
                        t_host = tl->t;
442 53920
                        vcc_NextToken(tl);
443 53920
                        SkipToken(tl, ';');
444 99520
                } else if (vcc_IdIs(t_field, "port")) {
445 40520
                        ExpectErr(tl, CSTR);
446 40520
                        assert(tl->t->dec != NULL);
447 40520
                        t_port = tl->t;
448 40520
                        vcc_NextToken(tl);
449 40520
                        SkipToken(tl, ';');
450 45600
                } else if (vcc_IdIs(t_field, "path")) {
451 1480
                        if (tl->syntax < VCL_41) {
452 40
                                VSB_cat(tl->sb,
453
                                    "Unix socket backends only supported"
454
                                    " in VCL4.1 and higher.\n");
455 40
                                vcc_ErrToken(tl, tl->t);
456 40
                                VSB_cat(tl->sb, " at ");
457 40
                                vcc_ErrWhere(tl, tl->t);
458 40
                                VSB_destroy(&tl->fb);
459 40
                                return;
460
                        }
461 1440
                        vcc_Redef(tl, "Address", &t_did, t_field);
462 1440
                        ERRCHK(tl);
463 1400
                        ExpectErr(tl, CSTR);
464 1400
                        assert(tl->t->dec != NULL);
465 1400
                        t_path = tl->t;
466 1400
                        vcc_NextToken(tl);
467 1400
                        SkipToken(tl, ';');
468 5000
                } else if (vcc_IdIs(t_field, "host_header")) {
469 160
                        ExpectErr(tl, CSTR);
470 160
                        assert(tl->t->dec != NULL);
471 160
                        t_hosthdr = tl->t;
472 160
                        vcc_NextToken(tl);
473 160
                        SkipToken(tl, ';');
474 3600
                } else if (vcc_IdIs(t_field, "connect_timeout")) {
475 120
                        Fb(tl, 0, "\t.connect_timeout = ");
476 120
                        vcc_Duration(tl, &connect_timeout);
477 120
                        ERRCHK(tl);
478 120
                        Fb(tl, 0, "%g,\n", connect_timeout);
479 120
                        SkipToken(tl, ';');
480 3440
                } else if (vcc_IdIs(t_field, "first_byte_timeout")) {
481 120
                        Fb(tl, 0, "\t.first_byte_timeout = ");
482 120
                        vcc_Duration(tl, &first_byte_timeout);
483 120
                        ERRCHK(tl);
484 120
                        Fb(tl, 0, "%g,\n", first_byte_timeout);
485 120
                        SkipToken(tl, ';');
486 3320
                } else if (vcc_IdIs(t_field, "between_bytes_timeout")) {
487 40
                        Fb(tl, 0, "\t.between_bytes_timeout = ");
488 40
                        vcc_Duration(tl, &between_bytes_timeout);
489 40
                        ERRCHK(tl);
490 40
                        Fb(tl, 0, "%g,\n", between_bytes_timeout);
491 40
                        SkipToken(tl, ';');
492 3200
                } else if (vcc_IdIs(t_field, "max_connections")) {
493 440
                        u = vcc_UintVal(tl);
494 440
                        ERRCHK(tl);
495 440
                        SkipToken(tl, ';');
496 440
                        Fb(tl, 0, "\t.max_connections = %u,\n", u);
497 3160
                } else if (vcc_IdIs(t_field, "proxy_header")) {
498 240
                        t_val = tl->t;
499 240
                        u = vcc_UintVal(tl);
500 240
                        ERRCHK(tl);
501 240
                        if (u != 1 && u != 2) {
502 0
                                VSB_cat(tl->sb,
503
                                    ".proxy_header must be 1 or 2\n");
504 0
                                vcc_ErrWhere(tl, t_val);
505 0
                                VSB_destroy(&tl->fb);
506 0
                                return;
507
                        }
508 240
                        SkipToken(tl, ';');
509 240
                        Fb(tl, 0, "\t.proxy_header = %u,\n", u);
510 2720
                } else if (vcc_IdIs(t_field, "probe") && tl->t->tok == '{') {
511 1040
                        vcc_ParseProbeSpec(tl, NULL, &p);
512 1040
                        Fb(tl, 0, "\t.probe = %s,\n", p);
513 1040
                        free(p);
514 1040
                        ERRCHK(tl);
515 2080
                } else if (vcc_IdIs(t_field, "probe") && tl->t->tok == ID) {
516 440
                        t_probe = tl->t;
517 440
                        pb = VCC_SymbolGet(tl, SYM_MAIN, SYM_PROBE,
518
                            SYMTAB_EXISTING, XREF_REF);
519 440
                        ERRCHK(tl);
520 400
                        AN(pb);
521 400
                        if (pb->type == DEFAULT) {
522 40
                                if (tl->default_probe == NULL) {
523 40
                                        VSB_cat(tl->sb,
524
                                            "No default probe defined\n");
525 40
                                        vcc_ErrToken(tl, t_probe);
526 40
                                        VSB_cat(tl->sb, " at\n");
527 40
                                        vcc_ErrWhere(tl, t_probe);
528 40
                                }
529 40
                                pb = PROBE->default_sym;
530 40
                        }
531 400
                        ERRCHK(tl);
532 360
                        Fb(tl, 0, "\t.probe = %s,\n", pb->rname);
533 360
                        SkipToken(tl, ';');
534 1360
                } else if (vcc_IdIs(t_field, "probe")) {
535 40
                        VSB_cat(tl->sb, "Expected '{' or name of probe, got ");
536 40
                        vcc_ErrToken(tl, tl->t);
537 40
                        VSB_cat(tl->sb, " at\n");
538 40
                        vcc_ErrWhere(tl, tl->t);
539 40
                        VSB_destroy(&tl->fb);
540 40
                        return;
541 960
                } else if (vcc_IdIs(t_field, "preamble")) {
542 40
                        ExpectErr(tl, CBLOB);
543 40
                        t_preamble = tl->t;
544 40
                        vcc_NextToken(tl);
545 40
                        SkipToken(tl, ';');
546 960
                } else if (vcc_IdIs(t_field, "via")) {
547 400
                        via = VCC_SymbolGet(tl, SYM_MAIN, SYM_BACKEND,
548
                            SYMTAB_EXISTING, XREF_REF);
549 400
                        ERRCHK(tl);
550 400
                        AN(via);
551 400
                        AN(via->rname);
552
553 400
                        if (via->extra != NULL) {
554 40
                                AZ(strcmp(via->extra, "via"));
555 40
                                VSB_cat(tl->sb,
556
                                        "Cannot stack .via backends at\n");
557 40
                                vcc_ErrWhere(tl, tl->t);
558 40
                                VSB_destroy(&tl->fb);
559 40
                                return;
560
                        }
561
562 360
                        AN(sym);
563 360
                        AZ(sym->extra);
564 360
                        sym->extra = "via";
565 360
                        SkipToken(tl, ';');
566 880
                } else if (vcc_IdIs(t_field, "authority")) {
567 120
                        ExpectErr(tl, CSTR);
568 120
                        assert(tl->t->dec != NULL);
569 120
                        t_authority = tl->t;
570 120
                        vcc_NextToken(tl);
571 120
                        SkipToken(tl, ';');
572 520
                } else if (vcc_IdIs(t_field, "wait_timeout")) {
573 200
                        Fb(tl, 0, "\t.backend_wait_timeout = ");
574 200
                        vcc_Duration(tl, &backend_wait_timeout);
575 200
                        ERRCHK(tl);
576 200
                        Fb(tl, 0, "%g,\n", backend_wait_timeout);
577 200
                        SkipToken(tl, ';');
578 400
                } else if (vcc_IdIs(t_field, "wait_limit")) {
579 200
                        u = vcc_UintVal(tl);
580 200
                        ERRCHK(tl);
581 200
                        SkipToken(tl, ';');
582 200
                        Fb(tl, 0, "\t.backend_wait_limit = %u,\n", u);
583 200
                } else {
584 0
                        ErrInternal(tl);
585 0
                        VSB_destroy(&tl->fb);
586 0
                        return;
587
                }
588
589
        }
590
591 54760
        vcc_FieldsOk(tl, fs);
592 54760
        free(fs);
593 54760
        ERRCHK(tl);
594
595 54760
        if (isnan(connect_timeout))
596 54640
                Fb(tl, 0, "\t.connect_timeout = -1.0,\n");
597 54760
        if (isnan(first_byte_timeout))
598 54640
                Fb(tl, 0, "\t.first_byte_timeout = -1.0,\n");
599 54760
        if (isnan(between_bytes_timeout))
600 54720
                Fb(tl, 0, "\t.between_bytes_timeout = -1.0,\n");
601 54760
        if (isnan(backend_wait_timeout))
602 54560
                Fb(tl, 0, "\t.backend_wait_timeout = -1.0,\n");
603
604 54760
        ExpectErr(tl, '}');
605
606 54760
        if (t_host == NULL && t_path == NULL) {
607 40
                VSB_cat(tl->sb, "Expected .host or .path.\n");
608 40
                vcc_ErrWhere(tl, t_be);
609 40
                VSB_destroy(&tl->fb);
610 40
                return;
611
        }
612
613 54720
        if (via != NULL && t_path != NULL) {
614 40
                VSB_cat(tl->sb, "Cannot set both .via and .path.\n");
615 40
                vcc_ErrWhere(tl, t_be);
616 40
                return;
617
        }
618
619 54680
        if (via != NULL)
620 320
                AZ(via->extra);
621
622 54680
        vsb1 = VSB_new_auto();
623 54680
        AN(vsb1);
624 109360
        VSB_printf(vsb1,
625
            "\nstatic const struct vrt_endpoint vgc_dir_ep_%s = {\n",
626 54680
            vgcname);
627 54680
        VSB_cat(vsb1, "\t.magic = VRT_ENDPOINT_MAGIC,\n");
628
629 54680
        assert(t_host != NULL || t_path != NULL);
630 54680
        if (t_host != NULL)
631
                /* Check that the hostname makes sense */
632 53320
                Emit_Sockaddr(tl, vsb1, t_host, t_port);
633
        else
634
                /* Check that the path can be a legal UDS */
635 1360
                Emit_UDS_Path(tl, vsb1, t_path, "Backend path");
636 54680
        ERRCHK(tl);
637
638 54480
        if (t_preamble != NULL)
639 40
                VSB_printf(vsb1, "\t.preamble = %s,\n", t_preamble->dec);
640
641 54480
        VSB_cat(vsb1, "};\n");
642 54480
        AZ(VSB_finish(vsb1));
643 54480
        Fh(tl, 0, "%s", VSB_data(vsb1));
644 54480
        VSB_destroy(&vsb1);
645
646
        /* Emit the hosthdr field, fall back to .host if not specified */
647
        /* If .path is specified, set "0.0.0.0". */
648 54480
        Fb(tl, 0, "\t.hosthdr = ");
649 54480
        if (t_hosthdr != NULL)
650 160
                EncToken(tl->fb, t_hosthdr);
651 54320
        else if (t_host != NULL)
652 53160
                EncToken(tl->fb, t_host);
653
        else
654 1160
                Fb(tl, 0, "\"0.0.0.0\"");
655 54480
        Fb(tl, 0, ",\n");
656
657
        /*
658
         * Emit the authority field, falling back to hosthdr, then host.
659
         *
660
         * When authority is "", sending the TLV is disabled.
661
         *
662
         * Falling back to host may result in an IP address in authority,
663
         * which is an illegal SNI HostName (RFC 4366 ch. 3.1). But we
664
         * document the potential error, rather than try to find out
665
         * whether or not Emit_Sockaddr() had to look up a name.
666
         */
667 54480
        if (via != NULL) {
668 320
                AN(t_host);
669 320
                Fb(tl, 0, "\t.authority = ");
670 320
                if (t_authority != NULL)
671 120
                        EncToken(tl->fb, t_authority);
672 200
                else if (t_hosthdr != NULL)
673 40
                        EncToken(tl->fb, t_hosthdr);
674
                else
675 160
                        EncToken(tl->fb, t_host);
676 320
                Fb(tl, 0, ",\n");
677 320
        }
678
679
        /* Close the struct */
680 54480
        Fb(tl, 0, "};\n");
681
682 54480
        vcc_NextToken(tl);
683
684 54480
        AZ(VSB_finish(tl->fb));
685 54480
        Fh(tl, 0, "%s", VSB_data(tl->fb));
686 54480
        VSB_destroy(&tl->fb);
687
688 54480
        ifp = New_IniFin(tl);
689 108960
        VSB_printf(ifp->ini,
690
            "\t%s =\n\t    VRT_new_backend_clustered(ctx, vsc_cluster,\n"
691
            "\t\t&vgc_dir_priv_%s, %s);\n",
692 54480
            vgcname, vgcname, via ? via->rname : "NULL");
693 108960
        VSB_printf(ifp->ini,
694 54480
            "\tif (%s)\n\t\tVRT_StaticDirector(%s);", vgcname, vgcname);
695 54480
        VSB_printf(ifp->fin, "\t\tVRT_delete_backend(ctx, &%s);", vgcname);
696 65000
}
697
698
/*--------------------------------------------------------------------
699
 * Parse directors and backends
700
 */
701
702
void
703 65200
vcc_ParseBackend(struct vcc *tl)
704
{
705
        struct token *t_first, *t_be;
706
        struct symbol *sym;
707
        const char *dn;
708
709 65200
        tl->ndirector++;
710 65200
        t_first = tl->t;
711 65200
        SkipToken(tl, ID);              /* ID: backend */
712
713 65200
        vcc_ExpectVid(tl, "backend");   /* ID: name */
714 65200
        ERRCHK(tl);
715
716 65160
        t_be = tl->t;
717
718 65160
        sym = VCC_HandleSymbol(tl, BACKEND);
719 65160
        ERRCHK(tl);
720 65040
        AN(sym);
721
722 65040
        if (sym->type == DEFAULT) {
723 2800
                if (tl->first_director != NULL) {
724 160
                        tl->first_director->noref = 0;
725 160
                        tl->first_director = NULL;
726 160
                        tl->default_director = NULL;
727 160
                }
728 2800
                if (tl->default_director != NULL) {
729 40
                        VSB_cat(tl->sb,
730
                            "Only one default director possible.\n");
731 40
                        vcc_ErrWhere(tl, t_first);
732 40
                        return;
733
                }
734 2760
                dn = "vgc_backend_default";
735 2760
                tl->default_director = dn;
736 2760
        } else {
737 62240
                dn = sym->rname;
738 62240
                if (tl->default_director == NULL) {
739 51720
                        tl->first_director = sym;
740 51720
                        tl->default_director = dn;
741 51720
                        sym->noref = 1;
742 51720
                }
743
        }
744
745 65000
        Fh(tl, 0, "\nstatic VCL_BACKEND %s;\n", dn);
746 65000
        vcc_ParseHostDef(tl, sym, t_be, dn);
747 65000
        if (tl->err) {
748 2080
                VSB_printf(tl->sb,
749 1040
                    "\nIn %.*s specification starting at:\n", PF(t_first));
750 1040
                vcc_ErrWhere(tl, t_first);
751 1040
                return;
752
        }
753 65200
}
754
755
void
756 119800
vcc_Backend_Init(struct vcc *tl)
757
{
758
        struct inifin *ifp;
759
760 119800
        Fh(tl, 0, "\nstatic struct vsmw_cluster *vsc_cluster;\n");
761 119800
        ifp = New_IniFin(tl);
762 119800
        VSB_cat(ifp->ini, "\tvsc_cluster = VRT_VSM_Cluster_New(ctx,\n"
763
            "\t    ndirector * VRT_backend_vsm_need(ctx));\n");
764 119800
        VSB_cat(ifp->ini, "\tif (vsc_cluster == 0)\n\t\treturn(1);");
765 119800
        VSB_cat(ifp->fin, "\t\tVRT_VSM_Cluster_Destroy(ctx, &vsc_cluster);");
766 119800
}