1 /*-
2  * Copyright (c) 2006 Verdens Gang AS
3  * Copyright (c) 2006-2021 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  * Runtime support for compiled VCL programs and VMODs.
32  *
33  * NB: When this file is changed, lib/libvcc/generate.py *MUST* be rerun.
34  */
35 
36 #ifdef CACHE_H_INCLUDED
37 #  error "vrt.h included after cache.h - they are inclusive"
38 #endif
39 
40 #ifdef VRT_H_INCLUDED
41 #  error "vrt.h included multiple times"
42 #endif
43 #define VRT_H_INCLUDED
44 
45 #ifndef VDEF_H_INCLUDED
46 #  error "include vdef.h before vrt.h"
47 #endif
48 
49 /***********************************************************************
50  * Major and minor VRT API versions.
51  *
52  * Whenever something is added, increment MINOR version
53  * Whenever something is deleted or changed in a way which is not
54  * binary/load-time compatible, increment MAJOR version
55  *
56  * 13.0 (2021-03-15)
57  *	Move VRT_synth_page() to deprecated status
58  *	Add VRT_synth_strands() and VRT_synth_blob()
59  *	struct vrt_type now produced by generate.py
60  *	VRT_acl_log() moved to VPI_acl_log()
61  *	VRT_Endpoint_Clone() added.
62  *	Calling convention for VDP implementation changed
63  *	VRT_ValidHdr() added.
64  *	struct vmod_priv_methods added
65  *	struct vmod_priv free member replaced with methods
66  *	VRT_CTX_Assert() added
67  *	VRT_ban_string() signature changed
68  *	VRT_priv_task_get() added
69  *	VRT_priv_top_get() added
70  *	VRT_re_init removed
71  *	VRT_re_fini removed
72  *	VRT_re_match signature changed
73  *	VRT_regsub signature changed
74  *	VRT_call() added
75  *	VRT_check_call() added
76  *	VRT_handled() added
77  * 12.0 (2020-09-15)
78  *	Added VRT_DirectorResolve()
79  *	Added VCL_STRING VRT_BLOB_string(VRT_CTX, VCL_BLOB)
80  *	[cache.h] WS_Reserve() removed
81  *	[cache.h] WS_Printf() changed
82  *	[cache.h] WS_ReservationSize() added
83  *	[cache.h] WS_Front() deprecated
84  *	[cache.h] WS_Reservation() added
85  * 11.0 (2020-03-16)
86  *	Changed type of vsa_suckaddr_len from int to size_t
87  *	New prefix_{ptr|len} fields in vrt_backend
88  *	VRT_HashStrands32() added
89  *	VRT_l_resp_body() changed
90  *	VRT_l_beresp_body() changed
91  *	VRT_Format_Proxy() added	// transitional interface
92  *	VRT_AllocStrandsWS() added
93  * 10.0 (2019-09-15)
94  *	VRT_UpperLowerStrands added.
95  *	VRT_synth_page now takes STRANDS argument
96  *	VRT_hashdata() now takes STRANDS argument
97  *	VCL_BOOL VRT_Strands2Bool(VCL_STRANDS) added.
98  *	VRT_BundleStrands() moved to vcc_interface.h
99  *	VRT_VCL_{Busy|Unbusy} changed to VRT_VCL_{Prevent|Allow}_Cold
100  *	VRT_re[fl]_vcl changed to VRT_VCL_{Prevent|Allow}_Discard
101  *	VRT_Vmod_{Init|Unload} moved to vcc_interface.h
102  *	VRT_count moved to vcc_interface.h
103  *	VRT_VCL_Prevent_Cold() and VRT_VCL_Allow_Cold() added.
104  *	VRT_vcl_get moved to vcc_interface.h
105  *	VRT_vcl_rel moved to vcc_interface.h
106  *	VRT_vcl_select moved to vcc_interface.h
107  *	VRT_VSA_GetPtr() changed
108  *	VRT_ipcmp() changed
109  *	VRT_Stv_*() functions renamed to VRT_stevedore_*()
110  *	[cache.h] WS_ReserveAll() added
111  *	[cache.h] WS_Reserve(ws, 0) deprecated
112  * 9.0 (2019-03-15)
113  *	Make 'len' in vmod_priv 'long'
114  *	HTTP_Copy() removed
115  *	HTTP_Dup() added
116  *	HTTP_Clone() added
117  *	VCL_BLOB changed to newly introduced struct vrt_blob *
118  *	VRT_blob() changed
119  *	req->req_bodybytes removed
120  *	    use: AZ(ObjGetU64(req->wrk, req->body_oc, OA_LEN, &u));
121  *	struct vdi_methods .list callback signature changed
122  *	VRT_LookupDirector() added
123  *	VRT_SetChanged() added
124  *	VRT_SetHealth() removed
125  *	// in cache_filter.h:
126  *	VRT_AddVDP() added
127  *	VRT_RemoveVDP() added
128  * 8.0 (2018-09-15)
129  *	VRT_Strands() added
130  *	VRT_StrandsWS() added
131  *	VRT_CollectStrands() added
132  *	VRT_STRANDS_string() removed from vrt.h (never implemented)
133  *	VRT_Vmod_Init signature changed
134  *	VRT_Vmod_Fini changed to VRT_Vmod_Unload
135  *	// directors
136  *	VRT_backend_healthy() removed
137  *	VRT_Healthy() changed prototype
138  *	struct vdi_methods and callback prototypes added
139  *	struct director added;
140  *	VRT_AddDirector() added
141  *	VRT_SetHealth() added
142  *	VRT_DisableDirector() added
143  *	VRT_DelDirector() added
144  *	// in cache_filter.h:
145  *	VRT_AddVFP() added
146  *	VRT_RemoveVFP() added
147  * 7.0 (2018-03-15)
148  *	lots of stuff moved from cache.h to cache_varnishd.h
149  *	   (ie: from "$Abi vrt" to "$Abi strict")
150  *	VCL_INT and VCL_BYTES are always 64 bits.
151  *	path field added to struct vrt_backend
152  *	VRT_Healthy() added
153  *	VRT_VSC_Alloc() added
154  *	VRT_VSC_Destroy() added
155  *	VRT_VSC_Hide() added
156  *	VRT_VSC_Reveal() added
157  *	VRT_VSC_Overhead() added
158  *	struct director.event added
159  *	struct director.destroy added
160  *	VRT_r_beresp_storage_hint() VCL <= 4.0  #2509
161  *	VRT_l_beresp_storage_hint() VCL <= 4.0  #2509
162  *	VRT_blob() added
163  *	VCL_STRANDS added
164  * 6.1 (2017-09-15 aka 5.2)
165  *	http_CollectHdrSep added
166  *	VRT_purge modified (may fail a transaction, signature changed)
167  *	VRT_r_req_hash() added
168  *	VRT_r_bereq_hash() added
169  * 6.0 (2017-03-15):
170  *	VRT_hit_for_pass added
171  *	VRT_ipcmp added
172  *	VRT_Vmod_Init signature changed
173  *	VRT_vcl_lookup removed
174  *	VRT_fail added
175  *	[cache.h] WS_Reset and WS_Snapshot signatures changed
176  *	[cache.h] WS_Front added
177  *	[cache.h] WS_ReserveLumps added
178  *	[cache.h] WS_Inside added
179  *	[cache.h] WS_Assert_Allocated added
180  * 5.0:
181  *	Varnish 5.0 release "better safe than sorry" bump
182  * 4.0:
183  *	VCL_BYTES changed to long long
184  *	VRT_CacheReqBody changed signature
185  * 3.2:
186  *	vrt_backend grew .proxy_header field
187  *	vrt_ctx grew .sp field.
188  *	vrt_acl type added
189  */
190 
191 #define VRT_MAJOR_VERSION	13U
192 
193 #define VRT_MINOR_VERSION	0U
194 
195 /***********************************************************************/
196 
197 #include <stddef.h>		// NULL, size_t
198 #include <stdint.h>		// [u]int%d_t
199 
200 struct busyobj;
201 struct director;
202 struct http;
203 struct req;
204 struct stevedore;
205 struct suckaddr;
206 struct vcl;
207 struct vcldir;
208 struct VCL_conf;
209 struct vmod;
210 struct vmod_priv;
211 struct vrt_acl;
212 struct vsb;
213 struct VSC_main;
214 struct vsc_seg;
215 struct vsl_log;
216 struct vsmw_cluster;
217 struct ws;
218 struct vcl_sub;
219 
220 /***********************************************************************
221  * VCL_STRANDS:
222  *
223  * An argc+argv type of data structure where n indicates the number of
224  * strings in the p array. Individual components of a strands may be null.
225  *
226  * A STRANDS allows you to work on a strings concatenation with the
227  * option to collect it into a single STRING, or if possible work
228  * directly on individual parts.
229  *
230  * The memory management is very strict: a VMOD function receiving a
231  * STRANDS argument should keep no reference after the function returns.
232  * Retention of a STRANDS further in the ongoing task is undefined
233  * behavior and may result in a panic or data corruption.
234  */
235 
236 struct strands {
237 	int		n;
238 	const char	**p;
239 };
240 
241 /***********************************************************************
242  * VCL_BLOB:
243  *
244  * Opaque, immutable data (pointer + length), minimum lifetime is the
245  * VCL task.
246  *
247  * Type (optional) is owned by the creator of the blob. blob consumers
248  * may use it for checks, but should not assert on it.
249  *
250  * The data behind the blob pointer is assumed to be immutable for the
251  * blob's lifetime.
252  *
253  * - memory for shortlived blobs can be put on the tasks workspace
254  *
255  * - management of memory for longer lived blobs is up to the vmod
256  *   (in which case the blob will probably be embedded in an object or
257  *    referenced by other state with vcl lifetime)
258  */
259 
260 struct vrt_blob {
261 	unsigned	type;
262 	size_t		len;
263 	const void	*blob;
264 };
265 
266 /***********************************************************************
267  * This is the central definition of the mapping from VCL types to
268  * C-types.  The python scripts read these from here.
269  * (keep alphabetic order)
270  */
271 
272 typedef const struct vrt_acl *			VCL_ACL;
273 typedef const struct director *			VCL_BACKEND;
274 typedef const struct vrt_blob *			VCL_BLOB;
275 typedef const char *				VCL_BODY;
276 typedef unsigned				VCL_BOOL;
277 typedef int64_t					VCL_BYTES;
278 typedef vtim_dur				VCL_DURATION;
279 typedef const char *				VCL_ENUM;
280 typedef const struct gethdr_s *			VCL_HEADER;
281 typedef struct http *				VCL_HTTP;
282 typedef void					VCL_INSTANCE;
283 typedef int64_t					VCL_INT;
284 typedef const struct suckaddr *			VCL_IP;
285 typedef const struct vrt_backend_probe *	VCL_PROBE;
286 typedef double					VCL_REAL;
287 typedef const struct vre *			VCL_REGEX;
288 typedef const struct stevedore *		VCL_STEVEDORE;
289 typedef const struct strands *			VCL_STRANDS;
290 typedef const char *				VCL_STRING;
291 typedef const struct vcl_sub *			VCL_SUB;
292 typedef vtim_real				VCL_TIME;
293 typedef struct vcl *				VCL_VCL;
294 typedef void					VCL_VOID;
295 
296 /***********************************************************************
297  * This is the composite "context" argument for compiled VCL, VRT and
298  * VMOD functions.
299  */
300 
301 struct vrt_ctx {
302 	unsigned			magic;
303 #define VRT_CTX_MAGIC			0x6bb8f0db
304 
305 	unsigned			syntax;
306 	unsigned			vclver;
307 	unsigned			method;
308 	unsigned			*handling;
309 
310 	/*
311 	 * msg is for error messages and exists only for
312 	 * VCL_EVENT_LOAD
313 	 * VCL_EVENT_WARM
314 	 */
315 	struct vsb			*msg;
316 	struct vsl_log			*vsl;
317 	VCL_VCL				vcl;
318 	struct ws			*ws;
319 
320 	struct sess			*sp;
321 
322 	struct req			*req;
323 	VCL_HTTP			http_req;
324 	VCL_HTTP			http_req_top;
325 	VCL_HTTP			http_resp;
326 
327 	struct busyobj			*bo;
328 	VCL_HTTP			http_bereq;
329 	VCL_HTTP			http_beresp;
330 
331 	vtim_real			now;
332 
333 	/*
334 	 * method specific argument:
335 	 *    hash:		struct VSHA256Context
336 	 *    synth+error:	struct vsb *
337 	 */
338 	void				*specific;
339 	/* if present, vbitmap of called subs */
340 	void				*called;
341 };
342 
343 #define VRT_CTX		const struct vrt_ctx *ctx
344 void VRT_CTX_Assert(VRT_CTX);
345 
346 enum vcl_func_call_e {
347 	VSUB_STATIC,	// VCL "call" action, only allowed from VCC
348 	VSUB_DYNAMIC,	// VRT_call()
349 	VSUB_CHECK	// VRT_check_call()
350 };
351 
352 enum vcl_func_fail_e {
353 	VSUB_E_OK,
354 	VSUB_E_RECURSE, // call would recurse
355 	VSUB_E_METHOD	// can not be called from this method
356 };
357 
358 typedef void vcl_func_f(VRT_CTX, enum vcl_func_call_e, enum vcl_func_fail_e *);
359 
360 /***********************************************************************
361  * This is the interface structure to a compiled VMOD
362  * (produced by vmodtool.py)
363  */
364 
365 struct vmod_data {
366 	/* The version/id fields must be first, they protect the rest */
367 	unsigned			vrt_major;
368 	unsigned			vrt_minor;
369 	const char			*file_id;
370 
371 	const char			*name;
372 	const char			*func_name;
373 	const void			*func;
374 	int				func_len;
375 	const char			*proto;
376 	const char			*json;
377 	const char			*abi;
378 };
379 
380 /***********************************************************************
381  * VCL events sent to VMODs
382  */
383 
384 enum vcl_event_e {
385 	VCL_EVENT_LOAD,
386 	VCL_EVENT_WARM,
387 	VCL_EVENT_COLD,
388 	VCL_EVENT_DISCARD,
389 };
390 
391 typedef int vmod_event_f(VRT_CTX, struct vmod_priv *, enum vcl_event_e);
392 
393 /***********************************************************************
394  * Utility functions operating on VCL_types
395  * (alphabetic by type-ish)
396  */
397 
398 /* VCL_ACL */
399 int VRT_acl_match(VRT_CTX, VCL_ACL, VCL_IP);
400 
401 /* VCL_BACKEND */
402 VCL_BACKEND VRT_DirectorResolve(VRT_CTX, VCL_BACKEND);
403 
404 /* VCL_BLOB */
405 VCL_BLOB VRT_blob(VRT_CTX, const char *, const void *, size_t, unsigned);
406 
407 /* VCL_IP */
408 int VRT_VSA_GetPtr(VRT_CTX, VCL_IP sua, const unsigned char ** dst);
409 VCL_BOOL VRT_ipcmp(VRT_CTX, VCL_IP, VCL_IP);
410 void VRT_Format_Proxy(struct vsb *, VCL_INT, VCL_IP, VCL_IP, VCL_STRING);
411 
412 /* VCL_REGEX */
413 VCL_BOOL VRT_re_match(VRT_CTX, VCL_STRING, VCL_REGEX);
414 VCL_STRING VRT_regsub(VRT_CTX, int all, VCL_STRING, VCL_REGEX, VCL_STRING);
415 
416 /* VCL_STEVEDORE */
417 VCL_STEVEDORE VRT_stevedore(const char *nm);
418 
419 /* VCL_STRANDS */
420 struct strands * VRT_AllocStrandsWS(struct ws *, int);
421 int VRT_CompareStrands(VCL_STRANDS a, VCL_STRANDS b);
422 VCL_BOOL VRT_Strands2Bool(VCL_STRANDS);
423 uint32_t VRT_HashStrands32(VCL_STRANDS);
424 char *VRT_Strands(char *, size_t, VCL_STRANDS);
425 VCL_STRING VRT_StrandsWS(struct ws *, const char *, VCL_STRANDS);
426 VCL_STRING VRT_CollectStrands(VRT_CTX, VCL_STRANDS);
427 VCL_STRING VRT_UpperLowerStrands(VRT_CTX, VCL_STRANDS s, int up);
428 
429 /* VCL_SUB */
430 VCL_STRING VRT_check_call(VRT_CTX, VCL_SUB);
431 VCL_VOID VRT_call(VRT_CTX, VCL_SUB);
432 
433 /* Functions to turn types into canonical strings */
434 
435 VCL_STRING VRT_BACKEND_string(VCL_BACKEND);
436 VCL_STRING VRT_BOOL_string(VCL_BOOL);
437 VCL_STRING VRT_BLOB_string(VRT_CTX, VCL_BLOB);
438 VCL_STRING VRT_CollectString(VRT_CTX, const char *p, ...);
439 VCL_STRING VRT_INT_string(VRT_CTX, VCL_INT);
440 VCL_STRING VRT_IP_string(VRT_CTX, VCL_IP);
441 VCL_STRING VRT_REAL_string(VRT_CTX, VCL_REAL);
442 VCL_STRING VRT_STEVEDORE_string(VCL_STEVEDORE);
443 VCL_STRING VRT_TIME_string(VRT_CTX, VCL_TIME);
444 
445 /* historical */
446 int VRT_strcmp(const char *s1, const char *s2);
447 void VRT_memmove(void *dst, const void *src, unsigned len);
448 
449 /***********************************************************************
450  * We want the VCC to spit this structs out as const, but when VMODs
451  * come up with them we want to clone them into malloc'ed space which
452  * we can free again.
453  * We collect all the knowledge here by macroizing the fields and make
454  * a macro for handling them all.
455  * See also:  cache_backend.h & cache_backend_cfg.c
456  * One of those things...
457  */
458 
459 struct vrt_endpoint {
460 	unsigned			magic;
461 #define VRT_ENDPOINT_MAGIC		0xcc419347
462 	VCL_IP				ipv4;
463 	VCL_IP				ipv6;
464 	const char			*uds_path;
465 	const struct vrt_blob		*preamble;
466 };
467 
468 #define VRT_BACKEND_FIELDS(rigid)				\
469 	rigid char			*vcl_name;		\
470 	rigid char			*hosthdr;		\
471 	vtim_dur			connect_timeout;	\
472 	vtim_dur			first_byte_timeout;	\
473 	vtim_dur			between_bytes_timeout;	\
474 	unsigned			max_connections;	\
475 	unsigned			proxy_header;
476 
477 #define VRT_BACKEND_HANDLE()			\
478 	do {					\
479 		DA(vcl_name);			\
480 		DA(hosthdr);			\
481 		DN(connect_timeout);		\
482 		DN(first_byte_timeout);		\
483 		DN(between_bytes_timeout);	\
484 		DN(max_connections);		\
485 		DN(proxy_header);		\
486 	} while(0)
487 
488 struct vrt_backend {
489 	unsigned			magic;
490 #define VRT_BACKEND_MAGIC		0x4799ce6c
491 	const struct vrt_endpoint	*endpoint;
492 	VRT_BACKEND_FIELDS(const)
493 	VCL_PROBE			probe;
494 };
495 
496 #define VRT_BACKEND_PROBE_FIELDS(rigid)				\
497 	vtim_dur			timeout;		\
498 	vtim_dur			interval;		\
499 	unsigned			exp_status;		\
500 	unsigned			window;			\
501 	unsigned			threshold;		\
502 	unsigned			initial;
503 
504 #define VRT_BACKEND_PROBE_HANDLE()		\
505 	do {					\
506 		DN(timeout);			\
507 		DN(interval);			\
508 		DN(exp_status);			\
509 		DN(window);			\
510 		DN(threshold);			\
511 		DN(initial);			\
512 	} while (0)
513 
514 struct vrt_backend_probe {
515 	unsigned			magic;
516 #define VRT_BACKEND_PROBE_MAGIC		0x84998490
517 	const char			*url;
518 	const char			*request;
519 	VRT_BACKEND_PROBE_FIELDS(const)
520 };
521 
522 /* Backend related */
523 VCL_BACKEND VRT_new_backend(VRT_CTX, const struct vrt_backend *);
524 VCL_BACKEND VRT_new_backend_clustered(VRT_CTX,
525     struct vsmw_cluster *, const struct vrt_backend *);
526 size_t VRT_backend_vsm_need(VRT_CTX);
527 void VRT_delete_backend(VRT_CTX, VCL_BACKEND *);
528 struct vrt_endpoint *VRT_Endpoint_Clone(const struct vrt_endpoint *vep);
529 
530 
531 /***********************************************************************
532  * Getting hold of the various struct http
533  */
534 
535 enum gethdr_e {
536 	HDR_REQ,
537 	HDR_REQ_TOP,
538 	HDR_RESP,
539 	HDR_OBJ,
540 	HDR_BEREQ,
541 	HDR_BERESP
542 };
543 
544 struct gethdr_s {
545 	enum gethdr_e	where;
546 	const char	*what;
547 };
548 
549 VCL_HTTP VRT_selecthttp(VRT_CTX, enum gethdr_e);
550 VCL_STRING VRT_GetHdr(VRT_CTX, VCL_HEADER);
551 
552 /***********************************************************************
553  * req related
554  */
555 
556 enum lbody_e {
557 	LBODY_SET,
558 	LBODY_ADD,
559 };
560 
561 VCL_BYTES VRT_CacheReqBody(VRT_CTX, VCL_BYTES maxsize);
562 
563 VCL_STRING VRT_ban_string(VRT_CTX, VCL_STRING);
564 VCL_INT VRT_purge(VRT_CTX, VCL_DURATION, VCL_DURATION, VCL_DURATION);
565 VCL_VOID VRT_synth(VRT_CTX, VCL_INT, VCL_STRING);
566 VCL_VOID VRT_hit_for_pass(VRT_CTX, VCL_DURATION);
567 
568 VCL_BOOL VRT_ValidHdr(VRT_CTX, VCL_STRANDS);
569 VCL_VOID VRT_SetHdr(VRT_CTX, VCL_HEADER, const char *, ...);
570 VCL_VOID VRT_handling(VRT_CTX, unsigned hand);
571 unsigned VRT_handled(VRT_CTX);
572 VCL_VOID VRT_fail(VRT_CTX, const char *fmt, ...) v_printflike_(2,3);
573 VCL_VOID VRT_hashdata(VRT_CTX, VCL_STRANDS);
574 
575 VCL_VOID VRT_Rollback(VRT_CTX, VCL_HTTP);
576 
577 /* Synthetic pages */
578 VCL_VOID VRT_synth_strands(VRT_CTX, VCL_STRANDS);
579 VCL_VOID VRT_synth_blob(VRT_CTX, VCL_BLOB);
580 
581 /***********************************************************************
582  * VDI - Director API
583  */
584 typedef VCL_BOOL vdi_healthy_f(VRT_CTX, VCL_BACKEND, VCL_TIME *);
585 typedef VCL_BACKEND vdi_resolve_f(VRT_CTX, VCL_BACKEND);
586 typedef int vdi_gethdrs_f(VRT_CTX, VCL_BACKEND);
587 typedef VCL_IP vdi_getip_f(VRT_CTX, VCL_BACKEND);
588 typedef void vdi_finish_f(VRT_CTX, VCL_BACKEND);
589 typedef enum sess_close vdi_http1pipe_f(VRT_CTX, VCL_BACKEND);
590 typedef void vdi_event_f(VCL_BACKEND, enum vcl_event_e);
591 typedef void vdi_destroy_f(VCL_BACKEND);
592 typedef void vdi_panic_f(VCL_BACKEND, struct vsb *);
593 typedef void vdi_list_f(VRT_CTX, VCL_BACKEND, struct vsb *, int, int);
594 
595 struct vdi_methods {
596 	unsigned			magic;
597 #define VDI_METHODS_MAGIC		0x4ec0c4bb
598 	const char			*type;
599 	vdi_http1pipe_f			*http1pipe;
600 	vdi_healthy_f			*healthy;
601 	vdi_resolve_f			*resolve;
602 	vdi_gethdrs_f			*gethdrs;
603 	vdi_getip_f			*getip;
604 	vdi_finish_f			*finish;
605 	vdi_event_f			*event;
606 	vdi_destroy_f			*destroy;
607 	vdi_panic_f			*panic;
608 	vdi_list_f			*list;
609 };
610 
611 struct director {
612 	unsigned			magic;
613 #define DIRECTOR_MAGIC			0x3336351d
614 	void				*priv;
615 	char				*vcl_name;
616 	struct vcldir			*vdir;
617 };
618 
619 VCL_BOOL VRT_Healthy(VRT_CTX, VCL_BACKEND, VCL_TIME *);
620 VCL_VOID VRT_SetChanged(VCL_BACKEND, VCL_TIME);
621 VCL_BACKEND VRT_AddDirector(VRT_CTX, const struct vdi_methods *,
622     void *, const char *, ...) v_printflike_(4, 5);
623 void VRT_DisableDirector(VCL_BACKEND);
624 VCL_BACKEND VRT_LookupDirector(VRT_CTX, VCL_STRING);
625 void VRT_DelDirector(VCL_BACKEND *);
626 
627 /***********************************************************************
628  * vmod_priv related
629  */
630 typedef void vmod_priv_fini_f(VRT_CTX, void *);
631 
632 struct vmod_priv_methods {
633 	unsigned			magic;
634 #define VMOD_PRIV_METHODS_MAGIC	0xcea5ff99
635 	const char			*type;
636 	vmod_priv_fini_f		*fini;
637 };
638 
639 struct vmod_priv {
640 	void				*priv;
641 	long				len;
642 	const struct vmod_priv_methods	*methods;
643 };
644 
645 void VRT_priv_fini(VRT_CTX, const struct vmod_priv *p);
646 struct vmod_priv *VRT_priv_task(VRT_CTX, const void *vmod_id);
647 struct vmod_priv *VRT_priv_task_get(VRT_CTX, const void *vmod_id);
648 struct vmod_priv *VRT_priv_top(VRT_CTX, const void *vmod_id);
649 struct vmod_priv *VRT_priv_top_get(VRT_CTX, const void *vmod_id);
650 
651 /***********************************************************************
652  * VSM and VSC
653  */
654 
655 struct vsmw_cluster *VRT_VSM_Cluster_New(VRT_CTX, size_t);
656 void VRT_VSM_Cluster_Destroy(VRT_CTX, struct vsmw_cluster **);
657 
658 #ifdef va_start	// XXX: hackish
659 void *VRT_VSC_Alloc(struct vsmw_cluster *, struct vsc_seg **,
660     const char *, size_t, const unsigned char *, size_t, const char *, va_list);
661 #endif
662 void VRT_VSC_Destroy(const char *, struct vsc_seg *);
663 void VRT_VSC_Hide(const struct vsc_seg *);
664 void VRT_VSC_Reveal(const struct vsc_seg *);
665 size_t VRT_VSC_Overhead(size_t);
666 
667 /***********************************************************************
668  * API to restrict the VCL in various ways
669  */
670 
671 struct vclref;
672 struct vclref * VRT_VCL_Prevent_Cold(VRT_CTX, const char *);
673 void VRT_VCL_Allow_Cold(struct vclref **);
674 
675 struct vclref * VRT_VCL_Prevent_Discard(VRT_CTX, const char *);
676 void VRT_VCL_Allow_Discard(struct vclref **);
677 
678 /***********************************************************************
679  * Deprecated interfaces, do not use, they will disappear at some point.
680  */
681 
682 VCL_VOID VRT_synth_page(VRT_CTX, VCL_STRANDS);
683 extern const void * const vrt_magic_string_end;
684 extern const void * const vrt_magic_string_unset;
685 int VRT_Stv(const char *nm);
686