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
 * Redistribution and use in source and binary forms, with or without
8
 * modification, are permitted provided that the following conditions
9
 * are met:
10
 * 1. Redistributions of source code must retain the above copyright
11
 *    notice, this list of conditions and the following disclaimer.
12
 * 2. Redistributions in binary form must reproduce the above copyright
13
 *    notice, this list of conditions and the following disclaimer in the
14
 *    documentation and/or other materials provided with the distribution.
15
 *
16
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
 * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
20
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26
 * SUCH DAMAGE.
27
 *
28
 * Struct sockaddr_* is not even close to a convenient API.
29
 *
30
 * These functions try to mitigate the madness, at the cost of actually
31
 * knowing something about address families.
32
 */
33
34
#include "config.h"
35
36
#include <string.h>
37
#include <stdlib.h>
38
#include <sys/socket.h>
39
#include <netinet/in.h>
40
41
#include "vdef.h"
42
#include "vas.h"
43
#include "vsa.h"
44
#include "vrt.h"
45
#include "miniobj.h"
46
47
/*
48
 * Struct sockaddr{|_in|_in6|_storage} is absolutely the worst data
49
 * structure I have ever seen gold-plated in international standards.
50
 *
51
 * Network addresses have multiple different forms, many fewer today
52
 * than in last century, but imagine that in addition to IPv4 and IPv6
53
 * we had 40 other protocols.  Actually, you don't need to imagine that
54
 * just count the AF_* macros in /usr/include/sys/socket.h.
55
 *
56
 * So what do we pass the kernel API for an address to bind(2), connect(2) &
57
 * listen(2) etc. etc ?
58
 *
59
 * We could define a struct which is big enough to hold any and all
60
 * of these addresses.  That would make it a fixed size argument.
61
 * obviously the struct would have to be something like:
62
 *      struct bla {
63
 *              int family;
64
 *              char address[MAX_ADDR_LEN];
65
 *      }
66
 * and MAX_ADDR_LEN would have to be quite large, 128 byte or so.
67
 *
68
 * Back in last century that was TOTALLY unacceptable waste of space.
69
 *
70
 * The way which was chosen instead, was to make a "generic" address,
71
 * and have per protocol "specific" addresses, and pass the length
72
 * argument explicitly to the KPI functions.
73
 *
74
 * The generic address was called "struct sockaddr", and the specific
75
 * were called "struct sockaddr_${whatever}".  All of these must have
76
 * a "family" field as first element, so the kernel can figure out
77
 * which protocol it is.
78
 *
79
 * The generic struct sockaddr was made big enough for all protocols
80
 * supported in the kernel, so it would have different sizes depending
81
 * on your machine and kernel configuration.
82
 *
83
 * However, that allowed you to write protocol-agnostic programs, by
84
 * using "struct sockaddr" throughout, and relying on libray APIs for
85
 * things like name to address (and vice versa) resolution, and since
86
 * nobody were in the business of shipping random UNIX binaries around
87
 * the lack of binary portability didn't matter.
88
 *
89
 * Along the way the BSD people figured out that it was a bother
90
 * to carry the length argument separately, and added that to the
91
 * format of sockaddr, but other groups found this unclean, as
92
 * the length was already an explicit paramter.
93
 *
94
 * The net result of this is that your "portable" code, must take
95
 * care to handle the "sa_len" member on kernels which have it,
96
 * while still tracking the separate length argument for all other
97
 * kernels.
98
 *
99
 * Needless to say, there were no neat #define to tell you which
100
 * was which, so each programmer found a different heuristic to
101
 * decide, often not understanding it fully, which caused the kind
102
 * of portability issues which lead to the autocrap tools.
103
 *
104
 * Then all the other protocols died, we were left with IP and
105
 * life were good, the dot-com madness multiplied the IT-business
106
 * by a factor 1000, by making any high-school student who had
107
 * programmed PERL for 6 weeks a "senior web-programmer".
108
 *
109
 * Next IPv6 happened, in a rush even, (no seriously, I'm not kidding!),
110
 * and since IPv6 addresses were HUGE, like 16 bytes HUGE, the generic
111
 * struct sockaddr was not increased in size.
112
 *
113
 * At least "not yet", because it would break all the shitty code written
114
 * by the dot-com generation.
115
 *
116
 * Nobody used IPv6 anyway so that didn't matter that much.
117
 *
118
 * Then people actually started using IPv6 and its struct sockaddr_in6,
119
 * and realized that all the code which used "struct sockaddr" to allocate
120
 * space at compile time were broken.
121
 *
122
 * Some people took to using sockaddr_in6, since that was known to
123
 * be big enough for both IPv4 and IPv6, but "purist" found that
124
 * ugly and "prone to future trouble".
125
 *
126
 * So instead they came up with a "clean solution":  The added
127
 * "struct sockaddr_storage" which is defined to be "Large enough
128
 * to accommodate all supported protocol-specific address structures".
129
 *
130
 * Since we cannot possibly know what zany protocols will exist in
131
 * the future, and since some people think that we will add future
132
 * protocols, while retaining ABI compatibility, (totally overlooking
133
 * the fact that no code for name-resolution supports that) it is
134
 * usually defined so it can cope with 128 byte addresses.
135
 *
136
 * Does that ring a bell ?
137
 *
138
 * Only, not quite:  Remember that all APIs require you to track
139
 * the address and the length separately, so you only get the
140
 * size of the specific protocols sockaddr_${whatever} from API
141
 * functions, not a full sockaddr_storage, and besides the
142
 * prototype for the KPI is still "struct sockaddr *", so you
143
 * cannot gain C type-safety back by using sockaddr_storage
144
 * as the "generic network address" type.
145
 *
146
 * So we have come full circle, while causing maximum havoc along
147
 * the way and for the forseeable future.
148
 *
149
 * Do I need to tell you that static code analysis tools have a
150
 * really hard time coping with this, and that they give a lot of
151
 * false negatives which confuse people ?
152
 *
153
 * I have decided to try to contain this crap in this single
154
 * source-file, with only minimum leakage into the rest of Varnish,
155
 * which will only know of pointers to "struct suckaddr", the naming
156
 * of which is my of the historical narrative above.
157
 *
158
 * And you don't need to take my word for this, you can see it all
159
 * in various #include files on your own system.   If you are on
160
 * a Solaris derivative, don't miss the beautiful horror hidden in the
161
 * variant definition of IPv6 addresses between kernel and userland.
162
 *
163
 */
164
165
struct suckaddr {
166
        unsigned                        magic;
167
#define SUCKADDR_MAGIC                  0x4b1e9335
168
        union {
169
                struct sockaddr         sa;
170
                struct sockaddr_in      sa4;
171
                struct sockaddr_in6     sa6;
172
        };
173
};
174
175
const int vsa_suckaddr_len = sizeof(struct suckaddr);
176
177
/*
178
 * This VRT interface is for the VCC generated ACL code, which needs
179
 * to know the address family and a pointer to the actual address.
180
 */
181
182
int
183 20
VRT_VSA_GetPtr(const struct suckaddr *sua, const unsigned char ** dst)
184
{
185
186 20
        AN(dst);
187 20
        if (sua == NULL)
188 0
                return (-1);
189 20
        CHECK_OBJ_NOTNULL(sua, SUCKADDR_MAGIC);
190
191 20
        switch (sua->sa.sa_family) {
192
        case PF_INET:
193 18
                assert(sua->sa.sa_family == sua->sa4.sin_family);
194 18
                *dst = (const unsigned char *)&sua->sa4.sin_addr;
195 18
                return (sua->sa4.sin_family);
196
        case PF_INET6:
197 2
                assert(sua->sa.sa_family == sua->sa6.sin6_family);
198 2
                *dst = (const unsigned char *)&sua->sa6.sin6_addr;
199 2
                return (sua->sa6.sin6_family);
200
        default:
201 0
                *dst = NULL;
202 0
                return (-1);
203
        }
204
}
205
206
/*
207
 * Malloc a suckaddr from a sockaddr of some kind.
208
 */
209
210
struct suckaddr *
211 8720
VSA_Malloc(const void *s, unsigned  sal)
212
{
213 8720
        struct suckaddr *sua = NULL;
214 8720
        const struct sockaddr *sa = s;
215 8720
        unsigned l = 0;
216
217 8720
        AN(s);
218 8720
        switch (sa->sa_family) {
219
        case PF_INET:
220 7333
                if (sal == sizeof sua->sa4)
221 7333
                        l = sal;
222 7333
                break;
223
        case PF_INET6:
224 1387
                if (sal == sizeof sua->sa6)
225 1387
                        l = sal;
226 1387
                break;
227
        default:
228 0
                break;
229
        }
230 8720
        if (l != 0) {
231 8720
                ALLOC_OBJ(sua, SUCKADDR_MAGIC);
232 8720
                if (sua != NULL)
233 8720
                        memcpy(&sua->sa, s, l);
234
        }
235 8720
        return (sua);
236
}
237
238
/* 'd' SHALL point to vsa_suckaddr_len aligned bytes of storage */
239
struct suckaddr *
240 2235
VSA_Build(void *d, const void *s, unsigned sal)
241
{
242 2235
        struct suckaddr *sua = d;
243 2235
        const struct sockaddr *sa = s;
244 2235
        unsigned l = 0;
245
246 2235
        AN(d);
247 2235
        AN(s);
248 2235
        switch (sa->sa_family) {
249
        case PF_INET:
250 2219
                if (sal == sizeof sua->sa4)
251 2219
                        l = sal;
252 2219
                break;
253
        case PF_INET6:
254 16
                if (sal == sizeof sua->sa6)
255 16
                        l = sal;
256 16
                break;
257
        default:
258 0
                break;
259
        }
260 2235
        if (l != 0) {
261 2235
                memset(sua, 0, sizeof *sua);
262 2235
                sua->magic = SUCKADDR_MAGIC;
263 2235
                memcpy(&sua->sa, s, l);
264 2235
                return (sua);
265
        }
266 0
        return (NULL);
267
}
268
269
const void *
270 14793
VSA_Get_Sockaddr(const struct suckaddr *sua, socklen_t *sl)
271
{
272
273 14793
        CHECK_OBJ_NOTNULL(sua, SUCKADDR_MAGIC);
274 14793
        AN(sl);
275 14793
        switch (sua->sa.sa_family) {
276
        case PF_INET:
277 13387
                *sl = sizeof sua->sa4;
278 13387
                break;
279
        case PF_INET6:
280 1406
                *sl = sizeof sua->sa6;
281 1406
                break;
282
        default:
283 0
                return (NULL);
284
        }
285 14793
        return (&sua->sa);
286
}
287
288
int
289 6308
VSA_Get_Proto(const struct suckaddr *sua)
290
{
291
292 6308
        CHECK_OBJ_NOTNULL(sua, SUCKADDR_MAGIC);
293 6308
        return (sua->sa.sa_family);
294
}
295
296
int
297 6795
VSA_Sane(const struct suckaddr *sua)
298
{
299 6795
        CHECK_OBJ_NOTNULL(sua, SUCKADDR_MAGIC);
300
301 6795
        switch (sua->sa.sa_family) {
302
        case PF_INET:
303
        case PF_INET6:
304 6795
                return (1);
305
        default:
306 0
                return (0);
307
        }
308
}
309
310
int
311 287
VSA_Compare(const struct suckaddr *sua1, const struct suckaddr *sua2)
312
{
313
314 287
        CHECK_OBJ_NOTNULL(sua1, SUCKADDR_MAGIC);
315 287
        CHECK_OBJ_NOTNULL(sua2, SUCKADDR_MAGIC);
316 287
        return (memcmp(sua1, sua2, vsa_suckaddr_len));
317
}
318
319
int
320 21
VSA_Compare_IP(const struct suckaddr *sua1, const struct suckaddr *sua2)
321
{
322
323 21
        assert(VSA_Sane(sua1));
324 21
        assert(VSA_Sane(sua2));
325
326 21
        if (sua1->sa.sa_family != sua2->sa.sa_family)
327 0
                return (-1);
328
329 21
        switch (sua1->sa.sa_family) {
330
        case PF_INET:
331 21
                return (memcmp(&sua1->sa4.sin_addr,
332 21
                    &sua2->sa4.sin_addr, sizeof(struct in_addr)));
333
        case PF_INET6:
334 0
                return (memcmp(&sua1->sa6.sin6_addr,
335 0
                    &sua2->sa6.sin6_addr, sizeof(struct in6_addr)));
336
        default:
337 0
                WRONG("Just plain insane");
338
        }
339
        NEEDLESS(return(-1));
340
}
341
342
struct suckaddr *
343 2957
VSA_Clone(const struct suckaddr *sua)
344
{
345
        struct suckaddr *sua2;
346
347 2957
        assert(VSA_Sane(sua));
348 2957
        sua2 = calloc(1, vsa_suckaddr_len);
349 2957
        XXXAN(sua2);
350 2957
        memcpy(sua2, sua, vsa_suckaddr_len);
351 2957
        return (sua2);
352
}
353
354
unsigned
355 720
VSA_Port(const struct suckaddr *sua)
356
{
357
358 720
        CHECK_OBJ_NOTNULL(sua, SUCKADDR_MAGIC);
359 720
        switch (sua->sa.sa_family) {
360
        case PF_INET:
361 687
                return (ntohs(sua->sa4.sin_port));
362
        case PF_INET6:
363 33
                return (ntohs(sua->sa6.sin6_port));
364
        default:
365 0
                return (0);
366
        }
367
}