varnish-cache/lib/libvcc/vcc_utils.c
1
/*-
2
 * Copyright (c) 2006 Verdens Gang AS
3
 * Copyright (c) 2006-2015 Varnish Software AS
4
 * All rights reserved.
5
 *
6
 * Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions
10
 * are met:
11
 * 1. Redistributions of source code must retain the above copyright
12
 *    notice, this list of conditions and the following disclaimer.
13
 * 2. Redistributions in binary form must reproduce the above copyright
14
 *    notice, this list of conditions and the following disclaimer in the
15
 *    documentation and/or other materials provided with the distribution.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
 * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
21
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27
 * SUCH DAMAGE.
28
 */
29
30
#include "config.h"
31
32
#include <math.h>
33
#include <string.h>
34
#include <stdlib.h>
35
#include <sys/socket.h>
36
#include <sys/types.h>
37
#include <sys/stat.h>
38
#include <unistd.h>
39
#include <errno.h>
40
41
#include "vcc_compile.h"
42
43
#include "vre.h"
44
#include "vsa.h"
45
#include "vss.h"
46
#include "vtcp.h"
47
48
/*--------------------------------------------------------------------*/
49
50
void
51 13930
vcc_regexp(struct vcc *tl, struct vsb *vgc_name)
52
{
53
        char buf[BUFSIZ];
54
        vre_t *t;
55
        const char *error;
56
        int erroroffset;
57
        struct inifin *ifp;
58
59 13930
        Expect(tl, CSTR);
60 13930
        if (tl->err)
61 5
                return;
62 13930
        t = VRE_compile(tl->t->dec, 0, &error, &erroroffset);
63 13930
        if (t == NULL) {
64 5
                VSB_printf(tl->sb,
65
                    "Regexp compilation error:\n\n%s\n\n", error);
66 5
                vcc_ErrWhere(tl, tl->t);
67 5
                return;
68
        }
69 13925
        VRE_free(&t);
70 13925
        bprintf(buf, "VGC_re_%u", tl->unique++);
71 13925
        if (vgc_name)
72 13925
                VSB_cat(vgc_name, buf);
73
74 13925
        Fh(tl, 0, "static void *%s;\n", buf);
75 13925
        ifp = New_IniFin(tl);
76 13925
        VSB_printf(ifp->ini, "\tVRT_re_init(&%s, ",buf);
77 13925
        EncToken(ifp->ini, tl->t);
78 13925
        VSB_printf(ifp->ini, ");");
79 13925
        VSB_printf(ifp->fin, "\t\tVRT_re_fini(%s);", buf);
80 13925
        vcc_NextToken(tl);
81
}
82
83
/*
84
 * The IPv6 crew royally screwed up the entire idea behind
85
 * struct sockaddr, see libvarnish/vsa.c for blow-by-blow account.
86
 *
87
 * There is no sane or even remotely portable way to initialize
88
 * a sockaddr for random protocols at compile time.
89
 *
90
 * In our case it is slightly more tricky than that, because we don't
91
 * even want to #include the struct sockaddr* definitions.
92
 *
93
 * Instead we make sure the sockaddr is sane (for our values of
94
 * sane) and dump it as our own "struct suckaddr" type, in binary,
95
 * using the widest integertype, hoping that this will ensure sufficient
96
 * alignment.
97
 */
98
99
static void
100 5780
vcc_suckaddr(struct vcc *tl, const char *host, const struct suckaddr *vsa,
101
    const char **ip, const char **ip_ascii, const char **p_ascii)
102 5780
{
103
        char a[VTCP_ADDRBUFSIZE];
104
        char p[VTCP_PORTBUFSIZE];
105 5780
        const int sz = sizeof(unsigned long long);
106 5780
        const unsigned n = (vsa_suckaddr_len + sz - 1) / sz;
107 5780
        unsigned long long b[n];
108
        int len;
109
        char *q;
110
111 5780
        VTCP_name(vsa, a, sizeof a, p, sizeof p);
112 5780
        Fh(tl, 0, "\n/* \"%s\" -> %s */\n", host, a);
113 5780
        if (ip_ascii != NULL)
114 5655
                *ip_ascii = TlDup(tl, a);
115 5780
        if (p_ascii != NULL && *p_ascii == NULL)
116 5650
                *p_ascii = TlDup(tl, p);
117
118 5780
        Fh(tl, 0, "static const unsigned long long");
119 5780
        Fh(tl, 0, " suckaddr_%u[%d] = {\n", tl->unique, n);
120 5780
        memcpy(b, vsa, vsa_suckaddr_len);
121 28900
        for (len = 0; len < n; len++)
122 23120
                Fh(tl, 0, "%s    0x%0*llxULL",
123
                    len ? ",\n" : "", sz * 2, b[len]);
124 5780
        Fh(tl, 0, "\n};\n");
125
126 5780
        q = TlAlloc(tl, 40);
127 5780
        AN(q);
128 5780
        assert(snprintf(q, 40, "(const void*)suckaddr_%u", tl->unique) < 40);
129 5780
        *ip = q;
130 5780
        tl->unique++;
131 5780
}
132
133
/*--------------------------------------------------------------------
134
 * This routine is a monster, but at least we only have one such monster.
135
 * Look up a IP number, and return IPv4/IPv6 address as VGC produced names
136
 * and optionally ascii strings.
137
 *
138
 * For IP compile time constants we only want one IP#, but it can be
139
 * IPv4 or IPv6.
140
 *
141
 * For backends, we accept up to one IPv4 and one IPv6.
142
 */
143
144
struct rss {
145
        unsigned                magic;
146
#define RSS_MAGIC               0x11e966ab
147
148
        struct suckaddr         *vsa4;
149
        struct suckaddr         *vsa6;
150
        struct vsb              *vsb;
151
        int                     retval;
152
        int                     wrong;
153
};
154
155
static int v_matchproto_(vss_resolved_f)
156 5780
rs_callback(void *priv, const struct suckaddr *vsa)
157
{
158
        struct rss *rss;
159
        int v;
160
        char a[VTCP_ADDRBUFSIZE];
161
        char p[VTCP_PORTBUFSIZE];
162
163 5780
        CAST_OBJ_NOTNULL(rss, priv, RSS_MAGIC);
164 5780
        assert(VSA_Sane(vsa));
165
166 5780
        v = VSA_Get_Proto(vsa);
167 5780
        assert(v != AF_UNIX);
168 5780
        VTCP_name(vsa, a, sizeof a, p, sizeof p);
169 5780
        VSB_printf(rss->vsb, "\t%s:%s\n", a, p);
170 5780
        if (v == AF_INET) {
171 5725
                if (rss->vsa4 == NULL)
172 5725
                        rss->vsa4 = VSA_Clone(vsa);
173 0
                else if (VSA_Compare(vsa, rss->vsa4))
174 0
                        rss->wrong++;
175 5725
                rss->retval++;
176 55
        } else if (v == AF_INET6) {
177 55
                if (rss->vsa6 == NULL)
178 55
                        rss->vsa6 = VSA_Clone(vsa);
179 0
                else if (VSA_Compare(vsa, rss->vsa6))
180 0
                        rss->wrong++;
181 55
                rss->retval++;
182
        }
183 5780
        return (0);
184
}
185
186
void
187 5790
Resolve_Sockaddr(struct vcc *tl,
188
    const char *host,
189
    const char *def_port,
190
    const char **ipv4,
191
    const char **ipv4_ascii,
192
    const char **ipv6,
193
    const char **ipv6_ascii,
194
    const char **p_ascii,
195
    int maxips,
196
    const struct token *t_err,
197
    const char *errid)
198
{
199
        int error;
200
        struct rss *rss;
201
        const char *err;
202
203 5790
        *ipv4 = NULL;
204 5790
        *ipv6 = NULL;
205 5790
        if (p_ascii != NULL)
206 5660
                *p_ascii = NULL;
207
208 5790
        ALLOC_OBJ(rss, RSS_MAGIC);
209 5790
        AN(rss);
210 5790
        rss->vsb = VSB_new_auto();
211 5790
        AN(rss->vsb);
212
213 5790
        error = VSS_resolver(host, def_port, rs_callback, rss, &err);
214 5790
        AZ(VSB_finish(rss->vsb));
215 5790
        if (err != NULL) {
216 40
                VSB_printf(tl->sb,
217
                    "%s '%.*s' could not be resolved to an IP address:\n"
218
                    "\t%s\n"
219
                    "(Sorry if that error message is gibberish.)\n",
220 20
                    errid, PF(t_err), err);
221 20
                vcc_ErrWhere(tl, t_err);
222 20
                free(rss->vsa4);
223 20
                free(rss->vsa6);
224 20
                VSB_destroy(&rss->vsb);
225 20
                FREE_OBJ(rss);
226 20
                return;
227
        }
228 5770
        AZ(error);
229 5770
        if (rss->vsa4 != NULL) {
230 5725
                vcc_suckaddr(tl, host, rss->vsa4, ipv4, ipv4_ascii, p_ascii);
231 5725
                free(rss->vsa4);
232
        }
233 5770
        if (rss->vsa6 != NULL) {
234 55
                vcc_suckaddr(tl, host, rss->vsa6, ipv6, ipv6_ascii, p_ascii);
235 55
                free(rss->vsa6);
236
        }
237 5770
        if (rss->retval == 0) {
238 0
                VSB_printf(tl->sb,
239
                    "%s '%.*s': resolves to "
240
                    "neither IPv4 nor IPv6 addresses.\n",
241 0
                    errid, PF(t_err) );
242 0
                vcc_ErrWhere(tl, t_err);
243
        }
244 5770
        if (rss->wrong || rss->retval > maxips) {
245 10
                VSB_printf(tl->sb,
246
                    "%s %.*s: resolves to too many addresses.\n"
247
                    "Only one IPv4 %s IPv6 are allowed.\n"
248
                    "Please specify which exact address "
249
                    "you want to use, we found all of these:\n%s",
250 5
                    errid, PF(t_err),
251
                    maxips > 1 ? "and one" :  "or",
252 5
                    VSB_data(rss->vsb));
253 5
                vcc_ErrWhere(tl, t_err);
254
        }
255 5770
        VSB_destroy(&rss->vsb);
256 5770
        FREE_OBJ(rss);
257
}
258
259
/*
260
 * For UDS, we do not create a VSA. Check if it's an absolute path, can
261
 * be accessed, and is a socket. If so, just emit the path field and set
262
 * the IP suckaddrs to NULL.
263
 */
264
void
265 150
Emit_UDS_Path(struct vcc *tl, const struct token *t_path, const char *errid)
266
{
267
        struct stat st;
268
269 150
        AN(t_path);
270 150
        AN(t_path->dec);
271
272 150
        if (*t_path->dec != '/') {
273 5
                VSB_printf(tl->sb,
274
                           "%s: Must be an absolute path:\n", errid);
275 5
                vcc_ErrWhere(tl, t_path);
276 5
                return;
277
        }
278 145
        errno = 0;
279 145
        if (stat(t_path->dec, &st) != 0) {
280 5
                VSB_printf(tl->sb, "%s: Cannot stat: %s\n", errid,
281 5
                           strerror(errno));
282 5
                vcc_ErrWhere(tl, t_path);
283 5
                return;
284
        }
285 140
        if (!S_ISSOCK(st.st_mode)) {
286 5
                VSB_printf(tl->sb, "%s: Not a socket:\n", errid);
287 5
                vcc_ErrWhere(tl, t_path);
288 5
                return;
289
        }
290 135
        Fb(tl, 0, "\t.path = \"%s\",\n", t_path->dec);
291 135
        Fb(tl, 0, "\t.ipv4_suckaddr = (void *) 0,\n");
292 135
        Fb(tl, 0, "\t.ipv6_suckaddr = (void *) 0,\n");
293
}
294
295
/*--------------------------------------------------------------------
296
 * Recognize and convert units of time, return seconds.
297
 */
298
299
double
300 19025
vcc_TimeUnit(struct vcc *tl)
301
{
302 19025
        double sc = 1.0;
303
304 19025
        assert(tl->t->tok == ID);
305 19025
        if (vcc_IdIs(tl->t, "ms"))
306 40
                sc = 1e-3;
307 18985
        else if (vcc_IdIs(tl->t, "s"))
308 18790
                sc = 1.0;
309 195
        else if (vcc_IdIs(tl->t, "m"))
310 115
                sc = 60.0;
311 80
        else if (vcc_IdIs(tl->t, "h"))
312 35
                sc = 60.0 * 60.0;
313 45
        else if (vcc_IdIs(tl->t, "d"))
314 20
                sc = 60.0 * 60.0 * 24.0;
315 25
        else if (vcc_IdIs(tl->t, "w"))
316 5
                sc = 60.0 * 60.0 * 24.0 * 7.0;
317 20
        else if (vcc_IdIs(tl->t, "y"))
318 15
                sc = 60.0 * 60.0 * 24.0 * 365.0;
319
        else {
320 5
                VSB_printf(tl->sb, "Unknown time unit ");
321 5
                vcc_ErrToken(tl, tl->t);
322 5
                VSB_printf(tl->sb,
323
                    ".  Legal are 'ms', 's', 'm', 'h', 'd', 'w' and 'y'\n");
324 5
                vcc_ErrWhere(tl, tl->t);
325 5
                return (1.0);
326
        }
327 19020
        vcc_NextToken(tl);
328 19020
        return (sc);
329
}
330
331
/*--------------------------------------------------------------------
332
 * Recognize and convert { CNUM } to unsigned value
333
 * The tokenizer made sure we only get digits.
334
 */
335
336
unsigned
337 370
vcc_UintVal(struct vcc *tl)
338
{
339 370
        unsigned d = 0;
340
        const char *p;
341
342 370
        Expect(tl, CNUM);
343 895
        for (p = tl->t->b; p < tl->t->e; p++) {
344 525
                d *= 10;
345 525
                d += *p - '0';
346
        }
347 370
        vcc_NextToken(tl);
348 370
        return (d);
349
}
350
351
static double
352 285
vcc_DoubleVal(struct vcc *tl)
353 285
{
354 285
        const size_t l = tl->t->e - tl->t->b;
355 285
        char buf[l + 1];
356
357 285
        assert(tl->t->tok == CNUM || tl->t->tok == FNUM);
358 285
        memcpy(buf, tl->t->b, l);
359 285
        vcc_NextToken(tl);
360 285
        buf[l] = '\0';
361 285
        return (strtod(buf, NULL));
362
}
363
364
/*--------------------------------------------------------------------*/
365
366
void
367 120
vcc_Duration(struct vcc *tl, double *d)
368
{
369
        double v, sc;
370
371 120
        v = vcc_DoubleVal(tl);
372 120
        ERRCHK(tl);
373 120
        ExpectErr(tl, ID);
374 120
        sc = vcc_TimeUnit(tl);
375 120
        *d = v * sc;
376
}
377
378
/*--------------------------------------------------------------------*/
379
380
void
381 165
vcc_ByteVal(struct vcc *tl, double *d)
382
{
383
        double v, sc;
384
385 165
        v = vcc_DoubleVal(tl);
386 165
        ERRCHK(tl);
387 165
        if (tl->t->tok != ID) {
388 5
                VSB_printf(tl->sb, "Expected BYTES unit (B, KB, MB...) got ");
389 5
                vcc_ErrToken(tl, tl->t);
390 5
                VSB_printf(tl->sb, "\n");
391 5
                vcc_ErrWhere(tl, tl->t);
392 5
                return;
393
        }
394 160
        if (vcc_IdIs(tl->t, "B"))
395 110
                sc = 1.;
396 50
        else if (vcc_IdIs(tl->t, "KB"))
397 30
                sc = 1024.;
398 20
        else if (vcc_IdIs(tl->t, "MB"))
399 5
                sc = 1024. * 1024.;
400 15
        else if (vcc_IdIs(tl->t, "GB"))
401 5
                sc = 1024. * 1024. * 1024.;
402 10
        else if (vcc_IdIs(tl->t, "TB"))
403 5
                sc = 1024. * 1024. * 1024. * 1024.;
404
        else {
405 5
                VSB_printf(tl->sb, "Unknown BYTES unit ");
406 5
                vcc_ErrToken(tl, tl->t);
407 5
                VSB_printf(tl->sb,
408
                    ".  Legal are 'B', 'KB', 'MB', 'GB' and 'TB'\n");
409 5
                vcc_ErrWhere(tl, tl->t);
410 5
                return;
411
        }
412 155
        vcc_NextToken(tl);
413 155
        *d = v * sc;
414
}
415