vinyl-cache/bin/vinyld/cache/cache_vrt_var.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
 * Runtime support for compiled VCL programs
31
 */
32
#include "config.h"
33
34
#include <stdio.h>
35
36
#include "cache_int.h"
37
#include "cache_objhead.h"
38
#include "cache_transport.h"
39
#include "storage/storage.h"
40
#include "common/heritage.h"
41
42
#include "vcl.h"
43
#include "vtim.h"
44
#include "vtcp.h"
45
46
#include "vrt_obj.h"
47
48
#define VRT_TMO(tmo) (isinf(tmo) ? VRT_DECIMAL_MAX : tmo)
49
50
static char vrt_hostname[255] = "";
51
const char *retry_disabled = "disabled from VCL";
52
53
/*--------------------------------------------------------------------
54
 * VRT variables relating to first line of HTTP/1.1 req/resp
55
 */
56
57
static void
58 1575
vrt_do_strands(VRT_CTX, struct http *hp, int fld,
59
    const char *err, const char *str, VCL_STRANDS s)
60
{
61
        const char *b;
62
63 1575
        CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
64
65 1575
        b = VRT_StrandsWS(hp->ws, str, s);
66 1575
        if (b == NULL) {
67 0
                VRT_fail(ctx, "Workspace overflow (%s)", err);
68 0
                WS_MarkOverflow(hp->ws);
69 0
                return;
70
        }
71 1575
        if (*b == '\0') {
72 63
                VRT_fail(ctx, "Setting %s to empty string", err);
73 63
                return;
74
        }
75 1512
        http_SetH(hp, fld, b);
76 1575
}
77
78
#define VRT_HDR_L(obj, hdr, fld)                                        \
79
VCL_VOID                                                                \
80
VRT_l_##obj##_##hdr(VRT_CTX, const char *str, VCL_STRANDS s)            \
81
{                                                                       \
82
                                                                        \
83
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
84
        vrt_do_strands(ctx, ctx->http_##obj, fld, #obj "." #hdr, str, s);       \
85
}
86
87
#define VRT_HDR_R(obj, hdr, fld)                                        \
88
VCL_STRING                                                              \
89
VRT_r_##obj##_##hdr(VRT_CTX)                                            \
90
{                                                                       \
91
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
92
        CHECK_OBJ_NOTNULL(ctx->http_##obj, HTTP_MAGIC);                 \
93
        return (ctx->http_##obj->hd[fld].b);                            \
94
}
95
96
#define VRT_HDR_LR(obj, hdr, fld)                                       \
97
        VRT_HDR_L(obj, hdr, fld)                                        \
98
        VRT_HDR_R(obj, hdr, fld)
99
100
#define VRT_STATUS_L(obj)                                               \
101
VCL_VOID                                                                \
102
VRT_l_##obj##_status(VRT_CTX, VCL_INT num)                              \
103
{                                                                       \
104
                                                                        \
105
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
106
        CHECK_OBJ_NOTNULL(ctx->http_##obj, HTTP_MAGIC);                 \
107
        if (num < 0)                                                    \
108
                VRT_fail(ctx, "%s.status (%jd) is negative",            \
109
                    #obj, (intmax_t)num);                               \
110
        else if (num > 65535)                                           \
111
                VRT_fail(ctx, "%s.status (%jd) > 65535",                \
112
                    #obj, (intmax_t)num);                               \
113
        else if ((num % 1000) < 100)                                    \
114
                VRT_fail(ctx, "illegal %s.status (%jd) (..0##)",        \
115
                    #obj, (intmax_t)num);                               \
116
        else                                                            \
117
                http_SetStatus(ctx->http_##obj, (uint16_t)num, NULL);   \
118
}
119
120
#define VRT_STATUS_R(obj)                                               \
121
VCL_INT                                                                 \
122
VRT_r_##obj##_status(VRT_CTX)                                           \
123
{                                                                       \
124
                                                                        \
125
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
126
        CHECK_OBJ_NOTNULL(ctx->http_##obj, HTTP_MAGIC);                 \
127
        return (ctx->http_##obj->status);                               \
128
}
129
130 176317
VRT_HDR_LR(req,    method,      HTTP_HDR_METHOD)
131 217118
VRT_HDR_LR(req,    url,         HTTP_HDR_URL)
132 2636
VRT_HDR_LR(req,    proto,       HTTP_HDR_PROTO)
133
134 126
VRT_HDR_R(req0,    method,      HTTP_HDR_METHOD)
135 126
VRT_HDR_R(req0,    url,         HTTP_HDR_URL)
136 126
VRT_HDR_R(req0,    proto,       HTTP_HDR_PROTO)
137
138 84
VRT_HDR_R(req_top,    method,   HTTP_HDR_METHOD)
139 84
VRT_HDR_R(req_top,    url,      HTTP_HDR_URL)
140 84
VRT_HDR_R(req_top,    proto,    HTTP_HDR_PROTO)
141
142 84
VRT_HDR_LR(resp,   proto,       HTTP_HDR_PROTO)
143 27636
VRT_HDR_LR(resp,   reason,      HTTP_HDR_REASON)
144 945
VRT_STATUS_L(resp)
145 19005
VRT_STATUS_R(resp)
146
147 51597
VRT_HDR_LR(bereq,  method,      HTTP_HDR_METHOD)
148 12684
VRT_HDR_LR(bereq,  url,         HTTP_HDR_URL)
149 63
VRT_HDR_LR(bereq,  proto,       HTTP_HDR_PROTO)
150 43617
VRT_HDR_LR(beresp, proto,       HTTP_HDR_PROTO)
151 19719
VRT_HDR_LR(beresp, reason,      HTTP_HDR_REASON)
152 2604
VRT_STATUS_L(beresp)
153 100652
VRT_STATUS_R(beresp)
154
155
/*--------------------------------------------------------------------
156
 * beresp bool-fields
157
 */
158
159
static inline int
160 8001
beresp_filter_fixed(VRT_CTX, const char *s)
161
{
162 8001
        if (ctx->bo->vfp_filter_list == NULL)
163 7980
                return (0);
164 42
        VRT_fail(ctx,
165 21
            "beresp.filters are already fixed, beresp.%s is undefined", s);
166 21
        return (1);
167 8001
}
168
169
#define VBERESPWF0(ctx, str) (void) 0
170
#define VBERESPWF1(ctx, str) do {               \
171
        if (beresp_filter_fixed((ctx), str))    \
172
                return;                 \
173
        } while(0)
174
175
#define VBERESPW0(field, str, fltchk)
176
#define VBERESPW1(field, str, fltchk)                                   \
177
void                                                                    \
178
VRT_l_beresp_##field(VRT_CTX, VCL_BOOL a)                               \
179
{                                                                       \
180
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
181
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);                      \
182
        VBERESPWF##fltchk(ctx, str);                                    \
183
        ctx->bo->field = a ? 1 : 0;                                     \
184
}
185
186
#define VBERESPRF0(ctx, str) (void) 0
187
#define VBERESPRF1(ctx, str) do {               \
188
        if (beresp_filter_fixed((ctx), str))    \
189
                return (0);                     \
190
        } while(0)
191
192
#define VBERESPR1(field, str, fltchk)                                   \
193
VCL_BOOL                                                                \
194
VRT_r_beresp_##field(VRT_CTX)                                           \
195
{                                                                       \
196
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
197
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);                      \
198
        VBERESPRF##fltchk(ctx, str);                                    \
199
        return (ctx->bo->field);                                        \
200
}
201
202
#define BERESP_FLAG(l, r, w, f, d)              \
203
        VBERESPR##r(l, #l, f)                   \
204
        VBERESPW##w(l, #l, f)
205
#include "tbl/beresp_flags.h"
206
207
#undef VBERESPWF0
208
#undef VBERESPWF1
209
#undef VBERESPW0
210
#undef VBERESPW1
211
212
#undef VBERESPRF0
213
#undef VBERESPRF1
214
#undef VBERESPR1
215
216
/*--------------------------------------------------------------------
217
 * bereq bool-fields
218
 *
219
 * for macro compatiblity with the client side, r is "req" for bereq
220
 */
221
222
#define VBEREQR0(field, str)
223
#define VBEREQRreq(field, str)                                          \
224
VCL_BOOL                                                                \
225
VRT_r_bereq_##field(VRT_CTX)                                            \
226
{                                                                       \
227
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
228
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);                      \
229
        return (ctx->bo->field);                                        \
230
}
231
232
#define BEREQ_FLAG(l, r, w, d)          \
233
        VBEREQR##r(l, #l)
234
#include "tbl/bereq_flags.h"
235
236
#undef VBEREQR0
237
#undef VBEREQRreq
238
/*--------------------------------------------------------------------*/
239
240
VCL_BOOL
241 43638
VRT_r_bereq_uncacheable(VRT_CTX)
242
{
243 43638
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
244 43638
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
245 43638
        return (ctx->bo->uncacheable);
246
}
247
248
VCL_VOID
249 1995
VRT_l_beresp_uncacheable(VRT_CTX, VCL_BOOL a)
250
{
251
        struct objcore *oc;
252
253 1995
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
254 1995
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
255 1995
        CHECK_OBJ_NOTNULL(ctx->bo->fetch_objcore, OBJCORE_MAGIC);
256
257 1995
        if (ctx->bo->uncacheable && !a) {
258 0
                VSLb(ctx->vsl, SLT_VCL_Error,
259
                    "Ignoring attempt to reset beresp.uncacheable");
260 1995
        } else if (a) {
261 1974
                ctx->bo->uncacheable = 1;
262 1974
        }
263 1995
        oc = ctx->bo->fetch_objcore;
264
265 3990
        VSLb(ctx->vsl, SLT_TTL, "VCL %.0f %.0f %.0f %.0f %s",   \
266 1995
            oc->ttl, oc->grace, oc->keep, oc->t_origin,         \
267 3990
            ctx->bo->uncacheable ? "uncacheable" : "cacheable");\
268
}
269
270
VCL_BOOL
271 21
VRT_r_beresp_uncacheable(VRT_CTX)
272
{
273 21
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
274 21
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
275 21
        return (ctx->bo->uncacheable);
276
}
277
278
VCL_VOID
279 21
VRT_l_req_trace(VRT_CTX, VCL_BOOL a)
280
{
281 21
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
282 21
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
283 21
        ctx->req->trace = a;
284 21
        VRT_trace(ctx, a);
285 21
}
286
VCL_VOID
287 0
VRT_l_bereq_trace(VRT_CTX, VCL_BOOL a)
288
{
289 0
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
290 0
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
291 0
        ctx->bo->trace = a;
292 0
        VRT_trace(ctx, a);
293 0
}
294
295
/*--------------------------------------------------------------------*/
296
297
VCL_BYTES
298 0
VRT_r_beresp_transit_buffer(VRT_CTX)
299
{
300
    struct objcore *oc;
301
302 0
    CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
303 0
    CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
304
305 0
    oc = ctx->bo->fetch_objcore;
306 0
    CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
307
308 0
    return oc->boc->transit_buffer;
309
}
310
311
VCL_VOID
312 42
VRT_l_beresp_transit_buffer(VRT_CTX, VCL_BYTES value)
313
{
314
    struct objcore *oc;
315
316 42
    CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
317 42
    CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
318
319 42
    oc = ctx->bo->fetch_objcore;
320 42
    CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
321
322 42
    oc->boc->transit_buffer = value;
323 42
}
324
325
/*--------------------------------------------------------------------*/
326
327
VCL_STRING
328 126
VRT_r_client_identity(VRT_CTX)
329
{
330
        const char *id;
331
332 126
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
333 126
        if (ctx->req != NULL) {
334 84
                CHECK_OBJ(ctx->req, REQ_MAGIC);
335 84
                id = ctx->req->client_identity;
336 84
        } else {
337 42
                CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
338 42
                id = ctx->bo->client_identity;
339
        }
340 126
        if (id != NULL)
341 84
                return (id);
342 42
        return (SES_Get_String_Attr(ctx->sp, SA_CLIENT_IP));
343 126
}
344
345
VCL_VOID
346 63
VRT_l_client_identity(VRT_CTX, const char *str, VCL_STRANDS s)
347
{
348
        const char *b;
349
350 63
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
351 63
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
352 63
        b = VRT_StrandsWS(ctx->req->http->ws, str, s);
353 63
        if (b == NULL) {
354 0
                VSLb(ctx->vsl, SLT_LostHeader, "client.identity");
355 0
                WS_MarkOverflow(ctx->req->http->ws);
356 0
                return;
357
        }
358 63
        ctx->req->client_identity = b;
359 63
}
360
361
/*--------------------------------------------------------------------*/
362
363
#define BEREQ_TIMEOUT(prefix, which)                            \
364
VCL_VOID                                                        \
365
VRT_l_bereq_##which(VRT_CTX, VCL_DURATION num)                  \
366
{                                                               \
367
                                                                \
368
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                  \
369
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);              \
370
        ctx->bo->which = num;                                   \
371
}                                                               \
372
                                                                \
373
VCL_DURATION                                                    \
374
VRT_r_bereq_##which(VRT_CTX)                                    \
375
{                                                               \
376
        vtim_dur res;                                           \
377
                                                                \
378
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                  \
379
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);              \
380
        res = BUSYOBJ_TMO(ctx->bo, prefix, which);              \
381
        return (VRT_TMO(res));                                  \
382
}                                                               \
383
                                                                \
384
VCL_VOID                                                        \
385
VRT_u_bereq_##which(VRT_CTX)                                    \
386
{                                                               \
387
                                                                \
388
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                  \
389
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);              \
390
        ctx->bo->which = NAN;                                   \
391
}
392
393 147
BEREQ_TIMEOUT(, connect_timeout)
394 189
BEREQ_TIMEOUT(, first_byte_timeout)
395 294
BEREQ_TIMEOUT(, between_bytes_timeout)
396 189
BEREQ_TIMEOUT(pipe_, task_deadline)
397
398
399
/*--------------------------------------------------------------------*/
400
401
VCL_STRING
402 21
VRT_r_beresp_backend_name(VRT_CTX)
403
{
404
405 21
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
406 21
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
407 21
        if (ctx->bo->director_resp != NULL)
408 21
                return (ctx->bo->director_resp->vcl_name);
409 0
        return (NULL);
410 21
}
411
412
/*--------------------------------------------------------------------
413
 * Backends do not in general have a IP number (any more) and this
414
 * variable is really not about the backend, but the backend connection.
415
 * XXX: we may need a more general beresp.backend.{details|ident}
416
 */
417
418
VCL_IP
419 21
VRT_r_beresp_backend_ip(VRT_CTX)
420
{
421
422 21
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
423 21
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
424 21
        return (VDI_GetIP(ctx->bo));
425
}
426
427
/*--------------------------------------------------------------------*/
428
429
VCL_STEVEDORE
430 21
VRT_r_req_storage(VRT_CTX)
431
{
432 21
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
433 21
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
434 21
        return (ctx->req->storage);
435
}
436
437
VCL_VOID
438 147
VRT_l_req_storage(VRT_CTX, VCL_STEVEDORE stv)
439
{
440 147
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
441 147
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
442 147
        ctx->req->storage = stv;
443 147
}
444
445
/*--------------------------------------------------------------------*/
446
447
VCL_STEVEDORE
448 63
VRT_r_resp_storage(VRT_CTX)
449
{
450
        struct objcore *oc;
451
452 63
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
453 63
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
454 63
        oc = ctx->req->objcore;
455 63
        if (oc == NULL)
456 21
                VRT_l_resp_storage(ctx, NULL);
457 63
        oc = ctx->req->objcore;
458 63
        if (oc == NULL)
459 21
                return (NULL);
460 42
        CHECK_OBJ(oc, OBJCORE_MAGIC);
461 42
        return (oc->stobj->stevedore);
462 63
}
463
464
VCL_VOID
465 10059
VRT_l_resp_storage(VRT_CTX, VCL_STEVEDORE stv)
466
{
467
468 10059
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
469 10059
        if (stv == NULL)
470 9975
                stv = stv_synth;
471 10059
        if (! Resp_l_storage(ctx->req, stv))
472 42
                VRT_fail(ctx, "Storage %s failed", stv->vclname);
473 10059
}
474
475
/*--------------------------------------------------------------------*/
476
477
VCL_STEVEDORE
478 189
VRT_r_beresp_storage(VRT_CTX)
479
{
480 189
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
481 189
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
482 189
        return (ctx->bo->storage);
483
}
484
485
VCL_VOID
486 546
VRT_l_beresp_storage(VRT_CTX, VCL_STEVEDORE stv)
487
{
488 546
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
489 546
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
490 546
        ctx->bo->storage = stv;
491 546
}
492
493
/*--------------------------------------------------------------------*/
494
495
#define VRT_OC_VAR_R(obj, which, which_magic, field)            \
496
VCL_STEVEDORE                                                   \
497
VRT_r_##obj##_storage(VRT_CTX)                                  \
498
{                                                               \
499
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                  \
500
        CHECK_OBJ_NOTNULL(ctx->which, which_magic);             \
501
        CHECK_OBJ_NOTNULL(ctx->which->field, OBJCORE_MAGIC);    \
502
        AN(ctx->which->field->stobj);                           \
503
        CHECK_OBJ_NOTNULL(ctx->which->field->stobj->stevedore,  \
504
            STEVEDORE_MAGIC);                                   \
505
        return (ctx->which->field->stobj->stevedore);           \
506
}                                                               \
507
                                                                \
508
VCL_BOOL                                                        \
509
VRT_r_##obj##_can_esi(VRT_CTX)                                  \
510
{                                                               \
511
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                  \
512
        CHECK_OBJ_NOTNULL(ctx->which, which_magic);             \
513
        CHECK_OBJ_NOTNULL(ctx->which->field, OBJCORE_MAGIC);    \
514
        return (ObjHasAttr(ctx->which->wrk, ctx->which->field,  \
515
            OA_ESIDATA));                                       \
516
}                                                               \
517
                                                                \
518
VCL_BOOL                                                        \
519
VRT_r_##obj##_uncacheable(VRT_CTX)                              \
520
{                                                               \
521
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                  \
522
        CHECK_OBJ_NOTNULL(ctx->which, which_magic);             \
523
        CHECK_OBJ_NOTNULL(ctx->which->field, OBJCORE_MAGIC);    \
524
                                                                \
525
        return (ctx->which->field->flags & OC_F_HFM ? 1 : 0);   \
526
}                                                               \
527
                                                                \
528
VCL_INT                                                         \
529
VRT_r_##obj##_status(VRT_CTX)                                   \
530
{                                                               \
531
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                  \
532
        CHECK_OBJ_NOTNULL(ctx->which, which_magic);             \
533
        CHECK_OBJ_NOTNULL(ctx->which->field, OBJCORE_MAGIC);    \
534
                                                                \
535
        return (HTTP_GetStatusPack(ctx->which->wrk,             \
536
            ctx->which->field));                                \
537
}                                                               \
538
                                                                \
539
VCL_STRING                                                      \
540
VRT_r_##obj##_proto(VRT_CTX)                                    \
541
{                                                               \
542
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                  \
543
        CHECK_OBJ_NOTNULL(ctx->which, which_magic);             \
544
        CHECK_OBJ_NOTNULL(ctx->which->field, OBJCORE_MAGIC);    \
545
                                                                \
546
        return (HTTP_GetHdrPack(ctx->which->wrk,                \
547
            ctx->which->field, H__Proto));                      \
548
}                                                               \
549
                                                                \
550
VCL_STRING                                                      \
551
VRT_r_##obj##_reason(VRT_CTX)                                   \
552
{                                                               \
553
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                  \
554
        CHECK_OBJ_NOTNULL(ctx->which, which_magic);             \
555
        CHECK_OBJ_NOTNULL(ctx->which->field, OBJCORE_MAGIC);    \
556
                                                                \
557
        return (HTTP_GetHdrPack(ctx->which->wrk,                \
558
            ctx->which->field, H__Reason));                     \
559
}
560
561 462
VRT_OC_VAR_R(obj, req, REQ_MAGIC, objcore)
562 798
VRT_OC_VAR_R(obj_stale, bo, BUSYOBJ_MAGIC, stale_oc)
563
564
/*--------------------------------------------------------------------*/
565
566
#define REQ_VAR_L(nm, elem, type, extra)                                \
567
                                                                        \
568
VCL_VOID                                                                \
569
VRT_l_req_##nm(VRT_CTX, type arg)                                       \
570
{                                                                       \
571
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
572
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);                         \
573
        extra;                                                          \
574
        ctx->req->elem = arg;                                           \
575
}
576
577
#define REQ_VAR_R(nm, elem, type)                                       \
578
                                                                        \
579
type                                                                    \
580
VRT_r_req_##nm(VRT_CTX)                                                 \
581
{                                                                       \
582
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
583
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);                         \
584
        return (ctx->req->elem);                                        \
585
}
586
587
#define REQ_VAR_U(nm, elem, val)                                        \
588
                                                                        \
589
VCL_VOID                                                                \
590
VRT_u_req_##nm(VRT_CTX)                                                 \
591
{                                                                       \
592
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
593
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);                         \
594
        ctx->req->elem = val;                                           \
595
}
596
597 336
REQ_VAR_R(backend_hint, director_hint, VCL_BACKEND)
598
599 219
REQ_VAR_L(max_age, d_ttl, VCL_DURATION, if (!(arg>0.0)) arg = 0;)
600 126
REQ_VAR_R(max_age, d_ttl, VCL_DURATION)
601 0
REQ_VAR_U(max_age, d_ttl, -1)
602 63
REQ_VAR_L(grace, d_grace, VCL_DURATION, if (!(arg>0.0)) arg = 0;)
603 189
REQ_VAR_R(grace, d_grace, VCL_DURATION)
604 21
REQ_VAR_U(grace, d_grace, -1)
605
606
// deprecated, to be removed
607 0
VCL_VOID VRT_l_req_ttl(VRT_CTX, VCL_DURATION arg) { VRT_l_req_max_age(ctx, arg); }
608 0
VCL_DURATION VRT_r_req_ttl(VRT_CTX) { return (VRT_r_req_max_age(ctx)); }
609 0
VCL_VOID VRT_u_req_ttl(VRT_CTX) { VRT_u_req_max_age(ctx); }
610
611
VCL_VOID
612 3171
VRT_l_req_backend_hint(VRT_CTX, VCL_BACKEND be)
613
{
614
615 3171
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
616 3171
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
617 3171
        VRT_Assign_Backend(&ctx->req->director_hint, be);
618 3171
}
619
620
/*--------------------------------------------------------------------*/
621
622
VCL_VOID
623 5732
VRT_l_bereq_backend(VRT_CTX, VCL_BACKEND be)
624
{
625
626 5732
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
627 5732
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
628 5732
        VRT_Assign_Backend(&ctx->bo->director_req, be);
629 5732
}
630
631
VCL_BACKEND
632 966
VRT_r_bereq_backend(VRT_CTX)
633
{
634
635 966
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
636 966
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
637 966
        return (ctx->bo->director_req);
638
}
639
640
VCL_BACKEND
641 819
VRT_r_beresp_backend(VRT_CTX)
642
{
643
644 819
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
645 819
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
646 819
        return (ctx->bo->director_resp);
647
}
648
649
/*--------------------------------------------------------------------*/
650
651
VCL_VOID
652 46262
VRT_u_bereq_body(VRT_CTX)
653
{
654 46262
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
655 46262
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
656
657 46262
        http_Unset(ctx->bo->bereq, H_Content_Length);
658
659 46262
        if (ctx->bo->bereq_body != NULL)
660 105
                (void)HSH_DerefObjCore(ctx->bo->wrk, &ctx->bo->bereq_body);
661
662 46262
        if (ctx->bo->req != NULL) {
663 167
                CHECK_OBJ(ctx->bo->req, REQ_MAGIC);
664 167
                VBO_SetState(ctx->bo->wrk, ctx->bo, BOS_REQ_DONE);
665 167
                AZ(ctx->bo->req);
666 167
        }
667 46262
}
668
669
/*--------------------------------------------------------------------*/
670
671
VCL_VOID
672 231
VRT_l_req_esi(VRT_CTX, VCL_BOOL process_esi)
673
{
674
675 231
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
676 231
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
677 231
        assert(ctx->syntax <= 40);
678
        /*
679
         * Only allow you to turn of esi in the main request
680
         * else everything gets confused
681
         * NOTE: this is not true, but we do not change behavior
682
         * for vcl 4.0. For 4.1, see VRT_l_resp_do_esi()
683
         */
684 231
        if (IS_TOPREQ(ctx->req))
685 147
                ctx->req->disable_esi = !process_esi;
686 231
}
687
688
VCL_BOOL
689 63
VRT_r_req_esi(VRT_CTX)
690
{
691
692 63
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
693 63
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
694 63
        assert(ctx->syntax <= 40);
695 63
        return (!ctx->req->disable_esi);
696
}
697
698
VCL_INT
699 4845
VRT_r_req_esi_level(VRT_CTX)
700
{
701
702 4845
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
703 4845
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
704 4845
        return (ctx->req->esi_level);
705
}
706
707
/*--------------------------------------------------------------------*/
708
709
VCL_BOOL
710 168
VRT_r_req_can_gzip(VRT_CTX)
711
{
712
713 168
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
714 168
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
715 168
        return (RFC2616_Req_Gzip(ctx->req->http));      // XXX ?
716
}
717
718
/*--------------------------------------------------------------------*/
719
720
VCL_INT
721 3054
VRT_r_req_restarts(VRT_CTX)
722
{
723
724 3054
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
725 3054
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
726 3054
        return (ctx->req->restarts);
727
}
728
729
VCL_INT
730 1407
VRT_r_bereq_retries(VRT_CTX)
731
{
732
733 1407
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
734 1407
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
735 1407
        return (ctx->bo->retries);
736
}
737
738
VCL_VOID
739 147
VRT_l_bereq_retry_connect(VRT_CTX, VCL_BOOL b)
740
{
741
742 147
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
743 147
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
744
745 147
        if (!b && ctx->bo->no_retry == NULL)
746 84
                ctx->bo->no_retry = retry_disabled;
747 63
        else if (b && ctx->bo->no_retry == retry_disabled)
748 0
                ctx->bo->no_retry = NULL;
749 147
}
750
751
VCL_BOOL
752 0
VRT_r_bereq_retry_connect(VRT_CTX)
753
{
754
755 0
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
756 0
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
757 0
        return (ctx->bo->no_retry == NULL);
758
}
759
760
/*--------------------------------------------------------------------*/
761
762
VCL_STRING
763 357
VRT_r_req_transport(VRT_CTX)
764
{
765 357
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
766
767 357
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
768 357
        CHECK_OBJ_NOTNULL(ctx->req->transport, TRANSPORT_MAGIC);
769 357
        return (ctx->req->transport->name);
770
}
771
772
/*--------------------------------------------------------------------
773
 * In exp.*:
774
 *      t_origin is absolute
775
 *      ttl is relative to t_origin
776
 *      grace&keep are relative to ttl
777
 * In VCL:
778
 *      ttl is relative to "ttl_now", which is t_req on the client
779
 *      side, except in vcl_deliver, where it is ctx->now. On the
780
 *      fetch side "ttl_now" is ctx->now (which is bo->t_prev).
781
 *      grace&keep are relative to ttl
782
 */
783
784
static double
785 32634
ttl_now(VRT_CTX)
786
{
787 32634
        if (ctx->bo) {
788 32046
                return (ctx->now);
789
        } else {
790 588
                CHECK_OBJ(ctx->req, REQ_MAGIC);
791 588
                return (ctx->method == VCL_MET_DELIVER
792 588
                    ? ctx->now : ctx->req->t_req);
793
        }
794 32634
}
795
796
#define VRT_DO_EXP_L(which, oc, fld, offset)                    \
797
                                                                \
798
VCL_VOID                                                        \
799
VRT_l_##which##_##fld(VRT_CTX, VCL_DURATION a)                  \
800
{                                                               \
801
                                                                \
802
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                  \
803
        a += (offset);                                          \
804
        if (a < 0.0)                                            \
805
                a = 0.0;                                        \
806
        oc->fld = a;                                            \
807
        VSLb(ctx->vsl, SLT_TTL, "VCL %.0f %.0f %.0f %.0f %s",   \
808
            oc->ttl, oc->grace, oc->keep, oc->t_origin,         \
809
            ctx->bo->uncacheable ? "uncacheable" : "cacheable");\
810
}
811
812
#define VRT_DO_EXP_R(which, oc, fld, offset)                    \
813
                                                                \
814
VCL_DURATION                                                    \
815
VRT_r_##which##_##fld(VRT_CTX)                                  \
816
{                                                               \
817
        double d;                                               \
818
                                                                \
819
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                  \
820
        d = oc->fld;                                            \
821
        if (d <= 0.0)                                           \
822
                d = 0.0;                                        \
823
        d -= (offset);                                          \
824
        return (d);                                             \
825
}
826
827
/*lint -save -e835 */   // Zero right hand arg to '-'
828
829 21
VRT_DO_EXP_R(obj_stale, ctx->bo->stale_oc, ttl,
830
    ttl_now(ctx) - ctx->bo->stale_oc->t_origin)
831 420
VRT_DO_EXP_R(obj, ctx->req->objcore, ttl,
832
    ttl_now(ctx) - ctx->req->objcore->t_origin)
833 21
VRT_DO_EXP_R(obj_stale, ctx->bo->stale_oc, grace, 0)
834 210
VRT_DO_EXP_R(obj, ctx->req->objcore, grace, 0)
835 21
VRT_DO_EXP_R(obj_stale, ctx->bo->stale_oc, keep, 0)
836 147
VRT_DO_EXP_R(obj, ctx->req->objcore, keep, 0)
837 5544
VRT_DO_EXP_L(beresp, ctx->bo->fetch_objcore, ttl,
838
    ttl_now(ctx) - ctx->bo->fetch_objcore->t_origin)
839 26439
VRT_DO_EXP_R(beresp, ctx->bo->fetch_objcore, ttl,
840
    ttl_now(ctx) - ctx->bo->fetch_objcore->t_origin)
841
842 2814
VRT_DO_EXP_L(beresp, ctx->bo->fetch_objcore, grace, 0)
843 126
VRT_DO_EXP_R(beresp, ctx->bo->fetch_objcore, grace, 0)
844 1722
VRT_DO_EXP_L(beresp, ctx->bo->fetch_objcore, keep, 0)
845 21
VRT_DO_EXP_R(beresp, ctx->bo->fetch_objcore, keep, 0)
846
847
/*lint -restore */
848
849
// XXX more assertions?
850
#define VRT_DO_TIME_R(which, where, field)                              \
851
                                                                        \
852
VCL_TIME                                                                \
853
VRT_r_##which##_time(VRT_CTX)                                           \
854
{                                                                       \
855
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
856
        AN((ctx)->where);                                               \
857
                                                                        \
858
        return ((ctx)->where->field);                                   \
859
}
860
861 189
VRT_DO_TIME_R(req, req, t_req)
862 84
VRT_DO_TIME_R(req_top, req->top->topreq, t_req)
863 84
VRT_DO_TIME_R(resp, req, t_resp)
864 126
VRT_DO_TIME_R(bereq, bo, t_first)
865 42
VRT_DO_TIME_R(beresp, bo, t_resp)
866 42
VRT_DO_TIME_R(obj, req->objcore, t_origin)
867 21
VRT_DO_TIME_R(obj_stale, bo->stale_oc, t_origin)
868
869
/*--------------------------------------------------------------------
870
 */
871
872
#define VRT_DO_AGE_R(which, oc)                                 \
873
                                                                \
874
VCL_DURATION                                                    \
875
VRT_r_##which##_##age(VRT_CTX)                                  \
876
{                                                               \
877
                                                                \
878
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                  \
879
        return (ttl_now(ctx) - oc->t_origin);                   \
880
}
881
882 21
VRT_DO_AGE_R(obj_stale, ctx->bo->stale_oc)
883 168
VRT_DO_AGE_R(obj, ctx->req->objcore)
884 21
VRT_DO_AGE_R(beresp, ctx->bo->fetch_objcore)
885
886
/*--------------------------------------------------------------------
887
 * [[be]req|sess].xid
888
 */
889
890
VCL_INT
891 13419
VRT_r_req_xid(VRT_CTX)
892
{
893
894 13419
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
895 13419
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
896 13419
        CHECK_OBJ_NOTNULL(ctx->req->http, HTTP_MAGIC);
897 13419
        AN(ctx->req->vsl);
898 13419
        return (VXID(ctx->req->vsl->wid));
899
}
900
901
VCL_INT
902 11781
VRT_r_bereq_xid(VRT_CTX)
903
{
904
905 11781
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
906 11781
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
907 11781
        AN(ctx->bo->vsl);
908
909 11781
        return (VXID(ctx->bo->vsl->wid));
910
}
911
912
VCL_INT
913 147
VRT_r_sess_xid(VRT_CTX)
914
{
915
        struct sess *sp;
916
917 147
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
918
919 147
        if (ctx->req) {
920 84
                CHECK_OBJ(ctx->req, REQ_MAGIC);
921 84
                sp = ctx->req->sp;
922 84
        } else {
923 63
                CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
924 63
                sp = ctx->bo->sp;
925
        }
926
927 147
        CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
928 147
        return (VXID(sp->vxid));
929
}
930
931
/*--------------------------------------------------------------------
932
 * req/resp fields, both stored in struct req
933
 */
934
935
#define VREQW(where, field)                                             \
936
VCL_VOID                                                                \
937
VRT_l_##where##_##field(VRT_CTX, VCL_BOOL a)                            \
938
{                                                                       \
939
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
940
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);                         \
941
        ctx->req->field = a ? 1 : 0;                                    \
942
}
943
944
#define VREQR(where, field)                                             \
945
VCL_BOOL                                                                \
946
VRT_r_##where##_##field(VRT_CTX)                                        \
947
{                                                                       \
948
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
949
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);                         \
950
        return (ctx->req->field);                                       \
951
}
952
953
#define VREQW0(field)
954
#define VREQR0(field)
955
#define VREQWreq(field)         VREQW(req, field)
956
#define VREQRreq(field)         VREQR(req, field)
957
#define VREQWresp(field)        VREQW(resp, field)
958
#define VREQRresp(field)        VREQR(resp, field)
959
960
#define REQ_FLAG(l, r, w, d) \
961
        VREQR##r(l) \
962
        VREQW##w(l)
963
#include "tbl/req_flags.h"
964
965
#undef VREQW
966
#undef VREQR
967
#undef VREQW0
968
#undef VREQR0
969
#undef VREQWreq
970
#undef VREQRreq
971
#undef VREQWresp
972
#undef VREQRresp
973
974
975
/*--------------------------------------------------------------------*/
976
977
#define GIP(fld)                                                \
978
        VCL_IP                                                  \
979
        VRT_r_##fld##_ip(VRT_CTX)                               \
980
        {                                                       \
981
                struct suckaddr *sa;                            \
982
                                                                \
983
                CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);          \
984
                CHECK_OBJ_NOTNULL(ctx->sp, SESS_MAGIC);         \
985
                AZ(SES_Get_##fld##_addr(ctx->sp, &sa));         \
986
                return (sa);                                    \
987
        }
988
989 1052
GIP(local)
990 1073
GIP(remote)
991 2186
GIP(client)
992 7232
GIP(server)
993
#undef GIP
994
995
/*--------------------------------------------------------------------
996
 * local.[endpoint|socket]
997
 */
998
999
#define LOC(var,fld)                                            \
1000
VCL_STRING                                                      \
1001
VRT_r_local_##var(VRT_CTX)                                      \
1002
{                                                               \
1003
        struct sess *sp;                                        \
1004
                                                                \
1005
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                  \
1006
        if (ctx->req) {                                         \
1007
                CHECK_OBJ(ctx->req, REQ_MAGIC);                 \
1008
                sp = ctx->req->sp;                              \
1009
        } else {                                                \
1010
                CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);      \
1011
                sp = ctx->bo->sp;                               \
1012
        }                                                       \
1013
                                                                \
1014
        CHECK_OBJ_NOTNULL(sp->listen_sock, LISTEN_SOCK_MAGIC);  \
1015
        AN(sp->listen_sock->fld);                               \
1016
        return (sp->listen_sock->fld);                          \
1017
}
1018
1019 147
LOC(endpoint, endpoint)
1020 147
LOC(socket, name)
1021
#undef LOC
1022
1023
/*--------------------------------------------------------------------*/
1024
1025
VCL_STRING
1026 210
VRT_r_server_identity(VRT_CTX)
1027
{
1028
1029 210
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
1030 210
        if (heritage.identity != NULL)
1031 210
                return (heritage.identity);
1032
        else
1033 0
                return ("vinyld");
1034 210
}
1035
1036
VCL_STRING
1037 63
VRT_r_server_hostname(VRT_CTX)
1038
{
1039
1040 63
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
1041 63
        if (vrt_hostname[0] == '\0')
1042 42
                AZ(gethostname(vrt_hostname, sizeof(vrt_hostname)));
1043 63
        return (vrt_hostname);
1044
}
1045
1046
/*--------------------------------------------------------------------*/
1047
1048
VCL_INT
1049 1848
VRT_r_obj_hits(VRT_CTX)
1050
{
1051 1848
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
1052 1848
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
1053 1848
        CHECK_OBJ_NOTNULL(ctx->req->objcore, OBJCORE_MAGIC);
1054 1848
        if (ctx->method == VCL_MET_HIT)
1055 42
                return (ctx->req->objcore->hits);
1056 1806
        return (ctx->req->is_hit ? ctx->req->objcore->hits : 0);
1057 1848
}
1058
1059
/*--------------------------------------------------------------------*/
1060
1061
VCL_INT
1062 21
VRT_r_obj_stale_hits(VRT_CTX)
1063
{
1064 21
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
1065 21
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
1066 21
        CHECK_OBJ_NOTNULL(ctx->bo->stale_oc, OBJCORE_MAGIC);
1067
1068 21
        return (ctx->bo->stale_oc->hits);
1069
}
1070
1071
VCL_BOOL
1072 819
VRT_r_obj_stale_is_valid(VRT_CTX)
1073
{
1074 819
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
1075 819
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
1076 819
        CHECK_OBJ_NOTNULL(ctx->bo->stale_oc, OBJCORE_MAGIC);
1077
1078 819
        return (!(ctx->bo->stale_oc->flags & OC_F_DYING));
1079
}
1080
1081
/*--------------------------------------------------------------------*/
1082
1083
VCL_BOOL
1084 105
VRT_r_resp_is_streaming(VRT_CTX)
1085
{
1086 105
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
1087 105
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
1088 105
        if (ctx->req->objcore == NULL)
1089 21
                return (0);     /* When called from vcl_synth */
1090 84
        CHECK_OBJ(ctx->req->objcore, OBJCORE_MAGIC);
1091 84
        return (ctx->req->objcore->boc == NULL ? 0 : 1);
1092 105
}
1093
1094
/*--------------------------------------------------------------------*/
1095
1096
static inline int
1097 294
resp_filter_fixed(VRT_CTX, const char *s)
1098
{
1099 294
        if (ctx->req->vdp_filter_list == NULL)
1100 273
                return (0);
1101 21
        VRT_fail(ctx, "resp.filters are already fixed, %s is undefined", s);
1102 21
        return (1);
1103 294
}
1104
1105
VCL_VOID
1106 105
VRT_l_resp_do_esi(VRT_CTX, VCL_BOOL process_esi)
1107
{
1108
1109 105
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
1110 105
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
1111 105
        assert(ctx->syntax >= 41);
1112 105
        if (resp_filter_fixed(ctx, "resp.do_esi"))
1113 21
                return;
1114 84
        ctx->req->disable_esi = !process_esi;
1115 105
}
1116
1117
VCL_BOOL
1118 189
VRT_r_resp_do_esi(VRT_CTX)
1119
{
1120
1121 189
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
1122 189
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
1123 189
        assert(ctx->syntax >= 41);
1124 189
        if (resp_filter_fixed(ctx, "resp.do_esi"))
1125 0
                return (0);
1126 189
        return (!ctx->req->disable_esi);
1127 189
}
1128
1129
/*--------------------------------------------------------------------*/
1130
1131
#define VRT_BODY_L(which)                                       \
1132
VCL_VOID                                                        \
1133
VRT_l_##which##_body(VRT_CTX, enum lbody_e type,                \
1134
    const char *str, VCL_BODY body)                             \
1135
{                                                               \
1136
        int n;                                                  \
1137
        struct vsb *vsb;                                        \
1138
        VCL_STRANDS s;                                          \
1139
        VCL_BLOB b;                                             \
1140
                                                                \
1141
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                  \
1142
        AN(body);                                               \
1143
        CAST_OBJ_NOTNULL(vsb, ctx->specific, VSB_MAGIC);        \
1144
        if (type == LBODY_SET_STRING || type == LBODY_SET_BLOB) \
1145
                VSB_clear(vsb);                                 \
1146
        if (type == LBODY_SET_BLOB || type == LBODY_ADD_BLOB) { \
1147
                AZ(str);                                        \
1148
                b = body;                                       \
1149
                CHECK_OBJ_NOTNULL(b, VRT_BLOB_MAGIC);           \
1150
                VSB_bcat(vsb, b->blob, b->len);                 \
1151
                return;                                         \
1152
        }                                                       \
1153
        if (str != NULL)                                        \
1154
                VSB_cat(vsb, str);                              \
1155
        assert(type == LBODY_SET_STRING ||                      \
1156
            type == LBODY_ADD_STRING);                          \
1157
        s = body;                                               \
1158
        CHECK_OBJ_NOTNULL(s, STRANDS_MAGIC);                    \
1159
        for (n = 0; s != NULL && n < s->n; n++)                 \
1160
                if (s->p[n] != NULL)                            \
1161
                        VSB_cat(vsb, s->p[n]);                  \
1162
}
1163
1164 91745
VRT_BODY_L(beresp)
1165 84
static VRT_BODY_L(resp_vsb)
1166
1167
VCL_VOID
1168 10080
VRT_l_resp_body(VRT_CTX, enum lbody_e type,
1169
    const char *str, VCL_BODY body)
1170
{
1171
        struct vscarab *scarab;
1172
        struct viov *viov;
1173
        struct req *req;
1174 10080
        ssize_t sz = 0;
1175
        VCL_STRANDS s;
1176
        VCL_BLOB b;
1177
        int n;
1178
1179
1180 10080
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
1181 10080
        AN(body);
1182 10080
        req = ctx->req;
1183 10080
        CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
1184
1185 10080
        if (req->objcore == NULL)
1186 9954
                VRT_l_resp_storage(ctx, NULL);
1187 126
        else if (type == LBODY_SET_STRING || type == LBODY_SET_BLOB)
1188 63
                VRT_l_resp_storage(ctx, req->objcore->stobj->stevedore);
1189 10080
        if (req->objcore == NULL)
1190 21
                return;
1191
1192 10059
        AN(req->objcore->stobj->stevedore);
1193 10059
        if (req->objcore->stobj->stevedore->allocobj != ssy_stevedore.allocobj) {
1194 21
                VRT_l_resp_vsb_body(ctx, type, str, body);
1195 21
                return;
1196
        }
1197
1198 10038
        if (! ObjGetSpace(req->wrk, req->objcore, &sz, (uint8_t **)(void*)&scarab)) {
1199 0
                VRT_fail(ctx, "Synth storage failed");
1200 0
                return;
1201
        }
1202
1203 10038
        VSCARAB_CHECK_NOTNULL(scarab);
1204
1205 10038
        if (type == LBODY_SET_BLOB || type == LBODY_ADD_BLOB) {
1206 126
                AZ(str);
1207 126
                b = body;
1208 126
                viov = VSCARAB_GET(scarab);
1209 126
                AN(viov);       // ObjGetSpace ensures
1210 126
                viov->iov.iov_base = TRUST_ME(b->blob);
1211 126
                viov->iov.iov_len = b->len;
1212 126
                return;
1213
        }
1214 9912
        if (str != NULL) {
1215 0
                viov = VSCARAB_GET(scarab);
1216 0
                AN(viov);       // ObjGetSpace ensures
1217 0
                viov->iov.iov_base = TRUST_ME(str);
1218 0
                viov->iov.iov_len = vstrlen(str);
1219 0
        }
1220
1221 9912
        s = body;
1222 128535
        for (n = 0; s != NULL && n < s->n; n++) {
1223 118623
                if (s->p[n] == NULL || *s->p[n] == '\0')
1224 334
                        continue;
1225
1226 118289
                viov = VSCARAB_GET(scarab);
1227 118289
                if (viov == NULL) {
1228 9051
                        if (! ObjGetSpace(req->wrk, req->objcore, &sz,
1229
                            (uint8_t **)(void*)&scarab)) {
1230 0
                                VRT_fail(ctx, "Synth storage failed");
1231 0
                                return;
1232
                        }
1233 9051
                        viov = VSCARAB_GET(scarab);
1234 9051
                }
1235 118289
                AN(viov);
1236 118289
                viov->iov.iov_base = TRUST_ME(s->p[n]);
1237 118289
                viov->iov.iov_len = vstrlen(s->p[n]);
1238 118289
        }
1239 10080
}
1240
1241
1242
/*--------------------------------------------------------------------*/
1243
1244
                        /* digest */
1245
#define BLOB_HASH_TYPE 0x00d16357
1246
1247
VCL_BLOB
1248 84
VRT_r_req_hash(VRT_CTX)
1249
{
1250 84
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
1251 84
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
1252 84
        return (VRT_blob(ctx, "req.hash", ctx->req->digest, DIGEST_LEN,
1253
            BLOB_HASH_TYPE));
1254
}
1255
1256
VCL_BLOB
1257 252
VRT_r_bereq_hash(VRT_CTX)
1258
{
1259 252
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
1260 252
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
1261 252
        return (VRT_blob(ctx, "bereq.hash", ctx->bo->digest, DIGEST_LEN,
1262
            BLOB_HASH_TYPE));
1263
}
1264
1265
/*--------------------------------------------------------------------*/
1266
1267
#define HTTP_VAR(x)                                             \
1268
VCL_HTTP                                                        \
1269
VRT_r_##x(VRT_CTX)                                              \
1270
{                                                               \
1271
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                  \
1272
        CHECK_OBJ_NOTNULL(ctx->http_##x, HTTP_MAGIC);           \
1273
        return (ctx->http_##x);                                 \
1274
}
1275
1276 336
HTTP_VAR(req)
1277 42
HTTP_VAR(resp)
1278 189
HTTP_VAR(bereq)
1279 42
HTTP_VAR(beresp)
1280
1281
/*--------------------------------------------------------------------*/
1282
1283
static inline void
1284 63
set_idle_send_timeout(const struct sess *sp, VCL_DURATION d)
1285
{
1286 63
        struct timeval tv = VTIM_timeval_sock(d);
1287 63
        VTCP_Assert(setsockopt(sp->fd, SOL_SOCKET, SO_SNDTIMEO,
1288
            &tv, sizeof tv));
1289 63
}
1290
1291
#define SESS_VAR_DUR(x, setter)                         \
1292
VCL_VOID                                                \
1293
VRT_l_sess_##x(VRT_CTX, VCL_DURATION d)                 \
1294
{                                                       \
1295
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);          \
1296
        CHECK_OBJ_NOTNULL(ctx->sp, SESS_MAGIC);         \
1297
        d = vmax(d, 0.0);                               \
1298
        setter;                                         \
1299
        ctx->sp->x = d;                                 \
1300
}                                                       \
1301
                                                        \
1302
VCL_DURATION                                            \
1303
VRT_r_sess_##x(VRT_CTX)                                 \
1304
{                                                       \
1305
        vtim_dur res;                                   \
1306
                                                        \
1307
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);          \
1308
        CHECK_OBJ_NOTNULL(ctx->sp, SESS_MAGIC);         \
1309
        res = SESS_TMO(ctx->sp, x);                     \
1310
        return (VRT_TMO(res));                          \
1311
}                                                       \
1312
                                                        \
1313
VCL_VOID                                                \
1314
VRT_u_sess_##x(VRT_CTX)                                 \
1315
{                                                       \
1316
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);          \
1317
        CHECK_OBJ_NOTNULL(ctx->sp, SESS_MAGIC);         \
1318
        ctx->sp->x = NAN;                               \
1319
}
1320
1321 210
SESS_VAR_DUR(timeout_idle, )
1322 231
SESS_VAR_DUR(timeout_linger, )
1323 147
SESS_VAR_DUR(send_timeout, )
1324 168
SESS_VAR_DUR(idle_send_timeout, set_idle_send_timeout(ctx->sp, d))
1325
1326
/*--------------------------------------------------------------------*/
1327
1328
#define PARAM_VAR(x, type)                              \
1329
VCL_##type                                              \
1330
VRT_r_param_##x(VRT_CTX)                                \
1331
{                                                       \
1332
                                                        \
1333
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);          \
1334
        return (cache_param->x);                        \
1335
}                                                       \
1336
1337 0
PARAM_VAR(backend_idle_timeout, DURATION)
1338 0
PARAM_VAR(backend_wait_limit, INT)
1339 0
PARAM_VAR(backend_wait_timeout, DURATION)
1340 0
PARAM_VAR(between_bytes_timeout, DURATION)
1341 0
PARAM_VAR(connect_timeout, DURATION)
1342 0
PARAM_VAR(default_grace, DURATION)
1343 0
PARAM_VAR(default_keep, DURATION)
1344 0
PARAM_VAR(default_ttl, DURATION)
1345 0
PARAM_VAR(first_byte_timeout, DURATION)
1346 0
PARAM_VAR(idle_send_timeout, DURATION)
1347 0
PARAM_VAR(max_esi_depth, INT)
1348 0
PARAM_VAR(max_restarts, INT)
1349 0
PARAM_VAR(max_retries, INT)
1350 0
PARAM_VAR(pipe_task_deadline, DURATION)
1351 0
PARAM_VAR(pipe_timeout, DURATION)
1352 0
PARAM_VAR(send_timeout, DURATION)
1353 0
PARAM_VAR(shortlived, DURATION)
1354 42
PARAM_VAR(timeout_idle, DURATION)
1355 0
PARAM_VAR(transit_buffer, BYTES)
1356 882
PARAM_VAR(uncacheable_ttl, DURATION)