vinyl-cache/bin/vinyld/cache/cache_backend.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
 * The director implementation for VCL backends.
31
 *
32
 */
33
34
#include "config.h"
35
36
#include <stdlib.h>
37
38 1604
#include "cache_int.h"
39 1520
#include "cache_director.h"
40 1468
41 1448
#include "vtcp.h"
42 1448
#include "vtim.h"
43 1036
#include "vsa.h"
44 964
45 820
#include "cache_backend.h"
46 776
#include "cache_conn_pool.h"
47 700
#include "cache_transport.h"
48 636
#include "cache_vcl.h"
49 636
#include "http1/cache_http1.h"
50 168
#include "proxy/cache_proxy.h"
51
52
#include "VSC_vbe.h"
53
54
/*--------------------------------------------------------------------*/
55
56
enum connwait_e {
57
        CW_DO_CONNECT = 1,
58
        CW_QUEUED,
59
        CW_DEQUEUED,
60
        CW_BE_BUSY,
61
};
62
63
struct connwait {
64
        unsigned                        magic;
65
#define CONNWAIT_MAGIC                  0x75c7a52b
66
        enum connwait_e                 cw_state;
67
        VTAILQ_ENTRY(connwait)          cw_list;
68
        pthread_cond_t                  cw_cond;
69
};
70
71
static const char * const vbe_proto_ident = "HTTP Backend";
72
73
static struct lock backends_mtx;
74
75
/*--------------------------------------------------------------------*/
76
77
void
78 186
VBE_Connect_Error(struct VSC_vbe *vsc, int err)
79
{
80
81 186
        switch(err) {
82
        case 0:
83
                /*
84
                 * This is kind of brittle, but zero is the only
85
                 * value of errno we can trust to have no meaning.
86
                 */
87 79
                vsc->helddown++;
88 79
                break;
89
        case EACCES:
90
        case EPERM:
91 0
                vsc->fail_eacces++;
92 0
                break;
93
        case EADDRNOTAVAIL:
94 0
                vsc->fail_eaddrnotavail++;
95 0
                break;
96
        case ECONNREFUSED:
97 107
                vsc->fail_econnrefused++;
98 107
                break;
99
        case ENETUNREACH:
100 0
                vsc->fail_enetunreach++;
101 0
                break;
102
        case ETIMEDOUT:
103 0
                vsc->fail_etimedout++;
104 0
                break;
105
        default:
106 0
                vsc->fail_other++;
107 0
        }
108 186
}
109
110
/*--------------------------------------------------------------------*/
111
112
#define FIND_TMO(tmx, dst, bo, be)                                      \
113
        do {                                                            \
114
                CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);                   \
115
                dst = bo->tmx;                                          \
116
                if (isnan(dst) && be->tmx >= 0.0)                       \
117
                        dst = be->tmx;                                  \
118
                if (isnan(dst))                                         \
119
                        dst = cache_param->tmx;                         \
120
        } while (0)
121
122
#define FIND_BE_SPEC(tmx, dst, be, def)                                 \
123
        do {                                                            \
124
                CHECK_OBJ_NOTNULL(bp, BACKEND_MAGIC);                   \
125
                dst = be->tmx;                                          \
126
                if (dst == def)                                         \
127
                        dst = cache_param->tmx;                         \
128
        } while (0)
129
130
#define FIND_BE_PARAM(tmx, dst, be)                                     \
131
        FIND_BE_SPEC(tmx, dst, be, 0)
132
133
#define FIND_BE_TMO(tmx, dst, be)                                       \
134
        FIND_BE_SPEC(tmx, dst, be, -1.0)
135
136
#define BE_BUSY(be)     \
137
        (be->max_connections > 0 && be->n_conn >= be->max_connections)
138
139
/*--------------------------------------------------------------------*/
140
141
static void
142 287
vbe_connwait_broadcast(const struct backend *bp)
143
{
144
        struct connwait *cw;
145
146 287
        CHECK_OBJ_NOTNULL(bp, BACKEND_MAGIC);
147
148 287
        Lck_Lock(bp->director->mtx);
149 323
        VTAILQ_FOREACH(cw, &bp->cw_head, cw_list) {
150 36
                CHECK_OBJ(cw, CONNWAIT_MAGIC);
151 36
                assert(cw->cw_state == CW_QUEUED);
152 36
                PTOK(pthread_cond_signal(&cw->cw_cond));
153 36
        }
154 287
        Lck_Unlock(bp->director->mtx);
155 287
}
156
157
static void
158 9215
vbe_connwait_signal_locked(const struct backend *bp)
159
{
160
        struct connwait *cw;
161
162 9215
        Lck_AssertHeld(bp->director->mtx);
163
164 9215
        if (bp->n_conn < bp->max_connections) {
165 44
                cw = VTAILQ_FIRST(&bp->cw_head);
166 44
                if (cw != NULL) {
167 4
                        CHECK_OBJ(cw, CONNWAIT_MAGIC);
168 4
                        assert(cw->cw_state == CW_QUEUED);
169 4
                        PTOK(pthread_cond_signal(&cw->cw_cond));
170 4
                }
171 44
        }
172 9215
}
173
174
static void
175 9272
vbe_connwait_fini(struct connwait *cw)
176
{
177 9272
        CHECK_OBJ_NOTNULL(cw, CONNWAIT_MAGIC);
178 9272
        assert(cw->cw_state != CW_QUEUED);
179 9272
        PTOK(pthread_cond_destroy(&cw->cw_cond));
180 9272
        FINI_OBJ(cw);
181 9272
}
182
183
/*--------------------------------------------------------------------
184
 * Update bc_ counters by reason (implementing ses_close_acct for backends)
185
 *
186
 * assuming that the approximation of non-atomic global counters is sufficient.
187
 * if not: update to per-wrk
188
 */
189
190
static void
191 1620
vbe_close_acct(const struct pfd *pfd, struct VSC_vbe *vsc,
192
    const stream_close_t reason)
193
{
194
195 1620
        if (reason == SC_NULL) {
196 16
                assert(PFD_State(pfd) == PFD_STATE_USED);
197 16
                VSC_C_main->bc_tx_proxy++;
198 16
                vsc->tx_proxy++;
199 16
                return;
200
        }
201
202
#define SESS_CLOSE(U, l, err, desc)                                     \
203
        if (reason == SC_ ## U) {                                       \
204
                VSC_C_main->bc_ ## l++;                                 \
205
                vsc->l++;                                               \
206
                if (err) {                                              \
207
                        VSC_C_main->backend_closed_err++;               \
208
                        vsc->closed_err++;                              \
209
                }                                                       \
210
                return;                                                 \
211
        }
212
#include "tbl/sess_close.h"
213
        else
214 0
                WRONG("Wrong event in vbe_close_acct");
215
}
216
217
static void v_matchproto_(vdi_finish_f)
218 8968
vbe_dir_finish(VRT_CTX, VCL_BACKEND d)
219
{
220
        struct backend *bp;
221
        struct busyobj *bo;
222
        struct pfd *pfd;
223
224 8968
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
225 8968
        CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC);
226 8968
        bo = ctx->bo;
227 8968
        CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
228 8968
        CAST_OBJ_NOTNULL(bp, d->priv, BACKEND_MAGIC);
229 8968
        AN(bp->vsc);
230
231 8968
        CHECK_OBJ_NOTNULL(bo->htc, HTTP_CONN_MAGIC);
232 8968
        CHECK_OBJ_NOTNULL(bo->htc->doclose, STREAM_CLOSE_MAGIC);
233
234 8968
        pfd = bo->htc->priv;
235 8968
        bo->htc->priv = NULL;
236 8968
        if (bo->htc->doclose != SC_NULL || bp->proxy_header != 0) {
237 1620
                vbe_close_acct(pfd, bp->vsc, bo->htc->doclose);
238 3240
                VSLb(bo->vsl, SLT_BackendClose, "%d %s close %s", *PFD_Fd(pfd),
239 1620
                    VRT_BACKEND_string(d), bo->htc->doclose->name);
240 1620
                VCP_Close(&pfd);
241 1620
                AZ(pfd);
242 1620
                Lck_Lock(bp->director->mtx);
243 1620
                VSC_C_main->backend_closed++;
244 1620
                bp->vsc->closed++;
245 1620
        } else {
246 7348
                assert (PFD_State(pfd) == PFD_STATE_USED);
247 14696
                VSLb(bo->vsl, SLT_BackendClose, "%d %s recycle", *PFD_Fd(pfd),
248 7348
                    VRT_BACKEND_string(d));
249 7348
                Lck_Lock(bp->director->mtx);
250 7348
                VSC_C_main->backend_recycle++;
251 7348
                VCP_Recycle(bo->wrk, &pfd);
252
        }
253 8968
        assert(bp->n_conn > 0);
254 8968
        bp->n_conn--;
255 8968
        AN(bp->vsc);
256 8968
        bp->vsc->conn--;
257
#define ACCT(foo)       bp->vsc->foo += bo->acct.foo;
258
#include "tbl/acct_fields_bereq.h"
259
        vbe_connwait_signal_locked(bp);
260
        Lck_Unlock(bp->director->mtx);
261
        bo->htc = NULL;
262
}
263
264
/*--------------------------------------------------------------------
265
 * Get a connection to the backend
266
 *
267
 * note: wrk is a separate argument because it differs for pipe vs. fetch
268
 */
269
270
static struct pfd *
271 9292
vbe_dir_getfd(VRT_CTX, struct worker *wrk, VCL_BACKEND dir, struct backend *bp,
272
    unsigned force_fresh)
273
{
274
        struct busyobj *bo;
275
        struct pfd *pfd;
276
        int *fdp, err;
277
        vtim_dur tmod;
278
        char abuf1[VTCP_ADDRBUFSIZE], abuf2[VTCP_ADDRBUFSIZE];
279
        char pbuf1[VTCP_PORTBUFSIZE], pbuf2[VTCP_PORTBUFSIZE];
280
        unsigned wait_limit;
281
        vtim_dur wait_tmod;
282
        vtim_dur wait_end;
283
        struct connwait cw[1];
284
285 9292
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
286 9292
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
287 9292
        bo = ctx->bo;
288 9292
        CHECK_OBJ_NOTNULL(bp, BACKEND_MAGIC);
289 9292
        AN(bp->vsc);
290
291 9292
        if (!VRT_Healthy(ctx, dir, NULL)) {
292 40
                VSLb(bo->vsl, SLT_FetchError,
293 20
                     "backend %s: unhealthy", VRT_BACKEND_string(dir));
294 20
                bp->vsc->unhealthy++;
295 20
                VSC_C_main->backend_unhealthy++;
296 20
                return (NULL);
297
        }
298 9272
        INIT_OBJ(cw, CONNWAIT_MAGIC);
299 9272
        PTOK(pthread_cond_init(&cw->cw_cond, NULL));
300 9272
        Lck_Lock(bp->director->mtx);
301 9272
        FIND_BE_PARAM(backend_wait_limit, wait_limit, bp);
302 9272
        FIND_BE_TMO(backend_wait_timeout, wait_tmod, bp);
303 9272
        cw->cw_state = CW_DO_CONNECT;
304 9272
        if (!VTAILQ_EMPTY(&bp->cw_head) || BE_BUSY(bp))
305 56
                cw->cw_state = CW_BE_BUSY;
306
307 9320
        if (cw->cw_state == CW_BE_BUSY && wait_limit > 0 &&
308 48
            wait_tmod > 0.0 && bp->cw_count < wait_limit) {
309 48
                VTAILQ_INSERT_TAIL(&bp->cw_head, cw, cw_list);
310 48
                bp->cw_count++;
311 48
                VSC_C_main->backend_wait++;
312 48
                cw->cw_state = CW_QUEUED;
313 48
                wait_end = VTIM_real() + wait_tmod;
314 48
                do {
315 96
                        err = Lck_CondWaitUntil(&cw->cw_cond, bp->director->mtx,
316 48
                            wait_end);
317 48
                } while (err == EINTR);
318 48
                assert(cw->cw_state == CW_QUEUED);
319 48
                VTAILQ_REMOVE(&bp->cw_head, cw, cw_list);
320 48
                cw->cw_state = CW_DEQUEUED;
321 48
                bp->cw_count--;
322 48
                if ((err != 0 && BE_BUSY(bp)) || !VRT_Healthy(ctx, dir, NULL)) {
323 44
                        VSC_C_main->backend_wait_fail++;
324 44
                        cw->cw_state = CW_BE_BUSY;
325 44
                }
326 48
        }
327 9272
        if (cw->cw_state != CW_BE_BUSY)
328 9220
                bp->n_conn++;
329
330 9272
        if (!VTAILQ_EMPTY(&bp->cw_head) && !BE_BUSY(bp)) {
331
                /* Signal the new head of the waiting queue */
332 0
                vbe_connwait_signal_locked(bp);
333 0
        }
334
335 9272
        Lck_Unlock(bp->director->mtx);
336
337 9272
        if (cw->cw_state == CW_BE_BUSY) {
338 104
                VSLb(bo->vsl, SLT_FetchError,
339 52
                     "backend %s: busy", VRT_BACKEND_string(dir));
340 52
                bp->vsc->busy++;
341 52
                VSC_C_main->backend_busy++;
342 52
                vbe_connwait_fini(cw);
343 52
                return (NULL);
344
        }
345
346 9220
        AZ(bo->htc);
347 9220
        bo->htc = WS_Alloc(bo->ws, sizeof *bo->htc);
348
        /* XXX: we may want to detect the ws overflow sooner */
349 9220
        if (bo->htc == NULL) {
350 124
                VSLb(bo->vsl, SLT_FetchError, "out of workspace");
351
                /* XXX: counter ? */
352 124
                Lck_Lock(bp->director->mtx);
353 124
                bp->n_conn--;
354 124
                vbe_connwait_signal_locked(bp);
355 124
                Lck_Unlock(bp->director->mtx);
356 124
                vbe_connwait_fini(cw);
357 124
                return (NULL);
358
        }
359 9096
        bo->htc->doclose = SC_NULL;
360 9096
        CHECK_OBJ_NOTNULL(bo->htc->doclose, STREAM_CLOSE_MAGIC);
361
362 9096
        FIND_TMO(connect_timeout, tmod, bo, bp);
363 9096
        pfd = VCP_Get(bp->conn_pool, tmod, wrk, force_fresh, &err);
364 9096
        if (pfd == NULL) {
365 124
                Lck_Lock(bp->director->mtx);
366 124
                VBE_Connect_Error(bp->vsc, err);
367 124
                bp->n_conn--;
368 124
                vbe_connwait_signal_locked(bp);
369 124
                Lck_Unlock(bp->director->mtx);
370 248
                VSLb(bo->vsl, SLT_FetchError,
371
                     "backend %s: fail errno %d (%s)",
372 124
                     VRT_BACKEND_string(dir), err, VAS_errtxt(err));
373 124
                VSC_C_main->backend_fail++;
374 124
                bo->htc = NULL;
375 124
                vbe_connwait_fini(cw);
376 124
                return (NULL);
377
        }
378
379 8972
        VSLb_ts_busyobj(bo, "Connected", W_TIM_real(wrk));
380 8972
        fdp = PFD_Fd(pfd);
381 8972
        AN(fdp);
382 8972
        assert(*fdp >= 0);
383
384 8972
        Lck_Lock(bp->director->mtx);
385 8972
        bp->vsc->conn++;
386 8972
        bp->vsc->req++;
387 8972
        Lck_Unlock(bp->director->mtx);
388
389 8972
        INIT_OBJ(bo->htc, HTTP_CONN_MAGIC);
390 8972
        bo->htc->priv = pfd;
391 8972
        bo->htc->rfd = fdp;
392 8972
        bo->htc->doclose = SC_NULL;
393 8972
        CHECK_OBJ_NOTNULL(bo->htc->doclose, STREAM_CLOSE_MAGIC);
394
395 8972
        err = 0;
396 8972
        if (bp->proxy_header != 0)
397 24
                err = VPX_Send_Proxy(*fdp, bp->proxy_header, bo->sp);
398 8972
        if (err < 0) {
399 8
                VSLb(bo->vsl, SLT_FetchError,
400
                     "backend %s: proxy write errno %d (%s)",
401 4
                     VRT_BACKEND_string(dir),
402 4
                     errno, VAS_errtxt(errno));
403 4
                bo->htc->doclose = SC_TX_ERROR;
404 4
                Lck_Lock(bp->director->mtx);
405 4
                VSC_C_main->backend_fail++;
406 4
                bp->vsc->req--;
407 4
                Lck_Unlock(bp->director->mtx);
408 4
                vbe_dir_finish(ctx, dir);
409 4
                vbe_connwait_fini(cw);
410 4
                return (NULL);
411
        }
412 8968
        bo->acct.bereq_hdrbytes += err;
413
414 8968
        PFD_LocalName(pfd, abuf1, sizeof abuf1, pbuf1, sizeof pbuf1);
415 8968
        PFD_RemoteName(pfd, abuf2, sizeof abuf2, pbuf2, sizeof pbuf2);
416 8968
        if (PFD_State(pfd) != PFD_STATE_STOLEN) {
417 11352
                VSLb(bo->vsl, SLT_BackendOpen, "%d %s %s %s %s %s connect",
418 5676
                    *fdp, VRT_BACKEND_string(dir), abuf2, pbuf2, abuf1, pbuf1);
419 5676
        } else {
420 6584
                VSLb(bo->vsl, SLT_BackendOpen,
421 3292
                    "%d %s %s %s %s %s reuse %.6f %ju", *fdp,
422 3292
                    VRT_BACKEND_string(dir), abuf2, pbuf2, abuf1, pbuf1,
423 3292
                    PFD_Age(pfd), (uintmax_t)PFD_Reused(pfd));
424
        }
425
426 8968
        FIND_TMO(first_byte_timeout,
427
            bo->htc->first_byte_timeout, bo, bp);
428 8968
        FIND_TMO(between_bytes_timeout,
429
            bo->htc->between_bytes_timeout, bo, bp);
430 8968
        vbe_connwait_fini(cw);
431 8968
        return (pfd);
432 9292
}
433
434
static int v_matchproto_(vdi_gethdrs_f)
435 9171
vbe_dir_gethdrs(VRT_CTX, VCL_BACKEND d)
436
{
437 9171
        int i, retry_connect = 1;
438
        struct backend *bp;
439
        struct pfd *pfd;
440
        struct busyobj *bo;
441
        struct worker *wrk;
442
443 9171
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
444 9171
        CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC);
445 9171
        bo = ctx->bo;
446 9171
        CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
447 9171
        CHECK_OBJ_NOTNULL(bo->bereq, HTTP_MAGIC);
448 9171
        if (bo->htc != NULL)
449 0
                CHECK_OBJ_NOTNULL(bo->htc->doclose, STREAM_CLOSE_MAGIC);
450 9171
        wrk = ctx->bo->wrk;
451 9171
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
452 9171
        CAST_OBJ_NOTNULL(bp, d->priv, BACKEND_MAGIC);
453
454
        /*
455
         * Now that we know our backend, we can set a default Host:
456
         * header if one is necessary.  This cannot be done in the VCL
457
         * because the backend may be chosen by a director.
458
         */
459 9171
        if (!http_GetHdr(bo->bereq, H_Host, NULL) && bp->hosthdr != NULL)
460 272
                http_PrintfHeader(bo->bereq, "Host: %s", bp->hosthdr);
461
462 9171
        do {
463 9196
                if (bo->htc != NULL)
464 0
                        CHECK_OBJ_NOTNULL(bo->htc->doclose, STREAM_CLOSE_MAGIC);
465 9196
                pfd = vbe_dir_getfd(ctx, wrk, d, bp, retry_connect == 0 ? 1 : 0);
466 9196
                if (pfd == NULL)
467 320
                        return (-1);
468 8876
                AN(bo->htc);
469 8876
                CHECK_OBJ_NOTNULL(bo->htc->doclose, STREAM_CLOSE_MAGIC);
470 8876
                if (PFD_State(pfd) != PFD_STATE_STOLEN)
471 5592
                        retry_connect = 0;
472
473 17752
                i = V1F_SendReq(wrk, bo, &bo->acct.bereq_hdrbytes,
474 8876
                    &bo->acct.bereq_bodybytes);
475
476 8876
                if (i == 0 && PFD_State(pfd) != PFD_STATE_USED) {
477 9840
                        if (VCP_Wait(wrk, pfd, VTIM_real() +
478 6560
                            bo->htc->first_byte_timeout) != 0) {
479 4
                                bo->htc->doclose = SC_RX_TIMEOUT;
480 4
                                VSLb(bo->vsl, SLT_FetchError,
481
                                     "first byte timeout (reused connection)");
482 4
                                retry_connect = 0;
483 4
                        }
484 3280
                }
485
486 8876
                if (bo->htc->doclose == SC_NULL) {
487 8740
                        assert(PFD_State(pfd) == PFD_STATE_USED);
488 8740
                        if (i == 0)
489 8740
                                i = V1F_FetchRespHdr(bo);
490 8740
                        if (i == 0) {
491 8416
                                AN(bo->htc->priv);
492 8416
                                http_VSL_log(bo->beresp);
493 8416
                                return (0);
494
                        }
495 324
                }
496 460
                CHECK_OBJ_NOTNULL(bo->htc->doclose, STREAM_CLOSE_MAGIC);
497
498
                /*
499
                 * If we recycled a backend connection, there is a finite chance
500
                 * that the backend closed it before we got the bereq to it.
501
                 * In that case do a single automatic retry if req.body allows.
502
                 */
503 460
                vbe_dir_finish(ctx, d);
504 460
                AZ(bo->htc);
505 460
                if (i < 0 || retry_connect == 0)
506 420
                        break;
507 40
                if (bo->no_retry != NULL)
508 16
                        break;
509 24
                VSC_C_main->backend_retry++;
510 24
        } while (retry_connect--);
511 437
        return (-1);
512 9173
}
513
514
static VCL_IP v_matchproto_(vdi_getip_f)
515 4
vbe_dir_getip(VRT_CTX, VCL_BACKEND d)
516
{
517
        struct pfd *pfd;
518
519 4
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
520 4
        CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC);
521 4
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
522 4
        CHECK_OBJ_NOTNULL(ctx->bo->htc, HTTP_CONN_MAGIC);
523 4
        pfd = ctx->bo->htc->priv;
524
525 4
        return (VCP_GetIp(pfd));
526
}
527
528
/*--------------------------------------------------------------------*/
529
530
static stream_close_t v_matchproto_(vdi_http1pipe_f)
531 96
vbe_dir_http1pipe(VRT_CTX, VCL_BACKEND d)
532
{
533
        int i;
534
        stream_close_t retval;
535
        struct backend *bp;
536
        struct v1p_acct v1a;
537
        struct pfd *pfd;
538
        vtim_real deadline;
539
540 96
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
541 96
        CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC);
542 96
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
543 96
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
544 96
        CAST_OBJ_NOTNULL(bp, d->priv, BACKEND_MAGIC);
545
546 96
        memset(&v1a, 0, sizeof v1a);
547
548
        /* This is hackish... */
549 96
        v1a.req = ctx->req->acct.req_hdrbytes;
550 96
        ctx->req->acct.req_hdrbytes = 0;
551
552 96
        ctx->req->res_pipe = 1;
553
554 96
        retval = SC_TX_ERROR;
555 96
        pfd = vbe_dir_getfd(ctx, ctx->req->wrk, d, bp, 0);
556
557 96
        if (pfd != NULL) {
558 92
                CHECK_OBJ_NOTNULL(ctx->bo->htc, HTTP_CONN_MAGIC);
559 184
                i = V1F_SendReq(ctx->req->wrk, ctx->bo,
560 92
                    &v1a.bereq, &v1a.out);
561 92
                VSLb_ts_req(ctx->req, "Pipe", W_TIM_real(ctx->req->wrk));
562 92
                if (i == 0) {
563 92
                        deadline = ctx->bo->task_deadline;
564 92
                        if (isnan(deadline))
565 88
                                deadline = cache_param->pipe_task_deadline;
566 92
                        if (deadline > 0.)
567 12
                                deadline += ctx->req->sp->t_idle;
568 184
                        retval = V1P_Process(ctx->req, *PFD_Fd(pfd), &v1a,
569 92
                            deadline);
570 92
                }
571 92
                VSLb_ts_req(ctx->req, "PipeSess", W_TIM_real(ctx->req->wrk));
572 92
                ctx->bo->htc->doclose = retval;
573 92
                vbe_dir_finish(ctx, d);
574 92
        }
575 96
        V1P_Charge(ctx->req, &v1a, bp->vsc);
576 96
        CHECK_OBJ_NOTNULL(retval, STREAM_CLOSE_MAGIC);
577 96
        return (retval);
578
}
579
580
/*--------------------------------------------------------------------*/
581
582
static void
583 6363
vbe_dir_event(const struct director *d, enum vcl_event_e ev)
584
{
585
        struct backend *bp;
586
587 6363
        CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC);
588 6363
        CAST_OBJ_NOTNULL(bp, d->priv, BACKEND_MAGIC);
589
590 6363
        if (ev == VCL_EVENT_WARM) {
591 5436
                VRT_VSC_Reveal(bp->vsc_seg);
592 5436
                if (bp->probe != NULL)
593 152
                        VBP_Control(bp, 1);
594 6363
        } else if (ev == VCL_EVENT_COLD) {
595 332
                if (bp->probe != NULL)
596 28
                        VBP_Control(bp, 0);
597 332
                VRT_VSC_Hide(bp->vsc_seg);
598 927
        } else if (ev == VCL_EVENT_DISCARD) {
599 268
                VRT_DelDirector(&bp->director);
600 595
        } else if (ev == VDI_EVENT_SICK) {
601 327
                const struct vdi_ahealth *ah = d->vdir->admin_health;
602
603 327
                if (ah == VDI_AH_SICK || (ah == VDI_AH_AUTO && bp->sick))
604 287
                        vbe_connwait_broadcast(bp);
605 327
        }
606 6363
}
607
608
/*---------------------------------------------------------------------*/
609
610
static void
611 324
vbe_free(struct backend *be)
612
{
613
614 324
        CHECK_OBJ_NOTNULL(be, BACKEND_MAGIC);
615
616 324
        if (be->probe != NULL)
617 24
                VBP_Remove(be);
618
619 324
        VSC_vbe_Destroy(&be->vsc_seg);
620 324
        Lck_Lock(&backends_mtx);
621 324
        VSC_C_main->n_backend--;
622 324
        Lck_Unlock(&backends_mtx);
623 324
        VCP_Rel(&be->conn_pool);
624
625
#define DA(x)   do { if (be->x != NULL) free(be->x); } while (0)
626
#define DN(x)   /**/
627 324
        VRT_BACKEND_HANDLE();
628
#undef DA
629
#undef DN
630 324
        free(be->endpoint);
631
632 324
        assert(VTAILQ_EMPTY(&be->cw_head));
633 324
        FREE_OBJ(be);
634 324
}
635
636
static void v_matchproto_(vdi_destroy_f)
637 324
vbe_destroy(const struct director *d)
638
{
639
        struct backend *be;
640
641 324
        CAST_OBJ_NOTNULL(be, d->priv, BACKEND_MAGIC);
642 324
        vbe_free(be);
643 324
}
644
645
/*--------------------------------------------------------------------*/
646
647
static void
648 24
vbe_panic(const struct director *d, struct vsb *vsb)
649
{
650
        struct backend *bp;
651
652 24
        PAN_CheckMagic(vsb, d, DIRECTOR_MAGIC);
653 24
        bp = d->priv;
654 24
        PAN_CheckMagic(vsb, bp, BACKEND_MAGIC);
655
656 24
        VCP_Panic(vsb, bp->conn_pool);
657 24
        VSB_printf(vsb, "hosthdr = %s,\n", bp->hosthdr);
658 24
        VSB_printf(vsb, "n_conn = %u,\n", bp->n_conn);
659 24
}
660
661
/*--------------------------------------------------------------------
662
 */
663
664
static void v_matchproto_(vdi_list_f)
665 4756
vbe_list(VRT_CTX, const struct director *d, struct vsb *vsb, int pflag,
666
    int jflag)
667
{
668
        char buf[VTCP_ADDRBUFSIZE];
669
        struct backend *bp;
670
        struct vrt_endpoint *vep;
671
672 4756
        (void)ctx;
673
674 4756
        CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC);
675 4756
        CAST_OBJ_NOTNULL(bp, d->priv, BACKEND_MAGIC);
676 4756
        CHECK_OBJ_NOTNULL(bp->endpoint, VRT_ENDPOINT_MAGIC);
677
678 4756
        vep = bp->endpoint;
679
680 4756
        if (bp->probe != NULL)
681 328
                VBP_Status(vsb, bp, pflag, jflag);
682 4428
        else if (jflag && pflag)
683 20
                VSB_cat(vsb, "{},\n");
684 4408
        else if (jflag)
685 60
                VSB_cat(vsb, "[0, 0, \"healthy\"]");
686 4348
        else if (pflag)
687 36
                return;
688
        else
689 4312
                VSB_cat(vsb, "0/0\thealthy");
690
691 4720
        if (jflag && pflag) {
692 32
                if (vep->ipv4 != NULL) {
693 28
                        VTCP_name(vep->ipv4, buf, sizeof buf, NULL, 0);
694 28
                        VSB_printf(vsb, "\"ipv4\": \"%s\",\n", buf);
695 28
                }
696 32
                if (vep->ipv6 != NULL) {
697 4
                        VTCP_name(vep->ipv6, buf, sizeof buf, NULL, 0);
698 4
                        VSB_printf(vsb, "\"ipv6\": \"%s\",\n", buf);
699 4
                }
700 32
        }
701 4756
}
702
703
/*--------------------------------------------------------------------
704
 */
705
706
static VCL_BOOL v_matchproto_(vdi_healthy_f)
707 267
vbe_healthy(VRT_CTX, VCL_BACKEND d, VCL_TIME *t)
708
{
709
        struct backend *bp;
710
711 267
        (void)ctx;
712 267
        CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC);
713 267
        CAST_OBJ_NOTNULL(bp, d->priv, BACKEND_MAGIC);
714
715 267
        if (t != NULL)
716 168
                *t = bp->changed;
717
718 267
        return (!bp->sick);
719
}
720
721
/*--------------------------------------------------------------------
722
 */
723
724
static const struct vdi_methods vbe_methods[1] = {{
725
        .magic =                VDI_METHODS_MAGIC,
726
        .type =                 "backend",
727
        .http1pipe =            vbe_dir_http1pipe,
728
        .gethdrs =              vbe_dir_gethdrs,
729
        .getip =                vbe_dir_getip,
730
        .finish =               vbe_dir_finish,
731
        .event =                vbe_dir_event,
732
        .destroy =              vbe_destroy,
733
        .panic =                vbe_panic,
734
        .list =                 vbe_list,
735
        .healthy =              vbe_healthy
736
}};
737
738
static const struct vdi_methods vbe_methods_noprobe[1] = {{
739
        .magic =                VDI_METHODS_MAGIC,
740
        .type =                 "backend",
741
        .http1pipe =            vbe_dir_http1pipe,
742
        .gethdrs =              vbe_dir_gethdrs,
743
        .getip =                vbe_dir_getip,
744
        .finish =               vbe_dir_finish,
745
        .event =                vbe_dir_event,
746
        .destroy =              vbe_destroy,
747
        .panic =                vbe_panic,
748
        .list =                 vbe_list
749
}};
750
751
/*--------------------------------------------------------------------
752
 * Create a new static or dynamic director::backend instance.
753
 */
754
755
size_t
756 5056
VRT_backend_vsm_need(VRT_CTX)
757
{
758 5056
        (void)ctx;
759 5056
        return (VRT_VSC_Overhead(VSC_vbe_size));
760
}
761
762
/*
763
 * The new_backend via parameter is a VCL_BACKEND, but we need a (struct
764
 * backend)
765
 *
766
 * For now, we resolve it when creating the backend, which implies no redundancy
767
 * / load balancing across the via director if it is more than a simple backend.
768
 */
769
770
static const struct backend *
771 32
via_resolve(VRT_CTX, const struct vrt_endpoint *vep, VCL_BACKEND via)
772
{
773 32
        const struct backend *viabe = NULL;
774
775 32
        CHECK_OBJ_NOTNULL(vep, VRT_ENDPOINT_MAGIC);
776 32
        CHECK_OBJ_NOTNULL(via, DIRECTOR_MAGIC);
777
778 32
        if (vep->uds_path) {
779 0
                VRT_fail(ctx, "Via is only supported for IP addresses");
780 0
                return (NULL);
781
        }
782
783 32
        via = VRT_DirectorResolve(ctx, via);
784
785 32
        if (via == NULL) {
786 0
                VRT_fail(ctx, "Via resolution failed");
787 0
                return (NULL);
788
        }
789
790 32
        CHECK_OBJ(via, DIRECTOR_MAGIC);
791 32
        CHECK_OBJ_NOTNULL(via->vdir, VCLDIR_MAGIC);
792
793 32
        if (via->vdir->methods == vbe_methods ||
794 32
            via->vdir->methods == vbe_methods_noprobe)
795 32
                CAST_OBJ_NOTNULL(viabe, via->priv, BACKEND_MAGIC);
796
797 32
        if (viabe == NULL)
798 0
                VRT_fail(ctx, "Via does not resolve to a backend");
799
800 32
        return (viabe);
801 32
}
802
803
/*
804
 * construct a new endpoint identical to vep with sa in a proxy header
805
 */
806
static struct vrt_endpoint *
807 32
via_endpoint(const struct vrt_endpoint *vep, const struct suckaddr *sa,
808
    const char *auth)
809
{
810
        struct vsb *preamble;
811
        struct vrt_blob blob[1];
812
        struct vrt_endpoint *nvep, *ret;
813
        const struct suckaddr *client_bogo;
814
815 32
        CHECK_OBJ_NOTNULL(vep, VRT_ENDPOINT_MAGIC);
816 32
        AN(sa);
817
818 32
        nvep = VRT_Endpoint_Clone(vep);
819 32
        CHECK_OBJ_NOTNULL(nvep, VRT_ENDPOINT_MAGIC);
820
821 32
        if (VSA_Get_Proto(sa) == AF_INET6)
822 0
                client_bogo = bogo_ip6;
823
        else
824 32
                client_bogo = bogo_ip;
825
826 32
        preamble = VSB_new_auto();
827 32
        AN(preamble);
828 32
        VPX_Format_Proxy(preamble, 2, client_bogo, sa, auth);
829 32
        INIT_OBJ(blob, VRT_BLOB_MAGIC);
830 32
        blob->blob = VSB_data(preamble);
831 32
        blob->len = VSB_len(preamble);
832 32
        nvep->preamble = blob;
833 32
        ret = VRT_Endpoint_Clone(nvep);
834 32
        CHECK_OBJ_NOTNULL(ret, VRT_ENDPOINT_MAGIC);
835 32
        VSB_destroy(&preamble);
836 32
        FREE_OBJ(nvep);
837
838 32
        return (ret);
839
}
840
841
VCL_BACKEND
842 5464
VRT_new_backend_clustered(VRT_CTX, struct vsmw_cluster *vc,
843
    const struct vrt_backend *vrt, VCL_BACKEND via)
844
{
845
        struct backend *be;
846
        struct vcl *vcl;
847
        const struct vrt_backend_probe *vbp;
848
        const struct vrt_endpoint *vep;
849
        const struct vdi_methods *m;
850 5464
        const struct suckaddr *sa = NULL;
851
        char abuf[VTCP_ADDRBUFSIZE];
852 5464
        const struct backend *viabe = NULL;
853
854 5464
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
855 5464
        CHECK_OBJ_NOTNULL(vrt, VRT_BACKEND_MAGIC);
856 5464
        vep = vrt->endpoint;
857 5464
        CHECK_OBJ_NOTNULL(vep, VRT_ENDPOINT_MAGIC);
858 5464
        if (vep->uds_path == NULL) {
859 5280
                if (vep->ipv4 == NULL && vep->ipv6 == NULL) {
860 0
                        VRT_fail(ctx, "%s: Illegal IP", __func__);
861 0
                        return (NULL);
862
                }
863 5280
        } else {
864 184
                assert(vep->ipv4== NULL && vep->ipv6== NULL);
865
        }
866
867 5464
        if (via != NULL) {
868 32
                viabe = via_resolve(ctx, vep, via);
869 32
                if (viabe == NULL)
870 0
                        return (NULL);
871 32
        }
872
873 5464
        vcl = ctx->vcl;
874 5464
        AN(vcl);
875 5464
        AN(vrt->vcl_name);
876
877
        /* Create new backend */
878 5464
        ALLOC_OBJ(be, BACKEND_MAGIC);
879 5464
        if (be == NULL)
880 0
                return (NULL);
881 5464
        VTAILQ_INIT(&be->cw_head);
882
883
#define DA(x)   do { if (vrt->x != NULL) REPLACE((be->x), (vrt->x)); } while (0)
884
#define DN(x)   do { be->x = vrt->x; } while (0)
885 5464
        VRT_BACKEND_HANDLE();
886
#undef DA
887
#undef DN
888
889
#define CPTMO(a, b, x) do {                             \
890
                if ((a)->x < 0.0 || isnan((a)->x))      \
891
                        (a)->x = (b)->x;                \
892
        } while(0)
893
894 5456
        if (viabe != NULL) {
895 32
                CPTMO(be, viabe, connect_timeout);
896 32
                CPTMO(be, viabe, first_byte_timeout);
897 32
                CPTMO(be, viabe, between_bytes_timeout);
898 32
        }
899
#undef CPTMO
900
901 5456
        if (viabe || be->hosthdr == NULL) {
902 36
                if (vrt->endpoint->uds_path != NULL)
903 4
                        sa = bogo_ip;
904 32
                else if (cache_param->prefer_ipv6 && vep->ipv6 != NULL)
905 0
                        sa = vep->ipv6;
906 32
                else if (vep->ipv4!= NULL)
907 32
                        sa = vep->ipv4;
908
                else
909 0
                        sa = vep->ipv6;
910 36
                if (be->hosthdr == NULL) {
911 4
                        VTCP_name(sa, abuf, sizeof abuf, NULL, 0);
912 4
                        REPLACE(be->hosthdr, abuf);
913 4
                }
914 36
        }
915
916 10912
        be->vsc = VSC_vbe_New(vc, &be->vsc_seg,
917 5456
            "%s.%s", VCL_Name(ctx->vcl), vrt->vcl_name);
918 5456
        AN(be->vsc);
919 5456
        if (! vcl->temp->is_warm)
920 5404
                VRT_VSC_Hide(be->vsc_seg);
921
922 5456
        if (viabe)
923 56
                vep = be->endpoint = via_endpoint(viabe->endpoint, sa,
924 28
                    be->authority);
925
        else
926 5428
                vep = be->endpoint = VRT_Endpoint_Clone(vep);
927
928 5456
        AN(vep);
929 5456
        be->conn_pool = VCP_Ref(vep, vbe_proto_ident);
930 5456
        AN(be->conn_pool);
931
932 5456
        vbp = vrt->probe;
933 5456
        if (vbp == NULL)
934 5356
                vbp = VCL_DefaultProbe(vcl);
935
936 5456
        if (vbp != NULL) {
937 148
                VBP_Insert(be, vbp, be->conn_pool);
938 148
                m = vbe_methods;
939 148
        } else {
940 5308
                be->sick = 0;
941 5308
                be->vsc->happy = UINT64_MAX;
942 5308
                m = vbe_methods_noprobe;
943
        }
944
945 5456
        Lck_Lock(&backends_mtx);
946 5456
        VSC_C_main->n_backend++;
947 5456
        Lck_Unlock(&backends_mtx);
948
949 5456
        be->director = VRT_AddDirector(ctx, m, be, "%s", vrt->vcl_name);
950
951 5456
        if (be->director == NULL) {
952 0
                vbe_free(be);
953 0
                return (NULL);
954
        }
955
        /* for cold VCL, update initial director state */
956 5456
        if (be->probe != NULL)
957 152
                VBP_Update_Backend(be->probe);
958 5456
        return (be->director);
959 5456
}
960
961
VCL_BACKEND
962 128
VRT_new_backend(VRT_CTX, const struct vrt_backend *vrt, VCL_BACKEND via)
963
{
964
965 128
        CHECK_OBJ_NOTNULL(vrt, VRT_BACKEND_MAGIC);
966 128
        CHECK_OBJ_NOTNULL(vrt->endpoint, VRT_ENDPOINT_MAGIC);
967 128
        return (VRT_new_backend_clustered(ctx, NULL, vrt, via));
968
}
969
970
/*--------------------------------------------------------------------
971
 * Delete a dynamic director::backend instance.  Undeleted dynamic and
972
 * static instances are GC'ed when the VCL is discarded (in cache_vcl.c)
973
 */
974
975
void
976 316
VRT_delete_backend(VRT_CTX, VCL_BACKEND *dp)
977
{
978
979 316
        (void)ctx;
980 316
        CHECK_OBJ_NOTNULL(*dp, DIRECTOR_MAGIC);
981 316
        VRT_DisableDirector(*dp);
982 316
        VRT_Assign_Backend(dp, NULL);
983 316
}
984
985
/*---------------------------------------------------------------------*/
986
987
void
988 3892
VBE_InitCfg(void)
989
{
990
991 3892
        Lck_New(&backends_mtx, lck_vbe);
992 3892
}