varnish-cache/lib/libvarnish/vsa.c
1
/*-
2
 * Copyright (c) 2013-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
 * Struct sockaddr_* is not even close to a convenient API.
31
 *
32
 * These functions try to mitigate the madness, at the cost of actually
33
 * knowing something about address families.
34
 */
35
36
#include "config.h"
37
38
#include <string.h>
39
#include <stdlib.h>
40
#include <sys/socket.h>
41
#include <sys/types.h>
42
#include <netinet/in.h>
43
44
#include "vdef.h"
45
#include "vas.h"
46
#include "vsa.h"
47
#include "miniobj.h"
48
49
/*
50
 * Struct sockaddr{|_in|_in6|_storage} is absolutely the worst data
51
 * structure I have ever seen gold-plated in international standards.
52
 *
53
 * Network addresses have multiple different forms, many fewer today
54
 * than in last century, but imagine that in addition to IPv4 and IPv6
55
 * we had 40 other protocols.  Actually, you don't need to imagine that
56
 * just count the AF_* macros in /usr/include/sys/socket.h.
57
 *
58
 * So what do we pass the kernel API for an address to bind(2), connect(2) &
59
 * listen(2) etc. etc ?
60
 *
61
 * We could define a struct which is big enough to hold any and all
62
 * of these addresses.  That would make it a fixed size argument.
63
 * obviously the struct would have to be something like:
64
 *      struct bla {
65
 *              int family;
66
 *              char address[MAX_ADDR_LEN];
67
 *      }
68
 * and MAX_ADDR_LEN would have to be quite large, 128 byte or so.
69
 *
70
 * Back in last century that was TOTALLY unacceptable waste of space.
71
 *
72
 * The way which was chosen instead, was to make a "generic" address,
73
 * and have per protocol "specific" addresses, and pass the length
74
 * argument explicitly to the KPI functions.
75
 *
76
 * The generic address was called "struct sockaddr", and the specific
77
 * were called "struct sockaddr_${whatever}".  All of these must have
78
 * a "family" field as first element, so the kernel can figure out
79
 * which protocol it is.
80
 *
81
 * The generic struct sockaddr was made big enough for all protocols
82
 * supported in the kernel, so it would have different sizes depending
83
 * on your machine and kernel configuration.
84
 *
85
 * However, that allowed you to write protocol-agnostic programs, by
86
 * using "struct sockaddr" throughout, and relying on libray APIs for
87
 * things like name to address (and vice versa) resolution, and since
88
 * nobody were in the business of shipping random UNIX binaries around
89
 * the lack of binary portability didn't matter.
90
 *
91
 * Along the way the BSD people figured out that it was a bother
92
 * to carry the length argument separately, and added that to the
93
 * format of sockaddr, but other groups found this unclean, as
94
 * the length was already an explicit parameter.
95
 *
96
 * The net result of this is that your "portable" code, must take
97
 * care to handle the "sa_len" member on kernels which have it,
98
 * while still tracking the separate length argument for all other
99
 * kernels.
100
 *
101
 * Needless to say, there were no neat #define to tell you which
102
 * was which, so each programmer found a different heuristic to
103
 * decide, often not understanding it fully, which caused the kind
104
 * of portability issues which lead to the autocrap tools.
105
 *
106
 * Then all the other protocols died, we were left with IP and
107
 * life were good, the dot-com madness multiplied the IT-business
108
 * by a factor 1000, by making any high-school student who had
109
 * programmed PERL for 6 weeks a "senior web-programmer".
110
 *
111
 * Next IPv6 happened, in a rush even, (no seriously, I'm not kidding!),
112
 * and since IPv6 addresses were HUGE, like 16 bytes HUGE, the generic
113
 * struct sockaddr was not increased in size.
114
 *
115
 * At least "not yet", because it would break all the shitty code written
116
 * by the dot-com generation.
117
 *
118
 * Nobody used IPv6 anyway so that didn't matter that much.
119
 *
120
 * Then people actually started using IPv6 and its struct sockaddr_in6,
121
 * and realized that all the code which used "struct sockaddr" to allocate
122
 * space at compile time were broken.
123
 *
124
 * Some people took to using sockaddr_in6, since that was known to
125
 * be big enough for both IPv4 and IPv6, but "purist" found that
126
 * ugly and "prone to future trouble".
127
 *
128
 * So instead they came up with a "clean solution":  The added
129
 * "struct sockaddr_storage" which is defined to be "Large enough
130
 * to accommodate all supported protocol-specific address structures".
131
 *
132
 * Since we cannot possibly know what zany protocols will exist in
133
 * the future, and since some people think that we will add future
134
 * protocols, while retaining ABI compatibility, (totally overlooking
135
 * the fact that no code for name-resolution supports that) it is
136
 * usually defined so it can cope with 128 byte addresses.
137
 *
138
 * Does that ring a bell ?
139
 *
140
 * Only, not quite:  Remember that all APIs require you to track
141
 * the address and the length separately, so you only get the
142
 * size of the specific protocols sockaddr_${whatever} from API
143
 * functions, not a full sockaddr_storage, and besides the
144
 * prototype for the KPI is still "struct sockaddr *", so you
145
 * cannot gain C type-safety back by using sockaddr_storage
146
 * as the "generic network address" type.
147
 *
148
 * So we have come full circle, while causing maximum havoc along
149
 * the way and for the forseeable future.
150
 *
151
 * Do I need to tell you that static code analysis tools have a
152
 * really hard time coping with this, and that they give a lot of
153
 * false negatives which confuse people ?
154
 *
155
 * I have decided to try to contain this crap in this single
156
 * source-file, with only minimum leakage into the rest of Varnish,
157
 * which will only know of pointers to "struct suckaddr", the naming
158
 * of which is my of the historical narrative above.
159
 *
160
 * And you don't need to take my word for this, you can see it all
161
 * in various #include files on your own system.   If you are on
162
 * a Solaris derivative, don't miss the beautiful horror hidden in the
163
 * variant definition of IPv6 addresses between kernel and userland.
164
 *
165
 */
166
167
struct suckaddr {
168
        unsigned                        magic;
169
#define SUCKADDR_MAGIC                  0x4b1e9335
170
        union {
171
                struct sockaddr         sa;
172
                struct sockaddr_in      sa4;
173
                struct sockaddr_in6     sa6;
174
        } u;
175
};
176
177
const size_t vsa_suckaddr_len = sizeof(struct suckaddr);
178
179
/*
180
 * Bogus IPv4 address 0.0.0.0:0 to be used for VCL *.ip variables when the
181
 * "real" address is not IP (such as UDS addresses).
182
 */
183
static struct suckaddr bogo_ip_vsa;
184
const struct suckaddr *bogo_ip = &bogo_ip_vsa;
185
/* same in IPv6 */
186
static struct suckaddr bogo_ip6_vsa;
187
const struct suckaddr *bogo_ip6 = &bogo_ip6_vsa;
188
189
void
190 34760
VSA_Init(void)
191
{
192 34760
        AN(VSA_BuildFAP(&bogo_ip_vsa, PF_INET, NULL, 0, NULL, 0));
193 34760
        AN(VSA_BuildFAP(&bogo_ip6_vsa, PF_INET6, NULL, 0, NULL, 0));
194 34760
}
195
196
/*
197
 * This VRT interface is for the VCC generated ACL code, which needs
198
 * to know the address family and a pointer to the actual address.
199
 */
200
201
int
202 3861920
VSA_GetPtr(const struct suckaddr *sua, const unsigned char ** dst)
203
{
204
205 3861920
        AN(dst);
206 3861920
        if (sua == NULL)
207 0
                return (-1);
208 3861920
        CHECK_OBJ_NOTNULL(sua, SUCKADDR_MAGIC);
209
210 3861920
        switch (sua->u.sa.sa_family) {
211
        case PF_INET:
212 7760
                assert(sua->u.sa.sa_family == sua->u.sa4.sin_family);
213 7760
                *dst = (const unsigned char *)&sua->u.sa4.sin_addr;
214 7760
                return (sua->u.sa4.sin_family);
215
        case PF_INET6:
216 3854160
                assert(sua->u.sa.sa_family == sua->u.sa6.sin6_family);
217 3854160
                *dst = (const unsigned char *)&sua->u.sa6.sin6_addr;
218 3854160
                return (sua->u.sa6.sin6_family);
219
        default:
220 0
                *dst = NULL;
221 0
                return (-1);
222
        }
223 3861920
}
224
225
/*
226
 * Return the size of a struct sockaddr in a struck suckaddr
227
 * or 0 if unknown family
228
 */
229
static inline
230 6182146
socklen_t sua_len(const struct sockaddr *sa)
231
{
232 6182146
        switch (sa->sa_family) {
233
        case PF_INET:
234 2110712
                return (sizeof(struct sockaddr_in));
235
        case PF_INET6:
236 4071400
                return (sizeof(struct sockaddr_in6));
237
        default:
238 40
                return (0);
239
        }
240 6182151
}
241
242
/*
243
 * Malloc a suckaddr from a sockaddr of some kind.
244
 */
245
246
struct suckaddr *
247 399628
VSA_Malloc(const void *s, unsigned  sal)
248
{
249 399628
        return (VSA_Build(malloc(vsa_suckaddr_len), s, sal));
250
}
251
252
/* 'd' SHALL point to vsa_suckaddr_len aligned bytes of storage
253
 *
254
 * fam: address family
255
 * a / al : address and length
256
 * p / pl : port and length
257
 *
258
 * NULL or 0 length argument are ignored.
259
 * argument of the wrong length are an error (NULL return value, EINVAL)
260
 */
261
struct suckaddr *
262 71040
VSA_BuildFAP(void *d, sa_family_t fam, const void *a, unsigned al,
263
            const void *p, unsigned pl)
264
{
265
        struct sockaddr_in sin4;
266
        struct sockaddr_in6 sin6;
267
268 71040
        switch (fam) {
269
        case PF_INET:
270 35880
                memset(&sin4, 0, sizeof sin4);
271 35880
                sin4.sin_family = fam;
272 35880
                if (a != NULL && al > 0) {
273 1120
                        if (al != sizeof(sin4.sin_addr))
274 0
                                break;
275 1120
                        memcpy(&sin4.sin_addr, a, al);
276 1120
                }
277 35880
                if (p != NULL && pl > 0) {
278 880
                        if (pl != sizeof(sin4.sin_port))
279 0
                                break;
280 880
                        memcpy(&sin4.sin_port, p, pl);
281 880
                }
282 35880
                return (VSA_Build(d, &sin4, sizeof sin4));
283
        case PF_INET6:
284 35160
                memset(&sin6, 0, sizeof sin6);
285 35160
                sin6.sin6_family = fam;
286 35160
                if (a != NULL && al > 0) {
287 400
                        if (al != sizeof(sin6.sin6_addr))
288 0
                                break;
289 400
                        memcpy(&sin6.sin6_addr, a, al);
290 400
                }
291 35160
                if (p != NULL && pl > 0) {
292 400
                        if (pl != sizeof(sin6.sin6_port))
293 0
                                break;
294 400
                        memcpy(&sin6.sin6_port, p, pl);
295 400
                }
296 35160
                return (VSA_Build(d, &sin6, sizeof sin6));
297
        default:
298 0
                errno = EAFNOSUPPORT;
299 0
                return (NULL);
300
        }
301 0
        errno = EINVAL;
302 0
        return (NULL);
303 71040
}
304
305
/* 'd' SHALL point to vsa_suckaddr_len aligned bytes of storage */
306
struct suckaddr *
307 543555
VSA_Build(void *d, const void *s, unsigned sal)
308
{
309
        struct suckaddr *sua;
310 543555
        const struct sockaddr *sa = s;
311
        unsigned l;     // for flexelint
312
313 543555
        AN(d);
314 543546
        AN(s);
315 543542
        l = sua_len(sa);
316 543542
        if (l == 0 || l != sal)
317 40
                return (NULL);
318
319 543497
        sua = d;
320
321 543497
        INIT_OBJ(sua, SUCKADDR_MAGIC);
322 543489
        switch (l) {
323
        case sizeof sua->u.sa4:
324 436166
                memcpy(&sua->u.sa4, s, l);
325 436166
                break;
326
        case sizeof sua->u.sa6:
327 107320
                memcpy(&sua->u.sa6, s, l);
328 107320
                break;
329
        default:
330 0
                WRONG("VSA protocol vs. size");
331 0
        }
332
#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
333 543501
        sua->u.sa.sa_len = (unsigned char)l;
334
#endif
335 543501
        return (sua);
336 543540
}
337
338
const void *
339 1405037
VSA_Get_Sockaddr(const struct suckaddr *sua, socklen_t *slp)
340
{
341
        socklen_t sl;
342
343 1405037
        CHECK_OBJ_NOTNULL(sua, SUCKADDR_MAGIC);
344 1405047
        AN(slp);
345 1405054
        sl = sua_len(&sua->u.sa);
346 1405054
        if (sl == 0)
347 0
                return (NULL);
348 1405017
        *slp = sl;
349 1405017
        return (&sua->u.sa);
350 1405021
}
351
352
int
353 434769
VSA_Get_Proto(const struct suckaddr *sua)
354
{
355
356 434769
        CHECK_OBJ_NOTNULL(sua, SUCKADDR_MAGIC);
357 434769
        return (sua->u.sa.sa_family);
358
}
359
360
int
361 4233576
VSA_Sane(const struct suckaddr *sua)
362
{
363 4233576
        return (VALID_OBJ(sua, SUCKADDR_MAGIC) && sua_len(&sua->u.sa) != 0);
364
}
365
366
int
367 7088
VSA_Compare(const struct suckaddr *sua1, const struct suckaddr *sua2)
368
{
369
370 7088
        CHECK_OBJ_NOTNULL(sua1, SUCKADDR_MAGIC);
371 7088
        CHECK_OBJ_NOTNULL(sua2, SUCKADDR_MAGIC);
372 7088
        return (memcmp(sua1, sua2, vsa_suckaddr_len));
373
}
374
375
int
376 642
VSA_Compare_IP(const struct suckaddr *sua1, const struct suckaddr *sua2)
377
{
378
379 642
        assert(VSA_Sane(sua1));
380 641
        assert(VSA_Sane(sua2));
381
382 641
        if (sua1->u.sa.sa_family != sua2->u.sa.sa_family)
383 0
                return (-1);
384
385 642
        switch (sua1->u.sa.sa_family) {
386
        case PF_INET:
387 1284
                return (memcmp(&sua1->u.sa4.sin_addr,
388 642
                    &sua2->u.sa4.sin_addr, sizeof(struct in_addr)));
389
        case PF_INET6:
390 0
                return (memcmp(&sua1->u.sa6.sin6_addr,
391 0
                    &sua2->u.sa6.sin6_addr, sizeof(struct in6_addr)));
392
        default:
393 0
                WRONG("Just plain insane");
394 0
        }
395 0
        NEEDLESS(return (-1));
396 642
}
397
398
struct suckaddr *
399 116680
VSA_Clone(const struct suckaddr *sua)
400
{
401
        struct suckaddr *sua2;
402
403 116680
        assert(VSA_Sane(sua));
404 116680
        sua2 = calloc(1, vsa_suckaddr_len);
405 116680
        XXXAN(sua2);
406 116680
        memcpy(sua2, sua, vsa_suckaddr_len);
407 116680
        return (sua2);
408
}
409
410
unsigned
411 36680
VSA_Port(const struct suckaddr *sua)
412
{
413
414 36680
        CHECK_OBJ_NOTNULL(sua, SUCKADDR_MAGIC);
415 36680
        switch (sua->u.sa.sa_family) {
416
        case PF_INET:
417 35120
                return (ntohs(sua->u.sa4.sin_port));
418
        case PF_INET6:
419 1560
                return (ntohs(sua->u.sa6.sin6_port));
420
        default:
421 0
                return (0);
422
        }
423 36680
}
424
425
#define VSA_getname(which)                              \
426
struct suckaddr *                                       \
427
VSA_get ## which ## name(int fd, void *d, size_t l)     \
428
{                                                       \
429
        struct suckaddr *sua;                           \
430
        socklen_t sl;                                   \
431
        int r;                                          \
432
                                                        \
433
        AN(d);                                          \
434
        if (l != vsa_suckaddr_len) {                    \
435
                errno = EINVAL;                         \
436
                return (NULL);                          \
437
        }                                               \
438
                                                        \
439
        sua = d;                                        \
440
                                                        \
441
        INIT_OBJ(sua, SUCKADDR_MAGIC);                  \
442
        sl = sizeof(sua->u);                            \
443
        r = get ## which ## name(fd, &sua->u.sa, &sl);  \
444
                                                        \
445
        return (r == 0 ? sua : NULL);                   \
446
}                                                       \
447
448 545577
VSA_getname(sock)
449 281573
VSA_getname(peer)
450
#undef VSA_getname