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