Coverage Report

Created: 2023-06-07 06:09

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