source: bin/varnishd/cache/cache.h @ 512ddd

Revision 512ddd, 28.8 KB checked in by Poul-Henning Kamp <phk@…>, 2 years ago (diff)

Hindsight is always so glaring sharp...

It was a mistake to put the gunzip delivery buffers on the worker
stack, given that only a minority of clients (mostly spiders and robots)
don't grok "Content-Encoding: gzip".

Move them to malloc space.

  • Property mode set to 100644
Line 
1/*-
2 * Copyright (c) 2006 Verdens Gang AS
3 * Copyright (c) 2006-2011 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/*
32 * This macro can be used in .h files to isolate bits that the manager
33 * should not (need to) see, such as pthread mutexes etc.
34 */
35#define VARNISH_CACHE_CHILD     1
36
37#include "common/common.h"
38
39#include "vapi/vsc_int.h"
40#include "vapi/vsl_int.h"
41
42#include <sys/socket.h>
43
44#include <pthread.h>
45#ifdef HAVE_PTHREAD_NP_H
46#include <pthread_np.h>
47#endif
48#include <stdarg.h>
49#include <string.h>
50#include <limits.h>
51#include <unistd.h>
52
53#if defined(HAVE_EPOLL_CTL)
54#include <sys/epoll.h>
55#endif
56
57
58#include "common/params.h"
59
60enum body_status {
61#define BODYSTATUS(U,l) BS_##U,
62#include "tbl/body_status.h"
63#undef BODYSTATUS
64};
65
66static inline const char *
67body_status(enum body_status e)
68{
69        switch(e) {
70#define BODYSTATUS(U,l) case BS_##U: return (#l);
71#include "tbl/body_status.h"
72#undef BODYSTATUS
73        default:
74                return ("?");
75        }
76}
77
78/*
79 * NB: HDR_STATUS is only used in cache_http.c, everybody else uses the
80 * http->status integer field.
81 */
82
83enum {
84        /* Fields from the first line of HTTP proto */
85        HTTP_HDR_REQ,
86        HTTP_HDR_URL,
87        HTTP_HDR_PROTO,
88        HTTP_HDR_STATUS,
89        HTTP_HDR_RESPONSE,
90        /* HTTP header lines */
91        HTTP_HDR_FIRST,
92};
93
94struct SHA256Context;
95struct VSC_C_lck;
96struct ban;
97struct busyobj;
98struct cli;
99struct cli_proto;
100struct director;
101struct iovec;
102struct mempool;
103struct objcore;
104struct object;
105struct objhead;
106struct pool;
107struct poolparam;
108struct sess;
109struct sesspool;
110struct vbc;
111struct vbo;
112struct vef_priv;
113struct vrt_backend;
114struct vsb;
115struct waitinglist;
116struct worker;
117
118#define DIGEST_LEN              32
119
120/*--------------------------------------------------------------------*/
121
122typedef struct {
123        char                    *b;
124        char                    *e;
125} txt;
126
127/*--------------------------------------------------------------------*/
128
129enum step {
130#define STEP(l, u, arg) STP_##u,
131#include "tbl/steps.h"
132#undef STEP
133};
134
135/*--------------------------------------------------------------------*/
136struct lock { void *priv; };    // Opaque
137
138/*--------------------------------------------------------------------
139 * Workspace structure for quick memory allocation.
140 */
141
142struct ws {
143        unsigned                magic;
144#define WS_MAGIC                0x35fac554
145        unsigned                overflow;       /* workspace overflowed */
146        const char              *id;            /* identity */
147        char                    *s;             /* (S)tart of buffer */
148        char                    *f;             /* (F)ree pointer */
149        char                    *r;             /* (R)eserved length */
150        char                    *e;             /* (E)nd of buffer */
151};
152
153/*--------------------------------------------------------------------
154 * HTTP Request/Response/Header handling structure.
155 */
156
157enum httpwhence {
158        HTTP_Rx  = 1,
159        HTTP_Tx  = 2,
160        HTTP_Obj = 3
161};
162
163/* NB: remember to update http_Copy() if you add fields */
164struct http {
165        unsigned                magic;
166#define HTTP_MAGIC              0x6428b5c9
167
168        enum httpwhence         logtag;
169
170        struct ws               *ws;
171        txt                     *hd;
172        unsigned char           *hdf;
173#define HDF_FILTER              (1 << 0)        /* Filtered by Connection */
174        uint16_t                shd;            /* Size of hd space */
175        uint16_t                nhd;            /* Next free hd */
176        uint16_t                status;
177        uint8_t                 protover;
178        uint8_t                 conds;          /* If-* headers present */
179};
180
181/*--------------------------------------------------------------------
182 * HTTP Protocol connection structure
183 */
184
185struct http_conn {
186        unsigned                magic;
187#define HTTP_CONN_MAGIC         0x3e19edd1
188
189        int                     fd;
190        unsigned                vsl_id;
191        unsigned                maxbytes;
192        unsigned                maxhdr;
193        struct ws               *ws;
194        txt                     rxbuf;
195        txt                     pipeline;
196};
197
198/*--------------------------------------------------------------------*/
199
200struct acct {
201#define ACCT(foo)       uint64_t        foo;
202#include "tbl/acct_fields.h"
203#undef ACCT
204};
205
206/*--------------------------------------------------------------------*/
207
208#define L0(t, n)
209#define L1(t, n)                t n;
210#define VSC_F(n, t, l, f, e,d)  L##l(t, n)
211struct dstat {
212#include "tbl/vsc_f_main.h"
213};
214#undef VSC_F
215#undef L0
216#undef L1
217
218/* Fetch processors --------------------------------------------------*/
219
220typedef void vfp_begin_f(struct worker *, size_t );
221typedef int vfp_bytes_f(struct worker *, struct http_conn *, ssize_t);
222typedef int vfp_end_f(struct worker *);
223
224struct vfp {
225        vfp_begin_f     *begin;
226        vfp_bytes_f     *bytes;
227        vfp_end_f       *end;
228};
229
230extern struct vfp vfp_gunzip;
231extern struct vfp vfp_gzip;
232extern struct vfp vfp_testgzip;
233extern struct vfp vfp_esi;
234
235/*--------------------------------------------------------------------*/
236
237struct exp {
238        double                  ttl;
239        double                  grace;
240        double                  keep;
241        double                  age;
242        double                  entered;
243};
244
245/*--------------------------------------------------------------------*/
246
247struct wrw {
248        int                     *wfd;
249        unsigned                werr;   /* valid after WRW_Flush() */
250        struct iovec            *iov;
251        unsigned                siov;
252        unsigned                niov;
253        ssize_t                 liov;
254        ssize_t                 cliov;
255        unsigned                ciov;   /* Chunked header marker */
256};
257
258/*--------------------------------------------------------------------*/
259
260struct stream_ctx {
261        unsigned                magic;
262#define STREAM_CTX_MAGIC        0x8213728b
263
264        struct vgz              *vgz;
265
266        /* Next byte we will take from storage */
267        ssize_t                 stream_next;
268
269        /* First byte of storage if we free it as we go (pass) */
270        ssize_t                 stream_front;
271};
272
273/*--------------------------------------------------------------------*/
274
275struct wrk_accept {
276        unsigned                magic;
277#define WRK_ACCEPT_MAGIC        0x8c4b4d59
278
279        /* Accept stuff */
280        struct sockaddr_storage acceptaddr;
281        socklen_t               acceptaddrlen;
282        int                     acceptsock;
283        struct listen_sock      *acceptlsock;
284};
285
286/* Worker pool stuff -------------------------------------------------*/
287
288typedef void pool_func_t(struct worker *wrk, void *priv);
289
290struct pool_task {
291        VTAILQ_ENTRY(pool_task)         list;
292        pool_func_t                     *func;
293        void                            *priv;
294};
295
296enum pool_how {
297        POOL_NO_QUEUE,
298        POOL_QUEUE_FRONT,
299        POOL_QUEUE_BACK
300};
301
302/*--------------------------------------------------------------------*/
303
304struct worker {
305        unsigned                magic;
306#define WORKER_MAGIC            0x6391adcf
307        struct pool             *pool;
308        struct objhead          *nobjhead;
309        struct objcore          *nobjcore;
310        struct waitinglist      *nwaitinglist;
311        struct vbo              *nvbo;
312        void                    *nhashpriv;
313        struct dstat            stats;
314
315        struct pool_task        task;
316
317        double                  lastused;
318
319        struct wrw              wrw;
320
321        pthread_cond_t          cond;
322
323        struct sess             *sp;
324
325        struct VCL_conf         *vcl;
326
327        uint32_t                *wlb, *wlp, *wle;
328        unsigned                wlr;
329
330        struct ws               ws[1];
331
332        struct busyobj          *busyobj;
333
334        /* Stream state */
335        struct stream_ctx       *sctx;
336
337        /* Timeouts */
338        double                  connect_timeout;
339        double                  first_byte_timeout;
340        double                  between_bytes_timeout;
341
342        /* Delivery mode */
343        unsigned                res_mode;
344#define RES_LEN                 (1<<1)
345#define RES_EOF                 (1<<2)
346#define RES_CHUNKED             (1<<3)
347#define RES_ESI                 (1<<4)
348#define RES_ESI_CHILD           (1<<5)
349#define RES_GUNZIP              (1<<6)
350
351        /* Temporary accounting */
352        struct acct             acct_tmp;
353};
354
355/* LRU ---------------------------------------------------------------*/
356
357struct lru {
358        unsigned                magic;
359#define LRU_MAGIC               0x3fec7bb0
360        VTAILQ_HEAD(,objcore)   lru_head;
361        struct lock             mtx;
362};
363
364/* Storage -----------------------------------------------------------*/
365
366struct storage {
367        unsigned                magic;
368#define STORAGE_MAGIC           0x1a4e51c0
369
370#ifdef SENDFILE_WORKS
371        int                     fd;
372        off_t                   where;
373#endif
374
375        VTAILQ_ENTRY(storage)   list;
376        struct stevedore        *stevedore;
377        void                    *priv;
378
379        unsigned char           *ptr;
380        unsigned                len;
381        unsigned                space;
382};
383
384/* Object core structure ---------------------------------------------
385 * Objects have sideways references in the binary heap and the LRU list
386 * and we want to avoid paging in a lot of objects just to move them up
387 * or down the binheap or to move a unrelated object on the LRU list.
388 * To avoid this we use a proxy object, objcore, to hold the relevant
389 * housekeeping fields parts of an object.
390 */
391
392typedef struct object *getobj_f(struct worker *wrk, struct objcore *oc);
393typedef unsigned getxid_f(struct worker *wrk, struct objcore *oc);
394typedef void updatemeta_f(struct objcore *oc);
395typedef void freeobj_f(struct objcore *oc);
396typedef struct lru *getlru_f(const struct objcore *oc);
397
398struct objcore_methods {
399        getobj_f        *getobj;
400        getxid_f        *getxid;
401        updatemeta_f    *updatemeta;
402        freeobj_f       *freeobj;
403        getlru_f        *getlru;
404};
405
406struct objcore {
407        unsigned                magic;
408#define OBJCORE_MAGIC           0x4d301302
409        unsigned                refcnt;
410        struct objcore_methods  *methods;
411        void                    *priv;
412        unsigned                priv2;
413        struct objhead          *objhead;
414        struct busyobj          *busyobj;
415        double                  timer_when;
416        unsigned                flags;
417#define OC_F_BUSY               (1<<1)
418#define OC_F_PASS               (1<<2)
419#define OC_F_LRUDONTMOVE        (1<<4)
420#define OC_F_PRIV               (1<<5)          /* Stevedore private flag */
421#define OC_F_LURK               (3<<6)          /* Ban-lurker-color */
422        unsigned                timer_idx;
423        VTAILQ_ENTRY(objcore)   list;
424        VTAILQ_ENTRY(objcore)   lru_list;
425        VTAILQ_ENTRY(objcore)   ban_list;
426        struct ban              *ban;
427};
428
429static inline unsigned
430oc_getxid(struct worker *wrk, struct objcore *oc)
431{
432        CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
433
434        AN(oc->methods);
435        AN(oc->methods->getxid);
436        return (oc->methods->getxid(wrk, oc));
437}
438
439static inline struct object *
440oc_getobj(struct worker *wrk, struct objcore *oc)
441{
442
443        CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
444        AZ(oc->flags & OC_F_BUSY);
445        AN(oc->methods);
446        AN(oc->methods->getobj);
447        return (oc->methods->getobj(wrk, oc));
448}
449
450static inline void
451oc_updatemeta(struct objcore *oc)
452{
453
454        CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
455        AN(oc->methods);
456        if (oc->methods->updatemeta != NULL)
457                oc->methods->updatemeta(oc);
458}
459
460static inline void
461oc_freeobj(struct objcore *oc)
462{
463
464        CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
465        AN(oc->methods);
466        AN(oc->methods->freeobj);
467        oc->methods->freeobj(oc);
468}
469
470static inline struct lru *
471oc_getlru(const struct objcore *oc)
472{
473
474        CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
475        AN(oc->methods);
476        AN(oc->methods->getlru);
477        return (oc->methods->getlru(oc));
478}
479
480/* Busy Object structure ---------------------------------------------
481 *
482 * The busyobj structure captures the aspects of an object related to,
483 * and while it is being fetched from the backend.
484 *
485 * One of these aspects will be how much has been fetched, which
486 * streaming delivery will make use of.
487 *
488 * XXX: many fields from worker needs to move here.
489 */
490
491struct busyobj {
492        unsigned                magic;
493#define BUSYOBJ_MAGIC           0x23b95567
494        struct vbo              *vbo;
495
496        uint8_t                 *vary;
497        unsigned                is_gzip;
498        unsigned                is_gunzip;
499
500        struct vfp              *vfp;
501        struct vep_state        *vep;
502        unsigned                fetch_failed;
503        struct vgz              *vgz_rx;
504
505        struct vbc              *vbc;
506        struct http             *bereq;
507        struct http             *beresp;
508        struct object           *fetch_obj;
509        struct exp              exp;
510        struct http_conn        htc;
511
512        enum body_status        body_status;
513        struct vef_priv         *vef_priv;
514
515        unsigned                should_close;
516        char                    *h_content_length;
517
518        unsigned                do_esi;
519        unsigned                do_gzip;
520        unsigned                do_gunzip;
521        unsigned                do_stream;
522        unsigned                do_pass;
523};
524
525/* Object structure --------------------------------------------------*/
526
527VTAILQ_HEAD(storagehead, storage);
528
529struct object {
530        unsigned                magic;
531#define OBJECT_MAGIC            0x32851d42
532        unsigned                xid;
533        struct storage          *objstore;
534        struct objcore          *objcore;
535
536        struct ws               ws_o[1];
537
538        uint8_t                 *vary;
539        unsigned                hits;
540        uint16_t                response;
541
542        /* XXX: make bitmap */
543        uint8_t                 gziped;
544        /* Bit positions in the gzip stream */
545        ssize_t                 gzip_start;
546        ssize_t                 gzip_last;
547        ssize_t                 gzip_stop;
548
549        ssize_t                 len;
550
551        struct exp              exp;
552
553        double                  last_modified;
554        double                  last_lru;
555
556        struct http             *http;
557
558        struct storagehead      store;
559
560        struct storage          *esidata;
561
562        double                  last_use;
563
564};
565
566/*--------------------------------------------------------------------*/
567
568struct req {
569        unsigned                magic;
570#define REQ_MAGIC               0x2751aaa1
571
572        unsigned                xid;
573        int                     restarts;
574        int                     esi_level;
575        int                     disable_esi;
576        uint8_t                 hash_ignore_busy;
577        uint8_t                 hash_always_miss;
578
579        /* The busy objhead we sleep on */
580        struct objhead          *hash_objhead;
581
582        /* Built Vary string */
583        uint8_t                 *vary_b;
584        uint8_t                 *vary_l;
585        uint8_t                 *vary_e;
586
587        unsigned char           digest[DIGEST_LEN];
588
589        const char              *doclose;
590        struct exp              exp;
591        unsigned                cur_method;
592        unsigned                handling;
593        unsigned char           reqbodydone;
594        unsigned char           wantbody;
595
596        uint16_t                err_code;
597        const char              *err_reason;
598
599        struct director         *director;
600        struct VCL_conf         *vcl;
601
602        uint64_t                req_bodybytes;
603        char                    *ws_req;        /* WS above request data */
604
605        double                  t_resp;
606
607        struct http_conn        htc[1];
608        char                    *client_identity;
609
610        /* HTTP request */
611        struct http             *http;
612        struct http             *http0;
613        struct http             *resp;
614
615        struct ws               ws[1];
616        struct object           *obj;
617        struct objcore          *objcore;
618        /* Lookup stuff */
619        struct SHA256Context    *sha256ctx;
620        /* This is only here so VRT can find it */
621        const char              *storage_hint;
622
623        /* ESI delivery stuff */
624        int                     gzip_resp;
625        ssize_t                 l_crc;
626        uint32_t                crc;
627
628
629};
630
631/*--------------------------------------------------------------------
632 * Struct sess is a high memory-load structure because sessions typically
633 * hang around the waiter for relatively long time.
634 *
635 * The size goal for struct sess + struct memitem is <512 bytes
636 *
637 * Getting down to the next relevant size (<256 bytes because of how malloc
638 * works, is not realistic without a lot of code changes.
639 */
640
641struct sess {
642        unsigned                magic;
643#define SESS_MAGIC              0x2c2f9c5a
644
645        enum step               step;
646        int                     fd;
647        unsigned                vsl_id;
648
649        /* Cross references ------------------------------------------*/
650
651        struct sesspool         *sesspool;
652        struct worker           *wrk;
653        struct req              *req;
654
655        struct pool_task        task;
656        VTAILQ_ENTRY(sess)      list;
657
658        /* Session related fields ------------------------------------*/
659
660        socklen_t               sockaddrlen;
661        socklen_t               mysockaddrlen;
662        struct sockaddr_storage sockaddr;
663        struct sockaddr_storage mysockaddr;
664        struct listen_sock      *mylsock;
665
666        /* formatted ascii client address */
667        char                    addr[ADDR_BUFSIZE];
668        char                    port[PORT_BUFSIZE];
669
670        struct acct             acct_ses;
671
672        /* Timestamps, all on TIM_real() timescale */
673        double                  t_open;         /* fd accepted */
674        double                  t_idle;         /* fd accepted or resp sent */
675        double                  t_req;
676
677#if defined(HAVE_EPOLL_CTL)
678        struct epoll_event ev;
679#endif
680};
681
682/* Prototypes etc ----------------------------------------------------*/
683
684/* cache_acceptor.c */
685void VCA_Init(void);
686void VCA_Shutdown(void);
687int VCA_Accept(struct listen_sock *ls, struct wrk_accept *wa);
688void VCA_SetupSess(struct worker *w);
689void VCA_FailSess(struct worker *w);
690
691/* cache_backend.c */
692void VBE_UseHealth(const struct director *vdi);
693
694struct vbc *VDI_GetFd(const struct director *, struct sess *sp);
695int VDI_Healthy(const struct director *, const struct sess *sp);
696void VDI_CloseFd(struct worker *wrk, struct vbc **vbp);
697void VDI_RecycleFd(struct worker *wrk, struct vbc **vbp);
698void VDI_AddHostHeader(struct worker *wrk, const struct vbc *vbc);
699void VBE_Poll(void);
700void VDI_Init(void);
701
702/* cache_backend_cfg.c */
703void VBE_InitCfg(void);
704struct backend *VBE_AddBackend(struct cli *cli, const struct vrt_backend *vb);
705
706/* cache_backend_poll.c */
707void VBP_Init(void);
708
709/* cache_ban.c */
710struct ban *BAN_New(void);
711int BAN_AddTest(struct cli *, struct ban *, const char *, const char *,
712    const char *);
713void BAN_Free(struct ban *b);
714void BAN_Insert(struct ban *b);
715void BAN_Init(void);
716void BAN_NewObjCore(struct objcore *oc);
717void BAN_DestroyObj(struct objcore *oc);
718int BAN_CheckObject(struct object *o, const struct sess *sp);
719void BAN_Reload(const uint8_t *ban, unsigned len);
720struct ban *BAN_TailRef(void);
721void BAN_Compile(void);
722struct ban *BAN_RefBan(struct objcore *oc, double t0, const struct ban *tail);
723void BAN_TailDeref(struct ban **ban);
724double BAN_Time(const struct ban *ban);
725
726/* cache_busyobj.c */
727void VBO_Init(void);
728struct busyobj *VBO_GetBusyObj(struct worker *wrk);
729void VBO_RefBusyObj(const struct busyobj *busyobj);
730void VBO_DerefBusyObj(struct worker *wrk, struct busyobj **busyobj);
731void VBO_Free(struct vbo **vbo);
732
733/* cache_center.c [CNT] */
734void CNT_Session(struct sess *sp);
735void CNT_Init(void);
736
737/* cache_cli.c [CLI] */
738void CLI_Init(void);
739void CLI_Run(void);
740void CLI_AddFuncs(struct cli_proto *p);
741extern pthread_t cli_thread;
742#define ASSERT_CLI() do {assert(pthread_self() == cli_thread);} while (0)
743
744/* cache_expiry.c */
745void EXP_Clr(struct exp *e);
746double EXP_Get_ttl(const struct exp *e);
747double EXP_Get_grace(const struct exp *e);
748double EXP_Get_keep(const struct exp *e);
749void EXP_Set_ttl(struct exp *e, double v);
750void EXP_Set_grace(struct exp *e, double v);
751void EXP_Set_keep(struct exp *e, double v);
752
753double EXP_Ttl(const struct sess *, const struct object*);
754double EXP_Grace(const struct sess *, const struct object*);
755void EXP_Insert(struct object *o);
756void EXP_Inject(struct objcore *oc, struct lru *lru, double when);
757void EXP_Init(void);
758void EXP_Rearm(const struct object *o);
759int EXP_Touch(struct objcore *oc);
760int EXP_NukeOne(struct worker *w, struct lru *lru);
761
762/* cache_fetch.c */
763struct storage *FetchStorage(struct worker *w, ssize_t sz);
764int FetchError(struct worker *w, const char *error);
765int FetchError2(struct worker *w, const char *error, const char *more);
766int FetchHdr(struct sess *sp, int need_host_hdr, int sendbody);
767int FetchBody(struct worker *w, struct object *obj);
768int FetchReqBody(const struct sess *sp, int sendbody);
769void Fetch_Init(void);
770
771/* cache_gzip.c */
772struct vgz;
773
774enum vgz_flag { VGZ_NORMAL, VGZ_ALIGN, VGZ_RESET, VGZ_FINISH };
775struct vgz *VGZ_NewUngzip(struct worker *wrk, const char *id);
776struct vgz *VGZ_NewGzip(struct worker *wrk, const char *id);
777void VGZ_Ibuf(struct vgz *, const void *, ssize_t len);
778int VGZ_IbufEmpty(const struct vgz *vg);
779void VGZ_Obuf(struct vgz *, void *, ssize_t len);
780int VGZ_ObufFull(const struct vgz *vg);
781int VGZ_ObufStorage(struct worker *w, struct vgz *vg);
782int VGZ_Gzip(struct vgz *, const void **, size_t *len, enum vgz_flag);
783int VGZ_Gunzip(struct vgz *, const void **, size_t *len);
784int VGZ_Destroy(struct vgz **, int vsl_id);
785void VGZ_UpdateObj(const struct vgz*, struct object *);
786
787int VGZ_WrwInit(struct vgz *vg);
788int VGZ_WrwGunzip(struct worker *w, struct vgz *, const void *ibuf,
789    ssize_t ibufl);
790void VGZ_WrwFlush(struct worker *wrk, struct vgz *vg);
791void VGZ_WrwFinish(struct worker *wrk, struct vgz *vg);
792
793/* Return values */
794#define VGZ_ERROR       -1
795#define VGZ_OK          0
796#define VGZ_END         1
797#define VGZ_STUCK       2
798
799/* cache_http.c */
800unsigned HTTP_estimate(unsigned nhttp);
801void HTTP_Copy(struct http *to, const struct http * const fm);
802struct http *HTTP_create(void *p, uint16_t nhttp);
803const char *http_StatusMessage(unsigned);
804unsigned http_EstimateWS(const struct http *fm, unsigned how, uint16_t *nhd);
805void HTTP_Init(void);
806void http_ClrHeader(struct http *to);
807unsigned http_Write(struct worker *w, unsigned vsl_id, const struct http *hp,
808    int resp);
809void http_SetResp(struct http *to, const char *proto, uint16_t status,
810    const char *response);
811void http_FilterReq(const struct sess *sp, unsigned how);
812void http_FilterResp(const struct sess *sp, const struct http *fm, struct http *to,
813    unsigned how);
814void http_PutProtocol(struct worker *w, unsigned vsl_id, const struct http *to,
815    const char *protocol);
816void http_PutStatus(struct http *to, uint16_t status);
817void http_PutResponse(struct worker *w, unsigned vsl_id, const struct http *to,
818    const char *response);
819void http_PrintfHeader(struct worker *w, unsigned vsl_id, struct http *to,
820    const char *fmt, ...)
821    __printflike(4, 5);
822void http_SetHeader(struct worker *w, unsigned vsl_id, struct http *to,
823    const char *hdr);
824void http_SetH(const struct http *to, unsigned n, const char *fm);
825void http_ForceGet(const struct http *to);
826void http_Setup(struct http *ht, struct ws *ws);
827int http_GetHdr(const struct http *hp, const char *hdr, char **ptr);
828int http_GetHdrData(const struct http *hp, const char *hdr,
829    const char *field, char **ptr);
830int http_GetHdrField(const struct http *hp, const char *hdr,
831    const char *field, char **ptr);
832double http_GetHdrQ(const struct http *hp, const char *hdr, const char *field);
833uint16_t http_GetStatus(const struct http *hp);
834const char *http_GetReq(const struct http *hp);
835int http_HdrIs(const struct http *hp, const char *hdr, const char *val);
836uint16_t http_DissectRequest(const struct sess *sp);
837uint16_t http_DissectResponse(struct worker *w, const struct http_conn *htc,
838    struct http *sp);
839const char *http_DoConnection(const struct http *hp);
840void http_CopyHome(struct worker *w, unsigned vsl_id, const struct http *hp);
841void http_Unset(struct http *hp, const char *hdr);
842void http_CollectHdr(struct http *hp, const char *hdr);
843
844/* cache_httpconn.c */
845void HTC_Init(struct http_conn *htc, struct ws *ws, int fd, unsigned vsl_id,
846    unsigned maxbytes, unsigned maxhdr);
847int HTC_Reinit(struct http_conn *htc);
848int HTC_Rx(struct http_conn *htc);
849ssize_t HTC_Read(struct worker *w, struct http_conn *htc, void *d, size_t len);
850int HTC_Complete(struct http_conn *htc);
851
852#define HTTPH(a, b, c) extern char b[];
853#include "tbl/http_headers.h"
854#undef HTTPH
855
856/* cache_main.c */
857extern volatile struct params * cache_param;
858void THR_SetName(const char *name);
859const char* THR_GetName(void);
860void THR_SetSession(const struct sess *sp);
861const struct sess * THR_GetSession(void);
862
863/* cache_lck.c */
864
865/* Internal functions, call only through macros below */
866void Lck__Lock(struct lock *lck, const char *p, const char *f, int l);
867void Lck__Unlock(struct lock *lck, const char *p, const char *f, int l);
868int Lck__Trylock(struct lock *lck, const char *p, const char *f, int l);
869void Lck__New(struct lock *lck, struct VSC_C_lck *, const char *);
870void Lck__Assert(const struct lock *lck, int held);
871
872/* public interface: */
873void LCK_Init(void);
874void Lck_Delete(struct lock *lck);
875int Lck_CondWait(pthread_cond_t *cond, struct lock *lck, struct timespec *ts);
876
877#define Lck_New(a, b) Lck__New(a, b, #b)
878#define Lck_Lock(a) Lck__Lock(a, __func__, __FILE__, __LINE__)
879#define Lck_Unlock(a) Lck__Unlock(a, __func__, __FILE__, __LINE__)
880#define Lck_Trylock(a) Lck__Trylock(a, __func__, __FILE__, __LINE__)
881#define Lck_AssertHeld(a) Lck__Assert(a, 1)
882
883#define LOCK(nam) extern struct VSC_C_lck *lck_##nam;
884#include "tbl/locks.h"
885#undef LOCK
886
887/* cache_mempool.c */
888void MPL_AssertSane(void *item);
889struct mempool * MPL_New(const char *name, volatile struct poolparam *pp,
890    volatile unsigned *cur_size);
891void MPL_Destroy(struct mempool **mpp);
892void *MPL_Get(struct mempool *mpl, unsigned *size);
893void MPL_Free(struct mempool *mpl, void *item);
894
895
896/* cache_panic.c */
897void PAN_Init(void);
898
899/* cache_pipe.c */
900void PipeSession(struct sess *sp);
901
902/* cache_pool.c */
903void Pool_Init(void);
904void Pool_Work_Thread(void *priv, struct worker *w);
905int Pool_Task(struct pool *pp, struct pool_task *task, enum pool_how how);
906
907#define WRW_IsReleased(w)       ((w)->wrw.wfd == NULL)
908int WRW_Error(const struct worker *w);
909void WRW_Chunked(struct worker *w);
910void WRW_EndChunk(struct worker *w);
911void WRW_Reserve(struct worker *w, int *fd);
912unsigned WRW_Flush(struct worker *w);
913unsigned WRW_FlushRelease(struct worker *w);
914unsigned WRW_Write(struct worker *w, const void *ptr, int len);
915unsigned WRW_WriteH(struct worker *w, const txt *hh, const char *suf);
916#ifdef SENDFILE_WORKS
917void WRW_Sendfile(struct worker *w, int fd, off_t off, unsigned len);
918#endif  /* SENDFILE_WORKS */
919
920/* cache_session.c [SES] */
921struct sess *SES_Alloc(void);
922void SES_Close(struct sess *sp, const char *reason);
923void SES_Delete(struct sess *sp, const char *reason, double now);
924void SES_Charge(struct sess *sp);
925struct sesspool *SES_NewPool(struct pool *pp, unsigned pool_no);
926void SES_DeletePool(struct sesspool *sp);
927int SES_Schedule(struct sess *sp);
928void SES_Handle(struct sess *sp, double now);
929void SES_GetReq(struct sess *sp);
930void SES_ReleaseReq(struct sess *sp);
931pool_func_t SES_pool_accept_task;
932
933/* cache_shmlog.c */
934extern struct VSC_C_main *VSC_C_main;
935void VSM_Init(void);
936void *VSM_Alloc(unsigned size, const char *class, const char *type,
937    const char *ident);
938void VSM_Free(void *ptr);
939#ifdef VSL_ENDMARKER
940void VSL(enum VSL_tag_e tag, int id, const char *fmt, ...)
941    __printflike(3, 4);
942void WSLR(struct worker *w, enum VSL_tag_e tag, int id, txt t);
943void WSL(struct worker *w, enum VSL_tag_e tag, int id, const char *fmt, ...)
944    __printflike(4, 5);
945void WSLB(struct worker *w, enum VSL_tag_e tag, const char *fmt, ...)
946    __printflike(3, 4);
947
948void WSL_Flush(struct worker *w, int overflow);
949
950#define DSL(flag, tag, id, ...)                                 \
951        do {                                                    \
952                if (cache_param->diag_bitmap & (flag))          \
953                        VSL((tag), (id), __VA_ARGS__);          \
954        } while (0)
955
956#define WSP(sess, tag, ...)                                     \
957        WSL((sess)->wrk, tag, (sess)->vsl_id, __VA_ARGS__)
958
959#define WSPR(sess, tag, txt)                                    \
960        WSLR((sess)->wrk, tag, (sess)->vsl_id, txt)
961
962#define INCOMPL() do {                                                  \
963        VSL(SLT_Debug, 0, "INCOMPLETE AT: %s(%d)", __func__, __LINE__); \
964        fprintf(stderr,                                                 \
965            "INCOMPLETE AT: %s(%d)\n",                                  \
966            (const char *)__func__, __LINE__);                          \
967        abort();                                                        \
968        } while (0)
969#endif
970
971/* cache_response.c */
972void RES_BuildHttp(const struct sess *sp);
973void RES_WriteObj(struct sess *sp);
974void RES_StreamStart(struct sess *sp);
975void RES_StreamEnd(struct sess *sp);
976void RES_StreamPoll(struct worker *);
977
978/* cache_vary.c */
979struct vsb *VRY_Create(const struct sess *sp, const struct http *hp);
980int VRY_Match(const struct sess *sp, const uint8_t *vary);
981void VRY_Validate(const uint8_t *vary);
982
983/* cache_vcl.c */
984void VCL_Init(void);
985void VCL_Refresh(struct VCL_conf **vcc);
986void VCL_Rel(struct VCL_conf **vcc);
987void VCL_Poll(void);
988const char *VCL_Return_Name(unsigned method);
989
990#define VCL_MET_MAC(l,u,b) void VCL_##l##_method(struct sess *);
991#include "tbl/vcl_returns.h"
992#undef VCL_MET_MAC
993
994/* cache_vrt.c */
995
996char *VRT_String(struct ws *ws, const char *h, const char *p, va_list ap);
997char *VRT_StringList(char *d, unsigned dl, const char *p, va_list ap);
998
999void ESI_Deliver(struct sess *);
1000void ESI_DeliverChild(const struct sess *);
1001
1002/* cache_vrt_vmod.c */
1003void VMOD_Init(void);
1004
1005/* cache_waiter.c */
1006void WAIT_Enter(struct sess *sp);
1007void WAIT_Init(void);
1008const char *WAIT_GetName(void);
1009
1010/* cache_wrk.c */
1011
1012void WRK_Init(void);
1013int WRK_TrySumStat(struct worker *w);
1014void WRK_SumStat(struct worker *w);
1015void *WRK_thread(void *priv);
1016typedef void *bgthread_t(struct sess *, void *priv);
1017void WRK_BgThread(pthread_t *thr, const char *name, bgthread_t *func,
1018    void *priv);
1019
1020/* cache_ws.c */
1021
1022void WS_Init(struct ws *ws, const char *id, void *space, unsigned len);
1023unsigned WS_Reserve(struct ws *ws, unsigned bytes);
1024void WS_Release(struct ws *ws, unsigned bytes);
1025void WS_ReleaseP(struct ws *ws, char *ptr);
1026void WS_Assert(const struct ws *ws);
1027void WS_Reset(struct ws *ws, char *p);
1028char *WS_Alloc(struct ws *ws, unsigned bytes);
1029char *WS_Snapshot(struct ws *ws);
1030unsigned WS_Free(const struct ws *ws);
1031
1032/* rfc2616.c */
1033void RFC2616_Ttl(const struct sess *sp);
1034enum body_status RFC2616_Body(const struct sess *sp);
1035unsigned RFC2616_Req_Gzip(const struct sess *sp);
1036int RFC2616_Do_Cond(const struct sess *sp);
1037
1038/* stevedore.c */
1039struct object *STV_NewObject(struct worker *wrk, const char *hint, unsigned len,
1040    uint16_t nhttp);
1041struct storage *STV_alloc(struct worker *w, size_t size);
1042void STV_trim(struct storage *st, size_t size);
1043void STV_free(struct storage *st);
1044void STV_open(void);
1045void STV_close(void);
1046void STV_Freestore(struct object *o);
1047
1048/* storage_synth.c */
1049struct vsb *SMS_Makesynth(struct object *obj);
1050void SMS_Finish(struct object *obj);
1051void SMS_Init(void);
1052
1053/* storage_persistent.c */
1054void SMP_Init(void);
1055void SMP_Ready(void);
1056void SMP_NewBan(const uint8_t *ban, unsigned len);
1057
1058/*
1059 * A normal pointer difference is signed, but we never want a negative value
1060 * so this little tool will make sure we don't get that.
1061 */
1062
1063static inline unsigned
1064pdiff(const void *b, const void *e)
1065{
1066
1067        assert(b <= e);
1068        return
1069            ((unsigned)((const unsigned char *)e - (const unsigned char *)b));
1070}
1071
1072static inline void
1073Tcheck(const txt t)
1074{
1075
1076        AN(t.b);
1077        AN(t.e);
1078        assert(t.b <= t.e);
1079}
1080
1081/*
1082 * unsigned length of a txt
1083 */
1084
1085static inline unsigned
1086Tlen(const txt t)
1087{
1088
1089        Tcheck(t);
1090        return ((unsigned)(t.e - t.b));
1091}
1092
1093static inline void
1094Tadd(txt *t, const char *p, int l)
1095{
1096        Tcheck(*t);
1097
1098        if (l <= 0) {
1099        } if (t->b + l < t->e) {
1100                memcpy(t->b, p, l);
1101                t->b += l;
1102        } else {
1103                t->b = t->e;
1104        }
1105}
1106
1107static inline void
1108AssertObjBusy(const struct object *o)
1109{
1110        AN(o->objcore);
1111        AN (o->objcore->flags & OC_F_BUSY);
1112        AN(o->objcore->busyobj);
1113}
1114
1115static inline void
1116AssertObjCorePassOrBusy(const struct objcore *oc)
1117{
1118        if (oc != NULL)
1119                AN (oc->flags & OC_F_BUSY);
1120}
1121
1122/*
1123 * We want to cache the most recent timestamp in wrk->lastused to avoid
1124 * extra timestamps in cache_pool.c.  Hide this detail with a macro
1125 */
1126#define W_TIM_real(w) ((w)->lastused = VTIM_real())
Note: See TracBrowser for help on using the repository browser.