varnish-cache/bin/varnishd/cache/cache_deliver_proc.c
0
/*-
1
 * Copyright (c) 2006 Verdens Gang AS
2
 * Copyright (c) 2006-2015 Varnish Software AS
3
 * All rights reserved.
4
 *
5
 * Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
6
 *
7
 * SPDX-License-Identifier: BSD-2-Clause
8
 *
9
 * Redistribution and use in source and binary forms, with or without
10
 * modification, are permitted provided that the following conditions
11
 * are met:
12
 * 1. Redistributions of source code must retain the above copyright
13
 *    notice, this list of conditions and the following disclaimer.
14
 * 2. Redistributions in binary form must reproduce the above copyright
15
 *    notice, this list of conditions and the following disclaimer in the
16
 *    documentation and/or other materials provided with the distribution.
17
 *
18
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21
 * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
22
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28
 * SUCH DAMAGE.
29
 */
30
31
#include "config.h"
32
33
#include "cache_varnishd.h"
34
#include "cache_filter.h"
35
#include "cache_objhead.h"
36
37
void
38 240
VDP_Panic(struct vsb *vsb, const struct vdp_ctx *vdc)
39
{
40
        struct vdp_entry *vde;
41
42 240
        if (PAN_dump_struct(vsb, vdc, VDP_CTX_MAGIC, "vdc"))
43 160
                return;
44 80
        VSB_printf(vsb, "nxt = %p,\n", vdc->nxt);
45 80
        VSB_printf(vsb, "retval = %d,\n", vdc->retval);
46
47 80
        if (!VTAILQ_EMPTY(&vdc->vdp)) {
48 40
                VSB_cat(vsb, "filters = {\n");
49 40
                VSB_indent(vsb, 2);
50 120
                VTAILQ_FOREACH(vde, &vdc->vdp, list)
51 160
                        VSB_printf(vsb, "%s = %p { priv = %p }\n",
52 80
                            vde->vdp->name, vde, vde->priv);
53 40
                VSB_indent(vsb, -2);
54 40
                VSB_cat(vsb, "},\n");
55 40
        }
56
57 80
        VSB_indent(vsb, -2);
58 80
        VSB_cat(vsb, "},\n");
59 240
}
60
61
/*
62
 * Ensure that transports have called VDP_Close()
63
 * to avoid leaks in VDPs
64
 */
65
void
66 157834
VDP_Fini(const struct vdp_ctx *vdc)
67
{
68 157834
        assert(VTAILQ_EMPTY(&vdc->vdp));
69 157834
}
70
71
void
72 224656
VDP_Init(struct vdp_ctx *vdc, struct worker *wrk, struct vsl_log *vsl,
73
    const struct req *req, const struct busyobj *bo, intmax_t *clen)
74
{
75 224656
        AN(vdc);
76 224656
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
77 224656
        AN(vsl);
78
79 224656
        AN(clen);
80
81 224656
        assert((req ? 1 : 0) ^ (bo ? 1 : 0));
82
83 224656
        AN(clen);
84 224656
        assert(*clen >= -1);
85
86 224656
        INIT_OBJ(vdc, VDP_CTX_MAGIC);
87 224656
        VTAILQ_INIT(&vdc->vdp);
88 224656
        vdc->wrk = wrk;
89 224656
        vdc->vsl = vsl;
90 224656
        vdc->clen = clen;
91
92 224656
        if (req != NULL) {
93 141059
                CHECK_OBJ(req, REQ_MAGIC);
94 141059
                vdc->oc = req->objcore;
95 141059
                vdc->hp = req->resp;
96 141059
        }
97
        else {
98 83597
                CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
99 83597
                vdc->oc = bo->bereq_body;
100 83597
                vdc->hp = bo->bereq;
101
        }
102 224656
}
103
104
/* VDP_bytes
105
 *
106
 * Pushes len bytes at ptr down the delivery processor list.
107
 *
108
 * This function picks and calls the next delivery processor from the
109
 * list. The return value is the return value of the delivery
110
 * processor. Upon seeing a non-zero return value, that lowest value
111
 * observed is latched in ->retval and all subsequent calls to
112
 * VDP_bytes will return that value directly without calling the next
113
 * processor.
114
 *
115
 * VDP_END marks the end of successful processing, it is issued by
116
 * VDP_DeliverObj() and may also be sent downstream by processors ending the
117
 * stream (for return value != 0)
118
 *
119
 * VDP_END must at most be received once per processor, so any VDP sending it
120
 * downstream must itself not forward it a second time.
121
 *
122
 * Valid return values (of VDP_bytes and any VDP function):
123
 * r < 0:  Error, breaks out early on an error condition
124
 * r == 0: Continue
125
 * r > 0:  Stop, breaks out early without error condition
126
 */
127
128
int
129 321741
VDP_bytes(struct vdp_ctx *vdc, enum vdp_action act,
130
    const void *ptr, ssize_t len)
131
{
132
        int retval;
133
        struct vdp_entry *vdpe;
134
135 321741
        CHECK_OBJ_NOTNULL(vdc, VDP_CTX_MAGIC);
136 321741
        if (vdc->retval)
137 958
                return (vdc->retval);
138 320783
        vdpe = vdc->nxt;
139 320783
        CHECK_OBJ_NOTNULL(vdpe, VDP_ENTRY_MAGIC);
140
141
        /* at most one VDP_END call */
142 320783
        assert(vdpe->end == VDP_NULL);
143
144 320783
        if (act == VDP_NULL)
145 17107
                assert(len > 0);
146 303676
        else if (act == VDP_END)
147 109561
                vdpe->end = VDP_END;
148
        else
149 194115
                assert(act == VDP_FLUSH);
150
151
        /* Call the present layer, while pointing to the next layer down */
152 320783
        vdc->nxt = VTAILQ_NEXT(vdpe, list);
153 320783
        vdpe->calls++;
154 320783
        vdc->bytes_done = len;
155 320783
        retval = vdpe->vdp->bytes(vdc, act, &vdpe->priv, ptr, len);
156 320783
        vdpe->bytes_in += vdc->bytes_done;
157 320783
        if (retval && (vdc->retval == 0 || retval < vdc->retval))
158 2182
                vdc->retval = retval; /* Latch error value */
159 320783
        vdc->nxt = vdpe;
160 320783
        return (vdc->retval);
161 321741
}
162
163
int
164 203655
VDP_Push(VRT_CTX, struct vdp_ctx *vdc, struct ws *ws, const struct vdp *vdp,
165
    void *priv)
166
{
167
        struct vdp_entry *vdpe;
168
169 203655
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
170 203655
        CHECK_OBJ_NOTNULL(vdc, VDP_CTX_MAGIC);
171 203655
        CHECK_OBJ_ORNULL(vdc->oc, OBJCORE_MAGIC);
172 203655
        CHECK_OBJ_NOTNULL(vdc->hp, HTTP_MAGIC);
173 203655
        AN(vdc->clen);
174 203655
        assert(*vdc->clen >= -1);
175 203655
        AN(ws);
176 203655
        AN(vdp);
177 203655
        AN(vdp->name);
178
179 203655
        if (vdc->retval)
180 0
                return (vdc->retval);
181
182 203655
        if (DO_DEBUG(DBG_PROCESSORS))
183 0
                VSLb(vdc->vsl, SLT_Debug, "VDP_push(%s)", vdp->name);
184
185 203655
        vdpe = WS_Alloc(ws, sizeof *vdpe);
186 203655
        if (vdpe == NULL) {
187 5120
                AZ(vdc->retval);
188 5120
                vdc->retval = -1;
189 5120
                return (vdc->retval);
190
        }
191 198535
        INIT_OBJ(vdpe, VDP_ENTRY_MAGIC);
192 198535
        vdpe->vdp = vdp;
193 198535
        vdpe->priv = priv;
194 198535
        VTAILQ_INSERT_TAIL(&vdc->vdp, vdpe, list);
195 198535
        vdc->nxt = VTAILQ_FIRST(&vdc->vdp);
196
197 198535
        AZ(vdc->retval);
198 198535
        if (vdpe->vdp->init != NULL)
199 186110
                vdc->retval = vdpe->vdp->init(ctx, vdc, &vdpe->priv);
200 198535
        vdc->oc = NULL;
201
202 198535
        if (vdc->retval > 0) {
203 1520
                VTAILQ_REMOVE(&vdc->vdp, vdpe, list);
204 1520
                vdc->nxt = VTAILQ_FIRST(&vdc->vdp);
205 1520
                vdc->retval = 0;
206 1520
        }
207 197015
        else if (vdc->retval == 0)
208 196698
                AN(vdp->bytes);
209 198535
        return (vdc->retval);
210 203655
}
211
212
uint64_t
213 224612
VDP_Close(struct vdp_ctx *vdc, struct objcore *oc, struct boc *boc)
214
{
215
        struct vdp_entry *vdpe;
216 224612
        uint64_t rv = 0;
217
218 224612
        CHECK_OBJ_NOTNULL(vdc, VDP_CTX_MAGIC);
219 224612
        CHECK_OBJ_NOTNULL(vdc->wrk, WORKER_MAGIC);
220 224612
        CHECK_OBJ_ORNULL(oc, OBJCORE_MAGIC);
221 224612
        CHECK_OBJ_ORNULL(boc, BOC_MAGIC);
222
223 421561
        while (!VTAILQ_EMPTY(&vdc->vdp)) {
224 196949
                vdpe = VTAILQ_FIRST(&vdc->vdp);
225 196949
                rv = vdpe->bytes_in;
226 393898
                VSLb(vdc->vsl, SLT_VdpAcct, "%s %ju %ju", vdpe->vdp->name,
227 196949
                    (uintmax_t)vdpe->calls, (uintmax_t)rv);
228 196949
                if (vdc->retval >= 0)
229 193007
                        AN(vdpe);
230 196949
                if (vdpe != NULL) {
231 196948
                        CHECK_OBJ(vdpe, VDP_ENTRY_MAGIC);
232 196948
                        if (vdpe->vdp->fini != NULL)
233 36757
                                AZ(vdpe->vdp->fini(vdc, &vdpe->priv));
234 196948
                        AZ(vdpe->priv);
235 196948
                        VTAILQ_REMOVE(&vdc->vdp, vdpe, list);
236 196948
                }
237 196949
                vdc->nxt = VTAILQ_FIRST(&vdc->vdp);
238
#ifdef VDP_PEDANTIC_ARMED
239
                // enable when we are confident to get VDP_END right
240
                if (vdc->nxt == NULL && vdc->retval >= 0)
241
                        assert(vdpe->end == VDP_END);
242
#endif
243
        }
244 224610
        if (oc != NULL)
245 141012
                HSH_Cancel(vdc->wrk, oc, boc);
246 224610
        return (rv);
247
}
248
249
/*--------------------------------------------------------------------*/
250
251
int v_matchproto_(objiterate_f)
252 163812
VDP_ObjIterate(void *priv, unsigned flush, const void *ptr, ssize_t len)
253
{
254
        enum vdp_action act;
255
256 163812
        if (flush == 0)
257 6307
                act = VDP_NULL;
258 157505
        else if ((flush & OBJ_ITER_END) != 0)
259 94834
                act = VDP_END;
260
        else
261 62671
                act = VDP_FLUSH;
262
263 163812
        return (VDP_bytes(priv, act, ptr, len));
264
}
265
266
267
int
268 92355
VDP_DeliverObj(struct vdp_ctx *vdc, struct objcore *oc)
269
{
270
        int r, final;
271
272 92355
        CHECK_OBJ_NOTNULL(vdc, VDP_CTX_MAGIC);
273 92355
        CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
274 92355
        CHECK_OBJ_NOTNULL(vdc->wrk, WORKER_MAGIC);
275 92355
        AN(vdc->vsl);
276 92355
        AZ(vdc->oc);
277 92355
        vdc->hp = NULL;
278 92355
        vdc->clen = NULL;
279 92355
        final = oc->flags & OC_F_TRANSIENT ? 1 : 0;
280 92355
        r = ObjIterate(vdc->wrk, oc, vdc, VDP_ObjIterate, final);
281 92355
        if (r < 0)
282 1540
                return (r);
283 90815
        return (0);
284 92355
}