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