varnish-cache/lib/libvcc/vcc_utils.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
#include "config.h"
32
33
#include <math.h>
34
#include <string.h>
35
#include <stdlib.h>
36
#include <sys/socket.h>
37
#include <sys/types.h>
38
#include <unistd.h>
39
40
#include "vcc_compile.h"
41
42
#include "vre.h"
43
#include "vnum.h"
44
#include "vsa.h"
45
#include "vss.h"
46
#include "vtcp.h"
47
48
/*--------------------------------------------------------------------*/
49
50
static void
51 336880
vcc_cstrcat(struct vcc *tl, struct vsb *vsb)
52
{
53
        struct token *t1;
54
55 336880
        assert(tl->t->tok == CSTR);
56 336880
        VSB_cat(vsb, tl->t->dec);
57
58 336880
        t1 = vcc_PeekToken(tl);
59 336880
        AN(t1);
60
61 337040
        while (t1->tok == '+') {
62 200
                vcc_NextToken(tl);
63 200
                SkipToken(tl, '+');
64 200
                ExpectErr(tl, CSTR);
65 160
                VSB_cat(vsb, tl->t->dec);
66 160
                t1 = vcc_PeekToken(tl);
67 160
                AN(t1);
68
        }
69 336880
}
70
71
void
72 336880
vcc_regexp(struct vcc *tl, struct vsb *vgc_name)
73
{
74
        struct vsb *pattern;
75
        struct token *t0;
76
        char buf[BUFSIZ];
77
        vre_t *t;
78
        int error, erroroffset;
79
        struct inifin *ifp;
80
81 336880
        t0 = tl->t;
82 336880
        pattern = VSB_new_auto();
83 336880
        AN(pattern);
84 336880
        vcc_cstrcat(tl, pattern);
85 336880
        AZ(VSB_finish(pattern));
86
87 336880
        t = VRE_compile(VSB_data(pattern), 0, &error, &erroroffset, 0);
88 336880
        if (t == NULL) {
89 80
                VSB_cat(tl->sb, "Regexp compilation error:\n\n");
90 80
                AZ(VRE_error(tl->sb, error));
91 80
                VSB_cat(tl->sb, "\n\n");
92 80
                vcc_ErrWhere2(tl, t0, tl->t);
93 80
                VSB_destroy(&pattern);
94 80
                return;
95
        }
96 336800
        VRE_free(&t);
97 336800
        bprintf(buf, "VGC_re_%u", tl->unique++);
98 336800
        if (vgc_name)
99 336800
                VSB_cat(vgc_name, buf);
100
101 336800
        Fh(tl, 0, "static struct vre *%s;\n", buf);
102 336800
        ifp = New_IniFin(tl);
103 336800
        VSB_printf(ifp->ini, "\tVPI_re_init(&%s, ",buf);
104 336800
        VSB_quote(ifp->ini, VSB_data(pattern), -1, VSB_QUOTE_CSTR);
105 336800
        VSB_cat(ifp->ini, ");");
106 336800
        VSB_printf(ifp->fin, "\t\tVPI_re_fini(%s);", buf);
107 336800
        VSB_destroy(&pattern);
108 336880
}
109
110
/*
111
 * The IPv6 crew royally screwed up the entire idea behind
112
 * struct sockaddr, see libvarnish/vsa.c for blow-by-blow account.
113
 *
114
 * There is no sane or even remotely portable way to initialize
115
 * a sockaddr for random protocols at compile time.
116
 *
117
 * In our case it is slightly more tricky than that, because we don't
118
 * even want to #include the struct sockaddr* definitions.
119
 *
120
 * Instead we make sure the sockaddr is sane (for our values of
121
 * sane) and dump it as our own "struct suckaddr" type, in binary,
122
 * using the widest integer type, hoping that this will ensure sufficient
123
 * alignment.
124
 */
125
126
static void
127 54360
vcc_suckaddr(struct vcc *tl, const char *host, const struct suckaddr *vsa,
128
    const char **ip, const char **ip_ascii, const char **p_ascii)
129
{
130
        char a[VTCP_ADDRBUFSIZE];
131
        char p[VTCP_PORTBUFSIZE];
132 54360
        const int sz = sizeof(unsigned long long);
133 54360
        const unsigned n = (vsa_suckaddr_len + sz - 1) / sz;
134 54360
        unsigned long long b[n];
135
        unsigned len;
136
        char *q;
137
138 54360
        VTCP_name(vsa, a, sizeof a, p, sizeof p);
139 54360
        Fh(tl, 0, "\n/* \"%s\" -> %s */\n", host, a);
140 54360
        if (ip_ascii != NULL)
141 53280
                *ip_ascii = TlDup(tl, a);
142 54360
        if (p_ascii != NULL && *p_ascii == NULL)
143 53240
                *p_ascii = TlDup(tl, p);
144
145 54360
        Fh(tl, 0, "static const unsigned long long");
146 54360
        Fh(tl, 0, " suckaddr_%u[%d] = {\n", tl->unique, n);
147 54360
        memcpy(b, vsa, vsa_suckaddr_len);
148 271800
        for (len = 0; len < n; len++)
149 434880
                Fh(tl, 0, "%s    0x%0*llxULL",
150 217440
                    len ? ",\n" : "", sz * 2, b[len]);
151 54360
        Fh(tl, 0, "\n};\n");
152
153 54360
        q = TlAlloc(tl, 40);
154 54360
        AN(q);
155 54360
        assert(snprintf(q, 40, "(const void*)suckaddr_%u", tl->unique) < 40);
156 54360
        *ip = q;
157 54360
        tl->unique++;
158 54360
}
159
160
/*--------------------------------------------------------------------
161
 * This routine is a monster, but at least we only have one such monster.
162
 * Look up a IP number, and return IPv4/IPv6 address as VGC produced names
163
 * and optionally ascii strings.
164
 *
165
 * For IP compile time constants we only want one IP#, but it can be
166
 * IPv4 or IPv6.
167
 *
168
 * For backends, we accept up to one IPv4 and one IPv6.
169
 */
170
171
struct rss {
172
        unsigned                magic;
173
#define RSS_MAGIC               0x11e966ab
174
175
        const struct suckaddr   *vsa4;
176
        const struct suckaddr   *vsa6;
177
        struct vsb              *vsb;
178
        int                     retval;
179
        int                     wrong;
180
};
181
182
static int v_matchproto_(vss_resolved_f)
183 54440
rs_callback(void *priv, const struct suckaddr *vsa)
184
{
185
        struct rss *rss;
186
        int v;
187
        char a[VTCP_ADDRBUFSIZE];
188
        char p[VTCP_PORTBUFSIZE];
189
190 54440
        CAST_OBJ_NOTNULL(rss, priv, RSS_MAGIC);
191 54440
        assert(VSA_Sane(vsa));
192
193 54440
        v = VSA_Get_Proto(vsa);
194 54440
        assert(v != AF_UNIX);
195 54440
        VTCP_name(vsa, a, sizeof a, p, sizeof p);
196 54440
        VSB_printf(rss->vsb, "\t%s:%s\n", a, p);
197 54440
        if (v == AF_INET) {
198 53840
                if (rss->vsa4 == NULL)
199 53760
                        rss->vsa4 = VSA_Clone(vsa);
200 80
                else if (VSA_Compare(vsa, rss->vsa4))
201 80
                        rss->wrong++;
202 53840
                rss->retval++;
203 54440
        } else if (v == AF_INET6) {
204 600
                if (rss->vsa6 == NULL)
205 600
                        rss->vsa6 = VSA_Clone(vsa);
206 0
                else if (VSA_Compare(vsa, rss->vsa6))
207 0
                        rss->wrong++;
208 600
                rss->retval++;
209 600
        }
210 54440
        return (0);
211
}
212
213
void
214 54480
Resolve_Sockaddr(struct vcc *tl,
215
    const char *host,
216
    const char *def_port,
217
    const char **ipv4,
218
    const char **ipv4_ascii,
219
    const char **ipv6,
220
    const char **ipv6_ascii,
221
    const char **p_ascii,
222
    int maxips,
223
    const struct token *t_err,
224
    const char *errid)
225
{
226
        int error;
227
        struct rss rss[1];
228
        const char *err;
229
230 54480
        *ipv4 = NULL;
231 54480
        *ipv6 = NULL;
232 54480
        if (p_ascii != NULL)
233 53320
                *p_ascii = NULL;
234
235 54480
        INIT_OBJ(rss, RSS_MAGIC);
236 54480
        rss->vsb = VSB_new_auto();
237 54480
        AN(rss->vsb);
238
239 54480
        error = VSS_resolver(host, def_port, rs_callback, rss, &err);
240 54480
        AZ(VSB_finish(rss->vsb));
241 54480
        if (err != NULL) {
242 320
                VSB_printf(tl->sb,
243
                    "%s '%.*s' could not be resolved to an IP address:\n"
244
                    "\t%s\n"
245
                    "(Sorry if that error message is gibberish.)\n",
246 160
                    errid, PF(t_err), err);
247 160
                vcc_ErrWhere(tl, t_err);
248 160
                if (rss->vsa4 != NULL)
249 0
                        VSA_free(&rss->vsa4);
250 160
                if (rss->vsa6 != NULL)
251 0
                        VSA_free(&rss->vsa6);
252 160
                VSB_destroy(&rss->vsb);
253 160
                ZERO_OBJ(rss, sizeof rss);
254 160
                return;
255
        }
256 54320
        AZ(error);
257 54320
        if (rss->vsa4 != NULL) {
258 53760
                vcc_suckaddr(tl, host, rss->vsa4, ipv4, ipv4_ascii, p_ascii);
259 53760
                VSA_free(&rss->vsa4);
260 53760
        }
261 54320
        if (rss->vsa6 != NULL) {
262 600
                vcc_suckaddr(tl, host, rss->vsa6, ipv6, ipv6_ascii, p_ascii);
263 600
                VSA_free(&rss->vsa6);
264 600
        }
265 54320
        if (rss->retval == 0) {
266 0
                VSB_printf(tl->sb,
267
                    "%s '%.*s': resolves to "
268
                    "neither IPv4 nor IPv6 addresses.\n",
269 0
                    errid, PF(t_err) );
270 0
                vcc_ErrWhere(tl, t_err);
271 0
        }
272 54320
        if (rss->wrong || rss->retval > maxips) {
273 80
                VSB_printf(tl->sb,
274
                    "%s %.*s: resolves to too many addresses.\n"
275
                    "Only one IPv4 %s IPv6 are allowed.\n"
276
                    "Please specify which exact address "
277
                    "you want to use, we found all of these:\n%s",
278 40
                    errid, PF(t_err),
279 40
                    maxips > 1 ? "and one" :  "or",
280 40
                    VSB_data(rss->vsb));
281 40
                vcc_ErrWhere(tl, t_err);
282 40
        }
283 54320
        VSB_destroy(&rss->vsb);
284 54320
        ZERO_OBJ(rss, sizeof rss);
285 54480
}
286
287
/*--------------------------------------------------------------------
288
* Recognize boolean const "true" or "false"
289
*/
290
291
uint8_t
292 160
vcc_BoolVal(struct vcc *tl)
293
{
294
        struct symbol* sym;
295
296 160
        if (tl->t->tok != ID) {
297 40
                VSB_cat(tl->sb, "Expected \"true\" or \"false\"\n");
298 40
                vcc_ErrWhere(tl, tl->t);
299 40
                return (0);
300
        }
301 120
        sym = VCC_SymbolGet(tl, SYM_MAIN, SYM_NONE, SYMTAB_NOERR, XREF_NONE);
302 120
        if (sym == NULL || sym->type != BOOL) {
303 40
                VSB_cat(tl->sb, "Expected \"true\" or \"false\"\n");
304 40
                vcc_ErrWhere(tl, tl->t);
305 40
                return (0);
306
        }
307 80
        return (sym->eval_priv != NULL);
308 160
}
309
310
/*--------------------------------------------------------------------
311
 * Recognize and convert units of duration, return seconds.
312
 */
313
314
double
315 232320
vcc_DurationUnit(struct vcc *tl)
316
{
317
        double sc;
318
319 232320
        assert(tl->t->tok == ID);
320 232320
        sc = VNUM_duration_unit(1.0, tl->t->b, tl->t->e);
321 232320
        if (!isnan(sc)) {
322 232280
                vcc_NextToken(tl);
323 232280
                return (sc);
324
        }
325 40
        VSB_cat(tl->sb, "Unknown duration unit ");
326 40
        vcc_ErrToken(tl, tl->t);
327 40
        VSB_printf(tl->sb, "\n%s\n", VNUM_LEGAL_DURATION);
328 40
        vcc_ErrWhere(tl, tl->t);
329 40
        return (1.0);
330 232320
}
331
332
/*--------------------------------------------------------------------
333
 * Recognize and convert { CNUM } to unsigned value
334
 * The tokenizer made sure we only get digits.
335
 */
336
337
uint64_t
338 8600
vcc_UintVal(struct vcc *tl)
339
{
340
        int64_t retval;
341
342 8600
        if (tl->t->tok != CNUM) {
343 0
                Expect(tl, CNUM);
344 0
                return (0);
345
        }
346 8600
        retval = (int64_t)round(tl->t->num);
347 8600
        if (retval < 0) {
348 0
                VSB_cat(tl->sb, "UINT cannot be negative\n");
349 0
                vcc_ErrWhere(tl, tl->t);
350 0
                return (0);
351
        }
352 8600
        vcc_NextToken(tl);
353 8600
        return (retval);
354 8600
}
355
356
static double
357 1920
vcc_DoubleVal(struct vcc *tl)
358
{
359
        double retval;
360
361 1920
        if (tl->t->tok != CNUM && tl->t->tok != FNUM) {
362 40
                Expect(tl, CNUM);
363 40
                return (0);
364
        }
365 1880
        retval = tl->t->num;
366 1880
        vcc_NextToken(tl);
367 1880
        return (retval);
368 1920
}
369
370
/*--------------------------------------------------------------------*/
371
372
void
373 1920
vcc_Duration(struct vcc *tl, double *d)
374
{
375
        double v, sc;
376
377 1920
        v = vcc_DoubleVal(tl);
378 1920
        ERRCHK(tl);
379 1880
        ExpectErr(tl, ID);
380 1880
        sc = vcc_DurationUnit(tl);
381 1880
        *d = v * sc;
382 1920
}
383
384
/*--------------------------------------------------------------------*/
385
386
void
387 1920
vcc_ByteVal(struct vcc *tl, VCL_INT *d)
388
{
389
        double v;
390
        VCL_INT retval;
391
        const char *errtxt;
392
393 1920
        if (tl->t->tok != CNUM && tl->t->tok != FNUM) {
394 0
                Expect(tl, CNUM);
395 0
                return;
396
        }
397 1920
        v = tl->t->num;
398 1920
        vcc_NextToken(tl);
399 1920
        if (tl->t->tok != ID) {
400 40
                VSB_cat(tl->sb, "Expected BYTES unit (B, KB, MB...) got ");
401 40
                vcc_ErrToken(tl, tl->t);
402 40
                VSB_cat(tl->sb, "\n");
403 40
                vcc_ErrWhere(tl, tl->t);
404 40
                return;
405
        }
406 1880
        retval = VNUM_bytes_unit(v, tl->t->b, tl->t->e, 0, &errtxt);
407 1880
        if (errno) {
408 40
                VSB_cat(tl->sb, errtxt);
409 40
                vcc_ErrToken(tl, tl->t);
410 40
                vcc_ErrWhere(tl, tl->t);
411 40
                return;
412
        }
413 1840
        vcc_NextToken(tl);
414 1840
        *d = retval;
415 1920
}
416
417
/*--------------------------------------------------------------------*/
418
419
int
420 4160
vcc_IsFlagRaw(struct vcc *tl, const struct token *t1, const struct token *t2)
421
{
422
423 4160
        if (t1->tok != '-' && t1->tok != '+')
424 3280
                return (-1);
425 880
        if (t2->b != t1->e) {
426 40
                VSB_cat(tl->sb, "Expected a flag at:\n");
427 40
                vcc_ErrWhere(tl, t1);
428 40
                return (-1);
429
        }
430 840
        return (t1->tok == '+' ? 1 : 0);
431 4160
}
432
433
int
434 2200
vcc_IsFlag(struct vcc *tl)
435
{
436
        struct token *t;
437
        int retval;
438
439 2200
        t = vcc_PeekToken(tl);
440 2200
        if (t == NULL)
441 0
                return (-1);
442 2200
        retval = vcc_IsFlagRaw(tl, tl->t, t);
443 2200
        if (retval >= 0)
444 640
                vcc_NextToken(tl);
445 2200
        return (retval);
446 2200
}
447
448
char *
449 25498720
vcc_Dup_be(const char *b, const char *e)
450
{
451
        char *p;
452
453 25498720
        AN(b);
454 25498720
        if (e == NULL)
455 0
                e = strchr(b, '\0');
456 25498720
        AN(e);
457 25498720
        assert(e >= b);
458
459 25498720
        p = strndup(b, e - b);
460 25498720
        AN(p);
461 25498720
        return (p);
462
}
463
464
int
465 97040
vcc_Has_vcl_prefix(const char *b)
466
{
467 88800
        return (
468 97040
            (b[0] == 'v' || b[0] == 'V') &&
469 8360
            (b[1] == 'c' || b[1] == 'C') &&
470 97160
            (b[2] == 'l' || b[2] == 'L') &&
471 120
            (b[3] == '_')
472
        );
473
}