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