varnish-cache/bin/varnishd/cache/cache.h
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
 */
31
32
#ifdef VRT_H_INCLUDED
33
#  error "vrt.h included before cache.h - they are exclusive"
34
#endif
35
36
#ifdef CACHE_H_INCLUDED
37
#  error "cache.h included multiple times"
38
#endif
39
40
#include <math.h>
41
#include <pthread.h>
42
#include <stdarg.h>
43
#include <sys/types.h>
44
#include <sys/uio.h>
45
46
#include "vdef.h"
47
#include "vrt.h"
48
49
#define CACHE_H_INCLUDED        // After vrt.h include.
50
51
#include "miniobj.h"
52
#include "vas.h"
53
#include "vqueue.h"
54
#include "vtree.h"
55
56
#include "vapi/vsl_int.h"
57
58
/*--------------------------------------------------------------------*/
59
60
struct vxids {
61
        uint64_t        vxid;
62
};
63
64
typedef struct vxids vxid_t;
65
66
#define NO_VXID ((struct vxids){0})
67
#define IS_NO_VXID(x) ((x).vxid == 0)
68
#define VXID_TAG(x) ((uintmax_t)((x).vxid & (VSL_CLIENTMARKER|VSL_BACKENDMARKER)))
69
#define VXID(u) ((uintmax_t)((u.vxid) & VSL_IDENTMASK))
70
#define IS_SAME_VXID(x, y) ((x).vxid == (y).vxid)
71
72
/*--------------------------------------------------------------------*/
73
74
struct body_status {
75
        const char              *name;
76
        int                     nbr;
77
        int                     avail;
78
        int                     length_known;
79
};
80
81
#define BODYSTATUS(U, l, n, a, k) extern const struct body_status BS_##U[1];
82
#include "tbl/body_status.h"
83
84
typedef const struct body_status *body_status_t;
85
86
/*--------------------------------------------------------------------*/
87
88
struct stream_close {
89
        unsigned                magic;
90
#define STREAM_CLOSE_MAGIC      0xc879c93d
91
        int                     idx;
92
        unsigned                is_err;
93
        const char              *name;
94
        const char              *desc;
95
};
96
    extern const struct stream_close SC_NULL[1];
97
#define SESS_CLOSE(nm, stat, err, desc) \
98
    extern const struct stream_close SC_##nm[1];
99
#include "tbl/sess_close.h"
100
101
102
/*--------------------------------------------------------------------
103
 * Indices into http->hd[]
104
 */
105
enum {
106
#define SLTH(tag, ind, req, resp, sdesc, ldesc) ind,
107
#include "tbl/vsl_tags_http.h"
108
};
109
110
/*--------------------------------------------------------------------*/
111
112
struct ban;
113
struct ban_proto;
114
struct cli;
115
struct http_conn;
116
struct listen_sock;
117
struct mempool;
118
struct objcore;
119
struct objhead;
120
struct pool;
121
struct req_step;
122
struct sess;
123
struct transport;
124
struct vcf;
125
struct VSC_lck;
126
struct VSC_main;
127
struct VSC_main_wrk;
128
struct worker;
129
struct worker_priv;
130
131
#define DIGEST_LEN              32
132
133
/*--------------------------------------------------------------------*/
134
135
struct lock { void *priv; };    // Opaque
136
137
/*--------------------------------------------------------------------
138
 * Workspace structure for quick memory allocation.
139
 */
140
141
#define WS_ID_SIZE 4
142
143
struct ws {
144
        unsigned                magic;
145
#define WS_MAGIC                0x35fac554
146
        char                    id[WS_ID_SIZE]; /* identity */
147
        char                    *s;             /* (S)tart of buffer */
148
        char                    *f;             /* (F)ree/front pointer */
149
        char                    *r;             /* (R)eserved length */
150
        char                    *e;             /* (E)nd of buffer */
151
};
152
153
/*--------------------------------------------------------------------
154
 *
155
 */
156
157
enum well_known_method {
158
#define WKM(wk, bit) WKM_##wk = 1U << bit,
159
#include "tbl/well_known_methods.h"
160
#undef WKM
161
};
162
163
struct http {
164
        unsigned                magic;
165
#define HTTP_MAGIC              0x6428b5c9
166
167
        uint16_t                shd;            /* Size of hd space */
168
        txt                     *hd;
169
        unsigned char           *hdf;
170
#define HDF_FILTER              (1 << 0)        /* Filtered by Connection */
171
172
        /* NB: ->nhd and below zeroed/initialized by http_Teardown */
173
        uint16_t                nhd;            /* Next free hd */
174
175
        enum VSL_tag_e          logtag;         /* Must be SLT_*Method */
176
        struct vsl_log          *vsl;
177
178
        struct ws               *ws;
179
        uint16_t                status;
180
        uint8_t                 protover;
181
        enum well_known_method  wkm;
182
};
183
184
/*--------------------------------------------------------------------*/
185
186
struct acct_req {
187
#define ACCT(foo)       uint64_t        foo;
188
#include "tbl/acct_fields_req.h"
189
};
190
191
/*--------------------------------------------------------------------*/
192
193
struct acct_bereq {
194
#define ACCT(foo)       uint64_t        foo;
195
#include "tbl/acct_fields_bereq.h"
196
};
197
198
/*--------------------------------------------------------------------*/
199
200
struct vsl_log {
201
        uint32_t                *wlb, *wlp, *wle;
202
        vxid_t                  wid;
203
        unsigned                wlr;
204
};
205
206
/*--------------------------------------------------------------------*/
207
208
VRBT_HEAD(vrt_privs, vrt_priv);
209
210
/* Worker pool stuff -------------------------------------------------*/
211
212
typedef void task_func_t(struct worker *wrk, void *priv);
213
214
struct pool_task {
215
        VTAILQ_ENTRY(pool_task)         list;
216
        task_func_t                     *func;
217
        void                            *priv;
218
};
219
220
/*
221
 * tasks are taken off the queues in this order
222
 *
223
 * TASK_QUEUE_{REQ|STR} are new req's (H1/H2), and subject to queue limit.
224
 *
225
 * TASK_QUEUE_RUSH is req's returning from waiting list
226
 *
227
 * NOTE: When changing the number of classes, update places marked with
228
 * TASK_QUEUE_RESERVE in params.h
229
 */
230
enum task_prio {
231
        TASK_QUEUE_BO,
232
        TASK_QUEUE_RUSH,
233
        TASK_QUEUE_REQ,
234
        TASK_QUEUE_STR,
235
        TASK_QUEUE_VCA,
236
        TASK_QUEUE_BG,
237
        TASK_QUEUE__END
238
};
239
240
#define TASK_QUEUE_HIGHEST_PRIORITY TASK_QUEUE_BO
241
#define TASK_QUEUE_RESERVE TASK_QUEUE_BG
242
#define TASK_QUEUE_LIMITED(prio) \
243
        (prio == TASK_QUEUE_REQ || prio == TASK_QUEUE_STR)
244
245
/*--------------------------------------------------------------------*/
246
247
struct worker {
248
        unsigned                magic;
249
#define WORKER_MAGIC            0x6391adcf
250
        int                     strangelove;
251
        struct worker_priv      *wpriv;
252
        struct pool             *pool;
253
        struct VSC_main_wrk     *stats;
254
        struct vsl_log          *vsl;           // borrowed from req/bo
255
256
        struct pool_task        task[1];
257
258
        vtim_real               lastused;
259
260
        pthread_cond_t          cond;
261
262
        struct ws               aws[1];
263
264
        unsigned                cur_method;
265
        unsigned                seen_methods;
266
267
        struct wrk_vpi          *vpi;
268
};
269
270
/* Stored object -----------------------------------------------------
271
 * This is just to encapsulate the fields owned by the stevedore
272
 */
273
274
struct storeobj {
275
        const struct stevedore  *stevedore;
276
        void                    *priv;
277
        uint64_t                priv2;
278
};
279
280
/* Busy Objcore structure --------------------------------------------
281
 *
282
 */
283
284
/*
285
 * The macro-states we expose outside the fetch code
286
 */
287
enum boc_state_e {
288
#define BOC_STATE(U, l)       BOS_##U,
289
#include "tbl/boc_state.h"
290
};
291
292
// cache_obj.h vai notify
293
struct vai_qe;
294
VSLIST_HEAD(vai_q_head, vai_qe);
295
296
struct boc {
297
        unsigned                magic;
298
#define BOC_MAGIC               0x70c98476
299
        unsigned                refcount;
300
        struct lock             mtx;
301
        pthread_cond_t          cond;
302
        void                    *stevedore_priv;
303
        enum boc_state_e        state;
304
        uint8_t                 *vary;
305
        uint64_t                fetched_so_far;
306
        uint64_t                delivered_so_far;
307
        uint64_t                transit_buffer;
308
        struct vai_q_head       vai_q_head;
309
};
310
311
/* Object core structure ---------------------------------------------
312
 * Objects have sideways references in the binary heap and the LRU list
313
 * and we want to avoid paging in a lot of objects just to move them up
314
 * or down the binheap or to move a unrelated object on the LRU list.
315
 * To avoid this we use a proxy object, objcore, to hold the relevant
316
 * housekeeping fields parts of an object.
317
 */
318
319
enum obj_attr {
320
#define OBJ_FIXATTR(U, l, s)    OA_##U,
321
#define OBJ_VARATTR(U, l)       OA_##U,
322
#define OBJ_AUXATTR(U, l)       OA_##U,
323
#include "tbl/obj_attr.h"
324
                                OA__MAX,
325
};
326
327
enum obj_flags {
328
#define OBJ_FLAG(U, l, v)       OF_##U = v,
329
#include "tbl/obj_attr.h"
330
};
331
332
enum oc_flags {
333
#define OC_FLAG(U, l, v)        OC_F_##U = v,
334
#include "tbl/oc_flags.h"
335
};
336
337
#define OC_F_TRANSIENT (OC_F_PRIVATE | OC_F_HFM | OC_F_HFP)
338
339
enum oc_exp_flags {
340
#define OC_EXP_FLAG(U, l, v)    OC_EF_##U = v,
341
#include "tbl/oc_exp_flags.h"
342
};
343
344
struct objcore {
345
        unsigned                magic;
346
#define OBJCORE_MAGIC           0x4d301302
347
        int                     refcnt;
348
        struct storeobj         stobj[1];
349
        struct objhead          *objhead;
350
        struct boc              *boc;
351
        vtim_real               timer_when;
352
        VCL_INT                 hits;
353
354
355
        vtim_real               t_origin;
356
        float                   ttl;
357
        float                   grace;
358
        float                   keep;
359
360
        uint8_t                 flags;
361
362
        uint8_t                 exp_flags;
363
364
        uint16_t                oa_present;
365
366
        unsigned                timer_idx;      // XXX 4Gobj limit
367
        unsigned                waitinglist_gen;
368
        vtim_real               last_lru;
369
        VTAILQ_ENTRY(objcore)   hsh_list;
370
        VTAILQ_ENTRY(objcore)   lru_list;
371
        VTAILQ_ENTRY(objcore)   ban_list;
372
        VSTAILQ_ENTRY(objcore)  exp_list;
373
        struct ban              *ban;
374
};
375
376
/* Busy Object structure ---------------------------------------------
377
 *
378
 * The busyobj structure captures the aspects of an object related to,
379
 * and while it is being fetched from the backend.
380
 *
381
 * One of these aspects will be how much has been fetched, which
382
 * streaming delivery will make use of.
383
 */
384
385
enum director_state_e {
386
        DIR_S_NULL = 0,
387
        DIR_S_HDRS = 1,
388
        DIR_S_BODY = 2,
389
};
390
391
struct busyobj {
392
        unsigned                magic;
393
#define BUSYOBJ_MAGIC           0x23b95567
394
395
        char                    *end;
396
397
        unsigned                max_retries;
398
        unsigned                retries;
399
        struct req              *req;
400
        struct sess             *sp;
401
        struct worker           *wrk;
402
403
        /* beresp.body */
404
        struct vfp_ctx          *vfc;
405
        const char              *vfp_filter_list;
406
        /* bereq.body */
407
        const char              *vdp_filter_list;
408
409
        struct ws               ws[1];
410
        uintptr_t               ws_bo;
411
        struct http             *bereq0;
412
        struct http             *bereq;
413
        struct http             *beresp;
414
        struct objcore          *bereq_body;
415
        struct objcore          *stale_oc;
416
        struct objcore          *fetch_objcore;
417
418
        const char              *no_retry;
419
420
        struct http_conn        *htc;
421
422
        struct pool_task        fetch_task[1];
423
424
        const char              *err_reason;
425
        enum director_state_e   director_state;
426
        uint16_t                err_code;
427
428
#define BERESP_FLAG(l, r, w, f, d) unsigned     l:1;
429
#define BEREQ_FLAG(l, r, w, d) BERESP_FLAG(l, r, w, 0, d)
430
#include "tbl/bereq_flags.h"
431
#include "tbl/beresp_flags.h"
432
433
434
        /* Timeouts */
435
        vtim_dur                connect_timeout;
436
        vtim_dur                first_byte_timeout;
437
        vtim_dur                between_bytes_timeout;
438
        vtim_dur                task_deadline;
439
440
        /* Timers */
441
        vtim_real               t_first;        /* First timestamp logged */
442
        vtim_real               t_resp;         /* response received */
443
        vtim_real               t_prev;         /* Previous timestamp logged */
444
445
        /* Acct */
446
        struct acct_bereq       acct;
447
448
        const struct stevedore  *storage;
449
        const struct director   *director_req;
450
        const struct director   *director_resp;
451
        struct vcl              *vcl;
452
453
        struct vsl_log          vsl[1];
454
455
        uint8_t                 digest[DIGEST_LEN];
456
        struct vrt_privs        privs[1];
457
458
        const char              *client_identity;
459
};
460
461
#define BUSYOBJ_TMO(bo, pfx, tmo)                                       \
462
        (isnan((bo)->tmo) ? cache_param->pfx##tmo : (bo)->tmo)
463
464
extern const char *retry_disabled;
465
466
/*--------------------------------------------------------------------*/
467
468
struct reqtop {
469
        unsigned                magic;
470
#define REQTOP_MAGIC            0x57fbda52
471
        struct req              *topreq;
472
        struct vcl              *vcl0;
473
        struct vrt_privs        privs[1];
474
};
475
476
struct req {
477
        unsigned                magic;
478
#define REQ_MAGIC               0xfb4abf6d
479
480
        unsigned                esi_level;
481
        body_status_t           req_body_status;
482
        stream_close_t          doclose;
483
        unsigned                restarts;
484
        unsigned                max_restarts;
485
        unsigned                waitinglist_gen;
486
487
        const struct req_step   *req_step;
488
        struct reqtop           *top;   /* esi_level == 0 request */
489
490
        uint16_t                err_code;
491
#define REQ_FLAG(l, r, w, d) unsigned   l:1;
492
#include "tbl/req_flags.h"
493
494
        const char              *err_reason;
495
496
        struct sess             *sp;
497
        struct worker           *wrk;
498
        struct pool_task        task[1];
499
500
        const struct transport  *transport;
501
        void                    *transport_priv;
502
503
        VTAILQ_ENTRY(req)       w_list;
504
505
        struct objcore          *body_oc;
506
507
        /* Built Vary string == workspace reservation */
508
        uint8_t                 *vary_b;
509
        uint8_t                 *vary_e;
510
511
        uint8_t                 digest[DIGEST_LEN];
512
513
        vtim_dur                d_ttl;
514
        vtim_dur                d_grace;
515
516
        const struct stevedore  *storage;
517
518
        const struct director   *director_hint;
519
        struct vcl              *vcl;
520
521
        uintptr_t               ws_req;         /* WS above request data */
522
523
        /* Timestamps */
524
        vtim_real               t_first;        /* First timestamp logged */
525
        vtim_real               t_prev;         /* Previous timestamp logged */
526
        vtim_real               t_req;          /* Headers complete */
527
        vtim_real               t_resp;         /* Entry to last deliver/synth */
528
529
        struct http_conn        *htc;
530
        struct vfp_ctx          *vfc;
531
        const char              *client_identity;
532
533
        /* HTTP request */
534
        struct http             *http;
535
        struct http             *http0;
536
537
        /* HTTP response */
538
        struct http             *resp;
539
        intmax_t                resp_len;
540
541
        struct ws               ws[1];
542
        struct objcore          *objcore;
543
        struct objcore          *stale_oc;
544
        struct boc              *boc;           /* valid during cnt_transmit */
545
546
        /* resp.body */
547
        struct vdp_ctx          *vdc;
548
        const char              *vdp_filter_list;
549
        /* req.body */
550
        const char              *vfp_filter_list;
551
552
        /* Transaction VSL buffer */
553
        struct vsl_log          vsl[1];
554
555
        /* Temporary accounting */
556
        struct acct_req         acct;
557
558
        struct vrt_privs        privs[1];
559
560
        struct vcf              *vcf;
561
};
562
563
#define IS_TOPREQ(req) ((req)->top->topreq == (req))
564
565
/*--------------------------------------------------------------------
566
 * Struct sess is a high memory-load structure because sessions typically
567
 * hang around the waiter for relatively long time.
568
 *
569
 * The size goal for struct sess + struct memitem is <512 bytes
570
 *
571
 * Getting down to the next relevant size (<256 bytes because of how malloc
572
 * works, is not realistic without a lot of code changes.
573
 */
574
575
enum sess_attr {
576
#define SESS_ATTR(UP, low, typ, len)    SA_##UP,
577
#include "tbl/sess_attr.h"
578
        SA_LAST
579
};
580
581
struct sess {
582
        unsigned                magic;
583
#define SESS_MAGIC              0x2c2f9c5a
584
585
        uint16_t                sattr[SA_LAST];
586
        struct listen_sock      *listen_sock;
587
        int                     refcnt;
588
        int                     fd;
589
        vxid_t                  vxid;
590
591
        struct lock             mtx;
592
593
        struct pool             *pool;
594
595
        struct ws               ws[1];
596
597
        vtim_real               t_open;         /* fd accepted */
598
        vtim_real               t_idle;         /* fd accepted or resp sent */
599
        vtim_dur                timeout_idle;
600
        vtim_dur                timeout_linger;
601
        vtim_dur                send_timeout;
602
        vtim_dur                idle_send_timeout;
603
};
604
605
#define SESS_TMO(sp, tmo)                                       \
606
        (isnan((sp)->tmo) ? cache_param->tmo : (sp)->tmo)
607
608
/* Prototypes etc ----------------------------------------------------*/
609
610
611
/* cache_ban.c */
612
613
/* for constructing bans */
614
struct ban_proto *BAN_Build(void);
615
const char *BAN_AddTest(struct ban_proto *,
616
    const char *, const char *, const char *);
617
const char *BAN_Commit(struct ban_proto *b);
618
void BAN_Abandon(struct ban_proto *b);
619
620
/* cache_cli.c [CLI] */
621
extern pthread_t cli_thread;
622
#define IS_CLI() (pthread_equal(pthread_self(), cli_thread))
623
#define ASSERT_CLI() do {assert(IS_CLI());} while (0)
624
625
/* cache_http.c */
626
unsigned HTTP_estimate(unsigned nhttp);
627
void HTTP_Clone(struct http *to, const struct http * const fm);
628
void HTTP_Dup(struct http *to, const struct http * const fm);
629
struct http *HTTP_create(void *p, uint16_t nhttp, unsigned);
630
const char *http_Status2Reason(unsigned, const char **);
631
int http_IsHdr(const txt *hh, hdr_t hdr);
632
unsigned http_EstimateWS(const struct http *fm, unsigned how);
633
void http_PutResponse(struct http *to, const char *proto, uint16_t status,
634
    const char *response);
635
void http_FilterReq(struct http *to, const struct http *fm, unsigned how);
636
void HTTP_Encode(const struct http *fm, uint8_t *, unsigned len, unsigned how);
637
int HTTP_Decode(struct http *to, const uint8_t *fm);
638
void http_ForceHeader(struct http *to, hdr_t, const char *val);
639
void http_AppendHeader(struct http *to, hdr_t, const char *val);
640
void http_PrintfHeader(struct http *to, const char *fmt, ...)
641
    v_printflike_(2, 3);
642
void http_TimeHeader(struct http *to, const char *fmt, vtim_real now);
643
const char * http_ViaHeader(void);
644
void http_Proto(struct http *to);
645
void http_SetHeader(struct http *to, const char *header);
646
void http_SetH(struct http *to, unsigned n, const char *header);
647
void http_ForceField(struct http *to, unsigned n, const char *t);
648
void HTTP_Setup(struct http *, struct ws *, struct vsl_log *, enum VSL_tag_e);
649
void http_Teardown(struct http *ht);
650
int http_GetHdr(const struct http *hp, hdr_t, const char **ptr);
651
int http_GetHdrToken(const struct http *hp, hdr_t,
652
    const char *token, const char **pb, const char **pe);
653
int http_GetHdrField(const struct http *hp, hdr_t,
654
    const char *field, const char **ptr);
655
double http_GetHdrQ(const struct http *hp, hdr_t, const char *field);
656
ssize_t http_GetContentLength(const struct http *hp);
657
ssize_t http_GetContentRange(const struct http *hp, ssize_t *lo, ssize_t *hi);
658
const char * http_GetRange(const struct http *hp, ssize_t *lo, ssize_t *hi,
659
    ssize_t len);
660
uint16_t http_GetStatus(const struct http *hp);
661
int http_IsStatus(const struct http *hp, int);
662
void http_SetStatus(struct http *to, uint16_t status, const char *reason);
663
const char *http_GetMethod(const struct http *hp);
664
int http_HdrIs(const struct http *hp, hdr_t, const char *val);
665
void http_CopyHome(const struct http *hp);
666
void http_Unset(struct http *hp, hdr_t);
667
unsigned http_CountHdr(const struct http *hp, hdr_t);
668
void http_CollectHdr(struct http *hp, hdr_t);
669
void http_CollectHdrSep(struct http *hp, hdr_t, const char *sep);
670
void http_VSL_log(const struct http *hp);
671
void HTTP_Merge(struct worker *, struct objcore *, struct http *to);
672
uint16_t HTTP_GetStatusPack(struct worker *, struct objcore *oc);
673
int HTTP_IterHdrPack(struct worker *, struct objcore *, const char **);
674
#define HTTP_FOREACH_PACK(wrk, oc, ptr) \
675
         for ((ptr) = NULL; HTTP_IterHdrPack(wrk, oc, &(ptr));)
676
const char *HTTP_GetHdrPack(struct worker *, struct objcore *, hdr_t);
677
stream_close_t http_DoConnection(struct http *hp, stream_close_t sc_close);
678
int http_IsFiltered(const struct http *hp, unsigned u, unsigned how);
679
void http_SetWellKnownMethod(struct http *hp);
680
681
#define HTTPH_R_PASS            (1 << 0)        /* Request (c->b) in pass mode */
682
#define HTTPH_R_FETCH           (1 << 1)        /* Request (c->b) for fetch */
683
#define HTTPH_A_INS             (1 << 2)        /* Response (b->o) for insert */
684
#define HTTPH_A_PASS            (1 << 3)        /* Response (b->o) for pass */
685
#define HTTPH_C_SPECIFIC        (1 << 4)        /* Connection-specific */
686
687
#define HTTPH(a, b, c) extern hdr_t b;
688
#include "tbl/http_headers.h"
689
690
extern hdr_t H__Status;
691
extern hdr_t H__Proto;
692
extern hdr_t H__Reason;
693
694
// rfc7233,l,1207,1208
695
#define http_tok_eq(s1, s2)             (!vct_casecmp(s1, s2))
696
#define http_tok_at(s1, s2, l)          (!vct_caselencmp(s1, s2, l))
697
#define http_ctok_at(s, cs)             (!vct_caselencmp(s, cs, sizeof(cs) - 1))
698
699
// rfc7230,l,1037,1038
700
#define http_scheme_at(str, tok)        http_ctok_at(str, #tok "://")
701
702
// rfc7230,l,1144,1144
703
// rfc7231,l,1156,1158
704
#define http_method_eq(check, wkm)      ((check & wkm) == wkm)
705
#define http_method_among(check, wkms)  ((check & (wkms)) != 0)
706
707
// rfc7230,l,1222,1222
708
// rfc7230,l,2848,2848
709
// rfc7231,l,3883,3885
710
// rfc7234,l,1339,1340
711
// rfc7234,l,1418,1419
712
#define http_hdr_eq(s1, s2)             http_tok_eq(s1, s2)
713
#define http_hdr_at(s1, s2, l)          http_tok_at(s1, s2, l)
714
715
// rfc7230,l,1952,1952
716
// rfc7231,l,604,604
717
#define http_coding_eq(str, tok)        http_tok_eq(str, #tok)
718
719
// rfc7231,l,1864,1864
720
#define http_expect_eq(str, tok)        http_tok_eq(str, #tok)
721
722
// rfc7233,l,1207,1208
723
#define http_range_at(str, tok, l)      http_tok_at(str, #tok, l)
724
725
/* cache_lck.c */
726
727
/* Internal functions, call only through macros below */
728
void Lck__Lock(struct lock *lck, const char *p,  int l);
729
void Lck__Unlock(struct lock *lck, const char *p,  int l);
730
int Lck__Trylock(struct lock *lck, const char *p,  int l);
731
void Lck__New(struct lock *lck, struct VSC_lck *, const char *);
732
int Lck__Held(const struct lock *lck);
733
int Lck__Owned(const struct lock *lck);
734
extern pthread_mutexattr_t mtxattr_errorcheck;
735
736
/* public interface: */
737
void Lck_Delete(struct lock *lck);
738
int Lck_CondWaitUntil(pthread_cond_t *, struct lock *, vtim_real when);
739
int Lck_CondWait(pthread_cond_t *, struct lock *);
740
int Lck_CondWaitTimeout(pthread_cond_t *, struct lock *, vtim_dur timeout);
741
742
#define Lck_New(a, b) Lck__New(a, b, #b)
743
#define Lck_Lock(a) Lck__Lock(a, __func__, __LINE__)
744
#define Lck_Unlock(a) Lck__Unlock(a, __func__, __LINE__)
745
#define Lck_Trylock(a) Lck__Trylock(a, __func__, __LINE__)
746
#define Lck_AssertHeld(a)               \
747
        do {                            \
748
                assert(Lck__Held(a));   \
749
                assert(Lck__Owned(a));  \
750
        } while (0)
751
752
struct VSC_lck *Lck_CreateClass(struct vsc_seg **, const char *);
753
void Lck_DestroyClass(struct vsc_seg **);
754
755
#define LOCK(nam) extern struct VSC_lck *lck_##nam;
756
#include "tbl/locks.h"
757
758
/* cache_obj.c */
759
760
int ObjHasAttr(struct worker *, struct objcore *, enum obj_attr);
761
const void *ObjGetAttr(struct worker *, struct objcore *, enum obj_attr,
762
    ssize_t *len);
763
764
typedef int objiterate_f(void *priv, unsigned flush,
765
    const void *ptr, ssize_t len);
766
#define OBJ_ITER_FLUSH  0x01
767
#define OBJ_ITER_END    0x02
768
769
int ObjIterate(struct worker *, struct objcore *,
770
    void *priv, objiterate_f *func, int final);
771
772
vxid_t ObjGetXID(struct worker *, struct objcore *);
773
uint64_t ObjGetLen(struct worker *, struct objcore *);
774
int ObjGetDouble(struct worker *, struct objcore *, enum obj_attr, double *);
775
int ObjGetU64(struct worker *, struct objcore *, enum obj_attr, uint64_t *);
776
int ObjCheckFlag(struct worker *, struct objcore *, enum obj_flags of);
777
778
/*====================================================================
779
 * ObjVAI...(): Asynchronous Iteration
780
 *
781
 * see comments in cache_obj.c for usage
782
 */
783
784
typedef void *vai_hdl;
785
typedef void vai_notify_cb(vai_hdl, void *priv);
786
787
788
/*
789
 * VSCARAB: Varnish SCatter ARAy of Buffers:
790
 *
791
 * an array of viovs, elsewhere also called an siov or sarray
792
 */
793
struct viov {
794
        uint64_t        lease;
795
        struct iovec    iov;
796
};
797
798
struct vscarab {
799
        unsigned        magic;
800
#define VSCARAB_MAGIC   0x05ca7ab0
801
        unsigned        flags;
802
#define VSCARAB_F_END   1       // last viov is last overall
803
        unsigned        capacity;
804
        unsigned        used;
805
        struct viov     s[] v_counted_by_(capacity);
806
};
807
808
// VFLA: starting generic container-with-flexible-array-member macros
809
// aka "struct hack"
810
//
811
// type : struct name
812
// name : a pointer to struct type
813
// mag  : the magic value for this VFLA
814
// cptr : pointer to container struct (aka "head")
815
// fam  : member name of the flexible array member
816
// cap  : capacity
817
//
818
// common properties of all VFLAs:
819
// - are a miniobj (have magic as the first element)
820
// - capacity member is the fam capacity
821
// - used member is the number of fam elements used
822
//
823
// VFLA_SIZE ignores the cap == 0 case, we assert in _INIT
824
// offsetoff ref: https://gustedt.wordpress.com/2011/03/14/flexible-array-member/
825
//lint -emacro(413, VFLA_SIZE)
826
//lint -emacro(545, VFLA_SIZE) bsd offsetof() seems to be using &
827
#define VFLA_SIZE(type, fam, cap) (offsetof(struct type, fam) + \
828
        (cap) * sizeof(((struct type *)0)->fam[0]))
829
#define VFLA_INIT_(type, cptr, mag, fam, cap, save) do {        \
830
        unsigned save = (cap);                                  \
831
        AN(save);                                               \
832
        memset((cptr), 0, VFLA_SIZE(type, fam, save));          \
833
        (cptr)->magic = (mag);                                  \
834
        (cptr)->capacity = (save);                              \
835
} while (0)
836
#define VFLA_INIT(type, cptr, mag, fam, cap)                    \
837
        VFLA_INIT_(type, cptr, mag, fam, cap, VUNIQ_NAME(save))
838
// declare, allocate and initialize a local VFLA
839
// the additional VLA buf declaration avoids
840
// "Variable-sized object may not be initialized"
841
#define VFLA_LOCAL_(type, name, mag, fam, cap, bufname)                         \
842
        char bufname[VFLA_SIZE(type, fam, cap)];                                \
843
        struct type *name = (void *)bufname;                                    \
844
        VFLA_INIT(type, name, mag, fam, cap)
845
#define VFLA_LOCAL(type, name, mag, fam, cap)                                   \
846
        VFLA_LOCAL_(type, name, mag, fam, cap, VUNIQ_NAME(buf))
847
// malloc and initialize a VFLA
848
#define VFLA_ALLOC(type, name, mag, fam, cap)   do {                    \
849
        (name) = malloc(VFLA_SIZE(type, fam, cap));                     \
850
        if ((name) != NULL)                                             \
851
                VFLA_INIT(type, name, mag, fam, cap);                   \
852
} while(0)
853
#define VFLA_FOREACH(var, cptr, fam)                                            \
854
        for (var = &(cptr)->fam[0];                                             \
855
             (var = (var < &(cptr)->fam[(cptr)->used] ? var : NULL)) != NULL;   \
856
             var++)
857
// continue iterating after a break of a _FOREACH
858
#define VFLA_FOREACH_RESUME(var, cptr, fam)                                     \
859
        for (;                                                                  \
860
             var != NULL &&                                                     \
861
               (var = (var < &(cptr)->fam[(cptr)->used] ? var : NULL)) != NULL; \
862
             var++)
863
#define VFLA_GET(cptr, fam) ((cptr)->used < (cptr)->capacity ? &(cptr)->fam[(cptr)->used++] : NULL)
864
// asserts sufficient capacity
865
#define VFLA_ADD(cptr, fam, val) do {                                           \
866
        assert((cptr)->used < (cptr)->capacity);                                \
867
        (cptr)->fam[(cptr)->used++] = (val);                                    \
868
} while(0)
869
870
#define VSCARAB_SIZE(cap) VFLA_SIZE(vscarab, s, cap)
871
#define VSCARAB_INIT(scarab, cap) VFLA_INIT(vscarab, scarab, VSCARAB_MAGIC, s, cap)
872
#define VSCARAB_LOCAL(scarab, cap) VFLA_LOCAL(vscarab, scarab, VSCARAB_MAGIC, s, cap)
873
#define VSCARAB_ALLOC(scarab, cap) VFLA_ALLOC(vscarab, scarab, VSCARAB_MAGIC, s, cap)
874
#define VSCARAB_FOREACH(var, scarab) VFLA_FOREACH(var, scarab, s)
875
#define VSCARAB_FOREACH_RESUME(var, scarab) VFLA_FOREACH_RESUME(var, scarab, s)
876
#define VSCARAB_GET(scarab) VFLA_GET(scarab, s)
877
#define VSCARAB_ADD(scarab, val) VFLA_ADD(scarab, s, val)
878
//lint -emacro(64, VSCARAB_ADD_IOV_NORET) weird flexelint bug?
879
#define VSCARAB_ADD_IOV_NORET(scarab, vec)                                      \
880
        VSCARAB_ADD(scarab, ((struct viov){.lease = VAI_LEASE_NORET, .iov = (vec)}))
881
#define VSCARAB_LAST(scarab) ((scarab)->used > 0 ?                              \
882
        &(scarab)->s[(scarab)->used - 1] : NULL)
883
884
#define VSCARAB_CHECK(scarab) do {                                              \
885
        CHECK_OBJ(scarab, VSCARAB_MAGIC);                                       \
886
        assert((scarab)->used <= (scarab)->capacity);                           \
887
} while(0)
888
889
#define VSCARAB_CHECK_NOTNULL(scarab) do {                                      \
890
        AN(scarab);                                                             \
891
        VSCARAB_CHECK(scarab);                                                  \
892
} while(0)
893
894
/*
895
 * VSCARET: Varnish SCatter Array Return
896
 *
897
 * an array of leases obtained from a vscarab
898
 */
899
900
struct vscaret {
901
        unsigned        magic;
902
#define VSCARET_MAGIC   0x9c1f3d7b
903
        unsigned        capacity;
904
        unsigned        used;
905
        uint64_t        lease[] v_counted_by_(capacity);
906
};
907
908
#define VSCARET_SIZE(cap) VFLA_SIZE(vscaret, lease, cap)
909
#define VSCARET_INIT(scaret, cap) VFLA_INIT(vscaret, scaret, VSCARET_MAGIC, lease, cap)
910
#define VSCARET_LOCAL(scaret, cap) VFLA_LOCAL(vscaret, scaret, VSCARET_MAGIC, lease, cap)
911
#define VSCARET_ALLOC(scaret, cap) VFLA_ALLOC(vscaret, scaret, VSCARET_MAGIC, lease, cap)
912
#define VSCARET_FOREACH(var, scaret) VFLA_FOREACH(var, scaret, lease)
913
#define VSCARET_GET(scaret) VFLA_GET(scaret, lease)
914
#define VSCARET_ADD(scaret, val) VFLA_ADD(scaret, lease, val)
915
916
#define VSCARET_CHECK(scaret) do {                                              \
917
        CHECK_OBJ(scaret, VSCARET_MAGIC);                                       \
918
        assert(scaret->used <= scaret->capacity);                               \
919
} while(0)
920
921
#define VSCARET_CHECK_NOTNULL(scaret) do {                                      \
922
        AN(scaret);                                                             \
923
        VSCARET_CHECK(scaret);                                                  \
924
} while(0)
925
926
/*
927
 * VSCARABs can contain leases which are not to be returned to storage, for
928
 * example static data or fragments of larger leases to be returned later. For
929
 * these cases, use this magic value as the lease. This is deliberately not 0 to
930
 * catch oversights.
931
 */
932
#define VAI_LEASE_NORET ((uint64_t)0x8)
933
934
vai_hdl ObjVAIinit(struct worker *, struct objcore *, struct ws *,
935
    vai_notify_cb *, void *);
936
int ObjVAIlease(struct worker *, vai_hdl, struct vscarab *);
937
int ObjVAIbuffer(struct worker *, vai_hdl, struct vscarab *);
938
void ObjVAIreturn(struct worker *, vai_hdl, struct vscaret *);
939
void ObjVAIfini(struct worker *, vai_hdl *);
940
941
/* cache_req_body.c */
942
ssize_t VRB_Iterate(struct worker *, struct vsl_log *, struct req *,
943
    objiterate_f *func, void *priv);
944
945
/* cache_session.c [SES] */
946
947
#define SESS_ATTR(UP, low, typ, len)                                    \
948
        int SES_Get_##low(const struct sess *sp, typ **dst);
949
#include "tbl/sess_attr.h"
950
const char *SES_Get_String_Attr(const struct sess *sp, enum sess_attr a);
951
952
/* cache_shmlog.c */
953
void VSLv(enum VSL_tag_e tag, vxid_t vxid, const char *fmt, va_list va);
954
void VSL(enum VSL_tag_e tag, vxid_t vxid, const char *fmt, ...)
955
    v_printflike_(3, 4);
956
void VSLs(enum VSL_tag_e tag, vxid_t vxid, const struct strands *s);
957
void VSLbv(struct vsl_log *, enum VSL_tag_e tag, const char *fmt, va_list va);
958
void VSLb(struct vsl_log *, enum VSL_tag_e tag, const char *fmt, ...)
959
    v_printflike_(3, 4);
960
void VSLbt(struct vsl_log *, enum VSL_tag_e tag, txt t);
961
void VSLbs(struct vsl_log *, enum VSL_tag_e tag, const struct strands *s);
962
void VSLb_ts(struct vsl_log *, const char *event, vtim_real first,
963
    vtim_real *pprev, vtim_real now);
964
void VSLb_bin(struct vsl_log *, enum VSL_tag_e, ssize_t, const void*);
965
int VSL_tag_is_masked(enum VSL_tag_e tag);
966
967
static inline void
968
VSLb_ts_req(struct req *req, const char *event, vtim_real now)
969
{
970
971
        if (isnan(req->t_first) || req->t_first == 0.)
972
                req->t_first = req->t_prev = now;
973
        VSLb_ts(req->vsl, event, req->t_first, &req->t_prev, now);
974
}
975
976
static inline void
977
VSLb_ts_busyobj(struct busyobj *bo, const char *event, vtim_real now)
978
{
979
980
        if (isnan(bo->t_first) || bo->t_first == 0.)
981
                bo->t_first = bo->t_prev = now;
982
        VSLb_ts(bo->vsl, event, bo->t_first, &bo->t_prev, now);
983
}
984
985
/* cache_vcl.c */
986
const char *VCL_Name(const struct vcl *);
987
988
/* cache_wrk.c */
989
990
typedef void *bgthread_t(struct worker *, void *priv);
991
void WRK_BgThread(pthread_t *thr, const char *name, bgthread_t *func,
992
    void *priv);
993
994
/* cache_ws.c */
995
void WS_Init(struct ws *ws, const char *id, void *space, unsigned len);
996
997
unsigned WS_ReserveSize(struct ws *, unsigned);
998
unsigned WS_ReserveAll(struct ws *);
999
void WS_Release(struct ws *ws, unsigned bytes);
1000
void WS_ReleaseP(struct ws *ws, const char *ptr);
1001
void WS_Assert(const struct ws *ws);
1002
void WS_Reset(struct ws *ws, uintptr_t);
1003
void *WS_Alloc(struct ws *ws, unsigned bytes);
1004
void *WS_Copy(struct ws *ws, const void *str, int len);
1005
uintptr_t WS_Snapshot(struct ws *ws);
1006
int WS_Allocated(const struct ws *ws, const void *ptr, ssize_t len);
1007
unsigned WS_Dump(const struct ws *ws, char, size_t off, void *buf, size_t len);
1008
1009
static inline void *
1010 1280
WS_Reservation(const struct ws *ws)
1011
{
1012
1013 1280
        WS_Assert(ws);
1014 1280
        AN(ws->r);
1015 1280
        AN(ws->f);
1016 1280
        return (ws->f);
1017
}
1018
1019
static inline unsigned
1020
WS_ReservationSize(const struct ws *ws)
1021
{
1022
1023
        AN(ws->r);
1024
        return (ws->r - ws->f);
1025
}
1026
1027
static inline unsigned
1028
WS_ReserveLumps(struct ws *ws, size_t sz)
1029
{
1030
1031
        AN(sz);
1032
        return (WS_ReserveAll(ws) / sz);
1033
}
1034
1035
/* cache_ws_common.c */
1036
void WS_MarkOverflow(struct ws *ws);
1037
int WS_Overflowed(const struct ws *ws);
1038
1039
const char *WS_Printf(struct ws *ws, const char *fmt, ...) v_printflike_(2, 3);
1040
1041
void WS_VSB_new(struct vsb *, struct ws *);
1042
char *WS_VSB_finish(struct vsb *, struct ws *, size_t *);
1043
1044
/* WS utility */
1045
#define WS_TASK_ALLOC_OBJ(ctx, ptr, magic) do {                 \
1046
        ptr = WS_Alloc((ctx)->ws, sizeof *(ptr));               \
1047
        if ((ptr) == NULL)                                      \
1048
                VRT_fail(ctx, "Out of workspace for " #magic);  \
1049
        else                                                    \
1050
                INIT_OBJ(ptr, magic);                           \
1051
} while(0)
1052
1053
/* cache_rfc2616.c */
1054
void RFC2616_Ttl(struct busyobj *, vtim_real now, vtim_real *t_origin,
1055
    float *ttl, float *grace, float *keep);
1056
unsigned RFC2616_Req_Gzip(const struct http *);
1057
int RFC2616_Do_Cond(const struct req *sp);
1058
void RFC2616_Weaken_Etag(struct http *hp);
1059
void RFC2616_Vary_AE(struct http *hp);
1060
const char * RFC2616_Strong_LM(const struct http *hp, struct worker *wrk,
1061
    struct objcore *oc);
1062
1063
/*
1064
 * We want to cache the most recent timestamp in wrk->lastused to avoid
1065
 * extra timestamps in cache_pool.c.  Hide this detail with a macro
1066
 */
1067
#define W_TIM_real(w) ((w)->lastused = VTIM_real())