varnish-cache/bin/varnishd/cache/cache_vrt.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
 * Runtime support for compiled VCL programs
30
 */
31
32
#include "config.h"
33
34
#include "cache_varnishd.h"
35
36
#include "cache_director.h"
37
#include "cache_objhead.h"
38
#include "vav.h"
39
#include "vcl.h"
40
#include "vrt_obj.h"
41
#include "vsa.h"
42
#include "vtcp.h"
43
#include "vtim.h"
44
45
const void * const vrt_magic_string_end = &vrt_magic_string_end;
46
const void * const vrt_magic_string_unset = &vrt_magic_string_unset;
47
48
/*--------------------------------------------------------------------*/
49
50
void
51 198
VRT_synth(VRT_CTX, unsigned code, const char *reason)
52
{
53
54 198
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
55 198
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
56 198
        if (code < 100)
57 0
                code = 503;
58 198
        ctx->req->err_code = (uint16_t)code;
59 396
        ctx->req->err_reason = reason ? reason
60 198
            : http_Status2Reason(ctx->req->err_code % 1000, NULL);
61 198
}
62
63
/*--------------------------------------------------------------------*/
64
65
void
66 40
VRT_acl_log(VRT_CTX, const char *msg)
67
{
68
69 40
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
70 40
        AN(msg);
71 40
        if (ctx->vsl != NULL)
72 38
                VSLb(ctx->vsl, SLT_VCL_acl, "%s", msg);
73
        else
74 2
                VSL(SLT_VCL_acl, 0, "%s", msg);
75 40
}
76
77
int
78 40
VRT_acl_match(VRT_CTX, VCL_ACL acl, VCL_IP ip)
79
{
80
81 40
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
82 40
        CHECK_OBJ_NOTNULL(acl, VRT_ACL_MAGIC);
83 40
        assert(VSA_Sane(ip));
84 40
        return (acl->match(ctx, ip));
85
}
86
87
void
88 22
VRT_hit_for_pass(VRT_CTX, VCL_DURATION d)
89
{
90
        struct objcore *oc;
91
92 22
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
93 22
        if (ctx->bo == NULL) {
94 2
                VSLb(ctx->vsl, SLT_Error,
95
                    "Note: Ignoring DURATION argument to return(pass);");
96 24
                return;
97
        }
98 20
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
99 20
        oc = ctx->bo->fetch_objcore;
100 20
        oc->ttl = d;
101 20
        oc->grace = 0.0;
102 20
        oc->keep = 0.0;
103 80
        VSLb(ctx->vsl, SLT_TTL, "HFP %.0f %.0f %.0f %.0f",
104 60
            oc->ttl, oc->grace, oc->keep, oc->t_origin);
105
}
106
107
/*--------------------------------------------------------------------*/
108
109
struct http *
110 26621
VRT_selecthttp(VRT_CTX, enum gethdr_e where)
111
{
112
        struct http *hp;
113
114 26621
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
115 26621
        switch (where) {
116
        case HDR_REQ:
117 13045
                hp = ctx->http_req;
118 13045
                break;
119
        case HDR_REQ_TOP:
120 8
                hp = ctx->http_req_top;
121 8
                break;
122
        case HDR_BEREQ:
123 218
                hp = ctx->http_bereq;
124 218
                break;
125
        case HDR_BERESP:
126 9794
                hp = ctx->http_beresp;
127 9794
                break;
128
        case HDR_RESP:
129 3556
                hp = ctx->http_resp;
130 3556
                break;
131
        default:
132 0
                WRONG("VRT_selecthttp 'where' invalid");
133
        }
134 26621
        return (hp);
135
}
136
137
/*--------------------------------------------------------------------*/
138
139
const char *
140 21842
VRT_GetHdr(VRT_CTX, const struct gethdr_s *hs)
141
{
142
        const char *p;
143
        struct http *hp;
144
145 21842
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
146 21842
        if (hs->where == HDR_OBJ) {
147 28
                CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
148 28
                CHECK_OBJ_NOTNULL(ctx->req->objcore, OBJCORE_MAGIC);
149 28
                return(HTTP_GetHdrPack(ctx->req->wrk, ctx->req->objcore,
150
                    hs->what));
151
        }
152 21814
        hp = VRT_selecthttp(ctx, hs->where);
153 21814
        CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
154 21814
        if (!http_GetHdr(hp, hs->what, &p))
155 19221
                return (NULL);
156 2594
        return (p);
157
}
158
159
/*--------------------------------------------------------------------
160
 * Build STRANDS from what is essentially a STRING_LIST
161
 */
162
163
VCL_STRANDS
164 508
VRT_BundleStrands(int n, struct strands *s, char const **d, const char *f, ...)
165
{
166
        va_list ap;
167
168 508
        s->n = n;
169 508
        s->p = d;
170 508
        *d++ = f;
171 508
        va_start(ap, f);
172 1440
        while(--n)
173 424
                *d++ = va_arg(ap, const char *);
174 508
        assert(va_arg(ap, const char *) == vrt_magic_string_end);
175 508
        va_end(ap);
176 508
        return (s);
177
}
178
179
/*--------------------------------------------------------------------
180
 * Compare two STRANDS
181
 */
182
183
int
184 254
VRT_CompareStrands(VCL_STRANDS a, VCL_STRANDS b)
185
{
186 254
        const char *pa = NULL, *pb = NULL;
187 254
        int na = 0, nb = 0;
188
189
        while (1) {
190 1140
                if (pa != NULL && *pa == '\0')
191 170
                        pa = NULL;
192 1140
                if (pb != NULL && *pb == '\0')
193 134
                        pb = NULL;
194 1140
                if (pa == NULL && na < a->n)
195 388
                        pa = a->p[na++];
196 752
                else if (pb == NULL && nb < b->n)
197 364
                        pb = b->p[nb++];
198 388
                else if (pa == NULL && pb == NULL)
199 74
                        return (0);
200 314
                else if (pa == NULL)
201 48
                        return (-1);
202 266
                else if (pb == NULL)
203 24
                        return (1);
204 242
                else if (*pa == '\0')
205 0
                        pa = NULL;
206 242
                else if (*pb == '\0')
207 0
                        pb = NULL;
208 242
                else if (*pa != *pb)
209 108
                        return (*pa - *pb);
210
                else {
211 134
                        pa++;
212 134
                        pb++;
213
                }
214 886
        }
215
}
216
217
/*--------------------------------------------------------------------
218
 * Collapse a STRING_LIST in the space provided, or return NULL
219
 */
220
221
char *
222 4910
VRT_StringList(char *d, unsigned dl, const char *p, va_list ap)
223
{
224
        char *b, *e;
225
        unsigned x;
226
227 4910
        b = d;
228 4910
        e = b + dl;
229 15060
        while (p != vrt_magic_string_end && b < e) {
230 5240
                if (p != NULL && *p != '\0') {
231 4966
                        x = strlen(p);
232 4966
                        if (b + x < e)
233 4942
                                memcpy(b, p, x);
234 4966
                        b += x;
235
                }
236 5240
                p = va_arg(ap, const char *);
237
        }
238 4910
        if (b >= e)
239 62
                return (NULL);
240 4848
        *b++ = '\0';
241 4848
        return (b);
242
}
243
244
/*--------------------------------------------------------------------
245
 * Copy and merge a STRING_LIST into a workspace.
246
 */
247
248
const char *
249 4910
VRT_String(struct ws *ws, const char *h, const char *p, va_list ap)
250
{
251
        char *b, *e;
252
        unsigned u, x;
253
254 4910
        u = WS_Reserve(ws, 0);
255 4910
        e = b = ws->f;
256 4910
        e += u;
257 4910
        if (h != NULL) {
258 4660
                x = strlen(h);
259 4660
                if (b + x < e)
260 4622
                        memcpy(b, h, x);
261 4660
                b += x;
262 4660
                if (b < e)
263 4622
                        *b = ' ';
264 4660
                b++;
265
        }
266 4910
        b = VRT_StringList(b, e > b ? e - b : 0, p, ap);
267 4910
        if (b == NULL || b == e) {
268
                /*
269
                 * NO WS_MarkOverflow here because the caller might have a
270
                 * fallback
271
                 */
272 62
                WS_Release(ws, 0);
273 62
                return (NULL);
274
        }
275 4848
        e = b;
276 4848
        b = ws->f;
277 4848
        WS_Release(ws, e - b);
278 4848
        return (b);
279
}
280
281
/*--------------------------------------------------------------------
282
 * Copy and merge a STRING_LIST on the current workspace
283
 */
284
285
const char *
286 48
VRT_CollectString(VRT_CTX, const char *p, ...)
287
{
288
        va_list ap;
289
        const char *b;
290
291 48
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
292 48
        CHECK_OBJ_NOTNULL(ctx->ws, WS_MAGIC);
293 48
        va_start(ap, p);
294 48
        b = VRT_String(ctx->ws, NULL, p, ap);
295 48
        va_end(ap);
296 48
        return (b);
297
}
298
299
/*--------------------------------------------------------------------*/
300
301
void
302 4786
VRT_SetHdr(VRT_CTX , const struct gethdr_s *hs,
303
    const char *p, ...)
304
{
305
        struct http *hp;
306
        va_list ap;
307
        const char *b;
308
309 4786
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
310 4786
        AN(hs);
311 4786
        AN(hs->what);
312 4786
        hp = VRT_selecthttp(ctx, hs->where);
313 4786
        CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
314 4786
        va_start(ap, p);
315 4786
        if (p == vrt_magic_string_unset) {
316 132
                http_Unset(hp, hs->what);
317
        } else {
318 4654
                b = VRT_String(hp->ws, hs->what + 1, p, ap);
319 4654
                if (b == NULL) {
320 62
                        VSLb(ctx->vsl, SLT_LostHeader, "%s", hs->what + 1);
321
                } else {
322 4592
                        http_Unset(hp, hs->what);
323 4592
                        http_SetHeader(hp, b);
324
                }
325
        }
326 4786
        va_end(ap);
327 4786
}
328
329
/*--------------------------------------------------------------------*/
330
331
void
332 22510
VRT_handling(VRT_CTX, unsigned hand)
333
{
334
335 22510
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
336 22510
        assert(hand > 0);
337 22510
        assert(hand < VCL_RET_MAX);
338
        // XXX:NOTYET assert(*ctx->handling == 0);
339 22510
        *ctx->handling = hand;
340 22510
}
341
342
/*--------------------------------------------------------------------*/
343
344
void
345 176
VRT_fail(VRT_CTX, const char *fmt, ...)
346
{
347
        va_list ap;
348
349 176
        assert(ctx->vsl != NULL || ctx->msg != NULL);
350 176
        AZ(strchr(fmt, '\n'));
351 176
        va_start(ap, fmt);
352 176
        if (ctx->vsl != NULL)
353 148
                VSLbv(ctx->vsl, SLT_VCL_Error, fmt, ap);
354
        else {
355 28
                VSB_vprintf(ctx->msg, fmt, ap);
356 28
                VSB_putc(ctx->msg, '\n');
357
        }
358 176
        va_end(ap);
359 176
        VRT_handling(ctx, VCL_RET_FAIL);
360 176
}
361
362
/*--------------------------------------------------------------------
363
 * Feed data into the hash calculation
364
 */
365
366
void
367 7744
VRT_hashdata(VRT_CTX, const char *str, ...)
368
{
369
        va_list ap;
370
        const char *p;
371
372 7744
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
373 7744
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
374 7744
        AN(ctx->specific);
375 7744
        HSH_AddString(ctx->req, ctx->specific, str);
376 7744
        va_start(ap, str);
377
        while (1) {
378 7752
                p = va_arg(ap, const char *);
379 7752
                if (p == vrt_magic_string_end)
380 7744
                        break;
381 8
                HSH_AddString(ctx->req, ctx->specific, p);
382 8
        }
383 7744
        va_end(ap);
384
        /*
385
         * Add a 'field-separator' to make it more difficult to
386
         * manipulate the hash.
387
         */
388 7744
        HSH_AddString(ctx->req, ctx->specific, NULL);
389 7745
}
390
391
/*--------------------------------------------------------------------*/
392
393
double
394 216
VRT_r_now(VRT_CTX)
395
{
396 216
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
397 216
        return (ctx->now);
398
}
399
400
/*--------------------------------------------------------------------*/
401
402
VCL_STRING v_matchproto_()
403 3926
VRT_IP_string(VRT_CTX, VCL_IP ip)
404
{
405
        char *p;
406
        unsigned len;
407
408 3926
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
409 3926
        if (ip == NULL)
410 0
                return (NULL);
411 3926
        len = WS_Reserve(ctx->ws, 0);
412 3925
        if (len == 0) {
413 0
                WS_Release(ctx->ws, 0);
414 0
                return (NULL);
415
        }
416 3925
        p = ctx->ws->f;
417 3925
        VTCP_name(ip, p, len, NULL, 0);
418 3926
        WS_Release(ctx->ws, strlen(p) + 1);
419 3926
        return (p);
420
}
421
422
VCL_STRING v_matchproto_()
423 1352
VRT_INT_string(VRT_CTX, long num)
424
{
425
426 1352
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
427 1352
        return (WS_Printf(ctx->ws, "%ld", num));
428
}
429
430
VCL_STRING v_matchproto_()
431 318
VRT_REAL_string(VRT_CTX, double num)
432
{
433
434 318
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
435 318
        return (WS_Printf(ctx->ws, "%.3f", num));
436
}
437
438
VCL_STRING v_matchproto_()
439 48
VRT_TIME_string(VRT_CTX, double t)
440
{
441
        char *p;
442
443 48
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
444 48
        p = WS_Alloc(ctx->ws, VTIM_FORMAT_SIZE);
445 48
        if (p != NULL)
446 48
                VTIM_format(t, p);
447 48
        return (p);
448
}
449
450
VCL_STRING v_matchproto_()
451 100
VRT_BACKEND_string(VCL_BACKEND d)
452
{
453 100
        if (d == NULL)
454 0
                return (NULL);
455 100
        CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC);
456 100
        return (d->vcl_name);
457
}
458
459
VCL_STRING v_matchproto_()
460 504
VRT_BOOL_string(unsigned val)
461
{
462
463 504
        return (val ? "true" : "false");
464
}
465
466
/*--------------------------------------------------------------------*/
467
468
void
469 8
VRT_Rollback(VRT_CTX, const struct http *hp)
470
{
471
472 8
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
473 8
        CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
474 8
        if (hp == ctx->http_req) {
475 6
                CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
476 6
                HTTP_Copy(ctx->req->http, ctx->req->http0);
477 6
                WS_Reset(ctx->req->ws, ctx->req->ws_req);
478 2
        } else if (hp == ctx->http_bereq) {
479 2
                CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
480 2
                HTTP_Copy(ctx->bo->bereq, ctx->bo->bereq0);
481 2
                WS_Reset(ctx->bo->bereq->ws, ctx->bo->ws_bo);
482 2
                WS_Reset(ctx->bo->ws, ctx->bo->ws_bo);
483
        } else
484 0
                WRONG("VRT_Rollback 'hp' invalid");
485 8
}
486
487
/*--------------------------------------------------------------------*/
488
489
void
490 20
VRT_synth_page(VRT_CTX, const char *str, ...)
491
{
492
        va_list ap;
493
        const char *p;
494
        struct vsb *vsb;
495
496 20
        CAST_OBJ_NOTNULL(vsb, ctx->specific, VSB_MAGIC);
497 20
        va_start(ap, str);
498 20
        p = str;
499 60
        while (p != vrt_magic_string_end) {
500 20
                if (p == NULL)
501 2
                        p = "(null)";
502 20
                if (VSB_cat(vsb, p)) {
503 0
                        VRT_fail(ctx, "synthetic(): %s",
504
                                 strerror(VSB_error(vsb)));
505 0
                        break;
506
                }
507 20
                p = va_arg(ap, const char *);
508
        }
509 20
        va_end(ap);
510 20
}
511
512
/*--------------------------------------------------------------------*/
513
514
void
515 48
VRT_ban_string(VRT_CTX, const char *str)
516
{
517
        char *a1, *a2, *a3;
518
        char **av;
519
        struct ban_proto *bp;
520
        const char *err;
521
        int i;
522
523 48
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
524 48
        AN(ctx->vsl);
525
526 48
        if (str == NULL) {
527 2
                VSLb(ctx->vsl, SLT_VCL_Error, "ban(): Null argument");
528 2
                return;
529
        }
530
531 46
        bp = BAN_Build();
532 46
        if (bp == NULL) {
533 0
                VSLb(ctx->vsl, SLT_VCL_Error, "ban(): Out of Memory");
534 0
                return;
535
        }
536 46
        av = VAV_Parse(str, NULL, ARGV_NOESC);
537 46
        AN(av);
538 46
        if (av[0] != NULL) {
539 0
                VSLb(ctx->vsl, SLT_VCL_Error, "ban(): %s", av[0]);
540 0
                VAV_Free(av);
541 0
                BAN_Abandon(bp);
542 0
                return;
543
        }
544 46
        for (i = 0; ;) {
545 52
                a1 = av[++i];
546 52
                if (a1 == NULL) {
547 2
                        VSLb(ctx->vsl, SLT_VCL_Error,
548
                            "ban(): No ban conditions found.");
549 2
                        break;
550
                }
551 50
                a2 = av[++i];
552 50
                if (a2 == NULL) {
553 2
                        VSLb(ctx->vsl, SLT_VCL_Error,
554
                            "ban(): Expected comparison operator.");
555 2
                        break;
556
                }
557 48
                a3 = av[++i];
558 48
                if (a3 == NULL) {
559 2
                        VSLb(ctx->vsl, SLT_VCL_Error,
560
                            "ban(): Expected second operand.");
561 2
                        break;
562
                }
563 46
                err = BAN_AddTest(bp, a1, a2, a3);
564 46
                if (err) {
565 4
                        VSLb(ctx->vsl, SLT_VCL_Error, "ban(): %s", err);
566 4
                        break;
567
                }
568 42
                if (av[++i] == NULL) {
569 34
                        err = BAN_Commit(bp);
570 34
                        if (err == NULL)
571 34
                                bp = NULL;
572
                        else
573 0
                                VSLb(ctx->vsl, SLT_VCL_Error, "ban(): %s", err);
574 34
                        break;
575
                }
576 8
                if (strcmp(av[i], "&&")) {
577 2
                        VSLb(ctx->vsl, SLT_VCL_Error,
578
                            "ban(): Expected && between conditions,"
579 2
                            " found \"%s\"", av[i]);
580 2
                        break;
581
                }
582 6
        }
583 46
        if (bp != NULL)
584 12
                BAN_Abandon(bp);
585 46
        VAV_Free(av);
586
}
587
588
VCL_BYTES
589 20
VRT_CacheReqBody(VRT_CTX, VCL_BYTES maxsize)
590
{
591
592 20
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
593 20
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
594 20
        if (ctx->method != VCL_MET_RECV) {
595 0
                VSLb(ctx->vsl, SLT_VCL_Error,
596
                    "req.body can only be cached in vcl_recv{}");
597 0
                return (-1);
598
        }
599 20
        return (VRB_Cache(ctx->req, maxsize));
600
}
601
602
/*--------------------------------------------------------------------
603
 * purges
604
 */
605
606
unsigned
607 28
VRT_purge(VRT_CTX, double ttl, double grace, double keep)
608
{
609
610 28
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
611
612 28
        if ((ctx->method & (VCL_MET_HIT|VCL_MET_MISS)) == 0) {
613 18
                VSLb(ctx->vsl, SLT_VCL_Error,
614
                    "purge can only happen in vcl_hit{} or vcl_miss{}");
615 18
                VRT_handling(ctx, VCL_RET_FAIL);
616 18
                return (0);
617
        }
618
619 10
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
620 10
        CHECK_OBJ_NOTNULL(ctx->req->wrk, WORKER_MAGIC);
621 10
        return (HSH_Purge(ctx->req->wrk, ctx->req->objcore->objhead,
622
            ttl, grace, keep));
623
}
624
625
/*--------------------------------------------------------------------
626
 * Simple stuff
627
 */
628
629
int
630 16208
VRT_strcmp(const char *s1, const char *s2)
631
{
632 16208
        if (s1 == NULL || s2 == NULL)
633 1730
                return(1);
634 14478
        return (strcmp(s1, s2));
635
}
636
637
void
638 0
VRT_memmove(void *dst, const void *src, unsigned len)
639
{
640
641 0
        (void)memmove(dst, src, len);
642 0
}
643
644
int
645 42
VRT_ipcmp(const struct suckaddr *sua1, const struct suckaddr *sua2)
646
{
647 42
        if (sua1 == NULL || sua2 == NULL)
648 0
                return(1);
649 42
        return (VSA_Compare_IP(sua1, sua2));
650
}
651
652
struct vmod_priv *
653 4
VRT_blob(VRT_CTX, const char *err, const uint8_t *src, size_t len)
654
{
655
        struct vmod_priv *p;
656
        void *d;
657
658 4
        p = (void *)WS_Alloc(ctx->ws, sizeof *p);
659 4
        d = WS_Copy(ctx->ws, src, len);
660 4
        if (p == NULL || d == NULL) {
661 0
                VRT_fail(ctx, "Workspace overflow (%s)", err);
662 0
                return (NULL);
663
        }
664 4
        memset(p, 0, sizeof *p);
665 4
        p->len = len;
666 4
        p->priv = d;
667 4
        return (p);
668
}