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