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