varnish-cache/bin/varnishd/cache/cache.h
1
/*-
2
 * Copyright (c) 2006 Verdens Gang AS
3
 * Copyright (c) 2006-2015 Varnish Software AS
4
 * All rights reserved.
5
 *
6
 * Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions
10
 * are met:
11
 * 1. Redistributions of source code must retain the above copyright
12
 *    notice, this list of conditions and the following disclaimer.
13
 * 2. Redistributions in binary form must reproduce the above copyright
14
 *    notice, this list of conditions and the following disclaimer in the
15
 *    documentation and/or other materials provided with the distribution.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
 * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
21
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27
 * SUCH DAMAGE.
28
 *
29
 */
30
31
#ifdef VRT_H_INCLUDED
32
#  error "vrt.h included before cache.h - they are exclusive"
33
#endif
34
35
#ifdef CACHE_H_INCLUDED
36
#  error "cache.h included multiple times"
37
#endif
38
39
#include <math.h>
40
#include <pthread.h>
41
#include <stdarg.h>
42
#include <sys/types.h>
43
44
#include "vdef.h"
45
#include "vrt.h"
46
47
#define CACHE_H_INCLUDED
48
49
#include "miniobj.h"
50
#include "vas.h"
51
#include "vqueue.h"
52
53
#include "vapi/vsl_int.h"
54
55
/*--------------------------------------------------------------------*/
56
57
enum body_status {
58
#define BODYSTATUS(U,l) BS_##U,
59
#include "tbl/body_status.h"
60
};
61
62
/*--------------------------------------------------------------------*/
63
64
enum req_body_state_e {
65
#define REQ_BODY(U)     REQ_BODY_##U,
66
#include "tbl/req_body.h"
67
};
68
69
/*--------------------------------------------------------------------*/
70
71
enum sess_close {
72
        SC_NULL = 0,
73
#define SESS_CLOSE(nm, stat, err, desc) SC_##nm,
74
#include "tbl/sess_close.h"
75
};
76
77
/*--------------------------------------------------------------------
78
 * Indices into http->hd[]
79
 */
80
enum {
81
#define SLTH(tag, ind, req, resp, sdesc, ldesc) ind,
82
#include "tbl/vsl_tags_http.h"
83
};
84
85
/*--------------------------------------------------------------------*/
86
87
struct VSC_lck;
88
struct VSC_main;
89
struct backend;
90
struct ban;
91
struct ban_proto;
92
struct cli;
93
struct http_conn;
94
struct mempool;
95
struct objcore;
96
struct objhead;
97
struct pool;
98
struct sess;
99
struct transport;
100
struct worker;
101
struct listen_sock;
102
103
#define DIGEST_LEN              32
104
105
/*--------------------------------------------------------------------*/
106
107
typedef struct {
108
        const char              *b;
109
        const char              *e;
110
} txt;
111
112
/*--------------------------------------------------------------------*/
113
114
enum req_step {
115
        R_STP_NONE = 0,
116
#define REQ_STEP(l, u, arg)     R_STP_##u,
117
#include "tbl/steps.h"
118
};
119
120
enum fetch_step {
121
        F_STP_NONE = 0,
122
#define FETCH_STEP(l, U, arg)   F_STP_##U,
123
#include "tbl/steps.h"
124
};
125
126
/*--------------------------------------------------------------------*/
127
128
struct lock { void *priv; };    // Opaque
129
130
/*--------------------------------------------------------------------
131
 * Workspace structure for quick memory allocation.
132
 */
133
134
struct ws {
135
        unsigned                magic;
136
#define WS_MAGIC                0x35fac554
137
        char                    id[4];          /* identity */
138
        char                    *s;             /* (S)tart of buffer */
139
        char                    *f;             /* (F)ree/front pointer */
140
        char                    *r;             /* (R)eserved length */
141
        char                    *e;             /* (E)nd of buffer */
142
};
143
144
/*--------------------------------------------------------------------
145
 *
146
 */
147
148
struct http {
149
        unsigned                magic;
150
#define HTTP_MAGIC              0x6428b5c9
151
152
        uint16_t                shd;            /* Size of hd space */
153
        txt                     *hd;
154
        unsigned char           *hdf;
155
#define HDF_FILTER              (1 << 0)        /* Filtered by Connection */
156
157
        /* NB: ->nhd and below zeroed/initialized by http_Teardown */
158
        uint16_t                nhd;            /* Next free hd */
159
160
        enum VSL_tag_e          logtag;         /* Must be SLT_*Method */
161
        struct vsl_log          *vsl;
162
163
        struct ws               *ws;
164
        uint16_t                status;
165
        uint8_t                 protover;
166
        uint8_t                 conds;          /* If-* headers present */
167
};
168
169
/*--------------------------------------------------------------------*/
170
171
struct acct_req {
172
#define ACCT(foo)       uint64_t        foo;
173
#include "tbl/acct_fields_req.h"
174
};
175
176
/*--------------------------------------------------------------------*/
177
178
struct acct_bereq {
179
#define ACCT(foo)       uint64_t        foo;
180
#include "tbl/acct_fields_bereq.h"
181
};
182
183
/*--------------------------------------------------------------------*/
184
185
struct vsl_log {
186
        uint32_t                *wlb, *wlp, *wle;
187
        unsigned                wlr;
188
        unsigned                wid;
189
};
190
191
/*--------------------------------------------------------------------*/
192
193
struct vxid_pool {
194
        uint32_t                next;
195
        uint32_t                count;
196
};
197
198
/*--------------------------------------------------------------------*/
199
200
struct vrt_privs {
201
        unsigned                magic;
202
#define VRT_PRIVS_MAGIC         0x03ba7501
203
        VTAILQ_HEAD(,vrt_priv)  privs;
204
};
205
206
/* Worker pool stuff -------------------------------------------------*/
207
208
typedef void task_func_t(struct worker *wrk, void *priv);
209
210
struct pool_task {
211
        VTAILQ_ENTRY(pool_task)         list;
212
        task_func_t                     *func;
213
        void                            *priv;
214
};
215
216
/*
217
 * tasks are taken off the queues in this order
218
 *
219
 * prios up to TASK_QUEUE_RESERVE are run from the reserve
220
 */
221
enum task_prio {
222
        TASK_QUEUE_BO,
223
#define TASK_QUEUE_RESERVE      TASK_QUEUE_BO
224
        TASK_QUEUE_REQ,
225
        TASK_QUEUE_STR,
226
        TASK_QUEUE_VCA,
227
        TASK_QUEUE_END
228
};
229
230
#define TASK_QUEUE_CLIENT(prio) \
231
        (prio == TASK_QUEUE_REQ || prio == TASK_QUEUE_STR)
232
233
/*--------------------------------------------------------------------*/
234
235
struct worker {
236
        unsigned                magic;
237
#define WORKER_MAGIC            0x6391adcf
238
        struct pool             *pool;
239
        struct objhead          *nobjhead;
240
        struct objcore          *nobjcore;
241
        void                    *nhashpriv;
242
        struct VSC_main         *stats;
243
        struct vsl_log          *vsl;           // borrowed from req/bo
244
245
        struct pool_task        task;
246
247
        double                  lastused;
248
        int                     strangelove;
249
250
        struct v1l              *v1l;
251
252
        pthread_cond_t          cond;
253
254
        struct vcl              *vcl;
255
256
        struct ws               aws[1];
257
258
        struct vxid_pool        vxid_pool;
259
260
        unsigned                cur_method;
261
        unsigned                seen_methods;
262
        unsigned                handling;
263
};
264
265
/* Stored object -----------------------------------------------------
266
 * This is just to encapsulate the fields owned by the stevedore
267
 */
268
269
struct storeobj {
270
        const struct stevedore  *stevedore;
271
        void                    *priv;
272
        uintptr_t               priv2;
273
};
274
275
/* Busy Objcore structure --------------------------------------------
276
 *
277
 */
278
279
/*
280
 * The macro-states we expose outside the fetch code
281
 */
282
enum boc_state_e {
283
#define BOC_STATE(U, l)       BOS_##U,
284
#include "tbl/boc_state.h"
285
};
286
287
struct boc {
288
        unsigned                magic;
289
#define BOC_MAGIC               0x70c98476
290
        unsigned                refcount;
291
        struct lock             mtx;
292
        pthread_cond_t          cond;
293
        void                    *stevedore_priv;
294
        enum boc_state_e        state;
295
        uint8_t                 *vary;
296
        uint64_t                len_so_far;
297
};
298
299
/* Object core structure ---------------------------------------------
300
 * Objects have sideways references in the binary heap and the LRU list
301
 * and we want to avoid paging in a lot of objects just to move them up
302
 * or down the binheap or to move a unrelated object on the LRU list.
303
 * To avoid this we use a proxy object, objcore, to hold the relevant
304
 * housekeeping fields parts of an object.
305
 */
306
307
enum obj_attr {
308
#define OBJ_FIXATTR(U, l, s)    OA_##U,
309
#define OBJ_VARATTR(U, l)       OA_##U,
310
#define OBJ_AUXATTR(U, l)       OA_##U,
311
#include "tbl/obj_attr.h"
312
                                OA__MAX,
313
};
314
315
enum obj_flags {
316
#define OBJ_FLAG(U, l, v)       OF_##U = v,
317
#include "tbl/obj_attr.h"
318
};
319
320
enum oc_flags {
321
#define OC_FLAG(U, l, v)        OC_F_##U = v,
322
#include "tbl/oc_flags.h"
323
};
324
325
enum oc_exp_flags {
326
#define OC_EXP_FLAG(U, l, v)    OC_EF_##U = v,
327
#include "tbl/oc_exp_flags.h"
328
};
329
330
struct objcore {
331
        unsigned                magic;
332
#define OBJCORE_MAGIC           0x4d301302
333
        int                     refcnt;
334
        struct storeobj         stobj[1];
335
        struct objhead          *objhead;
336
        struct boc              *boc;
337
        double                  timer_when;
338
        long                    hits;
339
340
        double                  t_origin;
341
        float                   ttl;
342
        float                   grace;
343
        float                   keep;
344
345
        uint8_t                 flags;
346
347
        uint8_t                 exp_flags;
348
349
        uint16_t                oa_present;
350
351
        unsigned                timer_idx;      // XXX 4Gobj limit
352
        double                  last_lru;
353
        VTAILQ_ENTRY(objcore)   hsh_list;
354
        VTAILQ_ENTRY(objcore)   lru_list;
355
        VTAILQ_ENTRY(objcore)   ban_list;
356
        VSTAILQ_ENTRY(objcore)  exp_list;
357
        struct ban              *ban;
358
};
359
360
/* Busy Object structure ---------------------------------------------
361
 *
362
 * The busyobj structure captures the aspects of an object related to,
363
 * and while it is being fetched from the backend.
364
 *
365
 * One of these aspects will be how much has been fetched, which
366
 * streaming delivery will make use of.
367
 */
368
369
enum director_state_e {
370
        DIR_S_NULL = 0,
371
        DIR_S_HDRS = 1,
372
        DIR_S_BODY = 2,
373
};
374
375
struct busyobj {
376
        unsigned                magic;
377
#define BUSYOBJ_MAGIC           0x23b95567
378
379
        char                    *end;
380
381
        /*
382
         * All fields from retries and down are zeroed when the busyobj
383
         * is recycled.
384
         */
385
        int                     retries;
386
        struct req              *req;
387
        struct sess             *sp;
388
        struct worker           *wrk;
389
390
        struct vfp_ctx          *vfc;
391
        const char              *filter_list;
392
393
        struct ws               ws[1];
394
        uintptr_t               ws_bo;
395
        struct http             *bereq0;
396
        struct http             *bereq;
397
        struct http             *beresp;
398
        struct objcore          *stale_oc;
399
        struct objcore          *fetch_objcore;
400
401
        struct http_conn        *htc;
402
403
        struct pool_task        fetch_task;
404
405
#define BO_FLAG(l, r, w, d) unsigned    l:1;
406
#include "tbl/bo_flags.h"
407
408
        /* Timeouts */
409
        double                  connect_timeout;
410
        double                  first_byte_timeout;
411
        double                  between_bytes_timeout;
412
413
        /* Timers */
414
        double                  t_first;        /* First timestamp logged */
415
        double                  t_prev;         /* Previous timestamp logged */
416
417
        /* Acct */
418
        struct acct_bereq       acct;
419
420
        const struct stevedore  *storage;
421
        const struct director   *director_req;
422
        const struct director   *director_resp;
423
        enum director_state_e   director_state;
424
        struct vcl              *vcl;
425
426
        struct vsl_log          vsl[1];
427
428
        uint8_t                 digest[DIGEST_LEN];
429
        struct vrt_privs        privs[1];
430
};
431
432
433
/*--------------------------------------------------------------------*/
434
435
struct req {
436
        unsigned                magic;
437
#define REQ_MAGIC               0x2751aaa1
438
439
        enum req_step           req_step;
440
        volatile enum req_body_state_e  req_body_status;
441
        enum sess_close         doclose;
442
        int                     restarts;
443
        int                     esi_level;
444
        struct req              *top;   /* esi_level == 0 request */
445
446
#define REQ_FLAG(l, r, w, d) unsigned   l:1;
447
#include "tbl/req_flags.h"
448
449
        uint16_t                err_code;
450
        const char              *err_reason;
451
452
        struct sess             *sp;
453
        struct worker           *wrk;
454
        struct pool_task        task;
455
456
        const struct transport  *transport;
457
        void                    *transport_priv;
458
459
        VTAILQ_ENTRY(req)       w_list;
460
461
        struct objcore          *body_oc;
462
463
        /* The busy objhead we sleep on */
464
        struct objhead          *hash_objhead;
465
466
        /* Built Vary string */
467
        uint8_t                 *vary_b;
468
        uint8_t                 *vary_l;
469
        uint8_t                 *vary_e;
470
471
        uint8_t                 digest[DIGEST_LEN];
472
473
        double                  d_ttl;
474
        double                  d_grace;
475
476
        ssize_t                 req_bodybytes;  /* Parsed req bodybytes */
477
        const struct stevedore  *storage;
478
479
        const struct director   *director_hint;
480
        struct vcl              *vcl;
481
482
        uintptr_t               ws_req;         /* WS above request data */
483
484
        /* Timestamps */
485
        double                  t_first;        /* First timestamp logged */
486
        double                  t_prev;         /* Previous timestamp logged */
487
        double                  t_req;          /* Headers complete */
488
489
        struct http_conn        *htc;
490
        struct vfp_ctx          *vfc;
491
        const char              *client_identity;
492
493
        /* HTTP request */
494
        struct http             *http;
495
        struct http             *http0;
496
497
        /* HTTP response */
498
        struct http             *resp;
499
        intmax_t                resp_len;
500
501
        struct ws               ws[1];
502
        struct objcore          *objcore;
503
        struct objcore          *stale_oc;
504
505
        /* Deliver pipeline */
506
        struct vdp_ctx          *vdc;
507
508
        /* Delivery mode */
509
        unsigned                res_mode;
510
#define RES_LEN                 (1<<1)
511
#define RES_EOF                 (1<<2)
512
#define RES_CHUNKED             (1<<3)
513
#define RES_ESI                 (1<<4)
514
#define RES_ESI_CHILD           (1<<5)
515
#define RES_GUNZIP              (1<<6)
516
#define RES_PIPE                (1<<7)
517
518
        /* Transaction VSL buffer */
519
        struct vsl_log          vsl[1];
520
521
        /* Temporary accounting */
522
        struct acct_req         acct;
523
524
        struct vrt_privs        privs[1];
525
};
526
527
/*--------------------------------------------------------------------
528
 * Struct sess is a high memory-load structure because sessions typically
529
 * hang around the waiter for relatively long time.
530
 *
531
 * The size goal for struct sess + struct memitem is <512 bytes
532
 *
533
 * Getting down to the next relevant size (<256 bytes because of how malloc
534
 * works, is not realistic without a lot of code changes.
535
 */
536
537
enum sess_attr {
538
#define SESS_ATTR(UP, low, typ, len)    SA_##UP,
539
        SA_TRANSPORT,
540
#include "tbl/sess_attr.h"
541
        SA_LAST
542
};
543
544
struct sess {
545
        unsigned                magic;
546
#define SESS_MAGIC              0x2c2f9c5a
547
548
        uint16_t                sattr[SA_LAST];
549
        struct listen_sock      *listen_sock;
550
        int                     refcnt;
551
        int                     fd;
552
        uint32_t                vxid;
553
554
        struct lock             mtx;
555
556
        struct pool             *pool;
557
558
        struct ws               ws[1];
559
560
        /* Timestamps, all on TIM_real() timescale */
561
        double                  t_open;         /* fd accepted */
562
        double                  t_idle;         /* fd accepted or resp sent */
563
564
};
565
566
/* Prototypes etc ----------------------------------------------------*/
567
568
569
/* cache_ban.c */
570
571
/* for constructing bans */
572
struct ban_proto *BAN_Build(void);
573
const char *BAN_AddTest(struct ban_proto *,
574
    const char *, const char *, const char *);
575
const char *BAN_Commit(struct ban_proto *b, struct VSC_main *stats);
576
void BAN_Abandon(struct ban_proto *b);
577
578
/* cache_cli.c [CLI] */
579
extern pthread_t cli_thread;
580
#define ASSERT_CLI() do {assert(pthread_self() == cli_thread);} while (0)
581
582
/* cache_http.c */
583
unsigned HTTP_estimate(unsigned nhttp);
584
void HTTP_Copy(struct http *to, const struct http * const fm);
585
struct http *HTTP_create(void *p, uint16_t nhttp, unsigned);
586
const char *http_Status2Reason(unsigned, const char **);
587
unsigned http_EstimateWS(const struct http *fm, unsigned how);
588
void http_PutResponse(struct http *to, const char *proto, uint16_t status,
589
    const char *response);
590
void http_FilterReq(struct http *to, const struct http *fm, unsigned how);
591
void HTTP_Encode(const struct http *fm, uint8_t *, unsigned len, unsigned how);
592
int HTTP_Decode(struct http *to, const uint8_t *fm);
593
void http_ForceHeader(struct http *to, const char *hdr, const char *val);
594
void http_PrintfHeader(struct http *to, const char *fmt, ...)
595
    v_printflike_(2, 3);
596
void http_TimeHeader(struct http *to, const char *fmt, double now);
597
void http_Proto(struct http *to);
598
void http_SetHeader(struct http *to, const char *hdr);
599
void http_SetH(struct http *to, unsigned n, const char *fm);
600
void http_ForceField(struct http *to, unsigned n, const char *t);
601
void HTTP_Setup(struct http *, struct ws *, struct vsl_log *, enum VSL_tag_e);
602
void http_Teardown(struct http *ht);
603
int http_GetHdr(const struct http *hp, const char *hdr, const char **ptr);
604
int http_GetHdrToken(const struct http *hp, const char *hdr,
605
    const char *token, const char **pb, const char **pe);
606
int http_GetHdrField(const struct http *hp, const char *hdr,
607
    const char *field, const char **ptr);
608
double http_GetHdrQ(const struct http *hp, const char *hdr, const char *field);
609
ssize_t http_GetContentLength(const struct http *hp);
610
uint16_t http_GetStatus(const struct http *hp);
611
int http_IsStatus(const struct http *hp, int);
612
void http_SetStatus(struct http *to, uint16_t status);
613
const char *http_GetMethod(const struct http *hp);
614
int http_HdrIs(const struct http *hp, const char *hdr, const char *val);
615
void http_CopyHome(const struct http *hp);
616
void http_Unset(struct http *hp, const char *hdr);
617
unsigned http_CountHdr(const struct http *hp, const char *hdr);
618
void http_CollectHdr(struct http *hp, const char *hdr);
619
void http_CollectHdrSep(struct http *hp, const char *hdr, const char *sep);
620
void http_VSL_log(const struct http *hp);
621
void HTTP_Merge(struct worker *, struct objcore *, struct http *to);
622
uint16_t HTTP_GetStatusPack(struct worker *, struct objcore *oc);
623
int HTTP_IterHdrPack(struct worker *, struct objcore *, const char **);
624
#define HTTP_FOREACH_PACK(wrk, oc, ptr) \
625
         for ((ptr) = NULL; HTTP_IterHdrPack(wrk, oc, &(ptr));)
626
const char *HTTP_GetHdrPack(struct worker *, struct objcore *, const char *hdr);
627
enum sess_close http_DoConnection(struct http *hp);
628
629
#define HTTPH_R_PASS    (1 << 0)        /* Request (c->b) in pass mode */
630
#define HTTPH_R_FETCH   (1 << 1)        /* Request (c->b) for fetch */
631
#define HTTPH_A_INS     (1 << 2)        /* Response (b->o) for insert */
632
#define HTTPH_A_PASS    (1 << 3)        /* Response (b->o) for pass */
633
634
#define HTTPH(a, b, c) extern char b[];
635
#include "tbl/http_headers.h"
636
637
extern const char H__Status[];
638
extern const char H__Proto[];
639
extern const char H__Reason[];
640
641
/* cache_main.c */
642
#define VXID(u) ((u) & VSL_IDENTMASK)
643
uint32_t VXID_Get(struct worker *, uint32_t marker);
644
extern pthread_key_t witness_key;
645
646
/* cache_lck.c */
647
648
/* Internal functions, call only through macros below */
649
void Lck__Lock(struct lock *lck, const char *p,  int l);
650
void Lck__Unlock(struct lock *lck, const char *p,  int l);
651
int Lck__Trylock(struct lock *lck, const char *p,  int l);
652
void Lck__New(struct lock *lck, struct VSC_lck *, const char *);
653
int Lck__Held(const struct lock *lck);
654
int Lck__Owned(const struct lock *lck);
655
656
/* public interface: */
657
void Lck_Delete(struct lock *lck);
658
int Lck_CondWait(pthread_cond_t *cond, struct lock *lck, double);
659
660
#define Lck_New(a, b) Lck__New(a, b, #b)
661
#define Lck_Lock(a) Lck__Lock(a, __func__, __LINE__)
662
#define Lck_Unlock(a) Lck__Unlock(a, __func__, __LINE__)
663
#define Lck_Trylock(a) Lck__Trylock(a, __func__, __LINE__)
664
#define Lck_AssertHeld(a)               \
665
        do {                            \
666
                assert(Lck__Held(a));   \
667
                assert(Lck__Owned(a));  \
668
        } while (0)
669
670
struct VSC_lck *Lck_CreateClass(struct vsc_seg **, const char *);
671
void Lck_DestroyClass(struct vsc_seg **);
672
673
#define LOCK(nam) extern struct VSC_lck *lck_##nam;
674
#include "tbl/locks.h"
675
676
/* cache_obj.c */
677
678
int ObjHasAttr(struct worker *, struct objcore *, enum obj_attr);
679
const void *ObjGetAttr(struct worker *, struct objcore *, enum obj_attr,
680
    ssize_t *len);
681
682
typedef int objiterate_f(void *priv, int flush, const void *ptr, ssize_t len);
683
684
int ObjIterate(struct worker *, struct objcore *,
685
    void *priv, objiterate_f *func, int final);
686
687
unsigned ObjGetXID(struct worker *, struct objcore *);
688
uint64_t ObjGetLen(struct worker *, struct objcore *);
689
int ObjGetDouble(struct worker *, struct objcore *, enum obj_attr, double *);
690
int ObjGetU32(struct worker *, struct objcore *, enum obj_attr, uint32_t *);
691
int ObjGetU64(struct worker *, struct objcore *, enum obj_attr, uint64_t *);
692
int ObjCheckFlag(struct worker *, struct objcore *, enum obj_flags of);
693
/* cache_session.c [SES] */
694
695
#define SESS_ATTR(UP, low, typ, len)                                    \
696
        int SES_Get_##low(const struct sess *sp, typ **dst);
697
#include "tbl/sess_attr.h"
698
const char *SES_Get_String_Attr(const struct sess *sp, enum sess_attr a);
699
700
/* cache_shmlog.c */
701
void VSLv(enum VSL_tag_e tag, uint32_t vxid, const char *fmt, va_list va);
702
void VSL(enum VSL_tag_e tag, uint32_t vxid, const char *fmt, ...)
703
    v_printflike_(3, 4);
704
void VSLbv(struct vsl_log *, enum VSL_tag_e tag, const char *fmt, va_list va);
705
void VSLb(struct vsl_log *, enum VSL_tag_e tag, const char *fmt, ...)
706
    v_printflike_(3, 4);
707
void VSLbt(struct vsl_log *, enum VSL_tag_e tag, txt t);
708
void VSLb_ts(struct vsl_log *, const char *event, double first, double *pprev,
709
    double now);
710
void VSLb_bin(struct vsl_log *, enum VSL_tag_e, ssize_t, const void*);
711
712
static inline void
713 33933
VSLb_ts_req(struct req *req, const char *event, double now)
714
{
715
716 33933
        if (isnan(req->t_first) || req->t_first == 0.)
717 738
                req->t_first = req->t_prev = now;
718 33933
        VSLb_ts(req->vsl, event, req->t_first, &req->t_prev, now);
719 33933
}
720
721
static inline void
722 19752
VSLb_ts_busyobj(struct busyobj *bo, const char *event, double now)
723
{
724
725 19752
        if (isnan(bo->t_first) || bo->t_first == 0.)
726 4935
                bo->t_first = bo->t_prev = now;
727 19752
        VSLb_ts(bo->vsl, event, bo->t_first, &bo->t_prev, now);
728 19752
}
729
730
/* cache_vcl.c */
731
const char *VCL_Name(const struct vcl *);
732
733
/* cache_vrt.c */
734
/*
735
 * These prototypes go here, because we do not want to pollute vrt.h
736
 * with va_list.  VCC never generates direct calls to them.
737
 * XXX: We should deprecate these (ref: STRANDS)
738
 */
739
const char *VRT_String(struct ws *ws, const char *h, const char *p, va_list ap);
740
char *VRT_StringList(char *d, unsigned dl, const char *p, va_list ap);
741
742
/* cache_wrk.c */
743
744
typedef void *bgthread_t(struct worker *, void *priv);
745
void WRK_BgThread(pthread_t *thr, const char *name, bgthread_t *func,
746
    void *priv);
747
748
/* cache_ws.c */
749
750
void WS_Init(struct ws *ws, const char *id, void *space, unsigned len);
751
unsigned WS_Reserve(struct ws *ws, unsigned bytes);
752
unsigned WS_ReserveLumps(struct ws *ws, size_t sz);
753
void WS_MarkOverflow(struct ws *ws);
754
void WS_Release(struct ws *ws, unsigned bytes);
755
void WS_ReleaseP(struct ws *ws, const char *ptr);
756
void WS_Assert(const struct ws *ws);
757
void WS_Reset(struct ws *ws, uintptr_t);
758
void *WS_Alloc(struct ws *ws, unsigned bytes);
759
void *WS_Copy(struct ws *ws, const void *str, int len);
760
uintptr_t WS_Snapshot(struct ws *ws);
761
int WS_Overflowed(const struct ws *ws);
762
void *WS_Printf(struct ws *ws, const char *fmt, ...) v_printflike_(2, 3);
763
int WS_Inside(const struct ws *, const void *, const void *);
764
void WS_Assert_Allocated(const struct ws *ws, const void *ptr, ssize_t len);
765
766
static inline char*
767 2028
WS_Front(const struct ws *ws)
768
{
769 2028
        return ws->f;
770
}
771
772
/* cache_rfc2616.c */
773
void RFC2616_Ttl(struct busyobj *, double now, double *t_origin,
774
    float *ttl, float *grace, float *keep);
775
unsigned RFC2616_Req_Gzip(const struct http *);
776
int RFC2616_Do_Cond(const struct req *sp);
777
void RFC2616_Weaken_Etag(struct http *hp);
778
void RFC2616_Vary_AE(struct http *hp);
779
void RFC2616_Response_Body(const struct worker *, const struct busyobj *);
780
781
/*
782
 * A normal pointer difference is signed, but we never want a negative value
783
 * so this little tool will make sure we don't get that.
784
 */
785
786
static inline unsigned
787 186254
pdiff(const void *b, const void *e)
788
{
789
790 186254
        assert(b <= e);
791
        return
792 186254
            ((unsigned)((const unsigned char *)e - (const unsigned char *)b));
793
}
794
795
#define Tcheck(t) do {                                          \
796
                AN((t).b);                                      \
797
                AN((t).e);                                      \
798
                assert((t).b <= (t).e);                         \
799
        } while(0)
800
801
/*
802
 * unsigned length of a txt
803
 */
804
805
static inline unsigned
806 400180
Tlen(const txt t)
807
{
808
809 400180
        Tcheck(t);
810 400180
        return ((unsigned)(t.e - t.b));
811
}
812
813
/*
814
 * We want to cache the most recent timestamp in wrk->lastused to avoid
815
 * extra timestamps in cache_pool.c.  Hide this detail with a macro
816
 */
817
#define W_TIM_real(w) ((w)->lastused = VTIM_real())
818
819
#define PAN_CheckMagic(vsb, ptr, exp)                                   \
820
        do {                                                            \
821
                if ((ptr)->magic != (exp))                              \
822
                        VSB_printf((vsb),                               \
823
                            "MAGIC at %p is 0x%08x (Should be: %s/0x%08x)\n", \
824
                            ptr, (ptr)->magic, #exp, exp);              \
825
        } while(0)