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
const char *
43 40
vcc_default_probe(struct vcc *tl)
44
{
45
46 40
        if (tl->default_probe != NULL)
47 0
                return (tl->default_probe);
48 40
        VSB_cat(tl->sb, "No default probe defined\n");
49 40
        vcc_ErrToken(tl, tl->t);
50 40
        VSB_cat(tl->sb, " at\n");
51 40
        vcc_ErrWhere(tl, tl->t);
52 40
        return ("");
53 40
}
54
55
/*--------------------------------------------------------------------
56
 * Struct sockaddr is not really designed to be a compile time
57
 * initialized data structure, so we encode it as a byte-string
58
 * and put it in an official sockaddr when we load the VCL.
59
 */
60
61
static void
62 52680
Emit_Sockaddr(struct vcc *tl, struct vsb *vsb1, const struct token *t_host,
63
    const struct token *t_port)
64
{
65
        const char *ipv4, *ipv4a, *ipv6, *ipv6a, *pa;
66
        char buf[BUFSIZ];
67
68 52680
        AN(t_host->dec);
69
70 52680
        if (t_port != NULL)
71 39880
                bprintf(buf, "%s %s", t_host->dec, t_port->dec);
72
        else
73 12800
                bprintf(buf, "%s", t_host->dec);
74 105360
        Resolve_Sockaddr(tl, buf, "80",
75 52680
            &ipv4, &ipv4a, &ipv6, &ipv6a, &pa, 2, t_host, "Backend host");
76 52680
        ERRCHK(tl);
77 52600
        if (ipv4 != NULL) {
78 104720
                VSB_printf(vsb1,
79
                    "\t.ipv4 = (const struct suckaddr *)%s,\n",
80 52360
                    ipv4);
81 52360
        }
82 52600
        if (ipv6 != NULL) {
83 560
                VSB_printf(vsb1,
84
                    "\t.ipv6 = (const struct suckaddr *)%s,\n",
85 280
                    ipv6);
86 280
        }
87 52600
        VSB_cat(vsb1, "\t.uds_path = (void *) 0,\n");
88 52680
}
89
90
/*
91
 * For UDS, we do not create a VSA. We run the VUS_resolver() checks and, if
92
 * it's a path, can be accessed, and is a socket. If so, just emit the path
93
 * field and set the IP suckaddrs to NULL.
94
 */
95
96
static int
97 1280
uds_resolved(void *priv, const struct sockaddr_un *uds)
98
{
99 1280
        (void) priv;
100 1280
        (void) uds;
101 1280
        return (42);
102
}
103
104
static void
105 1240
emit_path(struct vsb *vsb1, char *path)
106
{
107 1240
        VSB_printf(vsb1, "\t.uds_path = \"%s\",\n", path);
108 1240
        VSB_cat(vsb1, "\t.ipv4 = (void *) 0,\n");
109 1240
        VSB_cat(vsb1, "\t.ipv6 = (void *) 0,\n");
110 1240
}
111
112
static void
113 1360
Emit_UDS_Path(struct vcc *tl, struct vsb *vsb1,
114
    const struct token *t_path, const char *errid)
115
{
116
        struct stat st;
117
        const char *vus_err;
118
119 1360
        AN(t_path);
120 1360
        AN(t_path->dec);
121
122 1360
        if (! VUS_is(t_path->dec)) {
123 80
                VSB_printf(tl->sb,
124
                           "%s: Must be a valid path or abstract socket:\n",
125 40
                           errid);
126 40
                vcc_ErrWhere(tl, t_path);
127 40
                return;
128
        }
129 1320
        if (VUS_resolver(t_path->dec, uds_resolved, NULL, &vus_err) != 42) {
130 40
                VSB_printf(tl->sb, "%s: %s\n", errid, vus_err);
131 40
                vcc_ErrWhere(tl, t_path);
132 40
                return;
133
        }
134 1280
        if (*t_path->dec == '@') {
135 0
                emit_path(vsb1, t_path->dec);
136 0
                return;
137
        }
138 1280
        assert(*t_path->dec == '/');
139 1280
        errno = 0;
140 1280
        if (stat(t_path->dec, &st) != 0) {
141 40
                int err = errno;
142 80
                VSB_printf(tl->sb, "%s: Cannot stat: %s\n", errid,
143 40
                           strerror(errno));
144 40
                vcc_ErrWhere(tl, t_path);
145 40
                if (err == ENOENT || err == EACCES)
146 40
                        vcc_Warn(tl);
147
                else
148 0
                        return;
149 1280
        } else if (!S_ISSOCK(st.st_mode)) {
150 40
                VSB_printf(tl->sb, "%s: Not a socket:\n", errid);
151 40
                vcc_ErrWhere(tl, t_path);
152 40
                return;
153
        }
154 1240
        emit_path(vsb1, t_path->dec);
155 1360
}
156
157
/*--------------------------------------------------------------------
158
 * Disallow mutually exclusive field definitions
159
 */
160
161
static void
162 55360
vcc_Redef(struct vcc *tl, const char *redef, const struct token **t_did,
163
    const struct token *t_field)
164
{
165 55360
        if (*t_did != NULL) {
166 120
                VSB_printf(tl->sb, "%s redefinition at:\n", redef);
167 120
                vcc_ErrWhere(tl, t_field);
168 120
                VSB_cat(tl->sb, "Previous definition:\n");
169 120
                vcc_ErrWhere(tl, *t_did);
170 120
                return;
171
        }
172 55240
        *t_did = t_field;
173 55360
}
174
175
/*--------------------------------------------------------------------
176
 * Parse a backend probe specification
177
 */
178
179
static void
180 1800
vcc_ParseProbeSpec(struct vcc *tl, const struct symbol *sym, char **namep)
181
{
182
        struct fld_spec *fs;
183
        const struct token *t_field;
184 1800
        const struct token *t_did = NULL, *t_window = NULL, *t_threshold = NULL;
185 1800
        struct token *t_initial = NULL;
186
        unsigned window, threshold, initial, status, exp_close;
187
        char buf[32];
188
        const char *name;
189
        double t;
190
191 1800
        fs = vcc_FldSpec(tl,
192
            "?url",
193
            "?request",
194
            "?expected_response",
195
            "?timeout",
196
            "?interval",
197
            "?window",
198
            "?threshold",
199
            "?initial",
200
            "?expect_close",
201
            NULL);
202
203 1800
        SkipToken(tl, '{');
204
205 1800
        if (sym != NULL) {
206 440
                name = sym->rname;
207 440
        } else {
208 1360
                bprintf(buf, "vgc_probe__%d", tl->nprobe++);
209 1360
                name = buf;
210
        }
211 1800
        Fh(tl, 0, "static const struct vrt_backend_probe %s[] = {{\n", name);
212 1800
        Fh(tl, 0, "\t.magic = VRT_BACKEND_PROBE_MAGIC,\n");
213 1800
        if (namep != NULL)
214 1360
                *namep = TlDup(tl, name);
215
216 1800
        window = 0;
217 1800
        threshold = 0;
218 1800
        initial = 0;
219 1800
        status = 0;
220 1800
        exp_close = 1;
221 5800
        while (tl->t->tok != '}') {
222
223 4240
                vcc_IsField(tl, &t_field, fs);
224 4240
                ERRCHK(tl);
225 4240
                if (vcc_IdIs(t_field, "url")) {
226 440
                        vcc_Redef(tl, "Probe request", &t_did, t_field);
227 440
                        ERRCHK(tl);
228 400
                        ExpectErr(tl, CSTR);
229 400
                        Fh(tl, 0, "\t.url = ");
230 400
                        EncToken(tl->fh, tl->t);
231 400
                        Fh(tl, 0, ",\n");
232 400
                        vcc_NextToken(tl);
233 4200
                } else if (vcc_IdIs(t_field, "request")) {
234 200
                        vcc_Redef(tl, "Probe request", &t_did, t_field);
235 200
                        ERRCHK(tl);
236 160
                        ExpectErr(tl, CSTR);
237 160
                        Fh(tl, 0, "\t.request =\n");
238 640
                        while (tl->t->tok == CSTR) {
239 480
                                Fh(tl, 0, "\t\t");
240 480
                                EncToken(tl->fh, tl->t);
241 480
                                Fh(tl, 0, " \"\\r\\n\"\n");
242 480
                                vcc_NextToken(tl);
243
                        }
244 160
                        Fh(tl, 0, "\t\t\"\\r\\n\",\n");
245 3760
                } else if (vcc_IdIs(t_field, "timeout")) {
246 360
                        Fh(tl, 0, "\t.timeout = ");
247 360
                        vcc_Duration(tl, &t);
248 360
                        ERRCHK(tl);
249 320
                        Fh(tl, 0, "%g,\n", t);
250 3560
                } else if (vcc_IdIs(t_field, "interval")) {
251 960
                        Fh(tl, 0, "\t.interval = ");
252 960
                        vcc_Duration(tl, &t);
253 960
                        ERRCHK(tl);
254 960
                        Fh(tl, 0, "%g,\n", t);
255 3240
                } else if (vcc_IdIs(t_field, "window")) {
256 720
                        t_window = tl->t;
257 720
                        window = vcc_UintVal(tl);
258 720
                        ERRCHK(tl);
259 2280
                } else if (vcc_IdIs(t_field, "initial")) {
260 520
                        t_initial = tl->t;
261 520
                        initial = vcc_UintVal(tl);
262 520
                        ERRCHK(tl);
263 1560
                } else if (vcc_IdIs(t_field, "expected_response")) {
264 80
                        status = vcc_UintVal(tl);
265 80
                        if (status < 100 || status > 999) {
266 40
                                VSB_cat(tl->sb,
267
                                    "Must specify .expected_response with "
268
                                    "exactly three digits "
269
                                    "(100 <= x <= 999)\n");
270 40
                                vcc_ErrWhere(tl, tl->t);
271 40
                                return;
272
                        }
273 40
                        ERRCHK(tl);
274 1000
                } else if (vcc_IdIs(t_field, "threshold")) {
275 800
                        t_threshold = tl->t;
276 800
                        threshold = vcc_UintVal(tl);
277 800
                        ERRCHK(tl);
278 960
                } else if (vcc_IdIs(t_field, "expect_close")) {
279 160
                        exp_close = vcc_BoolVal(tl);
280 160
                        ERRCHK(tl);
281 80
                } else {
282 0
                        vcc_ErrToken(tl, t_field);
283 0
                        vcc_ErrWhere(tl, t_field);
284 0
                        ErrInternal(tl);
285 0
                        return;
286
                }
287
288 4000
                SkipToken(tl, ';');
289
        }
290 1560
        free(fs);
291
292 1560
        if (t_threshold != NULL || t_window != NULL) {
293 840
                if (t_threshold == NULL && t_window != NULL) {
294 40
                        VSB_cat(tl->sb,
295
                            "Must specify .threshold with .window\n");
296 40
                        vcc_ErrWhere(tl, t_window);
297 40
                        return;
298 800
                } else if (t_threshold != NULL && t_window == NULL) {
299 120
                        if (threshold > 64) {
300 40
                                VSB_cat(tl->sb,
301
                                    "Threshold must be 64 or less.\n");
302 40
                                vcc_ErrWhere(tl, t_threshold);
303 40
                                return;
304
                        }
305 80
                        window = threshold + 1;
306 760
                } else if (window > 64) {
307 40
                        AN(t_window);
308 40
                        VSB_cat(tl->sb, "Window must be 64 or less.\n");
309 40
                        vcc_ErrWhere(tl, t_window);
310 40
                        return;
311
                }
312 720
                if (threshold > window ) {
313 40
                        VSB_cat(tl->sb,
314
                            "Threshold can not be greater than window.\n");
315 40
                        AN(t_threshold);
316 40
                        vcc_ErrWhere(tl, t_threshold);
317 40
                        AN(t_window);
318 40
                        vcc_ErrWhere(tl, t_window);
319 40
                }
320 720
                Fh(tl, 0, "\t.window = %u,\n", window);
321 720
                Fh(tl, 0, "\t.threshold = %u,\n", threshold);
322 720
        }
323 1440
        if (t_initial != NULL)
324 520
                Fh(tl, 0, "\t.initial = %u,\n", initial);
325
        else
326 920
                Fh(tl, 0, "\t.initial = ~0U,\n");
327 1440
        if (status > 0)
328 40
                Fh(tl, 0, "\t.exp_status = %u,\n", status);
329 1440
        Fh(tl, 0, "\t.exp_close = %u,\n", exp_close);
330 1440
        Fh(tl, 0, "}};\n");
331 1440
        SkipToken(tl, '}');
332 1800
}
333
334
/*--------------------------------------------------------------------
335
 * Parse and emit a probe definition
336
 */
337
338
void
339 800
vcc_ParseProbe(struct vcc *tl)
340
{
341
        struct symbol *sym;
342
        char *p;
343
344 800
        vcc_NextToken(tl);                      /* ID: probe */
345
346 800
        vcc_ExpectVid(tl, "backend probe");     /* ID: name */
347 800
        ERRCHK(tl);
348 800
        if (vcc_IdIs(tl->t, "default")) {
349 320
                vcc_NextToken(tl);
350 320
                vcc_ParseProbeSpec(tl, NULL, &p);
351 320
                tl->default_probe = p;
352 320
        } else {
353 480
                sym = VCC_HandleSymbol(tl, PROBE);
354 480
                ERRCHK(tl);
355 440
                AN(sym);
356 440
                vcc_ParseProbeSpec(tl, sym, NULL);
357
        }
358 800
}
359
360
/*--------------------------------------------------------------------
361
 * Parse and emit a backend host definition
362
 *
363
 * The struct vrt_backend is emitted to Fh().
364
 */
365
366
static void
367 64320
vcc_ParseHostDef(struct vcc *tl, struct symbol *sym,
368
    const struct token *t_be, const char *vgcname)
369
{
370
        const struct token *t_field;
371
        const struct token *t_val;
372 64320
        const struct token *t_host = NULL;
373 64320
        const struct token *t_port = NULL;
374 64320
        const struct token *t_path = NULL;
375 64320
        const struct token *t_hosthdr = NULL;
376 64320
        const struct token *t_authority = NULL;
377 64320
        const struct token *t_did = NULL;
378 64320
        const struct token *t_preamble = NULL;
379
        struct symbol *pb;
380
        struct fld_spec *fs;
381
        struct inifin *ifp;
382
        struct vsb *vsb1;
383 64320
        struct symbol *via = NULL;
384 64320
        vtim_dur connect_timeout = NAN;
385 64320
        vtim_dur first_byte_timeout = NAN;
386 64320
        vtim_dur between_bytes_timeout = NAN;
387 64320
        vtim_dur backend_wait_timeout = NAN;
388
        char *p;
389
        unsigned u;
390
391 68480
        if (tl->t->tok == ID &&
392 9440
            (vcc_IdIs(tl->t, "none") || vcc_IdIs(tl->t, "None"))) {
393 9440
                vcc_NextToken(tl);
394 9440
                SkipToken(tl, ';');
395 9440
                ifp = New_IniFin(tl);
396 9440
                VSB_printf(ifp->ini, "\t(void)%s;", vgcname);
397 9440
                VSB_printf(ifp->fin, "\t\t(void)%s;", vgcname);
398 9440
                return;
399
        }
400
401 54880
        SkipToken(tl, '{');
402
403
        /* Check for old syntax */
404 54880
        if (tl->t->tok == ID && vcc_IdIs(tl->t, "set")) {
405 40
                VSB_cat(tl->sb,
406
                    "NB: Backend Syntax has changed:\n"
407
                    "Remove \"set\" and \"backend\" in front"
408
                    " of backend fields.\n" );
409 40
                vcc_ErrToken(tl, tl->t);
410 40
                VSB_cat(tl->sb, " at ");
411 40
                vcc_ErrWhere(tl, tl->t);
412 40
                return;
413
        }
414
415 54840
        fs = vcc_FldSpec(tl,
416
            "?host",
417
            "?port",
418
            "?path",
419
            "?host_header",
420
            "?connect_timeout",
421
            "?first_byte_timeout",
422
            "?between_bytes_timeout",
423
            "?probe",
424
            "?max_connections",
425
            "?proxy_header",
426
            "?preamble",
427
            "?via",
428
            "?authority",
429
            "?wait_timeout",
430
            "?wait_limit",
431
            NULL);
432
433 54840
        tl->fb = VSB_new_auto();
434 54840
        AN(tl->fb);
435
436 109680
        Fb(tl, 0, "\nstatic const struct vrt_backend vgc_dir_priv_%s = {\n",
437 54840
            vgcname);
438
439 54840
        Fb(tl, 0, "\t.magic = VRT_BACKEND_MAGIC,\n");
440 54840
        Fb(tl, 0, "\t.endpoint = &vgc_dir_ep_%s,\n", vgcname);
441 54840
        Fb(tl, 0, "\t.vcl_name = \"%.*s", PF(t_be));
442 54840
        Fb(tl, 0, "\",\n");
443
444 152200
        while (tl->t->tok != '}') {
445
446 98080
                vcc_IsField(tl, &t_field, fs);
447 98080
                ERRCHK(tl);
448 98000
                if (vcc_IdIs(t_field, "host")) {
449 53280
                        vcc_Redef(tl, "Address", &t_did, t_field);
450 53280
                        ERRCHK(tl);
451 53280
                        ExpectErr(tl, CSTR);
452 53280
                        assert(tl->t->dec != NULL);
453 53280
                        t_host = tl->t;
454 53280
                        vcc_NextToken(tl);
455 53280
                        SkipToken(tl, ';');
456 98000
                } else if (vcc_IdIs(t_field, "port")) {
457 39960
                        ExpectErr(tl, CSTR);
458 39960
                        assert(tl->t->dec != NULL);
459 39960
                        t_port = tl->t;
460 39960
                        vcc_NextToken(tl);
461 39960
                        SkipToken(tl, ';');
462 44720
                } else if (vcc_IdIs(t_field, "path")) {
463 1480
                        if (tl->syntax < VCL_41) {
464 40
                                VSB_cat(tl->sb,
465
                                    "Unix socket backends only supported"
466
                                    " in VCL4.1 and higher.\n");
467 40
                                vcc_ErrToken(tl, tl->t);
468 40
                                VSB_cat(tl->sb, " at ");
469 40
                                vcc_ErrWhere(tl, tl->t);
470 40
                                VSB_destroy(&tl->fb);
471 40
                                return;
472
                        }
473 1440
                        vcc_Redef(tl, "Address", &t_did, t_field);
474 1440
                        ERRCHK(tl);
475 1400
                        ExpectErr(tl, CSTR);
476 1400
                        assert(tl->t->dec != NULL);
477 1400
                        t_path = tl->t;
478 1400
                        vcc_NextToken(tl);
479 1400
                        SkipToken(tl, ';');
480 4680
                } else if (vcc_IdIs(t_field, "host_header")) {
481 160
                        ExpectErr(tl, CSTR);
482 160
                        assert(tl->t->dec != NULL);
483 160
                        t_hosthdr = tl->t;
484 160
                        vcc_NextToken(tl);
485 160
                        SkipToken(tl, ';');
486 3280
                } else if (vcc_IdIs(t_field, "connect_timeout")) {
487 120
                        Fb(tl, 0, "\t.connect_timeout = ");
488 120
                        vcc_Duration(tl, &connect_timeout);
489 120
                        ERRCHK(tl);
490 120
                        Fb(tl, 0, "%g,\n", connect_timeout);
491 120
                        SkipToken(tl, ';');
492 3120
                } else if (vcc_IdIs(t_field, "first_byte_timeout")) {
493 120
                        Fb(tl, 0, "\t.first_byte_timeout = ");
494 120
                        vcc_Duration(tl, &first_byte_timeout);
495 120
                        ERRCHK(tl);
496 120
                        Fb(tl, 0, "%g,\n", first_byte_timeout);
497 120
                        SkipToken(tl, ';');
498 3000
                } else if (vcc_IdIs(t_field, "between_bytes_timeout")) {
499 40
                        Fb(tl, 0, "\t.between_bytes_timeout = ");
500 40
                        vcc_Duration(tl, &between_bytes_timeout);
501 40
                        ERRCHK(tl);
502 40
                        Fb(tl, 0, "%g,\n", between_bytes_timeout);
503 40
                        SkipToken(tl, ';');
504 2880
                } else if (vcc_IdIs(t_field, "max_connections")) {
505 320
                        u = vcc_UintVal(tl);
506 320
                        ERRCHK(tl);
507 320
                        SkipToken(tl, ';');
508 320
                        Fb(tl, 0, "\t.max_connections = %u,\n", u);
509 2840
                } else if (vcc_IdIs(t_field, "proxy_header")) {
510 240
                        t_val = tl->t;
511 240
                        u = vcc_UintVal(tl);
512 240
                        ERRCHK(tl);
513 240
                        if (u != 1 && u != 2) {
514 0
                                VSB_cat(tl->sb,
515
                                    ".proxy_header must be 1 or 2\n");
516 0
                                vcc_ErrWhere(tl, t_val);
517 0
                                VSB_destroy(&tl->fb);
518 0
                                return;
519
                        }
520 240
                        SkipToken(tl, ';');
521 240
                        Fb(tl, 0, "\t.proxy_header = %u,\n", u);
522 2520
                } else if (vcc_IdIs(t_field, "probe") && tl->t->tok == '{') {
523 1040
                        vcc_ParseProbeSpec(tl, NULL, &p);
524 1040
                        Fb(tl, 0, "\t.probe = %s,\n", p);
525 1040
                        free(p);
526 1040
                        ERRCHK(tl);
527 1880
                } else if (vcc_IdIs(t_field, "probe") && tl->t->tok == ID) {
528 440
                        if (vcc_IdIs(tl->t, "default")) {
529 40
                                vcc_NextToken(tl);
530 40
                                (void)vcc_default_probe(tl);
531 40
                        } else {
532 400
                                pb = VCC_SymbolGet(tl, SYM_MAIN, SYM_PROBE,
533
                                    SYMTAB_EXISTING, XREF_REF);
534 400
                                ERRCHK(tl);
535 360
                                AN(pb);
536 360
                                Fb(tl, 0, "\t.probe = %s,\n", pb->rname);
537
                        }
538 400
                        SkipToken(tl, ';');
539 1160
                } else if (vcc_IdIs(t_field, "probe")) {
540 40
                        VSB_cat(tl->sb, "Expected '{' or name of probe, got ");
541 40
                        vcc_ErrToken(tl, tl->t);
542 40
                        VSB_cat(tl->sb, " at\n");
543 40
                        vcc_ErrWhere(tl, tl->t);
544 40
                        VSB_destroy(&tl->fb);
545 40
                        return;
546 760
                } else if (vcc_IdIs(t_field, "preamble")) {
547 40
                        ExpectErr(tl, CBLOB);
548 40
                        t_preamble = tl->t;
549 40
                        vcc_NextToken(tl);
550 40
                        SkipToken(tl, ';');
551 760
                } else if (vcc_IdIs(t_field, "via")) {
552 360
                        via = VCC_SymbolGet(tl, SYM_MAIN, SYM_BACKEND,
553
                            SYMTAB_EXISTING, XREF_REF);
554 360
                        ERRCHK(tl);
555 360
                        AN(via);
556 360
                        AN(via->rname);
557
558 360
                        if (via->extra != NULL) {
559 40
                                AZ(strcmp(via->extra, "via"));
560 40
                                VSB_cat(tl->sb,
561
                                        "Can not stack .via backends at\n");
562 40
                                vcc_ErrWhere(tl, tl->t);
563 40
                                VSB_destroy(&tl->fb);
564 40
                                return;
565
                        }
566
567 320
                        AN(sym);
568 320
                        AZ(sym->extra);
569 320
                        sym->extra = "via";
570 320
                        SkipToken(tl, ';');
571 680
                } else if (vcc_IdIs(t_field, "authority")) {
572 120
                        ExpectErr(tl, CSTR);
573 120
                        assert(tl->t->dec != NULL);
574 120
                        t_authority = tl->t;
575 120
                        vcc_NextToken(tl);
576 120
                        SkipToken(tl, ';');
577 360
                } else if (vcc_IdIs(t_field, "wait_timeout")) {
578 120
                        Fb(tl, 0, "\t.backend_wait_timeout = ");
579 120
                        vcc_Duration(tl, &backend_wait_timeout);
580 120
                        ERRCHK(tl);
581 120
                        Fb(tl, 0, "%g,\n", backend_wait_timeout);
582 120
                        SkipToken(tl, ';');
583 240
                } else if (vcc_IdIs(t_field, "wait_limit")) {
584 120
                        u = vcc_UintVal(tl);
585 120
                        ERRCHK(tl);
586 120
                        SkipToken(tl, ';');
587 120
                        Fb(tl, 0, "\t.backend_wait_limit = %u,\n", u);
588 120
                } else {
589 0
                        ErrInternal(tl);
590 0
                        VSB_destroy(&tl->fb);
591 0
                        return;
592
                }
593
594
        }
595
596 54120
        vcc_FieldsOk(tl, fs);
597 54120
        free(fs);
598 54120
        ERRCHK(tl);
599
600 54120
        if (isnan(connect_timeout))
601 54000
                Fb(tl, 0, "\t.connect_timeout = -1.0,\n");
602 54120
        if (isnan(first_byte_timeout))
603 54000
                Fb(tl, 0, "\t.first_byte_timeout = -1.0,\n");
604 54120
        if (isnan(between_bytes_timeout))
605 54080
                Fb(tl, 0, "\t.between_bytes_timeout = -1.0,\n");
606 54120
        if (isnan(backend_wait_timeout))
607 54000
                Fb(tl, 0, "\t.backend_wait_timeout = -1.0,\n");
608
609 54120
        ExpectErr(tl, '}');
610
611 54120
        if (t_host == NULL && t_path == NULL) {
612 40
                VSB_cat(tl->sb, "Expected .host or .path.\n");
613 40
                vcc_ErrWhere(tl, t_be);
614 40
                VSB_destroy(&tl->fb);
615 40
                return;
616
        }
617
618 54080
        if (via != NULL && t_path != NULL) {
619 40
                VSB_cat(tl->sb, "Cannot set both .via and .path.\n");
620 40
                vcc_ErrWhere(tl, t_be);
621 40
                return;
622
        }
623
624 54040
        if (via != NULL)
625 280
                AZ(via->extra);
626
627 54040
        vsb1 = VSB_new_auto();
628 54040
        AN(vsb1);
629 108080
        VSB_printf(vsb1,
630
            "\nstatic const struct vrt_endpoint vgc_dir_ep_%s = {\n",
631 54040
            vgcname);
632 54040
        VSB_cat(vsb1, "\t.magic = VRT_ENDPOINT_MAGIC,\n");
633
634 54040
        assert(t_host != NULL || t_path != NULL);
635 54040
        if (t_host != NULL)
636
                /* Check that the hostname makes sense */
637 52680
                Emit_Sockaddr(tl, vsb1, t_host, t_port);
638
        else
639
                /* Check that the path can be a legal UDS */
640 1360
                Emit_UDS_Path(tl, vsb1, t_path, "Backend path");
641 54040
        ERRCHK(tl);
642
643 53840
        if (t_preamble != NULL)
644 40
                VSB_printf(vsb1, "\t.preamble = %s,\n", t_preamble->dec);
645
646 53840
        VSB_cat(vsb1, "};\n");
647 53840
        AZ(VSB_finish(vsb1));
648 53840
        Fh(tl, 0, "%s", VSB_data(vsb1));
649 53840
        VSB_destroy(&vsb1);
650
651
        /* Emit the hosthdr field, fall back to .host if not specified */
652
        /* If .path is specified, set "0.0.0.0". */
653 53840
        Fb(tl, 0, "\t.hosthdr = ");
654 53840
        if (t_hosthdr != NULL)
655 160
                EncToken(tl->fb, t_hosthdr);
656 53680
        else if (t_host != NULL)
657 52520
                EncToken(tl->fb, t_host);
658
        else
659 1160
                Fb(tl, 0, "\"0.0.0.0\"");
660 53840
        Fb(tl, 0, ",\n");
661
662
        /*
663
         * Emit the authority field, falling back to hosthdr, then host.
664
         *
665
         * When authority is "", sending the TLV is disabled.
666
         *
667
         * Falling back to host may result in an IP address in authority,
668
         * which is an illegal SNI HostName (RFC 4366 ch. 3.1). But we
669
         * document the potential error, rather than try to find out
670
         * whether or not Emit_Sockaddr() had to look up a name.
671
         */
672 53840
        if (via != NULL) {
673 280
                AN(t_host);
674 280
                Fb(tl, 0, "\t.authority = ");
675 280
                if (t_authority != NULL)
676 120
                        EncToken(tl->fb, t_authority);
677 160
                else if (t_hosthdr != NULL)
678 40
                        EncToken(tl->fb, t_hosthdr);
679
                else
680 120
                        EncToken(tl->fb, t_host);
681 280
                Fb(tl, 0, ",\n");
682 280
        }
683
684
        /* Close the struct */
685 53840
        Fb(tl, 0, "};\n");
686
687 53840
        vcc_NextToken(tl);
688
689 53840
        AZ(VSB_finish(tl->fb));
690 53840
        Fh(tl, 0, "%s", VSB_data(tl->fb));
691 53840
        VSB_destroy(&tl->fb);
692
693 53840
        ifp = New_IniFin(tl);
694 107680
        VSB_printf(ifp->ini,
695
            "\t%s =\n\t    VRT_new_backend_clustered(ctx, vsc_cluster,\n"
696
            "\t\t&vgc_dir_priv_%s, %s);\n",
697 53840
            vgcname, vgcname, via ? via->rname : "NULL");
698 107680
        VSB_printf(ifp->ini,
699 53840
            "\tif (%s)\n\t\tVRT_StaticDirector(%s);", vgcname, vgcname);
700 53840
        VSB_printf(ifp->fin, "\t\tVRT_delete_backend(ctx, &%s);", vgcname);
701 64320
}
702
703
/*--------------------------------------------------------------------
704
 * Parse directors and backends
705
 */
706
707
void
708 64520
vcc_ParseBackend(struct vcc *tl)
709
{
710
        struct token *t_first, *t_be;
711 64520
        struct symbol *sym = NULL;
712
        const char *dn;
713
714 64520
        tl->ndirector++;
715 64520
        t_first = tl->t;
716 64520
        SkipToken(tl, ID);              /* ID: backend */
717
718 64520
        vcc_ExpectVid(tl, "backend");   /* ID: name */
719 64520
        ERRCHK(tl);
720
721 64480
        t_be = tl->t;
722 64480
        if (vcc_IdIs(tl->t, "default")) {
723 2680
                if (tl->first_director != NULL) {
724 120
                        tl->first_director->noref = 0;
725 120
                        tl->first_director = NULL;
726 120
                        tl->default_director = NULL;
727 120
                }
728 2680
                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 2640
                vcc_NextToken(tl);
735 2640
                dn = "vgc_backend_default";
736 2640
                tl->default_director = dn;
737 2640
        } else {
738 61800
                sym = VCC_HandleSymbol(tl, BACKEND);
739 61800
                ERRCHK(tl);
740 61680
                AN(sym);
741 61680
                dn = sym->rname;
742 61680
                if (tl->default_director == NULL) {
743 51200
                        tl->first_director = sym;
744 51200
                        tl->default_director = dn;
745 51200
                        sym->noref = 1;
746 51200
                }
747
        }
748 64320
        Fh(tl, 0, "\nstatic VCL_BACKEND %s;\n", dn);
749 64320
        vcc_ParseHostDef(tl, sym, t_be, dn);
750 64320
        if (tl->err) {
751 2080
                VSB_printf(tl->sb,
752 1040
                    "\nIn %.*s specification starting at:\n", PF(t_first));
753 1040
                vcc_ErrWhere(tl, t_first);
754 1040
                return;
755
        }
756 64520
}
757
758
void
759 118600
vcc_Backend_Init(struct vcc *tl)
760
{
761
        struct inifin *ifp;
762
763 118600
        Fh(tl, 0, "\nstatic struct vsmw_cluster *vsc_cluster;\n");
764 118600
        ifp = New_IniFin(tl);
765 118600
        VSB_cat(ifp->ini, "\tvsc_cluster = VRT_VSM_Cluster_New(ctx,\n"
766
            "\t    ndirector * VRT_backend_vsm_need(ctx));\n");
767 118600
        VSB_cat(ifp->ini, "\tif (vsc_cluster == 0)\n\t\treturn(1);");
768 118600
        VSB_cat(ifp->fin, "\t\tVRT_VSM_Cluster_Destroy(ctx, &vsc_cluster);");
769 118600
}