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