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 cli_proto;
94
struct mempool;
95
struct objcore;
96
struct objhead;
97
struct pool;
98
struct poolparam;
99
struct sess;
100
struct transport;
101
struct worker;
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
struct lock { void *priv; };    // Opaque
128
129
/*--------------------------------------------------------------------
130
 * Workspace structure for quick memory allocation.
131
 */
132
133
struct ws {
134
        unsigned                magic;
135
#define WS_MAGIC                0x35fac554
136
        char                    id[4];          /* identity */
137
        char                    *s;             /* (S)tart of buffer */
138
        char                    *f;             /* (F)ree/front pointer */
139
        char                    *r;             /* (R)eserved length */
140
        char                    *e;             /* (E)nd of buffer */
141
};
142
143
/*--------------------------------------------------------------------
144
 *
145
 */
146
147
struct http {
148
        unsigned                magic;
149
#define HTTP_MAGIC              0x6428b5c9
150
151
        uint16_t                shd;            /* Size of hd space */
152
        txt                     *hd;
153
        unsigned char           *hdf;
154
#define HDF_FILTER              (1 << 0)        /* Filtered by Connection */
155
156
        /* NB: ->nhd and below zeroed/initialized by http_Teardown */
157
        uint16_t                nhd;            /* Next free hd */
158
159
        enum VSL_tag_e          logtag;         /* Must be SLT_*Method */
160
        struct vsl_log          *vsl;
161
162
        struct ws               *ws;
163
        uint16_t                status;
164
        uint8_t                 protover;
165
        uint8_t                 conds;          /* If-* headers present */
166
};
167
168
/*--------------------------------------------------------------------
169
 * HTTP Protocol connection structure
170
 *
171
 * This is the protocol independent object for a HTTP connection, used
172
 * both for backend and client sides.
173
 *
174
 */
175
176
struct http_conn {
177
        unsigned                magic;
178
#define HTTP_CONN_MAGIC         0x3e19edd1
179
180
        int                     *rfd;
181
        enum sess_close         doclose;
182
        enum body_status        body_status;
183
        struct ws               *ws;
184
        char                    *rxbuf_b;
185
        char                    *rxbuf_e;
186
        char                    *pipeline_b;
187
        char                    *pipeline_e;
188
        ssize_t                 content_length;
189
        void                    *priv;
190
191
        /* Timeouts */
192
        double                  first_byte_timeout;
193
        double                  between_bytes_timeout;
194
};
195
196
/*--------------------------------------------------------------------*/
197
198
struct acct_req {
199
#define ACCT(foo)       uint64_t        foo;
200
#include "tbl/acct_fields_req.h"
201
};
202
203
/*--------------------------------------------------------------------*/
204
205
struct acct_bereq {
206
#define ACCT(foo)       uint64_t        foo;
207
#include "tbl/acct_fields_bereq.h"
208
};
209
210
/*--------------------------------------------------------------------*/
211
212
struct vsl_log {
213
        uint32_t                *wlb, *wlp, *wle;
214
        unsigned                wlr;
215
        unsigned                wid;
216
};
217
218
/*--------------------------------------------------------------------*/
219
220
struct vxid_pool {
221
        uint32_t                next;
222
        uint32_t                count;
223
};
224
225
/*--------------------------------------------------------------------*/
226
227
struct vrt_privs {
228
        unsigned                magic;
229
#define VRT_PRIVS_MAGIC         0x03ba7501
230
        VTAILQ_HEAD(,vrt_priv)  privs;
231
};
232
233
/* Worker pool stuff -------------------------------------------------*/
234
235
typedef void task_func_t(struct worker *wrk, void *priv);
236
237
struct pool_task {
238
        VTAILQ_ENTRY(pool_task)         list;
239
        task_func_t                     *func;
240
        void                            *priv;
241
};
242
243
/*
244
 * tasks are taken off the queues in this order
245
 *
246
 * prios up to TASK_QUEUE_RESERVE are run from the reserve
247
 */
248
enum task_prio {
249
        TASK_QUEUE_BO,
250
#define TASK_QUEUE_RESERVE      TASK_QUEUE_BO
251
        TASK_QUEUE_REQ,
252
        TASK_QUEUE_STR,
253
        TASK_QUEUE_VCA,
254
        TASK_QUEUE_END
255
};
256
257
#define TASK_QUEUE_CLIENT(prio) \
258
        (prio == TASK_QUEUE_REQ || prio == TASK_QUEUE_STR)
259
260
/*--------------------------------------------------------------------*/
261
262
struct worker {
263
        unsigned                magic;
264
#define WORKER_MAGIC            0x6391adcf
265
        struct pool             *pool;
266
        struct objhead          *nobjhead;
267
        struct objcore          *nobjcore;
268
        void                    *nhashpriv;
269
        struct VSC_main         *stats;
270
        struct vsl_log          *vsl;           // borrowed from req/bo
271
272
        struct pool_task        task;
273
274
        double                  lastused;
275
        int                     strangelove;
276
277
        struct v1l              *v1l;
278
279
        pthread_cond_t          cond;
280
281
        struct vcl              *vcl;
282
283
        struct ws               aws[1];
284
285
        struct vxid_pool        vxid_pool;
286
287
        unsigned                cur_method;
288
        unsigned                seen_methods;
289
        unsigned                handling;
290
};
291
292
/* Stored object -----------------------------------------------------
293
 * This is just to encapsulate the fields owned by the stevedore
294
 */
295
296
struct storeobj {
297
        const struct stevedore  *stevedore;
298
        void                    *priv;
299
        uintptr_t               priv2;
300
};
301
302
/* Busy Objcore structure --------------------------------------------
303
 *
304
 */
305
306
/*
307
 * The macro-states we expose outside the fetch code
308
 */
309
enum boc_state_e {
310
#define BOC_STATE(U, l)       BOS_##U,
311
#include "tbl/boc_state.h"
312
};
313
314
struct boc {
315
        unsigned                magic;
316
#define BOC_MAGIC               0x70c98476
317
        unsigned                refcount;
318
        struct lock             mtx;
319
        pthread_cond_t          cond;
320
        void                    *stevedore_priv;
321
        enum boc_state_e        state;
322
        uint8_t                 *vary;
323
        uint64_t                len_so_far;
324
};
325
326
/* Object core structure ---------------------------------------------
327
 * Objects have sideways references in the binary heap and the LRU list
328
 * and we want to avoid paging in a lot of objects just to move them up
329
 * or down the binheap or to move a unrelated object on the LRU list.
330
 * To avoid this we use a proxy object, objcore, to hold the relevant
331
 * housekeeping fields parts of an object.
332
 */
333
334
enum obj_attr {
335
#define OBJ_FIXATTR(U, l, s)    OA_##U,
336
#define OBJ_VARATTR(U, l)       OA_##U,
337
#define OBJ_AUXATTR(U, l)       OA_##U,
338
#include "tbl/obj_attr.h"
339
                                OA__MAX,
340
};
341
342
enum obj_flags {
343
#define OBJ_FLAG(U, l, v)       OF_##U = v,
344
#include "tbl/obj_attr.h"
345
};
346
347
enum oc_flags {
348
#define OC_FLAG(U, l, v)        OC_F_##U = v,
349
#include "tbl/oc_flags.h"
350
};
351
352
enum oc_exp_flags {
353
#define OC_EXP_FLAG(U, l, v)    OC_EF_##U = v,
354
#include "tbl/oc_exp_flags.h"
355
};
356
357
struct objcore {
358
        unsigned                magic;
359
#define OBJCORE_MAGIC           0x4d301302
360
        int                     refcnt;
361
        struct storeobj         stobj[1];
362
        struct objhead          *objhead;
363
        struct boc              *boc;
364
        double                  timer_when;
365
        long                    hits;
366
367
        double                  t_origin;
368
        float                   ttl;
369
        float                   grace;
370
        float                   keep;
371
372
        uint8_t                 flags;
373
374
        uint8_t                 exp_flags;
375
376
        uint16_t                oa_present;
377
378
        unsigned                timer_idx;      // XXX 4Gobj limit
379
        float                   last_lru;
380
        VTAILQ_ENTRY(objcore)   hsh_list;
381
        VTAILQ_ENTRY(objcore)   lru_list;
382
        VTAILQ_ENTRY(objcore)   ban_list;
383
        VSTAILQ_ENTRY(objcore)  exp_list;
384
        struct ban              *ban;
385
};
386
387
/* Busy Object structure ---------------------------------------------
388
 *
389
 * The busyobj structure captures the aspects of an object related to,
390
 * and while it is being fetched from the backend.
391
 *
392
 * One of these aspects will be how much has been fetched, which
393
 * streaming delivery will make use of.
394
 */
395
396
enum director_state_e {
397
        DIR_S_NULL = 0,
398
        DIR_S_HDRS = 1,
399
        DIR_S_BODY = 2,
400
};
401
402
struct busyobj {
403
        unsigned                magic;
404
#define BUSYOBJ_MAGIC           0x23b95567
405
406
        char                    *end;
407
408
        /*
409
         * All fields from retries and down are zeroed when the busyobj
410
         * is recycled.
411
         */
412
        int                     retries;
413
        struct req              *req;
414
        struct sess             *sp;
415
        struct worker           *wrk;
416
417
        struct vfp_ctx          *vfc;
418
419
        struct ws               ws[1];
420
        uintptr_t               ws_bo;
421
        struct http             *bereq0;
422
        struct http             *bereq;
423
        struct http             *beresp;
424
        struct objcore          *stale_oc;
425
        struct objcore          *fetch_objcore;
426
427
        struct http_conn        *htc;
428
429
        struct pool_task        fetch_task;
430
431
#define BO_FLAG(l, r, w, d) unsigned    l:1;
432
#include "tbl/bo_flags.h"
433
434
        /* Timeouts */
435
        double                  connect_timeout;
436
        double                  first_byte_timeout;
437
        double                  between_bytes_timeout;
438
439
        /* Timers */
440
        double                  t_first;        /* First timestamp logged */
441
        double                  t_prev;         /* Previous timestamp logged */
442
443
        /* Acct */
444
        struct acct_bereq       acct;
445
446
        const struct stevedore  *storage;
447
        const struct director   *director_req;
448
        const struct director   *director_resp;
449
        enum director_state_e   director_state;
450
        struct vcl              *vcl;
451
452
        struct vsl_log          vsl[1];
453
454
        uint8_t                 digest[DIGEST_LEN];
455
        struct vrt_privs        privs[1];
456
};
457
458
459
/*--------------------------------------------------------------------*/
460
461
struct req {
462
        unsigned                magic;
463
#define REQ_MAGIC               0x2751aaa1
464
465
        enum req_step           req_step;
466
        volatile enum req_body_state_e  req_body_status;
467
        enum sess_close         doclose;
468
        int                     restarts;
469
        int                     esi_level;
470
        struct req              *top;   /* esi_level == 0 request */
471
472
#define REQ_FLAG(l, r, w, d) unsigned   l:1;
473
#include "tbl/req_flags.h"
474
475
        uint16_t                err_code;
476
        const char              *err_reason;
477
478
        struct sess             *sp;
479
        struct worker           *wrk;
480
        struct pool_task        task;
481
482
        const struct transport  *transport;
483
        void                    *transport_priv;
484
485
        VTAILQ_ENTRY(req)       w_list;
486
487
        struct objcore          *body_oc;
488
489
        /* The busy objhead we sleep on */
490
        struct objhead          *hash_objhead;
491
492
        /* Built Vary string */
493
        uint8_t                 *vary_b;
494
        uint8_t                 *vary_l;
495
        uint8_t                 *vary_e;
496
497
        uint8_t                 digest[DIGEST_LEN];
498
499
        double                  d_ttl;
500
501
        ssize_t                 req_bodybytes;  /* Parsed req bodybytes */
502
        const struct stevedore  *storage;
503
504
        const struct director   *director_hint;
505
        struct vcl              *vcl;
506
507
        uintptr_t               ws_req;         /* WS above request data */
508
509
        /* Timestamps */
510
        double                  t_first;        /* First timestamp logged */
511
        double                  t_prev;         /* Previous timestamp logged */
512
        double                  t_req;          /* Headers complete */
513
514
        struct http_conn        htc[1];
515
        struct vfp_ctx          *vfc;
516
        const char              *client_identity;
517
518
        /* HTTP request */
519
        struct http             *http;
520
        struct http             *http0;
521
522
        /* HTTP response */
523
        struct http             *resp;
524
        intmax_t                resp_len;
525
526
        struct ws               ws[1];
527
        struct objcore          *objcore;
528
        struct objcore          *stale_oc;
529
530
        /* Deliver pipeline */
531
        struct vdp_ctx          *vdc;
532
533
        /* Delivery mode */
534
        unsigned                res_mode;
535
#define RES_LEN                 (1<<1)
536
#define RES_EOF                 (1<<2)
537
#define RES_CHUNKED             (1<<3)
538
#define RES_ESI                 (1<<4)
539
#define RES_ESI_CHILD           (1<<5)
540
#define RES_GUNZIP              (1<<6)
541
#define RES_PIPE                (1<<7)
542
543
        /* Transaction VSL buffer */
544
        struct vsl_log          vsl[1];
545
546
        /* Temporary accounting */
547
        struct acct_req         acct;
548
549
        struct vrt_privs        privs[1];
550
};
551
552
/*--------------------------------------------------------------------
553
 * Struct sess is a high memory-load structure because sessions typically
554
 * hang around the waiter for relatively long time.
555
 *
556
 * The size goal for struct sess + struct memitem is <512 bytes
557
 *
558
 * Getting down to the next relevant size (<256 bytes because of how malloc
559
 * works, is not realistic without a lot of code changes.
560
 */
561
562
enum sess_attr {
563
#define SESS_ATTR(UP, low, typ, len)    SA_##UP,
564
        SA_TRANSPORT,
565
#include "tbl/sess_attr.h"
566
        SA_LAST
567
};
568
569
struct sess {
570
        unsigned                magic;
571
#define SESS_MAGIC              0x2c2f9c5a
572
573
        uint16_t                sattr[SA_LAST];
574
        int                     refcnt;
575
        int                     fd;
576
        uint32_t                vxid;
577
578
        struct lock             mtx;
579
580
        struct pool             *pool;
581
582
        struct ws               ws[1];
583
584
        /* Timestamps, all on TIM_real() timescale */
585
        double                  t_open;         /* fd accepted */
586
        double                  t_idle;         /* fd accepted or resp sent */
587
588
};
589
590
/* Prototypes etc ----------------------------------------------------*/
591
592
/* Cross file typedefs */
593
594
typedef enum htc_status_e htc_complete_f(struct http_conn *);
595
596
/* cache_ban.c */
597
598
/* for constructing bans */
599
struct ban_proto *BAN_Build(void);
600
const char *BAN_AddTest(struct ban_proto *,
601
    const char *, const char *, const char *);
602
const char *BAN_Commit(struct ban_proto *b);
603
void BAN_Abandon(struct ban_proto *b);
604
605
/* for stevedoes resurrecting bans */
606
void BAN_Hold(void);
607
void BAN_Release(void);
608
void BAN_Reload(const uint8_t *ban, unsigned len);
609
struct ban *BAN_FindBan(double t0);
610
void BAN_RefBan(struct objcore *oc, struct ban *);
611
double BAN_Time(const struct ban *ban);
612
613
/* cache_busyobj.c */
614
struct busyobj *VBO_GetBusyObj(struct worker *, const struct req *);
615
void VBO_ReleaseBusyObj(struct worker *wrk, struct busyobj **busyobj);
616
617
/* cache_cli.c [CLI] */
618
extern pthread_t cli_thread;
619
#define ASSERT_CLI() do {assert(pthread_self() == cli_thread);} while (0)
620
621
/* cache_expire.c */
622
623
/*
624
 * The set of variables which control object expiry are inconveniently
625
 * 24 bytes long (double+3*float) and this causes alignment waste if
626
 * we put then in a struct.
627
 * These three macros operate on the struct we don't use.
628
 */
629
630
#define EXP_ZERO(xx)                                                    \
631
        do {                                                            \
632
                (xx)->t_origin = 0.0;                                   \
633
                (xx)->ttl = 0.0;                                        \
634
                (xx)->grace = 0.0;                                      \
635
                (xx)->keep = 0.0;                                       \
636
        } while (0)
637
638
#define EXP_COPY(to,fm)                                                 \
639
        do {                                                            \
640
                (to)->t_origin = (fm)->t_origin;                        \
641
                (to)->ttl = (fm)->ttl;                                  \
642
                (to)->grace = (fm)->grace;                              \
643
                (to)->keep = (fm)->keep;                                \
644
        } while (0)
645
646
#define EXP_WHEN(to)                                                    \
647
        ((to)->t_origin + (to)->ttl + (to)->grace + (to)->keep)
648
649
/* cache_exp.c */
650
void EXP_Rearm(struct objcore *, double now, double ttl, double grace,
651
    double keep);
652
653
/* cache_fetch.c */
654
enum vbf_fetch_mode_e {
655
        VBF_NORMAL = 0,
656
        VBF_PASS = 1,
657
        VBF_BACKGROUND = 2,
658
};
659
void VBF_Fetch(struct worker *wrk, struct req *req,
660
    struct objcore *oc, struct objcore *oldoc, enum vbf_fetch_mode_e);
661
662
/* cache_http.c */
663
unsigned HTTP_estimate(unsigned nhttp);
664
void HTTP_Copy(struct http *to, const struct http * const fm);
665
struct http *HTTP_create(void *p, uint16_t nhttp, unsigned);
666
const char *http_Status2Reason(unsigned, const char **);
667
unsigned http_EstimateWS(const struct http *fm, unsigned how);
668
void http_PutResponse(struct http *to, const char *proto, uint16_t status,
669
    const char *response);
670
void http_FilterReq(struct http *to, const struct http *fm, unsigned how);
671
void HTTP_Encode(const struct http *fm, uint8_t *, unsigned len, unsigned how);
672
int HTTP_Decode(struct http *to, const uint8_t *fm);
673
void http_ForceHeader(struct http *to, const char *hdr, const char *val);
674
void http_PrintfHeader(struct http *to, const char *fmt, ...)
675
    v_printflike_(2, 3);
676
void http_TimeHeader(struct http *to, const char *fmt, double now);
677
void http_Proto(struct http *to);
678
void http_SetHeader(struct http *to, const char *hdr);
679
void http_SetH(struct http *to, unsigned n, const char *fm);
680
void http_ForceField(struct http *to, unsigned n, const char *t);
681
void HTTP_Setup(struct http *, struct ws *, struct vsl_log *, enum VSL_tag_e);
682
void http_Teardown(struct http *ht);
683
int http_GetHdr(const struct http *hp, const char *hdr, const char **ptr);
684
int http_GetHdrToken(const struct http *hp, const char *hdr,
685
    const char *token, const char **pb, const char **pe);
686
int http_GetHdrField(const struct http *hp, const char *hdr,
687
    const char *field, const char **ptr);
688
double http_GetHdrQ(const struct http *hp, const char *hdr, const char *field);
689
ssize_t http_GetContentLength(const struct http *hp);
690
uint16_t http_GetStatus(const struct http *hp);
691
int http_IsStatus(const struct http *hp, int);
692
void http_SetStatus(struct http *to, uint16_t status);
693
const char *http_GetMethod(const struct http *hp);
694
int http_HdrIs(const struct http *hp, const char *hdr, const char *val);
695
void http_CopyHome(const struct http *hp);
696
void http_Unset(struct http *hp, const char *hdr);
697
unsigned http_CountHdr(const struct http *hp, const char *hdr);
698
void http_CollectHdr(struct http *hp, const char *hdr);
699
void http_CollectHdrSep(struct http *hp, const char *hdr, const char *sep);
700
void http_VSL_log(const struct http *hp);
701
void HTTP_Merge(struct worker *, struct objcore *, struct http *to);
702
uint16_t HTTP_GetStatusPack(struct worker *, struct objcore *oc);
703
int HTTP_IterHdrPack(struct worker *, struct objcore *, const char **);
704
#define HTTP_FOREACH_PACK(wrk, oc, ptr) \
705
         for ((ptr) = NULL; HTTP_IterHdrPack(wrk, oc, &(ptr));)
706
const char *HTTP_GetHdrPack(struct worker *, struct objcore *, const char *hdr);
707
enum sess_close http_DoConnection(struct http *hp);
708
709
/* cache_http1_proto.c */
710
711
htc_complete_f HTTP1_Complete;
712
uint16_t HTTP1_DissectRequest(struct http_conn *, struct http *);
713
uint16_t HTTP1_DissectResponse(struct http_conn *, struct http *resp,
714
    const struct http *req);
715
unsigned HTTP1_Write(const struct worker *w, const struct http *hp, const int*);
716
717
#define HTTPH_R_PASS    (1 << 0)        /* Request (c->b) in pass mode */
718
#define HTTPH_R_FETCH   (1 << 1)        /* Request (c->b) for fetch */
719
#define HTTPH_A_INS     (1 << 2)        /* Response (b->o) for insert */
720
#define HTTPH_A_PASS    (1 << 3)        /* Response (b->o) for pass */
721
722
#define HTTPH(a, b, c) extern char b[];
723
#include "tbl/http_headers.h"
724
725
extern const char H__Status[];
726
extern const char H__Proto[];
727
extern const char H__Reason[];
728
729
/* cache_main.c */
730
#define VXID(u) ((u) & VSL_IDENTMASK)
731
uint32_t VXID_Get(struct worker *, uint32_t marker);
732
extern volatile struct params * cache_param;
733
extern volatile struct vre_limits *vparam_vre_limits;
734
extern pthread_key_t witness_key;
735
736
/* cache_lck.c */
737
738
/* Internal functions, call only through macros below */
739
void Lck__Lock(struct lock *lck, const char *p,  int l);
740
void Lck__Unlock(struct lock *lck, const char *p,  int l);
741
int Lck__Trylock(struct lock *lck, const char *p,  int l);
742
void Lck__New(struct lock *lck, struct VSC_lck *, const char *);
743
int Lck__Held(const struct lock *lck);
744
int Lck__Owned(const struct lock *lck);
745
746
/* public interface: */
747
void Lck_Delete(struct lock *lck);
748
int Lck_CondWait(pthread_cond_t *cond, struct lock *lck, double);
749
750
#define Lck_New(a, b) Lck__New(a, b, #b)
751
#define Lck_Lock(a) Lck__Lock(a, __func__, __LINE__)
752
#define Lck_Unlock(a) Lck__Unlock(a, __func__, __LINE__)
753
#define Lck_Trylock(a) Lck__Trylock(a, __func__, __LINE__)
754
#define Lck_AssertHeld(a)               \
755
        do {                            \
756
                assert(Lck__Held(a));   \
757
                assert(Lck__Owned(a));  \
758
        } while (0)
759
760
struct VSC_lck *Lck_CreateClass(const char *name);
761
void Lck_DestroyClass(struct VSC_lck **vsclck);
762
763
#define LOCK(nam) extern struct VSC_lck *lck_##nam;
764
#include "tbl/locks.h"
765
766
/* cache_mempool.c */
767
void MPL_AssertSane(const void *item);
768
struct mempool * MPL_New(const char *name, volatile struct poolparam *pp,
769
    volatile unsigned *cur_size);
770
void MPL_Destroy(struct mempool **mpp);
771
void *MPL_Get(struct mempool *mpl, unsigned *size);
772
void MPL_Free(struct mempool *mpl, void *item);
773
774
/* cache_obj.c */
775
struct objcore * ObjNew(const struct worker *);
776
void ObjDestroy(const struct worker *, struct objcore **);
777
typedef int objiterate_f(void *priv, int flush, const void *ptr, ssize_t len);
778
int ObjIterate(struct worker *, struct objcore *,
779
    void *priv, objiterate_f *func, int final);
780
int ObjGetSpace(struct worker *, struct objcore *, ssize_t *sz, uint8_t **ptr);
781
void ObjExtend(struct worker *, struct objcore *, ssize_t l);
782
uint64_t ObjWaitExtend(const struct worker *, const struct objcore *,
783
    uint64_t l);
784
void ObjSetState(struct worker *, const struct objcore *,
785
    enum boc_state_e next);
786
void ObjWaitState(const struct objcore *, enum boc_state_e want);
787
void ObjTrimStore(struct worker *, struct objcore *);
788
void ObjTouch(struct worker *, struct objcore *, double now);
789
unsigned ObjGetXID(struct worker *, struct objcore *);
790
uint64_t ObjGetLen(struct worker *, struct objcore *);
791
void ObjFreeObj(struct worker *, struct objcore *);
792
void ObjSlim(struct worker *, struct objcore *);
793
int ObjHasAttr(struct worker *, struct objcore *, enum obj_attr);
794
const void *ObjGetAttr(struct worker *, struct objcore *, enum obj_attr,
795
    ssize_t *len);
796
void *ObjSetAttr(struct worker *, struct objcore *, enum obj_attr,
797
    ssize_t len, const void *);
798
int ObjCopyAttr(struct worker *, struct objcore *, struct objcore *,
799
    enum obj_attr attr);
800
void ObjBocDone(struct worker *, struct objcore *, struct boc **);
801
802
int ObjSetDouble(struct worker *, struct objcore *, enum obj_attr, double);
803
int ObjSetU32(struct worker *, struct objcore *, enum obj_attr, uint32_t);
804
int ObjSetU64(struct worker *, struct objcore *, enum obj_attr, uint64_t);
805
806
int ObjGetDouble(struct worker *, struct objcore *, enum obj_attr, double *);
807
int ObjGetU32(struct worker *, struct objcore *, enum obj_attr, uint32_t *);
808
int ObjGetU64(struct worker *, struct objcore *, enum obj_attr, uint64_t *);
809
810
int ObjCheckFlag(struct worker *, struct objcore *, enum obj_flags of);
811
void ObjSetFlag(struct worker *, struct objcore *, enum obj_flags of, int val);
812
813
#define OEV_INSERT      (1U<<1)
814
#define OEV_BANCHG      (1U<<2)
815
#define OEV_TTLCHG      (1U<<3)
816
#define OEV_EXPIRE      (1U<<4)
817
818
#define OEV_MASK (OEV_INSERT|OEV_BANCHG|OEV_TTLCHG|OEV_EXPIRE)
819
820
typedef void obj_event_f(struct worker *, void *priv, struct objcore *,
821
    unsigned);
822
823
uintptr_t ObjSubscribeEvents(obj_event_f *, void *, unsigned mask);
824
void ObjUnsubscribeEvents(uintptr_t *);
825
void ObjSendEvent(struct worker *, struct objcore *oc, unsigned event);
826
827
/* cache_panic.c */
828
const char *body_status_2str(enum body_status e);
829
const char *sess_close_2str(enum sess_close sc, int want_desc);
830
831
/* cache_req.c */
832
struct req *Req_New(const struct worker *, struct sess *);
833
void Req_Release(struct req *);
834
void Req_Cleanup(struct sess *sp, struct worker *wrk, struct req *req);
835
void Req_Fail(struct req *req, enum sess_close reason);
836
void Req_AcctLogCharge(struct VSC_main *, struct req *);
837
838
/* cache_req_body.c */
839
int VRB_Ignore(struct req *);
840
ssize_t VRB_Cache(struct req *, ssize_t maxsize);
841
ssize_t VRB_Iterate(struct req *, objiterate_f *func, void *priv);
842
void VRB_Free(struct req *);
843
844
/* cache_session.c [SES] */
845
846
void HTC_RxInit(struct http_conn *htc, struct ws *ws);
847
void HTC_RxPipeline(struct http_conn *htc, void *);
848
enum htc_status_e HTC_RxStuff(struct http_conn *, htc_complete_f *,
849
    double *t1, double *t2, double ti, double tn, int maxbytes);
850
851
#define SESS_ATTR(UP, low, typ, len)                                    \
852
        int SES_Set_##low(const struct sess *sp, const typ *src);       \
853
        int SES_Get_##low(const struct sess *sp, typ **dst);            \
854
        void SES_Reserve_##low(struct sess *sp, typ **dst);
855
#include "tbl/sess_attr.h"
856
857
void SES_Set_String_Attr(struct sess *sp, enum sess_attr a, const char *src);
858
const char *SES_Get_String_Attr(const struct sess *sp, enum sess_attr a);
859
860
/* cache_shmlog.c */
861
void VSLv(enum VSL_tag_e tag, uint32_t vxid, const char *fmt, va_list va);
862
void VSL(enum VSL_tag_e tag, uint32_t vxid, const char *fmt, ...)
863
    v_printflike_(3, 4);
864
void VSLbv(struct vsl_log *, enum VSL_tag_e tag, const char *fmt, va_list va);
865
void VSLb(struct vsl_log *, enum VSL_tag_e tag, const char *fmt, ...)
866
    v_printflike_(3, 4);
867
void VSLbt(struct vsl_log *, enum VSL_tag_e tag, txt t);
868
void VSLb_ts(struct vsl_log *, const char *event, double first, double *pprev,
869
    double now);
870
void VSLb_bin(struct vsl_log *, enum VSL_tag_e, ssize_t, const void*);
871
872
static inline void
873 18042
VSLb_ts_req(struct req *req, const char *event, double now)
874
{
875
876 18042
        if (isnan(req->t_first) || req->t_first == 0.)
877 489
                req->t_first = req->t_prev = now;
878 18042
        VSLb_ts(req->vsl, event, req->t_first, &req->t_prev, now);
879 18042
}
880
881
static inline void
882 10738
VSLb_ts_busyobj(struct busyobj *bo, const char *event, double now)
883
{
884
885 10738
        if (isnan(bo->t_first) || bo->t_first == 0.)
886 2678
                bo->t_first = bo->t_prev = now;
887 10738
        VSLb_ts(bo->vsl, event, bo->t_first, &bo->t_prev, now);
888 10740
}
889
890
891
void VSL_Flush(struct vsl_log *, int overflow);
892
893
/* cache_vcl.c */
894
const char *VCL_Name(const struct vcl *);
895
const char *VCL_Method_Name(unsigned);
896
#define VCL_MET_MAC(l,u,t,b) \
897
    void VCL_##l##_method(struct vcl *, struct worker *, struct req *, \
898
        struct busyobj *bo, void *specific);
899
#include "tbl/vcl_returns.h"
900
901
/* cache_vrt.c */
902
903
/*
904
 * These prototypes go here, because we do not want to pollute vrt.h
905
 * with va_list.  VCC never generates direct calls to them.
906
 */
907
const char *VRT_String(struct ws *ws, const char *h, const char *p, va_list ap);
908
char *VRT_StringList(char *d, unsigned dl, const char *p, va_list ap);
909
910
/* cache_wrk.c */
911
912
typedef void *bgthread_t(struct worker *, void *priv);
913
void WRK_BgThread(pthread_t *thr, const char *name, bgthread_t *func,
914
    void *priv);
915
916
/* cache_ws.c */
917
918
void WS_Init(struct ws *ws, const char *id, void *space, unsigned len);
919
unsigned WS_Reserve(struct ws *ws, unsigned bytes);
920
unsigned WS_ReserveLumps(struct ws *ws, size_t sz);
921
void WS_MarkOverflow(struct ws *ws);
922
void WS_Release(struct ws *ws, unsigned bytes);
923
void WS_ReleaseP(struct ws *ws, char *ptr);
924
void WS_Assert(const struct ws *ws);
925
void WS_Reset(struct ws *ws, uintptr_t);
926
void *WS_Alloc(struct ws *ws, unsigned bytes);
927
void *WS_Copy(struct ws *ws, const void *str, int len);
928
uintptr_t WS_Snapshot(struct ws *ws);
929
int WS_Overflowed(const struct ws *ws);
930
void *WS_Printf(struct ws *ws, const char *fmt, ...) v_printflike_(2, 3);
931
int WS_Inside(const struct ws *, const void *, const void *);
932
void WS_Assert_Allocated(const struct ws *ws, const void *ptr, ssize_t len);
933
934
static inline char*
935
WS_Front(const struct ws *ws)
936
{
937
        return ws->f;
938
}
939
940
/* cache_rfc2616.c */
941
void RFC2616_Ttl(struct busyobj *, double now, double *t_origin,
942
    float *ttl, float *grace, float *keep);
943
unsigned RFC2616_Req_Gzip(const struct http *);
944
int RFC2616_Do_Cond(const struct req *sp);
945
void RFC2616_Weaken_Etag(struct http *hp);
946
void RFC2616_Vary_AE(struct http *hp);
947
void RFC2616_Response_Body(const struct worker *, const struct busyobj *);
948
949
/* stevedore.c */
950
int STV_NewObject(struct worker *, struct objcore *,
951
    const struct stevedore *, unsigned len);
952
953
/*
954
 * A normal pointer difference is signed, but we never want a negative value
955
 * so this little tool will make sure we don't get that.
956
 */
957
958
static inline unsigned
959 106840
pdiff(const void *b, const void *e)
960
{
961
962 106840
        assert(b <= e);
963 106840
        return
964 106840
            ((unsigned)((const unsigned char *)e - (const unsigned char *)b));
965
}
966
967
#define Tcheck(t) do {                                          \
968
                AN((t).b);                                      \
969
                AN((t).e);                                      \
970
                assert((t).b <= (t).e);                         \
971
        } while(0)
972
973
/*
974
 * unsigned length of a txt
975
 */
976
977
static inline unsigned
978 221834
Tlen(const txt t)
979
{
980
981 221834
        Tcheck(t);
982 221834
        return ((unsigned)(t.e - t.b));
983
}
984
985
/*
986
 * We want to cache the most recent timestamp in wrk->lastused to avoid
987
 * extra timestamps in cache_pool.c.  Hide this detail with a macro
988
 */
989
#define W_TIM_real(w) ((w)->lastused = VTIM_real())
990
991
/*
992
 * XXX should cache.h refer to cache_param if common_param.h
993
 * is not in $DIST ?
994
 */
995
#define FEATURE(x)      COM_FEATURE(cache_param->feature_bits, x)
996
#define DO_DEBUG(x)     COM_DO_DEBUG(cache_param->debug_bits, x)
997
998
#define DSL(debug_bit, id, ...)                                 \
999
        do {                                                    \
1000
                if (DO_DEBUG(debug_bit))                        \
1001
                        VSL(SLT_Debug, (id), __VA_ARGS__);      \
1002
        } while (0)
1003
1004
#define PAN_CheckMagic(vsb, ptr, exp)                                   \
1005
        do {                                                            \
1006
                if ((ptr)->magic != (exp))                              \
1007
                        VSB_printf((vsb),                               \
1008
                            "MAGIC 0x%08x (Should:%s/0x%08x)\n",        \
1009
                            (ptr)->magic, #exp, exp);                   \
1010
        } while(0)